@ai-setting/roy-agent-core 1.7.76 → 1.7.77

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/dist/env/agent/agent-component.js +2 -2
  2. package/dist/env/agent/index.js +2 -2
  3. package/dist/env/event-source/event-source-handlers.js +6 -6
  4. package/dist/env/event-source/index.js +7 -7
  5. package/dist/env/index.js +11 -11
  6. package/dist/env/task/backend/index.js +37 -1
  7. package/dist/env/task/backend/task-store-backend.d.ts +12 -0
  8. package/dist/env/task/backend/types.d.ts +19 -0
  9. package/dist/env/task/index.js +3 -3
  10. package/dist/env/task/mcp/index.js +3 -0
  11. package/dist/env/task/mcp/task-mcp-server.d.ts +1 -1
  12. package/dist/env/task/plugins/fake-user-message-helper.d.ts +10 -2
  13. package/dist/env/task/plugins/index.d.ts +1 -0
  14. package/dist/env/task/plugins/index.js +15 -4
  15. package/dist/env/task/plugins/lark-card-patch-notifier.js +1 -1
  16. package/dist/env/task/plugins/task-op-watermark-plugin.d.ts +112 -0
  17. package/dist/env/task/storage/index.js +2 -2
  18. package/dist/env/task/storage/sqlite-task-store.d.ts +54 -0
  19. package/dist/env/task/task-component.d.ts +16 -0
  20. package/dist/env/task/tools/operation/operation-types.d.ts +13 -13
  21. package/dist/env/workflow/plugins/index.js +2 -2
  22. package/dist/env/workflow/types/event.d.ts +4 -4
  23. package/dist/index.js +11 -11
  24. package/dist/shared/@ai-setting/{roy-agent-core-cxy143m4.js → roy-agent-core-0v27y99n.js} +1 -1
  25. package/dist/shared/@ai-setting/{roy-agent-core-t3rrb959.js → roy-agent-core-3gpygqcx.js} +3 -3
  26. package/dist/shared/@ai-setting/{roy-agent-core-q5r75vev.js → roy-agent-core-9vhq7fvv.js} +5 -1
  27. package/dist/shared/@ai-setting/{roy-agent-core-zycadbpx.js → roy-agent-core-ew6qb5yx.js} +1 -1
  28. package/dist/shared/@ai-setting/{roy-agent-core-abqhkbn3.js → roy-agent-core-ezvpreqz.js} +23 -0
  29. package/dist/shared/@ai-setting/roy-agent-core-h21gngxf.js +247 -0
  30. package/dist/shared/@ai-setting/{roy-agent-core-p3zv1mx5.js → roy-agent-core-hd3n57zs.js} +1 -1
  31. package/dist/shared/@ai-setting/{roy-agent-core-ntq0gz7q.js → roy-agent-core-q813vafd.js} +1 -1
  32. package/dist/shared/@ai-setting/{roy-agent-core-z43aj03k.js → roy-agent-core-rhtdspx6.js} +20 -1
  33. package/dist/shared/@ai-setting/{roy-agent-core-ghnagzrh.js → roy-agent-core-rsn44n9y.js} +3 -3
  34. package/dist/shared/@ai-setting/{roy-agent-core-nmx9934r.js → roy-agent-core-w0qjeq2v.js} +1 -1
  35. package/package.json +1 -1
  36. package/dist/shared/@ai-setting/roy-agent-core-f77k3gqt.js +0 -71
@@ -71,6 +71,13 @@ export interface TaskStore {
71
71
  * 确定性映射:sub-agent 的 task_create 用 sessionId=sub-session id)。
72
72
  */
73
73
  getTaskIdBySessionId(sessionId: string): Promise<number | undefined>;
74
+ /**
75
+ * Task #5081(optional)— 按 session_id 反查该 session 关联的**全部**
76
+ * task id(不限定 create 记录)。TaskOpWatermarkPlugin 对全部 task
77
+ * 求并集水位。optional:外部宿主实现可不提供(调用方降级到
78
+ * getTaskIdBySessionId 单值)。
79
+ */
80
+ getTaskIdsBySessionId?(sessionId: string): Promise<number[]>;
74
81
  createOperation(options: CreateOperationOptions): Promise<TaskOperation>;
75
82
  getOperation(id: number): Promise<TaskOperation | undefined>;
76
83
  updateOperation(id: number, updates: {
@@ -82,6 +89,22 @@ export interface TaskStore {
82
89
  }): Promise<TaskOperation | undefined>;
83
90
  deleteOperation(id: number): Promise<boolean>;
84
91
  listOperations(options: ListOperationsOptions): Promise<TaskOperation[]>;
92
+ /**
93
+ * Task #5081(optional)— 绕过 operationsCache 的直读查询。
94
+ *
95
+ * 跨进程写入的 operation 不会失效本进程缓存 → `listOperations`
96
+ * 可能读陈旧快照。本方法**直打 DB**(`ORDER BY id DESC`,不读写
97
+ * 缓存),供 TaskOpWatermarkPlugin 的水位检查使用。
98
+ *
99
+ * optional:不破坏外部宿主实现的 TaskStore 契约(能力探测 +
100
+ * 降级路径见 plugin 侧)。
101
+ */
102
+ listOperationsFresh?(options: ListOperationsOptions): Promise<TaskOperation[]>;
103
+ /**
104
+ * Task #5081(optional)— 主动失效 operationsCache。
105
+ * 降级路径配套:`listOperations` 前调用,保证读到最新。
106
+ */
107
+ invalidateOperationsCache?(taskId: number): void;
85
108
  createTag(name: string): Promise<TaskTag>;
86
109
  getTag(id: number): Promise<TaskTag | undefined>;
87
110
  getTagByName(name: string): Promise<TaskTag | undefined>;
@@ -186,6 +209,28 @@ export declare class SQLiteTaskStore implements TaskStore {
186
209
  }): Promise<TaskOperation | undefined>;
