1212 lines · 48.1 KB · Swift
RawDownload
import Foundation#if canImport(Musl)import Musl#elseif canImport(Glibc)import Glibc#elseimport Darwin#endif extension CostUsageScanner {    static func codexRowsByDayModel(        cache: CostUsageCache,        range: CostUsageDayRange) -> [String: [String: [CodexUsageRow]]]    {        var rowsByDayModel: [String: [String: [CodexUsageRow]]] = [:]        for usage in cache.files.values {            for row in usage.codexRows ?? [] {                guard CostUsageDayRange.isInRange(dayKey: row.day, since: range.sinceKey, until: range.untilKey)                else { continue }                rowsByDayModel[row.day, default: [:]][row.model, default: []].append(row)            }        }        return rowsByDayModel    }     static func codexRowsByDayModel(        rows: [CodexUsageRow],        range: CostUsageDayRange) -> [String: [String: [CodexUsageRow]]]    {        var rowsByDayModel: [String: [String: [CodexUsageRow]]] = [:]        for row in rows {            guard CostUsageDayRange.isInRange(dayKey: row.day, since: range.sinceKey, until: range.untilKey)            else { continue }            rowsByDayModel[row.day, default: [:]][row.model, default: []].append(row)        }        return rowsByDayModel    }     static func codexCostNanosByDayModel(        cache: CostUsageCache,        range: CostUsageDayRange) -> [String: [String: Int64]]    {        self.codexNanosByDayModel(cache: cache, range: range) { $0.codexCostNanos }    }     static func codexPrioritySurchargeNanosByDayModel(        cache: CostUsageCache,        range: CostUsageDayRange) -> [String: [String: Int64]]    {        self.codexNanosByDayModel(cache: cache, range: range) { $0.codexPrioritySurchargeNanos }    }     static func codexStandardCostNanosByDayModel(        cache: CostUsageCache,        range: CostUsageDayRange) -> [String: [String: Int64]]    {        self.codexNanosByDayModel(cache: cache, range: range) { $0.codexStandardCostNanos }    }     static func codexPriorityCostNanosByDayModel(        cache: CostUsageCache,        range: CostUsageDayRange) -> [String: [String: Int64]]    {        self.codexNanosByDayModel(cache: cache, range: range) { $0.codexPriorityCostNanos }    }     static func codexStandardTokensByDayModel(        cache: CostUsageCache,        range: CostUsageDayRange) -> [String: [String: Int]]    {        self.codexIntByDayModel(cache: cache, range: range) { $0.codexStandardTokens }    }     static func codexPriorityTokensByDayModel(        cache: CostUsageCache,        range: CostUsageDayRange) -> [String: [String: Int]]    {        self.codexIntByDayModel(cache: cache, range: range) { $0.codexPriorityTokens }    }     static func codexNanosByDayModel(        cache: CostUsageCache,        range: CostUsageDayRange,        keyPath: (CostUsageFileUsage) -> [String: [String: Int64]]?) -> [String: [String: Int64]]    {        var out: [String: [String: Int64]] = [:]        for usage in cache.files.values {            for (day, models) in keyPath(usage) ?? [:] {                guard CostUsageDayRange.isInRange(dayKey: day, since: range.sinceKey, until: range.untilKey)                else { continue }                for (model, value) in models {                    out[day, default: [:]][model, default: 0] += value                }            }        }        return out    }     static func codexIntByDayModel(        cache: CostUsageCache,        range: CostUsageDayRange,        keyPath: (CostUsageFileUsage) -> [String: [String: Int]]?) -> [String: [String: Int]]    {        var out: [String: [String: Int]] = [:]        for usage in cache.files.values {            for (day, models) in keyPath(usage) ?? [:] {                guard CostUsageDayRange.isInRange(dayKey: day, since: range.sinceKey, until: range.untilKey)                else { continue }                for (model, value) in models {                    out[day, default: [:]][model, default: 0] += value                }            }        }        return out    }     static func codexRowsCostUSD(        rows: [CodexUsageRow],        modelsDevCatalog: ModelsDevCatalog?,        modelsDevCacheRoot: URL?) -> Double?    {        var total: Double = 0        var seen = false        for row in rows {            guard let cost = CostUsagePricing.codexCostUSD(                model: row.model,                inputTokens: row.input,                cachedInputTokens: row.cached,                outputTokens: row.output,                modelsDevCatalog: modelsDevCatalog,                modelsDevCacheRoot: modelsDevCacheRoot)            else { continue }            total += cost            seen = true        }        return seen ? total : nil    }     static func codexPrioritySurchargeUSD(        rows: [CodexUsageRow],        priorityTurns: [String: CodexPriorityTurnMetadata],        modelsDevCatalog: ModelsDevCatalog?,        modelsDevCacheRoot: URL?) -> Double?    {        var total: Double = 0        var seen = false        for row in rows {            guard let turnID = row.turnID, let priorityMetadata = priorityTurns[turnID] else { continue }            let pricedModel = Self.codexPriorityPricingModel(for: row, priorityMetadata: priorityMetadata)            guard let baseCost = CostUsagePricing.codexCostUSD(                model: pricedModel,                inputTokens: row.input,                cachedInputTokens: row.cached,                outputTokens: row.output,                modelsDevCatalog: modelsDevCatalog,                modelsDevCacheRoot: modelsDevCacheRoot),                let priorityCost = CostUsagePricing.codexPriorityCostUSD(                    model: pricedModel,                    inputTokens: row.input,                    cachedInputTokens: row.cached,                    outputTokens: row.output)            else { continue }            total += max(priorityCost - baseCost, 0)            seen = true        }        return seen ? total : nil    }     private static func codexPriorityPricingModel(        for row: CodexUsageRow,        priorityMetadata: CodexPriorityTurnMetadata) -> String    {        guard let model = priorityMetadata.model,              CostUsagePricing.codexPriorityCostUSD(                  model: model,                  inputTokens: row.input,                  cachedInputTokens: row.cached,                  outputTokens: row.output) != nil        else { return row.model }        return model    }     struct CodexRowCostBreakdown {        var standardCostUSD: Double = 0        var priorityCostUSD: Double = 0        var standardTokens: Int = 0        var priorityTokens: Int = 0        var sawStandardCost = false        var sawPriorityCost = false         var optionalStandardCostUSD: Double? {            self.sawStandardCost ? self.standardCostUSD : nil        }         var optionalPriorityCostUSD: Double? {            self.sawPriorityCost ? self.priorityCostUSD : nil        }         var optionalStandardTokens: Int? {            self.standardTokens > 0 ? self.standardTokens : nil        }         var optionalPriorityTokens: Int? {            self.priorityTokens > 0 ? self.priorityTokens : nil        }         var totalCostUSD: Double? {            guard self.sawStandardCost || self.sawPriorityCost else { return nil }            return self.standardCostUSD + self.priorityCostUSD        }         var hasModeSplit: Bool {            self.sawPriorityCost || self.priorityTokens > 0        }    }     static func codexRowCostBreakdown(        rows: [CodexUsageRow],        priorityTurns: [String: CodexPriorityTurnMetadata],        modelsDevCatalog: ModelsDevCatalog?,        modelsDevCacheRoot: URL?) -> CodexRowCostBreakdown    {        var breakdown = CodexRowCostBreakdown()        for row in rows {            let tokenCount = row.input + row.output            let priorityMetadata = row.turnID.flatMap { priorityTurns[$0] }            let isPriority = priorityMetadata != nil            if isPriority {                breakdown.priorityTokens += tokenCount            } else {                breakdown.standardTokens += tokenCount            }            let pricedModel = priorityMetadata.map { Self.codexPriorityPricingModel(for: row, priorityMetadata: $0) }                ?? row.model             let baseCost = CostUsagePricing.codexCostUSD(                model: pricedModel,                inputTokens: row.input,                cachedInputTokens: row.cached,                outputTokens: row.output,                modelsDevCatalog: modelsDevCatalog,                modelsDevCacheRoot: modelsDevCacheRoot)            if isPriority, let priorityCost = CostUsagePricing.codexPriorityCostUSD(                model: pricedModel,                inputTokens: row.input,                cachedInputTokens: row.cached,                outputTokens: row.output)            {                breakdown.priorityCostUSD += max(priorityCost, baseCost ?? priorityCost)                breakdown.sawPriorityCost = true            } else if isPriority, let baseCost {                breakdown.priorityCostUSD += baseCost                breakdown.sawPriorityCost = true            } else if let baseCost {                breakdown.standardCostUSD += baseCost                breakdown.sawStandardCost = true            }        }        return breakdown    }     // MARK: - File cache construction     static func makeFileUsage(        mtimeUnixMs: Int64,        size: Int64,        days: [String: [String: [Int]]],        parsedBytes: Int64?,        lastModel: String? = nil,        lastTotals: CostUsageCodexTotals? = nil,        lastCountedTotals: CostUsageCodexTotals? = nil,        lastRawTotalsBaseline: CostUsageCodexTotals? = nil,        hasDivergentTotals: Bool? = nil,        lastCodexTurnID: String? = nil,        sessionId: String? = nil,        forkedFromId: String? = nil,        codexCostNanos: [String: [String: Int64]]? = nil,        codexPrioritySurchargeNanos: [String: [String: Int64]]? = nil,        codexStandardCostNanos: [String: [String: Int64]]? = nil,        codexPriorityCostNanos: [String: [String: Int64]]? = nil,        codexStandardTokens: [String: [String: Int]]? = nil,        codexPriorityTokens: [String: [String: Int]]? = nil,        codexTurnIDs: [String]? = nil,        codexRows: [CodexUsageRow]? = nil,        claudeRows: [ClaudeUsageRow]? = nil) -> CostUsageFileUsage    {        CostUsageFileUsage(            mtimeUnixMs: mtimeUnixMs,            size: size,            days: days,            parsedBytes: parsedBytes,            lastModel: lastModel,            lastTotals: lastTotals,            lastCountedTotals: lastCountedTotals,            lastRawTotalsBaseline: lastRawTotalsBaseline,            hasDivergentTotals: hasDivergentTotals,            lastCodexTurnID: lastCodexTurnID,            sessionId: sessionId,            forkedFromId: forkedFromId,            codexCostNanos: codexCostNanos,            codexPrioritySurchargeNanos: codexPrioritySurchargeNanos,            codexStandardCostNanos: codexStandardCostNanos,            codexPriorityCostNanos: codexPriorityCostNanos,            codexStandardTokens: codexStandardTokens,            codexPriorityTokens: codexPriorityTokens,            codexTurnIDs: codexTurnIDs,            codexRows: codexRows,            claudeRows: claudeRows)    }     static func needsCodexCostCache(_ usage: CostUsageFileUsage) -> Bool {        !(usage.codexRows?.isEmpty ?? true)            && (usage.codexCostNanos == nil || self.needsCodexModeSplitCache(usage))    }     static func needsCodexCostCache(_ usage: CostUsageFileUsage, range: CostUsageDayRange) -> Bool {        guard let rows = usage.codexRows, !rows.isEmpty else { return false }        return rows.contains {            CostUsageDayRange.isInRange(dayKey: $0.day, since: range.sinceKey, until: range.untilKey)        } && (usage.codexCostNanos == nil || Self.needsCodexModeSplitCache(usage))    }     static func needsCodexModeSplitCache(_ usage: CostUsageFileUsage) -> Bool {        usage.codexStandardCostNanos == nil            || usage.codexPriorityCostNanos == nil            || usage.codexStandardTokens == nil            || usage.codexPriorityTokens == nil    }     static func codexFileUsageWithCostCache(        _ usage: CostUsageFileUsage,        context: CodexFileScanContext) -> CostUsageFileUsage    {        guard let rows = usage.codexRows, !rows.isEmpty else { return usage }        var migratedRows: [CodexUsageRow] = []        var retainedRows: [CodexUsageRow] = []        for row in rows {            if CostUsageDayRange.isInRange(                dayKey: row.day,                since: context.range.scanSinceKey,                until: context.range.scanUntilKey)            {                migratedRows.append(row)            } else {                retainedRows.append(row)            }        }        guard !migratedRows.isEmpty else { return usage }         let splitMaps = Self.codexModeSplitMaps(            rows: migratedRows,            range: context.range,            priorityTurns: context.resources.priorityTurns,            modelsDevCatalog: context.resources.modelsDevCatalog,            modelsDevCacheRoot: context.resources.modelsDevCacheRoot)        var updated = usage        updated.codexCostNanos = Self.mergeMissingCostMaps(            usage.codexCostNanos,            Self.codexCostNanos(                rows: migratedRows,                range: context.range,                modelsDevCatalog: context.resources.modelsDevCatalog,                modelsDevCacheRoot: context.resources.modelsDevCacheRoot))        updated.codexPrioritySurchargeNanos = Self.mergeMissingCostMaps(            usage.codexPrioritySurchargeNanos,            Self.codexPrioritySurchargeNanos(                rows: migratedRows,                range: context.range,                priorityTurns: context.resources.priorityTurns,                modelsDevCatalog: context.resources.modelsDevCatalog,                modelsDevCacheRoot: context.resources.modelsDevCacheRoot))        updated.codexStandardCostNanos = Self.mergeMissingCostMaps(            usage.codexStandardCostNanos,            splitMaps.standardCostNanos)        updated.codexPriorityCostNanos = Self.mergeMissingCostMaps(            usage.codexPriorityCostNanos,            splitMaps.priorityCostNanos)        updated.codexStandardTokens = Self.mergeMissingIntMaps(            usage.codexStandardTokens,            splitMaps.standardTokens)        updated.codexPriorityTokens = Self.mergeMissingIntMaps(            usage.codexPriorityTokens,            splitMaps.priorityTokens)        updated.codexTurnIDs = Self.mergeCodexTurnIDs(usage.codexTurnIDs, rows: migratedRows)        updated.codexRows = retainedRows.isEmpty ? nil : retainedRows        return updated    }     static func codexMergedCostMap(        _ existing: [String: [String: Int64]]?,        deltaRows: [CodexUsageRow],        context: CodexFileScanContext) -> [String: [String: Int64]]?    {        self.mergeCostMaps(            existing,            self.codexCostNanos(                rows: deltaRows,                range: context.range,                modelsDevCatalog: context.resources.modelsDevCatalog,                modelsDevCacheRoot: context.resources.modelsDevCacheRoot))    }     static func codexMergedPrioritySurchargeMap(        _ existing: [String: [String: Int64]]?,        deltaRows: [CodexUsageRow],        context: CodexFileScanContext) -> [String: [String: Int64]]?    {        self.mergeCostMaps(            existing,            self.codexPrioritySurchargeNanos(                rows: deltaRows,                range: context.range,                priorityTurns: context.resources.priorityTurns,                modelsDevCatalog: context.resources.modelsDevCatalog,                modelsDevCacheRoot: context.resources.modelsDevCacheRoot))    }     static func codexCostNanos(        rows: [CodexUsageRow],        range: CostUsageDayRange,        modelsDevCatalog: ModelsDevCatalog?,        modelsDevCacheRoot: URL?) -> [String: [String: Int64]]?    {        let rowsByDayModel = Self.codexRowsByDayModel(rows: rows, range: range)        var out: [String: [String: Int64]] = [:]        for (day, models) in rowsByDayModel {            for (model, rows) in models {                guard let cost = Self.codexRowsCostUSD(                    rows: rows,                    modelsDevCatalog: modelsDevCatalog,                    modelsDevCacheRoot: modelsDevCacheRoot)                else { continue }                out[day, default: [:]][model] = Int64((cost * Self.costScale).rounded())            }        }        return out.isEmpty ? nil : out    }     static func codexPrioritySurchargeNanos(        rows: [CodexUsageRow],        range: CostUsageDayRange,        priorityTurns: [String: CodexPriorityTurnMetadata],        modelsDevCatalog: ModelsDevCatalog?,        modelsDevCacheRoot: URL?) -> [String: [String: Int64]]?    {        guard !priorityTurns.isEmpty else { return nil }        let rowsByDayModel = Self.codexRowsByDayModel(rows: rows, range: range)        var out: [String: [String: Int64]] = [:]        for (day, models) in rowsByDayModel {            for (model, rows) in models {                guard let surcharge = Self.codexPrioritySurchargeUSD(                    rows: rows,                    priorityTurns: priorityTurns,                    modelsDevCatalog: modelsDevCatalog,                    modelsDevCacheRoot: modelsDevCacheRoot)                else { continue }                out[day, default: [:]][model] = Int64((surcharge * Self.costScale).rounded())            }        }        return out.isEmpty ? nil : out    }     static func codexModeSplitMaps(        rows: [CodexUsageRow],        range: CostUsageDayRange,        priorityTurns: [String: CodexPriorityTurnMetadata],        modelsDevCatalog: ModelsDevCatalog?,        modelsDevCacheRoot: URL?) -> (        standardCostNanos: [String: [String: Int64]]?,        priorityCostNanos: [String: [String: Int64]]?,        standardTokens: [String: [String: Int]]?,        priorityTokens: [String: [String: Int]]?)    {        var standardCostNanos: [String: [String: Int64]] = [:]        var priorityCostNanos: [String: [String: Int64]] = [:]        var standardTokens: [String: [String: Int]] = [:]        var priorityTokens: [String: [String: Int]] = [:]         for row in rows {            guard CostUsageDayRange.isInRange(dayKey: row.day, since: range.sinceKey, until: range.untilKey)            else { continue }             let tokenCount = row.input + row.output            let priorityMetadata = row.turnID.flatMap { priorityTurns[$0] }            let pricedModel = priorityMetadata.map { Self.codexPriorityPricingModel(for: row, priorityMetadata: $0) }                ?? row.model            let isPriority = priorityMetadata != nil             if isPriority {                priorityTokens[row.day, default: [:]][row.model, default: 0] += tokenCount            } else {                standardTokens[row.day, default: [:]][row.model, default: 0] += tokenCount            }             let baseCost = CostUsagePricing.codexCostUSD(                model: pricedModel,                inputTokens: row.input,                cachedInputTokens: row.cached,                outputTokens: row.output,                modelsDevCatalog: modelsDevCatalog,

Lines 1–500 of 1212.