@jsonstudio/llms 0.6.3275 → 0.6.3405
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/bridge-message-utils.d.ts +4 -4
- package/dist/conversion/bridge-message-utils.js +28 -538
- package/dist/conversion/compat/actions/claude-thinking-tools.d.ts +1 -14
- package/dist/conversion/compat/actions/claude-thinking-tools.js +3 -71
- package/dist/conversion/compat/actions/lmstudio-responses-fc-ids.d.ts +0 -8
- package/dist/conversion/compat/actions/lmstudio-responses-fc-ids.js +2 -57
- package/dist/conversion/compat/actions/normalize-tool-call-ids.d.ts +0 -9
- package/dist/conversion/compat/actions/normalize-tool-call-ids.js +6 -136
- package/dist/conversion/compat/actions/request-rules.js +2 -61
- package/dist/conversion/compat/actions/response-blacklist.d.ts +0 -4
- package/dist/conversion/compat/actions/response-blacklist.js +2 -77
- package/dist/conversion/compat/actions/response-normalize.js +2 -119
- package/dist/conversion/compat/actions/response-validate.js +2 -74
- package/dist/conversion/compat/actions/strip-orphan-function-calls-tag.js +2 -150
- package/dist/conversion/compat/profiles/responses-crs.json +15 -0
- package/dist/conversion/hub/operation-table/semantic-mappers/anthropic-mapper.js +24 -1
- package/dist/conversion/hub/operation-table/semantic-mappers/chat-mapper.js +16 -5
- package/dist/conversion/hub/pipeline/hub-pipeline.js +91 -0
- package/dist/conversion/hub/pipeline/stages/resp_process/resp_process_stage1_tool_governance/index.js +1 -6
- package/dist/conversion/hub/response/response-runtime.js +14 -6
- package/dist/conversion/responses/responses-openai-bridge/response-payload.js +11 -11
- package/dist/conversion/shared/anthropic-message-utils.js +2 -12
- package/dist/conversion/shared/chat-request-filters.js +2 -61
- package/dist/conversion/shared/reasoning-mapping.js +3 -0
- package/dist/conversion/shared/reasoning-normalizer.d.ts +1 -0
- package/dist/conversion/shared/reasoning-normalizer.js +35 -388
- package/dist/conversion/shared/reasoning-tool-normalizer.js +8 -15
- package/dist/conversion/shared/reasoning-tool-parser.js +7 -8
- package/dist/conversion/shared/reasoning-utils.js +13 -35
- package/dist/conversion/shared/responses-response-utils.js +3 -48
- package/dist/conversion/shared/responses-tool-utils.d.ts +1 -1
- package/dist/conversion/shared/responses-tool-utils.js +74 -180
- package/dist/conversion/shared/streaming-text-extractor.d.ts +0 -5
- package/dist/conversion/shared/streaming-text-extractor.js +18 -111
- package/dist/conversion/shared/text-markup-normalizer/normalize.d.ts +1 -1
- package/dist/conversion/shared/text-markup-normalizer/normalize.js +3 -91
- package/dist/conversion/shared/thought-signature-validator.js +19 -133
- package/dist/conversion/shared/tool-argument-repairer.js +16 -19
- package/dist/conversion/shared/tool-call-id-manager.d.ts +1 -5
- package/dist/conversion/shared/tool-call-id-manager.js +74 -98
- package/dist/conversion/shared/tool-harvester.js +19 -382
- package/dist/conversion/shared/tool-mapping.d.ts +2 -3
- package/dist/conversion/shared/tool-mapping.js +28 -184
- package/dist/conversion/shared/tooling.js +20 -151
- package/dist/filters/special/response-tool-arguments-stringify.js +9 -1
- package/dist/guidance/index.js +2 -2
- package/dist/native/router_hotpath_napi.node +0 -0
- package/dist/router/virtual-router/bootstrap/web-search-config.js +25 -0
- package/dist/router/virtual-router/bootstrap.js +21 -16
- package/dist/router/virtual-router/engine-legacy/helpers.js +1 -1
- package/dist/router/virtual-router/engine-selection/native-compat-action-semantics.d.ts +6 -0
- package/dist/router/virtual-router/engine-selection/native-compat-action-semantics.js +171 -0
- package/dist/router/virtual-router/engine-selection/native-hub-bridge-action-semantics.d.ts +39 -0
- package/dist/router/virtual-router/engine-selection/native-hub-bridge-action-semantics.js +196 -0
- package/dist/router/virtual-router/engine-selection/native-hub-pipeline-req-inbound-semantics.d.ts +1 -0
- package/dist/router/virtual-router/engine-selection/native-hub-pipeline-req-inbound-semantics.js +27 -0
- package/dist/router/virtual-router/engine-selection/native-router-hotpath-loader.js +45 -0
- package/dist/router/virtual-router/engine-selection/native-shared-conversion-semantics.d.ts +70 -1
- package/dist/router/virtual-router/engine-selection/native-shared-conversion-semantics.js +993 -55
- package/dist/router/virtual-router/engine.js +3 -2
- package/dist/router/virtual-router/routing-instructions/parse.js +30 -3
- package/dist/router/virtual-router/types.d.ts +23 -0
- package/dist/servertool/handlers/web-search.js +26 -1
- package/dist/servertool/server-side-tools.js +11 -2
- package/dist/servertool/types.d.ts +4 -0
- package/dist/sse/sse-to-json/builders/anthropic-response-builder.js +28 -3
- package/dist/sse/types/anthropic-types.d.ts +3 -1
- package/dist/tools/apply-patch/args-normalizer/extract-patch.js +2 -2
- package/dist/tools/apply-patch/patch-text/looks-like-patch.js +3 -6
- package/dist/tools/apply-patch/patch-text/normalize.js +14 -3
- package/dist/tools/tool-registry.js +12 -0
- package/package.json +6 -1
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
import type { BridgeInputItem } from './types/bridge-message-types.js';
|
|
2
|
-
export declare function coerceBridgeRole(role: unknown): string;
|
|
3
|
-
export declare function serializeToolArguments(argsStringOrObj: unknown, _functionName: string | undefined, _tools: unknown): string;
|
|
4
|
-
export declare function serializeToolOutput(entry: BridgeInputItem): string | null;
|
|
5
2
|
export interface BridgeInputBuildOptions {
|
|
6
3
|
messages: Array<Record<string, unknown>>;
|
|
7
4
|
tools?: Array<Record<string, unknown>> | undefined;
|
|
@@ -12,11 +9,14 @@ export interface BridgeInputBuildResult {
|
|
|
12
9
|
latestUserInstruction?: string;
|
|
13
10
|
originalSystemMessages: string[];
|
|
14
11
|
}
|
|
12
|
+
export declare function coerceBridgeRole(role: unknown): string;
|
|
13
|
+
export declare function serializeToolArguments(argsStringOrObj: unknown, _functionName: string | undefined, _tools: unknown): string;
|
|
14
|
+
export declare function serializeToolOutput(entry: BridgeInputItem): string | null;
|
|
15
15
|
export declare function convertMessagesToBridgeInput(options: BridgeInputBuildOptions): BridgeInputBuildResult;
|
|
16
16
|
export interface BridgeInputToChatOptions {
|
|
17
17
|
input?: BridgeInputItem[];
|
|
18
18
|
tools?: Array<Record<string, unknown>>;
|
|
19
|
-
normalizeFunctionName?: (raw: unknown) => string | undefined;
|
|
19
|
+
normalizeFunctionName?: ((raw: unknown) => string | undefined) | 'default' | 'responses';
|
|
20
20
|
toolResultFallbackText?: string;
|
|
21
21
|
}
|
|
22
22
|
export declare function convertBridgeInputToChatMessages(options: BridgeInputToChatOptions): Array<Record<string, unknown>>;
|
|
@@ -1,555 +1,45 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
(
|
|
10
|
-
|
|
11
|
-
: undefined) ??
|
|
12
|
-
fallbackId;
|
|
13
|
-
call.id = resolved;
|
|
14
|
-
call.tool_call_id = resolved;
|
|
15
|
-
call.call_id = resolved;
|
|
16
|
-
return resolved;
|
|
1
|
+
import { buildBridgeHistoryWithNative, coerceBridgeRoleWithNative, convertBridgeInputToChatMessagesWithNative, ensureMessagesArrayWithNative, serializeToolArgumentsWithNative, serializeToolOutputWithNative } from '../router/virtual-router/engine-selection/native-hub-bridge-action-semantics.js';
|
|
2
|
+
function assertBridgeMessageUtilsNativeAvailable() {
|
|
3
|
+
if (typeof buildBridgeHistoryWithNative !== 'function' ||
|
|
4
|
+
typeof convertBridgeInputToChatMessagesWithNative !== 'function' ||
|
|
5
|
+
typeof coerceBridgeRoleWithNative !== 'function' ||
|
|
6
|
+
typeof serializeToolArgumentsWithNative !== 'function' ||
|
|
7
|
+
typeof serializeToolOutputWithNative !== 'function' ||
|
|
8
|
+
typeof ensureMessagesArrayWithNative !== 'function') {
|
|
9
|
+
throw new Error('[bridge-message-utils] native bindings unavailable');
|
|
10
|
+
}
|
|
17
11
|
}
|
|
18
12
|
export function coerceBridgeRole(role) {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
if (normalized === 'system' || normalized === 'assistant' || normalized === 'user' || normalized === 'tool') {
|
|
22
|
-
return normalized;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
return 'user';
|
|
13
|
+
assertBridgeMessageUtilsNativeAvailable();
|
|
14
|
+
return coerceBridgeRoleWithNative(role);
|
|
26
15
|
}
|
|
27
16
|
export function serializeToolArguments(argsStringOrObj, _functionName, _tools) {
|
|
28
|
-
|
|
17
|
+
assertBridgeMessageUtilsNativeAvailable();
|
|
18
|
+
return serializeToolArgumentsWithNative({ args: argsStringOrObj });
|
|
29
19
|
}
|
|
30
20
|
export function serializeToolOutput(entry) {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
return out;
|
|
34
|
-
if (out && typeof out === 'object') {
|
|
35
|
-
try {
|
|
36
|
-
return JSON.stringify(out);
|
|
37
|
-
}
|
|
38
|
-
catch {
|
|
39
|
-
return String(out);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
return null;
|
|
43
|
-
}
|
|
44
|
-
function collectText(value) {
|
|
45
|
-
if (!value)
|
|
46
|
-
return '';
|
|
47
|
-
if (typeof value === 'string')
|
|
48
|
-
return value;
|
|
49
|
-
if (Array.isArray(value)) {
|
|
50
|
-
return value.map(part => collectText(part)).join('');
|
|
51
|
-
}
|
|
52
|
-
if (typeof value === 'object') {
|
|
53
|
-
const record = value;
|
|
54
|
-
if (typeof record.text === 'string')
|
|
55
|
-
return record.text;
|
|
56
|
-
if (Array.isArray(record.content))
|
|
57
|
-
return collectText(record.content);
|
|
58
|
-
if (typeof record.content === 'string')
|
|
59
|
-
return record.content;
|
|
60
|
-
}
|
|
61
|
-
return '';
|
|
62
|
-
}
|
|
63
|
-
function extractMediaBlocksFromContent(content) {
|
|
64
|
-
const media = [];
|
|
65
|
-
const visit = (value) => {
|
|
66
|
-
if (!value)
|
|
67
|
-
return;
|
|
68
|
-
if (Array.isArray(value)) {
|
|
69
|
-
for (const entry of value)
|
|
70
|
-
visit(entry);
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
|
-
if (typeof value !== 'object') {
|
|
74
|
-
return;
|
|
75
|
-
}
|
|
76
|
-
const record = value;
|
|
77
|
-
const typeValue = typeof record.type === 'string' ? record.type.toLowerCase() : '';
|
|
78
|
-
let kind = null;
|
|
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) {
|
|
92
|
-
let url = '';
|
|
93
|
-
const mediaUrl = kind === 'video' ? record.video_url : record.image_url;
|
|
94
|
-
if (typeof mediaUrl === 'string') {
|
|
95
|
-
url = mediaUrl;
|
|
96
|
-
}
|
|
97
|
-
else if (mediaUrl && typeof mediaUrl === 'object' && typeof mediaUrl.url === 'string') {
|
|
98
|
-
url = mediaUrl.url;
|
|
99
|
-
}
|
|
100
|
-
else if (typeof record.url === 'string') {
|
|
101
|
-
url = record.url;
|
|
102
|
-
}
|
|
103
|
-
else if (typeof record.uri === 'string') {
|
|
104
|
-
url = record.uri;
|
|
105
|
-
}
|
|
106
|
-
else if (typeof record.data === 'string') {
|
|
107
|
-
url = record.data;
|
|
108
|
-
}
|
|
109
|
-
const trimmed = url.trim();
|
|
110
|
-
if (trimmed.length) {
|
|
111
|
-
let detail;
|
|
112
|
-
if (mediaUrl && typeof mediaUrl === 'object' && typeof mediaUrl.detail === 'string') {
|
|
113
|
-
detail = mediaUrl.detail.trim() || undefined;
|
|
114
|
-
}
|
|
115
|
-
else if (typeof record.detail === 'string') {
|
|
116
|
-
detail = record.detail.trim() || undefined;
|
|
117
|
-
}
|
|
118
|
-
media.push({ kind, url: trimmed, detail });
|
|
119
|
-
}
|
|
120
|
-
return;
|
|
121
|
-
}
|
|
122
|
-
if (Array.isArray(record.content)) {
|
|
123
|
-
visit(record.content);
|
|
124
|
-
}
|
|
125
|
-
};
|
|
126
|
-
visit(content);
|
|
127
|
-
return media;
|
|
128
|
-
}
|
|
129
|
-
function extractUserTextFromEntry(entry) {
|
|
130
|
-
if (!entry || typeof entry !== 'object')
|
|
131
|
-
return '';
|
|
132
|
-
const directContent = entry.content ?? entry.message?.content;
|
|
133
|
-
if (typeof directContent === 'string')
|
|
134
|
-
return directContent.trim();
|
|
135
|
-
if (Array.isArray(directContent)) {
|
|
136
|
-
return directContent.map(block => collectText(block)).join('').trim();
|
|
137
|
-
}
|
|
138
|
-
const text = entry.text ?? entry.message?.text;
|
|
139
|
-
if (typeof text === 'string')
|
|
140
|
-
return text.trim();
|
|
141
|
-
return '';
|
|
21
|
+
assertBridgeMessageUtilsNativeAvailable();
|
|
22
|
+
return serializeToolOutputWithNative({ output: entry?.output });
|
|
142
23
|
}
|
|
143
24
|
export function convertMessagesToBridgeInput(options) {
|
|
25
|
+
assertBridgeMessageUtilsNativeAvailable();
|
|
144
26
|
const { messages, tools } = options;
|
|
145
27
|
const native = buildBridgeHistoryWithNative({ messages, tools });
|
|
146
28
|
return native;
|
|
147
29
|
}
|
|
148
|
-
function defaultNormalizeFunctionName(raw) {
|
|
149
|
-
if (typeof raw !== 'string')
|
|
150
|
-
return undefined;
|
|
151
|
-
const trimmed = raw.trim();
|
|
152
|
-
return trimmed.length ? trimmed : undefined;
|
|
153
|
-
}
|
|
154
|
-
function toReasoningSegments(value) {
|
|
155
|
-
if (Array.isArray(value)) {
|
|
156
|
-
return value.map((entry) => (typeof entry === 'string' ? entry.trim() : '')).filter((entry) => entry.length);
|
|
157
|
-
}
|
|
158
|
-
if (typeof value === 'string') {
|
|
159
|
-
const trimmed = value.trim();
|
|
160
|
-
return trimmed.length ? [trimmed] : [];
|
|
161
|
-
}
|
|
162
|
-
return [];
|
|
163
|
-
}
|
|
164
|
-
function combineReasoningSegments(primary, secondary) {
|
|
165
|
-
const combined = [];
|
|
166
|
-
if (Array.isArray(primary)) {
|
|
167
|
-
combined.push(...primary.filter((entry) => typeof entry === 'string' && entry.trim().length).map((entry) => entry.trim()));
|
|
168
|
-
}
|
|
169
|
-
if (Array.isArray(secondary)) {
|
|
170
|
-
combined.push(...secondary.filter((entry) => typeof entry === 'string' && entry.trim().length).map((entry) => entry.trim()));
|
|
171
|
-
}
|
|
172
|
-
return combined;
|
|
173
|
-
}
|
|
174
|
-
function pushNormalizedChatMessage(target, role, rawContent, options) {
|
|
175
|
-
if (typeof rawContent !== 'string') {
|
|
176
|
-
return;
|
|
177
|
-
}
|
|
178
|
-
const normalized = normalizeChatMessageContent(rawContent);
|
|
179
|
-
const contentText = typeof normalized.contentText === 'string' ? normalized.contentText : '';
|
|
180
|
-
const reasoningText = typeof normalized.reasoningText === 'string' ? normalized.reasoningText.trim() : '';
|
|
181
|
-
const hasContent = contentText.trim().length > 0;
|
|
182
|
-
if (!hasContent && !reasoningText) {
|
|
183
|
-
return;
|
|
184
|
-
}
|
|
185
|
-
const message = {
|
|
186
|
-
role,
|
|
187
|
-
content: contentText
|
|
188
|
-
};
|
|
189
|
-
const combinedReasoning = combineReasoningSegments(reasoningText.length ? [reasoningText] : [], options?.reasoningSegments);
|
|
190
|
-
if (combinedReasoning.length) {
|
|
191
|
-
message.reasoning_content = combinedReasoning.join('\n');
|
|
192
|
-
}
|
|
193
|
-
target.push(message);
|
|
194
|
-
}
|
|
195
|
-
function processMessageBlocks(blocks, normalizeFunctionName, tools, toolNameById, lastToolCallId, toolResultFallbackText) {
|
|
196
|
-
const textParts = [];
|
|
197
|
-
const toolCalls = [];
|
|
198
|
-
const toolMessages = [];
|
|
199
|
-
let currentLastCall = lastToolCallId;
|
|
200
|
-
const reasoningSegments = [];
|
|
201
|
-
const mediaBlocks = [];
|
|
202
|
-
for (const block of blocks) {
|
|
203
|
-
if (!block || typeof block !== 'object')
|
|
204
|
-
continue;
|
|
205
|
-
const type = typeof block.type === 'string' ? block.type.toLowerCase() : '';
|
|
206
|
-
if (type === 'input_text' || type === 'output_text' || type === 'text' || type === 'commentary') {
|
|
207
|
-
if (typeof block.text === 'string')
|
|
208
|
-
textParts.push(block.text);
|
|
209
|
-
else if (typeof block.content === 'string')
|
|
210
|
-
textParts.push(block.content);
|
|
211
|
-
reasoningSegments.push(...toReasoningSegments(block.reasoning_content));
|
|
212
|
-
continue;
|
|
213
|
-
}
|
|
214
|
-
if (type === 'message' && Array.isArray(block.content)) {
|
|
215
|
-
const nested = processMessageBlocks(block.content, normalizeFunctionName, tools, toolNameById, currentLastCall, toolResultFallbackText);
|
|
216
|
-
if (nested.text)
|
|
217
|
-
textParts.push(nested.text);
|
|
218
|
-
for (const tc of nested.toolCalls)
|
|
219
|
-
toolCalls.push(tc);
|
|
220
|
-
for (const tm of nested.toolMessages)
|
|
221
|
-
toolMessages.push(tm);
|
|
222
|
-
currentLastCall = nested.lastCallId;
|
|
223
|
-
reasoningSegments.push(...nested.reasoningSegments);
|
|
224
|
-
if (nested.mediaBlocks.length)
|
|
225
|
-
mediaBlocks.push(...nested.mediaBlocks);
|
|
226
|
-
continue;
|
|
227
|
-
}
|
|
228
|
-
if (type === 'input_image' || type === 'image' || type === 'image_url') {
|
|
229
|
-
let url = '';
|
|
230
|
-
if (typeof block.image_url === 'string') {
|
|
231
|
-
url = block.image_url.trim();
|
|
232
|
-
}
|
|
233
|
-
else if (block.image_url && typeof block.image_url.url === 'string') {
|
|
234
|
-
url = block.image_url.url.trim();
|
|
235
|
-
}
|
|
236
|
-
else if (typeof block.url === 'string') {
|
|
237
|
-
url = block.url.trim();
|
|
238
|
-
}
|
|
239
|
-
if (url) {
|
|
240
|
-
const detail = typeof block.detail === 'string' && block.detail.trim()
|
|
241
|
-
? block.detail.trim()
|
|
242
|
-
: undefined;
|
|
243
|
-
mediaBlocks.push({ kind: 'image', url, detail });
|
|
244
|
-
}
|
|
245
|
-
continue;
|
|
246
|
-
}
|
|
247
|
-
if (type === 'input_video' || type === 'video' || type === 'video_url') {
|
|
248
|
-
let url = '';
|
|
249
|
-
if (typeof block.video_url === 'string') {
|
|
250
|
-
url = block.video_url.trim();
|
|
251
|
-
}
|
|
252
|
-
else if (block.video_url && typeof block.video_url.url === 'string') {
|
|
253
|
-
url = block.video_url.url.trim();
|
|
254
|
-
}
|
|
255
|
-
else if (typeof block.url === 'string') {
|
|
256
|
-
url = block.url.trim();
|
|
257
|
-
}
|
|
258
|
-
if (url) {
|
|
259
|
-
const detail = typeof block.detail === 'string' && block.detail.trim()
|
|
260
|
-
? block.detail.trim()
|
|
261
|
-
: undefined;
|
|
262
|
-
mediaBlocks.push({ kind: 'video', url, detail });
|
|
263
|
-
}
|
|
264
|
-
continue;
|
|
265
|
-
}
|
|
266
|
-
if (type === 'function_call') {
|
|
267
|
-
const rawName = typeof block.name === 'string'
|
|
268
|
-
? block.name
|
|
269
|
-
: (typeof block?.function?.name === 'string'
|
|
270
|
-
? block.function.name
|
|
271
|
-
: undefined);
|
|
272
|
-
const name = normalizeFunctionName(rawName);
|
|
273
|
-
const args = block.arguments ?? block?.function?.arguments ?? {};
|
|
274
|
-
const parsedArgs = args;
|
|
275
|
-
const callIdCandidate = (typeof block.id === 'string' && block.id.trim().length ? block.id.trim() : undefined) ??
|
|
276
|
-
(typeof block.call_id === 'string' && block.call_id.trim().length ? block.call_id.trim() : undefined);
|
|
277
|
-
const callId = callIdCandidate ??
|
|
278
|
-
normalizeFunctionCallId({
|
|
279
|
-
callId: callIdCandidate,
|
|
280
|
-
fallback: `fc_call_${toolCalls.length + 1}`
|
|
281
|
-
});
|
|
282
|
-
if (typeof name !== 'string' || !name.trim()) {
|
|
283
|
-
currentLastCall = null;
|
|
284
|
-
continue;
|
|
285
|
-
}
|
|
286
|
-
const serialized = serializeToolArguments(parsedArgs, name, tools).trim();
|
|
287
|
-
toolNameById.set(callId, name);
|
|
288
|
-
toolCalls.push({ id: callId, type: 'function', function: { name, arguments: serialized } });
|
|
289
|
-
currentLastCall = callId;
|
|
290
|
-
continue;
|
|
291
|
-
}
|
|
292
|
-
if (type === 'function_call_output' || type === 'tool_result' || type === 'tool_message') {
|
|
293
|
-
let toolCallId = block.tool_call_id ||
|
|
294
|
-
block.call_id ||
|
|
295
|
-
block.tool_use_id ||
|
|
296
|
-
block.id ||
|
|
297
|
-
currentLastCall;
|
|
298
|
-
toolCallId = typeof toolCallId === 'string' && toolCallId.trim().length ? toolCallId.trim() : currentLastCall;
|
|
299
|
-
const output = serializeToolOutput(block);
|
|
300
|
-
if (toolCallId) {
|
|
301
|
-
try {
|
|
302
|
-
let contentStr = output != null ? String(output) : '';
|
|
303
|
-
if (!contentStr || contentStr.trim().length === 0) {
|
|
304
|
-
contentStr = toolResultFallbackText;
|
|
305
|
-
}
|
|
306
|
-
const nm = toolNameById.get(String(toolCallId));
|
|
307
|
-
const toolMsg = { role: 'tool', tool_call_id: String(toolCallId), content: contentStr };
|
|
308
|
-
if (typeof nm === 'string' && nm.trim().length)
|
|
309
|
-
toolMsg.name = nm;
|
|
310
|
-
toolMessages.push(toolMsg);
|
|
311
|
-
}
|
|
312
|
-
catch {
|
|
313
|
-
const fallback = (output ?? toolResultFallbackText);
|
|
314
|
-
const nm = toolNameById.get(String(toolCallId));
|
|
315
|
-
const toolMsg = { role: 'tool', tool_call_id: String(toolCallId), content: String(fallback) };
|
|
316
|
-
if (typeof nm === 'string' && nm.trim().length)
|
|
317
|
-
toolMsg.name = nm;
|
|
318
|
-
toolMessages.push(toolMsg);
|
|
319
|
-
}
|
|
320
|
-
currentLastCall = null;
|
|
321
|
-
}
|
|
322
|
-
continue;
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
const text = textParts.length ? textParts.join('\n').trim() : null;
|
|
326
|
-
return { text, mediaBlocks, toolCalls, toolMessages, lastCallId: currentLastCall, reasoningSegments };
|
|
327
|
-
}
|
|
328
30
|
export function convertBridgeInputToChatMessages(options) {
|
|
31
|
+
assertBridgeMessageUtilsNativeAvailable();
|
|
329
32
|
const { input, tools, normalizeFunctionName, toolResultFallbackText } = options;
|
|
330
|
-
const
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
for (let entryIndex = 0; entryIndex < input.length; entryIndex++) {
|
|
338
|
-
const entry = input[entryIndex];
|
|
339
|
-
if (!entry || typeof entry !== 'object')
|
|
340
|
-
continue;
|
|
341
|
-
const entryType = typeof entry.type === 'string' ? entry.type.toLowerCase() : 'message';
|
|
342
|
-
const entryReasoningSegments = toReasoningSegments(entry.reasoning_content);
|
|
343
|
-
let entryReasoningConsumed = false;
|
|
344
|
-
const consumeEntryReasoning = () => {
|
|
345
|
-
if (entryReasoningConsumed || !entryReasoningSegments.length) {
|
|
346
|
-
return undefined;
|
|
347
|
-
}
|
|
348
|
-
entryReasoningConsumed = true;
|
|
349
|
-
return entryReasoningSegments;
|
|
350
|
-
};
|
|
351
|
-
if (typeof entry.content === 'string') {
|
|
352
|
-
const normalizedRole = coerceBridgeRole(entry.role || 'user');
|
|
353
|
-
const directText = (entry.content || '').toString();
|
|
354
|
-
pushNormalizedChatMessage(messages, normalizedRole, directText, {
|
|
355
|
-
reasoningSegments: consumeEntryReasoning()
|
|
356
|
-
});
|
|
357
|
-
continue;
|
|
358
|
-
}
|
|
359
|
-
if (entryType === 'function_call' || entryType === 'tool_call') {
|
|
360
|
-
const rawName = typeof entry.name === 'string'
|
|
361
|
-
? entry.name
|
|
362
|
-
: (typeof entry?.function?.name === 'string' ? entry.function.name : undefined);
|
|
363
|
-
const name = resolveFunctionName(rawName);
|
|
364
|
-
if (typeof name !== 'string' || !name.trim()) {
|
|
365
|
-
continue;
|
|
366
|
-
}
|
|
367
|
-
const args = entry.arguments ?? entry?.function?.arguments ?? {};
|
|
368
|
-
const parsedArgs = args;
|
|
369
|
-
const callIdRaw = typeof entry.id === 'string' ? entry.id : (typeof entry.call_id === 'string' ? entry.call_id : undefined);
|
|
370
|
-
const callIdSource = typeof callIdRaw === 'string' && callIdRaw.trim().length ? callIdRaw.trim() : undefined;
|
|
371
|
-
let callId = callIdSource;
|
|
372
|
-
if (!callId) {
|
|
373
|
-
callId = normalizeFunctionCallId({
|
|
374
|
-
callId: callIdSource,
|
|
375
|
-
fallback: `fc_call_${messages.length + 1}`
|
|
376
|
-
});
|
|
377
|
-
}
|
|
378
|
-
const serialized = serializeToolArguments(parsedArgs, name, tools).trim();
|
|
379
|
-
toolNameById.set(callId, name);
|
|
380
|
-
const toolCall = {
|
|
381
|
-
id: callId,
|
|
382
|
-
call_id: callId,
|
|
383
|
-
tool_call_id: callId,
|
|
384
|
-
type: 'function',
|
|
385
|
-
function: { name, arguments: serialized }
|
|
386
|
-
};
|
|
387
|
-
messages.push({
|
|
388
|
-
role: 'assistant',
|
|
389
|
-
content: '',
|
|
390
|
-
tool_calls: [toolCall]
|
|
391
|
-
});
|
|
392
|
-
lastToolCallId = callId;
|
|
393
|
-
continue;
|
|
394
|
-
}
|
|
395
|
-
if (entryType === 'function_call_output' || entryType === 'tool_result' || entryType === 'tool_message') {
|
|
396
|
-
let toolCallId = entry.tool_call_id ||
|
|
397
|
-
entry.call_id ||
|
|
398
|
-
entry.tool_use_id ||
|
|
399
|
-
entry.id ||
|
|
400
|
-
lastToolCallId;
|
|
401
|
-
toolCallId = typeof toolCallId === 'string' && toolCallId.trim().length ? toolCallId.trim() : (lastToolCallId ?? undefined);
|
|
402
|
-
const output = serializeToolOutput(entry);
|
|
403
|
-
if (toolCallId) {
|
|
404
|
-
try {
|
|
405
|
-
let contentStr = output != null ? String(output) : '';
|
|
406
|
-
if (!contentStr || contentStr.trim().length === 0) {
|
|
407
|
-
contentStr = fallbackText;
|
|
408
|
-
}
|
|
409
|
-
const nm = toolNameById.get(String(toolCallId));
|
|
410
|
-
const toolMsg = {
|
|
411
|
-
role: 'tool',
|
|
412
|
-
tool_call_id: String(toolCallId),
|
|
413
|
-
id: String(toolCallId),
|
|
414
|
-
content: contentStr
|
|
415
|
-
};
|
|
416
|
-
if (typeof nm === 'string' && nm.trim().length)
|
|
417
|
-
toolMsg.name = nm;
|
|
418
|
-
messages.push(toolMsg);
|
|
419
|
-
}
|
|
420
|
-
catch {
|
|
421
|
-
const fallback = (output ?? fallbackText);
|
|
422
|
-
const nm = toolNameById.get(String(toolCallId));
|
|
423
|
-
const toolMsg = {
|
|
424
|
-
role: 'tool',
|
|
425
|
-
tool_call_id: String(toolCallId),
|
|
426
|
-
id: String(toolCallId),
|
|
427
|
-
content: String(fallback)
|
|
428
|
-
};
|
|
429
|
-
if (typeof nm === 'string' && nm.trim().length)
|
|
430
|
-
toolMsg.name = nm;
|
|
431
|
-
messages.push(toolMsg);
|
|
432
|
-
}
|
|
433
|
-
lastToolCallId = null;
|
|
434
|
-
}
|
|
435
|
-
continue;
|
|
436
|
-
}
|
|
437
|
-
let handledViaExplicitMessage = false;
|
|
438
|
-
if (entry && typeof entry.message === 'object' && Array.isArray(entry.message?.content)) {
|
|
439
|
-
const explicit = entry.message;
|
|
440
|
-
const nested = processMessageBlocks(Array.isArray(explicit.content) ? explicit.content : [], resolveFunctionName, tools, toolNameById, lastToolCallId, fallbackText);
|
|
441
|
-
if (nested.toolCalls.length) {
|
|
442
|
-
nested.toolCalls.forEach((call, idx) => ensureAssistantToolCallIdentity(call, `fc_call_${messages.length + idx + 1}`));
|
|
443
|
-
messages.push({
|
|
444
|
-
role: 'assistant',
|
|
445
|
-
content: '',
|
|
446
|
-
tool_calls: nested.toolCalls
|
|
447
|
-
});
|
|
448
|
-
}
|
|
449
|
-
for (const msg of nested.toolMessages)
|
|
450
|
-
messages.push(msg);
|
|
451
|
-
const normalizedRole = coerceBridgeRole((explicit.role ?? entry.role) || 'user');
|
|
452
|
-
if (nested.mediaBlocks.length) {
|
|
453
|
-
const contentBlocks = [];
|
|
454
|
-
if (typeof nested.text === 'string' && nested.text.trim().length) {
|
|
455
|
-
contentBlocks.push({ type: 'text', text: nested.text });
|
|
456
|
-
}
|
|
457
|
-
for (const media of nested.mediaBlocks) {
|
|
458
|
-
const mediaBlock = media.kind === 'video'
|
|
459
|
-
? { type: 'video_url', video_url: { url: media.url } }
|
|
460
|
-
: { type: 'image_url', image_url: { url: media.url } };
|
|
461
|
-
if (media.detail) {
|
|
462
|
-
const key = media.kind === 'video' ? 'video_url' : 'image_url';
|
|
463
|
-
mediaBlock[key].detail = media.detail;
|
|
464
|
-
}
|
|
465
|
-
contentBlocks.push(mediaBlock);
|
|
466
|
-
}
|
|
467
|
-
const msg = {
|
|
468
|
-
role: normalizedRole,
|
|
469
|
-
content: contentBlocks
|
|
470
|
-
};
|
|
471
|
-
const combinedReasoning = combineReasoningSegments(consumeEntryReasoning(), nested.reasoningSegments);
|
|
472
|
-
if (combinedReasoning.length) {
|
|
473
|
-
msg.reasoning_content = combinedReasoning.join('\n');
|
|
474
|
-
}
|
|
475
|
-
messages.push(msg);
|
|
476
|
-
}
|
|
477
|
-
else if (typeof nested.text === 'string') {
|
|
478
|
-
pushNormalizedChatMessage(messages, normalizedRole, nested.text, {
|
|
479
|
-
reasoningSegments: combineReasoningSegments(consumeEntryReasoning(), nested.reasoningSegments)
|
|
480
|
-
});
|
|
481
|
-
}
|
|
482
|
-
lastToolCallId = nested.lastCallId;
|
|
483
|
-
handledViaExplicitMessage = true;
|
|
484
|
-
}
|
|
485
|
-
if (!handledViaExplicitMessage) {
|
|
486
|
-
const nested = processMessageBlocks(Array.isArray(entry.content) ? entry.content : [], resolveFunctionName, tools, toolNameById, lastToolCallId, fallbackText);
|
|
487
|
-
if (nested.toolCalls.length) {
|
|
488
|
-
nested.toolCalls.forEach((call, idx) => ensureAssistantToolCallIdentity(call, `fc_call_${messages.length + idx + 1}`));
|
|
489
|
-
messages.push({
|
|
490
|
-
role: 'assistant',
|
|
491
|
-
content: '',
|
|
492
|
-
tool_calls: nested.toolCalls
|
|
493
|
-
});
|
|
494
|
-
}
|
|
495
|
-
for (const msg of nested.toolMessages)
|
|
496
|
-
messages.push(msg);
|
|
497
|
-
const normalizedRole = coerceBridgeRole(entry.role || 'user');
|
|
498
|
-
if (nested.mediaBlocks.length) {
|
|
499
|
-
const contentBlocks = [];
|
|
500
|
-
if (typeof nested.text === 'string' && nested.text.trim().length) {
|
|
501
|
-
contentBlocks.push({ type: 'text', text: nested.text });
|
|
502
|
-
}
|
|
503
|
-
for (const media of nested.mediaBlocks) {
|
|
504
|
-
const mediaBlock = media.kind === 'video'
|
|
505
|
-
? { type: 'video_url', video_url: { url: media.url } }
|
|
506
|
-
: { type: 'image_url', image_url: { url: media.url } };
|
|
507
|
-
if (media.detail) {
|
|
508
|
-
const key = media.kind === 'video' ? 'video_url' : 'image_url';
|
|
509
|
-
mediaBlock[key].detail = media.detail;
|
|
510
|
-
}
|
|
511
|
-
contentBlocks.push(mediaBlock);
|
|
512
|
-
}
|
|
513
|
-
const msg = {
|
|
514
|
-
role: normalizedRole,
|
|
515
|
-
content: contentBlocks
|
|
516
|
-
};
|
|
517
|
-
const combinedReasoning = combineReasoningSegments(consumeEntryReasoning(), nested.reasoningSegments);
|
|
518
|
-
if (combinedReasoning.length) {
|
|
519
|
-
msg.reasoning_content = combinedReasoning.join('\n');
|
|
520
|
-
}
|
|
521
|
-
messages.push(msg);
|
|
522
|
-
}
|
|
523
|
-
else if (typeof nested.text === 'string') {
|
|
524
|
-
pushNormalizedChatMessage(messages, normalizedRole, nested.text, {
|
|
525
|
-
reasoningSegments: consumeEntryReasoning()
|
|
526
|
-
});
|
|
527
|
-
}
|
|
528
|
-
lastToolCallId = nested.lastCallId;
|
|
529
|
-
}
|
|
530
|
-
try {
|
|
531
|
-
const t = String(entry.type || '').toLowerCase();
|
|
532
|
-
if ((t === 'input_text' || t === 'text' || t === 'output_text' || t === 'commentary') &&
|
|
533
|
-
typeof entry.text === 'string') {
|
|
534
|
-
const normalizedRole = coerceBridgeRole(entry.role || 'user');
|
|
535
|
-
const s = entry.text;
|
|
536
|
-
if (s && s.length) {
|
|
537
|
-
pushNormalizedChatMessage(messages, normalizedRole, s, {
|
|
538
|
-
reasoningSegments: consumeEntryReasoning()
|
|
539
|
-
});
|
|
540
|
-
}
|
|
541
|
-
}
|
|
542
|
-
}
|
|
543
|
-
catch {
|
|
544
|
-
/* ignore */
|
|
545
|
-
}
|
|
546
|
-
}
|
|
547
|
-
return messages;
|
|
33
|
+
const output = convertBridgeInputToChatMessagesWithNative({
|
|
34
|
+
input: Array.isArray(input) ? input : [],
|
|
35
|
+
tools,
|
|
36
|
+
toolResultFallbackText,
|
|
37
|
+
normalizeFunctionName: typeof normalizeFunctionName === 'string' ? normalizeFunctionName : undefined
|
|
38
|
+
});
|
|
39
|
+
return output.messages;
|
|
548
40
|
}
|
|
549
41
|
export function ensureMessagesArray(state) {
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
state.messages = [];
|
|
554
|
-
return state.messages;
|
|
42
|
+
assertBridgeMessageUtilsNativeAvailable();
|
|
43
|
+
const output = ensureMessagesArrayWithNative({ state });
|
|
44
|
+
return output.messages;
|
|
555
45
|
}
|
|
@@ -1,15 +1,2 @@
|
|
|
1
1
|
import type { JsonObject } from '../../hub/types/json.js';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Compat for Claude models routed via antigravity on gemini-chat.
|
|
5
|
-
*
|
|
6
|
-
* Anthropic requires tools[*].custom.input_schema to be valid JSON Schema draft 2020-12.
|
|
7
|
-
* We currently send OpenAI-style parameters which may not fully conform, causing upstream
|
|
8
|
-
* invalid_request_error on tools.N.custom.input_schema.
|
|
9
|
-
*
|
|
10
|
-
* For safety, when we detect the antigravity.*.claude-* path over gemini-chat,
|
|
11
|
-
* we aggressively simplify Gemini functionDeclarations[*].parameters to a minimal
|
|
12
|
-
* but valid object schema, letting RouteCodex govern tool semantics while keeping
|
|
13
|
-
* Anthropic's schema validator happy.
|
|
14
|
-
*/
|
|
15
|
-
export declare function applyClaudeThinkingToolSchemaCompat(payload: JsonObject, adapterContext?: AdapterContext): JsonObject;
|
|
2
|
+
export declare function applyClaudeThinkingToolSchemaCompat(payload: JsonObject): JsonObject;
|