Files
microdao-daarion/services/router
Apple 7b8499dd8a node2: P0 vision restore + P1 security hardening + node-specific router config
P0 — Vision:
- swapper_config_node2.yaml: add llava-13b as vision model (vision:true)
  /vision/models now returns non-empty list; inference verified ~3.5s
- ollama.url fixed to host.docker.internal:11434 (was localhost, broken in Docker)

P1 — Security:
- Remove NODES_NODA1_SSH_PASSWORD from .env and docker-compose.node2-sofiia.yml
- SSH ED25519 key generated, authorized on NODA1, mounted as /run/secrets/noda1_ssh_key
- sofiia-console reads key via NODES_NODA1_SSH_PRIVATE_KEY env var
- secrets/noda1_id_ed25519 added to .gitignore

P1 — Router:
- services/router/router-config.node2.yml: new node2-specific config
  replaces all 172.17.0.1:11434 → host.docker.internal:11434
- docker-compose.node2-sofiia.yml: mount router-config.node2.yml (not root config)

P1 — Ports:
- router (9102), swapper (8890), sofiia-console (8002): bind to 127.0.0.1
- gateway (9300): keep 0.0.0.0 (Telegram webhook requires public access)

Artifacts:
- ops/patch_node2_P0P1_20260227.md — change log
- ops/validation_node2_P0P1_20260227.md — all checks PASS
- ops/node2.env.example — safe env template (no secrets)
- ops/security_hardening_node2.md — SSH key migration guide + firewall
- ops/node2_models_pull.sh — model pull script for P0/P1

Made-with: Cursor
2026-02-27 01:27:38 -08:00
..
2026-01-10 04:53:17 -08:00

DAGI Router Service

Routes events to appropriate agents and services

Purpose

DAGI Router is the central orchestrator that routes various events (filter decisions, direct invocations, scheduled jobs) to agent-runtime for execution.

Features

  • Filter Decision Routing: Processes agent.filter.decision events
  • Agent Invocation: Creates and publishes router.invoke.agent messages
  • Configurable: YAML-based routing configuration
  • Test Mode: HTTP endpoint for testing routing logic

Architecture

agent.filter.decision (NATS)
    ↓
router: Create AgentInvocation
    ↓
router.invoke.agent (NATS)
    ↓
agent-runtime (subscribes)

Routing Rules

Messaging Inbound (Phase 2)

Input: agent.filter.decision (from agent-filter)
Output: router.invoke.agent (to agent-runtime)

Logic:

  1. Only process decision == "allow"
  2. Ensure target_agent_id is present
  3. Create AgentInvocation with channel context
  4. Publish to NATS

Future Rules (Phase 3+)

  • Direct agent invocations (API calls)
  • Scheduled/cron invocations
  • Webhook-triggered invocations
  • Agent-to-agent communication

API

Health Check

GET /health

Response:
{
  "status": "ok",
  "service": "router",
  "version": "1.0.0",
  "nats_connected": true,
  "messaging_inbound_enabled": true
}

Test Routing (Manual)

POST /internal/router/test-messaging
Content-Type: application/json

{
  "channel_id": "test-channel",
  "matrix_event_id": "$event123",
  "microdao_id": "microdao:daarion",
  "decision": "allow",
  "target_agent_id": "agent:sofia"
}

Response:
{
  "agent_id": "agent:sofia",
  "entrypoint": "channel_message",
  "payload": {
    "channel_id": "test-channel",
    "matrix_event_id": "$event123",
    "microdao_id": "microdao:daarion",
    "rewrite_prompt": null
  }
}

Configuration

File: router_config.yaml

messaging_inbound:
  enabled: true
  source_subject: "agent.filter.decision"
  target_subject: "router.invoke.agent"

Environment Variables

  • NATS_URL: NATS server URL (default: nats://nats:4222)

Running Locally

Install Dependencies

pip install -r requirements.txt

Run Service

uvicorn main:app --reload --port 8000

Test

# Health check
curl http://localhost:8000/health

# Test routing
curl -X POST http://localhost:8000/internal/router/test-messaging \
  -H "Content-Type: application/json" \
  -d '{
    "channel_id": "test-123",
    "matrix_event_id": "$test",
    "microdao_id": "microdao:daarion",
    "decision": "allow",
    "target_agent_id": "agent:sofia"
  }'

Docker

Build

docker build -t daarion/router:latest .

Run

docker run -p 8000:8000 \
  -e NATS_URL=nats://nats:4222 \
  daarion/router:latest

NATS Events

Subscribes To

  • Subject: agent.filter.decision
  • Payload: FilterDecision

Publishes To

  • Subject: router.invoke.agent
  • Payload: AgentInvocation

Monitoring

Logs

docker logs -f router

# Look for:
# ✅ Connected to NATS
# ✅ Subscribed to agent.filter.decision
# 🔀 Processing filter decision
# ✅ Decision: allow
# 🚀 Created invocation for agent:sofia
# ✅ Published invocation

Troubleshooting

Not Routing Messages

Check:

  1. Is router subscribed to NATS?
  2. Is agent-filter publishing decisions?
  3. Are decisions "allow"?
  4. Is target_agent_id present?
# Check NATS subscription
docker exec -it router cat /app/router_config.yaml

# Test routing logic
curl -X POST http://localhost:8000/internal/router/test-messaging \
  -d @test_decision.json

Future Enhancements

  • Multiple routing strategies
  • Agent load balancing
  • Priority queues
  • Rate limiting per agent
  • Retry logic
  • Dead letter queue
  • Routing analytics

Version

Current: 1.0.0
Status: Production Ready (Phase 2)
Last Updated: 2025-11-24