mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-28 18:19:28 +00:00
Two structural fixes from the Desktop performance audit (P2 tier): 1. Scope live tool-diff subscriptions. `ToolEntry` subscribed to the whole `$toolDiffs` map via `useStore`, so one `recordToolDiff` re-rendered every mounted tool row. Add a cached per-toolCallId derived atom (`$toolInlineDiff(id)`, mirroring the existing `$toolDisclosureOpen` pattern); computed() only notifies when that id's diff string changes, so a live patch re-renders one row. 2. Narrow profile / gateway-switch query invalidation. Both the active-profile subscription and `wipeSessionListsForGatewaySwitch` called keyless `queryClient.invalidateQueries()`, refetching account/marketplace/onboarding caches on every switch. Add `invalidateProfileScopedQueries()` with a denylist of profile-independent roots (billing, marketplace-themes, onboarding-model-options, contrib-logs-tail). A denylist is correctness-safe: a root we forget just refetches (cheap), whereas an allowlist that misses a profile-scoped key would paint the previous profile's data. Tests: per-tool notify isolation, and real-QueryClient invalidation partition (profile-scoped invalidated, global left intact, unknown keys invalidated).
38 lines
1.1 KiB
TypeScript
38 lines
1.1 KiB
TypeScript
import { atom, computed, type ReadableAtom } from 'nanostores'
|
|
|
|
const $toolDiffs = atom<Record<string, string>>({})
|
|
|
|
// Per-tool derived atoms, cached by toolCallId. A `ToolEntry` subscribes only
|
|
// to its own id's diff, so recording a diff for one tool re-renders that one
|
|
// row -- not every mounted tool row. computed() only notifies when the derived
|
|
// string actually changes, so unrelated writes to the map are inert here.
|
|
const inlineDiffCache = new Map<string, ReadableAtom<string>>()
|
|
|
|
export function recordToolDiff(toolCallId: string, diff: string) {
|
|
if (!toolCallId || !diff) {
|
|
return
|
|
}
|
|
|
|
const current = $toolDiffs.get()
|
|
|
|
if (current[toolCallId] === diff) {
|
|
return
|
|
}
|
|
|
|
$toolDiffs.set({ ...current, [toolCallId]: diff })
|
|
}
|
|
|
|
export function getToolDiff(toolCallId: string): string {
|
|
return toolCallId ? $toolDiffs.get()[toolCallId] || '' : ''
|
|
}
|
|
|
|
export function $toolInlineDiff(toolCallId: string): ReadableAtom<string> {
|
|
let cached = inlineDiffCache.get(toolCallId)
|
|
|
|
if (!cached) {
|
|
cached = computed($toolDiffs, diffs => (toolCallId ? diffs[toolCallId] || '' : ''))
|
|
inlineDiffCache.set(toolCallId, cached)
|
|
}
|
|
|
|
return cached
|
|
}
|