dsh-a2a

Concepts

English · 中文

This page defines the vocabulary the rest of the manual uses. It describes the current behavior of 0.4.0, including places where the implementation is narrower than the protocol.

1. A2A in one paragraph

Agent2Agent (A2A) is an HTTP + JSON-RPC protocol for one agent to call another. A server publishes an AgentCard describing its identity, endpoint, and skills; a client reads the card, sends a message to the endpoint, and waits for a task to settle (or subscribes to streaming updates). This plugin implements the A2A 1.0.1 JSON-RPC binding and declares protocol version 1.0. It does not implement the gRPC or HTTP+JSON bindings.

2. The two directions

Direction Who calls whom Plugin surface
Inbound A remote A2A client calls this DSH One inbound server per published agent
Outbound This DSH calls a remote A2A agent One outbound connection per remote card

The directions are independent. A profile can have zero or more of each, and they can point at other DSH instances or at non-DSH A2A agents.

3. Inbound server

An inbound server instance is a published agent. It owns:

Instances are created, edited, enabled, disabled, and deleted from the panel or the /a2a command. They are persisted; a restart re-assembles them and re-registers the enabled ones.

4. Outbound connection

An outbound connection instance is one remote agent this DSH can call. It owns:

On connect, the plugin fetches the card, imports its skills, and registers one tool per skill. A failed connection stays in the panel with its lastError and can be refreshed or edited.

5. Presets and skills

A preset is a DSH agent preset: a named composition of instructions, tools, skills, and model defaults. The inbound server binds one preset and composes a fresh DSH session from it for each A2A context.

Skills are derived, not typed. At create/update/boot, the plugin:

  1. resolves the preset and its standing scope;
  2. lists the skills visible to that preset;
  3. advertises the model-invocable entries on the AgentCard.

If the skills service or preset mount is unavailable, the card falls back to a single built-in chat skill. The same chat skill is the default routing target when a request omits message.metadata.skill.

A request whose metadata.skill is not in the advertised set is rejected by the skill gate before execution.

6. Tasks and contexts

An inbound SendMessage creates a task:

States follow the A2A vocabulary: 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. The last four are terminal; INPUT_REQUIRED and AUTH_REQUIRED are interrupted but not terminal.

A context is one conversation. The plugin keeps one live DSH session per context, with the deterministic id a2a-<contextId>. Reusing a contextId reuses that session; a different contextId opens a different one.

Session handles are memory-only. The panel’s Close action cancels the context’s active tasks and releases the live handle; the next task on the same contextId opens a fresh handle. Tasks and context→session bindings are persisted, so a restart keeps task history but does not resurrect sessions.

7. Executors

The inbound half has an executor seam with two implementations:

On the outbound side, the preset field is persisted and shown in the panel, but current tools call the remote directly: there is no local hand-off session composition behind it yet. Treat it as forward-looking metadata, not an active routing rule.

8. AgentCard

The card is a pure function of the instance record plus the advertised base URL and endpoint path:

The card is served as JSON at the instance’s cardPath. The well-known /.well-known/agent-card.json path is not used for instances; use the full per-instance URL printed by the panel.

9. Identity, storage, and sessions

Durable state lives in the a2a storage domain:

Table Contents
tasks Task records, including source instance id
contexts contextId → sessionId bindings
agents Per-outbound-instance agent records
identity Legacy service identity record
inbound_servers Inbound instance records
outbound_servers Outbound instance records

The default backend is the profile’s JSON storage; the a2a domain can be routed to SQLite. See Operations.

Inbound session working directories live under $DSH_HOME/a2a-sessions. Tasks and instances survive a restart; live sessions and stream subscriptions do not.

10. Security model

11. What this plugin is not