glrs
    Preparing search index...

    a turn

    a turn is one exchange: your message, the model's work, its answer. a step is one model call inside it. a turn with three tool calls takes several steps.

    send the conversation, read the stream, run the tools the model called, send again. the turn ends when the model calls no tool and has nothing left to say. a hundred steps is the ceiling.

    part contents changes
    instructions the system prompt never, byte for byte
    history every earlier message only by appending
    new message environment, skills catalogue, extension lines, what you typed every turn

    nothing volatile is in the system prompt. the date, the git branch and the skills catalogue ride in the per-turn message instead. a system prompt that varied would move the cached prefix, and every turn would pay full price for the whole conversation.

    a provider charges less for a prefix it has seen. that is why history is only ever appended to, and why steering joins at a step boundary rather than being inserted earlier.

    OpenAI and Google cache a prefix without being asked. Anthropic and Bedrock cache only what is marked, so glrs marks the second-to-last message: the newest point that will still be there next turn. the mark advances every turn, which extends the cached prefix rather than replacing it. on the first turn there is no second-to-last, so the only message is marked, and the second turn opens on a prefix the provider has already seen.

    everything else reaches an OpenAI-compatible endpoint, and caches or does not according to the model behind it. glrs sends no cache control there, because there is none to send: prompt_cache_key is OpenAI's, and a Foundry deployment answers Unrecognized request argument supplied rather than ignoring it. the same is true of textVerbosity, which is how a request about verbosity came to fail as though it were about reasoning.

    what that leaves is the prefix itself, which is the part glrs controls. measured over two turns on one Foundry resource:

    model reused on the second turn
    azure/gpt-5.6-sol 2601 of 2982
    azure-foundry/DeepSeek-V4-Flash 3584 of 4100
    azure-foundry/kimi-k2.6 nothing; that model does not cache

    a cold prefix reports nothing cached on its first outing. that is the cache being written, not a failure.

    joins costs
    steering the running turn, at its next step the tokens of what was said
    follow-up its own turn, once the agent runs out of work a new turn

    steering takes a modifier because it interrupts; a follow-up does not. steering that arrives too late to join becomes a follow-up, ahead of the ones already waiting.

    three layers, innermost first:

    1. fetch retries a connection that failed while the request was going out.
    2. the model client retries a refused request, five times.
    3. the turn re-sends the whole stream, three times.

    the third exists because the first two cannot see a mid-response drop: fetch resolved long ago and the body is still being read.

    re-sending is safe only while the attempt is unobservable, meaning no text, no reasoning and no tool call has been produced. once anything has, the failure surfaces instead of being retried.

    the context cannot grow forever, so past a threshold the older part is replaced by a summary. the cut lands on a user message, because a tool result separated from the call it answers is an invalid request.

    thresholds and what survives: sessions.

    see also: turns, events, models