github can1357/oh-my-pi v16.1.20

3 hours ago

@oh-my-pi/pi-ai

Fixed

  • Fixed Ollama/Ollama Cloud native chat responses that finish with done_reason: "length" and no assistant content surfacing as a normal empty stop; they now become a context-window error instead of entering empty-stop retry recovery. (#3464)
  • Fixed direct Anthropic Claude Sonnet/Haiku 4.5 requests serializing output_config.effort. The catalog classification (packages/catalog/src/model-thinking.ts) drove the anthropic-budget-effort branch in buildParams, which Anthropic's first-party Messages API rejects on Sonnet/Haiku 4.5 with HTTP 400 This model does not support the effort parameter. Sonnet/Haiku 4.5 now use plain thinking.budget_tokens; Opus 4.5 still emits output_config.effort because Anthropic supports it there. (#3497)

@oh-my-pi/pi-catalog

Fixed

  • Fixed direct Anthropic Claude Sonnet/Haiku 4.5 advisor/agent turns crashing every call with HTTP 400 This model does not support the effort parameter. The catalog classified the whole Claude 4.5 family on anthropic-messages (and bedrock-converse-stream) as anthropic-budget-effort, which made the Anthropic provider serialize output_config.effort alongside thinking.budget_tokens. Anthropic only honors output_config.effort on Opus 4.5 and adaptive (4.6+) Messages-API models, so Sonnet 4.5 / Haiku 4.5 rejected the field. inferThinkingControlMode now gates anthropic-budget-effort to parsedModel.kind === "opus" && semverGte(version, "4.5") on both Anthropic-routed APIs, so Sonnet 4.5 / Haiku 4.5 on direct Anthropic + Cloudflare-AI-Gateway + Vertex + GitLab-Duo + Copilot + Bedrock fall through to plain mode: "budget" (thinking budget still scales with the selected effort tier). Opus 4.5 keeps anthropic-budget-effort. anthropic-budget-effort also stays in use for Anthropic-compatible third-party backends that natively support the field (Umans GLM 5.2). (#3497)

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

Fixed

  • Fixed Ctrl+Z hanging the terminal after any tool call had run: the TUI tore down (ui.stop()) but the process kept running in Sl+ state, leaving the user with a dead terminal recoverable only via kill -9. The embedded brush-core shell behind every bash tool call installs a tokio SIGTSTP listener on Process::wait (crates/brush-core-vendored/src/sys/unix/signal.rs::tstp_signal_listenertokio::signal::unix::signal(SIGTSTP)); per tokio's contract, the first call for a SignalKind permanently replaces the kernel-default handler for the lifetime of the process. So the first bash invocation — even /usr/bin/true — silently overrode SIGTSTP's "stop" default, and InputController.handleCtrlZ's subsequent process.kill(0, "SIGTSTP") was swallowed by tokio. The handler now sends SIGSTOP (uncatchable, unblockable, unignorable) to the foreground process group, so the kernel parks omp regardless of installed handlers and the shell sees the whole job stop even when omp runs behind a wrapper (npx, pnpm exec, bunx, …) or as one stage of a pipeline. MCP stdio servers now spawn detached into their own session — they're insulated both from terminal job-control signals (which used to stop their process trees and leave the JSONL read loop blocked on silent pipes) and from the new pgid=0 suspend itself (#3461).
  • Fixed image-only composer submissions while the agent is streaming being treated as empty input, which dropped the image or aborted the active turn when another message was queued. Pending pasted images now count as submit content for Enter and Ctrl+Enter follow-ups. (#3467)
  • Fixed omp gallery --state accepting lifecycle tokens that did not match displayed state labels and rendering unknown state values as · undefined; displayed labels now work as aliases, invalid values fail with a valid-token list, and failed gallery fixtures visibly render failures. (#3473)
  • Fixed the bash tool's snapshotted mise() shell function dying with command: command not found: because $__MISE_EXE was empty in the replay shell. generateSnapshotScript captured the function via declare -f/typeset -f but only ever re-exported PATH, so every other env var the rc file set (notably the *_EXE sidecar mise activate exports) was lost; the function body then expanded command "$__MISE_EXE" "$@" to command "" … and died with exit 127. The snapshot script now scans captured function bodies for $VAR / ${VAR…} references and re-emits export NAME='value' for each referenced var that is currently set (with a denylist for shell-internal names like PATH/HOME/BASH_*/LC_* plus a likely-secret denylist for *TOKEN*/*SECRET*/*API_KEY*/*PASSWORD*/*PRIVATE_KEY*/*ACCESS_KEY*/*CREDENTIAL*/*SESSION_KEY*), the snapshot script umask 077s itself and the JS caller chmods the snapshot file/dir to 0600/0700 so the new export pass can't leak secrets into a shared tmp dir. Fixes mise, asdf shims, direnv-style helpers, and other activation idioms that pair a function with a helper env var. getShellConfigFile now also honours env.HOME (falling back to os.homedir()) so sandboxed callers can target a non-default rc. (#3470)
  • Fixed concise history:// transcript rendering for find and search so scoped paths arguments are visible instead of being hidden behind JSON fallback output or omitted when a search pattern is present. (#3482)
  • Fixed manual /compact leaving session.isCompacting false while active-turn abort teardown awaited, so the first steer/follow-up typed during compaction startup now routes through the compaction queue instead of being lost. (#3485)
  • Fixed ollama-cloud task/subagent fan-out exceeding the provider's three-request concurrency cap by adding a provider-specific subagent limiter, and let configured task/smol/advisor model roles inherit the default retry fallback chain when they do not define their own chain. (#3464)
  • Fixed the per-provider subagent concurrency limiter (e.g. providers.ollama-cloud.maxConcurrency) being replaced with a fresh semaphore whenever the configured limit changed, which orphaned the in-flight slots on the old instance and let a runtime or mixed limit value exceed the cap. The limiter now resizes a single shared semaphore in place — raising the ceiling admits queued waiters immediately, lowering it drains in-flight holders without admitting past the new cap. (#3464)
  • Fixed a background-task spawn slot leaking from the task.maxConcurrency limiter when progress reporting threw between acquiring the slot and entering the guarded run: markRunning/reportProgress now run inside the try whose finally releases the semaphore, so a failed progress report can no longer permanently shrink subagent concurrency. (#3464)
  • Fixed active goal runs that successfully call yield and then receive a trailing empty assistant stop skipping threshold compaction; post-yield empty-stop suppression now still anchors active-goal compaction on the yield-bearing assistant turn, so long-running tasks continue after maintenance instead of settling early.

@oh-my-pi/pi-tui

Fixed

  • Recognized Warp (TERM_PROGRAM=WarpTerminal) as a first-class terminal, enabling Kitty inline images on macOS/Linux while keeping Warp's unsafe OSC 8 hyperlinks and Windows Kitty graphics disabled (#3471).
  • Kept queued interrupt keys ahead of ordinary repaints so a slow long-transcript frame cannot consume the Ctrl+C/Esc double-press window before the second key is handled.

What's Changed

  • fix(coding-agent): switched ctrl-z handler to SIGSTOP-self to defeat brush tokio SIGTSTP hijack by @roboomp in #3463
  • fix(agent): handle ollama-cloud task backoff by @roboomp in #3466
  • fix(tui): queue image-only streaming submissions by @roboomp in #3468
  • fix(bash): re-export env vars referenced by snapshotted shell functions by @roboomp in #3474
  • fix(tui): recognize Warp terminal capabilities by @roboomp in #3475
  • fix(cli): align gallery state labels by @roboomp in #3477
  • fix(coding-agent): surface transcript search paths by @roboomp in #3486
  • fix(agent): queue input during manual compact startup by @roboomp in #3489
  • fix(catalog): classify direct Anthropic Claude 4.5 as plain budget thinking by @roboomp in #3498
  • Fix active goal compaction after yield stop by @cexll in #3428
  • fix(tui): keep interrupts ahead of repaint by @cexll in #3465

Full Changelog: v16.1.19...v16.1.20

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

NewReleases is sending notifications on new releases.