Releases: BYK/opencode-lore
0.3.2
- fix(ci): stage CHANGELOG.md in preReleaseCommand and use PAT for tag creation by @BYK in 7461fa63
- fix(ci): checkout release branch for CHANGELOG.md and set git identity by @BYK in 30a318e6
- fix(ci): set artifactProvider to none for github-only target by @BYK in 87dafec1
- fix(ci): wrap preReleaseCommand in bash for env var expansion by @BYK in 2dce6728
- fix(ci): revert to github-only Craft target with separate npm OIDC publish by @BYK in a5646f0a
- fix(ci): remove registry-url from setup-node to avoid OIDC interference by @BYK in 4f04d3c7
- fix(ci): upgrade npm for OIDC trusted publishing (requires >=11.5.1) by @BYK in ceeccf00
- fix(ci): configure artifact provider for npm tarball lookup by @BYK in 697a98cf
- fix(ci): add actions:read permission for artifact download by @BYK in cc05628c
- ci: upload npm tarball artifact on release branches by @BYK in 9d700397
- fix(ci): resolve version from Craft output instead of branch name by @BYK in bd53d77c
- fix(ci): add production environment to release job for PAT access by @BYK in f3a6ebd5
- fix(ci): use PAT for release branch push to trigger CI by @BYK in b171b8c2
- ci: run CI on release branches for Craft status checks by @BYK in 067d1205
- fix(ci): use composite action for release to get issues:write permission by @BYK in 8da99bc0
- ci: use Craft npm target with OIDC trusted publishing by @BYK in 20c1be34
- ci: upgrade to Craft 2.22 reusable workflow with accepted-label publish flow by @BYK in 7261873b
- fix(ci): use Craft CLI directly instead of composite action by @BYK in 58dc4e87
- doc: add conventional commits convention to AGENTS.md by @BYK in 3dec8769
- ci: add Craft release workflow with npm trusted publishing by @BYK in 6b0ad08b
0.3.0
What's changed
New eval infrastructure
- Self-contained session eval harness (
eval/session_eval.ts): loads session transcripts from JSON files, distills on the fly, seeds the DB so therecalltool works during evaluation, and compares against OpenCode's actual compaction behavior (summary of early messages + 80K tail window) - 20 questions across two real coding sessions (113K and 353K tokens)
- Token tracking with cost-per-correct-answer metrics
Results (Claude Sonnet 4)
| Mode | Score | Cost |
|---|---|---|
| Default (compaction + 80K tail) | 10/20 (50%) | $8.14 |
| Lore (distillation + recall) | 17/20 (85%) | $1.87 |
Lore's 35pp accuracy advantage comes entirely from early/mid-session details outside the tail window. Late details are tied. Cost per correct answer: $0.11 vs $0.81 (7.4x cheaper).
Bug fixes
agents-file: sort category headings alphabetically in AGENTS.md exportltmtest: fix monotonic ID test failing on fast CI (Date.now() collision)src/index.ts: session error handler now skips eval/child sessions
Eval harness improvements
- All eval files import
DISTILLATION_SYSTEMfromsrc/prompt(DRY) backfill.ts:--wipeflag to clear old distillations before re-distillingcoding_eval.ts: token tracking, stronger eval session isolation- Removed LongMemEval harness and old result files
0.2.5
Fix
Infinite tool-call loop from evicting mid-turn agentic steps
In agentic mode, each tool-call step is a separate assistant message sharing the same parentID as the current user message. As steps accumulated, the cumulative token cost could exceed the gradient's rawBudget, causing tryFit to set a cutoff that dropped earlier steps from the current turn. The model saw only the most recent step(s) + the original user request, had no memory of prior work, and re-issued the same tool call — infinite loop.
Fix: tryFit now identifies the current turn (last user message + all following assistant messages) and treats it as an atomic protected unit:
- Reserves budget for the entire current turn upfront
- Returns
null(escalates to next layer) if the current turn alone exceedsrawBudget - Fills remaining budget with older messages — these are the only ones that can be evicted
- Marks current-turn messages as strip-protected for tool-output stripping
tryFitStable inherits the fix via its tryFit fallback.
0.2.4
Fix
Infinite tool-call loop from over-aggressive trailing-message drop
The unconditional trailing-message drop introduced in 0.2.2 removed assistant messages that had pending (non-completed) tool calls. The model would then re-issue the tool call on the next turn, producing another trailing assistant+tool message that got dropped again — an infinite loop.
Fix: before dropping a trailing non-user message, check if it contains a pending tool part. If so, stop dropping and log a warning instead. Completed tool parts are still dropped safely.
0.2.3
Fix
Calibration using wrong message count after compressed turns
After a gradient-compressed turn (layers 1-4), calibrate() was called with the total DB message count instead of the compressed window size. On the next turn, newMsgCount ≈ 0 (dbCount − dbCount), so expectedInput ≈ lastKnownInput (the compressed prompt, e.g. 114K tokens). Since 114K < maxInput (168K), layer 0 fired and sent all messages uncompressed → 405K overflow on a 200K-limit model.
Fix: transform() now records the compressed message count in lastTransformedCount. The calibration call uses getLastTransformedCount() so the delta on the next turn is computed relative to the actual compressed window, not the DB snapshot.
0.2.2
Fixes
-
Uncalibrated overflow: on first turn (no calibration data from a prior API response),
tryFitnow applies a 1.5x safety multiplier to its estimated token count before accepting a layer.chars/4estimates can undercount by up to 1.8x on sessions with large tool outputs — the window appears to fit but actually overflows. The multiplier causes the gradient to escalate to the next (more aggressive) layer until the adjusted estimate fits withinmaxInput. Calibrated turns (where exact API token counts are available) are unaffected. -
Trailing assistant message prefill error: removed the
breakon tool parts from the trailing-message drop loop. The break left trailing assistant messages with tool parts at the end of the compressed window, causing'This model does not support assistant message prefill. The conversation must end with a user message.'errors. Trailing non-user messages are now always dropped regardless of whether they contain tool parts.
0.2.1
Fixes
- Overflow recovery: removed
session.summarize()call on 'prompt too long' errors — it sent all messages to the model causing an overflow→compact→overflow stuck loop. Now just distills + setsforceMinLayer(2); gradient layers 2-4 handle compression on the next turn. - Chunked /compact: the compacting hook now runs chunked distillation first, injects pre-computed summaries into
output.context, and instructs the model to consolidate them rather than re-reading raw messages. Prevents overflow during/compacton large sessions. - Broader error detection: matches both
error.data.messageanderror.messageshapes; adds more overflow message patterns; adds diagnostic logging to stderr. - New export:
distillation.loadForSession()for reading distillation rows without going through gradient internals.
0.1.1
Fix system-reminder content leaking into persisted UI messages Moved statsPart lookup to after the gradient transform so the PATCH to OpenCode's server uses the cleaned part text (system-reminder wrappers stripped) rather than the pre-transform ephemeral version.