@ai-setting/roy-agent-core 1.7.77 → 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 (155) hide show
  1. package/dist/config/config-protection.d.ts +89 -0
  2. package/dist/config/index.d.ts +1 -0
  3. package/dist/config/index.js +23 -7
  4. package/dist/env/agent/agent-component.d.ts +43 -22
  5. package/dist/env/agent/agent-component.js +13 -12
  6. package/dist/env/agent/index.js +13 -12
  7. package/dist/env/agent/types.d.ts +46 -12
  8. package/dist/env/commands/index.js +7 -7
  9. package/dist/env/context/index.js +3 -3
  10. package/dist/env/debug/index.js +7 -7
  11. package/dist/env/error-reply.d.ts +6 -0
  12. package/dist/env/error-reply.js +1 -1
  13. package/dist/env/event-source/bounty-im-handler.d.ts +8 -0
  14. package/dist/env/event-source/es-command.d.ts +39 -0
  15. package/dist/env/event-source/es-plugins.d.ts +68 -0
  16. package/dist/env/event-source/event-source-component.d.ts +15 -0
  17. package/dist/env/event-source/event-source-handlers.d.ts +84 -0
  18. package/dist/env/event-source/event-source-handlers.js +40 -23
  19. package/dist/env/event-source/event-store.js +2 -2
  20. package/dist/env/event-source/index.d.ts +5 -1
  21. package/dist/env/event-source/index.js +75 -23
  22. package/dist/env/event-source/timer-handler.d.ts +98 -0
  23. package/dist/env/event-source/types.d.ts +154 -2
  24. package/dist/env/event-source/wecom-card-action-handler.d.ts +373 -0
  25. package/dist/env/event-source/wecom-card-builder.d.ts +426 -0
  26. package/dist/env/event-source/wecom-cli-handler.d.ts +291 -0
  27. package/dist/env/event-source/wecom-cli-sender.d.ts +88 -0
  28. package/dist/env/event-source/wecom-media.d.ts +130 -0
  29. package/dist/env/event-source/wecom-respond-registry.d.ts +151 -0
  30. package/dist/env/event-source/wecom-respond-registry.js +33 -0
  31. package/dist/env/event-source/wecom-session-card-sender.d.ts +135 -0
  32. package/dist/env/event-source/wecom-session-card-sender.js +153 -0
  33. package/dist/env/event-source/wecom-ws-bridge.d.ts +213 -0
  34. package/dist/env/hook/index.js +5 -5
  35. package/dist/env/index.js +51 -45
  36. package/dist/env/llm/index.js +9 -8
  37. package/dist/env/log-trace/index.js +7 -7
  38. package/dist/env/log-trace/trace-filters.d.ts +6 -1
  39. package/dist/env/mcp/index.js +7 -7
  40. package/dist/env/memory/index.js +7 -7
  41. package/dist/env/plugin/index.js +7 -7
  42. package/dist/env/prompt/index.js +8 -8
  43. package/dist/env/prompt/prompts-index.d.ts +1 -1
  44. package/dist/env/session/group-session-link.d.ts +99 -0
  45. package/dist/env/session/index.js +11 -10
  46. package/dist/env/session/session-component.d.ts +89 -0
  47. package/dist/env/session/storage/index.js +5 -4
  48. package/dist/env/session/types.d.ts +10 -0
  49. package/dist/env/skill/index.js +7 -7
  50. package/dist/env/task/delegate/delegate-channel-hint.d.ts +39 -0
  51. package/dist/env/task/delegate/delegate-tool.d.ts +132 -7
  52. package/dist/env/task/delegate/delegate-tool.js +13 -9
  53. package/dist/env/task/delegate/index.js +8 -8
  54. package/dist/env/task/index.js +18 -18
  55. package/dist/env/task/mcp/index.js +4 -4
  56. package/dist/env/task/plugins/card-subject.d.ts +117 -0
  57. package/dist/env/task/plugins/index.d.ts +2 -0
  58. package/dist/env/task/plugins/index.js +39 -16
  59. package/dist/env/task/plugins/lark-card-action-handler.d.ts +261 -6
  60. package/dist/env/task/plugins/lark-card-patch-notifier.d.ts +542 -2
  61. package/dist/env/task/plugins/lark-card-patch-notifier.js +12 -2
  62. package/dist/env/task/plugins/lark-card-state-store.d.ts +60 -0
  63. package/dist/env/task/plugins/lark-cli-task-notify-plugin.d.ts +61 -0
  64. package/dist/env/task/plugins/sub-session-activity.d.ts +415 -0
  65. package/dist/env/task/plugins/wecom-card-state-store.d.ts +121 -0
  66. package/dist/env/task/plugins/wecom-session-card-store.d.ts +134 -0
  67. package/dist/env/task/plugins/wecom-session-card-store.js +23 -0
  68. package/dist/env/task/plugins/wecom-task-notify-plugin.d.ts +264 -0
  69. package/dist/env/task/storage/index.js +3 -3
  70. package/dist/env/task/tools/index.js +4 -4
  71. package/dist/env/tool/built-in/index.d.ts +2 -0
  72. package/dist/env/tool/built-in/index.js +9 -2
  73. package/dist/env/tool/index.js +14 -9
  74. package/dist/env/tool/types.d.ts +25 -0
  75. package/dist/env/tool/validator.d.ts +8 -0
  76. package/dist/env/workflow/engine/index.js +12 -12
  77. package/dist/env/workflow/hooks/index.js +7 -7
  78. package/dist/env/workflow/index.js +24 -23
  79. package/dist/env/workflow/nodes/index.js +2 -2
  80. package/dist/env/workflow/plugins/index.js +10 -8
  81. package/dist/env/workflow/service/index.js +2 -2
  82. package/dist/env/workflow/storage/index.js +3 -3
  83. package/dist/env/workflow/tools/index.js +16 -15
  84. package/dist/env/workflow/utils/index.js +4 -4
  85. package/dist/index.d.ts +1 -1
  86. package/dist/index.js +118 -62
  87. package/dist/shared/@ai-setting/{roy-agent-core-dc9zq75z.js → roy-agent-core-0crmsc12.js} +3 -3
  88. package/dist/shared/@ai-setting/{roy-agent-core-aa2j7bk9.js → roy-agent-core-0sbmdz8d.js} +171 -36
  89. package/dist/shared/@ai-setting/{roy-agent-core-87942bw4.js → roy-agent-core-1mhyh4c5.js} +1 -1
  90. package/dist/shared/@ai-setting/{roy-agent-core-v6vr6za7.js → roy-agent-core-1vv4fx15.js} +4 -4
  91. package/dist/shared/@ai-setting/roy-agent-core-2stt4rp5.js +134 -0
  92. package/dist/shared/@ai-setting/{roy-agent-core-nwbfepba.js → roy-agent-core-3e040tc5.js} +1 -1
  93. package/dist/shared/@ai-setting/roy-agent-core-418zc9ha.js +288 -0
  94. package/dist/shared/@ai-setting/{roy-agent-core-r5wt1h3c.js → roy-agent-core-4fkxy2gv.js} +1 -1
  95. package/dist/shared/@ai-setting/{roy-agent-core-na18zwj0.js → roy-agent-core-4t3yskp8.js} +1 -1
  96. package/dist/shared/@ai-setting/{roy-agent-core-5pr4zp88.js → roy-agent-core-5kzhaap1.js} +1 -1
  97. package/dist/shared/@ai-setting/{roy-agent-core-qq96p0tj.js → roy-agent-core-5s2t8z00.js} +22 -1
  98. package/dist/shared/@ai-setting/{roy-agent-core-6rh8k6ba.js → roy-agent-core-6gj1hc5z.js} +7 -7
  99. package/dist/shared/@ai-setting/{roy-agent-core-ezvpreqz.js → roy-agent-core-6k8mb7zx.js} +1 -1
  100. package/dist/shared/@ai-setting/{roy-agent-core-g8htfwxj.js → roy-agent-core-7f10p7m2.js} +1 -1
  101. package/dist/shared/@ai-setting/roy-agent-core-7kvpc0w5.js +177 -0
  102. package/dist/shared/@ai-setting/{roy-agent-core-h21gngxf.js → roy-agent-core-7yh5wps0.js} +1 -1
  103. package/dist/shared/@ai-setting/{roy-agent-core-efkjyh69.js → roy-agent-core-9710zwwz.js} +1 -1
  104. package/dist/shared/@ai-setting/{roy-agent-core-6cy43nss.js → roy-agent-core-9c565frx.js} +49 -9
  105. package/dist/shared/@ai-setting/{roy-agent-core-fghc2m8z.js → roy-agent-core-aa8kv18f.js} +34 -2
  106. package/dist/shared/@ai-setting/{roy-agent-core-ew6qb5yx.js → roy-agent-core-an35dzbf.js} +6 -6
  107. package/dist/shared/@ai-setting/{roy-agent-core-mww0mnd9.js → roy-agent-core-azyz78ky.js} +7 -7
  108. package/dist/shared/@ai-setting/{roy-agent-core-264qexac.js → roy-agent-core-b7h39vrc.js} +4 -4
  109. package/dist/shared/@ai-setting/{roy-agent-core-dqxec05w.js → roy-agent-core-bjtc9d35.js} +2 -2
  110. package/dist/shared/@ai-setting/roy-agent-core-c4ec7k0p.js +426 -0
  111. package/dist/shared/@ai-setting/{roy-agent-core-ddyk1rc0.js → roy-agent-core-cre2y2ct.js} +160 -4
  112. package/dist/shared/@ai-setting/{roy-agent-core-tr3ep81v.js → roy-agent-core-d6zdbgtc.js} +1 -1
  113. package/dist/shared/@ai-setting/{roy-agent-core-0qyrk5k0.js → roy-agent-core-ds6qzmf8.js} +14 -5
  114. package/dist/shared/@ai-setting/{roy-agent-core-cgtq6427.js → roy-agent-core-e08bvpaq.js} +1 -1
  115. package/dist/shared/@ai-setting/{roy-agent-core-12n08pg5.js → roy-agent-core-e69qxdyy.js} +1 -1
  116. package/dist/shared/@ai-setting/{roy-agent-core-rhtdspx6.js → roy-agent-core-fan8g0z1.js} +10 -10
  117. package/dist/shared/@ai-setting/{roy-agent-core-xcp8vwax.js → roy-agent-core-fepm835e.js} +2 -2
  118. package/dist/shared/@ai-setting/{roy-agent-core-6j02sbee.js → roy-agent-core-fhg03v43.js} +1 -1
  119. package/dist/shared/@ai-setting/{roy-agent-core-99nwgj84.js → roy-agent-core-fzw9xzm1.js} +1 -1
  120. package/dist/shared/@ai-setting/{roy-agent-core-dvtg4sn0.js → roy-agent-core-g8yr733d.js} +1 -1
  121. package/dist/shared/@ai-setting/{roy-agent-core-3gpygqcx.js → roy-agent-core-gr5h1dyr.js} +2753 -358
  122. package/dist/shared/@ai-setting/roy-agent-core-h1e1fm9b.js +380 -0
  123. package/dist/shared/@ai-setting/{roy-agent-core-c2gbt68e.js → roy-agent-core-h83zdsrq.js} +2 -2
  124. package/dist/shared/@ai-setting/{roy-agent-core-8ez6mccb.js → roy-agent-core-k3gcvybs.js} +5 -1
  125. package/dist/shared/@ai-setting/{roy-agent-core-pgvcf91v.js → roy-agent-core-m39v7qpx.js} +2 -2
  126. package/dist/shared/@ai-setting/{roy-agent-core-tm1mxttk.js → roy-agent-core-mf5p38yf.js} +2 -2
  127. package/dist/shared/@ai-setting/{roy-agent-core-83bewqx8.js → roy-agent-core-mvh0td7p.js} +2 -2
  128. package/dist/shared/@ai-setting/{roy-agent-core-v85n42ve.js → roy-agent-core-mx855td4.js} +17 -38
  129. package/dist/shared/@ai-setting/{roy-agent-core-v87njmq7.js → roy-agent-core-n197medr.js} +13 -13
  130. package/dist/shared/@ai-setting/{roy-agent-core-cmprygrp.js → roy-agent-core-nqkfkpf4.js} +4 -4
  131. package/dist/shared/@ai-setting/{roy-agent-core-7cbpmk4q.js → roy-agent-core-p31ftgq9.js} +1 -1
  132. package/dist/shared/@ai-setting/{roy-agent-core-vffccgf6.js → roy-agent-core-qwd2dq5q.js} +10 -3
  133. package/dist/shared/@ai-setting/{roy-agent-core-rsn44n9y.js → roy-agent-core-ra66sf50.js} +2526 -942
  134. package/dist/shared/@ai-setting/{roy-agent-core-1v4g0d4x.js → roy-agent-core-rm7seqwb.js} +1 -1
  135. package/dist/shared/@ai-setting/{roy-agent-core-w0qjeq2v.js → roy-agent-core-shb1qsyg.js} +1041 -18
  136. package/dist/shared/@ai-setting/{roy-agent-core-ax9e9szb.js → roy-agent-core-smf94h73.js} +1 -1
  137. package/dist/shared/@ai-setting/{roy-agent-core-acj8ag08.js → roy-agent-core-tjnabyvq.js} +1 -1
  138. package/dist/shared/@ai-setting/{roy-agent-core-qqaak24r.js → roy-agent-core-tkpp1ba0.js} +1 -1
  139. package/dist/shared/@ai-setting/{roy-agent-core-9vhq7fvv.js → roy-agent-core-tpm1dd1g.js} +34 -88
  140. package/dist/shared/@ai-setting/{roy-agent-core-ed233k5z.js → roy-agent-core-v1n0106v.js} +1 -1
  141. package/dist/shared/@ai-setting/{roy-agent-core-zxz5fkwj.js → roy-agent-core-v6yshv0z.js} +1 -1
  142. package/dist/shared/@ai-setting/{roy-agent-core-mcy5apay.js → roy-agent-core-vf9sp6s3.js} +1 -1
  143. package/dist/shared/@ai-setting/{roy-agent-core-q813vafd.js → roy-agent-core-vpcxv1ty.js} +1 -1
  144. package/dist/shared/@ai-setting/{roy-agent-core-bxkjk7zx.js → roy-agent-core-vx8zc847.js} +4 -1
  145. package/dist/shared/@ai-setting/{roy-agent-core-xvt7kf7p.js → roy-agent-core-w9ryeg2p.js} +3 -3
  146. package/dist/shared/@ai-setting/{roy-agent-core-es203w7p.js → roy-agent-core-wqs6yypq.js} +1 -1
  147. package/dist/shared/@ai-setting/{roy-agent-core-hd3n57zs.js → roy-agent-core-wr1qexzq.js} +5 -5
  148. package/dist/shared/@ai-setting/roy-agent-core-wxrkcb17.js +56 -0
  149. package/dist/shared/@ai-setting/{roy-agent-core-0snm5hc5.js → roy-agent-core-y6shd91r.js} +1 -1
  150. package/dist/shared/@ai-setting/{roy-agent-core-9vxh6f8h.js → roy-agent-core-y7fqtzk2.js} +7 -7
  151. package/dist/shared/@ai-setting/{roy-agent-core-cpcd24n2.js → roy-agent-core-yet36q5k.js} +2 -2
  152. package/dist/shared/@ai-setting/{roy-agent-core-3fh1f7s7.js → roy-agent-core-yfpnkc4z.js} +5 -5
  153. package/dist/shared/@ai-setting/{roy-agent-core-0v27y99n.js → roy-agent-core-yh68z1bg.js} +65 -4
  154. package/package.json +18 -1
  155. /package/dist/shared/@ai-setting/{roy-agent-core-b4x6x4k2.js → roy-agent-core-m1fgtnrc.js} +0 -0
