Skip to content

v0.43.2

Choose a tag to compare

@github-actions github-actions released this 25 Sep 11:19
· 3325 commits to master since this release

If you converted an OpenCode 1 store to OpenCode 2 and history compression stopped with MC-H01, update now. This release repairs those sessions (see the first fix below). It also makes updating Magic Context on OpenCode 2 clearer, honours ctx_reduce permission denies on OpenCode 1, and fixes a set of Rust mode problems in the ck-mc module.

Upgrading

  • No database change. The schema fence stays at 90 and nothing migrates, so 0.43.0, 0.43.1 and 0.43.2 can share a database.
  • OpenCode 2: OpenCode 2 does not install plugin updates on its own. To install this release, open /plugins, select Magic Context and press ctrl+u, or run opencode plugin update. ctrl+r in /plugins only re-checks; it installs nothing.
  • Rust transform mode: the Rust fixes below are in the ck-mc module and apply after a module update and restart. A few also have a part in the npm package; each item says which. Update the module as usual.

Fix for history compression that never recovered

  • OpenCode 2: the historian refused every run on a store converted from OpenCode 1 (#531, Daviid-P). When OpenCode 2 converts an OpenCode 1 store, it removes some messages, for example the boundary message of a finished native compaction. Magic Context then moves each compartment to the new message positions using the messages at its two ends. A compartment whose start or end message was gone was marked unresolved and kept its old positions, which could overlap the next compartment. The historian checks the saved compartments before every run, found the overlap, and refused the run, so history was never compressed again and MC-H01 came back on every trigger.
    • The move now fills a missing start or end from the neighbouring compartment. Compartments cover the history with no gaps, so the message after one compartment's end is where the next one starts. A compartment that still can't be placed is trimmed so it no longer overlaps a neighbour that was placed.
    • Sessions already stuck on 0.43.1 are repaired once, on their first pass after the update. The historian also tries the same repair before it gives up on a run.
    • If a compartment still can't be placed, you see MC-H03, "History compression is paused because this session's saved summaries no longer line up with its messages", with the action "Run /ctx-recomp to rebuild them". The historian then waits 30 minutes before checking again instead of failing on every trigger. Saved compartments that fail the check for any other reason keep the MC-H01 notice as before.

OpenCode 2: updating Magic Context

  • OpenCode 2 installs an @latest plugin once and keeps loading that copy. When a new release comes out it only marks the plugin as having an update in /plugins. The update notice Magic Context shows on OpenCode 2 now says how to install it: ctrl+u in /plugins, or opencode plugin update. It used to say only "Update the plugin to install it".
  • doctor reports an outdated OpenCode 2 install. It compares the copy in OpenCode 2's plugin cache with the latest release and warns when it is older. This is a warning, not a failure: an available update is not a broken install. doctor --fix removes Magic Context's cached copy so OpenCode installs the current release on its next start. It does this only when OpenCode isn't running: if any process holds the OpenCode database or a file in that cache folder, or if doctor can't tell, the copy is left in place and doctor says how to update from inside OpenCode. Other plugins' cache folders and version-pinned Magic Context installs are never touched.
  • Duplicate Magic Context entries across plugin and plugins (#493, deltacat). OpenCode 2 reads both keys. With Magic Context listed under both, it loaded the first entry and failed the second with "Duplicate plugin ID", so /plugins showed a second, failed row. OpenCode 2.0.15's own opencode plugin add can create this when an entry already sits under plugin. doctor now lists every Magic Context entry when there is more than one, and doctor --fix keeps one. It prefers a bare or @latest entry, keeps that entry's options, and carries over a removed entry's options when the kept one has none. Comments and other entries in the config are left as they were. A local development path is never removed, and when two entries carry different options doctor leaves them all in place.
  • Object entries keep their options. OpenCode 2 allows { "package": "...", "options": { ... } } entries. When doctor moves such an entry to @latest, the options and any other fields now stay.
  • doctor --clear, the installed-version lookup and the issue report read the OpenCode 2 cache. They only knew OpenCode 1's cache layout, so on OpenCode 2 they found nothing. doctor --clear now clears Magic Context's OpenCode 2 cache copy with the same "only when OpenCode isn't running" check as doctor --fix. The issue report points at the copy the host actually loads and lists every Magic Context install in both layouts.
  • An entry pinned to a dist-tag is checked against that tag. For an entry such as @cortexkit/opencode-magic-context@beta, doctor checks the @beta cache copy against the current beta release, not against latest. Prereleases of the same version are ordered correctly, so 0.44.0-beta.1 counts as older than 0.44.0-beta.3.
  • An absolute OPENCODE_DB is honoured on OpenCode 2. Magic Context placed an absolute OPENCODE_DB inside OpenCode's data directory, so it looked for the database in the wrong place. It now uses an absolute path as given and resolves a relative one against the data directory, as OpenCode 2 does.

The OpenCode 2 getting-started page has a new "Updating Magic Context on OpenCode 2" section covering the same steps.

Other fixes

  • ctx_reduce honours an agent or session permission deny (#519, iceteaSA). OpenCode 1 only. Magic Context decided whether ctx_reduce was available from the first user message's tool list, and OpenCode never puts agent or session permissions there. A session whose agent denied ctx_reduce still got §N§ tags, the reduce guidance and nudges for a tool it could not call. Magic Context now reads the agent and session permissions once, at the start of a session, and a deny turns all of that off. On OpenCode 1.18, which builds the system prompt before the messages on a session's first turn, both are read before either is sent. As before, the decision is fixed for the rest of the session once made, so a permission changed mid-session only takes effect in a new session. This applies in TypeScript and Rust mode (npm package).
  • OpenCode 2: the restore after a host checkpoint re-read the whole history on every pass. Before a session has its first compartment, Magic Context puts back the messages up to OpenCode 2's checkpoint, and it read and decoded every one of them on every pass: about 10,000 rows per turn on a 10,000-message session. It now keeps the rows it has decoded and on each pass reads only the rows that are new or changed. A steady pass on that session decodes none. What the model receives is unchanged.

Rust mode (ck-mc module)

Each item below needs the module update.

  • A session that ran under TypeScript was served raw on every later Rust pass (#527, iceteaSA). When a session switched back to Rust mode after running under TypeScript, the module kept its own older history boundary and ignored the newer one the host sent. OpenCode had already cut that old boundary out of the messages, so the module could never find it again and sent the raw messages on every pass. The module now takes the host's newer history when it covers more than its own, replaces its whole compartment set with the host's, and folds once on the next pass. Older host history is still ignored. session.status and health now say when a session is being served raw for this reason.
  • Long-lived module processes kept per-session caches forever (#521, iceteaSA). Two in-memory caches gained an entry for every session the module had ever seen. Both are now emptied when a session's last route closes or the session is deleted, and rebuilt from the store if the session comes back. The issue also mentions the module's change feed; this release does not change it.
  • /ctx-wrapup after a host restart said "Retry in a moment (MC-C09)", but retrying never worked (#529, iceteaSA). After a restart the module has not yet seen the session, and only a new model turn fixes that. You now see MC-C12, "History compression has not seen this session since Magic Context reconnected. Send a message in this session first, then run /ctx-wrapup again." The retry advice stays for the case where a pass is still in progress. (npm package and ck-mc.)
  • The historian waited 600 seconds after a module restart instead of historian_timeout_ms (#522, iceteaSA). A historian run picked up again after a module restart used the producer's 600-second default. It now uses the configured historian_timeout_ms, clamped the same way as a fresh run.
  • Module-run memory classification recorded 0 tokens and no model (#520, iceteaSA). When the module ran classify-memories, the run was recorded with no token usage and no model. The module now reports the runner's token usage, and the host records it with the model. With an older module the host still records the model. (npm package and ck-mc.)
  • The module's manifest did not declare the calls that spend provider quota (#502, iceteaSA). It said the module had no such effects, but the historian and the classify task both call models through the runner module. The manifest now declares both while that route is in use.
  • The module's model-chain fallback was always empty (#505, iceteaSA). The module built a fallback model chain from historian.* config keys the plugin's config schema does not have, so the fallback was empty on every valid config. The fallback is removed and the host is now the only source of the model chain. A historian run without a chain is skipped with model_chain_missing and a warning, /ctx-wrapup uses the chain from the session's last pass, and a dreamer task without a chain fails with model_chain_missing. The host now always sends the chain for classification, even when it is empty. (npm package and ck-mc.)
  • Signed thinking was rewritten after a failed module call. When a module call fails, the host sends its last-known-good copy plus the raw newest messages, so the newest assistant message reached the provider with its signed thinking intact. The module never saw that pass, so on the next pass it treated that message as older history and dropped its signed thinking, changing text the provider had cached on a pass meant to change nothing. The module now keeps the signed thinking of assistant messages it has not seen yet until a pass that rebuilds the cache anyway.

The subagent late-tag fix already shipped in 0.43.1 and is not part of this release.

Tests

  • Test fixtures write their fake executables once instead of on every run, the Pi tail-hygiene test no longer fails in a serial run (#530, iceteaSA), and several OpenCode 2 end-to-end tests now run in the OpenCode 2 CI lane from one shared OpenCode 2 install per version.

Credits

Thanks to Daviid-P (#531), deltacat (#493) and iceteaSA (#502, #505, #519, #520, #521, #522, #527, #529, #530) for the reports.