@kenkaiiii/ggcoder 5.79.1 → 5.79.2
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/core/agent-session.d.ts +7 -0
- package/dist/core/agent-session.js +56 -37
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/cache-diagnostics.d.ts +1 -1
- package/dist/core/cache-diagnostics.js +2 -1
- package/dist/core/cache-diagnostics.js.map +1 -1
- package/dist/core/compaction/tool-result-pruner.d.ts +10 -0
- package/dist/core/compaction/tool-result-pruner.js +12 -0
- package/dist/core/compaction/tool-result-pruner.js.map +1 -1
- package/dist/core/goals-store.js +1 -0
- package/dist/core/goals-store.js.map +1 -1
- package/dist/core/subagent-manager.js +8 -1
- package/dist/core/subagent-manager.js.map +1 -1
- package/dist/modes/subagent-worker-mode.d.ts +2 -0
- package/dist/modes/subagent-worker-mode.js +10 -0
- package/dist/modes/subagent-worker-mode.js.map +1 -1
- package/dist/ui/hooks/useContextCompaction.js +38 -31
- package/dist/ui/hooks/useContextCompaction.js.map +1 -1
- package/package.json +4 -4
|
@@ -776,6 +776,13 @@ export declare class AgentSession {
|
|
|
776
776
|
ok: false;
|
|
777
777
|
error: string;
|
|
778
778
|
}>;
|
|
779
|
+
/**
|
|
780
|
+
* Name a root change in the prompt only while there is no conversation yet.
|
|
781
|
+
* Mid-conversation the env-delta note tells the model instead: the roots sit
|
|
782
|
+
* in the Environment section, and rewriting it would invalidate every cached
|
|
783
|
+
* message after it (a goal attaching a folder re-sent ~75k tokens).
|
|
784
|
+
*/
|
|
785
|
+
private refreshPromptForRoots;
|
|
779
786
|
/**
|
|
780
787
|
* Names to advertise as available-on-demand. A tool the model already
|
|
781
788
|
* promoted lives in `this.tools` and carries its own schema, so it drops out
|
|
@@ -45,7 +45,7 @@ import { decidePlanStepCompaction, DEFAULT_CACHE_WRITE_READ_RATIO, PLAN_STEP_KEE
|
|
|
45
45
|
import { extractPlanSteps, findCompletedMarkers } from "../utils/plan-steps.js";
|
|
46
46
|
import { readFileSync } from "node:fs";
|
|
47
47
|
import { clampThinkingForPlanMode } from "./thinking-level.js";
|
|
48
|
-
import { pruneStaleToolResults } from "./compaction/tool-result-pruner.js";
|
|
48
|
+
import { pruneStaleToolResults, shouldPruneToolResults } from "./compaction/tool-result-pruner.js";
|
|
49
49
|
import { discoverAgents } from "./agents.js";
|
|
50
50
|
import { enhancePrompt } from "../utils/prompt-enhancer.js";
|
|
51
51
|
import { detectLanguages, detectProjectStack } from "./language-detector.js";
|
|
@@ -1691,36 +1691,6 @@ export class AgentSession {
|
|
|
1691
1691
|
if (!force) {
|
|
1692
1692
|
if (!this.settingsManager.get("autoCompact"))
|
|
1693
1693
|
return messages;
|
|
1694
|
-
// Cheap stale-tool-output pruning before the expensive LLM
|
|
1695
|
-
// compaction check. In-place mutation preserves anchors; drop the
|
|
1696
|
-
// retained usage afterwards since it counted the pruned content.
|
|
1697
|
-
const pruneResult = pruneStaleToolResults(messages);
|
|
1698
|
-
if (pruneResult.pruned) {
|
|
1699
|
-
this.cacheDiagnostics.noteEdit("tool_prune", pruneResult.freedTokens);
|
|
1700
|
-
this.providerContext = null;
|
|
1701
|
-
log("INFO", "compaction", "Pruned stale tool outputs", {
|
|
1702
|
-
prunedResults: String(pruneResult.prunedResults),
|
|
1703
|
-
compactedToolCalls: String(pruneResult.compactedToolCalls),
|
|
1704
|
-
freedTokens: String(pruneResult.freedTokens),
|
|
1705
|
-
});
|
|
1706
|
-
}
|
|
1707
|
-
if (Date.now() < this.compactionRetryAfter)
|
|
1708
|
-
return messages;
|
|
1709
|
-
// The turn's own usage also counted the pruned content — after a
|
|
1710
|
-
// prune, fall back to estimating the (now smaller) history so the
|
|
1711
|
-
// freed tokens actually defer the LLM compaction.
|
|
1712
|
-
let usage = pruneResult.pruned ? undefined : transformOpts.usage;
|
|
1713
|
-
let pendingMessages = transformOpts.pendingMessages;
|
|
1714
|
-
if (!usage && this.providerContext) {
|
|
1715
|
-
const anchorIndex = messages.lastIndexOf(this.providerContext.anchor);
|
|
1716
|
-
if (anchorIndex >= 0) {
|
|
1717
|
-
usage = this.providerContext.usage;
|
|
1718
|
-
pendingMessages = messages.slice(anchorIndex + 1);
|
|
1719
|
-
}
|
|
1720
|
-
else {
|
|
1721
|
-
this.providerContext = null;
|
|
1722
|
-
}
|
|
1723
|
-
}
|
|
1724
1694
|
const contextWindow = getContextWindow(this.model, {
|
|
1725
1695
|
provider: this.provider,
|
|
1726
1696
|
accountId,
|
|
@@ -1733,10 +1703,48 @@ export class AgentSession {
|
|
|
1733
1703
|
accountId,
|
|
1734
1704
|
approvedPlanPath: this.approvedPlanPath,
|
|
1735
1705
|
});
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1706
|
+
// Provider usage when there is some, else an estimate of the history.
|
|
1707
|
+
const measureActiveTokens = () => {
|
|
1708
|
+
let usage = transformOpts.usage;
|
|
1709
|
+
let pendingMessages = transformOpts.pendingMessages;
|
|
1710
|
+
if (!usage && this.providerContext) {
|
|
1711
|
+
const anchorIndex = messages.lastIndexOf(this.providerContext.anchor);
|
|
1712
|
+
if (anchorIndex >= 0) {
|
|
1713
|
+
usage = this.providerContext.usage;
|
|
1714
|
+
pendingMessages = messages.slice(anchorIndex + 1);
|
|
1715
|
+
}
|
|
1716
|
+
else {
|
|
1717
|
+
this.providerContext = null;
|
|
1718
|
+
}
|
|
1719
|
+
}
|
|
1720
|
+
return calculateActiveContextTokens(messages, { usage, pendingMessages });
|
|
1721
|
+
};
|
|
1722
|
+
let activeTokens = measureActiveTokens();
|
|
1723
|
+
// Cheap stale-tool-output pruning before the expensive LLM
|
|
1724
|
+
// compaction check, once the context is big enough for the freed
|
|
1725
|
+
// tokens to be worth a cache rewrite. In-place mutation preserves
|
|
1726
|
+
// anchors; drop the retained usage afterwards since it counted the
|
|
1727
|
+
// pruned content.
|
|
1728
|
+
if (shouldPruneToolResults(activeTokens, policy.targetTokens)) {
|
|
1729
|
+
const pruneResult = pruneStaleToolResults(messages);
|
|
1730
|
+
if (pruneResult.pruned) {
|
|
1731
|
+
this.cacheDiagnostics.noteEdit("tool_prune", pruneResult.freedTokens);
|
|
1732
|
+
this.providerContext = null;
|
|
1733
|
+
log("INFO", "compaction", "Pruned stale tool outputs", {
|
|
1734
|
+
prunedResults: String(pruneResult.prunedResults),
|
|
1735
|
+
compactedToolCalls: String(pruneResult.compactedToolCalls),
|
|
1736
|
+
freedTokens: String(pruneResult.freedTokens),
|
|
1737
|
+
});
|
|
1738
|
+
// The turn's own usage also counted the pruned content — estimate
|
|
1739
|
+
// the (now smaller) history so the freed tokens actually defer
|
|
1740
|
+
// the LLM compaction.
|
|
1741
|
+
activeTokens = calculateActiveContextTokens(messages, {
|
|
1742
|
+
pendingMessages: transformOpts.pendingMessages,
|
|
1743
|
+
});
|
|
1744
|
+
}
|
|
1745
|
+
}
|
|
1746
|
+
if (Date.now() < this.compactionRetryAfter)
|
|
1747
|
+
return messages;
|
|
1740
1748
|
// An approved plan runs as ONE run, so step boundaries are only
|
|
1741
1749
|
// visible here, between model steps — not after the run ends.
|
|
1742
1750
|
const planStep = this.observePlanStepProgress(messages, contextWindow, activeTokens);
|
|
@@ -2793,7 +2801,7 @@ export class AgentSession {
|
|
|
2793
2801
|
return relative.startsWith("..") || path.isAbsolute(relative);
|
|
2794
2802
|
});
|
|
2795
2803
|
this.additionalRoots.push(resolved);
|
|
2796
|
-
await this.
|
|
2804
|
+
await this.refreshPromptForRoots();
|
|
2797
2805
|
return { ok: true, root: resolved };
|
|
2798
2806
|
}
|
|
2799
2807
|
/** Remove an exact root previously added with `/add-dir`. */
|
|
@@ -2804,9 +2812,20 @@ export class AgentSession {
|
|
|
2804
2812
|
return { ok: false, error: `Not an additional workspace root: ${resolved}` };
|
|
2805
2813
|
}
|
|
2806
2814
|
this.additionalRoots.splice(index, 1);
|
|
2807
|
-
await this.
|
|
2815
|
+
await this.refreshPromptForRoots();
|
|
2808
2816
|
return { ok: true, root: resolved };
|
|
2809
2817
|
}
|
|
2818
|
+
/**
|
|
2819
|
+
* Name a root change in the prompt only while there is no conversation yet.
|
|
2820
|
+
* Mid-conversation the env-delta note tells the model instead: the roots sit
|
|
2821
|
+
* in the Environment section, and rewriting it would invalidate every cached
|
|
2822
|
+
* message after it (a goal attaching a folder re-sent ~75k tokens).
|
|
2823
|
+
*/
|
|
2824
|
+
async refreshPromptForRoots() {
|
|
2825
|
+
if (this.messages.some((message) => message.role !== "system"))
|
|
2826
|
+
return;
|
|
2827
|
+
await this.rebuildSystemPromptInPlace();
|
|
2828
|
+
}
|
|
2810
2829
|
/**
|
|
2811
2830
|
* Names to advertise as available-on-demand. A tool the model already
|
|
2812
2831
|
* promoted lives in `this.tools` and carries its own schema, so it drops out
|