@ai-setting/roy-agent-core 1.7.88 → 1.7.90

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/dist/env/event-source/event-source-handlers.js +6 -6
  2. package/dist/env/event-source/index.js +7 -7
  3. package/dist/env/event-source/wecom-session-card-sender.js +2 -2
  4. package/dist/env/index.js +12 -11
  5. package/dist/env/task/backend/index.d.ts +3 -0
  6. package/dist/env/task/backend/index.js +155 -5
  7. package/dist/env/task/backend/remote-task-port.d.ts +85 -0
  8. package/dist/env/task/backend/roy-sidecar-task-port.d.ts +8 -0
  9. package/dist/env/task/backend/types.d.ts +5 -0
  10. package/dist/env/task/index.d.ts +1 -1
  11. package/dist/env/task/index.js +20 -4
  12. package/dist/env/task/mcp/index.js +1 -1
  13. package/dist/env/task/plugins/index.js +3 -3
  14. package/dist/env/task/plugins/lark-card-patch-notifier.js +2 -2
  15. package/dist/env/task/plugins/wecom-session-card-store.js +2 -2
  16. package/dist/env/task/storage/index.d.ts +1 -0
  17. package/dist/env/task/storage/index.js +23 -3
  18. package/dist/env/task/storage/migrations/006_add_task_owner.d.ts +24 -0
  19. package/dist/env/task/storage/remote-task-store.d.ts +186 -0
  20. package/dist/env/task/task-component.d.ts +7 -0
  21. package/dist/env/task/tools/index.js +1 -1
  22. package/dist/env/task/tools/task-types.d.ts +7 -0
  23. package/dist/env/task/types.d.ts +17 -0
  24. package/dist/env/workflow/plugins/index.js +3 -3
  25. package/dist/index.d.ts +1 -1
  26. package/dist/index.js +17 -11
  27. package/dist/shared/@ai-setting/{roy-agent-core-vpcxv1ty.js → roy-agent-core-05z35shp.js} +1 -1
  28. package/dist/shared/@ai-setting/{roy-agent-core-shb1qsyg.js → roy-agent-core-0n1wwndq.js} +1 -1
  29. package/dist/shared/@ai-setting/{roy-agent-core-fan8g0z1.js → roy-agent-core-49qcpqwg.js} +46 -11
  30. package/dist/shared/@ai-setting/{roy-agent-core-gr5h1dyr.js → roy-agent-core-4b38m749.js} +4 -4
  31. package/dist/shared/@ai-setting/{roy-agent-core-wr1qexzq.js → roy-agent-core-5dhvfgaw.js} +1 -1
  32. package/dist/shared/@ai-setting/{roy-agent-core-qwd2dq5q.js → roy-agent-core-9cen1jvg.js} +8 -4
  33. package/dist/shared/@ai-setting/{roy-agent-core-7kvpc0w5.js → roy-agent-core-age3qseb.js} +1 -1
  34. package/dist/shared/@ai-setting/{roy-agent-core-an35dzbf.js → roy-agent-core-dvec4nn2.js} +1 -1
  35. package/dist/shared/@ai-setting/{roy-agent-core-ra66sf50.js → roy-agent-core-k3h8t4q1.js} +4 -3
  36. package/dist/shared/@ai-setting/{roy-agent-core-6k8mb7zx.js → roy-agent-core-m66ysky0.js} +53 -5
  37. package/dist/shared/@ai-setting/{roy-agent-core-yh68z1bg.js → roy-agent-core-m7d1t3db.js} +1 -1
  38. package/dist/shared/@ai-setting/roy-agent-core-zhwcje5a.js +352 -0
  39. package/package.json +1 -1
