Repository navigation
bug(omp): a steering message in the tail refuses every chained continuation — the host interjection envelope is not modelled (0.49.22) #792
Description
Short description
On OMP, a steering message (a message typed while the agent is working) in a chained continuation always makes the
continuation fail: chained continuation: delta differs from the prepared provider input tail. OMP wraps every
steering user message in a <system-notice>…</system-notice> interjection envelope after the context hook returns,
while piEncodeChainTail() re-encodes the raw text and has no steering handling at all. The turn is dropped and the
user's interjection is lost.
What happened
Plugin 0.49.22, OMP 18.12.6, openai-codex-responses / gpt-6.1-sol, Windows x64.
07:33:38.932 assistant stopReason=toolUse responseId=resp_04798c… providerPayload.dt=true items=3
07:34:42.144 toolResult (read_deadline_exceeded …)
07:34:42.455 user steering=true "note: ocr on books is not finished yet. it is planned for near future. …"
07:34:42.478 [magic-context][pi] CONTEXT REFUSED "Magic Context could not safely prepare this turn; send your
message again. stage=provider dispatch elapsed=282ms recovery=no managed result; refused
(provider request does not match this pass's managed dispatch (chained continuation:
delta differs from the prepared provider input tail))"
The assistant is a valid chain point (completed toolUse response with native items), so the continuation itself is
legitimate — the only unusual thing in the tail is the steering flag.
Root cause
OMP applies the envelope after the hook:
const transformContext = async (messages: AgentMessage[], signal?: AbortSignal) => {
const withContext = await extensionRunner.emitContext(messages, signal);
return wrapSteeringForModel(withContext); // packages/coding-agent/src/sdk.ts:4061-4063
};wrapSteeringForModel() (packages/coding-agent/src/session/messages.ts:685) wraps every message with
steering === true, drops the flag, and replaces the text with:
<system-notice>
User interjection during work: priority; supersedes conflicting prior instructions. Re-read; ensure current work reflects user intent.
</system-notice>
{{message}}
piEncodeChainTail() (both 0.49.22 and master) contains no reference to steering: it encodes the message as
{ "role": "user", "content": [{ "type": "input_text", "text": "<raw text>" }] }piExpandChainedRequest() compares that to the host's delta with isDeepStrictEqual and refuses on
"delta differs from the prepared provider input tail".
The general shape is reproducible without OMP internals:
reports/dispatch-failures/chain-delta-refusal.mjs shows that any host rewrite of a tail message (the same probe uses
pi-ai's own <stale-tool-result> rewrite) makes the plugin's delta differ and the continuation refused.
Impact: any chained turn whose tail contains a mid-turn message is dropped, and the interjection is lost with it —
which is the input most likely to redirect work in progress.
Proposed fix
- Model the envelope in the tail encoder for
steering === trueuser messages (pi-dispatch-chain-tail.ts, and
piAgentHistoryfor the full-request lanes). Prefer a single shared source for the template over a copy, and add
the host version to the pinned set the fence already tracks. - The structural fence already accepts host text variants through
prepared.responsesAlternatives. Give the chained
path the same tolerance: build a small candidate set (raw, steering-wrapped) and compare against it, so a
host-only text transform degrades the check rather than the turn. - Regression test: tail
[toolResult, { role: "user", steering: true, content }]must produce the wrapped delta and
be admitted.
Environment
@cortexkit/pi-magic-context0.49.22 (master0.49.23:pi-dispatch-chain-tail.tsstill has no steering handling)- OMP (
opencode-free-omp) 18.12.6, Bun, Windows x64 openai-codex-responses,gpt-6.1-sol; WebSocket chain active (previous_response_idframes observed)- Related: Design proposal: tier the dispatch verdict so unmodeled shapes degrade the check, not the turn #761 (degrade the check, not the turn) — this issue is one concrete, fixable shape
Activity
magic-alfonso commentedon Oct 26, 2026
Thanks for tracing this through the host. Losing the user's interjection along with the turn is the worst place for it to happen.
Confirmed. Oh My Pi wraps every steering message in its
<system-notice>envelope after the context hook returns (wrapSteeringForModel), and our chain tail encoder doesn't model that, so the delta never matches.We're working on a fix that encodes the steering envelope the way Oh My Pi does, checked against the installed host versions. I'll post here when it ships.
magic-alfonso commentedon Oct 27, 2026
Fixed in 0.49.24. Thanks @Zireael for the diagnosis.
The chained-request check now models the
<system-notice>envelope Oh My Pi wraps around a message typed while the agent is working, so steering messages no longer refuse every chained continuation. The model of Oh My Pi's text formatting was compared against Oh My Pi's own function on 4,096 generated texts across 18.12.3 and 18.12.6, and all of them match.Update the Pi package and restart Oh My Pi to pick it up.