From 9e7abe2deaf060558949fda1cb2e24e67acfb535 Mon Sep 17 00:00:00 2001 From: acamq <179265037+acamq@users.noreply.github.com> Date: Sun, 15 Mar 2026 20:02:56 -0600 Subject: [PATCH] fix(todo-continuation-enforcer): skip continuation for compaction-only message history --- .../todo-continuation-enforcer/idle-event.ts | 7 +++++-- .../resolve-message-info.ts | 17 +++++++++++------ src/hooks/todo-continuation-enforcer/types.ts | 5 +++++ 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/hooks/todo-continuation-enforcer/idle-event.ts b/src/hooks/todo-continuation-enforcer/idle-event.ts index 58a200121..7149613ba 100644 --- a/src/hooks/todo-continuation-enforcer/idle-event.ts +++ b/src/hooks/todo-continuation-enforcer/idle-event.ts @@ -144,8 +144,11 @@ export async function handleSessionIdle(args: { } let resolvedInfo: ResolvedMessageInfo | undefined + let encounteredCompaction = false try { - resolvedInfo = await resolveLatestMessageInfo(ctx, sessionID) + const messageInfoResult = await resolveLatestMessageInfo(ctx, sessionID) + resolvedInfo = messageInfoResult.resolvedInfo + encounteredCompaction = messageInfoResult.encounteredCompaction } catch (error) { log(`[${HOOK_NAME}] Failed to fetch messages for agent check`, { sessionID, error: String(error) }) } @@ -164,7 +167,7 @@ export async function handleSessionIdle(args: { log(`[${HOOK_NAME}] Skipped: agent in skipAgents list`, { sessionID, agent: resolvedAgentName }) return } - if (compactionGuardActive && !resolvedInfo?.agent) { + if ((compactionGuardActive || encounteredCompaction) && !resolvedInfo?.agent) { log(`[${HOOK_NAME}] Skipped: compaction occurred but no agent info resolved`, { sessionID }) return } diff --git a/src/hooks/todo-continuation-enforcer/resolve-message-info.ts b/src/hooks/todo-continuation-enforcer/resolve-message-info.ts index cf4c5170c..f968f6e71 100644 --- a/src/hooks/todo-continuation-enforcer/resolve-message-info.ts +++ b/src/hooks/todo-continuation-enforcer/resolve-message-info.ts @@ -2,30 +2,35 @@ import type { PluginInput } from "@opencode-ai/plugin" import { normalizeSDKResponse } from "../../shared" -import type { MessageInfo, ResolvedMessageInfo } from "./types" +import type { MessageInfo, ResolveLatestMessageInfoResult } from "./types" export async function resolveLatestMessageInfo( ctx: PluginInput, sessionID: string -): Promise { +): Promise { const messagesResp = await ctx.client.session.messages({ path: { id: sessionID }, }) const messages = normalizeSDKResponse(messagesResp, [] as Array<{ info?: MessageInfo }>) + let encounteredCompaction = false for (let i = messages.length - 1; i >= 0; i--) { const info = messages[i].info if (info?.agent === "compaction") { + encounteredCompaction = true continue } if (info?.agent || info?.model || (info?.modelID && info?.providerID)) { return { - agent: info.agent, - model: info.model ?? (info.providerID && info.modelID ? { providerID: info.providerID, modelID: info.modelID } : undefined), - tools: info.tools, + resolvedInfo: { + agent: info.agent, + model: info.model ?? (info.providerID && info.modelID ? { providerID: info.providerID, modelID: info.modelID } : undefined), + tools: info.tools, + }, + encounteredCompaction, } } } - return undefined + return { resolvedInfo: undefined, encounteredCompaction } } diff --git a/src/hooks/todo-continuation-enforcer/types.ts b/src/hooks/todo-continuation-enforcer/types.ts index b7a434e10..0f40cec28 100644 --- a/src/hooks/todo-continuation-enforcer/types.ts +++ b/src/hooks/todo-continuation-enforcer/types.ts @@ -54,3 +54,8 @@ export interface ResolvedMessageInfo { model?: { providerID: string; modelID: string } tools?: Record } + +export interface ResolveLatestMessageInfoResult { + resolvedInfo?: ResolvedMessageInfo + encounteredCompaction: boolean +}