VOXRole
File: vox/roles/base.py
A role is a modular behavioral unit attached to an agent. It handles events
and exposes commands. Every role is a Python file in agent_dir/roles/
containing a VOXRole subclass (one role class per module). Roles declare
which capabilities they need; the framework discovers this statically via AST
analysis of REQUIRES and mounts those capabilities.
Command vs Event
@command("run_analysis", description="...")
async def run_analysis(self, ...):
...
self.on("inbound_message")(self._receive_message)
self.on("on_boot")(self._greet)
| Type | Registered via | Shows in get_commands() |
Dispatched by |
|---|---|---|---|
| Command | @command() decorator |
Yes | NLU classifier or slash command |
| Event | self.on(name) |
No | agent.emit(name, ...) |
Contract
| Member | Required? | Purpose |
|---|---|---|
REQUIRES |
No | set[str] — capability IDs this role needs (default set()) |
PREFERRED_MODEL |
No | str | None — preferred LLM model for this role |
@command() |
No | Decorator for public command handlers |
self.on() |
No | Register event handlers |
self.agent |
Inherited | Weakref to the owning agent (raises AgentHostDeadError if gone) |
handle_event(event, **kwargs) |
Inherited | Dispatch an event to a registered handler |
get_commands() |
Inherited | {command_name: CommandInfo} |
CommandInfo
@dataclass
class CommandInfo:
handler: Callable
description: str = ""
params: dict[str, str] = field(default_factory=dict)
sample_prompts: list | None = None
Registered by the @command(name, description, **metadata) decorator. The NLU
classifier renders descriptions and sample prompts inline to guide intent
detection.
Capability dependencies
Roles declare capability needs via REQUIRES; the ASTAgentAnalyzer scans
role files statically (top-level REQUIRES = {...} sets) so capabilities are
mounted before roles run. Roles whose required capability is unavailable or
whose SENSITIVE_PARAMS cannot be satisfied from the vault are disabled at
boot, and the agent is flagged DEGRADED.
Chat role and outbound messaging
The chat role (a conventional chat.py in agent role dirs) acts as the NLU
router and message sink: it registers inbound_message, on_boot, and
send_message events. Other roles typically emit send_message events rather
than touching channel adapters directly; outbound delivery goes through the
mounted comm.gateway capability:
await self.agent.capabilities["comm.gateway"].send_text(
"telegram", recipient_id, text # channel, recipient, text
)
The recipient is a per-call argument — the channel adapters hold no hardcoded user ID. Roles never access channels directly — I/O stays capability-gated.
Overview
- Home
- Versioning
- Architecture Overview
- Building Blocks
Agent Model
- VOXAgent
- Agent Lifecycle
- VOXRole
- Creating an Agent
Capabilities
- VOXCapability
- Capabilities Reference
- Capability Contract
- Comm Gateway
- WhatsApp Setup
Messaging
- VOXMessage
- Messaging Contract
- Hierarchical Messaging Contract
- The War Room
Orchestrator & Control Plane
- VOXOrchestrator
- Orchestrator & Control Plane
- VOXApiServer
Persistence & Forensics
- Segmented Persistence & Forensic Traceability
Security & Governance
- Security Architecture
- Core Ontology (legacy)
- Capability Specification (legacy)
Status: v0.5.4