@jsonstudio/llms 0.6.3551 → 0.6.3686

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 (66) hide show
  1. package/dist/conversion/compat/actions/antigravity-thought-signature-cache.js +4 -115
  2. package/dist/conversion/compat/actions/auto-thinking.js +3 -2
  3. package/dist/conversion/compat/actions/deepseek-web-response.js +15 -49
  4. package/dist/conversion/compat/actions/gemini-cli-request.d.ts +2 -0
  5. package/dist/conversion/compat/actions/gemini-cli-request.js +1 -1
  6. package/dist/conversion/compat/actions/glm-history-image-trim.js +3 -37
  7. package/dist/conversion/compat/actions/glm-image-content.js +3 -32
  8. package/dist/conversion/compat/actions/glm-native-compat.d.ts +6 -0
  9. package/dist/conversion/compat/actions/glm-native-compat.js +34 -0
  10. package/dist/conversion/compat/actions/glm-vision-prompt.js +3 -76
  11. package/dist/conversion/compat/actions/glm-web-search.js +10 -43
  12. package/dist/conversion/compat/actions/iflow-kimi-cli-defaults.js +4 -53
  13. package/dist/conversion/compat/actions/iflow-kimi-history-media-placeholder.js +5 -141
  14. package/dist/conversion/compat/actions/iflow-kimi-thinking-reasoning-fill.js +7 -28
  15. package/dist/conversion/compat/actions/iflow-native-compat.d.ts +6 -0
  16. package/dist/conversion/compat/actions/iflow-native-compat.js +36 -0
  17. package/dist/conversion/compat/actions/iflow-response-body-unwrap.js +4 -119
  18. package/dist/conversion/compat/actions/iflow-web-search.js +14 -55
  19. package/dist/conversion/hub/operation-table/semantic-mappers/archive/chat-mapper.archive.js +5 -0
  20. package/dist/conversion/hub/operation-table/semantic-mappers/responses-mapper.js +31 -18
  21. package/dist/conversion/hub/pipeline/hub-pipeline.js +163 -163
  22. package/dist/conversion/hub/pipeline/hub-stage-timing.d.ts +6 -0
  23. package/dist/conversion/hub/pipeline/hub-stage-timing.js +178 -0
  24. package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage1_format_parse/index.d.ts +4 -4
  25. package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage1_format_parse/index.js +33 -14
  26. package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage2_semantic_map/index.d.ts +7 -6
  27. package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage2_semantic_map/index.js +41 -23
  28. package/dist/conversion/hub/pipeline/stages/req_outbound/req_outbound_stage1_semantic_map/index.js +44 -1
  29. package/dist/conversion/hub/pipeline/stages/req_process/req_process_stage1_tool_governance/index.js +4 -1
  30. package/dist/conversion/hub/process/chat-process-continue-execution.js +5 -4
  31. package/dist/conversion/hub/process/chat-process-governance-orchestration.js +3 -1
  32. package/dist/conversion/hub/process/chat-process-media.d.ts +3 -1
  33. package/dist/conversion/hub/process/chat-process-media.js +92 -2
  34. package/dist/conversion/hub/process/chat-process-session-usage.d.ts +7 -0
  35. package/dist/conversion/hub/process/chat-process-session-usage.js +147 -0
  36. package/dist/conversion/hub/response/provider-response.js +13 -0
  37. package/dist/conversion/responses/responses-openai-bridge/response-payload.js +0 -12
  38. package/dist/conversion/responses/responses-openai-bridge/types.d.ts +1 -9
  39. package/dist/conversion/responses/responses-openai-bridge.js +77 -44
  40. package/dist/conversion/shared/reasoning-normalizer.js +42 -0
  41. package/dist/conversion/shared/responses-tool-utils.js +2 -3
  42. package/dist/native/router_hotpath_napi.node +0 -0
  43. package/dist/router/virtual-router/bootstrap/profile-builder.js +1 -0
  44. package/dist/router/virtual-router/bootstrap/provider-normalization.d.ts +1 -0
  45. package/dist/router/virtual-router/bootstrap/provider-normalization.js +6 -0
  46. package/dist/router/virtual-router/bootstrap.js +1 -6
  47. package/dist/router/virtual-router/engine-legacy.js +43 -0
  48. package/dist/router/virtual-router/engine-logging.d.ts +3 -0
  49. package/dist/router/virtual-router/engine-logging.js +29 -3
  50. package/dist/router/virtual-router/engine-selection/native-hub-pipeline-edge-stage-semantics.d.ts +2 -2
  51. package/dist/router/virtual-router/engine-selection/native-hub-pipeline-edge-stage-semantics.js +96 -80
  52. package/dist/router/virtual-router/engine-selection/native-hub-pipeline-req-process-semantics.d.ts +1 -0
  53. package/dist/router/virtual-router/engine.js +34 -22
  54. package/dist/router/virtual-router/provider-registry.js +1 -0
  55. package/dist/router/virtual-router/routing-instructions/state.js +35 -3
  56. package/dist/router/virtual-router/routing-instructions/types.d.ts +4 -0
  57. package/dist/router/virtual-router/types.d.ts +7 -0
  58. package/dist/servertool/engine.js +3 -34
  59. package/dist/servertool/handlers/followup-request-builder.js +0 -6
  60. package/dist/servertool/handlers/gemini-empty-reply-continue.js +3 -274
  61. package/dist/servertool/handlers/stop-message-auto/runtime-utils.d.ts +0 -3
  62. package/dist/servertool/handlers/stop-message-auto/runtime-utils.js +0 -29
  63. package/dist/servertool/handlers/stop-message-auto.js +2 -10
  64. package/dist/servertool/handlers/vision.js +4 -1
  65. package/dist/servertool/server-side-tools.js +66 -3
  66. package/package.json +1 -1
