# @pleach/langchain (preview) (/docs/langchain)



A vine bridging your trellis to the LangChain one. `@pleach/langchain`
wires LangChain primitives into a `@pleach/core` session. LangChain
`Tool` instances become Pleach tool definitions, `BaseMessage` arrays
become event log rows, and an `AgentExecutor` can run inside a Pleach
session with its calls flowing through the audit ledger.

> **Pre-1.0 — pin a tight range.** The package is published below
> `1.0.0` and the surface will move before it cuts. Treat every
> minor as potentially breaking and pin via `~0.x.y` (patch only).
> The warning is in the package itself; it is repeated here because
> the migration cost of an unintended major-jump on this adapter is
> the highest of any sibling.

<SourceMeta pkg="{ name: &#x22;@pleach/langchain&#x22;, href: &#x22;https://www.npmjs.com/package/@pleach/langchain&#x22; }" source="{ label: &#x22;github.com/pleachhq/langchain&#x22;, href: &#x22;https://github.com/pleachhq/langchain&#x22; }" />

## This page vs the migration guide [#this-page-vs-the-migration-guide]

This page is the reference for the **active adapter** — for hosts
keeping a LangChain tool, agent, or history backend in production
and running it alongside Pleach primitives. The adapter is the
bridge.

If you're moving wholesale off LangChain, the right page is
[Migrating from LangChain](/docs/migrating-from-langchain). That
guide is one-time work: rewrite chains as runtime calls, retire
the LangChain dependency, end with no adapter in the tree. This
page is the opposite shape — long-lived integration, both
libraries in `package.json`, deliberate boundary between them.

## Install [#install]

```bash
npm install @pleach/langchain
# peer deps:
npm install langchain @langchain/core
```

The `langchain` and `@langchain/core` ranges are declared as peer
dependencies so the adapter doesn't pin a LangChain version on top
of the one the host already uses. Mismatches surface as peer-dep
warnings at install time — don't ignore them; the converters key
off LangChain type shapes that vary across majors.

```typescript
import {
  fromLangChainTool,
  fromLangChainTools,
  toLangChainTool,
  LangChainProvider,
  LangGraphCheckpointerAdapter,
  LangGraphStoreAdapter,
  HarnessCheckpointSaver,
  HarnessEventLogCallback,
} from "@pleach/langchain";
```

The adapter exposes converters in both directions — LangChain tools
become Pleach `ToolDefinition`s and vice versa — plus a
`LangChainProvider` that exposes a LangChain chat model as a Pleach
provider, plus LangGraph-shaped checkpointer/store adapters in
each direction. The package README on npm carries the version-current
constructor options.

## Bridging a LangChain tool into a Pleach session [#bridging-a-langchain-tool-into-a-pleach-session]

A LangChain `Tool` (or `StructuredTool`) instance wraps a callable
plus a schema. The adapter converts it into a `ToolDefinition`
usable on the Pleach side — registrable through
`setOrchestratorRegistry` or a plugin's `contributeTools`.

```typescript
import { fromLangChainTool } from "@pleach/langchain";
import { definePleachPlugin } from "@pleach/core";
import { DynamicStructuredTool } from "@langchain/core/tools";

const lcSearch = new DynamicStructuredTool({
  name: "search_db",
  description: "Search the product catalog.",
  schema: searchSchema,
  func: async (input) => productDb.query(input),
});

const pleachSearch = fromLangChainTool(lcSearch);

// Register through a plugin's `contributeTools` — the ergonomic path.
// Pass the plugin to `SessionRuntime({ plugins: [...] })`.
const langchainTools = definePleachPlugin("langchain-tools", {
  tools: [pleachSearch],
});
```

For bulk conversion use `fromLangChainTools(tools)` — same converter,
applied across an array.

Conversion notes documented in the package README cover the
LangChain features without a Pleach equivalent — callbacks scoped
to the tool, the `returnDirect` flag, the `tags`/`metadata` pass-
through. Anything the adapter can't carry across becomes a no-op
on the Pleach side; the converter doesn't silently change semantics.

The reverse — Pleach `ToolDefinition` → LangChain `Tool` — ships as
`toLangChainTool(def)`. Use it when a LangChain-driven agent needs
to call a Pleach-native tool:

```typescript
import { toLangChainTool } from "@pleach/langchain";

const lcTool = toLangChainTool(myPleachToolDef);
// pass `lcTool` into a LangChain AgentExecutor's tools array.
```

## Calling a LangChain chat model as a Pleach provider [#calling-a-langchain-chat-model-as-a-pleach-provider]

`LangChainProvider` wraps any LangChain `BaseChatModel` and exposes it
through the Pleach `AgentAdapter` provider contract. Use this when the
host already owns a configured LangChain model (custom provider, LCEL
chain composed upstream of the chat call, callback wiring) and wants
the Pleach runtime to drive the agent loop against that model.

```typescript
import { LangChainProvider } from "@pleach/langchain";
import { ChatOpenAI } from "@langchain/openai";
import { createPleachRuntime } from "@pleach/core/runtime";

const lcModel = new ChatOpenAI({ model: "gpt-4o-mini" });
// The constructor is positional: `new LangChainProvider(model, maxSteps=10)`.
const provider = new LangChainProvider(lcModel);

const runtime = createPleachRuntime({
  // `provider` is a top-level config slot on createPleachRuntime.
  provider,
});
```