187
210
  deleteOperation(id: number): Promise<boolean>;
188
211
  listOperations(options: ListOperationsOptions): Promise<TaskOperation[]>;
212
+ /**
213
+ * Task #5081 — 绕过 operationsCache 的直读查询(optional 能力)。
214
+ *
215
+ * 为什么必须有:operationsCache 只在本进程 create/update/delete 时
216
+ * 失效(:744/:785/:800),**跨进程写入的 operation 不会失效本进程
217
+ * 缓存** —— CLI 探针 / 另一 daemon 进程写的记录,本进程的
218
+ * `listOperations` 永远看不到(读陈旧快照)→ TaskOpWatermarkPlugin
219
+ * 的水位检查会漏报。
220
+ *
221
+ * 要点:
222
+ * - `ORDER BY id DESC`:水位语义要求**单调自增 id**(timestamp 同
223
+ * 毫秒多条会漏),id 是 AUTOINCREMENT 严格单调。
224
+ * - **只读,不写 operationsCache**:不污染其它调用方的缓存语义。
225
+ */
226
+ listOperationsFresh(options: ListOperationsOptions): Promise<TaskOperation[]>;
227
+ /**
228
+ * Task #5081 — 主动失效 operationsCache(optional 能力)。
229
+ *
230
+ * 供不支持 `listOperationsFresh` 的外部宿主 backend 走降级路径:
231
+ * `listOperations` 之前先失效缓存,保证下次读到最新。
232
+ */
233
+ invalidateOperationsCache(taskId: number): void;
189
234
  /**
190
235
  * 按 session_id 反查该 session 创建的第一个 task。
191
236
  *
@@ -195,6 +240,15 @@ export declare class SQLiteTaskStore implements TaskStore {
195
240
  * 不依赖易失的 EnvContext.currentTaskId(会被 task_complete 清空)或结果文本正则。
196
241
  */
197
242
  getTaskIdBySessionId(sessionId: string): Promise<number | undefined>;
243
+ /**
244
+ * Task #5081 — 按 session_id 反查该 session 关联的**全部** task id
245
+ * (optional 能力,TaskStore 接口同款 optional)。
246
+ *
247
+ * 与 getTaskIdBySessionId 的区别:不限定 milestone_type='create'、
248
+ * 不 LIMIT 1 —— sub-session 往同一 task 写过任何 operation 记录
249
+ * (记进度 / milestone / pre_complete 留痕)都算关联。
250
+ */
251
+ getTaskIdsBySessionId(sessionId: string): Promise<number[]>;
198
252
  private rowToTask;
199
253
  /**
200
254
  * 安全解析 tags 字段。
@@ -161,6 +161,14 @@ export declare class TaskComponent extends BaseComponent {
161
161
  * 按 session_id 反查该 session 创建的第一个 task(sub-session → task 确定性映射)。
162
162
  */
163
163
  getTaskIdBySessionId(sessionId: string): Promise<number | undefined>;
164
+ /**
165
+ * Task #5081 — 按 session_id 反查该 session 绑定的**全部** task。
166
+ *
167
+ * 为什么需要:一个 sub-session 可能创建/关联多个 task
168
+ * (getTaskIdBySessionId 只返回第一个,ORDER BY timestamp ASC)。
169
+ * TaskOpWatermarkPlugin 对全部 task 求并集水位(保守不漏报)。
170
+ */
171
+ getTaskIdsBySessionId(sessionId: string): Promise<number[]>;
164
172
  /**
165
173
  * Get task with operations
166
174
  *
@@ -383,6 +391,14 @@ export declare class TaskComponent extends BaseComponent {
383
391
  * List operations for a task
384
392
  */
385
393
  listOperations(options: ListOperationsOptions): Promise<TaskOperation[]>;
394
+ /**
395
+ * Task #5081 — 绕过 operationsCache 的直读(optional 能力探测)。
396
+ *
397
+ * store 实现 `listOperationsFresh` 时直打 DB;否则降级
398
+ * `listOperations` + `invalidateOperationsCache`(若支持)。
399
+ * 语义等价,保证跨进程写入的记录可见。
400
+ */
401
+ listOperationsFresh(options: ListOperationsOptions): Promise<TaskOperation[]>;
386
402
  /**
387
403
  * 获取 TagService
388
404
  */
