diff --git a/lib/hooks.ts b/lib/hooks.ts index f24d52c..72fda69 100644 --- a/lib/hooks.ts +++ b/lib/hooks.ts @@ -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 diff --git a/lib/messages/prune.ts b/lib/messages/prune.ts index 918056e..33d9a7a 100644 --- a/lib/messages/prune.ts +++ b/lib/messages/prune.ts @@ -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}`) diff --git a/lib/shared-utils.ts b/lib/shared-utils.ts index 9cb60a1..fe6fbd6 100644 --- a/lib/shared-utils.ts +++ b/lib/shared-utils.ts @@ -1,4 +1,3 @@ -import { Logger } from "./logger" import { SessionState, WithParts } from "./state" export const isMessageCompacted = ( @@ -20,12 +19,4 @@ export const getLastUserMessage = ( return null } -export const checkForCompaction = ( - state: SessionState, - messages: WithParts[], - logger: Logger -): void => { - for (const msg of messages) { - } -} diff --git a/lib/state/persistence.ts b/lib/state/persistence.ts index 89d6772..eb97551 100644 --- a/lib/state/persistence.ts +++ b/lib/state/persistence.ts @@ -16,7 +16,6 @@ export interface PersistedSessionState { prune: Prune stats: SessionStats; lastUpdated: string; - lastCompacted: number } const STORAGE_DIR = join( @@ -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); diff --git a/lib/state/state.ts b/lib/state/state.ts index 035f81b..7ad2617 100644 --- a/lib/state/state.ts +++ b/lib/state/state.ts @@ -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 { @@ -66,7 +74,8 @@ export async function ensureSessionInitialized( client: any, state: SessionState, sessionId: string, - logger: Logger + logger: Logger, + messages: WithParts[] ): Promise { if (state.sessionId === sessionId) { return; @@ -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 } diff --git a/lib/strategies/prune-tool.ts b/lib/strategies/prune-tool.ts index e361325..6cf9052 100644 --- a/lib/strategies/prune-tool.ts +++ b/lib/strategies/prune-tool.ts @@ -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)