GenServer for runtime agent management and discovery.
The Registry maintains a map of registered agents, each identified by a human-friendly name (alias) and associated with an LLM provider module.
Features
- Register agents with unique names, provider modules, and configuration
- Lookup agents by alias
- List all registered agents
- Update agent configuration
- Auto-discover available providers on startup
State Structure
The GenServer state is a map containing:
%{
agents: %{
"steve" => %Agent{name: "steve", provider: LlmCore.LLM.CLIProvider, ...},
"gemini" => %Agent{name: "gemini", provider: LlmCore.LLM.CLIProvider, ...},
"codex" => %Agent{name: "codex", provider: LlmCore.LLM.CLIProvider, ...}
}
}Usage
# Start the registry (usually via supervision tree)
{:ok, pid} = Registry.start_link(name: LlmCore.Agent.Registry)
# Register an agent
:ok = Registry.register("steve", LlmCore.LLM.CLIProvider, %{model: "claude-3-opus"})
# Lookup an agent
{:ok, agent} = Registry.get("steve")
# List all agents
agents = Registry.list()
Summary
Functions
Returns a specification to start this module under a supervisor.
Looks up an agent by name.
Returns all registered agents.
Registers an agent with the given name, provider module, and configuration.
Starts the Registry GenServer.
Synchronizes registered agents with provider definitions from TOML config.
Unregisters an agent by name.
Updates an agent's configuration.
Functions
Returns a specification to start this module under a supervisor.
See Supervisor.
@spec get(GenServer.server(), String.t()) :: {:ok, LlmCore.Agent.t()} | {:error, :not_found}
Looks up an agent by name.
Parameters
server- The Registry GenServer (default:LlmCore.Agent.Registry)name- The agent name to lookup
Returns
{:ok, Agent.t()}- Agent found{:error, :not_found}- No agent with that name
Examples
{:ok, agent} = Registry.get("steve")
agent.provider
#=> LlmCore.LLM.CLIProvider
@spec list(GenServer.server()) :: [LlmCore.Agent.t()]
Returns all registered agents.
Parameters
server- The Registry GenServer (default:LlmCore.Agent.Registry)
Returns
- List of
Agent.t()structs
Examples
agents = Registry.list()
Enum.map(agents, & &1.name)
#=> ["steve", "gemini", "codex", "openai"]
@spec register(GenServer.server(), String.t(), module(), map()) :: :ok | {:error, :already_registered | :invalid_name}
Registers an agent with the given name, provider module, and configuration.
Parameters
server- The Registry GenServer (default:LlmCore.Agent.Registry)name- Human-friendly alias for the agentprovider- Module implementingLlmCore.LLM.Providerbehaviourconfig- Provider-specific configuration map
Returns
:ok- Successfully registered{:error, :already_registered}- Name already taken{:error, :invalid_name}- Invalid name format
Examples
:ok = Registry.register("steve", LlmCore.LLM.CLIProvider, %{model: "claude-3-opus"})
@spec start_link(keyword()) :: GenServer.on_start()
Starts the Registry GenServer.
Options
:name- The name to register the GenServer under (default:LlmCore.Agent.Registry):auto_discover- Whether to auto-discover providers on startup (default: true)
Examples
{:ok, pid} = Registry.start_link(name: MyApp.Registry)
@spec sync_with_providers(GenServer.server()) :: :ok
Synchronizes registered agents with provider definitions from TOML config.
@spec unregister(GenServer.server(), String.t()) :: :ok
Unregisters an agent by name.
Parameters
server- The Registry GenServer (default:LlmCore.Agent.Registry)name- The agent name to unregister
Returns
:ok- Successfully unregistered (or agent didn't exist)
Examples
:ok = Registry.unregister("steve")
@spec update(GenServer.server(), String.t(), map()) :: :ok | {:error, :not_found}
Updates an agent's configuration.
Parameters
server- The Registry GenServer (default:LlmCore.Agent.Registry)name- The agent name to updateconfig- New configuration map (replaces existing config)
Returns
:ok- Successfully updated{:error, :not_found}- No agent with that name
Examples
:ok = Registry.update("steve", %{model: "claude-3-opus", temperature: 0.9})