zidane 6.5.5 → 6.5.7

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 (93) hide show
  1. package/dist/{acp-BPJbXS2J.js → acp-Dm95NwNM.js} +4 -4
  2. package/dist/{acp-BPJbXS2J.js.map → acp-Dm95NwNM.js.map} +1 -1
  3. package/dist/acp-cli.js +5 -5
  4. package/dist/acp.d.ts +1 -1
  5. package/dist/acp.js +1 -1
  6. package/dist/{agent-gZjHsUft.js → agent-CcTWL-Z6.js} +59 -5
  7. package/dist/agent-CcTWL-Z6.js.map +1 -0
  8. package/dist/agent.d.ts +1 -1
  9. package/dist/agent.js +1 -1
  10. package/dist/{anthropic-D3le2d-s.js → anthropic-BomWPIYw.js} +392 -30
  11. package/dist/anthropic-BomWPIYw.js.map +1 -0
  12. package/dist/{auth-DCiXCwGa.js → auth-C-Zx5zBo.js} +127 -35
  13. package/dist/auth-C-Zx5zBo.js.map +1 -0
  14. package/dist/chat/pure.d.ts +3 -3
  15. package/dist/chat.d.ts +91 -6
  16. package/dist/chat.d.ts.map +1 -1
  17. package/dist/chat.js +4 -4
  18. package/dist/contexts/daytona.d.ts +1 -1
  19. package/dist/contexts/e2b.d.ts +1 -1
  20. package/dist/eval.d.ts +1 -1
  21. package/dist/eval.js +1 -1
  22. package/dist/extensions.d.ts +1 -1
  23. package/dist/extensions.js +1 -1
  24. package/dist/headless.d.ts +1 -1
  25. package/dist/headless.js +3 -3
  26. package/dist/{index-BYKzzYzi.d.ts → index-ZWibV230.d.ts} +33 -7
  27. package/dist/index-ZWibV230.d.ts.map +1 -0
  28. package/dist/index.d.ts +1 -1
  29. package/dist/index.js +6 -6
  30. package/dist/mcp.d.ts +1 -1
  31. package/dist/{messages-CVVg5jUL.js → messages-CZMUuKzo.js} +2 -2
  32. package/dist/{messages-CVVg5jUL.js.map → messages-CZMUuKzo.js.map} +1 -1
  33. package/dist/{openai-compat-hmZzpDrB.js → openai-compat-BoTi-9fd.js} +8 -3
  34. package/dist/openai-compat-BoTi-9fd.js.map +1 -0
  35. package/dist/output/stream-json.d.ts +1 -1
  36. package/dist/output/terminal.d.ts +1 -1
  37. package/dist/plugins.d.ts +1 -1
  38. package/dist/presets.d.ts +1 -1
  39. package/dist/presets.js +1 -1
  40. package/dist/providers/anthropic.d.ts +1 -1
  41. package/dist/providers/anthropic.js +1 -1
  42. package/dist/providers/arcee.d.ts +1 -1
  43. package/dist/providers/arcee.js +1 -1
  44. package/dist/providers/baseten.d.ts +1 -1
  45. package/dist/providers/baseten.js +1 -1
  46. package/dist/providers/cerebras.d.ts +1 -1
  47. package/dist/providers/cerebras.js +2 -2
  48. package/dist/providers/cerebras.js.map +1 -1
  49. package/dist/providers/local.d.ts +1 -1
  50. package/dist/providers/local.js +1 -1
  51. package/dist/providers/openai-compat.d.ts +1 -1
  52. package/dist/providers/openai-compat.js +1 -1
  53. package/dist/providers/openai.d.ts +1 -1
  54. package/dist/providers/openai.js +2 -2
  55. package/dist/providers/openrouter.d.ts +1 -1
  56. package/dist/providers/openrouter.js +1 -1
  57. package/dist/providers/xai.d.ts +1 -1
  58. package/dist/providers/xai.js +1 -1
  59. package/dist/{providers-Cf0AXIIZ.js → providers-CmhdtD7w.js} +2 -2
  60. package/dist/{providers-Cf0AXIIZ.js.map → providers-CmhdtD7w.js.map} +1 -1
  61. package/dist/providers.d.ts +1 -1
  62. package/dist/providers.js +3 -3
  63. package/dist/restate.d.ts +1 -1
  64. package/dist/restate.js +2 -2
  65. package/dist/session/sqlite.d.ts +1 -1
  66. package/dist/{session-cqN5NbO-.js → session-CyRLSsVa.js} +2 -2
  67. package/dist/{session-cqN5NbO-.js.map → session-CyRLSsVa.js.map} +1 -1
  68. package/dist/session.d.ts +1 -1
  69. package/dist/session.js +2 -2
  70. package/dist/skills.d.ts +1 -1
  71. package/dist/{tool-formatters-B5WSHMCU.d.ts → tool-formatters-D3wSS2zz.d.ts} +2 -2
  72. package/dist/{tool-formatters-B5WSHMCU.d.ts.map → tool-formatters-D3wSS2zz.d.ts.map} +1 -1
  73. package/dist/tools/fetch-url.d.ts +1 -1
  74. package/dist/tools/web-search.d.ts +1 -1
  75. package/dist/tools.d.ts +1 -1
  76. package/dist/tools.js +1 -1
  77. package/dist/{transcript-anchors-BvC8t7dt.js → transcript-anchors-DGUqw92H.js} +3 -3
  78. package/dist/{transcript-anchors-BvC8t7dt.js.map → transcript-anchors-DGUqw92H.js.map} +1 -1
  79. package/dist/{transcript-anchors-BPnWHLyr.d.ts → transcript-anchors-llwMrLRG.d.ts} +2 -2
  80. package/dist/{transcript-anchors-BPnWHLyr.d.ts.map → transcript-anchors-llwMrLRG.d.ts.map} +1 -1
  81. package/dist/tui.d.ts +9 -3
  82. package/dist/tui.d.ts.map +1 -1
  83. package/dist/tui.js +232 -13
  84. package/dist/tui.js.map +1 -1
  85. package/dist/{turn-operations-BvP3_HsU.d.ts → turn-operations-C_XvfBU3.d.ts} +3 -3
  86. package/dist/{turn-operations-BvP3_HsU.d.ts.map → turn-operations-C_XvfBU3.d.ts.map} +1 -1
  87. package/dist/types.d.ts +1 -1
  88. package/package.json +2 -2
  89. package/dist/agent-gZjHsUft.js.map +0 -1
  90. package/dist/anthropic-D3le2d-s.js.map +0 -1
  91. package/dist/auth-DCiXCwGa.js.map +0 -1
  92. package/dist/index-BYKzzYzi.d.ts.map +0 -1
  93. package/dist/openai-compat-hmZzpDrB.js.map +0 -1
