@ryubyte/dsh-a2a
Agent2Agent (A2A) protocol v1.0 plugin for DeepSeek Harness (DSH): outbound client (remote AgentCard skills as ctx.tools), inbound server (A2A JSON-RPC + AgentCard endpoint), and a settings dashboard of live A2A connections
安装
npx -p @deepseek-ai/dsh dsh plugin --profile web add github:ryubyte/dsh-a2a说明文档
阅读完整 README ↗Runtime configuration (a2a.json)
Configuration is driven by a2a.json (per profile, UI-editable) — manage
agents without touching the composition. The file is resolved from the active
profile, not the launch directory: the plugin parses --profile from
the process command line and reads/writes ~/.dsh/profiles//a2a.json.
Usage
1. Configure a remote agent (outbound)
Declare agents to connect to in the profile's a2a.json:
{
"agents": [
{
"name": "research",
"agentCardUrl": "https://research.example.com/.well-known/agent-card.json",
// "bearerToken": "...",
// "timeoutMs": 8000,
// "mapSkills": true,
// "enabled": false // keep the entry, but don't auto-connect
}
]
}
Alternatively, in the Web GUI go to 设置 → A2A 连接 → 添加 Agent, paste an
AgentCard URL to import and connect — the config is written back to
a2a.json.
Once connected, the remote agent's skills appear as model tools:
a2a____.
2. Expose this DSH as an A2A agent (inbound)
Enable server mode in a2a.json:
{
"mode": "server",
"server": {
"enabled": true, // explicitly turn the inbound server on
// "baseUrl": "http://127.0.0.1:3080", // optional; default: derive from webServer
"agentName": "My DSH Agent",
"agentDescription": "A DSH agent over A2A v1.0",
"agentVersion": "0.1.0",
"skills": [
{ "id": "coding", "name": "Coding", "description": "Execute coding and shell tasks.", "tags": ["coding", "shell"] }
]
}
}
Other A2A clients discover this DSH via
http://: /.well-known/agent-card.json and call the /a2a endpoint.
Note: the default inbound executor runs shell commands — fine for local testing only; for production, inject a constrained executor programmatically (see below) and put a TLS reverse proxy in front.
3. Programmatic use
import { A2AClient, A2AServer, TaskStore } from '@ryubyte/dsh-a2a';
// outbound: connect to a remote agent
const client = await A2AClient.connect('https://agent.example.com');
const { task } = await client.sendMessage({
messageId: crypto.randomUUID(),
role: 'ROLE_USER',
parts: [{ text: 'Draft a report' }],
});
for await (const ev of client.streamMessage({ messageId: crypto.randomUUID(), role: 'ROLE_USER', parts: [{ text: 'hi' }] })) {
// ev.statusUpdate | ev.artifactUpdate | ev.task | ev.message
}
// inbound: wire a custom executor to your own agent loop
const store = new TaskStore();
const server = new A2AServer({
baseUrl: 'http://127.0.0.1:3080',
agentName: 'My DSH',
agentDescription: '...',
agentVersion: '1.0.0',
execute: async ({ message }) => ({
messageId: crypto.randomUUID(),
role: 'ROLE_AGENT',
parts: [{ text: await myAgentRun(message.parts) }],
}),
}, store);