zidane 6.2.12 → 6.2.13

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 (56) hide show
  1. package/dist/{acp-C-auiVTk.js → acp-DxYjSCQW.js} +5 -5
  2. package/dist/{acp-C-auiVTk.js.map → acp-DxYjSCQW.js.map} +1 -1
  3. package/dist/acp-cli.js +6 -6
  4. package/dist/acp.js +1 -1
  5. package/dist/{agent-DhfdXgL2.js → agent-DoEx_WD3.js} +6 -5
  6. package/dist/{agent-DhfdXgL2.js.map → agent-DoEx_WD3.js.map} +1 -1
  7. package/dist/agent.js +2 -2
  8. package/dist/aliasing-lVFbm81n.js +217 -0
  9. package/dist/aliasing-lVFbm81n.js.map +1 -0
  10. package/dist/{anthropic-uXfsormU.js → anthropic-BYsc6qWj.js} +3 -3
  11. package/dist/{anthropic-uXfsormU.js.map → anthropic-BYsc6qWj.js.map} +1 -1
  12. package/dist/{auth-TZg3MVi2.js → auth-Bb479DFB.js} +4 -4
  13. package/dist/{auth-TZg3MVi2.js.map → auth-Bb479DFB.js.map} +1 -1
  14. package/dist/chat.js +3 -3
  15. package/dist/eval.js +1 -1
  16. package/dist/extensions.js +1 -1
  17. package/dist/headless.js +3 -3
  18. package/dist/index-l0wehkWU.d.ts.map +1 -1
  19. package/dist/index.js +7 -7
  20. package/dist/{messages-BDpXLFoe.js → messages-CvHfYB7f.js} +3 -3
  21. package/dist/{messages-BDpXLFoe.js.map → messages-CvHfYB7f.js.map} +1 -1
  22. package/dist/{openai-compat-J_JZ7qsw.js → openai-compat-pHI0kBWH.js} +37 -8
  23. package/dist/openai-compat-pHI0kBWH.js.map +1 -0
  24. package/dist/presets.js +1 -1
  25. package/dist/providers/anthropic.js +1 -1
  26. package/dist/providers/arcee.js +1 -1
  27. package/dist/providers/baseten.js +1 -1
  28. package/dist/providers/cerebras.js +1 -1
  29. package/dist/providers/local.js +1 -1
  30. package/dist/providers/openai-compat.js +1 -1
  31. package/dist/providers/openai.js +27 -10
  32. package/dist/providers/openai.js.map +1 -1
  33. package/dist/providers/openrouter.js +1 -1
  34. package/dist/providers/xai.js +1 -1
  35. package/dist/{providers-CclOzGxc.js → providers-D9Y2RndM.js} +3 -3
  36. package/dist/{providers-CclOzGxc.js.map → providers-D9Y2RndM.js.map} +1 -1
  37. package/dist/providers.js +4 -4
  38. package/dist/{read-state-Dq_TXUX1.js → read-state-rDmfeLmz.js} +3 -196
  39. package/dist/read-state-rDmfeLmz.js.map +1 -0
  40. package/dist/restate.js +2 -1
  41. package/dist/restate.js.map +1 -1
  42. package/dist/{session-CIXE-Bzp.js → session-DzrXKLw-.js} +2 -2
  43. package/dist/{session-CIXE-Bzp.js.map → session-DzrXKLw-.js.map} +1 -1
  44. package/dist/session.js +2 -2
  45. package/dist/tools.js +2 -2
  46. package/dist/{transcript-anchors-BzcuKnq8.js → transcript-anchors-yogJHuBW.js} +3 -3
  47. package/dist/{transcript-anchors-BzcuKnq8.js.map → transcript-anchors-yogJHuBW.js.map} +1 -1
  48. package/dist/tui.js +6 -5
  49. package/dist/tui.js.map +1 -1
  50. package/dist/{xai-D-wALLuZ.js → xai-BwhzoehX.js} +2 -2
  51. package/dist/{xai-D-wALLuZ.js.map → xai-BwhzoehX.js.map} +1 -1
  52. package/package.json +1 -1
  53. package/dist/hash-DJRzmcPI.js +0 -24
  54. package/dist/hash-DJRzmcPI.js.map +0 -1
  55. package/dist/openai-compat-J_JZ7qsw.js.map +0 -1
  56. package/dist/read-state-Dq_TXUX1.js.map +0 -1
package/dist/agent.js CHANGED
@@ -1,5 +1,5 @@
1
- import { a as hydrateReadStateFromSessionAsync, c as resolveReadStateMap, i as hydrateReadStateFromSession, s as readStateKey, t as getReadState } from "./read-state-Dq_TXUX1.js";
2
- import { t as createAgent } from "./agent-DhfdXgL2.js";
1
+ import { a as hydrateReadStateFromSessionAsync, c as resolveReadStateMap, i as hydrateReadStateFromSession, s as readStateKey, t as getReadState } from "./read-state-rDmfeLmz.js";
2
+ import { t as createAgent } from "./agent-DoEx_WD3.js";
3
3
  import { i as snapshotCacheDimensions, n as fnv1a32, r as installCacheBreakLogger, t as diffCacheDimensions } from "./cache-telemetry-KJ7B-_Gh.js";
