@ai-setting/roy-agent-core 1.5.89 → 1.5.91

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 (90) hide show
  1. package/dist/config/index.js +8 -8
  2. package/dist/env/agent/index.js +14 -14
  3. package/dist/env/commands/index.js +8 -8
  4. package/dist/env/context/index.js +4 -4
  5. package/dist/env/debug/index.js +8 -8
  6. package/dist/env/event-source/index.js +18 -14
  7. package/dist/env/hook/index.js +6 -6
  8. package/dist/env/index.js +35 -35
  9. package/dist/env/llm/index.js +12 -10
  10. package/dist/env/log-trace/index.js +8 -8
  11. package/dist/env/mcp/index.js +9 -9
  12. package/dist/env/mcp/tool/index.js +2 -2
  13. package/dist/env/memory/index.js +9 -9
  14. package/dist/env/memory/plugin/index.js +2 -2
  15. package/dist/env/plugin/index.js +8 -8
  16. package/dist/env/prompt/index.js +9 -9
  17. package/dist/env/session/index.js +11 -11
  18. package/dist/env/session/storage/index.js +4 -4
  19. package/dist/env/skill/index.js +8 -8
  20. package/dist/env/task/delegate/index.js +7 -7
  21. package/dist/env/task/index.js +12 -12
  22. package/dist/env/task/plugins/index.js +7 -7
  23. package/dist/env/task/storage/index.js +2 -2
  24. package/dist/env/task/tools/index.js +4 -4
  25. package/dist/env/tool/built-in/index.js +3 -3
  26. package/dist/env/tool/index.js +10 -10
  27. package/dist/env/workflow/engine/index.js +9 -9
  28. package/dist/env/workflow/index.js +15 -15
  29. package/dist/env/workflow/nodes/index.js +3 -3
  30. package/dist/env/workflow/service/index.js +3 -3
  31. package/dist/env/workflow/storage/index.js +4 -4
  32. package/dist/env/workflow/tools/index.js +4 -4
  33. package/dist/env/workflow/utils/index.js +3 -3
  34. package/dist/index.js +155 -50
  35. package/dist/shared/@ai-setting/{roy-agent-core-fvfc7f6v.js → roy-agent-core-0ger6zdn.js} +65 -11
  36. package/dist/shared/@ai-setting/{roy-agent-core-bwjpte58.js → roy-agent-core-0vsnecwa.js} +6 -6
  37. package/dist/shared/@ai-setting/{roy-agent-core-h5867smx.js → roy-agent-core-0ye4q2jj.js} +2 -2
  38. package/dist/shared/@ai-setting/{roy-agent-core-prdngx28.js → roy-agent-core-33rhv946.js} +43 -7
  39. package/dist/shared/@ai-setting/{roy-agent-core-djtkntar.js → roy-agent-core-4w6rgxs4.js} +1 -1
  40. package/dist/shared/@ai-setting/{roy-agent-core-fgpnv7dt.js → roy-agent-core-55br4t6v.js} +80 -37
  41. package/dist/shared/@ai-setting/{roy-agent-core-3952rkj0.js → roy-agent-core-578qk38y.js} +2 -2
  42. package/dist/shared/@ai-setting/{roy-agent-core-2q7cshpm.js → roy-agent-core-5j649pb1.js} +289 -21
  43. package/dist/shared/@ai-setting/{roy-agent-core-2h38rvyj.js → roy-agent-core-634ee5jb.js} +2 -2
  44. package/dist/shared/@ai-setting/{roy-agent-core-w6bmrgap.js → roy-agent-core-7svhckhz.js} +5 -5
  45. package/dist/shared/@ai-setting/{roy-agent-core-ce10b0ez.js → roy-agent-core-8x4ngxcy.js} +1 -1
  46. package/dist/shared/@ai-setting/{roy-agent-core-83d035pp.js → roy-agent-core-97tjdb2r.js} +70 -1
  47. package/dist/shared/@ai-setting/{roy-agent-core-qbq3jgrn.js → roy-agent-core-9amq4epa.js} +14 -14
  48. package/dist/shared/@ai-setting/{roy-agent-core-pcdzfwdv.js → roy-agent-core-9xby523m.js} +1 -1
  49. package/dist/shared/@ai-setting/{roy-agent-core-mw4ty0ba.js → roy-agent-core-at05dk0z.js} +6 -6
  50. package/dist/shared/@ai-setting/{roy-agent-core-ewr1nw7t.js → roy-agent-core-b1vkkcbr.js} +7 -7
  51. package/dist/shared/@ai-setting/{roy-agent-core-n19rm7tw.js → roy-agent-core-b2thb9xj.js} +1 -1
  52. package/dist/shared/@ai-setting/{roy-agent-core-3sv590cv.js → roy-agent-core-b77yz0wt.js} +1 -1
  53. package/dist/shared/@ai-setting/{roy-agent-core-yanpq5gb.js → roy-agent-core-bdajt9cs.js} +2 -2
  54. package/dist/shared/@ai-setting/{roy-agent-core-3czy06aq.js → roy-agent-core-bqwj1dq0.js} +3 -3
  55. package/dist/shared/@ai-setting/{roy-agent-core-k05v31rc.js → roy-agent-core-cg146hmg.js} +1 -1
  56. package/dist/shared/@ai-setting/{roy-agent-core-07290s9n.js → roy-agent-core-cx67bv9d.js} +2 -2
  57. package/dist/shared/@ai-setting/{roy-agent-core-taxvytzz.js → roy-agent-core-cx9p8b2t.js} +4 -4
  58. package/dist/shared/@ai-setting/{roy-agent-core-d6597yp0.js → roy-agent-core-ddghwfmk.js} +3 -3
  59. package/dist/shared/@ai-setting/{roy-agent-core-vneyghpg.js → roy-agent-core-ddq5hcp5.js} +1 -1
  60. package/dist/shared/@ai-setting/{roy-agent-core-qhhxx2x2.js → roy-agent-core-ds5f75pg.js} +2 -1
  61. package/dist/shared/@ai-setting/{roy-agent-core-tq9528d3.js → roy-agent-core-e7t3rj0e.js} +1 -1
  62. package/dist/shared/@ai-setting/{roy-agent-core-h2d1s8yd.js → roy-agent-core-fg5eaht3.js} +5 -5
  63. package/dist/shared/@ai-setting/{roy-agent-core-q7sqeax6.js → roy-agent-core-fx1fdzbz.js} +163 -3
  64. package/dist/shared/@ai-setting/{roy-agent-core-hc20420t.js → roy-agent-core-g2mth323.js} +28 -4
  65. package/dist/shared/@ai-setting/{roy-agent-core-7tp56w6n.js → roy-agent-core-gp872e7m.js} +2 -2
  66. package/dist/shared/@ai-setting/{roy-agent-core-c67wr8sp.js → roy-agent-core-hf8pqrvy.js} +3 -3
  67. package/dist/shared/@ai-setting/{roy-agent-core-32m0nb9j.js → roy-agent-core-j3qb695p.js} +3 -3
  68. package/dist/shared/@ai-setting/{roy-agent-core-r0m0at3x.js → roy-agent-core-j7jeqxhd.js} +121 -9
  69. package/dist/shared/@ai-setting/{roy-agent-core-h4h55x4h.js → roy-agent-core-jexyz11d.js} +2 -2
  70. package/dist/shared/@ai-setting/{roy-agent-core-hxsbegfc.js → roy-agent-core-jf865m5b.js} +5 -5
  71. package/dist/shared/@ai-setting/{roy-agent-core-b8r4tfqq.js → roy-agent-core-ksx9a556.js} +1 -1
  72. package/dist/shared/@ai-setting/{roy-agent-core-rgckng3p.js → roy-agent-core-pf1c360e.js} +2 -2
  73. package/dist/shared/@ai-setting/{roy-agent-core-xckhrs2p.js → roy-agent-core-q7ffkt1e.js} +6 -6
  74. package/dist/shared/@ai-setting/{roy-agent-core-gb9gbkc3.js → roy-agent-core-q88vxmx5.js} +1 -1
  75. package/dist/shared/@ai-setting/{roy-agent-core-y5d04fm3.js → roy-agent-core-scp0afxg.js} +2 -2
  76. package/dist/shared/@ai-setting/{roy-agent-core-3f6k060j.js → roy-agent-core-snvsn60t.js} +5 -5
  77. package/dist/shared/@ai-setting/{roy-agent-core-xnxyzaw4.js → roy-agent-core-spzb03na.js} +1 -1
  78. package/dist/shared/@ai-setting/{roy-agent-core-86d4exyf.js → roy-agent-core-sssn8kt9.js} +4 -4
  79. package/dist/shared/@ai-setting/{roy-agent-core-m3dkyprg.js → roy-agent-core-svcr4gjw.js} +14 -9
  80. package/dist/shared/@ai-setting/{roy-agent-core-nqzt9ne4.js → roy-agent-core-vady4w02.js} +2 -2
  81. package/dist/shared/@ai-setting/{roy-agent-core-shme7set.js → roy-agent-core-vyygk314.js} +2 -2
  82. package/dist/shared/@ai-setting/{roy-agent-core-5kdw0p98.js → roy-agent-core-w1s8yrm5.js} +3 -3
  83. package/dist/shared/@ai-setting/{roy-agent-core-v8xa6vs8.js → roy-agent-core-wmkx79b1.js} +14 -12
  84. package/dist/shared/@ai-setting/{roy-agent-core-t1ef8hf2.js → roy-agent-core-ws76avbn.js} +3 -3
  85. package/dist/shared/@ai-setting/{roy-agent-core-xhcgg11h.js → roy-agent-core-wtbyj0q1.js} +1 -1
  86. package/dist/shared/@ai-setting/{roy-agent-core-fjexv5nm.js → roy-agent-core-xgnpr28w.js} +2 -2
  87. package/dist/shared/@ai-setting/{roy-agent-core-c1j7ev4e.js → roy-agent-core-yfhgxh5a.js} +71 -1
  88. package/dist/shared/@ai-setting/{roy-agent-core-qg4rma4c.js → roy-agent-core-zttjq1h3.js} +1 -1
  89. package/package.json +1 -1
  90. /package/dist/shared/@ai-setting/{roy-agent-core-4f3976cd.js → roy-agent-core-k5hxvaf0.js} +0 -0
