@vacbo/opencode-anthropic-fix 0.0.44 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/README.md +19 -0
  2. package/dist/bun-proxy.mjs +282 -55
  3. package/dist/opencode-anthropic-auth-cli.mjs +194 -55
  4. package/dist/opencode-anthropic-auth-plugin.js +1816 -594
  5. package/package.json +1 -1
  6. package/src/__tests__/billing-edge-cases.test.ts +84 -0
  7. package/src/__tests__/bun-proxy.parallel.test.ts +460 -0
  8. package/src/__tests__/debug-gating.test.ts +76 -0
  9. package/src/__tests__/decomposition-smoke.test.ts +92 -0
  10. package/src/__tests__/fingerprint-regression.test.ts +1 -1
  11. package/src/__tests__/helpers/conversation-history.smoke.test.ts +338 -0
  12. package/src/__tests__/helpers/conversation-history.ts +376 -0
  13. package/src/__tests__/helpers/deferred.smoke.test.ts +161 -0
  14. package/src/__tests__/helpers/deferred.ts +122 -0
  15. package/src/__tests__/helpers/in-memory-storage.smoke.test.ts +166 -0
  16. package/src/__tests__/helpers/in-memory-storage.ts +152 -0
  17. package/src/__tests__/helpers/mock-bun-proxy.smoke.test.ts +92 -0
  18. package/src/__tests__/helpers/mock-bun-proxy.ts +229 -0
  19. package/src/__tests__/helpers/plugin-fetch-harness.smoke.test.ts +337 -0
  20. package/src/__tests__/helpers/plugin-fetch-harness.ts +401 -0
  21. package/src/__tests__/helpers/sse.smoke.test.ts +243 -0
  22. package/src/__tests__/helpers/sse.ts +288 -0
  23. package/src/__tests__/index.parallel.test.ts +711 -0
  24. package/src/__tests__/sanitization-regex.test.ts +65 -0
  25. package/src/__tests__/state-bounds.test.ts +110 -0
  26. package/src/account-identity.test.ts +213 -0
  27. package/src/account-identity.ts +108 -0
  28. package/src/accounts.dedup.test.ts +696 -0
  29. package/src/accounts.test.ts +2 -1
  30. package/src/accounts.ts +485 -191
  31. package/src/bun-fetch.test.ts +379 -0
  32. package/src/bun-fetch.ts +447 -174
  33. package/src/bun-proxy.ts +289 -57
  34. package/src/circuit-breaker.test.ts +274 -0
  35. package/src/circuit-breaker.ts +235 -0
  36. package/src/cli.test.ts +1 -0
  37. package/src/cli.ts +37 -18
  38. package/src/commands/router.ts +25 -5
  39. package/src/env.ts +1 -0
  40. package/src/headers/billing.ts +31 -13
  41. package/src/index.ts +224 -247
  42. package/src/oauth.ts +7 -1
  43. package/src/parent-pid-watcher.test.ts +219 -0
  44. package/src/parent-pid-watcher.ts +99 -0
  45. package/src/plugin-helpers.ts +112 -0
  46. package/src/refresh-helpers.ts +169 -0
  47. package/src/refresh-lock.test.ts +36 -9
  48. package/src/refresh-lock.ts +2 -2
  49. package/src/request/body.history.test.ts +398 -0
  50. package/src/request/body.ts +200 -13
  51. package/src/request/metadata.ts +6 -2
  52. package/src/response/index.ts +1 -1
  53. package/src/response/mcp.ts +60 -31
  54. package/src/response/streaming.test.ts +382 -0
  55. package/src/response/streaming.ts +403 -76
  56. package/src/storage.test.ts +127 -104
  57. package/src/storage.ts +152 -62
  58. package/src/system-prompt/builder.ts +33 -3
  59. package/src/system-prompt/sanitize.ts +12 -2
  60. package/src/token-refresh.test.ts +84 -1
  61. package/src/token-refresh.ts +14 -8
