Skip to content

inference: cache-stable two-block system prompt (don’t bust the KV prefix) #558

Description

@btipling

Parent

#548 (agent session architecture)

Problem

OpenCode (and similar) pin a two-part system array so provider KV cache
stays valid across turns: if the first block is unchanged, later turns hit
cache instead of re-prefilling the world.

We already see cache working (1.2M cached on the usage chip) — the
prefix is enormous. Session-varying bits (cwd, attached skill bodies,
envelope-derived addenda, working notes once #550 exists) mixed into one
blob will invalidate that prefix whenever they twitch.

New-session “thinking hang” is still mostly serial I/O + cold start, but a
stable prefix is how we keep later turns from paying 1.2M uncached
again.

Goal

Assemble system as two (or few) stable blocks:

  1. Stable: tool schemas + persona snapshot + invariant harness law.
  2. Session-varying: cwd, skill catalog (skills: inject a catalog, not full bodies, every turn #557), working notes (agent memory: durable working notes / findings across turns (identity, not one-shot) #550),
    turn-specific addenda.

Do not mutate block 1 mid-session unless the operator actually changed
persona or the tool surface.

Success: consecutive turns on the same model show a high cache-read /
input ratio
on the occupancy/totals chip without stuffing new skill
bodies into block 1.

Constraints

Maps from peer harnesses

OpenCode system.ts + concatenate-into-two-blocks for Anthropic cache;
plugin transform only if it does not smash the first element.

Suggested next

create-plan with #557 (catalog vs bodies) — same assembly site.

Orrery (2026-08-15)

Choice precedes assembly. Resolve model (operator catalog / Next) then tools, system blocks, history. No generic prompt with the id slapped on.

Layout, strictly: system → tool definitions → durable spec / notes (#550) → plan/todo → history (#549). Nothing above history may vary turn-to-turn for a given (session, model) except at a phase/compact boundary.

Stay-put is a routing decision. Next mid-session is a family switch: #551/#552 treat it as a cache event, not a free paint change.

Breakpoints (if Gateway/provider can express them) sit at the stable/volatile cut. Do not invent cache_control the live runAgent path cannot send.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions