@bd7pil/opencode-deep-memory 0.4.2 → 0.4.3
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 +38 -30
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -390,6 +390,10 @@ var PluginState = class {
|
|
|
390
390
|
return this._toolSignatures.get(callID);
|
|
391
391
|
}
|
|
392
392
|
ccStore(hash2, entry) {
|
|
393
|
+
const now = Date.now();
|
|
394
|
+
for (const [k, v] of this._ccrCache) {
|
|
395
|
+
if (now - v.createdAt > 3e5) this._ccrCache.delete(k);
|
|
396
|
+
}
|
|
393
397
|
if (this._ccrCache.size > 200) {
|
|
394
398
|
const oldest = [...this._ccrCache.entries()].sort((a, b) => a[1].createdAt - b[1].createdAt).slice(0, 50);
|
|
395
399
|
for (const [k] of oldest) this._ccrCache.delete(k);
|
|
@@ -15366,11 +15370,17 @@ function deduplicateToolOutputs(messages, state) {
|
|
|
15366
15370
|
return deduped;
|
|
15367
15371
|
}
|
|
15368
15372
|
function simpleHash(s) {
|
|
15369
|
-
|
|
15370
|
-
|
|
15373
|
+
const len = s.length;
|
|
15374
|
+
const sampleSize = 500;
|
|
15375
|
+
let h = len;
|
|
15376
|
+
for (let i = 0; i < Math.min(len, sampleSize); i++) {
|
|
15377
|
+
h = h * 31 + s.charCodeAt(i) | 0;
|
|
15378
|
+
}
|
|
15379
|
+
const tailStart = Math.max(sampleSize, len - sampleSize);
|
|
15380
|
+
for (let i = tailStart; i < len; i++) {
|
|
15371
15381
|
h = h * 31 + s.charCodeAt(i) | 0;
|
|
15372
15382
|
}
|
|
15373
|
-
return h.toString(36)
|
|
15383
|
+
return `${len}:${h.toString(36)}`;
|
|
15374
15384
|
}
|
|
15375
15385
|
|
|
15376
15386
|
// src/compress/error-purge.ts
|
|
@@ -15562,7 +15572,8 @@ function pruneOldMessages(messages) {
|
|
|
15562
15572
|
if (p["type"] !== "text" || typeof p["text"] !== "string") continue;
|
|
15563
15573
|
const text = p["text"];
|
|
15564
15574
|
if (text.length < 500) continue;
|
|
15565
|
-
if (text === "[cleared]" || text === "[stripped]"
|
|
15575
|
+
if (text === "[cleared]" || text === "[stripped]") continue;
|
|
15576
|
+
if (text.includes("[compressed from")) continue;
|
|
15566
15577
|
const keyInfo = extractKeyInfo(text);
|
|
15567
15578
|
if (keyInfo.length < text.length * 0.6) {
|
|
15568
15579
|
p["text"] = keyInfo + "\n[compressed from " + text.length + " chars]";
|
|
@@ -15678,7 +15689,7 @@ function detectContentType(content) {
|
|
|
15678
15689
|
if (/Traceback \(most recent call last\)|at \S+\.\S+\(|Error: |Exception: |TypeError: |ReferenceError: /m.test(content)) return "error-trace";
|
|
15679
15690
|
if (/<[a-z][\s\S]*>/i.test(content) && /<(html|div|span|body|head|script|style)[\s>]/i.test(content)) return "html";
|
|
15680
15691
|
const lines = content.split("\n");
|
|
15681
|
-
const logLineCount = lines.filter((l) => /^\d{4}-\d{2}-\d{2}
|
|
15692
|
+
const logLineCount = lines.filter((l) => /^\s*(\d{4}-\d{2}-\d{2}|\[\d{4}|ERROR\b|WARN\b|INFO\b|DEBUG\b|FATAL\b|TRACE\b)/.test(l)).length;
|
|
15682
15693
|
if (lines.length > 5 && logLineCount / lines.length > 0.3) return "log";
|
|
15683
15694
|
const codePatterns = /\b(function |class |def |import |from .+ import|const |let |var |export |interface |type |struct |fn |func |pub |private |protected )\b/;
|
|
15684
15695
|
const codeLines = lines.filter((l) => codePatterns.test(l)).length;
|
|
@@ -15704,39 +15715,23 @@ function runCompressionPipeline(ctx) {
|
|
|
15704
15715
|
};
|
|
15705
15716
|
stats.toolDedup = deduplicateToolOutputs(messages, state);
|
|
15706
15717
|
stats.errorPurge = purgeOldErrors(messages);
|
|
15707
|
-
stats.toolOutputCompressed = compressOldToolOutputs(messages, state);
|
|
15708
15718
|
stats.jsonCrushed = crushJsonToolOutputs(messages, state);
|
|
15719
|
+
stats.toolOutputCompressed = compressOldToolOutputs(messages, state);
|
|
15709
15720
|
if (pressure.level === "medium" || pressure.level === "high") {
|
|
15710
15721
|
stats.messagePruned = pruneOldMessages(messages);
|
|
15711
15722
|
}
|
|
15712
15723
|
const messagesSinceNudge = state.messagesSinceLastNudge(messages.length);
|
|
15713
15724
|
if (shouldInjectNudge(pressure.level, messagesSinceNudge)) {
|
|
15714
|
-
|
|
15715
|
-
|
|
15716
|
-
|
|
15717
|
-
(p) => typeof p === "object" && p !== null && p.type === "text"
|
|
15718
|
-
);
|
|
15719
|
-
const lastTextPart = textParts[textParts.length - 1];
|
|
15720
|
-
if (lastTextPart && typeof lastTextPart.text === "string") {
|
|
15721
|
-
lastTextPart.text += buildNudgeText(pressure.level);
|
|
15722
|
-
stats.nudgeInjected = true;
|
|
15723
|
-
state.recordNudge(messages.length);
|
|
15724
|
-
}
|
|
15725
|
+
if (injectIntoLastAssistant(messages, buildNudgeText(pressure.level))) {
|
|
15726
|
+
stats.nudgeInjected = true;
|
|
15727
|
+
state.recordNudge(messages.length);
|
|
15725
15728
|
}
|
|
15726
15729
|
}
|
|
15727
15730
|
const memoryNudge = detectMemoryNudge(messages, state.messagesSinceLastNudge(messages.length));
|
|
15728
15731
|
if (memoryNudge.injected) {
|
|
15729
|
-
|
|
15730
|
-
|
|
15731
|
-
|
|
15732
|
-
(p) => typeof p === "object" && p !== null && p.type === "text"
|
|
15733
|
-
);
|
|
15734
|
-
const lastTextPart = textParts[textParts.length - 1];
|
|
15735
|
-
if (lastTextPart && typeof lastTextPart.text === "string") {
|
|
15736
|
-
lastTextPart.text += buildMemoryNudge(memoryNudge.type);
|
|
15737
|
-
state.recordNudge(messages.length);
|
|
15738
|
-
logger?.debug("compress: memory nudge", { type: memoryNudge.type });
|
|
15739
|
-
}
|
|
15732
|
+
if (injectIntoLastAssistant(messages, buildMemoryNudge(memoryNudge.type))) {
|
|
15733
|
+
state.recordNudge(messages.length);
|
|
15734
|
+
logger?.debug("compress: memory nudge", { type: memoryNudge.type });
|
|
15740
15735
|
}
|
|
15741
15736
|
}
|
|
15742
15737
|
const active = stats.toolDedup > 0 || stats.errorPurge > 0 || stats.toolOutputCompressed > 0 || stats.jsonCrushed > 0 || stats.messagePruned > 0 || stats.nudgeInjected;
|
|
@@ -15747,6 +15742,21 @@ function runCompressionPipeline(ctx) {
|
|
|
15747
15742
|
}
|
|
15748
15743
|
return { stats };
|
|
15749
15744
|
}
|
|
15745
|
+
function injectIntoLastAssistant(messages, text) {
|
|
15746
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
15747
|
+
const msg = messages[i];
|
|
15748
|
+
if (msg.info.role !== "assistant") continue;
|
|
15749
|
+
const textParts = msg.parts.filter(
|
|
15750
|
+
(p) => typeof p === "object" && p !== null && p.type === "text"
|
|
15751
|
+
);
|
|
15752
|
+
const lastTextPart = textParts[textParts.length - 1];
|
|
15753
|
+
if (lastTextPart && typeof lastTextPart.text === "string") {
|
|
15754
|
+
lastTextPart.text += text;
|
|
15755
|
+
return true;
|
|
15756
|
+
}
|
|
15757
|
+
}
|
|
15758
|
+
return false;
|
|
15759
|
+
}
|
|
15750
15760
|
function compressOldToolOutputs(messages, state) {
|
|
15751
15761
|
let compressed = 0;
|
|
15752
15762
|
const protectedTail = messages.length - 8;
|
|
@@ -15759,7 +15769,6 @@ function compressOldToolOutputs(messages, state) {
|
|
|
15759
15769
|
if (p.state?.status !== "completed") continue;
|
|
15760
15770
|
if (!p.state.output) continue;
|
|
15761
15771
|
if (p.state.output === "[superseded by duplicate call]") continue;
|
|
15762
|
-
if (p.state.output.startsWith("[compressed")) continue;
|
|
15763
15772
|
if (p.state.output.includes("[ccr:")) continue;
|
|
15764
15773
|
const toolName = p.tool || "unknown";
|
|
15765
15774
|
const output = p.state.output;
|
|
@@ -15784,7 +15793,6 @@ function crushJsonToolOutputs(messages, state) {
|
|
|
15784
15793
|
if (p.type !== "tool") continue;
|
|
15785
15794
|
if (p.state?.status !== "completed") continue;
|
|
15786
15795
|
if (!p.state.output) continue;
|
|
15787
|
-
if (p.state.output.startsWith("[compressed")) continue;
|
|
15788
15796
|
if (p.state.output.startsWith("[superseded")) continue;
|
|
15789
15797
|
if (p.state.output.includes("[ccr:")) continue;
|
|
15790
15798
|
if (detectContentType(p.state.output) !== "json") continue;
|