github can1357/oh-my-pi v18.12.0

3 hours ago

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

Fixed

  • Fixed Cursor turns failing with PROVIDER_ERROR when a follow-up (a finished background job, a late diagnostic, a reminder) arrived while the previous turn was still streaming (#15821 by @robfeldmann)

@oh-my-pi/pi-ai

Breaking Changes

  • PI_CODEX_ZSTD is replaced by PI_REQUEST_COMPRESSION; set PI_REQUEST_COMPRESSION=0 to send Codex (and every other) request body uncompressed (#16086 by @H4vC)

Added

  • Added ThinkingContent.narration, set on Anthropic and Bedrock thinking blocks whose signature marks them as between-tool narration, and presentNarrationAsAnswer(message) to show those blocks as reply text while replay keeps them as signed thinking
  • Added keys.peek(provider, { includeExpired: true }) to name the stored account behind an expired OAuth token for reads that never send it, such as keying an offline model-cache lookup (#16061 by @gchai)
  • Added prewarmModelConnection(model) (providers/connection-prewarm), which opens the model's API connection ahead of a request using the same transport and TLS settings so the request reuses it instead of paying the connection handshake (#16086 by @H4vC)

Changed

  • Anthropic requests to the official API now gzip the request body, so long conversations reach the model sooner on slow uplinks; set PI_REQUEST_COMPRESSION=0 to disable it (#16044 by @H4vC)
  • GitHub Copilot requests (chat completions, Responses, and Claude messages) now send zstd-compressed bodies, cutting upload size by roughly 60–75% on long conversations; set PI_REQUEST_COMPRESSION=0 to disable it (#16086 by @H4vC)
  • A rejected request-body encoding now only disables compression for that host, and only after the uncompressed resend succeeds, so a genuine 400 no longer turns compression off (#16086 by @H4vC)
  • Connection warm-up now covers every catalog provider, not only the official Anthropic API: it re-warms the origin a model's requests actually reach (Copilot plan hosts, MOONSHOT_BASE_URL, regional hosts), throttled per host; custom providers, built-in provider ids routed to a gateway, local hosts, and Anthropic gateways are never probed (#16086 by @H4vC)

Fixed

  • Fixed Ollama and Ollama Cloud streaming errors being silently accepted as successful responses (#16039 by @mottopanikeiku)
  • Fixed the hermes in-band scanner exposing a truncated tool name for streaming tool calls: toolStart now waits for the complete JSON name, so a stream that splits or stops mid-name never reports a partial tool name (#16064 by @adi-IL)
  • Fixed keys.peek() rotating through stored accounts on each call; it now returns the first account whose token has not expired, every time, so model discovery keeps reading one account's cached catalog (#16061 by @gchai)
  • Fixed local JSON Schema references with URI-percent-encoded, JSON Pointer-escaped, or empty definition names resolving incorrectly during dereferencing, strict conversion, and value validation (#15926 by @jchanghong023).
  • Fixed network failures showing a generic "Connection error."; offline, connection-refused, and TLS-verification failures now name the host and the cause (#16036 by @jorgoose)
  • Fixed Jev image limits rejecting inputs for unrelated native judges and redundant TypeSafe image judgments when only detail changes (#16002 by @anatoli-tsinovoy).
  • Fixed SIGTERM interrupting an in-flight OAuth token rotation before its replacement refresh token was saved (#15845).
  • Fixed sessions getting stuck on HTTP 400 after replaying tool names unsupported by the target provider, including invented proc://* calls and Google tool names sent to Bedrock (#15839)

@oh-my-pi/pi-catalog

Added

  • Added the request-encodings, request-encoding-rejection, and endpoint-hosts rule axes, resolveRequestCompression(model, url), and isCatalogEndpointUrl(model, url), declaring which providers' own endpoints decode compressed request bodies: official Anthropic API (gzip), Codex backend (zstd), and GitHub Copilot's API hosts (zstd, then gzip); Moonshot's China host counts as its own endpoint (#16086 by @H4vC)

Changed

  • Bundled GPT-5.4 rows on OpenAI, Azure, OpenCode Zen, and Command Code report a 1M context window, the window the coding agent already applied at runtime; GitHub Copilot and Factory Droid keep their own windows (#16094 by @H4vC)

Fixed

  • Fixed custom providers that declare a built-in providerType (Azure, GitHub Copilot, OpenCode, ClinePass, DeepSeek, NVIDIA) missing that provider's wire quirks, such as strict Responses pairing and the ClinePass reasoning field: they now follow the same catalog rules as the built-in provider (#16093 by @H4vC)
  • Fixed OpenCode Zen bringing back its retired bundled models after a failed refresh: the retry-backoff write no longer drops the cached snapshot's retention, so the pruned catalog survives the retry window and offline launches. (#16054 by @adi-IL)
  • Fixed providers.cacheWarming never arming for Claude on Google Antigravity: Claude models there now declare Vertex Anthropic's five-minute prompt-cache lifetime; Gemini models stay unwarmed because Google's implicit cache has no fixed lifetime (#15764, #16025 by @harshaygadekar)
  • Scoped Jev image bounds to the selected models instead of applying them to unrelated native judges (#16002 by @anatoli-tsinovoy)
  • Fixed Bedrock sessions rejecting replayed tool names over 64 characters after a model switch (#15839)

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

Added

  • Added statusLine.segmentOptions.pi.showProfile: set it to false to hide the profile name next to the π brand, for example when each profile already has its own theme (#16063 by @shgew)
  • Added sharpshooter.minPromptLength (default 16, minimum 2) to control the shortest prompt Sharpshooter extracts decisions from (#16043 by @bigHippoZz)

Changed

  • With a first-party Anthropic model on the official API selected, the interactive UI opens the API connection at startup, on model switch, and when you start typing, so the next turn skips connection setup; third-party gateways and custom endpoints are never probed (#16044 by @H4vC)
  • The API connection warm-up now covers every built-in provider (Copilot, OpenAI, Gemini, OpenRouter, …), not only Anthropic: between turns it keeps the connection your last request used open, through the configured proxy and CA settings, so the next turn skips connection setup; custom models.yml providers, built-in providers pointed at a gateway, and local servers are never probed (#16086 by @H4vC)
  • Snapcompact now shows an imaged read result's indentation as count brackets ([»2] two tabs, [·4] four spaces) and keeps its [path#TAG] header as text, so edits from imaged reads keep the right indentation and tag (#15899 by @apoc)
  • A custom model's explicit contextWindow or maxTokens in models.yml now wins over the catalog's limit rules for that model id, which previously overwrote it (#16094 by @H4vC)

Fixed

  • Fixed Claude Opus 5.5 replies sent between tool calls (for example an answer to a question asked mid-task) being folded into the "Thought" block; they now show as normal reply text in the transcript, print mode, ACP clients, and HTML exports
  • Fixed the shell's du --time=ctime (also status) printing ??? on Windows; it now shows the last write time, as stat already does for the status-change time
  • Fixed the shell's rmdir dir/. on Windows removing dir (and rmdir x/.. the parent); like POSIX it now fails with Invalid argument / Directory not empty
  • Fixed the shell's dd if=DIR on Windows failing with failed to open ...: Permission denied; like POSIX it now opens the directory and reports error reading ...: Is a directory with the transfer statistics
  • Fixed the LSP mux returning from shutdown before its language-server children exited, and spawning a duplicate language server when a session reconnected while the previous one was still closing its documents
  • Fixed the startup connection warm-up silently doing nothing on Windows, where Bun's fetch.preconnect throws (#16086 by @H4vC)
  • Fixed the RPC frame codec (modes/rpc/rpc-frame) failing to bundle for Node because it pulled in Bun-only modules and the native addon (#16072 by @oyty)
  • Fixed auth-gateway strict probes sending a raw token instead of the structured credential blob for Alibaba Coding Plan and Snowflake logins (#16092 by @H4vC)
  • Fixed a prompt sent while Esc was still interrupting the previous turn never settling, so a message steered in as it ended stayed queued instead of running (#16038 by @will-bogusz)
  • Fixed isolated tasks freezing the host when the checkout holds linked worktrees of the same repository (e.g. gitignored .claude/worktrees/); those worktrees are no longer snapshotted as nested repos (#16068)
  • Fixed edit moves dropping executable permissions in hashline, patch, and apply_patch modes (#16042 by @mottopanikeiku)
  • Fixed leaving a subagent view before its transcript finished replaying leaving rows of both sessions on screen, dropping the start of one, and clearing native scrollback twice; transcript rebuilds now run one at a time and a superseded rebuild is discarded without painting (#16066 by @cagedbird043)
  • Fixed Cursor task subagents losing their final report when it follows tool calls in the same turn (#16059).
  • Fixed SQLite read continuation hints dropping filters and sort order or truncating the next-page selector (#16040 by @mottopanikeiku)
  • Fixed SQLite table reads omitting generated columns from sample rows and query results, and rejecting sort orders on those columns (#16041 by @mottopanikeiku)
  • Fixed video timestamp selectors (clip.mp4:2s, clip.mp4:0:05) failing for files outside the session cwd, which also reported a colon-mangled path when the video was missing. (#16056 by @adi-IL)
  • Fixed recovery of hashed session directories for projects under a temporary directory inside home, including the default Windows temp directory (#15929 by @jchanghong023).
  • Fixed approval prompts for xd:// device dispatches and direct MCP tools to show readable, indented arguments with multiline content expanded into blocks (#15589, #16048 by @KunoLu).
  • Fixed retry.fallbackChains warning "references unknown model" at startup for models a discovery provider loads once its background refresh finishes (e.g. Copilot and Cursor -1m variants); a model still missing after discovery is warned about once (#16061 by @gchai)
  • Fixed GitHub Copilot models that only discovery lists (e.g. -1m variants) going missing at startup when two Copilot accounts are signed in (#16061 by @gchai)
  • Fixed Cursor models that only discovery lists (e.g. -1m variants) staying unavailable at startup until a background refresh whenever the stored Cursor access token had expired; the startup cache read now uses the same account key as the discovery write (#16061 by @gchai)
  • Fixed var declared inside a top-level control block disappearing after an awaited JavaScript Eval cell (#15859).
  • Fixed the eval runtime-state reminder omitting live Python kernels, so retained Python state no longer reads as dead or absent; Python kernels are listed with their generation, alive/dead status, and %load scripts like JavaScript kernels (#16032).
  • Fixed a browser call hanging for about 21 s, and its tab staying listed but dead, when the tab's worker crashed (such as on an error inside Puppeteer): the call fails at once with the cause and the next call continues on the same page (#16037 by @alnaggar-dev and @will-bogusz)
  • Fixed /restart losing explicitly opened session files outside the default session directories by resuming the persisted file directly (#16030 by @appboypov)
  • Fixed a failed todo call's hidden reminder resurfacing on the next prompt with an outdated list after the agent had already retried successfully (#16001)
  • Fixed TypeSafe image-cache reuse when only ignored image detail changes (#16002 by @anatoli-tsinovoy)
  • Fixed ssh:// ignoring a ControlPath from ~/.ssh/config, so it now reuses an already-authenticated master (e.g. on MFA/keyboard-interactive hosts) instead of failing with Permission denied (#15974)
  • Fixed --session-dir <dir> --resume <id> not finding a transcript that is a symlink in that directory, the session lists and id-prefix lookups skipping symlinked transcripts the same way, and a resume that must rewrite such a transcript replacing the link instead of updating the file it points at; a project bucket that is itself a symlink is no longer traversed, so a scan cannot leave the sessions root and no session is listed twice (#15878, #15882 by @AnxForever)
  • Fixed restarting an interactive session with SIGTERM disabling a rotating Anthropic OAuth login and requiring /login again (#15845).
  • Fixed URL read dropping everything past 500,000 characters: tail selectors, URL grep, and the linked full-output artifact now reach the whole response body (#15768).
  • Fixed find (tool and omp find) reporting "no hits" when every judge request failed; it now reports find unavailable with a hint to use grep, flags partial runs with how many judge requests failed, and exposes the status as coverage in its details and --json output (#15744)
  • Fixed resumed sessions with eval history (--continue, --resume) missing the prompt cache after the previous process's first request (#15736)
  • Fixed a failed streamed edit preview ending the whole run without retry: the harness now re-drives the turn with the preview diagnostic so the model can read the file again and correct the patch, and gives up with a notice only after two recoveries
  • Fixed MCP OAuth login requesting every scope in an authorization server's catalogue when the protected resource advertises no scopes; /mcp reauth now falls back to configured scopes or authorization-server defaults (#15996 by @unclesamwk).
  • Fixed the incomplete-todo stop reminder firing (and resuming work) when the agent's final message asks for permission or a decision before a closing status line, through "If you confirm, I'll…"/"Separately, tell me…"-style requests, or with a non-English question followed by another sentence (#15986)

@oh-my-pi/pi-natives

Breaking Changes

  • encodeSixel and encodeSixelAsync now require a fourth terminal-background RGB argument packed as 0xRRGGBB (#15891 by @Bouska).

Fixed

  • Fixed Windows file-lock contention returning permission errors when an existing lease allows synchronization but not full mutex access (#15930 by @jchanghong023).
  • Fixed SIXEL images dropping translucent details or showing dark, discolored edges when resized, while preserving fully transparent pixels (#15891 by @Bouska).

@oh-my-pi/omptype

Fixed

  • Fixed TypeBox numeric bounds written in exponent notation throwing during schema construction, while preserving validation and nested JSON Schema constraints (#15925 by @jchanghong023).
  • Fixed importing local JSON Schema definition references containing URI percent encoding or JSON Pointer escapes (#15926 by @jchanghong023).

@oh-my-pi/omp-stats

Fixed

  • Fixed usage stats pricing Google Antigravity and MiniMax Token Plan models at $0 when their catalog rows carry no price; they now use the catalog's pricing peer, as xai-oauth already did (#16092 by @H4vC)

@oh-my-pi/pi-tui

Breaking Changes

  • FindStats.errors is replaced by failed (judge requests that failed) and unanswered (unusable answers), and FindToolDetails requires a coverage status; the find renderer shows N/M requests failed (#15744)

Added

  • Added pi.showProfile to StatusLineSegmentOptions: false keeps the pi segment's bare glyph under a named profile, in the rendered bar and in describe (#16063 by @shgew)

Fixed

  • Fixed sessions run inside tmux silently falling back to the terminal's true-color profile when the client terminal-type probe answered slowly on a loaded machine (#16020 by @CharleoYang)
  • Fixed the read result notice printing the absolute resolved path, so a file under the home directory reads Resolved path: ~/notes.txt instead of /home/you/notes.txt (#16055 by @adi-IL).
  • Fixed grep/read previews and other tool cards passing raw escape sequences from file contents to the terminal, which could switch it to the alternate screen with mouse reporting on, live and again on every resume (#15963)
  • Fixed a final status-line render after shutdown scheduling another usage refresh (#15845).
  • Fixed Ctrl+O on LSP status and other plain LSP responses still clipping every row at 80 columns; expanded rows now wrap to show the full text (#15824)
  • Fixed Ctrl+O leaving long rows clipped in expanded LSP, debug, MCP, web search fallback, yield, task and custom-tool results; expanded rows now wrap to show the full text, expanded LSP references list every location, and the LSP expand hint no longer appears when nothing is hidden (#15824)
  • Fixed jagged text and disappearing translucent details in SIXEL images, including re-encoding when the terminal reports a changed background color (#15891 by @Bouska).
  • Fixed stale SIXEL backgrounds after terminal restarts, native appearance changes, and failed TSP handshakes, including background changes during the handshake, fixed themes, missing or invalid startup themes, or identical light/dark mappings (#15891 by @Bouska).

@oh-my-pi/pi-utils

Added

  • Added sanitizeTextDeep(), which applies sanitizeText() to every string in a JSON-shaped value without mutating it (#15963)

Fixed

  • Fixed Windows archive extraction overwriting existing files or following existing symlinks when copying a symlink entry without symlink privileges (#15931 by @jchanghong023).

What's Changed

  • anthropic gzip and prewarmed connection by @H4vC in #16044
  • fix(tui): composite SIXEL transparency against terminal backgrounds by @Bouska in #15891
  • fix(coding-agent): run transcript rebuilds one at a time and drop superseded ones by @cagedbird043 in #16066
  • fix(coding-agent): settle a turn begun while an interrupt is finishing by @will-bogusz in #16038
  • fix(ai): surface Ollama in-band streaming errors by @mottopanikeiku in #16039
  • fix(coding-agent): keep file permissions when edit moves a file by @mottopanikeiku in #16042
  • fix(task): preserved cursor final reports after tool calls by @roboomp in #16060
  • fix(task): skipped in-tree linked worktrees in nested-repo baseline by @roboomp in #16069
  • fix(omptype): validate exponent-form numeric bounds by @jchanghong023 in #15925
  • fix(coding-agent): migrate hashed home sessions shadowed by temp by @jchanghong023 in #15929
  • fix(natives): request only synchronization access for file leases by @jchanghong023 in #15930
  • fix(utils): preserve exclusive destinations in archive symlink fallback by @jchanghong023 in #15931
  • fix(coding-agent): suppressed todo reminder for closing user requests by @roboomp in #15991
  • fix(catalog): declare Vertex's prompt-cache lifetime for Claude on Google Antigravity by @harshaygadekar in #16025
  • fix(coding-agent): keep where and order in SQLite next-page hints by @mottopanikeiku in #16040
  • fix(coding-agent): include generated columns in SQLite table reads by @mottopanikeiku in #16041
  • fix(catalog): keep authoritative cache retention across a failed refresh by @adi-IL in #16054
  • fix(tui): shorten the resolved path in the read result notice by @adi-IL in #16055
  • fix(coding-agent): resolve video timestamp selectors outside the session cwd by @adi-IL in #16056
  • fix(ai): require a complete tool name before hermes in-band toolStart by @adi-IL in #16064
  • fix(tui): widened the tmux client-termtype probe budget to 2s by @CharleoYang in #16020
  • fix(schema): decode URI-fragment definition references by @jchanghong023 in #15926
  • fix(ssh): reused ssh_config ControlPath for ssh:// connections by @roboomp in #15976
  • fix(session): dropped stale todo-error reminders after successful retry by @roboomp in #16003
  • Resume persisted session files on restart (WORK-1187) by @appboypov in #16030
  • fix(eval): reported retained python kernels to the eval state registry by @roboomp in #16035
  • fix(ai): name offline/DNS failures instead of a generic Connection error by @jorgoose in #16036
  • fix(browser): reattach a tab whose worker exits unexpectedly by @will-bogusz in #16037
  • fix(ai,coding-agent): stop spurious fallback-chain "unknown model" warnings at startup by @gchai in #16061
  • fix(session): persisted the startup eval-state-context snapshot by @roboomp in #15743
  • fix(find): reported unavailable when every judge request failed by @roboomp in #15747
  • fix(coding-agent): kept url read bodies whole past 500k chars by @roboomp in #15786
  • fix(coding-agent): re-drive the turn after a failed streamed edit preview by @chefnaphtha in #15790
  • fix(agent): kept Cursor tool results in context for in-run follow-ups by @robfeldmann in #15821
  • fix(tui): revealed full rows in expanded tool results by @roboomp in #15829
  • fix(ai): dropped replayed tool calls with undeclarable name characters by @roboomp in #15840
  • fix(auth): preserved rotated oauth tokens on sigterm by @roboomp in #15849
  • fix(eval): preserved block var bindings across awaited cells by @roboomp in #15863
  • fix(session): found transcripts that are symlinks in a session directory by @AnxForever in #15882
  • feat(coding-agent): encode read indentation in snapcompact frames by @apoc in #15899
  • fix(tui): stripped control sequences from tool result details by @roboomp in #15964
  • fix(judgment): scope Jev limits and reuse TypeSafe image cache by @anatoli-tsinovoy in #16002
  • fix(coding-agent): show readable device and MCP approval arguments by @KunoLu in #16048
  • fix(mcp): avoid requesting OAuth scope catalogues by @unclesamwk in #15996
  • feat(tui): added segmentOptions.pi.showProfile to hide the profile tag by @shgew in #16063
  • feat(coding-agent): make Sharpshooter's prompt-length gate configurable by @bigHippoZz in #16043
  • fix(coding-agent): import isRecord from pi-utils/type-guards in rpc-frame by @oyty in #16072
  • feat(ai): KDL-driven request compression and connection prewarm for catalog providers by @H4vC in #16086
  • refactor: read duplicated model/provider policy from existing KDL rules by @H4vC in #16092
  • refactor(catalog): move hard-coded provider wire quirks into KDL rules by @H4vC in #16093
  • refactor: move literal model-id policy and role default chains into KDL by @H4vC in #16094

New Contributors

Full Changelog: v18.11.3...v18.12.0

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

NewReleases is sending notifications on new releases.