Tool calls round-trip via the `fromLangChainTool` / `toLangChainTool`
converters, so LangChain-native streaming `tool_call_chunks` surface
to Pleach as the same final `tool_calls` shape the runtime expects.

## LangGraph-shaped storage adapters [#langgraph-shaped-storage-adapters]

Two adapter pairs let LangGraph storage co-exist with Pleach's
checkpointer + store contracts:

* **`LangGraphCheckpointerAdapter`** — wraps a LangGraph
  `BaseCheckpointSaver` so Pleach's `SessionRuntime` uses LangGraph
  storage as its checkpointer backend.
* **`LangGraphStoreAdapter`** — wraps a LangGraph `BaseStore` so
  Pleach's memory contract reads/writes against LangGraph's store.
* **`HarnessCheckpointSaver`** — the reverse: a LangGraph-shaped
  `BaseCheckpointSaver` backed by a Pleach checkpointer.
* **`HarnessEventLogCallback`** — a LangGraph `BaseCallbackHandler`
  that writes LangGraph callback events into the Pleach event log.

```typescript
import {
  LangGraphCheckpointerAdapter,
  LangGraphStoreAdapter,
} from "@pleach/langchain";
import { MemorySaver, InMemoryStore } from "@langchain/langgraph";

const checkpointer = new LangGraphCheckpointerAdapter(new MemorySaver());
const store        = new LangGraphStoreAdapter(new InMemoryStore());

const runtime = createPleachRuntime({ checkpointer, store, /* ... */ });
```

The reverse direction (Pleach storage exposed as LangGraph storage) is
useful for a host running a LangGraph agent that wants the Pleach
event log as its callback sink and the Pleach checkpointer as its
state store — without rewriting the agent body.

## Not yet shipping [#not-yet-shipping]

The 0.x surface is intentionally narrow. Two converters described in
early scoping notes are NOT in the published dist:

* **`fromLangChainMessages` / `BaseMessage[]` → event-log rows.** No
  bulk message-history importer ships. Hosts cutting over from a
  LangChain `ChatMessageHistory` backend write the row-shape mapping
  themselves against `runtime.eventLog.append(...)` (see the
  [Event log](/docs/event-log) reference). On the roadmap; not present.
* **`wrapLangChainExecutor` / `AgentExecutor` wrap.** No executor
  wrapper ships. The migration story uses `LangChainProvider` plus
  `fromLangChainTools` to run the Pleach loop against the LangChain
  model + tools, rather than wrapping LangChain's agent loop. If you
  need to keep an `AgentExecutor` running, instrument it with
  `HarnessEventLogCallback` so its callbacks land in the Pleach
  event log alongside the Pleach loop's rows.

## Back-compat boundary [#back-compat-boundary]

The package sits below `1.0.0` because the converter signatures are
still settling. Pin patch-only:

```json
{
  "dependencies": {
    "@pleach/langchain": "~0.3.2"
  }
}
```

Kinds of changes consumers should expect across minors before 1.0:

* **Export renames.** Function names may shift as the surface
  consolidates pre-1.0; pin patch-only against the npm README.
* **Converter signature tweaks.** Optional-argument shapes for the
  three converters are still narrowing — expect new required
  options as edge cases get formalized.
* **Peer-dep range tightening.** Supported `langchain` and
  `@langchain/core` ranges may narrow as LangChain itself moves
  through majors.
* **Roadmap for `AgentExecutor` wrap + message-history import.**
  Neither converter is in the 0.x dist today (see "Not yet
  shipping" above). If they land, the API will be additive — none
  of the converters currently shipping change shape.

Read the package CHANGELOG before each upgrade. The release notes
flag any breaking change in the minor that introduces it.

## Not in scope [#not-in-scope]

* **LangSmith parity.** Distributed-tracing parity with LangSmith
  is out of scope for this adapter. For tracing, use OTel via
  [Observability](/docs/observability) — the audit ledger plus an
  OTel exporter covers the same trace store role.
* **LangGraph node-level bridging.** The adapter operates at the
  tool / message / executor boundary, not at the LangGraph state-
  graph node level. A LangGraph migration is the
  [migration guide's](/docs/migrating-from-langchain) territory.
* **Vector store / retriever wrapping.** LangChain's retrieval
  surface stays inside LangChain; expose it to Pleach as a
  `defineTool` call, the same way the migration guide describes.

## Where to go next [#where-to-go-next]

<Cards>
  <Card title="Migrating from LangChain" href="/docs/migrating-from-langchain" description="The one-time migration shape — when the adapter isn't the right tool." />

  <Card title="MCP integration" href="/docs/mcp-integration" description="The sibling integration page — Model Context Protocol in both directions." />

  <Card title="Host adapter" href="/docs/host-adapter" description="The dynamic-import seam for hosts mid-migration." />

  <Card title="Plugin contract" href="/docs/plugin-contract" description="Wrapping the LangChain bridge as a `HarnessPlugin` contribution." />
</Cards>