@@ -1,51 +1,51 @@
1
1
  import {
2
2
  withTimeout
3
- } from "./roy-agent-core-r0m0at3x.js";
3
+ } from "./roy-agent-core-j7jeqxhd.js";
4
4
  import {
5
5
  truncateOutputInline
6
- } from "./roy-agent-core-hxsbegfc.js";
6
+ } from "./roy-agent-core-jf865m5b.js";
7
7
  import {
8
8
  AskUserError,
9
9
  init_workflow_hil
10
10
  } from "./roy-agent-core-e25xkv53.js";
11
11
  import {
12
12
  AgentRegistry
13
- } from "./roy-agent-core-nqzt9ne4.js";
13
+ } from "./roy-agent-core-vady4w02.js";
14
14
  import {
15
15
  ContextError
16
16
  } from "./roy-agent-core-ctdhjv68.js";
17
17
  import {
18
18
  SessionMessageConverter
19
- } from "./roy-agent-core-c1j7ev4e.js";
19
+ } from "./roy-agent-core-yfhgxh5a.js";
20
20
  import {
21
21
  safeParseToolArgs
22
- } from "./roy-agent-core-ce10b0ez.js";
22
+ } from "./roy-agent-core-8x4ngxcy.js";
23
23
  import {
24
24
  envKeyToConfigKey
25
25
  } from "./roy-agent-core-qxhq8ven.js";
