Skip to content
AGNT

Backend · Core modules

Agent registry.

Three agent types register on ClawPulse: consumer agents (one per human user), venue agents (one per onboarded venue), and the platform bridge agent (one per deployment). This module defines their DNA, writes them to ClawPulse, and reconciles drift. File: agnt-backend/app/core/agent_registry.py.

Agent ID format

Every agent ID follows a strict prefix convention so the type is self-describing on the wire:

TypeID formatExample
Consumerconsumer-{user_uuid}consumer-7a4b2c9f-...
Venuevenue-{venue_uuid}venue-b9e1d3a8-...
Platform bridgeCLAWPULSE_PLATFORM_AGENT_ID env varagnt-bridge

Consumer agents

Every user gets one consumer agent. register_consumer_agent is called from the user registration flow as a background task. It builds the DNA, posts it to ClawPulse via cp.register_agent_profile, and writes users.cp_agent_id on success.

pythonapp/core/agent_registry.py — _consumer_dna
def _consumer_dna(user: User) -> dict:
    return {
        "capabilities": {
            "streams": ["news", "weather", "social"],
            "tools": ["venue_search", "create_booking", "set_reminder"],
            "role": "consumer_concierge",
        },
        "preferences": {
            "subjects": ["news.bali.>", "weather.bali.>", "action.>"],
            "minImportance": 0.4,
        },
        "behavioral": {
            "autoReconnect": True,
            "cursorPersist": True,
            "city": user.city or "Bali",
            "language": user.language or "en",
        },
    }

Venue agents

Venue agents are registered when a VenueClient completes onboarding. register_venue_agent takes both the venue_id and the venue_client_id, optionally enforces the expected owner, and triggers a sync of the per-venue inbox loop when registration succeeds.

pythonapp/core/agent_registry.py — _venue_dna
def _venue_dna(*, venue_name: str, venue_category: str | None, venue_area: str | None) -> dict:
    return {
        "capabilities": {
            "streams": ["watcher", "action"],
            "tools": ["venue_create_booking", "venue_send_menu", "escalate_to_human"],
            "role": "venue_concierge",
            "venue_name": venue_name,
            "venue_category": venue_category or "",
            "venue_area": venue_area or "",
        },
        "preferences": {
            "subjects": ["action.>", "watcher.>"],
            "minImportance": 0.5,
        },
        "behavioral": {
            "autoReconnect": True,
            "inboxPollEnabled": True,
        },
    }

Inbox loop sync

After a successful venue registration the function imports sync_venue_inbox_loops_now from app.core.background_runtimeand awaits it. This is what makes the new venue agent's inbox actually get polled in production.

Platform bridge agent

Exactly one platform agent exists per deployment. Its ID comes from the CLAWPULSE_PLATFORM_AGENT_ID env var. The ensure_platform_agent_registered function is called from the FastAPI lifespan hook so traffic never flows before the bridge is known to ClawPulse.

pythonapp/core/agent_registry.py — _platform_dna
def _platform_dna() -> dict:
    return {
        "capabilities": {
            "streams": ["booking", "status", "action"],
            "tools": ["send_message", "drain_inbox", "ack_messages"],
            "role": "booking_bridge",
        },
        "preferences": {
            "subjects": ["booking.>", "status.a2a.>", "action.>"],
            "minImportance": 0.5,
        },
        "behavioral": {
            "autoReconnect": True,
            "cursorPersist": True,
            "idempotencyRequired": True,
        },
    }

Reconciliation

Deploys can drift: a venue may be marked onboarded_at in the database but never actually have a cp_agent_id because the original registration failed. reconcile_onboarded_venue_agents is the safety net: it walks the table, re-registers any venue client with a NULL cp_agent_id, and patches the row on success.

The function returns a summary dict with found, registered, and failed counts. Call it manually after a ClawPulse outage, or schedule it as a recurring health job if drift becomes common.

Failure mode

Every function in this module is wrapped in try / except and logs via logger.exception on failure. If ClawPulse is not configured at all (CLAWPULSE_API_KEY empty), registration skips with a warning and returns False. Callers check the return value before treating the agent as registered.

Related