feat(matrix-bridge-dagi): add egress, audit integration, fix router endpoint (PR-M1.4)

Closes the full Matrix ↔ DAGI loop:

Egress:
- invoke Router POST /v1/agents/{agent_id}/infer (field: prompt, response: response)
- send_text() reply to Matrix room with idempotent txn_id = make_txn_id(room_id, event_id)
- empty reply → skip send (no spam)
- reply truncated to 4000 chars if needed

Audit (via sofiia-console POST /api/audit/internal):
- matrix.message.received (on ingress)
- matrix.agent.replied (on successful reply)
- matrix.error (on router/send failure, with error_code)
- fire-and-forget: audit failures never crash the loop

Router URL fix:
- DAGI_GATEWAY_URL now points to dagi-router-node1:8000 (not gateway:9300)
- Session ID: stable per room — matrix:{room_localpart} (memory context)

9 tests: invoke endpoint, fallback fields, audit write, full cycle,
dedupe, empty reply skip, metric callbacks

Made-with: Cursor
This commit is contained in:
Apple
2026-03-03 08:06:49 -08:00
parent 8d564fbbe5
commit cad3663508
4 changed files with 540 additions and 307 deletions

View File

@@ -31,8 +31,9 @@ services:
# Create the room manually, then paste the room_id here
- SOFIIA_ROOM_ID=${SOFIIA_ROOM_ID:-}
# ── DAGI backend ─────────────────────────────────────────────────────
- DAGI_GATEWAY_URL=http://dagi-gateway-node1:9300
# ── DAGI backend — Router for /v1/agents/{id}/infer ─────────────────
# Router internal port 8000 on dagi-network (ext port 9102 on host)
- DAGI_GATEWAY_URL=http://dagi-router-node1:8000
- DEFAULT_NODE_ID=NODA1
# ── Sofiia Console (audit write) ─────────────────────────────────────