@goodandready/dsh-cron 0.2.10 → 0.2.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -2
- package/README.ru.md +488 -0
- package/README.zh.md +488 -0
- package/docs/README.ru.md +41 -1
- package/docs/README.zh.md +41 -1
- package/lib/api.js +93 -2
- package/lib/chat-start.js +21 -1
- package/lib/client.js +595 -3
- package/lib/index.js +18 -0
- package/lib/runner.js +29 -1
- package/lib/scheduler.js +239 -4
- package/lib/store.js +34 -0
- package/lib/task-transfer.js +9 -0
- package/package.json +1 -1
package/README.zh.md
ADDED
|
@@ -0,0 +1,488 @@
|
|
|
1
|
+
# 📦 @goodandready/dsh-cron
|
|
2
|
+
|
|
3
|
+
<div align="center">
|
|
4
|
+
|
|
5
|
+
<h3>面向 DeepSeek Harness 的定时 Cron 调度、后台自动化与智能体任务执行引擎</h3>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<a href="https://www.npmjs.com/package/@goodandready/dsh-cron"><img src="https://img.shields.io/npm/v/@goodandready/dsh-cron.svg?style=for-the-badge&color=6366f1&labelColor=1e1b4b" alt="npm version"></a>
|
|
9
|
+
<a href="../LICENSE"><img src="https://img.shields.io/github/license/GooDAnDReaDY/dsh-cron.svg?style=for-the-badge&color=10b981&labelColor=064e3b" alt="license"></a>
|
|
10
|
+
<a href="https://github.com/topics/dsh-plugin"><img src="https://img.shields.io/badge/DSH-Plugin-8b5cf6.svg?style=for-the-badge&labelColor=2e1065" alt="DSH Plugin"></a>
|
|
11
|
+
<a href="https://nodejs.org"><img src="https://img.shields.io/badge/Node-20%2B-f59e0b.svg?style=for-the-badge&labelColor=451a03" alt="Node version"></a>
|
|
12
|
+
</p>
|
|
13
|
+
|
|
14
|
+
<p align="center">
|
|
15
|
+
<a href="https://goodandready.app/"><img src="https://img.shields.io/badge/所有项目-goodandready.app-ff4500.svg?style=for-the-badge&logo=rocket&logoColor=white&labelColor=1a1a2e" alt="所有项目"></a>
|
|
16
|
+
</p>
|
|
17
|
+
|
|
18
|
+
<p align="center">
|
|
19
|
+
<a href="README.md"><b>🇬🇧 English</b></a> •
|
|
20
|
+
<a href="README.ru.md"><b>🇷🇺 Русский</b></a> •
|
|
21
|
+
<a href="README.zh.md"><b>🇨🇳 中文说明</b></a>
|
|
22
|
+
</p>
|
|
23
|
+
|
|
24
|
+
<table align="center">
|
|
25
|
+
<tr>
|
|
26
|
+
<td align="center">
|
|
27
|
+
⭐ <strong>如果您喜欢这个插件,请在 GitHub 上为它点亮 Star</strong> — 这能让我知道插件对您有用,并鼓励我继续开发和维护它。
|
|
28
|
+
<br><br>
|
|
29
|
+
🐛 <strong>如果您发现 Bug 或希望增加功能</strong>,请使用任意语言在 GitHub 上提交 Issue — 我会评估您的建议,并在后续版本中实现有价值的改进。
|
|
30
|
+
</td>
|
|
31
|
+
</tr>
|
|
32
|
+
</table>
|
|
33
|
+
|
|
34
|
+
</div>
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## ⚡ 概述与问题
|
|
39
|
+
|
|
40
|
+
自主 AI 智能体经常需要执行周期性任务:生成每日晨报、整理缺陷跟踪、检查 API 健康状态、同步数据库或定期执行 Git 清理。如果 Harness 内没有专用调度器,用户只能依赖外部 crontab 封装、复杂的 webhook 方案或手动干预。
|
|
41
|
+
|
|
42
|
+
**`@goodandready/dsh-cron`** 是 DeepSeek Harness 的原生全栈调度与后台自动化插件。它将标准 cron 表达式、自然语言间隔语法与自主智能体执行连接起来:
|
|
43
|
+
|
|
44
|
+
1. **完善的可视化任务管理器** —— 侧边栏按钮带可折叠的活跃任务列表(下次运行时间或实时状态,行数有上限且状态可记忆),以及功能齐全的面板:按类型、模型、渠道筛选,暂停、立即运行、复制、导出/导入与创建任务。
|
|
45
|
+
2. **交互式“由 DSH 创建”流程** —— 与智能体对话,把高层需求转化为规范的定时任务。
|
|
46
|
+
3. **自主工具调用** —— 原生 `cron_*` 工具让智能体在会话中自行安排后续执行。
|
|
47
|
+
4. **健壮的调度器与原子存储** —— 基于 `croner`:间隔别名、一次性延时任务、原子写入、运行历史与成本追踪。
|
|
48
|
+
5. **六种执行运行时** —— shell、Node.js、Python、HTTP/webhook、远程 SSH 与 Docker,并支持按任务的环境变量、工作区绑定以及面向代码修改任务的隔离 git worktree。
|
|
49
|
+
6. **多渠道路由与模板** —— 一次运行可投递到 Telegram、dsh-kanban、Discord、Slack、ntfy、Bark、PushPlus、语音(`dsh-tts`)与 Gitea,支持 `{变量}` 消息模板与按 DSH 凭据名称引用的密钥。
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## 🏗️ 架构
|
|
54
|
+
|
|
55
|
+
```mermaid
|
|
56
|
+
graph TD
|
|
57
|
+
subgraph Client ["Web 客户端 (DSH UI)"]
|
|
58
|
+
SidebarBtn["侧边栏时钟按钮<br/>(DSH 客户端插槽)"]
|
|
59
|
+
Overlay["任务管理面板<br/>(标签: 全部 / 活跃 / 暂停 / 已完成)"]
|
|
60
|
+
CreateWithDSH["“由 DSH 创建”对话框<br/>(自然语言任务)"]
|
|
61
|
+
ManualForm["手动任务表单<br/>(运行时、cron、超时、重叠策略、渠道)"]
|
|
62
|
+
SettingsCard["设置卡片<br/>(渠道、模板、凭据)"]
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
subgraph Server ["服务端 (Cordis 与 DSH 服务)"]
|
|
66
|
+
HttpRoutes["HTTP REST API<br/>(/dsh-cron/*)"]
|
|
67
|
+
AgentTools["工具调用网关<br/>(cron_create_task, cron_list_tasks, ...)"]
|
|
68
|
+
Scheduler["TaskScheduler 引擎<br/>(Croner 实例 + one-shot 定时器)"]
|
|
69
|
+
Store["原子 TaskStore<br/>(tasks.json 原子写入)"]
|
|
70
|
+
AgentRunner["智能体会话调度器<br/>(以指定模型执行提示词)"]
|
|
71
|
+
Runtimes["执行运行时<br/>(shell、node、python、http、ssh、docker)"]
|
|
72
|
+
Notify["投递路由<br/>(模板 + 9 个渠道)"]
|
|
73
|
+
Secrets["凭据引用<br/>(DSH credentials / ENV)"]
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
SidebarBtn --> Overlay
|
|
77
|
+
Overlay --> CreateWithDSH
|
|
78
|
+
Overlay --> ManualForm
|
|
79
|
+
SettingsCard --> HttpRoutes
|
|
80
|
+
CreateWithDSH -->|POST /chat/start| HttpRoutes
|
|
81
|
+
ManualForm -->|POST /tasks| HttpRoutes
|
|
82
|
+
HttpRoutes --> Scheduler
|
|
83
|
+
AgentTools --> Scheduler
|
|
84
|
+
Scheduler --> Store
|
|
85
|
+
Scheduler -->|按间隔/一次性触发| AgentRunner
|
|
86
|
+
Scheduler --> Notify
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## ✨ 功能与能力
|
|
92
|
+
|
|
93
|
+
### 1. 可视化任务管理器
|
|
94
|
+
点击 DSH 侧边栏中的时钟图标(位于“新会话”按钮旁)打开管理面板:
|
|
95
|
+
* **状态过滤标签**:**全部**、**活跃**、**已暂停**、**已完成**。
|
|
96
|
+
* **即时操作**:立即运行(**Run Now**)、暂停/恢复调度、带确认的删除。
|
|
97
|
+
* **一键预设模板**:*每日摘要*、*每周回顾*、*待办监控*。
|
|
98
|
+
* **运行历史**:打开任务卡片查看历史运行 —— 时间、耗时、状态(成功 / 失败 / 超时 / 跳过 / 错过)、输出与错误。
|
|
99
|
+
* **汇总统计栏**:活跃任务数、总运行次数、总 token 消耗与估算美元成本。
|
|
100
|
+
|
|
101
|
+
### 2. “由 DSH 创建”对话框
|
|
102
|
+
无需猜测 cron 语法,用自然语言即可创建任务:
|
|
103
|
+
1. 点击 **Create ⌄** ➔ **Create with DSH**。
|
|
104
|
+
2. 描述要自动化的内容(例如:*“每个工作日早上 9 点检查未处理的 PR 并起草评论”*)。
|
|
105
|
+
3. 插件会创建一个注入了调度器指令的专属智能体会话。智能体会与你确认细节 —— LLM 还是 NO-LLM shell 任务、准确的 cron 表达式、在你的 DSH 安装中可用的经济型模型,以及是否启用“静默规则”(仅在新事件或故障时告警)—— 并在你确认后才通过 `cron_create_task` 工具注册任务。
|
|
106
|
+
|
|
107
|
+
### 3. 智能体工具(Tool Calling)
|
|
108
|
+
|
|
109
|
+
| 工具 | 说明 |
|
|
110
|
+
|:---|:---|
|
|
111
|
+
| `cron_create_task` | 创建任务:`title`、`schedule`、`prompt`、`fallbackModel`(失败时改用更强模型重试一次),可选 `type`(`llm`/`script`/`node`/`python`/`http`/`ssh`/`docker`/`skill`/`workflow`)、`delivery`、`provider`、`model`、`channels`、`template`、`notifyTelegram`、`onlyOnFailure`、`timeoutSeconds`、`overlapPolicy`、`kanbanMode` |
|
|
112
|
+
| `cron_schedule_task` | `cron_create_task` 的别名,保持与既有提示词兼容 |
|
|
113
|
+
| `cron_list_tasks` | 列出任务的状态、下次运行时间、token 总量与成本估算 |
|
|
114
|
+
| `cron_pause_task` | 暂停调度而不删除配置 |
|
|
115
|
+
| `cron_resume_task` | 恢复已暂停的调度 |
|
|
116
|
+
| `cron_delete_task` | 永久删除任务及其历史 |
|
|
117
|
+
| `cron_run_task` | 触发一次立即的带外运行 |
|
|
118
|
+
| `cron_get_task` | 读取单个任务的完整配置,包括列表中看不到的字段 |
|
|
119
|
+
| `cron_update_task` | 就地修改现有任务(白名单字段,校验与 HTTP 路由一致);提示模型先与用户确认会执行代码的改动 |
|
|
120
|
+
|
|
121
|
+
会话中模型可进行的调用示例:
|
|
122
|
+
|
|
123
|
+
```
|
|
124
|
+
cron_create_task({
|
|
125
|
+
"title": "Morning digest",
|
|
126
|
+
"schedule": "0 8 * * 1-5",
|
|
127
|
+
"prompt": "Prepare a brief morning digest of active tasks and open tickets.",
|
|
128
|
+
"type": "llm",
|
|
129
|
+
"delivery": "isolated"
|
|
130
|
+
})
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### 4. 调度表达式语法
|
|
134
|
+
基于 `croner`,支持标准 5 段 cron 表达式与友好的别名:
|
|
135
|
+
|
|
136
|
+
* `0 9 * * 1-5` —— 工作日 09:00
|
|
137
|
+
* `*/15 * * * *` —— 每 15 分钟
|
|
138
|
+
* `0 0 * * 0` —— 每周日午夜
|
|
139
|
+
* `every 10m` / `every 2h` / `every 30s` —— 自然语言间隔
|
|
140
|
+
* `daily` / `hourly` / `weekdays` 快捷方式,以及标准 `@hourly` / `@daily` / `@weekly` / `@monthly` / `@yearly` 与 `@every 30m`
|
|
141
|
+
* **任务级时区** —— 可为任务设置 IANA 时区(如 `Europe/Berlin`);未设置时按服务器本地时间调度
|
|
142
|
+
* **一次性任务**:`at: 2026-09-05T15:00:00Z`(精确 ISO 时间戳)或相对延时 `in 20m` / `in 2h`(也接受 `через 15 минут` 之类的俄语输入)。一次性任务在单次运行后自动转为 `completed`,显示在 **已完成** 标签下。
|
|
143
|
+
|
|
144
|
+
### 5. 执行可靠性
|
|
145
|
+
* **自动重试** —— 按任务设置 `maxRetries` 与基础 `retryBackoffMs`:失败(`error`/`timeout`)的运行按指数退避自动重试,成功后计数归零。
|
|
146
|
+
* **Misfire 策略** —— 选择守护进程离线期间错过的运行如何处理:`skip`(默认 —— 记录缺口)、`runOnce`(迟执行一次)或 `catchUpAll`(迟执行并记录缺口)。`skip` 下错过的一次性任务直接转为 `completed`,不再过期触发。
|
|
147
|
+
* **并发上限** —— 插件设置 `maxConcurrent` 限制并行运行数;超出的运行记录为 `skipped` 并附原因。
|
|
148
|
+
* **实时执行指示** —— 任务列表中的脉冲状态图标与运行计时器。
|
|
149
|
+
|
|
150
|
+
### 6. 执行运行时
|
|
151
|
+
每个任务可选择自己的运行时;非 LLM 运行时不需要模型,也不消耗 token:
|
|
152
|
+
|
|
153
|
+
* **Shell**(`script`)—— 通过 Harness shell 执行命令或脚本,支持 `env` 与 `cwd`。
|
|
154
|
+
* **Node.js**(`node`)与 **Python**(`python`)—— 指定解释器(`nodePath`、`pythonPath`)运行片段;Python 会自动识别项目虚拟环境。
|
|
155
|
+
* **HTTP**(`http`)—— 以自定义请求头与请求体访问 URL,状态码与响应写入运行历史。
|
|
156
|
+
* **SSH**(`ssh`)—— 通过 `dsh-remote-workspace` 配置(`sshProfileId`)或独立 host/key 字段在远程主机执行命令。
|
|
157
|
+
* **Docker**(`docker`)—— 在镜像容器(`dockerImage`)中执行命令。
|
|
158
|
+
* **环境变量** —— 按任务的 `env` 映射(界面中每行 KEY VALUE)应用于外部运行时;请勿在此存放密钥。
|
|
159
|
+
* **工作区与 worktree** —— 将任务绑定到 Harness 工作区(`workspaceId`);对会修改代码的智能体任务,可在隔离的 git worktree 中运行(`worktree`、`keepWorktree`)。
|
|
160
|
+
|
|
161
|
+
### 7. 成本控制:回退模型
|
|
162
|
+
任务可以默认使用便宜模型,失败时改用更强模型完成:设置 `fallbackModel`(可选 `fallbackProvider`),失败(`error` 或 `timeout`)的运行会在该模型上重试一次,之后才进入常规重试退避。历史记录会标明最终产出结果的模型以及是否使用了回退,两次尝试的用量与成本都会累计,模板变量 `{model}` 渲染完成运行的模型。回退仅适用于智能体类型(`llm`、`skill`、`workflow`)。
|
|
163
|
+
|
|
164
|
+
### 8. 会话集成与权限
|
|
165
|
+
* **按任务的权限预设** —— `default`、`read-only`、`workspace-write` 或 `full` 在提示词执行前应用于任务会话。
|
|
166
|
+
* **会话自动归档** —— 隔离的 cron 会话在运行后自动归档(尽力而为),不干扰聊天列表。
|
|
167
|
+
* **历史 → 会话** —— 每次 LLM 运行都会记录会话,可直接从历史记录打开对话。
|
|
168
|
+
|
|
169
|
+
### 9. 按规则保持安静
|
|
170
|
+
有输出的任务可以设置用自然语言描述的**静默规则**(例如“当没有分区使用率超过 80% 时保持安静”)。运行成功时,由便宜模型对照该规则判断输出,若结论为保持安静则跳过报告,并在运行历史中记录原因。遵循 fail-open:没有规则、没有模型、调用失败或答案无法解析时都会照常投递报告。插件设置 `silentRuleModel` 指定用于判断的模型。
|
|
171
|
+
|
|
172
|
+
### 10. 失败诊断
|
|
173
|
+
智能体任务可以请求诊断:设置 `inspectOnFailure` 后,失败(`error` 或 `timeout`)的运行会连同任务提示词与截断输出一起交给模型,运行历史中会保存简短诊断与具体的提示词修改建议。历史记录提供按钮把该建议载入编辑表单 —— 不会自动应用。模型由 `inspectorModel` 指定,消息模板中可使用 `{diagnosis}`。模型不可用或调用失败时,失败的运行保持原样。
|
|
174
|
+
|
|
175
|
+
### 11. 通知渠道与消息模板
|
|
176
|
+
运行完成后,报告会发送到该任务配置的所有渠道 —— Telegram、dsh-kanban、Discord、Slack、ntfy、Bark、PushPlus、语音(`dsh-tts`)以及 Gitea issue:
|
|
177
|
+
|
|
178
|
+
* **任务迁移** —— 将全部配置导出为版本化 JSON,并在别处导入(含预览摘要);导入的任务处于暂停状态。
|
|
179
|
+
* **按任务选择渠道** —— 在任务表单中勾选渠道;显式选择会覆盖旧版 `notifyTelegram`/`kanbanMode` 开关,留空则回退到它们。
|
|
180
|
+
* **故障隔离** —— 某个渠道不可用会记录在调度器日志中,其余渠道仍会收到报告;失效的 webhook 不会吞掉整份报告。
|
|
181
|
+
* **消息模板** —— 支持全局模板、按渠道覆盖或按任务模板,变量为 `{title} {id} {status} {output} {error} {duration} {schedule} {time} {tokens} {cost}`。未知占位符保持原样,失败运行默认使用失败模板。
|
|
182
|
+
* **`onlyOnFailure`** —— 全局或按任务生效:成功运行静默,仅发送 `error`/`timeout`。
|
|
183
|
+
* **凭据按名称引用** —— webhook token 与 Telegram bot token 填写 DSH 凭据的名称(`botTokenRef`、`ntfyTokenRef`、`pushplusTokenRef`、`giteaTokenRef`),发送时通过 DSH credentials 服务解析,并可回退到环境变量,且绝不会经过插件设置。webhook URL 与 Bark 设备键本身内嵌密钥,因此保存在插件设置文件中,但返回浏览器时始终为掩码,界面回传的掩码值也不会覆盖已保存的值。
|
|
184
|
+
* **投递超时** —— 每个渠道请求都有上限(`deliveryTimeoutMs`,默认 15000 毫秒,可在设置面板或 `settings.yaml` 中调整),且各渠道并发发送:无响应的端点只记录为失败,不会拖慢其他渠道或下一次调度。限制作用于整个渠道处理过程,也覆盖凭据解析——它不支持 abort 信号。
|
|
185
|
+
* **Telegram** —— 带状态徽标(✅ / ❌)、耗时、调度描述与等宽输出块的 Markdown 报告;动态值会被转义。凭据可直接填写,或从 DSH `settings.yaml` 的 `dsh-messenger-gateway` 段继承(尽力而为)。
|
|
186
|
+
* **Discord / Slack** —— 通过 webhook 投递:Discord 使用按运行状态着色的 embed,Slack 使用纯文本正文。
|
|
187
|
+
* **ntfy / Bark / PushPlus** —— 移动推送,支持主题/设备键与可选 bearer token;Bark 的标题与正文放在请求路径中,PushPlus 端点可指向自建代理。
|
|
188
|
+
* **语音** —— `dsh-tts` 通过其 HTTP 路由朗读报告(`ttsBaseUrl`,默认 `http://127.0.0.1:3080`)。
|
|
189
|
+
* **Gitea** —— 创建包含运行报告的 issue(`giteaBaseUrl`、`giteaRepo`、token 凭据);失败运行标记为 `cron`、`bug`、`alert`。
|
|
190
|
+
* **测试发送按钮** —— 在安排关键任务前现场验证 Telegram 连通性。
|
|
191
|
+
|
|
192
|
+
### 12. Kanban 集成与成本统计
|
|
193
|
+
* **自动创建 Kanban 卡片** —— 当 `kanbanMode` 为 `on_failure` 或 `always` 时,插件在 `dsh-kanban` 中创建卡片(`on_failure` → `error`/`timeout` 时进入 *Backlog*;`always` → 完成后进入 *Done*/*Backlog*)。
|
|
194
|
+
* **Token 与执行成本计量** —— 按运行与任务统计 token 消耗(输入、输出、缓存读取),基于内置价格表估算美元成本,并提供汇总分析栏。
|
|
195
|
+
|
|
196
|
+
### 13. 重叠策略与执行超时
|
|
197
|
+
|
|
198
|
+
* **执行超时(`timeoutSeconds`)** —— 达到限制后,shell 子进程通过 abort 信号立即终止,智能体会话被释放以停止消耗 token。默认 `1800`(30 分钟)。
|
|
199
|
+
* **重叠策略(`overlapPolicy`)** —— 上一次运行尚未结束时再次触发调度时的行为:
|
|
200
|
+
* **`skip`**(默认):丢弃重叠的运行,在历史中记录 `skipped`;
|
|
201
|
+
* **`queue`**:将下一次运行排队,当前任务完成后自动开始;
|
|
202
|
+
* **`replace`**:通过 `AbortController` 中止当前运行并启动新的执行。
|
|
203
|
+
|
|
204
|
+
如果守护进程在计划时刻处于离线状态,启动时该次运行会被记录为 `missed`,历史空档始终可见。
|
|
205
|
+
|
|
206
|
+
### 14. 心跳监控(Dead man's switch)
|
|
207
|
+
* 在插件设置中配置 `heartbeatUrl` 与 `heartbeatIntervalSec`,调度器会按间隔 GET 该地址 —— 外部监控可在心跳停止时告警。
|
|
208
|
+
* 内置 `GET /dsh-cron/heartbeat` 端点返回存活状态、活跃任务数与最近运行时间,便于自建看门狗。
|
|
209
|
+
|
|
210
|
+
### 15. 来自配置的声明式任务(#50)
|
|
211
|
+
长期运行的任务可以直接声明在配置文件里,而无需在界面中手工重建。配置文件拥有这些任务:每次插件启动时会创建或更新它们,从文件中消失的任务会被删除。
|
|
212
|
+
|
|
213
|
+
在配置文件(`cordis.patch.yml`)的插件段加入 `jobs` 列表:
|
|
214
|
+
|
|
215
|
+
```yaml
|
|
216
|
+
dsh-cron:
|
|
217
|
+
jobs:
|
|
218
|
+
- id: nightly-backup
|
|
219
|
+
title: Nightly backup
|
|
220
|
+
schedule: "0 3 * * *"
|
|
221
|
+
type: script
|
|
222
|
+
prompt: "bash /path/to/backup.sh"
|
|
223
|
+
channels: ["telegram"]
|
|
224
|
+
timeoutSeconds: 3600
|
|
225
|
+
- id: morning-digest
|
|
226
|
+
title: Morning digest
|
|
227
|
+
schedule: "0 8 * * 1-5"
|
|
228
|
+
type: llm
|
|
229
|
+
prompt: "Prepare a brief morning digest of active tasks."
|
|
230
|
+
provider: my-provider
|
|
231
|
+
model: provider-id/model-id
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
* 每条必填:`id`、`title`、`schedule`;以提示词承载有效载荷的类型(`script`、`node`、`python`、`ssh`、`docker`、`llm`、`skill`、`workflow`)还需非空 `prompt`。`http` 例外:目标由 `httpUrl`(或 `prompt`)给出。
|
|
235
|
+
* 其余任务字段按原样透传,校验与 API 一致:`channels`、`model`、`provider`、`fallbackModel`、`silentRule`、`inspectOnFailure`、`timezone`、`timeoutSeconds`、`template`、`env`、`cwd`,以及运行时字段(`nodePath`、`pythonPath`、`httpUrl`、`httpMethod`、`httpHeaders`、`httpBody`、`sshProfileId`、`sshTarget`、`dockerImage`、`workspaceId`、`worktree`、`keepWorktree`、`skillName`、`workflowName`)。
|
|
236
|
+
* 声明式任务标记为**由配置管理**;面板中显示来源标签而不是编辑/删除按钮。
|
|
237
|
+
* 对配置任务的编辑、暂停、恢复、切换与删除在面板和 API 上返回 `409`,携带配置任务现有 `id` 的创建或更新请求 `POST /dsh-cron/tasks` 同样被拒绝 —— 配置文件的来源为唯一真值。**立即运行**仍然可用。
|
|
238
|
+
* 通过 UI、API 或智能体工具创建的、`id` 相同的任务绝不会被覆盖:该条目会被跳过,冲突写入日志。
|
|
239
|
+
* 会执行代码的类型照常激活,但启动时插件会向日志写警告,使通过配置引入的代码路径可见。
|
|
240
|
+
* 条目逐条校验并带下标(`config.jobs[i]: …`);一条坏条目会被跳过,不会阻止其余任务或整个配置。
|
|
241
|
+
|
|
242
|
+
### 16. 外部 REST API(`/dsh-cron/api/*`,#54)
|
|
243
|
+
外部系统(CI、宿主机 cron、`curl`)无需打开面板即可驱动调度器。这是唯一由 bearer 令牌保护的接口;面板路由保持本地且防跨站。
|
|
244
|
+
|
|
245
|
+
令牌是插件设置 `apiToken`(与所有密钥一样掩码显示)。认证与错误:
|
|
246
|
+
* 未配置令牌 → 整个接口返回 `503`;
|
|
247
|
+
* 缺少或错误的 `Authorization: Bearer <token>` → `401`,比较为常量时间。
|
|
248
|
+
|
|
249
|
+
| 方法 | 路径 | 说明 |
|
|
250
|
+
|:---|:---|:---|
|
|
251
|
+
| `GET` | `/dsh-cron/api/tasks` | 任务列表(`status` / `query` 过滤,同面板) |
|
|
252
|
+
| `GET` | `/dsh-cron/api/tasks/:id` | 读取单个任务 |
|
|
253
|
+
| `POST` | `/dsh-cron/api/tasks` | 创建任务;带 `id` 时更新现有任务 |
|
|
254
|
+
| `DELETE` | `/dsh-cron/api/tasks/:id` | 删除任务 |
|
|
255
|
+
| `POST` | `/dsh-cron/api/tasks/:id/run` | 强制执行一次 |
|
|
256
|
+
|
|
257
|
+
这些操作复用面板处理器,因此对会执行代码类型的 `x-dsh-cron-confirm: script` 门禁以及对配置任务的 `409` 拒绝与 UI 完全一致。
|
|
258
|
+
|
|
259
|
+
```bash
|
|
260
|
+
BASE="http://127.0.0.1:3080"
|
|
261
|
+
TOKEN="<API_TOKEN>"
|
|
262
|
+
|
|
263
|
+
# 列表
|
|
264
|
+
curl -s -H "Authorization: Bearer $TOKEN" "$BASE/dsh-cron/api/tasks"
|
|
265
|
+
|
|
266
|
+
# 创建;请求体带 id 时为更新
|
|
267
|
+
curl -s -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
|
|
268
|
+
-d '{"id":"cleanup","title":"Cleanup","schedule":"0 4 * * *","prompt":"Remove stale temporary files."}' \
|
|
269
|
+
"$BASE/dsh-cron/api/tasks"
|
|
270
|
+
|
|
271
|
+
# 强制执行
|
|
272
|
+
curl -s -X POST -H "Authorization: Bearer $TOKEN" "$BASE/dsh-cron/api/tasks/cleanup/run"
|
|
273
|
+
|
|
274
|
+
# 删除
|
|
275
|
+
curl -s -X DELETE -H "Authorization: Bearer $TOKEN" "$BASE/dsh-cron/api/tasks/cleanup"
|
|
276
|
+
|
|
277
|
+
# 会执行代码的任务还需确认头
|
|
278
|
+
curl -s -X POST -H "Authorization: Bearer $TOKEN" -H "x-dsh-cron-confirm: script" \
|
|
279
|
+
-H "Content-Type: application/json" \
|
|
280
|
+
-d '{"title":"Disk check","schedule":"0 * * * *","type":"script","prompt":"df -h"}' \
|
|
281
|
+
"$BASE/dsh-cron/api/tasks"
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
### 17. Prometheus 指标(#53)
|
|
285
|
+
`GET /dsh-cron/metrics` 返回 Prometheus 文本格式,无需新增依赖即可被抓取:
|
|
286
|
+
|
|
287
|
+
* `dsh_cron_tasks_total{status}` —— 按状态统计的任务数(gauge)。
|
|
288
|
+
* `dsh_cron_task_last_duration_seconds{task}` —— 任务最近一次完成运行的耗时(秒,gauge)。
|
|
289
|
+
* `dsh_cron_runs_total{status}` —— 自插件进程启动以来完成的运行数(counter);状态为 `success`、`error`、`timeout`、`skipped`、`missed`。
|
|
290
|
+
* `dsh_cron_run_records` —— 当前保存在内存中的运行记录数(gauge)。
|
|
291
|
+
|
|
292
|
+
导出内容只有计数、状态和耗时;提示词、运行输出与任务配置不会出现在其中。
|
|
293
|
+
|
|
294
|
+
```yaml
|
|
295
|
+
scrape_configs:
|
|
296
|
+
- job_name: dsh-cron
|
|
297
|
+
static_configs:
|
|
298
|
+
- targets: ["127.0.0.1:3080"]
|
|
299
|
+
metrics_path: /dsh-cron/metrics
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
### 18. 严格的渠道校验(#121)
|
|
303
|
+
创建或更新任务时若包含未知的投递渠道 id,现在会返回 `400` 并列出违规项:
|
|
304
|
+
|
|
305
|
+
```json
|
|
306
|
+
{ "ok": false, "error": "Unknown channel ids: email_ping", "unknownChannels": ["email_ping"] }
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
Changed in v0.2.7:此前未知 id 会被静默丢弃,客户端即使有拼写错误也会得到 `ok: true`,最终得到一个不投递任何地方的任务。
|
|
310
|
+
|
|
311
|
+
导入有意保持宽容(文件可能来自旧版本):未知 id 会从导入的任务中丢弃,但会在响应(`unknownChannels`)中列出并写入调度器日志,而不是无声消失。
|
|
312
|
+
|
|
313
|
+
### 19. 安装后校验(#126)
|
|
314
|
+
`deploy.sh` 新增仅校验模式,用于检查已安装的配置而不安装任何东西:
|
|
315
|
+
|
|
316
|
+
```bash
|
|
317
|
+
bash deploy.sh verify [exact-version]
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
它确认配置报告了指定版本(默认取 `package.json` 的版本),登录 Web UI,然后下载客户端 bundle 并确认其中包含包名。
|
|
321
|
+
|
|
322
|
+
为什么需要它:Web 配置可能位于认证插件之后并对匿名请求返回 `401`,而插件客户端 bundle 只能通过认证后索引中打印的精确组合 `??` URL 获取 —— 裸的 `/plugins/<name>/client.js` 会返回 `404`。因此校验需要先建立已认证会话。
|
|
323
|
+
|
|
324
|
+
校验使用的环境变量:`DSH_WEB_BASE`(默认 `http://127.0.0.1:3080`)、`DSH_WEB_TOKEN`(令牌;未设置时脚本从单元日志读取最后一个)、`DSH_WEB_UNIT`(默认 `dsh-web.service`)。脚本中不含任何密钥。
|
|
325
|
+
|
|
326
|
+
### 20. 内部重构:调度解析与排程(#97)
|
|
327
|
+
面向开发者,行为不变。`parseScheduleExpression` 被拆分为保持相同分支顺序的小函数 —— `parseAtExpression`、`parseRelativeOneShot`、`parseIntervalExpression`、`parseAliasExpression`、`parseCronExpression`,`scheduleTask` 拆分为 `clearScheduled`、`scheduleOneShot`、`scheduleCron`。原有测试全部通过,并新增了针对分支优先级与错误的测试。
|
|
328
|
+
|
|
329
|
+
### 21. 性能与进程隔离增强包(v0.2.9,#134)
|
|
330
|
+
- **进程树终止隔离**:Shell 和 Script 任务在独立进程组启动(POSIX 下 `detached: true`);中止或超时向整组发送 `-child.pid SIGTERM -> SIGKILL`,杜绝孤儿进程与僵尸进程。
|
|
331
|
+
- **并发控制限流**:默认安全阈值 `maxConcurrent = 2`,避免定时重叠引发 CPU 和内存峰值。
|
|
332
|
+
- **瞬态错误重试**:针对网络抖动和模型速率限制(`429`、`502`、`503`、`504`、`ECONNRESET`)提供指数退避重试(最多3次)。
|
|
333
|
+
- **网络与前端优化**:`GET /dsh-cron/tasks` 支持 `ETag` 与 `304 Not Modified`;前端页面根据 `visibilityState` 自适应轮询(前台 8s,后台 30s)。
|
|
334
|
+
- **历史记录轮换与归档**:活动任务仅保留最新 100 次运行,超出部分自动归档至 `tasks-history-archive.json`。
|
|
335
|
+
- **自主 PR 审查配方 (#33)**:Template Hub 预置配方与 `prReviewerEnabled` 设置项。
|
|
336
|
+
|
|
337
|
+
### 22. 自动化、任务链与可观测性包(v0.2.10,#137)
|
|
338
|
+
- **Telegram 双向交互控制**:任务通知附带内嵌操作按钮(`🚀 立即运行`、`⏸️ 暂停/恢复`、`📋 最新日志`)。由 `POST /dsh-cron/telegram/webhook` 处理,严格鉴权 Chat ID 并调用 `answerCallbackQuery` 反馈。
|
|
339
|
+
- **任务管道与级联触发**:配置 `onSuccess` 与 `onFailure` 下游触发器。上游输出自动注入子任务环境变量 `$DSH_PREV_OUTPUT`,LLM 任务支持 `{{prevOutput}}` 插值。内置最大 5 级深度递归防护,杜绝死循环。
|
|
340
|
+
- **模型结构化动作指令**:自主分析任务可输出 JSON 指令触发级联任务(`trigger_task`)、定向告警(`notify`)或创建 Issue。受 `llmActionsEnabled: false` 严格保护。
|
|
341
|
+
- **历史归档与延迟洞察**:REST 接口 `GET /dsh-cron/tasks/:id/archive`(支持分页)与 `GET /dsh-cron/tasks/:id/stats`;UI 任务卡片展示耗时彩色徽章(<5s 绿,<30s 黄,≥30s 红)。
|
|
342
|
+
- **Prometheus 监控增强**:`/dsh-cron/metrics` 导出当前活动并发量 `dsh_cron_concurrent_running`、各任务 Token 计数器及成本预估指标。
|
|
343
|
+
|
|
344
|
+
### 23. 高级可靠性、自愈、心跳与体验包(v0.2.11,#139)
|
|
345
|
+
- **心跳与寂静监控(Heartbeat / Dead Man's Snitch)**:针对外部备份与后台作业提供反向监控。外部脚本定期向 `/dsh-cron/heartbeat/:id` 发送请求;超出 `heartbeatIntervalSeconds` + 宽限期未打卡时,任务标记为 `missed`,即刻推送失联告警并触发 `onFailure` 应急流程。
|
|
346
|
+
- **执行前置检查(Pre-flight Gates)**:执行前先验证条件(HTTP 状态 2xx、命令退出码 0、最低可用磁盘 MB)。未通过直接置为 `skipped`,杜绝因外部环境异常产生无意义的模型 Token 消耗与错误干扰。
|
|
347
|
+
- **试运行与调度模拟器(Dry-Run & Simulator)**:接口 `POST /dsh-cron/tasks/:id/dry-run` 与 UI `🧪 试运行` 按钮支持无副作用执行(不入库历史、不发渠道通知);`POST /dsh-cron/schedule/preview` 实时计算未来 5 次运行时间。
|
|
348
|
+
- **优先级队列与并发池(Priority Queues)**:并发满载时,等待队列严格依据任务 `priority`(1 最高,10 最低)调度。
|
|
349
|
+
- **自愈脚本与 AI 根因诊断(Self-Healing)**:任务失败后自动执行补偿指令 `selfHealingCommand`(例如重启服务或清理临时空间);`autoDiagnose` 自动生成 AI 故障根因摘要。
|
|
350
|
+
- **UI 交互式归档与管道全景**:支持分页浏览任务历史运行全量输出,直观展示 `➜ 成功触发` 与 `↳ 失败触发` 关联关系。
|
|
351
|
+
|
|
352
|
+
---
|
|
353
|
+
|
|
354
|
+
### 24. 自动挂载智能体预设与工具支持 (#141 / GH-1,v0.2.12 新增)
|
|
355
|
+
- **自动挂载智能体预设**:计划执行的自主 `llm` 任务和交互式启动现在会自动解析并挂载系统智能体预设(默认通过 `setup` 钩子中的 `presets.mount(agentCtx, preset.id)` 挂载用户的标准预设)。计划会话现已具备完整的工具调用能力(文件读写、工作区操作、Shell 终端等),彻底解决此前空会话无工具调用的问题。
|
|
356
|
+
- **单任务预设覆盖**:可在 Web 管理界面、REST API 或配置文件中为具体任务配置独立的 `agentPreset` 标识(例如 `coding`、`system`、`minimal`)。未设置时自动继承系统默认预设。
|
|
357
|
+
- **优雅降级保障**:当未安装 `agentPresets` 服务或指定了未知的预设 ID 时,调度器仅记录友好的警告日志,并安全平稳地继续执行基础模型会话,避免定时任务中断。
|
|
358
|
+
|
|
359
|
+
---
|
|
360
|
+
|
|
361
|
+
## 📦 安装
|
|
362
|
+
|
|
363
|
+
```bash
|
|
364
|
+
dsh plugin --profile web add @goodandready/dsh-cron
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
重启 DeepSeek Harness 实例并刷新浏览器。
|
|
368
|
+
|
|
369
|
+
---
|
|
370
|
+
|
|
371
|
+
## ⚙️ 配置(`settings.yaml`)
|
|
372
|
+
|
|
373
|
+
可以在 `settings.yaml` 中配置,也可以通过 DSH 中的插件设置卡片交互式管理:
|
|
374
|
+
|
|
375
|
+
```yaml
|
|
376
|
+
# settings.yaml
|
|
377
|
+
dsh-cron:
|
|
378
|
+
botToken: "" # Telegram Bot API 令牌(保密字段)
|
|
379
|
+
chatId: "" # 接收报告的 Telegram chat ID
|
|
380
|
+
notifyTelegram: false # 全局投递所有任务的报告
|
|
381
|
+
onlyOnFailure: false # 仅失败时投递报告
|
|
382
|
+
kanbanBaseUrl: "http://127.0.0.1:3000" # dsh-kanban HTTP API 基础地址
|
|
383
|
+
defaultTimezone: "" # 默认 IANA 时区(空 = 服务器本地)
|
|
384
|
+
maxConcurrent: 0 # 最大并行运行数(0 = 不限)
|
|
385
|
+
heartbeatUrl: "" # 心跳上报 URL(dead man's snitch)
|
|
386
|
+
heartbeatIntervalSec: 0 # 心跳间隔秒数(0 = 关闭)
|
|
387
|
+
# --- 投递渠道 ---
|
|
388
|
+
botTokenRef: "" # Telegram bot token 的凭据名称
|
|
389
|
+
template: "" # 全局消息模板,例如 "⏰ {title} — {status}"
|
|
390
|
+
channelTemplates: {} # 按渠道覆盖模板
|
|
391
|
+
deliveryTimeoutMs: 15000 # 每个渠道的投递超时;慢端点记为失败,不影响其他渠道
|
|
392
|
+
discordWebhookUrl: "" # Discord webhook
|
|
393
|
+
slackWebhookUrl: "" # Slack incoming webhook
|
|
394
|
+
ntfyUrl: "https://ntfy.sh" # ntfy 服务器;ntfyTopic / ntfyTokenRef
|
|
395
|
+
ntfyTopic: ""
|
|
396
|
+
ntfyTokenRef: ""
|
|
397
|
+
barkServerUrl: "https://api.day.app" # Bark 服务器;barkKey = 设备键
|
|
398
|
+
barkKey: ""
|
|
399
|
+
pushplusUrl: "https://www.pushplus.plus/send" # pushplusTokenRef
|
|
400
|
+
pushplusTokenRef: ""
|
|
401
|
+
ttsBaseUrl: "http://127.0.0.1:3080" # dsh-tts 基础地址
|
|
402
|
+
giteaBaseUrl: "" # giteaRepo = owner/repo,giteaTokenRef = 凭据名称
|
|
403
|
+
giteaRepo: ""
|
|
404
|
+
giteaTokenRef: ""
|
|
405
|
+
# --- 外部 REST API(#54)---
|
|
406
|
+
apiToken: "" # 外部 /dsh-cron/api/* 接口的 bearer 令牌(掩码;空 = 503)
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
### 配置参数
|
|
410
|
+
|
|
411
|
+
| 参数 | 类型 | 默认值 | 说明 |
|
|
412
|
+
|:---|:---|:---|:---|
|
|
413
|
+
| `botToken` | `string` | `""` | Telegram Bot API 令牌。留空时插件会尽力继承 DSH 设置中 `dsh-messenger-gateway` 配置的机器人。保密字段:界面只显示掩码值 |
|
|
414
|
+
| `chatId` | `string` | `""` | 接收报告的 Telegram chat ID。留空时回退到 `dsh-messenger-gateway` 的第一个允许会话 |
|
|
415
|
+
| `notifyTelegram` | `boolean` | `false` | 全局开关:向 Telegram 投递运行报告 |
|
|
416
|
+
| `onlyOnFailure` | `boolean` | `false` | 全局开关:仅对 `error`/`timeout` 运行投递报告 |
|
|
417
|
+
| `kanbanBaseUrl` | `string` | `"http://127.0.0.1:3000"` | 用于自动卡片的 `dsh-kanban` HTTP API 基础地址 |
|
|
418
|
+
| `defaultTimezone` | `string` | `""` | 任务调度的默认 IANA 时区;空 = 服务器本地时间 |
|
|
419
|
+
| `maxConcurrent` | `number` | `0` | 并行运行上限;超出的运行记录为 `skipped`(0 = 不限) |
|
|
420
|
+
| `heartbeatUrl` | `string` | `""` | 心跳上报 URL,调度器存活期间按 `heartbeatIntervalSec` 间隔 GET |
|
|
421
|
+
| `heartbeatIntervalSec` | `number` | `0` | 心跳间隔秒数(0 = 关闭) |
|
|
422
|
+
| `botTokenRef` | `string` | `""` | 保存 Telegram bot token 的 DSH 凭据名称;发送时解析(回退顺序:`botToken` → messenger-gateway 设置 → 环境变量 `CRON_TELEGRAM_BOT_TOKEN`) |
|
|
423
|
+
| `template` | `string` | `""` | 带 `{title}`/`{status}`/`{duration}` 等占位符的全局消息模板;留空使用内置文本 |
|
|
424
|
+
| `channelTemplates` | `object` | `{}` | 按渠道 ID 覆盖模板(`telegram`、`discord` 等) |
|
|
425
|
+
| `deliveryTimeoutMs` | `number` | `15000` | 每个渠道的投递超时;超时的端点记为失败,不拖慢其他渠道或下一次调度 |
|
|
426
|
+
| `discordWebhookUrl` / `slackWebhookUrl` | `string` | `""` | Discord 与 Slack 渠道的 webhook 地址 |
|
|
427
|
+
| `ntfyUrl` / `ntfyTopic` / `ntfyTokenRef` | `string` | `"https://ntfy.sh"` / `""` / `""` | ntfy 服务器、主题与可选的 token 凭据名称(以 `Authorization: Bearer …` 发送) |
|
|
428
|
+
| `barkServerUrl` / `barkKey` | `string` | `"https://api.day.app"` / `""` | Bark 服务器与设备键(键、标题和正文位于请求路径中) |
|
|
429
|
+
| `pushplusUrl` / `pushplusTokenRef` | `string` | `"https://www.pushplus.plus/send"` / `""` | PushPlus 端点(可指向自建代理)与 token 凭据名称 |
|
|
430
|
+
| `ttsBaseUrl` | `string` | `"http://127.0.0.1:3080"` | 用于语音播报的 `dsh-tts` 基础地址 |
|
|
431
|
+
| `giteaBaseUrl` / `giteaRepo` / `giteaTokenRef` | `string` | `""` | Gitea 渠道:基础地址、`owner/repo` 与 API token 的凭据名称 |
|
|
432
|
+
| `apiToken` | `string` | `""` | 外部 `/dsh-cron/api/*` 接口的 Bearer 令牌。保密字段,返回时掩码;为空时接口返回 503,错误值返回 401 |
|
|
433
|
+
|
|
434
|
+
说明:
|
|
435
|
+
|
|
436
|
+
* 运行历史上限为**每任务 50 条**(固定);每条记录最多保留 4000 字符输出。
|
|
437
|
+
* 任务在**服务器本地时区**执行;cron 表达式由 `croner` 按主机时钟计算。
|
|
438
|
+
* 任务持久化在 DSH 数据目录(`cron/tasks.json`),重启后保留;启动时会检测错过的一次性任务。
|
|
439
|
+
|
|
440
|
+
---
|
|
441
|
+
|
|
442
|
+
## 🔌 HTTP API 参考
|
|
443
|
+
|
|
444
|
+
所有端点由 DSH Web 服务器在 `/dsh-cron/` 下提供。读端点对本地 UI 开放;**变更端点拒绝跨域请求**且请求体最大 1 MB。通过 HTTP 创建 `script` 类型任务还需要 `x-dsh-cron-confirm: script` 请求头 —— 伪造的跨站请求无法附加该头。
|
|
445
|
+
|
|
446
|
+
| 方法 | 路径 | 说明 |
|
|
447
|
+
|:---|:---|:---|
|
|
448
|
+
| `GET` | `/dsh-cron/tasks` | 任务列表;查询参数 `status`(`all/active/paused/completed`)、`query`(子串搜索)。返回任务、推荐模板与汇总统计 |
|
|
449
|
+
| `POST` | `/dsh-cron/tasks` | 创建或更新任务(携带 `id` 时为更新)。需要 `title`、`schedule`、`prompt` |
|
|
450
|
+
| `GET` | `/dsh-cron/tasks/:id/history` | 运行历史,`?limit=20` |
|
|
451
|
+
| `POST` | `/dsh-cron/tasks/:id/run` | 立即手动运行 |
|
|
452
|
+
| `POST` | `/dsh-cron/tasks/:id/pause` | 暂停调度 |
|
|
453
|
+
| `POST` | `/dsh-cron/tasks/:id/resume` | 恢复调度 |
|
|
454
|
+
| `POST` | `/dsh-cron/tasks/:id/toggle` | 切换活跃/暂停 |
|
|
455
|
+
| `POST` | `/dsh-cron/tasks/:id/duplicate` | 创建暂停状态的副本:复制配置,重置运行历史与计数 |
|
|
456
|
+
| `GET` | `/dsh-cron/recipes` | 内置配方目录:按类别分组的现成监控预设,全部为只读操作 |
|
|
457
|
+
| `GET` | `/dsh-cron/tasks/export` | 仅含任务配置的版本化 JSON —— 不含历史与计数。渠道按名称引用凭据,但手动填写在任务中的 `env` 与 HTTP 请求头属于配置,会出现在文件里 |
|
|
458
|
+
| `POST` | `/dsh-cron/tasks/import` | 校验文档并以 `add`、`replace` 或 `skip` 策略导入;支持 `dryRun` 预览。导入的任务始终为**暂停**状态,恢复不会自动触发 |
|
|
459
|
+
| `PATCH` | `/dsh-cron/tasks/:id` | 部分更新(仅白名单字段:`title`、`schedule`、`prompt`、`type`、`delivery`、`provider`、`model`、通知/超时/重叠/Kanban 设置、`status`、`oneShot`) |
|
|
460
|
+
| `DELETE` | `/dsh-cron/tasks/:id` | 删除任务 |
|
|
461
|
+
| `GET` | `/dsh-cron/models` | 列出 LLM 提供方;`?provider=<id>` 列出模型 |
|
|
462
|
+
| `POST` | `/dsh-cron/chat/start` | 启动带任务配置指令的“由 DSH 创建”智能体会话 |
|
|
463
|
+
| `GET` | `/dsh-cron/settings` | 客户端安全设置(令牌掩码显示) |
|
|
464
|
+
| `POST` | `/dsh-cron/settings` | 更新集成设置(通过设置服务应用) |
|
|
465
|
+
| `GET` | `/dsh-cron/heartbeat` | 存活探针:活跃任务数与最近运行时间 |
|
|
466
|
+
| `POST` | `/dsh-cron/telegram/test` | 发送 Telegram 测试消息 |
|
|
467
|
+
| `POST` | `/dsh-cron/kanban/test` | 创建 Kanban 连通性测试卡片 |
|
|
468
|
+
| `*` | `/dsh-cron/action/:id/:action` | 任务操作路由的兼容别名(`run`、`toggle`、`delete`、`history`) |
|
|
469
|
+
| `GET` | `/dsh-cron/metrics` | Prometheus 文本格式的任务与运行计数 —— 不含提示词与输出(#53) |
|
|
470
|
+
| `GET` / `POST` | `/dsh-cron/api/tasks` | 令牌保护的外部接口:列表 / 创建或更新(#54) |
|
|
471
|
+
| `GET` / `DELETE` | `/dsh-cron/api/tasks/:id` | 令牌保护的外部接口:读取 / 删除(#54) |
|
|
472
|
+
| `POST` | `/dsh-cron/api/tasks/:id/run` | 令牌保护的外部接口:强制执行(#54) |
|
|
473
|
+
|
|
474
|
+
---
|
|
475
|
+
|
|
476
|
+
## 🧪 测试
|
|
477
|
+
|
|
478
|
+
```bash
|
|
479
|
+
npm test
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
测试覆盖调度表达式解析、调度器引擎、原子存储、HTTP 辅助函数、通知与工具契约。
|
|
483
|
+
|
|
484
|
+
---
|
|
485
|
+
|
|
486
|
+
## 📄 许可证
|
|
487
|
+
|
|
488
|
+
MIT © [GooDAnDReaDY](https://github.com/GooDAnDReaDY)
|
package/docs/README.ru.md
CHANGED
|
@@ -16,11 +16,21 @@
|
|
|
16
16
|
</p>
|
|
17
17
|
|
|
18
18
|
<p align="center">
|
|
19
|
-
<a href="
|
|
19
|
+
<a href="README.md"><b>🇬🇧 English</b></a> •
|
|
20
20
|
<a href="README.ru.md"><b>🇷🇺 Русский</b></a> •
|
|
21
21
|
<a href="README.zh.md"><b>🇨🇳 中文说明</b></a>
|
|
22
22
|
</p>
|
|
23
23
|
|
|
24
|
+
<table align="center">
|
|
25
|
+
<tr>
|
|
26
|
+
<td align="center">
|
|
27
|
+
⭐ <strong>Если вам нравится этот плагин, поставьте ему звезду на GitHub</strong> — это покажет мне, что плагин вам полезен, и будет мотивировать меня развивать его дальше.
|
|
28
|
+
<br><br>
|
|
29
|
+
🐛 <strong>Если вы нашли баг или хотите предложить новый функционал</strong>, создайте issue на GitHub на любом языке — я рассмотрю ваше предложение и реализую полезные идеи в одной из следующих версий плагина.
|
|
30
|
+
</td>
|
|
31
|
+
</tr>
|
|
32
|
+
</table>
|
|
33
|
+
|
|
24
34
|
</div>
|
|
25
35
|
|
|
26
36
|
---
|
|
@@ -193,6 +203,36 @@ cron_create_task({
|
|
|
193
203
|
|
|
194
204
|
Если сервис был выключен в момент планового запуска, при старте в истории появится запись `missed` — пробелы в истории остаются видимыми.
|
|
195
205
|
|
|
206
|
+
### 21. Пакет производительности и изоляции процессов (v0.2.9, #134)
|
|
207
|
+
- **Изоляция дерева процессов**: Shell и Script задачи запускаются в отдельной группе процессов (POSIX `detached: true`); при отмене или таймауте сигнал `-child.pid SIGTERM -> SIGKILL` завершает всё дерево, исключая зомби-процессы.
|
|
208
|
+
- **Троттлинг параллелизма**: Безопасный лимит `maxConcurrent = 2` по умолчанию предотвращает всплески нагрузки на CPU и RAM.
|
|
209
|
+
- **Повторы транзиентных сбоев**: Экспоненциальный backoff для ошибок 429 и 5xx (до 3 попыток).
|
|
210
|
+
- **Сетевая и UI-оптимизация**: `GET /dsh-cron/tasks` поддерживает `ETag` и `304 Not Modified`; адаптивный опрос UI (30с в фоне, 8с на активной вкладке).
|
|
211
|
+
- **Ротация истории и архив**: В памяти удерживается до 100 последних запусков на задачу, остальные архивируются в `tasks-history-archive.json`.
|
|
212
|
+
- **Рецепт автономного PR-ревьюера (#33)**: Готовый шаблон в Template Hub и тумблер `prReviewerEnabled`.
|
|
213
|
+
|
|
214
|
+
### 22. Автоматизация, цепочки задач и наблюдаемость (v0.2.10, #137)
|
|
215
|
+
- **Двухсторонний интерактивный Telegram**: Кнопки действий под уведомлениями (`🚀 Run Now`, `⏸️ Pause`, `📋 Last Output`), вебхук `POST /dsh-cron/telegram/webhook` с валидацией прав по Chat ID и откликом `answerCallbackQuery`.
|
|
216
|
+
- **Цепочки задач и конвейеры**: Триггеры `onSuccess` и `onFailure` для связывания задач. Передача вывода родительской задачи в переменную `$DSH_PREV_OUTPUT` (для shell) и `{{prevOutput}}` (для LLM). Ограничение глубины (максимум 5 уровней) против зацикливания.
|
|
217
|
+
- **Структурированные действия LLM**: Парсер директив модели (`trigger_task`, `notify`, `create_issue`) под опцией `llmActionsEnabled: false`.
|
|
218
|
+
- **Архивация и задержка в UI**: REST API `/dsh-cron/tasks/:id/archive` с пагинацией и статистика `/stats`. Бейджи латентности на карточках задач (<5с зелёный, <30с жёлтый, ≥30с красный).
|
|
219
|
+
- **Расширенные Prometheus-метрики**: Gauge `dsh_cron_concurrent_running`, счетчики токенов и стоимости в USD на задачу.
|
|
220
|
+
|
|
221
|
+
### 23. Расширенная надёжность, самовосстановление, Heartbeat и UX (v0.2.11, #139)
|
|
222
|
+
- **Мониторинг тишины (Heartbeat / Dead Man's Snitch)**: Эндпоинты `/dsh-cron/heartbeat/:id` и `/dsh-cron/api/heartbeat/:id` для приёма внешних пингов от бэкапов и демонов. При отсутствии пинга в пределах `heartbeatIntervalSeconds` + `gracePeriodSeconds` фиксируется статус `missed`, рассылается тревога и запускается `onFailure`.
|
|
223
|
+
- **Pre-flight проверки (условный запуск)**: Предварительная проверка HTTP-статуса 2xx, exit-кода команды или свободного места на диске. При непрохождении задача переходит в `skipped` без траты токенов LLM.
|
|
224
|
+
- **Dry-Run и симулятор расписания**: Тестовый запуск `POST /dsh-cron/tasks/:id/dry-run` и кнопка `🧪 Dry Run` в UI без записи в историю и без отправки в каналы; расчет следующих тиков через `POST /dsh-cron/schedule/preview`.
|
|
225
|
+
- **Очереди с приоритетами**: При достижении лимита параллелизма задачи упорядочиваются по полю `priority` (1 — наивысший, 10 — низший).
|
|
226
|
+
- **Команды самоисцеления и авто-диагностика (Self-Healing)**: Автоматический запуск компенсирующей команды `selfHealingCommand` при падении задачи; опция `autoDiagnose` для генерации AI-диагностики причин сбоя.
|
|
227
|
+
- **Интерактивный архив логов в UI**: Модальное окно просмотра истории с пагинацией и полным выводом логов, визуальные ссылки конвейеров `➜ onSuccess` и `↳ onFailure`.
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
### 24. Автоматическое подключение пресетов агента и инструментов (#141 / GH-1, добавлено в v0.2.12)
|
|
232
|
+
- **Автоматическое монтирование пресета агента**: Запланированные автономные `llm`-задачи и интерактивные запуски агента теперь автоматически определяют и подключают пресет агента системы (по умолчанию используется стандартный пресет пользователя через `presets.mount(agentCtx, preset.id)` внутри хука `setup`). Автономные сессии по расписанию получают полный доступ к инструментам (файлы, рабочее окружение, терминал и т.д.) вместо изолированного чата без инструментов.
|
|
233
|
+
- **Индивидуальный пресет для задачи**: Для каждой задачи можно явно задать идентификатор `agentPreset` в веб-интерфейсе, через REST API или в декларативных задачах профиля (например, `coding`, `system`, `minimal`). Если поле не заполнено, автоматически применяется пресет по умолчанию из настроек харнесса.
|
|
234
|
+
- **Безопасная деградация**: Если сервис `agentPresets` недоступен или указан несуществующий пресет, планировщик выводит информативное предупреждение и штатно продолжает выполнение модели без аварийной остановки задачи.
|
|
235
|
+
|
|
196
236
|
---
|
|
197
237
|
|
|
198
238
|
## 📦 Установка
|
package/docs/README.zh.md
CHANGED
|
@@ -16,11 +16,21 @@
|
|
|
16
16
|
</p>
|
|
17
17
|
|
|
18
18
|
<p align="center">
|
|
19
|
-
<a href="
|
|
19
|
+
<a href="README.md"><b>🇬🇧 English</b></a> •
|
|
20
20
|
<a href="README.ru.md"><b>🇷🇺 Русский</b></a> •
|
|
21
21
|
<a href="README.zh.md"><b>🇨🇳 中文说明</b></a>
|
|
22
22
|
</p>
|
|
23
23
|
|
|
24
|
+
<table align="center">
|
|
25
|
+
<tr>
|
|
26
|
+
<td align="center">
|
|
27
|
+
⭐ <strong>如果您喜欢这个插件,请在 GitHub 上为它点亮 Star</strong> — 这能让我知道插件对您有用,并鼓励我继续开发和维护它。
|
|
28
|
+
<br><br>
|
|
29
|
+
🐛 <strong>如果您发现 Bug 或希望增加功能</strong>,请使用任意语言在 GitHub 上提交 Issue — 我会评估您的建议,并在后续版本中实现有价值的改进。
|
|
30
|
+
</td>
|
|
31
|
+
</tr>
|
|
32
|
+
</table>
|
|
33
|
+
|
|
24
34
|
</div>
|
|
25
35
|
|
|
26
36
|
---
|
|
@@ -316,6 +326,36 @@ bash deploy.sh verify [exact-version]
|
|
|
316
326
|
### 20. 内部重构:调度解析与排程(#97)
|
|
317
327
|
面向开发者,行为不变。`parseScheduleExpression` 被拆分为保持相同分支顺序的小函数 —— `parseAtExpression`、`parseRelativeOneShot`、`parseIntervalExpression`、`parseAliasExpression`、`parseCronExpression`,`scheduleTask` 拆分为 `clearScheduled`、`scheduleOneShot`、`scheduleCron`。原有测试全部通过,并新增了针对分支优先级与错误的测试。
|
|
318
328
|
|
|
329
|
+
### 21. 性能与进程隔离增强包(v0.2.9,#134)
|
|
330
|
+
- **进程树终止隔离**:Shell 和 Script 任务在独立进程组启动(POSIX 下 `detached: true`);中止或超时向整组发送 `-child.pid SIGTERM -> SIGKILL`,杜绝孤儿进程与僵尸进程。
|
|
331
|
+
- **并发控制限流**:默认安全阈值 `maxConcurrent = 2`,避免定时重叠引发 CPU 和内存峰值。
|
|
332
|
+
- **瞬态错误重试**:针对网络抖动和模型速率限制(`429`、`502`、`503`、`504`、`ECONNRESET`)提供指数退避重试(最多3次)。
|
|
333
|
+
- **网络与前端优化**:`GET /dsh-cron/tasks` 支持 `ETag` 与 `304 Not Modified`;前端页面根据 `visibilityState` 自适应轮询(前台 8s,后台 30s)。
|
|
334
|
+
- **历史记录轮换与归档**:活动任务仅保留最新 100 次运行,超出部分自动归档至 `tasks-history-archive.json`。
|
|
335
|
+
- **自主 PR 审查配方 (#33)**:Template Hub 预置配方与 `prReviewerEnabled` 设置项。
|
|
336
|
+
|
|
337
|
+
### 22. 自动化、任务链与可观测性包(v0.2.10,#137)
|
|
338
|
+
- **Telegram 双向交互控制**:任务通知附带内嵌操作按钮(`🚀 立即运行`、`⏸️ 暂停/恢复`、`📋 最新日志`)。由 `POST /dsh-cron/telegram/webhook` 处理,严格鉴权 Chat ID 并调用 `answerCallbackQuery` 反馈。
|
|
339
|
+
- **任务管道与级联触发**:配置 `onSuccess` 与 `onFailure` 下游触发器。上游输出自动注入子任务环境变量 `$DSH_PREV_OUTPUT`,LLM 任务支持 `{{prevOutput}}` 插值。内置最大 5 级深度递归防护,杜绝死循环。
|
|
340
|
+
- **模型结构化动作指令**:自主分析任务可输出 JSON 指令触发级联任务(`trigger_task`)、定向告警(`notify`)或创建 Issue。受 `llmActionsEnabled: false` 严格保护。
|
|
341
|
+
- **历史归档与延迟洞察**:REST 接口 `GET /dsh-cron/tasks/:id/archive`(支持分页)与 `GET /dsh-cron/tasks/:id/stats`;UI 任务卡片展示耗时彩色徽章(<5s 绿,<30s 黄,≥30s 红)。
|
|
342
|
+
- **Prometheus 监控增强**:`/dsh-cron/metrics` 导出当前活动并发量 `dsh_cron_concurrent_running`、各任务 Token 计数器及成本预估指标。
|
|
343
|
+
|
|
344
|
+
### 23. 高级可靠性、自愈、心跳与体验包(v0.2.11,#139)
|
|
345
|
+
- **心跳与寂静监控(Heartbeat / Dead Man's Snitch)**:针对外部备份与后台作业提供反向监控。外部脚本定期向 `/dsh-cron/heartbeat/:id` 发送请求;超出 `heartbeatIntervalSeconds` + 宽限期未打卡时,任务标记为 `missed`,即刻推送失联告警并触发 `onFailure` 应急流程。
|
|
346
|
+
- **执行前置检查(Pre-flight Gates)**:执行前先验证条件(HTTP 状态 2xx、命令退出码 0、最低可用磁盘 MB)。未通过直接置为 `skipped`,杜绝因外部环境异常产生无意义的模型 Token 消耗与错误干扰。
|
|
347
|
+
- **试运行与调度模拟器(Dry-Run & Simulator)**:接口 `POST /dsh-cron/tasks/:id/dry-run` 与 UI `🧪 试运行` 按钮支持无副作用执行(不入库历史、不发渠道通知);`POST /dsh-cron/schedule/preview` 实时计算未来 5 次运行时间。
|
|
348
|
+
- **优先级队列与并发池(Priority Queues)**:并发满载时,等待队列严格依据任务 `priority`(1 最高,10 最低)调度。
|
|
349
|
+
- **自愈脚本与 AI 根因诊断(Self-Healing)**:任务失败后自动执行补偿指令 `selfHealingCommand`(例如重启服务或清理临时空间);`autoDiagnose` 自动生成 AI 故障根因摘要。
|
|
350
|
+
- **UI 交互式归档与管道全景**:支持分页浏览任务历史运行全量输出,直观展示 `➜ 成功触发` 与 `↳ 失败触发` 关联关系。
|
|
351
|
+
|
|
352
|
+
---
|
|
353
|
+
|
|
354
|
+
### 24. 自动挂载智能体预设与工具支持 (#141 / GH-1,v0.2.12 新增)
|
|
355
|
+
- **自动挂载智能体预设**:计划执行的自主 `llm` 任务和交互式启动现在会自动解析并挂载系统智能体预设(默认通过 `setup` 钩子中的 `presets.mount(agentCtx, preset.id)` 挂载用户的标准预设)。计划会话现已具备完整的工具调用能力(文件读写、工作区操作、Shell 终端等),彻底解决此前空会话无工具调用的问题。
|
|
356
|
+
- **单任务预设覆盖**:可在 Web 管理界面、REST API 或配置文件中为具体任务配置独立的 `agentPreset` 标识(例如 `coding`、`system`、`minimal`)。未设置时自动继承系统默认预设。
|
|
357
|
+
- **优雅降级保障**:当未安装 `agentPresets` 服务或指定了未知的预设 ID 时,调度器仅记录友好的警告日志,并安全平稳地继续执行基础模型会话,避免定时任务中断。
|
|
358
|
+
|
|
319
359
|
---
|
|
320
360
|
|
|
321
361
|
## 📦 安装
|