@kenz1117/dsh-ui-usage-billing 1.7.4 → 1.8.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +15 -14
- package/README.md +15 -14
- package/lib/client.js +5 -5
- package/lib/index.js +630 -3
- package/lib/types/client/PeakAlertBanner.d.ts +1 -1
- package/lib/types/client/TaskQueuePanel.d.ts +19 -0
- package/lib/types/client/api/task-queue.d.ts +21 -0
- package/lib/types/client/domain/types.d.ts +4 -4
- package/lib/types/client/live-cost.d.ts +1 -8
- package/lib/types/client/locales.d.ts +1 -1
- package/lib/types/client/peak-alert.d.ts +6 -0
- package/lib/types/config.d.ts +3 -0
- package/lib/types/routes/task-queue.d.ts +9 -0
- package/lib/types/task-queue-shared.d.ts +54 -0
- package/lib/types/task-queue.d.ts +63 -0
- package/package.json +1 -3
- package/lib/types/client/context-store.d.ts +0 -68
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/** Off-peak task queue panel: explicit enqueue, visible outcomes, safe old-host fallback. */
|
|
2
|
+
import type { BillingLanguage } from './usage-billing-settings.ts';
|
|
3
|
+
import type { UsageBillingKey } from './locales.ts';
|
|
4
|
+
import type { TaskQueueInput } from '../task-queue-shared.ts';
|
|
5
|
+
interface TaskQueuePanelProps {
|
|
6
|
+
readonly t: (key: UsageBillingKey, params?: Record<string, unknown>) => string;
|
|
7
|
+
readonly language: BillingLanguage;
|
|
8
|
+
readonly navigateToSession: (sessionId: string) => 'opened' | 'unavailable' | 'failed';
|
|
9
|
+
}
|
|
10
|
+
interface ImportDefaults {
|
|
11
|
+
readonly cwd: string;
|
|
12
|
+
readonly provider: string;
|
|
13
|
+
readonly model: string;
|
|
14
|
+
}
|
|
15
|
+
/** Normalize only the transport shape; authoritative validation stays atomic on the server. */
|
|
16
|
+
export declare function parseTaskQueueImport(text: string, defaults: ImportDefaults): TaskQueueInput[];
|
|
17
|
+
export declare function TaskQueuePanel({ t, language, navigateToSession }: TaskQueuePanelProps): React.ReactNode;
|
|
18
|
+
export {};
|
|
19
|
+
//# sourceMappingURL=TaskQueuePanel.d.ts.map
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** API client for the new-host off-peak task queue preview (issue #106). */
|
|
2
|
+
import type { TaskQueueInput, TaskQueueSnapshot, TaskQueueSummary } from '../../task-queue-shared.ts';
|
|
3
|
+
export declare function loadTaskQueue(): Promise<TaskQueueSnapshot>;
|
|
4
|
+
export declare function loadTaskQueueSummary(): Promise<TaskQueueSummary>;
|
|
5
|
+
export type TaskQueueAction = {
|
|
6
|
+
action: 'enqueue';
|
|
7
|
+
prompt: string;
|
|
8
|
+
cwd: string;
|
|
9
|
+
provider: string;
|
|
10
|
+
model: string;
|
|
11
|
+
} | {
|
|
12
|
+
action: 'enqueueMany';
|
|
13
|
+
tasks: readonly TaskQueueInput[];
|
|
14
|
+
} | {
|
|
15
|
+
action: 'remove';
|
|
16
|
+
id: string;
|
|
17
|
+
} | {
|
|
18
|
+
action: 'clearFinished';
|
|
19
|
+
};
|
|
20
|
+
export declare function mutateTaskQueue(action: TaskQueueAction): Promise<TaskQueueSnapshot>;
|
|
21
|
+
//# sourceMappingURL=task-queue.d.ts.map
|
|
@@ -27,12 +27,12 @@ export interface ModelHealth {
|
|
|
27
27
|
/** Idle health state before the probe settles. */
|
|
28
28
|
export declare const IDLE_HEALTH: ModelHealth;
|
|
29
29
|
/** 仪表盘分区 Tab id。 */
|
|
30
|
-
export type DashboardTab = 'overview' | '
|
|
30
|
+
export type DashboardTab = 'overview' | 'queue' | 'agents' | 'token' | 'trends' | 'providers' | 'pricing' | 'settings';
|
|
31
31
|
import type { UsageBillingKey } from '../locales.ts';
|
|
32
32
|
/**
|
|
33
|
-
* Tab 定义(顺序即渲染顺序):概览=主数字/KPI
|
|
34
|
-
*
|
|
35
|
-
*
|
|
33
|
+
* Tab 定义(顺序即渲染顺序):概览=主数字/KPI/热力图,队列=低谷任务(新宿主预览),
|
|
34
|
+
* 账单=厂商计费与订阅,用量=Token 用量,趋势=趋势图/每轮费用,费率=模型单价表,
|
|
35
|
+
* 设置=预算与峰谷提醒。导出供测试断言 tab 与文案 key 对齐。
|
|
36
36
|
*/
|
|
37
37
|
export declare const DASHBOARD_TABS: readonly {
|
|
38
38
|
id: DashboardTab;
|
|
@@ -21,7 +21,6 @@
|
|
|
21
21
|
import type { SessionId } from '@deepseek-ai/dsh-session/types';
|
|
22
22
|
import type { LiveCostBarPrefs } from './usage-billing-settings.ts';
|
|
23
23
|
import type { UsageBillingKey } from './locales.ts';
|
|
24
|
-
import type { UseProjection } from '@deepseek-ai/dsh-api-session-controller/client';
|
|
25
24
|
/** The usage-stats shape the composer bar needs (a thin slice, not the whole doc). */
|
|
26
25
|
export interface LiveStats {
|
|
27
26
|
bySession?: readonly {
|
|
@@ -117,12 +116,6 @@ export declare function isBlankPhase(session: SessionPhaseSlice): boolean;
|
|
|
117
116
|
export interface LiveCostBarProps {
|
|
118
117
|
/** Current Session identity supplied by the session-scope standard kit. */
|
|
119
118
|
sessionId: SessionId;
|
|
120
|
-
/**
|
|
121
|
-
* Host projection reader (session-scope standard kit). Present only on hosts
|
|
122
|
-
* that serve session projections; absent → no context dimension (the
|
|
123
|
-
* dashboard hides that card entirely rather than showing zeros).
|
|
124
|
-
*/
|
|
125
|
-
useProjection?: UseProjection;
|
|
126
119
|
/** The owning seat's locale seat (bound to the billing NS). */
|
|
127
120
|
t: (key: UsageBillingKey) => string;
|
|
128
121
|
/** Which host seat this instance occupies; it renders only when the position pref matches. */
|
|
@@ -135,7 +128,7 @@ export interface LiveCostBarProps {
|
|
|
135
128
|
* @param props - framework session identity, locale, the seat occupied, and
|
|
136
129
|
* (input.dock only) the owner session snapshot.
|
|
137
130
|
*/
|
|
138
|
-
export declare function LiveCostBar({ sessionId, t, seat, session
|
|
131
|
+
export declare function LiveCostBar({ sessionId, t, seat, session }: LiveCostBarProps): React.ReactNode;
|
|
139
132
|
/** Props of the tool-row chip: session identity and locale only (its seat is fixed to input.right). */
|
|
140
133
|
export type LiveCostChipProps = Pick<LiveCostBarProps, 'sessionId' | 't'>;
|
|
141
134
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Locale dictionaries for the usage billing surface. */
|
|
2
|
-
export type UsageBillingKey = 'title' | 'cost' | 'todayCost' | 'monthCost' | 'yearCost' | 'monthProjected' | 'monthProjectedHint' | 'liveTurn' | 'liveSession' | 'liveSessionSub' | 'calls' | 'cacheHitRate' | 'tokens' | 'inputTokens' | 'outputTokens' | 'avgCost' | 'kpiRange' | 'avgRangeToday' | 'avgRange7d' | 'avgRangeWeek' | 'avgRangeMonth' | 'avgRangeAll' | 'trend' | 'trend7d' | 'trend30d' | 'trendMetric' | 'trendMetricCost' | 'trendMetricTokens' | 'pricingSearch' | 'bandPinHint' | 'trendEmpty' | 'trendTotal' | 'roundsUnit' | 'healthModelsLive' | 'healthVendorsDown' | 'healthVendorsUnavailable' | 'budget' | 'budgetRemain' | 'budgetAmount' | 'budgetSummary' | 'sessions' | 'sessionTitle' | 'lastActive' | 'sessionOverflow' | 'budgetTierBody' | 'models' | 'providerBilling' | 'channelUnknown' | 'directTag' | 'relayTag' | 'unknownTag' | 'unknownChannelHint' | 'planCountUnit' | 'actual' | 'pricing' | 'input' | 'output' | 'cacheHit' | 'peak' | 'offPeak' | 'flat' | 'band' | 'close' | 'footer' | 'footerCredit' | 'lastUpdated' | 'noData' | 'todayRate' | 'rateLive' | 'rateBuiltin' | 'pricingSyncedAt' | 'pricingSyncNow' | 'pricingSyncing' | 'promoBadge' | 'promoUntil' | 'promoOpenEnded' | 'pricingTip' | 'pricingUnit' | 'pricingNotes' | 'ubPeak' | 'ubOff' | 'ubStd' | 'peakBand' | 'pricingSource' | 'noteCache' | 'noteBand' | 'noteSource' | 'balance' | 'recharge' | 'rechargeHint' | 'balanceUnconfigured' | 'balanceUnauthorized' | 'balanceUnreachable' | 'uncatalogued' | 'estimatedPricing' | 'balanceDays' | 'balanceLowBody' | 'reconcileDrift' | 'reconcileDismiss' | 'subscriptionNotConfigured' | 'subscriptionUnauthorized' | 'subscriptionUnavailable' | 'subscriptionInvalid' | 'subscriptionRateLimited' | 'subscriptionSession' | 'subscriptionWeekly' | 'subscriptionMonthly' | 'subscriptionBilling' | 'subscriptionRemaining' | 'subscriptionExhausted' | 'subscriptionReset' | 'subscriptionNoApi' | 'floatWindow' | 'floatModeCombined' | 'floatModeSubscription' | 'floatMode' | 'floatTargets' | 'floatWindowHint' | 'floatPrimaryToday' | 'floatPrimaryWeek' | 'floatPrimaryMonth' | 'floatNoTargets' | 'floatNoTargetsHint' | 'cardDisplay' | 'cardDisplayHint' | 'cardMetric' | 'cardMetricMoney' | 'cardMetricTokens' | 'cardSpan' | 'cardSpanDay' | 'cardSpanWeek' | 'cardSpanMonth' | 'cardDeltaBadge' | 'cardDeltaShow' | 'cardDeltaHide' | 'triggerMonthTokens' | 'triggerTodayTokens' | 'triggerWeekTokens' | 'subscriptionsStale' | 'balanceStaleNotice' | 'staleLedgerNotice' | 'staleSnapshotNotice' | 'unreadableNotice' | 'unreadableFormatNotice' | 'unreadableNoLedgerNotice' | 'tokenCacheWrite' | 'toolRank' | 'toolName' | 'userPrices' | 'userPricesHint' | 'userPriceSave' | 'userPriceModel' | 'userPriceSource' | 'userPriceSourceHint' | 'userPriceOffPeak' | 'userPriceNormal' | 'userPriceCurrency' | 'userPriceAdd' | 'userPriceRemoveSelected' | 'userPriceSelect' | 'sessionStaleBadge' | 'sessionUntitled' | 'sessionSubCost' | 'sessionSubCalls' | 'sessionSubRow' | 'heatmapLess' | 'heatmapMore' | 'currency' | 'currencyCny' | 'currencyUsd' | 'currencyEur' | 'language' | 'heatmap' | 'rounds' | 'roundsHint' | 'anomaly' | 'model' | 'thModel' | 'thInputMiss' | 'thInputHit' | 'costAbbr' | 'tabOverview' | 'tabTrends' | 'tabProviders' | 'tabPricing' | 'tabSettings' | 'budgetHint' | 'peakAlertHint' | 'peakAlertDescPeak' | 'peakAlertDescOff' | 'peakAlertDescPeakZhipu' | 'peakAlertDescOffZhipu' | 'export' | 'exportCsvDay' | 'exportCsvSession' | 'exportJson' | 'peakShare' | 'peakSharePerCall' | 'offPeakSavings' | 'perfMax' | 'weekCost' | 'roleCost' | 'roleUser' | 'roleAssistant' | 'roleTool' | 'roleHint' | 'tierPeak' | 'tierOff' | 'tierToPeak' | 'tierToOff' | 'tierAlertEnterPeak' | 'tierAlertEnterOff' | 'tierAlertEnterPeakZhipu' | 'tierAlertEnterOffZhipu' | 'peakAlertTitlePeak' | 'peakAlertTitleOff' | 'peakAlert' | 'peakAlertLeadMin' | 'peakAlertPos' | 'peakAlertMode' | 'peakAlertPosCorner' | 'peakAlertPosCenter' | 'peakAlertModePeak' | 'peakAlertModeOff' | 'peakAlertModeBoth' | 'peakAlertWebNotify' | 'peakAlertPreview' | 'planTypeCode' | 'planTypeToken' | 'subscriptionFeePerMonth' | 'triggerToday' | 'triggerMonth' | 'subscriptionTag' | 'cellEstimateHint' | 'free' | 'perfSamples' | 'perfTtft' | 'perfP50' | 'perfP90' | 'perfTps' | 'perfLatency' | 'perfEstimated' | 'perfEmpty' | 'perfTpsUnit' | 'perfTitle' | 'perfHint' | 'perfAll' | 'perfChartEmpty' | 'heatmapYear' | 'heatmapHalf' | 'heatmapMonth' | 'metricCost' | 'metricTokens' | 'heatmapTotal' | 'activeDays' | 'streakDays' | 'subscriptionAutoDetect' | 'pluginAuthor' | 'pluginRepository' | 'pluginNpm' | 'pluginLicense' | 'tabToken' | 'tokenExport' | 'tokenExportCsv' | 'tokenReasoningShare' | 'tokenReasoningShort' | 'tokenIo' | 'tokenPeak' | 'densityLabel' | 'densityHint' | 'densityCompact' | 'densityDefault' | 'densityComfortable' | 'motionLabel' | 'motionHint' | 'motionOff' | 'motionSubtle' | 'motionRich' | 'settingsNavDisplayPref' | 'settingsNavBudget' | 'settingsNavAlert' | 'settingsNavDisplay' | 'settingsNavAdvanced' | 'settingsNavAbout' | 'settingsSearchPlaceholder' | 'settingsSearchEmpty' | 'sessionsViewAll' | 'sessionViewerSearch' | 'modelBudgetTitle' | 'modelBudgetHint' | 'modelBudgetBody' | 'modelBudgetPlaceholder' | 'moreWorksTitle' | 'adEngramName' | 'adEngramDesc' | 'adRainbowName' | 'adRainbowDesc' | 'kpiDescCacheHit' | 'kpiDescTokens' | 'kpiDescAvgCost' | 'kpiDescCalls' | 'kpiDescReasoning' | 'kpiDescIo' | 'kpiDescPeak' | 'healthDotLive' | 'healthDotFailed' | 'healthDotUnknown' | 'settingsSectionDisplay' | 'emptyHint' | 'tokenDaily' | 'tokenByModel' | 'tokenMiss' | 'tokenHit' | 'tokenOutput' | 'tokenViewStructure' | 'tokenViewModel' | 'tokenHitShort' | 'tokenMissShort' | 'tokenTotal' | 'tokenShare' | 'usageStatsTool' | 'usageStatsToolHint' | 'balanceGranted' | 'balanceTopped' | 'balanceDaily' | 'balanceDaysLong' | 'balanceDaysUnit' | 'popTodayModel' | 'popNoConsumption' | 'popTitle' | 'popDirectLead' | 'popSubLead' | 'unpricedHint' | 'searchEstimateHint' | 'siteListDisplay' | 'siteListDisplayHint' | 'liveCostBar' | 'liveCostBarHint' | 'liveCostBarPosition' | 'liveCostBarPosBelow' | 'liveCostBarPosAbove' | 'liveCostBarPosToolbar' | 'exportCsvSite' | 'panelRelayQuota' | 'relayBalance' | 'relayNoQuota' | 'relayWindowUsed' | 'relayKindNewApi' | 'relayKindSub2Api' | 'relayKindUnknown' | 'expandAll' | 'collapseAll' | 'todayOnly' | 'todayNoConsumption' | 'commandUsageLabel' | 'commandUsageDescription' | 'sessionOpen' | 'sessionOpenFailed' | 'sessionOpenUnavailable' | '
|
|
2
|
+
export type UsageBillingKey = 'title' | 'cost' | 'todayCost' | 'monthCost' | 'yearCost' | 'monthProjected' | 'monthProjectedHint' | 'liveTurn' | 'liveSession' | 'liveSessionSub' | 'calls' | 'cacheHitRate' | 'tokens' | 'inputTokens' | 'outputTokens' | 'avgCost' | 'kpiRange' | 'avgRangeToday' | 'avgRange7d' | 'avgRangeWeek' | 'avgRangeMonth' | 'avgRangeAll' | 'trend' | 'trend7d' | 'trend30d' | 'trendMetric' | 'trendMetricCost' | 'trendMetricTokens' | 'pricingSearch' | 'bandPinHint' | 'trendEmpty' | 'trendTotal' | 'roundsUnit' | 'healthModelsLive' | 'healthVendorsDown' | 'healthVendorsUnavailable' | 'budget' | 'budgetRemain' | 'budgetAmount' | 'budgetSummary' | 'sessions' | 'sessionTitle' | 'lastActive' | 'sessionOverflow' | 'budgetTierBody' | 'models' | 'providerBilling' | 'channelUnknown' | 'directTag' | 'relayTag' | 'unknownTag' | 'unknownChannelHint' | 'planCountUnit' | 'actual' | 'pricing' | 'input' | 'output' | 'cacheHit' | 'peak' | 'offPeak' | 'flat' | 'band' | 'close' | 'footer' | 'footerCredit' | 'lastUpdated' | 'noData' | 'todayRate' | 'rateLive' | 'rateBuiltin' | 'pricingSyncedAt' | 'pricingSyncNow' | 'pricingSyncing' | 'promoBadge' | 'promoUntil' | 'promoOpenEnded' | 'pricingTip' | 'pricingUnit' | 'pricingNotes' | 'ubPeak' | 'ubOff' | 'ubStd' | 'peakBand' | 'pricingSource' | 'noteCache' | 'noteBand' | 'noteSource' | 'balance' | 'recharge' | 'rechargeHint' | 'balanceUnconfigured' | 'balanceUnauthorized' | 'balanceUnreachable' | 'uncatalogued' | 'estimatedPricing' | 'balanceDays' | 'balanceLowBody' | 'reconcileDrift' | 'reconcileDismiss' | 'subscriptionNotConfigured' | 'subscriptionUnauthorized' | 'subscriptionUnavailable' | 'subscriptionInvalid' | 'subscriptionRateLimited' | 'subscriptionSession' | 'subscriptionWeekly' | 'subscriptionMonthly' | 'subscriptionBilling' | 'subscriptionRemaining' | 'subscriptionExhausted' | 'subscriptionReset' | 'subscriptionNoApi' | 'floatWindow' | 'floatModeCombined' | 'floatModeSubscription' | 'floatMode' | 'floatTargets' | 'floatWindowHint' | 'floatPrimaryToday' | 'floatPrimaryWeek' | 'floatPrimaryMonth' | 'floatNoTargets' | 'floatNoTargetsHint' | 'cardDisplay' | 'cardDisplayHint' | 'cardMetric' | 'cardMetricMoney' | 'cardMetricTokens' | 'cardSpan' | 'cardSpanDay' | 'cardSpanWeek' | 'cardSpanMonth' | 'cardDeltaBadge' | 'cardDeltaShow' | 'cardDeltaHide' | 'triggerMonthTokens' | 'triggerTodayTokens' | 'triggerWeekTokens' | 'subscriptionsStale' | 'balanceStaleNotice' | 'staleLedgerNotice' | 'staleSnapshotNotice' | 'unreadableNotice' | 'unreadableFormatNotice' | 'unreadableNoLedgerNotice' | 'tokenCacheWrite' | 'toolRank' | 'toolName' | 'userPrices' | 'userPricesHint' | 'userPriceSave' | 'userPriceModel' | 'userPriceSource' | 'userPriceSourceHint' | 'userPriceOffPeak' | 'userPriceNormal' | 'userPriceCurrency' | 'userPriceAdd' | 'userPriceRemoveSelected' | 'userPriceSelect' | 'sessionStaleBadge' | 'sessionUntitled' | 'sessionSubCost' | 'sessionSubCalls' | 'sessionSubRow' | 'heatmapLess' | 'heatmapMore' | 'currency' | 'currencyCny' | 'currencyUsd' | 'currencyEur' | 'language' | 'heatmap' | 'rounds' | 'roundsHint' | 'anomaly' | 'model' | 'thModel' | 'thInputMiss' | 'thInputHit' | 'costAbbr' | 'tabOverview' | 'tabTrends' | 'tabProviders' | 'tabPricing' | 'tabSettings' | 'budgetHint' | 'peakAlertHint' | 'peakAlertDescPeak' | 'peakAlertDescOff' | 'peakAlertDescPeakZhipu' | 'peakAlertDescOffZhipu' | 'peakAlertQueuePeak' | 'peakAlertQueueOff' | 'export' | 'exportCsvDay' | 'exportCsvSession' | 'exportJson' | 'peakShare' | 'peakSharePerCall' | 'offPeakSavings' | 'perfMax' | 'weekCost' | 'roleCost' | 'roleUser' | 'roleAssistant' | 'roleTool' | 'roleHint' | 'tierPeak' | 'tierOff' | 'tierToPeak' | 'tierToOff' | 'tierAlertEnterPeak' | 'tierAlertEnterOff' | 'tierAlertEnterPeakZhipu' | 'tierAlertEnterOffZhipu' | 'peakAlertTitlePeak' | 'peakAlertTitleOff' | 'peakAlert' | 'peakAlertLeadMin' | 'peakAlertPos' | 'peakAlertMode' | 'peakAlertPosCorner' | 'peakAlertPosCenter' | 'peakAlertModePeak' | 'peakAlertModeOff' | 'peakAlertModeBoth' | 'peakAlertWebNotify' | 'peakAlertPreview' | 'planTypeCode' | 'planTypeToken' | 'subscriptionFeePerMonth' | 'triggerToday' | 'triggerMonth' | 'subscriptionTag' | 'cellEstimateHint' | 'free' | 'perfSamples' | 'perfTtft' | 'perfP50' | 'perfP90' | 'perfTps' | 'perfLatency' | 'perfEstimated' | 'perfEmpty' | 'perfTpsUnit' | 'perfTitle' | 'perfHint' | 'perfAll' | 'perfChartEmpty' | 'heatmapYear' | 'heatmapHalf' | 'heatmapMonth' | 'metricCost' | 'metricTokens' | 'heatmapTotal' | 'activeDays' | 'streakDays' | 'subscriptionAutoDetect' | 'pluginAuthor' | 'pluginRepository' | 'pluginNpm' | 'pluginLicense' | 'tabToken' | 'tokenExport' | 'tokenExportCsv' | 'tokenReasoningShare' | 'tokenReasoningShort' | 'tokenIo' | 'tokenPeak' | 'densityLabel' | 'densityHint' | 'densityCompact' | 'densityDefault' | 'densityComfortable' | 'motionLabel' | 'motionHint' | 'motionOff' | 'motionSubtle' | 'motionRich' | 'settingsNavDisplayPref' | 'settingsNavBudget' | 'settingsNavAlert' | 'settingsNavDisplay' | 'settingsNavAdvanced' | 'settingsNavAbout' | 'settingsSearchPlaceholder' | 'settingsSearchEmpty' | 'sessionsViewAll' | 'sessionViewerSearch' | 'modelBudgetTitle' | 'modelBudgetHint' | 'modelBudgetBody' | 'modelBudgetPlaceholder' | 'moreWorksTitle' | 'adEngramName' | 'adEngramDesc' | 'adRainbowName' | 'adRainbowDesc' | 'kpiDescCacheHit' | 'kpiDescTokens' | 'kpiDescAvgCost' | 'kpiDescCalls' | 'kpiDescReasoning' | 'kpiDescIo' | 'kpiDescPeak' | 'healthDotLive' | 'healthDotFailed' | 'healthDotUnknown' | 'settingsSectionDisplay' | 'emptyHint' | 'tokenDaily' | 'tokenByModel' | 'tokenMiss' | 'tokenHit' | 'tokenOutput' | 'tokenViewStructure' | 'tokenViewModel' | 'tokenHitShort' | 'tokenMissShort' | 'tokenTotal' | 'tokenShare' | 'usageStatsTool' | 'usageStatsToolHint' | 'balanceGranted' | 'balanceTopped' | 'balanceDaily' | 'balanceDaysLong' | 'balanceDaysUnit' | 'popTodayModel' | 'popNoConsumption' | 'popTitle' | 'popDirectLead' | 'popSubLead' | 'unpricedHint' | 'searchEstimateHint' | 'siteListDisplay' | 'siteListDisplayHint' | 'liveCostBar' | 'liveCostBarHint' | 'liveCostBarPosition' | 'liveCostBarPosBelow' | 'liveCostBarPosAbove' | 'liveCostBarPosToolbar' | 'exportCsvSite' | 'panelRelayQuota' | 'relayBalance' | 'relayNoQuota' | 'relayWindowUsed' | 'relayKindNewApi' | 'relayKindSub2Api' | 'relayKindUnknown' | 'expandAll' | 'collapseAll' | 'todayOnly' | 'todayNoConsumption' | 'commandUsageLabel' | 'commandUsageDescription' | 'sessionOpen' | 'sessionOpenFailed' | 'sessionOpenUnavailable' | 'tabAgents' | 'tabQueue' | 'queueSubtitle' | 'queueUntilPeak' | 'queueUntilOffPeak' | 'queueUnsupportedTitle' | 'queueUnsupportedBody' | 'queueSafety' | 'queueWorkspace' | 'queueModel' | 'queueNoOptions' | 'queuePromptLabel' | 'queuePromptPlaceholder' | 'queuePrivacy' | 'queueEnqueue' | 'queueImport' | 'queueImportHint' | 'queueImported' | 'queueImportFormat' | 'queueImportTooLarge' | 'queueActive' | 'queueClearFinished' | 'queueEmpty' | 'queueLoading' | 'queueOpenSession' | 'queueRemoveQueued' | 'queueRemoveHistory' | 'queueStatusQueued' | 'queueStatusStarting' | 'queueStatusRunning' | 'queueStatusCompleted' | 'queueStatusFailed' | 'agentsSummary' | 'agentsCount' | 'agentsDelegations' | 'agentsRoots' | 'agentsMostExpensive' | 'agentsChainTotal' | 'agentsNoData' | 'agentsSubagent' | 'agentsRoot';
|
|
3
3
|
export declare const NS = "usageBilling";
|
|
4
4
|
export declare const zh: Record<UsageBillingKey, string>;
|
|
5
5
|
export declare const en: Record<UsageBillingKey, string>;
|
|
@@ -33,7 +33,13 @@ export interface PeakAlertHit {
|
|
|
33
33
|
entering: PriceTierId;
|
|
34
34
|
atMs: number;
|
|
35
35
|
channel: RateChannel;
|
|
36
|
+
/** Waiting DeepSeek queue items; informational only, never an execution action. */
|
|
37
|
+
queueCount?: number;
|
|
36
38
|
}
|
|
39
|
+
/** Prefer the current model's alert; merge queue context only at the same switch. */
|
|
40
|
+
export declare function mergeQueuePeakAlert(current: PeakAlertHit | null, queue: PeakAlertHit | null, queuedCount: number): PeakAlertHit | null;
|
|
41
|
+
/** Keep an already-visible banner truthful as the lightweight queue count changes. */
|
|
42
|
+
export declare function refreshQueuePeakAlert(current: PeakAlertHit | null, queuedCount: number): PeakAlertHit | null;
|
|
37
43
|
/** 读取本地偏好(缺失/损坏回退默认,字段宽松校验)。 */
|
|
38
44
|
export declare function loadPeakAlertConfig(): PeakAlertConfig;
|
|
39
45
|
/** 保存偏好;存储失败静默(降级为关闭,不影响其它能力)。 */
|
package/lib/types/config.d.ts
CHANGED
|
@@ -46,6 +46,9 @@ export interface UsageBillingConfig {
|
|
|
46
46
|
ledgerPath?: string;
|
|
47
47
|
/** 余额差对账基准的持久化路径;默认 `<harness home>/.dsh-usage-reconcile.json`。 */
|
|
48
48
|
reconcilePath?: string;
|
|
49
|
+
/** 低谷任务队列的持久化路径;默认 `<harness home>/.dsh-usage-task-queue.json`。
|
|
50
|
+
* 文件包含待执行 Prompt,以 0600 写入;测试可注入临时路径隔离真实队列。 */
|
|
51
|
+
taskQueuePath?: string;
|
|
49
52
|
/** 订阅制(coding / token / agent plan)provider id 列表;默认 kimi-coding、xiaomi-token-plan-cn。 */
|
|
50
53
|
subscriptionProviders?: string[];
|
|
51
54
|
/** 订阅套餐额度适配器(kimi / zai / opencode-go);默认全部内置。 */
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** Loopback-only GET/POST /api/billing/task-queue (issue #106). */
|
|
2
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
3
|
+
import { type TaskQueueEngine } from '../task-queue.ts';
|
|
4
|
+
export interface TaskQueueRouteDeps {
|
|
5
|
+
readonly trustedHosts: ReadonlySet<string>;
|
|
6
|
+
readonly engine: TaskQueueEngine;
|
|
7
|
+
}
|
|
8
|
+
export declare function registerTaskQueueRoute(ctx: Context, deps: TaskQueueRouteDeps): void;
|
|
9
|
+
//# sourceMappingURL=task-queue.d.ts.map
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/** Browser-safe wire types for the opt-in off-peak task queue (issue #106). */
|
|
2
|
+
export type TaskQueueStatus = 'queued' | 'starting' | 'running' | 'completed' | 'failed';
|
|
3
|
+
/** Unvalidated enqueue input shared by the HTTP client and server-side engine. */
|
|
4
|
+
export interface TaskQueueInput {
|
|
5
|
+
readonly prompt?: unknown;
|
|
6
|
+
readonly cwd?: unknown;
|
|
7
|
+
readonly provider?: unknown;
|
|
8
|
+
readonly model?: unknown;
|
|
9
|
+
}
|
|
10
|
+
export interface TaskQueueTask {
|
|
11
|
+
readonly id: string;
|
|
12
|
+
readonly prompt: string;
|
|
13
|
+
readonly cwd: string;
|
|
14
|
+
readonly provider: string;
|
|
15
|
+
readonly model: string;
|
|
16
|
+
readonly status: TaskQueueStatus;
|
|
17
|
+
readonly createdAt: number;
|
|
18
|
+
readonly startedAt?: number | undefined;
|
|
19
|
+
readonly finishedAt?: number | undefined;
|
|
20
|
+
readonly sessionId?: string | undefined;
|
|
21
|
+
readonly error?: string | undefined;
|
|
22
|
+
}
|
|
23
|
+
export interface TaskQueueWorkspace {
|
|
24
|
+
readonly path: string;
|
|
25
|
+
readonly title: string;
|
|
26
|
+
}
|
|
27
|
+
export interface TaskQueueModel {
|
|
28
|
+
readonly provider: string;
|
|
29
|
+
readonly providerName: string;
|
|
30
|
+
readonly id: string;
|
|
31
|
+
readonly name: string;
|
|
32
|
+
}
|
|
33
|
+
export interface TaskQueueSnapshot {
|
|
34
|
+
/** All required host Session-control methods are available. */
|
|
35
|
+
readonly supported: boolean;
|
|
36
|
+
readonly tier: 'peak' | 'offPeak';
|
|
37
|
+
readonly nextSwitchInMs: number;
|
|
38
|
+
readonly tasks: readonly TaskQueueTask[];
|
|
39
|
+
readonly workspaces: readonly TaskQueueWorkspace[];
|
|
40
|
+
readonly models: readonly TaskQueueModel[];
|
|
41
|
+
readonly optionsError?: string;
|
|
42
|
+
}
|
|
43
|
+
/** Lightweight alert polling shape: never transports Prompt or Session content. */
|
|
44
|
+
export interface TaskQueueSummary {
|
|
45
|
+
readonly supported: boolean;
|
|
46
|
+
readonly tier: 'peak' | 'offPeak';
|
|
47
|
+
readonly nextSwitchInMs: number;
|
|
48
|
+
readonly queuedCount: number;
|
|
49
|
+
}
|
|
50
|
+
export interface TaskQueueMutation {
|
|
51
|
+
readonly ok: true;
|
|
52
|
+
readonly snapshot: TaskQueueSnapshot;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=task-queue-shared.d.ts.map
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Durable off-peak FIFO task queue (issue #106, new-host capability preview).
|
|
3
|
+
*
|
|
4
|
+
* Safety contract: tasks START only in the DeepSeek off-peak window; an admitted
|
|
5
|
+
* turn is never cancelled at the next peak. Failed/unknown outcomes never auto-
|
|
6
|
+
* retry. A file lock + owner lease prevents two DSH instances sharing DSH_HOME
|
|
7
|
+
* from submitting the same task. Prompts are persisted with mode 0600.
|
|
8
|
+
*/
|
|
9
|
+
import type { SessionController } from '@deepseek-ai/dsh-api-session-controller';
|
|
10
|
+
import type { TaskQueueInput, TaskQueueSnapshot, TaskQueueSummary, TaskQueueWorkspace } from './task-queue-shared.ts';
|
|
11
|
+
export type TaskQueueController = Pick<SessionController, 'create' | 'selectModel' | 'prompt' | 'follow' | 'modelCatalog'>;
|
|
12
|
+
type ControllerFace = TaskQueueController;
|
|
13
|
+
export interface TaskQueueEngineOptions {
|
|
14
|
+
readonly filePath: string;
|
|
15
|
+
readonly getController: () => ControllerFace | undefined;
|
|
16
|
+
readonly getWorkspaces: () => readonly TaskQueueWorkspace[];
|
|
17
|
+
readonly now?: () => number;
|
|
18
|
+
readonly createId?: () => string;
|
|
19
|
+
readonly ownerId?: string;
|
|
20
|
+
readonly pollMs?: number;
|
|
21
|
+
}
|
|
22
|
+
export declare class TaskQueueError extends Error {
|
|
23
|
+
readonly status: number;
|
|
24
|
+
constructor(message: string, status?: number);
|
|
25
|
+
}
|
|
26
|
+
export declare class TaskQueueEngine {
|
|
27
|
+
private readonly options;
|
|
28
|
+
private readonly now;
|
|
29
|
+
private readonly createId;
|
|
30
|
+
private readonly ownerId;
|
|
31
|
+
private readonly pollMs;
|
|
32
|
+
private timer;
|
|
33
|
+
private heartbeat;
|
|
34
|
+
private taskAbort;
|
|
35
|
+
private stopped;
|
|
36
|
+
private pumping;
|
|
37
|
+
private modelCache;
|
|
38
|
+
constructor(options: TaskQueueEngineOptions);
|
|
39
|
+
start(): void;
|
|
40
|
+
stop(): void;
|
|
41
|
+
snapshot(): Promise<TaskQueueSnapshot>;
|
|
42
|
+
summary(): Promise<TaskQueueSummary>;
|
|
43
|
+
enqueue(input: TaskQueueInput): Promise<void>;
|
|
44
|
+
/** Validate the whole batch before one locked append: no partially admitted import. */
|
|
45
|
+
enqueueMany(inputs: readonly TaskQueueInput[]): Promise<void>;
|
|
46
|
+
remove(id: string): Promise<void>;
|
|
47
|
+
clearFinished(): Promise<void>;
|
|
48
|
+
private modelOptions;
|
|
49
|
+
private pump;
|
|
50
|
+
private claimNext;
|
|
51
|
+
private recoverExpired;
|
|
52
|
+
private execute;
|
|
53
|
+
private watch;
|
|
54
|
+
private renewLease;
|
|
55
|
+
private requeue;
|
|
56
|
+
private finish;
|
|
57
|
+
private patch;
|
|
58
|
+
private update;
|
|
59
|
+
private readDocument;
|
|
60
|
+
private readDocumentWithRaw;
|
|
61
|
+
}
|
|
62
|
+
export {};
|
|
63
|
+
//# sourceMappingURL=task-queue.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kenz1117/dsh-ui-usage-billing",
|
|
3
3
|
"description": "Usage billing dashboard for DeepSeek Harness: sidebar cost metrics plus a full dashboard modal, priced from a current multi-provider catalog with real usage aggregated from session logs.",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.8.0-alpha.2",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"deepseek-harness",
|
|
7
7
|
"deepseek",
|
|
@@ -115,7 +115,6 @@
|
|
|
115
115
|
"@deepseek-ai/dsh-client-ui-slots": "*",
|
|
116
116
|
"@deepseek-ai/dsh-client-ui-commands": "*",
|
|
117
117
|
"@deepseek-ai/dsh-client-ui-workspace": "*",
|
|
118
|
-
"@deepseek-ai/dsh-token-meter": "*",
|
|
119
118
|
"@deepseek-ai/dsh-credentials": "*",
|
|
120
119
|
"@deepseek-ai/dsh-home-paths": "*",
|
|
121
120
|
"@deepseek-ai/dsh-host-webserver": "*",
|
|
@@ -162,7 +161,6 @@
|
|
|
162
161
|
"@deepseek-ai/dsh-session-persistence": "0.2.1-rc.4",
|
|
163
162
|
"@deepseek-ai/dsh-settings": "0.2.1-rc.4",
|
|
164
163
|
"@deepseek-ai/dsh-system-prompt": "0.2.1-rc.4",
|
|
165
|
-
"@deepseek-ai/dsh-token-meter": "0.2.1-rc.4",
|
|
166
164
|
"@deepseek-ai/dsh-tools": "0.2.1-rc.4",
|
|
167
165
|
"@deepseek-ai/dsh-typert-protocol": "0.2.1-rc.4",
|
|
168
166
|
"@deepseek-ai/dsh-user-approval": "0.2.1-rc.4",
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 上下文占用快照 store:把宿主的 token-meter 投影从**会话作用域**搬到全局弹窗。
|
|
3
|
-
*
|
|
4
|
-
* 宿主能力(@deepseek-ai/dsh-token-meter,经会话作用域标准 props 的 useProjection 读):
|
|
5
|
-
* - `contextPressure`:{ pressureTokens?, projectedTokens?, contextWindow? }
|
|
6
|
-
* —— provider 上报的最近一次提示词占用、下一次请求的占用外推、路由容量上限。
|
|
7
|
-
* - `contextBreakdown`:{ systemTokens, toolsTokens, messageTokens }
|
|
8
|
-
* —— 下一次请求上下文的构成拆解(**启发式 token 估算**,三项之和不等于
|
|
9
|
-
* provider 锚定的 projectedTokens:估算器系统性低估 CJK 与 JSON schema)。
|
|
10
|
-
*
|
|
11
|
-
* 为什么需要这个 store:`contextPressure` / `contextBreakdown` 只在**会话作用域**
|
|
12
|
-
* 的槽位里可读(投影按会话分发),而仪表盘弹窗是全局的——侧边栏触发的弹窗不在
|
|
13
|
-
* 任何会话作用域内。解法:会话作用域里已有的即时代费用条(conversation.composer.dock
|
|
14
|
-
* 座位)顺手读一次投影并发布到本 store,弹窗订阅它。
|
|
15
|
-
*
|
|
16
|
-
* 降级:没有会话 / 宿主不提供该投影 / 老宿主没有 token-meter → store 保持空,
|
|
17
|
-
* 界面整块隐藏(**不显示 0、不显示占位假数据**)。
|
|
18
|
-
*/
|
|
19
|
-
/** 上下文占用快照(两个投影的合并视图)。 */
|
|
20
|
-
export interface ContextOccupancy {
|
|
21
|
-
/** 下一次请求的提示词占用(provider 锚定 + 增量外推)——面板主指标。 */
|
|
22
|
-
projectedTokens?: number;
|
|
23
|
-
/** 最近一次请求的提示词占用(provider 上报值)。 */
|
|
24
|
-
pressureTokens?: number;
|
|
25
|
-
/** 路由容量(上下文窗口上限);适配器未上报时缺席。 */
|
|
26
|
-
contextWindow?: number;
|
|
27
|
-
/** 系统提示词占用(启发式估算)。 */
|
|
28
|
-
systemTokens?: number;
|
|
29
|
-
/** 工具 schema 占用(启发式估算)。 */
|
|
30
|
-
toolsTokens?: number;
|
|
31
|
-
/** 消息占用(启发式估算)。 */
|
|
32
|
-
messageTokens?: number;
|
|
33
|
-
}
|
|
34
|
-
/** 空快照:无数据(界面据此整块隐藏)。 */
|
|
35
|
-
export declare const EMPTY_CONTEXT: ContextOccupancy;
|
|
36
|
-
/** 上下文 store:写入方 = 会话作用域的费用条;读取方 = 全局仪表盘弹窗。 */
|
|
37
|
-
export interface ContextStore {
|
|
38
|
-
/** 发布新快照(内容未变时保持同一对象引用,避免无谓重渲染)。 */
|
|
39
|
-
publish(next: ContextOccupancy): void;
|
|
40
|
-
/** 订阅变更;立即收到当前值一次(若为空则收到 undefined)。 */
|
|
41
|
-
subscribe(listener: (value: ContextOccupancy | undefined) => void): () => void;
|
|
42
|
-
/** 读取当前快照(无数据返回 undefined)。 */
|
|
43
|
-
read(): ContextOccupancy | undefined;
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* 创建上下文 store。
|
|
47
|
-
* @returns store 实例。
|
|
48
|
-
*/
|
|
49
|
-
export declare function createContextStore(): ContextStore;
|
|
50
|
-
/**
|
|
51
|
-
* 占用率(0..1):以外推占用除以窗口容量。
|
|
52
|
-
* 缺任一要素 → undefined(界面不画进度,不以 0 冒充)。
|
|
53
|
-
* @param occupancy - 占用快照。
|
|
54
|
-
* @returns 占用率或 undefined。
|
|
55
|
-
*/
|
|
56
|
-
export declare function occupancyRatio(occupancy: ContextOccupancy | undefined): number | undefined;
|
|
57
|
-
/**
|
|
58
|
-
* 构成拆解的三项(顺序固定,便于渲染与比较)。
|
|
59
|
-
* @param occupancy - 占用快照。
|
|
60
|
-
* @returns 构成项数组(无任何构成数据时返回空数组)。
|
|
61
|
-
*/
|
|
62
|
-
export declare function occupancyBreakdown(occupancy: ContextOccupancy | undefined): readonly {
|
|
63
|
-
key: 'system' | 'tools' | 'message';
|
|
64
|
-
tokens: number;
|
|
65
|
-
}[];
|
|
66
|
-
/** 页面级单例:同一页面只有一个计费插件实例,与其它模块级单例同口径。 */
|
|
67
|
-
export declare const contextStore: ContextStore;
|
|
68
|
-
//# sourceMappingURL=context-store.d.ts.map
|