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.
- package/dist/{acp-C-auiVTk.js → acp-DxYjSCQW.js} +5 -5
- package/dist/{acp-C-auiVTk.js.map → acp-DxYjSCQW.js.map} +1 -1
- package/dist/acp-cli.js +6 -6
- package/dist/acp.js +1 -1
- package/dist/{agent-DhfdXgL2.js → agent-DoEx_WD3.js} +6 -5
- package/dist/{agent-DhfdXgL2.js.map → agent-DoEx_WD3.js.map} +1 -1
- package/dist/agent.js +2 -2
- package/dist/aliasing-lVFbm81n.js +217 -0
- package/dist/aliasing-lVFbm81n.js.map +1 -0
- package/dist/{anthropic-uXfsormU.js → anthropic-BYsc6qWj.js} +3 -3
- package/dist/{anthropic-uXfsormU.js.map → anthropic-BYsc6qWj.js.map} +1 -1
- package/dist/{auth-TZg3MVi2.js → auth-Bb479DFB.js} +4 -4
- package/dist/{auth-TZg3MVi2.js.map → auth-Bb479DFB.js.map} +1 -1
- package/dist/chat.js +3 -3
- package/dist/eval.js +1 -1
- package/dist/extensions.js +1 -1
- package/dist/headless.js +3 -3
- package/dist/index-l0wehkWU.d.ts.map +1 -1
- package/dist/index.js +7 -7
- package/dist/{messages-BDpXLFoe.js → messages-CvHfYB7f.js} +3 -3
- package/dist/{messages-BDpXLFoe.js.map → messages-CvHfYB7f.js.map} +1 -1
- package/dist/{openai-compat-J_JZ7qsw.js → openai-compat-pHI0kBWH.js} +37 -8
- package/dist/openai-compat-pHI0kBWH.js.map +1 -0
- package/dist/presets.js +1 -1
- package/dist/providers/anthropic.js +1 -1
- package/dist/providers/arcee.js +1 -1
- package/dist/providers/baseten.js +1 -1
- package/dist/providers/cerebras.js +1 -1
- package/dist/providers/local.js +1 -1
- package/dist/providers/openai-compat.js +1 -1
- package/dist/providers/openai.js +27 -10
- package/dist/providers/openai.js.map +1 -1
- package/dist/providers/openrouter.js +1 -1
- package/dist/providers/xai.js +1 -1
- package/dist/{providers-CclOzGxc.js → providers-D9Y2RndM.js} +3 -3
- package/dist/{providers-CclOzGxc.js.map → providers-D9Y2RndM.js.map} +1 -1
- package/dist/providers.js +4 -4
- package/dist/{read-state-Dq_TXUX1.js → read-state-rDmfeLmz.js} +3 -196
- package/dist/read-state-rDmfeLmz.js.map +1 -0
- package/dist/restate.js +2 -1
- package/dist/restate.js.map +1 -1
- package/dist/{session-CIXE-Bzp.js → session-DzrXKLw-.js} +2 -2
- package/dist/{session-CIXE-Bzp.js.map → session-DzrXKLw-.js.map} +1 -1
- package/dist/session.js +2 -2
- package/dist/tools.js +2 -2
- package/dist/{transcript-anchors-BzcuKnq8.js → transcript-anchors-yogJHuBW.js} +3 -3
- package/dist/{transcript-anchors-BzcuKnq8.js.map → transcript-anchors-yogJHuBW.js.map} +1 -1
- package/dist/tui.js +6 -5
- package/dist/tui.js.map +1 -1
- package/dist/{xai-D-wALLuZ.js → xai-BwhzoehX.js} +2 -2
- package/dist/{xai-D-wALLuZ.js.map → xai-BwhzoehX.js.map} +1 -1
- package/package.json +1 -1
- package/dist/hash-DJRzmcPI.js +0 -24
- package/dist/hash-DJRzmcPI.js.map +0 -1
- package/dist/openai-compat-J_JZ7qsw.js.map +0 -1
- 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-
|
|
2
|
-
import { t as createAgent } from "./agent-
|
|
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":"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"}
|
|
@@ -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 {
|
|
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-
|
|
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-
|
|
955
|
+
//# sourceMappingURL=anthropic-BYsc6qWj.js.map
|