scoutline 0.10.2 → 0.12.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 (151) hide show
  1. package/README.md +99 -44
  2. package/dist/capabilities/diagnostics.d.ts +75 -0
  3. package/dist/capabilities/diagnostics.d.ts.map +1 -1
  4. package/dist/capabilities/diagnostics.js.map +1 -1
  5. package/dist/capabilities/quota.d.ts +64 -1
  6. package/dist/capabilities/quota.d.ts.map +1 -1
  7. package/dist/capabilities/quota.js.map +1 -1
  8. package/dist/capabilities/vision.d.ts +4 -3
  9. package/dist/capabilities/vision.d.ts.map +1 -1
  10. package/dist/capabilities/vision.js +7 -5
  11. package/dist/capabilities/vision.js.map +1 -1
  12. package/dist/commands/code.d.ts +9 -1
  13. package/dist/commands/code.d.ts.map +1 -1
  14. package/dist/commands/code.js +4 -4
  15. package/dist/commands/code.js.map +1 -1
  16. package/dist/commands/crawl.d.ts.map +1 -1
  17. package/dist/commands/crawl.js +14 -3
  18. package/dist/commands/crawl.js.map +1 -1
  19. package/dist/commands/doctor.d.ts +71 -1
  20. package/dist/commands/doctor.d.ts.map +1 -1
  21. package/dist/commands/doctor.js +96 -15
  22. package/dist/commands/doctor.js.map +1 -1
  23. package/dist/commands/init.d.ts +186 -0
  24. package/dist/commands/init.d.ts.map +1 -0
  25. package/dist/commands/init.js +1221 -0
  26. package/dist/commands/init.js.map +1 -0
  27. package/dist/commands/map.d.ts.map +1 -1
  28. package/dist/commands/map.js +16 -3
  29. package/dist/commands/map.js.map +1 -1
  30. package/dist/commands/quota.d.ts +32 -0
  31. package/dist/commands/quota.d.ts.map +1 -1
  32. package/dist/commands/quota.js +165 -24
  33. package/dist/commands/quota.js.map +1 -1
  34. package/dist/commands/read.d.ts.map +1 -1
  35. package/dist/commands/read.js +9 -3
  36. package/dist/commands/read.js.map +1 -1
  37. package/dist/commands/repo.d.ts.map +1 -1
  38. package/dist/commands/repo.js +5 -3
  39. package/dist/commands/repo.js.map +1 -1
  40. package/dist/commands/research.d.ts +35 -7
  41. package/dist/commands/research.d.ts.map +1 -1
  42. package/dist/commands/research.js +93 -15
  43. package/dist/commands/research.js.map +1 -1
  44. package/dist/commands/tools.d.ts +8 -0
  45. package/dist/commands/tools.d.ts.map +1 -1
  46. package/dist/commands/tools.js +4 -4
  47. package/dist/commands/tools.js.map +1 -1
  48. package/dist/commands/vision.d.ts +10 -0
  49. package/dist/commands/vision.d.ts.map +1 -1
  50. package/dist/commands/vision.js +25 -2
  51. package/dist/commands/vision.js.map +1 -1
  52. package/dist/index.d.ts +136 -1
  53. package/dist/index.d.ts.map +1 -1
  54. package/dist/index.js +894 -298
  55. package/dist/index.js.map +1 -1
  56. package/dist/lib/api-client.d.ts +1 -1
  57. package/dist/lib/api-client.d.ts.map +1 -1
  58. package/dist/lib/api-client.js +6 -2
  59. package/dist/lib/api-client.js.map +1 -1
  60. package/dist/lib/cache.d.ts +9 -2
  61. package/dist/lib/cache.d.ts.map +1 -1
  62. package/dist/lib/cache.js +9 -2
  63. package/dist/lib/cache.js.map +1 -1
  64. package/dist/lib/code-mode.d.ts +8 -0
  65. package/dist/lib/code-mode.d.ts.map +1 -1
  66. package/dist/lib/code-mode.js +3 -1
  67. package/dist/lib/code-mode.js.map +1 -1
  68. package/dist/lib/config-store.d.ts +165 -0
  69. package/dist/lib/config-store.d.ts.map +1 -0
  70. package/dist/lib/config-store.js +332 -0
  71. package/dist/lib/config-store.js.map +1 -0
  72. package/dist/lib/config.d.ts +2 -2
  73. package/dist/lib/config.d.ts.map +1 -1
  74. package/dist/lib/config.js +19 -11
  75. package/dist/lib/config.js.map +1 -1
  76. package/dist/lib/consumption.d.ts +144 -0
  77. package/dist/lib/consumption.d.ts.map +1 -0
  78. package/dist/lib/consumption.js +161 -0
  79. package/dist/lib/consumption.js.map +1 -0
  80. package/dist/lib/errors.d.ts +11 -0
  81. package/dist/lib/errors.d.ts.map +1 -1
  82. package/dist/lib/errors.js +14 -0
  83. package/dist/lib/errors.js.map +1 -1
  84. package/dist/lib/execution.d.ts +32 -4
  85. package/dist/lib/execution.d.ts.map +1 -1
  86. package/dist/lib/execution.js +156 -13
  87. package/dist/lib/execution.js.map +1 -1
  88. package/dist/lib/mcp-client.d.ts +12 -0
  89. package/dist/lib/mcp-client.d.ts.map +1 -1
  90. package/dist/lib/mcp-client.js +16 -7
  91. package/dist/lib/mcp-client.js.map +1 -1
  92. package/dist/lib/mcp-config.d.ts +10 -0
  93. package/dist/lib/mcp-config.d.ts.map +1 -1
  94. package/dist/lib/mcp-config.js +13 -7
  95. package/dist/lib/mcp-config.js.map +1 -1
  96. package/dist/lib/monitor-client.d.ts +19 -3
  97. package/dist/lib/monitor-client.d.ts.map +1 -1
  98. package/dist/lib/monitor-client.js +21 -5
  99. package/dist/lib/monitor-client.js.map +1 -1
  100. package/dist/lib/provider-fallback.d.ts +150 -0
  101. package/dist/lib/provider-fallback.d.ts.map +1 -0
  102. package/dist/lib/provider-fallback.js +510 -0
  103. package/dist/lib/provider-fallback.js.map +1 -0
  104. package/dist/lib/quota-mapping.d.ts +402 -0
  105. package/dist/lib/quota-mapping.d.ts.map +1 -0
  106. package/dist/lib/quota-mapping.js +539 -0
  107. package/dist/lib/quota-mapping.js.map +1 -0
  108. package/dist/lib/quota-store.d.ts +271 -0
  109. package/dist/lib/quota-store.d.ts.map +1 -0
  110. package/dist/lib/quota-store.js +540 -0
  111. package/dist/lib/quota-store.js.map +1 -0
  112. package/dist/lib/trigger-detection.d.ts +149 -0
  113. package/dist/lib/trigger-detection.d.ts.map +1 -0
  114. package/dist/lib/trigger-detection.js +149 -0
  115. package/dist/lib/trigger-detection.js.map +1 -0
  116. package/dist/lib/tty.d.ts +8 -1
  117. package/dist/lib/tty.d.ts.map +1 -1
  118. package/dist/lib/tty.js +53 -1
  119. package/dist/lib/tty.js.map +1 -1
  120. package/dist/providers/brave/adapter.d.ts +26 -0
  121. package/dist/providers/brave/adapter.d.ts.map +1 -1
  122. package/dist/providers/brave/adapter.js +66 -4
  123. package/dist/providers/brave/adapter.js.map +1 -1
  124. package/dist/providers/brave/client.d.ts +46 -2
  125. package/dist/providers/brave/client.d.ts.map +1 -1
  126. package/dist/providers/brave/client.js +55 -3
  127. package/dist/providers/brave/client.js.map +1 -1
  128. package/dist/providers/exa/adapter.d.ts.map +1 -1
  129. package/dist/providers/exa/adapter.js +10 -1
  130. package/dist/providers/exa/adapter.js.map +1 -1
  131. package/dist/providers/firecrawl/adapter.d.ts.map +1 -1
  132. package/dist/providers/firecrawl/adapter.js +13 -3
  133. package/dist/providers/firecrawl/adapter.js.map +1 -1
  134. package/dist/providers/minimax/adapter.d.ts.map +1 -1
  135. package/dist/providers/minimax/adapter.js +4 -0
  136. package/dist/providers/minimax/adapter.js.map +1 -1
  137. package/dist/providers/selection.d.ts +114 -1
  138. package/dist/providers/selection.d.ts.map +1 -1
  139. package/dist/providers/selection.js +99 -3
  140. package/dist/providers/selection.js.map +1 -1
  141. package/dist/providers/tavily/adapter.d.ts.map +1 -1
  142. package/dist/providers/tavily/adapter.js +2 -0
  143. package/dist/providers/tavily/adapter.js.map +1 -1
  144. package/dist/providers/types.d.ts +33 -1
  145. package/dist/providers/types.d.ts.map +1 -1
  146. package/dist/providers/types.js +8 -0
  147. package/dist/providers/types.js.map +1 -1
  148. package/dist/providers/zai/adapter.d.ts.map +1 -1
  149. package/dist/providers/zai/adapter.js +18 -5
  150. package/dist/providers/zai/adapter.js.map +1 -1
  151. package/package.json +2 -1
