Member Junction
    Preparing search index...

    Type Alias SpecializationPlacement

    SpecializationPlacement: "auto" | "systemPrompt" | "trailingMessage"

    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.