- Add the `providers.cacheRetention` setting to control prompt-cache retention options per request.
- Forward configured cache retention preferences through the settings-aware stream function.
- Update documentation and test coverage for long cache retention behaviors.
The exact-echo check used accent-insensitive compare, but the collision
suffix path was a case-sensitive startsWith. AuthLoader-3 vs authloader
therefore leaked through as a real description.
The first HUD commit hid Name: Name. The cause was earlier: task
name was copied into identity.label, which became progress.description
and skipped generateTaskLabel. Keep the handle for id allocation, but
only treat eval label as a real UI description so the tiny-model
summary can run.
The anchored Subagents list printed only `Id: description` and treated a
label that repeated the spawn handle as a real description. Show the same
⟨role⟩ badge as inline task rows and omit descriptions that only echo the id.
Addresses review feedback on the initial commit:
- restore the trailing newline at EOF stripped by the first edit
- add a Fixed entry for this change under ## [Unreleased] in the coding-agent CHANGELOG
StopOnTextCriteria decoded the last STOP_DECODE_WINDOW_TOKENS of the whole
sequence, so prompt tokens were eligible for matching. A prompt that itself
contains the stop string stops generation at the first generated token and
yields an empty title.
Anchor the window to the generation boundary by recording the first
generated index per batch entry. Existing local title models are
unaffected: with the assistant-prefill prompt shape, the example `</title>`
tags sit outside the 32-token window for normal messages, so no shipping
model changes behavior. The bug becomes reachable with any chat-level
few-shot prompt that places the stop string near the generation boundary.
The memory-extraction prompt concatenated its instructions, few-shot
examples, and the user message into a single user turn, so a small local
model could not distinguish instructions from input and frequently echoed
the Globex/weather examples instead of extracting facts.
Send the instructions as a real system turn and the raw text as the user
turn. The tiny worker protocol gains a systemPrompt field, and Mnemopi
completion input carries task metadata so the backend selects the right
prompt per call.
Drop the code-built MEMORY_EXTRACTION_TEMPLATE rather than porting it:
prompt text belongs in .md files, and resolveMemoryCompletionInput already
overrides that template for every extraction call, so Mnemopi rendered it
only for the result to be discarded.
Measured on ONNX q4 CPU, LFM2.5-1.2B memory extraction improved from 1/8
to 5/8 once the roles were separated.
Retry: fixed changelog bundle probe asserting latest release equals VERSION (fails on releases with no coding-agent changelog content); widened issue-4593 watchdog test budgets from 5ms to 50ms against CI runner scheduling noise.
Three tests fail on a clean checkout depending on where the repo lives and
which terminal runs the suite:
- status-line-path builds its fake home inside the checkout, so a clone under
/tmp lands in a SCRATCH_ROOTS prefix and renders the scratch icon.
- status-line/component renders a fixed 120 columns, so a long checkout path
or branch name pushes the cost segment out of the assertion.
- bash-executor runs an interactive login zsh, which loads the system
/etc/zshrc; under Apple Terminal that appends session-save lines to the
captured output. HOME does not isolate a system-level file.
A developer shell with ANTHROPIC_BASE_URL set reroutes the effective endpoint
away from official, switching off eager tool-input streaming, long cache
retention, the Cowork TLS profile, the Claude Code session header and priority
service tier. 14 tests across 6 files assert those behaviors and fail on a
clean checkout.
Add withOfficialAnthropicEndpoint(), a beforeEach/afterEach pair that removes
the variable and restores it, and call it from the six affected files.
omp update re-threw Bun's raw fetch() UnsupportedProxyProtocol error, telling CLI users to pass verbose:true to fetch() — an instruction unavailable through the CLI. The update fetch catches now detect this failure and report which proxy env var uses an unsupported scheme plus the http/https requirement.
Fixes#8784
Force process termination via `postmortem.quit(0)` in
`Completions.run()` after writing completion scripts to stdout. Loading
all command modules during completion generation leaves open event loop
handles (sockets, timers) that prevent natural process exit, causing
tools like chezmoi to hang.
OpenCode substitutes {env:VAR} and {file:path} in config text at load
time, but OMP's OpenCode discovery ran the generic ${VAR}-only
expandEnvVarsDeep, leaving those tokens literal. An MCP header like
`Bearer {env:MCP_KEY}` reached the server verbatim and returned 401.
The OpenCode loader now applies OpenCode's own substitution to raw
config text before parsing: {env:VAR} -> env value or empty string,
{file:path} -> trimmed, JSON-escaped file contents resolved relative to
the config dir / ~ / absolute, skipping tokens on // comment lines.
Fixes#8778
The Home Manager module symlinked ~/.omp/agent/config.yml to a read-only
/nix/store path. OMP acquires an advisory lock on and atomically rewrites
its config when persisting runtime changes; on macOS the lock backend
creates an flock sidecar next to the target, so the first startup save
failed with "Failed to acquire native file lock ... Permission denied
(os error 13)", breaking every launch once programs.omp.settings was set.
Copy the generated config into place as a writable regular file via
home.activation instead. OMP can now lock and rewrite it, and the next
home-manager switch reapplies the declared settings. The DAG entry is
written literally so the home-manager-free module evaluation in flake.nix
keeps working; that check now asserts the activation entry.
Fixes#8775
Point xai and xai-oauth at grok-4.6, already in the bundled catalog.
Tests pin the default id in models.json and load picker fixtures from
the catalog so the next bump does not rot hardcoded name or cost.
Current Finder Cmd+C pasteboards advertise both a public.file-url and a
generated 1024x1024 file-icon bitmap. arboard::get_image() succeeded with
the icon, so handleImagePaste attached it before readMacFileUrlsFromClipboard
was reached, sending a generic PNG document icon to vision models instead of
the copied screenshot.
Probe the Darwin file URLs before the bitmap representation so an image-file
URL wins over the co-advertised icon. Pure bitmap pasteboards (screenshots,
browser copies) and non-image file URLs still fall through to the image/text
paths. readMacFileUrls is a no-op off Darwin.
Fixes#8769
A ThinkingLoop abort is the loop guard asking for a same-model resample
(it injects a thinking-loop-redirect notice that only makes sense on the
model that looped), not a provider failure. #handleRetryableError routed
it through the generic retryable-error branch, so on attempt 1 it called
noteRetryFallbackCooldown + #tryRetryModelFallback and could switch to
another family from retry.fallbackChains while parking the original
selector on a 5-minute cooldown. A healthy Grok 4.6 planning turn got
replaced by whatever the chain listed next.
Carve ThinkingLoop out of the model-fallback branch and out of the
Fireworks Fast->base degrade so the loop guard always re-samples the same
model; the retry budget still bounds a genuinely stuck stream.
Fixes#8760
Review noted that the option whitelist still let generic short flags
escape: `rm -rf -v /` and `rm -rf -i /` were not classified critical,
which is the same separator class the change set out to close.
Pin only the recursive/force flag and skip any other options on either
side of it, which also removes the need to enumerate long options. An
absolute target is still required, so `rm -rf -- ./build`,
`rm --recursive --force ./dist` and `rm -v /tmp/scratch` remain benign
and are asserted.
`CRITICAL_BASH_PATTERNS` required the target to follow one short flag
cluster directly, so anything in between escaped the check:
rm -rf / matched
rm -rf -- / missed
rm --recursive --force / missed
rm -rf --no-preserve-root / missed
rm --no-preserve-root -rf / missed
The last two matter most. GNU coreutils already refuses `rm -rf /` with
"it is dangerous to operate recursively on '/'" and names
`--no-preserve-root` as the override, so the pattern matched the form
that fails safe and missed the form that does not.
Repeat the option separator instead of assuming the path follows one
cluster, and treat `--no-preserve-root` as critical wherever it appears.
Absolute targets are still required for the first pattern, so
`rm -rf -- ./build` and `rm --recursive --force ./dist` stay benign;
both are asserted in the test.
PR #5270 reported the `--` and long-option forms in July and was closed
unmerged by the contributor-vouch bot rather than on merit. This keeps
its cases, credits them in the tests, and adds the `--no-preserve-root`
forms that patch did not cover.
Biome 2.x fully supports CSS parsing, formatting, linting, and assist
actions via its CLI and LSP proxy. The built-in Biome client config
did not include .css in its fileTypes array, causing OMP to skip Biome
for CSS files even when the project's biome.json enables CSS rules.
This change adds .css to the default fileTypes so that projects with
CSS files automatically route through Biome without needing a per-project
override of the full fileTypes array.
Closes#8735
resolveUpdateTargetFromPath gated the symlink->realpath resolution on
allowPackageManagers, so binary-only releases (a major bump or an explicit
omp.dist: "binary") wrote to the raw PATH symlink instead of the binary it
resolves to. On an admin shared install where /usr/local/bin/omp is a
root-owned symlink into a group-writable dir this either failed with EACCES
(writing <link>.new into the root-owned dir) or replaced the symlink with a
full copy, stranding the shared install behind a split-brain second binary.
Target selection no longer depends on the release's distribution channel: a
foreign symlink (a non-manager alias, an admin symlink into a shared install)
resolves to its real binary and the launcher is left intact in every channel.
A package-manager launcher (bun/npm) keeps its deliberate in-place takeover on
a binary-only release, detected by re-classifying the launcher as if managers
were allowed rather than by the channel flag. The manager bin dirs are probed
in the binary channel only when the launcher is a symlink, so plain-file
installs stay probe-free.
Fixes#8732