@ai-setting/roy-agent-core 1.7.85 → 1.7.88

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 (135) hide show
  1. package/dist/config/index.js +7 -7
  2. package/dist/env/agent/agent-component.d.ts +1 -1
  3. package/dist/env/agent/agent-component.js +13 -12
  4. package/dist/env/agent/index.js +13 -12
  5. package/dist/env/agent/types.d.ts +14 -0
  6. package/dist/env/commands/index.js +7 -7
  7. package/dist/env/context/index.js +3 -3
  8. package/dist/env/debug/index.js +7 -7
  9. package/dist/env/error-reply.js +1 -1
  10. package/dist/env/event-source/event-source-handlers.d.ts +18 -2
  11. package/dist/env/event-source/event-source-handlers.js +26 -21
  12. package/dist/env/event-source/event-store.js +2 -2
  13. package/dist/env/event-source/index.js +25 -22
  14. package/dist/env/event-source/timer-handler.d.ts +98 -0
  15. package/dist/env/event-source/types.d.ts +53 -1
  16. package/dist/env/event-source/wecom-card-action-handler.d.ts +235 -3
  17. package/dist/env/event-source/wecom-card-builder.d.ts +207 -1
  18. package/dist/env/event-source/wecom-cli-handler.d.ts +25 -0
  19. package/dist/{shared/@ai-setting/roy-agent-core-vyr6svt6.js → env/event-source/wecom-respond-registry.js} +8 -6
  20. package/dist/env/event-source/wecom-session-card-sender.d.ts +135 -0
  21. package/dist/env/event-source/wecom-session-card-sender.js +153 -0
  22. package/dist/env/hook/index.js +5 -5
  23. package/dist/env/index.js +49 -45
  24. package/dist/env/llm/index.js +9 -8
  25. package/dist/env/log-trace/index.js +7 -7
  26. package/dist/env/log-trace/trace-filters.d.ts +6 -1
  27. package/dist/env/mcp/index.js +7 -7
  28. package/dist/env/memory/index.js +7 -7
  29. package/dist/env/plugin/index.js +7 -7
  30. package/dist/env/prompt/index.js +8 -8
  31. package/dist/env/prompt/prompts-index.d.ts +1 -1
  32. package/dist/env/session/group-session-link.d.ts +99 -0
  33. package/dist/env/session/index.js +11 -10
  34. package/dist/env/session/session-component.d.ts +89 -0
  35. package/dist/env/session/storage/index.js +5 -4
  36. package/dist/env/session/types.d.ts +10 -0
  37. package/dist/env/skill/index.js +7 -7
  38. package/dist/env/task/delegate/delegate-channel-hint.d.ts +39 -0
  39. package/dist/env/task/delegate/delegate-tool.d.ts +71 -6
  40. package/dist/env/task/delegate/delegate-tool.js +11 -9
  41. package/dist/env/task/delegate/index.js +8 -8
  42. package/dist/env/task/index.js +18 -18
  43. package/dist/env/task/mcp/index.js +4 -4
  44. package/dist/env/task/plugins/card-subject.d.ts +117 -0
  45. package/dist/env/task/plugins/index.js +19 -17
  46. package/dist/env/task/plugins/lark-card-action-handler.d.ts +261 -6
  47. package/dist/env/task/plugins/lark-card-patch-notifier.d.ts +501 -0
  48. package/dist/env/task/plugins/lark-card-patch-notifier.js +12 -2
  49. package/dist/env/task/plugins/lark-card-state-store.d.ts +60 -0
  50. package/dist/env/task/plugins/lark-cli-task-notify-plugin.d.ts +45 -0
  51. package/dist/env/task/plugins/sub-session-activity.d.ts +415 -0
  52. package/dist/env/task/plugins/wecom-session-card-store.d.ts +134 -0
  53. package/dist/env/task/plugins/wecom-session-card-store.js +23 -0
  54. package/dist/env/task/plugins/wecom-task-notify-plugin.d.ts +40 -0
  55. package/dist/env/task/storage/index.js +3 -3
  56. package/dist/env/task/tools/index.js +4 -4
  57. package/dist/env/tool/built-in/index.js +6 -4
  58. package/dist/env/tool/index.js +14 -10
  59. package/dist/env/tool/types.d.ts +25 -0
  60. package/dist/env/tool/validator.d.ts +8 -0
  61. package/dist/env/workflow/engine/index.js +12 -12
  62. package/dist/env/workflow/hooks/index.js +7 -7
  63. package/dist/env/workflow/index.js +24 -23
  64. package/dist/env/workflow/nodes/index.js +2 -2
  65. package/dist/env/workflow/plugins/index.js +10 -8
  66. package/dist/env/workflow/service/index.js +2 -2
  67. package/dist/env/workflow/storage/index.js +3 -3
  68. package/dist/env/workflow/tools/index.js +16 -15
  69. package/dist/env/workflow/utils/index.js +4 -4
  70. package/dist/index.js +65 -60
  71. package/dist/shared/@ai-setting/{roy-agent-core-dc9zq75z.js → roy-agent-core-0crmsc12.js} +3 -3
  72. package/dist/shared/@ai-setting/{roy-agent-core-cha0jc7n.js → roy-agent-core-0sbmdz8d.js} +137 -16
  73. package/dist/shared/@ai-setting/{roy-agent-core-87942bw4.js → roy-agent-core-1mhyh4c5.js} +1 -1
  74. package/dist/shared/@ai-setting/{roy-agent-core-v6vr6za7.js → roy-agent-core-1vv4fx15.js} +4 -4
  75. package/dist/shared/@ai-setting/{roy-agent-core-nwbfepba.js → roy-agent-core-3e040tc5.js} +1 -1
  76. package/dist/shared/@ai-setting/roy-agent-core-418zc9ha.js +288 -0
  77. package/dist/shared/@ai-setting/{roy-agent-core-r5wt1h3c.js → roy-agent-core-4fkxy2gv.js} +1 -1
  78. package/dist/shared/@ai-setting/{roy-agent-core-na18zwj0.js → roy-agent-core-4t3yskp8.js} +1 -1
  79. package/dist/shared/@ai-setting/{roy-agent-core-5pr4zp88.js → roy-agent-core-5kzhaap1.js} +1 -1
  80. package/dist/shared/@ai-setting/{roy-agent-core-qq96p0tj.js → roy-agent-core-5s2t8z00.js} +22 -1
  81. package/dist/shared/@ai-setting/{roy-agent-core-6rh8k6ba.js → roy-agent-core-6gj1hc5z.js} +7 -7
  82. package/dist/shared/@ai-setting/{roy-agent-core-ezvpreqz.js → roy-agent-core-6k8mb7zx.js} +1 -1
  83. package/dist/shared/@ai-setting/{roy-agent-core-g8htfwxj.js → roy-agent-core-7f10p7m2.js} +1 -1
  84. package/dist/shared/@ai-setting/roy-agent-core-7kvpc0w5.js +177 -0
  85. package/dist/shared/@ai-setting/{roy-agent-core-h21gngxf.js → roy-agent-core-7yh5wps0.js} +1 -1
  86. package/dist/shared/@ai-setting/{roy-agent-core-efkjyh69.js → roy-agent-core-9710zwwz.js} +1 -1
  87. package/dist/shared/@ai-setting/{roy-agent-core-rykf7c04.js → roy-agent-core-9c565frx.js} +1 -1
  88. package/dist/shared/@ai-setting/{roy-agent-core-fghc2m8z.js → roy-agent-core-aa8kv18f.js} +34 -2
  89. package/dist/shared/@ai-setting/{roy-agent-core-p6ks90tb.js → roy-agent-core-an35dzbf.js} +6 -6
  90. package/dist/shared/@ai-setting/{roy-agent-core-7bpj859q.js → roy-agent-core-azyz78ky.js} +7 -7
  91. package/dist/shared/@ai-setting/{roy-agent-core-264qexac.js → roy-agent-core-b7h39vrc.js} +4 -4
  92. package/dist/shared/@ai-setting/{roy-agent-core-dqxec05w.js → roy-agent-core-bjtc9d35.js} +2 -2
  93. package/dist/shared/@ai-setting/roy-agent-core-c4ec7k0p.js +426 -0
  94. package/dist/shared/@ai-setting/{roy-agent-core-ddyk1rc0.js → roy-agent-core-cre2y2ct.js} +160 -4
  95. package/dist/shared/@ai-setting/{roy-agent-core-tr3ep81v.js → roy-agent-core-d6zdbgtc.js} +1 -1
  96. package/dist/shared/@ai-setting/{roy-agent-core-0qyrk5k0.js → roy-agent-core-ds6qzmf8.js} +14 -5
  97. package/dist/shared/@ai-setting/{roy-agent-core-cgtq6427.js → roy-agent-core-e08bvpaq.js} +1 -1
  98. package/dist/shared/@ai-setting/{roy-agent-core-12n08pg5.js → roy-agent-core-e69qxdyy.js} +1 -1
  99. package/dist/shared/@ai-setting/{roy-agent-core-qk9hd89p.js → roy-agent-core-fan8g0z1.js} +10 -10
  100. package/dist/shared/@ai-setting/{roy-agent-core-xcp8vwax.js → roy-agent-core-fepm835e.js} +2 -2
  101. package/dist/shared/@ai-setting/{roy-agent-core-6j02sbee.js → roy-agent-core-fhg03v43.js} +1 -1
  102. package/dist/shared/@ai-setting/{roy-agent-core-dvtg4sn0.js → roy-agent-core-g8yr733d.js} +1 -1
  103. package/dist/shared/@ai-setting/{roy-agent-core-xf6z96qy.js → roy-agent-core-gr5h1dyr.js} +818 -346
  104. package/dist/shared/@ai-setting/{roy-agent-core-m3vjepzz.js → roy-agent-core-h1e1fm9b.js} +38 -202
  105. package/dist/shared/@ai-setting/{roy-agent-core-c2gbt68e.js → roy-agent-core-h83zdsrq.js} +2 -2
  106. package/dist/shared/@ai-setting/{roy-agent-core-tk98f92b.js → roy-agent-core-k3gcvybs.js} +2 -2
  107. package/dist/shared/@ai-setting/{roy-agent-core-pgvcf91v.js → roy-agent-core-m39v7qpx.js} +2 -2
  108. package/dist/shared/@ai-setting/{roy-agent-core-tm1mxttk.js → roy-agent-core-mf5p38yf.js} +2 -2
  109. package/dist/shared/@ai-setting/{roy-agent-core-83bewqx8.js → roy-agent-core-mvh0td7p.js} +2 -2
  110. package/dist/shared/@ai-setting/{roy-agent-core-ze5cqpf2.js → roy-agent-core-mx855td4.js} +17 -38
  111. package/dist/shared/@ai-setting/{roy-agent-core-0dh8npnz.js → roy-agent-core-n197medr.js} +13 -13
  112. package/dist/shared/@ai-setting/{roy-agent-core-cmprygrp.js → roy-agent-core-nqkfkpf4.js} +4 -4
  113. package/dist/shared/@ai-setting/{roy-agent-core-7cbpmk4q.js → roy-agent-core-p31ftgq9.js} +1 -1
  114. package/dist/shared/@ai-setting/{roy-agent-core-vffccgf6.js → roy-agent-core-qwd2dq5q.js} +10 -3
  115. package/dist/shared/@ai-setting/{roy-agent-core-b31v3qpv.js → roy-agent-core-ra66sf50.js} +990 -211
  116. package/dist/shared/@ai-setting/{roy-agent-core-1v4g0d4x.js → roy-agent-core-rm7seqwb.js} +1 -1
  117. package/dist/shared/@ai-setting/{roy-agent-core-7dd0s3xb.js → roy-agent-core-shb1qsyg.js} +1027 -14
  118. package/dist/shared/@ai-setting/{roy-agent-core-ax9e9szb.js → roy-agent-core-smf94h73.js} +1 -1
  119. package/dist/shared/@ai-setting/{roy-agent-core-acj8ag08.js → roy-agent-core-tjnabyvq.js} +1 -1
  120. package/dist/shared/@ai-setting/{roy-agent-core-qqaak24r.js → roy-agent-core-tkpp1ba0.js} +1 -1
  121. package/dist/shared/@ai-setting/{roy-agent-core-dkrvmjsh.js → roy-agent-core-tpm1dd1g.js} +23 -15
  122. package/dist/shared/@ai-setting/{roy-agent-core-ed233k5z.js → roy-agent-core-v1n0106v.js} +1 -1
  123. package/dist/shared/@ai-setting/{roy-agent-core-zxz5fkwj.js → roy-agent-core-v6yshv0z.js} +1 -1
  124. package/dist/shared/@ai-setting/{roy-agent-core-mcy5apay.js → roy-agent-core-vf9sp6s3.js} +1 -1
  125. package/dist/shared/@ai-setting/{roy-agent-core-q813vafd.js → roy-agent-core-vpcxv1ty.js} +1 -1
  126. package/dist/shared/@ai-setting/{roy-agent-core-xvt7kf7p.js → roy-agent-core-w9ryeg2p.js} +3 -3
  127. package/dist/shared/@ai-setting/{roy-agent-core-es203w7p.js → roy-agent-core-wqs6yypq.js} +1 -1
  128. package/dist/shared/@ai-setting/{roy-agent-core-d1n4jbza.js → roy-agent-core-wr1qexzq.js} +5 -5
  129. package/dist/shared/@ai-setting/roy-agent-core-wxrkcb17.js +56 -0
  130. package/dist/shared/@ai-setting/{roy-agent-core-0snm5hc5.js → roy-agent-core-y6shd91r.js} +1 -1
  131. package/dist/shared/@ai-setting/{roy-agent-core-9vxh6f8h.js → roy-agent-core-y7fqtzk2.js} +7 -7
  132. package/dist/shared/@ai-setting/{roy-agent-core-cpcd24n2.js → roy-agent-core-yet36q5k.js} +2 -2
  133. package/dist/shared/@ai-setting/{roy-agent-core-3fh1f7s7.js → roy-agent-core-yfpnkc4z.js} +5 -5
  134. package/dist/shared/@ai-setting/{roy-agent-core-begm7ytz.js → roy-agent-core-yh68z1bg.js} +3 -3
  135. package/package.json +9 -1
