Properties2
Icon
Order
50Overview
The Usage Monitor is a subsystem that tracks AI subscription usage across multiple providers. It follows an actor-based architecture for thread-safe credential and API access.
Architecture
UsageMonitorService (MainActor, Observable)
│
├── CredentialManager (Actor)
│ └── Loads credentials from auth.json, env vars, keychain
│
└── Providers (Actors)
├── AnthropicProvider
├── CopilotProvider
├── GeminiCliProvider
├── AntigravityProvider
└── SyntheticProvider
Core Components
UsageMonitorService
The main orchestrator that:
- Manages provider lifecycle
- Coordinates periodic refresh
- Stores usage snapshots
- Emits notifications for threshold crossings
@MainActor
@Observable
final class UsageMonitorService {
var snapshots: [AIProvider: UsageSnapshot]
var isRefreshing: Bool
var enabledProviders: Set<AIProvider>
func startMonitoring()
func stopMonitoring()
func refreshAll() async
}
CredentialManager
Actor-based credential loading with caching:
- Primary:
~/.pi/agent/auth.json - Fallbacks: Environment variables, keychain, legacy config files
- 30-second cache to minimize file I/O
actor CredentialManager {
func credentials(for provider: AIProvider) -> [String: Any]?
func accessToken(for provider: AIProvider) -> String?
func hasCredentials(for provider: AIProvider) -> Bool
}
Provider Protocol
All providers conform to UsageProvider:
protocol UsageProvider: Sendable {
var id: AIProvider { get }
var displayName: String { get }
func hasCredentials() async -> Bool
func fetchUsage() async throws -> UsageSnapshot
}
Data Models
UsageSnapshot
Complete usage state for a provider:
struct UsageSnapshot {
let provider: AIProvider
let displayName: String
let windows: [RateWindow]
let lastUpdated: Date
let error: UsageError?
// Provider-specific extras
let extraUsageEnabled: Bool? // Anthropic
let requestsRemaining: Int? // Copilot
}
RateWindow
Individual quota window:
struct RateWindow {
let label: String // "5h", "Month", "Pro"
let usedPercent: Double // 0-100
let resetDescription: String?
let resetAt: Date?
}
Provider Implementations
Anthropic
- API:
GET https://api.anthropic.com/api/oauth/usage - Auth Header:
Authorization: Bearer <token>,anthropic-beta: oauth-2025-04-20 - Windows: 5-hour, 7-day, extra usage
GitHub Copilot
- API:
GET https://api.github.com/copilot_internal/user - Auth Header:
Authorization: token <refresh_token> - Note: Uses the
refreshtoken (GitHub OAuth), not theaccesstoken (Copilot session)
Google Gemini CLI
- API:
POST https://cloudcode-pa.googleapis.com/v1internal:retrieveUserQuota - Auth Header:
Authorization: Bearer <token> - Windows: Pro, Flash model quotas
Google Antigravity
- API:
POST https://daily-cloudcode-pa.sandbox.googleapis.com/v1internal:fetchAvailableModels - Fallback:
https://cloudcode-pa.googleapis.com/v1internal:fetchAvailableModels - Windows: Per-model quotas with reset times
Synthetic
- API:
GET https://api.synthetic.new/v2/quotas - Auth Header:
Authorization: Bearer <SYNTHETIC_API_KEY> - Windows: Subscription (monthly), Search/hr (hourly), Tool Calls (daily)
Credential Sources
┌─────────────────────────────────────────────────────┐
│ Credential Loading │
├─────────────────────────────────────────────────────┤
│ 1. ~/.pi/agent/auth.json (primary) │
│ └── Keys: anthropic, github-copilot, │
│ google-gemini-cli, google-antigravity, │
│ synthetic │
│ │
│ 2. Provider-specific fallbacks: │
│ ├── Anthropic: macOS Keychain │
│ ├── Copilot: ~/.config/github-copilot/hosts.json│
│ ├── Gemini: ~/.gemini/oauth_creds.json │
│ └── Synthetic: SYNTHETIC_API_KEY env var │
└─────────────────────────────────────────────────────┘
Notifications
When running as a bundled app:
- Permission Request: On first launch via
UNUserNotificationCenter - Warning Alerts: When usage exceeds
warningThreshold(default 80%) - Critical Alerts: When usage exceeds
criticalThreshold(default 95%) - Reset Notifications: When usage drops significantly (quota reset detected)
Alert tracking prevents notification spam - each provider only triggers once per threshold crossing until usage drops below the threshold.
UI Integration
The usage monitor integrates with the notch UI:
- UsageNotchView: Main view accessible via chart icon
- ProviderUsageCard: Card for each provider
- UsageWindowRow: Individual quota display with:
- Progress bar with linear pace marker
- Period bounds (start/end times)
- Elapsed/remaining time
- Pace comparison indicators