@ai-setting/roy-agent-core 1.7.57 → 1.7.59
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/error-reply.d.ts +4 -3
- package/dist/env/event-source/event-source-handlers.d.ts +11 -1
- package/dist/env/event-source/index.d.ts +1 -1
- package/dist/env/event-source/index.js +1 -1
- package/dist/env/event-source/types.d.ts +68 -0
- package/dist/env/index.d.ts +1 -1
- package/dist/env/index.js +3 -3
- package/dist/env/plugin/index.js +3 -1
- package/dist/env/plugin/lark-cli-notification-channel.d.ts +11 -2
- package/dist/env/task/delegate/delegate-tool.d.ts +26 -0
- package/dist/env/task/delegate/index.js +1 -1
- package/dist/env/task/index.js +2 -2
- package/dist/index.js +3 -3
- package/dist/shared/@ai-setting/{roy-agent-core-1sfbs57v.js → roy-agent-core-6bradb0j.js} +7 -2
- package/dist/shared/@ai-setting/{roy-agent-core-jw5ar4p0.js → roy-agent-core-6q5m1qk5.js} +60 -24
- package/dist/shared/@ai-setting/{roy-agent-core-ewcc5qdt.js → roy-agent-core-991pk4ss.js} +1 -1
- package/package.json +1 -1
|
@@ -57,9 +57,10 @@
|
|
|
57
57
|
* 都不得向上抛,绝不污染原始错误传播链
|
|
58
58
|
* - **有硬超时**:兜底 reply 在 5s 内一定 settle(超时 kill 子进程)。
|
|
59
59
|
* 否则 lark-cli 卡住会把 `QueryExecutor` 的 rethrow 拖死 → 事件队列堵死
|
|
60
|
-
* - **复用现有机制**:spawn 参数形态与 `
|
|
61
|
-
* `
|
|
62
|
-
* messageId → `+messages-reply`、
|
|
60
|
+
* - **复用现有机制**:spawn 参数形态与 `event-source-handlers.sendLarkMessage`
|
|
61
|
+
* / `lark-card-patch-notifier.buildSendCardArgs` / `telemetry-notice.buildLarkSendArgs`
|
|
62
|
+
* 保持一致(`--profile` 前置、messageId → `+messages-reply`、
|
|
63
|
+
* chatId → `+messages-send`、**两支都显式 `--as bot`**)
|
|
63
64
|
* - **去重**:同一 triggerEvent(messageId)只回一次;chat-only 通道走
|
|
64
65
|
* 5 分钟窗口,**不会**把整个群永久封锁;发送失败回滚去重标记
|
|
65
66
|
* - **无 channel 不崩但也不静默**:本地 REPL / `act` 没有飞书上下文 → debug;
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* 支持通过 handleRule.plugins 加载外部 Plugin
|
|
6
6
|
*/
|
|
7
7
|
import { ChildProcess } from "child_process";
|
|
8
|
-
import type { EventSourceConfig, EventSourceHandler, EventSourceInstance, EventSourceStatus, EventSourceEventHandler, EventMetadata, ReplyChannel, RecommendedAction } from "./types";
|
|
8
|
+
import type { EventSourceConfig, EventSourceHandler, EventSourceInstance, EventSourceStatus, EventSourceEventHandler, EventMetadata, ReplyChannel, RecommendedAction, RuleNoticeInfo } from "./types";
|
|
9
9
|
import { timerHandler } from "./timer-handler";
|
|
10
10
|
import { bountyIMHandler } from "./bounty-im-handler";
|
|
11
11
|
import { bountyCliHandler } from "./bounty-cli-handler";
|
|
@@ -469,6 +469,16 @@ export declare class LarkCliInstance implements EventSourceInstance {
|
|
|
469
469
|
*/
|
|
470
470
|
private sendLarkMessage;
|
|
471
471
|
}
|
|
472
|
+
/**
|
|
473
|
+
* 渲染「系统回执」小节 —— 告诉主 agent:群里**已经**看到了什么。
|
|
474
|
+
*
|
|
475
|
+
* 三种状态必须分开,否则 agent 会二选一地犯两种错:
|
|
476
|
+
* - 已送达却把「已超时」再讲一遍 → 重复刷屏
|
|
477
|
+
* - 未送达却以为发了 → 用户永远不知道任务结束了(正是 #4561 的现场)
|
|
478
|
+
*
|
|
479
|
+
* @param headline 事件标题句(未送达时要求 agent 自己讲清这个事实)
|
|
480
|
+
*/
|
|
481
|
+
export declare function renderRuleNoticeSection(ruleNotice: RuleNoticeInfo | undefined, headline: string): string;
|
|
472
482
|
/**
|
|
473
483
|
* LarkCli Handler
|
|
474
484
|
*/
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* 导出所有 EventSource 相关的类型、类和函数
|
|
5
5
|
*/
|
|
6
|
-
export type { EventSourceStatus, EventSourceType, EventSourceConfig, EventMetadata, RecommendedAction, ReplyChannel, EventSourceEventPayload, EventSourceEvent, EventSourceEventHandler, EventSourceStatusChangeEvent, EventSourcePersistenceConfig, EventSourceInstance, EventSourceHandler, EventSourceInitHook, EventSourceComponentInterface, EventSourceAgentHandlerConfig, } from "./types";
|
|
6
|
+
export type { EventSourceStatus, EventSourceType, EventSourceConfig, EventMetadata, RecommendedAction, ReplyChannel, EventSourceEventPayload, EventSourceEvent, EventSourceEventHandler, EventSourceStatusChangeEvent, EventSourcePersistenceConfig, EventSourceInstance, EventSourceHandler, EventSourceInitHook, EventSourceComponentInterface, EventSourceAgentHandlerConfig, NotifyChannelInfo, RuleNoticeInfo, } from "./types";
|
|
7
7
|
export { EventSourceInitHooks } from "./types";
|
|
8
8
|
export { BUILT_IN_EVENT_SOURCE_TYPES, BUILT_IN_EVENT_SOURCE_TYPE_LIST } from "./types";
|
|
9
9
|
export { isBuiltInEventSourceType, isValidEventSourceType, getDefaultConfigForType, validateEventSourceConfig, } from "./types";
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
larkCliHandler,
|
|
12
12
|
resolveBountyIMSystemPrompt,
|
|
13
13
|
timerHandler
|
|
14
|
-
} from "../../shared/@ai-setting/roy-agent-core-
|
|
14
|
+
} from "../../shared/@ai-setting/roy-agent-core-6q5m1qk5.js";
|
|
15
15
|
import {
|
|
16
16
|
BUILT_IN_EVENT_SOURCE_TYPES,
|
|
17
17
|
BUILT_IN_EVENT_SOURCE_TYPE_LIST,
|
|
@@ -580,6 +580,55 @@ export interface ReplyContext {
|
|
|
580
580
|
/** lark-cli profile(用于 im +messages-reply --profile) */
|
|
581
581
|
profile?: string;
|
|
582
582
|
}
|
|
583
|
+
/**
|
|
584
|
+
* 触发渠道信息(渠道无关的最小集合)。
|
|
585
|
+
*
|
|
586
|
+
* 由 CLI EventHandler 从 trigger event + handler.extractReplyContext 解析后
|
|
587
|
+
* 传给 buildNotifyHandlePrompt,让 prompt 能按**真实渠道**渲染:
|
|
588
|
+
* - 渠道类型(lark-cli / bounty-im / timer / ...)
|
|
589
|
+
* - 群 ID / 群聊还是私聊
|
|
590
|
+
* - 触发消息 ID、发送者、profile
|
|
591
|
+
*
|
|
592
|
+
* ★ 为什么不让每个 handler 自己从 triggerEvent 里抠字段:
|
|
593
|
+
* bounty-im 用 from/to 邮箱、lark 用 chatId/messageId,字段名完全不同;
|
|
594
|
+
* 统一在这里归一化,handler 只负责渲染「怎么发」。
|
|
595
|
+
*/
|
|
596
|
+
export interface NotifyChannelInfo {
|
|
597
|
+
/** EventSource 类型(lark-cli / bounty-im / timer / ...) */
|
|
598
|
+
esType: string;
|
|
599
|
+
/** 回复目标会话 ID(飞书为 oc_xxx) */
|
|
600
|
+
chatId?: string;
|
|
601
|
+
/** 群聊 / 私聊 / 未知(飞书 trigger event metadata.chatType) */
|
|
602
|
+
chatType?: "group" | "p2p" | "unknown";
|
|
603
|
+
/** 触发消息 ID(飞书为 om_xxx);reply 这条可保持话题线索 */
|
|
604
|
+
messageId?: string;
|
|
605
|
+
/** 触发者 ID(飞书为 ou_xxx) */
|
|
606
|
+
senderId?: string;
|
|
607
|
+
/** 多 appId 场景的 lark-cli profile */
|
|
608
|
+
profile?: string;
|
|
609
|
+
/** 回复方式:reply=回复触发消息 / send=新消息 / none=无可用通道 */
|
|
610
|
+
replyKind?: "reply" | "send" | "none";
|
|
611
|
+
}
|
|
612
|
+
/**
|
|
613
|
+
* 规则化回执(rule-based direct notice)的投递结果。
|
|
614
|
+
*
|
|
615
|
+
* 终态事件(completed / timeout)在进 lane 之前,会先用 telemetry 同一套
|
|
616
|
+
* 发送器直发一条**保底**消息到触发群;这里把「发没发出去」如实带给主 agent,
|
|
617
|
+
* 避免 prompt 谎称「已发送」而 agent 又重复/遗漏关键信息。
|
|
618
|
+
*/
|
|
619
|
+
export interface RuleNoticeInfo {
|
|
620
|
+
/** 是否尝试过直发(false = 该事件类型不在规则回执白名单) */
|
|
621
|
+
attempted: boolean;
|
|
622
|
+
/** 是否确实送到群里 */
|
|
623
|
+
delivered: boolean;
|
|
624
|
+
chatId?: string;
|
|
625
|
+
/** 实际发出的文案(送达时带,便于 prompt 里告知「回执已经说了什么」) */
|
|
626
|
+
text?: string;
|
|
627
|
+
/** 送达时刻(epoch ms) */
|
|
628
|
+
sentAt?: number;
|
|
629
|
+
/** 失败原因(未送达时带) */
|
|
630
|
+
error?: string;
|
|
631
|
+
}
|
|
583
632
|
/**
|
|
584
633
|
* buildNotifyHandlePrompt 输入
|
|
585
634
|
*/
|
|
@@ -591,6 +640,12 @@ export interface BuildNotifyHandlePromptInput {
|
|
|
591
640
|
description?: string;
|
|
592
641
|
result?: string;
|
|
593
642
|
error?: string;
|
|
643
|
+
/**
|
|
644
|
+
* 子 session ID —— 超时 / 失败后如需**续跑**,主 agent 可直接
|
|
645
|
+
* `delegate_task(existingSubSessionId=<此值>, ...)` 让子代理继承历史继续推进,
|
|
646
|
+
* 不必从零重来。
|
|
647
|
+
*/
|
|
648
|
+
subSessionId?: string;
|
|
594
649
|
};
|
|
595
650
|
/** 触发整个 delegate_task 的原始 event(从 EventStore 反查) */
|
|
596
651
|
triggerEvent: PersistedEvent;
|
|
@@ -605,6 +660,19 @@ export interface BuildNotifyHandlePromptInput {
|
|
|
605
660
|
* 让主 agent 拿到的回复命令带上正确的 `--profile`。
|
|
606
661
|
*/
|
|
607
662
|
profile?: string;
|
|
663
|
+
/**
|
|
664
|
+
* 触发渠道信息(渠道无关,由调用方归一化后传入)。
|
|
665
|
+
*
|
|
666
|
+
* 缺省时 handler 自行从 triggerEvent 反查(向后兼容)。
|
|
667
|
+
*/
|
|
668
|
+
channel?: NotifyChannelInfo;
|
|
669
|
+
/**
|
|
670
|
+
* 规则化回执的投递结果。
|
|
671
|
+
*
|
|
672
|
+
* 缺省 = 本事件不直发回执(如 failed / stopped / ask_user),
|
|
673
|
+
* prompt 需要引导 agent 把结果完整讲清楚。
|
|
674
|
+
*/
|
|
675
|
+
ruleNotice?: RuleNoticeInfo;
|
|
608
676
|
}
|
|
609
677
|
/**
|
|
610
678
|
* buildNotifyHandlePrompt 输出
|
package/dist/env/index.d.ts
CHANGED
|
@@ -16,7 +16,7 @@ export type { Task, TaskOperation, TaskStatus, TaskPriority, ActionType, CreateT
|
|
|
16
16
|
export { McpComponent, } from "./mcp";
|
|
17
17
|
export type { McpComponentConfig, McpComponentOptions, McpPath, McpServerConfig, McpServerStatus, DiscoveredMcpServer, } from "./mcp";
|
|
18
18
|
export { EventSourceComponent, larkCliHandler, builtInHandlers, } from "./event-source/event-source-component";
|
|
19
|
-
export type { EventSourceConfig, EventSourceStatus, EventSourceType, EventSourceEvent, EventSourceEventPayload, EventSourceEventHandler, EventSourceStatusChangeEvent, EventSourcePersistenceConfig, EventSourceComponentInterface, EventSourceHandler, EventSourceInstance, EventSourceAgentHandlerConfig, BUILT_IN_EVENT_SOURCE_TYPES, } from "./event-source/types";
|
|
19
|
+
export type { EventSourceConfig, EventSourceStatus, EventSourceType, EventSourceEvent, EventSourceEventPayload, EventSourceEventHandler, EventSourceStatusChangeEvent, EventSourcePersistenceConfig, EventSourceComponentInterface, EventSourceHandler, EventSourceInstance, EventSourceAgentHandlerConfig, NotifyChannelInfo, RuleNoticeInfo, BUILT_IN_EVENT_SOURCE_TYPES, } from "./event-source/types";
|
|
20
20
|
export { EventSourceInitHooks, isValidEventSourceType, isBuiltInEventSourceType, getDefaultConfigForType, validateEventSourceConfig, } from "./event-source/types";
|
|
21
21
|
export { WorkflowComponent, } from "./workflow/workflow-component";
|
|
22
22
|
export type { WorkflowComponentConfig, } from "./workflow/workflow-component";
|
package/dist/env/index.js
CHANGED
|
@@ -3,19 +3,19 @@ import {
|
|
|
3
3
|
} from "../shared/@ai-setting/roy-agent-core-84rs0c8d.js";
|
|
4
4
|
import {
|
|
5
5
|
TaskComponent
|
|
6
|
-
} from "../shared/@ai-setting/roy-agent-core-
|
|
6
|
+
} from "../shared/@ai-setting/roy-agent-core-991pk4ss.js";
|
|
7
7
|
import"../shared/@ai-setting/roy-agent-core-amkqnyzy.js";
|
|
8
8
|
import"../shared/@ai-setting/roy-agent-core-7q4wdze2.js";
|
|
9
9
|
import"../shared/@ai-setting/roy-agent-core-vh0qzb24.js";
|
|
10
10
|
import"../shared/@ai-setting/roy-agent-core-rn57psp0.js";
|
|
11
11
|
import"../shared/@ai-setting/roy-agent-core-8gxth0eh.js";
|
|
12
|
-
import"../shared/@ai-setting/roy-agent-core-
|
|
12
|
+
import"../shared/@ai-setting/roy-agent-core-6bradb0j.js";
|
|
13
13
|
import"../shared/@ai-setting/roy-agent-core-14bq77wr.js";
|
|
14
14
|
import {
|
|
15
15
|
EventSourceComponent,
|
|
16
16
|
builtInHandlers,
|
|
17
17
|
larkCliHandler
|
|
18
|
-
} from "../shared/@ai-setting/roy-agent-core-
|
|
18
|
+
} from "../shared/@ai-setting/roy-agent-core-6q5m1qk5.js";
|
|
19
19
|
import {
|
|
20
20
|
EventSourceInitHooks,
|
|
21
21
|
getDefaultConfigForType,
|
package/dist/env/plugin/index.js
CHANGED
|
@@ -19,10 +19,19 @@
|
|
|
19
19
|
*
|
|
20
20
|
* ## spawn lark-cli
|
|
21
21
|
*
|
|
22
|
-
* - messageId 走 `lark-cli im +messages-reply --message-id <id> --markdown <md
|
|
23
|
-
* - chatId 走 `lark-cli im +messages-send --chat-id <id> --markdown <md
|
|
22
|
+
* - messageId 走 `lark-cli im +messages-reply --message-id <id> --markdown <md> --as bot`
|
|
23
|
+
* - chatId 走 `lark-cli im +messages-send --chat-id <id> --markdown <md> --as bot`
|
|
24
24
|
* - profile 不为 undefined 时在 args 头部插入 `--profile <name>`
|
|
25
25
|
*
|
|
26
|
+
* ⚠️ **两支都必须显式 `--as bot`**(Task #4557)。chatId 分支历史上漏了,
|
|
27
|
+
* 不带 flag 时 lark-cli 用默认身份 = **user(真人账号)** 发出 →
|
|
28
|
+
* `lark-cli event consume im.message.receive_v1` 只看「是不是 user 发的」→
|
|
29
|
+
* 自己的通知被同一个 consumer 回灌成「用户消息」→ 又跑一次完整 agent run。
|
|
30
|
+
* Task #4552 在同类路径实测回灌率 **5/11 = 45%**,补 flag 后 **0/5 = 0%**
|
|
31
|
+
* (证据:本机 E2E 报告 `reports/4552-a1-real-e2e.md` §6(`reports/` 被 .gitignore 忽略,未入库))。
|
|
32
|
+
* 本 channel 虽 `@deprecated` 但仍是 opt-in 可启用实现,所以同样必须修。
|
|
33
|
+
* 失败即 reject → 由 `send()` 层 swallow + warn,**绝不降级成 user**。
|
|
34
|
+
*
|
|
26
35
|
* ## 失败处理
|
|
27
36
|
*
|
|
28
37
|
* - spawn 失败 / exit code != 0 → swallow(log warn,notification 失败不污染 Plugin 主流程)
|
|
@@ -49,6 +49,20 @@ export interface BackgroundTaskStartedPayload {
|
|
|
49
49
|
parentSessionId: string;
|
|
50
50
|
description: string;
|
|
51
51
|
subagentType: string;
|
|
52
|
+
/**
|
|
53
|
+
* ★ Task #4552 (A1):任务启动时刻(epoch ms)。
|
|
54
|
+
*
|
|
55
|
+
* 消费端(CLI EventHandler)把 telemetry 降级成一条纯 IM 进展提示后,
|
|
56
|
+
* 文案要回答「跑了多久」,只能从这里读。缺失时文案降级(不渲染「已跑」)。
|
|
57
|
+
*/
|
|
58
|
+
startedAt?: number;
|
|
59
|
+
/**
|
|
60
|
+
* ★ Task #4552 (A1):本任务被允许的运行时长(毫秒)。
|
|
61
|
+
*
|
|
62
|
+
* 让用户看到「预计 17:23 超时(timeout 5h)」,避免以为「早该有结论了」——
|
|
63
|
+
* 这正是 Task #4552 报障的认知错位(用户 16:40 以为超时,实际 17:23 才超)。
|
|
64
|
+
*/
|
|
65
|
+
timeoutMs?: number;
|
|
52
66
|
}
|
|
53
67
|
export interface BackgroundTaskProgressPayload {
|
|
54
68
|
backgroundTaskId: string;
|
|
@@ -58,6 +72,10 @@ export interface BackgroundTaskProgressPayload {
|
|
|
58
72
|
progress?: number;
|
|
59
73
|
description?: string;
|
|
60
74
|
associatedTaskId?: number;
|
|
75
|
+
/** ★ Task #4552 (A1):见 BackgroundTaskStartedPayload.startedAt */
|
|
76
|
+
startedAt?: number;
|
|
77
|
+
/** ★ Task #4552 (A1):见 BackgroundTaskStartedPayload.timeoutMs */
|
|
78
|
+
timeoutMs?: number;
|
|
61
79
|
}
|
|
62
80
|
export interface BackgroundTaskCompletedPayload {
|
|
63
81
|
backgroundTaskId: string;
|
|
@@ -191,6 +209,14 @@ export interface BackgroundTask {
|
|
|
191
209
|
/** Timestamp of the latest lifecycle state change or progress notification. */
|
|
192
210
|
lastUpdatedAt?: number;
|
|
193
211
|
startedAt?: number;
|
|
212
|
+
/**
|
|
213
|
+
* ★ Task #4552 (A1):本任务被允许的运行时长(毫秒,createTask 时确定)。
|
|
214
|
+
*
|
|
215
|
+
* 存到 task 上而不是每次重算:progress 心跳发生在 20 分钟后,那时
|
|
216
|
+
* `timeout` 参数已不在作用域内,只能靠这里。同时保证 started / progress
|
|
217
|
+
* 两条通知给出同一个超时时刻。
|
|
218
|
+
*/
|
|
219
|
+
timeoutMs?: number;
|
|
194
220
|
completedAt?: number;
|
|
195
221
|
result?: string;
|
|
196
222
|
error?: string;
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
BackgroundTaskManager,
|
|
4
4
|
createDelegateTool,
|
|
5
5
|
createStopTool
|
|
6
|
-
} from "../../../shared/@ai-setting/roy-agent-core-
|
|
6
|
+
} from "../../../shared/@ai-setting/roy-agent-core-6bradb0j.js";
|
|
7
7
|
import"../../../shared/@ai-setting/roy-agent-core-14bq77wr.js";
|
|
8
8
|
import"../../../shared/@ai-setting/roy-agent-core-2ctyjy62.js";
|
|
9
9
|
import"../../../shared/@ai-setting/roy-agent-core-1pg0fepg.js";
|
package/dist/env/task/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
TaskPriorityEnum,
|
|
6
6
|
TaskStatusEnum,
|
|
7
7
|
TaskTypeEnum
|
|
8
|
-
} from "../../shared/@ai-setting/roy-agent-core-
|
|
8
|
+
} from "../../shared/@ai-setting/roy-agent-core-991pk4ss.js";
|
|
9
9
|
import"../../shared/@ai-setting/roy-agent-core-amkqnyzy.js";
|
|
10
10
|
import"../../shared/@ai-setting/roy-agent-core-7q4wdze2.js";
|
|
11
11
|
import"../../shared/@ai-setting/roy-agent-core-vh0qzb24.js";
|
|
@@ -13,7 +13,7 @@ import"../../shared/@ai-setting/roy-agent-core-rn57psp0.js";
|
|
|
13
13
|
import {
|
|
14
14
|
TaskEntityEventTypes
|
|
15
15
|
} from "../../shared/@ai-setting/roy-agent-core-8gxth0eh.js";
|
|
16
|
-
import"../../shared/@ai-setting/roy-agent-core-
|
|
16
|
+
import"../../shared/@ai-setting/roy-agent-core-6bradb0j.js";
|
|
17
17
|
import"../../shared/@ai-setting/roy-agent-core-14bq77wr.js";
|
|
18
18
|
import {
|
|
19
19
|
SQLiteTaskStore,
|
package/dist/index.js
CHANGED
|
@@ -63,13 +63,13 @@ import {
|
|
|
63
63
|
} from "./shared/@ai-setting/roy-agent-core-84rs0c8d.js";
|
|
64
64
|
import {
|
|
65
65
|
TaskComponent
|
|
66
|
-
} from "./shared/@ai-setting/roy-agent-core-
|
|
66
|
+
} from "./shared/@ai-setting/roy-agent-core-991pk4ss.js";
|
|
67
67
|
import"./shared/@ai-setting/roy-agent-core-amkqnyzy.js";
|
|
68
68
|
import"./shared/@ai-setting/roy-agent-core-7q4wdze2.js";
|
|
69
69
|
import"./shared/@ai-setting/roy-agent-core-vh0qzb24.js";
|
|
70
70
|
import"./shared/@ai-setting/roy-agent-core-rn57psp0.js";
|
|
71
71
|
import"./shared/@ai-setting/roy-agent-core-8gxth0eh.js";
|
|
72
|
-
import"./shared/@ai-setting/roy-agent-core-
|
|
72
|
+
import"./shared/@ai-setting/roy-agent-core-6bradb0j.js";
|
|
73
73
|
import"./shared/@ai-setting/roy-agent-core-14bq77wr.js";
|
|
74
74
|
import {
|
|
75
75
|
BountyIMInstance,
|
|
@@ -83,7 +83,7 @@ import {
|
|
|
83
83
|
larkCliHandler,
|
|
84
84
|
resolveBountyIMSystemPrompt,
|
|
85
85
|
timerHandler
|
|
86
|
-
} from "./shared/@ai-setting/roy-agent-core-
|
|
86
|
+
} from "./shared/@ai-setting/roy-agent-core-6q5m1qk5.js";
|
|
87
87
|
import {
|
|
88
88
|
BUILT_IN_EVENT_SOURCE_TYPES,
|
|
89
89
|
BUILT_IN_EVENT_SOURCE_TYPE_LIST,
|
|
@@ -1207,6 +1207,7 @@ class BackgroundTaskManager {
|
|
|
1207
1207
|
status: "pending",
|
|
1208
1208
|
createdAt,
|
|
1209
1209
|
lastUpdatedAt: createdAt,
|
|
1210
|
+
timeoutMs: timeout || DEFAULT_TIMEOUT,
|
|
1210
1211
|
abortController,
|
|
1211
1212
|
similarTaskIds,
|
|
1212
1213
|
triggerEventId,
|
|
@@ -1219,7 +1220,9 @@ class BackgroundTaskManager {
|
|
|
1219
1220
|
subSessionId: subSession.id,
|
|
1220
1221
|
parentSessionId,
|
|
1221
1222
|
description,
|
|
1222
|
-
subagentType
|
|
1223
|
+
subagentType,
|
|
1224
|
+
startedAt: createdAt,
|
|
1225
|
+
timeoutMs: timeout || DEFAULT_TIMEOUT
|
|
1223
1226
|
};
|
|
1224
1227
|
this.publishBackgroundEvent(BackgroundTaskEventTypes.STARTED, startedPayload, parentSessionId, triggerEventId, replyChannelSnapshot);
|
|
1225
1228
|
this.executeTask(taskIdGen, prompt, timeout, parentSessionId).catch((err) => {
|
|
@@ -1403,7 +1406,9 @@ class BackgroundTaskManager {
|
|
|
1403
1406
|
parentSessionId,
|
|
1404
1407
|
description: task.description,
|
|
1405
1408
|
status: task.status,
|
|
1406
|
-
associatedTaskId: task.associatedTaskId
|
|
1409
|
+
associatedTaskId: task.associatedTaskId,
|
|
1410
|
+
startedAt: task.createdAt,
|
|
1411
|
+
timeoutMs: task.timeoutMs
|
|
1407
1412
|
};
|
|
1408
1413
|
this.publishBackgroundEvent(BackgroundTaskEventTypes.PROGRESS, progressPayload, parentSessionId, task.triggerEventId, task.replyChannel);
|
|
1409
1414
|
}, PROGRESS_INTERVAL);
|
|
@@ -1402,7 +1402,9 @@ function spawnLarkReply(options) {
|
|
|
1402
1402
|
"--chat-id",
|
|
1403
1403
|
chatId,
|
|
1404
1404
|
"--markdown",
|
|
1405
|
-
normalizedContent
|
|
1405
|
+
normalizedContent,
|
|
1406
|
+
"--as",
|
|
1407
|
+
"bot"
|
|
1406
1408
|
];
|
|
1407
1409
|
} else {
|
|
1408
1410
|
finish(new Error("No target specified for failure reply"));
|
|
@@ -2501,7 +2503,6 @@ class LarkCliInstance {
|
|
|
2501
2503
|
chatId: replyChannel.chatId,
|
|
2502
2504
|
userId: replyChannel.params?.userId,
|
|
2503
2505
|
content: text,
|
|
2504
|
-
as: "bot",
|
|
2505
2506
|
profile
|
|
2506
2507
|
});
|
|
2507
2508
|
},
|
|
@@ -2510,7 +2511,6 @@ class LarkCliInstance {
|
|
|
2510
2511
|
chatId: replyChannel.chatId,
|
|
2511
2512
|
userId: replyChannel.params?.userId,
|
|
2512
2513
|
content: markdown,
|
|
2513
|
-
as: "bot",
|
|
2514
2514
|
format: "markdown",
|
|
2515
2515
|
profile
|
|
2516
2516
|
});
|
|
@@ -2520,7 +2520,6 @@ class LarkCliInstance {
|
|
|
2520
2520
|
chatId: replyChannel.chatId,
|
|
2521
2521
|
userId: replyChannel.params?.userId,
|
|
2522
2522
|
content: JSON.stringify(content),
|
|
2523
|
-
as: "bot",
|
|
2524
2523
|
profile
|
|
2525
2524
|
});
|
|
2526
2525
|
},
|
|
@@ -2529,7 +2528,6 @@ class LarkCliInstance {
|
|
|
2529
2528
|
await this.sendLarkMessage({
|
|
2530
2529
|
messageId: replyChannel.messageId,
|
|
2531
2530
|
content: JSON.stringify(content),
|
|
2532
|
-
as: "bot",
|
|
2533
2531
|
profile
|
|
2534
2532
|
});
|
|
2535
2533
|
}
|
|
@@ -2538,16 +2536,16 @@ class LarkCliInstance {
|
|
|
2538
2536
|
}
|
|
2539
2537
|
async sendLarkMessage(options) {
|
|
2540
2538
|
return new Promise((resolve, reject) => {
|
|
2541
|
-
const { chatId, userId, messageId, content,
|
|
2539
|
+
const { chatId, userId, messageId, content, format = "text", profile } = options;
|
|
2542
2540
|
const normalizedContent = normalizeLarkAtMentions(content);
|
|
2543
2541
|
const contentFlag = format === "markdown" ? "--markdown" : "--text";
|
|
2544
2542
|
const args = ["im"];
|
|
2545
2543
|
if (messageId) {
|
|
2546
|
-
args.push("+messages-reply", "--message-id", messageId, "--as",
|
|
2544
|
+
args.push("+messages-reply", "--message-id", messageId, "--as", "bot", contentFlag, normalizedContent);
|
|
2547
2545
|
} else if (chatId) {
|
|
2548
|
-
args.push("+messages-send", "--chat-id", chatId, "--as",
|
|
2546
|
+
args.push("+messages-send", "--chat-id", chatId, "--as", "bot", contentFlag, normalizedContent);
|
|
2549
2547
|
} else if (userId) {
|
|
2550
|
-
args.push("+messages-send", "--user-id", userId, "--as",
|
|
2548
|
+
args.push("+messages-send", "--user-id", userId, "--as", "bot", contentFlag, normalizedContent);
|
|
2551
2549
|
} else {
|
|
2552
2550
|
reject(new Error("No target specified for sending message"));
|
|
2553
2551
|
return;
|
|
@@ -2623,6 +2621,24 @@ function describeNotifyEvent(type, taskId, desc) {
|
|
|
2623
2621
|
return { headline: `Sub-agent 更新了 Task #${taskId}「${desc}」。`, actionable };
|
|
2624
2622
|
}
|
|
2625
2623
|
}
|
|
2624
|
+
function renderRuleNoticeSection(ruleNotice, headline) {
|
|
2625
|
+
if (!ruleNotice || !ruleNotice.attempted) {
|
|
2626
|
+
return `(本事件不直发规则回执)
|
|
2627
|
+
` + `→ 你的回复要把结果讲**完整**(用户只能从你这条消息知道结论)。`;
|
|
2628
|
+
}
|
|
2629
|
+
if (ruleNotice.delivered) {
|
|
2630
|
+
const when = ruleNotice.sentAt ? new Date(ruleNotice.sentAt).toLocaleTimeString("zh-CN", {
|
|
2631
|
+
hour12: false,
|
|
2632
|
+
hour: "2-digit",
|
|
2633
|
+
minute: "2-digit"
|
|
2634
|
+
}) : "";
|
|
2635
|
+
const sent = ruleNotice.text ? `:「${ruleNotice.text.replace(/\s*\n+\s*/g, " ")}」` : "";
|
|
2636
|
+
return `✅ 系统已于 ${when || "刚才"} 把下面这条发到群里${sent}
|
|
2637
|
+
` + `→ 你的回复**只发增量**:不要再重复「任务已结束」这类回执原文,` + `直接讲结论/交付 + 下一步选项。`;
|
|
2638
|
+
}
|
|
2639
|
+
return `❌ **回执未送达**(原因:${ruleNotice.error ?? "unknown"})
|
|
2640
|
+
` + `→ 用户目前**还不知道**「${headline}」这件事,必须由你在回复里讲清楚,` + `并且不要假装系统已经通知过。`;
|
|
2641
|
+
}
|
|
2626
2642
|
var larkCliHandler = {
|
|
2627
2643
|
type: "lark-cli",
|
|
2628
2644
|
validateConfig(config) {
|
|
@@ -2685,47 +2701,67 @@ var larkCliHandler = {
|
|
|
2685
2701
|
senderOpenId: input.triggerEvent.metadata?.senderId ?? input.triggerEvent.senderId,
|
|
2686
2702
|
profile: input.profile
|
|
2687
2703
|
};
|
|
2688
|
-
const
|
|
2704
|
+
const esType = input.channel?.esType ?? ctx.esType ?? "lark-cli";
|
|
2705
|
+
const chatId = input.channel?.chatId || ctx.chatId;
|
|
2706
|
+
const messageId = input.channel?.messageId || ctx.messageId;
|
|
2707
|
+
const senderId = input.channel?.senderId || ctx.senderOpenId;
|
|
2708
|
+
const chatType = input.channel?.chatType ?? "unknown";
|
|
2709
|
+
const profile = input.channel?.profile ?? ctx.profile;
|
|
2710
|
+
const profileFlag = profile ? `--profile ${profile} ` : "";
|
|
2689
2711
|
const desc = input.notifyEvent.description ?? "(未命名任务)";
|
|
2690
2712
|
const result = input.subAgentResult.summary ?? input.notifyEvent.result ?? "";
|
|
2691
2713
|
const notifyType = input.notifyEvent.type;
|
|
2692
2714
|
const taskId = input.notifyEvent.taskId ?? "?";
|
|
2693
2715
|
const { headline, actionable } = describeNotifyEvent(notifyType, taskId, desc);
|
|
2716
|
+
const chatTypeLabel = chatType === "group" ? "群聊" : chatType === "p2p" ? "私聊" : "会话类型未知";
|
|
2717
|
+
const canReply = Boolean(chatId);
|
|
2718
|
+
const receiptSection = renderRuleNoticeSection(input.ruleNotice, headline);
|
|
2719
|
+
const replyCommand = messageId ? `lark-cli ${profileFlag}im +messages-reply --message-id ${messageId} --chat-id ${chatId} --as bot --markdown '<你的回复>'` : `lark-cli ${profileFlag}im +messages-send --chat-id ${chatId} --as bot --markdown '<你的回复>'`;
|
|
2720
|
+
const scopeWord = chatType === "group" ? "群聊" : chatType === "p2p" ? "私聊" : "会话";
|
|
2694
2721
|
const promptText = actionable ? `
|
|
2695
2722
|
## Notify Event: ${notifyType}
|
|
2696
2723
|
|
|
2697
2724
|
${headline}
|
|
2698
2725
|
|
|
2699
|
-
###
|
|
2700
|
-
- ES:
|
|
2701
|
-
- **chatId: ${
|
|
2702
|
-
- **messageId: ${
|
|
2703
|
-
- sender: ${
|
|
2704
|
-
${
|
|
2726
|
+
### 触发渠道(EventSource)
|
|
2727
|
+
- ES: ${esType}(飞书,${chatTypeLabel})
|
|
2728
|
+
- **chatId: ${chatId || "(缺失)"}** ← 关键!必须发到这里
|
|
2729
|
+
- **messageId: ${messageId || "(缺失)"}** ← ${messageId ? "reply 这条,保持话题线索" : "无触发消息,用 +messages-send"}
|
|
2730
|
+
- sender: ${senderId || "(未知)"}
|
|
2731
|
+
${input.notifyEvent.subSessionId ? `- 子 session: ${input.notifyEvent.subSessionId} ← 如需续跑:delegate_task(existingSubSessionId=<此值>, prompt=<新要求>)
|
|
2732
|
+
` : ""}${profile ? `- profile: ${profile} ← 调用 lark-cli 必须带 --profile
|
|
2705
2733
|
` : ""}
|
|
2734
|
+
### 系统回执(rule-based 直发)
|
|
2735
|
+
${receiptSection}
|
|
2736
|
+
|
|
2706
2737
|
### Sub-agent 输出
|
|
2707
2738
|
${result}
|
|
2708
2739
|
|
|
2709
|
-
### \uD83D\uDC49
|
|
2710
|
-
用
|
|
2711
|
-
|
|
2740
|
+
### \uD83D\uDC49 你要做什么
|
|
2741
|
+
1. 用 2~5 行总结:这次完成了什么 / 卡在哪(依据上面的输出与子 session)
|
|
2742
|
+
2. 给出 1~3 个下一步选项(继续推进 / 拆小 / 放弃),并**问用户选哪个**
|
|
2743
|
+
3. 用 lark-cli 把回复发到上面的${scopeWord}(见下)
|
|
2744
|
+
|
|
2745
|
+
### 发送方式(渠道 = lark-cli)
|
|
2746
|
+
${canReply ? ` ${replyCommand}` : `⚠️ 没有可用的 chatId —— 无法投递到触发会话。请在会话内汇报,并说明「未投递」的原因。`}
|
|
2712
2747
|
|
|
2713
2748
|
⚠️ 不要 fallback 到 lastReplyChannel 或 metadata.replyChannel — 那个 chatId
|
|
2714
2749
|
可能跟用户原始消息的 chatId 不一致(参见 #4035/#4038/#4039 bug)。
|
|
2750
|
+
⚠️ 必须 --as bot(否则会被自己的 lark-cli consumer 当用户消息回灌);不要用 user 身份。
|
|
2715
2751
|
` : `
|
|
2716
2752
|
## Notify Event: ${notifyType}
|
|
2717
2753
|
|
|
2718
2754
|
${headline}
|
|
2719
2755
|
|
|
2720
|
-
###
|
|
2721
|
-
- ES:
|
|
2722
|
-
- chatId: ${
|
|
2723
|
-
- messageId: ${
|
|
2756
|
+
### 触发渠道(EventSource)
|
|
2757
|
+
- ES: ${esType}(${chatTypeLabel})
|
|
2758
|
+
- chatId: ${chatId || "(缺失)"}
|
|
2759
|
+
- messageId: ${messageId || "(缺失)"}
|
|
2724
2760
|
|
|
2725
2761
|
(这是中间态通知:仅作状态同步,**不要**回复用户,也不要调用 lark-cli 发消息。
|
|
2726
2762
|
等收到 task.background.completed / failed / timeout / stopped 终态通知后再回复。)
|
|
2727
2763
|
`;
|
|
2728
|
-
const systemHint = actionable ? `回复必须用 lark-cli im +messages-reply(${profileFlag.trim() ? `带 ${profileFlag.trim()};` : ""}` + `chatId=${
|
|
2764
|
+
const systemHint = actionable ? `回复必须用 lark-cli im +messages-reply(${profileFlag.trim() ? `带 ${profileFlag.trim()};` : ""}` + `chatId=${chatId} / messageId=${messageId} 来自 trigger event(esType=${esType}),不要 fallback。` + (input.ruleNotice?.delivered ? "系统回执已送达,只发增量。" : "") : `这是 ${notifyType} 中间态通知,不要回复用户;仅等待终态通知。`;
|
|
2729
2765
|
return { promptText, systemHint };
|
|
2730
2766
|
},
|
|
2731
2767
|
setRunner(runner) {
|