26
26
  import {
27
27
  BaseComponent
28
- } from "./roy-agent-core-rgckng3p.js";
28
+ } from "./roy-agent-core-pf1c360e.js";
29
29
  import {
30
30
  globalHookManager,
31
31
  init_global_hook_manager
32
- } from "./roy-agent-core-7tp56w6n.js";
32
+ } from "./roy-agent-core-gp872e7m.js";
33
33
  import {
34
34
  init_context
35
- } from "./roy-agent-core-qg4rma4c.js";
35
+ } from "./roy-agent-core-zttjq1h3.js";
36
36
  import {
37
37
  getCurrentTaskId,
38
38
  getEnvContext,
39
39
  runWithEnvContextAsync
40
- } from "./roy-agent-core-y5d04fm3.js";
40
+ } from "./roy-agent-core-scp0afxg.js";
41
41
  import {
42
42
  TracedAs,
43
43
  init_decorator
44
- } from "./roy-agent-core-k05v31rc.js";
44
+ } from "./roy-agent-core-cg146hmg.js";
45
45
  import {
46
46
  createLogger,
47
47
  init_logger
48
- } from "./roy-agent-core-shme7set.js";
48
+ } from "./roy-agent-core-vyygk314.js";
49
49
  import {
50
50
  __legacyDecorateClassTS
51
51
  } from "./roy-agent-core-fs0mn2jk.js";
@@ -115,23 +115,53 @@ function toLLMMessage(msg) {
115
115
  toolName = toolResult?.toolName;
116
116
  } else {
117
117
  const toolCallParts = msg.content.filter((part) => part.type === "tool-call");
118
- const contentParts = msg.content.filter((part) => part.type === "text").map((part) => part.text || "");
119
- content = contentParts.join(`
118
+ const hasMultimodalPart = msg.content.some((part) => part.type === "image" || part.type === "file");
119
+ if (hasMultimodalPart) {
120
+ const llmContentParts = [];
121
+ for (const part of msg.content) {
122
+ if (part.type === "text") {
123
+ llmContentParts.push({ type: "text", text: part.text || "" });
124
+ } else if (part.type === "image") {
125
+ llmContentParts.push({ type: "image", image: part.image });
126
+ } else if (part.type === "file") {
127
+ llmContentParts.push({
128
+ type: "file",
129
+ file: part.data ?? part.file,
130
+ mediaType: part.mediaType || "application/octet-stream"
131
+ });
132
+ }
133
+ }
134
+ if (msg.role === "assistant" && toolCallParts.length > 0) {
135
+ for (const part of toolCallParts) {
136
+ const argsString = typeof part.input === "string" ? part.input : JSON.stringify(part.input || {});
137
+ toolCalls = (toolCalls ?? []).concat([{
138
+ id: part.toolCallId,
139
+ name: part.toolName || "unknown",
140
+ arguments: argsString,
141
+ function: { name: part.toolName || "unknown", arguments: argsString }
142
+ }]);
143
+ }
144
+ }
145
+ content = llmContentParts;
146
+ } else {
147
+ const contentParts = msg.content.filter((part) => part.type === "text").map((part) => part.text || "");
148
+ content = contentParts.join(`
120
149
  `);
121
- if (msg.role === "assistant" && toolCallParts.length > 0) {
122
- toolCalls = toolCallParts.map((part) => {
123
- const argsString = typeof part.input === "string" ? part.input : JSON.stringify(part.input || {});
124
- const toolName2 = part.toolName || "unknown";
125
- return {
126
- id: part.toolCallId,
127
- name: toolName2,
128
- arguments: argsString,
129
- function: {
150
+ if (msg.role === "assistant" && toolCallParts.length > 0) {
151
+ toolCalls = toolCallParts.map((part) => {
152
+ const argsString = typeof part.input === "string" ? part.input : JSON.stringify(part.input || {});
153
+ const toolName2 = part.toolName || "unknown";
154
+ return {
155
+ id: part.toolCallId,
130
156
  name: toolName2,
131
- arguments: argsString
132
- }
133
- };
134
- });
157
+ arguments: argsString,
158
+ function: {
159
+ name: toolName2,
160
+ arguments: argsString
161
+ }
162
+ };
163
+ });
164
+ }
135
165
  }
136
166
  }
137
167
  } else {
@@ -550,7 +580,8 @@ class AgentComponent extends BaseComponent {
550
580
  throw new Error(`Agent not found: ${agentName}`);
551
581
  }
552
582
  const runId = `${agentName}:${++this.runCounter}`;
553
- logger.info(`Starting agent run: ${agentName} (runId=${runId})`, { query: query.substring(0, 100) });
583
+ const querySummary = typeof query === "string" ? query.substring(0, 100) : query.filter((p) => p.type === "text").map((p) => p.text).join(" ").substring(0, 100) || "[multimodal query]";
584
+ logger.info(`Starting agent run: ${agentName} (runId=${runId})`, { query: querySummary });
554
585
  agent.status = "running";
555
586
  this.aborted.set(runId, false);
556
587
  const abortController = new AbortController;
@@ -559,24 +590,25 @@ class AgentComponent extends BaseComponent {
559
590
  this.doomLoopCaches.set(runId, new Map);
560
591
  }
561
592
  await this.resolveSystemPrompt(agent, agentName);
593
+ let resolvedSystemPrompt;
562
594
  if (agent.config.systemPrompt) {
563
- const sp = agent.config.systemPrompt;
564
- if (sp.includes("{{workspace_dir}}")) {
595
+ resolvedSystemPrompt = agent.config.systemPrompt;
596
+ if (resolvedSystemPrompt.includes("{{workspace_dir}}")) {
565
597
  const workspaceDir = this.env?.getComponent?.("config")?.get?.("workspace_dir") || process.cwd();
566
- agent.config.systemPrompt = agent.config.systemPrompt.replaceAll("{{workspace_dir}}", String(workspaceDir));
598
+ resolvedSystemPrompt = resolvedSystemPrompt.replaceAll("{{workspace_dir}}", String(workspaceDir));
567
599
  }
568
- if (sp.includes("{{memory}}")) {
600
+ if (resolvedSystemPrompt.includes("{{memory}}")) {
569
601
  try {
570
602
  const memoryComponent = this.env?.getComponent?.("memory");
571
603
  if (memoryComponent && typeof memoryComponent.recallMemory === "function") {
572
604
  const memoryContent = await memoryComponent.recallMemory();
573
- agent.config.systemPrompt = agent.config.systemPrompt.replace("{{memory}}", memoryContent || "(No memory)");
605
+ resolvedSystemPrompt = resolvedSystemPrompt.replaceAll("{{memory}}", memoryContent || "(No memory)");
574
606
  } else {
575
- agent.config.systemPrompt = agent.config.systemPrompt.replace("{{memory}}", "(Memory component not available)");
607
+ resolvedSystemPrompt = resolvedSystemPrompt.replaceAll("{{memory}}", "(Memory component not available)");
576
608
  }
577
609
  } catch (err) {
578
610
  logger.warn(`[AgentComponent._run] Failed to replace {{memory}}: ${err}`);
579
- agent.config.systemPrompt = agent.config.systemPrompt.replace("{{memory}}", "(Failed to load memory)");
611
+ resolvedSystemPrompt = resolvedSystemPrompt.replaceAll("{{memory}}", "(Failed to load memory)");
580
612
  }
581
613
  }
582
614
  }
@@ -597,7 +629,7 @@ class AgentComponent extends BaseComponent {
597
629
  maxIterations: agent.config.maxIterations,
598
630
  messages: [],
599
631
  tools: this.getAvailableTools(agent, effectiveContext),
600
- systemPrompt: agent.config.systemPrompt || "You are a helpful assistant.",
632
+ systemPrompt: resolvedSystemPrompt ?? agent.config.systemPrompt ?? "You are a helpful assistant.",
601
633
  context: effectiveContext
602
634
  };
603
635
  let historyMessageCount = 0;
@@ -969,6 +1001,7 @@ class AgentComponent extends BaseComponent {
969
1001
  }
970
1002
  this.aborted.delete(runId);
971
1003
  this.abortControllers.delete(runId);
1004
+ this.doomLoopCaches.delete(runId);
972
1005
  if (result.error) {
973
1006
  this.pushEnvEvent({
974
1007
  type: "agent.error",
@@ -1292,6 +1325,7 @@ ${additionInfo}`
1292
1325
  logger.warn("SessionComponent not found, skipping session recording");
1293
1326
  return;
1294
1327
  }
1328
+ const filtered2 = [];
1295
1329
  for (const msg of allMessages) {
1296
1330
  if (msg.role === "system") {
1297
1331
  continue;
@@ -1304,10 +1338,19 @@ ${additionInfo}`
1304
1338
  continue;
1305
1339
  }
1306
1340
  }
1307
- await sessionComponent.addMessage(sessionId, this.messageConverter.fromModelMessage(msg, { sessionID: sessionId }));
1341
+ filtered2.push(this.messageConverter.fromModelMessage(msg, { sessionID: sessionId }));
1308
1342
  }
1343
+ if (filtered2.length === 0) {
1344
+ return;
1345
+ }
1346
+ await sessionComponent.addMessages(sessionId, filtered2);
1309
1347
  } catch (err) {
1310
- logger.warn(`Failed to record session messages: ${err}`);
1348
+ const kind = err && typeof err === "object" && "kind" in err ? err.kind : undefined;
1349
+ if (kind === "lock_exhausted") {
1350
+ logger.error(`[recordSessionMessages] DROPPED ${filtered?.length ?? "?"} message(s) — SQLITE_BUSY retry exhausted after ${err.attempts ?? "?"} attempts. Session ${sessionId} is now inconsistent with LLM context. Original: ${err}`);
1351
+ } else {
1352
+ logger.error(`[recordSessionMessages] Failed to record session messages for ${sessionId}: ${err}`);
1353
+ }
1311
1354
  }
1312
1355
  }
1313
1356
  isEmptyMessage(content) {
@@ -4,11 +4,11 @@ import {
4
4
  } from "./roy-agent-core-qxhq8ven.js";
5
5
  import {
6
6
  BaseComponent
7
- } from "./roy-agent-core-rgckng3p.js";
7
+ } from "./roy-agent-core-pf1c360e.js";
8
8
  import {
9
9
  createLogger,
10
10
  init_logger
11
- } from "./roy-agent-core-shme7set.js";
11
+ } from "./roy-agent-core-vyygk314.js";
12
12
 
13
13
  // src/env/commands/commands-component.ts
14
14
  import path2 from "path";
@@ -1,32 +1,32 @@
1
1
  import {
2
2
  TaskTagPlugin,
3
3
  createLarkCliTaskNotifyHook
4
- } from "./roy-agent-core-m3dkyprg.js";
4
+ } from "./roy-agent-core-svcr4gjw.js";
5
5
  import {
6
6
  envKeyToConfigKey
7
7
  } from "./roy-agent-core-qxhq8ven.js";
8
8
  import {
9
9
  BaseComponent
10
- } from "./roy-agent-core-rgckng3p.js";
10
+ } from "./roy-agent-core-pf1c360e.js";
11
11
  import {
12
12
  globalHookManager,
13
13
  init_global_hook_manager
14
- } from "./roy-agent-core-7tp56w6n.js";
14
+ } from "./roy-agent-core-gp872e7m.js";
15
15
  import {
16
16
  init_context
17
- } from "./roy-agent-core-qg4rma4c.js";
17
+ } from "./roy-agent-core-zttjq1h3.js";
18
18
  import {
19
19
  createEnvContext,
20
20
  runWithEnvContext
21
- } from "./roy-agent-core-y5d04fm3.js";
21
+ } from "./roy-agent-core-scp0afxg.js";
22
22
  import {
23
23
  TracedAs,
24
24
  init_decorator
25
- } from "./roy-agent-core-k05v31rc.js";
25
+ } from "./roy-agent-core-cg146hmg.js";
26
26
  import {
27
27
  createLogger,
28
28
  init_logger
29
- } from "./roy-agent-core-shme7set.js";
29
+ } from "./roy-agent-core-vyygk314.js";
30
30
  import {
31
31
  getTracerProvider
32
32
  } from "./roy-agent-core-7z9b1fm8.js";
@@ -192,6 +192,249 @@ var timerHandler = {
192
192
  }
193
193
  };
194
194
 
195
+ // src/env/event-source/bounty-im-handler.ts
196
+ function readBountyIMConfig(config) {
197
+ const topLevelAddress = config.address;
198
+ const topLevelUrl = config.imServerUrl;
199
+ const optionsAddress = config.options?.address;
200
+ const optionsUrl = config.options?.imServerUrl;
201
+ return {
202
+ address: topLevelAddress || optionsAddress,
203
+ imServerUrl: topLevelUrl || optionsUrl
204
+ };
205
+ }
206
+ function readBountyIMTlsSkipVerify(config) {
207
+ const topLevel = config.tlsSkipVerify;
208
+ const fromOptions = config.options?.tlsSkipVerify;
209
+ const raw = topLevel !== undefined ? topLevel : fromOptions;
210
+ return raw === true;
211
+ }
212
+ function shouldWriteBunTlsSkipEnv(tlsSkipVerify, isBunRuntimeOverride) {
213
+ const isBun = isBunRuntimeOverride ?? typeof Bun !== "undefined";
214
+ return tlsSkipVerify === true && isBun;
215
+ }
216
+
217
+ class BountyIMInstance {
218
+ config;
219
+ status = "created";
220
+ ws = null;
221
+ buffer = "";
222
+ eventHandler;
223
+ constructor(config) {
224
+ this.config = config;
225
+ }
226
+ getCurrentAddress() {
227
+ const { address } = readBountyIMConfig(this.config);
228
+ return address || "unknown";
229
+ }
230
+ getStatus() {
231
+ return this.status;
232
+ }
233
+ async start() {
234
+ if (this.status === "running")
235
+ return;
236
+ this.setStatus("starting");
237
+ const { address, imServerUrl } = readBountyIMConfig(this.config);
238
+ if (!imServerUrl) {
239
+ throw new Error("imServerUrl is required for bounty-im event source");
240
+ }
241
+ const wsUrl = new URL(imServerUrl);
242
+ if (address) {
243
+ wsUrl.searchParams.set("address", address);
244
+ }
245
+ console.log(`[BountyIM] Connecting to ${wsUrl.toString()}...`);
246
+ try {
247
+ const { WebSocket } = await import("ws");
248
+ const tlsSkipVerify = readBountyIMTlsSkipVerify(this.config);
249
+ const isWss = imServerUrl.startsWith("wss://");
250
+ if (isWss && shouldWriteBunTlsSkipEnv(tlsSkipVerify)) {
251
+ process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
252
+ }
253
+ this.ws = new WebSocket(wsUrl.toString(), {
254
+ headers: this.config.headers,
255
+ rejectUnauthorized: !tlsSkipVerify
256
+ });
257
+ this.ws.on("open", () => {
258
+ console.log(`[BountyIM] Connected${address ? ` as ${address}` : ""}`);
259
+ this.setStatus("running");
260
+ });
261
+ this.ws.on("message", (data) => {
262
+ this.handleMessage(data.toString());
263
+ });
264
+ this.ws.on("error", (error) => {
265
+ console.error(`[BountyIM] Error:`, error.message);
266
+ this.setStatus("error");
267
+ });
268
+ this.ws.on("close", () => {
269
+ console.log(`[BountyIM] Connection closed`);
270
+ this.setStatus("stopped");
271
+ });
272
+ } catch (error) {
273
+ this.setStatus("error");
274
+ throw new Error(`Failed to connect to Bounty IM server: ${error}`);
275
+ }
276
+ }
277
+ async stop() {
278
+ if (this.status === "stopped" || this.status === "created")
279
+ return;
280
+ this.setStatus("stopping");
281
+ if (this.ws) {
282
+ this.ws.close();
283
+ this.ws = null;
284
+ }
285
+ this.setStatus("stopped");
286
+ }
287
+ onEvent(handler) {
288
+ this.eventHandler = handler;
289
+ }
290
+ offEvent() {
291
+ this.eventHandler = undefined;
292
+ }
293
+ setStatus(status) {
294
+ this.status = status;
295
+ }
296
+ handleMessage(data) {
297
+ this.buffer += data;
298
+ try {
299
+ JSON.parse(this.buffer);
300
+ this.processLine(this.buffer);
301
+ this.buffer = "";
302
+ } catch {}
303
+ }
304
+ processLine(rawData) {
305
+ try {
306
+ let rawEvent;
307
+ try {
308
+ rawEvent = JSON.parse(rawData);
309
+ } catch {
310
+ rawEvent = {
311
+ event: "message",
312
+ data: { content: { type: "text", body: rawData } }
313
+ };
314
+ }
315
+ const evt = rawEvent;
316
+ const msg = evt.data || {};
317
+ if (evt.event !== "message") {
318
+ return;
319
+ }
320
+ const eventType = `bounty-im.${evt.event || "message"}`;
321
+ const fromAddress = msg.from || "unknown";
322
+ const currentAddress = this.getCurrentAddress();
323
+ const toAddress = msg.to || currentAddress;
324
+ if (msg.to && msg.to !== currentAddress) {
325
+ console.warn(`[BountyIM] Warning: message.to (${msg.to}) !== current address (${currentAddress})`);
326
+ }
327
+ const msgContent = msg.content;
328
+ const content = msgContent?.type === "text" ? String(msgContent.body || "") : "";
329
+ const { imServerUrl } = readBountyIMConfig(this.config);
330
+ const agent = this.config.handleRule?.agent;
331
+ const metadata = {
332
+ eventType,
333
+ senderId: fromAddress,
334
+ chatId: toAddress,
335
+ agent
336
+ };
337
+ let recommendedAction;
338
+ if (evt.event === "message") {
339
+ recommendedAction = {
340
+ action: `处理消息并通过 bounty com send 回复发件人。使用格式:bounty com send -f ${toAddress} -t ${fromAddress} -b "回复内容"`,
341
+ replyTo: {
342
+ chatId: fromAddress
343
+ }
344
+ };
345
+ }
346
+ const replyChannel = {
347
+ type: "bounty-im",
348
+ chatId: fromAddress,
349
+ params: {
350
+ from: toAddress,
351
+ to: fromAddress,
352
+ imServerUrl
353
+ }
354
+ };
355
+ const displayMessage = content ? `[From ${fromAddress}] ${content}
356
+
357
+ \uD83D\uDCA1 回复: bounty com send -f ${toAddress} -t ${fromAddress} -b "回复内容"` : this.formatMessage(rawEvent);
358
+ const event = {
359
+ id: `es-${this.config.id}-${Date.now()}`,
360
+ type: eventType,
361
+ timestamp: Date.now(),
362
+ metadata: {
363
+ source: "event-source",
364
+ sourceId: this.config.id,
365
+ agent
366
+ },
367
+ payload: {
368
+ sourceId: this.config.id,
369
+ sourceType: "bounty-im",
370
+ rawEvent,
371
+ message: displayMessage,
372
+ metadata,
373
+ recommendedAction,
374
+ replyChannel,
375
+ timestamp: Date.now()
376
+ }
377
+ };
378
+ this.eventHandler?.(event);
379
+ if (msg.id && this.ws) {
380
+ try {
381
+ const ackPayload = JSON.stringify({
382
+ event: "ack",
383
+ data: { messageIds: [msg.id] }
384
+ });
385
+ this.ws.send(ackPayload);
386
+ console.log(`[BountyIM] 已发送 ACK for message: ${msg.id}`);
387
+ } catch (ackErr) {
388
+ console.error(`[BountyIM] 发送 ACK 失败:`, ackErr);
389
+ }
390
+ }
391
+ } catch (err) {
392
+ console.error(`[BountyIM] Error processing message:`, err);
393
+ }
394
+ }
395
+ formatMessage(rawEvent) {
396
+ const evt = rawEvent;
397
+ if (evt.event === "connected") {
398
+ return `✅ 已连接到 bounty IM 服务器`;
399
+ }
400
+ if (evt.event === "message") {
401
+ const msg = evt.data || {};
402
+ const from = msg.from || "unknown";
403
+ let content = "未知内容";
404
+ if (msg.content?.type === "text") {
405
+ content = String(msg.content?.body || "");
406
+ }
407
+ return `[${from}] ${content}`;
408
+ }
409
+ return `事件: ${evt.event || "unknown"}`;
410
+ }
411
+ }
412
+ var bountyIMHandler = {
413
+ type: "bounty-im",
414
+ validateConfig(config) {
415
+ const errors = [];
416
+ if (!config.id)
417
+ errors.push("EventSource ID is required");
418
+ if (!config.name)
419
+ errors.push("EventSource name is required");
420
+ const { address, imServerUrl } = readBountyIMConfig(config);
421
+ if (!address) {
422
+ errors.push("Bounty IM address is required (top-level address or options.address)");
423
+ } else if (!/^[\w-]+@[\w.-]+$/.test(address)) {
424
+ errors.push("Bounty IM address format invalid (expected: agent-id@host)");
425
+ }
426
+ if (!imServerUrl) {
427
+ errors.push("Bounty IM imServerUrl is required (top-level imServerUrl or options.imServerUrl)");
428
+ } else if (!imServerUrl.startsWith("ws://") && !imServerUrl.startsWith("wss://")) {
429
+ errors.push("Bounty IM imServerUrl must start with ws:// or wss://");
430
+ }
431
+ return errors;
432
+ },
433
+ createInstance(config) {
434
+ return new BountyIMInstance(config);
435
+ }
436
+ };
437
+
195
438
  // src/env/event-source/event-source-handlers.ts
196
439
  init_global_hook_manager();
197
440
  import { spawn } from "child_process";
@@ -259,18 +502,24 @@ function extractMetadata(rawEvent, eventType) {
259
502
  }
260
503
  let recommendedAction;
261
504
  if (eventType === "im.message.receive_v1" || event.type === "im.message.receive_v1") {
505
+ const profile2 = event.profile;
506
+ const profileFlag = profile2 ? `--profile ${profile2} ` : "";
507
+ const profileHint = profile2 ? `(⚠️ 必须使用 profile="${profile2}" 调用 lark-cli,否则会因 openId 跨 app 失败)` : "";
262
508
  recommendedAction = {
263
- action: '处理飞书消息并以机器人身份回复,比如lark-cli im +messages-reply --message-id "xxxxid" --as bot --text "回复内容"',
509
+ action: `处理飞书消息并以机器人身份回复${profileHint},例如:lark-cli ${profileFlag}im +messages-reply --message-id "xxxxid" --as bot --text "回复内容"`,
264
510
  replyTo: {
265
511
  appId: metadata.appId,
512
+ profile: profile2,
266
513
  chatId: metadata.chatId,
267
514
  messageId: metadata.messageId
268
515
  }
269
516
  };
270
517
  }
518
+ const profile = event.profile;
271
519
  const replyChannel = {
272
520
  type: "lark-cli",
273
521
  appId: metadata.appId,
522
+ profile,
274
523
  chatId: messageData?.chat_id,
275
524
  messageId: messageData?.message_id
276
525
  };
@@ -291,7 +540,14 @@ class LarkCliInstance {
291
540
  if (this.status === "running")
292
541
  return;
293
542
  await this.loadPlugins();
294
- const command = this.config.command || "lark-cli event consume im.message.receive_v1 --as bot";
543
+ const profile = this.config.profile;
544
+ const profileFlag = profile ? `--profile ${profile} ` : "";
545
+ let command;
546
+ if (this.config.command) {
547
+ command = this.config.command.replace(/^(lark-cli)(\s+|$)/, (_, head, tail) => `${head} ${profileFlag.trim()}${tail}`);
548
+ } else {
549
+ command = `lark-cli ${profileFlag}event consume im.message.receive_v1 --as bot`;
550
+ }
295
551
  this.child = spawn("exec " + command, [], {
296
552
  shell: true,
297
553
  stdio: ["pipe", "pipe", "pipe"],
@@ -530,7 +786,12 @@ class LarkCliInstance {
530
786
  if (this.config.eventTypes?.length && !matchEventType(eventType, this.config.eventTypes)) {
531
787
  return;
532
788
  }
533
- const { metadata, replyChannel, recommendedAction } = extractMetadata(rawEvent, eventType);
789
+ const enrichedEvent = {
790
+ ...rawEvent,
791
+ profile: this.config.profile,
792
+ eventSourceId: this.config.id
793
+ };
794
+ const { metadata, replyChannel, recommendedAction } = extractMetadata(enrichedEvent, eventType);
534
795
  const message = JSON.stringify({
535
796
  rawData,
536
797
  recommendedAction
@@ -598,18 +859,21 @@ class LarkCliInstance {
598
859
  if (!replyChannel || !replyChannel.chatId && !replyChannel.messageId) {
599
860
  return;
600
861
  }
862
+ const profile = replyChannel.profile;
601
863
  return {
602
864
  type: replyChannel.type,
603
865
  messageId: replyChannel.messageId,
604
866
  chatId: replyChannel.chatId,
605
867
  userId: replyChannel.params?.userId,
868
+ profile,
606
869
  identity: "bot",
607
870
  sendText: async (text) => {
608
871
  await this.sendLarkMessage({
609
872
  chatId: replyChannel.chatId,
610
873
  userId: replyChannel.params?.userId,
611
874
  content: text,
612
- as: "bot"
875
+ as: "bot",
876
+ profile
613
877
  });
614
878
  },
615
879
  sendMarkdown: async (markdown) => {
@@ -618,7 +882,8 @@ class LarkCliInstance {
618
882
  userId: replyChannel.params?.userId,
619
883
  content: markdown,
620
884
  as: "bot",
621
- format: "markdown"
885
+ format: "markdown",
886
+ profile
622
887
  });
623
888
  },
624
889
  sendMessage: async (content) => {
@@ -626,7 +891,8 @@ class LarkCliInstance {
626
891
  chatId: replyChannel.chatId,
627
892
  userId: replyChannel.params?.userId,
628
893
  content: JSON.stringify(content),
629
- as: "bot"
894
+ as: "bot",
895
+ profile
630
896
  });
631
897
  },
632
898
  reply: async (content) => {
@@ -634,7 +900,8 @@ class LarkCliInstance {
634
900
  await this.sendLarkMessage({
635
901
  messageId: replyChannel.messageId,
636
902
  content: JSON.stringify(content),
637
- as: "bot"
903
+ as: "bot",
904
+ profile
638
905
  });
639
906
  }
640
907
  }
@@ -642,7 +909,7 @@ class LarkCliInstance {
642
909
  }
643
910
  async sendLarkMessage(options) {
644
911
  return new Promise((resolve, reject) => {
645
- const { chatId, userId, messageId, content, as: identity, format = "text" } = options;
912
+ const { chatId, userId, messageId, content, as: identity, format = "text", profile } = options;
646
913
  const contentFlag = format === "markdown" ? "--markdown" : "--text";
647
914
  const args = ["im", "+messages-send", "--as", identity];
648
915
  if (messageId) {
@@ -655,6 +922,9 @@ class LarkCliInstance {
655
922
  reject(new Error("No target specified for sending message"));
656
923
  return;
657
924
  }
925
+ if (profile) {
926
+ args.unshift("--profile", profile);
927
+ }
658
928
  const proc = spawn("lark-cli", args, {
659
929
  shell: false,
660
930
  stdio: ["pipe", "pipe", "pipe"]
@@ -691,9 +961,6 @@ var larkCliHandler = {
691
961
  type: "lark-cli",
692
962
  validateConfig(config) {
693
963
  const errors = [];
694
- if (!config.command) {
695
- errors.push("command is optional, will use default: lark-cli event consume im.message.receive_v1 --as bot");
696
- }
697
964
  return errors;
698
965
  },
699
966
  createInstance(config) {
@@ -702,7 +969,8 @@ var larkCliHandler = {
702
969
  };
703
970
  var builtInHandlers = [
704
971
  larkCliHandler,
705
- timerHandler
972
+ timerHandler,
973
+ bountyIMHandler
706
974
  ];
707
975
  function getBuiltInHandler(type) {
708
976
  return builtInHandlers.find((h) => h.type === type);
@@ -804,7 +1072,7 @@ class EventSourceComponent extends BaseComponent {
804
1072
  }
805
1073
  }
806
1074
  async executeInitHooks() {
807
- const { EventSourceInitHooks } = await import("./roy-agent-core-vneyghpg.js");
1075
+ const { EventSourceInitHooks } = await import("./roy-agent-core-ddq5hcp5.js");
808
1076
  await EventSourceInitHooks.execute(this);
809
1077
  }
810
1078
  registerHandler(handler) {
@@ -1146,4 +1414,4 @@ __legacyDecorateClassTS([
1146
1414
  TracedAs("event-source.update", { recordParams: false, log: false })
1147
1415
  ], EventSourceComponent.prototype, "update", null);
1148
1416
 
1149
- export { TimerInstance, timerHandler, larkCliHandler, builtInHandlers, getBuiltInHandler, EventSourceComponent };
1417
+ export { TimerInstance, timerHandler, BountyIMInstance, bountyIMHandler, larkCliHandler, builtInHandlers, getBuiltInHandler, EventSourceComponent };