@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.
Files changed (91) hide show
  1. package/dist/conversion/codecs/anthropic-openai-codec.js +28 -2
  2. package/dist/conversion/codecs/gemini-openai-codec.js +23 -0
  3. package/dist/conversion/codecs/responses-openai-codec.js +8 -1
  4. package/dist/conversion/hub/node-support.js +14 -1
  5. package/dist/conversion/hub/pipeline/hub-pipeline.d.ts +66 -0
  6. package/dist/conversion/hub/pipeline/hub-pipeline.js +284 -193
  7. package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage1_format_parse/index.d.ts +11 -0
  8. package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage1_format_parse/index.js +6 -0
  9. package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage2_semantic_map/index.d.ts +16 -0
  10. package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage2_semantic_map/index.js +17 -0
  11. package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage3_context_capture/context-factories.d.ts +5 -0
  12. package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage3_context_capture/context-factories.js +17 -0
  13. package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage3_context_capture/index.d.ts +19 -0
  14. package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage3_context_capture/index.js +269 -0
  15. package/dist/conversion/hub/pipeline/stages/req_outbound/req_outbound_stage1_semantic_map/index.d.ts +18 -0
  16. package/dist/conversion/hub/pipeline/stages/req_outbound/req_outbound_stage1_semantic_map/index.js +141 -0
  17. package/dist/conversion/hub/pipeline/stages/req_outbound/req_outbound_stage2_format_build/index.d.ts +11 -0
  18. package/dist/conversion/hub/pipeline/stages/req_outbound/req_outbound_stage2_format_build/index.js +29 -0
  19. package/dist/conversion/hub/pipeline/stages/req_process/req_process_stage1_tool_governance/index.d.ts +16 -0
  20. package/dist/conversion/hub/pipeline/stages/req_process/req_process_stage1_tool_governance/index.js +15 -0
  21. package/dist/conversion/hub/pipeline/stages/req_process/req_process_stage2_route_select/index.d.ts +17 -0
  22. package/dist/conversion/hub/pipeline/stages/req_process/req_process_stage2_route_select/index.js +18 -0
  23. package/dist/conversion/hub/pipeline/stages/resp_inbound/resp_inbound_stage1_sse_decode/index.d.ts +17 -0
  24. package/dist/conversion/hub/pipeline/stages/resp_inbound/resp_inbound_stage1_sse_decode/index.js +63 -0
  25. package/dist/conversion/hub/pipeline/stages/resp_inbound/resp_inbound_stage2_format_parse/index.d.ts +11 -0
  26. package/dist/conversion/hub/pipeline/stages/resp_inbound/resp_inbound_stage2_format_parse/index.js +6 -0
  27. package/dist/conversion/hub/pipeline/stages/resp_inbound/resp_inbound_stage3_semantic_map/index.d.ts +12 -0
  28. package/dist/conversion/hub/pipeline/stages/resp_inbound/resp_inbound_stage3_semantic_map/index.js +6 -0
  29. package/dist/conversion/hub/pipeline/stages/resp_outbound/resp_outbound_stage1_client_remap/index.d.ts +13 -0
  30. package/dist/conversion/hub/pipeline/stages/resp_outbound/resp_outbound_stage1_client_remap/index.js +43 -0
  31. package/dist/conversion/hub/pipeline/stages/resp_outbound/resp_outbound_stage2_sse_stream/index.d.ts +17 -0
  32. package/dist/conversion/hub/pipeline/stages/resp_outbound/resp_outbound_stage2_sse_stream/index.js +22 -0
  33. package/dist/conversion/hub/pipeline/stages/resp_process/resp_process_stage1_tool_governance/index.d.ts +16 -0
  34. package/dist/conversion/hub/pipeline/stages/resp_process/resp_process_stage1_tool_governance/index.js +19 -0
  35. package/dist/conversion/hub/pipeline/stages/resp_process/resp_process_stage2_finalize/index.d.ts +17 -0
  36. package/dist/conversion/hub/pipeline/stages/resp_process/resp_process_stage2_finalize/index.js +19 -0
  37. package/dist/conversion/hub/pipeline/stages/utils.d.ts +2 -0
  38. package/dist/conversion/hub/pipeline/stages/utils.js +11 -0
  39. package/dist/conversion/hub/pipeline/target-utils.d.ts +5 -0
  40. package/dist/conversion/hub/pipeline/target-utils.js +87 -0
  41. package/dist/conversion/hub/process/chat-process.js +11 -11
  42. package/dist/conversion/hub/response/provider-response.js +69 -122
  43. package/dist/conversion/hub/response/response-mappers.d.ts +19 -0
  44. package/dist/conversion/hub/response/response-mappers.js +22 -2
  45. package/dist/conversion/hub/response/response-runtime.d.ts +8 -0
  46. package/dist/conversion/hub/response/response-runtime.js +239 -6
  47. package/dist/conversion/hub/semantic-mappers/anthropic-mapper.d.ts +8 -0
  48. package/dist/conversion/hub/semantic-mappers/anthropic-mapper.js +119 -59
  49. package/dist/conversion/hub/semantic-mappers/chat-mapper.js +74 -13
  50. package/dist/conversion/hub/semantic-mappers/gemini-mapper.js +0 -9
  51. package/dist/conversion/hub/semantic-mappers/responses-mapper.js +16 -13
  52. package/dist/conversion/hub/snapshot-recorder.d.ts +13 -0
  53. package/dist/conversion/hub/snapshot-recorder.js +90 -50
  54. package/dist/conversion/hub/standardized-bridge.js +44 -30
  55. package/dist/conversion/hub/types/chat-envelope.d.ts +68 -0
  56. package/dist/conversion/hub/types/standardized.d.ts +97 -0
  57. package/dist/conversion/pipeline/codecs/v2/anthropic-openai-pipeline.js +29 -2
  58. package/dist/conversion/pipeline/codecs/v2/responses-openai-pipeline.js +68 -1
  59. package/dist/conversion/responses/responses-openai-bridge.d.ts +6 -1
  60. package/dist/conversion/responses/responses-openai-bridge.js +132 -6
  61. package/dist/conversion/shared/anthropic-message-utils.d.ts +9 -1
  62. package/dist/conversion/shared/anthropic-message-utils.js +334 -14
  63. package/dist/conversion/shared/bridge-actions.js +267 -40
  64. package/dist/conversion/shared/bridge-message-utils.js +54 -8
  65. package/dist/conversion/shared/bridge-policies.js +29 -4
  66. package/dist/conversion/shared/chat-envelope-validator.d.ts +8 -0
  67. package/dist/conversion/shared/chat-envelope-validator.js +128 -0
  68. package/dist/conversion/shared/chat-request-filters.js +108 -25
  69. package/dist/conversion/shared/mcp-injection.js +41 -20
  70. package/dist/conversion/shared/openai-finalizer.d.ts +11 -0
  71. package/dist/conversion/shared/openai-finalizer.js +73 -0
  72. package/dist/conversion/shared/openai-message-normalize.js +32 -31
  73. package/dist/conversion/shared/reasoning-normalizer.d.ts +1 -0
  74. package/dist/conversion/shared/reasoning-normalizer.js +50 -18
  75. package/dist/conversion/shared/responses-output-builder.d.ts +1 -1
  76. package/dist/conversion/shared/responses-output-builder.js +76 -25
  77. package/dist/conversion/shared/responses-reasoning-registry.d.ts +8 -0
  78. package/dist/conversion/shared/responses-reasoning-registry.js +61 -0
  79. package/dist/conversion/shared/responses-response-utils.js +32 -2
  80. package/dist/conversion/shared/responses-tool-utils.js +28 -2
  81. package/dist/conversion/shared/snapshot-hooks.d.ts +9 -0
  82. package/dist/conversion/shared/snapshot-hooks.js +60 -6
  83. package/dist/conversion/shared/snapshot-utils.d.ts +16 -0
  84. package/dist/conversion/shared/snapshot-utils.js +84 -0
  85. package/dist/conversion/shared/tool-filter-pipeline.js +45 -5
  86. package/dist/conversion/shared/tool-mapping.js +13 -2
  87. package/dist/filters/special/request-tool-choice-policy.js +3 -1
  88. package/dist/filters/special/request-tool-list-filter.d.ts +11 -0
  89. package/dist/filters/special/request-tool-list-filter.js +20 -7
  90. package/dist/sse/shared/responses-output-normalizer.js +5 -4
  91. 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 anthropicPayload = buildAnthropicFromOpenAIChat(canonical);
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
- return runStandardChatRequestFilters(openaiPayload, profile, filterContext);
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
- export interface ResponsesRequestContext {
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: Array.isArray(payload.input) ? payload.input : undefined,
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 toolCallIdStyle = resolveToolCallIdStyle(envelopeMetadata);
197
- const historySeed = normalizeBridgeHistory(bridgeMetadata?.bridgeHistory ?? envelopeMetadata?.bridgeHistory ?? extras?.bridgeHistory);
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 declare function buildAnthropicFromOpenAIChat(oa: unknown): Unknown;
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 {};