# AGENTS.md - AI Agent Guidelines for LangChain.js This document provides guidance for AI coding agents working with the LangChain.js codebase. ## Corridor security analysis When Corridor's `analyzePlan` tool is available, create a plan and use the tool to analyze it before generating or modifying code. Apply the resulting security guidance before writing code. ## Project Overview LangChain.js is a TypeScript framework for building LLM-powered applications. It provides standard interfaces for agents, models, embeddings, vector stores, and more, enabling developers to chain together interoperable components and third-party integrations. ### Supported Environments - Node.js (ESM and CommonJS) - 20.x, 22.x, 24.x - Cloudflare Workers - Vercel / Next.js (Browser, Serverless and Edge functions) - Supabase Edge Functions - Browser - Deno - Bun ## Repository Structure This is a **monorepo** managed with [pnpm workspaces](https://pnpm.io/) (v10.14.0) and [Turborepo](https://turbo.build/). ### Key Packages | Package | Path | Description | | -------------------------- | ------------------------------------- | ---------------------------------------------------------------- | | `langchain` | `libs/langchain/` | Main LangChain package with agents, prompts, and orchestration | | `@langchain/core` | `libs/langchain-core/` | Core abstractions and interfaces (base classes, runnables, etc.) | | `@langchain/textsplitters` | `libs/langchain-textsplitters/` | Text splitting utilities | | `@langchain/openai` | `libs/providers/langchain-openai/` | OpenAI integration | | `@langchain/anthropic` | `libs/providers/langchain-anthropic/` | Anthropic integration | | Other providers | `libs/providers/langchain-*/` | First-party provider integrations | ### Internal Packages | Package | Path | Description | | --------------------------- | -------------------------------- | ------------------------------------ | | `@langchain/build` | `internal/build/` | Build utilities | | `@langchain/tsconfig` | `internal/tsconfig/` | Shared TypeScript configuration | | `@langchain/standard-tests` | `libs/langchain-standard-tests/` | Standard test suite for integrations | ## Development Setup ### Prerequisites - **Node.js v24.x** (check with `node -v`) - **pnpm v10.14.0** (package manager) ### Initial Setup ```bash # Install dependencies from root pnpm install # Build the core package first (required before other packages) pnpm --filter @langchain/core build ``` ## Common Commands All commands can be run from the project root using `pnpm --filter ` to target specific workspaces. ### Package Filters - `--filter langchain` - the main `langchain` package - `--filter @langchain/core` - the core package - `--filter @langchain/openai` - OpenAI integration (and similarly for other providers) ### Building ```bash pnpm --filter langchain build pnpm --filter @langchain/core build ``` ### Linting ```bash pnpm lint ``` ### Formatting ```bash pnpm format # Fix formatting pnpm format:check # Check only ``` ### Testing ```bash # Unit tests pnpm --filter langchain test pnpm --filter @langchain/core test # Integration tests (requires API keys) pnpm --filter langchain test:integration # Single test file pnpm --filter test:single ``` ## Coding Standards ### TypeScript Configuration The project uses a shared TypeScript configuration from `internal/tsconfig/base.json`: - Target: ES2022 - Module: ESNext with bundler resolution - Strict mode enabled - Source maps and declaration maps enabled ### Lint Rules Lint rules are defined in `.oxlintrc.json`. Key rules to follow: 1. **No `process.env`** - Except in test files (`node/no-process-env: error`) 2. **No explicit `any`** - Use proper types (`typescript/no-explicit-any: error`) 3. **Prefer template literals** - Over string concatenation (`prefer-template: error`) 4. **File extensions required** - In imports (`import/extensions: error`) ### Import Conventions ```typescript // Always include .js extension for local imports (ESM) import { Something } from "./something.js"; // Use named exports, not default exports export { MyClass, myFunction }; ``` ### Zod Schema Support The codebase supports both Zod v3 and v4: ```typescript import { z } from "zod/v3"; import { z as z4 } from "zod/v4"; ``` ## File Naming Conventions ### Source Files - Regular modules: `my_module.ts` (snake_case) - Index files: `index.ts` - Type definitions: `types.ts` ### Test Files - **Unit tests**: `*.test.ts` - Tests that don't require external APIs - **Integration tests**: `*.int.test.ts` - Tests that call external APIs - **Type tests**: `*.test-d.ts` - TypeScript type checking tests - **Standard tests**: `*.standard.test.ts` / `*.standard.int.test.ts` - Standard test suite Tests should be placed in a `tests/` folder alongside the module being tested. ## Core Abstractions ### Runnables The `Runnable` interface (`@langchain/core/runnables`) is the foundation of LangChain. All major components extend `Runnable`: ```typescript import { Runnable, RunnableConfig, RunnableLike, } from "@langchain/core/runnables"; ``` Key methods: - `invoke(input, config?)` - Single invocation - `stream(input, config?)` - Streaming invocation - `batch(inputs, config?)` - Batch invocation ### Messages Messages are in `@langchain/core/messages`: ```typescript import { HumanMessage, AIMessage, SystemMessage, ToolMessage, BaseMessage, } from "@langchain/core/messages"; ``` ### Tools Tools extend `StructuredTool` from `@langchain/core/tools`: ```typescript import { StructuredTool, DynamicTool, tool } from "@langchain/core/tools"; ``` ### Chat Models Chat models extend `BaseChatModel` from `@langchain/core/language_models/chat_models`: ```typescript import { BaseChatModel, BaseChatModelParams, } from "@langchain/core/language_models/chat_models"; ``` ## Writing Tests ### Unit Tests ```typescript import { test, expect, describe } from "vitest"; import { FakeChatModel } from "@langchain/core/utils/testing"; test("should do something", async () => { const model = new FakeChatModel({}); const result = await model.invoke([["human", "Hello!"]]); expect(result.content).toBe("Hello!"); }); ``` ### Integration Tests Integration tests require actual API credentials: ```typescript import { describe, test, expect } from "vitest"; import { ChatOpenAI } from "../index.js"; import { HumanMessage } from "@langchain/core/messages"; test("Test ChatOpenAI Generate", async () => { const chat = new ChatOpenAI({ model: "gpt-4o-mini", maxTokens: 10, }); const message = new HumanMessage("Hello!"); const result = await chat.invoke([message]); expect(typeof result.content).toBe("string"); }); ``` ### Type Tests Use `expectTypeOf` from vitest for type assertions: ```typescript import { expectTypeOf } from "vitest"; expectTypeOf(someFunction).returns.toMatchTypeOf(); ``` ### Standard Tests For provider integrations, extend the standard test classes: ```typescript import { ChatModelUnitTests } from "@langchain/standard-tests"; class MyChatModelStandardUnitTests extends ChatModelUnitTests< MyChatModelCallOptions, AIMessageChunk > { constructor() { super({ Cls: MyChatModel, chatModelHasToolCalling: true, chatModelHasStructuredOutput: true, constructorArgs: {}, }); } } ``` ## Creating New Integrations ### Provider Package Structure New provider packages should follow this structure: ```txt libs/providers/langchain-{provider}/ ├── package.json ├── tsconfig.json ├── tsdown.config.ts ├── vitest.config.ts ├── turbo.json ├── README.md ├── LICENSE └── src/ ├── index.ts ├── chat_models/ │ ├── index.ts │ └── tests/ │ ├── index.test.ts │ ├── index.int.test.ts │ ├── index.standard.test.ts │ └── index.standard.int.test.ts └── embeddings.ts (if applicable) ``` ### Package.json Requirements ```json { "name": "@langchain/provider-name", "type": "module", "engines": { "node": ">=20" }, "peerDependencies": { "@langchain/core": "^1.0.0" }, "devDependencies": { "@langchain/core": "workspace:^", "@langchain/standard-tests": "workspace:*", "@langchain/tsconfig": "workspace:*" } } ``` ### Scaffolding Use the CLI tool to create new integration packages: ```bash npx create-langchain-integration ``` ## Best Practices ### 1. Use Existing Abstractions Before creating new classes, check if `@langchain/core` already provides what you need: - `Runnable` and its variants - `StructuredTool` for tools - `BaseChatModel` for chat models - `Embeddings` for embedding models - `BaseRetriever` for retrievers - `VectorStore` for vector stores ### 2. Support Streaming All LLM-related components should support streaming when possible: ```typescript async *_streamResponseChunks( messages: BaseMessage[], options: this["ParsedCallOptions"], runManager?: CallbackManagerForLLMRun ): AsyncGenerator { // Yield chunks as they arrive } ``` ### 3. Handle Callbacks Properly Use the callback manager for tracing and observability: ```typescript await runManager?.handleLLMNewToken(token); ``` ### 4. Environment Variables Access environment variables using the utility: ```typescript import { getEnvironmentVariable } from "@langchain/core/utils/env"; const apiKey = getEnvironmentVariable("MY_API_KEY"); ``` ### 5. Error Handling Use typed errors with proper error codes: ```typescript throw new Error("Model authentication failed", { cause: { lc_error_code: "MODEL_AUTHENTICATION" }, }); ``` ### 6. Third-Party Dependencies - Add them as regular `dependencies` in standalone provider packages - Always use caret (`^`) for version ranges - Ensure dependencies are MIT or permissively licensed ## Pull Request Checklist Before submitting a PR: 1. [ ] Run `pnpm lint` and fix any issues 2. [ ] Run `pnpm format` to format code 3. [ ] Add/update unit tests (`*.test.ts`) 4. [ ] Add/update integration tests if applicable (`*.int.test.ts`) 5. [ ] Add/update type tests if changing public APIs (`*.test-d.ts`) 6. [ ] Update documentation if changing public APIs 7. [ ] Keep changes focused - one feature/fix per PR 8. [ ] Ensure no circular dependencies (checked by `lint:dpdm`) ## Debugging Tips ### Running Specific Tests ```bash # Run a single test file pnpm --filter @langchain/core test src/messages/tests/utils.test.ts # Run tests matching a pattern pnpm --filter @langchain/core test --grep "should handle" # Watch mode pnpm --filter @langchain/core test:watch ``` ### Building in Watch Mode ```bash pnpm watch ``` ### Checking for Circular Dependencies ```bash pnpm --filter @langchain/core lint:dpdm ``` ## Resources - [Documentation](https://docs.langchain.com/oss/javascript/langchain/overview) - [API Reference](https://api.js.langchain.com) - [GitHub Issues](https://github.com/langchain-ai/langchainjs/issues) - [LangChain Forum](https://forum.langchain.com) - [Contributing Guide](./CONTRIBUTING.md) - [Integration Guide](./.github/contributing/INTEGRATIONS.md)