tokentracker-cli 0.95.2 → 0.96.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-DtB1MwFe.js → AchievementBadge-Bb2ljquW.js} +1 -1
- package/dashboard/dist/assets/{AchievementsPage--vddu0dC.js → AchievementsPage-ByUP2x8a.js} +2 -2
- package/dashboard/dist/assets/{AchievementsSection-CDl9hsbj.js → AchievementsSection-_L6sCLTw.js} +1 -1
- package/dashboard/dist/assets/{BadgeDetailModal-C7WsIRy9.js → BadgeDetailModal-B9n_-45B.js} +1 -1
- package/dashboard/dist/assets/{BotAnimated-CmXyzIhX.js → BotAnimated-lWmg-aZg.js} +1 -1
- package/dashboard/dist/assets/{Card-SUbC3VNS.js → Card-aSp259T0.js} +1 -1
- package/dashboard/dist/assets/{ClawdAnimated-BdEbs8Me.js → ClawdAnimated-Cy-XaTXW.js} +2 -2
- package/dashboard/dist/assets/{CommandPalette-D1RLLeHB.js → CommandPalette-CNwtKCUm.js} +1 -1
- package/dashboard/dist/assets/{CommunityStatsModal-5ESGJgZQ.js → CommunityStatsModal-DJSezaPV.js} +1 -1
- package/dashboard/dist/assets/{ConfirmModal-DsCd51b2.js → ConfirmModal-CVjmhZd6.js} +1 -1
- package/dashboard/dist/assets/{Controls-BVrLC_QD.js → Controls-BIj6yVxE.js} +1 -1
- package/dashboard/dist/assets/{DashboardPage-DtUOG6og.js → DashboardPage-BjYZLmqQ.js} +1 -1
- package/dashboard/dist/assets/{DevicePage-zYjj-m5V.js → DevicePage-ptsI2fZc.js} +1 -1
- package/dashboard/dist/assets/{DialogClose-D66yBqkd.js → DialogClose-D1pLoZ56.js} +1 -1
- package/dashboard/dist/assets/DialogDescription-KY7X94CG.js +1 -0
- package/dashboard/dist/assets/{DialogTitle-C4ia00lc.js → DialogTitle-DfSBUjWf.js} +1 -1
- package/dashboard/dist/assets/{FadeIn-DF2c8XaR.js → FadeIn-DBn4L_BV.js} +1 -1
- package/dashboard/dist/assets/{HeaderGithubStar-Cnr3aqcX.js → HeaderGithubStar-EJLBwEqp.js} +1 -1
- package/dashboard/dist/assets/{HoverTooltip-DBOpxlH7.js → HoverTooltip-DaSrZhYd.js} +1 -1
- package/dashboard/dist/assets/{IpCheckPage-CUY6KBaV.js → IpCheckPage-diQTVaYt.js} +1 -1
- package/dashboard/dist/assets/{LandingPage-DKL8hZEq.js → LandingPage-BqCxjwar.js} +2 -2
- package/dashboard/dist/assets/{LeaderboardAvatar-DRYeMNlq.js → LeaderboardAvatar-CQImCsPN.js} +1 -1
- package/dashboard/dist/assets/{LeaderboardPage-DpD9Az3k.js → LeaderboardPage-D2ZDUi_O.js} +2 -2
- package/dashboard/dist/assets/{LeaderboardProfileModal-Dfg0V13F.js → LeaderboardProfileModal-DHvADX1d.js} +3 -3
- package/dashboard/dist/assets/{LeaderboardProfilePage-DH-jcVDu.js → LeaderboardProfilePage-CJsedB28.js} +1 -1
- package/dashboard/dist/assets/LimitsPage-CAwff24b.js +6 -0
- package/dashboard/dist/assets/{LocalOnlyNotice-Bj_m0hw7.js → LocalOnlyNotice-Cmnvu9tI.js} +1 -1
- package/dashboard/dist/assets/{LoginCard-BVKvtx60.js → LoginCard-BQmKkD7X.js} +1 -1
- package/dashboard/dist/assets/{LoginModal-mUGiSIJN.js → LoginModal-2oPROePZ.js} +1 -1
- package/dashboard/dist/assets/{LoginPage-BORCuCUt.js → LoginPage-aqdUJoQK.js} +1 -1
- package/dashboard/dist/assets/{PetPage-D1JfEOVA.js → PetPage-Bn3p_o5r.js} +1 -1
- package/dashboard/dist/assets/{PopoverPopup-DK3et-HG.js → PopoverPopup-DXD_YdiB.js} +1 -1
- package/dashboard/dist/assets/{ProviderIcon-By8FAjxR.js → ProviderIcon-BZZ45-gY.js} +1 -1
- package/dashboard/dist/assets/{ResetPasswordPage-DPa81jqa.js → ResetPasswordPage-Bn5ITiHQ.js} +1 -1
- package/dashboard/dist/assets/{SegmentedControl-DLzS-2eZ.js → SegmentedControl-hGXboQZy.js} +1 -1
- package/dashboard/dist/assets/{Select-C05W6XEM.js → Select-BP8aVRZ1.js} +1 -1
- package/dashboard/dist/assets/{SelectItemText-CcfB3blP.js → SelectItemText-Odx47kND.js} +1 -1
- package/dashboard/dist/assets/{ServiceStatusPage-ByqLbHv1.js → ServiceStatusPage-DUueam0N.js} +1 -1
- package/dashboard/dist/assets/SessionsPage-BA9IFqQ1.js +2 -0
- package/dashboard/dist/assets/{SettingsPage-DAcndJZQ.js → SettingsPage-DLOHHB4f.js} +2 -2
- package/dashboard/dist/assets/{SkillsPage-BuuqQuNU.js → SkillsPage-Ds2vH_PG.js} +1 -1
- package/dashboard/dist/assets/{TokenGalaxy-DzccxkXW.js → TokenGalaxy-CWBR4jnB.js} +1 -1
- package/dashboard/dist/assets/{ToolbarRootContext-XUDMp5uy.js → ToolbarRootContext-Bmg56vYz.js} +1 -1
- package/dashboard/dist/assets/{TrendMonitor-B-yYabbz.js → TrendMonitor-BQzcllvg.js} +1 -1
- package/dashboard/dist/assets/{WidgetsPage-CwUDjEFo.js → WidgetsPage-Bu3tHDjO.js} +1 -1
- package/dashboard/dist/assets/{WrappedPage-Dr9ow3gH.js → WrappedPage-BrAMJhgy.js} +1 -1
- package/dashboard/dist/assets/{__vite-browser-external-DPOlUkcY.js → __vite-browser-external-4IGm4Djn.js} +12 -12
- package/dashboard/dist/assets/{agent-logos-Cqc_suYk.js → agent-logos-B8lT-HcI.js} +1 -1
- package/dashboard/dist/assets/{arrow-up-right-DSsR3Ntr.js → arrow-up-right-rpBCOTg2.js} +1 -1
- package/dashboard/dist/assets/{check-Cy35lAKh.js → check-DIKw7TYH.js} +1 -1
- package/dashboard/dist/assets/{composite-BDwOlhhX.js → composite-_NeXO0lv.js} +1 -1
- package/dashboard/dist/assets/{copy-4szu5cYh.js → copy-CsfAtL7P.js} +1 -1
- package/dashboard/dist/assets/{download-DdGW6Krz.js → download-DM1W9pIW.js} +1 -1
- package/dashboard/dist/assets/{external-link-DwSt83cq.js → external-link-CwbuMbeQ.js} +1 -1
- package/dashboard/dist/assets/{flame-DubukWqK.js → flame-DcYbLdhE.js} +1 -1
- package/dashboard/dist/assets/{format-tokens-B70EdQcN.js → format-tokens-CEvr3dNy.js} +1 -1
- package/dashboard/dist/assets/{icons-B86TLdAj.js → icons-DaGMVsJ5.js} +1 -1
- package/dashboard/dist/assets/{index-B_KMoBeK.js → index-BVVLPj3N.js} +1 -1
- package/dashboard/dist/assets/{index-DI-W-pun.js → index-ChZkJjpk.js} +1 -1
- package/dashboard/dist/assets/{index-DzEMcUwI.js → index-T7OjmEuX.js} +1 -1
- package/dashboard/dist/assets/{info-BzFpLbl6.js → info-CAjN3dX4.js} +1 -1
- package/dashboard/dist/assets/limits-providers-jn7Yln_V.js +1 -0
- package/dashboard/dist/assets/{link-2-BQp7-3T7.js → link-2-DaWH2Tyc.js} +1 -1
- package/dashboard/dist/assets/{loader-circle-lrDmbIg5.js → loader-circle-CnF8qPi1.js} +1 -1
- package/dashboard/dist/assets/{maximize-2-Cnd_Oth8.js → maximize-2-B-2Pnj6g.js} +1 -1
- package/dashboard/dist/assets/{modifiers.esm-CPTpZdHU.js → modifiers.esm-BoDOvUKl.js} +1 -1
- package/dashboard/dist/assets/{monitor-smartphone-C7UY1zRx.js → monitor-smartphone-DDgwxG_E.js} +1 -1
- package/dashboard/dist/assets/{plus-Bglp9N_7.js → plus-DIc1YUWB.js} +1 -1
- package/dashboard/dist/assets/{provider-display-CGsFySs6.js → provider-display-yeNsVCO_.js} +1 -1
- package/dashboard/dist/assets/{react-DKXriBSF.js → react-DZqS6YTX.js} +1 -1
- package/dashboard/dist/assets/{search-D_LLDRdU.js → search-D6tEppYJ.js} +1 -1
- package/dashboard/dist/assets/{skills-api-CJWjKIco.js → skills-api-vsA1rc1Z.js} +1 -1
- package/dashboard/dist/assets/{sortable.esm-zlY09tye.js → sortable.esm-DDCnS1HI.js} +1 -1
- package/dashboard/dist/assets/{store-8e16Ac2h.js → store-Crne4DqF.js} +1 -1
- package/dashboard/dist/assets/{terminal-CR228ekj.js → terminal-Ca7dkLMF.js} +1 -1
- package/dashboard/dist/assets/{trash-2-BjLWewOp.js → trash-2-CjEAS5ic.js} +1 -1
- package/dashboard/dist/assets/{use-community-stats-DhOJPaVg.js → use-community-stats-BHx2YxyK.js} +1 -1
- package/dashboard/dist/assets/{use-latest-request-guard-lcGhb-NC.js → use-latest-request-guard-BLGbXQdf.js} +1 -1
- package/dashboard/dist/assets/{use-limits-display-prefs-DJIImtLN.js → use-limits-display-prefs-DBkAp6ob.js} +1 -1
- package/dashboard/dist/assets/{use-ordered-list-BJZfZuoJ.js → use-ordered-list-BTfW5M9u.js} +1 -1
- package/dashboard/dist/assets/use-reduced-motion-D_kUnDs4.js +1 -0
- package/dashboard/dist/assets/{use-session-efficiency-pref-C-l4b1cD.js → use-session-efficiency-pref-DBmd-MqH.js} +1 -1
- package/dashboard/dist/assets/{use-transform-UjIt477N.js → use-transform-Bp5XrwaQ.js} +1 -1
- package/dashboard/dist/assets/{use-usage-limits-DqoTZrqT.js → use-usage-limits-BmqRcyhH.js} +1 -1
- package/dashboard/dist/assets/{useCurrency-CnM8aB4v.js → useCurrency-B0YsRDj-.js} +1 -1
- package/dashboard/dist/assets/{useTokenFormat-D4pAK2ld.js → useTokenFormat-PP3D0Ket.js} +1 -1
- package/dashboard/dist/assets/{zap-Du1IyEtj.js → zap-BVOm1aBH.js} +1 -1
- 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/lib/ark-agent-plan-limits.js +437 -0
- package/src/lib/ark-coding-plan-limits.js +104 -27
- package/src/lib/codex-model-attribution.js +128 -0
- package/src/lib/codex-rollout-parser.js +98 -4
- package/src/lib/pricing/curated-overrides.json +6 -6
- package/src/lib/pricing/index.js +38 -1
- package/src/lib/pricing/seed-snapshot.json +1 -1
- package/src/lib/rollout.js +50 -9
- package/src/lib/session-analytics.js +374 -110
- package/src/lib/usage-limits.js +19 -5
- package/dashboard/dist/assets/DialogDescription-BVlaoajd.js +0 -1
- package/dashboard/dist/assets/LimitsPage-CVCKPScf.js +0 -5
- package/dashboard/dist/assets/SessionsPage-CEDv1thj.js +0 -2
- package/dashboard/dist/assets/limits-providers-DxZOjiXQ.js +0 -1
- package/dashboard/dist/assets/use-reduced-motion-DdpxZQoh.js +0 -1
package/src/lib/rollout.js
CHANGED
|
@@ -15,6 +15,12 @@ const {
|
|
|
15
15
|
createUsageDeltaState,
|
|
16
16
|
snapshotUsageBaselines,
|
|
17
17
|
} = require("./codex-token-usage");
|
|
18
|
+
const {
|
|
19
|
+
applyCodexModelEvent,
|
|
20
|
+
createCodexModelAttributionState,
|
|
21
|
+
currentCodexModel,
|
|
22
|
+
snapshotCodexModelAttributionState,
|
|
23
|
+
} = require("./codex-model-attribution");
|
|
18
24
|
const { USD_TICKS_PER_USD, normalizeGrokUsage } = require("./grok-usage");
|
|
19
25
|
|
|
20
26
|
const DEFAULT_SOURCE = "codex";
|
|
@@ -435,6 +441,9 @@ async function parseRolloutIncremental({
|
|
|
435
441
|
? prev.tokenUsageBaselines || null
|
|
436
442
|
: null;
|
|
437
443
|
const lastModel = sameInode && !truncated ? prev.lastModel || null : null;
|
|
444
|
+
const modelAttributionState = sameInode && !truncated
|
|
445
|
+
? prev.modelAttributionState || null
|
|
446
|
+
: null;
|
|
438
447
|
|
|
439
448
|
const codexProjectFastPath = projectEnabled && fileSource === DEFAULT_SOURCE;
|
|
440
449
|
const projectOffset = sameInode && !truncated ? Number(prev.projectOffset || 0) : 0;
|
|
@@ -506,6 +515,7 @@ async function parseRolloutIncremental({
|
|
|
506
515
|
lastTotal,
|
|
507
516
|
tokenUsageBaselines,
|
|
508
517
|
lastModel,
|
|
518
|
+
modelAttributionState,
|
|
509
519
|
projectState,
|
|
510
520
|
projectMetaCache,
|
|
511
521
|
publicRepoCache,
|
|
@@ -520,6 +530,7 @@ async function parseRolloutIncremental({
|
|
|
520
530
|
lastTotal,
|
|
521
531
|
tokenUsageBaselines,
|
|
522
532
|
lastModel,
|
|
533
|
+
modelAttributionState,
|
|
523
534
|
hourlyState,
|
|
524
535
|
touchedBuckets,
|
|
525
536
|
source: fileSource,
|
|
@@ -542,6 +553,7 @@ async function parseRolloutIncremental({
|
|
|
542
553
|
lastTotal: result.lastTotal,
|
|
543
554
|
tokenUsageBaselines: result.tokenUsageBaselines,
|
|
544
555
|
lastModel: result.lastModel,
|
|
556
|
+
modelAttributionState: result.modelAttributionState,
|
|
545
557
|
updatedAt: new Date().toISOString(),
|
|
546
558
|
};
|
|
547
559
|
if (codexProjectFastPath) {
|
|
@@ -2017,6 +2029,7 @@ async function parseRolloutFile({
|
|
|
2017
2029
|
lastTotal,
|
|
2018
2030
|
tokenUsageBaselines,
|
|
2019
2031
|
lastModel,
|
|
2032
|
+
modelAttributionState: previousModelAttributionState,
|
|
2020
2033
|
hourlyState,
|
|
2021
2034
|
touchedBuckets,
|
|
2022
2035
|
source,
|
|
@@ -2042,6 +2055,7 @@ async function parseRolloutFile({
|
|
|
2042
2055
|
lastTotal,
|
|
2043
2056
|
tokenUsageBaselines,
|
|
2044
2057
|
lastModel,
|
|
2058
|
+
modelAttributionState: previousModelAttributionState,
|
|
2045
2059
|
eventsAggregated: 0,
|
|
2046
2060
|
projectFileContexts,
|
|
2047
2061
|
};
|
|
@@ -2053,6 +2067,9 @@ async function parseRolloutFile({
|
|
|
2053
2067
|
});
|
|
2054
2068
|
|
|
2055
2069
|
let model = typeof lastModel === "string" ? lastModel : null;
|
|
2070
|
+
const modelAttributionState = createCodexModelAttributionState(
|
|
2071
|
+
previousModelAttributionState || { model },
|
|
2072
|
+
);
|
|
2056
2073
|
const usageDeltaState = createUsageDeltaState({
|
|
2057
2074
|
lastTotal,
|
|
2058
2075
|
baselines: tokenUsageBaselines,
|
|
@@ -2090,14 +2107,17 @@ async function parseRolloutFile({
|
|
|
2090
2107
|
const { line } = record;
|
|
2091
2108
|
if (!line) continue;
|
|
2092
2109
|
const maybeTokenCount = line.includes('"token_count"');
|
|
2093
|
-
const
|
|
2110
|
+
const maybeModelReroute =
|
|
2094
2111
|
!maybeTokenCount &&
|
|
2112
|
+
(line.includes('"model/rerouted"') || line.includes('"model_rerouted"'));
|
|
2113
|
+
const maybeTurnContext =
|
|
2114
|
+
!maybeTokenCount && !maybeModelReroute &&
|
|
2095
2115
|
(line.includes('"turn_context"') || line.includes('"session_meta"')) &&
|
|
2096
2116
|
(line.includes('"model"') ||
|
|
2097
2117
|
line.includes('"cwd"') ||
|
|
2098
2118
|
line.includes('"current_date"') ||
|
|
2099
2119
|
line.includes('"forked_from_id"'));
|
|
2100
|
-
if (!maybeTokenCount && !maybeTurnContext) {
|
|
2120
|
+
if (!maybeTokenCount && !maybeTurnContext && !maybeModelReroute) {
|
|
2101
2121
|
if (invalidRecordPolicy === "throw" || !record.terminated) {
|
|
2102
2122
|
try {
|
|
2103
2123
|
JSON.parse(line);
|
|
@@ -2120,6 +2140,9 @@ async function parseRolloutFile({
|
|
|
2120
2140
|
}
|
|
2121
2141
|
if (!record.terminated) committedEndOffset = scannedEndOffset;
|
|
2122
2142
|
|
|
2143
|
+
applyCodexModelEvent(modelAttributionState, obj);
|
|
2144
|
+
model = currentCodexModel(modelAttributionState) || model;
|
|
2145
|
+
|
|
2123
2146
|
if (
|
|
2124
2147
|
(obj?.type === "turn_context" || obj?.type === "session_meta") &&
|
|
2125
2148
|
obj?.payload &&
|
|
@@ -2131,9 +2154,6 @@ async function parseRolloutFile({
|
|
|
2131
2154
|
if (obj.type === "turn_context" && typeof obj.payload.current_date === "string") {
|
|
2132
2155
|
currentDate = normalizeIsoDate(obj.payload.current_date);
|
|
2133
2156
|
}
|
|
2134
|
-
if (typeof obj.payload.model === "string") {
|
|
2135
|
-
model = obj.payload.model;
|
|
2136
|
-
}
|
|
2137
2157
|
if (projectState && typeof obj.payload.cwd === "string") {
|
|
2138
2158
|
const nextCwd = obj.payload.cwd.trim();
|
|
2139
2159
|
if (nextCwd && nextCwd !== currentCwd) {
|
|
@@ -2167,7 +2187,9 @@ async function parseRolloutFile({
|
|
|
2167
2187
|
if (totalUsage && typeof totalUsage === "object") latestTotal = totalUsage;
|
|
2168
2188
|
|
|
2169
2189
|
const rawDelta = consumeUsageDelta(usageDeltaState, lastUsage, totalUsage);
|
|
2170
|
-
const
|
|
2190
|
+
const totalOnlyResetSentinel = source === DEFAULT_SOURCE
|
|
2191
|
+
&& isCodexTotalOnlyResetSentinel(lastUsage, totalUsage);
|
|
2192
|
+
const delta = rawDelta && !totalOnlyResetSentinel ? normalizeUsage(rawDelta) : null;
|
|
2171
2193
|
if (!delta || isAllZeroUsage(delta)) continue;
|
|
2172
2194
|
delta.conversation_count = 1;
|
|
2173
2195
|
|
|
@@ -2266,6 +2288,7 @@ async function parseRolloutFile({
|
|
|
2266
2288
|
lastTotal: latestTotal,
|
|
2267
2289
|
tokenUsageBaselines: snapshotUsageBaselines(usageDeltaState),
|
|
2268
2290
|
lastModel: model,
|
|
2291
|
+
modelAttributionState: snapshotCodexModelAttributionState(modelAttributionState),
|
|
2269
2292
|
eventsAggregated,
|
|
2270
2293
|
projectFileContexts,
|
|
2271
2294
|
};
|
|
@@ -2277,6 +2300,7 @@ async function scanRolloutProjectFileContexts({
|
|
|
2277
2300
|
lastTotal,
|
|
2278
2301
|
tokenUsageBaselines,
|
|
2279
2302
|
lastModel,
|
|
2303
|
+
modelAttributionState,
|
|
2280
2304
|
projectState,
|
|
2281
2305
|
projectMetaCache,
|
|
2282
2306
|
publicRepoCache,
|
|
@@ -2294,6 +2318,7 @@ async function scanRolloutProjectFileContexts({
|
|
|
2294
2318
|
lastTotal,
|
|
2295
2319
|
tokenUsageBaselines,
|
|
2296
2320
|
lastModel,
|
|
2321
|
+
modelAttributionState,
|
|
2297
2322
|
eventsAggregated: 0,
|
|
2298
2323
|
projectFileContexts,
|
|
2299
2324
|
};
|
|
@@ -2370,6 +2395,7 @@ async function scanRolloutProjectFileContexts({
|
|
|
2370
2395
|
lastTotal,
|
|
2371
2396
|
tokenUsageBaselines,
|
|
2372
2397
|
lastModel,
|
|
2398
|
+
modelAttributionState,
|
|
2373
2399
|
eventsAggregated: 0,
|
|
2374
2400
|
projectFileContexts,
|
|
2375
2401
|
};
|
|
@@ -4389,13 +4415,28 @@ function normalizeUsage(u) {
|
|
|
4389
4415
|
// bytes twice: once at the full input rate and again at the cache_read
|
|
4390
4416
|
// rate, producing ~6–7x cost inflation on cache-heavy Codex sessions
|
|
4391
4417
|
// (verified against ccusage's per-day numbers on the same rollouts).
|
|
4392
|
-
//
|
|
4393
|
-
//
|
|
4394
|
-
//
|
|
4418
|
+
// Preserve the reported total for compatibility with older Codex / Every
|
|
4419
|
+
// Code shapes where output_tokens can exclude reasoning or some component
|
|
4420
|
+
// fields are absent. The exact all-zero reset sentinel is rejected before
|
|
4421
|
+
// normalization by isCodexTotalOnlyResetSentinel().
|
|
4395
4422
|
out.input_tokens = Math.max(0, out.input_tokens - out.cached_input_tokens);
|
|
4396
4423
|
return out;
|
|
4397
4424
|
}
|
|
4398
4425
|
|
|
4426
|
+
function isCodexTotalOnlyResetSentinel(lastUsage, totalUsage) {
|
|
4427
|
+
const componentTotal = (usage) => [
|
|
4428
|
+
usage?.input_tokens,
|
|
4429
|
+
usage?.cached_input_tokens,
|
|
4430
|
+
usage?.cache_creation_input_tokens ?? usage?.cache_write_input_tokens,
|
|
4431
|
+
usage?.output_tokens,
|
|
4432
|
+
usage?.reasoning_output_tokens,
|
|
4433
|
+
].reduce((sum, value) => sum + Math.max(0, Number(value) || 0), 0);
|
|
4434
|
+
return Number(lastUsage?.total_tokens || 0) > 0
|
|
4435
|
+
&& Number(totalUsage?.total_tokens || 0) === 0
|
|
4436
|
+
&& componentTotal(lastUsage) === 0
|
|
4437
|
+
&& componentTotal(totalUsage) === 0;
|
|
4438
|
+
}
|
|
4439
|
+
|
|
4399
4440
|
// Stable dedup key for one Claude jsonl entry. Anthropic's official protocol
|
|
4400
4441
|
// guarantees `message.id` is globally unique per response, so msgId alone is a
|
|
4401
4442
|
// valid dedup key. Older code required both msgId AND requestId, which short-
|