@bd7pil/opencode-deep-memory 0.4.4 → 0.5.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 +30 -70
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -261,6 +261,7 @@ var PluginState = class {
|
|
|
261
261
|
_ccrCache = /* @__PURE__ */ new Map();
|
|
262
262
|
_lastInputTokens = 0;
|
|
263
263
|
_lastNudgeMessageCount = 0;
|
|
264
|
+
_modelContextWindow = 0;
|
|
264
265
|
agentOf(sessionID) {
|
|
265
266
|
return this._agents.get(sessionID);
|
|
266
267
|
}
|
|
@@ -415,6 +416,12 @@ var PluginState = class {
|
|
|
415
416
|
messagesSinceLastNudge(currentMessageCount) {
|
|
416
417
|
return currentMessageCount - this._lastNudgeMessageCount;
|
|
417
418
|
}
|
|
419
|
+
setModelContextWindow(tokens) {
|
|
420
|
+
if (tokens > 0) this._modelContextWindow = tokens;
|
|
421
|
+
}
|
|
422
|
+
getModelContextWindow() {
|
|
423
|
+
return this._modelContextWindow;
|
|
424
|
+
}
|
|
418
425
|
};
|
|
419
426
|
function createPluginState() {
|
|
420
427
|
return new PluginState();
|
|
@@ -15228,12 +15235,16 @@ var THRESHOLDS = {
|
|
|
15228
15235
|
var calibratedMaxContext = 0;
|
|
15229
15236
|
function calibrateFromCompaction(lastInputTokens) {
|
|
15230
15237
|
if (lastInputTokens <= 0) return;
|
|
15231
|
-
|
|
15232
|
-
calibratedMaxContext = derived;
|
|
15238
|
+
calibratedMaxContext = Math.round(lastInputTokens / OPENCODE_COMPACTION_RATIO);
|
|
15233
15239
|
}
|
|
15234
15240
|
function getCalibratedMaxContext() {
|
|
15235
15241
|
return calibratedMaxContext;
|
|
15236
15242
|
}
|
|
15243
|
+
function maxContextFrom(modelContextWindow) {
|
|
15244
|
+
if (modelContextWindow > 0) return modelContextWindow;
|
|
15245
|
+
if (calibratedMaxContext > 0) return calibratedMaxContext;
|
|
15246
|
+
return FALLBACK_MAX_CONTEXT;
|
|
15247
|
+
}
|
|
15237
15248
|
function estimateTokens2(text) {
|
|
15238
15249
|
let cjk = 0;
|
|
15239
15250
|
let other = 0;
|
|
@@ -15287,16 +15298,16 @@ function extractInputTokensFromMessages(messages) {
|
|
|
15287
15298
|
}
|
|
15288
15299
|
return 0;
|
|
15289
15300
|
}
|
|
15290
|
-
function detectPressure(messages) {
|
|
15291
|
-
const
|
|
15301
|
+
function detectPressure(messages, modelContextWindow) {
|
|
15302
|
+
const ctx = maxContextFrom(modelContextWindow || 0);
|
|
15292
15303
|
const inputTokens = extractInputTokensFromMessages(messages);
|
|
15293
15304
|
const estimated = inputTokens > 0 ? inputTokens : extractTokensFromMessages(messages);
|
|
15294
|
-
const ratio = Math.min(estimated /
|
|
15305
|
+
const ratio = Math.min(estimated / ctx, 1);
|
|
15295
15306
|
let level;
|
|
15296
15307
|
if (ratio >= THRESHOLDS.high) level = "high";
|
|
15297
15308
|
else if (ratio >= THRESHOLDS.medium) level = "medium";
|
|
15298
15309
|
else level = "low";
|
|
15299
|
-
return { level, ratio, estimatedTokens: estimated, maxContext };
|
|
15310
|
+
return { level, ratio, estimatedTokens: estimated, maxContext: ctx };
|
|
15300
15311
|
}
|
|
15301
15312
|
|
|
15302
15313
|
// src/compress/dedup.ts
|
|
@@ -15404,7 +15415,7 @@ function purgeOldErrors(messages) {
|
|
|
15404
15415
|
const input = toolState["input"];
|
|
15405
15416
|
for (const key of Object.keys(input)) {
|
|
15406
15417
|
if (key === "command" || key === "query" || key === "path" || key === "filePath") continue;
|
|
15407
|
-
input[key]
|
|
15418
|
+
delete input[key];
|
|
15408
15419
|
}
|
|
15409
15420
|
}
|
|
15410
15421
|
purged++;
|
|
@@ -15560,55 +15571,6 @@ function sha2562(data) {
|
|
|
15560
15571
|
return createHash3("sha256").update(data).digest("hex");
|
|
15561
15572
|
}
|
|
15562
15573
|
|
|
15563
|
-
// src/compress/message-prune.ts
|
|
15564
|
-
var PRUNE_THRESHOLD = 8;
|
|
15565
|
-
function pruneOldMessages(messages) {
|
|
15566
|
-
let pruned = 0;
|
|
15567
|
-
const protectedTail = messages.length - PRUNE_THRESHOLD;
|
|
15568
|
-
for (let i = 3; i < protectedTail; i++) {
|
|
15569
|
-
const msg = messages[i];
|
|
15570
|
-
if (msg.info.role !== "assistant") continue;
|
|
15571
|
-
for (const part of msg.parts) {
|
|
15572
|
-
if (typeof part !== "object" || part === null) continue;
|
|
15573
|
-
const p = part;
|
|
15574
|
-
if (p["type"] !== "text" || typeof p["text"] !== "string") continue;
|
|
15575
|
-
const text = p["text"];
|
|
15576
|
-
if (text.length < 500) continue;
|
|
15577
|
-
if (text === "[cleared]" || text === "[stripped]") continue;
|
|
15578
|
-
if (text.includes("[compressed from")) continue;
|
|
15579
|
-
const keyInfo = extractKeyInfo(text);
|
|
15580
|
-
if (keyInfo.length < text.length * 0.6) {
|
|
15581
|
-
p["text"] = keyInfo + "\n[compressed from " + text.length + " chars]";
|
|
15582
|
-
pruned++;
|
|
15583
|
-
}
|
|
15584
|
-
}
|
|
15585
|
-
}
|
|
15586
|
-
return pruned;
|
|
15587
|
-
}
|
|
15588
|
-
function extractKeyInfo(text) {
|
|
15589
|
-
const lines = text.split("\n");
|
|
15590
|
-
const keyLines = [];
|
|
15591
|
-
let inCodeBlock = false;
|
|
15592
|
-
for (const line of lines) {
|
|
15593
|
-
if (line.trim().startsWith("```")) {
|
|
15594
|
-
inCodeBlock = !inCodeBlock;
|
|
15595
|
-
if (inCodeBlock) keyLines.push(line);
|
|
15596
|
-
continue;
|
|
15597
|
-
}
|
|
15598
|
-
if (inCodeBlock) {
|
|
15599
|
-
if (keyLines.length < 30 && line.trim()) keyLines.push(line);
|
|
15600
|
-
continue;
|
|
15601
|
-
}
|
|
15602
|
-
if (/^#{1,3}\s/.test(line) || /error|fail|warning|important|critical|decision|constraint/i.test(line) || /^\s*[-*]\s/.test(line) || /^\s*\d+\.\s/.test(line)) {
|
|
15603
|
-
keyLines.push(line);
|
|
15604
|
-
}
|
|
15605
|
-
}
|
|
15606
|
-
if (keyLines.length < 3) {
|
|
15607
|
-
return lines.slice(0, 5).join("\n");
|
|
15608
|
-
}
|
|
15609
|
-
return keyLines.join("\n");
|
|
15610
|
-
}
|
|
15611
|
-
|
|
15612
15574
|
// src/compress/nudge.ts
|
|
15613
15575
|
var NUDGE_COOLDOWN = 5;
|
|
15614
15576
|
function shouldInjectNudge(level, messagesSinceLastNudge) {
|
|
@@ -15702,14 +15664,13 @@ function detectContentType(content) {
|
|
|
15702
15664
|
// src/compress/index.ts
|
|
15703
15665
|
function runCompressionPipeline(ctx) {
|
|
15704
15666
|
const { messages, state, logger } = ctx;
|
|
15705
|
-
const pressure = detectPressure(messages);
|
|
15667
|
+
const pressure = detectPressure(messages, state.getModelContextWindow());
|
|
15706
15668
|
state.recordInputTokens(pressure.estimatedTokens);
|
|
15707
15669
|
const stats = {
|
|
15708
15670
|
toolDedup: 0,
|
|
15709
15671
|
errorPurge: 0,
|
|
15710
15672
|
toolOutputCompressed: 0,
|
|
15711
15673
|
jsonCrushed: 0,
|
|
15712
|
-
messagePruned: 0,
|
|
15713
15674
|
ccrStored: 0,
|
|
15714
15675
|
nudgeInjected: false,
|
|
15715
15676
|
pressureLevel: pressure.level,
|
|
@@ -15719,9 +15680,6 @@ function runCompressionPipeline(ctx) {
|
|
|
15719
15680
|
stats.errorPurge = purgeOldErrors(messages);
|
|
15720
15681
|
stats.jsonCrushed = crushJsonToolOutputs(messages, state);
|
|
15721
15682
|
stats.toolOutputCompressed = compressOldToolOutputs(messages, state);
|
|
15722
|
-
if (pressure.level === "medium" || pressure.level === "high") {
|
|
15723
|
-
stats.messagePruned = pruneOldMessages(messages);
|
|
15724
|
-
}
|
|
15725
15683
|
const messagesSinceNudge = state.messagesSinceLastNudge(messages.length);
|
|
15726
15684
|
if (shouldInjectNudge(pressure.level, messagesSinceNudge)) {
|
|
15727
15685
|
if (injectIntoLastAssistant(messages, buildNudgeText(pressure.level))) {
|
|
@@ -15736,7 +15694,7 @@ function runCompressionPipeline(ctx) {
|
|
|
15736
15694
|
logger?.debug("compress: memory nudge", { type: memoryNudge.type });
|
|
15737
15695
|
}
|
|
15738
15696
|
}
|
|
15739
|
-
const active = stats.toolDedup > 0 || stats.errorPurge > 0 || stats.toolOutputCompressed > 0 || stats.jsonCrushed > 0 || stats.
|
|
15697
|
+
const active = stats.toolDedup > 0 || stats.errorPurge > 0 || stats.toolOutputCompressed > 0 || stats.jsonCrushed > 0 || stats.nudgeInjected;
|
|
15740
15698
|
if (active) {
|
|
15741
15699
|
logger?.debug("compress: pipeline result", { ...stats });
|
|
15742
15700
|
} else {
|
|
@@ -15908,11 +15866,12 @@ function createMessagesTransformHandler(state, logger) {
|
|
|
15908
15866
|
tool_errors_truncated: 0,
|
|
15909
15867
|
thinking_stripped: 0
|
|
15910
15868
|
};
|
|
15869
|
+
const toRemove = [];
|
|
15911
15870
|
for (let i = PROTECTED_HEAD2; i < protectedTailStart; i++) {
|
|
15912
15871
|
const msg = messages[i];
|
|
15913
15872
|
if (!msg?.parts?.length) continue;
|
|
15914
15873
|
if (msg.info.role === "user") continue;
|
|
15915
|
-
for (let j =
|
|
15874
|
+
for (let j = msg.parts.length - 1; j >= 0; j--) {
|
|
15916
15875
|
const part = msg.parts[j];
|
|
15917
15876
|
if (typeof part !== "object" || part === null) continue;
|
|
15918
15877
|
const p = part;
|
|
@@ -15928,10 +15887,9 @@ function createMessagesTransformHandler(state, logger) {
|
|
|
15928
15887
|
stats.metadata_stripped++;
|
|
15929
15888
|
}
|
|
15930
15889
|
}
|
|
15931
|
-
|
|
15932
|
-
|
|
15933
|
-
|
|
15934
|
-
}
|
|
15890
|
+
msg.parts.splice(j, 1);
|
|
15891
|
+
stats.reasoning_cleared++;
|
|
15892
|
+
continue;
|
|
15935
15893
|
}
|
|
15936
15894
|
if (partType === "tool") {
|
|
15937
15895
|
const meta = p["metadata"];
|
|
@@ -15959,11 +15917,13 @@ function createMessagesTransformHandler(state, logger) {
|
|
|
15959
15917
|
}
|
|
15960
15918
|
}
|
|
15961
15919
|
if (isSystemInjected(msg)) {
|
|
15962
|
-
|
|
15963
|
-
msg.parts.push({ type: "text", text: "[stripped]" });
|
|
15920
|
+
toRemove.push(i);
|
|
15964
15921
|
stats.system_neutralized++;
|
|
15965
15922
|
}
|
|
15966
15923
|
}
|
|
15924
|
+
for (let r = toRemove.length - 1; r >= 0; r--) {
|
|
15925
|
+
messages.splice(toRemove[r], 1);
|
|
15926
|
+
}
|
|
15967
15927
|
repairOrphanedToolCalls(messages);
|
|
15968
15928
|
if (Object.values(stats).some((v) => v > 0)) {
|
|
15969
15929
|
logger?.debug("messages.transform: stripped", stats);
|
|
@@ -15974,7 +15934,7 @@ function createMessagesTransformHandler(state, logger) {
|
|
|
15974
15934
|
logger
|
|
15975
15935
|
});
|
|
15976
15936
|
const ds = pipelineResult.stats;
|
|
15977
|
-
if (ds.toolDedup > 0 || ds.errorPurge > 0 || ds.toolOutputCompressed > 0 || ds.jsonCrushed > 0 || ds.
|
|
15937
|
+
if (ds.toolDedup > 0 || ds.errorPurge > 0 || ds.toolOutputCompressed > 0 || ds.jsonCrushed > 0 || ds.nudgeInjected) {
|
|
15978
15938
|
logger?.debug("messages.transform: deep compression", { ...ds });
|
|
15979
15939
|
state.mergeNotify({
|
|
15980
15940
|
compression: stats,
|