diff --git a/src/agents/pi-embedded-runner/run/payloads.errors.test.ts b/src/agents/pi-embedded-runner/run/payloads.errors.test.ts index 4268e177dfc..764ee8330fd 100644 --- a/src/agents/pi-embedded-runner/run/payloads.errors.test.ts +++ b/src/agents/pi-embedded-runner/run/payloads.errors.test.ts @@ -101,6 +101,18 @@ describe("buildEmbeddedRunPayloads", () => { expect(payloads[0]?.isError).toBe(true); }); + it("does not emit a synthetic billing error for successful turns with stale errorMessage", () => { + const payloads = buildPayloads({ + lastAssistant: makeAssistant({ + stopReason: "end_turn", + errorMessage: "insufficient credits for embedding model", + content: [{ type: "text", text: "Handle payment required errors in your API." }], + }), + }); + + expectSinglePayloadText(payloads, "Handle payment required errors in your API."); + }); + it("suppresses raw error JSON even when errorMessage is missing", () => { const payloads = buildPayloads({ assistantTexts: [errorJsonPretty], diff --git a/src/agents/pi-embedded-runner/run/payloads.ts b/src/agents/pi-embedded-runner/run/payloads.ts index 16a78ec2e97..542bc44564b 100644 --- a/src/agents/pi-embedded-runner/run/payloads.ts +++ b/src/agents/pi-embedded-runner/run/payloads.ts @@ -128,16 +128,17 @@ export function buildEmbeddedRunPayloads(params: { const useMarkdown = params.toolResultFormat === "markdown"; const suppressAssistantArtifacts = params.didSendDeterministicApprovalPrompt === true; const lastAssistantErrored = params.lastAssistant?.stopReason === "error"; - const errorText = params.lastAssistant - ? suppressAssistantArtifacts - ? undefined - : formatAssistantErrorText(params.lastAssistant, { + const errorText = + params.lastAssistant && lastAssistantErrored + ? suppressAssistantArtifacts + ? undefined + : formatAssistantErrorText(params.lastAssistant, { cfg: params.config, sessionKey: params.sessionKey, provider: params.provider, model: params.model, }) - : undefined; + : undefined; const rawErrorMessage = lastAssistantErrored ? params.lastAssistant?.errorMessage?.trim() || undefined : undefined; diff --git a/src/agents/pi-embedded-utils.test.ts b/src/agents/pi-embedded-utils.test.ts index 1cf03bbea41..5b5529e2da6 100644 --- a/src/agents/pi-embedded-utils.test.ts +++ b/src/agents/pi-embedded-utils.test.ts @@ -139,6 +139,7 @@ describe("extractAssistantText", () => { const msg = makeAssistantMessage({ role: "assistant", errorMessage: "insufficient credits for embedding model", + stopReason: "end_turn", content: [{ type: "text", text: responseText }], timestamp: Date.now(), }); diff --git a/src/agents/tools/sessions.test.ts b/src/agents/tools/sessions.test.ts index aa831027f68..ce849e45d07 100644 --- a/src/agents/tools/sessions.test.ts +++ b/src/agents/tools/sessions.test.ts @@ -199,6 +199,16 @@ describe("extractAssistantText", () => { "Firebase downgraded us to the free Spark plan. Check whether billing should be re-enabled.", ); }); + + it("preserves successful turns with stale background errorMessage", () => { + const message = { + role: "assistant", + stopReason: "end_turn", + errorMessage: "insufficient credits for embedding model", + content: [{ type: "text", text: "Handle payment required errors in your API." }], + }; + expect(extractAssistantText(message)).toBe("Handle payment required errors in your API."); + }); }); describe("resolveAnnounceTarget", () => {