dsh-timer-scheduler
Manifest valid★ 1简单的dsh定时任务插件 支持定时列表任务、ui显示,对于长期任务有益
dsh-timer-scheduler-ui
A DeepSeek Harness (DSH) plugin: an agent self-scheduler that wakes the agent at a future time to autonomously check on background jobs, remote tasks, or anything that needs a "come back later" look — without a human having to prompt it — plus a header reminder menu in the web UI.
Features
schedule_reminder— schedule a one-shot reminder, relative (delay_seconds) or absolute (at: ISO 8601 /HH:MM[:SS]).- Auto-cancel via
subject— pass asubject(background subagent id / shell background job id); when that subagent or background job settles and its completion notice enters the parent inbox, the plugin cancels matching reminders automatically. list_reminders— list pending reminders.cancel_reminder— cancel a reminder by id.- Auto-wake — on fire, the agent is woken through
agent.followup()with a new turn; it acts and reports on its own, no human wake-up needed. - Persistence — pending reminders are serialized to
$DSH_HOME/timer-reminders.jsonand re-armed on restart. - Header reminder menu (client half) — per-reminder note + live countdown, theme-aware via
--dsw-alias-*tokens, hidden when empty, never covering the send button.
Structure
One package, two halves, in the standard dsh.client + dsh.bundle.patch shape. Everything is host-plane: composing this bundle into the web profile's host composition makes the model tools available to every agent regardless of preset, and the route serves the browser panel.
| File | Half | Role |
|---|---|---|
lib/index.js | Host | The three model tools (schedule_reminder / list_reminders / cancel_reminder), auto-wake, disk persistence, and GET /api/timer-reminders |
lib/client.js | Client | conversation.session.header.actions compact dropdown, polling every second |
cordis.patch.yml | bundle | Inserts the Host half into the web profile's host composition |
package.json | — | dsh.client (browser bundle) + dsh.bundle.patch (host row) |
Preset adaptation: the anchored-standard preset keeps these tools resident for its agents via its residentTools option; every other preset works without any configuration.
Installation
Not published to npm yet. Install from source:
Host-plane tools: once this bundle is composed, every agent on any preset can call
schedule_reminder/list_reminders/cancel_reminder. If a preset uses an aggressive tool-bootstrap filter (likeanchored-standard), keep the three tool names resident so its agents still see them:# inside the tool-bootstrap row's config residentTools: [schedule_reminder, list_reminders, cancel_reminder]
-
Install it into a profile (this registers both the dependency and the bundle entry, so the Host half is composed):
dsh plugin --profile web add /path/to/dsh-timer-schedulerManual equivalent, if you prefer editing the profile yourself — the profile's
package.jsonneeds the package in both places:{ "dependencies": { "dsh-timer-scheduler-ui": "file:./packages/dsh-timer-scheduler-ui" }, "dsh": { "profile": { "bundles": ["@deepseek-ai/dsh-base", "@deepseek-ai/dsh-web-app", "dsh-timer-scheduler-ui"] } } } -
Restart DSH (the Host half lives in the server process; a browser refresh is not enough), then hard-refresh the page.
-
Verify from a shell — the Host half must answer both the list and an action:
curl 'http://127.0.0.1:<port>/api/timer-reminders?sessionId=x' # → {"reminders":[]} curl -X POST 'http://127.0.0.1:<port>/api/timer-reminders?action=retry&id=nope&sessionId=x' # → 404 {"ok":false,"error":"not-found","id":"nope"} (an OLD host answers 200 with the reminder list here)Then open any session: the session-header menu shows the countdown, and each row has 补触发 / 取消.
Standalone check (no DSH session needed)
node test/delivery.mjs # 8 cases: same-session delivery, resume w/ preset, queue actions, dedupe
node --check lib/index.js lib/client.js
A full standalone proof installs into a disposable profile and boots it; the
exact commands and their recorded output are in PROFILE_EVIDENCE.md.
Usage
In an agent session, just say:
- "Remind me in 30 minutes to check that background job" →
schedule_reminder(delay_seconds=1800, note=…, subject=<subagentId>) - "Check the deployment at 3pm" →
schedule_reminder(at="15:00", note=…) - Manage with
list_reminders/cancel_reminder.
The header reminder menu shows the countdown while reminders are pending and hides when empty.
How it works
- The agent calls
schedule_reminder; the host plugin arms a one-shot Cordistimerand writes{id, note, dueMs, sessionId, subject?}to~/.dsh/timer-reminders.json. - On fire, the host plugin wakes the same session that armed the reminder — never a relaunched stand-in and never a pre-branch/archived parent:
- live session →
agent.followup()(a live agent already carries its own tools); - cold ordinary session (forked/branched ones included) →
ctx.agents.resume()with the session's own persisted preset mounted in the factorysetup(header.agentPreset→agentPresets.mount), so the resumed agent gets the tool registry and prompt sections it was created with. Resuming without thatsetupcomposes no tools at all — the historicalunknown tool "bash"failure after a wake; - cold session-backed subagent child →
ctx.subagents.sendMessage()through its exact live direct parent, so the continuation seam cold-resumes the same child with thepersona/toolFilterrecorded in its durablesubagent/descriptorand keeps the parent's ownership of it. Resuming such a child as a root instead breaks later parent→child delivery with "already owned by an active write handle". A message is then built withsource.kind = 'plugin'and delivered to that agent to wake its driver.header.parentSessionis durable fork lineage (or a child's direct parent) — installation history, never a delivery target.
- live session →
- If a reminder carries a
subjectand a matching background subagent completion notice (source.kind = 'subagent-settled') or shell background job completion notice (source.plugin = 'tool-jobs') enters the parent session's inbox, the host plugin cancels the reminder automatically. - This package's client half fetches
/api/timer-reminders?sessionId=…every second and renders the countdown in the session-header menu. - The menu is also the manual control surface: each row has 补触发 (fire now, in the SAME session) and 取消 buttons, backed by
POST /api/timer-reminders?action=retry|cancel&id=…&sessionId=…. Without them a parked or overdue entry was visible but unpushable from the browser — only an agent could callretry_reminder. - Scheduling the same note for the same session within the same minute reuses the pending entry instead of stacking a second identical reminder (
已设定时提醒vs复用已存在的定时提醒), so an agent asked twice cannot leave two wakes that both fire.
Known limitations
- Cold resume requires session persistence to be configured and the owning session to be resumable. Resuming a session mounts the preset named by its durable
agentPreset; if that preset was deleted or will not mount, the reminder is parked for manual retry (list_remindersshows the reason) instead of being resumed under a different composition. - Transient resume failures (agent-loop not loaded yet at startup, session still owned by an in-flight write handle) are retried with bounded backoff (2s/5s/15s) — never by re-routing the reminder to another session.
- A cold subagent child can only be resumed through its live direct parent. If that parent is offline the reminder is parked for manual retry; the plugin will not wake an archived parent session on your behalf.
- Cold resume is bounded at 90s: a resume that never settles retries with backoff instead of leaving the entry
deliveringforever (which made it invisible to re-arming and unpushable). - The cold-resumed AgentHandle is kept until the plugin is unloaded, so the woken session stays resident after the reminder; a future version may dispose it after the wake turn settles. A handle whose session was closed or replaced in the meantime is dropped and resumed again.
- Reminders that become due while the DSH process is down are re-armed on startup and fire immediately (instead of being skipped).
- Delays beyond ~24.8 days are chunked, so they work, but the mechanism is "in-process timer + disk snapshot"; the timer only needs the process to stay up to fire.
Installing into a profile
node scripts/sync-profile.mjs [profile-dir] copies lib/ into both installed copies (packages/… and node_modules/…) and into the root aliases index.js / client.js.
That last part is not cosmetic. The host loader resolves the bundle name to the package directory and can prefer a root index.js when one exists, so a stale root alias makes the profile keep running old host code after a restart while lib/ looks current — the visible symptom is a menu action that returns HTTP 200 and does nothing, because the old handler ignores the request method. Always sync through the script (or copy both layouts) after editing lib/.
Tests
node test/delivery.mjs runs the delivery-contract regression suite against a fake host: live session, cold forked session with preset restoration, deleted preset, transient factory-missing retry, cold subagent child with an offline parent, and cold subagent child with a live parent. It asserts that a reminder never reroutes to a parent/branch session.
License
Comments
Loading…
From the same category
by omdsh-dev
开放的侧边栏底座,支持三方拓展注册新侧边栏页面。内置文件渲染编辑/终端/侧边对话/Git/子代理页面 | Open sidebar foundation, supports third-party extensions to register new sidebar pages. Built-in file rendering/editing, terminal, side chat, Git,
★ 3.7k
↓ 49.5k/wk
MIT
TypeScript
Sep 22, 2026
dsh plugin --profile web add dsh-better-sidebarby ccch1mneyyy
DSH 官方公众号收录的 TUI 补位插件:Claude Code 风,鲸鱼顶栏/实时状态/流式思考/双击 Esc 回滚/上下文进度+TPS。npm 一键装。 DSH official WeChat featured TUI plugin — Claude Code style: whale bar, live status, streaming thoughts, double-Esc rol
★ 3.2k
↓ 6.2k/wk
MIT
TypeScript
Sep 22, 2026
dsh plugin --profile web add @deepseek-harness-tui/dsh-tuiby MeteorNOX
DeepSeek Harness(DSH)一只住在 DSH 界面右下角的小鲸鱼娘,帮你盯着DeepSeek账户余额。QQ弹弹,支持拖拽吸附、左吸附翻转、数字滚动动画,随界面自动启用,建议直接喊来你的dsh安装
★ 3k
↓ 19.1k/wk
MIT
JavaScript
Sep 22, 2026
dsh plugin --profile web add dsh-whale-widgetby Devin-AXIS
DeepSeek Harness 可编辑设计系统:AI 生成、可视化编辑、模板市场与 PPT|Native Design & PPT Studio for DeepSeek Harness.
★ 1.5k
↓ 440/wk
NOASSERTION
JavaScript
Sep 4, 2026
dsh plugin --profile web add deepseek-idesignby omdsh-dev
GenUI for DeepSeek Harness: interactive UI components rendered inline in assistant replies via the dsh-ui fence — layout, charts, plots, forms, quizzes, mermaid, 3D scenes, and an action event loop ba
★ 474
↓ 5.1k/wk
MIT
TypeScript
Sep 22, 2026
dsh plugin --profile web add @changfenhuang/dsh-genuiby chenxiachan
Your thinking deserves a map: an infinite canvas where LLM conversations grow into an editable thought graph. Wires are the context.
★ 473
MIT
TypeScript
Sep 21, 2026