# `Pixir.Providers.Anthropic.Prompt`
[🔗](https://github.com/Ranvier-Technologies/pixir/blob/main/lib/pixir/providers/anthropic/prompt.ex#L1)

Provider-private pa5 prompt builder for Anthropic Messages requests.

pa5 mirrors the px8 prompt contract in doctrine, not bytes. Layer 0 is a
byte-stable system text block selected by mode, Layer 1 is the deterministic
Skills index when present, and volatile late context is inserted as the leading
text content block of the latest user message because Anthropic has no developer
role on the target model.

cache_control planning is fixed for pa5:

  * B1 is placed on the last system block.
  * B2 is placed on the content block at `prev_turn_boundary`, using a 1-based
    count over message content blocks after any late-context insertion. If that
    block is not cacheable, B2 walks backward to the nearest cacheable block at
    a lower position and is omitted when none exists.
  * B3 is placed only when more than 15 content blocks exist between the prior
    message breakpoint position, or B1 when B2 is absent, and the latest user
    message. When triggered, B3 targets the last content block before the latest
    user message, then walks backward to the nearest cacheable block at or
    before that target and is omitted when none exists or when it collides with
    B2.

Verified Anthropic prompt-caching documentation on 2026-07-08 says thinking,
redacted_thinking, and empty text blocks cannot be marked directly with
cache_control; pa5 treats those blocks as non-cacheable.

pa5 never emits more than three breakpoints. The fourth Anthropic breakpoint is
reserved by ADR 0037; using it or changing layout/fence tokens requires a future
prompt-contract bump. pa4 dropped the code-style reviewability sentence after the
N=3 A/B verdict (refs #570); pa3 exposed bash `timeout_ms` (refs #575).

pa5 changes the virtual-overlay tool schema/description and lifetime context, not
Layer 0 bytes, fence tokens, or cache-control planning. The px8/pa5 migration is an
intentional cache restart: expect cold prefixes before the new contract warms.
Its PR and observability window must remain separate from independent WebSocket
fixes so cache movement is attributable; a release may include both verified changes.

# `input`

```elixir
@type input() :: %{
  mode: :build | :plan,
  skills_index: String.t() | nil,
  messages: [map()],
  late_context: String.t() | nil,
  prev_turn_boundary: non_neg_integer() | nil
}
```

# `build`

```elixir
@spec build(input()) :: {:ok, map()} | {:error, map()}
```

Build Anthropic-native system and messages with the pa5 cache plan.

# `prompt_contract_version`

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

The pa5 prompt contract label, mirrored into neutral cache metadata (ADR 0037 D7).

---

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