DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

HangZhouXi /

HangZhouXi/dsh-xiaoyi

Verified

Turn your phone's Huawei XiaoYi into a remote control for the DSH agent on your own PC. DSH (DeepSeek Harness) host plugin for XiaoYi OpenClaw mode: zero third-party deps, hand-written RFC6455 WebSocket client, AK/SK auth, heartbeat, A2A streaming, SSRF-hardened inbound attachments.

★ 0 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHub
READMESource: master@921ebcf8

dsh-xiaoyi

English | 简体中文

A DSH (DeepSeek Harness) host plugin that connects Huawei XiaoYi in OpenClaw mode to your local DSH session — voice, text and images from your phone reach the agent running on your own machine.

This is not a standalone chatbot. XiaoYi is only the entry point; what it connects to is your local DSH session (same tools, same working directory). There is no second agent.

Huawei XiaoYi on your phone  (anywhere)
   │  voice / text / images
   ▼
Huawei Cloud  wss://hag.cloud.huawei.com/openclaw/v1/ws/link
   │  long-lived connection (AK/SK auth + 30s heartbeat)
   ▼
This plugin  (runs inside the DSH host process)
   │
   ▼
DSH session  xiaoyi-listen-*

Prerequisites

This is not plug-and-play. Before installing, make sure you have all three:

# Requirement Notes
1 A DSH host DSH = DeepSeek Harness. This is a host-side plugin; without a host it cannot run.
2 XiaoYi Open Platform credentials (OpenClaw mode) You need AK / SK / agentId. These are Huawei Cloud developer credentials you must apply for yourself on the XiaoYi Open Platform.
3 Node.js ≥ 20 The code uses the built-in fetch / FormData / Blob. Developed on Node 24.

If you cannot obtain item 2, you can still read this repository as a protocol reference implementation — index.js implements the XiaoYi/OpenClaw handshake, auth, heartbeat and JSON-RPC message exchange in full.

Where do AK / SK / agentId come from?

They are issued by Huawei. This project cannot create them for you and cannot tell you whether your account is eligible. You have to apply for them yourself:

  1. Register a Huawei developer account and complete real-name verification — https://developer.huawei.com/consumer/cn/register/
  2. Sign in to the XiaoYi Open Platform and create an agent — https://developer.huawei.com/consumer/cn/hag/hagindex.html#/ When creating it, choose the OpenClaw mode. Other modes are not compatible with this plugin.
  3. Take the values from the agent's detail page:
    • agentId — shown in the AgentCard block;
    • AK / SK — under Credentials → New credential. The SK is displayed only once, so copy it immediately.
  4. Add your own Huawei account to the agent's test whitelist. Until the agent is published, only whitelisted accounts can reach it; it takes effect after a few minutes.
  5. Official documentation for this mode — https://developer.huawei.com/consumer/cn/doc/doccenter-celia/openclaw-0000002518410344

Menu names, entry points and the review process are decided entirely by Huawei and may change at any time. If a step above no longer matches what you see, follow Huawei's own documentation rather than this file. This plugin only consumes the three credentials. It never asks Huawei for anything else on your behalf.


Features

  • Zero third-party dependencies. Only Node built-ins are used, including a hand-written minimal WebSocket client (RFC6455 client side: text frames, fragmentation reassembly, ping/pong, and handshake verification). Fewer packages in the plugin tree means fewer chances that one failed package takes the whole host down.
  • Complete protocol implementation. Auth signing, init handshake, heartbeat with stale-connection detection, JSON-RPC 2.0 streaming, and control messages (clearContext / tasks/cancel).
  • Inbound attachments. Images and files sent from XiaoYi are downloaded to disk, and their local paths are handed to the agent in the session (ready for read_image / read).
  • Outbound online files (experimental). Send local files back to XiaoYi (the protocol only accepts public https URLs; supports a local tunnel or a third-party image host). See the direction table below — this direction is not reliable.
  • Session reuse. On a cold start the plugin resumes the existing session instead of opening a new conversation every time.

What can travel in each direction

Direction Support
Phone → this plugin
(what you send to XiaoYi)
Text, voice (transcribed) and images/files all work. Attachments are downloaded to ~/.dsh/xiaoyi/media/ and their local paths are handed to the agent.
This plugin → phone
(what you get back in XiaoYi)
Text works — the reply body, plus anything sent with xiaoyi_send. Pushing an image or file back to the phone is unreliable: the protocol accepts only a public https URL, and the XiaoYi client is not guaranteed to render the file part. Treat xiaoyi_send_photo as experimental.

