github can1357/oh-my-pi v16.2.0

latest releases: v16.2.2, v16.2.1
8 hours ago

@oh-my-pi/pi-agent-core

Added

  • Added an optional cwdResolver to Agent and getCwd to AgentLoopConfig to dynamically resolve the working directory per LLM call, allowing workspace-scoped provider discovery (such as GitLab Duo Agent) to follow live directory changes without reconstructing the agent.

Fixed

  • Fixed an issue where API-level provider refusals were replayed as assistant dialogue on subsequent requests, preventing repeated refusals after a single blocked turn.
  • Fixed a bug where internal streaming state (partialJson) could leak onto the final AssistantMessage if a stream ended without a toolcall_end event.
  • Fixed Agent to correctly forward the working directory (cwd) into provider stream options, enabling providers like GitLab Duo Agent to scope local tool execution to the workspace.
  • Enabled custom OpenAI-compatible providers to use native remote compaction instead of falling back to local summarization.

@oh-my-pi/pi-ai

Breaking Changes

  • Removed the @oh-my-pi/pi-ai/utils/json-parse module. The JSON repair and parsing helpers (repairJson, parseJsonWithRepair, parseStreamingJson, parseStreamingJsonThrottled) have been moved to @oh-my-pi/pi-utils to be shared across utilities.

Added

  • Added the GitLab Duo Agent provider (gitlab-duo-agent) and built-in implementation, renaming the existing AI Gateway proxy provider to "GitLab Duo Non-Agentic" (gitlab-duo).
  • Added GitLab Duo Workflow provider support, featuring OAuth login via the official VS Code OAuth application, automatic project discovery, and automatic session-time namespace Duo settings enablement.
  • Added runaway detection for Gemini models to interrupt streams stuck in excessive planning steps.
  • Added a per-provider in-flight request limiter for LLM streams, shared across local OMP processes and configurable via maxInFlightRequests.
  • Added a credits field to UsageResetCredits to display when banked rate-limit resets expire, with support for OpenAI Codex usage details.

Changed

  • Optimized GitLab Duo Agent and Workflow providers to use an inline custom "ambient" flow with MCP-only agent privileges, registering MCP tools under their bare names.
  • Improved GitLab Duo Agent context management and auto-compaction by lowering the soft overflow threshold to 1 MB and stripping redundant bytes (such as tool-call UUIDs and escaped JSON) from the goal transcript.
  • Enhanced GitLab Duo Agent prompt engineering to render replayed tool calls as past-tense records, reducing model confusion and preventing the model from mimicking historical markers.
  • Added caching for discovered GitLab Duo Agent root namespaces per account to avoid redundant discovery requests.

Fixed

  • Fixed various GitLab Duo Agent and Workflow stability issues, including infinite tool-call loops, connection hangs on half-open WebSockets, and unhandled step-limit or generic server-side failures.
  • Improved GitLab Duo Workflow routing, namespace resolution, and project-path handling, ensuring correct numeric ID resolution and support for self-managed GitLab relative install base paths.
  • Fixed GitLab Duo Workflow checkpoint streaming to correctly map reasoning entries to thinking blocks, preserve tool boundaries, and accurately report token usage.
  • Fixed AuthStorage.login to only synthesize manual-code paste prompts for paste-code providers, preventing terminal-blocking races on loopback OAuth flows.
  • Fixed llama.cpp compatibility by downgrading named forced tool_choice objects to the string "required" in the chat-completions encoder.
  • Fixed omp usage omitting Ollama and Ollama Cloud accounts by registering placeholder usage providers.
  • Fixed Gemini reasoning-runaway detection to expose a dedicated thought-summary header guard to interrupt streams stuck in planning loops.

Removed

  • Removed legacy GitLab Duo Workflow chat and software_development flow paths and the non-MCP action bridge in favor of the inline custom ambient flow.

@oh-my-pi/pi-catalog

