From 54e981eaf158627892e517fbde89a5dd2b03059e Mon Sep 17 00:00:00 2001 From: Daniel Smolsky Date: Mon, 1 Dec 2025 19:18:52 -0500 Subject: [PATCH 1/4] fix: skip DCP fetch wrapper processing for subagent sessions --- lib/fetch-wrapper/index.ts | 12 +++++++++--- lib/hooks.ts | 14 ++++++++++++++ lib/state.ts | 6 ++++++ 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/lib/fetch-wrapper/index.ts b/lib/fetch-wrapper/index.ts index d57bda78..0cadb565 100644 --- a/lib/fetch-wrapper/index.ts +++ b/lib/fetch-wrapper/index.ts @@ -28,7 +28,7 @@ export function installFetchWrapper( prompts: SynthPrompts ): () => void { const originalGlobalFetch = globalThis.fetch - + const ctx: FetchHandlerContext = { state, logger, @@ -39,6 +39,14 @@ export function installFetchWrapper( } globalThis.fetch = async (input: any, init?: any) => { + // Skip all DCP processing for subagent sessions + if (state.lastSeenSessionId && state.subagentSessions.has(state.lastSeenSessionId)) { + logger.debug("fetch-wrapper", "Skipping DCP processing for subagent session", { + sessionId: state.lastSeenSessionId.substring(0, 8) + }) + return originalGlobalFetch(input, init) + } + if (init?.body && typeof init.body === 'string') { try { const body = JSON.parse(init.body) @@ -74,14 +82,12 @@ export function installFetchWrapper( init.body = JSON.stringify(body) } } catch (e) { - // Silently ignore parsing errors - pass through to original fetch } } return originalGlobalFetch(input, init) } - // Return cleanup function to restore original fetch return () => { globalThis.fetch = originalGlobalFetch } diff --git a/lib/hooks.ts b/lib/hooks.ts index 6c2e8073..2c39fd40 100644 --- a/lib/hooks.ts +++ b/lib/hooks.ts @@ -72,6 +72,20 @@ export function createChatParamsHandler( providerID = input.message.model.providerID } + // Track the last seen session ID for fetch wrapper correlation + state.lastSeenSessionId = sessionId + + // Check if this is a subagent session and track it to skip fetch wrapper processing + if (!state.subagentSessions.has(sessionId)) { + const isSubagent = await isSubagentSession(client, sessionId) + if (isSubagent) { + state.subagentSessions.add(sessionId) + logger.info("chat.params", "Detected subagent session, will skip DCP processing", { + sessionId: sessionId.substring(0, 8) + }) + } + } + // Cache model info for the session if (providerID && modelID) { state.model.set(sessionId, { diff --git a/lib/state.ts b/lib/state.ts index 5145eae4..abeebc87 100644 --- a/lib/state.ts +++ b/lib/state.ts @@ -22,6 +22,10 @@ export interface PluginState { googleToolCallMapping: Map> /** Set of session IDs that have been restored from disk */ restoredSessions: Set + /** Set of session IDs that are subagents (have a parentID) - used to skip fetch wrapper processing */ + subagentSessions: Set + /** The most recent session ID seen in chat.params - used to correlate fetch requests */ + lastSeenSessionId: string | null } export interface ToolParameterEntry { @@ -45,6 +49,8 @@ export function createPluginState(): PluginState { model: new Map(), googleToolCallMapping: new Map(), restoredSessions: new Set(), + subagentSessions: new Set(), + lastSeenSessionId: null, } } From aa24dc99f61ad890e4348bfee3ffcd61193a1eda Mon Sep 17 00:00:00 2001 From: Daniel Smolsky Date: Mon, 1 Dec 2025 19:43:59 -0500 Subject: [PATCH 2/4] perf: avoid redundant isSubagentSession API calls --- lib/hooks.ts | 8 +++----- lib/state.ts | 3 +++ 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/hooks.ts b/lib/hooks.ts index 2c39fd40..d6d18348 100644 --- a/lib/hooks.ts +++ b/lib/hooks.ts @@ -75,14 +75,12 @@ export function createChatParamsHandler( // Track the last seen session ID for fetch wrapper correlation state.lastSeenSessionId = sessionId - // Check if this is a subagent session and track it to skip fetch wrapper processing - if (!state.subagentSessions.has(sessionId)) { + // Check if this is a subagent session + if (!state.checkedSessions.has(sessionId)) { + state.checkedSessions.add(sessionId) const isSubagent = await isSubagentSession(client, sessionId) if (isSubagent) { state.subagentSessions.add(sessionId) - logger.info("chat.params", "Detected subagent session, will skip DCP processing", { - sessionId: sessionId.substring(0, 8) - }) } } diff --git a/lib/state.ts b/lib/state.ts index abeebc87..3bdb4223 100644 --- a/lib/state.ts +++ b/lib/state.ts @@ -22,6 +22,8 @@ export interface PluginState { googleToolCallMapping: Map> /** Set of session IDs that have been restored from disk */ restoredSessions: Set + /** Set of session IDs we've already checked for subagent status (to avoid redundant API calls) */ + checkedSessions: Set /** Set of session IDs that are subagents (have a parentID) - used to skip fetch wrapper processing */ subagentSessions: Set /** The most recent session ID seen in chat.params - used to correlate fetch requests */ @@ -49,6 +51,7 @@ export function createPluginState(): PluginState { model: new Map(), googleToolCallMapping: new Map(), restoredSessions: new Set(), + checkedSessions: new Set(), subagentSessions: new Set(), lastSeenSessionId: null, } From d1ef39334e125cdbb3c48b4529172f0bbb178ee7 Mon Sep 17 00:00:00 2001 From: Daniel Smolsky Date: Mon, 1 Dec 2025 19:46:55 -0500 Subject: [PATCH 3/4] docs: add subagents section with recommendation to disable prune tool --- README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/README.md b/README.md index 9d4f44ff..cb68f7ac 100644 --- a/README.md +++ b/README.md @@ -83,6 +83,20 @@ Settings are merged in order: **Defaults** → **Global** (`~/.config/opencode/d Restart OpenCode after making config changes. +## Subagents + +DCP automatically skips processing for subagent sessions (`general`, `explore`, etc.), but subagents can still invoke the `prune` tool. To prevent this, disable the tool in your OpenCode config. Any custom agents you've defined should also have prune disabled: + +```jsonc +// opencode.jsonc +{ + "agent": { + "general": { "tools": { "prune": false } }, + "explore": { "tools": { "prune": false } } + } +} +``` + ## License MIT From 872d37e9f3bd4c902c87fab1003b032a6bbb7981 Mon Sep 17 00:00:00 2001 From: Daniel Smolsky Date: Mon, 1 Dec 2025 19:53:49 -0500 Subject: [PATCH 4/4] v0.3.29 - Bump version --- README.md | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index cb68f7ac..6b29fe61 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Add to your OpenCode config: ```jsonc // opencode.jsonc { - "plugin": ["@tarquinen/opencode-dcp@0.3.28"] + "plugin": ["@tarquinen/opencode-dcp@0.3.29"] } ``` diff --git a/package-lock.json b/package-lock.json index b88cb2da..d9fa587b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@tarquinen/opencode-dcp", - "version": "0.3.28", + "version": "0.3.29", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@tarquinen/opencode-dcp", - "version": "0.3.28", + "version": "0.3.29", "license": "MIT", "dependencies": { "@ai-sdk/openai-compatible": "^1.0.27", diff --git a/package.json b/package.json index be2e5e85..c92bc4be 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@tarquinen/opencode-dcp", - "version": "0.3.28", + "version": "0.3.29", "type": "module", "description": "OpenCode plugin that optimizes token usage by pruning obsolete tool outputs from conversation context", "main": "./dist/index.js",