github can1357/oh-my-pi v17.1.6

latest release: v17.1.7
6 hours ago

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

Added

  • Added a pre-model-call gate: AgentLoopConfig.beforeModelCall receives the finalized provider context and run abort signal, and may return { stop: true, reason? } to end the run before the provider is called, so a host can refuse a request it has decided not to pay for (prompt no longer fits, budget boundary crossed, session should hand off). Agent.setBeforeModelCall installs the host callback; Agent.addBeforeModelCall registers an additional one without displacing it and returns a disposer. A gate-stopped run retains pending soft tool reminders/escalations and an unserved hard tool choice for the next admitted request; deferred choices are revalidated against active tools and cleared with queued session state (#6543 by @paralin).

Changed

  • Input message events (prompt, steering, soft reminders) are now emitted once provider-context preparation succeeds, so a pre-model gate can veto the request before any turn opens; gate-stopped and failed runs still commit their accepted inputs (#6543 by @paralin).

@oh-my-pi/pi-ai

Added

  • Added getProxyForUrl() for transports that need provider-specific and standard proxy environment resolution with NO_PROXY support (#6770).
  • Added SiliconFlow and SiliconFlow (China) to the built-in API-key login provider catalog so omp login siliconflow / omp login siliconflow-cn stores a reusable credential validated against each region's /v1/models endpoint.

@oh-my-pi/pi-catalog

Added

  • Added SiliconFlow providers (siliconflow, siliconflow-cn) with dynamic-only OpenAI-compatible model discovery: no bundled catalog — the model list is fetched live from each region's /v1/models endpoint, with non-chat entries (embedding, reranker, image, audio, video) filtered out. Discovery hydrates pricing, context/output limits, and reasoning metadata from the provider's models.dev catalog at runtime (with bundled upstream references as a reasoning-only fallback for ids models.dev has not indexed), so reasoning models keep thinking enabled and sessions compact against real context windows. SILICONFLOW_API_KEY / SILICONFLOW_CN_API_KEY environment variables are wired into getEnvApiKey.

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

Added

  • Added separate Advisor cost visibility to the status line, rendering primary and Advisor spend as $2.67 (sub) + $0.41 (adv) while keeping already-incurred Advisor cost across runtime disablement and same-session history rewrites.

Changed

  • Made the task tool's per-spawn effort parameter opt-in through task.enableEffort, which defaults to false and omits the field from flat and batch schemas and tool guidance until enabled.
  • Reduced terminal-title update overhead by deduplicating unchanged titles on every platform and using SetConsoleTitleW through bun:ffi instead of OSC writes on Windows. Windows working titles now keep a static : separator instead of scheduling spinner updates; other platforms retain the animated separator.
  • Added task.maxEffort to cap the task tool's optional per-spawn effort hint after model-specific resolution, so operators can enable effort hints without allowing them to exceed a configured ceiling; the ceiling now also rides into the spawned session so retry-fallback model swaps re-clamp to it instead of escalating past the cap (#6580, #6794 by @wolfiesch).
  • Restructured the steering/interjection envelope sent to the model: the injected <user_interjection>...<message>...</message>... wrapper around user text is now a <system-notice> explaining the interjection followed by the user's raw message unwrapped, matching the existing <system-notice>/<system-directive> convention instead of nesting the literal message inside its own tag pair, which some models found confusing.

Fixed

  • Fixed a disabled higher-priority MCP server no longer disabling a same-named lower-priority one: disabled servers are now suppressed after key-level dedupe instead of dropped before it, so a project foo with enabled: false keeps the user-level foo off while still not starving a differently-named equivalent connection.
  • Fixed the MCP tool-name collision winner flipping when the current owner reconnects: the winner is now chosen by a stable server+tool key instead of tool-array insertion order, which reconnects reorder.
  • Fixed MCP resources with custom URI schemes being treated as missing filesystem paths. read and omp read now resolve server-advertised native resource URIs such as ags://capabilities/current-host, while preserving the existing mcp://<resource-uri> form.
  • Fixed three gaps in native MCP resource URI resolution: server-advertised URIs whose path is exactly / (e.g. catalog://root/) are now preserved byte-for-byte instead of losing the trailing slash to reconstruction; opaque resource URIs (urn:example:document, custom:item) are recognized by the read and omp read resolver gates instead of falling through to filesystem handling; and a failing resources/templates/list no longer discards a successful resources/list, which previously produced a false missing-resource error.
  • Fixed custom LSP servers sending languageId: "plaintext" for extensions outside the built-in language map by honoring an optional per-server languageId in lsp.json for disk and in-memory document opens (#6800).
  • Fixed interactive extension confirmations ignoring dialogOptions, and cancelled handler-owned dialogs when the extension watchdog times out so stale approval UI cannot outlive a blocked tool call (#6805).
  • Fixed the per-handler extension context snapshotting the live ctx.model getter, so a handler calling pi.setModel() and then reading ctx.model saw the stale model; the scoped context now delegates to the base context instead of spreading it.
  • Fixed Python cell errors ($ commands and the eval tool) leaking runner-internal traceback frames. Cell syntax errors now render as the bare caret display with a <cell> filename instead of a _handle_request_async/ast.parse stack dump, and runtime tracebacks start at user code, matching the Ruby runner's user-frame filtering.
  • Dropped unavailable forced tool choices through the queue rejection lifecycle and discarded their remaining sequence yields so a skipped force cannot disable tools on the next request (#6543 by @paralin).
  • Fixed identical MCP server connections discovered under direct and marketplace-plugin names spawning twice and duplicating mounted tool routes; distinct tools whose server names sanitize to the same route now keep the first registration and log both origins (#6786).
  • Fixed /usage and the other large transcript command panels (/session, /advisor status, /jobs, /changelog, /context, /memory view) duplicating in native scrollback when invoked while an agent turn is streaming. These callsites mounted their finalized panel immediately via present() instead of deferring it until the turn ends via presentCommandOutput() (the path added in #5427 for /tools//mcp), so the panel landed above a still-growing live block and was recommitted lower down (#6767).
  • Fixed plan-mode task subagents unregistering extension-provided models, credentials, managers, and custom APIs from the shared parent ModelRegistry when restricted sessions intentionally skip extension loading (#6783).
  • Fixed /live sideband WebSockets ignoring standard proxy environment variables and NO_PROXY, which left proxied sessions stuck while the rest of the Codex connection succeeded (#6770).
  • Fixed the bash tool's kill builtin rejecting numeric signals and multiple process operands, stopping after the first failed target, and defaulting to SIGKILL instead of the standard SIGTERM. Negative PID operands (process groups per kill(2)) and the -- end-of-options marker are now handled instead of being misparsed as signals (#6779).
  • Fixed learned.md saves growing a blank line on every write (trailing-newline split artifact) and hoisting all headings/prose above all bullets, which re-scoped lessons under the wrong heading in hand-organized files. Saves are now byte-idempotent and preserve mixed Markdown ordering: non-list lines keep their positions, new lessons insert newest-first at the head of the first bullet run, and dedupe/cap operate on bullet lines in place.

@oh-my-pi/pi-natives

Changed

  • Native addons now build with Bazel (rules_rust + hermetic zig cc toolchains for linux-gnu/musl, host Xcode for darwin, and a hermetic clang-cl + xwin toolchain for windows-msvc) instead of the napi CLI + cargo-zigbuild/cargo-xwin pipeline. bun run build drives scripts/bazel-natives.ts; TypeScript binding regeneration moved to bun run build:bindings (needed only when the Rust API surface changes). CI caches through a content-addressed bazel-remote action cache instead of sccache + target-directory snapshots, cutting warm native rebuilds from ~20 minutes to seconds and cold cache-hit builds to ~2.5 minutes.

Fixed

  • napi binding build failures now surface the exit code and the tail of stdout/stderr instead of a bare "napi build failed" message (#6799).
  • Silenced cross-platform Rust build warnings: dead-code on unix-only fields/helpers in pi-uutils-ctx, pi-shell (fd owner filters, coreutils argv), and vendored uu-find/uu-stat when compiling for Windows, and deprecated libc::time_t casts in pi-iso on musl. pi-walker now declares the windows-sys features it uses (Win32_Foundation, Win32_Security, Win32_Storage_FileSystem, Win32_System_IO) instead of relying on workspace-wide feature unification.

@oh-my-pi/pi-tui

Fixed

  • Fixed omp dying with an uncaught setRawMode failed with errno: 2 instead of exiting 129 when the terminal disconnects. A recycled terminal pane revokes the pty, so the raw-mode restore in stop() hit an fd that is no longer a tty; the throw escaped #markTerminalDisconnected() and preempted its own SIGHUP. Terminal teardown on the disconnect path is now best-effort, matching emergencyTerminalRestore(), so the exit added in #5837 always runs.
  • Fixed the multi-line prompt editor bypassing the keybindings registry for word/line delete and yank: ctrl+backspace (a declared default of tui.editor.deleteWordBackward) never fired and keybindings.yml remaps of deleteWordBackward, deleteWordForward, deleteToLineStart, deleteToLineEnd, yank, and yankPop were ignored, because those actions were matched with hardcoded chords instead of keybindings.matches(...) like cursor motion and the single-line Input already do (#6782).
  • Restored the Windows Terminal raw 0x08ctrl+backspace disambiguation (WT_SESSION set, SSH_* unset) by routing the exported matchesRawBackspace helper through the matchesKey/parseKey seam. Remote SSH/container sessions where terminal identity is unavailable can opt in with PI_TUI_RAW_BACKSPACE_IS_CTRL=1 (#6782).
  • Fixed plain Backspace deleting a whole word inside tmux/GNU screen/Zellij panes launched from Windows Terminal: multiplexers inherit WT_SESSION but emit raw 0x08 for plain Backspace, so the automatic raw-backspace → ctrl+backspace heuristic misfired. The heuristic now skips multiplexer sessions (TMUX/STY/ZELLIJ or TERM starting with tmux/screen); PI_TUI_RAW_BACKSPACE_IS_CTRL=1 remains the explicit opt-in everywhere (#6784).

What's Changed

  • feat(agent): add a pre-model-call gate that can stop the turn by @paralin in #6543
  • feat(catalog,ai): add SiliconFlow providers with dynamic-only model discovery by @iacore in #6765
  • fix(tui): defer large command panels during streaming to stop scrollback dupes by @roboomp in #6768
  • fix(live): honor standard proxies for sideband websocket by @roboomp in #6773
  • fix(memories): preserve non-list learned content by @isaac-sun in #6774
  • test(coding-agent): decouple changelog bundle probe from native addon resolution by @wolfiesch in #6778
  • fix(shell): correct kill signal handling by @roboomp in #6780
  • fix(tui): route editor word delete through keybindings registry by @roboomp in #6784
  • fix(coding-agent): preserve extension providers for plan subagents by @roboomp in #6785
  • fix(mcp): deduplicate aliased server connections by @roboomp in #6787
  • fix(tui): don't crash on teardown when the pty is already gone by @dergachoff in #6788
  • fix(mcp): resolve native resource URIs by @FernandeZ-hjm in #6790
  • feat(task): add per-spawn effort ceiling by @wolfiesch in #6794
  • fix(natives): surface exit code and stdout in napi build error by @roboomp in #6799
  • fix(lsp): honor custom server language ids by @roboomp in #6802
  • fix(extensions): cancel timed-out handler dialogs by @roboomp in #6806

New Contributors

Full Changelog: v17.1.5...v17.1.6

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

NewReleases is sending notifications on new releases.