Skip to main content
Once events are flowing in, the next question is: where do they go? There are two models:
  • Pull (ContextStore) — your support AI agent calls enrich() at query time to fetch relevant context on demand.
  • Push (AsyncAgentContextWriter) — actions are streamed to the agent destination as they arrive, and compressed with an LLM before the context window overflows.
This page covers the push model.

What you own vs what the SDK handles

The SDK is built around plain callables — no base classes, no interfaces to implement. You supply functions; the SDK handles the orchestration. Swap any of those callables — OpenAI for Anthropic, Pinecone for pgvector, Intercom for Slack — and everything else stays the same.

The context window problem

Every user session produces a stream of actions. Left unmanaged, that stream grows unboundedly — eventually overwhelming any agent’s context window. The push model solves this with a two-step pattern:
The destination always has context. Before the threshold is hit it has the latest raw actions; after, it has a compact LLM summary that replaced them. The window never grows unboundedly.

The overwrite requires an LLM step

overwrite_with_summary is not a simple in-memory swap. It is only called after AsyncSessionSummarizer has run your configured prompt through your LLM and produced a summary. The AsyncSessionSummarizer is required — without it there is no LLM call, no summary, and no overwrite.

Real-world example: Intercom

This is exactly how the event connector manages context in Intercom conversations.
  • write_actions_cb posts each batch as an internal admin note to the conversation and records the returned part_id.
  • When K actions accumulate, AsyncSessionSummarizer calls the LLM via circuit_breaker_llm.
  • overwrite_cb posts the summary note first, then redacts all old action notes in parallel.
The ordering is intentional — the summary must exist in the conversation before any notes are removed, so the support agent (and Intercom’s AI) always has complete context.

The ordering guarantee

Always post the summary before removing old context.overwrite_with_summary is awaited to completion before anything else happens. Implement it so the summary is confirmed at the destination first — only then should you delete or redact the previous raw actions.If deletion fails, the summary is still visible. The agent never loses context entirely.
This contract mirrors what session_summary_worker.py enforces internally: write_summary (post the new note) runs before pre_write_summary (redact the old notes). The comment in that file reads: “no context gap is ever possible.”

Generic support AI agent example

For a support AI agent where you control the context directly, the pattern is simpler — set_context just overwrites the previous value:

Constructor

AsyncAgentContextWriter(summarizer, overwrite_with_summary, write_actions=None)

AsyncSessionSummarizer
required
The summarizer that accumulates actions and triggers LLM summarisation. Its LLM, threshold, and prompt are configured on this object. The writer hooks into summarizer.on_summary automatically — do not set on_summary separately.
async (session_id: str, summary: str) -> None
required
Called after each LLM summarisation. Must post the summary to the destination before removing any previous context. If this callback raises, the overwrite is logged and skipped — the raw action context remains in place.
async (session_id: str, text: str) -> None | None
default:"None"
Called on every new actions batch with the batch formatted as plain text. Use this to keep the destination current between summarisations. Optional — omit if you only want summaries pushed.
int
default:"0"
Per-session trailing-edge accumulation window in milliseconds. When > 0, multiple add() calls arriving within the window are merged into one ActionsPayload before write_actions is called — reducing destination API calls when events arrive in bursts.Set to 0 (default) if your write_actions callback already coalesces internally, such as a BaseChatbotWriter subclass that applies its own post_link_debounce_s window. Stacking both adds latency with no further reduction in API calls.

Debounce window

When debounce_ms > 0, the writer buffers ActionsPayload objects per session and merges them using ActionsPayload.merge() once the window expires with no new arrivals. The merged payload carries the full combined action list, so AsyncSessionSummarizer threshold counting is unaffected — it sees every action regardless of how many were coalesced.
Avoid double-debouncing. If write_actions already coalesces internally — for example a BaseChatbotWriter subclass with post_link_debounce_s — keep debounce_ms=0. Stacking both windows only adds latency.

API reference


  • SessionSummarizer — configure the LLM, threshold, and prompt used for compression
  • ContextStore — the pull model; fetch enriched context at query time instead of pushing it