# `Planck.Agent.Hooks.TurnEnd`
[🔗](https://github.com/alexdesousa/planck/blob/v0.2.2/lib/planck/agent/hooks/turn_end.ex#L1)

Behaviour for post-turn reflection in `Planck.Agent`.

Implement this behaviour in a sidecar module to inspect completed turns and
take action — for example, writing a skill when a complex repeatable workflow
is detected.

## Behaviour

Use `use Planck.Agent.Hooks.TurnEnd` and override `reflect/2`:

    defmodule MySidecar.SkillReflector do
      use Planck.Agent.Hooks.TurnEnd

      @tool_threshold 5

      @impl true
      def reflect(agent_id, turn_messages) do
        # The implementation decides whether to act (e.g. threshold check).
        # Signal back via `Planck.Agent.inject_tool_result/3` if a skill was written.
        :ok
      end
    end

## Dispatch

`Planck.Agent` fires `reflect/4` in a background `Task` after every `:turn_end`
broadcast:

    Hooks.TurnEnd.reflect(state.turn_end_hook, state.id, turn_messages, state.sidecar_node)

- `module: nil` — no-op.
- `sidecar_node: nil` — calls `module.reflect/2` in-process.
- `sidecar_node` set — calls via RPC; logs a warning on `:badrpc`.

The default RPC timeout is 30000 ms; override `reflect_timeout/0`
to declare a custom expected latency.

# `reflect`

```elixir
@callback reflect(agent_id :: String.t(), turn_messages :: [Planck.Agent.Message.t()]) ::
  :ok
```

Inspect the completed turn and take action.

Called after every turn. The implementation is responsible for any threshold
checks or filtering. Must return `:ok`.

# `reflect_timeout`

```elixir
@callback reflect_timeout() :: pos_integer()
```

RPC call timeout in milliseconds when this hook is invoked remotely.

Defaults to 30,000 ms.

# `default_timeout`

```elixir
@spec default_timeout() :: pos_integer()
```

Default RPC timeout used when a module omits `reflect_timeout/0`.

# `reflect`

```elixir
@spec reflect(module() | nil, String.t(), [Planck.Agent.Message.t()], atom() | nil) ::
  :ok
```

Fire reflection for the completed turn.

Returns `:ok` immediately when `module` is `nil`. Otherwise dispatches
`module.reflect/2` locally or via RPC.

---

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