Added

  • Added GitLab Duo Agent catalog discovery, including namespace selection, live model mapping, and a bundled fallback model for fresh installs.
  • Added OpenAICompat.supportsNamedToolChoice to support forced tool use on string-only OpenAI-compatible chat servers without emitting the named function-object tool_choice shape.
  • Added model metadata support for provider-native remote compaction and compaction-only model selection.

Changed

  • Disabled the thinking-effort selector for GitLab Duo Agent models since the underlying platform parameters are server-fixed.

Fixed

  • Improved GitLab Duo Agent and Duo Workflow namespace and project discovery to robustly handle paginated groups, SSH remotes with custom ports, Git worktrees, self-managed GitLab instances with relative paths, and configuration via GITLAB_DUO_PROJECT_PATH or GITLAB_DUO_PROJECT_ID.
  • Fixed built-in LiteLLM discovery to prefer rich proxy metadata from management endpoints and avoid caching stale capability data.
  • Fixed GitLab Duo Workflow model specifications to resolve correct static context windows, enabling accurate context usage tracking and auto-compaction.

@oh-my-pi/pi-coding-agent

Breaking Changes

  • Renamed the search tool to grep and the find tool to glob. Existing user settings are automatically migrated to the new configuration keys.

Added

  • Added ssh://host/path support to read, search, and write tools for single text files and directory listings on pre-configured POSIX SSH hosts.
  • Added an interactive /move overlay with path autocompletion and directory creation prompts, starting a fresh session in the target directory while leaving the previous session resumable.
  • Added support for file deletion and moving within file editing operations.
  • Added providers.maxInFlightRequests setting to cap concurrent LLM requests per provider across local OMP processes.
  • Added support for discovery.type: litellm in models.yml to automatically discover model metadata from LiteLLM gateways.
  • Added models.yml configuration options remoteCompaction and compactionModel to run compaction on a separate model or opt into provider-native compaction.
  • Added project, user, and plugin-level dap.json and dap.yaml support for defining or overriding debugger adapters used by the debug tool.
  • Added TinyFish, DuckDuckGo, xAI, and Firecrawl web search providers.
  • Added an Appearance setting for OSC 9;4 native terminal progress indicators during active agent turns and context maintenance.
  • Added Loop Guard "Tool-Call Reminder" to automatically interrupt Gemini reasoning loops that generate excessive planning headers without acting.

Changed

  • Redesigned the persistent Todo HUD as a compact connector tree with fixed-budget stage previews
  • Anchored status and HUD containers to prevent redundant UI elements in terminal scrollback
  • Redesigned the persistent Todo HUD to render active stages as a connector tree, capping the number of displayed stages and tasks to keep the plan overview concise and stable.
  • Anchored the status row container directly between the HUD and the editor to prevent redundant UI elements from piling up in terminal scrollback.
  • Optimized edit tool UI: delete and single-file move operations now render as compact status rows
  • Improved terminal output for file-level edits (delete/move) to display accurate paths and state
  • Refined edit renderer to prevent misleading "No changes" messages in multi-file operations
  • Changed the inlineToolDescriptors setting from a boolean to a three-way enum (auto | on | off), defaulting to auto to inline descriptors only for Gemini models.
  • Added caching for successful document conversions (PDFs, Office documents, EPUBs) to avoid redundant conversions on repeated reads.
  • Moved the Working… activity indicator below the sticky todo and subagent HUDs so it sits just above the editor instead of floating atop the todo panel.

