@jsonstudio/llms 0.6.1892 → 0.6.2172

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (159) hide show
  1. package/dist/conversion/compat/actions/deepseek-web-request.js +16 -2
  2. package/dist/conversion/compat/actions/deepseek-web-response.d.ts +7 -1
  3. package/dist/conversion/compat/actions/deepseek-web-response.js +302 -40
  4. package/dist/conversion/compat/actions/harvest-tool-calls-from-text.d.ts +5 -0
  5. package/dist/conversion/compat/actions/harvest-tool-calls-from-text.js +7 -4
  6. package/dist/conversion/compat/actions/iflow-tool-text-fallback.d.ts +1 -0
  7. package/dist/conversion/compat/actions/iflow-tool-text-fallback.js +12 -0
  8. package/dist/conversion/compat/actions/strip-orphan-function-calls-tag.js +1 -1
  9. package/dist/conversion/compat/actions/tool-text-request-guidance.d.ts +9 -0
  10. package/dist/conversion/compat/actions/tool-text-request-guidance.js +177 -0
  11. package/dist/conversion/compat/antigravity-session-signature.d.ts +6 -0
  12. package/dist/conversion/compat/antigravity-session-signature.js +15 -0
  13. package/dist/conversion/compat/profiles/chat-deepseek-web.json +52 -1
  14. package/dist/conversion/compat/profiles/chat-glm.json +22 -0
  15. package/dist/conversion/compat/profiles/chat-iflow.json +4 -0
  16. package/dist/conversion/hub/operation-table/semantic-mappers/gemini-mapper.js +13 -27
  17. package/dist/conversion/hub/operation-table/semantic-mappers/responses-mapper.js +10 -1
  18. package/dist/conversion/hub/pipeline/compat/compat-pipeline-executor.js +13 -4
  19. package/dist/conversion/hub/pipeline/compat/compat-profile-resolver.js +1 -53
  20. package/dist/conversion/hub/pipeline/compat/compat-types.d.ts +8 -0
  21. package/dist/conversion/hub/pipeline/hub-pipeline.js +8 -4
  22. package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage3_context_capture/index.js +191 -9
  23. package/dist/conversion/hub/pipeline/stages/resp_inbound/resp_inbound_stage1_sse_decode/index.js +118 -15
  24. package/dist/conversion/hub/pipeline/stages/resp_process/resp_process_stage1_tool_governance/index.js +65 -2
  25. package/dist/conversion/hub/pipeline/stages/resp_process/resp_process_stage3_servertool_orchestration/index.d.ts +34 -0
  26. package/dist/conversion/hub/pipeline/stages/resp_process/resp_process_stage3_servertool_orchestration/index.js +75 -0
  27. package/dist/conversion/hub/process/chat-process.js +85 -18
  28. package/dist/conversion/hub/response/provider-response.js +21 -50
  29. package/dist/conversion/hub/response/response-runtime.js +71 -10
  30. package/dist/conversion/responses/responses-openai-bridge/response-payload.d.ts +3 -0
  31. package/dist/conversion/responses/responses-openai-bridge/response-payload.js +576 -0
  32. package/dist/conversion/responses/responses-openai-bridge/types.d.ts +42 -0
  33. package/dist/conversion/responses/responses-openai-bridge/types.js +1 -0
  34. package/dist/conversion/responses/responses-openai-bridge.d.ts +3 -44
  35. package/dist/conversion/responses/responses-openai-bridge.js +193 -504
  36. package/dist/conversion/shared/anthropic-message-utils.js +82 -2
  37. package/dist/conversion/shared/bridge-message-utils.js +92 -39
  38. package/dist/conversion/shared/snapshot-hooks.js +8 -13
  39. package/dist/conversion/shared/text-markup-normalizer/extractors-apply-patch.d.ts +2 -0
  40. package/dist/conversion/shared/text-markup-normalizer/extractors-apply-patch.js +129 -0
  41. package/dist/conversion/shared/text-markup-normalizer/extractors-json.d.ts +4 -0
  42. package/dist/conversion/shared/text-markup-normalizer/extractors-json.js +637 -0
  43. package/dist/conversion/shared/text-markup-normalizer/extractors-shared.d.ts +21 -0
  44. package/dist/conversion/shared/text-markup-normalizer/extractors-shared.js +177 -0
  45. package/dist/conversion/shared/text-markup-normalizer/extractors-transcript.d.ts +5 -0
  46. package/dist/conversion/shared/text-markup-normalizer/extractors-transcript.js +385 -0
  47. package/dist/conversion/shared/text-markup-normalizer/extractors-xml.d.ts +10 -0
  48. package/dist/conversion/shared/text-markup-normalizer/extractors-xml.js +602 -0
  49. package/dist/conversion/shared/text-markup-normalizer/extractors.d.ts +5 -0
  50. package/dist/conversion/shared/text-markup-normalizer/extractors.js +4 -0
  51. package/dist/conversion/shared/text-markup-normalizer/normalize.d.ts +2 -0
  52. package/dist/conversion/shared/text-markup-normalizer/normalize.js +76 -0
  53. package/dist/conversion/shared/text-markup-normalizer.d.ts +3 -25
  54. package/dist/conversion/shared/text-markup-normalizer.js +2 -1386
  55. package/dist/conversion/shared/tool-governor.js +136 -10
  56. package/dist/filters/utils/snapshot-writer.js +3 -3
  57. package/dist/router/virtual-router/bootstrap/auth-utils.d.ts +6 -0
  58. package/dist/router/virtual-router/bootstrap/auth-utils.js +288 -0
  59. package/dist/router/virtual-router/bootstrap/claude-code-helpers.d.ts +11 -0
  60. package/dist/router/virtual-router/bootstrap/claude-code-helpers.js +18 -0
  61. package/dist/router/virtual-router/bootstrap/config-defaults.d.ts +5 -0
  62. package/dist/router/virtual-router/bootstrap/config-defaults.js +13 -0
  63. package/dist/router/virtual-router/bootstrap/config-normalizers.d.ts +4 -0
  64. package/dist/router/virtual-router/bootstrap/config-normalizers.js +106 -0
  65. package/dist/router/virtual-router/bootstrap/profile-builder.d.ts +7 -0
  66. package/dist/router/virtual-router/bootstrap/profile-builder.js +68 -0
  67. package/dist/router/virtual-router/bootstrap/provider-normalization.d.ts +40 -0
  68. package/dist/router/virtual-router/bootstrap/provider-normalization.js +212 -0
  69. package/dist/router/virtual-router/bootstrap/responses-helpers.d.ts +15 -0
  70. package/dist/router/virtual-router/bootstrap/responses-helpers.js +65 -0
  71. package/dist/router/virtual-router/bootstrap/routing-config.d.ts +23 -0
  72. package/dist/router/virtual-router/bootstrap/routing-config.js +293 -0
  73. package/dist/router/virtual-router/bootstrap/streaming-helpers.d.ts +12 -0
  74. package/dist/router/virtual-router/bootstrap/streaming-helpers.js +128 -0
  75. package/dist/router/virtual-router/bootstrap/utils.d.ts +5 -0
  76. package/dist/router/virtual-router/bootstrap/utils.js +41 -0
  77. package/dist/router/virtual-router/bootstrap/web-search-config.d.ts +4 -0
  78. package/dist/router/virtual-router/bootstrap/web-search-config.js +131 -0
  79. package/dist/router/virtual-router/bootstrap.d.ts +0 -4
  80. package/dist/router/virtual-router/bootstrap.js +31 -1275
  81. package/dist/router/virtual-router/classifier.js +32 -14
  82. package/dist/router/virtual-router/engine/antigravity/alias-lease.js +2 -2
  83. package/dist/router/virtual-router/engine/cooldown-manager.d.ts +34 -0
  84. package/dist/router/virtual-router/engine/cooldown-manager.js +118 -0
  85. package/dist/router/virtual-router/engine/route-analytics.d.ts +28 -0
  86. package/dist/router/virtual-router/engine/route-analytics.js +44 -0
  87. package/dist/router/virtual-router/engine/routing-pools/index.js +165 -4
  88. package/dist/router/virtual-router/engine/sticky-session-manager.d.ts +29 -0
  89. package/dist/router/virtual-router/engine/sticky-session-manager.js +55 -0
  90. package/dist/router/virtual-router/engine-logging.d.ts +42 -1
  91. package/dist/router/virtual-router/engine-logging.js +82 -15
  92. package/dist/router/virtual-router/engine-selection/multimodal-capability.d.ts +3 -0
  93. package/dist/router/virtual-router/engine-selection/multimodal-capability.js +26 -0
  94. package/dist/router/virtual-router/engine-selection/route-utils.js +6 -2
  95. package/dist/router/virtual-router/engine-selection/selection-deps.d.ts +1 -0
  96. package/dist/router/virtual-router/engine-selection/tier-selection.js +31 -1
  97. package/dist/router/virtual-router/engine.d.ts +21 -7
  98. package/dist/router/virtual-router/engine.js +198 -194
  99. package/dist/router/virtual-router/features.js +12 -4
  100. package/dist/router/virtual-router/message-utils.d.ts +8 -0
  101. package/dist/router/virtual-router/message-utils.js +170 -45
  102. package/dist/router/virtual-router/pre-command-file-resolver.js +40 -2
  103. package/dist/router/virtual-router/routing-instructions.d.ts +8 -0
  104. package/dist/router/virtual-router/routing-instructions.js +18 -2
  105. package/dist/router/virtual-router/routing-stop-message-actions.js +34 -10
  106. package/dist/router/virtual-router/routing-stop-message-state-codec.d.ts +2 -0
  107. package/dist/router/virtual-router/routing-stop-message-state-codec.js +50 -1
  108. package/dist/router/virtual-router/stop-message-state-sync.d.ts +1 -1
  109. package/dist/router/virtual-router/stop-message-state-sync.js +3 -0
  110. package/dist/router/virtual-router/token-counter.js +51 -10
  111. package/dist/router/virtual-router/tool-signals.js +4 -0
  112. package/dist/router/virtual-router/types.d.ts +15 -0
  113. package/dist/servertool/clock/session-scope.d.ts +3 -0
  114. package/dist/servertool/clock/session-scope.js +52 -0
  115. package/dist/servertool/clock/state.js +9 -0
  116. package/dist/servertool/clock/tasks.js +12 -1
  117. package/dist/servertool/clock/types.d.ts +3 -0
  118. package/dist/servertool/engine.js +177 -31
  119. package/dist/servertool/handlers/clock-auto.js +2 -8
  120. package/dist/servertool/handlers/clock.js +6 -9
  121. package/dist/servertool/handlers/recursive-detection-guard.js +53 -14
  122. package/dist/servertool/handlers/stop-message-auto/blocked-report.d.ts +16 -0
  123. package/dist/servertool/handlers/stop-message-auto/blocked-report.js +349 -0
  124. package/dist/servertool/handlers/stop-message-auto/iflow-followup.d.ts +23 -0
  125. package/dist/servertool/handlers/stop-message-auto/iflow-followup.js +503 -0
  126. package/dist/servertool/handlers/stop-message-auto/routing-state.d.ts +38 -0
  127. package/dist/servertool/handlers/stop-message-auto/routing-state.js +149 -0
  128. package/dist/servertool/handlers/stop-message-auto/runtime-utils.d.ts +67 -0
  129. package/dist/servertool/handlers/stop-message-auto/runtime-utils.js +387 -0
  130. package/dist/servertool/handlers/stop-message-auto.d.ts +1 -1
  131. package/dist/servertool/handlers/stop-message-auto.js +80 -556
  132. package/dist/servertool/handlers/stop-message-stage-policy/bd-runtime.d.ts +18 -0
  133. package/dist/servertool/handlers/stop-message-stage-policy/bd-runtime.js +398 -0
  134. package/dist/servertool/handlers/stop-message-stage-policy/decision.d.ts +9 -0
  135. package/dist/servertool/handlers/stop-message-stage-policy/decision.js +127 -0
  136. package/dist/servertool/handlers/stop-message-stage-policy/observation.d.ts +2 -0
  137. package/dist/servertool/handlers/stop-message-stage-policy/observation.js +179 -0
  138. package/dist/servertool/handlers/stop-message-stage-policy/templates.d.ts +4 -0
  139. package/dist/servertool/handlers/stop-message-stage-policy/templates.js +96 -0
  140. package/dist/servertool/handlers/stop-message-stage-policy/text-utils.d.ts +9 -0
  141. package/dist/servertool/handlers/stop-message-stage-policy/text-utils.js +89 -0
  142. package/dist/servertool/handlers/stop-message-stage-policy/types.d.ts +59 -0
  143. package/dist/servertool/handlers/stop-message-stage-policy/types.js +1 -0
  144. package/dist/servertool/handlers/stop-message-stage-policy.d.ts +3 -43
  145. package/dist/servertool/handlers/stop-message-stage-policy.js +2 -684
  146. package/dist/servertool/handlers/web-search.js +117 -0
  147. package/dist/servertool/server-side-tools.d.ts +0 -1
  148. package/dist/servertool/server-side-tools.js +4 -3
  149. package/dist/sse/sse-to-json/builders/response-builder.js +16 -0
  150. package/dist/sse/sse-to-json/chat-sse-to-json-converter.d.ts +1 -0
  151. package/dist/sse/sse-to-json/chat-sse-to-json-converter.js +110 -37
  152. package/dist/telemetry/stats-center.d.ts +9 -0
  153. package/dist/telemetry/stats-center.js +29 -1
  154. package/dist/tools/apply-patch/structured/coercion.js +3 -11
  155. package/dist/tools/exec-command/validator.d.ts +1 -0
  156. package/dist/tools/exec-command/validator.js +132 -0
  157. package/dist/tools/tool-registry.d.ts +1 -0
  158. package/dist/tools/tool-registry.js +1 -1
  159. package/package.json +1 -1
