Skip to content

Releases: jonaslsaa/pi-optchat

v0.8.2

Choose a tag to compare

@jonaslsaa jonaslsaa released this 09 Oct 14:08
6804bec

The main agent can now check on its subagents instead of taking their word for it, and profile memory sits behind one Store interface so it can live somewhere other than local files later.

Read a subagent's chat (#128)

zoom("<run id>") returns a subagent's chat so far: its task, replies, tool calls, tool results and what it was told. Tool calls and results are cut to their first and last ~500 characters, so one page covers many steps; pages are 25,000 characters. Every subagent report now ends with Full chat: zoom("<id>"), so the main agent can verify a claim like "CI green, 198 tests pass" against what the child actually ran. Works on running children too. Thanks to @aaaxn for the review that shaped this.

Know which subagents are running (#132)

While at least one subagent is running, each new input to the main agent (your message, a report, a tell_parent, the restart note) ends with one line:

[OptChat status] Agents at work now: 8f28e694 "Review PR #123 carefully", …

It is never stored, never sent while nothing runs, and sits after the cache marks so it costs nothing. Along the way this fixed a real cache bug: Pi ends Anthropic requests with an empty system message, and the turn's cache mark could land on the wrong block.

Memory behind a Store seam (#133)

Every durable memory read and write now goes through Store (src/store.ts). The only store is FileStore, which is the old code moved: the files on disk are byte-identical, so upgrading changes nothing. A store may write asynchronously (Memory keeps order and awaits on close) and may optionally provide a cross-machine lease; without one, the machine-local lock runs as before. This is the groundwork for a store shared between machines (for example Postgres); no discovery or settings yet. Import records stay per machine.

Small

  • Deleting a finished agent is now remembered in memory as [id] deleted by the user (#134). Running agents already report when stopped, so nothing is duplicated.

228+ tests pass on macOS, Linux and Windows.

0.8.1

Choose a tag to compare

@jonaslsaa jonaslsaa released this 09 Oct 00:14
2c7346d

A small release on top of 0.8.0: summaries with less filler, subagents that survive a Pi restart, and two delivery bugs fixed.

Less filler in summaries (#129)

The compaction prompt now says the size limit is a ceiling, not a target. Before, summaries padded short tool steps up to the limit and quoted bare "sure" / "done" replies word for word. Blind A/B over four prompt variants on frozen copies of real profiles ($25): this one wins on recall (+0.8 personal, +2.5 work) while cutting filler by about a quarter on the personal profile. Two variants that rewrote the prompt more aggressively lost recall and were dropped.

Along with it (#130): a summary now describes a tool result by what its output shows, not by a cause guessed from an exit code or an empty match. An audit of 42 recent memory lines found 4 invented causes of that kind.

Subagents survive a Pi restart (#126)

/reload or a Pi restart used to kill every running subagent, leaving them interrupted forever. Now their transcripts are kept, and when the profile comes back the cut-off subagents are resumed from where they were, with a short note to the main agent about who was restarted. Headless pi -p sessions don't resume anything.

Reports that Esc threw away (#127)

A subagent report arriving while the main agent was busy went into Pi's steer queue; pressing Esc cleared that queue and the report was lost until the next /reload, where it showed up hours late as a stale message. Reports are now re-sent as soon as the agent settles.

Import concurrency is a setting (#125)

"Import: summaries at once" (default 8, 1–64) controls how many summaries an import runs in parallel. Higher is faster; each extra one means summaries are written with one more unsummarized neighbour, about 0.8 points of recall per step in our measurements, so leave it unless an import is painfully slow.

For contributors (#130)

Every prompt sent to a model now lives in src/prompts.ts as readable multi-line text with a comment saying where it's used; the recipe's four prompts are byte-identical to before. The main and subagent prompts gained a note about not polling slow things (CI, deploys) yourself.

0.8.0

Choose a tag to compare

@jonaslsaa jonaslsaa released this 08 Oct 22:41
3615e74

OptChat 0.8.0 is the biggest release so far. It brings the memory engine in line with Victor Taelin's revised OptChat recipe, runs on Windows, remembers images, imports Pi and OMP sessions, works headless, and imports about twice as fast. Every change below was measured on real memories before it shipped: the studies are linked from Epic #101.

The revised recipe (Epic #101)

Victor revised his OptChat gist on Oct 7. We went through it line by line and adopted everything that proved itself in a blind A/B on frozen copies of real profiles.

  • Summaries keep more of what matters (#112). The compactor now runs Victor's whole revised compaction prompt. Blind Opus grading over 88 summaries: work memory +4.3 ± 1.3 (12 wins, 1 loss), personal +1.3 ± 1.4, same cost. We also tested giving the compactor your AGENTS.md: no gain and 7× more invented facts, so it stays blind to your instructions on purpose.
  • Turns read the view from the cache (#96, @aaaxn). The view is merged in batches and remembered in view.json, so the prompt prefix stays byte-stable between turns. Cache hit rate on a live profile: 29% → 96% personal, 41% → 92% work.
  • Compactions get their own smaller view and run up to 8 at once (#97, @aaaxn; #106, #108). A summary starts as soon as fewer than 8 lines before it are unbuilt, with gaps shown as placeholders. A 20-message burst now settles in about 10 s instead of 42 s, at a quality cost of 0.27 points per summary (vs 0.8 without placeholders). A turn also goes on once every summary it waited for has failed, instead of hanging forever.
  • The view is the truth (#102). The agent's prompt now carries the revised recipe's memory rule: find the latest mention in the view and zoom before any other source.
  • Subagent reports are their own memory kind, work: (#103), delivered as each one finishes. Grouped delivery is still there as a setting, now off by default for new profiles (existing profiles keep what they have).
  • Huge messages are read in pages (#93, #117). zoom(id, 1) on a 100 KB tool result used to lose its middle; now it pages 25,000 characters at a time, and tells the agent when it pages a message that would have fit in one zoom. Chosen over splitting messages on write by A/B: 26/32 vs 19/32 questions answered.

The full list of where we still deviate from the gist, and the numbers behind each choice, is in this comment.

Windows (#88, @bobneumann)

OptChat runs on Windows: profile locks over named pipes, ZIP import through the built-in tar.exe, and a windows CI job on every PR. Live-tested on a real Windows Server runner (#115, #116, #119, #122 give maintainers an SSH-able Windows machine on demand). The run found and fixed a real bug in re-imports on the way. Image paste, the memory browser and spaced paths are not yet tested on a Windows desktop: reports welcome. Closes #85.

Along with it, from @lmvdz: a half-created profile is cleaned up so the name can be retried (#120), and new tests for flush failure and lock recovery after the owner is killed (#121).

Images in memory (#113)

Pasted screenshots and image tool results used to become the text "[image attachment]" in memory. They are now stored once under images/<hash> (resized to at most 2048 px / 2 MB) and zoom(id, 1) returns the actual picture, so the agent can look at a screenshot from last week.

Import Pi and OMP sessions (#111, started by @netroms in #74)

A new import source reads Pi's own sessions and OMP's, which share a format. Off-path branches are tagged [alternate branch], /skill: prompts are kept, and !!cmd / $$code (hidden from the model when typed) are left out.

Headless Pi (#99, @ahlner; #110)

pi -p and RPC sessions no longer drop the prompt silently. A headless Pi never picks or creates a profile on its own; with a bound profile it joins the Pi that already has it open and prints the final reply, controlled by --optchat-connect auto|join|off.

Faster imports (#114)

Imports now summarize 8 messages at once with the same ahead rule as live chat. 228 messages: 356 s → 152 s, at the same cost.

Smaller things

  • Delete a subagent from the Agents page: press d twice on its row, running ones are stopped first (#123, @aaaxn). A connected window whose run is deleted is told so instead of waiting forever.
  • "Waiting for OptChat summaries…" shows the compactor's last error instead of a bare spinner (#91, reported by @tfcace).
  • /reload no longer re-logs a message that was queued, taken back with Esc, and sent again (#109).
  • A shown custom message counts as a user message, as in Pi (#87, @aaaxn).
  • The repo now protects main, release tags and npm publishing (#90).

Known issue

Running pi-interactive-subagents alongside OptChat can leave its subagent tool with a stale context after an OptChat spawn (#92, reported by @alexeyche). The cause is in that extension; the fix is open upstream as maplezzk/pi-extensions#234.

Upgrading

  • Restart or /reload every Pi window after updating.
  • The first turn on each profile is cold once: the view cache (view.json) is built, then turns hit the cache.
  • The compactor prompt changed, so new summaries read a little differently from old ones. Old summaries are untouched.
  • New profiles get Group subagent reports off; flip it in /optchat settings if you preferred one combined report.

218 tests. Thanks to @aaaxn, @bobneumann, @lmvdz, @ahlner, @netroms, @tfcace and @alexeyche, and to Victor Taelin for the recipe.

v0.7.2

Choose a tag to compare

@jonaslsaa jonaslsaa released this 06 Oct 21:47
d692f03

What's new

  • Searchable model picker (#83). /optchat model, /optchat agents model, the menu item and the inspector's M key now open the same searchable, scrolling 10-row picker the settings page uses: type to filter, current model marked, thinking step lists only levels the model supports. Replaces the plain select list that overflowed the terminal.

Upgrading

Update the package and restart every Pi window. 174 tests pass.

v0.7.1

Choose a tag to compare

@jonaslsaa jonaslsaa released this 06 Oct 20:55
07e5fd1

What's new

  • Activity view (#80). /optchat activity, or Tab from the Agents and Usage pages, shows where memory stands: how many messages it holds, how big the view is against the 128 KB budget, and whether summaries are Settled or Catching up (with a progress bar and the last error, if any), plus how many agents are running. The bar item gets an accent dot while anything is in flight. The old u shortcut is gone; Tab cycles the pages.
  • Interrupt a subagent from the agent view (#81). Ctrl+C no longer closes the view blind: on a working agent it aborts the current step. If you had messages queued they're delivered right away and the agent carries on; otherwise it pauses as interrupted · waiting for you until your next message (or a tell from main) resumes it, and main gets a one-line note. Up on an empty input pulls your newest queued message back for editing. Ctrl+X twice remains the only way to stop an agent. Subagents are also told not to run any single command longer than about a minute, so steering reaches them promptly.

Upgrading

  • Restart every Pi window after updating.

173 tests.

0.7.0

Choose a tag to compare

@jonaslsaa jonaslsaa released this 06 Oct 17:17
e4af09a

What's new

  • Grouped subagent reports (#70). The subagents started by one spawn now report together, in one message once the last of them finishes, as in Victor's recipe. A new per-profile setting, Group subagent reports (on by default), switches back to each subagent reporting as soon as it finishes. Reports held for a group survive a crash.
  • Memory search, opt-in (#73, #75). Agents can get a search tool that finds original messages by plain text, newest first, for exact names, numbers, paths or errors the memory view no longer shows. Each hit names the view line that covers it, and the prompt now says that zoom also works outward, so the agent can read the summary around a hit. It is off by default: turn Memory search on per profile in /optchat settings. The A/B study behind it is in this comment.
  • npm releases from GitHub Actions (#71). Publishing a GitHub release now publishes the package to npm with trusted publishing.

Fixes

  • Compactor thinking "off" really is off, or as low as the model allows (#66). Sonnet and Opus 5.5 have no "off", and Pi silently ran them at high effort. The pickers now list only the levels a model supports, and summaries and handoffs clamp to the lowest one.
  • The compactor's size example no longer leaks into memory (#72). The made-up sample line was sometimes summarized as if it were real chat. It is now a true line about OptChat, fenced as an example.
  • A failed summary is always retried (#68), and an unreadable import journal no longer breaks a turn (#69, the status line shows "import journal invalid" instead; thanks @aaaxn for #59).
  • A resumed Claude Code session is imported once (#77). Messages Claude Code copies into a resumed session are matched by message id and skipped. Built from @aaaxn's #62 and his review.

From @aaaxn, thank you

  • Tests never touch your real home folder (#54), and new tests for resuming and closing subagents (#55, #56).
  • A shared OpenAI prompt-cache key for compactor calls (#58).
  • Cleaner imports: Claude Code command output dropped while commands stay as typed (#60), context Codex injects dropped (#61), shorter headers on imported messages (#64).
  • Imports feed Memory one message at a time, as a live chat does, and refuse an invalid staged plan (#63). This follows Victor's recipe more closely, but a large import now sends the summarizer about 3x more input.

Upgrading

  • Restart every Pi window after updating.
  • Memory search stays off until you turn it on in /optchat settings. Group subagent reports is on; turn it off there to get each report right away, as before.

165 tests.

0.6.8

Choose a tag to compare

@jonaslsaa jonaslsaa released this 06 Oct 13:34
22a5e91

What's new

  • /optchat settings (#50). A per-profile settings page, saved in the profile's config.json: compactor and subagent models, subagent levels, max active agents, Previous exchange (on/off and its size limit) and summary size tolerance. Every row shows its value and its default. /optchat model and /optchat agents model still work as shortcuts. The last-exchange study behind the Previous exchange default is in this comment.
  • Previous exchange is capped (#41). The last exchange is still replayed in full, but one over 16 KB is dropped, and the agent reads it from memory instead.
  • Turns wait only for summaries (#42). A turn no longer also waits for the memory view to fit its budget, which matches Victor's recipe.
  • A real sample line for the compactor (#43). The dot-padded example line is replaced with an exact 512-byte sample, so its wording stops leaking into summaries.
  • Merged lines must save space (#49). A summary is kept without a retry only if it fits the size tolerance and is smaller than the lines it replaces.
  • Fixes from @aaaxn (#44, #45, #46, #47, #48), thank you:
    • cache marks survive a summary that quotes </chat>
    • bad usage records are rejected
    • Tab toggles in the import picker
    • run state changes can no longer be corrupted by a late stop, close or tell
    • a stale "Waiting for summaries" message is cleared, and import time, chain and YAML parsing are fixed
    • a second writer on a profile log is refused
  • Profile lock and early stops (#51). The lock and window sockets now live in the profile folder, so Pis with different TMPDIRs share one lock. A file that only shares a socket's name is refused, never deleted. A subagent stopped before its first request no longer runs its task.
  • A banner on pi.dev (#52). The package now has a preview image in the Pi package gallery and the README.

Upgrading

  • Subagent levels now default to 1 (Victor's flat recipe: subagents don't spawn their own). To keep the old nesting, set Subagent levels to 3 in /optchat settings.
  • Restart every Pi window after updating. The profile lock moved, so an old and a new Pi would not see each other's lock.

146 tests.

v0.6.7

Choose a tag to compare

@jonaslsaa jonaslsaa released this 06 Oct 01:23
4196ab3

What's new

  • Readable usage page (#35). The usage page now has period tabs, one headline (estimated cost, tokens, cache share) and an aligned table per role and model with cost, share, output and cache %. Large numbers are shortened, and the same model is no longer listed twice when a record has no provider.
  • Main-chat images no longer show through the agent view (#36). Pi's overlay compositor skips lines that contain terminal images (earendil-works/pi#6995), so images from the main chat were drawn over the full-screen agent view. While the agent view is open, OptChat now blanks those lines and brings them back when you close it.
  • Cheaper parallel compaction (#37). If the memory view is not cached yet, one compactor call goes first and the others wait until it starts answering, so they read the cache instead of each writing it. In a live A/B test, a catch-up batch of 8 calls cost 36% less and a normal-pace replay cost 9% less. Summaries were byte-identical.
  • Fewer compactor retries (#38). The compactor still asks for 512 bytes but keeps summaries up to 640 bytes instead of retrying them.

100 tests.

v0.6.6

Choose a tag to compare

@jonaslsaa jonaslsaa released this 05 Oct 23:56
1688d56

What's new

  • tell resumes finished subagents (#32). Telling a subagent that has finished (also one from an earlier session) reopens its saved transcript with the same id, parent, model and directory and continues the conversation. It takes one of the 8 slots again. Only its original parent can resume it. Connected windows are not resumed. If the transcript, directory or model is missing, you get a clear error.
  • Subagents get Pi's built-in extensions (#33). Children now load the same built-ins as the main session (MCP, codemode, tool search), so MCP tools such as Datadog and Slack work in subagents. --no-mcp and settings that turn built-ins off still apply. A child whose extensions fail to start, or whose launch or resume is rolled back, now shuts its extensions down so MCP servers do not keep running.

94 tests.

v0.6.5

Choose a tag to compare

@jonaslsaa jonaslsaa released this 05 Oct 21:57
53fcdf7

What's new

  • A subagent whose cleanup fails no longer hangs things (#29): if a finished subagent's session failed to close, its report was lost, its slot stayed taken, and a waiting parent could freeze the whole Pi. The report is now delivered and the slot freed, including when a batch fails partway through launching.
  • Fixes from aaaxn's fork (#30, thanks @aaaxn):
    • Faster memory: loading a large profile is about 10× quicker (100k messages: 4.4s → 0.4s), with identical views.
    • /skill: commands and messages with images are no longer recovered as unanswered input after a restart.
    • A broken package.json above an installed extension no longer blocks spawning subagents.
    • Subagent task folders can start with ~ or be relative; a missing folder is refused with a clear error.

85 tests pass.