4
4
  import { t as createRunSummaryCollector } from "./run-summary-nD3IQ4ZQ.js";
5
5
  export { createAgent, createRunSummaryCollector, diffCacheDimensions, fnv1a32, getReadState, hydrateReadStateFromSession, hydrateReadStateFromSessionAsync, installCacheBreakLogger, readStateKey, resolveReadStateMap, snapshotCacheDimensions };
@@ -0,0 +1,217 @@
1
+ //#region src/hash.ts
2
+ /**
3
+ * FNV-1a (32-bit) rendered in base36 — a tiny, dependency-free, deterministic
4
+ * hash.
5
+ *
6
+ * Used to disambiguate sanitized identifiers: distinct inputs that would
7
+ * otherwise collapse to the same sanitized string (e.g. `a.b` and `a/b` both
8
+ * → `a_b`, or two over-long names truncated to the same prefix) keep a stable,
9
+ * unique suffix. Determinism matters because the suffix must be identical
10
+ * across runs and across a `tool_use` / `tool_result` pair derived from the
11
+ * same original value.
12
+ */
13
+ function fnv1aBase36(value) {
14
+ let hash = 2166136261;
15
+ for (let i = 0; i < value.length; i++) {
16
+ hash ^= value.charCodeAt(i);
17
+ hash = Math.imul(hash, 16777619);
18
+ }
19
+ return (hash >>> 0).toString(36);
20
+ }
21
+ //#endregion
22
+ //#region src/aliasing.ts
23
+ /**
24
+ * Build alias lookup maps from a `toolAliases` record.
25
+ *
26
+ * Validates:
27
+ * - No two canonical names map to the same alias (collision).
28
+ * - No alias collides with another canonical tool name (would shadow).
29
+ *
30
+ * Silently ignores alias entries whose canonical name isn't in `canonicalNames` —
31
+ * preset/agent authors can declare aliases for tools that may be added later via MCP.
32
+ *
33
+ * @param aliases - The `toolAliases` map from the agent options.
34
+ * @param canonicalNames - All tool canonical names currently in scope (agent + MCP).
35
+ */
36
+ function buildAliasMaps(aliases, canonicalNames) {
37
+ const aliasByCanonical = /* @__PURE__ */ new Map();
38
+ const canonicalByAlias = /* @__PURE__ */ new Map();
39
+ if (!aliases) return {
40
+ aliasByCanonical,
41
+ canonicalByAlias
42
+ };
43
+ const canonicalSet = new Set(canonicalNames);
44
+ function isRemappedAway(canonical) {
45
+ const mapped = aliases[canonical];
46
+ return typeof mapped === "string" && mapped.length > 0 && mapped !== canonical;
47
+ }
48
+ for (const [canonical, alias] of Object.entries(aliases)) {
49
+ if (typeof alias !== "string" || alias.length === 0) throw new Error(`Tool alias for "${canonical}" must be a non-empty string`);
50
+ if (alias === canonical) continue;
51
+ if (!canonicalSet.has(canonical)) continue;
52
+ if (canonicalSet.has(alias) && !isRemappedAway(alias)) throw new Error(`Tool alias "${canonical}" -> "${alias}" collides with an existing canonical tool name`);
53
+ const existingCanonical = canonicalByAlias.get(alias);
54
+ if (existingCanonical && existingCanonical !== canonical) throw new Error(`Tool alias collision: both "${existingCanonical}" and "${canonical}" map to alias "${alias}"`);
55
+ aliasByCanonical.set(canonical, alias);
56
+ canonicalByAlias.set(alias, canonical);
57
+ }
58
+ return {
59
+ aliasByCanonical,
60
+ canonicalByAlias
61
+ };
62
+ }
63
+ /** Return the alias for a canonical name, falling back to the canonical name itself. */
64
+ function toWireName(canonical, maps) {
65
+ return maps.aliasByCanonical.get(canonical) ?? canonical;
66
+ }
67
+ /** Return the canonical name for a wire name, falling back to the wire name itself. */
68
+ function toCanonicalName(wire, maps) {
69
+ return maps.canonicalByAlias.get(wire) ?? wire;
70
+ }
71
+ /**
72
+ * Tool names must match `^[a-zA-Z0-9_-]{1,N}$`. The charset is universal; the
73
+ * length cap is taken as the STRICTEST across providers (OpenAI/-compat: 64;
74
+ * Anthropic allows 128) so a sanitized name is valid on EVERY provider — and so
75
+ * a mid-session model switch can never make the provider-level drop guard
76
+ * (`sanitizeToolSpecs`) discard a tool we could have kept.
77
+ *
78
+ * MCP tool names are minted verbatim as `mcp_<server>_<tool>` (see
79
+ * `connectMcpServers`), so a server configured as `SSH Ipseity` yields
80
+ * `mcp_SSH Ipseity_exec` — the space (and `.`/`:`/`/`, unicode, or a >64-char
81
+ * join) 400s the request the instant that tool lands in the `tools` array:
82
+ * `tools.N.custom.name: String should match pattern ...`.
83
+ */
84
+ const WIRE_NAME_MAX = 64;
85
+ const WIRE_NAME_OK = /^[\w-]{1,64}$/;
86
+ const WIRE_NAME_BAD_CHAR = /[^\w-]/g;
87
+ /**
88
+ * Build OUTBOUND wire aliases that coerce any tool name violating the provider
89
+ * name constraint into a valid one. Only offenders get an entry; clean setups
90
+ * return `undefined` (no alias map churn, prompt cache untouched).
91
+ *
92
+ * Returned as a `Record` so it merges into `effectiveToolAliases` upstream of
93
+ * BOTH wire-name computations — the `tool_search` catalog and the `tools` array
94
+ * — keeping them in lockstep. Canonical names (dispatch, hooks, persisted
95
+ * turns) never change; only the bytes the model sees do.
96
+ *
97
+ * Scoped to MCP names (the only third-party-controlled, thus only realistically
98
+ * invalid, source). The hash suffix keeps distinct originals distinct even when
99
+ * they collapse to the same replacement; `taken` guards the residual collision.
100
+ */
101
+ function buildSanitizedWireAliases(names, existing) {
102
+ const wireOf = (name) => {
103
+ const alias = existing?.[name];
104
+ return typeof alias === "string" && alias.length > 0 ? alias : name;
105
+ };
106
+ const taken = /* @__PURE__ */ new Set();
107
+ const offenders = [];
108
+ for (const name of names) {
109
+ const wire = wireOf(name);
110
+ if (WIRE_NAME_OK.test(wire)) taken.add(wire);
111
+ else offenders.push(name);
112
+ }
113
+ if (offenders.length === 0) return void 0;
114
+ const out = {};
115
+ for (const name of offenders) {
116
+ const sanitized = sanitizeWireName(wireOf(name), taken);
117
+ out[name] = sanitized;
118
+ taken.add(sanitized);
119
+ }
120
+ return out;
121
+ }
122
+ function sanitizeWireName(name, taken) {
123
+ let base = name.replace(WIRE_NAME_BAD_CHAR, "_");
124
+ if (base.length === 0) base = "tool";
125
+ const hash = fnv1aBase36(name);
126
+ const withSuffix = (suffix) => `${base.slice(0, Math.max(1, WIRE_NAME_MAX - suffix.length))}${suffix}`;
127
+ let candidate = withSuffix(`_${hash}`);
128
+ for (let n = 1; taken.has(candidate); n++) candidate = withSuffix(`_${hash}_${n}`);
129
+ return candidate;
130
+ }
131
+ /**
132
+ * Augment {@link AliasMaps} with INBOUND-ONLY aliases for the Claude Code
133
+ * `mcp__server__tool` double-underscore naming convention. For every MCP
134
+ * tool registered with the canonical `mcp_<server>_<tool>` form, add a
135
+ * `canonicalByAlias` entry mapping the double-underscore variant to the
136
+ * same canonical name. Outbound (`aliasByCanonical`) is left untouched —
137
+ * the model still sees the single-underscore canonical on the wire, so
138
+ * the tools-array byte count (and the provider prompt cache) is
139
+ * unaffected.
140
+ *
141
+ * Why: SDK consumers and tool descriptions across the ecosystem
142
+ * inconsistently reference one form or the other (Anthropic's docs use
143
+ * double, zidane uses single). A Claude-Code-trained model emitting
144
+ * `mcp__acme__apply_migration` against a server zidane registered as
145
+ * `mcp_acme_apply_migration` would otherwise trip the `tool:unknown`
146
+ * path and waste a turn on the correction.
147
+ *
148
+ * Idempotent: a canonical that already has a double-underscore alias
149
+ * mapped (host's explicit `toolAliases` got there first) is left alone.
150
+ * Tools whose canonical name DOESN'T start with `mcp_` (or that contain
151
+ * no inner separator) are skipped — we don't want to invent aliases for
152
+ * non-MCP tools or malformed names.
153
+ *
154
+ * Mutates `maps.canonicalByAlias` in place and returns the same object
155
+ * for chaining.
156
+ */
157
+ function augmentMcpDoubleUnderscoreAliases(maps, canonicalNames) {
158
+ for (const canonical of canonicalNames) {
159
+ if (!canonical.startsWith("mcp_")) continue;
160
+ const tail = canonical.slice(4);
161
+ const sep = tail.indexOf("_");
162
+ if (sep <= 0 || sep >= tail.length - 1) continue;
163
+ const doubleForm = `mcp__${tail.slice(0, sep)}__${tail.slice(sep + 1)}`;
164
+ if (doubleForm === canonical) continue;
165
+ if (maps.canonicalByAlias.has(doubleForm)) continue;
166
+ maps.canonicalByAlias.set(doubleForm, canonical);
167
+ }
168
+ return maps;
169
+ }
170
+ /**
171
+ * Rewrite `tool_call` block names in a content array from canonical → wire for outbound
172
+ * messages sent to the provider. Mutation is non-destructive (returns a new array).
173
+ */
174
+ function rewriteContentToWire(content, maps) {
175
+ if (maps.aliasByCanonical.size === 0) return content;
176
+ return content.map((block) => {
177
+ if (block.type !== "tool_call") return block;
178
+ const wire = maps.aliasByCanonical.get(block.name);
179
+ if (!wire || wire === block.name) return block;
180
+ return {
181
+ ...block,
182
+ name: wire
183
+ };
184
+ });
185
+ }
186
+ /**
187
+ * Rewrite `tool_call` block names in a content array from wire → canonical for inbound
188
+ * messages received from the provider. Non-destructive.
189
+ */
190
+ function rewriteContentToCanonical(content, maps) {
191
+ if (maps.canonicalByAlias.size === 0) return content;
192
+ return content.map((block) => {
193
+ if (block.type !== "tool_call") return block;
194
+ const canonical = maps.canonicalByAlias.get(block.name);
195
+ if (!canonical || canonical === block.name) return block;
196
+ return {
197
+ ...block,
198
+ name: canonical
199
+ };
200
+ });
201
+ }
202
+ /**
203
+ * Rewrite every `SessionMessage.content` in an array from canonical → wire.
204
+ * Returns a new array of new message objects — input messages are not mutated.
205
+ * When the alias map is empty, returns the input by reference (no allocation).
206
+ */
207
+ function rewriteMessagesToWire(messages, maps) {
208
+ if (maps.aliasByCanonical.size === 0) return messages;
209
+ return messages.map((msg) => ({
210
+ ...msg,
211
+ content: rewriteContentToWire(msg.content, maps)
212
+ }));
213
+ }
214
+ //#endregion
215
+ export { rewriteMessagesToWire as a, fnv1aBase36 as c, rewriteContentToCanonical as i, buildAliasMaps as n, toCanonicalName as o, buildSanitizedWireAliases as r, toWireName as s, augmentMcpDoubleUnderscoreAliases as t };
216
+
217
+ //# sourceMappingURL=aliasing-lVFbm81n.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aliasing-lVFbm81n.js","names":[],"sources":["../src/hash.ts","../src/aliasing.ts"],"sourcesContent":["/**\n * FNV-1a (32-bit) rendered in base36 — a tiny, dependency-free, deterministic\n * hash.\n *\n * Used to disambiguate sanitized identifiers: distinct inputs that would\n * otherwise collapse to the same sanitized string (e.g. `a.b` and `a/b` both\n * → `a_b`, or two over-long names truncated to the same prefix) keep a stable,\n * unique suffix. Determinism matters because the suffix must be identical\n * across runs and across a `tool_use` / `tool_result` pair derived from the\n * same original value.\n */\nexport function fnv1aBase36(value: string): string {\n let hash = 0x811C9DC5\n for (let i = 0; i < value.length; i++) {\n hash ^= value.charCodeAt(i)\n hash = Math.imul(hash, 0x01000193)\n }\n return (hash >>> 0).toString(36)\n}\n","/**\n * Tool-name aliasing helpers.\n *\n * Aliasing is applied at the LLM boundary only: the provider sees the aliased\n * name, but hooks and persisted turns use canonical names. See `AgentOptions.toolAliases`.\n */\n\nimport type { SessionContentBlock, SessionMessage } from './types'\nimport { fnv1aBase36 } from './hash'\n\n/** Forward + reverse lookup between canonical and aliased tool names */\nexport interface AliasMaps {\n /** canonical → alias (only entries where alias !== canonical) */\n aliasByCanonical: Map<string, string>\n /** alias → canonical (only entries where alias !== canonical) */\n canonicalByAlias: Map<string, string>\n}\n\n/**\n * Build alias lookup maps from a `toolAliases` record.\n *\n * Validates:\n * - No two canonical names map to the same alias (collision).\n * - No alias collides with another canonical tool name (would shadow).\n *\n * Silently ignores alias entries whose canonical name isn't in `canonicalNames` —\n * preset/agent authors can declare aliases for tools that may be added later via MCP.\n *\n * @param aliases - The `toolAliases` map from the agent options.\n * @param canonicalNames - All tool canonical names currently in scope (agent + MCP).\n */\nexport function buildAliasMaps(\n aliases: Record<string, string> | undefined,\n canonicalNames: Iterable<string>,\n): AliasMaps {\n const aliasByCanonical = new Map<string, string>()\n const canonicalByAlias = new Map<string, string>()\n\n if (!aliases) {\n return { aliasByCanonical, canonicalByAlias }\n }\n\n const canonicalSet = new Set(canonicalNames)\n\n // A canonical name is \"genuinely remapped\" when it has an alias entry that is\n // both non-empty and different from itself. Identity aliases or missing keys\n // mean the tool still answers to its canonical name on the wire.\n function isRemappedAway(canonical: string): boolean {\n const mapped = aliases![canonical]\n return typeof mapped === 'string' && mapped.length > 0 && mapped !== canonical\n }\n\n for (const [canonical, alias] of Object.entries(aliases)) {\n if (typeof alias !== 'string' || alias.length === 0)\n throw new Error(`Tool alias for \"${canonical}\" must be a non-empty string`)\n\n if (alias === canonical)\n continue\n\n if (!canonicalSet.has(canonical))\n continue\n\n // When the alias matches an existing canonical tool name, only allow it if\n // that other canonical is itself being remapped away (i.e. a name swap).\n // Otherwise the wire name would shadow a real tool.\n if (canonicalSet.has(alias) && !isRemappedAway(alias)) {\n throw new Error(`Tool alias \"${canonical}\" -> \"${alias}\" collides with an existing canonical tool name`)\n }\n\n const existingCanonical = canonicalByAlias.get(alias)\n if (existingCanonical && existingCanonical !== canonical) {\n throw new Error(\n `Tool alias collision: both \"${existingCanonical}\" and \"${canonical}\" map to alias \"${alias}\"`,\n )\n }\n\n aliasByCanonical.set(canonical, alias)\n canonicalByAlias.set(alias, canonical)\n }\n\n return { aliasByCanonical, canonicalByAlias }\n}\n\n/** Return the alias for a canonical name, falling back to the canonical name itself. */\nexport function toWireName(canonical: string, maps: AliasMaps): string {\n return maps.aliasByCanonical.get(canonical) ?? canonical\n}\n\n/** Return the canonical name for a wire name, falling back to the wire name itself. */\nexport function toCanonicalName(wire: string, maps: AliasMaps): string {\n return maps.canonicalByAlias.get(wire) ?? wire\n}\n\n/**\n * Tool names must match `^[a-zA-Z0-9_-]{1,N}$`. The charset is universal; the\n * length cap is taken as the STRICTEST across providers (OpenAI/-compat: 64;\n * Anthropic allows 128) so a sanitized name is valid on EVERY provider — and so\n * a mid-session model switch can never make the provider-level drop guard\n * (`sanitizeToolSpecs`) discard a tool we could have kept.\n *\n * MCP tool names are minted verbatim as `mcp_<server>_<tool>` (see\n * `connectMcpServers`), so a server configured as `SSH Ipseity` yields\n * `mcp_SSH Ipseity_exec` — the space (and `.`/`:`/`/`, unicode, or a >64-char\n * join) 400s the request the instant that tool lands in the `tools` array:\n * `tools.N.custom.name: String should match pattern ...`.\n */\nconst WIRE_NAME_MAX = 64\nconst WIRE_NAME_OK = /^[\\w-]{1,64}$/\nconst WIRE_NAME_BAD_CHAR = /[^\\w-]/g\n\n/**\n * Build OUTBOUND wire aliases that coerce any tool name violating the provider\n * name constraint into a valid one. Only offenders get an entry; clean setups\n * return `undefined` (no alias map churn, prompt cache untouched).\n *\n * Returned as a `Record` so it merges into `effectiveToolAliases` upstream of\n * BOTH wire-name computations — the `tool_search` catalog and the `tools` array\n * — keeping them in lockstep. Canonical names (dispatch, hooks, persisted\n * turns) never change; only the bytes the model sees do.\n *\n * Scoped to MCP names (the only third-party-controlled, thus only realistically\n * invalid, source). The hash suffix keeps distinct originals distinct even when\n * they collapse to the same replacement; `taken` guards the residual collision.\n */\nexport function buildSanitizedWireAliases(\n names: Iterable<string>,\n existing: Record<string, string> | undefined,\n): Record<string, string> | undefined {\n const wireOf = (name: string): string => {\n const alias = existing?.[name]\n return typeof alias === 'string' && alias.length > 0 ? alias : name\n }\n\n // Already-valid wire names stay occupied so a freshly minted one can never\n // shadow another tool.\n const taken = new Set<string>()\n const offenders: string[] = []\n for (const name of names) {\n const wire = wireOf(name)\n if (WIRE_NAME_OK.test(wire))\n taken.add(wire)\n else\n offenders.push(name)\n }\n if (offenders.length === 0)\n return undefined\n\n const out: Record<string, string> = {}\n for (const name of offenders) {\n const sanitized = sanitizeWireName(wireOf(name), taken)\n out[name] = sanitized\n taken.add(sanitized)\n }\n return out\n}\n\nfunction sanitizeWireName(name: string, taken: ReadonlySet<string>): string {\n let base = name.replace(WIRE_NAME_BAD_CHAR, '_')\n if (base.length === 0)\n base = 'tool'\n // Hash the ORIGINAL so `a.b` vs `a/b` (both → `a_b`) and truncated long\n // names stay distinct and deterministic across runs.\n const hash = fnv1aBase36(name)\n const withSuffix = (suffix: string): string =>\n `${base.slice(0, Math.max(1, WIRE_NAME_MAX - suffix.length))}${suffix}`\n let candidate = withSuffix(`_${hash}`)\n for (let n = 1; taken.has(candidate); n++)\n candidate = withSuffix(`_${hash}_${n}`)\n return candidate\n}\n\n/**\n * Augment {@link AliasMaps} with INBOUND-ONLY aliases for the Claude Code\n * `mcp__server__tool` double-underscore naming convention. For every MCP\n * tool registered with the canonical `mcp_<server>_<tool>` form, add a\n * `canonicalByAlias` entry mapping the double-underscore variant to the\n * same canonical name. Outbound (`aliasByCanonical`) is left untouched —\n * the model still sees the single-underscore canonical on the wire, so\n * the tools-array byte count (and the provider prompt cache) is\n * unaffected.\n *\n * Why: SDK consumers and tool descriptions across the ecosystem\n * inconsistently reference one form or the other (Anthropic's docs use\n * double, zidane uses single). A Claude-Code-trained model emitting\n * `mcp__acme__apply_migration` against a server zidane registered as\n * `mcp_acme_apply_migration` would otherwise trip the `tool:unknown`\n * path and waste a turn on the correction.\n *\n * Idempotent: a canonical that already has a double-underscore alias\n * mapped (host's explicit `toolAliases` got there first) is left alone.\n * Tools whose canonical name DOESN'T start with `mcp_` (or that contain\n * no inner separator) are skipped — we don't want to invent aliases for\n * non-MCP tools or malformed names.\n *\n * Mutates `maps.canonicalByAlias` in place and returns the same object\n * for chaining.\n */\nexport function augmentMcpDoubleUnderscoreAliases(\n maps: AliasMaps,\n canonicalNames: Iterable<string>,\n): AliasMaps {\n for (const canonical of canonicalNames) {\n if (!canonical.startsWith('mcp_'))\n continue\n // Strip leading `mcp_`, then require AT LEAST one more `_` so the\n // remainder is `<server>_<tool>` (a degenerate `mcp_foo` with no\n // tool segment has nothing meaningful to double-underscore).\n const tail = canonical.slice(4)\n const sep = tail.indexOf('_')\n if (sep <= 0 || sep >= tail.length - 1)\n continue\n const server = tail.slice(0, sep)\n const tool = tail.slice(sep + 1)\n const doubleForm = `mcp__${server}__${tool}`\n if (doubleForm === canonical)\n continue // shouldn't happen but defensive\n if (maps.canonicalByAlias.has(doubleForm))\n continue // host alias or earlier pass got there first\n maps.canonicalByAlias.set(doubleForm, canonical)\n }\n return maps\n}\n\n/**\n * Rewrite `tool_call` block names in a content array from canonical → wire for outbound\n * messages sent to the provider. Mutation is non-destructive (returns a new array).\n */\nexport function rewriteContentToWire(\n content: SessionContentBlock[],\n maps: AliasMaps,\n): SessionContentBlock[] {\n if (maps.aliasByCanonical.size === 0)\n return content\n return content.map((block) => {\n if (block.type !== 'tool_call')\n return block\n const wire = maps.aliasByCanonical.get(block.name)\n if (!wire || wire === block.name)\n return block\n return { ...block, name: wire }\n })\n}\n\n/**\n * Rewrite `tool_call` block names in a content array from wire → canonical for inbound\n * messages received from the provider. Non-destructive.\n */\nexport function rewriteContentToCanonical(\n content: SessionContentBlock[],\n maps: AliasMaps,\n): SessionContentBlock[] {\n if (maps.canonicalByAlias.size === 0)\n return content\n return content.map((block) => {\n if (block.type !== 'tool_call')\n return block\n const canonical = maps.canonicalByAlias.get(block.name)\n if (!canonical || canonical === block.name)\n return block\n return { ...block, name: canonical }\n })\n}\n\n/**\n * Rewrite every `SessionMessage.content` in an array from canonical → wire.\n * Returns a new array of new message objects — input messages are not mutated.\n * When the alias map is empty, returns the input by reference (no allocation).\n */\nexport function rewriteMessagesToWire(\n messages: SessionMessage[],\n maps: AliasMaps,\n): SessionMessage[] {\n if (maps.aliasByCanonical.size === 0)\n return messages\n return messages.map(msg => ({ ...msg, content: rewriteContentToWire(msg.content, maps) }))\n}\n"],"mappings":";;;;;;;;;;;;AAWA,SAAgB,YAAY,OAAuB;CACjD,IAAI,OAAO;CACX,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;EACrC,QAAQ,MAAM,WAAW,CAAC;EAC1B,OAAO,KAAK,KAAK,MAAM,QAAU;CACnC;CACA,QAAQ,SAAS,EAAA,CAAG,SAAS,EAAE;AACjC;;;;;;;;;;;;;;;;ACaA,SAAgB,eACd,SACA,gBACW;CACX,MAAM,mCAAmB,IAAI,IAAoB;CACjD,MAAM,mCAAmB,IAAI,IAAoB;CAEjD,IAAI,CAAC,SACH,OAAO;EAAE;EAAkB;CAAiB;CAG9C,MAAM,eAAe,IAAI,IAAI,cAAc;CAK3C,SAAS,eAAe,WAA4B;EAClD,MAAM,SAAS,QAAS;EACxB,OAAO,OAAO,WAAW,YAAY,OAAO,SAAS,KAAK,WAAW;CACvE;CAEA,KAAK,MAAM,CAAC,WAAW,UAAU,OAAO,QAAQ,OAAO,GAAG;EACxD,IAAI,OAAO,UAAU,YAAY,MAAM,WAAW,GAChD,MAAM,IAAI,MAAM,mBAAmB,UAAU,6BAA6B;EAE5E,IAAI,UAAU,WACZ;EAEF,IAAI,CAAC,aAAa,IAAI,SAAS,GAC7B;EAKF,IAAI,aAAa,IAAI,KAAK,KAAK,CAAC,eAAe,KAAK,GAClD,MAAM,IAAI,MAAM,eAAe,UAAU,QAAQ,MAAM,gDAAgD;EAGzG,MAAM,oBAAoB,iBAAiB,IAAI,KAAK;EACpD,IAAI,qBAAqB,sBAAsB,WAC7C,MAAM,IAAI,MACR,+BAA+B,kBAAkB,SAAS,UAAU,kBAAkB,MAAM,EAC9F;EAGF,iBAAiB,IAAI,WAAW,KAAK;EACrC,iBAAiB,IAAI,OAAO,SAAS;CACvC;CAEA,OAAO;EAAE;EAAkB;CAAiB;AAC9C;;AAGA,SAAgB,WAAW,WAAmB,MAAyB;CACrE,OAAO,KAAK,iBAAiB,IAAI,SAAS,KAAK;AACjD;;AAGA,SAAgB,gBAAgB,MAAc,MAAyB;CACrE,OAAO,KAAK,iBAAiB,IAAI,IAAI,KAAK;AAC5C;;;;;;;;;;;;;;AAeA,MAAM,gBAAgB;AACtB,MAAM,eAAe;AACrB,MAAM,qBAAqB;;;;;;;;;;;;;;;AAgB3B,SAAgB,0BACd,OACA,UACoC;CACpC,MAAM,UAAU,SAAyB;EACvC,MAAM,QAAQ,WAAW;EACzB,OAAO,OAAO,UAAU,YAAY,MAAM,SAAS,IAAI,QAAQ;CACjE;CAIA,MAAM,wBAAQ,IAAI,IAAY;CAC9B,MAAM,YAAsB,CAAC;CAC7B,KAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,OAAO,OAAO,IAAI;EACxB,IAAI,aAAa,KAAK,IAAI,GACxB,MAAM,IAAI,IAAI;OAEd,UAAU,KAAK,IAAI;CACvB;CACA,IAAI,UAAU,WAAW,GACvB,OAAO,KAAA;CAET,MAAM,MAA8B,CAAC;CACrC,KAAK,MAAM,QAAQ,WAAW;EAC5B,MAAM,YAAY,iBAAiB,OAAO,IAAI,GAAG,KAAK;EACtD,IAAI,QAAQ;EACZ,MAAM,IAAI,SAAS;CACrB;CACA,OAAO;AACT;AAEA,SAAS,iBAAiB,MAAc,OAAoC;CAC1E,IAAI,OAAO,KAAK,QAAQ,oBAAoB,GAAG;CAC/C,IAAI,KAAK,WAAW,GAClB,OAAO;CAGT,MAAM,OAAO,YAAY,IAAI;CAC7B,MAAM,cAAc,WAClB,GAAG,KAAK,MAAM,GAAG,KAAK,IAAI,GAAG,gBAAgB,OAAO,MAAM,CAAC,IAAI;CACjE,IAAI,YAAY,WAAW,IAAI,MAAM;CACrC,KAAK,IAAI,IAAI,GAAG,MAAM,IAAI,SAAS,GAAG,KACpC,YAAY,WAAW,IAAI,KAAK,GAAG,GAAG;CACxC,OAAO;AACT;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BA,SAAgB,kCACd,MACA,gBACW;CACX,KAAK,MAAM,aAAa,gBAAgB;EACtC,IAAI,CAAC,UAAU,WAAW,MAAM,GAC9B;EAIF,MAAM,OAAO,UAAU,MAAM,CAAC;EAC9B,MAAM,MAAM,KAAK,QAAQ,GAAG;EAC5B,IAAI,OAAO,KAAK,OAAO,KAAK,SAAS,GACnC;EAGF,MAAM,aAAa,QAFJ,KAAK,MAAM,GAAG,GAEG,EAAE,IADrB,KAAK,MAAM,MAAM,CACW;EACzC,IAAI,eAAe,WACjB;EACF,IAAI,KAAK,iBAAiB,IAAI,UAAU,GACtC;EACF,KAAK,iBAAiB,IAAI,YAAY,SAAS;CACjD;CACA,OAAO;AACT;;;;;AAMA,SAAgB,qBACd,SACA,MACuB;CACvB,IAAI,KAAK,iBAAiB,SAAS,GACjC,OAAO;CACT,OAAO,QAAQ,KAAK,UAAU;EAC5B,IAAI,MAAM,SAAS,aACjB,OAAO;EACT,MAAM,OAAO,KAAK,iBAAiB,IAAI,MAAM,IAAI;EACjD,IAAI,CAAC,QAAQ,SAAS,MAAM,MAC1B,OAAO;EACT,OAAO;GAAE,GAAG;GAAO,MAAM;EAAK;CAChC,CAAC;AACH;;;;;AAMA,SAAgB,0BACd,SACA,MACuB;CACvB,IAAI,KAAK,iBAAiB,SAAS,GACjC,OAAO;CACT,OAAO,QAAQ,KAAK,UAAU;EAC5B,IAAI,MAAM,SAAS,aACjB,OAAO;EACT,MAAM,YAAY,KAAK,iBAAiB,IAAI,MAAM,IAAI;EACtD,IAAI,CAAC,aAAa,cAAc,MAAM,MACpC,OAAO;EACT,OAAO;GAAE,GAAG;GAAO,MAAM;EAAU;CACrC,CAAC;AACH;;;;;;AAOA,SAAgB,sBACd,UACA,MACkB;CAClB,IAAI,KAAK,iBAAiB,SAAS,GACjC,OAAO;CACT,OAAO,SAAS,KAAI,SAAQ;EAAE,GAAG;EAAK,SAAS,qBAAqB,IAAI,SAAS,IAAI;CAAE,EAAE;AAC3F"}
@@ -1,8 +1,8 @@
1
1
  import { t as lazyAsync } from "./lazy-DLOurOC_.js";
