diff --git a/src/hooks/ralph-loop/index.test.ts b/src/hooks/ralph-loop/index.test.ts index 8492ec6ae..a344a5a14 100644 --- a/src/hooks/ralph-loop/index.test.ts +++ b/src/hooks/ralph-loop/index.test.ts @@ -603,7 +603,7 @@ describe("ralph-loop", () => { expect(hook.getState()).toBeNull() // then - messages API was called with correct session ID - expect(messagesCalls.length).toBe(1) + expect(messagesCalls.length).toBe(2) expect(messagesCalls[0].sessionID).toBe("session-123") }) @@ -633,7 +633,7 @@ describe("ralph-loop", () => { expect(hook.getState()).toBeNull() // then - messages API was called with correct session ID - expect(messagesCalls.length).toBe(1) + expect(messagesCalls.length).toBe(2) expect(messagesCalls[0].sessionID).toBe("session-123") }) @@ -1075,7 +1075,7 @@ Original task: Build something` expect(promptCalls.length).toBe(0) expect(hook.getState()).toBeNull() // API should NOT be called since transcript found completion - expect(messagesCalls.length).toBe(0) + expect(messagesCalls.length).toBe(1) }) test("should show ultrawork completion toast", async () => { diff --git a/src/hooks/ralph-loop/ralph-loop-hook.ts b/src/hooks/ralph-loop/ralph-loop-hook.ts index 9c069ee87..9e0ee3d04 100644 --- a/src/hooks/ralph-loop/ralph-loop-hook.ts +++ b/src/hooks/ralph-loop/ralph-loop-hook.ts @@ -24,6 +24,19 @@ export interface RalphLoopHook { const DEFAULT_API_TIMEOUT = 5000 as const +function getMessageCountFromResponse(messagesResponse: unknown): number { + if (Array.isArray(messagesResponse)) { + return messagesResponse.length + } + + if (typeof messagesResponse === "object" && messagesResponse !== null && "data" in messagesResponse) { + const data = (messagesResponse as { data?: unknown }).data + return Array.isArray(data) ? data.length : 0 + } + + return 0 +} + export function createRalphLoopHook( ctx: PluginInput, options?: RalphLoopOptions @@ -52,7 +65,25 @@ export function createRalphLoopHook( return { event, - startLoop: loopState.startLoop, + startLoop: (sessionID, prompt, loopOptions): boolean => { + const startSuccess = loopState.startLoop(sessionID, prompt, loopOptions) + if (!startSuccess || typeof loopOptions?.messageCountAtStart === "number") { + return startSuccess + } + + ctx.client.session + .messages({ + path: { id: sessionID }, + query: { directory: ctx.directory }, + }) + .then((messagesResponse: unknown) => { + const messageCountAtStart = getMessageCountFromResponse(messagesResponse) + loopState.setMessageCountAtStart(sessionID, messageCountAtStart) + }) + .catch(() => {}) + + return startSuccess + }, cancelLoop: loopState.cancelLoop, getState: loopState.getState as () => RalphLoopState | null, }