@code-yeongyu/senpi-ai 2026.9.24 → 2026.9.25
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/api/anthropic-tool-references.d.ts.map +1 -1
- package/dist/api/anthropic-tool-references.js +8 -35
- package/dist/api/anthropic-tool-references.js.map +1 -1
- package/dist/api/bedrock-converse-stream.js +16 -3
- package/dist/api/bedrock-converse-stream.js.map +1 -1
- package/dist/api/google-shared.d.ts.map +1 -1
- package/dist/api/google-shared.js +24 -17
- package/dist/api/google-shared.js.map +1 -1
- package/dist/api/openai-completions.d.ts.map +1 -1
- package/dist/api/openai-completions.js +67 -9
- package/dist/api/openai-completions.js.map +1 -1
- package/dist/api/openai-responses-prompt-cache.d.ts +24 -0
- package/dist/api/openai-responses-prompt-cache.d.ts.map +1 -0
- package/dist/api/openai-responses-prompt-cache.js +62 -0
- package/dist/api/openai-responses-prompt-cache.js.map +1 -0
- package/dist/api/openai-responses-shared.d.ts +6 -0
- package/dist/api/openai-responses-shared.d.ts.map +1 -1
- package/dist/api/openai-responses-shared.js +16 -7
- package/dist/api/openai-responses-shared.js.map +1 -1
- package/dist/api/openai-responses.d.ts +11 -1
- package/dist/api/openai-responses.d.ts.map +1 -1
- package/dist/api/openai-responses.js +114 -8
- package/dist/api/openai-responses.js.map +1 -1
- package/dist/api/openai-responses.lazy.d.ts.map +1 -1
- package/dist/api/openai-responses.lazy.js +5 -0
- package/dist/api/openai-responses.lazy.js.map +1 -1
- package/dist/api/openrouter-images.js +1 -1
- package/dist/api/openrouter-images.js.map +1 -1
- package/dist/api/prompt-cache-warmers.d.ts +13 -0
- package/dist/api/prompt-cache-warmers.d.ts.map +1 -0
- package/dist/api/prompt-cache-warmers.js +8 -0
- package/dist/api/prompt-cache-warmers.js.map +1 -0
- package/dist/api/warm-prompt-cache.d.ts +4 -2
- package/dist/api/warm-prompt-cache.d.ts.map +1 -1
- package/dist/api/warm-prompt-cache.js +22 -0
- package/dist/api/warm-prompt-cache.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/models.d.ts +6 -0
- package/dist/models.d.ts.map +1 -1
- package/dist/models.js +15 -0
- package/dist/models.js.map +1 -1
- package/dist/openai-responses-compat.d.ts +17 -0
- package/dist/openai-responses-compat.d.ts.map +1 -1
- package/dist/openai-responses-compat.js +4 -1
- package/dist/openai-responses-compat.js.map +1 -1
- package/dist/providers/data/.manifest.json +1 -1
- package/dist/providers/data/cerebras.json +1 -1
- package/dist/providers/data/chatgpt-subscription.json +1 -1
- package/dist/providers/data/google-vertex.json +1 -1
- package/dist/providers/data/openai.json +1 -1
- package/dist/providers/data/openrouter.json +1 -1
- package/dist/providers/data/vercel-ai-gateway.json +1 -1
- package/dist/types.d.ts +19 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/prompt-cache-ttl.d.ts +30 -0
- package/dist/utils/prompt-cache-ttl.d.ts.map +1 -1
- package/dist/utils/prompt-cache-ttl.js +71 -14
- package/dist/utils/prompt-cache-ttl.js.map +1 -1
- package/dist/utils/retry.d.ts.map +1 -1
- package/dist/utils/retry.js +8 -0
- package/dist/utils/retry.js.map +1 -1
- package/dist/utils/tool-choice-fallback.d.ts.map +1 -1
- package/dist/utils/tool-choice-fallback.js +7 -1
- package/dist/utils/tool-choice-fallback.js.map +1 -1
- package/dist/utils/tool-name-match.d.ts +30 -0
- package/dist/utils/tool-name-match.d.ts.map +1 -0
- package/dist/utils/tool-name-match.js +71 -0
- package/dist/utils/tool-name-match.js.map +1 -0
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"anthropic-tool-references.d.ts","sourceRoot":"","sources":["../../src/api/anthropic-tool-references.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEX,4BAA4B,EAE5B,MAAM,uDAAuD,CAAC;
|
|
1
|
+
{"version":3,"file":"anthropic-tool-references.d.ts","sourceRoot":"","sources":["../../src/api/anthropic-tool-references.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEX,4BAA4B,EAE5B,MAAM,uDAAuD,CAAC;AA8D/D,wBAAgB,+BAA+B,CAAC,MAAM,EAAE,4BAA4B,GAAG,4BAA4B,CAkIlH"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { resolveToolNameMatch } from "../utils/tool-name-match.js";
|
|
1
2
|
import { demotedToolCallText, demotedToolResultText } from "../utils/unavailable-tool-text.js";
|
|
2
3
|
function isRecord(value) {
|
|
3
4
|
return typeof value === "object" && value !== null;
|
|
@@ -27,14 +28,11 @@ function isRecord(value) {
|
|
|
27
28
|
* The same wire path can also recase the tool it namespaces (`memory` comes
|
|
28
29
|
* back as `mcp__a4e6__Memory`, `lsp_symbols` as `mcp__a4e6__LspSymbols`), so
|
|
29
30
|
* the suffix alone no longer matches the request's tool name byte for byte.
|
|
30
|
-
* Names are therefore
|
|
31
|
-
*
|
|
32
|
-
*
|
|
31
|
+
* Names are therefore resolved by the shared lenient matcher
|
|
32
|
+
* (`utils/tool-name-match.ts`, also used by the inbound tool-call resolver):
|
|
33
|
+
* case and `_`/`-` folded away, an `mcp_`/`mcp__` prefix stripped on either
|
|
34
|
+
* side, and a name resolves only when exactly one request tool matches.
|
|
33
35
|
*/
|
|
34
|
-
const GATEWAY_TOOL_NAMESPACE = /^mcp__[^_]+__(.+)$/;
|
|
35
|
-
function foldToolNameKey(name) {
|
|
36
|
-
return name.toLowerCase().replaceAll(/[-_]/g, "");
|
|
37
|
-
}
|
|
38
36
|
function collectAvailableToolNames(tools) {
|
|
39
37
|
const defined = new Set();
|
|
40
38
|
if (Array.isArray(tools)) {
|
|
@@ -43,32 +41,7 @@ function collectAvailableToolNames(tools) {
|
|
|
43
41
|
defined.add(tool.name);
|
|
44
42
|
}
|
|
45
43
|
}
|
|
46
|
-
|
|
47
|
-
const ambiguous = new Set();
|
|
48
|
-
for (const name of defined) {
|
|
49
|
-
const key = foldToolNameKey(name);
|
|
50
|
-
if (folded.has(key))
|
|
51
|
-
ambiguous.add(key);
|
|
52
|
-
else
|
|
53
|
-
folded.set(key, name);
|
|
54
|
-
}
|
|
55
|
-
for (const key of ambiguous)
|
|
56
|
-
folded.delete(key);
|
|
57
|
-
return { defined, folded };
|
|
58
|
-
}
|
|
59
|
-
function resolveAvailableToolName(name, available) {
|
|
60
|
-
const suffix = GATEWAY_TOOL_NAMESPACE.exec(name)?.[1];
|
|
61
|
-
const candidates = suffix === undefined ? [name] : [name, suffix];
|
|
62
|
-
for (const candidate of candidates) {
|
|
63
|
-
if (available.defined.has(candidate))
|
|
64
|
-
return candidate;
|
|
65
|
-
}
|
|
66
|
-
for (const candidate of candidates) {
|
|
67
|
-
const folded = available.folded.get(foldToolNameKey(candidate));
|
|
68
|
-
if (folded !== undefined)
|
|
69
|
-
return folded;
|
|
70
|
-
}
|
|
71
|
-
return undefined;
|
|
44
|
+
return defined;
|
|
72
45
|
}
|
|
73
46
|
function isNativeToolSearchResultBlock(block) {
|
|
74
47
|
return (isRecord(block) &&
|
|
@@ -82,7 +55,7 @@ export function demoteUnavailableToolReferences(params) {
|
|
|
82
55
|
if (!Array.isArray(messages) || messages.length === 0)
|
|
83
56
|
return params;
|
|
84
57
|
const available = collectAvailableToolNames(params.tools);
|
|
85
|
-
const resolve = (name) =>
|
|
58
|
+
const resolve = (name) => resolveToolNameMatch(name, available);
|
|
86
59
|
const demotedCallNames = new Map();
|
|
87
60
|
const renamedCallNames = new Map();
|
|
88
61
|
for (const message of messages) {
|
|
@@ -99,7 +72,7 @@ export function demoteUnavailableToolReferences(params) {
|
|
|
99
72
|
}
|
|
100
73
|
}
|
|
101
74
|
let changed = false;
|
|
102
|
-
const availableToolNames = [...available
|
|
75
|
+
const availableToolNames = [...available];
|
|
103
76
|
const seenDemotedCallNames = new Set();
|
|
104
77
|
const rewrittenMessages = [];
|
|
105
78
|
for (const message of messages) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"anthropic-tool-references.js","sourceRoot":"","sources":["../../src/api/anthropic-tool-references.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n\tBetaContentBlockParam as ContentBlockParam,\n\tMessageCreateParamsStreaming,\n\tBetaMessageParam as MessageParam,\n} from \"@anthropic-ai/sdk/resources/beta/messages/messages.js\";\nimport { demotedToolCallText, demotedToolResultText } from \"../utils/unavailable-tool-text.ts\";\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null;\n}\n\n/**\n * Anthropic validates that every tool referenced by the message history is\n * available in the same request — defined in `tools` or discovered through a\n * `tool_reference` block — and rejects the whole request otherwise\n * (\"Tool reference '<name>' not found in available tools\"). Sessions outlive\n * their tools: an MCP server can be absent after a resume, an extension can\n * stop registering a tool, or a payload hook can strip a definition while the\n * history still carries the call. Demote those references to plain text so\n * the turn can proceed; the matching tool_result is demoted in lockstep so no\n * orphan pairing error replaces the original one.\n *\n * Availability is decided by the request's `tools` array alone. A discovered\n * name never stands in for a missing definition: a `tool_reference` without a\n * definition is itself rejected, so it cannot keep a later `tool_use` alive.\n *\n * Native tool search results (`tool_search_tool_result`) replay verbatim on the\n * same model, and the wire path can hand their references back under a gateway\n * namespace (`mcp__<id>__<tool>`) that senpi never defined and that does not\n * survive across requests. Those references are folded back to the request's\n * own tool names; a reference that still does not resolve is dropped, and a\n * search pair left with no references is demoted to text.\n *\n * The same wire path can also recase the tool it namespaces (`memory` comes\n * back as `mcp__a4e6__Memory`, `lsp_symbols` as `mcp__a4e6__LspSymbols`), so\n * the suffix alone no longer matches the request's tool name byte for byte.\n * Names are therefore compared with case and `_`/`-` separators folded away,\n * and a folded key resolves only when exactly one request tool owns it: the\n * fold never guesses between two candidates.\n */\nconst GATEWAY_TOOL_NAMESPACE = /^mcp__[^_]+__(.+)$/;\n\ninterface AvailableToolNames {\n\treadonly defined: ReadonlySet<string>;\n\treadonly folded: ReadonlyMap<string, string>;\n}\n\nfunction foldToolNameKey(name: string): string {\n\treturn name.toLowerCase().replaceAll(/[-_]/g, \"\");\n}\n\nfunction collectAvailableToolNames(tools: unknown): AvailableToolNames {\n\tconst defined = new Set<string>();\n\tif (Array.isArray(tools)) {\n\t\tfor (const tool of tools) {\n\t\t\tif (isRecord(tool) && typeof tool.name === \"string\") defined.add(tool.name);\n\t\t}\n\t}\n\tconst folded = new Map<string, string>();\n\tconst ambiguous = new Set<string>();\n\tfor (const name of defined) {\n\t\tconst key = foldToolNameKey(name);\n\t\tif (folded.has(key)) ambiguous.add(key);\n\t\telse folded.set(key, name);\n\t}\n\tfor (const key of ambiguous) folded.delete(key);\n\treturn { defined, folded };\n}\n\nfunction resolveAvailableToolName(name: string, available: AvailableToolNames): string | undefined {\n\tconst suffix = GATEWAY_TOOL_NAMESPACE.exec(name)?.[1];\n\tconst candidates = suffix === undefined ? [name] : [name, suffix];\n\tfor (const candidate of candidates) {\n\t\tif (available.defined.has(candidate)) return candidate;\n\t}\n\tfor (const candidate of candidates) {\n\t\tconst folded = available.folded.get(foldToolNameKey(candidate));\n\t\tif (folded !== undefined) return folded;\n\t}\n\treturn undefined;\n}\n\nfunction isNativeToolSearchResultBlock(block: unknown): block is Record<string, unknown> & {\n\ttype: \"tool_search_tool_result\";\n\ttool_use_id: string;\n\tcontent: Record<string, unknown> & { tool_references: unknown[] };\n} {\n\treturn (\n\t\tisRecord(block) &&\n\t\tblock.type === \"tool_search_tool_result\" &&\n\t\ttypeof block.tool_use_id === \"string\" &&\n\t\tisRecord(block.content) &&\n\t\tArray.isArray(block.content.tool_references)\n\t);\n}\n\nexport function demoteUnavailableToolReferences(params: MessageCreateParamsStreaming): MessageCreateParamsStreaming {\n\tconst messages = params.messages;\n\tif (!Array.isArray(messages) || messages.length === 0) return params;\n\n\tconst available = collectAvailableToolNames(params.tools);\n\tconst resolve = (name: string): string | undefined => resolveAvailableToolName(name, available);\n\n\tconst demotedCallNames = new Map<string, string>();\n\tconst renamedCallNames = new Map<string, string>();\n\tfor (const message of messages) {\n\t\tif (message.role !== \"assistant\" || !Array.isArray(message.content)) continue;\n\t\tfor (const block of message.content) {\n\t\t\tif (!isRecord(block) || block.type !== \"tool_use\" || typeof block.name !== \"string\") continue;\n\t\t\tconst resolved = resolve(block.name);\n\t\t\tif (resolved === undefined) demotedCallNames.set(block.id, block.name);\n\t\t\telse if (resolved !== block.name) renamedCallNames.set(block.id, resolved);\n\t\t}\n\t}\n\n\tlet changed = false;\n\tconst availableToolNames = [...available.defined];\n\tconst seenDemotedCallNames = new Set<string>();\n\tconst rewrittenMessages: MessageParam[] = [];\n\tfor (const message of messages) {\n\t\tif (!Array.isArray(message.content)) {\n\t\t\trewrittenMessages.push(message);\n\t\t\tcontinue;\n\t\t}\n\t\tlet messageChanged = false;\n\t\t// A native search pair whose every reference stopped resolving is demoted\n\t\t// as a unit: the result decides, and its `server_tool_use` follows.\n\t\tconst droppedSearchUseIds = new Set<string>();\n\t\tconst droppedSearchNames = new Map<string, string[]>();\n\t\tif (message.role === \"assistant\") {\n\t\t\tfor (const block of message.content) {\n\t\t\t\tif (!isNativeToolSearchResultBlock(block)) continue;\n\t\t\t\tconst names = block.content.tool_references\n\t\t\t\t\t.filter((item): item is Record<string, unknown> => isRecord(item) && item.type === \"tool_reference\")\n\t\t\t\t\t.map((item) => (typeof item.tool_name === \"string\" ? item.tool_name : \"\"));\n\t\t\t\tif (names.length > 0 && names.every((name) => resolve(name) === undefined)) {\n\t\t\t\t\tdroppedSearchUseIds.add(block.tool_use_id);\n\t\t\t\t\tdroppedSearchNames.set(block.tool_use_id, names);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tconst content: ContentBlockParam[] = [];\n\t\tfor (const block of message.content) {\n\t\t\tif (message.role === \"assistant\" && isRecord(block) && block.type === \"tool_use\") {\n\t\t\t\tconst demotedName = demotedCallNames.get(block.id);\n\t\t\t\tif (demotedName !== undefined) {\n\t\t\t\t\tmessageChanged = true;\n\t\t\t\t\tconst firstOccurrence = !seenDemotedCallNames.has(demotedName);\n\t\t\t\t\tseenDemotedCallNames.add(demotedName);\n\t\t\t\t\tcontent.push({\n\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\ttext: demotedToolCallText(demotedName, availableToolNames, firstOccurrence),\n\t\t\t\t\t});\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst renamedName = renamedCallNames.get(block.id);\n\t\t\t\tif (renamedName !== undefined) {\n\t\t\t\t\tmessageChanged = true;\n\t\t\t\t\tcontent.push({ ...block, name: renamedName } as ContentBlockParam);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (message.role === \"assistant\" && isRecord(block) && block.type === \"server_tool_use\") {\n\t\t\t\tif (typeof block.id === \"string\" && droppedSearchUseIds.has(block.id)) {\n\t\t\t\t\tmessageChanged = true;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (message.role === \"assistant\" && isNativeToolSearchResultBlock(block)) {\n\t\t\t\tconst omitted = droppedSearchNames.get(block.tool_use_id);\n\t\t\t\tif (omitted !== undefined) {\n\t\t\t\t\tmessageChanged = true;\n\t\t\t\t\tcontent.push({ type: \"text\", text: `Tool reference unavailable: ${[...new Set(omitted)].join(\", \")}` });\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst rewritten = rewriteToolReferenceItems(block.content.tool_references, resolve);\n\t\t\t\tif (rewritten !== undefined) {\n\t\t\t\t\tmessageChanged = true;\n\t\t\t\t\tcontent.push({\n\t\t\t\t\t\t...block,\n\t\t\t\t\t\tcontent: { ...block.content, tool_references: rewritten.kept },\n\t\t\t\t\t} as ContentBlockParam);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (isRecord(block) && block.type === \"tool_result\") {\n\t\t\t\tconst demotedName = demotedCallNames.get(block.tool_use_id);\n\t\t\t\tif (demotedName !== undefined) {\n\t\t\t\t\tmessageChanged = true;\n\t\t\t\t\tcontent.push({ type: \"text\", text: demotedToolResultText(demotedName, toolResultText(block.content)) });\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (Array.isArray(block.content)) {\n\t\t\t\t\tconst rewritten = rewriteToolReferenceItems(block.content, resolve);\n\t\t\t\t\tif (rewritten !== undefined) {\n\t\t\t\t\t\tmessageChanged = true;\n\t\t\t\t\t\tconst nextContent =\n\t\t\t\t\t\t\trewritten.kept.length > 0\n\t\t\t\t\t\t\t\t? rewritten.kept\n\t\t\t\t\t\t\t\t: [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\t\t\t\t\ttext: `Tool reference unavailable: ${[...new Set(rewritten.omitted)].join(\", \")}`,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t];\n\t\t\t\t\t\tcontent.push({ ...block, content: nextContent } as ContentBlockParam);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontent.push(block);\n\t\t}\n\t\tif (content.length === 0) {\n\t\t\tchanged = true;\n\t\t\tcontinue;\n\t\t}\n\t\tif (messageChanged) {\n\t\t\tchanged = true;\n\t\t\trewrittenMessages.push({ ...message, content });\n\t\t\tcontinue;\n\t\t}\n\t\trewrittenMessages.push(message);\n\t}\n\n\tif (!changed) return params;\n\treturn { ...params, messages: rewrittenMessages };\n}\n\n/**\n * Folds every `tool_reference` item in `items` onto the request's own tool\n * name and drops the ones that still do not resolve. Returns undefined when\n * nothing changed so callers can keep the original block identity.\n */\nfunction rewriteToolReferenceItems(\n\titems: readonly unknown[],\n\tresolve: (name: string) => string | undefined,\n): { kept: unknown[]; omitted: string[] } | undefined {\n\tconst kept: unknown[] = [];\n\tconst omitted: string[] = [];\n\tlet rewritten = false;\n\tfor (const item of items) {\n\t\tif (!isRecord(item) || item.type !== \"tool_reference\" || typeof item.tool_name !== \"string\") {\n\t\t\tkept.push(item);\n\t\t\tcontinue;\n\t\t}\n\t\tconst resolved = resolve(item.tool_name);\n\t\tif (resolved === undefined) {\n\t\t\tomitted.push(item.tool_name);\n\t\t\trewritten = true;\n\t\t\tcontinue;\n\t\t}\n\t\tif (resolved !== item.tool_name) {\n\t\t\tkept.push({ ...item, tool_name: resolved });\n\t\t\trewritten = true;\n\t\t\tcontinue;\n\t\t}\n\t\tkept.push(item);\n\t}\n\treturn rewritten ? { kept, omitted } : undefined;\n}\n\nfunction toolResultText(content: unknown): string {\n\tif (typeof content === \"string\") return content;\n\tif (Array.isArray(content)) {\n\t\tconst parts: string[] = [];\n\t\tfor (const item of content) {\n\t\t\tif (!isRecord(item)) continue;\n\t\t\tif (item.type === \"text\" && typeof item.text === \"string\") parts.push(item.text);\n\t\t\telse if (typeof item.type === \"string\") parts.push(`[${item.type}]`);\n\t\t}\n\t\tif (parts.length > 0) return parts.join(\"\\n\");\n\t}\n\treturn \"Tool output unavailable.\";\n}\n"]}
|
|
1
|
+
{"version":3,"file":"anthropic-tool-references.js","sourceRoot":"","sources":["../../src/api/anthropic-tool-references.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAC;AAE/F,SAAS,QAAQ,CAAC,KAAc;IAC/B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC;AACpD,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,SAAS,yBAAyB,CAAC,KAAc;IAChD,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YAC1B,IAAI,QAAQ,CAAC,IAAI,CAAC,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ;gBAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7E,CAAC;IACF,CAAC;IACD,OAAO,OAAO,CAAC;AAChB,CAAC;AAED,SAAS,6BAA6B,CAAC,KAAc;IAKpD,OAAO,CACN,QAAQ,CAAC,KAAK,CAAC;QACf,KAAK,CAAC,IAAI,KAAK,yBAAyB;QACxC,OAAO,KAAK,CAAC,WAAW,KAAK,QAAQ;QACrC,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC;QACvB,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,eAAe,CAAC,CAC5C,CAAC;AACH,CAAC;AAED,MAAM,UAAU,+BAA+B,CAAC,MAAoC;IACnF,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;IACjC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC;IAErE,MAAM,SAAS,GAAG,yBAAyB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC1D,MAAM,OAAO,GAAG,CAAC,IAAY,EAAsB,EAAE,CAAC,oBAAoB,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAE5F,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAkB,CAAC;IACnD,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAkB,CAAC;IACnD,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAChC,IAAI,OAAO,CAAC,IAAI,KAAK,WAAW,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC;YAAE,SAAS;QAC9E,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YACrC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ;gBAAE,SAAS;YAC9F,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACrC,IAAI,QAAQ,KAAK,SAAS;gBAAE,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;iBAClE,IAAI,QAAQ,KAAK,KAAK,CAAC,IAAI;gBAAE,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;QAC5E,CAAC;IACF,CAAC;IAED,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,MAAM,kBAAkB,GAAG,CAAC,GAAG,SAAS,CAAC,CAAC;IAC1C,MAAM,oBAAoB,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/C,MAAM,iBAAiB,GAAmB,EAAE,CAAC;IAC7C,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAChC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YACrC,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAChC,SAAS;QACV,CAAC;QACD,IAAI,cAAc,GAAG,KAAK,CAAC;QAC3B,0EAA0E;QAC1E,oEAAoE;QACpE,MAAM,mBAAmB,GAAG,IAAI,GAAG,EAAU,CAAC;QAC9C,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAAoB,CAAC;QACvD,IAAI,OAAO,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YAClC,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBACrC,IAAI,CAAC,6BAA6B,CAAC,KAAK,CAAC;oBAAE,SAAS;gBACpD,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,eAAe;qBACzC,MAAM,CAAC,CAAC,IAAI,EAAmC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,KAAK,gBAAgB,CAAC;qBACnG,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;gBAC5E,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,SAAS,CAAC,EAAE,CAAC;oBAC5E,mBAAmB,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;oBAC3C,kBAAkB,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;gBAClD,CAAC;YACF,CAAC;QACF,CAAC;QACD,MAAM,OAAO,GAAwB,EAAE,CAAC;QACxC,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YACrC,IAAI,OAAO,CAAC,IAAI,KAAK,WAAW,IAAI,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;gBAClF,MAAM,WAAW,GAAG,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;gBACnD,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;oBAC/B,cAAc,GAAG,IAAI,CAAC;oBACtB,MAAM,eAAe,GAAG,CAAC,oBAAoB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;oBAC/D,oBAAoB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;oBACtC,OAAO,CAAC,IAAI,CAAC;wBACZ,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,mBAAmB,CAAC,WAAW,EAAE,kBAAkB,EAAE,eAAe,CAAC;qBAC3E,CAAC,CAAC;oBACH,SAAS;gBACV,CAAC;gBACD,MAAM,WAAW,GAAG,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;gBACnD,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;oBAC/B,cAAc,GAAG,IAAI,CAAC;oBACtB,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,EAAE,IAAI,EAAE,WAAW,EAAuB,CAAC,CAAC;oBACnE,SAAS;gBACV,CAAC;YACF,CAAC;YACD,IAAI,OAAO,CAAC,IAAI,KAAK,WAAW,IAAI,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;gBACzF,IAAI,OAAO,KAAK,CAAC,EAAE,KAAK,QAAQ,IAAI,mBAAmB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;oBACvE,cAAc,GAAG,IAAI,CAAC;oBACtB,SAAS;gBACV,CAAC;YACF,CAAC;YACD,IAAI,OAAO,CAAC,IAAI,KAAK,WAAW,IAAI,6BAA6B,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC1E,MAAM,OAAO,GAAG,kBAAkB,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;gBAC1D,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;oBAC3B,cAAc,GAAG,IAAI,CAAC;oBACtB,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,+BAA+B,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;oBACxG,SAAS;gBACV,CAAC;gBACD,MAAM,SAAS,GAAG,yBAAyB,CAAC,KAAK,CAAC,OAAO,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;gBACpF,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;oBAC7B,cAAc,GAAG,IAAI,CAAC;oBACtB,OAAO,CAAC,IAAI,CAAC;wBACZ,GAAG,KAAK;wBACR,OAAO,EAAE,EAAE,GAAG,KAAK,CAAC,OAAO,EAAE,eAAe,EAAE,SAAS,CAAC,IAAI,EAAE;qBACzC,CAAC,CAAC;oBACxB,SAAS;gBACV,CAAC;YACF,CAAC;YACD,IAAI,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;gBACrD,MAAM,WAAW,GAAG,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;gBAC5D,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;oBAC/B,cAAc,GAAG,IAAI,CAAC;oBACtB,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,qBAAqB,CAAC,WAAW,EAAE,cAAc,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;oBACxG,SAAS;gBACV,CAAC;gBACD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;oBAClC,MAAM,SAAS,GAAG,yBAAyB,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;oBACpE,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;wBAC7B,cAAc,GAAG,IAAI,CAAC;wBACtB,MAAM,WAAW,GAChB,SAAS,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC;4BACxB,CAAC,CAAC,SAAS,CAAC,IAAI;4BAChB,CAAC,CAAC;gCACA;oCACC,IAAI,EAAE,MAAM;oCACZ,IAAI,EAAE,+BAA+B,CAAC,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;iCACjF;6BACD,CAAC;wBACL,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,EAAE,OAAO,EAAE,WAAW,EAAuB,CAAC,CAAC;wBACtE,SAAS;oBACV,CAAC;gBACF,CAAC;YACF,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;QACD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,GAAG,IAAI,CAAC;YACf,SAAS;QACV,CAAC;QACD,IAAI,cAAc,EAAE,CAAC;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,iBAAiB,CAAC,IAAI,CAAC,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;YAChD,SAAS;QACV,CAAC;QACD,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACjC,CAAC;IAED,IAAI,CAAC,OAAO;QAAE,OAAO,MAAM,CAAC;IAC5B,OAAO,EAAE,GAAG,MAAM,EAAE,QAAQ,EAAE,iBAAiB,EAAE,CAAC;AACnD,CAAC;AAED;;;;GAIG;AACH,SAAS,yBAAyB,CACjC,KAAyB,EACzB,OAA6C;IAE7C,MAAM,IAAI,GAAc,EAAE,CAAC;IAC3B,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QAC1B,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,KAAK,gBAAgB,IAAI,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ,EAAE,CAAC;YAC7F,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAChB,SAAS;QACV,CAAC;QACD,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACzC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC5B,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC7B,SAAS,GAAG,IAAI,CAAC;YACjB,SAAS;QACV,CAAC;QACD,IAAI,QAAQ,KAAK,IAAI,CAAC,SAAS,EAAE,CAAC;YACjC,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC;YAC5C,SAAS,GAAG,IAAI,CAAC;YACjB,SAAS;QACV,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjB,CAAC;IACD,OAAO,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AAClD,CAAC;AAED,SAAS,cAAc,CAAC,OAAgB;IACvC,IAAI,OAAO,OAAO,KAAK,QAAQ;QAAE,OAAO,OAAO,CAAC;IAChD,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;YAC5B,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;gBAAE,SAAS;YAC9B,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ;gBAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;iBAC5E,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ;gBAAE,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;QACtE,CAAC;QACD,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/C,CAAC;IACD,OAAO,0BAA0B,CAAC;AACnC,CAAC","sourcesContent":["import type {\n\tBetaContentBlockParam as ContentBlockParam,\n\tMessageCreateParamsStreaming,\n\tBetaMessageParam as MessageParam,\n} from \"@anthropic-ai/sdk/resources/beta/messages/messages.js\";\nimport { resolveToolNameMatch } from \"../utils/tool-name-match.ts\";\nimport { demotedToolCallText, demotedToolResultText } from \"../utils/unavailable-tool-text.ts\";\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null;\n}\n\n/**\n * Anthropic validates that every tool referenced by the message history is\n * available in the same request — defined in `tools` or discovered through a\n * `tool_reference` block — and rejects the whole request otherwise\n * (\"Tool reference '<name>' not found in available tools\"). Sessions outlive\n * their tools: an MCP server can be absent after a resume, an extension can\n * stop registering a tool, or a payload hook can strip a definition while the\n * history still carries the call. Demote those references to plain text so\n * the turn can proceed; the matching tool_result is demoted in lockstep so no\n * orphan pairing error replaces the original one.\n *\n * Availability is decided by the request's `tools` array alone. A discovered\n * name never stands in for a missing definition: a `tool_reference` without a\n * definition is itself rejected, so it cannot keep a later `tool_use` alive.\n *\n * Native tool search results (`tool_search_tool_result`) replay verbatim on the\n * same model, and the wire path can hand their references back under a gateway\n * namespace (`mcp__<id>__<tool>`) that senpi never defined and that does not\n * survive across requests. Those references are folded back to the request's\n * own tool names; a reference that still does not resolve is dropped, and a\n * search pair left with no references is demoted to text.\n *\n * The same wire path can also recase the tool it namespaces (`memory` comes\n * back as `mcp__a4e6__Memory`, `lsp_symbols` as `mcp__a4e6__LspSymbols`), so\n * the suffix alone no longer matches the request's tool name byte for byte.\n * Names are therefore resolved by the shared lenient matcher\n * (`utils/tool-name-match.ts`, also used by the inbound tool-call resolver):\n * case and `_`/`-` folded away, an `mcp_`/`mcp__` prefix stripped on either\n * side, and a name resolves only when exactly one request tool matches.\n */\nfunction collectAvailableToolNames(tools: unknown): ReadonlySet<string> {\n\tconst defined = new Set<string>();\n\tif (Array.isArray(tools)) {\n\t\tfor (const tool of tools) {\n\t\t\tif (isRecord(tool) && typeof tool.name === \"string\") defined.add(tool.name);\n\t\t}\n\t}\n\treturn defined;\n}\n\nfunction isNativeToolSearchResultBlock(block: unknown): block is Record<string, unknown> & {\n\ttype: \"tool_search_tool_result\";\n\ttool_use_id: string;\n\tcontent: Record<string, unknown> & { tool_references: unknown[] };\n} {\n\treturn (\n\t\tisRecord(block) &&\n\t\tblock.type === \"tool_search_tool_result\" &&\n\t\ttypeof block.tool_use_id === \"string\" &&\n\t\tisRecord(block.content) &&\n\t\tArray.isArray(block.content.tool_references)\n\t);\n}\n\nexport function demoteUnavailableToolReferences(params: MessageCreateParamsStreaming): MessageCreateParamsStreaming {\n\tconst messages = params.messages;\n\tif (!Array.isArray(messages) || messages.length === 0) return params;\n\n\tconst available = collectAvailableToolNames(params.tools);\n\tconst resolve = (name: string): string | undefined => resolveToolNameMatch(name, available);\n\n\tconst demotedCallNames = new Map<string, string>();\n\tconst renamedCallNames = new Map<string, string>();\n\tfor (const message of messages) {\n\t\tif (message.role !== \"assistant\" || !Array.isArray(message.content)) continue;\n\t\tfor (const block of message.content) {\n\t\t\tif (!isRecord(block) || block.type !== \"tool_use\" || typeof block.name !== \"string\") continue;\n\t\t\tconst resolved = resolve(block.name);\n\t\t\tif (resolved === undefined) demotedCallNames.set(block.id, block.name);\n\t\t\telse if (resolved !== block.name) renamedCallNames.set(block.id, resolved);\n\t\t}\n\t}\n\n\tlet changed = false;\n\tconst availableToolNames = [...available];\n\tconst seenDemotedCallNames = new Set<string>();\n\tconst rewrittenMessages: MessageParam[] = [];\n\tfor (const message of messages) {\n\t\tif (!Array.isArray(message.content)) {\n\t\t\trewrittenMessages.push(message);\n\t\t\tcontinue;\n\t\t}\n\t\tlet messageChanged = false;\n\t\t// A native search pair whose every reference stopped resolving is demoted\n\t\t// as a unit: the result decides, and its `server_tool_use` follows.\n\t\tconst droppedSearchUseIds = new Set<string>();\n\t\tconst droppedSearchNames = new Map<string, string[]>();\n\t\tif (message.role === \"assistant\") {\n\t\t\tfor (const block of message.content) {\n\t\t\t\tif (!isNativeToolSearchResultBlock(block)) continue;\n\t\t\t\tconst names = block.content.tool_references\n\t\t\t\t\t.filter((item): item is Record<string, unknown> => isRecord(item) && item.type === \"tool_reference\")\n\t\t\t\t\t.map((item) => (typeof item.tool_name === \"string\" ? item.tool_name : \"\"));\n\t\t\t\tif (names.length > 0 && names.every((name) => resolve(name) === undefined)) {\n\t\t\t\t\tdroppedSearchUseIds.add(block.tool_use_id);\n\t\t\t\t\tdroppedSearchNames.set(block.tool_use_id, names);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tconst content: ContentBlockParam[] = [];\n\t\tfor (const block of message.content) {\n\t\t\tif (message.role === \"assistant\" && isRecord(block) && block.type === \"tool_use\") {\n\t\t\t\tconst demotedName = demotedCallNames.get(block.id);\n\t\t\t\tif (demotedName !== undefined) {\n\t\t\t\t\tmessageChanged = true;\n\t\t\t\t\tconst firstOccurrence = !seenDemotedCallNames.has(demotedName);\n\t\t\t\t\tseenDemotedCallNames.add(demotedName);\n\t\t\t\t\tcontent.push({\n\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\ttext: demotedToolCallText(demotedName, availableToolNames, firstOccurrence),\n\t\t\t\t\t});\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst renamedName = renamedCallNames.get(block.id);\n\t\t\t\tif (renamedName !== undefined) {\n\t\t\t\t\tmessageChanged = true;\n\t\t\t\t\tcontent.push({ ...block, name: renamedName } as ContentBlockParam);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (message.role === \"assistant\" && isRecord(block) && block.type === \"server_tool_use\") {\n\t\t\t\tif (typeof block.id === \"string\" && droppedSearchUseIds.has(block.id)) {\n\t\t\t\t\tmessageChanged = true;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (message.role === \"assistant\" && isNativeToolSearchResultBlock(block)) {\n\t\t\t\tconst omitted = droppedSearchNames.get(block.tool_use_id);\n\t\t\t\tif (omitted !== undefined) {\n\t\t\t\t\tmessageChanged = true;\n\t\t\t\t\tcontent.push({ type: \"text\", text: `Tool reference unavailable: ${[...new Set(omitted)].join(\", \")}` });\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst rewritten = rewriteToolReferenceItems(block.content.tool_references, resolve);\n\t\t\t\tif (rewritten !== undefined) {\n\t\t\t\t\tmessageChanged = true;\n\t\t\t\t\tcontent.push({\n\t\t\t\t\t\t...block,\n\t\t\t\t\t\tcontent: { ...block.content, tool_references: rewritten.kept },\n\t\t\t\t\t} as ContentBlockParam);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (isRecord(block) && block.type === \"tool_result\") {\n\t\t\t\tconst demotedName = demotedCallNames.get(block.tool_use_id);\n\t\t\t\tif (demotedName !== undefined) {\n\t\t\t\t\tmessageChanged = true;\n\t\t\t\t\tcontent.push({ type: \"text\", text: demotedToolResultText(demotedName, toolResultText(block.content)) });\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (Array.isArray(block.content)) {\n\t\t\t\t\tconst rewritten = rewriteToolReferenceItems(block.content, resolve);\n\t\t\t\t\tif (rewritten !== undefined) {\n\t\t\t\t\t\tmessageChanged = true;\n\t\t\t\t\t\tconst nextContent =\n\t\t\t\t\t\t\trewritten.kept.length > 0\n\t\t\t\t\t\t\t\t? rewritten.kept\n\t\t\t\t\t\t\t\t: [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\t\t\t\t\ttext: `Tool reference unavailable: ${[...new Set(rewritten.omitted)].join(\", \")}`,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t];\n\t\t\t\t\t\tcontent.push({ ...block, content: nextContent } as ContentBlockParam);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontent.push(block);\n\t\t}\n\t\tif (content.length === 0) {\n\t\t\tchanged = true;\n\t\t\tcontinue;\n\t\t}\n\t\tif (messageChanged) {\n\t\t\tchanged = true;\n\t\t\trewrittenMessages.push({ ...message, content });\n\t\t\tcontinue;\n\t\t}\n\t\trewrittenMessages.push(message);\n\t}\n\n\tif (!changed) return params;\n\treturn { ...params, messages: rewrittenMessages };\n}\n\n/**\n * Folds every `tool_reference` item in `items` onto the request's own tool\n * name and drops the ones that still do not resolve. Returns undefined when\n * nothing changed so callers can keep the original block identity.\n */\nfunction rewriteToolReferenceItems(\n\titems: readonly unknown[],\n\tresolve: (name: string) => string | undefined,\n): { kept: unknown[]; omitted: string[] } | undefined {\n\tconst kept: unknown[] = [];\n\tconst omitted: string[] = [];\n\tlet rewritten = false;\n\tfor (const item of items) {\n\t\tif (!isRecord(item) || item.type !== \"tool_reference\" || typeof item.tool_name !== \"string\") {\n\t\t\tkept.push(item);\n\t\t\tcontinue;\n\t\t}\n\t\tconst resolved = resolve(item.tool_name);\n\t\tif (resolved === undefined) {\n\t\t\tomitted.push(item.tool_name);\n\t\t\trewritten = true;\n\t\t\tcontinue;\n\t\t}\n\t\tif (resolved !== item.tool_name) {\n\t\t\tkept.push({ ...item, tool_name: resolved });\n\t\t\trewritten = true;\n\t\t\tcontinue;\n\t\t}\n\t\tkept.push(item);\n\t}\n\treturn rewritten ? { kept, omitted } : undefined;\n}\n\nfunction toolResultText(content: unknown): string {\n\tif (typeof content === \"string\") return content;\n\tif (Array.isArray(content)) {\n\t\tconst parts: string[] = [];\n\t\tfor (const item of content) {\n\t\t\tif (!isRecord(item)) continue;\n\t\t\tif (item.type === \"text\" && typeof item.text === \"string\") parts.push(item.text);\n\t\t\telse if (typeof item.type === \"string\") parts.push(`[${item.type}]`);\n\t\t}\n\t\tif (parts.length > 0) return parts.join(\"\\n\");\n\t}\n\treturn \"Tool output unavailable.\";\n}\n"]}
|
|
@@ -715,6 +715,19 @@ function convertToolResultContent(content) {
|
|
|
715
715
|
result.push({ text: EMPTY_TEXT_PLACEHOLDER });
|
|
716
716
|
return result;
|
|
717
717
|
}
|
|
718
|
+
// Bedrock Converse requires the conversation to alternate between user and assistant roles and answers
|
|
719
|
+
// "A conversation must alternate between user and assistant roles" otherwise. Adjacent senpi messages can share a
|
|
720
|
+
// role (the hidden environment-context user message right before the prompt, a user prompt after tool results, a
|
|
721
|
+
// user message around a skipped empty assistant), so a message whose role matches the previous wire message is
|
|
722
|
+
// folded into it with its blocks kept in order.
|
|
723
|
+
function appendMessage(result, message) {
|
|
724
|
+
const previous = result[result.length - 1];
|
|
725
|
+
if (previous?.role === message.role && previous.content && message.content) {
|
|
726
|
+
previous.content.push(...message.content);
|
|
727
|
+
return;
|
|
728
|
+
}
|
|
729
|
+
result.push(message);
|
|
730
|
+
}
|
|
718
731
|
function convertMessages(context, model, cacheRetention, options = {}) {
|
|
719
732
|
const result = [];
|
|
720
733
|
const transformedMessages = transformMessages(context.messages, model, normalizeToolCallId, {
|
|
@@ -747,7 +760,7 @@ function convertMessages(context, model, cacheRetention, options = {}) {
|
|
|
747
760
|
if (content.length === 0)
|
|
748
761
|
content.push({ text: EMPTY_TEXT_PLACEHOLDER });
|
|
749
762
|
}
|
|
750
|
-
result
|
|
763
|
+
appendMessage(result, {
|
|
751
764
|
role: ConversationRole.USER,
|
|
752
765
|
content,
|
|
753
766
|
});
|
|
@@ -827,7 +840,7 @@ function convertMessages(context, model, cacheRetention, options = {}) {
|
|
|
827
840
|
if (contentBlocks.length === 0) {
|
|
828
841
|
continue;
|
|
829
842
|
}
|
|
830
|
-
result
|
|
843
|
+
appendMessage(result, {
|
|
831
844
|
role: ConversationRole.ASSISTANT,
|
|
832
845
|
content: contentBlocks,
|
|
833
846
|
});
|
|
@@ -860,7 +873,7 @@ function convertMessages(context, model, cacheRetention, options = {}) {
|
|
|
860
873
|
}
|
|
861
874
|
// Skip the messages we've already processed
|
|
862
875
|
i = j - 1;
|
|
863
|
-
result
|
|
876
|
+
appendMessage(result, {
|
|
864
877
|
role: ConversationRole.USER,
|
|
865
878
|
content: toolResults,
|
|
866
879
|
});
|