@gamegeek-saikel/dsh-cost-meter 0.1.0 → 0.1.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.md +2 -2
- package/README.zh-CN.md +2 -2
- package/lib/client.js +110 -84
- package/lib/client.js.map +1 -1
- package/lib/index.js +96 -21
- package/lib/types/client/AssistantCostChip.d.ts.map +1 -1
- package/lib/types/client/AssistantCostChip.js +7 -3
- package/lib/types/client/CostView.d.ts.map +1 -1
- package/lib/types/client/CostView.js +8 -3
- package/lib/types/client/SessionCostLine.d.ts.map +1 -1
- package/lib/types/client/SessionCostLine.js +3 -2
- package/lib/types/client/SessionCostPill.d.ts.map +1 -1
- package/lib/types/client/SessionCostPill.js +11 -5
- package/lib/types/client/cost-math.d.ts +12 -4
- package/lib/types/client/cost-math.d.ts.map +1 -1
- package/lib/types/client/cost-math.js +14 -6
- package/lib/types/index.d.ts +1 -1
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/pricebook.d.ts +12 -5
- package/lib/types/pricebook.d.ts.map +1 -1
- package/lib/types/pricebook.js +23 -10
- package/lib/types/pricing.d.ts +33 -6
- package/lib/types/pricing.d.ts.map +1 -1
- package/lib/types/pricing.js +77 -14
- package/lib/types/types.d.ts +20 -2
- package/lib/types/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/client/AssistantCostChip.tsx +7 -3
- package/src/client/CostView.tsx +8 -3
- package/src/client/SessionCostLine.tsx +3 -2
- package/src/client/SessionCostPill.tsx +11 -5
- package/src/client/cost-math.ts +15 -5
- package/src/css-modules.d.ts +4 -4
- package/src/invariant.ts +46 -46
- package/src/pricebook.ts +30 -9
- package/src/pricing.ts +81 -13
- package/src/types.ts +22 -2
package/README.md
CHANGED
|
@@ -43,7 +43,7 @@ Chat costs in DeepSeek pricing change over time (list prices, USD→CNY exchange
|
|
|
43
43
|
|---|---|
|
|
44
44
|
| Cost anchoring | Append-only pricebook snapshots; step cost computed once at the event's own time |
|
|
45
45
|
| Price sources | Manual override > official pricing page > built-in fallback > OpenRouter (fallback only, USD→CNY) > none |
|
|
46
|
-
| Peak pricing | 2026-08-17 00:00 Beijing rollout; peak 09:00–12:00 / 14:00–18:00 Beijing, off-peak half price |
|
|
46
|
+
| Peak pricing | 2026-08-17 00:00 Beijing rollout; peak/off-peak windows parsed from each page's own schedule (the zh and en pages may differ; fallback 09:00–12:00 / 14:00–18:00 Beijing), off-peak half price |
|
|
47
47
|
| Cost formula | Uncached input + cache reads (hit rate) + cache writes (billed at uncached input rate) + output, per 1M tokens, CNY |
|
|
48
48
|
| Account balance | Official `GET /user/balance`, cached 60 s, single in-flight request, trust-fenced route |
|
|
49
49
|
| Subagent support | BFS over the live agent tree; conversation totals = main session + descendants |
|
|
@@ -71,7 +71,7 @@ The pricebook (`src/pricebook.ts`) is the durable price source, persisted on the
|
|
|
71
71
|
|
|
72
72
|
- **Priority chain** — per canonical model key (`provider/model`, bare model, or the `flash`/`pro` pricing key for DeepSeek-family models): manual override > official page > built-in fallback > OpenRouter (fallback only, USD→CNY, cache reads at the configured discount) > none.
|
|
73
73
|
- **Snapshot selection** — `snapshotForTime` picks the newest snapshot with `effectiveAt <= event time` (pre-install sessions anchor to the first snapshot once).
|
|
74
|
-
- **Peak/off-peak** — before the 2026-08-17 rollout all steps price at the single list price; after it, the band is chosen by
|
|
74
|
+
- **Peak/off-peak** — before the 2026-08-17 rollout all steps price at the single list price; after it, the band is chosen by the EVENT's own time against the schedule of the pricebook's own page (the zh and en pages each parse their own peak windows, falling back to Beijing 09:00–12:00 / 14:00–18:00, everything else off-peak). Each step's band is anchored once at fold time, so the per-reply cards and chips always show the band that round was billed at — never the band of the moment you are looking.
|
|
75
75
|
- **Immutable ledger** — the `sessionCost` projection (`src/session-cost-projection.ts`) folds `request/header` (model) and usage-carrying events into per-step rows; a second usage sample for the same (turn, step) replaces the first (same-step finalization, not a re-price), with O(1) incremental totals.
|
|
76
76
|
|
|
77
77
|
## Project Structure
|
package/README.zh-CN.md
CHANGED
|
@@ -43,7 +43,7 @@ DeepSeek 的价格随时间变化(官方价目表、USD→CNY 汇率、以及
|
|
|
43
43
|
|---|---|
|
|
44
44
|
| 成本锚定 | 只追加价格簿快照;步成本在事件自身时刻只计算一次 |
|
|
45
45
|
| 价格来源 | 手动覆盖 > 官方价格页 > 内置回退 > OpenRouter(仅回退,USD→CNY)> 无 |
|
|
46
|
-
| 峰值定价 | 2026-08-17 00:00
|
|
46
|
+
| 峰值定价 | 2026-08-17 00:00 北京生效;高峰/闲时窗口按各页面自己的时段表解析(中英文页面可能不同,缺省 09:00–12:00 / 14:00–18:00 北京),闲时为半价 |
|
|
47
47
|
| 成本公式 | 未命中输入 + 缓存命中(命中价)+ 缓存写入(按未命中输入价计)+ 输出,每百万 tokens,CNY |
|
|
48
48
|
| 账户余额 | 官方 `GET /user/balance`,缓存 60 秒,单飞请求,路由带信任围栏 |
|
|
49
49
|
| 子代理支持 | 沿活跃代理树 BFS;对话总花费 = 主会话 + 全部后代 |
|
|
@@ -71,7 +71,7 @@ DeepSeek 的价格随时间变化(官方价目表、USD→CNY 汇率、以及
|
|
|
71
71
|
|
|
72
72
|
- **优先级链**——按规范模型键(`provider/model`、裸模型名,或 DeepSeek 系模型的 `flash`/`pro` 定价键):手动覆盖 > 官方页面 > 内置回退 > OpenRouter(仅回退,USD→CNY,缓存读按配置折扣)> 无。
|
|
73
73
|
- **快照选取**——`snapshotForTime` 取 `effectiveAt <= 事件时间` 的最新快照(安装前的会话一次性锚到首个快照)。
|
|
74
|
-
- **峰值/闲时**——2026-08-17
|
|
74
|
+
- **峰值/闲时**——2026-08-17 上线前所有步按单一价目计费;上线后按事件自身时刻与该价格簿页面的时段表选档(中英文页面各自解析自己的高峰窗口,抓取失败时回退到北京 09:00–12:00 / 14:00–18:00,其余闲时)。每步的档位在折叠时锚定一次,逐回复卡片与回复小标签永远显示该轮对话当时被计价的档位,而不是查看时刻的档位。
|
|
75
75
|
- **不可变账本**——`sessionCost` 投影(`src/session-cost-projection.ts`)把 `request/header`(模型)与携带用量的事件折叠为逐步记录;同一 (turn, step) 的第二次用量样本**替换**第一条(同一步终结,而非重新计价),总计以 O(1) 增量维护。
|
|
76
76
|
|
|
77
77
|
## 项目结构
|
package/lib/client.js
CHANGED
|
@@ -155,6 +155,14 @@ window.__ModuleLoader__.load({
|
|
|
155
155
|
//#region src/pricing.ts
|
|
156
156
|
/** Official peak-pricing rollout: 2026-08-17 00:00 Beijing time (UTC+8). */
|
|
157
157
|
const PEAK_PRICING_START_MS = Date.UTC(2026, 7, 16, 16, 0, 0);
|
|
158
|
+
/**
|
|
159
|
+
* Built-in fallback zh peak schedule: the official announcement's windows in
|
|
160
|
+
* Beijing time (peak 09:00-12:00 / 14:00-18:00, everything else off-peak).
|
|
161
|
+
*/
|
|
162
|
+
const PEAK_SCHEDULE_ZH = {
|
|
163
|
+
timezone: "Asia/Shanghai",
|
|
164
|
+
ranges: [[9, 12], [14, 18]]
|
|
165
|
+
};
|
|
158
166
|
/** Built-in fallback USD prices from the English pricing page. */
|
|
159
167
|
const FALLBACK_CURRENT_USD = {
|
|
160
168
|
flash: {
|
|
@@ -170,20 +178,22 @@ window.__ModuleLoader__.load({
|
|
|
170
178
|
};
|
|
171
179
|
({ ...FALLBACK_CURRENT_USD.flash }), { ...FALLBACK_CURRENT_USD.pro };
|
|
172
180
|
/**
|
|
173
|
-
* Whether the
|
|
174
|
-
* 09:00-12:00 and 14:00-18:00
|
|
181
|
+
* Whether the given instant is a peak-pricing hour under one schedule: the
|
|
182
|
+
* zh fallback is Beijing time 09:00-12:00 and 14:00-18:00; each pricebook
|
|
183
|
+
* passes the schedule parsed from its own (zh or en) pricing page.
|
|
175
184
|
* @param now - the instant to classify.
|
|
185
|
+
* @param schedule - the peak-hour schedule to classify against.
|
|
176
186
|
* @returns true during peak hours.
|
|
177
187
|
*/
|
|
178
|
-
function isPeakHour(now = /* @__PURE__ */ new Date()) {
|
|
188
|
+
function isPeakHour(now = /* @__PURE__ */ new Date(), schedule = PEAK_SCHEDULE_ZH) {
|
|
179
189
|
const parts = new Intl.DateTimeFormat("en-US", {
|
|
180
|
-
timeZone:
|
|
190
|
+
timeZone: schedule.timezone,
|
|
181
191
|
hour: "numeric",
|
|
182
192
|
hour12: false
|
|
183
193
|
}).formatToParts(now);
|
|
184
194
|
const hour = Number(parts.find((part) => part.type === "hour")?.value);
|
|
185
195
|
if (Number.isNaN(hour)) return false;
|
|
186
|
-
return
|
|
196
|
+
return schedule.ranges.some(([start, end]) => hour >= start && hour < end);
|
|
187
197
|
}
|
|
188
198
|
//#endregion
|
|
189
199
|
//#region src/client/cost-math.ts
|
|
@@ -238,10 +248,18 @@ window.__ModuleLoader__.load({
|
|
|
238
248
|
if (subagents === void 0 || subagents.length === 0) return main;
|
|
239
249
|
return sumTotals([main, ...subagents.map((entry) => entry.totals)]);
|
|
240
250
|
}
|
|
241
|
-
/**
|
|
242
|
-
|
|
251
|
+
/**
|
|
252
|
+
* The price band in effect at one instant (mirror of the host helper). The
|
|
253
|
+
* schedule defaults to the zh fallback; live readouts pass the schedule of
|
|
254
|
+
* the pricebook they display (the zh and en pages may state different
|
|
255
|
+
* windows).
|
|
256
|
+
* @param time - epoch millis.
|
|
257
|
+
* @param schedule - the peak-hour schedule to classify against.
|
|
258
|
+
* @returns the band.
|
|
259
|
+
*/
|
|
260
|
+
function bandForTime(time, schedule = PEAK_SCHEDULE_ZH) {
|
|
243
261
|
if (time < PEAK_PRICING_START_MS) return "single";
|
|
244
|
-
return isPeakHour(new Date(time)) ? "peak" : "offPeak";
|
|
262
|
+
return isPeakHour(new Date(time), schedule) ? "peak" : "offPeak";
|
|
245
263
|
}
|
|
246
264
|
/** The bucket of one model's entry for one band (mirror of the host helper). */
|
|
247
265
|
function bucketOf(modelPrice, band) {
|
|
@@ -270,10 +288,10 @@ window.__ModuleLoader__.load({
|
|
|
270
288
|
}
|
|
271
289
|
}
|
|
272
290
|
/** Resolve one model's bucket at one instant from a snapshot. */
|
|
273
|
-
function bucketAt(snapshot, provider, model, time) {
|
|
291
|
+
function bucketAt(snapshot, provider, model, time, schedule = PEAK_SCHEDULE_ZH) {
|
|
274
292
|
const entry = modelPriceOf(snapshot, provider, model);
|
|
275
293
|
if (entry === void 0) return void 0;
|
|
276
|
-
return bucketOf(entry, bandForTime(time));
|
|
294
|
+
return bucketOf(entry, bandForTime(time, schedule));
|
|
277
295
|
}
|
|
278
296
|
/**
|
|
279
297
|
* The peak-to-off-peak price multiplier for one model's entry, when the
|
|
@@ -400,8 +418,8 @@ window.__ModuleLoader__.load({
|
|
|
400
418
|
return `${multiplier.toFixed(1)}×`;
|
|
401
419
|
}
|
|
402
420
|
//#endregion
|
|
403
|
-
//#region \0dsh-css
|
|
404
|
-
const css$4 = ".
|
|
421
|
+
//#region \0dsh-css:/home/runner/work/dsh-cost-meter/dsh-cost-meter/src/client/SessionCostLine.module.css.mjs
|
|
422
|
+
const css$4 = "._09e0Yq_root{text-align:center;max-width:var(--dsh-chat-content-width);box-sizing:border-box;width:100%;padding:0 calc(var(--dsh-composer-side-clearance) + 16px) 4px;color:var(--dsw-alias-label-tertiary);white-space:nowrap;text-overflow:ellipsis;margin:0 auto;font-size:12px;line-height:20px;display:block;overflow:hidden}";
|
|
405
423
|
const tagId$4 = "@gamegeek-saikel/dsh-cost-meter/SessionCostLine.module.css";
|
|
406
424
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$4) + "]") === null) {
|
|
407
425
|
const tag = document.createElement("style");
|
|
@@ -410,7 +428,7 @@ window.__ModuleLoader__.load({
|
|
|
410
428
|
tag.textContent = css$4;
|
|
411
429
|
document.head.appendChild(tag);
|
|
412
430
|
}
|
|
413
|
-
var SessionCostLine_module_css_default = { "root": "
|
|
431
|
+
var SessionCostLine_module_css_default = { "root": "_09e0Yq_root" };
|
|
414
432
|
//#endregion
|
|
415
433
|
//#region src/client/SessionCostLine.tsx
|
|
416
434
|
/**
|
|
@@ -465,7 +483,9 @@ window.__ModuleLoader__.load({
|
|
|
465
483
|
}
|
|
466
484
|
const SessionCostLine = (0, react.memo)(function SessionCostLine({ useProjection, sessionId, t }) {
|
|
467
485
|
const currency = displayCurrency(t);
|
|
468
|
-
const
|
|
486
|
+
const costCny = useProjection("sessionCost");
|
|
487
|
+
const costUsd = useProjection("sessionCostUsd");
|
|
488
|
+
const cost = currency === "USD" ? costUsd : costCny;
|
|
469
489
|
const [response, setResponse] = (0, react.useState)(null);
|
|
470
490
|
const [failed, setFailed] = (0, react.useState)(false);
|
|
471
491
|
(0, react.useEffect)(() => {
|
|
@@ -555,8 +575,8 @@ window.__ModuleLoader__.load({
|
|
|
555
575
|
});
|
|
556
576
|
});
|
|
557
577
|
//#endregion
|
|
558
|
-
//#region \0dsh-css
|
|
559
|
-
const css$3 = ".
|
|
578
|
+
//#region \0dsh-css:/home/runner/work/dsh-cost-meter/dsh-cost-meter/src/client/CostView.module.css.mjs
|
|
579
|
+
const css$3 = ".fZF-xq_root{max-width:var(--dsh-chat-content-width);box-sizing:border-box;width:100%;color:var(--dsw-alias-label-primary);flex-direction:column;gap:16px;margin:0 auto;padding:16px 24px;font-size:13px;line-height:20px;display:flex}.fZF-xq_summary{flex-direction:column;gap:8px;display:flex}.fZF-xq_totalRow{justify-content:space-between;align-items:baseline;display:flex}.fZF-xq_totalLabel{font-size:15px;font-weight:600}.fZF-xq_totalValue{font-variant-numeric:tabular-nums;font-size:18px;font-weight:700}.fZF-xq_bandBadge{opacity:.85;white-space:nowrap;font-size:11px;font-weight:500}.fZF-xq_bandBadge[data-band=peak]{color:var(--dsw-alias-state-error-primary)}.fZF-xq_bandBadge[data-band=offPeak]{color:var(--dsw-alias-state-success-primary)}.fZF-xq_bandBadge:before{content:\"·\";color:currentColor;opacity:.6;margin:0 4px}.fZF-xq_categories{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;flex-wrap:wrap;gap:4px 16px;font-size:12px;display:flex}.fZF-xq_unpricedNote{color:var(--dsw-alias-label-secondary);opacity:.75;font-size:12px}.fZF-xq_steps{flex-direction:column;gap:8px;display:flex}.fZF-xq_stepsTitle{margin:0;font-size:13px;font-weight:600}.fZF-xq_stepList{flex-direction:column;gap:6px;margin:0;padding:0;list-style:none;display:flex}.fZF-xq_step{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:8px;flex-direction:column;gap:2px;padding:8px 10px;display:flex}.fZF-xq_step[data-band=peak]{border-color:var(--dsw-alias-state-error-secondary)}.fZF-xq_step[data-band=offPeak]{border-color:var(--dsw-alias-state-success-secondary)}.fZF-xq_step[data-band=peak] .fZF-xq_stepCost{color:var(--dsw-alias-state-error-primary)}.fZF-xq_step[data-band=offPeak] .fZF-xq_stepCost{color:var(--dsw-alias-state-success-primary)}.fZF-xq_stepHead{flex-wrap:wrap;align-items:baseline;gap:8px;display:flex}.fZF-xq_stepTurn{font-weight:600}.fZF-xq_stepModel{color:var(--dsw-alias-label-secondary);font-size:12px}.fZF-xq_stepTime{color:var(--dsw-alias-label-secondary);opacity:.75;font-size:12px}.fZF-xq_stepCost{font-variant-numeric:tabular-nums;align-items:baseline;gap:4px;margin-left:auto;font-weight:600;display:inline-flex}.fZF-xq_stepBody{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;flex-wrap:wrap;gap:12px;font-size:12px;display:flex}.fZF-xq_stepMeta{color:var(--dsw-alias-label-secondary);opacity:.75}";
|
|
560
580
|
const tagId$3 = "@gamegeek-saikel/dsh-cost-meter/CostView.module.css";
|
|
561
581
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$3) + "]") === null) {
|
|
562
582
|
const tag = document.createElement("style");
|
|
@@ -566,25 +586,25 @@ window.__ModuleLoader__.load({
|
|
|
566
586
|
document.head.appendChild(tag);
|
|
567
587
|
}
|
|
568
588
|
var CostView_module_css_default = {
|
|
569
|
-
"bandBadge": "
|
|
570
|
-
"categories": "
|
|
571
|
-
"root": "
|
|
572
|
-
"step": "
|
|
573
|
-
"stepBody": "
|
|
574
|
-
"stepCost": "
|
|
575
|
-
"stepHead": "
|
|
576
|
-
"stepList": "
|
|
577
|
-
"stepMeta": "
|
|
578
|
-
"stepModel": "
|
|
579
|
-
"stepTime": "
|
|
580
|
-
"stepTurn": "
|
|
581
|
-
"steps": "
|
|
582
|
-
"stepsTitle": "
|
|
583
|
-
"summary": "
|
|
584
|
-
"totalLabel": "
|
|
585
|
-
"totalRow": "
|
|
586
|
-
"totalValue": "
|
|
587
|
-
"unpricedNote": "
|
|
589
|
+
"bandBadge": "fZF-xq_bandBadge",
|
|
590
|
+
"categories": "fZF-xq_categories",
|
|
591
|
+
"root": "fZF-xq_root",
|
|
592
|
+
"step": "fZF-xq_step",
|
|
593
|
+
"stepBody": "fZF-xq_stepBody",
|
|
594
|
+
"stepCost": "fZF-xq_stepCost",
|
|
595
|
+
"stepHead": "fZF-xq_stepHead",
|
|
596
|
+
"stepList": "fZF-xq_stepList",
|
|
597
|
+
"stepMeta": "fZF-xq_stepMeta",
|
|
598
|
+
"stepModel": "fZF-xq_stepModel",
|
|
599
|
+
"stepTime": "fZF-xq_stepTime",
|
|
600
|
+
"stepTurn": "fZF-xq_stepTurn",
|
|
601
|
+
"steps": "fZF-xq_steps",
|
|
602
|
+
"stepsTitle": "fZF-xq_stepsTitle",
|
|
603
|
+
"summary": "fZF-xq_summary",
|
|
604
|
+
"totalLabel": "fZF-xq_totalLabel",
|
|
605
|
+
"totalRow": "fZF-xq_totalRow",
|
|
606
|
+
"totalValue": "fZF-xq_totalValue",
|
|
607
|
+
"unpricedNote": "fZF-xq_unpricedNote"
|
|
588
608
|
};
|
|
589
609
|
//#endregion
|
|
590
610
|
//#region src/client/CostView.tsx
|
|
@@ -603,7 +623,9 @@ window.__ModuleLoader__.load({
|
|
|
603
623
|
}
|
|
604
624
|
const CostView = (0, react.memo)(function CostView({ useProjection, sessionId, t }) {
|
|
605
625
|
const currency = displayCurrency(t);
|
|
606
|
-
const
|
|
626
|
+
const costCny = useProjection("sessionCost");
|
|
627
|
+
const costUsd = useProjection("sessionCostUsd");
|
|
628
|
+
const cost = currency === "USD" ? costUsd : costCny;
|
|
607
629
|
const [response, setResponse] = (0, react.useState)(null);
|
|
608
630
|
const symbol = currencySymbol(currency);
|
|
609
631
|
(0, react.useEffect)(() => {
|
|
@@ -716,7 +738,7 @@ window.__ModuleLoader__.load({
|
|
|
716
738
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ol", {
|
|
717
739
|
className: CostView_module_css_default.stepList,
|
|
718
740
|
children: rows.map((step) => {
|
|
719
|
-
const stepBand = bandForTime(
|
|
741
|
+
const stepBand = step.band ?? bandForTime(step.time);
|
|
720
742
|
const stepRatio = peakOffPeakMultiplier(response?.pricebook?.current ?? null, step.provider, step.model);
|
|
721
743
|
const stepBandLabel = stepBand === "peak" ? stepRatio === null ? t("band.peak") : t("price.peakRatio", { multiplier: formatMultiplier(stepRatio) }) : stepBand === "offPeak" ? stepRatio === null ? t("band.offPeak") : t("price.offPeakRatio", { multiplier: formatMultiplier(1 / stepRatio) }) : null;
|
|
722
744
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
|
|
@@ -770,8 +792,8 @@ window.__ModuleLoader__.load({
|
|
|
770
792
|
});
|
|
771
793
|
});
|
|
772
794
|
//#endregion
|
|
773
|
-
//#region \0dsh-css
|
|
774
|
-
const css$2 = ".
|
|
795
|
+
//#region \0dsh-css:/home/runner/work/dsh-cost-meter/dsh-cost-meter/src/client/AssistantCostChip.module.css.mjs
|
|
796
|
+
const css$2 = "._9lx30q_root{color:var(--dsw-alias-label-tertiary);white-space:nowrap;font-variant-numeric:tabular-nums;order:10;align-items:baseline;gap:4px;margin-left:10px;font-size:14px;line-height:24px;display:inline-flex}._9lx30q_root:before{content:\"·\";color:var(--dsw-alias-separator-primary);margin-right:10px}._9lx30q_bandBadge{opacity:.85;white-space:nowrap;font-size:12px;line-height:18px}._9lx30q_bandBadge[data-band=peak]{color:var(--dsw-alias-state-error-primary)}._9lx30q_bandBadge[data-band=offPeak]{color:var(--dsw-alias-state-success-primary)}._9lx30q_bandBadge:before{content:\"·\";color:currentColor;opacity:.6;margin:0 4px}._9lx30q_unpriced{color:var(--dsw-alias-label-tertiary);white-space:nowrap;opacity:.6;cursor:help;order:10;margin-left:10px;font-size:14px;line-height:24px}._9lx30q_unpriced:before{content:\"·\";color:var(--dsw-alias-separator-primary);margin-right:10px}@media (hover:hover){[data-time-hover-root] [data-cost-chip]{opacity:0;transition:opacity 80ms}[data-time-hover-root]:hover [data-cost-chip],[data-time-hover-root]:focus-within [data-cost-chip]{opacity:1}[data-time-hover-root] [data-cost-chip]._9lx30q_unpriced{opacity:0}}";
|
|
775
797
|
const tagId$2 = "@gamegeek-saikel/dsh-cost-meter/AssistantCostChip.module.css";
|
|
776
798
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$2) + "]") === null) {
|
|
777
799
|
const tag = document.createElement("style");
|
|
@@ -781,9 +803,9 @@ window.__ModuleLoader__.load({
|
|
|
781
803
|
document.head.appendChild(tag);
|
|
782
804
|
}
|
|
783
805
|
var AssistantCostChip_module_css_default = {
|
|
784
|
-
"bandBadge": "
|
|
785
|
-
"root": "
|
|
786
|
-
"unpriced": "
|
|
806
|
+
"bandBadge": "_9lx30q_bandBadge",
|
|
807
|
+
"root": "_9lx30q_root",
|
|
808
|
+
"unpriced": "_9lx30q_unpriced"
|
|
787
809
|
};
|
|
788
810
|
//#endregion
|
|
789
811
|
//#region src/client/AssistantCostChip.tsx
|
|
@@ -822,10 +844,10 @@ window.__ModuleLoader__.load({
|
|
|
822
844
|
}
|
|
823
845
|
const AssistantCostChip = (0, react.memo)(function AssistantCostChip({ messageId, useSession, useProjection, t }) {
|
|
824
846
|
const currency = displayCurrency(t);
|
|
825
|
-
const projectionKey = currency === "USD" ? "sessionCostUsd" : "sessionCost";
|
|
826
847
|
const step = useSession((snapshot) => stepOfMessage(snapshot, messageId));
|
|
827
|
-
const
|
|
828
|
-
const
|
|
848
|
+
const costCny = useProjection("sessionCost");
|
|
849
|
+
const costUsd = useProjection("sessionCostUsd");
|
|
850
|
+
const ledger = step === null ? void 0 : stepOf((currency === "USD" ? costUsd : costCny)?.steps, step.turn, step.step);
|
|
829
851
|
const [response, setResponse] = (0, react.useState)(null);
|
|
830
852
|
(0, react.useEffect)(() => {
|
|
831
853
|
let alive = true;
|
|
@@ -849,7 +871,7 @@ window.__ModuleLoader__.load({
|
|
|
849
871
|
});
|
|
850
872
|
}
|
|
851
873
|
const amount = `${currencySymbol(currency)}${formatMoney(ledger.cost)}`;
|
|
852
|
-
const band = bandForTime(
|
|
874
|
+
const band = ledger.band ?? bandForTime(ledger.time);
|
|
853
875
|
const ratio = peakOffPeakMultiplier(response?.pricebook?.current ?? null, ledger.provider, ledger.model);
|
|
854
876
|
const bandLabel = band === "peak" ? ratio === null ? t("band.peak") : t("price.peakRatio", { multiplier: formatMultiplier(ratio) }) : band === "offPeak" ? ratio === null ? t("band.offPeak") : t("price.offPeakRatio", { multiplier: formatMultiplier(1 / ratio) }) : null;
|
|
855
877
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
@@ -866,8 +888,8 @@ window.__ModuleLoader__.load({
|
|
|
866
888
|
});
|
|
867
889
|
});
|
|
868
890
|
//#endregion
|
|
869
|
-
//#region \0dsh-css
|
|
870
|
-
const css$1 = ".
|
|
891
|
+
//#region \0dsh-css:/home/runner/work/dsh-cost-meter/dsh-cost-meter/src/client/SessionCostPill.module.css.mjs
|
|
892
|
+
const css$1 = ".jn2k9a_wrap{display:inline-flex;position:relative}.jn2k9a_pill{border:1px solid var(--dsw-alias-border-l2);height:32px;color:var(--dsw-alias-label-primary);font-family:var(--dsw-font-family);font-variant-numeric:tabular-nums;white-space:nowrap;cursor:pointer;user-select:none;background:0 0;border-radius:18px;justify-content:center;align-items:center;gap:4px;padding:6px 12px;font-size:13px;font-weight:400;line-height:20px;transition:background-color .15s,color .15s,border-color .15s;display:inline-flex}.jn2k9a_pill:hover{background:var(--dsw-alias-interactive-bg-hover)}.jn2k9a_pill:active{transform:translateY(.5px)}.jn2k9a_pill[data-running=true]{color:var(--dsw-alias-brand-primary)}.jn2k9a_pill[data-running=true]:hover{background:var(--dsw-alias-interactive-bg-hover)}.jn2k9a_pill[data-band=peak]{color:var(--dsw-alias-state-error-primary);border-color:var(--dsw-alias-state-error-secondary)}.jn2k9a_pill[data-band=offPeak]{color:var(--dsw-alias-state-success-primary);border-color:var(--dsw-alias-state-success-secondary)}.jn2k9a_bandBadge{opacity:.85;white-space:nowrap;font-size:11px;line-height:16px}.jn2k9a_bandBadge:before{content:\"·\";color:currentColor;opacity:.6;margin:0 4px}.jn2k9a_estimateNote{opacity:.75;font-size:11px}.jn2k9a_detail{z-index:100;border:1px solid var(--dsw-alias-border-inverted);background:var(--dsw-specific-menu);min-width:250px;max-width:340px;box-shadow:var(--dsw-shadow-lv3);color:var(--dsw-alias-label-primary);font-variant-numeric:tabular-nums;border-radius:12px;flex-direction:column;gap:5px;padding:12px 14px;font-size:12px;line-height:18px;display:flex;position:absolute;top:calc(100% + 8px);right:0}.jn2k9a_detailRow{white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.jn2k9a_detailRowSecondary{color:var(--dsw-alias-label-secondary)}.jn2k9a_detailRowMuted{color:var(--dsw-alias-label-secondary);opacity:.75}.jn2k9a_detailTotal{font-size:13px;font-weight:600}";
|
|
871
893
|
const tagId$1 = "@gamegeek-saikel/dsh-cost-meter/SessionCostPill.module.css";
|
|
872
894
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
|
|
873
895
|
const tag = document.createElement("style");
|
|
@@ -877,15 +899,15 @@ window.__ModuleLoader__.load({
|
|
|
877
899
|
document.head.appendChild(tag);
|
|
878
900
|
}
|
|
879
901
|
var SessionCostPill_module_css_default = {
|
|
880
|
-
"bandBadge": "
|
|
881
|
-
"detail": "
|
|
882
|
-
"detailRow": "
|
|
883
|
-
"detailRowMuted": "
|
|
884
|
-
"detailRowSecondary": "
|
|
885
|
-
"detailTotal": "
|
|
886
|
-
"estimateNote": "
|
|
887
|
-
"pill": "
|
|
888
|
-
"wrap": "
|
|
902
|
+
"bandBadge": "jn2k9a_bandBadge",
|
|
903
|
+
"detail": "jn2k9a_detail",
|
|
904
|
+
"detailRow": "jn2k9a_detailRow",
|
|
905
|
+
"detailRowMuted": "jn2k9a_detailRowMuted",
|
|
906
|
+
"detailRowSecondary": "jn2k9a_detailRowSecondary",
|
|
907
|
+
"detailTotal": "jn2k9a_detailTotal",
|
|
908
|
+
"estimateNote": "jn2k9a_estimateNote",
|
|
909
|
+
"pill": "jn2k9a_pill",
|
|
910
|
+
"wrap": "jn2k9a_wrap"
|
|
889
911
|
};
|
|
890
912
|
//#endregion
|
|
891
913
|
//#region src/client/SessionCostPill.tsx
|
|
@@ -934,7 +956,9 @@ window.__ModuleLoader__.load({
|
|
|
934
956
|
}
|
|
935
957
|
const SessionCostPill = (0, react.memo)(function SessionCostPill({ useSession, useProjection, sessionId, t }) {
|
|
936
958
|
const currency = displayCurrency(t);
|
|
937
|
-
const
|
|
959
|
+
const costCny = useProjection("sessionCost");
|
|
960
|
+
const costUsd = useProjection("sessionCostUsd");
|
|
961
|
+
const cost = currency === "USD" ? costUsd : costCny;
|
|
938
962
|
const pressure = useProjection("contextPressure");
|
|
939
963
|
const running = useSession(runningOf);
|
|
940
964
|
const partial = useSession((snapshot) => snapshot.partial);
|
|
@@ -962,13 +986,14 @@ window.__ModuleLoader__.load({
|
|
|
962
986
|
const projection = cost;
|
|
963
987
|
const model = projection?.model ?? null;
|
|
964
988
|
const snapshot = response?.pricebook.current ?? null;
|
|
989
|
+
const schedule = response?.pricebook.schedule;
|
|
965
990
|
const subagents = response?.subagents;
|
|
966
991
|
const combined = combineTotals(projection?.totals, subagents);
|
|
967
992
|
const subSpend = subagentSpend(subagents);
|
|
968
993
|
const symbol = currencySymbol(currency);
|
|
969
994
|
const estimate = (0, react.useMemo)(() => {
|
|
970
995
|
if (!running || projection === void 0) return null;
|
|
971
|
-
const bucket = bucketAt(snapshot ?? void 0, model?.provider, model?.model ?? "unknown", Date.now());
|
|
996
|
+
const bucket = bucketAt(snapshot ?? void 0, model?.provider, model?.model ?? "unknown", Date.now(), schedule);
|
|
972
997
|
if (bucket === void 0) return null;
|
|
973
998
|
const stepEstimate = estimateCost(bucket, pressure?.projectedTokens ?? pressure?.pressureTokens ?? 0, cacheReadRatioOf(projection.steps), blocksOutputTokens(partial?.blocks));
|
|
974
999
|
return (combined?.cost ?? 0) + stepEstimate;
|
|
@@ -977,6 +1002,7 @@ window.__ModuleLoader__.load({
|
|
|
977
1002
|
projection,
|
|
978
1003
|
combined,
|
|
979
1004
|
snapshot,
|
|
1005
|
+
schedule,
|
|
980
1006
|
model,
|
|
981
1007
|
pressure,
|
|
982
1008
|
partial,
|
|
@@ -988,7 +1014,7 @@ window.__ModuleLoader__.load({
|
|
|
988
1014
|
const last = projection?.steps.length !== void 0 && projection.steps.length > 0 ? projection.steps[projection.steps.length - 1] : void 0;
|
|
989
1015
|
const sourceKey = snapshot?.source ?? null;
|
|
990
1016
|
const source = sourceKey === null ? t("source.none") : t(`source.${sourceKey}`);
|
|
991
|
-
const band = bandForTime(Date.now());
|
|
1017
|
+
const band = bandForTime(Date.now(), schedule);
|
|
992
1018
|
const peakRatio = peakOffPeakMultiplier(snapshot ?? void 0, model?.provider, model?.model ?? "unknown");
|
|
993
1019
|
const bandLabel = band === "peak" ? peakRatio === null ? t("band.peak") : t("price.peakRatio", { multiplier: formatMultiplier(peakRatio) }) : band === "offPeak" ? peakRatio === null ? t("band.offPeak") : t("price.offPeakRatio", { multiplier: formatMultiplier(1 / peakRatio) }) : null;
|
|
994
1020
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -1085,8 +1111,8 @@ window.__ModuleLoader__.load({
|
|
|
1085
1111
|
});
|
|
1086
1112
|
});
|
|
1087
1113
|
//#endregion
|
|
1088
|
-
//#region \0dsh-css
|
|
1089
|
-
const css = ".
|
|
1114
|
+
//#region \0dsh-css:/home/runner/work/dsh-cost-meter/dsh-cost-meter/src/client/CostPluginCard.module.css.mjs
|
|
1115
|
+
const css = ".tDlB8a_card{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;list-style:none;transition:border-color .16s,background .16s}.tDlB8a_card:hover{border-color:var(--dsw-alias-label-dimmed)}.tDlB8a_cardOpen{background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-label-dimmed)}.tDlB8a_header{appearance:none;width:100%;font:inherit;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:12px;align-items:center;gap:12px;padding:14px 16px;display:flex}.tDlB8a_header:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:-2px}.tDlB8a_headText{flex-direction:column;flex:1;gap:4px;min-width:0;display:flex}.tDlB8a_name{color:var(--dsw-alias-label-primary);font-size:15px;font-weight:600;line-height:1.4}.tDlB8a_description{color:var(--dsw-alias-label-tertiary);font-size:13px;line-height:1.5}.tDlB8a_chevron{color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .16s}.tDlB8a_chevronOpen{transform:rotate(180deg)}.tDlB8a_pending{white-space:nowrap;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);text-overflow:ellipsis;border-radius:999px;flex:none;max-width:220px;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px;overflow:hidden}.tDlB8a_body{border-top:1px solid var(--dsw-alias-border-l2);margin:0 16px;padding-bottom:8px}.tDlB8a_field{flex-direction:column;gap:6px;padding:12px 0;display:flex}.tDlB8a_field+.tDlB8a_field{border-top:1px solid var(--dsw-alias-border-l2)}.tDlB8a_head{align-items:center;gap:8px;display:flex}.tDlB8a_label{min-width:0;color:var(--dsw-alias-label-primary);flex:1;font-size:13px;font-weight:500;line-height:1.5}.tDlB8a_input,.tDlB8a_select,.tDlB8a_textarea{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);font:inherit;border-radius:8px;font-size:13px;line-height:1.5}.tDlB8a_input{width:120px;padding:5px 8px}.tDlB8a_select{padding:5px 8px}.tDlB8a_textarea{width:100%;min-height:72px;font-family:var(--dsw-font-mono,monospace);resize:vertical;padding:6px 8px;font-size:12px}.tDlB8a_inline{align-items:center;gap:8px;display:flex}.tDlB8a_checkbox{width:16px;height:16px;accent-color:var(--dsw-alias-brand-primary)}.tDlB8a_hint{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:1.5}.tDlB8a_footer{border-top:1px solid var(--dsw-alias-border-l2);justify-content:flex-end;align-items:center;gap:8px;padding:12px 0 4px;display:flex}.tDlB8a_spacer{flex:1}.tDlB8a_status{color:var(--dsw-alias-state-success-primary);font-size:12px;line-height:1.5}";
|
|
1090
1116
|
const tagId = "@gamegeek-saikel/dsh-cost-meter/CostPluginCard.module.css";
|
|
1091
1117
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
1092
1118
|
const tag = document.createElement("style");
|
|
@@ -1096,28 +1122,28 @@ window.__ModuleLoader__.load({
|
|
|
1096
1122
|
document.head.appendChild(tag);
|
|
1097
1123
|
}
|
|
1098
1124
|
var CostPluginCard_module_css_default = {
|
|
1099
|
-
"body": "
|
|
1100
|
-
"card": "
|
|
1101
|
-
"cardOpen": "
|
|
1102
|
-
"checkbox": "
|
|
1103
|
-
"chevron": "
|
|
1104
|
-
"chevronOpen": "
|
|
1105
|
-
"description": "
|
|
1106
|
-
"field": "
|
|
1107
|
-
"footer": "
|
|
1108
|
-
"head": "
|
|
1109
|
-
"headText": "
|
|
1110
|
-
"header": "
|
|
1111
|
-
"hint": "
|
|
1112
|
-
"inline": "
|
|
1113
|
-
"input": "
|
|
1114
|
-
"label": "
|
|
1115
|
-
"name": "
|
|
1116
|
-
"pending": "
|
|
1117
|
-
"select": "
|
|
1118
|
-
"spacer": "
|
|
1119
|
-
"status": "
|
|
1120
|
-
"textarea": "
|
|
1125
|
+
"body": "tDlB8a_body",
|
|
1126
|
+
"card": "tDlB8a_card",
|
|
1127
|
+
"cardOpen": "tDlB8a_cardOpen",
|
|
1128
|
+
"checkbox": "tDlB8a_checkbox",
|
|
1129
|
+
"chevron": "tDlB8a_chevron",
|
|
1130
|
+
"chevronOpen": "tDlB8a_chevronOpen",
|
|
1131
|
+
"description": "tDlB8a_description",
|
|
1132
|
+
"field": "tDlB8a_field",
|
|
1133
|
+
"footer": "tDlB8a_footer",
|
|
1134
|
+
"head": "tDlB8a_head",
|
|
1135
|
+
"headText": "tDlB8a_headText",
|
|
1136
|
+
"header": "tDlB8a_header",
|
|
1137
|
+
"hint": "tDlB8a_hint",
|
|
1138
|
+
"inline": "tDlB8a_inline",
|
|
1139
|
+
"input": "tDlB8a_input",
|
|
1140
|
+
"label": "tDlB8a_label",
|
|
1141
|
+
"name": "tDlB8a_name",
|
|
1142
|
+
"pending": "tDlB8a_pending",
|
|
1143
|
+
"select": "tDlB8a_select",
|
|
1144
|
+
"spacer": "tDlB8a_spacer",
|
|
1145
|
+
"status": "tDlB8a_status",
|
|
1146
|
+
"textarea": "tDlB8a_textarea"
|
|
1121
1147
|
};
|
|
1122
1148
|
//#endregion
|
|
1123
1149
|
//#region src/client/CostPluginCard.tsx
|