@@ -14,18 +14,12 @@ export function bootstrapVirtualRouterConfig(input) {
14
14
  throw new VirtualRouterError('Virtual Router requires at least one provider in configuration', VirtualRouterErrorCode.CONFIG_ERROR);
15
15
  }
16
16
  const routingSource = normalizeRouting(section.routing);
17
- if (!Object.keys(routingSource).length) {
18
- throw new VirtualRouterError('Virtual Router routing table cannot be empty', VirtualRouterErrorCode.CONFIG_ERROR);
19
- }
20
17
  const webSearch = normalizeWebSearch(section.webSearch, routingSource);
21
18
  validateWebSearchRouting(webSearch, routingSource);
22
19
  const execCommandGuard = normalizeExecCommandGuard(section.execCommandGuard);
23
20
  const clock = normalizeClock(section.clock);
24
21
  const { runtimeEntries, aliasIndex, modelIndex } = buildProviderRuntimeEntries(providersSource);
25
22
  const { routing, targetKeys } = expandRoutingTable(routingSource, aliasIndex, modelIndex);
26
- if (!routing.default || routing.default.length === 0) {
27
- throw new VirtualRouterError('Virtual Router default route must contain at least one provider target', VirtualRouterErrorCode.CONFIG_ERROR);
28
- }
29
23
  const expandedTargetKeys = new Set(targetKeys);
