diff --git a/extensions/acpx/src/runtime-internals/events.test.ts b/extensions/acpx/src/runtime-internals/events.test.ts index bb8067c3327..6358cf339ca 100644 --- a/extensions/acpx/src/runtime-internals/events.test.ts +++ b/extensions/acpx/src/runtime-internals/events.test.ts @@ -67,6 +67,37 @@ describe("parsePromptEventLine", () => { }); }); + it("parses JSON-RPC result stopReason as done", () => { + const line = JSON.stringify({ + jsonrpc: "2.0", + id: 3, + result: { + stopReason: "end_turn", + }, + }); + expect(parsePromptEventLine(line)).toEqual({ + type: "done", + stopReason: "end_turn", + }); + }); + + it("parses JSON-RPC errors as runtime errors", () => { + const line = JSON.stringify({ + jsonrpc: "2.0", + id: 2, + error: { + code: -32002, + message: "Resource not found", + }, + }); + expect(parsePromptEventLine(line)).toEqual({ + type: "error", + message: "Resource not found", + code: undefined, + retryable: undefined, + }); + }); + it("keeps compatibility with simplified text/done lines", () => { expect(parsePromptEventLine(JSON.stringify({ type: "text", content: "alpha" }))).toEqual({ type: "text_delta", diff --git a/extensions/acpx/src/runtime-internals/events.ts b/extensions/acpx/src/runtime-internals/events.ts index f83f4ddabb9..8e863605aba 100644 --- a/extensions/acpx/src/runtime-internals/events.ts +++ b/extensions/acpx/src/runtime-internals/events.ts @@ -65,6 +65,28 @@ function resolveStructuredPromptPayload(parsed: Record): { } } + const result = parsed.result; + if (isRecord(result)) { + const stopReason = asTrimmedString(result.stopReason); + if (stopReason) { + return { + type: "done", + payload: result, + }; + } + } + + const rpcError = parsed.error; + if (isRecord(rpcError)) { + const message = asTrimmedString(rpcError.message); + if (message) { + return { + type: "error", + payload: rpcError, + }; + } + } + const sessionUpdate = asOptionalString(parsed.sessionUpdate) as AcpSessionUpdateTag | undefined; if (sessionUpdate) { return {