@sentropic/llm-mesh 0.13.0 → 0.14.0

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 (100) hide show
  1. package/README.md +105 -6
  2. package/dist/account-transports.d.ts +14 -1
  3. package/dist/account-transports.d.ts.map +1 -1
  4. package/dist/account-transports.js +37 -3
  5. package/dist/account-transports.js.map +1 -1
  6. package/dist/codex.d.ts +43 -0
  7. package/dist/codex.d.ts.map +1 -0
  8. package/dist/codex.js +62 -0
  9. package/dist/codex.js.map +1 -0
  10. package/dist/enrollment/cloud-code.d.ts +6 -1
  11. package/dist/enrollment/cloud-code.d.ts.map +1 -1
  12. package/dist/enrollment/cloud-code.js +53 -25
  13. package/dist/enrollment/cloud-code.js.map +1 -1
  14. package/dist/enrollment/codex.d.ts +1 -0
  15. package/dist/enrollment/codex.d.ts.map +1 -1
  16. package/dist/enrollment/codex.js +1 -0
  17. package/dist/enrollment/codex.js.map +1 -1
  18. package/dist/enrollment/contracts.d.ts +10 -0
  19. package/dist/enrollment/contracts.d.ts.map +1 -1
  20. package/dist/equivalence-council.d.ts +61 -0
  21. package/dist/equivalence-council.d.ts.map +1 -0
  22. package/dist/equivalence-council.js +119 -0
  23. package/dist/equivalence-council.js.map +1 -0
  24. package/dist/generated-model-council.d.ts +10 -0
  25. package/dist/generated-model-council.d.ts.map +1 -0
  26. package/dist/generated-model-council.js +32 -0
  27. package/dist/generated-model-council.js.map +1 -0
  28. package/dist/generation.d.ts +3 -0
  29. package/dist/generation.d.ts.map +1 -1
  30. package/dist/index.d.ts +9 -0
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +9 -0
  33. package/dist/index.js.map +1 -1
  34. package/dist/messages.d.ts +8 -1
  35. package/dist/messages.d.ts.map +1 -1
  36. package/dist/node/index.d.ts +1 -0
  37. package/dist/node/index.d.ts.map +1 -1
  38. package/dist/node/index.js +1 -0
  39. package/dist/node/index.js.map +1 -1
  40. package/dist/node/keyring/encrypted-file-keyring.d.ts +13 -0
  41. package/dist/node/keyring/encrypted-file-keyring.d.ts.map +1 -0
  42. package/dist/node/keyring/encrypted-file-keyring.js +134 -0
  43. package/dist/node/keyring/encrypted-file-keyring.js.map +1 -0
  44. package/dist/route-attempt.d.ts +18 -0
  45. package/dist/route-attempt.d.ts.map +1 -0
  46. package/dist/route-attempt.js +70 -0
  47. package/dist/route-attempt.js.map +1 -0
  48. package/dist/route-health.d.ts +14 -0
  49. package/dist/route-health.d.ts.map +1 -0
  50. package/dist/route-health.js +69 -0
  51. package/dist/route-health.js.map +1 -0
  52. package/dist/route-planner-state.d.ts +37 -0
  53. package/dist/route-planner-state.d.ts.map +1 -0
  54. package/dist/route-planner-state.js +27 -0
  55. package/dist/route-planner-state.js.map +1 -0
  56. package/dist/route-planner.d.ts +48 -0
  57. package/dist/route-planner.d.ts.map +1 -0
  58. package/dist/route-planner.js +327 -0
  59. package/dist/route-planner.js.map +1 -0
  60. package/dist/route-selection.d.ts +17 -0
  61. package/dist/route-selection.d.ts.map +1 -0
  62. package/dist/route-selection.js +127 -0
  63. package/dist/route-selection.js.map +1 -0
  64. package/dist/routing-contracts.d.ts +130 -0
  65. package/dist/routing-contracts.d.ts.map +1 -0
  66. package/dist/routing-contracts.js +2 -0
  67. package/dist/routing-contracts.js.map +1 -0
  68. package/dist/routing-policy.d.ts +68 -0
  69. package/dist/routing-policy.d.ts.map +1 -0
  70. package/dist/routing-policy.js +93 -0
  71. package/dist/routing-policy.js.map +1 -0
  72. package/dist/routing-targets.d.ts +25 -0
  73. package/dist/routing-targets.d.ts.map +1 -0
  74. package/dist/routing-targets.js +48 -0
  75. package/dist/routing-targets.js.map +1 -0
  76. package/dist/service/facade.d.ts +31 -0
  77. package/dist/service/facade.d.ts.map +1 -1
  78. package/dist/service/facade.js +11 -2
  79. package/dist/service/facade.js.map +1 -1
  80. package/dist/service/local-account-transport-service.d.ts +15 -2
  81. package/dist/service/local-account-transport-service.d.ts.map +1 -1
  82. package/dist/service/local-account-transport-service.js +279 -17
  83. package/dist/service/local-account-transport-service.js.map +1 -1
  84. package/dist/transport/cloud-code-runtime-client.d.ts +22 -0
  85. package/dist/transport/cloud-code-runtime-client.d.ts.map +1 -0
  86. package/dist/transport/cloud-code-runtime-client.js +306 -0
  87. package/dist/transport/cloud-code-runtime-client.js.map +1 -0
  88. package/dist/transport/cloud-code-transport.d.ts +3 -0
  89. package/dist/transport/cloud-code-transport.d.ts.map +1 -1
  90. package/dist/transport/cloud-code-transport.js +39 -10
  91. package/dist/transport/cloud-code-transport.js.map +1 -1
  92. package/dist/transport/codex-runtime-client.d.ts +17 -0
  93. package/dist/transport/codex-runtime-client.d.ts.map +1 -0
  94. package/dist/transport/codex-runtime-client.js +121 -0
  95. package/dist/transport/codex-runtime-client.js.map +1 -0
  96. package/dist/transport/codex-runtime-wire.d.ts +5 -0
  97. package/dist/transport/codex-runtime-wire.d.ts.map +1 -0
  98. package/dist/transport/codex-runtime-wire.js +144 -0
  99. package/dist/transport/codex-runtime-wire.js.map +1 -0
  100. package/package.json +1 -1
