-
Notifications
You must be signed in to change notification settings - Fork 694
feat(cursor): show Auto and API pool usage separately #553
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 all commits
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 |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| import Foundation | ||
|
|
||
| /// Usage snapshot for Cursor's Auto and API model pools (token-based pro plans). | ||
| /// | ||
| /// Cursor separates quota into two buckets: | ||
| /// - **Auto pool** – includes base quota + bonus credits; used when Cursor picks the model automatically. | ||
| /// - **API pool** – base quota only; used when a specific named/external model is selected. | ||
| public struct CursorPoolUsage: Codable, Sendable { | ||
| /// Percentage of Auto pool consumed (0-100). Accounts for bonus credits. | ||
| public let autoPercentUsed: Double | ||
| /// Percentage of API pool consumed (0-100). Base plan limit only. | ||
| public let apiPercentUsed: Double | ||
| /// Total Auto pool size in requests (included base + bonus credits). | ||
| public let autoPoolTotal: Int? | ||
| /// Total API pool size in requests (base plan limit). | ||
| public let apiPoolTotal: Int? | ||
| /// Requests consumed from the Auto pool. | ||
| public let autoPoolUsed: Int? | ||
| /// Requests consumed from the API pool (estimated from percent × total). | ||
| public let apiPoolUsed: Int? | ||
|
|
||
| public init( | ||
| autoPercentUsed: Double, | ||
| apiPercentUsed: Double, | ||
| autoPoolTotal: Int?, | ||
| apiPoolTotal: Int?, | ||
| autoPoolUsed: Int?, | ||
| apiPoolUsed: Int?) | ||
| { | ||
| self.autoPercentUsed = autoPercentUsed | ||
| self.apiPercentUsed = apiPercentUsed | ||
| self.autoPoolTotal = autoPoolTotal | ||
| self.apiPoolTotal = apiPoolTotal | ||
| self.autoPoolUsed = autoPoolUsed | ||
| self.apiPoolUsed = apiPoolUsed | ||
| } | ||
|
|
||
| public var autoRemainingPercent: Double { max(0, 100 - self.autoPercentUsed) } | ||
| public var apiRemainingPercent: Double { max(0, 100 - self.apiPercentUsed) } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -56,6 +56,8 @@ public struct UsageSnapshot: Codable, Sendable { | |
| public let minimaxUsage: MiniMaxUsageSnapshot? | ||
| public let openRouterUsage: OpenRouterUsageSnapshot? | ||
| public let cursorRequests: CursorRequestUsage? | ||
| /// Auto + API pool breakdown for token-based Cursor pro plans. | ||
| public let cursorPoolUsage: CursorPoolUsage? | ||
|
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.
The new Useful? React with 👍 / 👎. |
||
| public let updatedAt: Date | ||
| public let identity: ProviderIdentitySnapshot? | ||
|
|
||
|
|
@@ -81,6 +83,7 @@ public struct UsageSnapshot: Codable, Sendable { | |
| minimaxUsage: MiniMaxUsageSnapshot? = nil, | ||
| openRouterUsage: OpenRouterUsageSnapshot? = nil, | ||
| cursorRequests: CursorRequestUsage? = nil, | ||
| cursorPoolUsage: CursorPoolUsage? = nil, | ||
| updatedAt: Date, | ||
| identity: ProviderIdentitySnapshot? = nil) | ||
| { | ||
|
|
@@ -92,6 +95,7 @@ public struct UsageSnapshot: Codable, Sendable { | |
| self.minimaxUsage = minimaxUsage | ||
| self.openRouterUsage = openRouterUsage | ||
| self.cursorRequests = cursorRequests | ||
| self.cursorPoolUsage = cursorPoolUsage | ||
| self.updatedAt = updatedAt | ||
| self.identity = identity | ||
| } | ||
|
|
@@ -106,6 +110,7 @@ public struct UsageSnapshot: Codable, Sendable { | |
| self.minimaxUsage = nil // Not persisted, fetched fresh each time | ||
| self.openRouterUsage = try container.decodeIfPresent(OpenRouterUsageSnapshot.self, forKey: .openRouterUsage) | ||
| self.cursorRequests = nil // Not persisted, fetched fresh each time | ||
| self.cursorPoolUsage = nil // Not persisted, fetched fresh each time | ||
| self.updatedAt = try container.decode(Date.self, forKey: .updatedAt) | ||
| if let identity = try container.decodeIfPresent(ProviderIdentitySnapshot.self, forKey: .identity) { | ||
| self.identity = identity | ||
|
|
||
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.
This moves on-demand usage into
tertiary, but Cursor’s UI only renderstertiarywhensupportsOpusis true (checked inMenuDescriptor.accountSectionandMenuCardView.makeMetrics), while Cursor metadata keepssupportsOpusfalse. As a result, on-demand percent/limit is no longer shown as a usage bar (especially whenapiPercentUsedis absent, such as legacy/non-token responses), which is a regression from the previous secondary-window behavior.Useful? React with 👍 / 👎.