Skip to main content

AgentRegistry

Struct AgentRegistry 

Source
pub struct AgentRegistry { /* private fields */ }
Expand description

Agent registry with CCS alias and OpenCode dynamic provider/model support.

CCS aliases are eagerly resolved and registered as regular agents when set via set_ccs_aliases(). This allows get() to work uniformly for both regular agents and CCS aliases.

OpenCode provider/model combinations are resolved on-the-fly using the opencode/ prefix.

Implementations§

Source§

impl AgentRegistry

Source

pub fn new() -> Result<Self, AgentConfigError>

Create a new registry with default agents.

Source

pub fn set_opencode_catalog(&mut self, catalog: ApiCatalog)

Set the OpenCode API catalog for dynamic provider/model resolution.

This enables resolution of opencode/provider/model agent references.

Source

pub fn set_ccs_aliases( &mut self, aliases: &HashMap<String, CcsAliasConfig>, defaults: CcsConfig, )

Set CCS aliases for the registry.

This eagerly registers CCS aliases as agents so they can be resolved with resolve_config().

Source

pub fn register(&mut self, name: &str, config: AgentConfig)

Register a new agent.

Source

pub fn resolve_config(&self, name: &str) -> Option<AgentConfig>

Resolve an agent’s configuration, including on-the-fly CCS and OpenCode references.

CCS supports direct execution via ccs/<alias> even when the alias isn’t pre-registered in config; those are resolved lazily here.

OpenCode supports dynamic provider/model via opencode/provider/model syntax; those are validated against the API catalog and resolved lazily here.

Source

pub fn display_name(&self, name: &str) -> String

Get display name for an agent.

Returns the agent’s custom display name if set (e.g., “ccs-glm” for CCS aliases), otherwise returns the agent’s registry name.

§Arguments
  • name - The agent’s registry name (e.g., “ccs/glm”, “claude”)
§Examples
assert_eq!(registry.display_name("ccs/glm"), "ccs-glm");
assert_eq!(registry.display_name("claude"), "claude");
Source

pub fn resolve_from_logfile_name(&self, logfile_name: &str) -> Option<String>

Find the registry name for an agent given its log file name.

Log file names use a sanitized form of the registry name where / is replaced with - to avoid creating subdirectories. This function reverses that sanitization to find the original registry name.

This is used for session continuation, where the agent name is extracted from log file names (e.g., “ccs-glm”, “opencode-anthropic-claude-sonnet-4”) but we need to look up the agent in the registry (which uses names like “ccs/glm”, “opencode/anthropic/claude-sonnet-4”).

§Strategy
  1. Check if the name is already a valid registry key (no sanitization needed)
  2. Search registered agents for one whose sanitized name matches
  3. Try common patterns like “ccs-X” → “ccs/X”, “opencode-X-Y” → “opencode/X/Y”
§Arguments
  • logfile_name - The agent name extracted from a log file (e.g., “ccs-glm”)
§Returns

The registry name if found (e.g., “ccs/glm”), or None if no match.

§Examples
assert_eq!(registry.resolve_from_logfile_name("ccs-glm"), Some("ccs/glm".to_string()));
assert_eq!(registry.resolve_from_logfile_name("claude"), Some("claude".to_string()));
assert_eq!(registry.resolve_from_logfile_name("opencode-anthropic-claude-sonnet-4"),
           Some("opencode/anthropic/claude-sonnet-4".to_string()));
Source

pub fn resolve_fuzzy(&self, name: &str) -> Option<String>

Resolve a fuzzy agent name to a canonical agent name.

This handles common typos and alternative forms:

  • ccs/<unregistered>: Returns the name as-is for direct CCS execution
  • opencode/provider/model: Returns the name as-is for dynamic resolution
  • Other fuzzy matches: Returns the canonical name if a match is found
  • Exact matches: Returns the name as-is

Returns None if the name cannot be resolved to any known agent.

Source

pub fn list(&self) -> Vec<(&str, &AgentConfig)>

List all registered agents.

Source

pub fn developer_cmd(&self, agent_name: &str) -> Option<String>

Get command for developer role.

Source

pub fn reviewer_cmd(&self, agent_name: &str) -> Option<String>

Get command for reviewer role.

Source

pub fn load_from_file<P: AsRef<Path>>( &mut self, path: P, ) -> Result<usize, AgentConfigError>

Load custom agents from a TOML configuration file.

Source

pub fn apply_unified_config(&mut self, unified: &UnifiedConfig) -> usize

Apply settings from the unified config (~/.config/ralph-workflow.toml).

This merges (in increasing priority):

  1. Built-in defaults (embedded examples/agents.toml)
  2. Unified config: [agents], [ccs_aliases], and [agent_chain] (if present)

Returns the number of agents loaded from unified config, including CCS aliases.

Source

pub const fn fallback_config(&self) -> &FallbackConfig

Get the fallback configuration.

Source

pub fn retry_timer(&self) -> Arc<dyn RetryTimerProvider>

Get the retry timer provider.

Source

pub fn available_fallbacks(&self, role: AgentRole) -> Vec<&str>

Get all fallback agents for a role that are registered in this registry.

Source

pub fn validate_agent_chains(&self) -> Result<(), String>

Validate that agent chains are configured for both roles.

Source

pub fn is_agent_available(&self, name: &str) -> bool

Check if an agent is available (command exists and is executable).

Source

pub fn list_available(&self) -> Vec<&str>

List all available (installed) agents.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.