@@ -0,0 +1,711 @@
1
+ import { afterEach, beforeEach, describe, expect, it, vi, type Mock } from "vitest";
2
+
3
+ import { createDeferred, createDeferredQueue, nextTick } from "./helpers/deferred.js";
4
+ import { clearMockAccounts, createFetchHarness } from "./helpers/plugin-fetch-harness.js";
5
+ import {
6
+ contentBlockStartEvent,
7
+ contentBlockStopEvent,
8
+ encodeSSEStream,
9
+ makeSSEResponse,
10
+ messageDeltaEvent,
11
+ messageStartEvent,
12
+ messageStopEvent,
13
+ } from "./helpers/sse.js";
14
+
15
+ vi.mock("node:readline/promises", () => ({
16
+ createInterface: vi.fn(() => ({
17
+ question: vi.fn().mockResolvedValue("a"),
18
+ close: vi.fn(),
19
+ })),
20
+ }));
21
+
22
+ vi.mock("../storage.js", () => ({
23
+ createDefaultStats: (now?: number) => ({
24
+ requests: 0,
25
+ inputTokens: 0,
26
+ outputTokens: 0,
27
+ cacheReadTokens: 0,
28
+ cacheWriteTokens: 0,
29
+ lastReset: now ?? Date.now(),
30
+ }),
31
+ loadAccounts: vi.fn().mockResolvedValue(null),
32
+ saveAccounts: vi.fn().mockResolvedValue(undefined),
33
+ clearAccounts: vi.fn().mockResolvedValue(undefined),
34
+ getStoragePath: vi.fn(() => "/tmp/test-accounts.json"),
35
+ }));
36
+
37
+ vi.mock("../config.js", () => {
38
+ const DEFAULT_CONFIG = {
39
+ account_selection_strategy: "sticky",
40
+ failure_ttl_seconds: 3600,
41
+ debug: false,
42
+ signature_emulation: {
43
+ enabled: true,
44
+ fetch_claude_code_version_on_startup: false,
45
+ prompt_compaction: "minimal",
46
+ },
47
+ override_model_limits: {
48
+ enabled: false,
49
+ context: 1_000_000,
50
+ output: 0,
51
+ },
52
+ custom_betas: [],
53
+ health_score: {
54
+ initial: 70,
55
+ success_reward: 1,
56
+ rate_limit_penalty: -10,
57
+ failure_penalty: -20,
58
+ recovery_rate_per_hour: 2,
59
+ min_usable: 50,
60
+ max_score: 100,
61
+ },
62
+ token_bucket: {
63
+ max_tokens: 50,
64
+ regeneration_rate_per_minute: 6,
65
+ initial_tokens: 50,
66
+ },
67
+ toasts: {
68
+ quiet: true,
69
+ debounce_seconds: 30,
70
+ },
71
+ headers: {},
72
+ idle_refresh: {
73
+ enabled: false,
74
+ window_minutes: 60,
75
+ min_interval_minutes: 30,
76
+ },
77
+ cc_credential_reuse: {
78
+ enabled: false,
79
+ auto_detect: false,
80
+ prefer_over_oauth: false,
81
+ },
82
+ };
83
+
84
+ const createBaseConfig = () => ({
85
+ ...DEFAULT_CONFIG,
86
+ signature_emulation: { ...DEFAULT_CONFIG.signature_emulation },
87
+ override_model_limits: { ...DEFAULT_CONFIG.override_model_limits },
88
+ custom_betas: [...DEFAULT_CONFIG.custom_betas],
89
+ health_score: { ...DEFAULT_CONFIG.health_score },
90
+ token_bucket: { ...DEFAULT_CONFIG.token_bucket },
91
+ toasts: { ...DEFAULT_CONFIG.toasts },
92
+ headers: { ...DEFAULT_CONFIG.headers },
93
+ idle_refresh: { ...DEFAULT_CONFIG.idle_refresh },
94
+ cc_credential_reuse: { ...DEFAULT_CONFIG.cc_credential_reuse },
95
+ });
96
+
97
+ return {
98
+ CLIENT_ID: "9d1c250a-e61b-44d9-88ed-5944d1962f5e",
99
+ DEFAULT_CONFIG,
100
+ VALID_STRATEGIES: ["sticky", "round-robin", "hybrid"],
101
+ loadConfig: vi.fn(() => createBaseConfig()),
102
+ loadConfigFresh: vi.fn(() => createBaseConfig()),
103
+ saveConfig: vi.fn(),
104
+ getConfigDir: vi.fn(() => "/tmp/test-config"),
105
+ };
106
+ });
107
+
108
+ vi.mock("../cc-credentials.js", () => ({
109
+ readCCCredentials: vi.fn(() => []),
110
+ }));
111
+
112
+ vi.mock("../refresh-lock.js", () => ({
113
+ acquireRefreshLock: vi.fn().mockResolvedValue({
114
+ acquired: true,
115
+ lockPath: "/tmp/opencode-test.lock",
116
+ owner: null,
117
+ lockInode: null,
118
+ }),
119
+ releaseRefreshLock: vi.fn().mockResolvedValue(undefined),
120
+ }));
121
+
122
+ vi.mock("../oauth.js", () => ({
123
+ authorize: vi.fn(),
124
+ exchange: vi.fn(),
125
+ refreshToken: vi.fn(),
126
+ }));
127
+
128
+ vi.mock("@clack/prompts", () => {
129
+ const noop = vi.fn();
130
+ return {
131
+ text: vi.fn().mockResolvedValue(""),
132
+ confirm: vi.fn().mockResolvedValue(false),
133
+ select: vi.fn().mockResolvedValue("cancel"),
134
+ spinner: vi.fn(() => ({ start: noop, stop: noop, message: noop })),
135
+ intro: noop,
136
+ outro: noop,
137
+ isCancel: vi.fn().mockReturnValue(false),
138
+ log: {
139
+ info: noop,
140
+ success: noop,
141
+ warn: noop,
142
+ error: noop,
143
+ message: noop,
144
+ step: noop,
145
+ },
146
+ note: noop,
147
+ cancel: noop,
148
+ };
149
+ });
150
+
151
+ import { refreshToken } from "../oauth.js";
152
+
153
+ const mockRefreshToken = refreshToken as Mock;
154
+
155
+ function jsonResponse(payload: unknown, init: ResponseInit = {}): Response {
156
+ return new Response(JSON.stringify(payload), {
157
+ status: init.status ?? 200,
158
+ headers: {
159
+ "content-type": "application/json",
160
+ ...(init.headers as Record<string, string> | undefined),
161
+ },
162
+ });
163
+ }
164
+
165
+ function rateLimitResponse(message = "rate limit exceeded"): Response {
166
+ return jsonResponse(
167
+ {
168
+ error: {
169
+ type: "rate_limit_error",
170
+ message,
171
+ },
172
+ },
173
+ { status: 429 },
174
+ );
175
+ }
176
+
177
+ function makeRequestBody(
178
+ options: {
179
+ toolName?: string;
180
+ historicalToolName?: string;
181
+ text?: string;
182
+ } = {},
183
+ ): string {
184
+ const messages: Array<Record<string, unknown>> = [];
185
+
186
+ if (options.historicalToolName) {
187
+ messages.push({
188
+ role: "assistant",
189
+ content: [
190
+ {
191
+ type: "tool_use",
192
+ id: `tool_${options.historicalToolName}`,
193
+ name: options.historicalToolName,
194
+ input: { from: options.text ?? "history" },
195
+ },
196
+ ],
197
+ });
198
+ }
199
+
200
+ messages.push({
201
+ role: "user",
202
+ content: options.text ?? "parallel test",
203
+ });
204
+
205
+ return JSON.stringify({
206
+ model: "claude-sonnet",
207
+ max_tokens: 128,
208
+ messages,
209
+ ...(options.toolName
210
+ ? {
211
+ tools: [
212
+ {
213
+ name: options.toolName,
214
+ description: "Parallel test tool",
215
+ input_schema: {
216
+ type: "object",
217
+ properties: {
218
+ id: { type: "number" },
219
+ },
220
+ },
221
+ },
222
+ ],
223
+ }
224
+ : {}),
225
+ });
226
+ }
227
+
228
+ function parseSentBody(call: unknown[]): Record<string, any> {
229
+ const init = call[1] as RequestInit | undefined;
230
+ if (typeof init?.body !== "string") {
231
+ throw new Error(`Expected string body, received ${typeof init?.body}`);
232
+ }
233
+ return JSON.parse(init.body);
234
+ }
235
+
236
+ function callHeaders(call: unknown[]): Headers {
237
+ const init = call[1] as RequestInit | undefined;
238
+ return new Headers(init?.headers as HeadersInit | undefined);
239
+ }
240
+
241
+ function callUrl(call: unknown[]): string {
242
+ const input = call[0];
243
+ if (typeof input === "string") return input;
244
+ if (input instanceof URL) return input.toString();
245
+ if (input instanceof Request) return input.url;
246
+ return String(input);
247
+ }
248
+
249
+ function makeToolUseSseResponse(prefixedName: string): Response {
250
+ return makeSSEResponse(
251
+ encodeSSEStream([
252
+ messageStartEvent(),
253
+ contentBlockStartEvent(0, {
254
+ content_block: {
255
+ type: "tool_use",
256
+ id: "tool_stream_1",
257
+ name: prefixedName,
258
+ input: { ok: true },
259
+ },
260
+ }),
261
+ contentBlockStopEvent(0),
262
+ messageDeltaEvent({
263
+ delta: { stop_reason: "tool_use", stop_sequence: null },
264
+ usage: { output_tokens: 1 },
265
+ }),
266
+ messageStopEvent(),
267
+ ]),
268
+ );
269
+ }
270
+
271
+ describe("index.parallel RED", () => {
272
+ beforeEach(() => {
273
+ clearMockAccounts();
274
+ vi.clearAllMocks();
275
+ mockRefreshToken.mockResolvedValue({
276
+ access_token: "access-default-refresh",
277
+ expires_in: 3600,
278
+ refresh_token: "refresh-default-refresh",
279
+ });
280
+ });
281
+
282
+ afterEach(() => {
283
+ clearMockAccounts();
284
+ });
285
+
286
+ it("intercepts 50 concurrent requests without double-prefixing historical tool definitions", async () => {
287
+ const harness = await createFetchHarness();
288
+ const queue = createDeferredQueue<Response>();
289
+
290
+ harness.mockFetch.mockImplementation(() => queue.enqueue().promise);
291
+
292
+ const requests = Array.from({ length: 50 }, (_, index) =>
293
+ harness.fetch("https://api.anthropic.com/v1/messages", {
294
+ method: "POST",
295
+ headers: { "content-type": "application/json" },
296
+ body: makeRequestBody({
297
+ toolName: `mcp_parallel_tool_${index}`,
298
+ text: `fan-out-${index}`,
299
+ }),
300
+ }),
301
+ );
302
+
303
+ await harness.waitFor(() => expect(queue.pending).toBe(50), 1000);
304
+
305
+ for (let index = 0; index < 50; index += 1) {
306
+ queue.resolveNext(jsonResponse({ id: `msg_${index}`, content: [{ type: "text", text: `ok-${index}` }] }));
307
+ }
308
+
309
+ const responses = await Promise.all(requests);
310
+ await Promise.all(responses.map((response) => response.json()));
311
+
312
+ const sentBodies = harness.mockFetch.mock.calls.map((call) => parseSentBody(call));
313
+ sentBodies.forEach((body, index) => {
314
+ expect(body.tools[0].name).toBe(`mcp_mcp_parallel_tool_${index}`);
315
+ });
316
+
317
+ harness.tearDown();
318
+ });
319
+
320
+ it("keeps per-request tool definition state isolated under concurrent mixed prefix load", async () => {
321
+ const harness = await createFetchHarness();
322
+ const toolNames = [
323
+ "read_file",
324
+ "mcp_existing_read",
325
+ "write_file",
326
+ "mcp_existing_write",
327
+ "list_files",
328
+ "mcp_existing_list",
329
+ ];
330
+
331
+ harness.mockFetch.mockImplementation(() => jsonResponse({ id: "msg_mixed", content: [] }));
332
+
333
+ await Promise.all(
334
+ toolNames.map((toolName) =>
335
+ harness.fetch("https://api.anthropic.com/v1/messages", {
336
+ method: "POST",
337
+ headers: { "content-type": "application/json" },
338
+ body: makeRequestBody({ toolName, text: toolName }),
339
+ }),
340
+ ),
341
+ );
342
+
343
+ const transformedNames = harness.mockFetch.mock.calls.map((call) => parseSentBody(call).tools[0].name);
344
+ expect(transformedNames).toEqual([
345
+ "mcp_read_file",
346
+ "mcp_mcp_existing_read",
347
+ "mcp_write_file",
348
+ "mcp_mcp_existing_write",
349
+ "mcp_list_files",
350
+ "mcp_mcp_existing_list",
351
+ ]);
352
+
353
+ harness.tearDown();
354
+ });
355
+
356
+ it("keeps historical tool_use blocks isolated under concurrent request fan-out", async () => {
357
+ const harness = await createFetchHarness();
358
+
359
+ harness.mockFetch.mockImplementation(() => jsonResponse({ id: "msg_history", content: [] }));
360
+
361
+ await Promise.all(
362
+ Array.from({ length: 12 }, (_, index) =>
363
+ harness.fetch("https://api.anthropic.com/v1/messages", {
364
+ method: "POST",
365
+ headers: { "content-type": "application/json" },
366
+ body: makeRequestBody({
367
+ historicalToolName: `mcp_history_tool_${index}`,
368
+ text: `history-${index}`,
369
+ }),
370
+ }),
371
+ ),
372
+ );
373
+
374
+ const transformedNames = harness.mockFetch.mock.calls.map(
375
+ (call) => parseSentBody(call).messages[0].content[0].name,
376
+ );
377
+ transformedNames.forEach((name, index) => {
378
+ expect(name).toBe(`mcp_history_tool_${index}`);
379
+ });
380
+
381
+ harness.tearDown();
382
+ });
383
+
384
+ it("clones Request input bodies before service-wide retries", async () => {
385
+ const harness = await createFetchHarness();
386
+
387
+ harness.mockFetch
388
+ .mockResolvedValueOnce(new Response("temporary outage", { status: 503 }))
389
+ .mockResolvedValueOnce(jsonResponse({ id: "msg_retry", content: [] }));
390
+
391
+ const request = new Request("https://api.anthropic.com/v1/messages", {
392
+ method: "POST",
393
+ headers: { "content-type": "application/json" },
394
+ body: makeRequestBody({ toolName: "mcp_retry_body" }),
395
+ });
396
+
397
+ const response = await harness.fetch(request);
398
+ await response.json();
399
+
400
+ const firstInit = harness.mockFetch.mock.calls[0]?.[1] as RequestInit | undefined;
401
+ const secondInit = harness.mockFetch.mock.calls[1]?.[1] as RequestInit | undefined;
402
+
403
+ expect(typeof firstInit?.body).toBe("string");
404
+ expect(firstInit?.body).toBe(secondInit?.body);
405
+
406
+ harness.tearDown();
407
+ });
408
+
409
+ it("preserves each concurrent Request body independently across retry fan-out", async () => {
410
+ const harness = await createFetchHarness();
411
+ const attempts = new Map<string, number>();
412
+
413
+ harness.mockFetch.mockImplementation((input) => {
414
+ const url = typeof input === "string" ? input : input instanceof Request ? input.url : input.toString();
415
+ const attempt = attempts.get(url) ?? 0;
416
+ attempts.set(url, attempt + 1);
417
+
418
+ if (attempt === 0) {
419
+ return Promise.resolve(new Response("try again", { status: 503 }));
420
+ }
421
+
422
+ return Promise.resolve(jsonResponse({ id: `ok:${url}`, content: [] }));
423
+ });
424
+
425
+ const requests = Array.from({ length: 10 }, (_, index) =>
426
+ harness.fetch(
427
+ new Request(`https://api.anthropic.com/v1/messages?retry=${index}`, {
428
+ method: "POST",
429
+ headers: { "content-type": "application/json" },
430
+ body: makeRequestBody({ toolName: `mcp_retry_parallel_${index}` }),
431
+ }),
432
+ ),
433
+ );
434
+
435
+ const responses = await Promise.all(requests);
436
+ await Promise.all(responses.map((response) => response.json()));
437
+
438
+ for (let index = 0; index < 10; index += 1) {
439
+ const callsForUrl = harness.mockFetch.mock.calls.filter((call) => callUrl(call).includes(`retry=${index}`));
440
+ expect(callsForUrl).toHaveLength(2);
441
+ callsForUrl.forEach((call) => {
442
+ const init = call[1] as RequestInit | undefined;
443
+ expect(typeof init?.body).toBe("string");
444
+ });
445
+ }
446
+
447
+ harness.tearDown();
448
+ });
449
+
450
+ it("rotates accounts under concurrent 429 load without tool-prefix drift", async () => {
451
+ const harness = await createFetchHarness({
452
+ accounts: [
453
+ { email: "first@example.com", access: "access-1", refreshToken: "refresh-1", expires: Date.now() + 60_000 },
454
+ { email: "second@example.com", access: "access-2", refreshToken: "refresh-2", expires: Date.now() + 60_000 },
455
+ ],
456
+ });
457
+
458
+ harness.mockFetch.mockImplementation((_input, init) => {
459
+ const headers = new Headers(init?.headers as HeadersInit | undefined);
460
+ const auth = headers.get("authorization");
461
+ if (auth === "Bearer access-1") {
462
+ return Promise.resolve(rateLimitResponse());
463
+ }
464
+ return Promise.resolve(jsonResponse({ id: "msg_rotated", content: [] }));
465
+ });
466
+
467
+ const responses = await Promise.all(
468
+ Array.from({ length: 12 }, (_, index) =>
469
+ harness.fetch("https://api.anthropic.com/v1/messages", {
470
+ method: "POST",
471
+ headers: { "content-type": "application/json" },
472
+ body: makeRequestBody({ toolName: `mcp_rotation_tool_${index}` }),
473
+ }),
474
+ ),
475
+ );
476
+ await Promise.all(responses.map((response) => response.json()));
477
+
478
+ const successfulRotations = harness.mockFetch.mock.calls.filter(
479
+ (call) => callHeaders(call).get("authorization") !== "Bearer access-1",
480
+ );
481
+
482
+ expect(successfulRotations).toHaveLength(12);
483
+ successfulRotations.forEach((call) => {
484
+ expect(parseSentBody(call).tools[0].name).not.toMatch(/^mcp_mcp_mcp_/);
485
+ });
486
+
487
+ harness.tearDown();
488
+ });
489
+
490
+ it("shares one refresh across concurrent requests without cross-request contamination", async () => {
491
+ const harness = await createFetchHarness({
492
+ accounts: [
493
+ {
494
+ email: "refresh@example.com",
495
+ access: "",
496
+ refreshToken: "refresh-stale",
497
+ expires: Date.now() - 1_000,
498
+ },
499
+ ],
500
+ });
501
+ const refreshDeferred = createDeferred<{
502
+ access_token: string;
503
+ expires_in: number;
504
+ refresh_token: string;
505
+ }>();
506
+
507
+ mockRefreshToken.mockReturnValue(refreshDeferred.promise);
508
+ harness.mockFetch.mockImplementation(() => jsonResponse({ id: "msg_refresh", content: [] }));
509
+
510
+ const requests = Array.from({ length: 10 }, (_, index) =>
511
+ harness.fetch("https://api.anthropic.com/v1/messages", {
512
+ method: "POST",
513
+ headers: { "content-type": "application/json" },
514
+ body: makeRequestBody({ toolName: `mcp_refresh_tool_${index}` }),
515
+ }),
516
+ );
517
+
518
+ await harness.waitFor(() => expect(mockRefreshToken).toHaveBeenCalledTimes(1), 1000);
519
+
520
+ refreshDeferred.resolve({
521
+ access_token: "access-fresh",
522
+ expires_in: 3600,
523
+ refresh_token: "refresh-fresh",
524
+ });
525
+
526
+ const responses = await Promise.all(requests);
527
+ await Promise.all(responses.map((response) => response.json()));
528
+
529
+ harness.mockFetch.mock.calls.forEach((call, index) => {
530
+ expect(callHeaders(call).get("authorization")).toBe("Bearer access-fresh");
531
+ expect(parseSentBody(call).tools[0].name).toBe(`mcp_mcp_refresh_tool_${index}`);
532
+ });
533
+
534
+ harness.tearDown();
535
+ });
536
+
537
+ it("keeps SSE and JSON tool-name rewriting consistent when both run concurrently", async () => {
538
+ const harness = await createFetchHarness();
539
+
540
+ harness.mockFetch.mockImplementation((input) => {
541
+ const url = typeof input === "string" ? input : input instanceof Request ? input.url : input.toString();
542
+ if (url.includes("stream")) {
543
+ return Promise.resolve(makeToolUseSseResponse("mcp_parallel_stream"));
544
+ }
545
+ return Promise.resolve(
546
+ jsonResponse({
547
+ content: [{ type: "tool_use", name: "mcp_parallel_json", input: { ok: true } }],
548
+ }),
549
+ );
550
+ });
551
+
552
+ const [streamResponse, jsonResponseValue] = await Promise.all([
553
+ harness.fetch("https://api.anthropic.com/v1/messages/stream", {
554
+ method: "POST",
555
+ headers: { "content-type": "application/json" },
556
+ body: makeRequestBody({ toolName: "mcp_parallel_stream" }),
557
+ }),
558
+ harness.fetch("https://api.anthropic.com/v1/messages/json", {
559
+ method: "POST",
560
+ headers: { "content-type": "application/json" },
561
+ body: makeRequestBody({ toolName: "mcp_parallel_json" }),
562
+ }),
563
+ ]);
564
+
565
+ const [streamText, jsonPayload] = await Promise.all([streamResponse.text(), jsonResponseValue.json()]);
566
+
567
+ expect(streamText).toContain('"name":"parallel_stream"');
568
+ expect(streamText).not.toContain('"name":"mcp_parallel_stream"');
569
+ expect(jsonPayload.content[0].name).toBe("parallel_json");
570
+
571
+ harness.tearDown();
572
+ });
573
+
574
+ it("does not leak one request error into sibling concurrent requests", async () => {
575
+ const harness = await createFetchHarness();
576
+
577
+ harness.mockFetch.mockImplementation((input) => {
578
+ const url = typeof input === "string" ? input : input instanceof Request ? input.url : input.toString();
579
+ if (url.includes("explode")) {
580
+ return Promise.reject(new Error("socket reset"));
581
+ }
582
+ return Promise.resolve(jsonResponse({ id: "msg_ok", content: [] }));
583
+ });
584
+
585
+ const [failed, succeeded] = await Promise.allSettled([
586
+ harness.fetch("https://api.anthropic.com/v1/messages/explode", {
587
+ method: "POST",
588
+ headers: { "content-type": "application/json" },
589
+ body: makeRequestBody({ toolName: "mcp_fail_tool" }),
590
+ }),
591
+ harness.fetch("https://api.anthropic.com/v1/messages/ok", {
592
+ method: "POST",
593
+ headers: { "content-type": "application/json" },
594
+ body: makeRequestBody({ toolName: "mcp_ok_tool" }),
595
+ }),
596
+ ]);
597
+
598
+ expect(failed.status).toBe("rejected");
599
+ expect(succeeded.status).toBe("fulfilled");
600
+
601
+ if (succeeded.status === "fulfilled") {
602
+ await succeeded.value.json();
603
+ }
604
+
605
+ const successCall = harness.mockFetch.mock.calls.find((call) => callUrl(call).includes("/ok"));
606
+ expect(successCall).toBeDefined();
607
+ expect(parseSentBody(successCall!).tools[0].name).toBe("mcp_mcp_ok_tool");
608
+
609
+ harness.tearDown();
610
+ });
611
+
612
+ it("does not mutate shared request payloads across concurrent batches", async () => {
613
+ const harness = await createFetchHarness();
614
+ const sharedBody = makeRequestBody({ toolName: "mcp_shared_tool", text: "shared" });
615
+
616
+ harness.mockFetch.mockImplementation(() => jsonResponse({ id: "msg_shared", content: [] }));
617
+
618
+ const firstWave = Array.from({ length: 20 }, () =>
619
+ harness.fetch("https://api.anthropic.com/v1/messages", {
620
+ method: "POST",
621
+ headers: { "content-type": "application/json" },
622
+ body: sharedBody,
623
+ }),
624
+ );
625
+
626
+ await Promise.all(firstWave);
627
+
628
+ const followUp = await harness.fetch("https://api.anthropic.com/v1/messages", {
629
+ method: "POST",
630
+ headers: { "content-type": "application/json" },
631
+ body: sharedBody,
632
+ });
633
+ await followUp.json();
634
+
635
+ const lastSharedCall = harness.mockFetch.mock.calls[harness.mockFetch.mock.calls.length - 1];
636
+
637
+ expect(JSON.parse(sharedBody).tools[0].name).toBe("mcp_shared_tool");
638
+ expect(parseSentBody(lastSharedCall).tools[0].name).toBe("mcp_mcp_shared_tool");
639
+
640
+ harness.tearDown();
641
+ });
642
+
643
+ it("cleans up retry bookkeeping after each request", async () => {
644
+ const harness = await createFetchHarness();
645
+ let firstRetryAttempt = true;
646
+
647
+ harness.mockFetch.mockImplementation((input) => {
648
+ const url = typeof input === "string" ? input : input instanceof Request ? input.url : input.toString();
649
+ if (url.includes("retry-once") && firstRetryAttempt) {
650
+ firstRetryAttempt = false;
651
+ return Promise.resolve(new Response("temporary outage", { status: 503 }));
652
+ }
653
+ return Promise.resolve(jsonResponse({ id: `msg:${url}`, content: [] }));
654
+ });
655
+
656
+ const retried = await harness.fetch("https://api.anthropic.com/v1/messages/retry-once", {
657
+ method: "POST",
658
+ headers: { "content-type": "application/json" },
659
+ body: makeRequestBody({ toolName: "mcp_retry_cleanup" }),
660
+ });
661
+ await retried.json();
662
+
663
+ const clean = await harness.fetch("https://api.anthropic.com/v1/messages/clean", {
664
+ method: "POST",
665
+ headers: { "content-type": "application/json" },
666
+ body: makeRequestBody({ toolName: "mcp_clean_followup" }),
667
+ });
668
+ await clean.json();
669
+
670
+ const cleanCall = harness.mockFetch.mock.calls.find((call) => callUrl(call).includes("/clean"));
671
+ expect(cleanCall).toBeDefined();
672
+ expect(callHeaders(cleanCall!).get("x-stainless-retry-count")).toBe("0");
673
+ expect(parseSentBody(cleanCall!).tools[0].name).toBe("mcp_mcp_clean_followup");
674
+
675
+ harness.tearDown();
676
+ });
677
+
678
+ it("leaves no dangling deferred work after concurrent request cleanup", async () => {
679
+ const harness = await createFetchHarness();
680
+ const gate = createDeferred<Response>();
681
+
682
+ harness.mockFetch.mockImplementation(() => gate.promise);
683
+
684
+ const pendingRequest = harness.fetch("https://api.anthropic.com/v1/messages", {
685
+ method: "POST",
686
+ headers: { "content-type": "application/json" },
687
+ body: makeRequestBody({ toolName: "mcp_cleanup_gate" }),
688
+ });
689
+
690
+ await nextTick();
691
+ gate.resolve(jsonResponse({ id: "msg_cleanup_gate", content: [] }));
692
+
693
+ const response = await pendingRequest;
694
+ await response.json();
695
+
696
+ harness.mockFetch.mockImplementation(() => jsonResponse({ id: "msg_cleanup_followup", content: [] }));
697
+
698
+ const followUp = await harness.fetch("https://api.anthropic.com/v1/messages", {
699
+ method: "POST",
700
+ headers: { "content-type": "application/json" },
701
+ body: makeRequestBody({ toolName: "mcp_cleanup_gate_followup" }),
702
+ });
703
+ await followUp.json();
704
+
705
+ const lastCleanupCall = harness.mockFetch.mock.calls[harness.mockFetch.mock.calls.length - 1];
706
+
707
+ expect(parseSentBody(lastCleanupCall).tools[0].name).toBe("mcp_mcp_cleanup_gate_followup");
708
+
709
+ harness.tearDown();
710
+ });
711
+ });