@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 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.3,
15240
- high: 0.5
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 = 5;
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 < 500) return output;
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 PROTECTED_HEAD = 2;
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 <= PROTECTED_HEAD) return stats;
15652
+ if (totalMessages <= PROTECTED_HEAD_SINGLE) return stats;
15602
15653
  const seen = /* @__PURE__ */ new Map();
15603
- for (let i = PROTECTED_HEAD; i < totalMessages; 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 >= 500) {
15710
+ if (output.length >= 200) {
15660
15711
  const result = compressToolOutput(toolName, output);
15661
- if (result.length < output.length * 0.7) {
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 >= 500 && detectContentType(output) === "json") {
15719
+ if (output.length >= 200 && detectContentType(output) === "json") {
15669
15720
  const crushed = crushJsonArray(output);
15670
- if (crushed.length < output.length * 0.7) {
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 PROTECTED_HEAD2 = 3;
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 + PROTECTED_HEAD2) return;
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 = PROTECTED_HEAD2; i < protectedTailStart; 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: PROTECTED_HEAD2,
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: PROTECTED_HEAD2,
15992
+ protectedHead: PROTECTED_HEAD,
15942
15993
  protectedTail: KEEP_RECENT
15943
15994
  });
15944
15995
  }