# `Jido.Plugin.Instance`
[🔗](https://github.com/agentjido/jido/blob/v2.3.0/lib/jido/plugin/instance.ex#L1)

Represents a normalized plugin instance attached to an agent.

Supports multiple instances of the same plugin with different configurations
via the `as:` option. Each instance gets a unique derived state_key and
route_prefix based on the `as:` value.

## Fields

- `module` - The plugin module
- `as` - Optional instance alias atom (e.g., `:support`, `:sales`)
- `config` - Resolved config map (overrides from agent declaration)
- `manifest` - The plugin's manifest struct
- `state_key` - Derived state key (e.g., `:slack` or `:slack_support` if `as: :support`)
- `route_prefix` - Derived route prefix (e.g., `"slack"` or `"support.slack"`)

## Examples

    # Single instance (no alias)
    Instance.new(MyPlugin)
    Instance.new({MyPlugin, %{token: "abc"}})

    # Multiple instances with aliases
    Instance.new({MyPlugin, as: :support, token: "support-token"})
    Instance.new({MyPlugin, as: :sales, token: "sales-token"})

# `t`

```elixir
@type t() :: %Jido.Plugin.Instance{
  as: nil | atom(),
  config: map(),
  manifest: any(),
  module: atom(),
  route_prefix: binary(),
  state_key: atom()
}
```

# `derive_route_prefix`

```elixir
@spec derive_route_prefix(String.t(), atom() | nil) :: String.t()
```

Derives the route prefix from the plugin name and optional `as:` alias.

## Examples

    iex> derive_route_prefix("slack", nil)
    "slack"

    iex> derive_route_prefix("slack", :support)
    "support.slack"

# `derive_state_key`

```elixir
@spec derive_state_key(atom(), atom() | nil) :: atom()
```

Derives the state key from the base key and optional `as:` alias.

## Examples

    iex> derive_state_key(:slack, nil)
    :slack

    iex> derive_state_key(:slack, :support)
    :slack_support

# `new`

```elixir
@spec new(module() | {module(), map() | keyword()}) :: t()
```

Creates a new Instance from a plugin declaration.

Config resolution happens during instance creation:
1. Base config from `Application.get_env(otp_app, plugin_module)`
2. Per-agent overrides from the declaration
3. Validation against the plugin's `config_schema` if present

## Input Formats

- `PluginModule` - Module with no config
- `{PluginModule, %{key: value}}` - Module with config map
- `{PluginModule, [key: value]}` - Module with keyword list (may include `:as`)

The `:as` option is extracted from the config and used to derive
unique state_key and route_prefix for the instance.

## Examples

    Instance.new(MyPlugin)
    # => %Instance{module: MyPlugin, as: nil, state_key: :my_plugin}

    Instance.new({MyPlugin, as: :support, token: "abc"})
    # => %Instance{module: MyPlugin, as: :support, state_key: :my_plugin_support}

    Instance.new({MyPlugin, %{token: "abc"}})
    # => %Instance{module: MyPlugin, as: nil, config: %{token: "abc"}}

# `schema`

```elixir
@spec schema() :: Zoi.schema()
```

Returns the Zoi schema for Instance.
