🚀 Big News:Socket Has Acquired Secure Annex.Learn More
Socket
Book a DemoSign in
Socket

@mondaydotcomorg/atp-langchain

Package Overview
Dependencies
Maintainers
779
Versions
49
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@mondaydotcomorg/atp-langchain

LangChain integration for Agent Tool Protocol

latest
Source
npmnpm
Version
0.26.0
Version published
Weekly downloads
623
42.89%
Maintainers
779
Weekly downloads
 
Created
Source

@mondaydotcomorg/atp-langchain

LangChain and LangGraph integration for Agent Tool Protocol with production-ready human-in-the-loop support.

Overview

This package integrates ATP with LangChain and LangGraph, enabling agents to generate and execute ATP code as tools. Includes production-ready async approval workflows using LangGraph interrupts and checkpoints.

Installation

npm install @mondaydotcomorg/atp-langchain @langchain/core @langchain/langgraph

Architecture

graph TB
    LangChain[LangChain Agent] --> Tools[ATP Tools]
    Tools --> Client[LangGraphATPClient]

    Client --> Server[ATP Server]
    Server --> Runtime[Runtime APIs]

    Runtime --> LLM[atp.llm.*]
    Runtime --> Embed[atp.embedding.*]
    Runtime --> Approval[atp.approval.*]

    LLM --> Callback[Client LLM Callback]
    Embed --> EmbedCallback[Client Embedding Callback]
    Approval --> Interrupt[LangGraph Interrupt]

    Interrupt --> Checkpoint[Save State]
    Checkpoint --> Resume[Resume Later]

Features

  • 🤖 LangChain Tools - Use ATP as tools in any LangChain agent
  • 🔄 LangGraph Interrupts - Production-ready async approvals
  • 🧠 LLM Sampling - atp.llm.call() routes to your LangChain LLM
  • 🔍 Embedding Support - atp.embedding.* routes to your embeddings model
  • Approval Workflows - Human-in-the-loop via LangGraph checkpoints
  • 💾 State Persistence - PostgreSQL/Redis checkpointing
  • 📝 TypeScript - Full type safety

Quick Start

Simple Agent

import { ChatOpenAI } from '@langchain/openai';
import { createReactAgent } from '@langchain/langgraph/prebuilt';
import { createATPTools } from '@mondaydotcomorg/atp-langchain';

const llm = new ChatOpenAI({ modelName: 'gpt-4' });

// Create ATP tools
const { tools } = await createATPTools('http://localhost:3333', 'your-api-key', { llm });

// Create agent
const agent = createReactAgent({ llm, tools });

// Run agent
const result = await agent.invoke({
	messages: [{ role: 'user', content: 'Execute ATP code to get a joke from the LLM' }],
});

Production Agent with Approvals

import { MemorySaver } from '@langchain/langgraph';
import { createATPTools, ApprovalRequiredException } from '@mondaydotcomorg/atp-langchain';

const llm = new ChatOpenAI({ modelName: 'gpt-4' });

// Create tools with interrupt-based approvals
const { client, tools, isApprovalRequired, resumeWithApproval } =
  await createATPTools('http://localhost:3333', 'api-key', { llm });

// Create agent with checkpointer
const checkpointer = new MemorySaver();
const agent = createReactAgent({ llm, tools, checkpointSaver: checkpointer });

try {
  await agent.invoke({ messages: [...] }, { configurable: { thread_id: 'thread-1' } });
} catch (error) {
  if (isApprovalRequired(error)) {
    const { executionId, message, context } = error.approvalRequest;

    // Save to DB, notify user via Slack/email
    console.log(`Approval needed: ${message}`);
    await notifyUser(message);

    // Wait for approval (async - can take hours/days)
    const approved = await waitForUserApproval(executionId);

    // Resume execution
    const result = await resumeWithApproval(executionId, approved);
  }
}

With Embeddings

