@jsonstudio/rcc 0.90.814 → 0.90.876

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 (221) hide show
  1. package/README.md +8 -0
  2. package/configsamples/provider-default/ali-coding-plan/config.v2.json +76 -0
  3. package/configsamples/provider-default/antigravity/config.v2.json +142 -0
  4. package/configsamples/provider-default/ark-coding-plan/config.v2.json +64 -0
  5. package/configsamples/provider-default/crs/config.v2.json +54 -0
  6. package/configsamples/provider-default/deepseek-web/config.v2.json +56 -0
  7. package/configsamples/provider-default/gemini/config.v2.json +43 -0
  8. package/configsamples/provider-default/gemini-cli/config.v2.json +45 -0
  9. package/configsamples/provider-default/gemini-native/config.v2.json +208 -0
  10. package/configsamples/provider-default/glm/config.v2.json +33 -0
  11. package/configsamples/provider-default/glm-anthropic/config.v2.json +29 -0
  12. package/configsamples/provider-default/kimi/config.v2.json +25 -0
  13. package/configsamples/provider-default/lmstudio/config.v2.json +79 -0
  14. package/configsamples/provider-default/lmstudio-proxy/config.v2.json +78 -0
  15. package/configsamples/provider-default/manifest.json +31 -0
  16. package/configsamples/provider-default/meituan/config.v2.json +20 -0
  17. package/configsamples/provider-default/mimo/config.v2.json +26 -0
  18. package/configsamples/provider-default/modelscope/config.v2.json +81 -0
  19. package/configsamples/provider-default/my-openai/config.v2.json +20 -0
  20. package/configsamples/provider-default/nvidia/config.v2.json +32 -0
  21. package/configsamples/provider-default/opencode-zen-free/config.v2.json +56 -0
  22. package/configsamples/provider-default/openrouter/config.v2.json +210 -0
  23. package/configsamples/provider-default/qwen/config.v2.json +38 -0
  24. package/configsamples/provider-default/qwenchat/config.v2.json +53 -0
  25. package/configsamples/provider-default/tab/config.v2.json +26 -0
  26. package/configsamples/provider-default/tabglm/config.v2.json +77 -0
  27. package/dist/build-info.js +2 -2
  28. package/dist/cli/commands/config.d.ts +5 -0
  29. package/dist/cli/commands/config.js +369 -1
  30. package/dist/cli/commands/config.js.map +1 -1
  31. package/dist/cli/commands/examples.js +3 -0
  32. package/dist/cli/commands/examples.js.map +1 -1
  33. package/dist/cli/commands/init.js +25 -1
  34. package/dist/cli/commands/init.js.map +1 -1
  35. package/dist/cli/commands/launcher-kernel.js +122 -46
  36. package/dist/cli/commands/launcher-kernel.js.map +1 -1
  37. package/dist/cli/commands/start.js +60 -3
  38. package/dist/cli/commands/start.js.map +1 -1
  39. package/dist/cli/config/bundled-provider-pack.d.ts +20 -0
  40. package/dist/cli/config/bundled-provider-pack.js +146 -0
  41. package/dist/cli/config/bundled-provider-pack.js.map +1 -0
  42. package/dist/cli/register/status-config-commands.d.ts +2 -0
  43. package/dist/cli/register/status-config-commands.js.map +1 -1
  44. package/dist/cli.js +81 -28
  45. package/dist/cli.js.map +1 -1
  46. package/dist/debug/snapshot-store.js +2 -1
  47. package/dist/debug/snapshot-store.js.map +1 -1
  48. package/dist/index.js +23 -14
  49. package/dist/index.js.map +1 -1
  50. package/dist/manager/modules/quota/provider-quota-daemon.model-backoff.js +1 -1
  51. package/dist/manager/modules/quota/provider-quota-daemon.model-backoff.js.map +1 -1
  52. package/dist/manager/quota/provider-quota-center.js +1 -1
  53. package/dist/manager/quota/provider-quota-center.js.map +1 -1
  54. package/dist/manager/storage/file-store.js +10 -0
  55. package/dist/manager/storage/file-store.js.map +1 -1
  56. package/dist/modules/llmswitch/bridge/snapshot-recorder-runtime.js +18 -1
  57. package/dist/modules/llmswitch/bridge/snapshot-recorder-runtime.js.map +1 -1
  58. package/dist/modules/llmswitch/bridge/snapshot-recorder.js +132 -51
  59. package/dist/modules/llmswitch/bridge/snapshot-recorder.js.map +1 -1
  60. package/dist/provider-sdk/provider-runtime-inference.js +2 -2
  61. package/dist/provider-sdk/provider-runtime-inference.js.map +1 -1
  62. package/dist/providers/auth/deepseek-account-token-acquirer.js +32 -3
  63. package/dist/providers/auth/deepseek-account-token-acquirer.js.map +1 -1
  64. package/dist/providers/core/api/provider-types.d.ts +11 -0
  65. package/dist/providers/core/config/service-profiles.js +1 -1
  66. package/dist/providers/core/runtime/deepseek-http-provider.d.ts +2 -0
  67. package/dist/providers/core/runtime/deepseek-http-provider.js +31 -1
  68. package/dist/providers/core/runtime/deepseek-http-provider.js.map +1 -1
  69. package/dist/providers/core/runtime/qwenchat-http-provider-helpers.d.ts +3 -2
  70. package/dist/providers/core/runtime/qwenchat-http-provider-helpers.js +513 -96
  71. package/dist/providers/core/runtime/qwenchat-http-provider-helpers.js.map +1 -1
  72. package/dist/providers/core/runtime/standard-tool-text-harvest.d.ts +8 -0
  73. package/dist/providers/core/runtime/standard-tool-text-harvest.js +24 -0
  74. package/dist/providers/core/runtime/standard-tool-text-harvest.js.map +1 -0
  75. package/dist/providers/core/runtime/standard-tool-text-request-transform.d.ts +4 -1
  76. package/dist/providers/core/runtime/standard-tool-text-request-transform.js +129 -3
  77. package/dist/providers/core/runtime/standard-tool-text-request-transform.js.map +1 -1
  78. package/dist/providers/core/utils/snapshot-writer.js +5 -2
  79. package/dist/providers/core/utils/snapshot-writer.js.map +1 -1
  80. package/dist/providers/profile/provider-profile-loader.js +52 -1
  81. package/dist/providers/profile/provider-profile-loader.js.map +1 -1
  82. package/dist/providers/profile/provider-profile.d.ts +3 -0
  83. package/dist/server/handlers/handler-response-utils.js +1 -0
  84. package/dist/server/handlers/handler-response-utils.js.map +1 -1
  85. package/dist/server/handlers/images-handler.d.ts +9 -0
  86. package/dist/server/handlers/images-handler.js +258 -0
  87. package/dist/server/handlers/images-handler.js.map +1 -0
  88. package/dist/server/handlers/types.d.ts +7 -0
  89. package/dist/server/runtime/http-server/antigravity-startup-tasks.d.ts +3 -0
  90. package/dist/server/runtime/http-server/antigravity-startup-tasks.js +16 -0
  91. package/dist/server/runtime/http-server/antigravity-startup-tasks.js.map +1 -1
  92. package/dist/server/runtime/http-server/daemon-admin/auth-handler.js +3 -18
  93. package/dist/server/runtime/http-server/daemon-admin/auth-handler.js.map +1 -1
  94. package/dist/server/runtime/http-server/daemon-admin/providers-handler-utils.d.ts +7 -0
  95. package/dist/server/runtime/http-server/daemon-admin/providers-handler-utils.js +17 -0
  96. package/dist/server/runtime/http-server/daemon-admin/providers-handler-utils.js.map +1 -1
  97. package/dist/server/runtime/http-server/daemon-admin/providers-handler.js +50 -17
  98. package/dist/server/runtime/http-server/daemon-admin/providers-handler.js.map +1 -1
  99. package/dist/server/runtime/http-server/daemon-admin-routes.js +32 -2
  100. package/dist/server/runtime/http-server/daemon-admin-routes.js.map +1 -1
  101. package/dist/server/runtime/http-server/executor/provider-response-converter.js +42 -13
  102. package/dist/server/runtime/http-server/executor/provider-response-converter.js.map +1 -1
  103. package/dist/server/runtime/http-server/executor/provider-response-utils.js +41 -3
  104. package/dist/server/runtime/http-server/executor/provider-response-utils.js.map +1 -1
  105. package/dist/server/runtime/http-server/executor/usage-aggregator.js +7 -7
  106. package/dist/server/runtime/http-server/executor/usage-aggregator.js.map +1 -1
  107. package/dist/server/runtime/http-server/executor/usage-logger.d.ts +9 -0
  108. package/dist/server/runtime/http-server/executor/usage-logger.js +35 -2
  109. package/dist/server/runtime/http-server/executor/usage-logger.js.map +1 -1
  110. package/dist/server/runtime/http-server/executor-metadata.js +12 -4
  111. package/dist/server/runtime/http-server/executor-metadata.js.map +1 -1
  112. package/dist/server/runtime/http-server/executor-pipeline.js +24 -15
  113. package/dist/server/runtime/http-server/executor-pipeline.js.map +1 -1
  114. package/dist/server/runtime/http-server/executor-provider.d.ts +6 -1
  115. package/dist/server/runtime/http-server/executor-provider.js +137 -5
  116. package/dist/server/runtime/http-server/executor-provider.js.map +1 -1
  117. package/dist/server/runtime/http-server/http-server-bootstrap.js +6 -0
  118. package/dist/server/runtime/http-server/http-server-bootstrap.js.map +1 -1
  119. package/dist/server/runtime/http-server/http-server-lifecycle.js +23 -15
  120. package/dist/server/runtime/http-server/http-server-lifecycle.js.map +1 -1
  121. package/dist/server/runtime/http-server/http-server-runtime-providers.js +14 -4
  122. package/dist/server/runtime/http-server/http-server-runtime-providers.js.map +1 -1
  123. package/dist/server/runtime/http-server/http-server-runtime-setup.js +83 -1
  124. package/dist/server/runtime/http-server/http-server-runtime-setup.js.map +1 -1
  125. package/dist/server/runtime/http-server/hub-shadow-compare.js +2 -41
  126. package/dist/server/runtime/http-server/hub-shadow-compare.js.map +1 -1
  127. package/dist/server/runtime/http-server/provider-routing-scope.d.ts +9 -0
  128. package/dist/server/runtime/http-server/provider-routing-scope.js +20 -0
  129. package/dist/server/runtime/http-server/provider-routing-scope.js.map +1 -0
  130. package/dist/server/runtime/http-server/provider-traffic-governor.d.ts +67 -0
  131. package/dist/server/runtime/http-server/provider-traffic-governor.js +467 -0
  132. package/dist/server/runtime/http-server/provider-traffic-governor.js.map +1 -0
  133. package/dist/server/runtime/http-server/request-executor.d.ts +8 -0
  134. package/dist/server/runtime/http-server/request-executor.js +446 -21
  135. package/dist/server/runtime/http-server/request-executor.js.map +1 -1
  136. package/dist/server/runtime/http-server/routes.js +13 -0
  137. package/dist/server/runtime/http-server/routes.js.map +1 -1
  138. package/dist/server/runtime/http-server/session-client-registry.js +30 -4
  139. package/dist/server/runtime/http-server/session-client-registry.js.map +1 -1
  140. package/dist/server/runtime/http-server/session-client-route-utils.d.ts +7 -0
  141. package/dist/server/runtime/http-server/session-client-route-utils.js +38 -0
  142. package/dist/server/runtime/http-server/session-client-route-utils.js.map +1 -1
  143. package/dist/server/runtime/http-server/session-client-routes.js +12 -2
  144. package/dist/server/runtime/http-server/session-client-routes.js.map +1 -1
  145. package/dist/server/utils/request-id-manager.js +42 -5
  146. package/dist/server/utils/request-id-manager.js.map +1 -1
  147. package/dist/server/utils/stage-logger.d.ts +1 -0
  148. package/dist/server/utils/stage-logger.js +27 -0
  149. package/dist/server/utils/stage-logger.js.map +1 -1
  150. package/dist/utils/errorsamples.js +3 -1
  151. package/dist/utils/errorsamples.js.map +1 -1
  152. package/dist/utils/sensitive-redaction.d.ts +1 -0
  153. package/dist/utils/sensitive-redaction.js +122 -0
  154. package/dist/utils/sensitive-redaction.js.map +1 -0
  155. package/dist/utils/snapshot-writer.js +162 -2
  156. package/dist/utils/snapshot-writer.js.map +1 -1
  157. package/docs/INSTALLATION_AND_QUICKSTART.md +14 -1
  158. package/docs/PORTS.md +12 -0
  159. package/docs/lmstudio-tool-calling.md +25 -0
  160. package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/qwenchat-web-request.d.ts +3 -0
  161. package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/qwenchat-web-request.js +62 -0
  162. package/node_modules/@jsonstudio/llms/dist/conversion/compat/profiles/chat-qwenchat-web.json +47 -0
  163. package/node_modules/@jsonstudio/llms/dist/conversion/hub/node-support.js +5 -2
  164. package/node_modules/@jsonstudio/llms/dist/conversion/hub/operation-table/operation-table-runner.js +68 -7
  165. package/node_modules/@jsonstudio/llms/dist/conversion/hub/operation-table/semantic-mappers/anthropic-mapper-from-chat.js +138 -3
  166. package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/hub-pipeline-chat-process-request-utils.js +24 -0
  167. package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/hub-pipeline-execute-chat-process-entry.js +7 -1
  168. package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/hub-pipeline-execute-request-stage.js +7 -0
  169. package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/hub-pipeline-heavy-input-fastpath.d.ts +24 -0
  170. package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/hub-pipeline-heavy-input-fastpath.js +203 -0
  171. package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/hub-pipeline-route-and-outbound.js +17 -12
  172. package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/hub-stage-timing.d.ts +11 -0
  173. package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/hub-stage-timing.js +82 -1
  174. package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage2_semantic_map/index.js +47 -14
  175. package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/stages/req_outbound/req_outbound_stage1_semantic_map/index.js +43 -0
  176. package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/stages/resp_outbound/resp_outbound_stage1_client_remap/client-remap-protocol-switch.js +222 -19
  177. package/node_modules/@jsonstudio/llms/dist/conversion/hub/policy/policy-engine.js +2 -2
  178. package/node_modules/@jsonstudio/llms/dist/conversion/hub/process/chat-process-pending-tool-sync.js +24 -7
  179. package/node_modules/@jsonstudio/llms/dist/conversion/hub/response/provider-response.js +90 -1
  180. package/node_modules/@jsonstudio/llms/dist/conversion/hub/snapshot-recorder.d.ts +1 -0
  181. package/node_modules/@jsonstudio/llms/dist/conversion/hub/snapshot-recorder.js +252 -1
  182. package/node_modules/@jsonstudio/llms/dist/conversion/responses/responses-openai-bridge/utils.js +5 -3
  183. package/node_modules/@jsonstudio/llms/dist/conversion/responses/responses-openai-bridge.js +44 -4
  184. package/node_modules/@jsonstudio/llms/dist/conversion/shared/anthropic-message-utils-openai-request.d.ts +3 -1
  185. package/node_modules/@jsonstudio/llms/dist/conversion/shared/anthropic-message-utils-openai-request.js +20 -23
  186. package/node_modules/@jsonstudio/llms/dist/conversion/shared/tool-governor.js +68 -30
  187. package/node_modules/@jsonstudio/llms/dist/conversion/snapshot-utils.js +194 -10
  188. package/node_modules/@jsonstudio/llms/dist/native/router_hotpath_napi.node +0 -0
  189. package/node_modules/@jsonstudio/llms/dist/quota/quota-state.js +2 -2
  190. package/node_modules/@jsonstudio/llms/dist/router/virtual-router/engine/routing-state/store.js +35 -2
  191. package/node_modules/@jsonstudio/llms/dist/router/virtual-router/engine.js +9 -9
  192. package/node_modules/@jsonstudio/llms/dist/router/virtual-router/sticky-session-store.js +104 -18
  193. package/node_modules/@jsonstudio/llms/dist/servertool/engine.js +79 -32
  194. package/node_modules/@jsonstudio/llms/dist/servertool/handlers/vision.js +49 -0
  195. package/node_modules/@jsonstudio/llms/dist/servertool/pending-session.js +48 -2
  196. package/node_modules/@jsonstudio/llms/dist/servertool/server-side-tools.js +14 -1
  197. package/node_modules/@jsonstudio/llms/dist/servertool/types.d.ts +1 -0
  198. package/node_modules/@jsonstudio/llms/package.json +1 -1
  199. package/node_modules/ajv/dist/compile/jtd/serialize.js +9 -2
  200. package/node_modules/ajv/dist/compile/jtd/serialize.js.map +1 -1
  201. package/node_modules/ajv/dist/core.d.ts +1 -0
  202. package/node_modules/ajv/dist/core.js.map +1 -1
  203. package/node_modules/ajv/dist/vocabularies/validation/pattern.js +13 -4
  204. package/node_modules/ajv/dist/vocabularies/validation/pattern.js.map +1 -1
  205. package/node_modules/ajv/lib/compile/jtd/serialize.ts +13 -2
  206. package/node_modules/ajv/lib/core.ts +1 -0
  207. package/node_modules/ajv/lib/vocabularies/validation/pattern.ts +15 -4
  208. package/node_modules/ajv/package.json +2 -1
  209. package/package.json +15 -10
  210. package/scripts/ci/repo-sanity.mjs +23 -2
  211. package/scripts/ci/secrets-check.mjs +48 -0
  212. package/scripts/ci/silent-failure-audit.mjs +192 -0
  213. package/scripts/mock-provider/run-regressions.mjs +1 -0
  214. package/scripts/monitor/memory-guard.mjs +207 -0
  215. package/scripts/pack-mode.mjs +32 -36
  216. package/scripts/publish-rcc.mjs +38 -60
  217. package/scripts/tests/apply-patch-loop.mjs +1 -0
  218. package/scripts/tests/blackbox-rcc-vs-routecodex-antigravity.mjs +2 -0
  219. package/scripts/tools-dev/responses-debug-client/src/index.ts +8 -3
  220. package/scripts/verify-e2e-toolcall.mjs +1 -0
  221. package/scripts/verify-install-e2e.mjs +2 -1
