@kindgi/capabilities 0.0.0-bootstrap.0 → 0.1.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.
@@ -0,0 +1,73 @@
1
+ import type { Result } from '@kindgi/types';
2
+ import type { CapabilityError, CapabilityUnsatisfiableError } from './errors.js';
3
+ import type { Capability, ModelProvider, ProviderModelPick, RoutingDecision, TenantPolicy } from './types.js';
4
+ /**
5
+ * Input to `route()`. Callers pass the pre-scoped provider slice (e.g.
6
+ * `registry.list(tenantId)`) plus the capability declaration; the
7
+ * router expands each provider into one entry per exposed model,
8
+ * filters at the `(provider, model)` tuple level, ranks by
9
+ * preference, and returns the top pick.
10
+ */
11
+ export interface RouteInput {
12
+ readonly capability: Capability;
13
+ readonly providers: readonly ModelProvider[];
14
+ readonly tenantPolicy?: TenantPolicy;
15
+ /**
16
+ * Optional soft hint — the router prefers tuples whose provider id
17
+ * matches. When the preferred provider is absent or filtered out,
18
+ * the router falls back to normal `capability.prefer`-based
19
+ * ranking. Typical source: `Agent.preferredProvider`.
20
+ */
21
+ readonly preferredProvider?: string;
22
+ /**
23
+ * Optional soft hint — the router prefers tuples whose
24
+ * `ModelInfo.name` matches. Combined with `preferredProvider`:
25
+ *
26
+ * - Both set → promote the exact `(provider, model)` tuple.
27
+ * - Only `preferredModel` set → promote any tuple whose model
28
+ * matches, across every provider.
29
+ * - Only `preferredProvider` set → promote every model of that
30
+ * provider.
31
+ *
32
+ * Typical source: `Agent.preferredModel`.
33
+ */
34
+ readonly preferredModel?: string;
35
+ }
36
+ /**
37
+ * Route a capability declaration against a provider slice. Returns
38
+ * the highest-ranked `(provider, model)` tuple satisfying every
39
+ * `needs` constraint plus tenant policy, with alternates in ranked
40
+ * order for failover.
41
+ *
42
+ * The router is pure: given the same (capability, providers, policy)
43
+ * it always produces the same decision. Ties are broken lexically on
44
+ * `(providerId, modelName)`, so deterministic replay from journal is
45
+ * guaranteed.
46
+ *
47
+ * A fallback provider (`metadata.fallback`) is considered only when no
48
+ * other provider satisfies the capability; the decision then says so
49
+ * (`fallback: true`). Its tuples are never alternates to a regular pick.
50
+ *
51
+ * Tenant scoping happens BEFORE the router — callers pass a
52
+ * `providers` array that already reflects the target tenant. This
53
+ * keeps the router decoupled from whether the underlying registry is
54
+ * in-memory, postgres-backed, or a composed view.
55
+ */
56
+ export declare function route(input: RouteInput): Result<RoutingDecision, CapabilityError>;
57
+ /**
58
+ * Hard-filter `(provider, model)` tuples against `capability.needs`
59
+ * and `tenantPolicy`. Returns the surviving set (order preserved from
60
+ * `expandTuples`; the ranker sorts). On empty result, returns
61
+ * `capability-unsatisfiable` with per-requirement rejection reasons
62
+ * for diagnosis.
63
+ *
64
+ * Filter semantics per requirement:
65
+ * - `feature` / `contextWindow` / `costPerCall` / `p95LatencyMs`
66
+ * read from `ModelInfo` — filter at the model level.
67
+ * - `region` reads from `ProviderMetadata.region` — filter at the
68
+ * provider level (all models of one connection share region).
69
+ * - `providers` allow/deny reads `ProviderMetadata.id`.
70
+ * - `models` allow/deny reads `ModelInfo.name`.
71
+ */
72
+ export declare function matchTuples(input: RouteInput): Result<readonly ProviderModelPick[], CapabilityUnsatisfiableError>;
73
+ //# sourceMappingURL=router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,KAAK,EAAE,eAAe,EAAE,4BAA4B,EAAE,MAAM,aAAa,CAAC;AAEjF,OAAO,KAAK,EACV,UAAU,EAEV,aAAa,EAEb,iBAAiB,EAGjB,eAAe,EACf,YAAY,EAEb,MAAM,YAAY,CAAC;AAEpB;;;;;;GAMG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,QAAQ,CAAC,SAAS,EAAE,SAAS,aAAa,EAAE,CAAC;IAC7C,QAAQ,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC;IACrC;;;;;OAKG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;CAClC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAAC,eAAe,EAAE,eAAe,CAAC,CAwBjF;AAkBD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,UAAU,GAChB,MAAM,CAAC,SAAS,iBAAiB,EAAE,EAAE,4BAA4B,CAAC,CAoEpE"}
package/dist/router.js ADDED
@@ -0,0 +1,484 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (C) 2026 Kindgi Inc.
3
+ import { DEFAULT_CAPABILITY_KIND } from './types.js';
4
+ /**
5
+ * Route a capability declaration against a provider slice. Returns
6
+ * the highest-ranked `(provider, model)` tuple satisfying every
7
+ * `needs` constraint plus tenant policy, with alternates in ranked
8
+ * order for failover.
9
+ *
10
+ * The router is pure: given the same (capability, providers, policy)
11
+ * it always produces the same decision. Ties are broken lexically on
12
+ * `(providerId, modelName)`, so deterministic replay from journal is
13
+ * guaranteed.
14
+ *
15
+ * A fallback provider (`metadata.fallback`) is considered only when no
16
+ * other provider satisfies the capability; the decision then says so
17
+ * (`fallback: true`). Its tuples are never alternates to a regular pick.
18
+ *
19
+ * Tenant scoping happens BEFORE the router — callers pass a
20
+ * `providers` array that already reflects the target tenant. This
21
+ * keeps the router decoupled from whether the underlying registry is
22
+ * in-memory, postgres-backed, or a composed view.
23
+ */
24
+ export function route(input) {
25
+ const survivors = matchTuples(input);
26
+ if (survivors.kind === 'err')
27
+ return survivors;
28
+ const regular = survivors.value.filter((t) => t.provider.metadata.fallback !== true);
29
+ const fallback = regular.length === 0;
30
+ const candidates = fallback ? survivors.value : regular;
31
+ const ranked = rankByPreference(candidates, input.capability.prefer ?? []);
32
+ const finalOrder = applyPreferredHints(ranked, input.preferredProvider, input.preferredModel);
33
+ const top = finalOrder[0];
34
+ if (top === undefined) {
35
+ // Should be caught by matchTuples, but defensive.
36
+ return unsatisfiable([], input.tenantPolicy);
37
+ }
38
+ return {
39
+ kind: 'ok',
40
+ value: {
41
+ provider: top.provider,
42
+ model: top.model,
43
+ reason: buildReason(top, input, fallback),
44
+ alternates: finalOrder.slice(1),
45
+ fallback,
46
+ },
47
+ };
48
+ }
49
+ /**
50
+ * Expand every provider into one entry per exposed model. Emits
51
+ * `(provider, model)` tuples in deterministic order: providers in
52
+ * input order, models in the order they appear on each provider's
53
+ * `metadata.models[]`. Downstream sort determines the final tiebreak.
54
+ */
55
+ function expandTuples(providers) {
56
+ const out = [];
57
+ for (const p of providers) {
58
+ for (const m of p.metadata.models) {
59
+ out.push({ provider: p, model: m });
60
+ }
61
+ }
62
+ return out;
63
+ }
64
+ /**
65
+ * Hard-filter `(provider, model)` tuples against `capability.needs`
66
+ * and `tenantPolicy`. Returns the surviving set (order preserved from
67
+ * `expandTuples`; the ranker sorts). On empty result, returns
68
+ * `capability-unsatisfiable` with per-requirement rejection reasons
69
+ * for diagnosis.
70
+ *
71
+ * Filter semantics per requirement:
72
+ * - `feature` / `contextWindow` / `costPerCall` / `p95LatencyMs`
73
+ * read from `ModelInfo` — filter at the model level.
74
+ * - `region` reads from `ProviderMetadata.region` — filter at the
75
+ * provider level (all models of one connection share region).
76
+ * - `providers` allow/deny reads `ProviderMetadata.id`.
77
+ * - `models` allow/deny reads `ModelInfo.name`.
78
+ */
79
+ export function matchTuples(input) {
80
+ const tuples = expandTuples(input.providers);
81
+ const rejections = new Map();
82
+ const perRequirementReasons = [];
83
+ const requestedKind = input.capability.kind ?? DEFAULT_CAPABILITY_KIND;
84
+ const requirements = [
85
+ // Kind gate runs first so providers of the wrong resource kind are
86
+ // rejected with a clear reason instead of being pinned to a specific
87
+ // needs-based diagnostic.
88
+ {
89
+ label: `capability.kind = ${requestedKind}`,
90
+ test: (t) => {
91
+ const providerKind = t.provider.metadata.capabilityKind ?? DEFAULT_CAPABILITY_KIND;
92
+ if (providerKind === requestedKind)
93
+ return null;
94
+ return {
95
+ code: 'capability-kind-mismatch',
96
+ message: `provider kind "${providerKind}" does not match requested "${requestedKind}"`,
97
+ observed: providerKind,
98
+ wanted: requestedKind,
99
+ };
100
+ },
101
+ },
102
+ ...input.capability.needs.map((req) => ({
103
+ label: describeRequirement(req),
104
+ test: (t) => matchRequirement(req, t),
105
+ })),
106
+ ...tenantPolicyRequirements(input.tenantPolicy),
107
+ ];
108
+ for (const t of tuples) {
109
+ const key = tupleKey(t);
110
+ for (const r of requirements) {
111
+ const rejection = r.test(t);
112
+ if (rejection !== null) {
113
+ const existing = rejections.get(key) ?? [];
114
+ existing.push(`${r.label} → ${rejection.message}`);
115
+ rejections.set(key, existing);
116
+ }
117
+ }
118
+ }
119
+ const survivors = tuples.filter((t) => (rejections.get(tupleKey(t))?.length ?? 0) === 0);
120
+ if (survivors.length > 0)
121
+ return { kind: 'ok', value: survivors };
122
+ // Build per-requirement diagnostic. Skip requirements every tuple
123
+ // already satisfied — they add noise (e.g. the kind gate matches
124
+ // every llm-inference provider when the caller asked for llm-inference).
125
+ for (const r of requirements) {
126
+ const satisfying = [];
127
+ const rejecting = [];
128
+ for (const t of tuples) {
129
+ const failure = r.test(t);
130
+ const id = tupleKey(t);
131
+ if (failure === null)
132
+ satisfying.push(id);
133
+ else
134
+ rejecting.push({ id, reason: failure });
135
+ }
136
+ if (rejecting.length === 0)
137
+ continue;
138
+ perRequirementReasons.push({
139
+ requirement: r.label,
140
+ satisfyingProviders: satisfying,
141
+ rejectingProviders: rejecting,
142
+ });
143
+ }
144
+ return unsatisfiable(perRequirementReasons, input.tenantPolicy);
145
+ }
146
+ /** Stable tuple identifier — `providerId/modelName`. Used in rejection diagnostics. */
147
+ function tupleKey(t) {
148
+ return `${t.provider.metadata.id}/${t.model.name}`;
149
+ }
150
+ /**
151
+ * Rank tuples by summed weight of matched preferences, stable sort.
152
+ * Equal scores tiebreak lexically on `(providerId, modelName)` so
153
+ * replay is deterministic even when multiple tuples tie.
154
+ */
155
+ function rankByPreference(tuples, prefs) {
156
+ if (prefs.length === 0)
157
+ return [...tuples].sort(compareTuplesLex);
158
+ const scored = tuples.map((t) => ({ t, score: preferenceScore(t, prefs) }));
159
+ scored.sort((a, b) => {
160
+ if (a.score !== b.score)
161
+ return b.score - a.score;
162
+ return compareTuplesLex(a.t, b.t);
163
+ });
164
+ return scored.map((s) => s.t);
165
+ }
166
+ function compareTuplesLex(a, b) {
167
+ const p = a.provider.metadata.id.localeCompare(b.provider.metadata.id);
168
+ if (p !== 0)
169
+ return p;
170
+ return a.model.name.localeCompare(b.model.name);
171
+ }
172
+ function preferenceScore(t, prefs) {
173
+ let score = 0;
174
+ const providerAttrs = t.provider.metadata.attributes;
175
+ const modelFeatures = t.model.features;
176
+ for (const pref of prefs) {
177
+ if (modelFeatures.includes(pref.feature) ||
178
+ providerAttrs?.includes(pref.feature) === true) {
179
+ score += pref.weight;
180
+ }
181
+ }
182
+ return score;
183
+ }
184
+ /**
185
+ * Apply the `preferredProvider` + `preferredModel` soft hints. Matching
186
+ * tuples are promoted to the front while preserving the internal rank
187
+ * order from `rankByPreference`. Neither hint is required — the
188
+ * ranked order is returned untouched when both are absent.
189
+ */
190
+ function applyPreferredHints(ranked, preferredProvider, preferredModel) {
191
+ if (preferredProvider === undefined && preferredModel === undefined)
192
+ return ranked;
193
+ const matches = (t) => {
194
+ if (preferredProvider !== undefined && t.provider.metadata.id !== preferredProvider) {
195
+ return false;
196
+ }
197
+ if (preferredModel !== undefined && t.model.name !== preferredModel)
198
+ return false;
199
+ return true;
200
+ };
201
+ return [...ranked.filter(matches), ...ranked.filter((t) => !matches(t))];
202
+ }
203
+ /**
204
+ * Test a single Requirement against a `(provider, model)` tuple.
205
+ * Returns null on satisfaction, a structured `RejectionReason` on
206
+ * rejection. Rejections flow into `CapabilityUnsatisfiableError.
207
+ * reasons[].rejectingProviders[].reason` — consumers can switch on
208
+ * `code` to route on specific failure modes.
209
+ */
210
+ function matchRequirement(req, t) {
211
+ const meta = t.provider.metadata;
212
+ const model = t.model;
213
+ if ('feature' in req) {
214
+ if (model.features.includes(req.feature))
215
+ return null;
216
+ return {
217
+ code: 'missing-feature',
218
+ message: `does not support feature "${req.feature}"`,
219
+ feature: req.feature,
220
+ };
221
+ }
222
+ if ('contextWindow' in req) {
223
+ if (compare(model.contextWindow, req.contextWindow.op, req.contextWindow.value))
224
+ return null;
225
+ return {
226
+ code: 'context-window-mismatch',
227
+ message: `contextWindow=${model.contextWindow} fails ${req.contextWindow.op}${req.contextWindow.value}`,
228
+ observed: model.contextWindow,
229
+ op: req.contextWindow.op,
230
+ wanted: req.contextWindow.value,
231
+ };
232
+ }
233
+ if ('costPerCall' in req) {
234
+ const proxy = model.cost.promptUsdPer1kTokens;
235
+ if (compare(proxy, req.costPerCall.op, req.costPerCall.usd))
236
+ return null;
237
+ return {
238
+ code: 'cost-exceeds-cap',
239
+ message: `promptCost=$${proxy}/1k fails ${req.costPerCall.op}$${req.costPerCall.usd}`,
240
+ observedUsdPer1k: proxy,
241
+ op: req.costPerCall.op,
242
+ wantedUsd: req.costPerCall.usd,
243
+ };
244
+ }
245
+ if ('region' in req) {
246
+ if (meta.region === req.region)
247
+ return null;
248
+ return {
249
+ code: 'region-mismatch',
250
+ message: `region "${meta.region}" != required "${req.region}"`,
251
+ observed: meta.region,
252
+ wanted: req.region,
253
+ };
254
+ }
255
+ if ('p95LatencyMs' in req) {
256
+ if (model.p95LatencyMs === undefined) {
257
+ return { code: 'p95-latency-unknown', message: 'model does not report p95 latency' };
258
+ }
259
+ if (compareUpperBound(model.p95LatencyMs, req.p95LatencyMs.op, req.p95LatencyMs.value))
260
+ return null;
261
+ return {
262
+ code: 'p95-latency-exceeds',
263
+ message: `p95Latency=${model.p95LatencyMs}ms fails ${req.p95LatencyMs.op}${req.p95LatencyMs.value}ms`,
264
+ observedMs: model.p95LatencyMs,
265
+ op: req.p95LatencyMs.op,
266
+ wantedMs: req.p95LatencyMs.value,
267
+ };
268
+ }
269
+ if ('providers' in req) {
270
+ if (req.providers.deny?.includes(meta.id) === true) {
271
+ return {
272
+ code: 'provider-on-denylist',
273
+ message: 'provider on deny list',
274
+ providerId: meta.id,
275
+ };
276
+ }
277
+ if (req.providers.allow !== undefined && !req.providers.allow.includes(meta.id)) {
278
+ return {
279
+ code: 'provider-not-in-allowlist',
280
+ message: 'provider not on allow list',
281
+ providerId: meta.id,
282
+ allow: req.providers.allow,
283
+ };
284
+ }
285
+ return null;
286
+ }
287
+ if ('models' in req) {
288
+ if (req.models.deny?.includes(model.name) === true) {
289
+ return {
290
+ code: 'model-on-denylist',
291
+ message: 'model on deny list',
292
+ modelName: model.name,
293
+ };
294
+ }
295
+ if (req.models.allow !== undefined && !req.models.allow.includes(model.name)) {
296
+ return {
297
+ code: 'model-not-in-allowlist',
298
+ message: 'model not on allow list',
299
+ modelName: model.name,
300
+ allow: req.models.allow,
301
+ };
302
+ }
303
+ return null;
304
+ }
305
+ return { code: 'unknown-requirement', message: 'unknown requirement shape' };
306
+ }
307
+ /**
308
+ * Compile tenant policy into synthetic requirements for the shared filter
309
+ * loop. An allow list that is present restricts even when empty: `[]`
310
+ * allows nothing (fail closed), the same as a capability requirement's
311
+ * allow list. An empty deny list denies nothing.
312
+ */
313
+ function tenantPolicyRequirements(policy) {
314
+ if (policy === undefined)
315
+ return [];
316
+ const out = [];
317
+ const providerDeny = policy.providers?.deny;
318
+ if (providerDeny !== undefined && providerDeny.length > 0) {
319
+ const deny = providerDeny;
320
+ out.push({
321
+ label: `tenant.providers.deny[${deny.join(',')}]`,
322
+ test: (t) => deny.includes(t.provider.metadata.id)
323
+ ? {
324
+ code: 'tenant-denied',
325
+ message: 'tenant policy deny',
326
+ providerId: t.provider.metadata.id,
327
+ }
328
+ : null,
329
+ });
330
+ }
331
+ const providerAllow = policy.providers?.allow;
332
+ if (providerAllow !== undefined) {
333
+ const allow = providerAllow;
334
+ out.push({
335
+ label: `tenant.providers.allow[${allow.join(',')}]`,
336
+ test: (t) => allow.includes(t.provider.metadata.id)
337
+ ? null
338
+ : {
339
+ code: 'tenant-not-allowed',
340
+ message: 'not on tenant allow list',
341
+ providerId: t.provider.metadata.id,
342
+ },
343
+ });
344
+ }
345
+ const modelDeny = policy.models?.deny;
346
+ if (modelDeny !== undefined && modelDeny.length > 0) {
347
+ const deny = modelDeny;
348
+ out.push({
349
+ label: `tenant.models.deny[${deny.join(',')}]`,
350
+ test: (t) => deny.includes(t.model.name)
351
+ ? {
352
+ code: 'tenant-model-denied',
353
+ message: 'tenant policy deny (model)',
354
+ modelName: t.model.name,
355
+ }
356
+ : null,
357
+ });
358
+ }
359
+ const modelAllow = policy.models?.allow;
360
+ if (modelAllow !== undefined) {
361
+ const allow = modelAllow;
362
+ out.push({
363
+ label: `tenant.models.allow[${allow.join(',')}]`,
364
+ test: (t) => allow.includes(t.model.name)
365
+ ? null
366
+ : {
367
+ code: 'tenant-model-not-allowed',
368
+ message: 'not on tenant model allow list',
369
+ modelName: t.model.name,
370
+ },
371
+ });
372
+ }
373
+ if (policy.regionAllow !== undefined) {
374
+ const regions = policy.regionAllow;
375
+ out.push({
376
+ label: `tenant.regionAllow[${regions.join(',')}]`,
377
+ test: (t) => regions.includes(t.provider.metadata.region)
378
+ ? null
379
+ : {
380
+ code: 'tenant-region-not-allowed',
381
+ message: `region "${t.provider.metadata.region}" not in tenant allow list`,
382
+ observed: t.provider.metadata.region,
383
+ allow: regions,
384
+ },
385
+ });
386
+ }
387
+ if (policy.maxCostPerCallUsd !== undefined) {
388
+ const cap = policy.maxCostPerCallUsd;
389
+ out.push({
390
+ label: `tenant.maxCostPerCallUsd<=${cap}`,
391
+ test: (t) => t.model.cost.promptUsdPer1kTokens <= cap
392
+ ? null
393
+ : {
394
+ code: 'tenant-cost-cap-exceeded',
395
+ message: `promptCost/1k=$${t.model.cost.promptUsdPer1kTokens} > tenant cap $${cap}`,
396
+ observedUsd: t.model.cost.promptUsdPer1kTokens,
397
+ capUsd: cap,
398
+ },
399
+ });
400
+ }
401
+ if (policy.maxTokensPerCall !== undefined) {
402
+ const cap = policy.maxTokensPerCall;
403
+ out.push({
404
+ label: `tenant.maxTokensPerCall<=${cap}`,
405
+ test: (t) => t.model.contextWindow >= cap
406
+ ? null
407
+ : {
408
+ // Reuse context-window-mismatch for tenant-side context caps.
409
+ code: 'context-window-mismatch',
410
+ message: `contextWindow=${t.model.contextWindow} < tenant cap ${cap}`,
411
+ observed: t.model.contextWindow,
412
+ op: '>=',
413
+ wanted: cap,
414
+ },
415
+ });
416
+ }
417
+ return out;
418
+ }
419
+ function compare(actual, op, target) {
420
+ switch (op) {
421
+ case '>=':
422
+ return actual >= target;
423
+ case '>':
424
+ return actual > target;
425
+ case '=':
426
+ return actual === target;
427
+ case '<=':
428
+ return actual <= target;
429
+ case '<':
430
+ return actual < target;
431
+ }
432
+ }
433
+ function compareUpperBound(actual, op, target) {
434
+ return op === '<=' ? actual <= target : actual < target;
435
+ }
436
+ function describeRequirement(req) {
437
+ if ('feature' in req)
438
+ return `feature:${req.feature}`;
439
+ if ('contextWindow' in req)
440
+ return `contextWindow${req.contextWindow.op}${req.contextWindow.value}`;
441
+ if ('costPerCall' in req)
442
+ return `costPerCall${req.costPerCall.op}$${req.costPerCall.usd}`;
443
+ if ('region' in req)
444
+ return `region=${req.region}`;
445
+ if ('p95LatencyMs' in req)
446
+ return `p95LatencyMs${req.p95LatencyMs.op}${req.p95LatencyMs.value}`;
447
+ if ('providers' in req) {
448
+ const allow = req.providers.allow?.join(',') ?? '';
449
+ const deny = req.providers.deny?.join(',') ?? '';
450
+ return `providers{allow:[${allow}]deny:[${deny}]}`;
451
+ }
452
+ if ('models' in req) {
453
+ const allow = req.models.allow?.join(',') ?? '';
454
+ const deny = req.models.deny?.join(',') ?? '';
455
+ return `models{allow:[${allow}]deny:[${deny}]}`;
456
+ }
457
+ return 'unknown';
458
+ }
459
+ function buildReason(t, input, fallback) {
460
+ const parts = [
461
+ `picked "${t.provider.metadata.id}"/"${t.model.name}"`,
462
+ `satisfies ${input.capability.needs.length} constraint(s)`,
463
+ ];
464
+ if (fallback)
465
+ parts.push('a fallback provider — no other registered provider satisfies it');
466
+ if (input.tenantPolicy !== undefined)
467
+ parts.push('respects tenant policy');
468
+ const prefs = input.capability.prefer;
469
+ if (prefs !== undefined && prefs.length > 0)
470
+ parts.push(`ranked top of ${prefs.length} preference(s)`);
471
+ return parts.join(', ');
472
+ }
473
+ function unsatisfiable(reasons, tenantPolicy) {
474
+ return {
475
+ kind: 'err',
476
+ error: {
477
+ code: 'capability-unsatisfiable',
478
+ message: 'No registered provider satisfies the capability declaration',
479
+ reasons,
480
+ ...(tenantPolicy !== undefined && { tenantId: tenantPolicy.tenantId }),
481
+ },
482
+ };
483
+ }
484
+ //# sourceMappingURL=router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.js","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"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"}