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
@@ -0,0 +1,52 @@
import { describe, expect, test } from "bun:test"
import { injectContinuationPrompt } from "./continuation-prompt-injector"
describe("ralph-loop continuation prompt injector", () => {
test("#given inherited message model includes variant #when injecting continuation prompt #then promptAsync receives variant as a top-level field", async () => {
// given
let promptBody:
| {
model?: { providerID: string; modelID: string }
variant?: string
}
| undefined
const model = {
providerID: "openai",
modelID: "gpt-5.3-codex",
variant: "max",
}
const ctx = {
client: {
session: {
messages: async () => ({
data: [{ info: { agent: "sisyphus", model } }],
}),
promptAsync: async (input: {
body: {
model?: { providerID: string; modelID: string }
variant?: string
}
}) => {
promptBody = input.body
return {}
},
},
},
}
// when
await injectContinuationPrompt(ctx as never, {
sessionID: "ses_ralph_variant",
prompt: "continue",
directory: "/tmp/test",
apiTimeoutMs: 50,
})
// then
expect(promptBody?.model).toEqual({
providerID: "openai",
modelID: "gpt-5.3-codex",
})
expect(promptBody?.variant).toBe("max")
})
})
@@ -11,7 +11,7 @@ import {
type MessageInfo = {
agent?: string
model?: { providerID: string; modelID: string }
model?: { providerID: string; modelID: string; variant?: string }
modelID?: string
providerID?: string
tools?: Record<string, boolean | "allow" | "deny" | "ask">
@@ -28,7 +28,7 @@ export async function injectContinuationPrompt(
},
): Promise<void> {
let agent: string | undefined
let model: { providerID: string; modelID: string } | undefined
let model: { providerID: string; modelID: string; variant?: string } | undefined
let tools: Record<string, boolean | "allow" | "deny" | "ask"> | undefined
const sourceSessionID = options.inheritFromSessionID ?? options.sessionID
@@ -62,6 +62,7 @@ export async function injectContinuationPrompt(
? {
providerID: currentMessage.model.providerID,
modelID: currentMessage.model.modelID,
...(currentMessage.model.variant ? { variant: currentMessage.model.variant } : {}),
}
: undefined
tools = currentMessage?.tools
@@ -69,11 +70,17 @@ export async function injectContinuationPrompt(
const inheritedTools = resolveInheritedPromptTools(sourceSessionID, tools)
const launchModel = model
? { providerID: model.providerID, modelID: model.modelID }
: undefined
const launchVariant = model?.variant
await ctx.client.session.promptAsync({
path: { id: options.sessionID },
body: {
...(agent !== undefined ? { agent } : {}),
...(model !== undefined ? { model } : {}),
...(launchModel ? { model: launchModel } : {}),
...(launchVariant ? { variant: launchVariant } : {}),
...(inheritedTools ? { tools: inheritedTools } : {}),
parts: [createInternalAgentTextPart(options.prompt)],
},