30
24
  for (const [providerId, aliases] of aliasIndex.entries()) {
31
25
  const models = modelIndex.get(providerId)?.models ?? [];
@@ -123,6 +117,7 @@ function buildProviderRuntimeEntries(providers) {
123
117
  endpoint: normalizedProvider.endpoint,
124
118
  headers: normalizedProvider.headers,
125
119
  auth: runtimeAuth,
120
+ ...(normalizedProvider.enabled !== undefined ? { enabled: normalizedProvider.enabled } : {}),
126
121
  outboundProfile: normalizedProvider.outboundProfile,
127
122
  compatibilityProfile: normalizedProvider.compatibilityProfile,
128
123
  processMode: normalizedProvider.processMode,
@@ -16,6 +16,25 @@ import { selectProvider as selectProviderImpl, selectFromCandidates as selectFro
16
16
  import { parseDirectProviderModel as parseDirectProviderModelImpl, shouldFallbackDirectModelForMedia as shouldFallbackDirectModelForMediaImpl } from './engine-legacy/direct-model.js';
17
17
  import { normalizeRouteAlias as normalizeRouteAliasImpl, buildRouteCandidates as buildRouteCandidatesImpl, reorderForInlineVision as reorderForInlineVisionImpl, reorderForPreferredModel as reorderForPreferredModelImpl, routeSupportsModel as routeSupportsModelImpl, routeSupportsInlineVision as routeSupportsInlineVisionImpl, sortByPriority as sortByPriorityImpl, routeWeight as routeWeightImpl, routeHasForceFlag as routeHasForceFlagImpl, routeHasTargets as routeHasTargetsImpl, hasPrimaryPool as hasPrimaryPoolImpl, sortRoutePools as sortRoutePoolsImpl, flattenPoolTargets as flattenPoolTargetsImpl } from './engine-legacy/route-utils.js';
18
18
  import { resolveSelectionPenalty as resolveSelectionPenaltyImpl, resolveInstructionProcessModeForSelection as resolveInstructionProcessModeForSelectionImpl, resolveInstructionTarget as resolveInstructionTargetImpl, filterCandidatesByRoutingState as filterCandidatesByRoutingStateImpl, buildStickyRouteCandidatesFromFiltered as buildStickyRouteCandidatesFromFilteredImpl } from './engine-legacy/selection-state.js';
19
+ const ALLOW_ENGINE_LEGACY_IMPORTS = process.env.LLMSWITCH_ALLOW_ENGINE_LEGACY_IMPORTS === '1' ||
20
+ process.env.ROUTECODEX_ALLOW_ENGINE_LEGACY_IMPORTS === '1';
21
+ if (!ALLOW_ENGINE_LEGACY_IMPORTS) {
22
+ throw new Error('[engine-legacy] import is fail-closed. Set LLMSWITCH_ALLOW_ENGINE_LEGACY_IMPORTS=1 only for explicit compatibility/debug work.');
23
+ }
24
+ function warnLegacyCompatibilitySurface(method) {
25
+ const enabled = process.env.LLMSWITCH_WARN_LEGACY_SURFACES === '1' ||
26
+ process.env.ROUTECODEX_WARN_LEGACY_SURFACES === '1';
27
+ if (!enabled) {
28
+ return;
29
+ }
30
+ try {
31
+ // eslint-disable-next-line no-console
32
+ console.warn(`[engine-legacy] compatibility surface invoked: ${method}. Do not add new runtime logic to engine-legacy helpers.`);
33
+ }
34
+ catch {
35
+ // best-effort only
36
+ }
37
+ }
19
38
  export class VirtualRouterEngine {
20
39
  routing = {};
21
40
  providerRegistry = new ProviderRegistry();
@@ -99,42 +118,55 @@ export class VirtualRouterEngine {
99
118
  return this.nativeEngine.getStatus();
100
119
  }
101
120
  normalizeRouteAlias(routeName) {
121
+ warnLegacyCompatibilitySurface('normalizeRouteAlias');
102
122
  return normalizeRouteAliasImpl(routeName);
103
123
  }
104
124
  buildRouteCandidates(requestedRoute, classificationCandidates, features) {
125
+ warnLegacyCompatibilitySurface('buildRouteCandidates');
105
126
  return buildRouteCandidatesImpl(this, requestedRoute, classificationCandidates, features);
106
127
  }
107
128
  reorderForInlineVision(routeNames) {
129
+ warnLegacyCompatibilitySurface('reorderForInlineVision');
108
130
  return reorderForInlineVisionImpl(this, routeNames);
109
131
  }
110
132
  reorderForPreferredModel(routeNames, modelId) {
133
+ warnLegacyCompatibilitySurface('reorderForPreferredModel');
111
134
  return reorderForPreferredModelImpl(this, routeNames, modelId);
112
135
  }
113
136
  routeSupportsModel(routeName, modelId) {
137
+ warnLegacyCompatibilitySurface('routeSupportsModel');
114
138
  return routeSupportsModelImpl(this, routeName, modelId);
115
139
  }
116
140
  routeSupportsInlineVision(routeName) {
141
+ warnLegacyCompatibilitySurface('routeSupportsInlineVision');
117
142
  return routeSupportsInlineVisionImpl(this, routeName);
118
143
  }
119
144
  sortByPriority(routeNames) {
145
+ warnLegacyCompatibilitySurface('sortByPriority');
120
146
  return sortByPriorityImpl(routeNames);
121
147
  }
122
148
  routeWeight(routeName) {
149
+ warnLegacyCompatibilitySurface('routeWeight');
123
150
  return routeWeightImpl(routeName);
124
151
  }
125
152
  routeHasForceFlag(routeName) {
153
+ warnLegacyCompatibilitySurface('routeHasForceFlag');
126
154
  return routeHasForceFlagImpl(this, routeName);
127
155
  }
128
156
  routeHasTargets(pools) {
157
+ warnLegacyCompatibilitySurface('routeHasTargets');
129
158
  return routeHasTargetsImpl(this, pools);
130
159
  }
131
160
  hasPrimaryPool(pools) {
161
+ warnLegacyCompatibilitySurface('hasPrimaryPool');
132
162
  return hasPrimaryPoolImpl(this, pools);
133
163
  }
134
164
  sortRoutePools(pools) {
165
+ warnLegacyCompatibilitySurface('sortRoutePools');
135
166
  return sortRoutePoolsImpl(this, pools);
136
167
  }
137
168
  flattenPoolTargets(pools) {
169
+ warnLegacyCompatibilitySurface('flattenPoolTargets');
138
170
  return flattenPoolTargetsImpl(this, pools);
139
171
  }
140
172
  markProviderCooldown(providerKey, cooldownMs) {
@@ -167,36 +199,47 @@ export class VirtualRouterEngine {
167
199
  return shouldFallbackDirectModelForMediaImpl(this, direct, features);
168
200
  }
169
201
  selectProvider(requestedRoute, metadata, classification, features, routingState) {
202
+ warnLegacyCompatibilitySurface('selectProvider');
170
203
  return selectProviderImpl(this, requestedRoute, metadata, classification, features, routingState);
171
204
  }
172
205
  selectFromCandidates(routes, metadata, classification, features, state, requiredProviderKeys, allowAliasRotation) {
206
+ warnLegacyCompatibilitySurface('selectFromCandidates');
173
207
  return selectFromCandidatesImpl(this, routes, metadata, classification, features, state, requiredProviderKeys, allowAliasRotation);
174
208
  }
175
209
  selectFromStickyPool(stickyKeySet, metadata, features, state, allowAliasRotation) {
210
+ warnLegacyCompatibilitySurface('selectFromStickyPool');
176
211
  return selectFromStickyPoolImpl(this, stickyKeySet, metadata, features, state, allowAliasRotation);
177
212
  }
178
213
  extractExcludedProviderKeySet(metadata) {
214
+ warnLegacyCompatibilitySurface('extractExcludedProviderKeySet');
179
215
  return extractExcludedProviderKeySetImpl(this, metadata);
180
216
  }
181
217
  resolveSelectionPenalty(providerKey) {
218
+ warnLegacyCompatibilitySurface('resolveSelectionPenalty');
182
219
  return resolveSelectionPenaltyImpl(this, providerKey);
183
220
  }
184
221
  resolveInstructionProcessModeForSelection(providerKey, routingState) {
222
+ warnLegacyCompatibilitySurface('resolveInstructionProcessModeForSelection');
185
223
  return resolveInstructionProcessModeForSelectionImpl(this, providerKey, routingState);
186
224
  }
187
225
  resolveInstructionTarget(target) {
226
+ warnLegacyCompatibilitySurface('resolveInstructionTarget');
188
227
  return resolveInstructionTargetImpl(this, target);
189
228
  }
190
229
  buildStickyRouteCandidatesFromFiltered(filteredCandidates, stickyKeySet) {
230
+ warnLegacyCompatibilitySurface('buildStickyRouteCandidatesFromFiltered');
191
231
  return buildStickyRouteCandidatesFromFilteredImpl(this, filteredCandidates, stickyKeySet);
192
232
  }
193
233
  filterCandidatesByRoutingState(routes, state) {
234
+ warnLegacyCompatibilitySurface('filterCandidatesByRoutingState');
194
235
  return filterCandidatesByRoutingStateImpl(this, routes, state);
195
236
  }
196
237
  resolveStickyKey(metadata) {
238
+ warnLegacyCompatibilitySurface('resolveStickyKey');
197
239
  return resolveStickyKeyImpl(metadata);
198
240
  }
199
241
  resolveSessionScope(metadata) {
242
+ warnLegacyCompatibilitySurface('resolveSessionScope');
200
243
  return resolveSessionScopeImpl(metadata);
201
244
  }
202
245
  }
@@ -20,6 +20,7 @@ export type StopMessageRuntimeSummary = {
20
20
  export type VirtualRouterHitRecord = {
21
21
  timestampMs: number;
22
22
  requestId?: string;
23
+ sessionId?: string;
23
24
  routeName: string;
24
25
  poolId?: string;
25
26
  providerKey: string;
@@ -36,6 +37,7 @@ export type VirtualRouterHitEventMeta = {
36
37
  };
37
38
  export declare function createVirtualRouterHitRecord(input: {
38
39
  requestId?: string;
40
+ sessionId?: string;
39
41
  routeName: string;
40
42
  poolId?: string;
41
43
  providerKey: string;
@@ -58,6 +60,7 @@ export declare function describeTargetProvider(providerKey: string, fallbackMode
58
60
  providerLabel: string;
59
61
  resolvedModel?: string;
60
62
  };
63
+ export declare function resolveSessionColor(sessionId?: string): string;
61
64
  export declare function buildHitReason(routeUsed: string, providerKey: string, classification: ClassificationResult, features: RoutingFeatures, mode: RoutingInstructionMode | undefined, deps: LoggingDeps): string;
62
65
  export declare function formatVirtualRouterHit(record: VirtualRouterHitRecord): string;
63
66
  export {};
@@ -66,6 +66,7 @@ export function createVirtualRouterHitRecord(input) {
66
66
  ? input.timestampMs
67
67
  : Date.now(),
68
68
  ...(input.requestId ? { requestId: input.requestId } : {}),
69
+ ...(input.sessionId ? { sessionId: input.sessionId } : {}),
69
70
  routeName: input.routeName,
70
71
  ...(input.poolId ? { poolId: input.poolId } : {}),
71
72
  providerKey: input.providerKey,
@@ -156,6 +157,27 @@ function resolveRouteColor(routeName) {
156
157
  };
157
158
  return map[routeName] ?? '\x1b[36m';
158
159
  }
160
+ export function resolveSessionColor(sessionId) {
161
+ const palette = [
162
+ '\x1b[31m',
163
+ '\x1b[32m',
164
+ '\x1b[33m',
165
+ '\x1b[34m',
166
+ '\x1b[35m',
167
+ '\x1b[36m',
168
+ '\x1b[38;5;208m',
169
+ '\x1b[38;5;141m'
170
+ ];
171
+ const normalized = typeof sessionId === 'string' ? sessionId.trim() : '';
172
+ if (!normalized) {
173
+ return '\x1b[36m';
174
+ }
175
+ let hash = 0;
176
+ for (let i = 0; i < normalized.length; i += 1) {
177
+ hash = ((hash * 31) + normalized.charCodeAt(i)) >>> 0;
178
+ }
179
+ return palette[hash % palette.length];
180
+ }
159
181
  function describeContextUsage(providerKey, estimatedTokens, deps) {
160
182
  if (typeof estimatedTokens !== 'number' || !Number.isFinite(estimatedTokens) || estimatedTokens <= 0) {
161
183
  return undefined;
@@ -243,7 +265,7 @@ export function formatVirtualRouterHit(record) {
243
265
  const reset = '\x1b[0m';
244
266
  const timeColor = '\x1b[90m';
245
267
  const stickyColor = '\x1b[33m';
246
- const routeColor = resolveRouteColor(record.routeName);
268
+ const routeColor = resolveSessionColor(record.sessionId);
247
269
  const stopColor = '\x1b[38;5;214m';
248
270
  const prefix = `${prefixColor}[virtual-router-hit]${reset}`;
249
271
  const timeLabel = `${timeColor}${timestamp}${reset}`;
@@ -252,6 +274,8 @@ export function formatVirtualRouterHit(record) {
252
274
  const targetLabel = `${routeLabel} -> ${providerLabel}${resolvedModel ? '.' + resolvedModel : ''}`;
253
275
  const requestId = typeof record.requestId === 'string' ? record.requestId : '';
254
276
  const requestLabel = requestId && !requestId.includes('unknown') ? ` req=${requestId}` : '';
277
+ const sessionId = typeof record.sessionId === 'string' ? record.sessionId.trim() : '';
278
+ const sessionLabel = sessionId ? ` sid=${sessionId}` : '';
255
279
  const stickyText = formatStickyScope(record.stickyScope);
256
280
  const stickyLabel = stickyText ? ` ${stickyColor}[sticky:${stickyText}]${reset}` : '';
257
281
  const reasonLabel = record.hitReason ? ` reason=${record.hitReason}` : '';
@@ -279,7 +303,7 @@ export function formatVirtualRouterHit(record) {
279
303
  }
280
304
  stopLabel = ` ${stopColor}[stopMessage:${parts.join(' ')}]${reset}`;
281
305
  }
282
- return `${prefix} ${timeLabel}${requestLabel} ${routeColor}${targetLabel}${stickyLabel}${reasonLabel}${requestTokenLabel}${penaltyLabel}${stopLabel}${reset}`;
306
+ return `${prefix} ${timeLabel}${requestLabel}${sessionLabel} ${routeColor}${targetLabel}${stickyLabel}${reasonLabel}${requestTokenLabel}${penaltyLabel}${stopLabel}${reset}`;
283
307
  }
284
308
  catch {
285
309
  const now = new Date(record.timestampMs);
@@ -289,6 +313,8 @@ export function formatVirtualRouterHit(record) {
289
313
  const stickyLabel = stickyText ? ` [sticky:${stickyText}]` : '';
290
314
  const requestId = typeof record.requestId === 'string' ? record.requestId : '';
291
315
  const requestLabel = requestId && !requestId.includes('unknown') ? ` req=${requestId}` : '';
316
+ const sessionId = typeof record.sessionId === 'string' ? record.sessionId.trim() : '';
317
+ const sessionLabel = sessionId ? ` sid=${sessionId}` : '';
292
318
  const requestTokenLabel = typeof record.requestTokens === 'number' && Number.isFinite(record.requestTokens)
293
319
  ? ` reqTokens=${Math.max(0, Math.round(record.requestTokens))}`
294
320
  : '';
@@ -303,6 +329,6 @@ export function formatVirtualRouterHit(record) {
303
329
  const left = stop.remaining >= 0 ? String(stop.remaining) : 'n/a';
304
330
  stopLabel = ` [stopMessage:${safeText} mode=${stop.mode} round=${rounds} active=${stop.active ? 'yes' : 'no'} left=${left}]`;
305
331
  }
306
- return `[virtual-router-hit] ${timestamp}${requestLabel} ${routeLabel} -> ${record.providerKey}${record.modelId ? '.' + record.modelId : ''}${stickyLabel}${record.hitReason ? ` reason=${record.hitReason}` : ''}${requestTokenLabel}${penaltyLabel}${stopLabel}`;
332
+ return `[virtual-router-hit] ${timestamp}${requestLabel}${sessionLabel} ${routeLabel} -> ${record.providerKey}${record.modelId ? '.' + record.modelId : ''}${stickyLabel}${record.hitReason ? ` reason=${record.hitReason}` : ''}${requestTokenLabel}${penaltyLabel}${stopLabel}`;
307
333
  }
308
334
  }
@@ -12,7 +12,7 @@ export declare function parseRespInboundFormatEnvelopeWithNative(input: {
12
12
  protocol: string;
13
13
  }): Record<string, unknown>;
14
14
  export declare function validateChatEnvelopeWithNative(chatEnvelope: unknown, options: {
15
- stage: 'req_inbound' | 'req_outbound' | 'resp_inbound' | 'resp_outbound';
16
- direction: 'request' | 'response';
15
+ stage: "req_inbound" | "req_outbound" | "resp_inbound" | "resp_outbound";
16
+ direction: "request" | "response";
17
17
  source?: string;
18
18
  }): void;