diff --git a/src/plugin-sdk/provider-stream-shared.test.ts b/src/plugin-sdk/provider-stream-shared.test.ts index 887ce6321c9b..6805810c8f1d 100644 --- a/src/plugin-sdk/provider-stream-shared.test.ts +++ b/src/plugin-sdk/provider-stream-shared.test.ts @@ -199,6 +199,43 @@ describe("createPayloadPatchStreamWrapper", () => { }); describe("createPlainTextToolCallCompatWrapper", () => { + it("emits sanitized errors when stream normalization sees hostile failures", async () => { + const hostileError = new Error("stream failed"); + Object.defineProperty(hostileError, "message", { + get() { + throw new Error("message denied"); + }, + }); + const baseStreamFn: StreamFn = () => + (async function* () { + yield* []; + throw hostileError; + })() as never; + const wrapped = createPlainTextToolCallCompatWrapper(baseStreamFn); + const events: unknown[] = []; + + for await (const event of wrapped( + {} as never, + { tools: [{ name: "read" }] } as never, + {}, + ) as AsyncIterable) { + events.push(event); + } + + expect(events).toEqual([ + { + type: "error", + reason: "error", + error: { + role: "assistant", + content: [], + stopReason: "error", + errorMessage: "Unknown provider stream error", + }, + }, + ]); + }); + it("promotes standalone text tool calls into tool-call stream events", async () => { const baseStreamFn: StreamFn = () => createEventStream([ diff --git a/src/plugin-sdk/provider-stream-shared.ts b/src/plugin-sdk/provider-stream-shared.ts index 537fef379924..32a9f00c21be 100644 --- a/src/plugin-sdk/provider-stream-shared.ts +++ b/src/plugin-sdk/provider-stream-shared.ts @@ -173,6 +173,17 @@ function normalizeProviderDoneMessage( return promotedMessage ? { kind: "promoted", message: promotedMessage } : undefined; } +function describeProviderStreamError(error: unknown): string { + try { + if (error instanceof Error) { + return error.message || error.name || "Unknown provider stream error"; + } + return String(error); + } catch { + return "Unknown provider stream error"; + } +} + function wrapPlainTextToolCallStream( source: ReturnType, context: Parameters[1], @@ -220,7 +231,7 @@ function wrapPlainTextToolCallStream( role: "assistant", content: [], stopReason: "error", - errorMessage: error instanceof Error ? error.message : String(error), + errorMessage: describeProviderStreamError(error), }, }); } finally {