@@ -62,7 +62,8 @@ var CreateTaskToolSchema = z.object({
62
62
  ` + ` C. 新建根任务 → 省略 parent_task_id(让树根 ≤10)
63
63
  ` + `如何找到 parent_task_id:使用 task_tree(depth=2) 获取的树形结构,
64
64
  ` + "根据节点 id 选择合适的父任务 ID(来自 tree 输出,**不要硬编码**数字)。"),
65
- context: z.string().default('{"type":"unknown"}').describe("JSON string with time-space positioning information for task continuity. " + "This field is crucial for Agent task handoff. " + "Core fields: worktree_path (git worktree path), branch (current branch), type (feature/bug/refactor/chore). " + 'Example for coding: {"worktree_path": "/path/worktree", "branch": "feature/xyz", "type": "feature"}. ' + 'Example for other: {"type": "general"}. ' + `If unknown, use '{}' or '{"type":"unknown"}'. ` + "IMPORTANT: Must be a valid JSON string! " + "**Task #4467 — similar_task_ids (REQUIRED)**: array of existing task ids that " + "cover the same ground as this request, used by the task:before.create decision " + "check to suggest reusing/reopening instead of creating a duplicate. " + "Search first (task_search / task_get), then pass the ids. " + "It may be an empty array [] if you searched and found nothing related — " + "but the field itself must be present. " + 'Example: {"type":"feature", "similar_task_ids": [4433, 4445]}')
65
+ context: z.string().default('{"type":"unknown"}').describe("JSON string with time-space positioning information for task continuity. " + "This field is crucial for Agent task handoff. " + "Core fields: worktree_path (git worktree path), branch (current branch), type (feature/bug/refactor/chore). " + 'Example for coding: {"worktree_path": "/path/worktree", "branch": "feature/xyz", "type": "feature"}. ' + 'Example for other: {"type": "general"}. ' + `If unknown, use '{}' or '{"type":"unknown"}'. ` + "IMPORTANT: Must be a valid JSON string! " + "**Task #4467 — similar_task_ids (REQUIRED)**: array of existing task ids that " + "cover the same ground as this request, used by the task:before.create decision " + "check to suggest reusing/reopening instead of creating a duplicate. " + "Search first (task_search / task_get), then pass the ids. " + "It may be an empty array [] if you searched and found nothing related — " + "but the field itself must be present. " + 'Example: {"type":"feature", "similar_task_ids": [4433, 4445]}'),
66
+ owner: z.union([z.string(), z.null()]).optional().describe("负责人(owner):这个任务由**谁**负责推进,可空(不传 / 传 null 即未指派)。" + "取值为自由字符串(open_id / 用户名 / 邮箱均可,core 不解释格式);" + "多人协作场景下用它区分负责人,与 sessionId(谁在操作)、project_path(哪个项目)正交。" + "向后兼容:省略该字段时任务以 owner=null 创建。")
66
67
  });
67
68
  var GetTaskToolSchema = withLegacyTaskId({
68
69
  include_operations: z.boolean().optional().default(true).describe("Include operation records (milestones / process log) with the task. " + "Defaults to true — the task's operation history is part of its detail. " + "Pass false for a lean task-only response.")
@@ -100,7 +101,8 @@ var UpdateTaskToolSchema = withLegacyTaskId({
100
101
  tags: z.array(z.string()).optional(),
101
102
  project_path: z.string().optional().describe("Project path, identifies which project this task belongs to"),
102
103
  context: z.string().optional().describe("Task context information for storing additional context"),
103
- parent_task_id: z.union([z.number(), z.null()]).optional().describe("Parent task ID (set to null to make it a root task)")
104
+ parent_task_id: z.union([z.number(), z.null()]).optional().describe("Parent task ID (set to null to make it a root task)"),
105
+ owner: z.union([z.string(), z.null()]).optional().describe("负责人(owner):可空。传字符串 = 指派/改派该负责人;传 null 或空字符串 = 清空(未指派);" + "**省略该字段** = 不改动(与 status / progress 等字段语义一致)。" + "用于多人协作场景标注任务负责人。")
104
106
  });
105
107
  var DeleteTaskToolSchema = z.object({
106
108
  task_id: z.number().describe("Task ID")
@@ -518,7 +520,8 @@ function createTaskTool(taskComponent) {
518
520
  tags: inheritedTags,
519
521
  sessionId,
520
522
  project_path: inheritedProjectPath ?? (callerProjectPathIsExplicit ? callerProjectPath : UNKNOWN_PROJECT_PATH),
521
- context: enrichedContext
523
+ context: enrichedContext,
524
+ owner: params.owner ?? null
522
525
  });
523
526
  setCurrentTaskId(task.id);
524
527
  logger2.info(`[createTask] Trace: Task #${task.id} created, currentTaskId=${task.id} set in EnvContext`);
@@ -877,7 +880,8 @@ function updateTaskTool(taskComponent) {
877
880
  tags: params.tags,
878
881
  project_path: params.project_path,
879
882
  context: params.context,
880
- parent_task_id: params.parent_task_id
883
+ parent_task_id: params.parent_task_id,
884
+ owner: params.owner
881
885
  });
882
886
  if (!task) {
883
887
  return {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createCompatibleDatabase,
3
3
  init_sqlite_task_store
4
- } from "./roy-agent-core-6k8mb7zx.js";
4
+ } from "./roy-agent-core-m66ysky0.js";
5
5
  import {
6
6
  createLogger,
7
7
  init_logger
@@ -2,7 +2,7 @@ import {
2
2
  createAutoTaskPlugin,
3
3
  createLayaDecisionPlugin,
4
4
  registerLayaCompletionTaskHook
5
- } from "./roy-agent-core-ra66sf50.js";
5
+ } from "./roy-agent-core-k3h8t4q1.js";
6
6
  import {
7
7
  TaskHookPoints
8
8
  } from "./roy-agent-core-1pg0fepg.js";
@@ -33,14 +33,14 @@ import {
33
33
  createLarkCardStateStore,
34
34
  getSharedLarkCardNotifier,
35
35
  humanizeValue
36
- } from "./roy-agent-core-shb1qsyg.js";
36
+ } from "./roy-agent-core-0n1wwndq.js";
37
37
  import {
38
38
  RECENT_MESSAGE_LIMIT
39
39
  } from "./roy-agent-core-418zc9ha.js";
