dsh-subscriptions 0.2.0 → 0.2.2
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 +212 -180
- package/lib/auth/claude-code-creds.js +31 -9
- package/lib/auth/device-flow.js +16 -9
- package/lib/auth/oauth-flow.js +13 -10
- package/lib/auth/rpc.js +74 -23
- package/lib/auth/store.js +80 -31
- package/lib/client/CursorCard.d.ts +1 -1
- package/lib/client/CursorCard.js +50 -16
- package/lib/client/ExternalUsageCards.d.ts +1 -1
- package/lib/client/ExternalUsageCards.js +37 -16
- package/lib/client/ImageGallery.d.ts +2 -2
- package/lib/client/ImageGallery.js +92 -33
- package/lib/client/ImageGenerateToolview.js +50 -14
- package/lib/client/OllamaCard.d.ts +1 -1
- package/lib/client/OllamaCard.js +26 -8
- package/lib/client/OllamaSettingsManager.js +113 -30
- package/lib/client/ProviderAccountManager.d.ts +1 -1
- package/lib/client/ProviderAccountManager.js +164 -49
- package/lib/client/ProviderModelEditor.js +107 -26
- package/lib/client/SpeedSelect.d.ts +62 -14
- package/lib/client/SpeedSelect.js +257 -46
- package/lib/client/SubscriptionUsageBadge.d.ts +4 -10
- package/lib/client/SubscriptionUsageBadge.js +300 -112
- package/lib/client/SubscriptionsSection.js +258 -85
- package/lib/client/UsageBadgeDisplaySetting.js +35 -12
- package/lib/client/UsageMeter.d.ts +1 -1
- package/lib/client/UsageMeter.js +62 -24
- package/lib/client/VideoGenerateToolview.js +69 -17
- package/lib/client/account-preferences.d.ts +8 -0
- package/lib/client/account-preferences.js +20 -5
- package/lib/client/host-contract.d.ts +11 -2
- package/lib/client/host-contract.js +20 -3
- package/lib/client/index.d.ts +5 -5
- package/lib/client/index.js +34 -12
- package/lib/client/locales.d.ts +10 -0
- package/lib/client/locales.js +61 -51
- package/lib/client/ollama-draft.js +21 -12
- package/lib/client/reset-action.js +6 -4
- package/lib/client/reset-credits-view.d.ts +1 -1
- package/lib/client/reset-credits-view.js +66 -17
- package/lib/client/subscription-card-styles.js +94 -24
- package/lib/client/usage-color-preferences.js +4 -2
- package/lib/client/usage-pace.js +30 -12
- package/lib/client.js +287 -47
- package/lib/client.js.map +1 -1
- package/lib/http.js +1 -1
- package/lib/index.d.ts +3 -3
- package/lib/index.js +118 -64
- package/lib/model-defaults.js +4 -2
- package/lib/provider-settings.d.ts +12 -0
- package/lib/provider-settings.js +58 -16
- package/lib/providers/account-preferences.js +51 -22
- package/lib/providers/accounts.js +15 -9
- package/lib/providers/antigravity-oauth-client.js +2 -2
- package/lib/providers/antigravity.js +141 -68
- package/lib/providers/catalog-store.js +120 -41
- package/lib/providers/claude-cli-version.js +3 -3
- package/lib/providers/claude.d.ts +9 -2
- package/lib/providers/claude.js +153 -90
- package/lib/providers/codex-client-version.js +3 -3
- package/lib/providers/codex-search.js +40 -13
- package/lib/providers/codex.js +196 -112
- package/lib/providers/common.js +71 -39
- package/lib/providers/copilot.js +143 -82
- package/lib/providers/cursor-adapter.js +42 -18
- package/lib/providers/cursor-auth.d.ts +1 -1
- package/lib/providers/cursor-auth.js +69 -24
- package/lib/providers/cursor-model-settings.js +14 -5
- package/lib/providers/cursor-usage.js +27 -13
- package/lib/providers/external-usage-controller.js +14 -5
- package/lib/providers/external-usage.js +59 -23
- package/lib/providers/grok.js +152 -89
- package/lib/providers/image-pool.js +29 -11
- package/lib/providers/minimax-usage.js +31 -11
- package/lib/providers/npm-cli-version.js +10 -3
- package/lib/providers/ollama-settings.js +24 -8
- package/lib/providers/ollama-web.js +29 -11
- package/lib/providers/ollama.js +129 -66
- package/lib/providers/pool-family.js +11 -3
- package/lib/providers/pool-health.js +28 -8
- package/lib/providers/pool-usage.js +16 -9
- package/lib/providers/pool.d.ts +8 -0
- package/lib/providers/pool.js +81 -42
- package/lib/providers/rate-limit.js +8 -2
- package/lib/providers/replay.js +40 -17
- package/lib/providers/reset-redemption.js +18 -6
- package/lib/tools/image-generate.js +123 -65
- package/lib/tools/registration.js +5 -2
- package/lib/tools/video-generate.js +51 -31
- package/lib/tools/x-search.js +50 -22
- package/lib/translate/anthropic.js +85 -37
- package/lib/translate/antigravity-schema.js +71 -28
- package/lib/translate/antigravity-thinking.js +22 -9
- package/lib/translate/antigravity.js +141 -50
- package/lib/translate/chat-completions.js +67 -23
- package/lib/translate/resolved.js +55 -21
- package/lib/translate/responses.js +69 -29
- package/lib/translate/sse.js +4 -1
- package/package.json +26 -4
|
@@ -25,7 +25,9 @@ export function modelsFilePath() {
|
|
|
25
25
|
/** The per-account section of the file, or undefined when absent or malformed. */
|
|
26
26
|
function accountSection(store, provider) {
|
|
27
27
|
const accounts = store.accounts;
|
|
28
|
-
if (typeof accounts !== 'object' ||
|
|
28
|
+
if (typeof accounts !== 'object' ||
|
|
29
|
+
accounts === null ||
|
|
30
|
+
Array.isArray(accounts))
|
|
29
31
|
return undefined;
|
|
30
32
|
const section = accounts[provider];
|
|
31
33
|
if (typeof section !== 'object' || section === null || Array.isArray(section))
|
|
@@ -45,24 +47,31 @@ function sanitizeReasoning(value) {
|
|
|
45
47
|
if (typeof entry !== 'object' || entry === null)
|
|
46
48
|
return undefined;
|
|
47
49
|
const effort = entry;
|
|
48
|
-
if (typeof effort.id !== 'string' ||
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
if (typeof effort.id !== 'string' ||
|
|
51
|
+
effort.id.length === 0 ||
|
|
52
|
+
typeof effort.name !== 'string' ||
|
|
53
|
+
effort.name.length === 0 ||
|
|
54
|
+
(effort.description !== undefined &&
|
|
55
|
+
typeof effort.description !== 'string') ||
|
|
56
|
+
seen.has(effort.id))
|
|
52
57
|
return undefined;
|
|
53
58
|
seen.add(effort.id);
|
|
54
59
|
efforts.push({
|
|
55
60
|
id: ReasoningEffortId(effort.id),
|
|
56
61
|
name: effort.name,
|
|
57
|
-
...effort.description === undefined
|
|
62
|
+
...(effort.description === undefined
|
|
63
|
+
? {}
|
|
64
|
+
: { description: effort.description }),
|
|
58
65
|
});
|
|
59
66
|
}
|
|
60
|
-
if (raw.defaultEffort !== undefined
|
|
61
|
-
|
|
67
|
+
if (raw.defaultEffort !== undefined &&
|
|
68
|
+
(typeof raw.defaultEffort !== 'string' || !seen.has(raw.defaultEffort)))
|
|
62
69
|
return undefined;
|
|
63
70
|
return {
|
|
64
71
|
efforts,
|
|
65
|
-
...raw.defaultEffort === undefined
|
|
72
|
+
...(raw.defaultEffort === undefined
|
|
73
|
+
? {}
|
|
74
|
+
: { defaultEffort: ReasoningEffortId(raw.defaultEffort) }),
|
|
66
75
|
};
|
|
67
76
|
}
|
|
68
77
|
/** Validate one persisted model, or undefined when malformed. */
|
|
@@ -70,53 +79,80 @@ function sanitizeModel(value) {
|
|
|
70
79
|
if (typeof value !== 'object' || value === null)
|
|
71
80
|
return undefined;
|
|
72
81
|
const raw = value;
|
|
73
|
-
if (typeof raw.id !== 'string' ||
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
82
|
+
if (typeof raw.id !== 'string' ||
|
|
83
|
+
raw.id.length === 0 ||
|
|
84
|
+
typeof raw.name !== 'string' ||
|
|
85
|
+
raw.name.length === 0 ||
|
|
86
|
+
(raw.description !== undefined && typeof raw.description !== 'string') ||
|
|
87
|
+
(raw.contextWindow !== undefined &&
|
|
88
|
+
(typeof raw.contextWindow !== 'number' ||
|
|
89
|
+
!Number.isInteger(raw.contextWindow) ||
|
|
90
|
+
raw.contextWindow <= 0)) ||
|
|
91
|
+
(raw.maxContextWindow !== undefined &&
|
|
92
|
+
(typeof raw.maxContextWindow !== 'number' ||
|
|
93
|
+
!Number.isSafeInteger(raw.maxContextWindow) ||
|
|
94
|
+
raw.maxContextWindow <= 0)) ||
|
|
95
|
+
(raw.maxOutputTokens !== undefined &&
|
|
96
|
+
(typeof raw.maxOutputTokens !== 'number' ||
|
|
97
|
+
!Number.isSafeInteger(raw.maxOutputTokens) ||
|
|
98
|
+
raw.maxOutputTokens <= 0)) ||
|
|
99
|
+
(raw.priority !== undefined &&
|
|
100
|
+
(typeof raw.priority !== 'number' || !Number.isFinite(raw.priority))))
|
|
84
101
|
return undefined;
|
|
85
102
|
const reasoning = raw.reasoning === undefined ? undefined : sanitizeReasoning(raw.reasoning);
|
|
86
103
|
if (raw.reasoning !== undefined && reasoning === undefined)
|
|
87
104
|
return undefined;
|
|
88
105
|
const thinkingType = raw.thinkingType;
|
|
89
|
-
if (thinkingType !== undefined &&
|
|
106
|
+
if (thinkingType !== undefined &&
|
|
107
|
+
thinkingType !== 'enabled' &&
|
|
108
|
+
thinkingType !== 'adaptive')
|
|
90
109
|
return undefined;
|
|
91
110
|
const fastTier = raw.fastTier;
|
|
92
111
|
if (fastTier !== undefined && typeof fastTier !== 'boolean')
|
|
93
112
|
return undefined;
|
|
94
113
|
const copilotWire = raw.copilotWire;
|
|
95
|
-
if (copilotWire !== undefined &&
|
|
114
|
+
if (copilotWire !== undefined &&
|
|
115
|
+
copilotWire !== 'chat-completions' &&
|
|
116
|
+
copilotWire !== 'responses') {
|
|
96
117
|
return undefined;
|
|
97
118
|
}
|
|
98
119
|
const copilotResponses = raw.copilotResponses;
|
|
99
120
|
if (copilotResponses !== undefined && typeof copilotResponses !== 'boolean')
|
|
100
121
|
return undefined;
|
|
101
122
|
const inputModalities = raw.inputModalities;
|
|
102
|
-
if (inputModalities !== undefined
|
|
103
|
-
|
|
104
|
-
|
|
123
|
+
if (inputModalities !== undefined &&
|
|
124
|
+
(!Array.isArray(inputModalities) ||
|
|
125
|
+
inputModalities.length === 0 ||
|
|
126
|
+
inputModalities.some((modality) => modality !== 'text' && modality !== 'image')))
|
|
105
127
|
return undefined;
|
|
106
128
|
return {
|
|
107
129
|
id: raw.id,
|
|
108
130
|
name: raw.name,
|
|
109
|
-
...raw.description === undefined
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
...raw.
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
...
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
...
|
|
119
|
-
|
|
131
|
+
...(raw.description === undefined
|
|
132
|
+
? {}
|
|
133
|
+
: { description: raw.description }),
|
|
134
|
+
...(raw.contextWindow === undefined
|
|
135
|
+
? {}
|
|
136
|
+
: { contextWindow: raw.contextWindow }),
|
|
137
|
+
...(raw.maxContextWindow === undefined
|
|
138
|
+
? {}
|
|
139
|
+
: { maxContextWindow: raw.maxContextWindow }),
|
|
140
|
+
...(raw.maxOutputTokens === undefined
|
|
141
|
+
? {}
|
|
142
|
+
: { maxOutputTokens: raw.maxOutputTokens }),
|
|
143
|
+
...(raw.priority === undefined ? {} : { priority: raw.priority }),
|
|
144
|
+
...(reasoning === undefined ? {} : { reasoning }),
|
|
145
|
+
...(thinkingType === undefined
|
|
146
|
+
? {}
|
|
147
|
+
: { thinkingType: thinkingType }),
|
|
148
|
+
...(fastTier === undefined ? {} : { fastTier }),
|
|
149
|
+
...(copilotWire === undefined
|
|
150
|
+
? {}
|
|
151
|
+
: { copilotWire: copilotWire }),
|
|
152
|
+
...(copilotResponses === undefined ? {} : { copilotResponses }),
|
|
153
|
+
...(inputModalities === undefined
|
|
154
|
+
? {}
|
|
155
|
+
: { inputModalities: [...inputModalities] }),
|
|
120
156
|
};
|
|
121
157
|
}
|
|
122
158
|
/**
|
|
@@ -164,13 +200,46 @@ async function readCatalogFile(path) {
|
|
|
164
200
|
return {};
|
|
165
201
|
}
|
|
166
202
|
}
|
|
203
|
+
/**
|
|
204
|
+
* Windows refuses to replace a file another handle holds open without
|
|
205
|
+
* `FILE_SHARE_DELETE` (an indexer, antivirus scan, or a second dsh profile
|
|
206
|
+
* reading the cache), surfacing as a transient `EPERM`/`EBUSY`/`EACCES` on
|
|
207
|
+
* `rename` (V1ki/dsh-plugin-subscriptions#129). On Windows only, retry
|
|
208
|
+
* briefly before giving the write up: on POSIX those codes are real
|
|
209
|
+
* failures, so retrying would only delay surfacing them.
|
|
210
|
+
*/
|
|
211
|
+
const RENAME_RETRY_CODES = new Set([
|
|
212
|
+
'EPERM',
|
|
213
|
+
'EBUSY',
|
|
214
|
+
'EACCES',
|
|
215
|
+
]);
|
|
216
|
+
const RENAME_RETRIES = 5;
|
|
217
|
+
const RENAME_RETRY_DELAY_MS = 20;
|
|
218
|
+
/** `rename` with a short bounded retry on Windows share-mode conflicts. */
|
|
219
|
+
async function renameWithRetry(from, to) {
|
|
220
|
+
for (let attempt = 0;; attempt++) {
|
|
221
|
+
try {
|
|
222
|
+
await rename(from, to);
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
catch (error) {
|
|
226
|
+
const code = error.code;
|
|
227
|
+
if (process.platform !== 'win32' ||
|
|
228
|
+
attempt >= RENAME_RETRIES ||
|
|
229
|
+
code === undefined ||
|
|
230
|
+
!RENAME_RETRY_CODES.has(code))
|
|
231
|
+
throw error;
|
|
232
|
+
await new Promise((resolve) => setTimeout(resolve, RENAME_RETRY_DELAY_MS * (attempt + 1)));
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
167
236
|
/** Persist the whole file atomically (tmp file + rename). */
|
|
168
237
|
async function writeCatalogFile(store, path) {
|
|
169
238
|
await mkdir(dirname(path), { recursive: true });
|
|
170
239
|
const tmp = `${path}.tmp-${process.pid}-${Math.random().toString(36).slice(2)}`;
|
|
171
240
|
try {
|
|
172
241
|
await writeFile(tmp, JSON.stringify(store, null, 2));
|
|
173
|
-
await
|
|
242
|
+
await renameWithRetry(tmp, path);
|
|
174
243
|
}
|
|
175
244
|
catch (error) {
|
|
176
245
|
await rm(tmp, { force: true });
|
|
@@ -245,15 +314,22 @@ export function accountCatalogStore(provider, account, path = modelsFilePath())
|
|
|
245
314
|
return {
|
|
246
315
|
async load() {
|
|
247
316
|
const section = accountSection(await readCatalogFile(path), provider);
|
|
248
|
-
return section !== undefined && Object.hasOwn(section, account)
|
|
317
|
+
return section !== undefined && Object.hasOwn(section, account)
|
|
318
|
+
? sanitizeSnapshot(section[account])
|
|
319
|
+
: undefined;
|
|
249
320
|
},
|
|
250
321
|
async save(snapshot) {
|
|
251
322
|
return serialize(path, async () => {
|
|
252
323
|
const store = await readCatalogFile(path);
|
|
253
|
-
const accounts = typeof store.accounts === 'object' &&
|
|
324
|
+
const accounts = typeof store.accounts === 'object' &&
|
|
325
|
+
store.accounts !== null &&
|
|
326
|
+
!Array.isArray(store.accounts)
|
|
254
327
|
? store.accounts
|
|
255
328
|
: {};
|
|
256
|
-
const section = {
|
|
329
|
+
const section = {
|
|
330
|
+
...(accountSection(store, provider) ?? {}),
|
|
331
|
+
[account]: snapshot,
|
|
332
|
+
};
|
|
257
333
|
store.accounts = { ...accounts, [provider]: section };
|
|
258
334
|
await writeCatalogFile(store, path);
|
|
259
335
|
});
|
|
@@ -266,7 +342,10 @@ export function accountCatalogStore(provider, account, path = modelsFilePath())
|
|
|
266
342
|
return;
|
|
267
343
|
const rest = { ...section };
|
|
268
344
|
delete rest[account];
|
|
269
|
-
store.accounts = {
|
|
345
|
+
store.accounts = {
|
|
346
|
+
...store.accounts,
|
|
347
|
+
[provider]: rest,
|
|
348
|
+
};
|
|
270
349
|
await writeCatalogFile(store, path);
|
|
271
350
|
});
|
|
272
351
|
},
|
|
@@ -16,9 +16,9 @@ export class ClaudeCliVersionCache extends NpmCliVersionCache {
|
|
|
16
16
|
url: CLAUDE_CLI_VERSION_URL,
|
|
17
17
|
label: 'Claude Code',
|
|
18
18
|
floor: () => claudeCliVersionFloor(detect),
|
|
19
|
-
...fetchFn === undefined ? {} : { fetchFn },
|
|
20
|
-
...now === undefined ? {} : { now },
|
|
21
|
-
...timeoutMs === undefined ? {} : { timeoutMs },
|
|
19
|
+
...(fetchFn === undefined ? {} : { fetchFn }),
|
|
20
|
+
...(now === undefined ? {} : { now }),
|
|
21
|
+
...(timeoutMs === undefined ? {} : { timeoutMs }),
|
|
22
22
|
});
|
|
23
23
|
}
|
|
24
24
|
}
|
|
@@ -137,6 +137,12 @@ export interface ClaudeAdapterOptions {
|
|
|
137
137
|
resolveCliVersion?: () => Promise<string>;
|
|
138
138
|
/** Cache breakpoint lifetime; absent means the API's five-minute default. */
|
|
139
139
|
promptCacheTtl?: PromptCacheTtl;
|
|
140
|
+
/**
|
|
141
|
+
* The Settings page's per-route TTL override, consulted on every request so
|
|
142
|
+
* a saved change applies from the next turn without a restart. Returning
|
|
143
|
+
* undefined follows {@link ClaudeAdapterOptions.promptCacheTtl}.
|
|
144
|
+
*/
|
|
145
|
+
promptCacheTtlOverride?: () => PromptCacheTtl | undefined;
|
|
140
146
|
}
|
|
141
147
|
/**
|
|
142
148
|
* Inline image data a Claude request may carry, in base64 bytes. Every turn
|
|
@@ -161,8 +167,9 @@ export declare const CLAUDE_REQUEST_IMAGE_BUDGET: number;
|
|
|
161
167
|
* @param effort - the reasoning effort, when the model advertises efforts.
|
|
162
168
|
* @param cacheTtl - lifetime of every cache breakpoint; defaults to five minutes.
|
|
163
169
|
* Requests that carry a `purpose` (compaction, session titles) always use five
|
|
164
|
-
* minutes to preserve their existing auxiliary-request behavior
|
|
165
|
-
*
|
|
170
|
+
* minutes to preserve their existing auxiliary-request behavior — the override
|
|
171
|
+
* changes the TTL for ordinary turns only, never the auxiliary floor. A
|
|
172
|
+
* five-minute mark can still read an entry a one-hour mark wrote.
|
|
166
173
|
* @returns the JSON body to POST.
|
|
167
174
|
*/
|
|
168
175
|
export declare function claudeRequestBody(options: GenerateOptions, messages: readonly TranslatableMessage[], maxTokens: number, thinking?: Record<string, unknown>, effort?: string, cacheTtl?: PromptCacheTtl): Record<string, unknown>;
|