@jsonstudio/llms 0.4.4 → 0.4.6
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/codec-registry.js +11 -1
- package/dist/conversion/codecs/anthropic-openai-codec.d.ts +13 -0
- package/dist/conversion/codecs/anthropic-openai-codec.js +18 -473
- package/dist/conversion/codecs/gemini-openai-codec.js +91 -48
- package/dist/conversion/codecs/responses-openai-codec.js +9 -2
- package/dist/conversion/hub/format-adapters/anthropic-format-adapter.js +3 -0
- package/dist/conversion/hub/format-adapters/chat-format-adapter.js +3 -0
- package/dist/conversion/hub/format-adapters/gemini-format-adapter.js +3 -0
- package/dist/conversion/hub/format-adapters/responses-format-adapter.d.ts +19 -0
- package/dist/conversion/hub/format-adapters/responses-format-adapter.js +9 -0
- package/dist/conversion/hub/node-support.js +3 -1
- package/dist/conversion/hub/pipeline/hub-pipeline.js +37 -32
- package/dist/conversion/hub/response/provider-response.js +1 -1
- package/dist/conversion/hub/response/response-mappers.js +1 -1
- package/dist/conversion/hub/response/response-runtime.js +109 -10
- package/dist/conversion/hub/semantic-mappers/anthropic-mapper.js +70 -156
- package/dist/conversion/hub/semantic-mappers/chat-mapper.js +63 -52
- package/dist/conversion/hub/semantic-mappers/gemini-mapper.js +76 -143
- package/dist/conversion/hub/semantic-mappers/responses-mapper.js +40 -160
- package/dist/conversion/hub/standardized-bridge.js +3 -0
- package/dist/conversion/hub/tool-governance/rules.js +2 -2
- package/dist/conversion/index.d.ts +5 -0
- package/dist/conversion/index.js +5 -0
- package/dist/conversion/pipeline/codecs/v2/anthropic-openai-pipeline.d.ts +12 -0
- package/dist/conversion/pipeline/codecs/v2/anthropic-openai-pipeline.js +100 -0
- package/dist/conversion/pipeline/codecs/v2/openai-openai-pipeline.d.ts +15 -0
- package/dist/conversion/pipeline/codecs/v2/openai-openai-pipeline.js +174 -0
- package/dist/conversion/pipeline/codecs/v2/responses-openai-pipeline.d.ts +14 -0
- package/dist/conversion/pipeline/codecs/v2/responses-openai-pipeline.js +166 -0
- package/dist/conversion/pipeline/codecs/v2/shared/openai-chat-helpers.d.ts +13 -0
- package/dist/conversion/pipeline/codecs/v2/shared/openai-chat-helpers.js +66 -0
- package/dist/conversion/pipeline/hooks/adapter-context.d.ts +7 -0
- package/dist/conversion/pipeline/hooks/adapter-context.js +18 -0
- package/dist/conversion/pipeline/hooks/protocol-hooks.d.ts +67 -0
- package/dist/conversion/pipeline/hooks/protocol-hooks.js +1 -0
- package/dist/conversion/pipeline/index.d.ts +35 -0
- package/dist/conversion/pipeline/index.js +103 -0
- package/dist/conversion/pipeline/meta/meta-bag.d.ts +20 -0
- package/dist/conversion/pipeline/meta/meta-bag.js +81 -0
- package/dist/conversion/pipeline/schema/canonical-chat.d.ts +18 -0
- package/dist/conversion/pipeline/schema/canonical-chat.js +1 -0
- package/dist/conversion/pipeline/schema/index.d.ts +1 -0
- package/dist/conversion/pipeline/schema/index.js +1 -0
- package/dist/conversion/responses/responses-openai-bridge.d.ts +48 -0
- package/dist/conversion/responses/responses-openai-bridge.js +157 -1146
- package/dist/conversion/shared/anthropic-message-utils.d.ts +12 -0
- package/dist/conversion/shared/anthropic-message-utils.js +587 -0
- package/dist/conversion/shared/bridge-actions.d.ts +39 -0
- package/dist/conversion/shared/bridge-actions.js +709 -0
- package/dist/conversion/shared/bridge-conversation-store.d.ts +41 -0
- package/dist/conversion/shared/bridge-conversation-store.js +279 -0
- package/dist/conversion/shared/bridge-id-utils.d.ts +7 -0
- package/dist/conversion/shared/bridge-id-utils.js +42 -0
- package/dist/conversion/shared/bridge-instructions.d.ts +1 -0
- package/dist/conversion/shared/bridge-instructions.js +113 -0
- package/dist/conversion/shared/bridge-message-types.d.ts +39 -0
- package/dist/conversion/shared/bridge-message-types.js +1 -0
- package/dist/conversion/shared/bridge-message-utils.d.ts +22 -0
- package/dist/conversion/shared/bridge-message-utils.js +473 -0
- package/dist/conversion/shared/bridge-metadata.d.ts +1 -0
- package/dist/conversion/shared/bridge-metadata.js +1 -0
- package/dist/conversion/shared/bridge-policies.d.ts +18 -0
- package/dist/conversion/shared/bridge-policies.js +276 -0
- package/dist/conversion/shared/bridge-request-adapter.d.ts +28 -0
- package/dist/conversion/shared/bridge-request-adapter.js +430 -0
- package/dist/conversion/shared/chat-output-normalizer.d.ts +4 -0
- package/dist/conversion/shared/chat-output-normalizer.js +56 -0
- package/dist/conversion/shared/chat-request-filters.js +24 -1
- package/dist/conversion/shared/gemini-tool-utils.d.ts +5 -0
- package/dist/conversion/shared/gemini-tool-utils.js +130 -0
- package/dist/conversion/shared/metadata-passthrough.d.ts +11 -0
- package/dist/conversion/shared/metadata-passthrough.js +57 -0
- package/dist/conversion/shared/output-content-normalizer.d.ts +12 -0
- package/dist/conversion/shared/output-content-normalizer.js +119 -0
- package/dist/conversion/shared/reasoning-normalizer.d.ts +21 -0
- package/dist/conversion/shared/reasoning-normalizer.js +368 -0
- package/dist/conversion/shared/reasoning-tool-normalizer.d.ts +12 -0
- package/dist/conversion/shared/reasoning-tool-normalizer.js +132 -0
- package/dist/conversion/shared/reasoning-tool-parser.d.ts +10 -0
- package/dist/conversion/shared/reasoning-tool-parser.js +95 -0
- package/dist/conversion/shared/reasoning-utils.d.ts +2 -0
- package/dist/conversion/shared/reasoning-utils.js +42 -0
- package/dist/conversion/shared/responses-conversation-store.js +5 -11
- package/dist/conversion/shared/responses-message-utils.d.ts +15 -0
- package/dist/conversion/shared/responses-message-utils.js +206 -0
- package/dist/conversion/shared/responses-output-builder.d.ts +15 -0
- package/dist/conversion/shared/responses-output-builder.js +179 -0
- package/dist/conversion/shared/responses-output-utils.d.ts +7 -0
- package/dist/conversion/shared/responses-output-utils.js +108 -0
- package/dist/conversion/shared/responses-request-adapter.d.ts +28 -0
- package/dist/conversion/shared/responses-request-adapter.js +9 -40
- package/dist/conversion/shared/responses-response-utils.d.ts +3 -0
- package/dist/conversion/shared/responses-response-utils.js +209 -0
- package/dist/conversion/shared/responses-tool-utils.d.ts +12 -0
- package/dist/conversion/shared/responses-tool-utils.js +90 -0
- package/dist/conversion/shared/responses-types.d.ts +33 -0
- package/dist/conversion/shared/responses-types.js +1 -0
- package/dist/conversion/shared/tool-call-utils.d.ts +11 -0
- package/dist/conversion/shared/tool-call-utils.js +56 -0
- package/dist/conversion/shared/tool-governor.js +5 -0
- package/dist/conversion/shared/tool-mapping.d.ts +19 -0
- package/dist/conversion/shared/tool-mapping.js +124 -0
- package/dist/conversion/shared/tool-normalizers.d.ts +4 -0
- package/dist/conversion/shared/tool-normalizers.js +84 -0
- package/dist/router/virtual-router/bootstrap.js +18 -3
- package/dist/router/virtual-router/provider-registry.js +4 -2
- package/dist/router/virtual-router/types.d.ts +212 -0
- package/dist/sse/index.d.ts +38 -2
- package/dist/sse/index.js +27 -0
- package/dist/sse/json-to-sse/anthropic-json-to-sse-converter.d.ts +14 -0
- package/dist/sse/json-to-sse/anthropic-json-to-sse-converter.js +106 -73
- package/dist/sse/json-to-sse/chat-json-to-sse-converter.js +6 -2
- package/dist/sse/json-to-sse/gemini-json-to-sse-converter.d.ts +14 -0
- package/dist/sse/json-to-sse/gemini-json-to-sse-converter.js +99 -0
- package/dist/sse/json-to-sse/index.d.ts +7 -0
- package/dist/sse/json-to-sse/index.js +2 -0
- package/dist/sse/json-to-sse/sequencers/anthropic-sequencer.d.ts +13 -0
- package/dist/sse/json-to-sse/sequencers/anthropic-sequencer.js +150 -0
- package/dist/sse/json-to-sse/sequencers/chat-sequencer.d.ts +39 -0
- package/dist/sse/json-to-sse/sequencers/chat-sequencer.js +49 -3
- package/dist/sse/json-to-sse/sequencers/gemini-sequencer.d.ts +10 -0
- package/dist/sse/json-to-sse/sequencers/gemini-sequencer.js +95 -0
- package/dist/sse/json-to-sse/sequencers/responses-sequencer.js +31 -5
- package/dist/sse/registry/sse-codec-registry.d.ts +32 -0
- package/dist/sse/registry/sse-codec-registry.js +30 -1
- package/dist/sse/shared/reasoning-dispatcher.d.ts +10 -0
- package/dist/sse/shared/reasoning-dispatcher.js +25 -0
- package/dist/sse/shared/responses-output-normalizer.d.ts +12 -0
- package/dist/sse/shared/responses-output-normalizer.js +45 -0
- package/dist/sse/shared/serializers/anthropic-event-serializer.d.ts +2 -0
- package/dist/sse/shared/serializers/anthropic-event-serializer.js +9 -0
- package/dist/sse/shared/serializers/gemini-event-serializer.d.ts +2 -0
- package/dist/sse/shared/serializers/gemini-event-serializer.js +5 -0
- package/dist/sse/shared/serializers/index.d.ts +41 -0
- package/dist/sse/shared/serializers/index.js +2 -0
- package/dist/sse/shared/writer.d.ts +127 -0
- package/dist/sse/shared/writer.js +37 -1
- package/dist/sse/sse-to-json/anthropic-sse-to-json-converter.d.ts +11 -0
- package/dist/sse/sse-to-json/anthropic-sse-to-json-converter.js +92 -127
- package/dist/sse/sse-to-json/builders/anthropic-response-builder.d.ts +16 -0
- package/dist/sse/sse-to-json/builders/anthropic-response-builder.js +151 -0
- package/dist/sse/sse-to-json/builders/response-builder.d.ts +165 -0
- package/dist/sse/sse-to-json/builders/response-builder.js +27 -6
- package/dist/sse/sse-to-json/chat-sse-to-json-converter.d.ts +114 -0
- package/dist/sse/sse-to-json/chat-sse-to-json-converter.js +79 -3
- package/dist/sse/sse-to-json/gemini-sse-to-json-converter.d.ts +13 -0
- package/dist/sse/sse-to-json/gemini-sse-to-json-converter.js +160 -0
- package/dist/sse/sse-to-json/index.d.ts +7 -0
- package/dist/sse/sse-to-json/index.js +2 -0
- package/dist/sse/sse-to-json/parsers/sse-parser.js +53 -1
- package/dist/sse/types/anthropic-types.d.ts +170 -0
- package/dist/sse/types/anthropic-types.js +8 -5
- package/dist/sse/types/chat-types.d.ts +10 -0
- package/dist/sse/types/chat-types.js +2 -1
- package/dist/sse/types/core-interfaces.d.ts +1 -1
- package/dist/sse/types/gemini-types.d.ts +116 -0
- package/dist/sse/types/gemini-types.js +5 -0
- package/dist/sse/types/index.d.ts +5 -2
- package/dist/sse/types/index.js +2 -0
- package/package.json +1 -1
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { normalizeFunctionCallId } from './bridge-id-utils.js';
|
|
2
|
+
import { normalizeContentPart } from './output-content-normalizer.js';
|
|
3
|
+
import { expandResponsesMessageItem } from '../../sse/shared/responses-output-normalizer.js';
|
|
4
|
+
export function buildResponsesOutputFromChat(options) {
|
|
5
|
+
const { response, message, requestId, sanitizeFunctionName } = options;
|
|
6
|
+
const outputItems = [];
|
|
7
|
+
const allocateOutputId = (prefix) => `${prefix}_${requestId ?? Date.now()}_${outputItems.length + 1}`;
|
|
8
|
+
const role = message?.role || 'assistant';
|
|
9
|
+
const content = message?.content;
|
|
10
|
+
const reasoningText = typeof message?.reasoning_content === 'string' && message.reasoning_content.trim().length
|
|
11
|
+
? String(message.reasoning_content).trim()
|
|
12
|
+
: undefined;
|
|
13
|
+
const convertedContent = convertChatContentToResponses(content);
|
|
14
|
+
if (message || convertedContent.length > 0 || reasoningText) {
|
|
15
|
+
const responsesMessage = {
|
|
16
|
+
id: allocateOutputId('message'),
|
|
17
|
+
type: 'message',
|
|
18
|
+
status: 'completed',
|
|
19
|
+
role,
|
|
20
|
+
content: convertedContent.length > 0 ? convertedContent : []
|
|
21
|
+
};
|
|
22
|
+
const expandedItems = expandResponsesMessageItem(responsesMessage, {
|
|
23
|
+
requestId: requestId ?? 'responses_outbound',
|
|
24
|
+
outputIndex: outputItems.length,
|
|
25
|
+
extraReasoning: reasoningText
|
|
26
|
+
});
|
|
27
|
+
for (const expanded of expandedItems) {
|
|
28
|
+
outputItems.push(expanded);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
let toolCalls = Array.isArray(message?.tool_calls) ? message.tool_calls : [];
|
|
32
|
+
const normalizedToolCalls = [];
|
|
33
|
+
try {
|
|
34
|
+
toolCalls = toolCalls.filter((it) => {
|
|
35
|
+
const nm = (it && typeof it === 'object') ? (it?.function?.name || it.name) : undefined;
|
|
36
|
+
return typeof nm === 'string' && nm.trim().length > 0 && nm.toLowerCase() !== 'tool';
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
/* ignore */
|
|
41
|
+
}
|
|
42
|
+
let toolFallbackCounter = 0;
|
|
43
|
+
for (const call of toolCalls) {
|
|
44
|
+
const outputEntry = buildFunctionCallOutput(call, allocateOutputId, sanitizeFunctionName, outputItems.length, ++toolFallbackCounter);
|
|
45
|
+
if (outputEntry) {
|
|
46
|
+
outputItems.push(outputEntry.output);
|
|
47
|
+
normalizedToolCalls.push({
|
|
48
|
+
id: outputEntry.call_id,
|
|
49
|
+
name: outputEntry.name,
|
|
50
|
+
args: outputEntry.arguments
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
const usage = normalizeUsage(response.usage);
|
|
55
|
+
const outputText = extractOutputText(convertedContent);
|
|
56
|
+
const hasToolCalls = toolCalls.length > 0;
|
|
57
|
+
if (hasToolCalls) {
|
|
58
|
+
for (const item of outputItems) {
|
|
59
|
+
if (item.type === 'message') {
|
|
60
|
+
item.status = 'in_progress';
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
const requiredAction = normalizedToolCalls.length
|
|
65
|
+
? buildRequiredActionFromNormalized(normalizedToolCalls)
|
|
66
|
+
: undefined;
|
|
67
|
+
const status = hasToolCalls ? 'requires_action' : 'completed';
|
|
68
|
+
return {
|
|
69
|
+
outputItems,
|
|
70
|
+
outputText,
|
|
71
|
+
status,
|
|
72
|
+
requiredAction,
|
|
73
|
+
usage
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
function normalizeUsage(usageRaw) {
|
|
77
|
+
if (usageRaw && typeof usageRaw === 'object') {
|
|
78
|
+
const usage = { ...usageRaw };
|
|
79
|
+
if (usage.input_tokens != null && usage.prompt_tokens == null) {
|
|
80
|
+
usage.prompt_tokens = usage.input_tokens;
|
|
81
|
+
}
|
|
82
|
+
if (usage.output_tokens != null && usage.completion_tokens == null) {
|
|
83
|
+
usage.completion_tokens = usage.output_tokens;
|
|
84
|
+
}
|
|
85
|
+
if (usage.prompt_tokens != null && usage.completion_tokens != null && usage.total_tokens == null) {
|
|
86
|
+
const total = Number(usage.prompt_tokens) + Number(usage.completion_tokens);
|
|
87
|
+
if (!Number.isNaN(total))
|
|
88
|
+
usage.total_tokens = total;
|
|
89
|
+
}
|
|
90
|
+
try {
|
|
91
|
+
delete usage.input_tokens;
|
|
92
|
+
delete usage.output_tokens;
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
/* ignore */
|
|
96
|
+
}
|
|
97
|
+
return usage;
|
|
98
|
+
}
|
|
99
|
+
return usageRaw;
|
|
100
|
+
}
|
|
101
|
+
function buildFunctionCallOutput(call, allocateOutputId, sanitizeFunctionName, baseCount, offset) {
|
|
102
|
+
try {
|
|
103
|
+
const fn = call?.function || {};
|
|
104
|
+
const callName = typeof fn?.name === 'string' && fn.name.trim().length
|
|
105
|
+
? fn.name
|
|
106
|
+
: (typeof call.name === 'string' ? call.name : 'tool');
|
|
107
|
+
const sanitized = sanitizeFunctionName(callName);
|
|
108
|
+
if (!sanitized || sanitized.toLowerCase() === 'tool')
|
|
109
|
+
return null;
|
|
110
|
+
const rawArgs = fn?.arguments ?? call.arguments ?? {};
|
|
111
|
+
const argsStr = typeof rawArgs === 'string'
|
|
112
|
+
? rawArgs
|
|
113
|
+
: (() => {
|
|
114
|
+
try {
|
|
115
|
+
return JSON.stringify(rawArgs ?? {});
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
return '{}';
|
|
119
|
+
}
|
|
120
|
+
})();
|
|
121
|
+
const originalCallId = typeof call.id === 'string' && call.id.trim().length
|
|
122
|
+
? String(call.id)
|
|
123
|
+
: (typeof call.call_id === 'string' && call.call_id.trim().length ? String(call.call_id) : undefined);
|
|
124
|
+
const callId = originalCallId && originalCallId.trim().length
|
|
125
|
+
? originalCallId.trim()
|
|
126
|
+
: normalizeFunctionCallId({
|
|
127
|
+
callId: originalCallId,
|
|
128
|
+
fallback: `fc_call_${baseCount + offset}`
|
|
129
|
+
});
|
|
130
|
+
const output = {
|
|
131
|
+
id: allocateOutputId('function_call'),
|
|
132
|
+
type: 'function_call',
|
|
133
|
+
status: 'in_progress',
|
|
134
|
+
name: sanitized,
|
|
135
|
+
call_id: callId,
|
|
136
|
+
arguments: argsStr
|
|
137
|
+
};
|
|
138
|
+
return { output, call_id: callId, name: sanitized, arguments: argsStr };
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
function buildRequiredActionFromNormalized(calls) {
|
|
145
|
+
if (!calls.length)
|
|
146
|
+
return undefined;
|
|
147
|
+
const submitCalls = calls.map((entry) => ({
|
|
148
|
+
id: entry.id,
|
|
149
|
+
type: 'function',
|
|
150
|
+
function: {
|
|
151
|
+
name: entry.name,
|
|
152
|
+
arguments: entry.args
|
|
153
|
+
}
|
|
154
|
+
}));
|
|
155
|
+
return { type: 'submit_tool_outputs', submit_tool_outputs: { tool_calls: submitCalls } };
|
|
156
|
+
}
|
|
157
|
+
function convertChatContentToResponses(content) {
|
|
158
|
+
if (content == null)
|
|
159
|
+
return [];
|
|
160
|
+
if (Array.isArray(content)) {
|
|
161
|
+
return content
|
|
162
|
+
.map((part) => normalizeContentPart(part, []))
|
|
163
|
+
.filter((entry) => !!entry);
|
|
164
|
+
}
|
|
165
|
+
const normalized = normalizeContentPart(content, []);
|
|
166
|
+
return normalized ? [normalized] : [];
|
|
167
|
+
}
|
|
168
|
+
function extractOutputText(parts) {
|
|
169
|
+
if (!parts.length)
|
|
170
|
+
return '';
|
|
171
|
+
const reasoningCollector = [];
|
|
172
|
+
const normalizedTexts = parts
|
|
173
|
+
.map((part) => normalizeContentPart(part, reasoningCollector))
|
|
174
|
+
.filter((entry) => !!entry)
|
|
175
|
+
.map((entry) => (typeof entry.text === 'string' ? entry.text : ''))
|
|
176
|
+
.filter(Boolean);
|
|
177
|
+
const text = normalizedTexts.join('\n').trim();
|
|
178
|
+
return text.length ? text : '';
|
|
179
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
type UnknownRecord = Record<string, unknown>;
|
|
2
|
+
export declare function extractResponsesOutputSegments(response: UnknownRecord | undefined): {
|
|
3
|
+
textParts: string[];
|
|
4
|
+
reasoningParts: string[];
|
|
5
|
+
};
|
|
6
|
+
export declare function normalizeResponsesContentPart(part: unknown, reasoningCollector: string[]): UnknownRecord | null;
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { extractReasoningSegments, sanitizeReasoningTaggedText } from './reasoning-utils.js';
|
|
2
|
+
function collectMessageTexts(blocks, accumulator) {
|
|
3
|
+
const pushText = (value) => {
|
|
4
|
+
if (typeof value === 'string' && value.trim().length) {
|
|
5
|
+
const cleaned = extractReasoningSegments(value, accumulator.reasoningParts);
|
|
6
|
+
if (cleaned.length) {
|
|
7
|
+
accumulator.textParts.push(cleaned);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
if (typeof blocks === 'string') {
|
|
12
|
+
pushText(blocks);
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
if (!Array.isArray(blocks))
|
|
16
|
+
return;
|
|
17
|
+
for (const block of blocks) {
|
|
18
|
+
if (!block || typeof block !== 'object')
|
|
19
|
+
continue;
|
|
20
|
+
const type = typeof block.type === 'string' ? String(block.type).toLowerCase() : '';
|
|
21
|
+
if (type === 'text' || type === 'input_text' || type === 'output_text' || type === 'commentary') {
|
|
22
|
+
pushText(block.text ?? block.content);
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
if (Array.isArray(block.content)) {
|
|
26
|
+
collectMessageTexts(block.content, accumulator);
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
if (typeof block.text === 'string') {
|
|
30
|
+
pushText(block.text);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export function extractResponsesOutputSegments(response) {
|
|
35
|
+
if (!response || typeof response !== 'object') {
|
|
36
|
+
return { textParts: [], reasoningParts: [] };
|
|
37
|
+
}
|
|
38
|
+
const textParts = [];
|
|
39
|
+
const reasoningParts = [];
|
|
40
|
+
const outputItems = Array.isArray(response.output) ? response.output : [];
|
|
41
|
+
for (const item of outputItems) {
|
|
42
|
+
if (!item || typeof item !== 'object')
|
|
43
|
+
continue;
|
|
44
|
+
const type = typeof item.type === 'string' ? String(item.type).toLowerCase() : '';
|
|
45
|
+
if (type === 'message') {
|
|
46
|
+
const message = item.message && typeof item.message === 'object'
|
|
47
|
+
? item.message
|
|
48
|
+
: item;
|
|
49
|
+
const content = Array.isArray(message.content) ? message.content : [];
|
|
50
|
+
collectMessageTexts(content, { textParts, reasoningParts });
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
if (type === 'output_text') {
|
|
54
|
+
if (typeof item.text === 'string') {
|
|
55
|
+
const cleaned = extractReasoningSegments(item.text, reasoningParts);
|
|
56
|
+
if (cleaned.length) {
|
|
57
|
+
textParts.push(cleaned);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
if (type === 'reasoning') {
|
|
63
|
+
const content = Array.isArray(item.content) ? item.content : [];
|
|
64
|
+
for (const block of content) {
|
|
65
|
+
if (block && typeof block === 'object' && typeof block.text === 'string') {
|
|
66
|
+
const sanitized = sanitizeReasoningTaggedText(block.text);
|
|
67
|
+
if (sanitized.length)
|
|
68
|
+
reasoningParts.push(sanitized);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return { textParts, reasoningParts };
|
|
74
|
+
}
|
|
75
|
+
export function normalizeResponsesContentPart(part, reasoningCollector) {
|
|
76
|
+
if (part == null) {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
if (typeof part === 'string') {
|
|
80
|
+
const cleaned = extractReasoningSegments(part, reasoningCollector);
|
|
81
|
+
return { type: 'output_text', text: cleaned };
|
|
82
|
+
}
|
|
83
|
+
if (typeof part !== 'object') {
|
|
84
|
+
return { type: 'output_text', text: sanitizeReasoningTaggedText(String(part)) };
|
|
85
|
+
}
|
|
86
|
+
const clone = { ...part };
|
|
87
|
+
delete clone._initialText;
|
|
88
|
+
delete clone._hasDelta;
|
|
89
|
+
if (typeof clone.text === 'string') {
|
|
90
|
+
clone.text = extractReasoningSegments(clone.text, reasoningCollector);
|
|
91
|
+
}
|
|
92
|
+
if (clone.output_text && typeof clone.output_text === 'object' && typeof clone.output_text.text === 'string') {
|
|
93
|
+
clone.output_text = {
|
|
94
|
+
...clone.output_text,
|
|
95
|
+
text: extractReasoningSegments(clone.output_text.text, reasoningCollector)
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
if (typeof clone.content === 'string') {
|
|
99
|
+
clone.content = extractReasoningSegments(clone.content, reasoningCollector);
|
|
100
|
+
}
|
|
101
|
+
if (!clone.type) {
|
|
102
|
+
clone.type = 'output_text';
|
|
103
|
+
}
|
|
104
|
+
if (clone.type === 'output_text' && typeof clone.text !== 'string') {
|
|
105
|
+
clone.text = '';
|
|
106
|
+
}
|
|
107
|
+
return clone;
|
|
108
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { BridgeInputItem, BridgeToolDefinition } from './bridge-message-types.js';
|
|
2
|
+
export interface ResponsesRequestContext {
|
|
3
|
+
requestId?: string;
|
|
4
|
+
instructions?: string;
|
|
5
|
+
originalSystemMessages?: string[];
|
|
6
|
+
input?: BridgeInputItem[];
|
|
7
|
+
include?: unknown;
|
|
8
|
+
store?: unknown;
|
|
9
|
+
toolChoice?: unknown;
|
|
10
|
+
parallelToolCalls?: boolean;
|
|
11
|
+
metadata?: Record<string, unknown>;
|
|
12
|
+
responseFormat?: unknown;
|
|
13
|
+
toolsRaw?: BridgeToolDefinition[];
|
|
14
|
+
stream?: boolean;
|
|
15
|
+
instructionsIsRaw?: boolean;
|
|
16
|
+
isChatPayload?: boolean;
|
|
17
|
+
isResponsesPayload?: boolean;
|
|
18
|
+
}
|
|
19
|
+
export interface BuildChatRequestResult {
|
|
20
|
+
request: Record<string, unknown>;
|
|
21
|
+
toolsNormalized?: Array<Record<string, unknown>>;
|
|
22
|
+
}
|
|
23
|
+
export declare function captureResponsesContext(payload: Record<string, unknown>, dto?: {
|
|
24
|
+
route?: {
|
|
25
|
+
requestId?: string;
|
|
26
|
+
};
|
|
27
|
+
}): ResponsesRequestContext;
|
|
28
|
+
export declare function buildChatRequestFromResponses(payload: Record<string, unknown>, context: ResponsesRequestContext): BuildChatRequestResult;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { normalizeFunctionCallId, normalizeFunctionCallOutputId } from './responses-id-utils.js';
|
|
2
2
|
import { ensureResponsesInstructions } from './responses-instructions.js';
|
|
3
|
+
import { serializeToolArguments, coerceBridgeRole, serializeToolOutput } from './bridge-message-utils.js';
|
|
3
4
|
export function captureResponsesContext(payload, dto) {
|
|
4
5
|
ensureResponsesInstructions(payload);
|
|
5
6
|
const context = {
|
|
@@ -197,7 +198,7 @@ function mapResponsesInputToChat(options) {
|
|
|
197
198
|
if (typeof entry.content === 'string') {
|
|
198
199
|
const directText = (entry.content || '').toString().trim();
|
|
199
200
|
if (directText.length) {
|
|
200
|
-
const normalizedRole =
|
|
201
|
+
const normalizedRole = coerceBridgeRole(entry.role || 'user');
|
|
201
202
|
messages.push({ role: normalizedRole, content: directText });
|
|
202
203
|
continue;
|
|
203
204
|
}
|
|
@@ -215,7 +216,7 @@ function mapResponsesInputToChat(options) {
|
|
|
215
216
|
if (callIdRaw && callIdRaw !== callId) {
|
|
216
217
|
toolCallIdAliases.set(callIdRaw, callId);
|
|
217
218
|
}
|
|
218
|
-
const serialized =
|
|
219
|
+
const serialized = serializeToolArguments(parsedArgs, name, toolsNormalized).trim();
|
|
219
220
|
toolNameById.set(callId, name);
|
|
220
221
|
messages.push({ role: 'assistant', tool_calls: [{ id: callId, type: 'function', function: { name, arguments: serialized } }] });
|
|
221
222
|
lastToolCallId = callId;
|
|
@@ -233,7 +234,7 @@ function mapResponsesInputToChat(options) {
|
|
|
233
234
|
}
|
|
234
235
|
toolCallId = normalized;
|
|
235
236
|
}
|
|
236
|
-
const output =
|
|
237
|
+
const output = serializeToolOutput(entry);
|
|
237
238
|
if (toolCallId) {
|
|
238
239
|
try {
|
|
239
240
|
let contentStr = output != null ? String(output) : '';
|
|
@@ -266,7 +267,7 @@ function mapResponsesInputToChat(options) {
|
|
|
266
267
|
messages.push({ role: 'assistant', tool_calls: toolCalls });
|
|
267
268
|
for (const msg of toolMessages)
|
|
268
269
|
messages.push(msg);
|
|
269
|
-
const normalizedRole =
|
|
270
|
+
const normalizedRole = coerceBridgeRole((explicit.role ?? entry.role) || 'user');
|
|
270
271
|
if (typeof text === 'string' && text.trim().length) {
|
|
271
272
|
messages.push({ role: normalizedRole, content: text.trim() });
|
|
272
273
|
}
|
|
@@ -279,7 +280,7 @@ function mapResponsesInputToChat(options) {
|
|
|
279
280
|
messages.push({ role: 'assistant', tool_calls: toolCalls });
|
|
280
281
|
for (const msg of toolMessages)
|
|
281
282
|
messages.push(msg);
|
|
282
|
-
const normalizedRole =
|
|
283
|
+
const normalizedRole = coerceBridgeRole(entry.role || 'user');
|
|
283
284
|
if (typeof text === 'string' && text.trim().length) {
|
|
284
285
|
messages.push({ role: normalizedRole, content: text.trim() });
|
|
285
286
|
}
|
|
@@ -288,7 +289,7 @@ function mapResponsesInputToChat(options) {
|
|
|
288
289
|
try {
|
|
289
290
|
const t = String(entry.type || '').toLowerCase();
|
|
290
291
|
if ((t === 'input_text' || t === 'text' || t === 'output_text' || t === 'commentary') && typeof entry.text === 'string') {
|
|
291
|
-
const normalizedRole =
|
|
292
|
+
const normalizedRole = coerceBridgeRole(entry.role || 'user');
|
|
292
293
|
const s = entry.text;
|
|
293
294
|
if (s && s.length)
|
|
294
295
|
messages.push({ role: normalizedRole, content: s });
|
|
@@ -339,7 +340,7 @@ function processMessageBlocks(blocks, toolsNormalized, toolNameById, toolCallIdA
|
|
|
339
340
|
currentLastCall = null;
|
|
340
341
|
continue;
|
|
341
342
|
}
|
|
342
|
-
const serialized =
|
|
343
|
+
const serialized = serializeToolArguments(parsedArgs, name, toolsNormalized).trim();
|
|
343
344
|
toolNameById.set(callId, name);
|
|
344
345
|
toolCalls.push({ id: callId, type: 'function', function: { name, arguments: serialized } });
|
|
345
346
|
currentLastCall = callId;
|
|
@@ -357,7 +358,7 @@ function processMessageBlocks(blocks, toolsNormalized, toolNameById, toolCallIdA
|
|
|
357
358
|
}
|
|
358
359
|
toolCallId = normalized;
|
|
359
360
|
}
|
|
360
|
-
const output =
|
|
361
|
+
const output = serializeToolOutput(block);
|
|
361
362
|
if (toolCallId) {
|
|
362
363
|
try {
|
|
363
364
|
let contentStr = output != null ? String(output) : '';
|
|
@@ -390,38 +391,6 @@ function processMessageBlocks(blocks, toolsNormalized, toolNameById, toolCallIdA
|
|
|
390
391
|
lastCallId: currentLastCall
|
|
391
392
|
};
|
|
392
393
|
}
|
|
393
|
-
function normalizeResponseRole(role) {
|
|
394
|
-
if (typeof role === 'string') {
|
|
395
|
-
const normalized = role.toLowerCase();
|
|
396
|
-
if (normalized === 'system' || normalized === 'assistant' || normalized === 'user' || normalized === 'tool')
|
|
397
|
-
return normalized;
|
|
398
|
-
}
|
|
399
|
-
return 'user';
|
|
400
|
-
}
|
|
401
|
-
function normalizeArgumentsBySchema(argsStringOrObj, _functionName, _tools) {
|
|
402
|
-
if (typeof argsStringOrObj === 'string')
|
|
403
|
-
return argsStringOrObj;
|
|
404
|
-
try {
|
|
405
|
-
return JSON.stringify(argsStringOrObj ?? {});
|
|
406
|
-
}
|
|
407
|
-
catch {
|
|
408
|
-
return String(argsStringOrObj);
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
function normalizeToolOutput(entry) {
|
|
412
|
-
const out = entry?.output;
|
|
413
|
-
if (typeof out === 'string')
|
|
414
|
-
return out;
|
|
415
|
-
if (out && typeof out === 'object') {
|
|
416
|
-
try {
|
|
417
|
-
return JSON.stringify(out);
|
|
418
|
-
}
|
|
419
|
-
catch {
|
|
420
|
-
return String(out);
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
return null;
|
|
424
|
-
}
|
|
425
394
|
function normalizeTools(tools) {
|
|
426
395
|
const normalized = [];
|
|
427
396
|
for (const tool of tools) {
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export declare function collectToolCallsFromResponses(response: Record<string, unknown>): Array<Record<string, unknown>>;
|
|
2
|
+
export declare function resolveFinishReason(response: Record<string, unknown>, toolCalls: Array<Record<string, unknown>>): string;
|
|
3
|
+
export declare function buildChatResponseFromResponses(payload: unknown): Record<string, unknown> | unknown;
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import { sanitizeResponsesFunctionName } from './responses-tool-utils.js';
|
|
2
|
+
import { normalizeFunctionCallId } from './bridge-id-utils.js';
|
|
3
|
+
import { extractOutputSegments } from './output-content-normalizer.js';
|
|
4
|
+
import { sanitizeReasoningTaggedText } from './reasoning-utils.js';
|
|
5
|
+
import { createBridgeActionState, runBridgeActionPipeline } from './bridge-actions.js';
|
|
6
|
+
import { resolveBridgePolicy, resolvePolicyActions } from './bridge-policies.js';
|
|
7
|
+
function selectCallId(entry) {
|
|
8
|
+
const candidates = [
|
|
9
|
+
entry?.call_id,
|
|
10
|
+
entry?.tool_call_id,
|
|
11
|
+
entry?.tool_use_id,
|
|
12
|
+
entry?.id
|
|
13
|
+
];
|
|
14
|
+
for (const candidate of candidates) {
|
|
15
|
+
if (typeof candidate === 'string' && candidate.trim().length > 0) {
|
|
16
|
+
return candidate.trim();
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
function normalizeToolCall(entry, fallbackPrefix) {
|
|
22
|
+
if (!entry || typeof entry !== 'object')
|
|
23
|
+
return null;
|
|
24
|
+
const fn = entry.function || {};
|
|
25
|
+
const rawName = sanitizeResponsesFunctionName(fn.name ?? entry.name);
|
|
26
|
+
if (!rawName)
|
|
27
|
+
return null;
|
|
28
|
+
const argsRaw = fn.arguments ?? entry.arguments ?? {};
|
|
29
|
+
const argsStr = typeof argsRaw === 'string'
|
|
30
|
+
? argsRaw
|
|
31
|
+
: (() => {
|
|
32
|
+
try {
|
|
33
|
+
return JSON.stringify(argsRaw ?? {});
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return '{}';
|
|
37
|
+
}
|
|
38
|
+
})();
|
|
39
|
+
const callIdRaw = selectCallId(entry);
|
|
40
|
+
const callId = typeof callIdRaw === 'string' && callIdRaw.length
|
|
41
|
+
? callIdRaw
|
|
42
|
+
: normalizeFunctionCallId({
|
|
43
|
+
callId: callIdRaw,
|
|
44
|
+
fallback: `${fallbackPrefix}_${Math.random().toString(36).slice(2, 10)}`
|
|
45
|
+
});
|
|
46
|
+
return {
|
|
47
|
+
id: callId,
|
|
48
|
+
type: 'function',
|
|
49
|
+
function: {
|
|
50
|
+
name: rawName,
|
|
51
|
+
arguments: argsStr
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
export function collectToolCallsFromResponses(response) {
|
|
56
|
+
const collected = [];
|
|
57
|
+
const seenIds = new Set();
|
|
58
|
+
const pushCall = (call, source) => {
|
|
59
|
+
if (!call)
|
|
60
|
+
return;
|
|
61
|
+
const key = typeof call.id === 'string' ? call.id : `${source}_${collected.length}`;
|
|
62
|
+
if (key && seenIds.has(key))
|
|
63
|
+
return;
|
|
64
|
+
if (key)
|
|
65
|
+
seenIds.add(key);
|
|
66
|
+
collected.push(call);
|
|
67
|
+
};
|
|
68
|
+
const required = response?.required_action?.submit_tool_outputs?.tool_calls;
|
|
69
|
+
if (Array.isArray(required)) {
|
|
70
|
+
for (const call of required) {
|
|
71
|
+
pushCall(normalizeToolCall(call, 'req_call'), 'req_call');
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
const outputItems = Array.isArray(response.output) ? response.output : [];
|
|
75
|
+
for (const item of outputItems) {
|
|
76
|
+
if (!item || typeof item !== 'object')
|
|
77
|
+
continue;
|
|
78
|
+
const type = typeof item.type === 'string' ? String(item.type).toLowerCase() : '';
|
|
79
|
+
if (type !== 'function_call')
|
|
80
|
+
continue;
|
|
81
|
+
pushCall(normalizeToolCall(item, 'output_call'), 'output_call');
|
|
82
|
+
}
|
|
83
|
+
return collected;
|
|
84
|
+
}
|
|
85
|
+
export function resolveFinishReason(response, toolCalls) {
|
|
86
|
+
const meta = response.metadata && typeof response.metadata === 'object'
|
|
87
|
+
? response.metadata
|
|
88
|
+
: undefined;
|
|
89
|
+
if (meta && typeof meta.finish_reason === 'string') {
|
|
90
|
+
return meta.finish_reason;
|
|
91
|
+
}
|
|
92
|
+
if (toolCalls.length > 0) {
|
|
93
|
+
return 'tool_calls';
|
|
94
|
+
}
|
|
95
|
+
const status = typeof response.status === 'string' ? response.status.toLowerCase() : '';
|
|
96
|
+
if (status === 'requires_action')
|
|
97
|
+
return 'tool_calls';
|
|
98
|
+
if (status === 'in_progress' || status === 'streaming')
|
|
99
|
+
return 'length';
|
|
100
|
+
if (status === 'cancelled')
|
|
101
|
+
return 'cancelled';
|
|
102
|
+
if (status === 'failed')
|
|
103
|
+
return 'error';
|
|
104
|
+
return 'stop';
|
|
105
|
+
}
|
|
106
|
+
function unwrapResponsesResponse(payload) {
|
|
107
|
+
if (!payload || typeof payload !== 'object')
|
|
108
|
+
return undefined;
|
|
109
|
+
if (typeof payload.object === 'string' && payload.object === 'response') {
|
|
110
|
+
return payload;
|
|
111
|
+
}
|
|
112
|
+
if (Array.isArray(payload.output) ||
|
|
113
|
+
typeof payload.status === 'string' ||
|
|
114
|
+
payload.required_action) {
|
|
115
|
+
return payload;
|
|
116
|
+
}
|
|
117
|
+
let current = payload;
|
|
118
|
+
const visited = new Set();
|
|
119
|
+
while (current && typeof current === 'object' && !Array.isArray(current)) {
|
|
120
|
+
if (visited.has(current))
|
|
121
|
+
break;
|
|
122
|
+
visited.add(current);
|
|
123
|
+
if (typeof current.object === 'string' && current.object === 'response') {
|
|
124
|
+
return current;
|
|
125
|
+
}
|
|
126
|
+
if (current.response && typeof current.response === 'object') {
|
|
127
|
+
current = current.response;
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
if (current.data && typeof current.data === 'object') {
|
|
131
|
+
current = current.data;
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
return undefined;
|
|
137
|
+
}
|
|
138
|
+
export function buildChatResponseFromResponses(payload) {
|
|
139
|
+
if (!payload || typeof payload !== 'object')
|
|
140
|
+
return payload;
|
|
141
|
+
const response = unwrapResponsesResponse(payload);
|
|
142
|
+
if (!response) {
|
|
143
|
+
if (Array.isArray(payload.choices))
|
|
144
|
+
return payload;
|
|
145
|
+
return payload;
|
|
146
|
+
}
|
|
147
|
+
const id = typeof response.id === 'string' ? response.id : `resp_${Date.now()}`;
|
|
148
|
+
const model = response.model;
|
|
149
|
+
const created = typeof response.created_at === 'number'
|
|
150
|
+
? response.created_at
|
|
151
|
+
: (response.created ?? Math.floor(Date.now() / 1000));
|
|
152
|
+
const usage = response.usage;
|
|
153
|
+
const toolCalls = collectToolCallsFromResponses(response);
|
|
154
|
+
const { textParts, reasoningParts } = extractOutputSegments(response);
|
|
155
|
+
const explicitOutput = typeof response.output_text === 'string' && response.output_text.trim().length
|
|
156
|
+
? sanitizeReasoningTaggedText(response.output_text)
|
|
157
|
+
: undefined;
|
|
158
|
+
const messageContentText = explicitOutput || textParts.join('\n').trim();
|
|
159
|
+
const messageContent = messageContentText || '';
|
|
160
|
+
const message = {
|
|
161
|
+
role: 'assistant',
|
|
162
|
+
content: messageContent
|
|
163
|
+
};
|
|
164
|
+
try {
|
|
165
|
+
const bridgePolicy = resolveBridgePolicy({ protocol: 'openai-responses', moduleType: 'openai-responses' });
|
|
166
|
+
const policyActions = resolvePolicyActions(bridgePolicy, 'response_inbound');
|
|
167
|
+
if (policyActions?.length) {
|
|
168
|
+
const actionState = createBridgeActionState({
|
|
169
|
+
messages: [message],
|
|
170
|
+
rawResponse: response
|
|
171
|
+
});
|
|
172
|
+
runBridgeActionPipeline({
|
|
173
|
+
stage: 'response_inbound',
|
|
174
|
+
actions: policyActions,
|
|
175
|
+
protocol: bridgePolicy?.protocol ?? 'openai-responses',
|
|
176
|
+
moduleType: bridgePolicy?.moduleType ?? 'openai-responses',
|
|
177
|
+
requestId: typeof response?.id === 'string' ? response.id : undefined,
|
|
178
|
+
state: actionState
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
catch {
|
|
183
|
+
// Ignore policy errors
|
|
184
|
+
}
|
|
185
|
+
if (toolCalls.length) {
|
|
186
|
+
message.tool_calls = toolCalls;
|
|
187
|
+
}
|
|
188
|
+
if (reasoningParts.length) {
|
|
189
|
+
message.reasoning_content = reasoningParts.join('\n');
|
|
190
|
+
}
|
|
191
|
+
const finishReason = resolveFinishReason(response, toolCalls);
|
|
192
|
+
const chat = {
|
|
193
|
+
id,
|
|
194
|
+
object: 'chat.completion',
|
|
195
|
+
created,
|
|
196
|
+
model,
|
|
197
|
+
choices: [
|
|
198
|
+
{
|
|
199
|
+
index: 0,
|
|
200
|
+
finish_reason: finishReason,
|
|
201
|
+
message
|
|
202
|
+
}
|
|
203
|
+
]
|
|
204
|
+
};
|
|
205
|
+
if (usage !== undefined) {
|
|
206
|
+
chat.usage = usage;
|
|
207
|
+
}
|
|
208
|
+
return chat;
|
|
209
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type ToolCallIdStyle = 'preserve' | 'fc';
|
|
2
|
+
type BridgeInputItem = Record<string, unknown>;
|
|
3
|
+
export interface CallIdTransformer {
|
|
4
|
+
normalizeCallId(raw: unknown): string;
|
|
5
|
+
normalizeOutputId(callId: string, raw: unknown): string;
|
|
6
|
+
}
|
|
7
|
+
export declare function createToolCallIdTransformer(style: ToolCallIdStyle): CallIdTransformer | null;
|
|
8
|
+
export declare function enforceToolCallIdStyle(input: BridgeInputItem[], transformer: CallIdTransformer): void;
|
|
9
|
+
export declare function resolveToolCallIdStyle(metadata: Record<string, unknown> | undefined): ToolCallIdStyle;
|
|
10
|
+
export declare function stripInternalToolingMetadata(metadata: unknown): void;
|
|
11
|
+
export declare function sanitizeResponsesFunctionName(rawName: unknown): string | undefined;
|
|
12
|
+
export {};
|