LangGraph
Compress tool outputs, chat history, state-graph payloads, checkpoints, stores, and multi-agent handoffs with first-party Compresr components.
LangGraph 1.0+ shares the create_agent middleware mechanism with LangChain, so the three agent-level Compresr middlewares are re-exported from compresr.integrations.langgraph (Python) and @compresr/sdk/integrations/langgraph (TypeScript). The LangGraph package adds four LangGraph-native components on top: a state-graph node (make_compresr_node), a checkpoint serializer (CompresrCheckpointSerializer), a store wrapper (CompresrStore), and a multi-agent handoff tool (compresr_handoff_tool).
Both SDKs ship the full surface
The LangGraph integration is a peer of the LangChain one in both Python and TypeScript — same components, same defaults. Python uses snake_case classes; TypeScript uses camelCase factory functions for middleware and new-able classes for the other components.
1. Install
2. Agent-level middleware (re-exported)
The exact same CompresrToolMiddleware, CompresrSummarizationMiddleware, and CompresrPromptMiddleware covered on the LangChain page work inside LangGraph's create_agent. They are re-exported here for discovery:
See the LangChain doc for the full middleware reference — every keyword argument is identical.
3. Compress a state field inside a custom StateGraph
For graphs you build with StateGraph directly (not the pre-built ReAct shape), use make_compresr_node. It returns a callable node that reads state[context_key], compresses it, and writes the shortened text back into the same field.
Options
| Python | TypeScript | Required? | Notes |
|---|---|---|---|
context_key | contextKey | Yes | Name of the state field to compress. |
query_key | queryKey | Recommended | Field whose value is used as the query — latte_v1 is query-aware. |
query | query | — | Static query overriding extractor and query_key. |
query_extractor | queryExtractor | — | (state) -> Optional[str] — custom extraction. |
target_compression_ratio | targetCompressionRatio | — | Default 0.5. |
min_tokens | minTokens | — | Default 200. Skip if field shorter than this. |
coarse | coarse | — | Paragraph vs token level; server default. |
compression_model | compressionModel | — | Default "latte_v1". |
on_error | onError | — | "passthrough" (default) or "raise". |
api_key / base_url / client | apiKey / baseUrl / client | — | Standard auth knobs. |
The node returns {context_key: new_text} when it actually changed the field and {} otherwise, so it composes cleanly with LangGraph's diff-merging state updates.
Python also exports compresr_node as an alias for make_compresr_node; TypeScript exports compresrNode.
4. Compress checkpoints — CompresrCheckpointSerializer
Long agent state can balloon at-rest storage: Postgres rewrites the whole TOAST row on every checkpoint, Redis pays for every byte. CompresrCheckpointSerializer is a JsonPlusSerializer subclass that walks the state on dumps_typed, finds long strings, and rewrites them as {"__compresr__": true, "v": "<compressed>"} sentinels before encoding.
Lossy by design
This serializer is one-way — there is no decompression on loads_typed. Anything you compress at write time is what subsequent reads see. Use the fields allowlist in production to compress only the keys that carry bulk data (retrieved notes, scratchpads), not control state.
Default min_tokens is 500 for the serializer (vs 200 for middleware) — at-rest cost only matters above a certain payload size.
5. Compress at-rest store entries — CompresrStore
CompresrStore wraps any BaseStore (in-memory, Postgres, Redis, ...) and compresses long string fields on the write side. Reads pass through untouched, so anything you write through the wrapper is what subsequent get / search calls see. Same lossy contract as the checkpoint serializer.
The wrapper exposes the full BaseStore surface: put, get, delete, search, list_namespaces, batch, plus async siblings (aput, aget, ...). Only writes are mutated; reads, deletes, searches, and namespace listings delegate straight to the inner store.
6. Compress payloads passed between agents — compresr_handoff_tool
In a supervisor / sub-agent architecture, the supervisor often passes a large context blob (retrieved docs, prior conversation) to a sub-agent via a handoff tool. compresr_handoff_tool returns a LangChain BaseTool that compresses task_description and context before emitting Command(goto=agent_name, graph=Command.PARENT).
The tool name is auto-generated as f"transfer_to_{agent_name}". Both task_description and context are compressed with synthesised queries ("task for {agent_name}" and the task description itself), so latte_v1 always has a meaningful query.
When this helps
- ReAct agents with verbose tools —
CompresrToolMiddlewarecompresses each tool result before the next reasoning step. - Long-running graphs —
CompresrSummarizationMiddlewarekeeps the prompt bounded;CompresrPromptMiddlewarecaps the outbound budget regardless. - Multi-step workflows with bulky intermediate state —
make_compresr_nodecompresses a single field between two graph nodes. - Postgres / Redis-backed agents —
CompresrCheckpointSerializerandCompresrStorecut at-rest storage cost on the write path. - Supervisor → sub-agent topologies —
compresr_handoff_toolkeeps the payload tight when control transfers.