Commit e0cd94b
refactor(hooks): split useLlm into model / generation / streaming hooks
The 517-line useLlm hook bundled 20 Tauri-command wrappers plus a
single 7-field LlmState object. Consumers (DraftTab and SettingsTab)
used cleanly disjoint subsets: DraftTab touches only streaming +
non-streaming generation (9 functions, 2 state fields), SettingsTab
touches only model lifecycle + context-window config (9 functions, no
state fields). Every streaming token setState therefore re-rendered
SettingsTab, and every model load re-rendered DraftTab, because both
consumers subscribed to a single shared state object.
Splits useLlm into three focused hooks, each owning its own state
slice:
src/hooks/useLlmModel.ts (new)
State: modelInfo, isLoaded, loading, error
Commands: checkModelStatus, getLoadedModel, getModelInfo, listModels,
loadModel, loadCustomModel, validateGgufFile, unloadModel,
getContextWindow, setContextWindow
src/hooks/useLlmGeneration.ts (new)
State: generating, error
Commands: generate, generateWithContext, generateWithContextParams,
generateFirstResponse, generateChecklist, updateChecklist,
testModel (+ a runGenerating<T> internal helper that handles
the common setState/try/finally pattern once instead of
seven times)
src/hooks/useLlmStreaming.ts (new)
State: streamingText, isStreaming, generating, error
Commands: generateStreaming, clearStreamingText, cancelGeneration
Behavior: keeps the 500KB MAX_STREAMING_TEXT_SIZE truncation contract
and the UnlistenFn ref-based cleanup
src/hooks/useLlm.ts (rewritten, 517 -> 70 lines)
Thin orchestrator that composes all three and re-exposes the flat
API the codebase grew up with. Unifies `generating` (OR of
generation/streaming) and `error` (first non-null across all three)
so existing callers and the existing useLlm.test.ts see unchanged
semantics.
Migrations:
- DraftTab: useLlm() -> useLlmStreaming() + useLlmGeneration(). Drops
a subscription to loading/isLoaded/modelInfo it never read.
- SettingsTab: useLlm() -> useLlmModel(). Drops a subscription to
streamingText/isStreaming/generating it never read — the main
user-visible win of the split, since streaming tokens no longer
re-render the Settings view when it's open.
- SettingsTab.test.tsx: updates the corresponding vi.mock path from
"../../hooks/useLlm" to "../../hooks/useLlmModel".
No behavior change. The useLlm orchestrator test (4 cases covering
model mgmt / generation / streaming / errors) still passes unchanged
because the orchestrator's API surface is identical. Typecheck +
vitest (241/241) + eslint clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent 04473dc commit e0cd94b
7 files changed
Lines changed: 536 additions & 515 deletions
File tree
- src
- components
- Draft
- Settings
- hooks
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
26 | 26 | | |
27 | 27 | | |
28 | 28 | | |
29 | | - | |
| 29 | + | |
| 30 | + | |
30 | 31 | | |
31 | 32 | | |
32 | 33 | | |
| |||
190 | 191 | | |
191 | 192 | | |
192 | 193 | | |
| 194 | + | |
| 195 | + | |
193 | 196 | | |
194 | 197 | | |
195 | 198 | | |
196 | 199 | | |
197 | | - | |
| 200 | + | |
198 | 201 | | |
199 | 202 | | |
200 | 203 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
121 | 121 | | |
122 | 122 | | |
123 | 123 | | |
124 | | - | |
125 | | - | |
| 124 | + | |
| 125 | + | |
126 | 126 | | |
127 | 127 | | |
128 | 128 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
14 | 14 | | |
15 | 15 | | |
16 | 16 | | |
17 | | - | |
| 17 | + | |
18 | 18 | | |
19 | 19 | | |
20 | 20 | | |
| |||
72 | 72 | | |
73 | 73 | | |
74 | 74 | | |
75 | | - | |
| 75 | + | |
76 | 76 | | |
77 | 77 | | |
78 | 78 | | |
| |||
0 commit comments