@ai-setting/roy-agent-core 1.5.88 → 1.5.90
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/env/agent/index.js +8 -8
- package/dist/env/event-source/index.js +12 -4
- package/dist/env/index.js +20 -15
- package/dist/env/llm/index.js +4 -2
- package/dist/env/prompt/index.js +2 -1
- package/dist/env/session/index.js +3 -4
- package/dist/env/session/storage/index.js +2 -2
- package/dist/env/task/delegate/index.js +3 -2
- package/dist/env/task/index.js +4 -3
- package/dist/env/task/plugins/index.js +7 -4
- package/dist/env/tool/built-in/index.js +2 -1
- package/dist/env/tool/index.js +11 -8
- package/dist/env/workflow/engine/index.js +5 -3
- package/dist/env/workflow/index.js +6 -4
- package/dist/env/workflow/nodes/index.js +1 -1
- package/dist/env/workflow/tools/index.js +7 -1
- package/dist/env/workflow/utils/index.js +5 -0
- package/dist/index.js +144 -32
- package/dist/shared/@ai-setting/{roy-agent-core-r0m0at3x.js → roy-agent-core-0r4ndyn9.js} +119 -7
- package/dist/shared/@ai-setting/{roy-agent-core-jymz9fzp.js → roy-agent-core-2c8eraxq.js} +126 -41
- package/dist/shared/@ai-setting/{roy-agent-core-0y64qaac.js → roy-agent-core-32m0nb9j.js} +119 -30
- package/dist/shared/@ai-setting/roy-agent-core-4yq23m5g.js +421 -0
- package/dist/shared/@ai-setting/{roy-agent-core-h2d1s8yd.js → roy-agent-core-5ykms33a.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-mmkyydw7.js → roy-agent-core-83d035pp.js} +91 -579
- package/dist/shared/@ai-setting/roy-agent-core-8wd3qwx5.js +35 -0
- package/dist/shared/@ai-setting/{roy-agent-core-yx0vw1aw.js → roy-agent-core-8zjntsbb.js} +102 -32
- package/dist/shared/@ai-setting/{roy-agent-core-29fh9mxg.js → roy-agent-core-bwjpte58.js} +1 -2
- 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-4cdtdxqx.js → roy-agent-core-ewr1nw7t.js} +1 -1
- package/dist/shared/@ai-setting/roy-agent-core-hvdfgvfz.js +114 -0
- package/dist/shared/@ai-setting/{roy-agent-core-3arrpf7n.js → roy-agent-core-hxsbegfc.js} +229 -9
- package/dist/shared/@ai-setting/{roy-agent-core-9y09xfav.js → roy-agent-core-j0107ww1.js} +6 -418
- package/dist/shared/@ai-setting/{roy-agent-core-6mk0m4t3.js → roy-agent-core-m683wd1n.js} +283 -15
- package/dist/shared/@ai-setting/{roy-agent-core-bgw4dq11.js → roy-agent-core-mw4ty0ba.js} +44 -5
- package/dist/shared/@ai-setting/{roy-agent-core-7z4xtrmw.js → roy-agent-core-nqzt9ne4.js} +53 -0
- package/dist/shared/@ai-setting/roy-agent-core-pt7as39r.js +0 -0
- package/dist/shared/@ai-setting/{roy-agent-core-6n7xwv4v.js → roy-agent-core-rkz8r2sx.js} +5 -3
- package/dist/shared/@ai-setting/{roy-agent-core-c1j7ev4e.js → roy-agent-core-txwf64pd.js} +70 -0
- package/dist/shared/@ai-setting/{roy-agent-core-7fdzfsm6.js → roy-agent-core-w0kb72ve.js} +42 -213
- package/dist/shared/@ai-setting/roy-agent-core-w6bmrgap.js +581 -0
- package/dist/shared/@ai-setting/{roy-agent-core-qhjb153z.js → roy-agent-core-xnxyzaw4.js} +27 -4
- package/dist/shared/@ai-setting/roy-agent-core-yanpq5gb.js +116 -0
- package/dist/shared/@ai-setting/{roy-agent-core-hc20420t.js → roy-agent-core-z240ts1r.js} +27 -3
- package/dist/shared/@ai-setting/{roy-agent-core-q7sqeax6.js → roy-agent-core-zky9jse4.js} +163 -3
- package/package.json +1 -1
- package/dist/shared/@ai-setting/roy-agent-core-x3gtyqax.js +0 -378
- /package/dist/shared/@ai-setting/{roy-agent-core-4f3976cd.js → roy-agent-core-k5hxvaf0.js} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
TaskTagPlugin,
|
|
3
3
|
createLarkCliTaskNotifyHook
|
|
4
|
-
} from "./roy-agent-core-
|
|
4
|
+
} from "./roy-agent-core-w0kb72ve.js";
|
|
5
5
|
import {
|
|
6
6
|
envKeyToConfigKey
|
|
7
7
|
} from "./roy-agent-core-qxhq8ven.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 };
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ProcessRegistry,
|
|
3
|
+
runWithProcessRegistryAsync
|
|
4
|
+
} from "./roy-agent-core-hvdfgvfz.js";
|
|
1
5
|
import {
|
|
2
6
|
DEFAULT_SUBAGENT_PROMPT
|
|
3
|
-
} from "./roy-agent-core-
|
|
7
|
+
} from "./roy-agent-core-nqzt9ne4.js";
|
|
4
8
|
import {
|
|
5
9
|
TaskHookPoints
|
|
6
10
|
} from "./roy-agent-core-92z6t4he.js";
|
|
@@ -245,6 +249,7 @@ class BackgroundTaskManager {
|
|
|
245
249
|
tasks = new Map;
|
|
246
250
|
abortControllers = new Map;
|
|
247
251
|
progressTimers = new Map;
|
|
252
|
+
processRegistries = new Map;
|
|
248
253
|
constructor(env) {
|
|
249
254
|
this.env = env;
|
|
250
255
|
}
|
|
@@ -303,6 +308,8 @@ class BackgroundTaskManager {
|
|
|
303
308
|
throw new Error("Failed to create sub-session");
|
|
304
309
|
}
|
|
305
310
|
const abortController = new AbortController;
|
|
311
|
+
const processRegistry = new ProcessRegistry;
|
|
312
|
+
this.processRegistries.set(taskIdGen, processRegistry);
|
|
306
313
|
const task = {
|
|
307
314
|
id: taskIdGen,
|
|
308
315
|
subSessionId: subSession.id,
|
|
@@ -349,7 +356,8 @@ class BackgroundTaskManager {
|
|
|
349
356
|
if (!subSession) {
|
|
350
357
|
throw new Error(`Sub session not found: ${task.subSessionId}`);
|
|
351
358
|
}
|
|
352
|
-
const
|
|
359
|
+
const taskRegistry = this.processRegistries.get(taskId);
|
|
360
|
+
const result = await this.executeWithAbort(subSession, prompt, timeoutMs, abortController?.signal, task.similarTaskIds, taskRegistry);
|
|
353
361
|
if (abortController?.signal.aborted) {
|
|
354
362
|
logger.info(`[BackgroundTaskManager] Task was aborted`, { taskId });
|
|
355
363
|
return;
|
|
@@ -465,7 +473,7 @@ class BackgroundTaskManager {
|
|
|
465
473
|
this.progressTimers.delete(taskId);
|
|
466
474
|
}
|
|
467
475
|
}
|
|
468
|
-
async executeWithAbort(subSession, prompt, timeoutMs, signal, similarTaskIds) {
|
|
476
|
+
async executeWithAbort(subSession, prompt, timeoutMs, signal, similarTaskIds, processRegistry) {
|
|
469
477
|
const metadata = subSession.info?.metadata || {};
|
|
470
478
|
const taskId = metadata.task_id;
|
|
471
479
|
const taskDescription = metadata.task_description || "";
|
|
@@ -575,7 +583,17 @@ Use these as guidance to improve task execution efficiency.`;
|
|
|
575
583
|
const isWorkflowAgent = registry?.get(subagentType)?.type === "workflow";
|
|
576
584
|
const delegateQuery = isWorkflowAgent ? prompt : fullPrompt;
|
|
577
585
|
return new Promise((resolve, reject) => {
|
|
586
|
+
const killProcessTreeSafely = () => {
|
|
587
|
+
try {
|
|
588
|
+
processRegistry?.killAll();
|
|
589
|
+
} catch (err) {
|
|
590
|
+
logger.warn(`[delegate] ProcessRegistry.killAll failed`, {
|
|
591
|
+
error: err instanceof Error ? err.message : String(err)
|
|
592
|
+
});
|
|
593
|
+
}
|
|
594
|
+
};
|
|
578
595
|
const timer = setTimeout(() => {
|
|
596
|
+
killProcessTreeSafely();
|
|
579
597
|
reject(new Error(`Task execution timeout after ${timeoutMs}ms`));
|
|
580
598
|
try {
|
|
581
599
|
agentComponent?.abort?.(subagentType);
|
|
@@ -590,14 +608,17 @@ Use these as guidance to improve task execution efficiency.`;
|
|
|
590
608
|
agentComp.abort(subagentType);
|
|
591
609
|
}
|
|
592
610
|
} catch {}
|
|
611
|
+
killProcessTreeSafely();
|
|
593
612
|
reject(new Error("Task execution stopped"));
|
|
594
613
|
});
|
|
595
|
-
this.env.handle_query?.(delegateQuery, {
|
|
614
|
+
const invokeHandleQuery = () => this.env.handle_query?.(delegateQuery, {
|
|
596
615
|
sessionId,
|
|
597
616
|
deniedTools: deniedTools.length > 0 ? deniedTools : undefined,
|
|
598
617
|
agentType: subagentType,
|
|
599
618
|
abort: signal
|
|
600
|
-
})
|
|
619
|
+
});
|
|
620
|
+
const wrappedPromise = processRegistry ? runWithProcessRegistryAsync(processRegistry, () => invokeHandleQuery()) : Promise.resolve(invokeHandleQuery());
|
|
621
|
+
wrappedPromise?.then((result) => {
|
|
601
622
|
clearTimeout(timer);
|
|
602
623
|
resolve(result);
|
|
603
624
|
}).catch((error) => {
|
|
@@ -621,6 +642,14 @@ Use these as guidance to improve task execution efficiency.`;
|
|
|
621
642
|
task.status = "stopped";
|
|
622
643
|
task.abortController?.abort();
|
|
623
644
|
task.completedAt = Date.now();
|
|
645
|
+
try {
|
|
646
|
+
this.processRegistries.get(taskId)?.killAll();
|
|
647
|
+
} catch (err) {
|
|
648
|
+
logger.warn(`[delegate] stopTask killAll failed`, {
|
|
649
|
+
taskId,
|
|
650
|
+
error: err instanceof Error ? err.message : String(err)
|
|
651
|
+
});
|
|
652
|
+
}
|
|
624
653
|
const stoppedPayload = {
|
|
625
654
|
backgroundTaskId: task.id,
|
|
626
655
|
subSessionId: task.subSessionId,
|
|
@@ -646,6 +675,16 @@ Use these as guidance to improve task execution efficiency.`;
|
|
|
646
675
|
logger.debug(`[BackgroundTaskManager] Aborted task: ${taskId}`);
|
|
647
676
|
}
|
|
648
677
|
this.abortControllers.clear();
|
|
678
|
+
for (const [, registry] of this.processRegistries) {
|
|
679
|
+
try {
|
|
680
|
+
registry.killAll();
|
|
681
|
+
} catch (err) {
|
|
682
|
+
logger.warn(`[BackgroundTaskManager] dispose registry.killAll failed`, {
|
|
683
|
+
error: err instanceof Error ? err.message : String(err)
|
|
684
|
+
});
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
this.processRegistries.clear();
|
|
649
688
|
this.tasks.clear();
|
|
650
689
|
logger.info(`[BackgroundTaskManager] Disposed`);
|
|
651
690
|
}
|
|
@@ -193,6 +193,59 @@ class AgentRegistry {
|
|
|
193
193
|
};
|
|
194
194
|
this.agents.set(name, agent);
|
|
195
195
|
}
|
|
196
|
+
registerWorkflowExtractAgent() {
|
|
197
|
+
const name = "workflow-extract";
|
|
198
|
+
if (this.agents.has(name))
|
|
199
|
+
return;
|
|
200
|
+
const agent = {
|
|
201
|
+
name,
|
|
202
|
+
type: "sub",
|
|
203
|
+
description: "Workflow 提取子智能体 — 从父 task 的对话历史中分析需求,迭代式生成并验证 Workflow YAML",
|
|
204
|
+
systemPromptRef: "workflow-extract",
|
|
205
|
+
allowedTools: [
|
|
206
|
+
"workflow_get",
|
|
207
|
+
"workflow_list",
|
|
208
|
+
"workflow_add",
|
|
209
|
+
"workflow_validate"
|
|
210
|
+
],
|
|
211
|
+
deniedTools: [],
|
|
212
|
+
maxIterations: 10,
|
|
213
|
+
filterHistory: false
|
|
214
|
+
};
|
|
215
|
+
this.agents.set(name, agent);
|
|
216
|
+
}
|
|
217
|
+
registerCompactAgent() {
|
|
218
|
+
const name = "compact";
|
|
219
|
+
if (this.agents.has(name))
|
|
220
|
+
return;
|
|
221
|
+
const agent = {
|
|
222
|
+
name,
|
|
223
|
+
type: "sub",
|
|
224
|
+
description: "压缩子智能体 — 从父 session 的历史消息中提取结构化 checkpoint JSON",
|
|
225
|
+
systemPromptRef: "compact",
|
|
226
|
+
allowedTools: ["workflow_submit_output"],
|
|
227
|
+
deniedTools: [],
|
|
228
|
+
maxIterations: 1,
|
|
229
|
+
filterHistory: false
|
|
230
|
+
};
|
|
231
|
+
this.agents.set(name, agent);
|
|
232
|
+
}
|
|
233
|
+
registerCompactHintAgent() {
|
|
234
|
+
const name = "compact-hint";
|
|
235
|
+
if (this.agents.has(name))
|
|
236
|
+
return;
|
|
237
|
+
const agent = {
|
|
238
|
+
name,
|
|
239
|
+
type: "sub",
|
|
240
|
+
description: "压缩提示子智能体 — 分析父 session 历史,生成场景化压缩指导提示",
|
|
241
|
+
systemPromptRef: "compact-hint",
|
|
242
|
+
allowedTools: ["workflow_submit_output"],
|
|
243
|
+
deniedTools: [],
|
|
244
|
+
maxIterations: 1,
|
|
245
|
+
filterHistory: false
|
|
246
|
+
};
|
|
247
|
+
this.agents.set(name, agent);
|
|
248
|
+
}
|
|
196
249
|
async load() {
|
|
197
250
|
try {
|
|
198
251
|
return await this.loadFromDirectory(this.configDir);
|
|
File without changes
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
WorkflowEngine,
|
|
7
7
|
exports_engine,
|
|
8
8
|
init_engine
|
|
9
|
-
} from "./roy-agent-core-
|
|
9
|
+
} from "./roy-agent-core-j0107ww1.js";
|
|
10
10
|
import {
|
|
11
11
|
askUserTool,
|
|
12
12
|
createRunWorkflowTool,
|
|
@@ -16,8 +16,9 @@ import {
|
|
|
16
16
|
createWorkflowRunStatusTool,
|
|
17
17
|
createWorkflowRunStopTool,
|
|
18
18
|
createWorkflowSearchTool,
|
|
19
|
-
createWorkflowTagListTool
|
|
20
|
-
|
|
19
|
+
createWorkflowTagListTool,
|
|
20
|
+
createWorkflowValidateTool
|
|
21
|
+
} from "./roy-agent-core-32m0nb9j.js";
|
|
21
22
|
import {
|
|
22
23
|
WorkflowService
|
|
23
24
|
} from "./roy-agent-core-tq9528d3.js";
|
|
@@ -213,6 +214,7 @@ class WorkflowComponent extends BaseComponent {
|
|
|
213
214
|
createWorkflowGetTool(this.workflowService),
|
|
214
215
|
createWorkflowListTool(this.workflowService),
|
|
215
216
|
createWorkflowAddTool(this.workflowService),
|
|
217
|
+
createWorkflowValidateTool(this.workflowService),
|
|
216
218
|
createWorkflowSearchTool(this.workflowService),
|
|
217
219
|
createWorkflowTagListTool(this.workflowService),
|
|
218
220
|
createRunWorkflowTool(this.workflowService),
|