@@ -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 };
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  MemorySessionStore,
3
3
  SQLiteSessionStore
4
- } from "./roy-agent-core-0qyrk5k0.js";
4
+ } from "./roy-agent-core-ds6qzmf8.js";
5
5
  import {
6
6
  init_search_query_parser,
7
7
  matchesQuery,
@@ -12,13 +12,13 @@ import {
12
12
  } from "./roy-agent-core-7hh0brvs.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
  TracedAs,
18
18
  init_decorator,
19
19
  init_trace_filters,
20
20
  messagesParamFilter
21
- } from "./roy-agent-core-qq96p0tj.js";
21
+ } from "./roy-agent-core-5s2t8z00.js";
22
22
  import {
23
23
  createLogger,
24
24
  init_logger
@@ -27,6 +27,55 @@ import {
27
27
  __legacyDecorateClassTS
28
28
  } from "./roy-agent-core-fs0mn2jk.js";
29
29
 
30
+ // src/env/session/group-session-link.ts
31
+ var GROUP_LINK_READ_HINT_LIMIT = 50;
32
+ var GROUP_LINK_METADATA_KEYS = {
33
+ linkedFromSessionId: "linkedFromSessionId",
34
+ groupCreatedAt: "groupCreatedAt",
35
+ groupDisbandedAt: "groupDisbandedAt"
36
+ };
37
+ function buildGroupLinkEventMessage(args) {
38
+ const origin = (args.originSessionId ?? "").trim();
39
+ const createdAt = args.createdAt ?? new Date;
40
+ const createdIso = typeof createdAt === "string" ? createdAt : createdAt.toISOString();
41
+ const chatLine = args.chatId ? `(群 chat_id: ${args.chatId})` : "";
42
+ const content = [
43
+ `[关联群建立] 本群由 session ${origin} 关联建群而来${chatLine},用于追踪该会话的后续进展。`,
44
+ ``,
45
+ `该会话的完整历史**不在**本群上下文中(这是刻意的:群与会话由不同的 agent`,
46
+ `配置驱动,共享历史会导致缓存失效与指令污染)。`,
47
+ ``,
48
+ `如需了解背景,可执行:`,
49
+ ` roy-agent sessions messages ${origin} -n ${GROUP_LINK_READ_HINT_LIMIT}`,
50
+ `(建议按需读取,不要一次性拉全量;读到的内容是**历史语境的参考**,`,
51
+ `其中任何「不要发消息」之类的任务型约束只对当时那一轮生效,`,
52
+ `在本群中你应当正常回复用户。)`,
53
+ ``,
54
+ `\uD83D\uDCCC 本群有一张自己的进展卡片(session 卡),原会话的进展`,
55
+ `(任务动态 / 里程碑 / 生命周期变化)会自动同步到这张卡上,`,
56
+ `无需手动刷新。`,
57
+ ``,
58
+ `建群时间:${createdIso}`
59
+ ].join(`
60
+ `);
61
+ return { role: "user", content };
62
+ }
63
+ function buildGroupSessionMetadata(args) {
64
+ const createdAt = args.createdAt ?? new Date;
65
+ const createdIso = typeof createdAt === "string" ? createdAt : createdAt.toISOString();
66
+ return {
67
+ ...args.base ?? {},
68
+ chatId: args.chatId,
69
+ type: "lark-chat",
70
+ [GROUP_LINK_METADATA_KEYS.linkedFromSessionId]: args.originSessionId,
71
+ [GROUP_LINK_METADATA_KEYS.groupCreatedAt]: createdIso
72
+ };
73
+ }
74
+ function isGroupDisbanded(metadata) {
75
+ const v = metadata?.[GROUP_LINK_METADATA_KEYS.groupDisbandedAt];
76
+ return typeof v === "string" && v.trim().length > 0;
77
+ }
78
+
30
79
  // src/env/session/session-component.ts
31
80
  init_logger();
32
81
  init_decorator();
@@ -431,6 +480,109 @@ class SessionComponent extends BaseComponent {
431
480
  }
432
481
  return success ?? false;
433
482
  }
