@jsonstudio/llms 0.6.3685 → 0.6.3688

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 (65) hide show
  1. package/dist/conversion/compat/actions/antigravity-thought-signature-cache.js +2 -22
  2. package/dist/conversion/compat/actions/deepseek-web-response.js +7 -0
  3. package/dist/conversion/compat/actions/field-mapping.js +153 -2
  4. package/dist/conversion/compat/actions/lmstudio-responses-input-stringify.js +104 -3
  5. package/dist/conversion/hub/node-support.js +1 -1
  6. package/dist/conversion/hub/operation-table/semantic-mappers/anthropic-mapper.js +1 -9
  7. package/dist/conversion/hub/operation-table/semantic-mappers/responses-mapper.js +28 -35
  8. package/dist/conversion/hub/pipeline/hub-pipeline.js +121 -197
  9. package/dist/conversion/hub/pipeline/hub-stage-timing.d.ts +1 -0
  10. package/dist/conversion/hub/pipeline/hub-stage-timing.js +14 -8
  11. package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage1_format_parse/index.d.ts +4 -4
  12. package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage1_format_parse/index.js +37 -20
  13. package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage2_semantic_map/index.d.ts +7 -6
  14. package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage2_semantic_map/index.js +41 -69
  15. package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage3_context_capture/context-capture-orchestration.d.ts +0 -3
  16. package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage3_context_capture/context-capture-orchestration.js +1 -2
  17. package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage3_context_capture/context-factories.js +0 -2
  18. package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage3_context_capture/index.js +0 -1
  19. package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage3_context_capture/responses-context-snapshot.d.ts +2 -3
  20. package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage3_context_capture/responses-context-snapshot.js +5 -18
  21. package/dist/conversion/hub/pipeline/stages/req_outbound/req_outbound_stage1_semantic_map/context-merge.d.ts +2 -1
  22. package/dist/conversion/hub/pipeline/stages/req_outbound/req_outbound_stage1_semantic_map/context-merge.js +16 -0
  23. package/dist/conversion/hub/pipeline/stages/req_outbound/req_outbound_stage1_semantic_map/index.d.ts +1 -1
  24. package/dist/conversion/hub/pipeline/stages/req_outbound/req_outbound_stage1_semantic_map/index.js +50 -27
  25. package/dist/conversion/hub/pipeline/stages/req_process/req_process_stage1_tool_governance/index.d.ts +0 -1
  26. package/dist/conversion/hub/pipeline/stages/req_process/req_process_stage1_tool_governance/index.js +1 -1
  27. package/dist/conversion/hub/pipeline/stages/req_process/req_process_stage2_route_select/index.d.ts +1 -1
  28. package/dist/conversion/hub/pipeline/stages/req_process/req_process_stage2_route_select/index.js +5 -9
  29. package/dist/conversion/hub/process/chat-process-continue-execution.js +3 -0
  30. package/dist/conversion/hub/process/chat-process-media.d.ts +2 -1
  31. package/dist/conversion/hub/process/chat-process-media.js +63 -9
  32. package/dist/conversion/hub/process/chat-process-session-usage.d.ts +6 -24
  33. package/dist/conversion/hub/process/chat-process-session-usage.js +101 -200
  34. package/dist/conversion/hub/response/provider-response.js +13 -13
  35. package/dist/conversion/hub/types/chat-envelope.d.ts +0 -1
  36. package/dist/conversion/pipeline/codecs/v2/openai-openai-pipeline.js +4 -0
  37. package/dist/conversion/responses/responses-openai-bridge.d.ts +0 -1
  38. package/dist/conversion/responses/responses-openai-bridge.js +34 -28
  39. package/dist/conversion/shared/anthropic-message-utils.js +1 -14
  40. package/dist/conversion/shared/reasoning-normalizer.js +22 -41
  41. package/dist/conversion/shared/responses-tool-utils.js +2 -3
  42. package/dist/conversion/shared/tool-governor.js +4 -2
  43. package/dist/native/router_hotpath_napi.node +0 -0
  44. package/dist/router/virtual-router/engine/routing-state/store.js +2 -21
  45. package/dist/router/virtual-router/engine-selection/native-chat-process-governed-filter-semantics.d.ts +0 -1
  46. package/dist/router/virtual-router/engine-selection/native-chat-process-governed-filter-semantics.js +0 -1
  47. package/dist/router/virtual-router/engine-selection/native-compat-action-semantics.d.ts +0 -3
  48. package/dist/router/virtual-router/engine-selection/native-compat-action-semantics.js +0 -72
  49. package/dist/router/virtual-router/engine-selection/native-hub-bridge-action-semantics.d.ts +1 -1
  50. package/dist/router/virtual-router/engine-selection/native-hub-bridge-action-semantics.js +1 -1
  51. package/dist/router/virtual-router/engine-selection/native-hub-pipeline-edge-stage-semantics.d.ts +2 -2
  52. package/dist/router/virtual-router/engine-selection/native-hub-pipeline-edge-stage-semantics.js +96 -80
  53. package/dist/router/virtual-router/engine-selection/native-hub-pipeline-inbound-outbound-semantics.d.ts +1 -0
  54. package/dist/router/virtual-router/engine-selection/native-hub-pipeline-inbound-outbound-semantics.js +29 -0
  55. package/dist/router/virtual-router/engine-selection/native-router-hotpath-loader.js +2 -6
  56. package/dist/router/virtual-router/engine.js +6 -9
  57. package/dist/router/virtual-router/routing-instructions/state.js +27 -37
  58. package/dist/router/virtual-router/routing-instructions/types.d.ts +4 -6
  59. package/dist/router/virtual-router/token-estimator.js +0 -21
  60. package/dist/servertool/handlers/stop-message-auto.js +1 -11
  61. package/dist/tools/apply-patch/execution-capturer.d.ts +1 -1
  62. package/dist/tools/apply-patch/execution-capturer.js +2 -1
  63. package/dist/tools/apply-patch/regression-capturer.js +1 -2
  64. package/dist/tools/tool-registry.js +2 -1
  65. package/package.json +1 -1
