@ai-setting/roy-agent-core 1.7.71 → 1.7.75
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/agent/summary-agent.d.ts +6 -15
- package/dist/env/agent/types.d.ts +0 -17
- 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 +12 -12
- package/dist/env/event-source/index.js +13 -13
- package/dist/env/index.js +30 -31
- package/dist/env/llm/index.js +2 -2
- package/dist/env/llm/orphan-toolcall.d.ts +107 -0
- package/dist/env/llm/temperature-policy.d.ts +107 -0
- package/dist/env/llm/types.d.ts +2 -2
- package/dist/env/plugin/index.js +3 -3
- package/dist/env/prompt/index.js +3 -3
- package/dist/env/prompt/prompts-index.d.ts +26 -4
- package/dist/env/session/__bench__/replay-compact.d.ts +137 -0
- package/dist/env/session/__bench__/run-replay.d.ts +15 -0
- package/dist/env/session/compact-checkpoint-content.d.ts +67 -0
- package/dist/env/session/index.d.ts +1 -0
- package/dist/env/session/index.js +4 -5
- package/dist/env/session/session-component.d.ts +47 -30
- package/dist/env/session/storage/index.js +3 -3
- package/dist/env/session/storage/sqlite.d.ts +8 -0
- package/dist/env/session/types.d.ts +45 -30
- package/dist/env/task/delegate/delegate-tool.d.ts +8 -0
- package/dist/env/task/delegate/delegate-tool.js +4 -4
- package/dist/env/task/delegate/index.js +4 -4
- package/dist/env/task/index.js +7 -7
- package/dist/env/task/mcp/index.js +2 -2
- package/dist/env/task/plugins/index.d.ts +3 -0
- package/dist/env/task/plugins/index.js +32 -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 +1 -1
- package/dist/env/task/prompt/task-discipline.d.ts +9 -3
- package/dist/env/task/tools/cancel-tool.d.ts +28 -0
- package/dist/env/task/tools/index.d.ts +1 -0
- package/dist/env/task/tools/index.js +4 -2
- package/dist/env/task/tools/task-types.d.ts +22 -0
- 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 -7
- package/dist/env/workflow/index.js +15 -14
- 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 -10
- 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 +33 -34
- package/dist/shared/@ai-setting/{roy-agent-core-hy3zn2q2.js → roy-agent-core-0qyrk5k0.js} +22 -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-4jjwewvw.js → roy-agent-core-11shp00p.js} +31 -10
- 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-02j24hrg.js → roy-agent-core-264qexac.js} +71 -4
- package/dist/shared/@ai-setting/{roy-agent-core-9geem94g.js → roy-agent-core-29b6hc39.js} +1 -1
- package/dist/shared/@ai-setting/roy-agent-core-2akfd64z.js +374 -0
- package/dist/shared/@ai-setting/{roy-agent-core-zv8bswpw.js → roy-agent-core-3e6gg17d.js} +120 -28
- package/dist/shared/@ai-setting/{roy-agent-core-8cx7cfdg.js → roy-agent-core-3fh1f7s7.js} +2 -3
- package/dist/shared/@ai-setting/{roy-agent-core-mwa6apzx.js → roy-agent-core-4gr3k7qg.js} +17 -4
- package/dist/shared/@ai-setting/{roy-agent-core-zsbh9bfv.js → roy-agent-core-60jbrfye.js} +6 -6
- 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-mw2cen6s.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-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-9bshyqjn.js → roy-agent-core-ddyk1rc0.js} +183 -132
- package/dist/shared/@ai-setting/{roy-agent-core-hfr6bzts.js → roy-agent-core-djpq6yb0.js} +16 -7
- package/dist/shared/@ai-setting/{roy-agent-core-002g6nfk.js → roy-agent-core-dqxec05w.js} +7 -6
- package/dist/shared/@ai-setting/{roy-agent-core-07fvy74y.js → roy-agent-core-ed233k5z.js} +21 -7
- 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-7sj9xs9c.js → roy-agent-core-hnyk1by7.js} +110 -2
- package/dist/shared/@ai-setting/{roy-agent-core-101qtkyc.js → roy-agent-core-jg65qnwa.js} +11 -8
- 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-0cb6w0k7.js → roy-agent-core-mww0mnd9.js} +231 -27
- package/dist/shared/@ai-setting/{roy-agent-core-5repth1n.js → roy-agent-core-n9q1encx.js} +1 -1
- 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-snvh4s2p.js +662 -0
- 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-37tj4y6a.js → roy-agent-core-v87njmq7.js} +3 -3
- package/dist/shared/@ai-setting/{roy-agent-core-k13pxrpk.js → roy-agent-core-y7x2qzwc.js} +553 -92
- package/package.json +1 -1
- package/dist/shared/@ai-setting/roy-agent-core-1gsbqesr.js +0 -1083
- package/dist/shared/@ai-setting/roy-agent-core-58804s3j.js +0 -155
- package/dist/shared/@ai-setting/roy-agent-core-ze068vc9.js +0 -37
|
@@ -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: "",
|
|
@@ -63,6 +63,75 @@ function sanitizeInlineText(text, maxLen = 300) {
|
|
|
63
63
|
`).replace(/^#{1,6}\s+/gm, "").replace(/^\s*[-*+]\s+/gm, "· ").replace(/^\s*\d+\.\s+/gm, "· ").replace(/\*\*/g, "").replace(/`/g, "").replace(/\n+/g, " · ").replace(/\s{2,}/g, " ").replace(/(?:\s*·\s*){2,}/g, " · ").replace(/^(\s*·\s*)+/, "").replace(/(\s*·\s*)+$/, "").trim();
|
|
64
64
|
return flat.length <= maxLen ? flat : `${flat.slice(0, maxLen)}…`;
|
|
65
65
|
}
|
|
66
|
+
var HEAD_TITLE_MAX_WIDTH = 40;
|
|
67
|
+
function isWideChar(cp) {
|
|
68
|
+
return cp >= 4352 && cp <= 4447 || cp >= 11904 && cp <= 12350 || cp >= 12353 && cp <= 13311 || cp >= 13312 && cp <= 19903 || cp >= 19968 && cp <= 40959 || cp >= 40960 && cp <= 42191 || cp >= 44032 && cp <= 55203 || cp >= 63744 && cp <= 64255 || cp >= 65072 && cp <= 65135 || cp >= 65280 && cp <= 65376 || cp >= 65504 && cp <= 65510 || cp >= 127744 && cp <= 129791 || cp >= 131072 && cp <= 262141;
|
|
69
|
+
}
|
|
70
|
+
function charWidth(cp) {
|
|
71
|
+
return isWideChar(cp) ? 2 : 1;
|
|
72
|
+
}
|
|
73
|
+
function isTitleSeparator(ch) {
|
|
74
|
+
return ch === " " || ch === "·" || ch === "-" || ch === "_" || ch === "/" || ch === "、" || ch === "+" || ch === "=" || ch === "|" || ch === "|" || ch === "," || ch === "," || ch === ":" || ch === ":";
|
|
75
|
+
}
|
|
76
|
+
function truncateHeadTitle(text, maxWidth = HEAD_TITLE_MAX_WIDTH) {
|
|
77
|
+
if (!text)
|
|
78
|
+
return "";
|
|
79
|
+
const flat = text.replace(/\s+/g, " ").trim();
|
|
80
|
+
if (!flat)
|
|
81
|
+
return "";
|
|
82
|
+
if (!Number.isFinite(maxWidth) || maxWidth <= 0)
|
|
83
|
+
return flat;
|
|
84
|
+
const points = Array.from(flat);
|
|
85
|
+
const budget = Math.max(1, maxWidth - 1);
|
|
86
|
+
let width = 0;
|
|
87
|
+
let endIndex = points.length;
|
|
88
|
+
for (let i = 0;i < points.length; i++) {
|
|
89
|
+
const w = charWidth(points[i].codePointAt(0));
|
|
90
|
+
if (width + w > budget) {
|
|
91
|
+
endIndex = i;
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
width += w;
|
|
95
|
+
}
|
|
96
|
+
if (endIndex >= points.length)
|
|
97
|
+
return flat;
|
|
98
|
+
let cut = endIndex;
|
|
99
|
+
let cutAtBoundary = false;
|
|
100
|
+
const minCut = Math.max(0, endIndex - 12);
|
|
101
|
+
for (let i = endIndex - 1;i >= minCut; i--) {
|
|
102
|
+
if (isTitleSeparator(points[i])) {
|
|
103
|
+
cut = i;
|
|
104
|
+
cutAtBoundary = true;
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
let cutWidth = 0;
|
|
109
|
+
for (let i = 0;i < cut; i++)
|
|
110
|
+
cutWidth += charWidth(points[i].codePointAt(0));
|
|
111
|
+
if (cutAtBoundary && cutWidth < budget / 2) {
|
|
112
|
+
cut = endIndex;
|
|
113
|
+
cutAtBoundary = false;
|
|
114
|
+
}
|
|
115
|
+
let sliced = points.slice(0, cut).join("").trimEnd();
|
|
116
|
+
sliced = sliced.replace(/[+=||]+$/, "").trimEnd();
|
|
117
|
+
if (!cutAtBoundary) {
|
|
118
|
+
let wordStart = sliced.length;
|
|
119
|
+
for (let i = sliced.length - 1;i >= 0; i--) {
|
|
120
|
+
const ch = sliced[i];
|
|
121
|
+
if (ch === " " || ch === "·" || ch === "-" || ch === "_" || ch === "/") {
|
|
122
|
+
wordStart = i + 1;
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
if (wordStart === sliced.length)
|
|
126
|
+
wordStart = i;
|
|
127
|
+
}
|
|
128
|
+
const fragment = sliced.slice(wordStart);
|
|
129
|
+
if (fragment.length > 0 && /^[A-Za-z]+$/.test(fragment) && wordStart > 0) {
|
|
130
|
+
sliced = sliced.slice(0, wordStart).trimEnd();
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return sliced + "…";
|
|
134
|
+
}
|
|
66
135
|
function formatDateTimeForDisplay(value) {
|
|
67
136
|
const d = new Date(value);
|
|
68
137
|
if (isNaN(d.getTime()))
|
|
@@ -391,7 +460,9 @@ function buildTaskCard(opts) {
|
|
|
391
460
|
tag: "markdown",
|
|
392
461
|
content: effectiveProgress !== undefined ? `**\uD83D\uDCCA 进度**:${renderProgressBar(effectiveProgress)}` : isTerminalStatus ? `**\uD83D\uDCCA 进度**:${terminalProgressText}` : `**\uD83D\uDCCA 进度**:进行中(第 ${updateCount} 次更新,尚未上报百分比)`
|
|
393
462
|
});
|
|
394
|
-
const
|
|
463
|
+
const taskIdLabel = opts.meta.id !== undefined ? `#${opts.meta.id}` : "任务";
|
|
464
|
+
const taskTitleText = truncateHeadTitle(opts.meta.title);
|
|
465
|
+
const taskLabel = taskTitleText && taskTitleText !== taskIdLabel ? `${taskIdLabel} ${taskTitleText}` : taskIdLabel;
|
|
395
466
|
return {
|
|
396
467
|
schema: "2.0",
|
|
397
468
|
header: {
|
|
@@ -612,6 +683,10 @@ class LarkCardPatchNotifier {
|
|
|
612
683
|
}
|
|
613
684
|
async updateTask(opts) {
|
|
614
685
|
await this.mutexFor(opts.messageId).run(async () => {
|
|
686
|
+
if (this.finalisedCards.has(opts.messageId)) {
|
|
687
|
+
logger.debug(`updateTask: message ${opts.messageId} 已是终态卡片,忽略迟到的更新`);
|
|
688
|
+
return;
|
|
689
|
+
}
|
|
615
690
|
const state = this.states.get(opts.messageId) ?? {
|
|
616
691
|
chatId: opts.chatId ?? "",
|
|
617
692
|
profile: opts.profile,
|
|
@@ -684,6 +759,14 @@ class LarkCardPatchNotifier {
|
|
|
684
759
|
progress: snapshot.progress
|
|
685
760
|
});
|
|
686
761
|
}
|
|
762
|
+
mergeTimelineState(messageId, milestones = [], processSteps = []) {
|
|
763
|
+
const state = this.states.get(messageId);
|
|
764
|
+
if (!state)
|
|
765
|
+
return false;
|
|
766
|
+
state.milestones = mergeUnique(state.milestones, milestones, milestoneKey);
|
|
767
|
+
state.processSteps = mergeUnique(state.processSteps, processSteps, processStepKey);
|
|
768
|
+
return true;
|
|
769
|
+
}
|
|
687
770
|
async pauseTask(opts) {
|
|
688
771
|
await this.mutexFor(opts.messageId).run(async () => {
|
|
689
772
|
const state = this.states.get(opts.messageId);
|
|
@@ -766,6 +849,7 @@ class LarkCardPatchNotifier {
|
|
|
766
849
|
profile: opts.profile ?? state?.profile,
|
|
767
850
|
card
|
|
768
851
|
}), "patch");
|
|
852
|
+
this.finalisedCards.add(opts.messageId);
|
|
769
853
|
});
|
|
770
854
|
if (this.options.unpinOnFinish) {
|
|
771
855
|
const state = this.states.get(opts.messageId);
|
|
@@ -800,6 +884,7 @@ class LarkCardPatchNotifier {
|
|
|
800
884
|
spinner: SPINNER_EMOJIS[state.spinnerIndex] ?? SPINNER_EMOJIS[0]
|
|
801
885
|
});
|
|
802
886
|
}
|
|
887
|
+
finalisedCards = new Set;
|
|
803
888
|
trackedCardCount() {
|
|
804
889
|
return this.states.size;
|
|
805
890
|
}
|
|
@@ -854,6 +939,10 @@ class LarkCardPatchNotifier {
|
|
|
854
939
|
}
|
|
855
940
|
async updateWorkflow(opts) {
|
|
856
941
|
await this.mutexFor(opts.messageId).run(async () => {
|
|
942
|
+
if (this.finalisedCards.has(opts.messageId)) {
|
|
943
|
+
logger.debug(`updateWorkflow: message ${opts.messageId} 已是终态卡片,忽略迟到的更新`);
|
|
944
|
+
return;
|
|
945
|
+
}
|
|
857
946
|
const state = this.workflowStates.get(opts.messageId) ?? {
|
|
858
947
|
chatId: opts.chatId ?? "",
|
|
859
948
|
profile: opts.profile,
|
|
@@ -946,6 +1035,7 @@ class LarkCardPatchNotifier {
|
|
|
946
1035
|
profile: opts.profile ?? state?.profile,
|
|
947
1036
|
card
|
|
948
1037
|
}), "patch");
|
|
1038
|
+
this.finalisedCards.add(opts.messageId);
|
|
949
1039
|
});
|
|
950
1040
|
if (this.options.unpinOnFinish) {
|
|
951
1041
|
const state = this.workflowStates.get(opts.messageId);
|
|
@@ -1273,4 +1363,4 @@ function sanitize(text) {
|
|
|
1273
1363
|
return `${trimmed.slice(0, 500)}…`;
|
|
1274
1364
|
}
|
|
1275
1365
|
|
|
1276
|
-
export { formatTimestampForDisplay, sanitizeInlineText, formatDateTimeForDisplay, renderProgressBar, resolveTaskTitleForDisplay, humanizeValue, isTerminalStatusForTimeline, isTerminalStatusForWorkflowTimeline, buildCollapsiblePanel, renderTaskInfoLines, renderContextAsLines, renderMilestones, renderProcessSteps, partitionProcessSteps, buildTaskCard, buildChatAppLink, DEFAULT_APP_LINK_BASE, formatDurationMs, renderWorkflowInfoLines, buildWorkflowCard, LarkCardPatchNotifier };
|
|
1366
|
+
export { formatTimestampForDisplay, sanitizeInlineText, HEAD_TITLE_MAX_WIDTH, truncateHeadTitle, formatDateTimeForDisplay, renderProgressBar, resolveTaskTitleForDisplay, humanizeValue, isTerminalStatusForTimeline, isTerminalStatusForWorkflowTimeline, buildCollapsiblePanel, renderTaskInfoLines, renderContextAsLines, renderMilestones, renderProcessSteps, partitionProcessSteps, buildTaskCard, buildChatAppLink, DEFAULT_APP_LINK_BASE, formatDurationMs, renderWorkflowInfoLines, buildWorkflowCard, LarkCardPatchNotifier };
|