import type { AgentEvent, ThinkingLevel } from "@oh-my-pi/pi-agent-core"; import type { CompactionResult } from "@oh-my-pi/pi-agent-core/compaction"; import type { Effort } from "@oh-my-pi/pi-ai"; import type { Rule } from "../capability/rule.js"; import type { RetryErrorUpdate } from "../extensibility/shared-events.js"; import type { Goal } from "@oh-my-pi/pi-tui/tools/goal"; import type { GoalModeState } from "../goals/state.js"; import type { ConfiguredThinkingLevel } from "@oh-my-pi/pi-tui/thinking"; import type { TodoItem } from "@oh-my-pi/pi-tui/tools/todo"; import type { CustomMessage } from "./messages.js"; import type { CacheWarmingRefreshEnd, CacheWarmingRefreshStart } from "./cache-warmer.js"; /** Session-specific events that extend the core AgentEvent. */ export type AgentSessionEvent = Exclude | (Extract & { /** False when an async delivery will resume the session before its true final settle. */ isTerminal?: boolean; /** * True when the agent finished its turn: the end is terminal, or the session resumes * only for queued input or background-job results. False while the agent continues its * own work (retry, compaction continuation, stop-time reminders). */ yielded?: boolean; /** * True on a non-terminal end whose only possible resume is a background-job result * (no queued input, no continuation the agent scheduled itself). The wake is not * guaranteed: a cancelled or suppressed job never delivers one. */ awaitingAsyncWork?: boolean; }) | { type: "auto_compaction_start"; reason: "threshold" | "overflow" | "idle" | "incomplete"; action: "context-full" | "remote" | "handoff" | "shake" | "snapcompact"; } | { type: "auto_compaction_end"; action: "context-full" | "remote" | "handoff" | "shake" | "snapcompact"; result: CompactionResult | undefined; aborted: boolean; willRetry: boolean; errorMessage?: string; /** True when compaction was skipped for a benign reason. */ skipped?: boolean; } | { type: "manual_compaction_start"; /** The `/compact ` subcommand, when one was given. */ mode?: string; } | { type: "manual_compaction_end"; /** Present when the compaction committed. */ result?: CompactionResult; /** True when the compaction was cancelled (abort, or a `session_before_compact` hook). */ aborted: boolean; /** True when there was nothing to compact; `errorMessage` says why. */ skipped?: boolean; errorMessage?: string; } | { type: "auto_retry_start"; attempt: number; maxAttempts: number; delayMs: number; errorMessage: string; errorId?: number; } | { type: "auto_retry_end"; success: boolean; attempt: number; finalError?: string; retryErrors?: RetryErrorUpdate[]; } | ({ type: "cache_warming_start"; } & CacheWarmingRefreshStart) | ({ type: "cache_warming_end"; } & CacheWarmingRefreshEnd) | { type: "retry_fallback_applied"; from: string; to: string; role: string; reason?: string; } | { type: "retry_fallback_succeeded"; model: string; role: string; } | { type: "model_changed"; } | { type: "config_warnings_changed"; } | { type: "advisor_cost_changed"; } | { type: "advisor_yielded"; } | { type: "ttsr_triggered"; rules: Rule[]; } | { type: "todo_reminder"; todos: TodoItem[]; attempt: number; maxAttempts: number; } | { type: "todo_auto_clear"; } | { type: "irc_message"; message: CustomMessage; } | { type: "notice"; level: "info" | "warning" | "error"; message: string; source?: string; } | { type: "thinking_level_changed"; thinkingLevel: ThinkingLevel | undefined; /** The user-configured selector when it differs from the effective level. */ configured?: ConfiguredThinkingLevel; /** The level `auto` resolved to this turn, once classified. */ resolved?: Effort; } | { type: "goal_updated"; goal: Goal | null; state?: GoalModeState; } | { type: "queue_update"; steering: string[]; followUp: string[]; liveSteered: number; }; /** Listener function for agent session events. */ export type AgentSessionEventListener = (event: AgentSessionEvent) => void;