> ## Documentation Index
> Fetch the complete documentation index at: https://docs.vane.build/llms.txt
> Use this file to discover all available pages before exploring further.

# LangChain

> @vane.build/langchain — attest every LLM call and tool invocation automatically.

## Installation

```bash theme={null}
npm install @vane.build/langchain
```

Peer dependency: `@langchain/core >= 0.2.0`.

## Three-line setup

```typescript theme={null}
import { VaneCallbackHandler } from '@vane.build/langchain';
import { ChatOpenAI } from '@langchain/openai';

const handler = new VaneCallbackHandler({
  baseUrl: process.env.VANE_URL!,
  apiKey: process.env.VANE_API_KEY!,
  agentId: 'researcher-1',
});

const llm = new ChatOpenAI({ callbacks: [handler] });
await llm.invoke('Summarise this contract.');
```

That's it. Every LLM call and tool invocation is now attested to Vane.

## `VaneCallbackHandler`

Extends LangChain's `BaseCallbackHandler`. Attach it to any LLM, chain, or agent executor.

### Constructor options

| Option      | Type     | Required | Description                                                                                           |
| ----------- | -------- | -------- | ----------------------------------------------------------------------------------------------------- |
| `baseUrl`   | `string` | Yes      | Base URL of your Vane instance.                                                                       |
| `apiKey`    | `string` | Yes      | Company-scoped API key.                                                                               |
| `agentId`   | `string` | Yes      | Agent identifier that appears on every record.                                                        |
| `companyId` | `string` | No       | Company ID embedded in attestation payloads. If omitted, the API key's company is used by the server. |

### What gets attested

| Event                        | `actionType`     | Payload fields                                                                                       |
| ---------------------------- | ---------------- | ---------------------------------------------------------------------------------------------------- |
| LLM call completed           | `"llm-call"`     | `model`, `input` (prompts or messages), `output` (first generation text), `tokenUsage`, `durationMs` |
| Tool call completed          | `"tool-call"`    | `tool`, `input`, `output`, `durationMs`                                                              |
| Agent action (tool decision) | `"agent-action"` | `tool`, `toolInput`                                                                                  |

Chat models go through `handleChatModelStart` (not `handleLLMStart`). Both paths are covered — you will always get an `llm-call` record regardless of whether you use a chat model or a completion model.

### Error handling

Attestation calls are **fire-and-forget**. If the Vane server is unavailable, the error is logged to `console.error` and the LangChain execution continues uninterrupted. Attestation failures never block or crash your agent.

## Attaching to different LangChain components

**LLM or chat model:**

```typescript theme={null}
const llm = new ChatOpenAI({ callbacks: [handler] });
```

**Agent executor:**

```typescript theme={null}
const executor = AgentExecutor.fromAgentAndTools({
  agent,
  tools,
  callbacks: [handler],
});
```

**Chain:**

```typescript theme={null}
const chain = prompt.pipe(llm).withConfig({ callbacks: [handler] });
```

**Global (all callbacks):**

```typescript theme={null}
import { setGlobalCallbackManager } from '@langchain/core/callbacks/manager';
// Not recommended for production — attaches to every LangChain operation in the process.
```

## Example — full agent

```typescript theme={null}
import { VaneCallbackHandler } from '@vane.build/langchain';
import { createReactAgent } from '@langchain/langgraph/prebuilt';
import { ChatOpenAI } from '@langchain/openai';
import { tool } from '@langchain/core/tools';
import { z } from 'zod';

const handler = new VaneCallbackHandler({
  baseUrl: process.env.VANE_URL!,
  apiKey: process.env.VANE_API_KEY!,
  agentId: 'contract-reviewer',
  companyId: 'acme',
});

const searchTool = tool(
  async ({ query }) => `Results for: ${query}`,
  { name: 'search', description: 'Web search', schema: z.object({ query: z.string() }) },
);

const agent = createReactAgent({
  llm: new ChatOpenAI({ model: 'gpt-4o', callbacks: [handler] }),
  tools: [searchTool],
});

const result = await agent.invoke({
  messages: [{ role: 'user', content: 'Find the penalty clauses in EU AI Act.' }],
});
```

Each tool call and LLM completion in this run will produce a signed record in Vane.