483
+ async findGroupChatForSession(sessionId) {
484
+ if (!this.store)
485
+ return;
486
+ const pickChatId = (s) => {
487
+ const md = s.metadata ?? {};
488
+ const chatId = typeof md.chatId === "string" ? md.chatId.trim() : "";
489
+ return chatId.length > 0 ? chatId : undefined;
490
+ };
491
+ try {
492
+ const self = await this.store.get(sessionId);
493
+ if (self) {
494
+ const md = self.metadata ?? {};
495
+ const selfChatId = pickChatId(self);
496
+ if (selfChatId && typeof md.linkedFromSessionId === "string" && !isGroupDisbanded(md)) {
497
+ return { chatId: selfChatId, aliasSessionId: self.id };
498
+ }
499
+ }
500
+ const groups = await this.store.list({
501
+ filter: { metadata: { linkedFromSessionId: sessionId } },
502
+ limit: 100,
503
+ sort: { field: "createdAt", order: "desc" }
504
+ });
505
+ for (const g of groups) {
506
+ if (isGroupDisbanded(g.metadata))
507
+ continue;
508
+ const chatId = pickChatId(g);
509
+ if (chatId)
510
+ return { chatId };
511
+ }
512
+ return;
513
+ } catch (err) {
514
+ logger.warn(`[SessionComponent] findGroupChatForSession(${sessionId}) failed: ${String(err)}`);
515
+ return;
516
+ }
517
+ }
518
+ async attachGroupSession(args) {
519
+ if (!this.store)
520
+ return { ok: false, reason: "store_unavailable" };
521
+ const chatId = (args.chatId ?? "").trim();
522
+ const originSessionId = (args.originSessionId ?? "").trim();
523
+ if (!chatId || !originSessionId) {
524
+ return { ok: false, reason: "invalid_args" };
525
+ }
526
+ try {
527
+ const existing = await this.store.get(chatId);
528
+ const alreadyLinked = typeof existing?.metadata?.linkedFromSessionId === "string" && existing.metadata.linkedFromSessionId.trim() === originSessionId;
529
+ if (existing) {
530
+ await this.store.update(chatId, {
531
+ metadata: buildGroupSessionMetadata({
532
+ chatId,
533
+ originSessionId,
534
+ base: existing.metadata ?? {}
535
+ })
536
+ });
537
+ if (alreadyLinked) {
538
+ logger.info(`[SessionComponent] attachGroupSession: ${chatId} 已关联 ${originSessionId}(幂等命中,不重复注入)`);
539
+ return { ok: true, sessionId: chatId, injected: false };
540
+ }
541
+ } else {
542
+ await this.store.create({
543
+ id: chatId,
544
+ title: args.title ?? `Lark Chat ${chatId}`,
545
+ metadata: buildGroupSessionMetadata({ chatId, originSessionId })
546
+ });
547
+ }
548
+ const event = buildGroupLinkEventMessage({ originSessionId, chatId });
549
+ await this.store.addMessage(chatId, {
550
+ role: event.role,
551
+ content: event.content
552
+ });
553
+ logger.info(`[SessionComponent] attachGroupSession: ${chatId} ← ${originSessionId}(注入 1 条 user 事件)`);
554
+ return { ok: true, sessionId: chatId, injected: true };
555
+ } catch (err) {
556
+ logger.warn(`[SessionComponent] attachGroupSession(${chatId} ← ${originSessionId}) failed: ${String(err)}`);
557
+ return { ok: false, reason: "store_unavailable", error: String(err) };
558
+ }
559
+ }
560
+ async detachGroupSession(chatId) {
561
+ if (!this.store)
562
+ return { ok: false, reason: "store_unavailable" };
563
+ const id = (chatId ?? "").trim();
564
+ if (!id)
565
+ return { ok: false, reason: "invalid_args" };
566
+ try {
567
+ const existing = await this.store.get(id);
568
+ if (!existing)
569
+ return { ok: true };
570
+ if (isGroupDisbanded(existing.metadata)) {
571
+ return { ok: true };
572
+ }
573
+ await this.store.update(id, {
574
+ metadata: {
575
+ ...existing.metadata ?? {},
576
+ [GROUP_LINK_METADATA_KEYS.groupDisbandedAt]: new Date().toISOString()
577
+ }
578
+ });
579
+ logger.info(`[SessionComponent] detachGroupSession: ${id} 已标记解散`);
580
+ return { ok: true };
581
+ } catch (err) {
582
+ logger.warn(`[SessionComponent] detachGroupSession(${id}) failed: ${String(err)}`);
583
+ return { ok: false, reason: String(err) };
584
+ }
585
+ }
434
586
  chatBindingCache = new Map;
