Where the agent's specialization (its child prompt) is placed.
Background: the loop agent's per-iteration ("volatile") state — current date/time, Scratchpad
State, and the Payload — is never rendered in the system prompt. It is delivered as a single
framework-authored user-role message appended as the final message of the request, wrapped
in <mj-runtime-state> tags, with a static pointer in the system prompt telling the model where
to find it. This is not configurable: provider prompt caching is a prefix match over
tools → system → messages, and anything volatile in system renders ahead of the entire
message history, so the whole (growing) history would miss the cache on every iteration.
Measured on Sage, 2026-09-14: cache reads plateaued at ~21.5K tokens while uncached input grew
to 73K per call. Moving the volatile tail after the history lets the history cache incrementally.
'auto' (default): relocate the specialization into the trailing message ONLY if its template
references a volatile placeholder (_CURRENT_DATE*, _CURRENT_TIME*, _CURRENT_PAYLOAD,
_SCRATCHPAD_*). A static child prompt stays in the cached system prompt.
'systemPrompt': never relocate.
'trailingMessage': always relocate.
Why: the OS prompt cannot control what an agent designer puts in a child prompt. Six active
Loop agents embed a volatile placeholder in theirs, which mutates the system prompt every
iteration from a position ahead of the catalogs and the whole history — moving the runtime-state
tail does nothing for them. Measured (Gemini 2.5 Flash, volatile specialization): keeping it in
the system prompt caches 19%; relocating it caches 70%. For a STATIC child prompt, relocation
costs ≈3,100 uncached tokens per call for nothing, hence 'auto'. Decided once per run so the
layout never flips mid-run. Resolved through ResolveSpecializationPlacement.
Where the agent's specialization (its child prompt) is placed.
Background: the loop agent's per-iteration ("volatile") state — current date/time, Scratchpad State, and the Payload — is never rendered in the system prompt. It is delivered as a single framework-authored
user-role message appended as the final message of the request, wrapped in<mj-runtime-state>tags, with a static pointer in the system prompt telling the model where to find it. This is not configurable: provider prompt caching is a prefix match overtools → system → messages, and anything volatile insystemrenders ahead of the entire message history, so the whole (growing) history would miss the cache on every iteration. Measured on Sage, 2026-09-14: cache reads plateaued at ~21.5K tokens while uncached input grew to 73K per call. Moving the volatile tail after the history lets the history cache incrementally.'auto'(default): relocate the specialization into the trailing message ONLY if its template references a volatile placeholder (_CURRENT_DATE*,_CURRENT_TIME*,_CURRENT_PAYLOAD,_SCRATCHPAD_*). A static child prompt stays in the cached system prompt.'systemPrompt': never relocate.'trailingMessage': always relocate.Why: the OS prompt cannot control what an agent designer puts in a child prompt. Six active Loop agents embed a volatile placeholder in theirs, which mutates the system prompt every iteration from a position ahead of the catalogs and the whole history — moving the runtime-state tail does nothing for them. Measured (Gemini 2.5 Flash, volatile specialization): keeping it in the system prompt caches 19%; relocating it caches 70%. For a STATIC child prompt, relocation costs ≈3,100 uncached tokens per call for nothing, hence
'auto'. Decided once per run so the layout never flips mid-run. Resolved through ResolveSpecializationPlacement.