import { ChatOpenAI, OpenAIEmbeddings } from '@langchain/openai';
import { createATPTools } from '@mondaydotcomorg/atp-langchain';

const llm = new ChatOpenAI({ modelName: 'gpt-4' });
const embeddings = new OpenAIEmbeddings({ model: 'text-embedding-3-small' });

// Create tools with LLM and embedding support
const { tools } = await createATPTools('http://localhost:3333', 'api-key', {
	llm,
	embeddings, // Enable atp.embedding.*
});

const agent = createReactAgent({ llm, tools });

// Agent can now generate code that uses embeddings:
// const id = await atp.embedding.embed("Store this text");
// const results = await atp.embedding.search("Find similar", { topK: 5 });

How It Works

ATP Runtime in LangChain

When agents use ATP tools, they can generate TypeScript code using ATP's runtime APIs:

// Agent generates this code:
const idea = await atp.llm.call({
	prompt: 'Generate a product idea',
});

// Store embedding for semantic search
const embeddingId = await atp.embedding.embed(idea);

// Request approval
const approval = await atp.approval.request(`Launch product: ${idea}?`, { idea });

if (approval.approved) {
	return await atp.llm.call({
		prompt: `Create marketing copy for: ${idea}`,
	});
}

LLM Sampling

atp.llm.call() routes to your LangChain LLM:

  • Uses the same LLM as your agent
  • Fresh context for sub-reasoning
  • Supports call(), extract(), classify()
// In ATP code:
const analysis = await atp.llm.call({
	prompt: 'Analyze this data: ' + JSON.stringify(data),
	temperature: 0.7,
	model: 'gpt-4',
});

Approval Interrupts

When ATP code calls atp.approval.request(), LangGraph interrupts:

  • Pause - Execution pauses, state saved to checkpoint
  • Notify - Your code sends approval request (Slack, email, UI)
  • Wait - User reviews asynchronously (hours/days OK)
  • Resume - Call resumeWithApproval() with decision
  • Continue - Execution resumes from checkpoint
sequenceDiagram
    participant Agent
    participant ATP
    participant Checkpoint
    participant User

    Agent->>ATP: Execute code
    ATP->>ATP: atp.approval.request()
    ATP->>Checkpoint: Save state
    ATP-->>Agent: Throw ApprovalRequiredException
    Agent->>User: Notify (Slack/Email)

    Note over User: User reviews<br/>(async, can take hours)

    User->>Agent: Approve/Deny
    Agent->>ATP: resumeWithApproval(executionId, approved)
    ATP->>Checkpoint: Restore state
    ATP->>ATP: Continue execution
    ATP-->>Agent: Final result

API Reference

createATPTools()

async function createATPTools(
	serverUrl: string,
	apiKey: string,
	options: CreateATPToolsOptions
): Promise<ATPToolsResult>;

Options:

interface CreateATPToolsOptions {
	llm: BaseChatModel; // Required: LangChain LLM
	embeddings?: Embeddings; // Optional: Embeddings model
	useLangGraphInterrupts?: boolean; // Default: true
	approvalHandler?: ApprovalHandler; // If interrupts disabled
	defaultExecutionConfig?: ExecutionConfig;
}

Returns:

interface ATPToolsResult {
	client: LangGraphATPClient;
	tools: Tool[]; // LangChain tools
	isApprovalRequired: (error: any) => boolean;
	resumeWithApproval: (executionId: string, approved: boolean, reason?: string) => Promise<any>;
}

LangGraphATPClient

class LangGraphATPClient extends AgentToolProtocolClient {
	execute(code: string, config?: ExecutionConfig): Promise<ExecutionResult>;
	resumeWithApproval(executionId: string, approved: boolean, reason?: string): Promise<any>;
	getPendingApproval(executionId: string): Promise<ApprovalRequest | null>;
}

ApprovalRequiredException

class ApprovalRequiredException extends Error {
	approvalRequest: {
		executionId: string;
		message: string;
		context?: any;
		timestamp: number;
	};
}

