npm package: @gdrl/langgraph-toolbox
Description: LangGraph Toolbox - A comprehensive toolkit for building LangGraph agents with dynamic tool discovery, workflows, and more
Latest version: 0.1.2

# @gdrl/langgraph-toolbox

**LangGraph Toolbox** - A comprehensive toolkit for building LangGraph agents with dynamic tool discovery, workflows, programmatic tool calling, and more.

[![npm version](https://img.shields.io/npm/v/@gdrl/langgraph-toolbox)](https://www.npmjs.com/package/@gdrl/langgraph-toolbox)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

## About

LangGraph Toolbox provides a comprehensive set of tools and middleware for building powerful LangGraph agents. It includes:

- **Programmatic Tool Calling (PTC)**: Execute AI-written TypeScript code in E2B sandboxes to orchestrate tools programmatically
- **Dynamic Tool Discovery**: Automatically discover and enable relevant tools based on user queries
- **Workflow Management**: Create, discover, and manage reusable workflows
- **Todo List Management**: Track and manage task lists within agent conversations
- **Tool Flattening**: Simplify complex nested tool schemas for better agent understanding

## Installation

```bash
npm install @gdrl/langgraph-toolbox
# or
pnpm add @gdrl/langgraph-toolbox
```

## Quick Start

### 1. Install Dependencies

```bash
pnpm add @gdrl/langgraph-toolbox langchain @langchain/core @langchain/langgraph @langchain/openai
```

### 2. Create Your Tools

```typescript
// tools.ts
import { tool } from 'langchain';
import * as z from 'zod';

export const getWeather = tool(
  async ({ city }: { city: string }) => {
    return { weather: 'sunny', city };
  },
  {
    name: 'get_weather',
    description: 'Get weather for a city',
    schema: z.object({
      city: z.string().describe('City name'),
    }),
  }
);
```

### 3. Set Up Your Agent

```typescript
// agent.ts
import { createAgent } from 'langchain';
import { ChatOpenAI } from '@langchain/openai';
import { MemorySaver } from '@langchain/langgraph';
import { LangGraphToolbox, createPTCMiddleware, type PTCTool } from '@gdrl/langgraph-toolbox';
import * as z from 'zod';
import { getWeather } from './tools.js';

// Configure your tools with output schemas and capabilities
const tools: PTCTool[] = [
  {
    tool: getWeather,
    outputSchema: z.object({
      weather: z.string(),
      city: z.string(),
    }),
    dynamicallyDiscoverable: true,  // Can be discovered dynamically
    enabledForPTC: true,            // Can be used in PTC executor
    enabledForNative: true,          // Can be attached natively to agent
  },
];

// Initialize LangGraph Toolbox
const langGraphToolbox = new LangGraphToolbox({
  tools,
  ptc: {
    enabled: true,
    config: {
      e2bApiKey: process.env.E2B_API_KEY!,
      maxRecursionLimit: 100,
      timeoutMs: 10000,
    },
  },
  dynamicToolDiscovery: {
    enabled: true,
    model: new ChatOpenAI({ modelName: 'gpt-4' }), // Discovery model
  },
  workflows: {
    enabled: false, // Set to true and configure if using workflows
  },
  toolFlattening: {
    enabled: false,
  },
  todoList: {
    enabled: false,
  },
});

// Create middleware - returns both middleware and tools
const { middleware: ptcMiddleware, tools: ptcTools } = createPTCMiddleware({ 
  langGraphToolbox 
});

// Create your agent
export const agent = createAgent({
  model: new ChatOpenAI({ modelName: 'gpt-4' }),
  tools: [...ptcTools], // PTC tools + add your native tools here
  middleware: [ptcMiddleware], // Automatically injects base system prompt
  checkpointer: new MemorySaver(),
  systemPrompt: 'You are a helpful assistant.', // Your custom prompt
});
```

### 4. Use Your Agent

```typescript
// index.ts
import { agent } from './agent.js';

const result = await agent.invoke({
  messages: [{
    role: 'user',
    content: 'Get the weather for London, Paris, and Tokyo.'
  }],
});

console.log(result.messages.at(-1)?.content);
```

## Tool Configuration

Each tool can be configured with three flags:

- **`dynamicallyDiscoverable`**: If `true`, the tool can be automatically discovered and enabled based on user queries
- **`enabledForPTC`**: If `true`, the tool can be used in the PTC executor (E2B sandbox)
- **`enabledForNative`**: If `true`, the tool can be attached natively to the agent

You can enable any combination of these flags:

```typescript
const tools: PTCTool[] = [
  {
    tool: getWeather,
    outputSchema: z.object({ /* ... */ }),
    dynamicallyDiscoverable: true,
    enabledForPTC: false,  // Only native, not in PTC
    enabledForNative: true,
  },
  {
    tool: getSportsForWeather,
    outputSchema: z.object({ /* ... */ }),
    dynamicallyDiscoverable: true,
    enabledForPTC: true,   // Only in PTC, not native
    enabledForNative: false,
  },
  {
    tool: getSportDetails,
    outputSchema: z.object({ /* ... */ }),
    dynamicallyDiscoverable: true,
    enabledForPTC: true,   // Available in both modes
    enabledForNative: true,
  },
];
```

## Features

- ✅ **Secure**: AI-written code runs in isolated E2B sandbox
- ✅ **Flexible**: Agent can write complex TypeScript with loops, functions, conditionals
- ✅ **Cached**: Tool results are cached to avoid redundant calls
- ✅ **Type-safe**: Full TypeScript support with Zod schema validation
- ✅ **LangGraph Ready**: Works seamlessly with LangGraph agents (via `createAgent`)
- ✅ **Dynamic Discovery**: Automatically discover relevant tools based on context
- ✅ **Workflow Management**: Create and manage reusable workflows
- ✅ **Error Handling**: Clear error messages help the agent fix mistakes

## Requirements

- Node.js 20+
- E2B API key ([get one here](https://e2b.dev))
- LangChain v1+ and LangGraph v1+

## Environment Variables

```bash
E2B_API_KEY=your_e2b_api_key_here
DATABASE_URL=your_database_url_here  # Required if using workflows
VOYAGE_API_KEY=your_voyage_key_here   # Required if using workflows
MORPH_API_KEY=your_morph_key_here     # Required if using workflows
```

## Workflows

The workflow system automatically learns from successful agent interactions and creates reusable workflow guides that agents can discover and follow for similar tasks.

### How It Works

1. **Automatic Learning**: After each agent turn, the system:
   - Classifies whether the interaction represents a reusable workflow
   - Extracts the objective and success status
   - Searches for similar existing workflows
   - Creates new workflows or updates existing ones with improved guides

2. **Workflow Discovery**: Agents can search for relevant workflows using the `find_workflows` tool, which uses semantic search to match user queries to stored workflows.

3. **Workflow Guides**: Once a workflow is found, agents can retrieve the full guide using `get_workflow_guide`, which contains step-by-step instructions, tips, and specifics for completing similar tasks.

### Setup

1. **Run the database migration** (one-time setup):

```typescript
import { runWorkflowMigration } from '@gdrl/langgraph-toolbox';

await runWorkflowMigration(process.env.DATABASE_URL!);
```

This creates the workflows table, indexes, and enables the pgvector extension. It's safe to run multiple times (idempotent).

2. **Configure workflows in your agent**:

```typescript
const langGraphToolbox = new LangGraphToolbox({
  tools,
  workflows: {
    enabled: true,
    config: {
      databaseUrl: process.env.DATABASE_URL!,
      voyageApiKey: process.env.VOYAGE_API_KEY!, // For embeddings
      morphApiKey: process.env.MORPH_API_KEY!,   // For code generation
      classificationModel: model,  // Model for classifying if workflow is needed
      extractionModel: model,       // Model for extracting objectives
      matchingModel: model,         // Model for matching workflows
      mergeModel: model,            // Model for merging/updating workflows
      topK: 5, // Number of workflows to retrieve from semantic search
      deterministicallyProvideAgentWithTopWorkflowsGuides: true, // Auto-inject top workflows
    },
  },
  // ... other config
});
```

### Workflow Tools

When workflows are enabled, two tools are automatically added:

- **`find_workflows`**: Search for workflows matching a user query
- **`get_workflow_guide`**: Get the full guide for a specific workflow by ID

These tools are available both natively and in the PTC executor.

### Example Usage

```typescript
// Agent automatically uses workflows when enabled
// The middleware processes each agent turn and learns workflows
// Agents can discover workflows using the find_workflows tool
```

## Todo List

The todo list feature helps agents plan and track complex tasks by breaking them down into manageable subtasks.

### How It Works

1. **Task Planning**: At the start of a complex task, the agent creates a todo list with multiple tasks using the `todo_list` tool with action `"create"`.

2. **Task Tracking**: The middleware automatically:
   - Injects the current task objective before each model call
   - Reminds the agent to focus only on the current task
   - Automatically advances to the next task when a task is marked as done

3. **Task Completion**: The agent marks tasks as done using `todo_list` with action `"markDone"`, which automatically moves to the next task.

### Setup

```typescript
const langGraphToolbox = new LangGraphToolbox({
  tools,
  todoList: {
    enabled: true,
  },
  // ... other config
});
```

### Todo List Tool

When todo list is enabled, the `todo_list` tool is automatically added with three actions:

- **`create`**: Create a new todo list with an array of tasks
  ```typescript
  {
    action: 'create',
    tasks: [
      { objective: 'Get weather data', description: 'Fetch weather for multiple cities' },
      { objective: 'Analyze results', description: 'Compare weather conditions' },
      { objective: 'Provide recommendation', description: 'Suggest best city based on weather' }
    ]
  }
  ```

- **`markDone`**: Mark the current task (or a specific task by index) as completed
  ```typescript
  {
    action: 'markDone',
    taskIndex: 0  // Optional, defaults to current task
  }
  ```

- **`getCurrent`**: Get the current active task
  ```typescript
  {
    action: 'getCurrent'
  }
  ```

### How It Helps

- **Focus**: The middleware injects the current task objective before each model call, keeping the agent focused on one task at a time
- **Organization**: Breaks complex tasks into smaller, manageable pieces
- **Progress Tracking**: Automatically tracks which tasks are completed and which are next
- **Automatic Reminders**: The agent is reminded of the current task objective before each turn

### Example Flow

1. User asks: "Plan a trip to Paris"
2. Agent creates todo list: `[{ objective: 'Research flights', ... }, { objective: 'Find hotels', ... }, ...]`
3. Middleware injects: "CURRENT TASK: Research flights"
4. Agent completes flight research and calls `markDone`
5. Middleware automatically advances and injects: "CURRENT TASK: Find hotels"
6. Process continues until all tasks are complete

## Contributing

Contributions welcome! Please feel free to submit a Pull Request.

## License

MIT License - see [LICENSE](../../LICENSE) file for details.

## Links

- [npm package](https://www.npmjs.com/package/@gdrl/langgraph-toolbox)
- [E2B Documentation](https://docs.e2b.dev)
- [LangGraph Documentation](https://langchain-ai.github.io/langgraph/)