(
filePath: string,
options?: { notBeforeTimestampMs?: number },
)
| 502 | } |
| 503 | |
| 504 | async function readLatestTokenCountInfo( |
| 505 | filePath: string, |
| 506 | options?: { notBeforeTimestampMs?: number }, |
| 507 | ): Promise<CodexTokenCountInfo | null> { |
| 508 | let rawContent = "" |
| 509 | try { |
| 510 | rawContent = await readFile(filePath, "utf8") |
| 511 | } catch { |
| 512 | return null |
| 513 | } |
| 514 | |
| 515 | const lines = rawContent.split("\n") |
| 516 | for (let index = lines.length - 1; index >= 0; index -= 1) { |
| 517 | const rawLine = lines[index]?.trim() |
| 518 | if (!rawLine) continue |
| 519 | |
| 520 | let parsedLine: any |
| 521 | try { |
| 522 | parsedLine = JSON.parse(rawLine) |
| 523 | } catch { |
| 524 | continue |
| 525 | } |
| 526 | |
| 527 | if ( |
| 528 | parsedLine?.type !== "event_msg" || |
| 529 | parsedLine?.payload?.type !== "token_count" |
| 530 | ) { |
| 531 | continue |
| 532 | } |
| 533 | |
| 534 | const eventTimestampMs = toTimestampMs(parsedLine?.timestamp) |
| 535 | const notBeforeTimestampMs = options?.notBeforeTimestampMs |
| 536 | if ( |
| 537 | notBeforeTimestampMs !== undefined && |
| 538 | (eventTimestampMs === undefined || eventTimestampMs < notBeforeTimestampMs) |
| 539 | ) { |
| 540 | continue |
| 541 | } |
| 542 | |
| 543 | const rawInfo = parsedLine.payload?.info |
| 544 | if (!rawInfo || typeof rawInfo !== "object") continue |
| 545 | |
| 546 | const rawTokenUsage = (rawInfo as any).last_token_usage |
| 547 | let lastTokenUsage: CodexTokenUsage | undefined |
| 548 | if (rawTokenUsage && typeof rawTokenUsage === "object") { |
| 549 | const tokenUsage = rawTokenUsage as any |
| 550 | const parsedTokenUsage: CodexTokenUsage = { |
| 551 | input_tokens: toNonNegativeInt(tokenUsage.input_tokens), |
| 552 | cached_input_tokens: toNonNegativeInt(tokenUsage.cached_input_tokens), |
| 553 | output_tokens: toNonNegativeInt(tokenUsage.output_tokens), |
| 554 | total_tokens: toNonNegativeInt(tokenUsage.total_tokens), |
| 555 | } |
| 556 | if (Object.values(parsedTokenUsage).some((tokenCount) => tokenCount !== undefined)) { |
| 557 | lastTokenUsage = parsedTokenUsage |
| 558 | } |
| 559 | } |
| 560 | |
| 561 | const modelContextWindow = toNonNegativeInt( |
no test coverage detected