From faca80caa9724ab376dba30e6d81adef0c22c662 Mon Sep 17 00:00:00 2001 From: Mike <59196850+mmlmt2604@users.noreply.github.com> Date: Thu, 29 Jan 2026 08:30:37 +0800 Subject: [PATCH] fix(start-work): prevent overwriting session agent if already set; inherit parent model for subagent types (#1201) * fix(start-work): prevent overwriting session agent if already set; inherit parent model for subagent types * fix(model): include variant in StoredMessage model structure for better context propagation * fix(injector): include variant in model structure for hook message injection --- src/features/builtin-commands/commands.ts | 1 - src/features/hook-message-injector/injector.ts | 14 +++++++++++--- src/features/hook-message-injector/types.ts | 2 ++ src/hooks/start-work/index.ts | 7 +++++-- src/hooks/todo-continuation-enforcer.ts | 6 +++++- src/tools/background-task/tools.ts | 6 +++++- src/tools/delegate-task/tools.ts | 13 ++++++++++++- 7 files changed, 40 insertions(+), 9 deletions(-) diff --git a/src/features/builtin-commands/commands.ts b/src/features/builtin-commands/commands.ts index eec67a9a..78a03397 100644 --- a/src/features/builtin-commands/commands.ts +++ b/src/features/builtin-commands/commands.ts @@ -55,7 +55,6 @@ ${REFACTOR_TEMPLATE} }, "start-work": { description: "(builtin) Start Sisyphus work session from Prometheus plan", - agent: "atlas", template: ` ${START_WORK_TEMPLATE} diff --git a/src/features/hook-message-injector/injector.ts b/src/features/hook-message-injector/injector.ts index f5d87018..a4a238b8 100644 --- a/src/features/hook-message-injector/injector.ts +++ b/src/features/hook-message-injector/injector.ts @@ -5,7 +5,7 @@ import type { MessageMeta, OriginalMessageContext, TextPart, ToolPermission } fr export interface StoredMessage { agent?: string - model?: { providerID?: string; modelID?: string } + model?: { providerID?: string; modelID?: string; variant?: string } tools?: Record } @@ -141,9 +141,17 @@ export function injectHookMessage( const resolvedAgent = originalMessage.agent ?? fallback?.agent ?? "general" const resolvedModel = originalMessage.model?.providerID && originalMessage.model?.modelID - ? { providerID: originalMessage.model.providerID, modelID: originalMessage.model.modelID } + ? { + providerID: originalMessage.model.providerID, + modelID: originalMessage.model.modelID, + ...(originalMessage.model.variant ? { variant: originalMessage.model.variant } : {}) + } : fallback?.model?.providerID && fallback?.model?.modelID - ? { providerID: fallback.model.providerID, modelID: fallback.model.modelID } + ? { + providerID: fallback.model.providerID, + modelID: fallback.model.modelID, + ...(fallback.model.variant ? { variant: fallback.model.variant } : {}) + } : undefined const resolvedTools = originalMessage.tools ?? fallback?.tools diff --git a/src/features/hook-message-injector/types.ts b/src/features/hook-message-injector/types.ts index 47caaf93..f1f9cb25 100644 --- a/src/features/hook-message-injector/types.ts +++ b/src/features/hook-message-injector/types.ts @@ -12,6 +12,7 @@ export interface MessageMeta { model?: { providerID: string modelID: string + variant?: string } path?: { cwd: string @@ -25,6 +26,7 @@ export interface OriginalMessageContext { model?: { providerID?: string modelID?: string + variant?: string } path?: { cwd?: string diff --git a/src/hooks/start-work/index.ts b/src/hooks/start-work/index.ts index 4f3d528b..3ca15bd2 100644 --- a/src/hooks/start-work/index.ts +++ b/src/hooks/start-work/index.ts @@ -10,7 +10,7 @@ import { clearBoulderState, } from "../../features/boulder-state" import { log } from "../../shared/logger" -import { updateSessionAgent } from "../../features/claude-code-session-state" +import { getSessionAgent, updateSessionAgent } from "../../features/claude-code-session-state" export const HOOK_NAME = "start-work" @@ -71,7 +71,10 @@ export function createStartWorkHook(ctx: PluginInput) { sessionID: input.sessionID, }) - updateSessionAgent(input.sessionID, "atlas") + const currentAgent = getSessionAgent(input.sessionID) + if (!currentAgent) { + updateSessionAgent(input.sessionID, "atlas") + } const existingState = readBoulderState(ctx.directory) const sessionId = input.sessionID diff --git a/src/hooks/todo-continuation-enforcer.ts b/src/hooks/todo-continuation-enforcer.ts index a4e65ea6..d93bd16d 100644 --- a/src/hooks/todo-continuation-enforcer.ts +++ b/src/hooks/todo-continuation-enforcer.ts @@ -205,7 +205,11 @@ export function createTodoContinuationEnforcer( const prevMessage = messageDir ? findNearestMessageWithFields(messageDir) : null agentName = agentName ?? prevMessage?.agent model = model ?? (prevMessage?.model?.providerID && prevMessage?.model?.modelID - ? { providerID: prevMessage.model.providerID, modelID: prevMessage.model.modelID } + ? { + providerID: prevMessage.model.providerID, + modelID: prevMessage.model.modelID, + ...(prevMessage.model.variant ? { variant: prevMessage.model.variant } : {}) + } : undefined) tools = tools ?? prevMessage?.tools } diff --git a/src/tools/background-task/tools.ts b/src/tools/background-task/tools.ts index 5fe5e6cc..93ac690d 100644 --- a/src/tools/background-task/tools.ts +++ b/src/tools/background-task/tools.ts @@ -80,7 +80,11 @@ export function createBackgroundTask(manager: BackgroundManager): ToolDefinition }) const parentModel = prevMessage?.model?.providerID && prevMessage?.model?.modelID - ? { providerID: prevMessage.model.providerID, modelID: prevMessage.model.modelID } + ? { + providerID: prevMessage.model.providerID, + modelID: prevMessage.model.modelID, + ...(prevMessage.model.variant ? { variant: prevMessage.model.variant } : {}) + } : undefined const task = await manager.launch({ diff --git a/src/tools/delegate-task/tools.ts b/src/tools/delegate-task/tools.ts index 653ecf88..8009b41a 100644 --- a/src/tools/delegate-task/tools.ts +++ b/src/tools/delegate-task/tools.ts @@ -287,7 +287,11 @@ Prompts MUST be in English.` resolvedParentAgent: parentAgent, }) const parentModel = prevMessage?.model?.providerID && prevMessage?.model?.modelID - ? { providerID: prevMessage.model.providerID, modelID: prevMessage.model.modelID } + ? { + providerID: prevMessage.model.providerID, + modelID: prevMessage.model.modelID, + ...(prevMessage.model.variant ? { variant: prevMessage.model.variant } : {}) + } : undefined if (args.session_id) { @@ -806,6 +810,13 @@ Create the work plan directly - that's your job as the planning agent.` } catch { // If we can't fetch agents, proceed anyway - the session.prompt will fail with a clearer error } + + // When using subagent_type directly, inherit parent model so agents don't default + // to their hardcoded models (like grok-code) which may not be available + if (parentModel) { + categoryModel = parentModel + modelInfo = { model: `${parentModel.providerID}/${parentModel.modelID}`, type: "inherited" } + } } const systemContent = buildSystemContent({ skillContent, categoryPromptAppend, agentName: agentToUse })