# agents-js

A powerful JavaScript library for building and orchestrating AI agents with OpenAI's GPT models.

## Installation

```bash
npm install agents-js
```

## Features

- 🤖 **Multi-Agent Orchestration** - Coordinate multiple specialized agents
- 🔄 **Automatic Agent Transfers** - Seamless handoffs between agents
- 🛠️ **Pre-built Tools** - Web search (Serper, Firecrawl), calculations, time utilities
- 🔌 **MCP Server Integration** - Connect to any Model Context Protocol server
- 📊 **Token Tracking** - Monitor token usage across conversations
- 🔐 **Session Management** - Persistent conversation state
- ⚡ **Streaming Support** - Real-time response generation
- 🎯 **Lifecycle Hooks** - `beforeModel`, `afterModel`, `beforeTool`, `afterTool`
- ✅ **Tool Confirmation** - Human-in-the-loop for sensitive operations
- 📝 **TypeScript Support** - Full type definitions included
- 📋 **Detailed Logging** - Track agent transfers and tool calls

## Quick Start

### Basic Agent

```javascript
require("dotenv").config();
const { Agent, AgentController } = require("agents-js");
const { calculate, getCurrentTime } = require("agents-js/tools");
const OpenAI = require("openai");

const client = new OpenAI({
  apiKey: process.env.OPENAI_API_KEY,
});

const controller = new AgentController(client);

const agent = new Agent({
  name: "Assistant",
  model: "gpt-4o-mini",
  instructions: "You are a helpful assistant.",
  functions: [calculate, getCurrentTime],
});

const response = await controller.run(agent, [
  { role: "user", content: "What is 25 * 4?" },
]);

console.log(response.messages[response.messages.length - 1].content);
```

### Multi-Agent System with Sub-Agents

```javascript
require("dotenv").config();
const { Agent, AgentController } = require("agents-js");
const { serperSearch, calculate, getCurrentTime } = require("agents-js/tools");
const OpenAI = require("openai");

const client = new OpenAI({
  apiKey: process.env.OPENAI_API_KEY,
});

// Create specialized agents
const weatherAgent = new Agent({
  name: "WeatherSpecialist",
  model: "gpt-4o-mini",
  instructions:
    "You are a weather expert. Use serperSearch to find weather information.",
  functions: [serperSearch],
});

const mathAgent = new Agent({
  name: "MathSpecialist",
  model: "gpt-4o-mini",
  instructions: "You are a math expert. Use calculate for all calculations.",
  functions: [calculate],
});

const timeAgent = new Agent({
  name: "TimeSpecialist",
  model: "gpt-4o-mini",
  instructions:
    "You are a time expert. Use getCurrentTime to tell the current time.",
  functions: [getCurrentTime],
});

// Create main coordinator agent with sub-agents
const mainAgent = new Agent({
  name: "Assistant",
  model: "gpt-4o-mini",
  instructions: `You are a helpful coordinator. Route requests to specialists:
  - Weather questions → WeatherSpecialist
  - Math problems → MathSpecialist  
  - Time questions → TimeSpecialist`,
  subAgents: [weatherAgent, mathAgent, timeAgent],
});

const controller = new AgentController(client, {
  apiKeys: {
    serper: process.env.SERPER_API_KEY,
  },
});

// The controller will automatically transfer between agents
const response = await controller.run(mainAgent, [
  { role: "user", content: "What's the weather in Tokyo?" },
]);

console.log(response.messages[response.messages.length - 1].content);

// Export for playground
module.exports = { mainAgent, weatherAgent, mathAgent, timeAgent };
```

## Pre-built Tools

agents-js comes with several pre-built tools:

### Web Search & Scraping

```javascript
const {
  serperSearch,
  firecrawlSearch,
  firecrawlScrape,
} = require("agents-js/tools");

// Serper.dev web search (requires SERPER_API_KEY)
// Automatically falls back to Firecrawl if Serper key is missing

// Firecrawl web search (requires FIRECRAWL_API_KEY)
// Firecrawl web scraping
```

### Calculations & Time

```javascript
const {
  calculate,
  getCurrentTime,
  getTimestamp,
  formatDate,
} = require("agents-js/tools");
```

## MCP Server Integration

agents-js supports integration with [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) servers, allowing you to connect to any MCP-compatible tool server and use its tools seamlessly with your agents.

### Quick Start with MCP

