feat(core): let the agent consult its own past sessions - #272
Open
oratis wants to merge 1 commit into
Open
Conversation
Every session is already on disk as JSONL. Nothing could read it back, so "how did we fix this CI failure last month" was unanswerable — while the answer sat in a file the agent itself wrote. Having the history locally is the one thing a local agent has over a hosted one, and it was going unused. SessionSearch finds text across past sessions, newest first, and returns excerpts tagged with a session id and message offset. SessionRead follows a hit into the surrounding conversation. Together they are Grep and Read for history. Scope is the load-bearing decision, not the search. Searching every session on the machine would let a session opened in one project pull another project's code, client names, or credential fragments into this context. So the default — and, unless the user changes a setting, the only behavior — is the current workspace, matched on a resolved path boundary so /a/project does not capture /a/project-two. Neither tool takes a scope argument. That is deliberate: a parameter would let the model consent to reading another project's history on the user's behalf. SessionRead enforces the same rule, so knowing an id is not authorization. No index. A few thousand JSONL files scan in tens of milliseconds, and an index is a second copy of the truth that can disagree with it. If the volume ever outgrows a scan, an index goes behind this same interface. A corrupt or half-written session is skipped rather than failing the search: it is one of many, and the rest are still worth returning. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fifth implementation PR from
docs/DSH_ADOPTION_PLAN.md§1.5.The gap
Every session is already written to
~/.deepcode/sessionsas JSONL. Nothing could read it back. "How did we fix this CI failure last month" was unanswerable, while the answer sat in a file the agent itself wrote.Having the whole history on the machine is the one structural advantage a local agent has over a hosted one, and it was going unused.
SessionSearchfinds text across past sessions, newest first, returning excerpts tagged with a session id and message offset.SessionReadfollows a hit into the surrounding conversation. Together they are Grep and Read, for history.Scope is the decision here, not search
This is the part worth reviewing. Searching every session on the machine would let a session opened in one project pull another project's code, client names, or credential fragments into the current context. That is a privacy surface, not a convenience knob.
So the default — and, unless the user changes a setting, the only behaviour — is the current workspace, matched on a resolved path boundary so
/a/projectcannot capture/a/project-two.Neither tool takes a scope argument, and there is a test asserting the schema has no third property. A parameter would let the model consent to reading another project's history on the user's behalf, which is not the model's consent to give.
SessionReadenforces the same rule independently, so knowing an id is not authorisation — otherwise scoping would be a suggestion rather than a rule.No index
dsh backs its equivalent with SQLite FTS. Skipped: a few thousand JSONL files scan in tens of milliseconds, and an index is a second copy of the truth that can disagree with it — plus a schema version to migrate and a native dependency to ship. If volume ever outgrows a scan, an index goes behind this same interface with no caller change.
A corrupt or half-written session is skipped rather than failing the search: it is one of many, and the rest are still worth returning.
Verification
pnpm typecheck,lint,format:checkclean. Full suite green — core 1062 passed / 28 skipped, cli 242, desktop 104, server 49, protocol 34, lsp 13, vscode 12, scripts 42.28 new tests. The ones carrying weight are the negative ones: another workspace stays invisible by default,
SessionReadrefuses a known id from another workspace and does not leak its content in the error,/a/project-twois not inside/a/project, and the running session is excluded from its own results.Related
While writing these tests I found
new SessionManager(sessionsRoot)silently ignores a positional argument (the constructor wants{ root }) and falls back to the real~/.deepcode/sessions. A test I added in #268 was doing exactly that and writing into the user's home directory on every run — fixed on that branch, and this PR's tests use the correct form throughout.