fix(hooks): do not clear sessionFirstMessageProcessed on session.idle

SessionStart hooks fire on every user prompt instead of only at session
start. The root cause is clearSessionHookState(), called on every
session.idle event, which clears sessionFirstMessageProcessed. This
resets the isFirstMessage guard, making it always return true, so
SessionStart hooks execute on every prompt.

sessionFirstMessageProcessed is session-level state (tracks whether the
first message has been processed) and should only be cleared in
clearAllSessionHookState() on session deletion/disposal, not on idle.

sessionErrorState and sessionInterruptState remain cleared on idle since
they are per-response transient state.
This commit is contained in:
brooksbUWO
2026-05-04 13:27:07 -05:00
committed by YeonGyu-Kim
parent ac66a43e99
commit 9f6b68118e
@@ -7,7 +7,12 @@ export const sessionInterruptState = new Map<string, { interrupted: boolean }>()
export function clearSessionHookState(sessionID: string): void {
sessionErrorState.delete(sessionID)
sessionInterruptState.delete(sessionID)
sessionFirstMessageProcessed.delete(sessionID)
// sessionFirstMessageProcessed must NOT be cleared on idle.
// It tracks whether the first message of a session has been processed,
// so that SessionStart hooks fire only once per session. Clearing it
// on idle (which fires after every model response) makes isFirstMessage
// always return true, causing SessionStart hooks to fire on every
// prompt instead of only the first one.
}
export function clearAllSessionHookState(): void {