@jsonstudio/llms 0.6.1172 → 0.6.1397

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 (167) hide show
  1. package/dist/conversion/codecs/gemini-openai-codec.d.ts +3 -1
  2. package/dist/conversion/codecs/gemini-openai-codec.js +10 -4
  3. package/dist/conversion/compat/actions/gemini-web-search.d.ts +1 -1
  4. package/dist/conversion/compat/actions/gemini-web-search.js +5 -2
  5. package/dist/conversion/compat/actions/iflow-tool-text-fallback.d.ts +12 -0
  6. package/dist/conversion/compat/actions/iflow-tool-text-fallback.js +199 -0
  7. package/dist/conversion/compat/actions/iflow-web-search.d.ts +1 -1
  8. package/dist/conversion/compat/actions/iflow-web-search.js +5 -2
  9. package/dist/conversion/compat/profiles/chat-gemini.json +5 -0
  10. package/dist/conversion/hub/operation-table/semantic-mappers/anthropic-mapper.js +47 -56
  11. package/dist/conversion/hub/operation-table/semantic-mappers/chat-mapper.js +1 -13
  12. package/dist/conversion/hub/operation-table/semantic-mappers/gemini-mapper.js +748 -52
  13. package/dist/conversion/hub/operation-table/semantic-mappers/responses-mapper.js +18 -38
  14. package/dist/conversion/hub/pipeline/compat/compat-pipeline-executor.js +6 -0
  15. package/dist/conversion/hub/pipeline/compat/compat-types.d.ts +3 -0
  16. package/dist/conversion/hub/pipeline/hub-pipeline/adapter-context.d.ts +10 -0
  17. package/dist/conversion/hub/pipeline/hub-pipeline/adapter-context.js +142 -0
  18. package/dist/conversion/hub/pipeline/hub-pipeline/anthropic-alias-map.d.ts +6 -0
  19. package/dist/conversion/hub/pipeline/hub-pipeline/anthropic-alias-map.js +79 -0
  20. package/dist/conversion/hub/pipeline/hub-pipeline/apply-patch-tool-mode.d.ts +3 -0
  21. package/dist/conversion/hub/pipeline/hub-pipeline/apply-patch-tool-mode.js +46 -0
  22. package/dist/conversion/hub/pipeline/hub-pipeline/execute-chat-process-entry.d.ts +8 -0
  23. package/dist/conversion/hub/pipeline/hub-pipeline/execute-chat-process-entry.js +366 -0
  24. package/dist/conversion/hub/pipeline/hub-pipeline/execute-request-stage.d.ts +9 -0
  25. package/dist/conversion/hub/pipeline/hub-pipeline/execute-request-stage.js +390 -0
  26. package/dist/conversion/hub/pipeline/hub-pipeline/node-results.d.ts +3 -0
  27. package/dist/conversion/hub/pipeline/hub-pipeline/node-results.js +14 -0
  28. package/dist/conversion/hub/pipeline/hub-pipeline/payload-normalize.d.ts +2 -0
  29. package/dist/conversion/hub/pipeline/hub-pipeline/payload-normalize.js +144 -0
  30. package/dist/conversion/hub/pipeline/hub-pipeline/policy.d.ts +4 -0
  31. package/dist/conversion/hub/pipeline/hub-pipeline/policy.js +32 -0
  32. package/dist/conversion/hub/pipeline/hub-pipeline/protocol.d.ts +8 -0
  33. package/dist/conversion/hub/pipeline/hub-pipeline/protocol.js +63 -0
  34. package/dist/conversion/hub/pipeline/hub-pipeline/resolve-protocol-hooks.d.ts +2 -0
  35. package/dist/conversion/hub/pipeline/hub-pipeline/resolve-protocol-hooks.js +43 -0
  36. package/dist/conversion/hub/pipeline/hub-pipeline/semantic-gate.d.ts +1 -0
  37. package/dist/conversion/hub/pipeline/hub-pipeline/semantic-gate.js +29 -0
  38. package/dist/conversion/hub/pipeline/hub-pipeline/servertool-runtime-config.d.ts +2 -0
  39. package/dist/conversion/hub/pipeline/hub-pipeline/servertool-runtime-config.js +16 -0
  40. package/dist/conversion/hub/pipeline/hub-pipeline/types.d.ts +116 -0
  41. package/dist/conversion/hub/pipeline/hub-pipeline/types.js +1 -0
  42. package/dist/conversion/hub/pipeline/hub-pipeline.d.ts +3 -95
  43. package/dist/conversion/hub/pipeline/hub-pipeline.js +19 -1281
  44. package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage1_format_parse/index.js +1 -1
  45. package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage2_semantic_map/index.d.ts +7 -0
  46. package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage2_semantic_map/index.js +65 -1
  47. package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage3_context_capture/index.js +25 -22
  48. package/dist/conversion/hub/pipeline/stages/req_outbound/req_outbound_stage1_semantic_map/index.js +1 -1
  49. package/dist/conversion/hub/pipeline/stages/req_outbound/req_outbound_stage2_format_build/index.d.ts +1 -1
  50. package/dist/conversion/hub/pipeline/stages/req_outbound/req_outbound_stage2_format_build/index.js +2 -2
  51. package/dist/conversion/hub/pipeline/stages/req_outbound/req_outbound_stage2_thought_signature_inject/index.d.ts +10 -0
  52. package/dist/conversion/hub/pipeline/stages/req_outbound/req_outbound_stage2_thought_signature_inject/index.js +172 -0
  53. package/dist/conversion/hub/pipeline/stages/req_outbound/req_outbound_stage3_compat/index.js +2 -2
  54. package/dist/conversion/hub/pipeline/stages/req_process/req_process_stage1_tool_governance/index.js +1 -1
  55. package/dist/conversion/hub/pipeline/stages/req_process/req_process_stage2_route_select/index.js +1 -1
  56. package/dist/conversion/hub/pipeline/stages/resp_inbound/resp_inbound_stage1_sse_decode/index.js +11 -11
  57. package/dist/conversion/hub/pipeline/stages/resp_inbound/resp_inbound_stage2_format_parse/index.js +1 -1
  58. package/dist/conversion/hub/pipeline/stages/resp_inbound/resp_inbound_stage3_semantic_map/index.d.ts +1 -0
  59. package/dist/conversion/hub/pipeline/stages/resp_inbound/resp_inbound_stage3_semantic_map/index.js +4 -2
  60. package/dist/conversion/hub/pipeline/stages/resp_inbound/resp_inbound_stage3_thought_signature_capture/index.d.ts +10 -0
  61. package/dist/conversion/hub/pipeline/stages/resp_inbound/resp_inbound_stage3_thought_signature_capture/index.js +71 -0
  62. package/dist/conversion/hub/pipeline/stages/resp_outbound/resp_outbound_stage1_client_remap/index.d.ts +1 -0
  63. package/dist/conversion/hub/pipeline/stages/resp_outbound/resp_outbound_stage1_client_remap/index.js +17 -9
  64. package/dist/conversion/hub/pipeline/stages/resp_outbound/resp_outbound_stage2_sse_stream/index.js +2 -2
  65. package/dist/conversion/hub/pipeline/stages/resp_process/resp_process_stage1_tool_governance/index.js +40 -2
  66. package/dist/conversion/hub/pipeline/stages/resp_process/resp_process_stage2_finalize/index.js +1 -1
  67. package/dist/conversion/hub/pipeline/target-utils.js +9 -5
  68. package/dist/conversion/hub/pipeline/thought-signature/thought-signature-center.d.ts +14 -0
  69. package/dist/conversion/hub/pipeline/thought-signature/thought-signature-center.js +289 -0
  70. package/dist/conversion/hub/process/chat-process.js +256 -16
  71. package/dist/conversion/hub/response/provider-response.d.ts +8 -0
  72. package/dist/conversion/hub/response/provider-response.js +91 -27
  73. package/dist/conversion/hub/response/response-mappers.d.ts +10 -3
  74. package/dist/conversion/hub/response/response-mappers.js +30 -6
  75. package/dist/conversion/hub/response/response-runtime.js +4 -38
  76. package/dist/conversion/hub/snapshot-recorder.js +5 -1
  77. package/dist/conversion/hub/standardized-bridge.js +23 -15
  78. package/dist/conversion/pipeline/codecs/v2/anthropic-openai-pipeline.js +36 -5
  79. package/dist/conversion/responses/responses-openai-bridge.js +20 -4
  80. package/dist/conversion/shared/gemini-tool-utils.d.ts +8 -1
  81. package/dist/conversion/shared/gemini-tool-utils.js +580 -108
  82. package/dist/conversion/shared/jsonish.js +1 -1
  83. package/dist/conversion/shared/mcp-injection.js +67 -33
  84. package/dist/conversion/shared/openai-finalizer.js +2 -1
  85. package/dist/conversion/shared/openai-message-normalize.js +76 -21
  86. package/dist/conversion/shared/responses-output-builder.js +6 -0
  87. package/dist/conversion/shared/runtime-metadata.d.ts +7 -0
  88. package/dist/conversion/shared/runtime-metadata.js +23 -0
  89. package/dist/conversion/shared/text-markup-normalizer.d.ts +2 -0
  90. package/dist/conversion/shared/text-markup-normalizer.js +284 -4
  91. package/dist/conversion/shared/tool-canonicalizer.js +2 -1
  92. package/dist/conversion/shared/tool-governor.js +3 -3
  93. package/dist/filters/engine.js +5 -5
  94. package/dist/filters/special/request-tool-list-filter.js +194 -60
  95. package/dist/filters/special/request-tools-normalize.js +1 -1
  96. package/dist/filters/special/response-tool-text-canonicalize.d.ts +4 -7
  97. package/dist/filters/special/response-tool-text-canonicalize.js +7 -35
  98. package/dist/filters/special/tool-filter-hooks.js +58 -62
  99. package/dist/guidance/index.js +5 -1
  100. package/dist/http/sse-response.js +6 -6
  101. package/dist/router/virtual-router/bootstrap.js +54 -4
  102. package/dist/router/virtual-router/engine-health.d.ts +1 -1
  103. package/dist/router/virtual-router/engine-health.js +11 -110
  104. package/dist/router/virtual-router/engine-selection/alias-selection.d.ts +30 -0
  105. package/dist/router/virtual-router/engine-selection/alias-selection.js +237 -0
  106. package/dist/router/virtual-router/engine-selection/context-weight-multipliers.d.ts +11 -0
  107. package/dist/router/virtual-router/engine-selection/context-weight-multipliers.js +23 -0
  108. package/dist/router/virtual-router/engine-selection/direct-provider-model.d.ts +9 -0
  109. package/dist/router/virtual-router/engine-selection/direct-provider-model.js +49 -0
  110. package/dist/router/virtual-router/engine-selection/instruction-target.d.ts +6 -0
  111. package/dist/router/virtual-router/engine-selection/instruction-target.js +54 -0
  112. package/dist/router/virtual-router/engine-selection/key-parsing.d.ts +8 -0
  113. package/dist/router/virtual-router/engine-selection/key-parsing.js +64 -0
  114. package/dist/router/virtual-router/engine-selection/route-utils.d.ts +12 -0
  115. package/dist/router/virtual-router/engine-selection/route-utils.js +150 -0
  116. package/dist/router/virtual-router/engine-selection/routing-state-filter.d.ts +4 -0
  117. package/dist/router/virtual-router/engine-selection/routing-state-filter.js +50 -0
  118. package/dist/router/virtual-router/engine-selection/selection-deps.d.ts +39 -0
  119. package/dist/router/virtual-router/engine-selection/selection-deps.js +1 -0
  120. package/dist/router/virtual-router/engine-selection/sticky-pool.d.ts +11 -0
  121. package/dist/router/virtual-router/engine-selection/sticky-pool.js +109 -0
  122. package/dist/router/virtual-router/engine-selection/tier-priority.d.ts +12 -0
  123. package/dist/router/virtual-router/engine-selection/tier-priority.js +55 -0
  124. package/dist/router/virtual-router/engine-selection/tier-selection-select.d.ts +22 -0
  125. package/dist/router/virtual-router/engine-selection/tier-selection-select.js +423 -0
  126. package/dist/router/virtual-router/engine-selection/tier-selection.d.ts +3 -0
  127. package/dist/router/virtual-router/engine-selection/tier-selection.js +228 -0
  128. package/dist/router/virtual-router/engine-selection.d.ts +4 -30
  129. package/dist/router/virtual-router/engine-selection.js +10 -962
  130. package/dist/router/virtual-router/engine.d.ts +1 -0
  131. package/dist/router/virtual-router/engine.js +64 -11
  132. package/dist/router/virtual-router/routing-instructions.js +6 -1
  133. package/dist/router/virtual-router/stop-message-state-sync.d.ts +5 -0
  134. package/dist/router/virtual-router/stop-message-state-sync.js +6 -14
  135. package/dist/router/virtual-router/types.d.ts +38 -1
  136. package/dist/servertool/clock/config.d.ts +8 -0
  137. package/dist/servertool/clock/config.js +22 -0
  138. package/dist/servertool/clock/log.d.ts +3 -0
  139. package/dist/servertool/clock/log.js +13 -0
  140. package/dist/servertool/clock/task-store.d.ts +1 -1
  141. package/dist/servertool/clock/task-store.js +1 -1
  142. package/dist/servertool/clock/tasks.js +1 -1
  143. package/dist/servertool/engine.js +146 -21
  144. package/dist/servertool/handlers/clock-auto.js +11 -6
  145. package/dist/servertool/handlers/clock.js +36 -10
  146. package/dist/servertool/handlers/followup-request-builder.js +8 -2
  147. package/dist/servertool/handlers/gemini-empty-reply-continue.js +15 -9
  148. package/dist/servertool/handlers/iflow-model-error-retry.js +6 -4
  149. package/dist/servertool/handlers/recursive-detection-guard.js +4 -2
  150. package/dist/servertool/handlers/stop-message-auto.js +100 -10
  151. package/dist/servertool/handlers/vision.js +4 -1
  152. package/dist/servertool/handlers/web-search.js +3 -1
  153. package/dist/servertool/pending-session.d.ts +19 -0
  154. package/dist/servertool/pending-session.js +97 -0
  155. package/dist/servertool/reenter-backend.js +5 -3
  156. package/dist/servertool/server-side-tools.js +235 -6
  157. package/dist/servertool/types.d.ts +13 -0
  158. package/dist/sse/json-to-sse/event-generators/responses.js +1 -1
  159. package/dist/sse/shared/chat-serializer.js +2 -2
  160. package/dist/sse/shared/constants.js +1 -1
  161. package/dist/sse/sse-to-json/anthropic-sse-to-json-converter.d.ts +7 -1
  162. package/dist/sse/sse-to-json/builders/response-builder.js +16 -0
  163. package/dist/sse/sse-to-json/responses-sse-to-json-converter.d.ts +1 -1
  164. package/dist/tools/apply-patch/execution-capturer.js +1 -1
  165. package/dist/tools/exec-command/normalize.js +4 -0
  166. package/dist/tools/exec-command/regression-capturer.js +1 -1
  167. package/package.json +10 -5
