"""Attention:每个 agent 的事件收件箱与打断策略(docs/agent-runtime-v2.md §1.3)。

- 事件入箱;salience ≥ INTERRUPT_AT 时回调 on_interrupt(立即唤醒认知);
- 低显著度事件累积,等下一个思考点 drain() 一次性消化(一批一次 LLM,省钱);
- 同质低显著度事件去重压缩(同一个人反复走动只留最后一条)。
"""

from __future__ import annotations

from dataclasses import dataclass, field
from typing import Callable

from genesis.runtime.bus import Event

INTERRUPT_AT = 0.8


@dataclass
class Attention:
    agent_id: str
    on_interrupt: Callable[[Event], None] | None = None
    _inbox: list[Event] = field(default_factory=list)

    def receive(self, event: Event) -> None:
        # 同 actor 同类型的低显著度事件只留最新(脚步声不刷屏)
        if event.salience < 0.4:
            self._inbox = [e for e in self._inbox
                           if not (e.actor == event.actor and e.etype == event.etype and e.salience < 0.4)]
        self._inbox.append(event)
        if event.salience >= INTERRUPT_AT and self.on_interrupt is not None:
            self.on_interrupt(event)

    def drain(self) -> list[Event]:
        out, self._inbox = self._inbox, []
        return out

    def peek_urgent(self) -> Event | None:
        urgent = [e for e in self._inbox if e.salience >= INTERRUPT_AT]
        return urgent[-1] if urgent else None
