Catalog accessors and global registry for tools, skills, plugins, MCP servers, agents, and slash commands.
This module serves two purposes:
Session Catalog -- a read-only view of the extensions available to a live session. It queries the session's backend for native catalog listings when available, and falls back to normalised metadata extracted from the session info map otherwise.
Global Registry -- CRUD operations for agent types, plugins, and slash commands that are shared across all sessions. Mutations notify the reload bus so live sessions react without restart.
When to use directly vs through BeamAgent
Use this module directly when you need to inspect or switch the tooling available to a session, or when you need focused access to global registry operations -- for example, in a capability-discovery UI, an orchestrator that selects agents dynamically, a plugin marketplace, or a command palette.
Quick example
# --- Session Catalog ---
# List all available tools for a session:
{:ok, tools} = BeamAgent.Catalog.list_tools(session)
# Look up a specific tool by name or ID:
{:ok, tool} = BeamAgent.Catalog.get_tool(session, "file_read")
# --- Global Registry ---
# Register an agent type globally:
:ok = BeamAgent.Catalog.register_agent("code-reviewer", %{
name: "Code Reviewer",
description: "Reviews code for quality"
})
# List all registered plugins:
plugins = BeamAgent.Catalog.registered_plugins()Core concepts
Catalog entries: each entry is a map with at least an
:idor:namekey. The exact shape depends on the backend, but entries are normalised to ensure consistent lookup by id, name, or path.Native vs fallback: backends that expose native listing functions are queried first. When native listings are unavailable, the catalog falls back to metadata extracted from the session info's
system_infomap.Default agent: setting the default agent for a session. This is supported because agent selection is part of the unified query option shape and can be merged into future requests without backend-specific logic.
Global registry: agent types, plugins, and slash commands registered globally via
register_agent/2,register_plugin/2, andregister_command/2. These are stored in:beam_agent_registrywith composite keys{Kind, Id}and are shared across all sessions.
Architecture deep dive
This module delegates every call to :beam_agent_catalog. Session catalog
queries go through :beam_agent_catalog_core (native backend APIs with
:gen_statem.call fallback). Global registry operations go through
:beam_agent_registry (unified ETS store).
See also: BeamAgent.Runtime, BeamAgent.Control, BeamAgent.
Summary
Types
A registry entry stored in the global agent/plugin/slash-command table.
Functions
Clear any default agent override for a session.
Remove all globally registered agent types.
Remove all globally registered slash commands.
Remove all globally registered plugins.
Return the currently selected default agent for a session.
Create the global registry ETS table. Idempotent.
List files and directories at the given path.
Read the contents of a file at the given path.
Get the version-control status of files in the session's project.
Find files matching a pattern in the session's working directory.
Search for code symbols matching query in the session's project.
Search for text matching pattern in the session's working directory.
Fuzzy-search for files by name in the session's project.
Fuzzy-search for files by name with options.
Look up a single agent by its id, name, or path.
Look up a single plugin by its id, name, or path.
Fetch a single registered agent type by id.
Fetch a single registered slash command by id.
Fetch a single registered plugin by id.
Look up a single skill by its id, name, or path.
Look up a single tool by its id, name, or path.
List all agents available to a session.
List commands available for the session using native-first routing.
List all MCP servers connected to a session.
List all plugins available to a session.
List all skills available to a session.
List all tools available to a session.
List models available for the session using native-first routing.
List models with backend-specific filter options.
Register an agent type globally (shared across all sessions).
Register a slash command globally (shared across all sessions).
Register a plugin globally (shared across all sessions).
List all globally registered agent types.
List all globally registered slash commands.
List all globally registered plugins.
Start a stateful fuzzy file search session.
Stop and clean up a fuzzy file search session.
Update a search session with a new query string.
Set the default agent for future queries on a session.
Return the static list of sub-agents that the session's backend exposes.
Return the static list of CLI commands that the session's backend supports.
Return the static list of LLM models available for the session's backend.
Unregister an agent type by id. Idempotent.
Unregister a slash command by id. Idempotent.
Unregister a plugin by id. Idempotent.
Types
@type registry_entry() :: %{ :id => binary(), :name => binary(), :kind => :agent | :plugin | :slash, :enabled => boolean(), optional(:description) => binary(), optional(:role) => atom(), optional(:version) => binary(), optional(:handler) => (map() -> {:ok, map()} | {:error, term()}), optional(:config) => map() }
A registry entry stored in the global agent/plugin/slash-command table.
Functions
@spec clear_default_agent(pid()) :: :ok
Clear any default agent override for a session.
After clearing, the session will use whatever agent the backend selects by default or infers from session metadata.
@spec clear_registered_agents() :: :ok
Remove all globally registered agent types.
@spec clear_registered_commands() :: :ok
Remove all globally registered slash commands.
@spec clear_registered_plugins() :: :ok
Remove all globally registered plugins.
Return the currently selected default agent for a session.
Returns {:ok, agent_id} if one has been set or inferred, or
{:error, :not_set} when no agent is active.
@spec ensure_registry() :: :ok
Create the global registry ETS table. Idempotent.
@spec file_list(pid(), binary()) :: {:ok, [:beam_agent_catalog.file_entry()]} | {:error, term()}
List files and directories at the given path.
@spec file_read(pid(), binary()) :: {:ok, %{path: binary(), content: binary()}} | {:error, :enoent | term()}
Read the contents of a file at the given path.
@spec file_status(pid()) :: {:ok, %{cwd: binary(), source: :git | :filesystem, files: [map()]}} | {:error, term()}
Get the version-control status of files in the session's project.
@spec find_files(pid(), map()) :: {:ok, [:beam_agent_catalog.file_entry()]} | {:error, term()}
Find files matching a pattern in the session's working directory.
@spec find_symbols(pid(), binary()) :: {:ok, [:beam_agent_catalog.file_search_result()]} | {:error, term()}
Search for code symbols matching query in the session's project.
@spec find_text(pid(), binary()) :: {:ok, [:beam_agent_catalog.file_search_result()]} | {:error, term()}
Search for text matching pattern in the session's working directory.
@spec fuzzy_search(pid(), binary()) :: {:ok, [:beam_agent_search_core.search_match()]} | {:error, term()}
Fuzzy-search for files by name in the session's project.
@spec fuzzy_search(pid(), binary(), map()) :: {:ok, [:beam_agent_search_core.search_match()]} | {:error, term()}
Fuzzy-search for files by name with options.
Look up a single agent by its id, name, or path.
Returns {:error, :not_found} when no agent matches the given identifier.
Look up a single plugin by its id, name, or path.
Returns {:error, :not_found} when no plugin matches the given identifier.
@spec get_registered_agent(binary()) :: {:ok, registry_entry()} | {:error, :not_found}
Fetch a single registered agent type by id.
@spec get_registered_command(binary()) :: {:ok, registry_entry()} | {:error, :not_found}
Fetch a single registered slash command by id.
@spec get_registered_plugin(binary()) :: {:ok, registry_entry()} | {:error, :not_found}
Fetch a single registered plugin by id.
Look up a single skill by its id, name, or path.
Returns {:error, :not_found} when no skill matches the given identifier.
Look up a single tool by its id, name, or path.
Returns {:error, :not_found} when no tool matches the given identifier.
Example
case BeamAgent.Catalog.get_tool(session, "file_read") do
{:ok, %{name: name, description: desc}} -> IO.puts("Found " <> name <> ": " <> desc)
{:error, :not_found} -> IO.puts("Tool not available")
end
List all agents available to a session.
Prefers native agent listings from the backend (e.g., Copilot's
list_server_agents) when available, falling back to agents extracted from
session metadata.
List commands available for the session using native-first routing.
Attempts the backend's native command listing first. Falls back to
supported_commands/1 if the backend does not support dynamic listing.
The result may include commands added at runtime (e.g., via plugins or
MCP servers).
Parameters
session-- pid of a running session.
Returns
{:ok, commands}wherecommandsis a list of command maps.{:error, reason}on failure.
List all MCP servers connected to a session.
Returns metadata about each MCP server, including server names, capabilities, and connection status as reported by the backend.
List all plugins available to a session.
Returns plugin entries from the session's metadata. Plugin availability depends on the backend's extension model.
List all skills available to a session.
Prefers native skill listings from the backend when available, falling back to skills extracted from session metadata.
List all tools available to a session.
Returns catalog entries from the session's tool listing. The exact contents depend on the backend and any MCP servers connected to the session.
Example
{:ok, tools} = BeamAgent.Catalog.list_tools(session)
Enum.each(tools, fn %{name: name} -> IO.puts("Tool: #{name}") end)
List models available for the session using native-first routing.
Convenience wrapper that calls model_list/2 with empty options.
Attempts the backend's native model listing first; falls back to
supported_models/1 if the backend does not support dynamic listing.
Parameters
session-- pid of a running session.
Returns
{:ok, models}wheremodelsis a list of model maps.{:error, reason}on failure.
List models with backend-specific filter options.
Filters are backend-specific and may include capabilities, context window
size, or model family. Uses native-first routing with a fallback to
supported_models/1.
Parameters
session-- pid of a running session.opts-- backend-specific filter options map.
Returns
{:ok, models}or{:error, reason}.
Register an agent type globally (shared across all sessions).
Parameters
id-- unique binary identifier for the agent type.opts-- map of agent options (:name,:description,:role,:enabled,:config).
Register a slash command globally (shared across all sessions).
Parameters
id-- unique binary identifier for the command.opts-- map of command options (:name,:description,:handler,:enabled,:config).
Register a plugin globally (shared across all sessions).
Parameters
id-- unique binary identifier for the plugin.opts-- map of plugin options (:name,:description,:version,:enabled,:config).
@spec registered_agents() :: [registry_entry()]
List all globally registered agent types.
@spec registered_commands() :: [registry_entry()]
List all globally registered slash commands.
@spec registered_plugins() :: [registry_entry()]
List all globally registered plugins.
@spec search_session_start(pid(), binary(), [binary()]) :: {:ok, :beam_agent_search_core.search_session()} | {:error, term()}
Start a stateful fuzzy file search session.
Stop and clean up a fuzzy file search session.
@spec search_session_update(pid(), binary(), binary()) :: {:ok, [:beam_agent_search_core.search_match()]} | {:error, term()}
Update a search session with a new query string.
Set the default agent for future queries on a session.
The agent ID is stored in the runtime state and merged into future query options automatically. Allows switching between agents without restarting the session.
Example
:ok = BeamAgent.Catalog.set_default_agent(session, "claude-sonnet-4-6")
{:ok, "claude-sonnet-4-6"} = BeamAgent.Catalog.current_agent(session)
Return the static list of sub-agents that the session's backend exposes.
Sub-agents are specialized assistants that handle focused tasks such as code review, test generation, or documentation writing.
Parameters
session-- pid of a running session.
Returns
{:ok, agents}whereagentsis a list of agent maps, each containing:name,:description, and:capabilities.{:error, reason}on failure.
Return the static list of CLI commands that the session's backend supports.
Each backend advertises a fixed set of commands it can handle (e.g.,
"query", "interrupt", "config"). Use this to discover what operations
are available before attempting them, or to build dynamic command palettes.
Parameters
session-- pid of a running session.
Returns
{:ok, commands}wherecommandsis a list of command maps, each containing:nameand:description.{:error, reason}on failure.
Return the static list of LLM models available for the session's backend.
Use this to present model selection options or validate a model identifier
before passing it to BeamAgent.Runtime.set_model/2.
Parameters
session-- pid of a running session.
Returns
{:ok, models}wheremodelsis a list of model maps, each containing:nameand:capabilities.{:error, reason}on failure.
@spec unregister_agent(binary()) :: :ok
Unregister an agent type by id. Idempotent.
@spec unregister_command(binary()) :: :ok
Unregister a slash command by id. Idempotent.
@spec unregister_plugin(binary()) :: :ok
Unregister a plugin by id. Idempotent.