@ian2018cs/agenthub 0.2.6 → 0.2.7
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/package.json
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import crypto from 'crypto';
|
|
2
|
+
import fs from 'fs';
|
|
2
3
|
import cron from 'node-cron';
|
|
3
4
|
import { cronScheduler } from './cron-scheduler.js';
|
|
4
5
|
import { feishuDb } from '../../database/db.js';
|
|
@@ -78,17 +79,35 @@ export const cronCreateTool = {
|
|
|
78
79
|
|
|
79
80
|
systemPrompt: `
|
|
80
81
|
## 定时任务(Cron)
|
|
81
|
-
使用以下 Bash
|
|
82
|
+
使用以下 Bash 命令操作定时任务(任务持久化到数据库,服务重启自动恢复,循环任务永久运行直到用户手动删除,**没有 7 天过期限制**):
|
|
82
83
|
|
|
83
|
-
###
|
|
84
|
+
### 创建定时任务(**必须用文件方式**,避免 prompt 含特殊字符时解析失败)
|
|
85
|
+
|
|
86
|
+
**步骤一**:用 Write 工具把参数写入临时文件(纯文本,无需 JSON,文件名用时间戳保证唯一):
|
|
87
|
+
\`\`\`
|
|
88
|
+
Write /tmp/<userUuid>/cron/task_<timestamp>.txt
|
|
89
|
+
<第1行: cron 表达式>
|
|
90
|
+
<第2行: true 或 false(是否循环)>
|
|
91
|
+
<第3行起: prompt 内容,原样保留,支持任意字符和换行>
|
|
92
|
+
\`\`\`
|
|
93
|
+
|
|
94
|
+
**示例**:
|
|
95
|
+
\`\`\`
|
|
96
|
+
Write /tmp/abc123/cron/task_1700000000.txt
|
|
97
|
+
30 9 * * *
|
|
98
|
+
true
|
|
99
|
+
[channel:feishu]每天查询前天广告收入,分析数据并发送到飞书群
|
|
100
|
+
\`\`\`
|
|
101
|
+
|
|
102
|
+
**步骤二**:把文件路径传给 __cron_create__:
|
|
84
103
|
\`\`\`
|
|
85
|
-
Bash(__cron_create__
|
|
104
|
+
Bash(__cron_create__ /tmp/abc123/cron/task_1700000000.txt)
|
|
86
105
|
\`\`\`
|
|
87
106
|
|
|
88
107
|
参数说明:
|
|
89
|
-
- cron: 标准 5 字段 cron 表达式(如 "*/5 * * * *")
|
|
90
|
-
-
|
|
91
|
-
-
|
|
108
|
+
- 第1行 cron: 标准 5 字段 cron 表达式(如 "*/5 * * * *")
|
|
109
|
+
- 第2行 recurring: true=循环(永久),false=单次(触发后删除)
|
|
110
|
+
- 第3行起 prompt: 触发时执行的内容,开头可加前缀指定会话方式和投递渠道
|
|
92
111
|
|
|
93
112
|
### 前缀说明(**创建前务必询问用户**,在 prompt 开头使用,顺序任意,均可选):
|
|
94
113
|
|
|
@@ -124,12 +143,41 @@ Bash(__cron_list__)
|
|
|
124
143
|
},
|
|
125
144
|
|
|
126
145
|
async execute(hookInput, ctx) {
|
|
127
|
-
const rawArgs = hookInput.tool_input.command.replace(/^\s*__cron_create__\s*/, '');
|
|
146
|
+
const rawArgs = hookInput.tool_input.command.replace(/^\s*__cron_create__\s*/, '').trim();
|
|
128
147
|
let params;
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
148
|
+
|
|
149
|
+
if (rawArgs.startsWith('/')) {
|
|
150
|
+
// 文件路径模式:纯文本格式(无 JSON,彻底避免转义问题)
|
|
151
|
+
// 第1行: cron 表达式
|
|
152
|
+
// 第2行: recurring (true/false)
|
|
153
|
+
// 第3行起: prompt 内容(原样保留,支持任意字符和换行)
|
|
154
|
+
let fileContent;
|
|
155
|
+
try {
|
|
156
|
+
fileContent = fs.readFileSync(rawArgs, 'utf8');
|
|
157
|
+
} catch (e) {
|
|
158
|
+
return { decision: 'deny', reason: `读取参数文件失败: ${e.message}(路径: ${rawArgs})` };
|
|
159
|
+
} finally {
|
|
160
|
+
try { fs.unlinkSync(rawArgs); } catch {}
|
|
161
|
+
}
|
|
162
|
+
const lines = fileContent.split('\n');
|
|
163
|
+
const cronExprLine = lines[0]?.trim();
|
|
164
|
+
const recurringLine = lines[1]?.trim().toLowerCase();
|
|
165
|
+
const promptText = lines.slice(2).join('\n').trim();
|
|
166
|
+
if (!cronExprLine || !promptText) {
|
|
167
|
+
return { decision: 'deny', reason: '❌ 参数文件格式错误:第1行应为 cron 表达式,第2行为 true/false,第3行起为 prompt 内容' };
|
|
168
|
+
}
|
|
169
|
+
params = {
|
|
170
|
+
cron: cronExprLine,
|
|
171
|
+
recurring: recurringLine !== 'false',
|
|
172
|
+
prompt: promptText,
|
|
173
|
+
};
|
|
174
|
+
} else {
|
|
175
|
+
// 内联 JSON 模式(兼容旧用法,不推荐)
|
|
176
|
+
try {
|
|
177
|
+
params = parseJsonArg(rawArgs);
|
|
178
|
+
} catch (e) {
|
|
179
|
+
return { decision: 'deny', reason: `参数解析失败: ${e.message}。请改用文件方式:Write /tmp/<uuid>/cron/task_<ts>.txt,第1行cron表达式,第2行true/false,第3行起prompt内容,再调 Bash(__cron_create__ /tmp/.../task.txt)` };
|
|
180
|
+
}
|
|
133
181
|
}
|
|
134
182
|
|
|
135
183
|
const { cron: cronExpr, prompt: rawPrompt, recurring = true } = params;
|
|
@@ -197,10 +245,10 @@ Bash(__cron_list__)
|
|
|
197
245
|
return {
|
|
198
246
|
decision: 'deny',
|
|
199
247
|
reason: [
|
|
200
|
-
`✅
|
|
248
|
+
`✅ 定时任务已创建并持久化(无过期限制,永久有效)`,
|
|
201
249
|
`任务 ID: ${id}`,
|
|
202
250
|
`频率: ${cronExpr}`,
|
|
203
|
-
`类型: ${recurring ? '
|
|
251
|
+
`类型: ${recurring ? '循环(永久运行)' : '单次(触发后删除)'}`,
|
|
204
252
|
`会话方式: ${sessionDesc}`,
|
|
205
253
|
`投递渠道: ${channelDesc}`,
|
|
206
254
|
`内容: ${prompt}`,
|
|
@@ -272,8 +320,8 @@ export const cronListTool = {
|
|
|
272
320
|
// ─── SDK 原生工具重定向(拦截并引导 AI 使用 Bash 版本)─────────────────────────
|
|
273
321
|
|
|
274
322
|
const SDK_CRON_REDIRECT = `❌ 请勿使用 SDK 内置的 CronCreate/CronDelete/CronList 工具,它们在本系统中无法持久化。
|
|
275
|
-
请改用以下 Bash
|
|
276
|
-
-
|
|
323
|
+
请改用以下 Bash 命令(必须用文件方式创建,避免 prompt 特殊字符导致解析失败):
|
|
324
|
+
- 创建:先 Write /tmp/<uuid>/cron/task_<ts>.txt(第1行cron表达式,第2行true/false,第3行起prompt),再 Bash(__cron_create__ /tmp/<uuid>/cron/task_<ts>.txt)
|
|
277
325
|
- 删除:Bash(__cron_delete__ '{"id":"任务ID"}')
|
|
278
326
|
- 列表:Bash(__cron_list__)`;
|
|
279
327
|
|