@ai-setting/roy-agent-core 1.7.72 → 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.
Files changed (81) hide show
  1. package/dist/env/agent/agent-component.js +6 -6
  2. package/dist/env/agent/agent-registry.d.ts +4 -1
  3. package/dist/env/agent/index.js +6 -6
  4. package/dist/env/error-reply.d.ts +46 -0
  5. package/dist/env/error-reply.js +3 -1
  6. package/dist/env/event-source/event-source-handlers.js +12 -12
  7. package/dist/env/event-source/index.js +13 -13
  8. package/dist/env/index.js +30 -30
  9. package/dist/env/llm/index.js +2 -2
  10. package/dist/env/llm/orphan-toolcall.d.ts +107 -0
  11. package/dist/env/plugin/index.js +3 -3
  12. package/dist/env/prompt/index.js +3 -3
  13. package/dist/env/prompt/prompts-index.d.ts +24 -2
  14. package/dist/env/session/index.js +4 -4
  15. package/dist/env/session/storage/index.js +3 -3
  16. package/dist/env/task/delegate/delegate-tool.d.ts +8 -0
  17. package/dist/env/task/delegate/delegate-tool.js +4 -4
  18. package/dist/env/task/delegate/index.js +4 -4
  19. package/dist/env/task/index.js +7 -7
  20. package/dist/env/task/mcp/index.js +2 -2
  21. package/dist/env/task/plugins/index.d.ts +3 -0
  22. package/dist/env/task/plugins/index.js +32 -9
  23. package/dist/env/task/plugins/lark-card-patch-notifier.d.ts +61 -0
  24. package/dist/env/task/plugins/lark-card-patch-notifier.js +6 -2
  25. package/dist/env/task/plugins/lark-cli-task-notify-plugin.d.ts +42 -0
  26. package/dist/env/task/prompt/index.js +1 -1
  27. package/dist/env/task/prompt/task-discipline.d.ts +9 -3
  28. package/dist/env/task/tools/cancel-tool.d.ts +28 -0
  29. package/dist/env/task/tools/index.d.ts +1 -0
  30. package/dist/env/task/tools/index.js +4 -2
  31. package/dist/env/task/tools/task-types.d.ts +22 -0
  32. package/dist/env/tool/built-in/compact-session-tool.d.ts +120 -0
  33. package/dist/env/tool/built-in/index.d.ts +2 -0
  34. package/dist/env/tool/built-in/index.js +6 -2
  35. package/dist/env/tool/index.js +4 -4
  36. package/dist/env/workflow/engine/index.js +6 -6
  37. package/dist/env/workflow/index.js +15 -13
  38. package/dist/env/workflow/plugins/index.js +2 -2
  39. package/dist/env/workflow/tools/ask-user-tool.d.ts +88 -0
  40. package/dist/env/workflow/tools/index.js +11 -9
  41. package/dist/env/workflow/tools/run-workflow.d.ts +2 -2
  42. package/dist/env/workflow/types/index.js +2 -2
  43. package/dist/env/workflow/types/workflow-hil.d.ts +25 -1
  44. package/dist/env/workflow/utils/index.js +5 -5
  45. package/dist/index.js +33 -33
  46. package/dist/shared/@ai-setting/{roy-agent-core-sm0sf6sb.js → roy-agent-core-0qyrk5k0.js} +2 -2
  47. package/dist/shared/@ai-setting/{roy-agent-core-kmbct9yg.js → roy-agent-core-0snm5hc5.js} +1 -1
  48. package/dist/shared/@ai-setting/{roy-agent-core-4jjwewvw.js → roy-agent-core-11shp00p.js} +31 -10
  49. package/dist/shared/@ai-setting/{roy-agent-core-yr1mryb8.js → roy-agent-core-1v4g0d4x.js} +1 -1
  50. package/dist/shared/@ai-setting/{roy-agent-core-rxb00gjm.js → roy-agent-core-264qexac.js} +1 -1
  51. package/dist/shared/@ai-setting/{roy-agent-core-34jz9mgh.js → roy-agent-core-29b6hc39.js} +1 -1
  52. package/dist/shared/@ai-setting/roy-agent-core-2akfd64z.js +374 -0
  53. package/dist/shared/@ai-setting/{roy-agent-core-yhwxpj12.js → roy-agent-core-3e6gg17d.js} +90 -12
  54. package/dist/shared/@ai-setting/{roy-agent-core-skyc30qx.js → roy-agent-core-3fh1f7s7.js} +2 -2
  55. package/dist/shared/@ai-setting/{roy-agent-core-2gzt2q8c.js → roy-agent-core-4gr3k7qg.js} +17 -4
  56. package/dist/shared/@ai-setting/{roy-agent-core-y12kyxwa.js → roy-agent-core-60jbrfye.js} +6 -6
  57. package/dist/shared/@ai-setting/{roy-agent-core-add1zqsh.js → roy-agent-core-6cy43nss.js} +22 -1
  58. package/dist/shared/@ai-setting/{roy-agent-core-vah6g5yx.js → roy-agent-core-6rh8k6ba.js} +5 -5
  59. package/dist/shared/@ai-setting/{roy-agent-core-kpg25s2q.js → roy-agent-core-8ez6mccb.js} +4 -2
  60. package/dist/shared/@ai-setting/{roy-agent-core-sjr1kmfz.js → roy-agent-core-acj8ag08.js} +1 -1
  61. package/dist/shared/@ai-setting/{roy-agent-core-mds8tqd0.js → roy-agent-core-cgtq6427.js} +1 -1
  62. package/dist/shared/@ai-setting/{roy-agent-core-pakhchy7.js → roy-agent-core-ddyk1rc0.js} +1 -1
  63. package/dist/shared/@ai-setting/{roy-agent-core-jgb3bb42.js → roy-agent-core-djpq6yb0.js} +16 -7
  64. package/dist/shared/@ai-setting/{roy-agent-core-attpry6g.js → roy-agent-core-dqxec05w.js} +4 -3
  65. package/dist/shared/@ai-setting/{roy-agent-core-vm8h5zyj.js → roy-agent-core-ed233k5z.js} +1 -1
  66. package/dist/shared/@ai-setting/{roy-agent-core-jrj30vq3.js → roy-agent-core-er070zjq.js} +1 -1
  67. package/dist/shared/@ai-setting/{roy-agent-core-40rv283c.js → roy-agent-core-fghc2m8z.js} +152 -2
  68. package/dist/shared/@ai-setting/{roy-agent-core-7sj9xs9c.js → roy-agent-core-hnyk1by7.js} +110 -2
  69. package/dist/shared/@ai-setting/{roy-agent-core-7qvw65jt.js → roy-agent-core-jg65qnwa.js} +11 -8
  70. package/dist/shared/@ai-setting/{roy-agent-core-e25xkv53.js → roy-agent-core-mkc3zshb.js} +3 -1
  71. package/dist/shared/@ai-setting/{roy-agent-core-hfyfavp3.js → roy-agent-core-mww0mnd9.js} +231 -27
  72. package/dist/shared/@ai-setting/{roy-agent-core-wr7mv7k3.js → roy-agent-core-n9q1encx.js} +1 -1
  73. package/dist/shared/@ai-setting/{roy-agent-core-46rv4d7d.js → roy-agent-core-nmx9934r.js} +92 -2
  74. package/dist/shared/@ai-setting/{roy-agent-core-1w9y7mxj.js → roy-agent-core-p3zv1mx5.js} +1 -1
  75. package/dist/shared/@ai-setting/roy-agent-core-snvh4s2p.js +662 -0
  76. package/dist/shared/@ai-setting/{roy-agent-core-dt104qa1.js → roy-agent-core-v85n42ve.js} +1 -1
  77. package/dist/shared/@ai-setting/{roy-agent-core-gr48c89p.js → roy-agent-core-v87njmq7.js} +3 -3
  78. package/dist/shared/@ai-setting/{roy-agent-core-5gw0qa8m.js → roy-agent-core-y7x2qzwc.js} +553 -92
  79. package/package.json +1 -1
  80. package/dist/shared/@ai-setting/roy-agent-core-1p6syv85.js +0 -1083
  81. package/dist/shared/@ai-setting/roy-agent-core-58804s3j.js +0 -155