@@ -14,7 +14,7 @@ import { runRespProcessStage3ServerToolOrchestration } from '../pipeline/stages/
14
14
  import { runRespOutboundStage1ClientRemap } from '../pipeline/stages/resp_outbound/resp_outbound_stage1_client_remap/index.js';
15
15
  import { runRespOutboundStage2SseStream } from '../pipeline/stages/resp_outbound/resp_outbound_stage2_sse_stream/index.js';
16
16
  import { applyResponseBlacklistWithNative } from '../../../router/virtual-router/engine-selection/native-compat-action-semantics.js';
17
- import { measureHubStage } from '../pipeline/hub-stage-timing.js';
17
+ import { measureHubStage, peekHubStageTopSummary } from '../pipeline/hub-stage-timing.js';
18
18
  import { recordResponsesResponse } from '../../shared/responses-conversation-store.js';
19
19
  import { saveChatProcessSessionActualUsage } from '../process/chat-process-session-usage.js';
20
20
  import { coerceClientPayloadToCanonicalChatCompletionOrThrow, maybeCommitClockReservationFromContext, resolveProviderResponseContextSignals } from './provider-response-helpers.js';
@@ -47,6 +47,94 @@ const INTERNAL_POLICY_DEBUG_BLACKLIST_PATHS = [
47
47
  '__responses_passthrough',
48
48
  'anthropicToolNameMap'
49
49
  ];
