github can1357/oh-my-pi v16.1.19

6 hours ago

@oh-my-pi/pi-ai

Fixed

  • Fixed Ollama/llama.cpp chat payloads serializing user-attributed mid-conversation developer messages (auto-learn capture nudge, advisor cards, file-mention companions) as system turns; they now serialize as user so llama.cpp can reuse the warm prompt prefix instead of forcing full re-processing. Agent-owned developer reminders (attribution: "agent" — empty/unexpected-stop retries, checkpoint rewind warning, todo reminders) keep their system priority. (#3456)
  • Fixed prior-turn reasoning being lost on cross-API provider switches: when a session moved from an Anthropic-compatible 3p endpoint to an OpenAI-compatible one (Z.AI Anthropic → Z.AI OpenAI, Kimi Anthropic → Kimi OpenAI, DeepSeek, OpenCode-hosted reasoning models, or any custom models.yaml switch that crosses API types), the cross-API path of transformMessages text-demoted every prior thinking block, so the next request shipped the reasoning chain as plain conversation content instead of structured reasoning_content — losing it as reasoning context and re-billing it. convertMessages now threads the request-time resolved compat into transformMessages, which preserves the prior reasoning as a native, signature-stripped thinking block whenever that resolved target accepts reasoning_content as a continuation hint (requiresReasoningContentForToolCalls — including the whenThinking policy OpenCode reactivates for thinking-on requests, #1071/#1484 — or thinkingFormat: "zai"); the openai-completions encoder surfaces those blocks via reasoningContentField, with a new branch for Z.AI-format hosts (Z.AI, Zhipu, Moonshot Kimi, Xiaomi MiMo) that accept but don't require the field. Targets that can't replay unsigned reasoning (encrypted reasoning blobs, signed thought parts, non-reasoning models, thinking-disabled OpenCode) still text-demote so the reasoning survives as conversation context. (#3437, #3439 by @roboomp; #3433, #3434)
  • Fixed Bedrock cross-region inference profiles routing to us-east-1 regardless of their geo prefix: a profile such as eu.anthropic.claude-… (or apac./au./jp.) sent to the hardcoded us-east-1 endpoint returned HTTP 400 The provided model identifier is invalid. streamBedrock now derives the runtime region from the profile's geo prefix — honoring an ambient AWS_REGION/AWS_DEFAULT_REGION only when it can serve that geo and falling back to the geo's default region otherwise — while explicit per-request and ARN-embedded regions still win and region-agnostic global. profiles stay unchanged.
  • Fixed malformed tool calls (empty name) wedging entire sessions in HTTP 400 loops: when a model occasionally emits { "name": "", "arguments": "{}" } (observed: GLM-5.2 + thinking on long turns), the agent rejected the call at execution time with Tool not found, but the malformed block plus its error toolResult stayed in conversation history and every subsequent request 400'd on tool_use.name/tool_calls[i].function.name validation until the user ran /clear. transformMessages — the canonical sanitize boundary every provider passes through — now drops toolCall blocks with empty/whitespace name, pairs them with their toolResult messages only inside the same assistant→tool-result window (per-id FIFO queue cleared at non-result boundaries, so stale malformed calls without a result cannot consume later valid duplicate-id outputs), and drops the assistant turn when it has no replayable content left. Defensive (provider-agnostic, fires regardless of model), idempotent (no-op on a clean history), and self-healing (one round-trip after the fix lands sanitizes an already-poisoned session). (#3458)

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

Fixed

  • Fixed omp install <plugin> failing extension validation in compiled-binary mode with Cannot find module '@(scope)/pi-ai/oauth' from '<plugin>/src/oauth.ts' (and any other non-wildcard pi-* subpath import like @oh-my-pi/pi-coding-agent/tools). The bundled-registry override map seeded by __buildLegacyPiPackageRootOverrides only covered the bare package roots, so rewriteLegacyPiImports rewrote @(scope)/pi-ai/oauth to @oh-my-pi/pi-ai/oauth, fell through to Bun.resolveSync (which bunfs can't satisfy on Bun 1.3.14+), then left the original specifier alone — at which point Bun's native resolver failed because most plugins declare @(scope)/pi-ai as a peerDependency only and never materialize a real install. The new scripts/generate-legacy-pi-bundled-registry.ts reads every bundled pi-* package's non-wildcard exports field and emits both the heavy legacy-pi-bundled-registry.ts (static imports + map) and a light legacy-pi-bundled-keys.ts (statically imported by legacy-pi-compat.ts to seed the override map without the cascade through legacy-pi-coding-agent-shim → ../index → export/html/...). scripts/build-binary.ts now runs the generator before bun build --compile. (#3442)
  • Fixed skill:// tool resolution losing loaded session skills when a tool runs outside the session-initialization module state. Internal URL resolution now prefers the caller's session.skills snapshot before falling back to the process-global skill list, so read skill://<name> works across tool execution boundaries. (#3436)
  • Fixed @image mentions on OpenAI Codex Responses (chatgpt.com gpt-5.5 and siblings) failing with Codex error event: [OneOfParam] [input[N].content[…]] [invalid_enum_value] Invalid value: 'input_image'. Supported values are: 'input_text'.. convertToLlm for fileMention always emitted a developer-role message, so the auto-attached image landed in a Responses content array that the Codex backend (and OpenAI Responses generally) only allows to carry input_text. #3421's previous fix only stopped the Codex Responses Lite header from going out on image-bearing turns; the full transport kept rejecting the same payload. convertToLlm now splits a mixed-content fileMention into two messages — text-only files stay on developer (so the auto-read context keeps instruction priority), while image-bearing files ride on user (the only Responses content slot that accepts input_image). (#3443)
  • Fixed local:// binary attachments being decoded with Bun.file().text() before read-tool file safeguards could reject or stream them. read local://... now routes file-backed resources through the normal filesystem reader, the protocol handler refuses known binary/container resources without materializing their bytes, and the streaming reader's NUL-byte refusal now also covers binary blobs whose first newline lies beyond the byte budget (videos, archives) — those previously bypassed the per-line scan and surfaced as decoded mojibake. (#3448)

@oh-my-pi/pi-tui

Fixed

  • Fixed bordered Editor rendering 1–2 cells past the terminal width when the end-of-line cursor glyph landed past a wide trailing grapheme (CJK comma , emoji, etc.), wrapping the bottom-right corner () to its own row. The right chrome (padding + + corner) now shrinks by the exact cursor overflow cell count instead of a 1-cell boolean, so the box stays inside width for any paddingX (#3431).

What's Changed

  • fix(ai): preserve cross-api reasoning replay by @roboomp in #3437
  • fix(ai): preserve 3p thinking blocks across cross-API switches by @roboomp in #3439
  • fix(tui): shrink bordered Editor right chrome by cursor overflow cells by @roboomp in #3432
  • fix(agent): preserve skill URL session context by @roboomp in #3438
  • fix(coding-agent): route image-bearing @ mentions as user-role messages by @roboomp in #3445
  • fix(plugins): route bundled pi-* subpath imports through the virtual registry by @roboomp in #3446
  • fix(coding-agent): refuse local binary attachment text reads by @roboomp in #3450
  • fix(ai): preserve Ollama cache for capture turns by @roboomp in #3457
  • fix(ai): drop malformed (empty-name) tool calls in transformMessages by @roboomp in #3459

Full Changelog: v16.1.18...v16.1.19

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

NewReleases is sending notifications on new releases.