github can1357/oh-my-pi v16.0.3

4 hours ago

@oh-my-pi/pi-ai

Added

  • Exported renderDelimitedThinking from the @oh-my-pi/pi-ai/dialect barrel so consumers can reuse the dialect's <thinking> envelope unwrap-and-rewrap logic (the only ./dialect/rendering primitive re-exported; the rest stay dialect-internal).

Fixed

  • Fixed OpenAI Responses/Codex tool schema normalization stripping provider-rejected regex lookaround patterns from MCP tool parameter schemas. (#2784)
  • Fixed OpenAI Responses parallel tool-call routing so late keyed argument deltas for a closed call are dropped instead of being appended to another open call.

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

Added

  • Added support for LaTeX color commands (\textcolor, \colorbox, and \fcolorbox) in user-visible terminal prose and final chat to colorize output

Changed

  • Changed STT dependency setup to validate recorder and model assets per stt.modelName, so switching speech models re-runs dependency checks and downloads for the new model
  • Changed STT startup with cached models to warm the speech model in the background and defer full model loading until transcription begins, reducing push-to-talk start latency
  • Allowed user-visible terminal and final-chat responses to include LaTeX math delimiters/commands and Mermaid ```mermaid diagrams
  • Changed the hold-Space push-to-talk gesture to recognize a held bar from the regularity of the OS key auto-repeat rather than a raw space count or speed alone, so it no longer spams the editor, no longer eats deliberate space taps, and no longer triggers when the bar is smashed. Recording starts only after two consecutive inter-space deltas are "mechanical" — both fast (within ~120 ms) and near-identical, the metronomic signature of auto-repeat; the few pre-burst spaces typed are then tracked back out. Smashing (fast but jittery) and deliberate spacing (steady but slow) both keep typing real spaces and never start recording.
  • Updated markdown Mermaid rendering to color ASCII diagrams with the active theme and automatically choose a narrower layout that better fits the terminal width
  • Made the watched-session transcript sent to the advisor (and shown by /advisor dump) clearer: each turn now opens with a ### Session update heading; watched-agent roles render as inline **agent**: / **user**: labels instead of level-2 headings that collided with the advisor's own turns; consecutive same-role messages collapse under one label (the watched agent emits one assistant message per tool call); and batched updates are joined by a blank line rather than a --- rule.
  • Changed the compact transcript tool-intent prefix (history://, /advisor dump) from # to // so intent lines read as comments instead of rendering as Markdown H1 headings.
  • Changed the advisor advice injected into the primary transcript from a Advisor (...): - [severity] note prose block to one <advisory severity="…" guidance="weigh, don't blindly obey">…</advisory> element per note, with XML-escaped bodies. (Relocated the shared escapeXmlText helper to @oh-my-pi/pi-utils.)
  • Reverted /dump and /advisor dump raw to the pre-16.x full verbose dump: system prompt, model/thinking config, tool inventory with parameters, and the message transcript rendered with markdown role headings (## User, ## Assistant, ### Tool Call: <name> with the call's _i intent as a // comment under the heading and the remaining arguments as a fenced YAML block, ### Tool Result: <name>, plus ## Bash Execution/## File Mention/summary sections) instead of the model's native-dialect turn envelopes and <invoke>/<parameter> XML tool calls. Dropped the compact default and the [raw] flag on /dump; the compact → tool(...) ⇒ ok history format is no longer reachable from /dump. /advisor dump still defaults to compact, and /advisor dump raw now renders the same markdown dump (previously the model's native-dialect envelopes).

Fixed

  • Fixed Whisper STT cache detection to require both encoder and decoder .onnx files, so partial model downloads now trigger a proper foreground download instead of being treated as fully cached
  • Fixed same-process JsRuntime cleanup so disposing an older inline/direct runtime no longer deletes a newer runtime's JS helper globals; inactive cmux/direct runtimes now re-activate their globals before sequential use while overlapping cross-runtime runs fail explicitly.
  • Fixed magic-keyword steering notices (ultrathink-notice, orchestrate-notice, workflow-notice) to be prepended before the related user message so they influence that same turn
  • Fixed dequeuing or popping queued user messages to remove their preceding hidden magic-keyword notice companions, preventing orphaned queued notices
  • Fixed queued user steers to auto-resume after interrupts even when the transcript tail is a preserved advisor card or other non-conversational custom message
  • Fixed queued user follow-up messages to remain queued after an interrupt and only run on explicit resume, even when an IRC wake leaves a provider-valid tail
  • Fixed stranded IRC asides to wake a response turn after interruption instead of remaining pending
  • Fixed accepted IRC asides to be flushed into the transcript during disposal instead of being discarded
  • Fixed interactive submissions made while the TUI had no active input waiter: they now start a real prompt directly, with steer fallback if a background turn races in, instead of queueing behind a non-resumable idle transcript and appearing to do nothing.
  • Fixed pressing Esc (or Alt+Up dequeue) while agent-authored messages were queued — advisor concern/blocker notes, hidden goal/plan/budget steers, IRC/extension asides — dumping their text into the user's editor. Editor restoration (clearQueue()), pending chips (getQueuedMessages()), and popLastQueuedMessage() now surface only genuinely user-authored queued messages (plain user turns and attribution: "user" custom messages like /skill). Plain Alt+Up dequeue leaves all other queued messages in place for the continuing stream; only the Esc interrupt path keeps just advisor cards (so abort's preservation still re-records them as visible advice) and drops other internal steers, so a user interrupt can't be silently undone by an auto-resume on leftover internal context. queuedMessageCount still reflects all actual queued work (advisor cards included) so hasPendingMessages()/RPC and the empty-submit abort gate stay accurate.
  • Fixed advisor concern/blocker advice being withheld from the running agent and then dumped as one burst at the next user prompt after a deliberate interrupt. A user interrupt latches advisor auto-resume suppression, but a non-user resume (synthetic/auto-continue, or a queued steer draining after the abort) leaves the run streaming with that latch still set, so every interrupting note was parked hidden in the next-turn queue instead of steered into the live turn — the agent never heard the advisor mid-run and the backlog flushed all at once on the next prompt. Suppression now only withholds interrupting advice while the agent is idle (or still tearing the interrupted turn down); once a turn is streaming again the note is steered in live, since steering an active run never auto-resumes a stopped one. A concern that strands in the steer queue past the resumed turn's final poll is reclaimed as visible advice when the agent settles (mirroring abort), so it neither auto-resumes the stopped run nor lingers to flush at the next prompt.
  • Fixed omp --continue/-c sometimes resuming into a subagent transcript instead of the interactive session. Subagent (and HTML-export) SessionManager.open() calls run in the parent's terminal and were clobbering the per-TTY --continue breadcrumb with their own artifact-dir session file; these headless opens now suppress the breadcrumb. continueRecent() also recovers already-poisoned breadcrumbs by resolving any session file inside a parent's artifacts dir (<parent>/<agentId>.jsonl) back up to the top-level session.
  • Fixed the Agent Hub stacking duplicate Agent Hub · N running frames and stranding garbage rows in scrollback while navigating with subagents still streaming. The hub was a non-fullscreen overlay composited over a live transcript, so each time a running subagent's progress grew the frame and scrolled the window the previously-painted hub copy was pushed permanently into the terminal's native scrollback (which the engine can't rewrite). It now renders inline in the editor slot — the same anchored region every other selector and the ask tool use — riding the normal append-only commit path, so the transcript commits above it exactly once and the hub repaints in place instead of leaking copies. (Avoids borrowing the alternate screen.)
  • Fixed every subagent registering itself as its own parent in the agent registry (parentId === id), so the Agent Hub rendered each agent as sub · of <itself> and the ←← parent-navigation gesture looped on the same agent. The SDK was reusing parentTaskPrefix — the agent's own artifact/output-id prefix — as the registry parent link; spawns now pass a separate parentAgentId (the spawning agent's id: Main for top-level task spawns, the parent subagent for nested spawns and eval agent(), the focused agent for /tan) and the registry records that as the parent.
  • Fixed messaging a parked subagent that was restored from disk (Agent Hub scan, or a resumed/restarted session) failing with cannot be revived (no reviver registered) even though its transcript was intact. Such refs carry a session file but no in-memory reviver — the executor's live reviver closure dies with the spawning turn/process — so IRC sends and Agent Hub focus refused them. AgentLifecycleManager.ensureLive now cold-revives them through a persisted-subagent reviver factory (installed by the top-level interactive/RPC session) that rebuilds the subagent from its JSONL the way --resume rebuilds a session: it reopens the file and replays it through createAgentSession, but sources the runtime contract from a now-readable session_init record (SessionManager.peekSessionInit) so tools, system prompt, output schema, and kind are restored rather than resurrected as a default top-level session. session_init now also persists the effective spawns allowlist and read-summarization flag so a cold revive keeps the original capability surface (old files without them deny re-spawning rather than defaulting to wildcard). Isolated runs and pre-session_init files whose recorded workspace no longer exists stay transcript-only (history://).
  • Fixed the terminal window-title OSC writes (setTerminalTitle/pushTerminalTitle/popTerminalTitle) leaking escape sequences to a developer's terminal during bun test; they now skip when the terminal is headless (the test-runtime default), matching the ProcessTerminal render/probe suppression so interactive-mode tests no longer paint to the real terminal
  • Fixed empty CLI sessions being retained after opening omp and exiting without a prompt (#2800).
  • Fixed hooks/pre/*.ts and hooks/post/*.ts files discovered through hookCapability being registered in discovery but never loaded into the extension runner, so their tool_call handlers now run without a manual settings.json extensions entry (#2796).
  • Fixed startup model fallback choosing the plain OpenAI gpt-5.5 provider before the Codex OAuth provider when both shared the same default model id, which could surface a misleading OpenAI 401 despite valid Codex credentials (#2807).
  • Fixed local auto-thinking classification for reasoning-capable tiny models by giving them the same safe answer budget as online reasoning classifiers, with a larger local floor for non-reasoning tiny models (#2808).

Removed

  • Removed the built-in render_mermaid tool and its renderMermaid.enabled setting, so it can no longer be invoked directly

@oh-my-pi/collab-web

Removed

  • Removed rendering support for the render_mermaid tool from the web tool registry

@oh-my-pi/pi-tui

Added

  • Added \tfrac support to stacked display-math rendering so it now displays as a vertical fraction in latexToBlock output
  • Added markdown parsing for own-line display-math blocks ($$...$$ and \[...\]) and delimiter-free \begin{...}...\end{...} math environments so block equations render via LaTeX-to-Unicode
  • Added stacked rendering of display-math fractions (\frac, \dfrac, \cfrac): the numerator is drawn over a horizontal bar over the denominator, with surrounding terms and align/equation-style environment rows aligned to the bar. Triggered for own-line $$/\[ blocks, bare \begin{...} environments, and a paragraph whose sole content is a single display-math span; inline $...$ fractions stay single-line (½, (a+b)/c)
  • Added bare math auto-rendering in renderMathInText for math-shaped lines and math environment blocks that omit $/\( delimiters
  • Added LaTeX-to-Unicode rendering for markdown math spans, converting $$...$$, $...$, \(...\), and \[...\] into readable Unicode in Markdown output
  • Exported LaTeX conversion helpers from the package entrypoint so consumers can call latexToUnicode, latexToBlock, renderMathInText, inlineMathSpanEnd, and isBareMathEnvironment directly
  • Expanded LaTeX-to-Unicode conversion coverage for additional math fonts, delimiters, extensible arrows, layout environments, cancel/brace annotations, references, and AMS symbols
  • Added ANSI color rendering for LaTeX \textcolor, scoped \color, \colorbox, and \fcolorbox, including xcolor/CSS color parsing and truecolor/256-color terminal output
  • Added an optional maxWidth parameter to MarkdownTheme.resolveMermaidAscii to allow diagram resolvers to fit ASCII output to the available content width

Changed

  • Changed markdown math rendering to preserve multiline layout for display equations, keeping \\ row breaks as separate output lines (including inside list items)

Fixed

  • Fixed alignat/alignedat/gatheredat rendering in latexToBlock so the required {n} preamble is not rendered as visible math content
  • Fixed math parsing to leave non-math LaTeX snippets (for example \begin{itemize}) and fenced code blocks as literal text instead of rendering them as math
  • Fixed renderInlineMarkdown to handle top-level display-math tokens so raw $$...$$ delimiters are no longer leaked
  • Fixed inline math span detection so escaped dollars and currency-like patterns (such as $5 and $10) are not converted as math
  • Fixed Mermaid diagram rendering in Markdown code blocks to clip each ASCII line to content width before wrapping, preventing preformatted diagram rows from fragmenting
  • Fixed fullscreen overlays losing keyboard focus to hidden prompt surfaces, which could make settings unresponsive while a background approval request was pending (#2789).
  • Fixed bun test runs inside a real terminal leaking TUI output: ProcessTerminal now honors a headless test-runtime default, so frame paints, start() capability probes (OSC 11 / DA1 / kitty), the progress keepalive, notifications, and teardown escapes no longer reach the developer's terminal, and stdin raw mode is never engaged. Previously #safeWrite only skipped on !process.stdout.isTTY, so a developer running the suite in an interactive terminal saw stray status/editor boxes and probe queries. Terminal-contract suites opt back into real I/O via setTerminalHeadless(false)

@oh-my-pi/pi-utils

Added

  • Added escapeXmlText utility to escape XML-significant characters &, <, and > in element body text
  • Added isTerminalHeadless() / setTerminalHeadless() to centrally suppress real-terminal side effects (stdout escape/frame writes, stdin raw mode, CSI/OSC capability probes, SIGWINCH, window-title changes, emergency restore) under the test runtime. Defaults on when bun test sets NODE_ENV=test; terminal-contract tests opt out via setTerminalHeadless(false)

What's Changed

  • fix(tui): keep overlay focus above hidden prompts by @roboomp in #2795
  • fix(coding-agent): load discovered hook factories by @roboomp in #2798
  • fix(cli): skip empty session persistence by @roboomp in #2804
  • fix(coding-agent): prefer Codex default auth by @roboomp in #2810
  • fix(coding-agent): expand local auto-thinking classifier budget by @roboomp in #2814

Full Changelog: v16.0.2...v16.0.3

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

NewReleases is sending notifications on new releases.