@bd7pil/opencode-deep-memory 0.8.1 → 0.8.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/README.md +8 -3
- package/dist/index.js +208 -74
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -61,7 +61,7 @@ OpenCode auto-installs on startup. Memory appears at `.deep-memory/` in your pro
|
|
|
61
61
|
|
|
62
62
|
## Context compression
|
|
63
63
|
|
|
64
|
-
|
|
64
|
+
Three layers, fully automatic, no LLM calls.
|
|
65
65
|
|
|
66
66
|
### Layer 1: Deterministic stripping (always active)
|
|
67
67
|
|
|
@@ -92,11 +92,16 @@ Thresholds are absolute, not percentage-based — they work consistently across
|
|
|
92
92
|
| Command outputs | Keep errors + tail | [Edgee][] |
|
|
93
93
|
| Search results | Keep top-20, group by file | [Edgee][] |
|
|
94
94
|
| JSON arrays | Head + dedup middle + tail | [Headroom][] |
|
|
95
|
+
| Subagent output | Headers + key lines + tail with [ccr:] preservation | [Claude Code][] |
|
|
96
|
+
| Skill output | Frontmatter + MUST rules + structure headers | [Claude Code][] |
|
|
97
|
+
| Nested JSON objects | Compress child arrays >30 items | This project |
|
|
95
98
|
| Old assistant text | Preserve structure, compress prose | [LLMLingua][] |
|
|
96
99
|
|
|
97
|
-
All compressed content is **reversible** via CCR (Compress-Cache-Retrieve) — originals cached with SHA-256 hash, retrievable via `deep_expand` tool.
|
|
100
|
+
All compressed content is **reversible** via CCR (Compress-Cache-Retrieve) — originals cached for 30 minutes with SHA-256 hash, retrievable via `deep_expand` tool.
|
|
98
101
|
|
|
99
|
-
**
|
|
102
|
+
**No compression** on protected tools: `question`, `edit`, `write`, `todowrite`, `memory_*`, `deep_expand`, `task`, `skill`. These tools' outputs contain verification data (LSP diagnostics, subagent decisions) essential for the agent to function correctly.
|
|
103
|
+
|
|
104
|
+
**Post-compression re-read**: after compression modifies content, recent modified files are listed in a `<dm-nudge>` so the agent can re-verify if needed — inspired by Claude Code's `onCompact` callback.
|
|
100
105
|
|
|
101
106
|
## Memory nudge
|
|
102
107
|
|
package/dist/index.js
CHANGED
|
@@ -264,6 +264,7 @@ var PluginState = class {
|
|
|
264
264
|
_lastMemoryNudgeMessageCount = /* @__PURE__ */ new Map();
|
|
265
265
|
_lastCCRCleanup = 0;
|
|
266
266
|
_modelContextWindow = 0;
|
|
267
|
+
_recentEdits = /* @__PURE__ */ new Set();
|
|
267
268
|
agentOf(sessionID) {
|
|
268
269
|
return this._agents.get(sessionID);
|
|
269
270
|
}
|
|
@@ -432,12 +433,15 @@ var PluginState = class {
|
|
|
432
433
|
const last = this._lastMemoryNudgeMessageCount.get(sessionID);
|
|
433
434
|
return last != null ? currentMessageCount - last : Number.POSITIVE_INFINITY;
|
|
434
435
|
}
|
|
435
|
-
setModelContextWindow(tokens) {
|
|
436
|
-
if (tokens > 0) this._modelContextWindow = tokens;
|
|
437
|
-
}
|
|
438
436
|
getModelContextWindow() {
|
|
439
437
|
return this._modelContextWindow;
|
|
440
438
|
}
|
|
439
|
+
trackEdit(filePath) {
|
|
440
|
+
if (filePath) this._recentEdits.add(filePath);
|
|
441
|
+
}
|
|
442
|
+
getRecentEdits() {
|
|
443
|
+
return Array.from(this._recentEdits);
|
|
444
|
+
}
|
|
441
445
|
};
|
|
442
446
|
function createPluginState() {
|
|
443
447
|
return new PluginState();
|
|
@@ -14874,7 +14878,7 @@ ${part.thinking || part.text || "[empty]"}
|
|
|
14874
14878
|
|
|
14875
14879
|
// src/compress/ccr.ts
|
|
14876
14880
|
import { createHash as createHash2 } from "crypto";
|
|
14877
|
-
var CCR_TTL_MS =
|
|
14881
|
+
var CCR_TTL_MS = 30 * 60 * 1e3;
|
|
14878
14882
|
function ccrStore(state, original, compressed, toolName, callID) {
|
|
14879
14883
|
const hash2 = sha256(original).slice(0, 24);
|
|
14880
14884
|
state.ccStore(hash2, {
|
|
@@ -15369,14 +15373,13 @@ function extractInputTokensFromMessages(messages) {
|
|
|
15369
15373
|
for (const part of msg.parts) {
|
|
15370
15374
|
if (typeof part !== "object" || part === null) continue;
|
|
15371
15375
|
const p = part;
|
|
15372
|
-
if (p["type"]
|
|
15373
|
-
|
|
15374
|
-
|
|
15375
|
-
|
|
15376
|
-
|
|
15377
|
-
|
|
15378
|
-
|
|
15379
|
-
}
|
|
15376
|
+
if (p["type"] !== "step-finish") continue;
|
|
15377
|
+
const tokens = p;
|
|
15378
|
+
const input = tokens.tokens?.input ?? 0;
|
|
15379
|
+
const cached2 = tokens.tokens?.cache?.read ?? 0;
|
|
15380
|
+
const total = input + cached2;
|
|
15381
|
+
if (total > best) best = total;
|
|
15382
|
+
if (best > 0) return best;
|
|
15380
15383
|
}
|
|
15381
15384
|
}
|
|
15382
15385
|
return best;
|
|
@@ -15469,6 +15472,28 @@ function createToolSignature(tool5, args) {
|
|
|
15469
15472
|
return `${tool5}::${sorted}`;
|
|
15470
15473
|
}
|
|
15471
15474
|
|
|
15475
|
+
// src/compress/detector.ts
|
|
15476
|
+
function detectContentType(content) {
|
|
15477
|
+
const trimmed = content.trimStart();
|
|
15478
|
+
if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
|
|
15479
|
+
try {
|
|
15480
|
+
JSON.parse(content);
|
|
15481
|
+
return "json";
|
|
15482
|
+
} catch {
|
|
15483
|
+
}
|
|
15484
|
+
}
|
|
15485
|
+
if (/^diff --git |^@@ -\d+,\d+ \+\d+,\d+ @@|^[+-]{3} \//m.test(content)) return "diff";
|
|
15486
|
+
if (/Traceback \(most recent call last\)|at \S+\.\S+\(|Error: |Exception: |TypeError: |ReferenceError: /m.test(content)) return "error-trace";
|
|
15487
|
+
if (/<[a-z][\s\S]*>/i.test(content) && /<(html|div|span|body|head|script|style)[\s>]/i.test(content)) return "html";
|
|
15488
|
+
const lines = content.split("\n");
|
|
15489
|
+
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;
|
|
15490
|
+
if (lines.length > 5 && logLineCount / lines.length > 0.3) return "log";
|
|
15491
|
+
const codePatterns = /\b(function |class |def |import |from .+ import|const |let |var |export |interface |type |struct |fn |func |pub |private |protected )\b/;
|
|
15492
|
+
const codeLines = lines.filter((l) => codePatterns.test(l)).length;
|
|
15493
|
+
if (lines.length > 10 && codeLines / lines.length > 0.15) return "code";
|
|
15494
|
+
return "text";
|
|
15495
|
+
}
|
|
15496
|
+
|
|
15472
15497
|
// src/compress/tool-compress.ts
|
|
15473
15498
|
var TOOL_COMPRESS_STRATEGIES = {
|
|
15474
15499
|
read: compressFileRead,
|
|
@@ -15482,7 +15507,12 @@ var TOOL_COMPRESS_STRATEGIES = {
|
|
|
15482
15507
|
grep_app_searchGitHub: compressSearchResults,
|
|
15483
15508
|
searxng_searxng_web_search: compressSearchResults,
|
|
15484
15509
|
websearch_web_search_exa: compressSearchResults,
|
|
15485
|
-
tavily_tavily_search: compressSearchResults
|
|
15510
|
+
tavily_tavily_search: compressSearchResults,
|
|
15511
|
+
background_output: compressAgentOutput,
|
|
15512
|
+
task: compressAgentOutput,
|
|
15513
|
+
skill: compressSkillOutput,
|
|
15514
|
+
session_read: compressAgentOutput,
|
|
15515
|
+
webfetch: compressAgentOutput
|
|
15486
15516
|
};
|
|
15487
15517
|
var DEFAULT_HEAD_LINES = 50;
|
|
15488
15518
|
var DEFAULT_TAIL_LINES = 20;
|
|
@@ -15571,6 +15601,136 @@ function truncateLine(line, maxLen) {
|
|
|
15571
15601
|
if (line.length <= maxLen) return line;
|
|
15572
15602
|
return line.slice(0, maxLen - 15) + "...[truncated]";
|
|
15573
15603
|
}
|
|
15604
|
+
function compressJsonOutput(output) {
|
|
15605
|
+
try {
|
|
15606
|
+
const parsed = JSON.parse(output);
|
|
15607
|
+
if (Array.isArray(parsed)) {
|
|
15608
|
+
return compressJsonArray(parsed);
|
|
15609
|
+
}
|
|
15610
|
+
if (typeof parsed === "object" && parsed !== null) {
|
|
15611
|
+
return compressJsonObject(parsed);
|
|
15612
|
+
}
|
|
15613
|
+
return output;
|
|
15614
|
+
} catch {
|
|
15615
|
+
return output;
|
|
15616
|
+
}
|
|
15617
|
+
}
|
|
15618
|
+
function compressJsonArray(arr) {
|
|
15619
|
+
const head = 30;
|
|
15620
|
+
const tail = 15;
|
|
15621
|
+
const maxItems = 50;
|
|
15622
|
+
if (arr.length <= maxItems) return JSON.stringify(arr, null, 2);
|
|
15623
|
+
const kept = [...arr.slice(0, head), { _truncated: true, total: arr.length }, ...arr.slice(-tail)];
|
|
15624
|
+
return JSON.stringify(kept, null, 2);
|
|
15625
|
+
}
|
|
15626
|
+
function compressJsonObject(obj) {
|
|
15627
|
+
const MAX_CHILD_ITEMS = 30;
|
|
15628
|
+
let modified = false;
|
|
15629
|
+
const result = {};
|
|
15630
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
15631
|
+
if (Array.isArray(value) && value.length > MAX_CHILD_ITEMS) {
|
|
15632
|
+
result[key] = {
|
|
15633
|
+
_truncated: true,
|
|
15634
|
+
total: value.length,
|
|
15635
|
+
items: [...value.slice(0, 10), toStringPlaceholder(value.slice(10, 20)), ...value.slice(-10)]
|
|
15636
|
+
};
|
|
15637
|
+
modified = true;
|
|
15638
|
+
} else {
|
|
15639
|
+
result[key] = value;
|
|
15640
|
+
}
|
|
15641
|
+
}
|
|
15642
|
+
if (modified) {
|
|
15643
|
+
return JSON.stringify(result, null, 2);
|
|
15644
|
+
}
|
|
15645
|
+
return JSON.stringify(obj, null, 2);
|
|
15646
|
+
}
|
|
15647
|
+
function toStringPlaceholder(items) {
|
|
15648
|
+
return { _skipped: items.length };
|
|
15649
|
+
}
|
|
15650
|
+
function compressAgentOutput(output) {
|
|
15651
|
+
if (detectContentType(output) === "json") {
|
|
15652
|
+
return compressJsonOutput(output);
|
|
15653
|
+
}
|
|
15654
|
+
const lines = output.split("\n");
|
|
15655
|
+
if (lines.length <= 40 && output.length <= 3e3) return output;
|
|
15656
|
+
const MAX_SECTION_LINES = 5;
|
|
15657
|
+
const result = [];
|
|
15658
|
+
for (let i = 0; i < lines.length; i++) {
|
|
15659
|
+
const line = lines[i];
|
|
15660
|
+
if (line.includes("[ccr:") || line.includes("[superseded")) {
|
|
15661
|
+
result.push(line);
|
|
15662
|
+
continue;
|
|
15663
|
+
}
|
|
15664
|
+
const isHeader = /^#{1,4}\s/.test(line) || /^---/.test(line) || /^\*\*$/.test(line);
|
|
15665
|
+
const hasCode = line.includes("```");
|
|
15666
|
+
const hasKey = /\b(error|fail|success|completed|result|summary|warning)\b/i.test(line);
|
|
15667
|
+
if (isHeader || hasCode || hasKey) {
|
|
15668
|
+
result.push(truncateLine(line, 300));
|
|
15669
|
+
continue;
|
|
15670
|
+
}
|
|
15671
|
+
if (i < 5 || i >= lines.length - 10) {
|
|
15672
|
+
result.push(truncateLine(line, 300));
|
|
15673
|
+
continue;
|
|
15674
|
+
}
|
|
15675
|
+
const inSection = result.length > 0 && result[result.length - 1] !== "";
|
|
15676
|
+
if (!inSection) {
|
|
15677
|
+
if (line.trim()) {
|
|
15678
|
+
result.push(line);
|
|
15679
|
+
}
|
|
15680
|
+
} else {
|
|
15681
|
+
const recentLines = result.slice(-MAX_SECTION_LINES).filter((l) => l.trim() && l !== "...");
|
|
15682
|
+
if (recentLines.length >= MAX_SECTION_LINES) {
|
|
15683
|
+
result.push("...[truncated]");
|
|
15684
|
+
while (i < lines.length && !/^#{1,4}\s/.test(lines[i]) && !lines[i].includes("```") && !/\b(error|fail|summary)\b/i.test(lines[i])) {
|
|
15685
|
+
i++;
|
|
15686
|
+
}
|
|
15687
|
+
i--;
|
|
15688
|
+
} else {
|
|
15689
|
+
result.push(truncateLine(line, 300));
|
|
15690
|
+
}
|
|
15691
|
+
}
|
|
15692
|
+
}
|
|
15693
|
+
return result.join("\n");
|
|
15694
|
+
}
|
|
15695
|
+
function compressSkillOutput(output) {
|
|
15696
|
+
const lines = output.split("\n");
|
|
15697
|
+
if (lines.length <= 60 && output.length <= 4e3) return output;
|
|
15698
|
+
const result = [];
|
|
15699
|
+
const FRONTMATTER_END = lines.findIndex((l, i) => i > 0 && l.trim() === "---");
|
|
15700
|
+
for (let i = 0; i < lines.length; i++) {
|
|
15701
|
+
if (i <= FRONTMATTER_END || i < 10) {
|
|
15702
|
+
result.push(lines[i]);
|
|
15703
|
+
continue;
|
|
15704
|
+
}
|
|
15705
|
+
if (i >= lines.length - 10) {
|
|
15706
|
+
result.push(lines[i]);
|
|
15707
|
+
continue;
|
|
15708
|
+
}
|
|
15709
|
+
const line = lines[i];
|
|
15710
|
+
if (/^#{1,4}\s/.test(line) || /^```/.test(line) || /^---/.test(line)) {
|
|
15711
|
+
result.push(line);
|
|
15712
|
+
continue;
|
|
15713
|
+
}
|
|
15714
|
+
if (/\b(must|must not|required|forbidden|never|always)\b/i.test(line)) {
|
|
15715
|
+
result.push(line);
|
|
15716
|
+
continue;
|
|
15717
|
+
}
|
|
15718
|
+
const recentNonEmpty = result.slice(-8).filter((l) => l.trim());
|
|
15719
|
+
if (recentNonEmpty.length >= 8 && !result[result.length - 1].startsWith("...")) {
|
|
15720
|
+
result.push("...[truncated]");
|
|
15721
|
+
while (i < lines.length && !/^#{1,4}\s/.test(lines[i]) && !/^```/.test(lines[i])) {
|
|
15722
|
+
i++;
|
|
15723
|
+
}
|
|
15724
|
+
i--;
|
|
15725
|
+
} else {
|
|
15726
|
+
result.push(line);
|
|
15727
|
+
}
|
|
15728
|
+
}
|
|
15729
|
+
if (result.length < lines.length * 0.7) {
|
|
15730
|
+
return result.join("\n");
|
|
15731
|
+
}
|
|
15732
|
+
return output;
|
|
15733
|
+
}
|
|
15574
15734
|
|
|
15575
15735
|
// src/compress/json-crush.ts
|
|
15576
15736
|
import { createHash as createHash3 } from "crypto";
|
|
@@ -15616,28 +15776,6 @@ function sha2562(data) {
|
|
|
15616
15776
|
return createHash3("sha256").update(data).digest("hex");
|
|
15617
15777
|
}
|
|
15618
15778
|
|
|
15619
|
-
// src/compress/detector.ts
|
|
15620
|
-
function detectContentType(content) {
|
|
15621
|
-
const trimmed = content.trimStart();
|
|
15622
|
-
if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
|
|
15623
|
-
try {
|
|
15624
|
-
JSON.parse(content);
|
|
15625
|
-
return "json";
|
|
15626
|
-
} catch {
|
|
15627
|
-
}
|
|
15628
|
-
}
|
|
15629
|
-
if (/^diff --git |^@@ -\d+,\d+ \+\d+,\d+ @@|^[+-]{3} \//m.test(content)) return "diff";
|
|
15630
|
-
if (/Traceback \(most recent call last\)|at \S+\.\S+\(|Error: |Exception: |TypeError: |ReferenceError: /m.test(content)) return "error-trace";
|
|
15631
|
-
if (/<[a-z][\s\S]*>/i.test(content) && /<(html|div|span|body|head|script|style)[\s>]/i.test(content)) return "html";
|
|
15632
|
-
const lines = content.split("\n");
|
|
15633
|
-
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;
|
|
15634
|
-
if (lines.length > 5 && logLineCount / lines.length > 0.3) return "log";
|
|
15635
|
-
const codePatterns = /\b(function |class |def |import |from .+ import|const |let |var |export |interface |type |struct |fn |func |pub |private |protected )\b/;
|
|
15636
|
-
const codeLines = lines.filter((l) => codePatterns.test(l)).length;
|
|
15637
|
-
if (lines.length > 10 && codeLines / lines.length > 0.15) return "code";
|
|
15638
|
-
return "text";
|
|
15639
|
-
}
|
|
15640
|
-
|
|
15641
15779
|
// src/compress/single-pass.ts
|
|
15642
15780
|
var PROTECTED_TOOLS = /* @__PURE__ */ new Set([
|
|
15643
15781
|
"question",
|
|
@@ -15648,7 +15786,9 @@ var PROTECTED_TOOLS = /* @__PURE__ */ new Set([
|
|
|
15648
15786
|
"memory_search",
|
|
15649
15787
|
"memory_forget",
|
|
15650
15788
|
"memory_expand",
|
|
15651
|
-
"deep_expand"
|
|
15789
|
+
"deep_expand",
|
|
15790
|
+
"task",
|
|
15791
|
+
"skill"
|
|
15652
15792
|
]);
|
|
15653
15793
|
var NEVER_DEDUP = /* @__PURE__ */ new Set(["read", "bash", "grep", "glob", "find", "search"]);
|
|
15654
15794
|
var ERROR_PURGE_TURN_THRESHOLD = 4;
|
|
@@ -15711,7 +15851,7 @@ function singlePassCompress(messages, state, protectedTail) {
|
|
|
15711
15851
|
const toolName = p["tool"];
|
|
15712
15852
|
const callID = p["callID"];
|
|
15713
15853
|
const toolState = p["state"];
|
|
15714
|
-
if (toolState?.["status"] === "error") {
|
|
15854
|
+
if (toolState?.["status"] === "error" && !PROTECTED_TOOLS.has(toolName ?? "")) {
|
|
15715
15855
|
const age = totalMessages - i;
|
|
15716
15856
|
if (age >= ERROR_PURGE_TURN_THRESHOLD) {
|
|
15717
15857
|
if (typeof toolState["input"] === "object" && toolState["input"] !== null) {
|
|
@@ -15755,7 +15895,7 @@ function singlePassCompress(messages, state, protectedTail) {
|
|
|
15755
15895
|
seen.set(signature, { msgIdx: i, outputHash });
|
|
15756
15896
|
}
|
|
15757
15897
|
}
|
|
15758
|
-
if (output.length >= 200) {
|
|
15898
|
+
if (output.length >= 200 && !PROTECTED_TOOLS.has(toolName)) {
|
|
15759
15899
|
const result = compressToolOutput(toolName, output);
|
|
15760
15900
|
if (result.length < output.length * 0.85) {
|
|
15761
15901
|
const hash2 = ccrStore(state, output, result, toolName, callID);
|
|
@@ -15764,7 +15904,7 @@ function singlePassCompress(messages, state, protectedTail) {
|
|
|
15764
15904
|
continue;
|
|
15765
15905
|
}
|
|
15766
15906
|
}
|
|
15767
|
-
if (output.length >= 200 && detectContentType(output) === "json") {
|
|
15907
|
+
if (output.length >= 200 && detectContentType(output) === "json" && !PROTECTED_TOOLS.has(toolName)) {
|
|
15768
15908
|
const crushed = crushJsonArray(output);
|
|
15769
15909
|
if (crushed.length < output.length * 0.85) {
|
|
15770
15910
|
const hash2 = ccrStore(state, output, crushed, toolName, callID);
|
|
@@ -16051,6 +16191,23 @@ function createMessagesTransformHandler(state, logger) {
|
|
|
16051
16191
|
protectedHead: PROTECTED_HEAD,
|
|
16052
16192
|
protectedTail: KEEP_RECENT
|
|
16053
16193
|
});
|
|
16194
|
+
const recentEdits = state.getRecentEdits();
|
|
16195
|
+
if (recentEdits.length > 0) {
|
|
16196
|
+
const fileList = recentEdits.slice(0, 5).join(", ");
|
|
16197
|
+
const nudge = '\n\n<dm-nudge level="medium">Context was compressed. Recent files may have shifted: ' + fileList + ". Use `read` to re-verify if needed.</dm-nudge>";
|
|
16198
|
+
for (let k = output.messages.length - 1; k >= 0; k--) {
|
|
16199
|
+
const msg = output.messages[k];
|
|
16200
|
+
if (msg.info.role !== "assistant") continue;
|
|
16201
|
+
for (const part of msg.parts) {
|
|
16202
|
+
const p = part;
|
|
16203
|
+
if (p["type"] === "text" && typeof p["text"] === "string") {
|
|
16204
|
+
p.text += nudge;
|
|
16205
|
+
break;
|
|
16206
|
+
}
|
|
16207
|
+
}
|
|
16208
|
+
break;
|
|
16209
|
+
}
|
|
16210
|
+
}
|
|
16054
16211
|
} else if (Object.values(stats).some((v) => v > 0)) {
|
|
16055
16212
|
state.mergeNotify({
|
|
16056
16213
|
compression: stats,
|
|
@@ -16182,29 +16339,6 @@ function createNotifyHandler(client, logger) {
|
|
|
16182
16339
|
};
|
|
16183
16340
|
}
|
|
16184
16341
|
|
|
16185
|
-
// src/shared/model-limits.ts
|
|
16186
|
-
var KNOWN_MODEL_LIMITS = {
|
|
16187
|
-
"deepseek-v4-pro": 1e6,
|
|
16188
|
-
"deepseek-v4": 1e6,
|
|
16189
|
-
"deepseek-v3": 64e3,
|
|
16190
|
-
"deepseek-r1": 64e3,
|
|
16191
|
-
"claude-opus-4": 2e5,
|
|
16192
|
-
"claude-sonnet-4": 2e5,
|
|
16193
|
-
"gpt-4o": 128e3,
|
|
16194
|
-
"o1": 2e5,
|
|
16195
|
-
"o3-mini": 2e5,
|
|
16196
|
-
"gemini-2.5-pro": 1e6,
|
|
16197
|
-
"gemini-2.5-flash": 1e6,
|
|
16198
|
-
"qwen-max": 131072
|
|
16199
|
-
};
|
|
16200
|
-
function lookupModelLimit(modelID) {
|
|
16201
|
-
if (KNOWN_MODEL_LIMITS[modelID]) return KNOWN_MODEL_LIMITS[modelID];
|
|
16202
|
-
for (const [key, limit] of Object.entries(KNOWN_MODEL_LIMITS)) {
|
|
16203
|
-
if (modelID.includes(key)) return limit;
|
|
16204
|
-
}
|
|
16205
|
-
return void 0;
|
|
16206
|
-
}
|
|
16207
|
-
|
|
16208
16342
|
// src/extract/enrich.ts
|
|
16209
16343
|
import { stat } from "fs/promises";
|
|
16210
16344
|
|
|
@@ -16536,14 +16670,10 @@ var deepMemoryPlugin = async (input) => {
|
|
|
16536
16670
|
const defaultModel = configResult.data?.model;
|
|
16537
16671
|
if (typeof defaultModel === "string" && defaultModel.includes("/")) {
|
|
16538
16672
|
const slashIdx = defaultModel.indexOf("/");
|
|
16539
|
-
|
|
16540
|
-
|
|
16541
|
-
|
|
16542
|
-
|
|
16543
|
-
if (limit) {
|
|
16544
|
-
state.setModelContextWindow(limit);
|
|
16545
|
-
logger.debug("resolved model context window", { modelID, limit });
|
|
16546
|
-
}
|
|
16673
|
+
state.recordFallbackModel({
|
|
16674
|
+
providerID: defaultModel.slice(0, slashIdx),
|
|
16675
|
+
modelID: defaultModel.slice(slashIdx + 1)
|
|
16676
|
+
});
|
|
16547
16677
|
}
|
|
16548
16678
|
}).catch((err) => {
|
|
16549
16679
|
logger.debug("config.get failed, dream/distill will omit model", {
|
|
@@ -16704,12 +16834,16 @@ var deepMemoryPlugin = async (input) => {
|
|
|
16704
16834
|
},
|
|
16705
16835
|
tool: { ...memoryTools, deep_expand: createDeepExpandTool(state) },
|
|
16706
16836
|
"tool.execute.after": async (input2, output) => {
|
|
16707
|
-
if (input2.tool !== "read") return;
|
|
16708
16837
|
const filePath = input2.args?.path ?? input2.args?.filePath;
|
|
16709
16838
|
if (!filePath) return;
|
|
16710
|
-
|
|
16711
|
-
|
|
16712
|
-
|
|
16839
|
+
if (input2.tool === "read") {
|
|
16840
|
+
const lang = getLanguage(filePath);
|
|
16841
|
+
if (!lang) return;
|
|
16842
|
+
tracker.recordRead(filePath, output.output || "");
|
|
16843
|
+
}
|
|
16844
|
+
if (input2.tool === "edit" || input2.tool === "write") {
|
|
16845
|
+
state.trackEdit(filePath);
|
|
16846
|
+
}
|
|
16713
16847
|
},
|
|
16714
16848
|
"experimental.session.compacting": createCompactingHandler({
|
|
16715
16849
|
client: input.client,
|