Skip to content
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,6 @@ DCP uses its own config file:
"enabled": true,
// Enable debug logging to ~/.config/opencode/logs/dcp/
"debug": false,
// Show toast notifications when a new version is available
"showUpdateToasts": true,
// Summary display: "off", "minimal", or "detailed"
"pruningSummary": "detailed",
// Strategies for pruning tokens from chat history
Expand Down
12 changes: 1 addition & 11 deletions lib/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ export interface PruneTool {
export interface PluginConfig {
enabled: boolean
debug: boolean
showUpdateToasts?: boolean
pruningSummary: "off" | "minimal" | "detailed"
strategies: {
deduplication: Deduplication
Expand All @@ -47,7 +46,7 @@ export const VALID_CONFIG_KEYS = new Set([
// Top-level keys
'enabled',
'debug',
'showUpdateToasts',
'showUpdateToasts', // Deprecated but kept for backwards compatibility
'pruningSummary',
'strategies',
// strategies.deduplication
Expand Down Expand Up @@ -106,9 +105,6 @@ function validateConfigTypes(config: Record<string, any>): ValidationError[] {
if (config.debug !== undefined && typeof config.debug !== 'boolean') {
errors.push({ key: 'debug', expected: 'boolean', actual: typeof config.debug })
}
if (config.showUpdateToasts !== undefined && typeof config.showUpdateToasts !== 'boolean') {
errors.push({ key: 'showUpdateToasts', expected: 'boolean', actual: typeof config.showUpdateToasts })
}
if (config.pruningSummary !== undefined) {
const validValues = ['off', 'minimal', 'detailed']
if (!validValues.includes(config.pruningSummary)) {
Expand Down Expand Up @@ -217,7 +213,6 @@ function showConfigValidationWarnings(
const defaultConfig: PluginConfig = {
enabled: true,
debug: false,
showUpdateToasts: true,
pruningSummary: 'detailed',
strategies: {
deduplication: {
Expand Down Expand Up @@ -310,8 +305,6 @@ function createDefaultConfig(): void {
"enabled": true,
// Enable debug logging to ~/.config/opencode/logs/dcp/
"debug": false,
// Show toast notifications when a new version is available
"showUpdateToasts": true,
// Summary display: "off", "minimal", or "detailed"
"pruningSummary": "detailed",
// Strategies for pruning tokens from chat history
Expand Down Expand Up @@ -468,7 +461,6 @@ export function getConfig(ctx: PluginInput): PluginConfig {
config = {
enabled: result.data.enabled ?? config.enabled,
debug: result.data.debug ?? config.debug,
showUpdateToasts: result.data.showUpdateToasts ?? config.showUpdateToasts,
pruningSummary: result.data.pruningSummary ?? config.pruningSummary,
strategies: mergeStrategies(config.strategies, result.data.strategies as any)
}
Expand Down Expand Up @@ -500,7 +492,6 @@ export function getConfig(ctx: PluginInput): PluginConfig {
config = {
enabled: result.data.enabled ?? config.enabled,
debug: result.data.debug ?? config.debug,
showUpdateToasts: result.data.showUpdateToasts ?? config.showUpdateToasts,
pruningSummary: result.data.pruningSummary ?? config.pruningSummary,
strategies: mergeStrategies(config.strategies, result.data.strategies as any)
}
Expand Down Expand Up @@ -529,7 +520,6 @@ export function getConfig(ctx: PluginInput): PluginConfig {
config = {
enabled: result.data.enabled ?? config.enabled,
debug: result.data.debug ?? config.debug,
showUpdateToasts: result.data.showUpdateToasts ?? config.showUpdateToasts,
pruningSummary: result.data.pruningSummary ?? config.pruningSummary,
strategies: mergeStrategies(config.strategies, result.data.strategies as any)
}
Expand Down
5 changes: 0 additions & 5 deletions lib/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,6 @@ export function createEventHandler(
return
}

if (event.type === "session.compacted") {
logger.info("Session compaction detected - updating state")
state.lastCompaction = Date.now()
}

if (event.type === "session.status" && event.properties.status.type === "idle") {
if (!config.strategies.onIdle.enabled) {
return
Expand Down
4 changes: 4 additions & 0 deletions lib/messages/prune.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ const buildPrunableToolsList = (
return
}
const numericId = toolIdList.indexOf(toolCallId)
if (numericId === -1) {
logger.warn(`Tool in cache but not in toolIdList - possible stale entry`, { toolCallId, tool: toolParameterEntry.tool })
return
}
const paramKey = extractParameterKey(toolParameterEntry.tool, toolParameterEntry.parameters)
const description = paramKey ? `${toolParameterEntry.tool}, ${paramKey}` : toolParameterEntry.tool
lines.push(`${numericId}: ${description}`)
Expand Down
9 changes: 0 additions & 9 deletions lib/shared-utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { Logger } from "./logger"
import { SessionState, WithParts } from "./state"

export const isMessageCompacted = (
Expand All @@ -20,12 +19,4 @@ export const getLastUserMessage = (
return null
}

export const checkForCompaction = (
state: SessionState,
messages: WithParts[],
logger: Logger
): void => {
for (const msg of messages) {

}
}
4 changes: 1 addition & 3 deletions lib/state/persistence.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ export interface PersistedSessionState {
prune: Prune
stats: SessionStats;
lastUpdated: string;
lastCompacted: number
}

const STORAGE_DIR = join(
Expand Down Expand Up @@ -55,8 +54,7 @@ export async function saveSessionState(
sessionName: sessionName,
prune: sessionState.prune,
stats: sessionState.stats,
lastUpdated: new Date().toISOString(),
lastCompacted: sessionState.lastCompaction
lastUpdated: new Date().toISOString()
};

const filePath = getSessionFilePath(sessionState.sessionId);
Expand Down
24 changes: 21 additions & 3 deletions lib/state/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,19 @@ export const checkSession = async (
if (state.sessionId === null || state.sessionId !== lastSessionId) {
logger.info(`Session changed: ${state.sessionId} -> ${lastSessionId}`)
try {
await ensureSessionInitialized(client, state, lastSessionId, logger)
await ensureSessionInitialized(client, state, lastSessionId, logger, messages)
} catch (err: any) {
logger.error("Failed to initialize session state", { error: err.message })
}
}

const lastCompactionTimestamp = findLastCompactionTimestamp(messages)
if (lastCompactionTimestamp > state.lastCompaction) {
state.lastCompaction = lastCompactionTimestamp
state.toolParameters.clear()
state.prune.toolIds = []
logger.info("Detected compaction from messages - cleared tool cache", { timestamp: lastCompactionTimestamp })
}
}

export function createSessionState(): SessionState {
Expand Down Expand Up @@ -66,7 +74,8 @@ export async function ensureSessionInitialized(
client: any,
state: SessionState,
sessionId: string,
logger: Logger
logger: Logger,
messages: WithParts[]
): Promise<void> {
if (state.sessionId === sessionId) {
return;
Expand Down Expand Up @@ -97,5 +106,14 @@ export async function ensureSessionInitialized(
pruneTokenCounter: persisted.stats?.pruneTokenCounter || 0,
totalPruneTokens: persisted.stats?.totalPruneTokens || 0,
}
state.lastCompaction = persisted.lastCompacted || 0
}

function findLastCompactionTimestamp(messages: WithParts[]): number {
for (let i = messages.length - 1; i >= 0; i--) {
const msg = messages[i]
if (msg.info.role === "assistant" && msg.info.summary === true) {
return msg.info.time.created
}
}
return 0
}
4 changes: 2 additions & 2 deletions lib/strategies/prune-tool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,14 @@ export function createPruneTool(
return "No numeric IDs provided. Format: [reason, id1, id2, ...] where reason is 'completion', 'noise', or 'consolidation'."
}

await ensureSessionInitialized(ctx.client, state, sessionId, logger)

// Fetch messages to calculate tokens and find current agent
const messagesResponse = await client.session.messages({
path: { id: sessionId }
})
const messages: WithParts[] = messagesResponse.data || messagesResponse

await ensureSessionInitialized(ctx.client, state, sessionId, logger, messages)

const currentParams = getCurrentParams(messages, logger)
const toolIdList: string[] = buildToolIdList(state, messages, logger)

Expand Down