Containers¶
In C4 terms, a container is a separately running or deployable part. AutoDiag has one central server process and several clients.
flowchart TB
subgraph clients["Clients"]
cli["<b>CLI</b><br/>Python · argparse<br/>dds-autodiag"]
web["<b>Web dashboard</b><br/>HTML · vanilla JS<br/>served by the server"]
panel["<b>RViz2 panel</b><br/>C++17 · Qt 5 · pluginlib<br/>loaded by rviz2"]
end
server["<b>AutoDiag server</b><br/>Python · FastAPI · Uvicorn<br/>127.0.0.1:8080"]
native["<b>Native core</b><br/>C++20 binaries<br/>autodiag_core_cli · autodiag_bt"]
store[("<b>Local state</b><br/>~/.config/dds-autodiag (keys, 0600)<br/>~/.cache/dds-autodiag (embeddings)")]
kb[("<b>Knowledge base</b><br/>autodiag/kb/*.json")]
web -- "HTTP REST + NDJSON" --> server
panel -- "HTTP REST + NDJSON<br/>QNetworkAccessManager" --> server
cli -- "in-process Python calls" --> engines
server --> engines["Engines<br/>(in-process)"]
engines -- "subprocess, no shell" --> native
engines --> store
engines --> kb
| Container | Technology | Runs as | Talks to |
|---|---|---|---|
| Server | FastAPI, Uvicorn, Pydantic | dds-autodiag serve, systemd user unit, or Docker |
Probes the system, calls AI providers, serves the dashboard |
| CLI | argparse | One-shot process | Imports the engines directly, no server needed (except serve) |
| Web dashboard | Static HTML/CSS/JS, no framework | Browser | Server REST API and NDJSON stream |
| RViz2 panel | C++17, Qt Widgets/Network, rviz_common |
Plugin inside rviz2 |
Server REST API and NDJSON stream; RViz display API |
| Native core | C++20, CMake, CTest, BehaviorTree.CPP | Subprocess per request | Called by the server with argument lists, JSON on stdout |
Communication¶
| From → to | Protocol | Notes |
|---|---|---|
| Dashboard / panel → server | HTTP/JSON | Same API for both clients; bearer token or cookie when enabled |
| Server → clients (AI) | NDJSON over HTTP | One JSON event per line: context, meta, thinking, token, done/error |
| Server → ROS 2 | ros2 CLI subprocesses |
--no-daemon with a discovery wait; timeouts and output caps |
| Server → native core | Subprocess | Fixed argument list, 5–8 s timeout, JSON / JSON-lines output |
| Server → Ollama | HTTP, loopback only | Streaming chat, embeddings, model list |
| Server → cloud AI | HTTPS | Official Anthropic SDK; REST with SSE for OpenAI-compatible and Gemini |
| Server → peer collector | HTTP | Private or loopback IP only, no proxy, no redirects, size-capped |
Why a server at all?¶
The RViz panel could have called AI providers itself. Keeping one server means:
- Keys live in one place, never in
.rvizfiles or the browser. - One implementation of rules, retrieval and providers serves the CLI, dashboard and panel.
- The panel stays thin: it only adds RViz context and applies validated plans.
See ADR-003.
Deployment views¶
dds-autodiag serve in a terminal with ROS 2 sourced; RViz panel built with colcon.
The user unit sources ROS 2 and starts the server on login (or on boot with loginctl enable-linger). Access
via SSH tunnel, or token + allowed hosts.
--net=host --ipc=host so the container sees the host's DDS graph and shared memory. Runs as a non-root user
with a health check on /api/healthz.