In short: the inbound direction is the reliable one. If your workflow depends on images or files arriving on your phone, do not rely on it.


Installation

1. Place the source

Put this directory anywhere you keep plugins. The conventional location is:

~/.dsh/plugin-sources/dsh-xiaoyi

2. Register it in your profile

Option A (recommended, one command):

# install from the GitHub repository
dsh plugin --profile web add git+https://github.com/HangZhouXi/dsh-xiaoyi

# or from npm (after it is published there)
dsh plugin --profile web add dsh-xiaoyi

Option B (edit by hand):

Edit ~/.dsh/profiles/web/package.json:

{
  "dsh": {
    "profile": {
      "bundles": [
        // ...
        "dsh-xiaoyi"          // ← add to bundles
      ]
    }
  },
  "dependencies": {
    // ...
    "dsh-xiaoyi": "git+file:///C:/Users/<you>/.dsh/plugin-sources/dsh-xiaoyi"
  }
}

A plain local path dependency also works: "dsh-xiaoyi": "file:../../plugin-sources/dsh-xiaoyi".

3. Install and cold-start

dsh plugin --profile web install

Then cold-start the DSH host. (Host-side plugins are not applied by hot reload — a cold start is required.)

4. Provide credentials

Edit ~/.dsh/xiaoyi/state.json:

{
  "enabled": true,
  "ak": "XiaoYi Open Platform AK",
  "sk": "XiaoYi Open Platform SK",
  "agentId": "agentId of your OpenClaw-mode agent",
  "wsUrl": "wss://hag.cloud.huawei.com/openclaw/v1/ws/link",
  "sessionId": "",
  "cwd": "C:\\Users\\<you>\\Desktop",
  "publicBaseUrl": "",
  "imageHost": ""
}
Field Purpose
enabled Master switch. false disconnects the channel.
ak / sk / agentId XiaoYi Open Platform credentials. All three are required.
wsUrl WebSocket endpoint. Leave as the default unless Huawei changes it.
sessionId The DSH session to reuse. Normally written by the plugin itself.
cwd Working directory for the session. Must be writable.
publicBaseUrl Only for outbound files in local mode: the public https base URL of your tunnel.
imageHost Optional default publisher for outbound files. Set "catbox" to make catbox.moe the default; leave empty to stay local-only.

You can also let the agent configure these at runtime with the xiaoyi_set tool (changes take effect immediately and reconnect).

Log file: ~/.dsh/xiaoyi/xiaoyi.log


Agent tools

Tool Purpose
xiaoyi_status Channel status: whether credentials are complete, whether the WebSocket is connected, the listening session id, queue length, last error, message counters.
xiaoyi_set Update credentials / switch (ak, sk, agentId, wsUrl, enabled). Takes effect immediately on the live connection.
xiaoyi_send Push a short message to the current XiaoYi conversation (useful as a long-task completion notice).
xiaoyi_send_photo Send a local image or file to XiaoYi (the protocol only accepts public https; see "Outbound files" below).
xiaoyi_reconnect Force a disconnect and reconnect (after changing credentials, or when the link looks stale).

HTTP routes

Path Purpose
GET /xiaoyi/state JSON status.
GET /xiaoyi/connect Start the channel and make sure the listening session is ready.
GET /xiaoyi/disconnect Stop the channel.
GET /xiaoyi/public/<filename> Serves published outbound files. Filenames carry a random component and are not guessable.

Protocol summary

Verified against the published artifacts of @ynhcj/xiaoyi. This project does not depend on that package.

Stage Detail
Endpoint wss://hag.cloud.huawei.com/openclaw/v1/ws/link
Auth headers x-access-key=AK, x-sign=Base64(HMAC-SHA256(SK, ts)), x-ts=milliseconds, x-agent-id=agentId
Handshake {"msgType":"clawd_bot_init","agentId":"..."}
Heartbeat Every 30s {"msgType":"heartbeat","agentId":"...","timestamp":...} plus a protocol-level ping
Inbound JSON-RPC 2.0, method="message/stream"; sessionId=params.sessionId, taskId=params.id, messageId=top-level id; text in params.message.parts[kind=text].text, attachments in parts[kind=file].file{name,mimeType,uri}
Outbound {"msgType":"agent_response", agentId, sessionId, taskId, msgDetail:"<JSON-RPC string>"}
Outbound frame kinds result.kind="status-update" (acknowledge with state=working), result.kind="artifact-update" (the body, closed with lastChunk=true, final=true)
Control clearContext / tasks/cancel / action="clear" → reply with the matching JSON-RPC response

