pub struct Ring { /* private fields */ }Expand description
The Ring — the central coordinator for the Punch Agent Combat System.
Thread-safe by design: all collections use DashMap and all shared state
is behind Arc. Wrap the Ring itself in an Arc to share across tasks.
Implementations§
Source§impl Ring
impl Ring
Sourcepub fn new(
config: PunchConfig,
memory: Arc<MemorySubstrate>,
driver: Arc<dyn LlmDriver>,
) -> Self
pub fn new( config: PunchConfig, memory: Arc<MemorySubstrate>, driver: Arc<dyn LlmDriver>, ) -> Self
Create a new Ring.
The caller provides the already-initialised memory substrate, LLM driver, and configuration. The Ring will create its own event bus and scheduler internally.
Sourcepub fn with_quota_config(
config: PunchConfig,
memory: Arc<MemorySubstrate>,
driver: Arc<dyn LlmDriver>,
quota_config: QuotaConfig,
) -> Self
pub fn with_quota_config( config: PunchConfig, memory: Arc<MemorySubstrate>, driver: Arc<dyn LlmDriver>, quota_config: QuotaConfig, ) -> Self
Create a new Ring with a custom quota configuration.
Sourcepub fn memory(&self) -> &Arc<MemorySubstrate>
pub fn memory(&self) -> &Arc<MemorySubstrate>
Get a reference to the memory substrate.
Sourcepub fn config(&self) -> &PunchConfig
pub fn config(&self) -> &PunchConfig
Get a reference to the configuration.
Sourcepub fn background(&self) -> &BackgroundExecutor
pub fn background(&self) -> &BackgroundExecutor
Get a reference to the background executor.
Sourcepub fn workflow_engine(&self) -> &WorkflowEngine
pub fn workflow_engine(&self) -> &WorkflowEngine
Get a reference to the workflow engine.
Sourcepub fn metering(&self) -> &MeteringEngine
pub fn metering(&self) -> &MeteringEngine
Get a reference to the metering engine.
Sourcepub fn budget_enforcer(&self) -> &Arc<BudgetEnforcer>
pub fn budget_enforcer(&self) -> &Arc<BudgetEnforcer>
Get a reference to the budget enforcer.
Sourcepub fn trigger_engine(&self) -> &TriggerEngine
pub fn trigger_engine(&self) -> &TriggerEngine
Get a reference to the trigger engine.
Sourcepub fn metrics(&self) -> &Arc<MetricsRegistry>
pub fn metrics(&self) -> &Arc<MetricsRegistry>
Get a reference to the metrics registry.
Sourcepub fn tenant_registry(&self) -> &TenantRegistry
pub fn tenant_registry(&self) -> &TenantRegistry
Get a reference to the tenant registry.
Sourcepub fn marketplace(&self) -> &SkillMarketplace
pub fn marketplace(&self) -> &SkillMarketplace
Access the skill marketplace.
Sourcepub fn mcp_clients(&self) -> &Arc<DashMap<String, Arc<McpClient>>>
pub fn mcp_clients(&self) -> &Arc<DashMap<String, Arc<McpClient>>>
Access the active MCP clients.
Sourcepub async fn spawn_mcp_servers(&self)
pub async fn spawn_mcp_servers(&self)
Spawn and initialize all MCP servers defined in the configuration.
Each server is started as a subprocess, initialized via JSON-RPC 2.0 handshake, and its tools are discovered. Servers that fail to start are logged and skipped — they don’t block the Ring from operating.
Sourcepub async fn shutdown_mcp_servers(&self)
pub async fn shutdown_mcp_servers(&self)
Shut down all active MCP servers gracefully.
Sourcepub async fn mcp_tools(&self) -> Vec<ToolDefinition>
pub async fn mcp_tools(&self) -> Vec<ToolDefinition>
Collect tool definitions from all active MCP servers.
Sourcepub async fn spawn_fighter_for_tenant(
&self,
tenant_id: &TenantId,
manifest: FighterManifest,
) -> PunchResult<FighterId>
pub async fn spawn_fighter_for_tenant( &self, tenant_id: &TenantId, manifest: FighterManifest, ) -> PunchResult<FighterId>
Spawn a fighter scoped to a tenant, enforcing quota limits.
Returns an error if the tenant is suspended or the fighter quota is exceeded.
Sourcepub fn list_fighters_for_tenant(
&self,
tenant_id: &TenantId,
) -> Vec<(FighterId, FighterManifest, FighterStatus)>
pub fn list_fighters_for_tenant( &self, tenant_id: &TenantId, ) -> Vec<(FighterId, FighterManifest, FighterStatus)>
List fighters that belong to a specific tenant.
Sourcepub fn kill_fighter_for_tenant(
&self,
fighter_id: &FighterId,
tenant_id: &TenantId,
) -> PunchResult<()>
pub fn kill_fighter_for_tenant( &self, fighter_id: &FighterId, tenant_id: &TenantId, ) -> PunchResult<()>
Kill a fighter, validating that the caller tenant owns it.
Returns an error if the fighter doesn’t belong to the given tenant.
Sourcepub fn check_tenant_tool_access(
&self,
tenant_id: &TenantId,
tool_name: &str,
) -> bool
pub fn check_tenant_tool_access( &self, tenant_id: &TenantId, tool_name: &str, ) -> bool
Check whether a tenant’s tool access is allowed for the given tool name.
Returns true if the tenant has no tool restrictions (empty list) or
the tool is in the allowed list.
Sourcepub fn register_trigger(&self, trigger: Trigger) -> TriggerId
pub fn register_trigger(&self, trigger: Trigger) -> TriggerId
Register a trigger with the engine.
Sourcepub fn remove_trigger(&self, id: &TriggerId)
pub fn remove_trigger(&self, id: &TriggerId)
Remove a trigger by ID.
Sourcepub fn list_triggers(&self) -> Vec<(TriggerId, TriggerSummary)>
pub fn list_triggers(&self) -> Vec<(TriggerId, TriggerSummary)>
List all triggers with summary information.
Sourcepub async fn spawn_fighter(&self, manifest: FighterManifest) -> FighterId
pub async fn spawn_fighter(&self, manifest: FighterManifest) -> FighterId
Spawn a new fighter from a manifest.
Returns the newly-assigned FighterId. The fighter starts in
FighterStatus::Idle and is persisted to the memory substrate.
Sourcepub async fn ensure_creed(&self, fighter_name: &str, manifest: &FighterManifest)
pub async fn ensure_creed(&self, fighter_name: &str, manifest: &FighterManifest)
Create a default creed for a fighter if none exists. The default creed includes self-awareness from the manifest.
Sourcepub async fn send_message(
&self,
fighter_id: &FighterId,
message: String,
) -> PunchResult<FighterLoopResult>
pub async fn send_message( &self, fighter_id: &FighterId, message: String, ) -> PunchResult<FighterLoopResult>
Send a user message to a fighter and run the agent loop (without coordinator).
Convenience wrapper around [send_message_with_coordinator] that passes
None, meaning the fighter will not have access to inter-agent tools.
Sourcepub async fn send_message_with_coordinator(
&self,
fighter_id: &FighterId,
message: String,
coordinator: Option<Arc<dyn AgentCoordinator>>,
content_parts: Vec<ContentPart>,
) -> PunchResult<FighterLoopResult>
pub async fn send_message_with_coordinator( &self, fighter_id: &FighterId, message: String, coordinator: Option<Arc<dyn AgentCoordinator>>, content_parts: Vec<ContentPart>, ) -> PunchResult<FighterLoopResult>
Send a user message to a fighter and run the agent loop.
This creates (or reuses) a bout for the fighter, checks quotas, then
delegates to run_fighter_loop. Usage is recorded through the
metering engine after a successful completion.
If coordinator is provided, the fighter can use inter-agent tools
(agent_spawn, agent_message, agent_list).
Sourcepub fn heartbeat_scheduler(&self) -> &HeartbeatScheduler
pub fn heartbeat_scheduler(&self) -> &HeartbeatScheduler
Access the heartbeat scheduler (e.g. for refresh after heartbeat config changes).
Sourcepub fn set_channel_notifier(&self, notifier: Arc<dyn ChannelNotifier>)
pub fn set_channel_notifier(&self, notifier: Arc<dyn ChannelNotifier>)
Set the channel notifier for proactive heartbeat notifications.
Should be called once during API server setup after the channel bridge is constructed. Existing heartbeat monitors will pick up the notifier on their next refresh cycle.
Sourcepub fn kill_fighter(&self, fighter_id: &FighterId)
pub fn kill_fighter(&self, fighter_id: &FighterId)
Kill (remove) a fighter.
Sourcepub fn list_fighters(&self) -> Vec<(FighterId, FighterManifest, FighterStatus)>
pub fn list_fighters(&self) -> Vec<(FighterId, FighterManifest, FighterStatus)>
List all fighters with their current status.
Sourcepub fn get_fighter(&self, fighter_id: &FighterId) -> Option<FighterEntry>
pub fn get_fighter(&self, fighter_id: &FighterId) -> Option<FighterEntry>
Get a snapshot of a single fighter’s entry.
Sourcepub fn register_gorilla(&self, manifest: GorillaManifest) -> GorillaId
pub fn register_gorilla(&self, manifest: GorillaManifest) -> GorillaId
Register a gorilla with the Ring.
Returns the newly-assigned GorillaId. The gorilla starts in
GorillaStatus::Caged.
Sourcepub async fn unleash_gorilla(&self, gorilla_id: &GorillaId) -> PunchResult<()>
pub async fn unleash_gorilla(&self, gorilla_id: &GorillaId) -> PunchResult<()>
Unleash (start) a gorilla’s background task.
This uses the BackgroundExecutor to spawn the gorilla’s autonomous
loop, which will run the fighter loop on the gorilla’s schedule.
Sourcepub async fn cage_gorilla(&self, gorilla_id: &GorillaId) -> PunchResult<()>
pub async fn cage_gorilla(&self, gorilla_id: &GorillaId) -> PunchResult<()>
Cage (stop) a gorilla’s background task.
Sourcepub async fn list_gorillas(
&self,
) -> Vec<(GorillaId, GorillaManifest, GorillaStatus, GorillaMetrics)>
pub async fn list_gorillas( &self, ) -> Vec<(GorillaId, GorillaManifest, GorillaStatus, GorillaMetrics)>
List all gorillas with their current status and metrics.
Sourcepub async fn get_gorilla_manifest(
&self,
gorilla_id: &GorillaId,
) -> Option<GorillaManifest>
pub async fn get_gorilla_manifest( &self, gorilla_id: &GorillaId, ) -> Option<GorillaManifest>
Get a gorilla’s manifest by ID.
Sourcepub async fn find_gorilla_by_name(&self, name: &str) -> Option<GorillaId>
pub async fn find_gorilla_by_name(&self, name: &str) -> Option<GorillaId>
Find a gorilla ID by name (case-insensitive).
Sourcepub async fn run_gorilla_tick(
&self,
gorilla_id: &GorillaId,
) -> PunchResult<FighterLoopResult>
pub async fn run_gorilla_tick( &self, gorilla_id: &GorillaId, ) -> PunchResult<FighterLoopResult>
Run a single autonomous tick for a gorilla (for testing/debugging).
This executes the gorilla’s autonomous prompt once, without starting the background scheduler. Useful for verifying configuration.
Sourcepub fn driver(&self) -> &Arc<dyn LlmDriver>
pub fn driver(&self) -> &Arc<dyn LlmDriver>
Get the LLM driver (useful for CLI commands that need to run ticks directly).
Sourcepub async fn fighter_to_fighter(
&self,
source_id: &FighterId,
target_id: &FighterId,
message: String,
) -> PunchResult<FighterLoopResult>
pub async fn fighter_to_fighter( &self, source_id: &FighterId, target_id: &FighterId, message: String, ) -> PunchResult<FighterLoopResult>
Send a message from one fighter to another.
The source fighter’s message becomes the target fighter’s input, enriched with source context so the target knows who is speaking. The target processes it through its own fighter loop (with its own creed) and the response is returned.
Sourcepub fn find_fighter_by_name_sync(
&self,
name: &str,
) -> Option<(FighterId, FighterManifest)>
pub fn find_fighter_by_name_sync( &self, name: &str, ) -> Option<(FighterId, FighterManifest)>
Find a fighter by name (case-insensitive).
Returns the fighter ID and manifest if found.
Sourcepub async fn update_fighter_relationships(
&self,
fighter_a_name: &str,
fighter_b_name: &str,
)
pub async fn update_fighter_relationships( &self, fighter_a_name: &str, fighter_b_name: &str, )
Update relationship tracking in both fighters’ creeds after inter-agent communication.
Loads both creeds, adds or updates the peer relationship entry (incrementing interaction_count), and saves them back.
Sourcepub fn troop_manager(&self) -> &TroopManager
pub fn troop_manager(&self) -> &TroopManager
Get a reference to the troop manager.
Sourcepub fn swarm_coordinator(&self) -> &SwarmCoordinator
pub fn swarm_coordinator(&self) -> &SwarmCoordinator
Get a reference to the swarm coordinator.
Sourcepub fn message_router(&self) -> &MessageRouter
pub fn message_router(&self) -> &MessageRouter
Get a reference to the message router.
Sourcepub fn form_troop(
&self,
name: String,
leader: FighterId,
members: Vec<FighterId>,
strategy: CoordinationStrategy,
) -> PunchResult<TroopId>
pub fn form_troop( &self, name: String, leader: FighterId, members: Vec<FighterId>, strategy: CoordinationStrategy, ) -> PunchResult<TroopId>
Form a new troop with a leader and initial members.
Sourcepub fn disband_troop(&self, troop_id: &TroopId) -> PunchResult<()>
pub fn disband_troop(&self, troop_id: &TroopId) -> PunchResult<()>
Disband (dissolve) a troop.
Sourcepub fn assign_troop_task(
&self,
troop_id: &TroopId,
task_description: &str,
) -> PunchResult<Vec<FighterId>>
pub fn assign_troop_task( &self, troop_id: &TroopId, task_description: &str, ) -> PunchResult<Vec<FighterId>>
Assign a task to a troop, returning the fighters that should handle it.
Sourcepub async fn assign_troop_task_async(
&self,
troop_id: &TroopId,
task: &str,
) -> PunchResult<TaskAssignmentResult>
pub async fn assign_troop_task_async( &self, troop_id: &TroopId, task: &str, ) -> PunchResult<TaskAssignmentResult>
Assign a task to a troop asynchronously, returning full results including responses from fighters.
Sourcepub fn get_troop_status(&self, troop_id: &TroopId) -> Option<Troop>
pub fn get_troop_status(&self, troop_id: &TroopId) -> Option<Troop>
Get the current status of a troop.
Sourcepub fn list_troops(&self) -> Vec<Troop>
pub fn list_troops(&self) -> Vec<Troop>
List all troops.
Sourcepub fn recruit_to_troop(
&self,
troop_id: &TroopId,
fighter_id: FighterId,
) -> PunchResult<()>
pub fn recruit_to_troop( &self, troop_id: &TroopId, fighter_id: FighterId, ) -> PunchResult<()>
Recruit a fighter into a troop.
Sourcepub fn dismiss_from_troop(
&self,
troop_id: &TroopId,
fighter_id: &FighterId,
) -> PunchResult<()>
pub fn dismiss_from_troop( &self, troop_id: &TroopId, fighter_id: &FighterId, ) -> PunchResult<()>
Dismiss a fighter from a troop.
Sourcepub fn kill_fighter_safe(&self, fighter_id: &FighterId)
pub fn kill_fighter_safe(&self, fighter_id: &FighterId)
Kill a fighter, warning if they’re in a troop.
Unlike [kill_fighter], this checks troop membership and dismisses
the fighter from all troops before killing them.
Sourcepub fn register_workflow(&self, workflow: Workflow) -> WorkflowId
pub fn register_workflow(&self, workflow: Workflow) -> WorkflowId
Register a workflow with the engine.
Sourcepub async fn execute_workflow(
&self,
workflow_id: &WorkflowId,
input: String,
) -> PunchResult<WorkflowRunId>
pub async fn execute_workflow( &self, workflow_id: &WorkflowId, input: String, ) -> PunchResult<WorkflowRunId>
Execute a workflow by ID with the given input.
Trait Implementations§
Source§impl AgentCoordinator for Ring
impl AgentCoordinator for Ring
Source§fn spawn_fighter<'life0, 'async_trait>(
&'life0 self,
manifest: FighterManifest,
) -> Pin<Box<dyn Future<Output = PunchResult<FighterId>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn spawn_fighter<'life0, 'async_trait>(
&'life0 self,
manifest: FighterManifest,
) -> Pin<Box<dyn Future<Output = PunchResult<FighterId>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Source§fn send_message_to_agent<'life0, 'life1, 'async_trait>(
&'life0 self,
target: &'life1 FighterId,
message: String,
) -> Pin<Box<dyn Future<Output = PunchResult<AgentMessageResult>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn send_message_to_agent<'life0, 'life1, 'async_trait>(
&'life0 self,
target: &'life1 FighterId,
message: String,
) -> Pin<Box<dyn Future<Output = PunchResult<AgentMessageResult>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn find_fighter_by_name<'life0, 'life1, 'async_trait>(
&'life0 self,
name: &'life1 str,
) -> Pin<Box<dyn Future<Output = PunchResult<Option<FighterId>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn find_fighter_by_name<'life0, 'life1, 'async_trait>(
&'life0 self,
name: &'life1 str,
) -> Pin<Box<dyn Future<Output = PunchResult<Option<FighterId>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn list_fighters<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = PunchResult<Vec<AgentInfo>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn list_fighters<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = PunchResult<Vec<AgentInfo>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Auto Trait Implementations§
impl !Freeze for Ring
impl !RefUnwindSafe for Ring
impl Send for Ring
impl Sync for Ring
impl Unpin for Ring
impl UnsafeUnpin for Ring
impl !UnwindSafe for Ring
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more