Skip to content

Commit 565a6d8

Browse files
config and docs
1 parent 62bca34 commit 565a6d8

File tree

4 files changed

+26
-10
lines changed

4 files changed

+26
-10
lines changed

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,13 @@ DCP implements two complementary strategies:
2828
**Deduplication** — Fast, zero-cost pruning that identifies repeated tool calls (e.g., reading the same file multiple times) and keeps only the most recent output. Runs instantly with no LLM calls.
2929

3030
**AI Analysis** — Uses a language model to semantically analyze conversation context and identify tool outputs that are no longer relevant to the current task. More thorough but incurs LLM cost.
31+
32+
## Context Pruning Tool
33+
34+
When `strategies.onTool` is enabled, DCP exposes a `context_pruning` tool to Opencode that the AI can call to trigger pruning on demand. To help the AI use this tool effectively, DCP also injects guidance.
35+
36+
When `nudge_freq` is enabled, injects reminders (every `nudge_freq` tool results) prompting the AI to consider pruning when appropriate.
37+
3138
## How It Works
3239

3340
DCP is **non-destructive**—pruning state is kept in memory only. When requests go to your LLM, DCP replaces pruned outputs with a placeholder; original session data stays intact.
@@ -46,6 +53,7 @@ DCP uses its own config file (`~/.config/opencode/dcp.jsonc` or `.opencode/dcp.j
4653
| `showModelErrorToasts` | `true` | Show notifications on model fallback |
4754
| `strictModelSelection` | `false` | Only run AI analysis with session or configured model (disables fallback models) |
4855
| `pruning_summary` | `"detailed"` | `"off"`, `"minimal"`, or `"detailed"` |
56+
| `nudge_freq` | `5` | Remind AI to prune every N tool results (0 = disabled) |
4957
| `protectedTools` | `["task", "todowrite", "todoread", "context_pruning"]` | Tools that are never pruned |
5058
| `strategies.onIdle` | `["deduplication", "ai-analysis"]` | Strategies for automatic pruning |
5159
| `strategies.onTool` | `["deduplication", "ai-analysis"]` | Strategies when AI calls `context_pruning` |

index.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,9 @@ const plugin: Plugin = (async (ctx) => {
7777

7878
let modified = false
7979

80-
// Inject periodic nudge every 5 tool results
81-
if (config.strategies.onTool.length > 0) {
82-
if (injectNudge(body.messages, toolTracker, NUDGE_INSTRUCTION)) {
80+
// Inject periodic nudge every N tool results
81+
if (config.strategies.onTool.length > 0 && config.nudge_freq > 0) {
82+
if (injectNudge(body.messages, toolTracker, NUDGE_INSTRUCTION, config.nudge_freq)) {
8383
logger.debug("fetch", "Injected tool-result nudge", {
8484
toolResultCount: toolTracker.toolResultCount
8585
})

lib/config.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export interface PluginConfig {
1515
showModelErrorToasts?: boolean
1616
strictModelSelection?: boolean
1717
pruning_summary: "off" | "minimal" | "detailed"
18+
nudge_freq: number
1819
strategies: {
1920
onIdle: PruningStrategy[]
2021
onTool: PruningStrategy[]
@@ -33,6 +34,7 @@ const defaultConfig: PluginConfig = {
3334
showModelErrorToasts: true,
3435
strictModelSelection: false,
3536
pruning_summary: 'detailed',
37+
nudge_freq: 5,
3638
strategies: {
3739
onIdle: ['deduplication', 'ai-analysis', "strip-reasoning"],
3840
onTool: ['deduplication', 'ai-analysis', "strip-reasoning"]
@@ -47,6 +49,7 @@ const VALID_CONFIG_KEYS = new Set([
4749
'showModelErrorToasts',
4850
'strictModelSelection',
4951
'pruning_summary',
52+
'nudge_freq',
5053
'strategies'
5154
])
5255

@@ -118,6 +121,8 @@ function createDefaultConfig(): void {
118121
},
119122
// Summary display: "off", "minimal", or "detailed"
120123
"pruning_summary": "detailed",
124+
// How often to nudge the AI to prune (every N tool results, 0 = disabled)
125+
"nudge_freq": 5,
121126
// Tools that should never be pruned
122127
"protectedTools": ["task", "todowrite", "todoread", "context_pruning"]
123128
}
@@ -196,7 +201,8 @@ export function getConfig(ctx?: PluginInput): ConfigResult {
196201
showModelErrorToasts: globalConfig.showModelErrorToasts ?? config.showModelErrorToasts,
197202
strictModelSelection: globalConfig.strictModelSelection ?? config.strictModelSelection,
198203
strategies: mergeStrategies(config.strategies, globalConfig.strategies as any),
199-
pruning_summary: globalConfig.pruning_summary ?? config.pruning_summary
204+
pruning_summary: globalConfig.pruning_summary ?? config.pruning_summary,
205+
nudge_freq: globalConfig.nudge_freq ?? config.nudge_freq
200206
}
201207
logger.info('config', 'Loaded global config', { path: configPaths.global })
202208
}
@@ -226,7 +232,8 @@ export function getConfig(ctx?: PluginInput): ConfigResult {
226232
showModelErrorToasts: projectConfig.showModelErrorToasts ?? config.showModelErrorToasts,
227233
strictModelSelection: projectConfig.strictModelSelection ?? config.strictModelSelection,
228234
strategies: mergeStrategies(config.strategies, projectConfig.strategies as any),
229-
pruning_summary: projectConfig.pruning_summary ?? config.pruning_summary
235+
pruning_summary: projectConfig.pruning_summary ?? config.pruning_summary,
236+
nudge_freq: projectConfig.nudge_freq ?? config.nudge_freq
230237
}
231238
logger.info('config', 'Loaded project config (overrides global)', { path: configPaths.project })
232239
}

lib/synth-instruction.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,21 +38,22 @@ function countToolResults(messages: any[], tracker: ToolTracker): number {
3838
}
3939

4040
/**
41-
* Counts new tool results and injects nudge instruction every 5th tool result.
41+
* Counts new tool results and injects nudge instruction every N tool results.
4242
* Returns true if injection happened.
4343
*/
4444
export function injectNudge(
4545
messages: any[],
4646
tracker: ToolTracker,
47-
nudgeText: string
47+
nudgeText: string,
48+
freq: number
4849
): boolean {
4950
const prevCount = tracker.toolResultCount
5051
const newCount = countToolResults(messages, tracker)
5152

5253
if (newCount > 0) {
53-
// Check if we crossed a multiple of 5
54-
const prevBucket = Math.floor(prevCount / 5)
55-
const newBucket = Math.floor(tracker.toolResultCount / 5)
54+
// Check if we crossed a multiple of freq
55+
const prevBucket = Math.floor(prevCount / freq)
56+
const newBucket = Math.floor(tracker.toolResultCount / freq)
5657
if (newBucket > prevBucket) {
5758
// Inject at the END of messages so it's in immediate context
5859
return appendNudge(messages, nudgeText)

0 commit comments

Comments
 (0)