5.6 KiB
Agent CLI Simplification — Handoff to ria-toolkit-oss
Repo: ria-toolkit-oss, branch screens-connection
Goal: Reduce agent setup from 3+ commands to 2 simple ones.
Current UX (painful)
# Step 1: Register via curl against FastAPI directly
curl -X POST http://hub:8005/screens/agents/register \
-H 'X-API-Key: supersecretapikey' \
-d '{"name": "my-agent"}'
# → {"agent_id": "agent-55cf3c5b8137f6f3", "token": "45Hbt..."}
# Step 2: Manually save credentials
ria-agent register \
--url http://hub:8005 \
--token 45HbtlpVDX7_XTF47biDcLcyiVmM51icEZVJ7J_UrEE \
--agent-id agent-55cf3c5b8137f6f3
# Step 3: Stream (with manual URL construction)
ria-agent stream \
--url "ws://hub:8005/screens/agent/ws?agent_id=agent-55cf3c5b8137f6f3" \
--token 45HbtlpVDX7_XTF47biDcLcyiVmM51icEZVJ7J_UrEE
Problems:
- User must know the FastAPI port (8005), not just the hub URL (3005)
registersubcommand only saves locally — doesn't call the server_derive_ws_urlbuilds/api/agent/ws/{agent_id}but server endpoint is/screens/agent/ws?agent_id=...- User must copy-paste agent_id and token between commands
Target UX
# One-time setup: register with the hub (hits server, saves config)
ria-agent register --hub http://whitehorse:3005 --api-key supersecretapikey --name lab-pluto
# Stream (reads config, connects automatically)
ria-agent stream
That's it. Two commands, no copy-pasting.
Changes needed in ria-toolkit-oss
1. cli.py — Make register call the server
Current _cmd_register just saves to ~/.ria/agent.json. It should:
- POST to
{hub_url}/screens/agents/registerwithX-API-Keyheader - Receive
{agent_id, token}from the server - Save everything to
~/.ria/agent.json
def _cmd_register(args: argparse.Namespace) -> int:
import urllib.request
import json as _json
hub_url = args.hub.rstrip("/")
api_key = args.api_key
# Call the server to register
url = f"{hub_url}/screens/agents/register"
body = _json.dumps({"name": args.name or ""}).encode()
req = urllib.request.Request(
url,
data=body,
headers={
"Content-Type": "application/json",
"X-API-Key": api_key,
},
)
try:
with urllib.request.urlopen(req) as resp:
data = _json.loads(resp.read())
except Exception as e:
print(f"error: registration failed: {e}", file=sys.stderr)
return 1
agent_id = data["agent_id"]
token = data["token"]
# Save to config
cfg = _config.load()
cfg.hub_url = hub_url
cfg.agent_id = agent_id
cfg.token = token
if args.name:
cfg.name = args.name
cfg.insecure = bool(args.insecure)
path = _config.save(cfg)
print(f"Registered agent: {agent_id}")
print(f"Credentials saved to {path}")
return 0
Update the argparse for register:
p_reg = sub.add_parser("register", help="Register agent with RIA Hub and save credentials")
p_reg.add_argument("--hub", required=True, help="RIA Hub URL (e.g. http://whitehorse:3005)")
p_reg.add_argument("--api-key", required=True, help="Hub API key for authentication")
p_reg.add_argument("--name", default=None, help="Human-friendly agent name")
p_reg.add_argument("--insecure", action="store_true", help="Skip TLS verification")
Remove --url, --token, --agent-id from register — those are now server-generated.
2. cli.py — Fix _derive_ws_url
Current (wrong):
suffix = f"/api/agent/ws/{agent_id}" if agent_id else "/api/agent/ws"
Should be:
suffix = f"/screens/agent/ws?agent_id={agent_id}" if agent_id else "/screens/agent/ws"
3. cli.py — Make stream zero-arg by default
Current _cmd_stream already loads config and derives the URL — it just needs the URL fix above. After that, bare ria-agent stream works if register was run first.
4. config.py — Add api_key field (optional)
Add api_key: str = "" to AgentConfig so the hub API key can be persisted for re-registration or other API calls. Not strictly required but useful.
Changes already done in ria-hub (Part B)
The server side is ready:
POST /screens/agents/register— accepts{"name": "..."}withX-API-Keyheader, returns{"agent_id": "...", "token": "..."}GET /screens/agent/ws?agent_id=...— WebSocket endpoint, authenticates viaAuthorization: Bearer {token}header- Agent token is hashed (SHA-256) and stored in MongoDB; lookup happens on WS connect
The Go proxy for /screens/agents/register through port 3005 still needs to be added (currently agents must hit FastAPI port 8005 directly). That's a ria-hub task, not ria-toolkit-oss.
Summary of file changes
| File | Change |
|---|---|
src/ria_toolkit_oss/agent/cli.py |
register calls server API, new flags --hub/--api-key; fix _derive_ws_url path |
src/ria_toolkit_oss/agent/config.py |
Optional: add api_key field to AgentConfig |
tests/agent/test_cli.py |
Update register tests for new server-calling behavior |
Validated E2E flow (what works today)
We tested the full pipeline on whitehorse with a real Pluto SDR:
- Agent connects via WebSocket with bearer token auth ✅
- Server sends
startwithradio_configvia Redis pub/sub → agent ✅ - Agent opens Pluto, streams interleaved float32 IQ via binary WS frames ✅
- FastAPI pushes frames to Redis list, Celery worker's
AgentDataSource.next_chunk()BLPOP reads them ✅ - Inference loop runs on live agent data identically to direct SDR mode ✅
The only manual friction is the multi-step registration and URL construction — which these CLI changes eliminate.