@ai-setting/roy-agent-core 1.5.15-test → 1.5.17-beta.1

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.
Files changed (141) hide show
  1. package/dist/config/index.d.ts +1250 -0
  2. package/dist/config/index.js +32 -0
  3. package/dist/env/agent/index.d.ts +2279 -0
  4. package/dist/env/agent/index.js +24 -0
  5. package/dist/env/commands/index.d.ts +1131 -0
  6. package/dist/env/commands/index.js +14 -0
  7. package/dist/env/debug/formatters/index.d.ts +236 -0
  8. package/dist/env/debug/formatters/index.js +11 -0
  9. package/dist/env/debug/index.d.ts +1652 -0
  10. package/dist/env/debug/index.js +26 -0
  11. package/dist/env/hook/index.d.ts +279 -0
  12. package/dist/env/hook/index.js +29 -0
  13. package/dist/env/index.d.ts +3481 -0
  14. package/dist/env/index.js +82 -0
  15. package/dist/env/llm/index.d.ts +1760 -0
  16. package/dist/env/llm/index.js +40 -0
  17. package/dist/env/log-trace/index.d.ts +1574 -0
  18. package/dist/env/log-trace/index.js +83 -0
  19. package/dist/env/mcp/index.d.ts +1331 -0
  20. package/dist/env/mcp/index.js +39 -0
  21. package/dist/env/mcp/tool/index.d.ts +183 -0
  22. package/dist/env/mcp/tool/index.js +14 -0
  23. package/dist/env/memory/built-in/index.d.ts +232 -0
  24. package/dist/env/memory/built-in/index.js +11 -0
  25. package/dist/env/memory/index.d.ts +1799 -0
  26. package/dist/env/memory/index.js +56 -0
  27. package/dist/env/memory/plugin/index.d.ts +747 -0
  28. package/dist/env/memory/plugin/index.js +36 -0
  29. package/dist/env/prompt/index.d.ts +1164 -0
  30. package/dist/env/prompt/index.js +20 -0
  31. package/dist/env/session/index.d.ts +1908 -0
  32. package/dist/env/session/index.js +25 -0
  33. package/dist/env/session/storage/index.d.ts +564 -0
  34. package/dist/env/session/storage/index.js +18 -0
  35. package/dist/env/skill/index.d.ts +1266 -0
  36. package/dist/env/skill/index.js +34 -0
  37. package/dist/env/skill/tool/index.d.ts +193 -0
  38. package/dist/env/skill/tool/index.js +9 -0
  39. package/dist/env/task/delegate/index.d.ts +1612 -0
  40. package/dist/env/task/delegate/index.js +18 -0
  41. package/dist/env/task/events/index.d.ts +171 -0
  42. package/dist/env/task/events/index.js +7 -0
  43. package/dist/env/task/hooks/index.d.ts +624 -0
  44. package/dist/env/task/hooks/index.js +7 -0
  45. package/dist/env/task/index.d.ts +1553 -0
  46. package/dist/env/task/index.js +34 -0
  47. package/dist/env/task/plugins/index.d.ts +466 -0
  48. package/dist/env/task/plugins/index.js +23 -0
  49. package/dist/env/task/storage/index.d.ts +241 -0
  50. package/dist/env/task/storage/index.js +14 -0
  51. package/dist/env/task/tools/index.d.ts +1485 -0
  52. package/dist/env/task/tools/index.js +17 -0
  53. package/dist/env/task/tools/operation/index.d.ts +1484 -0
  54. package/dist/env/task/tools/operation/index.js +15 -0
  55. package/dist/env/tool/built-in/index.d.ts +218 -0
  56. package/dist/env/tool/built-in/index.js +25 -0
  57. package/dist/env/tool/index.d.ts +1396 -0
  58. package/dist/env/tool/index.js +39 -0
  59. package/dist/env/workflow/decorators/index.d.ts +2161 -0
  60. package/dist/env/workflow/decorators/index.js +27 -0
  61. package/dist/env/workflow/engine/index.d.ts +3453 -0
  62. package/dist/env/workflow/engine/index.js +28 -0
  63. package/dist/env/workflow/index.d.ts +3546 -0
  64. package/dist/env/workflow/index.js +136 -0
  65. package/dist/env/workflow/nodes/index.d.ts +2092 -0
  66. package/dist/env/workflow/nodes/index.js +19 -0
  67. package/dist/env/workflow/service/index.d.ts +227 -0
  68. package/dist/env/workflow/service/index.js +13 -0
  69. package/dist/env/workflow/storage/index.d.ts +165 -0
  70. package/dist/env/workflow/storage/index.js +27 -0
  71. package/dist/env/workflow/tools/index.d.ts +416 -0
  72. package/dist/env/workflow/tools/index.js +159 -0
  73. package/dist/env/workflow/types/index.d.ts +2255 -0
  74. package/dist/env/workflow/types/index.js +98 -0
  75. package/dist/env/workflow/utils/index.d.ts +2031 -0
  76. package/dist/env/workflow/utils/index.js +637 -0
  77. package/dist/index.d.ts +7858 -0
  78. package/dist/index.js +399 -0
  79. package/dist/shared/@ai-setting/roy-agent-core-0rtxwr28.js +258 -0
  80. package/dist/shared/@ai-setting/roy-agent-core-0vbdz0x7.js +36 -0
  81. package/dist/shared/@ai-setting/roy-agent-core-1akcqxj9.js +349 -0
  82. package/dist/shared/@ai-setting/roy-agent-core-1ce3fqrk.js +117 -0
  83. package/dist/shared/@ai-setting/roy-agent-core-2dhd60aw.js +11 -0
  84. package/dist/shared/@ai-setting/roy-agent-core-3jywqmdd.js +393 -0
  85. package/dist/shared/@ai-setting/roy-agent-core-3rr5k71j.js +200 -0
  86. package/dist/shared/@ai-setting/roy-agent-core-44hnfb02.js +299 -0
  87. package/dist/shared/@ai-setting/roy-agent-core-4t40mkpv.js +206 -0
  88. package/dist/shared/@ai-setting/roy-agent-core-4txzpsbt.js +393 -0
  89. package/dist/shared/@ai-setting/roy-agent-core-5x94xmt6.js +350 -0
  90. package/dist/shared/@ai-setting/roy-agent-core-69jskqjg.js +180 -0
  91. package/dist/shared/@ai-setting/roy-agent-core-6kvtahqv.js +408 -0
  92. package/dist/shared/@ai-setting/roy-agent-core-7fgf85wc.js +284 -0
  93. package/dist/shared/@ai-setting/roy-agent-core-81w1963m.js +762 -0
  94. package/dist/shared/@ai-setting/roy-agent-core-8gxth0eh.js +10 -0
  95. package/dist/shared/@ai-setting/roy-agent-core-92z6t4he.js +14 -0
  96. package/dist/shared/@ai-setting/roy-agent-core-93zfb3r1.js +922 -0
  97. package/dist/shared/@ai-setting/roy-agent-core-9yxb3ty9.js +15 -0
  98. package/dist/shared/@ai-setting/roy-agent-core-b0x5dda6.js +1130 -0
  99. package/dist/shared/@ai-setting/roy-agent-core-bcbqy27c.js +14 -0
  100. package/dist/shared/@ai-setting/roy-agent-core-bvr1761x.js +653 -0
  101. package/dist/shared/@ai-setting/roy-agent-core-ctdhjv68.js +93 -0
  102. package/dist/shared/@ai-setting/roy-agent-core-d7cyjkf7.js +872 -0
  103. package/dist/shared/@ai-setting/roy-agent-core-dh9d7a3m.js +11 -0
  104. package/dist/shared/@ai-setting/roy-agent-core-e25xkv53.js +64 -0
  105. package/dist/shared/@ai-setting/roy-agent-core-eajcvp4e.js +378 -0
  106. package/dist/shared/@ai-setting/roy-agent-core-f7q2x5z6.js +492 -0
  107. package/dist/shared/@ai-setting/roy-agent-core-fs0mn2jk.js +52 -0
  108. package/dist/shared/@ai-setting/roy-agent-core-g1s2h0e5.js +171 -0
  109. package/dist/shared/@ai-setting/roy-agent-core-g99pxzn5.js +862 -0
  110. package/dist/shared/@ai-setting/roy-agent-core-gbqcyegm.js +1387 -0
  111. package/dist/shared/@ai-setting/roy-agent-core-gjq1yk68.js +208 -0
  112. package/dist/shared/@ai-setting/roy-agent-core-gq20wsgv.js +139 -0
  113. package/dist/shared/@ai-setting/roy-agent-core-gwc4h96n.js +534 -0
  114. package/dist/shared/@ai-setting/roy-agent-core-jfh9q2qh.js +204 -0
  115. package/dist/shared/@ai-setting/roy-agent-core-jvatggbb.js +603 -0
  116. package/dist/shared/@ai-setting/roy-agent-core-kkbwepqb.js +97 -0
  117. package/dist/shared/@ai-setting/roy-agent-core-pjr12nnd.js +587 -0
  118. package/dist/shared/@ai-setting/roy-agent-core-psv4v63c.js +176 -0
  119. package/dist/shared/@ai-setting/roy-agent-core-psvxt4c9.js +60 -0
  120. package/dist/shared/@ai-setting/roy-agent-core-qqceba6k.js +442 -0
  121. package/dist/shared/@ai-setting/roy-agent-core-qxhq8ven.js +57 -0
  122. package/dist/shared/@ai-setting/roy-agent-core-qxnbvgwe.js +66 -0
  123. package/dist/shared/@ai-setting/roy-agent-core-r9ezzemr.js +10 -0
  124. package/dist/shared/@ai-setting/roy-agent-core-rhmtwnw1.js +267 -0
  125. package/dist/shared/@ai-setting/roy-agent-core-rvv6ydff.js +584 -0
  126. package/dist/shared/@ai-setting/roy-agent-core-rvxg1wps.js +102 -0
  127. package/dist/shared/@ai-setting/roy-agent-core-satmq6sh.js +549 -0
  128. package/dist/shared/@ai-setting/roy-agent-core-sx7wsvnn.js +15 -0
  129. package/dist/shared/@ai-setting/roy-agent-core-t94ktchq.js +213 -0
  130. package/dist/shared/@ai-setting/roy-agent-core-vf215qfv.js +812 -0
  131. package/dist/shared/@ai-setting/roy-agent-core-vkz81f7v.js +1316 -0
  132. package/dist/shared/@ai-setting/roy-agent-core-vn2bc59q.js +1205 -0
  133. package/dist/shared/@ai-setting/roy-agent-core-wa1kzqky.js +328 -0
  134. package/dist/shared/@ai-setting/roy-agent-core-wft9ra24.js +20 -0
  135. package/dist/shared/@ai-setting/roy-agent-core-wrcy0h6z.js +2098 -0
  136. package/dist/shared/@ai-setting/roy-agent-core-xq8hhqb8.js +419 -0
  137. package/dist/shared/@ai-setting/roy-agent-core-xs5rsgat.js +368 -0
  138. package/dist/shared/@ai-setting/roy-agent-core-zbkpc41z.js +377 -0
  139. package/dist/shared/@ai-setting/roy-agent-core-zgypchmt.js +172 -0
  140. package/dist/shared/@ai-setting/roy-agent-core-zpn0bqa8.js +103 -0
  141. package/package.json +29 -8
