Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Add to your OpenCode config:
```jsonc
// opencode.jsonc
{
"plugin": ["@tarquinen/[email protected].28"]
"plugin": ["@tarquinen/[email protected].29"]
}
```

Expand Down Expand Up @@ -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
12 changes: 9 additions & 3 deletions lib/fetch-wrapper/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export function installFetchWrapper(
prompts: SynthPrompts
): () => void {
const originalGlobalFetch = globalThis.fetch

const ctx: FetchHandlerContext = {
state,
logger,
Expand All @@ -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)
Expand Down Expand Up @@ -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
}
Expand Down
12 changes: 12 additions & 0 deletions lib/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,18 @@ 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
if (!state.checkedSessions.has(sessionId)) {
state.checkedSessions.add(sessionId)
const isSubagent = await isSubagentSession(client, sessionId)
if (isSubagent) {
state.subagentSessions.add(sessionId)
}
}

// Cache model info for the session
if (providerID && modelID) {
state.model.set(sessionId, {
Expand Down
9 changes: 9 additions & 0 deletions lib/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ export interface PluginState {
googleToolCallMapping: Map<string, Map<string, string>>
/** Set of session IDs that have been restored from disk */
restoredSessions: Set<string>
/** Set of session IDs we've already checked for subagent status (to avoid redundant API calls) */
checkedSessions: Set<string>
/** Set of session IDs that are subagents (have a parentID) - used to skip fetch wrapper processing */
subagentSessions: Set<string>
/** The most recent session ID seen in chat.params - used to correlate fetch requests */
lastSeenSessionId: string | null
}

export interface ToolParameterEntry {
Expand All @@ -45,6 +51,9 @@ export function createPluginState(): PluginState {
model: new Map(),
googleToolCallMapping: new Map(),
restoredSessions: new Set(),
checkedSessions: new Set(),
subagentSessions: new Set(),
lastSeenSessionId: null,
}
}

Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down