While a provider error is pinned in the banner above the editor the inline transcript block is suppressed, so the prior guard skipped re-rendering on Ctrl+O and the full body stayed unreachable until the next turn.
- Track whether the message carries a truncatable error regardless of pinning, so setExpanded re-renders while pinned.
- Render the inline error block in full when expanded even while pinned; keep it suppressed only while pinned and collapsed.
- Disable the streaming fast path whenever the inline error block is drawn.
Fixes#6555
New live, rebuilt, and transcript-builder assistant components now inherit the active tool-output expansion state before provider errors render.
Added regression coverage for an error arriving after expanded mode was already enabled.
Fixes#6555
Turn-ending provider errors rendered inline through
AssistantMessageComponent#appendErrorBlock, capped at 8 lines with no
setExpanded method, so isExpandable filtered the component out of the
Ctrl+O tool-output expansion and the truncated tail was unreachable in
the live TUI (full text was persisted but not shown).
- Add setExpanded to AssistantMessageComponent; when expanded the error
block renders the full body (tabs replaced, blank lines preserved,
Text word-wraps to width).
- Collapsed view appends a dim "+N more lines (Ctrl+O to expand)" hint so
the truncation and its remedy are discoverable.
- Only re-render on toggle when the last render produced a truncatable
error block, so expansion skips ordinary turns.
Fixes#6555
Passed session-scoped settings through Edit and Write generated-file checks and fell back to schema defaults when no global singleton exists.
Guarded inline image sizing against an uninitialized global settings proxy and added isolated-session regression coverage.
Fixes#6549
- Remove uniform language inference requirement, allowing mixed-language paths to rewrite each file in its own language.
- Update `ast_edit_blocking` in `crates/pi-natives/src/ast.rs` to compile rewrite rules per language and skip unsupported languages gracefully.
- Update `ast-edit.md` prompt documentation to reflect mixed-language path support.
- Add test coverage verifying mixed-language tree rewrites.
Cursor forwards mounted xd:// devices (e.g. ast_edit) into its
request-context catalog but filtered the built-in write tool out via
CURSOR_NATIVE_TOOL_NAMES. ast_edit always stages a dry-run preview whose
resolution rides a write to xd://resolve / xd://reject, so with no
model-visible write the SoftToolRequirement('write') escalation aborted
the turn after three forced turns.
Re-include write in the forwarded catalog whenever pi-agent devices are
advertised; other native tools stay filtered.
Fixes#6536
- find -exec/-execdir children inherited the omp process's real
stdout/stderr, spamming output into the TUI terminal and bypassing
shell redirects; they also inherited the host env instead of the
shell's exported environment.
- Added pi_uutils_ctx::run_captured (moved from uu-xargs' private
helper): stdin null, stdout streamed into scope stdout, stderr
drained on a helper thread and forwarded after exit.
- uu-find exec matchers now use env_clear + env_snapshot and
run_captured; MultiExecMatcher rebuilds a std Command from the
argmax command's accumulated state (argmax only Derefs immutably).
- uu-xargs reuses the shared helper; added pi-shell regression test
asserting -exec child stdout flows through the shell redirect with
the exported env.
- Treated transient non-array retain items as absent during TUI streaming.
- Added regression coverage for malformed partial renderer arguments.
- Documented the fix in the coding-agent changelog.
Fixes#6528
- Kept zero timeout resolutions distinct from missing first-event policy so the iterator does not fall back to the idle watchdog.
- Added deterministic coverage for an SSE response that opens before local prompt prefill emits its first event.
- Added a per-model first-event watchdog policy and disabled it for local OpenAI-compatible backends while retaining inter-event stall detection.
- Applied the policy to Responses and chat-completions transports with regression coverage for resolver and runtime precedence.
Fixes#6524
- Added language-specific code formatters for JavaScript, Julia, Python, and Ruby to improve display rendering.
- Integrated display formatting into browser run and eval render tools while preserving verbatim execution.
- Added comprehensive test suites verifying formatting stability, lexical safety, and streaming behavior.
- Implemented a structured web-search query parsing module supporting directives, tokenization, date parsing, and syntax serialization.
- Updated search providers to map query directives and date bounds to native provider parameters and filters.
- Added lenient result constraint post-filtering and configuration settings for enhanced engine routing.
- Added comprehensive unit and integration tests covering query parsing, constraint filtering, and provider-specific request mapping.
The rebuild dedup dropped any preserved pendingTools component whose toolCallId
had a persisted toolResult. A background task's initial async.state=="running"
result is persisted while EventController#handleToolExecutionEnd deliberately
keeps its component in pendingTools so a later tool_execution_update/_end can
settle it. Dropping that still-live handle stranded those updates on the running
snapshot. Only terminal results are now owned by the replay; running async
handles stay preserved. Added a regression covering the running-task case.
rebuildChatFromMessages preserves the live pendingTools components across its
clear+replay so streaming keeps routing into them. That preservation assumed
every pending-tool component was still dangling (its result outside
state.messages). Once a tool's result had landed in the session entries while
its component still lingered in pendingTools (a rebuild racing the
tool-completion event, or a background/displaceable snapshot), the replay
reconstructed the completed block from the persisted toolResult AND the
preserved live component was re-appended, so the same tool block rendered twice.
Resolved tool calls are now dropped from the preserved live set and owned by the
replay; only genuinely in-flight (dangling, replay-stripped) calls are preserved.
Fixes#6516
- Add leniency rule in parser to auto-accept bare `-` rows as literal content when hunks represent Markdown bullet lists.
- Emit MINUS_BULLET_AUTO_PIPED_WARNING when bullet-shaped rows lack explicit plus prefixes.
- Reject ambiguous or non-bullet minus rows to prevent unified-diff contamination.
Replaced direct assertions on internal ordering and recovery helpers with an isolated broker integration test. The test seeds recovered terminal metadata, starts an active daemon, sends the authenticated list RPC, and asserts active-first ordering, true exit-time recency, the terminal cap, and protocol serialization/parsing.
Made the ordering and recovery helpers internal again because production wiring now supplies their coverage.
Fixes#6517
Recovery unconditionally restamped every non-detached record's exitedAt with the restart timestamp, including already-exited/failed ones, so after an idle-broker restart the list history cap could keep arbitrary directory-order entries and drop the genuinely most-recently-exited process.
Reap only records that were still alive at recovery; terminal records keep their real exitedAt/exitReason. Extract reapRecoveredSnapshot() and cover it with tests.
Fixes#6517
- Added handling for signature-bearing thinking blocks that never streamed deltas before closing.
- Implemented a safety net in `LeakedThinkingProjector` to recover thinking blocks with signatures missing per-block events.
- Added test coverage verifying proper projection order and recovery of unstreamed thinking signatures.
- Added guidelines stating that concurrent edits to the same files are safe.
- Specified prerequisites for safe overlap including skipping validation and defining contracts up front.
The broker `list`/ps op sorted every daemon record by createdAt ascending and never pruned, so in a long-lived project the active (newest) daemon rendered behind all exited ones and the response grew without bound.
List non-terminal daemons first (oldest to newest) and cap exited/failed history at the 10 most recently exited; truncated records stay addressable by name via describe/logs/restart.
Fixes#6517
- Add usage history, reporting, and client summary endpoints to the auth broker.
- Implement SQLite persistence, batching, and periodic flushing for observed client usage.
- Integrate usage reporting into the coding agent session for completed assistant messages.
- Update stats aggregator and dashboard to retrieve usage history snapshots from the broker.
- Added tool schema and description compaction for oversized data payloads in `packages/coding-agent/src/debug/raw-sse-buffer.ts`.
- Implemented head-tail trimming to preserve leading and trailing event fields when events exceed character budgets.
- Added test coverage verifying SSE debug event truncation, elision markers, and JSON-safe tool compaction behavior.
- Added available shell builtins list to the bash tool prompt template.
- Added helper to check if shell builtins are disabled via settings or environment.
- Added six builtin commands: ts, sponge, ifne, isutf8, combine, and errno to pi-shell.
- Created moreutils module with independent implementations for all tools.
- Added jiff dependency for timestamp and timezone functionality.
- Integrated builtins into shell execution pipeline with in-process execution.
- Added integration tests verifying pipe chains like ts | sponge with isutf8.
- Removes `model` field from task item/schema, TaskParams, and TaskItem types.
- Removes model selector validation, formatting, and approval display logic.
- Updates task tool priority docs to reflect that model is no longer per-call overridable.
- Updates eval agent() helper docs and prompt templates to remove model parameter.
- Updates tests to reflect removal of model override capability.
Gate the runtime alt-toggle resize latch when PI_TUI_RESIZE_IN_PLACE explicitly forces the fast path off, while preserving multiplexer handling.
Add regression coverage that auto-detects the alt-toggle echo, then verifies a later width resize still borrows the alternate screen and performs the authoritative ED3 rewrap.
Terminals that re-report their size whenever the alternate screen buffer toggles turned every fullscreen-overlay exit (/settings, models page) and resize into a spurious height-only SIGWINCH. That armed the resize drag/settle behind the overlay and drove a destructive ED3 clear-scrollback full repaint on exit -- visible as a flicker on terminals without DEC 2026 synchronized output -- with the size revert flashing another.
A SIGWINCH while a fullscreen overlay covers the transcript now repaints the overlay in place instead of arming the drag/settle, and the in-place resize path is latched once the height-only alt-toggle echo is observed, so this was previously handled only for Warp and is now auto-detected for any such terminal.
Fixes#6511
- Renamed quota label from "ZAI Web Search / Reader / Zread Quota" to "ZAI Zread Quota".
- Shortened tier slug from `web-search-reader-zread` to `zread` and updated associated limit IDs.
Skipped the context-management beta whenever OpenCode Zen requests omit the corresponding body field. Extended the issue regression test to assert both stay aligned.
The Zen Anthropic gateway requires `x-api-key` and rejects bearer-only
requests with `401 Missing API key`, breaking every Claude model on the
`opencode-zen` provider while OpenAI-format models on the same credential
work. `buildAnthropicClientOptions` special-cased `opencode-zen` to
bearer-only (`apiKey: null`); route it through the existing `X-Api-Key`
branch alongside `opencode-go`/`umans`, which share the same api-key login.
Also skip the unconditional `context_management` (`clear_thinking_20251015`)
field for `opencode-zen`: the proxy rejects it with `400 Extra inputs are
not permitted` on several Claude families, mirroring the Copilot skip.
Fixes#6510
Required CLI model registries to expose getAvailable() and used that authenticated
set whenever callers omit availableModels. Deferred SDK and bench/dry-balance
resolution now lets configured roles beat unauthenticated catalog id collisions.
Updated resolver test registries and made the #6508 regression omit the explicit
availableModels option, covering the deferred-caller path from the review.
Fixes#6508