chore(deps): update dependency can1357/oh-my-pi to v15.11.0 #56
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "renovate/can1357-oh-my-pi-15.x"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
This PR contains the following updates:
15.10.12→15.11.0Release Notes
can1357/oh-my-pi (can1357/oh-my-pi)
v15.11.0Compare Source
@oh-my-pi/pi-agent-core
Breaking Changes
compaction/index.tsre-export of snapcompact helpers, so snapcompact utilities are no longer available from the agent compaction barrel and should be imported from@oh-my-pi/snapcompactconvertToLlmalias export fromcompaction/messages— it duplicateddefaultConvertToLlmunder a second name. ImportdefaultConvertToLlm(array form) or the newconvertMessageToLlm(single-message form) insteadAdded
convertMessageToLlm(): the single-message core transformer behinddefaultConvertToLlm(). Embedders with app-specific message roles should handle their own roles and delegate every core role (user/developer/assistant/toolResult/custom/hookMessage/branchSummary/compactionSummary) to it instead of duplicating the conversion — a duplicatedcompactionSummarycase is how snapcompact frames once silently dropped off provider requestspruneSupersededToolResults()and the opt-inPruneConfig.supersedeKeyhook so harnesses can prune stale tool results superseded by a newer read of the same file; superseded results are pruned ahead of age-based victims during overflow pruning and replaced with a[Superseded by a newer read of this file]placeholder. Without the new config,pruneToolOutputs()behavior is unchanged.readToolSupersedeKey()implementing the read-tool path/selector grammar (selector-free reads supersede range reads of the same file; URL-scheme paths exempt). Pruning honors prompt-cache economics: per-turn prunes only fire when the post-candidate suffix is small or the cache is cold (idle gap).snapcompactcompaction strategy via@oh-my-pi/snapcompact: instead of an LLM summary, discarded history is printed onto dense bitmap frames and re-attached to the compaction summary message as image blocks.CompactionSummaryMessagegains an optionalimagesfield,estimateTokens()charges per attached frame, and frames persist underpreserveData.snapcompactwith an 8-frame middle-out eviction budget.SNAPCOMPACT_SHAPES+resolveSnapcompactShape(api)), following the snapcompact 200k-token monolithic evals: Anthropic-family and unknown APIs get8x8r-bw(unscii-8 square cells, black ink, every line printed twice with the copy on a pale highlight band — read at F1 parity with raw text at ~2x lower cost and the most refusal-robust), Google gets8x8r-sent(sentence-hue ink, ~2.9x cheaper), and OpenAI gets6x6u-sent(unscii Lanczos-stretched to 6x6 cells — OpenAI bills a flat ~2.9k tokens per image, so frame count is the only cost lever) withdetail: "original"on the frame images.snapcompactCompact()acceptsmodel/shapeoptions, frames persist their shape metadata, mixed-shape archives (provider switches, legacy 5x8 frames) are flagged in the reading instructions, andsnapcompactGeometry()/renderSnapcompactFrame()now take a shapeChanged
<files>tag instead of<read-files>/<modified-files>: paths render as the grouped, prefix-folded directory tree the find/search tools emit (# dir/headers, bare basenames), each annotated(Read),(Write), or(RW)— modified files that were also read get(RW). Legacy tags in summaries written by earlier versions are still stripped and self-heal on the next compactionFixed
Agent.continue().<read-files>compaction lists recording the same file once per line-range/raw selector (src/foo.ts:50-200,:raw,:1-50:raw, …): read-tool selectors are now stripped before tracking, so reads dedupe to the base path and match their write/edit path when splitting read-only vs modified lists. Selector-polluted lists stored by earlier compactions self-heal on the next compaction.readToolSupersedeKey()now shares the same splitter (splitReadSelector()), gaining the..range alias andL-prefix forms it previously missed.estimateTokens()undercounting thinking-heavy assistant messages on replay:thinkingSignaturepayloads (OpenAI Responses encrypted reasoning items, Anthropic signed thinking blocks, etc.) andredactedThinking.dataare now charged alongside the visible thinking text, so the local estimate tracks provider-reported usage instead of straddling the threshold on every turn (#2275).@oh-my-pi/pi-ai
Added
ImageContent.detail("auto" | "low" | "high" | "original"): an OpenAI resolution hint forwarded by theopenai-responsesserializers (default staysauto) and byopenai-completionsfor the values Chat Completions supports."original"preserves native resolution — required for snapcompact frames, whose pixel-font glyphs do not survive the default downscale. Providers without a detail knob ignore the field.Fixed
anyOfinside the nullable wrapper for optional unions, which produced a branch withouttypeand triggered OpenRouter'sInvalid tool parameters schema : field anyOf: missing field type400. (#2270)enforceStrictSchemanow splices natively nested pure unions into the parentanyOf(only when the inner node carries no constraining siblings, since sibling keywords are conjunctive withanyOf), so source schemas with nested unions no longer produce type-lessanyOfbranches that strict upstream validators reject. (#2270)"mixed"strict mode (previously gated toall_strict, i.e. Cerebras only) and taught it to recognize upstream tool-schema validation 400s (Invalid tool parameters schema …,Invalid schema for function …). A matching rejection now retries the request with base (non-strict) schemas and persistsstrictToolsDisabledon the provider session, so later requests skip the doomed strict attempt instead of paying a 400 + retry round-trip each turn. (#2270)anthropic-messages → anthropic-messagescontinuations now preserve prior assistant turns' reasoning chains end-to-end: every priorthinking/redactedThinkingblock survives (not just the latest surviving assistant), and third-party ↔ third-party replays keep their signatures intact so the reasoning chain stays signed for the next turn. Signatures are stripped (and anyredacted_thinkingsibling without a native landing spot is dropped) only when an official Anthropic endpoint is on either end of the replay — official Anthropic cryptographically binds reasoning signatures to its key+session+model, while compatible reasoning endpoints (Z.AI, DeepSeek, custom anthropic-messages providers configured viamodels.yaml) treat them as opaque continuation hints. Source-side official detection uses the canonical catalog provider id"anthropic"(assistant messages carry nobaseUrl); target-side detection reuses the bakedcompat.officialEndpointflag. Latest-turn byte-for-byte behavior (Anthropic's "thinking blocks in the latest assistant message cannot be modified" rule) and existing aborted/errored last-block sanitization are unchanged. (#2257, #2265)@oh-my-pi/pi-catalog
Fixed
buildModelso malformed explicit thinking metadata withouteffortsis treated as sparse input and inferred instead of crashing during model resolution (#2251).@oh-my-pi/pi-coding-agent
Breaking Changes
resumeoption from thetasktool API and its resume execution path; continue work on finished subagents by sending follow-up messages viaircinsteadirc.enabledsetting: irc availability is now derived — the tool exists exactly when there is someone to message (the session can spawn subagents throughtask, or it is a subagent itself). A staleirc.enabledkey in config is ignoredtasktool was reworked to always run spawns in the background as independent, persistent agents: results arrive as async job deliveries (block withjob pollonly when genuinely needed). The wire schema is now shape-swapped by the newtask.batchsetting (default on):{ agent, context, tasks[] }— one subagent per task item, per-itemisolated, and a required sharedcontext— or, when disabled, a flat single-spawn shape{ agent, id?, description?, assignment, isolated? }with shared background passed vialocal://files insteadtask.simplesetting and the task tool's per-callschemaparameter outright: structured subagent output now comes only from the agent definition'soutputfrontmatter or the inherited session schema, and ad-hoc structured workflows use evalagent(prompt, schema). A staletask.simplekey in config is migrated awayirctosend/wait/inbox/listops over a per-agent mailbox bus: the blockingawaitReplyauto-reply turn is removed —sendis fire-and-forget with delivery receipts, and replies are real turns by the recipient observed viawait(or thesendawait: truesugar)contextargument from evalagent()in both the JS and Python preludes: pass shared background via alocal://file referenced in the promptapp.session.observe(ctrl+s) now opens the hub, whose chat view absorbed the observer's transcript rendererAdded
8x8r-bwfor Anthropic-family/unknown APIs,8x8r-sentfor Google, Lanczos-stretched6x6u-sentwithdetail: "original"for OpenAI), per the snapcompact 200k-token evalsreadresults: when a file is re-read, older copies of the same path/selector are pruned from context at cache-favorable moments (small suffix, idle gap, or alongside overflow pruning). Gated by the newcompaction.supersedeReadssetting (default on)task.softRequestBudget, 0 disables): crossing the budget injects a one-time wrap-up steer into the child; crossing 1.5× aborts the run gracefully(no output), merged task results now carry the child's last activity snippet plus request/token stats, and per-child stats lines include request countsreadtool: the third and later reads of the same file in a session append a one-line note suggesting range re-reads or the context echoed in edit resultsartifact://footer for the full output, closing paths that previously let 100KB+ results land inlinectrl+s,alt+a, or double-tap left arrow on an empty editor): a live table of registered subagents (status, unread IRC count, current task, last activity) with per-agent chat — Enter opens a transcript + input line that steers a running agent, prompts an idle one, and revives a parked one;rrevives andxaborts/releases the selected agentsnapcompactcompaction strategy (compaction.strategy: "snapcompact"): history is archived onto dense bitmap "snapcompact" frames a vision model reads back directly, instead of an LLM-generated summary — instant, free, and verbatim. Auto compaction (including overflow recovery) and manual/compactboth honor it; falls back to context-full with a visible warning notice when the current model is text-only (e.g. Codex API surfaces) or when/compactis given custom instructions. Frames survive context rebuilds and later compactions (budget eviction is middle-out: the session-head frame is pinned); the expanded compaction message notes the attached frame countidle, are parked to disk aftertask.agentIdleTtlMs(default 7 minutes;0keeps them live until exit), and are revived automatically when messaged or prompted from the Agent Hubhistory://protocol:history://lists every registered agent andhistory://<agentId>renders a concise markdown transcript (tool calls collapsed to one line each, thinking elided) for live and parked agents alikeircwaitblocks until a matching message arrives,inboxdrains or peeks pending messages, and sending to an idle or parked agent wakes or revives it for a real turnirctool: directional send/receive headers with delivery-outcome coloring, quoted message bodies with expand-aware truncation, per-recipient receipt trees for broadcasts and failures, and status-badged peer listings with unread countstask.batchsetting (default on): the task tool's batch shape{ agent, context, tasks[] }spawns one subagent per item — each its own independent background job with the normal idle/parked lifecycle and optional per-item isolation — and prepends the required sharedcontextto every spawned subagent's system prompt; disabling it restores the flat single-spawn schemaChanged
tasks[]items in parallel and return a merged result payload when no async job manager is availablebuildSessionContext({ transcript: true })), with each compaction shown as a slim inline divider —── 📷 compacted · ctrl+o ──— at the point it fired; expanding (ctrl+o) reveals the summary and snapcompact frame count. Applies to live compaction,/compact,/treenavigation, and session resumeasync.enabledto gate async bash commands only — thetasktool now runs asynchronously regardless of the settingirc.timeoutMsto be the default timeout forircwaitandsendwithawait: truebuildPathTree,walkPathTree, find's grouped output formatter — nowformatGroupedPaths) to@oh-my-pi/pi-utilsso compaction summaries can render file lists with the same prefix-folded tree as find/search;tools/findno longer exportsformatFindGroupedOutputname: descriptionrows (collapsed view caps at 4 rules with a+N morehint, ctrl+o expands), and consecutive notifications merge into the previous block while it is still the live transcript tailRemoved
Fixed
irclive message delivery so successfully handed-off messages are no longer enqueued as mailbox mail, so they do not inflate unreadirccountsirc sendwithawait: trueto wait for a fresh reply to the current call instead of consuming previously buffered messagesircsends from the main agent as relay cardstaskcalls (agent,assignment) still execute undertask.batcheven though the wire schema is batch-firstjobtool's TUI preview leaking the model-facing<task-result>envelope for settled task jobs — the preview now shows the inner output body, and pretty-printed JSON bodies are flattened onto one line instead of previewing a lone{resolvetool's result block turning white after the leading icon: the accent-styled symbol embedded a foreground reset inside the inverse-rendered line, dropping the block color for the rest of the row<div id="root"></div>andindex.jsin smoke-test dashboard responsesthinking.autoPendingstatusbar indicator using question-mark glyphs (▣?, nf-md-help_box,[?]) in every symbol preset, which made the auto-thinking pending state indistinguishable from a terminal missing-glyph fallback. Replaced with clear loading indicators (⟳, fa-circle-o-notch,[~]) (#2267).tab.screenshot({ save })ignoring the save path's extension: an explicit.webp/.jpgdestination received hardcoded PNG bytes behind a mismatched name. The full-res capture format is now derived from the save path (png/jpeg/webp, puppeteer-native), and the reported mime type follows the bytes actually written; unknown or missing extensions still capture PNGcompaction.strategy: shakeauto-continue loop in thinking-heavy sessions: the post-shake check now uses the provider-anchored trigger metric (instead of a local estimate that undercountsthinkingSignaturepayloads) and only treats pressure as resolved when residual context lands inside an 80% recovery band, so shake reliably falls back to context-full compaction when it cannot create real headroom (#2275).@oh-my-pi/hashline
Changed
replace block N:/delete block N/insert after block N:failing to resolve a syntactic block) now append a numbered preview of the file around the anchor line — same*-marked context rows the hash-mismatch error shows — so the offending line is visible without a re-read@oh-my-pi/pi-natives
Breaking Changes
renderSnapcompactPng(text, options)to return a base64-encoded PNGstringinstead of aUint8ArrayAdded
renderSnapcompactPng:U+000E/U+000Fin the input switch to a dim gray ink (palette index 9) and back without occupying a glyph cell, letting callers visually de-emphasize spans such as archived tool outputrenderSnapcompactPng(text, options): rasterizes pre-normalized text onto a square PNG in an eval-validated snapcompact shape. Options select the bundled font (5x8X.org BDF or8x8unscii-8, both public domain, shipped incrates/pi-natives/src/fonts/), the ink variant (sentsix-hue sentence cycling orbwblack), line repetition (each text line printed N times, copies on a pale highlight band), and a target cell size — cells differing from the font's natural cell render via Lanczos3 stretch into an anti-aliased RGB frame (e.g. the OpenAI-optimal 6x6 unscii shape); native-cell shapes encode as 4-bit indexed PNG. Replaces the JS rasterizer/PNG writer previously in@oh-my-pi/pi-agent-core.@oh-my-pi/snapcompact
Breaking Changes
renderSnapcompactFrameoutput frompng: Uint8Arraytodata: stringbase64, requiring consumers to read frame payloads fromframe.dataAdded
toolResultMaxChars,toolArgMaxChars,toolCallMaxChars,truncateHeadRatio, anddimToolResultstosnapcompactCompact/serializeSnapcompactConversationso callers can tune how tool results and arguments are archivedSNAPCOMPACT_TOOL_RESULT_MAX_CHARS,SNAPCOMPACT_TOOL_ARG_MAX_CHARS,SNAPCOMPACT_TOOL_CALL_MAX_CHARS, andSNAPCOMPACT_TRUNCATE_HEAD_RATIOfor reuse when configuring truncation limitsSNAPCOMPACT_SHAPES,resolveSnapcompactShape,isSnapcompactShape) so callers can consistently select validated image-frame geometry for archive rendersfile-operations.mdandsnapcompact-summary.mdprompts to preserve file-read/write context and frame metadata in the compaction prompt flowpackages/snapcompact/researchexperiment and visualization suite for running snapcompact SQuAD studies, provider probes, and activation-style analyses@oh-my-pi/snapcompactwith typed access to snapcompact APIs@oh-my-pi/snapcompactas the reusable snapcompact compaction package, including bitmap-frame rendering helpers, archive helpers, and the localsnapcompactCompact()strategy.Changed
RenderedFramevisible-character accounting socharsno longer includes invisible dim-control markers<files>tag: one grouped, prefix-folded directory tree with per-file(Read)/(Write)/(RW)markers, replacing the separate<read-files>/<modified-files>lists;upsertSnapcompactFileOperationstakes the cumulative read set to distinguish(RW)from blind writesFixed
@oh-my-pi/omp-stats
Added
PI_BUNDLED, allowing the stats server to use an embedded dashboard bundle in packaged CLI distributionsFixed
embedded-client.generated.txtplaceholder content so it is treated as missing archive instead of being decoded into invalid bytesclient/ordist/clienttrees no longer crash startup@oh-my-pi/pi-tui
Added
onSubmithandlers by allowing the callback to return aPromise<void>@oh-my-pi/pi-utils
Added
path-treemodule (buildPathTree,walkPathTree,formatGroupedPaths,isUrlLikePath), moved from the coding agent's grouped file output so compaction file lists can share the same prefix-folded directory-tree rendering;formatGroupedPathsgains an optionalannotatecallback for per-file suffixesFixed
{{join}}prompt helper joining with a literal two-character\nwhen templates pass"\n"as the separator — Handlebars string literals carry no escape processing. The separator now unescapes\n/\t, matching the{{#list}}helper's documented convention (visible as literal\nbetween paths in compaction<read-files>lists).What's Changed
Full Changelog: https://github.com/can1357/oh-my-pi/compare/v15.10.12...v15.11.0
Configuration
📅 Schedule: (UTC)
🚦 Automerge: Enabled.
♻ Rebasing: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR has been generated by Mend Renovate.