package/dist/agent.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { $h as hydrateReadStateFromSessionAsync, $r as createRunSummaryCollector, Bf as installCacheBreakLogger, Ff as CacheDimensionSnapshot, Gi as AgentHookMap, Gr as RunSummaryBudget, If as CacheDriftInfo, Jh as ReadStateEntry, Ji as McpConnector, Jr as RunSummaryCollectorOptions, Ki as AgentHooks, Kr as RunSummaryByModel, Lf as diffCacheDimensions, Mf as CacheBreakLoggerOptions, Nf as CacheDimensionDiff, Pf as CacheDimensionName, Qh as hydrateReadStateFromSession, Qr as RunSummaryValidation, Rf as fnv1a32, Ur as RunSummary, Vf as snapshotCacheDimensions, Wi as Agent, Wr as RunSummaryBlock, Xh as getReadState, Xi as McpToolWrap, Xr as RunSummaryRepeatGuard, Yh as ReadStateMap, Yi as McpToolMeta, Yr as RunSummaryError, Zi as createAgent, Zr as RunSummaryTokens, eg as readStateKey, jf as CacheBreakInfo, qh as HydrateReadStateOptions, qi as AgentOptions, qr as RunSummaryCollector, tg as resolveReadStateMap, zf as hashMessages } from "./index-BYKzzYzi.js";
1
+ import { $h as hydrateReadStateFromSessionAsync, $r as createRunSummaryCollector, Bf as installCacheBreakLogger, Ff as CacheDimensionSnapshot, Gi as AgentHookMap, Gr as RunSummaryBudget, If as CacheDriftInfo, Jh as ReadStateEntry, Ji as McpConnector, Jr as RunSummaryCollectorOptions, Ki as AgentHooks, Kr as RunSummaryByModel, Lf as diffCacheDimensions, Mf as CacheBreakLoggerOptions, Nf as CacheDimensionDiff, Pf as CacheDimensionName, Qh as hydrateReadStateFromSession, Qr as RunSummaryValidation, Rf as fnv1a32, Ur as RunSummary, Vf as snapshotCacheDimensions, Wi as Agent, Wr as RunSummaryBlock, Xh as getReadState, Xi as McpToolWrap, Xr as RunSummaryRepeatGuard, Yh as ReadStateMap, Yi as McpToolMeta, Yr as RunSummaryError, Zi as createAgent, Zr as RunSummaryTokens, eg as readStateKey, jf as CacheBreakInfo, qh as HydrateReadStateOptions, qi as AgentOptions, qr as RunSummaryCollector, tg as resolveReadStateMap, zf as hashMessages } from "./index-ZWibV230.js";
2
2
  export { type Agent, type AgentHookMap, type AgentHooks, type AgentOptions, type CacheBreakInfo, type CacheBreakLoggerOptions, type CacheDimensionDiff, type CacheDimensionName, type CacheDimensionSnapshot, type CacheDriftInfo, type HydrateReadStateOptions, type McpConnector, type McpToolMeta, type McpToolWrap, type ReadStateEntry, type ReadStateMap, type RunSummary, type RunSummaryBlock, type RunSummaryBudget, type RunSummaryByModel, type RunSummaryCollector, type RunSummaryCollectorOptions, type RunSummaryError, type RunSummaryRepeatGuard, type RunSummaryTokens, type RunSummaryValidation, createAgent, createRunSummaryCollector, diffCacheDimensions, fnv1a32, getReadState, hashMessages, hydrateReadStateFromSession, hydrateReadStateFromSessionAsync, installCacheBreakLogger, readStateKey, resolveReadStateMap, snapshotCacheDimensions };
package/dist/agent.js CHANGED
@@ -1,4 +1,4 @@
1
- import { In as hydrateReadStateFromSession, Ln as hydrateReadStateFromSessionAsync, Pn as getReadState, Rn as readStateKey, t as createAgent, zn as resolveReadStateMap } from "./agent-gZjHsUft.js";
1
+ import { Bn as hydrateReadStateFromSessionAsync, Hn as resolveReadStateMap, Ln as getReadState, Vn as readStateKey, t as createAgent, zn as hydrateReadStateFromSession } from "./agent-CcTWL-Z6.js";
2
2
  import { a as snapshotCacheDimensions, i as installCacheBreakLogger, n as fnv1a32, r as hashMessages, t as diffCacheDimensions } from "./cache-telemetry-ehVdWsg2.js";
