import CodexBarCore import Foundation struct KiloScopeSnapshot: Identifiable, Equatable { let id: String // KiloUsageScope.scopeIdentifier let scope: KiloUsageScope let snapshot: UsageSnapshot? let errorMessage: String? let sourceLabel: String? static func == (lhs: KiloScopeSnapshot, rhs: KiloScopeSnapshot) -> Bool { lhs.id == rhs.id && lhs.snapshot?.updatedAt == rhs.snapshot?.updatedAt && lhs.errorMessage == rhs.errorMessage && lhs.sourceLabel == rhs.sourceLabel } } extension UsageStore { var kiloEnabledScopes: [KiloUsageScope] { var scopes: [KiloUsageScope] = [.personal] let enabled = self.settings.kiloEnabledOrganizationIDs guard !enabled.isEmpty else { return scopes } let knownByID = Dictionary( uniqueKeysWithValues: self.settings.kiloKnownOrganizations.map { ($0.id, $0) }) for id in enabled { if let org = knownByID[id] { scopes.append(.organization(id: org.id, name: org.name)) } } return scopes } func shouldFanOutKiloScopes() -> Bool { self.kiloEnabledScopes.count > 1 } func refreshKiloScopes(generation: UInt64? = nil) async { let scopes = self.kiloEnabledScopes guard scopes.count > 1 else { await MainActor.run { self.kiloScopeSnapshots = [] } return } let env = ProcessInfo.processInfo.environment let resolved: KiloResolvedBearerToken do { resolved = try KiloBearerTokenResolver.resolve( source: self.settings.kiloUsageDataSource, apiKey: self.settings.configSnapshot.providerConfig(for: .kilo)?.sanitizedAPIKey, environment: env) } catch { let message = (error as? LocalizedError)?.errorDescription ?? error.localizedDescription await MainActor.run { self.kiloScopeSnapshots = scopes.map { KiloScopeSnapshot( id: $0.scopeIdentifier, scope: $0, snapshot: nil, errorMessage: message, sourceLabel: nil) } } return } let results: [KiloScopeSnapshot] = await withTaskGroup(of: KiloScopeSnapshot.self) { group in for scope in scopes { group.addTask { do { let raw = try await KiloUsageFetcher.fetchUsage( apiKey: resolved.token, scope: scope, environment: env) let snapshot = raw.toUsageSnapshot() .withAccountOrganization(scope.displayName) return KiloScopeSnapshot( id: scope.scopeIdentifier, scope: scope, snapshot: snapshot, errorMessage: nil, sourceLabel: resolved.sourceLabel) } catch { return KiloScopeSnapshot( id: scope.scopeIdentifier, scope: scope, snapshot: nil, errorMessage: (error as? LocalizedError)?.errorDescription ?? error.localizedDescription, sourceLabel: nil) } } } var collected: [KiloScopeSnapshot] = [] for await result in group { collected.append(result) } return collected } let resultByID = Dictionary(uniqueKeysWithValues: results.map { ($0.id, $0) }) let ordered = scopes.compactMap { resultByID[$0.scopeIdentifier] } await MainActor.run { guard self.isCurrentProviderRefreshGeneration(.kilo, generation: generation) else { return } self.kiloScopeSnapshots = ordered } } } extension UsageSnapshot { fileprivate func withAccountOrganization(_ org: String) -> UsageSnapshot { let baseIdentity = self.identity let newIdentity = ProviderIdentitySnapshot( providerID: baseIdentity?.providerID ?? .kilo, accountEmail: baseIdentity?.accountEmail, accountOrganization: org, loginMethod: baseIdentity?.loginMethod) return self.withIdentity(newIdentity) } }