Skip to main content
An exporter is an object that receives a session’s data as the adapter produces it. Python adapters evaluate locally and keep the session in memory; registering an exporter, or setting the two streaming variables that register one for you, is what sends it anywhere. The library ships three kinds: You can also write your own.

The SessionExporter protocol

SessionExporter (importable from agentegrity) is a typing.Protocol with three async methods:
The adapter calls them at three points in a session:
  • on_session_start fires 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_agents and so on) and the agent profile as a JSON-ready dict.
  • on_event fires for every event the adapter emits, with FrameworkEvent.to_dict().
  • on_session_end fires when the adapter is closed, with the session summary from get_summary().
Register exporters before the agent runs. An exporter added after the session has started never receives 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 the agentegrity.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 implement describe() -> 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

Every Python framework module exposes 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.
With agentegrity.init(), register on each adapter the runtime built:
Registration is idempotent: registering the same instance twice has no effect. Each registered exporter receives every callback.

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 under exporters. In Python, read it from report() on a framework module, runtime.report() after agentegrity.init(), or get_summary() on an adapter:
An empty list means no exporter is attached to that adapter, so the session’s events went nowhere. Telemetry and opt-in model-backed layers are separate paths that this list does not cover; see What leaves your process. The TypeScript report() summary has no exporters field.