- Union changelog merges interleaved stale pre-17.2.5 PR-branch entries into
released sections; released bodies are restored byte-for-byte from the
pre-merge main state.
- [Unreleased] now carries exactly the entries for PR #7080 and the nine
merged fixes (#7495, #7460, #7466, #7468, #7473, #7481, #7477, #7368, #7453).
- Account-scoped bearer /v1/models responses now replace the static seed
instead of merging, so models disabled for the account are not selectable.
- Extended the catalog regression to run a real online refresh and assert
the static seeds are pruned to the fetched IDs.
A peer-IRC interrupt (e.g. a subagent message) aborts only interruptible
waits and leaves already-running non-interruptible foreground work alone.
But runTool's `interruptState.triggered` early-return skipped every
not-yet-started tool regardless of source, so a non-interruptible tool
queued behind an interruptible wait in the same batch (a batched todo/write
after `hub wait`) was dropped with "Skipped due to pending peer interrupt".
Exclude non-interruptible tools from the early skip on the IRC path; user
and system steering still preempt all queued work.
Fixes#7493
Applied GitHub Copilot's discovered default token-price tier to base models while preserving the provider fallback for unreported cache-write costs. Added regression coverage for GPT-5.6 Luna base and long-context pricing.
Fixes#7471
Dynamically discovered deepseek-v4* models (e.g. deepseek-v4-flash-0731)
now receive reasoning: true and [high, max] thinking efforts via prefix
matching in the discovery mapper.
An agent-attributed developer turn (e.g. a plan-approval handoff into a
fresh session) maps to Ollama's `system` role, so a request whose only
non-system message is that turn carried zero `user`-role turns. Ollama
answers such a request with `done_reason: "load"`, generating nothing,
and `mapDoneReason` laundered it into a clean `stopReason: "stop"` with
zero usage — indistinguishable from a legitimate empty completion, so
every recovery layer retried the impossible request until the cap
surfaced a misleading empty-stop error.
- convertMessages now demotes the last non-prefix `system` turn to
`user` when no user turn survives, keeping the static system-prompt
prefix intact for prefix caching.
- mapDoneReason maps `done_reason: "load"` to `error` with an explicit
message so it surfaces immediately instead of being retried.
Fixes#7465
- waitForLogEntry raced winston's async flush and JSON.parsed a
partially written line, failing the error-serialization tests on
loaded CI runners; unparseable lines now wait for the next poll.
- Aborting a caller while it was the sole extraction waiter tore the shared
extraction down and deadlocked against the blocked conversion mock, hanging
the CI chunk until SIGKILL.
- Sequenced owner/joiner starts and added an untilAborted spy barrier that
waits for both waiters to attach before aborting.
Protect only the harness pid during cancellation sweeps. The host recorded parent pid can be stale on Windows and recycled onto the hung command; adding that raw pid to the protected set spared the cancellation target and pruned its whole subtree from cleanup.
Keep protected-subtree pruning rooted at the harness itself, which still spares its real workers while allowing the timed-out target to be reaped.
Fixes#7452
The flattened descendant list can contain a protected node (the
harness, on a Windows PID-reuse false-descendant) together with that
node's real children, collected by recursing through it. Skipping only
the exact protected pid kept omp alive but still TerminateProcess'd its
unrelated worker/tool subprocesses.
signal_tree/terminate_tree now drop every node whose recorded parent
chain within the enumerated set passes through a protected pid, so a
false descendant of the harness can no longer drag the harness's real
children into the kill set.
Fixes#7452
- The 'N tool calls elided' replay placeholder leaked tool activity while
display.hideToolActivity was on; it is now a visibility-aware component
wired into both the hotkey and /settings toggle paths.
- Added replay + live-reveal regression coverage.
- A reload that drops a module's last require() edge leaves the permanent
hooks serving it from the synchronous snapshot map, which was only
refreshed while the path stayed flagged; an edit after the downgrade
replayed stale bytes. Ensure now re-rewrites and refreshes the snapshot
for every ever-synchronous path on each graph walk.
- Added the mirror reload regression (require edge dropped + source edited).
On Windows the descendant tree used to reap a cancelled bash run is
built from raw th32ParentProcessID links that outlive their recorded
parent. A recycled pid matching the harness's stale parent pid could
surface omp itself (or an ancestor) as a false descendant, and
signal_tree TerminateProcess'd it — killing the session with no
cleanup and no session_exit record when a blocking command hit its
timeout.
Add host_protected_pids() (harness pid plus its resolvable ancestor
chain) and skip those pids in signal_tree and terminate_tree. The
guard is cross-platform: a no-op on Unix, where the descendant walk is
already identity-pinned, and the safety net that keeps a tool timeout
from ever taking down the harness on Windows.
Fixes#7452
- A reload that adds a require() edge to an already-hooked ESM module never
re-registers hooks, and the original async onLoad filter keeps matching;
require() rejects async onLoad results, so the async hook now serves the
pre-rewritten synchronous source inline when one exists.
- Added a same-process reload regression covering the async-to-sync upgrade.
inspect_image resolved @vision with resolveModelFromString, which dropped the
:high thinking selector, and passed no reasoning to the oneshot. The
google-gemini-cli mapper then emitted thinkingBudget: 0, which thinking-only
Gemini models reject with HTTP 400. Resolve the role's explicit thinking
selector, clamp it to the model's supported efforts, and forward it as the
oneshot reasoning.
Fixes#7448
- Added shared Python call and literal serialization utilities with multiline verbatim support.
- Standardized tool inventories to format as an OpenAI-Harmony functions namespace using TypeScript declarations.
- Updated tool normalization and rendering functions to accept options objects and default to Python-syntax examples.
- Refactored Gemini dialect rendering to leverage shared serialization functions directly.