@@ -1,20 +1,29 @@
1
1
  import {
2
2
  isValidSessionId
3
- } from "./roy-agent-core-pakhchy7.js";
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-yr1mryb8.js";
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-e25xkv53.js";
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
- throw new AskUserError(runId, sessionId, nodeId, "agent", fullQuery);
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 logger = createLogger("workflow-get-tool");
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
- logger.error("Failed to get workflow info", { error });
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 logger2 = createLogger("workflow-list-tool");
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
- logger2.error("Failed to list workflows", { error });
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 logger3 = createLogger("workflow-tag-list-tool");
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
- logger3.error("Failed to list workflow tags", { error });
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 logger4 = createLogger("workflow-add-tool");
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
- logger4.error("Failed to add workflow", { error });
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 logger5 = createLogger("workflow-validate-tool");
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
- logger5.error("[workflow_validate] failed", { error });
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 logger6 = createLogger("workflow-search-tool");
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
- logger6.error("Failed to search workflows", { error });
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 logger7 = createLogger("run-workflow-tool");
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
- logger7.warn(`Failed to stop workflow ${runId} after timeout: ${stopErr instanceof Error ? stopErr.message : String(stopErr)}`);
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
- logger7.warn(`workflow_run: could not resolve definition for ${workflowName}; ` + `falling back to the default run budget`, { error: err instanceof Error ? err.message : String(err) });
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
- logger7.info(`Running workflow: ${workflow_name}`, {
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
- logger7.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}`);
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 (logger7?.error) {
1106
- logger7.error(`Failed to run workflow: ${workflow_name}`, {
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 logger8 = createLogger("workflow-run-status-tool");
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
- logger8.error("Failed to get run status", { error });
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 logger9 = createLogger("workflow-run-stop-tool");
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
- logger9.error("Failed to stop workflow run", { error });
1445
+ logger10.error("Failed to stop workflow run", { error });
1242
1446
  return {
1243
1447
  success: false,
1244
1448
  output: "",
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  builtInHandlers
3
- } from "./roy-agent-core-y12kyxwa.js";
3
+ } from "./roy-agent-core-60jbrfye.js";
4
4
  import {
5
5
  envKeyToConfigKey
6
6
  } from "./roy-agent-core-7hh0brvs.js";
@@ -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 taskLabel = opts.meta.id !== undefined ? `#${opts.meta.id}` : "任务";
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 };
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  LarkCardPatchNotifier,
3
3
  formatDurationMs
4
- } from "./roy-agent-core-46rv4d7d.js";
4
+ } from "./roy-agent-core-nmx9934r.js";
5
5
  import {
6
6
  WorkflowHookPoints,
7
7
  init_workflow_hook_points