Production Patterns

PostgreSQL Checkpointing

import { PostgresSaver } from '@langchain/langgraph-checkpoint-postgres';

const checkpointer = new PostgresSaver({
	connectionString: process.env.DATABASE_URL,
});

const agent = createReactAgent({
	llm,
	tools,
	checkpointSaver: checkpointer,
});

// State persists across restarts

Async Approval via Slack

if (isApprovalRequired(error)) {
	const { executionId, message, context } = error.approvalRequest;

	// Save to database
	await db.approvals.create({
		id: executionId,
		message,
		context,
		status: 'pending',
	});

	// Send Slack notification
	await slack.chat.postMessage({
		channel: '#approvals',
		text: message,
		blocks: [
			{
				type: 'actions',
				elements: [
					{ type: 'button', text: 'Approve', action_id: 'approve' },
					{ type: 'button', text: 'Deny', action_id: 'deny' },
				],
			},
		],
	});
}

// In Slack webhook handler:
app.post('/slack/actions', async (req, res) => {
	const { action_id } = req.body;
	const executionId = req.body.state.executionId;

	const approved = action_id === 'approve';
	const result = await resumeWithApproval(executionId, approved);

	await db.approvals.update(executionId, { status: approved ? 'approved' : 'denied' });
	res.json({ ok: true });
});

Multiple Sequential Approvals

// Agent generates ATP code with multiple approvals:
const step1 = await atp.approval.request('Approve step 1?');
if (!step1.approved) return { cancelled: true };

const step2 = await atp.approval.request('Approve step 2?');
if (!step2.approved) return { cancelled: true };

return { success: true };

Each atp.approval.request() triggers a new interrupt → checkpoint → resume cycle.

Comparison: Direct vs Interrupt Mode

Direct Mode

const { tools } = await createATPTools(url, key, {
	llm,
	useLangGraphInterrupts: false,
	approvalHandler: async (message) => {
		return await promptUser(message); // Blocks
	},
});

Pros: Simpler setup, good for CLI tools
Cons: Blocks execution, no persistence, not production-ready

const { tools, isApprovalRequired, resumeWithApproval } = await createATPTools(url, key, { llm });

try {
	await agent.invoke({ messages });
} catch (error) {
	if (isApprovalRequired(error)) {
		await handleApprovalAsync(error.approvalRequest);
	}
}

Pros: Non-blocking, state persists, production-ready, multi-user support
Cons: Slightly more complex setup

Examples

See examples/langchain-react-agent/:

  • simple-test.ts - Integration test with all 3 ATP tools
  • simple-agent.ts - Basic React agent without approvals
  • agent.ts - Production agent with interrupts and checkpoints

RAG with Embeddings

import { ChatOpenAI, OpenAIEmbeddings } from '@langchain/openai';
import { createATPTools } from '@mondaydotcomorg/atp-langchain';

const llm = new ChatOpenAI({ modelName: 'gpt-4' });
const embeddings = new OpenAIEmbeddings();

const { tools } = await createATPTools(url, key, { llm, embeddings });
const agent = createReactAgent({ llm, tools });

// Agent can do RAG:
const result = await agent.invoke({
	messages: [
		{
			role: 'user',
			content: `Use ATP to:
      1. Embed these documents: ["AI is...", "ML is...", "DL is..."]
      2. Search for content similar to "neural networks"
      3. Use atp.llm.call() to answer based on results`,
		},
	],
});

TypeScript Support

import type {
	LangGraphATPClient,
	LangGraphATPClientOptions,
	ApprovalRequest,
	ApprovalResponse,
	CreateATPToolsOptions,
	ATPToolsResult,
} from '@mondaydotcomorg/atp-langchain';

Requirements

  • Node.js 18+
  • TypeScript 5.0+
  • @langchain/core ^0.3.0
  • @langchain/langgraph ^0.2.0

License

MIT

Learn More

Keywords

agent

FAQs

Package last updated on 05 May 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts