A2A protocol handler for Next.js. Translates AI SDK streams to A2A events.
npm install a2a-nextjsA2A protocol handler for Next.js. Translates AI SDK streams to A2A events.
``bash`
pnpm add a2a-nextjs @a2a-js/sdk
`typescript
// lib/agents/my-agent.ts
import { createAgent, InMemoryTaskStore } from "a2a-nextjs"
export const myAgent = createAgent({
card: {
name: "my-agent",
description: "A helpful assistant",
skills: [
{ id: "chat", name: "Chat", description: "General conversation" },
],
},
taskStore: new InMemoryTaskStore(),
execute: async (prompt) => {
// Return a ReadableStream
},
})
`
`typescript
// app/api/agent/route.ts
import { myAgent } from "@/lib/agents/my-agent"
export const POST = myAgent
`
`typescript
// app/.well-known/a2a/agent-card/route.ts
import { myAgent } from "@/lib/agents/my-agent"
export const GET = myAgent.cardHandler("/api/agent")
`
`typescript
// lib/agents/my-agent.ts
import { createAgent, InMemoryTaskStore } from "a2a-nextjs"
import { start, getRun } from "workflow/api"
import { runAgentWorkflow } from "@/lib/agent"
export const myAgent = createAgent({
card: {
name: "my-agent",
description: "A helpful assistant",
skills: [],
},
taskStore: new InMemoryTaskStore(),
execute: async (prompt) => {
const run = await start(runAgentWorkflow, [{ prompt }])
return getRun(run.runId).getReadable()
},
})
`
`typescript
// lib/agent.ts
import { DurableAgent } from "@workflow/ai/agent"
import { getWritable } from "workflow"
import type { UIMessageChunk } from "ai"
export async function runAgentWorkflow({ prompt }: { prompt: string }) {
"use workflow"
const writable = getWritable
const agent = new DurableAgent({
model: "anthropic/claude-sonnet-4",
system: "You are a helpful assistant.",
tools: {},
})
await agent.stream({
messages: [{ role: "user", content: prompt }],
writable,
})
}
`
Creates an agent handler.
Config:
- card - Agent metadata (name, description, skills)taskStore
- - Task persistence (InMemoryTaskStore or custom)execute
- - Returns ReadableStream
Returns a callable handler with:
- (request: Request) => Promise - POST handler.cardHandler(path)
- - Returns GET handler that builds card with full URL from request origin.buildCard({ url })
- - Build full AgentCard manually
`typescript
interface AgentCardConfig {
name: string
description: string
version?: string
protocolVersion?: string
skills?: AgentSkillConfig[]
capabilities?: Record
defaultInputModes?: string[]
defaultOutputModes?: string[]
}
interface UIMessageChunk {
type: string
delta?: string
toolCallId?: string
toolName?: string
output?: unknown
errorText?: string
}
``