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
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.decisionevents - Agent Invocation: Creates and publishes
router.invoke.agentmessages - 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:
- Only process
decision == "allow" - Ensure
target_agent_idis present - Create
AgentInvocationwith channel context - 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:
- Is router subscribed to NATS?
- Is agent-filter publishing decisions?
- Are decisions "allow"?
- 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