@oh-my-pi/omp-stats 15.0.2 → 15.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/package.json +3 -3
- package/src/parser.ts +39 -1
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@oh-my-pi/omp-stats",
|
|
4
|
-
"version": "15.0
|
|
4
|
+
"version": "15.1.0",
|
|
5
5
|
"description": "Local observability dashboard for pi AI usage statistics",
|
|
6
6
|
"homepage": "https://omp.sh",
|
|
7
7
|
"author": "Can Boluk",
|
|
@@ -37,8 +37,8 @@
|
|
|
37
37
|
"fmt": "biome format --write ."
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@oh-my-pi/pi-ai": "15.0
|
|
41
|
-
"@oh-my-pi/pi-utils": "15.0
|
|
40
|
+
"@oh-my-pi/pi-ai": "15.1.0",
|
|
41
|
+
"@oh-my-pi/pi-utils": "15.1.0",
|
|
42
42
|
"@tailwindcss/node": "^4.2.4",
|
|
43
43
|
"chart.js": "^4.5.1",
|
|
44
44
|
"date-fns": "^4.1.0",
|
package/src/parser.ts
CHANGED
|
@@ -164,9 +164,45 @@ function parseSessionEntriesLenient(bytes: Uint8Array): { entries: SessionEntry[
|
|
|
164
164
|
return { entries, read: cursor };
|
|
165
165
|
}
|
|
166
166
|
|
|
167
|
+
function scanLastServiceTier(bytes: Uint8Array): ServiceTier | undefined {
|
|
168
|
+
let cursor = 0;
|
|
169
|
+
let currentServiceTier: ServiceTier | undefined;
|
|
170
|
+
|
|
171
|
+
while (cursor < bytes.length) {
|
|
172
|
+
const { values, error, read, done } = Bun.JSONL.parseChunk(bytes, cursor, bytes.length);
|
|
173
|
+
for (const value of values as SessionEntry[]) {
|
|
174
|
+
if (isServiceTierChange(value)) currentServiceTier = value.serviceTier ?? undefined;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (error) {
|
|
178
|
+
const nextNewline = bytes.indexOf(LF, Math.max(read, cursor));
|
|
179
|
+
if (nextNewline === -1) break;
|
|
180
|
+
cursor = nextNewline + 1;
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (read <= cursor) break;
|
|
185
|
+
cursor = read;
|
|
186
|
+
if (done) break;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
return currentServiceTier;
|
|
190
|
+
}
|
|
167
191
|
/**
|
|
168
192
|
* Parse a session file and extract all assistant message stats.
|
|
169
193
|
* Uses incremental reading with offset tracking.
|
|
194
|
+
*
|
|
195
|
+
* Service-tier carry-over: `currentServiceTier` is a session-scoped piece of
|
|
196
|
+
* state derived from `service_tier_change` entries that affects whether
|
|
197
|
+
* subsequent OpenAI assistant replies count as premium requests. Incremental
|
|
198
|
+
* syncs that resume past the most-recent tier change would otherwise lose
|
|
199
|
+
* that state and silently record `premiumRequests = 0` for priority traffic
|
|
200
|
+
* (the coding-agent stopped folding the tier into `usage.premiumRequests`
|
|
201
|
+
* after 13f59162e — the parser is now the sole source of truth). When
|
|
202
|
+
* `fromOffset > 0` we therefore scan the bytes preceding `fromOffset`
|
|
203
|
+
* for the latest service-tier value before parsing the unprocessed tail.
|
|
204
|
+
* The scan only keeps the current tier and does not materialize prefix
|
|
205
|
+
* entries, preserving offset-based memory behavior for large sessions.
|
|
170
206
|
*/
|
|
171
207
|
export interface ParseSessionResult {
|
|
172
208
|
stats: MessageStats[];
|
|
@@ -174,7 +210,6 @@ export interface ParseSessionResult {
|
|
|
174
210
|
userLinks: UserMessageLink[];
|
|
175
211
|
newOffset: number;
|
|
176
212
|
}
|
|
177
|
-
|
|
178
213
|
export async function parseSessionFile(sessionPath: string, fromOffset = 0): Promise<ParseSessionResult> {
|
|
179
214
|
let bytes: Uint8Array;
|
|
180
215
|
try {
|
|
@@ -193,6 +228,9 @@ export async function parseSessionFile(sessionPath: string, fromOffset = 0): Pro
|
|
|
193
228
|
const unprocessed = bytes.subarray(start);
|
|
194
229
|
const { entries, read } = parseSessionEntriesLenient(unprocessed);
|
|
195
230
|
let currentServiceTier: ServiceTier | undefined;
|
|
231
|
+
if (start > 0) {
|
|
232
|
+
currentServiceTier = scanLastServiceTier(bytes.subarray(0, start));
|
|
233
|
+
}
|
|
196
234
|
for (const entry of entries) {
|
|
197
235
|
if (isServiceTierChange(entry)) {
|
|
198
236
|
currentServiceTier = entry.serviceTier ?? undefined;
|