

























@@ -88,6 +88,23 @@ function fetchRequestInit(mockFetch: { mock: { calls: Array<Array<unknown>> } },
8888return fetchCall(mockFetch, index)[1];
8989}
909091+function createBodyOnlyErrorResponse(params: { body: string; status: number }): Response {
92+const bytes = new TextEncoder().encode(params.body);
93+const body = new ReadableStream<Uint8Array>({
94+start(controller) {
95+controller.enqueue(bytes);
96+controller.close();
97+},
98+});
99+return {
100+ok: false,
101+status: params.status,
102+statusText: "Too Many Requests",
103+headers: new Headers(),
104+ body,
105+} as Response;
106+}
107+91108describe("brave web search provider", () => {
92109const priorFetch = global.fetch;
93110@@ -347,6 +364,66 @@ describe("brave web search provider", () => {
347364);
348365});
349366367+it("bounds Brave web error bodies without using response.text", async () => {
368+vi.stubEnv("BRAVE_API_KEY", "");
369+const mockFetch = vi.fn(async (_input?: unknown, _init?: unknown) =>
370+createBodyOnlyErrorResponse({
371+status: 429,
372+body: `${"x".repeat(24 * 1024)}tail-marker`,
373+}),
374+);
375+global.fetch = mockFetch as typeof global.fetch;
376+377+const provider = createBraveWebSearchProvider();
378+const tool = provider.createTool({
379+config: {},
380+searchConfig: {
381+apiKey: "brave-test-key",
382+brave: { mode: "web" },
383+},
384+});
385+if (!tool) {
386+throw new Error("Expected tool definition");
387+}
388+389+const error = await tool.execute({ query: "latest ai news" }).catch((value: unknown) => value);
390+expect(error).toBeInstanceOf(Error);
391+const message = error instanceof Error ? error.message : String(error);
392+expect(message).toContain("Brave Search API error (429):");
393+expect(message).not.toContain("tail-marker");
394+expect(message.length).toBeLessThan(700);
395+});
396+397+it("bounds Brave llm-context error bodies without using response.text", async () => {
398+vi.stubEnv("BRAVE_API_KEY", "");
399+const mockFetch = vi.fn(async (_input?: unknown, _init?: unknown) =>
400+createBodyOnlyErrorResponse({
401+status: 429,
402+body: `${"x".repeat(24 * 1024)}tail-marker`,
403+}),
404+);
405+global.fetch = mockFetch as typeof global.fetch;
406+407+const provider = createBraveWebSearchProvider();
408+const tool = provider.createTool({
409+config: {},
410+searchConfig: {
411+apiKey: "brave-test-key",
412+brave: { mode: "llm-context" },
413+},
414+});
415+if (!tool) {
416+throw new Error("Expected tool definition");
417+}
418+419+const error = await tool.execute({ query: "latest ai news" }).catch((value: unknown) => value);
420+expect(error).toBeInstanceOf(Error);
421+const message = error instanceof Error ? error.message : String(error);
422+expect(message).toContain("Brave LLM Context API error (429):");
423+expect(message).not.toContain("tail-marker");
424+expect(message.length).toBeLessThan(700);
425+});
426+350427it("keeps Brave cache entries isolated by baseUrl", async () => {
351428vi.stubEnv("BRAVE_API_KEY", "");
352429const mockFetch = vi.fn(async (_input?: unknown, _init?: unknown) => {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。