# `AgentSessionManager.Core.Registry`
[🔗](https://github.com/nshkrdotcom/agent_session_manager/blob/v0.8.0/lib/agent_session_manager/core/registry.ex#L1)

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

# `t`

```elixir
@type t() :: %AgentSessionManager.Core.Registry{
  manifests: %{required(String.t()) =&gt; AgentSessionManager.Core.Manifest.t()},
  metadata: map()
}
```

# `count`

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

Returns the count of registered manifests.

## Examples

    iex> Registry.count(registry)
    3

# `exists?`

```elixir
@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`

```elixir
@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`

```elixir
@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`

```elixir
@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`

```elixir
@spec get(t(), String.t()) ::
  {:ok, AgentSessionManager.Core.Manifest.t()}
  | {:error, AgentSessionManager.Core.Error.t()}
```

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`

```elixir
@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`

```elixir
@spec new() :: t()
```

Creates a new empty registry.

## Examples

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

# `new`

```elixir
@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`

```elixir
@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`

```elixir
@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`

```elixir
@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`

```elixir
@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`

```elixir
@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..."}}

---

*Consult [api-reference.md](api-reference.md) for complete listing*
