diff options
| author | Adam Malczewski <[email protected]> | 2026-05-29 15:38:35 +0900 |
|---|---|---|
| committer | Adam Malczewski <[email protected]> | 2026-05-29 15:38:35 +0900 |
| commit | 48194753eee9c6cb8995cf52afcbd615cf115491 (patch) | |
| tree | a4aa2c22ed0db272d6848c28f755ad9950418c54 /packages/api | |
| parent | aa230050f4edb7bfc8d3e4d59d95c68c36264b41 (diff) | |
| download | dispatch-48194753eee9c6cb8995cf52afcbd615cf115491.tar.gz dispatch-48194753eee9c6cb8995cf52afcbd615cf115491.zip | |
feat: subagent summon — catalog filter, error hints, system prompt, AgentBuilder default, SubAgent mode display
- Filter summon tool catalog to is_subagent-flagged agents only
- Return fresh subagent list in error when slug not found
- Add subagent hint to system prompt when summon tool available
- Default is_subagent checkbox to true in AgentBuilder
- Fix tab-created event to include agentSlug and agentModels
- Add SubAgent read-only mode to ModelSelector with model slider
Diffstat (limited to 'packages/api')
| -rw-r--r-- | packages/api/src/agent-manager.ts | 32 |
1 files changed, 23 insertions, 9 deletions
diff --git a/packages/api/src/agent-manager.ts b/packages/api/src/agent-manager.ts index 9ed2f51..69c071d 100644 --- a/packages/api/src/agent-manager.ts +++ b/packages/api/src/agent-manager.ts @@ -134,10 +134,15 @@ function buildSystemPrompt(toolNames: string[], basePrompt?: string): string { if (!toolList) return base; const hasTodo = toolNames.includes("todo"); + const hasSummon = toolNames.includes("summon"); let prompt = `${base}\n\nYou have access to the following tools:\n\n${toolList}\n\nWhen asked to work with files, use these tools. Always confirm what you did after completing an action.`; if (hasTodo) { prompt += `\n\n${TODO_GUIDANCE}`; } + if (hasSummon) { + prompt += + '\n\nYou have pre-configured subagent types. Use summon(agent="slug", task="...") to delegate specialized work to a subagent. Use list_files and read_file to inspect available agent definitions.'; + } return prompt; } @@ -940,9 +945,13 @@ export class AgentManager { if (options.agentSlug) { agentDef = loadAgent(options.agentSlug, parentEffectiveDir); if (!agentDef) { - throw new Error( - `Agent definition not found: "${options.agentSlug}". Inspect the agents directories to see available slugs.`, - ); + const allDefs = loadAgents(parentEffectiveDir); + const subagents = allDefs.filter((d) => d.is_subagent).map((d) => `${d.slug} (${d.name})`); + const hint = + subagents.length > 0 + ? ` Available subagents: ${subagents.join(", ")}.` + : " No subagent definitions exist yet."; + throw new Error(`Agent definition not found: "${options.agentSlug}".${hint}`); } } @@ -989,13 +998,16 @@ export class AgentManager { tabAgent.workingDirectoryOverride = resolvedWorkingDirectory; tabAgent.finalOutput = ""; - if (agentDef && agentDef.models.length > 0) { + const primary = agentDef?.models[0]; + if (agentDef && primary) { // The agent definition specifies its own model fallback chain. - // Clear keyId/modelId so the fallback sequence uses the - // definition's models (matches how a top-level tab using this - // definition would be configured). - tabAgent.keyId = null; - tabAgent.modelId = null; + // Set keyId/modelId to the primary (first) model in the chain so + // the frontend can display the concrete key/model this subagent + // was configured with, while `agentModels` drives the fallback + // sequence (matches how a top-level tab using this definition + // would be configured). + tabAgent.keyId = primary.key_id; + tabAgent.modelId = primary.model_id; tabAgent.agentModels = agentDef.models; } else { // No definition (or definition has no models) → inherit from @@ -1036,7 +1048,9 @@ export class AgentManager { keyId: tabAgent.keyId, modelId: tabAgent.modelId, parentTabId: options.parentTabId ?? null, + agentSlug: options.agentSlug ?? null, workingDirectory: resolvedWorkingDirectory ?? null, + agentModels: tabAgent.agentModels ?? null, }, tabId, ); |
