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
@@ -214,4 +214,45 @@ describe("unstable-agent-babysitter hook", () => {
expect(promptCalls.length).toBe(1)
Date.now = originalNow
})
test("#given the main session model includes variant #when injecting a babysitter reminder #then promptAsync receives variant as a top-level field", async () => {
// given
setMainSession("main-1")
const promptCalls: Array<{ input: unknown }> = []
const mainModel = {
providerID: "openai",
modelID: "gpt-4",
variant: "max",
}
const ctx = createMockPluginInput({
messagesBySession: {
"main-1": [
{ info: { agent: "sisyphus", model: mainModel } },
],
"bg-1": [
{ info: { role: "assistant" }, parts: [{ type: "thinking", thinking: "deep thought" }] },
],
},
promptCalls,
})
const backgroundManager = createBackgroundManager([createTask()])
const hook = createUnstableAgentBabysitterHook(ctx, {
backgroundManager,
config: { timeout_ms: 120000 },
})
// when
await hook.event({ event: { type: "session.idle", properties: { sessionID: "main-1" } } })
// then
expect(promptCalls.length).toBe(1)
const payload = promptCalls[0].input as {
body?: {
model?: { providerID: string; modelID: string }
variant?: string
}
}
expect(payload.body?.model).toEqual({ providerID: "openai", modelID: "gpt-4" })
expect(payload.body?.variant).toBe("max")
})
})
@@ -5,7 +5,7 @@ export const THINKING_SUMMARY_MAX_CHARS = 500 as const
type MessageInfo = {
role?: string
agent?: string
model?: { providerID: string; modelID: string }
model?: { providerID: string; modelID: string; variant?: string }
providerID?: string
modelID?: string
tools?: Record<string, boolean | "allow" | "deny" | "ask">
@@ -33,7 +33,11 @@ export function getMessageInfo(value: unknown): MessageInfo | undefined {
? info.model
: undefined
const model = modelValue && typeof modelValue.providerID === "string" && typeof modelValue.modelID === "string"
? { providerID: modelValue.providerID, modelID: modelValue.modelID }
? {
providerID: modelValue.providerID,
modelID: modelValue.modelID,
...(typeof modelValue.variant === "string" ? { variant: modelValue.variant } : {}),
}
: undefined
return {
role: typeof info.role === "string" ? info.role : undefined,
@@ -30,6 +30,7 @@ type BabysitterContext = {
body: {
parts: Array<{ type: "text"; text: string }>
agent?: string
variant?: string
model?: { providerID: string; modelID: string }
tools?: Record<string, boolean>
}
@@ -40,6 +41,7 @@ type BabysitterContext = {
body: {
parts: Array<{ type: "text"; text: string }>
agent?: string
variant?: string
model?: { providerID: string; modelID: string }
tools?: Record<string, boolean>
}
@@ -58,9 +60,9 @@ type BabysitterOptions = {
async function resolveMainSessionTarget(
ctx: BabysitterContext,
sessionID: string
): Promise<{ agent?: string; model?: { providerID: string; modelID: string }; tools?: Record<string, boolean> }> {
): Promise<{ agent?: string; model?: { providerID: string; modelID: string; variant?: string }; tools?: Record<string, boolean> }> {
let agent = getSessionAgent(sessionID)
let model: { providerID: string; modelID: string } | undefined
let model: { providerID: string; modelID: string; variant?: string } | undefined
let tools: Record<string, boolean> | undefined
try {
@@ -206,11 +208,17 @@ export function createUnstableAgentBabysitterHook(ctx: BabysitterContext, option
const { agent, model, tools } = await resolveMainSessionTarget(ctx, mainSessionID)
try {
const launchModel = model
? { providerID: model.providerID, modelID: model.modelID }
: undefined
const launchVariant = model?.variant
await ctx.client.session.promptAsync({
path: { id: mainSessionID },
body: {
...(agent ? { agent } : {}),
...(model ? { model } : {}),
...(launchModel ? { model: launchModel } : {}),
...(launchVariant ? { variant: launchVariant } : {}),
...(tools ? { tools } : {}),
parts: [createInternalAgentTextPart(reminder)],
},