50
+ function normalizeHubStageTopEntries(raw) {
51
+ if (!Array.isArray(raw) || raw.length === 0) {
52
+ return [];
53
+ }
54
+ return raw
55
+ .map((entry) => {
56
+ if (!entry || typeof entry !== 'object' || Array.isArray(entry)) {
57
+ return null;
58
+ }
59
+ const record = entry;
60
+ const stage = typeof record.stage === 'string' ? record.stage.trim() : '';
61
+ const totalMs = typeof record.totalMs === 'number' && Number.isFinite(record.totalMs)
62
+ ? Math.max(0, Math.round(record.totalMs))
63
+ : undefined;
64
+ if (!stage || totalMs === undefined) {
65
+ return null;
66
+ }
67
+ const count = typeof record.count === 'number' && Number.isFinite(record.count)
68
+ ? Math.max(0, Math.floor(record.count))
69
+ : undefined;
70
+ const avgMs = typeof record.avgMs === 'number' && Number.isFinite(record.avgMs)
71
+ ? Math.max(0, Math.round(record.avgMs))
72
+ : undefined;
73
+ const maxMs = typeof record.maxMs === 'number' && Number.isFinite(record.maxMs)
74
+ ? Math.max(0, Math.round(record.maxMs))
75
+ : undefined;
76
+ return {
77
+ stage,
78
+ totalMs,
79
+ ...(count !== undefined ? { count } : {}),
80
+ ...(avgMs !== undefined ? { avgMs } : {}),
81
+ ...(maxMs !== undefined ? { maxMs } : {})
82
+ };
83
+ })
84
+ .filter((entry) => Boolean(entry));
85
+ }
86
+ function mergeHubStageTopEntries(baseEntries, appendEntries) {
87
+ if (baseEntries.length === 0) {
88
+ return appendEntries;
89
+ }
90
+ if (appendEntries.length === 0) {
91
+ return baseEntries;
92
+ }
93
+ const merged = new Map();
94
+ const apply = (entry) => {
95
+ const existing = merged.get(entry.stage);
96
+ if (!existing) {
97
+ merged.set(entry.stage, { ...entry });
98
+ return;
99
+ }
100
+ const totalMs = Math.max(0, Math.round((existing.totalMs ?? 0) + (entry.totalMs ?? 0)));
101
+ const count = Math.max(0, Math.round((existing.count ?? 0) + (entry.count ?? 0)));
102
+ const maxMs = Math.max(existing.maxMs ?? 0, entry.maxMs ?? 0, entry.totalMs ?? 0);
103
+ merged.set(entry.stage, {
104
+ stage: entry.stage,
105
+ totalMs,
106
+ ...(count > 0 ? { count } : {}),
107
+ ...(count > 0 ? { avgMs: Math.max(0, Math.round(totalMs / count)) } : {}),
108
+ ...(maxMs > 0 ? { maxMs } : {})
109
+ });
110
+ };
111
+ for (const item of baseEntries) {
112
+ apply(item);
113
+ }
114
+ for (const item of appendEntries) {
115
+ apply(item);
116
+ }
117
+ return Array.from(merged.values()).sort((a, b) => b.totalMs - a.totalMs);
118
+ }
119
+ function attachHubStageTopToContext(context, requestId) {
120
+ if (!requestId || requestId === 'unknown') {
121
+ return;
122
+ }
123
+ const latest = normalizeHubStageTopEntries(peekHubStageTopSummary(requestId, { topN: 12, minMs: 1 }));
124
+ if (latest.length === 0) {
125
+ return;
126
+ }
127
+ const contextRecord = context;
128
+ const rt = contextRecord.__rt && typeof contextRecord.__rt === 'object' && !Array.isArray(contextRecord.__rt)
129
+ ? contextRecord.__rt
130
+ : {};
131
+ const existing = normalizeHubStageTopEntries(rt.hubStageTop);
132
+ const merged = mergeHubStageTopEntries(existing, latest);
133
+ contextRecord.__rt = {
134
+ ...rt,
135
+ hubStageTop: merged
136
+ };
137
+ }
50
138
  export async function convertProviderResponse(options) {
51
139
  const requestId = options.context.requestId || 'unknown';
52
140
  const contextSignals = resolveProviderResponseContextSignals(options.context, options.entryEndpoint);
@@ -265,6 +353,7 @@ export async function convertProviderResponse(options) {
265
353
  hasBody: Boolean(value.body)
266
354
  })
