Skip to content

v2026.8.6

Latest

Choose a tag to compare

@github-actions github-actions released this 06 Aug 08:45
03eea87

miloco v2026.8.6

Since v2026.7.17: 175 commits, 29 PRs, 250 files changed (+27,347 / −2,886).

Hotfix for v2026.8.5. On v2026.8.5 the camera process could die with SIGSEGV on some older camera models, taking perception down with it; newer models were unaffected. The cause was traced to the updated miss native library that shipped alongside camera IP direct-connect, so that feature is reverted in full (@Zirconi) and will come back once the library is fixed. If your cameras are already stable on v2026.8.5, the only other change here is the Smart Crop scaling rework listed under Perception Stability. Everything else from v2026.8.5 is intact and listed below.

If the crash took your backend down with it, the dashboard's upgrade banner won't reach you — upgrade from the command line instead:

curl -LsSf https://github.com/XiaoMi/xiaomi-miloco/releases/latest/download/install.sh | bash

On a healthy v2026.8.5 the banner appears on its own, but the release check is cached for 6 hours — click "check for updates" in the sidebar to see it immediately.

🎯 New Features

  • Pet recognition (experimental, off by default) (@ExWang): the largest change in this release. Pets become first-class family members — a pet roster with structured identities, multi-image registration with reference crops persisted and injected into the fused perception prompt, appearance-text matching with an explicit abstain discipline, and body grounding for non-cat/dog species. Ships with a full Web management UI (registration flow, auto-generated appearance, editable profiles, reference-image counts), a CLI command group, and a miloco-miot-pet-register agent skill. Gated behind features.* flags, get/set-able from the CLI.
  • Smart Crop — adaptive resolution before OMNI inference (@Molly-3000): crops the active region out of each perception window before inference, so the model sees the subject at usable resolution instead of a full frame downscaled. Two independent config switches, the crop scaled proportionally until it just fits the panorama frame of the same video_short_edge tier, crop video + full-frame reference persisted side by side, and crop coordinates recorded into the trace. Frame selection uses per-frame human/cat/dog detection boxes inside the window and excludes no_person false detections. Enabled by default.
  • Upgrade notice and one-click self-upgrade in Web (@hlccd): opening the dashboard checks GitHub releases/latest once (server-side cached, with a force re-check) and shows a dot next to the sidebar version plus a dismissible top banner; confirming runs the official install.sh in non-interactive agent mode, detached so it survives the backend restarting itself, and the front end polls /upgrade/status through download → install → restart. Release deployments only — dev (git) deployments are pointed at git pull. If GitHub is unreachable it degrades silently rather than erroring.
  • Process CPU and thread-count charts on the Perf page (@Zirconi): per-process CPU and thread count tracked as a time series with dual axes, CPU normalized to 0–100%, and in-bucket peaks surfaced so a one-minute full-core spike isn't averaged away in the 24h / 3d views.
  • Agent action ledger (@LeonJoeeee): persistent audit of every agent-initiated device control, TTS, and scene trigger, merged into the event page timeline.
  • On-demand perception log (@Molly-3000): actively querying the log now persists its result with artifact storage, front-end display, clip playback, and feedback.
  • Per-camera perception prompt (@HCl8): each camera can carry its own perception-guidance prompt, injected at the tail of the system prompt for both video and audio paths.
  • Urgency filter for suggestion → agent dispatch (@Molly-3000): perception.min_suggestion_urgency filters which suggestions reach the agent, exposed through the admin API and CLI, and surfaced in Web as a 3-stop slider plus an "agent interruption threshold" three-way selector in the settings drawer.
  • Task name and trigger status in rule-reminder logs (@Molly-3000): logs now show which task and which rule fired, with a collapsed-state badge for the backend's trigger verdict.
  • Editable task trigger conditions in Web (@idootop): task detail consolidated into a single edit entry point.
  • Manual avatar replacement for family members (@ExWang): explicit avatars are stored separately under avatars/, with in-browser cropping.

