fix: propagate variant field in all promptAsync continuation paths (#3081)

All 5 continuation paths now send variant as top-level body field:
- boulder-continuation-injector.ts
- ralph-loop/continuation-prompt-injector.ts
- todo-continuation-enforcer/continuation-injection.ts
- unstable-agent-babysitter-hook.ts
- session-recovery/resume.ts

Plus type/helper updates in atlas, todo-continuation-enforcer,
unstable-agent-babysitter, and session-recovery.

TDD: 18 regression tests added, all pass. tsc clean.
This commit is contained in:
YeonGyu-Kim
2026-04-07 15:10:38 +09:00
parent 3e8fd5ff18
commit aa528e42c0
15 changed files with 310 additions and 23 deletions
@@ -119,4 +119,57 @@ describe("injectContinuation", () => {
// then
expect(injected).toBe(false)
})
test("#given resolved model info includes variant #when reinjecting continuation #then promptAsync receives variant as a top-level field", async () => {
// given
let capturedBody:
| {
model?: { providerID: string; modelID: string }
variant?: string
}
| undefined
const ctx = {
directory: "/tmp/test",
client: {
session: {
todo: async () => ({ data: [{ id: "1", content: "todo", status: "pending", priority: "high" }] }),
promptAsync: async (input: {
body: {
model?: { providerID: string; modelID: string }
variant?: string
}
}) => {
capturedBody = input.body
return {}
},
},
},
}
const sessionStateStore = {
getExistingState: () => ({ inFlight: false, lastInjectedAt: 0, consecutiveFailures: 0 }),
}
const model = {
providerID: "openai",
modelID: "gpt-5.3-codex",
variant: "max",
}
// when
await injectContinuation({
ctx: ctx as never,
sessionID: "ses_continuation_variant",
resolvedInfo: {
agent: "Hephaestus",
model,
},
sessionStateStore: sessionStateStore as never,
})
// then
expect(capturedBody?.model).toEqual({
providerID: "openai",
modelID: "gpt-5.3-codex",
})
expect(capturedBody?.variant).toBe("max")
})
})
@@ -174,11 +174,17 @@ ${todoList}`
const inheritedTools = resolveInheritedPromptTools(sessionID, tools)
const launchModel = model
? { providerID: model.providerID, modelID: model.modelID }
: undefined
const launchVariant = model?.variant
await ctx.client.session.promptAsync({
path: { id: sessionID },
body: {
agent: promptAgent,
...(model !== undefined ? { model } : {}),
...(launchModel ? { model: launchModel } : {}),
...(launchVariant ? { variant: launchVariant } : {}),
...(inheritedTools ? { tools: inheritedTools } : {}),
parts: [createInternalAgentTextPart(prompt)],
},
@@ -45,7 +45,7 @@ export interface MessageInfo {
role?: string
error?: { name?: string; data?: unknown }
agent?: string
model?: { providerID: string; modelID: string }
model?: { providerID: string; modelID: string; variant?: string }
providerID?: string
modelID?: string
tools?: Record<string, ToolPermission>
@@ -57,7 +57,7 @@ export interface MessageWithInfo {
export interface ResolvedMessageInfo {
agent?: string
model?: { providerID: string; modelID: string }
model?: { providerID: string; modelID: string; variant?: string }
tools?: Record<string, ToolPermission>
}