# langchain-ai/langchain — codebase unpack

> Canonical page: https://codevetter.com/unpack/langchain

This is a deterministic Repo Unpack scan of langchain-ai/langchain — a structural map, not a review, security audit, or maintainer-endorsed description.

- Scanned commit: 9e4ea7a3495992c02a79de6fa5788e028b03df11 (2026-09-22)
- Last upstream commit: fix(fireworks): use current completions model in LLM tests (#40740)
- Generated by codevetter 1.12.0 on 2026-09-22
- 3001 files scanned · 16.1 MB

## Languages

- Python: 2610 files
- JSON: 71 files
- Markdown: 56 files
- YAML: 48 files
- TOML: 30 files
- Shell: 22 files
- HTML: 2 files
- JavaScript: 2 files

## Repository structure

- libs/ — 2888 files
- openwiki/ — 50 files
- .github/ — 48 files
- .devcontainer/ — 3 files

Probable source entrypoint: `libs/` (inferred from the tree, not upstream docs)

## Source layout — libs/

- libs/core/ — 303 files
- libs/text-splitters/ — 32 files

## Package

- libs/core/pyproject.toml: langchain-core v1.6.4 — 0 declared dependencies

## Structural health signals

Average score 6.1/10 across 96 files; 81 hotspots. These are deterministic review leads, not proof of a bug.

## Recent history

- 9e4ea7a34959 (2026-09-22) fix(fireworks): use current completions model in LLM tests (#40740)
- 219b372051b6 (2026-09-22) fix(deepseek,infra): resolve compatible minimum OpenAI dependencies, bump min ver (#40738)
- b976c82c587a (2026-09-22) hotfix(fireworks): use available model in LLM tests (#40737)
- e2eab823c728 (2026-09-22) release(deepseek): 1.1.1 (#40734)
- 0683934fb211 (2026-09-22) release(fireworks): 1.6.2 (#40735)

## Overview

LangChain is a Python monorepo for building LLM-powered agents and applications. The actively maintained `langchain` package (libs/langchain_v1) is a thin orchestration layer over LangGraph: `create_agent()` compiles a tool-calling agent loop into a `CompiledStateGraph`, `init_chat_model()` lazily instantiates provider chat models from a registry, and a middleware system lets users hook every stage of the agent loop. `langchain-core` owns the stable abstractions (Runnable, BaseChatModel, BaseTool, messages, callbacks), `libs/partners/` holds ~17 independently released provider integrations, and `langchain-classic` preserves the legacy chains/agents API without new features.

## System map

A uv-managed Python monorepo of independently versioned packages under libs/. langchain-core defines provider-agnostic abstractions; langchain (langchain_v1) is the user-facing orchestration layer built on LangGraph's StateGraph; langchain-classic is a frozen legacy package; libs/partners/ contains per-provider integrations released individually. There is no server or CLI entrypoint — the 'entrypoints' are library factories (create_agent, init_chat_model, init_embeddings) plus the langchain-profiles CLI. Build is hatchling, tests are pytest, and CI is a set of reusable GitHub Actions workflows.
- The repo is a monorepo of independently versioned packages: langchain-core v1.6.4 (libs/core), langchain v1.4.2 (libs/langchain_v1), langchain-classic v1.0.8 (libs/langchain), plus text-splitters, standard-tests (langchain-tests), and model-profiles. — [libs/core/pyproject.toml#L6-24](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/core/pyproject.toml#L6-L24) [libs/langchain_v1/pyproject.toml#L6-24](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/pyproject.toml#L6-L24) [libs/langchain/pyproject.toml](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain/pyproject.toml)
- The actively maintained `langchain` package depends only on langchain-core>=1.6.3, langgraph>=1.2.11, and pydantic>=2.7.4; all provider integrations (openai, anthropic, mcp/fastmcp, etc.) are optional extras. — [libs/langchain_v1/pyproject.toml#L26-51](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/pyproject.toml#L26-L51)
- langchain-core is the abstraction layer housing runnables, language_models, messages, tools, callbacks, vectorstores, output_parsers, prompts, tracers, and a _security subpackage; its own deps are langsmith, httpx, tenacity, pydantic, jsonpatch, PyYAML. — [libs/core/pyproject.toml#L26-37](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/core/pyproject.toml#L26-L37) [openwiki/architecture.md#L87-107](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/openwiki/architecture.md#L87-L107)
- The primary public entrypoint is `create_agent`, re-exported from `langchain.agents`, which builds and compiles a LangGraph `StateGraph` into a `CompiledStateGraph`. — [libs/langchain_v1/langchain/agents/__init__.py#L3-9](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/__init__.py#L3-L9) [libs/langchain_v1/langchain/agents/factory.py#L840-860](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/factory.py#L840-L860)
- `init_chat_model` resolves provider strings like 'openai:gpt-5.5' through the `_BUILTIN_PROVIDERS` registry (~28 entries mapping provider key -> (module_path, class_name, creator_func)) and lazily imports the partner package. — [libs/langchain_v1/langchain/chat_models/base.py#L56-97](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/chat_models/base.py#L56-L97) [libs/langchain_v1/langchain/chat_models/base.py#L150-191](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/chat_models/base.py#L150-L191)
- Provider integrations live in libs/partners/ (anthropic, chroma, deepseek, exa, fireworks, groq, huggingface, mistralai, nomic, ollama, openai, openrouter, perplexity, qdrant, xai) each with its own pyproject.toml and uv.lock, and each implementing langchain-core abstractions (e.g. ChatOpenAI in langchain_openai/chat_models/base.py). — [libs/partners/openai/langchain_openai/chat_models/base.py#L2836](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/partners/openai/langchain_openai/chat_models/base.py#L2836) [libs/langchain_v1/pyproject.toml#L100-105](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/pyproject.toml#L100-L105)
- langchain-classic is the legacy package: `initialize_agent` is decorated @deprecated since 0.1.0 pointing users to `create_agent`, and its chains/agents tree (AgentExecutor, chains/*) is maintained for backward compatibility only. — [libs/langchain/langchain_classic/agents/initialize.py#L19-47](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain/langchain_classic/agents/initialize.py#L19-L47) [libs/langchain/langchain_classic/agents/agent.py#L1012](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain/langchain_classic/agents/agent.py#L1012) [libs/langchain/pyproject.toml](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain/pyproject.toml)
- All packages build with hatchling and are developed via uv; local cross-package deps use editable `[tool.uv.sources]` path references (e.g. langchain-core -> ../core). — [libs/langchain_v1/pyproject.toml#L1-3](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/pyproject.toml#L1-L3) [libs/langchain_v1/pyproject.toml#L100-105](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/pyproject.toml#L100-L105) [libs/Makefile](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/Makefile)
- Per-package Makefiles define the dev surface: `make test` (pytest with docker compose postgres+redis services), `make lint` (ruff check + ruff format --diff + mypy), `make format`, `make benchmark`. — [libs/langchain_v1/Makefile#L10-50](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/Makefile#L10-L50) [libs/langchain_v1/Makefile#L95-105](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/Makefile#L95-L105)
- CI is organized as reusable workflows: `_test.yml` runs unit tests then re-runs them against computed minimum dependency versions via `.github/scripts/get_min_versions.py`. — [.github/workflows/_test.yml#L46-73](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/.github/workflows/_test.yml#L46-L73)
- Releases are per-package and manually dispatched through `_release.yml` (workflow_call/workflow_dispatch), which resolves a working-directory dropdown value to a PyPI package name (langchain->langchain-classic, langchain_v1->langchain). — [.github/workflows/_release.yml#L1-35](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/.github/workflows/_release.yml#L1-L35) [AGENTS.md](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/AGENTS.md)
- The `langchain.mcp` namespace is beta-gated (importing it emits LangChainBetaWarning) and adapts MCP servers via the optional `fastmcp` extra. — [libs/langchain_v1/langchain/mcp/__init__.py#L7-32](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/mcp/__init__.py#L7-L32) [libs/langchain_v1/pyproject.toml#L51](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/pyproject.toml#L51)
- openwiki/ contains generated architecture documentation (e.g. architecture.md) that mirrors the three-layer design and is refreshed by the openwiki-update workflow. (inferred) — [openwiki/architecture.md#L37-41](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/openwiki/architecture.md#L37-L41)

## Feature catalog

User-facing surface: agent construction (create_agent with middleware, structured output, persistence, interrupts), model/embeddings factories (init_chat_model, init_embeddings), tool authoring (@tool, BaseTool, ToolRuntime injection), a large built-in middleware catalog (HITL, summarization, PII, retries, limits, shell tool, file search, todo lists, tool selection/emulation), MCP server tool adaptation, and message/rate-limiter re-exports. langchain-classic preserves the legacy chains/agents API. langchain-tests ships a conformance suite for partner authors; langchain-profiles ships a CLI for model capability data.
- `create_agent(model, tools, system_prompt, middleware, response_format, state_schema, context_schema, checkpointer, store, interrupt_before, interrupt_after, debug, name, cache, transformers)` returns a `CompiledStateGraph` implementing the model->tools loop until no tool_calls remain. — [libs/langchain_v1/langchain/agents/factory.py#L840-992](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/factory.py#L840-L992)
- `init_chat_model` supports string specs ('provider:model'), explicit model_provider, configurable_fields producing a deferred `_ConfigurableModel`, and a special 'langsmith' provider that routes ChatOpenAI through the LangSmith gateway (LANGSMITH_GATEWAY_API_KEY / gateway.smith.langchain.com). — [libs/langchain_v1/langchain/chat_models/base.py#L24-38](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/chat_models/base.py#L24-L38) [libs/langchain_v1/langchain/chat_models/base.py#L657](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/chat_models/base.py#L657)
- `init_embeddings` provides the same lazy provider-registry pattern for ~10 embeddings providers (azure_openai, bedrock, cohere, google_genai, huggingface, mistralai, ollama, openai, ...). — [libs/langchain_v1/langchain/embeddings/base.py#L15-34](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/embeddings/base.py#L15-L34) [libs/langchain_v1/langchain/embeddings/base.py#L57-93](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/embeddings/base.py#L57-L93)
- Tools are authored via the `@tool` decorator (langchain_core.tools.convert) or BaseTool subclasses; langchain.tools re-exports these plus ToolRuntime, InjectedState, and InjectedStore for runtime/state injection into tool functions. — [libs/langchain_v1/langchain/tools/__init__.py](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/tools/__init__.py) [libs/core/langchain_core/tools/convert.py#L18](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/core/langchain_core/tools/convert.py#L18)
- The built-in middleware catalog includes: SummarizationMiddleware, HumanInTheLoopMiddleware, PIIMiddleware, TodoListMiddleware, ModelRetryMiddleware, ModelFallbackMiddleware, ModelCallLimitMiddleware, ToolRetryMiddleware, ToolCallLimitMiddleware, ToolErrorMiddleware, LLMToolSelectorMiddleware, LLMToolEmulator, ContextEditingMiddleware, FilesystemFileSearchMiddleware, ProviderToolSearchMiddleware, and ShellToolMiddleware. — [libs/langchain_v1/langchain/agents/middleware/__init__.py#L6-30](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/middleware/__init__.py#L6-L30)
- Structured output is configured via `response_format` accepting a raw Pydantic/dataclass/TypedDict/JSON-schema or explicit ToolStrategy/ProviderStrategy/AutoStrategy; AutoStrategy picks provider-native output when `_supports_provider_strategy` says the model supports it. — [libs/langchain_v1/langchain/agents/structured_output.py#L29-33](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/structured_output.py#L29-L33) [libs/langchain_v1/langchain/agents/factory.py#L1347-1367](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/factory.py#L1347-L1367)
- HumanInTheLoopMiddleware pauses tool calls via langgraph `interrupt()` with ReviewConfig policies allowing approve/edit/reject/respond decisions, and annotates edited calls with an `_EDIT_NOTICE` so the model knows the call was replaced. — [libs/langchain_v1/langchain/agents/middleware/human_in_the_loop.py#L31-78](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/middleware/human_in_the_loop.py#L31-L78)
- ShellToolMiddleware exposes a persistent `shell` tool executing commands under pluggable policies: HostExecutionPolicy (direct subprocess), DockerExecutionPolicy, and CodexSandboxExecutionPolicy, with output redaction via RedactionRule. — [libs/langchain_v1/langchain/agents/middleware/shell_tool.py#L59-120](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/middleware/shell_tool.py#L59-L120) [libs/langchain_v1/langchain/agents/middleware/_execution.py#L92-323](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/middleware/_execution.py#L92-L323)
- PIIMiddleware detects emails/credit cards/IPs/MACs/URLs via `_redaction` helpers and can mutate streaming deltas in flight through `_PIIStreamTransformer` (a 128-char lookback buffer catches patterns straddling token boundaries). — [libs/langchain_v1/langchain/agents/middleware/pii.py#L12-66](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/middleware/pii.py#L12-L66)
- `MCPAdapter` converts FastMCP targets (URL, Path, transport, MCPConfig, in-process server, client/group) into LangChain tools via `list_tools()`, and arms clients so server elicitation requests become LangGraph interrupts answered by humans. — [libs/langchain_v1/langchain/mcp/adapter.py#L125-242](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/mcp/adapter.py#L125-L242) [libs/langchain_v1/langchain/mcp/elicitation.py](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/mcp/elicitation.py)
- langchain.messages re-exports the canonical message model (AIMessage, ToolMessage, HumanMessage, SystemMessage, content-block types, ToolCall, trim_messages) from langchain-core. — [libs/langchain_v1/langchain/messages/__init__.py](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/messages/__init__.py)
- BaseRateLimiter/InMemoryRateLimiter are re-exported from langchain.rate_limiters and are honored by BaseChatModel._generate_with_cache which acquires the limiter before hitting the provider API (but after cache lookup). — [libs/langchain_v1/langchain/rate_limiters/__init__.py](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/rate_limiters/__init__.py) [libs/core/langchain_core/language_models/chat_models.py#L1931-1935](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/core/langchain_core/language_models/chat_models.py#L1931-L1935)
- langchain-tests (standard-tests) ships reusable conformance suites — unit_tests/chat_models.py, embeddings.py, tools.py and integration_tests/{chat_models,vectorstores,retrievers,indexer,cache,sandboxes}.py — that partner packages subclass to prove compliance. — [libs/standard-tests/langchain_tests/unit_tests](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/standard-tests/langchain_tests/unit_tests) [libs/standard-tests/langchain_tests/integration_tests](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/standard-tests/langchain_tests/integration_tests)
- langchain-model-profiles ships a `langchain-profiles` CLI that generates per-model capability profile data consumed by partners' data/ dirs. — [libs/model-profiles/langchain_model_profiles/cli.py](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/model-profiles/langchain_model_profiles/cli.py) [AGENTS.md](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/AGENTS.md)
- langchain-classic retains the legacy feature surface: AgentExecutor, agent types (react, conversational, structured_chat, tool_calling_agent, openai_functions_*), and the full chains/ tree (retrieval, combine_documents, graph_qa, etc.). — [libs/langchain/langchain_classic/agents/agent.py#L1012](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain/langchain_classic/agents/agent.py#L1012) [libs/langchain/langchain_classic/agents/types.py](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain/langchain_classic/agents/types.py)

## Data flow

Agents are LangGraph state machines: input is a messages list merged into a resolved state schema (middleware schemas + AgentState, base last so caller schema wins conflicts). Each loop iteration builds a ModelRequest carried through the wrap_model_call middleware stack to a bound model; the AIMessage is post-processed for structured output and packed into Command state updates. Tool calls route to ToolNode, whose ToolMessages append via the add_messages reducer. Tool calls go through a wrap_tool_call stack. Streaming is reshaped by TransformerFactory instances registered at compile time. Outside agents, init_chat_model resolves provider strings to lazily imported classes, and BaseChatModel.invoke routes through callbacks, an LLM cache, and a rate limiter before _generate/_stream.
- Agent input boundary is `{"messages": [...]}`: `_resolve_schemas` merges each middleware's `state_schema` (in registration order) with the base schema last, producing resolved_state_schema, input_schema, output_schema for the StateGraph. — [libs/langchain_v1/langchain/agents/factory.py#L1174-1192](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/factory.py#L1174-L1192)
- ModelRequest is the data unit flowing through wrap_model_call middleware: it carries model, messages (excluding system message), system_message, tool_choice, tools, response_format, state, runtime, and model_settings, with an `override()` API (direct attribute assignment is deprecated). — [libs/langchain_v1/langchain/agents/middleware/types.py#L87-200](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/middleware/types.py#L87-L200)
- The model node builds a ModelRequest, runs it through the composed `wrap_model_call_handler` (or calls `_execute_model` directly), then `_build_commands` converts the ModelResponse into Command objects updating `messages` and `structured_response` state. — [libs/langchain_v1/langchain/agents/factory.py#L1519-1540](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/factory.py#L1519-L1540) [libs/langchain_v1/langchain/agents/factory.py#L213-250](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/factory.py#L213-L250)
- `_get_bound_model` validates middleware-added client-side tools against `tool_node.tools_by_name` (skipped when wrap_tool_call middleware can handle dynamic tools), normalizes raw schemas to AutoStrategy, and picks ProviderStrategy vs ToolStrategy by model capability. — [libs/langchain_v1/langchain/agents/factory.py#L1298-1369](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/factory.py#L1298-L1369)
- Structured output is marshaled inside `_handle_model_output`: ProviderStrategy parses the AIMessage via `ProviderStrategyBinding.parse`, ToolStrategy intercepts tool_calls matching `structured_output_tools` names and validates args into `structured_response` state. — [libs/langchain_v1/langchain/agents/factory.py#L1194-1296](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/factory.py#L1194-L1296) [libs/langchain_v1/langchain/agents/structured_output.py](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/structured_output.py)
- Tool execution reuses LangGraph's ToolNode — langchain's tools/tool_node.py is a backwards-compat shim re-exporting ToolNode, ToolCallRequest, ToolCallWrapper, InjectedState, InjectedStore, ToolRuntime from langgraph.prebuilt. — [libs/langchain_v1/langchain/tools/tool_node.py](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/tools/tool_node.py)
- Conversation history accumulates in the `messages` channel via langgraph's `add_messages` reducer imported in middleware types; agent state also carries ephemeral routing via JumpTo ('tools'|'model'|'end'). — [libs/langchain_v1/langchain/agents/middleware/types.py#L27-68](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/middleware/types.py#L27-L68)
- Stream output is post-processed by transformers registered at compile: ToolCallTransformer and SubagentTransformer always run first, then per-middleware `transformers` (e.g. InternalCallTransformer for SummarizationMiddleware's internal calls), then user-supplied factories, deduped. — [libs/langchain_v1/langchain/agents/factory.py#L1836-1857](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/factory.py#L1836-L1857) [libs/langchain_v1/langchain/agents/_subagent_transformer.py](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/_subagent_transformer.py)
- Tracing flows through LangSmith: middleware wrap hooks are wrapped in `traceable` with `_scrub_inputs` stripping unserializable handler/runtime, per-middleware TracePolicy via `_node_trace_policy`, and the compiled graph gets metadata `ls_integration: langchain_create_agent`. — [libs/langchain_v1/langchain/agents/factory.py#L146-171](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/factory.py#L146-L171) [libs/langchain_v1/langchain/agents/factory.py#L1829-1835](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/factory.py#L1829-L1835)
- init_chat_model data flow: provider key lookup in `_BUILTIN_PROVIDERS` -> `_import_module` (importlib with 'pip install <pkg>' hint on failure) -> getattr class -> functools.partial creator; provider inference from model name uses the registry keys. — [libs/langchain_v1/langchain/chat_models/base.py#L123-191](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/chat_models/base.py#L123-L191)
- BaseChatModel.invoke pipelines through callback_manager.on_chat_model_start -> `_generate_with_cache` (llm cache lookup via `dumps(messages)` key, then rate_limiter.acquire) -> either protocol v2 streaming, implicit `_stream` chunk accumulation with on_llm_new_token, or `_generate` -> on_llm_end with LLMResult. — [libs/core/langchain_core/language_models/chat_models.py#L1892-2011](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/core/langchain_core/language_models/chat_models.py#L1892-L2011)
- BaseTool.run wraps execution in on_tool_start/on_tool_end callbacks and converts ToolException into tool output content per the tool's `handle_tool_error` flag (bool, str template, or callable) via `_handle_tool_error`. — [libs/core/langchain_core/tools/base.py#L1009-1145](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/core/langchain_core/tools/base.py#L1009-L1145) [libs/core/langchain_core/tools/base.py#L1313-1345](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/core/langchain_core/tools/base.py#L1313-L1345)
- MCP tool data flow: MCPAdapter builds a FastMCPClient (str targets restricted to http/https), `list_tools` calls client.list_tools(cache_mode) then `as_langchain_tool` per remote tool; elicitation requests surface as langgraph interrupts. — [libs/langchain_v1/langchain/mcp/adapter.py#L221-242](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/mcp/adapter.py#L221-L242) [libs/langchain_v1/langchain/mcp/tools.py](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/mcp/tools.py)

## Behavior traces

Key flows traced end-to-end: (1) model initialization via init_chat_model; (2) agent construction via create_agent — middleware classification, schema merge, node/edge wiring, compile; (3) the agent loop — before_agent/before_model hooks, model call through the wrap_model_call stack, tool dispatch, loop-back or exit through after_model/after_agent; (4) single chat-model invocation through cache/rate-limiter/streaming; (5) MCP tool adoption; (6) CI test and release flows.
- Import/startup: `import langchain` sets only __version__; `from langchain.agents import create_agent` pulls factory.py which imports langgraph (StateGraph, ToolNode, Command, Send), langsmith.traceable, and init_chat_model; `import langchain.mcp` emits a LangChainBetaWarning. — [libs/langchain_v1/langchain/__init__.py](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/__init__.py) [libs/langchain_v1/langchain/agents/factory.py#L21-64](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/factory.py#L21-L64) [libs/langchain_v1/langchain/mcp/__init__.py#L28-33](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/mcp/__init__.py#L28-L33)
- init_chat_model('openai:gpt-5.5'): parse provider prefix -> `_get_chat_model_creator` (lru_cached) -> `_import_module('langchain_openai')` -> getattr ChatOpenAI -> functools.partial(_call, cls) -> cls(**kwargs); ollama falls back to langchain_community.chat_models for backwards compat. — [libs/langchain_v1/langchain/chat_models/base.py#L150-191](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/chat_models/base.py#L150-L191)
- create_agent construction order: str model -> init_chat_model; system_prompt -> SystemMessage; middleware partitioned by which hooks each subclass overrides (before_agent/before_model/after_model/after_agent/wrap_model_call/wrap_tool_call); sync and async wrap handlers composed via `_chain_model_call_handlers`/`_chain_async_model_call_handlers`. — [libs/langchain_v1/langchain/agents/factory.py#L994-999](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/factory.py#L994-L999) [libs/langchain_v1/langchain/agents/factory.py#L1150-1172](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/factory.py#L1150-L1172)
- Graph wiring: nodes added — 'model' (RunnableCallable(model_node, amodel_node)), 'tools' (ToolNode, only if tools exist), and '<middleware_name>.<hook>' RunnableCallables; START->entry_node; conditional edges route tools->loop_entry|exit and model->tools|exit|loop_entry; middleware chains wired via `_add_middleware_edge` with can_jump_to. — [libs/langchain_v1/langchain/agents/factory.py#L1543-1733](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/factory.py#L1543-L1733)
- Compile step: graph.compile(checkpointer, store, interrupt_before, interrupt_after, debug, name, cache, transformers=[ToolCallTransformer, SubagentTransformer, middleware+user transformers]) then `.with_config({recursion_limit: 9999, metadata: {ls_integration: langchain_create_agent}})`. — [libs/langchain_v1/langchain/agents/factory.py#L1829-1857](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/factory.py#L1829-L1857)
- Runtime loop order on agent.invoke: START -> first before_agent middleware -> before_model chain -> 'model' -> after_model chain (reverse order) -> conditional edge: tool_calls present -> 'tools' -> back to loop_entry_node (first before_model or 'model'); no tool_calls -> exit_node -> after_agent chain -> END. — [libs/langchain_v1/langchain/agents/factory.py#L1647-1733](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/factory.py#L1647-L1733) [openwiki/architecture.md#L214-243](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/openwiki/architecture.md#L214-L243)
- Inside the model node (sync path mirrored by amodel_node): ModelRequest assembled -> awrap_model_call_handler(request, _execute_model_async) -> _get_bound_model binds tools and resolves response format -> model.ainvoke(messages) -> _handle_model_output -> ModelResponse -> _build_commands (rejecting Command.goto from wrap_model_call with NotImplementedError). — [libs/langchain_v1/langchain/agents/factory.py#L1498-1540](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/factory.py#L1498-L1540) [libs/langchain_v1/langchain/agents/factory.py#L244-250](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/factory.py#L244-L250)
- Structured-output error recovery: StructuredOutputValidationError or MultipleStructuredOutputsError goes through `_handle_structured_output_error`; if retryable, an error ToolMessage (STRUCTURED_OUTPUT_ERROR_TEMPLATE 'Please fix your mistakes.') is appended and the loop continues. — [libs/langchain_v1/langchain/agents/factory.py#L117-117](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/factory.py#L117-L117) [libs/langchain_v1/langchain/agents/factory.py#L1232-1294](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/factory.py#L1232-L1294)
- Single chat-model call: BaseChatModel.invoke -> generate -> callback_manager.on_chat_model_start -> _generate_with_cache -> cache.lookup(prompt, llm_string) short-circuits on hit -> rate_limiter.acquire -> protocol-v2 streaming / implicit _stream (on_llm_new_token per chunk) / _generate -> run_manager.on_llm_end(LLMResult). — [libs/core/langchain_core/language_models/chat_models.py#L475](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/core/langchain_core/language_models/chat_models.py#L475) [libs/core/langchain_core/language_models/chat_models.py#L1892-2011](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/core/langchain_core/language_models/chat_models.py#L1892-L2011)
- Tool invocation inside ToolNode delegates to BaseTool.run: callback_manager.on_tool_start -> _run -> on ToolException, `_handle_tool_error` renders handled content per handle_tool_error -> on_tool_end(output). — [libs/core/langchain_core/tools/base.py#L1009-1137](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/core/langchain_core/tools/base.py#L1009-L1137)
- MCP adoption flow: MCPAdapter(target) -> str targets pass `_validate_url_target` -> FastMCPClient(target) -> `_arm_for_interrupts` (clones pre-built clients that lack an elicitation handler) -> `async with adapter` connects -> list_tools -> as_langchain_tool -> tools passed to create_agent. — [libs/langchain_v1/langchain/mcp/adapter.py#L174-242](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/mcp/adapter.py#L174-L242)
- CI unit-test flow: _test.yml -> uv_setup action -> `uv sync --group test --dev` -> `make test` (docker compose postgres+redis up, pytest -n auto --disable-socket --allow-unix-socket) -> get_min_versions.py -> `uv pip install $MIN_VERSIONS` -> `make tests` again -> git-clean check. — [.github/workflows/_test.yml#L46-85](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/.github/workflows/_test.yml#L46-L85) [libs/langchain_v1/Makefile#L40-44](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/Makefile#L40-L44)
- Release flow per AGENTS.md: bump `_version.py` + pyproject version + `uv lock`, merge `release(<partner>): <version>` PR, then `gh workflow run` on _release.yml — build -> release-notes -> pre-release-checks -> TestPyPI -> PyPI -> GitHub release/tag via ncipollo/release-action. — [AGENTS.md](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/AGENTS.md) [.github/workflows/_release.yml#L1-35](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/.github/workflows/_release.yml#L1-L35)

## Testing signals

pytest is the framework everywhere, configured per-package with strict markers/config, asyncio auto mode, syrupy snapshots, and pytest-socket to forbid network in unit tests. langchain_v1 has ~85 unit-test files (heavy agents/middleware coverage, plus chat_models, embeddings, mcp, tools), integration tests with VCR cassettes, and a benchmark suite for create_agent. CI runs tests twice — current and minimum dependency versions — and scheduled integration tests trace to LangSmith. langchain-tests packages the conformance suite partners must pass. Gaps: unit tests need docker postgres/redis for checkpointer paths, and langchain-classic's huge legacy surface relies on older coverage.
- pytest config: `--strict-markers --strict-config --durations=5 --snapshot-warn-unused -vv`, asyncio_mode=auto, custom markers (requires, scheduled, compile, benchmark), syrupy snapshots under tests/**/__snapshots__. — [libs/langchain_v1/pyproject.toml#L179-192](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/pyproject.toml#L179-L192)
- Unit tests live in tests/unit_tests mirroring source layout; langchain_v1's agents suite includes test_react_agent.py, test_response_format*.py, test_return_direct*.py, test_subagent_*.py, middleware/ and middleware_typing/ dirs, plus specifications/ and cassettes/ for VCR replay. — [libs/langchain_v1/tests/unit_tests/agents](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/tests/unit_tests/agents) [libs/langchain_v1/tests/cassettes](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/tests/cassettes)
- Network isolation is enforced: `make test` runs pytest with `--disable-socket --allow-unix-socket` (pytest-socket), and unit tests must not hit the network per AGENTS.md. — [libs/langchain_v1/Makefile#L40-47](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/Makefile#L40-L47) [libs/langchain_v1/pyproject.toml#L69](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/pyproject.toml#L69)
- Persistence tests are not hermetic: `make test`/`extended_tests`/`test_watch` spin up postgres and redis via `tests/unit_tests/agents/compose-postgres.yml` and `compose-redis.yml` before running, then tear them down. — [libs/langchain_v1/Makefile#L10-14](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/Makefile#L10-L14) [libs/langchain_v1/tests/unit_tests/agents/compose-postgres.yml](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/tests/unit_tests/agents/compose-postgres.yml)
- Async correctness is checked with blockbuster (blocking-call detection) in the test group; freezegun and responses are used in core tests. — [libs/langchain_v1/pyproject.toml#L64-79](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/pyproject.toml#L64-L79) [libs/core/pyproject.toml#L62-79](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/core/pyproject.toml#L62-L79)
- Benchmarks exist for agent creation: `make benchmark` runs tests/benchmarks/test_create_agent.py with -m benchmark; a codspeed workflow exists for perf tracking. — [libs/langchain_v1/Makefile#L49-50](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/Makefile#L49-L50) [.github/workflows/codspeed.yml](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/.github/workflows/codspeed.yml)
- CI runs the unit suite twice — once on current deps and once after installing computed minimum versions via `.github/scripts/get_min_versions.py` — catching lower-bound regressions. — [.github/workflows/_test.yml#L55-73](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/.github/workflows/_test.yml#L55-L73)
- Scheduled integration tests (integration_tests.yml) trace runs to LangSmith using LANGSMITH_TRACING/API_KEY/PROJECT/TAGS env vars and authenticate to cloud providers via workload identity (google-github-actions/auth, configure-aws-credentials). — [.github/workflows/integration_tests.yml#L187-293](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/.github/workflows/integration_tests.yml#L187-L293)
- langchain-tests is a published package exposing standard unit+integration test classes (chat_models, embeddings, tools, vectorstores, retrievers, indexers, caches, sandboxes) that partner packages subclass for conformance. — [libs/standard-tests/langchain_tests/unit_tests/chat_models.py](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/standard-tests/langchain_tests/unit_tests/chat_models.py) [libs/standard-tests/langchain_tests/integration_tests/vectorstores.py](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/standard-tests/langchain_tests/integration_tests/vectorstores.py)
- Static checks are strict: ruff with `select = ["ALL"]` (google docstring convention, banned relative imports) and mypy strict mode with pydantic plugin; `check_imports` script verifies every module imports cleanly in CI. — [libs/langchain_v1/pyproject.toml#L110-154](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/pyproject.toml#L110-L154) [libs/langchain_v1/Makefile#L73-77](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/Makefile#L73-L77)
- Coverage is gated by make targets `coverage` and `coverage_agents` (term-missing + xml/html reports scoped to langchain.agents); test_react_agent.py is exempted from all lint rules, suggesting it is a large legacy-style test file. — [libs/langchain_v1/Makefile#L24-38](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/Makefile#L24-L38) [libs/langchain_v1/pyproject.toml#L156-164](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/pyproject.toml#L156-L164)

## Risk map

The highest blast radius sits in places that execute or reach out: ShellToolMiddleware spawns real subprocesses (host/docker/codex policies), MCPAdapter intentionally blocks non-http(s) string targets because FastMCP would otherwise exec local files, and core's _security module provides SSRF validation with a test-only bypass env var. Fragile spots: regex-based model capability fallbacks that must track provider releases, a 9_999 recursion limit, deferred import errors from lazy provider loading, validation gaps when wrap_tool_call middleware exists, and the still-shipped langchain-classic legacy surface.
- ShellToolMiddleware executes model-generated shell commands via subprocess.Popen (n noqa'd S603); HostExecutionPolicy runs commands directly on the host — DockerExecutionPolicy/CodexSandboxExecutionPolicy exist precisely because host execution is dangerous. Agents given this middleware have arbitrary-code-execution capability. — [libs/langchain_v1/langchain/agents/middleware/_execution.py#L27-140](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/middleware/_execution.py#L27-L140) [libs/langchain_v1/langchain/agents/middleware/shell_tool.py#L59-120](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/middleware/shell_tool.py#L59-L120)
- MCPAdapter._validate_url_target rejects any str target that is not http/https because fastmcp.Client tests strings as filesystem paths first and would launch a matching .py/.js file as a subprocess — a deliberate guard against config/model-supplied strings becoming local code execution. — [libs/langchain_v1/langchain/mcp/adapter.py#L84-122](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/mcp/adapter.py#L84-L122)
- core._security provides SSRF protection (validate_safe_url) blocking private IPs, localhost, cloud metadata, and k8s-internal addresses — but a `LANGCHAIN_ENV=local_test` env var bypasses validation for hostnames starting with 'test' containing 'server', a foot-gun if set in production. — [libs/core/langchain_core/_security/_ssrf_protection.py#L29-80](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/core/langchain_core/_security/_ssrf_protection.py#L29-L80) [libs/core/langchain_core/_security/_policy.py](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/core/langchain_core/_security/_policy.py)
- FALLBACK_MODELS_WITH_STRUCTURED_OUTPUT is a hand-maintained regex list of model names assumed to support provider-native structured output when profile data is missing — it will silently mispredict capabilities for new models until updated. — [libs/langchain_v1/langchain/agents/factory.py#L174-194](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/factory.py#L174-L194)
- The compiled agent gets `recursion_limit: 9_999` (working around a langgraph issue), so a model stuck in a tool-call loop can iterate ~10k times before stopping — cost/runaway risk mitigated only by opt-in ModelCallLimitMiddleware/ToolCallLimitMiddleware. — [libs/langchain_v1/langchain/agents/factory.py#L1829-1831](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/factory.py#L1829-L1831) [libs/langchain_v1/langchain/agents/middleware/model_call_limit.py](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/middleware/model_call_limit.py)
- Lazy provider loading means ImportError surfaces at first use, not import time: `_import_module` rewrites failures into 'pip install <pkg>' messages, and ollama has a langchain_community fallback that can mask which package is actually missing. — [libs/langchain_v1/langchain/chat_models/base.py#L123-191](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/chat_models/base.py#L123-L191)
- Client-side tool validation in `_get_bound_model` is skipped entirely when any middleware defines wrap_tool_call, so a typo'd dynamic tool name fails only when the middleware's own handler misses it — validation coverage depends on middleware correctness. — [libs/langchain_v1/langchain/agents/factory.py#L1317-1345](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/factory.py#L1317-L1345)
- wrap_model_call middleware cannot return Command.goto (raises NotImplementedError pointing users at jump_to), and commands accumulate inner-first through the composed stack — ordering/return-shape mistakes produce runtime errors deep in the loop. — [libs/langchain_v1/langchain/agents/factory.py#L244-250](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/factory.py#L244-L250) [libs/langchain_v1/langchain/agents/factory.py#L67-80](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/factory.py#L67-L80)
- langchain-classic remains a large shipped legacy surface (chains/, agents/, retrievers/, utilities/ including many network-calling API wrappers); the dangerous LLMBashChain was removed — its module is now a stub raising AttributeError redirecting to langchain-experimental. — [libs/langchain/langchain_classic/chains/llm_bash/__init__.py](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain/langchain_classic/chains/llm_bash/__init__.py) [libs/langchain/langchain_classic/agents/agent.py#L1012](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain/langchain_classic/agents/agent.py#L1012)
- PIIMiddleware mutates streamed content in flight via _PIIStreamTransformer — silent redaction means downstream consumers (logs, users) see altered text; a false-positive detection corrupts model output with no record unless tracing is on. (inferred) — [libs/langchain_v1/langchain/agents/middleware/pii.py#L39-66](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/middleware/pii.py#L39-L66)
- Unit tests for persistence require live postgres/redis containers — a contributor running plain pytest without `make test`'s docker compose step will hit connection failures, not skips. (inferred) — [libs/langchain_v1/Makefile#L10-44](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/Makefile#L10-L44) [libs/langchain_v1/tests/unit_tests/agents/conftest_checkpointer.py](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/tests/unit_tests/agents/conftest_checkpointer.py)
- init_chat_model's 'langsmith' provider silently rewrites kwargs (openai_api_base -> gateway.smith.langchain.com, api key from LANGSMITH_GATEWAY_API_KEY/LANGSMITH_API_KEY, use_responses_api=True) — credentials and traffic routing change based on env vars. — [libs/langchain_v1/langchain/chat_models/base.py#L24-38](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/chat_models/base.py#L24-L38)

## Extension points

The framework is built around extension. Agents are extended via AgentMiddleware subclasses (six hook points + state_schema + transformers), custom tools (BaseTool/@tool/dict provider tools), custom state/context schemas, structured-output strategies, checkpointers/stores/caches from LangGraph, and stream transformers. Models and embeddings plug in through partner packages implementing core abstractions plus registry entries in _BUILTIN_PROVIDERS, validated by the langchain-tests conformance suite. Shell execution is extensible via BaseExecutionPolicy.
- AgentMiddleware is the primary extension point: subclasses override any of before_agent/before_model/after_model/after_agent/wrap_model_call/wrap_tool_call (sync and/or async variants); decorators @before_agent/@before_model/@after_agent/@after_model/@dynamic_prompt/@wrap_model_call/@wrap_tool_call offer a functional alternative. — [libs/langchain_v1/langchain/agents/middleware/types.py#L42-66](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/middleware/types.py#L42-L66) [libs/langchain_v1/langchain/agents/middleware/__init__.py#L90-100](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/middleware/__init__.py#L90-L100)
- Middleware can declare `state_schema` (merged into agent state), `tools` (registered on the agent), `transformers` (stream post-processors), `trace_policy`, and `can_jump_to` per hook — factory.py inspects which hooks are overridden to decide which graph nodes to add. — [libs/langchain_v1/langchain/agents/factory.py#L1174-1182](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/factory.py#L1174-L1182) [libs/langchain_v1/langchain/agents/factory.py#L1550-1645](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/factory.py#L1550-L1645)
- New chat-model providers are added by implementing BaseChatModel in a partner package and adding a (module_path, class_name, creator_func) entry to `_BUILTIN_PROVIDERS`; custom creator lambdas handle non-standard constructors (e.g. huggingface's from_model_id, ibm's model_id kwarg). — [libs/langchain_v1/langchain/chat_models/base.py#L56-97](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/chat_models/base.py#L56-L97)
- New embeddings providers follow the identical registry pattern in embeddings/base.py `_BUILTIN_PROVIDERS`. — [libs/langchain_v1/langchain/embeddings/base.py#L15-34](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/embeddings/base.py#L15-L34)
- Partner packages prove conformance by subclassing langchain-tests suites (unit_tests/chat_models.py, integration_tests/vectorstores.py, etc.) rather than writing their own contract tests. — [libs/standard-tests/langchain_tests/unit_tests/chat_models.py](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/standard-tests/langchain_tests/unit_tests/chat_models.py) [libs/standard-tests/langchain_tests/integration_tests](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/standard-tests/langchain_tests/integration_tests)
- Tools plug in as BaseTool subclasses, @tool-decorated callables, or raw dicts (provider built-in tools); tools can inject runtime/state/store via ToolRuntime/InjectedState/InjectedStore annotations. — [libs/langchain_v1/langchain/tools/__init__.py](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/tools/__init__.py) [libs/langchain_v1/langchain/agents/factory.py#L879-882](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/factory.py#L879-L882)
- Agent state is extensible two ways: a custom `state_schema` TypedDict passed to create_agent (wins field conflicts over middleware schemas since it's merged last), or middleware-declared state_schema attributes. — [libs/langchain_v1/langchain/agents/factory.py#L916-923](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/factory.py#L916-L923) [libs/langchain_v1/langchain/agents/factory.py#L1174-1182](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/factory.py#L1174-L1182)
- Structured output strategies are pluggable ResponseFormat implementations (ToolStrategy, ProviderStrategy, AutoStrategy); callers can also pass raw Pydantic/dataclass/TypedDict/JSON-schema which get wrapped in AutoStrategy. — [libs/langchain_v1/langchain/agents/structured_output.py#L29-33](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/structured_output.py#L29-L33) [libs/langchain_v1/langchain/agents/factory.py#L1347-1353](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/factory.py#L1347-L1353)
- Persistence/streaming extension points come straight from LangGraph: create_agent accepts checkpointer (Checkpointer), store (BaseStore), cache (BaseCache), interrupt_before/after node names, and user `transformers` factories appended to the default pipeline. — [libs/langchain_v1/langchain/agents/factory.py#L849-858](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/factory.py#L849-L858) [libs/langchain_v1/langchain/agents/factory.py#L1841-1857](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/factory.py#L1841-L1857)
- Shell execution policy is pluggable via BaseExecutionPolicy subclasses — built-ins are HostExecutionPolicy, DockerExecutionPolicy, CodexSandboxExecutionPolicy, each implementing process launch and post-spawn limits. — [libs/langchain_v1/langchain/agents/middleware/_execution.py#L92-323](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/middleware/_execution.py#L92-L323)
- Multi-agent composition is supported by naming an agent (`name=` becomes a subgraph node name) and by SubagentTransformer, which is always registered on the compiled graph to reshape nested-agent stream events. — [libs/langchain_v1/langchain/agents/factory.py#L946-950](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/factory.py#L946-L950) [libs/langchain_v1/langchain/agents/_subagent_transformer.py](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/_subagent_transformer.py)
- Observability is extensible per-middleware via TracePolicy and process-wide via configure_trace_policy; all wrap_* hooks are traced through LangSmith `traceable` with scrubbed inputs. — [libs/langchain_v1/langchain/agents/middleware/_trace_policy.py](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/middleware/_trace_policy.py) [libs/langchain_v1/langchain/agents/factory.py#L158-171](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/factory.py#L158-L171)

## Contributor handoff

Read AGENTS.md/CLAUDE.md first — they encode the real conventions (uv-only, Conventional Commits with mandatory scope, Google docstrings, mypy strict + ruff ALL, no breaking signature changes). Work in libs/langchain_v1 for new features; libs/langchain (langchain-classic) is frozen. Re-export shims point at canonical homes: edit langchain_core or langgraph.prebuilt, not the shim. Tests must be hermetic unit tests under tests/unit_tests unless they need the docker services. Watch for: the manual structured-output model regexes, validation gaps around wrap_tool_call, and checkpointer tests that need containers.
- AGENTS.md and CLAUDE.md at repo root are the canonical contributor contract: uv for all env/dep ops (never pip/poetry), `uv sync --all-groups` before tests, make test/lint/format per package, Conventional Commits with mandatory scope, branch naming `<user>/<scope>/<desc>`. — [AGENTS.md](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/AGENTS.md) [CLAUDE.md](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/CLAUDE.md)
- New features go in libs/langchain_v1 (package `langchain`); libs/langchain ships `langchain-classic` and is explicitly 'legacy, no new features' per AGENTS.md — don't add capabilities there. — [AGENTS.md](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/AGENTS.md) [libs/langchain/pyproject.toml](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain/pyproject.toml)
- Public API stability is a hard rule: preserve signatures/positions/names, add new params keyword-only, mark experimental features with `!!! warning` docstring admonitions, and check `__init__.py` exports before touching anything public. — [AGENTS.md](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/AGENTS.md) [libs/langchain_v1/langchain/agents/__init__.py](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/__init__.py)
- Several langchain_v1 modules are backwards-compat re-export shims — e.g. langchain/tools/tool_node.py re-exports langgraph.prebuilt ToolNode/ToolCallRequest, langchain/tools/__init__.py re-exports langchain_core.tools — so edit the canonical implementation, not the shim. — [libs/langchain_v1/langchain/tools/tool_node.py](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/tools/tool_node.py) [libs/langchain_v1/langchain/tools/__init__.py](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/tools/__init__.py)
- Before writing agent-loop code, read factory.py end-to-end: node names are '<middleware_name>.<hook>', edges must go through `_add_middleware_edge`/`_get_can_jump_to`, wrap handlers compose via `_chain_model_call_handlers`, and Command.goto inside wrap_model_call is unsupported. — [libs/langchain_v1/langchain/agents/factory.py#L1543-1857](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/factory.py#L1543-L1857)
- Test conventions: mirror source layout under tests/unit_tests, no network (pytest-socket enforced), use fixtures/mocks, determinism required; persistence tests need `make start_services` (postgres+redis) first. — [AGENTS.md](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/AGENTS.md) [libs/langchain_v1/Makefile#L10-47](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/Makefile#L10-L47)
- Lint bar is high: ruff `select = ["ALL"]` with google pydocstyle, single-backtick docstring code refs, banned relative imports, mypy strict with pydantic plugin and warn_unreachable; run `make lint` and `uv run --all-groups mypy .` before submitting. — [libs/langchain_v1/pyproject.toml#L107-174](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/pyproject.toml#L107-L174)
- Releasing a package = bump `_version.py` + pyproject version + `uv lock`, merge, then trigger _release.yml via `gh workflow run 63880841` — never tag or create GitHub releases manually. — [AGENTS.md](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/AGENTS.md) [.github/workflows/_release.yml](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/.github/workflows/_release.yml)
- Known traps: FALLBACK_MODELS_WITH_STRUCTURED_OUTPUT regexes must be updated for new model families; middleware-added tools bypass validation when wrap_tool_call exists; ModelRequest attribute mutation is deprecated (use override()); system_prompt param deprecated in favor of SystemMessage. — [libs/langchain_v1/langchain/agents/factory.py#L174-194](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/factory.py#L174-L194) [libs/langchain_v1/langchain/agents/factory.py#L1317-1345](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/factory.py#L1317-L1345) [libs/langchain_v1/langchain/agents/middleware/types.py#L169-200](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/langchain/agents/middleware/types.py#L169-L200)
- Model profile data (capabilities/context windows) is generated, not hand-edited: use `uv run langchain-profiles refresh --provider <p> --data-dir <partner>/langchain_<p>/data` from libs/model-profiles. — [AGENTS.md](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/AGENTS.md) [libs/model-profiles/langchain_model_profiles/cli.py](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/model-profiles/langchain_model_profiles/cli.py)
- Every public module/function needs Google-style docstrings with Args/Returns/Raises, full type hints, and American English; tests get relaxed lint rules but still require the strict pytest config (no bare markers). — [AGENTS.md](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/AGENTS.md) [libs/langchain_v1/pyproject.toml#L156-164](https://github.com/langchain-ai/langchain/blob/9e4ea7a3495992c02a79de6fa5788e028b03df11/libs/langchain_v1/pyproject.toml#L156-L164)

Source repository: https://github.com/langchain-ai/langchain
Full evidence corpus: https://github.com/Codevetter/codevetter/tree/main/benchmarks/repo-unpacks/langchain.json

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
