@kenz1117/dsh-ui-usage-billing 0.4.2 → 0.6.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.md +20 -14
- package/lib/client.js +1614 -1026
- package/lib/index.js +250 -13
- package/lib/types/aggregate.d.ts +28 -0
- package/lib/types/client/TrendChart.d.ts +4 -1
- package/lib/types/client/UsageBilling.d.ts +52 -4
- package/lib/types/client/anomaly.d.ts +52 -0
- package/lib/types/client/budget-store.d.ts +3 -3
- package/lib/types/client/export.d.ts +33 -0
- package/lib/types/client/heatmap.d.ts +35 -0
- package/lib/types/client/live-cost.d.ts +55 -0
- package/lib/types/client/locales.d.ts +1 -1
- package/lib/types/client/pricing.d.ts +5 -0
- package/lib/types/client/round-chart.d.ts +37 -0
- package/lib/types/index.d.ts +2 -1
- package/package.json +3 -1
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LiveCostBar: the session-scope cost ticker mounted on the composer's dock,
|
|
3
|
+
* showing the current session's accumulated spend and the latest turn's cost.
|
|
4
|
+
*
|
|
5
|
+
* It rides `conversation.composer.dock` (the stats-line family seat under the
|
|
6
|
+
* composer card, same posture as ui-conversation's own StatsLine), so it stays
|
|
7
|
+
* visible while working without opening the full dashboard. Data comes from the
|
|
8
|
+
* same `/api/billing/usage-stats` endpoint the dashboard polls; the bar reads
|
|
9
|
+
* the current session id off the framework snapshot (`useSession` parent of
|
|
10
|
+
* `sessionId`) and matches `bySession` (session total) and `byTurn` (latest
|
|
11
|
+
* turn cost). Rendering is a pure function of the snapshot, never a side effect.
|
|
12
|
+
*/
|
|
13
|
+
import type { SnapshotSelectorHook } from '@deepseek-ai/dsh-client-ui-slots';
|
|
14
|
+
import type { ConversationSnapshot } from '@deepseek-ai/dsh-client-runtime/client';
|
|
15
|
+
/** The usage-stats shape the composer bar needs (a thin slice, not the whole doc). */
|
|
16
|
+
export interface LiveStats {
|
|
17
|
+
bySession?: readonly {
|
|
18
|
+
id: string;
|
|
19
|
+
cost: number;
|
|
20
|
+
}[];
|
|
21
|
+
byTurn?: readonly {
|
|
22
|
+
sessionId: string;
|
|
23
|
+
turn: number;
|
|
24
|
+
cost: number;
|
|
25
|
+
}[];
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* 当前会话累计费用:bySession 里会话 id 匹配的那行;缺省为 0。
|
|
29
|
+
* 导出供测试:纯函数。
|
|
30
|
+
* @param stats - 薄统计切片。
|
|
31
|
+
* @param sessionId - 当前会话 id。
|
|
32
|
+
* @returns 该会话累计费用(人民币元)。
|
|
33
|
+
*/
|
|
34
|
+
export declare function sessionCostOf(stats: LiveStats | null, sessionId: string | undefined): number;
|
|
35
|
+
/**
|
|
36
|
+
* 当前轮费用:byTurn 里该会话最新一轮的 cost;缺省为 0。
|
|
37
|
+
* byTurn 服务端按起始时间倒序下发,但求 max(turn) 更稳健(不依赖顺序)。
|
|
38
|
+
* 导出供测试:纯函数。
|
|
39
|
+
* @param stats - 薄统计切片。
|
|
40
|
+
* @param sessionId - 当前会话 id。
|
|
41
|
+
* @returns 最新一轮费用(人民币元)。
|
|
42
|
+
*/
|
|
43
|
+
export declare function turnCostOf(stats: LiveStats | null, sessionId: string | undefined): number;
|
|
44
|
+
/** Props: the session-scope snapshot selector the framework injects. */
|
|
45
|
+
export interface LiveCostBarProps {
|
|
46
|
+
useSession: SnapshotSelectorHook<ConversationSnapshot>;
|
|
47
|
+
/** The owning dock's locale seat (bound to the billing NS). */
|
|
48
|
+
t: (key: 'billing.liveTurn' | 'billing.liveSession') => string;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Render the live cost ticker for the current session.
|
|
52
|
+
* @param props - framework session snapshot hook and locale.
|
|
53
|
+
*/
|
|
54
|
+
export declare function LiveCostBar({ useSession, t }: LiveCostBarProps): React.ReactNode;
|
|
55
|
+
//# sourceMappingURL=live-cost.d.ts.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Locale dictionaries for the usage billing surface. */
|
|
2
|
-
export type UsageBillingKey = 'billing.title' | 'billing.subtitle' | 'billing.cost' | 'billing.todayCost' | 'billing.monthCost' | 'billing.yearCost' | 'billing.totalCost' | 'billing.calls' | 'billing.cacheHitRate' | 'billing.tokens' | 'billing.inputTokens' | 'billing.outputTokens' | 'billing.avgCost' | 'billing.trend' | 'billing.trend7d' | 'billing.trend30d' | 'billing.trendEmpty' | 'billing.budget' | 'billing.sessions' | 'billing.project' | 'billing.lastActive' | 'billing.sessionOverflow' | 'billing.
|
|
2
|
+
export type UsageBillingKey = 'billing.title' | 'billing.subtitle' | 'billing.cost' | 'billing.todayCost' | 'billing.monthCost' | 'billing.yearCost' | 'billing.monthProjected' | 'billing.liveTurn' | 'billing.liveSession' | 'billing.totalCost' | 'billing.calls' | 'billing.cacheHitRate' | 'billing.tokens' | 'billing.inputTokens' | 'billing.outputTokens' | 'billing.avgCost' | 'billing.trend' | 'billing.trend7d' | 'billing.trend30d' | 'billing.trendEmpty' | 'billing.budget' | 'billing.sessions' | 'billing.project' | 'billing.lastActive' | 'billing.sessionOverflow' | 'billing.budgetTierBody' | 'billing.models' | 'billing.providerBilling' | 'billing.estimated' | 'billing.actual' | 'billing.pricing' | 'billing.showPricing' | 'billing.hidePricing' | 'billing.pricePerM' | 'billing.input' | 'billing.output' | 'billing.cacheHit' | 'billing.peak' | 'billing.offPeak' | 'billing.flat' | 'billing.peakHours' | 'billing.band' | 'billing.openDashboard' | 'billing.close' | 'billing.lastUpdated' | 'billing.noData' | 'billing.todayRate' | 'billing.rateLive' | 'billing.rateBuiltin' | 'billing.balance' | 'billing.balanceUnconfigured' | 'billing.balanceUnauthorized' | 'billing.balanceUnreachable' | 'billing.uncatalogued' | 'billing.estimatedPricing' | 'billing.balanceDays' | 'billing.balanceLowBody' | 'billing.subscriptions' | 'billing.subscriptionNotConfigured' | 'billing.subscriptionUnauthorized' | 'billing.subscriptionUnavailable' | 'billing.subscriptionInvalid' | 'billing.subscriptionRateLimited' | 'billing.subscriptionSession' | 'billing.subscriptionWeekly' | 'billing.subscriptionMonthly' | 'billing.subscriptionBilling' | 'billing.subscriptionRemaining' | 'billing.subscriptionReset' | 'billing.subscriptionNoApi' | 'billing.heatmapLess' | 'billing.heatmapMore' | 'billing.currency' | 'billing.currencyCny' | 'billing.currencyUsd' | 'billing.heatmap' | 'billing.rounds' | 'billing.anomaly' | 'billing.workspaces' | 'billing.plan' | 'billing.remaining' | 'billing.unknownModel' | 'billing.model' | 'billing.currentRound' | 'billing.costAbbr' | 'billing.tabOverview' | 'billing.tabTrends' | 'billing.tabProviders' | 'billing.tabDetails' | 'billing.tabPricing' | 'billing.export' | 'billing.exportCsvDay' | 'billing.exportCsvSession' | 'billing.exportJson' | 'billing.peakShare' | 'billing.peakShareHint' | 'billing.weekCost' | 'billing.roleCost' | 'billing.roleUser' | 'billing.roleAssistant' | 'billing.roleTool' | 'billing.roleHint';
|
|
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>;
|
|
@@ -95,6 +95,11 @@ export interface ModelEntry {
|
|
|
95
95
|
price: ModelPrice;
|
|
96
96
|
/** Peak-hour window label for time-of-day priced models. */
|
|
97
97
|
peakHours?: string;
|
|
98
|
+
/**
|
|
99
|
+
* 单价为估算价:厂商未公布按量官方单价(公测 / 套餐制),表内价格为估算,
|
|
100
|
+
* 展示时标注以免误当正式定价;正式定价公布后移除。
|
|
101
|
+
*/
|
|
102
|
+
estimated?: boolean;
|
|
98
103
|
}
|
|
99
104
|
/**
|
|
100
105
|
* Built-in catalog of current mainstream models as of 2026-08-16, priced from
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RoundCostChart: dependency-free per-turn cost bars with spike markers.
|
|
3
|
+
*
|
|
4
|
+
* One bar per turn (most recent N, newest last), height scaled to the window
|
|
5
|
+
* maximum. Turns flagged by {@link flagAnomalies} get a warning outline and a
|
|
6
|
+
* corner marker; hover shows the turn's model, cost, and window time. Styling
|
|
7
|
+
* lives in the billing CSS module (`.rounds*`).
|
|
8
|
+
*/
|
|
9
|
+
import type { AnomalyFlag } from './anomaly.ts';
|
|
10
|
+
import { type CostCurrency } from './pricing.ts';
|
|
11
|
+
/** 每轮费用图的一行(TurnUsageRow 的展示子集)。 */
|
|
12
|
+
export interface RoundChartRow {
|
|
13
|
+
sessionId: string;
|
|
14
|
+
turn: number;
|
|
15
|
+
model: string;
|
|
16
|
+
cost: number;
|
|
17
|
+
input: number;
|
|
18
|
+
output: number;
|
|
19
|
+
cacheHit: number;
|
|
20
|
+
cacheMiss: number;
|
|
21
|
+
startedAt: number;
|
|
22
|
+
endedAt?: number;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Render the per-turn cost bars.
|
|
26
|
+
* @param props.rounds - turns, most recent last (ascending startedAt); oldest beyond the limit are dropped.
|
|
27
|
+
* @param props.flags - spike flags matched by sessionId+turn.
|
|
28
|
+
* @param props.currency - display currency for the amount labels.
|
|
29
|
+
* @param props.t - locale function for the model label.
|
|
30
|
+
*/
|
|
31
|
+
export declare function RoundCostChart({ rounds, flags, currency, t }: {
|
|
32
|
+
rounds: readonly RoundChartRow[];
|
|
33
|
+
flags: readonly AnomalyFlag[];
|
|
34
|
+
currency: CostCurrency;
|
|
35
|
+
t: (key: 'billing.model' | 'billing.costAbbr') => string;
|
|
36
|
+
}): React.ReactNode;
|
|
37
|
+
//# sourceMappingURL=round-chart.d.ts.map
|
package/lib/types/index.d.ts
CHANGED
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
import type { Context } from '@deepseek-ai/cordis';
|
|
13
13
|
import type { CredentialProvider } from '@deepseek-ai/dsh-credentials';
|
|
14
14
|
import type { SettingsProvider } from '@deepseek-ai/dsh-settings';
|
|
15
|
-
import
|
|
15
|
+
import type { SubscriptionPlanConfig } from './pricing-shared.ts';
|
|
16
|
+
import { type IdentifiedSubscriptionPlan, type SubscriptionKeys } from './subscriptions.ts';
|
|
16
17
|
/** Plugin configuration. */
|
|
17
18
|
export interface UsageBillingConfig {
|
|
18
19
|
/** Absolute path to a `.dsh-usage-stats.json` fallback file. */
|
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": "0.
|
|
4
|
+
"version": "0.6.0",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -48,6 +48,7 @@
|
|
|
48
48
|
"license": "MIT",
|
|
49
49
|
"peerDependencies": {
|
|
50
50
|
"@deepseek-ai/dsh-api-remotes": "*",
|
|
51
|
+
"@deepseek-ai/dsh-atomic-write": "*",
|
|
51
52
|
"@deepseek-ai/dsh-client-connection": "*",
|
|
52
53
|
"@deepseek-ai/dsh-host-webserver": "*",
|
|
53
54
|
"@deepseek-ai/dsh-client-locale": "*",
|
|
@@ -62,6 +63,7 @@
|
|
|
62
63
|
"@deepseek-ai/dsh-session": "*",
|
|
63
64
|
"@deepseek-ai/dsh-session-persistence": "*",
|
|
64
65
|
"@deepseek-ai/dsh-settings": "*",
|
|
66
|
+
"@deepseek-ai/dsh-tools": "*",
|
|
65
67
|
"@deepseek-ai/schemastery": "*",
|
|
66
68
|
"@deepseek-ai/cordis": "*",
|
|
67
69
|
"react": "^18.2.0"
|