@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.
- package/dist/conversion/codecs/anthropic-openai-codec.d.ts +12 -3
- package/dist/conversion/codecs/anthropic-openai-codec.js +32 -92
- package/dist/conversion/codecs/gemini-openai-codec.d.ts +6 -5
- package/dist/conversion/codecs/gemini-openai-codec.js +48 -685
- package/dist/conversion/codecs/openai-openai-codec.d.ts +1 -1
- package/dist/conversion/codecs/openai-openai-codec.js +34 -100
- package/dist/conversion/codecs/responses-openai-codec.d.ts +1 -1
- package/dist/conversion/codecs/responses-openai-codec.js +47 -159
- package/dist/conversion/compat/actions/anthropic-claude-code-system-prompt.d.ts +2 -6
- package/dist/conversion/compat/actions/anthropic-claude-code-system-prompt.js +29 -245
- package/dist/conversion/compat/actions/anthropic-claude-code-user-id.d.ts +3 -0
- package/dist/conversion/compat/actions/anthropic-claude-code-user-id.js +30 -0
- package/dist/conversion/compat/actions/antigravity-thought-signature-prepare.js +21 -232
- package/dist/conversion/compat/actions/deepseek-web-request.js +41 -276
- package/dist/conversion/compat/actions/deepseek-web-response.js +64 -859
- package/dist/conversion/compat/actions/gemini-cli-request.d.ts +1 -1
- package/dist/conversion/compat/actions/gemini-cli-request.js +20 -613
- package/dist/conversion/compat/actions/gemini-web-search.d.ts +1 -15
- package/dist/conversion/compat/actions/gemini-web-search.js +22 -69
- package/dist/conversion/compat/actions/glm-tool-extraction.d.ts +3 -2
- package/dist/conversion/compat/actions/glm-tool-extraction.js +28 -257
- package/dist/conversion/compat/actions/iflow-tool-text-fallback.d.ts +0 -8
- package/dist/conversion/compat/actions/iflow-tool-text-fallback.js +24 -206
- package/dist/conversion/compat/actions/qwen-transform.d.ts +3 -2
- package/dist/conversion/compat/actions/qwen-transform.js +30 -271
- package/dist/conversion/compat/actions/tool-text-request-guidance.js +3 -173
- package/dist/conversion/compat/actions/universal-shape-filter.d.ts +6 -23
- package/dist/conversion/compat/actions/universal-shape-filter.js +4 -383
- package/dist/conversion/hub/pipeline/compat/native-adapter-context.js +1 -0
- package/dist/conversion/pipeline/codecs/v2/anthropic-openai-pipeline.d.ts +1 -2
- package/dist/conversion/pipeline/codecs/v2/anthropic-openai-pipeline.js +50 -104
- package/dist/conversion/pipeline/codecs/v2/openai-openai-pipeline.js +12 -10
- package/dist/conversion/pipeline/codecs/v2/responses-openai-pipeline.d.ts +0 -2
- package/dist/conversion/pipeline/codecs/v2/responses-openai-pipeline.js +46 -67
- package/dist/conversion/pipeline/codecs/v2/shared/openai-chat-helpers.js +15 -40
- package/dist/conversion/responses/responses-openai-bridge/response-payload.js +47 -348
- package/dist/conversion/responses/responses-openai-bridge.js +129 -611
- package/dist/conversion/shared/chat-output-normalizer.js +6 -0
- package/dist/conversion/shared/chat-request-filters.js +1 -1
- package/dist/conversion/shared/output-content-normalizer.js +10 -0
- package/dist/conversion/shared/responses-conversation-store.js +22 -135
- package/dist/conversion/shared/responses-output-builder.d.ts +0 -2
- package/dist/conversion/shared/responses-output-builder.js +28 -318
- package/dist/conversion/shared/responses-response-utils.js +35 -86
- package/dist/conversion/shared/streaming-text-extractor.d.ts +1 -2
- package/dist/conversion/shared/streaming-text-extractor.js +13 -14
- package/dist/native/router_hotpath_napi.node +0 -0
- package/dist/router/virtual-router/bootstrap/routing-config.js +11 -3
- package/dist/router/virtual-router/engine-legacy.d.ts +3 -3
- package/dist/router/virtual-router/engine-legacy.js +15 -7
- package/dist/router/virtual-router/engine-selection/native-compat-action-semantics.d.ts +16 -0
- package/dist/router/virtual-router/engine-selection/native-compat-action-semantics.js +434 -46
- package/dist/router/virtual-router/engine-selection/native-hub-bridge-action-semantics.d.ts +83 -0
- package/dist/router/virtual-router/engine-selection/native-hub-bridge-action-semantics.js +295 -0
- package/dist/router/virtual-router/engine-selection/native-hub-pipeline-req-outbound-semantics.d.ts +1 -0
- package/dist/router/virtual-router/engine-selection/native-hub-pipeline-resp-semantics.d.ts +7 -0
- package/dist/router/virtual-router/engine-selection/native-hub-pipeline-resp-semantics.js +8 -1
- package/dist/router/virtual-router/engine-selection/native-router-hotpath-loader.js +383 -298
- package/dist/router/virtual-router/engine-selection/native-shared-conversion-semantics.d.ts +20 -0
- package/dist/router/virtual-router/engine-selection/native-shared-conversion-semantics.js +201 -0
- package/dist/router/virtual-router/engine-selection/native-virtual-router-routing-instructions-semantics.d.ts +1 -0
- package/dist/router/virtual-router/engine-selection/native-virtual-router-routing-instructions-semantics.js +37 -0
- package/dist/router/virtual-router/engine.js +0 -38
- package/dist/router/virtual-router/features.js +44 -3
- package/dist/router/virtual-router/routing-instructions/parse.d.ts +0 -12
- package/dist/router/virtual-router/routing-instructions/parse.js +9 -389
- package/dist/router/virtual-router/stop-message-state-sync.d.ts +3 -6
- package/dist/router/virtual-router/stop-message-state-sync.js +50 -21
- package/dist/sse/sse-to-json/anthropic-sse-to-json-converter.d.ts +1 -0
- package/dist/sse/sse-to-json/anthropic-sse-to-json-converter.js +26 -0
- package/dist/sse/sse-to-json/builders/anthropic-response-builder.js +12 -2
- package/package.json +1 -1
- package/dist/router/virtual-router/engine-legacy/route-finalize.d.ts +0 -9
- package/dist/router/virtual-router/engine-legacy/route-finalize.js +0 -84
- package/dist/router/virtual-router/engine-legacy/route-selection.d.ts +0 -17
- package/dist/router/virtual-router/engine-legacy/route-selection.js +0 -205
- package/dist/router/virtual-router/engine-legacy/route-state-allowlist.d.ts +0 -3
- package/dist/router/virtual-router/engine-legacy/route-state-allowlist.js +0 -36
- package/dist/router/virtual-router/engine-legacy/route-state.d.ts +0 -12
- package/dist/router/virtual-router/engine-legacy/route-state.js +0 -386
- package/dist/router/virtual-router/engine-legacy/routing.d.ts +0 -8
- 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;
|