3
3
  import { t as createRunSummaryCollector } from "./run-summary-BU_NgwUT.js";
4
4
  export { createAgent, createRunSummaryCollector, diffCacheDimensions, fnv1a32, getReadState, hashMessages, hydrateReadStateFromSession, hydrateReadStateFromSessionAsync, installCacheBreakLogger, readStateKey, resolveReadStateMap, snapshotCacheDimensions };
@@ -1,9 +1,12 @@
1
- import { F as unsupportedMediaError, S as resolvePromptCacheKey, b as sanitizeToolSpecs, k as lookupModel, v as createToolNameBoundary, w as fillEstimatedCost } from "./openai-compat-hmZzpDrB.js";
1
+ import { F as unsupportedMediaError, S as resolvePromptCacheKey, b as sanitizeToolSpecs, k as lookupModel, v as createToolNameBoundary, w as fillEstimatedCost } from "./openai-compat-BoTi-9fd.js";
2
2
  import { t as lazyAsync } from "./lazy-DLOurOC_.js";
3
3
  import { f as isRetryableHttpStatus, h as matchesToolPairingError, l as classifyErrorPrelude, m as matchesContextExceeded, u as errorMessage } from "./errors-DKiMrOKq.js";
4
4
  import { renderSystemForWire, splitSystemPrompt } from "./prompt.js";
5
- import { g as toAnthropic, u as fromAnthropic } from "./messages-CVVg5jUL.js";
5
+ import { g as toAnthropic, u as fromAnthropic } from "./messages-CZMUuKzo.js";
6
6
  import { a as readOAuthCredentials, r as extractRuntimeCredentials, s as resolveOAuthApiKey } from "./oauth-C4GvY_p1.js";
7
+ import { Buffer } from "node:buffer";
8
+ import { arch, homedir, hostname, platform, userInfo } from "node:os";
9
+ import { createHash, randomUUID } from "node:crypto";
7
10
  //#region src/chat/anthropic-models.ts
8
11
  /**
9
12
  * Anthropic "fast mode" — `speed: "fast"` on the Messages API. ~2.5× output
@@ -55,6 +58,18 @@ function fastModeCostMultiplier(modelId) {
55
58
  return FAST_MODE_OPTIONS[modelId]?.costMultiplier;
56
59
  }
57
60
  /**
61
+ * Claude Fable 5.1 — GA 2026-09-01, `claude-fable-5-1`. Same input/output price
62
+ * as Fable 5 ($10/$50 per MTok) with cache reads cut 75% ($1 → $0.25); 1M
63
+ * context, 128k output, adaptive thinking always on, vision. Rates are the
64
+ * published table, not inferred: input $10, 5m cache write $12.50, 1h cache
65
+ * write $20, cache hit $0.25, output $50.
66
+ * See https://platform.claude.com/docs/en/models/fable-5-1/overview.
67
+ *
68
+ * CAVEAT — this model REJECTS forced tool use: `tool_choice` of `any` or `tool`
69
+ * returns 400. Zidane pins a forced tool for structured output (`loop.ts`,
70
+ * `generate-data.ts`, the eval judge), so those paths fail on this model. Not
71
+ * handled here; adding the entry only makes the model selectable.
72
+ *
58
73
  * Claude Opus 5 — GA 2026-07-24. The announcement confirms $5/$25 per MTok
59
74
  * (same as Opus 4.8) and fast mode at 2×; the 1M context, 128k output, and
60
75
  * cache rates are ASSUMED from Opus 4.8 — verify against the model docs once
@@ -68,12 +83,28 @@ function fastModeCostMultiplier(modelId) {
68
83
  * ($5/$25 per MTok, 1M context, 128k output), adaptive thinking, vision.
69
84
  * See https://www.anthropic.com/news/claude-opus-4-8.
70
85
  *
71
- * Claude Mythos 5 is deliberately absent: it's invitation-only (Project
72
- * Glasswing), so it would be a dead picker entry for virtually all users.
86
+ * Claude Mythos 5 / 5.1 are deliberately absent: invitation-only (Project
87
+ * Glasswing) despite sharing Fable's specs and pricing, so they would be dead
88
+ * picker entries for virtually all users.
73
89
  *
74
90
  * See https://platform.claude.com/docs/en/about-claude/models/overview.
75
91
  */
