tokentracker-cli 0.97.2 → 0.99.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/dashboard/dist/assets/AchievementBadge-kRsjlB3p.js +1 -0
- package/dashboard/dist/assets/{AchievementsPage-CnkSNpJx.js → AchievementsPage-C3xybY0k.js} +2 -2
- package/dashboard/dist/assets/AchievementsSection-y5mok2w0.js +1 -0
- package/dashboard/dist/assets/{BadgeDetailModal-BJBrgn24.js → BadgeDetailModal-IFLXYuKp.js} +1 -1
- package/dashboard/dist/assets/{BotAnimated-BJM20N9T.js → BotAnimated-D6x0PDt2.js} +1 -1
- package/dashboard/dist/assets/{Card-BRWOMoBk.js → Card-CiKwEyVu.js} +1 -1
- package/dashboard/dist/assets/{ClawdAnimated-CtX8cne4.js → ClawdAnimated-BQFcAIOy.js} +2 -2
- package/dashboard/dist/assets/CommandPalette-BvpX8PM_.js +1 -0
- package/dashboard/dist/assets/CommunityStatsModal-D5rNlwfO.js +1 -0
- package/dashboard/dist/assets/{ConfirmModal-ZZXg_OLV.js → ConfirmModal-CR0Evu8-.js} +1 -1
- package/dashboard/dist/assets/{Controls-VDvgw_ed.js → Controls-lyLUkbJW.js} +1 -1
- package/dashboard/dist/assets/DashboardPage-X8CLr_au.js +1 -0
- package/dashboard/dist/assets/{DevicePage-CP5m8azV.js → DevicePage-RCIANm45.js} +1 -1
- package/dashboard/dist/assets/{DialogClose-8pTCallP.js → DialogClose-Bplj_718.js} +1 -1
- package/dashboard/dist/assets/DialogDescription-C2EzE7DU.js +1 -0
- package/dashboard/dist/assets/{DialogTitle-BWYdq4TT.js → DialogTitle-Ckzf1tdi.js} +1 -1
- package/dashboard/dist/assets/{FadeIn-CEJfaKnL.js → FadeIn-C2Jqe95f.js} +1 -1
- package/dashboard/dist/assets/{HeaderGithubStar-Bg2vijF8.js → HeaderGithubStar-DgE7Cd5u.js} +1 -1
- package/dashboard/dist/assets/{HoverTooltip-B03JQ3PO.js → HoverTooltip-CEmo0N-P.js} +1 -1
- package/dashboard/dist/assets/{IpCheckPage-DYZucBOf.js → IpCheckPage-BwkpsLaF.js} +1 -1
- package/dashboard/dist/assets/{LandingPage-m-byhnVx.js → LandingPage-CA2klwbE.js} +2 -2
- package/dashboard/dist/assets/{LeaderboardAvatar-JtGhJC1s.js → LeaderboardAvatar-B_PUenGZ.js} +1 -1
- package/dashboard/dist/assets/LeaderboardPage-D6HGW3jX.js +2 -0
- package/dashboard/dist/assets/{LeaderboardProfileModal-Cm4DDrcY.js → LeaderboardProfileModal-Bfo1dSsS.js} +4 -4
- package/dashboard/dist/assets/{LeaderboardProfilePage-bKbMm856.js → LeaderboardProfilePage-2OqwrqOs.js} +1 -1
- package/dashboard/dist/assets/{LimitsPage-B271tZOj.js → LimitsPage-BHrkLXHZ.js} +5 -5
- package/dashboard/dist/assets/{LocalOnlyNotice-DKIxuBP0.js → LocalOnlyNotice-C45MmWYt.js} +1 -1
- package/dashboard/dist/assets/LoginCard-BikBibax.js +1 -0
- package/dashboard/dist/assets/{LoginModal-PxTgIoLk.js → LoginModal-D0Aq85Zg.js} +1 -1
- package/dashboard/dist/assets/{LoginPage-uEUnU7NP.js → LoginPage-B-kQaDQ_.js} +1 -1
- package/dashboard/dist/assets/PetPage-ZgPREiwD.js +1 -0
- package/dashboard/dist/assets/{PopoverPopup-DWIMb8D6.js → PopoverPopup-eQgg3h1i.js} +1 -1
- package/dashboard/dist/assets/{ProviderIcon-DqqwXu3b.js → ProviderIcon-nDBPxn0N.js} +1 -1
- package/dashboard/dist/assets/{ResetPasswordPage-BVuJTR9A.js → ResetPasswordPage-CjsOtiGr.js} +1 -1
- package/dashboard/dist/assets/{SegmentedControl-iHtWKWtc.js → SegmentedControl-6NcttkEH.js} +1 -1
- package/dashboard/dist/assets/{Select-Cr9wq8mD.js → Select-CzEhPICe.js} +1 -1
- package/dashboard/dist/assets/{SelectItemText-BWnP4yuq.js → SelectItemText-BwvzfXwj.js} +1 -1
- package/dashboard/dist/assets/{ServiceStatusPage-DLuiUUYV.js → ServiceStatusPage-C35wpxrT.js} +1 -1
- package/dashboard/dist/assets/{SessionsPage-CBAH4ieT.js → SessionsPage-a30adkhf.js} +2 -2
- package/dashboard/dist/assets/SettingsPage-C_7ZPBUF.js +2 -0
- package/dashboard/dist/assets/SkillsPage-DsxkFnrV.js +1 -0
- package/dashboard/dist/assets/TokenGalaxy-D_bXRotA.js +4426 -0
- package/dashboard/dist/assets/ToolbarRootContext-CL7ma7ba.js +1 -0
- package/dashboard/dist/assets/{TrendMonitor-CCzwGDst.js → TrendMonitor-QZBF2IEY.js} +1 -1
- package/dashboard/dist/assets/{WidgetsPage-CcWCidAd.js → WidgetsPage-CWlxR0H-.js} +1 -1
- package/dashboard/dist/assets/{WrappedPage-B6dn8eyh.js → WrappedPage-D8XQ72nF.js} +1 -1
- package/dashboard/dist/assets/__vite-browser-external-CTGqjrCe.js +45 -0
- package/dashboard/dist/assets/{agent-logos-Dh2k8E_G.js → agent-logos-BscA25fS.js} +1 -1
- package/dashboard/dist/assets/arrow-up-right-DTxCEGbR.js +1 -0
- package/dashboard/dist/assets/check-CCEoh2wj.js +1 -0
- package/dashboard/dist/assets/{composite-CSBcryzA.js → composite-B2s880f5.js} +1 -1
- package/dashboard/dist/assets/copy-CJVQglwG.js +1 -0
- package/dashboard/dist/assets/download-Cn-OpYm6.js +1 -0
- package/dashboard/dist/assets/external-link-BnYlUn56.js +1 -0
- package/dashboard/dist/assets/flame-D4yFLV1L.js +1 -0
- package/dashboard/dist/assets/{format-tokens-CqiCmYtk.js → format-tokens-CBUNbBvp.js} +1 -1
- package/dashboard/dist/assets/{icons-DD8OvYVG.js → icons-CcgNgAvb.js} +1 -1
- package/dashboard/dist/assets/{index-DLLivlEh.js → index-CTjeDkbu.js} +1 -1
- package/dashboard/dist/assets/{index-21lDN4rA.js → index-CkELwUyg.js} +1 -1
- package/dashboard/dist/assets/{index-Cm8jn8Va.js → index-ZWeEKbo-.js} +1 -1
- package/dashboard/dist/assets/info-DoehRSQU.js +1 -0
- package/dashboard/dist/assets/link-2-D8xSsPqy.js +1 -0
- package/dashboard/dist/assets/loader-circle-DMu0-X5r.js +1 -0
- package/dashboard/dist/assets/maximize-2-DLyYsZvE.js +1 -0
- package/dashboard/dist/assets/{modifiers.esm-Cwj0l9Zb.js → modifiers.esm-Dm5Xy2jA.js} +1 -1
- package/dashboard/dist/assets/module-B5tW98jG.js +3 -0
- package/dashboard/dist/assets/monitor-smartphone-5uZGQNGJ.js +1 -0
- package/dashboard/dist/assets/plus-8fnU0dkt.js +1 -0
- package/dashboard/dist/assets/provider-display-B3ed-pSc.js +42 -0
- package/dashboard/dist/assets/{react-xH4nkyuj.js → react-Gft01KYk.js} +1 -1
- package/dashboard/dist/assets/search-jqzJg2kG.js +1 -0
- package/dashboard/dist/assets/{skills-api-B7lb1cjO.js → skills-api-Bwn_xcHV.js} +1 -1
- package/dashboard/dist/assets/{sortable.esm-BUPRsWL6.js → sortable.esm-CYjzLCp7.js} +1 -1
- package/dashboard/dist/assets/{store-DneqOW0h.js → store-CgJHe9jU.js} +1 -1
- package/dashboard/dist/assets/terminal-CZ5j8yEQ.js +1 -0
- package/dashboard/dist/assets/trash-DtMLjI_S.js +1 -0
- package/dashboard/dist/assets/{use-community-stats-DB98TGn9.js → use-community-stats-Px3dHGlR.js} +1 -1
- package/dashboard/dist/assets/{use-latest-request-guard-DK3KulKx.js → use-latest-request-guard-B7Vw4Wsd.js} +1 -1
- package/dashboard/dist/assets/{use-limits-display-prefs-BACCRUMZ.js → use-limits-display-prefs-DWWrcMPi.js} +1 -1
- package/dashboard/dist/assets/{use-ordered-list-DnKFdI9a.js → use-ordered-list-CevbB79U.js} +1 -1
- package/dashboard/dist/assets/use-reduced-motion-CCuEY-79.js +1 -0
- package/dashboard/dist/assets/use-session-efficiency-pref-DoIaI0vm.js +1 -0
- package/dashboard/dist/assets/{use-transform-DweC2iKa.js → use-transform-qRwUetOk.js} +1 -1
- package/dashboard/dist/assets/{use-usage-limits-CN5xWIBs.js → use-usage-limits-DlP7yg78.js} +1 -1
- package/dashboard/dist/assets/{useCurrency-CFjvWawL.js → useCurrency-DRUe8YoY.js} +1 -1
- package/dashboard/dist/assets/{useTokenFormat-Cf81HqWi.js → useTokenFormat-CmLbznUC.js} +1 -1
- package/dashboard/dist/assets/zap-CS80c_uN.js +1 -0
- package/dashboard/dist/index.html +1 -1
- package/dashboard/dist/ip-check.html +1 -1
- package/dashboard/dist/leaderboard.html +1 -1
- package/dashboard/dist/share.html +1 -1
- package/package.json +1 -1
- package/src/commands/sync.js +15 -4
- package/src/lib/cloud-account.js +120 -1
- package/src/lib/grok-limits.js +37 -0
- package/src/lib/heatmap-compact.js +114 -0
- package/src/lib/local-api.js +11 -10
- package/src/lib/opencode-config.js +20 -1
- package/src/lib/pricing/curated-overrides.json +22 -0
- package/src/lib/pricing/index.js +2 -0
- package/src/lib/pricing/seed-snapshot.json +1 -1
- package/src/lib/rollout.js +1085 -146
- package/src/lib/usage-limits.js +7 -1
- package/dashboard/dist/assets/AchievementBadge-Bf2T612R.js +0 -1
- package/dashboard/dist/assets/AchievementsSection-CPwsy04Y.js +0 -1
- package/dashboard/dist/assets/CommandPalette-C8BwOnSn.js +0 -1
- package/dashboard/dist/assets/CommunityStatsModal-BGMbgSjq.js +0 -1
- package/dashboard/dist/assets/DashboardPage-BcJGzQWK.js +0 -1
- package/dashboard/dist/assets/DialogDescription-DRQEfAWH.js +0 -1
- package/dashboard/dist/assets/LeaderboardPage-vVDKFLhl.js +0 -2
- package/dashboard/dist/assets/LoginCard-DA46RXDo.js +0 -1
- package/dashboard/dist/assets/PetPage-DDPZtxMw.js +0 -1
- package/dashboard/dist/assets/SettingsPage-Djku-i8K.js +0 -2
- package/dashboard/dist/assets/SkillsPage-DtBRoB8R.js +0 -1
- package/dashboard/dist/assets/TokenGalaxy-nvyPu5eV.js +0 -4314
- package/dashboard/dist/assets/ToolbarRootContext-DhpHv55w.js +0 -1
- package/dashboard/dist/assets/__vite-browser-external-sJsF0ioo.js +0 -45
- package/dashboard/dist/assets/arrow-up-right-BLDQog1A.js +0 -1
- package/dashboard/dist/assets/check-DNq_ySSn.js +0 -1
- package/dashboard/dist/assets/copy-DHRrNtRb.js +0 -1
- package/dashboard/dist/assets/download-CluyujgG.js +0 -1
- package/dashboard/dist/assets/external-link-Cf12tdLf.js +0 -1
- package/dashboard/dist/assets/flame-CJEYinxo.js +0 -1
- package/dashboard/dist/assets/info-dv3Y0z8Q.js +0 -1
- package/dashboard/dist/assets/link-2-CWHBxVuk.js +0 -1
- package/dashboard/dist/assets/loader-circle-9l5p9Dwa.js +0 -1
- package/dashboard/dist/assets/maximize-2-DQ2t3MJB.js +0 -1
- package/dashboard/dist/assets/module-DUSXqJtA.js +0 -3
- package/dashboard/dist/assets/monitor-smartphone-B-9at3iV.js +0 -1
- package/dashboard/dist/assets/plus-C_CTQjDD.js +0 -1
- package/dashboard/dist/assets/provider-display-XJQod7k9.js +0 -42
- package/dashboard/dist/assets/search-Ut41Fw1G.js +0 -1
- package/dashboard/dist/assets/terminal-DPQyZyHR.js +0 -1
- package/dashboard/dist/assets/trash-CVdV1bBR.js +0 -1
- package/dashboard/dist/assets/use-reduced-motion-BfdrKOsS.js +0 -1
- package/dashboard/dist/assets/use-session-efficiency-pref-BTm6RoSm.js +0 -1
- package/dashboard/dist/assets/zap-Vx_j5oJN.js +0 -1
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
// Expand the `format=compact` activity-heatmap payload back into the schema the
|
|
4
|
+
// dashboard, popover and widget already render.
|
|
5
|
+
//
|
|
6
|
+
// The heatmap is the single largest cloud read we serve: 2.55 GB/day on
|
|
7
|
+
// 2026-09-21, 31% of all egress, and 94% of it proxied through this CLI. The
|
|
8
|
+
// bytes were never the data — `account_heatmap_compact` hands the edge ~12 KB
|
|
9
|
+
// of sparse rows, and the edge blew that up to ~42 KB by materialising a
|
|
10
|
+
// 52-week × 7-day grid of five-key objects, where `billable_total_tokens`
|
|
11
|
+
// simply repeats `total_tokens` and `level` is derived from the window maximum.
|
|
12
|
+
//
|
|
13
|
+
// So the grid gets rebuilt here instead, one hop later, off the same sparse
|
|
14
|
+
// rows. The rendered payload is identical; it just stops crossing the network.
|
|
15
|
+
//
|
|
16
|
+
// Model names are the other half of it. A year of daily rows repeats the same
|
|
17
|
+
// ~160 names ~1900 times, which was 57% of even the sparse payload, so they are
|
|
18
|
+
// sent once in `model_names` and referenced by index from flat
|
|
19
|
+
// [index, tokens, index, tokens, ...] pairs.
|
|
20
|
+
//
|
|
21
|
+
// This mirrors the tail of dashboard/edge-patches/tokentracker-account-heatmap.ts
|
|
22
|
+
// step for step, including the details that look incidental but are not:
|
|
23
|
+
// coercion through Number(), last-row-wins on a repeated day, and `{}` (not
|
|
24
|
+
// null) for a present row whose models map is empty.
|
|
25
|
+
|
|
26
|
+
/** Next YYYY-MM-DD, treating the key as a UTC calendar day (same as the edge). */
|
|
27
|
+
function nextDayKey(dayKey) {
|
|
28
|
+
const d = new Date(`${dayKey}T00:00:00Z`);
|
|
29
|
+
d.setUTCDate(d.getUTCDate() + 1);
|
|
30
|
+
return d.toISOString().slice(0, 10);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const DAY_KEY_RE = /^\d{4}-\d{2}-\d{2}$/;
|
|
34
|
+
|
|
35
|
+
// 104 weeks is the edge's own `weeks` clamp; the guard is here so a malformed
|
|
36
|
+
// `to` cannot spin the grid loop forever.
|
|
37
|
+
const MAX_GRID_DAYS = 104 * 7 + 7;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @param {unknown} payload a `tokentracker-account-heatmap` response.
|
|
41
|
+
* @returns {unknown} the dense payload, or `payload` itself when it is not a
|
|
42
|
+
* well-formed compact response — which is also how a new CLI stays correct
|
|
43
|
+
* against an edge that predates the compact branch.
|
|
44
|
+
*/
|
|
45
|
+
function expandHeatmapCompact(payload) {
|
|
46
|
+
if (!payload || typeof payload !== "object") return payload;
|
|
47
|
+
if (payload.format !== "compact") return payload;
|
|
48
|
+
if (!Array.isArray(payload.days)) return payload;
|
|
49
|
+
// Without the dictionary the indices resolve to nothing and every model
|
|
50
|
+
// breakdown would render empty, so refuse the payload instead of silently
|
|
51
|
+
// dropping data.
|
|
52
|
+
if (!Array.isArray(payload.model_names)) return payload;
|
|
53
|
+
if (!DAY_KEY_RE.test(String(payload.from)) || !DAY_KEY_RE.test(String(payload.to))) return payload;
|
|
54
|
+
|
|
55
|
+
const names = payload.model_names;
|
|
56
|
+
const byDay = new Map();
|
|
57
|
+
for (const row of payload.days) {
|
|
58
|
+
if (!Array.isArray(row)) continue;
|
|
59
|
+
const [day, total, pairs] = row;
|
|
60
|
+
if (!DAY_KEY_RE.test(String(day))) continue;
|
|
61
|
+
const mdl = {};
|
|
62
|
+
if (Array.isArray(pairs)) {
|
|
63
|
+
// `i + 1 < length` drops a trailing index with no value rather than
|
|
64
|
+
// recording it as 0.
|
|
65
|
+
for (let i = 0; i + 1 < pairs.length; i += 2) {
|
|
66
|
+
const name = names[pairs[i]];
|
|
67
|
+
if (typeof name === "string") mdl[name] = Number(pairs[i + 1]) || 0;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
// Last row wins, as Map.set did on the edge.
|
|
71
|
+
byDay.set(String(day), { total: Number(total) || 0, models: mdl });
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const maxValue = Number(payload.max_value) || 0;
|
|
75
|
+
const levelOf = (v) => {
|
|
76
|
+
if (v <= 0) return 0;
|
|
77
|
+
if (maxValue === 0) return 1;
|
|
78
|
+
const r = v / maxValue;
|
|
79
|
+
if (r <= 0.25) return 1;
|
|
80
|
+
if (r <= 0.5) return 2;
|
|
81
|
+
if (r <= 0.75) return 3;
|
|
82
|
+
return 4;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const cells = [];
|
|
86
|
+
const to = String(payload.to);
|
|
87
|
+
let cursor = String(payload.from);
|
|
88
|
+
while (cursor <= to && cells.length < MAX_GRID_DAYS) {
|
|
89
|
+
const hit = byDay.get(cursor);
|
|
90
|
+
const total = hit ? hit.total : 0;
|
|
91
|
+
cells.push({
|
|
92
|
+
day: cursor,
|
|
93
|
+
total_tokens: total,
|
|
94
|
+
billable_total_tokens: total,
|
|
95
|
+
level: levelOf(total),
|
|
96
|
+
models: hit ? hit.models : null,
|
|
97
|
+
});
|
|
98
|
+
cursor = nextDayKey(cursor);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const weeks = [];
|
|
102
|
+
for (let i = 0; i < cells.length; i += 7) weeks.push(cells.slice(i, i + 7));
|
|
103
|
+
|
|
104
|
+
return {
|
|
105
|
+
from: payload.from,
|
|
106
|
+
to: payload.to,
|
|
107
|
+
week_starts_on: payload.week_starts_on,
|
|
108
|
+
active_days: payload.active_days,
|
|
109
|
+
streak_days: payload.streak_days,
|
|
110
|
+
weeks,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
module.exports = { expandHeatmapCompact };
|
package/src/lib/local-api.js
CHANGED
|
@@ -2380,20 +2380,21 @@ function createLocalApiHandler({ queuePath }) {
|
|
|
2380
2380
|
ma.totals.cached_input_tokens += row.cached_input_tokens || 0;
|
|
2381
2381
|
ma.totals.cache_creation_input_tokens += row.cache_creation_input_tokens || 0;
|
|
2382
2382
|
ma.totals.reasoning_output_tokens += row.reasoning_output_tokens || 0;
|
|
2383
|
-
|
|
2384
|
-
|
|
2383
|
+
// Price each row, exactly as aggregateByDay does for the hero (#653).
|
|
2384
|
+
// computeRowCost is not linear for models with a Fast tier or
|
|
2385
|
+
// long-context rates: priority_* / long_context_* mark a subset of the
|
|
2386
|
+
// base columns rather than adding volume, so they survive only while the
|
|
2387
|
+
// row is intact. Summing the base columns first and pricing once silently
|
|
2388
|
+
// dropped every premium — same tokens, fewer dollars than the hero.
|
|
2389
|
+
ma.totals.total_cost_usd = Number(ma.totals.total_cost_usd || 0) + computeRowCost(row);
|
|
2385
2390
|
}
|
|
2386
2391
|
|
|
2387
2392
|
const sources = Array.from(bySource.values()).map((s) => {
|
|
2388
2393
|
s.models = Array.from(s.models.values())
|
|
2389
|
-
.map((m) => {
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
source: s.source,
|
|
2394
|
-
});
|
|
2395
|
-
return { ...m, totals: { ...m.totals, total_cost_usd: cost.toFixed(6) } };
|
|
2396
|
-
})
|
|
2394
|
+
.map((m) => ({
|
|
2395
|
+
...m,
|
|
2396
|
+
totals: { ...m.totals, total_cost_usd: Number(m.totals.total_cost_usd || 0).toFixed(6) },
|
|
2397
|
+
}))
|
|
2397
2398
|
.sort((a, b) => b.totals.total_tokens - a.totals.total_tokens);
|
|
2398
2399
|
const sourceCost = s.models.reduce((sum, m) => sum + Number(m.totals.total_cost_usd), 0);
|
|
2399
2400
|
s.totals.total_cost_usd = sourceCost.toFixed(6);
|
|
@@ -26,7 +26,7 @@ function buildOpencodePlugin({ notifyPath }) {
|
|
|
26
26
|
return (
|
|
27
27
|
`// ${PLUGIN_MARKER}\n` +
|
|
28
28
|
`const notifyPath = ${JSON.stringify(safeNotifyPath)};\n` +
|
|
29
|
-
`
|
|
29
|
+
`const server = async ({ $ }) => {\n` +
|
|
30
30
|
` return {\n` +
|
|
31
31
|
` event: async ({ event }) => {\n` +
|
|
32
32
|
` if (!event || event.type !== ${JSON.stringify(DEFAULT_EVENT)}) return;\n` +
|
|
@@ -40,6 +40,25 @@ function buildOpencodePlugin({ notifyPath }) {
|
|
|
40
40
|
` } catch (_) {}\n` +
|
|
41
41
|
` }\n` +
|
|
42
42
|
` };\n` +
|
|
43
|
+
`};\n` +
|
|
44
|
+
// Three loaders read this one file (issue #646):
|
|
45
|
+
// * older opencode v1 takes the named export;
|
|
46
|
+
// * current v1 (verified on 1.18.30) requires a default export carrying
|
|
47
|
+
// `id` and `server()`, and rejects the file outright without them;
|
|
48
|
+
// * v2 requires a default export carrying `id` and `setup()`/`effect()`,
|
|
49
|
+
// and ignores `server()`.
|
|
50
|
+
// Emitting all three keeps a single generated file valid everywhere. v2's
|
|
51
|
+
// plugin context exposes no event stream and no shell (`@opencode-ai/plugin`
|
|
52
|
+
// v2 PluginContext is agent/aisdk/catalog/command/integration/reference/skill
|
|
53
|
+
// only), so there is nothing for `setup` to subscribe to -- it exists to make
|
|
54
|
+
// the plugin load instead of erroring on every startup. Usage itself does not
|
|
55
|
+
// depend on this hook: opencode rows are parsed from the on-disk storage and
|
|
56
|
+
// opencode.db, and the hook only makes a sync happen sooner.
|
|
57
|
+
`export const TokenTrackerPlugin = server;\n` +
|
|
58
|
+
`export default {\n` +
|
|
59
|
+
` id: "tokentracker",\n` +
|
|
60
|
+
` server,\n` +
|
|
61
|
+
` setup: async () => {},\n` +
|
|
43
62
|
`};\n`
|
|
44
63
|
);
|
|
45
64
|
}
|
|
@@ -159,6 +159,20 @@
|
|
|
159
159
|
"cache_read": 0.014,
|
|
160
160
|
"cache_write": 0.44
|
|
161
161
|
},
|
|
162
|
+
"deepseek-v4.1-flash": {
|
|
163
|
+
"input": 0.3,
|
|
164
|
+
"output": 1.2,
|
|
165
|
+
"cache_read": 0.006,
|
|
166
|
+
"cache_write": 0.3,
|
|
167
|
+
"note": "DeepSeek V4.1 Flash (official API id deepseek-flash, released 2026-09-10). deepseek-v4.1-flash is the id reported by OpenRouter, Command Code and WorkBuddy. Peak rates per https://api-docs.deepseek.com/quick_start/pricing/ ($0.30 / $1.20 / $0.006 cache read per MTok); computeRowCost halves them off-peak like the other DeepSeek V4 entries."
|
|
168
|
+
},
|
|
169
|
+
"deepseek-flash": {
|
|
170
|
+
"input": 0.3,
|
|
171
|
+
"output": 1.2,
|
|
172
|
+
"cache_read": 0.006,
|
|
173
|
+
"cache_write": 0.3,
|
|
174
|
+
"note": "Official DeepSeek API id for DeepSeek-V4.1-Flash. Same rates as deepseek-v4.1-flash."
|
|
175
|
+
},
|
|
162
176
|
"deepseek-chat": {
|
|
163
177
|
"input": 0.14,
|
|
164
178
|
"output": 0.28,
|
|
@@ -544,6 +558,14 @@
|
|
|
544
558
|
"match": "minimax-m2.7",
|
|
545
559
|
"ref": "MiniMax-M2.7"
|
|
546
560
|
},
|
|
561
|
+
{
|
|
562
|
+
"match": "deepseek-v4.1-flash",
|
|
563
|
+
"ref": "deepseek-v4.1-flash"
|
|
564
|
+
},
|
|
565
|
+
{
|
|
566
|
+
"match": "deepseek-flash",
|
|
567
|
+
"ref": "deepseek-flash"
|
|
568
|
+
},
|
|
547
569
|
{
|
|
548
570
|
"match": "deepseek-v4-flash",
|
|
549
571
|
"ref": "deepseek-v4-flash"
|
package/src/lib/pricing/index.js
CHANGED
|
@@ -33,6 +33,8 @@ const SOURCES_WITH_AUTHORITATIVE_COST = new Set(["grok"]);
|
|
|
33
33
|
const SEED_SNAPSHOT_PATH = path.resolve(__dirname, "seed-snapshot.json");
|
|
34
34
|
const DEEPSEEK_TIME_PRICED_MODELS = [
|
|
35
35
|
"deepseek-v4-flash",
|
|
36
|
+
"deepseek-v4.1-flash",
|
|
37
|
+
"deepseek-flash",
|
|
36
38
|
"deepseek-v4-pro",
|
|
37
39
|
];
|
|
38
40
|
// Sync seed load. Done at require-time so callers that haven't awaited
|