@@ -0,0 +1,539 @@
1
+ /**
2
+ * Quota normalization — capability/category mapping + authority-aware
3
+ * scoring (Plan B — PB-T3).
4
+ *
5
+ * Derives a remaining score per `(provider, capability)` from the **raw
6
+ * category snapshot** persisted by PB-T1, so PB-T4 can rank providers
7
+ * without learning any Provider's category schema. Pure derivation only:
8
+ * takes a {@link QuotaState} as input, returns scored/ranked results,
9
+ * never touches disk or transport.
10
+ *
11
+ * Two review fixes shape the contract:
12
+ *
13
+ * 1. **Map raw categories, not a pre-derived remaining.** Each Provider
14
+ * normalizes its native quota payload into named {@link QuotaCategory}
15
+ * entries (PB-T1). This module declares which category name governs
16
+ * which `(provider, capability)` pair, then reads that category's
17
+ * `current.remainingPercent` as the score. The score is already
18
+ * normalized 0..100 by `buildQuotaWindow`; this module does NOT
19
+ * re-derive or re-clamp.
20
+ *
21
+ * 2. **Separate authority from score.** The "neutral 50 yet never
22
+ * fullest" contradiction is resolved by representing unknown
23
+ * authority explicitly rather than encoding it as a numeric score.
24
+ * Providers with a real credit/token signal form a **known tier**,
25
+ * ranked by score; providers without a signal (Brave rate-limit,
26
+ * Exa none) form an **unknown tier**, ranked after every known
27
+ * provider. The unknown tier never wins over a known provider, even
28
+ * a low-scored one.
29
+ *
30
+ * Boundary rules:
31
+ * - Imports the quota contract types from `capabilities/quota.js`,
32
+ * provider identity/capability types from `providers/types.js`, and
33
+ * PB-T1's `QuotaState` from `lib/quota-store.js`. No provider
34
+ * transport, no command presentation, no `MainDependencies`.
35
+ * - **Pure module.** No disk I/O, no transport, no
36
+ * `process.stderr.write`. Warning output is returned to the caller
37
+ * through an `onWarning` callback; the scoring result itself never
38
+ * observes the outside world.
39
+ * - **Fail-open on drift.** If a mapped category name is absent from
40
+ * the live snapshot (provider renamed it), degrade to the
41
+ * provider-level fallback, then to **unknown** — never hard-fail.
42
+ * Each degradation emits a structured warning so drift is visible.
43
+ *
44
+ * Relation to other Plan B tickets:
45
+ * - PB-T1: this module reads `QuotaState` (the persisted snapshot);
46
+ * it does not write.
47
+ * - PB-T2: consumption events advance `locallyUpdatedAt` and adjust
48
+ * category estimates. This module reads the resulting category
49
+ * `current` window; the locally-decremented value is the score.
50
+ * - PB-T4: consumes `rankProvidersForCapability` and applies the
51
+ * selection algorithm. This module never selects.
52
+ */
53
+ import { PROVIDER_IDS } from "../providers/types.js";
54
+ /**
55
+ * Default MiniMax model-name aliases per capability. MiniMax's
56
+ * `/remains` normalizer emits one category per live `model_name`
57
+ * string, and `model_name` values are arbitrary (the live schema does
58
+ * NOT emit a stable `general` label — see ticket
59
+ * `tests/quota-conformance.test.js:310-370` and fixtures including
60
+ * `zorla-x` and `abab6.5s-chat`). This table is the documented
61
+ * mapping policy: the first alias that matches a live category wins.
62
+ *
63
+ * Tests and PB-T4 callers can override this table via
64
+ * {@link ScoreOptions.minimaxModelAliases} when a deployment uses
65
+ * a different model name. Fail-open applies: an empty match degrades
66
+ * to unknown + warn, never a throw.
67
+ */
68
+ export const DEFAULT_MINIMAX_MODEL_ALIASES = {
69
+ // MiniMax Coding Plan search endpoint (/v1/coding_plan/search) is
70
+ // served by the Coding Plan model. The fixture's `zorla-x` is the
71
+ // characterized representative; `MiniMax-Text-01` and `coding-plan`
72
+ // are documented alternates the live API has used. `general` is the
73
+ // policy label the original ticket named; it is intentionally last
74
+ // because the live schema does not emit it.
75
+ search: ["zorla-x", "MiniMax-Text-01", "coding-plan", "general"],
76
+ // MiniMax Coding Plan VLM endpoint (/v1/coding_plan/vlm) is served
77
+ // by the multimodal variant. `abab6.5-vl` and `MiniMax-VL-01` are
78
+ // documented; the fixture's `abab6.5s-chat` is included as a
79
+ // characterized fallback.
80
+ "vision.interpret-image": ["abab6.5-vl", "MiniMax-VL-01", "abab6.5s-chat", "vlm"],
81
+ };
82
+ /**
83
+ * The full Vision capability set advertised by Z.AI, plus the
84
+ * specialized operations MiniMax may attest. They all share the same
85
+ * category mapping within their provider (Z.AI → `tokens`, MiniMax →
86
+ * the VLM model alias), so the table is generated from one constant
87
+ * list per provider to keep the rows in sync.
88
+ */
89
+ export const ZAI_VISION_CAPABILITIES = [
90
+ "vision.interpret-image",
91
+ "vision.ui-artifact",
92
+ "vision.extract-text",
93
+ "vision.diagnose-error",
94
+ "vision.diagram",
95
+ "vision.chart",
96
+ "vision.diff",
97
+ "vision.video",
98
+ ];
99
+ /**
100
+ * Specialized MiniMax Vision operations (mirror of the descriptor's
101
+ * attested set). They all share the VLM model alias.
102
+ */
103
+ export const MINIMAX_VISION_CAPABILITIES = [
104
+ "vision.interpret-image",
105
+ "vision.ui-artifact",
106
+ "vision.extract-text",
107
+ "vision.diagnose-error",
108
+ "vision.diagram",
109
+ "vision.chart",
110
+ ];
111
+ /**
112
+ * Z.AI capabilities that share the rolling `requests` category.
113
+ * `quota` and `diagnostics` are intentionally absent — they are
114
+ * observational, not selection candidates.
115
+ */
116
+ export const ZAI_REQUEST_CAPABILITIES = [
117
+ "search",
118
+ "reader",
119
+ "repository-exploration",
120
+ ];
121
+ /**
122
+ * Tavily endpoint-mapped capabilities. Each maps to a same-named
123
+ * endpoint category with a fallback to the aggregate `requests`
124
+ * pool (every Tavily endpoint bills against one credit pool).
125
+ */
126
+ export const TAVILY_ENDPOINT_CAPABILITIES = [
127
+ "search",
128
+ "reader",
129
+ "crawl",
130
+ "map",
131
+ "research",
132
+ ];
133
+ /**
134
+ * Tavily `(capability → endpoint category name)` resolution. `reader`
135
+ * is mapped to the `extract` endpoint (the Tavily `/extract` endpoint
136
+ * serves reader calls). Other capabilities map to the same-named
137
+ * endpoint category.
138
+ */
139
+ export const TAVILY_CAPABILITY_TO_ENDPOINT = {
140
+ search: "search",
141
+ reader: "extract",
142
+ crawl: "crawl",
143
+ map: "map",
144
+ research: "research",
145
+ // Observational / non-Tavily capabilities are absent; the lookup
146
+ // returns undefined and the mapping loop skips them.
147
+ "vision.interpret-image": undefined,
148
+ "vision.ui-artifact": undefined,
149
+ "vision.extract-text": undefined,
150
+ "vision.diagnose-error": undefined,
151
+ "vision.diagram": undefined,
152
+ "vision.chart": undefined,
153
+ "vision.diff": undefined,
154
+ "vision.video": undefined,
155
+ quota: undefined,
156
+ diagnostics: undefined,
157
+ "repository-exploration": undefined,
158
+ };
159
+ /**
160
+ * Firecrawl capabilities. All four consume the shared `Credits` pool.
161
+ */
162
+ export const FIRECRAWL_CREDIT_CAPABILITIES = [
163
+ "search",
164
+ "reader",
165
+ "crawl",
166
+ "map",
167
+ ];
168
+ /**
169
+ * The static capability→category mapping table. Built once at module
170
+ * load from the per-provider capability lists so a future capability
171
+ * addition only edits one constant, not 8 rows.
172
+ *
173
+ * Excluded by design:
174
+ * - Brave: always-unknown authority (rate-limit, not spend).
175
+ * - Exa: always-unknown authority (no quota capability).
176
+ * - `quota`/`diagnostics` on every provider: observational, not
177
+ * selection candidates.
178
+ *
179
+ * The table is `readonly` and exported so PB-T5/dashboards/Doctor can
180
+ * render the same source of truth the scorer uses.
181
+ */
182
+ export const CAPABILITY_MAPPINGS = [
183
+ // Z.AI — search/reader/repository share `requests`; vision ops share `tokens`.
184
+ ...ZAI_REQUEST_CAPABILITIES.map((capability) => ({
185
+ provider: "zai",
186
+ capability,
187
+ categoryAliases: ["requests"],
188
+ })),
189
+ ...ZAI_VISION_CAPABILITIES.map((capability) => ({
190
+ provider: "zai",
191
+ capability,
192
+ categoryAliases: ["tokens"],
193
+ })),
194
+ // MiniMax — search and vision ops resolve via the model alias table.
195
+ // The alias list is filled at scoring time from
196
+ // DEFAULT_MINIMAX_MODEL_ALIASES (or the injected override); the
197
+ // static table holds an empty alias list as a sentinel that the
198
+ // mapping EXISTS but resolves dynamically. The scorer knows to
199
+ // expand MiniMax rows via the alias table.
200
+ {
201
+ provider: "minimax",
202
+ capability: "search",
203
+ categoryAliases: [],
204
+ },
205
+ ...MINIMAX_VISION_CAPABILITIES.map((capability) => ({
206
+ provider: "minimax",
207
+ capability,
208
+ categoryAliases: [],
209
+ })),
210
+ // Tavily — endpoint category with aggregate `requests` fallback.
211
+ ...TAVILY_ENDPOINT_CAPABILITIES.map((capability) => ({
212
+ provider: "tavily",
213
+ capability,
214
+ categoryAliases: [TAVILY_CAPABILITY_TO_ENDPOINT[capability]],
215
+ providerFallbackCategory: "requests",
216
+ })),
217
+ // Firecrawl — every capability consumes the shared `Credits` pool.
218
+ ...FIRECRAWL_CREDIT_CAPABILITIES.map((capability) => ({
219
+ provider: "firecrawl",
220
+ capability,
221
+ categoryAliases: ["Credits"],
222
+ })),
223
+ ];
224
+ /**
225
+ * The static authority-policy table. Two providers are explicitly
226
+ * non-authoritative:
227
+ *
228
+ * - **Brave**: reports a rate-limit window via `X-RateLimit-*` headers,
229
+ * not spend or credits consumed. Brave uses metered billing, so the
230
+ * `remainingPercent` is a rate-limit signal, not a budget signal
231
+ * (see `BRAVE_QUOTA_CAVEAT` in `providers/brave/quota.ts`). The
232
+ * numeric window is retained for PB-T5 dashboard display; the
233
+ * authority axis deliberately ignores it.
234
+ * - **Exa**: advertises no `quota` capability at all. There is nothing
235
+ * to map or synthesize.
236
+ *
237
+ * Both providers stay **eligible** for PB-T4 fallback (their
238
+ * `authority:"unknown"` score sorts after every known provider), so
239
+ * they can still be picked when no known provider remains.
240
+ */
241
+ export const PROVIDER_AUTHORITY_POLICIES = [
242
+ { provider: "zai", kind: "mapped", reason: "Z.AI exposes TIME_LIMIT/TOKENS_LIMIT signals." },
243
+ {
244
+ provider: "minimax",
245
+ kind: "mapped",
246
+ reason: "MiniMax exposes per-model remaining counters.",
247
+ },
248
+ {
249
+ provider: "tavily",
250
+ kind: "mapped",
251
+ reason: "Tavily exposes per-endpoint and aggregate usage counts.",
252
+ },
253
+ {
254
+ provider: "firecrawl",
255
+ kind: "mapped",
256
+ reason: "Firecrawl exposes a credit-usage pool.",
257
+ },
258
+ {
259
+ provider: "brave",
260
+ kind: "always-unknown",
261
+ reason: "Brave quota reflects a rate-limit window (requests remaining this period), not spend or credits consumed.",
262
+ },
263
+ {
264
+ provider: "exa",
265
+ kind: "always-unknown",
266
+ reason: "Exa does not advertise a quota capability; no signal to map.",
267
+ },
268
+ ];
269
+ // ---------------------------------------------------------------------------
270
+ // Lookup helpers — pure, total
271
+ // ---------------------------------------------------------------------------
272
+ /**
273
+ * Look up the authority policy for a provider. Returns `undefined`
274
+ * only if the registry learns a new provider ID without a corresponding
275
+ * policy row; the scorer treats undefined as `"always-unknown"` so an
276
+ * unmapped provider never accidentally wins.
277
+ */
278
+ export function getProviderAuthorityPolicy(provider) {
279
+ return PROVIDER_AUTHORITY_POLICIES.find((p) => p.provider === provider);
280
+ }
281
+ /**
282
+ * Look up the static mapping entry for `(provider, capability)`.
283
+ * Returns `undefined` when no row exists (observational capability,
284
+ * unknown capability, or a mapping-table gap).
285
+ *
286
+ * For MiniMax, the returned entry has an empty `categoryAliases`
287
+ * sentinel; the scorer expands it via
288
+ * {@link resolveMiniMaxAliasesForCapability}.
289
+ */
290
+ export function getCapabilityMapping(provider, capability) {
291
+ return CAPABILITY_MAPPINGS.find((m) => m.provider === provider && m.capability === capability);
292
+ }
293
+ /**
294
+ * Resolve the MiniMax alias list for a capability. Search returns the
295
+ * `search` aliases; every MiniMax vision capability returns the
296
+ * `vision.interpret-image` aliases (they all share the VLM transport).
297
+ * Unknown capabilities return an empty list.
298
+ */
299
+ export function resolveMiniMaxAliasesForCapability(capability, aliases = DEFAULT_MINIMAX_MODEL_ALIASES) {
300
+ if (capability === "search")
301
+ return aliases.search;
302
+ if (MINIMAX_VISION_CAPABILITIES.includes(capability)) {
303
+ return aliases["vision.interpret-image"];
304
+ }
305
+ return [];
306
+ }
307
+ /**
308
+ * Resolve the effective alias list for a mapping entry. For non-MiniMax
309
+ * providers, returns the entry's static `categoryAliases`. For MiniMax,
310
+ * expands the alias table.
311
+ */
312
+ function resolveEffectiveAliases(entry, minimaxAliases) {
313
+ if (entry.provider === "minimax") {
314
+ return resolveMiniMaxAliasesForCapability(entry.capability, minimaxAliases);
315
+ }
316
+ return entry.categoryAliases;
317
+ }
318
+ function findCategoryByName(categories, name) {
319
+ for (const c of categories) {
320
+ if (c.name === name)
321
+ return c;
322
+ }
323
+ return undefined;
324
+ }
325
+ function isTrustworthyPercent(value) {
326
+ return typeof value === "number" && Number.isFinite(value) && value >= 0 && value <= 100;
327
+ }
328
+ /**
329
+ * Derive the authority-aware score for a single `(provider, capability)`
330
+ * pair from the persisted {@link QuotaState}.
331
+ *
332
+ * Resolution order:
333
+ * 1. **Authority policy.** An `always-unknown` provider returns
334
+ * `{ authority: "unknown", reason: "PROVIDER_NON_AUTHORITATIVE" }`
335
+ * without consulting the snapshot. This is the Brave/Exa contract.
336
+ * 2. **Mapping presence.** A `(provider, capability)` with no row in
337
+ * {@link CAPABILITY_MAPPINGS} returns `reason: "MAPPING_MISSING"`.
338
+ * Observational capabilities (`quota`/`diagnostics`) hit this path
339
+ * by design.
340
+ * 3. **Snapshot presence.** Missing snapshot → `SNAPSHOT_MISSING`;
341
+ * empty `categories` array → `SNAPSHOT_EMPTY`.
342
+ * 4. **Alias match.** Walk the entry's effective alias list (static
343
+ * for most providers; MiniMax resolves through the alias table).
344
+ * The first category whose name matches wins.
345
+ * 5. **Provider-level fallback.** When no alias matches and the entry
346
+ * declares a `providerFallbackCategory`, look it up. A match
347
+ * emits a `PROVIDER_FALLBACK_USED` warning so drift is visible.
348
+ * 6. **Unknown + warn.** No match at all → `CATEGORY_NOT_FOUND`.
349
+ * 7. **Percent validation.** A matched category whose
350
+ * `remainingPercent` is non-finite or outside 0..100 returns
351
+ * `PERCENT_CORRUPT`. PB-T1's `buildQuotaWindow` is supposed to
352
+ * guarantee this, but a hand-edited `state.json` could violate
353
+ * it; the scorer treats corrupt input as unknown rather than
354
+ * synthesizing a score.
355
+ *
356
+ * This function is total: it never throws. Every failure path returns
357
+ * a typed unknown score; the warning channel explains why.
358
+ */
359
+ export function scoreCapability(state, provider, capability, options = {}) {
360
+ const onWarning = options.onWarning ?? (() => { });
361
+ const minimaxAliases = options.minimaxModelAliases ?? DEFAULT_MINIMAX_MODEL_ALIASES;
362
+ // 1. Authority policy gate.
363
+ const policy = getProviderAuthorityPolicy(provider);
364
+ if (!policy || policy.kind === "always-unknown") {
365
+ onWarning({
366
+ code: "PROVIDER_NON_AUTHORITATIVE",
367
+ provider,
368
+ capability,
369
+ message: `${provider} is non-authoritative for quota scoring (${policy?.reason ?? "no policy"}); treated as unknown tier.`,
370
+ });
371
+ return { authority: "unknown", reason: "PROVIDER_NON_AUTHORITATIVE" };
372
+ }
373
+ // 2. Mapping presence.
374
+ const entry = getCapabilityMapping(provider, capability);
375
+ if (!entry) {
376
+ onWarning({
377
+ code: "MAPPING_MISSING",
378
+ provider,
379
+ capability,
380
+ message: `No quota mapping for (${provider}, ${capability}); treat as unknown or add a mapping row.`,
381
+ });
382
+ return { authority: "unknown", reason: "MAPPING_MISSING" };
383
+ }
384
+ // 3. Snapshot presence.
385
+ const snapshot = state.quota[provider];
386
+ if (!snapshot) {
387
+ onWarning({
388
+ code: "SNAPSHOT_MISSING",
389
+ provider,
390
+ capability,
391
+ message: `No quota snapshot for ${provider}; scoring degrades to unknown tier.`,
392
+ });
393
+ return { authority: "unknown", reason: "SNAPSHOT_MISSING" };
394
+ }
395
+ const categories = snapshot.categories;
396
+ if (categories.length === 0) {
397
+ onWarning({
398
+ code: "SNAPSHOT_EMPTY",
399
+ provider,
400
+ capability,
401
+ message: `Quota snapshot for ${provider} has no categories; scoring degrades to unknown tier.`,
402
+ });
403
+ return { authority: "unknown", reason: "SNAPSHOT_EMPTY" };
404
+ }
405
+ // 4. Alias match.
406
+ const aliases = resolveEffectiveAliases(entry, minimaxAliases);
407
+ let matched;
408
+ for (const alias of aliases) {
409
+ const found = findCategoryByName(categories, alias);
410
+ if (found) {
411
+ matched = found;
412
+ break;
413
+ }
414
+ }
415
+ // 5. Provider-level fallback.
416
+ if (!matched && entry.providerFallbackCategory) {
417
+ matched = findCategoryByName(categories, entry.providerFallbackCategory);
418
+ if (matched) {
419
+ onWarning({
420
+ code: "PROVIDER_FALLBACK_USED",
421
+ provider,
422
+ capability,
423
+ message: `(${provider}, ${capability}) mapped category not found; using provider fallback "${matched.name}".`,
424
+ });
425
+ }
426
+ }
427
+ // 6. Unknown + warn.
428
+ if (!matched) {
429
+ onWarning({
430
+ code: "CATEGORY_NOT_FOUND",
431
+ provider,
432
+ capability,
433
+ message: `(${provider}, ${capability}) mapped category not found in snapshot (aliases: [${aliases.join(", ")}]${entry.providerFallbackCategory ? `, fallback: "${entry.providerFallbackCategory}"` : ""}); likely provider-side rename.`,
434
+ });
435
+ return { authority: "unknown", reason: "CATEGORY_NOT_FOUND" };
436
+ }
437
+ // 7. Percent validation. PB-T1 should guarantee finite 0..100, but
438
+ // a hand-edited state.json could violate the contract; treat corrupt
439
+ // input as unknown rather than letting NaN/Infinity pollute ranking.
440
+ const percent = matched.current?.remainingPercent;
441
+ if (!isTrustworthyPercent(percent)) {
442
+ onWarning({
443
+ code: "PERCENT_CORRUPT",
444
+ provider,
445
+ capability,
446
+ message: `(${provider}, ${capability}) category "${matched.name}" has corrupt remainingPercent (${String(percent)}); treated as unknown.`,
447
+ });
448
+ return { authority: "unknown", reason: "PERCENT_CORRUPT" };
449
+ }
450
+ return {
451
+ authority: "known",
452
+ score: percent,
453
+ category: matched.name,
454
+ };
455
+ }
456
+ /**
457
+ * Rank candidate providers for a capability.
458
+ *
459
+ * Returns a new array (caller owns it). The ranking is deterministic
460
+ * for identical inputs: same `state` + same `candidates` + same
461
+ * `registryOrder` → byte-identical output order.
462
+ *
463
+ * Algorithm:
464
+ * 1. Score each candidate via {@link scoreCapability}.
465
+ * 2. Partition into known and unknown tiers.
466
+ * 3. Sort known tier by score desc; break ties by registry order.
467
+ * 4. Sort unknown tier by registry order only.
468
+ * 5. Concatenate: known first, then unknown.
469
+ *
470
+ * The "5% known beats unknown" contract falls out of steps 3–5: every
471
+ * known entry precedes every unknown entry regardless of score. A
472
+ * known provider at 5% remaining still ranks above a non-authoritative
473
+ * Brave/Exa provider, because Brave/Exa are in the unknown tier.
474
+ *
475
+ * Duplicate candidates are de-duplicated in first-occurrence order
476
+ * before scoring (defensive — PB-T4 builds candidate lists, and a
477
+ * duplicate would otherwise double-emit warnings).
478
+ */
479
+ export function rankProvidersForCapability(state, capability, candidates, options = {}) {
480
+ const registryOrder = options.registryOrder ?? PROVIDER_IDS;
481
+ const orderRank = new Map();
482
+ for (let i = 0; i < registryOrder.length; i++) {
483
+ orderRank.set(registryOrder[i], i);
484
+ }
485
+ // Providers absent from the supplied registryOrder sort after every
486
+ // known entry, preserving first-occurrence order via a large offset.
487
+ const unknownRank = registryOrder.length;
488
+ // De-duplicate candidates (first occurrence wins) so a repeated
489
+ // provider does not double-emit warnings or appear twice in output.
490
+ const seen = new Set();
491
+ const unique = [];
492
+ for (const c of candidates) {
493
+ if (seen.has(c))
494
+ continue;
495
+ seen.add(c);
496
+ unique.push(c);
497
+ }
498
+ const staged = unique.map((provider, idx) => ({
499
+ provider,
500
+ score: scoreCapability(state, provider, capability, options),
501
+ orderRank: orderRank.get(provider) ?? unknownRank,
502
+ inputOrder: idx,
503
+ }));
504
+ const known = staged.filter((s) => s.score.authority === "known");
505
+ const unknown = staged.filter((s) => s.score.authority === "unknown");
506
+ // Known tier: score desc, registry order, then input order (stable).
507
+ known.sort((a, b) => {
508
+ const sa = a.score.score;
509
+ const sb = b.score.score;
510
+ if (sb !== sa)
511
+ return sb - sa;
512
+ if (a.orderRank !== b.orderRank)
513
+ return a.orderRank - b.orderRank;
514
+ return a.inputOrder - b.inputOrder;
515
+ });
516
+ // Unknown tier: registry order, then input order (stable).
517
+ unknown.sort((a, b) => {
518
+ if (a.orderRank !== b.orderRank)
519
+ return a.orderRank - b.orderRank;
520
+ return a.inputOrder - b.inputOrder;
521
+ });
522
+ const toRanked = (s) => {
523
+ if (s.score.authority === "known") {
524
+ return {
525
+ provider: s.provider,
526
+ authority: "known",
527
+ score: s.score.score,
528
+ category: s.score.category,
529
+ };
530
+ }
531
+ return {
532
+ provider: s.provider,
533
+ authority: "unknown",
534
+ reason: s.score.reason,
535
+ };
536
+ };
537
+ return [...known.map(toRanked), ...unknown.map(toRanked)];
538
+ }
539
+ //# sourceMappingURL=quota-mapping.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quota-mapping.js","sourceRoot":"","sources":["../../src/lib/quota-mapping.ts"],"names":[],"mappings":"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"}