You can also write your own.
The SessionExporter protocol
SessionExporter (importable from agentegrity) is a typing.Protocol with three async methods:
on_session_startfires once, when the adapter emits its first event while at least one exporter is registered. It receives the adapter’s session id (32 hex characters), the adapter name (langchain,claude,openai_agentsand so on) and the agent profile as a JSON-ready dict.on_eventfires for every event the adapter emits, withFrameworkEvent.to_dict().on_session_endfires when the adapter is closed, with the session summary fromget_summary().
on_session_start, and events emitted before it was added are not replayed. The one exception is credential_declared: credentials declared while no exporter existed are delivered right after on_session_start.
on_session_end only fires when the session is closed. Call close() on the adapter, use it as an async with block, or call agentegrity.shutdown() if you started with agentegrity.init(). For the module-level adapters, close the default adapter with adapter().close(), for example agentegrity.langchain.adapter().close().
Fail-open delivery
An exporter cannot break the agent. The adapter wraps every callback: an exception raised while creating or awaiting the coroutine is caught and logged as a warning on theagentegrity.adapters logger, and the agent continues. When an event loop is running, each callback is scheduled with asyncio.ensure_future and not awaited, so callbacks can complete out of order; without a running loop, each one runs to completion with asyncio.run before the adapter continues. A slow exporter therefore blocks the agent only when there is no running loop. The built-in HTTP and alert exporters avoid this by handing work to a background thread.
Describing a sink
An exporter may also implementdescribe() -> dict[str, str]. This is a convention, outside the protocol, so older exporters keep working without it. Return at least a type key and, when the exporter streams to a nameable destination, a target. The result is copied into the session summary, so it must never contain credentials. Exporters without describe() are reported by class name.
Registering an exporter
- Python
- TypeScript
Every Python framework module exposes With Registration is idempotent: registering the same instance twice has no effect. Each registered exporter receives every callback.
register_exporter, which attaches the exporter to that module’s default adapter: agentegrity.claude, agentegrity.langchain, agentegrity.openai_agents, agentegrity.crewai, agentegrity.google_adk, agentegrity.autogen, agentegrity.agno and agentegrity.bedrock_agents. Adapter instances have the same method.agentegrity.init(), register on each adapter the runtime built:What each payload contains
data carries the full content the framework handed to the adapter. Anything you register receives prompts, tool arguments and tool outputs. Field-by-field definitions, every event type and JSON examples are in Events and wire format.
Checking which sinks are attached
The session summary lists every attached exporter underexporters. In Python, read it from report() on a framework module, runtime.report() after agentegrity.init(), or get_summary() on an adapter:
report() summary has no exporters field.