@@ -0,0 +1,576 @@
1
+ import { evaluateResponsesHostPolicy } from '../responses-host-policy.js';
2
+ import { canonicalizeChatResponseTools } from '../../shared/tool-canonicalizer.js';
3
+ import { normalizeMessageReasoningTools } from '../../shared/reasoning-tool-normalizer.js';
4
+ import { createBridgeActionState, runBridgeActionPipeline } from '../../shared/bridge-actions.js';
5
+ import { resolveBridgePolicy, resolvePolicyActions } from '../../shared/bridge-policies.js';
6
+ import { buildResponsesOutputFromChat } from '../../shared/responses-output-builder.js';
7
+ import { consumeResponsesPayloadSnapshot, consumeResponsesPassthrough } from '../../shared/responses-reasoning-registry.js';
8
+ import { sanitizeResponsesFunctionName, stripInternalToolingMetadata } from '../../shared/responses-tool-utils.js';
9
+ import { ProviderProtocolError } from '../../shared/errors.js';
10
+ function isPlainObject(value) {
11
+ return Boolean(value && typeof value === 'object' && !Array.isArray(value));
12
+ }
13
+ function deepCloneRecord(value) {
14
+ try {
15
+ const structuredCloneImpl = globalThis.structuredClone;
16
+ if (typeof structuredCloneImpl === 'function') {
17
+ return structuredCloneImpl(value);
18
+ }
19
+ }
20
+ catch {
21
+ // ignore structuredClone failures
22
+ }
23
+ try {
24
+ return JSON.parse(JSON.stringify(value));
25
+ }
26
+ catch {
27
+ return { ...value };
28
+ }
29
+ }
30
+ function isMissingResponseField(value) {
31
+ if (value === undefined || value === null) {
32
+ return true;
33
+ }
34
+ if (Array.isArray(value)) {
35
+ return value.length === 0;
36
+ }
37
+ return false;
38
+ }
39
+ function mergeResponseOutputItems(baseOutput, sourceOutput) {
40
+ if (!Array.isArray(baseOutput) || !Array.isArray(sourceOutput)) {
41
+ return baseOutput;
42
+ }
43
+ const sourceById = new Map();
44
+ sourceOutput.forEach((entry) => {
45
+ if (!entry || typeof entry !== 'object' || Array.isArray(entry)) {
46
+ return;
47
+ }
48
+ const id = typeof entry.id === 'string' ? entry.id.trim() : '';
49
+ if (!id.length) {
50
+ return;
51
+ }
52
+ sourceById.set(id, entry);
53
+ });
54
+ return baseOutput.map((entry, index) => {
55
+ if (!entry || typeof entry !== 'object' || Array.isArray(entry)) {
56
+ return entry;
57
+ }
58
+ const baseItem = deepCloneRecord(entry);
59
+ const baseId = typeof baseItem.id === 'string' ? String(baseItem.id).trim() : '';
60
+ let sourceItem;
61
+ if (baseId.length) {
62
+ sourceItem = sourceById.get(baseId);
63
+ }
64
+ if (!sourceItem) {
65
+ const candidate = sourceOutput[index];
66
+ if (candidate && typeof candidate === 'object' && !Array.isArray(candidate)) {
67
+ sourceItem = candidate;
68
+ }
69
+ }
70
+ if (!sourceItem) {
71
+ return baseItem;
72
+ }
73
+ if (isMissingResponseField(baseItem.content) && sourceItem.content !== undefined) {
74
+ baseItem.content = deepCloneRecord({ value: sourceItem.content }).value;
75
+ }
76
+ if (isMissingResponseField(baseItem.summary) && sourceItem.summary !== undefined) {
77
+ baseItem.summary = deepCloneRecord({ value: sourceItem.summary }).value;
78
+ }
79
+ return baseItem;
80
+ });
81
+ }
82
+ function mergeResponseTopLevelFields(options) {
83
+ const merged = deepCloneRecord(options.base);
84
+ const source = options.source;
85
+ const sourceWins = options.sourceWinsKeys ?? [];
86
+ for (const key of sourceWins) {
87
+ if (source[key] !== undefined) {
88
+ merged[key] = deepCloneRecord({ value: source[key] }).value;
89
+ }
90
+ }
91
+ const passthroughKeys = ['metadata', 'temperature', 'top_p', 'prompt_cache_key', 'reasoning'];
92
+ for (const key of passthroughKeys) {
93
+ if (source[key] !== undefined && merged[key] === undefined) {
94
+ merged[key] = deepCloneRecord({ value: source[key] }).value;
95
+ }
96
+ }
97
+ if (merged.output !== undefined && source.output !== undefined) {
98
+ merged.output = mergeResponseOutputItems(merged.output, source.output);
99
+ }
100
+ return merged;
101
+ }
102
+ function tryParseJson(value) {
103
+ if (typeof value !== 'string')
104
+ return null;
105
+ const trimmed = value.trim();
106
+ if (!trimmed)
107
+ return null;
108
+ if (!(trimmed.startsWith('{') || trimmed.startsWith('[')))
109
+ return null;
110
+ try {
111
+ return JSON.parse(trimmed);
112
+ }
113
+ catch {
114
+ return null;
115
+ }
116
+ }
117
+ function looksLikeApplyPatchText(value) {
118
+ const trimmed = value.trim();
119
+ if (!trimmed)
120
+ return false;
121
+ return trimmed.includes('*** Begin Patch') && trimmed.includes('*** End Patch');
122
+ }
123
+ function extractFreeformTextFromArgs(argsRaw) {
124
+ if (typeof argsRaw === 'string') {
125
+ const trimmed = argsRaw.trim();
126
+ if (!trimmed)
127
+ return null;
128
+ // If JSON wrapper, extract common fields first.
129
+ const parsed = tryParseJson(trimmed);
130
+ if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
131
+ const rec = parsed;
132
+ for (const key of ['instructions', 'patch', 'input', 'text']) {
133
+ if (typeof rec[key] === 'string' && rec[key].trim().length) {
134
+ return String(rec[key]).trim();
135
+ }
136
+ }
137
+ }
138
+ // If it's already freeform (not a JSON wrapper), keep.
139
+ if (!trimmed.startsWith('{') && !trimmed.startsWith('[') && looksLikeApplyPatchText(trimmed)) {
140
+ return trimmed;
141
+ }
142
+ // Unknown freeform: return as-is so client can error.
143
+ return trimmed;
144
+ }
145
+ // If arguments is an object (malformed), try to extract patch-like fields.
146
+ if (argsRaw && typeof argsRaw === 'object' && !Array.isArray(argsRaw)) {
147
+ const rec = argsRaw;
148
+ for (const key of ['instructions', 'patch', 'input', 'text']) {
149
+ if (typeof rec[key] === 'string' && rec[key].trim().length) {
150
+ return String(rec[key]).trim();
151
+ }
152
+ }
153
+ }
154
+ return null;
155
+ }
156
+ function extractJsonSchemaLike(parameters) {
157
+ const required = Array.isArray(parameters.required)
158
+ ? parameters.required.filter((v) => typeof v === 'string' && v.trim().length > 0).map((v) => v.trim())
159
+ : [];
160
+ const props = parameters.properties && typeof parameters.properties === 'object' && !Array.isArray(parameters.properties)
161
+ ? parameters.properties
162
+ : {};
163
+ const properties = Object.keys(props);
164
+ if (!required.length && !properties.length) {
165
+ return null;
166
+ }
167
+ const additionalProperties = typeof parameters.additionalProperties === 'boolean' ? parameters.additionalProperties : true;
168
+ return { required, properties, additionalProperties };
169
+ }
170
+ function repairToolArgsBySchemaKeys(toolName, record, schema) {
171
+ // Apply known alias mappings only if the target keys are present in schema properties.
172
+ const wants = new Set(schema.properties);
173
+ const out = { ...record };
174
+ if (toolName === 'exec_command') {
175
+ if (wants.has('cmd') && out.command !== undefined && out.cmd === undefined)
176
+ out.cmd = out.command;
177
+ if (wants.has('command') && out.cmd !== undefined && out.command === undefined)
178
+ out.command = out.cmd;
179
+ }
180
+ if (toolName === 'write_stdin') {
181
+ if (wants.has('chars') && out.text !== undefined && out.chars === undefined)
182
+ out.chars = out.text;
183
+ if (wants.has('text') && out.chars !== undefined && out.text === undefined)
184
+ out.text = out.chars;
185
+ }
186
+ if (toolName === 'apply_patch') {
187
+ if (wants.has('instructions') && out.instructions === undefined) {
188
+ if (typeof out.patch === 'string' && out.patch.trim().length)
189
+ out.instructions = out.patch;
190
+ else if (typeof out.input === 'string' && out.input.trim().length)
191
+ out.instructions = out.input;
192
+ }
193
+ if (wants.has('patch') && out.patch === undefined) {
194
+ if (typeof out.instructions === 'string' && out.instructions.trim().length)
195
+ out.patch = out.instructions;
196
+ else if (typeof out.input === 'string' && out.input.trim().length)
197
+ out.patch = out.input;
198
+ }
199
+ }
200
+ for (const key of schema.required) {
201
+ if (!Object.prototype.hasOwnProperty.call(out, key)) {
202
+ return null;
203
+ }
204
+ }
205
+ if (schema.additionalProperties === false && schema.properties.length > 0) {
206
+ for (const key of Object.keys(out)) {
207
+ if (!wants.has(key))
208
+ delete out[key];
209
+ }
210
+ }
211
+ return out;
212
+ }
213
+ function buildClientToolIndex(toolsRaw) {
214
+ const index = new Map();
215
+ for (const tool of toolsRaw) {
216
+ if (!tool || typeof tool !== 'object' || Array.isArray(tool))
217
+ continue;
218
+ const t = tool;
219
+ const fn = t.function && typeof t.function === 'object' && !Array.isArray(t.function) ? t.function : undefined;
220
+ const nameRaw = (fn && typeof fn.name === 'string' ? fn.name : undefined) ?? (typeof t.name === 'string' ? t.name : undefined);
221
+ const name = typeof nameRaw === 'string' ? nameRaw.trim() : '';
222
+ if (!name)
223
+ continue;
224
+ const formatRaw = (typeof t.format === 'string' ? t.format : undefined) ??
225
+ (fn && typeof fn.format === 'string' ? fn.format : undefined);
226
+ const parametersRaw = (fn && fn.parameters && typeof fn.parameters === 'object' && !Array.isArray(fn.parameters) ? fn.parameters : undefined) ??
227
+ (t.parameters && typeof t.parameters === 'object' && !Array.isArray(t.parameters) ? t.parameters : undefined) ??
228
+ undefined;
229
+ index.set(name, {
230
+ name,
231
+ ...(typeof formatRaw === 'string' && formatRaw.trim().length ? { format: formatRaw.trim() } : {}),
232
+ ...(parametersRaw ? { parameters: parametersRaw } : {})
233
+ });
234
+ }
235
+ return index;
236
+ }
237
+ const CLIENT_TOOL_NAME_ALIASES = new Map([
238
+ ['shell_command', 'exec_command'],
239
+ ['shell', 'exec_command'],
240
+ ['bash', 'exec_command'],
241
+ ['terminal', 'exec_command']
242
+ ]);
243
+ function resolveClientToolName(toolIndex, rawToolName) {
244
+ const trimmed = rawToolName.trim();
245
+ if (!trimmed.length)
246
+ return undefined;
247
+ if (toolIndex.has(trimmed))
248
+ return trimmed;
249
+ const lower = trimmed.toLowerCase();
250
+ for (const key of toolIndex.keys()) {
251
+ if (key.toLowerCase() === lower) {
252
+ return key;
253
+ }
254
+ }
255
+ const aliased = CLIENT_TOOL_NAME_ALIASES.get(lower);
256
+ if (!aliased)
257
+ return undefined;
258
+ for (const key of toolIndex.keys()) {
259
+ if (key.toLowerCase() === aliased) {
260
+ return key;
261
+ }
262
+ }
263
+ return undefined;
264
+ }
265
+ function normalizeResponsesToolCallArgumentsForClient(responsesPayload, context) {
266
+ const toolsRaw = Array.isArray(context?.toolsRaw) ? context?.toolsRaw : [];
267
+ if (!toolsRaw.length) {
268
+ return;
269
+ }
270
+ const toolIndex = buildClientToolIndex(toolsRaw);
271
+ if (!toolIndex.size) {
272
+ return;
273
+ }
274
+ const normalizeCallArgs = (toolName, argsRaw) => {
275
+ const spec = toolIndex.get(toolName);
276
+ if (!spec)
277
+ return argsRaw;
278
+ // format:"freeform" means client expects raw text (not JSON) in the arguments field.
279
+ if (typeof spec.format === 'string' && spec.format.trim().toLowerCase() === 'freeform') {
280
+ const rawText = extractFreeformTextFromArgs(argsRaw);
281
+ if (rawText && rawText.trim().length) {
282
+ return rawText;
283
+ }
284
+ return argsRaw;
285
+ }
286
+ // Schema-aware key alignment for common server-side tools.
287
+ const params = spec.parameters;
288
+ if (!params)
289
+ return argsRaw;
290
+ const schema = extractJsonSchemaLike(params);
291
+ if (!schema)
292
+ return argsRaw;
293
+ const parsed = tryParseJson(argsRaw);
294
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
295
+ return argsRaw;
296
+ }
297
+ const record = parsed;
298
+ const repaired = repairToolArgsBySchemaKeys(toolName, record, schema);
299
+ if (!repaired) {
300
+ return argsRaw;
301
+ }
302
+ try {
303
+ return JSON.stringify(repaired);
304
+ }
305
+ catch {
306
+ return argsRaw;
307
+ }
308
+ };
309
+ // 1) output[] function_call items
310
+ const output = Array.isArray(responsesPayload.output) ? responsesPayload.output : [];
311
+ for (const item of output) {
312
+ if (!item || typeof item !== 'object')
313
+ continue;
314
+ const type = typeof item.type === 'string' ? String(item.type).trim().toLowerCase() : '';
315
+ if (type !== 'function_call')
316
+ continue;
317
+ const name = typeof item.name === 'string' ? String(item.name).trim() : '';
318
+ if (!name)
319
+ continue;
320
+ const targetName = resolveClientToolName(toolIndex, name);
321
+ if (!targetName)
322
+ continue;
323
+ if (targetName !== name) {
324
+ item.name = targetName;
325
+ }
326
+ item.arguments = normalizeCallArgs(targetName, item.arguments);
327
+ }
328
+ // 2) required_action.submit_tool_outputs.tool_calls[] tool calls
329
+ const toolCalls = responsesPayload?.required_action?.submit_tool_outputs?.tool_calls;
330
+ const calls = Array.isArray(toolCalls) ? toolCalls : [];
331
+ for (const call of calls) {
332
+ if (!call || typeof call !== 'object')
333
+ continue;
334
+ const fn = call.function && typeof call.function === 'object' && !Array.isArray(call.function) ? call.function : null;
335
+ const name = (typeof fn?.name === 'string' ? String(fn.name).trim() : '') ||
336
+ (typeof call.name === 'string' ? String(call.name).trim() : '');
337
+ if (!name)
338
+ continue;
339
+ const targetName = resolveClientToolName(toolIndex, name);
340
+ if (!targetName)
341
+ continue;
342
+ if (typeof call.name === 'string' && call.name !== targetName) {
343
+ call.name = targetName;
344
+ }
345
+ if (fn && typeof fn === 'object' && fn.name !== targetName) {
346
+ fn.name = targetName;
347
+ }
348
+ const normalizedArgs = normalizeCallArgs(targetName, fn?.arguments ?? call.arguments);
349
+ if (fn && typeof fn === 'object') {
350
+ fn.arguments = normalizedArgs;
351
+ }
352
+ call.arguments = normalizedArgs;
353
+ }
354
+ }
355
+ function unwrapData(value) {
356
+ let current = value;
357
+ const seen = new Set();
358
+ while (current && typeof current === 'object' && !Array.isArray(current) && !seen.has(current)) {
359
+ seen.add(current);
360
+ if ('choices' in current || 'message' in current)
361
+ break;
362
+ if ('data' in current && typeof current.data === 'object') {
363
+ current = current.data;
364
+ continue;
365
+ }
366
+ break;
367
+ }
368
+ return current;
369
+ }
370
+ function resolveSnapshotLookupKey(response, context) {
371
+ if (typeof response?.request_id === 'string') {
372
+ return response.request_id;
373
+ }
374
+ if (typeof context?.requestId === 'string') {
375
+ return context.requestId;
376
+ }
377
+ if (typeof response?.id === 'string') {
378
+ return response.id;
379
+ }
380
+ return undefined;
381
+ }
382
+ function shouldStripHostManagedFields(context) {
383
+ const result = evaluateResponsesHostPolicy(context, typeof context?.targetProtocol === 'string' ? context?.targetProtocol : undefined);
384
+ return result.shouldStripHostManagedFields;
385
+ }
386
+ export function buildResponsesPayloadFromChat(payload, context) {
387
+ if (!payload || typeof payload !== 'object')
388
+ return payload;
389
+ const response = unwrapData(payload);
390
+ if (!response || typeof response !== 'object')
391
+ return payload;
392
+ if (response.object === 'response' && Array.isArray(response.output)) {
393
+ return response;
394
+ }
395
+ const snapshotLookupKey = resolveSnapshotLookupKey(response, context);
396
+ const snapshotPayload = snapshotLookupKey ? consumeResponsesPayloadSnapshot(snapshotLookupKey) : undefined;
397
+ const passthroughPayload = snapshotLookupKey ? consumeResponsesPassthrough(snapshotLookupKey) : undefined;
398
+ const sourceForRetention = (passthroughPayload && typeof passthroughPayload === 'object' ? passthroughPayload : undefined) ??
399
+ (snapshotPayload && typeof snapshotPayload === 'object' ? snapshotPayload : undefined);
400
+ const hasChoicesArray = Array.isArray(response.choices);
401
+ const choicesLength = hasChoicesArray ? response.choices.length : 0;
402
+ if (!hasChoicesArray || choicesLength === 0) {
403
+ const rawStatus = response.status;
404
+ const statusCode = typeof rawStatus === 'string' && rawStatus.trim().length
405
+ ? rawStatus.trim()
406
+ : typeof rawStatus === 'number'
407
+ ? String(rawStatus)
408
+ : undefined;
409
+ const message = typeof response.msg === 'string' && response.msg.trim().length
410
+ ? response.msg.trim()
411
+ : typeof response.message === 'string' && response.message.trim().length
412
+ ? response.message.trim()
413
+ : 'Upstream returned non-standard Chat completion payload (missing choices).';
414
+ const out = {
415
+ id: response.id || `resp-${Date.now()}`,
416
+ object: 'response',
417
+ created_at: response.created_at || response.created || Math.floor(Date.now() / 1000),
418
+ model: response.model,
419
+ status: 'failed',
420
+ output: []
421
+ };
422
+ if (message) {
423
+ out.output_text = message;
424
+ out.error = {
425
+ type: 'provider_error',
426
+ code: statusCode,
427
+ message
428
+ };
429
+ }
430
+ if (context) {
431
+ for (const k of ['metadata', 'parallel_tool_calls', 'tool_choice', 'include']) {
432
+ if (context[k] !== undefined)
433
+ out[k] = context[k];
434
+ }
435
+ if (!shouldStripHostManagedFields(context) && context.store !== undefined) {
436
+ out.store = context.store;
437
+ }
438
+ }
439
+ if (typeof response.request_id === 'string') {
440
+ out.request_id = response.request_id;
441
+ }
442
+ else if (typeof response.id === 'string') {
443
+ out.request_id = response.id;
444
+ }
445
+ else if (typeof context?.requestId === 'string') {
446
+ out.request_id = context.requestId;
447
+ }
448
+ const mergedFallback = sourceForRetention && typeof sourceForRetention === 'object'
449
+ ? mergeResponseTopLevelFields({
450
+ base: out,
451
+ source: sourceForRetention,
452
+ sourceWinsKeys: ['metadata', 'temperature', 'top_p', 'prompt_cache_key', 'reasoning']
453
+ })
454
+ : out;
455
+ if (mergedFallback.metadata) {
456
+ stripInternalToolingMetadata(mergedFallback.metadata);
457
+ }
458
+ return mergedFallback;
459
+ }
460
+ const canonical = canonicalizeChatResponseTools(response);
461
+ const choices = Array.isArray(canonical?.choices) ? canonical.choices : [];
462
+ const primaryChoice = choices[0] && typeof choices[0] === 'object' ? choices[0] : undefined;
463
+ const message = primaryChoice && typeof primaryChoice.message === 'object' ? primaryChoice.message : undefined;
464
+ if (!message) {
465
+ throw new ProviderProtocolError('Responses bridge could not locate assistant message in Chat completion', {
466
+ code: 'MALFORMED_RESPONSE',
467
+ protocol: 'openai-chat',
468
+ providerType: 'openai',
469
+ details: {
470
+ context: 'buildResponsesPayloadFromChat',
471
+ choicesLength: choices.length,
472
+ requestId: context?.requestId
473
+ }
474
+ });
475
+ }
476
+ if (message) {
477
+ try {
478
+ const bridgePolicy = resolveBridgePolicy({ protocol: 'openai-responses', moduleType: 'openai-responses' });
479
+ const policyActions = resolvePolicyActions(bridgePolicy, 'response_outbound');
480
+ if (policyActions?.length) {
481
+ const actionState = createBridgeActionState({ messages: [message] });
482
+ runBridgeActionPipeline({
483
+ stage: 'response_outbound',
484
+ actions: policyActions,
485
+ protocol: bridgePolicy?.protocol ?? 'openai-responses',
486
+ moduleType: bridgePolicy?.moduleType ?? 'openai-responses',
487
+ requestId: context?.requestId,
488
+ state: actionState
489
+ });
490
+ }
491
+ }
492
+ catch (error) {
493
+ const errorMessage = error instanceof Error
494
+ ? error.message
495
+ : typeof error === 'string'
496
+ ? error
497
+ : 'unknown_error';
498
+ try {
499
+ // eslint-disable-next-line no-console
500
+ console.error(`\x1b[31m[responses-bridge][response_outbound] bridge action pipeline failed requestId=${context?.requestId ?? 'unknown'} error=${errorMessage}\x1b[0m`);
501
+ }
502
+ catch {
503
+ // ignore logging failures
504
+ }
505
+ }
506
+ }
507
+ if (message) {
508
+ try {
509
+ normalizeMessageReasoningTools(message, {
510
+ idPrefix: `responses_reasoning_${context?.requestId ?? 'canonical'}`
511
+ });
512
+ }
513
+ catch {
514
+ // best-effort reasoning normalization
515
+ }
516
+ }
517
+ const outputBuild = buildResponsesOutputFromChat({
518
+ response: response,
519
+ message,
520
+ requestId: context?.requestId,
521
+ sanitizeFunctionName: sanitizeResponsesFunctionName
522
+ });
523
+ const out = {
524
+ id: response.id || `resp-${Date.now()}`,
525
+ object: 'response',
526
+ created_at: response.created_at || response.created || Math.floor(Date.now() / 1000),
527
+ model: response.model,
528
+ status: outputBuild.status,
529
+ output: outputBuild.outputItems
530
+ };
531
+ if (typeof outputBuild.outputText === 'string') {
532
+ out.output_text = outputBuild.outputText;
533
+ }
534
+ if (outputBuild.usage !== undefined)
535
+ out.usage = outputBuild.usage;
536
+ if (outputBuild.requiredAction)
537
+ out.required_action = outputBuild.requiredAction;
538
+ normalizeResponsesToolCallArgumentsForClient(out, context);
539
+ if (context) {
540
+ for (const k of ['metadata', 'parallel_tool_calls', 'tool_choice', 'include']) {
541
+ if (context[k] !== undefined)
542
+ out[k] = context[k];
543
+ }
544
+ if (!shouldStripHostManagedFields(context) && context.store !== undefined) {
545
+ out.store = context.store;
546
+ }
547
+ }
548
+ if (typeof response.request_id === 'string') {
549
+ out.request_id = response.request_id;
550
+ }
551
+ else if (typeof response.id === 'string') {
552
+ out.request_id = response.id;
553
+ }
554
+ else if (typeof context?.requestId === 'string') {
555
+ out.request_id = context.requestId;
556
+ }
557
+ const merged = sourceForRetention && typeof sourceForRetention === 'object'
558
+ ? mergeResponseTopLevelFields({
559
+ base: out,
560
+ source: sourceForRetention,
561
+ sourceWinsKeys: ['metadata', 'temperature', 'top_p', 'prompt_cache_key', 'reasoning']
562
+ })
563
+ : out;
564
+ if (merged.metadata) {
565
+ stripInternalToolingMetadata(merged.metadata);
566
+ }
567
+ return merged;
568
+ }
569
+ export function extractRequestIdFromResponse(response) {
570
+ if (response && typeof response === 'object' && 'metadata' in response && response.metadata && typeof response.metadata === 'object') {
571
+ const meta = response.metadata;
572
+ if (typeof meta.requestId === 'string')
573
+ return meta.requestId;
574
+ }
575
+ return undefined;
576
+ }
@@ -0,0 +1,42 @@
1
+ import type { BridgeInputItem, BridgeToolDefinition } from '../../shared/bridge-message-types.js';
2
+ import type { ChatToolDefinition } from '../../hub/types/chat-envelope.js';
3
+ import type { JsonObject, JsonValue } from '../../hub/types/json.js';
4
+ import type { ToolCallIdStyle } from '../../shared/responses-tool-utils.js';
5
+ export type Unknown = Record<string, unknown>;
6
+ export interface ResponsesRequestContext extends Unknown {
7
+ requestId?: string;
8
+ originalSystemMessages?: string[];
9
+ input?: BridgeInputItem[];
10
+ include?: unknown;
11
+ store?: unknown;
12
+ serviceTier?: unknown;
13
+ truncation?: unknown;
14
+ toolChoice?: unknown;
15
+ parallelToolCalls?: boolean;
16
+ metadata?: JsonObject;
17
+ responseFormat?: JsonValue;
18
+ stream?: boolean;
19
+ isChatPayload?: boolean;
20
+ isResponsesPayload?: boolean;
21
+ historyMessages?: Array<{
22
+ role: string;
23
+ content: string;
24
+ }>;
25
+ currentMessage?: {
26
+ role: string;
27
+ content: string;
28
+ } | null;
29
+ toolsRaw?: BridgeToolDefinition[];
30
+ toolsNormalized?: Array<Record<string, unknown>>;
31
+ parameters?: Record<string, unknown>;
32
+ systemInstruction?: string;
33
+ toolCallIdStyle?: ToolCallIdStyle;
34
+ }
35
+ export interface BuildChatRequestResult {
36
+ request: Record<string, unknown>;
37
+ toolsNormalized?: ChatToolDefinition[];
38
+ }
39
+ export interface BuildResponsesRequestResult {
40
+ request: Record<string, unknown>;
41
+ originalSystemMessages?: string[];
42
+ }
@@ -1,46 +1,6 @@
1
- import type { BridgeInputItem, BridgeToolDefinition } from '../shared/bridge-message-types.js';
2
- import type { ChatToolDefinition } from '../hub/types/chat-envelope.js';
3
- import type { JsonObject, JsonValue } from '../hub/types/json.js';
4
1
  import type { BridgeInputBuildResult } from '../shared/bridge-message-utils.js';
