github can1357/oh-my-pi v17.1.2

6 hours ago

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

Added

  • Added resolveFallbackTool option to allow routing unadvertised tool calls to host-side transports (e.g., device mounts)

@oh-my-pi/pi-ai

Added

  • Added GET /v1/usage/history to the auth broker (recorded usage-limit snapshots with sinceMs/provider filters) and AuthBrokerClient.fetchUsageHistory — in broker deployments the broker host performs every upstream usage fetch, so its durable history is the only complete utilization record
  • Added per-client burn tracking to the auth broker: clients batch observed request usage per (provider, model) and flush it to POST /v1/usage/observed every 10 seconds (install id as client key, hostname as display name); the broker persists 5-minute buckets in client_usage/clients and serves aggregates from GET /v1/usage/clients. Brokers without the endpoint disable reporting for the process lifetime

Changed

  • Renamed the Z.AI feature quota row to ZAI Zread Quota (tier/id slug zread), replacing the 74-char ZAI Web Search / Reader / Zread Quota (web-search-reader-zread) title that wrapped omp usage rows

Fixed

  • Fixed every Claude (anthropic-messages) model on the opencode-zen provider failing with 401 Missing API key: the gateway requires x-api-key, so opencode-zen now uses X-Api-Key auth like opencode-go/umans instead of bearer-only, and no longer sends the context_management field its Anthropic proxy rejects on thinking requests (#6510).
  • Fixed Anthropic native server-tool blocks being dropped from persisted assistant turns, preserving signed web-search continuations in their original response order (#6495)

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

Added

  • Added in-process moreutils-style shell builtins to the bash tool's embedded shell: ts (timestamp lines; -i/-s elapsed modes, -m monotonic clock, -r relative rewriting of RFC3339/syslog timestamps, %.S/%.s/%.T subsecond extensions), sponge (soak stdin fully before atomically writing the target, so foo file | ... | sponge file works; -a appends), ifne (run a command only when stdin is non-empty; -n inverts and passes non-empty stdin through), isutf8 (streaming UTF-8 validation with line/char/byte diagnostics; -q, -l, -i), combine (boolean and/not/or/xor on the lines of two files, - for stdin), and errno (errno name/number/description lookup with -l list and -s search; unix only). Like the uutils-backed builtins, they run in-process against the command's own stdio, resolve paths against the shell working directory, honor cancellation, and are disabled by PI_DISABLE_UUTILS_BUILTINS.
  • The bash tool prompt now lists the available shell builtins (mkdir through jq, rm/mv/ln, and the moreutils set) so the model relies on them without existence checks; the line is dropped when PI_DISABLE_UUTILS_BUILTINS disables the builtins and omits unix-only errno on Windows.
  • Sessions using a broker-backed auth store now report each completed request's token usage and cost to the auth broker (batched, 10s cadence) so the broker can track actual token burn per client install
  • Added a per-spawn effort parameter to the task tool ("lo" | "med" | "hi"): each selector maps onto the resolved model's supported thinking range (lowest, middle, and highest level — whatever the model tops out at, e.g. high, xhigh, or max) and overrides the agent's default selector, including auto. Omitting effort keeps the existing automatic per-prompt thinking classification.
  • Added searxng.engines setting for the SearXNG web search provider: a comma-separated list of engine names or bang shortcuts (e.g. ddg, br, startpage) sent as the API's engines= parameter. Shortcuts are resolved to canonical engine names via the instance's /config endpoint (cached per endpoint; entries pass through verbatim if /config is unreachable). Bang syntax in queries (!ddg foo) continues to pass through to the instance, and external bangs (!!g) are now stripped client-side since SearXNG answers them with an HTTP redirect even for JSON requests.
  • Web search queries now understand Google-style directives on every provider: site:/-site: (plus domain:/host: aliases), after:/before:/since:/until: date bounds, inurl:/intitle:/intext:/allin*:, filetype:/ext:, lang:, quoted phrases (including smart quotes), +term, -/NOT exclusions, and OR/| groups. A shared parser (web/search/query.ts) structures the query once per request; each provider maps constraints onto native API filters where the upstream supports them (Perplexity domain/date/language filters on both the API-key and ask paths, Tavily include_domains/exclude_domains + start_date/end_date, Exa domain lists + published-date bounds on API and MCP paths, Anthropic allowed_domains/blocked_domains, xAI filters.allowed_domains/excluded_domains, Parallel source_policy, Brave absolute freshness ranges, Firecrawl tbs=cdr date ranges, Jina X-Site, SearXNG language) and otherwise re-emits only the operator syntax its engine parses (full Google syntax for Gemini grounding, OpenAI, Kagi, and the credential-free scrapers — with scraper-hostile path-site:/inurl: operators demoted to plain keywords; conservative subsets for DuckDuckGo, Mojeek, Kimi, Z.AI, TinyFish, and Synthetic). The pipeline then applies a lenient post-filter to every response: constraints the engine ignored are enforced on the returned sources, and any constraint dimension that would eliminate every result is relaxed and reported to the model (Note: no results matched \site:...`; the constraint was relaxed`) instead of returning nothing. Directive-free queries are passed through byte-identical everywhere.
  • Eval and browser run code previews are now prettified for display: minified/compact agent-written cells are expanded by conservative streaming formatters (Python, JavaScript, Ruby, Julia) that indent block structure, split statements, normalize operator spacing (JS), and expand object literals wider than 100 columns onto one property per line — purely for rendering, the executed source is untouched. The formatters handle in-flight prefixes (unterminated strings/comments/blocks) without inventing closers, and layout decisions are prefix-stable so already-rendered lines never reflow while a call streams.

Changed

  • Large pastes saved via the large-paste menu now insert local://paste-N.md references (previously local://attachment-N), so the saved paste carries a markdown extension and a clearer name.
  • Raw SSE debug capture now trims over-budget events smartly instead of chopping off the tail: tool definitions inside data: payloads are compacted first (name kept, schema/description elided — often enough to keep the whole payload as valid JSON), and anything still over the 64k cap keeps its head and tail with a : omp-debug-elided chars=N comment marking the removed middle, so trailing fields like usage stay visible.
  • The web_search tool prompt now tells the model to never search for content that is programmatically accessible or has a known URL (GitHub, known arXiv papers, Wikipedia pages, official docs) and to read the URL directly instead.

Fixed

  • Fixed todo calls that omit op hard-failing validation ("op must be operation to apply (was missing)"): the tool now validates leniently and infers the op for unambiguous payloads (listinit, phase+itemsappend, bare items on an empty list → init); op stays required in the schema, and ambiguous op-less calls surface the schema error as a retryable tool error.
  • Fixed credential-free web search engines (SearXNG, DuckDuckGo, Google, Startpage, Ecosia, Mojeek, and the Public Web fan-out) returning zero results for queries with site: paths (e.g. site:github.com/owner/repo) or inurl: operators: scraper engines only match site: against a bare domain and DuckDuckGo ignores inurl: entirely, so such queries silently emptied the result set and fell through to the next provider in the chain. A shared formatScraperQuery formatter now structurally demotes path-carrying site: and all inurl: values to plain search terms (covering OR-grouped and quoted directives) while preserving bare-domain site: filters, negated operators, and each engine's supported syntax; the pipeline post-filter still enforces the demoted constraints on returned sources.
  • Fixed ast_edit previews reading like applied edits to the model: the ⟨proposed⟩ badge was TUI-only, so the model-visible result (hashline header + -/+ rows, identical to applied edit output) carried no staged-proposal signal. The preview result now leads with a "Staged as a proposal — files NOT modified yet" notice naming xd://resolve/xd://reject, the injected resolve reminder names the source tool, and the ast_edit tool prompt documents the two-phase flow.
  • Fixed the hub launch ps/list response burying the active process behind every exited one and growing without bound in long-lived projects: the broker now lists non-terminal daemons first (oldest to newest) and caps exited/failed history at the 10 most recently exited, so the active launch is immediately visible and the response stays bounded. Broker recovery also preserves each already-terminal daemon's real exit time instead of overwriting it with the restart timestamp, so the history cap keeps the genuinely most-recently-exited processes after an idle-broker restart (#6517).
  • Fixed a tool call rendering twice in the transcript. A mid-stream rebuildChatFromMessages (from /shake, auto-compaction, or a settings toggle) preserves the live pendingTools components across the clear+replay, but that preservation assumed every pending-tool component was still dangling. When a tool's result had already landed in the session entries while its component still lingered in pendingTools, the replay reconstructed the completed block and the preserved live component was re-appended, so the same block appeared twice; resolved components are now dropped from preservation and owned by the replay (#6516).
  • Fixed --model default (and other bare role names) resolving to the bundled cursor/default catalog model instead of the configured modelRoles.default role. resolveCliModel's exact-match phase ran its unauthenticated catalog fallback before role resolution, so a bundled id colliding with a reserved role name shadowed a configured, runnable role — failing with No API key found for cursor on machines without Cursor credentials. The catalog fallback is now deferred so an authenticated exact model still wins, a configured role beats an unauthenticated catalog-only id, and the catalog id is still recovered when no role matches (#6508).

Removed

  • Removed the model parameter from task and agent(): explicit per-spawn model selectors and fallback chains are no longer supported; spawns always use the agent's configured model

@oh-my-pi/hashline

Changed

  • Bare - bullet body rows are now auto-accepted as literal content with a warning when the hunk is unambiguously a Markdown bullet list (every - row bullet-shaped and no plain +new diff counterpart); ambiguous - rows still fail with the teaching error.

@oh-my-pi/pi-natives

Fixed

  • Fixed native addon builds with CMake 4.x (bundled opus policy floor) and stopped passing -C target-cpu=native on darwin arm64, which baked build-host CPU features into shipped addons and broke ring compilation.

@oh-my-pi/omp-stats

Added

  • Added a Providers dashboard section: per-provider totals, stacked token/cost burn over time, peak-burn-hours histogram, subscription-window insights (windows burned, estimated tokens per window, peak concurrent utilization, ideal account count, exhaustion events), and latest window utilization per account — window analytics read the auth broker's /v1/usage/history when a broker is configured (falling back to the local agent DB), since broker deployments record usage history on the broker host

@oh-my-pi/pi-tui

Fixed

  • Fixed the terminal flickering when leaving a fullscreen overlay (e.g. /settings, the models page) or resizing on terminals that re-report their size whenever the alternate screen buffer toggles: the alt-toggle size echo no longer arms a destructive full-screen (ED3) rebuild, and the in-place repaint path is now auto-detected for any such terminal instead of only Warp (#6511).

What's Changed

  • fix(ai): preserve Anthropic server-tool history by @roboomp in #6496
  • fix(coding-agent): honor modelRoles.default over cursor/default catalog id by @roboomp in #6509
  • fix(providers): use x-api-key auth for opencode-zen anthropic models by @roboomp in #6512
  • fix(tui): auto-detect alt-toggle size echo to stop overlay-exit flicker by @roboomp in #6515
  • fix(launch): surface active daemons ahead of exited history in ps by @roboomp in #6518
  • fix(coding-agent): avoid duplicate tools in transcript rebuilds by @roboomp in #6519

Full Changelog: v17.1.1...v17.1.2

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

NewReleases is sending notifications on new releases.