Home / Class/ ContextEditingMiddleware Class — langchain Architecture

ContextEditingMiddleware Class — langchain Architecture

Architecture documentation for the ContextEditingMiddleware class in context_editing.py from the langchain codebase.

Entity Profile

Dependency Diagram

graph TD
  670767f0_01ad_c9dd_6835_d1a9fb775005["ContextEditingMiddleware"]
  4055d589_37db_876d_2f46_94061df76932["context_editing.py"]
  670767f0_01ad_c9dd_6835_d1a9fb775005 -->|defined in| 4055d589_37db_876d_2f46_94061df76932
  01e32015_213d_50ed_0d7e_96a1cc300601["__init__()"]
  670767f0_01ad_c9dd_6835_d1a9fb775005 -->|method| 01e32015_213d_50ed_0d7e_96a1cc300601
  fe7b3bde_4a2b_18e3_bb12_39dc2996869d["wrap_model_call()"]
  670767f0_01ad_c9dd_6835_d1a9fb775005 -->|method| fe7b3bde_4a2b_18e3_bb12_39dc2996869d
  8ea33785_b55b_c969_ea50_490f985dd1bf["awrap_model_call()"]
  670767f0_01ad_c9dd_6835_d1a9fb775005 -->|method| 8ea33785_b55b_c969_ea50_490f985dd1bf

Relationship Graph

Source Code

libs/langchain_v1/langchain/agents/middleware/context_editing.py lines 187–292

class ContextEditingMiddleware(AgentMiddleware[AgentState[ResponseT], ContextT, ResponseT]):
    """Automatically prune tool results to manage context size.

    The middleware applies a sequence of edits when the total input token count exceeds
    configured thresholds.

    Currently the `ClearToolUsesEdit` strategy is supported, aligning with Anthropic's
    `clear_tool_uses_20250919` behavior [(read more)](https://platform.claude.com/docs/en/agents-and-tools/tool-use/memory-tool).
    """

    edits: list[ContextEdit]
    token_count_method: Literal["approximate", "model"]

    def __init__(
        self,
        *,
        edits: Iterable[ContextEdit] | None = None,
        token_count_method: Literal["approximate", "model"] = "approximate",  # noqa: S107
    ) -> None:
        """Initialize an instance of context editing middleware.

        Args:
            edits: Sequence of edit strategies to apply.

                Defaults to a single `ClearToolUsesEdit` mirroring Anthropic defaults.
            token_count_method: Whether to use approximate token counting
                (faster, less accurate) or exact counting implemented by the
                chat model (potentially slower, more accurate).
        """
        super().__init__()
        self.edits = list(edits or (ClearToolUsesEdit(),))
        self.token_count_method = token_count_method

    def wrap_model_call(
        self,
        request: ModelRequest[ContextT],
        handler: Callable[[ModelRequest[ContextT]], ModelResponse[ResponseT]],
    ) -> ModelResponse[ResponseT] | AIMessage:
        """Apply context edits before invoking the model via handler.

        Args:
            request: Model request to execute (includes state and runtime).
            handler: Async callback that executes the model request and returns
                `ModelResponse`.

        Returns:
            The result of invoking the handler with potentially edited messages.
        """
        if not request.messages:
            return handler(request)

        if self.token_count_method == "approximate":  # noqa: S105

            def count_tokens(messages: Sequence[BaseMessage]) -> int:
                return count_tokens_approximately(messages)

        else:
            system_msg = [request.system_message] if request.system_message else []

            def count_tokens(messages: Sequence[BaseMessage]) -> int:
                return request.model.get_num_tokens_from_messages(
                    system_msg + list(messages), request.tools
                )

        edited_messages = deepcopy(list(request.messages))
        for edit in self.edits:
            edit.apply(edited_messages, count_tokens=count_tokens)

        return handler(request.override(messages=edited_messages))

    async def awrap_model_call(
        self,
        request: ModelRequest[ContextT],
        handler: Callable[[ModelRequest[ContextT]], Awaitable[ModelResponse[ResponseT]]],
    ) -> ModelResponse[ResponseT] | AIMessage:
        """Apply context edits before invoking the model via handler.

        Args:
            request: Model request to execute (includes state and runtime).
            handler: Async callback that executes the model request and returns
                `ModelResponse`.

Frequently Asked Questions

What is the ContextEditingMiddleware class?
ContextEditingMiddleware is a class in the langchain codebase, defined in libs/langchain_v1/langchain/agents/middleware/context_editing.py.
Where is ContextEditingMiddleware defined?
ContextEditingMiddleware is defined in libs/langchain_v1/langchain/agents/middleware/context_editing.py at line 187.

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free