@jsonstudio/llms 0.4.6 → 0.6.0
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/codecs/anthropic-openai-codec.js +28 -2
- package/dist/conversion/codecs/gemini-openai-codec.js +23 -0
- package/dist/conversion/codecs/responses-openai-codec.js +8 -1
- package/dist/conversion/hub/node-support.js +14 -1
- package/dist/conversion/hub/pipeline/hub-pipeline.d.ts +66 -0
- package/dist/conversion/hub/pipeline/hub-pipeline.js +284 -193
- package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage1_format_parse/index.d.ts +11 -0
- package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage1_format_parse/index.js +6 -0
- package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage2_semantic_map/index.d.ts +16 -0
- package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage2_semantic_map/index.js +17 -0
- package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage3_context_capture/context-factories.d.ts +5 -0
- package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage3_context_capture/context-factories.js +17 -0
- package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage3_context_capture/index.d.ts +19 -0
- package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage3_context_capture/index.js +269 -0
- package/dist/conversion/hub/pipeline/stages/req_outbound/req_outbound_stage1_semantic_map/index.d.ts +18 -0
- package/dist/conversion/hub/pipeline/stages/req_outbound/req_outbound_stage1_semantic_map/index.js +141 -0
- package/dist/conversion/hub/pipeline/stages/req_outbound/req_outbound_stage2_format_build/index.d.ts +11 -0
- package/dist/conversion/hub/pipeline/stages/req_outbound/req_outbound_stage2_format_build/index.js +29 -0
- package/dist/conversion/hub/pipeline/stages/req_process/req_process_stage1_tool_governance/index.d.ts +16 -0
- package/dist/conversion/hub/pipeline/stages/req_process/req_process_stage1_tool_governance/index.js +15 -0
- package/dist/conversion/hub/pipeline/stages/req_process/req_process_stage2_route_select/index.d.ts +17 -0
- package/dist/conversion/hub/pipeline/stages/req_process/req_process_stage2_route_select/index.js +18 -0
- package/dist/conversion/hub/pipeline/stages/resp_inbound/resp_inbound_stage1_sse_decode/index.d.ts +17 -0
- package/dist/conversion/hub/pipeline/stages/resp_inbound/resp_inbound_stage1_sse_decode/index.js +63 -0
- package/dist/conversion/hub/pipeline/stages/resp_inbound/resp_inbound_stage2_format_parse/index.d.ts +11 -0
- package/dist/conversion/hub/pipeline/stages/resp_inbound/resp_inbound_stage2_format_parse/index.js +6 -0
- package/dist/conversion/hub/pipeline/stages/resp_inbound/resp_inbound_stage3_semantic_map/index.d.ts +12 -0
- package/dist/conversion/hub/pipeline/stages/resp_inbound/resp_inbound_stage3_semantic_map/index.js +6 -0
- package/dist/conversion/hub/pipeline/stages/resp_outbound/resp_outbound_stage1_client_remap/index.d.ts +13 -0
- package/dist/conversion/hub/pipeline/stages/resp_outbound/resp_outbound_stage1_client_remap/index.js +43 -0
- package/dist/conversion/hub/pipeline/stages/resp_outbound/resp_outbound_stage2_sse_stream/index.d.ts +17 -0
- package/dist/conversion/hub/pipeline/stages/resp_outbound/resp_outbound_stage2_sse_stream/index.js +22 -0
- package/dist/conversion/hub/pipeline/stages/resp_process/resp_process_stage1_tool_governance/index.d.ts +16 -0
- package/dist/conversion/hub/pipeline/stages/resp_process/resp_process_stage1_tool_governance/index.js +19 -0
- package/dist/conversion/hub/pipeline/stages/resp_process/resp_process_stage2_finalize/index.d.ts +17 -0
- package/dist/conversion/hub/pipeline/stages/resp_process/resp_process_stage2_finalize/index.js +19 -0
- package/dist/conversion/hub/pipeline/stages/utils.d.ts +2 -0
- package/dist/conversion/hub/pipeline/stages/utils.js +11 -0
- package/dist/conversion/hub/pipeline/target-utils.d.ts +5 -0
- package/dist/conversion/hub/pipeline/target-utils.js +87 -0
- package/dist/conversion/hub/process/chat-process.js +11 -11
- package/dist/conversion/hub/response/provider-response.js +69 -122
- package/dist/conversion/hub/response/response-mappers.d.ts +19 -0
- package/dist/conversion/hub/response/response-mappers.js +22 -2
- package/dist/conversion/hub/response/response-runtime.d.ts +8 -0
- package/dist/conversion/hub/response/response-runtime.js +239 -6
- package/dist/conversion/hub/semantic-mappers/anthropic-mapper.d.ts +8 -0
- package/dist/conversion/hub/semantic-mappers/anthropic-mapper.js +119 -59
- package/dist/conversion/hub/semantic-mappers/chat-mapper.js +74 -13
- package/dist/conversion/hub/semantic-mappers/gemini-mapper.js +0 -9
- package/dist/conversion/hub/semantic-mappers/responses-mapper.js +16 -13
- package/dist/conversion/hub/snapshot-recorder.d.ts +13 -0
- package/dist/conversion/hub/snapshot-recorder.js +90 -50
- package/dist/conversion/hub/standardized-bridge.js +44 -30
- package/dist/conversion/hub/types/chat-envelope.d.ts +68 -0
- package/dist/conversion/hub/types/standardized.d.ts +97 -0
- package/dist/conversion/pipeline/codecs/v2/anthropic-openai-pipeline.js +29 -2
- package/dist/conversion/pipeline/codecs/v2/responses-openai-pipeline.js +68 -1
- package/dist/conversion/responses/responses-openai-bridge.d.ts +6 -1
- package/dist/conversion/responses/responses-openai-bridge.js +132 -6
- package/dist/conversion/shared/anthropic-message-utils.d.ts +9 -1
- package/dist/conversion/shared/anthropic-message-utils.js +334 -14
- package/dist/conversion/shared/bridge-actions.js +267 -40
- package/dist/conversion/shared/bridge-message-utils.js +54 -8
- package/dist/conversion/shared/bridge-policies.js +29 -4
- package/dist/conversion/shared/chat-envelope-validator.d.ts +8 -0
- package/dist/conversion/shared/chat-envelope-validator.js +128 -0
- package/dist/conversion/shared/chat-request-filters.js +108 -25
- package/dist/conversion/shared/mcp-injection.js +41 -20
- package/dist/conversion/shared/openai-finalizer.d.ts +11 -0
- package/dist/conversion/shared/openai-finalizer.js +73 -0
- package/dist/conversion/shared/openai-message-normalize.js +32 -31
- package/dist/conversion/shared/reasoning-normalizer.d.ts +1 -0
- package/dist/conversion/shared/reasoning-normalizer.js +50 -18
- package/dist/conversion/shared/responses-output-builder.d.ts +1 -1
- package/dist/conversion/shared/responses-output-builder.js +76 -25
- package/dist/conversion/shared/responses-reasoning-registry.d.ts +8 -0
- package/dist/conversion/shared/responses-reasoning-registry.js +61 -0
- package/dist/conversion/shared/responses-response-utils.js +32 -2
- package/dist/conversion/shared/responses-tool-utils.js +28 -2
- package/dist/conversion/shared/snapshot-hooks.d.ts +9 -0
- package/dist/conversion/shared/snapshot-hooks.js +60 -6
- package/dist/conversion/shared/snapshot-utils.d.ts +16 -0
- package/dist/conversion/shared/snapshot-utils.js +84 -0
- package/dist/conversion/shared/tool-filter-pipeline.js +45 -5
- package/dist/conversion/shared/tool-mapping.js +13 -2
- package/dist/filters/special/request-tool-choice-policy.js +3 -1
- package/dist/filters/special/request-tool-list-filter.d.ts +11 -0
- package/dist/filters/special/request-tool-list-filter.js +20 -7
- package/dist/sse/shared/responses-output-normalizer.js +5 -4
- package/package.json +1 -1
|
@@ -14,6 +14,23 @@ function assertJsonObject(value, stage) {
|
|
|
14
14
|
}
|
|
15
15
|
return value;
|
|
16
16
|
}
|
|
17
|
+
function coerceAliasMap(candidate) {
|
|
18
|
+
if (!candidate || typeof candidate !== 'object' || Array.isArray(candidate)) {
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
let populated = false;
|
|
22
|
+
const result = {};
|
|
23
|
+
for (const [key, value] of Object.entries(candidate)) {
|
|
24
|
+
if (typeof key !== 'string' || typeof value !== 'string')
|
|
25
|
+
continue;
|
|
26
|
+
const trimmedKey = key.trim();
|
|
27
|
+
if (!trimmedKey.length)
|
|
28
|
+
continue;
|
|
29
|
+
result[trimmedKey] = value;
|
|
30
|
+
populated = true;
|
|
31
|
+
}
|
|
32
|
+
return populated ? result : undefined;
|
|
33
|
+
}
|
|
17
34
|
function createAnthropicHooks() {
|
|
18
35
|
const formatAdapter = new AnthropicFormatAdapter();
|
|
19
36
|
const semanticMapper = new AnthropicSemanticMapper();
|
|
@@ -28,6 +45,12 @@ function createAnthropicHooks() {
|
|
|
28
45
|
});
|
|
29
46
|
const formatEnvelope = await formatAdapter.parseRequest(wire, adapterContext);
|
|
30
47
|
const chatEnvelope = await semanticMapper.toChat(formatEnvelope, adapterContext);
|
|
48
|
+
const aliasMap = coerceAliasMap(adapterContext.anthropicToolNameMap) ??
|
|
49
|
+
coerceAliasMap(chatEnvelope.metadata?.anthropicToolNameMap);
|
|
50
|
+
if (aliasMap) {
|
|
51
|
+
context.metadata = context.metadata ?? {};
|
|
52
|
+
context.metadata.anthropicToolNameMap = aliasMap;
|
|
53
|
+
}
|
|
31
54
|
const canonical = chatEnvelopeToStandardized(chatEnvelope, {
|
|
32
55
|
adapterContext,
|
|
33
56
|
endpoint: context.entryEndpoint ?? DEFAULT_ANTHROPIC_ENDPOINT,
|
|
@@ -37,8 +60,12 @@ function createAnthropicHooks() {
|
|
|
37
60
|
}
|
|
38
61
|
},
|
|
39
62
|
outbound: {
|
|
40
|
-
serialize: async ({ canonical }) => {
|
|
41
|
-
const
|
|
63
|
+
serialize: async ({ canonical, context }) => {
|
|
64
|
+
const aliasMap = coerceAliasMap(context.metadata?.anthropicToolNameMap);
|
|
65
|
+
const anthropicPayload = buildAnthropicFromOpenAIChat(canonical, {
|
|
66
|
+
toolNameMap: aliasMap,
|
|
67
|
+
requestId: context.requestId
|
|
68
|
+
});
|
|
42
69
|
return { payload: assertJsonObject(anthropicPayload, 'anthropic_outbound_serialize') };
|
|
43
70
|
}
|
|
44
71
|
}
|
|
@@ -14,6 +14,71 @@ function assertJsonObject(value, stage) {
|
|
|
14
14
|
}
|
|
15
15
|
return value;
|
|
16
16
|
}
|
|
17
|
+
function sanitizeResponsesMessages(payload) {
|
|
18
|
+
const messages = Array.isArray(payload?.messages) ? payload.messages : [];
|
|
19
|
+
if (!messages.length)
|
|
20
|
+
return;
|
|
21
|
+
const sanitized = [];
|
|
22
|
+
let counter = 0;
|
|
23
|
+
const normalizeId = (raw) => {
|
|
24
|
+
if (typeof raw !== 'string')
|
|
25
|
+
return undefined;
|
|
26
|
+
const trimmed = raw.trim();
|
|
27
|
+
if (!trimmed.length)
|
|
28
|
+
return undefined;
|
|
29
|
+
if (trimmed.startsWith('fc_'))
|
|
30
|
+
return trimmed;
|
|
31
|
+
const stripped = trimmed.replace(/^call[_-]?/i, '');
|
|
32
|
+
const normalized = stripped.length ? stripped : trimmed;
|
|
33
|
+
return normalized.startsWith('fc_') ? normalized : `fc_${normalized}`;
|
|
34
|
+
};
|
|
35
|
+
for (const message of messages) {
|
|
36
|
+
if (!message || typeof message !== 'object')
|
|
37
|
+
continue;
|
|
38
|
+
const role = String(message.role || '').toLowerCase();
|
|
39
|
+
if (role === 'assistant' && Array.isArray(message.tool_calls) && message.tool_calls.length) {
|
|
40
|
+
message.tool_calls = message.tool_calls.map((call) => {
|
|
41
|
+
if (!call || typeof call !== 'object')
|
|
42
|
+
return call;
|
|
43
|
+
const existing = normalizeId(call.id) ?? normalizeId(call.call_id) ?? `fc_function_call_${counter++}`;
|
|
44
|
+
if (existing) {
|
|
45
|
+
call.id = existing;
|
|
46
|
+
}
|
|
47
|
+
if (call.call_id !== undefined)
|
|
48
|
+
delete call.call_id;
|
|
49
|
+
if (call.tool_call_id !== undefined)
|
|
50
|
+
delete call.tool_call_id;
|
|
51
|
+
return call;
|
|
52
|
+
});
|
|
53
|
+
sanitized.push(message);
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
if (role === 'tool') {
|
|
57
|
+
const clone = { ...message };
|
|
58
|
+
const normalizedToolId = normalizeId(clone.tool_call_id ?? clone.call_id);
|
|
59
|
+
if (normalizedToolId) {
|
|
60
|
+
clone.tool_call_id = normalizedToolId;
|
|
61
|
+
}
|
|
62
|
+
else if (typeof clone.tool_call_id === 'string') {
|
|
63
|
+
const trimmed = clone.tool_call_id.trim();
|
|
64
|
+
if (!trimmed.length) {
|
|
65
|
+
delete clone.tool_call_id;
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
clone.tool_call_id = trimmed;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
if ('call_id' in clone)
|
|
72
|
+
delete clone.call_id;
|
|
73
|
+
if ('id' in clone)
|
|
74
|
+
delete clone.id;
|
|
75
|
+
sanitized.push(clone);
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
sanitized.push(message);
|
|
79
|
+
}
|
|
80
|
+
payload.messages = sanitized;
|
|
81
|
+
}
|
|
17
82
|
function cloneResponsesContext(context) {
|
|
18
83
|
try {
|
|
19
84
|
return JSON.parse(JSON.stringify(context ?? {}));
|
|
@@ -143,7 +208,9 @@ export class ResponsesOpenAIPipelineCodec {
|
|
|
143
208
|
entryEndpoint: context.entryEndpoint ?? DEFAULT_RESPONSES_ENDPOINT,
|
|
144
209
|
endpoint: context.endpoint ?? DEFAULT_RESPONSES_ENDPOINT
|
|
145
210
|
};
|
|
146
|
-
|
|
211
|
+
const filtered = await runStandardChatRequestFilters(openaiPayload, profile, filterContext);
|
|
212
|
+
sanitizeResponsesMessages(filtered);
|
|
213
|
+
return filtered;
|
|
147
214
|
}
|
|
148
215
|
async convertResponse(payload, profile, context) {
|
|
149
216
|
this.ensureInitialized();
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type { BridgeInputItem, BridgeToolDefinition } from '../shared/bridge-message-types.js';
|
|
2
2
|
import type { ChatToolDefinition } from '../hub/types/chat-envelope.js';
|
|
3
3
|
import type { BridgeInputBuildResult } from '../shared/bridge-message-utils.js';
|
|
4
|
-
|
|
4
|
+
import type { ToolCallIdStyle } from '../shared/responses-tool-utils.js';
|
|
5
|
+
type Unknown = Record<string, unknown>;
|
|
6
|
+
export interface ResponsesRequestContext extends Unknown {
|
|
5
7
|
requestId?: string;
|
|
6
8
|
originalSystemMessages?: string[];
|
|
7
9
|
input?: BridgeInputItem[];
|
|
@@ -24,6 +26,9 @@ export interface ResponsesRequestContext {
|
|
|
24
26
|
} | null;
|
|
25
27
|
toolsRaw?: BridgeToolDefinition[];
|
|
26
28
|
toolsNormalized?: Array<Record<string, unknown>>;
|
|
29
|
+
parameters?: Record<string, unknown>;
|
|
30
|
+
systemInstruction?: string;
|
|
31
|
+
toolCallIdStyle?: ToolCallIdStyle;
|
|
27
32
|
}
|
|
28
33
|
export interface BuildChatRequestResult {
|
|
29
34
|
request: Record<string, unknown>;
|
|
@@ -17,10 +17,11 @@ function isObject(v) {
|
|
|
17
17
|
// NOTE: 自修复提示已移除(统一标准:不做模糊兜底)。
|
|
18
18
|
// --- Public bridge functions ---
|
|
19
19
|
export function captureResponsesContext(payload, dto) {
|
|
20
|
+
const preservedInput = cloneBridgeEntries(payload.input);
|
|
20
21
|
ensureBridgeInstructions(payload);
|
|
21
22
|
const context = {
|
|
22
23
|
requestId: dto?.route?.requestId,
|
|
23
|
-
input:
|
|
24
|
+
input: preservedInput,
|
|
24
25
|
include: payload.include,
|
|
25
26
|
store: payload.store,
|
|
26
27
|
toolChoice: payload.tool_choice,
|
|
@@ -30,8 +31,14 @@ export function captureResponsesContext(payload, dto) {
|
|
|
30
31
|
stream: typeof payload.stream === 'boolean' ? payload.stream : undefined,
|
|
31
32
|
isChatPayload: Array.isArray(payload.messages)
|
|
32
33
|
};
|
|
34
|
+
if (payload.parameters && typeof payload.parameters === 'object') {
|
|
35
|
+
context.parameters = { ...payload.parameters };
|
|
36
|
+
}
|
|
37
|
+
if (typeof payload.instructions === 'string' && payload.instructions.trim().length) {
|
|
38
|
+
context.systemInstruction = payload.instructions;
|
|
39
|
+
}
|
|
33
40
|
if (Array.isArray(payload.tools)) {
|
|
34
|
-
context.toolsRaw = payload.tools;
|
|
41
|
+
context.toolsRaw = cloneBridgeEntries(payload.tools);
|
|
35
42
|
}
|
|
36
43
|
context.isResponsesPayload = !context.isChatPayload && Array.isArray(context.input);
|
|
37
44
|
return context;
|
|
@@ -193,8 +200,21 @@ export function buildResponsesRequestFromChat(payload, ctx, extras) {
|
|
|
193
200
|
// ignore policy errors
|
|
194
201
|
}
|
|
195
202
|
const envelopeMetadata = ctx?.metadata && typeof ctx.metadata === 'object' ? ctx.metadata : undefined;
|
|
196
|
-
const
|
|
197
|
-
const
|
|
203
|
+
const metadataExtraFields = extractMetadataExtraFields(envelopeMetadata);
|
|
204
|
+
const contextToolCallIdStyle = readToolCallIdStyleFromContext(ctx);
|
|
205
|
+
const toolCallIdStyle = contextToolCallIdStyle ?? resolveToolCallIdStyle(envelopeMetadata);
|
|
206
|
+
const fallbackHistory = ctx?.input && Array.isArray(ctx.input)
|
|
207
|
+
? {
|
|
208
|
+
input: ctx.input,
|
|
209
|
+
originalSystemMessages: ctx.originalSystemMessages,
|
|
210
|
+
combinedSystemInstruction: ctx.systemInstruction
|
|
211
|
+
}
|
|
212
|
+
: undefined;
|
|
213
|
+
const historySeed = normalizeBridgeHistory(extras?.bridgeHistory) ??
|
|
214
|
+
normalizeBridgeHistory(fallbackHistory) ??
|
|
215
|
+
normalizeBridgeHistory(bridgeMetadata?.bridgeHistory) ??
|
|
216
|
+
normalizeBridgeHistory(envelopeMetadata?.bridgeHistory) ??
|
|
217
|
+
fallbackHistory;
|
|
198
218
|
const history = historySeed ??
|
|
199
219
|
convertMessagesToBridgeInput({
|
|
200
220
|
messages,
|
|
@@ -206,6 +226,7 @@ export function buildResponsesRequestFromChat(payload, ctx, extras) {
|
|
|
206
226
|
}
|
|
207
227
|
const { input, combinedSystemInstruction, originalSystemMessages } = history;
|
|
208
228
|
const instructionCandidates = [
|
|
229
|
+
typeof ctx?.systemInstruction === 'string' && ctx.systemInstruction.trim().length ? ctx.systemInstruction.trim() : undefined,
|
|
209
230
|
typeof extras?.systemInstruction === 'string' && extras.systemInstruction.trim().length ? extras.systemInstruction.trim() : undefined,
|
|
210
231
|
typeof envelopeMetadata?.systemInstruction === 'string' && envelopeMetadata.systemInstruction.trim().length ? envelopeMetadata.systemInstruction.trim() : undefined,
|
|
211
232
|
combinedSystemInstruction && combinedSystemInstruction.length > 0 ? combinedSystemInstruction : undefined
|
|
@@ -233,9 +254,112 @@ export function buildResponsesRequestFromChat(payload, ctx, extras) {
|
|
|
233
254
|
else if (resolvedStream === false) {
|
|
234
255
|
out.stream = false;
|
|
235
256
|
}
|
|
257
|
+
if (ctx?.include !== undefined && out.include === undefined) {
|
|
258
|
+
out.include = ctx.include;
|
|
259
|
+
}
|
|
260
|
+
else if (metadataExtraFields?.include !== undefined && out.include === undefined) {
|
|
261
|
+
out.include = metadataExtraFields.include;
|
|
262
|
+
}
|
|
263
|
+
if (ctx?.store !== undefined && out.store === undefined) {
|
|
264
|
+
out.store = ctx.store;
|
|
265
|
+
}
|
|
266
|
+
else if (metadataExtraFields?.store !== undefined && out.store === undefined) {
|
|
267
|
+
out.store = metadataExtraFields.store;
|
|
268
|
+
}
|
|
269
|
+
if (ctx?.toolChoice !== undefined && out.tool_choice === undefined) {
|
|
270
|
+
out.tool_choice = ctx.toolChoice;
|
|
271
|
+
}
|
|
272
|
+
else if (metadataExtraFields?.tool_choice !== undefined && out.tool_choice === undefined) {
|
|
273
|
+
out.tool_choice = metadataExtraFields.tool_choice;
|
|
274
|
+
}
|
|
275
|
+
if (typeof ctx?.parallelToolCalls === 'boolean' && out.parallel_tool_calls === undefined) {
|
|
276
|
+
out.parallel_tool_calls = ctx.parallelToolCalls;
|
|
277
|
+
}
|
|
278
|
+
else if (typeof metadataExtraFields?.parallel_tool_calls === 'boolean' && out.parallel_tool_calls === undefined) {
|
|
279
|
+
out.parallel_tool_calls = metadataExtraFields.parallel_tool_calls;
|
|
280
|
+
}
|
|
281
|
+
if (ctx?.responseFormat !== undefined && out.response_format === undefined) {
|
|
282
|
+
out.response_format = ctx.responseFormat;
|
|
283
|
+
}
|
|
284
|
+
else if (metadataExtraFields?.response_format !== undefined && out.response_format === undefined) {
|
|
285
|
+
out.response_format = metadataExtraFields.response_format;
|
|
286
|
+
}
|
|
287
|
+
if (ctx?.metadata && Object.keys(ctx.metadata).length) {
|
|
288
|
+
out.metadata = { ...ctx.metadata };
|
|
289
|
+
}
|
|
290
|
+
else if (isPlainObject(metadataExtraFields?.metadata)) {
|
|
291
|
+
out.metadata = { ...metadataExtraFields.metadata };
|
|
292
|
+
}
|
|
293
|
+
if (ctx?.parameters && Object.keys(ctx.parameters).length) {
|
|
294
|
+
out.parameters = { ...ctx.parameters };
|
|
295
|
+
}
|
|
296
|
+
else if (chat.parameters && typeof chat.parameters === 'object') {
|
|
297
|
+
out.parameters = { ...chat.parameters };
|
|
298
|
+
}
|
|
299
|
+
else if (isPlainObject(metadataExtraFields?.parameters)) {
|
|
300
|
+
out.parameters = { ...metadataExtraFields.parameters };
|
|
301
|
+
}
|
|
236
302
|
ensureBridgeInstructions(out);
|
|
237
303
|
return { request: out, originalSystemMessages };
|
|
238
304
|
}
|
|
305
|
+
function readToolCallIdStyleFromContext(ctx) {
|
|
306
|
+
if (!ctx) {
|
|
307
|
+
return undefined;
|
|
308
|
+
}
|
|
309
|
+
const direct = normalizeToolCallIdStyleCandidate(ctx.toolCallIdStyle);
|
|
310
|
+
if (direct) {
|
|
311
|
+
return direct;
|
|
312
|
+
}
|
|
313
|
+
if (ctx.metadata && typeof ctx.metadata === 'object') {
|
|
314
|
+
const fromMetadata = normalizeToolCallIdStyleCandidate(ctx.metadata.toolCallIdStyle);
|
|
315
|
+
if (fromMetadata) {
|
|
316
|
+
return fromMetadata;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
return undefined;
|
|
320
|
+
}
|
|
321
|
+
function normalizeToolCallIdStyleCandidate(candidate) {
|
|
322
|
+
if (typeof candidate !== 'string') {
|
|
323
|
+
return undefined;
|
|
324
|
+
}
|
|
325
|
+
const normalized = candidate.trim().toLowerCase();
|
|
326
|
+
if (normalized === 'fc') {
|
|
327
|
+
return 'fc';
|
|
328
|
+
}
|
|
329
|
+
if (normalized === 'preserve') {
|
|
330
|
+
return 'preserve';
|
|
331
|
+
}
|
|
332
|
+
return undefined;
|
|
333
|
+
}
|
|
334
|
+
function cloneBridgeEntries(entries) {
|
|
335
|
+
if (!Array.isArray(entries)) {
|
|
336
|
+
return undefined;
|
|
337
|
+
}
|
|
338
|
+
return entries.map((entry) => {
|
|
339
|
+
if (!entry || typeof entry !== 'object') {
|
|
340
|
+
return entry;
|
|
341
|
+
}
|
|
342
|
+
try {
|
|
343
|
+
return JSON.parse(JSON.stringify(entry));
|
|
344
|
+
}
|
|
345
|
+
catch {
|
|
346
|
+
return entry;
|
|
347
|
+
}
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
function extractMetadataExtraFields(metadata) {
|
|
351
|
+
if (!metadata) {
|
|
352
|
+
return undefined;
|
|
353
|
+
}
|
|
354
|
+
const extras = metadata.extraFields;
|
|
355
|
+
if (extras && typeof extras === 'object' && !Array.isArray(extras)) {
|
|
356
|
+
return extras;
|
|
357
|
+
}
|
|
358
|
+
return undefined;
|
|
359
|
+
}
|
|
360
|
+
function isPlainObject(value) {
|
|
361
|
+
return Boolean(value && typeof value === 'object' && !Array.isArray(value));
|
|
362
|
+
}
|
|
239
363
|
export function buildResponsesPayloadFromChat(payload, context) {
|
|
240
364
|
if (!payload || typeof payload !== 'object')
|
|
241
365
|
return payload;
|
|
@@ -297,9 +421,11 @@ export function buildResponsesPayloadFromChat(payload, context) {
|
|
|
297
421
|
created_at: response.created_at || response.created || Math.floor(Date.now() / 1000),
|
|
298
422
|
model: response.model,
|
|
299
423
|
status: outputBuild.status,
|
|
300
|
-
output: outputBuild.outputItems
|
|
301
|
-
output_text: outputBuild.outputText || ''
|
|
424
|
+
output: outputBuild.outputItems
|
|
302
425
|
};
|
|
426
|
+
if (typeof outputBuild.outputText === 'string') {
|
|
427
|
+
out.output_text = outputBuild.outputText;
|
|
428
|
+
}
|
|
303
429
|
if (outputBuild.usage !== undefined)
|
|
304
430
|
out.usage = outputBuild.usage;
|
|
305
431
|
if (outputBuild.requiredAction)
|
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
import type { ChatToolDefinition, MissingField } from '../hub/types/chat-envelope.js';
|
|
2
|
+
import { type JsonObject } from '../hub/types/json.js';
|
|
2
3
|
type Unknown = Record<string, unknown>;
|
|
3
4
|
type UnknownArray = Unknown[];
|
|
4
5
|
interface OpenAIChatPayload extends Unknown {
|
|
5
6
|
messages: UnknownArray;
|
|
6
7
|
}
|
|
8
|
+
export declare function normalizeAnthropicToolName(value: unknown): string | undefined;
|
|
9
|
+
export declare function denormalizeAnthropicToolName(value: unknown): string | undefined;
|
|
7
10
|
export declare function buildOpenAIChatFromAnthropic(payload: unknown): OpenAIChatPayload;
|
|
8
|
-
export
|
|
11
|
+
export interface BuildAnthropicFromOpenAIOptions {
|
|
12
|
+
toolNameMap?: Record<string, string>;
|
|
13
|
+
requestId?: string;
|
|
14
|
+
}
|
|
15
|
+
export declare function buildAnthropicFromOpenAIChat(oa: unknown, options?: BuildAnthropicFromOpenAIOptions): Unknown;
|
|
9
16
|
export declare function buildAnthropicRequestFromOpenAIChat(chatReq: unknown): Unknown;
|
|
10
17
|
export declare function mapAnthropicToolsToChat(rawTools: unknown, missing?: MissingField[]): ChatToolDefinition[] | undefined;
|
|
11
18
|
export declare function mapChatToolsToAnthropicTools(rawTools: unknown): UnknownArray | undefined;
|
|
19
|
+
export declare function buildAnthropicToolAliasMap(rawTools: unknown): JsonObject | undefined;
|
|
12
20
|
export {};
|