Skip to content

feat: robot network discovery daemon#2484

Open
johnny-kantaros wants to merge 4 commits into
dimensionalOS:mainfrom
johnny-kantaros:jkantaros/dimensional-wizard
Open

feat: robot network discovery daemon#2484
johnny-kantaros wants to merge 4 commits into
dimensionalOS:mainfrom
johnny-kantaros:jkantaros/dimensional-wizard

Conversation

@johnny-kantaros

@johnny-kantaros johnny-kantaros commented Jun 13, 2026

Copy link
Copy Markdown

Problem

An agentic harness has no current mechanism for detecting robots running on the same network. This PR addresses that limitation by installing a persistent background service that broadcasts each robot's identity over mDNS, making them more easily discoverable.

Solution

Adds dimwizard, a daemon that makes robots discoverable on the local network via mDNS. Includes a new hook in dimos run which prompts the user to install the background service (launchd on macOS, systemd on Linux).

The service will continuously broadcasts the robot's name and LCM URL under _dimensional._tcp.local. A follow-up harness PR will use this to automatically detect + connect to robots on the same network without manual config.

How to Test

  uv sync
  dimos run <blueprint>  # wizard should prompt on first invocation
  dimwizard status          # confirm beacon is running
  dimwizard kill               # tear down

Contributor License Agreement

  • I have read and approved the CLA.

@johnny-kantaros johnny-kantaros force-pushed the jkantaros/dimensional-wizard branch from 55b71a8 to 758bce8 Compare June 13, 2026 00:03
@johnny-kantaros johnny-kantaros changed the title feat: persistent discovery daemon for dimos feat: robot network discovery daemon Jun 13, 2026
@greptile-apps

greptile-apps Bot commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR introduces dimwizard, a self-contained sub-package that makes a Dimensional robot permanently discoverable on the local network via mDNS (zeroconf). It integrates with the existing dimos run CLI to optionally install a background beacon as a launchd agent (macOS) or systemd user service (Linux).

  • dimwizard/dimwizard/advertise.pyAdvertiser wraps zeroconf ServiceInfo registration with a local_ip() helper that uses the UDP-connect trick with a psutil fallback; start/stop lifecycle is sound.
  • dimwizard/dimwizard/__main__.py — Daemon entry-point installs signal handlers before start() and uses try/finally to guarantee stop() runs on every exit path.
  • dimwizard/dimwizard/install.py — Platform-specific install/uninstall for macOS (plist) and Linux (systemd); macOS escapes values with xml.sax.saxutils.escape(), but the Linux Environment= lines embed robot_name and lcm_url without escaping.

Confidence Score: 4/5

Safe to merge with one fix: the status command reports values from the current shell environment rather than the installed service configuration, so its output can be misleading after a custom-name install.

The daemon lifecycle (signal handling, start/stop, try/finally cleanup) is solid. The main outstanding defect is in the status command, which reads DIMENSIONAL_ROBOT_NAME and LCM_DEFAULT_URL from the current process environment instead of the values baked into the installed unit file — meaning the displayed robot name and LCM URL can contradict what the running beacon actually advertises. The Linux Environment= escaping issue in install.py is the other open concern.

dimwizard/dimwizard/cli.py (status command reads env vars instead of persisted config) and dimwizard/dimwizard/install.py (unescaped values in Linux systemd unit file)

Important Files Changed

Filename Overview
dimwizard/dimwizard/advertise.py New mDNS advertiser — local_ip() uses UDP-connect-to-8.8.8.8 with psutil fallback; Advertiser.start/stop manage the zeroconf lifecycle correctly
dimwizard/dimwizard/main.py Daemon entry-point — signal handlers registered before advertiser.start(), try/finally guarantees stop() is always called, clean shutdown path
dimwizard/dimwizard/cli.py Typer CLI for status/kill — status reads env vars at query time instead of the persisted unit-file values, so reported robot name/LCM URL can disagree with what the daemon actually advertises
dimwizard/dimwizard/install.py Platform installer — macOS plist uses xml.sax.saxutils.escape() correctly; Linux systemd unit embeds robot_name and lcm_url directly into Environment= lines without escaping
dimwizard/dimwizard/setup.py Setup wizard hook — None return from questionary (non-TTY) is now handled with early return; no persistent opt-out mechanism
dimos/robot/cli/dimos.py Calls _setup_wizard() at start of run; KeyboardInterrupt is re-raised, all other exceptions are swallowed gracefully; optional dimwizard dependency handled via ImportError catch

Sequence Diagram

sequenceDiagram
    participant User
    participant DimosCLI as dimos run
    participant SetupWizard as dimwizard/setup.py
    participant Install as dimwizard/install.py
    participant SystemD as systemd/launchd
    participant Beacon as dimwizard __main__
    participant Zeroconf as zeroconf

    User->>DimosCLI: dimos run
    DimosCLI->>SetupWizard: setup_wizard()
    SetupWizard->>Install: is_installed()?
    alt not installed
        SetupWizard->>User: Prompt: Set up network discovery?
        User->>SetupWizard: yes
        SetupWizard->>Install: install()
        Install->>SystemD: write unit file + enable --now
        SystemD->>Beacon: start process
        Beacon->>Zeroconf: Advertiser.start() register_service()
        Zeroconf-->>Beacon: mDNS beacon running
    else already installed
        SetupWizard-->>DimosCLI: return (skip)
    end
    DimosCLI-->>User: robot running

    User->>DimosCLI: Ctrl+C / SIGTERM
    DimosCLI-->>User: exit
    SystemD->>Beacon: SIGTERM
    Beacon->>Zeroconf: Advertiser.stop() unregister + close
Loading

Reviews (3): Last reviewed commit: "fix: dimwizard cleanup" | Re-trigger Greptile

Comment thread dimwizard/dimwizard/setup.py
Comment thread dimwizard/dimwizard/setup.py
Comment thread dimwizard/dimwizard/cli.py
Comment thread dimwizard/dimwizard/__main__.py Outdated
Comment thread dimwizard/pyproject.toml
@@ -0,0 +1,21 @@
[build-system]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why a separate pyproject.toml? Does this get included in the dimos package?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants