@kenz1117/dsh-ui-usage-billing 1.6.7 → 1.7.0
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 +28 -4
- package/README.md +32 -4
- package/lib/client.js +3 -3
- package/lib/index.js +158 -39
- package/lib/types/aggregate.d.ts +19 -0
- package/lib/types/client/api/balance.d.ts +8 -4
- package/lib/types/client/api/http.d.ts +36 -0
- package/lib/types/client/api/subscriptions.d.ts +7 -1
- package/lib/types/client/context-store.d.ts +68 -0
- package/lib/types/client/domain/agent-tree.d.ts +60 -0
- package/lib/types/client/domain/types.d.ts +12 -13
- package/lib/types/client/live-cost.d.ts +8 -1
- package/lib/types/client/locales.d.ts +1 -1
- package/lib/types/client/session-navigation.d.ts +36 -0
- package/lib/types/client/usage-command.d.ts +37 -0
- package/lib/types/pricing-shared.d.ts +6 -0
- package/lib/types/routes/balance.d.ts +18 -2
- package/lib/types/routes/relay-quotas.d.ts +8 -0
- package/lib/types/routes/subscriptions.d.ts +8 -0
- package/lib/types/routes/usage-stats.d.ts +7 -0
- package/package.json +39 -31
|
@@ -21,6 +21,7 @@
|
|
|
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';
|
|
24
25
|
/** The usage-stats shape the composer bar needs (a thin slice, not the whole doc). */
|
|
25
26
|
export interface LiveStats {
|
|
26
27
|
bySession?: readonly {
|
|
@@ -116,6 +117,12 @@ export declare function isBlankPhase(session: SessionPhaseSlice): boolean;
|
|
|
116
117
|
export interface LiveCostBarProps {
|
|
117
118
|
/** Current Session identity supplied by the session-scope standard kit. */
|
|
118
119
|
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;
|
|
119
126
|
/** The owning seat's locale seat (bound to the billing NS). */
|
|
120
127
|
t: (key: UsageBillingKey) => string;
|
|
121
128
|
/** Which host seat this instance occupies; it renders only when the position pref matches. */
|
|
@@ -128,7 +135,7 @@ export interface LiveCostBarProps {
|
|
|
128
135
|
* @param props - framework session identity, locale, the seat occupied, and
|
|
129
136
|
* (input.dock only) the owner session snapshot.
|
|
130
137
|
*/
|
|
131
|
-
export declare function LiveCostBar({ sessionId, t, seat, session }: LiveCostBarProps): React.ReactNode;
|
|
138
|
+
export declare function LiveCostBar({ sessionId, t, seat, session, useProjection }: LiveCostBarProps): React.ReactNode;
|
|
132
139
|
/** Props of the tool-row chip: session identity and locale only (its seat is fixed to input.right). */
|
|
133
140
|
export type LiveCostChipProps = Pick<LiveCostBarProps, 'sessionId' | 't'>;
|
|
134
141
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Locale dictionaries for the usage billing surface. */
|
|
2
|
-
export type UsageBillingKey = 'title' | 'cost' | 'todayCost' | 'monthCost' | 'yearCost' | 'monthProjected' | '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' | 'staleLedgerNotice' | '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';
|
|
2
|
+
export type UsageBillingKey = 'title' | 'cost' | 'todayCost' | 'monthCost' | 'yearCost' | 'monthProjected' | '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' | 'contextOccupancy' | 'contextWindow' | 'contextSystem' | 'contextTools' | 'contextMessages' | 'contextNoData' | 'tabContext' | 'tabAgents' | 'contextNextRequest' | 'contextLastRequest' | 'contextComposition' | 'contextCompositionHint' | '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>;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 会话跳转(跨插件导航):把面板里的会话行接到宿主的会话选择通道。
|
|
3
|
+
*
|
|
4
|
+
* 宿主有**两代**通道(实测自 deepseek-harness 源码,非推测):
|
|
5
|
+
* - 0.1.6-alpha.2+:`ctx.uiWorkspace.openSession(SessionId)`
|
|
6
|
+
* (@deepseek-ai/dsh-client-ui-workspace,packages/client/ui-workspace/src/client/navigation.ts:36)
|
|
7
|
+
* - 0.1.2-alpha.1 ~ 0.1.6-alpha.1:`ctx.sessions.open(SessionId)`
|
|
8
|
+
* (@deepseek-ai/dsh-api-session-controller,packages/api/session-controller/src/client/contract/sessions.ts:44
|
|
9
|
+
* —— 注释写明「id 必须在列表中,不存在则 fail loud」)
|
|
10
|
+
* master 已移除 `sessions.open`,故运行时按「新 → 旧」探测,两条都不可用时降级为不可跳转。
|
|
11
|
+
*
|
|
12
|
+
* 取服务一律走 `ctx.get()`(cordis 的免 inject 服务读取),**不进 inject 列表**:
|
|
13
|
+
* 老宿主没有 uiWorkspace 服务,把它声明成注入依赖会挂起等它、卡住整个 web 启动
|
|
14
|
+
* (本仓 apply.ts 对 remote.llm 的注释记过这个坑:issue #28 的同源教训)。
|
|
15
|
+
*
|
|
16
|
+
* 老宿主的 `sessions.open` 对未知 id 会 fail loud——本插件的会话行来自**持久化会话
|
|
17
|
+
* 日志**,可能不在宿主当前会话列表里(删过、别的 profile、只读快照),故调用必须
|
|
18
|
+
* 包 try/catch 并把失败如实回报给 UI,不得让点击抛错。
|
|
19
|
+
*/
|
|
20
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
21
|
+
/** 跳转结果:opened=已跳转;unavailable=宿主无通道(老到没有);failed=通道报错。 */
|
|
22
|
+
export type SessionNavigationResult = 'opened' | 'unavailable' | 'failed';
|
|
23
|
+
/** 会话跳转器:面板用它把「点会话行」接到宿主导航。 */
|
|
24
|
+
export interface SessionNavigator {
|
|
25
|
+
/** 当前宿主是否具备跳转能力(运行时探测,服务可能后到)。 */
|
|
26
|
+
available(): boolean;
|
|
27
|
+
/** 打开指定会话;返回结果供 UI 决定是否提示。 */
|
|
28
|
+
open(sessionId: string): SessionNavigationResult;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* 构造会话跳转器。
|
|
32
|
+
* @param ctx - 客户端根 context(服务读取走 ctx.get,不声明注入依赖)。
|
|
33
|
+
* @returns 跳转器。
|
|
34
|
+
*/
|
|
35
|
+
export declare function createSessionNavigator(ctx: Context): SessionNavigator;
|
|
36
|
+
//# sourceMappingURL=session-navigation.d.ts.map
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `/usage` 对话内命令:把计费仪表盘拉进对话流。
|
|
3
|
+
*
|
|
4
|
+
* 宿主能力(@deepseek-ai/dsh-client-ui-commands,`ctx.commandUi`):
|
|
5
|
+
* - `register(contribution)` 注册一个**客户端自有**的斜杠命令,与宿主命令目录按
|
|
6
|
+
* 名字合并;同名撞宿主命令会 fail loud(绝不遮蔽宿主命令)——故命令名取
|
|
7
|
+
* `usage`,宿主目录里没有同名命令。
|
|
8
|
+
* - `contribution.ui` 用 `{ kind: 'action', run(session) }`:行为完全在客户端,
|
|
9
|
+
* 不回传宿主命令执行器。
|
|
10
|
+
* - `label` / `description` 是**函数**:菜单每次打开都重新读取,切换语言立即生效,
|
|
11
|
+
* 无需重新注册。
|
|
12
|
+
*
|
|
13
|
+
* 取服务走 `ctx.get('commandUi')`(cordis 免 inject 读取):老宿主没有该服务时
|
|
14
|
+
* **不注册命令**,面板功能完全不受影响——这是「服务缺席即降级、不得因此收窄兼容
|
|
15
|
+
* 矩阵」的落点(宿主自己的 ui-permission-presets 也是 `ctx.get('commandUi')`)。
|
|
16
|
+
*/
|
|
17
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
18
|
+
/** 命令名(斜杠后不带斜杠):与宿主命令目录合并的键。 */
|
|
19
|
+
export declare const USAGE_COMMAND_NAME = "usage";
|
|
20
|
+
/** 注册参数。 */
|
|
21
|
+
export interface UsageCommandOptions {
|
|
22
|
+
/** 打开计费仪表盘(复用面板已注册的打开回调)。 */
|
|
23
|
+
openDashboard: () => void;
|
|
24
|
+
/** 菜单行标题(每次候选合成时读取,语言切换即时生效)。 */
|
|
25
|
+
label: () => string;
|
|
26
|
+
/** 菜单行描述。 */
|
|
27
|
+
description: () => string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* 注册 `/usage` 命令。
|
|
31
|
+
*
|
|
32
|
+
* @param ctx - 客户端根 context。
|
|
33
|
+
* @param options - 打开回调与文案。
|
|
34
|
+
* @returns 是否注册成功(宿主无 commandUi 服务时返回 false,属正常降级)。
|
|
35
|
+
*/
|
|
36
|
+
export declare function registerUsageCommand(ctx: Context, options: UsageCommandOptions): boolean;
|
|
37
|
+
//# sourceMappingURL=usage-command.d.ts.map
|
|
@@ -78,6 +78,12 @@ export interface BalanceResponse {
|
|
|
78
78
|
balances: readonly ProviderBalance[];
|
|
79
79
|
/** 官方余额差对账提示(对账开启且当日有余额消费时下发)。 */
|
|
80
80
|
reconcile?: ReconcileNotice;
|
|
81
|
+
/**
|
|
82
|
+
* 本次余额来自上一次成功的查询(服务端刷新超预算,issue #104):
|
|
83
|
+
* 上游查询被拖住时不再把响应长期挂起,改为回旧值并标记,客户端据此提示
|
|
84
|
+
* 「余额数据来自上次查询」。
|
|
85
|
+
*/
|
|
86
|
+
stale?: boolean;
|
|
81
87
|
}
|
|
82
88
|
/** 官方余额差对账提示(drift 时携带供 UI 展示的已用/本地费用)。 */
|
|
83
89
|
export interface ReconcileNotice {
|
|
@@ -5,8 +5,9 @@
|
|
|
5
5
|
* TokenHub 等)+ 用户自定义余额 + 声明端点 + 余额差对账。5 分钟缓存(避免
|
|
6
6
|
* 每 30s 后台轮询打上游),in-flight 去重(并发请求共享同一次进行中的刷新)。
|
|
7
7
|
*
|
|
8
|
-
* 路由文件只关心 HTTP 缓存逻辑:5 分钟过期判定 +
|
|
9
|
-
*
|
|
8
|
+
* 路由文件只关心 HTTP 缓存逻辑:5 分钟过期判定 + 刷新预算(超预算回旧
|
|
9
|
+
* 缓存并标 stale,不把响应挂在长查询上)+ 失败时仍发旧缓存(不挂起已
|
|
10
|
+
* writeHead 的响应)。上游查询(queryBalances / queryCustomBalances /
|
|
10
11
|
* queryDeclaredEndpoints / reconcileBalanceDelta)在装配器里跑,路由只通过
|
|
11
12
|
* `cached()` 与 `refreshOnce()` 拿到结果。
|
|
12
13
|
*/
|
|
@@ -17,6 +18,11 @@ import type { ReconcileEvent } from '../reconcile.ts';
|
|
|
17
18
|
export interface BalanceDoc {
|
|
18
19
|
balances: readonly ProviderBalance[];
|
|
19
20
|
reconcile?: ReconcileEvent;
|
|
21
|
+
/**
|
|
22
|
+
* 本次余额来自上一次成功的查询(刷新超预算,见 {@link BalanceDeps.responseBudgetMs})。
|
|
23
|
+
* 客户端据此提示「余额数据来自上次查询」,别把旧值当最新读。
|
|
24
|
+
*/
|
|
25
|
+
stale?: boolean;
|
|
20
26
|
}
|
|
21
27
|
interface CachedBalance {
|
|
22
28
|
doc: BalanceDoc;
|
|
@@ -31,6 +37,16 @@ export interface BalanceDeps {
|
|
|
31
37
|
refreshOnce: () => Promise<void>;
|
|
32
38
|
/** 5 分钟缓存间隔(毫秒)。 */
|
|
33
39
|
cacheMs: number;
|
|
40
|
+
/**
|
|
41
|
+
* 刷新的总等待预算(毫秒):超预算立刻回上一次成功的余额。
|
|
42
|
+
*
|
|
43
|
+
* 存在的理由(issue #104):浏览器对同源最多 6 条并发连接,而余额响应被
|
|
44
|
+
* 上游查询(最坏 8s 超时 × 重试)拖住时,这条连接会被长期占住;多标签页
|
|
45
|
+
* 各挂一条即占满连接池,宿主自己的资源请求排队——用户看到的是「整个 DSH
|
|
46
|
+
* 界面卡死」。预算到期后刷新在后台继续(in-flight 去重共享同一次刷新),
|
|
47
|
+
* 下一轮轮询即可拿到新值。
|
|
48
|
+
*/
|
|
49
|
+
responseBudgetMs: number;
|
|
34
50
|
}
|
|
35
51
|
export declare function registerBalanceRoute(ctx: Context, deps: BalanceDeps): void;
|
|
36
52
|
export {};
|
|
@@ -21,6 +21,14 @@ export interface RelayQuotasDeps {
|
|
|
21
21
|
refreshOnce: () => Promise<void>;
|
|
22
22
|
/** 5 分钟缓存间隔(毫秒)。 */
|
|
23
23
|
cacheMs: number;
|
|
24
|
+
/**
|
|
25
|
+
* 刷新的总等待预算(毫秒):超预算立刻回上一次成功的额度(stale 标记)。
|
|
26
|
+
*
|
|
27
|
+
* 与 balance 路由同因(issue #104):中转站不可达时(8s 超时 × 重试)响应
|
|
28
|
+
* 会被长期挂住,占着浏览器的同源连接(每源 6 条)——多标签页各挂一条即让
|
|
29
|
+
* 宿主自己的资源请求排队,界面整体卡死。
|
|
30
|
+
*/
|
|
31
|
+
responseBudgetMs: number;
|
|
24
32
|
}
|
|
25
33
|
export declare function registerRelayQuotasRoute(ctx: Context, deps: RelayQuotasDeps): void;
|
|
26
34
|
export {};
|
|
@@ -22,6 +22,14 @@ export interface SubscriptionsDeps {
|
|
|
22
22
|
refreshOnce: () => Promise<void>;
|
|
23
23
|
/** 5 分钟缓存间隔(毫秒)。 */
|
|
24
24
|
cacheMs: number;
|
|
25
|
+
/**
|
|
26
|
+
* 刷新的总等待预算(毫秒):超预算立刻回上一次成功的额度(stale 标记)。
|
|
27
|
+
*
|
|
28
|
+
* 与 balance 路由同因(issue #104):上游额度接口不可达时(8s 超时 × 重试)
|
|
29
|
+
* 响应会被长期挂住,占着浏览器的同源连接(每源 6 条)——多标签页各挂一条
|
|
30
|
+
* 即让宿主自己的资源请求排队,界面整体卡死。
|
|
31
|
+
*/
|
|
32
|
+
responseBudgetMs: number;
|
|
25
33
|
}
|
|
26
34
|
export declare function registerSubscriptionsRoute(ctx: Context, deps: SubscriptionsDeps): void;
|
|
27
35
|
export {};
|
|
@@ -37,6 +37,13 @@ export interface UsageStatsDeps {
|
|
|
37
37
|
packageVersion: string;
|
|
38
38
|
/** 等待预算(毫秒):聚合在此预算内完成就回实时数据,超预算立即回最近快照。 */
|
|
39
39
|
responseBudgetMs: number;
|
|
40
|
+
/**
|
|
41
|
+
* 最近一次**已完成**的聚合文档(只读,不触发新折叠)。
|
|
42
|
+
*
|
|
43
|
+
* 超预算时的第一回落:它比磁盘快照新(磁盘快照受落盘节流影响,最多落后数分钟;
|
|
44
|
+
* 内存文档只落后一个聚合周期)。从未完成过一次聚合时 undefined,继续回落磁盘快照。
|
|
45
|
+
*/
|
|
46
|
+
lastDoc?: () => Record<string, unknown> | undefined;
|
|
40
47
|
}
|
|
41
48
|
/** 校验一份聚合文档;返回漂移原因(null = 形状正常)。纯只读,不改 doc。 */
|
|
42
49
|
export declare function usageStatsShapeError(doc: unknown): string | null;
|
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.7.0",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"deepseek-harness",
|
|
7
7
|
"deepseek",
|
|
@@ -81,7 +81,8 @@
|
|
|
81
81
|
"0.2.1-alpha.4": "compatible",
|
|
82
82
|
"0.2.1-alpha.5": "compatible",
|
|
83
83
|
"0.2.1-rc.1": "compatible",
|
|
84
|
-
"0.2.1-rc.2": "compatible"
|
|
84
|
+
"0.2.1-rc.2": "compatible",
|
|
85
|
+
"0.2.1-rc.3": "compatible"
|
|
85
86
|
}
|
|
86
87
|
}
|
|
87
88
|
},
|
|
@@ -90,6 +91,7 @@
|
|
|
90
91
|
"bundle": "tsdown",
|
|
91
92
|
"watch": "tsdown --watch",
|
|
92
93
|
"lint": "node scripts/lint.mjs && node scripts/check-clientbundle-sync.mjs",
|
|
94
|
+
"size": "node scripts/check-bundle-size.mjs",
|
|
93
95
|
"test": "vitest run",
|
|
94
96
|
"test:e2e": "playwright test",
|
|
95
97
|
"test:e2e:install": "playwright install chromium"
|
|
@@ -110,6 +112,9 @@
|
|
|
110
112
|
"@deepseek-ai/dsh-client-ui-primitives": "*",
|
|
111
113
|
"@deepseek-ai/dsh-client-ui-sidebar": "*",
|
|
112
114
|
"@deepseek-ai/dsh-client-ui-slots": "*",
|
|
115
|
+
"@deepseek-ai/dsh-client-ui-commands": "*",
|
|
116
|
+
"@deepseek-ai/dsh-client-ui-workspace": "*",
|
|
117
|
+
"@deepseek-ai/dsh-token-meter": "*",
|
|
113
118
|
"@deepseek-ai/dsh-credentials": "*",
|
|
114
119
|
"@deepseek-ai/dsh-home-paths": "*",
|
|
115
120
|
"@deepseek-ai/dsh-host-webserver": "*",
|
|
@@ -129,36 +134,39 @@
|
|
|
129
134
|
"@deepseek-ai/cordis": "*",
|
|
130
135
|
"@deepseek-ai/cordis-plugin-include": "^1.0.7",
|
|
131
136
|
"@deepseek-ai/cordis-plugin-loader": "^1.0.5",
|
|
132
|
-
"@deepseek-ai/dsh-agent": "0.2.1-rc.
|
|
133
|
-
"@deepseek-ai/dsh-api-gateway": "0.2.1-rc.
|
|
134
|
-
"@deepseek-ai/dsh-api-remotes": "0.2.1-rc.
|
|
135
|
-
"@deepseek-ai/dsh-api-session-controller": "0.2.1-rc.
|
|
136
|
-
"@deepseek-ai/dsh-atomic-write": "0.2.1-rc.
|
|
137
|
-
"@deepseek-ai/dsh-client-locale": "0.2.1-rc.
|
|
138
|
-
"@deepseek-ai/dsh-client-store": "0.2.1-rc.
|
|
139
|
-
"@deepseek-ai/dsh-client-ui-conversation": "0.2.1-rc.
|
|
140
|
-
"@deepseek-ai/dsh-client-ui-
|
|
141
|
-
"@deepseek-ai/dsh-client-ui-
|
|
142
|
-
"@deepseek-ai/dsh-client-ui-
|
|
143
|
-
"@deepseek-ai/dsh-client-ui-
|
|
144
|
-
"@deepseek-ai/dsh-
|
|
145
|
-
"@deepseek-ai/dsh-
|
|
146
|
-
"@deepseek-ai/dsh-
|
|
137
|
+
"@deepseek-ai/dsh-agent": "0.2.1-rc.3",
|
|
138
|
+
"@deepseek-ai/dsh-api-gateway": "0.2.1-rc.3",
|
|
139
|
+
"@deepseek-ai/dsh-api-remotes": "0.2.1-rc.3",
|
|
140
|
+
"@deepseek-ai/dsh-api-session-controller": "0.2.1-rc.3",
|
|
141
|
+
"@deepseek-ai/dsh-atomic-write": "0.2.1-rc.3",
|
|
142
|
+
"@deepseek-ai/dsh-client-locale": "0.2.1-rc.3",
|
|
143
|
+
"@deepseek-ai/dsh-client-store": "0.2.1-rc.3",
|
|
144
|
+
"@deepseek-ai/dsh-client-ui-conversation": "0.2.1-rc.3",
|
|
145
|
+
"@deepseek-ai/dsh-client-ui-commands": "0.2.1-rc.3",
|
|
146
|
+
"@deepseek-ai/dsh-client-ui-workspace": "0.2.1-rc.3",
|
|
147
|
+
"@deepseek-ai/dsh-client-ui-primitives": "0.2.1-rc.3",
|
|
148
|
+
"@deepseek-ai/dsh-client-ui-renderer": "0.2.1-rc.3",
|
|
149
|
+
"@deepseek-ai/dsh-client-ui-sidebar": "0.2.1-rc.3",
|
|
150
|
+
"@deepseek-ai/dsh-client-ui-slots": "0.2.1-rc.3",
|
|
151
|
+
"@deepseek-ai/dsh-credentials": "0.2.1-rc.3",
|
|
152
|
+
"@deepseek-ai/dsh-home-paths": "0.2.1-rc.3",
|
|
153
|
+
"@deepseek-ai/dsh-host-webserver": "0.2.1-rc.3",
|
|
147
154
|
"@deepseek-ai/dsh-invariants": "0.2.0-rc.2",
|
|
148
|
-
"@deepseek-ai/dsh-llm": "0.2.1-rc.
|
|
149
|
-
"@deepseek-ai/dsh-ptc-runtime": "0.2.1-rc.
|
|
150
|
-
"@deepseek-ai/dsh-sandbox": "0.2.1-rc.
|
|
151
|
-
"@deepseek-ai/dsh-sandbox-policy": "0.2.1-rc.
|
|
152
|
-
"@deepseek-ai/dsh-scope": "0.2.1-rc.
|
|
153
|
-
"@deepseek-ai/dsh-session": "0.2.1-rc.
|
|
154
|
-
"@deepseek-ai/dsh-session-persistence": "0.2.1-rc.
|
|
155
|
-
"@deepseek-ai/dsh-settings": "0.2.1-rc.
|
|
156
|
-
"@deepseek-ai/dsh-system-prompt": "0.2.1-rc.
|
|
157
|
-
"@deepseek-ai/dsh-
|
|
158
|
-
"@deepseek-ai/dsh-
|
|
159
|
-
"@deepseek-ai/dsh-
|
|
160
|
-
"@deepseek-ai/dsh-
|
|
161
|
-
"@deepseek-ai/dsh-util-
|
|
155
|
+
"@deepseek-ai/dsh-llm": "0.2.1-rc.3",
|
|
156
|
+
"@deepseek-ai/dsh-ptc-runtime": "0.2.1-rc.3",
|
|
157
|
+
"@deepseek-ai/dsh-sandbox": "0.2.1-rc.3",
|
|
158
|
+
"@deepseek-ai/dsh-sandbox-policy": "0.2.1-rc.3",
|
|
159
|
+
"@deepseek-ai/dsh-scope": "0.2.1-rc.3",
|
|
160
|
+
"@deepseek-ai/dsh-session": "0.2.1-rc.3",
|
|
161
|
+
"@deepseek-ai/dsh-session-persistence": "0.2.1-rc.3",
|
|
162
|
+
"@deepseek-ai/dsh-settings": "0.2.1-rc.3",
|
|
163
|
+
"@deepseek-ai/dsh-system-prompt": "0.2.1-rc.3",
|
|
164
|
+
"@deepseek-ai/dsh-token-meter": "0.2.1-rc.3",
|
|
165
|
+
"@deepseek-ai/dsh-tools": "0.2.1-rc.3",
|
|
166
|
+
"@deepseek-ai/dsh-typert-protocol": "0.2.1-rc.3",
|
|
167
|
+
"@deepseek-ai/dsh-user-approval": "0.2.1-rc.3",
|
|
168
|
+
"@deepseek-ai/dsh-util-code-language": "0.2.1-rc.3",
|
|
169
|
+
"@deepseek-ai/dsh-util-workspace-path": "0.2.1-rc.3",
|
|
162
170
|
"@deepseek-ai/schemastery": "^3.18.4",
|
|
163
171
|
"@playwright/test": "^1.64.1",
|
|
164
172
|
"@shikijs/langs": "^4.3.1",
|