@@ -55,11 +55,7 @@ function mapToolOutputs(entries, missing) {
55
55
  });
56
56
  return outputs.length ? outputs : undefined;
57
57
  }
58
- function deriveResumeToolOutputs(ctx) {
59
- if (!ctx || typeof ctx !== 'object') {
60
- return undefined;
61
- }
62
- const resume = ctx.responsesResume;
58
+ function deriveResumeToolOutputsFromResume(resume) {
63
59
  if (!resume || typeof resume !== 'object') {
64
60
  return undefined;
65
61
  }
@@ -252,12 +248,7 @@ function readResponsesResumeFromSemantics(chat) {
252
248
  }
253
249
  function selectResponsesContextSnapshot(chat, envelopeMetadata) {
254
250
  const semanticsContext = readResponsesContextFromSemantics(chat);
255
- const metadataContextCandidate = chat.metadata?.responsesContext;
256
- const metadataContext = metadataContextCandidate && isJsonObject(metadataContextCandidate)
257
- ? jsonClone(metadataContextCandidate)
258
- : undefined;
259
251
  const context = semanticsContext ??
260
- metadataContext ??
261
252
  {
262
253
  metadata: envelopeMetadata
263
254
  };
@@ -267,10 +258,7 @@ function selectResponsesContextSnapshot(chat, envelopeMetadata) {
267
258
  }
268
259
  return context;
269
260
  }
270
- function resolveSubmitResponseId(ctx, responsesContext) {
271
- const resumeMeta = ctx.responsesResume && typeof ctx.responsesResume === 'object'
272
- ? ctx.responsesResume
273
- : undefined;
261
+ function resolveSubmitResponseId(resumeMeta, responsesContext) {
274
262
  const resumeId = typeof resumeMeta?.restoredFromResponseId === 'string'
275
263
  ? resumeMeta.restoredFromResponseId.trim()
276
264
  : undefined;
@@ -342,7 +330,7 @@ function extractCapturedToolOutputs(responsesContext) {
342
330
  });
343
331
  return entries;
344
332
  }
345
- function collectSubmitToolOutputs(chat, ctx, responsesContext) {
333
+ function collectSubmitToolOutputs(chat, responsesContext) {
346
334
  const outputs = [];
347
335
  const seen = new Set();
348
336
  const append = (idSeed, outputSeed, name) => {
@@ -369,11 +357,9 @@ function collectSubmitToolOutputs(chat, ctx, responsesContext) {
369
357
  captured.forEach((entry) => append(entry.tool_call_id ?? entry.id, entry.output, entry.name));
370
358
  }
371
359
  if (!outputs.length) {
372
- const resume = ctx.responsesResume && typeof ctx.responsesResume === 'object'
373
- ? ctx.responsesResume
374
- : undefined;
360
+ const resume = readResponsesResumeFromSemantics(chat);
375
361
  const detailed = Array.isArray(resume?.toolOutputsDetailed)
376
- ? resume?.toolOutputsDetailed
362
+ ? (resume.toolOutputsDetailed ?? undefined)
377
363
  : undefined;
378
364
  if (detailed) {
379
365
  detailed.forEach((entry, index) => {
@@ -417,17 +403,23 @@ function resolveSubmitModel(chat, responsesContext) {
417
403
  return undefined;
418
404
  }
419
405
  function buildSubmitToolOutputsPayload(chat, ctx, responsesContext) {
420
- const responseId = resolveSubmitResponseId(ctx, responsesContext);
406
+ const resumeMeta = (() => {
407
+ try {
408
+ const resume = readResponsesResumeFromSemantics(chat);
409
+ return resume && typeof resume === 'object' && !Array.isArray(resume) ? resume : undefined;
410
+ }
411
+ catch {
412
+ return undefined;
413
+ }
414
+ })();
415
+ const responseId = resolveSubmitResponseId(resumeMeta, responsesContext);
421
416
  if (!responseId) {
422
417
  throw new Error('Submit tool outputs requires response_id from Responses resume context');
423
418
  }
424
- const toolOutputs = collectSubmitToolOutputs(chat, ctx, responsesContext);
419
+ const toolOutputs = collectSubmitToolOutputs(chat, responsesContext);
425
420
  if (!toolOutputs.length) {
426
421
  throw new Error('Submit tool outputs requires at least one tool output entry');
427
422
  }
428
- const resumeMeta = ctx.responsesResume && typeof ctx.responsesResume === 'object'
429
- ? ctx.responsesResume
430
- : undefined;
431
423
  const payload = {
432
424
  response_id: responseId,
433
425
  tool_outputs: toolOutputs
@@ -454,25 +446,13 @@ export class ResponsesSemanticMapper {
454
446
  const missingFields = [];
455
447
  const messages = normalizeMessages(request.messages, missingFields);
456
448
  let toolOutputs = mapToolOutputs(payload.tool_outputs, missingFields);
457
- if (!toolOutputs || toolOutputs.length === 0) {
458
- const resumeToolOutputs = deriveResumeToolOutputs(ctx);
459
- if (resumeToolOutputs && resumeToolOutputs.length) {
460
- toolOutputs = resumeToolOutputs;
461
- }
462
- }
463
449
  const parameters = collectParameters(payload, responsesContext.stream);
464
450
  const metadata = { context: ctx };
465
451
  if (missingFields.length) {
466
452
  metadata.missingFields = missingFields;
467
453
  }
468
- if (responsesContext.responseFormat) {
469
- metadata.responseFormat = jsonClone(responsesContext.responseFormat);
470
- }
471
- metadata.responsesContext = jsonClone(responsesContext);
472
- const resumeNode = ctx.responsesResume && isJsonObject(ctx.responsesResume)
473
- ? ctx.responsesResume
474
- : undefined;
475
- const semantics = attachResponsesSemantics(undefined, responsesContext, resumeNode);
454
+ // Keep responses protocol semantics in chat.semantics (not metadata).
455
+ const semantics = attachResponsesSemantics(undefined, responsesContext, undefined);
476
456
  return {
477
457
  messages,
478
458
  tools: normalizeTools(toolsNormalized, missingFields),
@@ -13,6 +13,7 @@ import { extractGlmToolMarkup } from '../../../compat/actions/glm-tool-extractio
13
13
  import { applyGlmWebSearchRequestTransform } from '../../../compat/actions/glm-web-search.js';
14
14
  import { applyGeminiWebSearchCompat } from '../../../compat/actions/gemini-web-search.js';
15
15
  import { applyIflowWebSearchRequestTransform } from '../../../compat/actions/iflow-web-search.js';
16
+ import { applyIflowToolTextFallback } from '../../../compat/actions/iflow-tool-text-fallback.js';
16
17
  import { applyGlmImageContentTransform } from '../../../compat/actions/glm-image-content.js';
17
18
  import { applyGlmVisionPromptTransform } from '../../../compat/actions/glm-vision-prompt.js';
18
19
  import { applyClaudeThinkingToolSchemaCompat } from '../../../compat/actions/claude-thinking-tools.js';
@@ -189,6 +190,11 @@ function applyMapping(root, mapping, state) {
189
190
  replaceRoot(root, applyIflowWebSearchRequestTransform(root, state.adapterContext));
190
191
  }
191
192
  break;
193
+ case 'iflow_tool_text_fallback':
194
+ if (state.direction === 'request') {
195
+ replaceRoot(root, applyIflowToolTextFallback(root, { models: mapping.models }));
196
+ }
197
+ break;
192
198
  case 'claude_thinking_tool_schema':
193
199
  if (state.direction === 'request') {
194
200
  replaceRoot(root, applyClaudeThinkingToolSchemaCompat(root, state.adapterContext));
@@ -111,6 +111,9 @@ export type MappingInstruction = {
111
111
  action: 'gemini_web_search_request';
112
112
  } | {
113
113
  action: 'iflow_web_search_request';
114
+ } | {
115
+ action: 'iflow_tool_text_fallback';
116
+ models?: string[];
114
117
  } | {
115
118
  action: 'claude_thinking_tool_schema';
116
119
  };
@@ -0,0 +1,10 @@
1
+ import type { StandardizedRequest, ProcessedRequest } from '../../types/standardized.js';
2
+ import type { AdapterContext } from '../../types/chat-envelope.js';
3
+ import type { StageRecorder } from '../../format-adapters/index.js';
4
+ import type { NormalizedRequest, TargetMetadata } from './types.js';
5
+ export declare function buildAdapterContext(normalized: NormalizedRequest, target?: TargetMetadata): AdapterContext;
6
+ export declare function maybeCreateStageRecorder(context: AdapterContext, endpoint?: string, options?: {
7
+ disableSnapshots?: boolean;
8
+ }): StageRecorder | undefined;
9
+ export declare function resolveOutboundStreamIntent(providerPreference?: TargetMetadata['streaming']): boolean | undefined;
10
+ export declare function applyOutboundStreamPreference(request: StandardizedRequest | ProcessedRequest, stream: boolean | undefined): StandardizedRequest | ProcessedRequest;
@@ -0,0 +1,142 @@
1
+ import { jsonClone } from '../../types/json.js';
2
+ import { applyHubOperations } from '../../ops/operations.js';
3
+ import { createSnapshotRecorder } from '../../snapshot-recorder.js';
4
+ import { shouldRecordSnapshots } from '../../../shared/snapshot-utils.js';
5
+ import { cloneRuntimeMetadata } from '../../../shared/runtime-metadata.js';
6
+ function normalizeToolCallIdStyleCandidate(value) {
7
+ if (typeof value !== 'string') {
8
+ return undefined;
9
+ }
10
+ const normalized = value.trim().toLowerCase();
11
+ if (normalized === 'fc') {
12
+ return 'fc';
13
+ }
14
+ if (normalized === 'preserve') {
15
+ return 'preserve';
16
+ }
17
+ return undefined;
18
+ }
19
+ export function buildAdapterContext(normalized, target) {
20
+ const metadata = normalized.metadata || {};
21
+ const providerProtocol = target?.outboundProfile || normalized.providerProtocol;
22
+ const providerId = (target?.providerKey || metadata.providerKey);
23
+ const routeId = metadata.routeName;
24
+ const profileId = (target?.providerKey || metadata.pipelineId);
25
+ const streamingHint = normalized.stream === true ? 'force' : normalized.stream === false ? 'disable' : 'auto';
26
+ const toolCallIdStyle = normalizeToolCallIdStyleCandidate(metadata.toolCallIdStyle);
27
+ const adapterContext = {
28
+ requestId: normalized.id,
29
+ entryEndpoint: normalized.entryEndpoint || '/v1/chat/completions',
30
+ providerProtocol,
31
+ providerId,
32
+ routeId,
33
+ profileId,
34
+ streamingHint,
35
+ toolCallIdStyle
36
+ };
37
+ const runtime = metadata.runtime;
38
+ if (runtime && typeof runtime === 'object' && !Array.isArray(runtime)) {
39
+ adapterContext.runtime = jsonClone(runtime);
40
+ }
41
+ const clientRequestId = typeof metadata.clientRequestId === 'string'
42
+ ? metadata.clientRequestId.trim()
43
+ : '';
44
+ if (clientRequestId) {
45
+ adapterContext.clientRequestId = clientRequestId;
46
+ }
47
+ const groupRequestId = typeof metadata.groupRequestId === 'string'
48
+ ? metadata.groupRequestId.trim()
49
+ : '';
50
+ if (groupRequestId) {
51
+ adapterContext.groupRequestId = groupRequestId;
52
+ }
53
+ if (typeof metadata.originalModelId === 'string') {
54
+ adapterContext.originalModelId = metadata.originalModelId;
55
+ }
56
+ if (typeof metadata.clientModelId === 'string') {
57
+ adapterContext.clientModelId = metadata.clientModelId;
58
+ }
59
+ if (typeof metadata.assignedModelId === 'string') {
60
+ adapterContext.modelId = metadata.assignedModelId;
61
+ }
62
+ const rt = cloneRuntimeMetadata(metadata);
63
+ if (rt) {
64
+ adapterContext.__rt = rt;
65
+ }
66
+ const sessionId = typeof metadata.sessionId === 'string'
67
+ ? metadata.sessionId.trim()
68
+ : '';
69
+ if (sessionId) {
70
+ adapterContext.sessionId = sessionId;
71
+ }
72
+ const conversationId = typeof metadata.conversationId === 'string'
73
+ ? metadata.conversationId.trim()
74
+ : '';
75
+ if (conversationId) {
76
+ adapterContext.conversationId = conversationId;
77
+ }
78
+ const projectIdRaw = typeof metadata.projectId === 'string'
79
+ ? metadata.projectId.trim()
80
+ : typeof metadata.project_id === 'string'
81
+ ? metadata.project_id.trim()
82
+ : '';
83
+ if (projectIdRaw) {
84
+ adapterContext.projectId = projectIdRaw;
85
+ }
86
+ const clientConnectionState = metadata.clientConnectionState;
87
+ if (clientConnectionState && typeof clientConnectionState === 'object' && !Array.isArray(clientConnectionState)) {
88
+ const stateRecord = clientConnectionState;
89
+ adapterContext.clientConnectionState = clientConnectionState;
90
+ if (typeof stateRecord.disconnected === 'boolean') {
91
+ adapterContext.clientDisconnected = stateRecord.disconnected;
92
+ }
93
+ }
94
+ const clientDisconnectedRaw = metadata.clientDisconnected;
95
+ if (clientDisconnectedRaw === true ||
96
+ (typeof clientDisconnectedRaw === 'string' && clientDisconnectedRaw.trim().toLowerCase() === 'true')) {
97
+ adapterContext.clientDisconnected = true;
98
+ }
99
+ if (target?.compatibilityProfile && typeof target.compatibilityProfile === 'string') {
100
+ adapterContext.compatibilityProfile = target.compatibilityProfile;
101
+ }
102
+ return adapterContext;
103
+ }
104
+ export function maybeCreateStageRecorder(context, endpoint, options) {
105
+ if (options?.disableSnapshots === true) {
106
+ return undefined;
107
+ }
108
+ if (!shouldRecordSnapshots()) {
109
+ return undefined;
110
+ }
111
+ const effectiveEndpoint = endpoint || context.entryEndpoint || '/v1/chat/completions';
112
+ try {
113
+ return createSnapshotRecorder(context, effectiveEndpoint);
114
+ }
115
+ catch {
116
+ return undefined;
117
+ }
118
+ }
119
+ export function resolveOutboundStreamIntent(providerPreference) {
120
+ if (providerPreference === 'always') {
121
+ return true;
122
+ }
123
+ if (providerPreference === 'never') {
124
+ return false;
125
+ }
126
+ return undefined;
127
+ }
128
+ export function applyOutboundStreamPreference(request, stream) {
129
+ if (!request || typeof request !== 'object') {
130
+ return request;
131
+ }
132
+ const ops = [];
133
+ if (typeof stream === 'boolean') {
134
+ ops.push({ op: 'set_request_parameter_fields', fields: { stream } });
135
+ ops.push({ op: 'set_request_metadata_fields', fields: { outboundStream: stream } });
136
+ }
137
+ else {
138
+ ops.push({ op: 'unset_request_parameter_keys', keys: ['stream'] });
139
+ ops.push({ op: 'unset_request_metadata_keys', keys: ['outboundStream'] });
140
+ }
141
+ return applyHubOperations(request, ops);
142
+ }
@@ -0,0 +1,6 @@
1
+ import type { AdapterContext, ChatEnvelope } from '../../types/chat-envelope.js';
2
+ export declare function captureAnthropicToolNameAliasMap(options: {
3
+ entryEndpoint: string;
4
+ adapterContext: AdapterContext;
5
+ chatEnvelope: ChatEnvelope;
6
+ }): void;
@@ -0,0 +1,79 @@
1
+ import { isJsonObject, jsonClone } from '../../types/json.js';
2
+ function coerceAliasMap(candidate) {
3
+ if (!candidate || typeof candidate !== 'object' || Array.isArray(candidate)) {
4
+ return undefined;
5
+ }
6
+ const normalized = {};
7
+ for (const [key, value] of Object.entries(candidate)) {
8
+ if (typeof key !== 'string' || typeof value !== 'string') {
9
+ continue;
10
+ }
11
+ const trimmedKey = key.trim();
12
+ const trimmedValue = value.trim();
13
+ if (!trimmedKey.length || !trimmedValue.length) {
14
+ continue;
15
+ }
16
+ normalized[trimmedKey] = trimmedValue;
17
+ }
18
+ return Object.keys(normalized).length ? normalized : undefined;
19
+ }
20
+ function readAliasMapFromSemantics(chatEnvelope) {
21
+ if (!chatEnvelope?.semantics || typeof chatEnvelope.semantics !== 'object') {
22
+ return undefined;
23
+ }
24
+ const node = chatEnvelope.semantics.tools;
25
+ if (!node || !isJsonObject(node)) {
26
+ return undefined;
27
+ }
28
+ const candidate = node.toolNameAliasMap ?? node.toolAliasMap;
29
+ return coerceAliasMap(candidate);
30
+ }
31
+ function shouldCapture(entryEndpoint) {
32
+ return typeof entryEndpoint === 'string' && entryEndpoint.toLowerCase().includes('/v1/messages');
33
+ }
34
+ function resolveAliasMapFromSources(adapterContext, chatEnvelope) {
35
+ const fromContext = coerceAliasMap(adapterContext.anthropicToolNameMap);
36
+ if (fromContext) {
37
+ return fromContext;
38
+ }
39
+ const metadataNode = chatEnvelope.metadata;
40
+ const direct = metadataNode ? coerceAliasMap(metadataNode.anthropicToolNameMap) : undefined;
41
+ if (direct) {
42
+ return direct;
43
+ }
44
+ const contextNode = metadataNode && metadataNode.context && typeof metadataNode.context === 'object'
45
+ ? metadataNode.context
46
+ : undefined;
47
+ const fromContextNode = coerceAliasMap(contextNode?.anthropicToolNameMap);
48
+ if (fromContextNode) {
49
+ return fromContextNode;
50
+ }
51
+ return readAliasMapFromSemantics(chatEnvelope);
52
+ }
53
+ export function captureAnthropicToolNameAliasMap(options) {
54
+ if (!shouldCapture(options.entryEndpoint)) {
55
+ return;
56
+ }
57
+ const aliasMap = resolveAliasMapFromSources(options.adapterContext, options.chatEnvelope);
58
+ if (!aliasMap) {
59
+ return;
60
+ }
61
+ // Tool name alias map is mappable semantics and must live in chat.semantics (never metadata).
62
+ try {
63
+ const chatEnvelope = options.chatEnvelope;
64
+ if (!chatEnvelope.semantics || typeof chatEnvelope.semantics !== 'object' || Array.isArray(chatEnvelope.semantics)) {
65
+ chatEnvelope.semantics = {};
66
+ }
67
+ const semantics = chatEnvelope.semantics;
68
+ if (!semantics.tools || !isJsonObject(semantics.tools)) {
69
+ semantics.tools = {};
70
+ }
71
+ const toolsNode = semantics.tools;
72
+ if (!isJsonObject(toolsNode.toolNameAliasMap) && !isJsonObject(toolsNode.toolAliasMap)) {
73
+ toolsNode.toolNameAliasMap = jsonClone(aliasMap);
74
+ }
75
+ }
76
+ catch {
77
+ // best-effort: never block request handling due to alias map propagation failures
78
+ }
79
+ }
@@ -0,0 +1,3 @@
1
+ import type { ApplyPatchToolMode } from './types.js';
2
+ export declare function resolveApplyPatchToolModeFromEnv(): ApplyPatchToolMode | undefined;
3
+ export declare function resolveApplyPatchToolModeFromTools(toolsRaw: unknown): ApplyPatchToolMode | undefined;
@@ -0,0 +1,46 @@
1
+ function isTruthyEnv(value) {
2
+ const v = typeof value === 'string' ? value.trim().toLowerCase() : '';
3
+ return v === '1' || v === 'true' || v === 'yes' || v === 'on';
4
+ }
5
+ export function resolveApplyPatchToolModeFromEnv() {
6
+ const rawMode = String(process.env.RCC_APPLY_PATCH_TOOL_MODE || process.env.ROUTECODEX_APPLY_PATCH_TOOL_MODE || '')
7
+ .trim()
8
+ .toLowerCase();
9
+ if (rawMode === 'freeform')
10
+ return 'freeform';
11
+ if (rawMode === 'schema' || rawMode === 'json_schema')
12
+ return 'schema';
13
+ const freeformFlag = process.env.RCC_APPLY_PATCH_FREEFORM || process.env.ROUTECODEX_APPLY_PATCH_FREEFORM;
14
+ if (isTruthyEnv(freeformFlag))
15
+ return 'freeform';
16
+ return undefined;
17
+ }
18
+ export function resolveApplyPatchToolModeFromTools(toolsRaw) {
19
+ if (!Array.isArray(toolsRaw) || toolsRaw.length === 0) {
20
+ return undefined;
21
+ }
22
+ for (const entry of toolsRaw) {
23
+ if (!entry || typeof entry !== 'object' || Array.isArray(entry))
24
+ continue;
25
+ const record = entry;
26
+ const type = typeof record.type === 'string' ? record.type.trim().toLowerCase() : '';
27
+ if (type && type !== 'function')
28
+ continue;
29
+ const fn = record.function && typeof record.function === 'object' && !Array.isArray(record.function)
30
+ ? record.function
31
+ : undefined;
32
+ const name = typeof fn?.name === 'string' ? fn.name.trim().toLowerCase() : '';
33
+ if (name !== 'apply_patch')
34
+ continue;
35
+ const format = typeof record.format === 'string'
36
+ ? record.format.trim().toLowerCase()
37
+ : typeof fn?.format === 'string'
38
+ ? String(fn.format).trim().toLowerCase()
39
+ : '';
40
+ if (format === 'freeform')
41
+ return 'freeform';
42
+ // If apply_patch is present without explicit freeform marker, default to schema mode.
43
+ return 'schema';
44
+ }
45
+ return undefined;
46
+ }
@@ -0,0 +1,8 @@
1
+ import type { VirtualRouterEngine } from '../../../../router/virtual-router/engine.js';
2
+ import type { HubPipelineConfig, HubPipelineResult, NormalizedRequest, ProviderProtocol, RequestStageHooks } from './types.js';
3
+ export declare function executeChatProcessEntryPipeline(options: {
4
+ config: HubPipelineConfig;
5
+ routerEngine: VirtualRouterEngine;
6
+ normalized: NormalizedRequest;
7
+ resolveProtocolHooks: (protocol: ProviderProtocol) => RequestStageHooks<Record<string, unknown>> | undefined;
8
+ }): Promise<HubPipelineResult>;