Skip to content

v0.21.2

Choose a tag to compare

@github-actions github-actions released this 19 May 10:16
· 2095 commits to master since this release

v0.21.2 — Pi extension compatibility and high-pressure safety

A short patch release fixing real cache-stability and Pi subagent issues found in production over the past week.

What's improved

Pi: extensions adding custom messages no longer break compartment boundaries

Pi extensions that emit customType messages — Magic Context's own /ctx-status output, plus several common Pi extensions like anthropic-auth, pi-http-dump-src, and condensed-milk-pi — add real entries to agent.state.messages that are stored as custom_message (rather than message) branch entries. Our previous walk through getBranch() assumed those two counts were always equal, so any custom messages mixed in shifted every subsequent index by one. Compartment boundary lookups stopped matching, <session-history> injection fell into degraded mode, the visible tail couldn't be trimmed, and context kept growing until the 95% emergency.

The mapping is now resolved by AgentMessage reference identity instead of by array position, so custom messages from any extension can sit anywhere in state.messages without affecting boundary resolution. Resolves the symptom reported in issue #81 and fixes a smaller off-by-one drift around agent_end that we observed in our own sessions.

Pi: subagent spawn works in npm-only installs

PiSubagentRunner was spawning the pi binary from PATH for historian, dreamer, and sidekick child processes. In environments without a globally installed Pi binary (npm-only installs, CI, sandboxed setups) that silently failed, leaving subagent features unusable. The runner now resolves @earendil-works/pi-coding-agent from node_modules and falls back to PATH only when resolution fails, then invokes Pi directly under Node — no Bun dependency.

OpenCode: no infinite loop at high context pressure

At ≥95% pressure during historian work, the "Magic Context is compacting history" notification was being emitted on every transform pass. Each notification persists as a new user message; OpenCode's assistant runLoop break condition compares the latest user and assistant message IDs, so a stream of new user messages kept the loop iterating. Sessions that hit very high pressure could spin through hundreds of identical requests before recovering. The notification now fires at most once per historian run.

OpenCode: bounded session message fetches

Several internal paths (historian, compressor, dreamer, sidekick, key-files, conflict-warning) were calling OpenCode's session.messages endpoint without an explicit limit, which the underlying API treats as "load the entire session into memory." All nine callsites now request at most the latest 50 messages — enough for what they actually need. Reported by an external audit.

Upgrade

This release does not add any database migrations.

# OpenCode
npx @cortexkit/magic-context@latest doctor --force

# Pi (requires Pi >= 0.74)
npx @cortexkit/magic-context@latest setup --harness pi