Skip to content

Parasite Plugin

实现本地 Agent 与云端 Host Agent 的 NAT 穿透连接。

Host Agent 端

接收本地 Agent 注册:

typescript
import { createAgentServer, createParasiteHostPlugin } from '@multi-agent/a2a'

const hostPlugin = createParasiteHostPlugin()

const server = createAgentServer(config)
  .use(hostPlugin)

await server.start()

// 获取已注册 Agent
const agents = hostPlugin.getRegisteredAgents()

// 获取指定用户的 Agent
const userAgents = hostPlugin.getRegisteredAgentCards({
  namespace: 'user-123'
})

Tool Agent 端

主动连接到 Host:

typescript
import { createAgentServer, createParasitePlugin } from '@multi-agent/a2a'

const parasitePlugin = createParasitePlugin({
  hostAddress: 'a2a://cloud.example.com:50050',
  namespace: 'user-123',
  callbacks: {
    onRegistered: () => console.log('已连接'),
    onDisconnect: () => console.log('断开'),
    onReconnecting: (attempt) => console.log(`重连 ${attempt}`),
    onReconnected: () => console.log('重连成功'),
  }
})

const server = createAgentServer(config)
  .use(parasitePlugin)

await server.start()

配置选项

typescript
createParasitePlugin({
  hostAddress: string,   // Host Agent 地址,格式: a2a://host:port
  namespace?: string,    // 用户命名空间(隔离)
  callbacks?: {
    onRegistered?: () => void,
    onDisconnect?: () => void,
    onReconnecting?: (attempt: number, delay: number) => void,
    onReconnected?: () => void,
    onError?: (error: Error) => void,
  }
})

命名空间

用于多用户隔离:

tool-agent@user_a    // User A 的 Tool Agent
tool-agent@user_b    // User B 的 Tool Agent
typescript
// Tool Agent 注册
createParasitePlugin({
  hostAddress: 'a2a://cloud.example.com:50050',
  namespace: 'user-123'
})

// Host Agent 查询
const agents = hostPlugin.getRegisteredAgentCards({
  namespace: 'user-123'
})

工作流程

工作流程

完整示例

Host Agent

typescript
const hostPlugin = createParasiteHostPlugin()

async function executeHandler(params, ctx) {
  const userId = ctx.getMetadata<string>('x-user-id')

  // 获取用户的 Tool Agent
  const agents = hostPlugin.getRegisteredAgentCards({
    namespace: userId
  })

  if (agents.length === 0) {
    throw new Error('No tool agent')
  }

  // 转发调用
  const toolClient = createAgentClient({
    agentId: agents[0].agentId,
    address: 'a2a://localhost:50050',
    namespace: userId,
  })

  const stream = await toolClient.call('execute', params, {
    metadata: ctx.metadata
  })

  for await (const msg of stream) {
    ctx.stream.send(msg)
    if (msg.type === 'done') return msg.data
  }
}

const config: AgentConfig = {
  agentId: 'host-agent',
  // ...
  skills: [
    { name: 'execute', description: '执行命令', handler: executeHandler },
  ],
}

createAgentServer(config).use(hostPlugin).start()

Tool Agent

typescript
const parasitePlugin = createParasitePlugin({
  hostAddress: 'a2a://cloud.example.com:50050',
  namespace: process.env.USER_ID,
  callbacks: {
    onRegistered: () => console.log('Connected'),
    onReconnecting: (n) => console.log(`Reconnecting ${n}`),
  }
})

async function executeHandler(params, ctx) {
  const result = await exec(params.command)
  return { result }
}

const config: AgentConfig = {
  agentId: 'tool-agent',
  address: 'a2a://0.0.0.0:0',  // 动态端口
  skills: [
    { name: 'execute', description: '执行命令', handler: executeHandler },
  ],
}

createAgentServer(config).use(parasitePlugin).start()

API

typescript
// Host Plugin
hostPlugin.getRegisteredAgents()              // 获取命名空间列表
hostPlugin.getRegisteredAgentCards({ namespace }) // 获取 AgentCard

// Parasite Plugin
parasitePlugin.isRegistered()  // 是否已注册
parasitePlugin.detach()        // 断开连接

MIT Licensed