Fixed

  • Fixed Z.AI web search to initialize the Streamable HTTP MCP session before calling web_search_prime, preserving the returned session ID for authenticated tool calls. (#3619)
  • Fixed terminal hangs on Ctrl+Z (SIGTSTP) after running bash tool calls, and insulated MCP stdio servers from terminal job-control signals.
  • Fixed macOS Cmd+V silently dropping image-only clipboard pastes in supported terminals.
  • Fixed an infinite loop in auto-compaction when a single recent turn exceeded the compaction threshold.
  • Fixed an issue where the advisor could enter a spam loop of repeated blocker injections, polluting the transcript.
  • Fixed Claude API and Anthropic classifier refusals polluting the replayed session context or persisting as assistant dialogue.
  • Fixed MCP tool calls failing with strict-schema servers by stripping internal metadata fields at the MCP boundary.
  • Fixed a terminal freeze/hang when a subagent abort was triggered.
  • Fixed thinking blocks appearing in the UI when thinking level is "off" for providers that return them anyway.
  • Fixed GitLab Duo Agent namespace/project discovery and authentication flow hangs.
  • Hardened and improved ssh:// protocol handling, including support for IPv6 brackets, percent-encoded hosts, port validation, and POSIX shell restrictions, while preventing unsupported tools from attempting SSH connections.
  • Fixed TUI usage display fraction resolution and added expiry dates for banked Codex rate-limit resets to the /usage display.
  • Fixed a rendering issue where long-running SSH commands left stale pending headers in terminal scrollback.
  • Fixed garbled casing in auto-generated session titles by reconciling title tokens against the user's original messages.
  • Fixed IRC broadcasts rendering twice in the main agent's transcript.
  • Improved the persistent Todo HUD styling and progress indicators to make it self-describing and visually distinct.
  • Fixed browser screenshots reporting 0x0 dimensions when image headers expose real dimensions.
  • Fixed snapcompact compaction silently falling back to LLM summaries when local preflight rejects the archive.
  • Fixed snapcompact compaction silently falling back to an LLM summary when local preflight rejects the archive; manual and auto snapcompact now fail locally with the blocker instead of making provider calls. (#3599)
  • Fixed garbled casing in auto-generated session titles. normalizeGeneratedTitle (packages/coding-agent/src/tiny/text.ts) used to force Title Case via a \b\p{Ll} regex, capitalizing function words ("for" → "For") and amplifying stray model capitals ("dAemon" → "DAemon"). It now reconciles each title token against the user's own message: tokens typed verbatim are kept; proper nouns the user cased distinctively are restored when the model flattened them ("tinyvmm" → "TinyVMM"); lowercase words carrying a stray interior capital the user never wrote are flattened ("dAemon" → "daemon"); and model-cased PascalCase proper nouns ("GitHub", "OAuth") are left untouched. Restoration is limited to distinctively cased source tokens so a message that merely starts with "For" can't force a mid-title "for" to "For". Applies to both the local tiny-model and online pi/smol title paths.
  • Fixed IRC broadcasts (to: "all") rendering twice in the main agent's transcript. A subagent broadcast fans out one bus.send per live peer, and listVisibleTo always includes Main, so the main agent received the body once as its own irc:incoming card and once per other recipient as an irc:relay observation of the sibling legs (Sender → Other) — identical text shown N+1 times. IrcTool.#executeSend now sets suppressRelay on every broadcast leg when Main is among the targets (it already has the body via its direct incoming card), and IrcBus.send skips #relayToMainUi for suppressed legs. Direct sub→sub relays, direct messages to Main, and Main's own outbound sends are unaffected.
  • Fixed Claude API refusals polluting the replayed session context and causing later prompts to refuse again. (#3592)
  • Fixed browser screenshots reporting 0x0 dimensions when Bun.Image rejects an image whose PNG/JPEG header still exposes real dimensions. (#3577)
  • Fixed Anthropic classifier refusals being persisted as assistant dialogue after no fallback handled them; refusal stops are now displayed as errors but pruned from active and saved context before the next prompt. (#3591)
  • Fixed the eval tool.* bridge leaking the harness-internal i ("intent") field into MCP tools/call requests, so strict-schema servers (Linear, anything with additionalProperties:false / Zod .strict()) rejected every call with -32602 unrecognized_keys: ["i"] while the same call via the direct model tool-call path succeeded. MCPTool.execute / DeferredMCPTool.execute (packages/coding-agent/src/mcp/tool-bridge.ts) now strip INTENT_FIELD at the MCP boundary, so an MCP call behaves identically whether issued by the model directly or via the eval tool.* bridge; servers that legitimately declare i as a real parameter keep it untouched. (#3575)
  • Fixed the advisor entering a spam loop in which it emitted hundreds of repeated Stop., Done., and No issue; continue. <advisory severity="blocker"> injections, polluting the primary transcript and destabilizing the watched agent after the task was already complete. The advisor system prompt's rules ("at most one advise per update", "NEVER send the same advice twice") are now enforced in code by a new AdvisorEmissionGuard on the enqueueAdvice boundary in AgentSession: it normalizes each note (case-insensitive, punctuation-folded), drops content-free self-talk filler (stop/done/no issue continue/lgtm/etc.), dedupes by exact normalized text across the session (bounded FIFO history), and rate-limits to one accepted note per advisor model prompt cycle. Reset on advisor reset (compaction, session switch, /new) so a re-primed reviewer can re-raise old issues. (#3520)
  • Fixed auto-compaction thrashing on a session whose single most-recent kept turn already exceeds the compaction threshold. prepareCompaction keeps that turn verbatim (findCutPoint never cuts at tool results), so the rewritten context stays above threshold; the context-full / snapcompact success tail scheduled the agent-authored auto-continue (and the overflow/incomplete retry) unconditionally, so the next agent_end re-entered #checkCompaction over the same oversized tail and re-fired forever. This is the residual loop left after #3247 capped snapcompact's own frame projection — once the frame cap drops below one frame, snapcompact is skipped and the context-full summarizer path still made no headroom. #runAutoCompaction now gates the threshold auto-continue on a post-maintenance headroom check (#compactionCreatedHeadroom, sharing shake's COMPACTION_RECOVERY_BAND hysteresis from #2275) and the overflow/incomplete retry on a separate fit check (#compactionCreatedRetryFit, measured after the failed turn is dropped) so a recoverable overflow that fits the window still retries; when a pass frees too little for the relevant path it pauses automatic maintenance and emits a single warning instead of looping. The post-turn threshold check also ignores an assistant's stale pre-compaction usage so the scheduled auto-continue cannot re-trip on the kept assistant's old high token count. The headroom check now treats any residual at or below the recovery band as progress: the band sits strictly under the compaction threshold, so a stale/tool-output prune that already pushed the trigger sub-band no longer makes a residual that merely holds the line report a false "no progress" and suppress a valid auto-continue.
  • Fixed the advisor prompt allowing confident root-cause claims about tool-call arguments absent from its reviewed transcript, so timeout advice now has to cite observed fields instead of inventing mechanisms like paths[0] array flattening. (#3483)
  • Fixed eval agent() helper subagents remaining visible as idle/IRC-revivable peers after the helper call returns; one-shot eval subagents now dispose and unregister at completion. (#3407)
  • Fixed the parent interactive prompt wedging (frozen, 0% CPU) after a subagent's yield-triggered abort. The executor's abort monitor and abort listener each called session.abort() fire-and-forget, so runSubprocess could resolve and adopt the subagent before its abort cleanup finished clearing in-flight session state. Active-subagent aborts are now deduped through a single cached cleanup promise that the subprocess awaits (bounded) before finalizing. (#2805)
  • Fixed thinking blocks appearing in the UI when thinking level is "off". Some providers (MiniMax, GLM, DeepSeek) return thinking blocks even with reasoning disabled; thinking blocks are now auto-hidden when the thinking level is "off", regardless of the hideThinkingBlock setting. Toggling thinking block visibility while thinking is off shows a status message instead of silently no-op'ing. (#626)
  • Fixed the TUI usage display failing to resolve a used fraction for limits that only populate remainingFraction (no usedFraction, used/limit, or percent+used). The TUI's local resolveFraction was missing the inverted-remaining fallback that the shared resolveUsedFraction from @oh-my-pi/pi-ai already handles — replaced the local copy with the shared function so the TUI and CLI paths resolve fractions identically.
  • Fixed long-running SSH command boxes leaving a stale ⏳ SSH: [host] header above the final ⇄ SSH: [host] header in terminal scrollback. The SSH renderer now keeps its partial-result chrome on the pending icon/state and opts the block out of stream-commit while isPartial holds (via the new ToolRenderer.provisionalPartialResult flag honored by ToolExecutionComponent.isTranscriptBlockCommitStable), so the stable-prefix ratchet can't promote the partial header to native scrollback only to have the final render strand it above the settled frame (#3177).
  • Fixed Gemini over-planning runs that emit long chains of thinking headers (**Refining …**, ## Examining …) without ever issuing a tool call. The session now interrupts that stream, discards the partial reasoning turn, injects a hidden tool-call reminder, and continues with the corrective context instead of burning the full budget on planning.
  • Fixed Cmd+V on macOS silently dropping image-only clipboard pastes (screenshot via Cmd+Shift+5 "save to clipboard", Chrome image copy, …) — the user had to fall back to Ctrl+V. Follow-up to #3506: that fix handled clipboards exposing a file URL or path; the screenshot path leaves only raw image bytes on the pasteboard. macOS terminals (iTerm2, Terminal.app, Warp, Ghostty without OSC 5522, Windows Terminal forwarding, …) intercept Cmd+V and read NSPasteboardTypeString first; for an image-only clipboard that read returns "", so the terminal forwards a complete-but-empty bracketed paste (\x1b[200~\x1b[201~). CustomEditor.handleInput inserted the empty payload and the keystroke disappeared. CustomEditor now runs its own BracketedPasteHandler ahead of the inherited handler so the assembled paste payload is routed regardless of whether the start marker, payload, and end marker arrive in one stdin chunk or are fragmented across several (Windows Terminal under load, certain SSH muxes, tmux extended-keys passthrough, …). Strict-zero-length assembled payloads route to the same onPasteImage smart reader the app.clipboard.pasteImage keybind uses (attaches the clipboard image, or falls back to the #1628 smart text paste / "clipboard is empty" diagnostic); explicit image-file paths route to onPasteImagePath (the #3506 path also benefits from split-chunk assembly); everything else hands off to the base editor's pasteText so [Paste #N] markers, autocomplete, and undo state stay intact. Whitespace-only pastes are preserved as literal text. Trailing keystrokes that arrive in the same stdin read as the paste (a user hitting Enter right after Cmd+V) are queued behind the in-flight clipboard read and only dispatched once the image has reached pendingImages, so submit can't fire against an empty draft and leave the image stranded on the next prompt. (#3601)

@oh-my-pi/collab-web

Added

  • Added dedicated renderers for glob, grep, and legacy find and search tools to improve the readability of search and file discovery results.

@oh-my-pi/hashline

Added

  • Added REM (remove) and MV (move/rename) section operations to hashline patches, allowing files to be deleted or relocated (with snapshot history migration) directly within the edit tool.

@oh-my-pi/omp-stats

Added

  • Added a Gain tab to the omp stats dashboard (/#/gain) to display snapcompact token-savings with project scoping from synced session folders.

@oh-my-pi/pi-tui

Added

  • Added support for rendering HTML ,
    , and
    tags with proper theme styling, entity decoding, and layout consistency across Markdown transcripts, table cells, list items, and option labels.
  • Added first-class support for Warp terminal (TERM_PROGRAM=WarpTerminal), enabling true color, platform-specific Kitty graphics protocol negotiation for inline images, and safe defaults for OSC 8 hyperlinks and synchronized output.
  • Added SelectList.routeMouse() and shared SGR mouse input routing helpers to support fullscreen overlay hit-testing.

Fixed

  • Fixed issues where stray, unmatched, or raw HTML tags would leak into the rendered output.
  • Fixed render scheduling to yield behind queued terminal input, preventing delayed Escape key delivery during heavy streaming paints.

@oh-my-pi/pi-utils

Added

  • Added a relaxed JSON parser supporting single-quoted strings, unquoted keys, and comments.
  • Added parseStreamingJson and parseStreamingJsonThrottled for robust, efficient parsing of truncated or incremental streaming JSON.
  • Added an XDG-aware document conversion cache directory helper.
  • Exported removeWithRetries() as a standalone asynchronous function to handle retry-on-EBUSY cleanup logic.

Changed

  • Improved readSseJson to gracefully recover truncated or malformed final events using the streaming JSON parser, ending the stream cleanly instead of throwing.
  • Increased the retry delay for EBUSY file-lock errors from 25ms to 50ms (extending the total retry window to 2 seconds) to improve reliability on Windows.

What's Changed

  • fix(ai): send llama.cpp string tool_choice by @roboomp in #3596
  • test(utils): add contract tests for lang-from-path detection by @oldschoola in #3334
  • fix(coding-agent): dispose eval subagents after run by @korri123 in #3407
  • fix(advisor): ground hidden argument warnings by @roboomp in #3488
  • fix(advisor): enforce one-advise-per-update + dedupe + noise filter at enqueueAdvice boundary by @roboomp in #3523
  • fix(ai): surface Ollama usage accounts by @roboomp in #3558
  • fix(mcp): strip harness intent field at MCP tools/call boundary by @roboomp in #3584
  • fix(coding-agent): report screenshot fallback dimensions by @roboomp in #3585
  • fix(session): prune classifier refusals from context by @roboomp in #3594
  • fix(agent): stop replaying provider refusals by @roboomp in #3595
  • fix(compaction): keep snapcompact local on preflight failure by @roboomp in #3600
  • fix(tui): keep partial SSH headers pending by @roboomp in #3178
  • fix(tui): auto-hide thinking blocks when thinking level is off by @oldschoola in #3314
  • fix(usage): use shared resolveUsedFraction in TUI path, fixing missing remainingFraction fallback by @oldschoola in #3317
  • fix(usage): replace inline casts with typeof guards in TUI renderer by @oldschoola in #3318
  • fix(proxy): use side-channel Map for partialJson, eliminating as-any casts by @oldschoola in #3328
  • fix(utils): handle truncated JSON gracefully in readSseJson by @usr-bin-roygbiv in #3362
  • feat(omp): ssh:// URL support for read, search, and write by @zommiommy in #3553
  • feat(coding-agent): add directory tab completion for /move command by @KamijoToma in #2992
  • feat(debug): load user DAP adapter configs by @danzaio in #3025
  • feat(coding-agent): add native terminal progress setting by @lederniermagicien in #3056
  • feat(provider): add GitLab Duo Agent provider (Agent Platform) by @jiwangyihao in #3060
  • fix(compaction): enable custom provider remote compaction by @roboomp in #3106
  • fix(advisor): surface nested repo context by @oldschoola in #3156
  • feat(eval): added isolated/apply/merge options to agent() helper by @roboomp in #3205
  • fix(coding-agent): anchored todo HUD with borders and progress header by @roboomp in #3215
  • feat: add provider in-flight request limits by @H4vC in #3216
  • feat(coding-agent): cache successful document conversions by @wolfiesch in #3264
  • feat(usage): show expiry dates for banked Codex rate-limit resets by @oldschoola in #3343
  • fix(utils): export removeWithRetries + migrate 24 ai test files from fs.rm to retry-enabled cleanup by @oldschoola in #3347
  • fix: migrate coding-agent tests from fs.rm to removeWithRetries by @oldschoola in #3354
  • feat(move): interactive /move overlay with fresh session in target directory by @oldschoola in #3401
  • Shared TUI mouse-routing helpers and overlay selector migration by @wolfiesch in #3402
  • feat(tui): recognize Warp as a first-class terminal by @metaphorics in #3472
  • fix(tui): guard streaming Esc cancellation by @roboomp in #3496
  • fix(tui): surface running subagents in status line by @roboomp in #3501
  • feat(stats): gain dashboard — project filter, unparsed commands panel by @GratefulDave in #3543
  • (feat) add xai, ddg, firecrawl, and tinyfish as web_search providers by @zekdevs in #3572
  • feat(coding-agent): discover rich LiteLLM proxy metadata by @jdavv in #3574
  • fix(providers): initialize Z.AI MCP search session by @roboomp in #3620

New Contributors

  • @zommiommy made their first contribution in #3553
  • @zekdevs made their first contribution in #3572
  • @jdavv made their first contribution in #3574

Full Changelog: v16.1.23...v16.2.0

Don't miss a new oh-my-pi release

NewReleases is sending notifications on new releases.