🧠 Perception Stability

  • Latent memory leaks hardened, and the stale match / centroid cache on cluster-centroid change fixed (@idootop): _match_cache invalidation widened from member-set to centroid change and extended to fetch-side embedding backfill and partial cluster-member eviction; dead clusters evicted from _centroid_cache; _drained trimmed regardless of full_action.
  • Decoder worker leak on reconnect fixed (@Zirconi): stop() now joins before clearing the reference, returns False on timeout so the camera can consume it concurrently, and a failure mid-stop no longer aborts the rest of the cleanup.
  • KleidiAI disabled on the silero VAD CPU-EP session and the EventEmbedder session, via a shared apply_kleidiai_opt_out helper with CI-enforced spy tests (@idootop).
  • Smart Crop robustness: bad config now fails closed, crop rejection reasons are observable, degenerate/out-of-bounds coordinates fold into a single 410, and a corrupt trace no longer swallows the entire reference-frame card (@Molly-3000).
  • Smart Crop scaling rewritten around one geometric rule (@Molly-3000): the short-edge budget is gone — a crop is now scaled proportionally until it just fits the panorama frame the same native frame would produce at the same video_short_edge tier. Verified by exhaustive check over 4 source resolutions × 4 tiers × ~890k region sizes: encoded pixels never exceed the same-tier panorama, and subject pixel density is never lower than it. Behavior change: the ceiling is now the same-tier panorama frame rather than the native frame, so a crop can exceed native pixel count when video_short_edge is set above the source's short edge — same as panorama encoding already did. The crop_enhance.crop_short_edge config key is removed; a leftover key in config.json is silently dropped by the existing unknown-key filter and does not block startup.
  • Pet-recognition correctness: the registration size gate switched to absolute size + linear area ratio (large sharp pets no longer rejected), multiple_pets now requires same-frame co-occurrence (a broken track no longer reports one pet as many), subject tracks count real frames, and pool eviction keeps gate-passers first (@ExWang).
  • Plugins grant butler capabilities without overriding the host agent's identity; the backend event body and the habit-suggest skill no longer make the agent refer to itself as miloco (@idootop).
  • Deploy-timezone handling aligned with the CLI write path via ZoneInfo for UTC configs (@HCl8).

🚀 Performance

  • Idle thread pools trimmed across libraries (@Zirconi): every library defaulted to one thread per CPU core, which sits mostly idle on a single low-quality stream. swscale pixel conversion pinned to 2 threads, video decode to 4, OpenCV to 4, the ONNX detector / reid down from 4 to 2, and a new TINY_MODEL_THREADS=1 used by dedup and VAD, where fork-join costs more than it saves.
  • SQLite free pages actually reclaimed now (@Zirconi): PRAGMA incremental_vacuum is driven by consuming its result set, and the missing fetchall meant each cleanup reclaimed exactly one page while pages freed by DELETE piled up — a production observability.db had 142.5 MB of free pages inside 222.8 MB. Reclaim is now capped per run, split into short write transactions, validated against the auto_vacuum mode, and moved to a worker thread since it is real blocking I/O.

⚙️ Improvements: CLI / Web

  • Habit-suggestion state machine moved from the plugin tool into miloco-cli (@HCl8), for both the OpenClaw and Hermes plugins, which is what lets plugins/openclaw and plugins/hermes shed ~1,900 lines between them.
  • Web loading behavior reworked: skeleton placeholders instead of a permanent skeleton on API failure, loading initialized to true to kill the first-frame "load failed" flash, the settings drawer no longer exposes default slider values before data arrives, and the log tab no longer flashes stale history before going blank (@Molly-3000).
  • Device status semantics clarified in Web (@wei-dou).
  • Pet reference-image lookup switched to functools.lru_cache, dropping a module-level try-once global (@ExWang).
  • Rule-reminder log labels trimmed to "task / rule" across backend and front end (@Molly-3000).

🔒 Security / Supply Chain

  • Avatar and pet reference-image endpoints hardened (@ExWang): on-disk extension decided by content magic bytes rather than the filename, realpath containment checks on avatar paths, subject_id validated in the storage layer, uploaded bytes verified as images, person_id anchored with \Z to reject trailing newlines, and a size gate applied before the body is read into memory instead of after.
  • Log-injection fixes flagged by CodeQL: CR/LF stripped from read_crop_meta logging (@Molly-3000); path and log injection closed in the pet and avatar paths (@ExWang); an empty except in perf sampling given a debug log (@Zirconi).
  • Rule short-name stripping now collapses whitespace before matching and narrows its regex to ASCII on both sides, closing a task_id leak through whitespace-leading names, plus free-text prompt-injection guards (@Molly-3000).
  • PR AI-review job timeout raised 30 → 60 minutes (@ExWang); offline eval artifacts and sampling lists added to .gitignore so subject labels can't leak through (@Molly-3000).

📚 Docs

  • Full-chain resolution table added — capture / streaming / omni / crop / provider, with the source and conversion at each tier (@Molly-3000).
  • Smart Crop's two config switches renamed by configuration layer, with the CLI-writes-config.json failure path documented (@Molly-3000).
  • create-task skill tightened (@Zirconi): the TTS action JSON contract documented, Rule.action "play fixed text" scoped to speakers, the perception-viewpoint section given a "no single camera subject" branch, and cross-references realigned.
  • One-click upgrade documented as a feature page, with troubleshooting entries (@hlccd).
  • Perception-guidance injection wording aligned between the system-prompt tail and the video+audio paths (@HCl8).
  • The candidate-bbox comment in prompt_builder corrected — coasting tracks are not filtered upstream, so a Kalman-only phantom box can still reach the remap decision; tracked as #494 (@Molly-3000).

🙏 Acknowledgements

Special thanks to @ExWang for landing experimental pet recognition — the biggest change in this release — and to @Molly-3000 for Smart Crop.

Thanks as well to everyone else who contributed: @Zirconi, @hlccd, @LeonJoeeee, @HCl8, @idootop, @wei-dou