Repository navigation
perf(opencode): load session history once per turn, append the id-tail per step - #26
PierrotAWB wants to merge 1 commit into
Conversation
…l per step Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Hey! Your PR title Please update it to start with one of:
Where See CONTRIBUTING.md for details. |
|
The following comment was made by an LLM, it may be inaccurate: |
There was a problem hiding this comment.
1 issue found across 2 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="packages/opencode/src/session/prompt.ts">
<violation number="1" location="packages/opencode/src/session/prompt.ts:1218">
P2: On multi-step plan/build turns, `cachedMsgs` retains each iteration's in-memory reminder and plugin mutations, so synthetic prompts or transformed parts accumulate across model requests. Keep the cached history immutable, or run per-step transforms on a clone and merge only persisted changes.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
| Effect.provideService(FSUtil.Service, fsys), | ||
| Effect.provideService(Session.Service, sessions), | ||
| ) | ||
| cachedMsgs = msgs |
There was a problem hiding this comment.
P2: On multi-step plan/build turns, cachedMsgs retains each iteration's in-memory reminder and plugin mutations, so synthetic prompts or transformed parts accumulate across model requests. Keep the cached history immutable, or run per-step transforms on a clone and merge only persisted changes.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/opencode/src/session/prompt.ts, line 1218:
<comment>On multi-step plan/build turns, `cachedMsgs` retains each iteration's in-memory reminder and plugin mutations, so synthetic prompts or transformed parts accumulate across model requests. Keep the cached history immutable, or run per-step transforms on a clone and merge only persisted changes.</comment>
<file context>
@@ -1197,6 +1215,7 @@ const layer = Layer.effect(
Effect.provideService(FSUtil.Service, fsys),
Effect.provideService(Session.Service, sessions),
)
+ cachedMsgs = msgs
const msg: SessionV1.Assistant = {
</file context>
|
Consolidated into #29 (one commit per concern there; review history for the prep_ms retry semantics is on this PR's threads). |
Issue for this PR
Issues are disabled on this fork; motivation below. Stacked on #25 (phase telemetry); re-target after it merges.
Type of change
What does this PR do?
runLoopreloaded and re-hydrated the entire session history from SQLite on every step (filterCompactedEffectinside thewhileloop) — O(history × steps) I/O per turn, the largest per-step prep cost on long sessions. The runner lock makes a turn the session's single writer, so the loop can reuse what it already loaded.Now the first iteration loads history as before; each later iteration fetches only rows with id greater than the last-seen id (new
MessageV2.after, one indexed query — ids are monotonic per session) and appends. Two correctness guards, both traced against real behaviors:createUserMessageruns before the runner parks); today's per-step reload picks it up, and the id-tail query preserves exactly that.filterCompacted) is no longer append-stable, so the loop recomputes from scratch.The cache is captured after
SessionReminders.applyso reminder transforms persist into it, and it lives only for onerunLoopinvocation — cross-turn behavior is untouched.How did you verify your code works?
The existing multi-step, subtask, question, and compaction suites all depend on correct cross-step history threading and are the golden tests here:
prompt.test.ts+compaction.test.ts+message-v2.test.ts148/148, fullpackages/opencodesuite 3129 pass with the only failures being the pre-existingTruncatedate bug (fixed in #24, not in this branch's ancestry) and a pty test that passes 9/9 in isolation (load-contention flake).bun run typecheckclean,bun run lint0 errors. Fleet-wide before/after comes free from #25'shistory_msfield.Checklist
🤖 Generated with Claude Code
Summary by cubic
Loads session history once per turn and appends newly created messages by id on subsequent steps, replacing per-step full reloads. This removes O(history × steps) I/O in long turns while preserving correctness and cross-turn behavior.
MessageV2.after(sessionID, id)to fetch rows with id > last seen (ids are monotonic per session).msgsacross steps in the turnrunLoop; if fresh rows include any compaction part or an assistant summary, recomputes the retained window from scratch.SessionReminders.apply, so reminder transforms persist; cache lives for a singlerunLoop.history_msto validate the perf win.Written for commit 2137c4c. Summary will update on new commits.