@kafca/agentdock 0.1.61 → 0.1.62
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 +18 -0
- package/dist/renderer/assets/AutomationList-BgJgAdVO.js +16 -0
- package/dist/renderer/assets/{Badge-BLI4LHse.js → Badge-Bq2hPVcR.js} +1 -1
- package/dist/renderer/assets/{Card-DJeLDdL3.js → Card-BPJNSZce.js} +1 -1
- package/dist/renderer/assets/{Config-D1awc81A.js → Config-aSFqlI88.js} +2 -2
- package/dist/renderer/assets/Dashboard-D3ezFmb7.js +36 -0
- package/dist/renderer/assets/{EmptyState-CkI1RwPX.js → EmptyState-DK496gBq.js} +1 -1
- package/dist/renderer/assets/{HighlightedMarkdown-BUhDlhgW.js → HighlightedMarkdown-Ckre5jNv.js} +1 -1
- package/dist/renderer/assets/{Input-DHYrn-Ne.js → Input-C5C1d0ba.js} +1 -1
- package/dist/renderer/assets/{KnowledgeDetail-Bij-Xo90.js → KnowledgeDetail-N8Ey1ikc.js} +2 -2
- package/dist/renderer/assets/{KnowledgeHome-DmPZ2IlI.js → KnowledgeHome-9aF8nJEf.js} +2 -2
- package/dist/renderer/assets/{Logs-ISY99heA.js → Logs-sgAdwEeS.js} +2 -2
- package/dist/renderer/assets/{Modal-DAQfz0ot.js → Modal-BB10hTRc.js} +3 -3
- package/dist/renderer/assets/{Page-Dw43UYDT.js → Page-DfC319Ck.js} +1 -1
- package/dist/renderer/assets/{Select-DzmN5OGQ.js → Select-RHJBmNER.js} +1 -1
- package/dist/renderer/assets/{ThreadChat-B5CWqqMK.js → ThreadChat-BU1zCdr4.js} +3 -3
- package/dist/renderer/assets/{Workspace-C5g9LBj9.js → Workspace-BoZCz7S8.js} +1 -1
- package/dist/renderer/assets/{arrow-left-BLXh56Ip.js → arrow-left-D2V1eZSD.js} +1 -1
- package/dist/renderer/assets/{book-open-DhPGbc-7.js → book-open-DUcBn7Bb.js} +1 -1
- package/dist/renderer/assets/{channels-DfQrmuYO.js → channels-DMhDSlf2.js} +2 -2
- package/dist/renderer/assets/{chevron-down-CEFtpPDc.js → chevron-down-Ca2FQDB7.js} +1 -1
- package/dist/renderer/assets/en-Bnr4nMzg.js +1 -0
- package/dist/renderer/assets/es-B1GIFh3i.js +1 -0
- package/dist/renderer/assets/{index-BIKL3fTP.css → index-B6WcpkJF.css} +1 -1
- package/dist/renderer/assets/{index-CYhDUAR_.js → index-BlnvlekJ.js} +1 -1
- package/dist/renderer/assets/index-DRJ5wgw_.js +162 -0
- package/dist/renderer/assets/ja-CDWPWqEW.js +1 -0
- package/dist/renderer/assets/{knowledge-uHRQ80sR.js → knowledge-D1-k56eY.js} +1 -1
- package/dist/renderer/assets/{pencil-BD2Y31YC.js → pencil-BhWdv_86.js} +1 -1
- package/dist/renderer/assets/{plus-DDcldp_c.js → plus-BacLMlK3.js} +1 -1
- package/dist/renderer/assets/{save-CMW_cZI9.js → save-Bpoxbzau.js} +1 -1
- package/dist/renderer/assets/{search-BM-0CvJr.js → search-BVJcpdFX.js} +1 -1
- package/dist/renderer/assets/{shield-check-DaMB0FKG.js → shield-check-C2cw_Ip6.js} +1 -1
- package/dist/renderer/assets/{threads-DZgt9tWj.js → threads-DOsBQBg_.js} +1 -1
- package/dist/renderer/assets/{trash-2-DTXVbC5y.js → trash-2-Bs3rEm3g.js} +1 -1
- package/dist/renderer/assets/zh-MSddxMDX.js +1 -0
- package/dist/renderer/assets/zh-TW-C_LNWX0o.js +1 -0
- package/dist/renderer/index.html +2 -2
- package/dist-electron/electron/managed-skills/agent-browser/SKILL.md +41 -0
- package/dist-electron/electron/managed-skills/agent-browser/references/authentication.md +83 -0
- package/dist-electron/electron/managed-skills/agent-browser/references/commands.md +50 -0
- package/dist-electron/electron/managed-skills/agent-browser/references/profiling.md +20 -0
- package/dist-electron/electron/managed-skills/agent-browser/references/proxy-support.md +18 -0
- package/dist-electron/electron/managed-skills/agent-browser/references/session-management.md +17 -0
- package/dist-electron/electron/managed-skills/agent-browser/references/snapshot-refs.md +17 -0
- package/dist-electron/electron/managed-skills/agent-browser/references/video-recording.md +21 -0
- package/dist-electron/electron/managed-skills/agent-browser/templates/authenticated-session.sh +11 -0
- package/dist-electron/electron/managed-skills/agent-browser/templates/capture-workflow.sh +12 -0
- package/dist-electron/electron/managed-skills/agent-browser/templates/form-automation.sh +10 -0
- package/dist-electron/electron/managed-skills/condition-trigger/SKILL.md +21 -0
- package/dist-electron/electron/managed-skills/condition-trigger/scripts/register-condition-trigger.sh +106 -0
- package/dist-electron/electron/managed-skills/knowledge-base/SKILL.md +13 -0
- package/dist-electron/electron/managed-skills/knowledge-base/scripts/search-knowledge.sh +80 -0
- package/dist-electron/packages/contracts/src/automations.js +211 -0
- package/dist-electron/packages/contracts/src/index.js +1 -0
- package/dist-electron/packages/core-sdk/src/automations.js +87 -0
- package/dist-electron/packages/core-sdk/src/client.js +101 -0
- package/dist-electron/packages/core-sdk/src/index.js +2 -1
- package/dist-electron/services/local-ai-core/src/acp/store/automation-script-store.js +415 -0
- package/dist-electron/services/local-ai-core/src/acp/store/automation-store.js +829 -0
- package/dist-electron/services/local-ai-core/src/acp/store/local-core-acp-store.js +158 -0
- package/dist-electron/services/local-ai-core/src/acp/store/schema.js +81 -0
- package/dist-electron/services/local-ai-core/src/automation/automation-action-executor.js +144 -0
- package/dist-electron/services/local-ai-core/src/automation/automation-condition-engine.js +79 -0
- package/dist-electron/services/local-ai-core/src/automation/automation-conversation-executor.js +39 -73
- package/dist-electron/services/local-ai-core/src/automation/automation-monitor-service.js +695 -260
- package/dist-electron/services/local-ai-core/src/automation/automation-script-service.js +507 -0
- package/dist-electron/services/local-ai-core/src/automation/automation-service.js +1019 -0
- package/dist-electron/services/local-ai-core/src/automation/automation-trigger-engine.js +141 -0
- package/dist-electron/services/local-ai-core/src/automation/condition-evaluator.js +60 -17
- package/dist-electron/services/local-ai-core/src/automation/legacy-automation-mappers.js +286 -0
- package/dist-electron/services/local-ai-core/src/automation/scripts/anthropic-sandbox-runner.js +792 -0
- package/dist-electron/services/local-ai-core/src/automation/scripts/sandbox-runner.js +2 -0
- package/dist-electron/services/local-ai-core/src/automation/scripts/script-package.js +475 -0
- package/dist-electron/services/local-ai-core/src/automation/scripts/script-protocol-runner.js +266 -0
- package/dist-electron/services/local-ai-core/src/automation/scripts/secret-resolver.js +37 -0
- package/dist-electron/services/local-ai-core/src/channel/weixin/inbound-poller.js +1 -2
- package/dist-electron/services/local-ai-core/src/channel/weixin/transport.js +9 -8
- package/dist-electron/services/local-ai-core/src/cli/lac.js +229 -0
- package/dist-electron/services/local-ai-core/src/kernel/bootstrap.js +21 -0
- package/dist-electron/services/local-ai-core/src/runtime/deployment-diagnostics.js +76 -0
- package/dist-electron/services/local-ai-core/src/runtime/handlers/automations-handler.js +322 -0
- package/dist-electron/services/local-ai-core/src/runtime/local-core-controller.js +20 -0
- package/dist-electron/services/local-ai-core/src/runtime/managed-skill-catalog.js +37 -0
- package/dist-electron/services/local-ai-core/src/runtime/server-helpers.js +14 -4
- package/dist-electron/services/local-ai-core/src/runtime/server-routes.js +75 -0
- package/dist-electron/services/local-ai-core/src/runtime/server.js +21 -0
- package/dist-electron/services/local-ai-core/src/runtime/standalone.js +1 -0
- package/dist-electron/services/local-ai-core/src/scheduler/cron.js +151 -39
- package/dist-electron/services/local-ai-core/src/scheduler/scheduled-conversation-executor.js +2 -4
- package/dist-electron/services/local-ai-core/src/scheduler/scheduled-job-application-service.js +64 -12
- package/dist-electron/services/local-ai-core/src/scheduler/scheduler-service.js +71 -4
- package/dist-electron/services/local-ai-core/src/scheduler/thread-resolution.js +10 -0
- package/dist-electron/services/local-ai-core/src/thread/agent-message-policy.js +16 -1
- package/dist-electron/src/pages/Automation/automation-page-model.js +76 -0
- package/dist-electron/tests/contracts/agent-message-policy.test.js +32 -0
- package/dist-electron/tests/contracts/architecture-docs.test.js +30 -0
- package/dist-electron/tests/contracts/automation-contracts.test.js +154 -0
- package/dist-electron/tests/contracts/automation-renderer-model.test.js +47 -0
- package/dist-electron/tests/electron/automation-action-executor.test.js +75 -0
- package/dist-electron/tests/electron/automation-compatibility.test.js +463 -0
- package/dist-electron/tests/electron/automation-deployment.test.js +66 -0
- package/dist-electron/tests/electron/automation-engine.test.js +264 -0
- package/dist-electron/tests/electron/automation-monitor.test.js +1333 -0
- package/dist-electron/tests/electron/automation-sandbox-runner.test.js +333 -0
- package/dist-electron/tests/electron/automation-script-approval.test.js +553 -0
- package/dist-electron/tests/electron/automation-script-package.test.js +499 -0
- package/dist-electron/tests/electron/automation-script-runner.test.js +120 -0
- package/dist-electron/tests/electron/automation-service.test.js +1078 -0
- package/dist-electron/tests/electron/automation-store.test.js +593 -0
- package/dist-electron/tests/electron/condition-trigger-skill.test.js +93 -0
- package/dist-electron/tests/electron/core-client.test.js +99 -0
- package/dist-electron/tests/electron/lac-cli.test.js +110 -0
- package/dist-electron/tests/electron/workspace-task-store.test.js +25 -0
- package/dist-electron/tests/integration/automation-routes.test.js +186 -0
- package/dist-electron/tests/integration/automation-sandbox-runtime.test.js +92 -0
- package/package.json +4 -3
- package/dist/renderer/assets/CronList-CupZoNwW.js +0 -1
- package/dist/renderer/assets/Dashboard-nLZnOtcs.js +0 -41
- package/dist/renderer/assets/MonitorList-BlX82rXF.js +0 -1
- package/dist/renderer/assets/en-CmAr_0e6.js +0 -1
- package/dist/renderer/assets/es-Cs9x52ca.js +0 -1
- package/dist/renderer/assets/index-Dd00oqgY.js +0 -167
- package/dist/renderer/assets/ja-DtvtBRTW.js +0 -1
- package/dist/renderer/assets/play-DBJ8wsSy.js +0 -6
- package/dist/renderer/assets/zh-CcJ9vBZj.js +0 -1
- package/dist/renderer/assets/zh-TW-elI72AC1.js +0 -1
|
@@ -7,6 +7,9 @@ const node_path_1 = require("node:path");
|
|
|
7
7
|
const superai_contracts_1 = require("../../../../../packages/contracts/src/index.js");
|
|
8
8
|
const agent_task_store_js_1 = require("./agent-task-store.js");
|
|
9
9
|
const automation_monitor_store_js_1 = require("./automation-monitor-store.js");
|
|
10
|
+
const automation_script_store_js_1 = require("./automation-script-store.js");
|
|
11
|
+
const automation_script_service_js_1 = require("../../automation/automation-script-service.js");
|
|
12
|
+
const automation_store_js_1 = require("./automation-store.js");
|
|
10
13
|
const schema_js_1 = require("./schema.js");
|
|
11
14
|
const platform_store_js_1 = require("./platform-store.js");
|
|
12
15
|
const scheduler_store_js_1 = require("./scheduler-store.js");
|
|
@@ -24,6 +27,9 @@ class LocalCoreAcpStore {
|
|
|
24
27
|
agentTasks;
|
|
25
28
|
scheduler;
|
|
26
29
|
automationMonitors;
|
|
30
|
+
automationScripts;
|
|
31
|
+
automationScriptLifecycle;
|
|
32
|
+
automations;
|
|
27
33
|
platform;
|
|
28
34
|
modelProviders;
|
|
29
35
|
external;
|
|
@@ -43,6 +49,9 @@ class LocalCoreAcpStore {
|
|
|
43
49
|
});
|
|
44
50
|
this.scheduler = new scheduler_store_js_1.LocalSchedulerStore(this.db);
|
|
45
51
|
this.automationMonitors = new automation_monitor_store_js_1.LocalAutomationMonitorStore(this.db);
|
|
52
|
+
this.automationScripts = new automation_script_store_js_1.LocalAutomationScriptStore(this.db, userDataPath);
|
|
53
|
+
this.automationScriptLifecycle = new automation_script_service_js_1.AutomationScriptService({ db: this.db, security: this.security });
|
|
54
|
+
this.automations = new automation_store_js_1.LocalAutomationStore(this.db);
|
|
46
55
|
this.platform = new platform_store_js_1.LocalPlatformStore(this.db);
|
|
47
56
|
this.modelProviders = new model_provider_store_js_1.LocalModelProviderStore(this.db);
|
|
48
57
|
this.external = new external_store_js_1.LocalExternalStore(this.db);
|
|
@@ -237,6 +246,143 @@ class LocalCoreAcpStore {
|
|
|
237
246
|
updateAutomationMonitorRun(runId, input) {
|
|
238
247
|
return this.automationMonitors.updateRun(runId, input);
|
|
239
248
|
}
|
|
249
|
+
listAutomations(workspaceId) {
|
|
250
|
+
return this.automations.list(workspaceId);
|
|
251
|
+
}
|
|
252
|
+
getAutomation(automationId) {
|
|
253
|
+
return this.automations.get(automationId);
|
|
254
|
+
}
|
|
255
|
+
getAutomationNextCheckAt(automationId) {
|
|
256
|
+
return this.automations.getNextCheckAt(automationId);
|
|
257
|
+
}
|
|
258
|
+
createAutomation(input) {
|
|
259
|
+
return this.automations.create(input);
|
|
260
|
+
}
|
|
261
|
+
createTrustedAutomation(input) {
|
|
262
|
+
return this.automations.createTrusted(input);
|
|
263
|
+
}
|
|
264
|
+
createAutomationAtomically(input, initialize) {
|
|
265
|
+
return this.automationTransaction(() => {
|
|
266
|
+
const created = this.automations.create(input);
|
|
267
|
+
return this.automations.updateState(created.id, initialize(created));
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
createTrustedAutomationAtomically(input, initialize) {
|
|
271
|
+
return this.automationTransaction(() => {
|
|
272
|
+
const created = this.automations.createTrusted(input);
|
|
273
|
+
return this.automations.updateState(created.id, initialize(created));
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
updateAutomation(automationId, input) {
|
|
277
|
+
return this.automations.update(automationId, input);
|
|
278
|
+
}
|
|
279
|
+
updateTrustedAutomation(automationId, input) {
|
|
280
|
+
return this.automations.updateTrusted(automationId, input);
|
|
281
|
+
}
|
|
282
|
+
updateAutomationAtomically(automationId, input, initialize) {
|
|
283
|
+
return this.automationTransaction(() => {
|
|
284
|
+
const updated = this.automations.update(automationId, input);
|
|
285
|
+
const state = initialize?.(updated);
|
|
286
|
+
return state ? this.automations.updateState(automationId, state) : updated;
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
updateTrustedAutomationAtomically(automationId, input, initialize) {
|
|
290
|
+
return this.automationTransaction(() => {
|
|
291
|
+
const updated = this.automations.updateTrusted(automationId, input);
|
|
292
|
+
const state = initialize?.(updated);
|
|
293
|
+
return state ? this.automations.updateState(automationId, state) : updated;
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
updateAutomationState(automationId, input) {
|
|
297
|
+
return this.automations.updateState(automationId, input);
|
|
298
|
+
}
|
|
299
|
+
deleteAutomation(automationId) {
|
|
300
|
+
return this.automations.delete(automationId);
|
|
301
|
+
}
|
|
302
|
+
listAutomationScripts(workspaceId) {
|
|
303
|
+
return this.automationScripts.listScripts(workspaceId);
|
|
304
|
+
}
|
|
305
|
+
getAutomationScript(scriptId) {
|
|
306
|
+
return this.automationScripts.getScript(scriptId);
|
|
307
|
+
}
|
|
308
|
+
createAutomationScript(input) {
|
|
309
|
+
return this.automationScripts.createScript(input);
|
|
310
|
+
}
|
|
311
|
+
updateAutomationScript(scriptId, input) {
|
|
312
|
+
return this.automationScripts.updateScript(scriptId, input);
|
|
313
|
+
}
|
|
314
|
+
createAutomationScriptVersionFromPackage(input) {
|
|
315
|
+
return this.automationScripts.createVersionFromPackage(input);
|
|
316
|
+
}
|
|
317
|
+
stageAutomationScriptSource(input) {
|
|
318
|
+
return this.automationScripts.stageSource(input);
|
|
319
|
+
}
|
|
320
|
+
createAutomationScriptVersionFromStaged(input) {
|
|
321
|
+
return this.automationScripts.createVersionFromStaged(input.scriptId, input.staged, input.interpreterPath, input.interpreterVersion);
|
|
322
|
+
}
|
|
323
|
+
discardUnreferencedAutomationScriptPackage(scriptId, staged) {
|
|
324
|
+
this.automationScripts.discardUnreferencedPackage(scriptId, staged);
|
|
325
|
+
}
|
|
326
|
+
listAutomationScriptVersions(scriptId) {
|
|
327
|
+
return this.automationScripts.listVersions(scriptId);
|
|
328
|
+
}
|
|
329
|
+
getAutomationScriptVersion(versionId) {
|
|
330
|
+
return this.automationScripts.getVersion(versionId);
|
|
331
|
+
}
|
|
332
|
+
requestAutomationScriptTestApproval(versionId, actor) {
|
|
333
|
+
return this.automationScriptLifecycle.requestTestApproval(versionId, actor);
|
|
334
|
+
}
|
|
335
|
+
authorizeAutomationScriptTest(versionId, approvalId, actor) {
|
|
336
|
+
return this.automationScriptLifecycle.authorizeTest(versionId, approvalId, actor);
|
|
337
|
+
}
|
|
338
|
+
recordAutomationScriptTestResult(versionId, result) {
|
|
339
|
+
return this.automationScriptLifecycle.recordTestResult(versionId, result);
|
|
340
|
+
}
|
|
341
|
+
claimAutomationScriptTestExecution(versionId) {
|
|
342
|
+
return this.automationScriptLifecycle.claimTestExecution(versionId);
|
|
343
|
+
}
|
|
344
|
+
failClaimedAutomationScriptTestExecution(versionId) {
|
|
345
|
+
return this.automationScriptLifecycle.failClaimedTestExecution(versionId);
|
|
346
|
+
}
|
|
347
|
+
requestAutomationScriptEnableApproval(versionId, actor) {
|
|
348
|
+
return this.automationScriptLifecycle.requestEnableApproval(versionId, actor);
|
|
349
|
+
}
|
|
350
|
+
approveAutomationScriptVersion(versionId, approvalId, actor) {
|
|
351
|
+
return this.automationScriptLifecycle.approveVersion(versionId, approvalId, actor);
|
|
352
|
+
}
|
|
353
|
+
revokeAutomationScriptVersion(versionId, actor) {
|
|
354
|
+
return this.automationScriptLifecycle.revokeVersion(versionId, actor);
|
|
355
|
+
}
|
|
356
|
+
createAutomationEvaluation(automationId, input) {
|
|
357
|
+
return this.automations.createEvaluation(automationId, input);
|
|
358
|
+
}
|
|
359
|
+
finishAutomationEvaluation(evaluationId, input) {
|
|
360
|
+
return this.automations.finishEvaluation(evaluationId, input);
|
|
361
|
+
}
|
|
362
|
+
listAutomationEvaluations(automationId) {
|
|
363
|
+
return this.automations.listEvaluations(automationId);
|
|
364
|
+
}
|
|
365
|
+
getLatestAutomationEvaluationWithState(automationId) {
|
|
366
|
+
return this.automations.getLatestEvaluationWithState(automationId);
|
|
367
|
+
}
|
|
368
|
+
createAutomationRun(automationId, evaluationId, input = {}) {
|
|
369
|
+
return this.automations.createRun(automationId, evaluationId, input);
|
|
370
|
+
}
|
|
371
|
+
updateAutomationRun(runId, input) {
|
|
372
|
+
return this.automations.updateRun(runId, input);
|
|
373
|
+
}
|
|
374
|
+
listAutomationRuns(automationId) {
|
|
375
|
+
return this.automations.listRuns(automationId);
|
|
376
|
+
}
|
|
377
|
+
reconcileInterruptedAutomationRuns(reason, finishedAt) {
|
|
378
|
+
return this.automations.reconcileInterruptedRuns(reason, finishedAt);
|
|
379
|
+
}
|
|
380
|
+
importLegacyAutomations() {
|
|
381
|
+
return this.automations.importLegacyRecords();
|
|
382
|
+
}
|
|
383
|
+
pruneAutomationEvaluations(now) {
|
|
384
|
+
return this.automations.pruneEvaluations(now);
|
|
385
|
+
}
|
|
240
386
|
getThreadRow(threadId) {
|
|
241
387
|
return this.threads.getRow(threadId);
|
|
242
388
|
}
|
|
@@ -303,6 +449,18 @@ class LocalCoreAcpStore {
|
|
|
303
449
|
listPairingRequests(workspaceId, platform) {
|
|
304
450
|
return this.platform.listPairingRequests(workspaceId, platform);
|
|
305
451
|
}
|
|
452
|
+
automationTransaction(work) {
|
|
453
|
+
this.db.exec('BEGIN IMMEDIATE');
|
|
454
|
+
try {
|
|
455
|
+
const result = work();
|
|
456
|
+
this.db.exec('COMMIT');
|
|
457
|
+
return result;
|
|
458
|
+
}
|
|
459
|
+
catch (error) {
|
|
460
|
+
this.db.exec('ROLLBACK');
|
|
461
|
+
throw error;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
306
464
|
}
|
|
307
465
|
exports.LocalCoreAcpStore = LocalCoreAcpStore;
|
|
308
466
|
function resolveLegacyConfigPaths(runtimeDir) {
|
|
@@ -162,6 +162,86 @@ function ensureLocalCoreAcpSchema(db) {
|
|
|
162
162
|
FOREIGN KEY (monitor_id) REFERENCES automation_monitors(id) ON DELETE CASCADE
|
|
163
163
|
);
|
|
164
164
|
CREATE INDEX IF NOT EXISTS idx_automation_monitor_runs_monitor_triggered ON automation_monitor_runs (monitor_id, triggered_at DESC);
|
|
165
|
+
CREATE TABLE IF NOT EXISTS automations (
|
|
166
|
+
id TEXT PRIMARY KEY,
|
|
167
|
+
workspace_id TEXT NOT NULL,
|
|
168
|
+
title TEXT NOT NULL,
|
|
169
|
+
enabled INTEGER NOT NULL,
|
|
170
|
+
health TEXT NOT NULL,
|
|
171
|
+
blocked_reason TEXT,
|
|
172
|
+
activation_json TEXT NOT NULL,
|
|
173
|
+
condition_json TEXT NOT NULL,
|
|
174
|
+
action_json TEXT NOT NULL,
|
|
175
|
+
delivery_json TEXT NOT NULL,
|
|
176
|
+
policies_json TEXT NOT NULL,
|
|
177
|
+
last_successful_match INTEGER,
|
|
178
|
+
last_evaluation_at TEXT,
|
|
179
|
+
last_triggered_at TEXT,
|
|
180
|
+
consecutive_evaluation_failures INTEGER NOT NULL DEFAULT 0,
|
|
181
|
+
next_check_at TEXT,
|
|
182
|
+
origin_kind TEXT NOT NULL DEFAULT 'native',
|
|
183
|
+
legacy_metadata_json TEXT,
|
|
184
|
+
created_at TEXT NOT NULL,
|
|
185
|
+
updated_at TEXT NOT NULL
|
|
186
|
+
);
|
|
187
|
+
CREATE INDEX IF NOT EXISTS idx_automations_workspace_updated ON automations (workspace_id, updated_at DESC);
|
|
188
|
+
CREATE INDEX IF NOT EXISTS idx_automations_enabled_next_check ON automations (enabled, next_check_at);
|
|
189
|
+
CREATE INDEX IF NOT EXISTS idx_automations_health ON automations (health);
|
|
190
|
+
CREATE INDEX IF NOT EXISTS idx_automations_origin ON automations (origin_kind);
|
|
191
|
+
CREATE TABLE IF NOT EXISTS automation_evaluations (
|
|
192
|
+
id TEXT PRIMARY KEY,
|
|
193
|
+
automation_id TEXT NOT NULL,
|
|
194
|
+
status TEXT NOT NULL,
|
|
195
|
+
activation_kind TEXT NOT NULL,
|
|
196
|
+
script_version_id TEXT,
|
|
197
|
+
started_at TEXT NOT NULL,
|
|
198
|
+
finished_at TEXT,
|
|
199
|
+
evaluation_json TEXT NOT NULL,
|
|
200
|
+
FOREIGN KEY (automation_id) REFERENCES automations(id) ON DELETE CASCADE
|
|
201
|
+
);
|
|
202
|
+
CREATE INDEX IF NOT EXISTS idx_automation_evaluations_automation_started
|
|
203
|
+
ON automation_evaluations (automation_id, started_at DESC);
|
|
204
|
+
CREATE TABLE IF NOT EXISTS automation_runs (
|
|
205
|
+
id TEXT PRIMARY KEY,
|
|
206
|
+
automation_id TEXT NOT NULL,
|
|
207
|
+
evaluation_id TEXT NOT NULL UNIQUE,
|
|
208
|
+
status TEXT NOT NULL,
|
|
209
|
+
created_at TEXT NOT NULL,
|
|
210
|
+
run_json TEXT NOT NULL,
|
|
211
|
+
FOREIGN KEY (automation_id) REFERENCES automations(id) ON DELETE CASCADE,
|
|
212
|
+
FOREIGN KEY (evaluation_id) REFERENCES automation_evaluations(id) ON DELETE CASCADE
|
|
213
|
+
);
|
|
214
|
+
CREATE INDEX IF NOT EXISTS idx_automation_runs_automation_created
|
|
215
|
+
ON automation_runs (automation_id, created_at DESC);
|
|
216
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_automation_runs_evaluation_unique ON automation_runs (evaluation_id);
|
|
217
|
+
CREATE TABLE IF NOT EXISTS automation_scripts (
|
|
218
|
+
id TEXT PRIMARY KEY,
|
|
219
|
+
workspace_id TEXT NOT NULL,
|
|
220
|
+
title TEXT NOT NULL,
|
|
221
|
+
description TEXT,
|
|
222
|
+
created_at TEXT NOT NULL,
|
|
223
|
+
updated_at TEXT NOT NULL
|
|
224
|
+
);
|
|
225
|
+
CREATE INDEX IF NOT EXISTS idx_automation_scripts_workspace_updated
|
|
226
|
+
ON automation_scripts (workspace_id, updated_at DESC);
|
|
227
|
+
CREATE TABLE IF NOT EXISTS automation_script_versions (
|
|
228
|
+
id TEXT PRIMARY KEY,
|
|
229
|
+
script_id TEXT NOT NULL,
|
|
230
|
+
status TEXT NOT NULL,
|
|
231
|
+
package_sha256 TEXT NOT NULL,
|
|
232
|
+
package_path TEXT NOT NULL,
|
|
233
|
+
shebang TEXT NOT NULL,
|
|
234
|
+
interpreter_path TEXT NOT NULL,
|
|
235
|
+
interpreter_version TEXT NOT NULL,
|
|
236
|
+
created_at TEXT NOT NULL,
|
|
237
|
+
updated_at TEXT NOT NULL,
|
|
238
|
+
version_json TEXT NOT NULL,
|
|
239
|
+
FOREIGN KEY (script_id) REFERENCES automation_scripts(id) ON DELETE CASCADE
|
|
240
|
+
);
|
|
241
|
+
CREATE INDEX IF NOT EXISTS idx_automation_script_versions_script_created
|
|
242
|
+
ON automation_script_versions (script_id, created_at DESC);
|
|
243
|
+
CREATE INDEX IF NOT EXISTS idx_automation_script_versions_hash
|
|
244
|
+
ON automation_script_versions (script_id, package_sha256);
|
|
165
245
|
CREATE TABLE IF NOT EXISTS workspace_registry (
|
|
166
246
|
id TEXT PRIMARY KEY,
|
|
167
247
|
display_name TEXT NOT NULL,
|
|
@@ -317,6 +397,7 @@ function ensureLocalCoreAcpSchema(db) {
|
|
|
317
397
|
ensureColumn(db, 'scheduled_job_runs', 'delivery_error', 'TEXT');
|
|
318
398
|
ensureColumn(db, 'scheduled_job_runs', 'last_bridge_event_at', 'TEXT');
|
|
319
399
|
ensureColumn(db, 'threads', 'agent_mode', "TEXT NOT NULL DEFAULT 'default'");
|
|
400
|
+
ensureColumn(db, 'automations', 'legacy_metadata_json', 'TEXT');
|
|
320
401
|
}
|
|
321
402
|
function ensureColumn(db, table, column, definition) {
|
|
322
403
|
const rows = db.prepare(`PRAGMA table_info(${table})`).all();
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AutomationActionExecutor = void 0;
|
|
4
|
+
exports.renderAutomationPrompt = renderAutomationPrompt;
|
|
5
|
+
const scheduled_bridge_session_js_1 = require("../scheduler/scheduled-bridge-session.js");
|
|
6
|
+
const scheduled_job_route_js_1 = require("../scheduler/scheduled-job-route.js");
|
|
7
|
+
const run_polling_js_1 = require("../scheduler/run-polling.js");
|
|
8
|
+
const thread_resolution_js_1 = require("../scheduler/thread-resolution.js");
|
|
9
|
+
const AUTOMATION_RUN_PERMISSION_MODE = 'bypassPermissions';
|
|
10
|
+
const UNSAFE_PROMPT_KEYS = new Set(['__proto__', 'constructor', 'prototype', 'toString']);
|
|
11
|
+
class AutomationActionExecutor {
|
|
12
|
+
options;
|
|
13
|
+
constructor(options) {
|
|
14
|
+
this.options = options;
|
|
15
|
+
}
|
|
16
|
+
async execute(input, timeoutMs = 15 * 60 * 1_000) {
|
|
17
|
+
const { automation } = input;
|
|
18
|
+
const workspaceRouter = this.options.getWorkspaceRouter();
|
|
19
|
+
const threadId = await this.resolveThread(automation);
|
|
20
|
+
const prompt = renderAutomationPrompt(automation.action.promptTemplate, input.promptVariables);
|
|
21
|
+
const channelRuntime = automation.delivery.platform === 'local'
|
|
22
|
+
? undefined
|
|
23
|
+
: this.options.getChannelRuntime(automation.delivery.platform);
|
|
24
|
+
const bridge = channelRuntime
|
|
25
|
+
? await scheduled_bridge_session_js_1.ScheduledBridgeSession.open({
|
|
26
|
+
target: {
|
|
27
|
+
id: automation.id,
|
|
28
|
+
workspaceId: automation.workspaceId,
|
|
29
|
+
platform: automation.delivery.platform,
|
|
30
|
+
route: automation.delivery.route,
|
|
31
|
+
title: automation.title,
|
|
32
|
+
promptTemplate: automation.action.promptTemplate,
|
|
33
|
+
},
|
|
34
|
+
threadId,
|
|
35
|
+
workspaceRouter,
|
|
36
|
+
getChannelRuntime: () => channelRuntime,
|
|
37
|
+
noticeIcon: automation.originKind === 'automation-monitor'
|
|
38
|
+
&& input.promptVariables.sourceType === 'stock.quote' ? '📈' : '🔔',
|
|
39
|
+
noticeTitle: automation.title,
|
|
40
|
+
})
|
|
41
|
+
: undefined;
|
|
42
|
+
try {
|
|
43
|
+
const sendResult = await workspaceRouter.sendThreadMessage(threadId, prompt, {
|
|
44
|
+
permissionMode: AUTOMATION_RUN_PERMISSION_MODE,
|
|
45
|
+
runtimeEnv: (0, scheduled_job_route_js_1.buildPlatformRuntimeEnv)(automation.delivery.platform, automation.delivery.route),
|
|
46
|
+
});
|
|
47
|
+
await (0, run_polling_js_1.waitForRunCompletion)(this.options.store, sendResult.runId, timeoutMs, automation.originKind === 'automation-monitor' ? 'Monitor' : 'Automation');
|
|
48
|
+
const thread = await workspaceRouter.getThread(threadId);
|
|
49
|
+
const replyText = [...thread.messages]
|
|
50
|
+
.reverse()
|
|
51
|
+
.find((message) => message.role === 'assistant' && message.kind === 'final')
|
|
52
|
+
?.content;
|
|
53
|
+
return {
|
|
54
|
+
threadId,
|
|
55
|
+
acpRunId: sendResult.runId,
|
|
56
|
+
replyText,
|
|
57
|
+
deliveryMode: bridge ? 'bridge-stream' : 'thread-only',
|
|
58
|
+
deliveryStatus: 'succeeded',
|
|
59
|
+
lastBridgeEventAt: bridge ? new Date().toISOString() : undefined,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
finally {
|
|
63
|
+
await bridge?.close();
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
async resolveThread(automation) {
|
|
67
|
+
const workspaceRouter = this.options.getWorkspaceRouter();
|
|
68
|
+
const route = automation.delivery.route;
|
|
69
|
+
const platform = automation.delivery.platform;
|
|
70
|
+
if (automation.action.executionMode === 'same-thread') {
|
|
71
|
+
const binding = this.options.store.getPlatformThreadBinding(automation.workspaceId, route.channelId, route.participantId || '', platform);
|
|
72
|
+
if (binding?.thread_id && await (0, thread_resolution_js_1.threadExists)(workspaceRouter, binding.thread_id))
|
|
73
|
+
return binding.thread_id;
|
|
74
|
+
if (route.threadId && await (0, thread_resolution_js_1.threadExists)(workspaceRouter, route.threadId))
|
|
75
|
+
return route.threadId;
|
|
76
|
+
}
|
|
77
|
+
const label = automation.originKind === 'automation-monitor' ? 'Monitor' : 'Automation';
|
|
78
|
+
const title = platform === 'local'
|
|
79
|
+
? `[${label}] ${automation.title}`
|
|
80
|
+
: `[${label}:${(0, scheduled_job_route_js_1.getChannelPlatformBase)(platform) || platform}] ${automation.title}`;
|
|
81
|
+
const existing = (await workspaceRouter.listThreads(automation.workspaceId))
|
|
82
|
+
.find((thread) => thread.title === title);
|
|
83
|
+
if (existing)
|
|
84
|
+
return existing.id;
|
|
85
|
+
return (await workspaceRouter.createThread(automation.workspaceId, title)).id;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
exports.AutomationActionExecutor = AutomationActionExecutor;
|
|
89
|
+
function renderAutomationPrompt(template, values) {
|
|
90
|
+
return String(template || '').replace(/\{\{\s*([a-zA-Z0-9_.-]+)\s*\}\}/g, (_match, key) => {
|
|
91
|
+
if (UNSAFE_PROMPT_KEYS.has(key))
|
|
92
|
+
return '';
|
|
93
|
+
const descriptor = Object.getOwnPropertyDescriptor(values, key);
|
|
94
|
+
if (!descriptor || !Object.prototype.hasOwnProperty.call(descriptor, 'value'))
|
|
95
|
+
return '';
|
|
96
|
+
return serializePromptValue(descriptor.value);
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
function serializePromptValue(value) {
|
|
100
|
+
if (value === null || value === undefined)
|
|
101
|
+
return '';
|
|
102
|
+
if (typeof value !== 'object')
|
|
103
|
+
return String(value);
|
|
104
|
+
try {
|
|
105
|
+
return JSON.stringify(toSafeJsonValue(value, new Set())) ?? '';
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
return '[Unserializable]';
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
function toSafeJsonValue(value, seen) {
|
|
112
|
+
if (value === null || typeof value !== 'object') {
|
|
113
|
+
return typeof value === 'bigint' ? String(value) : value;
|
|
114
|
+
}
|
|
115
|
+
if (seen.has(value))
|
|
116
|
+
throw new Error('Circular prompt value.');
|
|
117
|
+
seen.add(value);
|
|
118
|
+
try {
|
|
119
|
+
if (Array.isArray(value)) {
|
|
120
|
+
return value.map((_entry, index) => {
|
|
121
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, String(index));
|
|
122
|
+
return descriptor && Object.prototype.hasOwnProperty.call(descriptor, 'value')
|
|
123
|
+
? toSafeJsonValue(descriptor.value, seen)
|
|
124
|
+
: null;
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
const result = Object.create(null);
|
|
128
|
+
for (const key of Object.keys(value)) {
|
|
129
|
+
if (UNSAFE_PROMPT_KEYS.has(key))
|
|
130
|
+
continue;
|
|
131
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
132
|
+
if (!descriptor || !Object.prototype.hasOwnProperty.call(descriptor, 'value'))
|
|
133
|
+
continue;
|
|
134
|
+
const nested = descriptor.value;
|
|
135
|
+
if (typeof nested === 'function' || typeof nested === 'symbol' || nested === undefined)
|
|
136
|
+
continue;
|
|
137
|
+
result[key] = toSafeJsonValue(nested, seen);
|
|
138
|
+
}
|
|
139
|
+
return result;
|
|
140
|
+
}
|
|
141
|
+
finally {
|
|
142
|
+
seen.delete(value);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.admitConditionEvaluation = admitConditionEvaluation;
|
|
4
|
+
exports.decideTrigger = decideTrigger;
|
|
5
|
+
exports.evaluateCondition = evaluateCondition;
|
|
6
|
+
exports.decideCondition = decideCondition;
|
|
7
|
+
const condition_evaluator_js_1 = require("./condition-evaluator.js");
|
|
8
|
+
function admitConditionEvaluation(evaluationRunning) {
|
|
9
|
+
return evaluationRunning
|
|
10
|
+
? { admitted: false, conditionOutcome: 'skipped', triggerDecision: 'skipped_concurrent' }
|
|
11
|
+
: { admitted: true };
|
|
12
|
+
}
|
|
13
|
+
function decideTrigger(input) {
|
|
14
|
+
if (!input.matched) {
|
|
15
|
+
return { conditionOutcome: 'not_matched', triggerDecision: 'not_rising', nextMatch: false };
|
|
16
|
+
}
|
|
17
|
+
if (input.previous === true) {
|
|
18
|
+
return { conditionOutcome: 'matched', triggerDecision: 'not_rising', nextMatch: true };
|
|
19
|
+
}
|
|
20
|
+
if (input.coolingDown) {
|
|
21
|
+
return { conditionOutcome: 'matched', triggerDecision: 'skipped_cooldown', nextMatch: true };
|
|
22
|
+
}
|
|
23
|
+
if (input.actionRunning) {
|
|
24
|
+
return { conditionOutcome: 'matched', triggerDecision: 'skipped_action_running', nextMatch: true };
|
|
25
|
+
}
|
|
26
|
+
return { conditionOutcome: 'matched', triggerDecision: 'triggered', nextMatch: true };
|
|
27
|
+
}
|
|
28
|
+
function evaluateCondition(condition, payload = {}) {
|
|
29
|
+
switch (condition.kind) {
|
|
30
|
+
case 'always':
|
|
31
|
+
return { kind: 'evaluated', matched: true };
|
|
32
|
+
case 'expression':
|
|
33
|
+
return { kind: 'evaluated', matched: (0, condition_evaluator_js_1.evaluateRestrictedExpression)(condition.expression, payload) };
|
|
34
|
+
case 'approved-script':
|
|
35
|
+
return {
|
|
36
|
+
kind: 'script-delegation',
|
|
37
|
+
request: {
|
|
38
|
+
scriptId: condition.scriptId,
|
|
39
|
+
approvedVersionId: condition.approvedVersionId,
|
|
40
|
+
edge: condition.edge,
|
|
41
|
+
payload,
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function decideCondition(input, evaluator = evaluateCondition) {
|
|
47
|
+
const admission = admitConditionEvaluation(input.evaluationRunning === true);
|
|
48
|
+
if (!admission.admitted) {
|
|
49
|
+
return {
|
|
50
|
+
kind: 'decision',
|
|
51
|
+
conditionOutcome: admission.conditionOutcome,
|
|
52
|
+
triggerDecision: admission.triggerDecision,
|
|
53
|
+
nextMatch: input.previous,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
try {
|
|
57
|
+
const evaluation = evaluator(input.condition, input.payload);
|
|
58
|
+
if (evaluation.kind === 'script-delegation')
|
|
59
|
+
return evaluation;
|
|
60
|
+
return {
|
|
61
|
+
kind: 'decision',
|
|
62
|
+
...decideTrigger({
|
|
63
|
+
previous: input.previous,
|
|
64
|
+
matched: evaluation.matched,
|
|
65
|
+
coolingDown: input.coolingDown,
|
|
66
|
+
actionRunning: input.actionRunning,
|
|
67
|
+
}),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
return {
|
|
72
|
+
kind: 'decision',
|
|
73
|
+
conditionOutcome: 'error',
|
|
74
|
+
triggerDecision: 'not_evaluated',
|
|
75
|
+
nextMatch: input.previous,
|
|
76
|
+
error: error instanceof Error ? error.message : String(error),
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
}
|
package/dist-electron/services/local-ai-core/src/automation/automation-conversation-executor.js
CHANGED
|
@@ -2,88 +2,55 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.AutomationConversationExecutor = void 0;
|
|
4
4
|
exports.renderMonitorPrompt = renderMonitorPrompt;
|
|
5
|
-
const
|
|
6
|
-
const scheduled_job_route_js_1 = require("../scheduler/scheduled-job-route.js");
|
|
7
|
-
const run_polling_js_1 = require("../scheduler/run-polling.js");
|
|
8
|
-
const thread_resolution_js_1 = require("../scheduler/thread-resolution.js");
|
|
9
|
-
const MONITOR_RUN_PERMISSION_MODE = 'bypassPermissions';
|
|
5
|
+
const automation_action_executor_js_1 = require("./automation-action-executor.js");
|
|
10
6
|
class AutomationConversationExecutor {
|
|
11
|
-
|
|
7
|
+
executor;
|
|
12
8
|
constructor(options) {
|
|
13
|
-
this.
|
|
9
|
+
this.executor = new automation_action_executor_js_1.AutomationActionExecutor(options);
|
|
14
10
|
}
|
|
15
11
|
async execute(monitor, event, timeoutMs = 15 * 60 * 1000) {
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
title: monitor.title,
|
|
12
|
+
const result = await this.executor.execute({
|
|
13
|
+
automation: {
|
|
14
|
+
id: monitor.id,
|
|
15
|
+
workspaceId: monitor.workspaceId,
|
|
16
|
+
title: monitor.title,
|
|
17
|
+
enabled: monitor.enabled,
|
|
18
|
+
health: 'healthy',
|
|
19
|
+
activation: { kind: 'provider-event', sourceType: monitor.sourceType, sourceConfig: monitor.sourceConfig },
|
|
20
|
+
condition: { kind: 'always' },
|
|
21
|
+
action: {
|
|
22
|
+
kind: 'agent-prompt',
|
|
28
23
|
promptTemplate: monitor.promptTemplate,
|
|
24
|
+
executionMode: monitor.executionMode === 'same-thread' ? 'same-thread' : 'side-thread',
|
|
29
25
|
},
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
runId: sendResult.runId,
|
|
51
|
-
replyText,
|
|
52
|
-
deliveryMode: bridge ? 'bridge-stream' : 'thread-only',
|
|
53
|
-
deliveryStatus: 'succeeded',
|
|
54
|
-
lastBridgeEventAt: bridge ? new Date().toISOString() : undefined,
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
finally {
|
|
58
|
-
await bridge?.close();
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
async resolveThread(monitor) {
|
|
62
|
-
const workspaceRouter = this.options.getWorkspaceRouter();
|
|
63
|
-
if (monitor.executionMode === 'same-thread') {
|
|
64
|
-
const binding = this.options.store.getPlatformThreadBinding(monitor.workspaceId, monitor.route.channelId, monitor.route.participantId || '', monitor.platform);
|
|
65
|
-
if (binding?.thread_id && await (0, thread_resolution_js_1.threadExists)(workspaceRouter, binding.thread_id)) {
|
|
66
|
-
return binding.thread_id;
|
|
67
|
-
}
|
|
68
|
-
if (monitor.route.threadId && await (0, thread_resolution_js_1.threadExists)(workspaceRouter, monitor.route.threadId)) {
|
|
69
|
-
return monitor.route.threadId;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
const title = monitor.platform === 'local'
|
|
73
|
-
? `[Monitor] ${monitor.title}`
|
|
74
|
-
: `[Monitor:${(0, scheduled_job_route_js_1.getChannelPlatformBase)(monitor.platform) || monitor.platform}] ${monitor.title}`;
|
|
75
|
-
const existing = (await workspaceRouter.listThreads(monitor.workspaceId))
|
|
76
|
-
.find((thread) => thread.title === title);
|
|
77
|
-
if (existing) {
|
|
78
|
-
return existing.id;
|
|
79
|
-
}
|
|
80
|
-
const created = await workspaceRouter.createThread(monitor.workspaceId, title);
|
|
81
|
-
return created.id;
|
|
26
|
+
delivery: { platform: monitor.platform, route: monitor.route },
|
|
27
|
+
policies: { concurrency: 'skip-if-running', cooldownMs: monitor.cooldownMs },
|
|
28
|
+
consecutiveEvaluationFailures: 0,
|
|
29
|
+
createdAt: monitor.createdAt,
|
|
30
|
+
updatedAt: monitor.updatedAt,
|
|
31
|
+
originKind: 'automation-monitor',
|
|
32
|
+
},
|
|
33
|
+
evaluation: {
|
|
34
|
+
id: `legacy-monitor-event:${monitor.id}`,
|
|
35
|
+
automationId: monitor.id,
|
|
36
|
+
status: 'finished',
|
|
37
|
+
activationKind: 'provider-event',
|
|
38
|
+
startedAt: event.occurredAt,
|
|
39
|
+
finishedAt: event.occurredAt,
|
|
40
|
+
conditionOutcome: 'matched',
|
|
41
|
+
triggerDecision: 'triggered',
|
|
42
|
+
},
|
|
43
|
+
promptVariables: monitorPromptVariables(event, monitor),
|
|
44
|
+
}, timeoutMs);
|
|
45
|
+
return { ...result, runId: result.acpRunId };
|
|
82
46
|
}
|
|
83
47
|
}
|
|
84
48
|
exports.AutomationConversationExecutor = AutomationConversationExecutor;
|
|
85
49
|
function renderMonitorPrompt(template, event, monitor) {
|
|
86
|
-
|
|
50
|
+
return String(template || '').replace(/\{\{\s*([a-zA-Z0-9_.-]+)\s*\}\}/g, (_match, key) => String(monitorPromptVariables(event, monitor)[key] ?? ''));
|
|
51
|
+
}
|
|
52
|
+
function monitorPromptVariables(event, monitor) {
|
|
53
|
+
return {
|
|
87
54
|
title: monitor.title,
|
|
88
55
|
sourceType: event.sourceType,
|
|
89
56
|
subject: event.subject,
|
|
@@ -91,5 +58,4 @@ function renderMonitorPrompt(template, event, monitor) {
|
|
|
91
58
|
timestamp: event.occurredAt,
|
|
92
59
|
...event.payload,
|
|
93
60
|
};
|
|
94
|
-
return String(template || '').replace(/\{\{\s*([a-zA-Z0-9_.-]+)\s*\}\}/g, (_match, key) => String(values[key] ?? ''));
|
|
95
61
|
}
|