AgentSessionManager.Core.Registry (AgentSessionManager v0.2.1)

Copy Markdown View Source

A thread-safe registry for storing and retrieving provider manifests.

The Registry provides deterministic operations for managing provider manifests, including registration, retrieval, update, and filtering capabilities.

Thread Safety

The Registry uses immutable data structures, making all operations inherently thread-safe. Each operation returns a new Registry struct without mutating the original, enabling safe concurrent access patterns.

Determinism

All operations are deterministic - the same inputs will always produce the same outputs. The list/1 function returns manifests in a consistent order (sorted alphabetically by name).

Usage

# Create a registry
registry = Registry.new()

# Register a manifest
{:ok, manifest} = Manifest.new(%{name: "my-agent", version: "1.0.0"})
{:ok, registry} = Registry.register(registry, manifest)

# Retrieve a manifest
{:ok, retrieved} = Registry.get(registry, "my-agent")

# List all manifests
manifests = Registry.list(registry)

# Filter by provider
anthropic_agents = Registry.filter_by_provider(registry, "anthropic")

# Filter by capability
tool_agents = Registry.filter_by_capability(registry, :tool)

Validation

The Registry validates manifests before registration, providing helpful error messages for common issues:

result = Registry.validate_manifest(manifest)
case result do
  :ok -> IO.puts("Valid!")
  {:error, error} -> IO.puts("Error: #{error.message}")
end

Summary

Functions

Returns the count of registered manifests.

Checks if a manifest with the given name exists in the registry.

Filters manifests by capability type.

Filters manifests by provider.

Reconstructs a registry from a map.

Retrieves a manifest by name.

Lists all registered manifests in deterministic order (sorted by name).

Creates a new empty registry.

Creates a new registry with the given options.

Registers a new manifest in the registry.

Converts the registry to a map suitable for JSON serialization.

Removes a manifest from the registry by name.

Updates an existing manifest in the registry.

Validates a manifest, returning :ok if valid or {:error, error} with a helpful error message if invalid.

Types

t()

@type t() :: %AgentSessionManager.Core.Registry{
  manifests: %{required(String.t()) => AgentSessionManager.Core.Manifest.t()},
  metadata: map()
}

Functions

count(registry)

@spec count(t()) :: non_neg_integer()

Returns the count of registered manifests.

Examples

iex> Registry.count(registry)
3

exists?(registry, name)

@spec exists?(t(), String.t()) :: boolean()

Checks if a manifest with the given name exists in the registry.

Examples

iex> Registry.exists?(registry, "my-agent")
true

filter_by_capability(registry, capability_type)

@spec filter_by_capability(t(), atom()) :: [AgentSessionManager.Core.Manifest.t()]

Filters manifests by capability type.

Returns all manifests that have at least one enabled capability of the specified type.

Examples

iex> tool_agents = Registry.filter_by_capability(registry, :tool)

filter_by_provider(registry, provider)

@spec filter_by_provider(t(), String.t()) :: [AgentSessionManager.Core.Manifest.t()]

Filters manifests by provider.

Returns all manifests that have the specified provider.

Examples

iex> anthropic_agents = Registry.filter_by_provider(registry, "anthropic")

from_map(map)

@spec from_map(map()) :: {:ok, t()} | {:error, AgentSessionManager.Core.Error.t()}

Reconstructs a registry from a map.

Examples

iex> {:ok, registry} = Registry.from_map(map)

get(registry, name)

Retrieves a manifest by name.

Returns an error if the manifest does not exist.

Examples

iex> {:ok, retrieved} = Registry.get(registry, "my-agent")
iex> retrieved.name
"my-agent"

list(registry)

@spec list(t()) :: [AgentSessionManager.Core.Manifest.t()]

Lists all registered manifests in deterministic order (sorted by name).

Examples

iex> manifests = Registry.list(registry)
iex> length(manifests)
2

new()

@spec new() :: t()

Creates a new empty registry.

Examples

iex> Registry.new()
%Registry{manifests: %{}, metadata: %{}}

new(opts)

@spec new(keyword()) :: t()

Creates a new registry with the given options.

Options

  • :metadata - Optional metadata map for the registry

Examples

iex> Registry.new(metadata: %{version: "1.0"})
%Registry{manifests: %{}, metadata: %{version: "1.0"}}

register(registry, manifest)

@spec register(t(), AgentSessionManager.Core.Manifest.t()) ::
  {:ok, t()} | {:error, AgentSessionManager.Core.Error.t()}

Registers a new manifest in the registry.

Returns an error if:

  • A manifest with the same name already exists
  • The manifest fails validation

Examples

iex> registry = Registry.new()
iex> {:ok, manifest} = Manifest.new(%{name: "agent", version: "1.0.0"})
iex> {:ok, updated} = Registry.register(registry, manifest)
iex> Registry.exists?(updated, "agent")
true

to_map(registry)

@spec to_map(t()) :: map()

Converts the registry to a map suitable for JSON serialization.

Examples

iex> map = Registry.to_map(registry)
%{"manifests" => [...], "metadata" => %{}}

unregister(registry, name)

@spec unregister(t(), String.t()) ::
  {:ok, t()} | {:error, AgentSessionManager.Core.Error.t()}

Removes a manifest from the registry by name.

Returns an error if the manifest does not exist.

Examples

iex> {:ok, registry} = Registry.register(Registry.new(), manifest)
iex> {:ok, updated} = Registry.unregister(registry, "my-agent")
iex> Registry.exists?(updated, "my-agent")
false

update(registry, manifest)

@spec update(t(), AgentSessionManager.Core.Manifest.t()) ::
  {:ok, t()} | {:error, AgentSessionManager.Core.Error.t()}

Updates an existing manifest in the registry.

The manifest must already exist (matched by name). Returns an error if the manifest does not exist.

Examples

iex> {:ok, updated_registry} = Registry.update(registry, updated_manifest)

validate_manifest(manifest)

@spec validate_manifest(AgentSessionManager.Core.Manifest.t()) ::
  :ok | {:error, AgentSessionManager.Core.Error.t()}

Validates a manifest, returning :ok if valid or {:error, error} with a helpful error message if invalid.

Validation Rules

  • Name must be present and non-empty
  • Version must be present and non-empty
  • All capabilities must be valid

Examples

iex> Registry.validate_manifest(valid_manifest)
:ok

iex> Registry.validate_manifest(%Manifest{})
{:error, %Error{code: :validation_error, message: "Manifest name is required..."}}