Outbound files (xiaoyi_send_photo)

The Part sent back to the client is { url, filename, mediaType } — only public https URLs are accepted; there is no "upload bytes" interface. Hence two modes:

mode Behaviour Privacy
local (default) The file is copied to ~/.dsh/xiaoyi/public/ and served by this plugin's own route; pair it with a tunnel (e.g. localhost.run) and point state.publicBaseUrl at it. The file never leaves your machine (except through your tunnel).
catbox Uploads to the third-party host catbox.moe. The file is sent to a third party. Must be requested explicitly.

local mode requires state.publicBaseUrl; without it the tool returns an error and never silently falls back to an image host.


Security and privacy

  • Credentials stay local. They live in ~/.dsh/xiaoyi/state.json, which is excluded by .gitignore. They are never committed and never logged (the log only records whether a value is present).
  • Inbound attachments are protected against SSRF. The inbound uri comes from an external message and is treated as untrusted input. Only http/https is allowed. Every hop of a redirect chain is checked before it is fetched (redirect: 'manual'), and each host is judged two ways: structurally, and by what it actually resolves to. IPv6 addresses are parsed into bytes rather than compared as strings, so equivalent spellings cannot slip through. Blocked ranges: loopback, private, link-local, unique-local, multicast, site-local, IPv4-mapped (::ffff:a.b.c.d), NAT64, 6to4 and Teredo — including cloud metadata endpoints such as 169.254.169.254.
  • Attachments are size-capped. 50 MB per file, read as a stream, so a lying content-length cannot exhaust memory.
  • Published URLs are unguessable. Filenames include 8 random bytes.
  • ⚠️ The HTTP routes themselves have no authentication. /xiaoyi/state and /xiaoyi/public/* are reachable by anyone who can reach the port. Do not expose the DSH port directly to the internet; if you use a tunnel, prefer one with authentication or an unguessable hostname.

Known limitations

  • A file or image cannot be pushed back to the phone reliably. The protocol only accepts a public https URL for outbound files, and whether the XiaoYi client renders the resulting file part is outside this project's control. Text replies are unaffected.
  • Outbound attachments must use a public URL. This is a protocol constraint, not a shortcut in the implementation.
  • Inbound attachment URLs are pre-signed and expire in roughly 30 minutes, so they must be fetched immediately. This plugin does exactly that; if a download fails, the link has most likely expired.
  • The media/ directory is never cleaned automatically. Prune ~/.dsh/xiaoyi/media/ yourself periodically.
  • Platform-side policies may change. OpenClaw mode, endpoints and field names can be adjusted by Huawei at any time; long-term availability is not guaranteed.

Uninstall

  1. Remove dsh-xiaoyi from bundles and dependencies in ~/.dsh/profiles/web/package.json.
  2. dsh plugin --profile web install
  3. Cold-start the host.
  4. For a complete cleanup, delete ~/.dsh/xiaoyi/ (it contains credentials and logs).

Troubleshooting

Symptom What to check
Nothing happens after installing Did you cold-start? Host-side plugins are not applied by hot reload.
status reports ready:false One of AK / SK / agentId is missing.
Cannot connect, lastError mentions a handshake failure Is wsUrl correct? Can the machine reach hag.cloud.huawei.com:443?
Connects then keeps reconnecting Look for "stale connection" in the log; if nothing (including pong) arrives for over 90 seconds the plugin reconnects on purpose.
XiaoYi messages get no reply Check ~/.dsh/xiaoyi/xiaoyi.log and confirm in the host log that the plugin loaded.
Reply says the DSH session is not ready The very first request after a host start has to create the session; send the message again shortly after.
Sent images do not arrive This direction is unreliable by design — see "What can travel in each direction". The protocol also requires a public https URL, so check publicBaseUrl and whether your tunnel is still alive.

License

MIT

Disclaimer

Please read DISCLAIMER.md before use.

—/ 5

No ratings yet

Verified DSH bundle

Commit 921ebcf8c24e

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout