@tokz/cli 0.2.15 → 0.2.17
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.
|
@@ -766,9 +766,6 @@ function parseLine(raw) {
|
|
|
766
766
|
obj: o
|
|
767
767
|
};
|
|
768
768
|
}
|
|
769
|
-
function tokenCountInfo(p) {
|
|
770
|
-
return p.type === "event_msg" && p.payload?.type === "token_count" ? asDict(p.payload.info) : void 0;
|
|
771
|
-
}
|
|
772
769
|
function headlessUsage(o) {
|
|
773
770
|
const usage = rawUsage(asDict(o.usage)) ?? rawUsage(asDict(asDict(o.data)?.usage)) ?? rawUsage(asDict(asDict(o.result)?.usage)) ?? rawUsage(asDict(asDict(o.response)?.usage));
|
|
774
771
|
if (!usage) return void 0;
|
|
@@ -784,6 +781,29 @@ function headlessTimestamp(o, pick) {
|
|
|
784
781
|
const fromFields = (f) => f ? pick(f.timestamp) ?? pick(f.created_at) ?? pick(f.createdAt) : void 0;
|
|
785
782
|
return fromFields(o) ?? fromFields(asDict(o.data)) ?? fromFields(asDict(o.result)) ?? fromFields(asDict(o.response));
|
|
786
783
|
}
|
|
784
|
+
function detectReplaySecond(content, lines) {
|
|
785
|
+
const head = content.slice(0, 16384);
|
|
786
|
+
if (!head.includes("thread_spawn") && !head.includes("forked_from_id")) return void 0;
|
|
787
|
+
let firstSecond;
|
|
788
|
+
for (const p of lines) {
|
|
789
|
+
if (p.type !== "event_msg" || p.payload?.type !== "token_count") continue;
|
|
790
|
+
const info = p.payload.info;
|
|
791
|
+
if (!info) continue;
|
|
792
|
+
if (!asDict(info.last_token_usage) && !asDict(info.total_token_usage)) continue;
|
|
793
|
+
const ts = p.timestamp;
|
|
794
|
+
if (!ts || typeof ts !== "string" || ts.length < 19) continue;
|
|
795
|
+
const sec = ts.slice(0, 19);
|
|
796
|
+
if (firstSecond === void 0) {
|
|
797
|
+
firstSecond = sec;
|
|
798
|
+
} else {
|
|
799
|
+
if (firstSecond === sec) {
|
|
800
|
+
return sec;
|
|
801
|
+
}
|
|
802
|
+
return void 0;
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
return void 0;
|
|
806
|
+
}
|
|
787
807
|
async function parseCodexRollout(file, seen = /* @__PURE__ */ new Set()) {
|
|
788
808
|
const stats = { file, usageByModel: {}, toolCalls: {}, toolCostUsd: {}, dailyUsage: {} };
|
|
789
809
|
const content = await readFile4(file, "utf8").catch(() => "");
|
|
@@ -793,6 +813,8 @@ async function parseCodexRollout(file, seen = /* @__PURE__ */ new Set()) {
|
|
|
793
813
|
const parsed = parseLine(raw);
|
|
794
814
|
if (parsed) lines.push(parsed);
|
|
795
815
|
}
|
|
816
|
+
const replaySecond = detectReplaySecond(content, lines);
|
|
817
|
+
let skipReplay = replaySecond !== void 0;
|
|
796
818
|
const modelState = { currentIsFallback: false };
|
|
797
819
|
let prev;
|
|
798
820
|
let turnTools = [];
|
|
@@ -812,7 +834,6 @@ async function parseCodexRollout(file, seen = /* @__PURE__ */ new Set()) {
|
|
|
812
834
|
}
|
|
813
835
|
seen.add(dedupKey);
|
|
814
836
|
const delta = {
|
|
815
|
-
// Codex's input_tokens INCLUDES cached tokens; split them out.
|
|
816
837
|
inputTokens: Math.max(0, usage.input - cached),
|
|
817
838
|
cacheReadTokens: cached,
|
|
818
839
|
cacheCreationTokens: 0,
|
|
@@ -862,21 +883,34 @@ async function parseCodexRollout(file, seen = /* @__PURE__ */ new Set()) {
|
|
|
862
883
|
}
|
|
863
884
|
continue;
|
|
864
885
|
}
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
886
|
+
if (type === "event_msg" && payload2?.type === "token_count") {
|
|
887
|
+
const info = asDict(payload2.info);
|
|
888
|
+
if (replaySecond !== void 0 && skipReplay) {
|
|
889
|
+
const ts = timestamp ?? parsed.obj.timestamp;
|
|
890
|
+
const matchesReplay = typeof ts === "string" && ts.length >= 19 && ts.slice(0, 19) === replaySecond;
|
|
891
|
+
if (matchesReplay) {
|
|
892
|
+
const totals = rawUsage(info?.total_token_usage);
|
|
893
|
+
if (totals) prev = totals;
|
|
894
|
+
turnTools = [];
|
|
895
|
+
continue;
|
|
896
|
+
}
|
|
897
|
+
skipReplay = false;
|
|
898
|
+
}
|
|
899
|
+
if (info) {
|
|
900
|
+
const totals = rawUsage(info.total_token_usage);
|
|
901
|
+
const last = rawUsage(info.last_token_usage);
|
|
902
|
+
if (!last && !totals) continue;
|
|
903
|
+
const usage2 = last ?? subtractUsage(totals, prev);
|
|
904
|
+
if (totals) prev = totals;
|
|
905
|
+
if (usage2.input === 0 && usage2.cached === 0 && usage2.output === 0 && usage2.reasoning === 0) {
|
|
906
|
+
continue;
|
|
907
|
+
}
|
|
908
|
+
const ts = nonEmpty(timestamp) ?? normalizeTimestamp(parsed.obj.timestamp);
|
|
909
|
+
const parsedModel = modelFromParts(payload2) ?? modelFromParts(info);
|
|
910
|
+
const model2 = resolveModel(parsedModel, ts ?? "", modelState);
|
|
911
|
+
accumulate(usage2, model2, ts);
|
|
873
912
|
continue;
|
|
874
913
|
}
|
|
875
|
-
const ts = nonEmpty(timestamp) ?? normalizeTimestamp(parsed.obj.timestamp);
|
|
876
|
-
const parsedModel = modelFromParts(payload2) ?? modelFromParts(info);
|
|
877
|
-
const model2 = resolveModel(parsedModel, ts ?? "", modelState);
|
|
878
|
-
accumulate(usage2, model2, ts);
|
|
879
|
-
continue;
|
|
880
914
|
}
|
|
881
915
|
if (type === "event_msg" || payload2?.type === "turn_context") continue;
|
|
882
916
|
const usage = headlessUsage(parsed.obj);
|
package/dist/cli.js
CHANGED
|
@@ -276,7 +276,7 @@ program.action(async () => {
|
|
|
276
276
|
const [{ render }, React, { Root }, { Fullscreen }] = await Promise.all([
|
|
277
277
|
import("ink"),
|
|
278
278
|
import("react"),
|
|
279
|
-
import("./Root-
|
|
279
|
+
import("./Root-K4HFMFGA.js"),
|
|
280
280
|
import("./Fullscreen-GK2ZYXHV.js")
|
|
281
281
|
]);
|
|
282
282
|
render(React.createElement(Fullscreen, null, React.createElement(Root)));
|