diff --git a/src/hooks/ralph-loop/continuation-prompt-injector.test.ts b/src/hooks/ralph-loop/continuation-prompt-injector.test.ts index 95cd07294..6455e70e1 100644 --- a/src/hooks/ralph-loop/continuation-prompt-injector.test.ts +++ b/src/hooks/ralph-loop/continuation-prompt-injector.test.ts @@ -2,6 +2,65 @@ import { describe, expect, test } from "bun:test" import { injectContinuationPrompt } from "./continuation-prompt-injector" describe("ralph-loop continuation prompt injector", () => { + test("#given inherited message agent has ZWSP prefix #when injecting continuation prompt #then promptAsync receives normalized agent", async () => { + // given + let promptBody: { agent?: string } | undefined + const ctx = { + client: { + session: { + messages: async () => ({ + data: [{ info: { agent: "\u200bSisyphus - Ultraworker" } }], + }), + promptAsync: async (input: { body: { agent?: string } }) => { + promptBody = input.body + return {} + }, + }, + }, + } + + // when + await injectContinuationPrompt(ctx as never, { + sessionID: "ses_ralph_zwsp_agent", + prompt: "continue", + directory: "/tmp/test", + apiTimeoutMs: 50, + }) + + // then + expect(promptBody?.agent).toBe("sisyphus") + expect(promptBody?.agent).not.toContain("\u200b") + }) + + test("#given inherited message agent has no ZWSP prefix #when injecting continuation prompt #then promptAsync receives normalized agent", async () => { + // given + let promptBody: { agent?: string } | undefined + const ctx = { + client: { + session: { + messages: async () => ({ + data: [{ info: { agent: "Sisyphus - Ultraworker" } }], + }), + promptAsync: async (input: { body: { agent?: string } }) => { + promptBody = input.body + return {} + }, + }, + }, + } + + // when + await injectContinuationPrompt(ctx as never, { + sessionID: "ses_ralph_clean_agent", + prompt: "continue", + directory: "/tmp/test", + apiTimeoutMs: 50, + }) + + // then + expect(promptBody?.agent).toBe("sisyphus") + }) + test("#given inherited message model includes variant #when injecting continuation prompt #then promptAsync receives variant as a top-level field", async () => { // given let promptBody: diff --git a/src/hooks/ralph-loop/continuation-prompt-injector.ts b/src/hooks/ralph-loop/continuation-prompt-injector.ts index 94df8debf..fc1405c74 100644 --- a/src/hooks/ralph-loop/continuation-prompt-injector.ts +++ b/src/hooks/ralph-loop/continuation-prompt-injector.ts @@ -8,6 +8,7 @@ import { normalizeSDKResponse, resolveInheritedPromptTools, } from "../../shared" +import { normalizeAgentForPromptKey } from "../../shared/agent-display-names" type MessageInfo = { agent?: string @@ -69,6 +70,7 @@ export async function injectContinuationPrompt( } const inheritedTools = resolveInheritedPromptTools(sourceSessionID, tools) + const cleanAgent = normalizeAgentForPromptKey(agent) const launchModel = model ? { providerID: model.providerID, modelID: model.modelID } @@ -78,7 +80,7 @@ export async function injectContinuationPrompt( await ctx.client.session.promptAsync({ path: { id: options.sessionID }, body: { - ...(agent !== undefined ? { agent } : {}), + ...(cleanAgent !== undefined ? { agent: cleanAgent } : {}), ...(launchModel ? { model: launchModel } : {}), ...(launchVariant ? { variant: launchVariant } : {}), ...(inheritedTools ? { tools: inheritedTools } : {}),