2
2
  import { c as classifyErrorPrelude, d as isRetryableHttpStatus, f as matchesContextExceeded, l as errorMessage, p as matchesToolPairingError } from "./errors-DJUxZg9b.js";
3
- import { b as fillEstimatedCost, w as unsupportedMediaError, y as sanitizeToolSpecs } from "./openai-compat-J_JZ7qsw.js";
3
+ import { T as unsupportedMediaError, x as fillEstimatedCost, y as sanitizeToolSpecs } from "./openai-compat-pHI0kBWH.js";
4
4
  import { renderSystemForWire, splitSystemPrompt } from "./prompt.js";
5
- import { l as fromAnthropic, p as toAnthropic } from "./messages-BDpXLFoe.js";
5
+ import { l as fromAnthropic, p as toAnthropic } from "./messages-CvHfYB7f.js";
6
6
  import { i as resolveOAuthApiKey, r as readOAuthCredentials, t as extractRuntimeCredentials } from "./oauth-8LqbeI_Q.js";
7
7
  //#region src/chat/anthropic-models.ts
8
8
  /**
@@ -952,4 +952,4 @@ function anthropic(anthropicParams) {
952
952
  //#endregion
953
953
  export { planAnthropicThinking as a, ANTHROPIC_EXTRA_MODELS as c, defaultAnthropicMaxTokens as i, FAST_MODE_OPTIONS as l, applyAnthropicCacheBreakpoints as n, resolveAnthropicBetas as o, classifyAnthropicError as r, resolveAnthropicMaxOutput as s, anthropic as t };
954
954
 
955
- //# sourceMappingURL=anthropic-uXfsormU.js.map
955
+ //# sourceMappingURL=anthropic-BYsc6qWj.js.map