@eddyskywalker/dsh-chatgpt-subscription 0.14.0 → 0.16.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/CHANGELOG.md +38 -0
- package/README.md +3 -0
- package/lib/client.js +69 -10
- package/lib/client.js.map +1 -1
- package/lib/index.js +567 -18
- package/lib/types/client/workbuddy/WorkBuddySection.d.ts +36 -0
- package/lib/types/client/workbuddy/WorkBuddySection.d.ts.map +1 -1
- package/lib/types/client/workbuddy/locales.d.ts +18 -0
- package/lib/types/client/workbuddy/locales.d.ts.map +1 -1
- package/lib/types/host/reasoning-collapse-guard/index.d.ts +166 -0
- package/lib/types/host/reasoning-collapse-guard/index.d.ts.map +1 -1
- package/lib/types/host/workbuddy/client.d.ts +9 -1
- package/lib/types/host/workbuddy/client.d.ts.map +1 -1
- package/lib/types/host/workbuddy/model-catalog.d.ts +107 -5
- package/lib/types/host/workbuddy/model-catalog.d.ts.map +1 -1
- package/lib/types/host/workbuddy/routes.d.ts +14 -1
- package/lib/types/host/workbuddy/routes.d.ts.map +1 -1
- package/lib/types/shared/workbuddy-contracts.d.ts +42 -0
- package/lib/types/shared/workbuddy-contracts.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -7,7 +7,43 @@
|
|
|
7
7
|
* behaviour is unchanged, and this one should stay render-shaped.
|
|
8
8
|
*/
|
|
9
9
|
import React from 'react';
|
|
10
|
+
import type { WorkBuddyModelCredits, WorkBuddyRegion } from '../../shared/workbuddy-contracts.ts';
|
|
10
11
|
import { type WorkBuddySectionProps } from './useWorkBuddySection.ts';
|
|
12
|
+
/**
|
|
13
|
+
* The consumption rate of one model, as the settings row states it.
|
|
14
|
+
*
|
|
15
|
+
* The gateway publishes one rate per region and the official CodeBuddy picker
|
|
16
|
+
* spells it beside a model as `6.67x`; the row uses the same shape behind the
|
|
17
|
+
* section's own label. Which rates reach the row depends on what the card knows
|
|
18
|
+
* about the account, and the two cases are deliberately different:
|
|
19
|
+
*
|
|
20
|
+
* - A KNOWN region shows that region's rate and nothing else. Borrowing the
|
|
21
|
+
* sibling region's number would state a price this account never pays —
|
|
22
|
+
* measured 2026-10-09, `deepseek-v4.1-flash` is `0.11` on cn against `0.00`
|
|
23
|
+
* on intl, and the backends reject a model asked of the wrong region anyway.
|
|
24
|
+
* - An UNKNOWN region (no account read back yet) shows both rates when the
|
|
25
|
+
* backends disagree, so the row is honest about the range instead of picking
|
|
26
|
+
* one of them. When they agree there is nothing to disambiguate.
|
|
27
|
+
*
|
|
28
|
+
* The two-region form is assembled entirely from the caller's labels: the
|
|
29
|
+
* qualifier comes from `labels.region(value, key)` and the join from
|
|
30
|
+
* `labels.pair(first, second)`, so the dictionary owns the region nouns, the
|
|
31
|
+
* bracket glyphs AND the separator. Nothing about the two-region string is
|
|
32
|
+
* spelled in this file, which is the point — the glyphs differ per language
|
|
33
|
+
* (`倍率 0.11x(国区) / 0.00x(国际区)` in Chinese,
|
|
34
|
+
* `Multiplier 0.11x (China) / 0.00x (International)` in English) and a
|
|
35
|
+
* separator chosen here would be right in at most one of them.
|
|
36
|
+
*
|
|
37
|
+
* `null` means "this row states no rate"; the caller drops it from the hint
|
|
38
|
+
* array rather than rendering a placeholder, because a guessed rate on a spend
|
|
39
|
+
* figure is worse than a missing one. `'0.00'` is a declaration — this model
|
|
40
|
+
* consumes no allowance — so it renders like any other value.
|
|
41
|
+
*/
|
|
42
|
+
export declare function creditMultiplierHint(credits: WorkBuddyModelCredits | undefined, region: WorkBuddyRegion | null, labels: {
|
|
43
|
+
multiplier: string;
|
|
44
|
+
region: (value: string, key: WorkBuddyRegion) => string;
|
|
45
|
+
pair: (first: string, second: string) => string;
|
|
46
|
+
}): string | null;
|
|
11
47
|
/** Mask a UIN so the card shows identity without publishing the full number. */
|
|
12
48
|
export declare function maskUin(uin?: string | null): string;
|
|
13
49
|
export declare function WorkBuddySection({ onModelChange, loadModelDirectory }: WorkBuddySectionProps): React.ReactElement;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WorkBuddySection.d.ts","sourceRoot":"","sources":["../../../../src/client/workbuddy/WorkBuddySection.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"WorkBuddySection.d.ts","sourceRoot":"","sources":["../../../../src/client/workbuddy/WorkBuddySection.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,KAAK,EAEV,qBAAqB,EAGrB,eAAe,EAChB,MAAM,qCAAqC,CAAA;AAK5C,OAAO,EAAuB,KAAK,qBAAqB,EAAE,MAAM,0BAA0B,CAAA;AAgB1F;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,qBAAqB,GAAG,SAAS,EAC1C,MAAM,EAAE,eAAe,GAAG,IAAI,EAC9B,MAAM,EAAE;IACN,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,eAAe,KAAK,MAAM,CAAA;IACvD,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,MAAM,CAAA;CAChD,GACA,MAAM,GAAG,IAAI,CA4Bf;AAED,gFAAgF;AAChF,wBAAgB,OAAO,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAInD;AAED,wBAAgB,gBAAgB,CAAC,EAAE,aAAa,EAAE,kBAAkB,EAAE,EAAE,qBAAqB,GAAG,KAAK,CAAC,YAAY,CA4WjH"}
|
|
@@ -40,6 +40,9 @@ export declare const zh: {
|
|
|
40
40
|
readonly unselectAll: "全不选";
|
|
41
41
|
readonly imageSupport: "图片";
|
|
42
42
|
readonly textOnly: "纯文本";
|
|
43
|
+
readonly creditMultiplier: "倍率";
|
|
44
|
+
readonly creditMultiplierRegion: "{value}({region})";
|
|
45
|
+
readonly creditMultiplierPair: "{first} / {second}";
|
|
43
46
|
readonly regionBadge: "区域";
|
|
44
47
|
readonly unavailableHere: "当前区域不可用";
|
|
45
48
|
readonly enhanced: "增强功能";
|
|
@@ -123,6 +126,9 @@ export declare const en: {
|
|
|
123
126
|
readonly unselectAll: "Deselect all";
|
|
124
127
|
readonly imageSupport: "Images";
|
|
125
128
|
readonly textOnly: "Text only";
|
|
129
|
+
readonly creditMultiplier: "Multiplier";
|
|
130
|
+
readonly creditMultiplierRegion: "{value} ({region})";
|
|
131
|
+
readonly creditMultiplierPair: "{first} / {second}";
|
|
126
132
|
readonly regionBadge: "Regions";
|
|
127
133
|
readonly unavailableHere: "Unavailable in this region";
|
|
128
134
|
readonly enhanced: "Enhanced features";
|
|
@@ -207,6 +213,9 @@ export declare const dictionaries: {
|
|
|
207
213
|
readonly unselectAll: "全不选";
|
|
208
214
|
readonly imageSupport: "图片";
|
|
209
215
|
readonly textOnly: "纯文本";
|
|
216
|
+
readonly creditMultiplier: "倍率";
|
|
217
|
+
readonly creditMultiplierRegion: "{value}({region})";
|
|
218
|
+
readonly creditMultiplierPair: "{first} / {second}";
|
|
210
219
|
readonly regionBadge: "区域";
|
|
211
220
|
readonly unavailableHere: "当前区域不可用";
|
|
212
221
|
readonly enhanced: "增强功能";
|
|
@@ -290,6 +299,9 @@ export declare const dictionaries: {
|
|
|
290
299
|
readonly unselectAll: "全不选";
|
|
291
300
|
readonly imageSupport: "图片";
|
|
292
301
|
readonly textOnly: "纯文本";
|
|
302
|
+
readonly creditMultiplier: "倍率";
|
|
303
|
+
readonly creditMultiplierRegion: "{value}({region})";
|
|
304
|
+
readonly creditMultiplierPair: "{first} / {second}";
|
|
293
305
|
readonly regionBadge: "区域";
|
|
294
306
|
readonly unavailableHere: "当前区域不可用";
|
|
295
307
|
readonly enhanced: "增强功能";
|
|
@@ -373,6 +385,9 @@ export declare const dictionaries: {
|
|
|
373
385
|
readonly unselectAll: "Deselect all";
|
|
374
386
|
readonly imageSupport: "Images";
|
|
375
387
|
readonly textOnly: "Text only";
|
|
388
|
+
readonly creditMultiplier: "Multiplier";
|
|
389
|
+
readonly creditMultiplierRegion: "{value} ({region})";
|
|
390
|
+
readonly creditMultiplierPair: "{first} / {second}";
|
|
376
391
|
readonly regionBadge: "Regions";
|
|
377
392
|
readonly unavailableHere: "Unavailable in this region";
|
|
378
393
|
readonly enhanced: "Enhanced features";
|
|
@@ -456,6 +471,9 @@ export declare const dictionaries: {
|
|
|
456
471
|
readonly unselectAll: "Deselect all";
|
|
457
472
|
readonly imageSupport: "Images";
|
|
458
473
|
readonly textOnly: "Text only";
|
|
474
|
+
readonly creditMultiplier: "Multiplier";
|
|
475
|
+
readonly creditMultiplierRegion: "{value} ({region})";
|
|
476
|
+
readonly creditMultiplierPair: "{first} / {second}";
|
|
459
477
|
readonly regionBadge: "Regions";
|
|
460
478
|
readonly unavailableHere: "Unavailable in this region";
|
|
461
479
|
readonly enhanced: "Enhanced features";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"locales.d.ts","sourceRoot":"","sources":["../../../../src/client/workbuddy/locales.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,YAAY,kBAAkB,CAAA;AAE3C,eAAO,MAAM,EAAE
|
|
1
|
+
{"version":3,"file":"locales.d.ts","sourceRoot":"","sources":["../../../../src/client/workbuddy/locales.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,YAAY,kBAAkB,CAAA;AAE3C,eAAO,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqFL,CAAA;AAEV,eAAO,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqFL,CAAA;AAEV,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAKxB,CAAA;AAED,MAAM,MAAM,kBAAkB,GAAG,MAAM,OAAO,EAAE,CAAA"}
|
|
@@ -12,6 +12,22 @@
|
|
|
12
12
|
* degenerate stream scores near one. On a hit it stops yielding chunks, so the
|
|
13
13
|
* in-flight request ends, and lets the turn resume on a fresh step.
|
|
14
14
|
*
|
|
15
|
+
* Uniqueness alone only sees verbatim repetition. A stream can restate one
|
|
16
|
+
* conclusion over and over in fresh words, score 0.48 where the threshold is
|
|
17
|
+
* 0.85, and run to the output ceiling untouched. So a second, independent
|
|
18
|
+
* signal scores the same window for recurrence: how strongly each sentence
|
|
19
|
+
* repeats something the model already said at least `semanticLag` sentences
|
|
20
|
+
* earlier. Enumerative reasoning repeats itself too, but adjacently — each item
|
|
21
|
+
* borrows the previous item's frame — and recurrence ignores adjacency, which
|
|
22
|
+
* is what separates the two.
|
|
23
|
+
*
|
|
24
|
+
* Neither signal stops anything on its own. A break needs both over their
|
|
25
|
+
* thresholds in the same window, and then `semanticConfirmations` consecutive
|
|
26
|
+
* such windows: one signal alone, or a single anomalous window, is logged and
|
|
27
|
+
* released. That gradient is the whole design. A guard that cuts a healthy
|
|
28
|
+
* answer is worse than one that lets a runaway finish, because the user sees a
|
|
29
|
+
* turn stop mid-sentence with no explanation, and the fix costs a whole turn.
|
|
30
|
+
*
|
|
15
31
|
* Seam choice: the guard wraps `llm/stream`, not `agent/assistant-stream`.
|
|
16
32
|
* `agent/assistant-stream` is emit-mode — it can observe but cannot stop a
|
|
17
33
|
* stream — and it does not exist before harness 0.1.5, which would make the
|
|
@@ -120,6 +136,91 @@ export interface GuardOptions {
|
|
|
120
136
|
cooldownMs?: number;
|
|
121
137
|
/** Model ids to watch; empty watches every model. */
|
|
122
138
|
includeModels?: string[];
|
|
139
|
+
/**
|
|
140
|
+
* Recurrence score at or above which the semantic signal is considered to
|
|
141
|
+
* hold (default 0.35).
|
|
142
|
+
*
|
|
143
|
+
* Measured on the trailing window: the three healthy fixtures peak at 0.19,
|
|
144
|
+
* 0.17 and 0.17 across every streaming prefix, while a paraphrased loop and
|
|
145
|
+
* the verbatim loop score 0.75 and 0.99. 0.35 sits near the geometric mean
|
|
146
|
+
* of that gap, roughly 1.8x above the worst healthy prefix.
|
|
147
|
+
*/
|
|
148
|
+
semanticThreshold?: number;
|
|
149
|
+
/**
|
|
150
|
+
* Sentences a claim must be separated from to count as recurrence
|
|
151
|
+
* (default 6).
|
|
152
|
+
*
|
|
153
|
+
* Zero would make healthy enumeration look degenerate: item N of a list
|
|
154
|
+
* legitimately shares most of its wording with item N-1. Requiring the
|
|
155
|
+
* earlier sentence to be at least this far back keeps the measurement on
|
|
156
|
+
* "the model said this before" rather than "the model is still on this point".
|
|
157
|
+
*/
|
|
158
|
+
semanticLag?: number;
|
|
159
|
+
/**
|
|
160
|
+
* Characters required before the semantic signal is scored (default 360).
|
|
161
|
+
*
|
|
162
|
+
* Deliberately its own floor, well below `minWindowChars`: a real trace
|
|
163
|
+
* emitted 16 steps of which only one crossed 1500 characters, so the
|
|
164
|
+
* literal signal saw a single step of a whole turn. The two floors are
|
|
165
|
+
* separate knobs because they answer different questions — the literal one
|
|
166
|
+
* is about how much text a duplicate needs to be visible in, the semantic
|
|
167
|
+
* one about how much text a recurrence needs to be measurable in.
|
|
168
|
+
*/
|
|
169
|
+
semanticMinChars?: number;
|
|
170
|
+
/** Sentences required before recurrence is scored (default 8). */
|
|
171
|
+
semanticMinSentences?: number;
|
|
172
|
+
/**
|
|
173
|
+
* Consecutive windows in which both signals must hold before a break
|
|
174
|
+
* (default 3).
|
|
175
|
+
*
|
|
176
|
+
* Counted independently of the per-turn break budget, which bounds how often
|
|
177
|
+
* the guard may act, not how sure it must be. A stream delivers a scoring
|
|
178
|
+
* window every few dozen characters, so three confirmations cost a few
|
|
179
|
+
* hundred wasted tokens against a runaway measured in the tens of thousands.
|
|
180
|
+
*/
|
|
181
|
+
semanticConfirmations?: number;
|
|
182
|
+
/**
|
|
183
|
+
* Lowest literal score the low-literal path will act on (default 0.6).
|
|
184
|
+
*
|
|
185
|
+
* A paraphrased loop sits far below `threshold` — measured at 0.676 for a
|
|
186
|
+
* model restating twelve conclusions in fresh words, against 0.85 for
|
|
187
|
+
* verbatim repetition. So a strong semantic signal has to be allowed to
|
|
188
|
+
* carry a decision the literal signal cannot make on its own.
|
|
189
|
+
*
|
|
190
|
+
* The floor exists because a low score is not the same as a high one: 0.6 is
|
|
191
|
+
* evidence that something is repeating, 0.2 is a short trace that has not
|
|
192
|
+
* repeated long enough to say anything. Measured healthy literal peaks at
|
|
193
|
+
* 0.276, so 0.6 keeps a 2.2x margin over every healthy prefix.
|
|
194
|
+
*/
|
|
195
|
+
semanticLiteralFloor?: number;
|
|
196
|
+
/**
|
|
197
|
+
* Semantic score the low-literal path demands (default 0.45).
|
|
198
|
+
*
|
|
199
|
+
* Strictly greater than `semanticThreshold`, and validated as such. The literal
|
|
200
|
+
* evidence on this path is weaker by construction, so the semantic evidence
|
|
201
|
+
* has to be stronger: 0.45 against a measured healthy peak of 0.194 is a
|
|
202
|
+
* 2.3x margin, while a paraphrase loop measures 0.77.
|
|
203
|
+
*/
|
|
204
|
+
semanticStrictThreshold?: number;
|
|
205
|
+
/**
|
|
206
|
+
* Most of a window's sentences may be distinct and still be eligible for the
|
|
207
|
+
* low-literal path (default 0.47).
|
|
208
|
+
*
|
|
209
|
+
* This is the dimension that separates a model circling from a model
|
|
210
|
+
* listing. Both reuse a frame heavily and both score high on recurrence, but
|
|
211
|
+
* a list writes a sentence that has never been written before on every line
|
|
212
|
+
* — measured at 1.000 distinct, against 0.42 for a paraphrase loop and 0.075
|
|
213
|
+
* for a verbatim one. Recurrence says the wording comes back; this says
|
|
214
|
+
* whether anything at all was new.
|
|
215
|
+
*/
|
|
216
|
+
semanticDistinctCeiling?: number;
|
|
217
|
+
/**
|
|
218
|
+
* Consecutive windows the low-literal path needs (default 5).
|
|
219
|
+
*
|
|
220
|
+
* Strictly greater than `semanticConfirmations`, and validated as such. The path is
|
|
221
|
+
* acting on weaker evidence, so it also waits longer before it acts.
|
|
222
|
+
*/
|
|
223
|
+
semanticStrictConfirmations?: number;
|
|
123
224
|
/** Injectable clock, so the cooldown is testable without a timer. */
|
|
124
225
|
now?: () => number;
|
|
125
226
|
}
|
|
@@ -132,6 +233,15 @@ export interface ResolvedGuardOptions {
|
|
|
132
233
|
maxBreaksPerTurn: number;
|
|
133
234
|
cooldownMs: number;
|
|
134
235
|
includeModels: string[];
|
|
236
|
+
semanticThreshold: number;
|
|
237
|
+
semanticLag: number;
|
|
238
|
+
semanticMinChars: number;
|
|
239
|
+
semanticMinSentences: number;
|
|
240
|
+
semanticConfirmations: number;
|
|
241
|
+
semanticLiteralFloor: number;
|
|
242
|
+
semanticStrictThreshold: number;
|
|
243
|
+
semanticDistinctCeiling: number;
|
|
244
|
+
semanticStrictConfirmations: number;
|
|
135
245
|
now: () => number;
|
|
136
246
|
}
|
|
137
247
|
export declare const DEFAULT_GUARD_OPTIONS: ResolvedGuardOptions;
|
|
@@ -151,6 +261,62 @@ export declare function resolveGuardOptions(options?: GuardOptions): ResolvedGua
|
|
|
151
261
|
* @returns collapse score in [0,1]; 0 means every n-gram is unique.
|
|
152
262
|
*/
|
|
153
263
|
export declare function collapseScore(window: string, n: number): number;
|
|
264
|
+
/**
|
|
265
|
+
* Split reasoning text into sentences, for mixed CJK and Latin streams.
|
|
266
|
+
*
|
|
267
|
+
* A Chinese full stop ends a sentence whatever follows it. An ASCII `.!?` only
|
|
268
|
+
* ends one when whitespace or the end of the text follows, because the same
|
|
269
|
+
* characters carry out decimals, file names and version numbers
|
|
270
|
+
* (`selectors.test.ts:745`, `3.14`) that must not become sentence
|
|
271
|
+
* edges. Whitespace runs collapse and case folds, so a difference in spacing
|
|
272
|
+
* or capitalisation cannot read as a difference in wording.
|
|
273
|
+
*
|
|
274
|
+
* @param text - reasoning text, typically one trailing window.
|
|
275
|
+
* @returns non-empty normalized sentences, in order.
|
|
276
|
+
*/
|
|
277
|
+
export declare function splitSentences(text: string): string[];
|
|
278
|
+
/**
|
|
279
|
+
* How strongly a window keeps returning to sentences it already stated.
|
|
280
|
+
*
|
|
281
|
+
* Each sentence is compared against every sentence at least `lag` positions earlier
|
|
282
|
+
* and keeps the best match; the score is the mean of those best matches. The
|
|
283
|
+
* comparison is normalized (Jaccard), so two sentences match on shared wording
|
|
284
|
+
* rather than on shared length, and character n-grams are used rather than words
|
|
285
|
+
* because no tokenizer is available here, and none would survive a CJK/Latin
|
|
286
|
+
* mix without segmenting Chinese first.
|
|
287
|
+
*
|
|
288
|
+
* Two properties matter more than the exact number. The score saturates — a
|
|
289
|
+
* twelve-sentence loop and a four-hundred-sentence one both approach one — so
|
|
290
|
+
* it does not drift with length the way a mean pairwise similarity does, and
|
|
291
|
+
* it does not reward a long answer merely for containing more pairs. And the
|
|
292
|
+
* lag is what makes it safe to ship: healthy enumeration reuses its framing
|
|
293
|
+
* from the sentence immediately before, which this metric cannot see.
|
|
294
|
+
*
|
|
295
|
+
* @param window - trailing reasoning characters.
|
|
296
|
+
* @param lag - sentences a claim must be separated from to count as recurrence.
|
|
297
|
+
* @returns recurrence score in [0,1]; 0 means nothing recurs, or too little text to tell.
|
|
298
|
+
*/
|
|
299
|
+
export declare function semanticRecurrence(window: string, lag: number): number;
|
|
300
|
+
/**
|
|
301
|
+
* The share of a window's sentences that have never been said before.
|
|
302
|
+
*
|
|
303
|
+
* Recurrence cannot tell a model that is circling from a model that is
|
|
304
|
+
* listing, because a list reuses its frame as heavily as a loop does and
|
|
305
|
+
* scores just as high. The difference is that a list writes a new sentence on
|
|
306
|
+
* every line. Measured over a trailing window: 0.075 for the verbatim loop,
|
|
307
|
+
* 0.42 for a paraphrase loop, 1.000 for every healthy fixture and for every
|
|
308
|
+
* list shape tried.
|
|
309
|
+
*
|
|
310
|
+
* Equality is exact and on the normalized sentence, which is what keeps the
|
|
311
|
+
* lists out. Two rows differing only by a row number are 0.86 similar by
|
|
312
|
+
* `semanticRecurrence` and 1.000 distinct here, and that gap is the whole point: the
|
|
313
|
+
* fuzzy measure asks whether the wording came back, this one asks whether
|
|
314
|
+
* anything was new.
|
|
315
|
+
*
|
|
316
|
+
* @param window - trailing reasoning characters.
|
|
317
|
+
* @returns distinct share in (0,1]; 1 when every sentence is unique.
|
|
318
|
+
*/
|
|
319
|
+
export declare function distinctSentenceRatio(window: string): number;
|
|
154
320
|
export declare const RESUME_HINT: string;
|
|
155
321
|
/** The second resume message, used once a resume has also collapsed. */
|
|
156
322
|
export declare const RESUME_HINT_STRICT: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/host/reasoning-collapse-guard/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/host/reasoning-collapse-guard/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@ import type { WorkBuddyAccount, WorkBuddyAccountQuota, WorkBuddyMeter } from '..
|
|
|
2
2
|
import { PROVIDER_ID, PROVIDER_NAME } from './types.ts';
|
|
3
3
|
import { FileCredentialStore, type WorkBuddyCredentials } from './token-store.ts';
|
|
4
4
|
import type { WorkBuddyTokenIdentity } from './identity.ts';
|
|
5
|
-
import type
|
|
5
|
+
import { type WorkBuddyModelEntry } from './model-catalog.ts';
|
|
6
6
|
export interface WorkBuddyRequestOptions {
|
|
7
7
|
fetchFn?: typeof fetch;
|
|
8
8
|
signal?: AbortSignal;
|
|
@@ -49,6 +49,14 @@ export declare function fetchAccountIdentity(credentials: WorkBuddyCredentials,
|
|
|
49
49
|
* inferred from the model's name. Image-generation tools (`tags` naming
|
|
50
50
|
* `text-to-image`/`image-to-image`) are skipped: they are not chat models and
|
|
51
51
|
* carry no context window.
|
|
52
|
+
*
|
|
53
|
+
* `credits` is read here rather than left to the shipped table because a
|
|
54
|
+
* reachable gateway **replaces** that table entirely: a multiplier transcribed
|
|
55
|
+
* offline would be the only one a signed-in user ever saw, and it would stay
|
|
56
|
+
* wrong the moment the subscription repriced a model. A string this route cannot
|
|
57
|
+
* turn into a number (`''`, which `default-model` publishes, or a value a
|
|
58
|
+
* future gateway invents) leaves the field off the entry altogether instead of
|
|
59
|
+
* writing a plausible-looking `0` — see `parseWorkBuddyCreditMultiplier`.
|
|
52
60
|
*/
|
|
53
61
|
export declare function parseConfigModels(payload: unknown, region: WorkBuddyCredentials['region']): WorkBuddyModelEntry[];
|
|
54
62
|
export declare function getCachedCatalog(): WorkBuddyModelEntry[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../../src/host/workbuddy/client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,gBAAgB,EAChB,qBAAqB,EACrB,cAAc,EACf,MAAM,qCAAqC,CAAA;AAC5C,OAAO,EAiBL,WAAW,EACX,aAAa,EAKd,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,mBAAmB,EAAsB,KAAK,oBAAoB,EAAE,MAAM,kBAAkB,CAAA;AACrG,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAA;AAC3D,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../../src/host/workbuddy/client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,gBAAgB,EAChB,qBAAqB,EACrB,cAAc,EACf,MAAM,qCAAqC,CAAA;AAC5C,OAAO,EAiBL,WAAW,EACX,aAAa,EAKd,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,mBAAmB,EAAsB,KAAK,oBAAoB,EAAE,MAAM,kBAAkB,CAAA;AACrG,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAA;AAC3D,OAAO,EAAyB,KAAK,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AAQpF,MAAM,WAAW,uBAAuB;IACtC,OAAO,CAAC,EAAE,OAAO,KAAK,CAAA;IACtB,MAAM,CAAC,EAAE,WAAW,CAAA;CACrB;AA6BD;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,IAAI,CAAC,oBAAoB,EAAE,aAAa,GAAG,QAAQ,GAAG,KAAK,GAAG,cAAc,GAAG,SAAS,CAAC,EACtG,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GACjC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAmBxB;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,oBAAoB,EACjC,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,oBAAoB,CAAC,CAoD/B;AAED,kDAAkD;AAClD,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,oBAAoB,GAAG,gBAAgB,CAiB1F;AAMD;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,oBAAoB,CACxC,WAAW,EAAE,oBAAoB,EACjC,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,sBAAsB,GAAG,IAAI,CAAC,CAyBxC;AAMD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,oBAAoB,CAAC,QAAQ,CAAC,GAAG,mBAAmB,EAAE,CA0EjH;AAkBD,wBAAgB,gBAAgB,IAAI,mBAAmB,EAAE,CAExD;AAED,wBAAgB,kBAAkB,IAAI,IAAI,CAMzC;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,oBAAoB,EACjC,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAchC;AAED;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CACrC,WAAW,EAAE,oBAAoB,EACjC,OAAO,GAAE,uBAAuB,GAAG;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GAC1D,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAyDhC;AAiDD,wEAAwE;AACxE,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;CAC3B;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,aAAa,CAwC5D;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAQ5D;AAED,uEAAuE;AACvE,wBAAgB,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,cAAc,EAAE,CAmCtE;AA4CD;;;;;;GAMG;AACH,wBAAgB,cAAc,IAAI,qBAAqB,GAAG,SAAS,CAElE;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,qBAAqB,GAAG,SAAS,CAG9F;AAED,wBAAgB,gBAAgB,IAAI,IAAI,CAKvC;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,KAAK,sBAA4B,EACjC,OAAO,GAAE,OAAO,KAAa,EAC7B,KAAK,UAAQ,EACb,SAAS,GAAE,MAAM,GAAG,IAAW,EAC/B,gBAAgB,GAAE,SAAS,MAAM,EAAO,GACvC,OAAO,CAAC,qBAAqB,CAAC,CAmEhC;AAED,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,CAAA"}
|
|
@@ -11,9 +11,21 @@
|
|
|
11
11
|
* The fallback is a verbatim transcription of a live `/v3/config` read, not
|
|
12
12
|
* hand-written guesses: an earlier revision of this file guessed context
|
|
13
13
|
* windows from vendor marketing and was wrong in both directions (`glm-5.3`
|
|
14
|
-
* and `kimi-k3` are 1M, not 200K/256K).
|
|
15
|
-
*
|
|
16
|
-
*
|
|
14
|
+
* and `kimi-k3` are 1M, not 200K/256K).
|
|
15
|
+
*
|
|
16
|
+
* One entry serves both regions, so a model the regions disagree about needs a
|
|
17
|
+
* merged figure. The rule is asymmetric on purpose: the **larger maximum** is
|
|
18
|
+
* kept, while the **served default** and the **output cap** take the **smaller**
|
|
19
|
+
* of the two. Over-declaring either one is a hard failure — DSH would send a
|
|
20
|
+
* request the gateway rejects — whereas under-declaring only compresses a
|
|
21
|
+
* conversation earlier than needed, and both remain overridable per model from
|
|
22
|
+
* the settings card. Measured disagreements (`glm-5.3-flash`, `glm-5.3`,
|
|
23
|
+
* `glm-5.2`, `kimi-k2.8-preview` served 300000/48000/48000/32000 by intl
|
|
24
|
+
* against 1000000/64000/64000/64000 by cn) are reconciled that way.
|
|
25
|
+
*
|
|
26
|
+
* The regions also do not serve the same ids. intl added `glm-5.3-flash` and
|
|
27
|
+
* keeps `gemini-3.5-flash`, `kimi-k3` and the `*-model` aliases to itself; cn
|
|
28
|
+
* keeps `glm-5.3-flash`, `kimi-k3-1` and its own `-x` variants.
|
|
17
29
|
*
|
|
18
30
|
* `regions` is a routing fact, not a preference: asking a region for a model it
|
|
19
31
|
* does not serve answers 400 `code 11102`.
|
|
@@ -27,6 +39,17 @@
|
|
|
27
39
|
* shipped default selection excludes them anyway. The adapter's failure message
|
|
28
40
|
* names this case so a user knows to pick another model rather than to retry.
|
|
29
41
|
*
|
|
42
|
+
* `credits` is the consumption multiplier the same payload publishes as a
|
|
43
|
+
* string (`x0.79 credits` on cn, `x6.67` on intl), stored here in the bare
|
|
44
|
+
* numeric form the settings card renders. It is kept per region because the two
|
|
45
|
+
* backends do not always agree — measured 2026-10-09, `deepseek-v4.1-flash`
|
|
46
|
+
* is `0.11` on cn against `0.00` on intl — and a key is written only for a
|
|
47
|
+
* region that actually published one (every `gpt-5.x` and `gpt-6-astra` is
|
|
48
|
+
* intl-only, the `minimax` and `glm-5.0`/`glm-4.x` rows carry no intl key).
|
|
49
|
+
* An empty string (`default-model`) means no rate was declared at all, so that
|
|
50
|
+
* row has no `credits` field rather than a zeroed one: a guessed rate on a
|
|
51
|
+
* spend figure is worse than a missing one.
|
|
52
|
+
*
|
|
30
53
|
* `reasoningEfforts` carries the ladder a model accepts, transcribed from the
|
|
31
54
|
* gateway's own declaration. `/v3/config` uses two shapes and they were once
|
|
32
55
|
* conflated, in opposite directions: a lone `{ effort: 'high' }` (no
|
|
@@ -37,7 +60,7 @@
|
|
|
37
60
|
* three the gateway declares explicitly for `glm-5.3-flash` and
|
|
38
61
|
* `kimi-k2.8-preview`, and routes any other value into the nearest of them.
|
|
39
62
|
*/
|
|
40
|
-
import type { WorkBuddyRegion } from '../../shared/workbuddy-contracts.ts';
|
|
63
|
+
import type { WorkBuddyModelCredits, WorkBuddyRegion } from '../../shared/workbuddy-contracts.ts';
|
|
41
64
|
export interface WorkBuddyModelEntry {
|
|
42
65
|
id: string;
|
|
43
66
|
name: string;
|
|
@@ -56,6 +79,16 @@ export interface WorkBuddyModelEntry {
|
|
|
56
79
|
maxTokens: number;
|
|
57
80
|
/** Regions whose backend serves this id. */
|
|
58
81
|
regions: readonly WorkBuddyRegion[];
|
|
82
|
+
/**
|
|
83
|
+
* Consumption multiplier per region, as `/v3/config` publishes it.
|
|
84
|
+
*
|
|
85
|
+
* Optional on purpose: the multiplier is the one field the gateway may omit
|
|
86
|
+
* for a model it otherwise describes (`default-model` ships an empty string),
|
|
87
|
+
* so every catalog literal in this repo — test fixtures and the live parser
|
|
88
|
+
* alike — must stay valid without it. Absent therefore means "nothing usable
|
|
89
|
+
* was published", never "zero": `x0.00` is a real declaration and is kept.
|
|
90
|
+
*/
|
|
91
|
+
credits?: WorkBuddyModelCredits;
|
|
59
92
|
/** Whether the model accepts image input. */
|
|
60
93
|
supportsImage: boolean;
|
|
61
94
|
/** Reasoning ladder the model accepts; empty for a non-reasoning model. */
|
|
@@ -67,6 +100,38 @@ export interface WorkBuddyModelEntry {
|
|
|
67
100
|
/** One-line note shown beside the model in the settings card. */
|
|
68
101
|
description: string;
|
|
69
102
|
}
|
|
103
|
+
/**
|
|
104
|
+
* Models the gateway serves but does not publish in `/v3/config`.
|
|
105
|
+
*
|
|
106
|
+
* The catalog is a published list, not the served one: measured on the
|
|
107
|
+
* international backend, `gpt-6-sol`, `gpt-6-luna` and `gemini-3.8-flash` all
|
|
108
|
+
* answer a normal streaming completion with 200 while being absent from
|
|
109
|
+
* `/v3/config` entirely, and a reachable gateway *replaces* the shipped table
|
|
110
|
+
* with that list. Without these rows the picker would simply never show them, so
|
|
111
|
+
* they are declared here and merged into a live catalog too
|
|
112
|
+
* ({@link withUnpublishedModels}) rather than living in the fallback alone.
|
|
113
|
+
*
|
|
114
|
+
* What each row records, and how it was established, differs by field:
|
|
115
|
+
*
|
|
116
|
+
* - **Existence, the reasoning ladder, image support** were measured against the
|
|
117
|
+
* live endpoint, not inferred from the name. A rejected level answers 400
|
|
118
|
+
* `code 11133` with `extError` `400002`; `gpt-6-sol` takes exactly the ladder
|
|
119
|
+
* `gpt-6-astra` publishes (`minimal` refused, `low`/`medium`/`high`/`xhigh`/
|
|
120
|
+
* `max` accepted) and both accept a 1x1 PNG.
|
|
121
|
+
* - **Context window, output cap and `canDisableThinking` are inherited from the
|
|
122
|
+
* published sibling in the same family** — `gpt-6-astra` for `gpt-6-sol` and
|
|
123
|
+
* `gpt-6-luna`, `gemini-3.5-flash` for `gemini-3.8-flash`. They are marked
|
|
124
|
+
* here rather than measured because the gateway publishes nothing for these
|
|
125
|
+
* ids and offers no cheap way to read the real figure: it accepts a
|
|
126
|
+
* `max_tokens` larger than any published window (even for `gpt-6-astra`, whose
|
|
127
|
+
* own catalog caps at 128000), so the number is neither enforced nor
|
|
128
|
+
* discoverable from the request side.
|
|
129
|
+
*
|
|
130
|
+
* Every field stays overridable per model from the settings card, and an
|
|
131
|
+
* inherited window errs low rather than high: over-declaring overflows the
|
|
132
|
+
* gateway mid-session, while under-declaring only compresses earlier.
|
|
133
|
+
*/
|
|
134
|
+
export declare const UNPUBLISHED_MODELS: readonly WorkBuddyModelEntry[];
|
|
70
135
|
/**
|
|
71
136
|
* Offline fallback catalog, transcribed from a live `/v3/config` read.
|
|
72
137
|
*
|
|
@@ -85,6 +150,17 @@ export declare const FALLBACK_MODELS: readonly WorkBuddyModelEntry[];
|
|
|
85
150
|
export declare const DEFAULT_VISIBLE_MODEL_IDS: readonly string[];
|
|
86
151
|
/** Every id the fallback knows, in declaration order. */
|
|
87
152
|
export declare const WORKBUDDY_MODEL_IDS: readonly string[];
|
|
153
|
+
/**
|
|
154
|
+
* Add the served-but-unpublished models to a live `/v3/config` catalog.
|
|
155
|
+
*
|
|
156
|
+
* A reachable gateway replaces the shipped table with the list it publishes, so
|
|
157
|
+
* a model it serves without listing ({@link UNPUBLISHED_MODELS}) would drop out
|
|
158
|
+
* of the picker the moment the catalog loads. Merging here keeps it offered.
|
|
159
|
+
*
|
|
160
|
+
* A published entry always wins: the gateway is the authority on anything it
|
|
161
|
+
* does describe, so these rows only fill ids the payload is silent about.
|
|
162
|
+
*/
|
|
163
|
+
export declare function withUnpublishedModels(catalog: readonly WorkBuddyModelEntry[], region: WorkBuddyRegion): WorkBuddyModelEntry[];
|
|
88
164
|
/**
|
|
89
165
|
* Resolve one entry from a catalog.
|
|
90
166
|
*
|
|
@@ -95,12 +171,38 @@ export declare const WORKBUDDY_MODEL_IDS: readonly string[];
|
|
|
95
171
|
export declare function resolveWorkBuddyModel(id: string, catalog?: readonly WorkBuddyModelEntry[]): WorkBuddyModelEntry;
|
|
96
172
|
/** Whether one catalog knows this exact id. */
|
|
97
173
|
export declare function isWorkBuddyModelId(id: unknown, catalog?: readonly WorkBuddyModelEntry[]): id is string;
|
|
98
|
-
/**
|
|
174
|
+
/** The vendor family one model belongs to. */
|
|
175
|
+
export declare function workBuddyModelVendor(id: string): string;
|
|
176
|
+
/**
|
|
177
|
+
* Group a list so every vendor's models sit together.
|
|
178
|
+
*
|
|
179
|
+
* Families appear in the order their first model does — the catalog decides
|
|
180
|
+
* which vendor leads, not this function — and each family is ordered newest
|
|
181
|
+
* generation first.
|
|
182
|
+
*/
|
|
183
|
+
export declare function groupWorkBuddyModelsByVendor<T extends {
|
|
184
|
+
id: string;
|
|
185
|
+
}>(models: readonly T[]): T[];
|
|
186
|
+
/**
|
|
187
|
+
* Models an account in `region` can actually call, grouped by vendor.
|
|
188
|
+
*
|
|
189
|
+
* Grouped here rather than in the settings card because this is also what the
|
|
190
|
+
* request path resolves against: one ordering rule, so the picker and the
|
|
191
|
+
* adapter can never disagree about which models a region offers.
|
|
192
|
+
*/
|
|
99
193
|
export declare function modelsForRegion(region: WorkBuddyRegion, catalog?: readonly WorkBuddyModelEntry[]): WorkBuddyModelEntry[];
|
|
100
194
|
/** Whether one model accepts image input. */
|
|
101
195
|
export declare function workBuddyModelSupportsImage(id: string, catalog?: readonly WorkBuddyModelEntry[]): boolean;
|
|
102
196
|
/** Reasoning ladder one model accepts. */
|
|
103
197
|
export declare function workBuddyReasoningEfforts(id: string, catalog?: readonly WorkBuddyModelEntry[]): readonly string[];
|
|
198
|
+
/**
|
|
199
|
+
* Consumption multiplier per region one model publishes.
|
|
200
|
+
*
|
|
201
|
+
* Read through {@link resolveWorkBuddyModel} like the other accessors, so an id
|
|
202
|
+
* no catalog describes reports `{}` — "no rate published" rather than a rate
|
|
203
|
+
* of zero.
|
|
204
|
+
*/
|
|
205
|
+
export declare function workBuddyModelCredits(id: string, catalog?: readonly WorkBuddyModelEntry[]): WorkBuddyModelCredits;
|
|
104
206
|
/** Output cap requested when the caller omits one. */
|
|
105
207
|
export declare function maxOutputTokensFor(id: string, catalog?: readonly WorkBuddyModelEntry[]): number;
|
|
106
208
|
/** Context window assumed when no override is saved. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-catalog.d.ts","sourceRoot":"","sources":["../../../../src/host/workbuddy/model-catalog.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"model-catalog.d.ts","sourceRoot":"","sources":["../../../../src/host/workbuddy/model-catalog.ts"],"names":[],"mappings":"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"}
|
|
@@ -15,7 +15,20 @@ import type { WorkBuddyAccountPool } from './account-pool.ts';
|
|
|
15
15
|
* behind an unedited default. Any explicit edit is honoured exactly.
|
|
16
16
|
*/
|
|
17
17
|
export declare function resolveEnabledModelIds(stored: readonly string[], available: readonly string[], enabled?: boolean): string[];
|
|
18
|
-
/**
|
|
18
|
+
/**
|
|
19
|
+
* Build the model options the settings card renders.
|
|
20
|
+
*
|
|
21
|
+
* Order comes from the caller, which passes a vendor-grouped list so a family
|
|
22
|
+
* is not interleaved with the next one; this preserves whatever order it is
|
|
23
|
+
* given rather than imposing a second one.
|
|
24
|
+
*
|
|
25
|
+
* `credits` is passed through whole, every region the entry carries. Trimming
|
|
26
|
+
* it to one account's region is tempting and wrong: this DTO is also read with
|
|
27
|
+
* no account in hand (the harness resolves a model list before a credential is
|
|
28
|
+
* chosen), and such a caller would be told nothing rather than everything. The
|
|
29
|
+
* region key the reader actually has is already on each entry as `regions`, so
|
|
30
|
+
* picking a value is the renderer's job, not this one's.
|
|
31
|
+
*/
|
|
19
32
|
export declare function buildModelOptions(catalog: readonly WorkBuddyModelEntry[], available: readonly string[], enabledModelIds: readonly string[], overrides: Record<string, number>): WorkBuddyModelOption[];
|
|
20
33
|
export interface WorkBuddyStatusOptions {
|
|
21
34
|
fetchFn?: typeof fetch;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../../../src/host/workbuddy/routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAIlD,OAAO,EAGL,sBAAsB,EACtB,WAAW,EACX,aAAa,EAEd,MAAM,YAAY,CAAA;AACnB,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EAGtB,KAAK,wBAAwB,EAC9B,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAKL,cAAc,EAKf,MAAM,aAAa,CAAA;AACpB,OAAO,
|
|
1
|
+
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../../../src/host/workbuddy/routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAIlD,OAAO,EAGL,sBAAsB,EACtB,WAAW,EACX,aAAa,EAEd,MAAM,YAAY,CAAA;AACnB,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EAGtB,KAAK,wBAAwB,EAC9B,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAKL,cAAc,EAKf,MAAM,aAAa,CAAA;AACpB,OAAO,EAUL,KAAK,mBAAmB,EACzB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,KAAK,EAIV,oBAAoB,EACpB,kBAAkB,EACnB,MAAM,qCAAqC,CAAA;AAC5C,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAA;AAG3D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA;AA6C7D;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,SAAS,MAAM,EAAE,EACzB,SAAS,EAAE,SAAS,MAAM,EAAE,EAC5B,OAAO,UAAO,GACb,MAAM,EAAE,CASV;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,SAAS,mBAAmB,EAAE,EACvC,SAAS,EAAE,SAAS,MAAM,EAAE,EAC5B,eAAe,EAAE,SAAS,MAAM,EAAE,EAClC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAChC,oBAAoB,EAAE,CA6BxB;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,CAAC,EAAE,OAAO,KAAK,CAAA;IACtB,sFAAsF;IACtF,OAAO,CAAC,EAAE,OAAO,GAAG,CAAC,MAAM,OAAO,CAAC,CAAA;IACnC,uFAAuF;IACvF,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,MAAM,GAAG,IAAI,CAAC,CAAA;IAChD,4FAA4F;IAC5F,WAAW,CAAC,EAAE,oBAAoB,CAAA;IAClC,6EAA6E;IAC7E,OAAO,CAAC,EAAE,IAAI,CAAC,uBAAuB,EAAE,MAAM,GAAG,SAAS,CAAC,CAAA;CAC5D;AAMD,mFAAmF;AACnF,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,mBAAmB,EAC1B,aAAa,EAAE,sBAAsB,EACrC,WAAW,CAAC,EAAE,wBAAwB,EACtC,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,kBAAkB,CAAC,CA2E7B;AAED,qEAAqE;AACrE,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,OAAO,EACZ,KAAK,EAAE,mBAAmB,EAC1B,aAAa,EAAE,sBAAsB,EACrC,WAAW,CAAC,EAAE,wBAAwB,EACtC,OAAO,GAAE,sBAA2B,GACnC,MAAM,IAAI,CAkXZ;AAED,OAAO,EACL,WAAW,EACX,aAAa,EACb,sBAAsB,EACtB,cAAc,EACd,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,GACxB,CAAA"}
|
|
@@ -12,6 +12,38 @@ import type { AccountPoolStatusDto, PoolAccountSummaryDto } from './account-pool
|
|
|
12
12
|
* a property of the credential, not of the request.
|
|
13
13
|
*/
|
|
14
14
|
export type WorkBuddyRegion = 'cn' | 'intl';
|
|
15
|
+
/**
|
|
16
|
+
* Consumption multiplier of one model, per region.
|
|
17
|
+
*
|
|
18
|
+
* The subscription publishes a \`credits\` string per model in its own
|
|
19
|
+
* \`/v3/config\` catalog — \`x0.79 credits\`, \`x6.67\` — which is the relative rate at
|
|
20
|
+
* which that model consumes the package allowance. The official CodeBuddy
|
|
21
|
+
* client renders it as \`6.67x\` beside the model in its picker; this route
|
|
22
|
+
* carries the same fact to the settings card, so a model's cost is visible at
|
|
23
|
+
* the moment it is chosen rather than only on the bill.
|
|
24
|
+
*
|
|
25
|
+
* Keyed by region because the two backends do not always agree: measured
|
|
26
|
+
* 2026-10-09, \`deepseek-v4.1-flash\` is \`0.11\` on cn against \`0.00\` on intl. A
|
|
27
|
+
* region the catalog did not name for this model is absent rather than guessed,
|
|
28
|
+
* and a model whose publisher declares no usable rate (\`default-model\` ships an
|
|
29
|
+
* empty string) carries no entry at all.
|
|
30
|
+
*
|
|
31
|
+
* Values are the bare numeric form (\`'0.79'\`), never the wire spelling: the
|
|
32
|
+
* label and the \`x\` suffix belong to whichever surface renders it.
|
|
33
|
+
*/
|
|
34
|
+
export type WorkBuddyModelCredits = Partial<Record<WorkBuddyRegion, string>>;
|
|
35
|
+
/**
|
|
36
|
+
* Parse one gateway \`credits\` string into the bare multiplier it names.
|
|
37
|
+
*
|
|
38
|
+
* Measured shapes: \`x6.67\` (intl), \`x0.79 credits\` (cn), and \`''\` for a model
|
|
39
|
+
* whose publisher declares no rate. \`x0.00\` is deliberately kept — it is a real
|
|
40
|
+
* declaration ("this model does not consume allowance"), not a missing value,
|
|
41
|
+
* so it must not be confused with the empty string that means nothing is known.
|
|
42
|
+
*
|
|
43
|
+
* The return is \`null\` rather than \`0\` for anything unparseable, so a caller can
|
|
44
|
+
* tell "no rate published" from "a rate of zero".
|
|
45
|
+
*/
|
|
46
|
+
export declare function parseWorkBuddyCreditMultiplier(raw: unknown): string | null;
|
|
15
47
|
/**
|
|
16
48
|
* Reasoning levels this route can name.
|
|
17
49
|
*
|
|
@@ -69,6 +101,16 @@ export interface WorkBuddyModelOption {
|
|
|
69
101
|
supportsImage: boolean;
|
|
70
102
|
/** Regions that serve this model; the account's own region must be listed. */
|
|
71
103
|
regions: WorkBuddyRegion[];
|
|
104
|
+
/**
|
|
105
|
+
* Consumption multiplier per region, as the gateway declares it.
|
|
106
|
+
*
|
|
107
|
+
* Absent when nothing usable was published for this model — an unreachable
|
|
108
|
+
* gateway served by the shipped fallback for a model it does not rate, or an
|
|
109
|
+
* account whose region is not among the keys. The card must then show no
|
|
110
|
+
* multiplier rather than a placeholder: a guessed rate on a spend figure is
|
|
111
|
+
* worse than a missing one.
|
|
112
|
+
*/
|
|
113
|
+
credits?: WorkBuddyModelCredits;
|
|
72
114
|
/** One-line description shown beside the model in the settings card. */
|
|
73
115
|
description?: string;
|
|
74
116
|
}
|