@jsonstudio/llms 0.6.3409 → 0.6.3539

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 (82) hide show
  1. package/dist/conversion/codecs/anthropic-openai-codec.d.ts +12 -3
  2. package/dist/conversion/codecs/anthropic-openai-codec.js +32 -92
  3. package/dist/conversion/codecs/gemini-openai-codec.d.ts +6 -5
  4. package/dist/conversion/codecs/gemini-openai-codec.js +48 -685
  5. package/dist/conversion/codecs/openai-openai-codec.d.ts +1 -1
  6. package/dist/conversion/codecs/openai-openai-codec.js +34 -100
  7. package/dist/conversion/codecs/responses-openai-codec.d.ts +1 -1
  8. package/dist/conversion/codecs/responses-openai-codec.js +47 -159
  9. package/dist/conversion/compat/actions/anthropic-claude-code-system-prompt.d.ts +2 -6
  10. package/dist/conversion/compat/actions/anthropic-claude-code-system-prompt.js +29 -245
  11. package/dist/conversion/compat/actions/anthropic-claude-code-user-id.d.ts +3 -0
  12. package/dist/conversion/compat/actions/anthropic-claude-code-user-id.js +30 -0
  13. package/dist/conversion/compat/actions/antigravity-thought-signature-prepare.js +21 -232
  14. package/dist/conversion/compat/actions/deepseek-web-request.js +41 -276
  15. package/dist/conversion/compat/actions/deepseek-web-response.js +64 -859
  16. package/dist/conversion/compat/actions/gemini-cli-request.d.ts +1 -1
  17. package/dist/conversion/compat/actions/gemini-cli-request.js +20 -613
  18. package/dist/conversion/compat/actions/gemini-web-search.d.ts +1 -15
  19. package/dist/conversion/compat/actions/gemini-web-search.js +22 -69
  20. package/dist/conversion/compat/actions/glm-tool-extraction.d.ts +3 -2
  21. package/dist/conversion/compat/actions/glm-tool-extraction.js +28 -257
  22. package/dist/conversion/compat/actions/iflow-tool-text-fallback.d.ts +0 -8
  23. package/dist/conversion/compat/actions/iflow-tool-text-fallback.js +24 -206
  24. package/dist/conversion/compat/actions/qwen-transform.d.ts +3 -2
  25. package/dist/conversion/compat/actions/qwen-transform.js +30 -271
  26. package/dist/conversion/compat/actions/tool-text-request-guidance.js +3 -173
  27. package/dist/conversion/compat/actions/universal-shape-filter.d.ts +6 -23
  28. package/dist/conversion/compat/actions/universal-shape-filter.js +4 -383
  29. package/dist/conversion/hub/pipeline/compat/native-adapter-context.js +1 -0
  30. package/dist/conversion/pipeline/codecs/v2/anthropic-openai-pipeline.d.ts +1 -2
  31. package/dist/conversion/pipeline/codecs/v2/anthropic-openai-pipeline.js +50 -104
  32. package/dist/conversion/pipeline/codecs/v2/openai-openai-pipeline.js +12 -10
  33. package/dist/conversion/pipeline/codecs/v2/responses-openai-pipeline.d.ts +0 -2
  34. package/dist/conversion/pipeline/codecs/v2/responses-openai-pipeline.js +46 -67
  35. package/dist/conversion/pipeline/codecs/v2/shared/openai-chat-helpers.js +15 -40
  36. package/dist/conversion/responses/responses-openai-bridge/response-payload.js +47 -348
  37. package/dist/conversion/responses/responses-openai-bridge.js +129 -611
  38. package/dist/conversion/shared/chat-output-normalizer.js +6 -0
  39. package/dist/conversion/shared/chat-request-filters.js +1 -1
  40. package/dist/conversion/shared/output-content-normalizer.js +10 -0
  41. package/dist/conversion/shared/responses-conversation-store.js +22 -135
  42. package/dist/conversion/shared/responses-output-builder.d.ts +0 -2
  43. package/dist/conversion/shared/responses-output-builder.js +28 -318
  44. package/dist/conversion/shared/responses-response-utils.js +35 -86
  45. package/dist/conversion/shared/streaming-text-extractor.d.ts +1 -2
  46. package/dist/conversion/shared/streaming-text-extractor.js +13 -14
  47. package/dist/native/router_hotpath_napi.node +0 -0
  48. package/dist/router/virtual-router/bootstrap/routing-config.js +11 -3
  49. package/dist/router/virtual-router/engine-legacy.d.ts +3 -3
  50. package/dist/router/virtual-router/engine-legacy.js +15 -7
  51. package/dist/router/virtual-router/engine-selection/native-compat-action-semantics.d.ts +16 -0
  52. package/dist/router/virtual-router/engine-selection/native-compat-action-semantics.js +434 -46
  53. package/dist/router/virtual-router/engine-selection/native-hub-bridge-action-semantics.d.ts +83 -0
  54. package/dist/router/virtual-router/engine-selection/native-hub-bridge-action-semantics.js +295 -0
  55. package/dist/router/virtual-router/engine-selection/native-hub-pipeline-req-outbound-semantics.d.ts +1 -0
  56. package/dist/router/virtual-router/engine-selection/native-hub-pipeline-resp-semantics.d.ts +7 -0
  57. package/dist/router/virtual-router/engine-selection/native-hub-pipeline-resp-semantics.js +8 -1
  58. package/dist/router/virtual-router/engine-selection/native-router-hotpath-loader.js +383 -298
  59. package/dist/router/virtual-router/engine-selection/native-shared-conversion-semantics.d.ts +20 -0
  60. package/dist/router/virtual-router/engine-selection/native-shared-conversion-semantics.js +201 -0
  61. package/dist/router/virtual-router/engine-selection/native-virtual-router-routing-instructions-semantics.d.ts +1 -0
  62. package/dist/router/virtual-router/engine-selection/native-virtual-router-routing-instructions-semantics.js +37 -0
  63. package/dist/router/virtual-router/engine.js +0 -38
  64. package/dist/router/virtual-router/features.js +44 -3
  65. package/dist/router/virtual-router/routing-instructions/parse.d.ts +0 -12
  66. package/dist/router/virtual-router/routing-instructions/parse.js +9 -389
  67. package/dist/router/virtual-router/stop-message-state-sync.d.ts +3 -6
  68. package/dist/router/virtual-router/stop-message-state-sync.js +50 -21
  69. package/dist/sse/sse-to-json/anthropic-sse-to-json-converter.d.ts +1 -0
  70. package/dist/sse/sse-to-json/anthropic-sse-to-json-converter.js +26 -0
  71. package/dist/sse/sse-to-json/builders/anthropic-response-builder.js +12 -2
  72. package/package.json +1 -1
  73. package/dist/router/virtual-router/engine-legacy/route-finalize.d.ts +0 -9
  74. package/dist/router/virtual-router/engine-legacy/route-finalize.js +0 -84
  75. package/dist/router/virtual-router/engine-legacy/route-selection.d.ts +0 -17
  76. package/dist/router/virtual-router/engine-legacy/route-selection.js +0 -205
  77. package/dist/router/virtual-router/engine-legacy/route-state-allowlist.d.ts +0 -3
  78. package/dist/router/virtual-router/engine-legacy/route-state-allowlist.js +0 -36
  79. package/dist/router/virtual-router/engine-legacy/route-state.d.ts +0 -12
  80. package/dist/router/virtual-router/engine-legacy/route-state.js +0 -386
  81. package/dist/router/virtual-router/engine-legacy/routing.d.ts +0 -8
  82. package/dist/router/virtual-router/engine-legacy/routing.js +0 -8
