@jsonstudio/llms 0.6.1892 → 0.6.2172
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/conversion/compat/actions/deepseek-web-request.js +16 -2
- package/dist/conversion/compat/actions/deepseek-web-response.d.ts +7 -1
- package/dist/conversion/compat/actions/deepseek-web-response.js +302 -40
- package/dist/conversion/compat/actions/harvest-tool-calls-from-text.d.ts +5 -0
- package/dist/conversion/compat/actions/harvest-tool-calls-from-text.js +7 -4
- package/dist/conversion/compat/actions/iflow-tool-text-fallback.d.ts +1 -0
- package/dist/conversion/compat/actions/iflow-tool-text-fallback.js +12 -0
- package/dist/conversion/compat/actions/strip-orphan-function-calls-tag.js +1 -1
- package/dist/conversion/compat/actions/tool-text-request-guidance.d.ts +9 -0
- package/dist/conversion/compat/actions/tool-text-request-guidance.js +177 -0
- package/dist/conversion/compat/antigravity-session-signature.d.ts +6 -0
- package/dist/conversion/compat/antigravity-session-signature.js +15 -0
- package/dist/conversion/compat/profiles/chat-deepseek-web.json +52 -1
- package/dist/conversion/compat/profiles/chat-glm.json +22 -0
- package/dist/conversion/compat/profiles/chat-iflow.json +4 -0
- package/dist/conversion/hub/operation-table/semantic-mappers/gemini-mapper.js +13 -27
- package/dist/conversion/hub/operation-table/semantic-mappers/responses-mapper.js +10 -1
- package/dist/conversion/hub/pipeline/compat/compat-pipeline-executor.js +13 -4
- package/dist/conversion/hub/pipeline/compat/compat-profile-resolver.js +1 -53
- package/dist/conversion/hub/pipeline/compat/compat-types.d.ts +8 -0
- package/dist/conversion/hub/pipeline/hub-pipeline.js +8 -4
- package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage3_context_capture/index.js +191 -9
- package/dist/conversion/hub/pipeline/stages/resp_inbound/resp_inbound_stage1_sse_decode/index.js +118 -15
- package/dist/conversion/hub/pipeline/stages/resp_process/resp_process_stage1_tool_governance/index.js +65 -2
- package/dist/conversion/hub/pipeline/stages/resp_process/resp_process_stage3_servertool_orchestration/index.d.ts +34 -0
- package/dist/conversion/hub/pipeline/stages/resp_process/resp_process_stage3_servertool_orchestration/index.js +75 -0
- package/dist/conversion/hub/process/chat-process.js +85 -18
- package/dist/conversion/hub/response/provider-response.js +21 -50
- package/dist/conversion/hub/response/response-runtime.js +71 -10
- package/dist/conversion/responses/responses-openai-bridge/response-payload.d.ts +3 -0
- package/dist/conversion/responses/responses-openai-bridge/response-payload.js +576 -0
- package/dist/conversion/responses/responses-openai-bridge/types.d.ts +42 -0
- package/dist/conversion/responses/responses-openai-bridge/types.js +1 -0
- package/dist/conversion/responses/responses-openai-bridge.d.ts +3 -44
- package/dist/conversion/responses/responses-openai-bridge.js +193 -504
- package/dist/conversion/shared/anthropic-message-utils.js +82 -2
- package/dist/conversion/shared/bridge-message-utils.js +92 -39
- package/dist/conversion/shared/snapshot-hooks.js +8 -13
- package/dist/conversion/shared/text-markup-normalizer/extractors-apply-patch.d.ts +2 -0
- package/dist/conversion/shared/text-markup-normalizer/extractors-apply-patch.js +129 -0
- package/dist/conversion/shared/text-markup-normalizer/extractors-json.d.ts +4 -0
- package/dist/conversion/shared/text-markup-normalizer/extractors-json.js +637 -0
- package/dist/conversion/shared/text-markup-normalizer/extractors-shared.d.ts +21 -0
- package/dist/conversion/shared/text-markup-normalizer/extractors-shared.js +177 -0
- package/dist/conversion/shared/text-markup-normalizer/extractors-transcript.d.ts +5 -0
- package/dist/conversion/shared/text-markup-normalizer/extractors-transcript.js +385 -0
- package/dist/conversion/shared/text-markup-normalizer/extractors-xml.d.ts +10 -0
- package/dist/conversion/shared/text-markup-normalizer/extractors-xml.js +602 -0
- package/dist/conversion/shared/text-markup-normalizer/extractors.d.ts +5 -0
- package/dist/conversion/shared/text-markup-normalizer/extractors.js +4 -0
- package/dist/conversion/shared/text-markup-normalizer/normalize.d.ts +2 -0
- package/dist/conversion/shared/text-markup-normalizer/normalize.js +76 -0
- package/dist/conversion/shared/text-markup-normalizer.d.ts +3 -25
- package/dist/conversion/shared/text-markup-normalizer.js +2 -1386
- package/dist/conversion/shared/tool-governor.js +136 -10
- package/dist/filters/utils/snapshot-writer.js +3 -3
- package/dist/router/virtual-router/bootstrap/auth-utils.d.ts +6 -0
- package/dist/router/virtual-router/bootstrap/auth-utils.js +288 -0
- package/dist/router/virtual-router/bootstrap/claude-code-helpers.d.ts +11 -0
- package/dist/router/virtual-router/bootstrap/claude-code-helpers.js +18 -0
- package/dist/router/virtual-router/bootstrap/config-defaults.d.ts +5 -0
- package/dist/router/virtual-router/bootstrap/config-defaults.js +13 -0
- package/dist/router/virtual-router/bootstrap/config-normalizers.d.ts +4 -0
- package/dist/router/virtual-router/bootstrap/config-normalizers.js +106 -0
- package/dist/router/virtual-router/bootstrap/profile-builder.d.ts +7 -0
- package/dist/router/virtual-router/bootstrap/profile-builder.js +68 -0
- package/dist/router/virtual-router/bootstrap/provider-normalization.d.ts +40 -0
- package/dist/router/virtual-router/bootstrap/provider-normalization.js +212 -0
- package/dist/router/virtual-router/bootstrap/responses-helpers.d.ts +15 -0
- package/dist/router/virtual-router/bootstrap/responses-helpers.js +65 -0
- package/dist/router/virtual-router/bootstrap/routing-config.d.ts +23 -0
- package/dist/router/virtual-router/bootstrap/routing-config.js +293 -0
- package/dist/router/virtual-router/bootstrap/streaming-helpers.d.ts +12 -0
- package/dist/router/virtual-router/bootstrap/streaming-helpers.js +128 -0
- package/dist/router/virtual-router/bootstrap/utils.d.ts +5 -0
- package/dist/router/virtual-router/bootstrap/utils.js +41 -0
- package/dist/router/virtual-router/bootstrap/web-search-config.d.ts +4 -0
- package/dist/router/virtual-router/bootstrap/web-search-config.js +131 -0
- package/dist/router/virtual-router/bootstrap.d.ts +0 -4
- package/dist/router/virtual-router/bootstrap.js +31 -1275
- package/dist/router/virtual-router/classifier.js +32 -14
- package/dist/router/virtual-router/engine/antigravity/alias-lease.js +2 -2
- package/dist/router/virtual-router/engine/cooldown-manager.d.ts +34 -0
- package/dist/router/virtual-router/engine/cooldown-manager.js +118 -0
- package/dist/router/virtual-router/engine/route-analytics.d.ts +28 -0
- package/dist/router/virtual-router/engine/route-analytics.js +44 -0
- package/dist/router/virtual-router/engine/routing-pools/index.js +165 -4
- package/dist/router/virtual-router/engine/sticky-session-manager.d.ts +29 -0
- package/dist/router/virtual-router/engine/sticky-session-manager.js +55 -0
- package/dist/router/virtual-router/engine-logging.d.ts +42 -1
- package/dist/router/virtual-router/engine-logging.js +82 -15
- package/dist/router/virtual-router/engine-selection/multimodal-capability.d.ts +3 -0
- package/dist/router/virtual-router/engine-selection/multimodal-capability.js +26 -0
- package/dist/router/virtual-router/engine-selection/route-utils.js +6 -2
- package/dist/router/virtual-router/engine-selection/selection-deps.d.ts +1 -0
- package/dist/router/virtual-router/engine-selection/tier-selection.js +31 -1
- package/dist/router/virtual-router/engine.d.ts +21 -7
- package/dist/router/virtual-router/engine.js +198 -194
- package/dist/router/virtual-router/features.js +12 -4
- package/dist/router/virtual-router/message-utils.d.ts +8 -0
- package/dist/router/virtual-router/message-utils.js +170 -45
- package/dist/router/virtual-router/pre-command-file-resolver.js +40 -2
- package/dist/router/virtual-router/routing-instructions.d.ts +8 -0
- package/dist/router/virtual-router/routing-instructions.js +18 -2
- package/dist/router/virtual-router/routing-stop-message-actions.js +34 -10
- package/dist/router/virtual-router/routing-stop-message-state-codec.d.ts +2 -0
- package/dist/router/virtual-router/routing-stop-message-state-codec.js +50 -1
- package/dist/router/virtual-router/stop-message-state-sync.d.ts +1 -1
- package/dist/router/virtual-router/stop-message-state-sync.js +3 -0
- package/dist/router/virtual-router/token-counter.js +51 -10
- package/dist/router/virtual-router/tool-signals.js +4 -0
- package/dist/router/virtual-router/types.d.ts +15 -0
- package/dist/servertool/clock/session-scope.d.ts +3 -0
- package/dist/servertool/clock/session-scope.js +52 -0
- package/dist/servertool/clock/state.js +9 -0
- package/dist/servertool/clock/tasks.js +12 -1
- package/dist/servertool/clock/types.d.ts +3 -0
- package/dist/servertool/engine.js +177 -31
- package/dist/servertool/handlers/clock-auto.js +2 -8
- package/dist/servertool/handlers/clock.js +6 -9
- package/dist/servertool/handlers/recursive-detection-guard.js +53 -14
- package/dist/servertool/handlers/stop-message-auto/blocked-report.d.ts +16 -0
- package/dist/servertool/handlers/stop-message-auto/blocked-report.js +349 -0
- package/dist/servertool/handlers/stop-message-auto/iflow-followup.d.ts +23 -0
- package/dist/servertool/handlers/stop-message-auto/iflow-followup.js +503 -0
- package/dist/servertool/handlers/stop-message-auto/routing-state.d.ts +38 -0
- package/dist/servertool/handlers/stop-message-auto/routing-state.js +149 -0
- package/dist/servertool/handlers/stop-message-auto/runtime-utils.d.ts +67 -0
- package/dist/servertool/handlers/stop-message-auto/runtime-utils.js +387 -0
- package/dist/servertool/handlers/stop-message-auto.d.ts +1 -1
- package/dist/servertool/handlers/stop-message-auto.js +80 -556
- package/dist/servertool/handlers/stop-message-stage-policy/bd-runtime.d.ts +18 -0
- package/dist/servertool/handlers/stop-message-stage-policy/bd-runtime.js +398 -0
- package/dist/servertool/handlers/stop-message-stage-policy/decision.d.ts +9 -0
- package/dist/servertool/handlers/stop-message-stage-policy/decision.js +127 -0
- package/dist/servertool/handlers/stop-message-stage-policy/observation.d.ts +2 -0
- package/dist/servertool/handlers/stop-message-stage-policy/observation.js +179 -0
- package/dist/servertool/handlers/stop-message-stage-policy/templates.d.ts +4 -0
- package/dist/servertool/handlers/stop-message-stage-policy/templates.js +96 -0
- package/dist/servertool/handlers/stop-message-stage-policy/text-utils.d.ts +9 -0
- package/dist/servertool/handlers/stop-message-stage-policy/text-utils.js +89 -0
- package/dist/servertool/handlers/stop-message-stage-policy/types.d.ts +59 -0
- package/dist/servertool/handlers/stop-message-stage-policy/types.js +1 -0
- package/dist/servertool/handlers/stop-message-stage-policy.d.ts +3 -43
- package/dist/servertool/handlers/stop-message-stage-policy.js +2 -684
- package/dist/servertool/handlers/web-search.js +117 -0
- package/dist/servertool/server-side-tools.d.ts +0 -1
- package/dist/servertool/server-side-tools.js +4 -3
- package/dist/sse/sse-to-json/builders/response-builder.js +16 -0
- package/dist/sse/sse-to-json/chat-sse-to-json-converter.d.ts +1 -0
- package/dist/sse/sse-to-json/chat-sse-to-json-converter.js +110 -37
- package/dist/telemetry/stats-center.d.ts +9 -0
- package/dist/telemetry/stats-center.js +29 -1
- package/dist/tools/apply-patch/structured/coercion.js +3 -11
- package/dist/tools/exec-command/validator.d.ts +1 -0
- package/dist/tools/exec-command/validator.js +132 -0
- package/dist/tools/tool-registry.d.ts +1 -0
- package/dist/tools/tool-registry.js +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,602 @@
|
|
|
1
|
+
import { isImagePath } from '../media.js';
|
|
2
|
+
import { KNOWN_TOOLS, coerceCommandValueToString, filterArgsForTool, genToolCallId, normalizeKey, readDefaultWorkdirFromEnv, tryParseJsonValue, tryParsePrimitiveValue } from './extractors-shared.js';
|
|
3
|
+
function applyToolInnerField(lname, argsObj, rawKey, rawValInput) {
|
|
4
|
+
const key = normalizeKey(rawKey).toLowerCase();
|
|
5
|
+
if (!key || key === 'requires_approval') {
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
const rawVal = String(rawValInput ?? '');
|
|
9
|
+
const value = tryParsePrimitiveValue(rawVal);
|
|
10
|
+
if (lname === 'exec_command' && (key === 'command' || key === 'cmd')) {
|
|
11
|
+
const cmd = coerceCommandValueToString(value);
|
|
12
|
+
if (cmd.trim().length) {
|
|
13
|
+
argsObj.cmd = cmd;
|
|
14
|
+
argsObj.command = cmd;
|
|
15
|
+
}
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
if (lname === 'exec_command' && (key === 'cwd' || key === 'workdir')) {
|
|
19
|
+
const wd = String(value ?? rawVal).trim();
|
|
20
|
+
if (wd)
|
|
21
|
+
argsObj.workdir = wd;
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
if (lname === 'write_stdin') {
|
|
25
|
+
if (key === 'input' || key === 'data' || key === 'chars' || key === 'text') {
|
|
26
|
+
argsObj.chars = rawVal;
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
if (key === 'session_id') {
|
|
30
|
+
const n = Number.parseInt(String(value), 10);
|
|
31
|
+
argsObj.session_id = Number.isFinite(n) ? n : value;
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
if (lname === 'apply_patch' && (key === 'patch' || key === 'input' || key === 'text' || key === 'instructions')) {
|
|
36
|
+
const patchText = typeof value === 'string' ? value : rawVal;
|
|
37
|
+
if (typeof patchText === 'string' && patchText.trim().length) {
|
|
38
|
+
argsObj.patch = patchText;
|
|
39
|
+
}
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
argsObj[key] = value;
|
|
43
|
+
}
|
|
44
|
+
// Extract <tool:NAME>...</tool:NAME> blocks used by some tool-mode outputs.
|
|
45
|
+
export function extractToolNamespaceXmlBlocksFromText(text) {
|
|
46
|
+
try {
|
|
47
|
+
if (typeof text !== 'string' || !text)
|
|
48
|
+
return null;
|
|
49
|
+
const hasOpenTag = text.includes('<tool:');
|
|
50
|
+
const hasCloseTag = /<\/\s*tool:\s*[A-Za-z0-9_]+\s*>/i.test(text);
|
|
51
|
+
const hasToolPrefix = /(?:^|\n)\s*(?:[•*+-]\s*)?tool:[A-Za-z0-9_]+/i.test(text);
|
|
52
|
+
if (!hasOpenTag && !(hasCloseTag && hasToolPrefix)) {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
const out = [];
|
|
56
|
+
const blockRe = /<\s*tool:([A-Za-z0-9_]+)\s*>([\s\S]*?)<\/\s*tool:\s*\1\s*>/gi;
|
|
57
|
+
let bm;
|
|
58
|
+
while ((bm = blockRe.exec(text)) !== null) {
|
|
59
|
+
const rawName = String(bm[1] || '').trim();
|
|
60
|
+
const lname = rawName.toLowerCase();
|
|
61
|
+
if (!lname || !KNOWN_TOOLS.has(lname))
|
|
62
|
+
continue;
|
|
63
|
+
const inner = String(bm[2] || '');
|
|
64
|
+
const argsObj = {};
|
|
65
|
+
const kvRe = /<\s*([A-Za-z_][A-Za-z0-9_]*)\s*>([\s\S]*?)<\/\s*\1\s*>/g;
|
|
66
|
+
let km;
|
|
67
|
+
while ((km = kvRe.exec(inner)) !== null) {
|
|
68
|
+
const rawKey = String(km[1] || '').trim();
|
|
69
|
+
const rawVal = String(km[2] ?? '');
|
|
70
|
+
applyToolInnerField(lname, argsObj, rawKey, rawVal);
|
|
71
|
+
}
|
|
72
|
+
// Tolerate malformed parameter blocks like:
|
|
73
|
+
// <parameter name="command">...</command>
|
|
74
|
+
// and the normal form:
|
|
75
|
+
// <parameter name="command">...</parameter>
|
|
76
|
+
const paramRe = /<\s*parameter\s+name\s*=\s*"([^">]+)"\s*>([\s\S]*?)<\/\s*(?:parameter|\1)\s*>/gi;
|
|
77
|
+
let pm;
|
|
78
|
+
while ((pm = paramRe.exec(inner)) !== null) {
|
|
79
|
+
const rawKey = String(pm[1] || '').trim();
|
|
80
|
+
const rawVal = String(pm[2] ?? '');
|
|
81
|
+
applyToolInnerField(lname, argsObj, rawKey, rawVal);
|
|
82
|
+
}
|
|
83
|
+
const filtered = filterArgsForTool(lname, argsObj);
|
|
84
|
+
if (lname === 'exec_command') {
|
|
85
|
+
const cmd = typeof filtered?.cmd === 'string' ? String(filtered.cmd).trim() : '';
|
|
86
|
+
if (!cmd)
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
if (lname === 'write_stdin') {
|
|
90
|
+
const sid = filtered?.session_id;
|
|
91
|
+
if (sid === undefined || sid === null || String(sid).trim().length === 0)
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
if (lname === 'apply_patch') {
|
|
95
|
+
const patchText = typeof filtered?.patch === 'string' ? String(filtered.patch).trim() : '';
|
|
96
|
+
if (!patchText)
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
let argsStr = '{}';
|
|
100
|
+
try {
|
|
101
|
+
argsStr = JSON.stringify(filtered);
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
argsStr = '{}';
|
|
105
|
+
}
|
|
106
|
+
out.push({ id: genToolCallId(), name: lname, args: argsStr });
|
|
107
|
+
}
|
|
108
|
+
// Broken variant (seen in the wild):
|
|
109
|
+
// tool:exec_command (tool:exec_command)
|
|
110
|
+
// <command>...</command>
|
|
111
|
+
// </tool:exec_command>
|
|
112
|
+
const prefixBlockRe = /(?:^|\n)\s*(?:[•*+-]\s*)?tool:([A-Za-z0-9_]+)[^\n]*\n([\s\S]*?)<\/\s*tool:\s*\1\s*>/gi;
|
|
113
|
+
let pm;
|
|
114
|
+
while ((pm = prefixBlockRe.exec(text)) !== null) {
|
|
115
|
+
const rawName = String(pm[1] || '').trim();
|
|
116
|
+
const lname = rawName.toLowerCase();
|
|
117
|
+
if (!lname || !KNOWN_TOOLS.has(lname))
|
|
118
|
+
continue;
|
|
119
|
+
const inner = String(pm[2] || '');
|
|
120
|
+
const argsObj = {};
|
|
121
|
+
const kvRe = /<\s*([A-Za-z_][A-Za-z0-9_]*)\s*>([\s\S]*?)<\/\s*\1\s*>/g;
|
|
122
|
+
let km;
|
|
123
|
+
while ((km = kvRe.exec(inner)) !== null) {
|
|
124
|
+
const rawKey = String(km[1] || '').trim();
|
|
125
|
+
const rawVal = String(km[2] ?? '');
|
|
126
|
+
applyToolInnerField(lname, argsObj, rawKey, rawVal);
|
|
127
|
+
}
|
|
128
|
+
const paramRe = /<\s*parameter\s+name\s*=\s*"([^">]+)"\s*>([\s\S]*?)<\/\s*(?:parameter|\1)\s*>/gi;
|
|
129
|
+
let pm2;
|
|
130
|
+
while ((pm2 = paramRe.exec(inner)) !== null) {
|
|
131
|
+
const rawKey = String(pm2[1] || '').trim();
|
|
132
|
+
const rawVal = String(pm2[2] ?? '');
|
|
133
|
+
applyToolInnerField(lname, argsObj, rawKey, rawVal);
|
|
134
|
+
}
|
|
135
|
+
const filtered = filterArgsForTool(lname, argsObj);
|
|
136
|
+
if (lname === 'exec_command') {
|
|
137
|
+
const cmd = typeof filtered?.cmd === 'string' ? String(filtered.cmd).trim() : '';
|
|
138
|
+
if (!cmd)
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
if (lname === 'write_stdin') {
|
|
142
|
+
const sid = filtered?.session_id;
|
|
143
|
+
if (sid === undefined || sid === null || String(sid).trim().length === 0)
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
if (lname === 'apply_patch') {
|
|
147
|
+
const patchText = typeof filtered?.patch === 'string' ? String(filtered.patch).trim() : '';
|
|
148
|
+
if (!patchText)
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
let argsStr = '{}';
|
|
152
|
+
try {
|
|
153
|
+
argsStr = JSON.stringify(filtered);
|
|
154
|
+
}
|
|
155
|
+
catch {
|
|
156
|
+
argsStr = '{}';
|
|
157
|
+
}
|
|
158
|
+
out.push({ id: genToolCallId(), name: lname, args: argsStr });
|
|
159
|
+
}
|
|
160
|
+
return out.length ? out : null;
|
|
161
|
+
}
|
|
162
|
+
catch {
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
// Extract Anthropic/GLM-style XML tool tags that use <parameter name="...">...</parameter>.
|
|
167
|
+
export function extractParameterXmlToolsFromText(text) {
|
|
168
|
+
try {
|
|
169
|
+
if (typeof text !== 'string' || !text)
|
|
170
|
+
return null;
|
|
171
|
+
const out = [];
|
|
172
|
+
// Some providers/models emit mismatched closing tags like </func_call>; accept a small set of known variants.
|
|
173
|
+
const toolRe = /<\s*(exec_command)\s*>([\s\S]*?)<\/\s*(?:\1|func_call|tool_call)\s*>/gi;
|
|
174
|
+
let tm;
|
|
175
|
+
while ((tm = toolRe.exec(text)) !== null) {
|
|
176
|
+
const rawName = (tm[1] || '').trim();
|
|
177
|
+
const inner = (tm[2] || '').trim();
|
|
178
|
+
if (!rawName || !inner)
|
|
179
|
+
continue;
|
|
180
|
+
const lname = rawName.toLowerCase();
|
|
181
|
+
const argsObj = {};
|
|
182
|
+
const paramRe = /<\s*parameter\s+name\s*=\s*"([^"]+)"\s*>([\s\S]*?)<\/\s*parameter\s*>/gi;
|
|
183
|
+
let pm;
|
|
184
|
+
while ((pm = paramRe.exec(inner)) !== null) {
|
|
185
|
+
const rawKey = (pm[1] || '').trim();
|
|
186
|
+
const key = normalizeKey(rawKey);
|
|
187
|
+
if (!key)
|
|
188
|
+
continue;
|
|
189
|
+
const rawVal = (pm[2] || '').trim();
|
|
190
|
+
if (!rawVal)
|
|
191
|
+
continue;
|
|
192
|
+
const parsed = tryParseJsonValue(rawVal);
|
|
193
|
+
if (key.toLowerCase() === 'command' || key.toLowerCase() === 'cmd') {
|
|
194
|
+
const cmd = coerceCommandValueToString(parsed ?? rawVal);
|
|
195
|
+
if (cmd.trim().length) {
|
|
196
|
+
argsObj.cmd = cmd;
|
|
197
|
+
argsObj.command = cmd;
|
|
198
|
+
}
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
if (key.toLowerCase() === 'workdir') {
|
|
202
|
+
argsObj.workdir = rawVal;
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
205
|
+
argsObj[key] = parsed ?? rawVal;
|
|
206
|
+
}
|
|
207
|
+
const filtered = filterArgsForTool(lname, argsObj);
|
|
208
|
+
if (!filtered || typeof filtered !== 'object' || Array.isArray(filtered))
|
|
209
|
+
continue;
|
|
210
|
+
const cmd = typeof filtered.cmd === 'string' ? String(filtered.cmd).trim() : '';
|
|
211
|
+
if (!cmd)
|
|
212
|
+
continue;
|
|
213
|
+
// If caller didn't provide workdir, fallback to a conservative env-derived workdir.
|
|
214
|
+
try {
|
|
215
|
+
if (!filtered.workdir) {
|
|
216
|
+
const envWorkdir = readDefaultWorkdirFromEnv();
|
|
217
|
+
if (envWorkdir)
|
|
218
|
+
filtered.workdir = envWorkdir;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
catch {
|
|
222
|
+
/* ignore */
|
|
223
|
+
}
|
|
224
|
+
let argsStr = '{}';
|
|
225
|
+
try {
|
|
226
|
+
argsStr = JSON.stringify(filtered);
|
|
227
|
+
}
|
|
228
|
+
catch {
|
|
229
|
+
argsStr = '{}';
|
|
230
|
+
}
|
|
231
|
+
out.push({
|
|
232
|
+
id: genToolCallId(),
|
|
233
|
+
name: lname,
|
|
234
|
+
args: argsStr
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
return out.length ? out : null;
|
|
238
|
+
}
|
|
239
|
+
catch {
|
|
240
|
+
return null;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
function applyInvokeParameterAliases(toolName, argsObj) {
|
|
244
|
+
try {
|
|
245
|
+
const lname = String(toolName || '').toLowerCase();
|
|
246
|
+
if (lname === 'write_stdin') {
|
|
247
|
+
// Some models emit `data` / `wait` instead of our canonical `chars` / `yield_time_ms`.
|
|
248
|
+
if (Object.prototype.hasOwnProperty.call(argsObj, 'data')) {
|
|
249
|
+
const data = argsObj.data;
|
|
250
|
+
if (!Object.prototype.hasOwnProperty.call(argsObj, 'chars') && !Object.prototype.hasOwnProperty.call(argsObj, 'text')) {
|
|
251
|
+
argsObj.chars = data == null ? '' : String(data);
|
|
252
|
+
}
|
|
253
|
+
delete argsObj.data;
|
|
254
|
+
}
|
|
255
|
+
if (Object.prototype.hasOwnProperty.call(argsObj, 'wait') && !Object.prototype.hasOwnProperty.call(argsObj, 'yield_time_ms')) {
|
|
256
|
+
const wait = argsObj.wait;
|
|
257
|
+
let ms;
|
|
258
|
+
if (typeof wait === 'number' && Number.isFinite(wait)) {
|
|
259
|
+
// Heuristic: small values are usually seconds; large values are likely already ms.
|
|
260
|
+
ms = wait <= 1000 ? Math.round(wait * 1000) : Math.round(wait);
|
|
261
|
+
}
|
|
262
|
+
else if (typeof wait === 'string' && wait.trim().length) {
|
|
263
|
+
const num = Number(wait.trim());
|
|
264
|
+
if (Number.isFinite(num)) {
|
|
265
|
+
ms = num <= 1000 ? Math.round(num * 1000) : Math.round(num);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
if (typeof ms === 'number' && Number.isFinite(ms) && ms >= 0) {
|
|
269
|
+
argsObj.yield_time_ms = ms;
|
|
270
|
+
}
|
|
271
|
+
delete argsObj.wait;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
catch {
|
|
276
|
+
// ignore
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
// Extract <function_calls><invoke name="...">...</invoke> blocks.
|
|
280
|
+
export function extractInvokeToolsFromText(text) {
|
|
281
|
+
try {
|
|
282
|
+
if (typeof text !== 'string' || !text)
|
|
283
|
+
return null;
|
|
284
|
+
const out = [];
|
|
285
|
+
const invokeRe = /<\s*invoke\s+name\s*=\s*"([^">]+)"\s*>([\s\S]*?)<\/\s*invoke\s*>/gi;
|
|
286
|
+
let im;
|
|
287
|
+
while ((im = invokeRe.exec(text)) !== null) {
|
|
288
|
+
const rawName = (im[1] || '').trim();
|
|
289
|
+
const inner = (im[2] || '').trim();
|
|
290
|
+
if (!rawName || !inner)
|
|
291
|
+
continue;
|
|
292
|
+
const lname = rawName.toLowerCase();
|
|
293
|
+
const argsObj = {};
|
|
294
|
+
const paramRe = /<\s*parameter\s+name\s*=\s*"([^">]+)"\s*>([\s\S]*?)<\/\s*parameter\s*>/gi;
|
|
295
|
+
let pm;
|
|
296
|
+
while ((pm = paramRe.exec(inner)) !== null) {
|
|
297
|
+
const rawKey = (pm[1] || '').trim();
|
|
298
|
+
const key = normalizeKey(rawKey);
|
|
299
|
+
if (!key)
|
|
300
|
+
continue;
|
|
301
|
+
const rawVal = (pm[2] ?? '').toString();
|
|
302
|
+
const value = tryParsePrimitiveValue(rawVal);
|
|
303
|
+
if (lname === 'exec_command' && (key.toLowerCase() === 'command' || key.toLowerCase() === 'cmd')) {
|
|
304
|
+
const cmd = coerceCommandValueToString(value);
|
|
305
|
+
if (cmd.trim().length) {
|
|
306
|
+
argsObj.cmd = cmd;
|
|
307
|
+
argsObj.command = cmd;
|
|
308
|
+
}
|
|
309
|
+
continue;
|
|
310
|
+
}
|
|
311
|
+
argsObj[key] = value;
|
|
312
|
+
}
|
|
313
|
+
applyInvokeParameterAliases(lname, argsObj);
|
|
314
|
+
const filtered = filterArgsForTool(lname, argsObj);
|
|
315
|
+
let argsStr = '{}';
|
|
316
|
+
try {
|
|
317
|
+
argsStr = JSON.stringify(filtered);
|
|
318
|
+
}
|
|
319
|
+
catch {
|
|
320
|
+
argsStr = '{}';
|
|
321
|
+
}
|
|
322
|
+
out.push({ id: genToolCallId(), name: lname, args: argsStr });
|
|
323
|
+
}
|
|
324
|
+
// Some Gemini CLI / antigravity variants emit a looser XML shape.
|
|
325
|
+
if (out.length === 0) {
|
|
326
|
+
const invokeBareRe = /<\s*invoke\s*>([\s\S]*?)<\/\s*invoke\s*>/gi;
|
|
327
|
+
let bm;
|
|
328
|
+
while ((bm = invokeBareRe.exec(text)) !== null) {
|
|
329
|
+
const inner = (bm[1] || '').trim();
|
|
330
|
+
if (!inner)
|
|
331
|
+
continue;
|
|
332
|
+
const toolNameMatch = /<\s*(?:tool_name|toolname|tool)\s*>\s*([\s\S]*?)\s*<\/\s*(?:tool_name|toolname|tool)\s*>/i.exec(inner);
|
|
333
|
+
const rawName = (toolNameMatch?.[1] || '').trim();
|
|
334
|
+
if (!rawName)
|
|
335
|
+
continue;
|
|
336
|
+
const lname = rawName.toLowerCase();
|
|
337
|
+
if (!KNOWN_TOOLS.has(lname))
|
|
338
|
+
continue;
|
|
339
|
+
const argsObj = {};
|
|
340
|
+
const paramsMatch = /<\s*parameters\s*>([\s\S]*?)<\/\s*parameters\s*>/i.exec(inner);
|
|
341
|
+
if (paramsMatch && paramsMatch[1]) {
|
|
342
|
+
const paramsInner = String(paramsMatch[1] || '');
|
|
343
|
+
const kvRe = /<\s*([A-Za-z_][A-Za-z0-9_]*)\s*>([\s\S]*?)<\/\s*\1\s*>/g;
|
|
344
|
+
let km;
|
|
345
|
+
while ((km = kvRe.exec(paramsInner)) !== null) {
|
|
346
|
+
const rawKey = (km[1] || '').trim();
|
|
347
|
+
const key = normalizeKey(rawKey);
|
|
348
|
+
if (!key)
|
|
349
|
+
continue;
|
|
350
|
+
const rawVal = (km[2] ?? '').toString();
|
|
351
|
+
const value = tryParsePrimitiveValue(rawVal);
|
|
352
|
+
if (lname === 'exec_command' && (key.toLowerCase() === 'command' || key.toLowerCase() === 'cmd')) {
|
|
353
|
+
const cmd = coerceCommandValueToString(value);
|
|
354
|
+
if (cmd.trim().length) {
|
|
355
|
+
argsObj.cmd = cmd;
|
|
356
|
+
argsObj.command = cmd;
|
|
357
|
+
}
|
|
358
|
+
continue;
|
|
359
|
+
}
|
|
360
|
+
argsObj[key] = value;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
applyInvokeParameterAliases(lname, argsObj);
|
|
364
|
+
const filtered = filterArgsForTool(lname, argsObj);
|
|
365
|
+
let argsStr = '{}';
|
|
366
|
+
try {
|
|
367
|
+
argsStr = JSON.stringify(filtered);
|
|
368
|
+
}
|
|
369
|
+
catch {
|
|
370
|
+
argsStr = '{}';
|
|
371
|
+
}
|
|
372
|
+
out.push({ id: genToolCallId(), name: lname, args: argsStr });
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
return out.length ? out : null;
|
|
376
|
+
}
|
|
377
|
+
catch {
|
|
378
|
+
return null;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
// Extract XML-like <tool_call> blocks used by some agents.
|
|
382
|
+
export function extractXMLToolCallsFromText(text) {
|
|
383
|
+
try {
|
|
384
|
+
if (typeof text !== 'string' || !text)
|
|
385
|
+
return null;
|
|
386
|
+
const out = [];
|
|
387
|
+
const blockRe = /<tool_call[\s\S]*?>([\s\S]*?)<\/tool_call>/gi;
|
|
388
|
+
let bm;
|
|
389
|
+
while ((bm = blockRe.exec(text)) !== null) {
|
|
390
|
+
const inner = (bm[1] || '').trim();
|
|
391
|
+
if (!inner)
|
|
392
|
+
continue;
|
|
393
|
+
// 1) try function/name tags
|
|
394
|
+
let name = '';
|
|
395
|
+
const fnTag = inner.match(/<\s*(?:function|name)\s*>\s*([a-zA-Z0-9_.-]+)\s*<\/(?:function|name)\s*>/i);
|
|
396
|
+
if (fnTag && fnTag[1]) {
|
|
397
|
+
name = String(fnTag[1]).trim();
|
|
398
|
+
}
|
|
399
|
+
else {
|
|
400
|
+
// 2) else pick the first non-empty line without tags as the name
|
|
401
|
+
const lines = inner.split(/\r?\n/).map((s) => s.trim()).filter(Boolean);
|
|
402
|
+
const candidate = lines.find((l) => !l.startsWith('<') && /^[a-zA-Z0-9_.-]+$/.test(l));
|
|
403
|
+
if (candidate)
|
|
404
|
+
name = candidate;
|
|
405
|
+
}
|
|
406
|
+
if (!name)
|
|
407
|
+
continue;
|
|
408
|
+
const lname = String(name).toLowerCase();
|
|
409
|
+
// Collect arg_key/arg_value pairs
|
|
410
|
+
const argRe = /<\s*arg_key\s*>\s*([^<]+?)\s*<\/(?:arg_key)\s*>\s*<\s*arg_value\s*>\s*([\s\S]*?)\s*<\/(?:arg_value)\s*>/gi;
|
|
411
|
+
let am;
|
|
412
|
+
const argsObj = {};
|
|
413
|
+
while ((am = argRe.exec(inner)) !== null) {
|
|
414
|
+
const k = normalizeKey((am[1] || '').trim());
|
|
415
|
+
const vRaw = (am[2] || '').trim();
|
|
416
|
+
if (!k)
|
|
417
|
+
continue;
|
|
418
|
+
// If value looks like JSON array/object, parse; else keep as string
|
|
419
|
+
let v = vRaw;
|
|
420
|
+
if ((vRaw.startsWith('[') && vRaw.endsWith(']')) || (vRaw.startsWith('{') && vRaw.endsWith('}'))) {
|
|
421
|
+
try {
|
|
422
|
+
v = JSON.parse(vRaw);
|
|
423
|
+
}
|
|
424
|
+
catch {
|
|
425
|
+
v = vRaw;
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
argsObj[k] = v;
|
|
429
|
+
}
|
|
430
|
+
// If no args collected but inner contains JSON object, try as whole arguments
|
|
431
|
+
const hasAnyArg = Object.keys(argsObj).length > 0;
|
|
432
|
+
if (!hasAnyArg) {
|
|
433
|
+
const jsonMatch = inner.match(/\{[\s\S]*\}|\[[\s\S]*\]/);
|
|
434
|
+
if (jsonMatch) {
|
|
435
|
+
try {
|
|
436
|
+
const val = JSON.parse(jsonMatch[0]);
|
|
437
|
+
argsObj.arguments = val;
|
|
438
|
+
}
|
|
439
|
+
catch {
|
|
440
|
+
/* ignore */
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
const filtered = filterArgsForTool(lname, argsObj);
|
|
445
|
+
// Guard: view_image must have a valid image path
|
|
446
|
+
try {
|
|
447
|
+
if (lname === 'view_image') {
|
|
448
|
+
const p = filtered && typeof filtered === 'object' ? filtered.path : undefined;
|
|
449
|
+
if (!isImagePath(p)) {
|
|
450
|
+
continue;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
catch {
|
|
455
|
+
/* ignore guard errors */
|
|
456
|
+
}
|
|
457
|
+
let argsStr = '{}';
|
|
458
|
+
try {
|
|
459
|
+
argsStr = JSON.stringify(filtered);
|
|
460
|
+
}
|
|
461
|
+
catch {
|
|
462
|
+
argsStr = '{}';
|
|
463
|
+
}
|
|
464
|
+
out.push({ id: genToolCallId(), name, args: argsStr });
|
|
465
|
+
}
|
|
466
|
+
// Fallback: loose XML variant (missing <tool_call> start).
|
|
467
|
+
try {
|
|
468
|
+
const pairRe = /<\s*arg_key\s*>\s*([^<]+?)\s*<\/\s*arg_key\s*>\s*<\s*arg_value\s*>\s*([\s\S]*?)\s*<\/\s*arg_value\s*>/gi;
|
|
469
|
+
let pm;
|
|
470
|
+
while ((pm = pairRe.exec(text)) !== null) {
|
|
471
|
+
const start = pm.index;
|
|
472
|
+
// find a likely function name on the immediately preceding non-empty line
|
|
473
|
+
let name = '';
|
|
474
|
+
try {
|
|
475
|
+
const before = text.slice(0, start);
|
|
476
|
+
const lines = before.split(/\r?\n/).map((s) => s.trim()).filter(Boolean);
|
|
477
|
+
const cand = lines.length ? lines[lines.length - 1] : '';
|
|
478
|
+
if (/^[a-zA-Z0-9_.-]{2,}$/.test(cand))
|
|
479
|
+
name = cand;
|
|
480
|
+
}
|
|
481
|
+
catch {
|
|
482
|
+
/* ignore */
|
|
483
|
+
}
|
|
484
|
+
// 如果前一行抽不到合法函数名,但 arg_key 明显是 toon/command,
|
|
485
|
+
// 视为 CLI 通路下的 exec_command 工具。
|
|
486
|
+
const rawKey = (pm[1] || '').trim();
|
|
487
|
+
const normalizedKey = normalizeKey(rawKey).toLowerCase();
|
|
488
|
+
if (!name && (normalizedKey === 'toon' || normalizedKey === 'command')) {
|
|
489
|
+
name = 'exec_command';
|
|
490
|
+
}
|
|
491
|
+
if (!name)
|
|
492
|
+
continue;
|
|
493
|
+
const k = normalizeKey(rawKey);
|
|
494
|
+
const vRaw = (pm[2] || '').trim();
|
|
495
|
+
const argsObj = {};
|
|
496
|
+
if (k) {
|
|
497
|
+
let v = vRaw;
|
|
498
|
+
if ((vRaw.startsWith('[') && vRaw.endsWith(']')) || (vRaw.startsWith('{') && vRaw.endsWith('}'))) {
|
|
499
|
+
try {
|
|
500
|
+
v = JSON.parse(vRaw);
|
|
501
|
+
}
|
|
502
|
+
catch {
|
|
503
|
+
v = vRaw;
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
argsObj[k] = v;
|
|
507
|
+
}
|
|
508
|
+
const lname2 = String(name || '').toLowerCase();
|
|
509
|
+
const filtered2 = filterArgsForTool(lname2, argsObj);
|
|
510
|
+
// Guard: view_image must have a valid image path
|
|
511
|
+
try {
|
|
512
|
+
if (lname2 === 'view_image') {
|
|
513
|
+
const p = filtered2 && typeof filtered2 === 'object' ? filtered2.path : undefined;
|
|
514
|
+
if (!isImagePath(p)) {
|
|
515
|
+
continue;
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
catch {
|
|
520
|
+
/* ignore guard errors */
|
|
521
|
+
}
|
|
522
|
+
let argsStr = '{}';
|
|
523
|
+
try {
|
|
524
|
+
argsStr = JSON.stringify(filtered2);
|
|
525
|
+
}
|
|
526
|
+
catch {
|
|
527
|
+
argsStr = '{}';
|
|
528
|
+
}
|
|
529
|
+
out.push({ id: genToolCallId(), name, args: argsStr });
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
catch {
|
|
533
|
+
/* ignore */
|
|
534
|
+
}
|
|
535
|
+
return out.length ? out : null;
|
|
536
|
+
}
|
|
537
|
+
catch {
|
|
538
|
+
return null;
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
/**
|
|
542
|
+
* 提取简单 XML 形式的工具调用块,例如:
|
|
543
|
+
* <list_directory><path>/path</path><recursive>false</recursive></list_directory>
|
|
544
|
+
*/
|
|
545
|
+
export function extractSimpleXmlToolsFromText(text) {
|
|
546
|
+
try {
|
|
547
|
+
if (typeof text !== 'string' || !text)
|
|
548
|
+
return null;
|
|
549
|
+
const out = [];
|
|
550
|
+
const blockRe = /<\s*([A-Za-z0-9_.-]+)\s*>([\s\S]*?)<\/\s*\1\s*>/gi;
|
|
551
|
+
let bm;
|
|
552
|
+
while ((bm = blockRe.exec(text)) !== null) {
|
|
553
|
+
const rawName = (bm[1] || '').trim();
|
|
554
|
+
const lname = rawName.toLowerCase();
|
|
555
|
+
if (!lname || lname === 'tool_call')
|
|
556
|
+
continue;
|
|
557
|
+
// 目前仅支持 list_directory,后续按需扩展
|
|
558
|
+
if (lname !== 'list_directory')
|
|
559
|
+
continue;
|
|
560
|
+
const inner = bm[2] || '';
|
|
561
|
+
const args = {};
|
|
562
|
+
const argRe = /<\s*([A-Za-z0-9_]+)\s*>([\s\S]*?)<\/\s*\1\s*>/gi;
|
|
563
|
+
let am;
|
|
564
|
+
while ((am = argRe.exec(inner)) !== null) {
|
|
565
|
+
const key = normalizeKey((am[1] || '').trim());
|
|
566
|
+
if (!key)
|
|
567
|
+
continue;
|
|
568
|
+
const rawVal = (am[2] || '').trim();
|
|
569
|
+
let v = rawVal;
|
|
570
|
+
if ((rawVal.startsWith('[') && rawVal.endsWith(']')) || (rawVal.startsWith('{') && rawVal.endsWith('}'))) {
|
|
571
|
+
try {
|
|
572
|
+
v = JSON.parse(rawVal);
|
|
573
|
+
}
|
|
574
|
+
catch {
|
|
575
|
+
v = rawVal;
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
else if (rawVal === 'true' || rawVal === 'false') {
|
|
579
|
+
v = rawVal === 'true';
|
|
580
|
+
}
|
|
581
|
+
args[key] = v;
|
|
582
|
+
}
|
|
583
|
+
const filtered = filterArgsForTool(lname, args);
|
|
584
|
+
let argsStr = '{}';
|
|
585
|
+
try {
|
|
586
|
+
argsStr = JSON.stringify(filtered);
|
|
587
|
+
}
|
|
588
|
+
catch {
|
|
589
|
+
argsStr = '{}';
|
|
590
|
+
}
|
|
591
|
+
out.push({
|
|
592
|
+
id: genToolCallId(),
|
|
593
|
+
name: lname,
|
|
594
|
+
args: argsStr
|
|
595
|
+
});
|
|
596
|
+
}
|
|
597
|
+
return out.length ? out : null;
|
|
598
|
+
}
|
|
599
|
+
catch {
|
|
600
|
+
return null;
|
|
601
|
+
}
|
|
602
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export type { JsonToolRepairConfig, TextMarkupNormalizeOptions, ToolCallLite } from './extractors-shared.js';
|
|
2
|
+
export { extractJsonToolCallsFromText } from './extractors-json.js';
|
|
3
|
+
export { extractInvokeToolsFromText, extractParameterXmlToolsFromText, extractSimpleXmlToolsFromText, extractToolNamespaceXmlBlocksFromText, extractXMLToolCallsFromText } from './extractors-xml.js';
|
|
4
|
+
export { extractApplyPatchCallsFromText } from './extractors-apply-patch.js';
|
|
5
|
+
export { extractBareExecCommandFromText, extractExecuteBlocksFromText, extractExploredListDirectoryCallsFromText, extractQwenToolCallTokensFromText } from './extractors-transcript.js';
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { extractJsonToolCallsFromText } from './extractors-json.js';
|
|
2
|
+
export { extractInvokeToolsFromText, extractParameterXmlToolsFromText, extractSimpleXmlToolsFromText, extractToolNamespaceXmlBlocksFromText, extractXMLToolCallsFromText } from './extractors-xml.js';
|
|
3
|
+
export { extractApplyPatchCallsFromText } from './extractors-apply-patch.js';
|
|
4
|
+
export { extractBareExecCommandFromText, extractExecuteBlocksFromText, extractExploredListDirectoryCallsFromText, extractQwenToolCallTokensFromText } from './extractors-transcript.js';
|