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

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 (82) 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 +16 -0
  4. package/dist/env/agent/agent-component.d.ts +42 -21
  5. package/dist/env/agent/agent-component.js +3 -3
  6. package/dist/env/agent/index.js +3 -3
  7. package/dist/env/agent/types.d.ts +32 -12
  8. package/dist/env/error-reply.d.ts +6 -0
  9. package/dist/env/error-reply.js +1 -1
  10. package/dist/env/event-source/bounty-im-handler.d.ts +8 -0
  11. package/dist/env/event-source/es-command.d.ts +39 -0
  12. package/dist/env/event-source/es-plugins.d.ts +68 -0
  13. package/dist/env/event-source/event-source-component.d.ts +15 -0
  14. package/dist/env/event-source/event-source-handlers.d.ts +68 -0
  15. package/dist/env/event-source/event-source-handlers.js +22 -10
  16. package/dist/env/event-source/index.d.ts +5 -1
  17. package/dist/env/event-source/index.js +59 -10
  18. package/dist/env/event-source/types.d.ts +101 -1
  19. package/dist/env/event-source/wecom-card-action-handler.d.ts +141 -0
  20. package/dist/env/event-source/wecom-card-builder.d.ts +220 -0
  21. package/dist/env/event-source/wecom-cli-handler.d.ts +266 -0
  22. package/dist/env/event-source/wecom-cli-sender.d.ts +88 -0
  23. package/dist/env/event-source/wecom-media.d.ts +130 -0
  24. package/dist/env/event-source/wecom-respond-registry.d.ts +151 -0
  25. package/dist/env/event-source/wecom-ws-bridge.d.ts +213 -0
  26. package/dist/env/index.js +19 -17
  27. package/dist/env/task/backend/index.js +37 -1
  28. package/dist/env/task/backend/task-store-backend.d.ts +12 -0
  29. package/dist/env/task/backend/types.d.ts +19 -0
  30. package/dist/env/task/delegate/delegate-tool.d.ts +62 -2
  31. package/dist/env/task/delegate/delegate-tool.js +3 -1
  32. package/dist/env/task/delegate/index.js +1 -1
  33. package/dist/env/task/index.js +4 -4
  34. package/dist/env/task/mcp/index.js +3 -0
  35. package/dist/env/task/mcp/task-mcp-server.d.ts +1 -1
  36. package/dist/env/task/plugins/fake-user-message-helper.d.ts +10 -2
  37. package/dist/env/task/plugins/index.d.ts +3 -0
  38. package/dist/env/task/plugins/index.js +36 -4
  39. package/dist/env/task/plugins/lark-card-patch-notifier.d.ts +41 -2
  40. package/dist/env/task/plugins/lark-card-patch-notifier.js +1 -1
  41. package/dist/env/task/plugins/lark-cli-task-notify-plugin.d.ts +16 -0
  42. package/dist/env/task/plugins/task-op-watermark-plugin.d.ts +112 -0
  43. package/dist/env/task/plugins/wecom-card-state-store.d.ts +121 -0
  44. package/dist/env/task/plugins/wecom-task-notify-plugin.d.ts +224 -0
  45. package/dist/env/task/storage/index.js +2 -2
  46. package/dist/env/task/storage/sqlite-task-store.d.ts +54 -0
  47. package/dist/env/task/task-component.d.ts +16 -0
  48. package/dist/env/task/tools/operation/operation-types.d.ts +13 -13
  49. package/dist/env/tool/built-in/index.d.ts +2 -0
  50. package/dist/env/tool/built-in/index.js +6 -1
  51. package/dist/env/tool/index.js +3 -2
  52. package/dist/env/workflow/index.js +3 -3
  53. package/dist/env/workflow/plugins/index.js +2 -2
  54. package/dist/env/workflow/tools/index.js +2 -2
  55. package/dist/env/workflow/types/event.d.ts +4 -4
  56. package/dist/index.d.ts +1 -1
  57. package/dist/index.js +71 -20
  58. package/dist/shared/@ai-setting/{roy-agent-core-v87njmq7.js → roy-agent-core-0dh8npnz.js} +1 -1
  59. package/dist/shared/@ai-setting/roy-agent-core-2stt4rp5.js +134 -0
  60. package/dist/shared/@ai-setting/{roy-agent-core-mww0mnd9.js → roy-agent-core-7bpj859q.js} +1 -1
  61. package/dist/shared/@ai-setting/{roy-agent-core-nmx9934r.js → roy-agent-core-7dd0s3xb.js} +15 -5
  62. package/dist/shared/@ai-setting/{roy-agent-core-ghnagzrh.js → roy-agent-core-b31v3qpv.js} +853 -48
  63. package/dist/shared/@ai-setting/{roy-agent-core-cxy143m4.js → roy-agent-core-begm7ytz.js} +63 -2
  64. package/dist/shared/@ai-setting/{roy-agent-core-aa2j7bk9.js → roy-agent-core-cha0jc7n.js} +40 -26
  65. package/dist/shared/@ai-setting/{roy-agent-core-p3zv1mx5.js → roy-agent-core-d1n4jbza.js} +1 -1
  66. package/dist/shared/@ai-setting/{roy-agent-core-q5r75vev.js → roy-agent-core-dkrvmjsh.js} +17 -75
  67. package/dist/shared/@ai-setting/{roy-agent-core-abqhkbn3.js → roy-agent-core-ezvpreqz.js} +23 -0
  68. package/dist/shared/@ai-setting/{roy-agent-core-99nwgj84.js → roy-agent-core-fzw9xzm1.js} +1 -1
  69. package/dist/shared/@ai-setting/roy-agent-core-h21gngxf.js +247 -0
  70. package/dist/shared/@ai-setting/roy-agent-core-m3vjepzz.js +544 -0
  71. package/dist/shared/@ai-setting/{roy-agent-core-zycadbpx.js → roy-agent-core-p6ks90tb.js} +1 -1
  72. package/dist/shared/@ai-setting/{roy-agent-core-ntq0gz7q.js → roy-agent-core-q813vafd.js} +1 -1
  73. package/dist/shared/@ai-setting/{roy-agent-core-z43aj03k.js → roy-agent-core-qk9hd89p.js} +21 -2
  74. package/dist/shared/@ai-setting/{roy-agent-core-6cy43nss.js → roy-agent-core-rykf7c04.js} +49 -9
  75. package/dist/shared/@ai-setting/{roy-agent-core-8ez6mccb.js → roy-agent-core-tk98f92b.js} +4 -0
  76. package/dist/shared/@ai-setting/{roy-agent-core-bxkjk7zx.js → roy-agent-core-vx8zc847.js} +4 -1
  77. package/dist/shared/@ai-setting/roy-agent-core-vyr6svt6.js +31 -0
  78. package/dist/shared/@ai-setting/{roy-agent-core-t3rrb959.js → roy-agent-core-xf6z96qy.js} +2086 -163
  79. package/package.json +10 -1
  80. package/dist/shared/@ai-setting/roy-agent-core-f77k3gqt.js +0 -71
  81. /package/dist/shared/@ai-setting/{roy-agent-core-b4x6x4k2.js → roy-agent-core-m1fgtnrc.js} +0 -0
  82. /package/dist/shared/@ai-setting/{roy-agent-core-v85n42ve.js → roy-agent-core-ze5cqpf2.js} +0 -0
@@ -0,0 +1,544 @@
1
+ import {
2
+ getEnvContextOrEmpty,
3
+ init_env_context
4
+ } from "./roy-agent-core-7cbpmk4q.js";
5
+
6
+ // src/env/event-source/wecom-respond-registry.ts
7
+ init_env_context();
8
+ import { z } from "zod";
9
+
10
+ // src/env/event-source/wecom-cli-sender.ts
11
+ import { spawn } from "child_process";
12
+ var WECOM_CLI_SEND_TIMEOUT_MS = 15000;
13
+ var WECOM_CLI_RESOLVE_TIMEOUT_MS = 15000;
14
+ function resolveWecomCliBinary() {
15
+ const fromEnv = process.env.WECOM_CLI_BIN;
16
+ if (typeof fromEnv === "string" && fromEnv.trim().length > 0) {
17
+ return fromEnv.trim();
18
+ }
19
+ return "wecom-cli";
20
+ }
21
+ function buildWecomCliSendArgs(input) {
22
+ return [
23
+ "message",
24
+ "aibot",
25
+ "send",
26
+ "--chat-id",
27
+ input.chatId,
28
+ "--msg-type",
29
+ "markdown",
30
+ "--markdown",
31
+ JSON.stringify({ content: input.content })
32
+ ];
33
+ }
34
+ function buildWecomCliResolveArgs(keywords) {
35
+ return ["contact", "users", "search", "--set", `keywords=${keywords}`];
36
+ }
37
+ function parseWecomCliResult(stdout) {
38
+ const text = (stdout ?? "").trim();
39
+ if (!text)
40
+ return { ok: false, error: "empty stdout" };
41
+ const start = text.indexOf("{");
42
+ const jsonText = start >= 0 ? text.slice(start) : text;
43
+ let parsed;
44
+ try {
45
+ parsed = JSON.parse(jsonText);
46
+ } catch {
47
+ return { ok: false, error: `non-JSON stdout: ${text.slice(0, 200)}` };
48
+ }
49
+ const obj = parsed;
50
+ if (obj?.error) {
51
+ const code = obj.error.code ?? "?";
52
+ const message = obj.error.message ?? obj.error.type ?? "unknown error";
53
+ return { ok: false, error: `[code=${code}] ${message}` };
54
+ }
55
+ if (obj?.success === true)
56
+ return { ok: true };
57
+ return { ok: true };
58
+ }
59
+ function parseWecomCliUserSearch(stdout, fallback) {
60
+ const text = (stdout ?? "").trim();
61
+ const start = text.indexOf("{");
62
+ if (start < 0)
63
+ return fallback;
64
+ try {
65
+ const parsed = JSON.parse(text.slice(start));
66
+ const userid = parsed?.users?.[0]?.userid;
67
+ return typeof userid === "string" && userid.length > 0 ? userid : fallback;
68
+ } catch {
69
+ return fallback;
70
+ }
71
+ }
72
+ function runCli(args, timeoutMs) {
73
+ return new Promise((resolve) => {
74
+ let settled = false;
75
+ let stdout = "";
76
+ let stderr = "";
77
+ const finish = (code) => {
78
+ if (settled)
79
+ return;
80
+ settled = true;
81
+ clearTimeout(timer);
82
+ resolve({ stdout, stderr, code });
83
+ };
84
+ let proc;
85
+ try {
86
+ proc = spawn(resolveWecomCliBinary(), args, {
87
+ shell: false,
88
+ stdio: ["ignore", "pipe", "pipe"]
89
+ });
90
+ } catch (err) {
91
+ resolve({
92
+ stdout: "",
93
+ stderr: err instanceof Error ? err.message : String(err),
94
+ code: null
95
+ });
96
+ return;
97
+ }
98
+ const timer = setTimeout(() => {
99
+ try {
100
+ proc.kill("SIGKILL");
101
+ } catch {}
102
+ finish(null);
103
+ }, timeoutMs);
104
+ timer.unref?.();
105
+ proc.stdout?.on("data", (d) => {
106
+ stdout += d.toString();
107
+ });
108
+ proc.stderr?.on("data", (d) => {
109
+ stderr += d.toString();
110
+ });
111
+ proc.on("error", (err) => {
112
+ stderr += err.message;
113
+ finish(null);
114
+ });
115
+ proc.on("close", (code) => finish(code));
116
+ });
117
+ }
118
+ var cliChatIdCache = new Map;
119
+ async function resolveWecomCliChatId(userId) {
120
+ const key = userId.trim();
121
+ if (!key)
122
+ return key;
123
+ const cached = cliChatIdCache.get(key);
124
+ if (cached)
125
+ return cached;
126
+ const { stdout } = await runCli(buildWecomCliResolveArgs(key), WECOM_CLI_RESOLVE_TIMEOUT_MS);
127
+ const resolved = parseWecomCliUserSearch(stdout, key);
128
+ if (resolved !== key)
129
+ cliChatIdCache.set(key, resolved);
130
+ return resolved;
131
+ }
132
+ async function sendWecomCliMarkdown(input) {
133
+ const content = input.content ?? "";
134
+ if (!input.chatId || content.trim().length === 0) {
135
+ return { ok: false, error: "empty chatId or content" };
136
+ }
137
+ const { stdout, stderr, code } = await runCli(buildWecomCliSendArgs({ chatId: input.chatId, content }), input.timeoutMs ?? WECOM_CLI_SEND_TIMEOUT_MS);
138
+ const parsed = parseWecomCliResult(stdout);
139
+ if (parsed.ok)
140
+ return parsed;
141
+ const detail = stderr.trim() ? `${parsed.error} | stderr: ${stderr.trim().slice(0, 200)}` : parsed.error;
142
+ return { ok: false, error: `${detail} (exit=${code ?? "null"})` };
143
+ }
144
+
145
+ // src/env/event-source/wecom-card-builder.ts
146
+ var WecomCardActionKey = {
147
+ VIEW: "task_view",
148
+ MARK_DONE: "task_mark_done",
149
+ REOPEN: "task_reopen"
150
+ };
151
+ function wecomCardTaskIdForTask(taskId) {
152
+ return `roy-task-${taskId}`;
153
+ }
154
+ var cardSeq = 0;
155
+ function newWecomCardTaskId(taskId) {
156
+ cardSeq = (cardSeq + 1) % 1e6;
157
+ const rand = Math.random().toString(36).slice(2, 8);
158
+ return `${wecomCardTaskIdForTask(taskId)}-${cardSeq}-${rand}`;
159
+ }
160
+ function formatTs(iso) {
161
+ try {
162
+ const d = new Date(iso);
163
+ if (isNaN(d.getTime()))
164
+ return iso;
165
+ const pad = (n) => String(n).padStart(2, "0");
166
+ return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ` + `${pad(d.getHours())}:${pad(d.getMinutes())}`;
167
+ } catch {
168
+ return iso;
169
+ }
170
+ }
171
+ function clip(text, max) {
172
+ if (!text)
173
+ return "";
174
+ const t = text.trim();
175
+ return t.length > max ? `${t.slice(0, max)}…` : t;
176
+ }
177
+ function shortMilestoneValue(text) {
178
+ if (!text)
179
+ return "";
180
+ const t = text.trim();
181
+ const colonIdx = t.indexOf(":");
182
+ const head = colonIdx > 0 && colonIdx <= 20 ? t.slice(0, colonIdx).trim() : t;
183
+ if (head.length <= MAX_HORIZONTAL_VALUE)
184
+ return head;
185
+ return clipWord(head, MAX_HORIZONTAL_VALUE);
186
+ }
187
+ function clipWord(text, max) {
188
+ if (!text)
189
+ return "";
190
+ const t = text.trim();
191
+ if (t.length <= max)
192
+ return t;
193
+ let cut = t.slice(0, max - 1);
194
+ const lastSpace = cut.lastIndexOf(" ");
195
+ if (lastSpace > max * 0.4)
196
+ return `${cut.slice(0, lastSpace).trimEnd()}…`;
197
+ const cjkBoundary = findCjkAsciiBoundary(cut);
198
+ if (cjkBoundary > max * 0.4)
199
+ return `${cut.slice(0, cjkBoundary).trimEnd()}…`;
200
+ return cut.slice(0, max - 1);
201
+ }
202
+ function findCjkAsciiBoundary(text) {
203
+ const isCjk = (ch) => /[一-鿿぀-ヿ가-힯]/.test(ch);
204
+ const isAsciiAlnum = (ch) => /[A-Za-z0-9]/.test(ch);
205
+ for (let i = text.length - 1;i > 0; i--) {
206
+ const prev = text[i - 1];
207
+ const cur = text[i];
208
+ if (isCjk(prev) !== isAsciiAlnum(cur) && isCjk(cur) !== isAsciiAlnum(prev)) {
209
+ if (isCjk(prev) && isAsciiAlnum(cur) || isAsciiAlnum(prev) && isCjk(cur)) {
210
+ return i;
211
+ }
212
+ }
213
+ }
214
+ return -1;
215
+ }
216
+ var MAX_TIMELINE_LINES = 8;
217
+ var MAX_HORIZONTAL_ROWS = 6;
218
+ var MAX_HORIZONTAL_VALUE = 26;
219
+ function buildWecomTextNoticeCard(input) {
220
+ const progressPct = `${Math.max(0, Math.min(100, Math.round(input.progress ?? 0)))}%`;
221
+ const sorted = [...input.milestones].slice(-MAX_TIMELINE_LINES).reverse();
222
+ const timelineRows = sorted.slice(0, MAX_HORIZONTAL_ROWS - 1).map((m) => ({
223
+ keyname: formatTs(m.timestamp).slice(11),
224
+ value: shortMilestoneValue(m.title)
225
+ }));
226
+ const horizontal = [
227
+ { keyname: "状态", value: clip(input.statusLabel, MAX_HORIZONTAL_VALUE) },
228
+ ...timelineRows
229
+ ];
230
+ const latest = sorted[0];
231
+ const quoteLine = latest ? `${formatTs(latest.timestamp)} — ${clipWord(latest.title, 80)}${latest.description ? `:${clipWord(latest.description, 80)}` : ""}` : "";
232
+ const latestSummary = latest && latest.title ? `${formatTs(latest.timestamp)} ${clip(latest.title, 140)}` : undefined;
233
+ const subTitle = input.terminal ? `任务${input.statusLabel.replace(/^[^\u4e00-\u9fa5A-Za-z]*/, "")} · 详见会话` : latestSummary;
234
+ return {
235
+ card_type: "text_notice",
236
+ main_title: {
237
+ title: `\uD83D\uDCCB Task #${input.taskId} · ${clip(input.title, 60)}`,
238
+ desc: clip(input.description, 80) || undefined
239
+ },
240
+ emphasis_content: {
241
+ title: progressPct,
242
+ desc: "进度"
243
+ },
244
+ sub_title_text: subTitle,
245
+ horizontal_content_list: horizontal,
246
+ quote_area: {
247
+ type: 0,
248
+ title: "最新进展",
249
+ quote_text: quoteLine || "(暂无操作记录)"
250
+ },
251
+ card_action: { type: 0 }
252
+ };
253
+ }
254
+ var MAX_BUTTONS = 6;
255
+ var MAX_BUTTON_TEXT = 10;
256
+ function buildWecomButtonInteractionCard(input) {
257
+ const notice = buildWecomTextNoticeCard({
258
+ taskId: input.taskId,
259
+ title: input.title,
260
+ statusLabel: input.statusLabel,
261
+ progress: input.progress,
262
+ description: input.description,
263
+ changeSummary: input.changeSummary,
264
+ milestones: input.milestones ?? []
265
+ });
266
+ const buttons = (input.buttons ?? []).slice(0, MAX_BUTTONS).map((b) => ({
267
+ text: clip(b.text, MAX_BUTTON_TEXT),
268
+ style: b.style ?? 1,
269
+ key: b.key
270
+ }));
271
+ return {
272
+ card_type: "button_interaction",
273
+ main_title: notice.main_title,
274
+ sub_title_text: notice.sub_title_text,
275
+ horizontal_content_list: notice.horizontal_content_list,
276
+ quote_area: notice.quote_area,
277
+ button_list: buttons,
278
+ card_action: { type: 0 },
279
+ task_id: input.cardTaskId ?? newWecomCardTaskId(input.taskId)
280
+ };
281
+ }
282
+ function buildWecomSendCardFrame(input) {
283
+ const reqId = input.reqId && input.reqId.trim() ? input.reqId.trim() : `aibot_send_msg_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`;
284
+ return {
285
+ cmd: "aibot_send_msg",
286
+ headers: { req_id: reqId },
287
+ body: {
288
+ chatid: input.chatId,
289
+ chat_type: input.chatType === "group" ? 2 : 1,
290
+ msgtype: "template_card",
291
+ template_card: input.card
292
+ }
293
+ };
294
+ }
295
+ var MAX_UPDATE_TITLE = 60;
296
+ function buildUpdateMainTitle(statusLabel, taskNumber, taskTitle) {
297
+ const segments = [];
298
+ if (taskNumber !== undefined && Number.isFinite(taskNumber)) {
299
+ segments.push(`Task #${taskNumber}`);
300
+ }
301
+ if (taskTitle) {
302
+ segments.push(clip(taskTitle, MAX_UPDATE_TITLE));
303
+ }
304
+ segments.push(statusLabel);
305
+ return segments.length > 1 ? `\uD83D\uDCCB ${segments.join(" · ")}` : `\uD83D\uDCCB ${statusLabel}`;
306
+ }
307
+ function buildWecomCardUpdateFrame(input) {
308
+ const reqId = (input.reqId ?? "").trim();
309
+ if (!reqId) {
310
+ throw new Error("buildWecomCardUpdateFrame: req_id is required " + "(update must reference the template_card_event frame)");
311
+ }
312
+ const buttons = (input.buttonOverrides ?? []).slice(0, MAX_BUTTONS).map((b) => ({
313
+ text: clip(b.text, MAX_BUTTON_TEXT),
314
+ style: b.style ?? 1,
315
+ key: b.key
316
+ }));
317
+ const sorted = [...input.timeline ?? []].reverse();
318
+ const timelineRows = sorted.slice(0, MAX_HORIZONTAL_ROWS).map((m) => ({
319
+ keyname: formatTs(m.timestamp).slice(11),
320
+ value: shortMilestoneValue(m.title)
321
+ }));
322
+ const total = sorted.length;
323
+ const subTitle = total > 0 ? total > MAX_HORIZONTAL_ROWS ? `共 ${total} 条操作记录,显示最近 ${MAX_HORIZONTAL_ROWS} 条(最新在顶部)` : `共 ${total} 条操作记录(最新在顶部)` : undefined;
324
+ return {
325
+ cmd: "aibot_respond_update_msg",
326
+ headers: { req_id: reqId },
327
+ body: {
328
+ response_type: "update_template_card",
329
+ template_card: {
330
+ card_type: "button_interaction",
331
+ main_title: {
332
+ title: buildUpdateMainTitle(input.statusLabel, input.taskNumber, input.taskTitle),
333
+ desc: input.note ? clip(input.note, 80) : undefined
334
+ },
335
+ sub_title_text: subTitle,
336
+ horizontal_content_list: timelineRows,
337
+ button_list: buttons,
338
+ task_id: String(input.taskId)
339
+ }
340
+ }
341
+ };
342
+ }
343
+
344
+ // src/env/event-source/wecom-respond-registry.ts
345
+ var registry = new Map;
346
+ function registerWecomRespondTarget(sourceId, target) {
347
+ registry.set(sourceId, target);
348
+ }
349
+ function unregisterWecomRespondTarget(sourceId) {
350
+ registry.delete(sourceId);
351
+ }
352
+ function getWecomRespondTarget(sourceId) {
353
+ return registry.get(sourceId);
354
+ }
355
+ function __resetWecomRespondRegistryForTest() {
356
+ registry.clear();
357
+ }
358
+ async function sendWecomReply(input) {
359
+ const content = input.content ?? "";
360
+ if (content.trim().length === 0) {
361
+ return { ok: false, error: "empty content" };
362
+ }
363
+ const errors = [];
364
+ if (input.reqId) {
365
+ const target = getWecomRespondTarget(input.sourceId);
366
+ if (target) {
367
+ const wsErr = target.respond(input.reqId, {
368
+ msgtype: "markdown",
369
+ markdown: { content }
370
+ });
371
+ if (!wsErr)
372
+ return { ok: true, channel: "ws" };
373
+ errors.push(`ws: ${wsErr.message}`);
374
+ } else {
375
+ errors.push(`ws: no instance registered for sourceId=${input.sourceId}`);
376
+ }
377
+ } else {
378
+ errors.push("ws: no req_id");
379
+ }
380
+ if (input.rawChatId) {
381
+ try {
382
+ const chatId = await resolveWecomCliChatId(input.rawChatId);
383
+ const cliResult = await sendWecomCliMarkdown({ chatId, content });
384
+ if (cliResult.ok)
385
+ return { ok: true, channel: "cli" };
386
+ errors.push(`cli: ${cliResult.error}`);
387
+ } catch (err) {
388
+ errors.push(`cli: ${err instanceof Error ? err.message : String(err)}`);
389
+ }
390
+ } else {
391
+ errors.push("cli: no chatId");
392
+ }
393
+ return { ok: false, error: errors.join(" | ") };
394
+ }
395
+ async function sendWecomTemplateCard(input) {
396
+ if (!input.chatId) {
397
+ return { ok: false, error: "no chatId" };
398
+ }
399
+ const target = getWecomRespondTarget(input.sourceId);
400
+ if (!target) {
401
+ return {
402
+ ok: false,
403
+ error: `no instance registered for sourceId=${input.sourceId}`
404
+ };
405
+ }
406
+ if (typeof target.sendCmd !== "function") {
407
+ return {
408
+ ok: false,
409
+ error: `registered instance has no sendCmd (old bridge?)`
410
+ };
411
+ }
412
+ const frame = buildWecomSendCardFrame({
413
+ chatId: input.chatId,
414
+ chatType: input.chatType,
415
+ card: input.card
416
+ });
417
+ try {
418
+ const err = target.sendCmd(frame.cmd, frame.body);
419
+ if (err)
420
+ return { ok: false, error: err.message };
421
+ return { ok: true, channel: "ws" };
422
+ } catch (err) {
423
+ return {
424
+ ok: false,
425
+ error: err instanceof Error ? err.message : String(err)
426
+ };
427
+ }
428
+ }
429
+ var wecomRespondTool = {
430
+ name: "wecom_respond",
431
+ description: "Reply to the WeCom (企业微信) user. Primary path is the official wecom-cli " + "(message aibot send, markdown); WS long-connection frame is used as fallback. " + "This is the ONLY outbound channel for WeCom messages.",
432
+ parameters: z.object({
433
+ content: z.string().describe("Reply content (markdown supported)"),
434
+ chat_id: z.string().optional().describe("Target chat id (single chat = peer userid, group = chatid). " + "Defaults to the current event's chatId/senderId."),
435
+ req_id: z.string().optional().describe("Original message frame req_id (optional; used for WS fallback only). " + "Defaults to the current event metadata.reqId.")
436
+ }),
437
+ metadata: {
438
+ category: "messaging",
439
+ tags: ["wecom", "reply", "im"],
440
+ version: "2.0.0"
441
+ },
442
+ execute: async (args, _ctx) => {
443
+ const { content } = args;
444
+ let sourceId;
445
+ let eventChatId;
446
+ let eventReqId;
447
+ try {
448
+ const ctx = getEnvContextOrEmpty();
449
+ sourceId = typeof ctx.sourceId === "string" ? ctx.sourceId : undefined;
450
+ const meta = ctx.envEvent?.metadata;
451
+ const cid = meta?.chatId;
452
+ if (typeof cid === "string" && cid.length > 0)
453
+ eventChatId = cid;
454
+ const rid = meta?.reqId;
455
+ if (typeof rid === "string" && rid.length > 0)
456
+ eventReqId = rid;
457
+ } catch {}
458
+ const chatId = args.chat_id?.trim() || eventChatId;
459
+ const reqId = args.req_id?.trim() || eventReqId;
460
+ if (!chatId) {
461
+ return {
462
+ success: false,
463
+ output: "",
464
+ error: "wecom_respond: cannot resolve chat_id (no explicit chat_id and no EnvContext event chatId)."
465
+ };
466
+ }
467
+ if (!sourceId) {
468
+ sourceId = "unknown";
469
+ }
470
+ const startedAt = Date.now();
471
+ const result = await sendWecomReply({
472
+ sourceId,
473
+ rawChatId: chatId,
474
+ reqId,
475
+ content
476
+ });
477
+ if (!result.ok) {
478
+ return {
479
+ success: false,
480
+ output: "",
481
+ error: `wecom_respond: send failed: ${result.error ?? "unknown"}`
482
+ };
483
+ }
484
+ markWecomReplySent();
485
+ return {
486
+ success: true,
487
+ output: `Reply sent to WeCom via ${result.channel} ` + `(chat_id=${chatId}, ${content.length} chars)`,
488
+ metadata: {
489
+ execution_time_ms: Date.now() - startedAt,
490
+ channel: result.channel,
491
+ chat_id: chatId
492
+ }
493
+ };
494
+ }
495
+ };
496
+ var REPLY_SENT_KEY = "__wecomReplySent";
497
+ function replySentBag(explicit) {
498
+ if (explicit)
499
+ return explicit;
500
+ try {
501
+ const ctx = getEnvContextOrEmpty();
502
+ return ctx.agentContext ??= {};
503
+ } catch {
504
+ return {};
505
+ }
506
+ }
507
+ function markWecomReplySent(explicitBag) {
508
+ replySentBag(explicitBag)[REPLY_SENT_KEY] = true;
509
+ }
510
+ function wasWecomReplySent(explicitBag) {
511
+ return replySentBag(explicitBag)[REPLY_SENT_KEY] === true;
512
+ }
513
+ function __resetWecomReplySentForTest(explicitBag) {
514
+ delete replySentBag(explicitBag)[REPLY_SENT_KEY];
515
+ }
516
+ var WECOM_EVENT_TYPE = "event-source.event.wecom-cli";
517
+ async function autoReplyWecomTurn(envEvent, finalText) {
518
+ const evt = envEvent;
519
+ if (evt?.type !== WECOM_EVENT_TYPE) {
520
+ return { skipped: true, reason: "not a wecom event" };
521
+ }
522
+ const text = (finalText ?? "").trim();
523
+ if (!text)
524
+ return { skipped: true, reason: "empty final text" };
525
+ if (wasWecomReplySent()) {
526
+ return { skipped: true, reason: "already replied via tool" };
527
+ }
528
+ const meta = evt.metadata ?? {};
529
+ const chatId = typeof meta.chatId === "string" && meta.chatId || typeof meta.senderId === "string" && meta.senderId || "";
530
+ const sourceId = typeof meta.sourceId === "string" && meta.sourceId || "unknown";
531
+ const reqId = typeof meta.reqId === "string" ? meta.reqId : undefined;
532
+ if (!chatId) {
533
+ return { skipped: true, reason: "no chatId in event metadata" };
534
+ }
535
+ const r = await sendWecomReply({
536
+ sourceId,
537
+ rawChatId: chatId,
538
+ reqId,
539
+ content: text
540
+ });
541
+ return { skipped: false, ok: r.ok, channel: r.channel, error: r.error };
542
+ }
543
+
544
+ export { WecomCardActionKey, buildWecomTextNoticeCard, buildWecomButtonInteractionCard, buildWecomCardUpdateFrame, registerWecomRespondTarget, unregisterWecomRespondTarget, getWecomRespondTarget, __resetWecomRespondRegistryForTest, sendWecomReply, sendWecomTemplateCard, wecomRespondTool, markWecomReplySent, wasWecomReplySent, __resetWecomReplySentForTest, autoReplyWecomTurn };
@@ -2,7 +2,7 @@ import {
2
2
  createAutoTaskPlugin,
3
3
  createLayaDecisionPlugin,
4
4
  registerLayaCompletionTaskHook
5
- } from "./roy-agent-core-ghnagzrh.js";
5
+ } from "./roy-agent-core-b31v3qpv.js";
6
6
  import {
7
7
  TaskHookPoints
8
8
  } from "./roy-agent-core-1pg0fepg.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  init_sqlite_task_store
