Skip to content

symfonic.agent.cutover.typed_interrupts

typed_interrupts

Translating a paused kernel run into the typed pause vocabulary (HK1).

ST1's typed_interrupt_translation drift row asked for one thing: structured typed behaviour must stay structured -- a paused graph reaches the consumer as an AskUserQuestionEvent or an InterruptEvent, never as the raw payload the runtime happened to carry it in. ST2 closed that row on the legacy body and recorded, honestly, that it could not close it on the kernel route: the kernel had no interrupt kind, so nothing arrived at that loop to translate. TA8.34 added the kinds; this module is the translation they made possible.

Next door to :mod:~symfonic.agent.cutover.typed_projection rather than inside it, for the line-budget reason typed_close_state and typed_route are: one module per shape, and this one owns exactly the two public events a pause becomes.

Translation, not interpretation -- and here that cuts the other way. The rest of the projection drops what the kernel did not report. A pause cannot be dropped: the run has already stopped, and a consumer that receives nothing holds a stream that simply ended, which is the very "inferred from an absence" shape this task exists to remove. So a pause that cannot be rendered honestly raises instead, naming the field that is missing and who fills it.

interrupt_events

interrupt_events(event: AgentEvent) -> tuple[StreamEvent, ...]

Project one paused kernel event onto the typed pause vocabulary.

Returns () for anything that is not a pause, so the caller can hand every event through without branching on the kind twice.

Source code in src/symfonic/agent/cutover/typed_interrupts.py
def interrupt_events(event: AgentEvent) -> tuple[StreamEvent, ...]:
    """Project one paused kernel event onto the typed pause vocabulary.

    Returns ``()`` for anything that is not a pause, so the caller can hand
    every event through without branching on the kind twice.
    """
    pending = event.interrupt
    if pending is None:
        return ()
    if event.kind == "ask_user":
        return (_ask_user(event, pending),)
    return (_generic(event, pending),)