Skip to main content
This page describes the planned event-handler registration surface for aion-langgraph. The idea is to let developers register handler nodes for normalized messaging events without giving up ordinary LangGraph composition.

Overview

The intended helper shape looks like this:
from langgraph.graph import StateGraph

from aion.langgraph import AionContext, add_event_handlers


builder = StateGraph(State, context_schema=AionContext)

add_event_handlers(
    builder,
    on_message=handle_message,
    on_reaction=handle_reaction,
    on_command=handle_command,
    on_card_action=handle_card_action,
    on_event=handle_event,
)

graph = builder.compile()
Each registered handler should remain an ordinary LangGraph node. It can:
  • return state updates
  • write to the shared response buffer through fluent helpers
  • set a2a_outbox for full protocol-level control

Registrations

RegistrationCalled for
on_messageNormalized inbound message events
on_reactionNormalized reaction change events
on_commandNormalized command invocation events
on_card_actionNormalized card-action callback events
on_eventFallback when no more specific handler is registered

Dispatch Rules

The dispatch surface should be based on normalized event kinds, not on provider-specific trigger names. That means:
  • a Slack mention and a Telegram DM should both normalize to on_message
  • a slash command should normalize to on_command
  • a card button click should normalize to on_card_action
If an author needs provider-specific behavior, they should inspect runtime.context.event or runtime.context.inbox, not register provider-only handler names.

Example

async def handle_command(state: State, runtime: Runtime[AionContext]) -> dict:
    event = runtime.context.event
    await runtime.context.thread.reply(f"Running command: {event.command}")
    return {}


async def handle_event(state: State, runtime: Runtime[AionContext]) -> dict:
    await runtime.context.thread.reply("Unhandled event.")
    return {}

Why This Is Useful

This keeps the authoring model close to Vercel-style event registration while still preserving a generic transport model underneath:
  • the event registration stays fluent
  • the event payloads still normalize through Aion extensions
  • the actual execution surface is still just LangGraph nodes and edges