Skip to content

Commit 1d1fe36

Browse files
committed
refactor: simplify notification UI and remove unused code
1 parent 05db835 commit 1d1fe36

File tree

3 files changed

+67
-82
lines changed

3 files changed

+67
-82
lines changed

lib/core/janitor.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export interface SessionStats {
1616
totalToolsPruned: number
1717
totalTokensSaved: number
1818
totalGCTokens: number
19+
totalGCTools: number
1920
}
2021

2122
export interface GCStats {
@@ -181,14 +182,16 @@ async function runWithStrategies(
181182
const currentStats = state.stats.get(sessionID) ?? {
182183
totalToolsPruned: 0,
183184
totalTokensSaved: 0,
184-
totalGCTokens: 0
185+
totalGCTokens: 0,
186+
totalGCTools: 0
185187
}
186188

187189
// Update session stats including GC contribution
188190
const sessionStats: SessionStats = {
189191
totalToolsPruned: currentStats.totalToolsPruned + finalNewlyPrunedIds.length,
190192
totalTokensSaved: currentStats.totalTokensSaved + tokensSaved,
191-
totalGCTokens: currentStats.totalGCTokens + (gcPending?.tokensCollected ?? 0)
193+
totalGCTokens: currentStats.totalGCTokens + (gcPending?.tokensCollected ?? 0),
194+
totalGCTools: currentStats.totalGCTools + (gcPending?.toolsDeduped ?? 0)
192195
}
193196
state.stats.set(sessionID, sessionStats)
194197

@@ -466,7 +469,9 @@ async function calculateTokensSaved(prunedIds: string[], toolOutputs: Map<string
466469
const outputsToTokenize: string[] = []
467470

468471
for (const prunedId of prunedIds) {
469-
const output = toolOutputs.get(prunedId)
472+
// toolOutputs uses lowercase keys, so normalize the lookup
473+
const normalizedId = prunedId.toLowerCase()
474+
const output = toolOutputs.get(normalizedId)
470475
if (output) {
471476
outputsToTokenize.push(output)
472477
}

lib/state/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,8 @@ export async function ensureSessionRestored(
6464
const stats: SessionStats = {
6565
totalToolsPruned: persisted.stats.totalToolsPruned,
6666
totalTokensSaved: persisted.stats.totalTokensSaved,
67-
totalGCTokens: persisted.stats.totalGCTokens ?? 0
67+
totalGCTokens: persisted.stats.totalGCTokens ?? 0,
68+
totalGCTools: persisted.stats.totalGCTools ?? 0
6869
}
6970
state.stats.set(sessionId, stats)
7071
}

lib/ui/notification.ts

Lines changed: 57 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -75,105 +75,84 @@ export async function sendUnifiedNotification(
7575
}
7676

7777
function buildMinimalMessage(data: NotificationData): string {
78-
const hasAiPruning = data.aiPrunedCount > 0
79-
const hasGcActivity = data.gcPending && data.gcPending.toolsDeduped > 0
78+
const { justNowTokens, totalTokens } = calculateStats(data)
8079

81-
if (hasAiPruning) {
82-
const gcTokens = hasGcActivity ? data.gcPending!.tokensCollected : 0
83-
const totalSaved = formatTokenCount(data.aiTokensSaved + gcTokens)
84-
const toolText = data.aiPrunedCount === 1 ? 'tool' : 'tools'
85-
86-
let cycleStats = `${data.aiPrunedCount} ${toolText}`
87-
if (hasGcActivity) {
88-
cycleStats += `, ~${formatTokenCount(data.gcPending!.tokensCollected)} 🗑️`
89-
}
80+
return formatStatsHeader(totalTokens, justNowTokens)
81+
}
9082

91-
let message = `🧹 DCP: ~${totalSaved} saved (${cycleStats})`
92-
message += buildSessionSuffix(data.sessionStats, data.aiPrunedCount)
83+
function calculateStats(data: NotificationData): {
84+
justNowTokens: number
85+
totalTokens: number
86+
} {
87+
// "Just now" = AI pruning + pending GC from this notification cycle
88+
const justNowTokens = data.aiTokensSaved + (data.gcPending?.tokensCollected ?? 0)
9389

94-
return message
95-
} else {
96-
const tokensCollected = formatTokenCount(data.gcPending!.tokensCollected)
90+
// Session stats are updated BEFORE notification is sent, so they already include
91+
// the current cycle's values (totalTokensSaved includes current cycle, totalGCTokens includes current cycle)
92+
const totalTokens = data.sessionStats
93+
? data.sessionStats.totalTokensSaved + data.sessionStats.totalGCTokens
94+
: justNowTokens
9795

98-
let message = `🗑️ DCP: ~${tokensCollected} collected`
99-
message += buildSessionSuffix(data.sessionStats, 0)
96+
return { justNowTokens, totalTokens }
97+
}
10098

101-
return message
102-
}
99+
function formatStatsHeader(
100+
totalTokens: number,
101+
justNowTokens: number
102+
): string {
103+
// Format token counts (formatTokenCount already includes "tokens" suffix)
104+
const totalTokensStr = `~${formatTokenCount(totalTokens)}`
105+
const justNowTokensStr = `~${formatTokenCount(justNowTokens)}`
106+
107+
// Pad token strings to align columns
108+
const maxTokenLen = Math.max(totalTokensStr.length, justNowTokensStr.length)
109+
const totalTokensPadded = totalTokensStr.padStart(maxTokenLen)
110+
const justNowTokensPadded = justNowTokensStr.padStart(maxTokenLen)
111+
112+
return [
113+
`▣ DCP Stats`,
114+
` Total saved │ ${totalTokensPadded}`,
115+
` Just now │ ${justNowTokensPadded}`,
116+
].join('\n')
103117
}
104118

105119
function buildDetailedMessage(data: NotificationData, workingDirectory?: string): string {
106-
const hasAiPruning = data.aiPrunedCount > 0
107-
const hasGcActivity = data.gcPending && data.gcPending.toolsDeduped > 0
108-
109-
let message: string
110-
111-
if (hasAiPruning) {
112-
const gcTokens = hasGcActivity ? data.gcPending!.tokensCollected : 0
113-
const totalSaved = formatTokenCount(data.aiTokensSaved + gcTokens)
114-
const toolText = data.aiPrunedCount === 1 ? 'tool' : 'tools'
115-
116-
let cycleStats = `${data.aiPrunedCount} ${toolText}`
117-
if (hasGcActivity) {
118-
cycleStats += `, ~${formatTokenCount(data.gcPending!.tokensCollected)} 🗑️`
119-
}
120+
const { justNowTokens, totalTokens } = calculateStats(data)
120121

121-
message = `🧹 DCP: ~${totalSaved} saved (${cycleStats})`
122-
message += buildSessionSuffix(data.sessionStats, data.aiPrunedCount)
123-
message += '\n'
122+
let message = formatStatsHeader(totalTokens, justNowTokens)
124123

125-
message += `\n🤖 LLM analysis (${data.aiPrunedIds.length}):\n`
126-
const toolsSummary = buildToolsSummary(data.aiPrunedIds, data.toolMetadata, workingDirectory)
127-
128-
for (const [toolName, params] of toolsSummary.entries()) {
129-
if (params.length > 0) {
130-
message += ` ${toolName} (${params.length}):\n`
131-
for (const param of params) {
132-
message += ` ${param}\n`
124+
// Add tool breakdown if there was AI pruning
125+
if (data.aiPrunedCount > 0) {
126+
message += '\n\n▣ Pruned tools:'
127+
128+
for (const prunedId of data.aiPrunedIds) {
129+
const normalizedId = prunedId.toLowerCase()
130+
const metadata = data.toolMetadata.get(normalizedId)
131+
132+
if (metadata) {
133+
const paramKey = extractParameterKey(metadata)
134+
if (paramKey) {
135+
const displayKey = truncate(shortenPath(paramKey, workingDirectory), 60)
136+
message += `\n→ ${metadata.tool}: ${displayKey}`
137+
} else {
138+
message += `\n→ ${metadata.tool}`
133139
}
134140
}
135141
}
136142

137-
const foundToolNames = new Set(toolsSummary.keys())
138-
const missingTools = data.aiPrunedIds.filter(id => {
139-
const normalizedId = id.toLowerCase()
140-
const metadata = data.toolMetadata.get(normalizedId)
141-
return !metadata || !foundToolNames.has(metadata.tool)
142-
})
143+
const knownCount = data.aiPrunedIds.filter(id =>
144+
data.toolMetadata.has(id.toLowerCase())
145+
).length
146+
const unknownCount = data.aiPrunedIds.length - knownCount
143147

144-
if (missingTools.length > 0) {
145-
message += ` (${missingTools.length} tool${missingTools.length > 1 ? 's' : ''} with unknown metadata)\n`
148+
if (unknownCount > 0) {
149+
message += `\n→ (${unknownCount} tool${unknownCount > 1 ? 's' : ''} with unknown metadata)`
146150
}
147-
} else {
148-
const tokensCollected = formatTokenCount(data.gcPending!.tokensCollected)
149-
150-
message = `🗑️ DCP: ~${tokensCollected} collected`
151-
message += buildSessionSuffix(data.sessionStats, 0)
152151
}
153152

154153
return message.trim()
155154
}
156155

157-
function buildSessionSuffix(sessionStats: SessionStats | null, currentAiPruned: number): string {
158-
if (!sessionStats) {
159-
return ''
160-
}
161-
162-
if (sessionStats.totalToolsPruned <= currentAiPruned) {
163-
return ''
164-
}
165-
166-
const totalSaved = sessionStats.totalTokensSaved + sessionStats.totalGCTokens
167-
let suffix = ` │ Session: ~${formatTokenCount(totalSaved)} (${sessionStats.totalToolsPruned} tools`
168-
169-
if (sessionStats.totalGCTokens > 0) {
170-
suffix += `, ~${formatTokenCount(sessionStats.totalGCTokens)} 🗑️`
171-
}
172-
173-
suffix += ')'
174-
return suffix
175-
}
176-
177156
export function formatPruningResultForTool(
178157
result: PruningResult,
179158
workingDirectory?: string

0 commit comments

Comments
 (0)