@bd7pil/opencode-deep-memory 0.5.1 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +67 -16
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -15166,6 +15166,53 @@ async function writeCheckpoint(args) {
|
|
|
15166
15166
|
|
|
15167
15167
|
// src/hooks/compacting.ts
|
|
15168
15168
|
import { readFile as readFile2 } from "fs/promises";
|
|
15169
|
+
|
|
15170
|
+
// src/extract/summarize.ts
|
|
15171
|
+
var HANDOFF_PREFIX = `Another OpenCode session started by the same user was working on this task. It was compacted mid-conversation to save context space. Review the summary below to understand what happened and continue from where it left off.`;
|
|
15172
|
+
var STRUCTURED_COMPACTION_PROMPT = `You are performing a CONTEXT CHECKPOINT COMPACTION.
|
|
15173
|
+
Create a structured handoff summary for an LLM that will resume the task.
|
|
15174
|
+
|
|
15175
|
+
SUMMARY SECTIONS (include all that apply):
|
|
15176
|
+
|
|
15177
|
+
## Task Overview
|
|
15178
|
+
One sentence: what the user is building, fixing, or investigating.
|
|
15179
|
+
|
|
15180
|
+
## Current Progress
|
|
15181
|
+
### Completed
|
|
15182
|
+
- Specific changes made (file paths, functions, tests)
|
|
15183
|
+
- Commands executed and their outcomes
|
|
15184
|
+
### In Progress
|
|
15185
|
+
- What was being worked on when compaction happened
|
|
15186
|
+
- Partial edits, unresolved questions
|
|
15187
|
+
|
|
15188
|
+
## Key Technical Decisions
|
|
15189
|
+
- Decision \u2192 Reasoning (e.g., "used Map over Array for O(1) lookup")
|
|
15190
|
+
- Architecture choices and tradeoffs discussed
|
|
15191
|
+
|
|
15192
|
+
## Constraints & Requirements
|
|
15193
|
+
- User preferences (coding style, libraries, patterns)
|
|
15194
|
+
- Explicit constraints (must not, always, never)
|
|
15195
|
+
- Environment details (OS, Node version, dependencies)
|
|
15196
|
+
|
|
15197
|
+
## Files Modified or Touched
|
|
15198
|
+
- path/to/file \u2014 what changed and why
|
|
15199
|
+
|
|
15200
|
+
## Errors Encountered & Fixes
|
|
15201
|
+
- Error message \u2192 Root cause \u2192 Fix applied
|
|
15202
|
+
- Unresolved errors that need attention
|
|
15203
|
+
|
|
15204
|
+
## Next Steps
|
|
15205
|
+
- Clear, actionable items to continue the work
|
|
15206
|
+
- Dependencies: what must be done first
|
|
15207
|
+
|
|
15208
|
+
## Critical Context
|
|
15209
|
+
- Specific values, API keys (do NOT include real secrets), configuration
|
|
15210
|
+
- User's exact phrasing when it matters
|
|
15211
|
+
|
|
15212
|
+
Be concise. Prefer structured lists over prose. Focus on what the next LLM NEEDS to know to continue seamlessly.
|
|
15213
|
+
`;
|
|
15214
|
+
|
|
15215
|
+
// src/hooks/compacting.ts
|
|
15169
15216
|
function createCompactingHandler(args) {
|
|
15170
15217
|
const { client, state, projectPath, logger, tracker } = args;
|
|
15171
15218
|
return async (input, output) => {
|
|
@@ -15211,6 +15258,10 @@ function createCompactingHandler(args) {
|
|
|
15211
15258
|
logger
|
|
15212
15259
|
});
|
|
15213
15260
|
state.setPendingEnrichment(sessionID);
|
|
15261
|
+
if (capture.messageCount >= 20) {
|
|
15262
|
+
output.prompt = STRUCTURED_COMPACTION_PROMPT;
|
|
15263
|
+
}
|
|
15264
|
+
output.context.push(HANDOFF_PREFIX);
|
|
15214
15265
|
output.context.push(
|
|
15215
15266
|
`Prior conversation archived to ${checkpointPath}`
|
|
15216
15267
|
);
|
|
@@ -15236,8 +15287,8 @@ function createCompactingHandler(args) {
|
|
|
15236
15287
|
var FALLBACK_MAX_CONTEXT = 128e3;
|
|
15237
15288
|
var OPENCODE_COMPACTION_RATIO = 0.75;
|
|
15238
15289
|
var THRESHOLDS = {
|
|
15239
|
-
medium: 0.
|
|
15240
|
-
high: 0.
|
|
15290
|
+
medium: 0.2,
|
|
15291
|
+
high: 0.4
|
|
15241
15292
|
};
|
|
15242
15293
|
var calibratedMaxContext = 0;
|
|
15243
15294
|
function calibrateFromCompaction(lastInputTokens) {
|
|
@@ -15318,7 +15369,7 @@ function detectPressure(messages, modelContextWindow) {
|
|
|
15318
15369
|
}
|
|
15319
15370
|
|
|
15320
15371
|
// src/compress/nudge.ts
|
|
15321
|
-
var NUDGE_COOLDOWN =
|
|
15372
|
+
var NUDGE_COOLDOWN = 3;
|
|
15322
15373
|
function shouldInjectNudge(level, messagesSinceLastNudge) {
|
|
15323
15374
|
if (level !== "high") return false;
|
|
15324
15375
|
if (messagesSinceLastNudge < NUDGE_COOLDOWN) return false;
|
|
@@ -15411,7 +15462,7 @@ var DEFAULT_HEAD_LINES = 50;
|
|
|
15411
15462
|
var DEFAULT_TAIL_LINES = 20;
|
|
15412
15463
|
var MAX_LINE_LENGTH = 500;
|
|
15413
15464
|
function compressToolOutput(toolName, output) {
|
|
15414
|
-
if (!output || output.length <
|
|
15465
|
+
if (!output || output.length < 200) return output;
|
|
15415
15466
|
const strategy = TOOL_COMPRESS_STRATEGIES[toolName];
|
|
15416
15467
|
if (strategy) return strategy(output);
|
|
15417
15468
|
return compressGeneric(output);
|
|
@@ -15575,7 +15626,7 @@ var PROTECTED_TOOLS = /* @__PURE__ */ new Set([
|
|
|
15575
15626
|
]);
|
|
15576
15627
|
var NEVER_DEDUP = /* @__PURE__ */ new Set(["read", "bash", "grep", "glob", "find", "search"]);
|
|
15577
15628
|
var ERROR_PURGE_TURN_THRESHOLD = 4;
|
|
15578
|
-
var
|
|
15629
|
+
var PROTECTED_HEAD_SINGLE = 2;
|
|
15579
15630
|
function simpleHash(s) {
|
|
15580
15631
|
const len = s.length;
|
|
15581
15632
|
const sampleSize = 500;
|
|
@@ -15598,9 +15649,9 @@ function singlePassCompress(messages, state, protectedTail) {
|
|
|
15598
15649
|
ccrStored: 0
|
|
15599
15650
|
};
|
|
15600
15651
|
const totalMessages = messages.length;
|
|
15601
|
-
if (totalMessages <=
|
|
15652
|
+
if (totalMessages <= PROTECTED_HEAD_SINGLE) return stats;
|
|
15602
15653
|
const seen = /* @__PURE__ */ new Map();
|
|
15603
|
-
for (let i =
|
|
15654
|
+
for (let i = PROTECTED_HEAD_SINGLE; i < totalMessages; i++) {
|
|
15604
15655
|
const msg = messages[i];
|
|
15605
15656
|
if (!msg?.parts?.length) continue;
|
|
15606
15657
|
if (msg.info.role === "user") continue;
|
|
@@ -15656,18 +15707,18 @@ function singlePassCompress(messages, state, protectedTail) {
|
|
|
15656
15707
|
seen.set(signature, { msgIdx: i, outputHash });
|
|
15657
15708
|
}
|
|
15658
15709
|
}
|
|
15659
|
-
if (output.length >=
|
|
15710
|
+
if (output.length >= 200) {
|
|
15660
15711
|
const result = compressToolOutput(toolName, output);
|
|
15661
|
-
if (result.length < output.length * 0.
|
|
15712
|
+
if (result.length < output.length * 0.85) {
|
|
15662
15713
|
const hash2 = ccrStore(state, output, result, toolName, callID);
|
|
15663
15714
|
toolState["output"] = ccrInjectMarker(result, hash2);
|
|
15664
15715
|
stats.toolOutputCompressed++;
|
|
15665
15716
|
continue;
|
|
15666
15717
|
}
|
|
15667
15718
|
}
|
|
15668
|
-
if (output.length >=
|
|
15719
|
+
if (output.length >= 200 && detectContentType(output) === "json") {
|
|
15669
15720
|
const crushed = crushJsonArray(output);
|
|
15670
|
-
if (crushed.length < output.length * 0.
|
|
15721
|
+
if (crushed.length < output.length * 0.85) {
|
|
15671
15722
|
const hash2 = ccrStore(state, output, crushed, toolName, callID);
|
|
15672
15723
|
toolState["output"] = ccrInjectMarker(crushed, hash2);
|
|
15673
15724
|
stats.jsonCrushed++;
|
|
@@ -15760,7 +15811,7 @@ function injectIntoLastAssistant(messages, text) {
|
|
|
15760
15811
|
|
|
15761
15812
|
// src/hooks/messages-transform.ts
|
|
15762
15813
|
var KEEP_RECENT = 8;
|
|
15763
|
-
var
|
|
15814
|
+
var PROTECTED_HEAD = 3;
|
|
15764
15815
|
var SYSTEM_INJECTION_PATTERNS = [
|
|
15765
15816
|
/^$/,
|
|
15766
15817
|
/^<!-- OMO_INTERNAL_INITIATOR -->$/,
|
|
@@ -15847,7 +15898,7 @@ function createMessagesTransformHandler(state, logger) {
|
|
|
15847
15898
|
return async (input, output) => {
|
|
15848
15899
|
const messages = output.messages;
|
|
15849
15900
|
if (messages.length <= KEEP_RECENT) return;
|
|
15850
|
-
if (messages.length <= KEEP_RECENT +
|
|
15901
|
+
if (messages.length <= KEEP_RECENT + PROTECTED_HEAD) return;
|
|
15851
15902
|
const protectedTailStart = messages.length - KEEP_RECENT;
|
|
15852
15903
|
const stats = {
|
|
15853
15904
|
reasoning_cleared: 0,
|
|
@@ -15857,7 +15908,7 @@ function createMessagesTransformHandler(state, logger) {
|
|
|
15857
15908
|
thinking_stripped: 0
|
|
15858
15909
|
};
|
|
15859
15910
|
const toRemove = [];
|
|
15860
|
-
for (let i =
|
|
15911
|
+
for (let i = PROTECTED_HEAD; i < protectedTailStart; i++) {
|
|
15861
15912
|
const msg = messages[i];
|
|
15862
15913
|
if (!msg?.parts?.length) continue;
|
|
15863
15914
|
if (msg.info.role === "user") continue;
|
|
@@ -15931,14 +15982,14 @@ function createMessagesTransformHandler(state, logger) {
|
|
|
15931
15982
|
compression: stats,
|
|
15932
15983
|
deepCompression: ds,
|
|
15933
15984
|
messageCount: messages.length,
|
|
15934
|
-
protectedHead:
|
|
15985
|
+
protectedHead: PROTECTED_HEAD,
|
|
15935
15986
|
protectedTail: KEEP_RECENT
|
|
15936
15987
|
});
|
|
15937
15988
|
} else if (Object.values(stats).some((v) => v > 0)) {
|
|
15938
15989
|
state.mergeNotify({
|
|
15939
15990
|
compression: stats,
|
|
15940
15991
|
messageCount: messages.length,
|
|
15941
|
-
protectedHead:
|
|
15992
|
+
protectedHead: PROTECTED_HEAD,
|
|
15942
15993
|
protectedTail: KEEP_RECENT
|
|
15943
15994
|
});
|
|
15944
15995
|
}
|