5
- import type { ToolCallIdStyle } from '../shared/responses-tool-utils.js';
6
- type Unknown = Record<string, unknown>;
7
- export interface ResponsesRequestContext extends Unknown {
8
- requestId?: string;
9
- originalSystemMessages?: string[];
10
- input?: BridgeInputItem[];
11
- include?: unknown;
12
- store?: unknown;
13
- serviceTier?: unknown;
14
- truncation?: unknown;
15
- toolChoice?: unknown;
16
- parallelToolCalls?: boolean;
17
- metadata?: JsonObject;
18
- responseFormat?: JsonValue;
19
- stream?: boolean;
20
- isChatPayload?: boolean;
21
- isResponsesPayload?: boolean;
22
- historyMessages?: Array<{
23
- role: string;
24
- content: string;
25
- }>;
26
- currentMessage?: {
27
- role: string;
28
- content: string;
29
- } | null;
30
- toolsRaw?: BridgeToolDefinition[];
31
- toolsNormalized?: Array<Record<string, unknown>>;
32
- parameters?: Record<string, unknown>;
33
- systemInstruction?: string;
34
- toolCallIdStyle?: ToolCallIdStyle;
35
- }
36
- export interface BuildChatRequestResult {
37
- request: Record<string, unknown>;
38
- toolsNormalized?: ChatToolDefinition[];
39
- }
40
- export interface BuildResponsesRequestResult {
41
- request: Record<string, unknown>;
42
- originalSystemMessages?: string[];
43
- }
2
+ import type { BuildChatRequestResult, BuildResponsesRequestResult, ResponsesRequestContext } from './responses-openai-bridge/types.js';
3
+ export type { BuildChatRequestResult, BuildResponsesRequestResult, ResponsesRequestContext } from './responses-openai-bridge/types.js';
44
4
  export declare function captureResponsesContext(payload: Record<string, unknown>, dto?: {
45
5
  route?: {
46
6
  requestId?: string;
@@ -51,6 +11,5 @@ export declare function buildResponsesRequestFromChat(payload: Record<string, un
51
11
  bridgeHistory?: BridgeInputBuildResult;
52
12
  systemInstruction?: string;
53
13
  }): BuildResponsesRequestResult;
54
- export declare function buildResponsesPayloadFromChat(payload: unknown, context?: ResponsesRequestContext): Record<string, unknown> | unknown;
55
- export declare function extractRequestIdFromResponse(response: any): string | undefined;
14
+ export { buildResponsesPayloadFromChat, extractRequestIdFromResponse } from './responses-openai-bridge/response-payload.js';
56
15
  export { buildChatResponseFromResponses } from '../shared/responses-response-utils.js';