Releases: abz2much/NOVA
Releases · abz2much/NOVA
Release list
v8.7.7 — Internal tidy: the panel debug log moves to its own module, all 41 admin commands are checked by a test, coverage floors raised
v8.7.7 — Internal tidy: the panel debug log moves to its own module, all 41 admin commands are checked by a test, coverage floors raised
Latest
[8.7.7] — Internal tidy: the panel debug log moves to its own module, all 41 admin commands are checked by a test, coverage floors raised
This is an internal change. Nothing you can see or configure changes: no setting, service, websocket command, error code or stored file is different, and the panel behaves as before. It is the first step of splitting websocket.py, which is 4,300 lines.
Moved (code moved as it was, no edits)
- The panel debug log moved from
websocket.pyto a newcustom_components/nova/ws_log.py: the two in memory buffers (500 entries, and 80 for conversation and reply routing), thenova.logfile, its queue, writer thread and lock,nova_log,recent_debug_logandrecent_conversation_log. The new module imports nothing from Home Assistant. - The persisted log is still read once when Nova is imported, before the config folder is set, from the same file (
nova/nova.log).websocket.pystill exportsnova_log,recent_debug_logandrecent_conversation_log, so the 15 modules that importnova_logfrom it are untouched. _read_integration_versionand_INTEGRATION_VERSIONstay inwebsocket.py.
Tests
- New
tests/ws_sources.pyreadswebsocket.pyand everyws_*.pytogether. The tests andtests/contract_extract.pythat readwebsocket.pyby path now use it, so they keep finding commands and helpers after later moves. test_websocket_admin_gate.pylisted 36 of the 41 admin gated commands. It now lists all 41 (it addscamera_snapshot,clear_scene_memory,get_debug_log,list_actionsandsay_hello), and the count check is exact. These five were already admin gated and pinned bywebsocket.json. This only makes the gate test cover them.- 31 new unit tests for the debug log (
tests/unit/test_ws_log.py). The behaviour tests passed against the old code before the move. - The one test that patched
_LOG_FILEonwebsocketnow patches it onws_log._LOG_FILEis not re exported, so a stray patch of it onwebsocketfails loudly instead of doing nothing. tests/fixtures/contracts/storage.json: the owner ofnova/nova.logis nowws_loginstead ofwebsocket. The path is the same.websocket.jsonis unchanged.
Coverage floors
agent_runtime71 to 74 andintent33 to 35 (measured 75.1% and 36.5% on the unit run). The Python 3.14 run that CI also does was not measured.
v8.7.6 — Delivery and mail: no wide views, a 30 minute announce cooldown, early checks from sensors
[8.7.6] — Delivery and mail: no wide views, a 30 minute announce cooldown, early checks from sensors
Fixed
- Package watch no longer sweeps wide views. It matched the text "front" anywhere in a camera's entity ID, so
camera.front_yardandcamera.front_gardenwere checked for packages. It now matches whole words in the part after the dot (split on_and on letters versus digits). A camera is watched when it has the word doorbell, frontdoor, porch or front (or frontporch, frontdoorbell) and none of these wide view words: yard, backyard, frontyard, street, road, lawn, garden, driveway, curb, field, garage, pool, patio, deck, gate, parking, lot. - A camera you name yourself (the
entity_idonnova.check_packages) is never filtered, and a Eufy camera with native package sensors is still left to its own sensors, both as before.
Camera names whose behaviour changes
- Watched before, not now, because of a wide view word:
camera.front_yard,camera.front_garden,camera.front_driveway,camera.front_lawn,camera.front_gate,camera.front_garage_door,camera.porch_driveway,camera.frontyard. - Watched before, not now, because the word is glued to other letters:
camera.porchcam,camera.doorbellcam,camera.frontcam,camera.frontdoorcam,camera.backporch. Use thenova.check_packagesentity ID, or rename the entity, to keep one watched. - Not changed:
camera.front_door,camera.frontdoor,camera.front_door_hd,camera.frontdoor_hd,camera.front_door_2,camera.porch,camera.back_porch,camera.doorbell,camera.my_doorbell,camera.front,camera.frontporch,camera.frontdoorbell, andcamera.front_porch_wide(the word "wide" is not on the wide view list).
Added
- A 30 minute announce cooldown for each camera and kind of alert (delivered, mail, removed, stranded). A repeat inside 1800 seconds is not spoken. The state, the log, the observer event and the learning record all happen as before. Only the speech is skipped. A "removed while away" alert is never held back by a recent "delivered", because each kind has its own clock. A "stranded" reminder is gated too.
- Porch motion sensors can start a check early. A binary sensor with device class motion, occupancy or presence, whose name passes the same test as a camera, starts the existing package sweep 20 seconds after it turns on. At most one early check every 3 minutes. It only brings the sweep forward: the second look and the state machine are the same, and it adds no new way to speak. Sensors on a Eufy camera that already has package sensors are left out.
- Mailbox sensors can announce mail. A binary sensor with device class opening, door, occupancy or none, whose name has the word mailbox, letterbox or postbox, runs the package state machine with mail True when it turns on. Mail already true is ignored, and each sensor is debounced for 5 minutes.
- Both sensor triggers respect Package Watch (
package_detection), quiet hours, announcements and the cooldown. There is no new setting. Only a real off to on change counts, so a sensor coming back from unavailable does nothing. - The sensors are found once at setup, the same way as the Eufy sensors. A sensor added later needs a Nova reload.
Caveats
- Opening your own mailbox to collect mail can announce once, because a sensor cannot tell who opened it.
- A real second delivery inside 30 minutes is logged and shown in the panel but not spoken.
- Mail that sits in a mailbox is not visible to a porch camera, so camera mail detection is unchanged.
- A mailbox sensor gets its own entry in the tracked package state (the sensor's entity ID). Mail counts as already announced for 30 minutes. After that, the next opening counts as new mail, because nothing else clears that entry.
- In quiet hours, or with announcements off, a mailbox opening updates the state and the log but is not spoken, like every other package event. With Package Watch off it does nothing at all. A mailbox opening is recorded for pattern learning with the source "vision", because that recorder has no sensor source.
- The cooldown and the debounce are kept in memory, like the package state, so a restart clears them.
- An early check costs the same vision calls as the regular 15 minute sweep, at most one extra sweep every 3 minutes.
- No existing test assertion was changed.
tests/conftest.pygains a fixture that clears the new cooldown and debounce dictionaries around every test, because the test loader keeps the module between tests.
v8.7.5 — Diagnostics downloads scrub error lines, log tails and service health
[8.7.5] — Diagnostics downloads scrub error lines, log tails and service health
Fixed
- The error lines in a diagnostics download (the
*_errorfields and a subsystem'serror) now pass through the same scrubbing as the rest of the file. Each one reads as the error type and its text, with passwords in URLs (user:pass@host), token or key query parameters and webhook addresses removed. The detail is kept otherwise, because the download is for you. - The recent log tail (
recent_log) and the conversation log (conversation_log) in the download are scrubbed the same way. Each entry keeps its date, time, category and message, and a message without credentials is unchanged. - The service health section (
service_health) is scrubbed the same way, including each service's detail and error text. - Webhook addresses inside free text are now hidden too. Before, a webhook address was hidden only when its setting name said webhook. Now everything after the webhook part of the path goes: n8n
/webhook/and/webhook-test/, Home Assistant/api/webhook/, Discord/api/webhooks/and Slackhooks.slack.com/services/.
Caveats
- Scrubbing works on patterns. A secret that is not in a URL's
user:pass@, a token or key query parameter or a webhook path, such as a bare key pasted into a message, is not caught. - The
connectivitykey is never in the download. Nova's connectivity module has no snapshot to give it. Its call is scrubbed in case one is added later. - Only the download changes. The panel's Logs tab and Nova's log file still hold the full text.
- Error lines are now at most 200 characters, as the audio routing and subsystem errors already were.
- Audio routing still lists the paired speakers by entity ID, and the entity counts per domain are unchanged.
v8.7.4 — Security tidy up: file permissions, safe error text, document scans off the event loop
[8.7.4] — Security tidy up: file permissions, safe error text, document scans off the event loop
Fixed
- Nova's config file (
/config/nova/config.json) is now readable only by Home Assistant's own user. Before, it was written readable by everyone on the system. An existing file is tightened the next time Nova loads it. - The backup of
secrets.yamlNova makes before changing it (secrets.yaml.nova.bak), and the state backups in/config/nova_backups/, are now readable only by Home Assistant's own user too. Both can hold keys. - Errors no longer pass raw exception text to the AI model or the panel. They now say what kind of error it was and that the details are in the Home Assistant log, which keeps the full error. Three kinds of text still come through as they are: Nova's own settings validation messages, Nova's provider errors (built only from fixed phrases and the HTTP status), and, for tool calls, Home Assistant's own error text, which Home Assistant itself also gives the model.
- Document scans no longer block Home Assistant. Listing the documents and watch folders, the seen files table and the semantic search store now all run off the event loop, as does turning semantic search on or off.
- The reasoning loop retries a provider only when the provider is rate limited, timed out or unavailable. Before, any error text containing "500", "503" or "429" counted, so "1500 tokens" could trigger a pointless retry.
- Diagnostics downloads now scrub passwords in URLs (
user:pass@host) and token or key query parameters from every value, and hide webhook addresses.
Caveats
- Only Nova's own files change permissions.
secrets.yamlitself was already written owner only by Nova, and is unchanged. - A provider error that has no HTTP status is still classified from its text by the shared provider classifier, so a number such as "1500" in that text can still read as "500" there. Errors with a status, which is most of them, are classified by the status.
- A connection failure is still not retried by the reasoning loop, as before.
- The error lines in a diagnostics download (the
*_errorfields), the recent log tail and the service health section are not scrubbed. Diagnostics already hides a URL's password in the service health section. - Panel error messages are shorter. Check the Home Assistant log for the detail.
v8.7.3 — Adaptive awareness learns only from what you confirm
[8.7.3] — Adaptive awareness learns only from what you confirm
Changed
- Adaptive awareness no longer guesses. Before, a routine alert left unmuted for a day counted as welcome, and muting something soon after an alert counted as unwelcome. Neither counts any more.
- Each routine alert now comes with Helpful and Not helpful buttons on your phone. When the alert goes to your phone (quiet hours, asleep), the buttons are on it. When it is spoken, a silent phone notification, "Was this helpful?", carries them. It makes no sound.
- You can still rate an alert in the panel (Logs, Decisions: Helpful, Unnecessary, Wrong).
- Only those ratings count. Nothing changes until at least five alerts have been rated, and the first rating of an alert stands.
Caveats
- The buttons only appear while adaptive awareness is on, and only on routine alerts that leave a decision record: usually active by now, usually home or out by now, routine starts and calendar departures.
- Ratings already stored by earlier versions, including those from mutes, still count until they are 30 days old.
- On Android the silent notification uses a new "Nova ratings" channel, which you can change in the app's notification settings.
- Hard refresh the page (Ctrl+Shift+R) after updating.
[8.7.2] — Scene memory keeps only real sightings, GPT-5 replies, and review fixes
Fixed
- Scene memory no longer stores the intrusion "is anyone there?" check. Its "PERSON: NO" answer was saved as a person sighting, so "when did you last see a person in the hall?" could point at a frame where vision had said nobody was there.
- Scene memory no longer stores the doorbell backlog scan. Those are old recordings, but they were saved as seen now, so "where did I last see the package?" could answer "just now" about a weeks-old event.
- Scene memory never answers from descriptions older than the retention, and expired descriptions are deleted at startup, including while scene memory is off. Before, they were only deleted when a new one was written.
- OpenAI's GPT-5 and o-series models no longer return empty replies on short requests. Their hidden reasoning counts against the reply budget, and Nova's scenes, classifier, sentinel and package checks ask for 40 to 120 tokens, which reasoning could use up before any text was written. Nova now adds room for the reasoning on top of the budget and asks for low reasoning effort. Fine-tuned GPT-5 and o-series models are recognised too.
- "Go quiet after 3 days" now saves its file off the event loop.
- Replacing a saved key in secrets.yaml keeps backslashes in it. Before, a custom or Ollama key containing a backslash was changed on write or made secrets.yaml unreadable. Other providers' keys never contain one.
- Adaptive awareness can now also wait less. A routine alert left unmuted for a day counts as welcome. Before, muting was the only automatic verdict, so after five mutes it stayed at "wait longer" for good.
- The welcome card's voice step, and Setup Doctor's Assist pipeline check, accept any pipeline that uses Nova as its conversation agent, whatever it is called. Before, only a pipeline named or voiced "Nova" counted.
- A Home Assistant user who isn't an admin now sees that Setup Doctor and Say hello need an admin account, instead of "restart Home Assistant after updating".
Caveats
- Descriptions the two checks above already stored are kept until they expire (14 days by default), or until "Forget everything" in Settings.
- The GPT-5 change was checked against OpenAI's documentation and with a fake client, not with a real key. The extra room is a ceiling, not a cost: only tokens actually used are billed.
- With adaptive awareness on, routine alerts from the last 30 days count right away, including ones from before this update. An alert you didn't mute counts as welcome even if you simply didn't see it, and calendar departure alerts can still only be marked unwelcome by hand.
- Hard refresh the page (Ctrl+Shift+R) after updating.
v8.7.1 — Fewer classifier calls, quieter infrastructure audit, fewer blocking calls
Fixed
- Motion, occupancy and presence sensors no longer use up the hourly classifier budget while someone is home. They are kept as recent context but not sent to the AI classifier. They still are when everyone is away or presence is unknown (presence here comes from people and the alarm only, not from occupied rooms), and a local cognition anomaly still escalates them. While home they no longer appear in the activity feed as "not worth considering". On a busy home this hit the 100 calls an hour limit several times a day.
- The infrastructure audit no longer reports sensors that don't exist in your home. Before, every home without those exact server and switch sensors got "I can't read root storage" every 15 minutes.
- The audit no longer speaks to a built-in "office" area. Pick its room in Settings, Host Health, "Audit alerts room". Left at none, it only logs what it finds. If you relied on hearing audit alerts in an area called office, pick that room.
- Nova no longer reads the learned names file on the event loop when it resolves a device name.
- Answering the "Heading to bed?" notification no longer saves settings on the event loop, and the sleep override now saves once instead of twice.
v8.7.0 — Set up every AI role at first run
Added
- First setup takes a key for each cloud provider (Groq, Anthropic, OpenAI, Gemini) and an Ollama address, all optional, and tests each one.
- You choose the provider and the model for each role: conversation, classifier, reasoning, camera reasoning and vision. Sensible choices are filled in.
- Each model is tested on submit. The vision model gets a small test picture.
- Keys left in secrets.yaml by an earlier install are found and reused.
- Setup Doctor's new "AI roles" check warns when a role's provider has no key or address.
Fixed
- A new install with only an Anthropic, OpenAI, Gemini or Ollama setup no longer leaves the background and camera roles pointing at Groq with no key.
- OpenAI's GPT-5 and o series models now work: Nova sends them max_completion_tokens and no temperature, which is what they require. Before, every call to them failed.
- A fresh setup through the screens over an old config.json no longer lets the old AI choices win.
- The config flow unit tests now run in CI. They were silently skipped.
- Camera vision works again on Groq. Groq shut down the default vision model, qwen/qwen3.6-27b, on 14 September 2026. The default is now its successor, qwen/qwen3.8-27b, and a saved setting that still names the old model is sent as the new one.
- Gemini's chat reply to a bad key ("Please pass a valid API key") now shows as an invalid key, not a general error.
- The Anthropic default model is now claude-sonnet-5-5, the current Sonnet. claude-sonnet-5 is still offered but is a legacy model.
Caveats
- The setup screens save keys in secrets.yaml, never in Home Assistant's config entry.
- The setup screens only show on a fresh install, so they have not been seen on a live install.
- Each provider's reply to a bad key was checked live with a fake key. Model names and request formats were checked against each provider's docs, not with real keys.
v8.6.1 — fix: two file reads blocking Home Assistant
Fixed
- The panel no longer reads the doorbell training log on Home Assistant's event loop. It read the whole file on every 20 second refresh. It now reads it in the background.
- Nova now loads its habituation file during setup, in the background, like its other state files. Before, the first panel status request read it on the event loop.
- Home Assistant's "Detected blocking call to open" warnings for these two files no longer appear.
v8.6.0 — Voice setup shows its progress in Repairs
Added
- On HA OS, the first voice setup now shows a Repair notice, "Nova is setting up voice", with the current step: installing the Piper, Whisper and openWakeWord add-ons, connecting Wyoming, then creating the Nova pipeline. It clears itself when setup finishes.
- If any part fails, a "Nova voice setup is incomplete" notice names what failed and gives the steps to finish it by hand. Nova checks again on each restart and clears the notice once voice works, including when you fix the pipeline yourself.
- The notice text is translated into all seven languages.
Caveats
- The progress notice shows on the first voice setup only, not on routine Nova updates.
- On HA Container there is no Supervisor, so there is no voice setup and no notice. Setup Doctor's Assist pipeline check covers that case.
v8.5.0 — Nova follows Home Assistant's config directory
Changed
- Nova no longer hard codes
/configanywhere. A newpaths.pytakes Home Assistant's own config directory at setup, and every store (databases, state files, logs, documents, secrets) is found through it when used. - Shared files such as
patterns.dbandconversations.dbare named in one place instead of many. - Messages that show a path now show the real one: the broken config.json notice, the IMAP password hint, the documents folder in the panel, and the documents tool text the AI model sees.
Caveats
- On HA OS and HA Container the config directory is
/config, so every file stays exactly where it was. Nothing moves and no data is migrated. - Installs whose config directory isn't
/confignow keep Nova's files in that directory, as they always should have. - Hard refresh the page (Ctrl+Shift+R) after updating.