Repository navigation
v0.43.2
·
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 runopencode plugin update. ctrl+r in/pluginsonly re-checks; it installs nothing. - Rust transform mode: the Rust fixes below are in the
ck-mcmodule 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
@latestplugin 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, oropencode plugin update. It used to say only "Update the plugin to install it". doctorreports 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 --fixremoves 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
pluginandplugins(#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/pluginsshowed a second, failed row. OpenCode 2.0.15's ownopencode plugin addcan create this when an entry already sits underplugin.doctornow lists every Magic Context entry when there is more than one, anddoctor --fixkeeps one. It prefers a bare or@latestentry, 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 --clearnow clears Magic Context's OpenCode 2 cache copy with the same "only when OpenCode isn't running" check asdoctor --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@betacache copy against the currentbetarelease, not againstlatest. 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_DBis honoured on OpenCode 2. Magic Context placed an absoluteOPENCODE_DBinside 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_reducehonours an agent or session permission deny (#519, iceteaSA). OpenCode 1 only. Magic Context decided whetherctx_reducewas available from the first user message's tool list, and OpenCode never puts agent or session permissions there. A session whose agent deniedctx_reducestill 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.statusand 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-wrapupafter 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 andck-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 configuredhistorian_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 andck-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 withmodel_chain_missingand a warning,/ctx-wrapupuses the chain from the session's last pass, and a dreamer task without a chain fails withmodel_chain_missing. The host now always sends the chain for classification, even when it is empty. (npm package andck-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.