@linxin666/dsh-usage 0.4.5 → 0.4.7
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.i18n.yaml +2 -2
- package/README.md +2 -2
- package/README.zh.md +2 -2
- package/lib/client.js +45 -38
- package/lib/client.js.map +1 -1
- package/lib/index.js +2 -2
- package/lib/types/client/voucher.d.ts +27 -9
- package/package.json +18 -18
- package/src/client/UsageSectionCard.tsx +10 -10
- package/src/client/locales.ts +4 -4
- package/src/client/settings-entry-form.ts +0 -1
- package/src/client/voucher.ts +33 -11
package/lib/index.js
CHANGED
|
@@ -118,7 +118,7 @@ function mountOnce(packageName, fn) {
|
|
|
118
118
|
return mount;
|
|
119
119
|
}
|
|
120
120
|
//#endregion
|
|
121
|
-
//#region ../../node_modules/.pnpm/@deepseek-ai+dsh-brand@0.2.
|
|
121
|
+
//#region ../../node_modules/.pnpm/@deepseek-ai+dsh-brand@0.2.1-rc.2_@deepseek-ai+cordis@4.0.5/node_modules/@deepseek-ai/dsh-brand/lib/index.js
|
|
122
122
|
/**
|
|
123
123
|
* Duplicate-install-safe nominal primitive helpers.
|
|
124
124
|
*
|
|
@@ -141,7 +141,7 @@ function brandString(value) {
|
|
|
141
141
|
return value;
|
|
142
142
|
}
|
|
143
143
|
//#endregion
|
|
144
|
-
//#region ../../node_modules/.pnpm/@deepseek-ai+dsh-credentials@0.2.
|
|
144
|
+
//#region ../../node_modules/.pnpm/@deepseek-ai+dsh-credentials@0.2.1-rc.2_@deepseek-ai+cordis@4.0.5/node_modules/@deepseek-ai/dsh-credentials/lib/index.js
|
|
145
145
|
/**
|
|
146
146
|
* Service Definition for the credential-reference capability seam (`ctx.credentials`). Settings and composition files carry
|
|
147
147
|
* *references* to secrets — environment-variable names — while providers own
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The Whale-yuan voucher (鲸元券): the
|
|
3
|
-
*
|
|
2
|
+
* The Whale-yuan voucher (鲸元券): the mint family's retained ledger totals
|
|
3
|
+
* stamped onto the banknote artwork as a denomination, ready
|
|
4
4
|
* to save or share. The canvas copy is deliberately locale-neutral (digits,
|
|
5
5
|
* latin captions, ISO dates) so the exported image needs no dictionary;
|
|
6
6
|
* everything user-facing around it lives in the section's locales. The pure
|
|
@@ -11,11 +11,11 @@
|
|
|
11
11
|
import type { UsageWindowSummary } from '../core/types.ts';
|
|
12
12
|
/** The facts stamped onto one voucher. */
|
|
13
13
|
export interface VoucherData {
|
|
14
|
-
/** DeepSeek official
|
|
14
|
+
/** Mint family (DeepSeek official + MiMo) total tokens over the retained window. */
|
|
15
15
|
tokens: number;
|
|
16
16
|
/** Provider calls that reported usage. */
|
|
17
17
|
calls: number;
|
|
18
|
-
/** Fold-time spend estimate in CNY
|
|
18
|
+
/** Fold-time spend estimate in CNY; only the priced family contributes. */
|
|
19
19
|
cost: number;
|
|
20
20
|
/** Retained window bounds (local date keys, inclusive). */
|
|
21
21
|
from: string;
|
|
@@ -28,12 +28,30 @@ export declare function faceValue(tokens: number): number;
|
|
|
28
28
|
/** Local calendar day (`YYYY-MM-DD`) for an epoch ms timestamp. */
|
|
29
29
|
export declare function formatDay(ms: number): string;
|
|
30
30
|
/**
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
31
|
+
* Provider route ids minted beside the DeepSeek official family: the MiMo
|
|
32
|
+
* gateway, which a profile may run as its default route and which the ledger
|
|
33
|
+
* records under its own route id. The bank counts the tokens a profile spends,
|
|
34
|
+
* not only the ones DeepSeek bills. Route ids rather than adapter families
|
|
35
|
+
* because minting is an accounting decision that must never widen the
|
|
36
|
+
* credential or probing paths — the same split `isDeepSeekProviderRoute()`
|
|
37
|
+
* keeps against `adapterFor()` (issue #1772). An empty list mints exactly the
|
|
38
|
+
* official family, which is how a profile that never runs MiMo behaves.
|
|
35
39
|
*/
|
|
36
|
-
export declare
|
|
40
|
+
export declare const EXTRA_MINT_ROUTE_IDS: readonly string[];
|
|
41
|
+
/** Whether one provider route's ledger rows mint whale yuan. */
|
|
42
|
+
export declare function mintsWhaleYuan(provider: string): boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Sum the mint family's rows out of a usage window: the whole DeepSeek
|
|
45
|
+
* official family (the `deepseek` catalog alias, the live `deepseek-official`
|
|
46
|
+
* route and the signed-in `deepseek-account` route all fold into one voucher)
|
|
47
|
+
* plus {@link EXTRA_MINT_ROUTE_IDS}. Undefined when the window is absent
|
|
48
|
+
* (older host) or the family has no usage — a zero-token note mints nothing.
|
|
49
|
+
*
|
|
50
|
+
* Only the priced family contributes `cost`: MiMo ships no price book, so it
|
|
51
|
+
* mints tokens and calls while the spend line keeps reporting the official
|
|
52
|
+
* family's fold-time estimate (and the observed-balance watch above it).
|
|
53
|
+
*/
|
|
54
|
+
export declare function voucherData(window: UsageWindowSummary | undefined): VoucherData | undefined;
|
|
37
55
|
/** Banknote denomination: full digits with thousands separators. */
|
|
38
56
|
export declare function formatDenomination(value: number): string;
|
|
39
57
|
/** Deterministic serial number flavor: the face value mod 1e9, zero-padded. */
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@linxin666/dsh-usage",
|
|
3
3
|
"description": "Usage statistics plugin for the dsh web GUI: per-provider balance and coding-plan quota detection plus a live token usage ledger, with a compact price glance card above the sidebar's Settings row",
|
|
4
|
-
"version": "0.4.
|
|
4
|
+
"version": "0.4.7",
|
|
5
5
|
"icon": "icon.svg",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"engines": {
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"license": "Apache-2.0",
|
|
34
34
|
"dsh": {
|
|
35
35
|
"engines": {
|
|
36
|
-
"dsh": ">=0.2.
|
|
36
|
+
"dsh": ">=0.2.1-rc.2"
|
|
37
37
|
},
|
|
38
38
|
"bundle": {
|
|
39
39
|
"patch": "./cordis.patch.yml"
|
|
@@ -50,25 +50,25 @@
|
|
|
50
50
|
}
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
|
-
"@deepseek-ai/schemastery": "^3.18.
|
|
53
|
+
"@deepseek-ai/schemastery": "^3.18.5"
|
|
54
54
|
},
|
|
55
55
|
"peerDependencies": {
|
|
56
|
-
"@deepseek-ai/dsh": ">=0.2.
|
|
56
|
+
"@deepseek-ai/dsh": ">=0.2.1-rc.2",
|
|
57
57
|
"react": "^18.2.0"
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
|
-
"@deepseek-ai/cordis": "^4.0.
|
|
61
|
-
"@deepseek-ai/dsh-credentials": "^0.2.
|
|
62
|
-
"@deepseek-ai/dsh-client-connection": "^0.2.
|
|
63
|
-
"@deepseek-ai/dsh-client-locale": "^0.2.
|
|
64
|
-
"@deepseek-ai/dsh-client-store": "^0.2.
|
|
65
|
-
"@deepseek-ai/dsh-client-ui-renderer": "^0.2.
|
|
66
|
-
"@deepseek-ai/dsh-client-ui-settings": "^0.2.
|
|
67
|
-
"@deepseek-ai/dsh-client-ui-slots": "^0.2.
|
|
68
|
-
"@deepseek-ai/dsh-host-webserver": "^0.2.
|
|
69
|
-
"@deepseek-ai/dsh-llm": "^0.2.
|
|
70
|
-
"@deepseek-ai/dsh-session": "^0.2.
|
|
71
|
-
"@deepseek-ai/dsh-settings": "^0.2.
|
|
60
|
+
"@deepseek-ai/cordis": "^4.0.5",
|
|
61
|
+
"@deepseek-ai/dsh-credentials": "^0.2.1-rc.2",
|
|
62
|
+
"@deepseek-ai/dsh-client-connection": "^0.2.1-rc.2",
|
|
63
|
+
"@deepseek-ai/dsh-client-locale": "^0.2.1-rc.2",
|
|
64
|
+
"@deepseek-ai/dsh-client-store": "^0.2.1-rc.2",
|
|
65
|
+
"@deepseek-ai/dsh-client-ui-renderer": "^0.2.1-rc.2",
|
|
66
|
+
"@deepseek-ai/dsh-client-ui-settings": "^0.2.1-rc.2",
|
|
67
|
+
"@deepseek-ai/dsh-client-ui-slots": "^0.2.1-rc.2",
|
|
68
|
+
"@deepseek-ai/dsh-host-webserver": "^0.2.1-rc.2",
|
|
69
|
+
"@deepseek-ai/dsh-llm": "^0.2.1-rc.2",
|
|
70
|
+
"@deepseek-ai/dsh-session": "^0.2.1-rc.2",
|
|
71
|
+
"@deepseek-ai/dsh-settings": "^0.2.1-rc.2",
|
|
72
72
|
"@testing-library/dom": "^10.4.1",
|
|
73
73
|
"@testing-library/react": "^16.3.2",
|
|
74
74
|
"@types/node": "^22.20.0",
|
|
@@ -87,9 +87,9 @@
|
|
|
87
87
|
"url": "https://github.com/zhu1090093659/dsh-web.git"
|
|
88
88
|
},
|
|
89
89
|
"scripts": {
|
|
90
|
-
"build": "tsc -
|
|
90
|
+
"build": "tsc -b tsconfig.build.json && tsdown",
|
|
91
91
|
"watch": "tsdown --watch",
|
|
92
92
|
"test": "vitest run",
|
|
93
|
-
"typecheck": "
|
|
93
|
+
"typecheck": "tsgo --noEmit && tsgo -p tsconfig.test.json --pretty false"
|
|
94
94
|
}
|
|
95
95
|
}
|
|
@@ -15,7 +15,7 @@ import { t } from './locales.ts'
|
|
|
15
15
|
import styles from './usage.module.css'
|
|
16
16
|
import { isDeepSeekProviderRoute } from '../core/adapters.ts'
|
|
17
17
|
import { deepseekPeriodAt } from '../core/pricing.ts'
|
|
18
|
-
import {
|
|
18
|
+
import { voucherData, drawVoucher, faceValue, formatDay, formatDenomination, loadVoucherArt } from './voucher.ts'
|
|
19
19
|
import type { ObservedSpendView, ProviderSnapshotView, UsageDayView, UsageOverviewView, UsageProviderSummary, UsageTokenTotals, UsageWindowSummary } from '../core/types.ts'
|
|
20
20
|
|
|
21
21
|
/** The settings fields this section edits (immediate-apply semantics). */
|
|
@@ -550,18 +550,18 @@ function totalOf(totals: UsageTokenTotals): number {
|
|
|
550
550
|
}
|
|
551
551
|
|
|
552
552
|
/**
|
|
553
|
-
* The Token 银行 card: the
|
|
554
|
-
* minted onto the whale-yuan note at 1,000,000 tokens
|
|
555
|
-
* window is the whole retained ledger by default (the
|
|
556
|
-
* falling back to the 30-day trend when an older host serves
|
|
557
|
-
* single day the user picked; the spend line prefers the
|
|
558
|
-
* watch (whole window only) and falls back to the fold-time
|
|
559
|
-
*
|
|
560
|
-
* down.
|
|
553
|
+
* The Token 银行 card: the mint family's (DeepSeek official + MiMo)
|
|
554
|
+
* retained-ledger usage minted onto the whale-yuan note at 1,000,000 tokens
|
|
555
|
+
* per whale yuan. The window is the whole retained ledger by default (the
|
|
556
|
+
* host's aggregate, falling back to the 30-day trend when an older host serves
|
|
557
|
+
* no `all`) or the single day the user picked; the spend line prefers the
|
|
558
|
+
* official balance watch (whole window only) and falls back to the fold-time
|
|
559
|
+
* estimate, which only the priced family feeds; the artwork draw failure
|
|
560
|
+
* degrades to an error line and never takes the section down.
|
|
561
561
|
*/
|
|
562
562
|
function VoucherCard(props: { window?: UsageWindowSummary; observedSpend?: ObservedSpendView; loading?: boolean; error?: string }): ReactNode {
|
|
563
563
|
const { window: ledger, observedSpend, loading, error } = props
|
|
564
|
-
const data =
|
|
564
|
+
const data = voucherData(ledger)
|
|
565
565
|
const canvasRef = useRef<HTMLCanvasElement | null>(null)
|
|
566
566
|
const [drawError, setDrawError] = useState<string | undefined>(undefined)
|
|
567
567
|
const dataKey = data === undefined ? '' : `${data.from}|${data.to}|${data.tokens}|${data.calls}|${data.cost}`
|
package/src/client/locales.ts
CHANGED
|
@@ -57,8 +57,8 @@ export const zh = {
|
|
|
57
57
|
'usage.config.pollIntervalSec': '轮询间隔(秒)',
|
|
58
58
|
'usage.config.saveFailed': '保存失败:设置未被接受。',
|
|
59
59
|
'usage.bank.title': '鲸元券',
|
|
60
|
-
'usage.bank.hint': '官方 API 每消耗 100 万 tokens 铸造 1 鲸元;保存或分享这张票券。',
|
|
61
|
-
'usage.bank.noUsage': '暂无 DeepSeek
|
|
60
|
+
'usage.bank.hint': 'DeepSeek 官方 API 与 MiMo 每消耗 100 万 tokens 铸造 1 鲸元;保存或分享这张票券。',
|
|
61
|
+
'usage.bank.noUsage': '暂无 DeepSeek 官方 / MiMo 用量数据(统计自插件启用起)',
|
|
62
62
|
'usage.bank.minted': '累计铸造 {minted} 鲸元({tokens} tokens)',
|
|
63
63
|
'usage.bank.spend.observed': '官方余额实测花费 ¥{cost}(自 {since} 起)',
|
|
64
64
|
'usage.bank.spend.estimated': '消费估算:约 ¥{cost}',
|
|
@@ -124,8 +124,8 @@ export const en: Record<UsageKey, string> = {
|
|
|
124
124
|
'usage.config.pollIntervalSec': 'Poll interval (seconds)',
|
|
125
125
|
'usage.config.saveFailed': 'Save failed: the deployment did not accept the setting.',
|
|
126
126
|
'usage.bank.title': 'Whale-yuan voucher',
|
|
127
|
-
'usage.bank.hint': 'Every 1,000,000 tokens spent on the official API mint one whale yuan; save or share the note.',
|
|
128
|
-
'usage.bank.noUsage': 'No official
|
|
127
|
+
'usage.bank.hint': 'Every 1,000,000 tokens spent on the DeepSeek official API or on MiMo mint one whale yuan; save or share the note.',
|
|
128
|
+
'usage.bank.noUsage': 'No DeepSeek official or MiMo usage yet (counting starts when the plugin is enabled)',
|
|
129
129
|
'usage.bank.minted': 'Minted {minted} whale yuan ({tokens} tokens)',
|
|
130
130
|
'usage.bank.spend.observed': 'Spent ¥{cost} observed on the official balance (watching since {since})',
|
|
131
131
|
'usage.bank.spend.estimated': 'Estimated spend: about ¥{cost}',
|
package/src/client/voucher.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The Whale-yuan voucher (鲸元券): the
|
|
3
|
-
*
|
|
2
|
+
* The Whale-yuan voucher (鲸元券): the mint family's retained ledger totals
|
|
3
|
+
* stamped onto the banknote artwork as a denomination, ready
|
|
4
4
|
* to save or share. The canvas copy is deliberately locale-neutral (digits,
|
|
5
5
|
* latin captions, ISO dates) so the exported image needs no dictionary;
|
|
6
6
|
* everything user-facing around it lives in the section's locales. The pure
|
|
@@ -16,11 +16,11 @@ import { VOUCHER_ART_DATA_URL } from './voucher-art.generated.ts'
|
|
|
16
16
|
|
|
17
17
|
/** The facts stamped onto one voucher. */
|
|
18
18
|
export interface VoucherData {
|
|
19
|
-
/** DeepSeek official
|
|
19
|
+
/** Mint family (DeepSeek official + MiMo) total tokens over the retained window. */
|
|
20
20
|
tokens: number
|
|
21
21
|
/** Provider calls that reported usage. */
|
|
22
22
|
calls: number
|
|
23
|
-
/** Fold-time spend estimate in CNY
|
|
23
|
+
/** Fold-time spend estimate in CNY; only the priced family contributes. */
|
|
24
24
|
cost: number
|
|
25
25
|
/** Retained window bounds (local date keys, inclusive). */
|
|
26
26
|
from: string
|
|
@@ -44,21 +44,43 @@ export function formatDay(ms: number): string {
|
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
/**
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
47
|
+
* Provider route ids minted beside the DeepSeek official family: the MiMo
|
|
48
|
+
* gateway, which a profile may run as its default route and which the ledger
|
|
49
|
+
* records under its own route id. The bank counts the tokens a profile spends,
|
|
50
|
+
* not only the ones DeepSeek bills. Route ids rather than adapter families
|
|
51
|
+
* because minting is an accounting decision that must never widen the
|
|
52
|
+
* credential or probing paths — the same split `isDeepSeekProviderRoute()`
|
|
53
|
+
* keeps against `adapterFor()` (issue #1772). An empty list mints exactly the
|
|
54
|
+
* official family, which is how a profile that never runs MiMo behaves.
|
|
51
55
|
*/
|
|
52
|
-
export
|
|
56
|
+
export const EXTRA_MINT_ROUTE_IDS: readonly string[] = ['mimo']
|
|
57
|
+
|
|
58
|
+
/** Whether one provider route's ledger rows mint whale yuan. */
|
|
59
|
+
export function mintsWhaleYuan(provider: string): boolean {
|
|
60
|
+
return isDeepSeekProviderRoute(provider) || EXTRA_MINT_ROUTE_IDS.includes(provider)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Sum the mint family's rows out of a usage window: the whole DeepSeek
|
|
65
|
+
* official family (the `deepseek` catalog alias, the live `deepseek-official`
|
|
66
|
+
* route and the signed-in `deepseek-account` route all fold into one voucher)
|
|
67
|
+
* plus {@link EXTRA_MINT_ROUTE_IDS}. Undefined when the window is absent
|
|
68
|
+
* (older host) or the family has no usage — a zero-token note mints nothing.
|
|
69
|
+
*
|
|
70
|
+
* Only the priced family contributes `cost`: MiMo ships no price book, so it
|
|
71
|
+
* mints tokens and calls while the spend line keeps reporting the official
|
|
72
|
+
* family's fold-time estimate (and the observed-balance watch above it).
|
|
73
|
+
*/
|
|
74
|
+
export function voucherData(window: UsageWindowSummary | undefined): VoucherData | undefined {
|
|
53
75
|
if (window === undefined) return undefined
|
|
54
76
|
let tokens = 0
|
|
55
77
|
let calls = 0
|
|
56
78
|
let cost = 0
|
|
57
79
|
for (const row of window.providers) {
|
|
58
|
-
if (!
|
|
80
|
+
if (!mintsWhaleYuan(row.provider)) continue
|
|
59
81
|
tokens += totalTokens(row.totals)
|
|
60
82
|
calls += row.totals.calls
|
|
61
|
-
cost += row.totals.cost
|
|
83
|
+
if (isDeepSeekProviderRoute(row.provider)) cost += row.totals.cost
|
|
62
84
|
}
|
|
63
85
|
if (tokens <= 0) return undefined
|
|
64
86
|
return { tokens, calls, cost, from: window.from, to: window.to }
|