Skip to content

Commit 0932eb5

Browse files
authored
Merge pull request #216 from Opencode-DCP/refactor/remove-on-idle
refactor: remove on-idle functionality
2 parents 7bf1a61 + b88c6a3 commit 0932eb5

File tree

12 files changed

+18
-664
lines changed

12 files changed

+18
-664
lines changed

README.md

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,6 @@ DCP uses multiple tools and strategies to reduce context size:
4141

4242
**Purge Errors** — Prunes tool inputs for tools that returned errors after a configurable number of turns (default: 4). Error messages are preserved for context, but the potentially large input content is removed. Runs automatically on every request with zero LLM cost.
4343

44-
**On Idle Analysis** — Uses a language model to semantically analyze conversation context during idle periods and identify tool outputs that are no longer relevant. Disabled by default (legacy behavior).
45-
4644
Your session history is never modified—DCP replaces pruned content with placeholders before sending requests to your LLM.
4745

4846
## Impact on Prompt Caching
@@ -118,18 +116,6 @@ DCP uses its own config file:
118116
// Additional tools to protect from pruning
119117
"protectedTools": [],
120118
},
121-
// (Legacy) Run an LLM to analyze what tool calls are no longer relevant on idle
122-
"onIdle": {
123-
"enabled": false,
124-
// Additional tools to protect from pruning
125-
"protectedTools": [],
126-
// Override model for analysis (format: "provider/model")
127-
// "model": "anthropic/claude-haiku-4-5",
128-
// Show toast notifications when model selection fails
129-
"showModelErrorToasts": true,
130-
// When true, fallback models are not permitted
131-
"strictModelSelection": false,
132-
},
133119
},
134120
}
135121
```

index.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import type { Plugin } from "@opencode-ai/plugin"
22
import { getConfig } from "./lib/config"
33
import { Logger } from "./lib/logger"
4-
import { loadPrompt } from "./lib/prompt"
4+
import { loadPrompt } from "./lib/prompts"
55
import { createSessionState } from "./lib/state"
66
import { createDiscardTool, createExtractTool } from "./lib/strategies"
7-
import { createChatMessageTransformHandler, createEventHandler } from "./lib/hooks"
7+
import { createChatMessageTransformHandler } from "./lib/hooks"
88

99
const plugin: Plugin = (async (ctx) => {
1010
const config = getConfig(ctx)
@@ -91,7 +91,6 @@ const plugin: Plugin = (async (ctx) => {
9191
)
9292
}
9393
},
94-
event: createEventHandler(ctx.client, config, state, logger, ctx.directory),
9594
}
9695
}) satisfies Plugin
9796

lib/config.ts

Lines changed: 0 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,6 @@ export interface Deduplication {
99
protectedTools: string[]
1010
}
1111

12-
export interface OnIdle {
13-
enabled: boolean
14-
model?: string
15-
showModelErrorToasts?: boolean
16-
strictModelSelection?: boolean
17-
protectedTools: string[]
18-
}
19-
2012
export interface DiscardTool {
2113
enabled: boolean
2214
}
@@ -63,7 +55,6 @@ export interface PluginConfig {
6355
deduplication: Deduplication
6456
supersedeWrites: SupersedeWrites
6557
purgeErrors: PurgeErrors
66-
onIdle: OnIdle
6758
}
6859
}
6960

@@ -102,13 +93,6 @@ export const VALID_CONFIG_KEYS = new Set([
10293
"strategies.purgeErrors.enabled",
10394
"strategies.purgeErrors.turns",
10495
"strategies.purgeErrors.protectedTools",
105-
// strategies.onIdle
106-
"strategies.onIdle",
107-
"strategies.onIdle.enabled",
108-
"strategies.onIdle.model",
109-
"strategies.onIdle.showModelErrorToasts",
110-
"strategies.onIdle.strictModelSelection",
111-
"strategies.onIdle.protectedTools",
11296
])
11397

11498
// Extract all key paths from a config object for validation
@@ -272,60 +256,6 @@ function validateConfigTypes(config: Record<string, any>): ValidationError[] {
272256
})
273257
}
274258

275-
// onIdle
276-
if (strategies.onIdle) {
277-
if (
278-
strategies.onIdle.enabled !== undefined &&
279-
typeof strategies.onIdle.enabled !== "boolean"
280-
) {
281-
errors.push({
282-
key: "strategies.onIdle.enabled",
283-
expected: "boolean",
284-
actual: typeof strategies.onIdle.enabled,
285-
})
286-
}
287-
if (
288-
strategies.onIdle.model !== undefined &&
289-
typeof strategies.onIdle.model !== "string"
290-
) {
291-
errors.push({
292-
key: "strategies.onIdle.model",
293-
expected: "string",
294-
actual: typeof strategies.onIdle.model,
295-
})
296-
}
297-
if (
298-
strategies.onIdle.showModelErrorToasts !== undefined &&
299-
typeof strategies.onIdle.showModelErrorToasts !== "boolean"
300-
) {
301-
errors.push({
302-
key: "strategies.onIdle.showModelErrorToasts",
303-
expected: "boolean",
304-
actual: typeof strategies.onIdle.showModelErrorToasts,
305-
})
306-
}
307-
if (
308-
strategies.onIdle.strictModelSelection !== undefined &&
309-
typeof strategies.onIdle.strictModelSelection !== "boolean"
310-
) {
311-
errors.push({
312-
key: "strategies.onIdle.strictModelSelection",
313-
expected: "boolean",
314-
actual: typeof strategies.onIdle.strictModelSelection,
315-
})
316-
}
317-
if (
318-
strategies.onIdle.protectedTools !== undefined &&
319-
!Array.isArray(strategies.onIdle.protectedTools)
320-
) {
321-
errors.push({
322-
key: "strategies.onIdle.protectedTools",
323-
expected: "string[]",
324-
actual: typeof strategies.onIdle.protectedTools,
325-
})
326-
}
327-
}
328-
329259
// supersedeWrites
330260
if (strategies.supersedeWrites) {
331261
if (
@@ -459,12 +389,6 @@ const defaultConfig: PluginConfig = {
459389
turns: 4,
460390
protectedTools: [...DEFAULT_PROTECTED_TOOLS],
461391
},
462-
onIdle: {
463-
enabled: false,
464-
protectedTools: [...DEFAULT_PROTECTED_TOOLS],
465-
showModelErrorToasts: true,
466-
strictModelSelection: false,
467-
},
468392
},
469393
}
470394

@@ -587,18 +511,6 @@ function createDefaultConfig(): void {
587511
"turns": 4,
588512
// Additional tools to protect from pruning
589513
"protectedTools": []
590-
},
591-
// (Legacy) Run an LLM to analyze what tool calls are no longer relevant on idle
592-
"onIdle": {
593-
"enabled": false,
594-
// Additional tools to protect from pruning
595-
"protectedTools": [],
596-
// Override model for analysis (format: "provider/model")
597-
// "model": "anthropic/claude-haiku-4-5",
598-
// Show toast notifications when model selection fails
599-
"showModelErrorToasts": true,
600-
// When true, fallback models are not permitted
601-
"strictModelSelection": false
602514
}
603515
}
604516
}
@@ -660,20 +572,6 @@ function mergeStrategies(
660572
]),
661573
],
662574
},
663-
onIdle: {
664-
enabled: override.onIdle?.enabled ?? base.onIdle.enabled,
665-
model: override.onIdle?.model ?? base.onIdle.model,
666-
showModelErrorToasts:
667-
override.onIdle?.showModelErrorToasts ?? base.onIdle.showModelErrorToasts,
668-
strictModelSelection:
669-
override.onIdle?.strictModelSelection ?? base.onIdle.strictModelSelection,
670-
protectedTools: [
671-
...new Set([
672-
...base.onIdle.protectedTools,
673-
...(override.onIdle?.protectedTools ?? []),
674-
]),
675-
],
676-
},
677575
}
678576
}
679577

@@ -728,10 +626,6 @@ function deepCloneConfig(config: PluginConfig): PluginConfig {
728626
...config.strategies.purgeErrors,
729627
protectedTools: [...config.strategies.purgeErrors.protectedTools],
730628
},
731-
onIdle: {
732-
...config.strategies.onIdle,
733-
protectedTools: [...config.strategies.onIdle.protectedTools],
734-
},
735629
},
736630
}
737631
}

lib/hooks.ts

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { syncToolCache } from "./state/tool-cache"
55
import { deduplicate, supersedeWrites, purgeErrors } from "./strategies"
66
import { prune, insertPruneToolContext } from "./messages"
77
import { checkSession } from "./state"
8-
import { runOnIdle } from "./strategies/on-idle"
98

109
export function createChatMessageTransformHandler(
1110
client: any,
@@ -35,33 +34,3 @@ export function createChatMessageTransformHandler(
3534
}
3635
}
3736
}
38-
39-
export function createEventHandler(
40-
client: any,
41-
config: PluginConfig,
42-
state: SessionState,
43-
logger: Logger,
44-
workingDirectory?: string,
45-
) {
46-
return async ({ event }: { event: any }) => {
47-
if (state.sessionId === null || state.isSubAgent) {
48-
return
49-
}
50-
51-
if (event.type === "session.status" && event.properties.status.type === "idle") {
52-
if (!config.strategies.onIdle.enabled) {
53-
return
54-
}
55-
if (state.lastToolPrune) {
56-
logger.info("Skipping OnIdle pruning - last tool was prune")
57-
return
58-
}
59-
60-
try {
61-
await runOnIdle(client, state, logger, config, workingDirectory)
62-
} catch (err: any) {
63-
logger.error("OnIdle pruning failed", { error: err.message })
64-
}
65-
}
66-
}
67-
}

lib/messages/inject.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { SessionState, WithParts } from "../state"
22
import type { Logger } from "../logger"
33
import type { PluginConfig } from "../config"
4-
import { loadPrompt } from "../prompt"
4+
import { loadPrompt } from "../prompts"
55
import { extractParameterKey, buildToolIdList, createSyntheticUserMessage } from "./utils"
66
import { getLastUserMessage } from "../shared-utils"
77

0 commit comments

Comments
 (0)