@ai-setting/roy-agent-core 1.5.83 → 1.5.85
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/dist/env/agent/index.js +2 -2
- package/dist/env/event-source/index.js +2 -2
- package/dist/env/index.js +14 -14
- package/dist/env/prompt/index.js +1 -1
- package/dist/env/task/delegate/index.js +2 -2
- package/dist/env/task/index.js +3 -3
- package/dist/env/task/plugins/index.js +1 -1
- package/dist/env/workflow/engine/index.js +3 -4
- package/dist/env/workflow/index.js +7 -7
- package/dist/env/workflow/service/index.js +8 -2
- package/dist/env/workflow/storage/index.js +11 -6
- package/dist/env/workflow/tools/index.js +16 -2
- package/dist/index.js +17 -16
- package/dist/shared/@ai-setting/{roy-agent-core-f6p7wwpd.js → roy-agent-core-0kt57b72.js} +1 -6
- package/dist/shared/@ai-setting/{roy-agent-core-whw7jap0.js → roy-agent-core-1db4vpc6.js} +3 -2
- package/dist/shared/@ai-setting/{roy-agent-core-68sef3es.js → roy-agent-core-29fh9mxg.js} +1 -1
- package/dist/shared/@ai-setting/roy-agent-core-3sv590cv.js +132 -0
- package/dist/shared/@ai-setting/{roy-agent-core-m4qjnhz6.js → roy-agent-core-5kdw0p98.js} +114 -68
- package/dist/shared/@ai-setting/{roy-agent-core-78yzt2bq.js → roy-agent-core-7fdzfsm6.js} +2 -2
- package/dist/shared/@ai-setting/{roy-agent-core-mbre4fxg.js → roy-agent-core-7z4xtrmw.js} +16 -0
- package/dist/shared/@ai-setting/{roy-agent-core-am646wfz.js → roy-agent-core-86d4exyf.js} +5 -2
- package/dist/shared/@ai-setting/roy-agent-core-c67wr8sp.js +11 -0
- package/dist/shared/@ai-setting/{roy-agent-core-v3t28k5n.js → roy-agent-core-dp73ghtz.js} +24 -26
- package/dist/shared/@ai-setting/{roy-agent-core-qjv8537d.js → roy-agent-core-dv12wpdv.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-6b0r2e7j.js → roy-agent-core-gttz2jpm.js} +15 -52
- package/dist/shared/@ai-setting/{roy-agent-core-496zzm5a.js → roy-agent-core-h4h55x4h.js} +183 -3
- package/dist/shared/@ai-setting/roy-agent-core-hhrg314p.js +34 -0
- package/dist/shared/@ai-setting/{roy-agent-core-vcvgq9hy.js → roy-agent-core-mmkyydw7.js} +128 -6
- package/dist/shared/@ai-setting/roy-agent-core-r5axf0ad.js +751 -0
- package/dist/shared/@ai-setting/{roy-agent-core-74cp3zp1.js → roy-agent-core-taxvytzz.js} +4 -1
- package/dist/shared/@ai-setting/roy-agent-core-tq9528d3.js +336 -0
- package/dist/shared/@ai-setting/{roy-agent-core-nc0n0bdc.js → roy-agent-core-xckhrs2p.js} +2 -3
- package/dist/shared/@ai-setting/{roy-agent-core-67yzhmg2.js → roy-agent-core-ya1ayt1k.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-015vw11k.js → roy-agent-core-yx0vw1aw.js} +8 -6
- package/package.json +1 -1
- package/dist/shared/@ai-setting/roy-agent-core-4t40mkpv.js +0 -206
- package/dist/shared/@ai-setting/roy-agent-core-6b57g1zk.js +0 -103
- package/dist/shared/@ai-setting/roy-agent-core-7z8fzxck.js +0 -265
- package/dist/shared/@ai-setting/roy-agent-core-a6j7g1qe.js +0 -428
- package/dist/shared/@ai-setting/roy-agent-core-qf9gvx02.js +0 -39
|
@@ -1,16 +1,135 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
} from "./roy-agent-core-
|
|
2
|
+
TagRepository
|
|
3
|
+
} from "./roy-agent-core-3sv590cv.js";
|
|
4
4
|
import {
|
|
5
5
|
exports_search_query_parser,
|
|
6
6
|
init_search_query_parser
|
|
7
7
|
} from "./roy-agent-core-rvxg1wps.js";
|
|
8
8
|
import {
|
|
9
|
+
createLogger,
|
|
10
|
+
init_logger
|
|
11
|
+
} from "./roy-agent-core-shme7set.js";
|
|
12
|
+
import {
|
|
13
|
+
__require,
|
|
9
14
|
__toCommonJS
|
|
10
15
|
} from "./roy-agent-core-fs0mn2jk.js";
|
|
11
16
|
|
|
12
17
|
// src/env/workflow/storage/workflow-repo.ts
|
|
13
18
|
import { randomUUID } from "crypto";
|
|
19
|
+
|
|
20
|
+
// src/env/workflow/storage/sqlite.ts
|
|
21
|
+
init_logger();
|
|
22
|
+
import { join } from "path";
|
|
23
|
+
var logger = createLogger("workflow:sqlite");
|
|
24
|
+
function getDatabaseClass() {
|
|
25
|
+
if (typeof Bun !== "undefined") {
|
|
26
|
+
const { Database } = __require("bun:sqlite");
|
|
27
|
+
return Database;
|
|
28
|
+
} else {
|
|
29
|
+
return __require("better-sqlite3");
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function createCompatibleDatabase(path) {
|
|
33
|
+
const Database = getDatabaseClass();
|
|
34
|
+
const db = new Database(path);
|
|
35
|
+
if (typeof db.run !== "function") {
|
|
36
|
+
db.run = function(sql, ...params) {
|
|
37
|
+
if (params.length > 0) {
|
|
38
|
+
return this.prepare(sql).run(...params);
|
|
39
|
+
} else {
|
|
40
|
+
return this.exec(sql);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
return db;
|
|
45
|
+
}
|
|
46
|
+
function getDefaultDataDir() {
|
|
47
|
+
const home = process.env.HOME || process.env.USERPROFILE || "/tmp";
|
|
48
|
+
return join(home, ".local", "share", "roy-agent");
|
|
49
|
+
}
|
|
50
|
+
function getDatabasePath() {
|
|
51
|
+
return join(getDefaultDataDir(), "workflows.db");
|
|
52
|
+
}
|
|
53
|
+
var dbInstance = null;
|
|
54
|
+
function getDatabase(path) {
|
|
55
|
+
if (!dbInstance) {
|
|
56
|
+
const dbPath = path ?? getDatabasePath();
|
|
57
|
+
const dbDir = dbPath.substring(0, dbPath.lastIndexOf("/"));
|
|
58
|
+
if (dbDir && dbDir !== "/") {
|
|
59
|
+
try {
|
|
60
|
+
const { mkdirSync } = __require("fs");
|
|
61
|
+
mkdirSync(dbDir, { recursive: true });
|
|
62
|
+
} catch {}
|
|
63
|
+
}
|
|
64
|
+
dbInstance = createCompatibleDatabase(dbPath);
|
|
65
|
+
try {
|
|
66
|
+
if (typeof dbInstance.pragma === "function") {
|
|
67
|
+
dbInstance.pragma("journal_mode = WAL");
|
|
68
|
+
}
|
|
69
|
+
} catch {
|
|
70
|
+
logger?.debug("WAL mode not available, using default journal mode");
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return dbInstance;
|
|
74
|
+
}
|
|
75
|
+
function closeDatabase() {
|
|
76
|
+
if (dbInstance) {
|
|
77
|
+
dbInstance.close();
|
|
78
|
+
dbInstance = null;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
function initializeTables() {
|
|
82
|
+
const db = getDatabase();
|
|
83
|
+
db.exec(`
|
|
84
|
+
CREATE TABLE IF NOT EXISTS workflows (
|
|
85
|
+
id TEXT PRIMARY KEY,
|
|
86
|
+
name TEXT NOT NULL UNIQUE,
|
|
87
|
+
version TEXT NOT NULL DEFAULT '1.0',
|
|
88
|
+
description TEXT,
|
|
89
|
+
definition TEXT NOT NULL,
|
|
90
|
+
config TEXT NOT NULL DEFAULT '{}',
|
|
91
|
+
metadata TEXT NOT NULL DEFAULT '{}',
|
|
92
|
+
tags TEXT NOT NULL DEFAULT '[]',
|
|
93
|
+
task_id INTEGER,
|
|
94
|
+
created_at TEXT NOT NULL,
|
|
95
|
+
updated_at TEXT NOT NULL
|
|
96
|
+
)
|
|
97
|
+
`);
|
|
98
|
+
db.exec(`
|
|
99
|
+
CREATE INDEX IF NOT EXISTS idx_workflows_name ON workflows(name);
|
|
100
|
+
CREATE INDEX IF NOT EXISTS idx_workflows_tags ON workflows(tags);
|
|
101
|
+
CREATE INDEX IF NOT EXISTS idx_workflows_task_id ON workflows(task_id);
|
|
102
|
+
`);
|
|
103
|
+
TagRepository.createTable(db);
|
|
104
|
+
const migrated = migrateEmptyTagsToDefault(db);
|
|
105
|
+
if (migrated > 0) {
|
|
106
|
+
logger?.info?.(`[workflow:sqlite] Auto-migrated ${migrated} workflow(s) to default tag`);
|
|
107
|
+
}
|
|
108
|
+
const countRow = db.prepare("SELECT COUNT(*) as c FROM workflows WHERE tags LIKE ?").get('%"default"%');
|
|
109
|
+
const expectedDefaultCount = countRow.c;
|
|
110
|
+
if (expectedDefaultCount > 0) {
|
|
111
|
+
const tagRepo = new TagRepository(db);
|
|
112
|
+
const existing = tagRepo.get("default");
|
|
113
|
+
const now = new Date().toISOString();
|
|
114
|
+
if (!existing) {
|
|
115
|
+
db.prepare(`INSERT INTO workflow_tags (name, usage_count, created_at, updated_at)
|
|
116
|
+
VALUES ('default', ?, ?, ?)`).run(expectedDefaultCount, now, now);
|
|
117
|
+
} else if (existing.usage_count !== expectedDefaultCount) {
|
|
118
|
+
db.prepare("UPDATE workflow_tags SET usage_count = ?, updated_at = ? WHERE name = ?").run(expectedDefaultCount, now, "default");
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
function resetDatabase() {
|
|
123
|
+
closeDatabase();
|
|
124
|
+
dbInstance = null;
|
|
125
|
+
}
|
|
126
|
+
function initDatabase(path) {
|
|
127
|
+
const db = getDatabase(path);
|
|
128
|
+
initializeTables();
|
|
129
|
+
return db;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// src/env/workflow/storage/workflow-repo.ts
|
|
14
133
|
function rowToWorkflow(row) {
|
|
15
134
|
const metadata = JSON.parse(row.metadata);
|
|
16
135
|
if (row.task_id !== null) {
|
|
@@ -185,6 +304,38 @@ class WorkflowRepository {
|
|
|
185
304
|
const result = this.db.prepare("SELECT COUNT(*) as count FROM workflows").get();
|
|
186
305
|
return result.count;
|
|
187
306
|
}
|
|
307
|
+
countAll(options) {
|
|
308
|
+
let sql = "SELECT * FROM workflows";
|
|
309
|
+
const params = [];
|
|
310
|
+
const conditions = [];
|
|
311
|
+
if (options?.tag) {
|
|
312
|
+
conditions.push("tags LIKE ?");
|
|
313
|
+
params.push(`%${options.tag}%`);
|
|
314
|
+
}
|
|
315
|
+
if (options?.taskId !== undefined) {
|
|
316
|
+
conditions.push("task_id = ?");
|
|
317
|
+
params.push(options.taskId);
|
|
318
|
+
}
|
|
319
|
+
if (conditions.length > 0) {
|
|
320
|
+
sql += " WHERE " + conditions.join(" AND ");
|
|
321
|
+
}
|
|
322
|
+
const rows = this.db.prepare(sql).all(...params);
|
|
323
|
+
let workflows = rows.map(rowToWorkflow);
|
|
324
|
+
if (options?.tags && options.tags.length > 0) {
|
|
325
|
+
const requiredTags = options.tags;
|
|
326
|
+
workflows = workflows.filter((w) => requiredTags.every((t) => w.tags.includes(t)));
|
|
327
|
+
}
|
|
328
|
+
if (options?.search) {
|
|
329
|
+
const { parseSearchQuery, matchesQuery } = (init_search_query_parser(), __toCommonJS(exports_search_query_parser));
|
|
330
|
+
const query = parseSearchQuery(options.search);
|
|
331
|
+
workflows = workflows.filter((w) => {
|
|
332
|
+
const descMatch = w.description ? matchesQuery(w.description, query) : false;
|
|
333
|
+
const tagsMatch = w.tags.some((tag) => matchesQuery(tag, query));
|
|
334
|
+
return descMatch || tagsMatch;
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
return workflows.length;
|
|
338
|
+
}
|
|
188
339
|
search(query, limit) {
|
|
189
340
|
let sql = "SELECT * FROM workflows WHERE name LIKE ? ORDER BY updated_at DESC";
|
|
190
341
|
const params = [`%${query}%`];
|
|
@@ -195,6 +346,35 @@ class WorkflowRepository {
|
|
|
195
346
|
const rows = this.db.prepare(sql).all(...params);
|
|
196
347
|
return rows.map(rowToWorkflow);
|
|
197
348
|
}
|
|
349
|
+
migrateEmptyTagsToDefault() {
|
|
350
|
+
return migrateEmptyTagsToDefault(this.db);
|
|
351
|
+
}
|
|
352
|
+
transaction(fn) {
|
|
353
|
+
this.db.exec("BEGIN");
|
|
354
|
+
try {
|
|
355
|
+
const result = fn();
|
|
356
|
+
this.db.exec("COMMIT");
|
|
357
|
+
return result;
|
|
358
|
+
} catch (e) {
|
|
359
|
+
try {
|
|
360
|
+
this.db.exec("ROLLBACK");
|
|
361
|
+
} catch {}
|
|
362
|
+
throw e;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
function migrateEmptyTagsToDefault(db) {
|
|
367
|
+
const DEFAULT_TAG_VALUE = "default";
|
|
368
|
+
const rows = db.prepare("SELECT id FROM workflows WHERE tags IS NULL OR tags = '' OR tags = '[]'").all();
|
|
369
|
+
if (rows.length === 0)
|
|
370
|
+
return 0;
|
|
371
|
+
const updateStmt = db.prepare("UPDATE workflows SET tags = ?, updated_at = ? WHERE id = ?");
|
|
372
|
+
const now = new Date().toISOString();
|
|
373
|
+
const defaultTagsJson = JSON.stringify([DEFAULT_TAG_VALUE]);
|
|
374
|
+
for (const row of rows) {
|
|
375
|
+
updateStmt.run(defaultTagsJson, now, row.id);
|
|
376
|
+
}
|
|
377
|
+
return rows.length;
|
|
198
378
|
}
|
|
199
379
|
|
|
200
|
-
export { rowToWorkflow, WorkflowRepository };
|
|
380
|
+
export { rowToWorkflow, WorkflowRepository, migrateEmptyTagsToDefault, getDatabasePath, getDatabase, closeDatabase, initializeTables, resetDatabase, initDatabase };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// src/env/workflow/service/registry.ts
|
|
2
|
+
class WorkflowServiceRegistry {
|
|
3
|
+
static instance;
|
|
4
|
+
service = null;
|
|
5
|
+
constructor() {}
|
|
6
|
+
static getInstance() {
|
|
7
|
+
if (!WorkflowServiceRegistry.instance) {
|
|
8
|
+
WorkflowServiceRegistry.instance = new WorkflowServiceRegistry;
|
|
9
|
+
}
|
|
10
|
+
return WorkflowServiceRegistry.instance;
|
|
11
|
+
}
|
|
12
|
+
register(service) {
|
|
13
|
+
this.service = service;
|
|
14
|
+
}
|
|
15
|
+
get() {
|
|
16
|
+
if (!this.service) {
|
|
17
|
+
throw new Error("WorkflowService is not registered. Call register() first.");
|
|
18
|
+
}
|
|
19
|
+
return this.service;
|
|
20
|
+
}
|
|
21
|
+
isRegistered() {
|
|
22
|
+
return this.service !== null;
|
|
23
|
+
}
|
|
24
|
+
reset() {
|
|
25
|
+
this.service = null;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function getWorkflowService() {
|
|
29
|
+
return WorkflowServiceRegistry.getInstance().get();
|
|
30
|
+
}
|
|
31
|
+
function registerWorkflowService(service) {
|
|
32
|
+
WorkflowServiceRegistry.getInstance().register(service);
|
|
33
|
+
}
|
|
34
|
+
export { WorkflowServiceRegistry, getWorkflowService, registerWorkflowService };
|
|
@@ -136,7 +136,8 @@ var builtInPrompts = {
|
|
|
136
136
|
- **文件浏览 / 读取**:\`ls -la\`、\`cat file.txt\`、\`head -n 20 file.txt\`、\`tail -n 50 log.txt\`、\`grep "pattern" file.txt\`、\`find . -name "*.ts"\`
|
|
137
137
|
- **状态查询**:\`pwd\`、\`date\`、\`whoami\`、\`which node\`、\`git status\`、\`git log -5\`、\`git diff\`
|
|
138
138
|
- **简单测试 / 工具调用**:\`echo "hello"\`、\`node --version\`、\`bun --version\`
|
|
139
|
-
- **调用一行 \`roy-agent\` 命令**(如 \`bun packages/cli/dist/bin/roy-agent.js tasks list\`)
|
|
139
|
+
- **调用一行 \`roy-agent\` 命令**(如 \`bun packages/cli/dist/bin/roy-agent.js tasks list\`、\`roy-agent workflow list\`、\`roy-agent workflow tag list\`、\`roy-agent workflow search --keyword xxx\`)
|
|
140
|
+
- workflow 创建流程:\`roy-agent workflow add --name <name> --file <yaml> --tags "tag1,tag2"\`,创建前可用 \`roy-agent workflow validate --file <yaml>\` 验证 YAML 语法
|
|
140
141
|
|
|
141
142
|
**\`bash\` 适合 vs 需要委托的边界:**
|
|
142
143
|
- ✅ \`ls -la\`、\`cat file.txt\`、\`grep "TODO" src/*.ts\`、\`git status\`、\`find . -name "*.ts"\` — **直接用 \`bash\` 执行**
|
|
@@ -245,6 +246,21 @@ delegate_task(
|
|
|
245
246
|
4. **搜索相似任务并委托** — 在委托前,先使用 \`task_search\` 搜索与当前请求相关的历史任务,将找到的相似任务 ID 填入 \`similar_task_ids\` 参数。在给子智能体的提示词中,始终包含简要指令,要求将工作视为任务一等公民:创建任务(\`task_create\`)、跟踪进度并完成。
|
|
246
247
|
5. **汇报结果** — 向用户总结结果
|
|
247
248
|
|
|
249
|
+
## Workflow 创建指南
|
|
250
|
+
|
|
251
|
+
当收到用户请求**创建/注册 Workflow** 时,必须遵循以下标准流程:
|
|
252
|
+
|
|
253
|
+
### 流程
|
|
254
|
+
1. **先查 tag 池** — 调用 \`bash\` 执行 \`roy-agent workflow tag list\` 查看现有 tag,选择语义最匹配的 1-3 个 tag
|
|
255
|
+
2. **验证 YAML** — 调用 \`bash\` 执行 \`roy-agent workflow validate --file <yaml路径>\` 验证 Workflow 定义语法
|
|
256
|
+
3. **注册 Workflow** — 确认验证通过后,用 \`roy-agent workflow add --name <name> --file <yaml> --tags "tag1,tag2"\` 注册
|
|
257
|
+
4. **核实结果** — 用 \`roy-agent workflow get <name>\` 或 \`roy-agent workflow list --tag <tag>\` 确认注册成功
|
|
258
|
+
|
|
259
|
+
### Tag 选择原则
|
|
260
|
+
- **必选已有 tag**:优先从 \`workflow tag list\` 显示的已有 tag 池中选语义最相似的
|
|
261
|
+
- **新增 tag**:池中确实没有合适 tag 时才新增,以扩展 tag 池
|
|
262
|
+
- **避免膨胀**:已有 \`ci-cd\` 时不新增 \`continuous-integration\`,已有 \`build-publish\` 时不新增 \`release-deploy\`
|
|
263
|
+
|
|
248
264
|
## 行为规则
|
|
249
265
|
|
|
250
266
|
1. **复杂任务必须委托** — 不要尝试自己解决复杂任务。使用 \`delegate_task\` 委托给子智能体。
|
|
@@ -287,6 +303,37 @@ delegate_task(
|
|
|
287
303
|
- 遇到阻塞:尝试绕过或选替代方案,无法绕过的暂停任务等用户回来
|
|
288
304
|
- 任务完成:记录完整结果,用户回来时统一汇报
|
|
289
305
|
|
|
306
|
+
|
|
307
|
+
## Workflow 操作指南
|
|
308
|
+
|
|
309
|
+
Workflow 是预定义的自动化流程,可以高效解决常见类型的任务。在接手一个复杂任务时,**建议先用 workflow 检索看看有没有现成的解决方案**。
|
|
310
|
+
|
|
311
|
+
### 如何用 workflow 辅助解决任务
|
|
312
|
+
1. **查 tag 发现可用 workflow**:\`workflow tag list\` — 查看 tag 池,找与任务领域匹配的 tag
|
|
313
|
+
2. **按 tag 搜索 workflow**:\`workflow list --tag <tag>\` — 找到相关的 workflow
|
|
314
|
+
3. **按关键词搜索**:\`workflow search --keyword <key>\` — 用关键词匹配
|
|
315
|
+
4. **查看详情**:\`workflow get <name>\` — 了解 workflow 的输入参数和节点流程
|
|
316
|
+
5. **运行 workflow**:\`workflow run <name> --input '{"key":"value"}'\` — 直接执行
|
|
317
|
+
|
|
318
|
+
> \uD83D\uDCA1 **什么时候该用 workflow?**
|
|
319
|
+
> - ✅ 你的任务与现有 workflow 的 tag 或描述高度匹配时 → 优先用 \`workflow run\`
|
|
320
|
+
> - ✅ 现有 workflow 可以作为参考模板 → 参考其设计自行实现
|
|
321
|
+
> - ❌ 找不到匹配的 workflow → **用传统方式解决**(委托子智能体、直接编码等)
|
|
322
|
+
|
|
323
|
+
### 可用命令速查
|
|
324
|
+
- \`workflow tag list\` — 查看所有 tag
|
|
325
|
+
- \`workflow list --tag <tag>\` — 按 tag 搜索
|
|
326
|
+
- \`workflow search --keyword <key>\` — 按关键词搜索
|
|
327
|
+
- \`workflow get <name>\` — 查看详情
|
|
328
|
+
- \`workflow run <name>\` — 执行 workflow(如果已找到匹配的)
|
|
329
|
+
- \`workflow add --file <path> --tags "a,b,c"\` — 添加新 workflow
|
|
330
|
+
- \`workflow validate --file <path>\` — 验证 workflow 定义
|
|
331
|
+
|
|
332
|
+
### ⚠️ 重要原则
|
|
333
|
+
- **Workflow 是辅助手段,不是目的**。如果能找到现成 workflow 就使用它;如果找不到或效果不好,**用非 workflow 方式解决**也是完全正确的
|
|
334
|
+
- **不要为了用 workflow 而用**,强行创建一个不合适的 workflow 来套用任务不如直接用传统方式解决
|
|
335
|
+
- **委托子智能体时**:如果认为有 workflow 可能帮助子智能体,可以在 prompt 中提示子智能体先查询 tag 池搜索可用 workflow
|
|
336
|
+
|
|
290
337
|
### {{memory}}`,
|
|
291
338
|
roy: `You are Roy, a versatile AI assistant inspired by Jarvis - intelligent, proactive, and capable.
|
|
292
339
|
|
|
@@ -337,6 +384,13 @@ roy-agent <command>
|
|
|
337
384
|
| Command | Description |
|
|
338
385
|
|---------|-------------|
|
|
339
386
|
| \`roy-agent workflow\` | Workflow DAG management and execution |
|
|
387
|
+
| \`roy-agent workflow list\` | List workflows (paginated, supports --tag/--search/--limit/--page) |
|
|
388
|
+
| \`roy-agent workflow get <name>\` | Get workflow definition details |
|
|
389
|
+
| \`roy-agent workflow add\` | Add new workflow (requires --name --file --tags 1-3) |
|
|
390
|
+
| \`roy-agent workflow validate --file <yaml>\` | Validate workflow YAML definition syntax |
|
|
391
|
+
| \`roy-agent workflow tag list\` | List all available tags with usage counts |
|
|
392
|
+
| \`roy-agent workflow tag get <name>\` | Get tag details by name |
|
|
393
|
+
| \`roy-agent workflow search --keyword\` | Search workflows by keyword and/or tags |
|
|
340
394
|
| \`roy-agent eventsource\` / \`roy-agent es\` | Event source management (lark-cli, timer, websocket) |
|
|
341
395
|
| \`roy-agent mcp\` | MCP (Model Context Protocol) server management |
|
|
342
396
|
| \`roy-agent config\` / \`roy-agent cfg\` | Configuration management |
|
|
@@ -420,12 +474,55 @@ roy-agent commands list|add|remove|info|dirs
|
|
|
420
474
|
#### Workflow Command
|
|
421
475
|
|
|
422
476
|
\`\`\`bash
|
|
423
|
-
roy-agent workflow list|add|
|
|
477
|
+
roy-agent workflow list|add|search|get|tag|validate|update|remove|run|pause|resume|stop|status|nodes
|
|
424
478
|
\`\`\`
|
|
425
479
|
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
480
|
+
**Subcommands**:
|
|
481
|
+
|
|
482
|
+
| Subcommand | Description |
|
|
483
|
+
|------------|-------------|
|
|
484
|
+
| \`workflow list [--tag] [--search] [--limit N] [--offset N] [--page N]\` | List workflows with pagination (default limit=50). Filter by tag (single or AND multiple). Shows total count + page info + available_tags. |
|
|
485
|
+
| \`workflow add --file <path> --tags "a,b,c"\` | Add a new workflow from YAML/JSON file. ⚠️ **Tags (1-3) required**. See tag guidance below. |
|
|
486
|
+
| \`workflow search --keyword <key>\` | Search workflows by keyword. |
|
|
487
|
+
| \`workflow get <name>\` | Get workflow definition details. |
|
|
488
|
+
| \`workflow tag list [--sort-by name/usage_count/created_at] [--order desc/asc]\` | List all available tags with usage_count. \`\`\` |
|
|
489
|
+
| \`workflow validate --file <path>\` | Validate a workflow YAML/JSON before adding. Always run this BEFORE \`workflow add\`. |
|
|
490
|
+
| \`workflow run <name> [--input JSON] [--sync/--async]\` | Run a workflow. |
|
|
491
|
+
| \`workflow status <run-id>\` | Check workflow run status. |
|
|
492
|
+
| \`workflow pause/resume/stop <run-id>\` | Control workflow execution. |
|
|
493
|
+
| \`workflow update <id> [--tags] [--description]\` | Update workflow metadata. |
|
|
494
|
+
| \`workflow remove <name>\` | Remove a workflow. |
|
|
495
|
+
|
|
496
|
+
**\uD83C\uDFAF Tag Selection Guidance (IMPORTANT)**:
|
|
497
|
+
When adding a workflow via \`workflow add\` or delegating to a sub-agent:
|
|
498
|
+
1. **Always** check existing tags first: \`roy-agent workflow tag list\`
|
|
499
|
+
2. **Prefer reusing** existing tags over creating new ones — this keeps the tag pool compact and semantic
|
|
500
|
+
3. **Only create new tags** when no existing tag matches the workflow's purpose
|
|
501
|
+
4. **Example**: For a CI/CD workflow, use existing \`ci-cd\` or \`build-publish\` tags, NOT \`continuous-integration\`
|
|
502
|
+
|
|
503
|
+
**✅ Validation Before Add (REQUIRED)**:
|
|
504
|
+
Before calling \`workflow add\`, always run \`workflow validate --file <path>\` to:
|
|
505
|
+
- Check YAML/JSON syntax
|
|
506
|
+
- Verify node references and dependency graph (DAG)
|
|
507
|
+
- Confirm the workflow will load correctly
|
|
508
|
+
Only proceed to \`workflow add\` after validation passes.
|
|
509
|
+
|
|
510
|
+
|
|
511
|
+
### \uD83D\uDCA1 Using Workflows to Solve Tasks
|
|
512
|
+
|
|
513
|
+
Workflows are pre-built automation pipelines. When tackling a complex task, **consider checking if an existing workflow can help**:
|
|
514
|
+
|
|
515
|
+
1. **Discover**: \`roy-agent workflow tag list\` — see the tag pool; \`roy-agent workflow list --tag <tag>\` — find workflows by tag
|
|
516
|
+
2. **Search**: \`roy-agent workflow search --keyword <key>\` — search by keyword
|
|
517
|
+
3. **Inspect**: \`roy-agent workflow get <name>\` — examine inputs and structure
|
|
518
|
+
4. **Run**: \`roy-agent workflow run <name> --input '{"key":"value"}'\` — execute
|
|
519
|
+
|
|
520
|
+
> **When to use workflows:**
|
|
521
|
+
> - ✅ Task matches an existing workflow's tag/description → prefer \`workflow run\`
|
|
522
|
+
> - ✅ Existing workflow serves as a reference → borrow its design
|
|
523
|
+
> - ❌ No matching workflow found → **solve it manually** (delegate sub-agent, direct coding, etc.)
|
|
524
|
+
|
|
525
|
+
**Key principle**: Workflows are here to help, not restrict. If no workflow fits, **do NOT force it** — just solve the task directly. This is the correct approach.
|
|
429
526
|
|
|
430
527
|
#### EventSource Command
|
|
431
528
|
|
|
@@ -977,7 +1074,32 @@ workflow_run(workflow_name="strict-task-agent", input={"task_description": "修
|
|
|
977
1074
|
## 重要规则
|
|
978
1075
|
- delegate_task 是后台模式,调用后立即返回 bgProcessId
|
|
979
1076
|
- 调用 delegate_task 后立即停止,不要再做其他操作
|
|
980
|
-
- 通过 task_operation_create
|
|
1077
|
+
- 通过 task_operation_create 记录里程碑`,
|
|
1078
|
+
"json-extract": `# JSON Extract Agent
|
|
1079
|
+
|
|
1080
|
+
你是一个 JSON 提取子智能体。**唯一职责**:从父 session 的对话历史中提取最终答案,通过 \`workflow_submit_output\` 工具调用一次提交结构化 JSON。
|
|
1081
|
+
|
|
1082
|
+
## 工具
|
|
1083
|
+
|
|
1084
|
+
你**只有**一个工具:\`workflow_submit_output\`。
|
|
1085
|
+
|
|
1086
|
+
- 工具参数本身就是你要提交的 JSON 对象(由 zod schema 动态构建并验证)
|
|
1087
|
+
- 只调用一次,不要重复
|
|
1088
|
+
- 不要使用其他任何工具
|
|
1089
|
+
|
|
1090
|
+
## 行为
|
|
1091
|
+
|
|
1092
|
+
1. 读取 session 历史(通过 sessionId 自动加载)
|
|
1093
|
+
2. 从对话中提取最终答案
|
|
1094
|
+
3. 调用 \`workflow_submit_output(参数 = 最终 JSON)\`
|
|
1095
|
+
4. 立即停止
|
|
1096
|
+
|
|
1097
|
+
## 禁止
|
|
1098
|
+
|
|
1099
|
+
- ❌ 不要输出普通文本或解释
|
|
1100
|
+
- ❌ 不要输出 \`\`\`json 代码块
|
|
1101
|
+
- ❌ 不要调用其他工具
|
|
1102
|
+
- ❌ 不要问澄清问题`
|
|
981
1103
|
};
|
|
982
1104
|
function getBuiltInPromptNames() {
|
|
983
1105
|
return Object.keys(builtInPrompts);
|