dsh-context 0.59.0 → 0.59.1
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/lib/client.js +170 -133
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -56,15 +56,16 @@ window.__ModuleLoader__.load({
|
|
|
56
56
|
"stats.cacheHit": "缓存命中",
|
|
57
57
|
"stats.cacheHitTip": "整个会话累计的缓存读取占计费输入的比例。",
|
|
58
58
|
"stats.cost": "费用",
|
|
59
|
-
"stats.costTip": "
|
|
59
|
+
"stats.costTip": "估算的费用,含当前智能体及所有子智能体,仅供参考。",
|
|
60
60
|
"stats.costTipDeepseek": "DeepSeek 高峰时段(北京时间工作日 9:00–12:00、14:00–18:00)按挂牌价计费,其余时段半价。",
|
|
61
|
+
"stats.costTipCny": "人民币按 1 元 = 0.15 美元换算。",
|
|
61
62
|
"stats.subCost": "子 Agent 费用",
|
|
62
63
|
"stats.subCostTip": "所有子 Agent 会话各自累计费用(同口径估算)的合计,不含当前 Agent 自身。",
|
|
63
|
-
"stats.costPriceHead": "每百万
|
|
64
|
-
"stats.
|
|
65
|
-
"stats.costHit": "
|
|
66
|
-
"stats.costMiss": "
|
|
67
|
-
"stats.costWrite": "
|
|
64
|
+
"stats.costPriceHead": "每百万 Token 价格:",
|
|
65
|
+
"stats.costPriceBy": "按 {p} · {m} 在 models.dev 的刊登价格如上。",
|
|
66
|
+
"stats.costHit": "缓存输入",
|
|
67
|
+
"stats.costMiss": "未缓存输入",
|
|
68
|
+
"stats.costWrite": "缓存写入",
|
|
68
69
|
"stats.costOut": "输出",
|
|
69
70
|
"stats.costUnavailable": "模型价格暂不可用(自动重试中),费用暂无法估算。",
|
|
70
71
|
"timing.title": "耗时统计",
|
|
@@ -442,16 +443,17 @@ window.__ModuleLoader__.load({
|
|
|
442
443
|
"stats.cacheHit": "Cache Hit",
|
|
443
444
|
"stats.cacheHitTip": "Cumulative cache-read share of billed input across the session.",
|
|
444
445
|
"stats.cost": "Cost",
|
|
445
|
-
"stats.costTip": "
|
|
446
|
+
"stats.costTip": "Estimated cost for this agent and all its subagents, for reference only.",
|
|
446
447
|
"stats.costTipDeepseek": "DeepSeek bills peak windows (Beijing Time weekdays 09:00–12:00, 14:00–18:00) at list price; all other hours are half price.",
|
|
448
|
+
"stats.costTipCny": "The CNY display converts at 1 CNY = 0.15 USD.",
|
|
447
449
|
"stats.subCost": "Subagent Cost",
|
|
448
450
|
"stats.subCostTip": "Summed estimates of every subagent session’s own cumulative cost (same basis); the current agent is not included.",
|
|
449
451
|
"stats.costPriceHead": "Per-1M-token rates:",
|
|
450
|
-
"stats.
|
|
451
|
-
"stats.costHit": "
|
|
452
|
-
"stats.costMiss": "
|
|
453
|
-
"stats.costWrite": "write",
|
|
454
|
-
"stats.costOut": "
|
|
452
|
+
"stats.costPriceBy": "Priced as listed on models.dev for {p} · {m}.",
|
|
453
|
+
"stats.costHit": "Cache input",
|
|
454
|
+
"stats.costMiss": "Uncached input",
|
|
455
|
+
"stats.costWrite": "Cache write",
|
|
456
|
+
"stats.costOut": "Output",
|
|
455
457
|
"stats.costUnavailable": "Model prices are unavailable (retrying automatically) — the cost cannot be estimated yet.",
|
|
456
458
|
"timing.title": "Timing Stats",
|
|
457
459
|
"timing.total": "Active Time",
|
|
@@ -5593,6 +5595,7 @@ window.__ModuleLoader__.load({
|
|
|
5593
5595
|
const lower = mid.toLowerCase();
|
|
5594
5596
|
const cand = {
|
|
5595
5597
|
pid,
|
|
5598
|
+
mid,
|
|
5596
5599
|
rate,
|
|
5597
5600
|
primary
|
|
5598
5601
|
};
|
|
@@ -5604,47 +5607,47 @@ window.__ModuleLoader__.load({
|
|
|
5604
5607
|
return { byModel };
|
|
5605
5608
|
}
|
|
5606
5609
|
/**
|
|
5607
|
-
* The rate shared by a candidate group, or null: the
|
|
5608
|
-
* group wins, a tie refuses. Agreeing mirrors are noise;
|
|
5609
|
-
* price nothing rather than guess.
|
|
5610
|
+
* The candidate carrying the rate shared by a candidate group, or null: the
|
|
5611
|
+
* largest equal-rate group wins, a tie refuses. Agreeing mirrors are noise;
|
|
5612
|
+
* disagreeing ones price nothing rather than guess.
|
|
5610
5613
|
*/
|
|
5611
|
-
function
|
|
5614
|
+
function majorityCandidate(cands) {
|
|
5612
5615
|
const groups = [];
|
|
5613
5616
|
for (const c of cands) {
|
|
5614
|
-
const g = groups.find((g) => sameRate(g.rate, c.rate));
|
|
5617
|
+
const g = groups.find((g) => sameRate(g.cand.rate, c.rate));
|
|
5615
5618
|
if (g === void 0) groups.push({
|
|
5616
|
-
|
|
5619
|
+
cand: c,
|
|
5617
5620
|
n: 1
|
|
5618
5621
|
});
|
|
5619
5622
|
else g.n++;
|
|
5620
5623
|
}
|
|
5621
5624
|
groups.sort((a, b) => b.n - a.n);
|
|
5622
|
-
return groups.length > 1 && groups[0].n === groups[1].n ? null : groups[0].
|
|
5625
|
+
return groups.length > 1 && groups[0].n === groups[1].n ? null : groups[0].cand;
|
|
5623
5626
|
}
|
|
5624
5627
|
/**
|
|
5625
|
-
* Pick one candidate
|
|
5626
|
-
*
|
|
5627
|
-
*
|
|
5628
|
+
* Pick one candidate: the model's own vendor (unique or unanimous), then a
|
|
5629
|
+
* provider the model id itself names (`deepseek-v4-flash` under `deepseek`),
|
|
5630
|
+
* then a lone carrier. Everything else prices null.
|
|
5628
5631
|
*/
|
|
5629
5632
|
function resolveCandidates(lower, cands, org) {
|
|
5630
5633
|
if (org !== null) {
|
|
5631
5634
|
const named = cands.filter((c) => c.pid === org || org.startsWith(c.pid + "-") || org.length >= 4 && org.startsWith(c.pid));
|
|
5632
5635
|
if (named.length > 0) {
|
|
5633
|
-
const
|
|
5634
|
-
if (
|
|
5636
|
+
const cand = majorityCandidate(named);
|
|
5637
|
+
if (cand !== null) return cand;
|
|
5635
5638
|
}
|
|
5636
5639
|
}
|
|
5637
5640
|
const primaries = cands.filter((c) => c.primary);
|
|
5638
5641
|
if (primaries.length > 0) {
|
|
5639
|
-
const
|
|
5640
|
-
if (
|
|
5642
|
+
const cand = majorityCandidate(primaries);
|
|
5643
|
+
if (cand !== null) return cand;
|
|
5641
5644
|
}
|
|
5642
5645
|
const prefixed = cands.filter((c) => lower.startsWith(c.pid + "-") || lower.startsWith(c.pid + "/"));
|
|
5643
5646
|
if (prefixed.length > 0) {
|
|
5644
|
-
const
|
|
5645
|
-
if (
|
|
5647
|
+
const cand = majorityCandidate(prefixed);
|
|
5648
|
+
if (cand !== null) return cand;
|
|
5646
5649
|
}
|
|
5647
|
-
return cands.length === 1 ? cands[0]
|
|
5650
|
+
return cands.length === 1 ? cands[0] : null;
|
|
5648
5651
|
}
|
|
5649
5652
|
/**
|
|
5650
5653
|
* Resolve a model id book-wide: the full id first, then its last `/`-segment
|
|
@@ -5658,34 +5661,29 @@ window.__ModuleLoader__.load({
|
|
|
5658
5661
|
for (const key of slash > 0 ? [lower, lower.slice(slash + 1)] : [lower]) {
|
|
5659
5662
|
const cands = index.byModel.get(key);
|
|
5660
5663
|
if (cands === void 0) continue;
|
|
5661
|
-
const
|
|
5662
|
-
if (
|
|
5664
|
+
const cand = resolveCandidates(key, cands, org);
|
|
5665
|
+
if (cand !== null) return cand;
|
|
5663
5666
|
}
|
|
5664
5667
|
return null;
|
|
5665
5668
|
}
|
|
5666
|
-
/** One rate triple at the doubled peak rate (the tooltip's `peak | off` pair). */
|
|
5667
|
-
function peakOf(rate) {
|
|
5668
|
-
return {
|
|
5669
|
-
hit: rate.hit * PEAK_FACTOR,
|
|
5670
|
-
miss: rate.miss * PEAK_FACTOR,
|
|
5671
|
-
write: rate.write * PEAK_FACTOR,
|
|
5672
|
-
out: rate.out * PEAK_FACTOR
|
|
5673
|
-
};
|
|
5674
|
-
}
|
|
5675
5669
|
/** One book branch (a provider's models), as far as runtime can prove it. */
|
|
5676
5670
|
function branchOf(book, id) {
|
|
5677
5671
|
const v = book[id];
|
|
5678
5672
|
return v !== null && typeof v === "object" ? v : null;
|
|
5679
5673
|
}
|
|
5680
5674
|
/**
|
|
5681
|
-
* One branch's
|
|
5682
|
-
* key first (the book is untrusted
|
|
5683
|
-
* by id SUFFIX — dsh spells some
|
|
5684
|
-
*
|
|
5685
|
-
* hypothetical `other-k3`) are
|
|
5675
|
+
* One branch's lookup hit — the registry's own model id and its rates, as
|
|
5676
|
+
* far as runtime can prove it: exact own key first (the book is untrusted
|
|
5677
|
+
* wire data), then case-insensitively, then by id SUFFIX — dsh spells some
|
|
5678
|
+
* models short (`k3`) where the registry namespaces them (`kimi-k3`).
|
|
5679
|
+
* Several suffix candidates (e.g. `k3` vs a hypothetical `other-k3`) are
|
|
5680
|
+
* ambiguous and price nothing.
|
|
5686
5681
|
*/
|
|
5687
|
-
function
|
|
5688
|
-
if (Object.hasOwn(models, model)) return
|
|
5682
|
+
function lookupFace(models, model) {
|
|
5683
|
+
if (Object.hasOwn(models, model)) return {
|
|
5684
|
+
mid: model,
|
|
5685
|
+
rate: models[model]
|
|
5686
|
+
};
|
|
5689
5687
|
const m = model.toLowerCase();
|
|
5690
5688
|
let found = null;
|
|
5691
5689
|
let seen = null;
|
|
@@ -5694,24 +5692,63 @@ window.__ModuleLoader__.load({
|
|
|
5694
5692
|
if (lower !== m && !lower.endsWith("-" + m)) continue;
|
|
5695
5693
|
if (seen !== null && seen !== lower) return null;
|
|
5696
5694
|
seen = lower;
|
|
5697
|
-
found =
|
|
5695
|
+
found = {
|
|
5696
|
+
mid: id,
|
|
5697
|
+
rate: models[id]
|
|
5698
|
+
};
|
|
5698
5699
|
}
|
|
5699
5700
|
return found;
|
|
5700
5701
|
}
|
|
5701
5702
|
/**
|
|
5702
|
-
*
|
|
5703
|
-
*
|
|
5704
|
-
*
|
|
5705
|
-
*
|
|
5706
|
-
*
|
|
5707
|
-
*
|
|
5708
|
-
*
|
|
5709
|
-
|
|
5710
|
-
|
|
5703
|
+
* One billed model's price: the USD rates plus the registry face — the
|
|
5704
|
+
* models.dev provider id and branch model id spelling — they resolved from
|
|
5705
|
+
* (what the stats board prints as the listing source).
|
|
5706
|
+
*
|
|
5707
|
+
* Resolution: the dsh provider id goes through modelsDevProviderOf (unmapped
|
|
5708
|
+
* ids pass through) and prices by model id — exact, case-insensitive, or
|
|
5709
|
+
* suffix. A provider the book does not carry falls back to the model-side
|
|
5710
|
+
* resolution index, which names the vendor from data (org segment, own-vendor
|
|
5711
|
+
* SDK, id prefix, lone carrier) — never from a per-model hardcode. The one
|
|
5712
|
+
* vendor-level seam: a `deepseek-` model id prices from DeepSeek's own
|
|
5713
|
+
* registry branch first — its listing is the first-party price book (cache
|
|
5714
|
+
* rates included), while the model-side tiers can hand the same id to a
|
|
5715
|
+
* self-named hosting provider whose flat listing bills cache hits as plain
|
|
5716
|
+
* input (azure's `deepseek-v4-pro`, issue #93) — the same specialness the
|
|
5717
|
+
* peak/off-peak split already grants DeepSeek.
|
|
5718
|
+
*/
|
|
5719
|
+
function priceFaceOf(book, provider, model) {
|
|
5711
5720
|
if (book === null || book === void 0) return null;
|
|
5712
|
-
const
|
|
5713
|
-
|
|
5714
|
-
|
|
5721
|
+
const registryPid = modelsDevProviderOf(provider);
|
|
5722
|
+
const direct = branchOf(book.prices, registryPid);
|
|
5723
|
+
if (direct !== null) {
|
|
5724
|
+
const found = lookupFace(direct, model);
|
|
5725
|
+
return found === null ? null : {
|
|
5726
|
+
pid: registryPid,
|
|
5727
|
+
mid: found.mid,
|
|
5728
|
+
rate: found.rate
|
|
5729
|
+
};
|
|
5730
|
+
}
|
|
5731
|
+
if (model.toLowerCase().startsWith("deepseek-")) {
|
|
5732
|
+
const firstParty = branchOf(book.prices, "deepseek");
|
|
5733
|
+
if (firstParty !== null) {
|
|
5734
|
+
const official = lookupFace(firstParty, model);
|
|
5735
|
+
if (official !== null) return {
|
|
5736
|
+
pid: "deepseek",
|
|
5737
|
+
mid: official.mid,
|
|
5738
|
+
rate: official.rate
|
|
5739
|
+
};
|
|
5740
|
+
}
|
|
5741
|
+
}
|
|
5742
|
+
const cand = resolveRate(book.index, model);
|
|
5743
|
+
return cand === null ? null : {
|
|
5744
|
+
pid: cand.pid,
|
|
5745
|
+
mid: cand.mid,
|
|
5746
|
+
rate: cand.rate
|
|
5747
|
+
};
|
|
5748
|
+
}
|
|
5749
|
+
/** The book's rates for one folded (provider, model) bucket ({@link priceFaceOf} without the face). */
|
|
5750
|
+
function priceOf(book, provider, model) {
|
|
5751
|
+
return priceFaceOf(book, provider, model)?.rate ?? null;
|
|
5715
5752
|
}
|
|
5716
5753
|
/**
|
|
5717
5754
|
* Price the session's cumulative billed-token totals. Cache reads bill at
|
|
@@ -5798,9 +5835,9 @@ window.__ModuleLoader__.load({
|
|
|
5798
5835
|
function formatCost(amount, currency) {
|
|
5799
5836
|
return (currency === "cny" ? "¥" : "$") + (amount >= 1 ? amount.toFixed(2) : amount.toPrecision(2));
|
|
5800
5837
|
}
|
|
5801
|
-
/** Price-list figure:
|
|
5838
|
+
/** Price-list figure: always two decimals (the tooltip's `¥ XX.XX` rate format). */
|
|
5802
5839
|
function formatPriceRate(amount, currency) {
|
|
5803
|
-
return
|
|
5840
|
+
return (currency === "cny" ? "¥" : "$") + amount.toFixed(2);
|
|
5804
5841
|
}
|
|
5805
5842
|
//#endregion
|
|
5806
5843
|
//#region node_modules/.pnpm/@opencode-ai+models@0.0.87/node_modules/@opencode-ai/models/dist/error.js
|
|
@@ -10747,7 +10784,7 @@ window.__ModuleLoader__.load({
|
|
|
10747
10784
|
return function PluginInfo() {
|
|
10748
10785
|
const [latest, setLatest] = (0, react.useState)(null);
|
|
10749
10786
|
(0, react.useEffect)(() => {
|
|
10750
|
-
if ("0.59.
|
|
10787
|
+
if ("0.59.1".includes("-dev")) return;
|
|
10751
10788
|
let on = true;
|
|
10752
10789
|
fetchLatestVersion().then((v) => {
|
|
10753
10790
|
if (on && v) setLatest(v);
|
|
@@ -10756,8 +10793,8 @@ window.__ModuleLoader__.load({
|
|
|
10756
10793
|
on = false;
|
|
10757
10794
|
};
|
|
10758
10795
|
}, []);
|
|
10759
|
-
const update = latest !== null && isNewerVersion(latest, "0.59.
|
|
10760
|
-
const nameText = "dsh-context (v0.59.
|
|
10796
|
+
const update = latest !== null && isNewerVersion(latest, "0.59.1") ? latest : null;
|
|
10797
|
+
const nameText = "dsh-context (v0.59.1)";
|
|
10761
10798
|
const nameValue = [nameText];
|
|
10762
10799
|
if (update) nameValue.push(/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
10763
10800
|
className: "lc-pi-update",
|
|
@@ -11222,18 +11259,22 @@ window.__ModuleLoader__.load({
|
|
|
11222
11259
|
* and the caller derives them from the collections on the inline generation
|
|
11223
11260
|
* (`countsOfRecords`). The card itself never touches the collections.
|
|
11224
11261
|
*/
|
|
11262
|
+
/** The four billed buckets of a price block, in display order, with their label keys. */
|
|
11263
|
+
const BANDS = [
|
|
11264
|
+
["hit", "stats.costHit"],
|
|
11265
|
+
["miss", "stats.costMiss"],
|
|
11266
|
+
["write", "stats.costWrite"],
|
|
11267
|
+
["out", "stats.costOut"]
|
|
11268
|
+
];
|
|
11225
11269
|
/**
|
|
11226
|
-
* The
|
|
11227
|
-
*
|
|
11228
|
-
*
|
|
11229
|
-
*
|
|
11230
|
-
* with an off-peak bucket (DeepSeek's period-based list) shows the
|
|
11231
|
-
* peak | off-peak pair.
|
|
11270
|
+
* The billed models' price blocks — the usage keys priced against the book,
|
|
11271
|
+
* in fold order, each carrying the registry face (models.dev provider id ·
|
|
11272
|
+
* model id) its rates resolved from. Hostile branches skip; unpriced models
|
|
11273
|
+
* drop (their buckets simply do not contribute).
|
|
11232
11274
|
*/
|
|
11233
11275
|
function priceRowsOf(usage, book) {
|
|
11234
11276
|
if (usage === void 0 || book === null) return [];
|
|
11235
11277
|
const rows = [];
|
|
11236
|
-
const multi = Object.keys(usage).length > 1;
|
|
11237
11278
|
for (const provider of Object.keys(usage)) {
|
|
11238
11279
|
const models = asRecord(usage[provider]);
|
|
11239
11280
|
/* v8 ignore next 1 -- the fold's inputs are mergeCostUsage's own output
|
|
@@ -11241,16 +11282,11 @@ window.__ModuleLoader__.load({
|
|
|
11241
11282
|
reaches here; the guard stays for the helper's own contract. */
|
|
11242
11283
|
if (models === null) continue;
|
|
11243
11284
|
for (const model of Object.keys(models)) {
|
|
11244
|
-
const
|
|
11245
|
-
if (
|
|
11246
|
-
const periods = asRecord(models[model]);
|
|
11247
|
-
const deepseek = isDeepSeekProvider(provider);
|
|
11248
|
-
const billedOff = deepseek && periods !== null && periods.off !== void 0;
|
|
11285
|
+
const face = priceFaceOf(book, provider, model);
|
|
11286
|
+
if (face === null) continue;
|
|
11249
11287
|
rows.push({
|
|
11250
11288
|
key: provider + "/" + model,
|
|
11251
|
-
|
|
11252
|
-
rate: deepseek ? peakOf(rate) : rate,
|
|
11253
|
-
...billedOff ? { offRate: rate } : {}
|
|
11289
|
+
face
|
|
11254
11290
|
});
|
|
11255
11291
|
}
|
|
11256
11292
|
}
|
|
@@ -11314,62 +11350,50 @@ window.__ModuleLoader__.load({
|
|
|
11314
11350
|
const subCost = estimateSessionCost(subUsage, book, currency);
|
|
11315
11351
|
const fmtRate = (usd) => formatPriceRate(toCurrency(usd, currency), currency);
|
|
11316
11352
|
const rows = priceRowsOf(usage, book);
|
|
11353
|
+
const subRows = priceRowsOf(subUsage ?? void 0, book);
|
|
11317
11354
|
const deepseek = usage !== void 0 && Object.keys(usage).some((p) => isDeepSeekProvider(p));
|
|
11318
11355
|
const subDeepseek = subUsage !== null && Object.keys(subUsage).some((p) => isDeepSeekProvider(p));
|
|
11319
|
-
const anyPair = rows.some((r) => r.offRate !== void 0);
|
|
11320
11356
|
const unpriced = rows.length === 0 && usage !== void 0 && Object.keys(usage).length > 0 && (failed || book !== null);
|
|
11321
|
-
const subUnpriced =
|
|
11322
|
-
const
|
|
11323
|
-
|
|
11324
|
-
|
|
11325
|
-
className: "lc-stat-tip-
|
|
11326
|
-
children:
|
|
11327
|
-
|
|
11328
|
-
|
|
11329
|
-
|
|
11330
|
-
|
|
11331
|
-
|
|
11332
|
-
|
|
11333
|
-
|
|
11334
|
-
|
|
11335
|
-
|
|
11336
|
-
|
|
11337
|
-
|
|
11338
|
-
|
|
11339
|
-
|
|
11340
|
-
|
|
11341
|
-
|
|
11342
|
-
t("stats.costWrite"),
|
|
11343
|
-
r.rate.write,
|
|
11344
|
-
r.offRate?.write
|
|
11345
|
-
],
|
|
11346
|
-
[
|
|
11347
|
-
t("stats.costOut"),
|
|
11348
|
-
r.rate.out,
|
|
11349
|
-
r.offRate?.out
|
|
11350
|
-
]
|
|
11351
|
-
];
|
|
11352
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
11353
|
-
className: "lc-stat-tip-row",
|
|
11354
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", {
|
|
11355
|
-
className: "lc-stat-tip-model",
|
|
11356
|
-
children: r.label
|
|
11357
|
-
}), cells.map(([name, peak, off]) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
|
|
11358
|
-
" · ",
|
|
11359
|
-
name,
|
|
11360
|
-
" ",
|
|
11361
|
-
off === void 0 ? fmtRate(peak) : `${fmtRate(peak)}|${fmtRate(off)}`
|
|
11362
|
-
] }, name))]
|
|
11363
|
-
}, r.key);
|
|
11357
|
+
const subUnpriced = subRows.length === 0 && subUsage !== null && (failed || book !== null);
|
|
11358
|
+
const pricesBlock = (blocks) => blocks.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
11359
|
+
className: "lc-stat-tip-prices",
|
|
11360
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
11361
|
+
className: "lc-stat-tip-head",
|
|
11362
|
+
children: t("stats.costPriceHead")
|
|
11363
|
+
}), blocks.map((r) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
11364
|
+
className: "lc-stat-tip-row",
|
|
11365
|
+
children: [BANDS.filter(([bucket]) => r.face.rate[bucket] > 0).map(([bucket, label]) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
11366
|
+
className: "lc-stat-tip-band",
|
|
11367
|
+
children: [
|
|
11368
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("i", { children: t(label) }),
|
|
11369
|
+
" ",
|
|
11370
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: fmtRate(r.face.rate[bucket]) })
|
|
11371
|
+
]
|
|
11372
|
+
}, bucket)), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
11373
|
+
className: "lc-stat-tip-by",
|
|
11374
|
+
children: t("stats.costPriceBy", {
|
|
11375
|
+
p: r.face.pid,
|
|
11376
|
+
m: r.face.mid
|
|
11377
|
+
})
|
|
11364
11378
|
})]
|
|
11365
|
-
},
|
|
11379
|
+
}, r.key))]
|
|
11380
|
+
}, "prices") : null;
|
|
11381
|
+
const notes = (deep) => [currency === "cny" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("stats.costTipCny") }, "cny") : null, deep ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("stats.costTipDeepseek") }, "peak") : null].filter((el) => el !== null);
|
|
11382
|
+
const costTip = [
|
|
11383
|
+
t("stats.costTip"),
|
|
11384
|
+
pricesBlock(rows),
|
|
11385
|
+
...notes(deepseek),
|
|
11366
11386
|
unpriced ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("stats.costUnavailable") }, "unavailable") : null
|
|
11367
11387
|
];
|
|
11368
|
-
const subTip = [
|
|
11388
|
+
const subTip = [
|
|
11389
|
+
t("stats.subCostTip"),
|
|
11390
|
+
pricesBlock(subRows),
|
|
11391
|
+
...notes(subDeepseek),
|
|
11392
|
+
subUnpriced ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("stats.costUnavailable") }, "unavailable") : null
|
|
11393
|
+
];
|
|
11369
11394
|
const hit = props.usage === null ? null : cacheHitPercent(numOf(props.usage.cacheReadTokens), numOf(props.usage.uncachedInputTokens) + numOf(props.usage.cacheReadTokens) + numOf(props.usage.cacheWriteTokens));
|
|
11370
|
-
const cell = (label, value, tip) =>
|
|
11371
|
-
|
|
11372
|
-
children: [
|
|
11395
|
+
const cell = (label, value, tip, href) => {
|
|
11396
|
+
const body = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
11373
11397
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
11374
11398
|
className: "lc-stat-label",
|
|
11375
11399
|
children: [label, tip !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("i", {
|
|
@@ -11387,8 +11411,21 @@ window.__ModuleLoader__.load({
|
|
|
11387
11411
|
role: "tooltip",
|
|
11388
11412
|
children: tip
|
|
11389
11413
|
})
|
|
11390
|
-
]
|
|
11391
|
-
|
|
11414
|
+
] });
|
|
11415
|
+
const className = "lc-stat" + (tip === void 0 ? "" : " lc-stat-tipped group/tip");
|
|
11416
|
+
return href === void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
11417
|
+
className,
|
|
11418
|
+
children: body
|
|
11419
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
|
|
11420
|
+
className,
|
|
11421
|
+
href,
|
|
11422
|
+
target: "_blank",
|
|
11423
|
+
rel: "noreferrer noopener",
|
|
11424
|
+
children: body
|
|
11425
|
+
});
|
|
11426
|
+
};
|
|
11427
|
+
const costPids = new Set(rows.map((r) => r.face.pid).filter((p) => p !== ""));
|
|
11428
|
+
const costHref = costPids.size === 1 ? "https://models.dev/providers/" + [...costPids][0] + "/" : void 0;
|
|
11392
11429
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
11393
11430
|
className: "lc-card lc-col-stats flex-[3] min-w-[min(360px,100%)]",
|
|
11394
11431
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
@@ -11405,7 +11442,7 @@ window.__ModuleLoader__.load({
|
|
|
11405
11442
|
cell(t("stats.humanInputs"), props.humanInputs ?? 0, t("stats.humanInputsTip")),
|
|
11406
11443
|
cell(t("stats.toolCalls"), props.toolCalls ?? 0),
|
|
11407
11444
|
cell(t("stats.cacheHit"), hit === null ? "—" : `${hit}%`, t("stats.cacheHitTip")),
|
|
11408
|
-
cell(t("stats.cost"), cost === null ? "—" : formatCost(cost, currency), costTip),
|
|
11445
|
+
cell(t("stats.cost"), cost === null ? "—" : formatCost(cost, currency), costTip, costHref),
|
|
11409
11446
|
cell(t("stats.subCost"), subCost === null ? "—" : formatCost(subCost, currency), subTip)
|
|
11410
11447
|
]
|
|
11411
11448
|
})]
|
|
@@ -12320,7 +12357,7 @@ window.__ModuleLoader__.load({
|
|
|
12320
12357
|
}
|
|
12321
12358
|
//#endregion
|
|
12322
12359
|
//#region \0dsh-global-css:/home/runner/work/dsh-context/dsh-context/src/client/styles/stats.css.mjs
|
|
12323
|
-
const css$13 = ".lc-stat{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:8px;flex-direction:column;gap:2px;min-width:0;padding:6px;display:flex}.lc-stats .lc-stat{padding:6px 3px}.lc-stats .lc-stat-q{margin:0;position:absolute;top:3px;right:4px}.lc-stat-label{color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;font-size:11px;font-weight:600;overflow:hidden}.lc-stat-value{color:var(--dsw-alias-label-primary);white-space:nowrap;text-overflow:ellipsis;text-align:center;font-size:14px;font-weight:600;overflow:hidden}.lc-stat-sub{color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;font-size:11px;overflow:hidden}.lc-stat-tipped{position:relative}.lc-stat-q{text-align:center;width:11px;height:11px;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l2);cursor:help;transition:color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out), border-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);border-radius:50%;margin-left:4px;font-size:9px;font-style:normal;font-weight:700;line-height:11px;display:inline-block}.lc-stat-tip{max-width:280px;font-weight:400;line-height:1.5;top:calc(100% + 6px);left:0}.lc-stat-tip-prices{border-top:1px dashed var(--dsw-alias-border-l1);margin-top:5px;padding-top:5px;display:block}.lc-stat-tip-head{font-weight:600;display:block}.lc-timing-tps{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);font-variant-numeric:tabular-nums;cursor:default;border-radius:999px;flex:none;margin-left:auto;padding:1px 8px;font-size:12px;line-height:18px}.lc-stat-tip-row{margin-top:2px;display:block}.lc-stat-tip-
|
|
12360
|
+
const css$13 = ".lc-stat{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:8px;flex-direction:column;gap:2px;min-width:0;padding:6px;display:flex}a.lc-stat{color:inherit;cursor:pointer;text-decoration:none}a.lc-stat:hover{border-color:var(--dsw-alias-label-secondary)}.lc-stats .lc-stat{padding:6px 3px}.lc-stats .lc-stat-q{margin:0;position:absolute;top:3px;right:4px}.lc-stat-label{color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;font-size:11px;font-weight:600;overflow:hidden}.lc-stat-value{color:var(--dsw-alias-label-primary);white-space:nowrap;text-overflow:ellipsis;text-align:center;font-size:14px;font-weight:600;overflow:hidden}.lc-stat-sub{color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;font-size:11px;overflow:hidden}.lc-stat-tipped{position:relative}.lc-stat-q{text-align:center;width:11px;height:11px;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l2);cursor:help;transition:color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out), border-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);border-radius:50%;margin-left:4px;font-size:9px;font-style:normal;font-weight:700;line-height:11px;display:inline-block}.lc-stat-tip{max-width:280px;font-weight:400;line-height:1.5;top:calc(100% + 6px);left:0}.lc-stat-tip-prices{border-top:1px dashed var(--dsw-alias-border-l1);margin-top:5px;padding-top:5px;display:block}.lc-stat-tip-head{font-weight:600;display:block}.lc-timing-tps{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);font-variant-numeric:tabular-nums;cursor:default;border-radius:999px;flex:none;margin-left:auto;padding:1px 8px;font-size:12px;line-height:18px}.lc-stat-tip-row{margin-top:2px;display:block}.lc-stat-tip-band{justify-content:space-between;gap:2rem;display:flex}.lc-stat-tip-band i{font-style:normal}.lc-stat-tip-by{color:var(--dsw-alias-label-secondary);margin-top:3px;display:block}.lc-card-sub{color:var(--dsw-alias-label-secondary);margin-left:auto;font-size:12px;font-weight:400}.lc-overview-num{align-items:baseline;gap:6px;margin-bottom:8px;display:flex}.lc-overview-num>b{font-size:20px}.lc-overview-num span{color:var(--dsw-alias-label-secondary)}.lc-overview-pct{margin-left:auto;font-size:11px}.lc-overview-pct b{color:var(--dsw-alias-label-primary);margin-right:4px;font-size:20px}.lc-stat-head{color:var(--dsw-alias-label-secondary);margin:12px 0 8px;font-size:11px;font-weight:600}.lc-col-donut{flex-direction:column;display:flex}.lc-col-donut .lc-donut-row{flex:1}.lc-donut{flex:none;position:relative}.lc-donut svg{display:block}.lc-donut-track{stroke:color-mix(in srgb, var(--color-neutral-500) 18%, transparent)}.lc-donut-seg{transition:opacity var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out)}.lc-donut-dim .lc-donut-seg{opacity:.35}.lc-donut-dim .lc-donut-seg-on{opacity:1}.lc-donut-center{pointer-events:none;text-align:center;box-sizing:border-box;flex-direction:column;justify-content:center;align-items:center;gap:1px;padding:0 7px;display:flex;position:absolute;inset:0}.lc-donut-center b{white-space:nowrap;text-overflow:ellipsis;max-width:100%;line-height:1.15;overflow:hidden}.lc-donut-center span{color:var(--dsw-alias-label-secondary);white-space:nowrap}.lc-sl{grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:4px 20px;min-width:0;display:grid;overflow:hidden}.lc-sl-row{min-width:0;transition:background-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);border-radius:6px;flex-direction:column;gap:1px;margin:0 -6px;padding:1px 6px;font-size:12px;display:flex}.lc-sl-row-on{background:var(--dsw-alias-interactive-bg-hover)}.lc-sl-row-dim{opacity:.55}.lc-sl-main{align-items:center;gap:6px;min-width:0;display:flex}.lc-sl-dot{border-radius:2px;flex:none;width:8px;height:8px}.lc-sl-label{white-space:nowrap;text-overflow:ellipsis;flex:auto;min-width:0;font-weight:600;line-height:1.25;overflow:hidden}.lc-sl-pct{text-align:right;font-variant-numeric:tabular-nums;flex:none;min-width:34px;font-weight:700}.lc-sl-sub{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;white-space:nowrap;text-overflow:ellipsis;margin-left:14px;font-size:11px;line-height:1.3;overflow:hidden}.lc-pi-grid{grid-template-columns:1fr;gap:8px;display:grid}.lc-pi-row-btn{appearance:none;font:inherit;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;width:100%;padding:0}.lc-pi-row{min-width:0;color:inherit;flex-direction:row;justify-content:space-between;align-items:baseline;gap:12px;text-decoration:none;display:flex}.lc-pi-hint{text-decoration:none}.lc-pi-update{color:var(--dsw-alias-state-warn-primary);white-space:nowrap;margin-left:6px;font-size:11px}.lc-pi-label{color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;flex:none;font-size:11px;font-weight:600;overflow:hidden}.lc-pi-labelicon{vertical-align:-2px;margin-right:4px;display:inline-block}.lc-pi-value{min-width:0;color:var(--dsw-alias-label-primary);white-space:nowrap;text-overflow:ellipsis;text-align:right;font-size:13px;font-weight:600;overflow:hidden}";
|
|
12324
12361
|
const tagId$13 = "dsh-context/stats.css";
|
|
12325
12362
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$13) + "]") === null) {
|
|
12326
12363
|
const tag = document.createElement("style");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-context",
|
|
3
|
-
"version": "0.59.
|
|
3
|
+
"version": "0.59.1",
|
|
4
4
|
"description": "A DeepSeek Harness plugin for context insight and management, with context dashboard and context command, for understanding how the context is made of, and how it evolves.",
|
|
5
5
|
"icon": "icon.svg",
|
|
6
6
|
"author": "bowenliang123",
|