@@ -82,31 +82,31 @@ export declare const CreateOperationToolSchema: z.ZodEffects<z.ZodObject<{
82
82
  md_path: z.ZodOptional<z.ZodString>;
83
83
  }, "strip", z.ZodTypeAny, {
84
84
  task_id: number;
85
- milestone_type?: "progress" | "completed" | "create" | "milestone" | "problem" | "solution" | "decision" | "review" | "workflow_extracted" | undefined;
85
+ milestone_type?: "completed" | "create" | "progress" | "milestone" | "problem" | "solution" | "decision" | "review" | "workflow_extracted" | undefined;
86
86
  milestone_title?: string | undefined;
87
87
  milestone_description?: string | undefined;
88
88
  process_description?: string | undefined;
89
- action_type?: "progress" | "completed" | "create" | "milestone" | "problem" | "solution" | "decision" | "review" | "workflow_extracted" | undefined;
89
+ action_type?: "completed" | "create" | "progress" | "milestone" | "problem" | "solution" | "decision" | "review" | "workflow_extracted" | undefined;
90
90
  action_title?: string | undefined;
91
91
  action_description?: string | undefined;
92
92
  md_path?: string | undefined;
93
93
  }, {
94
94
  task_id: number;
95
- milestone_type?: "progress" | "completed" | "create" | "milestone" | "problem" | "solution" | "decision" | "review" | "workflow_extracted" | undefined;
95
+ milestone_type?: "completed" | "create" | "progress" | "milestone" | "problem" | "solution" | "decision" | "review" | "workflow_extracted" | undefined;
96
96
  milestone_title?: string | undefined;
97
97
  milestone_description?: string | undefined;
98
98
  process_description?: string | undefined;
99
- action_type?: "progress" | "completed" | "create" | "milestone" | "problem" | "solution" | "decision" | "review" | "workflow_extracted" | undefined;
99
+ action_type?: "completed" | "create" | "progress" | "milestone" | "problem" | "solution" | "decision" | "review" | "workflow_extracted" | undefined;
100
100
  action_title?: string | undefined;
101
101
  action_description?: string | undefined;
102
102
  md_path?: string | undefined;
103
103
  }>, CreateOperationToolParams, {
104
104
  task_id: number;
105
- milestone_type?: "progress" | "completed" | "create" | "milestone" | "problem" | "solution" | "decision" | "review" | "workflow_extracted" | undefined;
105
+ milestone_type?: "completed" | "create" | "progress" | "milestone" | "problem" | "solution" | "decision" | "review" | "workflow_extracted" | undefined;
106
106
  milestone_title?: string | undefined;
107
107
  milestone_description?: string | undefined;
108
108
  process_description?: string | undefined;
109
- action_type?: "progress" | "completed" | "create" | "milestone" | "problem" | "solution" | "decision" | "review" | "workflow_extracted" | undefined;
109
+ action_type?: "completed" | "create" | "progress" | "milestone" | "problem" | "solution" | "decision" | "review" | "workflow_extracted" | undefined;
110
110
  action_title?: string | undefined;
111
111
  action_description?: string | undefined;
112
112
  md_path?: string | undefined;
@@ -144,17 +144,17 @@ export declare const ListOperationsToolSchema: z.ZodEffects<z.ZodObject<{
144
144
  task_id: number;
145
145
  limit: number;
146
146
  offset: number;
147
- milestone_type?: "progress" | "completed" | "create" | "milestone" | "problem" | "solution" | "decision" | "review" | "workflow_extracted" | undefined;
148
- action_type?: "progress" | "completed" | "create" | "milestone" | "problem" | "solution" | "decision" | "review" | "workflow_extracted" | undefined;
147
+ milestone_type?: "completed" | "create" | "progress" | "milestone" | "problem" | "solution" | "decision" | "review" | "workflow_extracted" | undefined;
148
+ action_type?: "completed" | "create" | "progress" | "milestone" | "problem" | "solution" | "decision" | "review" | "workflow_extracted" | undefined;
149
149
  }, {
150
150
  task_id: number;
151
151
  limit?: number | undefined;
152
152
  offset?: number | undefined;
153
- milestone_type?: "progress" | "completed" | "create" | "milestone" | "problem" | "solution" | "decision" | "review" | "workflow_extracted" | undefined;
154
- action_type?: "progress" | "completed" | "create" | "milestone" | "problem" | "solution" | "decision" | "review" | "workflow_extracted" | undefined;
153
+ milestone_type?: "completed" | "create" | "progress" | "milestone" | "problem" | "solution" | "decision" | "review" | "workflow_extracted" | undefined;
154
+ action_type?: "completed" | "create" | "progress" | "milestone" | "problem" | "solution" | "decision" | "review" | "workflow_extracted" | undefined;
155
155
  }>, {
156
156
  task_id: number;
157
- milestone_type: "progress" | "completed" | "create" | "milestone" | "problem" | "solution" | "decision" | "review" | "workflow_extracted" | undefined;
157
+ milestone_type: "completed" | "create" | "progress" | "milestone" | "problem" | "solution" | "decision" | "review" | "workflow_extracted" | undefined;
158
158
  limit: number;
159
159
  offset: number;
160
160
  _deprecated_fields_used: string[];
@@ -162,8 +162,8 @@ export declare const ListOperationsToolSchema: z.ZodEffects<z.ZodObject<{
162
162
  task_id: number;
163
163
  limit?: number | undefined;
164
164
  offset?: number | undefined;
165
- milestone_type?: "progress" | "completed" | "create" | "milestone" | "problem" | "solution" | "decision" | "review" | "workflow_extracted" | undefined;
166
- action_type?: "progress" | "completed" | "create" | "milestone" | "problem" | "solution" | "decision" | "review" | "workflow_extracted" | undefined;
165
+ milestone_type?: "completed" | "create" | "progress" | "milestone" | "problem" | "solution" | "decision" | "review" | "workflow_extracted" | undefined;
166
+ action_type?: "completed" | "create" | "progress" | "milestone" | "problem" | "solution" | "decision" | "review" | "workflow_extracted" | undefined;
167
167
  }>;
168
168
  export interface ListOperationsToolParams {
169
169
  task_id: number;
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  LarkCliWorkflowNotifyHook,
3
3
  createLarkCliWorkflowNotifyHook
4
- } from "../../../shared/@ai-setting/roy-agent-core-p3zv1mx5.js";
5
- import"../../../shared/@ai-setting/roy-agent-core-nmx9934r.js";
4
+ } from "../../../shared/@ai-setting/roy-agent-core-hd3n57zs.js";
5
+ import"../../../shared/@ai-setting/roy-agent-core-w0qjeq2v.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";
@@ -206,17 +206,17 @@ export declare const NodeProgressEventSchema: z.ZodObject<{
206
206
  message: z.ZodOptional<z.ZodString>;
207
207
  }, "strip", z.ZodTypeAny, {
208
208
  type: "node.progress";
209
+ progress: number;
209
210
  run_id: string;
210
211
  timestamp: number;
211
212
  node_id: string;
212
- progress: number;
213
213
  message?: string | undefined;
214
214
  }, {
215
215
  type: "node.progress";
216
+ progress: number;
216
217
  run_id: string;
217
218
  timestamp: number;
218
219
  node_id: string;
219
- progress: number;
220
220
  message?: string | undefined;
221
221
  }>;
222
222
  export declare const NodeCompletedEventSchema: z.ZodObject<{
@@ -632,17 +632,17 @@ export declare const WorkflowEventSchema: z.ZodUnion<[z.ZodObject<{
632
632
  message: z.ZodOptional<z.ZodString>;
633
633
  }, "strip", z.ZodTypeAny, {
634
634
  type: "node.progress";
635
+ progress: number;
635
636
  run_id: string;
636
637
  timestamp: number;
637
638
  node_id: string;
638
- progress: number;
639
639
  message?: string | undefined;
640
640
  }, {
641
641
  type: "node.progress";
642
+ progress: number;
642
643
  run_id: string;
643
644
  timestamp: number;
644
645
  node_id: string;
645
- progress: number;
646
646
  message?: string | undefined;
647
647
  }>, z.ZodObject<{
648
648
  run_id: z.ZodString;
package/dist/index.js CHANGED
@@ -62,21 +62,21 @@ import {
62
62
  BaseEnvironment,
63
63
  generateDescendingId,
64
64
  generateId
65
- } from "./shared/@ai-setting/roy-agent-core-zycadbpx.js";
65
+ } from "./shared/@ai-setting/roy-agent-core-ew6qb5yx.js";
66
66
  import {
67
67
  TaskComponent
68
- } from "./shared/@ai-setting/roy-agent-core-z43aj03k.js";
68
+ } from "./shared/@ai-setting/roy-agent-core-rhtdspx6.js";
69
69
  import"./shared/@ai-setting/roy-agent-core-2akfd64z.js";
70
70
  import"./shared/@ai-setting/roy-agent-core-jm136jzh.js";
71
71
  import"./shared/@ai-setting/roy-agent-core-aa2j7bk9.js";
72
72
  import"./shared/@ai-setting/roy-agent-core-fttgm52a.js";
73
- import"./shared/@ai-setting/roy-agent-core-ntq0gz7q.js";
73
+ import"./shared/@ai-setting/roy-agent-core-q813vafd.js";
74
74
  import"./shared/@ai-setting/roy-agent-core-8gxth0eh.js";
75
75
  import"./shared/@ai-setting/roy-agent-core-vffccgf6.js";
76
76
  import"./shared/@ai-setting/roy-agent-core-p5cz9m8v.js";
77
77
  import {
78
78
  EventSourceComponent
79
- } from "./shared/@ai-setting/roy-agent-core-cxy143m4.js";
79
+ } from "./shared/@ai-setting/roy-agent-core-0v27y99n.js";
80
80
  import {
81
81
  BountyIMInstance,
82
82
  COMMAND_PREFIX,
@@ -108,7 +108,7 @@ import {
108
108
  timerHandler,
109
109
  translateCardActionToCommand,
110
110
  writeFallbackModelList
111
- } from "./shared/@ai-setting/roy-agent-core-t3rrb959.js";
111
+ } from "./shared/@ai-setting/roy-agent-core-3gpygqcx.js";
112
112
  import {
113
113
  BUILT_IN_EVENT_SOURCE_TYPES,
114
114
  BUILT_IN_EVENT_SOURCE_TYPE_LIST,
@@ -132,7 +132,7 @@ import {
132
132
  import {
133
133
  TaskTagPlugin,
134
134
  createAutoTaskPlugin
135
- } from "./shared/@ai-setting/roy-agent-core-ghnagzrh.js";
135
+ } from "./shared/@ai-setting/roy-agent-core-rsn44n9y.js";
136
136
  import {
137
137
  EventStoreImpl,
138
138
  getSharedEventStore,
@@ -146,7 +146,7 @@ import {
146
146
  import {
147
147
  SQLiteTaskStore,
148
148
  getDefaultTaskDbPath
149
- } from "./shared/@ai-setting/roy-agent-core-abqhkbn3.js";
149
+ } from "./shared/@ai-setting/roy-agent-core-ezvpreqz.js";
150
150
  import {
151
151
  TaskHookPoints
152
152
  } from "./shared/@ai-setting/roy-agent-core-1pg0fepg.js";
@@ -164,8 +164,8 @@ import {
164
164
  TASK_COMPLETED_STATUS_WORD,
165
165
  TASK_DELIVERABLE_RECORDED
166
166
  } from "./shared/@ai-setting/roy-agent-core-4rtg69cn.js";
167
- import"./shared/@ai-setting/roy-agent-core-p3zv1mx5.js";
168
- import"./shared/@ai-setting/roy-agent-core-nmx9934r.js";
167
+ import"./shared/@ai-setting/roy-agent-core-hd3n57zs.js";
168
+ import"./shared/@ai-setting/roy-agent-core-w0qjeq2v.js";
169
169
  import {
170
170
  WorkflowComponent
171
171
  } from "./shared/@ai-setting/roy-agent-core-v87njmq7.js";
@@ -212,7 +212,7 @@ import"./shared/@ai-setting/roy-agent-core-jagkferh.js";
212
212
  import {
213
213
  AgentComponent,
214
214
  AgentComponentConfigSchema
215
- } from "./shared/@ai-setting/roy-agent-core-q5r75vev.js";
215
+ } from "./shared/@ai-setting/roy-agent-core-9vhq7fvv.js";
216
216
  import {
217
217
  ToolComponent,
218
218
  ToolRegistry,
@@ -227,7 +227,7 @@ import {
227
227
  getXDGPath,
228
228
  getXDGPaths
229
229
  } from "./shared/@ai-setting/roy-agent-core-qxnbvgwe.js";
230
- import"./shared/@ai-setting/roy-agent-core-f77k3gqt.js";
230
+ import"./shared/@ai-setting/roy-agent-core-h21gngxf.js";
231
231
  import"./shared/@ai-setting/roy-agent-core-0snm5hc5.js";
232
232
  import {
233
233
  buildOpencodeHeaders,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  builtInHandlers
3
- } from "./roy-agent-core-t3rrb959.js";
3
+ } from "./roy-agent-core-3gpygqcx.js";
4
4
  import {
5
5
  envKeyToConfigKey
6
6
  } from "./roy-agent-core-7hh0brvs.js";
@@ -10,17 +10,17 @@ import {
10
10
  createPerTaskGroupChatPlugin,
11
11
  extractPerTaskChatId,
12
12
  extractPerTaskChatName
13
- } from "./roy-agent-core-ghnagzrh.js";
13
+ } from "./roy-agent-core-rsn44n9y.js";
14
14
  import {
15
15
  getSharedEventStore
16
16
  } from "./roy-agent-core-na18zwj0.js";
17
17
  import {
18
18
  createLarkCliWorkflowNotifyHook
19
- } from "./roy-agent-core-p3zv1mx5.js";
19
+ } from "./roy-agent-core-hd3n57zs.js";
20
20
  import {
21
21
  LarkCardPatchNotifier,
22
22
  buildTaskCard
23
- } from "./roy-agent-core-nmx9934r.js";
23
+ } from "./roy-agent-core-w0qjeq2v.js";
24
24
  import {
25
25
  notifyReactFailure
26
26
  } from "./roy-agent-core-6cy43nss.js";
