@jingyi0605/codingns4dsh 0.2.1-rc.3 → 0.2.1-rc.5
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 +3 -3
- package/README.md +3 -3
- package/data/build/dist/client/bundle.js +1838 -223
- package/data/build/dist/client/bundle.js.map +1 -1
- package/data/build/dist/client/cli-session-config-cache.d.ts.map +1 -1
- package/data/build/dist/client/cli-session-config-cache.js +9 -3
- package/data/build/dist/client/cli-session-config-cache.js.map +1 -1
- package/data/build/dist/client/client.native-workspace-store.js +7 -1
- package/data/build/dist/client/client.native-workspace-store.js.map +1 -1
- package/data/build/dist/client/client.transport.js +276 -60
- package/data/build/dist/client/client.transport.js.map +1 -1
- package/data/build/dist/client/desktop-assistant.js +274 -58
- package/data/build/dist/client/features/cli-adapters.d.ts.map +1 -1
- package/data/build/dist/client/features/cli-adapters.js +13 -1
- package/data/build/dist/client/features/cli-adapters.js.map +1 -1
- package/data/build/dist/client/features/index.d.ts.map +1 -1
- package/data/build/dist/client/features/index.js +2 -0
- package/data/build/dist/client/features/index.js.map +1 -1
- package/data/build/dist/client/features/magpie-management-controls.d.ts.map +1 -1
- package/data/build/dist/client/features/magpie-management-controls.js +45 -10
- package/data/build/dist/client/features/magpie-management-controls.js.map +1 -1
- package/data/build/dist/client/features/magpie-management-page.d.ts +6 -1
- package/data/build/dist/client/features/magpie-management-page.d.ts.map +1 -1
- package/data/build/dist/client/features/magpie-management-page.js +109 -37
- package/data/build/dist/client/features/magpie-management-page.js.map +1 -1
- package/data/build/dist/client/features/magpie-management.d.ts.map +1 -1
- package/data/build/dist/client/features/magpie-management.js +3 -2
- package/data/build/dist/client/features/magpie-management.js.map +1 -1
- package/data/build/dist/client/features/plugin-update.d.ts +3 -0
- package/data/build/dist/client/features/plugin-update.d.ts.map +1 -0
- package/data/build/dist/client/features/plugin-update.js +8 -0
- package/data/build/dist/client/features/plugin-update.js.map +1 -0
- package/data/build/dist/client/features/types.d.ts +3 -0
- package/data/build/dist/client/features/types.d.ts.map +1 -1
- package/data/build/dist/client/locale.d.ts.map +1 -1
- package/data/build/dist/client/locale.js +3 -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 +92 -12
- package/data/build/dist/client/locales/magpie.js.map +1 -1
- package/data/build/dist/client/locales/pluginUpdate.d.ts +3 -0
- package/data/build/dist/client/locales/pluginUpdate.d.ts.map +1 -0
- package/data/build/dist/client/locales/pluginUpdate.js +131 -0
- package/data/build/dist/client/locales/pluginUpdate.js.map +1 -0
- package/data/build/dist/client/locales/usage.d.ts.map +1 -1
- package/data/build/dist/client/locales/usage.js +2 -0
- package/data/build/dist/client/locales/usage.js.map +1 -1
- package/data/build/dist/client/magpie-context-meter.d.ts +18 -0
- package/data/build/dist/client/magpie-context-meter.d.ts.map +1 -0
- package/data/build/dist/client/magpie-context-meter.js +274 -0
- package/data/build/dist/client/magpie-context-meter.js.map +1 -0
- package/data/build/dist/client/magpie-context-store.d.ts +32 -0
- package/data/build/dist/client/magpie-context-store.d.ts.map +1 -0
- package/data/build/dist/client/magpie-context-store.js +165 -0
- package/data/build/dist/client/magpie-context-store.js.map +1 -0
- package/data/build/dist/client/settings-promo-styles.d.ts +5 -0
- package/data/build/dist/client/settings-promo-styles.d.ts.map +1 -1
- package/data/build/dist/client/settings-promo-styles.js +15 -2
- package/data/build/dist/client/settings-promo-styles.js.map +1 -1
- package/data/build/dist/client/settings-promo.d.ts +4 -2
- package/data/build/dist/client/settings-promo.d.ts.map +1 -1
- package/data/build/dist/client/settings-promo.js +4 -4
- package/data/build/dist/client/settings-promo.js.map +1 -1
- package/data/build/dist/client/settings-section.d.ts +2 -3
- package/data/build/dist/client/settings-section.d.ts.map +1 -1
- package/data/build/dist/client/settings-section.js +7 -7
- package/data/build/dist/client/settings-section.js.map +1 -1
- package/data/build/dist/client/settings-update.d.ts +8 -0
- package/data/build/dist/client/settings-update.d.ts.map +1 -0
- package/data/build/dist/client/settings-update.js +57 -0
- package/data/build/dist/client/settings-update.js.map +1 -0
- package/data/build/dist/client/subscription-slot.d.ts +3 -2
- package/data/build/dist/client/subscription-slot.d.ts.map +1 -1
- package/data/build/dist/client/subscription-slot.js +115 -43
- package/data/build/dist/client/subscription-slot.js.map +1 -1
- package/data/build/dist/client/update-panel-styles.d.ts +29 -0
- package/data/build/dist/client/update-panel-styles.d.ts.map +1 -0
- package/data/build/dist/client/update-panel-styles.js +69 -0
- package/data/build/dist/client/update-panel-styles.js.map +1 -0
- package/data/build/dist/client/update-panel.d.ts +7 -0
- package/data/build/dist/client/update-panel.d.ts.map +1 -0
- package/data/build/dist/client/update-panel.js +52 -0
- package/data/build/dist/client/update-panel.js.map +1 -0
- package/data/build/dist/client/update-store.d.ts +43 -0
- package/data/build/dist/client/update-store.d.ts.map +1 -0
- package/data/build/dist/client/update-store.js +207 -0
- package/data/build/dist/client/update-store.js.map +1 -0
- package/data/build/dist/dsh-capabilities/client/plugin-reload-adapter.d.ts +4 -0
- package/data/build/dist/dsh-capabilities/client/plugin-reload-adapter.d.ts.map +1 -0
- package/data/build/dist/dsh-capabilities/client/plugin-reload-adapter.js +6 -0
- package/data/build/dist/dsh-capabilities/client/plugin-reload-adapter.js.map +1 -0
- package/data/build/dist/dsh-capabilities/client/session-performance-adapter.d.ts +15 -1
- package/data/build/dist/dsh-capabilities/client/session-performance-adapter.d.ts.map +1 -1
- package/data/build/dist/dsh-capabilities/client/session-performance-adapter.js +53 -21
- package/data/build/dist/dsh-capabilities/client/session-performance-adapter.js.map +1 -1
- package/data/build/dist/dsh-capabilities/host/plugin-update-adapter.d.ts +22 -0
- package/data/build/dist/dsh-capabilities/host/plugin-update-adapter.d.ts.map +1 -0
- package/data/build/dist/dsh-capabilities/host/plugin-update-adapter.js +71 -0
- package/data/build/dist/dsh-capabilities/host/plugin-update-adapter.js.map +1 -0
- package/data/build/dist/dsh-capabilities/host/session-model-selection-adapter.d.ts +4 -0
- package/data/build/dist/dsh-capabilities/host/session-model-selection-adapter.d.ts.map +1 -1
- package/data/build/dist/dsh-capabilities/host/session-model-selection-adapter.js +16 -1
- package/data/build/dist/dsh-capabilities/host/session-model-selection-adapter.js.map +1 -1
- package/data/build/dist/dsh-capabilities/matrix.d.ts.map +1 -1
- package/data/build/dist/dsh-capabilities/matrix.js +4 -0
- 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 +10 -0
- 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/feature.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/feature.js +230 -34
- package/data/build/dist/host/cli-adapters/feature.js.map +1 -1
- package/data/build/dist/host/cli-adapters/magpie-context.d.ts +9 -0
- package/data/build/dist/host/cli-adapters/magpie-context.d.ts.map +1 -0
- package/data/build/dist/host/cli-adapters/magpie-context.js +128 -0
- package/data/build/dist/host/cli-adapters/magpie-context.js.map +1 -0
- package/data/build/dist/host/cli-adapters/magpie-detection.d.ts +3 -3
- package/data/build/dist/host/cli-adapters/magpie-detection.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/magpie-detection.js +18 -4
- package/data/build/dist/host/cli-adapters/magpie-detection.js.map +1 -1
- package/data/build/dist/host/cli-adapters/magpie-management.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/magpie-management.js +95 -20
- package/data/build/dist/host/cli-adapters/magpie-management.js.map +1 -1
- package/data/build/dist/host/cli-adapters/magpie-update.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/magpie-update.js +14 -4
- package/data/build/dist/host/cli-adapters/magpie-update.js.map +1 -1
- package/data/build/dist/host/cli-adapters/magpie-usage.d.ts +17 -3
- package/data/build/dist/host/cli-adapters/magpie-usage.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/magpie-usage.js +382 -92
- package/data/build/dist/host/cli-adapters/magpie-usage.js.map +1 -1
- package/data/build/dist/host/cli-adapters/magpie-web.d.ts +15 -0
- package/data/build/dist/host/cli-adapters/magpie-web.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/magpie-web.js +100 -22
- package/data/build/dist/host/cli-adapters/magpie-web.js.map +1 -1
- package/data/build/dist/host/cli-adapters/process-utils.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/process-utils.js +4 -0
- package/data/build/dist/host/cli-adapters/process-utils.js.map +1 -1
- package/data/build/dist/host/cli-adapters/registry.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/registry.js +6 -5
- package/data/build/dist/host/cli-adapters/registry.js.map +1 -1
- package/data/build/dist/host/cli-adapters/session-performance-projection.d.ts +6 -0
- package/data/build/dist/host/cli-adapters/session-performance-projection.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/session-performance-projection.js +25 -0
- package/data/build/dist/host/cli-adapters/session-performance-projection.js.map +1 -1
- package/data/build/dist/host/features/index.d.ts.map +1 -1
- package/data/build/dist/host/features/index.js +2 -0
- package/data/build/dist/host/features/index.js.map +1 -1
- package/data/build/dist/host/features/plugin-update.d.ts +6 -0
- package/data/build/dist/host/features/plugin-update.d.ts.map +1 -0
- package/data/build/dist/host/features/plugin-update.js +45 -0
- package/data/build/dist/host/features/plugin-update.js.map +1 -0
- package/data/build/dist/host/index.d.ts.map +1 -1
- package/data/build/dist/host/index.js +31 -1
- package/data/build/dist/host/index.js.map +1 -1
- package/data/build/dist/host/native-session-bridge.d.ts +8 -0
- package/data/build/dist/host/native-session-bridge.d.ts.map +1 -1
- package/data/build/dist/host/native-session-bridge.js +43 -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 +33 -7
- package/data/build/dist/host/rpc.js.map +1 -1
- package/data/build/dist/host/session-handle-eviction.d.ts +29 -0
- package/data/build/dist/host/session-handle-eviction.d.ts.map +1 -0
- package/data/build/dist/host/session-handle-eviction.js +413 -0
- package/data/build/dist/host/session-handle-eviction.js.map +1 -0
- package/data/build/dist/host/settings.d.ts.map +1 -1
- package/data/build/dist/host/settings.js +12 -1
- package/data/build/dist/host/settings.js.map +1 -1
- package/data/build/dist/host/update/application-result.d.ts +3 -0
- package/data/build/dist/host/update/application-result.d.ts.map +1 -0
- package/data/build/dist/host/update/application-result.js +13 -0
- package/data/build/dist/host/update/application-result.js.map +1 -0
- package/data/build/dist/host/update/http.d.ts +7 -0
- package/data/build/dist/host/update/http.d.ts.map +1 -0
- package/data/build/dist/host/update/http.js +55 -0
- package/data/build/dist/host/update/http.js.map +1 -0
- package/data/build/dist/host/update/metadata.d.ts +14 -0
- package/data/build/dist/host/update/metadata.d.ts.map +1 -0
- package/data/build/dist/host/update/metadata.js +75 -0
- package/data/build/dist/host/update/metadata.js.map +1 -0
- package/data/build/dist/host/update/release-notes.d.ts +6 -0
- package/data/build/dist/host/update/release-notes.d.ts.map +1 -0
- package/data/build/dist/host/update/release-notes.js +52 -0
- package/data/build/dist/host/update/release-notes.js.map +1 -0
- package/data/build/dist/host/update/service.d.ts +25 -0
- package/data/build/dist/host/update/service.d.ts.map +1 -0
- package/data/build/dist/host/update/service.js +209 -0
- package/data/build/dist/host/update/service.js.map +1 -0
- package/data/build/dist/shared/contracts/config.d.ts +17 -0
- package/data/build/dist/shared/contracts/config.d.ts.map +1 -1
- package/data/build/dist/shared/contracts/config.js +8 -0
- package/data/build/dist/shared/contracts/config.js.map +1 -1
- package/data/build/dist/shared/contracts/magpie-management.d.ts +59 -0
- package/data/build/dist/shared/contracts/magpie-management.d.ts.map +1 -1
- package/data/build/dist/shared/contracts/plugin-update.d.ts +93 -0
- package/data/build/dist/shared/contracts/plugin-update.d.ts.map +1 -0
- package/data/build/dist/shared/contracts/plugin-update.js +128 -0
- package/data/build/dist/shared/contracts/plugin-update.js.map +1 -0
- package/data/build/dist/shared/contracts/subscription.d.ts +5 -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/version.d.ts +1 -1
- package/data/build/dist/shared/contracts/version.js +1 -1
- package/data/build/dist/shared/index.d.ts +2 -1
- package/data/build/dist/shared/index.d.ts.map +1 -1
- package/data/build/dist/shared/index.js +1 -0
- package/data/build/dist/shared/index.js.map +1 -1
- package/data/build/dist/shared/magpie-provider-id.d.ts +12 -0
- package/data/build/dist/shared/magpie-provider-id.d.ts.map +1 -0
- package/data/build/dist/shared/magpie-provider-id.js +16 -0
- package/data/build/dist/shared/magpie-provider-id.js.map +1 -0
- package/package.json +2 -1
- package/profile/README.md +2 -2
- package/profile/package.json +2 -2
- package/profile/version.json +1 -1
- package/version.json +1 -1
|
@@ -21,7 +21,7 @@ import { CodingNsCliSessionStore } from './session-store.js';
|
|
|
21
21
|
import { CodingNsDshMessageProjector } from './dsh-message-projector.js';
|
|
22
22
|
import { CommandCodeSubscriptionService } from './command-code-subscription.js';
|
|
23
23
|
import { ProviderSubscriptionService } from './provider-subscription.js';
|
|
24
|
-
import { attachMagpieSessionNames, MagpieUsageService, magpieAgentForAdapter } from './magpie-usage.js';
|
|
24
|
+
import { attachMagpieSessionNames, MagpieUsageService, magpieAgentForAdapter, magpieUsageAgentAliases } from './magpie-usage.js';
|
|
25
25
|
import { readDshProviderSource } from './dsh-config.js';
|
|
26
26
|
import { MagpieManagementService } from './magpie-management.js';
|
|
27
27
|
import { MagpieWebService } from './magpie-web.js';
|
|
@@ -55,6 +55,7 @@ import { sessionPromptScope } from '../../dsh-capabilities/host/session-prompt-a
|
|
|
55
55
|
import { createSessionPromptTranslation } from '../features/session-prompt-translation.js';
|
|
56
56
|
import { codexPerformanceProjection } from './codex-performance-projection.js';
|
|
57
57
|
import { grokContextProjection, grokPerformanceProjection } from './grok-performance-projection.js';
|
|
58
|
+
import { countSessionTurnSteps } from './session-performance-projection.js';
|
|
58
59
|
import { fromCliProviderId, toCliProviderId } from '../../shared/cli-provider-route.js';
|
|
59
60
|
import { DshAgentTeamAdapter } from '../../dsh-capabilities/host/agent-team-adapter.js';
|
|
60
61
|
import { CodingNsTeamDispatcher } from '../cli-bridge/team-dispatch.js';
|
|
@@ -88,6 +89,7 @@ export function createCliAdaptersFeature(options = {}) {
|
|
|
88
89
|
};
|
|
89
90
|
let subscriptions = options.subscriptions ?? buildSubscriptions(context.services.settings?.get());
|
|
90
91
|
let magpieDetection = options.magpieDetection ?? new MagpieInstallDetectionService(options.magpieDetectionOptions);
|
|
92
|
+
let magpieDetectionRequest = 0;
|
|
91
93
|
// 最近一次可用的 Magpie 入口;探测会随用户指定的路径变化而重建,Web 服务总是读最新值。
|
|
92
94
|
let magpieCommand = null;
|
|
93
95
|
let magpieVersion = null;
|
|
@@ -386,6 +388,14 @@ export function createCliAdaptersFeature(options = {}) {
|
|
|
386
388
|
case 'subscription': {
|
|
387
389
|
const subscription = readSubscriptionRequest(payload);
|
|
388
390
|
const requestSignal = signal ?? lifetime.signal;
|
|
391
|
+
// A newly opened native DSH session may not be in the Host bridge's
|
|
392
|
+
// local store yet. Adopt it before reading the Registry, otherwise
|
|
393
|
+
// the native model/provider selection is invisible and the request
|
|
394
|
+
// incorrectly falls back to the official DSH balance.
|
|
395
|
+
if (subscription.adapterId === 'dsh' && subscription.sessionId !== undefined && nativeSessions !== undefined) {
|
|
396
|
+
await nativeSessions.ensure(subscription.sessionId);
|
|
397
|
+
requestSignal.throwIfAborted();
|
|
398
|
+
}
|
|
389
399
|
const session = subscription.sessionId === undefined ? undefined : registry.getSession(subscription.sessionId);
|
|
390
400
|
if (context.services.settings?.get().modules.magpieManagement === true
|
|
391
401
|
&& session !== undefined && session.adapterId === subscription.adapterId) {
|
|
@@ -393,9 +403,9 @@ export function createCliAdaptersFeature(options = {}) {
|
|
|
393
403
|
requestSignal.throwIfAborted();
|
|
394
404
|
const snapshot = magpie ?? (subscription.sessionId === undefined
|
|
395
405
|
? null
|
|
396
|
-
: await pendingMagpieUsage(magpieUsage, nativeSessions, subscription.sessionId, session, requestSignal));
|
|
406
|
+
: await pendingMagpieUsage(magpieUsage, nativeSessions, subscription.sessionId, session, requestSignal, subscription.includeRoute));
|
|
397
407
|
if (snapshot !== null) {
|
|
398
|
-
const sessionName = subscription.sessionId === undefined ? undefined : readDshSessionDisplayName(subscription.sessionId, sessionStore, nativeSessions);
|
|
408
|
+
const sessionName = subscription.sessionId === undefined ? undefined : readDshSessionDisplayName(subscription.sessionId, sessionStore, nativeSessions, context.services.dshContext);
|
|
399
409
|
return { providerUsage: null, magpie: sessionName === undefined ? snapshot : { ...snapshot, sessionName } };
|
|
400
410
|
}
|
|
401
411
|
}
|
|
@@ -429,34 +439,66 @@ export function createCliAdaptersFeature(options = {}) {
|
|
|
429
439
|
const signal = isAbortSignal(rpcSignal) ? rpcSignal : lifetime.signal;
|
|
430
440
|
// 安装探测本身就是启用前的判断依据,因此不要求模块已启用。
|
|
431
441
|
if (action === 'management/detection') {
|
|
442
|
+
const requestId = ++magpieDetectionRequest;
|
|
432
443
|
const request = readMagpieDetectionRequest(payload);
|
|
433
444
|
const force = readMagpieDetectionForce(payload);
|
|
434
|
-
//
|
|
445
|
+
// Only a successful custom probe replaces the Host-session selection.
|
|
435
446
|
const customCommand = normalizeCustomCommand(request.commandPath);
|
|
436
447
|
const detectionService = customCommand === null
|
|
437
448
|
? magpieDetection
|
|
438
449
|
: new MagpieInstallDetectionService({ ...options.magpieDetectionOptions, customCommand });
|
|
439
450
|
const detection = await detectionService.detect(customCommand === null ? {} : { commandPath: customCommand }, { force: force || customCommand !== null });
|
|
440
|
-
|
|
441
|
-
|
|
451
|
+
if (requestId !== magpieDetectionRequest || lifetime.signal.aborted)
|
|
452
|
+
return detection;
|
|
453
|
+
const usable = MagpieInstallDetectionService.isUsable(detection);
|
|
454
|
+
if (usable || customCommand === null) {
|
|
455
|
+
if (usable && customCommand !== null)
|
|
456
|
+
magpieDetection = detectionService;
|
|
457
|
+
magpieInstalled = usable;
|
|
458
|
+
magpieCommand = usable ? detection.command : null;
|
|
459
|
+
magpieVersion = usable ? detection.version : null;
|
|
460
|
+
scheduleMagpieWebSync(context.services.settings?.get().modules.magpieManagement === true && usable);
|
|
461
|
+
}
|
|
442
462
|
return detection;
|
|
443
463
|
}
|
|
464
|
+
if (action === 'context') {
|
|
465
|
+
const request = readMagpieContextRequest(payload);
|
|
466
|
+
const target = await resolveMagpieContextTarget(request.sessionId, sessionStore, nativeSessions, magpieUsage, signal);
|
|
467
|
+
if (target === null || !magpieInstalled)
|
|
468
|
+
return null;
|
|
469
|
+
try {
|
|
470
|
+
await magpieWeb.start();
|
|
471
|
+
}
|
|
472
|
+
catch {
|
|
473
|
+
return null;
|
|
474
|
+
}
|
|
475
|
+
return magpieUsage.readContext(target, signal);
|
|
476
|
+
}
|
|
444
477
|
if (context.services.settings?.get().modules.magpieManagement !== true) {
|
|
445
478
|
throw new CodingNsRpcError('CODINGNS_MAGPIE_DISABLED', 'Magpie management is disabled');
|
|
446
479
|
}
|
|
447
480
|
switch (action) {
|
|
448
481
|
case 'usage/dashboard': {
|
|
449
482
|
const dashboard = await magpieUsage.readDashboard(readMagpieDashboardPeriod(payload), signal);
|
|
450
|
-
return attachMagpieSessionNames(dashboard, await magpieSessionNameBindings(sessionStore, nativeSessions, signal));
|
|
483
|
+
return attachMagpieSessionNames(dashboard, await magpieSessionNameBindings(sessionStore, nativeSessions, signal, context.services.dshContext));
|
|
451
484
|
}
|
|
452
485
|
case 'usage/dashboard/stream': {
|
|
453
486
|
const input = asRecord(payload);
|
|
454
487
|
const period = readMagpieDashboardPeriod(payload);
|
|
455
488
|
const force = input?.force === true;
|
|
456
|
-
return streamMagpieDashboard(magpieUsage, period, signal, force, sessionStore, nativeSessions);
|
|
489
|
+
return streamMagpieDashboard(magpieUsage, period, signal, force, sessionStore, nativeSessions, context.services.dshContext);
|
|
490
|
+
}
|
|
491
|
+
case 'usage/requests': {
|
|
492
|
+
const request = readMagpieRequestOptions(payload);
|
|
493
|
+
const page = await magpieUsage.readRequestPage(request, signal);
|
|
494
|
+
if (page === null || request.sessionId === undefined)
|
|
495
|
+
return page;
|
|
496
|
+
return {
|
|
497
|
+
...page,
|
|
498
|
+
sessionName: readDshSessionDisplayName(request.sessionId, sessionStore, nativeSessions, context.services.dshContext) ?? null,
|
|
499
|
+
sessionMetrics: readMagpieSessionMetrics(sessionStore, nativeSessions, request.sessionId, request.sessionIds),
|
|
500
|
+
};
|
|
457
501
|
}
|
|
458
|
-
case 'usage/requests':
|
|
459
|
-
return magpieUsage.readRequestPage(readMagpieRequestOptions(payload), signal);
|
|
460
502
|
case 'management/snapshot':
|
|
461
503
|
return magpieManagement.readSnapshot(signal);
|
|
462
504
|
case 'management/provider/update':
|
|
@@ -1535,6 +1577,11 @@ function readOptionalText(value) {
|
|
|
1535
1577
|
function readNativeModelSelection(nativeSessions, sessionId) {
|
|
1536
1578
|
if (nativeSessions === undefined)
|
|
1537
1579
|
return undefined;
|
|
1580
|
+
const current = nativeSessions.modelSelection?.(sessionId);
|
|
1581
|
+
if (current !== undefined && current.model.trim() !== '') {
|
|
1582
|
+
const provider = current.provider.trim();
|
|
1583
|
+
return provider === '' ? { modelId: current.model.trim() } : { providerId: provider, modelId: current.model.trim() };
|
|
1584
|
+
}
|
|
1538
1585
|
let session;
|
|
1539
1586
|
try {
|
|
1540
1587
|
session = nativeSessions.get(sessionId);
|
|
@@ -1578,6 +1625,43 @@ function isMagpieGatewayProvider(providerId) {
|
|
|
1578
1625
|
return isMagpieGateway(source.baseUrl);
|
|
1579
1626
|
return /^magpie(?:[-_.].*)?$/iu.test(providerId);
|
|
1580
1627
|
}
|
|
1628
|
+
/** Resolve the exact identities needed for one Magpie context read. */
|
|
1629
|
+
async function resolveMagpieContextTarget(sessionId, sessionStore, nativeSessions, magpieUsage, signal) {
|
|
1630
|
+
const normalizedSessionId = sessionId.trim();
|
|
1631
|
+
if (normalizedSessionId === '')
|
|
1632
|
+
return null;
|
|
1633
|
+
let stored = sessionStore.get(normalizedSessionId);
|
|
1634
|
+
if (stored === undefined && nativeSessions !== undefined) {
|
|
1635
|
+
try {
|
|
1636
|
+
await nativeSessions.ensure(normalizedSessionId);
|
|
1637
|
+
signal.throwIfAborted();
|
|
1638
|
+
}
|
|
1639
|
+
catch {
|
|
1640
|
+
return null;
|
|
1641
|
+
}
|
|
1642
|
+
stored = sessionStore.get(normalizedSessionId);
|
|
1643
|
+
}
|
|
1644
|
+
const adapterId = stored?.adapterId ?? DSH_NATIVE_SESSION_ADAPTER_ID;
|
|
1645
|
+
const selection = adapterId === DSH_NATIVE_SESSION_ADAPTER_ID
|
|
1646
|
+
? readNativeModelSelection(nativeSessions, normalizedSessionId)
|
|
1647
|
+
: undefined;
|
|
1648
|
+
const modelId = stored?.modelId?.trim() || selection?.modelId;
|
|
1649
|
+
if (modelId === undefined || modelId === '')
|
|
1650
|
+
return null;
|
|
1651
|
+
const providerId = stored?.providerId?.trim() || selection?.providerId;
|
|
1652
|
+
if (adapterId === DSH_NATIVE_SESSION_ADAPTER_ID) {
|
|
1653
|
+
if (providerId === undefined || !isMagpieGatewayProvider(providerId))
|
|
1654
|
+
return null;
|
|
1655
|
+
}
|
|
1656
|
+
else if (await magpieUsage.readModelMetadata(adapterId, modelId, signal) === null) {
|
|
1657
|
+
return null;
|
|
1658
|
+
}
|
|
1659
|
+
const agents = magpieUsageAgentAliases(adapterId);
|
|
1660
|
+
if (agents.length === 0)
|
|
1661
|
+
return null;
|
|
1662
|
+
const sessionIds = [...new Set([normalizedSessionId, stored?.providerSessionId?.trim() ?? ''].filter(Boolean))];
|
|
1663
|
+
return { agents, sessionIds };
|
|
1664
|
+
}
|
|
1581
1665
|
/**
|
|
1582
1666
|
* 读到用量之后仍然要判断「这个模型是不是 Magpie 的」。
|
|
1583
1667
|
*
|
|
@@ -1586,21 +1670,25 @@ function isMagpieGatewayProvider(providerId) {
|
|
|
1586
1670
|
* 会话 ID 在滚动升级期间并不相等,这时返回 null 会让 Host 直接回退到官方余量。
|
|
1587
1671
|
* 只有确认模型由 Magpie 提供时才下发占位快照,避免官方数字抢占首屏。
|
|
1588
1672
|
*/
|
|
1589
|
-
async function pendingMagpieUsage(magpie, nativeSessions, sessionId, session, signal) {
|
|
1673
|
+
async function pendingMagpieUsage(magpie, nativeSessions, sessionId, session, signal, includeRoute = false) {
|
|
1590
1674
|
const agent = magpieAgentForAdapter(session.adapterId);
|
|
1591
1675
|
const modelId = session.modelId?.trim();
|
|
1592
1676
|
if (agent === null || modelId === undefined || modelId === '')
|
|
1593
1677
|
return null;
|
|
1594
1678
|
try {
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
return null;
|
|
1679
|
+
if (session.adapterId === DSH_NATIVE_SESSION_ADAPTER_ID) {
|
|
1680
|
+
const providerId = session.providerId?.trim() || readNativeModelSelection(nativeSessions, sessionId)?.providerId;
|
|
1681
|
+
if (providerId === undefined || !isMagpieGatewayProvider(providerId))
|
|
1682
|
+
return null;
|
|
1683
|
+
}
|
|
1601
1684
|
const confirmed = await magpie.readModelMetadata(session.adapterId, modelId, signal);
|
|
1602
1685
|
signal.throwIfAborted();
|
|
1603
|
-
|
|
1686
|
+
if (confirmed === null)
|
|
1687
|
+
return null;
|
|
1688
|
+
// Gateway totals do not depend on a provider session binding. Keep them
|
|
1689
|
+
// while the exact session row is pending, without attributing other rows.
|
|
1690
|
+
return await magpie.read(session, signal, includeRoute, sessionId, { allowPendingSession: true })
|
|
1691
|
+
?? pendingMagpieSnapshot(agent, modelId);
|
|
1604
1692
|
}
|
|
1605
1693
|
catch {
|
|
1606
1694
|
// 目录不可读、超时或请求被取消:保持原有回退语义,不伪造 Magpie 用量。
|
|
@@ -2128,8 +2216,8 @@ function readMagpieDashboardPeriod(payload) {
|
|
|
2128
2216
|
return value;
|
|
2129
2217
|
throw new TypeError('Magpie usage period must be today, week, month, or all');
|
|
2130
2218
|
}
|
|
2131
|
-
async function* streamMagpieDashboard(service, period, signal, force, sessionStore, nativeSessions) {
|
|
2132
|
-
const names = magpieSessionNameBindings(sessionStore, nativeSessions, signal).catch(() => []);
|
|
2219
|
+
async function* streamMagpieDashboard(service, period, signal, force, sessionStore, nativeSessions, dshContext) {
|
|
2220
|
+
const names = magpieSessionNameBindings(sessionStore, nativeSessions, signal, dshContext).catch(() => []);
|
|
2133
2221
|
let latest;
|
|
2134
2222
|
for await (const chunk of service.readDashboardStream(period, signal, force)) {
|
|
2135
2223
|
latest = chunk.dashboard;
|
|
@@ -2153,6 +2241,12 @@ function readMagpieDetectionRequest(payload) {
|
|
|
2153
2241
|
function readMagpieDetectionForce(payload) {
|
|
2154
2242
|
return asRecord(payload)?.force === true;
|
|
2155
2243
|
}
|
|
2244
|
+
function readMagpieContextRequest(payload) {
|
|
2245
|
+
const sessionId = readOptionalMagpieIdentity(asRecord(payload)?.sessionId, 512);
|
|
2246
|
+
if (sessionId === undefined)
|
|
2247
|
+
throw new TypeError('Magpie context requires a session ID');
|
|
2248
|
+
return { sessionId };
|
|
2249
|
+
}
|
|
2156
2250
|
function readMagpieRequestOptions(payload) {
|
|
2157
2251
|
const record = asRecord(payload);
|
|
2158
2252
|
if (record === null)
|
|
@@ -2167,10 +2261,16 @@ function readMagpieRequestOptions(payload) {
|
|
|
2167
2261
|
throw new TypeError('Magpie request limit must be between 1 and 100');
|
|
2168
2262
|
}
|
|
2169
2263
|
const sessionId = readOptionalMagpieIdentity(record.sessionId, 512);
|
|
2264
|
+
const sessionIds = record.sessionIds === undefined
|
|
2265
|
+
? undefined
|
|
2266
|
+
: readOptionalMagpieIdentityList(record.sessionIds, 16, 512);
|
|
2170
2267
|
const sessionAgent = readOptionalMagpieIdentity(record.sessionAgent, 64);
|
|
2171
2268
|
if ((sessionId === undefined) !== (sessionAgent === undefined)) {
|
|
2172
2269
|
throw new TypeError('Magpie session details require both sessionId and sessionAgent');
|
|
2173
2270
|
}
|
|
2271
|
+
if (sessionIds !== undefined && sessionId === undefined) {
|
|
2272
|
+
throw new TypeError('Magpie session IDs require a primary session ID');
|
|
2273
|
+
}
|
|
2174
2274
|
if (sessionAgent !== undefined && !/^[a-z0-9][a-z0-9-]*$/u.test(sessionAgent)) {
|
|
2175
2275
|
throw new TypeError('Magpie session Agent is invalid');
|
|
2176
2276
|
}
|
|
@@ -2179,9 +2279,38 @@ function readMagpieRequestOptions(payload) {
|
|
|
2179
2279
|
offset,
|
|
2180
2280
|
limit,
|
|
2181
2281
|
...(sessionId === undefined ? {} : { sessionId }),
|
|
2282
|
+
...(sessionIds === undefined ? {} : { sessionIds }),
|
|
2182
2283
|
...(sessionAgent === undefined ? {} : { sessionAgent }),
|
|
2183
2284
|
};
|
|
2184
2285
|
}
|
|
2286
|
+
function readMagpieSessionMetrics(sessionStore, nativeSessions, sessionId, sessionIds) {
|
|
2287
|
+
if (nativeSessions === undefined)
|
|
2288
|
+
return null;
|
|
2289
|
+
const identities = new Set([sessionId, ...(sessionIds ?? [])]);
|
|
2290
|
+
const bindings = sessionStore.list({ includeArchived: true }).filter((record) => identities.has(record.dshSessionId) || (record.providerSessionId !== undefined && identities.has(record.providerSessionId)));
|
|
2291
|
+
const direct = bindings.find((record) => record.dshSessionId === sessionId);
|
|
2292
|
+
const boundSessionIds = [...new Set(bindings.map((record) => record.dshSessionId))];
|
|
2293
|
+
if (direct === undefined && boundSessionIds.length > 1)
|
|
2294
|
+
return null;
|
|
2295
|
+
const dshSessionId = direct?.dshSessionId ?? boundSessionIds[0] ?? sessionId;
|
|
2296
|
+
let session;
|
|
2297
|
+
try {
|
|
2298
|
+
session = nativeSessions.get(dshSessionId);
|
|
2299
|
+
}
|
|
2300
|
+
catch {
|
|
2301
|
+
return null;
|
|
2302
|
+
}
|
|
2303
|
+
const snapshotEvents = asRecord(session)?.snapshotEvents;
|
|
2304
|
+
if (typeof snapshotEvents !== 'function')
|
|
2305
|
+
return null;
|
|
2306
|
+
try {
|
|
2307
|
+
const events = snapshotEvents.call(session);
|
|
2308
|
+
return Array.isArray(events) ? countSessionTurnSteps(events) : null;
|
|
2309
|
+
}
|
|
2310
|
+
catch {
|
|
2311
|
+
return null;
|
|
2312
|
+
}
|
|
2313
|
+
}
|
|
2185
2314
|
function readOptionalMagpieIdentity(value, maxLength) {
|
|
2186
2315
|
if (value === undefined)
|
|
2187
2316
|
return undefined;
|
|
@@ -2193,7 +2322,15 @@ function readOptionalMagpieIdentity(value, maxLength) {
|
|
|
2193
2322
|
}
|
|
2194
2323
|
return text;
|
|
2195
2324
|
}
|
|
2196
|
-
|
|
2325
|
+
function readOptionalMagpieIdentityList(value, maxItems, maxLength) {
|
|
2326
|
+
if (!Array.isArray(value) || value.length > maxItems)
|
|
2327
|
+
throw new TypeError('Magpie session IDs are invalid');
|
|
2328
|
+
const values = value.map((item) => readOptionalMagpieIdentity(item, maxLength));
|
|
2329
|
+
if (values.some((item) => item === undefined))
|
|
2330
|
+
throw new TypeError('Magpie session IDs are invalid');
|
|
2331
|
+
return [...new Set(values)];
|
|
2332
|
+
}
|
|
2333
|
+
async function magpieSessionNameBindings(sessionStore, nativeSessions, signal, dshContext) {
|
|
2197
2334
|
const records = sessionStore.list({ includeArchived: true });
|
|
2198
2335
|
const bindings = [];
|
|
2199
2336
|
const knownSessionIds = new Set();
|
|
@@ -2209,20 +2346,18 @@ async function magpieSessionNameBindings(sessionStore, nativeSessions, signal) {
|
|
|
2209
2346
|
const nativeNames = new Map();
|
|
2210
2347
|
for (const value of nativeValues) {
|
|
2211
2348
|
const sessionId = nativeSessionId(value);
|
|
2212
|
-
const name = readNativeSessionDisplayName(value);
|
|
2349
|
+
const name = readNativeSessionDisplayName(value, dshContext);
|
|
2213
2350
|
if (sessionId !== undefined && name !== undefined)
|
|
2214
2351
|
nativeNames.set(sessionId, name);
|
|
2215
2352
|
}
|
|
2216
2353
|
for (const record of records) {
|
|
2217
2354
|
knownSessionIds.add(record.dshSessionId);
|
|
2218
|
-
const name = nativeNames.get(record.dshSessionId) ?? readDshSessionDisplayName(record.dshSessionId, sessionStore, nativeSessions);
|
|
2219
|
-
if (name === undefined)
|
|
2220
|
-
continue;
|
|
2355
|
+
const name = nativeNames.get(record.dshSessionId) ?? readDshSessionDisplayName(record.dshSessionId, sessionStore, nativeSessions, dshContext);
|
|
2221
2356
|
bindings.push({
|
|
2222
2357
|
dshSessionId: record.dshSessionId,
|
|
2223
2358
|
adapterId: record.adapterId,
|
|
2224
2359
|
...(record.providerSessionId === undefined ? {} : { providerSessionId: record.providerSessionId }),
|
|
2225
|
-
name,
|
|
2360
|
+
...(name === undefined ? {} : { name }),
|
|
2226
2361
|
});
|
|
2227
2362
|
}
|
|
2228
2363
|
// Native DSH sessions do not always have a CodingNS session-index record. They
|
|
@@ -2232,33 +2367,94 @@ async function magpieSessionNameBindings(sessionStore, nativeSessions, signal) {
|
|
|
2232
2367
|
const sessionId = nativeSessionId(value);
|
|
2233
2368
|
if (sessionId === undefined || knownSessionIds.has(sessionId))
|
|
2234
2369
|
continue;
|
|
2235
|
-
const name = readNativeSessionDisplayName(value);
|
|
2236
|
-
|
|
2237
|
-
continue;
|
|
2238
|
-
bindings.push({ dshSessionId: sessionId, adapterId: 'dsh', name });
|
|
2370
|
+
const name = readNativeSessionDisplayName(value, dshContext);
|
|
2371
|
+
bindings.push({ dshSessionId: sessionId, adapterId: 'dsh', ...(name === undefined ? {} : { name }) });
|
|
2239
2372
|
}
|
|
2240
2373
|
return bindings;
|
|
2241
2374
|
}
|
|
2242
|
-
function readDshSessionDisplayName(sessionId, sessionStore, nativeSessions) {
|
|
2243
|
-
|
|
2375
|
+
function readDshSessionDisplayName(sessionId, sessionStore, nativeSessions, dshContext) {
|
|
2376
|
+
const direct = readNativeSession(nativeSessions, sessionId);
|
|
2377
|
+
const directName = readNativeSessionDisplayName(direct, dshContext);
|
|
2378
|
+
if (directName !== undefined)
|
|
2379
|
+
return directName;
|
|
2380
|
+
const directRecord = sessionStore.get(sessionId);
|
|
2381
|
+
const directRecordName = cleanDisplayName(directRecord?.title);
|
|
2382
|
+
if (directRecordName !== undefined)
|
|
2383
|
+
return directRecordName;
|
|
2384
|
+
const binding = sessionStore.list({ includeArchived: true }).find((record) => record.dshSessionId === sessionId || record.providerSessionId === sessionId);
|
|
2385
|
+
if (binding === undefined)
|
|
2386
|
+
return undefined;
|
|
2387
|
+
return readNativeSessionDisplayName(readNativeSession(nativeSessions, binding.dshSessionId), dshContext)
|
|
2388
|
+
?? cleanDisplayName(binding.title);
|
|
2244
2389
|
}
|
|
2245
|
-
function readNativeSessionDisplayName(value) {
|
|
2390
|
+
function readNativeSessionDisplayName(value, dshContext) {
|
|
2246
2391
|
const root = asRecord(value);
|
|
2247
2392
|
if (root === null)
|
|
2248
2393
|
return undefined;
|
|
2249
2394
|
const projection = asRecord(root.projections) ?? asRecord(asRecord(root.record)?.projections);
|
|
2250
2395
|
const values = asRecord(projection?.values);
|
|
2251
2396
|
const record = asRecord(root.record);
|
|
2397
|
+
const header = asRecord(root.header);
|
|
2398
|
+
const recordHeader = asRecord(record?.header);
|
|
2252
2399
|
const rows = asRecord(record?.rows);
|
|
2253
2400
|
const rowProjection = asRecord(rows?.projections);
|
|
2254
2401
|
const rowValues = asRecord(rowProjection?.values);
|
|
2255
|
-
|
|
2402
|
+
const titleService = asRecord(readOptionalDshService(dshContext, 'sessionTitle'));
|
|
2403
|
+
if (typeof titleService?.get === 'function') {
|
|
2404
|
+
try {
|
|
2405
|
+
const snapshot = titleService.get(value);
|
|
2406
|
+
const title = cleanDisplayName(asRecord(snapshot)?.title ?? snapshot);
|
|
2407
|
+
if (title !== undefined)
|
|
2408
|
+
return title;
|
|
2409
|
+
}
|
|
2410
|
+
catch { /* The optional native title service may not accept this session shape. */ }
|
|
2411
|
+
}
|
|
2412
|
+
for (const candidate of [
|
|
2413
|
+
values?.title, rowValues?.title, root.title, root.name, root.displayName,
|
|
2414
|
+
header?.title, header?.name, header?.displayName,
|
|
2415
|
+
record?.title, record?.name, recordHeader?.title, recordHeader?.name,
|
|
2416
|
+
]) {
|
|
2256
2417
|
const title = cleanDisplayName(candidate);
|
|
2257
2418
|
if (title !== undefined)
|
|
2258
2419
|
return title;
|
|
2259
2420
|
}
|
|
2421
|
+
if (typeof root.snapshotEvents === 'function') {
|
|
2422
|
+
try {
|
|
2423
|
+
const events = root.snapshotEvents.call(value);
|
|
2424
|
+
if (Array.isArray(events)) {
|
|
2425
|
+
for (let index = events.length - 1; index >= 0; index -= 1) {
|
|
2426
|
+
const event = asRecord(events[index]);
|
|
2427
|
+
if (event?.type !== 'session/title')
|
|
2428
|
+
continue;
|
|
2429
|
+
const title = cleanDisplayName(asRecord(event.data)?.title ?? event.title);
|
|
2430
|
+
if (title !== undefined)
|
|
2431
|
+
return title;
|
|
2432
|
+
}
|
|
2433
|
+
}
|
|
2434
|
+
}
|
|
2435
|
+
catch { /* A missing or closed native history cannot block usage rendering. */ }
|
|
2436
|
+
}
|
|
2260
2437
|
return undefined;
|
|
2261
2438
|
}
|
|
2439
|
+
function readNativeSession(nativeSessions, sessionId) {
|
|
2440
|
+
try {
|
|
2441
|
+
return nativeSessions?.get(sessionId);
|
|
2442
|
+
}
|
|
2443
|
+
catch {
|
|
2444
|
+
return undefined;
|
|
2445
|
+
}
|
|
2446
|
+
}
|
|
2447
|
+
function readOptionalDshService(context, name) {
|
|
2448
|
+
const get = context?.get;
|
|
2449
|
+
if (typeof get !== 'function')
|
|
2450
|
+
return undefined;
|
|
2451
|
+
try {
|
|
2452
|
+
return get.call(context, name);
|
|
2453
|
+
}
|
|
2454
|
+
catch {
|
|
2455
|
+
return undefined;
|
|
2456
|
+
}
|
|
2457
|
+
}
|
|
2262
2458
|
function cleanDisplayName(value) {
|
|
2263
2459
|
if (typeof value !== 'string')
|
|
2264
2460
|
return undefined;
|