feat(codex): add weekly usage report command#904
feat(codex): add weekly usage report command#904Cheese-Yu wants to merge 1 commit intoryoppippi:mainfrom
Conversation
📝 WalkthroughWalkthroughThis PR introduces a new weekly reporting feature to the Codex CLI. It adds type definitions for weekly summaries, implements a date utility for week-key derivation, creates a report builder that aggregates token usage and costs by week with pricing calculations, registers a new Changes
Sequence DiagramsequenceDiagram
participant CLI as Weekly CLI Command
participant EventLoader as Event Loader
participant ReportBuilder as Report Builder
participant PricingSource as Pricing Source
participant Output as Output Formatter
CLI->>EventLoader: Load token usage events
EventLoader-->>CLI: Return TokenUsageEvent[]
CLI->>ReportBuilder: buildWeeklyReport(events, filters, timezone)
ReportBuilder->>ReportBuilder: Filter events by since/until
ReportBuilder->>ReportBuilder: Group events by weekKey
ReportBuilder->>ReportBuilder: Aggregate per-week & per-model usage
ReportBuilder->>PricingSource: Fetch pricing for each model
PricingSource-->>ReportBuilder: Model pricing data
ReportBuilder->>ReportBuilder: Calculate weekly costUSD
ReportBuilder-->>CLI: WeeklyReportRow[]
CLI->>Output: Format rows as JSON or table
Output-->>CLI: Formatted result
CLI-->>User: Display weekly report with totals
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (2)
apps/codex/src/weekly-report.ts (1)
83-86: Consider parallelizing pricing lookups for better performance.The sequential
awaitin the loop fetches pricing one model at a time. For reports with many unique models, this could be slow. UsingPromise.allwould parallelize the requests.♻️ Suggested parallel fetch
const modelPricing = new Map<string, Awaited<ReturnType<PricingSource['getPricing']>>>(); -for (const modelName of uniqueModels) { - modelPricing.set(modelName, await pricingSource.getPricing(modelName)); -} +const pricingEntries = await Promise.all( + Array.from(uniqueModels).map(async (modelName) => { + const pricing = await pricingSource.getPricing(modelName); + return [modelName, pricing] as const; + }), +); +for (const [modelName, pricing] of pricingEntries) { + modelPricing.set(modelName, pricing); +}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/codex/src/weekly-report.ts` around lines 83 - 86, The loop that fills modelPricing does sequential awaits (for const modelName of uniqueModels) which is slow; instead map uniqueModels to an array of promises using pricingSource.getPricing(modelName), run them in parallel with Promise.all, then populate the modelPricing Map with the resolved results; update the code that currently references modelPricing, uniqueModels, and pricingSource.getPricing to use the Promise.all pattern and preserve the same Map entries (key = modelName, value = resolved pricing).apps/codex/src/commands/weekly.ts (1)
77-95: Consider reusing thetotalsForDisplayaccumulation logic.The totals are computed twice: once in lines 77-95 for JSON output and again in lines 135-151 for display. While the structures differ slightly (
reasoningOutputTokensvsreasoningTokens), consider extracting a single accumulation pass or reusing the first result to avoid redundant iteration overrows.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/codex/src/commands/weekly.ts` around lines 77 - 95, The code iterates rows twice to compute totals (first into totals via rows.reduce and again into totalsForDisplay), which is redundant; modify the logic to compute a single accumulator from rows (reuse the existing rows.reduce that produces totals) and then derive totalsForDisplay from that result (map totals.reasoningOutputTokens to reasoningTokens and compute any display-specific fields) or replace the second reduce with a conversion function that transforms totals into the display shape; update references to use the single computed totals to avoid the duplicate pass.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@apps/codex/src/commands/weekly.ts`:
- Around line 77-95: The code iterates rows twice to compute totals (first into
totals via rows.reduce and again into totalsForDisplay), which is redundant;
modify the logic to compute a single accumulator from rows (reuse the existing
rows.reduce that produces totals) and then derive totalsForDisplay from that
result (map totals.reasoningOutputTokens to reasoningTokens and compute any
display-specific fields) or replace the second reduce with a conversion function
that transforms totals into the display shape; update references to use the
single computed totals to avoid the duplicate pass.
In `@apps/codex/src/weekly-report.ts`:
- Around line 83-86: The loop that fills modelPricing does sequential awaits
(for const modelName of uniqueModels) which is slow; instead map uniqueModels to
an array of promises using pricingSource.getPricing(modelName), run them in
parallel with Promise.all, then populate the modelPricing Map with the resolved
results; update the code that currently references modelPricing, uniqueModels,
and pricingSource.getPricing to use the Promise.all pattern and preserve the
same Map entries (key = modelName, value = resolved pricing).
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: a96db863-d886-492b-8323-2bcc6416993c
📒 Files selected for processing (6)
apps/codex/README.mdapps/codex/src/_types.tsapps/codex/src/commands/weekly.tsapps/codex/src/date-utils.tsapps/codex/src/run.tsapps/codex/src/weekly-report.ts
Motivation
@ccusage/codex@latest#780.Description
weeklysubcommand implemented inapps/codex/src/commands/weekly.tsand register it in the CLI router inapps/codex/src/run.ts.apps/codex/src/weekly-report.ts, usingPricingSourcefor per-model pricing and producing per-model breakdowns.toWeekKey()toapps/codex/src/date-utils.tsand addWeeklyUsageSummary/WeeklyReportRowinapps/codex/src/_types.ts.apps/codex/README.mdto document the newweeklycommand and feature list.Testing
pnpm --filter @ccusage/codex format,pnpm --filter @ccusage/codex typecheck, andpnpm --filter @ccusage/codex test, and the Codex package formatting, typecheck and tests passed (Codex tests: all reported test files passed).pnpm run typecheckandpnpm run test; these produced failures unrelated to this change (other packages had network/config dependent failures and test failures inapps/ccusage), so workspace-wide CI may need environment/pricing fetch fixes to fully green.@ccusage/codex@latest#780.Summary by CodeRabbit