40
40
  import {
41
41
  createCompatibleDatabase,
42
42
  init_sqlite_task_store
43
- } from "./roy-agent-core-6k8mb7zx.js";
43
+ } from "./roy-agent-core-m66ysky0.js";
44
44
  import {
45
45
  validateWorkflowDefinition
46
46
  } from "./roy-agent-core-rm7seqwb.js";
@@ -194,7 +194,8 @@ class TaskTagPlugin extends BasePlugin {
194
194
  const keywords = this.extractKeywords(currentTask);
195
195
  if (keywords.length === 0)
196
196
  return;
197
- const similarTasks = await this.tagService?.findSimilarTasksByKeywords?.(keywords, {
197
+ const tagService = (this.taskComponent && typeof this.taskComponent.getTagService === "function" ? this.taskComponent.getTagService() : undefined) ?? this.tagService;
198
+ const similarTasks = await tagService?.findSimilarTasksByKeywords?.(keywords, {
198
199
  limit: 5,
199
200
  excludeTaskId: taskId
200
201
  }) ?? [];
@@ -208,6 +208,37 @@ var init_005_convert_blob_description_to_text = __esm(() => {
208
208
  if (false) {}
209
209
  });
210
210
 
211
+ // src/env/task/storage/migrations/006_add_task_owner.ts
212
+ var exports_006_add_task_owner = {};
213
+ __export(exports_006_add_task_owner, {
214
+ runMigration: () => runMigration6
215
+ });
216
+ function runMigration6(dbPath) {
217
+ logMigration(`[Migration 006] Starting migration for: ${dbPath}`);
218
+ const db = createCompatibleDatabase(dbPath);
219
+ try {
220
+ try {
221
+ db.run(`ALTER TABLE task ADD COLUMN owner TEXT`);
222
+ logMigration(`[Migration 006] Added owner column`);
223
+ } catch (e) {
224
+ if (e.message?.includes("duplicate column name")) {
225
+ logMigration(`[Migration 006] owner column already exists, skipping`);
226
+ } else {
227
+ throw e;
228
+ }
229
+ }
230
+ db.run(`CREATE INDEX IF NOT EXISTS idx_task_owner ON task(owner)`);
231
+ logMigration(`[Migration 006] Migration completed successfully`);
232
+ } finally {
233
+ db.close();
234
+ }
235
+ }
236
+ var init_006_add_task_owner = __esm(() => {
237
+ init_sqlite_task_store();
238
+ init_log_migration();
239
+ if (false) {}
240
+ });
241
+
211
242
  // src/env/task/storage/sqlite-task-store.ts
212
243
  import { join } from "path";
213
244
  function getDatabaseClass() {
@@ -305,7 +336,8 @@ var init_sqlite_task_store = __esm(() => {
305
336
  due_date TEXT,
306
337
  tags TEXT,
307
338
  project_path TEXT NOT NULL DEFAULT 'unknown',
308
- context TEXT NOT NULL DEFAULT '{}'
339
+ context TEXT NOT NULL DEFAULT '{}',
340
+ owner TEXT
309
341
  )
310
342
  `);
311
343
  this.db.run(`
@@ -375,6 +407,17 @@ var init_sqlite_task_store = __esm(() => {
375
407
  } catch (e) {
376
408
  logger.warn(`[Migration 005] Failed to run: ${e.message}`);
377
409
  }
410
+ try {
411
+ const { runMigration: runMigration006 } = (init_006_add_task_owner(), __toCommonJS(exports_006_add_task_owner));
412
+ runMigration006(this.dbPath);
413
+ } catch (e) {
414
+ logger.warn(`[Migration 006] Failed to run: ${e.message}`);
415
+ }
416
+ }
417
+ try {
418
+ this.db.run("CREATE INDEX IF NOT EXISTS idx_task_owner ON task(owner)");
419
+ } catch (e) {
420
+ logger.warn(`[TaskStore] idx_task_owner creation failed: ${e.message}`);
378
421
  }
379
422
  this.initialized = true;
380
423
  logger.info(`TaskStore initialized at ${this.dbPath}`);
@@ -385,10 +428,10 @@ var init_sqlite_task_store = __esm(() => {
385
428
  const stmt = this.db.prepare(`
386
429
  INSERT INTO task (title, description, priority, type, parent_task_id,
387
430
  goals_and_expected_deliverables, due_date, tags, status,
388
- current_status, created_at, updated_at, project_path, context)
389
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, 'todo', '', ?, ?, ?, ?)
431
+ current_status, created_at, updated_at, project_path, context, owner)
432
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, 'todo', '', ?, ?, ?, ?, ?)
390
433
  `);
391
- const result = stmt.run(options.title, options.description || "", options.priority || "medium", options.type || "normal", options.parent_task_id || null, options.goals_and_expected_deliverables || "", options.due_date || null, options.tags ? JSON.stringify(options.tags) : null, now, now, options.project_path, options.context);
434
+ const result = stmt.run(options.title, options.description || "", options.priority || "medium", options.type || "normal", options.parent_task_id || null, options.goals_and_expected_deliverables || "", options.due_date || null, options.tags ? JSON.stringify(options.tags) : null, now, now, options.project_path, options.context, options.owner || null);
392
435
  const task = await this.getTask(result.lastInsertRowid);
393
436
  if (task) {
394
437
  this.tasksCache.set(task.id, task);
@@ -468,6 +511,10 @@ var init_sqlite_task_store = __esm(() => {
468
511
  updates.push("parent_task_id = ?");
469
512
  values.push(options.parent_task_id);
470
513
  }
514
+ if (options.owner !== undefined) {
515
+ updates.push("owner = ?");
516
+ values.push(options.owner || null);
517
+ }
471
518
  if (updates.length === 0)
472
519
  return task;
473
520
  updates.push("updated_at = ?");
@@ -756,7 +803,8 @@ var init_sqlite_task_store = __esm(() => {
756
803
  due_date: row.due_date ? String(row.due_date) : undefined,
757
804
  tags: SQLiteTaskStore.parseTagsSafely(row.tags),
758
805
  project_path: String(row.project_path ?? "unknown"),
759
- context: row.context
806
+ context: row.context,
807
+ owner: row.owner === undefined || row.owner === null ? null : String(row.owner)
760
808
  };
761
809
  }
762
810
  static parseTagsSafely(raw) {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  builtInHandlers
3
- } from "./roy-agent-core-gr5h1dyr.js";
3
+ } from "./roy-agent-core-4b38m749.js";
4
4
  import {
5
5
  appendAuditLog,
6
6
  checkSourceCountDrop,
@@ -0,0 +1,352 @@
1
+ import {
2
+ createLogger,
3
+ init_logger
4
+ } from "./roy-agent-core-7f7t9wwp.js";
5
+
6
+ // src/env/task/storage/remote-task-store.ts
7
+ init_logger();
8
+
9
+ class RemoteTaskStoreError extends Error {
10
+ endpoint;
11
+ cause;
12
+ constructor(message, endpoint, cause) {
13
+ super(message);
14
+ this.endpoint = endpoint;
15
+ this.cause = cause;
16
+ this.name = new.target.name;
17
+ }
18
+ }
19
+
20
+ class RemoteAuthError extends RemoteTaskStoreError {
21
+ }
22
+
23
+ class RemoteIdempotencyConflictError extends RemoteTaskStoreError {
24
+ }
25
+
26
+ class RemoteBatchBusyError extends RemoteTaskStoreError {
27
+ }
28
+
29
+ class RemoteProtocolError extends RemoteTaskStoreError {
30
+ }
31
+ var WRITE_METHODS = new Set([
32
+ "createTask",
33
+ "updateTask",
34
+ "deleteTask",
35
+ "createOperation",
36
+ "updateOperation",
37
+ "deleteOperation",
38
+ "createTag",
39
+ "deleteTag",
40
+ "addTagsToTask",
41
+ "removeTagsFromTask",
42
+ "updateTaskTags"
43
+ ]);
44
+ var REMOTE_TASK_STORE_METHODS = [
45
+ "createTask",
46
+ "getTask",
47
+ "updateTask",
48
+ "deleteTask",
49
+ "listTasks",
50
+ "getTaskIdBySessionId",
51
+ "getTaskIdsBySessionId",
52
+ "createOperation",
53
+ "getOperation",
54
+ "updateOperation",
55
+ "deleteOperation",
56
+ "listOperations",
57
+ "listOperationsFresh",
58
+ "invalidateOperationsCache",
59
+ "createTag",
60
+ "getTag",
61
+ "getTagByName",
62
+ "listTags",
63
+ "searchTags",
64
+ "deleteTag",
65
+ "addTagsToTask",
66
+ "removeTagsFromTask",
67
+ "getTagsForTask",
68
+ "getTaskIdsByTags",
69
+ "updateTaskTags",
70
+ "searchTasksByKeywords",
71
+ "findSimilarTasksByKeywords",
72
+ "getTaskTree",
73
+ "getChildTasks",
74
+ "findSimilarTasks",
75
+ "searchTasks",
76
+ "findTasksByContextValue"
77
+ ];
78
+ var REMOTE_PROTOCOL_MAJOR = 1;
79
+ function trimTrailingNullish(args) {
80
+ let end = args.length;
81
+ while (end > 0) {
82
+ const v = args[end - 1];
83
+ if (v === null || v === undefined)
84
+ end -= 1;
85
+ else
86
+ break;
87
+ }
88
+ return end === args.length ? args : args.slice(0, end);
89
+ }
90
+ var defaultLog = createLogger("task-remote");
91
+
92
+ class RemoteTaskStore {
93
+ endpoint;
94
+ authToken;
95
+ timeoutMs;
96
+ maxRetries;
97
+ retryBaseDelayMs;
98
+ fetchImpl;
99
+ log;
100
+ stats = { handshakes: 0, requests: 0, retries: 0 };
101
+ handshake;
102
+ closed = false;
103
+ constructor(options) {
104
+ if (!options?.endpoint) {
105
+ throw new Error("[RemoteTaskStore] endpoint is required (task.storage.endpoint)");
106
+ }
107
+ this.endpoint = options.endpoint.replace(/\/+$/, "");
108
+ this.authToken = options.authToken;
109
+ this.timeoutMs = options.timeoutMs ?? 5000;
110
+ this.maxRetries = options.maxRetries ?? 3;
111
+ this.retryBaseDelayMs = options.retryBaseDelayMs ?? 200;
112
+ this.fetchImpl = options.fetchImpl ?? globalThis.fetch;
113
+ this.log = options.log ?? defaultLog;
114
+ }
115
+ getStats() {
116
+ return { ...this.stats };
117
+ }
118
+ ensureOpen() {
119
+ if (this.closed) {
120
+ throw new RemoteTaskStoreError(`RemoteTaskStore is closed (endpoint=${this.endpoint})`, this.endpoint);
121
+ }
122
+ }
123
+ async ensureHandshake() {
124
+ if (!this.handshake) {
125
+ this.handshake = this.doHandshake().catch((e) => {
126
+ this.handshake = undefined;
127
+ throw e;
128
+ });
129
+ }
130
+ return this.handshake;
131
+ }
132
+ async doHandshake() {
133
+ this.ensureOpen();
134
+ let res;
135
+ try {
136
+ res = await this.fetchWithTimeout(`${this.endpoint}/version`, { method: "GET" });
137
+ } catch (e) {
138
+ throw new RemoteTaskStoreError(`Cannot reach task-service at ${this.endpoint} (/version): ` + `${e instanceof Error ? e.message : String(e)}. ` + `Start it (systemctl --user start roy-task-service) or set task.storage.endpoint correctly. ` + `No local fallback is performed by design.`, this.endpoint, e);
139
+ }
140
+ if (!res.ok) {
141
+ throw new RemoteProtocolError(`task-service /version returned HTTP ${res.status} (endpoint=${this.endpoint})`, this.endpoint);
142
+ }
143
+ const body = await res.json().catch(() => ({}));
144
+ const major = body?.protocol?.major;
145
+ if (typeof major !== "number") {
146
+ throw new RemoteProtocolError(`task-service /version response has no protocol.major (endpoint=${this.endpoint})`, this.endpoint);
147
+ }
148
+ if (major !== REMOTE_PROTOCOL_MAJOR) {
149
+ throw new RemoteProtocolError(`Protocol mismatch: client speaks store-major ${REMOTE_PROTOCOL_MAJOR}, ` + `task-service speaks ${major} (endpoint=${this.endpoint}). Upgrade one side.`, this.endpoint);
150
+ }
151
+ this.stats.handshakes += 1;
152
+ }
153
+ async fetchWithTimeout(url, init) {
154
+ const controller = new AbortController;
155
+ const timer = setTimeout(() => controller.abort(), this.timeoutMs);
156
+ try {
157
+ return await this.fetchImpl(url, { ...init, signal: controller.signal });
158
+ } finally {
159
+ clearTimeout(timer);
160
+ }
161
+ }
162
+ isRetryableStatus(status) {
163
+ return status === 503 || status === 502 || status === 504 || status >= 500;
164
+ }
165
+ async call(method, rawArgs) {
166
+ this.ensureOpen();
167
+ await this.ensureHandshake();
168
+ const args = trimTrailingNullish(rawArgs);
169
+ const idempotencyKey = WRITE_METHODS.has(method) ? `${method}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}` : undefined;
170
+ let lastError;
171
+ for (let attempt = 0;attempt <= this.maxRetries; attempt++) {
172
+ if (attempt > 0) {
173
+ this.stats.retries += 1;
174
+ const backoff = this.retryBaseDelayMs * 2 ** (attempt - 1);
175
+ this.log.debug?.(`[RemoteTaskStore] retry ${attempt}/${this.maxRetries} ${method} in ${backoff}ms`);
176
+ await new Promise((r) => setTimeout(r, backoff));
177
+ }
178
+ const headers = { "content-type": "application/json" };
179
+ if (this.authToken)
180
+ headers.authorization = `Bearer ${this.authToken}`;
181
+ if (idempotencyKey)
182
+ headers["idempotency-key"] = idempotencyKey;
183
+ this.stats.requests += 1;
184
+ let res;
185
+ try {
186
+ res = await this.fetchWithTimeout(`${this.endpoint}/store/${method}`, {
187
+ method: "POST",
188
+ headers,
189
+ body: JSON.stringify({ args })
190
+ });
191
+ } catch (e) {
192
+ lastError = e;
193
+ if (attempt === this.maxRetries) {
194
+ throw new RemoteTaskStoreError(`task-service request failed: ${method} (endpoint=${this.endpoint}) after ` + `${attempt + 1} attempts: ${e instanceof Error ? e.message : String(e)}. ` + `No local fallback is performed by design.`, this.endpoint, e);
195
+ }
196
+ continue;
197
+ }
198
+ if (res.ok) {
199
+ const text = await res.text();
200
+ if (!text)
201
+ return;
202
+ try {
203
+ return JSON.parse(text);
204
+ } catch (e) {
205
+ throw new RemoteTaskStoreError(`task-service returned non-JSON for ${method} (endpoint=${this.endpoint})`, this.endpoint, e);
206
+ }
207
+ }
208
+ const body = await res.json().catch(() => null);
209
+ const code = body?.error?.code ?? "";
210
+ const detail = body?.error?.message ?? `HTTP ${res.status}`;
211
+ if (res.status === 401) {
212
+ throw new RemoteAuthError(`task-service rejected the request (401 ${code}): ${detail}. ` + `Check task.storage.authToken against the service's TASK_AUTH_TOKEN ` + `(endpoint=${this.endpoint}).`, this.endpoint);
213
+ }
214
+ if (res.status === 409 && code === "IDEMPOTENCY_CONFLICT") {
215
+ throw new RemoteIdempotencyConflictError(`task-service idempotency conflict for ${method}: ${detail} (endpoint=${this.endpoint})`, this.endpoint);
216
+ }
217
+ if (res.status === 404 && code === "METHOD_NOT_FOUND") {
218
+ throw new RemoteProtocolError(`task-service does not implement ${method}() — service is older than this client ` + `(endpoint=${this.endpoint}). deploy a newer task-service.`, this.endpoint);
219
+ }
220
+ if (res.status === 400) {
221
+ throw new RemoteTaskStoreError(`task-service rejected ${method} payload (400 ${code}): ${detail} (endpoint=${this.endpoint})`, this.endpoint);
222
+ }
223
+ if (res.status === 503 && code === "BUSY") {
224
+ lastError = new RemoteBatchBusyError(`sqlite backend busy for ${method}: a batch transaction holds the single shared ` + `connection; retried ${this.maxRetries} times without success (endpoint=${this.endpoint}). ` + `Retry after the batch completes.`, this.endpoint);
225
+ if (attempt === this.maxRetries)
226
+ throw lastError;
227
+ continue;
228
+ }
229
+ if (this.isRetryableStatus(res.status)) {
230
+ lastError = new RemoteTaskStoreError(`task-service error for ${method} (HTTP ${res.status} ${code}): ${detail} ` + `(endpoint=${this.endpoint})`, this.endpoint);
231
+ if (attempt === this.maxRetries)
232
+ throw lastError;
233
+ continue;
234
+ }
235
+ throw new RemoteTaskStoreError(`task-service rejected ${method} (HTTP ${res.status} ${code}): ${detail} ` + `(endpoint=${this.endpoint})`, this.endpoint);
236
+ }
237
+ throw new RemoteTaskStoreError(`task-service call ${method} exhausted retries (endpoint=${this.endpoint}): ` + `${lastError instanceof Error ? lastError.message : String(lastError)}`, this.endpoint, lastError);
238
+ }
239
+ createTask(options) {
240
+ return this.call("createTask", [options]);
241
+ }
242
+ async getTask(id) {
243
+ const task = await this.call("getTask", [id]);
244
+ return task ?? undefined;
245
+ }
246
+ async updateTask(id, options) {
247
+ const task = await this.call("updateTask", [id, options]);
248
+ return task ?? undefined;
249
+ }
250
+ deleteTask(id) {
251
+ return this.call("deleteTask", [id]);
252
+ }
253
+ listTasks(options) {
254
+ return this.call("listTasks", [options]);
255
+ }
256
+ async getTaskIdBySessionId(sessionId) {
257
+ const id = await this.call("getTaskIdBySessionId", [sessionId]);
258
+ return id ?? undefined;
259
+ }
260
+ getTaskIdsBySessionId(sessionId) {
261
+ return this.call("getTaskIdsBySessionId", [sessionId]);
262
+ }
263
+ createOperation(options) {
264
+ return this.call("createOperation", [options]);
265
+ }
266
+ async getOperation(id) {
267
+ const op = await this.call("getOperation", [id]);
268
+ return op ?? undefined;
269
+ }
270
+ async updateOperation(id, updates) {
271
+ const op = await this.call("updateOperation", [id, updates]);
272
+ return op ?? undefined;
273
+ }
274
+ deleteOperation(id) {
275
+ return this.call("deleteOperation", [id]);
276
+ }
277
+ listOperations(options) {
278
+ return this.call("listOperations", [options]);
279
+ }
280
+ listOperationsFresh(options) {
281
+ return this.call("listOperationsFresh", [options]);
282
+ }
283
+ invalidateOperationsCache(taskId) {
284
+ this.call("invalidateOperationsCache", [taskId]).catch((e) => {
285
+ this.log.warn?.(`[RemoteTaskStore] invalidateOperationsCache(${taskId}) failed: ` + `${e instanceof Error ? e.message : String(e)}`);
286
+ });
287
+ }
288
+ createTag(name) {
289
+ return this.call("createTag", [name]);
290
+ }
291
+ async getTag(id) {
292
+ const tag = await this.call("getTag", [id]);
293
+ return tag ?? undefined;
294
+ }
295
+ async getTagByName(name) {
296
+ const tag = await this.call("getTagByName", [name]);
297
+ return tag ?? undefined;
298
+ }
299
+ listTags(options) {
300
+ return this.call("listTags", [options]);
301
+ }
302
+ searchTags(options) {
303
+ return this.call("searchTags", [options]);
304
+ }
305
+ deleteTag(id) {
306
+ return this.call("deleteTag", [id]);
307
+ }
308
+ async addTagsToTask(taskId, tagIds) {
309
+ await this.call("addTagsToTask", [taskId, tagIds]);
310
+ }
311
+ async removeTagsFromTask(taskId, tagIds) {
312
+ await this.call("removeTagsFromTask", [taskId, tagIds]);
313
+ }
314
+ getTagsForTask(taskId) {
315
+ return this.call("getTagsForTask", [taskId]);
316
+ }
317
+ getTaskIdsByTags(tagNames) {
318
+ return this.call("getTaskIdsByTags", [tagNames]);
319
+ }
320
+ async updateTaskTags(taskId, tagNames) {
321
+ await this.call("updateTaskTags", [taskId, tagNames]);
322
+ }
323
+ searchTasksByKeywords(keywords, options) {
324
+ return this.call("searchTasksByKeywords", [keywords, options]);
325
+ }
326
+ findSimilarTasksByKeywords(keywords, options) {
327
+ return this.call("findSimilarTasksByKeywords", [keywords, options]);
328
+ }
329
+ getTaskTree(taskId, depth) {
330
+ return this.call("getTaskTree", [taskId, depth]);
331
+ }
332
+ getChildTasks(taskId, options) {
333
+ return this.call("getChildTasks", [taskId, options]);
334
+ }
335
+ findSimilarTasks(taskId, limit) {
336
+ return this.call("findSimilarTasks", [taskId, limit]);
337
+ }
338
+ searchTasks(query, limit) {
339
+ return this.call("searchTasks", [query, limit]);
340
+ }
341
+ findTasksByContextValue(value, limit) {
342
+ return this.call("findTasksByContextValue", [value, limit]);
343
+ }
344
+ close() {
345
+ this.closed = true;
346
+ }
347
+ }
348
+ function createRemoteTaskStore(options) {
349
+ return new RemoteTaskStore(options);
350
+ }
351
+
352
+ export { RemoteTaskStoreError, RemoteAuthError, RemoteIdempotencyConflictError, RemoteBatchBusyError, RemoteProtocolError, REMOTE_TASK_STORE_METHODS, REMOTE_PROTOCOL_MAJOR, RemoteTaskStore, createRemoteTaskStore };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-setting/roy-agent-core",
3
- "version": "1.7.88",
3
+ "version": "1.7.90",
4
4
  "type": "module",
5
5
  "description": "Core SDK for roy-agent - Environment, Components, Tools, Sessions, Tasks",
6
6
  "main": "./dist/index.js",