# `JidoGralkor.Plugin`
[🔗](https://github.com/elimydlarz/jido_gralkor/blob/main/lib/jido_gralkor/plugin.ex#L1)

Jido plugin that replaces `Jido.Memory.BasicPlugin` with Gralkor-backed
memory. Claims the `:__memory__` slot so it is the only memory plugin
attached to the agent.

On `ai.react.query` the plugin plants two values on the signal's
`tool_context` so the `MemorySearch` ReAct tool can find them:

  * `:session_id` — the current Jido thread id (read from
    `agent.state[:__thread__].id`). Absent when no thread is
    committed yet (first query of a fresh agent, before the ReAct
    strategy's `ThreadAgent.append` runs inside `@start`); on that
    turn `MemorySearch` short-circuits with a non-result message.
  * `:agent_name` — the value supplied at mount.

The plugin does **not** call `Gralkor.Client.recall/3` on its own.
Recall is the LLM's job, invoked through the `MemorySearch` tool.
Consumers force it on the first ReAct iteration via
`JidoGralkor.ReAct.maybe_force_memory_search/2` from their
`Jido.AI.Reasoning.ReAct.RequestTransformer`.

Capture fires on `ai.request.completed` / `ai.request.failed`: the
full request trace and assistant answer are normalised via
`JidoGralkor.Canonical.to_messages/3` into Gralkor's canonical
`[%Gralkor.Message{role, content}]` shape and shipped to the server,
which keeps the rolling conversation buffer keyed by `session_id`.
Capture is skipped if the thread isn't present (first-turn failure
with nothing committed) or if the canonical message list is empty.
Capture failures raise (Gralkor capture is server-side buffered and
its retry lives in the capture buffer, not here — a raise from
`capture/3` means the server is unreachable).

# `__plugin_metadata__`

```elixir
@spec __plugin_metadata__() :: map()
```

Returns metadata for Jido.Discovery integration.

This function is used by `Jido.Discovery` to index plugins
for fast lookup and filtering.

# `actions`

```elixir
@spec actions() :: [module()]
```

Returns the list of action modules provided by this plugin.

# `capabilities`

```elixir
@spec capabilities() :: [atom()]
```

Returns the capabilities provided by this plugin.

# `category`

```elixir
@spec category() :: String.t() | nil
```

Returns the plugin's category.

# `config_schema`

```elixir
@spec config_schema() :: Zoi.schema() | nil
```

Returns the Zoi schema for per-agent configuration.

# `description`

```elixir
@spec description() :: String.t() | nil
```

Returns the plugin's description.

# `manifest`

```elixir
@spec manifest() :: Jido.Plugin.Manifest.t()
```

Returns the plugin manifest with all metadata.

The manifest provides compile-time metadata for discovery
and introspection, including capabilities, requirements,
signal routes, and schedules.

# `name`

```elixir
@spec name() :: String.t()
```

Returns the plugin's name.

# `otp_app`

```elixir
@spec otp_app() :: atom() | nil
```

Returns the OTP application for config resolution.

# `plugin_spec`

```elixir
@spec plugin_spec(map()) :: Jido.Plugin.Spec.t()
```

Returns the plugin specification with optional per-agent configuration.

## Examples

    spec = MyModule.plugin_spec(%{})
    spec = MyModule.plugin_spec(%{custom_option: true})

# `requires`

```elixir
@spec requires() :: [tuple()]
```

Returns the requirements for this plugin.

# `schedules`

```elixir
@spec schedules() :: [tuple()]
```

Returns the schedules for this plugin.

# `schema`

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

Returns the Zoi schema for plugin state.

# `signal_patterns`

```elixir
@spec signal_patterns() :: [String.t()]
```

Returns the signal patterns this plugin handles.

# `signal_routes`

```elixir
@spec signal_routes() :: [tuple()]
```

Returns the signal routes for this plugin.

# `singleton?`

```elixir
@spec singleton?() :: boolean()
```

Returns whether this plugin is a singleton.

# `state_key`

```elixir
@spec state_key() :: atom()
```

Returns the key used to store plugin state in the agent.

# `subscriptions`

```elixir
@spec subscriptions() :: [tuple()]
```

Returns the sensor subscriptions for this plugin.

# `tags`

```elixir
@spec tags() :: [String.t()]
```

Returns the plugin's tags.

# `vsn`

```elixir
@spec vsn() :: String.t() | nil
```

Returns the plugin's version.

---

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