@@ -1,3 +1,6 @@
1
+ import {
2
+ isToolReasonRequired
3
+ } from "./roy-agent-core-wxrkcb17.js";
1
4
  import {
2
5
  sniffImageMime
3
6
  } from "./roy-agent-core-zjdzk1gg.js";
@@ -11,7 +14,7 @@ import {
11
14
  embedResultFilter,
12
15
  init_decorator,
13
16
  init_trace_filters
14
- } from "./roy-agent-core-qq96p0tj.js";
17
+ } from "./roy-agent-core-5s2t8z00.js";
15
18
  import {
16
19
  createLogger,
17
20
  init_logger
@@ -309,7 +312,20 @@ function toolParametersToJsonSchema(parameters) {
309
312
  if (deref["properties"] && typeof deref["properties"] === "object") {
310
313
  deref["type"] = "object";
311
314
  } else {
312
- return EMPTY;
315
+ const emptyWithReason = {
316
+ type: "object",
317
+ properties: {}
318
+ };
319
+ if (isToolReasonRequired()) {
320
+ emptyWithReason["properties"] = {
321
+ reason: {
322
+ type: "string",
323
+ description: "一句话说明为什么调用此工具(将随调用记录存入会话,便于事后追溯)"
324
+ }
325
+ };
326
+ emptyWithReason["required"] = ["reason"];
327
+ }
328
+ return emptyWithReason;
313
329
  }
314
330
  }
315
331
  if (!deref["properties"] || typeof deref["properties"] !== "object") {
@@ -318,6 +334,22 @@ function toolParametersToJsonSchema(parameters) {
318
334
  delete deref["definitions"];
319
335
  delete deref["$defs"];
320
336
  delete deref["$schema"];
337
+ if (isToolReasonRequired()) {
338
+ const props = deref["properties"];
339
+ if (!props["reason"]) {
340
+ props["reason"] = {
341
+ type: "string",
342
+ description: "一句话说明为什么调用此工具(将随调用记录存入会话,便于事后追溯)"
343
+ };
344
+ }
345
+ const required = deref["required"];
346
+ if (Array.isArray(required)) {
347
+ if (!required.includes("reason"))
348
+ required.push("reason");
349
+ } else {
350
+ deref["required"] = ["reason"];
351
+ }
352
+ }
321
353
  return deref;
322
354
  }
323
355
 
@@ -2,7 +2,7 @@ import {
2
2
  createAutoTaskPlugin,
3
3
  createLayaDecisionPlugin,
4
4
  registerLayaCompletionTaskHook
5
- } from "./roy-agent-core-b31v3qpv.js";
5
+ } from "./roy-agent-core-ra66sf50.js";
6
6
  import {
7
7
  TaskHookPoints
8
8
  } from "./roy-agent-core-1pg0fepg.js";
@@ -12,24 +12,24 @@ import {
12
12
  } from "./roy-agent-core-ctdhjv68.js";
13
13
  import {
14
14
  BaseComponent
15
- } from "./roy-agent-core-pgvcf91v.js";
15
+ } from "./roy-agent-core-m39v7qpx.js";
16
16
  import {
17
17
  init_hook
18
- } from "./roy-agent-core-ax9e9szb.js";
18
+ } from "./roy-agent-core-smf94h73.js";
19
19
  import {
20
20
  init_context
21
- } from "./roy-agent-core-qqaak24r.js";
21
+ } from "./roy-agent-core-tkpp1ba0.js";
22
22
  import {
23
23
  getEnvContext,
24
24
  init_env_context,
25
25
  runWithEnvContextAsync
26
- } from "./roy-agent-core-7cbpmk4q.js";
26
+ } from "./roy-agent-core-p31ftgq9.js";
27
27
  import {
28
28
  TracedAs,
29
29
  envQueryParamFilter,
30
30
  init_decorator,
31
31
  init_trace_filters
32
- } from "./roy-agent-core-qq96p0tj.js";
32
+ } from "./roy-agent-core-5s2t8z00.js";
33
33
  import {
34
34
  createLogger,
35
35
  init_logger
@@ -1,16 +1,16 @@
1
1
  import {
2
2
  isValidSessionId
3
- } from "./roy-agent-core-ddyk1rc0.js";
3
+ } from "./roy-agent-core-cre2y2ct.js";
4
4
  import {
5
5
  TAG_MAX_COUNT,
6
6
  TAG_MIN_COUNT
7
- } from "./roy-agent-core-12n08pg5.js";
7
+ } from "./roy-agent-core-e69qxdyy.js";
8
8
  import {
9
9
  deliverAskUserMessage
10
- } from "./roy-agent-core-rykf7c04.js";
10
+ } from "./roy-agent-core-9c565frx.js";
11
11
  import {
12
12
  validateWorkflowDefinition
13
- } from "./roy-agent-core-1v4g0d4x.js";
13
+ } from "./roy-agent-core-rm7seqwb.js";
14
14
  import {
15
15
  getCurrentBgTaskId
16
16
  } from "./roy-agent-core-c1v263jn.js";
