@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,134 @@
1
+ import { createCipheriv, createDecipheriv, createHash, randomBytes, } from 'node:crypto';
2
+ import { chmod, link, mkdir, readFile, rename, unlink, writeFile, } from 'node:fs/promises';
3
+ import { homedir } from 'node:os';
4
+ import { join } from 'node:path';
5
+ const isErrorCode = (error, code) => typeof error === 'object' &&
6
+ error !== null &&
7
+ 'code' in error &&
8
+ error.code === code;
9
+ export class EncryptedFileKeyring {
10
+ directory;
11
+ constructor(directory = process.env.SENTROPIC_LLM_MESH_KEYRING_DIR ??
12
+ join(homedir(), '.sentropic', 'llm-mesh-keyring')) {
13
+ this.directory = directory;
14
+ }
15
+ async getSecret(key) {
16
+ let raw;
17
+ try {
18
+ raw = await readFile(this.secretPath(key), 'utf8');
19
+ }
20
+ catch (error) {
21
+ if (isErrorCode(error, 'ENOENT'))
22
+ return null;
23
+ throw error;
24
+ }
25
+ const masterKey = await this.readMasterKey(false);
26
+ let record;
27
+ try {
28
+ record = JSON.parse(raw);
29
+ if (record.v !== 1 ||
30
+ typeof record.iv !== 'string' ||
31
+ typeof record.tag !== 'string' ||
32
+ typeof record.data !== 'string') {
33
+ throw new Error('invalid record');
34
+ }
35
+ }
36
+ catch {
37
+ throw new Error(`Encrypted keyring record is corrupt for key '${key}'`);
38
+ }
39
+ try {
40
+ const decipher = createDecipheriv('aes-256-gcm', masterKey, Buffer.from(record.iv, 'base64'));
41
+ decipher.setAAD(Buffer.from(key, 'utf8'));
42
+ decipher.setAuthTag(Buffer.from(record.tag, 'base64'));
43
+ return Buffer.concat([
44
+ decipher.update(Buffer.from(record.data, 'base64')),
45
+ decipher.final(),
46
+ ]).toString('utf8');
47
+ }
48
+ catch {
49
+ throw new Error(`Encrypted keyring authentication failed for key '${key}'`);
50
+ }
51
+ }
52
+ async setSecret(key, secret) {
53
+ const masterKey = await this.readMasterKey(true);
54
+ const iv = randomBytes(12);
55
+ const cipher = createCipheriv('aes-256-gcm', masterKey, iv);
56
+ cipher.setAAD(Buffer.from(key, 'utf8'));
57
+ const encrypted = Buffer.concat([
58
+ cipher.update(Buffer.from(secret, 'utf8')),
59
+ cipher.final(),
60
+ ]);
61
+ const record = {
62
+ v: 1,
63
+ iv: iv.toString('base64'),
64
+ tag: cipher.getAuthTag().toString('base64'),
65
+ data: encrypted.toString('base64'),
66
+ };
67
+ const destination = this.secretPath(key);
68
+ const temporary = `${destination}.${randomBytes(8).toString('hex')}.tmp`;
69
+ try {
70
+ await writeFile(temporary, JSON.stringify(record), { flag: 'wx', mode: 0o600 });
71
+ await rename(temporary, destination);
72
+ await chmod(destination, 0o600);
73
+ }
74
+ catch (error) {
75
+ await this.unlinkIfPresent(temporary);
76
+ throw error;
77
+ }
78
+ }
79
+ async deleteSecret(key) {
80
+ await this.unlinkIfPresent(this.secretPath(key));
81
+ }
82
+ secretPath(key) {
83
+ const filename = createHash('sha256').update(key).digest('hex');
84
+ return join(this.directory, `${filename}.json`);
85
+ }
86
+ async readMasterKey(create) {
87
+ await mkdir(this.directory, { recursive: true, mode: 0o700 });
88
+ await chmod(this.directory, 0o700);
89
+ const path = join(this.directory, '.key');
90
+ try {
91
+ return await this.loadAndValidateMasterKey(path);
92
+ }
93
+ catch (error) {
94
+ if (!isErrorCode(error, 'ENOENT') || !create) {
95
+ if (isErrorCode(error, 'ENOENT')) {
96
+ throw new Error('Encrypted keyring master key is missing');
97
+ }
98
+ throw error;
99
+ }
100
+ }
101
+ const candidate = randomBytes(32);
102
+ const temporary = join(this.directory, `.key.${randomBytes(8).toString('hex')}.tmp`);
103
+ await writeFile(temporary, candidate, { flag: 'wx', mode: 0o600 });
104
+ try {
105
+ await link(temporary, path);
106
+ }
107
+ catch (error) {
108
+ if (!isErrorCode(error, 'EEXIST'))
109
+ throw error;
110
+ }
111
+ finally {
112
+ await this.unlinkIfPresent(temporary);
113
+ }
114
+ await chmod(path, 0o600);
115
+ return this.loadAndValidateMasterKey(path);
116
+ }
117
+ async loadAndValidateMasterKey(path) {
118
+ const masterKey = await readFile(path);
119
+ if (masterKey.length !== 32) {
120
+ throw new Error('Encrypted keyring master key is corrupt');
121
+ }
122
+ return masterKey;
123
+ }
124
+ async unlinkIfPresent(path) {
125
+ try {
126
+ await unlink(path);
127
+ }
128
+ catch (error) {
129
+ if (!isErrorCode(error, 'ENOENT'))
130
+ throw error;
131
+ }
132
+ }
133
+ }
134
+ //# sourceMappingURL=encrypted-file-keyring.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encrypted-file-keyring.js","sourceRoot":"","sources":["../../../src/node/keyring/encrypted-file-keyring.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { RankedRouteCandidate } from './route-selection.js';
2
+ import type { StoredPlan } from './route-planner-state.js';
3
+ import type { AccountDirectoryPort, Clock, PreparedRouteAttempt, RouteFailureClassification, VerifiedRoutingSubject } from './routing-contracts.js';
4
+ export declare const prepareStoredRouteAttempt: (input: {
5
+ readonly stored: StoredPlan | undefined;
6
+ readonly subject: VerifiedRoutingSubject;
7
+ readonly planRef: string;
8
+ readonly candidateRef: string;
9
+ readonly requestId: string;
10
+ readonly attemptIndex: number;
11
+ readonly directory: AccountDirectoryPort;
12
+ readonly clock: Clock;
13
+ readonly onOutcome: (stored: StoredPlan, candidate: RankedRouteCandidate, classification: RouteFailureClassification) => void;
14
+ readonly onCommitted: (stored: StoredPlan, candidate: RankedRouteCandidate) => void;
15
+ readonly onSuccess: (stored: StoredPlan, candidate: RankedRouteCandidate) => void;
16
+ readonly onCancelled: (stored: StoredPlan, candidate: RankedRouteCandidate) => void;
17
+ }) => Promise<PreparedRouteAttempt>;
18
+ //# sourceMappingURL=route-attempt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-attempt.d.ts","sourceRoot":"","sources":["../src/route-attempt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAE3D,OAAO,KAAK,EACV,oBAAoB,EACpB,KAAK,EACL,oBAAoB,EACpB,0BAA0B,EAC1B,sBAAsB,EACvB,MAAM,wBAAwB,CAAC;AAEhC,eAAO,MAAM,yBAAyB,UAAiB;IACrD,QAAQ,CAAC,MAAM,EAAE,UAAU,GAAG,SAAS,CAAC;IACxC,QAAQ,CAAC,OAAO,EAAE,sBAAsB,CAAC;IACzC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,oBAAoB,CAAC;IACzC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,CAClB,MAAM,EAAE,UAAU,EAClB,SAAS,EAAE,oBAAoB,EAC/B,cAAc,EAAE,0BAA0B,KACvC,IAAI,CAAC;IACV,QAAQ,CAAC,WAAW,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,oBAAoB,KAAK,IAAI,CAAC;IACpF,QAAQ,CAAC,SAAS,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,oBAAoB,KAAK,IAAI,CAAC;IAClF,QAAQ,CAAC,WAAW,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,oBAAoB,KAAK,IAAI,CAAC;CACrF,KAAG,QAAQ,oBAAoB,CAiE/B,CAAC"}
@@ -0,0 +1,70 @@
1
+ import { RoutePlanError, subjectRef } from './route-planner-state.js';
2
+ export const prepareStoredRouteAttempt = async (input) => {
3
+ const { stored } = input;
4
+ if (!stored || stored.plan.planRef !== input.planRef) {
5
+ throw new RoutePlanError('Unknown route plan', 'invalid-plan');
6
+ }
7
+ if (stored.subjectRef !== subjectRef(input.subject)) {
8
+ throw new RoutePlanError('Route plan belongs to another owner', 'invalid-plan');
9
+ }
10
+ if (Date.parse(stored.plan.expiresAt) <= input.clock.now().getTime()) {
11
+ throw new RoutePlanError('Route plan expired', 'expired-plan');
12
+ }
13
+ const candidate = stored.candidates[input.attemptIndex];
14
+ if (!candidate || candidate.candidateRef !== input.candidateRef) {
15
+ throw new RoutePlanError('Candidate does not match attempt index', 'invalid-plan');
16
+ }
17
+ const claim = [input.candidateRef, input.requestId, input.attemptIndex].join('\u001f');
18
+ if (stored.claimedAttempts.has(claim)) {
19
+ throw new RoutePlanError('Route attempt was already prepared', 'invalid-plan');
20
+ }
21
+ stored.claimedAttempts.add(claim);
22
+ const current = (await input.directory.listEligible(input.subject)).find((account) => account.accountRef === candidate.account.accountRef);
23
+ if (!current || current.revision !== candidate.account.revision || current.readiness !== 'ready') {
24
+ throw new RoutePlanError('Candidate account changed after planning', 'stale-candidate');
25
+ }
26
+ const attempt = await input.directory.prepareAttempt({
27
+ subject: input.subject,
28
+ ...(stored.affinityRef ? { affinityRef: stored.affinityRef } : {}),
29
+ accountRef: current.accountRef,
30
+ target: candidate.target,
31
+ requestId: input.requestId,
32
+ attemptIndex: input.attemptIndex,
33
+ });
34
+ let committed = false;
35
+ let terminal = false;
36
+ return {
37
+ attemptRef: attempt.attemptRef,
38
+ generate: (request) => attempt.generate(request),
39
+ stream: (request) => attempt.stream(request),
40
+ recordOutcome: async (classification, usage) => {
41
+ if (terminal)
42
+ return;
43
+ terminal = true;
44
+ input.onOutcome(stored, candidate, classification);
45
+ await attempt.recordOutcome(classification, usage);
46
+ },
47
+ markCommitted: async () => {
48
+ if (committed)
49
+ return;
50
+ committed = true;
51
+ input.onCommitted(stored, candidate);
52
+ await attempt.markCommitted();
53
+ },
54
+ complete: async (usage) => {
55
+ if (terminal)
56
+ return;
57
+ terminal = true;
58
+ input.onSuccess(stored, candidate);
59
+ await attempt.complete(usage);
60
+ },
61
+ releaseCancelled: async () => {
62
+ if (terminal)
63
+ return;
64
+ terminal = true;
65
+ input.onCancelled(stored, candidate);
66
+ await attempt.releaseCancelled();
67
+ },
68
+ };
69
+ };
70
+ //# sourceMappingURL=route-attempt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-attempt.js","sourceRoot":"","sources":["../src/route-attempt.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { RankedRouteCandidate } from './route-selection.js';
2
+ import type { Clock, RouteFailureClassification } from './routing-contracts.js';
3
+ import type { RoutePolicy } from './routing-policy.js';
4
+ export declare class InMemoryRouteHealth {
5
+ private readonly clock;
6
+ private readonly maximumEntries;
7
+ private readonly entries;
8
+ constructor(clock: Clock, maximumEntries?: number);
9
+ record(candidate: RankedRouteCandidate, classification: RouteFailureClassification, policy: RoutePolicy): void;
10
+ isSuppressed(candidate: RankedRouteCandidate): boolean;
11
+ clear(candidate: RankedRouteCandidate): void;
12
+ private evict;
13
+ }
14
+ //# sourceMappingURL=route-health.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-health.d.ts","sourceRoot":"","sources":["../src/route-health.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,KAAK,EAAE,KAAK,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AAChF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAoCvD,qBAAa,mBAAmB;IAI5B,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,cAAc;IAJjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkC;gBAGvC,KAAK,EAAE,KAAK,EACZ,cAAc,SAAQ;IAGzC,MAAM,CACJ,SAAS,EAAE,oBAAoB,EAC/B,cAAc,EAAE,0BAA0B,EAC1C,MAAM,EAAE,WAAW,GAClB,IAAI;IAaP,YAAY,CAAC,SAAS,EAAE,oBAAoB,GAAG,OAAO;IAStD,KAAK,CAAC,SAAS,EAAE,oBAAoB,GAAG,IAAI;IAI5C,OAAO,CAAC,KAAK;CAWd"}
@@ -0,0 +1,69 @@
1
+ const availabilityReasons = new Set([
2
+ 'network-unavailable',
3
+ 'provider-5xx',
4
+ 'rate-limited',
5
+ ]);
6
+ const keyFor = (candidate, scope) => {
7
+ switch (scope) {
8
+ case 'account': return `account:${candidate.account.accountRef}`;
9
+ case 'transport': return `transport:${candidate.target.transportProviderId}`;
10
+ case 'provider-model': return `provider-model:${candidate.target.providerId}:${candidate.target.modelId}`;
11
+ default: return [
12
+ 'route', candidate.target.providerId, candidate.target.modelId,
13
+ candidate.target.transportProviderId, candidate.account.accountRef,
14
+ ].join(':');
15
+ }
16
+ };
17
+ const applicableKeys = (candidate) => [
18
+ keyFor(candidate, 'route'),
19
+ keyFor(candidate, 'account'),
20
+ keyFor(candidate, 'transport'),
21
+ keyFor(candidate, 'provider-model'),
22
+ ];
23
+ export class InMemoryRouteHealth {
24
+ clock;
25
+ maximumEntries;
26
+ entries = new Map();
27
+ constructor(clock, maximumEntries = 1_000) {
28
+ this.clock = clock;
29
+ this.maximumEntries = maximumEntries;
30
+ }
31
+ record(candidate, classification, policy) {
32
+ if (!classification.retryable || !availabilityReasons.has(classification.reason))
33
+ return;
34
+ const requestedTtl = classification.retryAfterMs ?? policy.negativeCacheTtlMs;
35
+ const ttl = Math.min(Math.max(requestedTtl, 1_000), 3_600_000);
36
+ const key = keyFor(candidate, classification.healthScope);
37
+ this.entries.set(key, {
38
+ key,
39
+ reason: classification.reason,
40
+ expiresAt: this.clock.now().getTime() + ttl,
41
+ });
42
+ this.evict();
43
+ }
44
+ isSuppressed(candidate) {
45
+ this.evict();
46
+ const now = this.clock.now().getTime();
47
+ return applicableKeys(candidate).some((key) => {
48
+ const entry = this.entries.get(key);
49
+ return Boolean(entry && entry.expiresAt > now);
50
+ });
51
+ }
52
+ clear(candidate) {
53
+ applicableKeys(candidate).forEach((key) => this.entries.delete(key));
54
+ }
55
+ evict() {
56
+ const now = this.clock.now().getTime();
57
+ for (const [key, entry] of this.entries) {
58
+ if (entry.expiresAt <= now)
59
+ this.entries.delete(key);
60
+ }
61
+ while (this.entries.size > this.maximumEntries) {
62
+ const oldest = [...this.entries.values()].sort((a, b) => a.expiresAt - b.expiresAt)[0];
63
+ if (!oldest)
64
+ break;
65
+ this.entries.delete(oldest.key);
66
+ }
67
+ }
68
+ }
69
+ //# sourceMappingURL=route-health.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-health.js","sourceRoot":"","sources":["../src/route-health.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ import type { RankedRouteCandidate } from './route-selection.js';
2
+ import type { AffinityDescription, IdFactory, RouteAvailabilityDiagnostic, RoutePlan, VerifiedRoutingSubject } from './routing-contracts.js';
3
+ import type { RoutePolicy } from './routing-policy.js';
4
+ export interface StoredCandidate extends RankedRouteCandidate {
5
+ readonly candidateRef: string;
6
+ }
7
+ export interface StoredPlan {
8
+ readonly plan: RoutePlan;
9
+ readonly subjectRef: string;
10
+ readonly affinityRef?: string;
11
+ readonly affinityRevision?: number;
12
+ readonly policyProfileName?: string;
13
+ readonly policyProfileRevision?: string;
14
+ readonly hadAffinity: boolean;
15
+ readonly candidates: readonly StoredCandidate[];
16
+ readonly policy: RoutePolicy;
17
+ readonly claimedAttempts: Set<string>;
18
+ readonly roundRobinKey?: string;
19
+ }
20
+ export interface StoredAffinity extends AffinityDescription {
21
+ readonly accountRef: string;
22
+ readonly workspaceId?: string;
23
+ }
24
+ export declare class RoutePlanError extends Error {
25
+ readonly code: 'no-route' | 'invalid-plan' | 'expired-plan' | 'stale-candidate' | 'conflict';
26
+ readonly diagnostic?: RouteAvailabilityDiagnostic | undefined;
27
+ constructor(message: string, code: 'no-route' | 'invalid-plan' | 'expired-plan' | 'stale-candidate' | 'conflict', diagnostic?: RouteAvailabilityDiagnostic | undefined);
28
+ }
29
+ export declare const subjectRef: (subject: VerifiedRoutingSubject) => string;
30
+ export declare const routingOwnerRef: (subject: VerifiedRoutingSubject) => string;
31
+ export declare const affinityRef: (subject: VerifiedRoutingSubject, affinityKey: string, workspaceId?: string) => string;
32
+ export declare const mergeRoutePolicy: (base: RoutePolicy, override?: Partial<RoutePolicy>) => RoutePolicy;
33
+ export declare class SequentialIdFactory implements IdFactory {
34
+ private sequence;
35
+ next(prefix: 'plan' | 'candidate' | 'attempt'): string;
36
+ }
37
+ //# sourceMappingURL=route-planner-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-planner-state.d.ts","sourceRoot":"","sources":["../src/route-planner-state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,KAAK,EACV,mBAAmB,EACnB,SAAS,EACT,2BAA2B,EAC3B,SAAS,EACT,sBAAsB,EACvB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD,MAAM,WAAW,eAAgB,SAAQ,oBAAoB;IAC3D,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,qBAAqB,CAAC,EAAE,MAAM,CAAC;IACxC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,SAAS,eAAe,EAAE,CAAC;IAChD,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,eAAe,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACtC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CACjC;AAED,MAAM,WAAW,cAAe,SAAQ,mBAAmB;IACzD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,qBAAa,cAAe,SAAQ,KAAK;IAGrC,QAAQ,CAAC,IAAI,EAAE,UAAU,GAAG,cAAc,GAAG,cAAc,GAAG,iBAAiB,GAAG,UAAU;IAC5F,QAAQ,CAAC,UAAU,CAAC;gBAFpB,OAAO,EAAE,MAAM,EACN,IAAI,EAAE,UAAU,GAAG,cAAc,GAAG,cAAc,GAAG,iBAAiB,GAAG,UAAU,EACnF,UAAU,CAAC,yCAA6B;CAKpD;AAED,eAAO,MAAM,UAAU,YAAa,sBAAsB,KAAG,MACJ,CAAC;AAE1D,eAAO,MAAM,eAAe,YAAa,sBAAsB,KAAG,MAC3C,CAAC;AAExB,eAAO,MAAM,WAAW,YACb,sBAAsB,eAClB,MAAM,gBACL,MAAM,KACnB,MAAmF,CAAC;AAEvF,eAAO,MAAM,gBAAgB,SACrB,WAAW,aACN,QAAQ,WAAW,CAAC,KAC9B,WAKD,CAAC;AAEH,qBAAa,mBAAoB,YAAW,SAAS;IACnD,OAAO,CAAC,QAAQ,CAAK;IAErB,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,GAAG,MAAM;CAIvD"}
@@ -0,0 +1,27 @@
1
+ export class RoutePlanError extends Error {
2
+ code;
3
+ diagnostic;
4
+ constructor(message, code, diagnostic) {
5
+ super(message);
6
+ this.code = code;
7
+ this.diagnostic = diagnostic;
8
+ this.name = 'RoutePlanError';
9
+ }
10
+ }
11
+ export const subjectRef = (subject) => `${subject.principalRef}\u001f${subject.ownerScopeRef}`;
12
+ export const routingOwnerRef = (subject) => subject.ownerScopeRef;
13
+ export const affinityRef = (subject, affinityKey, workspaceId) => [routingOwnerRef(subject), workspaceId ?? '', affinityKey].join('\u001f');
14
+ export const mergeRoutePolicy = (base, override) => ({
15
+ ...base,
16
+ ...override,
17
+ strategy: override?.strategy ?? base.strategy,
18
+ rules: override?.rules ?? base.rules,
19
+ });
20
+ export class SequentialIdFactory {
21
+ sequence = 0;
22
+ next(prefix) {
23
+ this.sequence += 1;
24
+ return `${prefix}_${this.sequence.toString(36)}`;
25
+ }
26
+ }
27
+ //# sourceMappingURL=route-planner-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-planner-state.js","sourceRoot":"","sources":["../src/route-planner-state.ts"],"names":[],"mappings":"AAiCA,MAAM,OAAO,cAAe,SAAQ,KAAK;IAG5B;IACA;IAHX,YACE,OAAe,EACN,IAAmF,EACnF,UAAwC;QAEjD,KAAK,CAAC,OAAO,CAAC,CAAC;QAHN,SAAI,GAAJ,IAAI,CAA+E;QACnF,eAAU,GAAV,UAAU,CAA8B;QAGjD,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF;AAED,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,OAA+B,EAAU,EAAE,CACpE,GAAG,OAAO,CAAC,YAAY,SAAS,OAAO,CAAC,aAAa,EAAE,CAAC;AAE1D,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,OAA+B,EAAU,EAAE,CACzE,OAAO,CAAC,aAAa,CAAC;AAExB,MAAM,CAAC,MAAM,WAAW,GAAG,CACzB,OAA+B,EAC/B,WAAmB,EACnB,WAAoB,EACZ,EAAE,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,EAAE,WAAW,IAAI,EAAE,EAAE,WAAW,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AAEvF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,IAAiB,EACjB,QAA+B,EAClB,EAAE,CAAC,CAAC;IACjB,GAAG,IAAI;IACP,GAAG,QAAQ;IACX,QAAQ,EAAE,QAAQ,EAAE,QAAQ,IAAI,IAAI,CAAC,QAAQ;IAC7C,KAAK,EAAE,QAAQ,EAAE,KAAK,IAAI,IAAI,CAAC,KAAK;CACrC,CAAC,CAAC;AAEH,MAAM,OAAO,mBAAmB;IACtB,QAAQ,GAAG,CAAC,CAAC;IAErB,IAAI,CAAC,MAAwC;QAC3C,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAC;QACnB,OAAO,GAAG,MAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;IACnD,CAAC;CACF"}
@@ -0,0 +1,48 @@
1
+ import { type ModelEquivalenceCouncil } from './equivalence-council.js';
2
+ import type { AccountDirectoryPort, AffinityDescription, Clock, IdFactory, PreparedRouteAttempt, AffinityMutationEvent, RoutePlan, RoutePlanInput, RoutePlanner, VerifiedRoutingSubject, RouteModelInventoryEntry } from './routing-contracts.js';
3
+ import { InMemoryRoutePolicyProfiles } from './routing-policy.js';
4
+ export interface InMemoryRoutePlannerOptions {
5
+ readonly directory: AccountDirectoryPort;
6
+ readonly council?: ModelEquivalenceCouncil;
7
+ readonly profiles?: InMemoryRoutePolicyProfiles;
8
+ readonly clock?: Clock;
9
+ readonly idFactory?: IdFactory;
10
+ readonly planTtlMs?: number;
11
+ readonly maximumPlanEntries?: number;
12
+ readonly maximumAffinityEntries?: number;
13
+ readonly maximumRoundRobinEntries?: number;
14
+ readonly affinityAudit?: (event: AffinityMutationEvent) => void;
15
+ }
16
+ export declare class InMemoryRoutePlanner implements RoutePlanner {
17
+ private readonly options;
18
+ private readonly plans;
19
+ private readonly affinities;
20
+ private readonly roundRobin;
21
+ private readonly clock;
22
+ private readonly ids;
23
+ private readonly council;
24
+ private readonly profiles;
25
+ private readonly health;
26
+ private readonly planTtlMs;
27
+ private readonly maximumPlanEntries;
28
+ private readonly maximumAffinityEntries;
29
+ private readonly maximumRoundRobinEntries;
30
+ constructor(options: InMemoryRoutePlannerOptions);
31
+ listModels(subject: VerifiedRoutingSubject): Promise<readonly RouteModelInventoryEntry[]>;
32
+ plan(subject: VerifiedRoutingSubject, input: RoutePlanInput): Promise<RoutePlan>;
33
+ prepareAttempt(subject: VerifiedRoutingSubject, planRef: string, candidateRef: string, requestId: string, attemptIndex: number): Promise<PreparedRouteAttempt>;
34
+ describeAffinity(subject: VerifiedRoutingSubject, key: string, workspaceId?: string): AffinityDescription | null;
35
+ promoteAffinity(subject: VerifiedRoutingSubject, planRef: string, candidateRef: string, expectedRevision?: number): AffinityDescription;
36
+ rebindAffinity(subject: VerifiedRoutingSubject, planRef: string, candidateRef: string, expectedRevision?: number): AffinityDescription;
37
+ resetAffinity(subject: VerifiedRoutingSubject, key: string, expectedRevision?: number, workspaceId?: string): boolean;
38
+ private mutateAffinity;
39
+ private bind;
40
+ private isAffinityTarget;
41
+ private evictPlans;
42
+ private commitRoundRobin;
43
+ private releaseRoundRobin;
44
+ private touchRoundRobin;
45
+ private trimPlans;
46
+ private trim;
47
+ }
48
+ //# sourceMappingURL=route-planner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-planner.d.ts","sourceRoot":"","sources":["../src/route-planner.ts"],"names":[],"mappings":"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"}