dsh-subscriptions 0.1.5 → 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 -154
- 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.d.ts +73 -2
- package/lib/auth/rpc.js +124 -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 +13 -0
- package/lib/client/OllamaCard.js +94 -0
- package/lib/client/OllamaSettingsManager.d.ts +24 -0
- package/lib/client/OllamaSettingsManager.js +329 -0
- package/lib/client/ProviderAccountManager.d.ts +1 -1
- package/lib/client/ProviderAccountManager.js +164 -49
- package/lib/client/ProviderModelEditor.js +109 -26
- package/lib/client/SpeedSelect.d.ts +62 -14
- package/lib/client/SpeedSelect.js +257 -46
- package/lib/client/SubscriptionUsageBadge.d.ts +5 -11
- package/lib/client/SubscriptionUsageBadge.js +301 -112
- package/lib/client/SubscriptionsSection.d.ts +2 -0
- package/lib/client/SubscriptionsSection.js +259 -85
- package/lib/client/UsageBadgeDisplaySetting.js +35 -12
- package/lib/client/UsageMeter.d.ts +1 -1
- package/lib/client/UsageMeter.js +69 -27
- 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 +78 -0
- package/lib/client/locales.js +121 -34
- package/lib/client/ollama-draft.d.ts +229 -0
- package/lib/client/ollama-draft.js +255 -0
- 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.d.ts +7 -0
- package/lib/client/usage-pace.js +43 -10
- package/lib/client.js +1647 -266
- package/lib/client.js.map +1 -1
- package/lib/http.js +1 -1
- package/lib/index.d.ts +28 -3
- package/lib/index.js +9329 -8217
- package/lib/model-defaults.js +4 -2
- package/lib/provider-settings.d.ts +14 -1
- package/lib/provider-settings.js +64 -20
- 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 +23 -3
- package/lib/providers/claude.js +167 -92
- 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.d.ts +14 -0
- package/lib/providers/common.js +118 -38
- 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.d.ts +9 -2
- package/lib/providers/external-usage-controller.js +30 -7
- package/lib/providers/external-usage.d.ts +8 -0
- package/lib/providers/external-usage.js +140 -20
- 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.d.ts +90 -0
- package/lib/providers/ollama-settings.js +213 -0
- package/lib/providers/ollama-web.d.ts +46 -0
- package/lib/providers/ollama-web.js +231 -0
- package/lib/providers/ollama.d.ts +107 -0
- package/lib/providers/ollama.js +608 -0
- 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
|
}
|
|
@@ -127,10 +127,22 @@ export interface ClaudeAdapterOptions {
|
|
|
127
127
|
* the provider's own default.
|
|
128
128
|
*/
|
|
129
129
|
defaultEffortOf?: (model: string) => string | undefined;
|
|
130
|
+
/**
|
|
131
|
+
* The user's local context-window override for one model (the Settings
|
|
132
|
+
* editor). Returns undefined to follow the advertised window. The result
|
|
133
|
+
* is capped at that window: Anthropic advertises no separate maximum.
|
|
134
|
+
*/
|
|
135
|
+
contextWindowOf?: (model: string) => number | undefined;
|
|
130
136
|
/** Resolves the Claude Code version to present (npm-backed); absent means the local floor. */
|
|
131
137
|
resolveCliVersion?: () => Promise<string>;
|
|
132
138
|
/** Cache breakpoint lifetime; absent means the API's five-minute default. */
|
|
133
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;
|
|
134
146
|
}
|
|
135
147
|
/**
|
|
136
148
|
* Inline image data a Claude request may carry, in base64 bytes. Every turn
|
|
@@ -155,8 +167,9 @@ export declare const CLAUDE_REQUEST_IMAGE_BUDGET: number;
|
|
|
155
167
|
* @param effort - the reasoning effort, when the model advertises efforts.
|
|
156
168
|
* @param cacheTtl - lifetime of every cache breakpoint; defaults to five minutes.
|
|
157
169
|
* Requests that carry a `purpose` (compaction, session titles) always use five
|
|
158
|
-
* minutes to preserve their existing auxiliary-request behavior
|
|
159
|
-
*
|
|
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.
|
|
160
173
|
* @returns the JSON body to POST.
|
|
161
174
|
*/
|
|
162
175
|
export declare function claudeRequestBody(options: GenerateOptions, messages: readonly TranslatableMessage[], maxTokens: number, thinking?: Record<string, unknown>, effort?: string, cacheTtl?: PromptCacheTtl): Record<string, unknown>;
|
|
@@ -183,7 +196,14 @@ export declare class ClaudeAdapter extends LlmAdapter {
|
|
|
183
196
|
listOwnModels(provider: string, account?: string, signal?: AbortSignal): Promise<readonly LlmModelInfo[]>;
|
|
184
197
|
resolveModel(provider: string, model: string): Promise<LlmResolvedModelInfo>;
|
|
185
198
|
/** Capability resolution of the provider's own models (the pool resolves members here). */
|
|
186
|
-
resolveOwnModel(provider: string, model: string): Promise<LlmResolvedModelInfo>;
|
|
199
|
+
resolveOwnModel(provider: string, model: string, account?: string): Promise<LlmResolvedModelInfo>;
|
|
200
|
+
/** The advertised window is both the default and the ceiling for a local override. */
|
|
201
|
+
private contextLimitsFor;
|
|
202
|
+
/** Account-specific bounds the Settings editor shows next to a model's override input. */
|
|
203
|
+
contextLimits(model: string, account?: string): Promise<{
|
|
204
|
+
default: number;
|
|
205
|
+
max: number;
|
|
206
|
+
}>;
|
|
187
207
|
stream(options: GenerateOptions): AsyncIterable<StreamChunk>;
|
|
188
208
|
/** Pool seam: stream through one specific account instead of the default. */
|
|
189
209
|
streamAccount(options: GenerateOptions, account: string): AsyncIterable<StreamChunk>;
|