@@ -20,14 +20,14 @@ import {
20
20
  } from "./roy-agent-core-mkc3zshb.js";
21
21
  import {
22
22
  init_context
23
- } from "./roy-agent-core-qqaak24r.js";
23
+ } from "./roy-agent-core-tkpp1ba0.js";
24
24
  import {
25
25
  getEnvContext
26
- } from "./roy-agent-core-7cbpmk4q.js";
26
+ } from "./roy-agent-core-p31ftgq9.js";
27
27
  import {
28
28
  TracedAs,
29
29
  init_decorator
30
- } from "./roy-agent-core-qq96p0tj.js";
30
+ } from "./roy-agent-core-5s2t8z00.js";
31
31
  import {
32
32
  createLogger,
33
33
  init_logger
@@ -6,7 +6,7 @@ import {
6
6
  PiAiAdapter,
7
7
  invoke,
8
8
  invokeNonStream
9
- } from "./roy-agent-core-fghc2m8z.js";
9
+ } from "./roy-agent-core-aa8kv18f.js";
10
10
  import {
11
11
  ContextError,
12
12
  ErrorCodes
@@ -17,12 +17,12 @@ import {
17
17
  } from "./roy-agent-core-7hh0brvs.js";
18
18
  import {
19
19
  BaseComponent
20
- } from "./roy-agent-core-pgvcf91v.js";
20
+ } from "./roy-agent-core-m39v7qpx.js";
21
21
  import {
22
22
  LLMHookPoints,
23
23
  globalHookManager,
24
24
  init_global_hook_manager
25
- } from "./roy-agent-core-cpcd24n2.js";
25
+ } from "./roy-agent-core-yet36q5k.js";
26
26
  import {
27
27
  TracedAs,
28
28
  embedParamFilter,
@@ -32,7 +32,7 @@ import {
32
32
  llmInvokeParamFilter,
33
33
  llmInvokeResultFilter,
34
34
  wrapFunction
35
- } from "./roy-agent-core-qq96p0tj.js";
35
+ } from "./roy-agent-core-5s2t8z00.js";
36
36
  import {
37
37
  createLogger,
38
38
  init_logger
@@ -9,12 +9,12 @@ import {
9
9
  import {
10
10
  globalHookManager,
11
11
  init_global_hook_manager
12
- } from "./roy-agent-core-cpcd24n2.js";
12
+ } from "./roy-agent-core-yet36q5k.js";
13
13
  import {
14
14
  TracedAs,
15
15
  init_decorator,
16
16
  wrapFunction
17
- } from "./roy-agent-core-qq96p0tj.js";
17
+ } from "./roy-agent-core-5s2t8z00.js";
18
18
  import {
19
19
  createLogger,
20
20
  init_logger
@@ -0,0 +1,426 @@
1
+ import {
2
+ formatActivityQuote
3
+ } from "./roy-agent-core-418zc9ha.js";
4
+
5
+ // src/env/event-source/wecom-card-builder.ts
6
+ var WecomCardActionKey = {
7
+ VIEW: "task_view",
8
+ MARK_DONE: "task_mark_done",
9
+ REOPEN: "task_reopen",
10
+ REFRESH_ACTIVITY: "task_refresh_activity",
11
+ CREATE_LARK_GROUP: "task_create_lark_group"
12
+ };
13
+ function wecomCardTaskIdForTask(taskId) {
14
+ return `roy-task-${taskId}`;
15
+ }
16
+ var ROY_SESSION_PREFIX = "roy-session-";
17
+ function wecomCardTaskIdForSession(sessionId, taskId) {
18
+ const id = typeof sessionId === "string" ? sessionId.trim() : "";
19
+ if (!id)
20
+ throw new Error("wecomCardTaskIdForSession: sessionId is required");
21
+ const base = `${ROY_SESSION_PREFIX}${id}`;
22
+ if (typeof taskId === "number" && Number.isSafeInteger(taskId) && taskId > 0) {
23
+ return `${base}${WECOM_SESSION_TASK_SEP}${taskId}`;
24
+ }
25
+ return base;
26
+ }
27
+ var WECOM_SESSION_TASK_SEP = "@task-";
28
+ var cardSeq = 0;
29
+ function newWecomCardTaskId(taskId) {
30
+ cardSeq = (cardSeq + 1) % 1e6;
31
+ const rand = Math.random().toString(36).slice(2, 8);
32
+ return `${wecomCardTaskIdForTask(taskId)}-${cardSeq}-${rand}`;
33
+ }
34
+ function formatTs(iso) {
35
+ try {
36
+ const d = new Date(iso);
37
+ if (isNaN(d.getTime()))
38
+ return iso;
39
+ const pad = (n) => String(n).padStart(2, "0");
40
+ return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ` + `${pad(d.getHours())}:${pad(d.getMinutes())}`;
41
+ } catch {
42
+ return iso;
43
+ }
44
+ }
45
+ function clip(text, max) {
46
+ if (!text)
47
+ return "";
48
+ const t = text.trim();
49
+ return t.length > max ? `${t.slice(0, max)}…` : t;
50
+ }
51
+ function shortMilestoneValue(text) {
52
+ if (!text)
53
+ return "";
54
+ const t = text.trim();
55
+ const colonIdx = t.indexOf(":");
56
+ const head = colonIdx > 0 && colonIdx <= 20 ? t.slice(0, colonIdx).trim() : t;
57
+ if (head.length <= MAX_HORIZONTAL_VALUE)
58
+ return head;
59
+ return clipWord(head, MAX_HORIZONTAL_VALUE);
60
+ }
61
+ function clipWord(text, max) {
62
+ if (!text)
63
+ return "";
64
+ const t = text.trim();
65
+ if (t.length <= max)
66
+ return t;
67
+ let cut = t.slice(0, max - 1);
68
+ const lastSpace = cut.lastIndexOf(" ");
69
+ if (lastSpace > max * 0.4)
70
+ return `${cut.slice(0, lastSpace).trimEnd()}…`;
71
+ const cjkBoundary = findCjkAsciiBoundary(cut);
72
+ if (cjkBoundary > max * 0.4)
73
+ return `${cut.slice(0, cjkBoundary).trimEnd()}…`;
74
+ return cut.slice(0, max - 1);
75
+ }
76
+ function findCjkAsciiBoundary(text) {
77
+ const isCjk = (ch) => /[一-鿿぀-ヿ가-힯]/.test(ch);
78
+ const isAsciiAlnum = (ch) => /[A-Za-z0-9]/.test(ch);
79
+ for (let i = text.length - 1;i > 0; i--) {
80
+ const prev = text[i - 1];
81
+ const cur = text[i];
82
+ if (isCjk(prev) !== isAsciiAlnum(cur) && isCjk(cur) !== isAsciiAlnum(prev)) {
83
+ if (isCjk(prev) && isAsciiAlnum(cur) || isAsciiAlnum(prev) && isCjk(cur)) {
84
+ return i;
85
+ }
86
+ }
87
+ }
88
+ return -1;
89
+ }
90
+ var MAX_TIMELINE_LINES = 8;
91
+ var MAX_HORIZONTAL_ROWS = 6;
92
+ var MAX_HORIZONTAL_VALUE = 26;
93
+ var MAX_HORIZONTAL_KEYNAME = 5;
94
+ function buildWecomTextNoticeCard(input) {
95
+ const progressPct = `${Math.max(0, Math.min(100, Math.round(input.progress ?? 0)))}%`;
96
+ const sorted = [...input.milestones].slice(-MAX_TIMELINE_LINES).reverse();
97
+ const timelineRows = sorted.slice(0, MAX_HORIZONTAL_ROWS - 1).map((m) => ({
98
+ keyname: formatTs(m.timestamp).slice(11),
99
+ value: shortMilestoneValue(m.title)
100
+ }));
101
+ const horizontal = [
102
+ { keyname: "状态", value: clip(input.statusLabel, MAX_HORIZONTAL_VALUE) },
103
+ ...timelineRows
104
+ ];
105
+ const latest = sorted[0];
106
+ const quoteLine = latest ? `${formatTs(latest.timestamp)} — ${clipWord(latest.title, 80)}${latest.description ? `:${clipWord(latest.description, 80)}` : ""}` : "";
107
+ const latestSummary = latest && latest.title ? `${formatTs(latest.timestamp)} ${clip(latest.title, 140)}` : undefined;
108
+ const subTitle = input.terminal ? `任务${input.statusLabel.replace(/^[^\u4e00-\u9fa5A-Za-z]*/, "")} · 详见会话` : latestSummary;
109
+ return {
110
+ card_type: "text_notice",
111
+ main_title: {
112
+ title: `\uD83D\uDCCB Task #${input.taskId} · ${clip(input.title, 60)}`,
113
+ desc: clip(input.description, 80) || undefined
114
+ },
115
+ emphasis_content: {
116
+ title: progressPct,
117
+ desc: "进度"
118
+ },
119
+ sub_title_text: subTitle,
120
+ horizontal_content_list: horizontal,
121
+ quote_area: {
122
+ type: 0,
123
+ title: "最新进展",
124
+ quote_text: quoteLine || "(暂无操作记录)"
125
+ },
126
+ card_action: { type: 0 }
127
+ };
128
+ }
129
+ var MAX_BUTTONS = 6;
130
+ var MAX_BUTTON_TEXT = 10;
131
+ function buildWecomButtonInteractionCard(input) {
132
+ const notice = buildWecomTextNoticeCard({
133
+ taskId: input.taskId,
134
+ title: input.title,
135
+ statusLabel: input.statusLabel,
136
+ progress: input.progress,
137
+ description: input.description,
138
+ changeSummary: input.changeSummary,
139
+ milestones: input.milestones ?? []
140
+ });
141
+ const buttons = (input.buttons ?? []).slice(0, MAX_BUTTONS).map((b) => ({
142
+ text: clip(b.text, MAX_BUTTON_TEXT),
143
+ style: b.style ?? 1,
144
+ key: b.key
145
+ }));
146
+ return {
147
+ card_type: "button_interaction",
148
+ main_title: notice.main_title,
149
+ sub_title_text: notice.sub_title_text,
150
+ horizontal_content_list: notice.horizontal_content_list,
151
+ quote_area: notice.quote_area,
152
+ button_list: buttons,
153
+ card_action: { type: 0 },
154
+ task_id: input.cardTaskId ?? newWecomCardTaskId(input.taskId)
155
+ };
156
+ }
157
+ var WECOM_SESSION_LIFECYCLE_PHRASE = {
158
+ running: "运行中",
159
+ completed: "已完成",
160
+ timeout: "已超时",
161
+ failed: "已失败",
162
+ stopped: "已停止",
163
+ unknown: "状态未知"
164
+ };
165
+ var MAX_SESSION_TITLE = 100;
166
+ function buildWecomSessionCard(input) {
167
+ const lifecycle = input.lifecycle ?? "running";
168
+ const statusLabel = WECOM_SESSION_LIFECYCLE_PHRASE[lifecycle];
169
+ const terminal = lifecycle !== "running";
170
+ const headRaw = input.title?.trim() || input.sessionId;
171
+ const head = clip(headRaw, MAX_SESSION_TITLE);
172
+ const titleParts = [`\uD83D\uDCCA 子会话`, head, statusLabel];
173
+ const rows = [];
174
+ rows.push({ keyname: "会话", value: clip(input.sessionId, MAX_HORIZONTAL_VALUE) });
175
+ if (input.agentType) {
176
+ rows.push({ keyname: "Agent", value: clip(input.agentType, MAX_HORIZONTAL_VALUE) });
177
+ }
178
+ if (input.elapsedText) {
179
+ rows.push({ keyname: "已运行", value: clip(input.elapsedText, MAX_HORIZONTAL_VALUE) });
180
+ }
181
+ if (input.task) {
182
+ rows.push({
183
+ keyname: "任务",
184
+ value: clip(`#${input.task.id}${input.task.title ? ` ${input.task.title}` : ""}`, MAX_HORIZONTAL_VALUE)
185
+ });
186
+ if (input.task.status) {
187
+ rows.push({
188
+ keyname: "任务状态",
189
+ value: clip(input.task.status, MAX_HORIZONTAL_VALUE)
190
+ });
191
+ }
192
+ }
193
+ let quoteArea;
194
+ let subTitle;
195
+ if (input.activity !== undefined) {
196
+ const q = formatActivityQuote(input.activity ?? undefined, input.activityNow ?? Date.now(), terminal);
197
+ if (q.overflow) {
198
+ subTitle = q.text.replace(/\n/g, " · ");
199
+ } else {
200
+ quoteArea = { type: 0, title: q.title, quote_text: q.text };
201
+ }
202
+ } else if (input.milestones && input.milestones.length > 0) {
203
+ const latest = input.milestones[input.milestones.length - 1];
204
+ subTitle = clipWord(latest.title, 60);
205
+ }
206
+ return {
207
+ card_type: "button_interaction",
208
+ main_title: {
209
+ title: titleParts.join(" · ")
210
+ },
211
+ sub_title_text: subTitle,
212
+ horizontal_content_list: rows,
213
+ ...quoteArea ? { quote_area: quoteArea } : {},
214
+ button_list: [
215
+ {
216
+ text: "刷新活性",
217
+ style: 1,
218
+ key: WecomCardActionKey.REFRESH_ACTIVITY
219
+ },
220
+ {
221
+ text: "建飞书群",
222
+ style: 1,
223
+ key: WecomCardActionKey.CREATE_LARK_GROUP
224
+ }
225
+ ],
226
+ card_action: { type: 0 },
227
+ task_id: wecomCardTaskIdForSession(input.sessionId, input.task?.id)
228
+ };
229
+ }
230
+ function buildWecomSendCardFrame(input) {
231
+ const reqId = input.reqId && input.reqId.trim() ? input.reqId.trim() : `aibot_send_msg_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`;
232
+ return {
233
+ cmd: "aibot_send_msg",
234
+ headers: { req_id: reqId },
235
+ body: {
236
+ chatid: input.chatId,
237
+ chat_type: input.chatType === "group" ? 2 : 1,
238
+ msgtype: "template_card",
239
+ template_card: input.card
240
+ }
241
+ };
242
+ }
243
+ var MAX_UPDATE_TITLE = 60;
244
+ function buildUpdateMainTitle(statusLabel, taskNumber, taskTitle) {
245
+ const segments = [];
246
+ if (taskNumber !== undefined && Number.isFinite(taskNumber)) {
247
+ segments.push(`Task #${taskNumber}`);
248
+ }
249
+ if (taskTitle) {
250
+ segments.push(clip(taskTitle, MAX_UPDATE_TITLE));
251
+ }
252
+ segments.push(statusLabel);
253
+ return segments.length > 1 ? `\uD83D\uDCCB ${segments.join(" · ")}` : `\uD83D\uDCCB ${statusLabel}`;
254
+ }
255
+ function buildWecomCardUpdateFrame(input) {
256
+ const reqId = (input.reqId ?? "").trim();
257
+ if (!reqId) {
258
+ throw new Error("buildWecomCardUpdateFrame: req_id is required " + "(update must reference the template_card_event frame)");
259
+ }
260
+ const buttons = (input.buttonOverrides ?? []).slice(0, MAX_BUTTONS).map((b) => ({
261
+ text: clip(b.text, MAX_BUTTON_TEXT),
262
+ style: b.style ?? 1,
263
+ key: b.key
264
+ }));
265
+ const sorted = [...input.timeline ?? []].reverse();
266
+ const timelineRows = sorted.slice(0, MAX_HORIZONTAL_ROWS).map((m) => ({
267
+ keyname: formatTs(m.timestamp).slice(11),
268
+ value: shortMilestoneValue(m.title)
269
+ }));
270
+ const total = sorted.length;
271
+ let subTitle = total > 0 ? total > MAX_HORIZONTAL_ROWS ? `共 ${total} 条操作记录,显示最近 ${MAX_HORIZONTAL_ROWS} 条(最新在顶部)` : `共 ${total} 条操作记录(最新在顶部)` : undefined;
272
+ let quoteArea;
273
+ if (input.activity !== undefined) {
274
+ const q = formatActivityQuote(input.activity ?? undefined, input.activityNow ?? Date.now(), input.activityTerminal ?? false);
275
+ if (q.overflow) {
276
+ const oneLine = q.text.replace(/\n/g, " · ");
277
+ subTitle = subTitle ? `${subTitle}
278
+ ${oneLine}` : oneLine;
279
+ quoteArea = undefined;
280
+ } else {
281
+ quoteArea = { type: 0, title: q.title, quote_text: q.text };
282
+ }
283
+ }
284
+ return {
285
+ cmd: "aibot_respond_update_msg",
286
+ headers: { req_id: reqId },
287
+ body: {
288
+ response_type: "update_template_card",
289
+ template_card: {
290
+ card_type: "button_interaction",
291
+ main_title: {
292
+ title: buildUpdateMainTitle(input.statusLabel, input.taskNumber, input.taskTitle),
293
+ desc: input.note ? clip(input.note, 80) : undefined
294
+ },
295
+ sub_title_text: subTitle,
296
+ horizontal_content_list: timelineRows,
297
+ ...quoteArea ? { quote_area: quoteArea } : {},
298
+ button_list: buttons,
299
+ task_id: String(input.taskId)
300
+ }
301
+ }
302
+ };
303
+ }
304
+ var MAX_SESSION_UPDATE_HEAD = 40;
305
+ function buildWecomSessionUpdateFrame(input) {
306
+ const reqId = (input.reqId ?? "").trim();
307
+ if (!reqId) {
308
+ throw new Error("buildWecomSessionUpdateFrame: req_id is required " + "(update must reference the template_card_event frame)");
309
+ }
310
+ const now = input.now ?? Date.now();
311
+ const lifecycle = input.lifecycle;
312
+ const statusLabel = WECOM_SESSION_LIFECYCLE_PHRASE[lifecycle];
313
+ const terminal = lifecycle !== "running";
314
+ const headRaw = input.title?.trim() || input.sessionId;
315
+ const head = clip(headRaw, MAX_SESSION_UPDATE_HEAD);
316
+ const mainTitle = `\uD83D\uDCCA 子会话 · ${head} · ${statusLabel}`;
317
+ const rows = [];
318
+ rows.push({
319
+ keyname: clip("状态", MAX_HORIZONTAL_KEYNAME),
320
+ value: clip(statusLabel, MAX_HORIZONTAL_VALUE)
321
+ });
322
+ rows.push({
323
+ keyname: clip("会话", MAX_HORIZONTAL_KEYNAME),
324
+ value: clip(input.sessionId, MAX_HORIZONTAL_VALUE)
325
+ });
326
+ if (input.agentType) {
327
+ rows.push({
328
+ keyname: clip("Agent", MAX_HORIZONTAL_KEYNAME),
329
+ value: clip(input.agentType, MAX_HORIZONTAL_VALUE)
330
+ });
331
+ }
332
+ const elapsed = input.elapsedText ?? formatElapsedText(input.startedAt, now, terminal);
333
+ if (elapsed) {
334
+ rows.push({
335
+ keyname: clip("已运行", MAX_HORIZONTAL_KEYNAME),
336
+ value: clip(elapsed, MAX_HORIZONTAL_VALUE)
337
+ });
338
+ }
339
+ if (input.task) {
340
+ rows.push({
341
+ keyname: clip("任务", MAX_HORIZONTAL_KEYNAME),
342
+ value: clip(`#${input.task.id}${input.task.title ? ` ${input.task.title}` : ""}`, MAX_HORIZONTAL_VALUE)
343
+ });
344
+ }
345
+ if (input.perTaskChatId) {
346
+ rows.push({
347
+ keyname: clip("飞书群", MAX_HORIZONTAL_KEYNAME),
348
+ value: clip(input.perTaskChatId, MAX_HORIZONTAL_VALUE)
349
+ });
350
+ }
351
+ if (input.task?.status && rows.length < MAX_HORIZONTAL_ROWS) {
352
+ rows.push({
353
+ keyname: clip("任务状态", MAX_HORIZONTAL_KEYNAME),
354
+ value: clip(input.task.status, MAX_HORIZONTAL_VALUE)
355
+ });
356
+ }
357
+ const sorted = [...input.milestones ?? []].reverse();
358
+ const remaining = Math.max(0, MAX_HORIZONTAL_ROWS - rows.length);
359
+ const timelineRows = sorted.slice(0, remaining).map((m) => ({
360
+ keyname: clip(formatTs(m.timestamp).slice(11), MAX_HORIZONTAL_KEYNAME),
361
+ value: shortMilestoneValue(m.title)
362
+ }));
363
+ const totalMs = sorted.length;
364
+ const droppedMs = totalMs - timelineRows.length;
365
+ let quoteArea;
366
+ let subTitle;
367
+ if (input.activity !== undefined) {
368
+ const q = formatActivityQuote(input.activity ?? undefined, input.now ?? Date.now(), terminal);
369
+ if (q.overflow) {
370
+ subTitle = q.text.replace(/\n/g, " · ");
371
+ } else {
372
+ quoteArea = { type: 0, title: q.title, quote_text: q.text };
373
+ }
374
+ }
375
+ if (droppedMs > 0) {
376
+ const hint = `共 ${totalMs} 条操作记录,显示最近 ${timelineRows.length} 条`;
377
+ subTitle = subTitle ? `${hint} · ${subTitle}` : hint;
378
+ }
379
+ if (input.errorHint) {
380
+ subTitle = subTitle ? `${input.errorHint} · ${subTitle}` : input.errorHint;
381
+ }
382
+ return {
383
+ cmd: "aibot_respond_update_msg",
384
+ headers: { req_id: reqId },
385
+ body: {
386
+ response_type: "update_template_card",
387
+ template_card: {
388
+ card_type: "button_interaction",
389
+ main_title: { title: mainTitle },
390
+ ...subTitle ? { sub_title_text: subTitle } : {},
391
+ horizontal_content_list: [...rows, ...timelineRows],
392
+ ...quoteArea ? { quote_area: quoteArea } : {},
393
+ button_list: [
394
+ {
395
+ text: "刷新活性",
396
+ style: 1,
397
+ key: WecomCardActionKey.REFRESH_ACTIVITY
398
+ },
399
+ {
400
+ text: "建飞书群",
401
+ style: 1,
402
+ key: WecomCardActionKey.CREATE_LARK_GROUP
403
+ }
404
+ ],
405
+ card_action: { type: 0 },
406
+ task_id: String(input.cardTaskId)
407
+ }
408
+ }
409
+ };
410
+ }
411
+ function formatElapsedText(startedAt, now, _terminal) {
412
+ if (!startedAt)
413
+ return;
414
+ const start = new Date(startedAt).getTime();
415
+ if (!Number.isFinite(start))
416
+ return;
417
+ const ms = Math.max(0, now - start);
418
+ const totalMin = Math.floor(ms / 60000);
419
+ if (totalMin < 1)
420
+ return "<1m";
421
+ const h = Math.floor(totalMin / 60);
422
+ const m = totalMin % 60;
423
+ return h > 0 ? `${h}h${m}m` : `${m}m`;
424
+ }
425
+
426
+ export { WecomCardActionKey, ROY_SESSION_PREFIX, WECOM_SESSION_TASK_SEP, buildWecomTextNoticeCard, buildWecomButtonInteractionCard, buildWecomSessionCard, buildWecomSendCardFrame, buildWecomCardUpdateFrame, buildWecomSessionUpdateFrame };