@ai-setting/roy-agent-core 1.7.88 → 1.7.89
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/event-source/event-source-handlers.js +6 -6
- package/dist/env/event-source/index.js +7 -7
- package/dist/env/event-source/wecom-session-card-sender.js +2 -2
- package/dist/env/index.js +12 -11
- package/dist/env/task/backend/index.d.ts +3 -0
- package/dist/env/task/backend/index.js +151 -3
- package/dist/env/task/backend/remote-task-port.d.ts +85 -0
- package/dist/env/task/backend/types.d.ts +5 -0
- package/dist/env/task/index.d.ts +1 -1
- package/dist/env/task/index.js +20 -4
- package/dist/env/task/mcp/index.js +1 -1
- package/dist/env/task/plugins/index.js +3 -3
- package/dist/env/task/plugins/lark-card-patch-notifier.js +2 -2
- package/dist/env/task/plugins/wecom-session-card-store.js +2 -2
- package/dist/env/task/storage/index.d.ts +1 -0
- package/dist/env/task/storage/index.js +23 -3
- package/dist/env/task/storage/migrations/006_add_task_owner.d.ts +24 -0
- package/dist/env/task/storage/remote-task-store.d.ts +186 -0
- package/dist/env/task/task-component.d.ts +7 -0
- package/dist/env/task/tools/index.js +1 -1
- package/dist/env/task/tools/task-types.d.ts +7 -0
- package/dist/env/task/types.d.ts +17 -0
- package/dist/env/workflow/plugins/index.js +3 -3
- package/dist/index.d.ts +1 -1
- package/dist/index.js +17 -11
- package/dist/shared/@ai-setting/{roy-agent-core-vpcxv1ty.js → roy-agent-core-05z35shp.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-shb1qsyg.js → roy-agent-core-0n1wwndq.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-fan8g0z1.js → roy-agent-core-49qcpqwg.js} +46 -11
- package/dist/shared/@ai-setting/{roy-agent-core-gr5h1dyr.js → roy-agent-core-4b38m749.js} +4 -4
- package/dist/shared/@ai-setting/{roy-agent-core-wr1qexzq.js → roy-agent-core-5dhvfgaw.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-qwd2dq5q.js → roy-agent-core-9cen1jvg.js} +8 -4
- package/dist/shared/@ai-setting/{roy-agent-core-7kvpc0w5.js → roy-agent-core-age3qseb.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-an35dzbf.js → roy-agent-core-dvec4nn2.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-ra66sf50.js → roy-agent-core-k3h8t4q1.js} +4 -3
- package/dist/shared/@ai-setting/{roy-agent-core-6k8mb7zx.js → roy-agent-core-m66ysky0.js} +53 -5
- package/dist/shared/@ai-setting/{roy-agent-core-yh68z1bg.js → roy-agent-core-m7d1t3db.js} +1 -1
- package/dist/shared/@ai-setting/roy-agent-core-zhwcje5a.js +352 -0
- package/package.json +1 -1
|
@@ -33,14 +33,14 @@ import {
|
|
|
33
33
|
createLarkCardStateStore,
|
|
34
34
|
getSharedLarkCardNotifier,
|
|
35
35
|
humanizeValue
|
|
36
|
-
} from "./roy-agent-core-
|
|
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-
|
|
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
|
|
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) {
|
|
@@ -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 };
|