A2A Net JavaScript SDK
A JavaScript/TypeScript package with a pre-built Agent2Agent (A2A) Protocol Agent Executor for the OpenAI Agents JS SDK.
The package should allow you to create an A2A agent with the OpenAI SDK in 5 minutes, and is fully customisable. By default, the Agent Executor converts OpenAI SDK messages and tool calls into A2A compatible messages. The Agent Executor also accepts a "Task Agent" that reviews the conversation history, determines the TaskState (e.g. input-required, completed, failed, etc.), and extracts Artifacts. Because the OpenAI SDK doesn’t support sessions out-of-the-box, the library use…
A2A Net JavaScript SDK
A JavaScript/TypeScript package with a pre-built Agent2Agent (A2A) Protocol Agent Executor for the OpenAI Agents JS SDK.
The package should allow you to create an A2A agent with the OpenAI SDK in 5 minutes, and is fully customisable. By default, the Agent Executor converts OpenAI SDK messages and tool calls into A2A compatible messages. The Agent Executor also accepts a "Task Agent" that reviews the conversation history, determines the TaskState (e.g. input-required, completed, failed, etc.), and extracts Artifacts. Because the OpenAI SDK doesn’t support sessions out-of-the-box, the library uses @stackone/openai-agents-js-sessions which is based on OpenAI Agents Python SDK Sessions.
Test your agent with the Agent2Agent (A2A) UI, and add your deployed agent to A2A Net.
📋 Overview
A2A Support
-
Agent Executor
-
execute()method -
cancelTask()method -
Task State type
-
Artifact type
-
TextPartArtifact -
DataPartArtifact -
FilePartArtifact -
Streaming
-
Push notifications
Frameworks
OpenAI Agents JS SDK
run_item_stream_event
-
message_output_item -
output_text -
audio -
refusal -
image -
tool_call_item -
function_call -
hosted_tool_call -
computer_call -
tool_call_output_item -
function_call_result -
computer_call_result
Other
-
MCP (Model Context Protocol) servers
-
Hosted MCP tools
-
Streamable HTTP MCP servers
-
Stdio MCP servers
-
Sessions with @stackone/openai-agents-js-sessions
📦 Installation
npm install a2anet @openai/agents @a2a-js/sdk zod@3
Or with your preferred package manager:
yarn add a2anet @openai/agents @a2a-js/sdk zod@3
pnpm add a2anet @openai/agents @a2a-js/sdk zod@3
⚡ Quick Start
import express from "express";
import { Agent, tool } from "@openai/agents";
import { z } from "zod";
import { OpenAIAgentExecutor, StructuredResponseSchema } from "a2anet";
import type { AgentCard } from "@a2a-js/sdk";
import { DefaultRequestHandler, InMemoryTaskStore } from "@a2a-js/sdk/server";
import { A2AExpressApp } from "@a2a-js/sdk/server/express";
// Define a tool
const getWeather = tool({
name: "get_weather",
description: "Get the current weather for a city",
parameters: z.object({
city: z.string(),
}),
async execute({ city }) {
// In a real app, call a weather API
return `The weather in ${city} is sunny and 72°F`;
},
});
// 1. Create your main agent using OpenAI Agents SDK
const weatherAgent = new Agent({
name: "Weather Assistant",
instructions: `You are a helpful weather assistant.
When users ask about weather, use the get_weather tool.
Provide clear and friendly responses.`,
tools: [getWeather],
model: "gpt-4.1",
});
// 2. Create a task agent to determine task state and extract artifacts
const taskAgent = new Agent({
name: "Task Analyzer",
instructions: `Review the conversation and determine the task state.
Mark as 'completed' when:
- The user's weather question has been answered with specific information
- Extract the weather information as an artifact
Mark as 'input-required' when:
- The user hasn't specified which city they want weather for
- More clarification is needed
Mark as 'failed' if the weather lookup failed or returned an error.`,
outputType: StructuredResponseSchema,
model: "gpt-4.1",
});
// 3. Define your agent's identity card
const agentCard: AgentCard = {
name: "Weather Assistant",
description: "A helpful weather assistant that provides weather information for cities.",
protocolVersion: "0.3.0",
version: "0.1.0",
url: "http://localhost:4000/",
skills: [
{
id: "weather",
name: "Weather Information",
description: "Get current weather for a city",
tags: ["weather", "information"],
},
],
};
// 4. Create the A2A executor
const executor = new OpenAIAgentExecutor(weatherAgent, taskAgent, agentCard);
// 5. Set up and run the A2A server
const requestHandler = new DefaultRequestHandler(agentCard, new InMemoryTaskStore(), executor);
const appBuilder = new A2AExpressApp(requestHandler);
const expressApp = appBuilder.setupRoutes(express());
expressApp.listen(4000, () => {
console.log("🚀 Server started on http://localhost:4000");
});
🧩 Core Concepts
Agent Executor
The OpenAIAgentExecutor is the bridge between OpenAI Agents and the A2A protocol. It implements the A2A AgentExecutor interface and handles:
- Request Processing - Receives A2A protocol requests and converts them to OpenAI Agent inputs
- Event Streaming - Streams agent responses, tool calls, and task updates back to the client
- Session Management - Maintains conversation history across multiple turns
- Task State Detection - Uses a specialized "task agent" to determine task completion and extract results
Two-Agent Architecture
The executor uses two agents:
- Main Agent - Your actual AI agent that handles user requests, uses tools, and generates responses
- Task Agent - A specialized agent that analyzes the conversation to determine:
- Is the task complete, or does it need more input?
- What are the final artifacts/results?
- What is the task state (completed, failed, input-required, etc.)?
This separation allows your main agent to focus on the conversation while the task agent handles A2A protocol requirements.
Task States
The task agent can return these states:
completed- Task successfully finished (must include artifacts)input-required- Agent needs more information from the userfailed- Task failed to completerejected- Task was rejected (e.g., violates policy)auth-required- Task requires authentication
Other states like submitted, working, canceled, and unknown are handled automatically by the executor.
Artifacts
When a task is completed, the task agent must provide artifacts - the final outputs of the task. Artifacts can be:
- Text - Plain text or markdown
- Data - Structured JSON objects
// Example structured response from task agent
{
task_state: 'completed',
artifacts: [
{
name: 'Weather Report',
description: 'Current weather conditions for the requested location',
part: {
kind: 'data',
data: JSON.stringify({
temperature: 72,
conditions: 'sunny',
humidity: 45
})
}
}
]
}
🤖 OpenAI Agents JS SDK
Session Management
The executor supports conversation history through session providers. This uses @stackone/openai-agents-js-sessions, which is based on the OpenAI Agents Python SDK Sessions.
Using Sessions
import { InMemorySession } from "@stackone/openai-agents-js-sessions";
import { OpenAIAgentExecutor } from "a2anet";
// Create a session provider function
const sessionProvider = (sessionId: string) => {
return new InMemorySession(sessionId);
};
// Pass it to the executor
const executor = new OpenAIAgentExecutor(agent, taskAgent, agentCard, {
sessionProvider,
});
Available Session Backends
The @stackone/openai-agents-js-sessions package provides multiple storage backends:
InMemorySession
In-memory storage (data lost when process ends). Ideal for development and testing.
import { InMemorySession } from "@stackone/openai-agents-js-sessions";
const sessionProvider = (sessionId: string) => {
return new InMemorySession(sessionId);
};
SQLiteSession
SQLite-backed storage for persistent conversation history.
import { SQLiteSession } from "@stackone/openai-agents-js-sessions";
const sessionProvider = (sessionId: string) => {
return new SQLiteSession(sessionId, "conversations.db");
};
SequelizeSession
Sequelize-powered storage supporting PostgreSQL, MySQL, SQLite, and more.
import { SequelizeSession } from "@stackone/openai-agents-js-sessions";
import { Sequelize } from "sequelize";
// From URL (PostgreSQL)
const sessionProvider = async (sessionId: string) => {
return await SequelizeSession.fromUrl(sessionId, "postgres://user:pass@localhost:5432/mydb", {
createTables: true,
});
};
MCP Server Support
The executor supports Model Context Protocol (MCP) servers, allowing your agents to access external tools and data sources. Three types of MCP servers are supported:
Hosted MCP Tools
Hosted MCP tools are remote servers that the OpenAI Responses API invokes directly. Configure them on your Agent’s tools array - no lifecycle management needed:
import { Agent, hostedMcpTool } from "@openai/agents";
import { OpenAIAgentExecutor } from "a2anet";
const agent = new Agent({
name: "Documentation Assistant",
instructions: "Use the MCP tools to answer questions about the repository.",
tools: [
hostedMcpTool({
serverLabel: "gitmcp",
serverUrl: "https://gitmcp.io/openai/codex",
}),
],
});
const executor = new OpenAIAgentExecutor(agent, taskAgent, agentCard);
Streamable HTTP MCP Servers
For Streamable HTTP MCP servers (local or remote), pass them to the executor’s mcpServers option. The executor automatically handles connect() and close():
import { Agent, MCPServerStreamableHttp } from "@openai/agents";
import { OpenAIAgentExecutor } from "a2anet";
const mcpServer = new MCPServerStreamableHttp({
url: "https://example.com/mcp",
name: "My MCP Server",
});
const agent = new Agent({
name: "MCP Assistant",
instructions: "Use the tools to respond to user requests.",
mcpServers: [mcpServer],
});
const executor = new OpenAIAgentExecutor(agent, taskAgent, agentCard, {
mcpServers: [mcpServer],
});
Stdio MCP Servers
For local MCP servers that use standard I/O, use MCPServerStdio:
import { Agent, MCPServerStdio } from "@openai/agents";
import { OpenAIAgentExecutor } from "a2anet";
const mcpServer = new MCPServerStdio({
name: "Filesystem MCP Server",
fullCommand: "npx -y @modelcontextprotocol/server-filesystem /path/to/files",
});
const agent = new Agent({
name: "File Assistant",
instructions: "Use the tools to read files and answer questions.",
mcpServers: [mcpServer],
});
const executor = new OpenAIAgentExecutor(agent, taskAgent, agentCard, {
mcpServers: [mcpServer],
});
For more details on MCP, see the OpenAI Agents MCP documentation.
Tracing
The executor wraps all agent runs in an OpenAI Agents SDK trace context, which is required when using MCP servers. This enables tracing and debugging through the OpenAI Agents Tracing features.
📄 License
a2anet is distributed under the terms of the Apache-2.0 license.
🤝 Join the A2A Net Community
A2A Net is a site to find and share AI agents and open-source community. Join to share your A2A agents, ask questions, stay up-to-date with the latest A2A news, be the first to hear about open-source releases, tutorials, and more!
- 🌍 Site: https://a2anet.com/
- 🤖 Discord: https://discord.gg/674NGXpAjU