@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
|
@@ -166,7 +166,8 @@ function requireSystemText(block, context) {
|
|
|
166
166
|
const ANTHROPIC_TOOL_NAME_ALIASES = new Map([
|
|
167
167
|
['bash', 'shell_command'],
|
|
168
168
|
['shell', 'shell_command'],
|
|
169
|
-
['terminal', 'shell_command']
|
|
169
|
+
['terminal', 'shell_command'],
|
|
170
|
+
['exec_command', 'shell_command']
|
|
170
171
|
]);
|
|
171
172
|
const CANONICAL_TO_ANTHROPIC_TOOL_NAMES = new Map([['shell_command', 'Bash']]);
|
|
172
173
|
const ANTHROPIC_TOP_LEVEL_FIELDS = new Set([
|
|
@@ -221,6 +222,69 @@ export function denormalizeAnthropicToolName(value) {
|
|
|
221
222
|
}
|
|
222
223
|
return trimmed;
|
|
223
224
|
}
|
|
225
|
+
function coerceShellLikeCommand(value) {
|
|
226
|
+
if (typeof value === 'string') {
|
|
227
|
+
const trimmed = value.trim();
|
|
228
|
+
return trimmed.length ? trimmed : undefined;
|
|
229
|
+
}
|
|
230
|
+
if (Array.isArray(value)) {
|
|
231
|
+
const parts = value
|
|
232
|
+
.map((entry) => (typeof entry === 'string' ? entry.trim() : ''))
|
|
233
|
+
.filter((entry) => entry.length > 0);
|
|
234
|
+
if (!parts.length) {
|
|
235
|
+
return undefined;
|
|
236
|
+
}
|
|
237
|
+
return parts.join(' ');
|
|
238
|
+
}
|
|
239
|
+
return undefined;
|
|
240
|
+
}
|
|
241
|
+
function normalizeShellLikeToolInput(toolName, input) {
|
|
242
|
+
const canonical = normalizeAnthropicToolName(toolName);
|
|
243
|
+
if (canonical !== 'shell_command') {
|
|
244
|
+
return input;
|
|
245
|
+
}
|
|
246
|
+
const rawToolName = typeof toolName === 'string' ? toolName.trim().toLowerCase() : '';
|
|
247
|
+
const isExecCommand = rawToolName === 'exec_command';
|
|
248
|
+
if (!input || typeof input !== 'object' || Array.isArray(input)) {
|
|
249
|
+
const cmd = coerceShellLikeCommand(input);
|
|
250
|
+
if (!cmd) {
|
|
251
|
+
return {};
|
|
252
|
+
}
|
|
253
|
+
return isExecCommand ? { cmd } : { command: cmd };
|
|
254
|
+
}
|
|
255
|
+
const next = { ...input };
|
|
256
|
+
const commandValue = coerceShellLikeCommand(next.command);
|
|
257
|
+
const cmdValue = coerceShellLikeCommand(next.cmd);
|
|
258
|
+
const fallbackValue = coerceShellLikeCommand(next.script) ??
|
|
259
|
+
coerceShellLikeCommand(next.toon);
|
|
260
|
+
if (commandValue) {
|
|
261
|
+
next.command = commandValue;
|
|
262
|
+
}
|
|
263
|
+
if (cmdValue) {
|
|
264
|
+
next.cmd = cmdValue;
|
|
265
|
+
}
|
|
266
|
+
if (!commandValue && !cmdValue && fallbackValue) {
|
|
267
|
+
if (isExecCommand) {
|
|
268
|
+
next.cmd = fallbackValue;
|
|
269
|
+
}
|
|
270
|
+
else {
|
|
271
|
+
next.command = fallbackValue;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
else if (!commandValue && cmdValue && !isExecCommand) {
|
|
275
|
+
next.command = cmdValue;
|
|
276
|
+
}
|
|
277
|
+
else if (!cmdValue && commandValue && isExecCommand) {
|
|
278
|
+
next.cmd = commandValue;
|
|
279
|
+
}
|
|
280
|
+
if (!isExecCommand && 'cmd' in next) {
|
|
281
|
+
delete next.cmd;
|
|
282
|
+
}
|
|
283
|
+
if (typeof next.workdir !== 'string' && typeof next.cwd === 'string' && next.cwd.trim().length > 0) {
|
|
284
|
+
next.workdir = next.cwd.trim();
|
|
285
|
+
}
|
|
286
|
+
return next;
|
|
287
|
+
}
|
|
224
288
|
function invertAnthropicAliasMap(source) {
|
|
225
289
|
if (!source) {
|
|
226
290
|
return undefined;
|
|
@@ -510,6 +574,7 @@ export function buildAnthropicFromOpenAIChat(oa, options) {
|
|
|
510
574
|
else {
|
|
511
575
|
input = argsRaw ?? {};
|
|
512
576
|
}
|
|
577
|
+
input = normalizeShellLikeToolInput(name, input);
|
|
513
578
|
blocks.push({ type: 'tool_use', id, name, input });
|
|
514
579
|
}
|
|
515
580
|
catch {
|
|
@@ -660,7 +725,15 @@ function createAnthropicToolNameResolver(source) {
|
|
|
660
725
|
if (!trimmed.length) {
|
|
661
726
|
return name;
|
|
662
727
|
}
|
|
663
|
-
|
|
728
|
+
const direct = lookup.get(trimmed) ?? lookup.get(trimmed.toLowerCase());
|
|
729
|
+
if (direct) {
|
|
730
|
+
return direct;
|
|
731
|
+
}
|
|
732
|
+
const normalized = normalizeAnthropicToolName(trimmed);
|
|
733
|
+
if (normalized) {
|
|
734
|
+
return lookup.get(normalized) ?? lookup.get(normalized.toLowerCase()) ?? trimmed;
|
|
735
|
+
}
|
|
736
|
+
return trimmed;
|
|
664
737
|
};
|
|
665
738
|
}
|
|
666
739
|
function normalizeAnthropicToolChoice(value) {
|
|
@@ -928,6 +1001,7 @@ export function buildAnthropicRequestFromOpenAIChat(chatReq) {
|
|
|
928
1001
|
else {
|
|
929
1002
|
input = argsRaw ?? {};
|
|
930
1003
|
}
|
|
1004
|
+
input = normalizeShellLikeToolInput(name, input);
|
|
931
1005
|
blocks.push({ type: 'tool_use', id, name, input });
|
|
932
1006
|
}
|
|
933
1007
|
if (blocks.length > 0) {
|
|
@@ -1167,6 +1241,12 @@ export function buildAnthropicToolAliasMap(rawTools) {
|
|
|
1167
1241
|
continue;
|
|
1168
1242
|
}
|
|
1169
1243
|
aliasMap.set(canonicalKey, rawName);
|
|
1244
|
+
// Anthropic shell-like tools (e.g. Bash) and exec_command are treated as one family.
|
|
1245
|
+
// Keep an explicit exec_command key so reverse mapping can preserve
|
|
1246
|
+
// canonical exec_command when upstream already uses that name.
|
|
1247
|
+
if (canonicalKey === 'shell_command' && !aliasMap.has('exec_command')) {
|
|
1248
|
+
aliasMap.set('exec_command', rawName);
|
|
1249
|
+
}
|
|
1170
1250
|
const lowerKey = canonicalKey.toLowerCase();
|
|
1171
1251
|
if (lowerKey !== canonicalKey && !aliasMap.has(lowerKey)) {
|
|
1172
1252
|
aliasMap.set(lowerKey, rawName);
|
|
@@ -60,8 +60,8 @@ function collectText(value) {
|
|
|
60
60
|
}
|
|
61
61
|
return '';
|
|
62
62
|
}
|
|
63
|
-
function
|
|
64
|
-
const
|
|
63
|
+
function extractMediaBlocksFromContent(content) {
|
|
64
|
+
const media = [];
|
|
65
65
|
const visit = (value) => {
|
|
66
66
|
if (!value)
|
|
67
67
|
return;
|
|
@@ -75,14 +75,27 @@ function extractImageBlocksFromContent(content) {
|
|
|
75
75
|
}
|
|
76
76
|
const record = value;
|
|
77
77
|
const typeValue = typeof record.type === 'string' ? record.type.toLowerCase() : '';
|
|
78
|
+
let kind = null;
|
|
78
79
|
if (typeValue === 'image' || typeValue === 'image_url' || typeValue === 'input_image') {
|
|
80
|
+
kind = 'image';
|
|
81
|
+
}
|
|
82
|
+
else if (typeValue === 'video' || typeValue === 'video_url' || typeValue === 'input_video') {
|
|
83
|
+
kind = 'video';
|
|
84
|
+
}
|
|
85
|
+
else if (record.video_url !== undefined) {
|
|
86
|
+
kind = 'video';
|
|
87
|
+
}
|
|
88
|
+
else if (record.image_url !== undefined) {
|
|
89
|
+
kind = 'image';
|
|
90
|
+
}
|
|
91
|
+
if (kind) {
|
|
79
92
|
let url = '';
|
|
80
|
-
const
|
|
81
|
-
if (typeof
|
|
82
|
-
url =
|
|
93
|
+
const mediaUrl = kind === 'video' ? record.video_url : record.image_url;
|
|
94
|
+
if (typeof mediaUrl === 'string') {
|
|
95
|
+
url = mediaUrl;
|
|
83
96
|
}
|
|
84
|
-
else if (
|
|
85
|
-
url =
|
|
97
|
+
else if (mediaUrl && typeof mediaUrl === 'object' && typeof mediaUrl.url === 'string') {
|
|
98
|
+
url = mediaUrl.url;
|
|
86
99
|
}
|
|
87
100
|
else if (typeof record.url === 'string') {
|
|
88
101
|
url = record.url;
|
|
@@ -96,13 +109,13 @@ function extractImageBlocksFromContent(content) {
|
|
|
96
109
|
const trimmed = url.trim();
|
|
97
110
|
if (trimmed.length) {
|
|
98
111
|
let detail;
|
|
99
|
-
if (
|
|
100
|
-
detail =
|
|
112
|
+
if (mediaUrl && typeof mediaUrl === 'object' && typeof mediaUrl.detail === 'string') {
|
|
113
|
+
detail = mediaUrl.detail.trim() || undefined;
|
|
101
114
|
}
|
|
102
115
|
else if (typeof record.detail === 'string') {
|
|
103
116
|
detail = record.detail.trim() || undefined;
|
|
104
117
|
}
|
|
105
|
-
|
|
118
|
+
media.push({ kind, url: trimmed, detail });
|
|
106
119
|
}
|
|
107
120
|
return;
|
|
108
121
|
}
|
|
@@ -111,7 +124,7 @@ function extractImageBlocksFromContent(content) {
|
|
|
111
124
|
}
|
|
112
125
|
};
|
|
113
126
|
visit(content);
|
|
114
|
-
return
|
|
127
|
+
return media;
|
|
115
128
|
}
|
|
116
129
|
function extractUserTextFromEntry(entry) {
|
|
117
130
|
if (!entry || typeof entry !== 'object')
|
|
@@ -141,7 +154,7 @@ export function convertMessagesToBridgeInput(options) {
|
|
|
141
154
|
const role = coerceBridgeRole(m.role || 'user');
|
|
142
155
|
const content = m.content;
|
|
143
156
|
const collectedText = collectText(content);
|
|
144
|
-
const
|
|
157
|
+
const mediaBlocks = extractMediaBlocksFromContent(content);
|
|
145
158
|
const text = role === 'system' ? collectedText : collectedText.trim();
|
|
146
159
|
if (role === 'system') {
|
|
147
160
|
if (collectedText && collectedText.length) {
|
|
@@ -218,20 +231,26 @@ export function convertMessagesToBridgeInput(options) {
|
|
|
218
231
|
}
|
|
219
232
|
continue;
|
|
220
233
|
}
|
|
221
|
-
if (typeof text === 'string' ||
|
|
234
|
+
if (typeof text === 'string' || mediaBlocks.length) {
|
|
222
235
|
const tRole = role === 'assistant' ? 'output_text' : 'input_text';
|
|
223
236
|
const blocks = [];
|
|
224
237
|
if (typeof text === 'string' && text.length) {
|
|
225
238
|
blocks.push({ type: tRole, text });
|
|
226
239
|
}
|
|
227
|
-
for (const
|
|
228
|
-
const block =
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
240
|
+
for (const media of mediaBlocks) {
|
|
241
|
+
const block = media.kind === 'video'
|
|
242
|
+
? {
|
|
243
|
+
type: 'input_video',
|
|
244
|
+
video_url: media.url
|
|
245
|
+
}
|
|
246
|
+
: {
|
|
247
|
+
type: 'input_image',
|
|
248
|
+
image_url: media.url
|
|
249
|
+
};
|
|
250
|
+
if (media.detail) {
|
|
251
|
+
block.detail = media.detail;
|
|
234
252
|
}
|
|
253
|
+
;
|
|
235
254
|
blocks.push(block);
|
|
236
255
|
}
|
|
237
256
|
if (blocks.length) {
|
|
@@ -324,7 +343,7 @@ function processMessageBlocks(blocks, normalizeFunctionName, tools, toolNameById
|
|
|
324
343
|
const toolMessages = [];
|
|
325
344
|
let currentLastCall = lastToolCallId;
|
|
326
345
|
const reasoningSegments = [];
|
|
327
|
-
const
|
|
346
|
+
const mediaBlocks = [];
|
|
328
347
|
for (const block of blocks) {
|
|
329
348
|
if (!block || typeof block !== 'object')
|
|
330
349
|
continue;
|
|
@@ -347,17 +366,45 @@ function processMessageBlocks(blocks, normalizeFunctionName, tools, toolNameById
|
|
|
347
366
|
toolMessages.push(tm);
|
|
348
367
|
currentLastCall = nested.lastCallId;
|
|
349
368
|
reasoningSegments.push(...nested.reasoningSegments);
|
|
350
|
-
if (nested.
|
|
351
|
-
|
|
369
|
+
if (nested.mediaBlocks.length)
|
|
370
|
+
mediaBlocks.push(...nested.mediaBlocks);
|
|
371
|
+
continue;
|
|
372
|
+
}
|
|
373
|
+
if (type === 'input_image' || type === 'image' || type === 'image_url') {
|
|
374
|
+
let url = '';
|
|
375
|
+
if (typeof block.image_url === 'string') {
|
|
376
|
+
url = block.image_url.trim();
|
|
377
|
+
}
|
|
378
|
+
else if (block.image_url && typeof block.image_url.url === 'string') {
|
|
379
|
+
url = block.image_url.url.trim();
|
|
380
|
+
}
|
|
381
|
+
else if (typeof block.url === 'string') {
|
|
382
|
+
url = block.url.trim();
|
|
383
|
+
}
|
|
384
|
+
if (url) {
|
|
385
|
+
const detail = typeof block.detail === 'string' && block.detail.trim()
|
|
386
|
+
? block.detail.trim()
|
|
387
|
+
: undefined;
|
|
388
|
+
mediaBlocks.push({ kind: 'image', url, detail });
|
|
389
|
+
}
|
|
352
390
|
continue;
|
|
353
391
|
}
|
|
354
|
-
if (type === '
|
|
355
|
-
|
|
392
|
+
if (type === 'input_video' || type === 'video' || type === 'video_url') {
|
|
393
|
+
let url = '';
|
|
394
|
+
if (typeof block.video_url === 'string') {
|
|
395
|
+
url = block.video_url.trim();
|
|
396
|
+
}
|
|
397
|
+
else if (block.video_url && typeof block.video_url.url === 'string') {
|
|
398
|
+
url = block.video_url.url.trim();
|
|
399
|
+
}
|
|
400
|
+
else if (typeof block.url === 'string') {
|
|
401
|
+
url = block.url.trim();
|
|
402
|
+
}
|
|
356
403
|
if (url) {
|
|
357
404
|
const detail = typeof block.detail === 'string' && block.detail.trim()
|
|
358
405
|
? block.detail.trim()
|
|
359
406
|
: undefined;
|
|
360
|
-
|
|
407
|
+
mediaBlocks.push({ kind: 'video', url, detail });
|
|
361
408
|
}
|
|
362
409
|
continue;
|
|
363
410
|
}
|
|
@@ -421,7 +468,7 @@ function processMessageBlocks(blocks, normalizeFunctionName, tools, toolNameById
|
|
|
421
468
|
}
|
|
422
469
|
}
|
|
423
470
|
const text = textParts.length ? textParts.join('\n').trim() : null;
|
|
424
|
-
return { text,
|
|
471
|
+
return { text, mediaBlocks, toolCalls, toolMessages, lastCallId: currentLastCall, reasoningSegments };
|
|
425
472
|
}
|
|
426
473
|
export function convertBridgeInputToChatMessages(options) {
|
|
427
474
|
const { input, tools, normalizeFunctionName, toolResultFallbackText } = options;
|
|
@@ -547,17 +594,20 @@ export function convertBridgeInputToChatMessages(options) {
|
|
|
547
594
|
for (const msg of nested.toolMessages)
|
|
548
595
|
messages.push(msg);
|
|
549
596
|
const normalizedRole = coerceBridgeRole((explicit.role ?? entry.role) || 'user');
|
|
550
|
-
if (nested.
|
|
597
|
+
if (nested.mediaBlocks.length) {
|
|
551
598
|
const contentBlocks = [];
|
|
552
599
|
if (typeof nested.text === 'string' && nested.text.trim().length) {
|
|
553
600
|
contentBlocks.push({ type: 'text', text: nested.text });
|
|
554
601
|
}
|
|
555
|
-
for (const
|
|
556
|
-
const
|
|
557
|
-
|
|
558
|
-
|
|
602
|
+
for (const media of nested.mediaBlocks) {
|
|
603
|
+
const mediaBlock = media.kind === 'video'
|
|
604
|
+
? { type: 'video_url', video_url: { url: media.url } }
|
|
605
|
+
: { type: 'image_url', image_url: { url: media.url } };
|
|
606
|
+
if (media.detail) {
|
|
607
|
+
const key = media.kind === 'video' ? 'video_url' : 'image_url';
|
|
608
|
+
mediaBlock[key].detail = media.detail;
|
|
559
609
|
}
|
|
560
|
-
contentBlocks.push(
|
|
610
|
+
contentBlocks.push(mediaBlock);
|
|
561
611
|
}
|
|
562
612
|
const msg = {
|
|
563
613
|
role: normalizedRole,
|
|
@@ -590,17 +640,20 @@ export function convertBridgeInputToChatMessages(options) {
|
|
|
590
640
|
for (const msg of nested.toolMessages)
|
|
591
641
|
messages.push(msg);
|
|
592
642
|
const normalizedRole = coerceBridgeRole(entry.role || 'user');
|
|
593
|
-
if (nested.
|
|
643
|
+
if (nested.mediaBlocks.length) {
|
|
594
644
|
const contentBlocks = [];
|
|
595
645
|
if (typeof nested.text === 'string' && nested.text.trim().length) {
|
|
596
646
|
contentBlocks.push({ type: 'text', text: nested.text });
|
|
597
647
|
}
|
|
598
|
-
for (const
|
|
599
|
-
const
|
|
600
|
-
|
|
601
|
-
|
|
648
|
+
for (const media of nested.mediaBlocks) {
|
|
649
|
+
const mediaBlock = media.kind === 'video'
|
|
650
|
+
? { type: 'video_url', video_url: { url: media.url } }
|
|
651
|
+
: { type: 'image_url', image_url: { url: media.url } };
|
|
652
|
+
if (media.detail) {
|
|
653
|
+
const key = media.kind === 'video' ? 'video_url' : 'image_url';
|
|
654
|
+
mediaBlock[key].detail = media.detail;
|
|
602
655
|
}
|
|
603
|
-
contentBlocks.push(
|
|
656
|
+
contentBlocks.push(mediaBlock);
|
|
604
657
|
}
|
|
605
658
|
const msg = {
|
|
606
659
|
role: normalizedRole,
|
|
@@ -83,11 +83,11 @@ async function writeUniqueErrorsampleFile(dir, baseName, contents) {
|
|
|
83
83
|
await fs.writeFile(path.join(dir, fallback), contents, { encoding: 'utf-8' });
|
|
84
84
|
}
|
|
85
85
|
function resolveSnapshotFolder(endpoint) {
|
|
86
|
-
const lowered = (endpoint || '').toLowerCase();
|
|
87
|
-
if (lowered.includes('/responses')) {
|
|
86
|
+
const lowered = (endpoint || '').trim().toLowerCase();
|
|
87
|
+
if (lowered.includes('/v1/responses') || lowered.includes('/responses.submit')) {
|
|
88
88
|
return 'openai-responses';
|
|
89
89
|
}
|
|
90
|
-
if (lowered.includes('/messages')) {
|
|
90
|
+
if (lowered.includes('/v1/messages')) {
|
|
91
91
|
return 'anthropic-messages';
|
|
92
92
|
}
|
|
93
93
|
return 'openai-chat';
|
|
@@ -187,8 +187,7 @@ function extractNestedEntryEndpoint(value) {
|
|
|
187
187
|
}
|
|
188
188
|
const obj = value;
|
|
189
189
|
const direct = readStringField(obj.entryEndpoint) ||
|
|
190
|
-
readStringField(obj.entry_endpoint)
|
|
191
|
-
readStringField(obj.endpoint);
|
|
190
|
+
readStringField(obj.entry_endpoint);
|
|
192
191
|
if (direct) {
|
|
193
192
|
return direct;
|
|
194
193
|
}
|
|
@@ -196,8 +195,7 @@ function extractNestedEntryEndpoint(value) {
|
|
|
196
195
|
if (meta && typeof meta === 'object') {
|
|
197
196
|
const m = meta;
|
|
198
197
|
const fromMeta = readStringField(m.entryEndpoint) ||
|
|
199
|
-
readStringField(m.entry_endpoint)
|
|
200
|
-
readStringField(m.endpoint);
|
|
198
|
+
readStringField(m.entry_endpoint);
|
|
201
199
|
if (fromMeta) {
|
|
202
200
|
return fromMeta;
|
|
203
201
|
}
|
|
@@ -205,8 +203,7 @@ function extractNestedEntryEndpoint(value) {
|
|
|
205
203
|
if (ctx && typeof ctx === 'object') {
|
|
206
204
|
const c = ctx;
|
|
207
205
|
const fromCtx = readStringField(c.entryEndpoint) ||
|
|
208
|
-
readStringField(c.entry_endpoint)
|
|
209
|
-
readStringField(c.endpoint);
|
|
206
|
+
readStringField(c.entry_endpoint);
|
|
210
207
|
if (fromCtx) {
|
|
211
208
|
return fromCtx;
|
|
212
209
|
}
|
|
@@ -216,8 +213,7 @@ function extractNestedEntryEndpoint(value) {
|
|
|
216
213
|
if (metadata && typeof metadata === 'object') {
|
|
217
214
|
const md = metadata;
|
|
218
215
|
const fromMetadata = readStringField(md.entryEndpoint) ||
|
|
219
|
-
readStringField(md.entry_endpoint)
|
|
220
|
-
readStringField(md.endpoint);
|
|
216
|
+
readStringField(md.entry_endpoint);
|
|
221
217
|
if (fromMetadata) {
|
|
222
218
|
return fromMetadata;
|
|
223
219
|
}
|
|
@@ -226,8 +222,7 @@ function extractNestedEntryEndpoint(value) {
|
|
|
226
222
|
if (runtime && typeof runtime === 'object') {
|
|
227
223
|
const r = runtime;
|
|
228
224
|
const fromRuntime = readStringField(r.entryEndpoint) ||
|
|
229
|
-
readStringField(r.entry_endpoint)
|
|
230
|
-
readStringField(r.endpoint);
|
|
225
|
+
readStringField(r.entry_endpoint);
|
|
231
226
|
if (fromRuntime) {
|
|
232
227
|
return fromRuntime;
|
|
233
228
|
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { isStructuredApplyPatchPayload } from '../../../tools/apply-patch-structured.js';
|
|
2
|
+
import { genToolCallId } from './extractors-shared.js';
|
|
3
|
+
function extractStructuredApplyPatchPayloads(text) {
|
|
4
|
+
const payloads = [];
|
|
5
|
+
try {
|
|
6
|
+
const fenceRe = /```(?:json|apply_patch|toon)?\s*([\s\S]*?)\s*```/gi;
|
|
7
|
+
let fm;
|
|
8
|
+
while ((fm = fenceRe.exec(text)) !== null) {
|
|
9
|
+
const body = fm[1] || '';
|
|
10
|
+
try {
|
|
11
|
+
const parsed = JSON.parse(body);
|
|
12
|
+
if (isStructuredApplyPatchPayload(parsed)) {
|
|
13
|
+
payloads.push(parsed);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
/* ignore invalid JSON */
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
if (!payloads.length && typeof text === 'string' && text.includes('"changes"')) {
|
|
21
|
+
try {
|
|
22
|
+
const parsed = JSON.parse(text);
|
|
23
|
+
if (isStructuredApplyPatchPayload(parsed)) {
|
|
24
|
+
payloads.push(parsed);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
/* ignore */
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
/* ignore */
|
|
34
|
+
}
|
|
35
|
+
return payloads;
|
|
36
|
+
}
|
|
37
|
+
function normalizeRawApplyPatchBlock(raw) {
|
|
38
|
+
try {
|
|
39
|
+
const lines = String(raw || '')
|
|
40
|
+
.split(/\r?\n/)
|
|
41
|
+
.map((line) => line.replace(/\r/g, ''));
|
|
42
|
+
while (lines.length > 0 && !lines[0].trim()) {
|
|
43
|
+
lines.shift();
|
|
44
|
+
}
|
|
45
|
+
while (lines.length > 0 && !lines[lines.length - 1].trim()) {
|
|
46
|
+
lines.pop();
|
|
47
|
+
}
|
|
48
|
+
if (!lines.length)
|
|
49
|
+
return '';
|
|
50
|
+
const indents = lines
|
|
51
|
+
.filter((line) => line.trim().length > 0)
|
|
52
|
+
.map((line) => {
|
|
53
|
+
const m = line.match(/^[ \t]*/);
|
|
54
|
+
return m ? m[0].length : 0;
|
|
55
|
+
});
|
|
56
|
+
const minIndent = indents.length ? Math.min(...indents) : 0;
|
|
57
|
+
if (minIndent <= 0) {
|
|
58
|
+
return lines.join('\n').trim();
|
|
59
|
+
}
|
|
60
|
+
return lines
|
|
61
|
+
.map((line) => line.replace(new RegExp(`^[ \\t]{0,${minIndent}}`), ''))
|
|
62
|
+
.join('\n')
|
|
63
|
+
.trim();
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
return String(raw || '').trim();
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function extractRawApplyPatchBlocks(text) {
|
|
70
|
+
const out = [];
|
|
71
|
+
try {
|
|
72
|
+
if (typeof text !== 'string' || !text)
|
|
73
|
+
return out;
|
|
74
|
+
const seen = new Set();
|
|
75
|
+
const blockRe = /\*\*\*\s*Begin Patch(?:\s*\*\*\*)?[\s\S]*?\*\*\*\s*End Patch(?:\s*\*\*\*)?/gi;
|
|
76
|
+
let m;
|
|
77
|
+
while ((m = blockRe.exec(text)) !== null) {
|
|
78
|
+
const normalized = normalizeRawApplyPatchBlock(String(m[0] || ''));
|
|
79
|
+
if (!normalized)
|
|
80
|
+
continue;
|
|
81
|
+
// Avoid turning incidental prose into apply_patch.
|
|
82
|
+
if (!/\*\*\*\s*(?:Add|Update|Delete)\s+File:/i.test(normalized))
|
|
83
|
+
continue;
|
|
84
|
+
if (seen.has(normalized))
|
|
85
|
+
continue;
|
|
86
|
+
seen.add(normalized);
|
|
87
|
+
out.push(normalized);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
/* ignore */
|
|
92
|
+
}
|
|
93
|
+
return out;
|
|
94
|
+
}
|
|
95
|
+
export function extractApplyPatchCallsFromText(text) {
|
|
96
|
+
try {
|
|
97
|
+
if (typeof text !== 'string' || !text)
|
|
98
|
+
return null;
|
|
99
|
+
const payloads = extractStructuredApplyPatchPayloads(text);
|
|
100
|
+
const patchBlocks = extractRawApplyPatchBlocks(text);
|
|
101
|
+
if (!payloads.length && !patchBlocks.length)
|
|
102
|
+
return null;
|
|
103
|
+
const out = [];
|
|
104
|
+
for (const payload of payloads) {
|
|
105
|
+
let argsStr = '{}';
|
|
106
|
+
try {
|
|
107
|
+
argsStr = JSON.stringify(payload);
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
argsStr = '{"changes":[]}';
|
|
111
|
+
}
|
|
112
|
+
out.push({ id: genToolCallId(), name: 'apply_patch', args: argsStr });
|
|
113
|
+
}
|
|
114
|
+
for (const patch of patchBlocks) {
|
|
115
|
+
let argsStr = '{}';
|
|
116
|
+
try {
|
|
117
|
+
argsStr = JSON.stringify({ patch, input: patch });
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
argsStr = '{"patch":""}';
|
|
121
|
+
}
|
|
122
|
+
out.push({ id: genToolCallId(), name: 'apply_patch', args: argsStr });
|
|
123
|
+
}
|
|
124
|
+
return out;
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { type TextMarkupNormalizeOptions, type ToolCallLite } from './extractors-shared.js';
|
|
2
|
+
export declare function tryParseJsonWithModelRepairs(raw: string): unknown | null;
|
|
3
|
+
export declare function salvageToolArgsFromRawText(toolName: string, rawArgs: string): Record<string, unknown> | null;
|
|
4
|
+
export declare function extractJsonToolCallsFromText(text: string, options?: TextMarkupNormalizeOptions): ToolCallLite[] | null;
|