Bug fixes:
- Bug A: GROK_API_KEY env mismatch — router expected GROK_API_KEY but only
XAI_API_KEY was present. Added GROK_API_KEY=${XAI_API_KEY} alias in compose.
- Bug B: 'grok' profile missing in router-config.node2.yml — added cloud_grok
profile (provider: grok, model: grok-2-1212). Sofiia now has
default_llm=cloud_grok with fallback_llm=local_default_coder.
- Bug C: Router silently defaulted to cloud DeepSeek when profile was unknown.
Now falls back to agent.fallback_llm or local_default_coder with WARNING log.
Hardcoded Ollama URL (172.18.0.1) replaced with config-driven base_url.
New service: Node Capabilities Service (NCS)
- services/node-capabilities/ — FastAPI microservice exposing live model
inventory from Ollama, Swapper, and llama-server.
- GET /capabilities — canonical JSON with served_models[] and inventory_only[]
- GET /capabilities/models — flat list of served models
- POST /capabilities/refresh — force cache refresh
- Cache TTL 15s, bound to 127.0.0.1:8099
- services/router/capabilities_client.py — async client with TTL cache
Artifacts:
- ops/node2_models_audit.md — 3-layer model view (served/disk/cloud)
- ops/node2_models_audit.yml — machine-readable audit
- ops/node2_capabilities_example.json — sample NCS output (14 served models)
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