
























@@ -58,7 +58,14 @@ async function handleAgentEndAndReadWarnMeta(ctx: EmbeddedPiSubscribeContext) {
5858const warn = vi.mocked(ctx.log.warn);
5959expect(warn).toHaveBeenCalledTimes(1);
6060expect(warn.mock.calls[0]?.[0]).toBe("embedded run agent end");
61-return warn.mock.calls[0]?.[1];
61+return readRecord(warn.mock.calls[0]?.[1]);
62+}
63+64+function readRecord(value: unknown): Record<string, unknown> {
65+if (!value || typeof value !== "object") {
66+throw new Error("expected metadata record");
67+}
68+return value as Record<string, unknown>;
6269}
63706471describe("handleAgentEnd", () => {
@@ -76,15 +83,14 @@ describe("handleAgentEnd", () => {
7683ctx.state.livenessState = "working";
77847885const warnMeta = await handleAgentEndAndReadWarnMeta(ctx);
79-expect(warnMeta).toMatchObject({
80-event: "embedded_run_agent_end",
81-runId: "run-1",
82-error: "LLM request failed: connection refused by the provider endpoint.",
83-providerRuntimeFailureKind: "timeout",
84-rawErrorPreview: "connection refused",
85-consoleMessage:
86-"embedded run agent end: runId=run-1 isError=true model=unknown provider=unknown error=LLM request failed: connection refused by the provider endpoint. rawError=connection refused",
87-});
86+expect(warnMeta.event).toBe("embedded_run_agent_end");
87+expect(warnMeta.runId).toBe("run-1");
88+expect(warnMeta.error).toBe("LLM request failed: connection refused by the provider endpoint.");
89+expect(warnMeta.providerRuntimeFailureKind).toBe("timeout");
90+expect(warnMeta.rawErrorPreview).toBe("connection refused");
91+expect(warnMeta.consoleMessage).toBe(
92+"embedded run agent end: runId=run-1 isError=true model=unknown provider=unknown error=LLM request failed: connection refused by the provider endpoint. rawError=connection refused",
93+);
8894expect(onAgentEvent).toHaveBeenCalledWith({
8995stream: "lifecycle",
9096data: {
@@ -106,16 +112,17 @@ describe("handleAgentEnd", () => {
106112});
107113108114const warnMeta = await handleAgentEndAndReadWarnMeta(ctx);
109-expect(warnMeta).toMatchObject({
110-event: "embedded_run_agent_end",
111-runId: "run-1",
112-error: "The AI service is temporarily overloaded. Please try again in a moment.",
113-failoverReason: "overloaded",
114-providerRuntimeFailureKind: "timeout",
115-providerErrorType: "overloaded_error",
116-consoleMessage:
117-'embedded run agent end: runId=run-1 isError=true model=claude-test provider=anthropic error=The AI service is temporarily overloaded. Please try again in a moment. rawError={"type":"error","error":{"type":"overloaded_error","message":"Overloaded"}}',
118-});
115+expect(warnMeta.event).toBe("embedded_run_agent_end");
116+expect(warnMeta.runId).toBe("run-1");
117+expect(warnMeta.error).toBe(
118+"The AI service is temporarily overloaded. Please try again in a moment.",
119+);
120+expect(warnMeta.failoverReason).toBe("overloaded");
121+expect(warnMeta.providerRuntimeFailureKind).toBe("timeout");
122+expect(warnMeta.providerErrorType).toBe("overloaded_error");
123+expect(warnMeta.consoleMessage).toBe(
124+'embedded run agent end: runId=run-1 isError=true model=claude-test provider=anthropic error=The AI service is temporarily overloaded. Please try again in a moment. rawError={"type":"error","error":{"type":"overloaded_error","message":"Overloaded"}}',
125+);
119126});
120127121128it("sanitizes model and provider before writing consoleMessage", async () => {
@@ -131,11 +138,10 @@ describe("handleAgentEnd", () => {
131138await handleAgentEnd(ctx);
132139133140const warn = vi.mocked(ctx.log.warn);
134-const meta = warn.mock.calls[0]?.[1];
135-expect(meta).toMatchObject({
136-consoleMessage:
137-"embedded run agent end: runId=run-1 isError=true model=claude sonnet 4 provider=anthropic]8;;https://evil.test error=LLM request failed: connection refused by the provider endpoint. rawError=connection refused",
138-});
141+const meta = readRecord(warn.mock.calls[0]?.[1]);
142+expect(meta.consoleMessage).toBe(
143+"embedded run agent end: runId=run-1 isError=true model=claude sonnet 4 provider=anthropic]8;;https://evil.test error=LLM request failed: connection refused by the provider endpoint. rawError=connection refused",
144+);
139145expect(meta?.consoleMessage).not.toContain("\n");
140146expect(meta?.consoleMessage).not.toContain("\r");
141147expect(meta?.consoleMessage).not.toContain("\t");
@@ -157,11 +163,10 @@ describe("handleAgentEnd", () => {
157163await handleAgentEnd(ctx);
158164159165const warn = vi.mocked(ctx.log.warn);
160-expect(warn.mock.calls[0]?.[1]).toMatchObject({
161-event: "embedded_run_agent_end",
162-error: "x-api-key: ***",
163-rawErrorPreview: "x-api-key: ***",
164-});
166+const meta = readRecord(warn.mock.calls[0]?.[1]);
167+expect(meta.event).toBe("embedded_run_agent_end");
168+expect(meta.error).toBe("x-api-key: ***");
169+expect(meta.rawErrorPreview).toBe("x-api-key: ***");
165170expect(onAgentEvent).toHaveBeenCalledWith({
166171stream: "lifecycle",
167172data: {
@@ -184,11 +189,10 @@ describe("handleAgentEnd", () => {
184189185190await handleAgentEnd(ctx);
186191187-expect(vi.mocked(ctx.log.warn).mock.calls[0]?.[1]).toMatchObject({
188-failoverReason: "auth",
189-providerRuntimeFailureKind: "auth_scope",
190-httpCode: "401",
191-});
192+const meta = readRecord(vi.mocked(ctx.log.warn).mock.calls[0]?.[1]);
193+expect(meta.failoverReason).toBe("auth");
194+expect(meta.providerRuntimeFailureKind).toBe("auth_scope");
195+expect(meta.httpCode).toBe("401");
192196});
193197194198it("omits raw HTML auth bodies from consoleMessage for HTML 403 auth failures", async () => {
@@ -204,13 +208,13 @@ describe("handleAgentEnd", () => {
204208await handleAgentEnd(ctx);
205209206210const warnMeta = vi.mocked(ctx.log.warn).mock.calls[0]?.[1];
207-expect(warnMeta).toMatchObject({
208- providerRuntimeFailureKind: "auth_html_403",
209- rawErrorPreview: "403 <!DOCTYPE html><html><body>Access denied</body></html>",
210- error:
211- "Authentication failed with an HTML 403 response from the provider. Re-authenticate and verify your provider account access.",
212-});
213-const consoleMsg = typeof warnMeta?.consoleMessage === "string" ? warnMeta.consoleMessage : "";
211+const meta = readRecord(warnMeta);
212+expect(meta.providerRuntimeFailureKind).toBe("auth_html_403");
213+expect(meta.rawErrorPreview).toBe("403 <!DOCTYPE html><html><body>Access denied</body></html>");
214+expect(meta.error).toBe(
215+"Authentication failed with an HTML 403 response from the provider. Re-authenticate and verify your provider account access.",
216+);
217+const consoleMsg = typeof meta.consoleMessage === "string" ? meta.consoleMessage : "";
214218expect(consoleMsg).not.toContain("rawError=");
215219expect(consoleMsg).not.toContain("<html>");
216220});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。