Suggestion: optional delta hook on SessionStore #89
Replies: 4 comments
-
|
this makes a ton of sense to me, definitely directionally interesting. We designed our message format with this in mind, where compaction doesn't overwrite the message conversation history and instead just appends a "compaction point" in the conversation history, preserving the original history. I'd love for this layer to be more pluggable, similar to how we do sandboxes. If we could create a session persistence API that any DB/storage solution could hook into, that would be great.
FYI If you're on Cloudflare, you should be getting persistence already out of the box, thanks to Durable Objects and D1. |
Beta Was this translation helpful? Give feedback.
-
|
Thanks Fred — the "compaction as append point, not overwrite" detail is exactly the constraint I was hoping someone with the design history would confirm. That makes Option A (the optional
Strong +1, and that's the right shape. I'd been holding back on a Two ways to thread this:
I'm fine with either — leaning toward (1) since the docs and the category land most naturally together. Will comment on the PR with the same question so the conversation has a single home.
Quick fact-check: Durable Objects yes (the generated Cloudflare entry uses |
Beta Was this translation helpful? Give feedback.
-
|
Closing the loop on this one. PR #87 shipped the connector restructure (Postgres + D1 recipes as Tests deferred to a follow-up after the in-flight |
Beta Was this translation helpful? Give feedback.
-
|
Possibly related contribution from @ketankhairnar — opened #95 which appears to be addressing this. Their summary: Adds an optional Implementation: ketankhairnar/flue@feat/sdk-savedelta-hook (diff) This comment was posted automatically when #95 was redirected. The implementation is preserved on the branch above so it can inform the work here. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Suggestion: optional delta hook on SessionStore
What I noticed
While drafting persistence guides for Postgres and D1, I went looking at how other coding-agent CLIs persist sessions to see if there were patterns worth lifting. Three independent implementations have landed on the same shape — append-only event log + queryable index:
~/.claude/projects/<project>/<sessionId>.jsonl— one line per event, append-only. Sidecar.meta.jsonand.session-intelligence.json.The thread that runs through all three: don't rewrite the whole conversation history every turn. Append the delta. Read by reconstructing.
How this maps to flue
Flue's data model is already append-friendly —
SessionEntryhas stableid, immutableparentId, and compaction creates new entries pointing back at afirstKeptEntryIdrather than mutating prior ones. The bit that doesn't fit the append model is the store interface:save()is blob-overwrite — every turn, the adapter receives the entireSessionDataand is expected to persist all of it. For a 50-turn coding-agent session with embedded tool results, that's hundreds of KB rewritten on every save.Concretely, the Option 2 schema referenced in the new persistence guides (the append-log shape Claude Code / Codex / OpenCode use) currently has to:
SessionDatafromsave().That diff cost is paid by every adapter, and the interface gives the adapter no signal about what changed. Worst case: a session where compaction replaced recent entries with a summary; the adapter has to detect that the prior entries should be marked superseded.
For discussion: a small, opt-in delta hook
Extend
SessionStorewith an optional method that, when present, is called instead ofsave()with just what's new:Properties of this shape:
save()keeps working.InMemorySessionStore, the Cloudflare DO store, and the new Postgres/D1 recipes need zero changes.SessionData— it knows what it just appended. Probably <50 lines insession.tsto thread it through.(A larger reshape — a fully entry-level interface with
appendEntries/loadEntriesinstead of save/load — is also possible but bigger; mentioning for completeness, not advocating.)What I'd want to know
Is this directionally interesting, or does the blob-overwrite shape stay because of constraints I'm missing (e.g. something about compaction's
firstKeptEntryIdpointer or branch-summary entries that doesn't fit the delta model cleanly)? Happy to draft a PR if so, or back off if not.Beta Was this translation helpful? Give feedback.
All reactions