Repository navigation
let Sentinel's LLM work be isolated from the interactive path #866
Description
Checklist
- I have filled out the template to the best of my ability.
- This only contains 1 feature request (if you have multiple feature requests, open one feature request for each feature request).
- This issue is not a duplicate feature request of previous feature requests.
Is your feature request related to a problem? Please describe.
On a local single-GPU edge setup, Sentinel's LLM work (triage, discovery) can contend with
and occasionally stall the interactive voice/chat path, even when the machine has plenty of
spare memory and CPU. Two gaps make this hard to manage today:
-
Sentinel has no model/provider selector. Conversation (Chat), Camera (VLM),
Conversation Summary, and Embeddings can each be assigned their own model, but Sentinel
inherits a shared tier. There's no way to point Sentinel at a small dedicated model or a
separate Ollama instance, so its LLM work necessarily runs on a tier that's also serving
interactive requests. -
Triage fans out one LLM call per finding with no batching or rate limit. A single
detection cycle that produces many findings fires a burst of triage calls in a tight
window. For a background safety engine, that's a disproportionate, bursty load on a
shared model.
Real-world example (my setup):
- Mac mini (Apple Silicon, one GPU, 48 GB),
qwen3:8bserving both voice and Sentinel via
Ollama,NUM_PARALLEL=1. - A Sentinel cycle fired ~17 triage calls in a couple of seconds. Shortly after, a voice
turn arrived; admission control correctly cancelled the in-flight Sentinel task — but on
Ollama the cancellation appears to wedge the runner (prefix-cache/[3.45.0-beta.1] All LLM-backed features stall together; backend Ollama enters a stuck state and an HGA config-entry reload does not recover it #813 family), so the
voice request then stalled for several minutes until an external watchdog issued
ollama stop. The machine had ~58% memory free throughout — this is a request-pattern
interaction, not a capacity problem. sensor.sentinel_healthshowedtriage_suppress_rate: 0across ~500 findings — i.e. the
triage fan-out was pure load with no suppression benefit on this install, which made the
cost especially visible.
Describe the solution you'd like
-
A model/provider selector for the Sentinel subentry, mirroring the existing feature
tiers, defaulting to the current behaviour (Chat tier) for backward compatibility. This
lets users put Sentinel on a small dedicated model (e.g.qwen3:4b) and/or a separate
Ollama instance, fully isolating it from the interactive path at negligible cost — triage
is a trivial classification and discovery is periodic, so a small model is ample. -
Batching / rate-limiting of triage calls so a cycle with N findings doesn't issue N
concurrent (or rapid serial) LLM calls on a shared model — e.g. a small concurrency cap,
or a single batched triage request per cycle.
Describe alternatives you've considered
.
Additional context
t would also help to document that model_provider_uncontended should stay false on
shared-GPU edge hosts (so admission control keeps chat ahead of Sentinel), and to note that
task cancellation alone can't recover a wedged Ollama runner — an upstream consideration, but
relevant to how aggressively Sentinel should contend on a single local GPU.
Thanks for HGA — happy to test any of this on the local-Ollama path (as with #830).
Activity
goruck commentedon Oct 27, 2026
Thanks Andy, this is a clear write-up, and the
triage_suppress_rate: 0across ~500 findings is a useful data point.What the code does today:
chat_modelis passed to the triage service and the explainer at setup), so on a single-GPU Ollama host they always share a runner with voice.sentinel_admissionfirst. A voice turn arriving mid-burst cancels the in-flight one, which is the cancellation you saw wedge the runner.Workaround now: since triage suppressed nothing on your install, turning it off (Sentinel options → "Enable LLM triage of findings") removes the burst entirely. Findings still notify; triage only ever filters, and it fails open.
Plan (both in the next monthly bundle, with a pre-release for you to test on the Mac mini like #830):
I'll also add your two doc points: keep
model_provider_uncontended: falseon shared-GPU hosts, and cancellation can't recover a wedged Ollama runner.andymcmanus commentedon Oct 27, 2026
Brilliant. I will test the pre-release when it's available.
fix(sentinel): close the review findings on the triage budget, chat g…
Merge pull request #875 from goruck/fix/sentinel-triage-burst-866
goruck commentedon Oct 27, 2026
Step 1 is merged (#875) and ships in 3.45.0, the next monthly bundle. What it does on a local model shared with chat:
sensor.sentinel_healthshowstriage_calls_last_runandtriage_passed_through_last_run, andtriage_suppress_ratenow counts only findings the model decided on.model_provider_uncontendednow bypasses every local gate as documented; keep it off on the Mac mini.A cloud provider is never limited. The review found and fixed a few things on the way, including the option not reaching runtime at first and the burst moving to explanations, so the field test matters: say the word and I'll cut a pre-release so you can run it on the Mac mini before the bundle, as with #830.
Step 2, a model selector for Sentinel so it can run on a small model or a second Ollama server, is still planned as its own PR.
andymcmanus commentedon Oct 28, 2026
Thanks Lindo — this is exactly the shape I was hoping for, and the “never cancel a probe once sent” point is spot on given the re-wedge behaviour we saw.
Yes please, cut the pre-release and I’ll run it on the Mac mini ahead of the bundle, same as #830.
What I’ll report back:
ollama-doctor restart frequency before vs after — that watchdog’s restart count has been my real-world proxy for the runner wedging, so it’s the number I most want to see move.
sensor.sentinel_health — triage_calls_last_run, triage_passed_through_last_run, and the corrected triage_suppress_rate, to confirm the per-run cap is actually biting and to see what proportion now passes through untriaged on my install.
The contention case directly — fire a voice turn mid-Sentinel-run and confirm it no longer stalls, and that the 30 s grace behaves as described without starving Sentinel over a busy period.
model_provider_uncontended staying off on the mini, understood. And good to hear the selector (step 2) is still on the roadmap — that’s the piece that’ll let me move Sentinel off the voice model’s runner entirely.
fix(sentinel): close the review findings on the Sentinel model tier (#…
Merge pull request #876 from goruck/feat/sentinel-model-tier-866
goruck commentedon Oct 28, 2026
The pre-release is up: v3.45.0-beta.5. It has both steps:
It installs the same way as the #830 beta: with beta versions enabled for Home Generative Agent in HACS, pick
v3.45.0-beta.5, then restart Home Assistant.Some notes for your setup:
gpt-5-nano, say, is never held back or cancelled by your local voice model.qwen3:4bbeside yourqwen3:8b) needs room for both:OLLAMA_MAX_LOADED_MODELSof 2 or more, and enough memory. Otherwise each Sentinel call unloads the voice model and the next voice turn waits for it to load again.Your three measurements are what I'd most like to see, the restart count especially. I'll keep this issue open until you've had a chance to run it.