kiku-agent 1.3.2 → 1.3.4
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 +69 -12
- package/package.json +2 -1
- package/server/agent/agentCore.js +319 -46
- package/server/agent/appPaths.js +31 -0
- package/server/agent/audioPlayer.js +339 -12
- package/server/agent/autoContext.js +193 -0
- package/server/agent/catalogEntityResolver.js +170 -28
- package/server/agent/clarifyingQuestions.js +137 -35
- package/server/agent/cli.js +177 -48
- package/server/agent/cloudAdapters.js +116 -0
- package/server/agent/commandRegistry.js +409 -80
- package/server/agent/commands.js +1056 -125
- package/server/agent/config.js +1088 -690
- package/server/agent/contextCompactor.js +213 -21
- package/server/agent/cpuMetrics.js +199 -0
- package/server/agent/engineService.js +591 -0
- package/server/agent/eval/modules/evaluation/runner.js +4 -14
- package/server/agent/eval/modules/evaluation/scoring.js +15 -3
- package/server/agent/eval/modules/server/evalApi.js +5 -5
- package/server/agent/eval/modules/ui/evalUi.js +7 -4
- package/server/agent/eventBus.js +1 -0
- package/server/agent/ink/main.jsx +196 -191
- package/server/agent/jobManager.js +11 -1
- package/server/agent/lanDiscovery.js +721 -23
- package/server/agent/llmClient.js +317 -71
- package/server/agent/lmStudioWakeup.js +517 -65
- package/server/agent/locationService.js +797 -0
- package/server/agent/mcpQuizData.js +509 -0
- package/server/agent/memory/contextAllocator.js +19 -7
- package/server/agent/memory.js +3 -1
- package/server/agent/modelCompatibility.js +352 -0
- package/server/agent/modelDefaults.js +1 -0
- package/server/agent/modelManager.js +46 -2
- package/server/agent/newsWatch.js +9 -3
- package/server/agent/processManager.js +229 -0
- package/server/agent/prompts.js +174 -8
- package/server/agent/routingInterceptor.js +9 -1
- package/server/agent/sanitizer.js +41 -6
- package/server/agent/searchQueryPlanner.js +202 -0
- package/server/agent/session.js +59 -4
- package/server/agent/tests/agentFollowUps.test.js +128 -2
- package/server/agent/tests/agentMusicControl.test.js +245 -0
- package/server/agent/tests/apiRouter.test.js +1 -1
- package/server/agent/tests/autoContext.test.js +176 -0
- package/server/agent/tests/bilibiliEmbed.test.js +45 -0
- package/server/agent/tests/chatHardening.test.js +121 -0
- package/server/agent/tests/chineseWebSearchEscalation.test.js +62 -0
- package/server/agent/tests/clarifyingQuestions.test.js +33 -0
- package/server/agent/tests/cliAutomation.test.js +38 -1
- package/server/agent/tests/cloudProviders.test.js +91 -3
- package/server/agent/tests/commands.test.js +92 -3
- package/server/agent/tests/contextIntelligence.test.js +50 -3
- package/server/agent/tests/cpuMetrics.test.js +101 -0
- package/server/agent/tests/decisionAndSearchEnhancements.test.js +32 -0
- package/server/agent/tests/edgeCasesScenarios.test.js +82 -0
- package/server/agent/tests/engineService.test.js +436 -0
- package/server/agent/tests/engineUnload.test.js +94 -0
- package/server/agent/tests/envCommand.test.js +69 -0
- package/server/agent/tests/evalMetrics.test.js +8 -0
- package/server/agent/tests/fetchApi.test.js +99 -0
- package/server/agent/tests/hybridWebSearch.test.js +2 -0
- package/server/agent/tests/lanDiscovery.test.js +5 -0
- package/server/agent/tests/lanInterfaces.test.js +510 -0
- package/server/agent/tests/lmStudioWakeup.test.js +278 -0
- package/server/agent/tests/locationTool.test.js +278 -0
- package/server/agent/tests/memoryRoute.test.js +173 -0
- package/server/agent/tests/memoryUiNormalization.test.js +75 -0
- package/server/agent/tests/modelCompatibility.test.js +148 -0
- package/server/agent/tests/modelManager.test.js +32 -0
- package/server/agent/tests/musicControlUiBridge.test.js +113 -0
- package/server/agent/tests/nextGenArchitecture.test.js +4 -2
- package/server/agent/tests/openDomainPrompt.test.js +197 -0
- package/server/agent/tests/openDomainSearch.test.js +121 -0
- package/server/agent/tests/processManager.test.js +144 -0
- package/server/agent/tests/providerPersistence.test.js +10 -5
- package/server/agent/tests/quickActionsAndModals.test.js +180 -0
- package/server/agent/tests/searchQueryPlanner.test.js +108 -0
- package/server/agent/tests/securityAuditRemediation.test.js +16 -9
- package/server/agent/tests/securityAuditRemediations2.test.js +154 -0
- package/server/agent/tests/securityHardening.test.js +4 -4
- package/server/agent/tests/sessionAndCopy.test.js +39 -4
- package/server/agent/tests/sidebarControls.test.js +34 -0
- package/server/agent/tests/statefulMemory.test.js +8 -1
- package/server/agent/tests/textProtocolLoop.test.js +71 -0
- package/server/agent/tests/textToolParsing.test.js +48 -0
- package/server/agent/tests/toolRoutingRegressions.test.js +41 -0
- package/server/agent/tests/unifiedEndpoints.test.js +13 -6
- package/server/agent/tests/v110Features.test.js +1 -1
- package/server/agent/tests/vramEstimator.test.js +75 -0
- package/server/agent/tests/webChatDocs.test.js +199 -0
- package/server/agent/tests/webChatInferenceControl.test.js +298 -0
- package/server/agent/tests/webChatInspection.test.js +256 -5
- package/server/agent/tests/webChatMcp.test.js +94 -0
- package/server/agent/tests/webExtract.test.js +23 -0
- package/server/agent/tests/webSources.test.js +46 -12
- package/server/agent/textToolProtocol.js +173 -46
- package/server/agent/toolRouter.js +318 -44
- package/server/agent/tools.js +877 -96
- package/server/agent/ui.js +39 -34
- package/server/agent/vramService.js +35 -54
- package/server/agent/webSearch.js +441 -162
- package/server/agent/websearch/orchestrator.js +15 -5
- package/server/agent/websearch/resilience/cache.js +9 -2
- package/server/agent/websearch/security/ssrf.js +41 -10
- package/server/agent/youtubeAuth.js +5 -20
- package/server/apiRouter.js +5558 -4422
- package/server/mcp/data/discography.js +2 -2
- package/server/mcp/examples/antigravity.example.json +17 -0
- package/server/mcp/handler.js +8 -4
- package/server/mcp/security.js +220 -21
- package/server/mcp/server.js +2 -1
- package/server/mcp/tests/connection.test.js +14 -8
- package/server/mcp/tests/mcpKeyAuth.test.js +156 -0
- package/server/mcp/tools.js +7 -1
- package/server/supabase_migration_prefix.sql +102 -0
- package/server/supabase_schema.sql +18 -18
- package/server/web-chat/core/connection.js +179 -218
- package/server/web-chat/core/conversationContext.js +9 -2
- package/server/web-chat/core/directCatalogEngine.js +52 -28
- package/server/web-chat/core/dramaKnowledge.js +33 -22
- package/server/web-chat/core/followUpEngine.js +735 -81
- package/server/web-chat/core/futureEventGuard.js +5 -1
- package/server/web-chat/core/musicControlAction.js +70 -0
- package/server/web-chat/core/security.js +32 -21
- package/server/web-chat/core/toolInspector.js +6 -6
- package/server/web-chat/core/urlGuard.js +45 -0
- package/server/web-chat/router.js +204 -157
- package/server/web-chat/routes/chatRoute.js +885 -488
- package/server/web-chat/routes/engineRoute.js +270 -0
- package/server/web-chat/routes/exportRoute.js +1 -1
- package/server/web-chat/routes/lanDiscoveryRoute.js +17 -2
- package/server/web-chat/routes/lmStudioLoadRoute.js +172 -0
- package/server/web-chat/routes/mcpRoute.js +386 -0
- package/server/web-chat/routes/memoryRoute.js +253 -0
- package/server/web-chat/routes/providerRoute.js +49 -16
- package/server/web-chat/routes/staticRoute.js +306 -17
- package/server/web-chat/routes/statusRoute.js +194 -73
- package/server/web-chat/routes/suggestRoute.js +11 -3
- package/server/web-chat/routes/verifyRoute.js +26 -4
- package/server/web-chat/server.js +7 -6
- package/server/web-chat/ui/docsBuilder.js +3558 -0
- package/server/web-chat/ui/htmlBuilder.js +12 -0
- package/server/web-chat/ui/scripts/client.js +3401 -1302
- package/server/web-chat/ui/scripts/webchatI18n.js +155 -153
- package/server/web-chat/ui/settingsBuilder.js +7870 -0
- package/server/web-chat/ui/styles/lan-card.css +165 -0
- package/server/web-chat/ui/styles/main.css +4289 -447
- package/server/web-chat/ui/sw.js +64 -0
- package/server/web-chat/ui/templates/body.html +407 -281
- package/src/data/awardsData.js +146 -146
- package/src/data/musicVideoData.js +6 -4
- package/src/lib/vram/estimator.js +195 -19
|
@@ -80,8 +80,69 @@ export function sanitizeToolArguments(toolName, rawArgs = {}, toolsSchema = [])
|
|
|
80
80
|
return cleanArgs;
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
+
export const TOOL_NAME_ALIASES = Object.freeze({
|
|
84
|
+
websearch: 'web_search',
|
|
85
|
+
searchweb: 'web_search',
|
|
86
|
+
search_web: 'web_search',
|
|
87
|
+
google_search: 'web_search',
|
|
88
|
+
bing_search: 'web_search',
|
|
89
|
+
webimages: 'search_web_images',
|
|
90
|
+
web_images: 'search_web_images',
|
|
91
|
+
search_images: 'search_web_images',
|
|
92
|
+
search_image: 'search_web_images',
|
|
93
|
+
image_search: 'search_web_images',
|
|
94
|
+
works: 'search_works',
|
|
95
|
+
search_works: 'search_works',
|
|
96
|
+
dramas: 'search_works',
|
|
97
|
+
get_works: 'search_works',
|
|
98
|
+
songs: 'search_discography',
|
|
99
|
+
discography: 'search_discography',
|
|
100
|
+
search_discography: 'search_discography',
|
|
101
|
+
brands: 'get_brand_endorsements',
|
|
102
|
+
get_brand_endorsements: 'get_brand_endorsements',
|
|
103
|
+
news: 'search_news',
|
|
104
|
+
search_news: 'search_news',
|
|
105
|
+
timeline: 'get_career_timeline',
|
|
106
|
+
get_timeline: 'get_career_timeline',
|
|
107
|
+
awards: 'get_awards',
|
|
108
|
+
get_awards: 'get_awards',
|
|
109
|
+
profile: 'get_artist_profile',
|
|
110
|
+
get_profile: 'get_artist_profile',
|
|
111
|
+
gallery: 'get_gallery_photos',
|
|
112
|
+
get_photos: 'get_gallery_photos',
|
|
113
|
+
photos: 'get_gallery_photos',
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
export function resolveCanonicalToolName(rawName) {
|
|
117
|
+
if (!rawName) return null;
|
|
118
|
+
const cleaned = String(rawName).trim().replace(/^call:/i, '').toLowerCase();
|
|
119
|
+
return TOOL_NAME_ALIASES[cleaned] || String(rawName).trim().replace(/^call:/i, '');
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export function parseCustomToolArgs(rawArgs) {
|
|
123
|
+
if (!rawArgs) return {};
|
|
124
|
+
let clean = String(rawArgs).replace(/<\|["']\|>/g, '"').trim();
|
|
125
|
+
if (clean.startsWith('{') && clean.endsWith('}')) {
|
|
126
|
+
try {
|
|
127
|
+
const parsed = JSON.parse(clean);
|
|
128
|
+
if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) return parsed;
|
|
129
|
+
} catch {}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const args = {};
|
|
133
|
+
const kvRegex = /([a-zA-Z0-9_]+)\s*:\s*(?:"([^"]*)"|'([^']*)'|([^,}\s]+))/g;
|
|
134
|
+
for (const m of clean.matchAll(kvRegex)) {
|
|
135
|
+
let key = m[1].trim();
|
|
136
|
+
if (key === 'targetlanguage') key = 'target_language';
|
|
137
|
+
if (key === 'domainfilter') key = 'domain_filter';
|
|
138
|
+
const val = m[2] !== undefined ? m[2] : (m[3] !== undefined ? m[3] : m[4]);
|
|
139
|
+
args[key] = val;
|
|
140
|
+
}
|
|
141
|
+
return args;
|
|
142
|
+
}
|
|
143
|
+
|
|
83
144
|
/**
|
|
84
|
-
* Parse text-emitted tool calls (fenced JSON
|
|
145
|
+
* Parse text-emitted tool calls (fenced JSON, ReAct "Action:" blocks, or [TOOLCALL] tags).
|
|
85
146
|
* Returns { calls, malformed } — malformed counts blocks that LOOK like tool
|
|
86
147
|
* calls but could not be parsed, so the caller can feed that back to the model
|
|
87
148
|
* instead of silently treating the message as the final answer.
|
|
@@ -92,63 +153,124 @@ export function parseTextToolCallsFromContent(content, toolsSchema) {
|
|
|
92
153
|
const allTools = toolsSchema || [];
|
|
93
154
|
const isValidTool = (name) => allTools.some(t => t.function?.name === name);
|
|
94
155
|
|
|
95
|
-
const pushCall = (prefix,
|
|
96
|
-
const
|
|
156
|
+
const pushCall = (prefix, rawToolName, args) => {
|
|
157
|
+
const canonicalName = resolveCanonicalToolName(rawToolName);
|
|
158
|
+
if (!canonicalName || !isValidTool(canonicalName)) return false;
|
|
159
|
+
const cleanArgs = sanitizeToolArguments(canonicalName, args, allTools);
|
|
97
160
|
result.calls.push({
|
|
98
161
|
id: `${prefix}_${Date.now()}_${result.calls.length}`,
|
|
99
|
-
function: { name:
|
|
162
|
+
function: { name: canonicalName, arguments: JSON.stringify(cleanArgs) }
|
|
100
163
|
});
|
|
164
|
+
return true;
|
|
101
165
|
};
|
|
102
166
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
167
|
+
// 1. [TOOLCALL] or <tool_call> with toolName{...}
|
|
168
|
+
const inlineToolCallRegex = /(?:\[TOOLCALL\]|<tool_call>|<toolcall>|<\|tool_call\|>)\s*(?:call:)?([a-zA-Z0-9_]+)\s*\{([\s\S]*?)\}\s*(?:<toolcall\|?>|<\/tool_call>|<\/toolcall>|\[\/TOOLCALL\]|$)/gi;
|
|
169
|
+
for (const match of content.matchAll(inlineToolCallRegex)) {
|
|
170
|
+
const toolName = match[1];
|
|
171
|
+
const args = parseCustomToolArgs(match[2]);
|
|
172
|
+
pushCall('call_tc', toolName, args);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// 2. <tool_call> or [TOOLCALL] containing JSON object
|
|
176
|
+
if (result.calls.length === 0) {
|
|
177
|
+
const tagJsonRegex = /(?:<tool_call>|\[TOOLCALL\]|<\|tool_call\|>)\s*(\{[\s\S]*?\})\s*(?:<\/tool_call>|<toolcall\|?>|\[\/TOOLCALL\]|$)/gi;
|
|
178
|
+
for (const match of content.matchAll(tagJsonRegex)) {
|
|
111
179
|
try {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
180
|
+
const obj = JSON.parse(match[1].replace(/<\|["']\|>/g, '"'));
|
|
181
|
+
const toolName = obj.name || obj.action || obj.tool || obj.function;
|
|
182
|
+
let args = obj.arguments || obj.parameters || obj.action_input || obj.args || {};
|
|
183
|
+
if (typeof args === 'string') {
|
|
184
|
+
try { args = JSON.parse(args); } catch {}
|
|
185
|
+
}
|
|
186
|
+
if (toolName) pushCall('call_tag_json', toolName, args);
|
|
187
|
+
} catch {}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// 3. [TOOL_CALLS] array format
|
|
192
|
+
if (result.calls.length === 0) {
|
|
193
|
+
const arrayRegex = /\[TOOL_CALLS\]\s*(\[[\s\S]*?\])/gi;
|
|
194
|
+
for (const match of content.matchAll(arrayRegex)) {
|
|
195
|
+
try {
|
|
196
|
+
const arr = JSON.parse(match[1].replace(/<\|["']\|>/g, '"'));
|
|
197
|
+
if (Array.isArray(arr)) {
|
|
198
|
+
for (const item of arr) {
|
|
199
|
+
const toolName = item.name || item.function?.name || item.action;
|
|
200
|
+
let args = item.arguments || item.parameters || item.function?.arguments || {};
|
|
201
|
+
if (typeof args === 'string') {
|
|
202
|
+
try { args = JSON.parse(args); } catch {}
|
|
203
|
+
}
|
|
204
|
+
if (toolName) pushCall('call_arr', toolName, args);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
} catch {}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// 4. Standalone tool_name{...}<toolcall|>
|
|
212
|
+
if (result.calls.length === 0) {
|
|
213
|
+
const standaloneRegex = /(?:^|\n)(?:call:)?([a-zA-Z0-9_]+)\s*\{([\s\S]*?)\}\s*<toolcall\|?>/gi;
|
|
214
|
+
for (const match of content.matchAll(standaloneRegex)) {
|
|
215
|
+
const toolName = match[1];
|
|
216
|
+
const args = parseCustomToolArgs(match[2]);
|
|
217
|
+
pushCall('call_standalone', toolName, args);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// 5. Fenced JSON: ```json ... ```
|
|
222
|
+
if (result.calls.length === 0) {
|
|
223
|
+
const fenceRegex = /```(?:json)?\s*([\s\S]*?)```/g;
|
|
224
|
+
for (const match of content.matchAll(fenceRegex)) {
|
|
225
|
+
const body = match[1];
|
|
226
|
+
if (!body.includes('{')) continue;
|
|
227
|
+
const { objects, unbalanced } = extractTopLevelJsonObjects(body);
|
|
228
|
+
if (unbalanced) result.malformed++;
|
|
229
|
+
for (const obj of objects) {
|
|
230
|
+
let parsed = null;
|
|
231
|
+
try {
|
|
232
|
+
parsed = JSON.parse(obj.raw);
|
|
233
|
+
} catch {
|
|
234
|
+
parsed = null;
|
|
235
|
+
}
|
|
236
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
237
|
+
result.malformed++;
|
|
238
|
+
continue;
|
|
239
|
+
}
|
|
240
|
+
const toolName = parsed.action || parsed.tool || parsed.name || parsed.function;
|
|
241
|
+
if (!toolName) continue;
|
|
242
|
+
let toolArgs = parsed.action_input ?? parsed.parameters ?? parsed.arguments ?? parsed.args ?? {};
|
|
243
|
+
if (toolArgs && typeof toolArgs === 'string') {
|
|
244
|
+
try { toolArgs = JSON.parse(toolArgs); } catch { toolArgs = { query: toolArgs }; }
|
|
245
|
+
}
|
|
246
|
+
if (!toolArgs || typeof toolArgs !== 'object' || Array.isArray(toolArgs)) toolArgs = {};
|
|
128
247
|
pushCall('call_txt', String(toolName), toolArgs);
|
|
129
248
|
}
|
|
130
249
|
}
|
|
131
250
|
}
|
|
132
251
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
const
|
|
136
|
-
const
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
252
|
+
// 6. Action: ... \n Action Input: ...
|
|
253
|
+
if (result.calls.length === 0) {
|
|
254
|
+
const actionRegex = /Action:\s*([a-zA-Z0-9_]+)\s*\nAction Input:\s*([\s\S]*?)(?=\nAction:|\nObservation:|$)/g;
|
|
255
|
+
for (const match of content.matchAll(actionRegex)) {
|
|
256
|
+
const toolName = match[1].trim();
|
|
257
|
+
const rawInput = match[2].trim();
|
|
258
|
+
if (!isValidTool(resolveCanonicalToolName(toolName))) continue;
|
|
259
|
+
if (rawInput.startsWith('{')) {
|
|
260
|
+
const { objects, unbalanced } = extractTopLevelJsonObjects(rawInput);
|
|
261
|
+
const candidate = objects.length > 0 ? objects[0].raw : unbalanced;
|
|
262
|
+
let parsed = null;
|
|
263
|
+
if (candidate) {
|
|
264
|
+
try { parsed = JSON.parse(candidate); } catch { parsed = null; }
|
|
265
|
+
}
|
|
266
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
267
|
+
result.malformed++;
|
|
268
|
+
continue;
|
|
269
|
+
}
|
|
270
|
+
pushCall('call_act', toolName, parsed);
|
|
271
|
+
} else {
|
|
272
|
+
pushCall('call_act', toolName, { query: rawInput });
|
|
148
273
|
}
|
|
149
|
-
pushCall('call_act', toolName, parsed);
|
|
150
|
-
} else {
|
|
151
|
-
pushCall('call_act', toolName, { query: rawInput });
|
|
152
274
|
}
|
|
153
275
|
}
|
|
154
276
|
|
|
@@ -186,5 +308,10 @@ export function stripToolCallBlocks(content) {
|
|
|
186
308
|
let cleaned = String(content || '');
|
|
187
309
|
cleaned = cleaned.replace(/```(?:json)?\s*[\s\S]*?```/g, '');
|
|
188
310
|
cleaned = cleaned.replace(/Action:\s*[a-zA-Z0-9_]+\s*\nAction Input:[\s\S]*?(?=\nAction:|\nObservation:|$)/g, '');
|
|
311
|
+
cleaned = cleaned.replace(/(?:\[TOOLCALL\]|<tool_call>|<toolcall>|<\|tool_call\|>)\s*(?:call:)?[a-zA-Z0-9_]+\s*\{[\s\S]*?\}\s*(?:<toolcall\|?>|<\/tool_call>|<\/toolcall>|\[\/TOOLCALL\]|$)/gi, '');
|
|
312
|
+
cleaned = cleaned.replace(/(?:<tool_call>|\[TOOLCALL\]|<\|tool_call\|>)\s*\{[\s\S]*?\}\s*(?:<\/tool_call>|<toolcall\|?>|\[\/TOOLCALL\]|$)/gi, '');
|
|
313
|
+
cleaned = cleaned.replace(/\[TOOL_CALLS\]\s*\[[\s\S]*?\]/gi, '');
|
|
314
|
+
cleaned = cleaned.replace(/(?:^|\n)(?:call:)?[a-zA-Z0-9_]+\s*\{[\s\S]*?\}\s*<toolcall\|?>/gi, '');
|
|
315
|
+
cleaned = cleaned.replace(/<\|?toolcall\|?>|<\/?tool_call>|<\/?toolcall>|\[\/?TOOLCALL\]|\[TOOL_CALLS\]|<\|["']\|>/gi, '');
|
|
189
316
|
return cleaned.trim();
|
|
190
317
|
}
|