@knpkv/agent-usage 0.1.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/LICENSE +21 -0
- package/README.md +111 -0
- package/dist/client/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
- package/dist/client/assets/geist-mono-latin-wght-normal-XN7g48iV.woff2 +0 -0
- package/dist/client/assets/index-CUuLXODk.css +1 -0
- package/dist/client/assets/index-DB-VXWqy.js +55 -0
- package/dist/client/index.html +15 -0
- package/dist/core/Attribution.d.ts +59 -0
- package/dist/core/Attribution.js +108 -0
- package/dist/core/Attribution.js.map +1 -0
- package/dist/core/Balances.d.ts +27 -0
- package/dist/core/Balances.js +63 -0
- package/dist/core/Balances.js.map +1 -0
- package/dist/core/ClaudeLimits.d.ts +58 -0
- package/dist/core/ClaudeLimits.js +125 -0
- package/dist/core/ClaudeLimits.js.map +1 -0
- package/dist/core/ClaudeLimitsLive.d.ts +18 -0
- package/dist/core/ClaudeLimitsLive.js +36 -0
- package/dist/core/ClaudeLimitsLive.js.map +1 -0
- package/dist/core/ClaudeReader.d.ts +27 -0
- package/dist/core/ClaudeReader.js +154 -0
- package/dist/core/ClaudeReader.js.map +1 -0
- package/dist/core/CodexReader.d.ts +91 -0
- package/dist/core/CodexReader.js +365 -0
- package/dist/core/CodexReader.js.map +1 -0
- package/dist/core/Database.d.ts +4 -0
- package/dist/core/Database.js +65 -0
- package/dist/core/Database.js.map +1 -0
- package/dist/core/Ingest.d.ts +55 -0
- package/dist/core/Ingest.js +267 -0
- package/dist/core/Ingest.js.map +1 -0
- package/dist/core/Model.d.ts +160 -0
- package/dist/core/Model.js +125 -0
- package/dist/core/Model.js.map +1 -0
- package/dist/core/Pricing.d.ts +42 -0
- package/dist/core/Pricing.js +126 -0
- package/dist/core/Pricing.js.map +1 -0
- package/dist/core/Readers.d.ts +42 -0
- package/dist/core/Readers.js +18 -0
- package/dist/core/Readers.js.map +1 -0
- package/dist/core/Report.d.ts +53 -0
- package/dist/core/Report.js +270 -0
- package/dist/core/Report.js.map +1 -0
- package/dist/core/Store.d.ts +94 -0
- package/dist/core/Store.js +376 -0
- package/dist/core/Store.js.map +1 -0
- package/dist/core/Tickets.d.ts +42 -0
- package/dist/core/Tickets.js +125 -0
- package/dist/core/Tickets.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/main.d.ts +2 -0
- package/dist/main.js +65 -0
- package/dist/main.js.map +1 -0
- package/dist/server/Api.d.ts +304 -0
- package/dist/server/Api.js +20 -0
- package/dist/server/Api.js.map +1 -0
- package/dist/server/Config.d.ts +27 -0
- package/dist/server/Config.js +49 -0
- package/dist/server/Config.js.map +1 -0
- package/dist/server/Handlers.d.ts +5 -0
- package/dist/server/Handlers.js +48 -0
- package/dist/server/Handlers.js.map +1 -0
- package/dist/server/HttpApplication.d.ts +7 -0
- package/dist/server/HttpApplication.js +70 -0
- package/dist/server/HttpApplication.js.map +1 -0
- package/dist/server/OwnerSession.d.ts +60 -0
- package/dist/server/OwnerSession.js +206 -0
- package/dist/server/OwnerSession.js.map +1 -0
- package/dist/server/Runtime.d.ts +57 -0
- package/dist/server/Runtime.js +85 -0
- package/dist/server/Runtime.js.map +1 -0
- package/dist/server/Server.d.ts +15 -0
- package/dist/server/Server.js +39 -0
- package/dist/server/Server.js.map +1 -0
- package/dist/shared/contracts.d.ts +309 -0
- package/dist/shared/contracts.js +105 -0
- package/dist/shared/contracts.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +68 -0
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reading Claude Code transcripts (`<config>/projects/<project>/<session>.jsonl`, and each session's
|
|
3
|
+
* `subagents/*.jsonl`, booked to the parent session) into Usage Events.
|
|
4
|
+
*
|
|
5
|
+
* **Mental model**
|
|
6
|
+
*
|
|
7
|
+
* - **One event per model request.** Claude Code writes a message once per content block, each line
|
|
8
|
+
* repeating the usage; message id + request id dedupes them. Should a later line carry larger
|
|
9
|
+
* counts (a streamed request's final usage), the larger counts win, here and in the store.
|
|
10
|
+
* - **Zero-token messages are placeholders** (`<synthetic>` local replies), not requests.
|
|
11
|
+
* - **The Active Ticket follows the human.** Each typed user turn sets it to the one ticket it names,
|
|
12
|
+
* or clears it; tool results, meta turns, sidechain (subagent) prompts and injected reminders
|
|
13
|
+
* never touch it.
|
|
14
|
+
* - **Prompt and response text is read here and dropped here.** Nothing but counts and metadata
|
|
15
|
+
* leaves this module.
|
|
16
|
+
*
|
|
17
|
+
* @module
|
|
18
|
+
*/
|
|
19
|
+
import { Option, Predicate, Schema } from "effect";
|
|
20
|
+
import { claudeHumanText, singleTicket } from "./Attribution.js";
|
|
21
|
+
import { Count } from "./Model.js";
|
|
22
|
+
import { countSkip, noSkips, parseInstant } from "./Readers.js";
|
|
23
|
+
export const ClaudeReaderState = Schema.Struct({ activeTicket: Schema.NullOr(Schema.String) });
|
|
24
|
+
export const initialClaudeState = { activeTicket: null };
|
|
25
|
+
const Usage = Schema.Struct({
|
|
26
|
+
input_tokens: Schema.optionalKey(Count),
|
|
27
|
+
output_tokens: Schema.optionalKey(Count),
|
|
28
|
+
cache_read_input_tokens: Schema.optionalKey(Count),
|
|
29
|
+
cache_creation_input_tokens: Schema.optionalKey(Count),
|
|
30
|
+
cache_creation: Schema.optionalKey(Schema.Struct({
|
|
31
|
+
ephemeral_5m_input_tokens: Schema.optionalKey(Count),
|
|
32
|
+
ephemeral_1h_input_tokens: Schema.optionalKey(Count)
|
|
33
|
+
})),
|
|
34
|
+
speed: Schema.optionalKey(Schema.NullOr(Schema.String))
|
|
35
|
+
});
|
|
36
|
+
const AssistantLine = Schema.Struct({
|
|
37
|
+
timestamp: Schema.optionalKey(Schema.String),
|
|
38
|
+
cwd: Schema.optionalKey(Schema.String),
|
|
39
|
+
gitBranch: Schema.optionalKey(Schema.String),
|
|
40
|
+
requestId: Schema.optionalKey(Schema.String),
|
|
41
|
+
message: Schema.Struct({
|
|
42
|
+
id: Schema.optionalKey(Schema.String),
|
|
43
|
+
model: Schema.NonEmptyString,
|
|
44
|
+
usage: Usage
|
|
45
|
+
})
|
|
46
|
+
});
|
|
47
|
+
const UserLine = Schema.Struct({
|
|
48
|
+
type: Schema.Literal("user"),
|
|
49
|
+
isMeta: Schema.optionalKey(Schema.Boolean),
|
|
50
|
+
isSidechain: Schema.optionalKey(Schema.Boolean),
|
|
51
|
+
message: Schema.Struct({
|
|
52
|
+
content: Schema.Union([
|
|
53
|
+
Schema.String,
|
|
54
|
+
Schema.Array(Schema.Struct({ type: Schema.String, text: Schema.optionalKey(Schema.String) }))
|
|
55
|
+
])
|
|
56
|
+
})
|
|
57
|
+
});
|
|
58
|
+
/** Claude Code's record of the latest prompt the human typed, written as the session moves on. */
|
|
59
|
+
const LastPromptLine = Schema.Struct({ type: Schema.Literal("last-prompt"), lastPrompt: Schema.String });
|
|
60
|
+
const decodeLastPrompt = Schema.decodeUnknownOption(Schema.fromJsonString(LastPromptLine));
|
|
61
|
+
const decodeAssistant = Schema.decodeUnknownOption(Schema.fromJsonString(AssistantLine));
|
|
62
|
+
const decodeUser = Schema.decodeUnknownOption(Schema.fromJsonString(UserLine));
|
|
63
|
+
const isToolResultTurn = (content) => !Predicate.isString(content) && content.length > 0 && content.every((block) => block.type === "tool_result");
|
|
64
|
+
const toEvent = (file, line, record, occurredAt, activeTicket) => {
|
|
65
|
+
const usage = record.message.usage;
|
|
66
|
+
const write5m = usage.cache_creation?.ephemeral_5m_input_tokens ?? 0;
|
|
67
|
+
const write1h = usage.cache_creation?.ephemeral_1h_input_tokens ?? 0;
|
|
68
|
+
// Older records carry only the total; those count at the 5-minute rate.
|
|
69
|
+
const split = write5m + write1h > 0;
|
|
70
|
+
const tokens = {
|
|
71
|
+
input: usage.input_tokens ?? 0,
|
|
72
|
+
output: usage.output_tokens ?? 0,
|
|
73
|
+
reasoning: 0,
|
|
74
|
+
cacheRead: usage.cache_read_input_tokens ?? 0,
|
|
75
|
+
cacheWrite5m: split ? write5m : usage.cache_creation_input_tokens ?? 0,
|
|
76
|
+
cacheWrite1h: split ? write1h : 0
|
|
77
|
+
};
|
|
78
|
+
if (tokens.input + tokens.output + tokens.cacheRead + tokens.cacheWrite5m + tokens.cacheWrite1h === 0)
|
|
79
|
+
return null;
|
|
80
|
+
const messageId = record.message.id ?? "";
|
|
81
|
+
const requestId = record.requestId ?? "";
|
|
82
|
+
return {
|
|
83
|
+
agent: "claude",
|
|
84
|
+
dedupeKey: messageId === "" && requestId === ""
|
|
85
|
+
? `${file.fileKey}#${line.offset}`
|
|
86
|
+
: `${messageId} ${requestId}`,
|
|
87
|
+
machine: file.machine,
|
|
88
|
+
sessionId: file.sessionId,
|
|
89
|
+
occurredAt,
|
|
90
|
+
model: record.message.model,
|
|
91
|
+
fast: usage.speed === "fast",
|
|
92
|
+
tokens,
|
|
93
|
+
attribution: { cwd: record.cwd ?? "", branch: record.gitBranch ?? "", activeTicket }
|
|
94
|
+
};
|
|
95
|
+
};
|
|
96
|
+
/** Reads one chunk of a transcript, continuing from the state the previous chunk ended in. */
|
|
97
|
+
export const readClaude = (file, lines, state) => {
|
|
98
|
+
const events = [];
|
|
99
|
+
const seen = new Map();
|
|
100
|
+
let skipped = noSkips;
|
|
101
|
+
let activeTicket = state.activeTicket;
|
|
102
|
+
for (const line of lines) {
|
|
103
|
+
if (line.text.includes("\"type\":\"user\"")) {
|
|
104
|
+
const user = decodeUser(line.text);
|
|
105
|
+
if (Option.isSome(user)) {
|
|
106
|
+
const content = user.value.message.content;
|
|
107
|
+
// A sidechain's user turns are the parent agent delegating, not the human typing.
|
|
108
|
+
if (user.value.isMeta !== true && user.value.isSidechain !== true && !isToolResultTurn(content)) {
|
|
109
|
+
const typed = claudeHumanText(content);
|
|
110
|
+
if (typed !== "")
|
|
111
|
+
activeTicket = singleTicket(typed);
|
|
112
|
+
}
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
if (line.text.includes("\"last-prompt\"")) {
|
|
117
|
+
const prompt = decodeLastPrompt(line.text);
|
|
118
|
+
if (Option.isSome(prompt)) {
|
|
119
|
+
const typed = claudeHumanText(prompt.value.lastPrompt);
|
|
120
|
+
if (typed !== "")
|
|
121
|
+
activeTicket = singleTicket(typed);
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
if (!line.text.includes("\"usage\""))
|
|
126
|
+
continue;
|
|
127
|
+
const assistant = decodeAssistant(line.text);
|
|
128
|
+
if (Option.isNone(assistant)) {
|
|
129
|
+
skipped = countSkip(skipped, "unparseableLine");
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
const occurredAt = parseInstant(assistant.value.timestamp ?? "");
|
|
133
|
+
if (occurredAt === null) {
|
|
134
|
+
skipped = countSkip(skipped, "missingTimestamp");
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
const event = toEvent(file, line, assistant.value, occurredAt, activeTicket);
|
|
138
|
+
if (event === null)
|
|
139
|
+
continue;
|
|
140
|
+
// A request's usage can be written more than once as it streams; the largest is the final one.
|
|
141
|
+
const earlier = seen.get(event.dedupeKey);
|
|
142
|
+
if (earlier === undefined) {
|
|
143
|
+
seen.set(event.dedupeKey, events.length);
|
|
144
|
+
events.push(event);
|
|
145
|
+
}
|
|
146
|
+
else if (event.tokens.output > (events[earlier]?.tokens.output ?? 0)) {
|
|
147
|
+
const first = events[earlier];
|
|
148
|
+
if (first !== undefined)
|
|
149
|
+
events[earlier] = { ...first, tokens: event.tokens };
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return { events, snapshots: [], balances: [], skipped, state: { activeTicket } };
|
|
153
|
+
};
|
|
154
|
+
//# sourceMappingURL=ClaudeReader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ClaudeReader.js","sourceRoot":"","sources":["../../src/core/ClaudeReader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAClD,OAAO,EAAsB,eAAe,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AACpF,OAAO,EAAE,KAAK,EAAmB,MAAM,YAAY,CAAA;AACnD,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,YAAY,EAAqD,MAAM,cAAc,CAAA;AAElH,MAAM,CAAC,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;AAG9F,MAAM,CAAC,MAAM,kBAAkB,GAAsB,EAAE,YAAY,EAAE,IAAI,EAAE,CAAA;AAE3E,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC;IACvC,aAAa,EAAE,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC;IACxC,uBAAuB,EAAE,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC;IAClD,2BAA2B,EAAE,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC;IACtD,cAAc,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC;QAC/C,yBAAyB,EAAE,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC;QACpD,yBAAyB,EAAE,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC;KACrD,CAAC,CAAC;IACH,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;CACxD,CAAC,CAAA;AAEF,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC;IAClC,SAAS,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC;IAC5C,GAAG,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC;IACtC,SAAS,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC;IAC5C,SAAS,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC;IAC5C,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC;QACrB,EAAE,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC;QACrC,KAAK,EAAE,MAAM,CAAC,cAAc;QAC5B,KAAK,EAAE,KAAK;KACb,CAAC;CACH,CAAC,CAAA;AAEF,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC;IAC7B,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;IAC5B,MAAM,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC;IAC1C,WAAW,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC;IAC/C,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC;QACrB,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC;YACpB,MAAM,CAAC,MAAM;YACb,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;SAC9F,CAAC;KACH,CAAC;CACH,CAAC,CAAA;AAEF,kGAAkG;AAClG,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAA;AACxG,MAAM,gBAAgB,GAAG,MAAM,CAAC,mBAAmB,CAAC,MAAM,CAAC,cAAc,CAAC,cAAc,CAAC,CAAC,CAAA;AAE1F,MAAM,eAAe,GAAG,MAAM,CAAC,mBAAmB,CAAC,MAAM,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC,CAAA;AACxF,MAAM,UAAU,GAAG,MAAM,CAAC,mBAAmB,CAAC,MAAM,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAA;AAE9E,MAAM,gBAAgB,GAAG,CAAC,OAAsB,EAAW,EAAE,CAC3D,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,aAAa,CAAC,CAAA;AAI9G,MAAM,OAAO,GAAG,CACd,IAAgB,EAChB,IAAgB,EAChB,MAAiB,EACjB,UAAkB,EAClB,YAA2B,EACR,EAAE;IACrB,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAA;IAClC,MAAM,OAAO,GAAG,KAAK,CAAC,cAAc,EAAE,yBAAyB,IAAI,CAAC,CAAA;IACpE,MAAM,OAAO,GAAG,KAAK,CAAC,cAAc,EAAE,yBAAyB,IAAI,CAAC,CAAA;IACpE,wEAAwE;IACxE,MAAM,KAAK,GAAG,OAAO,GAAG,OAAO,GAAG,CAAC,CAAA;IACnC,MAAM,MAAM,GAAG;QACb,KAAK,EAAE,KAAK,CAAC,YAAY,IAAI,CAAC;QAC9B,MAAM,EAAE,KAAK,CAAC,aAAa,IAAI,CAAC;QAChC,SAAS,EAAE,CAAC;QACZ,SAAS,EAAE,KAAK,CAAC,uBAAuB,IAAI,CAAC;QAC7C,YAAY,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,2BAA2B,IAAI,CAAC;QACtE,YAAY,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;KAClC,CAAA;IACD,IAAI,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,SAAS,GAAG,MAAM,CAAC,YAAY,GAAG,MAAM,CAAC,YAAY,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IAClH,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAA;IACzC,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,EAAE,CAAA;IACxC,OAAO;QACL,KAAK,EAAE,QAAQ;QACf,SAAS,EAAE,SAAS,KAAK,EAAE,IAAI,SAAS,KAAK,EAAE;YAC7C,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,MAAM,EAAE;YAClC,CAAC,CAAC,GAAG,SAAS,IAAI,SAAS,EAAE;QAC/B,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,UAAU;QACV,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK;QAC3B,IAAI,EAAE,KAAK,CAAC,KAAK,KAAK,MAAM;QAC5B,MAAM;QACN,WAAW,EAAE,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,IAAI,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,SAAS,IAAI,EAAE,EAAE,YAAY,EAAE;KACrF,CAAA;AACH,CAAC,CAAA;AAED,8FAA8F;AAC9F,MAAM,CAAC,MAAM,UAAU,GAAG,CACxB,IAAgB,EAChB,KAAgC,EAChC,KAAwB,EACO,EAAE;IACjC,MAAM,MAAM,GAAsB,EAAE,CAAA;IACpC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAkB,CAAA;IACtC,IAAI,OAAO,GAAG,OAAO,CAAA;IACrB,IAAI,YAAY,GAAG,KAAK,CAAC,YAAY,CAAA;IAErC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC;YAC5C,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YAClC,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;gBACxB,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAA;gBAC1C,kFAAkF;gBAClF,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,WAAW,KAAK,IAAI,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,EAAE,CAAC;oBAChG,MAAM,KAAK,GAAG,eAAe,CAAC,OAAO,CAAC,CAAA;oBACtC,IAAI,KAAK,KAAK,EAAE;wBAAE,YAAY,GAAG,YAAY,CAAC,KAAK,CAAC,CAAA;gBACtD,CAAC;gBACD,SAAQ;YACV,CAAC;QACH,CAAC;QACD,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC;YAC1C,MAAM,MAAM,GAAG,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YAC1C,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC1B,MAAM,KAAK,GAAG,eAAe,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAA;gBACtD,IAAI,KAAK,KAAK,EAAE;oBAAE,YAAY,GAAG,YAAY,CAAC,KAAK,CAAC,CAAA;gBACpD,SAAQ;YACV,CAAC;QACH,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC;YAAE,SAAQ;QAC9C,MAAM,SAAS,GAAG,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC5C,IAAI,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;YAC7B,OAAO,GAAG,SAAS,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAA;YAC/C,SAAQ;QACV,CAAC;QACD,MAAM,UAAU,GAAG,YAAY,CAAC,SAAS,CAAC,KAAK,CAAC,SAAS,IAAI,EAAE,CAAC,CAAA;QAChE,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;YACxB,OAAO,GAAG,SAAS,CAAC,OAAO,EAAE,kBAAkB,CAAC,CAAA;YAChD,SAAQ;QACV,CAAC;QACD,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,CAAC,KAAK,EAAE,UAAU,EAAE,YAAY,CAAC,CAAA;QAC5E,IAAI,KAAK,KAAK,IAAI;YAAE,SAAQ;QAC5B,+FAA+F;QAC/F,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;QACzC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,CAAA;YACxC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACpB,CAAC;aAAM,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC,EAAE,CAAC;YACvE,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,CAAA;YAC7B,IAAI,KAAK,KAAK,SAAS;gBAAE,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAA;QAC/E,CAAC;IACH,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,YAAY,EAAE,EAAE,CAAA;AAClF,CAAC,CAAA"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reading Codex rollouts (`<CODEX_HOME>/sessions/YYYY/MM/DD/rollout-*.jsonl`) into Usage Events,
|
|
3
|
+
* Limit Snapshots and credit Balance Readings.
|
|
4
|
+
*
|
|
5
|
+
* **Mental model**
|
|
6
|
+
*
|
|
7
|
+
* - **A rollout is a running log.** `session_meta` names the cwd and branch, `turn_context` the
|
|
8
|
+
* model, and every `token_count` carries the request's own usage (`last_token_usage`) beside the
|
|
9
|
+
* session's running total. Those three facts live in the carried state, so a chunk read on the next
|
|
10
|
+
* pass books its requests exactly as one long read would.
|
|
11
|
+
* - **A repeated token_count is not a request.** Codex re-emits the event when only rate limits
|
|
12
|
+
* change; the running total not moving is how that shows.
|
|
13
|
+
* - **Only the `codex` limit is the account's** (or, in rollouts before it was named, the block with
|
|
14
|
+
* no limit id). Model-scoped limits arrive in their own blocks and are not the weekly or five-hour
|
|
15
|
+
* allowance; they are ignored here.
|
|
16
|
+
* - **A fork repeats its parent.** A forked subagent rollout starts with a copy of the parent's
|
|
17
|
+
* history, below `subagent_history_start_ordinal`; that copy only advances the running total.
|
|
18
|
+
* - **Limits are kept on change, and at least every ten minutes.** Codex repeats them on every
|
|
19
|
+
* request; the repeats in between say nothing new.
|
|
20
|
+
* - **Every token_count backfills limit history**, so Codex limits are recoverable from old rollouts
|
|
21
|
+
* in a way Claude's are not.
|
|
22
|
+
*
|
|
23
|
+
* @module
|
|
24
|
+
*/
|
|
25
|
+
import { Schema } from "effect";
|
|
26
|
+
import { type ReadResult, type SourceFile, type SourceLine } from "./Readers.js";
|
|
27
|
+
/** A Codex usage block with optional fields filled in, as codex-session-cost.jq normalizes it. */
|
|
28
|
+
export declare const CodexUsage: Schema.Struct<{
|
|
29
|
+
readonly input: Schema.Int;
|
|
30
|
+
readonly cached: Schema.Int;
|
|
31
|
+
readonly cacheWrite: Schema.Int;
|
|
32
|
+
readonly output: Schema.Int;
|
|
33
|
+
readonly reasoning: Schema.Int;
|
|
34
|
+
readonly total: Schema.Int;
|
|
35
|
+
}>;
|
|
36
|
+
export type CodexUsage = typeof CodexUsage.Type;
|
|
37
|
+
/**
|
|
38
|
+
* The tokens one token_count adds, ported exactly from codex-session-cost.jq's `usage_delta`:
|
|
39
|
+
* an unchanged running total adds nothing (a rate-limit-only re-emit); a first event, a reset
|
|
40
|
+
* total, or a last usage equal to the whole total adds the last usage; otherwise the difference of
|
|
41
|
+
* running totals, which also recovers tokens of any token_count in between that failed to decode.
|
|
42
|
+
*/
|
|
43
|
+
export declare const usageDelta: (previous: CodexUsage | null, total: CodexUsage, last: CodexUsage) => CodexUsage;
|
|
44
|
+
/**
|
|
45
|
+
* How long an unchanged reading may go unrecorded. Codex repeats its limits on every request; one
|
|
46
|
+
* observation per window of this length keeps the series honest about when it was last seen, and
|
|
47
|
+
* bounds how far a change back can land from where it happened when rollouts interleave.
|
|
48
|
+
*/
|
|
49
|
+
export declare const RESAMPLE_MILLIS: number;
|
|
50
|
+
export declare const CodexReaderState: Schema.Struct<{
|
|
51
|
+
readonly cwd: Schema.String;
|
|
52
|
+
readonly branch: Schema.String;
|
|
53
|
+
readonly model: Schema.NullOr<Schema.String>;
|
|
54
|
+
readonly activeTicket: Schema.NullOr<Schema.String>;
|
|
55
|
+
/** The session's running usage at the last valid token_count read. */
|
|
56
|
+
readonly previousTotal: Schema.NullOr<Schema.Struct<{
|
|
57
|
+
readonly input: Schema.Int;
|
|
58
|
+
readonly cached: Schema.Int;
|
|
59
|
+
readonly cacheWrite: Schema.Int;
|
|
60
|
+
readonly output: Schema.Int;
|
|
61
|
+
readonly reasoning: Schema.Int;
|
|
62
|
+
readonly total: Schema.Int;
|
|
63
|
+
}>>;
|
|
64
|
+
/** This rollout's own session id, from its first session_meta. */
|
|
65
|
+
readonly ownSession: Schema.NullOr<Schema.String>;
|
|
66
|
+
/**
|
|
67
|
+
* A forked subagent rollout copies its parent's history first; lines with an ordinal below this
|
|
68
|
+
* one are that copy, already booked from the parent's own rollout.
|
|
69
|
+
*/
|
|
70
|
+
readonly historyStart: Schema.NullOr<Schema.Int>;
|
|
71
|
+
/** A subagent's rollout: its user items are the parent agent delegating, not the human typing. */
|
|
72
|
+
readonly delegated: Schema.Boolean;
|
|
73
|
+
/** The rollout writes the human's prompts as user_message events; its response items are copies. */
|
|
74
|
+
readonly userEvents: Schema.Boolean;
|
|
75
|
+
readonly keptPrimary: Schema.NullOr<Schema.Struct<{
|
|
76
|
+
readonly signature: Schema.String;
|
|
77
|
+
readonly at: Schema.Int;
|
|
78
|
+
}>>;
|
|
79
|
+
readonly keptSecondary: Schema.NullOr<Schema.Struct<{
|
|
80
|
+
readonly signature: Schema.String;
|
|
81
|
+
readonly at: Schema.Int;
|
|
82
|
+
}>>;
|
|
83
|
+
readonly keptCredits: Schema.NullOr<Schema.Struct<{
|
|
84
|
+
readonly signature: Schema.String;
|
|
85
|
+
readonly at: Schema.Int;
|
|
86
|
+
}>>;
|
|
87
|
+
}>;
|
|
88
|
+
export type CodexReaderState = typeof CodexReaderState.Type;
|
|
89
|
+
export declare const initialCodexState: CodexReaderState;
|
|
90
|
+
/** Reads one chunk of a rollout, continuing from the state the previous chunk ended in. */
|
|
91
|
+
export declare const readCodex: (file: SourceFile, lines: ReadonlyArray<SourceLine>, initial: CodexReaderState) => ReadResult<CodexReaderState>;
|
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reading Codex rollouts (`<CODEX_HOME>/sessions/YYYY/MM/DD/rollout-*.jsonl`) into Usage Events,
|
|
3
|
+
* Limit Snapshots and credit Balance Readings.
|
|
4
|
+
*
|
|
5
|
+
* **Mental model**
|
|
6
|
+
*
|
|
7
|
+
* - **A rollout is a running log.** `session_meta` names the cwd and branch, `turn_context` the
|
|
8
|
+
* model, and every `token_count` carries the request's own usage (`last_token_usage`) beside the
|
|
9
|
+
* session's running total. Those three facts live in the carried state, so a chunk read on the next
|
|
10
|
+
* pass books its requests exactly as one long read would.
|
|
11
|
+
* - **A repeated token_count is not a request.** Codex re-emits the event when only rate limits
|
|
12
|
+
* change; the running total not moving is how that shows.
|
|
13
|
+
* - **Only the `codex` limit is the account's** (or, in rollouts before it was named, the block with
|
|
14
|
+
* no limit id). Model-scoped limits arrive in their own blocks and are not the weekly or five-hour
|
|
15
|
+
* allowance; they are ignored here.
|
|
16
|
+
* - **A fork repeats its parent.** A forked subagent rollout starts with a copy of the parent's
|
|
17
|
+
* history, below `subagent_history_start_ordinal`; that copy only advances the running total.
|
|
18
|
+
* - **Limits are kept on change, and at least every ten minutes.** Codex repeats them on every
|
|
19
|
+
* request; the repeats in between say nothing new.
|
|
20
|
+
* - **Every token_count backfills limit history**, so Codex limits are recoverable from old rollouts
|
|
21
|
+
* in a way Claude's are not.
|
|
22
|
+
*
|
|
23
|
+
* @module
|
|
24
|
+
*/
|
|
25
|
+
import { Option, Predicate, Schema } from "effect";
|
|
26
|
+
import { codexHumanText, singleTicket } from "./Attribution.js";
|
|
27
|
+
import { classifyCodexCredits, CodexCredits } from "./Balances.js";
|
|
28
|
+
import { BalanceValue, Count, LimitReading } from "./Model.js";
|
|
29
|
+
import { countSkip, noSkips, parseInstant } from "./Readers.js";
|
|
30
|
+
/** A Codex usage block with optional fields filled in, as codex-session-cost.jq normalizes it. */
|
|
31
|
+
export const CodexUsage = Schema.Struct({
|
|
32
|
+
input: Count,
|
|
33
|
+
cached: Count,
|
|
34
|
+
cacheWrite: Count,
|
|
35
|
+
output: Count,
|
|
36
|
+
reasoning: Count,
|
|
37
|
+
total: Count
|
|
38
|
+
});
|
|
39
|
+
const zeroUsage = { input: 0, cached: 0, cacheWrite: 0, output: 0, reasoning: 0, total: 0 };
|
|
40
|
+
/**
|
|
41
|
+
* The tokens one token_count adds, ported exactly from codex-session-cost.jq's `usage_delta`:
|
|
42
|
+
* an unchanged running total adds nothing (a rate-limit-only re-emit); a first event, a reset
|
|
43
|
+
* total, or a last usage equal to the whole total adds the last usage; otherwise the difference of
|
|
44
|
+
* running totals, which also recovers tokens of any token_count in between that failed to decode.
|
|
45
|
+
*/
|
|
46
|
+
export const usageDelta = (previous, total, last) => {
|
|
47
|
+
if (previous !== null && total.total === previous.total)
|
|
48
|
+
return zeroUsage;
|
|
49
|
+
if (previous === null || total.total < previous.total || total.total === last.total)
|
|
50
|
+
return last;
|
|
51
|
+
return {
|
|
52
|
+
input: total.input - previous.input,
|
|
53
|
+
cached: total.cached - previous.cached,
|
|
54
|
+
cacheWrite: total.cacheWrite - previous.cacheWrite,
|
|
55
|
+
output: total.output - previous.output,
|
|
56
|
+
reasoning: total.reasoning - previous.reasoning,
|
|
57
|
+
total: total.total - previous.total
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
/** The last observation of one series this rollout kept: what it said, and when. */
|
|
61
|
+
const Kept = Schema.NullOr(Schema.Struct({ signature: Schema.String, at: Schema.Int }));
|
|
62
|
+
/**
|
|
63
|
+
* How long an unchanged reading may go unrecorded. Codex repeats its limits on every request; one
|
|
64
|
+
* observation per window of this length keeps the series honest about when it was last seen, and
|
|
65
|
+
* bounds how far a change back can land from where it happened when rollouts interleave.
|
|
66
|
+
*/
|
|
67
|
+
export const RESAMPLE_MILLIS = 10 * 60 * 1000;
|
|
68
|
+
export const CodexReaderState = Schema.Struct({
|
|
69
|
+
cwd: Schema.String,
|
|
70
|
+
branch: Schema.String,
|
|
71
|
+
model: Schema.NullOr(Schema.String),
|
|
72
|
+
activeTicket: Schema.NullOr(Schema.String),
|
|
73
|
+
/** The session's running usage at the last valid token_count read. */
|
|
74
|
+
previousTotal: Schema.NullOr(CodexUsage),
|
|
75
|
+
/** This rollout's own session id, from its first session_meta. */
|
|
76
|
+
ownSession: Schema.NullOr(Schema.String),
|
|
77
|
+
/**
|
|
78
|
+
* A forked subagent rollout copies its parent's history first; lines with an ordinal below this
|
|
79
|
+
* one are that copy, already booked from the parent's own rollout.
|
|
80
|
+
*/
|
|
81
|
+
historyStart: Schema.NullOr(Schema.Int),
|
|
82
|
+
/** A subagent's rollout: its user items are the parent agent delegating, not the human typing. */
|
|
83
|
+
delegated: Schema.Boolean,
|
|
84
|
+
/** The rollout writes the human's prompts as user_message events; its response items are copies. */
|
|
85
|
+
userEvents: Schema.Boolean,
|
|
86
|
+
keptPrimary: Kept,
|
|
87
|
+
keptSecondary: Kept,
|
|
88
|
+
keptCredits: Kept
|
|
89
|
+
});
|
|
90
|
+
export const initialCodexState = {
|
|
91
|
+
cwd: "",
|
|
92
|
+
branch: "",
|
|
93
|
+
model: null,
|
|
94
|
+
activeTicket: null,
|
|
95
|
+
previousTotal: null,
|
|
96
|
+
ownSession: null,
|
|
97
|
+
historyStart: null,
|
|
98
|
+
delegated: false,
|
|
99
|
+
userEvents: false,
|
|
100
|
+
keptPrimary: null,
|
|
101
|
+
keptSecondary: null,
|
|
102
|
+
keptCredits: null
|
|
103
|
+
};
|
|
104
|
+
const TokenUsage = Schema.Struct({
|
|
105
|
+
input_tokens: Count,
|
|
106
|
+
cached_input_tokens: Schema.optionalKey(Count),
|
|
107
|
+
cache_write_input_tokens: Schema.optionalKey(Count),
|
|
108
|
+
output_tokens: Count,
|
|
109
|
+
reasoning_output_tokens: Schema.optionalKey(Count),
|
|
110
|
+
total_tokens: Count
|
|
111
|
+
});
|
|
112
|
+
const normalizeUsage = (usage) => ({
|
|
113
|
+
input: usage.input_tokens,
|
|
114
|
+
cached: usage.cached_input_tokens ?? 0,
|
|
115
|
+
cacheWrite: usage.cache_write_input_tokens ?? 0,
|
|
116
|
+
output: usage.output_tokens,
|
|
117
|
+
reasoning: usage.reasoning_output_tokens ?? 0,
|
|
118
|
+
total: usage.total_tokens
|
|
119
|
+
});
|
|
120
|
+
const Window = Schema.Struct({
|
|
121
|
+
used_percent: Schema.Finite,
|
|
122
|
+
window_minutes: Schema.optionalKey(Schema.NullOr(Schema.Int)),
|
|
123
|
+
resets_at: Schema.optionalKey(Schema.NullOr(Schema.Finite))
|
|
124
|
+
});
|
|
125
|
+
const RateLimits = Schema.Struct({
|
|
126
|
+
limit_id: Schema.optionalKey(Schema.NullOr(Schema.String)),
|
|
127
|
+
primary: Schema.optionalKey(Schema.NullOr(Window)),
|
|
128
|
+
secondary: Schema.optionalKey(Schema.NullOr(Window)),
|
|
129
|
+
credits: Schema.optionalKey(Schema.NullOr(CodexCredits))
|
|
130
|
+
});
|
|
131
|
+
const RolloutLine = Schema.Union([
|
|
132
|
+
Schema.Struct({
|
|
133
|
+
type: Schema.Literal("session_meta"),
|
|
134
|
+
ordinal: Schema.optionalKey(Schema.Int),
|
|
135
|
+
payload: Schema.Struct({
|
|
136
|
+
id: Schema.optionalKey(Schema.String),
|
|
137
|
+
subagent_history_start_ordinal: Schema.optionalKey(Schema.NullOr(Schema.Int)),
|
|
138
|
+
thread_source: Schema.optionalKey(Schema.NullOr(Schema.String)),
|
|
139
|
+
source: Schema.optionalKey(Schema.NullOr(Schema.Union([Schema.String, Schema.Struct({ subagent: Schema.optionalKey(Schema.Unknown) })]))),
|
|
140
|
+
parent_thread_id: Schema.optionalKey(Schema.NullOr(Schema.String)),
|
|
141
|
+
cwd: Schema.optionalKey(Schema.NullOr(Schema.String)),
|
|
142
|
+
git: Schema.optionalKey(Schema.NullOr(Schema.Struct({ branch: Schema.optionalKey(Schema.NullOr(Schema.String)) })))
|
|
143
|
+
})
|
|
144
|
+
}),
|
|
145
|
+
Schema.Struct({
|
|
146
|
+
type: Schema.Literal("turn_context"),
|
|
147
|
+
ordinal: Schema.optionalKey(Schema.Int),
|
|
148
|
+
payload: Schema.Struct({
|
|
149
|
+
model: Schema.optionalKey(Schema.NullOr(Schema.String)),
|
|
150
|
+
cwd: Schema.optionalKey(Schema.NullOr(Schema.String))
|
|
151
|
+
})
|
|
152
|
+
}),
|
|
153
|
+
Schema.Struct({
|
|
154
|
+
type: Schema.Literal("response_item"),
|
|
155
|
+
ordinal: Schema.optionalKey(Schema.Int),
|
|
156
|
+
payload: Schema.Struct({
|
|
157
|
+
type: Schema.Literal("message"),
|
|
158
|
+
role: Schema.Literal("user"),
|
|
159
|
+
content: Schema.Array(Schema.Struct({ type: Schema.String, text: Schema.optionalKey(Schema.String) }))
|
|
160
|
+
})
|
|
161
|
+
}),
|
|
162
|
+
Schema.Struct({
|
|
163
|
+
type: Schema.Literal("event_msg"),
|
|
164
|
+
ordinal: Schema.optionalKey(Schema.Int),
|
|
165
|
+
timestamp: Schema.String,
|
|
166
|
+
payload: Schema.Struct({ type: Schema.Literal("user_message"), message: Schema.String })
|
|
167
|
+
}),
|
|
168
|
+
Schema.Struct({
|
|
169
|
+
type: Schema.Literal("event_msg"),
|
|
170
|
+
ordinal: Schema.optionalKey(Schema.Int),
|
|
171
|
+
timestamp: Schema.String,
|
|
172
|
+
payload: Schema.Struct({
|
|
173
|
+
type: Schema.Literal("token_count"),
|
|
174
|
+
info: Schema.optionalKey(Schema.NullOr(Schema.Struct({
|
|
175
|
+
total_token_usage: TokenUsage,
|
|
176
|
+
last_token_usage: TokenUsage
|
|
177
|
+
}))),
|
|
178
|
+
rate_limits: Schema.optionalKey(Schema.NullOr(RateLimits))
|
|
179
|
+
})
|
|
180
|
+
})
|
|
181
|
+
]);
|
|
182
|
+
const SESSION_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/iu;
|
|
183
|
+
const encodeReading = Schema.encodeSync(Schema.fromJsonString(LimitReading));
|
|
184
|
+
const encodeBalance = Schema.encodeSync(Schema.fromJsonString(BalanceValue));
|
|
185
|
+
const decodeLine = Schema.decodeUnknownOption(Schema.fromJsonString(RolloutLine));
|
|
186
|
+
/** Lines a decode is spent on; everything else in a rollout is conversation or tool traffic. */
|
|
187
|
+
const RELEVANT = ["\"session_meta\"", "\"turn_context\"", "\"token_count\"", "\"role\":\"user\"", "\"user_message\""];
|
|
188
|
+
const mayMatter = (text) => RELEVANT.some((marker) => text.includes(marker));
|
|
189
|
+
/** User-role response items that fail to decode are other item kinds; only these count as damage. */
|
|
190
|
+
const mustDecode = (text) => text.includes("\"session_meta\"") || text.includes("\"turn_context\"") || text.includes("\"token_count\"");
|
|
191
|
+
/** Keep an observation when it says something new, or when the last kept one is getting old. */
|
|
192
|
+
const worthKeeping = (kept, signature, at) => kept === null || kept.signature !== signature || at - kept.at >= RESAMPLE_MILLIS || at < kept.at;
|
|
193
|
+
const snapshotOf = (file, observedAt, label, window) => {
|
|
194
|
+
if (window === undefined || window === null)
|
|
195
|
+
return [];
|
|
196
|
+
const minutes = window.window_minutes;
|
|
197
|
+
const resets = window.resets_at;
|
|
198
|
+
const snapshot = {
|
|
199
|
+
agent: "codex",
|
|
200
|
+
machine: file.machine,
|
|
201
|
+
source: "codex-rollout",
|
|
202
|
+
label,
|
|
203
|
+
windowMinutes: minutes !== undefined && minutes !== null && minutes > 0 ? minutes : null,
|
|
204
|
+
observedAt,
|
|
205
|
+
reading: {
|
|
206
|
+
_tag: "Known",
|
|
207
|
+
usedPercent: window.used_percent,
|
|
208
|
+
resetsAt: resets === undefined || resets === null ? null : Math.round(resets * 1000)
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
return [snapshot];
|
|
212
|
+
};
|
|
213
|
+
const snapshotsOf = (file, observedAt, limits) => [
|
|
214
|
+
...snapshotOf(file, observedAt, "primary", limits.primary),
|
|
215
|
+
...snapshotOf(file, observedAt, "secondary", limits.secondary)
|
|
216
|
+
];
|
|
217
|
+
/** Reads one chunk of a rollout, continuing from the state the previous chunk ended in. */
|
|
218
|
+
export const readCodex = (file, lines, initial) => {
|
|
219
|
+
const events = [];
|
|
220
|
+
const snapshots = [];
|
|
221
|
+
const balances = [];
|
|
222
|
+
let skipped = noSkips;
|
|
223
|
+
let state = initial;
|
|
224
|
+
for (const line of lines) {
|
|
225
|
+
if (!mayMatter(line.text))
|
|
226
|
+
continue;
|
|
227
|
+
const decoded = decodeLine(line.text);
|
|
228
|
+
if (Option.isNone(decoded)) {
|
|
229
|
+
if (mustDecode(line.text))
|
|
230
|
+
skipped = countSkip(skipped, "unparseableLine");
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
const record = decoded.value;
|
|
234
|
+
const copied = state.historyStart !== null && record.ordinal !== undefined && record.ordinal < state.historyStart;
|
|
235
|
+
switch (record.type) {
|
|
236
|
+
case "session_meta": {
|
|
237
|
+
// A fork copies its parent's session_meta too; only this rollout's own one describes it.
|
|
238
|
+
// The rollout's file name carries its own id, so the order of the two lines does not matter;
|
|
239
|
+
// without an id in the name, the first session_meta is taken as the rollout's own.
|
|
240
|
+
const id = record.payload.id ?? null;
|
|
241
|
+
const own = state.ownSession ?? (SESSION_ID.test(file.sessionId) ? file.sessionId : id);
|
|
242
|
+
if (own !== null && id !== null && id !== own)
|
|
243
|
+
break;
|
|
244
|
+
state = {
|
|
245
|
+
...state,
|
|
246
|
+
ownSession: own,
|
|
247
|
+
historyStart: state.historyStart ?? record.payload.subagent_history_start_ordinal ?? null,
|
|
248
|
+
delegated: state.delegated || record.payload.thread_source === "subagent" ||
|
|
249
|
+
(Predicate.isObject(record.payload.source) && record.payload.source.subagent !== undefined) ||
|
|
250
|
+
(record.payload.parent_thread_id !== undefined && record.payload.parent_thread_id !== null),
|
|
251
|
+
cwd: record.payload.cwd ?? state.cwd,
|
|
252
|
+
branch: record.payload.git?.branch ?? state.branch
|
|
253
|
+
};
|
|
254
|
+
break;
|
|
255
|
+
}
|
|
256
|
+
case "turn_context": {
|
|
257
|
+
// Each turn says where it ran; a resumed session may have moved to another worktree. The
|
|
258
|
+
// branch was read for the old directory, so a move drops it rather than book the new work to
|
|
259
|
+
// the old branch's ticket.
|
|
260
|
+
// A fork's copied parent turns say where the parent ran, not the fork: they leave its own
|
|
261
|
+
// directory and branch alone.
|
|
262
|
+
if (copied) {
|
|
263
|
+
state = { ...state, model: record.payload.model ?? state.model };
|
|
264
|
+
break;
|
|
265
|
+
}
|
|
266
|
+
const cwd = record.payload.cwd ?? state.cwd;
|
|
267
|
+
state = {
|
|
268
|
+
...state,
|
|
269
|
+
model: record.payload.model ?? state.model,
|
|
270
|
+
cwd,
|
|
271
|
+
branch: cwd === state.cwd || state.cwd === "" ? state.branch : ""
|
|
272
|
+
};
|
|
273
|
+
break;
|
|
274
|
+
}
|
|
275
|
+
case "response_item": {
|
|
276
|
+
// A subagent's own user items are its delegated task; the parent history it copied holds the
|
|
277
|
+
// human's turns, which still set the Active Ticket. A rollout that writes user_message events
|
|
278
|
+
// has its response items as copies (replayed history included), so those are not read.
|
|
279
|
+
if ((state.delegated && !copied) || state.userEvents)
|
|
280
|
+
break;
|
|
281
|
+
const typed = record.payload.content
|
|
282
|
+
.filter((item) => item.type === "input_text")
|
|
283
|
+
.map((item) => codexHumanText(item.text ?? ""))
|
|
284
|
+
.filter((text) => text !== "")
|
|
285
|
+
.join("\n");
|
|
286
|
+
if (typed !== "")
|
|
287
|
+
state = { ...state, activeTicket: singleTicket(typed) };
|
|
288
|
+
break;
|
|
289
|
+
}
|
|
290
|
+
case "event_msg": {
|
|
291
|
+
if (record.payload.type === "user_message") {
|
|
292
|
+
if (state.delegated && !copied)
|
|
293
|
+
break;
|
|
294
|
+
const typed = codexHumanText(record.payload.message);
|
|
295
|
+
state = { ...state, userEvents: true, activeTicket: typed === "" ? state.activeTicket : singleTicket(typed) };
|
|
296
|
+
break;
|
|
297
|
+
}
|
|
298
|
+
const observedAt = parseInstant(record.timestamp);
|
|
299
|
+
if (observedAt === null) {
|
|
300
|
+
skipped = countSkip(skipped, "missingTimestamp");
|
|
301
|
+
break;
|
|
302
|
+
}
|
|
303
|
+
const info = record.payload.info;
|
|
304
|
+
if (info !== undefined && info !== null) {
|
|
305
|
+
const total = normalizeUsage(info.total_token_usage);
|
|
306
|
+
const delta = usageDelta(state.previousTotal, total, normalizeUsage(info.last_token_usage));
|
|
307
|
+
// Codex counts cache hits inside input and reasoning inside output; split them out.
|
|
308
|
+
const tokens = {
|
|
309
|
+
input: Math.max(0, delta.input - delta.cached - delta.cacheWrite),
|
|
310
|
+
output: Math.max(0, delta.output - delta.reasoning),
|
|
311
|
+
reasoning: Math.max(0, delta.reasoning),
|
|
312
|
+
cacheRead: Math.max(0, delta.cached),
|
|
313
|
+
cacheWrite5m: Math.max(0, delta.cacheWrite),
|
|
314
|
+
cacheWrite1h: 0
|
|
315
|
+
};
|
|
316
|
+
// Copied fork history only advances the running total, so the fork's own first request
|
|
317
|
+
// diffs against the right baseline; its requests were booked from the parent's rollout.
|
|
318
|
+
if (delta.total !== 0 && !copied) {
|
|
319
|
+
events.push({
|
|
320
|
+
agent: "codex",
|
|
321
|
+
dedupeKey: `${file.sessionId}@${line.offset}`,
|
|
322
|
+
machine: file.machine,
|
|
323
|
+
sessionId: file.sessionId,
|
|
324
|
+
occurredAt: observedAt,
|
|
325
|
+
model: state.model ?? "unknown",
|
|
326
|
+
fast: false,
|
|
327
|
+
tokens,
|
|
328
|
+
attribution: { cwd: state.cwd, branch: state.branch, activeTicket: state.activeTicket }
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
state = { ...state, previousTotal: total };
|
|
332
|
+
}
|
|
333
|
+
const limits = record.payload.rate_limits;
|
|
334
|
+
// Copied history carries the parent's limit readings restamped at fork time: not observations.
|
|
335
|
+
// Older rollouts (to early 2026) wrote the account limit with no limit_id; newer ones name it
|
|
336
|
+
// "codex". Any other id is a model-scoped limit.
|
|
337
|
+
const accountLimit = limits !== undefined && limits !== null &&
|
|
338
|
+
(limits.limit_id === "codex" || limits.limit_id === undefined || limits.limit_id === null);
|
|
339
|
+
if (!copied && accountLimit) {
|
|
340
|
+
for (const snapshot of snapshotsOf(file, observedAt, limits)) {
|
|
341
|
+
const signature = `${snapshot.windowMinutes} ${encodeReading(snapshot.reading)}`;
|
|
342
|
+
const kept = snapshot.label === "primary" ? state.keptPrimary : state.keptSecondary;
|
|
343
|
+
if (!worthKeeping(kept, signature, observedAt))
|
|
344
|
+
continue;
|
|
345
|
+
snapshots.push(snapshot);
|
|
346
|
+
state = snapshot.label === "primary"
|
|
347
|
+
? { ...state, keptPrimary: { signature, at: observedAt } }
|
|
348
|
+
: { ...state, keptSecondary: { signature, at: observedAt } };
|
|
349
|
+
}
|
|
350
|
+
if (limits.credits !== undefined && limits.credits !== null) {
|
|
351
|
+
const value = classifyCodexCredits(limits.credits);
|
|
352
|
+
const signature = encodeBalance(value);
|
|
353
|
+
if (value._tag === "Unknown" || worthKeeping(state.keptCredits, signature, observedAt)) {
|
|
354
|
+
balances.push({ kind: "codex-credits", machine: file.machine, observedAt, value });
|
|
355
|
+
state = { ...state, keptCredits: { signature, at: observedAt } };
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
break;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
return { events, snapshots, balances, skipped, state };
|
|
364
|
+
};
|
|
365
|
+
//# sourceMappingURL=CodexReader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CodexReader.js","sourceRoot":"","sources":["../../src/core/CodexReader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { FileSystem, Layer, Path } from "effect";
|
|
2
|
+
import { StoreError, UsageStore } from "./Store.js";
|
|
3
|
+
/** The store, opened privately in `directory` (`usage.db`), migrated and ready. */
|
|
4
|
+
export declare const databaseLayer: (directory: string) => Layer.Layer<UsageStore, StoreError, FileSystem.FileSystem | Path.Path>;
|