@kafca/agentdock 0.1.23 → 0.1.25
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/README.md +3 -0
- package/dist/renderer/assets/{Badge-C2K5apfV.js → Badge-Bn2h-Qkf.js} +1 -1
- package/dist/renderer/assets/{Chat-DI2YeVKb.js → Chat-Cgo9aneg.js} +1 -1
- package/dist/renderer/assets/{ChatMarkdown-DMAr15Oi.js → ChatMarkdown-CYzHfSiR.js} +1 -1
- package/dist/renderer/assets/{Config-7rP3EuUf.js → Config-DljB2-eP.js} +1 -1
- package/dist/renderer/assets/{CronList-81QslYE8.js → CronList-DeVbiY9a.js} +1 -1
- package/dist/renderer/assets/{Dashboard-Db2T7rSZ.js → Dashboard-fSqx5sm8.js} +2 -2
- package/dist/renderer/assets/{EmptyState-BBJ3cTvB.js → EmptyState-DgqKDwlq.js} +1 -1
- package/dist/renderer/assets/{KnowledgeDetail-Dz_6flG3.js → KnowledgeDetail-u8s2SmPV.js} +1 -1
- package/dist/renderer/assets/{KnowledgeHome-DIh046mN.js → KnowledgeHome-BdQw8nbY.js} +1 -1
- package/dist/renderer/assets/{Logs-BXBtHJLf.js → Logs-DSbndMpy.js} +1 -1
- package/dist/renderer/assets/{Modal-BB2Av_Xs.js → Modal-0d0EmAuK.js} +1 -1
- package/dist/renderer/assets/{Page-DPSdvMgU.js → Page-CVbOH_Kh.js} +1 -1
- package/dist/renderer/assets/{ProjectDetail-C6EWGvGg.js → ProjectDetail-C91tF7uA.js} +1 -1
- package/dist/renderer/assets/{ProjectList-BBo5ygnS.js → ProjectList-D78Pc-BQ.js} +1 -1
- package/dist/renderer/assets/{Select-CNX-Tx_O.js → Select-BbKzAIuO.js} +1 -1
- package/dist/renderer/assets/{SessionChat-BIn46jqZ.js → SessionChat-BERvL5e4.js} +1 -1
- package/dist/renderer/assets/{SessionList-CZt6f1Rd.js → SessionList-Bomz335M.js} +1 -1
- package/dist/renderer/assets/ThreadChat-CLr3amU2.js +23 -0
- package/dist/renderer/assets/{Workspace-C_4tdpjX.js → Workspace-In91z4W2.js} +1 -1
- package/dist/renderer/assets/{arrow-left-cHr5wkpq.js → arrow-left-FBnVKKBl.js} +1 -1
- package/dist/renderer/assets/{book-open-4nx5C8T-.js → book-open-4_CuP6Sa.js} +1 -1
- package/dist/renderer/assets/{check-exTS-R-x.js → check-vsoVjvac.js} +1 -1
- package/dist/renderer/assets/{chevron-down-DSvxXQa0.js → chevron-down-DFpmFTJW.js} +1 -1
- package/dist/renderer/assets/{circle-DyvEovdw.js → circle-vRULegER.js} +1 -1
- package/dist/renderer/assets/desktop-BkMW-h5p.js +4 -0
- package/dist/renderer/assets/{desktop-B-KVT10D.js → desktop-ul0Tpzyc.js} +1 -1
- package/dist/renderer/assets/{funnel-DA9qVdTy.js → funnel-Gu0E_hJ_.js} +1 -1
- package/dist/renderer/assets/{heart-DuEV0ZRJ.js → heart-DsdofOHf.js} +1 -1
- package/dist/renderer/assets/{index-Biz-aexG.js → index-BD3aCyBa.js} +3 -3
- package/dist/renderer/assets/{index-BgflqkCN.js → index-pJUFobU7.js} +1 -1
- package/dist/renderer/assets/{pencil-DBDxeNmO.js → pencil-DbKmV8nD.js} +1 -1
- package/dist/renderer/assets/{play-IzlP83_7.js → play-BDMsRxSm.js} +1 -1
- package/dist/renderer/assets/{plug-CuT-qFnW.js → plug-t2dMl78-.js} +1 -1
- package/dist/renderer/assets/{plus-DEqgkn63.js → plus-BUb6zOAe.js} +1 -1
- package/dist/renderer/assets/projects-4F6D_Q8t.js +1 -0
- package/dist/renderer/assets/{save-D4sRo07y.js → save-C-_5rQdv.js} +1 -1
- package/dist/renderer/assets/{search-DbPZLuV8.js → search-R3ekHFPM.js} +1 -1
- package/dist/renderer/assets/{server-D1jUQmwN.js → server-BTuvHf5n.js} +1 -1
- package/dist/renderer/assets/{session-utils-Aife8ep2.js → session-utils-ClX6VPFG.js} +1 -1
- package/dist/renderer/assets/{sessions-DaH3H7gC.js → sessions-AFKIC-ub.js} +1 -1
- package/dist/renderer/assets/{shield-check-BGwUFWNr.js → shield-check-CqMW8CHe.js} +1 -1
- package/dist/renderer/assets/{trash-2-CIFBioBa.js → trash-2-BNLcHyUw.js} +1 -1
- package/dist/renderer/assets/{user-CnKcvHdo.js → user-BCCN8FYK.js} +1 -1
- package/dist/renderer/assets/{wifi-off-ClO53WGa.js → wifi-off-BsNsx3oX.js} +1 -1
- package/dist/renderer/index.html +1 -1
- package/dist-electron/electron/agent-runtime-detector.test.js +64 -0
- package/dist-electron/electron/architecture-docs.test.js +56 -0
- package/dist-electron/electron/channel-content.test.js +37 -0
- package/dist-electron/electron/lac-cli.test.js +297 -4
- package/dist-electron/electron/local-core-acp-content.test.js +39 -0
- package/dist-electron/electron/local-core-contracts.test.js +67 -0
- package/dist-electron/electron/local-core-refactor.test.js +789 -3
- package/dist-electron/electron/plugin-kernel.test.js +108 -0
- package/dist-electron/electron/renderer-packaging.test.js +77 -0
- package/dist-electron/electron/workspace-task-store.test.js +181 -0
- package/dist-electron/packages/contracts/src/local-core.js +110 -0
- package/dist-electron/services/local-ai-core/src/acp/local-core-acp-backend.js +67 -6
- package/dist-electron/services/local-ai-core/src/acp/local-core-acp-content.js +25 -4
- package/dist-electron/services/local-ai-core/src/acp/local-core-acp-permission-lifecycle.js +76 -0
- package/dist-electron/services/local-ai-core/src/acp/local-core-acp-progress.js +201 -0
- package/dist-electron/services/local-ai-core/src/acp/local-core-acp-response-processor.js +3 -2
- package/dist-electron/services/local-ai-core/src/acp/local-core-acp-session-coordinator.js +29 -0
- package/dist-electron/services/local-ai-core/src/acp/local-core-acp-store.js +74 -46
- package/dist-electron/services/local-ai-core/src/acp/local-core-acp-turn-coordinator.js +112 -210
- package/dist-electron/services/local-ai-core/src/acp/local-core-slash-commands.js +60 -0
- package/dist-electron/services/local-ai-core/src/acp/workspace-acp-permissions.js +5 -48
- package/dist-electron/services/local-ai-core/src/channel/lark/local-core-lark-gateway.js +83 -28
- package/dist-electron/services/local-ai-core/src/channel/lark/runtime-state.js +11 -0
- package/dist-electron/services/local-ai-core/src/channel/shared/content.js +23 -0
- package/dist-electron/services/local-ai-core/src/channel/shared/file-utils.js +13 -1
- package/dist-electron/services/local-ai-core/src/channel/weixin/local-core-weixin-gateway.js +31 -29
- package/dist-electron/services/local-ai-core/src/cli/lac.js +22 -17
- package/dist-electron/services/local-ai-core/src/kernel/bootstrap.js +1 -0
- package/dist-electron/services/local-ai-core/src/plugins/builtin/agent-localcore-acp-plugin.js +9 -0
- package/dist-electron/services/local-ai-core/src/router/workspace-route-config.js +221 -10
- package/dist-electron/services/local-ai-core/src/runtime/agent-runtime-detector.js +39 -9
- package/dist-electron/services/local-ai-core/src/runtime/local-core-controller.js +1 -0
- package/dist-electron/services/local-ai-core/src/runtime/runtime-detection-service.js +1 -0
- package/dist-electron/services/local-ai-core/src/runtime/server-routes.js +439 -0
- package/dist-electron/services/local-ai-core/src/runtime/server.js +208 -303
- package/dist-electron/services/local-ai-core/src/scheduler/job-id.js +15 -0
- package/dist-electron/services/local-ai-core/src/scheduler/scheduler-service.js +30 -5
- package/dist-electron/shared/desktop.js +34 -8
- package/dist-electron/src/pages/Threads/thread-chat-message-blocks.js +187 -0
- package/dist-electron/src/pages/Threads/thread-chat-model.js +58 -0
- package/dist-electron/src/pages/Threads/thread-chat-page-state.js +96 -0
- package/dist-electron/src/pages/Threads/thread-chat-permission.js +18 -0
- package/dist-electron/src/pages/Threads/thread-chat-permission.test.js +347 -0
- package/package.json +4 -2
- package/dist/renderer/assets/ThreadChat-BotD0gKQ.js +0 -23
- package/dist/renderer/assets/desktop-CVibRyAw.js +0 -4
- package/dist/renderer/assets/projects-DDtDN1rc.js +0 -1
|
@@ -6,6 +6,8 @@ const node_crypto_1 = require("node:crypto");
|
|
|
6
6
|
const node_fs_1 = require("node:fs");
|
|
7
7
|
const node_sqlite_1 = require("node:sqlite");
|
|
8
8
|
const node_path_1 = require("node:path");
|
|
9
|
+
const index_js_1 = require("../../../../packages/contracts/src/index.js");
|
|
10
|
+
const job_id_js_1 = require("../scheduler/job-id.js");
|
|
9
11
|
const desktop_js_1 = require("../../../../shared/desktop.js");
|
|
10
12
|
const workspace_thread_mappers_js_1 = require("../thread/workspace-thread-mappers.js");
|
|
11
13
|
const workspace_thread_id_js_1 = require("../thread/workspace-thread-id.js");
|
|
@@ -29,7 +31,8 @@ class LocalCoreAcpStore {
|
|
|
29
31
|
history_count INTEGER NOT NULL DEFAULT 0,
|
|
30
32
|
excerpt TEXT NOT NULL DEFAULT '',
|
|
31
33
|
acp_session_id TEXT,
|
|
32
|
-
acp_supports_load INTEGER NOT NULL DEFAULT 0
|
|
34
|
+
acp_supports_load INTEGER NOT NULL DEFAULT 0,
|
|
35
|
+
agent_mode TEXT NOT NULL DEFAULT 'default'
|
|
33
36
|
);
|
|
34
37
|
CREATE INDEX IF NOT EXISTS idx_threads_workspace_updated ON threads (workspace_id, updated_at DESC);
|
|
35
38
|
CREATE TABLE IF NOT EXISTS messages (
|
|
@@ -37,6 +40,7 @@ class LocalCoreAcpStore {
|
|
|
37
40
|
thread_id TEXT NOT NULL,
|
|
38
41
|
role TEXT NOT NULL,
|
|
39
42
|
content TEXT NOT NULL,
|
|
43
|
+
tool_call_json TEXT,
|
|
40
44
|
timestamp TEXT NOT NULL,
|
|
41
45
|
kind TEXT NOT NULL,
|
|
42
46
|
seq INTEGER NOT NULL,
|
|
@@ -217,14 +221,16 @@ class LocalCoreAcpStore {
|
|
|
217
221
|
CREATE INDEX IF NOT EXISTS idx_audit_events_task_created ON audit_events (task_id, created_at DESC);
|
|
218
222
|
CREATE INDEX IF NOT EXISTS idx_audit_events_type_created ON audit_events (type, created_at DESC);
|
|
219
223
|
`);
|
|
224
|
+
this.ensureColumn('messages', 'tool_call_json', 'TEXT');
|
|
220
225
|
this.ensureColumn('scheduled_jobs', 'execution_mode', "TEXT NOT NULL DEFAULT 'same-thread'");
|
|
226
|
+
this.ensureColumn('threads', 'agent_mode', "TEXT NOT NULL DEFAULT 'default'");
|
|
221
227
|
}
|
|
222
228
|
close() {
|
|
223
229
|
this.db.close();
|
|
224
230
|
}
|
|
225
231
|
listThreadSummaries(workspaceId) {
|
|
226
232
|
const rows = this.db.prepare(`
|
|
227
|
-
SELECT id, workspace_id, session_id, bridge_session_key, title, agent_type, created_at, updated_at, history_count, excerpt
|
|
233
|
+
SELECT id, workspace_id, session_id, bridge_session_key, title, agent_type, created_at, updated_at, history_count, excerpt, acp_session_id, acp_supports_load, agent_mode
|
|
228
234
|
FROM threads
|
|
229
235
|
WHERE workspace_id = ?
|
|
230
236
|
ORDER BY updated_at DESC
|
|
@@ -247,15 +253,15 @@ class LocalCoreAcpStore {
|
|
|
247
253
|
const row = this.db.prepare('SELECT COUNT(*) AS total FROM threads WHERE workspace_id = ?').get(workspaceId);
|
|
248
254
|
return Number(row?.total || 0);
|
|
249
255
|
}
|
|
250
|
-
createThread(workspaceId, title, agentType = desktop_js_1.LOCALCORE_ACP_AGENT_TYPE) {
|
|
256
|
+
createThread(workspaceId, title, agentType = desktop_js_1.LOCALCORE_ACP_AGENT_TYPE, agentMode = 'default') {
|
|
251
257
|
const sessionId = (0, node_crypto_1.randomUUID)();
|
|
252
258
|
const threadId = (0, workspace_thread_id_js_1.encodeThreadId)(workspaceId, sessionId);
|
|
253
259
|
const now = new Date().toISOString();
|
|
254
260
|
const bridgeSessionKey = `${desktop_js_1.LOCALCORE_ACP_AGENT_TYPE}:${workspaceId}:${sessionId}`;
|
|
255
261
|
this.db.prepare(`
|
|
256
|
-
INSERT INTO threads (id, workspace_id, session_id, bridge_session_key, title, agent_type, created_at, updated_at, history_count, excerpt)
|
|
257
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, 0, '')
|
|
258
|
-
`).run(threadId, workspaceId, sessionId, bridgeSessionKey, title, agentType, now, now);
|
|
262
|
+
INSERT INTO threads (id, workspace_id, session_id, bridge_session_key, title, agent_type, created_at, updated_at, history_count, excerpt, agent_mode)
|
|
263
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, 0, '', ?)
|
|
264
|
+
`).run(threadId, workspaceId, sessionId, bridgeSessionKey, title, agentType, now, now, agentMode || 'default');
|
|
259
265
|
return {
|
|
260
266
|
id: threadId,
|
|
261
267
|
workspaceId,
|
|
@@ -278,7 +284,7 @@ class LocalCoreAcpStore {
|
|
|
278
284
|
throw new Error(`Thread not found: ${threadId}`);
|
|
279
285
|
}
|
|
280
286
|
const messages = this.db.prepare(`
|
|
281
|
-
SELECT id, thread_id, role, content, timestamp, kind, seq
|
|
287
|
+
SELECT id, thread_id, role, content, tool_call_json, timestamp, kind, seq
|
|
282
288
|
FROM messages
|
|
283
289
|
WHERE thread_id = ?
|
|
284
290
|
ORDER BY seq ASC
|
|
@@ -298,6 +304,7 @@ class LocalCoreAcpStore {
|
|
|
298
304
|
id: message.id,
|
|
299
305
|
role: message.role,
|
|
300
306
|
content: message.content,
|
|
307
|
+
toolCall: parseJson(message.tool_call_json || 'null', null) || undefined,
|
|
301
308
|
timestamp: message.timestamp,
|
|
302
309
|
kind: message.kind,
|
|
303
310
|
})),
|
|
@@ -312,7 +319,7 @@ class LocalCoreAcpStore {
|
|
|
312
319
|
deleteThread(threadId) {
|
|
313
320
|
this.db.prepare('DELETE FROM threads WHERE id = ?').run(threadId);
|
|
314
321
|
}
|
|
315
|
-
appendMessage(threadId, role, content, kind) {
|
|
322
|
+
appendMessage(threadId, role, content, kind, toolCall) {
|
|
316
323
|
const timestamp = new Date().toISOString();
|
|
317
324
|
const nextSequenceRow = this.db.prepare('SELECT COALESCE(MAX(seq), -1) + 1 AS next_seq FROM messages WHERE thread_id = ?').get(threadId);
|
|
318
325
|
const nextSeq = Number(nextSequenceRow?.next_seq || 0);
|
|
@@ -321,9 +328,9 @@ class LocalCoreAcpStore {
|
|
|
321
328
|
this.db.exec('BEGIN IMMEDIATE');
|
|
322
329
|
try {
|
|
323
330
|
this.db.prepare(`
|
|
324
|
-
INSERT INTO messages (id, thread_id, role, content, timestamp, kind, seq)
|
|
325
|
-
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
326
|
-
`).run(id, threadId, role, content, timestamp, kind, nextSeq);
|
|
331
|
+
INSERT INTO messages (id, thread_id, role, content, tool_call_json, timestamp, kind, seq)
|
|
332
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
333
|
+
`).run(id, threadId, role, content, toolCall ? JSON.stringify(toolCall) : null, timestamp, kind, nextSeq);
|
|
327
334
|
this.db.prepare(`
|
|
328
335
|
UPDATE threads
|
|
329
336
|
SET updated_at = ?, history_count = history_count + 1, excerpt = ?
|
|
@@ -337,7 +344,7 @@ class LocalCoreAcpStore {
|
|
|
337
344
|
}
|
|
338
345
|
return { id, timestamp };
|
|
339
346
|
}
|
|
340
|
-
upsertMessage(threadId, id, role, content, kind) {
|
|
347
|
+
upsertMessage(threadId, id, role, content, kind, toolCall) {
|
|
341
348
|
const timestamp = new Date().toISOString();
|
|
342
349
|
const excerpt = (0, workspace_thread_mappers_js_1.normalizeMessageContent)(content);
|
|
343
350
|
const existing = this.db.prepare('SELECT id FROM messages WHERE id = ? AND thread_id = ?').get(id, threadId);
|
|
@@ -346,17 +353,17 @@ class LocalCoreAcpStore {
|
|
|
346
353
|
if (existing) {
|
|
347
354
|
this.db.prepare(`
|
|
348
355
|
UPDATE messages
|
|
349
|
-
SET content = ?, timestamp = ?, kind = ?
|
|
356
|
+
SET content = ?, tool_call_json = ?, timestamp = ?, kind = ?
|
|
350
357
|
WHERE id = ? AND thread_id = ?
|
|
351
|
-
`).run(content, timestamp, kind, id, threadId);
|
|
358
|
+
`).run(content, toolCall ? JSON.stringify(toolCall) : null, timestamp, kind, id, threadId);
|
|
352
359
|
}
|
|
353
360
|
else {
|
|
354
361
|
const nextSequenceRow = this.db.prepare('SELECT COALESCE(MAX(seq), -1) + 1 AS next_seq FROM messages WHERE thread_id = ?').get(threadId);
|
|
355
362
|
const nextSeq = Number(nextSequenceRow?.next_seq || 0);
|
|
356
363
|
this.db.prepare(`
|
|
357
|
-
INSERT INTO messages (id, thread_id, role, content, timestamp, kind, seq)
|
|
358
|
-
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
359
|
-
`).run(id, threadId, role, content, timestamp, kind, nextSeq);
|
|
364
|
+
INSERT INTO messages (id, thread_id, role, content, tool_call_json, timestamp, kind, seq)
|
|
365
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
366
|
+
`).run(id, threadId, role, content, toolCall ? JSON.stringify(toolCall) : null, timestamp, kind, nextSeq);
|
|
360
367
|
this.db.prepare(`
|
|
361
368
|
UPDATE threads
|
|
362
369
|
SET history_count = history_count + 1
|
|
@@ -378,31 +385,34 @@ class LocalCoreAcpStore {
|
|
|
378
385
|
}
|
|
379
386
|
updateRun(runId, threadId, status) {
|
|
380
387
|
const now = new Date().toISOString();
|
|
388
|
+
const normalizedStatus = (0, index_js_1.normalizeRunStatus)(status);
|
|
381
389
|
const existing = this.db.prepare('SELECT id FROM runs WHERE id = ?').get(runId);
|
|
382
390
|
if (existing) {
|
|
383
|
-
this.db.prepare('UPDATE runs SET status = ?, updated_at = ? WHERE id = ?').run(
|
|
391
|
+
this.db.prepare('UPDATE runs SET status = ?, updated_at = ? WHERE id = ?').run(normalizedStatus, now, runId);
|
|
384
392
|
return;
|
|
385
393
|
}
|
|
386
394
|
this.db.prepare(`
|
|
387
395
|
INSERT INTO runs (id, thread_id, status, started_at, updated_at)
|
|
388
396
|
VALUES (?, ?, ?, ?, ?)
|
|
389
|
-
`).run(runId, threadId,
|
|
397
|
+
`).run(runId, threadId, normalizedStatus, now, now);
|
|
390
398
|
}
|
|
391
399
|
getLatestRunForThread(threadId) {
|
|
392
|
-
|
|
400
|
+
const row = this.db.prepare(`
|
|
393
401
|
SELECT id, thread_id, status, started_at, updated_at
|
|
394
402
|
FROM runs
|
|
395
403
|
WHERE thread_id = ?
|
|
396
404
|
ORDER BY updated_at DESC
|
|
397
405
|
LIMIT 1
|
|
398
406
|
`).get(threadId);
|
|
407
|
+
return row ? { ...row, status: (0, index_js_1.normalizeRunStatus)(row.status) } : undefined;
|
|
399
408
|
}
|
|
400
409
|
getRun(runId) {
|
|
401
|
-
|
|
410
|
+
const row = this.db.prepare(`
|
|
402
411
|
SELECT id, thread_id, status, started_at, updated_at
|
|
403
412
|
FROM runs
|
|
404
413
|
WHERE id = ?
|
|
405
414
|
`).get(runId);
|
|
415
|
+
return row ? { ...row, status: (0, index_js_1.normalizeRunStatus)(row.status) } : undefined;
|
|
406
416
|
}
|
|
407
417
|
listWorkspaceRegistry() {
|
|
408
418
|
const rows = this.db.prepare(`
|
|
@@ -573,7 +583,7 @@ class LocalCoreAcpStore {
|
|
|
573
583
|
params.push(query.taskId);
|
|
574
584
|
}
|
|
575
585
|
if (query.status) {
|
|
576
|
-
const statuses = Array.isArray(query.status) ? query.status : [query.status];
|
|
586
|
+
const statuses = (Array.isArray(query.status) ? query.status : [query.status]).map((status) => (0, index_js_1.normalizeApprovalRequestStatus)(status));
|
|
577
587
|
predicates.push(`status IN (${statuses.map(() => '?').join(', ')})`);
|
|
578
588
|
params.push(...statuses);
|
|
579
589
|
}
|
|
@@ -669,7 +679,7 @@ class LocalCoreAcpStore {
|
|
|
669
679
|
createAgentTask(input) {
|
|
670
680
|
const id = `task:${(0, node_crypto_1.randomUUID)()}`;
|
|
671
681
|
const now = new Date().toISOString();
|
|
672
|
-
const status = input.status
|
|
682
|
+
const status = (0, index_js_1.normalizeAgentTaskStatus)(input.status);
|
|
673
683
|
const timeline = [{
|
|
674
684
|
id: `timeline:${(0, node_crypto_1.randomUUID)()}`,
|
|
675
685
|
type: 'status_change',
|
|
@@ -706,7 +716,7 @@ class LocalCoreAcpStore {
|
|
|
706
716
|
params.push(query.runtimeId);
|
|
707
717
|
}
|
|
708
718
|
if (query.status) {
|
|
709
|
-
const statuses = Array.isArray(query.status) ? query.status : [query.status];
|
|
719
|
+
const statuses = (Array.isArray(query.status) ? query.status : [query.status]).map((status) => (0, index_js_1.normalizeAgentTaskStatus)(status));
|
|
710
720
|
predicates.push(`status IN (${statuses.map(() => '?').join(', ')})`);
|
|
711
721
|
params.push(...statuses);
|
|
712
722
|
}
|
|
@@ -735,17 +745,17 @@ class LocalCoreAcpStore {
|
|
|
735
745
|
throw new Error(`Task not found: ${taskId}`);
|
|
736
746
|
}
|
|
737
747
|
const now = new Date().toISOString();
|
|
738
|
-
const nextStatus = input.status
|
|
748
|
+
const nextStatus = input.status ? (0, index_js_1.normalizeAgentTaskStatus)(input.status) : existing.status;
|
|
739
749
|
const timeline = [...existing.timeline];
|
|
740
750
|
const logs = [...existing.logs];
|
|
741
751
|
const artifacts = [...existing.artifacts];
|
|
742
752
|
const approvalIds = [...existing.approvalIds];
|
|
743
|
-
if (input.status &&
|
|
753
|
+
if (input.status && nextStatus !== existing.status) {
|
|
744
754
|
timeline.push({
|
|
745
755
|
id: `timeline:${(0, node_crypto_1.randomUUID)()}`,
|
|
746
756
|
type: 'status_change',
|
|
747
|
-
title: `Task ${
|
|
748
|
-
status:
|
|
757
|
+
title: `Task ${nextStatus}`,
|
|
758
|
+
status: nextStatus,
|
|
749
759
|
timestamp: now,
|
|
750
760
|
});
|
|
751
761
|
}
|
|
@@ -780,14 +790,14 @@ class LocalCoreAcpStore {
|
|
|
780
790
|
WHERE id = ?
|
|
781
791
|
`).run(nextStatus, input.threadId || existing.threadId || null, input.runId || existing.runId || null, input.title || existing.title, now, existing.queuedAt || (nextStatus === 'queued' ? now : null), existing.startedAt || (nextStatus === 'running' ? now : null), existing.completedAt || (['completed', 'failed', 'cancelled'].includes(nextStatus) ? now : null), input.summary ?? existing.summary ?? null, input.error === null ? null : input.error ?? existing.error ?? null, JSON.stringify(timeline), JSON.stringify(logs), JSON.stringify(artifacts), JSON.stringify(approvalIds), JSON.stringify(input.metadata || existing.metadata || {}), taskId);
|
|
782
792
|
const task = this.getAgentTask(taskId);
|
|
783
|
-
if (input.status &&
|
|
793
|
+
if (input.status && nextStatus !== existing.status) {
|
|
784
794
|
this.createAuditEvent({
|
|
785
795
|
type: 'task.updated',
|
|
786
796
|
workspaceId: task.workspaceId,
|
|
787
797
|
taskId: task.taskId,
|
|
788
798
|
actor: 'local',
|
|
789
|
-
summary: `Task status changed to ${
|
|
790
|
-
metadata: { previousStatus: existing.status, status:
|
|
799
|
+
summary: `Task status changed to ${nextStatus}.`,
|
|
800
|
+
metadata: { previousStatus: existing.status, status: nextStatus, runId: task.runId },
|
|
791
801
|
});
|
|
792
802
|
}
|
|
793
803
|
return task;
|
|
@@ -820,14 +830,20 @@ class LocalCoreAcpStore {
|
|
|
820
830
|
return row ? this.toScheduledJob(row) : undefined;
|
|
821
831
|
}
|
|
822
832
|
createScheduledJob(input) {
|
|
823
|
-
|
|
833
|
+
let id = (0, job_id_js_1.createScheduledJobId)();
|
|
834
|
+
for (let attempt = 0; attempt < 5 && this.getScheduledJob(id); attempt += 1) {
|
|
835
|
+
id = (0, job_id_js_1.createScheduledJobId)();
|
|
836
|
+
}
|
|
837
|
+
if (this.getScheduledJob(id)) {
|
|
838
|
+
throw new Error('Unable to allocate a unique scheduled job id.');
|
|
839
|
+
}
|
|
824
840
|
const now = new Date().toISOString();
|
|
825
841
|
this.db.prepare(`
|
|
826
842
|
INSERT INTO scheduled_jobs (
|
|
827
843
|
id, workspace_id, platform, route_type, route_config, execution_mode, trigger_type, cron_expr, run_at,
|
|
828
844
|
prompt_template, description, enabled, concurrency_policy, created_at, updated_at
|
|
829
845
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'skip_if_running', ?, ?)
|
|
830
|
-
`).run(id, input.workspaceId, input.platform, input.route.type, JSON.stringify(input.route), input.executionMode
|
|
846
|
+
`).run(id, input.workspaceId, (0, index_js_1.normalizeChannelPlatform)(input.platform), input.route.type, JSON.stringify(input.route), (0, index_js_1.normalizeScheduledJobExecutionMode)(input.executionMode), (0, index_js_1.normalizeScheduledJobTriggerType)(input.triggerType), input.cronExpr || null, input.runAt || null, input.promptTemplate, input.description || '', input.enabled === false ? 0 : 1, now, now);
|
|
831
847
|
return this.getScheduledJob(id);
|
|
832
848
|
}
|
|
833
849
|
updateScheduledJob(jobId, input) {
|
|
@@ -838,8 +854,8 @@ class LocalCoreAcpStore {
|
|
|
838
854
|
const next = {
|
|
839
855
|
...existing,
|
|
840
856
|
...(input.route ? { route: input.route } : {}),
|
|
841
|
-
...(input.executionMode ? { executionMode: input.executionMode } : {}),
|
|
842
|
-
...(input.triggerType ? { triggerType: input.triggerType } : {}),
|
|
857
|
+
...(input.executionMode ? { executionMode: (0, index_js_1.normalizeScheduledJobExecutionMode)(input.executionMode) } : {}),
|
|
858
|
+
...(input.triggerType ? { triggerType: (0, index_js_1.normalizeScheduledJobTriggerType)(input.triggerType) } : {}),
|
|
843
859
|
...(Object.prototype.hasOwnProperty.call(input, 'cronExpr') ? { cronExpr: input.cronExpr || undefined } : {}),
|
|
844
860
|
...(Object.prototype.hasOwnProperty.call(input, 'runAt') ? { runAt: input.runAt || undefined } : {}),
|
|
845
861
|
...(typeof input.promptTemplate === 'string' ? { promptTemplate: input.promptTemplate } : {}),
|
|
@@ -856,7 +872,10 @@ class LocalCoreAcpStore {
|
|
|
856
872
|
return this.getScheduledJob(jobId);
|
|
857
873
|
}
|
|
858
874
|
deleteScheduledJob(jobId) {
|
|
859
|
-
this.db.prepare('DELETE FROM scheduled_jobs WHERE id = ?').run(jobId);
|
|
875
|
+
const result = this.db.prepare('DELETE FROM scheduled_jobs WHERE id = ?').run(jobId);
|
|
876
|
+
if (result.changes === 0) {
|
|
877
|
+
throw new Error(`Scheduled job not found: ${jobId}`);
|
|
878
|
+
}
|
|
860
879
|
return { deleted: true };
|
|
861
880
|
}
|
|
862
881
|
listScheduledJobRuns(jobId) {
|
|
@@ -871,13 +890,14 @@ class LocalCoreAcpStore {
|
|
|
871
890
|
createScheduledJobRun(jobId, status, input = {}) {
|
|
872
891
|
const id = `jobrun:${(0, node_crypto_1.randomUUID)()}`;
|
|
873
892
|
const triggeredAt = input.triggeredAt || new Date().toISOString();
|
|
893
|
+
const normalizedStatus = (0, index_js_1.normalizeScheduledJobRunStatus)(status);
|
|
874
894
|
this.db.prepare(`
|
|
875
895
|
INSERT INTO scheduled_job_runs (id, job_id, status, triggered_at, started_at, finished_at, error, thread_id, run_id, platform_message_id)
|
|
876
896
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
877
|
-
`).run(id, jobId,
|
|
897
|
+
`).run(id, jobId, normalizedStatus, triggeredAt, input.startedAt || null, input.finishedAt || null, input.error || null, input.threadId || null, input.runId || null, input.platformMessageId || null);
|
|
878
898
|
this.updateScheduledJobStatus(jobId, {
|
|
879
899
|
lastRunAt: triggeredAt,
|
|
880
|
-
lastStatus:
|
|
900
|
+
lastStatus: normalizedStatus,
|
|
881
901
|
lastError: input.error || '',
|
|
882
902
|
});
|
|
883
903
|
return this.getScheduledJobRun(id);
|
|
@@ -898,6 +918,7 @@ class LocalCoreAcpStore {
|
|
|
898
918
|
const next = {
|
|
899
919
|
...existing,
|
|
900
920
|
...input,
|
|
921
|
+
...(input.status ? { status: (0, index_js_1.normalizeScheduledJobRunStatus)(input.status) } : {}),
|
|
901
922
|
};
|
|
902
923
|
this.db.prepare(`
|
|
903
924
|
UPDATE scheduled_job_runs
|
|
@@ -926,11 +947,18 @@ class LocalCoreAcpStore {
|
|
|
926
947
|
}
|
|
927
948
|
getThreadRow(threadId) {
|
|
928
949
|
return this.db.prepare(`
|
|
929
|
-
SELECT id, workspace_id, session_id, bridge_session_key, title, agent_type, created_at, updated_at, history_count, excerpt, acp_session_id, acp_supports_load
|
|
950
|
+
SELECT id, workspace_id, session_id, bridge_session_key, title, agent_type, created_at, updated_at, history_count, excerpt, acp_session_id, acp_supports_load, agent_mode
|
|
930
951
|
FROM threads
|
|
931
952
|
WHERE id = ?
|
|
932
953
|
`).get(threadId);
|
|
933
954
|
}
|
|
955
|
+
updateThreadAgentMode(threadId, mode) {
|
|
956
|
+
this.db.prepare(`
|
|
957
|
+
UPDATE threads
|
|
958
|
+
SET agent_mode = ?, updated_at = ?
|
|
959
|
+
WHERE id = ?
|
|
960
|
+
`).run(mode, new Date().toISOString(), threadId);
|
|
961
|
+
}
|
|
934
962
|
updateThreadSession(threadId, sessionId, supportsLoad) {
|
|
935
963
|
this.db.prepare(`
|
|
936
964
|
UPDATE threads
|
|
@@ -1113,10 +1141,10 @@ class LocalCoreAcpStore {
|
|
|
1113
1141
|
return {
|
|
1114
1142
|
id: row.id,
|
|
1115
1143
|
workspaceId: row.workspace_id,
|
|
1116
|
-
platform: row.platform,
|
|
1144
|
+
platform: (0, index_js_1.normalizeChannelPlatform)(row.platform),
|
|
1117
1145
|
route,
|
|
1118
|
-
executionMode: row.execution_mode
|
|
1119
|
-
triggerType: row.trigger_type,
|
|
1146
|
+
executionMode: (0, index_js_1.normalizeScheduledJobExecutionMode)(row.execution_mode),
|
|
1147
|
+
triggerType: (0, index_js_1.normalizeScheduledJobTriggerType)(row.trigger_type),
|
|
1120
1148
|
cronExpr: row.cron_expr || undefined,
|
|
1121
1149
|
runAt: row.run_at || undefined,
|
|
1122
1150
|
promptTemplate: row.prompt_template,
|
|
@@ -1126,7 +1154,7 @@ class LocalCoreAcpStore {
|
|
|
1126
1154
|
createdAt: row.created_at,
|
|
1127
1155
|
updatedAt: row.updated_at,
|
|
1128
1156
|
lastRunAt: row.last_run_at || undefined,
|
|
1129
|
-
lastStatus: row.last_status
|
|
1157
|
+
lastStatus: row.last_status ? (0, index_js_1.normalizeScheduledJobRunStatus)(row.last_status) : undefined,
|
|
1130
1158
|
lastError: row.last_error || undefined,
|
|
1131
1159
|
};
|
|
1132
1160
|
}
|
|
@@ -1134,7 +1162,7 @@ class LocalCoreAcpStore {
|
|
|
1134
1162
|
return {
|
|
1135
1163
|
id: row.id,
|
|
1136
1164
|
jobId: row.job_id,
|
|
1137
|
-
status: row.status,
|
|
1165
|
+
status: (0, index_js_1.normalizeScheduledJobRunStatus)(row.status),
|
|
1138
1166
|
triggeredAt: row.triggered_at,
|
|
1139
1167
|
startedAt: row.started_at || undefined,
|
|
1140
1168
|
finishedAt: row.finished_at || undefined,
|
|
@@ -1187,7 +1215,7 @@ class LocalCoreAcpStore {
|
|
|
1187
1215
|
runId: row.run_id || undefined,
|
|
1188
1216
|
title: row.title,
|
|
1189
1217
|
prompt: row.prompt || undefined,
|
|
1190
|
-
status: row.status,
|
|
1218
|
+
status: (0, index_js_1.normalizeAgentTaskStatus)(row.status),
|
|
1191
1219
|
createdAt: row.created_at,
|
|
1192
1220
|
updatedAt: row.updated_at,
|
|
1193
1221
|
queuedAt: row.queued_at || undefined,
|
|
@@ -1224,7 +1252,7 @@ class LocalCoreAcpStore {
|
|
|
1224
1252
|
runId: row.run_id || undefined,
|
|
1225
1253
|
deviceId: row.device_id,
|
|
1226
1254
|
kind: row.kind,
|
|
1227
|
-
status: row.status,
|
|
1255
|
+
status: (0, index_js_1.normalizeApprovalRequestStatus)(row.status),
|
|
1228
1256
|
riskLevel: row.risk_level,
|
|
1229
1257
|
title: row.title,
|
|
1230
1258
|
description: row.description,
|