@jingyi0605/codingns4dsh 0.2.1-rc.5 → 0.2.1-rc.7
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.en.md +4 -4
- package/README.md +5 -5
- package/data/build/dist/bootstrap/dsh-peer-host-preboot-shim.d.ts +1 -1
- package/data/build/dist/bootstrap/dsh-peer-host-preboot-shim.js +1 -1
- package/data/build/dist/client/bundle.js +1550 -148
- package/data/build/dist/client/bundle.js.map +1 -1
- package/data/build/dist/client/cli-slots.js +2 -2
- package/data/build/dist/client/cli-slots.js.map +1 -1
- package/data/build/dist/client/client.delegate-command.js +3 -2
- package/data/build/dist/client/client.delegate-command.js.map +1 -1
- package/data/build/dist/client/client.magpie-model-tag.js +24 -8
- package/data/build/dist/client/client.magpie-model-tag.js.map +1 -1
- package/data/build/dist/client/client.native-workspace-store.js +26 -15
- package/data/build/dist/client/client.native-workspace-store.js.map +1 -1
- package/data/build/dist/client/client.session-translation.js +25 -0
- package/data/build/dist/client/client.session-translation.js.map +1 -1
- package/data/build/dist/client/client.transport.js +224 -0
- package/data/build/dist/client/client.transport.js.map +1 -1
- package/data/build/dist/client/delegate-command.js +2 -1
- package/data/build/dist/client/delegate-command.js.map +1 -1
- package/data/build/dist/client/desktop-assistant.js +224 -0
- package/data/build/dist/client/features/index.d.ts +2 -1
- package/data/build/dist/client/features/index.d.ts.map +1 -1
- package/data/build/dist/client/features/index.js +3 -1
- package/data/build/dist/client/features/index.js.map +1 -1
- package/data/build/dist/client/features/magpie-management-page.d.ts +7 -3
- package/data/build/dist/client/features/magpie-management-page.d.ts.map +1 -1
- package/data/build/dist/client/features/magpie-management-page.js +142 -8
- package/data/build/dist/client/features/magpie-management-page.js.map +1 -1
- package/data/build/dist/client/features/workspace-mcp.d.ts +3 -0
- package/data/build/dist/client/features/workspace-mcp.d.ts.map +1 -0
- package/data/build/dist/client/features/workspace-mcp.js +320 -0
- package/data/build/dist/client/features/workspace-mcp.js.map +1 -0
- package/data/build/dist/client/locale.d.ts.map +1 -1
- package/data/build/dist/client/locale.js +180 -0
- package/data/build/dist/client/locale.js.map +1 -1
- package/data/build/dist/client/locales/magpie.d.ts.map +1 -1
- package/data/build/dist/client/locales/magpie.js +12 -0
- package/data/build/dist/client/locales/magpie.js.map +1 -1
- package/data/build/dist/client/locales/panels.d.ts.map +1 -1
- package/data/build/dist/client/locales/panels.js +18 -0
- package/data/build/dist/client/locales/panels.js.map +1 -1
- package/data/build/dist/client/locales/usage.d.ts.map +1 -1
- package/data/build/dist/client/locales/usage.js +14 -0
- package/data/build/dist/client/locales/usage.js.map +1 -1
- package/data/build/dist/client/magpie-model-tag.d.ts +4 -2
- package/data/build/dist/client/magpie-model-tag.d.ts.map +1 -1
- package/data/build/dist/client/magpie-model-tag.js +25 -8
- package/data/build/dist/client/magpie-model-tag.js.map +1 -1
- package/data/build/dist/client/native-model-translation-menu.d.ts +1 -0
- package/data/build/dist/client/native-model-translation-menu.d.ts.map +1 -1
- package/data/build/dist/client/native-model-translation-menu.js +2 -2
- package/data/build/dist/client/native-model-translation-menu.js.map +1 -1
- package/data/build/dist/client/session-translation-chat.d.ts.map +1 -1
- package/data/build/dist/client/session-translation-chat.js +6 -2
- package/data/build/dist/client/session-translation-chat.js.map +1 -1
- package/data/build/dist/client/settings-section.d.ts.map +1 -1
- package/data/build/dist/client/settings-section.js +6 -3
- package/data/build/dist/client/settings-section.js.map +1 -1
- package/data/build/dist/client/subscription-slot.d.ts.map +1 -1
- package/data/build/dist/client/subscription-slot.js +104 -11
- package/data/build/dist/client/subscription-slot.js.map +1 -1
- package/data/build/dist/dsh-capabilities/host/workspace-approval-adapter.d.ts +18 -0
- package/data/build/dist/dsh-capabilities/host/workspace-approval-adapter.d.ts.map +1 -0
- package/data/build/dist/dsh-capabilities/host/workspace-approval-adapter.js +172 -0
- package/data/build/dist/dsh-capabilities/host/workspace-approval-adapter.js.map +1 -0
- package/data/build/dist/dsh-capabilities/host/workspace-pending-questions-adapter.d.ts +28 -0
- package/data/build/dist/dsh-capabilities/host/workspace-pending-questions-adapter.d.ts.map +1 -0
- package/data/build/dist/dsh-capabilities/host/workspace-pending-questions-adapter.js +103 -0
- package/data/build/dist/dsh-capabilities/host/workspace-pending-questions-adapter.js.map +1 -0
- package/data/build/dist/dsh-capabilities/host/workspace-session-control-adapter.d.ts +26 -0
- package/data/build/dist/dsh-capabilities/host/workspace-session-control-adapter.d.ts.map +1 -0
- package/data/build/dist/dsh-capabilities/host/workspace-session-control-adapter.js +86 -0
- package/data/build/dist/dsh-capabilities/host/workspace-session-control-adapter.js.map +1 -0
- package/data/build/dist/dsh-capabilities/matrix.d.ts.map +1 -1
- package/data/build/dist/dsh-capabilities/matrix.js +17 -14
- package/data/build/dist/dsh-capabilities/matrix.js.map +1 -1
- package/data/build/dist/dsh-capabilities/routes.d.ts.map +1 -1
- package/data/build/dist/dsh-capabilities/routes.js +19 -10
- package/data/build/dist/dsh-capabilities/routes.js.map +1 -1
- package/data/build/dist/dsh-capabilities/types.d.ts +1 -1
- package/data/build/dist/dsh-capabilities/types.d.ts.map +1 -1
- package/data/build/dist/dsh-capabilities/types.js.map +1 -1
- package/data/build/dist/host/cli-adapters/claude-model-options.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/claude-model-options.js +13 -2
- package/data/build/dist/host/cli-adapters/claude-model-options.js.map +1 -1
- package/data/build/dist/host/cli-adapters/dsh-message-projector.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/dsh-message-projector.js +6 -2
- package/data/build/dist/host/cli-adapters/dsh-message-projector.js.map +1 -1
- package/data/build/dist/host/cli-adapters/feature.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/feature.js +12 -4
- package/data/build/dist/host/cli-adapters/feature.js.map +1 -1
- package/data/build/dist/host/cli-adapters/magpie-usage.d.ts +13 -2
- package/data/build/dist/host/cli-adapters/magpie-usage.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/magpie-usage.js +186 -14
- package/data/build/dist/host/cli-adapters/magpie-usage.js.map +1 -1
- package/data/build/dist/host/dsh-runtime-version.d.ts.map +1 -1
- package/data/build/dist/host/dsh-runtime-version.js +4 -1
- package/data/build/dist/host/dsh-runtime-version.js.map +1 -1
- package/data/build/dist/host/features/index.d.ts +1 -0
- package/data/build/dist/host/features/index.d.ts.map +1 -1
- package/data/build/dist/host/features/index.js +3 -0
- package/data/build/dist/host/features/index.js.map +1 -1
- package/data/build/dist/host/features/workspace-mcp.d.ts +9 -0
- package/data/build/dist/host/features/workspace-mcp.d.ts.map +1 -0
- package/data/build/dist/host/features/workspace-mcp.js +197 -0
- package/data/build/dist/host/features/workspace-mcp.js.map +1 -0
- package/data/build/dist/host/index.d.ts.map +1 -1
- package/data/build/dist/host/index.js +6 -2
- package/data/build/dist/host/index.js.map +1 -1
- package/data/build/dist/host/native-session-bridge.d.ts +2 -0
- package/data/build/dist/host/native-session-bridge.d.ts.map +1 -1
- package/data/build/dist/host/native-session-bridge.js +30 -0
- package/data/build/dist/host/native-session-bridge.js.map +1 -1
- package/data/build/dist/host/rpc.d.ts +4 -1
- package/data/build/dist/host/rpc.d.ts.map +1 -1
- package/data/build/dist/host/rpc.js +57 -9
- package/data/build/dist/host/rpc.js.map +1 -1
- package/data/build/dist/host/session-handle-eviction.d.ts +4 -2
- package/data/build/dist/host/session-handle-eviction.d.ts.map +1 -1
- package/data/build/dist/host/session-handle-eviction.js +10 -9
- package/data/build/dist/host/session-handle-eviction.js.map +1 -1
- package/data/build/dist/host/terminal/terminal-process-service.d.ts +22 -0
- package/data/build/dist/host/terminal/terminal-process-service.d.ts.map +1 -1
- package/data/build/dist/host/terminal/terminal-process-service.js +102 -0
- package/data/build/dist/host/terminal/terminal-process-service.js.map +1 -1
- package/data/build/dist/host/terminal/terminal-service.d.ts +5 -1
- package/data/build/dist/host/terminal/terminal-service.d.ts.map +1 -1
- package/data/build/dist/host/terminal/terminal-service.js +32 -0
- package/data/build/dist/host/terminal/terminal-service.js.map +1 -1
- package/data/build/dist/host/workspace-mcp/api-key-store.d.ts +16 -0
- package/data/build/dist/host/workspace-mcp/api-key-store.d.ts.map +1 -0
- package/data/build/dist/host/workspace-mcp/api-key-store.js +65 -0
- package/data/build/dist/host/workspace-mcp/api-key-store.js.map +1 -0
- package/data/build/dist/host/workspace-mcp/tools.d.ts +54 -0
- package/data/build/dist/host/workspace-mcp/tools.d.ts.map +1 -0
- package/data/build/dist/host/workspace-mcp/tools.js +800 -0
- package/data/build/dist/host/workspace-mcp/tools.js.map +1 -0
- package/data/build/dist/host/workspace-mcp/transport.d.ts +35 -0
- package/data/build/dist/host/workspace-mcp/transport.d.ts.map +1 -0
- package/data/build/dist/host/workspace-mcp/transport.js +575 -0
- package/data/build/dist/host/workspace-mcp/transport.js.map +1 -0
- package/data/build/dist/shared/contracts/cli-adapter.d.ts +2 -0
- package/data/build/dist/shared/contracts/cli-adapter.d.ts.map +1 -1
- package/data/build/dist/shared/contracts/errors.d.ts +2 -2
- package/data/build/dist/shared/contracts/errors.d.ts.map +1 -1
- package/data/build/dist/shared/contracts/errors.js +1 -1
- package/data/build/dist/shared/contracts/errors.js.map +1 -1
- package/data/build/dist/shared/contracts/magpie-management.d.ts +15 -1
- package/data/build/dist/shared/contracts/magpie-management.d.ts.map +1 -1
- package/data/build/dist/shared/contracts/session-translation.d.ts +4 -0
- package/data/build/dist/shared/contracts/session-translation.d.ts.map +1 -1
- package/data/build/dist/shared/contracts/session-translation.js +21 -0
- package/data/build/dist/shared/contracts/session-translation.js.map +1 -1
- package/data/build/dist/shared/contracts/subscription.d.ts +7 -0
- package/data/build/dist/shared/contracts/subscription.d.ts.map +1 -1
- package/data/build/dist/shared/contracts/subscription.js.map +1 -1
- package/data/build/dist/shared/contracts/terminal.d.ts +2 -0
- package/data/build/dist/shared/contracts/terminal.d.ts.map +1 -1
- package/data/build/dist/shared/contracts/version.d.ts +7 -7
- package/data/build/dist/shared/contracts/version.d.ts.map +1 -1
- package/data/build/dist/shared/contracts/version.js +11 -17
- package/data/build/dist/shared/contracts/version.js.map +1 -1
- package/data/build/dist/shared/index.d.ts +1 -1
- package/data/build/dist/shared/index.d.ts.map +1 -1
- package/data/build/dist/shared/index.js +1 -1
- package/data/build/dist/shared/index.js.map +1 -1
- package/package.json +3 -3
- package/profile/README.md +6 -6
- package/profile/package.json +3 -3
- package/profile/scripts/check-dsh-install.mjs +14 -1
- package/profile/version.json +2 -2
- package/scripts/check-dsh-install.mjs +14 -1
- package/version.json +2 -2
|
@@ -135,9 +135,12 @@ export class MagpieUsageService {
|
|
|
135
135
|
if (id === null)
|
|
136
136
|
return model;
|
|
137
137
|
const record = metadata?.get(id);
|
|
138
|
-
const
|
|
138
|
+
const metadataModel = record === undefined
|
|
139
139
|
? model.source === 'magpie' ? model : { ...model, source: 'magpie' }
|
|
140
140
|
: mergeMagpieModelMetadata(model, record);
|
|
141
|
+
const providerId = providerFromModel(id);
|
|
142
|
+
const enriched = providerId === null || metadataModel.magpieProviderId === providerId
|
|
143
|
+
? metadataModel : { ...metadataModel, magpieProviderId: providerId };
|
|
141
144
|
if (enriched === model)
|
|
142
145
|
return model;
|
|
143
146
|
groupChanged = true;
|
|
@@ -154,11 +157,13 @@ export class MagpieUsageService {
|
|
|
154
157
|
.filter((id) => !existingModelIds.has(id))
|
|
155
158
|
.map((id) => {
|
|
156
159
|
const record = metadata?.get(id);
|
|
160
|
+
const providerId = providerFromModel(id);
|
|
157
161
|
const model = {
|
|
158
162
|
id,
|
|
159
163
|
name: record?.name ?? agentCatalog.displayNames.get(id) ?? id,
|
|
160
164
|
efforts: record?.efforts ?? [],
|
|
161
165
|
source: 'magpie',
|
|
166
|
+
...(providerId === null ? {} : { magpieProviderId: providerId }),
|
|
162
167
|
};
|
|
163
168
|
return record === undefined ? model : mergeMagpieModelMetadata(model, record);
|
|
164
169
|
});
|
|
@@ -178,6 +183,31 @@ export class MagpieUsageService {
|
|
|
178
183
|
}
|
|
179
184
|
return changed ? { ...resolvedCatalog, groups } : resolvedCatalog;
|
|
180
185
|
}
|
|
186
|
+
async updateAccountPolicy(input, signal) {
|
|
187
|
+
const update = readMagpieAccountPolicyUpdate(input);
|
|
188
|
+
const path = update.policy === 'credits' ? '/api/settings/codex-credits' : '/api/settings/codex-auto-reset';
|
|
189
|
+
const body = update.policy === 'credits'
|
|
190
|
+
? { user: update.user, on: update.enabled }
|
|
191
|
+
: { user: update.user, on: update.enabled, when: update.policy };
|
|
192
|
+
const result = await this.requestWebJson(path, { method: 'POST', body }, signal);
|
|
193
|
+
if (!result.ok)
|
|
194
|
+
throw new Error('Magpie account policy update failed');
|
|
195
|
+
const settings = parseMagpieAccountPolicies(result.value);
|
|
196
|
+
if (settings === null || !magpieAccountPolicyMatches(settings, update)) {
|
|
197
|
+
throw new Error('Magpie account policy update could not be verified');
|
|
198
|
+
}
|
|
199
|
+
return update;
|
|
200
|
+
}
|
|
201
|
+
async resetCodexAccount(input, signal) {
|
|
202
|
+
const user = readMagpieAccountUser(input);
|
|
203
|
+
const result = await this.requestWebJson('/api/usage/codex-reset', {
|
|
204
|
+
method: 'POST',
|
|
205
|
+
body: { user },
|
|
206
|
+
}, signal);
|
|
207
|
+
if (!result.ok)
|
|
208
|
+
throw new Error('Magpie Codex reset failed');
|
|
209
|
+
return { outcome: normalizeMagpieResetOutcome(result.value) };
|
|
210
|
+
}
|
|
181
211
|
/** Return an exact, CLI-confirmed Magpie model record for trusted Host use. */
|
|
182
212
|
async readModelMetadata(adapterId, modelId, signal) {
|
|
183
213
|
signal?.throwIfAborted();
|
|
@@ -204,16 +234,16 @@ export class MagpieUsageService {
|
|
|
204
234
|
return parseMagpieContextResponse(response.value, options);
|
|
205
235
|
}
|
|
206
236
|
/** Read bounded, graph-ready usage and quota data through authenticated Magpie Web. */
|
|
207
|
-
async readDashboard(period, signal) {
|
|
237
|
+
async readDashboard(period, signal, force = false) {
|
|
208
238
|
signal?.throwIfAborted();
|
|
209
239
|
const cached = this.dashboardCache.get(period);
|
|
210
|
-
if (cached !== undefined) {
|
|
240
|
+
if (!force && cached !== undefined) {
|
|
211
241
|
if (this.now() - cached.loadedAt >= MAGPIE_DASHBOARD_CACHE_TTL_MS) {
|
|
212
242
|
void this.refreshDashboard(period).catch(() => undefined);
|
|
213
243
|
}
|
|
214
244
|
return cached.dashboard;
|
|
215
245
|
}
|
|
216
|
-
return this.refreshDashboard(period, signal);
|
|
246
|
+
return this.refreshDashboard(period, signal, force);
|
|
217
247
|
}
|
|
218
248
|
/** Stream cumulative dashboard snapshots as each independent Web API part is ready. */
|
|
219
249
|
async *readDashboardStream(period, signal, force = false) {
|
|
@@ -233,22 +263,25 @@ export class MagpieUsageService {
|
|
|
233
263
|
if (latest !== undefined)
|
|
234
264
|
this.dashboardCache.set(period, { dashboard: latest, loadedAt: this.now() });
|
|
235
265
|
}
|
|
236
|
-
async refreshDashboard(period, signal) {
|
|
266
|
+
async refreshDashboard(period, signal, force = false) {
|
|
237
267
|
const pending = this.dashboardRefreshes.get(period);
|
|
238
|
-
if (pending !== undefined)
|
|
268
|
+
if (!force && pending !== undefined)
|
|
239
269
|
return awaitWithSignal(pending, signal);
|
|
240
|
-
|
|
270
|
+
let request = null;
|
|
271
|
+
const task = (async () => {
|
|
241
272
|
let latest;
|
|
242
273
|
for await (const chunk of this.readDashboardNetwork(period, signal))
|
|
243
274
|
latest = chunk.dashboard;
|
|
244
275
|
if (latest === undefined)
|
|
245
276
|
throw new Error('Magpie dashboard returned no snapshot');
|
|
246
|
-
|
|
277
|
+
if (request !== null && this.dashboardRefreshes.get(period) === request)
|
|
278
|
+
this.dashboardCache.set(period, { dashboard: latest, loadedAt: this.now() });
|
|
247
279
|
return latest;
|
|
248
280
|
})().finally(() => {
|
|
249
|
-
if (this.dashboardRefreshes.get(period) === request)
|
|
281
|
+
if (request !== null && this.dashboardRefreshes.get(period) === request)
|
|
250
282
|
this.dashboardRefreshes.delete(period);
|
|
251
283
|
});
|
|
284
|
+
request = task;
|
|
252
285
|
this.dashboardRefreshes.set(period, request);
|
|
253
286
|
return awaitWithSignal(request, signal);
|
|
254
287
|
}
|
|
@@ -257,19 +290,23 @@ export class MagpieUsageService {
|
|
|
257
290
|
let dashboard = emptyMagpieDashboard(period, capturedAt);
|
|
258
291
|
let quotas = null;
|
|
259
292
|
let logoLoad;
|
|
293
|
+
let settingsRead = false;
|
|
260
294
|
const results = new Map([
|
|
261
295
|
['usage', this.timedDashboardRead('usage', () => this.readWebJson(`/api/usage?period=${magpieWebPeriod(period)}`, signal))],
|
|
262
296
|
['quotas', this.timedDashboardRead('quotas', () => this.readWebJson('/api/usage/quotas', signal))],
|
|
297
|
+
['settings', this.timedDashboardRead('settings', () => this.readWebJson('/api/settings', signal))],
|
|
263
298
|
['history', this.timedDashboardRead('history', () => this.readWebJson('/api/usage/quotas/history?days=30', signal))],
|
|
264
299
|
]);
|
|
265
300
|
const completed = new Map();
|
|
301
|
+
let policies = null;
|
|
266
302
|
while (results.size > 0) {
|
|
267
303
|
const result = await Promise.race(results.values());
|
|
268
304
|
results.delete(result.part);
|
|
269
305
|
const response = asRecord(result.value);
|
|
270
306
|
const partOk = result.ok && response?.ok === true;
|
|
271
307
|
const partValue = partOk ? response.value : undefined;
|
|
272
|
-
|
|
308
|
+
if (result.part !== 'settings')
|
|
309
|
+
completed.set(result.part, partOk);
|
|
273
310
|
if (result.part === 'usage') {
|
|
274
311
|
const parsed = partOk ? parseMagpieDashboardUsage(partValue) : null;
|
|
275
312
|
dashboard = {
|
|
@@ -286,10 +323,21 @@ export class MagpieUsageService {
|
|
|
286
323
|
};
|
|
287
324
|
}
|
|
288
325
|
else if (result.part === 'quotas') {
|
|
289
|
-
|
|
326
|
+
const parsedQuotas = partOk ? parseMagpieQuotaCards(partValue) : null;
|
|
327
|
+
quotas = parsedQuotas === null ? null : applyMagpieDashboardAccountPolicies(parsedQuotas, policies);
|
|
290
328
|
dashboard = { ...dashboard, quotaStatus: quotas === null ? 'unavailable' : 'available', quotas: quotas ?? [] };
|
|
329
|
+
if (quotas !== null && settingsRead)
|
|
330
|
+
logoLoad = this.timedDashboardRead('quota-logos', () => this.attachQuotaLogos(quotas, signal)).then((logoResult) => logoResult.value);
|
|
331
|
+
}
|
|
332
|
+
else if (result.part === 'settings') {
|
|
333
|
+
settingsRead = true;
|
|
334
|
+
policies = partOk ? parseMagpieAccountPolicies(partValue) : null;
|
|
335
|
+
if (quotas !== null && policies !== null) {
|
|
336
|
+
quotas = applyMagpieDashboardAccountPolicies(quotas, policies);
|
|
337
|
+
dashboard = { ...dashboard, quotas };
|
|
338
|
+
}
|
|
291
339
|
if (quotas !== null)
|
|
292
|
-
logoLoad = this.timedDashboardRead('quota-logos', () => this.attachQuotaLogos(quotas, signal)).then((
|
|
340
|
+
logoLoad = this.timedDashboardRead('quota-logos', () => this.attachQuotaLogos(quotas, signal)).then((logoResult) => logoResult.value);
|
|
293
341
|
}
|
|
294
342
|
else {
|
|
295
343
|
const parsed = partOk ? parseMagpieQuotaHistory(partValue) : null;
|
|
@@ -469,10 +517,11 @@ export class MagpieUsageService {
|
|
|
469
517
|
}
|
|
470
518
|
async readFromWeb(agent, modelId, sessionId, magpieSessionId, fallbackSessionId, signal, includeRoute, allowPendingSession) {
|
|
471
519
|
const capturedAt = new Date(this.now()).toISOString();
|
|
472
|
-
const [usageResult, sessionResult, quotaResult] = await Promise.all([
|
|
520
|
+
const [usageResult, sessionResult, quotaResult, settingsResult] = await Promise.all([
|
|
473
521
|
this.readWebJson('/api/usage?period=today', signal),
|
|
474
522
|
this.readWebJson('/api/usage?period=all', signal),
|
|
475
523
|
this.readWebJson('/api/usage/quotas', signal),
|
|
524
|
+
agent === 'codex' ? this.readWebJson('/api/settings', signal) : Promise.resolve({ ok: false }),
|
|
476
525
|
]);
|
|
477
526
|
const aggregate = usageResult.ok ? readTotals(usageResult.value) : null;
|
|
478
527
|
const primarySession = sessionResult.ok && magpieSessionId !== null
|
|
@@ -514,7 +563,9 @@ export class MagpieUsageService {
|
|
|
514
563
|
: !canReadRoute || !routeHistoryValid
|
|
515
564
|
? 'unavailable'
|
|
516
565
|
: 'no-route';
|
|
517
|
-
const allQuotas = quotaResult.ok
|
|
566
|
+
const allQuotas = quotaResult.ok
|
|
567
|
+
? applyMagpieAccountPolicies(parseMagpieQuotas(quotaResult.value), settingsResult.ok ? settingsResult.value : null)
|
|
568
|
+
: null;
|
|
518
569
|
const routeProviders = [...new Set([
|
|
519
570
|
providerFromRoute(route),
|
|
520
571
|
...routeHistory.map((record) => record.provider),
|
|
@@ -725,6 +776,20 @@ export class MagpieUsageService {
|
|
|
725
776
|
return { ok: false };
|
|
726
777
|
}
|
|
727
778
|
}
|
|
779
|
+
async requestWebJson(path, options, signal) {
|
|
780
|
+
if (this.webApi === undefined)
|
|
781
|
+
return { ok: false };
|
|
782
|
+
try {
|
|
783
|
+
return {
|
|
784
|
+
ok: true,
|
|
785
|
+
value: await this.webApi.requestJson(path, signal === undefined ? options : { ...options, signal }),
|
|
786
|
+
};
|
|
787
|
+
}
|
|
788
|
+
catch {
|
|
789
|
+
signal?.throwIfAborted();
|
|
790
|
+
return { ok: false };
|
|
791
|
+
}
|
|
792
|
+
}
|
|
728
793
|
/** Provider management data is the canonical source when a usage row mislabels its upstream. */
|
|
729
794
|
async readProviderCatalog(signal) {
|
|
730
795
|
const cached = this.providerCatalog;
|
|
@@ -1390,6 +1455,113 @@ export function parseMagpieQuotas(value) {
|
|
|
1390
1455
|
}
|
|
1391
1456
|
return quotas;
|
|
1392
1457
|
}
|
|
1458
|
+
function parseMagpieAccountPolicies(value) {
|
|
1459
|
+
const root = asRecord(value);
|
|
1460
|
+
if (root === null)
|
|
1461
|
+
return null;
|
|
1462
|
+
const autoResetUsers = readLowercaseSet(root.codexAutoReset, 500);
|
|
1463
|
+
const noCreditsUsers = readLowercaseSet(root.codexNoCredits, 500);
|
|
1464
|
+
const autoResetOnly = new Map();
|
|
1465
|
+
const only = asRecord(root.codexAutoResetOnly);
|
|
1466
|
+
if (only !== null) {
|
|
1467
|
+
for (const [user, value] of Object.entries(only).slice(0, 500)) {
|
|
1468
|
+
if (value === 'week' || value === 'expiring')
|
|
1469
|
+
autoResetOnly.set(user.toLocaleLowerCase(), value);
|
|
1470
|
+
}
|
|
1471
|
+
}
|
|
1472
|
+
if (autoResetUsers === null || noCreditsUsers === null)
|
|
1473
|
+
return null;
|
|
1474
|
+
return { autoResetUsers, autoResetOnly, noCreditsUsers };
|
|
1475
|
+
}
|
|
1476
|
+
function applyMagpieAccountPolicies(quotas, settingsValue) {
|
|
1477
|
+
if (quotas === null)
|
|
1478
|
+
return null;
|
|
1479
|
+
const settings = parseMagpieAccountPolicies(settingsValue);
|
|
1480
|
+
if (settings === null)
|
|
1481
|
+
return quotas;
|
|
1482
|
+
return quotas.map((quota) => {
|
|
1483
|
+
if (quota.provider.toLocaleLowerCase() !== 'codex' || quota.user === null)
|
|
1484
|
+
return quota;
|
|
1485
|
+
const user = quota.user.toLocaleLowerCase();
|
|
1486
|
+
const enabled = settings.autoResetUsers.has(user);
|
|
1487
|
+
const only = settings.autoResetOnly.get(user);
|
|
1488
|
+
return {
|
|
1489
|
+
...quota,
|
|
1490
|
+
autoReset: {
|
|
1491
|
+
week: enabled && only !== 'expiring',
|
|
1492
|
+
expiring: enabled && only !== 'week',
|
|
1493
|
+
},
|
|
1494
|
+
useCredits: !settings.noCreditsUsers.has(user),
|
|
1495
|
+
};
|
|
1496
|
+
});
|
|
1497
|
+
}
|
|
1498
|
+
function applyMagpieDashboardAccountPolicies(quotas, settings) {
|
|
1499
|
+
return quotas.map((quota) => {
|
|
1500
|
+
if (quota.provider.toLocaleLowerCase() !== 'codex' || quota.user === null)
|
|
1501
|
+
return quota;
|
|
1502
|
+
if (settings === null)
|
|
1503
|
+
return { ...quota, policyStatus: 'unavailable' };
|
|
1504
|
+
const user = quota.user.toLocaleLowerCase();
|
|
1505
|
+
const enabled = settings.autoResetUsers.has(user);
|
|
1506
|
+
const only = settings.autoResetOnly.get(user);
|
|
1507
|
+
return {
|
|
1508
|
+
...quota,
|
|
1509
|
+
autoReset: {
|
|
1510
|
+
week: enabled && only !== 'expiring',
|
|
1511
|
+
expiring: enabled && only !== 'week',
|
|
1512
|
+
},
|
|
1513
|
+
useCredits: !settings.noCreditsUsers.has(user),
|
|
1514
|
+
policyStatus: 'available',
|
|
1515
|
+
};
|
|
1516
|
+
});
|
|
1517
|
+
}
|
|
1518
|
+
function readLowercaseSet(value, maxItems) {
|
|
1519
|
+
if (value === undefined)
|
|
1520
|
+
return new Set();
|
|
1521
|
+
if (!Array.isArray(value) || value.length > maxItems)
|
|
1522
|
+
return null;
|
|
1523
|
+
const values = value.filter((item) => typeof item === 'string' && item.trim() !== '');
|
|
1524
|
+
return values.length === value.length
|
|
1525
|
+
? new Set(values.map((item) => item.trim().toLocaleLowerCase()))
|
|
1526
|
+
: null;
|
|
1527
|
+
}
|
|
1528
|
+
function readMagpieAccountUser(value) {
|
|
1529
|
+
const record = asRecord(value);
|
|
1530
|
+
const user = typeof record?.user === 'string' ? record.user.trim() : '';
|
|
1531
|
+
if (user === '' || user.length > 180)
|
|
1532
|
+
throw new TypeError('Magpie account user is invalid');
|
|
1533
|
+
return user;
|
|
1534
|
+
}
|
|
1535
|
+
function readMagpieAccountPolicyUpdate(value) {
|
|
1536
|
+
const record = asRecord(value);
|
|
1537
|
+
const user = readMagpieAccountUser(value);
|
|
1538
|
+
const policy = record?.policy;
|
|
1539
|
+
if (policy !== 'week' && policy !== 'expiring' && policy !== 'credits') {
|
|
1540
|
+
throw new TypeError('Magpie account policy is invalid');
|
|
1541
|
+
}
|
|
1542
|
+
if (typeof record?.enabled !== 'boolean')
|
|
1543
|
+
throw new TypeError('Magpie account policy state is invalid');
|
|
1544
|
+
return { user, policy, enabled: record.enabled };
|
|
1545
|
+
}
|
|
1546
|
+
function magpieAccountPolicyMatches(settings, update) {
|
|
1547
|
+
const user = update.user.toLocaleLowerCase();
|
|
1548
|
+
if (update.policy === 'credits')
|
|
1549
|
+
return settings.noCreditsUsers.has(user) !== update.enabled;
|
|
1550
|
+
const enabled = settings.autoResetUsers.has(user);
|
|
1551
|
+
const only = settings.autoResetOnly.get(user);
|
|
1552
|
+
const current = update.policy === 'week'
|
|
1553
|
+
? enabled && only !== 'expiring'
|
|
1554
|
+
: enabled && only !== 'week';
|
|
1555
|
+
return current === update.enabled;
|
|
1556
|
+
}
|
|
1557
|
+
function normalizeMagpieResetOutcome(value) {
|
|
1558
|
+
const record = asRecord(value);
|
|
1559
|
+
const outcome = record?.code ?? record?.outcome;
|
|
1560
|
+
if (outcome === 'reset' || outcome === 'alreadyRedeemed' || outcome === 'nothingToReset' || outcome === 'noCredit') {
|
|
1561
|
+
return outcome;
|
|
1562
|
+
}
|
|
1563
|
+
throw new Error('Magpie returned an unknown reset result');
|
|
1564
|
+
}
|
|
1393
1565
|
/** Normalize the live aggregate and per-dimension usage response. */
|
|
1394
1566
|
export function parseMagpieDashboardUsage(value) {
|
|
1395
1567
|
const root = asRecord(value);
|