Files
orca/src/preload/api/agent-usage-api.ts
T
Neil eb18eaf2b6 feat(usage): add Muse Code local usage provider (#22379)
* feat(usage): add Muse Code local usage provider

Scan Muse session logs (including subagent logs, which hold usage the parent
log does not) for model_completed token events and surface them as a fourth
local usage provider: shared scan worker, persisted per-file cache reused by
mtime/size, cross-log dedupe, Stats tab, and Usage Overview integration.
Muse logs carry no price, so the provider reports tokens only.

* fix(usage): name Muse in Stats & Usage copy; skip partial-cost warning when nothing is priced

* fix(usage): surface unreadable Muse sessions root; name Muse in remaining Stats & Usage copy

* fix(usage): count distinct same-content Muse records within one log
2026-09-22 22:44:10 -07:00

63 lines
2.6 KiB
TypeScript

import type { ClaudeUsageBreakdownKind, ClaudeUsageSnapshot } from '../../shared/claude-usage-types'
import type { CodexUsageBreakdownKind, CodexUsageSnapshot } from '../../shared/codex-usage-types'
import type {
OpenCodeUsageBreakdownKind,
OpenCodeUsageSnapshot
} from '../../shared/opencode-usage-types'
import type { MuseUsageBreakdownKind, MuseUsageSnapshot } from '../../shared/muse-usage-types'
import type {
CodexRateLimitResetResult,
RateLimitRuntimeTarget,
RateLimitState
} from '../../shared/rate-limit-types'
export type UsageProviderSnapshot = {
scanState: unknown
summary: { scope: string; range: string }
daily: unknown[]
modelBreakdown: unknown[]
recentSessions: unknown[]
}
export type UsageQueryArgs<Snapshot extends UsageProviderSnapshot> = Pick<
Snapshot['summary'],
'scope' | 'range'
>
export type UsageProviderApi<Snapshot extends UsageProviderSnapshot, BreakdownKind> = {
getScanState: () => Promise<Snapshot['scanState']>
setEnabled: (args: { enabled: boolean }) => Promise<Snapshot['scanState']>
refresh: (args?: { force?: boolean }) => Promise<Snapshot['scanState']>
getSnapshot: (args: UsageQueryArgs<Snapshot> & { limit?: number }) => Promise<Snapshot>
getSummary: (args: UsageQueryArgs<Snapshot>) => Promise<Snapshot['summary']>
getDaily: (args: UsageQueryArgs<Snapshot>) => Promise<Snapshot['daily']>
getBreakdown: (
args: UsageQueryArgs<Snapshot> & { kind: BreakdownKind }
) => Promise<Snapshot['modelBreakdown']>
getRecentSessions: (
args: UsageQueryArgs<Snapshot> & { limit?: number }
) => Promise<Snapshot['recentSessions']>
}
export type ClaudeUsageApi = UsageProviderApi<ClaudeUsageSnapshot, ClaudeUsageBreakdownKind>
export type CodexUsageApi = UsageProviderApi<CodexUsageSnapshot, CodexUsageBreakdownKind>
export type OpenCodeUsageApi = UsageProviderApi<OpenCodeUsageSnapshot, OpenCodeUsageBreakdownKind>
export type MuseUsageApi = UsageProviderApi<MuseUsageSnapshot, MuseUsageBreakdownKind>
export type RateLimitsApi = {
get: () => Promise<RateLimitState>
refresh: () => Promise<RateLimitState>
refreshCodexForTarget: (target: RateLimitRuntimeTarget) => Promise<RateLimitState>
consumeCodexResetCredit: () => Promise<CodexRateLimitResetResult>
refreshClaudeForTarget: (target: RateLimitRuntimeTarget) => Promise<RateLimitState>
setPollingInterval: (ms: number) => Promise<void>
fetchInactiveClaudeAccounts: () => Promise<void>
fetchInactiveCodexAccounts: () => Promise<void>
refreshMiniMax: () => Promise<RateLimitState>
refreshGrok: () => Promise<RateLimitState>
onUpdate: (callback: (state: RateLimitState) => void) => () => void
}