267
355
  });
356
+ attachHubStageTopToContext(options.context, requestId);
268
357
  // Commit scheduled-task delivery only after a successful client payload/stream is prepared.
269
358
  await maybeCommitClockReservationFromContext(options.context);
270
359
  try {
@@ -4,6 +4,7 @@ export interface SnapshotStageRecorderOptions {
4
4
  context: AdapterContext;
5
5
  endpoint: string;
6
6
  }
7
+ export declare function trimSnapshotHotpathPayloadForNative(stage: string, payload: unknown): unknown;
7
8
  export declare class SnapshotStageRecorder implements StageRecorder {
8
9
  private readonly options;
9
10
  private readonly writer?;
@@ -1,5 +1,255 @@
1
1
  import { createSnapshotWriter } from '../snapshot-utils.js';
2
2
  import { normalizeSnapshotStagePayloadWithNative } from '../../router/virtual-router/engine-selection/native-snapshot-hooks.js';
3
+ const SNAPSHOT_STRING_PREVIEW_CHARS = 240;
4
+ const SNAPSHOT_ARRAY_PREVIEW_ITEMS = 2;
5
+ const FORMAT_PARSE_STAGE_NAMES = new Set([
6
+ 'req_inbound_stage1_format_parse',
7
+ 'chat_process.req.stage1.format_parse'
8
+ ]);
9
+ const TOOL_GOVERNANCE_STAGE_NAMES = new Set([
10
+ 'req_process_stage1_tool_governance',
11
+ 'chat_process.req.stage4.tool_governance'
12
+ ]);
13
+ function clipSnapshotString(value) {
14
+ const text = String(value ?? '');
15
+ return text.length > SNAPSHOT_STRING_PREVIEW_CHARS
16
+ ? `${text.slice(0, SNAPSHOT_STRING_PREVIEW_CHARS)}…`
17
+ : text;
18
+ }
19
+ function summarizeScalar(value) {
20
+ if (typeof value === 'string') {
21
+ return clipSnapshotString(value);
22
+ }
23
+ if (value === null ||
24
+ value === undefined ||
25
+ typeof value === 'number' ||
26
+ typeof value === 'boolean') {
27
+ return value;
28
+ }
29
+ return undefined;
30
+ }
31
+ function summarizeValuePreview(value, depth = 0) {
32
+ const scalar = summarizeScalar(value);
33
+ if (scalar !== undefined || value === null) {
34
+ return scalar;
35
+ }
36
+ if (Array.isArray(value)) {
37
+ if (depth >= 2) {
38
+ return { type: 'array', count: value.length };
39
+ }
40
+ const first = value.slice(0, SNAPSHOT_ARRAY_PREVIEW_ITEMS).map((entry) => summarizeValuePreview(entry, depth + 1));
41
+ const last = value.slice(-SNAPSHOT_ARRAY_PREVIEW_ITEMS).map((entry) => summarizeValuePreview(entry, depth + 1));
42
+ return {
43
+ type: 'array',
44
+ count: value.length,
45
+ first,
46
+ last
47
+ };
48
+ }
49
+ if (!value || typeof value !== 'object') {
50
+ return String(value);
51
+ }
52
+ const record = value;
53
+ const keys = Object.keys(record);
54
+ const preferredKeys = ['role', 'type', 'name', 'id', 'call_id', 'content', 'text', 'input', 'output', 'status'];
55
+ const preview = {};
56
+ for (const key of preferredKeys) {
57
+ if (key in record) {
58
+ preview[key] = summarizeValuePreview(record[key], depth + 1);
59
+ }
60
+ }
61
+ if (!Object.keys(preview).length) {
62
+ for (const key of keys.slice(0, 6)) {
63
+ preview[key] = summarizeValuePreview(record[key], depth + 1);
64
+ }
65
+ }
66
+ return {
67
+ type: 'object',
68
+ keys,
69
+ preview
70
+ };
71
+ }
72
+ function summarizeCollection(value) {
73
+ if (!Array.isArray(value)) {
74
+ return summarizeValuePreview(value);
75
+ }
76
+ return {
77
+ count: value.length,
78
+ preview: summarizeValuePreview(value)
79
+ };
80
+ }
81
+ function summarizeTools(value) {
82
+ if (!Array.isArray(value)) {
83
+ return summarizeValuePreview(value);
84
+ }
85
+ return {
86
+ count: value.length,
87
+ names: value
88
+ .map((tool) => {
89
+ if (!tool || typeof tool !== 'object') {
90
+ return null;
91
+ }
92
+ const node = tool;
93
+ if (typeof node.name === 'string' && node.name.trim()) {
94
+ return node.name.trim();
95
+ }
96
+ const fn = node.function;
97
+ if (fn && typeof fn === 'object' && typeof fn.name === 'string') {
98
+ return String(fn.name).trim();
99
+ }
100
+ return typeof node.type === 'string' ? node.type : null;
101
+ })
102
+ .filter((name) => Boolean(name))
103
+ .slice(0, 32)
104
+ };
105
+ }
106
+ function summarizeMetadata(value) {
107
+ if (!value || typeof value !== 'object' || Array.isArray(value)) {
108
+ return summarizeValuePreview(value);
109
+ }
110
+ const metadata = value;
111
+ const summary = {};
112
+ for (const key of [
113
+ 'requestId',
114
+ 'clientRequestId',
115
+ 'providerProtocol',
116
+ 'endpoint',
117
+ 'entryEndpoint',
118
+ 'originalEndpoint',
119
+ 'processMode',
120
+ 'sessionId',
121
+ 'conversationId',
122
+ 'workdir',
123
+ 'cwd',
124
+ 'processedAt',
125
+ 'stage',
126
+ 'stream'
127
+ ]) {
128
+ if (key in metadata) {
129
+ summary[key] = summarizeValuePreview(metadata[key]);
130
+ }
131
+ }
132
+ if ('clientHeaders' in metadata) {
133
+ const headers = metadata.clientHeaders;
134
+ if (headers && typeof headers === 'object' && !Array.isArray(headers)) {
135
+ summary.clientHeaders = { keys: Object.keys(headers).sort() };
136
+ }
137
+ else {
138
+ summary.clientHeaders = summarizeValuePreview(headers);
139
+ }
140
+ }
141
+ if ('capturedContext' in metadata) {
142
+ summary.capturedContext = summarizeValuePreview(metadata.capturedContext);
143
+ }
144
+ if ('__rt' in metadata) {
145
+ summary.__rt = summarizeValuePreview(metadata.__rt);
146
+ }
147
+ if ('__raw_request_body' in metadata) {
148
+ const raw = metadata.__raw_request_body;
149
+ summary.__raw_request_body = {
150
+ omitted: true,
151
+ preview: summarizeValuePreview(raw, 1)
152
+ };
153
+ }
154
+ return summary;
155
+ }
156
+ function summarizeSemantics(value) {
157
+ if (!value || typeof value !== 'object' || Array.isArray(value)) {
158
+ return summarizeValuePreview(value);
159
+ }
160
+ const semantics = value;
161
+ const summary = {};
162
+ if ('tools' in semantics) {
163
+ const tools = semantics.tools;
164
+ const toolsRecord = tools && typeof tools === 'object' && !Array.isArray(tools) ? tools : null;
165
+ summary.tools = toolsRecord
166
+ ? {
167
+ keys: Object.keys(toolsRecord).sort(),
168
+ toolNameAliasMap: summarizeValuePreview(toolsRecord.toolNameAliasMap, 1),
169
+ clientToolsRaw: summarizeTools(toolsRecord.clientToolsRaw)
170
+ }
171
+ : summarizeValuePreview(tools);
172
+ }
173
+ const responses = semantics.responses;
174
+ const responsesRecord = responses && typeof responses === 'object' && !Array.isArray(responses)
175
+ ? responses
176
+ : null;
177
+ if (responsesRecord) {
178
+ const context = responsesRecord.context;
179
+ const contextRecord = context && typeof context === 'object' && !Array.isArray(context)
180
+ ? context
181
+ : null;
182
+ summary.responses = contextRecord
183
+ ? {
184
+ context: {
185
+ requestId: summarizeValuePreview(contextRecord.requestId),
186
+ isChatPayload: summarizeValuePreview(contextRecord.isChatPayload),
187
+ isResponsesPayload: summarizeValuePreview(contextRecord.isResponsesPayload),
188
+ systemInstruction: summarizeValuePreview(contextRecord.systemInstruction),
189
+ parameters: summarizeValuePreview(contextRecord.parameters, 1),
190
+ input: summarizeCollection(contextRecord.input),
191
+ __captured_tool_results: summarizeCollection(contextRecord.__captured_tool_results),
192
+ toolsRaw: summarizeTools(contextRecord.toolsRaw),
193
+ toolsNormalized: summarizeTools(contextRecord.toolsNormalized)
194
+ }
195
+ }
196
+ : summarizeValuePreview(responsesRecord);
197
+ }
198
+ return summary;
199
+ }
200
+ function buildFormatParseSnapshotSummary(payload) {
201
+ const envelope = payload.payload && typeof payload.payload === 'object' && !Array.isArray(payload.payload)
202
+ ? payload.payload
203
+ : null;
204
+ return {
205
+ __snapshot_summary: true,
206
+ stage: 'format_parse',
207
+ format: summarizeValuePreview(payload.format),
208
+ metadata: summarizeValuePreview(payload.metadata, 1),
209
+ payload: envelope
210
+ ? {
211
+ model: summarizeValuePreview(envelope.model),
212
+ include: summarizeValuePreview(envelope.include, 1),
213
+ stream: summarizeValuePreview(envelope.stream),
214
+ tool_choice: summarizeValuePreview(envelope.tool_choice),
215
+ max_output_tokens: summarizeValuePreview(envelope.max_output_tokens),
216
+ max_tokens: summarizeValuePreview(envelope.max_tokens),
217
+ input: summarizeCollection(envelope.input),
218
+ messages: summarizeCollection(envelope.messages),
219
+ tools: summarizeTools(envelope.tools)
220
+ }
221
+ : summarizeValuePreview(payload.payload, 1)
222
+ };
223
+ }
224
+ function buildToolGovernanceSnapshotSummary(payload) {
225
+ return {
226
+ __snapshot_summary: true,
227
+ stage: 'tool_governance',
228
+ model: summarizeValuePreview(payload.model),
229
+ stream: summarizeValuePreview(payload.stream),
230
+ tool_choice: summarizeValuePreview(payload.tool_choice),
231
+ parameters: summarizeValuePreview(payload.parameters, 1),
232
+ processed: summarizeValuePreview(payload.processed, 1),
233
+ processingMetadata: summarizeValuePreview(payload.processingMetadata, 1),
234
+ messages: summarizeCollection(payload.messages),
235
+ tools: summarizeTools(payload.tools),
236
+ metadata: summarizeMetadata(payload.metadata),
237
+ semantics: summarizeSemantics(payload.semantics)
238
+ };
239
+ }
240
+ export function trimSnapshotHotpathPayloadForNative(stage, payload) {
241
+ if (!payload || typeof payload !== 'object' || Array.isArray(payload)) {
242
+ return payload;
243
+ }
244
+ const record = payload;
245
+ if (FORMAT_PARSE_STAGE_NAMES.has(stage)) {
246
+ return buildFormatParseSnapshotSummary(record);
247
+ }
248
+ if (TOOL_GOVERNANCE_STAGE_NAMES.has(stage)) {
249
+ return buildToolGovernanceSnapshotSummary(record);
250
+ }
251
+ return payload;
252
+ }
3
253
  export class SnapshotStageRecorder {
4
254
  options;
5
255
  writer;
@@ -21,7 +271,8 @@ export class SnapshotStageRecorder {
21
271
  if (!this.writer) {
22
272
  return;
23
273
  }
24
- const normalized = normalizeSnapshotStagePayloadWithNative(stage, payload);
274
+ const trimmed = trimSnapshotHotpathPayloadForNative(stage, payload);
275
+ const normalized = normalizeSnapshotStagePayloadWithNative(stage, trimmed);
25
276
  if (!normalized) {
26
277
  return;
27
278
  }
@@ -102,8 +102,10 @@ export function sanitizeCapturedResponsesInput(input) {
102
102
  if (!sanitizedName) {
103
103
  continue;
104
104
  }
105
- const next = jsonClone(entry);
106
- next.name = sanitizedName;
105
+ const rawName = typeof entry.name === 'string' ? String(entry.name) : '';
106
+ const next = rawName === sanitizedName
107
+ ? entry
108
+ : { ...entry, name: sanitizedName };
107
109
  const callId = typeof next.call_id === 'string' ? String(next.call_id).trim() : '';
108
110
  if (callId) {
109
111
  acceptedCallIds.add(callId);
@@ -117,7 +119,7 @@ export function sanitizeCapturedResponsesInput(input) {
117
119
  continue;
118
120
  }
119
121
  }
120
- out.push(jsonClone(entry));
122
+ out.push(entry);
121
123
  }
122
124
  return out;
123
125
  }
@@ -43,6 +43,43 @@ function filterRedundantResponsesReasoningAction(actions) {
43
43
  return name !== 'reasoning.extract';
44
44
  });
45
45
  }
46
+ function hasToolSignalsInMessages(messages) {
47
+ for (const message of messages) {
48
+ if (!message || typeof message !== 'object') {
49
+ continue;
50
+ }
51
+ const role = typeof message.role === 'string' ? message.role.trim().toLowerCase() : '';
52
+ if (role === 'tool') {
53
+ return true;
54
+ }
55
+ if (typeof message.tool_call_id === 'string' && message.tool_call_id.trim().length) {
56
+ return true;
57
+ }
58
+ const toolCalls = message.tool_calls;
59
+ if (Array.isArray(toolCalls) && toolCalls.length > 0) {
60
+ return true;
61
+ }
62
+ }
63
+ return false;
64
+ }
65
+ function filterResponsesInboundActionsByPayloadHints(actions, messages) {
66
+ if (!actions?.length) {
67
+ return actions;
68
+ }
69
+ const hasToolSignals = hasToolSignalsInMessages(messages);
70
+ if (hasToolSignals) {
71
+ return actions;
72
+ }
73
+ const toolOnlyActions = new Set([
74
+ 'tools.normalize-call-ids',
75
+ 'compat.fix-apply-patch',
76
+ 'tools.ensure-placeholders'
77
+ ]);
78
+ return actions.filter((action) => {
79
+ const name = typeof action?.name === 'string' ? action.name.trim().toLowerCase() : '';
80
+ return !toolOnlyActions.has(name);
81
+ });
82
+ }
46
83
  export function captureResponsesContext(payload, dto) {
47
84
  const preservedInput = Array.isArray(payload.input)
48
85
  ? payload.input
@@ -71,9 +108,12 @@ export function captureResponsesContext(payload, dto) {
71
108
  captured.systemInstruction = payload.instructions;
72
109
  }
73
110
  if (captured.metadata && isJsonObject(captured.metadata)) {
74
- const cloned = jsonClone(captured.metadata);
75
- delete cloned.extraFields;
76
- captured.metadata = cloned;
111
+ const rawMetadata = captured.metadata;
112
+ if (Object.prototype.hasOwnProperty.call(rawMetadata, 'extraFields')) {
113
+ const cloned = jsonClone(rawMetadata);
114
+ delete cloned.extraFields;
115
+ captured.metadata = cloned;
116
+ }
77
117
  }
78
118
  return captured;
79
119
  }
@@ -98,7 +138,7 @@ export function buildChatRequestFromResponses(payload, context) {
98
138
  });
