English · 中文
本页定义手册后面会用到的术语,描述 0.4.0 的当前行为——也包括实现比协议更窄的地方。
Agent2Agent(A2A)是让一个 agent 通过 HTTP + JSON-RPC 调用另一个 agent 的协议。
server 发布 AgentCard,描述身份、端点和技能;client 读取卡片,向端点发消息,
等待任务落定(或订阅流式更新)。本插件实现 A2A 1.0.1 的 JSON-RPC 绑定,
声明协议版本 1.0;不实现 gRPC 或 HTTP+JSON 绑定。
| 方向 | 谁调用谁 | 插件面 |
|---|---|---|
| 入站 | 远端 A2A 客户端调用这个 DSH | 每个被发布的 agent 一个入站 server |
| 出站 | 这个 DSH 调用远端 A2A agent | 每张远端卡片一个出站连接 |
两个方向互相独立。一个 profile 可以有任意多个入站和出站,也可以指向其他 DSH 实例或非 DSH 的 A2A agent。
一个入站 server 实例就是一个被发布的 agent,拥有:
/a2a/<id>;/a2a/<id>/agent-card.json;实例在面板或 /a2a 命令里创建、编辑、启停、删除,并持久化;重启后会重新组装,
并重新注册已启用的实例。
一个出站连接就是“这个 DSH 可以调用的一个远端 agent”,拥有:
连接时插件读取卡片、导入技能、按技能注册工具。连接失败会保留在面板里,显示 lastError,
可以刷新或编辑。
Preset 是 DSH 的 agent 预设:命名的一套指令、工具、技能和模型默认值组合。 入站 server 绑定一个 preset,并为每个 A2A 上下文用该 preset 组装一个新的 DSH 会话。
技能是派生的,不是手写的。 创建/更新/启动时,插件:
如果 skills 服务或 preset 挂载不可用,卡片回退到内置的单个 chat 技能。
请求省略 message.metadata.skill 时,也默认路由到 chat。
如果请求的 metadata.skill 不在宣告集合里,技能门禁会在执行前拒绝。
入站 SendMessage 会创建一个任务:
a2a-<uuid>;状态使用 A2A 词汇:TASK_STATE_SUBMITTED、TASK_STATE_WORKING、
TASK_STATE_INPUT_REQUIRED、TASK_STATE_AUTH_REQUIRED、
TASK_STATE_COMPLETED、TASK_STATE_FAILED、TASK_STATE_CANCELED、
TASK_STATE_REJECTED。后四个是终态;INPUT_REQUIRED 和 AUTH_REQUIRED
是中断态,但不是终态。
上下文是一条对话。插件为每个上下文保留一个活跃 DSH 会话,
id 固定为 a2a-<contextId>。复用同一个 contextId 就复用该会话;不同的
contextId 会打开不同会话。
会话句柄只在内存里。面板的关闭会取消该上下文所有活跃任务并释放活跃句柄;
同一 contextId 的下一个任务会重新打开一个新句柄。任务和 context→session 绑定会持久化,
所以重启保留任务历史,但不会复活会话。
入站侧有一层执行器接缝,两个实现:
ctx.subagents 时会接线,但当前默认技能→执行器表只把 chat 绑到 session,
未知技能也默认 session;今天没有公开配置能选中 subagent。出站侧的 preset 字段会持久化并显示在面板里,但当前工具是直接调用远端:
背后还没有本地衔接会话的组装。把它当成前瞻性元数据,不是当前生效的路由规则。
卡片是实例记录 + 对外 base URL + 端点路径的纯函数:
name、description、version 来自实例;provider 固定为 DeepSeek;capabilities:streaming true、push notifications false、extended card true、
state-transition history false;defaultInputModes / defaultOutputModes:text/plain;skills:派生出的技能列表;supportedInterfaces:一个 JSON-RPC 接口,指向实例端点,协议版本 1.0;bearer 安全方案与要求,但不含任何密钥值。卡片以 JSON 形式在实例的 cardPath 提供。实例不使用 /.well-known/agent-card.json;
请用面板给出的完整 per-instance URL。
持久状态在 a2a 存储域:
| 表 | 内容 |
|---|---|
tasks |
任务记录,含来源实例 id |
contexts |
contextId → sessionId 绑定 |
agents |
每个出站实例的 agent 记录 |
identity |
旧版服务身份记录 |
inbound_servers |
入站实例记录 |
outbound_servers |
出站实例记录 |
默认后端是 profile 的 JSON 存储;a2a 域可以路由到 SQLite。见
运维指南。
入站会话的工作目录在 $DSH_HOME/a2a-sessions。任务与实例跨重启保留;
活跃会话与流订阅不保留。
/a2a/api 只接受 127.0.0.1、::1、::ffff:127.0.0.1;
其他来源直接 403。远端 A2A 客户端能调协议端点,但永远驱动不了控制面板。A2A_INBOUND_<id>、A2A_OUTBOUND_<id>);实例记录只存变量名,
AgentCard 只存方案。Authorization: Bearer <token>,
否则返回 401 和 WWW-Authenticate: Bearer。流式请求在写 200 SSE 头之前先鉴权。