feat: separate system task token usage and add usage refresh

Add a System tasks tab to run history that splits background usage (supervisor, auto-supervision, magic notes, knowledge base, delegation) from conversation usage, with a manual refresh button and automatic refresh when usage is recorded. Record previously dropped usage from supervisor reviews, image regeneration, knowledge graph extraction, and remote embeddings.
This commit is contained in:
mesalogo
2026-09-29 10:38:37 +08:00
parent 3c9229ac7a
commit 9a9170441e
24 changed files with 991 additions and 286 deletions
+36 -9
View File
@@ -781,8 +781,38 @@ export type ModelUsageCallInput = {
cacheWrite: number
}
export const tokenUsageSystemSources = [
'heartbeat',
'supervision',
'magic-notes',
'knowledge',
'delegation'
] as const
export type TokenUsageSystemSource = (typeof tokenUsageSystemSources)[number]
export type SystemModelUsageInput = Omit<
ModelUsageCallInput,
'requestId' | 'callId'
> & {
source: Extract<TokenUsageSystemSource, 'knowledge'>
bucket: 'graph-extraction' | 'embedding'
}
export type TokenUsageTotals = {
callCount: number
input: number
output: number
cacheRead: number
cacheWrite: number
cacheInput?: number
totalTokens: number
}
export type TokenUsageRecord = {
requestId: string
/** Set when the usage came from background system work instead of a conversation. */
systemSource?: TokenUsageSystemSource
projectId?: string
projectName?: string
conversationId?: string
@@ -800,15 +830,12 @@ export type TokenUsageRecord = {
}
export type TokenUsageSummary = {
totals: {
callCount: number
input: number
output: number
cacheRead: number
cacheWrite: number
cacheInput?: number
totalTokens: number
}
/** Totals across all recorded usage. */
totals: TokenUsageTotals
/** Totals for conversation work only; absent in legacy summaries. */
conversationTotals?: TokenUsageTotals
/** Totals for background system work only; absent in legacy summaries. */
systemTotals?: TokenUsageTotals
records: TokenUsageRecord[]
}
+2
View File
@@ -2159,6 +2159,8 @@ export type DesktopApi = {
}
usage: {
getTokenSummary: () => Promise<TokenUsageSummary>
/** Fires (debounced) after any model usage is recorded. */
onChanged: (listener: () => void) => () => void
}
artifacts: {
list: (projectId?: string) => Promise<AssistantArtifact[]>
+1
View File
@@ -249,6 +249,7 @@ export const ipcChannels = {
activityHistoryGet: 'activity-history:get',
activityHistoryReplace: 'activity-history:replace',
tokenUsageSummary: 'usage:token-summary',
tokenUsageChanged: 'usage:token-changed',
artifactsList: 'artifacts:list',
artifactsGet: 'artifacts:get',
artifactsImportFiles: 'artifacts:import-files',