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,402 @@
|
|
|
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 type { ProviderCapability, ProviderId } from "../providers/types.js";
|
|
54
|
+
import type { QuotaState } from "./quota-store.js";
|
|
55
|
+
/**
|
|
56
|
+
* The authority-aware score for a single `(provider, capability)` pair.
|
|
57
|
+
*
|
|
58
|
+
* - `authority: "known"` — the provider exposes a real credit/token
|
|
59
|
+
* signal and the mapped category was found in the snapshot. `score`
|
|
60
|
+
* is the category's `current.remainingPercent` (already normalized
|
|
61
|
+
* 0..100 by PB-T1). `category` is the matched category name (after
|
|
62
|
+
* alias resolution / fallback), so PB-T4 can surface which pool was
|
|
63
|
+
* ranked.
|
|
64
|
+
* - `authority: "unknown"` — no authoritative signal is available
|
|
65
|
+
* (provider has no spend quota; snapshot missing; mapped category
|
|
66
|
+
* absent and no fallback matched; percent corrupt). `reason` is a
|
|
67
|
+
* stable, machine-readable reason code, NOT a user-facing message.
|
|
68
|
+
* Unknown entries are eligible as fallback but never win over a
|
|
69
|
+
* known-scored provider (PB-T4 contract).
|
|
70
|
+
*
|
|
71
|
+
* `unknown` is NEVER encoded as a numeric score (no neutral `50`, no
|
|
72
|
+
* `Infinity`, no `0`). This is the explicit fix for the "neutral 50 yet
|
|
73
|
+
* never fullest" contradiction flagged in review item 12: authority is
|
|
74
|
+
* a separate axis from score, and PB-T4 sorts the two tiers
|
|
75
|
+
* independently.
|
|
76
|
+
*/
|
|
77
|
+
export type CapabilityScore = {
|
|
78
|
+
readonly authority: "known";
|
|
79
|
+
readonly score: number;
|
|
80
|
+
readonly category: string;
|
|
81
|
+
} | {
|
|
82
|
+
readonly authority: "unknown";
|
|
83
|
+
readonly reason: UnknownScoreReason;
|
|
84
|
+
};
|
|
85
|
+
/**
|
|
86
|
+
* Machine-readable reason for an unknown score. Stable across releases
|
|
87
|
+
* so callers (PB-T4, dashboards) can branch without parsing prose. The
|
|
88
|
+
* matching human-readable text lives in the warning metadata.
|
|
89
|
+
*/
|
|
90
|
+
export type UnknownScoreReason =
|
|
91
|
+
/**
|
|
92
|
+
* The provider is in the always-unknown authority tier by policy
|
|
93
|
+
* (Brave rate-limit, Exa no quota capability). No category lookup
|
|
94
|
+
* is attempted.
|
|
95
|
+
*/
|
|
96
|
+
"PROVIDER_NON_AUTHORITATIVE"
|
|
97
|
+
/**
|
|
98
|
+
* No mapping entry exists for `(provider, capability)`. Either the
|
|
99
|
+
* capability is observational (`quota`/`diagnostics`) or the
|
|
100
|
+
* mapping table has a gap (ticket: add a row + warn).
|
|
101
|
+
*/
|
|
102
|
+
| "MAPPING_MISSING"
|
|
103
|
+
/**
|
|
104
|
+
* The provider has no snapshot in {@link QuotaState} (never
|
|
105
|
+
* harvested, or the entry was cleared).
|
|
106
|
+
*/
|
|
107
|
+
| "SNAPSHOT_MISSING"
|
|
108
|
+
/**
|
|
109
|
+
* The snapshot exists but its `categories` array is empty.
|
|
110
|
+
*/
|
|
111
|
+
| "SNAPSHOT_EMPTY"
|
|
112
|
+
/**
|
|
113
|
+
* None of the mapped aliases matched a category, and no
|
|
114
|
+
* provider-level fallback matched either. Likely provider-side
|
|
115
|
+
* rename (drift).
|
|
116
|
+
*/
|
|
117
|
+
| "CATEGORY_NOT_FOUND"
|
|
118
|
+
/**
|
|
119
|
+
* The matched category's `remainingPercent` is not a finite number
|
|
120
|
+
* in 0..100. PB-T1's `buildQuotaWindow` is supposed to guarantee
|
|
121
|
+
* this, but a hand-edited `state.json` could violate it; the scorer
|
|
122
|
+
* treats corrupt input as unknown rather than synthesizing a score.
|
|
123
|
+
*/
|
|
124
|
+
| "PERCENT_CORRUPT";
|
|
125
|
+
/**
|
|
126
|
+
* One row of the static mapping table: for `(provider, capability)`,
|
|
127
|
+
* which raw `QuotaCategory.name` governs the score.
|
|
128
|
+
*
|
|
129
|
+
* `categoryAliases` is an **ordered** list of acceptable category names.
|
|
130
|
+
* The first alias that matches a category in the live snapshot wins.
|
|
131
|
+
* This is the fail-open seam: when a provider renames a category, the
|
|
132
|
+
* lookup silently misses and the scorer degrades to the
|
|
133
|
+
* `providerFallbackCategory` (if any), then to unknown. Drift is
|
|
134
|
+
* surfaced through a structured warning.
|
|
135
|
+
*
|
|
136
|
+
* Case-sensitivity follows the existing normalizers: Tavily emits
|
|
137
|
+
* lowercase endpoint names (`search`, `crawl`, ...), Z.AI emits
|
|
138
|
+
* `requests`/`tokens`, Firecrawl emits a case-sensitive `Credits`. The
|
|
139
|
+
* alias list must match the normalizer's exact emission; do not
|
|
140
|
+
* case-fold here or the mapping will hide drift.
|
|
141
|
+
*/
|
|
142
|
+
export interface CapabilityMappingEntry {
|
|
143
|
+
readonly provider: ProviderId;
|
|
144
|
+
readonly capability: ProviderCapability;
|
|
145
|
+
readonly categoryAliases: readonly string[];
|
|
146
|
+
/**
|
|
147
|
+
* Optional provider-level category used when no alias matches.
|
|
148
|
+
* For Tavily, this is the aggregate `requests` category — every
|
|
149
|
+
* endpoint shares one credit pool, so a missing endpoint category
|
|
150
|
+
* degrades to the pool-level remaining. For providers with one
|
|
151
|
+
* category per capability (Z.AI, Firecrawl), this is intentionally
|
|
152
|
+
* absent: a missing category means real drift, not a graceful
|
|
153
|
+
* fallback target.
|
|
154
|
+
*/
|
|
155
|
+
readonly providerFallbackCategory?: string;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Default MiniMax model-name aliases per capability. MiniMax's
|
|
159
|
+
* `/remains` normalizer emits one category per live `model_name`
|
|
160
|
+
* string, and `model_name` values are arbitrary (the live schema does
|
|
161
|
+
* NOT emit a stable `general` label — see ticket
|
|
162
|
+
* `tests/quota-conformance.test.js:310-370` and fixtures including
|
|
163
|
+
* `zorla-x` and `abab6.5s-chat`). This table is the documented
|
|
164
|
+
* mapping policy: the first alias that matches a live category wins.
|
|
165
|
+
*
|
|
166
|
+
* Tests and PB-T4 callers can override this table via
|
|
167
|
+
* {@link ScoreOptions.minimaxModelAliases} when a deployment uses
|
|
168
|
+
* a different model name. Fail-open applies: an empty match degrades
|
|
169
|
+
* to unknown + warn, never a throw.
|
|
170
|
+
*/
|
|
171
|
+
export declare const DEFAULT_MINIMAX_MODEL_ALIASES: Readonly<Record<"search" | "vision.interpret-image", readonly string[]>>;
|
|
172
|
+
/**
|
|
173
|
+
* The full Vision capability set advertised by Z.AI, plus the
|
|
174
|
+
* specialized operations MiniMax may attest. They all share the same
|
|
175
|
+
* category mapping within their provider (Z.AI → `tokens`, MiniMax →
|
|
176
|
+
* the VLM model alias), so the table is generated from one constant
|
|
177
|
+
* list per provider to keep the rows in sync.
|
|
178
|
+
*/
|
|
179
|
+
export declare const ZAI_VISION_CAPABILITIES: readonly ProviderCapability[];
|
|
180
|
+
/**
|
|
181
|
+
* Specialized MiniMax Vision operations (mirror of the descriptor's
|
|
182
|
+
* attested set). They all share the VLM model alias.
|
|
183
|
+
*/
|
|
184
|
+
export declare const MINIMAX_VISION_CAPABILITIES: readonly ProviderCapability[];
|
|
185
|
+
/**
|
|
186
|
+
* Z.AI capabilities that share the rolling `requests` category.
|
|
187
|
+
* `quota` and `diagnostics` are intentionally absent — they are
|
|
188
|
+
* observational, not selection candidates.
|
|
189
|
+
*/
|
|
190
|
+
export declare const ZAI_REQUEST_CAPABILITIES: readonly ProviderCapability[];
|
|
191
|
+
/**
|
|
192
|
+
* Tavily endpoint-mapped capabilities. Each maps to a same-named
|
|
193
|
+
* endpoint category with a fallback to the aggregate `requests`
|
|
194
|
+
* pool (every Tavily endpoint bills against one credit pool).
|
|
195
|
+
*/
|
|
196
|
+
export declare const TAVILY_ENDPOINT_CAPABILITIES: readonly ProviderCapability[];
|
|
197
|
+
/**
|
|
198
|
+
* Tavily `(capability → endpoint category name)` resolution. `reader`
|
|
199
|
+
* is mapped to the `extract` endpoint (the Tavily `/extract` endpoint
|
|
200
|
+
* serves reader calls). Other capabilities map to the same-named
|
|
201
|
+
* endpoint category.
|
|
202
|
+
*/
|
|
203
|
+
export declare const TAVILY_CAPABILITY_TO_ENDPOINT: Readonly<Record<ProviderCapability, string | undefined>>;
|
|
204
|
+
/**
|
|
205
|
+
* Firecrawl capabilities. All four consume the shared `Credits` pool.
|
|
206
|
+
*/
|
|
207
|
+
export declare const FIRECRAWL_CREDIT_CAPABILITIES: readonly ProviderCapability[];
|
|
208
|
+
/**
|
|
209
|
+
* The static capability→category mapping table. Built once at module
|
|
210
|
+
* load from the per-provider capability lists so a future capability
|
|
211
|
+
* addition only edits one constant, not 8 rows.
|
|
212
|
+
*
|
|
213
|
+
* Excluded by design:
|
|
214
|
+
* - Brave: always-unknown authority (rate-limit, not spend).
|
|
215
|
+
* - Exa: always-unknown authority (no quota capability).
|
|
216
|
+
* - `quota`/`diagnostics` on every provider: observational, not
|
|
217
|
+
* selection candidates.
|
|
218
|
+
*
|
|
219
|
+
* The table is `readonly` and exported so PB-T5/dashboards/Doctor can
|
|
220
|
+
* render the same source of truth the scorer uses.
|
|
221
|
+
*/
|
|
222
|
+
export declare const CAPABILITY_MAPPINGS: readonly CapabilityMappingEntry[];
|
|
223
|
+
/**
|
|
224
|
+
* Per-provider authority policy.
|
|
225
|
+
*
|
|
226
|
+
* - `"mapped"` — the provider exposes real credit/token signals; its
|
|
227
|
+
* categories map to capabilities via {@link CAPABILITY_MAPPINGS} and
|
|
228
|
+
* the score is the matched category's `remainingPercent`.
|
|
229
|
+
* - `"always-unknown"` — the provider has no authoritative spend
|
|
230
|
+
* signal. {@link CapabilityScore} always returns `authority:"unknown"`
|
|
231
|
+
* with the documented reason, regardless of whether a snapshot
|
|
232
|
+
* exists. The provider remains **eligible** for PB-T4 fallback, but
|
|
233
|
+
* it never wins over a known-scored provider.
|
|
234
|
+
*
|
|
235
|
+
* `reason` is surfaced unchanged through the warning channel when a
|
|
236
|
+
* score is requested for an always-unknown provider; it documents the
|
|
237
|
+
* policy for dashboards and Doctor.
|
|
238
|
+
*/
|
|
239
|
+
export interface ProviderAuthorityPolicy {
|
|
240
|
+
readonly provider: ProviderId;
|
|
241
|
+
readonly kind: "mapped" | "always-unknown";
|
|
242
|
+
readonly reason: string;
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* The static authority-policy table. Two providers are explicitly
|
|
246
|
+
* non-authoritative:
|
|
247
|
+
*
|
|
248
|
+
* - **Brave**: reports a rate-limit window via `X-RateLimit-*` headers,
|
|
249
|
+
* not spend or credits consumed. Brave uses metered billing, so the
|
|
250
|
+
* `remainingPercent` is a rate-limit signal, not a budget signal
|
|
251
|
+
* (see `BRAVE_QUOTA_CAVEAT` in `providers/brave/quota.ts`). The
|
|
252
|
+
* numeric window is retained for PB-T5 dashboard display; the
|
|
253
|
+
* authority axis deliberately ignores it.
|
|
254
|
+
* - **Exa**: advertises no `quota` capability at all. There is nothing
|
|
255
|
+
* to map or synthesize.
|
|
256
|
+
*
|
|
257
|
+
* Both providers stay **eligible** for PB-T4 fallback (their
|
|
258
|
+
* `authority:"unknown"` score sorts after every known provider), so
|
|
259
|
+
* they can still be picked when no known provider remains.
|
|
260
|
+
*/
|
|
261
|
+
export declare const PROVIDER_AUTHORITY_POLICIES: readonly ProviderAuthorityPolicy[];
|
|
262
|
+
/**
|
|
263
|
+
* A structured warning emitted by the scorer. The pure module never
|
|
264
|
+
* writes to stderr; it returns warnings through the
|
|
265
|
+
* {@link ScoreOptions.onWarning} callback so the caller (PB-T4 / main)
|
|
266
|
+
* owns the rendering surface.
|
|
267
|
+
*
|
|
268
|
+
* `code` is stable across releases so dashboards can de-duplicate.
|
|
269
|
+
* `message` is a single-line human-readable string suitable for stderr.
|
|
270
|
+
*/
|
|
271
|
+
export interface QuotaMappingWarning {
|
|
272
|
+
readonly code: "PROVIDER_NON_AUTHORITATIVE" | "MAPPING_MISSING" | "SNAPSHOT_MISSING" | "SNAPSHOT_EMPTY" | "CATEGORY_NOT_FOUND" | "PROVIDER_FALLBACK_USED" | "PERCENT_CORRUPT";
|
|
273
|
+
readonly provider: ProviderId;
|
|
274
|
+
readonly capability: ProviderCapability;
|
|
275
|
+
readonly message: string;
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Look up the authority policy for a provider. Returns `undefined`
|
|
279
|
+
* only if the registry learns a new provider ID without a corresponding
|
|
280
|
+
* policy row; the scorer treats undefined as `"always-unknown"` so an
|
|
281
|
+
* unmapped provider never accidentally wins.
|
|
282
|
+
*/
|
|
283
|
+
export declare function getProviderAuthorityPolicy(provider: ProviderId): ProviderAuthorityPolicy | undefined;
|
|
284
|
+
/**
|
|
285
|
+
* Look up the static mapping entry for `(provider, capability)`.
|
|
286
|
+
* Returns `undefined` when no row exists (observational capability,
|
|
287
|
+
* unknown capability, or a mapping-table gap).
|
|
288
|
+
*
|
|
289
|
+
* For MiniMax, the returned entry has an empty `categoryAliases`
|
|
290
|
+
* sentinel; the scorer expands it via
|
|
291
|
+
* {@link resolveMiniMaxAliasesForCapability}.
|
|
292
|
+
*/
|
|
293
|
+
export declare function getCapabilityMapping(provider: ProviderId, capability: ProviderCapability): CapabilityMappingEntry | undefined;
|
|
294
|
+
/**
|
|
295
|
+
* Resolve the MiniMax alias list for a capability. Search returns the
|
|
296
|
+
* `search` aliases; every MiniMax vision capability returns the
|
|
297
|
+
* `vision.interpret-image` aliases (they all share the VLM transport).
|
|
298
|
+
* Unknown capabilities return an empty list.
|
|
299
|
+
*/
|
|
300
|
+
export declare function resolveMiniMaxAliasesForCapability(capability: ProviderCapability, aliases?: Readonly<Record<"search" | "vision.interpret-image", readonly string[]>>): readonly string[];
|
|
301
|
+
/**
|
|
302
|
+
* Options for {@link scoreCapability} and {@link rankProvidersForCapability}.
|
|
303
|
+
*/
|
|
304
|
+
export interface ScoreOptions {
|
|
305
|
+
/**
|
|
306
|
+
* Override the MiniMax model-name alias table. Production uses
|
|
307
|
+
* {@link DEFAULT_MINIMAX_MODEL_ALIASES}; tests pass a tailored table
|
|
308
|
+
* to assert specific match paths.
|
|
309
|
+
*/
|
|
310
|
+
readonly minimaxModelAliases?: Readonly<Record<"search" | "vision.interpret-image", readonly string[]>>;
|
|
311
|
+
/**
|
|
312
|
+
* Best-effort warning sink. The scorer never calls
|
|
313
|
+
* `process.stderr.write`; every degradation routes through this
|
|
314
|
+
* callback. Caller owns the rendering surface. Production wires a
|
|
315
|
+
* stderr writer; tests inject a recorder.
|
|
316
|
+
*/
|
|
317
|
+
readonly onWarning?: (warning: QuotaMappingWarning) => void;
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Derive the authority-aware score for a single `(provider, capability)`
|
|
321
|
+
* pair from the persisted {@link QuotaState}.
|
|
322
|
+
*
|
|
323
|
+
* Resolution order:
|
|
324
|
+
* 1. **Authority policy.** An `always-unknown` provider returns
|
|
325
|
+
* `{ authority: "unknown", reason: "PROVIDER_NON_AUTHORITATIVE" }`
|
|
326
|
+
* without consulting the snapshot. This is the Brave/Exa contract.
|
|
327
|
+
* 2. **Mapping presence.** A `(provider, capability)` with no row in
|
|
328
|
+
* {@link CAPABILITY_MAPPINGS} returns `reason: "MAPPING_MISSING"`.
|
|
329
|
+
* Observational capabilities (`quota`/`diagnostics`) hit this path
|
|
330
|
+
* by design.
|
|
331
|
+
* 3. **Snapshot presence.** Missing snapshot → `SNAPSHOT_MISSING`;
|
|
332
|
+
* empty `categories` array → `SNAPSHOT_EMPTY`.
|
|
333
|
+
* 4. **Alias match.** Walk the entry's effective alias list (static
|
|
334
|
+
* for most providers; MiniMax resolves through the alias table).
|
|
335
|
+
* The first category whose name matches wins.
|
|
336
|
+
* 5. **Provider-level fallback.** When no alias matches and the entry
|
|
337
|
+
* declares a `providerFallbackCategory`, look it up. A match
|
|
338
|
+
* emits a `PROVIDER_FALLBACK_USED` warning so drift is visible.
|
|
339
|
+
* 6. **Unknown + warn.** No match at all → `CATEGORY_NOT_FOUND`.
|
|
340
|
+
* 7. **Percent validation.** A matched category whose
|
|
341
|
+
* `remainingPercent` is non-finite or outside 0..100 returns
|
|
342
|
+
* `PERCENT_CORRUPT`. PB-T1's `buildQuotaWindow` is supposed to
|
|
343
|
+
* guarantee this, but a hand-edited `state.json` could violate
|
|
344
|
+
* it; the scorer treats corrupt input as unknown rather than
|
|
345
|
+
* synthesizing a score.
|
|
346
|
+
*
|
|
347
|
+
* This function is total: it never throws. Every failure path returns
|
|
348
|
+
* a typed unknown score; the warning channel explains why.
|
|
349
|
+
*/
|
|
350
|
+
export declare function scoreCapability(state: QuotaState, provider: ProviderId, capability: ProviderCapability, options?: ScoreOptions): CapabilityScore;
|
|
351
|
+
/**
|
|
352
|
+
* A ranked provider entry. The order in the returned array is the
|
|
353
|
+
* selection order PB-T4 walks.
|
|
354
|
+
*
|
|
355
|
+
* - Known-tier entries appear first, sorted by `score` descending.
|
|
356
|
+
* Ties break by registry order (`PROVIDER_IDS` by default, or the
|
|
357
|
+
* `registryOrder` option).
|
|
358
|
+
* - Unknown-tier entries appear after every known entry, in registry
|
|
359
|
+
* order. They remain eligible as fallback.
|
|
360
|
+
*
|
|
361
|
+
* Optional fields are present only when meaningful: `score`/`category`
|
|
362
|
+
* for known entries; `reason` for unknown entries.
|
|
363
|
+
*/
|
|
364
|
+
export interface RankedProvider {
|
|
365
|
+
readonly provider: ProviderId;
|
|
366
|
+
readonly authority: "known" | "unknown";
|
|
367
|
+
readonly score?: number;
|
|
368
|
+
readonly category?: string;
|
|
369
|
+
readonly reason?: UnknownScoreReason;
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Rank candidate providers for a capability.
|
|
373
|
+
*
|
|
374
|
+
* Returns a new array (caller owns it). The ranking is deterministic
|
|
375
|
+
* for identical inputs: same `state` + same `candidates` + same
|
|
376
|
+
* `registryOrder` → byte-identical output order.
|
|
377
|
+
*
|
|
378
|
+
* Algorithm:
|
|
379
|
+
* 1. Score each candidate via {@link scoreCapability}.
|
|
380
|
+
* 2. Partition into known and unknown tiers.
|
|
381
|
+
* 3. Sort known tier by score desc; break ties by registry order.
|
|
382
|
+
* 4. Sort unknown tier by registry order only.
|
|
383
|
+
* 5. Concatenate: known first, then unknown.
|
|
384
|
+
*
|
|
385
|
+
* The "5% known beats unknown" contract falls out of steps 3–5: every
|
|
386
|
+
* known entry precedes every unknown entry regardless of score. A
|
|
387
|
+
* known provider at 5% remaining still ranks above a non-authoritative
|
|
388
|
+
* Brave/Exa provider, because Brave/Exa are in the unknown tier.
|
|
389
|
+
*
|
|
390
|
+
* Duplicate candidates are de-duplicated in first-occurrence order
|
|
391
|
+
* before scoring (defensive — PB-T4 builds candidate lists, and a
|
|
392
|
+
* duplicate would otherwise double-emit warnings).
|
|
393
|
+
*/
|
|
394
|
+
export declare function rankProvidersForCapability(state: QuotaState, capability: ProviderCapability, candidates: readonly ProviderId[], options?: ScoreOptions & {
|
|
395
|
+
/**
|
|
396
|
+
* Stable registry order for tie-breaking. Defaults to
|
|
397
|
+
* {@link PROVIDER_IDS} (the canonical production order
|
|
398
|
+
* `[zai, minimax, tavily, exa, brave, firecrawl]`).
|
|
399
|
+
*/
|
|
400
|
+
readonly registryOrder?: readonly ProviderId[];
|
|
401
|
+
}): readonly RankedProvider[];
|
|
402
|
+
//# sourceMappingURL=quota-mapping.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quota-mapping.d.ts","sourceRoot":"","sources":["../../src/lib/quota-mapping.ts"],"names":[],"mappings":"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"}
|