The /todo rm reminder was a generic "user manually modified" message
showing an empty list, so the model read the cleared list as missing and
re-populated it on the next turn. buildSystemReminder now emits an explicit
do-not-recreate / do-not-re-add directive for removals while keeping
status mutations (done/drop) neutral.
Fixes#5258
When the single most-recent turn is itself over budget, prepareCompaction
returns undefined (findCutPoint never cuts inside a tool result, so the kept
tail has nothing on the summarizable side) and summary compaction cannot
start. The !preparation short-circuit in #runAutoCompaction emitted the
"Compaction freed too little context to make progress" warning and paused,
never running the artifact-backed shake elide rescue that #3786 wired into the
post-maintenance guard — so snapcompact/context-full maintenance looped the
warning with no attempt to shrink the oversized tail.
Run the same elide rescue before pausing, re-prepare on the shrunken branch,
and fall through to a normal compaction when the tail became summarizable
(writing a compaction entry anchors the stale billed usage so the auto-continue
re-check cannot re-trip). Only pause with a single warning when nothing is
elide-eligible. Flag historyRewritten on a rescue that offloaded content so
overflow recovery does not re-restore the just-failed turn onto the elided tail.
Fixes#4786
parseModelPatternWithContext ran matchModel on the whole pattern
(including a trailing :level thinking suffix) and only stripped the
suffix if that first pass missed. matchModel's provider-scoped fuzzy
match normalizes colons away and does subsequence matching, so
kimi-for-coding:high matched the longer sibling kimi-for-coding-highspeed
before the suffix was recognized as a thinking level, silently switching
model and billing tier.
Match the full pattern exactly first (new exactOnly mode skips the
fuzzy/substring fallbacks), then strip a valid :level suffix and recurse
before any fuzzy match; fuzzy-match the whole pattern only as a last
resort. Literal ids ending in :max still win via the exact pass.
Fixes#5151
Preferred the active session provider after any explicit image preference and retained the configured auto order for remaining candidates.
Continued to the next credentialed image provider after HTTP failures.
Fixes#5218
RPC mode iterated readJsonl(Bun.stdin.stream()), where JSON parsing runs
inside the generator. A parse error thrown from the generator escaped the
frame loop's try/catch (which only wrapped dispatch), unwound runRpcMode,
and exited the process on any non-JSON stdin line.
Read raw lines via readLines and JSON.parse each inside the existing
try/catch so a malformed line emits a Failed to parse command error frame
and the loop keeps running. Shared readJsonl stays strict for session-file
reads.
Fixes#5194
Manual /compact with the snapcompact strategy hard-threw when the active
model lacked image input, unlike the auto-compaction path which downgrades
to LLM-backed compaction. Clear snapcompactReady instead of throwing so the
flow falls through to #compactWithFallbackModel (active text-only model
tried first for text->text summarization).
Fixes#5064
Plugin/custom tool renderers can return a component whose render() throws
(e.g. a plugin styling its header off an object without a bold method,
producing TypeError: th.bold is not a function). ToolExecutionComponent only
caught the renderCall/renderResult factory, not the child component's later
render() pass, so the exception escaped and crashed the transcript.
Wrap every renderer-returned call/result component in SafeToolRendererComponent,
which catches render() errors and falls back to the tool label (call) or raw
result text (result), logging once per component.
Fixes#4978
`omp marketplace add xyz` and the other documented `omp plugin <action>`
verbs (marketplace, discover, upgrade, uninstall, enable, disable) were
never registered top-level commands, so `resolveCliArgv` forwarded the
whole argv to `launch` as an LLM prompt. The #2935 guard only caught
bare single-word verbs, missing the multi-word documented grammar.
Extended `reservedTopLevelWordMessage` to hint at the real
`omp plugin <action>` command for these verbs when used bare, with a
marketplace sub-action, or with a `name@marketplace` plugin id, while
genuine prose prompts beginning with the same words still route to
`launch`.
Fixes#4845