@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
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { startSerialPolling } from './serial-polling.js';
|
|
2
2
|
import { createElement, Fragment, useEffect, useLayoutEffect, useRef, useState } from 'react';
|
|
3
|
+
import { createPortal } from 'react-dom';
|
|
3
4
|
import { isSubscriptionUsageFresh } from '../shared/contracts/subscription.js';
|
|
4
5
|
import { DEFAULT_SUBSCRIPTION_USAGE_SETTINGS } from '../shared/contracts/config.js';
|
|
5
6
|
import { callCliRpc } from './cli-catalog.js';
|
|
@@ -7,7 +8,7 @@ import { resolveCodingNsTranslator, useCodingNsTranslator } from './locale.js';
|
|
|
7
8
|
import { providerIconUrl } from './provider-icons.js';
|
|
8
9
|
import { MagpieProviderLogo } from './features/magpie-provider-logo.js';
|
|
9
10
|
import { MAGPIE_REQUESTS_PAGE_SIZE, RequestsPage, installMagpiePageStyles } from './features/magpie-management-page.js';
|
|
10
|
-
import { createQuotaAccountBlock, createQuotaGroupHeader, formatQuotaCredits, formatQuotaNumber, groupQuotasByProvider, readWindowCreditBalance, resolveQuotaBalanceLabel, resolveQuotaCreditBalance, } from './features/subscription-quota-groups.js';
|
|
11
|
+
import { createQuotaAccountBlock, createQuotaGroupHeader, formatQuotaCredits, formatQuotaNumber, groupQuotasByProvider, readWindowCreditBalance, quotaWindowRemaining, resolveQuotaBalanceLabel, resolveQuotaCreditBalance, } from './features/subscription-quota-groups.js';
|
|
11
12
|
import { subscribeSessionAdapters } from './session-adapter-cache.js';
|
|
12
13
|
import { loadCliSessionConfig } from './cli-session-config-cache.js';
|
|
13
14
|
import { dshPopupSurfaceStyle, dshSettingsButtonStyle, dshSettingsPrimaryButtonStyle, dshThemeColor } from './theme.js';
|
|
@@ -123,6 +124,7 @@ function CommandCodeSubscriptionSlot(props) {
|
|
|
123
124
|
const [clock, setClock] = useState(() => Date.now());
|
|
124
125
|
const rootRef = useRef(null);
|
|
125
126
|
const magpiePopoverRef = useRef(null);
|
|
127
|
+
const magpieRequestsDialogRef = useRef(null);
|
|
126
128
|
const resetDialogRef = useRef(null);
|
|
127
129
|
// 重置成功后的刷新不能重跑加载 effect,否则 usage 会被清空导致底部入口闪断。
|
|
128
130
|
const refreshRef = useRef(null);
|
|
@@ -131,6 +133,8 @@ function CommandCodeSubscriptionSlot(props) {
|
|
|
131
133
|
const [resetPending, setResetPending] = useState(false);
|
|
132
134
|
const [resetResult, setResetResult] = useState(null);
|
|
133
135
|
const [resetError, setResetError] = useState(null);
|
|
136
|
+
const sessionRef = useRef(undefined);
|
|
137
|
+
const routeKeyRef = useRef(null);
|
|
134
138
|
// Agent-native session bindings are written by Host during a turn. Refresh
|
|
135
139
|
// at turn state changes so a snapshot loaded before the binding is not kept.
|
|
136
140
|
const modelSelectionRevision = props.useSession?.((value) => JSON.stringify([value.modelSelection, value.running]));
|
|
@@ -189,6 +193,8 @@ function CommandCodeSubscriptionSlot(props) {
|
|
|
189
193
|
useEffect(() => {
|
|
190
194
|
const sessionId = props.sessionId?.trim();
|
|
191
195
|
if (!sessionId) {
|
|
196
|
+
sessionRef.current = undefined;
|
|
197
|
+
routeKeyRef.current = null;
|
|
192
198
|
setEligible(false);
|
|
193
199
|
setSnapshot(null);
|
|
194
200
|
setAdapterId(null);
|
|
@@ -205,18 +211,23 @@ function CommandCodeSubscriptionSlot(props) {
|
|
|
205
211
|
// 未解析的 Magpie 配额必须快速补读:官方余额一旦抢先显示,用户要等到下一次
|
|
206
212
|
// 轮询(默认 5 分钟)或整页刷新才会切到 Magpie。
|
|
207
213
|
let upstreamUnresolved = false;
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
214
|
+
if (sessionRef.current !== sessionId) {
|
|
215
|
+
sessionRef.current = sessionId;
|
|
216
|
+
routeKeyRef.current = null;
|
|
217
|
+
setEligible(false);
|
|
218
|
+
setSnapshot(null);
|
|
219
|
+
setAdapterId(null);
|
|
220
|
+
setProviderId(null);
|
|
221
|
+
setOpen(false);
|
|
222
|
+
setResetOpen(false);
|
|
223
|
+
setResetPending(false);
|
|
224
|
+
setResetResult(null);
|
|
225
|
+
setResetError(null);
|
|
226
|
+
setMagpieTab('usage');
|
|
227
|
+
}
|
|
218
228
|
const refresh = async (signal) => {
|
|
219
229
|
let routeSignal;
|
|
230
|
+
let routeChanged = false;
|
|
220
231
|
setLoading(true);
|
|
221
232
|
try {
|
|
222
233
|
// 订阅入口必须读取当前会话的真实 Provider;模型选择器切换后不能复用
|
|
@@ -234,6 +245,16 @@ function CommandCodeSubscriptionSlot(props) {
|
|
|
234
245
|
}
|
|
235
246
|
if (signal.aborted)
|
|
236
247
|
return false;
|
|
248
|
+
const cacheKey = JSON.stringify([adapterId, selection.providerId ?? '', selection.modelId ?? '', sessionId, selection.providerSessionId ?? '']);
|
|
249
|
+
routeChanged = routeKeyRef.current !== cacheKey;
|
|
250
|
+
if (routeChanged) {
|
|
251
|
+
routeKeyRef.current = cacheKey;
|
|
252
|
+
if (active) {
|
|
253
|
+
setSnapshot(null);
|
|
254
|
+
setOpen(false);
|
|
255
|
+
setMagpieTab('usage');
|
|
256
|
+
}
|
|
257
|
+
}
|
|
237
258
|
if (active) {
|
|
238
259
|
setEligible(true);
|
|
239
260
|
setAdapterId(adapterId);
|
|
@@ -243,8 +264,7 @@ function CommandCodeSubscriptionSlot(props) {
|
|
|
243
264
|
// 模型也是读取键的一部分:Antigravity 的 Gemini 与 Claude/GPT 是两个独立配额组。
|
|
244
265
|
// 会话 ID 同时承担 PeerHost 的路由身份;缓存也必须按会话隔离,
|
|
245
266
|
// 否则本机与远端使用相同 Agent/Provider/模型时会互相复用上游结果。
|
|
246
|
-
const
|
|
247
|
-
const magpieSnapshot = snapshotRef.current?.magpie;
|
|
267
|
+
const magpieSnapshot = routeChanged ? undefined : snapshotRef.current?.magpie;
|
|
248
268
|
const includeRoute = magpieSnapshot !== null && magpieSnapshot !== undefined
|
|
249
269
|
&& (openRef.current || shouldResolveMagpieQuota(magpieSnapshot));
|
|
250
270
|
const cached = subscriptionUsageCache.get(cacheKey);
|
|
@@ -278,8 +298,12 @@ function CommandCodeSubscriptionSlot(props) {
|
|
|
278
298
|
if (signal.aborted || routeSignal?.aborted === true)
|
|
279
299
|
return false;
|
|
280
300
|
if (active) {
|
|
281
|
-
|
|
282
|
-
|
|
301
|
+
// A temporary Host/Web failure must not make the compact entry
|
|
302
|
+
// disappear. A later poll will replace the retained snapshot.
|
|
303
|
+
if (routeChanged || snapshotRef.current === null) {
|
|
304
|
+
setEligible(false);
|
|
305
|
+
setSnapshot(null);
|
|
306
|
+
}
|
|
283
307
|
}
|
|
284
308
|
return false;
|
|
285
309
|
}
|
|
@@ -361,7 +385,7 @@ function CommandCodeSubscriptionSlot(props) {
|
|
|
361
385
|
}
|
|
362
386
|
})();
|
|
363
387
|
};
|
|
364
|
-
useDismissOnOutsidePointer(rootRef, open, () => setOpen(false));
|
|
388
|
+
useDismissOnOutsidePointer(rootRef, open, () => setOpen(false), { portal: magpieRequestsDialogRef });
|
|
365
389
|
useDismissOnOutsidePointer(resetDialogRef, resetOpen && !resetPending, closeResetDialog);
|
|
366
390
|
if (!eligible || snapshot === null)
|
|
367
391
|
return null;
|
|
@@ -392,6 +416,7 @@ function CommandCodeSubscriptionSlot(props) {
|
|
|
392
416
|
onToggleGroup: toggleQuotaGroup,
|
|
393
417
|
placement: magpiePlacement,
|
|
394
418
|
popoverRef: magpiePopoverRef,
|
|
419
|
+
requestsDialogRef: magpieRequestsDialogRef,
|
|
395
420
|
}));
|
|
396
421
|
}
|
|
397
422
|
const usage = snapshot.providerUsage;
|
|
@@ -473,7 +498,7 @@ function CommandCodeSubscriptionSlot(props) {
|
|
|
473
498
|
dialogRef: resetDialogRef,
|
|
474
499
|
}));
|
|
475
500
|
}
|
|
476
|
-
function MagpieUsagePopover({ rpc, usage, t, tab = 'usage', onTabChange = () => { }, expandedGroups = [], onToggleGroup = () => { }, placement = { left: 0, width: 400 }, popoverRef }) {
|
|
501
|
+
function MagpieUsagePopover({ rpc, usage, t, tab = 'usage', onTabChange = () => { }, expandedGroups = [], onToggleGroup = () => { }, placement = { left: 0, width: 400 }, popoverRef, requestsDialogRef }) {
|
|
477
502
|
const aggregateRows = usage.aggregate === null ? [] : [
|
|
478
503
|
[t('usage.magpieRequests'), formatMagpieNumber(usage.aggregate.calls)],
|
|
479
504
|
[t('usage.magpieErrors'), formatMagpieNumber(usage.aggregate.errors)],
|
|
@@ -523,12 +548,14 @@ function MagpieUsagePopover({ rpc, usage, t, tab = 'usage', onTabChange = () =>
|
|
|
523
548
|
'aria-labelledby': `codingns4dsh-magpie-tab-${tab}`,
|
|
524
549
|
style: magpieTabPanelStyle,
|
|
525
550
|
}, tab === 'usage' ? MagpieUsagePanel({ usage, aggregateRows, sessionRows, t })
|
|
526
|
-
: MagpieRoutePanel({ rpc, usage, quotas, t, expandedGroups, onToggleGroup
|
|
551
|
+
: MagpieRoutePanel({ rpc, usage, quotas, t, expandedGroups, onToggleGroup,
|
|
552
|
+
...(requestsDialogRef === undefined ? {} : { requestsDialogRef }),
|
|
553
|
+
})));
|
|
527
554
|
}
|
|
528
555
|
function MagpieUsagePanel({ usage, aggregateRows, sessionRows, t }) {
|
|
529
556
|
return createElement('div', undefined, createElement('section', { style: magpieUsageSectionStyle }, createElement('strong', { style: magpieSectionTitleStyle }, t('usage.magpieAggregateTitle')), usage.usageStatus === 'available'
|
|
530
557
|
? createMagpieRows(aggregateRows)
|
|
531
|
-
: createElement('div', { style: magpieMutedTextStyle }, t('usage.magpieUsageUnavailable'))), createElement('section', { style: magpieUsageSectionStyle }, createElement('strong', { style: magpieSectionTitleStyle }, t('usage.magpieSessionTitle')), usage.sessionId !== null && createElement('div', { style: magpieSessionIdentityStyle }, createElement('span',
|
|
558
|
+
: createElement('div', { style: magpieMutedTextStyle }, t('usage.magpieUsageUnavailable'))), createElement('section', { style: magpieUsageSectionStyle }, createElement('strong', { style: magpieSectionTitleStyle }, t(usage.sessionPeriod === 'today' ? 'usage.magpieSessionTodayTitle' : 'usage.magpieSessionTitle')), usage.sessionId !== null && createElement('div', { style: magpieSessionIdentityStyle }, createElement('div', { style: magpieSessionNameRowStyle }, createElement('span', { style: { flex: 'none' } }, t('usage.magpieAgent', { agent: usage.agent })), usage.sessionName !== undefined && createElement('strong', { style: magpieSessionNameStyle, title: usage.sessionName }, usage.sessionName)), createElement('code', { style: magpieSessionIdStyle }, usage.sessionId)), usage.session === null
|
|
532
559
|
? createElement('div', { style: magpieMutedTextStyle }, usage.sessionId === null ? t('usage.magpieSessionIdUnavailable') : t('usage.magpieSessionNoUsage'))
|
|
533
560
|
: createMagpieRows(sessionRows)));
|
|
534
561
|
}
|
|
@@ -549,7 +576,7 @@ function createMagpieQuotaCard(quota, t, index) {
|
|
|
549
576
|
return createElement('div', { key: `${quota.provider}-${quota.user ?? 'account'}-${index}`, style: magpieQuotaCardStyle }, createElement('div', { style: magpieQuotaCardHeadingStyle }, createElement('span', { style: magpieQuotaNameWithLogoStyle }, createElement(MagpieProviderLogo, { identities: [quota.provider, quota.name], logoDataUrl: quota.logoDataUrl, size: 20, className: 'codingns4dsh-magpie-quota-logo', fallback: 'none' }), createElement('span', { style: magpieQuotaNameStyle }, quota.alias ?? quota.name)), createElement('span', { style: magpieQuotaHeadingMetaStyle }, quota.plan ?? quota.provider)), (quota.user !== null || quota.balance !== null) && createElement('div', { style: magpieQuotaIdentityStyle }, quota.user !== null && createElement('span', { title: quota.user }, t('usage.magpieQuotaAccount', { account: quota.user })), quota.balance !== null && createElement('span', undefined, t('usage.magpieQuotaBalance', { balance: quota.balance }))), quota.windows.length === 0
|
|
550
577
|
? createElement('div', { style: magpieQuotaMetaStyle }, t('usage.magpieQuotaNoWindows'))
|
|
551
578
|
: quota.windows.map((window, windowIndex) => {
|
|
552
|
-
const remaining = window
|
|
579
|
+
const remaining = quotaWindowRemaining(window);
|
|
553
580
|
// 积分窗口(WorkBuddy 的 `0 / 350`)按数量读更准确:百分比在这里没有意义。
|
|
554
581
|
const credits = formatQuotaWindowCredits(window);
|
|
555
582
|
const amount = window.display ?? (window.amount !== null && window.limit !== null ? `${window.amount} / ${window.limit}${window.unit === null ? '' : ` ${window.unit}`}` : null);
|
|
@@ -569,10 +596,11 @@ function formatQuotaWindowCredits(window) {
|
|
|
569
596
|
const credits = readWindowCreditBalance(window);
|
|
570
597
|
return credits === null ? null : formatQuotaCredits(credits);
|
|
571
598
|
}
|
|
572
|
-
function MagpieRoutePanel({ rpc, usage, quotas, t, expandedGroups, onToggleGroup }) {
|
|
599
|
+
function MagpieRoutePanel({ rpc, usage, quotas, t, expandedGroups, onToggleGroup, requestsDialogRef }) {
|
|
573
600
|
const route = usage.route;
|
|
574
601
|
const groups = groupQuotasByProvider(quotas);
|
|
575
602
|
const sessionAccount = route?.providerAccount ?? null;
|
|
603
|
+
const requestSessionId = usage.requestSessionId ?? usage.session?.id ?? usage.sessionId;
|
|
576
604
|
const quotaMessage = magpieQuotaUnavailableMessage(usage, quotas, t);
|
|
577
605
|
const routeStatus = usage.routeStatus === 'no-route'
|
|
578
606
|
? t('usage.magpieRouteNoRequests')
|
|
@@ -615,10 +643,11 @@ function MagpieRoutePanel({ rpc, usage, quotas, t, expandedGroups, onToggleGroup
|
|
|
615
643
|
// “查看请求”入口与状态徽标同高、同排:入口在左,状态在右。
|
|
616
644
|
createElement(MagpieRouteRequests, {
|
|
617
645
|
rpc,
|
|
618
|
-
sessionId:
|
|
646
|
+
sessionId: requestSessionId,
|
|
619
647
|
sessionName: usage.sessionName ?? null,
|
|
620
648
|
agent: usage.agent,
|
|
621
649
|
t,
|
|
650
|
+
...(requestsDialogRef === undefined ? {} : { requestsDialogRef }),
|
|
622
651
|
}), createElement('span', { className: active ? 'codingns4dsh-magpie-route-node-active' : undefined, style: magpieRouteStatusStyle }, createElement('span', { style: magpieRouteStatusDotStyle }), createElement('strong', undefined, route.done === true ? t('usage.magpieRouteComplete') : route.done === false ? t('usage.magpieRouteRunning').replace(/\s*·\s*$/u, '') : route.status ?? '--')))), route === null
|
|
623
652
|
? createElement('div', { style: magpieEmptyStateStyle }, routeStatus)
|
|
624
653
|
: createElement('div', { style: magpieRouteHeroStyle }, createElement('div', { style: magpieRouteTrackStyle, 'aria-label': t('usage.magpieRouteFlowTitle'), role: 'list' }, ...routeStages.map(([label, model], index) => createElement('div', {
|
|
@@ -635,35 +664,42 @@ function MagpieRoutePanel({ rpc, usage, quotas, t, expandedGroups, onToggleGroup
|
|
|
635
664
|
* `MagpieRoutePanel` 渲染元素,真正的状态留在本组件内部。模态框内的请求明细
|
|
636
665
|
* 直接复用管理页的 `RequestsPage`,只把会话筛选固定为当前会话。
|
|
637
666
|
*/
|
|
638
|
-
export function MagpieRouteRequests({ rpc, sessionId, sessionName, agent, t }) {
|
|
667
|
+
export function MagpieRouteRequests({ rpc, sessionId, sessionName, agent, t, requestsDialogRef }) {
|
|
639
668
|
const enabled = canReadMagpieSessionRequests(sessionId, agent);
|
|
640
669
|
const [open, setOpen] = useState(false);
|
|
670
|
+
// 弹层固定筛选一个会话:这里持有从头累计的所有已加载请求,而不是只留当前一页。
|
|
641
671
|
const [page, setPage] = useState(null);
|
|
642
672
|
const [offset, setOffset] = useState(0);
|
|
643
673
|
const [loading, setLoading] = useState(false);
|
|
644
674
|
const [error, setError] = useState(false);
|
|
645
675
|
const [reloadKey, setReloadKey] = useState(0);
|
|
646
676
|
const controllerRef = useRef(null);
|
|
677
|
+
const sequenceRef = useRef(0);
|
|
647
678
|
useEffect(() => {
|
|
648
679
|
if (!open || !enabled)
|
|
649
680
|
return;
|
|
650
681
|
const controller = new AbortController();
|
|
651
682
|
controllerRef.current = controller;
|
|
683
|
+
// 只有一次请求在飞:更晚的请求序号作废更早的回包。
|
|
684
|
+
const sequence = sequenceRef.current + 1;
|
|
685
|
+
sequenceRef.current = sequence;
|
|
652
686
|
setLoading(true);
|
|
653
687
|
setError(false);
|
|
654
688
|
void readMagpieSessionRequestPage(rpc, sessionId, agent, offset, controller.signal).then((next) => {
|
|
655
|
-
if (controller.signal.aborted)
|
|
689
|
+
if (controller.signal.aborted || sequence !== sequenceRef.current)
|
|
656
690
|
return;
|
|
657
691
|
if (next === null) {
|
|
658
692
|
setError(true);
|
|
659
693
|
return;
|
|
660
694
|
}
|
|
661
|
-
setPage(
|
|
695
|
+
setPage((current) => current === null || offset === 0
|
|
696
|
+
? next
|
|
697
|
+
: { ...next, items: [...current.items, ...next.items] });
|
|
662
698
|
}).catch(() => {
|
|
663
|
-
if (!controller.signal.aborted)
|
|
699
|
+
if (!controller.signal.aborted && sequence === sequenceRef.current)
|
|
664
700
|
setError(true);
|
|
665
701
|
}).finally(() => {
|
|
666
|
-
if (!controller.signal.aborted)
|
|
702
|
+
if (!controller.signal.aborted && sequence === sequenceRef.current)
|
|
667
703
|
setLoading(false);
|
|
668
704
|
});
|
|
669
705
|
return () => {
|
|
@@ -672,6 +708,24 @@ export function MagpieRouteRequests({ rpc, sessionId, sessionName, agent, t }) {
|
|
|
672
708
|
controllerRef.current = null;
|
|
673
709
|
};
|
|
674
710
|
}, [open, enabled, offset, reloadKey, rpc, sessionId, agent]);
|
|
711
|
+
// 滚到列表底部就自动追加下一页:149 条请求也能一口气看完,不必数着点“加载更多”。
|
|
712
|
+
// 用捕获阶段监听滚动,真实滚动容器(弹层主体、表格横向容器)都在子树里。
|
|
713
|
+
useEffect(() => {
|
|
714
|
+
if (!open || typeof document === 'undefined' || !enabled)
|
|
715
|
+
return;
|
|
716
|
+
const onScroll = (event) => {
|
|
717
|
+
const target = event.target;
|
|
718
|
+
if (!(target instanceof Element) || !target.closest('.codingns4dsh-magpie-requests-body'))
|
|
719
|
+
return;
|
|
720
|
+
if (target.scrollHeight - target.scrollTop - target.clientHeight > 160)
|
|
721
|
+
return;
|
|
722
|
+
if (loading || error || page === null || !page.hasMore)
|
|
723
|
+
return;
|
|
724
|
+
setOffset(page.items.length);
|
|
725
|
+
};
|
|
726
|
+
document.addEventListener('scroll', onScroll, true);
|
|
727
|
+
return () => document.removeEventListener('scroll', onScroll, true);
|
|
728
|
+
}, [open, enabled, loading, error, page]);
|
|
675
729
|
// 模态框覆盖整个视口,Esc 是移动端之外唯一的键盘关闭方式。
|
|
676
730
|
useEffect(() => {
|
|
677
731
|
if (!open || typeof document === 'undefined')
|
|
@@ -718,7 +772,13 @@ export function MagpieRouteRequests({ rpc, sessionId, sessionName, agent, t }) {
|
|
|
718
772
|
error,
|
|
719
773
|
t,
|
|
720
774
|
onClose: close,
|
|
721
|
-
|
|
775
|
+
...(requestsDialogRef === undefined ? {} : { dialogRef: requestsDialogRef }),
|
|
776
|
+
onOffsetChange: (value) => {
|
|
777
|
+
// 追加下一页;重试则从头重读,避免把同一页拼两遍。
|
|
778
|
+
if (value === 0)
|
|
779
|
+
setPage(null);
|
|
780
|
+
setOffset(value);
|
|
781
|
+
},
|
|
722
782
|
onRetry: () => { setLoading(true); setError(false); setReloadKey((value) => value + 1); },
|
|
723
783
|
}));
|
|
724
784
|
}
|
|
@@ -726,10 +786,10 @@ export function MagpieRouteRequests({ rpc, sessionId, sessionName, agent, t }) {
|
|
|
726
786
|
function canReadMagpieSessionRequests(sessionId, agent) {
|
|
727
787
|
return sessionId !== null && sessionId.trim() !== '' && sessionId.length <= 512 && /^[a-z0-9][a-z0-9-]*$/u.test(agent);
|
|
728
788
|
}
|
|
729
|
-
/**
|
|
789
|
+
/** Include every date in the selected session's paginated request history. */
|
|
730
790
|
async function readMagpieSessionRequestPage(rpc, sessionId, agent, offset, signal) {
|
|
731
791
|
const result = await callCodingNsRpcResult(rpc, 'magpie/usage/requests', {
|
|
732
|
-
period: '
|
|
792
|
+
period: 'all',
|
|
733
793
|
offset,
|
|
734
794
|
limit: MAGPIE_REQUESTS_PAGE_SIZE,
|
|
735
795
|
sessionId,
|
|
@@ -748,9 +808,11 @@ async function readMagpieSessionRequestPage(rpc, sessionId, agent, offset, signa
|
|
|
748
808
|
* 管理页视图自带统计条、桌面表格 / 移动卡片、分页和空状态,这里只负责把会话固定住,
|
|
749
809
|
* 不再维护一套重复的请求卡片渲染。
|
|
750
810
|
*/
|
|
751
|
-
function MagpieSessionRequestsDialog({ sessionId, sessionName, agent, page, offset, loading, error, t, onClose, onOffsetChange, onRetry }) {
|
|
752
|
-
|
|
811
|
+
function MagpieSessionRequestsDialog({ sessionId, sessionName, agent, page, offset, loading, error, t, onClose, dialogRef, onOffsetChange, onRetry }) {
|
|
812
|
+
const displaySessionName = sessionName ?? page?.sessionName ?? null;
|
|
813
|
+
const dialog = createElement('div', {
|
|
753
814
|
className: 'codingns4dsh-magpie-requests-overlay',
|
|
815
|
+
ref: dialogRef,
|
|
754
816
|
role: 'presentation',
|
|
755
817
|
style: magpieRequestsOverlayStyle,
|
|
756
818
|
// 只有按在遮罩自身时才关闭;从内容内部按下再拖到遮罩上不会误关。
|
|
@@ -780,12 +842,18 @@ function MagpieSessionRequestsDialog({ sessionId, sessionName, agent, page, offs
|
|
|
780
842
|
page,
|
|
781
843
|
loading,
|
|
782
844
|
error,
|
|
783
|
-
selectedSession: { id: sessionId, agent, ...(
|
|
845
|
+
selectedSession: { id: sessionId, agent, ...(displaySessionName === null ? {} : { dshSessionName: displaySessionName }) },
|
|
784
846
|
offset,
|
|
785
847
|
onOffsetChange,
|
|
786
848
|
onClearSession: null,
|
|
787
849
|
t,
|
|
850
|
+
// 弹层筛选的是单一会话,列表从头累计,直到整条会话的请求都加载完。
|
|
851
|
+
append: true,
|
|
788
852
|
})))));
|
|
853
|
+
// The usage popover has its own lower stacking context. Portaling the modal
|
|
854
|
+
// to body lets it actually cover the host sidebar instead of being clipped
|
|
855
|
+
// by the popover's parent context.
|
|
856
|
+
return typeof document === 'undefined' ? dialog : createPortal(dialog, document.body);
|
|
789
857
|
}
|
|
790
858
|
function createMagpieRows(rows) {
|
|
791
859
|
if (rows.length === 0)
|
|
@@ -1206,17 +1274,20 @@ const MAGPIE_QUOTA_RETRY_MS = 3_000;
|
|
|
1206
1274
|
function shouldResolveMagpieQuota(usage) {
|
|
1207
1275
|
if (usage === null || usage === undefined)
|
|
1208
1276
|
return false;
|
|
1277
|
+
if (usage.session === null)
|
|
1278
|
+
return true;
|
|
1209
1279
|
if (usage.quotaStatus !== 'available')
|
|
1210
1280
|
return usage.upstreamProvider === null;
|
|
1211
|
-
return usage.sessionId !== null && usage.session !== null && usage.quotas
|
|
1281
|
+
return usage.sessionId !== null && usage.session !== null && (usage.quotas?.length ?? 0) === 0;
|
|
1212
1282
|
}
|
|
1213
1283
|
function resolveMagpieQuotaRemaining(usage) {
|
|
1214
|
-
|
|
1215
|
-
return null;
|
|
1216
|
-
for (const quota of usage.quotas) {
|
|
1284
|
+
for (const quota of usage.quotas ?? []) {
|
|
1217
1285
|
for (const window of quota.windows) {
|
|
1218
|
-
|
|
1219
|
-
|
|
1286
|
+
// A few Magpie responses report only `used`; the quota card derives the same
|
|
1287
|
+
// remaining share, so the compact trigger must use that normalized value too.
|
|
1288
|
+
const remaining = quotaWindowRemaining(window);
|
|
1289
|
+
if (remaining !== null)
|
|
1290
|
+
return remaining;
|
|
1220
1291
|
}
|
|
1221
1292
|
}
|
|
1222
1293
|
return null;
|
|
@@ -1411,9 +1482,10 @@ const magpieStatsGridStyle = { display: 'grid', gridTemplateColumns: 'repeat(3,
|
|
|
1411
1482
|
const magpieStatStyle = { display: 'grid', alignContent: 'space-between', gap: 1, minWidth: 0, minHeight: 40, boxSizing: 'border-box', padding: '5px 7px', borderRadius: 8, background: dshThemeColor.surfaceSubtle };
|
|
1412
1483
|
const magpieStatLabelStyle = { minWidth: 0, color: dshThemeColor.labelTertiary, fontSize: uiFontSize(10), lineHeight: '13px', overflowWrap: 'anywhere' };
|
|
1413
1484
|
const magpieRowValueStyle = { color: dshThemeColor.labelPrimary, fontSize: uiFontSize(14), fontWeight: 650, lineHeight: '18px', textAlign: 'right', overflowWrap: 'anywhere' };
|
|
1414
|
-
const magpieSessionIdentityStyle = { display: '
|
|
1415
|
-
const
|
|
1416
|
-
const
|
|
1485
|
+
const magpieSessionIdentityStyle = { display: 'grid', gap: 2, minWidth: 0, color: dshThemeColor.labelSecondary, fontSize: uiFontSize(12), lineHeight: '16px' };
|
|
1486
|
+
const magpieSessionNameRowStyle = { display: 'flex', alignItems: 'baseline', gap: 10, minWidth: 0 };
|
|
1487
|
+
const magpieSessionNameStyle = { minWidth: 0, maxWidth: '100%', overflow: 'hidden', color: dshThemeColor.labelPrimary, fontSize: uiFontSize(12), fontWeight: 650, textOverflow: 'ellipsis', whiteSpace: 'nowrap' };
|
|
1488
|
+
const magpieSessionIdStyle = { minWidth: 0, color: dshThemeColor.labelTertiary, fontSize: uiFontSize(10), lineHeight: '14px', whiteSpace: 'normal', overflowWrap: 'anywhere' };
|
|
1417
1489
|
const magpieAttemptsStyle = { display: 'grid', gap: 5, paddingTop: 6 };
|
|
1418
1490
|
const magpieAttemptRowStyle = { display: 'flex', justifyContent: 'space-between', gap: 14, fontSize: uiFontSize(12) };
|
|
1419
1491
|
const magpieAttemptModelStyle = { color: dshThemeColor.labelSecondary, overflowWrap: 'anywhere' };
|
|
@@ -1452,7 +1524,7 @@ const magpieRouteMetaValueStyle = { color: dshThemeColor.labelSecondary, fontSiz
|
|
|
1452
1524
|
// 请求入口与请求模态框:入口与状态徽标同高并排在标题栏,模态框覆盖视口并在内部滚动。
|
|
1453
1525
|
const magpieRouteHeadingActionsStyle = { display: 'inline-flex', alignItems: 'center', gap: 8, minWidth: 0 };
|
|
1454
1526
|
const magpieRouteRequestsButtonStyle = { flex: 'none', display: 'inline-flex', alignItems: 'center', gap: 4, boxSizing: 'border-box', padding: '2px 8px', border: `1px solid ${dshThemeColor.border}`, borderRadius: 999, background: dshThemeColor.menuBackground, color: dshThemeColor.labelSecondary, fontFamily: 'inherit', fontSize: uiFontSize(11), lineHeight: '15px', cursor: 'pointer', whiteSpace: 'nowrap', transition: 'background .15s ease,color .15s ease' };
|
|
1455
|
-
const magpieRequestsOverlayStyle = { position: 'fixed', inset: 0, zIndex:
|
|
1527
|
+
const magpieRequestsOverlayStyle = { position: 'fixed', inset: 0, zIndex: 2147483000, display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 16, boxSizing: 'border-box', background: dshThemeColor.overlay };
|
|
1456
1528
|
const magpieRequestsDialogStyle = { ...dshPopupSurfaceStyle, display: 'flex', flexDirection: 'column', gap: 10, width: 'min(96vw, 1320px)', maxHeight: 'min(88vh, 820px)', boxSizing: 'border-box', padding: 14, borderRadius: 14 };
|
|
1457
1529
|
const magpieRequestsHeadingStyle = { display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12, paddingBottom: 10, borderBottom: `1px solid ${dshThemeColor.border}` };
|
|
1458
1530
|
const magpieRequestsHeadingActionsStyle = { display: 'inline-flex', alignItems: 'center', gap: 8, flex: 'none' };
|