diff --git a/Sources/CodexBar/MenuBarMetricWindowResolver.swift b/Sources/CodexBar/MenuBarMetricWindowResolver.swift index a154be9cf..9c77e0646 100644 --- a/Sources/CodexBar/MenuBarMetricWindowResolver.swift +++ b/Sources/CodexBar/MenuBarMetricWindowResolver.swift @@ -45,7 +45,7 @@ enum MenuBarMetricWindowResolver { if provider == .antigravity { return snapshot.primary ?? snapshot.secondary ?? snapshot.tertiary } - if provider == .factory || provider == .kimi { + if provider == .factory { return snapshot.secondary ?? snapshot.primary } if provider == .copilot, diff --git a/Sources/CodexBarCore/Providers/Kimi/KimiProviderDescriptor.swift b/Sources/CodexBarCore/Providers/Kimi/KimiProviderDescriptor.swift index 711c20bc8..bd7392baf 100644 --- a/Sources/CodexBarCore/Providers/Kimi/KimiProviderDescriptor.swift +++ b/Sources/CodexBarCore/Providers/Kimi/KimiProviderDescriptor.swift @@ -10,8 +10,8 @@ public enum KimiProviderDescriptor { metadata: ProviderMetadata( id: .kimi, displayName: "Kimi", - sessionLabel: "Weekly", - weeklyLabel: "Rate Limit", + sessionLabel: "Rate Limit", + weeklyLabel: "Weekly", opusLabel: nil, supportsOpus: false, supportsCredits: false, diff --git a/Sources/CodexBarCore/Providers/Kimi/KimiUsageSnapshot.swift b/Sources/CodexBarCore/Providers/Kimi/KimiUsageSnapshot.swift index d19ff420d..54c53c160 100644 --- a/Sources/CodexBarCore/Providers/Kimi/KimiUsageSnapshot.swift +++ b/Sources/CodexBarCore/Providers/Kimi/KimiUsageSnapshot.swift @@ -73,8 +73,8 @@ extension KimiUsageSnapshot { loginMethod: nil) return UsageSnapshot( - primary: weeklyWindow, - secondary: rateLimitWindow, + primary: rateLimitWindow, + secondary: weeklyWindow, tertiary: nil, providerCost: nil, updatedAt: self.updatedAt, diff --git a/Tests/CodexBarTests/KimiProviderTests.swift b/Tests/CodexBarTests/KimiProviderTests.swift index bcac5c943..6d9592e8c 100644 --- a/Tests/CodexBarTests/KimiProviderTests.swift +++ b/Tests/CodexBarTests/KimiProviderTests.swift @@ -191,16 +191,16 @@ struct KimiUsageSnapshotConversionTests { let usageSnapshot = snapshot.toUsageSnapshot() #expect(usageSnapshot.primary != nil) - let weeklyExpected = 375.0 / 2048.0 * 100.0 - #expect(abs((usageSnapshot.primary?.usedPercent ?? 0.0) - weeklyExpected) < 0.01) - #expect(usageSnapshot.primary?.resetDescription == "375/2048 requests") - #expect(usageSnapshot.primary?.windowMinutes == nil) + let rateExpected = 200.0 / 200.0 * 100.0 + #expect(abs((usageSnapshot.primary?.usedPercent ?? 0.0) - rateExpected) < 0.01) + #expect(usageSnapshot.primary?.windowMinutes == 300) // 5 hours + #expect(usageSnapshot.primary?.resetDescription == "Rate: 200/200 per 5 hours") #expect(usageSnapshot.secondary != nil) - let rateExpected = 200.0 / 200.0 * 100.0 - #expect(abs((usageSnapshot.secondary?.usedPercent ?? 0.0) - rateExpected) < 0.01) - #expect(usageSnapshot.secondary?.windowMinutes == 300) // 5 hours - #expect(usageSnapshot.secondary?.resetDescription == "Rate: 200/200 per 5 hours") + let weeklyExpected = 375.0 / 2048.0 * 100.0 + #expect(abs((usageSnapshot.secondary?.usedPercent ?? 0.0) - weeklyExpected) < 0.01) + #expect(usageSnapshot.secondary?.resetDescription == "375/2048 requests") + #expect(usageSnapshot.secondary?.windowMinutes == nil) #expect(usageSnapshot.tertiary == nil) #expect(usageSnapshot.updatedAt == now) @@ -222,10 +222,10 @@ struct KimiUsageSnapshotConversionTests { let usageSnapshot = snapshot.toUsageSnapshot() - #expect(usageSnapshot.primary != nil) + #expect(usageSnapshot.primary == nil) + #expect(usageSnapshot.secondary != nil) let weeklyExpected = 375.0 / 2048.0 * 100.0 - #expect(abs((usageSnapshot.primary?.usedPercent ?? 0.0) - weeklyExpected) < 0.01) - #expect(usageSnapshot.secondary == nil) + #expect(abs((usageSnapshot.secondary?.usedPercent ?? 0.0) - weeklyExpected) < 0.01) #expect(usageSnapshot.tertiary == nil) } @@ -244,7 +244,7 @@ struct KimiUsageSnapshotConversionTests { updatedAt: now) let usageSnapshot = snapshot.toUsageSnapshot() - #expect(usageSnapshot.primary?.usedPercent == 0.0) + #expect(usageSnapshot.secondary?.usedPercent == 0.0) } @Test @@ -262,7 +262,7 @@ struct KimiUsageSnapshotConversionTests { updatedAt: now) let usageSnapshot = snapshot.toUsageSnapshot() - #expect(usageSnapshot.primary?.usedPercent == 100.0) + #expect(usageSnapshot.secondary?.usedPercent == 100.0) } } diff --git a/Tests/CodexBarTests/StatusItemAnimationTests.swift b/Tests/CodexBarTests/StatusItemAnimationTests.swift index f29ada71b..9eb118a9d 100644 --- a/Tests/CodexBarTests/StatusItemAnimationTests.swift +++ b/Tests/CodexBarTests/StatusItemAnimationTests.swift @@ -308,8 +308,8 @@ struct StatusItemAnimationTests { statusBar: self.makeStatusBarForTesting()) let snapshot = UsageSnapshot( - primary: RateWindow(usedPercent: 12, windowMinutes: nil, resetsAt: nil, resetDescription: nil), - secondary: RateWindow(usedPercent: 42, windowMinutes: 300, resetsAt: nil, resetDescription: nil), + primary: RateWindow(usedPercent: 42, windowMinutes: 300, resetsAt: nil, resetDescription: nil), + secondary: RateWindow(usedPercent: 12, windowMinutes: nil, resetsAt: nil, resetDescription: nil), updatedAt: Date()) store._setSnapshotForTesting(snapshot, provider: .kimi) diff --git a/Tests/CodexBarTests/UsageStoreCoverageTests.swift b/Tests/CodexBarTests/UsageStoreCoverageTests.swift index 67b0a323a..04824bf98 100644 --- a/Tests/CodexBarTests/UsageStoreCoverageTests.swift +++ b/Tests/CodexBarTests/UsageStoreCoverageTests.swift @@ -95,10 +95,12 @@ struct UsageStoreCoverageTests { secondary: nil, updatedAt: now), provider: .codex) + // With the fix, Kimi's primary is now rate limit and secondary is weekly. + // In automatic mode, Kimi uses primary like other providers. store._setSnapshotForTesting( UsageSnapshot( - primary: RateWindow(usedPercent: 10, windowMinutes: nil, resetsAt: nil, resetDescription: nil), - secondary: RateWindow(usedPercent: 80, windowMinutes: 300, resetsAt: nil, resetDescription: nil), + primary: RateWindow(usedPercent: 80, windowMinutes: 300, resetsAt: nil, resetDescription: nil), + secondary: RateWindow(usedPercent: 10, windowMinutes: nil, resetsAt: nil, resetDescription: nil), updatedAt: now), provider: .kimi) diff --git a/Tests/CodexBarTests/UsageStoreHighestUsageTests.swift b/Tests/CodexBarTests/UsageStoreHighestUsageTests.swift index 190c00892..b5dd8f3ec 100644 --- a/Tests/CodexBarTests/UsageStoreHighestUsageTests.swift +++ b/Tests/CodexBarTests/UsageStoreHighestUsageTests.swift @@ -80,7 +80,7 @@ struct UsageStoreHighestUsageTests { } @Test - func `automatic metric uses secondary for kimi when ranking highest usage`() { + func `automatic metric uses primary for kimi when ranking highest usage`() { let settings = SettingsStore( configStore: testConfigStore(suiteName: "UsageStoreHighestUsageTests-kimi-automatic"), zaiTokenStore: NoopZaiTokenStore(), @@ -104,9 +104,11 @@ struct UsageStoreHighestUsageTests { primary: RateWindow(usedPercent: 70, windowMinutes: nil, resetsAt: nil, resetDescription: nil), secondary: nil, updatedAt: Date()) + // With the fix, Kimi's primary is now rate limit (typically lower usage %) + // and secondary is weekly. In automatic mode, Kimi uses primary like other providers. let kimiSnapshot = UsageSnapshot( - primary: RateWindow(usedPercent: 90, windowMinutes: nil, resetsAt: nil, resetDescription: nil), - secondary: RateWindow(usedPercent: 20, windowMinutes: nil, resetsAt: nil, resetDescription: nil), + primary: RateWindow(usedPercent: 20, windowMinutes: nil, resetsAt: nil, resetDescription: nil), + secondary: RateWindow(usedPercent: 90, windowMinutes: nil, resetsAt: nil, resetDescription: nil), updatedAt: Date()) store._setSnapshotForTesting(codexSnapshot, provider: .codex)