Files
TokenLens/NativeTokenLens/Sources/TokenLensCore/Models.swift

207 lines
5.8 KiB
Swift

import Foundation
public enum Provider: String, CaseIterable, Codable, Hashable, Sendable {
case claude = "Claude"
case codex = "Codex"
case gemini = "Gemini"
case hermes = "Hermes"
case opencode = "OpenCode"
}
public struct UsageRecord: Identifiable, Hashable, Sendable {
public let id: UUID
public let provider: Provider
public let source: String
public let sourcePath: String
public let timestamp: Date
public let sessionID: String
public let model: String
public let inputTokens: Int
public let outputTokens: Int
public let cachedTokens: Int
public let reasoningTokens: Int
public let toolTokens: Int
public let totalTokens: Int
public init(
id: UUID = UUID(),
provider: Provider,
source: String,
sourcePath: String,
timestamp: Date,
sessionID: String,
model: String,
inputTokens: Int,
outputTokens: Int,
cachedTokens: Int,
reasoningTokens: Int,
toolTokens: Int,
explicitTotal: Int? = nil
) {
self.id = id
self.provider = provider
self.source = source
self.sourcePath = sourcePath
self.timestamp = timestamp
self.sessionID = sessionID
self.model = model
self.inputTokens = inputTokens
self.outputTokens = outputTokens
self.cachedTokens = cachedTokens
self.reasoningTokens = reasoningTokens
self.toolTokens = toolTokens
self.totalTokens = explicitTotal ?? inputTokens + outputTokens + cachedTokens + reasoningTokens + toolTokens
}
}
public struct TokenBucket: Hashable, Sendable {
public let provider: Provider?
public var inputTokens: Int = 0
public var outputTokens: Int = 0
public var cachedTokens: Int = 0
public var reasoningTokens: Int = 0
public var toolTokens: Int = 0
public var totalTokens: Int = 0
public var count: Int = 0
public init(provider: Provider? = nil) {
self.provider = provider
}
public mutating func add(_ record: UsageRecord) {
add(
inputTokens: record.inputTokens,
outputTokens: record.outputTokens,
cachedTokens: record.cachedTokens,
reasoningTokens: record.reasoningTokens,
toolTokens: record.toolTokens,
totalTokens: record.totalTokens
)
}
public mutating func add(
inputTokens: Int,
outputTokens: Int,
cachedTokens: Int,
reasoningTokens: Int,
toolTokens: Int,
totalTokens: Int
) {
self.inputTokens += inputTokens
self.outputTokens += outputTokens
self.cachedTokens += cachedTokens
self.reasoningTokens += reasoningTokens
self.toolTokens += toolTokens
self.totalTokens += totalTokens
count += 1
}
}
public struct SummaryCards: Hashable, Sendable {
public let todayTokens: Int
public let monthTokens: Int
public let totalTokens: Int
public let cacheHitRate: Int
public let sessionCount: Int
}
public struct DailyPoint: Identifiable, Hashable, Sendable {
public let id = UUID()
public let date: Date
public let values: [Provider: Int]
}
public enum TrendMode: String, CaseIterable, Sendable {
case daily = "每日"
case weekly = "每周"
case monthly = "每月"
case yearly = "每年"
}
public struct ToolRow: Identifiable, Hashable, Sendable {
public let id = UUID()
public let provider: Provider
public let inputTokens: Int
public let outputTokens: Int
public let cachedTokens: Int
public let totalTokens: Int
public let trendTokens: [Int]
}
public struct DailyUsageDetail: Identifiable, Hashable, Sendable {
public var id: Date { date }
public let date: Date
public var inputTokens: Int
public var outputTokens: Int
public var cachedTokens: Int
public var totalTokens: Int
public var providerTotals: [Provider: Int]
public init(
date: Date,
inputTokens: Int = 0,
outputTokens: Int = 0,
cachedTokens: Int = 0,
totalTokens: Int = 0,
providerTotals: [Provider: Int] = [:]
) {
self.date = date
self.inputTokens = inputTokens
self.outputTokens = outputTokens
self.cachedTokens = cachedTokens
self.totalTokens = totalTokens
self.providerTotals = providerTotals
}
public mutating func add(_ record: UsageRecord) {
add(
provider: record.provider,
inputTokens: record.inputTokens,
outputTokens: record.outputTokens,
cachedTokens: record.cachedTokens,
totalTokens: record.totalTokens
)
}
public mutating func add(
provider: Provider,
inputTokens: Int,
outputTokens: Int,
cachedTokens: Int,
totalTokens: Int
) {
self.inputTokens += inputTokens
self.outputTokens += outputTokens
self.cachedTokens += cachedTokens
self.totalTokens += totalTokens
providerTotals[provider, default: 0] += totalTokens
}
}
public struct Insight: Identifiable, Hashable, Sendable {
public enum Tone: String, Sendable {
case warning
case positive
case accent
}
public let id = UUID()
public let tone: Tone
public let title: String
public let message: String
}
public struct UsageSummary: Sendable {
public let generatedAt: Date
public let records: [UsageRecord]
public let cards: SummaryCards
public let providerTotals: [Provider: TokenBucket]
public let todayProviderTotals: [Provider: TokenBucket]
public let dailyTrend: [DailyPoint]
public let trendPointsByMode: [TrendMode: [DailyPoint]]
public let dailyDetails: [DailyUsageDetail]
public let toolRows: [ToolRow]
public let insights: [Insight]
}