@ai-setting/roy-agent-core 1.7.71 → 1.7.75
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/agent-component.js +6 -6
- package/dist/env/agent/agent-registry.d.ts +4 -1
- package/dist/env/agent/index.js +6 -6
- package/dist/env/agent/summary-agent.d.ts +6 -15
- package/dist/env/agent/types.d.ts +0 -17
- package/dist/env/error-reply.d.ts +46 -0
- package/dist/env/error-reply.js +3 -1
- package/dist/env/event-source/event-source-handlers.js +12 -12
- package/dist/env/event-source/index.js +13 -13
- package/dist/env/index.js +30 -31
- package/dist/env/llm/index.js +2 -2
- package/dist/env/llm/orphan-toolcall.d.ts +107 -0
- package/dist/env/llm/temperature-policy.d.ts +107 -0
- package/dist/env/llm/types.d.ts +2 -2
- package/dist/env/plugin/index.js +3 -3
- package/dist/env/prompt/index.js +3 -3
- package/dist/env/prompt/prompts-index.d.ts +26 -4
- package/dist/env/session/__bench__/replay-compact.d.ts +137 -0
- package/dist/env/session/__bench__/run-replay.d.ts +15 -0
- package/dist/env/session/compact-checkpoint-content.d.ts +67 -0
- package/dist/env/session/index.d.ts +1 -0
- package/dist/env/session/index.js +4 -5
- package/dist/env/session/session-component.d.ts +47 -30
- package/dist/env/session/storage/index.js +3 -3
- package/dist/env/session/storage/sqlite.d.ts +8 -0
- package/dist/env/session/types.d.ts +45 -30
- package/dist/env/task/delegate/delegate-tool.d.ts +8 -0
- package/dist/env/task/delegate/delegate-tool.js +4 -4
- package/dist/env/task/delegate/index.js +4 -4
- package/dist/env/task/index.js +7 -7
- package/dist/env/task/mcp/index.js +2 -2
- package/dist/env/task/plugins/index.d.ts +3 -0
- package/dist/env/task/plugins/index.js +32 -9
- package/dist/env/task/plugins/lark-card-patch-notifier.d.ts +61 -0
- package/dist/env/task/plugins/lark-card-patch-notifier.js +6 -2
- package/dist/env/task/plugins/lark-cli-task-notify-plugin.d.ts +42 -0
- package/dist/env/task/prompt/index.js +1 -1
- package/dist/env/task/prompt/task-discipline.d.ts +9 -3
- package/dist/env/task/tools/cancel-tool.d.ts +28 -0
- package/dist/env/task/tools/index.d.ts +1 -0
- package/dist/env/task/tools/index.js +4 -2
- package/dist/env/task/tools/task-types.d.ts +22 -0
- package/dist/env/tool/built-in/compact-session-tool.d.ts +120 -0
- package/dist/env/tool/built-in/index.d.ts +2 -0
- package/dist/env/tool/built-in/index.js +6 -2
- package/dist/env/tool/index.js +4 -4
- package/dist/env/workflow/engine/index.js +6 -7
- package/dist/env/workflow/index.js +15 -14
- package/dist/env/workflow/plugins/index.js +2 -2
- package/dist/env/workflow/tools/ask-user-tool.d.ts +88 -0
- package/dist/env/workflow/tools/index.js +11 -10
- package/dist/env/workflow/tools/run-workflow.d.ts +2 -2
- package/dist/env/workflow/types/index.js +2 -2
- package/dist/env/workflow/types/workflow-hil.d.ts +25 -1
- package/dist/env/workflow/utils/index.js +5 -5
- package/dist/index.d.ts +1 -1
- package/dist/index.js +33 -34
- package/dist/shared/@ai-setting/{roy-agent-core-hy3zn2q2.js → roy-agent-core-0qyrk5k0.js} +22 -2
- package/dist/shared/@ai-setting/{roy-agent-core-kmbct9yg.js → roy-agent-core-0snm5hc5.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-4jjwewvw.js → roy-agent-core-11shp00p.js} +31 -10
- package/dist/shared/@ai-setting/{roy-agent-core-yr1mryb8.js → roy-agent-core-1v4g0d4x.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-02j24hrg.js → roy-agent-core-264qexac.js} +71 -4
- package/dist/shared/@ai-setting/{roy-agent-core-9geem94g.js → roy-agent-core-29b6hc39.js} +1 -1
- package/dist/shared/@ai-setting/roy-agent-core-2akfd64z.js +374 -0
- package/dist/shared/@ai-setting/{roy-agent-core-zv8bswpw.js → roy-agent-core-3e6gg17d.js} +120 -28
- package/dist/shared/@ai-setting/{roy-agent-core-8cx7cfdg.js → roy-agent-core-3fh1f7s7.js} +2 -3
- package/dist/shared/@ai-setting/{roy-agent-core-mwa6apzx.js → roy-agent-core-4gr3k7qg.js} +17 -4
- package/dist/shared/@ai-setting/{roy-agent-core-zsbh9bfv.js → roy-agent-core-60jbrfye.js} +6 -6
- package/dist/shared/@ai-setting/{roy-agent-core-add1zqsh.js → roy-agent-core-6cy43nss.js} +22 -1
- package/dist/shared/@ai-setting/{roy-agent-core-mw2cen6s.js → roy-agent-core-6rh8k6ba.js} +5 -5
- package/dist/shared/@ai-setting/{roy-agent-core-kpg25s2q.js → roy-agent-core-8ez6mccb.js} +4 -2
- package/dist/shared/@ai-setting/{roy-agent-core-sjr1kmfz.js → roy-agent-core-acj8ag08.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-mds8tqd0.js → roy-agent-core-cgtq6427.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-9bshyqjn.js → roy-agent-core-ddyk1rc0.js} +183 -132
- package/dist/shared/@ai-setting/{roy-agent-core-hfr6bzts.js → roy-agent-core-djpq6yb0.js} +16 -7
- package/dist/shared/@ai-setting/{roy-agent-core-002g6nfk.js → roy-agent-core-dqxec05w.js} +7 -6
- package/dist/shared/@ai-setting/{roy-agent-core-07fvy74y.js → roy-agent-core-ed233k5z.js} +21 -7
- package/dist/shared/@ai-setting/{roy-agent-core-jrj30vq3.js → roy-agent-core-er070zjq.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-40rv283c.js → roy-agent-core-fghc2m8z.js} +152 -2
- package/dist/shared/@ai-setting/{roy-agent-core-7sj9xs9c.js → roy-agent-core-hnyk1by7.js} +110 -2
- package/dist/shared/@ai-setting/{roy-agent-core-101qtkyc.js → roy-agent-core-jg65qnwa.js} +11 -8
- package/dist/shared/@ai-setting/{roy-agent-core-e25xkv53.js → roy-agent-core-mkc3zshb.js} +3 -1
- package/dist/shared/@ai-setting/{roy-agent-core-0cb6w0k7.js → roy-agent-core-mww0mnd9.js} +231 -27
- package/dist/shared/@ai-setting/{roy-agent-core-5repth1n.js → roy-agent-core-n9q1encx.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-46rv4d7d.js → roy-agent-core-nmx9934r.js} +92 -2
- package/dist/shared/@ai-setting/{roy-agent-core-1w9y7mxj.js → roy-agent-core-p3zv1mx5.js} +1 -1
- package/dist/shared/@ai-setting/roy-agent-core-snvh4s2p.js +662 -0
- package/dist/shared/@ai-setting/{roy-agent-core-dt104qa1.js → roy-agent-core-v85n42ve.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-37tj4y6a.js → roy-agent-core-v87njmq7.js} +3 -3
- package/dist/shared/@ai-setting/{roy-agent-core-k13pxrpk.js → roy-agent-core-y7x2qzwc.js} +553 -92
- package/package.json +1 -1
- package/dist/shared/@ai-setting/roy-agent-core-1gsbqesr.js +0 -1083
- package/dist/shared/@ai-setting/roy-agent-core-58804s3j.js +0 -155
- package/dist/shared/@ai-setting/roy-agent-core-ze068vc9.js +0 -37
|
@@ -149,6 +149,13 @@ export declare class LarkCliTaskNotifyHook implements Hook {
|
|
|
149
149
|
* key: `op:${taskId}`,value: 上次 patch 时间戳
|
|
150
150
|
*/
|
|
151
151
|
private lastNotifyTimestamps;
|
|
152
|
+
/**
|
|
153
|
+
* ★ Task #5020 —— 尾沿补发定时器(key: taskId)。
|
|
154
|
+
*
|
|
155
|
+
* 被节流的 operation 只登记一个待补发标记;窗口结束时补发**一次**
|
|
156
|
+
* patch,渲染累积后的完整时间线。见 {@link scheduleTrailingPatch}。
|
|
157
|
+
*/
|
|
158
|
+
private trailingPatchTimers;
|
|
152
159
|
/** 卡片路由端口(由 EventSource handler 注入) */
|
|
153
160
|
private cardRoutingPorts?;
|
|
154
161
|
/**
|
|
@@ -236,6 +243,37 @@ export declare class LarkCliTaskNotifyHook implements Hook {
|
|
|
236
243
|
* 旧实现会 fallback `startTask`(凭空多发一张卡)——已删除。
|
|
237
244
|
*/
|
|
238
245
|
private onAfterOperationCreate;
|
|
246
|
+
/**
|
|
247
|
+
* ★ Task #5020 —— 立即 patch 一次 operation 时间线。
|
|
248
|
+
*
|
|
249
|
+
* 失败只记日志:**不能**因为飞书侧失败就丢掉已经落进 ledger 的数据
|
|
250
|
+
* (ledger 落库在调用方、且早于本方法)。
|
|
251
|
+
*/
|
|
252
|
+
private patchOperationTimeline;
|
|
253
|
+
/**
|
|
254
|
+
* ★ Task #5020 —— 尾沿补发:窗口结束时把累积的时间线 patch 一次。
|
|
255
|
+
*
|
|
256
|
+
* ## 为什么需要(review round-2 MAJOR)
|
|
257
|
+
*
|
|
258
|
+
* 若「被节流就不 patch」,那条里程碑可能永远不上卡(等不到下一个事件);
|
|
259
|
+
* 若「被节流也立刻 patch」,节流就完全没有减少 patch 次数,形同虚设。
|
|
260
|
+
*
|
|
261
|
+
* 尾沿补发是两者的正解:窗口内的 N 条只排队、**不发**;窗口一结束补发
|
|
262
|
+
* **一次**,渲染当时**累积后的完整时间线**(`updateTask` 传空数组即用
|
|
263
|
+
* state 里的全部里程碑)。于是「可见性」与「限频」同时满足。
|
|
264
|
+
*
|
|
265
|
+
* - 同一 task 同时只挂一个定时器(重入只刷新,不叠加)
|
|
266
|
+
* - 定时器 `unref()`,不阻止进程退出
|
|
267
|
+
* - 补发失败只 warn(数据已在 ledger,跨进程回填仍有保障)
|
|
268
|
+
*/
|
|
269
|
+
private scheduleTrailingPatch;
|
|
270
|
+
/**
|
|
271
|
+
* ★ Task #5020 —— 取消该 task 待补发的尾沿 patch(终态 / 暂停时调用)。
|
|
272
|
+
*
|
|
273
|
+
* 与 {@link scheduleTrailingPatch} 里的二次校验互为双保险:
|
|
274
|
+
* 这里主动取消,避免即使校验通过也多发一次无意义的 patch。
|
|
275
|
+
*/
|
|
276
|
+
private cancelTrailingPatch;
|
|
239
277
|
/**
|
|
240
278
|
* 从持久层回填内存 messageId(一次性/幂等)
|
|
241
279
|
*
|
|
@@ -375,6 +413,10 @@ export declare class LarkCliTaskNotifyHook implements Hook {
|
|
|
375
413
|
*
|
|
376
414
|
* 同一 Task 在 operationThrottleMs(默认 5s)窗口内只 patch 一次,
|
|
377
415
|
* 避免 agent 每次 tool call 都刷屏 patch 卡片。
|
|
416
|
+
*
|
|
417
|
+
* ★ Task #5020 —— 返回 true **不代表丢弃**:被节流的 operation 仍会
|
|
418
|
+
* 并进 notifier 的内存态(`mergeTimelineState`)并落进共享 ledger,
|
|
419
|
+
* 只是**不立刻 patch 飞书**。节流只限制**频率**,不丢**数据**。
|
|
378
420
|
*/
|
|
379
421
|
private shouldThrottleOperation;
|
|
380
422
|
/** 检查是否应该发送通知 */
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
TASK_DISCIPLINE_LIFECYCLE,
|
|
6
6
|
TASK_DISCIPLINE_OPERATION,
|
|
7
7
|
TASK_DISCIPLINE_PROMPT
|
|
8
|
-
} from "../../../shared/@ai-setting/roy-agent-core-
|
|
8
|
+
} from "../../../shared/@ai-setting/roy-agent-core-11shp00p.js";
|
|
9
9
|
import"../../../shared/@ai-setting/roy-agent-core-fs0mn2jk.js";
|
|
10
10
|
export {
|
|
11
11
|
TASK_DISCIPLINE_PROMPT,
|
|
@@ -21,12 +21,18 @@
|
|
|
21
21
|
* prompts-index(超大模板串)与外部 npm 消费方安全引用。
|
|
22
22
|
*/
|
|
23
23
|
/** 分片 1:生命周期契约(M1/M2/M13/M14/M15) */
|
|
24
|
-
export declare const TASK_DISCIPLINE_LIFECYCLE
|
|
24
|
+
export declare const TASK_DISCIPLINE_LIFECYCLE: string;
|
|
25
25
|
/** 分片 2:操作记录双维度规范(M3/M4/M5/M6/M16) */
|
|
26
26
|
export declare const TASK_DISCIPLINE_OPERATION = "### Operation Record \u2014 \u53CC\u7EF4\u5EA6\u5206\u5DE5\u89C4\u8303\n\n**Record milestones as you work** \u2014 call `task_operation_create` the moment a\nstage is reached, **not after the fact** (not in a batch at the end).\n\n**\u64CD\u4F5C\u8BB0\u5F55\u5FC5\u987B\u4E25\u683C\u533A\u5206\u4E24\u4E2A\u7EF4\u5EA6\uFF0C\u4E8C\u8005\u914D\u5957\u8BB0\u5F55\u3001\u5404\u53F8\u5176\u804C**\uFF1A\n\n#### \u7EF4\u5EA6 1\uFF1A\u72B6\u6001/\u91CC\u7A0B\u7891\uFF08\"\u8FBE\u5230\u4EC0\u4E48\"\uFF09\u2014 \u5FC5\u586B\u7EF4\u5EA6\n\u4F7F\u7528 `task_operation_create` \u7684 milestone_* \u4E3B\u5B57\u6BB5\uFF1A\n- **milestone_type**\uFF1A\u91CC\u7A0B\u7891\u7C7B\u578B\uFF08create / progress / milestone / problem / solution / decision / review / completed / workflow_extracted\uFF09\n- **milestone_title**\uFF1A\u91CC\u7A0B\u7891\u6807\u9898\uFF08\u4E00\u884C\uFF09\n- **milestone_description**\uFF1A\u8FBE\u6210\u7684\u72B6\u6001/\u7ED3\u679C\u63CF\u8FF0\uFF08\u53EF\u957F\u53EF\u77ED\uFF09\n\n#### \u7EF4\u5EA6 2\uFF1A\u8FC7\u7A0B\uFF08\"\u5982\u4F55\u8FBE\u5230\"\uFF09\u2014 \u53EF\u9009\u4F46\u63A8\u8350\u7EF4\u5EA6\n\u4F7F\u7528 `task_operation_create` \u7684 `process_description` \u5B57\u6BB5\uFF1A\n- \u5B57\u7B26\u8303\u56F4\u786C\u7EA6\u675F 100-500 \u5B57\u7B26 (100\u2013500 characters)\n- \u5185\u5BB9\uFF1A\u91C7\u53D6\u7684\u7B56\u7565 + \u5DE5\u5177\u6B65\u9AA4\u6982\u8981\n- \u5B8C\u6574\u8FC7\u7A0B\u901A\u8FC7 sessionId \u56DE\u67E5 session\n\n#### \u53CC\u7EF4\u5EA6\u914D\u5408\u94C1\u5F8B\n- \u274C **\u4E0D\u8981\u628A action \u5F53\u72B6\u6001**\uFF1A\u65E7 `action_*` \u547D\u540D\u504F\u52A8\u4F5C/\u884C\u4E3A\u5C42\uFF0C\u4E0D\u80FD\u8868\u8FBE\"\u6B64\u523B\u8FBE\u5230\u4EC0\u4E48\"\uFF1B\u73B0\u5728\u7EDF\u4E00\u6539\u7528 `milestone_*`\u3002\n- \u274C **\u4E0D\u8981\u8BA9 process_description \u4E0E milestone_description \u91CD\u590D**\uFF1Aprocess \u662F\"\u5982\u4F55\u8FBE\u5230\"\uFF0Cmilestone \u662F\"\u8FBE\u5230\u4EC0\u4E48\u72B6\u6001\"\u3002\n- \u2705 **\u914D\u5957\u8BB0\u5F55**\uFF1A\u6BCF\u4E2A\u6709\u610F\u4E49\u7684 operation \u90FD\u5E94\u540C\u65F6\u5305\u542B\u4E24\u8005\uFF1B\u4E0D\u5199 process \u65F6\uFF0Cdetail \u5E94\u901A\u8FC7 sessionId \u56DE\u67E5\u3002\n- \u26A0\uFE0F **\u517C\u5BB9\u7A97\u53E3\u671F**\uFF1A\u65E7 `action_type` / `action_title` / `action_description` \u4ECD\u88AB tool \u63A5\u53D7\uFF08\u6807\u8BB0 @deprecated\uFF09\uFF0C\u4F1A\u81EA\u52A8\u6620\u5C04\u5230 milestone_* \u5E76\u8FD4\u56DE deprecation warning\u3002\n\n#### \u8303\u4F8B\uFF08\u53CC\u7EF4\u5EA6\u9F50\u5168\u7684 operation \u8BB0\u5F55\uFF09\n```json\n{\n \"task_id\": 123,\n \"milestone_type\": \"milestone\",\n \"milestone_title\": \"GREEN \u901A\u8FC7\uFF1Amilestone_* schema/storage/tool \u5168\u94FE\u8DEF\",\n \"milestone_description\": \"21/21 \u6D4B\u8BD5\u901A\u8FC7\uFF0C\u5305\u542B 4 \u4E2A action_* alias \u517C\u5BB9\u6D4B\u8BD5\",\n \"process_description\": \"TDD RED \u5199 4 \u4E2A\u5931\u8D25\u6D4B\u8BD5\u8986\u76D6 storage/tool\uFF1B\u8FC1\u79FB 004 rename \u5217\uFF1BrowToOperation \u540C\u65F6\u8F93\u51FA\u53CC\u5B57\u6BB5\u517C\u5BB9\uFF1Btool zod preprocess \u81EA\u52A8\u6620\u5C04 action_*\"\n}\n```";
|
|
27
27
|
/** 分片 3:goals 编号子项规则(M7/M8/M9) */
|
|
28
28
|
export declare const TASK_DISCIPLINE_GOALS = "### Goals \u5B50\u9879\u62C6\u5206\u89C4\u5219\n\n`goals_and_expected_deliverables` **MUST** be written as\n**numbered sub-items** (\u7F16\u53F7\u5B50\u9879) that can each be verified\none by one (\u9010\u6761\u9A8C\u6536) \u2014 for `type=normal` tasks:\n\n1. \u5B9E\u73B0 X\uFF08\u542B\u6587\u4EF6\u8DEF\u5F84\uFF09\n2. \u6D4B\u8BD5 Y \u8986\u76D6 Z \u573A\u666F\uFF08pass/fail \u8BA1\u6570\uFF09\n3. \u6587\u6863 W \u843D\u76D8\u5230 <path>\n\n\u26A0\uFE0F For `type=longterm` / `type=cycle` tasks there is no\nper-item completion acceptance\uFF08\u4E0D\u8D70\u9010\u6761 complete \u9A8C\u6536\uFF09, so the\nMUST above does not apply; for those, it is **strongly recommended**\n(\u5EFA\u8BAE) to split goals into staged, individually checkable sub-items\n(\u9636\u6BB5\u6027\u53EF\u5224\u5B50\u9879) instead of one vague sentence.\n\nWhy: when the task is completed, the completion hook\n(task:after.complete) judges the whole goal against the\noperation-record chain, using each sub-item as fine-grained\nevidence (\u9010\u6761\u5BF9\u7167\u7684\u4F9D\u636E). Vague one-line goals (\u4E00\u53E5\u8BDD\u6A21\u7CCA\u76EE\u6807\uFF0C\n\u5982\u300C\u505A\u597D X\u300D\u300C\u5B8C\u6210\u8C03\u7814\u300D) give the judge nothing to check\nand make a completion hint much more likely.\n\nReference the four atomic assertion forms (Task #4768\n\u56DB\u539F\u5B50\u5F62\u6001) when writing each sub-item:\n\n- \u6587\u4EF6\u65AD\u8A00 (file assertion): file exists / size / content grep\n- \u8FDB\u7A0B\u65AD\u8A00 (process assertion): command exit code / stdout match\n- \u6D4B\u8BD5\u65AD\u8A00 (test assertion): pass/fail counts, no NEW fail\n- \u72B6\u6001\u65AD\u8A00 (state assertion): version number / HTTP 200 / status field";
|
|
29
|
-
/** 分片 4:complete 逐条验收 + HINT 核实义务(M10/M11/M12)
|
|
30
|
-
|
|
29
|
+
/** 分片 4:complete 逐条验收 + HINT 核实义务(M10/M11/M12)
|
|
30
|
+
*
|
|
31
|
+
* ★ Task #5007 —— 角色作用域说明:
|
|
32
|
+
* 本分片描述的是**验收方**(default agent / 接待员)的动作。
|
|
33
|
+
* 执行方(roy sub-agent)**没有** `task_complete` 权限,不适用本分片。
|
|
34
|
+
* 为避免执行方误读,段落开头显式声明「仅验收方适用」。
|
|
35
|
+
*/
|
|
36
|
+
export declare const TASK_DISCIPLINE_COMPLETE = "### Task Complete \u2014 \u6838\u5B9E\u4E49\u52A1\uFF08**\u4EC5\u9A8C\u6536\u65B9\u9002\u7528**\uFF09\n\n> \u26A0\uFE0F **\u89D2\u8272\u4F5C\u7528\u57DF\uFF08Task #5007\uFF09**\uFF1A\u672C\u8282\u662F**\u9A8C\u6536\u65B9**\uFF08default agent / \u63A5\u5F85\u5458\uFF09\u7684\u52A8\u4F5C\u3002\n> \u82E5\u4F60\u662F**\u6267\u884C\u65B9**\uFF08roy sub-agent\uFF09\uFF0C\u4F60\u6CA1\u6709 `task_complete` \u6743\u9650 \u2014\u2014\n> \u4F60\u7684\u6536\u5C3E\u52A8\u4F5C\u662F\u300C\u8FDB\u5EA6\u63A8\u5230 100% + \u8BB0\u5B8C\u64CD\u4F5C\u8BB0\u5F55 + \u7ED3\u675F\u8FD4\u56DE\u300D\uFF0C\u9A8C\u6536\u7531\u4E3B\u667A\u80FD\u4F53\u8D1F\u8D23\u3002\n\nBefore calling `task_complete`, you MUST:\n\n1. Read the task's `goal` (description) and `delivery` (goals_and_expected_deliverables) fields.\n - Use `task_get(task_id=<id>)` to fetch the full task record.\n2. **Validate whether each goal sub-item was achieved** \u2014 accept the goal\n **item-by-item** (\u6309\u5B50\u9879\u9010\u6761\u9A8C\u6536).\n - Goals should be numbered sub-items (\u7F16\u53F7\u5B50\u9879). Check\n each sub-item against the operation-record chain (\u64CD\u4F5C\u8BB0\u5F55\u94FE) and the\n deliverable evidence (context.deliverable_storage_path).\n - The completion hook (task:after.complete) judges the whole goal vs.\n deliverables; numbered sub-items give it finer-grained evidence to\n reason with (\u9010\u6761\u5BF9\u7167\u7684\u8BC1\u636E\u7C92\u5EA6). If it detects that the goal or\n deliverables appear unmet, the task context will carry a\n `[TASK_COMPLETION_HINT]`.\n - **If you receive a [TASK_COMPLETION_HINT]**, you MUST verify it\n (\u6838\u5B9E\u4E49\u52A1): re-read the task via `task_get`, then do exactly one of:\n (a) \u786E\u8BA4\u672A\u5B8C\u6210 \u2192 **\u91CD\u65B0\u59D4\u6258**\uFF08\u7528\u4F60\u7684\u59D4\u6258\u5DE5\u5177 + \u540C\u4E00 sub-session \u7EED\u8DD1\uFF0C\n \u5728\u6307\u4EE4\u91CC\u5199\u660E\"\u76EE\u6807\u5C1A\u672A\u8FBE\u6210\uFF0C\u9700\u8981\u8865 X/Y/Z\"\uFF09\uFF0C\u7531 sub-agent \u7528\n `task_update(status=active)` \u91CD\u5F00\u5E76\u7EE7\u7EED\u63A8\u8FDB\uFF1B\u82E5\u4F60**\u81EA\u5DF1\u5C31\u662F\u6267\u884C\u65B9**\n \uFF08\u6709 `task_update` \u6743\u9650\uFF09\uFF0C\u5219\u76F4\u63A5 `task_update(status=todo)` \u91CD\u5F00\uFF1B\u6216\n (b) \u786E\u8BA4\u5DF2\u5B8C\u6210 \u2192 **\u7528\u4F60\u624B\u4E0A\u6709\u6743\u9650\u7684\u5199\u5DE5\u5177**\u843D\u4E00\u6761 `decision` \u7C7B\u64CD\u4F5C\u8BB0\u5F55\n \uFF08`task_operation_create`\uFF0Cmilestone_type=decision\uFF0Cmilestone_title=<\u4E00\u884C\u7ED3\u8BBA>\uFF09\n \u8BF4\u660E\u5B50\u9879\u5B9E\u9645\u5DF2\u8FBE\u6210\uFF08\u8BF4\u660E\u7406\u7531\uFF09\u3002\u82E5\u4F60\u6CA1\u6709\u8BE5\u5DE5\u5177\u7684\u6743\u9650\uFF08\u9A8C\u6536\u65B9\u573A\u666F\uFF09\uFF0C\n \u5C31\u901A\u8FC7\u4F60\u7684**\u59D4\u6258\u5DE5\u5177**\u8BA9 sub-agent \u4EE3\u5199\u8FD9\u6761\u8BB0\u5F55\uFF0C\u6216\u5728 `task_complete`\n \u7684 `deliverable_storage_path` / \u6700\u7EC8\u6C47\u62A5\u91CC\u660E\u786E\u5199\u51FA\u6838\u5B9E\u7ED3\u8BBA\u4E0E\u8BC1\u636E\u3002\n Never ignore it (\u4E0D\u5141\u8BB8\u65E0\u89C6).\n \u26A0\uFE0F **\u6838\u5B9E\u4E49\u52A1\u7684\u4E24\u6761\u8DEF\u5F84\u90FD\u4F9D\u8D56\u5199\u6743\u9650**\uFF08`task_update` / `task_operation_create`\uFF09\u3002\n \u82E5\u8FD9\u4E9B\u5DE5\u5177\u5BF9\u4F60**\u4E0D\u53EF\u7528**\uFF08\u5982\u9A8C\u6536\u65B9\u4E0D\u6301\u6709\u6267\u884C\u7C7B\u5DE5\u5177\uFF09\uFF0C\u5FC5\u987B**\u6539\u7528\u59D4\u6258**\u628A\u52A8\u4F5C\n \u4EA4\u56DE\u7ED9\u6709\u6743\u9650\u7684 sub-agent \u6267\u884C \u2014\u2014 \u4E0D\u8981\u8BD5\u56FE\u8C03\u7528\u4E0D\u53EF\u7528\u7684\u5DE5\u5177\uFF08\u4F1A\u88AB\u62E6\u6389\u5E76\u6D6A\u8D39\u4E00\u8F6E\u8FED\u4EE3\uFF09\u3002\n - If the goal and delivery mismatch **without** a hint, either:\n (a) extend the task via `task_update`, or\n (b) record the discrepancy via `task_operation_create`\n (milestone_type=decision) \u2014 the reason **must** land in the\n operation record (\u5FC5\u987B\u843D\u5230\u64CD\u4F5C\u8BB0\u5F55\u91CC), not merely a line in\n your final report (\u4E0D\u80FD\u53EA\u5728\u62A5\u544A\u91CC\u5E26\u4E00\u53E5).\n3. **Provide `deliverable_storage_path`** parameter with the deliverable's address.\n It may name **multiple paths** (multiple deliverables), space-separated\n (`/tmp/report.md /tmp/diff.patch`) \u2014 the judge splits on whitespace as\n well as `,` `;` `\u3001` and ` + `. A local path may also be written in its\n `file://` form (`file:///tmp/report.md`) \u2014 the scheme is stripped and the\n path kept. Declare **every** artefact you produced: a path left out reads\n as \"not produced\".\n - Feishu doc URL (e.g., https://my.feishu.cn/docx/abc)\n - Local file path (e.g., /tmp/report.md)\n - Git branch or worktree path (e.g., feature/my-feature)\n - GitHub commit URL or PR URL\n - Cloud drive URL (e.g., https://my.feishu.cn/file/abc)\n - Or any other locator that points to where the work product lives\n\nThe `deliverable_storage_path` will be persisted to the task's\n`context.deliverable_storage_path` for future reference and traceability.";
|
|
31
37
|
/** 完整纪律正文(主出口):4 分片拼装 */
|
|
32
38
|
export declare const TASK_DISCIPLINE_PROMPT: string;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Task Cancel Tool (Task #5007)
|
|
3
|
+
*
|
|
4
|
+
* 架构背景 —— 验收权从 roy sub-agent 移交 default agent(接待员):
|
|
5
|
+
*
|
|
6
|
+
* 原本「验收」与「执行」都在 roy sub-agent 手里(裁判和运动员同一人),
|
|
7
|
+
* 且 sub-agent 超时 / 未更新状态时任务状态会长期不同步。
|
|
8
|
+
* 调整后 default agent 承担验收:
|
|
9
|
+
* - task_complete —— 核对产出后判定完成(触发 goal 检查 decision model)
|
|
10
|
+
* - task_cancel —— 验收不通过 / 用户要求时取消任务
|
|
11
|
+
*
|
|
12
|
+
* 本工具的职责边界:
|
|
13
|
+
* - **取消 Task 本身**(task.status = "cancelled")
|
|
14
|
+
* - **不是**停后台进程 —— 那是 `stop_task` 的职责(stop_task 停 bg process,
|
|
15
|
+
* task_cancel 停 Task 记录)。两者正交,default agent 可能需要连用:
|
|
16
|
+
* 先 stop_task 掐掉还在跑的 sub-agent,再 task_cancel 取消任务记录。
|
|
17
|
+
*
|
|
18
|
+
* 终态 hook:`cancelled` 属于 TASK_COMPLETE_TERMINAL_STATUSES
|
|
19
|
+
* ⇒ 走 taskComponent.updateTask ⇒ 自动 fire AFTER_COMPLETE
|
|
20
|
+
* ⇒ 飞书终态通知 / lark-card 状态机正常收敛,无需额外接线。
|
|
21
|
+
*/
|
|
22
|
+
import type { Tool } from "../../tool/types";
|
|
23
|
+
import type { TaskComponent } from "../task-component";
|
|
24
|
+
/**
|
|
25
|
+
* task_cancel 工具描述(导出便于单测和未来 reuse)
|
|
26
|
+
*/
|
|
27
|
+
export declare const TASK_CANCEL_DESCRIPTION: string;
|
|
28
|
+
export declare function cancelTaskTool(taskComponent: TaskComponent): Tool;
|
|
@@ -10,4 +10,5 @@ export { batchDeleteTaskTool } from "./batch-delete-tool";
|
|
|
10
10
|
export { updateTaskTool } from "./update-tool";
|
|
11
11
|
export { deleteTaskTool } from "./delete-tool";
|
|
12
12
|
export { completeTaskTool } from "./complete-tool";
|
|
13
|
+
export { cancelTaskTool } from "./cancel-tool";
|
|
13
14
|
export { treeTasksTool } from "./task-tree-tool";
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
batchArchiveTaskTool,
|
|
3
3
|
batchDeleteTaskTool,
|
|
4
|
+
cancelTaskTool,
|
|
4
5
|
completeTaskTool,
|
|
5
6
|
createTaskTool,
|
|
6
7
|
deleteTaskTool,
|
|
@@ -9,9 +10,9 @@ import {
|
|
|
9
10
|
searchTasksTool,
|
|
10
11
|
treeTasksTool,
|
|
11
12
|
updateTaskTool
|
|
12
|
-
} from "../../../shared/@ai-setting/roy-agent-core-
|
|
13
|
+
} from "../../../shared/@ai-setting/roy-agent-core-hnyk1by7.js";
|
|
13
14
|
import"../../../shared/@ai-setting/roy-agent-core-tr3ep81v.js";
|
|
14
|
-
import"../../../shared/@ai-setting/roy-agent-core-
|
|
15
|
+
import"../../../shared/@ai-setting/roy-agent-core-11shp00p.js";
|
|
15
16
|
import"../../../shared/@ai-setting/roy-agent-core-7cbpmk4q.js";
|
|
16
17
|
import"../../../shared/@ai-setting/roy-agent-core-qq96p0tj.js";
|
|
17
18
|
import"../../../shared/@ai-setting/roy-agent-core-7f7t9wwp.js";
|
|
@@ -26,6 +27,7 @@ export {
|
|
|
26
27
|
deleteTaskTool,
|
|
27
28
|
createTaskTool,
|
|
28
29
|
completeTaskTool,
|
|
30
|
+
cancelTaskTool,
|
|
29
31
|
batchDeleteTaskTool,
|
|
30
32
|
batchArchiveTaskTool
|
|
31
33
|
};
|
|
@@ -248,6 +248,28 @@ export declare const CompleteTaskToolSchema: z.ZodEffects<z.ZodObject<{
|
|
|
248
248
|
deliverable_storage_path?: string | undefined;
|
|
249
249
|
}, unknown>;
|
|
250
250
|
export type CompleteTaskToolParams = z.infer<typeof CompleteTaskToolSchema>;
|
|
251
|
+
/**
|
|
252
|
+
* task_cancel tool parameters (Task #5007)
|
|
253
|
+
*
|
|
254
|
+
* 取消 Task 本身(status = "cancelled")。
|
|
255
|
+
* ⚠️ 与 `stop_task` 正交:stop_task 停**后台进程**(bg process id),
|
|
256
|
+
* task_cancel 停**任务记录**(task id)。需要连用时先 stop_task 再 task_cancel。
|
|
257
|
+
*/
|
|
258
|
+
export declare const CancelTaskToolSchema: z.ZodEffects<z.ZodObject<{
|
|
259
|
+
task_id: z.ZodNumber;
|
|
260
|
+
} & {
|
|
261
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
262
|
+
}, "strip", z.ZodTypeAny, {
|
|
263
|
+
task_id: number;
|
|
264
|
+
reason?: string | undefined;
|
|
265
|
+
}, {
|
|
266
|
+
task_id: number;
|
|
267
|
+
reason?: string | undefined;
|
|
268
|
+
}>, {
|
|
269
|
+
task_id: number;
|
|
270
|
+
reason?: string | undefined;
|
|
271
|
+
}, unknown>;
|
|
272
|
+
export type CancelTaskToolParams = z.infer<typeof CancelTaskToolSchema>;
|
|
251
273
|
/**
|
|
252
274
|
* task_batch_archive tool parameters
|
|
253
275
|
*/
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview compact_session — Default Agent sub-session 压缩工具
|
|
3
|
+
*
|
|
4
|
+
* Task #4982 — 用户需求:
|
|
5
|
+
* 「给 Default agent 添加一个压缩 session 的工具,遇到 sub-agent
|
|
6
|
+
* 返回上下文超了的问题,可以用这个工具来压缩 sub-session,
|
|
7
|
+
* 继续复用 session」
|
|
8
|
+
*
|
|
9
|
+
* 背景(真实踩坑):
|
|
10
|
+
* Default agent 通过 delegate_task 委托子代理,sub-session 积累大量
|
|
11
|
+
* 上下文。当 sub-agent 返回 Context threshold exceeded(如
|
|
12
|
+
* 125575/120000 = 104.6%)时,default agent 只能用
|
|
13
|
+
* delegate_task(sub_session_id=...) 续跑 —— 但被污染/过长的
|
|
14
|
+
* sub-session 续跑会再次超限。本工具让 default agent 先压缩
|
|
15
|
+
* sub-session(生成 checkpoint、归档旧消息),再继续复用。
|
|
16
|
+
*
|
|
17
|
+
* 可见性:
|
|
18
|
+
* - metadata.allowedAgentTypes: ["default"] — 只对 default 接待员可见
|
|
19
|
+
* - 其他 agent(roy / strict-task-agent / explore 等)看不到
|
|
20
|
+
*
|
|
21
|
+
* 安全设计(四层):
|
|
22
|
+
* 1. deps 未注入 → success=false, error="not initialized"
|
|
23
|
+
* 2. 压缩当前会话 → success=false(default agent 自毁上下文防线)
|
|
24
|
+
* 3. session 不存在 / 非自己的 sub-session → status='not_found'
|
|
25
|
+
* (不暴露存在性,与 query_background_process 同一哲学)
|
|
26
|
+
* 4. 后台任务 running/pending → success=false(sub-session 每轮
|
|
27
|
+
* ReAct 增量落盘(Task #4720 Fix A),与归档竞态会撕裂任务状态)
|
|
28
|
+
*
|
|
29
|
+
* 复用闭环:
|
|
30
|
+
* compact_session 压缩后,用
|
|
31
|
+
* delegate_task(subagentType=..., sub_session_id=<同 id>, prompt=...) 续跑。
|
|
32
|
+
*
|
|
33
|
+
* 注入方式(2026-11-05,与 query_background_process 同模式):
|
|
34
|
+
* - createCompactSessionTool(manager, sessionComponent) 工厂闭包注入
|
|
35
|
+
* - TaskComponent.start() 注册 manager-bound 实例;stop() 注销为 null 版本
|
|
36
|
+
* - getAllBuiltInTools() 中的默认版本为 null-deps(执行即 not initialized)
|
|
37
|
+
*
|
|
38
|
+
* 输出(JSON 字符串):
|
|
39
|
+
* {
|
|
40
|
+
* status: 'compacted' | 'not_found',
|
|
41
|
+
* sessionId: string,
|
|
42
|
+
* checkpointId?: string,
|
|
43
|
+
* checkpointTitle?: string,
|
|
44
|
+
* contentLength?: number,
|
|
45
|
+
* originalMessages?: number, // 压缩前可压缩消息数
|
|
46
|
+
* deletedMessages?: number, // 归档条数
|
|
47
|
+
* remainingMessages?: number, // 归档后剩余活跃消息数
|
|
48
|
+
* hintUsed?: boolean, // phase1 hint 是否注入
|
|
49
|
+
* }
|
|
50
|
+
*
|
|
51
|
+
* 失败行为:
|
|
52
|
+
* - manager / sessionComponent 未注入 → success=false
|
|
53
|
+
* - zod 参数校验失败 → throw(ToolComponent 捕获)
|
|
54
|
+
* - previewCompact / compact 抛错 → success=false, error=原始 message
|
|
55
|
+
* - generateCompactHint 抛错 → 容错(hint 为空串,不阻塞压缩)
|
|
56
|
+
*/
|
|
57
|
+
import type { Tool } from "../types";
|
|
58
|
+
import type { BackgroundTaskManager, BackgroundTask } from "../../task/delegate/delegate-tool";
|
|
59
|
+
import type { SessionComponent } from "../../session/session-component";
|
|
60
|
+
/**
|
|
61
|
+
* 成功压缩的输出
|
|
62
|
+
*/
|
|
63
|
+
export interface CompactSessionOutput {
|
|
64
|
+
status: "compacted" | "not_found";
|
|
65
|
+
sessionId: string;
|
|
66
|
+
checkpointId?: string;
|
|
67
|
+
checkpointTitle?: string;
|
|
68
|
+
contentLength?: number;
|
|
69
|
+
originalMessages?: number;
|
|
70
|
+
deletedMessages?: number;
|
|
71
|
+
remainingMessages?: number;
|
|
72
|
+
hintUsed?: boolean;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* not_found 输出(不暴露存在性)
|
|
76
|
+
*/
|
|
77
|
+
export declare function compactSessionNotFoundOutput(sessionId: string): CompactSessionOutput;
|
|
78
|
+
/**
|
|
79
|
+
* 在 manager 的任务表里查找 sub-session 归属的任务。
|
|
80
|
+
*
|
|
81
|
+
* - 优先按 subSessionId 反查(工具入参就是 sub-session id)
|
|
82
|
+
* - 再回退 getTask(兼容直接传 bgProcessId 的误用场景)
|
|
83
|
+
*
|
|
84
|
+
* 返回 undefined 表示没有任何任务关联该 session。
|
|
85
|
+
*/
|
|
86
|
+
export declare function findTaskBySubSessionId(manager: Pick<BackgroundTaskManager, "getTask" | "listTasks">, sessionId: string): BackgroundTask | undefined;
|
|
87
|
+
/**
|
|
88
|
+
* ownership 校验:
|
|
89
|
+
* 该 session 是否是「当前会话自己 delegate 出去的 sub-session」。
|
|
90
|
+
*
|
|
91
|
+
* 规则:task 存在 且 task.parentSessionId === ctx.session_id。
|
|
92
|
+
* (delegate_tool 创建 sub-session 时把 parentSessionId 写成
|
|
93
|
+
* ctx.session_id —— 见 createTask。)
|
|
94
|
+
*/
|
|
95
|
+
export declare function isOwnSubSession(task: BackgroundTask | undefined, currentSessionId: string | undefined): boolean;
|
|
96
|
+
/**
|
|
97
|
+
* 该 session 是否属于一个仍在运行中的后台任务。
|
|
98
|
+
* running/pending 的 sub-session 正在被 sub-agent 每轮增量落盘,
|
|
99
|
+
* 此时归档旧消息会产生竞态(归档读到的窗口与 sub-agent 正在写的窗口冲突)。
|
|
100
|
+
*/
|
|
101
|
+
export declare function isTaskActive(task: BackgroundTask | undefined): boolean;
|
|
102
|
+
/**
|
|
103
|
+
* 工厂函数 — 创建 deps-bound 工具实例。
|
|
104
|
+
*
|
|
105
|
+
* @param backgroundTaskManager BackgroundTaskManager 实例(查任务归属 / 判运行中);
|
|
106
|
+
* 传 null 表示未注入
|
|
107
|
+
* @param sessionComponent SessionComponent 实例(执行压缩);传 null 表示未注入
|
|
108
|
+
*/
|
|
109
|
+
export declare function createCompactSessionTool(backgroundTaskManager?: BackgroundTaskManager | null, sessionComponent?: SessionComponent | null): Tool;
|
|
110
|
+
/**
|
|
111
|
+
* compact_session 工具的"无 deps"实例。
|
|
112
|
+
*
|
|
113
|
+
* 历史:与 queryBackgroundProcessTool 同模式 ——
|
|
114
|
+
* - 实际注入的 deps 通过 createCompactSessionTool(manager, sessionComponent)
|
|
115
|
+
* 工厂绑定;TaskComponent.start() 会用它重新注册真正的实例到
|
|
116
|
+
* ToolComponent,覆盖此 no-deps 版本。
|
|
117
|
+
* - 此 named export 保留用于 getAllBuiltInTools() 注册与向后兼容;
|
|
118
|
+
* 它绑定 null deps → 执行时返回 "not initialized" 错误。
|
|
119
|
+
*/
|
|
120
|
+
export declare const compactSessionTool: Tool;
|
|
@@ -8,6 +8,7 @@ import { editFileTool } from "./edit-file";
|
|
|
8
8
|
import { grepTool } from "./grep";
|
|
9
9
|
import { understandImageTool } from "./understand-image";
|
|
10
10
|
import { createQueryBackgroundProcessTool } from "./query-background-process-tool";
|
|
11
|
+
import { createCompactSessionTool, compactSessionTool } from "./compact-session-tool";
|
|
11
12
|
export { bashTool };
|
|
12
13
|
export { echoTool };
|
|
13
14
|
export { globTool };
|
|
@@ -18,6 +19,7 @@ export { grepTool };
|
|
|
18
19
|
export { understandImageTool };
|
|
19
20
|
import { queryBackgroundProcessTool } from "./query-background-process-tool";
|
|
20
21
|
export { queryBackgroundProcessTool, createQueryBackgroundProcessTool };
|
|
22
|
+
export { compactSessionTool, createCompactSessionTool };
|
|
21
23
|
export { setUnderstandImageLLMProvider, getUnderstandImageLLMProvider, resetUnderstandImageLLMProvider, type UnderstandImageLLMProvider, } from "./understand-image";
|
|
22
24
|
/**
|
|
23
25
|
* 获取所有内置工具
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
grepTool,
|
|
9
9
|
readFileTool,
|
|
10
10
|
writeFileTool
|
|
11
|
-
} from "../../../shared/@ai-setting/roy-agent-core-
|
|
11
|
+
} from "../../../shared/@ai-setting/roy-agent-core-8ez6mccb.js";
|
|
12
12
|
import {
|
|
13
13
|
getUnderstandImageLLMProvider,
|
|
14
14
|
resetUnderstandImageLLMProvider,
|
|
@@ -16,9 +16,11 @@ import {
|
|
|
16
16
|
understandImageTool
|
|
17
17
|
} from "../../../shared/@ai-setting/roy-agent-core-xwm8zavb.js";
|
|
18
18
|
import {
|
|
19
|
+
compactSessionTool,
|
|
20
|
+
createCompactSessionTool,
|
|
19
21
|
createQueryBackgroundProcessTool,
|
|
20
22
|
queryBackgroundProcessTool
|
|
21
|
-
} from "../../../shared/@ai-setting/roy-agent-core-
|
|
23
|
+
} from "../../../shared/@ai-setting/roy-agent-core-2akfd64z.js";
|
|
22
24
|
import"../../../shared/@ai-setting/roy-agent-core-fttgm52a.js";
|
|
23
25
|
import"../../../shared/@ai-setting/roy-agent-core-zjdzk1gg.js";
|
|
24
26
|
import"../../../shared/@ai-setting/roy-agent-core-qq96p0tj.js";
|
|
@@ -40,5 +42,7 @@ export {
|
|
|
40
42
|
editFileTool,
|
|
41
43
|
echoTool,
|
|
42
44
|
createQueryBackgroundProcessTool,
|
|
45
|
+
createCompactSessionTool,
|
|
46
|
+
compactSessionTool,
|
|
43
47
|
bashTool
|
|
44
48
|
};
|
package/dist/env/tool/index.js
CHANGED
|
@@ -10,14 +10,14 @@ import {
|
|
|
10
10
|
grepTool,
|
|
11
11
|
readFileTool,
|
|
12
12
|
writeFileTool
|
|
13
|
-
} from "../../shared/@ai-setting/roy-agent-core-
|
|
13
|
+
} from "../../shared/@ai-setting/roy-agent-core-8ez6mccb.js";
|
|
14
14
|
import {
|
|
15
15
|
getUnderstandImageLLMProvider,
|
|
16
16
|
resetUnderstandImageLLMProvider,
|
|
17
17
|
setUnderstandImageLLMProvider,
|
|
18
18
|
understandImageTool
|
|
19
19
|
} from "../../shared/@ai-setting/roy-agent-core-xwm8zavb.js";
|
|
20
|
-
import"../../shared/@ai-setting/roy-agent-core-
|
|
20
|
+
import"../../shared/@ai-setting/roy-agent-core-2akfd64z.js";
|
|
21
21
|
import"../../shared/@ai-setting/roy-agent-core-fttgm52a.js";
|
|
22
22
|
import {
|
|
23
23
|
ToolComponent,
|
|
@@ -25,10 +25,10 @@ import {
|
|
|
25
25
|
ToolValidator,
|
|
26
26
|
getMaxOutputSize,
|
|
27
27
|
setToolConfigComponent
|
|
28
|
-
} from "../../shared/@ai-setting/roy-agent-core-
|
|
28
|
+
} from "../../shared/@ai-setting/roy-agent-core-v85n42ve.js";
|
|
29
29
|
import"../../shared/@ai-setting/roy-agent-core-jvv2h3d6.js";
|
|
30
30
|
import"../../shared/@ai-setting/roy-agent-core-zjdzk1gg.js";
|
|
31
|
-
import"../../shared/@ai-setting/roy-agent-core-
|
|
31
|
+
import"../../shared/@ai-setting/roy-agent-core-mkc3zshb.js";
|
|
32
32
|
import"../../shared/@ai-setting/roy-agent-core-7hh0brvs.js";
|
|
33
33
|
import"../../shared/@ai-setting/roy-agent-core-pgvcf91v.js";
|
|
34
34
|
import"../../shared/@ai-setting/roy-agent-core-ax9e9szb.js";
|
|
@@ -5,21 +5,20 @@ import {
|
|
|
5
5
|
Scheduler,
|
|
6
6
|
WorkflowEngine,
|
|
7
7
|
init_engine
|
|
8
|
-
} from "../../../shared/@ai-setting/roy-agent-core-
|
|
8
|
+
} from "../../../shared/@ai-setting/roy-agent-core-6rh8k6ba.js";
|
|
9
9
|
import"../../../shared/@ai-setting/roy-agent-core-6atd905e.js";
|
|
10
|
-
import"../../../shared/@ai-setting/roy-agent-core-
|
|
10
|
+
import"../../../shared/@ai-setting/roy-agent-core-dqxec05w.js";
|
|
11
11
|
import"../../../shared/@ai-setting/roy-agent-core-efkjyh69.js";
|
|
12
12
|
import"../../../shared/@ai-setting/roy-agent-core-1db4vpc6.js";
|
|
13
|
-
import"../../../shared/@ai-setting/roy-agent-core-ze068vc9.js";
|
|
14
13
|
import"../../../shared/@ai-setting/roy-agent-core-dvtg4sn0.js";
|
|
15
14
|
import"../../../shared/@ai-setting/roy-agent-core-c2gbt68e.js";
|
|
16
|
-
import"../../../shared/@ai-setting/roy-agent-core-
|
|
15
|
+
import"../../../shared/@ai-setting/roy-agent-core-acj8ag08.js";
|
|
17
16
|
import"../../../shared/@ai-setting/roy-agent-core-ddwa0n6h.js";
|
|
18
17
|
import {
|
|
19
18
|
DAGManager
|
|
20
|
-
} from "../../../shared/@ai-setting/roy-agent-core-
|
|
21
|
-
import"../../../shared/@ai-setting/roy-agent-core-
|
|
22
|
-
import"../../../shared/@ai-setting/roy-agent-core-
|
|
19
|
+
} from "../../../shared/@ai-setting/roy-agent-core-cgtq6427.js";
|
|
20
|
+
import"../../../shared/@ai-setting/roy-agent-core-er070zjq.js";
|
|
21
|
+
import"../../../shared/@ai-setting/roy-agent-core-mkc3zshb.js";
|
|
23
22
|
import"../../../shared/@ai-setting/roy-agent-core-ax9e9szb.js";
|
|
24
23
|
import"../../../shared/@ai-setting/roy-agent-core-cpcd24n2.js";
|
|
25
24
|
import"../../../shared/@ai-setting/roy-agent-core-qqaak24r.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
WorkflowComponent
|
|
3
|
-
} from "../../shared/@ai-setting/roy-agent-core-
|
|
3
|
+
} from "../../shared/@ai-setting/roy-agent-core-v87njmq7.js";
|
|
4
4
|
import"../../shared/@ai-setting/roy-agent-core-es203w7p.js";
|
|
5
5
|
import {
|
|
6
6
|
Edge,
|
|
@@ -14,24 +14,24 @@ import {
|
|
|
14
14
|
DecoratorNode,
|
|
15
15
|
init_decorator_node
|
|
16
16
|
} from "../../shared/@ai-setting/roy-agent-core-1ce3fqrk.js";
|
|
17
|
-
import"../../shared/@ai-setting/roy-agent-core-
|
|
18
|
-
import"../../shared/@ai-setting/roy-agent-core-
|
|
19
|
-
import"../../shared/@ai-setting/roy-agent-core-
|
|
17
|
+
import"../../shared/@ai-setting/roy-agent-core-mww0mnd9.js";
|
|
18
|
+
import"../../shared/@ai-setting/roy-agent-core-ddyk1rc0.js";
|
|
19
|
+
import"../../shared/@ai-setting/roy-agent-core-0qyrk5k0.js";
|
|
20
20
|
import"../../shared/@ai-setting/roy-agent-core-hhrg314p.js";
|
|
21
21
|
import"../../shared/@ai-setting/roy-agent-core-12n08pg5.js";
|
|
22
|
-
import"../../shared/@ai-setting/roy-agent-core-
|
|
22
|
+
import"../../shared/@ai-setting/roy-agent-core-6cy43nss.js";
|
|
23
|
+
import"../../shared/@ai-setting/roy-agent-core-6rh8k6ba.js";
|
|
23
24
|
import"../../shared/@ai-setting/roy-agent-core-6atd905e.js";
|
|
24
|
-
import"../../shared/@ai-setting/roy-agent-core-
|
|
25
|
+
import"../../shared/@ai-setting/roy-agent-core-dqxec05w.js";
|
|
25
26
|
import"../../shared/@ai-setting/roy-agent-core-efkjyh69.js";
|
|
26
27
|
import"../../shared/@ai-setting/roy-agent-core-1db4vpc6.js";
|
|
27
|
-
import"../../shared/@ai-setting/roy-agent-core-ze068vc9.js";
|
|
28
28
|
import"../../shared/@ai-setting/roy-agent-core-dvtg4sn0.js";
|
|
29
29
|
import"../../shared/@ai-setting/roy-agent-core-c2gbt68e.js";
|
|
30
30
|
import"../../shared/@ai-setting/roy-agent-core-7exqwax1.js";
|
|
31
|
-
import"../../shared/@ai-setting/roy-agent-core-
|
|
32
|
-
import"../../shared/@ai-setting/roy-agent-core-
|
|
31
|
+
import"../../shared/@ai-setting/roy-agent-core-1v4g0d4x.js";
|
|
32
|
+
import"../../shared/@ai-setting/roy-agent-core-acj8ag08.js";
|
|
33
33
|
import"../../shared/@ai-setting/roy-agent-core-ddwa0n6h.js";
|
|
34
|
-
import"../../shared/@ai-setting/roy-agent-core-
|
|
34
|
+
import"../../shared/@ai-setting/roy-agent-core-cgtq6427.js";
|
|
35
35
|
import {
|
|
36
36
|
BaseEventSchema,
|
|
37
37
|
ControlPauseEventSchema,
|
|
@@ -83,10 +83,10 @@ import {
|
|
|
83
83
|
parseWorkflowFileSync,
|
|
84
84
|
pathNotFound,
|
|
85
85
|
unresolvedVariable
|
|
86
|
-
} from "../../shared/@ai-setting/roy-agent-core-
|
|
86
|
+
} from "../../shared/@ai-setting/roy-agent-core-er070zjq.js";
|
|
87
87
|
import"../../shared/@ai-setting/roy-agent-core-rvxg1wps.js";
|
|
88
|
-
import"../../shared/@ai-setting/roy-agent-core-
|
|
89
|
-
import"../../shared/@ai-setting/roy-agent-core-
|
|
88
|
+
import"../../shared/@ai-setting/roy-agent-core-0snm5hc5.js";
|
|
89
|
+
import"../../shared/@ai-setting/roy-agent-core-fghc2m8z.js";
|
|
90
90
|
import"../../shared/@ai-setting/roy-agent-core-zjdzk1gg.js";
|
|
91
91
|
import"../../shared/@ai-setting/roy-agent-core-c1v263jn.js";
|
|
92
92
|
import"../../shared/@ai-setting/roy-agent-core-ntn32q7j.js";
|
|
@@ -94,7 +94,8 @@ import {
|
|
|
94
94
|
AskUserError,
|
|
95
95
|
createNodeInterruptEvent,
|
|
96
96
|
createWorkflowAskUserEvent
|
|
97
|
-
} from "../../shared/@ai-setting/roy-agent-core-
|
|
97
|
+
} from "../../shared/@ai-setting/roy-agent-core-mkc3zshb.js";
|
|
98
|
+
import"../../shared/@ai-setting/roy-agent-core-m880qz3y.js";
|
|
98
99
|
import"../../shared/@ai-setting/roy-agent-core-7hh0brvs.js";
|
|
99
100
|
import"../../shared/@ai-setting/roy-agent-core-pgvcf91v.js";
|
|
100
101
|
import"../../shared/@ai-setting/roy-agent-core-ax9e9szb.js";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
LarkCliWorkflowNotifyHook,
|
|
3
3
|
createLarkCliWorkflowNotifyHook
|
|
4
|
-
} from "../../../shared/@ai-setting/roy-agent-core-
|
|
5
|
-
import"../../../shared/@ai-setting/roy-agent-core-
|
|
4
|
+
} from "../../../shared/@ai-setting/roy-agent-core-p3zv1mx5.js";
|
|
5
|
+
import"../../../shared/@ai-setting/roy-agent-core-nmx9934r.js";
|
|
6
6
|
import"../../../shared/@ai-setting/roy-agent-core-c2gbt68e.js";
|
|
7
7
|
import"../../../shared/@ai-setting/roy-agent-core-ax9e9szb.js";
|
|
8
8
|
import"../../../shared/@ai-setting/roy-agent-core-cpcd24n2.js";
|
|
@@ -3,6 +3,56 @@
|
|
|
3
3
|
*
|
|
4
4
|
* When an AgentNode calls this tool, it throws AskUserError to interrupt
|
|
5
5
|
* the workflow, allowing the workflow to pause and wait for user response.
|
|
6
|
+
*
|
|
7
|
+
* ★ Task #4983 — 无 TTY 场景的 **IM 直连投递**。
|
|
8
|
+
*
|
|
9
|
+
* ## 为什么需要这一段(生产日志铁证)
|
|
10
|
+
*
|
|
11
|
+
* traceId `01a1a68652ee79c9c6508579b504e662`(2026-11-04 20:55:38 → 20:56:09,
|
|
12
|
+
* 飞书 p2p `oc_9406ee012e5b7ae65a7a83314b2f8fbc`):
|
|
13
|
+
*
|
|
14
|
+
* 20:55:38.788 [BackgroundTaskManager] Event published: task.background.ask_user
|
|
15
|
+
* (triggerEventId + replyChannel 都齐 ✅ —— #3147 的 notify 链路完好)
|
|
16
|
+
* 20:55:38.790 cli.query-executor.execute enter: "[通知] ❓ 后台子代理「…」请求用户输入 …"
|
|
17
|
+
* 20:56:09.513 [agent:component] Iteration 1 error
|
|
18
|
+
* {runId:"unknown", nodeId:"unknown", type:"ask-user", name:"AskUserError"}
|
|
19
|
+
* 20:56:09.517 cli.query-executor.execute error: __ASK_USER_ERROR__:{…}
|
|
20
|
+
* ⇒ 此后该 traceId **0 次** lark messages-send / messages-reply
|
|
21
|
+
*
|
|
22
|
+
* 根因链:
|
|
23
|
+
* 1. 本工具只「抛 AskUserError」当作中断信号;
|
|
24
|
+
* 2. 交互层(REPL + readline)在守护进程(无 TTY)里是死的;
|
|
25
|
+
* 3. headless 下没人接这个异常 ⇒ 直接冒泡终止整次查询;
|
|
26
|
+
* 4. `query-executor.ts` 的 `isAskUserError → return` + `error-reply.ts` 的
|
|
27
|
+
* `ask_user` 规则 `notify:false` ⇒ **双重静默**,连失败兜底都不发。
|
|
28
|
+
*
|
|
29
|
+
* ⇒ **问题正文从未离开进程,用户零感知**(用户原话:「sub agent 的 ask_user 被淹没了」)。
|
|
30
|
+
*
|
|
31
|
+
* ## 本次修复(路线 A:工具自己投递)
|
|
32
|
+
*
|
|
33
|
+
* 在抛 AskUserError **之前**,若当前上下文存在可用的 IM 投递目标,
|
|
34
|
+
* 就**自己把问题(含选项)投递过去**,让用户真正看到并能答复。
|
|
35
|
+
*
|
|
36
|
+
* 契约:
|
|
37
|
+
* - C1 无投递目标 → 行为不变(抛 AskUserError,交给 TTY 交互层)
|
|
38
|
+
* - C2 有投递目标 → 先投递,再抛 AskUserError(中断信号保留,agent 本轮终止)
|
|
39
|
+
* - C3 投递失败 → **绝不抛**(不能让投递故障掩盖原始中断语义),只记 warn
|
|
40
|
+
* - C4 投递内容含问题正文 + 选项(用户要能选)
|
|
41
|
+
* - C5 投递目标从 EnvContext 取(replyChannel → envEvent.metadata.replyChannel)
|
|
42
|
+
*
|
|
43
|
+
* ⚠️ **为什么不在 CLI 层兜底**:CLI 层的兜底(query-executor / error-reply)都只能
|
|
44
|
+
* 看到「一次失败的查询」,拿不到「用户到底要回答什么」的结构化信息,而且要靠
|
|
45
|
+
* 规则表区分「TTY 场景该静默 / headless 场景该发」—— 极易再次静默。
|
|
46
|
+
* 在**工具层**投递是唯一能保证「问题一定离开进程」的位置。
|
|
47
|
+
*
|
|
48
|
+
* ⚠️ **TTY 场景不会重复发(精确条件)**:仅当「有可用投递目标
|
|
49
|
+
* (EnvContext.replyChannel 等)**且** TTY 交互层也会打印」时,
|
|
50
|
+
* 用户会同时看到 IM 那条和本地回显那条 ⇒ **两条,这不是 bug**:
|
|
51
|
+
* 投递到 IM 渠道的那条才是「离开进程」的那条;TTY 那条是给本地
|
|
52
|
+
* 用户看的回显。本地 TTY 通常**没有** replyChannel(不投);
|
|
53
|
+
* 有 replyChannel 且需要静音时,可通过
|
|
54
|
+
* `context.metadata.askUserDelivery === "off"` 关闭(workflow 路径
|
|
55
|
+
* 已默认关闭,agent-component-adapter.ts)。
|
|
6
56
|
*/
|
|
7
57
|
import { z } from 'zod';
|
|
8
58
|
import type { ToolInfo } from '../../tool/types';
|
|
@@ -31,5 +81,43 @@ export type AskUserInput = z.infer<typeof AskUserInputSchema>;
|
|
|
31
81
|
* catch and convert to a workflow pause event.
|
|
32
82
|
*/
|
|
33
83
|
export type AskUserTool = ToolInfo<typeof AskUserInputSchema>;
|
|
84
|
+
/**
|
|
85
|
+
* Task #4983 — 从 EnvContext 解析可用的 IM 投递目标。
|
|
86
|
+
*
|
|
87
|
+
* 优先级(与 buildRunEnvContext 的 replyChannel 优先级一致):
|
|
88
|
+
* 1. `envContext.replyChannel`(当前层已构建好的渠道,**带 sendMarkdown/reply 实现**)
|
|
89
|
+
* 2. `envContext.envEvent.metadata.replyChannel`(只有裸字段,没有发送实现)
|
|
90
|
+
*
|
|
91
|
+
* 只有 1 能真正发送(它带 `sendMarkdown` / `reply` 函数)。
|
|
92
|
+
* 2 只提供 chatId/messageId 快照 —— 在 core 层没有 lark-cli 发送器可用,
|
|
93
|
+
* 因此**不作为投递目标**(避免在这里 spawn lark-cli 造成职责外 IO)。
|
|
94
|
+
*/
|
|
95
|
+
interface DeliveryTarget {
|
|
96
|
+
chatId?: string;
|
|
97
|
+
messageId?: string;
|
|
98
|
+
profile?: string;
|
|
99
|
+
/** 真正能发消息的通道(EnvContext.replyChannel) */
|
|
100
|
+
channel?: {
|
|
101
|
+
sendMarkdown?: (text: string) => Promise<void>;
|
|
102
|
+
sendText?: (text: string) => Promise<void>;
|
|
103
|
+
reply?: (content: unknown) => Promise<void>;
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Task #4983 — 渲染投递到用户渠道的正文。
|
|
108
|
+
*
|
|
109
|
+
* 硬要求:
|
|
110
|
+
* - 必须含**问题正文**(用户要看的就是问题)
|
|
111
|
+
* - 必须含**全部选项**(用户要能选)
|
|
112
|
+
* - 必须含**答复指引**(用户不知道回哪儿答)
|
|
113
|
+
* - 绝不渲染 `undefined` / `NaN`
|
|
114
|
+
*/
|
|
115
|
+
export declare function buildAskUserDeliveryText(args: {
|
|
116
|
+
query: string;
|
|
117
|
+
options?: string[];
|
|
118
|
+
requiredConfirm?: boolean;
|
|
119
|
+
}): string;
|
|
120
|
+
export declare function deliverAskUserToChannel(target: DeliveryTarget, text: string): Promise<boolean>;
|
|
34
121
|
export declare const askUserTool: AskUserTool;
|
|
35
122
|
export declare const askUserToolInstance: AskUserTool;
|
|
123
|
+
export {};
|