@@ -0,0 +1,393 @@
1
+ import {
2
+ TaskHookPoints
3
+ } from "./roy-agent-core-92z6t4he.js";
4
+ import {
5
+ createLogger,
6
+ init_logger
7
+ } from "./roy-agent-core-44hnfb02.js";
8
+ import {
9
+ __require
10
+ } from "./roy-agent-core-fs0mn2jk.js";
11
+
12
+ // src/env/task/plugins/task-plugin.ts
13
+ class TaskPlugin {
14
+ config;
15
+ constructor(config = {}) {
16
+ this.config = { enabled: true, priority: 0, ...config };
17
+ }
18
+ getHookPoints() {
19
+ return this.hooks.map((h) => h.point);
20
+ }
21
+ getPriorityForHook(hookPoint) {
22
+ const hook = this.hooks.find((h) => h.point === hookPoint);
23
+ return hook?.priority ?? this.config.priority ?? 0;
24
+ }
25
+ isEnabled() {
26
+ return this.config.enabled ?? true;
27
+ }
28
+ setEnabled(enabled) {
29
+ this.config.enabled = enabled;
30
+ }
31
+ }
32
+ // src/env/task/plugins/task-tag-plugin.ts
33
+ init_logger();
34
+
35
+ // src/env/task/plugins/workflow-extractor-agent.ts
36
+ var WORKFLOW_EXTRACTOR_PROMPT = `你是 Workflow 提取专家,负责将自然语言描述转换为符合规范的 Workflow YAML。
37
+
38
+ ## 提取原则
39
+
40
+ 1. **优先具象节点**:优先使用特定工具节点(如 read_file, write_file, grep, bash 等)
41
+ 2. **Fallback 到通用节点**:没有对应工具时,使用 agent/llm/bash 节点
42
+ 3. **避免条件分支**:不提取循环和条件判断,保持线性流程
43
+ 4. **泛化但可执行**:步骤描述可泛化,但节点类型和工具要具体
44
+
45
+ ## 构建流程
46
+
47
+ **重要**:构建的 Workflow 必须通过 \`roy workflow validate\` 验证才能输出。
48
+
49
+ \`\`\`
50
+ 1. 理解用户需求
51
+ 2. 参考 roy workflow nodes 查看可用节点类型
52
+ 3. 参考 roy workflow get <name> 查看已有 workflow 示例
53
+ 4. 生成 Workflow YAML
54
+ 5. 使用 roy workflow validate --yaml "<生成的YAML>" 验证
55
+ 6. 验证通过后输出最终结果
56
+ \`\`\`
57
+
58
+ ## 验证检查清单
59
+
60
+ 完成 Workflow 构建后,必须使用以下命令验证:
61
+
62
+ \`\`\`bash
63
+ roy workflow validate --yaml "<your-yaml>"
64
+ \`\`\`
65
+
66
+ 验证通过后(无错误输出)才输出最终结果。验证失败时根据错误信息修正后重新验证。
67
+
68
+ ## 可用的 Workflow 节点类型
69
+
70
+ 使用以下命令查看所有节点类型的详细配置:
71
+
72
+ \`\`\`bash
73
+ roy workflow nodes # 列出所有节点类型
74
+ roy workflow nodes <type> # 查看特定节点详情(如 tool, agent, skill)
75
+ \`\`\`
76
+
77
+ **支持的节点类型:**
78
+ - **tool**:执行工具(bash, read-file, write-file, grep 等)
79
+ - **skill**:调用技能
80
+ - **agent**:AI Agent
81
+ - **workflow**:子工作流
82
+ - **condition**:条件判断
83
+ - **merge**:合并结果
84
+ - **decorator**:装饰器方法
85
+
86
+ ## 查看已有 Workflow 示例
87
+
88
+ 使用以下命令查看已有 workflow 的 YAML 结构:
89
+
90
+ \`\`\`bash
91
+ roy workflow list # 列出所有 workflow
92
+ roy workflow get <name> # 获取指定 workflow 详情(YAML 格式)
93
+ \`\`\`
94
+
95
+ ## 输出要求
96
+
97
+ 验证通过后,输出符合以下格式的 YAML Workflow:
98
+
99
+ \`\`\`yaml
100
+ name: {泛化的任务名称}
101
+ version: "1.0"
102
+ description: {一句话描述}
103
+ nodes:
104
+ - id: node-1
105
+ type: tool|skill|agent|workflow|condition|merge|decorator
106
+ name: {节点名称}
107
+ config:
108
+ # 根据类型配置必填字段:
109
+ # tool: tool, input/args
110
+ # skill: skill, input
111
+ # agent: agent_type, prompt, options
112
+ # workflow: workflow_name, input
113
+ # condition: condition
114
+ # merge: strategy, depends_on
115
+ # decorator: _methodName, _instance
116
+ depends_on: []
117
+ outputs: []
118
+ \`\`\`
119
+
120
+ ## 限制
121
+
122
+ - 至少 2 个节点才有意义
123
+ - 不要生成条件节点(if/else/switch)
124
+ - 不要生成循环节点(while/for)
125
+ - 每个节点要有清晰的名称和描述
126
+ - 必须为 tool 节点指定 tool 名称
127
+ - 必须为 agent 节点指定 agent_type 和 prompt`;
128
+ function createWorkflowExtractorAgent() {
129
+ return {
130
+ type: "sub",
131
+ name: "workflow-extractor",
132
+ systemPrompt: WORKFLOW_EXTRACTOR_PROMPT,
133
+ maxIterations: 10,
134
+ filterHistory: false
135
+ };
136
+ }
137
+ function formatExtractorInput(params) {
138
+ const lines = [];
139
+ lines.push("# 任务信息");
140
+ lines.push(`- 标题: ${params.task.title}`);
141
+ if (params.task.description) {
142
+ lines.push(`- 描述: ${params.task.description}`);
143
+ }
144
+ if (params.task.goals_and_expected_deliverables) {
145
+ lines.push(`- 目标: ${params.task.goals_and_expected_deliverables}`);
146
+ }
147
+ lines.push("");
148
+ if (params.operations.length > 0) {
149
+ lines.push("# 操作记录");
150
+ for (const op of params.operations) {
151
+ lines.push(`- [${op.actionType}] ${op.actionTitle}`);
152
+ if (op.actionDescription) {
153
+ lines.push(` ${op.actionDescription.slice(0, 200)}`);
154
+ }
155
+ }
156
+ lines.push("");
157
+ }
158
+ lines.push("# Session 消息历史");
159
+ lines.push("(以下是相关的对话历史,请从中提取 Workflow)");
160
+ for (const msg of params.messages.slice(-50)) {
161
+ const content = typeof msg.content === "string" ? msg.content : JSON.stringify(msg.content);
162
+ const truncated = content.slice(0, 500);
163
+ lines.push(`**${msg.role}**: ${truncated}${content.length > 500 ? "..." : ""}`);
164
+ }
165
+ lines.push("");
166
+ lines.push("## 任务");
167
+ lines.push("请分析以上信息,构建一个可复用的 Workflow。");
168
+ lines.push("使用迭代式流程:生成 YAML → validate 验证 → 修正错误 → 重复直到通过验证。");
169
+ return lines.join(`
170
+ `);
171
+ }
172
+ function formatExtractorInputFromDescription(params) {
173
+ const lines = [];
174
+ lines.push("# Workflow 描述");
175
+ lines.push(params.description);
176
+ lines.push("");
177
+ lines.push("## 任务");
178
+ lines.push("请根据以上描述,构建一个可复用的 Workflow。");
179
+ lines.push("使用迭代式流程:生成 YAML → validate 验证 → 修正错误 → 重复直到通过验证。");
180
+ return lines.join(`
181
+ `);
182
+ }
183
+ async function parseExtractorOutput(output) {
184
+ const yamlMatch = output.match(/```yaml\n?([\s\S]*?)\n?```/) || output.match(/```\n?([\s\S]*?)\n?```/) || output.match(/(\|[\s\S]*?)(?:\n\n|$)/);
185
+ const yamlContent = yamlMatch?.[1] || output;
186
+ try {
187
+ const YAML = await import("yaml");
188
+ const parsed = YAML.parse(yamlContent);
189
+ if (!parsed.name || !parsed.nodes || !Array.isArray(parsed.nodes)) {
190
+ return null;
191
+ }
192
+ if (parsed.nodes.length < 2) {
193
+ return null;
194
+ }
195
+ parsed.version = parsed.version || "1.0";
196
+ return parsed;
197
+ } catch {
198
+ return null;
199
+ }
200
+ }
201
+
202
+ // src/env/task/plugins/task-tag-plugin.ts
203
+ var logger = createLogger("task:plugin:tag");
204
+
205
+ class TaskTagPlugin extends TaskPlugin {
206
+ name = "TaskTagPlugin";
207
+ hooks = [
208
+ { point: TaskHookPoints.DELEGATE_BEFORE, priority: 20 },
209
+ { point: TaskHookPoints.OPERATION_AFTER_CREATE, priority: 10 }
210
+ ];
211
+ taskComponent = null;
212
+ agentComponent = null;
213
+ constructor(config = {}) {
214
+ super({ enabled: true, priority: 0, ...config });
215
+ }
216
+ static getRequiredAgents() {
217
+ return [createWorkflowExtractorAgent()];
218
+ }
219
+ setComponents(_llmComponent, taskComponent) {
220
+ this.taskComponent = taskComponent;
221
+ if (taskComponent?.env) {
222
+ this.agentComponent = taskComponent.env.getComponent("agent");
223
+ }
224
+ }
225
+ async execute(ctx) {
226
+ if (!this.config.enabled)
227
+ return;
228
+ switch (ctx.hookPoint) {
229
+ case TaskHookPoints.DELEGATE_BEFORE:
230
+ await this.onDelegateBefore(ctx);
231
+ break;
232
+ case TaskHookPoints.OPERATION_AFTER_CREATE:
233
+ await this.onOperationAfterCreate(ctx);
234
+ break;
235
+ }
236
+ }
237
+ async onDelegateBefore(ctx) {
238
+ const { taskId, tagService, prompt } = ctx.data;
239
+ if (!taskId || !this.taskComponent) {
240
+ return;
241
+ }
242
+ try {
243
+ const currentTask = await this.taskComponent.getTask(taskId);
244
+ if (!currentTask)
245
+ return;
246
+ const keywords = this.extractKeywords(currentTask);
247
+ if (keywords.length === 0)
248
+ return;
249
+ const tagServiceForSearch = tagService;
250
+ const similarTasks = await tagServiceForSearch?.findSimilarTasksByKeywords?.(keywords, {
251
+ limit: 5,
252
+ excludeTaskId: taskId
253
+ }) ?? [];
254
+ if (similarTasks.length === 0)
255
+ return;
256
+ const hint = this.formatSimilarTasks(similarTasks);
257
+ ctx.data.prompt = `${hint}
258
+
259
+ ---
260
+
261
+ ## 用户指令
262
+
263
+ ${prompt}`;
264
+ logger.info(`[TaskTagPlugin] Injected ${similarTasks.length} similar tasks`);
265
+ } catch (error) {
266
+ logger.warn(`[TaskTagPlugin] Similar tasks injection failed: ${error}`);
267
+ }
268
+ }
269
+ extractKeywords(task) {
270
+ const keywords = [];
271
+ if (task.tags?.length) {
272
+ keywords.push(...task.tags);
273
+ }
274
+ if (task.title) {
275
+ const words = task.title.split(/[\s\-_,,。、#]+/).filter((w) => w.length > 2 && !/^\d+$/.test(w)).slice(0, 5);
276
+ keywords.push(...words);
277
+ }
278
+ return keywords;
279
+ }
280
+ formatSimilarTasks(tasks) {
281
+ const lines = [
282
+ "## \uD83D\uDD0D 类似任务参考",
283
+ "",
284
+ "_提示:可通过 `task_get <id>` 获取详情,`task_operation_list <id>` 获取操作记录_",
285
+ ""
286
+ ];
287
+ for (const task of tasks) {
288
+ lines.push(`### Task #${task.id}`);
289
+ lines.push(`**Title**: ${task.title}`);
290
+ if (task.description) {
291
+ const desc = task.description.slice(0, 100);
292
+ lines.push(`**Description**: ${desc}${task.description.length > 100 ? "..." : ""}`);
293
+ }
294
+ if (task.goals_and_expected_deliverables) {
295
+ const goal = task.goals_and_expected_deliverables.slice(0, 100);
296
+ lines.push(`**Goal**: ${goal}${task.goals_and_expected_deliverables.length > 100 ? "..." : ""}`);
297
+ }
298
+ lines.push("");
299
+ }
300
+ return lines.join(`
301
+ `);
302
+ }
303
+ async onOperationAfterCreate(ctx) {
304
+ const data = ctx.data;
305
+ const operation = data?.operation ?? data?.data?.operation;
306
+ if (!operation || operation?.actionType !== "completed")
307
+ return;
308
+ await this.extractWorkflow(operation.taskId, operation.sessionId);
309
+ }
310
+ async extractWorkflow(taskId, sessionId) {
311
+ try {
312
+ const task = await this.taskComponent?.getTask(taskId);
313
+ if (!task)
314
+ return;
315
+ const operations = await this.taskComponent?.listOperations({ taskId }) ?? [];
316
+ const allSessionIds = [...new Set([sessionId, ...operations.map((op) => op.sessionId).filter(Boolean)])];
317
+ const sessionComponent = this.taskComponent?.env?.getComponent("session");
318
+ const allMessages = [];
319
+ for (const sid of allSessionIds) {
320
+ try {
321
+ const ctx = await sessionComponent?.getContext(sid, { fullHistory: false, minUserMessages: 200 });
322
+ if (ctx?.messages)
323
+ allMessages.push(...ctx.messages);
324
+ } catch {}
325
+ }
326
+ if (!this.agentComponent)
327
+ return;
328
+ const input = formatExtractorInput({ task, operations, messages: allMessages });
329
+ const result = await this.agentComponent.run("workflow-extractor", input);
330
+ const workflowDef = await parseExtractorOutput(result.finalText || "");
331
+ if (!workflowDef)
332
+ return;
333
+ const workflowRepo = await this.getWorkflowRepository();
334
+ if (!workflowRepo)
335
+ return;
336
+ let version = workflowDef.version || "1.0";
337
+ const existingWf = workflowRepo.getByName(workflowDef.name);
338
+ if (existingWf) {
339
+ const parts = existingWf.version?.split(".") ?? ["1", "0"];
340
+ version = `${parts[0]}.${parseInt(parts[1] || "0") + 1}`;
341
+ }
342
+ const workflow = workflowRepo.create({
343
+ name: workflowDef.name,
344
+ version,
345
+ description: workflowDef.description,
346
+ definition: workflowDef,
347
+ config: workflowDef.config || {},
348
+ metadata: { author: "workflow-extractor", created_at: new Date().toISOString() },
349
+ tags: [`task:${taskId}`]
350
+ });
351
+ await this.taskComponent?.createOperation({
352
+ taskId,
353
+ sessionId,
354
+ actionType: "workflow_extracted",
355
+ actionTitle: `Workflow extracted: ${workflow.name}`,
356
+ actionDescription: workflow.id
357
+ });
358
+ logger.info(`Workflow extracted: ${workflow.id}`);
359
+ } catch (error) {
360
+ logger.warn(`Workflow extraction failed: ${error}`);
361
+ }
362
+ }
363
+ async getWorkflowRepository() {
364
+ const workflowComponent = this.taskComponent?.env?.getComponent("workflow");
365
+ if (workflowComponent?.workflowService?.workflowRepository) {
366
+ return workflowComponent.workflowService.workflowRepository;
367
+ }
368
+ if (!this._workflowRepo) {
369
+ try {
370
+ const sqlite = await import("./roy-agent-core-wft9ra24.js");
371
+ this.ensureDataDir();
372
+ const db = sqlite.getDatabase();
373
+ sqlite.initializeTables();
374
+ const { WorkflowRepository } = await import("./roy-agent-core-bcbqy27c.js");
375
+ this._workflowRepo = new WorkflowRepository(db);
376
+ return this._workflowRepo;
377
+ } catch {
378
+ return null;
379
+ }
380
+ }
381
+ return this._workflowRepo;
382
+ }
383
+ ensureDataDir() {
384
+ const { join } = __require("path");
385
+ const { mkdirSync, existsSync } = __require("fs");
386
+ const home = process.env.HOME || process.env.USERPROFILE || "/tmp";
387
+ const dataDir = join(home, ".local", "share", "roy-agent");
388
+ if (!existsSync(dataDir))
389
+ mkdirSync(dataDir, { recursive: true });
390
+ }
391
+ _workflowRepo = null;
392
+ }
393
+ export { TaskPlugin, WORKFLOW_EXTRACTOR_PROMPT, createWorkflowExtractorAgent, formatExtractorInput, formatExtractorInputFromDescription, parseExtractorOutput, TaskTagPlugin };
@@ -0,0 +1,200 @@
1
+ import {
2
+ getDatabase
3
+ } from "./roy-agent-core-zpn0bqa8.js";
4
+ import {
5
+ exports_search_query_parser,
6
+ init_search_query_parser
7
+ } from "./roy-agent-core-rvxg1wps.js";
8
+ import {
9
+ __toCommonJS
10
+ } from "./roy-agent-core-fs0mn2jk.js";
11
+
12
+ // src/env/workflow/storage/workflow-repo.ts
13
+ import { randomUUID } from "crypto";
14
+ function rowToWorkflow(row) {
15
+ const metadata = JSON.parse(row.metadata);
16
+ if (row.task_id !== null) {
17
+ metadata.taskId = row.task_id;
18
+ }
19
+ return {
20
+ id: row.id,
21
+ name: row.name,
22
+ version: row.version,
23
+ description: row.description || undefined,
24
+ definition: JSON.parse(row.definition),
25
+ config: JSON.parse(row.config),
26
+ metadata,
27
+ tags: JSON.parse(row.tags),
28
+ createdAt: new Date(row.created_at),
29
+ updatedAt: new Date(row.updated_at)
30
+ };
31
+ }
32
+
33
+ class WorkflowRepository {
34
+ db;
35
+ constructor(db) {
36
+ this.db = db || getDatabase();
37
+ }
38
+ create(workflow) {
39
+ const id = randomUUID();
40
+ const now = new Date().toISOString();
41
+ const stmt = this.db.prepare(`
42
+ INSERT INTO workflows (id, name, version, description, definition, config, metadata, tags, task_id, created_at, updated_at)
43
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
44
+ `);
45
+ stmt.run(id, workflow.name, workflow.version, workflow.description || null, JSON.stringify(workflow.definition), JSON.stringify(workflow.config), JSON.stringify(workflow.metadata), JSON.stringify(workflow.tags), workflow.metadata?.taskId || null, now, now);
46
+ return {
47
+ ...workflow,
48
+ id,
49
+ createdAt: new Date(now),
50
+ updatedAt: new Date(now)
51
+ };
52
+ }
53
+ createFromDefinition(definition, options) {
54
+ const workflow = {
55
+ name: definition.name,
56
+ version: definition.version,
57
+ description: definition.description,
58
+ definition,
59
+ config: options?.config || definition.config || {},
60
+ metadata: options?.metadata || definition.metadata || {},
61
+ tags: options?.tags || definition.metadata?.tags || []
62
+ };
63
+ return this.create(workflow);
64
+ }
65
+ getById(id) {
66
+ const row = this.db.prepare("SELECT * FROM workflows WHERE id = ?").get(id);
67
+ if (!row)
68
+ return;
69
+ return rowToWorkflow(row);
70
+ }
71
+ getByName(name) {
72
+ const row = this.db.prepare("SELECT * FROM workflows WHERE name = ? ORDER BY updated_at DESC LIMIT 1").get(name);
73
+ if (!row)
74
+ return;
75
+ return rowToWorkflow(row);
76
+ }
77
+ getByNameAndVersion(name, version) {
78
+ const row = this.db.prepare("SELECT * FROM workflows WHERE name = ? AND version = ?").get(name, version);
79
+ if (!row)
80
+ return;
81
+ return rowToWorkflow(row);
82
+ }
83
+ list(options) {
84
+ let sql = "SELECT * FROM workflows";
85
+ const params = [];
86
+ const conditions = [];
87
+ if (options?.tag) {
88
+ conditions.push("tags LIKE ?");
89
+ params.push(`%${options.tag}%`);
90
+ }
91
+ if (options?.taskId !== undefined) {
92
+ conditions.push("task_id = ?");
93
+ params.push(options.taskId);
94
+ }
95
+ if (conditions.length > 0) {
96
+ sql += " WHERE " + conditions.join(" AND ");
97
+ }
98
+ const orderBy = options?.orderBy || "updated_at";
99
+ const order = options?.order || "desc";
100
+ sql += ` ORDER BY ${orderBy} ${order.toUpperCase()}`;
101
+ if (options?.limit !== undefined) {
102
+ sql += " LIMIT ?";
103
+ params.push(options.limit);
104
+ }
105
+ if (options?.offset !== undefined) {
106
+ sql += " OFFSET ?";
107
+ params.push(options.offset);
108
+ }
109
+ const rows = this.db.prepare(sql).all(...params);
110
+ let workflows = rows.map(rowToWorkflow);
111
+ if (options?.search) {
112
+ const { parseSearchQuery, matchesQuery } = (init_search_query_parser(), __toCommonJS(exports_search_query_parser));
113
+ const query = parseSearchQuery(options.search);
114
+ workflows = workflows.filter((w) => {
115
+ const descMatch = w.description ? matchesQuery(w.description, query) : false;
116
+ const tagsMatch = w.tags.some((tag) => matchesQuery(tag, query));
117
+ return descMatch || tagsMatch;
118
+ });
119
+ }
120
+ return workflows;
121
+ }
122
+ listVersions(name) {
123
+ const rows = this.db.prepare("SELECT * FROM workflows WHERE name = ? ORDER BY version DESC").all(name);
124
+ return rows.map(rowToWorkflow);
125
+ }
126
+ update(id, updates) {
127
+ const existing = this.getById(id);
128
+ if (!existing)
129
+ return;
130
+ const now = new Date().toISOString();
131
+ const setClauses = ["updated_at = ?"];
132
+ const params = [now];
133
+ if (updates.name !== undefined) {
134
+ setClauses.push("name = ?");
135
+ params.push(updates.name);
136
+ }
137
+ if (updates.version !== undefined) {
138
+ setClauses.push("version = ?");
139
+ params.push(updates.version);
140
+ }
141
+ if (updates.description !== undefined) {
142
+ setClauses.push("description = ?");
143
+ params.push(updates.description);
144
+ }
145
+ if (updates.definition !== undefined) {
146
+ setClauses.push("definition = ?");
147
+ params.push(JSON.stringify(updates.definition));
148
+ }
149
+ if (updates.config !== undefined) {
150
+ setClauses.push("config = ?");
151
+ params.push(JSON.stringify(updates.config));
152
+ }
153
+ if (updates.metadata !== undefined) {
154
+ setClauses.push("metadata = ?");
155
+ params.push(JSON.stringify(updates.metadata));
156
+ if (updates.metadata.taskId !== undefined) {
157
+ setClauses.push("task_id = ?");
158
+ params.push(updates.metadata.taskId);
159
+ }
160
+ }
161
+ if (updates.tags !== undefined) {
162
+ setClauses.push("tags = ?");
163
+ params.push(JSON.stringify(updates.tags));
164
+ }
165
+ params.push(id);
166
+ this.db.prepare(`UPDATE workflows SET ${setClauses.join(", ")} WHERE id = ?`).run(...params);
167
+ return this.getById(id);
168
+ }
169
+ delete(id) {
170
+ const existing = this.getById(id);
171
+ if (!existing)
172
+ return false;
173
+ this.db.prepare("DELETE FROM workflows WHERE id = ?").run(id);
174
+ return true;
175
+ }
176
+ exists(id) {
177
+ const result = this.db.prepare("SELECT 1 FROM workflows WHERE id = ?").get(id);
178
+ return result !== undefined;
179
+ }
180
+ existsByNameAndVersion(name, version) {
181
+ const result = this.db.prepare("SELECT 1 FROM workflows WHERE name = ? AND version = ?").get(name, version);
182
+ return result !== undefined;
183
+ }
184
+ count() {
185
+ const result = this.db.prepare("SELECT COUNT(*) as count FROM workflows").get();
186
+ return result.count;
187
+ }
188
+ search(query, limit) {
189
+ let sql = "SELECT * FROM workflows WHERE name LIKE ? ORDER BY updated_at DESC";
190
+ const params = [`%${query}%`];
191
+ if (limit !== undefined) {
192
+ sql += " LIMIT ?";
193
+ params.push(limit);
194
+ }
195
+ const rows = this.db.prepare(sql).all(...params);
196
+ return rows.map(rowToWorkflow);
197
+ }
198
+ }
199
+
200
+ export { rowToWorkflow, WorkflowRepository };