@@ -6,8 +6,9 @@ import {
6
6
  AgentRegistry
7
7
  } from "./roy-agent-core-ed233k5z.js";
8
8
  import {
9
+ createTaskOpWatermarkPlugin,
9
10
  enqueueToAddFakeUserMessage
10
- } from "./roy-agent-core-f77k3gqt.js";
11
+ } from "./roy-agent-core-h21gngxf.js";
11
12
  import {
12
13
  SessionMessageConverter
13
14
  } from "./roy-agent-core-0snm5hc5.js";
@@ -919,6 +920,9 @@ class AgentComponent extends BaseComponent {
919
920
  };
920
921
  this.agents.set(name, instance);
921
922
  this.registerPlugin(name, createMaxIterationReminderPlugin());
923
+ this.registerPlugin(name, createTaskOpWatermarkPlugin({
924
+ resolveTaskComponent: () => this.env?.getComponent?.("task")
925
+ }));
922
926
  logger2.info(`Agent registered: ${name}`, { type: instance.config.type });
923
927
  return instance;
924
928
  }
@@ -2,7 +2,7 @@ import {
2
2
  createAutoTaskPlugin,
3
3
  createLayaDecisionPlugin,
4
4
  registerLayaCompletionTaskHook
5
- } from "./roy-agent-core-ghnagzrh.js";
5
+ } from "./roy-agent-core-rsn44n9y.js";
6
6
  import {
7
7
  TaskHookPoints
8
8
  } from "./roy-agent-core-1pg0fepg.js";