99
139
  try {
100
140
  const bridgePolicy = resolveBridgePolicy({ protocol: 'openai-responses', moduleType: 'openai-responses' });
101
- const policyActions = filterRedundantResponsesReasoningAction(resolvePolicyActions(bridgePolicy, 'request_inbound'));
141
+ const policyActions = filterResponsesInboundActionsByPayloadHints(filterRedundantResponsesReasoningAction(resolvePolicyActions(bridgePolicy, 'request_inbound')), messages);
102
142
  if (policyActions?.length) {
103
143
  logHubStageTiming(requestId, 'req_inbound.responses.inbound_policy', 'start');
104
144
  const policyStart = Date.now();
@@ -1,3 +1,5 @@
1
1
  type Unknown = Record<string, unknown>;
2
- export declare function buildAnthropicRequestFromOpenAIChat(chatReq: unknown): Unknown;
2
+ export declare function buildAnthropicRequestFromOpenAIChat(chatReq: unknown, options?: {
3
+ requestId?: string;
4
+ }): Unknown;
3
5
  export {};
@@ -1,8 +1,7 @@
1
- import { createBridgeActionState, runBridgeActionPipeline } from '../bridge-actions.js';
2
- import { resolveBridgePolicy, resolvePolicyActions } from '../bridge-policies.js';
3
1
  import { mapChatToolsToAnthropicTools } from './anthropic-message-utils-tool-schema.js';
4
2
  import { ProviderProtocolError } from '../provider-protocol-error.js';
5
3
  import { jsonClone } from '../hub/types/json.js';
4
+ import { logHubStageTiming } from '../hub/pipeline/hub-stage-timing.js';
6
5
  import { parseLenientJsonishWithNative } from '../../router/virtual-router/engine-selection/native-shared-conversion-semantics.js';
7
6
  import { isObject, normalizeShellLikeToolInput, requireSystemText, requireTrimmedString, sanitizeToolUseId } from './anthropic-message-utils-core.js';
8
7
  import { normalizeAnthropicToolChoice } from './anthropic-message-utils-openai-response.js';
@@ -22,30 +21,18 @@ const ANTHROPIC_TOP_LEVEL_FIELDS = new Set([
22
21
  'tool_choice',
23
22
  'thinking'
24
23
  ]);
25
- export function buildAnthropicRequestFromOpenAIChat(chatReq) {
24
+ export function buildAnthropicRequestFromOpenAIChat(chatReq, options) {
26
25
  const requestBody = isObject(chatReq) ? chatReq : {};
26
+ const requestId = typeof options?.requestId === 'string' && options.requestId.trim().length
27
+ ? options.requestId.trim()
28
+ : 'unknown';
27
29
  const model = String(requestBody?.model || 'unknown');
28
30
  const messages = [];
29
- try {
30
- const bridgePolicy = resolveBridgePolicy({ protocol: 'anthropic-messages' });
31
- const actions = resolvePolicyActions(bridgePolicy, 'request_outbound');
32
- if (actions?.length && Array.isArray(requestBody.messages)) {
33
- const actionState = createBridgeActionState({
34
- messages: requestBody.messages,
35
- rawRequest: requestBody
36
- });
37
- runBridgeActionPipeline({
38
- stage: 'request_outbound',
39
- actions,
40
- protocol: bridgePolicy?.protocol ?? 'anthropic-messages',
41
- moduleType: bridgePolicy?.moduleType ?? 'anthropic-messages',
42
- state: actionState
43
- });
44
- }
45
- }
46
- catch {
47
- // ignore policy errors
48
- }
31
+ // IMPORTANT:
32
+ // The request_outbound bridge-policy pipeline was previously executed here, but
33
+ // its output state was never consumed by this builder. That made the whole pass
34
+ // pure overhead (large-message O(n) scans/clones) with zero semantic effect.
35
+ // To preserve payload semantics and stop latency bleed, we skip that no-op pass.
49
36
  const collectText = (val) => {
50
37
  if (!val)
51
38
  return '';
@@ -65,6 +52,8 @@ export function buildAnthropicRequestFromOpenAIChat(chatReq) {
65
52
  const mirrorShapes = extractMirrorShapesFromRequest(requestBody);
66
53
  let mirrorIndex = 0;
67
54
  const knownToolCallIds = new Set();
55
+ logHubStageTiming(requestId, 'req_outbound.anthropic.pre_scan_tool_calls', 'start');
56
+ const preScanStart = Date.now();
68
57
  for (const m of msgs) {
69
58
  if (!m || typeof m !== 'object')
70
59
  continue;
@@ -81,6 +70,9 @@ export function buildAnthropicRequestFromOpenAIChat(chatReq) {
81
70
  knownToolCallIds.add(id);
82
71
  }
83
72
  }
73
+ logHubStageTiming(requestId, 'req_outbound.anthropic.pre_scan_tool_calls', 'completed', {
74
+ elapsedMs: Date.now() - preScanStart
75
+ });
84
76
  const systemBlocks = [];
85
77
  const pushSystemBlock = (text) => {
86
78
  const trimmed = text.trim();
@@ -117,6 +109,8 @@ export function buildAnthropicRequestFromOpenAIChat(chatReq) {
117
109
  catch {
118
110
  // ignore system pre-scan errors
119
111
  }
112
+ logHubStageTiming(requestId, 'req_outbound.anthropic.map_messages', 'start');
113
+ const mapMessagesStart = Date.now();
120
114
  for (const m of msgs) {
121
115
  if (!m || typeof m !== 'object')
122
116
  continue;
@@ -253,6 +247,9 @@ export function buildAnthropicRequestFromOpenAIChat(chatReq) {
253
247
  messages.push({ role, content: contentNode });
254
248
  }
255
249
  }
250
+ logHubStageTiming(requestId, 'req_outbound.anthropic.map_messages', 'completed', {
251
+ elapsedMs: Date.now() - mapMessagesStart
252
+ });
256
253
  const out = { model };
257
254
  if (systemBlocks.length) {
258
255
  out.system = systemBlocks;