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.
- package/README.md +99 -44
- package/dist/capabilities/diagnostics.d.ts +75 -0
- package/dist/capabilities/diagnostics.d.ts.map +1 -1
- package/dist/capabilities/diagnostics.js.map +1 -1
- package/dist/capabilities/quota.d.ts +64 -1
- package/dist/capabilities/quota.d.ts.map +1 -1
- package/dist/capabilities/quota.js.map +1 -1
- package/dist/capabilities/vision.d.ts +4 -3
- package/dist/capabilities/vision.d.ts.map +1 -1
- package/dist/capabilities/vision.js +7 -5
- package/dist/capabilities/vision.js.map +1 -1
- package/dist/commands/code.d.ts +9 -1
- package/dist/commands/code.d.ts.map +1 -1
- package/dist/commands/code.js +4 -4
- package/dist/commands/code.js.map +1 -1
- package/dist/commands/crawl.d.ts.map +1 -1
- package/dist/commands/crawl.js +14 -3
- package/dist/commands/crawl.js.map +1 -1
- package/dist/commands/doctor.d.ts +71 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +96 -15
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/init.d.ts +186 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +1221 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/map.d.ts.map +1 -1
- package/dist/commands/map.js +16 -3
- package/dist/commands/map.js.map +1 -1
- package/dist/commands/quota.d.ts +32 -0
- package/dist/commands/quota.d.ts.map +1 -1
- package/dist/commands/quota.js +165 -24
- package/dist/commands/quota.js.map +1 -1
- package/dist/commands/read.d.ts.map +1 -1
- package/dist/commands/read.js +9 -3
- package/dist/commands/read.js.map +1 -1
- package/dist/commands/repo.d.ts.map +1 -1
- package/dist/commands/repo.js +5 -3
- package/dist/commands/repo.js.map +1 -1
- package/dist/commands/research.d.ts +35 -7
- package/dist/commands/research.d.ts.map +1 -1
- package/dist/commands/research.js +93 -15
- package/dist/commands/research.js.map +1 -1
- package/dist/commands/tools.d.ts +8 -0
- package/dist/commands/tools.d.ts.map +1 -1
- package/dist/commands/tools.js +4 -4
- package/dist/commands/tools.js.map +1 -1
- package/dist/commands/vision.d.ts +10 -0
- package/dist/commands/vision.d.ts.map +1 -1
- package/dist/commands/vision.js +25 -2
- package/dist/commands/vision.js.map +1 -1
- package/dist/index.d.ts +136 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +894 -298
- package/dist/index.js.map +1 -1
- package/dist/lib/api-client.d.ts +1 -1
- package/dist/lib/api-client.d.ts.map +1 -1
- package/dist/lib/api-client.js +6 -2
- package/dist/lib/api-client.js.map +1 -1
- package/dist/lib/cache.d.ts +9 -2
- package/dist/lib/cache.d.ts.map +1 -1
- package/dist/lib/cache.js +9 -2
- package/dist/lib/cache.js.map +1 -1
- package/dist/lib/code-mode.d.ts +8 -0
- package/dist/lib/code-mode.d.ts.map +1 -1
- package/dist/lib/code-mode.js +3 -1
- package/dist/lib/code-mode.js.map +1 -1
- package/dist/lib/config-store.d.ts +165 -0
- package/dist/lib/config-store.d.ts.map +1 -0
- package/dist/lib/config-store.js +332 -0
- package/dist/lib/config-store.js.map +1 -0
- package/dist/lib/config.d.ts +2 -2
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +19 -11
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/consumption.d.ts +144 -0
- package/dist/lib/consumption.d.ts.map +1 -0
- package/dist/lib/consumption.js +161 -0
- package/dist/lib/consumption.js.map +1 -0
- package/dist/lib/errors.d.ts +11 -0
- package/dist/lib/errors.d.ts.map +1 -1
- package/dist/lib/errors.js +14 -0
- package/dist/lib/errors.js.map +1 -1
- package/dist/lib/execution.d.ts +32 -4
- package/dist/lib/execution.d.ts.map +1 -1
- package/dist/lib/execution.js +156 -13
- package/dist/lib/execution.js.map +1 -1
- package/dist/lib/mcp-client.d.ts +12 -0
- package/dist/lib/mcp-client.d.ts.map +1 -1
- package/dist/lib/mcp-client.js +16 -7
- package/dist/lib/mcp-client.js.map +1 -1
- package/dist/lib/mcp-config.d.ts +10 -0
- package/dist/lib/mcp-config.d.ts.map +1 -1
- package/dist/lib/mcp-config.js +13 -7
- package/dist/lib/mcp-config.js.map +1 -1
- package/dist/lib/monitor-client.d.ts +19 -3
- package/dist/lib/monitor-client.d.ts.map +1 -1
- package/dist/lib/monitor-client.js +21 -5
- package/dist/lib/monitor-client.js.map +1 -1
- package/dist/lib/provider-fallback.d.ts +150 -0
- package/dist/lib/provider-fallback.d.ts.map +1 -0
- package/dist/lib/provider-fallback.js +510 -0
- package/dist/lib/provider-fallback.js.map +1 -0
- package/dist/lib/quota-mapping.d.ts +402 -0
- package/dist/lib/quota-mapping.d.ts.map +1 -0
- package/dist/lib/quota-mapping.js +539 -0
- package/dist/lib/quota-mapping.js.map +1 -0
- package/dist/lib/quota-store.d.ts +271 -0
- package/dist/lib/quota-store.d.ts.map +1 -0
- package/dist/lib/quota-store.js +540 -0
- package/dist/lib/quota-store.js.map +1 -0
- package/dist/lib/trigger-detection.d.ts +149 -0
- package/dist/lib/trigger-detection.d.ts.map +1 -0
- package/dist/lib/trigger-detection.js +149 -0
- package/dist/lib/trigger-detection.js.map +1 -0
- package/dist/lib/tty.d.ts +8 -1
- package/dist/lib/tty.d.ts.map +1 -1
- package/dist/lib/tty.js +53 -1
- package/dist/lib/tty.js.map +1 -1
- package/dist/providers/brave/adapter.d.ts +26 -0
- package/dist/providers/brave/adapter.d.ts.map +1 -1
- package/dist/providers/brave/adapter.js +66 -4
- package/dist/providers/brave/adapter.js.map +1 -1
- package/dist/providers/brave/client.d.ts +46 -2
- package/dist/providers/brave/client.d.ts.map +1 -1
- package/dist/providers/brave/client.js +55 -3
- package/dist/providers/brave/client.js.map +1 -1
- package/dist/providers/exa/adapter.d.ts.map +1 -1
- package/dist/providers/exa/adapter.js +10 -1
- package/dist/providers/exa/adapter.js.map +1 -1
- package/dist/providers/firecrawl/adapter.d.ts.map +1 -1
- package/dist/providers/firecrawl/adapter.js +13 -3
- package/dist/providers/firecrawl/adapter.js.map +1 -1
- package/dist/providers/minimax/adapter.d.ts.map +1 -1
- package/dist/providers/minimax/adapter.js +4 -0
- package/dist/providers/minimax/adapter.js.map +1 -1
- package/dist/providers/selection.d.ts +114 -1
- package/dist/providers/selection.d.ts.map +1 -1
- package/dist/providers/selection.js +99 -3
- package/dist/providers/selection.js.map +1 -1
- package/dist/providers/tavily/adapter.d.ts.map +1 -1
- package/dist/providers/tavily/adapter.js +2 -0
- package/dist/providers/tavily/adapter.js.map +1 -1
- package/dist/providers/types.d.ts +33 -1
- package/dist/providers/types.d.ts.map +1 -1
- package/dist/providers/types.js +8 -0
- package/dist/providers/types.js.map +1 -1
- package/dist/providers/zai/adapter.d.ts.map +1 -1
- package/dist/providers/zai/adapter.js +18 -5
- package/dist/providers/zai/adapter.js.map +1 -1
- 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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"}
|