@@ -21,15 +21,11 @@ function isHubStageTimingEnabled() {
21
21
  const explicit = process.env.ROUTECODEX_STAGE_TIMING ??
22
22
  process.env.RCC_STAGE_TIMING ??
23
23
  process.env.ROUTECODEX_HUB_STAGE_TIMING ??
24
- process.env.RCC_HUB_STAGE_TIMING ??
25
- process.env.ROUTECODEX_BUILD_MODE ??
26
- process.env.RCC_BUILD_MODE ??
27
- process.env.BUILD_MODE ??
28
- process.env.LLMSWITCH_BUILD_MODE;
24
+ process.env.RCC_HUB_STAGE_TIMING;
29
25
  if (explicit !== undefined) {
30
- return resolveBool(explicit, true);
26
+ return resolveBool(explicit, false);
31
27
  }
32
- return true;
28
+ return false;
33
29
  }
34
30
  function isHubStageTimingVerboseEnabled() {
35
31
  const explicit = process.env.ROUTECODEX_STAGE_TIMING_VERBOSE ??
@@ -41,6 +37,16 @@ function isHubStageTimingVerboseEnabled() {
41
37
  }
42
38
  return false;
43
39
  }
40
+ export function isHubStageTimingDetailEnabled() {
41
+ const explicit = process.env.ROUTECODEX_STAGE_TIMING_DETAIL ??
42
+ process.env.RCC_STAGE_TIMING_DETAIL ??
43
+ process.env.ROUTECODEX_HUB_STAGE_TIMING_DETAIL ??
44
+ process.env.RCC_HUB_STAGE_TIMING_DETAIL;
45
+ if (explicit !== undefined) {
46
+ return resolveBool(explicit, false);
47
+ }
48
+ return false;
49
+ }
44
50
  function resolveHubStageTimingMinMs() {
45
51
  const raw = process.env.ROUTECODEX_STAGE_TIMING_MIN_MS ??
46
52
  process.env.RCC_STAGE_TIMING_MIN_MS ??
@@ -127,7 +133,7 @@ export function logHubStageTiming(requestId, stage, phase, details) {
127
133
  const timing = advanceTiming(requestId);
128
134
  if (phase !== 'error') {
129
135
  const forceLog = details?.forceLog === true;
130
- if (forceLog) {
136
+ if (forceLog && isHubStageTimingDetailEnabled()) {
131
137
  const detailSuffix = renderDetails(details);
132
138
  const line = `[hub.detail][${requestId}] ${stage}.${phase}${timing.label}${detailSuffix}`;
133
139
  console.log(line);
@@ -1,7 +1,7 @@
1
- import type { AdapterContext } from '../../../../types/chat-envelope.js';
2
- import type { FormatEnvelope } from '../../../../types/format-envelope.js';
3
- import type { JsonObject } from '../../../../types/json.js';
4
- import type { StageRecorder } from '../../../../format-adapters/index.js';
1
+ import type { AdapterContext } from "../../../../types/chat-envelope.js";
2
+ import type { FormatEnvelope } from "../../../../types/format-envelope.js";
3
+ import type { JsonObject } from "../../../../types/json.js";
4
+ import type { StageRecorder } from "../../../../format-adapters/index.js";
5
5
  export interface ReqInboundStage1FormatParseOptions {
6
6
  rawRequest: JsonObject;
7
7
  adapterContext: AdapterContext;
@@ -1,44 +1,61 @@
1
- import { recordStage } from '../../../stages/utils.js';
2
- import { sanitizeReqInboundFormatEnvelopeWithNative } from '../../../../../../router/virtual-router/engine-selection/native-hub-pipeline-req-inbound-semantics.js';
3
- import { parseReqInboundFormatEnvelopeWithNative } from '../../../../../../router/virtual-router/engine-selection/native-hub-pipeline-edge-stage-semantics.js';
4
- import { normalizeReasoningInAnthropicPayload, normalizeReasoningInChatPayload, normalizeReasoningInGeminiPayload, normalizeReasoningInResponsesPayload } from '../../../../../shared/reasoning-normalizer.js';
5
- import { measureHubStage } from '../../../hub-stage-timing.js';
1
+ import { recordStage } from "../../../stages/utils.js";
2
+ import { sanitizeReqInboundFormatEnvelopeWithNative } from "../../../../../../router/virtual-router/engine-selection/native-hub-pipeline-req-inbound-semantics.js";
3
+ import { parseReqInboundFormatEnvelopeWithNative } from "../../../../../../router/virtual-router/engine-selection/native-hub-pipeline-edge-stage-semantics.js";
4
+ import { normalizeReasoningInAnthropicPayload, normalizeReasoningInChatPayload, normalizeReasoningInGeminiPayload, normalizeReasoningInResponsesPayload, } from "../../../../../shared/reasoning-normalizer.js";
5
+ import { logHubStageTiming } from "../../../hub-stage-timing.js";
6
6
  function resolveProtocolToken(adapterContext) {
7
- const candidate = typeof adapterContext.providerProtocol === 'string' && adapterContext.providerProtocol.trim().length
7
+ const candidate = typeof adapterContext.providerProtocol === "string" &&
8
+ adapterContext.providerProtocol.trim().length
8
9
  ? adapterContext.providerProtocol.trim().toLowerCase()
9
- : '';
10
- if (candidate === 'openai-chat' || candidate === 'openai-responses' || candidate === 'anthropic-messages' || candidate === 'gemini-chat') {
10
+ : "";
11
+ if (candidate === "openai-chat" ||
12
+ candidate === "openai-responses" ||
13
+ candidate === "anthropic-messages" ||
14
+ candidate === "gemini-chat") {
11
15
  return candidate;
12
16
  }
13
- return 'openai-chat';
17
+ return "openai-chat";
14
18
  }
15
19
  function applyReasoningNormalization(rawRequest, protocol) {
16
- if (protocol === 'openai-responses') {
20
+ if (protocol === "openai-responses") {
17
21
  normalizeReasoningInResponsesPayload(rawRequest, {
18
22
  includeInput: true,
19
- includeInstructions: true
23
+ includeInstructions: true,
20
24
  });
21
25
  return;
22
26
  }
23
- if (protocol === 'anthropic-messages') {
27
+ if (protocol === "anthropic-messages") {
24
28
  normalizeReasoningInAnthropicPayload(rawRequest);
25
29
  return;
26
30
  }
27
- if (protocol === 'gemini-chat') {
31
+ if (protocol === "gemini-chat") {
28
32
  normalizeReasoningInGeminiPayload(rawRequest);
29
33
  return;
30
34
  }
31
35
  normalizeReasoningInChatPayload(rawRequest);
32
36
  }
33
37
  export async function runReqInboundStage1FormatParse(options) {
38
+ const requestId = options.adapterContext.requestId || "unknown";
34
39
  const protocol = resolveProtocolToken(options.adapterContext);
35
- const requestId = options.adapterContext.requestId;
36
- await measureHubStage(requestId, 'request_stage.req_inbound.format_parse.reasoning_normalize', () => applyReasoningNormalization(options.rawRequest, protocol));
37
- const envelopeRaw = await measureHubStage(requestId, 'request_stage.req_inbound.format_parse.native_parse', () => parseReqInboundFormatEnvelopeWithNative({
40
+ logHubStageTiming(requestId, "req_inbound.stage1_reasoning_normalize", "start", { protocol });
41
+ const normalizeStart = Date.now();
42
+ applyReasoningNormalization(options.rawRequest, protocol);
43
+ logHubStageTiming(requestId, "req_inbound.stage1_reasoning_normalize", "completed", { elapsedMs: Date.now() - normalizeStart, protocol });
44
+ logHubStageTiming(requestId, "req_inbound.stage1_native_parse", "start");
45
+ const parseStart = Date.now();
46
+ const envelopeRaw = parseReqInboundFormatEnvelopeWithNative({
38
47
  rawRequest: options.rawRequest,
39
- protocol
40
- }));
41
- const envelope = await measureHubStage(requestId, 'request_stage.req_inbound.format_parse.native_sanitize', () => sanitizeReqInboundFormatEnvelopeWithNative(envelopeRaw));
42
- recordStage(options.stageRecorder, 'chat_process.req.stage1.format_parse', envelope);
48
+ protocol,
49
+ });
50
+ logHubStageTiming(requestId, "req_inbound.stage1_native_parse", "completed", {
51
+ elapsedMs: Date.now() - parseStart,
52
+ });
53
+ logHubStageTiming(requestId, "req_inbound.stage1_sanitize", "start");
54
+ const sanitizeStart = Date.now();
55
+ const envelope = sanitizeReqInboundFormatEnvelopeWithNative(envelopeRaw);
56
+ logHubStageTiming(requestId, "req_inbound.stage1_sanitize", "completed", {
57
+ elapsedMs: Date.now() - sanitizeStart,
58
+ });
59
+ recordStage(options.stageRecorder, "chat_process.req.stage1.format_parse", envelope);
43
60
  return envelope;
44
61
  }
@@ -1,12 +1,12 @@
1
- import type { AdapterContext, ChatEnvelope } from '../../../../types/chat-envelope.js';
2
- import type { FormatEnvelope } from '../../../../types/format-envelope.js';
3
- import { type JsonObject } from '../../../../types/json.js';
4
- import type { SemanticMapper, StageRecorder } from '../../../../format-adapters/index.js';
5
- import type { StandardizedRequest } from '../../../../types/standardized.js';
1
+ import type { AdapterContext, ChatEnvelope } from "../../../../types/chat-envelope.js";
2
+ import type { FormatEnvelope } from "../../../../types/format-envelope.js";
3
+ import { type JsonObject } from "../../../../types/json.js";
4
+ import type { SemanticMapper, StageRecorder } from "../../../../format-adapters/index.js";
5
+ import type { StandardizedRequest } from "../../../../types/standardized.js";
6
6
  export interface ReqInboundStage2SemanticMapOptions {
7
7
  adapterContext: AdapterContext;
8
8
  formatEnvelope: FormatEnvelope<JsonObject>;
9
- semanticMapper: Pick<SemanticMapper, 'toChat'>;
9
+ semanticMapper: Pick<SemanticMapper, "toChat">;
10
10
  /**
11
11
  * Mappable cross-protocol semantics (e.g. /v1/responses submit resume) must be
12
12
  * lifted into chat semantics before entering chat_process.
@@ -19,5 +19,6 @@ export interface ReqInboundStage2SemanticMapOptions {
19
19
  export interface ReqInboundStage2SemanticMapResult {
20
20
  chatEnvelope: ChatEnvelope;
21
21
  standardizedRequest: StandardizedRequest;
22
+ responsesContext?: JsonObject;
22
23
  }
23
24
  export declare function runReqInboundStage2SemanticMap(options: ReqInboundStage2SemanticMapOptions): Promise<ReqInboundStage2SemanticMapResult>;
@@ -1,59 +1,18 @@
1
- import { isJsonObject, jsonClone } from '../../../../types/json.js';
2
- import { applyHubOperationTableInbound } from '../../../../operation-table/operation-table-runner.js';
3
- import { recordStage } from '../../../stages/utils.js';
4
- import { liftReqInboundSemantics } from './semantic-lift.js';
5
- import { validateChatEnvelopeWithNative } from '../../../../../../router/virtual-router/engine-selection/native-hub-pipeline-edge-stage-semantics.js';
6
- import { chatEnvelopeToStandardizedWithNative } from '../../../../../../router/virtual-router/engine-selection/native-hub-pipeline-req-inbound-semantics.js';
7
- import { runResponsesOpenAIReqInboundSemanticMapWithNative } from '../../../../../../router/virtual-router/engine-selection/native-compat-action-semantics.js';
8
- import { logHubStageTiming, measureHubStage } from '../../../hub-stage-timing.js';
9
- function logNativeResponsesSemanticMapBreakdown(requestId, timings) {
10
- if (!requestId || !timings) {
11
- return;
12
- }
13
- const stages = [
14
- ['captureContextMs', 'request_stage.req_inbound.semantic_map.native.capture_context'],
15
- ['buildRequestMs', 'request_stage.req_inbound.semantic_map.native.build_request'],
16
- ['mapChatMs', 'request_stage.req_inbound.semantic_map.native.map_chat'],
17
- ['toStandardizedMs', 'request_stage.req_inbound.semantic_map.native.to_standardized']
18
- ];
19
- for (const [key, stage] of stages) {
20
- const value = timings[key];
21
- if (typeof value === 'number' && Number.isFinite(value)) {
22
- logHubStageTiming(requestId, stage, 'completed', { nativeMs: value, elapsedMs: value });
23
- }
24
- }
25
- }
26
- function isResponsesCreateFastPathCandidate(options) {
27
- if (options.responsesResume) {
28
- return false;
29
- }
30
- const protocol = options.formatEnvelope.protocol?.trim().toLowerCase();
31
- if (protocol !== 'openai-responses') {
32
- return false;
33
- }
34
- const endpoint = options.adapterContext.entryEndpoint?.trim().toLowerCase();
35
- return endpoint !== '/v1/responses.submit_tool_outputs';
36
- }
1
+ import { isJsonObject, jsonClone, } from "../../../../types/json.js";
2
+ import { applyHubOperationTableInbound } from "../../../../operation-table/operation-table-runner.js";
3
+ import { recordStage } from "../../../stages/utils.js";
4
+ import { liftReqInboundSemantics } from "./semantic-lift.js";
5
+ import { validateChatEnvelopeWithNative } from "../../../../../../router/virtual-router/engine-selection/native-hub-pipeline-edge-stage-semantics.js";
6
+ import { chatEnvelopeToStandardizedWithNative } from "../../../../../../router/virtual-router/engine-selection/native-hub-pipeline-req-inbound-semantics.js";
7
+ import { logHubStageTiming } from "../../../hub-stage-timing.js";
37
8
  export async function runReqInboundStage2SemanticMap(options) {
38
- if (isResponsesCreateFastPathCandidate(options)) {
39
- const nativeResult = await measureHubStage(options.adapterContext.requestId, 'request_stage.req_inbound.semantic_map.native.fast_path', () => runResponsesOpenAIReqInboundSemanticMapWithNative(options.formatEnvelope.payload, {
40
- requestId: options.adapterContext.requestId,
41
- entryEndpoint: options.adapterContext.entryEndpoint,
42
- adapterContext: options.adapterContext
43
- }));
44
- logNativeResponsesSemanticMapBreakdown(options.adapterContext.requestId, nativeResult.timings);
45
- const chatEnvelope = nativeResult.chatEnvelope;
46
- const standardizedRequest = nativeResult.standardizedRequest;
47
- validateChatEnvelopeWithNative(chatEnvelope, {
48
- stage: 'req_inbound',
49
- direction: 'request'
50
- });
51
- recordStage(options.stageRecorder, 'chat_process.req.stage2.semantic_map', chatEnvelope);
52
- return { chatEnvelope, standardizedRequest };
53
- }
9
+ const requestId = options.adapterContext.requestId || "unknown";
10
+ logHubStageTiming(requestId, "req_inbound.stage2_semantic_mapper_toChat", "start");
11
+ const toChatStart = Date.now();
54
12
  const chatEnvelope = await options.semanticMapper.toChat(options.formatEnvelope, options.adapterContext);
13
+ logHubStageTiming(requestId, "req_inbound.stage2_semantic_mapper_toChat", "completed", { elapsedMs: Date.now() - toChatStart });
55
14
  const preservedResponsesContext = (() => {
56
- if (!chatEnvelope.semantics || typeof chatEnvelope.semantics !== 'object') {
15
+ if (!chatEnvelope.semantics || typeof chatEnvelope.semantics !== "object") {
57
16
  return undefined;
58
17
  }
59
18
  const semantics = chatEnvelope.semantics;
@@ -68,7 +27,7 @@ export async function runReqInboundStage2SemanticMap(options) {
68
27
  applyHubOperationTableInbound({
69
28
  formatEnvelope: options.formatEnvelope,
70
29
  chatEnvelope,
71
- adapterContext: options.adapterContext
30
+ adapterContext: options.adapterContext,
72
31
  });
73
32
  // Semantic Gate (request): before entering chat_process, lift any mappable protocol semantics
74
33
  // into ChatEnvelope.semantics. Do not persist these in metadata.
@@ -76,12 +35,14 @@ export async function runReqInboundStage2SemanticMap(options) {
76
35
  chatEnvelope,
77
36
  formatEnvelope: options.formatEnvelope,
78
37
  adapterContext: options.adapterContext,
79
- responsesResume: options.responsesResume
38
+ responsesResume: options.responsesResume,
80
39
  });
81
40
  if (preservedResponsesContext) {
82
41
  const currentSemantics = chatEnvelope.semantics;
83
- if (!currentSemantics || typeof currentSemantics !== 'object') {
84
- chatEnvelope.semantics = { responses: { context: jsonClone(preservedResponsesContext) } };
42
+ if (!currentSemantics || typeof currentSemantics !== "object") {
43
+ chatEnvelope.semantics = {
44
+ responses: { context: jsonClone(preservedResponsesContext) },
45
+ };
85
46
  }
86
47
  else {
87
48
  const semantics = currentSemantics;
@@ -93,28 +54,31 @@ export async function runReqInboundStage2SemanticMap(options) {
93
54
  ...semantics,
94
55
  responses: {
95
56
  ...responsesNode,
96
- context: jsonClone(preservedResponsesContext)
97
- }
57
+ context: jsonClone(preservedResponsesContext),
58
+ },
98
59
  };
99
60
  }
100
61
  }
101
62
  }
102
63
  validateChatEnvelopeWithNative(chatEnvelope, {
103
- stage: 'req_inbound',
104
- direction: 'request'
64
+ stage: "req_inbound",
65
+ direction: "request",
105
66
  });
106
- recordStage(options.stageRecorder, 'chat_process.req.stage2.semantic_map', chatEnvelope);
67
+ recordStage(options.stageRecorder, "chat_process.req.stage2.semantic_map", chatEnvelope);
68
+ logHubStageTiming(requestId, "req_inbound.stage2_to_standardized", "start");
69
+ const stdStart = Date.now();
107
70
  const standardizedRequest = chatEnvelopeToStandardizedWithNative({
108
71
  chatEnvelope: chatEnvelope,
109
72
  adapterContext: options.adapterContext,
110
73
  endpoint: options.adapterContext.entryEndpoint,
111
- requestId: options.adapterContext.requestId
74
+ requestId: options.adapterContext.requestId,
112
75
  });
76
+ logHubStageTiming(requestId, "req_inbound.stage2_to_standardized", "completed", { elapsedMs: Date.now() - stdStart });
113
77
  // Ensure responses semantics (context) survive into standardized request for VirtualRouter parsing.
114
- if (chatEnvelope.semantics && typeof chatEnvelope.semantics === 'object') {
78
+ if (chatEnvelope.semantics && typeof chatEnvelope.semantics === "object") {
115
79
  const envelopeSemantics = chatEnvelope.semantics;
116
80
  const existing = standardizedRequest.semantics;
117
- if (!existing || typeof existing !== 'object') {
81
+ if (!existing || typeof existing !== "object") {
118
82
  standardizedRequest.semantics = jsonClone(envelopeSemantics);
119
83
  }
120
84
  else {
@@ -127,15 +91,23 @@ export async function runReqInboundStage2SemanticMap(options) {
127
91
  : undefined;
128
92
  if (envelopeContext) {
129
93
  const nextResponses = {
130
- ...(isJsonObject(existingObj.responses) ? existingObj.responses : {}),
131
- context: jsonClone(envelopeContext)
94
+ ...(isJsonObject(existingObj.responses)
95
+ ? existingObj.responses
96
+ : {}),
97
+ context: jsonClone(envelopeContext),
132
98
  };
133
99
  standardizedRequest.semantics = {
134
100
  ...existingObj,
135
- responses: nextResponses
101
+ responses: nextResponses,
136
102
  };
137
103
  }
138
104
  }
139
105
  }
140
- return { chatEnvelope, standardizedRequest };
106
+ return {
107
+ chatEnvelope,
108
+ standardizedRequest,
109
+ ...(preservedResponsesContext
110
+ ? { responsesContext: preservedResponsesContext }
111
+ : {}),
112
+ };
141
113
  }
@@ -1,18 +1,15 @@
1
1
  import type { AdapterContext } from '../../../../types/chat-envelope.js';
2
- import type { ChatEnvelope } from '../../../../types/chat-envelope.js';
3
2
  import type { StageRecorder } from '../../../../format-adapters/index.js';
4
3
  import type { JsonObject } from '../../../../types/json.js';
5
4
  export interface ContextCaptureOptions {
6
5
  rawRequest: JsonObject;
7
6
  adapterContext: AdapterContext;
8
- chatEnvelope?: ChatEnvelope;
9
7
  stageRecorder?: StageRecorder;
10
8
  }
11
9
  export type ContextCaptureHandler = (options: ContextCaptureOptions) => Promise<Record<string, unknown> | undefined> | Record<string, unknown> | undefined;
12
10
  export interface ReqInboundStage3ContextCaptureOptions {
13
11
  rawRequest: JsonObject;
14
12
  adapterContext: AdapterContext;
15
- chatEnvelope?: ChatEnvelope;
16
13
  captureContext?: ContextCaptureHandler;
17
14
  stageRecorder?: StageRecorder;
18
15
  }
@@ -13,8 +13,7 @@ export async function runReqInboundStage3ContextCaptureOrchestration(options) {
13
13
  try {
14
14
  context = await options.captureContext({
15
15
  rawRequest: options.rawRequest,
16
- adapterContext: options.adapterContext,
17
- chatEnvelope: options.chatEnvelope
16
+ adapterContext: options.adapterContext
18
17
  });
19
18
  }
20
19
  catch {
@@ -4,7 +4,6 @@ export function createResponsesContextCapture(captureImpl) {
4
4
  return (options) => runReqInboundStage3ContextCapture({
5
5
  rawRequest: options.rawRequest,
6
6
  adapterContext: options.adapterContext,
7
- chatEnvelope: options.chatEnvelope,
8
7
  stageRecorder: options.stageRecorder,
9
8
  captureContext: captureImpl
10
9
  });
@@ -14,7 +13,6 @@ export function createNoopContextCapture(label) {
14
13
  return (options) => runReqInboundStage3ContextCapture({
15
14
  rawRequest: options.rawRequest,
16
15
  adapterContext: options.adapterContext,
17
- chatEnvelope: options.chatEnvelope,
18
16
  stageRecorder: options.stageRecorder,
19
17
  captureContext: () => ({ stage: normalizedLabel })
20
18
  });
@@ -9,7 +9,6 @@ export function runChatContextCapture(options) {
9
9
  return runReqInboundStage3ContextCapture({
10
10
  rawRequest: options.rawRequest,
11
11
  adapterContext: options.adapterContext,
12
- chatEnvelope: options.chatEnvelope,
13
12
  stageRecorder: options.stageRecorder,
14
13
  captureContext: captureChatContextSnapshot
15
14
  });
@@ -1,9 +1,8 @@
1
- import type { AdapterContext, ChatEnvelope } from '../../../../types/chat-envelope.js';
2
- import { type JsonObject } from '../../../../types/json.js';
1
+ import type { AdapterContext } from '../../../../types/chat-envelope.js';
2
+ import type { JsonObject } from '../../../../types/json.js';
3
3
  import type { ResponsesRequestContext } from '../../../../../responses/responses-openai-bridge.js';
4
4
  export interface ResponsesContextCaptureOptions {
5
5
  rawRequest: JsonObject;
6
6
  adapterContext: AdapterContext;
7
- chatEnvelope?: ChatEnvelope;
8
7
  }
9
8
  export declare function captureResponsesContextSnapshot(options: ResponsesContextCaptureOptions): ResponsesRequestContext;
@@ -1,24 +1,11 @@
1
- import { isJsonObject } from '../../../../types/json.js';
2
1
  import { captureResponsesRequestContext } from '../../../../../shared/responses-conversation-store.js';
3
2
  import { captureReqInboundResponsesContextSnapshotWithNative } from '../../../../../../router/virtual-router/engine-selection/native-hub-pipeline-req-inbound-semantics.js';
4
- function readResponsesContextFromChatEnvelope(chatEnvelope) {
5
- if (!chatEnvelope?.semantics || typeof chatEnvelope.semantics !== 'object') {
6
- return undefined;
7
- }
8
- const responsesNode = isJsonObject(chatEnvelope.semantics.responses)
9
- ? chatEnvelope.semantics.responses
10
- : undefined;
11
- return responsesNode && isJsonObject(responsesNode.context)
12
- ? responsesNode.context
13
- : undefined;
14
- }
15
3
  export function captureResponsesContextSnapshot(options) {
16
- const context = readResponsesContextFromChatEnvelope(options.chatEnvelope) ??
17
- captureReqInboundResponsesContextSnapshotWithNative({
18
- rawRequest: options.rawRequest,
19
- requestId: options.adapterContext.requestId,
20
- toolCallIdStyle: options.adapterContext.toolCallIdStyle
21
- });
4
+ const context = captureReqInboundResponsesContextSnapshotWithNative({
5
+ rawRequest: options.rawRequest,
6
+ requestId: options.adapterContext.requestId,
7
+ toolCallIdStyle: options.adapterContext.toolCallIdStyle
8
+ });
22
9
  // OpenAI Responses tool loop: store the request context keyed by requestId so that
23
10
  // `/v1/responses/:id/submit_tool_outputs` can resume the conversation later.
24
11
  //
@@ -1,2 +1,3 @@
1
- import type { ChatEnvelope } from '../../../../types/chat-envelope.js';
1
+ import type { AdapterContext, ChatEnvelope } from '../../../../types/chat-envelope.js';
2
+ export declare function applyToolCallIdStyleMetadata(chatEnvelope: ChatEnvelope, adapterContext: AdapterContext, snapshot?: Record<string, unknown>): void;
2
3
  export declare function applyContextSnapshotToChatEnvelope(chatEnvelope: ChatEnvelope, snapshot: Record<string, unknown>): void;
@@ -1,4 +1,20 @@
1
+ import { selectToolCallIdStyleWithNative } from '../../../../../../router/virtual-router/engine-selection/native-hub-pipeline-inbound-outbound-semantics.js';
1
2
  import { applyReqOutboundContextSnapshotWithNative } from '../../../../../../router/virtual-router/engine-selection/native-hub-pipeline-req-outbound-semantics.js';
3
+ export function applyToolCallIdStyleMetadata(chatEnvelope, adapterContext, snapshot) {
4
+ const metadata = chatEnvelope.metadata || (chatEnvelope.metadata = { context: adapterContext });
5
+ const current = typeof metadata.toolCallIdStyle === 'string'
6
+ ? String(metadata.toolCallIdStyle).trim()
7
+ : '';
8
+ const resolved = selectToolCallIdStyleWithNative(adapterContext, snapshot ?? {}, current || undefined);
9
+ if (!resolved) {
10
+ return;
11
+ }
12
+ // Always honor the route-selected AdapterContext toolCallIdStyle when present.
13
+ // This prevents cross-provider leakage (e.g. LM Studio "preserve" contaminating OpenAI "fc").
14
+ if (!current || current !== resolved) {
15
+ metadata.toolCallIdStyle = resolved;
16
+ }
17
+ }
2
18
  export function applyContextSnapshotToChatEnvelope(chatEnvelope, snapshot) {
3
19
  const hasExistingTools = Array.isArray(chatEnvelope.tools) && chatEnvelope.tools.length > 0;
4
20
  const patch = applyReqOutboundContextSnapshotWithNative({
@@ -1,6 +1,6 @@
1
1
  import type { AdapterContext, ChatEnvelope } from '../../../../types/chat-envelope.js';
2
2
  import type { FormatEnvelope } from '../../../../types/format-envelope.js';
3
- import { type JsonObject } from '../../../../types/json.js';
3
+ import type { JsonObject } from '../../../../types/json.js';
4
4
  import type { StageRecorder, SemanticMapper } from '../../../../format-adapters/index.js';
5
5
  import type { ProcessedRequest, StandardizedRequest } from '../../../../types/standardized.js';
6
6
  export interface ReqOutboundStage1SemanticMapOptions {
@@ -1,53 +1,76 @@
1
- import { isJsonObject } from '../../../../types/json.js';
2
1
  import { applyHubOperationTableOutboundPostMap, applyHubOperationTableOutboundPreMap } from '../../../../operation-table/operation-table-runner.js';
3
2
  import { recordStage } from '../../../stages/utils.js';
4
- import { applyContextSnapshotToChatEnvelope } from './context-merge.js';
3
+ import { applyContextSnapshotToChatEnvelope, applyToolCallIdStyleMetadata } from './context-merge.js';
5
4
  import { shouldAttachReqOutboundContextSnapshotWithNative, standardizedToChatEnvelopeWithNative } from '../../../../../../router/virtual-router/engine-selection/native-hub-pipeline-req-outbound-semantics.js';
6
5
  import { validateChatEnvelopeWithNative } from '../../../../../../router/virtual-router/engine-selection/native-hub-pipeline-edge-stage-semantics.js';
7
- import { measureHubStage } from '../../../hub-stage-timing.js';
8
- function hasResponsesContextSemantics(chatEnvelope) {
9
- if (!chatEnvelope?.semantics || typeof chatEnvelope.semantics !== 'object') {
10
- return false;
11
- }
12
- const responsesNode = isJsonObject(chatEnvelope.semantics.responses)
13
- ? chatEnvelope.semantics.responses
14
- : undefined;
15
- return Boolean(responsesNode && isJsonObject(responsesNode.context));
16
- }
6
+ import { isHubStageTimingDetailEnabled, logHubStageTiming } from '../../../hub-stage-timing.js';
17
7
  export async function runReqOutboundStage1SemanticMap(options) {
18
- const requestId = options.adapterContext.requestId;
19
- const chatEnvelope = await measureHubStage(requestId, 'request_stage.req_outbound.semantic_map.native.to_chat_envelope', () => standardizedToChatEnvelopeWithNative({
8
+ const requestId = options.adapterContext.requestId || 'unknown';
9
+ const forceDetailLog = isHubStageTimingDetailEnabled();
10
+ logHubStageTiming(requestId, 'req_outbound.stage1_native_to_chat_envelope', 'start');
11
+ const toChatStart = Date.now();
12
+ const chatEnvelope = standardizedToChatEnvelopeWithNative({
20
13
  request: options.request,
21
14
  adapterContext: options.adapterContext
22
- }));
15
+ });
16
+ logHubStageTiming(requestId, 'req_outbound.stage1_native_to_chat_envelope', 'completed', {
17
+ elapsedMs: Date.now() - toChatStart,
18
+ forceLog: forceDetailLog
19
+ });
20
+ applyToolCallIdStyleMetadata(chatEnvelope, options.adapterContext, options.contextSnapshot);
23
21
  const shouldAttachContextSnapshot = shouldAttachReqOutboundContextSnapshotWithNative(Boolean(options.contextSnapshot), options.contextMetadataKey);
24
- const shouldSkipResponsesSnapshotMerge = options.contextMetadataKey === 'responsesContext' &&
25
- hasResponsesContextSemantics(chatEnvelope);
26
- if (shouldAttachContextSnapshot &&
27
- !shouldSkipResponsesSnapshotMerge &&
28
- options.contextSnapshot &&
29
- options.contextMetadataKey) {
22
+ if (shouldAttachContextSnapshot && options.contextSnapshot && options.contextMetadataKey) {
23
+ logHubStageTiming(requestId, 'req_outbound.stage1_context_merge', 'start');
24
+ const contextMergeStart = Date.now();
30
25
  const snapshot = options.contextSnapshot;
31
26
  if (options.contextMetadataKey !== 'responsesContext') {
32
27
  chatEnvelope.metadata[options.contextMetadataKey] = snapshot;
33
28
  }
34
- await measureHubStage(requestId, 'request_stage.req_outbound.semantic_map.context_merge', () => applyContextSnapshotToChatEnvelope(chatEnvelope, snapshot));
29
+ applyContextSnapshotToChatEnvelope(chatEnvelope, snapshot);
30
+ logHubStageTiming(requestId, 'req_outbound.stage1_context_merge', 'completed', {
31
+ elapsedMs: Date.now() - contextMergeStart,
32
+ forceLog: forceDetailLog
33
+ });
35
34
  }
35
+ logHubStageTiming(requestId, 'req_outbound.stage1_validate_chat_envelope', 'start');
36
+ const validateStart = Date.now();
36
37
  validateChatEnvelopeWithNative(chatEnvelope, {
37
38
  stage: 'req_outbound',
38
39
  direction: 'request'
39
40
  });
40
- await measureHubStage(requestId, 'request_stage.req_outbound.semantic_map.operation_table_pre_map', () => applyHubOperationTableOutboundPreMap({
41
+ logHubStageTiming(requestId, 'req_outbound.stage1_validate_chat_envelope', 'completed', {
42
+ elapsedMs: Date.now() - validateStart,
43
+ forceLog: forceDetailLog
44
+ });
45
+ logHubStageTiming(requestId, 'req_outbound.stage1_operation_table_pre_map', 'start');
46
+ const preMapStart = Date.now();
47
+ await applyHubOperationTableOutboundPreMap({
41
48
  protocol: options.adapterContext.providerProtocol,
42
49
  chatEnvelope,
43
50
  adapterContext: options.adapterContext
44
- }));
45
- const formatEnvelope = await measureHubStage(requestId, 'request_stage.req_outbound.semantic_map.mapper.from_chat', async () => (await options.semanticMapper.fromChat(chatEnvelope, options.adapterContext)));
46
- await measureHubStage(requestId, 'request_stage.req_outbound.semantic_map.operation_table_post_map', () => applyHubOperationTableOutboundPostMap({
51
+ });
52
+ logHubStageTiming(requestId, 'req_outbound.stage1_operation_table_pre_map', 'completed', {
53
+ elapsedMs: Date.now() - preMapStart,
54
+ forceLog: forceDetailLog
55
+ });
56
+ logHubStageTiming(requestId, 'req_outbound.stage1_mapper_from_chat', 'start');
57
+ const fromChatStart = Date.now();
58
+ const formatEnvelope = (await options.semanticMapper.fromChat(chatEnvelope, options.adapterContext));
59
+ logHubStageTiming(requestId, 'req_outbound.stage1_mapper_from_chat', 'completed', {
60
+ elapsedMs: Date.now() - fromChatStart,
61
+ forceLog: forceDetailLog
62
+ });
63
+ logHubStageTiming(requestId, 'req_outbound.stage1_operation_table_post_map', 'start');
64
+ const postMapStart = Date.now();
65
+ applyHubOperationTableOutboundPostMap({
47
66
  chatEnvelope,
48
67
  formatEnvelope,
49
68
  adapterContext: options.adapterContext
50
- }));
69
+ });
70
+ logHubStageTiming(requestId, 'req_outbound.stage1_operation_table_post_map', 'completed', {
71
+ elapsedMs: Date.now() - postMapStart,
72
+ forceLog: forceDetailLog
73
+ });
51
74
  recordStage(options.stageRecorder, 'chat_process.req.stage6.outbound.semantic_map', chatEnvelope);
52
75
  return { chatEnvelope, formatEnvelope };
53
76
  }
@@ -7,7 +7,6 @@ export interface ReqProcessStage1ToolGovernanceOptions {
7
7
  metadata: Record<string, unknown>;
8
8
  entryEndpoint: string;
9
9
  requestId: string;
10
- applyPatchToolMode?: 'schema' | 'freeform';
11
10
  stageRecorder?: StageRecorder;
12
11
  }
13
12
  export interface ReqProcessStage1ToolGovernanceResult {
@@ -54,7 +54,7 @@ export async function runReqProcessStage1ToolGovernance(options) {
54
54
  recordStage(options.stageRecorder, 'chat_process.req.stage4.tool_governance', processedRequest);
55
55
  // Best-effort: capture apply_patch execution failures reported by tool role messages.
56
56
  // This is for errorsamples collection only and must not affect runtime behavior.
57
- captureApplyPatchExecutionFailuresFromProcessedRequest(processedRequest, options.applyPatchToolMode);
57
+ captureApplyPatchExecutionFailuresFromProcessedRequest(processedRequest);
58
58
  return {
59
59
  processedRequest,
60
60
  nodeResult
@@ -14,4 +14,4 @@ export interface ReqProcessStage2RouteSelectResult {
14
14
  decision: RoutingDecision;
15
15
  diagnostics: RoutingDiagnostics;
16
16
  }
17
- export declare function runReqProcessStage2RouteSelect(options: ReqProcessStage2RouteSelectOptions): Promise<ReqProcessStage2RouteSelectResult>;
17
+ export declare function runReqProcessStage2RouteSelect(options: ReqProcessStage2RouteSelectOptions): ReqProcessStage2RouteSelectResult;