Introduction¶
Running a long DSH session, the most troublesome issue isn’t a slow task, but it quietly stopping to wait on you: the model calling ask_user_question waiting for an answer, tools requesting approval for sandbox upgrades, turns ending directly due to model 4xx errors — while you are doing other things, you return after ten minutes and realize it stopped long ago.
dsh-lark-bridge solves this problem: it calls lark-cli in real-time when a DSH session stops working, aiming to achieve “DSH stops working = must receive notification”. Compared to existing methods (polling the screen, or scripts covering single events), it incorporates waiting for interaction, task completion, being blocked, request backoff, process stagnation, and process death into the same notification system.
What is it¶
dsh-lark-bridge is a DeepSeek Harness plugin maintained by leo-lab-2026, licensed under MIT, current version 0.3.0-beta.0. It is a pure read-only observer: it only listens to the DSH persistent event stream and agent/status lifecycle, does not intercept any execution chain, and does not answer any approval/questions. When lark-cli is missing or fails to send, it fails-softly — it only alerts, never affecting DSH itself.
Scenarios Covered by “Stopping Work”¶
| Category | Trigger | Notification Timing |
|---|---|---|
| Permission Requests | Tool requesting approval (e.g., sandbox upgrade) | During waiting for approval (won’t disturb if approved within ~0.5s grace period) |
| Asking User | Model calls ask_user_question (including plan mode plan review) |
During waiting for answer |
| Error-induced Stop | Turn ends with fatal error (model 400/401/403/quota/retry exhausted, etc. 4xx-5xx) | Immediately, throttled to once per 5 minutes per session |
| Task Completion | Turn ends with completed and agent enters idle (5s grace period filters goal auto-looping//loop) |
After idle grace period, throttled to once per 30 minutes per session |
| Goal Blocked | turn/end blocked (goal blocked / pre-step rejected) |
After idle grace period |
| Token Limit | turn/end max-tokens |
After idle grace period |
| Turn Aborted / Exceptional Interrupt Closure | turn/end aborted and interrupted (crashed orphan turns close on reload) |
After idle grace period |
| Request Backoff | llm/retry event reaches retry threshold (default starting from the 2nd time) |
Sent as soon as threshold is reached, throttled to once per 5 minutes per session |
| No Progress Stagnation | Agent stays running but no events for default 10 minutes |
Sent upon determination, default 60-minute recurring reminders |
| Normal Exit | Plugin dispose (only when entire app tree is unloaded, HMR/reload doesn’t trigger false positives) | Farewell notification on exit |
| Process Death | Heartbeat file + external process monitor detects heartbeat loss | Sent when heartbeat timeout |
All notification categories have independent switches, all enabled by default. Noise is controlled by grace periods and throttling. The first line of notifications defaults to Workspace: {workspace}, allowing easy identification of the source when multiple projects run in parallel.
Installation and Enablement¶
Prerequisites: Node ^22.19 || >=24, pnpm, DeepSeek Harness (dsh).
dsh plugin --profile <name> add dsh-lark-bridge
You can also install from GitHub source code (requires authorization for build scripts):
dsh plugin --profile <name> add github:<you>/dsh-lark-bridge#<sha>
Verify installation before restarting:
dsh --profile <name> --dump-config # dsh-lark-notify line should appear in the output
Note on updates: For minor versions/patches within the same semver range, use update; for cross-version or installing pre-release versions (e.g., current 0.3.0-beta.0), use add with an explicit version number:
dsh plugin --profile <name> list dsh-lark-bridge # View currently installed version
dsh plugin --profile <name> update dsh-lark-bridge # Update within range
dsh plugin --profile <name> add dsh-lark-bridge@0.2.0-beta.1 # Cross-version/pre-release upgrade
You need to restart dsh after updating the plugin for changes to take effect.
First-time Configuration (3 Steps)¶
1. Prepare Lark App and lark-cli¶
- Create an enterprise self-built app on the Lark Open Platform, get App ID and App Secret, and enable the bot in “Application Capabilities”;
- Enable message sending permissions in “Permission Management” (
im:messageorim:message:send_as_bot); if you want to usesetupfor automatic configuration, you also need to enableim.message.receive_v1event subscription and permissions likeim:message.p2p_msg:readonly; - Install and configure lark-cli (credentials are stored in lark-cli itself; the plugin never touches the App Secret):
npx @larksuite/cli@latest install
lark-cli config init
lark-cli auth status -- --verify
2. Configure Notification Target¶
After plugin installation, there is no notification target by default, so you need to specify it once and persist it to settings.yaml. It is recommended to run this inside a DSH session:
/lark-notify setup
Then go to Lark and send any message to the bot (default 3-minute window). The plugin will automatically capture the session chat_id and write it to settings, while sending a test notification to confirm the link. You can also manually fill in chatId in the DSH Web settings panel, or write YAML in the profile’s cordis.patch.yml as a deployment default. Configuration priority: Web settings panel (user layer) > YAML (deployment layer) > Default.
3. Verify¶
/lark-notify test 你好 # Send test notification
/lark-notify status # One-click diagnosis: notification target, lark-cli status, send stats, enabled categories
Trigger a couple of real scenarios (let the model request approval once, call ask_user_question, create a retry backoff), and you should receive the corresponding notifications in Lark.
Route Notifications by Workspace (Optional)¶
When one project corresponds to one Lark group, you can have notifications for each workspace sent to their respective groups. Run the following in the DSH session corresponding to the target workspace:
/lark-notify route
Then go to the target Lark group and send any message to the bot (the bot needs to have been added to that group first, default 3-minute window). The plugin will complete the binding of “current workspace -> that group” and reply with a test notification. For CI/batch scenarios, you can write a routing map in cordis.patch.yml to match by workspace title exactly, with a fallback path match; notifications that are not bound will go to the global default target and won’t be lost.
Process Death Watchdog (Optional)¶
Process internal observers cannot report their own death (OOM/crash/mis-killed). The plugin supports writing a heartbeat file, combined with an external process monitor script to cover this case:
config:
watchdog:
enabled: true
heartbeatFile: '/tmp/dsh-heartbeat' # Updated by plugin every 5s
The watchdog script has two running modes:
# Daemon mode (checks every staleMs/4 by default)
node scripts/lark-watchdog.mjs --heartbeat-file /tmp/dsh-heartbeat --stale-ms 60000 --chat-id oc_xxx
# Cron / systemd timer mode
node scripts/lark-watchdog.mjs --heartbeat-file /tmp/dsh-heartbeat --stale-ms 60000 --chat-id oc_xxx --once
A “DSH Process Death” notification is sent when heartbeat loss exceeds stale-ms. Same death events are deduplicated by --repeat-ms (default 60 minutes).
Use Cases and Notes¶
Suitable for people using DSH as a long-term background worker: running a pile of sessions with tasks, multiple workspaces in parallel, or batch processing in unattended environments. Notification content supports template variables (sessionId, workspace, time, tool, reason, errorLabel, etc.), allowing format adjustments as needed.
A few notes before use:
- The plugin runs with the permissions of the current
dshprocess; it is recommended to check the source code and license before installing third-party plugins (this plugin is MIT licensed); - You need to build a self-built Lark app and enable corresponding permissions; lark-cli credentials are held by lark-cli itself, and the plugin does not touch the App Secret;
- The sending link is fail-soft; if lark-cli has issues, it only alerts and won’t drag down the DSH session.
Conclusion¶
dsh-lark-bridge turns “no one knows when the session stopped” into “receive Lark notification as soon as it stops”. It covers the complete chain from waiting for approval to process death, and integrates as a read-only observer, without affecting DSH’s own execution.
- Plugin directory page: https://www.skillhub.cn/plugins/leo-lab-2026/dsh-lark-bridge (community-maintained independent directory site, no official affiliation with DeepSeek / Hypersphere)
- Source code repository: https://github.com/leo-lab-2026/dsh-lark-bridge