Skip tool guidance, custom prompt, and Agent Skills for tool-incapable models

effectiveSystemPrompt now gates tool-usage guidelines, the user's
custom system prompt, and active Agent Skills behind whether the
selected model actually supports tools (ModelInfo.capabilities.tools).
All three assume tool/file/web access and can easily blow past small
context windows.

Confirmed live against Apple Intelligence: the default system prompt
dropped from 16,377 to ~250 tokens (well under the 4K on-device
limit), fully resolving the context-exceeded error from the initial
Phase 1 rollout. Verified end-to-end with a real successful generation
in the app after the fix.

Also: .gitignore now excludes *.profraw (stray code-coverage artifact
picked up while testing).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-24 10:12:39 +02:00
co-authored by Claude Sonnet 5
parent 30fbb4162e
commit 30d0500323
2 changed files with 26 additions and 14 deletions
+23 -14
View File
@@ -151,8 +151,14 @@ Don't narrate future actions ("Let me...") - just use the tools.
/// Builds the complete system prompt by combining default + conditional sections + custom
private var effectiveSystemPrompt: String {
// Tool guidance, the user's custom prompt, and Agent Skills all generally assume tool
// access and can easily blow past small context windows (e.g. Apple's on-device 4K
// limit) skip all three for tool-incapable models.
let modelSupportsTools = selectedModel?.capabilities.tools ?? true
// Check if user wants to replace the default prompt entirely (BYOP mode)
if settings.customPromptMode == .replace,
if modelSupportsTools,
settings.customPromptMode == .replace,
let customPrompt = settings.systemPrompt,
!customPrompt.isEmpty {
// BYOP: Use ONLY the custom prompt
@@ -170,29 +176,32 @@ Don't narrate future actions ("Let me...") - just use the tools.
}
// Add tool-specific guidelines if MCP is enabled (tools are available)
if mcpEnabled {
if mcpEnabled && modelSupportsTools {
prompt += toolUsageGuidelines
}
// Append custom prompt if in append mode and custom prompt exists
if settings.customPromptMode == .append,
if modelSupportsTools,
settings.customPromptMode == .append,
let customPrompt = settings.systemPrompt,
!customPrompt.isEmpty {
prompt += "\n\n---\n\nAdditional Instructions:\n" + customPrompt
}
// Append active agent skills (SKILL.md-style behavioral instructions)
let activeSkills = settings.agentSkills.filter { $0.isActive }
if !activeSkills.isEmpty {
prompt += "\n\n---\n\n## Installed Skills\n\nThe following skills are active. Apply them when relevant:\n\n"
for skill in activeSkills {
prompt += "### \(skill.name)\n\n\(skill.content)\n\n"
let files = AgentSkillFilesService.shared.readTextFiles(for: skill.id)
if !files.isEmpty {
prompt += "**Skill Data Files:**\n\n"
for (name, content) in files {
let ext = URL(fileURLWithPath: name).pathExtension.lowercased()
prompt += "**\(name):**\n```\(ext)\n\(content)\n```\n\n"
if modelSupportsTools {
let activeSkills = settings.agentSkills.filter { $0.isActive }
if !activeSkills.isEmpty {
prompt += "\n\n---\n\n## Installed Skills\n\nThe following skills are active. Apply them when relevant:\n\n"
for skill in activeSkills {
prompt += "### \(skill.name)\n\n\(skill.content)\n\n"
let files = AgentSkillFilesService.shared.readTextFiles(for: skill.id)
if !files.isEmpty {
prompt += "**Skill Data Files:**\n\n"
for (name, content) in files {
let ext = URL(fileURLWithPath: name).pathExtension.lowercased()
prompt += "**\(name):**\n```\(ext)\n\(content)\n```\n\n"
}
}
}
}