Conversation
…handling Bug 1: Worker sessions were reused across multiple LLM calls in distillation and curation. Each call's assistant response with reasoning/thinking parts accumulated in the session history. When the next call sent the full history back, providers rejected it with 'Multiple reasoning_opaque values received in a single response'. Fix: Delete the parent→worker mapping from the workerSessions Map immediately after reading the response in all 4 functions (distillSegment, metaDistill, curator.run, curator.consolidate). This ensures each LLM call gets a fresh session. Worker session IDs are kept in workerSessionIDs Set so shouldSkip() still recognizes them. Bug 2: The recall tool's execute() had no try/catch. If any of the three search calls (temporal.search, searchDistillations, ltm.search) threw, the entire tool execution failed and returned nothing. Fix: Wrap each search call in independent try/catch blocks so partial results are returned even if one source fails. Errors are logged via log.error() (always visible).
Almost every query in the codebase filters on (project_id, session_id) but only single-column indexes existed, forcing SQLite to pick one and scan the remaining rows for other conditions. New compound indexes (schema version 6): - temporal_messages(project_id, session_id) — 10+ queries - temporal_messages(project_id, session_id, distilled) — undistilled() - temporal_messages(project_id, distilled, created_at) — pruning - distillations(project_id, session_id) — 8+ queries - distillations(project_id, session_id, generation, archived) — gen0 ops Drop redundant single-column indexes that are now left-prefixes: - idx_temporal_project (prefix of idx_temporal_project_session) - idx_temporal_distilled (low-selectivity, covered by compounds) - idx_distillation_project (prefix of idx_distillation_project_session)
- Add error.name === 'ContextOverflowError' check to isContextOverflow()
so it catches both API-level overflow and OpenCode's compaction overflow
('Conversation history too large to compact')
- Wrap LorePlugin body in try-catch with process.stderr.write for always-on
error visibility (not gated by LORE_DEBUG)
- Add '[lore] active: <path>' startup log so silent init failures are
immediately detectable
- Add 4 test cases for ContextOverflowError name matching
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.
Problem
Two issues causing sessions to get permanently stuck with context overflow errors:
isContextOverflow()misses OpenCode's compaction error: When a session overflows and OpenCode's built-in compaction also fails, the error hasname: 'ContextOverflowError'with message'Conversation history too large to compact'. Lore's detection only checked for 5 API-level message strings — none match this compaction error, so auto-recovery never triggers.Silent plugin initialization failures: Lore hasn't captured messages for any session since March 12. The plugin init fails silently because all lore logging is gated behind
LORE_DEBUG, and OpenCode's plugin loader catches and swallows the error. Zero visibility into what's going wrong.Fix
Part 1:
isContextOverflow()name-based detectionAdd
error.name === 'ContextOverflowError'as the first check, before the message text pattern matching. This catches:Part 2: Always-on init visibility
LorePluginbody in try-catch that logs the full error + stack trace viaprocess.stderr.writebefore re-throwing[lore] active: <path>success log at end of init (always-on, not gated byLORE_DEBUG)Tests