@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.
- package/dist/config/index.js +8 -8
- package/dist/env/agent/index.js +14 -14
- package/dist/env/commands/index.js +8 -8
- package/dist/env/context/index.js +4 -4
- package/dist/env/debug/index.js +8 -8
- package/dist/env/event-source/index.js +18 -14
- package/dist/env/hook/index.js +6 -6
- package/dist/env/index.js +35 -35
- package/dist/env/llm/index.js +12 -10
- package/dist/env/log-trace/index.js +8 -8
- package/dist/env/mcp/index.js +9 -9
- package/dist/env/mcp/tool/index.js +2 -2
- package/dist/env/memory/index.js +9 -9
- package/dist/env/memory/plugin/index.js +2 -2
- package/dist/env/plugin/index.js +8 -8
- package/dist/env/prompt/index.js +9 -9
- package/dist/env/session/index.js +11 -11
- package/dist/env/session/storage/index.js +4 -4
- package/dist/env/skill/index.js +8 -8
- package/dist/env/task/delegate/index.js +7 -7
- package/dist/env/task/index.js +12 -12
- package/dist/env/task/plugins/index.js +7 -7
- package/dist/env/task/storage/index.js +2 -2
- package/dist/env/task/tools/index.js +4 -4
- package/dist/env/tool/built-in/index.js +3 -3
- package/dist/env/tool/index.js +10 -10
- package/dist/env/workflow/engine/index.js +9 -9
- package/dist/env/workflow/index.js +15 -15
- package/dist/env/workflow/nodes/index.js +3 -3
- package/dist/env/workflow/service/index.js +3 -3
- package/dist/env/workflow/storage/index.js +4 -4
- package/dist/env/workflow/tools/index.js +4 -4
- package/dist/env/workflow/utils/index.js +3 -3
- package/dist/index.js +155 -50
- package/dist/shared/@ai-setting/{roy-agent-core-fvfc7f6v.js → roy-agent-core-0ger6zdn.js} +65 -11
- package/dist/shared/@ai-setting/{roy-agent-core-bwjpte58.js → roy-agent-core-0vsnecwa.js} +6 -6
- package/dist/shared/@ai-setting/{roy-agent-core-h5867smx.js → roy-agent-core-0ye4q2jj.js} +2 -2
- package/dist/shared/@ai-setting/{roy-agent-core-prdngx28.js → roy-agent-core-33rhv946.js} +43 -7
- package/dist/shared/@ai-setting/{roy-agent-core-djtkntar.js → roy-agent-core-4w6rgxs4.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-fgpnv7dt.js → roy-agent-core-55br4t6v.js} +80 -37
- package/dist/shared/@ai-setting/{roy-agent-core-3952rkj0.js → roy-agent-core-578qk38y.js} +2 -2
- package/dist/shared/@ai-setting/{roy-agent-core-2q7cshpm.js → roy-agent-core-5j649pb1.js} +289 -21
- package/dist/shared/@ai-setting/{roy-agent-core-2h38rvyj.js → roy-agent-core-634ee5jb.js} +2 -2
- package/dist/shared/@ai-setting/{roy-agent-core-w6bmrgap.js → roy-agent-core-7svhckhz.js} +5 -5
- package/dist/shared/@ai-setting/{roy-agent-core-ce10b0ez.js → roy-agent-core-8x4ngxcy.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-83d035pp.js → roy-agent-core-97tjdb2r.js} +70 -1
- package/dist/shared/@ai-setting/{roy-agent-core-qbq3jgrn.js → roy-agent-core-9amq4epa.js} +14 -14
- package/dist/shared/@ai-setting/{roy-agent-core-pcdzfwdv.js → roy-agent-core-9xby523m.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-mw4ty0ba.js → roy-agent-core-at05dk0z.js} +6 -6
- package/dist/shared/@ai-setting/{roy-agent-core-ewr1nw7t.js → roy-agent-core-b1vkkcbr.js} +7 -7
- package/dist/shared/@ai-setting/{roy-agent-core-n19rm7tw.js → roy-agent-core-b2thb9xj.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-3sv590cv.js → roy-agent-core-b77yz0wt.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-yanpq5gb.js → roy-agent-core-bdajt9cs.js} +2 -2
- package/dist/shared/@ai-setting/{roy-agent-core-3czy06aq.js → roy-agent-core-bqwj1dq0.js} +3 -3
- package/dist/shared/@ai-setting/{roy-agent-core-k05v31rc.js → roy-agent-core-cg146hmg.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-07290s9n.js → roy-agent-core-cx67bv9d.js} +2 -2
- package/dist/shared/@ai-setting/{roy-agent-core-taxvytzz.js → roy-agent-core-cx9p8b2t.js} +4 -4
- package/dist/shared/@ai-setting/{roy-agent-core-d6597yp0.js → roy-agent-core-ddghwfmk.js} +3 -3
- package/dist/shared/@ai-setting/{roy-agent-core-vneyghpg.js → roy-agent-core-ddq5hcp5.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-qhhxx2x2.js → roy-agent-core-ds5f75pg.js} +2 -1
- package/dist/shared/@ai-setting/{roy-agent-core-tq9528d3.js → roy-agent-core-e7t3rj0e.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-h2d1s8yd.js → roy-agent-core-fg5eaht3.js} +5 -5
- package/dist/shared/@ai-setting/{roy-agent-core-q7sqeax6.js → roy-agent-core-fx1fdzbz.js} +163 -3
- package/dist/shared/@ai-setting/{roy-agent-core-hc20420t.js → roy-agent-core-g2mth323.js} +28 -4
- package/dist/shared/@ai-setting/{roy-agent-core-7tp56w6n.js → roy-agent-core-gp872e7m.js} +2 -2
- package/dist/shared/@ai-setting/{roy-agent-core-c67wr8sp.js → roy-agent-core-hf8pqrvy.js} +3 -3
- package/dist/shared/@ai-setting/{roy-agent-core-32m0nb9j.js → roy-agent-core-j3qb695p.js} +3 -3
- package/dist/shared/@ai-setting/{roy-agent-core-r0m0at3x.js → roy-agent-core-j7jeqxhd.js} +121 -9
- package/dist/shared/@ai-setting/{roy-agent-core-h4h55x4h.js → roy-agent-core-jexyz11d.js} +2 -2
- package/dist/shared/@ai-setting/{roy-agent-core-hxsbegfc.js → roy-agent-core-jf865m5b.js} +5 -5
- package/dist/shared/@ai-setting/{roy-agent-core-b8r4tfqq.js → roy-agent-core-ksx9a556.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-rgckng3p.js → roy-agent-core-pf1c360e.js} +2 -2
- package/dist/shared/@ai-setting/{roy-agent-core-xckhrs2p.js → roy-agent-core-q7ffkt1e.js} +6 -6
- package/dist/shared/@ai-setting/{roy-agent-core-gb9gbkc3.js → roy-agent-core-q88vxmx5.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-y5d04fm3.js → roy-agent-core-scp0afxg.js} +2 -2
- package/dist/shared/@ai-setting/{roy-agent-core-3f6k060j.js → roy-agent-core-snvsn60t.js} +5 -5
- package/dist/shared/@ai-setting/{roy-agent-core-xnxyzaw4.js → roy-agent-core-spzb03na.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-86d4exyf.js → roy-agent-core-sssn8kt9.js} +4 -4
- package/dist/shared/@ai-setting/{roy-agent-core-m3dkyprg.js → roy-agent-core-svcr4gjw.js} +14 -9
- package/dist/shared/@ai-setting/{roy-agent-core-nqzt9ne4.js → roy-agent-core-vady4w02.js} +2 -2
- package/dist/shared/@ai-setting/{roy-agent-core-shme7set.js → roy-agent-core-vyygk314.js} +2 -2
- package/dist/shared/@ai-setting/{roy-agent-core-5kdw0p98.js → roy-agent-core-w1s8yrm5.js} +3 -3
- package/dist/shared/@ai-setting/{roy-agent-core-v8xa6vs8.js → roy-agent-core-wmkx79b1.js} +14 -12
- package/dist/shared/@ai-setting/{roy-agent-core-t1ef8hf2.js → roy-agent-core-ws76avbn.js} +3 -3
- package/dist/shared/@ai-setting/{roy-agent-core-xhcgg11h.js → roy-agent-core-wtbyj0q1.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-fjexv5nm.js → roy-agent-core-xgnpr28w.js} +2 -2
- package/dist/shared/@ai-setting/{roy-agent-core-c1j7ev4e.js → roy-agent-core-yfhgxh5a.js} +71 -1
- package/dist/shared/@ai-setting/{roy-agent-core-qg4rma4c.js → roy-agent-core-zttjq1h3.js} +1 -1
- package/package.json +1 -1
- /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-
|
|
3
|
+
} from "./roy-agent-core-j7jeqxhd.js";
|
|
4
4
|
import {
|
|
5
5
|
truncateOutputInline
|
|
6
|
-
} from "./roy-agent-core-
|
|
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-
|
|
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-
|
|
19
|
+
} from "./roy-agent-core-yfhgxh5a.js";
|
|
20
20
|
import {
|
|
21
21
|
safeParseToolArgs
|
|
22
|
-
} from "./roy-agent-core-
|
|
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-
|
|
28
|
+
} from "./roy-agent-core-pf1c360e.js";
|
|
29
29
|
import {
|
|
30
30
|
globalHookManager,
|
|
31
31
|
init_global_hook_manager
|
|
32
|
-
} from "./roy-agent-core-
|
|
32
|
+
} from "./roy-agent-core-gp872e7m.js";
|
|
33
33
|
import {
|
|
34
34
|
init_context
|
|
35
|
-
} from "./roy-agent-core-
|
|
35
|
+
} from "./roy-agent-core-zttjq1h3.js";
|
|
36
36
|
import {
|
|
37
37
|
getCurrentTaskId,
|
|
38
38
|
getEnvContext,
|
|
39
39
|
runWithEnvContextAsync
|
|
40
|
-
} from "./roy-agent-core-
|
|
40
|
+
} from "./roy-agent-core-scp0afxg.js";
|
|
41
41
|
import {
|
|
42
42
|
TracedAs,
|
|
43
43
|
init_decorator
|
|
44
|
-
} from "./roy-agent-core-
|
|
44
|
+
} from "./roy-agent-core-cg146hmg.js";
|
|
45
45
|
import {
|
|
46
46
|
createLogger,
|
|
47
47
|
init_logger
|
|
48
|
-
} from "./roy-agent-core-
|
|
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
|
|
119
|
-
|
|
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
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
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
|
-
|
|
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
|
-
|
|
564
|
-
if (
|
|
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
|
-
|
|
598
|
+
resolvedSystemPrompt = resolvedSystemPrompt.replaceAll("{{workspace_dir}}", String(workspaceDir));
|
|
567
599
|
}
|
|
568
|
-
if (
|
|
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
|
-
|
|
605
|
+
resolvedSystemPrompt = resolvedSystemPrompt.replaceAll("{{memory}}", memoryContent || "(No memory)");
|
|
574
606
|
} else {
|
|
575
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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-
|
|
7
|
+
} from "./roy-agent-core-pf1c360e.js";
|
|
8
8
|
import {
|
|
9
9
|
createLogger,
|
|
10
10
|
init_logger
|
|
11
|
-
} from "./roy-agent-core-
|
|
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-
|
|
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-
|
|
10
|
+
} from "./roy-agent-core-pf1c360e.js";
|
|
11
11
|
import {
|
|
12
12
|
globalHookManager,
|
|
13
13
|
init_global_hook_manager
|
|
14
|
-
} from "./roy-agent-core-
|
|
14
|
+
} from "./roy-agent-core-gp872e7m.js";
|
|
15
15
|
import {
|
|
16
16
|
init_context
|
|
17
|
-
} from "./roy-agent-core-
|
|
17
|
+
} from "./roy-agent-core-zttjq1h3.js";
|
|
18
18
|
import {
|
|
19
19
|
createEnvContext,
|
|
20
20
|
runWithEnvContext
|
|
21
|
-
} from "./roy-agent-core-
|
|
21
|
+
} from "./roy-agent-core-scp0afxg.js";
|
|
22
22
|
import {
|
|
23
23
|
TracedAs,
|
|
24
24
|
init_decorator
|
|
25
|
-
} from "./roy-agent-core-
|
|
25
|
+
} from "./roy-agent-core-cg146hmg.js";
|
|
26
26
|
import {
|
|
27
27
|
createLogger,
|
|
28
28
|
init_logger
|
|
29
|
-
} from "./roy-agent-core-
|
|
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:
|
|
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
|
|
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
|
|
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-
|
|
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 };
|