@nanocollective/nanocoder 1.14.3 → 1.15.1
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/README.md +31 -1
- package/dist/ai-sdk-client.d.ts +22 -0
- package/dist/ai-sdk-client.d.ts.map +1 -0
- package/dist/ai-sdk-client.js +389 -0
- package/dist/ai-sdk-client.js.map +1 -0
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +1 -1
- package/dist/app.js.map +1 -1
- package/dist/client-factory.d.ts.map +1 -1
- package/dist/client-factory.js +5 -5
- package/dist/client-factory.js.map +1 -1
- package/dist/commands/index.d.ts +1 -0
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +1 -0
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/recommendations.js +1 -1
- package/dist/commands/recommendations.js.map +1 -1
- package/dist/commands/streaming.d.ts +3 -0
- package/dist/commands/streaming.d.ts.map +1 -0
- package/dist/commands/streaming.js +23 -0
- package/dist/commands/streaming.js.map +1 -0
- package/dist/commands.d.ts.map +1 -1
- package/dist/commands.js +17 -3
- package/dist/commands.js.map +1 -1
- package/dist/components/assistant-message.d.ts +0 -1
- package/dist/components/assistant-message.d.ts.map +1 -1
- package/dist/components/assistant-message.js +70 -122
- package/dist/components/assistant-message.js.map +1 -1
- package/dist/components/thinking-indicator.js +1 -1
- package/dist/components/thinking-indicator.js.map +1 -1
- package/dist/components/user-input.d.ts.map +1 -1
- package/dist/components/user-input.js +135 -27
- package/dist/components/user-input.js.map +1 -1
- package/dist/components/user-message.d.ts.map +1 -1
- package/dist/components/user-message.js +34 -1
- package/dist/components/user-message.js.map +1 -1
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +2 -1
- package/dist/config/index.js.map +1 -1
- package/dist/config/index.spec.d.ts +2 -0
- package/dist/config/index.spec.d.ts.map +1 -0
- package/dist/config/index.spec.js +99 -0
- package/dist/config/index.spec.js.map +1 -0
- package/dist/config/preferences.d.ts +2 -0
- package/dist/config/preferences.d.ts.map +1 -1
- package/dist/config/preferences.js +10 -0
- package/dist/config/preferences.js.map +1 -1
- package/dist/hooks/useAppInitialization.d.ts.map +1 -1
- package/dist/hooks/useAppInitialization.js +2 -1
- package/dist/hooks/useAppInitialization.js.map +1 -1
- package/dist/hooks/useChatHandler.d.ts +2 -0
- package/dist/hooks/useChatHandler.d.ts.map +1 -1
- package/dist/hooks/useChatHandler.js +59 -9
- package/dist/hooks/useChatHandler.js.map +1 -1
- package/dist/mcp/mcp-client.d.ts +20 -1
- package/dist/mcp/mcp-client.d.ts.map +1 -1
- package/dist/mcp/mcp-client.js +57 -0
- package/dist/mcp/mcp-client.js.map +1 -1
- package/dist/message-handler.d.ts.map +1 -1
- package/dist/message-handler.js +7 -2
- package/dist/message-handler.js.map +1 -1
- package/dist/tool-calling/index.d.ts +1 -1
- package/dist/tool-calling/index.d.ts.map +1 -1
- package/dist/tool-calling/index.js +1 -1
- package/dist/tool-calling/index.js.map +1 -1
- package/dist/tool-calling/json-parser.d.ts +19 -2
- package/dist/tool-calling/json-parser.d.ts.map +1 -1
- package/dist/tool-calling/json-parser.js +65 -28
- package/dist/tool-calling/json-parser.js.map +1 -1
- package/dist/tool-calling/json-parser.spec.d.ts +2 -0
- package/dist/tool-calling/json-parser.spec.d.ts.map +1 -0
- package/dist/tool-calling/json-parser.spec.js +518 -0
- package/dist/tool-calling/json-parser.spec.js.map +1 -0
- package/dist/tool-calling/tool-parser.d.ts +20 -0
- package/dist/tool-calling/tool-parser.d.ts.map +1 -0
- package/dist/tool-calling/tool-parser.js +58 -0
- package/dist/tool-calling/tool-parser.js.map +1 -0
- package/dist/tool-calling/tool-parser.spec.d.ts +2 -0
- package/dist/tool-calling/tool-parser.spec.d.ts.map +1 -0
- package/dist/tool-calling/tool-parser.spec.js +250 -0
- package/dist/tool-calling/tool-parser.spec.js.map +1 -0
- package/dist/tool-calling/xml-parser.d.ts +17 -0
- package/dist/tool-calling/xml-parser.d.ts.map +1 -1
- package/dist/tool-calling/xml-parser.js +101 -13
- package/dist/tool-calling/xml-parser.js.map +1 -1
- package/dist/tool-calling/xml-parser.spec.d.ts +2 -0
- package/dist/tool-calling/xml-parser.spec.d.ts.map +1 -0
- package/dist/tool-calling/xml-parser.spec.js +437 -0
- package/dist/tool-calling/xml-parser.spec.js.map +1 -0
- package/dist/tools/create-file.d.ts.map +1 -1
- package/dist/tools/create-file.js +26 -23
- package/dist/tools/create-file.js.map +1 -1
- package/dist/tools/delete-lines.d.ts.map +1 -1
- package/dist/tools/delete-lines.js +29 -27
- package/dist/tools/delete-lines.js.map +1 -1
- package/dist/tools/execute-bash.d.ts.map +1 -1
- package/dist/tools/execute-bash.js +21 -19
- package/dist/tools/execute-bash.js.map +1 -1
- package/dist/tools/fetch-url.d.ts.map +1 -1
- package/dist/tools/fetch-url.js +21 -19
- package/dist/tools/fetch-url.js.map +1 -1
- package/dist/tools/index.d.ts +2 -2
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +8 -6
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/insert-lines.d.ts.map +1 -1
- package/dist/tools/insert-lines.js +29 -27
- package/dist/tools/insert-lines.js.map +1 -1
- package/dist/tools/read-file.d.ts.map +1 -1
- package/dist/tools/read-file.js +23 -19
- package/dist/tools/read-file.js.map +1 -1
- package/dist/tools/read-many-files.d.ts.map +1 -1
- package/dist/tools/read-many-files.js +24 -20
- package/dist/tools/read-many-files.js.map +1 -1
- package/dist/tools/replace-lines.d.ts.map +1 -1
- package/dist/tools/replace-lines.js +33 -31
- package/dist/tools/replace-lines.js.map +1 -1
- package/dist/tools/search-files.d.ts.map +1 -1
- package/dist/tools/search-files.js +33 -31
- package/dist/tools/search-files.js.map +1 -1
- package/dist/tools/tool-manager.d.ts +35 -19
- package/dist/tools/tool-manager.d.ts.map +1 -1
- package/dist/tools/tool-manager.js +63 -33
- package/dist/tools/tool-manager.js.map +1 -1
- package/dist/tools/tool-registry.d.ts +121 -0
- package/dist/tools/tool-registry.d.ts.map +1 -0
- package/dist/tools/tool-registry.js +195 -0
- package/dist/tools/tool-registry.js.map +1 -0
- package/dist/tools/web-search.d.ts.map +1 -1
- package/dist/tools/web-search.js +25 -23
- package/dist/tools/web-search.js.map +1 -1
- package/dist/types/config.d.ts +2 -1
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/core.d.ts +58 -3
- package/dist/types/core.d.ts.map +1 -1
- package/dist/types/core.js +2 -0
- package/dist/types/core.js.map +1 -1
- package/dist/utils/file-autocomplete.d.ts +31 -0
- package/dist/utils/file-autocomplete.d.ts.map +1 -0
- package/dist/utils/file-autocomplete.js +156 -0
- package/dist/utils/file-autocomplete.js.map +1 -0
- package/dist/utils/file-autocomplete.spec.d.ts +2 -0
- package/dist/utils/file-autocomplete.spec.d.ts.map +1 -0
- package/dist/utils/file-autocomplete.spec.js +142 -0
- package/dist/utils/file-autocomplete.spec.js.map +1 -0
- package/dist/utils/file-content-loader.d.ts +31 -0
- package/dist/utils/file-content-loader.d.ts.map +1 -0
- package/dist/utils/file-content-loader.js +142 -0
- package/dist/utils/file-content-loader.js.map +1 -0
- package/dist/utils/file-content-loader.spec.d.ts +2 -0
- package/dist/utils/file-content-loader.spec.d.ts.map +1 -0
- package/dist/utils/file-content-loader.spec.js +140 -0
- package/dist/utils/file-content-loader.spec.js.map +1 -0
- package/dist/utils/file-mention-handler.d.ts +21 -0
- package/dist/utils/file-mention-handler.d.ts.map +1 -0
- package/dist/utils/file-mention-handler.js +59 -0
- package/dist/utils/file-mention-handler.js.map +1 -0
- package/dist/utils/file-mention-handler.spec.d.ts +2 -0
- package/dist/utils/file-mention-handler.spec.d.ts.map +1 -0
- package/dist/utils/file-mention-handler.spec.js +147 -0
- package/dist/utils/file-mention-handler.spec.js.map +1 -0
- package/dist/utils/file-mention-parser.d.ts +40 -0
- package/dist/utils/file-mention-parser.d.ts.map +1 -0
- package/dist/utils/file-mention-parser.js +122 -0
- package/dist/utils/file-mention-parser.js.map +1 -0
- package/dist/utils/file-mention-parser.spec.d.ts +2 -0
- package/dist/utils/file-mention-parser.spec.d.ts.map +1 -0
- package/dist/utils/file-mention-parser.spec.js +149 -0
- package/dist/utils/file-mention-parser.spec.js.map +1 -0
- package/dist/utils/fuzzy-matching.d.ts +13 -0
- package/dist/utils/fuzzy-matching.d.ts.map +1 -0
- package/dist/utils/fuzzy-matching.js +127 -0
- package/dist/utils/fuzzy-matching.js.map +1 -0
- package/dist/utils/fuzzy-matching.spec.d.ts +2 -0
- package/dist/utils/fuzzy-matching.spec.d.ts.map +1 -0
- package/dist/utils/fuzzy-matching.spec.js +123 -0
- package/dist/utils/fuzzy-matching.spec.js.map +1 -0
- package/dist/utils/prompt-assembly.spec.js +100 -2
- package/dist/utils/prompt-assembly.spec.js.map +1 -1
- package/dist/utils/prompt-processor.d.ts +2 -2
- package/dist/utils/prompt-processor.d.ts.map +1 -1
- package/dist/utils/prompt-processor.js +24 -41
- package/dist/utils/prompt-processor.js.map +1 -1
- package/package.json +8 -5
- package/dist/langgraph-client.d.ts +0 -19
- package/dist/langgraph-client.d.ts.map +0 -1
- package/dist/langgraph-client.js +0 -295
- package/dist/langgraph-client.js.map +0 -1
- package/dist/mcp/mcp-tool-adapter.d.ts +0 -22
- package/dist/mcp/mcp-tool-adapter.d.ts.map +0 -1
- package/dist/mcp/mcp-tool-adapter.js +0 -50
- package/dist/mcp/mcp-tool-adapter.js.map +0 -1
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import test from 'ava';
|
|
2
|
+
import { parseToolCalls } from './tool-parser.js';
|
|
3
|
+
console.log(`\ntool-parser.spec.ts`);
|
|
4
|
+
// XML Parser Tests
|
|
5
|
+
test('parseToolCalls: successfully parses valid XML tool call', t => {
|
|
6
|
+
const content = `
|
|
7
|
+
<read_file>
|
|
8
|
+
<path>/path/to/file.txt</path>
|
|
9
|
+
</read_file>
|
|
10
|
+
`;
|
|
11
|
+
const result = parseToolCalls(content);
|
|
12
|
+
t.true(result.success);
|
|
13
|
+
if (result.success) {
|
|
14
|
+
t.is(result.toolCalls.length, 1);
|
|
15
|
+
t.is(result.toolCalls[0].function.name, 'read_file');
|
|
16
|
+
t.deepEqual(result.toolCalls[0].function.arguments, {
|
|
17
|
+
path: '/path/to/file.txt',
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
test('parseToolCalls: detects malformed XML with attribute syntax', t => {
|
|
22
|
+
const content = `
|
|
23
|
+
<function=read_file>
|
|
24
|
+
<parameter=path>/path/to/file.txt</parameter>
|
|
25
|
+
</function>
|
|
26
|
+
|
|
27
|
+
I want to read the file at /path/to/file.txt
|
|
28
|
+
`;
|
|
29
|
+
const result = parseToolCalls(content);
|
|
30
|
+
t.false(result.success);
|
|
31
|
+
if (!result.success) {
|
|
32
|
+
t.regex(result.error, /Invalid syntax/i);
|
|
33
|
+
t.regex(result.examples, /Correct format/i);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
test('parseToolCalls: handles multiple valid XML tool calls', t => {
|
|
37
|
+
const content = `
|
|
38
|
+
<read_file>
|
|
39
|
+
<path>/path/to/file1.txt</path>
|
|
40
|
+
</read_file>
|
|
41
|
+
|
|
42
|
+
<create_file>
|
|
43
|
+
<path>/path/to/file2.txt</path>
|
|
44
|
+
<content>Hello world</content>
|
|
45
|
+
</create_file>
|
|
46
|
+
`;
|
|
47
|
+
const result = parseToolCalls(content);
|
|
48
|
+
t.true(result.success);
|
|
49
|
+
if (result.success) {
|
|
50
|
+
t.is(result.toolCalls.length, 2);
|
|
51
|
+
t.is(result.toolCalls[0].function.name, 'read_file');
|
|
52
|
+
t.is(result.toolCalls[1].function.name, 'create_file');
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
test('parseToolCalls: cleans XML tool calls from content', t => {
|
|
56
|
+
const content = `
|
|
57
|
+
Here is some text before the tool call.
|
|
58
|
+
|
|
59
|
+
<read_file>
|
|
60
|
+
<path>/path/to/file.txt</path>
|
|
61
|
+
</read_file>
|
|
62
|
+
|
|
63
|
+
And some text after.
|
|
64
|
+
`;
|
|
65
|
+
const result = parseToolCalls(content);
|
|
66
|
+
t.true(result.success);
|
|
67
|
+
if (result.success) {
|
|
68
|
+
t.is(result.toolCalls.length, 1);
|
|
69
|
+
t.regex(result.cleanedContent, /Here is some text before/);
|
|
70
|
+
t.regex(result.cleanedContent, /And some text after/);
|
|
71
|
+
t.notRegex(result.cleanedContent, /<read_file>/);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
// JSON Parser Tests
|
|
75
|
+
test('parseToolCalls: successfully parses valid JSON tool call', t => {
|
|
76
|
+
const content = `
|
|
77
|
+
{
|
|
78
|
+
"name": "read_file",
|
|
79
|
+
"arguments": {
|
|
80
|
+
"path": "/path/to/file.txt"
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
`;
|
|
84
|
+
const result = parseToolCalls(content);
|
|
85
|
+
t.true(result.success);
|
|
86
|
+
if (result.success) {
|
|
87
|
+
t.is(result.toolCalls.length, 1);
|
|
88
|
+
t.is(result.toolCalls[0].function.name, 'read_file');
|
|
89
|
+
t.deepEqual(result.toolCalls[0].function.arguments, {
|
|
90
|
+
path: '/path/to/file.txt',
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
test('parseToolCalls: detects malformed JSON missing arguments field', t => {
|
|
95
|
+
const content = `
|
|
96
|
+
{
|
|
97
|
+
"name": "read_file"
|
|
98
|
+
}
|
|
99
|
+
`;
|
|
100
|
+
const result = parseToolCalls(content);
|
|
101
|
+
t.false(result.success);
|
|
102
|
+
if (!result.success) {
|
|
103
|
+
t.regex(result.error, /missing "arguments" field/i);
|
|
104
|
+
t.regex(result.examples, /Correct format/i);
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
test('parseToolCalls: detects malformed JSON missing name field', t => {
|
|
108
|
+
const content = `
|
|
109
|
+
{
|
|
110
|
+
"arguments": {
|
|
111
|
+
"path": "/path/to/file.txt"
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
`;
|
|
115
|
+
const result = parseToolCalls(content);
|
|
116
|
+
t.false(result.success);
|
|
117
|
+
if (!result.success) {
|
|
118
|
+
t.regex(result.error, /missing "name" field/i);
|
|
119
|
+
t.regex(result.examples, /Correct format/i);
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
test('parseToolCalls: detects malformed JSON with string arguments', t => {
|
|
123
|
+
const content = `
|
|
124
|
+
{
|
|
125
|
+
"name": "read_file",
|
|
126
|
+
"arguments": "/path/to/file.txt"
|
|
127
|
+
}
|
|
128
|
+
`;
|
|
129
|
+
const result = parseToolCalls(content);
|
|
130
|
+
t.false(result.success);
|
|
131
|
+
if (!result.success) {
|
|
132
|
+
t.regex(result.error, /"arguments" must be an object/i);
|
|
133
|
+
t.regex(result.examples, /Correct format/i);
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
test('parseToolCalls: handles JSON in markdown code blocks', t => {
|
|
137
|
+
const content = `
|
|
138
|
+
\`\`\`json
|
|
139
|
+
{
|
|
140
|
+
"name": "read_file",
|
|
141
|
+
"arguments": {
|
|
142
|
+
"path": "/path/to/file.txt"
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
\`\`\`
|
|
146
|
+
`;
|
|
147
|
+
const result = parseToolCalls(content);
|
|
148
|
+
t.true(result.success);
|
|
149
|
+
if (result.success) {
|
|
150
|
+
t.is(result.toolCalls.length, 1);
|
|
151
|
+
t.is(result.toolCalls[0].function.name, 'read_file');
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
test('parseToolCalls: cleans JSON tool calls from content', t => {
|
|
155
|
+
const content = `
|
|
156
|
+
Here is some text before.
|
|
157
|
+
|
|
158
|
+
{
|
|
159
|
+
"name": "read_file",
|
|
160
|
+
"arguments": {
|
|
161
|
+
"path": "/path/to/file.txt"
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
And some text after.
|
|
166
|
+
`;
|
|
167
|
+
const result = parseToolCalls(content);
|
|
168
|
+
t.true(result.success);
|
|
169
|
+
if (result.success) {
|
|
170
|
+
t.is(result.toolCalls.length, 1);
|
|
171
|
+
t.regex(result.cleanedContent, /Here is some text before/);
|
|
172
|
+
t.regex(result.cleanedContent, /And some text after/);
|
|
173
|
+
t.notRegex(result.cleanedContent, /"name":\s*"read_file"/);
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
// Priority Tests (XML should be tried first)
|
|
177
|
+
test('parseToolCalls: prioritizes XML over JSON when both present', t => {
|
|
178
|
+
const content = `
|
|
179
|
+
<read_file>
|
|
180
|
+
<path>/xml/path.txt</path>
|
|
181
|
+
</read_file>
|
|
182
|
+
|
|
183
|
+
{
|
|
184
|
+
"name": "read_file",
|
|
185
|
+
"arguments": {
|
|
186
|
+
"path": "/json/path.txt"
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
`;
|
|
190
|
+
const result = parseToolCalls(content);
|
|
191
|
+
t.true(result.success);
|
|
192
|
+
if (result.success) {
|
|
193
|
+
// Should parse XML first and return immediately
|
|
194
|
+
t.is(result.toolCalls.length, 1);
|
|
195
|
+
t.is(result.toolCalls[0].function.name, 'read_file');
|
|
196
|
+
// Verify it's the XML call (xml_call_ prefix)
|
|
197
|
+
t.regex(result.toolCalls[0].id, /xml_call/);
|
|
198
|
+
t.is(result.toolCalls[0].function.arguments.path, '/xml/path.txt');
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
// Edge Cases
|
|
202
|
+
test('parseToolCalls: handles empty content', t => {
|
|
203
|
+
const result = parseToolCalls('');
|
|
204
|
+
t.true(result.success);
|
|
205
|
+
if (result.success) {
|
|
206
|
+
t.is(result.toolCalls.length, 0);
|
|
207
|
+
t.is(result.cleanedContent, '');
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
test('parseToolCalls: handles content with no tool calls', t => {
|
|
211
|
+
const content = 'Just some plain text without any tool calls.';
|
|
212
|
+
const result = parseToolCalls(content);
|
|
213
|
+
t.true(result.success);
|
|
214
|
+
if (result.success) {
|
|
215
|
+
t.is(result.toolCalls.length, 0);
|
|
216
|
+
t.is(result.cleanedContent, content);
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
test('parseToolCalls: handles empty JSON object', t => {
|
|
220
|
+
const content = '{}';
|
|
221
|
+
const result = parseToolCalls(content);
|
|
222
|
+
t.true(result.success);
|
|
223
|
+
if (result.success) {
|
|
224
|
+
t.is(result.toolCalls.length, 0);
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
test('parseToolCalls: deduplicates identical tool calls', t => {
|
|
228
|
+
const content = `
|
|
229
|
+
{
|
|
230
|
+
"name": "read_file",
|
|
231
|
+
"arguments": {
|
|
232
|
+
"path": "/path/to/file.txt"
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
{
|
|
237
|
+
"name": "read_file",
|
|
238
|
+
"arguments": {
|
|
239
|
+
"path": "/path/to/file.txt"
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
`;
|
|
243
|
+
const result = parseToolCalls(content);
|
|
244
|
+
t.true(result.success);
|
|
245
|
+
if (result.success) {
|
|
246
|
+
// Should deduplicate to single call
|
|
247
|
+
t.is(result.toolCalls.length, 1);
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
//# sourceMappingURL=tool-parser.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-parser.spec.js","sourceRoot":"","sources":["../../source/tool-calling/tool-parser.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,6 +14,11 @@ export declare class XMLToolCallParser {
|
|
|
14
14
|
* Extracts tool calls from text content containing XML-formatted tool calls
|
|
15
15
|
*/
|
|
16
16
|
static parseToolCalls(content: string): ParsedToolCall[];
|
|
17
|
+
/**
|
|
18
|
+
* Validates that a matched string is a proper tool call
|
|
19
|
+
* Rejects partial matches, malformed syntax, and invalid structures
|
|
20
|
+
*/
|
|
21
|
+
private static isValidToolCall;
|
|
17
22
|
/**
|
|
18
23
|
* Parses parameters from inner XML content
|
|
19
24
|
*/
|
|
@@ -30,6 +35,18 @@ export declare class XMLToolCallParser {
|
|
|
30
35
|
* Checks if content contains XML-formatted tool calls
|
|
31
36
|
*/
|
|
32
37
|
static hasToolCalls(content: string): boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Detects malformed XML tool call attempts and returns error details
|
|
40
|
+
* Returns null if no malformed tool calls detected
|
|
41
|
+
*/
|
|
42
|
+
static detectMalformedToolCall(content: string): {
|
|
43
|
+
error: string;
|
|
44
|
+
examples: string;
|
|
45
|
+
} | null;
|
|
46
|
+
/**
|
|
47
|
+
* Generates correct format examples for error messages
|
|
48
|
+
*/
|
|
49
|
+
private static getCorrectFormatExamples;
|
|
33
50
|
}
|
|
34
51
|
export {};
|
|
35
52
|
//# sourceMappingURL=xml-parser.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"xml-parser.d.ts","sourceRoot":"","sources":["../../source/tool-calling/xml-parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,eAAe,CAAC;AAE5C,UAAU,cAAc;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED;;;GAGG;AACH,qBAAa,iBAAiB;IAC7B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAA0B;IACjE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,
|
|
1
|
+
{"version":3,"file":"xml-parser.d.ts","sourceRoot":"","sources":["../../source/tool-calling/xml-parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,eAAe,CAAC;AAE5C,UAAU,cAAc;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED;;;GAGG;AACH,qBAAa,iBAAiB;IAC7B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAA0B;IACjE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAA0B;IAEjE;;OAEG;IACH,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,EAAE;IAwCxD;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,eAAe;IAiC9B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,eAAe;IAyB9B;;OAEG;IACH,MAAM,CAAC,kBAAkB,CAAC,WAAW,EAAE,cAAc,EAAE,GAAG,QAAQ,EAAE;IAUpE;;OAEG;IACH,MAAM,CAAC,0BAA0B,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAiC1D;;OAEG;IACH,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAM7C;;;OAGG;IACH,MAAM,CAAC,uBAAuB,CAC7B,OAAO,EAAE,MAAM,GACb;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAC,GAAG,IAAI;IAmD3C;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,wBAAwB;CAQvC"}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
export class XMLToolCallParser {
|
|
6
6
|
static TOOL_CALL_REGEX = /<(\w+)>(.*?)<\/\1>/gs;
|
|
7
|
-
static PARAMETER_REGEX = /<(\w+)>(.*?)<\/\1>/
|
|
7
|
+
static PARAMETER_REGEX = /<(\w+)>(.*?)<\/\1>/gs;
|
|
8
8
|
/**
|
|
9
9
|
* Extracts tool calls from text content containing XML-formatted tool calls
|
|
10
10
|
*/
|
|
@@ -22,11 +22,15 @@ export class XMLToolCallParser {
|
|
|
22
22
|
// Find all tool call blocks
|
|
23
23
|
this.TOOL_CALL_REGEX.lastIndex = 0; // Reset regex state
|
|
24
24
|
while ((match = this.TOOL_CALL_REGEX.exec(processedContent)) !== null) {
|
|
25
|
-
const [, toolName, innerXml] = match;
|
|
25
|
+
const [fullMatch, toolName, innerXml] = match;
|
|
26
26
|
// Skip if this is a generic "tool_call" tag that slipped through
|
|
27
27
|
if (toolName === 'tool_call') {
|
|
28
28
|
continue;
|
|
29
29
|
}
|
|
30
|
+
// Validate that this is a properly formed tool call
|
|
31
|
+
if (!this.isValidToolCall(fullMatch, toolName)) {
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
30
34
|
const parameters = this.parseParameters(innerXml);
|
|
31
35
|
toolCalls.push({
|
|
32
36
|
toolName,
|
|
@@ -35,6 +39,33 @@ export class XMLToolCallParser {
|
|
|
35
39
|
}
|
|
36
40
|
return toolCalls;
|
|
37
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* Validates that a matched string is a proper tool call
|
|
44
|
+
* Rejects partial matches, malformed syntax, and invalid structures
|
|
45
|
+
*/
|
|
46
|
+
static isValidToolCall(fullMatch, toolName) {
|
|
47
|
+
// Check for malformed attribute-style syntax like <function=name> or <parameter=name>
|
|
48
|
+
if (fullMatch.includes('=')) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
// Check if the closing tag is properly formed
|
|
52
|
+
if (!fullMatch.endsWith(`</${toolName}>`)) {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
// Extract inner content between opening and closing tags
|
|
56
|
+
const innerContent = fullMatch.substring(toolName.length + 2, fullMatch.length - (toolName.length + 3));
|
|
57
|
+
// Valid tool calls should contain parameter tags (other XML tags inside)
|
|
58
|
+
// This prevents matching on standalone parameter tags from malformed XML
|
|
59
|
+
const hasNestedTags = /<\w+>/.test(innerContent);
|
|
60
|
+
// Tool names should contain underscores (snake_case convention for tools)
|
|
61
|
+
// or be reasonably long compound words
|
|
62
|
+
const hasUnderscore = toolName.includes('_');
|
|
63
|
+
// Allow if it has nested tags OR follows naming convention
|
|
64
|
+
if (!hasNestedTags && !hasUnderscore) {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
38
69
|
/**
|
|
39
70
|
* Parses parameters from inner XML content
|
|
40
71
|
*/
|
|
@@ -45,13 +76,15 @@ export class XMLToolCallParser {
|
|
|
45
76
|
this.PARAMETER_REGEX.lastIndex = 0;
|
|
46
77
|
while ((match = this.PARAMETER_REGEX.exec(innerXml)) !== null) {
|
|
47
78
|
const [, paramName, paramValue] = match;
|
|
79
|
+
// Trim whitespace from parameter value
|
|
80
|
+
const trimmedValue = paramValue.trim();
|
|
48
81
|
// Try to parse as JSON for complex objects/arrays
|
|
49
82
|
try {
|
|
50
|
-
parameters[paramName] = JSON.parse(
|
|
83
|
+
parameters[paramName] = JSON.parse(trimmedValue);
|
|
51
84
|
}
|
|
52
85
|
catch {
|
|
53
|
-
// If not valid JSON, use as string
|
|
54
|
-
parameters[paramName] =
|
|
86
|
+
// If not valid JSON, use as string (preserving internal whitespace/newlines)
|
|
87
|
+
parameters[paramName] = trimmedValue;
|
|
55
88
|
}
|
|
56
89
|
}
|
|
57
90
|
return parameters;
|
|
@@ -99,15 +132,70 @@ export class XMLToolCallParser {
|
|
|
99
132
|
* Checks if content contains XML-formatted tool calls
|
|
100
133
|
*/
|
|
101
134
|
static hasToolCalls(content) {
|
|
102
|
-
//
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
135
|
+
// Use parseToolCalls with validation to ensure we only detect valid tool calls
|
|
136
|
+
const toolCalls = this.parseToolCalls(content);
|
|
137
|
+
return toolCalls.length > 0;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Detects malformed XML tool call attempts and returns error details
|
|
141
|
+
* Returns null if no malformed tool calls detected
|
|
142
|
+
*/
|
|
143
|
+
static detectMalformedToolCall(content) {
|
|
144
|
+
// Common malformed patterns
|
|
145
|
+
const patterns = [
|
|
146
|
+
{
|
|
147
|
+
// <function=name> syntax
|
|
148
|
+
regex: /<function=(\w+)>/,
|
|
149
|
+
error: 'Invalid syntax: <function=name> is not supported',
|
|
150
|
+
hint: (match) => {
|
|
151
|
+
const toolName = match.match(/<function=(\w+)>/)?.[1];
|
|
152
|
+
return `Use <${toolName}> instead of <function=${toolName}>`;
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
// <parameter=name> syntax
|
|
157
|
+
regex: /<parameter=(\w+)>/,
|
|
158
|
+
error: 'Invalid syntax: <parameter=name> is not supported',
|
|
159
|
+
hint: (match) => {
|
|
160
|
+
const paramName = match.match(/<parameter=(\w+)>/)?.[1];
|
|
161
|
+
return `Use <${paramName}>value</${paramName}> instead of <parameter=${paramName}>value</parameter>`;
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
// Generic closing </parameter> without proper name
|
|
166
|
+
regex: /<parameter=\w+>[\s\S]*?<\/parameter>/,
|
|
167
|
+
error: 'Invalid parameter syntax: parameters must use named tags, not generic <parameter> wrapper',
|
|
168
|
+
hint: () => 'Use <param_name>value</param_name> format',
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
// Generic closing </function> when <function=name> was used
|
|
172
|
+
regex: /<function=\w+>[\s\S]*?<\/function>/,
|
|
173
|
+
error: 'Invalid function syntax: use simple named tags, not <function=name> wrapper',
|
|
174
|
+
hint: () => 'Use <tool_name><param>value</param></tool_name> format',
|
|
175
|
+
},
|
|
176
|
+
];
|
|
177
|
+
for (const pattern of patterns) {
|
|
178
|
+
const match = content.match(pattern.regex);
|
|
179
|
+
if (match) {
|
|
180
|
+
const hint = pattern.hint(match[0]);
|
|
181
|
+
return {
|
|
182
|
+
error: pattern.error,
|
|
183
|
+
examples: this.getCorrectFormatExamples(hint),
|
|
184
|
+
};
|
|
185
|
+
}
|
|
107
186
|
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Generates correct format examples for error messages
|
|
191
|
+
*/
|
|
192
|
+
static getCorrectFormatExamples(specificHint) {
|
|
193
|
+
return `${specificHint}
|
|
194
|
+
|
|
195
|
+
Correct format:
|
|
196
|
+
<tool_name>
|
|
197
|
+
<param>value</param>
|
|
198
|
+
</tool_name>`;
|
|
111
199
|
}
|
|
112
200
|
}
|
|
113
201
|
//# sourceMappingURL=xml-parser.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"xml-parser.js","sourceRoot":"","sources":["../../source/tool-calling/xml-parser.ts"],"names":[],"mappings":"AAOA;;;GAGG;AACH,MAAM,OAAO,iBAAiB;IACrB,MAAM,CAAU,eAAe,GAAG,sBAAsB,CAAC;IACzD,MAAM,CAAU,eAAe,GAAG,
|
|
1
|
+
{"version":3,"file":"xml-parser.js","sourceRoot":"","sources":["../../source/tool-calling/xml-parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xml-parser.spec.d.ts","sourceRoot":"","sources":["../../source/tool-calling/xml-parser.spec.ts"],"names":[],"mappings":""}
|