@@ -0,0 +1,327 @@
1
+ import { DEFAULT_MODEL_EQUIVALENCE_COUNCIL } from './equivalence-council.js';
2
+ import { prepareStoredRouteAttempt } from './route-attempt.js';
3
+ import { InMemoryRouteHealth } from './route-health.js';
4
+ import { affinityRef, mergeRoutePolicy, RoutePlanError, SequentialIdFactory, routingOwnerRef, subjectRef, } from './route-planner-state.js';
5
+ import { selectRouteCandidates } from './route-selection.js';
6
+ import { DEFAULT_ROUTE_POLICY, InMemoryRoutePolicyProfiles, resolveRoutePolicy, resolveRouteStrategy, validateRoutePolicy, } from './routing-policy.js';
7
+ export class InMemoryRoutePlanner {
8
+ options;
9
+ plans = new Map();
10
+ affinities = new Map();
11
+ roundRobin = new Map();
12
+ clock;
13
+ ids;
14
+ council;
15
+ profiles;
16
+ health;
17
+ planTtlMs;
18
+ maximumPlanEntries;
19
+ maximumAffinityEntries;
20
+ maximumRoundRobinEntries;
21
+ constructor(options) {
22
+ this.options = options;
23
+ this.clock = options.clock ?? { now: () => new Date() };
24
+ this.ids = options.idFactory ?? new SequentialIdFactory();
25
+ this.council = options.council ?? DEFAULT_MODEL_EQUIVALENCE_COUNCIL;
26
+ this.profiles = options.profiles ?? new InMemoryRoutePolicyProfiles();
27
+ this.health = new InMemoryRouteHealth(this.clock);
28
+ this.planTtlMs = options.planTtlMs ?? 30_000;
29
+ this.maximumPlanEntries = Math.max(1, options.maximumPlanEntries ?? 1_000);
30
+ this.maximumAffinityEntries = Math.max(1, options.maximumAffinityEntries ?? 10_000);
31
+ this.maximumRoundRobinEntries = Math.max(this.maximumPlanEntries, options.maximumRoundRobinEntries ?? 10_000);
32
+ }
33
+ async listModels(subject) {
34
+ const accounts = await this.options.directory.listEligible(subject);
35
+ const inventory = new Map();
36
+ for (const account of accounts) {
37
+ if (account.readiness !== 'ready')
38
+ continue;
39
+ for (const modelId of account.supportedModelIds) {
40
+ const key = `${account.targetProviderId}\u001f${modelId}`;
41
+ inventory.set(key, { modelId, providerId: account.targetProviderId });
42
+ }
43
+ }
44
+ return [...inventory.values()].sort((left, right) => left.modelId.localeCompare(right.modelId)
45
+ || left.providerId.localeCompare(right.providerId));
46
+ }
47
+ async plan(subject, input) {
48
+ this.evictPlans();
49
+ const profile = input.policyProfile
50
+ ? this.profiles.list().find((entry) => entry.name === input.policyProfile)
51
+ : this.profiles.active();
52
+ if (input.policyProfile && !profile)
53
+ throw new RoutePlanError('Unknown policy profile', 'no-route');
54
+ const policy = resolveRoutePolicy(mergeRoutePolicy(profile?.policy ?? DEFAULT_ROUTE_POLICY, input.policyOverride), input);
55
+ validateRoutePolicy(policy);
56
+ const strategy = resolveRouteStrategy(policy, input);
57
+ const affinity = input.affinityKey
58
+ ? this.affinities.get(affinityRef(subject, input.affinityKey, input.workspaceId))
59
+ : undefined;
60
+ const accounts = await this.options.directory.listEligible(subject);
61
+ const roundRobinKey = `${routingOwnerRef(subject)}\u001f${input.requestedModel}`;
62
+ const roundRobinState = strategy.kind === 'round-robin'
63
+ ? this.roundRobin.get(roundRobinKey)
64
+ : undefined;
65
+ const roundRobinOffset = roundRobinState
66
+ ? roundRobinState.committedOffset + roundRobinState.reservations.size
67
+ : 0;
68
+ let candidates = [...selectRouteCandidates({
69
+ request: input, policy, council: this.council, accounts,
70
+ roundRobinOffset,
71
+ now: this.clock.now(),
72
+ applyAttemptLimit: false,
73
+ })];
74
+ if (affinity && policy.stickyAccount) {
75
+ const account = accounts.find((entry) => entry.accountRef === affinity.accountRef);
76
+ if (!account || account.readiness !== 'ready') {
77
+ candidates = [];
78
+ }
79
+ else {
80
+ const sameAccount = candidates.filter((candidate) => candidate.account.accountRef === affinity.accountRef
81
+ && !this.isAffinityTarget(candidate, affinity));
82
+ const rotated = policy.rotateEquivalentAccounts
83
+ ? candidates.filter((candidate) => candidate.account.accountRef !== affinity.accountRef)
84
+ : [];
85
+ const sticky = {
86
+ account,
87
+ target: { ...affinity.target, requestedModel: input.requestedModel, reason: 'sticky' },
88
+ };
89
+ candidates = [sticky, ...sameAccount, ...rotated]
90
+ .filter((candidate) => !this.health.isSuppressed(candidate))
91
+ .slice(0, policy.maxAttempts);
92
+ }
93
+ }
94
+ else {
95
+ candidates = candidates
96
+ .filter((candidate) => !this.health.isSuppressed(candidate))
97
+ .slice(0, policy.maxAttempts);
98
+ }
99
+ if (candidates.length === 0) {
100
+ const diagnostic = (await this.options.directory.listDiagnostics?.(subject))?.[0];
101
+ throw new RoutePlanError(diagnostic?.message ?? 'No eligible route', 'no-route', diagnostic);
102
+ }
103
+ const planRef = this.ids.next('plan');
104
+ const storedCandidates = candidates.map((candidate) => ({
105
+ ...candidate, candidateRef: this.ids.next('candidate'),
106
+ }));
107
+ const plan = {
108
+ planRef,
109
+ expiresAt: new Date(this.clock.now().getTime() + this.planTtlMs).toISOString(),
110
+ candidateRefs: storedCandidates.map((candidate) => candidate.candidateRef),
111
+ policy,
112
+ councilRevision: this.council.revision,
113
+ diagnostics: storedCandidates.map((candidate) => ({
114
+ candidateRef: candidate.candidateRef,
115
+ diagnosticAccountRef: candidate.account.diagnosticAccountRef,
116
+ requestedModel: input.requestedModel,
117
+ actualProviderId: candidate.target.providerId,
118
+ actualModelId: candidate.target.modelId,
119
+ actualTransportProviderId: candidate.target.transportProviderId,
120
+ reason: candidate.target.reason,
121
+ cacheContinuityRisk: Boolean(affinity && affinity.accountRef !== candidate.account.accountRef),
122
+ })),
123
+ };
124
+ this.plans.set(planRef, {
125
+ plan, subjectRef: subjectRef(subject), candidates: storedCandidates, policy,
126
+ hadAffinity: Boolean(affinity),
127
+ ...(affinity ? { affinityRevision: affinity.revision } : {}),
128
+ ...(profile ? {
129
+ policyProfileName: profile.name,
130
+ policyProfileRevision: profile.revision,
131
+ } : {}),
132
+ ...(input.affinityKey
133
+ ? { affinityRef: affinityRef(subject, input.affinityKey, input.workspaceId) }
134
+ : {}),
135
+ claimedAttempts: new Set(),
136
+ ...(strategy.kind === 'round-robin' && !affinity ? { roundRobinKey } : {}),
137
+ });
138
+ if (strategy.kind === 'round-robin' && !affinity) {
139
+ const state = this.roundRobin.get(roundRobinKey) ?? {
140
+ committedOffset: 0,
141
+ reservations: new Set(),
142
+ };
143
+ state.reservations.add(planRef);
144
+ this.touchRoundRobin(roundRobinKey, state);
145
+ }
146
+ this.trimPlans();
147
+ return plan;
148
+ }
149
+ async prepareAttempt(subject, planRef, candidateRef, requestId, attemptIndex) {
150
+ const stored = this.plans.get(planRef);
151
+ if (stored?.plan.councilRevision !== this.council.revision) {
152
+ throw new RoutePlanError('Route council revision changed', 'invalid-plan');
153
+ }
154
+ if (stored?.affinityRef && stored.affinityRevision !== undefined
155
+ && this.affinities.get(stored.affinityRef)?.revision !== stored.affinityRevision) {
156
+ throw new RoutePlanError('Route affinity revision changed', 'conflict');
157
+ }
158
+ if (stored?.policyProfileName && this.profiles.list().find((profile) => profile.name === stored.policyProfileName)?.revision !== stored.policyProfileRevision) {
159
+ throw new RoutePlanError('Route policy revision changed', 'invalid-plan');
160
+ }
161
+ try {
162
+ return await prepareStoredRouteAttempt({
163
+ stored, subject, planRef, candidateRef, requestId, attemptIndex,
164
+ directory: this.options.directory, clock: this.clock,
165
+ onOutcome: (activePlan, candidate, failure) => {
166
+ this.health.record(candidate, failure, activePlan.policy);
167
+ const terminalCandidate = activePlan.candidates.at(-1) === candidate;
168
+ if (!failure.retryable || terminalCandidate)
169
+ this.releaseRoundRobin(activePlan);
170
+ },
171
+ onCommitted: (activePlan, candidate) => this.bind(activePlan, candidate),
172
+ onSuccess: (activePlan, candidate) => {
173
+ this.health.clear(candidate);
174
+ this.bind(activePlan, candidate);
175
+ },
176
+ onCancelled: (activePlan) => this.releaseRoundRobin(activePlan),
177
+ });
178
+ }
179
+ catch (error) {
180
+ if (stored && attemptIndex + 1 >= stored.candidates.length) {
181
+ this.releaseRoundRobin(stored);
182
+ }
183
+ throw error;
184
+ }
185
+ }
186
+ describeAffinity(subject, key, workspaceId) {
187
+ return this.affinities.get(affinityRef(subject, key, workspaceId)) ?? null;
188
+ }
189
+ promoteAffinity(subject, planRef, candidateRef, expectedRevision) {
190
+ return this.mutateAffinity(subject, planRef, candidateRef, false, expectedRevision);
191
+ }
192
+ rebindAffinity(subject, planRef, candidateRef, expectedRevision) {
193
+ return this.mutateAffinity(subject, planRef, candidateRef, true, expectedRevision);
194
+ }
195
+ resetAffinity(subject, key, expectedRevision, workspaceId) {
196
+ const ref = affinityRef(subject, key, workspaceId);
197
+ const current = this.affinities.get(ref);
198
+ if (!current)
199
+ return false;
200
+ if (expectedRevision !== undefined && current.revision !== expectedRevision) {
201
+ throw new RoutePlanError('Affinity revision changed', 'conflict');
202
+ }
203
+ const removed = this.affinities.delete(ref);
204
+ if (removed)
205
+ this.options.affinityAudit?.({
206
+ operation: 'reset', subjectRef: subjectRef(subject), affinityRef: ref,
207
+ previousRevision: current.revision, cacheContinuityRisk: false,
208
+ });
209
+ return removed;
210
+ }
211
+ mutateAffinity(subject, planRef, candidateRef, allowRebind, expectedRevision) {
212
+ const stored = this.plans.get(planRef);
213
+ if (!stored || stored.subjectRef !== subjectRef(subject) || !stored.affinityRef) {
214
+ throw new RoutePlanError('Invalid affinity plan', 'invalid-plan');
215
+ }
216
+ const candidate = stored.candidates.find((entry) => entry.candidateRef === candidateRef);
217
+ const current = this.affinities.get(stored.affinityRef);
218
+ if (!candidate || !current)
219
+ throw new RoutePlanError('Affinity candidate missing', 'invalid-plan');
220
+ if (expectedRevision !== undefined && current.revision !== expectedRevision) {
221
+ throw new RoutePlanError('Affinity revision changed', 'conflict');
222
+ }
223
+ const rebind = current.accountRef !== candidate.account.accountRef;
224
+ if (rebind && !allowRebind)
225
+ throw new RoutePlanError('Promotion cannot change account', 'conflict');
226
+ const next = {
227
+ ...current, accountRef: candidate.account.accountRef,
228
+ diagnosticAccountRef: candidate.account.diagnosticAccountRef,
229
+ target: candidate.target, revision: current.revision + 1, promoted: !rebind,
230
+ };
231
+ this.affinities.set(stored.affinityRef, next);
232
+ this.trim(this.affinities, this.maximumAffinityEntries);
233
+ this.options.affinityAudit?.({
234
+ operation: rebind ? 'rebind' : 'promote', subjectRef: subjectRef(subject),
235
+ affinityRef: stored.affinityRef, previousRevision: current.revision,
236
+ nextRevision: next.revision, cacheContinuityRisk: rebind,
237
+ });
238
+ return next;
239
+ }
240
+ bind(stored, candidate) {
241
+ this.commitRoundRobin(stored);
242
+ if (!stored.affinityRef)
243
+ return;
244
+ const current = this.affinities.get(stored.affinityRef);
245
+ if (current && stored.policy.fallbackMode !== 'one-way')
246
+ return;
247
+ if (current?.target.providerId === candidate.target.providerId
248
+ && current.target.modelId === candidate.target.modelId
249
+ && current.target.transportProviderId === candidate.target.transportProviderId)
250
+ return;
251
+ const rebind = Boolean(current && current.accountRef !== candidate.account.accountRef);
252
+ const next = {
253
+ affinityRef: stored.affinityRef, accountRef: candidate.account.accountRef,
254
+ diagnosticAccountRef: candidate.account.diagnosticAccountRef,
255
+ target: candidate.target, revision: (current?.revision ?? 0) + 1,
256
+ promoted: Boolean(current && !rebind),
257
+ };
258
+ this.affinities.set(stored.affinityRef, next);
259
+ this.trim(this.affinities, this.maximumAffinityEntries);
260
+ if (current)
261
+ this.options.affinityAudit?.({
262
+ operation: rebind ? 'rebind' : 'promote', subjectRef: stored.subjectRef,
263
+ affinityRef: stored.affinityRef, previousRevision: current.revision,
264
+ nextRevision: next.revision, cacheContinuityRisk: rebind,
265
+ });
266
+ }
267
+ isAffinityTarget(candidate, affinity) {
268
+ return candidate.target.providerId === affinity.target.providerId
269
+ && candidate.target.modelId === affinity.target.modelId
270
+ && candidate.target.transportProviderId === affinity.target.transportProviderId;
271
+ }
272
+ evictPlans() {
273
+ const now = this.clock.now().getTime();
274
+ for (const [ref, stored] of this.plans) {
275
+ if (Date.parse(stored.plan.expiresAt) <= now) {
276
+ this.releaseRoundRobin(stored);
277
+ this.plans.delete(ref);
278
+ }
279
+ }
280
+ }
281
+ commitRoundRobin(stored) {
282
+ if (!stored.roundRobinKey)
283
+ return;
284
+ const state = this.roundRobin.get(stored.roundRobinKey);
285
+ if (!state?.reservations.delete(stored.plan.planRef))
286
+ return;
287
+ state.committedOffset += 1;
288
+ this.touchRoundRobin(stored.roundRobinKey, state);
289
+ }
290
+ releaseRoundRobin(stored) {
291
+ if (!stored.roundRobinKey)
292
+ return;
293
+ const state = this.roundRobin.get(stored.roundRobinKey);
294
+ if (!state)
295
+ return;
296
+ state.reservations.delete(stored.plan.planRef);
297
+ this.touchRoundRobin(stored.roundRobinKey, state);
298
+ }
299
+ touchRoundRobin(key, state) {
300
+ this.roundRobin.delete(key);
301
+ this.roundRobin.set(key, state);
302
+ while (this.roundRobin.size > this.maximumRoundRobinEntries) {
303
+ const removable = [...this.roundRobin].find(([, candidate]) => candidate.reservations.size === 0);
304
+ if (!removable)
305
+ break;
306
+ this.roundRobin.delete(removable[0]);
307
+ }
308
+ }
309
+ trimPlans() {
310
+ while (this.plans.size > this.maximumPlanEntries) {
311
+ const oldest = this.plans.entries().next().value;
312
+ if (!oldest)
313
+ break;
314
+ this.releaseRoundRobin(oldest[1]);
315
+ this.plans.delete(oldest[0]);
316
+ }
317
+ }
318
+ trim(entries, maximum) {
319
+ while (entries.size > maximum) {
320
+ const oldest = entries.keys().next().value;
321
+ if (!oldest)
322
+ break;
323
+ entries.delete(oldest);
324
+ }
325
+ }
326
+ }
327
+ //# sourceMappingURL=route-planner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-planner.js","sourceRoot":"","sources":["../src/route-planner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import { type ModelEquivalenceCouncil } from './equivalence-council.js';
2
+ import type { EligibleAccountDescriptor, PlannedRouteTarget, RoutePlanInput } from './routing-contracts.js';
3
+ import { type RoutePolicy } from './routing-policy.js';
4
+ export interface RankedRouteCandidate {
5
+ readonly account: EligibleAccountDescriptor;
6
+ readonly target: PlannedRouteTarget;
7
+ }
8
+ export declare const selectRouteCandidates: (input: {
9
+ readonly request: RoutePlanInput;
10
+ readonly policy: RoutePolicy;
11
+ readonly council: ModelEquivalenceCouncil;
12
+ readonly accounts: readonly EligibleAccountDescriptor[];
13
+ readonly roundRobinOffset?: number;
14
+ readonly now?: Date;
15
+ readonly applyAttemptLimit?: boolean;
16
+ }) => readonly RankedRouteCandidate[];
17
+ //# sourceMappingURL=route-selection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-selection.d.ts","sourceRoot":"","sources":["../src/route-selection.ts"],"names":[],"mappings":"AACA,OAAO,EAA2B,KAAK,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AACjG,OAAO,KAAK,EAAE,yBAAyB,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC5G,OAAO,EAAwB,KAAK,WAAW,EAAsB,MAAM,qBAAqB,CAAC;AAEjG,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,OAAO,EAAE,yBAAyB,CAAC;IAC5C,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAC;CACrC;AA8CD,eAAO,MAAM,qBAAqB,UAAW;IAC3C,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;IACjC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,uBAAuB,CAAC;IAC1C,QAAQ,CAAC,QAAQ,EAAE,SAAS,yBAAyB,EAAE,CAAC;IACxD,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC;IACpB,QAAQ,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAC;CACtC,KAAG,SAAS,oBAAoB,EAyGhC,CAAC"}
@@ -0,0 +1,127 @@
1
+ import { modelProfiles } from './catalog.js';
2
+ import { modelSupportsCapability } from './equivalence-council.js';
3
+ import { resolveRouteStrategy } from './routing-policy.js';
4
+ import { createCanonicalTargetResolver } from './routing-targets.js';
5
+ const resolveCanonical = createCanonicalTargetResolver();
6
+ const supportsCapabilities = (profile, required) => !required?.length
7
+ || required.every((capability) => modelSupportsCapability(profile, capability));
8
+ const selectorMatches = (selector, candidate, requestedModel) => (!selector.providerId || selector.providerId === candidate.target.providerId)
9
+ && (!selector.modelId || selector.modelId === candidate.target.modelId)
10
+ && (!selector.alias || selector.alias === requestedModel)
11
+ && (!selector.transportProviderId
12
+ || selector.transportProviderId === candidate.target.transportProviderId)
13
+ && (!selector.diagnosticAccountRef
14
+ || selector.diagnosticAccountRef === candidate.account.diagnosticAccountRef);
15
+ const resolveRequestedTarget = (requestedModel) => {
16
+ const canonical = resolveCanonical(requestedModel);
17
+ if (canonical)
18
+ return { ...canonical, reason: requestedModel === canonical.model ? 'exact' : 'alias' };
19
+ const profile = modelProfiles.find((candidate) => candidate.modelId === requestedModel);
20
+ return profile ? {
21
+ providerId: profile.providerId,
22
+ model: profile.modelId,
23
+ reason: 'exact',
24
+ } : undefined;
25
+ };
26
+ export const selectRouteCandidates = (input) => {
27
+ const resolved = resolveRequestedTarget(input.request.requestedModel);
28
+ if (!resolved)
29
+ return [];
30
+ const requestedProfile = modelProfiles.find((profile) => profile.providerId === resolved.providerId && profile.modelId === resolved.model);
31
+ if (!supportsCapabilities(requestedProfile, input.request.requiredCapabilities))
32
+ return [];
33
+ const targets = [{
34
+ providerId: resolved.providerId,
35
+ modelId: resolved.model,
36
+ ...(resolved.effort ? { effort: resolved.effort } : {}),
37
+ ...(resolved.transportProviderId
38
+ ? { transportProviderId: resolved.transportProviderId }
39
+ : {}),
40
+ reason: resolved.reason,
41
+ }];
42
+ if (input.policy.allowEquivalentModels) {
43
+ const now = (input.now ?? new Date()).getTime();
44
+ const group = input.council.groups.find((candidate) => Date.parse(candidate.expiresAt) > now
45
+ && candidate.evidence.length > 0
46
+ && candidate.members.some((member) => member.providerId === resolved.providerId && member.modelId === resolved.model));
47
+ group?.members.filter((member) => member.providerId !== resolved.providerId || member.modelId !== resolved.model)
48
+ .sort((left, right) => left.rank - right.rank)
49
+ .forEach((member) => targets.push({
50
+ providerId: member.providerId,
51
+ modelId: member.modelId,
52
+ ...(member.effort ? { effort: member.effort } : {}),
53
+ ...(member.transportPreferences
54
+ ? { transportPreferences: member.transportPreferences }
55
+ : {}),
56
+ reason: 'equivalent',
57
+ }));
58
+ }
59
+ let candidates = targets.flatMap((target) => {
60
+ const targetProfile = modelProfiles.find((profile) => profile.providerId === target.providerId && profile.modelId === target.modelId);
61
+ if (!supportsCapabilities(targetProfile, input.request.requiredCapabilities))
62
+ return [];
63
+ return input.accounts
64
+ .filter((account) => account.readiness === 'ready'
65
+ && account.targetProviderId === target.providerId
66
+ && account.supportedModelIds.includes(target.modelId)
67
+ && (!target.transportProviderId
68
+ || target.transportProviderId === account.transportProviderId))
69
+ .map((account) => ({
70
+ account,
71
+ target: {
72
+ requestedModel: input.request.requestedModel,
73
+ providerId: target.providerId,
74
+ modelId: target.modelId,
75
+ transportProviderId: account.transportProviderId,
76
+ ...(target.effort ? { effort: target.effort } : {}),
77
+ reason: target.reason,
78
+ },
79
+ }));
80
+ });
81
+ if (input.request.explicit) {
82
+ candidates = candidates.filter((candidate) => selectorMatches(input.request.explicit, candidate, input.request.requestedModel));
83
+ }
84
+ const strategy = resolveRouteStrategy(input.policy, input.request);
85
+ const preferredExactTransport = candidates
86
+ .filter((candidate) => candidate.target.reason !== 'equivalent')
87
+ .sort((left, right) => Date.parse(right.account.enrollmentCompletedAt)
88
+ - Date.parse(left.account.enrollmentCompletedAt))[0]?.account.transportProviderId;
89
+ const targetFor = (candidate) => targets.find((target) => target.providerId === candidate.target.providerId && target.modelId === candidate.target.modelId);
90
+ candidates.sort((left, right) => {
91
+ if (strategy.kind === 'ordered') {
92
+ const rank = (candidate) => strategy.preferences.findIndex((selector) => selectorMatches(selector, candidate, input.request.requestedModel));
93
+ const leftRank = rank(left);
94
+ const rightRank = rank(right);
95
+ if (leftRank !== rightRank)
96
+ return (leftRank < 0 ? Number.MAX_SAFE_INTEGER : leftRank)
97
+ - (rightRank < 0 ? Number.MAX_SAFE_INTEGER : rightRank);
98
+ }
99
+ const classRank = (candidate) => candidate.target.reason === 'equivalent' ? 1 : 0;
100
+ if (classRank(left) !== classRank(right))
101
+ return classRank(left) - classRank(right);
102
+ if (input.policy.preferSameTransport && classRank(left) === 1 && preferredExactTransport) {
103
+ const sameTransportRank = (candidate) => candidate.account.transportProviderId === preferredExactTransport ? 0 : 1;
104
+ if (sameTransportRank(left) !== sameTransportRank(right)) {
105
+ return sameTransportRank(left) - sameTransportRank(right);
106
+ }
107
+ }
108
+ const transportRank = (candidate) => {
109
+ const rank = targetFor(candidate)?.transportPreferences
110
+ ?.indexOf(candidate.account.transportProviderId) ?? -1;
111
+ return rank < 0 ? Number.MAX_SAFE_INTEGER : rank;
112
+ };
113
+ if (transportRank(left) !== transportRank(right))
114
+ return transportRank(left) - transportRank(right);
115
+ return Date.parse(right.account.enrollmentCompletedAt)
116
+ - Date.parse(left.account.enrollmentCompletedAt)
117
+ || left.account.diagnosticAccountRef.localeCompare(right.account.diagnosticAccountRef);
118
+ });
119
+ if (strategy.kind === 'round-robin' && candidates.length > 1) {
120
+ const offset = (input.roundRobinOffset ?? 0) % candidates.length;
121
+ candidates = [...candidates.slice(offset), ...candidates.slice(0, offset)];
122
+ }
123
+ return input.applyAttemptLimit === false
124
+ ? candidates
125
+ : candidates.slice(0, input.policy.maxAttempts);
126
+ };
127
+ //# sourceMappingURL=route-selection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-selection.js","sourceRoot":"","sources":["../src/route-selection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,130 @@
1
+ import type { CapabilityRequirement } from './equivalence-council.js';
2
+ import type { GenerateRequest, GenerateResponse, StreamRequest, StreamResult } from './generation.js';
3
+ import type { RoutePolicy, RouteSelector } from './routing-policy.js';
4
+ export interface VerifiedRoutingSubject {
5
+ readonly principalRef: string;
6
+ readonly ownerScopeRef: string;
7
+ readonly grants?: readonly string[];
8
+ }
9
+ export interface EligibleAccountDescriptor {
10
+ readonly accountRef: string;
11
+ readonly diagnosticAccountRef: string;
12
+ readonly targetProviderId: string;
13
+ readonly transportProviderId: string;
14
+ readonly supportedModelIds: readonly string[];
15
+ readonly enrollmentCompletedAt: string;
16
+ readonly readiness: 'ready' | 'cooldown' | 'reauth-required' | 'disabled';
17
+ readonly revision: string;
18
+ }
19
+ export interface RouteAvailabilityDiagnostic {
20
+ readonly code: 'reenrollment-required' | 'reauth-required';
21
+ readonly transportProviderId: string;
22
+ readonly message: string;
23
+ }
24
+ export interface PlannedRouteTarget {
25
+ readonly requestedModel: string;
26
+ readonly providerId: string;
27
+ readonly modelId: string;
28
+ readonly transportProviderId: string;
29
+ readonly effort?: string;
30
+ readonly reason: 'exact' | 'alias' | 'equivalent' | 'sticky' | 'promoted';
31
+ }
32
+ export interface RoutePlanInput {
33
+ readonly requestedModel: string;
34
+ readonly intent?: 'coding' | 'general' | 'reasoning' | 'fast';
35
+ readonly requiredCapabilities?: readonly CapabilityRequirement[];
36
+ readonly affinityKey?: string;
37
+ readonly workspaceId?: string;
38
+ readonly policyProfile?: string;
39
+ readonly policyOverride?: Partial<RoutePolicy>;
40
+ readonly explicit?: RouteSelector;
41
+ }
42
+ export interface RouteDiagnostic {
43
+ readonly candidateRef: string;
44
+ readonly diagnosticAccountRef: string;
45
+ readonly requestedModel: string;
46
+ readonly actualProviderId: string;
47
+ readonly actualModelId: string;
48
+ readonly actualTransportProviderId: string;
49
+ readonly reason: PlannedRouteTarget['reason'];
50
+ readonly cacheContinuityRisk: boolean;
51
+ readonly suppressed?: boolean;
52
+ }
53
+ export interface RoutePlan {
54
+ readonly planRef: string;
55
+ readonly expiresAt: string;
56
+ readonly candidateRefs: readonly string[];
57
+ readonly policy: RoutePolicy;
58
+ readonly councilRevision: string;
59
+ readonly diagnostics: readonly RouteDiagnostic[];
60
+ }
61
+ export interface RouteModelInventoryEntry {
62
+ readonly modelId: string;
63
+ readonly providerId: string;
64
+ }
65
+ export type RouteOutcomeReason = 'success' | 'network-unavailable' | 'provider-5xx' | 'rate-limited' | 'auth-failed' | 'reauth-required' | 'unsupported-model' | 'invalid-request' | 'cancelled';
66
+ export interface RouteFailureClassification {
67
+ readonly reason: RouteOutcomeReason;
68
+ readonly retryable: boolean;
69
+ readonly retryAfterMs?: number;
70
+ readonly healthScope: 'route' | 'account' | 'transport' | 'provider-model';
71
+ }
72
+ export interface RouteAttemptUsage {
73
+ readonly inputTokens: number;
74
+ readonly outputTokens: number;
75
+ readonly estimated: boolean;
76
+ }
77
+ export interface PreparedRouteAttempt {
78
+ readonly attemptRef: string;
79
+ generate(request: GenerateRequest): Promise<GenerateResponse>;
80
+ stream(request: StreamRequest): Promise<StreamResult>;
81
+ recordOutcome(classification: RouteFailureClassification, usage?: RouteAttemptUsage): Promise<void>;
82
+ markCommitted(): Promise<void>;
83
+ complete(usage?: RouteAttemptUsage): Promise<void>;
84
+ releaseCancelled(): Promise<void>;
85
+ }
86
+ export interface AccountDirectoryPort {
87
+ listEligible(subject: VerifiedRoutingSubject): Promise<readonly EligibleAccountDescriptor[]>;
88
+ listDiagnostics?(subject: VerifiedRoutingSubject): Promise<readonly RouteAvailabilityDiagnostic[]>;
89
+ prepareAttempt(input: {
90
+ readonly subject: VerifiedRoutingSubject;
91
+ /** Mesh-internal affinity reference; never exposed in a route plan. */
92
+ readonly affinityRef?: string;
93
+ readonly accountRef: string;
94
+ readonly target: PlannedRouteTarget;
95
+ readonly requestId: string;
96
+ readonly attemptIndex: number;
97
+ }): Promise<PreparedRouteAttempt>;
98
+ }
99
+ export interface Clock {
100
+ now(): Date;
101
+ }
102
+ export interface IdFactory {
103
+ next(prefix: 'plan' | 'candidate' | 'attempt'): string;
104
+ }
105
+ export interface AffinityDescription {
106
+ readonly affinityRef: string;
107
+ readonly revision: number;
108
+ readonly diagnosticAccountRef: string;
109
+ readonly target: PlannedRouteTarget;
110
+ readonly promoted: boolean;
111
+ }
112
+ export interface AffinityMutationEvent {
113
+ readonly operation: 'promote' | 'reset' | 'rebind';
114
+ readonly subjectRef: string;
115
+ readonly affinityRef: string;
116
+ readonly previousRevision: number;
117
+ readonly nextRevision?: number;
118
+ readonly cacheContinuityRisk: boolean;
119
+ }
120
+ export interface RoutePlanner {
121
+ /** Owner-scoped executable inventory for provider-compatible model listing. */
122
+ listModels?(subject: VerifiedRoutingSubject): Promise<readonly RouteModelInventoryEntry[]>;
123
+ plan(subject: VerifiedRoutingSubject, input: RoutePlanInput): Promise<RoutePlan>;
124
+ prepareAttempt(subject: VerifiedRoutingSubject, planRef: string, candidateRef: string, requestId: string, attemptIndex: number): Promise<PreparedRouteAttempt>;
125
+ describeAffinity(subject: VerifiedRoutingSubject, affinityKey: string, workspaceId?: string): AffinityDescription | null;
126
+ promoteAffinity(subject: VerifiedRoutingSubject, planRef: string, candidateRef: string, expectedRevision?: number): AffinityDescription;
127
+ rebindAffinity(subject: VerifiedRoutingSubject, planRef: string, candidateRef: string, expectedRevision?: number): AffinityDescription;
128
+ resetAffinity(subject: VerifiedRoutingSubject, affinityKey: string, expectedRevision?: number, workspaceId?: string): boolean;
129
+ }
130
+ //# sourceMappingURL=routing-contracts.d.ts.map