3
- } from "./roy-agent-core-abqhkbn3.js";
3
+ } from "./roy-agent-core-ezvpreqz.js";
4
4
 
5
5
  // src/env/task/storage/index.ts
6
6
  init_sqlite_task_store();
@@ -9,7 +9,7 @@ import {
9
9
  import {
10
10
  BackgroundTaskManager,
11
11
  createDelegateTool
12
- } from "./roy-agent-core-aa2j7bk9.js";
12
+ } from "./roy-agent-core-cha0jc7n.js";
13
13
  import {
14
14
  TaskEntityEventTypes
15
15
  } from "./roy-agent-core-8gxth0eh.js";
@@ -37,7 +37,7 @@ import {
37
37
  import {
38
38
  SQLiteTaskStore,
39
39
  getDefaultTaskDbPath
40
- } from "./roy-agent-core-abqhkbn3.js";
40
+ } from "./roy-agent-core-ezvpreqz.js";
41
41
  import {
42
42
  TaskHookPoints
43
43
  } from "./roy-agent-core-1pg0fepg.js";
@@ -471,6 +471,15 @@ class TaskComponent extends BaseComponent {
471
471
  async getTaskIdBySessionId(sessionId) {
472
472
  return this.store.getTaskIdBySessionId(sessionId);
473
473
  }
474
+ async getTaskIdsBySessionId(sessionId) {
475
+ const store = this.store;
476
+ if (typeof store.getTaskIdsBySessionId === "function") {
477
+ const ids = await store.getTaskIdsBySessionId(sessionId);
478
+ return Array.isArray(ids) ? ids : [];
479
+ }
480
+ const first = await this.store.getTaskIdBySessionId(sessionId);
481
+ return typeof first === "number" ? [first] : [];
482
+ }
474
483
  async getTaskWithOperations(id) {
475
484
  const task = await this.store.getTask(id);
476
485
  if (!task)
@@ -676,6 +685,16 @@ class TaskComponent extends BaseComponent {
676
685
  async listOperations(options) {
677
686
  return this.store.listOperations(options);
678
687
  }
688
+ async listOperationsFresh(options) {
689
+ const store = this.store;
690
+ if (typeof store.listOperationsFresh === "function") {
691
+ return await store.listOperationsFresh(options);
692
+ }
693
+ if (typeof store.invalidateOperationsCache === "function") {
694
+ store.invalidateOperationsCache(options.taskId);
695
+ }
696
+ return await this.store.listOperations(options);
697
+ }
679
698
  getTagService() {
680
699
  return this.tagService;
681
700
  }