respect subagent in command, add subtask flag (#2569)

This commit is contained in:
Aiden Cline
2025-09-13 12:47:18 -05:00
committed by GitHub
parent 6506e48c54
commit 16d66c209d
3 changed files with 122 additions and 6 deletions

View File

@@ -10,6 +10,7 @@ export namespace Command {
agent: z.string().optional(),
model: z.string().optional(),
template: z.string(),
subtask: z.boolean().optional(),
})
.openapi({
ref: "Command",
@@ -28,6 +29,7 @@ export namespace Command {
model: command.model,
description: command.description,
template: command.template,
subtask: command.subtask,
}
}

View File

@@ -244,6 +244,7 @@ export namespace Config {
description: z.string().optional(),
agent: z.string().optional(),
model: z.string().optional(),
subtask: z.boolean().optional(),
})
export type Command = z.infer<typeof Command>

View File

@@ -38,6 +38,7 @@ import { MCP } from "../mcp"
import { LSP } from "../lsp"
import { ReadTool } from "../tool/read"
import { ListTool } from "../tool/ls"
import { TaskTool } from "../tool/task"
import { FileTime } from "../file/time"
import { Permission } from "../permission"
import { Snapshot } from "../snapshot"
@@ -1315,7 +1316,7 @@ export namespace SessionPrompt {
export async function command(input: CommandInput) {
log.info("command", input)
const command = await Command.get(input.command)
const agent = command.agent ?? input.agent ?? "build"
const agentName = command.agent ?? input.agent ?? "build"
let template = command.template.replace("$ARGUMENTS", input.arguments)
@@ -1385,22 +1386,134 @@ export namespace SessionPrompt {
return Provider.parseModel(command.model)
}
if (command.agent) {
const agent = await Agent.get(command.agent)
if (agent.model) {
return agent.model
const cmdAgent = await Agent.get(command.agent)
if (cmdAgent.model) {
return cmdAgent.model
}
}
if (input.model) {
return Provider.parseModel(input.model)
}
return undefined
return await Provider.defaultModel()
})()
const agent = await Agent.get(agentName)
if (agent.mode === "subagent" || command.subtask) {
using abort = lock(input.sessionID)
const userMsg: MessageV2.User = {
id: Identifier.ascending("message"),
sessionID: input.sessionID,
time: {
created: Date.now(),
},
role: "user",
}
await Session.updateMessage(userMsg)
const userPart: MessageV2.Part = {
type: "text",
id: Identifier.ascending("part"),
messageID: userMsg.id,
sessionID: input.sessionID,
text: "The following tool was executed by the user",
synthetic: true,
}
await Session.updatePart(userPart)
const assistantMsg: MessageV2.Assistant = {
id: Identifier.ascending("message"),
sessionID: input.sessionID,
system: [],
mode: agentName,
cost: 0,
path: {
cwd: Instance.directory,
root: Instance.worktree,
},
time: {
created: Date.now(),
},
role: "assistant",
tokens: {
input: 0,
output: 0,
reasoning: 0,
cache: { read: 0, write: 0 },
},
modelID: model.modelID,
providerID: model.providerID,
}
await Session.updateMessage(assistantMsg)
const args = {
description: "Consulting " + agent.name,
subagent_type: agent.name,
prompt: template,
}
const toolPart: MessageV2.ToolPart = {
type: "tool",
id: Identifier.ascending("part"),
messageID: assistantMsg.id,
sessionID: input.sessionID,
tool: "task",
callID: ulid(),
state: {
status: "running",
time: {
start: Date.now(),
},
input: {
description: args.description,
subagent_type: args.subagent_type,
// truncate prompt to preserve context
prompt: args.prompt.length > 100 ? args.prompt.substring(0, 97) + "..." : args.prompt,
},
},
}
await Session.updatePart(toolPart)
const result = await TaskTool.init().then((t) =>
t.execute(args, {
sessionID: input.sessionID,
abort: abort.signal,
agent: agent.name,
messageID: assistantMsg.id,
extra: {},
metadata: async (metadata) => {
if (toolPart.state.status === "running") {
toolPart.state.metadata = metadata.metadata
toolPart.state.title = metadata.title
await Session.updatePart(toolPart)
}
},
}),
)
assistantMsg.time.completed = Date.now()
await Session.updateMessage(assistantMsg)
if (toolPart.state.status === "running") {
toolPart.state = {
status: "completed",
time: {
...toolPart.state.time,
end: Date.now(),
},
input: toolPart.state.input,
title: "",
metadata: result.metadata,
output: result.output,
}
await Session.updatePart(toolPart)
}
return { info: assistantMsg, parts: [toolPart] }
}
return prompt({
sessionID: input.sessionID,
messageID: input.messageID,
model,
agent,
agent: agentName,
parts,
})
}