Connect to the [Zomato MCP server](https://github.com/Zomato/mcp-server-manifest) for food ordering capabilities:

```javascript
const { connectMCPServer } = require("agents-js/tools");

// Connect to Zomato using mcp-remote (for HTTP-based MCP servers)
// Requires: npm install -g mcp-remote
const zomatoTools = await connectMCPServer(
  "zomato",
  "npx",
  ["-y", "mcp-remote", "https://mcp-server.zomato.com/mcp"]
);

// Use MCP tools with your agent
const foodAgent = new Agent({
  name: "FoodOrderingAssistant",
  model: "gpt-4o-mini",
  instructions: "You are a food ordering assistant powered by Zomato.",
  functions: zomatoTools, // MCP tools work just like built-in tools!
});
```

For local stdio-based MCP servers:

```javascript
const { connectMCPServer } = require("agents-js/tools");

// Connect to a local MCP server (e.g., filesystem)
const mcpTools = await connectMCPServer("filesystem", "npx", [
  "-y",
  "@modelcontextprotocol/server-filesystem",
  "/tmp",
]);
```

**Note:** HTTP-based MCP servers (like Zomato) require `mcp-remote` as a proxy. Install it with:
```bash
npm install -g mcp-remote
```

### Available MCP Functions

```javascript
const {
  connectMCPServer, // Connect to stdio-based MCP server
  connectMCPServerHTTP, // Connect to HTTP-based MCP server
  disconnectMCPServer, // Disconnect a specific server
  disconnectAllMCPServers, // Disconnect all servers
  getMCPManager, // Get manager for advanced usage
} = require("agents-js/tools");
```

### Mixing MCP Tools with Built-in Tools

```javascript
const { connectMCPServer } = require("agents-js/tools");
const { calculate, getCurrentTime } = require("agents-js/tools");

// Connect to Zomato MCP server using mcp-remote
const zomatoTools = await connectMCPServer(
  "zomato",
  "npx",
  ["-y", "mcp-remote", "https://mcp-server.zomato.com/mcp"]
);

// Combine with built-in tools
const agent = new Agent({
  name: "HybridAssistant",
  model: "gpt-4o-mini",
  instructions: "You have food ordering, calculation, and time capabilities.",
  functions: [...zomatoTools, calculate, getCurrentTime],
});
```

### Advanced MCP Usage

For more control, use the MCP Manager directly:

```javascript
const { getMCPManager } = require("agents-js/tools");
const mcpManager = getMCPManager();

// Connect to HTTP-based servers using mcp-remote
await mcpManager.connectStdio("zomato", "npx", [
  "-y",
  "mcp-remote",
  "https://mcp-server.zomato.com/mcp"
]);

// Connect to local stdio-based servers
await mcpManager.connectStdio("filesystem", "npx", [
  "-y",
  "@modelcontextprotocol/server-filesystem",
  "/tmp",
]);

// Get all tools from all servers
const allTools = mcpManager.getAllToolFunctions();

// Get tools from a specific server
const zomatoTools = mcpManager.getToolFunctions("zomato");

// Disconnect specific servers
await mcpManager.disconnect("zomato");
```

### Example MCP Servers

You can use any MCP-compatible server:

**HTTP-based servers (requires mcp-remote):**

First install mcp-remote:
```bash
npm install -g mcp-remote
```

Then connect to servers like:
- [Zomato Food Ordering](https://github.com/Zomato/mcp-server-manifest) - Restaurant discovery, menu browsing, food ordering
- And more in the [MCP Registry](https://github.com/modelcontextprotocol/servers)

**Stdio-based servers (local install):**

```bash
# Filesystem access
npm install -g @modelcontextprotocol/server-filesystem

# SQLite database
npm install -g @modelcontextprotocol/server-sqlite

# GitHub integration
npm install -g @modelcontextprotocol/server-github
```

### Complete Example

See [examples/mcp-integration.js](https://github.com/vgulerianb/agents-js/blob/main/examples/mcp-integration.js) for complete working examples.

## Advanced Features

### Lifecycle Hooks

```javascript
const agent = new Agent({
  name: "Assistant",
  model: "gpt-4o-mini",
  instructions: "You are helpful.",
  functions: [calculate],
  beforeModel: async (messages, contextVariables) => {
    console.log("📤 Sending to model:", messages.length, "messages");
  },
  afterModel: async (response, contextVariables) => {
    console.log("📥 Received from model");
  },
  beforeTool: async (toolName, args, contextVariables) => {
    console.log("🔧 Calling tool:", toolName);
  },
  afterTool: async (toolName, args, result, contextVariables) => {
    console.log("✅ Tool completed:", toolName);
  },
});
```

### Session Management

```javascript
const { Session } = require("agents-js");

const session = new Session();

// Store conversation state
session.set("user_name", "John");
session.set("preferences", { theme: "dark" });

// Retrieve state
const userName = session.get("user_name");

// Pass session in context
const response = await controller.run(agent, messages, {
  session: session,
});
```

### Tool Confirmation (Human-in-the-Loop)

```javascript
const { ToolConfirmation } = require("agents-js");

function dangerousOperation({ action }) {
  // Sensitive operation
  return `Executed: ${action}`;
}

const agent = new Agent({
  name: "Assistant",
  model: "gpt-4o-mini",
  instructions: "You are helpful.",
  functions: [
    new ToolConfirmation({
      tool: dangerousOperation,
      message: "This action is sensitive. Confirm?",
      autoConfirm: false,
    }),
  ],
});

const controller = new AgentController(client, {
  confirmationHandler: async (toolName, args, message) => {
    console.log(`Confirm ${toolName}?`, args);
    return true; // or false to cancel
  },
});
```

### Disable Logging

```javascript
const controller = new AgentController(client, {
  enableLogging: false, // Disable automatic logging
});
```

## Testing with Playground

Test your agents interactively with the playground:

```bash
# Install playground globally
npm install -g agents-playground

# Run with your agents file
npx agents-playground ./my-agents.js
```

The playground provides:

- 🎨 Beautiful chat interface
- 📊 Real-time token tracking
- 🔄 Agent transfer visualization
- 🔧 Environment variable management
- 📝 Detailed execution logs

## Examples

Check out the [examples directory](https://github.com/vgulerianb/agents-js/tree/main/examples) for complete working examples:

- **[basic-agent.js](https://github.com/vgulerianb/agents-js/blob/main/examples/basic-agent.js)** - Simple agent with tools
- **[multi-agent-system.js](https://github.com/vgulerianb/agents-js/blob/main/examples/multi-agent-system.js)** - Coordinator with specialized sub-agents
- **[advanced-features.js](https://github.com/vgulerianb/agents-js/blob/main/examples/advanced-features.js)** - Lifecycle hooks, sessions, and tool confirmation
- **[mcp-integration.js](https://github.com/vgulerianb/agents-js/blob/main/examples/mcp-integration.js)** - Integrate any MCP server with your agents
- **[subagents-parallel.js](https://github.com/vgulerianb/agents-js/blob/main/examples/subagents-parallel.js)** - Complex multi-agent coordination
- **[subagents-parallel-streaming.js](https://github.com/vgulerianb/agents-js/blob/main/examples/subagents-parallel-streaming.js)** - Streaming with multiple agents

### Running Examples

```bash
# Clone the repository
git clone https://github.com/vgulerianb/agents-js.git
cd agents-js

# Install dependencies
npm install
cd packages/agents-js
npm link

# Set up environment variables
cp .env.example .env
# Edit .env with your API keys

# Run an example
node examples/basic-agent.js

# Or test with playground
npx agents-playground examples/multi-agent-system.js
```

## API Reference

### Agent

```typescript
new Agent({
  name: string;
  model: string;
  instructions: string | ((context) => string);
  functions?: Function[];
  subAgents?: Agent[];
  parallelToolCalls?: boolean;
  beforeModel?: (messages, context) => Promise<void>;
  afterModel?: (response, context) => Promise<void>;
  beforeTool?: (toolName, args, context) => Promise<boolean | void>;
  afterTool?: (toolName, args, result, context) => Promise<void>;
});
```

### AgentController

```typescript
new AgentController(client: OpenAI, options?: {
  confirmationHandler?: (toolName, args, message) => Promise<boolean>;
  apiKeys?: Record<string, string>;
  enableLogging?: boolean;
});
```

### Result

```typescript
new Result({
  value: string;
  agent?: Agent;
  agentName?: string;
  contextVariables?: Record<string, any>;
});
```

## Environment Variables

Create a `.env` file:

```env
# OpenAI Configuration
OPENAI_API_KEY=your_openai_api_key
OPENAI_BASE_URL=https://api.openai.com/v1  # Optional

# External Tool API Keys
SERPER_API_KEY=your_serper_api_key  # Optional, for web search
FIRECRAWL_API_KEY=your_firecrawl_api_key  # Optional, for web scraping
```

## TypeScript Support

Full TypeScript definitions are included:

```typescript
import { Agent, AgentController, Result, Session } from "agents-js";
import { serperSearch, calculate } from "agents-js/tools";
```

## License

MIT © Vikrant Guleria

## Links

- [GitHub Repository](https://github.com/vgulerianb/agents-js)
- [npm Package](https://www.npmjs.com/package/agents-js)
- [Playground Package](https://www.npmjs.com/package/agents-playground)
- [Report Issues](https://github.com/vgulerianb/agents-js/issues)

## Contributing

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