Skip to content

v2026.8.5

Latest

Choose a tag to compare

@github-actions github-actions released this 05 Aug 14:07
eebd84a

miloco v2026.8.5

Since v2026.7.17: 171 commits, 26 PRs, 269 files changed (+28,623 / βˆ’2,942).

🎯 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, short-edge upscaling by tier when the crop is below budget, 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.
  • Camera IP direct-connect, with cross-NAT streaming diagnostics (@HCl8): cameras on a different subnet can now be streamed directly β€” the cloud localip field is parsed correctly (previously read as local_ip, so direct-connect silently never worked), unicast probing moved to its own socket isolated from broadcast, and already-connected cameras count as LAN-reachable. When a cross-subnet stream stalls, the camera card now says what to do ("join the same network, or switch to full-cone / open NAT") instead of just failing. Scanning pauses once every known camera is connected.
  • 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, upscaling is capped per axis so an upscaled frame can't exceed the original, degenerate/out-of-bounds coordinates fold into a single 410, and a corrupt trace no longer swallows the entire reference-frame card (@Molly-3000).
  • 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).
  • miot unit tests now actually run in CI β€” norecursedirs had excluded the whole directory, so they never had (@HCl8).

πŸ”’ 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).
  • Unicast probe replies filtered against a source-IP allowlist (@HCl8).
  • 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).

πŸ™ 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