VOXAgent
File: vox/agents/base.py
An agent is a self-contained execution unit with a unique identity, mounted
capabilities, and loaded roles. It is the "I" in the VOX system — every
decision, command, and message originates from or is addressed to an agent.
Agents are declarative: configuration lives in agent.yml, behavior in
roles/*.py, and I/O is capability-gated (no implicit filesystem magic).
Declaration (agent.yml)
The manifest schema is validated by AgentLoader.MANIFEST_SCHEMA:
name: "<agent_name>" # required, str
id: "<agent_uuid>" # required, str
master_id: "" # optional; empty = root agent
autostart: true # optional; start on orchestrator boot
conversational: true # optional; allow free-form LLM conversation
roles: ["chat"] # optional; explicit role allow-list
personality: # optional; consumed by roles
rules: |
You are a helpful assistant.
messages:
on_boot: "Ready."
rate_limit_max_calls: 30 # optional; events per rate-limit window
rate_limit_window: 60 # optional; window in seconds
Capabilities are not declared in agent.yml. They are derived from role
REQUIRES declarations (discovered by static AST analysis of the role files)
plus the agent's system capabilities (e.g. comm.gateway). Unknown manifest
fields produce warnings; wrong types are rejected.
Bootstrap Flow
Load agent.yml → validate schema, extract config
Load .env → optional per-agent environment overrides
Load roles → import roles/*.py, find VOXRole subclasses
Discover capabilities→ AST-scan REQUIRES in role files + system capabilities
Mount capabilities → bind each as a VOXBoundCapability proxy
Inject vault secrets → for SENSITIVE_PARAMS
Validate REQUIRES → missing capability → role disabled, agent DEGRADED
Ready → agent object exists (IDLE)
Boot (async) → cap.initialize() + cap.boot() on each, emit on_boot → ACTIVE
Hierarchy
Each agent has a master_id pointing to its parent. The orchestrator enforces
creation order: root first, then children.
describe() embeds direct subordinates recursively in the "subordinates"
field — each child's full describe() dict appears nested inside its parent.
This produces a clean tree: root agents at the top, with subordinates: [...]
containing their children, grandchildren, etc.
Key Members
| Member | Purpose |
|---|---|
self.id |
Agent UUID |
self.name |
Agent display name |
self.master_id |
Parent UUID (empty for root) |
self.capabilities |
{cap_id: VOXBoundCapability} — mounted capabilities (e.g. self.capabilities["ai.llm"]) |
self.roles |
{role_name: VOXRole} |
self.commands |
Set of all registered command names |
self.events |
Set of all registered event names |
self.orchestrator |
Reference to the runtime orchestrator (may be None) |
self.memory |
VOXAgentMemory — append-only forensic ledger |
self.store |
VOXAgentStore — operational asset storage |
self.get_safe_path(sub_dir, filename) |
Sandboxed path resolution (raises on escape) |
self.emit(event, **kwargs) |
Dispatch an event to registered role handlers |
self.boot() |
Transition to ACTIVE |
self.pause() / self.resume() / self.stop() / self.shutdown() |
Lifecycle operations |
Agents access subordinates via self.orchestrator.get_children(id). Command
discovery for delegation goes through get_command_map() (own commands) and
the orchestrator's command registry.
Note: there is no
cap_llm/cap_telegramattribute sugar and noself.messagingbus in the current API. Capabilities live in theself.capabilitiesdict; inter-agent traffic flows throughVOXMessageenvelopes,agent.emit(), andorchestrator.dispatch_inbound_message().
Outbound messaging
Roles send messages through the mounted comm.gateway capability with an
explicit channel and recipient:
await self.agent.capabilities["comm.gateway"].send_text(
"telegram", recipient_id, text # channel, recipient, text
)
Lifecycle States
VOX uses a nine-state machine (BOOTING, IDLE, ACTIVE, PAUSING,
PAUSED, RESUMING, STOPPING, STOPPED, FAILED) with validated
transitions. See Agent Lifecycle.
Degradation
An agent is flagged DEGRADED when:
- no active roles are loaded,
- a role's required capability is unavailable or missing secrets,
- a capability is missing required params (
None-defaulted param unset).
Degraded agents are tracked separately by the orchestrator and surfaced in the fleet snapshot.
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