-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Expose Codex scan completeness in cost JSON #2520
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,5 @@ | ||
| // Generated by Scripts/regenerate-codex-parser-hash.sh. Do not edit by hand. | ||
|
|
||
| enum CodexParserHash { | ||
| static let value = "3aa49b47f4b78e13" | ||
| static let value = "7f01e8da62d05fec" | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -962,6 +962,11 @@ enum CostUsageScanner { | |
| let parsedBytes: Int64 | ||
| } | ||
|
|
||
| struct DailyReportLoadResult { | ||
| let report: CostUsageDailyReport | ||
| let historyCoverageIsEstablished: Bool | ||
| } | ||
|
|
||
| enum ClaudePathRole: String, Codable { | ||
| case parent | ||
| case subagent | ||
|
|
@@ -1009,6 +1014,23 @@ enum CostUsageScanner { | |
| now: Date = Date(), | ||
| options: Options = Options(), | ||
| checkCancellation: CancellationCheck?) throws -> CostUsageDailyReport | ||
| { | ||
| try self.loadDailyReportResultCancellable( | ||
| provider: provider, | ||
| since: since, | ||
| until: until, | ||
| now: now, | ||
| options: options, | ||
| checkCancellation: checkCancellation).report | ||
| } | ||
|
|
||
| static func loadDailyReportResultCancellable( | ||
| provider: UsageProvider, | ||
| since: Date, | ||
| until: Date, | ||
| now: Date = Date(), | ||
| options: Options = Options(), | ||
| checkCancellation: CancellationCheck?) throws -> DailyReportLoadResult | ||
| { | ||
| let range = CostUsageDayRange(since: since, until: until, calendar: options.calendar) | ||
| let emptyReport = CostUsageDailyReport(data: [], summary: nil) | ||
|
|
@@ -1022,31 +1044,35 @@ enum CostUsageScanner { | |
| options: options, | ||
| checkCancellation: checkCancellation) | ||
| case .claude: | ||
| return try self.loadClaudeDaily( | ||
| provider: .claude, | ||
| range: range, | ||
| now: now, | ||
| options: options, | ||
| checkCancellation: checkCancellation) | ||
| return try DailyReportLoadResult( | ||
| report: self.loadClaudeDaily( | ||
| provider: .claude, | ||
| range: range, | ||
| now: now, | ||
| options: options, | ||
| checkCancellation: checkCancellation), | ||
| historyCoverageIsEstablished: true) | ||
| case .vertexai: | ||
| var filtered = options | ||
| if filtered.claudeLogProviderFilter == .all { | ||
| filtered.claudeLogProviderFilter = .vertexAIOnly | ||
| } | ||
| return try self.loadClaudeDaily( | ||
| provider: .vertexai, | ||
| range: range, | ||
| now: now, | ||
| options: filtered, | ||
| checkCancellation: checkCancellation) | ||
| return try DailyReportLoadResult( | ||
| report: self.loadClaudeDaily( | ||
| provider: .vertexai, | ||
| range: range, | ||
| now: now, | ||
| options: filtered, | ||
| checkCancellation: checkCancellation), | ||
| historyCoverageIsEstablished: true) | ||
| case .openai, .azureopenai, .clinepass, .zai, .gemini, .antigravity, .cursor, .opencode, .opencodego, .alibaba, | ||
| .alibabatokenplan, .qwencloud, .factory, | ||
| .copilot, .devin, .minimax, .manus, .kilo, .kiro, .kimi, .moonshot, .augment, .jetbrains, .amp, | ||
| .ollama, .t3chat, .synthetic, .openrouter, .elevenlabs, .warp, .perplexity, .mimo, .doubao, .sakana, | ||
| .abacus, .mistral, .deepseek, .deepinfra, .codebuff, .crof, .windsurf, .zed, .venice, .commandcode, | ||
| .qoder, .stepfun, .bedrock, .grok, .groq, .llmproxy, .litellm, .deepgram, .poe, .chutes, .neuralwatt, | ||
| .clawrouter, .longcat, .sub2api, .wayfinder, .zenmux, .aiand, .zoommate, .xai: | ||
| return emptyReport | ||
| return DailyReportLoadResult(report: emptyReport, historyCoverageIsEstablished: true) | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -3390,7 +3416,7 @@ enum CostUsageScanner { | |
| range: CostUsageDayRange, | ||
| now: Date, | ||
| options: Options, | ||
| checkCancellation: CancellationCheck?) throws -> CostUsageDailyReport | ||
| checkCancellation: CancellationCheck?) throws -> DailyReportLoadResult | ||
| { | ||
| var cache = Self.loadCodexCache(options: options, range: range) | ||
| let nowMs = Int64(now.timeIntervalSince1970 * 1000) | ||
|
|
@@ -3531,8 +3557,22 @@ enum CostUsageScanner { | |
| } | ||
| } | ||
|
|
||
| let shouldRetainWiderWindow = !options.forceRescan && !plan.pricingChanged && !plan | ||
| .priorityMetadataChanged && !plan.needsTurnIDCacheMigration && !plan.needsProjectMetadataMigration | ||
| let historyCoverageIsEstablished = | ||
| scanBudget.resumedPartialFileCount == 0 | ||
| && scanBudget.deferredByBudgetFileCount == 0 | ||
| && !cache.files.values.contains { | ||
| $0.codexScanComplete == false | ||
| && $0.touchesCodexScanWindow( | ||
| sinceKey: range.scanSinceKey, | ||
| untilKey: range.scanUntilKey) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When a recently modified session outside the requested date partitions is only partially scanned before reaching events in the requested window, its cached Useful? React with 👍 / 👎. |
||
| } | ||
| let shouldRetainWiderWindow = !options.forceRescan | ||
| && !plan.pricingChanged | ||
| && !plan.priorityMetadataChanged | ||
| && !plan.needsTurnIDCacheMigration | ||
| && !plan.needsProjectMetadataMigration | ||
| && cache.codexHistoryCoverageIsEstablished == true | ||
| && historyCoverageIsEstablished | ||
| let retainedSinceKey = shouldRetainWiderWindow | ||
| ? [cachedSinceKey, range.scanSinceKey].compactMap(\.self).min() ?? range.scanSinceKey | ||
| : range.scanSinceKey | ||
|
|
@@ -3546,6 +3586,7 @@ enum CostUsageScanner { | |
| cache.codexPricingKey = plan.codexPricingKey | ||
| cache.codexPriorityMetadataKey = plan.codexPriorityMetadataKey | ||
| cache.codexProjectMetadataVersion = Self.codexProjectMetadataVersion | ||
| cache.codexHistoryCoverageIsEstablished = historyCoverageIsEstablished | ||
| if plan.hasPriorityMetadata { | ||
| cache.codexPriorityTurnKeys = Self.mergePriorityTurnKeys( | ||
| existing: shouldRetainWiderWindow ? cache.codexPriorityTurnKeys : nil, | ||
|
|
@@ -3565,12 +3606,14 @@ enum CostUsageScanner { | |
| Self.saveCodexCache(cache, options: options, range: range) | ||
| } | ||
|
|
||
| return Self.buildCodexReportFromCache( | ||
| cache: cache, | ||
| range: range, | ||
| modelsDevCatalog: plan.modelsDevCatalog, | ||
| modelsDevCacheRoot: options.cacheRoot, | ||
| priorityTurns: plan.priorityTurns) | ||
| return DailyReportLoadResult( | ||
| report: Self.buildCodexReportFromCache( | ||
| cache: cache, | ||
| range: range, | ||
| modelsDevCatalog: plan.modelsDevCatalog, | ||
| modelsDevCacheRoot: options.cacheRoot, | ||
| priorityTurns: plan.priorityTurns), | ||
| historyCoverageIsEstablished: cache.codexHistoryCoverageIsEstablished == true) | ||
| } | ||
|
|
||
| private static func codexFileScanContext( | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When the Pi cache is valid but the native Codex cache is rejected by the root, timezone, or requested-window checks above,
reportscan still contain the Pi report and reach this assignment. The coverage value nevertheless comes unconditionally from that rejected native cache; for example, after a complete 30-day native scan and a wider Pi scan, switching to 365 days can hydrate a Pi-only snapshot withhistoryCoverageIsEstablished: trueeven though native Codex history for the expanded window was never scanned. Gate this flag on the same native-cache validity checks, otherwise usefalsewhen only Pi data is loaded.Useful? React with 👍 / 👎.