@code-yeongyu/senpi 2026.7.13 → 2026.7.14-2
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/CHANGELOG.md +31 -0
- package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.js +14 -5
- package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/runtime-session.d.ts +1 -1
- package/dist/core/extensions/builtin/terminal/runtime-session.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/runtime-session.js +3 -2
- package/dist/core/extensions/builtin/terminal/runtime-session.js.map +1 -1
- package/dist/core/extensions/builtin/websearch/websearch/native.d.ts +1 -1
- package/dist/core/extensions/builtin/websearch/websearch/native.d.ts.map +1 -1
- package/dist/core/extensions/builtin/websearch/websearch/native.js +83 -33
- package/dist/core/extensions/builtin/websearch/websearch/native.js.map +1 -1
- package/dist/core/extensions/builtin/websearch/websearch/provider-endpoints.d.ts.map +1 -1
- package/dist/core/extensions/builtin/websearch/websearch/provider-endpoints.js +2 -1
- package/dist/core/extensions/builtin/websearch/websearch/provider-endpoints.js.map +1 -1
- package/dist/core/extensions/builtin/websearch/websearch/tool.d.ts.map +1 -1
- package/dist/core/extensions/builtin/websearch/websearch/tool.js +3 -3
- package/dist/core/extensions/builtin/websearch/websearch/tool.js.map +1 -1
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +1 -0
- package/dist/core/model-registry.js.map +1 -1
- package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +18 -0
- package/node_modules/@code-yeongyu/senpi-codemode/package.json +3 -3
- package/node_modules/@code-yeongyu/senpi-codemode/src/prompt/eval-prompt.ts +16 -23
- package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js +2 -23
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts +175 -158
- package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.models.d.ts +60 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.models.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.models.js +54 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.models.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/cerebras.models.js +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/cerebras.models.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-ai-gateway.models.d.ts +92 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-ai-gateway.models.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-ai-gateway.models.js +72 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-ai-gateway.models.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.d.ts +23 -22
- package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.js +54 -54
- package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/vercel-ai-gateway.models.d.ts +0 -136
- package/node_modules/@earendil-works/pi-ai/dist/providers/vercel-ai-gateway.models.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/vercel-ai-gateway.models.js +0 -136
- package/node_modules/@earendil-works/pi-ai/dist/providers/vercel-ai-gateway.models.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/context-transformer.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/context-transformer.js +9 -0
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/context-transformer.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/index.d.ts +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/index.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/index.js +6 -2
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/index.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/coerce-parameters.d.ts +8 -0
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/coerce-parameters.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/coerce-parameters.js +92 -0
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/coerce-parameters.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/format.d.ts +6 -0
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/format.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/format.js +54 -0
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/format.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/index.d.ts +4 -0
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/index.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/index.js +4 -0
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/index.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/invoke-match.d.ts +7 -0
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/invoke-match.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/invoke-match.js +16 -0
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/invoke-match.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/invoke-tag-scanner.d.ts +19 -0
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/invoke-tag-scanner.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/invoke-tag-scanner.js +217 -0
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/invoke-tag-scanner.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/parse.d.ts +4 -0
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/parse.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/parse.js +46 -0
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/parse.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/stream-boundary.d.ts +13 -0
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/stream-boundary.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/stream-boundary.js +144 -0
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/stream-boundary.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/stream.d.ts +5 -0
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/stream.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/stream.js +208 -0
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/stream.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/tool-resolver.d.ts +4 -0
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/tool-resolver.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/tool-resolver.js +17 -0
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/tool-resolver.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/xml-entities.d.ts +5 -0
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/xml-entities.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/xml-entities.js +34 -0
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/xml-entities.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/types.d.ts +3 -1
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/types.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/types.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/package.json +1 -1
- package/node_modules/@earendil-works/pi-pty/native/prebuilds/darwin-arm64/senpi_pty.darwin-arm64.node +0 -0
- package/node_modules/@earendil-works/pi-pty/package.json +1 -1
- package/node_modules/@earendil-works/pi-tui/package.json +1 -1
- package/package.json +6 -6
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import { decodeXmlEntities } from "./xml-entities.js";
|
|
2
|
+
const PROTOCOL_TAG_NAMES = ["invoke", "parameter", "function_calls"];
|
|
3
|
+
const INVOKE_OPEN_TAG_BODY = String.raw `<\s*invoke\b\s+name\s*=\s*(?:"([^"]+)"|'([^']+)')`;
|
|
4
|
+
const INVOKE_OPEN_TAG = new RegExp(`${INVOKE_OPEN_TAG_BODY}\\s*>`, "g");
|
|
5
|
+
const INVOKE_CLOSE_TAG = /<\s*\/\s*invoke\s*>/g;
|
|
6
|
+
const NESTED_INVOKE_OPEN_TAG = /<\s*invoke\b[^>]*>/g;
|
|
7
|
+
const PARAMETER_MARKUP = /<\s*\/?\s*parameter\b/g;
|
|
8
|
+
const PARAMETER_OPEN_TAG = /<\s*parameter\b\s+name\s*=\s*(?:"([^"]+)"|'([^']+)')\s*>/g;
|
|
9
|
+
const PARAMETER_CLOSE_TAG = /<\s*\/\s*parameter\s*>/g;
|
|
10
|
+
function findTag(pattern, text, fromIndex) {
|
|
11
|
+
pattern.lastIndex = Math.max(0, fromIndex);
|
|
12
|
+
const match = pattern.exec(text);
|
|
13
|
+
return match ? { index: match.index, length: match[0].length } : null;
|
|
14
|
+
}
|
|
15
|
+
function findParameterOpenTagAt(text, index) {
|
|
16
|
+
PARAMETER_OPEN_TAG.lastIndex = index;
|
|
17
|
+
const match = PARAMETER_OPEN_TAG.exec(text);
|
|
18
|
+
if (!match || match.index !== index) {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
const name = match[1] ?? match[2];
|
|
22
|
+
return name ? { index, length: match[0].length, name: decodeXmlEntities(name) } : null;
|
|
23
|
+
}
|
|
24
|
+
function findParameterBoundary(text, fromIndex) {
|
|
25
|
+
let cursor = fromIndex;
|
|
26
|
+
let nestedInvokeDepth = 0;
|
|
27
|
+
while (cursor < text.length) {
|
|
28
|
+
const parameterClose = findTag(PARAMETER_CLOSE_TAG, text, cursor);
|
|
29
|
+
const invokeOpen = findTag(NESTED_INVOKE_OPEN_TAG, text, cursor);
|
|
30
|
+
const invokeClose = findTag(INVOKE_CLOSE_TAG, text, cursor);
|
|
31
|
+
const nextIndex = Math.min(parameterClose?.index ?? Number.POSITIVE_INFINITY, invokeOpen?.index ?? Number.POSITIVE_INFINITY, invokeClose?.index ?? Number.POSITIVE_INFINITY);
|
|
32
|
+
if (!Number.isFinite(nextIndex)) {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
if (invokeOpen && invokeOpen.index === nextIndex) {
|
|
36
|
+
const nextParameterClose = findTag(PARAMETER_CLOSE_TAG, text, invokeOpen.index + invokeOpen.length);
|
|
37
|
+
const nestedParameterOpen = findTag(PARAMETER_OPEN_TAG, text, invokeOpen.index + invokeOpen.length);
|
|
38
|
+
const nestedInvokeClose = findTag(INVOKE_CLOSE_TAG, text, invokeOpen.index + invokeOpen.length);
|
|
39
|
+
if (nestedInvokeClose === null ||
|
|
40
|
+
((nestedParameterOpen === null || nestedParameterOpen.index > nestedInvokeClose.index) &&
|
|
41
|
+
nextParameterClose !== null &&
|
|
42
|
+
nestedInvokeClose.index > nextParameterClose.index)) {
|
|
43
|
+
cursor = invokeOpen.index + invokeOpen.length;
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
nestedInvokeDepth += 1;
|
|
47
|
+
cursor = invokeOpen.index + invokeOpen.length;
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
if (invokeClose && invokeClose.index === nextIndex) {
|
|
51
|
+
if (nestedInvokeDepth === 0) {
|
|
52
|
+
return { kind: "invoke-close", match: invokeClose };
|
|
53
|
+
}
|
|
54
|
+
nestedInvokeDepth -= 1;
|
|
55
|
+
cursor = invokeClose.index + invokeClose.length;
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
if (parameterClose) {
|
|
59
|
+
if (nestedInvokeDepth === 0) {
|
|
60
|
+
return { kind: "parameter-close", match: parameterClose };
|
|
61
|
+
}
|
|
62
|
+
cursor = parameterClose.index + parameterClose.length;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
export function findInvokeOpenTag(text, fromIndex) {
|
|
68
|
+
INVOKE_OPEN_TAG.lastIndex = Math.max(0, fromIndex);
|
|
69
|
+
const match = INVOKE_OPEN_TAG.exec(text);
|
|
70
|
+
if (!match || match.index === undefined) {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
const toolName = match[1] ?? match[2];
|
|
74
|
+
return toolName ? { index: match.index, length: match[0].length, toolName: decodeXmlEntities(toolName) } : null;
|
|
75
|
+
}
|
|
76
|
+
export function findIncompleteInvokeOpenTag(text, fromIndex) {
|
|
77
|
+
const index = Math.max(0, fromIndex);
|
|
78
|
+
const candidate = text.slice(index);
|
|
79
|
+
const match = /^<\s*invoke\b\s+name\s*=\s*/.exec(candidate);
|
|
80
|
+
if (!match) {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
const quoteIndex = match[0].length;
|
|
84
|
+
const quote = candidate[quoteIndex];
|
|
85
|
+
if (quote !== '"' && quote !== "'") {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
const toolNameStart = quoteIndex + 1;
|
|
89
|
+
const closingQuoteIndex = candidate.indexOf(quote, toolNameStart);
|
|
90
|
+
if (closingQuoteIndex === -1) {
|
|
91
|
+
const toolName = decodeXmlEntities(candidate.slice(toolNameStart));
|
|
92
|
+
return toolName.length > 0 ? { index, length: candidate.length, toolName } : null;
|
|
93
|
+
}
|
|
94
|
+
const toolName = decodeXmlEntities(candidate.slice(toolNameStart, closingQuoteIndex));
|
|
95
|
+
if (toolName.length === 0 || candidate.slice(closingQuoteIndex + 1).trim().length > 0) {
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
return { index, length: candidate.length, toolName };
|
|
99
|
+
}
|
|
100
|
+
export function scanInvokeBlock(text, openingTag) {
|
|
101
|
+
const parameters = [];
|
|
102
|
+
let cursor = Math.max(0, openingTag.index + openingTag.length);
|
|
103
|
+
while (cursor <= text.length) {
|
|
104
|
+
const invokeClose = findTag(INVOKE_CLOSE_TAG, text, cursor);
|
|
105
|
+
if (!invokeClose) {
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
const parameterMarkup = findTag(PARAMETER_MARKUP, text, cursor);
|
|
109
|
+
const nestedInvokeOpen = findTag(NESTED_INVOKE_OPEN_TAG, text, cursor);
|
|
110
|
+
if (nestedInvokeOpen &&
|
|
111
|
+
nestedInvokeOpen.index < invokeClose.index &&
|
|
112
|
+
(!parameterMarkup || nestedInvokeOpen.index < parameterMarkup.index)) {
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
if (!parameterMarkup || invokeClose.index < parameterMarkup.index) {
|
|
116
|
+
return {
|
|
117
|
+
contentEnd: invokeClose.index,
|
|
118
|
+
end: invokeClose.index + invokeClose.length,
|
|
119
|
+
parameters,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
const parameterOpen = findParameterOpenTagAt(text, parameterMarkup.index);
|
|
123
|
+
if (!parameterOpen) {
|
|
124
|
+
return {
|
|
125
|
+
contentEnd: invokeClose.index,
|
|
126
|
+
end: invokeClose.index + invokeClose.length,
|
|
127
|
+
parameters: null,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
const valueStart = parameterOpen.index + parameterOpen.length;
|
|
131
|
+
const boundary = findParameterBoundary(text, valueStart);
|
|
132
|
+
if (!boundary) {
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
switch (boundary.kind) {
|
|
136
|
+
case "invoke-close":
|
|
137
|
+
return {
|
|
138
|
+
contentEnd: boundary.match.index,
|
|
139
|
+
end: boundary.match.index + boundary.match.length,
|
|
140
|
+
parameters: null,
|
|
141
|
+
};
|
|
142
|
+
case "parameter-close":
|
|
143
|
+
parameters.push({
|
|
144
|
+
name: parameterOpen.name,
|
|
145
|
+
rawValue: text.slice(valueStart, boundary.match.index),
|
|
146
|
+
});
|
|
147
|
+
cursor = boundary.match.index + boundary.match.length;
|
|
148
|
+
break;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
function isAttributePrefix(remainder) {
|
|
154
|
+
const attributeMatch = /^(\s*)([A-Za-z]*)/.exec(remainder);
|
|
155
|
+
if (!attributeMatch) {
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
const attributeName = attributeMatch[2] ?? "";
|
|
159
|
+
const afterAttributeName = remainder.slice(attributeMatch[0].length);
|
|
160
|
+
if (attributeName.length < "name".length) {
|
|
161
|
+
return "name".startsWith(attributeName) && afterAttributeName.trim().length === 0;
|
|
162
|
+
}
|
|
163
|
+
if (attributeName !== "name") {
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
if (afterAttributeName.trim().length === 0) {
|
|
167
|
+
return true;
|
|
168
|
+
}
|
|
169
|
+
const equalsMatch = /^\s*=\s*(.*)$/.exec(afterAttributeName);
|
|
170
|
+
if (!equalsMatch) {
|
|
171
|
+
return false;
|
|
172
|
+
}
|
|
173
|
+
const valuePrefix = equalsMatch[1] ?? "";
|
|
174
|
+
if (valuePrefix.length === 0) {
|
|
175
|
+
return true;
|
|
176
|
+
}
|
|
177
|
+
const quote = valuePrefix[0];
|
|
178
|
+
if (quote !== '"' && quote !== "'") {
|
|
179
|
+
return false;
|
|
180
|
+
}
|
|
181
|
+
const closingQuoteIndex = valuePrefix.indexOf(quote, 1);
|
|
182
|
+
return closingQuoteIndex === -1 || valuePrefix.slice(closingQuoteIndex + 1).trim().length === 0;
|
|
183
|
+
}
|
|
184
|
+
function isPotentialProtocolStart(candidate) {
|
|
185
|
+
if (!candidate.startsWith("<")) {
|
|
186
|
+
return false;
|
|
187
|
+
}
|
|
188
|
+
const body = candidate.slice(1);
|
|
189
|
+
const leadingWhitespace = /^\s*/.exec(body)?.[0] ?? "";
|
|
190
|
+
const namePart = body.slice(leadingWhitespace.length);
|
|
191
|
+
if (namePart.length === 0) {
|
|
192
|
+
return true;
|
|
193
|
+
}
|
|
194
|
+
const tagName = PROTOCOL_TAG_NAMES.find((name) => name.startsWith(namePart) || namePart.startsWith(name));
|
|
195
|
+
if (!tagName) {
|
|
196
|
+
return false;
|
|
197
|
+
}
|
|
198
|
+
if (namePart.length < tagName.length) {
|
|
199
|
+
return true;
|
|
200
|
+
}
|
|
201
|
+
const remainder = namePart.slice(tagName.length);
|
|
202
|
+
if (remainder.includes(">")) {
|
|
203
|
+
return false;
|
|
204
|
+
}
|
|
205
|
+
if (tagName === "function_calls") {
|
|
206
|
+
return /^\s*$/.test(remainder);
|
|
207
|
+
}
|
|
208
|
+
return isAttributePrefix(remainder);
|
|
209
|
+
}
|
|
210
|
+
export function getSafeInvokeTextLength(text) {
|
|
211
|
+
const lastTagIndex = text.lastIndexOf("<");
|
|
212
|
+
if (lastTagIndex === -1) {
|
|
213
|
+
return text.length;
|
|
214
|
+
}
|
|
215
|
+
return isPotentialProtocolStart(text.slice(lastTagIndex)) ? lastTagIndex : text.length;
|
|
216
|
+
}
|
|
217
|
+
//# sourceMappingURL=invoke-tag-scanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invoke-tag-scanner.js","sourceRoot":"","sources":["../../../../src/tool-call-middleware/protocols/anthropic-xml/invoke-tag-scanner.ts"],"names":[],"mappings":"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","sourcesContent":["import { decodeXmlEntities } from \"./xml-entities.ts\";\n\nconst PROTOCOL_TAG_NAMES = [\"invoke\", \"parameter\", \"function_calls\"] as const;\n\nconst INVOKE_OPEN_TAG_BODY = String.raw`<\\s*invoke\\b\\s+name\\s*=\\s*(?:\"([^\"]+)\"|'([^']+)')`;\nconst INVOKE_OPEN_TAG = new RegExp(`${INVOKE_OPEN_TAG_BODY}\\\\s*>`, \"g\");\nconst INVOKE_CLOSE_TAG = /<\\s*\\/\\s*invoke\\s*>/g;\nconst NESTED_INVOKE_OPEN_TAG = /<\\s*invoke\\b[^>]*>/g;\nconst PARAMETER_MARKUP = /<\\s*\\/?\\s*parameter\\b/g;\nconst PARAMETER_OPEN_TAG = /<\\s*parameter\\b\\s+name\\s*=\\s*(?:\"([^\"]+)\"|'([^']+)')\\s*>/g;\nconst PARAMETER_CLOSE_TAG = /<\\s*\\/\\s*parameter\\s*>/g;\n\ntype TagMatch = {\n\treadonly index: number;\n\treadonly length: number;\n};\n\ntype ParameterOpenTagMatch = TagMatch & {\n\treadonly name: string;\n};\n\ntype ParameterBoundary =\n\t| { readonly kind: \"parameter-close\"; readonly match: TagMatch }\n\t| { readonly kind: \"invoke-close\"; readonly match: TagMatch };\n\nexport type InvokeOpenTagMatch = {\n\treadonly index: number;\n\treadonly length: number;\n\treadonly toolName: string;\n};\n\nexport type InvokeParameter = {\n\treadonly name: string;\n\treadonly rawValue: string;\n};\n\nexport type InvokeBlockMatch = {\n\treadonly contentEnd: number;\n\treadonly end: number;\n\treadonly parameters: InvokeParameter[] | null;\n};\n\nfunction findTag(pattern: RegExp, text: string, fromIndex: number): TagMatch | null {\n\tpattern.lastIndex = Math.max(0, fromIndex);\n\tconst match = pattern.exec(text);\n\treturn match ? { index: match.index, length: match[0].length } : null;\n}\n\nfunction findParameterOpenTagAt(text: string, index: number): ParameterOpenTagMatch | null {\n\tPARAMETER_OPEN_TAG.lastIndex = index;\n\tconst match = PARAMETER_OPEN_TAG.exec(text);\n\tif (!match || match.index !== index) {\n\t\treturn null;\n\t}\n\n\tconst name = match[1] ?? match[2];\n\treturn name ? { index, length: match[0].length, name: decodeXmlEntities(name) } : null;\n}\n\nfunction findParameterBoundary(text: string, fromIndex: number): ParameterBoundary | null {\n\tlet cursor = fromIndex;\n\tlet nestedInvokeDepth = 0;\n\n\twhile (cursor < text.length) {\n\t\tconst parameterClose = findTag(PARAMETER_CLOSE_TAG, text, cursor);\n\t\tconst invokeOpen = findTag(NESTED_INVOKE_OPEN_TAG, text, cursor);\n\t\tconst invokeClose = findTag(INVOKE_CLOSE_TAG, text, cursor);\n\t\tconst nextIndex = Math.min(\n\t\t\tparameterClose?.index ?? Number.POSITIVE_INFINITY,\n\t\t\tinvokeOpen?.index ?? Number.POSITIVE_INFINITY,\n\t\t\tinvokeClose?.index ?? Number.POSITIVE_INFINITY,\n\t\t);\n\n\t\tif (!Number.isFinite(nextIndex)) {\n\t\t\treturn null;\n\t\t}\n\t\tif (invokeOpen && invokeOpen.index === nextIndex) {\n\t\t\tconst nextParameterClose = findTag(PARAMETER_CLOSE_TAG, text, invokeOpen.index + invokeOpen.length);\n\t\t\tconst nestedParameterOpen = findTag(PARAMETER_OPEN_TAG, text, invokeOpen.index + invokeOpen.length);\n\t\t\tconst nestedInvokeClose = findTag(INVOKE_CLOSE_TAG, text, invokeOpen.index + invokeOpen.length);\n\t\t\tif (\n\t\t\t\tnestedInvokeClose === null ||\n\t\t\t\t((nestedParameterOpen === null || nestedParameterOpen.index > nestedInvokeClose.index) &&\n\t\t\t\t\tnextParameterClose !== null &&\n\t\t\t\t\tnestedInvokeClose.index > nextParameterClose.index)\n\t\t\t) {\n\t\t\t\tcursor = invokeOpen.index + invokeOpen.length;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tnestedInvokeDepth += 1;\n\t\t\tcursor = invokeOpen.index + invokeOpen.length;\n\t\t\tcontinue;\n\t\t}\n\t\tif (invokeClose && invokeClose.index === nextIndex) {\n\t\t\tif (nestedInvokeDepth === 0) {\n\t\t\t\treturn { kind: \"invoke-close\", match: invokeClose };\n\t\t\t}\n\t\t\tnestedInvokeDepth -= 1;\n\t\t\tcursor = invokeClose.index + invokeClose.length;\n\t\t\tcontinue;\n\t\t}\n\t\tif (parameterClose) {\n\t\t\tif (nestedInvokeDepth === 0) {\n\t\t\t\treturn { kind: \"parameter-close\", match: parameterClose };\n\t\t\t}\n\t\t\tcursor = parameterClose.index + parameterClose.length;\n\t\t}\n\t}\n\n\treturn null;\n}\n\nexport function findInvokeOpenTag(text: string, fromIndex: number): InvokeOpenTagMatch | null {\n\tINVOKE_OPEN_TAG.lastIndex = Math.max(0, fromIndex);\n\tconst match = INVOKE_OPEN_TAG.exec(text);\n\tif (!match || match.index === undefined) {\n\t\treturn null;\n\t}\n\n\tconst toolName = match[1] ?? match[2];\n\treturn toolName ? { index: match.index, length: match[0].length, toolName: decodeXmlEntities(toolName) } : null;\n}\n\nexport function findIncompleteInvokeOpenTag(text: string, fromIndex: number): InvokeOpenTagMatch | null {\n\tconst index = Math.max(0, fromIndex);\n\tconst candidate = text.slice(index);\n\tconst match = /^<\\s*invoke\\b\\s+name\\s*=\\s*/.exec(candidate);\n\tif (!match) {\n\t\treturn null;\n\t}\n\n\tconst quoteIndex = match[0].length;\n\tconst quote = candidate[quoteIndex];\n\tif (quote !== '\"' && quote !== \"'\") {\n\t\treturn null;\n\t}\n\n\tconst toolNameStart = quoteIndex + 1;\n\tconst closingQuoteIndex = candidate.indexOf(quote, toolNameStart);\n\tif (closingQuoteIndex === -1) {\n\t\tconst toolName = decodeXmlEntities(candidate.slice(toolNameStart));\n\t\treturn toolName.length > 0 ? { index, length: candidate.length, toolName } : null;\n\t}\n\n\tconst toolName = decodeXmlEntities(candidate.slice(toolNameStart, closingQuoteIndex));\n\tif (toolName.length === 0 || candidate.slice(closingQuoteIndex + 1).trim().length > 0) {\n\t\treturn null;\n\t}\n\n\treturn { index, length: candidate.length, toolName };\n}\n\nexport function scanInvokeBlock(text: string, openingTag: InvokeOpenTagMatch): InvokeBlockMatch | null {\n\tconst parameters: InvokeParameter[] = [];\n\tlet cursor = Math.max(0, openingTag.index + openingTag.length);\n\n\twhile (cursor <= text.length) {\n\t\tconst invokeClose = findTag(INVOKE_CLOSE_TAG, text, cursor);\n\t\tif (!invokeClose) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst parameterMarkup = findTag(PARAMETER_MARKUP, text, cursor);\n\t\tconst nestedInvokeOpen = findTag(NESTED_INVOKE_OPEN_TAG, text, cursor);\n\t\tif (\n\t\t\tnestedInvokeOpen &&\n\t\t\tnestedInvokeOpen.index < invokeClose.index &&\n\t\t\t(!parameterMarkup || nestedInvokeOpen.index < parameterMarkup.index)\n\t\t) {\n\t\t\treturn null;\n\t\t}\n\t\tif (!parameterMarkup || invokeClose.index < parameterMarkup.index) {\n\t\t\treturn {\n\t\t\t\tcontentEnd: invokeClose.index,\n\t\t\t\tend: invokeClose.index + invokeClose.length,\n\t\t\t\tparameters,\n\t\t\t};\n\t\t}\n\n\t\tconst parameterOpen = findParameterOpenTagAt(text, parameterMarkup.index);\n\t\tif (!parameterOpen) {\n\t\t\treturn {\n\t\t\t\tcontentEnd: invokeClose.index,\n\t\t\t\tend: invokeClose.index + invokeClose.length,\n\t\t\t\tparameters: null,\n\t\t\t};\n\t\t}\n\n\t\tconst valueStart = parameterOpen.index + parameterOpen.length;\n\t\tconst boundary = findParameterBoundary(text, valueStart);\n\t\tif (!boundary) {\n\t\t\treturn null;\n\t\t}\n\n\t\tswitch (boundary.kind) {\n\t\t\tcase \"invoke-close\":\n\t\t\t\treturn {\n\t\t\t\t\tcontentEnd: boundary.match.index,\n\t\t\t\t\tend: boundary.match.index + boundary.match.length,\n\t\t\t\t\tparameters: null,\n\t\t\t\t};\n\t\t\tcase \"parameter-close\":\n\t\t\t\tparameters.push({\n\t\t\t\t\tname: parameterOpen.name,\n\t\t\t\t\trawValue: text.slice(valueStart, boundary.match.index),\n\t\t\t\t});\n\t\t\t\tcursor = boundary.match.index + boundary.match.length;\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn null;\n}\n\nfunction isAttributePrefix(remainder: string): boolean {\n\tconst attributeMatch = /^(\\s*)([A-Za-z]*)/.exec(remainder);\n\tif (!attributeMatch) {\n\t\treturn false;\n\t}\n\n\tconst attributeName = attributeMatch[2] ?? \"\";\n\tconst afterAttributeName = remainder.slice(attributeMatch[0].length);\n\tif (attributeName.length < \"name\".length) {\n\t\treturn \"name\".startsWith(attributeName) && afterAttributeName.trim().length === 0;\n\t}\n\tif (attributeName !== \"name\") {\n\t\treturn false;\n\t}\n\tif (afterAttributeName.trim().length === 0) {\n\t\treturn true;\n\t}\n\n\tconst equalsMatch = /^\\s*=\\s*(.*)$/.exec(afterAttributeName);\n\tif (!equalsMatch) {\n\t\treturn false;\n\t}\n\n\tconst valuePrefix = equalsMatch[1] ?? \"\";\n\tif (valuePrefix.length === 0) {\n\t\treturn true;\n\t}\n\n\tconst quote = valuePrefix[0];\n\tif (quote !== '\"' && quote !== \"'\") {\n\t\treturn false;\n\t}\n\n\tconst closingQuoteIndex = valuePrefix.indexOf(quote, 1);\n\treturn closingQuoteIndex === -1 || valuePrefix.slice(closingQuoteIndex + 1).trim().length === 0;\n}\n\nfunction isPotentialProtocolStart(candidate: string): boolean {\n\tif (!candidate.startsWith(\"<\")) {\n\t\treturn false;\n\t}\n\n\tconst body = candidate.slice(1);\n\tconst leadingWhitespace = /^\\s*/.exec(body)?.[0] ?? \"\";\n\tconst namePart = body.slice(leadingWhitespace.length);\n\tif (namePart.length === 0) {\n\t\treturn true;\n\t}\n\n\tconst tagName = PROTOCOL_TAG_NAMES.find((name) => name.startsWith(namePart) || namePart.startsWith(name));\n\tif (!tagName) {\n\t\treturn false;\n\t}\n\tif (namePart.length < tagName.length) {\n\t\treturn true;\n\t}\n\n\tconst remainder = namePart.slice(tagName.length);\n\tif (remainder.includes(\">\")) {\n\t\treturn false;\n\t}\n\tif (tagName === \"function_calls\") {\n\t\treturn /^\\s*$/.test(remainder);\n\t}\n\treturn isAttributePrefix(remainder);\n}\n\nexport function getSafeInvokeTextLength(text: string): number {\n\tconst lastTagIndex = text.lastIndexOf(\"<\");\n\tif (lastTagIndex === -1) {\n\t\treturn text.length;\n\t}\n\n\treturn isPotentialProtocolStart(text.slice(lastTagIndex)) ? lastTagIndex : text.length;\n}\n"]}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Tool } from "../../../types.ts";
|
|
2
|
+
import type { ParsedToolCall, ParserOptions } from "../../types.ts";
|
|
3
|
+
export declare function parseAnthropicXmlGeneratedText(text: string, tools: Tool[], options?: ParserOptions): ParsedToolCall[];
|
|
4
|
+
//# sourceMappingURL=parse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../../../src/tool-call-middleware/protocols/anthropic-xml/parse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAMpE,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,cAAc,EAAE,CAsDrH"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { coerceParameters } from "./coerce-parameters.js";
|
|
2
|
+
import { findNextInvokeMatch } from "./invoke-match.js";
|
|
3
|
+
import { findInvokeOpenTag, scanInvokeBlock } from "./invoke-tag-scanner.js";
|
|
4
|
+
import { createToolResolver } from "./tool-resolver.js";
|
|
5
|
+
export function parseAnthropicXmlGeneratedText(text, tools, options) {
|
|
6
|
+
if (text.length === 0 || tools.length === 0) {
|
|
7
|
+
return [];
|
|
8
|
+
}
|
|
9
|
+
const resolveTool = createToolResolver(tools);
|
|
10
|
+
const parsedToolCalls = [];
|
|
11
|
+
let cursor = 0;
|
|
12
|
+
while (cursor < text.length) {
|
|
13
|
+
const openingTag = findInvokeOpenTag(text, cursor);
|
|
14
|
+
if (!openingTag) {
|
|
15
|
+
break;
|
|
16
|
+
}
|
|
17
|
+
const tool = resolveTool(openingTag.toolName);
|
|
18
|
+
const block = scanInvokeBlock(text, openingTag);
|
|
19
|
+
if (!tool) {
|
|
20
|
+
const nextKnownInvoke = findNextInvokeMatch(text, openingTag.index + openingTag.length, (toolName) => resolveTool(toolName) !== undefined);
|
|
21
|
+
if (nextKnownInvoke &&
|
|
22
|
+
(block === null || (nextKnownInvoke.block !== null && nextKnownInvoke.block.end === block.end))) {
|
|
23
|
+
cursor = nextKnownInvoke.openingTag.index;
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
if (!block) {
|
|
28
|
+
break;
|
|
29
|
+
}
|
|
30
|
+
const originalCallText = text.slice(openingTag.index, block.end);
|
|
31
|
+
cursor = block.end;
|
|
32
|
+
if (!tool) {
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
const argumentsRecord = block.parameters ? coerceParameters(block.parameters, tool) : null;
|
|
36
|
+
if (!argumentsRecord) {
|
|
37
|
+
options?.onError?.("Could not process anthropic-xml tool call, keeping original text.", {
|
|
38
|
+
toolCall: originalCallText,
|
|
39
|
+
});
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
parsedToolCalls.push({ name: tool.name, arguments: argumentsRecord });
|
|
43
|
+
}
|
|
44
|
+
return parsedToolCalls;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=parse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse.js","sourceRoot":"","sources":["../../../../src/tool-call-middleware/protocols/anthropic-xml/parse.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC7E,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAExD,MAAM,UAAU,8BAA8B,CAAC,IAAY,EAAE,KAAa,EAAE,OAAuB;IAClG,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7C,OAAO,EAAE,CAAC;IACX,CAAC;IAED,MAAM,WAAW,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;IAC9C,MAAM,eAAe,GAAqB,EAAE,CAAC;IAC7C,IAAI,MAAM,GAAG,CAAC,CAAC;IAEf,OAAO,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC7B,MAAM,UAAU,GAAG,iBAAiB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACnD,IAAI,CAAC,UAAU,EAAE,CAAC;YACjB,MAAM;QACP,CAAC;QAED,MAAM,IAAI,GAAG,WAAW,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;QAC9C,MAAM,KAAK,GAAG,eAAe,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QAChD,IAAI,CAAC,IAAI,EAAE,CAAC;YACX,MAAM,eAAe,GAAG,mBAAmB,CAC1C,IAAI,EACJ,UAAU,CAAC,KAAK,GAAG,UAAU,CAAC,MAAM,EACpC,CAAC,QAAQ,EAAE,EAAE,CAAC,WAAW,CAAC,QAAQ,CAAC,KAAK,SAAS,CACjD,CAAC;YACF,IACC,eAAe;gBACf,CAAC,KAAK,KAAK,IAAI,IAAI,CAAC,eAAe,CAAC,KAAK,KAAK,IAAI,IAAI,eAAe,CAAC,KAAK,CAAC,GAAG,KAAK,KAAK,CAAC,GAAG,CAAC,CAAC,EAC9F,CAAC;gBACF,MAAM,GAAG,eAAe,CAAC,UAAU,CAAC,KAAK,CAAC;gBAC1C,SAAS;YACV,CAAC;QACF,CAAC;QACD,IAAI,CAAC,KAAK,EAAE,CAAC;YACZ,MAAM;QACP,CAAC;QAED,MAAM,gBAAgB,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;QACjE,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC;QAEnB,IAAI,CAAC,IAAI,EAAE,CAAC;YACX,SAAS;QACV,CAAC;QAED,MAAM,eAAe,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,gBAAgB,CAAC,KAAK,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC3F,IAAI,CAAC,eAAe,EAAE,CAAC;YACtB,OAAO,EAAE,OAAO,EAAE,CAAC,mEAAmE,EAAE;gBACvF,QAAQ,EAAE,gBAAgB;aAC1B,CAAC,CAAC;YACH,SAAS;QACV,CAAC;QAED,eAAe,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,eAAe,EAAE,CAAC,CAAC;IACvE,CAAC;IAED,OAAO,eAAe,CAAC;AACxB,CAAC","sourcesContent":["import type { Tool } from \"../../../types.ts\";\nimport type { ParsedToolCall, ParserOptions } from \"../../types.ts\";\nimport { coerceParameters } from \"./coerce-parameters.ts\";\nimport { findNextInvokeMatch } from \"./invoke-match.ts\";\nimport { findInvokeOpenTag, scanInvokeBlock } from \"./invoke-tag-scanner.ts\";\nimport { createToolResolver } from \"./tool-resolver.ts\";\n\nexport function parseAnthropicXmlGeneratedText(text: string, tools: Tool[], options?: ParserOptions): ParsedToolCall[] {\n\tif (text.length === 0 || tools.length === 0) {\n\t\treturn [];\n\t}\n\n\tconst resolveTool = createToolResolver(tools);\n\tconst parsedToolCalls: ParsedToolCall[] = [];\n\tlet cursor = 0;\n\n\twhile (cursor < text.length) {\n\t\tconst openingTag = findInvokeOpenTag(text, cursor);\n\t\tif (!openingTag) {\n\t\t\tbreak;\n\t\t}\n\n\t\tconst tool = resolveTool(openingTag.toolName);\n\t\tconst block = scanInvokeBlock(text, openingTag);\n\t\tif (!tool) {\n\t\t\tconst nextKnownInvoke = findNextInvokeMatch(\n\t\t\t\ttext,\n\t\t\t\topeningTag.index + openingTag.length,\n\t\t\t\t(toolName) => resolveTool(toolName) !== undefined,\n\t\t\t);\n\t\t\tif (\n\t\t\t\tnextKnownInvoke &&\n\t\t\t\t(block === null || (nextKnownInvoke.block !== null && nextKnownInvoke.block.end === block.end))\n\t\t\t) {\n\t\t\t\tcursor = nextKnownInvoke.openingTag.index;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\tif (!block) {\n\t\t\tbreak;\n\t\t}\n\n\t\tconst originalCallText = text.slice(openingTag.index, block.end);\n\t\tcursor = block.end;\n\n\t\tif (!tool) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst argumentsRecord = block.parameters ? coerceParameters(block.parameters, tool) : null;\n\t\tif (!argumentsRecord) {\n\t\t\toptions?.onError?.(\"Could not process anthropic-xml tool call, keeping original text.\", {\n\t\t\t\ttoolCall: originalCallText,\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\n\t\tparsedToolCalls.push({ name: tool.name, arguments: argumentsRecord });\n\t}\n\n\treturn parsedToolCalls;\n}\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** Incomplete protocol fragments are rejected before retained input can exceed this many UTF-16 code units. */
|
|
2
|
+
export declare const ANTHROPIC_XML_MAX_RETAINED_FRAGMENT_LENGTH: number;
|
|
3
|
+
export type StreamBoundaryMatcher = {
|
|
4
|
+
feed(text: string): boolean;
|
|
5
|
+
};
|
|
6
|
+
export type PendingFragment = {
|
|
7
|
+
readonly kind: "invoke" | "function-calls" | "open-tag";
|
|
8
|
+
readonly matcher: StreamBoundaryMatcher;
|
|
9
|
+
};
|
|
10
|
+
export declare function createClosingTagMatcher(tagName: "invoke" | "function_calls"): StreamBoundaryMatcher;
|
|
11
|
+
export declare function createTagEndMatcher(): StreamBoundaryMatcher;
|
|
12
|
+
export declare function createPendingFragment(kind: PendingFragment["kind"], text: string): PendingFragment;
|
|
13
|
+
//# sourceMappingURL=stream-boundary.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream-boundary.d.ts","sourceRoot":"","sources":["../../../../src/tool-call-middleware/protocols/anthropic-xml/stream-boundary.ts"],"names":[],"mappings":"AAMA,+GAA+G;AAC/G,eAAO,MAAM,0CAA0C,QAAY,CAAC;AAEpE,MAAM,MAAM,qBAAqB,GAAG;IACnC,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC7B,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,gBAAgB,GAAG,UAAU,CAAC;IACxD,QAAQ,CAAC,OAAO,EAAE,qBAAqB,CAAC;CACxC,CAAC;AAsEF,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,QAAQ,GAAG,gBAAgB,GAAG,qBAAqB,CA0DnG;AAED,wBAAgB,mBAAmB,IAAI,qBAAqB,CAM3D;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,eAAe,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,eAAe,CASlG"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
const WHITESPACE = /\s/;
|
|
2
|
+
const INVOKE_OPEN_TAG = /^<\s*invoke\b[^>]*>$/;
|
|
3
|
+
const INVOKE_CLOSE_TAG = /^<\s*\/\s*invoke\s*>$/;
|
|
4
|
+
const PARAMETER_OPEN_TAG = /^<\s*parameter\b[^>]*>$/;
|
|
5
|
+
const PARAMETER_CLOSE_TAG = /^<\s*\/\s*parameter\s*>$/;
|
|
6
|
+
/** Incomplete protocol fragments are rejected before retained input can exceed this many UTF-16 code units. */
|
|
7
|
+
export const ANTHROPIC_XML_MAX_RETAINED_FRAGMENT_LENGTH = 64 * 1024;
|
|
8
|
+
function isWhitespace(character) {
|
|
9
|
+
return WHITESPACE.test(character);
|
|
10
|
+
}
|
|
11
|
+
function createInvokeBoundaryMatcher() {
|
|
12
|
+
let invokeDepth = 0;
|
|
13
|
+
const parameterInvokeDepths = [];
|
|
14
|
+
let tagCharacters = null;
|
|
15
|
+
return {
|
|
16
|
+
feed(text) {
|
|
17
|
+
for (const character of text) {
|
|
18
|
+
if (tagCharacters === null) {
|
|
19
|
+
if (character === "<") {
|
|
20
|
+
tagCharacters = [character];
|
|
21
|
+
}
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
if (character === "<") {
|
|
25
|
+
tagCharacters = [character];
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
tagCharacters.push(character);
|
|
29
|
+
if (character !== ">") {
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
const tag = tagCharacters.join("");
|
|
33
|
+
tagCharacters = null;
|
|
34
|
+
if (INVOKE_OPEN_TAG.test(tag)) {
|
|
35
|
+
invokeDepth += 1;
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
if (PARAMETER_OPEN_TAG.test(tag)) {
|
|
39
|
+
parameterInvokeDepths.push(invokeDepth);
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
if (PARAMETER_CLOSE_TAG.test(tag)) {
|
|
43
|
+
const parameterInvokeDepth = parameterInvokeDepths.pop();
|
|
44
|
+
if (parameterInvokeDepth !== undefined && invokeDepth > parameterInvokeDepth) {
|
|
45
|
+
invokeDepth = parameterInvokeDepth;
|
|
46
|
+
}
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
if (!INVOKE_CLOSE_TAG.test(tag) || invokeDepth === 0) {
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
invokeDepth -= 1;
|
|
53
|
+
while (parameterInvokeDepths.length > 0) {
|
|
54
|
+
const parameterInvokeDepth = parameterInvokeDepths[parameterInvokeDepths.length - 1];
|
|
55
|
+
if (parameterInvokeDepth === undefined || parameterInvokeDepth <= invokeDepth) {
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
parameterInvokeDepths.pop();
|
|
59
|
+
}
|
|
60
|
+
if (invokeDepth === 0) {
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return false;
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
export function createClosingTagMatcher(tagName) {
|
|
69
|
+
let state = "seek";
|
|
70
|
+
let nameIndex = 0;
|
|
71
|
+
function restart(character) {
|
|
72
|
+
state = character === "<" ? "after-open" : "seek";
|
|
73
|
+
nameIndex = 0;
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
feed(text) {
|
|
77
|
+
let matched = false;
|
|
78
|
+
for (const character of text) {
|
|
79
|
+
switch (state) {
|
|
80
|
+
case "seek":
|
|
81
|
+
if (character === "<") {
|
|
82
|
+
state = "after-open";
|
|
83
|
+
}
|
|
84
|
+
break;
|
|
85
|
+
case "after-open":
|
|
86
|
+
if (character === "/") {
|
|
87
|
+
state = "after-slash";
|
|
88
|
+
}
|
|
89
|
+
else if (!isWhitespace(character)) {
|
|
90
|
+
restart(character);
|
|
91
|
+
}
|
|
92
|
+
break;
|
|
93
|
+
case "after-slash":
|
|
94
|
+
if (character === tagName[0]) {
|
|
95
|
+
nameIndex = 1;
|
|
96
|
+
state = "name";
|
|
97
|
+
}
|
|
98
|
+
else if (!isWhitespace(character)) {
|
|
99
|
+
restart(character);
|
|
100
|
+
}
|
|
101
|
+
break;
|
|
102
|
+
case "name":
|
|
103
|
+
if (character !== tagName[nameIndex]) {
|
|
104
|
+
restart(character);
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
nameIndex += 1;
|
|
108
|
+
if (nameIndex === tagName.length) {
|
|
109
|
+
state = "after-name";
|
|
110
|
+
}
|
|
111
|
+
break;
|
|
112
|
+
case "after-name":
|
|
113
|
+
if (character === ">") {
|
|
114
|
+
matched = true;
|
|
115
|
+
state = "seek";
|
|
116
|
+
nameIndex = 0;
|
|
117
|
+
}
|
|
118
|
+
else if (!isWhitespace(character)) {
|
|
119
|
+
restart(character);
|
|
120
|
+
}
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return matched;
|
|
125
|
+
},
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
export function createTagEndMatcher() {
|
|
129
|
+
return {
|
|
130
|
+
feed(text) {
|
|
131
|
+
return text.includes(">");
|
|
132
|
+
},
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
export function createPendingFragment(kind, text) {
|
|
136
|
+
const matcher = kind === "invoke"
|
|
137
|
+
? createInvokeBoundaryMatcher()
|
|
138
|
+
: kind === "function-calls"
|
|
139
|
+
? createClosingTagMatcher("function_calls")
|
|
140
|
+
: createTagEndMatcher();
|
|
141
|
+
matcher.feed(text);
|
|
142
|
+
return { kind, matcher };
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=stream-boundary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream-boundary.js","sourceRoot":"","sources":["../../../../src/tool-call-middleware/protocols/anthropic-xml/stream-boundary.ts"],"names":[],"mappings":"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","sourcesContent":["const WHITESPACE = /\\s/;\nconst INVOKE_OPEN_TAG = /^<\\s*invoke\\b[^>]*>$/;\nconst INVOKE_CLOSE_TAG = /^<\\s*\\/\\s*invoke\\s*>$/;\nconst PARAMETER_OPEN_TAG = /^<\\s*parameter\\b[^>]*>$/;\nconst PARAMETER_CLOSE_TAG = /^<\\s*\\/\\s*parameter\\s*>$/;\n\n/** Incomplete protocol fragments are rejected before retained input can exceed this many UTF-16 code units. */\nexport const ANTHROPIC_XML_MAX_RETAINED_FRAGMENT_LENGTH = 64 * 1024;\n\nexport type StreamBoundaryMatcher = {\n\tfeed(text: string): boolean;\n};\n\nexport type PendingFragment = {\n\treadonly kind: \"invoke\" | \"function-calls\" | \"open-tag\";\n\treadonly matcher: StreamBoundaryMatcher;\n};\n\ntype ClosingTagState = \"seek\" | \"after-open\" | \"after-slash\" | \"name\" | \"after-name\";\n\nfunction isWhitespace(character: string): boolean {\n\treturn WHITESPACE.test(character);\n}\n\nfunction createInvokeBoundaryMatcher(): StreamBoundaryMatcher {\n\tlet invokeDepth = 0;\n\tconst parameterInvokeDepths: number[] = [];\n\tlet tagCharacters: string[] | null = null;\n\n\treturn {\n\t\tfeed(text: string): boolean {\n\t\t\tfor (const character of text) {\n\t\t\t\tif (tagCharacters === null) {\n\t\t\t\t\tif (character === \"<\") {\n\t\t\t\t\t\ttagCharacters = [character];\n\t\t\t\t\t}\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif (character === \"<\") {\n\t\t\t\t\ttagCharacters = [character];\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\ttagCharacters.push(character);\n\t\t\t\tif (character !== \">\") {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst tag = tagCharacters.join(\"\");\n\t\t\t\ttagCharacters = null;\n\t\t\t\tif (INVOKE_OPEN_TAG.test(tag)) {\n\t\t\t\t\tinvokeDepth += 1;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (PARAMETER_OPEN_TAG.test(tag)) {\n\t\t\t\t\tparameterInvokeDepths.push(invokeDepth);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (PARAMETER_CLOSE_TAG.test(tag)) {\n\t\t\t\t\tconst parameterInvokeDepth = parameterInvokeDepths.pop();\n\t\t\t\t\tif (parameterInvokeDepth !== undefined && invokeDepth > parameterInvokeDepth) {\n\t\t\t\t\t\tinvokeDepth = parameterInvokeDepth;\n\t\t\t\t\t}\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (!INVOKE_CLOSE_TAG.test(tag) || invokeDepth === 0) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tinvokeDepth -= 1;\n\t\t\t\twhile (parameterInvokeDepths.length > 0) {\n\t\t\t\t\tconst parameterInvokeDepth = parameterInvokeDepths[parameterInvokeDepths.length - 1];\n\t\t\t\t\tif (parameterInvokeDepth === undefined || parameterInvokeDepth <= invokeDepth) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tparameterInvokeDepths.pop();\n\t\t\t\t}\n\t\t\t\tif (invokeDepth === 0) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\t};\n}\n\nexport function createClosingTagMatcher(tagName: \"invoke\" | \"function_calls\"): StreamBoundaryMatcher {\n\tlet state: ClosingTagState = \"seek\";\n\tlet nameIndex = 0;\n\n\tfunction restart(character: string): void {\n\t\tstate = character === \"<\" ? \"after-open\" : \"seek\";\n\t\tnameIndex = 0;\n\t}\n\n\treturn {\n\t\tfeed(text: string): boolean {\n\t\t\tlet matched = false;\n\t\t\tfor (const character of text) {\n\t\t\t\tswitch (state) {\n\t\t\t\t\tcase \"seek\":\n\t\t\t\t\t\tif (character === \"<\") {\n\t\t\t\t\t\t\tstate = \"after-open\";\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"after-open\":\n\t\t\t\t\t\tif (character === \"/\") {\n\t\t\t\t\t\t\tstate = \"after-slash\";\n\t\t\t\t\t\t} else if (!isWhitespace(character)) {\n\t\t\t\t\t\t\trestart(character);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"after-slash\":\n\t\t\t\t\t\tif (character === tagName[0]) {\n\t\t\t\t\t\t\tnameIndex = 1;\n\t\t\t\t\t\t\tstate = \"name\";\n\t\t\t\t\t\t} else if (!isWhitespace(character)) {\n\t\t\t\t\t\t\trestart(character);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"name\":\n\t\t\t\t\t\tif (character !== tagName[nameIndex]) {\n\t\t\t\t\t\t\trestart(character);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tnameIndex += 1;\n\t\t\t\t\t\tif (nameIndex === tagName.length) {\n\t\t\t\t\t\t\tstate = \"after-name\";\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"after-name\":\n\t\t\t\t\t\tif (character === \">\") {\n\t\t\t\t\t\t\tmatched = true;\n\t\t\t\t\t\t\tstate = \"seek\";\n\t\t\t\t\t\t\tnameIndex = 0;\n\t\t\t\t\t\t} else if (!isWhitespace(character)) {\n\t\t\t\t\t\t\trestart(character);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn matched;\n\t\t},\n\t};\n}\n\nexport function createTagEndMatcher(): StreamBoundaryMatcher {\n\treturn {\n\t\tfeed(text: string): boolean {\n\t\t\treturn text.includes(\">\");\n\t\t},\n\t};\n}\n\nexport function createPendingFragment(kind: PendingFragment[\"kind\"], text: string): PendingFragment {\n\tconst matcher =\n\t\tkind === \"invoke\"\n\t\t\t? createInvokeBoundaryMatcher()\n\t\t\t: kind === \"function-calls\"\n\t\t\t\t? createClosingTagMatcher(\"function_calls\")\n\t\t\t\t: createTagEndMatcher();\n\tmatcher.feed(text);\n\treturn { kind, matcher };\n}\n"]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Tool } from "../../../types.ts";
|
|
2
|
+
import type { ParserOptions, StreamParser } from "../../types.ts";
|
|
3
|
+
export { ANTHROPIC_XML_MAX_RETAINED_FRAGMENT_LENGTH } from "./stream-boundary.ts";
|
|
4
|
+
export declare function createAnthropicXmlStreamParser(tools: Tool[], options?: ParserOptions): StreamParser;
|
|
5
|
+
//# sourceMappingURL=stream.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../../../src/tool-call-middleware/protocols/anthropic-xml/stream.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAqB,MAAM,gBAAgB,CAAC;AAiBrF,OAAO,EAAE,0CAA0C,EAAE,MAAM,sBAAsB,CAAC;AA6DlF,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,YAAY,CA6LnG"}
|