# `PtcRunner.SubAgent.Loop.LispOpts`
[🔗](https://github.com/andreasronge/ptc_runner/blob/main/lib/ptc_runner/sub_agent/loop/lisp_opts.ex#L1)

Shared builder for `PtcRunner.Lisp.run/2` opts across every loop transport.

Single source of truth: all three transports — the `:content` path in
`PtcRunner.SubAgent.Loop`, the `:tool_call` path in
`PtcRunner.SubAgent.Loop.PtcToolCall`, and combined-mode
`lisp_eval` dispatch in `PtcRunner.SubAgent.Loop.TextMode` —
build their `Lisp.run/2` opts here. Past divergence between the
copies (see issue #874) was a real bug class; resolving it requires
one builder, not coordinated edits across three.

Per-transport defaults that don't fit the universal shape
(e.g. combined mode wanting `memory` and `tool_cache` to default to
`%{}` rather than `nil`) belong in the call site — normalize the
`state` you pass in, don't fork the builder.

# `build`

```elixir
@spec build(agent :: map(), state :: map(), exec_context :: map(), tools :: term()) ::
  keyword()
```

Build the `Lisp.run/2` opts list.

Reads from `agent` and `state` and emits the canonical 14-key
keyword list, optionally appending `:max_heap` and `:max_tool_calls`
when set.

---

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