diff --git a/packages/opencode/src/session/message-v2.ts b/packages/opencode/src/session/message-v2.ts index 2dff17a5efa..d2c2bd8ed24 100644 --- a/packages/opencode/src/session/message-v2.ts +++ b/packages/opencode/src/session/message-v2.ts @@ -168,6 +168,12 @@ export namespace MessageV2 { prompt: z.string(), description: z.string(), agent: z.string(), + model: z + .object({ + providerID: z.string(), + modelID: z.string(), + }) + .optional(), command: z.string().optional(), }) export type SubtaskPart = z.infer diff --git a/packages/opencode/src/session/prompt.ts b/packages/opencode/src/session/prompt.ts index f891612272c..ee7f86403f1 100644 --- a/packages/opencode/src/session/prompt.ts +++ b/packages/opencode/src/session/prompt.ts @@ -316,6 +316,7 @@ export namespace SessionPrompt { // TODO: centralize "invoke tool" logic if (task?.type === "subtask") { const taskTool = await TaskTool.init() + const taskModel = task.model ? await Provider.getModel(task.model.providerID, task.model.modelID) : model const assistantMessage = (await Session.updateMessage({ id: Identifier.ascending("message"), role: "assistant", @@ -334,8 +335,8 @@ export namespace SessionPrompt { reasoning: 0, cache: { read: 0, write: 0 }, }, - modelID: model.id, - providerID: model.providerID, + modelID: taskModel.id, + providerID: taskModel.providerID, time: { created: Date.now(), }, @@ -1505,7 +1506,7 @@ export namespace SessionPrompt { } template = template.trim() - const model = await (async () => { + const taskModel = await (async () => { if (command.model) { return Provider.parseModel(command.model) } @@ -1520,7 +1521,7 @@ export namespace SessionPrompt { })() try { - await Provider.getModel(model.providerID, model.modelID) + await Provider.getModel(taskModel.providerID, taskModel.modelID) } catch (e) { if (Provider.ModelNotFoundError.isInstance(e)) { const { providerID, modelID, suggestions } = e.data @@ -1545,25 +1546,36 @@ export namespace SessionPrompt { } const templateParts = await resolvePromptParts(template) - const parts = - (agent.mode === "subagent" && command.subtask !== false) || command.subtask === true - ? [ - { - type: "subtask" as const, - agent: agent.name, - description: command.description ?? "", - command: input.command, - // TODO: how can we make task tool accept a more complex input? - prompt: templateParts.find((y) => y.type === "text")?.text ?? "", + const isSubtask = (agent.mode === "subagent" && command.subtask !== false) || command.subtask === true + const parts = isSubtask + ? [ + { + type: "subtask" as const, + agent: agent.name, + description: command.description ?? "", + command: input.command, + model: { + providerID: taskModel.providerID, + modelID: taskModel.modelID, }, - ] - : [...templateParts, ...(input.parts ?? [])] + // TODO: how can we make task tool accept a more complex input? + prompt: templateParts.find((y) => y.type === "text")?.text ?? "", + }, + ] + : [...templateParts, ...(input.parts ?? [])] + + const userAgent = isSubtask ? (input.agent ?? (await Agent.defaultAgent())) : agentName + const userModel = isSubtask + ? input.model + ? Provider.parseModel(input.model) + : await lastModel(input.sessionID) + : taskModel const result = (await prompt({ sessionID: input.sessionID, messageID: input.messageID, - model, - agent: agentName, + model: userModel, + agent: userAgent, parts, variant: input.variant, })) as MessageV2.WithParts