English · 中文
Work in this order; each step narrows the layer:
/a2a status returns a snapshot./a2a inbound list / outbound list.curl <cardUrl>.SendMessage with a tiny prompt./a2a tasks, /a2a task get <id>.$DSH_HOME/sessions.(no reply) or an empty artifactA completed task whose artifact is (no reply) means the inbound session
executor finished without an assistant message. In 0.3.6 this was a known
bug: the executor sent the agent a message with
source: { kind: 'plugin', plugin: 'a2a' }. The JSONL v4 session codec refuses
kind: 'plugin'; the write failed in the session handle’s background flush,
the agent loop contained the error, and the task settled COMPLETED with no
reply. Fixed in 0.3.7 by using the producer-owned { kind: 'a2a' }.
If you still see an empty reply on 0.3.7 or newer:
node -p "require('/path/to/profile/node_modules/@hanphone/dsh-a2a/package.json').version"
It must be 0.3.7 or newer. Reinstall and restart dsh web if not.
/a2a task get <taskId>
TASK_STATE_FAILED carries an error message; COMPLETED with an empty
artifact points back at the model/session layer.
contextId, and check whether the session is running or idle.a2a warnings in the DSH host log and in
$DSH_HOME/sessions/... for the a2a-<contextId> session.If the task is CANCELED, the caller or the panel canceled it; start a new
task on the same contextId to reopen the session.
The instance has a bearer token and the request does not match it.
Authorization: Bearer <token>.A2A_INBOUND_<ID> (uppercased, non-alphanumerics replaced by _);A2A_OUTBOUND_<ID>.200; a 401 is a clean
status, not a broken stream./a2a inbound list and the panel show the
enabled state. Enable it and retry./a2a/<id>/agent-card.json). The well-known
/.well-known/agent-card.json is not used for instances.curl -v http://127.0.0.1:3080/a2a/<id>/agent-card.json
/a2a/ prefix and preserves the Host header expected by the web app.failedThe panel shows lastError; the common causes are:
| Symptom | Check |
|---|---|
HTTP 401 |
Remote requires a token; edit the connection and set it |
HTTP 404 |
Wrong card URL; use the remote’s full per-instance card path |
invalid agent card |
The URL returns HTML or a non-card JSON; verify content type and shape |
no JSON-RPC interface |
The card has no supportedInterfaces entry with a JSON-RPC URL |
| timeout | Raise the connection’s timeoutMs or check network reachability |
| TLS/DNS error | Check the remote certificate/hostname and local network |
After fixing, click Refresh (or call outbound.refresh). A failed record is
kept so you can edit it; deleting and re-adding is not required.
connected and skillCount > 0, toolCount > 0.
A card with zero skills registers zero tools by design.a2a__<connection-name>__<skill-id>, normalized to
[A-Za-z0-9_-] and truncated to 64 characters. If the remote name has
spaces or punctuation, inspect the actual registered name in the model’s
tool list or ask the model to list its tools.{ "prompt": "..." }, not a bare string.FAILED remote task
raises a tool error with the remote message; INPUT_REQUIRED /
AUTH_REQUIRED are returned as text.The remote agent’s task settled non-terminal or failed. Use the remote’s own
GetTask/panel to inspect it, or check the tool error text:
(remote agent returned no output) — the remote completed with no artifacts.Remote agent task failed: ... — the remote reported TASK_STATE_FAILED.[remote agent INPUT_REQUIRED] ... — the remote needs more input; send a
follow-up prompt.[remote agent AUTH_REQUIRED] ... — the remote needs authentication; update
the connection token.incompatible-version or the plugin is not loadedDSH 0.1.7+ evaluates the plugin’s @deepseek-ai/dsh and
@deepseek-ai/dsh-* peer ranges before importing it. A refusal means the
running harness is outside the declared ranges.
package.json and the verification record in
Harness compatibility.dsh plugin allow-version ... --accept-risk is an explicit, exact-version
exemption for an emergency; it is not a substitute for testing.The a2a domain is a single store rooted at DSH_HOME (JSON by default). Two
processes sharing the same home write the same domain and can overwrite each
other’s instances/tasks. Run one writer per DSH_HOME; use separate homes and
ports for two-instance tests. This is exactly what the hermetic e2e does.
Accept: text/event-stream on the POST. Without it, the
server handles the request as non-streaming JSON-RPC.SendStreamingMessage and SubscribeToTask are valid on the streaming
path; other methods return a method-not-found error frame.data: lines; use curl -N and do not buffer.SendMessage remains blocking even if the caller expects streaming; choose
the streaming method explicitly.returnImmediately and historyLength are implemented; history is reconstructed from the durable task input/output.GetTask returns no history array.subagent executor is not selected by the default skill map.preset is metadata; there is no local hand-off session yet.Please attach:
0.4.0), harness version, and OS;/a2a task get <id>) and the AgentCard;a2a-<contextId> session log path;lastError text.The automated layers that guard these paths are described in Testing. If you are contributing a fix, add the failing assertion to the layer that can see it: mirror check for a type contract, real-persistence integration for a durable-session shape, or the e2e smoke for a released-artifact path.