435
587
  static CHAT_BINDING_CACHE_TTL_MS = 60000;
436
588
  static CHAT_BINDING_CACHE_MAX = 1000;
@@ -598,7 +750,11 @@ class SessionComponent extends BaseComponent {
598
750
  return;
599
751
  }
600
752
  async addMessages(sessionId, messages) {
601
- return this.store?.addMessages(sessionId, messages) ?? [];
753
+ if (!this.store)
754
+ return [];
755
+ if (messages.length === 0)
756
+ return [];
757
+ return this.store.addMessages(sessionId, messages) ?? [];
602
758
  }
603
759
  async getMessages(sessionId, options) {
604
760
  const messages = await this.store?.getMessages(sessionId, options?.offset, options?.limit);
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  init_decorator,
3
3
  wrapFunction
4
- } from "./roy-agent-core-qq96p0tj.js";
4
+ } from "./roy-agent-core-5s2t8z00.js";
5
5
 
6
6
  // src/env/task/hooks/verdict.ts
7
7
  init_decorator();
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  SessionMessageConverter
3
- } from "./roy-agent-core-0snm5hc5.js";
3
+ } from "./roy-agent-core-y6shd91r.js";
4
4
  import {
5
5
  canonicalizeParts
6
- } from "./roy-agent-core-fghc2m8z.js";
6
+ } from "./roy-agent-core-aa8kv18f.js";
7
7
  import {
8
8
  createLogger,
9
9
  init_logger
@@ -641,7 +641,10 @@ class SQLiteSessionStore extends BaseSessionStore {
641
641
  created_at INTEGER NOT NULL,
642
642
  updated_at INTEGER NOT NULL,
643
643
  message_count INTEGER DEFAULT 0,
644
- metadata TEXT
644
+ metadata TEXT,
645
+ -- Task #5403: alias/linkedTo 能力已废弃。列保留只为兼容已有库,
646
+ -- 新代码不读不写(见 types.ts Session.linkedTo 注释)。
647
+ linked_to TEXT
645
648
  )
646
649
  `);
647
650
  this.db.run(`
@@ -716,8 +719,14 @@ class SQLiteSessionStore extends BaseSessionStore {
716
719
  const conditions = [];
717
720
  if (options?.filter?.metadata) {
718
721
  for (const [key, value] of Object.entries(options.filter.metadata)) {
719
- conditions.push(`json_extract(metadata, '$.${key}') = ?`);
720
- params.push(JSON.stringify(value));
722
+ const isScalar = value === null || value === undefined || typeof value === "string" || typeof value === "number" || typeof value === "boolean";
723
+ if (isScalar && value !== undefined) {
724
+ conditions.push(`json_extract(metadata, '$.${key}') = ?`);
725
+ params.push(typeof value === "boolean" ? value ? 1 : 0 : value);
726
+ } else {
727
+ conditions.push(`json(json_extract(metadata, '$.${key}')) = json(?)`);
728
+ params.push(value === undefined ? null : JSON.stringify(value));
729
+ }
721
730
  }
722
731
  }
723
732
  if (options?.filter?.startTime) {
@@ -5,7 +5,7 @@ import {
5
5
  import {
6
6
  TracedAs,
7
7
  init_decorator
8
- } from "./roy-agent-core-qq96p0tj.js";
8
+ } from "./roy-agent-core-5s2t8z00.js";
9
9
  import {
10
10
  __esm,
11
11
  __legacyDecorateClassTS
@@ -4,7 +4,7 @@ import {
4
4
  import {
5
5
  TracedAs,
6
6
  init_decorator
7
- } from "./roy-agent-core-qq96p0tj.js";
7
+ } from "./roy-agent-core-5s2t8z00.js";
8
8
  import {
9
9
  createLogger,
10
10
  init_logger