@@ -1,84 +0,0 @@
1
- import { resolveRoutingMode } from '../engine/routing-state/metadata.js';
2
- import { buildHitReason, createVirtualRouterHitRecord, formatVirtualRouterHit, toVirtualRouterHitEvent } from '../engine-logging.js';
3
- import { recordAntigravitySessionLease } from '../engine/antigravity/alias-lease.js';
4
- export function finalizeRoutingDecision(engine, metadata, routingState, metadataInstructions, instructions, selectionResult) {
5
- const { selection, classification, requestedRoute, features } = selectionResult;
6
- const baseTarget = engine.providerRegistry.buildTarget(selection.providerKey);
7
- const forceVision = selection.routeUsed === 'vision' && engine.routeHasForceFlag('vision');
8
- const target = {
9
- ...baseTarget,
10
- ...(engine.webSearchForce ? { forceWebSearch: true } : {}),
11
- ...(forceVision ? { forceVision: true } : {})
12
- };
13
- const instructionProcessMode = engine.resolveInstructionProcessModeForSelection(selection.providerKey, routingState);
14
- if (instructionProcessMode) {
15
- target.processMode = instructionProcessMode;
16
- }
17
- recordAntigravitySessionLease({
18
- metadata: features.metadata,
19
- providerKey: selection.providerKey,
20
- sessionKey: engine.resolveSessionScope(features.metadata),
21
- providerRegistry: engine.providerRegistry,
22
- leaseStore: engine.stickySessionManager.getAllStores().aliasLeaseStore,
23
- sessionAliasStore: engine.stickySessionManager.getAllStores().sessionAliasStore,
24
- persistence: engine.antigravityLeasePersistence,
25
- aliasReuseCooldownMs: engine.stickySessionManager.getAliasReuseCooldownMs(),
26
- commitSessionBinding: false,
27
- debug: engine.debug
28
- });
29
- const routingMode = resolveRoutingMode([...metadataInstructions, ...instructions], routingState);
30
- const hitReason = buildHitReason(selection.routeUsed, selection.providerKey, classification, features, routingMode, { providerRegistry: engine.providerRegistry, contextRouting: engine.contextRouting });
31
- const stickyScope = routingMode !== 'none' ? engine.resolveSessionScope(metadata) : undefined;
32
- const routeForLog = routingMode === 'sticky' ? 'sticky' : selection.routeUsed;
33
- const hitRecord = createVirtualRouterHitRecord({
34
- requestId: metadata.requestId,
35
- routeName: routeForLog,
36
- poolId: selection.poolId,
37
- providerKey: selection.providerKey,
38
- modelId: target.modelId || undefined,
39
- hitReason,
40
- stickyScope,
41
- routingState,
42
- requestTokens: features.estimatedTokens,
43
- selectionPenalty: engine.resolveSelectionPenalty(selection.providerKey)
44
- });
45
- engine.routeAnalytics.incrementRouteStat(selection.routeUsed, selection.providerKey, hitRecord);
46
- try {
47
- engine.statsCenter.recordVirtualRouterHit(toVirtualRouterHitEvent(hitRecord, {
48
- requestId: metadata.requestId,
49
- entryEndpoint: metadata.entryEndpoint || '/v1/chat/completions'
50
- }));
51
- }
52
- catch {
53
- // stats must never break routing
54
- }
55
- const formatted = formatVirtualRouterHit(hitRecord);
56
- if (formatted) {
57
- engine.debug?.log?.(formatted);
58
- }
59
- else {
60
- engine.debug?.log?.(formatVirtualRouterHit(hitRecord));
61
- }
62
- const didFallback = selection.routeUsed !== requestedRoute;
63
- return {
64
- target,
65
- decision: {
66
- routeName: selection.routeUsed,
67
- providerKey: selection.providerKey,
68
- pool: selection.pool,
69
- poolId: selection.poolId,
70
- confidence: classification.confidence,
71
- reasoning: classification.reasoning,
72
- fallback: didFallback
73
- },
74
- diagnostics: {
75
- routeName: selection.routeUsed,
76
- providerKey: selection.providerKey,
77
- pool: selection.pool,
78
- poolId: selection.poolId,
79
- reasoning: classification.reasoning,
80
- fallback: didFallback,
81
- confidence: classification.confidence
82
- }
83
- };
84
- }
@@ -1,17 +0,0 @@
1
- import type { ProcessedRequest, StandardizedRequest } from '../../../conversion/hub/types/standardized.js';
2
- import type { ClassificationResult, RoutingFeatures, RouterMetadataInput } from '../types.js';
3
- import type { RoutingInstructionState } from '../routing-instructions.js';
4
- import type { VirtualRouterEngine } from '../engine-legacy.js';
5
- export type RoutingSelectionResult = {
6
- routingState: RoutingInstructionState;
7
- requestedRoute: string;
8
- classification: ClassificationResult;
9
- selection: {
10
- providerKey: string;
11
- routeUsed: string;
12
- pool: string[];
13
- poolId?: string;
14
- };
15
- features: RoutingFeatures;
16
- };
17
- export declare function selectRoutingTarget(engine: VirtualRouterEngine, request: StandardizedRequest | ProcessedRequest, metadata: RouterMetadataInput, routingState: RoutingInstructionState, stateKey: string): RoutingSelectionResult;
@@ -1,205 +0,0 @@
1
- import { DEFAULT_ROUTE, VirtualRouterError, VirtualRouterErrorCode } from '../types.js';
2
- import { buildRoutingFeatures } from '../features.js';
3
- import { persistRoutingInstructionState } from '../engine/routing-state/store.js';
4
- import { selectDirectProviderModel, selectFromStickyPool as selectFromStickyPoolImpl } from '../engine/routing-pools/index.js';
5
- export function selectRoutingTarget(engine, request, metadata, routingState, stateKey) {
6
- const features = buildRoutingFeatures(request, metadata);
7
- const directProviderModel = engine.parseDirectProviderModel(request?.model);
8
- let classification;
9
- let requestedRoute;
10
- let selection = null;
11
- const selectionDeps = {
12
- routing: engine.routing,
13
- providerRegistry: engine.providerRegistry,
14
- healthManager: engine.healthManager,
15
- contextAdvisor: engine.contextAdvisor,
16
- loadBalancer: engine.loadBalancer,
17
- isProviderCoolingDown: (key) => engine.isProviderCoolingDown(key),
18
- resolveStickyKey: (m) => engine.resolveStickyKey(m),
19
- quotaView: engine.quotaView
20
- };
21
- if (directProviderModel) {
22
- const forceMediaFallback = engine.shouldFallbackDirectModelForMedia(directProviderModel, features);
23
- const providerKeys = engine.providerRegistry.listProviderKeys(directProviderModel.providerId);
24
- let hasModel = false;
25
- for (const key of providerKeys) {
26
- try {
27
- const profile = engine.providerRegistry.get(key);
28
- if (profile?.modelId === directProviderModel.modelId) {
29
- hasModel = true;
30
- break;
31
- }
32
- }
33
- catch {
34
- continue;
35
- }
36
- }
37
- if (!hasModel) {
38
- throw new VirtualRouterError(`Unknown model ${directProviderModel.modelId} for provider ${directProviderModel.providerId}`, VirtualRouterErrorCode.CONFIG_ERROR, { providerId: directProviderModel.providerId, modelId: directProviderModel.modelId });
39
- }
40
- if (!forceMediaFallback) {
41
- const directSelection = selectDirectProviderModel(directProviderModel.providerId, directProviderModel.modelId, metadata, features, routingState, selectionDeps);
42
- if (!directSelection) {
43
- throw new VirtualRouterError(`All providers unavailable for model ${directProviderModel.providerId}.${directProviderModel.modelId}`, VirtualRouterErrorCode.PROVIDER_NOT_AVAILABLE, { providerId: directProviderModel.providerId, modelId: directProviderModel.modelId });
44
- }
45
- classification = {
46
- routeName: 'direct',
47
- confidence: 1,
48
- reasoning: `direct_model:${directProviderModel.providerId}.${directProviderModel.modelId}`,
49
- fallback: false,
50
- candidates: ['direct']
51
- };
52
- requestedRoute = 'direct';
53
- selection = directSelection;
54
- }
55
- else {
56
- classification = engine.classifier.classify(features);
57
- requestedRoute = engine.normalizeRouteAlias(classification.routeName || DEFAULT_ROUTE);
58
- selection = engine.selectProvider(requestedRoute, metadata, classification, features, routingState);
59
- }
60
- }
61
- else {
62
- // Prefer target (from "<**!provider.model**>") is evaluated before routing classification.
63
- const preferTarget = routingState.preferTarget;
64
- if (preferTarget && typeof preferTarget.provider === 'string' && preferTarget.provider.trim()) {
65
- const providerId = preferTarget.provider.trim();
66
- const keyAlias = typeof preferTarget.keyAlias === 'string' ? preferTarget.keyAlias.trim() : '';
67
- const modelId = typeof preferTarget.model === 'string' ? preferTarget.model.trim() : '';
68
- const keyIndex = typeof preferTarget.keyIndex === 'number' && Number.isFinite(preferTarget.keyIndex)
69
- ? Math.floor(preferTarget.keyIndex)
70
- : undefined;
71
- const candidateKeys = [];
72
- if (keyIndex !== undefined && keyIndex > 0) {
73
- const runtimeKey = engine.providerRegistry.resolveRuntimeKeyByIndex(providerId, keyIndex);
74
- if (runtimeKey) {
75
- candidateKeys.push(runtimeKey);
76
- }
77
- }
78
- else if (modelId) {
79
- const allKeys = engine.providerRegistry.listProviderKeys(providerId);
80
- for (const key of allKeys) {
81
- if (keyAlias) {
82
- const prefix = `${providerId}.${keyAlias}.`;
83
- if (!key.startsWith(prefix)) {
84
- continue;
85
- }
86
- }
87
- try {
88
- const profile = engine.providerRegistry.get(key);
89
- if (profile?.modelId === modelId) {
90
- candidateKeys.push(key);
91
- }
92
- }
93
- catch {
94
- continue;
95
- }
96
- }
97
- }
98
- const allowAliasRotation = !keyAlias && keyIndex === undefined;
99
- const eligibleKeys = (() => {
100
- if (candidateKeys.length === 0) {
101
- return [];
102
- }
103
- const quotaView = selectionDeps.quotaView;
104
- const now = quotaView ? Date.now() : 0;
105
- return candidateKeys.filter((key) => {
106
- if (!quotaView) {
107
- if (engine.isProviderCoolingDown(key)) {
108
- return false;
109
- }
110
- if (!engine.healthManager.isAvailable(key)) {
111
- return false;
112
- }
113
- return true;
114
- }
115
- const entry = quotaView(key);
116
- if (!entry) {
117
- return true;
118
- }
119
- if (!entry.inPool) {
120
- return false;
121
- }
122
- if (entry.cooldownUntil && entry.cooldownUntil > now) {
123
- return false;
124
- }
125
- if (entry.blacklistUntil && entry.blacklistUntil > now) {
126
- return false;
127
- }
128
- return true;
129
- });
130
- })();
131
- const preferSelection = eligibleKeys.length > 0
132
- ? selectFromStickyPoolImpl(new Set(eligibleKeys), metadata, features, routingState, selectionDeps, {
133
- allowAliasRotation
134
- })
135
- : null;
136
- if (preferSelection) {
137
- classification = {
138
- routeName: 'prefer',
139
- confidence: 1,
140
- reasoning: keyIndex !== undefined ? `prefer_key:${providerId}.${keyIndex}` : `prefer_model:${providerId}.${modelId}`,
141
- fallback: false,
142
- candidates: ['prefer']
143
- };
144
- requestedRoute = 'prefer';
145
- selection = {
146
- ...preferSelection,
147
- routeUsed: 'prefer',
148
- poolId: 'prefer-primary'
149
- };
150
- }
151
- else if (routingState.preferTarget) {
152
- // Auto-clear only when the target becomes invalid or blocked by explicit routing instructions.
153
- // Do NOT clear for temporary unavailability (e.g. 429 cooldown, quota cooldown, transient health).
154
- const shouldAutoClear = (() => {
155
- if (candidateKeys.length === 0) {
156
- return true;
157
- }
158
- // Prefer selection failed despite eligible keys existing: treat as a hard block (e.g. routing rules).
159
- if (eligibleKeys.length > 0) {
160
- return true;
161
- }
162
- // If quota explicitly marks the preferred target as out-of-pool, clear the prefer instruction so
163
- // the router can fall back to other targets without repeatedly retrying an impossible preference.
164
- if (selectionDeps.quotaView) {
165
- for (const key of candidateKeys) {
166
- const entry = selectionDeps.quotaView(key);
167
- if (entry && entry.inPool === false) {
168
- return true;
169
- }
170
- }
171
- }
172
- return false;
173
- })();
174
- if (shouldAutoClear) {
175
- routingState = {
176
- ...routingState,
177
- preferTarget: undefined
178
- };
179
- engine.routingInstructionState.set(stateKey, routingState);
180
- persistRoutingInstructionState(stateKey, routingState, engine.routingStateStore);
181
- }
182
- }
183
- }
184
- if (!selection) {
185
- classification = metadata.routeHint && metadata.routeHint.trim()
186
- ? {
187
- routeName: metadata.routeHint.trim(),
188
- confidence: 1,
189
- reasoning: `route_hint:${metadata.routeHint.trim()}`,
190
- fallback: false,
191
- candidates: [metadata.routeHint.trim()]
192
- }
193
- : engine.classifier.classify(features);
194
- requestedRoute = engine.normalizeRouteAlias(classification.routeName || DEFAULT_ROUTE);
195
- selection = engine.selectProvider(requestedRoute, metadata, classification, features, routingState);
196
- }
197
- }
198
- return {
199
- routingState,
200
- requestedRoute,
201
- classification: classification,
202
- selection: selection,
203
- features
204
- };
205
- }
@@ -1,3 +0,0 @@
1
- import type { RoutingInstructionState } from '../routing-instructions.js';
2
- import type { VirtualRouterEngine } from '../engine-legacy.js';
3
- export declare function enforceAllowlistIntersection(engine: VirtualRouterEngine, routingState: RoutingInstructionState, stateKey: string): RoutingInstructionState;
@@ -1,36 +0,0 @@
1
- import { extractProviderId } from '../engine/provider-key/parse.js';
2
- import { persistRoutingInstructionState } from '../engine/routing-state/store.js';
3
- export function enforceAllowlistIntersection(engine, routingState, stateKey) {
4
- if (routingState.allowedProviders.size === 0) {
5
- return routingState;
6
- }
7
- const providersInRouting = new Set();
8
- for (const pools of Object.values(engine.routing)) {
9
- if (!Array.isArray(pools))
10
- continue;
11
- for (const pool of pools) {
12
- if (!pool || !Array.isArray(pool.targets))
13
- continue;
14
- for (const key of pool.targets) {
15
- if (typeof key !== 'string' || !key)
16
- continue;
17
- const providerId = extractProviderId(key);
18
- if (providerId) {
19
- providersInRouting.add(providerId);
20
- }
21
- }
22
- }
23
- }
24
- const allowed = Array.from(routingState.allowedProviders).filter((provider) => typeof provider === 'string');
25
- const hasIntersection = allowed.some((provider) => providersInRouting.has(provider));
26
- if (!hasIntersection) {
27
- const nextState = {
28
- ...routingState,
29
- allowedProviders: new Set()
30
- };
31
- engine.routingInstructionState.set(stateKey, nextState);
32
- persistRoutingInstructionState(stateKey, nextState, engine.routingStateStore);
33
- return nextState;
34
- }
35
- return routingState;
36
- }
@@ -1,12 +0,0 @@
1
- import type { ProcessedRequest, StandardizedRequest } from '../../../conversion/hub/types/standardized.js';
2
- import type { RouterMetadataInput } from '../types.js';
3
- import type { RoutingInstruction, RoutingInstructionState } from '../routing-instructions.js';
4
- import type { VirtualRouterEngine } from '../engine-legacy.js';
5
- export type RoutingStateResult = {
6
- routingState: RoutingInstructionState;
7
- stateKey: string;
8
- stopMessageScope?: string;
9
- metadataInstructions: RoutingInstruction[];
10
- instructions: RoutingInstruction[];
11
- };
12
- export declare function buildRoutingState(engine: VirtualRouterEngine, request: StandardizedRequest | ProcessedRequest, metadata: RouterMetadataInput): RoutingStateResult;