@ai-setting/roy-agent-core 1.7.72 → 1.7.76
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/agent-component.js +6 -6
- package/dist/env/agent/agent-registry.d.ts +4 -1
- package/dist/env/agent/index.js +6 -6
- package/dist/env/error-reply.d.ts +46 -0
- package/dist/env/error-reply.js +3 -1
- package/dist/env/event-source/event-source-handlers.js +13 -12
- package/dist/env/event-source/index.js +14 -13
- package/dist/env/index.js +31 -30
- package/dist/env/llm/index.js +2 -2
- package/dist/env/llm/orphan-toolcall.d.ts +107 -0
- package/dist/env/plugin/index.js +3 -3
- package/dist/env/prompt/index.js +4 -3
- package/dist/env/prompt/prompts-index.d.ts +27 -3
- package/dist/env/session/index.js +4 -4
- package/dist/env/session/storage/index.js +3 -3
- package/dist/env/task/backend/index.js +9 -1
- package/dist/env/task/delegate/delegate-tool.d.ts +8 -0
- package/dist/env/task/delegate/delegate-tool.js +5 -4
- package/dist/env/task/delegate/index.js +5 -4
- package/dist/env/task/hooks/contexts.d.ts +12 -1
- package/dist/env/task/hooks/task-hook-points.d.ts +8 -3
- package/dist/env/task/index.d.ts +1 -0
- package/dist/env/task/index.js +17 -7
- package/dist/env/task/mcp/index.js +3 -2
- package/dist/env/task/plugins/index.d.ts +3 -0
- package/dist/env/task/plugins/index.js +33 -9
- package/dist/env/task/plugins/lark-card-patch-notifier.d.ts +61 -0
- package/dist/env/task/plugins/lark-card-patch-notifier.js +6 -2
- package/dist/env/task/plugins/lark-cli-task-notify-plugin.d.ts +42 -0
- package/dist/env/task/prompt/index.js +2 -1
- package/dist/env/task/prompt/task-discipline.d.ts +9 -3
- package/dist/env/task/task-component.d.ts +79 -0
- package/dist/env/task/tools/cancel-tool.d.ts +36 -0
- package/dist/env/task/tools/completion-copy.d.ts +92 -0
- package/dist/env/task/tools/index.d.ts +2 -0
- package/dist/env/task/tools/index.js +7 -2
- package/dist/env/task/tools/pre-complete-tool.d.ts +32 -0
- package/dist/env/task/tools/task-types.d.ts +71 -17
- package/dist/env/task/types.d.ts +13 -1
- package/dist/env/tool/built-in/compact-session-tool.d.ts +120 -0
- package/dist/env/tool/built-in/index.d.ts +2 -0
- package/dist/env/tool/built-in/index.js +6 -2
- package/dist/env/tool/index.js +4 -4
- package/dist/env/workflow/engine/index.js +6 -6
- package/dist/env/workflow/index.js +15 -13
- package/dist/env/workflow/plugins/index.js +2 -2
- package/dist/env/workflow/tools/ask-user-tool.d.ts +88 -0
- package/dist/env/workflow/tools/index.js +11 -9
- package/dist/env/workflow/tools/run-workflow.d.ts +2 -2
- package/dist/env/workflow/types/index.js +2 -2
- package/dist/env/workflow/types/workflow-hil.d.ts +25 -1
- package/dist/env/workflow/utils/index.js +5 -5
- package/dist/index.d.ts +1 -1
- package/dist/index.js +43 -33
- package/dist/shared/@ai-setting/{roy-agent-core-sm0sf6sb.js → roy-agent-core-0qyrk5k0.js} +2 -2
- package/dist/shared/@ai-setting/{roy-agent-core-kmbct9yg.js → roy-agent-core-0snm5hc5.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-yr1mryb8.js → roy-agent-core-1v4g0d4x.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-rxb00gjm.js → roy-agent-core-264qexac.js} +1 -1
- package/dist/shared/@ai-setting/roy-agent-core-2akfd64z.js +374 -0
- package/dist/shared/@ai-setting/{roy-agent-core-skyc30qx.js → roy-agent-core-3fh1f7s7.js} +2 -2
- package/dist/shared/@ai-setting/roy-agent-core-4rtg69cn.js +26 -0
- package/dist/shared/@ai-setting/{roy-agent-core-add1zqsh.js → roy-agent-core-6cy43nss.js} +22 -1
- package/dist/shared/@ai-setting/{roy-agent-core-vah6g5yx.js → roy-agent-core-6rh8k6ba.js} +5 -5
- package/dist/shared/@ai-setting/{roy-agent-core-kpg25s2q.js → roy-agent-core-8ez6mccb.js} +4 -2
- package/dist/shared/@ai-setting/{roy-agent-core-yhwxpj12.js → roy-agent-core-9vxh6f8h.js} +233 -16
- package/dist/shared/@ai-setting/{roy-agent-core-7qvw65jt.js → roy-agent-core-aa2j7bk9.js} +11 -8
- package/dist/shared/@ai-setting/{roy-agent-core-sjr1kmfz.js → roy-agent-core-acj8ag08.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-mds8tqd0.js → roy-agent-core-cgtq6427.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-34jz9mgh.js → roy-agent-core-cmprygrp.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-wr7mv7k3.js → roy-agent-core-cxy143m4.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-pakhchy7.js → roy-agent-core-ddyk1rc0.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-attpry6g.js → roy-agent-core-dqxec05w.js} +4 -3
- package/dist/shared/@ai-setting/{roy-agent-core-vm8h5zyj.js → roy-agent-core-ed233k5z.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-jrj30vq3.js → roy-agent-core-er070zjq.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-40rv283c.js → roy-agent-core-fghc2m8z.js} +152 -2
- package/dist/shared/@ai-setting/{roy-agent-core-5gw0qa8m.js → roy-agent-core-ghnagzrh.js} +557 -92
- package/dist/shared/@ai-setting/{roy-agent-core-4jjwewvw.js → roy-agent-core-m46fe3x4.js} +41 -30
- package/dist/shared/@ai-setting/{roy-agent-core-e25xkv53.js → roy-agent-core-mkc3zshb.js} +3 -1
- package/dist/shared/@ai-setting/{roy-agent-core-hfyfavp3.js → roy-agent-core-mww0mnd9.js} +231 -27
- package/dist/shared/@ai-setting/{roy-agent-core-46rv4d7d.js → roy-agent-core-nmx9934r.js} +92 -2
- package/dist/shared/@ai-setting/{roy-agent-core-1w9y7mxj.js → roy-agent-core-p3zv1mx5.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-jgb3bb42.js → roy-agent-core-q5r75vev.js} +17 -8
- package/dist/shared/@ai-setting/{roy-agent-core-y12kyxwa.js → roy-agent-core-t3rrb959.js} +33 -9
- package/dist/shared/@ai-setting/{roy-agent-core-dt104qa1.js → roy-agent-core-v85n42ve.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-gr48c89p.js → roy-agent-core-v87njmq7.js} +3 -3
- package/dist/shared/@ai-setting/{roy-agent-core-7sj9xs9c.js → roy-agent-core-vffccgf6.js} +252 -25
- package/dist/shared/@ai-setting/{roy-agent-core-2gzt2q8c.js → roy-agent-core-z43aj03k.js} +134 -29
- package/dist/shared/@ai-setting/roy-agent-core-zycadbpx.js +662 -0
- package/package.json +1 -1
- package/dist/shared/@ai-setting/roy-agent-core-1p6syv85.js +0 -1083
- package/dist/shared/@ai-setting/roy-agent-core-58804s3j.js +0 -155
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import {
|
|
2
|
+
TASK_COMPLETE_ITEM_BY_ITEM,
|
|
3
|
+
TASK_COMPLETE_VERIFY_DUTY,
|
|
4
|
+
TASK_COMPLETION_HINT_ANCHOR
|
|
5
|
+
} from "./roy-agent-core-4rtg69cn.js";
|
|
5
6
|
|
|
6
7
|
// src/env/task/prompt/task-discipline.ts
|
|
7
8
|
var TASK_DISCIPLINE_LIFECYCLE = `### Task Lifecycle (7 steps, 0-6)
|
|
@@ -52,13 +53,21 @@ var TASK_DISCIPLINE_LIFECYCLE = `### Task Lifecycle (7 steps, 0-6)
|
|
|
52
53
|
|
|
53
54
|
4. TRACK
|
|
54
55
|
- Update progress (0-100%) as the work advances
|
|
55
|
-
- Update status: todo → active
|
|
56
|
+
- Update status: todo → active
|
|
56
57
|
- Record \`current_status\` with human-readable progress
|
|
58
|
+
- ⚠️ **不要**把 status 直接置为 \`completed\` 或 \`to_validate\` ——
|
|
59
|
+
终态由验收方落、待验证由 \`task_pre_complete\` 提交(见步骤 6)
|
|
57
60
|
|
|
58
61
|
5. RECORD — operation records (see Operation Discipline below)
|
|
59
62
|
|
|
60
|
-
6. COMPLETE —
|
|
61
|
-
|
|
63
|
+
6. COMPLETE — 收尾分两种角色(Task #5007/#5073,验收权分离)
|
|
64
|
+
- **执行方(roy sub-agent)**:进度达到你判断的 100% ⇒
|
|
65
|
+
\`task_pre_complete\` **提交待验证**(\`deliverable_storage_path\`
|
|
66
|
+
传交付物地址;status → to_validate,并触发一次 goal 检查自查)
|
|
67
|
+
+ 最后一条 \`task_operation_create\` ⇒ **结束并返回结果**。
|
|
68
|
+
❌ **不要调用 \`task_complete\`**(你无此权限)。
|
|
69
|
+
- **验收方(default agent / 接待员)**:\`task_complete\` after item-by-item verification
|
|
70
|
+
(see Complete Discipline below)`.trim();
|
|
62
71
|
var TASK_DISCIPLINE_OPERATION = `### Operation Record — 双维度分工规范
|
|
63
72
|
|
|
64
73
|
**Record milestones as you work** — call \`task_operation_create\` the moment a
|
|
@@ -124,7 +133,11 @@ Reference the four atomic assertion forms (Task #4768
|
|
|
124
133
|
- 进程断言 (process assertion): command exit code / stdout match
|
|
125
134
|
- 测试断言 (test assertion): pass/fail counts, no NEW fail
|
|
126
135
|
- 状态断言 (state assertion): version number / HTTP 200 / status field`;
|
|
127
|
-
var TASK_DISCIPLINE_COMPLETE = `### Task Complete —
|
|
136
|
+
var TASK_DISCIPLINE_COMPLETE = `### Task Complete — 核实义务(**仅验收方适用**)
|
|
137
|
+
|
|
138
|
+
> ⚠️ **角色作用域(Task #5007)**:本节是**验收方**(default agent / 接待员)的动作。
|
|
139
|
+
> 若你是**执行方**(roy sub-agent),你没有 \`task_complete\` 权限 ——
|
|
140
|
+
> 你的收尾动作是「进度推到 100% + 记完操作记录 + 结束返回」,验收由主智能体负责。
|
|
128
141
|
|
|
129
142
|
Before calling \`task_complete\`, you MUST:
|
|
130
143
|
|
|
@@ -142,34 +155,32 @@ Before calling \`task_complete\`, you MUST:
|
|
|
142
155
|
\`[${TASK_COMPLETION_HINT_ANCHOR}]\`.
|
|
143
156
|
- **If you receive a [${TASK_COMPLETION_HINT_ANCHOR}]**, you MUST verify it
|
|
144
157
|
(${TASK_COMPLETE_VERIFY_DUTY}): re-read the task via \`task_get\`, then do exactly one of:
|
|
145
|
-
(a) 确认未完成 →
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
158
|
+
(a) 确认未完成 → **重新委托**(用你的委托工具 + 同一 sub-session 续跑,
|
|
159
|
+
在指令里写明"目标尚未达成,需要补 X/Y/Z"),由 sub-agent 用
|
|
160
|
+
\`task_update(status=active)\` 重开并继续推进;若你**自己就是执行方**
|
|
161
|
+
(有 \`task_update\` 权限),则直接 \`task_update(status=todo)\` 重开;或
|
|
162
|
+
(b) 确认已完成 → **用你手上有权限的写工具**落一条 \`decision\` 类操作记录
|
|
163
|
+
(\`task_operation_create\`,milestone_type=decision,milestone_title=<一行结论>)
|
|
164
|
+
说明子项实际已达成(说明理由)。若你没有该工具的权限(验收方场景),
|
|
165
|
+
就通过你的**委托工具**让 sub-agent 代写这条记录,或在最终汇报里
|
|
166
|
+
明确写出核实结论与证据。
|
|
150
167
|
Never ignore it (不允许无视).
|
|
168
|
+
⚠️ **核实义务的两条路径都依赖写权限**(\`task_update\` / \`task_operation_create\`)。
|
|
169
|
+
若这些工具对你**不可用**(如验收方不持有执行类工具),必须**改用委托**把动作
|
|
170
|
+
交回给有权限的 sub-agent 执行 —— 不要试图调用不可用的工具(会被拦掉并浪费一轮迭代)。
|
|
151
171
|
- If the goal and delivery mismatch **without** a hint, either:
|
|
152
172
|
(a) extend the task via \`task_update\`, or
|
|
153
173
|
(b) record the discrepancy via \`task_operation_create\`
|
|
154
174
|
(milestone_type=decision) — the reason **must** land in the
|
|
155
175
|
operation record (必须落到操作记录里), not merely a line in
|
|
156
176
|
your final report (不能只在报告里带一句).
|
|
157
|
-
3.
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
\`
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
- Feishu doc URL (e.g., https://my.feishu.cn/docx/abc)
|
|
165
|
-
- Local file path (e.g., /tmp/report.md)
|
|
166
|
-
- Git branch or worktree path (e.g., feature/my-feature)
|
|
167
|
-
- GitHub commit URL or PR URL
|
|
168
|
-
- Cloud drive URL (e.g., https://my.feishu.cn/file/abc)
|
|
169
|
-
- Or any other locator that points to where the work product lives
|
|
170
|
-
|
|
171
|
-
The \`deliverable_storage_path\` will be persisted to the task's
|
|
172
|
-
\`context.deliverable_storage_path\` for future reference and traceability.`;
|
|
177
|
+
3. Deliverables were submitted by the executor via \`task_pre_complete\`
|
|
178
|
+
(Task #5073 two-phase acceptance): they live in
|
|
179
|
+
\`context.deliverable_storage_path\` and the operation trail
|
|
180
|
+
(\`Deliverable: <path>\` lines). Cross-check them in step 2.
|
|
181
|
+
\`task_complete\` takes **no** deliverable parameter — if the
|
|
182
|
+
deliverables are missing from the record, re-delegate instead of
|
|
183
|
+
asking for a path here.`;
|
|
173
184
|
var TASK_DISCIPLINE_PROMPT = [
|
|
174
185
|
TASK_DISCIPLINE_LIFECYCLE,
|
|
175
186
|
TASK_DISCIPLINE_OPERATION,
|
|
@@ -179,4 +190,4 @@ var TASK_DISCIPLINE_PROMPT = [
|
|
|
179
190
|
|
|
180
191
|
`);
|
|
181
192
|
|
|
182
|
-
export {
|
|
193
|
+
export { TASK_DISCIPLINE_LIFECYCLE, TASK_DISCIPLINE_OPERATION, TASK_DISCIPLINE_GOALS, TASK_DISCIPLINE_COMPLETE, TASK_DISCIPLINE_PROMPT };
|
|
@@ -35,9 +35,10 @@ var init_workflow_hil = __esm(() => {
|
|
|
35
35
|
query;
|
|
36
36
|
agentSessionId;
|
|
37
37
|
timestamp;
|
|
38
|
+
delivered;
|
|
38
39
|
type = "ask-user";
|
|
39
40
|
name = "AskUserError";
|
|
40
|
-
constructor(runId, sessionId, nodeId, nodeType, query, agentSessionId, timestamp = Date.now()) {
|
|
41
|
+
constructor(runId, sessionId, nodeId, nodeType, query, agentSessionId, timestamp = Date.now(), delivered = false) {
|
|
41
42
|
super(`[${nodeType}:${nodeId}] Ask user: ${query}`);
|
|
42
43
|
this.runId = runId;
|
|
43
44
|
this.sessionId = sessionId;
|
|
@@ -46,6 +47,7 @@ var init_workflow_hil = __esm(() => {
|
|
|
46
47
|
this.query = query;
|
|
47
48
|
this.agentSessionId = agentSessionId;
|
|
48
49
|
this.timestamp = timestamp;
|
|
50
|
+
this.delivered = delivered;
|
|
49
51
|
}
|
|
50
52
|
toEvent() {
|
|
51
53
|
return {
|
|
@@ -1,20 +1,29 @@
|
|
|
1
1
|
import {
|
|
2
2
|
isValidSessionId
|
|
3
|
-
} from "./roy-agent-core-
|
|
3
|
+
} from "./roy-agent-core-ddyk1rc0.js";
|
|
4
4
|
import {
|
|
5
5
|
TAG_MAX_COUNT,
|
|
6
6
|
TAG_MIN_COUNT
|
|
7
7
|
} from "./roy-agent-core-12n08pg5.js";
|
|
8
|
+
import {
|
|
9
|
+
deliverAskUserMessage
|
|
10
|
+
} from "./roy-agent-core-6cy43nss.js";
|
|
8
11
|
import {
|
|
9
12
|
validateWorkflowDefinition
|
|
10
|
-
} from "./roy-agent-core-
|
|
13
|
+
} from "./roy-agent-core-1v4g0d4x.js";
|
|
11
14
|
import {
|
|
12
15
|
getCurrentBgTaskId
|
|
13
16
|
} from "./roy-agent-core-c1v263jn.js";
|
|
14
17
|
import {
|
|
15
18
|
AskUserError,
|
|
16
19
|
init_workflow_hil
|
|
17
|
-
} from "./roy-agent-core-
|
|
20
|
+
} from "./roy-agent-core-mkc3zshb.js";
|
|
21
|
+
import {
|
|
22
|
+
init_context
|
|
23
|
+
} from "./roy-agent-core-qqaak24r.js";
|
|
24
|
+
import {
|
|
25
|
+
getEnvContext
|
|
26
|
+
} from "./roy-agent-core-7cbpmk4q.js";
|
|
18
27
|
import {
|
|
19
28
|
TracedAs,
|
|
20
29
|
init_decorator
|
|
@@ -30,12 +39,185 @@ import {
|
|
|
30
39
|
|
|
31
40
|
// src/env/workflow/tools/ask-user-tool.ts
|
|
32
41
|
init_workflow_hil();
|
|
42
|
+
init_context();
|
|
43
|
+
init_logger();
|
|
33
44
|
import { z } from "zod";
|
|
45
|
+
var logger = createLogger("AskUserTool");
|
|
34
46
|
var AskUserInputSchema = z.object({
|
|
35
47
|
query: z.string().describe("The question or request to ask the user"),
|
|
36
48
|
options: z.array(z.string()).optional().describe("Optional choices for the user"),
|
|
37
49
|
required_confirm: z.boolean().optional().describe("If true, user must explicitly confirm")
|
|
38
50
|
});
|
|
51
|
+
function isProcessingAskUserEvent(envContext) {
|
|
52
|
+
const type = envContext?.envEvent?.type;
|
|
53
|
+
return type === "task.background.ask_user";
|
|
54
|
+
}
|
|
55
|
+
function getEnvContextSafe() {
|
|
56
|
+
try {
|
|
57
|
+
return getEnvContext();
|
|
58
|
+
} catch {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
function resolveDeliveryTarget(context) {
|
|
63
|
+
if (context.metadata?.askUserDelivery === "off") {
|
|
64
|
+
return { skipReason: "off" };
|
|
65
|
+
}
|
|
66
|
+
let envContext;
|
|
67
|
+
try {
|
|
68
|
+
envContext = getEnvContext();
|
|
69
|
+
} catch {
|
|
70
|
+
envContext = undefined;
|
|
71
|
+
}
|
|
72
|
+
if (!envContext)
|
|
73
|
+
return {};
|
|
74
|
+
if (isProcessingAskUserEvent(envContext)) {
|
|
75
|
+
const payloadDelivered = envContext.envEvent?.payload?.delivered;
|
|
76
|
+
if (payloadDelivered === true) {
|
|
77
|
+
return { skipReason: "guarded-turn" };
|
|
78
|
+
}
|
|
79
|
+
const fallback = resolveDeliveryTargetFromContext(context, envContext);
|
|
80
|
+
return { ...fallback, skipReason: "delivery-failed" };
|
|
81
|
+
}
|
|
82
|
+
return resolveDeliveryTargetFromContext(context, envContext);
|
|
83
|
+
}
|
|
84
|
+
function resolveDeliveryTargetFromContext(_context, envContext) {
|
|
85
|
+
const replyChannel = envContext.replyChannel;
|
|
86
|
+
if (replyChannel) {
|
|
87
|
+
const hasSender = typeof replyChannel.sendMarkdown === "function" || typeof replyChannel.sendText === "function" || typeof replyChannel.reply === "function";
|
|
88
|
+
if (!replyChannel.chatId && !replyChannel.messageId) {
|
|
89
|
+
return {};
|
|
90
|
+
}
|
|
91
|
+
return {
|
|
92
|
+
target: {
|
|
93
|
+
chatId: replyChannel.chatId,
|
|
94
|
+
messageId: replyChannel.messageId,
|
|
95
|
+
profile: replyChannel.profile,
|
|
96
|
+
...hasSender ? { channel: replyChannel } : {}
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
const metaChannel = envContext.envEvent?.metadata?.replyChannel;
|
|
101
|
+
if (metaChannel?.chatId || metaChannel?.messageId) {
|
|
102
|
+
return {
|
|
103
|
+
target: {
|
|
104
|
+
chatId: metaChannel.chatId,
|
|
105
|
+
messageId: metaChannel.messageId,
|
|
106
|
+
profile: metaChannel.profile
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
return {};
|
|
111
|
+
}
|
|
112
|
+
function buildAskUserDeliveryText(args) {
|
|
113
|
+
const lines = [];
|
|
114
|
+
lines.push("❓ **需要您确认**");
|
|
115
|
+
lines.push("");
|
|
116
|
+
lines.push(args.query.trim());
|
|
117
|
+
if (args.options && args.options.length > 0) {
|
|
118
|
+
lines.push("");
|
|
119
|
+
lines.push("**可选方案:**");
|
|
120
|
+
args.options.forEach((opt, i) => {
|
|
121
|
+
lines.push(`${i + 1}. ${opt}`);
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
if (args.requiredConfirm) {
|
|
125
|
+
lines.push("");
|
|
126
|
+
lines.push("(需要您明确确认后才会继续)");
|
|
127
|
+
}
|
|
128
|
+
lines.push("");
|
|
129
|
+
lines.push("\uD83D\uDC49 直接在本会话回复文字或序号即可(例如「1」)。");
|
|
130
|
+
return lines.join(`
|
|
131
|
+
`);
|
|
132
|
+
}
|
|
133
|
+
var DELIVERY_TIMEOUT_MS = 15000;
|
|
134
|
+
function withDeliveryTimeout(p, ms) {
|
|
135
|
+
return new Promise((resolve) => {
|
|
136
|
+
let settled = false;
|
|
137
|
+
const timer = setTimeout(() => {
|
|
138
|
+
if (settled)
|
|
139
|
+
return;
|
|
140
|
+
settled = true;
|
|
141
|
+
resolve(null);
|
|
142
|
+
}, ms);
|
|
143
|
+
timer.unref?.();
|
|
144
|
+
p.then((v) => {
|
|
145
|
+
if (settled)
|
|
146
|
+
return;
|
|
147
|
+
settled = true;
|
|
148
|
+
clearTimeout(timer);
|
|
149
|
+
resolve(v);
|
|
150
|
+
}, () => {
|
|
151
|
+
if (settled)
|
|
152
|
+
return;
|
|
153
|
+
settled = true;
|
|
154
|
+
clearTimeout(timer);
|
|
155
|
+
resolve(null);
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
async function deliverAskUserToChannel(target, text) {
|
|
160
|
+
const channel = target.channel;
|
|
161
|
+
if (channel) {
|
|
162
|
+
try {
|
|
163
|
+
if (typeof channel.sendMarkdown === "function") {
|
|
164
|
+
const r = await withDeliveryTimeout(Promise.resolve(channel.sendMarkdown(text)), DELIVERY_TIMEOUT_MS);
|
|
165
|
+
if (r === null) {
|
|
166
|
+
logger.warn("[ask_user] Channel delivery timed out (ignored)", {
|
|
167
|
+
chatId: target.chatId,
|
|
168
|
+
timeoutMs: DELIVERY_TIMEOUT_MS
|
|
169
|
+
});
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
return true;
|
|
173
|
+
}
|
|
174
|
+
if (typeof channel.sendText === "function") {
|
|
175
|
+
const r = await withDeliveryTimeout(Promise.resolve(channel.sendText(text)), DELIVERY_TIMEOUT_MS);
|
|
176
|
+
if (r === null) {
|
|
177
|
+
logger.warn("[ask_user] Channel delivery timed out (ignored)", {
|
|
178
|
+
chatId: target.chatId,
|
|
179
|
+
timeoutMs: DELIVERY_TIMEOUT_MS
|
|
180
|
+
});
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
183
|
+
return true;
|
|
184
|
+
}
|
|
185
|
+
if (typeof channel.reply === "function" && target.messageId) {
|
|
186
|
+
const r = await withDeliveryTimeout(Promise.resolve(channel.reply(text)), DELIVERY_TIMEOUT_MS);
|
|
187
|
+
if (r === null) {
|
|
188
|
+
logger.warn("[ask_user] Channel delivery timed out (ignored)", {
|
|
189
|
+
chatId: target.chatId,
|
|
190
|
+
timeoutMs: DELIVERY_TIMEOUT_MS
|
|
191
|
+
});
|
|
192
|
+
return false;
|
|
193
|
+
}
|
|
194
|
+
return true;
|
|
195
|
+
}
|
|
196
|
+
return false;
|
|
197
|
+
} catch (err) {
|
|
198
|
+
logger.warn("[ask_user] Failed to deliver question to channel (ignored)", {
|
|
199
|
+
error: err instanceof Error ? err.message : String(err),
|
|
200
|
+
chatId: target.chatId
|
|
201
|
+
});
|
|
202
|
+
return false;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
if (!target.chatId && !target.messageId)
|
|
206
|
+
return false;
|
|
207
|
+
const result = await deliverAskUserMessage({
|
|
208
|
+
chatId: target.chatId,
|
|
209
|
+
messageId: target.messageId,
|
|
210
|
+
profile: target.profile,
|
|
211
|
+
content: text
|
|
212
|
+
});
|
|
213
|
+
if (!result.sent) {
|
|
214
|
+
logger.warn("[ask_user] Failed to deliver question via lark-cli (ignored)", {
|
|
215
|
+
error: result.error,
|
|
216
|
+
chatId: target.chatId
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
return result.sent;
|
|
220
|
+
}
|
|
39
221
|
var askUserTool = {
|
|
40
222
|
name: "ask_user",
|
|
41
223
|
description: "Ask user for input or confirmation. Use this tool when you need user input or validation to continue the workflow.",
|
|
@@ -48,7 +230,29 @@ var askUserTool = {
|
|
|
48
230
|
if (args.options && args.options.length > 0) {
|
|
49
231
|
fullQuery = `${args.query} (选项: ${args.options.join(", ")})`;
|
|
50
232
|
}
|
|
51
|
-
|
|
233
|
+
const resolved = resolveDeliveryTarget(context);
|
|
234
|
+
const target = resolved.target;
|
|
235
|
+
let delivered = false;
|
|
236
|
+
if (resolved.skipReason === "guarded-turn") {
|
|
237
|
+
delivered = true;
|
|
238
|
+
logger.info("[ask_user] Guarded turn — question already delivered by sub-agent, skip (delivered=true)", {
|
|
239
|
+
envEventType: getEnvContextSafe()?.envEvent?.type
|
|
240
|
+
});
|
|
241
|
+
} else if (target) {
|
|
242
|
+
const text = buildAskUserDeliveryText({
|
|
243
|
+
query: args.query,
|
|
244
|
+
options: args.options,
|
|
245
|
+
requiredConfirm: args.required_confirm
|
|
246
|
+
});
|
|
247
|
+
delivered = await deliverAskUserToChannel(target, text);
|
|
248
|
+
logger.info("[ask_user] Question delivered to channel", {
|
|
249
|
+
chatId: target.chatId,
|
|
250
|
+
delivered,
|
|
251
|
+
skipReason: resolved.skipReason,
|
|
252
|
+
hasOptions: Boolean(args.options && args.options.length > 0)
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
throw new AskUserError(runId, sessionId, nodeId, "agent", fullQuery, undefined, undefined, delivered);
|
|
52
256
|
},
|
|
53
257
|
metadata: {
|
|
54
258
|
category: "workflow",
|
|
@@ -61,7 +265,7 @@ var askUserToolInstance = askUserTool;
|
|
|
61
265
|
// src/env/workflow/tools/workflow-get-tool.ts
|
|
62
266
|
init_logger();
|
|
63
267
|
import { z as z2 } from "zod";
|
|
64
|
-
var
|
|
268
|
+
var logger2 = createLogger("workflow-get-tool");
|
|
65
269
|
var WorkflowGetInputSchema = z2.object({
|
|
66
270
|
name: z2.string().optional().describe("Workflow name to get definition details"),
|
|
67
271
|
run_id: z2.string().optional().describe("Run/session ID to get run status")
|
|
@@ -137,7 +341,7 @@ function createWorkflowGetTool(workflowService) {
|
|
|
137
341
|
metadata: { execution_time_ms: 0 }
|
|
138
342
|
};
|
|
139
343
|
} catch (error) {
|
|
140
|
-
|
|
344
|
+
logger2.error("Failed to get workflow info", { error });
|
|
141
345
|
return {
|
|
142
346
|
success: false,
|
|
143
347
|
output: "",
|
|
@@ -152,7 +356,7 @@ function createWorkflowGetTool(workflowService) {
|
|
|
152
356
|
// src/env/workflow/tools/workflow-list-tool.ts
|
|
153
357
|
init_logger();
|
|
154
358
|
import { z as z3 } from "zod";
|
|
155
|
-
var
|
|
359
|
+
var logger3 = createLogger("workflow-list-tool");
|
|
156
360
|
var WorkflowListInputSchema = z3.object({
|
|
157
361
|
tag: z3.string().optional().describe("Filter by single tag (legacy single-tag filter)"),
|
|
158
362
|
tags: z3.array(z3.string()).optional().describe("Filter by multiple tags (AND)"),
|
|
@@ -237,7 +441,7 @@ function createWorkflowListTool(workflowService) {
|
|
|
237
441
|
metadata: { execution_time_ms: 0 }
|
|
238
442
|
};
|
|
239
443
|
} catch (error) {
|
|
240
|
-
|
|
444
|
+
logger3.error("Failed to list workflows", { error });
|
|
241
445
|
return {
|
|
242
446
|
success: false,
|
|
243
447
|
output: "",
|
|
@@ -253,7 +457,7 @@ function createWorkflowListTool(workflowService) {
|
|
|
253
457
|
init_logger();
|
|
254
458
|
init_decorator();
|
|
255
459
|
import { z as z4 } from "zod";
|
|
256
|
-
var
|
|
460
|
+
var logger4 = createLogger("workflow-tag-list-tool");
|
|
257
461
|
var WorkflowTagListInputSchema = z4.object({
|
|
258
462
|
sort_by: z4.enum(["usage_count", "name", "created_at"]).default("usage_count").describe("Sort field: usage_count (default), name, or created_at"),
|
|
259
463
|
order: z4.enum(["asc", "desc"]).default("desc").describe("Sort order: desc (default) or asc"),
|
|
@@ -304,7 +508,7 @@ function createWorkflowTagListTool(workflowService) {
|
|
|
304
508
|
metadata: { execution_time_ms: 0 }
|
|
305
509
|
};
|
|
306
510
|
} catch (error) {
|
|
307
|
-
|
|
511
|
+
logger4.error("Failed to list workflow tags", { error });
|
|
308
512
|
return {
|
|
309
513
|
success: false,
|
|
310
514
|
output: "",
|
|
@@ -320,7 +524,7 @@ function createWorkflowTagListTool(workflowService) {
|
|
|
320
524
|
import { z as z5 } from "zod";
|
|
321
525
|
init_logger();
|
|
322
526
|
import yaml from "yaml";
|
|
323
|
-
var
|
|
527
|
+
var logger5 = createLogger("workflow-add-tool");
|
|
324
528
|
var WorkflowAddInputSchema = z5.object({
|
|
325
529
|
definition: z5.any().optional().describe("Workflow definition object (alternative to definition_yaml)"),
|
|
326
530
|
definition_yaml: z5.string().optional().describe("Workflow definition as YAML or JSON string"),
|
|
@@ -461,7 +665,7 @@ function createWorkflowAddTool(workflowService) {
|
|
|
461
665
|
metadata: { execution_time_ms: 0 }
|
|
462
666
|
};
|
|
463
667
|
}
|
|
464
|
-
|
|
668
|
+
logger5.error("Failed to add workflow", { error });
|
|
465
669
|
return {
|
|
466
670
|
success: false,
|
|
467
671
|
output: "",
|
|
@@ -477,7 +681,7 @@ function createWorkflowAddTool(workflowService) {
|
|
|
477
681
|
init_logger();
|
|
478
682
|
import { z as z6 } from "zod";
|
|
479
683
|
import yaml2 from "yaml";
|
|
480
|
-
var
|
|
684
|
+
var logger6 = createLogger("workflow-validate-tool");
|
|
481
685
|
var WorkflowValidateInputSchema = z6.object({
|
|
482
686
|
definition: z6.any().optional().describe("Workflow definition object (alternative to definition_yaml)"),
|
|
483
687
|
definition_yaml: z6.string().optional().describe("Workflow definition as YAML or JSON string"),
|
|
@@ -611,7 +815,7 @@ Advisory warnings (${warnings.length}) — evaluate and fix where sensible:
|
|
|
611
815
|
metadata: { execution_time_ms: 0 }
|
|
612
816
|
};
|
|
613
817
|
} catch (error) {
|
|
614
|
-
|
|
818
|
+
logger6.error("[workflow_validate] failed", { error });
|
|
615
819
|
return {
|
|
616
820
|
success: false,
|
|
617
821
|
output: "",
|
|
@@ -626,7 +830,7 @@ Advisory warnings (${warnings.length}) — evaluate and fix where sensible:
|
|
|
626
830
|
// src/env/workflow/tools/workflow-search-tool.ts
|
|
627
831
|
init_logger();
|
|
628
832
|
import { z as z7 } from "zod";
|
|
629
|
-
var
|
|
833
|
+
var logger7 = createLogger("workflow-search-tool");
|
|
630
834
|
var WorkflowSearchInputSchema = z7.object({
|
|
631
835
|
keyword: z7.string().optional().describe("Search keyword in name and description (case-insensitive substring)"),
|
|
632
836
|
tags: z7.array(z7.string()).optional().describe("Filter by tags (ALL must match - AND filter)"),
|
|
@@ -677,7 +881,7 @@ function createWorkflowSearchTool(workflowService) {
|
|
|
677
881
|
metadata: { execution_time_ms: 0 }
|
|
678
882
|
};
|
|
679
883
|
} catch (error) {
|
|
680
|
-
|
|
884
|
+
logger7.error("Failed to search workflows", { error });
|
|
681
885
|
return {
|
|
682
886
|
success: false,
|
|
683
887
|
output: "",
|
|
@@ -693,7 +897,7 @@ function createWorkflowSearchTool(workflowService) {
|
|
|
693
897
|
init_logger();
|
|
694
898
|
init_decorator();
|
|
695
899
|
import { z as z8 } from "zod";
|
|
696
|
-
var
|
|
900
|
+
var logger8 = createLogger("run-workflow-tool");
|
|
697
901
|
function synthFallbackRunId(now = Date.now()) {
|
|
698
902
|
return `workflow_${now}_fallback_${Math.random().toString(36).slice(2, 8)}`;
|
|
699
903
|
}
|
|
@@ -701,7 +905,7 @@ function attemptStopOnTimeout(workflowService, runId, reason) {
|
|
|
701
905
|
if (typeof workflowService.stopRun !== "function")
|
|
702
906
|
return;
|
|
703
907
|
workflowService.stopRun(runId, reason).catch((stopErr) => {
|
|
704
|
-
|
|
908
|
+
logger8.warn(`Failed to stop workflow ${runId} after timeout: ${stopErr instanceof Error ? stopErr.message : String(stopErr)}`);
|
|
705
909
|
});
|
|
706
910
|
}
|
|
707
911
|
function buildErrorReturn(args) {
|
|
@@ -922,7 +1126,7 @@ function resolveEffectiveTimeout(workflowService, workflowName, explicitTimeout)
|
|
|
922
1126
|
return declared;
|
|
923
1127
|
}
|
|
924
1128
|
} catch (err) {
|
|
925
|
-
|
|
1129
|
+
logger8.warn(`workflow_run: could not resolve definition for ${workflowName}; ` + `falling back to the default run budget`, { error: err instanceof Error ? err.message : String(err) });
|
|
926
1130
|
}
|
|
927
1131
|
}
|
|
928
1132
|
return DEFAULT_WORKFLOW_RUN_TIMEOUT_MS;
|
|
@@ -951,7 +1155,7 @@ function createRunWorkflowTool(workflowService, hooks) {
|
|
|
951
1155
|
const startTime = Date.now();
|
|
952
1156
|
const { workflow_name, input, session, timeout, node_config } = args;
|
|
953
1157
|
const effectiveTimeout = resolveEffectiveTimeout(workflowService, workflow_name, timeout);
|
|
954
|
-
|
|
1158
|
+
logger8.info(`Running workflow: ${workflow_name}`, {
|
|
955
1159
|
input,
|
|
956
1160
|
timeout: effectiveTimeout,
|
|
957
1161
|
timeoutSource: timeout ? "caller" : "definition-or-default",
|
|
@@ -960,7 +1164,7 @@ function createRunWorkflowTool(workflowService, hooks) {
|
|
|
960
1164
|
const ctxSessionId = typeof ctx?.session_id === "string" && isValidSessionId(ctx.session_id) ? ctx.session_id : undefined;
|
|
961
1165
|
const envSessionId = typeof process.env.ROY_PARENT_SESSION_ID === "string" && isValidSessionId(process.env.ROY_PARENT_SESSION_ID) ? process.env.ROY_PARENT_SESSION_ID : undefined;
|
|
962
1166
|
if (process.env.ROY_PARENT_SESSION_ID && !envSessionId) {
|
|
963
|
-
|
|
1167
|
+
logger8.warn(`Ignoring malformed ROY_PARENT_SESSION_ID env value (must match /^[A-Za-z0-9_-]{8,128}$/); received length=${process.env.ROY_PARENT_SESSION_ID.length}`);
|
|
964
1168
|
}
|
|
965
1169
|
const parentSessionId = ctxSessionId ?? envSessionId;
|
|
966
1170
|
let timeoutHandle;
|
|
@@ -1102,8 +1306,8 @@ function createRunWorkflowTool(workflowService, hooks) {
|
|
|
1102
1306
|
durationMs
|
|
1103
1307
|
});
|
|
1104
1308
|
}
|
|
1105
|
-
if (
|
|
1106
|
-
|
|
1309
|
+
if (logger8?.error) {
|
|
1310
|
+
logger8.error(`Failed to run workflow: ${workflow_name}`, {
|
|
1107
1311
|
error: rawErrorMessage,
|
|
1108
1312
|
errorClassification
|
|
1109
1313
|
});
|
|
@@ -1156,7 +1360,7 @@ function createLegacyRunWorkflowTool(workflowService) {
|
|
|
1156
1360
|
// src/env/workflow/tools/workflow-run-status-tool.ts
|
|
1157
1361
|
init_logger();
|
|
1158
1362
|
import { z as z9 } from "zod";
|
|
1159
|
-
var
|
|
1363
|
+
var logger9 = createLogger("workflow-run-status-tool");
|
|
1160
1364
|
var WorkflowRunStatusInputSchema = z9.object({
|
|
1161
1365
|
run_id: z9.string().describe("Run/session ID to query status")
|
|
1162
1366
|
});
|
|
@@ -1198,7 +1402,7 @@ function createWorkflowRunStatusTool(workflowService) {
|
|
|
1198
1402
|
metadata: { execution_time_ms: 0 }
|
|
1199
1403
|
};
|
|
1200
1404
|
} catch (error) {
|
|
1201
|
-
|
|
1405
|
+
logger9.error("Failed to get run status", { error });
|
|
1202
1406
|
return {
|
|
1203
1407
|
success: false,
|
|
1204
1408
|
output: "",
|
|
@@ -1213,7 +1417,7 @@ function createWorkflowRunStatusTool(workflowService) {
|
|
|
1213
1417
|
// src/env/workflow/tools/workflow-run-stop-tool.ts
|
|
1214
1418
|
init_logger();
|
|
1215
1419
|
import { z as z10 } from "zod";
|
|
1216
|
-
var
|
|
1420
|
+
var logger10 = createLogger("workflow-run-stop-tool");
|
|
1217
1421
|
var WorkflowRunStopInputSchema = z10.object({
|
|
1218
1422
|
run_id: z10.string().describe("Run/session ID to stop"),
|
|
1219
1423
|
reason: z10.string().optional().describe("Optional reason for stopping the workflow")
|
|
@@ -1238,7 +1442,7 @@ function createWorkflowRunStopTool(workflowService) {
|
|
|
1238
1442
|
metadata: { execution_time_ms: 0 }
|
|
1239
1443
|
};
|
|
1240
1444
|
} catch (error) {
|
|
1241
|
-
|
|
1445
|
+
logger10.error("Failed to stop workflow run", { error });
|
|
1242
1446
|
return {
|
|
1243
1447
|
success: false,
|
|
1244
1448
|
output: "",
|