langchainjs (Agent Skills)

GitHub

The agent engineering platform

18,105 stars TypeScript 1 Rule Files Full Docs MCP View JSON API

AGENTS.md

# AGENTS.md - AI Agent Guidelines for LangChain.js

This document provides guidance for AI coding agents working with the LangChain.js codebase.

## 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 <package>` 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 <package> test:single <path-to-test>
```

## 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<ExpectedType>();
```

### 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<ChatGenerationChunk> {
  // 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)