dsh-a2a

Agent2Agent(A2A)v1.0.1 双端插件,用于 DeepSeek Harness — English · 中文

@hanphone/dsh-a2a 是一个独立开源的 A2A 插件,把 DeepSeek Harness profile 变成多面手 A2A 一等公民:能同时对外发布多个入站 A2A server,每个绑定一个自己的 agent preset、拥有独立端点 / AgentCard / 派生技能 / 鉴权;也能同时接入多个出站 A2A server,每个独立 preset,远端技能映射为模型工具。所有 server 实例的创建、启停、编辑、删除全部在 GUI 完成——无需改任何配置文件。

架构与设计决策:docs/architecture.md。 跟随 DeepSeek Harness 版本更新:docs/harness-compatibility.md。

功能

安装

从 npm

dsh plugin --profile web add @hanphone/dsh-a2a

任意 profile 名均可(web、自定义 profile、headless 等):

dsh plugin --profile <name> add @hanphone/dsh-a2a

本地构建安装

cd dsh-a2a
pnpm build
npm pack
dsh plugin --profile <name> add <path-to>/hanphone-dsh-a2a-<version>.tgz

快速开始

  1. 安装 — dsh plugin --profile web add @hanphone/dsh-a2a。
  2. 重启 GUI — 浏览器端插件表在 host 启动时扫描,装完请重启一次(pnpm dsh web 或对应 profile 启动命令)。
  3. 打开 设置 → A2A 连接 — 创建第一个入站 server(选 preset——技能自动派生——可选鉴权 env)。创建即时启用并发布自己的端点与 AgentCard。

每个入站 server 监听在 profile 的 webServer 上:

# 所建实例的 AgentCard(确切 id 见 GUI)
curl http://127.0.0.1:3080/a2a/<id>/agent-card.json

向实例发任务(其宣告的 chat 技能):

curl -X POST http://127.0.0.1:3080/a2a/<id> \
  -H "content-type: application/json" \
  -d '{"jsonrpc":"2.0","id":"1","method":"SendMessage","params":{"message":{"role":"user","parts":[{"text":"hello"}],"metadata":{"skill":"chat"}}}}'

GUI 面板

浏览器端在设置中注册 A2A 连接 页,分三个 Tab。无需改文件即可:

所有面板流量走 profile webServer 上的仅回环 /a2a/api 路由——远程对端永远无法驱动它。

配置

GUI 覆盖日常实例管理。插件 Config 只有宿主级默认值,如需覆盖可经 profile 用户 patch 层($DSH_HOME/profiles/<name>/cordis.patch.yml)设置:

- id: a2a
  config:
    baseUrl: http://127.0.0.1:<port>   # 省略则从 webServer 地址派生
    subagentProvider: in-process
    defaultTimeoutMs: 60000            # 出站连接默认超时

实例不经 patch 配置——它们在 GUI 中创建并持久化于 a2a 域(inbound_servers / outbound_servers 表)。

所需宿主服务

base 类 profile 全部挂载:webServer(@deepseek-ai/dsh-host-webserver)、存储栈(@deepseek-ai/dsh-storage + @deepseek-ai/dsh-storage-domain)、工具注册表(@deepseek-ai/dsh-tools)、agent 循环(@deepseek-ai/dsh-agent + @deepseek-ai/dsh-agent-loop)、agent presets(@deepseek-ai/dsh-agent-presets;preset 选择器与 preset 化会话组装需要它)。subagent 执行器还需要 @deepseek-ai/dsh-subagent。

存储后端

任务与实例存储位于 a2a 存储域。base 组合默认走 json 后端;要切 SQLite,在同一 patch 层路由域并加后端:

- id: storage-domain
  config:
    backend: json
    routes:
      a2a: sqlite
- insert:
    - id: storage-sqlite
      name: '@deepseek-ai/dsh-storage-sqlite'
      config:
        path: /absolute/path/to/a2a.sqlite

CLI

/a2a 聊天命令与面板对应(GUI 的文字备用路线):

a2a status | presets | peers |
    inbound list|create|remove|enable|disable |
    outbound list|create|remove|enable|disable|refresh |
    tasks | task get|cancel <id> |
    sessions | session cancel|close <contextId> | help

工作原理

完整设计见 docs/architecture.md。

目录结构

src/
  api.ts                  # 回环面板 API (/a2a/api、/a2a/api/presets)
  index.ts                # Cordis 插件入口 (apply)
  protocol.ts             # A2A v1.0.1 协议常量与类型
  jsonrpc.ts              # JSON-RPC 帧
  servers/                # 多实例管理器
    inbound-manager.ts    #   入站 server 实例(CRUD、路由、生命周期)
    outbound-manager.ts   #   出站连接实例(CRUD、工具)
  server/                 # 单实例内部件:store、card、a2a-server、
                          #   routes、executors、inbound-registry、session-registry
  outbound/               # 出站内部件:A2AClient、registry、tools
  client/                 # 浏览器半区:设置面板 (React)
  service.ts              # ctx.a2a 服务 facade
  commands.ts             # /a2a 聊天命令
tests/
  unit/                   # protocol、framing、card、store、registry、server、
                          #   client、api、inbound-registry、identity
  composition/            # 在真实 Cordis Context 上以 stub 宿主服务跑 apply()
  integration/            # 真 agent loop + JSONL 持久化 + mock LLM
  types/                  # 对真实 DSH 类型做编译期镜像检查
scripts/
  e2e-a2a.mjs             # 双实例 A2A hermetic 冒烟
docs/                     # 公开手册 + 架构/兼容性/测试
cordis.patch.yml          # bundle patch(挂载插件;实例由 GUI 管理)

文档

公开手册按当前行为展开:

深入文档:架构、 Harness 兼容性、 测试。

开发

插件通过项目引用对 harness 源码图做类型检查;需要已构建宿主聚合的 harness checkout。

pnpm typecheck   # host + client + 编译期镜像检查
pnpm test        # vitest run(单元 + 组合 + 真实持久化)
pnpm build       # tsc + tsdown → lib/index.js(host)+ lib/client.js(浏览器)
pnpm test:e2e    # 对已构建产物的双实例 A2A hermetic 冒烟
pnpm test:all    # typecheck + test + build + e2e

stub 测试看不见宿主运行时契约漂移。分层、各层能抓什么、e2e 流程见 docs/testing.zh.md。

致谢

本项目受 ryubyte/dsh-a2a 启发并与其并行开发——那是 DeepSeek Harness 上更早的 A2A 插件。其设计——双端范围、AgentCard 宣告、设置面板模式——为本文实现指明了方向。我们的协议层、任务存储与执行器接缝均为独立实现;GUI 管理模型则直接承袭了 ryubyte 的连接面板。

许可证

MIT