76
92
  const ANTHROPIC_EXTRA_MODELS = [
93
+ {
94
+ id: "claude-fable-5-1",
95
+ name: "Claude Fable 5.1",
96
+ reasoning: true,
97
+ input: ["text", "image"],
98
+ cost: {
99
+ input: 10,
100
+ output: 50,
101
+ cacheRead: .25,
102
+ cacheWrite: 12.5
103
+ },
104
+ contextWindow: 1e6,
105
+ maxTokens: 128e3,
106
+ provider: "anthropic"
107
+ },
77
108
  {
78
109
  id: "claude-opus-5",
79
110
  name: "Claude Opus 5",
@@ -123,6 +154,324 @@ const ANTHROPIC_EXTRA_MODELS = [
123
154
  }
124
155
  ];
125
156
  //#endregion
157
+ //#region src/providers/anthropic-claude-code.ts
158
+ /**
159
+ * Claude Code client alignment for Anthropic subscription OAuth.
160
+ *
161
+ * Anthropic's subscription endpoint serves the Claude Code CLI. Requests that
162
+ * do not look like that client are, at best, treated as a different product; at
163
+ * worst they miss features the CLI relies on. This module holds every surface
164
+ * that has to match, in one file, so a client bump is one edit rather than a
165
+ * scavenger hunt through the provider.
166
+ *
167
+ * Modelled on `@pi-plugins/claude-oauth`, which maintains the same alignment
168
+ * for pi and verifies its pins against a live client trace. Everything here is
169
+ * scoped to the OAuth path — API-key, gateway-bearer and Bedrock requests never
170
+ * reach it.
171
+ */
172
+ /**
173
+ * Pinned Claude Code client versions.
174
+ *
175
+ * These travel together: the billing fingerprint below hashes
176
+ * {@link CLAUDE_CODE_VERSION}, so bumping one without the others produces a
177
+ * value that does not correspond to any real client. Re-check all five against
178
+ * the upstream plugin's `constants.ts` when bumping.
179
+ */
180
+ const CLAUDE_CODE_VERSION = "2.1.165";
181
+ const CLAUDE_AGENT_SDK_VERSION = "0.3.165";
182
+ const CLAUDE_CLIENT_VERSION = "1.11187.4";
183
+ const CLAUDE_CODE_STAINLESS_PACKAGE_VERSION = "0.94.0";
184
+ const CLAUDE_CODE_STAINLESS_RUNTIME_VERSION = "v24.3.0";
185
+ /**
186
+ * Claude Code caps requested output at 64k even where the model ceiling is
187
+ * higher (Opus allows 128k). Requests above the cap are clamped to match.
188
+ */
189
+ const CLAUDE_CODE_MAX_OUTPUT_TOKENS = 64e3;
190
+ /**
191
+ * Tool names the Claude subscription backend reserves.
192
+ *
193
+ * A tool named exactly `todowrite` is classified as a paid Claude product
194
+ * surface: the otherwise-valid OAuth request is refused with "You're out of
195
+ * extra usage" when the account has no purchased usage credits. The same body
196
+ * succeeds when only that wire name changes.
197
+ */
198
+ const CLAUDE_CODE_RESERVED_TOOL_NAMES = ["todowrite"];
199
+ const RESERVED_TOOL_ALIAS_PREFIX = "zidane_";
200
+ /**
201
+ * Request-local wire aliases that move reserved names out of the way, for
202
+ * Claude subscription OAuth only.
203
+ *
204
+ * Resolved against the request's FULL name set (history + current specs) rather
205
+ * than hardcoded, because the obvious alias is itself a legal tool name: an
206
+ * extension shipping `zidane_todowrite` alongside `todowrite` would otherwise
207
+ * make the boundary throw on a collision it can trivially avoid. Suffixing is
208
+ * deterministic, so the wire bytes — and the provider prompt cache — stay
209
+ * stable across turns with the same tool set.
210
+ *
211
+ * Canonical names are restored at the provider boundary, so dispatch, hooks,
212
+ * persistence, and other auth modes never see the alias.
213
+ */
214
+ function claudeCodeToolAliases(names) {
215
+ let aliases;
216
+ const taken = new Set(names);
217
+ for (const reserved of CLAUDE_CODE_RESERVED_TOOL_NAMES) {
218
+ if (!names.has(reserved)) continue;
219
+ let candidate = `${RESERVED_TOOL_ALIAS_PREFIX}${reserved}`;
220
+ for (let n = 2; taken.has(candidate); n++) candidate = `${RESERVED_TOOL_ALIAS_PREFIX}${reserved}_${n}`;
221
+ taken.add(candidate);
222
+ aliases ??= {};
223
+ aliases[reserved] = candidate;
224
+ }
225
+ return aliases;
226
+ }
227
+ /**
228
+ * Beta set the Claude Code agent sends, in client order.
229
+ *
230
+ * Sent as one unit: the endpoint is configured for this combination, and
231
+ * trimming it to "the ones we think we use" is how a client stops looking like
232
+ * the client. Betas without matching request fields are inert.
233
+ */
234
+ const CLAUDE_CODE_BETAS = [
235
+ "claude-code-20250219",
236
+ "oauth-2025-04-20",
237
+ "interleaved-thinking-2025-05-14",
238
+ "fine-grained-tool-streaming-2025-05-14",
239
+ "context-management-2025-06-27",
240
+ "prompt-caching-scope-2026-01-05",
241
+ "mid-conversation-system-2026-04-07",
242
+ "advanced-tool-use-2025-11-20",
243
+ "effort-2025-11-24",
244
+ "extended-cache-ttl-2025-04-11"
245
+ ];
246
+ /** Billing-header pins. See {@link claudeCodeBillingText}. */
247
+ const BILLING_FINGERPRINT_SALT = "59cf53e54c78";
248
+ const BILLING_FINGERPRINT_INDICES = [
249
+ 4,
250
+ 7,
251
+ 20
252
+ ];
253
+ const BILLING_HEADER_PREFIX = "x-anthropic-billing-header:";
254
+ const CCH_PLACEHOLDER = "cch=00000";
255
+ const CCH_SEED = 5577024349156291176n;
256
+ /** `os.arch()` values mapped to the labels Stainless emits. */
257
+ function stainlessArch(value) {
258
+ switch (value.toLowerCase()) {
259
+ case "amd64":
260
+ case "x64": return "x64";
261
+ case "arm64":
262
+ case "aarch64": return "arm64";
263
+ case "386":
264
+ case "x86":
265
+ case "ia32": return "x86";
266
+ default: return `other::${value.toLowerCase()}`;
267
+ }
268
+ }
269
+ /** `os.platform()` values mapped to the labels Stainless emits. */
270
+ function stainlessOs(value) {
271
+ switch (value.toLowerCase()) {
272
+ case "darwin": return "MacOS";
273
+ case "win32":
274
+ case "windows": return "Windows";
275
+ case "linux": return "Linux";
276
+ case "freebsd": return "FreeBSD";
277
+ default: return `Other::${value.toLowerCase()}`;
278
+ }
279
+ }
280
+ /**
281
+ * Headers a Claude Code OAuth request carries.
282
+ *
283
+ * The `x-stainless-*` entries deliberately OVERRIDE the ones the Anthropic SDK
284
+ * generates about itself: left alone they advertise `Anthropic/JS <sdk version>`
285
+ * on a request claiming to be the CLI, which is a contradiction no real client
286
+ * produces.
287
+ */
288
+ function buildClaudeCodeHeaders() {
289
+ return {
290
+ "user-agent": `claude-cli/${CLAUDE_CODE_VERSION} (external, local-agent, agent-sdk/${CLAUDE_AGENT_SDK_VERSION})`,
291
+ "x-app": "cli",
292
+ "anthropic-dangerous-direct-browser-access": "true",
293
+ "x-stainless-retry-count": "0",
294
+ "x-stainless-runtime-version": CLAUDE_CODE_STAINLESS_RUNTIME_VERSION,
295
+ "x-stainless-package-version": CLAUDE_CODE_STAINLESS_PACKAGE_VERSION,
296
+ "x-stainless-runtime": "node",
297
+ "x-stainless-lang": "js",
298
+ "x-stainless-arch": stainlessArch(arch()),
299
+ "x-stainless-os": stainlessOs(platform()),
300
+ "x-stainless-timeout": "900",
301
+ "anthropic-client-platform": "desktop_app",
302
+ "anthropic-client-version": CLAUDE_CLIENT_VERSION
303
+ };
304
+ }
305
+ /**
306
+ * Text of the `system[0]` billing block.
307
+ *
308
+ * The version suffix is `sha256(salt + msg[4] + msg[7] + msg[20] + version)`
309
+ * truncated to 3 hex chars, where the indices sample the first user message.
310
+ * Missing characters (a first message shorter than 21 chars) contribute `'0'`,
311
+ * matching the client rather than throwing.
312
+ *
313
+ * The `cch` field ships as {@link CCH_PLACEHOLDER} and is overwritten by
314
+ * {@link patchCch} once the body is serialized — it hashes those very bytes, so
315
+ * it cannot be computed here.
316
+ */
317
+ function claudeCodeBillingText(firstUserMessage) {
318
+ const seed = BILLING_FINGERPRINT_INDICES.map((i) => firstUserMessage[i] ?? "0").join("");
319
+ const suffix = createHash("sha256").update(`${BILLING_FINGERPRINT_SALT}${seed}${CLAUDE_CODE_VERSION}`).digest("hex").slice(0, 3);
320
+ return `${BILLING_HEADER_PREFIX} cc_version=${CLAUDE_CODE_VERSION}.${suffix}; cc_entrypoint=local-agent; ${CCH_PLACEHOLDER};`;
321
+ }
322
+ /** Concatenated text of the first user message — the fingerprint's sample source. */
323
+ function firstUserMessageText(messages) {
324
+ const content = messages.find((m) => m.role === "user")?.content;
325
+ if (typeof content === "string") return content;
326
+ if (!Array.isArray(content)) return "";
327
+ return content.filter((b) => !!b && typeof b === "object" && b.type === "text" && typeof b.text === "string").map((b) => b.text).join("");
328
+ }
329
+ /**
330
+ * Machine-stable device id + per-process session id, sent as
331
+ * `metadata.user_id`'s JSON envelope.
332
+ *
333
+ * `userInfo()` throws in locked-down sandboxes, so the seed degrades to the
334
+ * hostname rather than taking the process down.
335
+ */
336
+ function machineSeed() {
337
+ try {
338
+ return `${hostname()}:${userInfo().username}:${homedir()}`;
339
+ } catch {
340
+ return `${hostname()}:zidane-claude-code-fallback`;
341
+ }
342
+ }
343
+ const DEVICE_ID = createHash("sha256").update(`zidane-claude-code-device-v1:${machineSeed()}`).digest("hex");
344
+ const SESSION_ID = randomUUID();
345
+ /** The `metadata.user_id` envelope Claude Code sends. */
346
+ function claudeCodeUserId() {
347
+ return JSON.stringify({
348
+ device_id: DEVICE_ID,
349
+ session_id: SESSION_ID
350
+ });
351
+ }
352
+ const MASK = (1n << 64n) - 1n;
353
+ const PRIME64_1 = 11400714785074694791n;
354
+ const PRIME64_2 = 14029467366897019727n;
355
+ const PRIME64_3 = 1609587929392839161n;
356
+ const PRIME64_4 = 9650029242287828579n;
357
+ const PRIME64_5 = 2870177450012600261n;
358
+ const rotl = (x, r) => (x << r | x >> 64n - r) & MASK;
359
+ function round(acc, input) {
360
+ const next = acc + input * PRIME64_2 & MASK;
361
+ return rotl(next, 31n) * PRIME64_1 & MASK;
362
+ }
363
+ function mergeRound(acc, val) {
364
+ return ((acc ^ round(0n, val)) * PRIME64_1 & MASK) + PRIME64_4 & MASK;
365
+ }
366
+ /**
367
+ * XXH64, reproducing Claude Code's `cch` request-integrity value.
368
+ *
369
+ * Ported rather than delegated to `Bun.hash.xxHash64` so the result cannot
370
+ * drift with a runtime's hash implementation or seed handling, and so the
371
+ * provider still works off-Bun. Verified against published XXH64 vectors.
372
+ */
373
+ function xxHash64(input, seed) {
374
+ const len = input.length;
375
+ const dv = new DataView(input.buffer, input.byteOffset, input.byteLength);
376
+ let h64;
377
+ let p = 0;
378
+ if (len >= 32) {
379
+ let v1 = seed + PRIME64_1 + PRIME64_2 & MASK;
380
+ let v2 = seed + PRIME64_2 & MASK;
381
+ let v3 = seed & MASK;
382
+ let v4 = seed - PRIME64_1 & MASK;
383
+ const limit = len - 32;
384
+ while (p <= limit) {
385
+ v1 = round(v1, dv.getBigUint64(p, true));
386
+ p += 8;
387
+ v2 = round(v2, dv.getBigUint64(p, true));
388
+ p += 8;
389
+ v3 = round(v3, dv.getBigUint64(p, true));
390
+ p += 8;
391
+ v4 = round(v4, dv.getBigUint64(p, true));
392
+ p += 8;
393
+ }
394
+ h64 = rotl(v1, 1n) + rotl(v2, 7n) + rotl(v3, 12n) + rotl(v4, 18n) & MASK;
395
+ h64 = mergeRound(h64, v1);
396
+ h64 = mergeRound(h64, v2);
397
+ h64 = mergeRound(h64, v3);
398
+ h64 = mergeRound(h64, v4);
399
+ } else h64 = seed + PRIME64_5 & MASK;
400
+ h64 = h64 + BigInt(len) & MASK;
401
+ while (p + 8 <= len) {
402
+ h64 ^= round(0n, dv.getBigUint64(p, true));
403
+ h64 = rotl(h64, 27n) * PRIME64_1 & MASK;
404
+ h64 = h64 + PRIME64_4 & MASK;
405
+ p += 8;
406
+ }
407
+ if (p + 4 <= len) {
408
+ h64 ^= BigInt(dv.getUint32(p, true)) * PRIME64_1 & MASK;
409
+ h64 = rotl(h64, 23n) * PRIME64_2 & MASK;
410
+ h64 = h64 + PRIME64_3 & MASK;
411
+ p += 4;
412
+ }
413
+ while (p < len) {
414
+ h64 ^= BigInt(input[p] ?? 0) * PRIME64_5 & MASK;
415
+ h64 = rotl(h64, 11n) * PRIME64_1 & MASK;
416
+ p += 1;
417
+ }
418
+ h64 ^= h64 >> 33n;
419
+ h64 = h64 * PRIME64_2 & MASK;
420
+ h64 ^= h64 >> 29n;
421
+ h64 = h64 * PRIME64_3 & MASK;
422
+ h64 ^= h64 >> 32n;
423
+ return h64 & MASK;
424
+ }
425
+ const encoder = new TextEncoder();
426
+ /**
427
+ * Anchor for the placeholder search. The SDK serializes `messages` before
428
+ * `system`, so these bytes can only belong to the block we injected — user
429
+ * content that happens to contain `cch=00000` can never match.
430
+ */
431
+ const BILLING_SYSTEM_MARKER = encoder.encode(`"system":[{"type":"text","text":"${BILLING_HEADER_PREFIX}`);
432
+ const CCH_PLACEHOLDER_BYTES = encoder.encode(CCH_PLACEHOLDER);
433
+ /** The placeholder must sit this close to the marker, else system[0] was reshaped. */
434
+ const CCH_SEARCH_WINDOW = 150;
435
+ /**
436
+ * Overwrite the `cch` placeholder with `XXH64(body) & 0xfffff`, in place.
437
+ *
438
+ * Returns the original bytes untouched when the placeholder is absent or not
439
+ * anchored to `system[0]` — a request that goes out with the placeholder intact
440
+ * is far better than one whose user content was corrupted by a stray patch.
441
+ */
442
+ function patchCch(encoded) {
443
+ const view = Buffer.from(encoded.buffer, encoded.byteOffset, encoded.byteLength);
444
+ const markerIdx = view.indexOf(BILLING_SYSTEM_MARKER);
445
+ if (markerIdx === -1) return encoded;
446
+ const searchFrom = markerIdx + BILLING_SYSTEM_MARKER.length;
447
+ const placeholderIdx = view.indexOf(CCH_PLACEHOLDER_BYTES, searchFrom);
448
+ if (placeholderIdx === -1 || placeholderIdx - searchFrom > CCH_SEARCH_WINDOW) return encoded;
449
+ const cch = (xxHash64(encoded, CCH_SEED) & 1048575n).toString(16).padStart(5, "0");
450
+ for (let i = 0; i < 5; i++) encoded[placeholderIdx + 4 + i] = cch.charCodeAt(i);
451
+ return encoded;
452
+ }
453
+ /**
454
+ * Wrap a `fetch` so bodies carrying the placeholder get their attestation
455
+ * patched after serialization.
456
+ *
457
+ * Handed to the Anthropic SDK per client rather than installed on
458
+ * `globalThis` — every other request in the process stays untouched, and two
459
+ * providers cannot fight over the global.
460
+ */
461
+ function wrapFetchForCch(base) {
462
+ const wrapped = (input, init) => {
463
+ const body = init?.body;
464
+ let finalBody = body;
465
+ if (typeof body === "string" && body.includes("cch=00000")) finalBody = patchCch(encoder.encode(body));
466
+ return base(input, finalBody === body ? init : {
467
+ ...init,
468
+ body: finalBody
469
+ });
470
+ };
471
+ wrapped.preconnect = base.preconnect?.bind(base) ?? (() => {});
472
+ return wrapped;
473
+ }
474
+ //#endregion
126
475
  //#region src/providers/anthropic.ts
127
476
  const loadAnthropicSdk = lazyAsync(async () => {
128
477
  try {
@@ -156,23 +505,15 @@ function normalizeBedrock(value) {
156
505
  if (!value) return void 0;
157
506
  return value === true ? {} : value;
158
507
  }
159
- /** Beta flags sent unconditionally on the OAuth path (Claude Code parity). */
160
- const OAUTH_DEFAULT_BETAS = ["claude-code-20250219", "oauth-2025-04-20"];
161
508
  /**
162
- * Claude Code identity advertised on subscription-OAuth requests. Anthropic's
163
- * subscription endpoint checks the Claude CLI identity; zidane's package
164
- * version is not a compatible user agent.
165
- *
166
- * Mirrors `claudeCodeVersion` in the pinned pi-ai
167
- * (`@earendil-works/pi-ai@0.84.2`, `dist/api/anthropic-messages.js`), which is
168
- * module-private there — there is no constant to import, so this has to be
169
- * re-checked by hand whenever pi-ai is bumped. The version is named here so
170
- * that check has an anchor instead of "the pinned release".
509
+ * Beta flags sent unconditionally on the OAuth path (Claude Code parity).
171
510
  *
172
- * Note this is parity-improving, not parity-complete: the SDK still stamps its
173
- * own `X-Stainless-*` platform headers, which the real CLI does not send.
511
+ * The full client set, sent as one unit — see `CLAUDE_CODE_BETAS`. Betas whose
512
+ * request fields we never populate are inert, so the cost of matching the
513
+ * client exactly is nil while the cost of guessing a subset is looking like a
514
+ * different client.
174
515
  */
175
- const CLAUDE_CODE_USER_AGENT = "claude-cli/2.1.75";
516
+ const OAUTH_DEFAULT_BETAS = CLAUDE_CODE_BETAS;
176
517
  /**
177
518
  * Beta flag that enables the `speed: "fast"` request field (fast mode — up to
178
519
  * 2.5× output tokens/sec at premium pricing; supported models are enumerated
@@ -187,6 +528,16 @@ const API_KEY_RESERVED_EXTRA_HEADER_NAMES = /* @__PURE__ */ new Set(["anthropic-
187
528
  const OAUTH_RESERVED_EXTRA_HEADER_NAMES = /* @__PURE__ */ new Set([
188
529
  "accept",
189
530
  "anthropic-beta",
531
+ "anthropic-client-platform",
532
+ "anthropic-client-version",
533
+ "x-stainless-arch",
534
+ "x-stainless-lang",
535
+ "x-stainless-os",
536
+ "x-stainless-package-version",
537
+ "x-stainless-retry-count",
538
+ "x-stainless-runtime",
539
+ "x-stainless-runtime-version",
540
+ "x-stainless-timeout",
190
541
  "anthropic-dangerous-direct-browser-access",
191
542
  "user-agent",
192
543
  "x-app"
@@ -296,10 +647,8 @@ function buildAnthropicClientOptions(apiKey, auth, baseURL, extraBetas, extraHea
296
647
  if (auth.claudeCode) {
297
648
  const defaultHeaders = {
298
649
  ...filterReservedExtraHeaders(extraHeaders, OAUTH_RESERVED_EXTRA_HEADER_NAMES),
299
- "accept": "application/json",
300
- "anthropic-dangerous-direct-browser-access": "true",
301
- "user-agent": CLAUDE_CODE_USER_AGENT,
302
- "x-app": "cli"
650
+ accept: "application/json",
651
+ ...buildClaudeCodeHeaders()
303
652
  };
304
653
  if (betaHeader) defaultHeaders["anthropic-beta"] = betaHeader;
305
654
  return {
@@ -307,6 +656,7 @@ function buildAnthropicClientOptions(apiKey, auth, baseURL, extraBetas, extraHea
307
656
  authToken: apiKey,
308
657
  dangerouslyAllowBrowser: true,
309
658
  defaultHeaders,
659
+ fetch: wrapFetchForCch(globalThis.fetch),
310
660
  ...base
311
661
  };
312
662
  }
@@ -1086,7 +1436,7 @@ function anthropic(anthropicParams) {
1086
1436
  ...payload.messages
1087
1437
  ] : [...payload.messages];
1088
1438
  const countTools = payload.tools;
1089
- const countBoundary = createToolNameBoundary(messages, countTools.map((t) => t.name));
1439
+ const countBoundary = createToolNameBoundary(messages, countTools.map((t) => t.name), callIsOAuth ? claudeCodeToolAliases : void 0);
1090
1440
  return (await client.messages.countTokens({
1091
1441
  model: payload.model,
1092
1442
  system,
@@ -1150,8 +1500,9 @@ function anthropic(anthropicParams) {
1150
1500
  * far — `callAuth.bearer` is false for both.
1151
1501
  */
1152
1502
  const callCanRotateAuth = callAuth.bearer;
1153
- const extendedTtl = options.cache !== false && options.cacheTtl === "1h" && !callIsOAuth && !bedrockConfig;
1154
- const conditionalBetas = [...options.modelOptions?.fast ? [FAST_MODE_BETA] : [], ...extendedTtl ? [EXTENDED_CACHE_TTL_BETA] : []];
1503
+ const effectiveCacheTtl = options.cacheTtl ?? (callIsOAuth ? "1h" : void 0);
1504
+ const extendedTtl = options.cache !== false && effectiveCacheTtl === "1h" && !bedrockConfig;
1505
+ const conditionalBetas = [...options.modelOptions?.fast && !callIsOAuth ? [FAST_MODE_BETA] : [], ...extendedTtl ? [EXTENDED_CACHE_TTL_BETA] : []];
1155
1506
  const requestBetas = conditionalBetas.length > 0 ? [...anthropicParams?.extraBetas ?? [], ...conditionalBetas] : anthropicParams?.extraBetas;
1156
1507
  const resolvedExtraHeaders = await resolveExtraHeaders(anthropicParams?.extraHeaders);
1157
1508
  let client = bedrockConfig ? await createBedrockClient(bedrockConfig, anthropicParams, resolvedExtraHeaders) : createClient(await loadAnthropicSdk(), apiKey, callAuth, anthropicParams?.baseURL, requestBetas, resolvedExtraHeaders);
@@ -1176,7 +1527,7 @@ function anthropic(anthropicParams) {
1176
1527
  ] : [...options.messages];
1177
1528
  const thinking = options.thinking ?? "off";
1178
1529
  const inputTools = options.tools ?? [];
1179
- const nameBoundary = createToolNameBoundary(messages, inputTools.map((t) => t.name));
1530
+ const nameBoundary = createToolNameBoundary(messages, inputTools.map((t) => t.name), callIsOAuth ? claudeCodeToolAliases : void 0);
1180
1531
  const wireTools = nameBoundary.changed ? inputTools.map((t) => t.name === nameBoundary.toWire(t.name) ? t : {
1181
1532
  ...t,
1182
1533
  name: nameBoundary.toWire(t.name)
@@ -1193,7 +1544,7 @@ function anthropic(anthropicParams) {
1193
1544
  stream: true
1194
1545
  };
1195
1546
  if (anthropicParams?.contextManagement && !bedrockConfig) params.context_management = anthropicParams.contextManagement;
1196
- if (options.cache !== false) applyAnthropicCacheBreakpoints(params, callIsOAuth ? void 0 : options.system, extendedTtl ? options.cacheTtl : void 0);
1547
+ if (options.cache !== false) applyAnthropicCacheBreakpoints(params, callIsOAuth ? void 0 : options.system, extendedTtl ? effectiveCacheTtl : void 0);
1197
1548
  const plan = planAnthropicThinking(thinking, options.thinkingBudget, options.taskBudget, options.effortHint !== false);
1198
1549
  if (plan && bedrockConfig) {
1199
1550
  const budget = plan.kind === "enabled" ? plan.budgetTokens : BEDROCK_THINKING_BUDGETS[plan.effort ?? "medium"];
@@ -1235,6 +1586,17 @@ function anthropic(anthropicParams) {
1235
1586
  params.temperature = 1;
1236
1587
  }
1237
1588
  params.max_tokens = Math.min(params.max_tokens, modelMaxOutput);
1589
+ if (callIsOAuth) {
1590
+ params.max_tokens = Math.min(params.max_tokens, CLAUDE_CODE_MAX_OUTPUT_TOKENS);
1591
+ if (Array.isArray(params.system)) params.system = [{
1592
+ type: "text",
1593
+ text: claudeCodeBillingText(firstUserMessageText(params.messages))
1594
+ }, ...params.system];
1595
+ if (typeof params.metadata?.user_id !== "string") params.metadata = {
1596
+ ...params.metadata,
1597
+ user_id: claudeCodeUserId()
1598
+ };
1599
+ }
1238
1600
  if (params.thinking?.type === "enabled" && params.thinking.budget_tokens >= params.max_tokens) {
1239
1601
  const fitted = params.max_tokens - THINKING_RESPONSE_RESERVE_TOKENS;
1240
1602
  if (fitted >= 1024) params.thinking.budget_tokens = fitted;
@@ -1243,7 +1605,7 @@ function anthropic(anthropicParams) {
1243
1605
  delete params.temperature;
1244
1606
  }
1245
1607
  }
1246
- if (options.modelOptions?.fast) params.speed = "fast";
1608
+ if (options.modelOptions?.fast && !callIsOAuth) params.speed = "fast";
1247
1609
  if (options.toolChoice) if (options.toolChoice.type === "tool" && options.toolChoice.name) params.tool_choice = {
1248
1610
  type: "tool",
1249
1611
  name: nameBoundary.toWire(options.toolChoice.name)
@@ -1373,11 +1735,11 @@ function anthropic(anthropicParams) {
1373
1735
  usage
1374
1736
  };
1375
1737
  };
1376
- return await runStream(params, options.modelOptions?.fast === true);
1738
+ return await runStream(params, options.modelOptions?.fast === true && !callIsOAuth);
1377
1739
  }
1378
1740
  };
1379
1741
  }
1380
1742
  //#endregion
1381
1743
  export { classifyAnthropicError as a, planAnthropicThinking as c, resolveAnthropicMaxOutput as d, ANTHROPIC_EXTRA_MODELS as f, buildAnthropicClientOptions as i, resolveAnthropicAuthShape as l, anthropic as n, credentialIdentity as o, FAST_MODE_OPTIONS as p, applyAnthropicCacheBreakpoints as r, defaultAnthropicMaxTokens as s, EXTENDED_CACHE_TTL_BETA as t, resolveAnthropicBetas as u };
1382
1744
 
1383
- //# sourceMappingURL=anthropic-D3le2d-s.js.map
1745
+ //# sourceMappingURL=anthropic-BomWPIYw.js.map