@@ -709,6 +709,22 @@ var init_sqlite_task_store = __esm(() => {
709
709
  const limit = options.limit || 20;
710
710
  return ops.slice(offset, offset + limit);
711
711
  }
712
+ async listOperationsFresh(options) {
713
+ await this.initialize();
714
+ const stmt = this.db.prepare("SELECT * FROM task_operation WHERE task_id = ? ORDER BY id DESC");
715
+ const rows = stmt.all(options.taskId);
716
+ let ops = rows.map((row) => this.rowToOperation(row));
717
+ const filterType = options.milestoneType ?? options.actionType;
718
+ if (filterType) {
719
+ ops = ops.filter((op) => op.milestoneType === filterType);
720
+ }
721
+ const offset = options.offset || 0;
722
+ const limit = options.limit || 20;
723
+ return ops.slice(offset, offset + limit);
724
+ }
725
+ invalidateOperationsCache(taskId) {
726
+ this.operationsCache.delete(taskId);
727
+ }
712
728
  async getTaskIdBySessionId(sessionId) {
713
729
  await this.initialize();
714
730
  if (!sessionId)
@@ -716,6 +732,13 @@ var init_sqlite_task_store = __esm(() => {
716
732
  const row = this.db.prepare("SELECT task_id FROM task_operation WHERE session_id = ? AND milestone_type = 'create' ORDER BY timestamp ASC LIMIT 1").get(sessionId);
717
733
  return typeof row?.task_id === "number" ? row.task_id : undefined;
718
734
  }
735
+ async getTaskIdsBySessionId(sessionId) {
736
+ await this.initialize();
737
+ if (!sessionId)
738
+ return [];
739
+ const rows = this.db.prepare("SELECT DISTINCT task_id FROM task_operation WHERE session_id = ? ORDER BY task_id ASC").all(sessionId);
740
+ return rows.map((r) => r.task_id).filter((id) => typeof id === "number");
741
+ }
719
742
  rowToTask(row) {
720
743
  return {
721
744
  id: row.id,
@@ -0,0 +1,247 @@
1
+ import {
2
+ init_decorator,
3
+ wrapFunction
4
+ } from "./roy-agent-core-qq96p0tj.js";
5
+ import {
6
+ createLogger,
7
+ init_logger
8
+ } from "./roy-agent-core-7f7t9wwp.js";
9
+
10
+ // src/env/task/plugins/task-op-watermark-plugin.ts
11
+ init_logger();
12
+
13
+ // src/env/task/plugins/fake-user-message-helper.ts
14
+ init_decorator();
15
+ var KIND_PRIORITY = {
16
+ delegate: 10,
17
+ "task-ops": 20,
18
+ "max-iter": 30
19
+ };
20
+ var KIND_FIELD = "__fakeUserMessageKind";
21
+ function ensureMetadata(toolResult) {
22
+ if (!toolResult)
23
+ return;
24
+ if (!toolResult.result)
25
+ toolResult.result = {};
26
+ if (!toolResult.result.metadata)
27
+ toolResult.result.metadata = {};
28
+ return toolResult.result.metadata;
29
+ }
30
+ function stringContent(msg) {
31
+ const c = msg?.content;
32
+ return typeof c === "string" ? c : JSON.stringify(c);
33
+ }
34
+ function enqueueToAddFakeUserMessageImpl(toolResult, newMsg, newKind) {
35
+ const meta = ensureMetadata(toolResult);
36
+ if (!meta)
37
+ return { willMerge: false, finalKind: newKind };
38
+ const existing = meta.toAddFakeUserMessage;
39
+ const existingKind = meta[KIND_FIELD];
40
+ if (!existing) {
41
+ meta.toAddFakeUserMessage = newMsg;
42
+ meta[KIND_FIELD] = newKind;
43
+ return { willMerge: false, finalKind: newKind };
44
+ }
45
+ let merged;
46
+ if (KIND_PRIORITY[newKind] >= KIND_PRIORITY[existingKind ?? newKind]) {
47
+ merged = {
48
+ role: "user",
49
+ content: `${stringContent(existing)}
50
+
51
+ ${stringContent(newMsg)}`
52
+ };
53
+ } else {
54
+ merged = {
55
+ role: "user",
56
+ content: `${stringContent(newMsg)}
57
+
58
+ ${stringContent(existing)}`
59
+ };
60
+ }
61
+ meta.toAddFakeUserMessage = merged;
62
+ const finalKind = KIND_PRIORITY[newKind] >= KIND_PRIORITY[existingKind ?? newKind] ? newKind : existingKind ?? newKind;
63
+ meta[KIND_FIELD] = finalKind;
64
+ return { willMerge: true, finalKind };
65
+ }
66
+ var enqueueToAddFakeUserMessage = wrapFunction(enqueueToAddFakeUserMessageImpl, "plugin.fake-user-message.enqueue", {
67
+ recordParams: false,
68
+ recordResult: false,
69
+ log: true,
70
+ resultFilter: (result) => ({
71
+ "fake-user-message.will_merge": result.willMerge,
72
+ "fake-user-message.final_kind": result.finalKind
73
+ })
74
+ });
75
+
76
+ // src/env/task/plugins/task-op-watermark-plugin.ts
77
+ var logger = createLogger("TaskOpWatermarkPlugin");
78
+ var TASK_OP_WATERMARK_MAX_REMINDERS = 5;
79
+ var TASK_OP_WATERMARK_MESSAGE_LIMIT = 1500;
80
+ var TASK_OP_WATERMARK_AUDIT_INTERVAL = 15;
81
+ var MAX_DETAIL_ITEMS = 3;
82
+ var MAX_DESC_LENGTH = 200;
83
+ var UNKNOWN_SESSION = "unknown";
84
+ var TRUNCATION_SUFFIX = "…(已截断)";
85
+ function truncate(s, max) {
86
+ if (s.length <= max)
87
+ return s;
88
+ return `${s.slice(0, max)}…(已截断)`;
89
+ }
90
+ function buildReminderMessage(taskId, taskTitle, ops) {
91
+ const count = ops.length;
92
+ const lines = [];
93
+ lines.push(`[task-ops] Task #${taskId}${taskTitle ? `「${taskTitle}」` : ""} 有 ${count} 条由**其他 agent** 新增的操作记录,请读取并按需调整你的行为。`);
94
+ lines.push("");
95
+ lines.push("最新记录:");
96
+ const details = ops.slice(0, MAX_DETAIL_ITEMS);
97
+ for (const op of details) {
98
+ const desc = op.milestoneDescription ? truncate(op.milestoneDescription.split(`
99
+ `)[0], MAX_DESC_LENGTH) : "";
100
+ lines.push(`- [${op.milestoneType}] ${op.milestoneTitle}${desc ? `
101
+ ${desc}` : ""}`);
102
+ }
103
+ if (count > MAX_DETAIL_ITEMS) {
104
+ lines.push(`(其余 ${count - MAX_DETAIL_ITEMS} 条较旧记录省略,可用 task_operation_list 查看全部)`);
105
+ }
106
+ lines.push("");
107
+ lines.push(`请调用 task_operation_list(task_id=${taskId}) 读取全部新记录,判断是否需要修改你的计划、产出或下一步动作。`);
108
+ lines.push("若这些记录与你的当前工作无关,忽略即可,无需回复。");
109
+ return lines.join(`
110
+ `);
111
+ }
112
+
113
+ class TaskOpWatermarkPlugin {
114
+ name = "TaskOpWatermarkPlugin";
115
+ version = "1.0.0";
116
+ description = "Task #5081 — agent:after.tool 水位比对:同一 task 出现他人(sessionId 过滤 + unknown 过滤)新增的 operation 时,经共享 meta-protocol 注入 user role 提醒(N 聚 1 / 限流 5 / 长度 1500 / 15 次兜底对账 / fresh 旁路绕 operationsCache)。";
117
+ priority = 40;
118
+ watermarks = new Map;
119
+ resolveTaskComponent;
120
+ constructor(config) {
121
+ this.resolveTaskComponent = config?.resolveTaskComponent;
122
+ }
123
+ async execute(ctx) {
124
+ try {
125
+ await this.check(ctx);
126
+ } catch (err) {
127
+ logger.warn(`[TaskOpWatermark] check failed (fail-open): ${err?.message}`);
128
+ }
129
+ return { continue: true };
130
+ }
131
+ async check(ctx) {
132
+ const sessionId = ctx.context?.sessionId;
133
+ if (!sessionId)
134
+ return;
135
+ const taskComponent = this.resolveTaskComponent?.();
136
+ if (!taskComponent)
137
+ return;
138
+ const taskIds = await this.resolveTaskIds(taskComponent, sessionId);
139
+ if (taskIds.length === 0)
140
+ return;
141
+ const taskKey = taskIds.join(",");
142
+ let wm = this.watermarks.get(sessionId);
143
+ if (!wm || wm.taskIds.join(",") !== taskKey) {
144
+ wm = {
145
+ lastSeenOpId: 0,
146
+ lastNotifiedOpId: 0,
147
+ taskIds,
148
+ reminderCount: 0,
149
+ toolsSinceAudit: 0
150
+ };
151
+ this.watermarks.set(sessionId, wm);
152
+ }
153
+ wm.toolsSinceAudit++;
154
+ const isAuditTurn = wm.toolsSinceAudit >= TASK_OP_WATERMARK_AUDIT_INTERVAL;
155
+ if (isAuditTurn)
156
+ wm.toolsSinceAudit = 0;
157
+ const lowerBound = isAuditTurn || wm.lastSeenOpId === 0 ? wm.lastNotifiedOpId : wm.lastSeenOpId;
158
+ let newOps = [];
159
+ let maxIdSeen = wm.lastSeenOpId;
160
+ for (const taskId of taskIds) {
161
+ const ops = await this.listOps(taskComponent, taskId);
162
+ const othersNew = ops.filter((op) => op.id > lowerBound && !this.isSelf(op, sessionId));
163
+ for (const op of othersNew) {
164
+ newOps.push(op);
165
+ if (op.id > maxIdSeen)
166
+ maxIdSeen = op.id;
167
+ }
168
+ const selfMax = ops.filter((op) => this.isSelf(op, sessionId)).reduce((m, op) => Math.max(m, op.id), 0);
169
+ maxIdSeen = Math.max(maxIdSeen, selfMax);
170
+ }
171
+ const seen = new Set;
172
+ newOps = newOps.filter((op) => seen.has(op.id) ? false : (seen.add(op.id), true)).sort((a, b) => b.id - a.id);
173
+ wm.lastSeenOpId = Math.max(wm.lastSeenOpId, maxIdSeen);
174
+ if (newOps.length === 0)
175
+ return;
176
+ if (wm.reminderCount >= TASK_OP_WATERMARK_MAX_REMINDERS) {
177
+ logger.info(`[TaskOpWatermark] session=${sessionId.slice(0, 12)}... reminder limit reached (${wm.reminderCount}) — watermark advanced silently`);
178
+ return;
179
+ }
180
+ if (!ctx.toolResult)
181
+ return;
182
+ const byTask = new Map;
183
+ for (const op of newOps) {
184
+ const arr = byTask.get(op.taskId) ?? [];
185
+ arr.push(op);
186
+ byTask.set(op.taskId, arr);
187
+ }
188
+ const sections = [];
189
+ for (const [taskId, ops] of byTask) {
190
+ const title = (await safeGetTask(taskComponent, taskId))?.title;
191
+ sections.push(buildReminderMessage(taskId, title, ops));
192
+ }
193
+ const content = sections.join(`
194
+
195
+ `);
196
+ const finalContent = content.length > TASK_OP_WATERMARK_MESSAGE_LIMIT ? `${content.slice(0, TASK_OP_WATERMARK_MESSAGE_LIMIT - TRUNCATION_SUFFIX.length)}${TRUNCATION_SUFFIX}` : content;
197
+ enqueueToAddFakeUserMessage(ctx.toolResult, { role: "user", content: finalContent }, "task-ops");
198
+ wm.reminderCount++;
199
+ const maxNotified = newOps.reduce((m, op) => Math.max(m, op.id), 0);
200
+ wm.lastNotifiedOpId = Math.max(wm.lastNotifiedOpId, maxNotified);
201
+ logger.info(`[TaskOpWatermark] reminder injected: session=${sessionId.slice(0, 12)}..., tasks=${[...byTask.keys()].join(",")}, newOps=${newOps.length}, reminderCount=${wm.reminderCount}`);
202
+ }
203
+ isSelf(op, sessionId) {
204
+ return op.sessionId === sessionId || op.sessionId === UNKNOWN_SESSION;
205
+ }
206
+ async resolveTaskIds(tc, sessionId) {
207
+ if (typeof tc.getTaskIdsBySessionId === "function") {
208
+ const ids = await tc.getTaskIdsBySessionId(sessionId);
209
+ return Array.isArray(ids) ? ids : [];
210
+ }
211
+ if (typeof tc.getTaskIdBySessionId === "function") {
212
+ const id = await tc.getTaskIdBySessionId(sessionId);
213
+ return typeof id === "number" ? [id] : [];
214
+ }
215
+ return [];
216
+ }
217
+ async listOps(tc, taskId) {
218
+ if (typeof tc.listOperationsFresh === "function") {
219
+ return await tc.listOperationsFresh({ taskId, limit: 50 });
220
+ }
221
+ if (typeof tc.invalidateOperationsCache === "function") {
222
+ tc.invalidateOperationsCache(taskId);
223
+ }
224
+ return await tc.listOperations({ taskId, limit: 50 });
225
+ }
226
+ }
227
+ async function safeGetTask(tc, taskId) {
228
+ try {
229
+ return await tc.getTask(taskId);
230
+ } catch {
231
+ return;
232
+ }
233
+ }
234
+ function createTaskOpWatermarkPlugin(config) {
235
+ const inst = new TaskOpWatermarkPlugin(config);
236
+ return {
237
+ name: inst.name,
238
+ version: inst.version,
239
+ description: inst.description,
240
+ hooks: [{ point: "agent:after.tool", priority: inst.priority }],
241
+ execute: async (ctx) => {
242
+ return inst.execute(ctx);
243
+ }
244
+ };
245
+ }
246
+
247
+ export { enqueueToAddFakeUserMessage, TASK_OP_WATERMARK_MAX_REMINDERS, TASK_OP_WATERMARK_MESSAGE_LIMIT, TASK_OP_WATERMARK_AUDIT_INTERVAL, TaskOpWatermarkPlugin, createTaskOpWatermarkPlugin };