github can1357/oh-my-pi v15.5.8

latest releases: v15.5.10, v15.5.9
7 hours ago

@oh-my-pi/pi-ai

Added

  • Added CheckCredentialsOptions.completionProbe (and completionTimeoutMs) so AuthStorage.checkCredentials can additionally exercise each credential against the provider's chat-completion endpoint after refresh-on-expiry. Result lands on CredentialHealthResult.completion ({ok, reason?, modelId?, latencyMs?}) without disturbing the usage ok field. Public types: CompletionProbe, CompletionProbeInput, CompletionProbeCredential, CredentialCompletionResult. The probe is invoked even when no UsageProvider is registered for the row, and is skipped when OAuth refresh fails (the stale bytes would only mask the upstream failure).
  • Added Wafer Pass and Wafer Serverless providers (wafer-pass, wafer-serverless). OpenAI-compatible (https://pass.wafer.ai/v1), bearer auth, wfr_… keys. /login wafer-pass and /login wafer-serverless paste-and-validate the key against /v1/models. WAFER_PASS_API_KEY and WAFER_SERVERLESS_API_KEY environment variables wired into getEnvApiKey. Bundled catalog seeds wafer-pass/{GLM-5.1, Qwen3.5-397B-A17B} and wafer-serverless/{GLM-5.1, Kimi-K2.6, Qwen3.5-397B-A17B, Qwen3.6-35B-A3B, qwen3.7-max, deepseek-v4-flash, deepseek-v4-pro}; dynamic discovery via /v1/models overlays additional models at runtime. Pass-tier discovery filters wafer.tier === "pass_included". Pass-SKU costs are seeded at 0 (flat-rate subscription, no per-token charge — matches kimi-code/firepass/alibaba-coding-plan). Serverless costs are the wafer.ai retail rate, derived from the *_cents_per_million envelope via value × 125 / 10000 (e.g. GLM-5.1 120 → $1.50/M, Kimi-K2.6 88 → $1.10/M). Reasoning entries get a thinking compat picked from the wafer.provider envelope: zai/moonshotai → zai-style thinking: { type }, qwen → top-level enable_thinking, deepseek and unknown upstreams stay unset so detectOpenAICompat can pick reasoning_effort from the id pattern at request time.

Changed

  • Changed auth-gateway credential resolution to use per-conversation promptCacheKey/sessionId when calling AuthStorage.getApiKey, so repeated turns can keep the same credential until it becomes unavailable
  • Changed auth-gateway and pi-native request handling to align sessionId with prompt/context identity before credential lookup
  • Changed Anthropic prompt preparation to downscale image blocks over 2000px when a request includes 20+ images, reducing oversized payloads automatically
  • Changed OpenAI chat request parsing to accept name on tool messages and fall back to the matching assistant tool_calls name, so parsed tool results now carry a proper tool name when the wire omits it
  • Changed checkCredentials to skip running completionProbe when OAuth refresh fails, so stale bearer tokens are never probed and the refresh failure remains the returned reason
  • Changed completion reporting to return completion: { ok: null, reason: ... } when a credential has no usable bearer bytes instead of attempting the probe
  • Refactored AuthStorage.checkCredentials so OAuth refresh-on-expiry runs up-front and the refreshed credential is shared between the usage probe and the new completion probe; rows without a registered UsageProvider no longer short-circuit before the completion probe runs.

Fixed

  • Fixed DeepSeek DSML tool-call envelope leaks on Ollama Cloud and OpenAI-compatible streams by healing leaked envelopes into structured tool calls without displaying raw DSML markers. (#1462)
  • Fixed auth-gateway to classify usage-limit messages such as usage_limit_reached, resource_exhausted, and Codex-style Try again in ~X min text as 429 rate_limit_error responses
  • Fixed auth-gateway usage-limit handling to honor parsed retry hints and switch to a sibling credential via markUsageLimitReached instead of invalidating the rate-limited credential
  • Fixed streamSimple to retry on usage-limit errors (including message-only error events) before any content is emitted, so onAuthError can rotate credentials automatically
  • Fixed auth-gateway error classification to extract embedded status codes and use word-boundary matching, so GenerateContentRequest and similar messages are no longer misreported as rate-limit errors
  • Fixed checkCredentials to handle completionProbe exceptions by recording the failure in CredentialHealthResult.completion.reason while still returning the usage probe result

Fixed

  • Fixed Google Vertex's bundled model list to use the authoritative models.dev catalog, including MaaS entries such as deepseek-ai/deepseek-v3.2-maas and removing retired Gemini 1.5 fallbacks. (#1456)

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

Breaking Changes

  • Changed hashline edit parsing to require wrapped hunk headers such as @@ A..B @@ (including @@ BOF @@ and @@ EOF @@), with empty @@ A..B @@ blocks deleting the anchored range and legacy inline payload forms treated as malformed

Added

  • Added vault.enabled setting (Tools → Obsidian Vault, default false) gating the vault:// internal URL. When disabled, VaultProtocolHandler.resolve / write, resolveVaultUrlToPath, and hasObsidian() all refuse — the latter hides the vault:// entry from the system prompt's Handlebars {{#if hasObsidian}} block. Tests can opt in via vi.spyOn(vaultProtocol, "isVaultEnabled").mockReturnValue(true).

  • Added support for vault:// URLs in path resolution utilities, including plan mode and internal selector parsing so read and edit paths can target Obsidian vault files directly

  • Added vault:// internal URLs for editable Obsidian vault files, with filesystem-backed read/write/listing and CLI-backed vault index operations.

  • Added strict-mode indicators to omp auth-gateway check output by appending [strict] to strict-mode text headers and adding a top-level strict field in --json output

  • omp auth-gateway check --strict exercises each broker-supplied credential against its provider's chat-completion endpoint (cheapest bundled chat model per provider, with 15s/attempt timeout and up to 4 catalog fall-throughs on "model not found / invalid model" errors). Surfaces failures where the usage endpoint reports 200 but the chat endpoint 401s the same bearer (revoked OAuth scope, mislabeled provider row, …). Output gains a [chat: ok|FAIL|skip] column in text mode and a completion field on each credential in --json mode; the chat-failed count contributes to the non-zero exit code.

Changed

  • Changed hashline apply behavior to preserve duplicated boundary and context lines in replacement and insert payloads instead of auto-absorbing or dropping them
  • Updated hashline syntax: replaced / payload sigils with ^ repeat syntax and | literal rows for clearer edit semantics
  • Changed hashline delete syntax from bare A: or A-B: to explicit A-B:- inline delete marker
  • Modified hashline anchor syntax to require explicit range notation A-B: instead of shorthand A: for single-line operations
  • Updated hashline description in settings to clarify pure insert context behavior without arrow notation

Removed

  • Removed the edit.hashlineAutoDropPureInsertDuplicates setting
  • Removed the edit.hashlineAutoDropPureInsertDuplicates setting from configuration and execution paths
  • Removed the edit.hashlineAutoDropPureInsertDuplicates setting
  • Removed the edit.hashlineAutoDropPureInsertDuplicates setting from configuration and execution paths

Fixed

  • Fixed agent yielding silently on response.incomplete (OpenAI Responses / Codex stopReason: "length"). The agent now treats output-side incompletion as a recovery case: drops the truncated/reasoning-only assistant turn, attempts context promotion to a larger model, and falls back to compaction or handoff. AutoCompactionStartEvent.reason and the custom-tool auto_compaction_start.trigger discriminator gain an "incomplete" value. The handoff strategy is honored for "incomplete" (unlike "overflow", where the input is broken and handoff would hit the same wall).
  • Fixed eval tool to resize large displayed images and append dimension notes to text output
  • Fixed write tool to strip malformed or loose hashline section headers before writing file content
  • Fixed eval tool image rendering to resize displayed images before returning them and append image-dimension notes to text output
  • Fixed write tool output sanitation to strip malformed or loose hashline section headers before writing file content
  • Fixed omp auth-broker serve crashing at startup with logger.setTransports is not a function — switched the call site to import { setTransports } from "@oh-my-pi/pi-utils/logger", bypassing the logger namespace re-export that some Bun versions failed to expose at runtime
  • Fixed omp auth-gateway returning 502 upstream_error and refusing to rotate credentials when a provider responded with a non-401 usage-limit error (Codex usage_limit_reached, Anthropic usage_limit_reached, Google resource_exhausted). classifyGatewayError now reuses pi-ai's central isUsageLimitError heuristic and reports those failures as 429 rate_limit_error. streamSimple's pre-emit retry hook fires on usage-limit phrasing in addition to HTTP 401; the gateway's refresh callback branches on the error type and calls AuthStorage.markUsageLimitReached(provider, sessionId, { retryAfterMs }) — temporarily blocking just the exhausted credential and surfacing the next sibling — instead of invalidateCredentialMatching, which would have suspect/deleted the row. The same branching is wired into the coding-agent streamFn callback so subscription multi-account rotation works the same on both surfaces.
  • Fixed extractRetryHint not recognising Codex's Try again in ~N min. / … hour / … hours phrasing, which left the gateway and TUI without a server-suggested retry window when an upstream account hit its usage cap. The shared try again in pattern now accepts min, minutes, mins, h, hr, hour, hours units in addition to ms / s / sec, and tolerates a leading ~ and embedded whitespace.
  • Fixed the auth-gateway threading sessionId: undefined into AuthStorage.getApiKey, which left #sessionLastCredential empty and made markUsageLimitReached a no-op for gateway-mediated requests. Both /v1/chat/completions-style endpoints and the /v1/pi/stream fast path now derive a stable sessionId from the client's prompt_cache_key (or the existing model+system+tools+first-message hash when absent) and reuse the same identity for credential-stickiness and prefix-cache routing.
  • Fixed eval tool to resize large displayed images and append dimension notes to text output
  • Fixed write tool to strip malformed or loose hashline section headers before writing file content
  • Fixed eval tool image rendering to resize displayed images before returning them and append image-dimension notes to text output
  • Fixed write tool output sanitation to strip malformed or loose hashline section headers before writing file content
  • Fixed omp auth-broker serve crashing at startup with logger.setTransports is not a function — switched the call site to import { setTransports } from "@oh-my-pi/pi-utils/logger", bypassing the logger namespace re-export that some Bun versions failed to expose at runtime
  • Fixed user shortcut Python execution to namespace session IDs like eval, so both paths share one kernel

Security

  • Secured vault:// reads and writes by validating URL paths and blocking traversal, absolute paths, and symlink escapes outside the selected vault root

@oh-my-pi/hashline

Breaking Changes

  • Removed the single-number hunk header shorthand. A hunk header now REQUIRES two line numbers (A A for a single line, A B for a range); a bare A row throws single-number hunk header "A" is no longer accepted. The &A body-row shorthand for &A..A is unchanged.
  • Changed hunk header syntax from A-B: to @@ A..B @@ with @@ A @@ shorthand for single lines
  • Changed repeat payload sigil from ^A-B to &A..B with &A shorthand for single lines
  • Changed range separator from - to .. in all contexts (anchors and repeats)
  • Changed empty hunk behavior: concrete ranges now delete (no blank-line insertion); BOF/EOF empty hunks are now no-ops
  • Removed ApplyOptions parameter from applyEdits() and related APIs; auto-absorb behavior is no longer configurable
  • Removed diagnostic warnings for auto-absorbed duplicates from ApplyResult; warnings now come only from parser, patcher, or recovery
  • Removed legacy hashline block syntax A-B:, A-B:-, and ^A-B and replaced edits with @@ A..B @@ hunks using + and & body rows
  • Removed A: shorthand syntax; use explicit A-A: for single-line anchors
  • Removed and payload sigils; use |TEXT for literal rows and ^A-B for repeating original lines
  • Removed standalone delete rows; use inline A-B:- syntax instead
  • Removed after_anchor cursor kind; all inserts now use before_anchor positioning
  • Replaced insert-above/insert-below payload sigils with linear body rows: |TEXT emits literal text and ^A-B repeats original file lines inline.
  • Replaced standalone delete rows with inline range deletes: use A-B:-.
  • Changed empty A-B:, BOF:, and EOF: blocks to write one blank line instead of being rejected.

Added

  • Added compatibility parsing for apply_patch-style and unified-diff row noise by stripping path noise and converting context/delete body rows into hashline-compatible operations with warnings
  • Added A-B:- inline delete syntax for concrete range anchors
  • Added ^A-B repeat payload syntax to emit original file lines inline
  • Added support for empty anchor blocks to write one blank line at the anchor position

Changed

  • Changed unified-diff compatibility mode to silently drop -old rows and convert context rows to +TEXT literals with a warning instead of rejecting them
  • Changed ABORT_MARKER behavior to terminate parsing without surfacing a warning
  • Changed numeric ranges to A..B form and accepted @@ A @@ as shorthand for @@ A..A @@
  • Changed empty hunk behavior so a concrete empty hunk deletes the selected range and BOF/EOF empty hunks no longer insert a blank line
  • Changed parse behavior for *** Abort to stop processing without returning a speculative truncation warning
  • Changed payload row format from three sigils (|, , ) to two (|, ^)
  • Changed range anchor syntax to require explicit A-B form (no single-line shorthand)
  • Changed error messages to reference new syntax and remove references to removed sigils

What's Changed

New Contributors

Full Changelog: v15.5.7...v15.5.8

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

NewReleases is sending notifications on new releases.