Files
microdao-daarion/services/agent-filter
Apple 744c149300
Some checks failed
Build and Deploy Docs / build-and-deploy (push) Has been cancelled
Add automated session logging system
- Created logs/ structure (sessions, operations, incidents)
- Added session-start/log/end scripts
- Installed Git hooks for auto-logging commits/pushes
- Added shell integration for zsh
- Created CHANGELOG.md
- Documented today's session (2026-01-10)
2026-01-10 04:53:17 -08:00
..
2026-01-10 04:53:17 -08:00
2026-01-10 04:53:17 -08:00
2026-01-10 04:53:17 -08:00
2026-01-10 04:53:17 -08:00
2026-01-10 04:53:17 -08:00
2026-01-10 04:53:17 -08:00

Agent Filter Service

Security & routing layer for DAARION agents in Messenger

Purpose

Agent Filter decides when and which agents should respond to messages based on configurable rules.

Features

  • Loop Prevention: Blocks agent→agent message loops
  • Quiet Hours: Modifies agent behavior during specified times (23:0007:00)
  • Agent Mapping: Maps microDAOs to default agents
  • Channel Permissions: Respects allowed/disabled agents per channel
  • NATS Integration: Subscribes to message events, publishes filter decisions

Architecture

messaging.message.created (NATS)
    ↓
agent-filter: Apply Rules
    ↓
agent.filter.decision (NATS)

Rules

1. Loop Prevention

  • Rule: Block messages from agents
  • Reason: Prevent infinite agent→agent conversations

2. Quiet Hours

  • Time: 23:00 07:00 (configurable in config.yaml)
  • Effect: Adds rewrite prompt for concise responses
  • Purpose: Reduce agent activity during off-hours

3. Agent Mapping

  • Default Agents: Defined per microDAO in config.yaml
  • Channel Override: Channels can specify allowed_agents
  • Fallback: If no agent found, deny

4. Disabled Agents

  • Check: Ensures target agent is not in disabled_agents list
  • Source: From channel context

API

Health Check

GET /health

Response:
{
  "status": "ok",
  "service": "agent-filter",
  "version": "1.0.0",
  "nats_connected": true
}

Test Filtering (Manual)

POST /internal/agent-filter/test
Content-Type: application/json

{
  "channel_id": "test-channel-id",
  "matrix_event_id": "$event123:matrix.daarion.city",
  "sender_id": "user:93",
  "sender_type": "human",
  "microdao_id": "microdao:daarion",
  "created_at": "2025-11-24T12:00:00Z"
}

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

Configuration

File: config.yaml

nats:
  servers: ["nats://nats:4222"]
  messaging_subject: "messaging.message.created"
  decision_subject: "agent.filter.decision"

rules:
  quiet_hours:
    start: "23:00"
    end: "07:00"
  
  default_agents:
    "microdao:daarion": "agent:sofia"
    "microdao:7": "agent:sofia"

Environment Variables

  • MESSAGING_SERVICE_URL: URL of messaging-service (default: http://messaging-service:7004)
  • 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 7005

Test

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

# Test filtering
curl -X POST http://localhost:7005/internal/agent-filter/test \
  -H "Content-Type: application/json" \
  -d '{
    "channel_id": "test-123",
    "matrix_event_id": "$test:matrix.daarion.city",
    "sender_id": "user:1",
    "sender_type": "human",
    "microdao_id": "microdao:daarion",
    "created_at": "2025-11-24T12:00:00Z"
  }'

Docker

Build

docker build -t daarion/agent-filter:latest .

Run

docker run -p 7005:7005 \
  -e MESSAGING_SERVICE_URL=http://messaging-service:7004 \
  -e NATS_URL=nats://nats:4222 \
  daarion/agent-filter:latest

NATS Events

Subscribes To

  • Subject: messaging.message.created
  • Payload: MessageCreatedEvent
{
  "channel_id": "uuid",
  "message_id": "uuid",
  "matrix_event_id": "$event:server",
  "sender_id": "user:X or agent:Y",
  "sender_type": "human | agent",
  "microdao_id": "microdao:X",
  "created_at": "2025-11-24T12:00:00Z"
}

Publishes To

  • Subject: agent.filter.decision
  • Payload: FilterDecision
{
  "channel_id": "uuid",
  "message_id": "uuid",
  "matrix_event_id": "$event:server",
  "microdao_id": "microdao:X",
  "decision": "allow | deny | modify",
  "target_agent_id": "agent:sofia",
  "rewrite_prompt": "Optional prompt modification"
}

Development

Adding New Rules

Edit rules.py:

def decide(self, event: MessageCreatedEvent, ctx: FilterContext) -> FilterDecision:
    # Add your rule here
    if some_condition:
        return FilterDecision(
            decision="deny",
            # ... other fields
        )
    
    # Continue with existing rules
    ...

Testing Rules

Use the test endpoint:

curl -X POST http://localhost:7005/internal/agent-filter/test \
  -H "Content-Type: application/json" \
  -d @test_event.json

Monitoring

Logs

# Docker
docker logs -f agent-filter

# Look for:
# ✅ Connected to NATS
# ✅ Subscribed to messaging.message.created
# 📨 Received message.created event
# 🎯 Decision: allow/deny/modify
# ✅ Published decision to NATS

Metrics (Future)

  • Total messages processed
  • Decisions per type (allow/deny/modify)
  • Average processing time
  • NATS connection status

Troubleshooting

NATS Not Connected

⚠️ NATS not available: [error]
⚠️ Running in test mode (HTTP only)

Solution: Check NATS is running and accessible:

docker ps | grep nats
docker logs nats

No Decisions Published

Check:

  1. Is messaging-service publishing events?
  2. Is channel context endpoint working?
  3. Are rules correctly configured?
# Test channel context
curl http://localhost:7004/internal/messaging/channels/{channel_id}/context

Always Denying

Common causes:

  1. Sender is agent (loop prevention)
  2. No target agent found
  3. Target agent is disabled
  4. Channel context not accessible

Debug: Use test endpoint and check logs

Future Enhancements

  • Keyword-based triggers ("@sofia", "@assistant")
  • Per-user permissions
  • Rate limiting per agent
  • Sentiment analysis for filtering
  • ML-based spam detection
  • Custom rule scripting (Lua/Python)

Version

Current: 1.0.0
Status: Production Ready
Last Updated: 2025-11-24