Skip to content
dsh.fish
Bundle

deepseek-harness-dingtalk

DingTalk Stream text, image, and file channel bridge for DeepSeek Harness

Source
sliverp
stars
3 stars
License
MIT
Updated
Updated 4 days ago

Readme

# DeepSeek Harness DingTalk plugin

A DeepSeek Harness channel powered by the official `dingtalk-stream` SDK. It uses Stream WebSocket delivery, so no public callback server is required; a Client ID and Client Secret are sufficient for an application robot.

## Features

- Official Stream WebSocket and heartbeat, with plugin-supervised reconnect that contains SDK promise failures
- Direct and group policies with allowlists
- Text, Markdown, rich-text, voice transcription, image, and ordinary-file input
- Official `downloadCode` retrieval for images and files; ordinary files are safely stored in the Agent workspace
- Model-aware multimodal input with text-only fallback metadata
- Native DingTalk Markdown replies plus generated-image and workspace-file upload
- Full Harness Agent Loop execution with structured tool events and final-visible-reply-only delivery
- Persistent, isolated sessions that restore their Agent preset and borrow an existing live Agent writer
- Same-conversation `/approve <code>` and `/reject <code>` decisions for one-shot tool approvals
- `/new`, registered Harness slash commands, `/bot-ping`, `/bot-help`, `/bot-image-test`, `/bot-file-test`, `/bot-status`, `/bot-cancel`
- Client Secret resolution through the Harness credential service
- Dormant startup when Client ID or Client Secret is not configured, so installation alone never blocks Harness Web

## Requirements

- Node.js 22.19 or later
- pnpm 10.33.4
- DeepSeek Harness 0.1.0-rc.7 or later

## Install

```sh
pnpm dsh plugin --profile web add github:sliverp/DeepSeek-harness-dingtalk
```

For a local checkout:

```sh
pnpm dsh plugin --profile web add /absolute/path/to/DeepSeek-harness-dingtalk
```

## Configure DingTalk

1. Open the [DingTalk developer console](https://open-dev.dingtalk.com/) and create an internal application.
2. Add the robot capability, or use DingTalk's official one-click OpenClaw robot application flow.
3. Copy the Client ID (formerly AppKey) and Client Secret (formerly AppSecret) from the credentials page.
4. Put the Client ID in `DINGTALK_CLIENT_ID` and store the Client Secret under the Harness credential reference `DINGTALK_CLIENT_SECRET`.

Environment injection is supported for development:

```sh
export DINGTALK_CLIENT_ID='ding_your-client-id'
export DINGTALK_CLIENT_SECRET='your-client-secret'
pnpm dsh --profile web
```

For durable use, put the Client ID in `~/.dsh/.env` and store the Client Secret through the Harness credential settings surface. Never commit credentials.

## Bundle configuration

```yaml
- id: dingtalk-channel
  name: deepseek-harness-dingtalk
  config:
    clientId: !!js process.env.DINGTALK_CLIENT_ID
    clientSecretRef: DINGTALK_CLIENT_SECRET
    cwd: !!js process.env.DSH_DINGTALK_CWD ?? process.cwd()
    agentPreset: standard
```

Restrictive production example:

```yaml
    singlePolicy: allowlist
    singleAllowFrom: [staff-id-1]
    groupPolicy: allowlist
    groupAllowChats: [conversation-id-1]
    imageInputMode: auto
    maxInboundFileBytes: 20971520
    maxOutboundFileBytes: 20971520
    approvalTimeoutMs: 240000
    reconnectDelayMs: 1000
```

Policies accept `open`, `allowlist`, or `disabled`. Combine allowlists with least-privilege Harness tool and workspace permissions.

Connection and authentication run in the background. Missing or invalid DingTalk credentials leave this channel offline and are logged without blocking Harness startup. The official SDK's built-in reconnect can leave endpoint-discovery failures as unhandled promises, so the plugin disables that path and supervises retries at `reconnectDelayMs` (1,000 milliseconds by default). Temporary DNS, authentication-endpoint, or WebSocket failures keep DingTalk offline and retrying without terminating Harness.

When Harness requests tool approval, the plugin sends a requester-bound six-digit code to the originating conversation. Reply `/approve <code>` to allow that operation once or `/reject <code>` to deny it. Codes are one-shot, cannot cross conversations, bypass ordinary message capacity while the original turn waits, and fail closed on timeout, cancellation, send failure, or shutdown. `approvalTimeoutMs` must remain below `responseTimeoutMs`.

## Verify

Send `/bot-ping`, `/bot-image-test`, and `/bot-file-test`. The bot should return `pong`, a blue diagnostic image, and a text file. Then send “What files do I have?” plus an image or ordinary file to verify tool, image, and file paths. Request an operation that needs approval and reply with the exact `/approve <code>` or `/reject <code>` shown; the same turn should continue or stop without using the Web approval panel.

To verify lifecycle isolation, temporarily make the DingTalk endpoint unreachable. The log should report supervised reconnect failures at `reconnectDelayMs` while Harness Web continues returning HTTP 200; DingTalk should reconnect on its own after network recovery.

## Session compatibility

Version `0.1.1` uses the new `dingtalk-v2` session namespace. Existing `dingtalk-v1` sessions are not deleted and remain in Harness persistence, but the channel no longer appends to those potentially polluted sessions. It starts with a clean v2 session instead. `/new` creates another durable session while retaining existing records.

## Security

- Stream callbacks are acknowledged immediately and business message IDs are deduplicated.
- A `sessionWebhook` is used only for its originating reply; it is not logged, persisted, or exposed to the model.
- Media transfer uses official DingTalk APIs, including authenticated HTTP/HTTPS signed download URLs, with count and byte limits for images and files.
- Inbound files use safe names and private directories. Outbound delivery accepts only explicitly linked regular files inside the current workspace and rejects symlink escapes.

## Develop

```sh
pnpm install
pnpm run check
pnpm pack
```

The repository uses PNPM `10.33.4`. Plugin runtime requires Node.js `>=22.19` and does not require PNPM 11.

Protocol, message, and media behavior were cross-checked against DingTalk's official [DingTalk-Real-AI/dingtalk-openclaw-connector](https://github.com/DingTalk-Real-AI/dingtalk-openclaw-connector) `v0.8.24`. MIT licensed.

Install

dsh plugin --profile web add github:sliverp/DeepSeek-harness-dingtalk

Profile: web

  • This package builds from source on install. pnpm will ask you to allow its build script — that is permission to run the package’s code on your machine, outside the agent sandbox. Only allow sources you trust.
  • This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.
Source