Skip to main content

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.

Installation

npm install @vane.build/langchain
Peer dependency: @langchain/core >= 0.2.0.

Three-line setup

import { VaneCallbackHandler } from '@vane.build/langchain';
import { ChatOpenAI } from '@langchain/openai';

const handler = new VaneCallbackHandler({
  baseUrl: process.env.COUNSEL_URL!,
  apiKey: process.env.COUNSEL_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

OptionTypeRequiredDescription
baseUrlstringYesBase URL of your Vane instance.
apiKeystringYesCompany-scoped API key.
agentIdstringYesAgent identifier that appears on every record.
companyIdstringNoCompany ID embedded in attestation payloads. If omitted, the API key’s company is used by the server.

What gets attested

EventactionTypePayload 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:
const llm = new ChatOpenAI({ callbacks: [handler] });
Agent executor:
const executor = AgentExecutor.fromAgentAndTools({
  agent,
  tools,
  callbacks: [handler],
});
Chain:
const chain = prompt.pipe(llm).withConfig({ callbacks: [handler] });
Global (all callbacks):
import { setGlobalCallbackManager } from '@langchain/core/callbacks/manager';
// Not recommended for production — attaches to every LangChain operation in the process.

Example — full agent

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.COUNSEL_URL!,
  apiKey: process.env.COUNSEL_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.