@xopcai/xopc 0.0.205 → 0.0.207
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 +7 -7
- package/README.zh-CN.md +7 -7
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{activity-store-DJBadfSX.js → activity-store-BmpM0zwM.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-Br6C32BX.js → agent-avatar-dicebear-DhK5wi6_.js} +1 -1
- package/dist/gateway/static/root/assets/agents-Bc3Lc-n2.js +68 -0
- package/dist/gateway/static/root/assets/{api-B5O7fKXa.js → api-CzaAcDOn.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-Le1vJ1OO.js → app-management-settings-panel-Dqj5G_cd.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-CZlAU60t.js → appearance-settings-Bm1uLGMi.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-BKtwU47-.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-CRzXRXPE.js → archive-plugin-CgnzBplN.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-CYAAQ6Qi.js → attachment-load-Cuybcmhn.js} +1 -1
- package/dist/gateway/static/root/assets/automations-page-ilGeRLDN.js +6 -0
- package/dist/gateway/static/root/assets/{binary-plugins-CVR5cUmS.js → binary-plugins-D6BBx6Ps.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-CFe74rWi.js → block-editor-Dk1c3Spa.js} +46 -46
- package/dist/gateway/static/root/assets/browser-settings-page-BCu8AZbs.js +8 -0
- package/dist/gateway/static/root/assets/{browser-workflow-inputs-Bd68yluo.js → browser-workflow-inputs-DvfIzCgV.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-workflows-page-B0uiDLga.js → browser-workflows-page-DZScuPlF.js} +2 -2
- package/dist/gateway/static/root/assets/capabilities-settings-panel-BbWQBtTe.js +7 -0
- package/dist/gateway/static/root/assets/{capability-presets-api-BerPMp6f.js → capability-presets-api-hoA8R_J1.js} +1 -1
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-BTVU46Yn.js +3 -0
- package/dist/gateway/static/root/assets/{channel-recipient-api-D2d21_XA.js → channel-recipient-api-BS8I65NT.js} +1 -1
- package/dist/gateway/static/root/assets/channels-settings-BEQsC9a9.js +1 -0
- package/dist/gateway/static/root/assets/channels-status-swr-DRwbgtOT.js +1 -0
- package/dist/gateway/static/root/assets/chat-terminal-dock-BIPhWBDI.js +36 -0
- package/dist/gateway/static/root/assets/chat-terminal-dock-uQUnjRtf.css +1 -0
- package/dist/gateway/static/root/assets/{connectors-api-Bq_vUzxP.js → connectors-api-B_78jmvM.js} +1 -1
- package/dist/gateway/static/root/assets/connectors-page-w_3kpqbc.js +2 -0
- package/dist/gateway/static/root/assets/{cron-expression-DZBxmKGR.js → cron-expression-BBheaBIr.js} +1 -1
- package/dist/gateway/static/root/assets/{date-picker-BNHd7HT7.js → date-picker-CDwj7UrT.js} +1 -1
- package/dist/gateway/static/root/assets/{dependency-picker-D1kJBknt.js → dependency-picker-Dnrc2qZe.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-Di75oHkC.js → desktop-pet-Bj_vUjXp.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-D6tD1uym.js → desktop-pet-settings-uiCwJJk4.js} +1 -1
- package/dist/gateway/static/root/assets/directory-picker-path-field-D0zUQ-TO.js +1 -0
- package/dist/gateway/static/root/assets/{extension-debug-page-D91_S7NQ.js → extension-debug-page-_GZ4y2da.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-DHzmmr_N.js → extension-page-scR96Edg.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-BpJNtePi.js → extension-settings-page-CILsAwxx.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-api-BAzLYTKZ.js → gateway-config-api-984O_4wM.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-swr-VVcfd3sG.js → gateway-config-swr-D4hvsdJA.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-settings-C5-aKkTp.js → gateway-settings-aF4eQHo3.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-startup-retry-qAX_T2t2.js → gateway-startup-retry-Deo5-O87.js} +1 -1
- package/dist/gateway/static/root/assets/heartbeat-settings-D5DrFWH6.js +1 -0
- package/dist/gateway/static/root/assets/home-page-DiMWxngC.js +3 -0
- package/dist/gateway/static/root/assets/index-DzKLVgY-.js +85 -0
- package/dist/gateway/static/root/assets/index-wR5jX-lw.css +2 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-fpNjXnJK.js → keyboard-shortcuts-settings-DGmOlNcB.js} +1 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-De8vuwu1.js +2 -0
- package/dist/gateway/static/root/assets/{local-apps-page-DBpQIfNd.js → local-apps-page-CzS2sCxg.js} +1 -1
- package/dist/gateway/static/root/assets/{locale-store-CbPVxonP.js → locale-store-C7xtkP3D.js} +1 -1
- package/dist/gateway/static/root/assets/logs-page-BI9stsVO.js +2 -0
- package/dist/gateway/static/root/assets/{management-settings-CiK7Xkvi.js → management-settings-Cpxs43JB.js} +1 -1
- package/dist/gateway/static/root/assets/{markdown-split-DVgpcOze.js → markdown-split-CQvFHxUa.js} +1 -1
- package/dist/gateway/static/root/assets/{markdown-view-Dl-0_9JR.js → markdown-view-BRwrSbwM.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-DMj1lW-n.js → media-plugins-Bs9MsiaM.js} +1 -1
- package/dist/gateway/static/root/assets/messages-Dxk5Rzj_.js +3 -0
- package/dist/gateway/static/root/assets/{notes-page-DvX1sTlf.js → notes-page-Dux_g6aZ.js} +1 -1
- package/dist/gateway/static/root/assets/notes-workbench-CGafcgJ8.js +4 -0
- package/dist/gateway/static/root/assets/{preview-open-alternatives-DvsLigha.js → preview-open-alternatives-fvhtN4Y2.js} +1 -1
- package/dist/gateway/static/root/assets/{product-open-page-DbCraAI3.js → product-open-page-f_jbg-9N.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-C6mNsjYr.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-D1G6VIxR.js +1 -0
- package/dist/gateway/static/root/assets/remote-access-hub-CIez6X0x.js +1 -0
- package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-DzuUglQo.js → runtime-tools-settings-panel-zapSiJrv.js} +1 -1
- package/dist/gateway/static/root/assets/{schema-form-plDnazVj.js → schema-form-CFyz8y5v.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-6irxQjHb.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-CRb0QTG2.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-BwAxX_7e.js → settings-form-section-DCiK4TIq.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-loading-skeleton-B3OiTnF9.js → settings-loading-skeleton-DFUJEv4G.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-DvIWXBvp.js → settings-page-Cnp9Bdd0.js} +1 -1
- package/dist/gateway/static/root/assets/{setup-status-panel-DThKKjLV.js → setup-status-panel-BFMGTGBO.js} +1 -1
- package/dist/gateway/static/root/assets/{share-preview-page-CFnoGHJb.js → share-preview-page-DA8nA4cz.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-CaKfvJzQ.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-BOBUcYr5.js +1 -0
- package/dist/gateway/static/root/assets/{skills-page-B38fY22S.js → skills-page-BJJACxzz.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page.utils-vLIlk1c3.js → skills-page.utils--1-vOg3V.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-DRV2wljT.js → system-settings-panel-DY0lIaXY.js} +1 -1
- package/dist/gateway/static/root/assets/task-detail-page-Ciuwe7AG.js +1 -0
- package/dist/gateway/static/root/assets/{theme-store-Bc_eRUev.js → theme-store-DoyRfkoi.js} +1 -1
- package/dist/gateway/static/root/assets/{use-autosave-DTu23D9J.js → use-autosave-DzIR5Lxf.js} +1 -1
- package/dist/gateway/static/root/assets/{user-context-page-DCwqzN03.js → user-context-page-yf18T_BZ.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-api-key-field-CVDMesWc.js → voice-api-key-field-B7MZS8tS.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-overlay-cyt93k0V.js → work-discovery-overlay-zyX6yxxF.js} +1 -1
- package/dist/gateway/static/root/assets/work-discovery-page-2e5J0sIp.js +1 -0
- package/dist/gateway/static/root/assets/workflow-run-setup-panel-Cj1vPWRM.js +3 -0
- package/dist/gateway/static/root/assets/workflows-page-D37zWlWY.js +5 -0
- package/dist/gateway/static/root/assets/{working-directory-picker-modal-CYWdZUJ5.js → working-directory-picker-modal-Bm7cox3y.js} +1 -1
- package/dist/gateway/static/root/index.html +10 -10
- package/dist/package.js +1 -1
- package/dist/src/agent/agent-manager.d.ts +11 -0
- package/dist/src/agent/agent-manager.js +36 -6
- package/dist/src/agent/embedded/transcript-runtime.d.ts +2 -1
- package/dist/src/agent/embedded/transcript-runtime.js +38 -4
- package/dist/src/agent/inbound/inbound-loop.d.ts +1 -1
- package/dist/src/agent/memory/compaction-ledger.d.ts +11 -0
- package/dist/src/agent/memory/compaction-ledger.js +108 -0
- package/dist/src/agent/memory/compaction-serializer.d.ts +2 -0
- package/dist/src/agent/memory/compaction-serializer.js +52 -0
- package/dist/src/agent/memory/compaction-source-planner.d.ts +20 -0
- package/dist/src/agent/memory/compaction-source-planner.js +67 -0
- package/dist/src/agent/memory/compaction.d.ts +11 -5
- package/dist/src/agent/memory/compaction.js +245 -153
- package/dist/src/agent/prompt/sections/behavior.js +1 -1
- package/dist/src/agent/prompt/sections/memory-skills.js +4 -2
- package/dist/src/agent/prompt/sections/tooling.js +2 -0
- package/dist/src/agent/service.d.ts +4 -1
- package/dist/src/agent/service.js +12 -0
- package/dist/src/agent/tool-manuals/xopc-use.d.ts +1 -1
- package/dist/src/agent/tool-manuals/xopc-use.js +1 -1
- package/dist/src/agent/tools/factory.js +5 -0
- package/dist/src/agent/tools/index.d.ts +1 -0
- package/dist/src/agent/tools/index.js +2 -1
- package/dist/src/agent/tools/session-recall-tool.d.ts +7 -0
- package/dist/src/agent/tools/session-recall-tool.js +82 -0
- package/dist/src/agent/tools/xopc-use-tool.js +6 -2
- package/dist/src/automations/api/routes.js +8 -0
- package/dist/src/automations/domain/index.js +2 -2
- package/dist/src/automations/domain/types.d.ts +17 -12
- package/dist/src/automations/domain/validation.d.ts +30 -32
- package/dist/src/automations/domain/validation.js +8 -10
- package/dist/src/automations/draft/automation-draft-prompt.js +9 -5
- package/dist/src/automations/draft/automation-draft-validator.d.ts +3 -8
- package/dist/src/automations/draft/automation-draft-validator.js +3 -3
- package/dist/src/automations/index.js +2 -2
- package/dist/src/automations/service/action-executor.js +13 -4
- package/dist/src/automations/service/automation-service.d.ts +5 -1
- package/dist/src/automations/service/automation-service.js +19 -12
- package/dist/src/automations/storage/automation-repository.js +8 -4
- package/dist/src/automations/storage/automation-run-repository.d.ts +5 -0
- package/dist/src/automations/storage/automation-run-repository.js +24 -8
- package/dist/src/automations/storage/index.js +2 -2
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/config/agent-profile.js +1 -1
- package/dist/src/config/schema.d.ts +1 -0
- package/dist/src/gateway/agents-admin.js +1 -1
- package/dist/src/gateway/automation-agent-session.d.ts +4 -0
- package/dist/src/gateway/automation-agent-session.js +40 -0
- package/dist/src/gateway/dreaming-automation-reconciler.js +3 -2
- package/dist/src/gateway/heartbeat/service.js +1 -1
- package/dist/src/gateway/hono/lib/config-payload.d.ts +1 -0
- package/dist/src/gateway/hono/routes/commands-skills.js +36 -2
- package/dist/src/gateway/hono/routes/lazy-bundles.js +1 -0
- package/dist/src/gateway/service/marketplace-service.d.ts +4 -1
- package/dist/src/gateway/service/marketplace-service.js +9 -0
- package/dist/src/gateway/service/run-gateway-agent.js +3 -3
- package/dist/src/gateway/service.js +19 -2
- package/dist/src/heartbeat/index.js +1 -1
- package/dist/src/mobile/notification-service.js +7 -4
- package/dist/src/session/compaction-types.d.ts +30 -0
- package/dist/src/session/compaction-types.js +35 -0
- package/dist/src/session/manager.d.ts +3 -0
- package/dist/src/session/session-context-for-llm.d.ts +4 -2
- package/dist/src/session/session-context-for-llm.js +2 -1
- package/dist/src/session/store.d.ts +10 -1
- package/dist/src/session/store.js +55 -23
- package/dist/src/session/types.d.ts +3 -2
- package/dist/src/storage/sqlite/index.d.ts +1 -1
- package/dist/src/storage/sqlite/index.js +2 -2
- package/dist/src/storage/sqlite/migrations/121_automation_inbox.sql +24 -0
- package/dist/src/storage/sqlite/migrations/122_automation_session_projects.sql +18 -0
- package/dist/src/storage/sqlite/migrations/123_remove_v2_compaction_boundaries.sql +25 -0
- package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
- package/dist/src/storage/sqlite/migrations/runner.js +3 -3
- package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
- package/dist/src/storage/sqlite/schema.js +1 -1
- package/dist/src/storage/sqlite/transcript-repository.d.ts +24 -1
- package/dist/src/storage/sqlite/transcript-repository.js +78 -29
- package/dist/src/user-context/config.d.ts +4 -0
- package/dist/src/user-context/config.js +2 -0
- package/package.json +4 -3
- package/skills/THIRD_PARTY_NOTICES.md +1 -1
- package/skills/engineering/define-task/SKILL.md +48 -0
- package/skills/engineering/define-task/references/task-contract-rubric.md +15 -0
- package/dist/gateway/static/root/assets/agents-DnFIy8Ye.js +0 -68
- package/dist/gateway/static/root/assets/apps-page-CONlVc-f.js +0 -1
- package/dist/gateway/static/root/assets/automations-page-DuG69tIj.js +0 -6
- package/dist/gateway/static/root/assets/browser-settings-page-Cvt-8fqE.js +0 -8
- package/dist/gateway/static/root/assets/capabilities-settings-panel-yk3QkGBP.js +0 -7
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-DJjVOCJY.js +0 -3
- package/dist/gateway/static/root/assets/channels-settings-CaNnYUQo.js +0 -1
- package/dist/gateway/static/root/assets/channels-status-swr-CZ5P9jbB.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-DTpCnOsQ.js +0 -2
- package/dist/gateway/static/root/assets/directory-picker-path-field-Ly0TUflq.js +0 -1
- package/dist/gateway/static/root/assets/heartbeat-settings-CMZr1_Op.js +0 -1
- package/dist/gateway/static/root/assets/home-page-CBG9Bk-1.js +0 -3
- package/dist/gateway/static/root/assets/index-BBw9QL0p.js +0 -85
- package/dist/gateway/static/root/assets/index-Dm-cvIpl.css +0 -2
- package/dist/gateway/static/root/assets/local-app-workbench-page-Bi_0Sknt.js +0 -2
- package/dist/gateway/static/root/assets/logs-page-BmXcJCKz.js +0 -2
- package/dist/gateway/static/root/assets/messages-9zCa8KkW.js +0 -3
- package/dist/gateway/static/root/assets/notes-workbench-CMyosgjY.js +0 -4
- package/dist/gateway/static/root/assets/project-detail-page-DkS-kbpj.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-B3NxP6S4.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-DwhrMhjl.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-BOfXXmBL.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-sPrZfZVR.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-Dvl13Udt.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-D9elkZOz.js +0 -1
- package/dist/gateway/static/root/assets/task-detail-page-Xd8PlB24.js +0 -1
- package/dist/gateway/static/root/assets/work-discovery-page--DTi90d5.js +0 -1
- package/dist/gateway/static/root/assets/workflow-run-setup-panel-DrdcfX_N.js +0 -3
- package/dist/gateway/static/root/assets/workflows-page-DXyButkm.js +0 -5
- package/dist/src/agent/memory/compaction-planner.d.ts +0 -16
- package/dist/src/agent/memory/compaction-planner.js +0 -168
- package/dist/src/agent/memory/summary-generator.d.ts +0 -46
- package/dist/src/agent/memory/summary-generator.js +0 -229
- package/skills/engineering/define-goal/SKILL.md +0 -41
- package/skills/engineering/define-goal/references/objective-rubric.md +0 -12
|
@@ -49,6 +49,10 @@ export declare class AutomationService {
|
|
|
49
49
|
}): Promise<AutomationProductEventRun[]>;
|
|
50
50
|
getRun(runId: string): Promise<AutomationRun | null>;
|
|
51
51
|
listRunEvents(runId: string): Promise<AutomationRunEvent[]>;
|
|
52
|
+
markRunRead(runId: string): Promise<boolean>;
|
|
53
|
+
markAllRunsRead(options?: {
|
|
54
|
+
projectId?: string;
|
|
55
|
+
}): Promise<number>;
|
|
52
56
|
cancelRun(runId: string): Promise<boolean>;
|
|
53
57
|
getMetrics(): Promise<AutomationMetrics>;
|
|
54
58
|
private recomputeNextRuns;
|
|
@@ -60,5 +64,5 @@ export declare class AutomationService {
|
|
|
60
64
|
private waitForRetry;
|
|
61
65
|
private appendRunEvent;
|
|
62
66
|
private finishAutomationRun;
|
|
63
|
-
private
|
|
67
|
+
private postCompletionWebhook;
|
|
64
68
|
}
|
|
@@ -5,7 +5,7 @@ import { computeNextAutomationRunAtMs, timerDelayUntil } from "../domain/schedul
|
|
|
5
5
|
import { AutomationSchema, CreateAutomationSchema, UpdateAutomationSchema } from "../domain/validation.js";
|
|
6
6
|
import { AutomationActionExecutor } from "./action-executor.js";
|
|
7
7
|
import { deleteAutomation, getAutomation, listAutomations, saveAutomation, saveAutomations } from "../storage/automation-repository.js";
|
|
8
|
-
import { appendAutomationRunEvent, getAutomationRun, listAutomationRunEvents, listAutomationRuns, listAutomationRunsForProductEvent, saveAutomationRun, touchAutomationRunLease } from "../storage/automation-run-repository.js";
|
|
8
|
+
import { appendAutomationRunEvent, getAutomationRun, listAutomationRunEvents, listAutomationRuns, listAutomationRunsForProductEvent, markAllAutomationRunsRead, markAutomationRunRead, saveAutomationRun, touchAutomationRunLease } from "../storage/automation-run-repository.js";
|
|
9
9
|
import "../storage/index.js";
|
|
10
10
|
import { randomUUID } from "node:crypto";
|
|
11
11
|
//#region src/automations/service/automation-service.ts
|
|
@@ -71,7 +71,8 @@ var AutomationService = class {
|
|
|
71
71
|
id: parsed.id?.trim() || randomUUID().slice(0, 12),
|
|
72
72
|
enabled: parsed.enabled ?? true,
|
|
73
73
|
safety: parsed.safety ?? { mode: "auto_apply" },
|
|
74
|
-
|
|
74
|
+
conversationMode: parsed.conversationMode ?? "new_session",
|
|
75
|
+
notificationPolicy: parsed.notificationPolicy ?? "attention",
|
|
75
76
|
state: parsed.state ?? {},
|
|
76
77
|
createdAtMs: now,
|
|
77
78
|
updatedAtMs: now
|
|
@@ -165,6 +166,12 @@ var AutomationService = class {
|
|
|
165
166
|
async listRunEvents(runId) {
|
|
166
167
|
return listAutomationRunEvents(runId);
|
|
167
168
|
}
|
|
169
|
+
async markRunRead(runId) {
|
|
170
|
+
return markAutomationRunRead(runId);
|
|
171
|
+
}
|
|
172
|
+
async markAllRunsRead(options) {
|
|
173
|
+
return markAllAutomationRunsRead(options);
|
|
174
|
+
}
|
|
168
175
|
async cancelRun(runId) {
|
|
169
176
|
const controller = this.activeRuns.get(runId);
|
|
170
177
|
if (!controller) return false;
|
|
@@ -389,30 +396,30 @@ var AutomationService = class {
|
|
|
389
396
|
};
|
|
390
397
|
this.appendRunEvent(run, task.termination.cancellationConfirmed ? "run.cancel_confirmed" : "run.cancellation_unconfirmed", task.termination.cancellationConfirmed ? "Automation cancellation confirmed" : "Automation cancellation was not confirmed within the cleanup grace period", { termination: task.termination });
|
|
391
398
|
}
|
|
392
|
-
if (status === "timeout" || status === "cancelled") {} else if ((automation.safety?.mode ?? "auto_apply") !== "auto_apply" && automation.
|
|
393
|
-
else if (automation.
|
|
394
|
-
activePhase = "
|
|
399
|
+
if (status === "timeout" || status === "cancelled") {} else if ((automation.safety?.mode ?? "auto_apply") !== "auto_apply" && automation.completionWebhookUrl) this.appendRunEvent(run, "completion_hook.completed", "Completion webhook skipped by safety mode", { safety: automation.safety ?? { mode: "auto_apply" } });
|
|
400
|
+
else if (automation.completionWebhookUrl) {
|
|
401
|
+
activePhase = "completion_hook";
|
|
395
402
|
run = {
|
|
396
403
|
...run,
|
|
397
|
-
currentPhase: "
|
|
404
|
+
currentPhase: "completion_hook"
|
|
398
405
|
};
|
|
399
406
|
saveAutomationRun(run);
|
|
400
|
-
this.appendRunEvent(run, "
|
|
401
|
-
await this.
|
|
402
|
-
this.appendRunEvent(run, "
|
|
407
|
+
this.appendRunEvent(run, "completion_hook.started", "Calling completion webhook", { url: automation.completionWebhookUrl });
|
|
408
|
+
await this.postCompletionWebhook(automation.completionWebhookUrl, run, controller.signal);
|
|
409
|
+
this.appendRunEvent(run, "completion_hook.completed", "Completion webhook completed");
|
|
403
410
|
}
|
|
404
411
|
} catch (err) {
|
|
405
412
|
error = err instanceof Error ? err.message : String(err);
|
|
406
413
|
const deadlineExceeded = run.deadlineAtMs !== void 0 && Date.now() >= run.deadlineAtMs;
|
|
407
414
|
status = controller.signal.aborted ? "cancelled" : deadlineExceeded ? "timeout" : "failed";
|
|
408
|
-
this.appendRunEvent(run, activePhase === "
|
|
415
|
+
this.appendRunEvent(run, activePhase === "completion_hook" ? "completion_hook.failed" : "action.failed", `Automation run ${status}`, { error });
|
|
409
416
|
run = {
|
|
410
417
|
...run,
|
|
411
418
|
status,
|
|
412
419
|
error,
|
|
413
420
|
termination: {
|
|
414
421
|
reason: status === "cancelled" ? "user_cancelled" : status === "timeout" ? "deadline_exceeded" : "failed",
|
|
415
|
-
component: activePhase === "
|
|
422
|
+
component: activePhase === "completion_hook" ? "automation" : run.termination?.component,
|
|
416
423
|
cancellationConfirmed: status !== "cancelled" || controller.signal.aborted
|
|
417
424
|
}
|
|
418
425
|
};
|
|
@@ -580,7 +587,7 @@ var AutomationService = class {
|
|
|
580
587
|
saveAutomation(next);
|
|
581
588
|
this.armTimer();
|
|
582
589
|
}
|
|
583
|
-
async
|
|
590
|
+
async postCompletionWebhook(url, run, signal) {
|
|
584
591
|
const remainingMs = run.deadlineAtMs === void 0 ? 3e4 : Math.max(1, run.deadlineAtMs - Date.now());
|
|
585
592
|
const requestSignal = AbortSignal.any([signal, AbortSignal.timeout(remainingMs)]);
|
|
586
593
|
const response = await fetch(url, {
|
|
@@ -18,7 +18,9 @@ function rowToAutomation(row) {
|
|
|
18
18
|
trigger: parseJson(row.trigger_json),
|
|
19
19
|
action: parseJson(row.action_json),
|
|
20
20
|
safety: parseJson(row.safety_json) ?? { mode: "auto_apply" },
|
|
21
|
-
|
|
21
|
+
conversationMode: row.conversation_mode,
|
|
22
|
+
notificationPolicy: row.notification_policy,
|
|
23
|
+
completionWebhookUrl: row.completion_webhook_url ?? void 0,
|
|
22
24
|
reliability: parseJson(row.reliability_json),
|
|
23
25
|
state: parseJson(row.state_json) ?? {},
|
|
24
26
|
createdAtMs: row.created_at_ms,
|
|
@@ -28,12 +30,14 @@ function rowToAutomation(row) {
|
|
|
28
30
|
function upsertAutomation(db, automation) {
|
|
29
31
|
db.prepare(`INSERT OR REPLACE INTO automations (
|
|
30
32
|
automation_id, name, description, project_id, enabled, trigger_json, action_json,
|
|
31
|
-
safety_json,
|
|
32
|
-
|
|
33
|
+
safety_json, conversation_mode, notification_policy, completion_webhook_url,
|
|
34
|
+
reliability_json, state_json, created_at_ms, updated_at_ms
|
|
35
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(automation.id, automation.name, automation.description ?? null, automation.projectId ?? null, automation.enabled ? 1 : 0, JSON.stringify(automation.trigger), JSON.stringify(automation.action), bindJson(automation.safety ?? { mode: "auto_apply" }), automation.conversationMode, automation.notificationPolicy, automation.completionWebhookUrl ?? null, bindJson(automation.reliability), JSON.stringify(automation.state ?? {}), automation.createdAtMs, automation.updatedAtMs);
|
|
33
36
|
}
|
|
34
37
|
const AUTOMATION_SELECT = `
|
|
35
38
|
SELECT automation_id, name, description, project_id, enabled, trigger_json, action_json,
|
|
36
|
-
safety_json,
|
|
39
|
+
safety_json, conversation_mode, notification_policy, completion_webhook_url,
|
|
40
|
+
reliability_json, state_json, created_at_ms, updated_at_ms
|
|
37
41
|
FROM automations
|
|
38
42
|
`;
|
|
39
43
|
function listAutomations(options) {
|
|
@@ -17,3 +17,8 @@ export declare function listAutomationRunsForProductEvent(options: {
|
|
|
17
17
|
limit?: number;
|
|
18
18
|
}): AutomationProductEventRun[];
|
|
19
19
|
export declare function deleteAutomationRunsForAutomation(automationId: string): void;
|
|
20
|
+
export declare function markAutomationRunRead(runId: string, readAtMs?: number): boolean;
|
|
21
|
+
export declare function markAllAutomationRunsRead(options?: {
|
|
22
|
+
projectId?: string;
|
|
23
|
+
readAtMs?: number;
|
|
24
|
+
}): number;
|
|
@@ -29,7 +29,8 @@ function rowToRun(row) {
|
|
|
29
29
|
leaseOwner: row.lease_owner ?? void 0,
|
|
30
30
|
leaseExpiresAtMs: row.lease_expires_at_ms ?? void 0,
|
|
31
31
|
attemptNumber: row.attempt_number,
|
|
32
|
-
rootRunId: row.root_run_id ?? void 0
|
|
32
|
+
rootRunId: row.root_run_id ?? void 0,
|
|
33
|
+
readAtMs: row.read_at_ms ?? void 0
|
|
33
34
|
};
|
|
34
35
|
}
|
|
35
36
|
function rowToEvent(row) {
|
|
@@ -68,8 +69,8 @@ function saveAutomationRun(run) {
|
|
|
68
69
|
duration_ms, summary, error, session_key, workflow_run_id, model,
|
|
69
70
|
deadline_at_ms, current_phase, cancel_requested_at_ms, cancel_confirmed_at_ms,
|
|
70
71
|
termination_json, heartbeat_at_ms, lease_owner, lease_expires_at_ms,
|
|
71
|
-
attempt_number, root_run_id
|
|
72
|
-
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(run.id, run.automationId, run.automationName, run.status, JSON.stringify(run.triggerSnapshot), JSON.stringify(run.actionSnapshot), run.manual ? 1 : 0, run.createdAtMs, run.startedAtMs ?? null, run.endedAtMs ?? null, run.durationMs ?? null, run.summary ?? null, run.error ?? null, run.sessionKey ?? null, run.workflowRunId ?? null, run.model ?? null, run.deadlineAtMs ?? null, run.currentPhase ?? null, run.cancelRequestedAtMs ?? null, run.cancelConfirmedAtMs ?? null, run.termination ? JSON.stringify(run.termination) : null, run.heartbeatAtMs ?? null, run.leaseOwner ?? null, run.leaseExpiresAtMs ?? null, run.attemptNumber ?? 1, run.rootRunId ?? run.id);
|
|
72
|
+
attempt_number, root_run_id, read_at_ms
|
|
73
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(run.id, run.automationId, run.automationName, run.status, JSON.stringify(run.triggerSnapshot), JSON.stringify(run.actionSnapshot), run.manual ? 1 : 0, run.createdAtMs, run.startedAtMs ?? null, run.endedAtMs ?? null, run.durationMs ?? null, run.summary ?? null, run.error ?? null, run.sessionKey ?? null, run.workflowRunId ?? null, run.model ?? null, run.deadlineAtMs ?? null, run.currentPhase ?? null, run.cancelRequestedAtMs ?? null, run.cancelConfirmedAtMs ?? null, run.termination ? JSON.stringify(run.termination) : null, run.heartbeatAtMs ?? null, run.leaseOwner ?? null, run.leaseExpiresAtMs ?? null, run.attemptNumber ?? 1, run.rootRunId ?? run.id, run.readAtMs ?? null);
|
|
73
74
|
trimRuns(db, run.automationId);
|
|
74
75
|
});
|
|
75
76
|
}
|
|
@@ -90,7 +91,7 @@ function getAutomationRun(runId) {
|
|
|
90
91
|
duration_ms, summary, error, session_key, workflow_run_id, model,
|
|
91
92
|
deadline_at_ms, current_phase, cancel_requested_at_ms, cancel_confirmed_at_ms,
|
|
92
93
|
termination_json, heartbeat_at_ms, lease_owner, lease_expires_at_ms,
|
|
93
|
-
attempt_number, root_run_id
|
|
94
|
+
attempt_number, root_run_id, read_at_ms
|
|
94
95
|
FROM automation_runs
|
|
95
96
|
WHERE run_id = ?`).get(runId);
|
|
96
97
|
return row ? rowToRun(row) : null;
|
|
@@ -103,7 +104,7 @@ function listAutomationRuns(options) {
|
|
|
103
104
|
duration_ms, summary, error, session_key, workflow_run_id, model,
|
|
104
105
|
deadline_at_ms, current_phase, cancel_requested_at_ms, cancel_confirmed_at_ms,
|
|
105
106
|
termination_json, heartbeat_at_ms, lease_owner, lease_expires_at_ms,
|
|
106
|
-
attempt_number, root_run_id
|
|
107
|
+
attempt_number, root_run_id, read_at_ms
|
|
107
108
|
FROM automation_runs`;
|
|
108
109
|
let rows;
|
|
109
110
|
if (options?.automationId) rows = db.prepare(`${base} WHERE automation_id = ? ORDER BY created_at_ms DESC LIMIT ?`).all(options.automationId, limit);
|
|
@@ -112,7 +113,7 @@ function listAutomationRuns(options) {
|
|
|
112
113
|
r.duration_ms, r.summary, r.error, r.session_key, r.workflow_run_id, r.model,
|
|
113
114
|
r.deadline_at_ms, r.current_phase, r.cancel_requested_at_ms, r.cancel_confirmed_at_ms,
|
|
114
115
|
r.termination_json, r.heartbeat_at_ms, r.lease_owner, r.lease_expires_at_ms,
|
|
115
|
-
r.attempt_number, r.root_run_id
|
|
116
|
+
r.attempt_number, r.root_run_id, r.read_at_ms
|
|
116
117
|
FROM automation_runs r
|
|
117
118
|
JOIN automations a ON a.automation_id = r.automation_id
|
|
118
119
|
WHERE a.project_id = ?
|
|
@@ -138,7 +139,7 @@ function listAutomationRunsForProductEvent(options) {
|
|
|
138
139
|
r.duration_ms, r.summary, r.error, r.session_key, r.workflow_run_id, r.model,
|
|
139
140
|
r.deadline_at_ms, r.current_phase, r.cancel_requested_at_ms, r.cancel_confirmed_at_ms,
|
|
140
141
|
r.termination_json, r.heartbeat_at_ms, r.lease_owner, r.lease_expires_at_ms,
|
|
141
|
-
r.attempt_number, r.root_run_id,
|
|
142
|
+
r.attempt_number, r.root_run_id, r.read_at_ms,
|
|
142
143
|
e.event_id, e.run_id AS event_run_id, e.automation_id AS event_automation_id,
|
|
143
144
|
e.type AS event_type, e.message AS event_message, e.data_json AS event_data_json,
|
|
144
145
|
e.created_at_ms AS event_created_at_ms
|
|
@@ -165,5 +166,20 @@ function deleteAutomationRunsForAutomation(automationId) {
|
|
|
165
166
|
db.prepare(`DELETE FROM automation_runs WHERE automation_id = ?`).run(automationId);
|
|
166
167
|
});
|
|
167
168
|
}
|
|
169
|
+
function markAutomationRunRead(runId, readAtMs = Date.now()) {
|
|
170
|
+
return getSqliteDatabase().prepare(`UPDATE automation_runs SET read_at_ms = ? WHERE run_id = ? AND ended_at_ms IS NOT NULL`).run(readAtMs, runId).changes > 0;
|
|
171
|
+
}
|
|
172
|
+
function markAllAutomationRunsRead(options) {
|
|
173
|
+
const projectId = options?.projectId?.trim();
|
|
174
|
+
const result = getSqliteDatabase().prepare(projectId ? `UPDATE automation_runs
|
|
175
|
+
SET read_at_ms = ?
|
|
176
|
+
WHERE read_at_ms IS NULL
|
|
177
|
+
AND ended_at_ms IS NOT NULL
|
|
178
|
+
AND EXISTS (
|
|
179
|
+
SELECT 1 FROM automations a
|
|
180
|
+
WHERE a.automation_id = automation_runs.automation_id AND a.project_id = ?
|
|
181
|
+
)` : `UPDATE automation_runs SET read_at_ms = ? WHERE read_at_ms IS NULL AND ended_at_ms IS NOT NULL`).run(options?.readAtMs ?? Date.now(), ...projectId ? [projectId] : []);
|
|
182
|
+
return Number(result.changes);
|
|
183
|
+
}
|
|
168
184
|
//#endregion
|
|
169
|
-
export { appendAutomationRunEvent, deleteAutomationRunsForAutomation, getAutomationRun, listAutomationRunEvents, listAutomationRuns, listAutomationRunsForProductEvent, saveAutomationRun, touchAutomationRunLease };
|
|
185
|
+
export { appendAutomationRunEvent, deleteAutomationRunsForAutomation, getAutomationRun, listAutomationRunEvents, listAutomationRuns, listAutomationRunsForProductEvent, markAllAutomationRunsRead, markAutomationRunRead, saveAutomationRun, touchAutomationRunLease };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { deleteAutomation, getAutomation, listAutomations, saveAutomation, saveAutomations } from "./automation-repository.js";
|
|
2
|
-
import { appendAutomationRunEvent, deleteAutomationRunsForAutomation, getAutomationRun, listAutomationRunEvents, listAutomationRuns, listAutomationRunsForProductEvent, saveAutomationRun, touchAutomationRunLease } from "./automation-run-repository.js";
|
|
3
|
-
export { appendAutomationRunEvent, deleteAutomation, deleteAutomationRunsForAutomation, getAutomation, getAutomationRun, listAutomationRunEvents, listAutomationRuns, listAutomationRunsForProductEvent, listAutomations, saveAutomation, saveAutomationRun, saveAutomations, touchAutomationRunLease };
|
|
2
|
+
import { appendAutomationRunEvent, deleteAutomationRunsForAutomation, getAutomationRun, listAutomationRunEvents, listAutomationRuns, listAutomationRunsForProductEvent, markAllAutomationRunsRead, markAutomationRunRead, saveAutomationRun, touchAutomationRunLease } from "./automation-run-repository.js";
|
|
3
|
+
export { appendAutomationRunEvent, deleteAutomation, deleteAutomationRunsForAutomation, getAutomation, getAutomationRun, listAutomationRunEvents, listAutomationRuns, listAutomationRunsForProductEvent, listAutomations, markAllAutomationRunsRead, markAutomationRunRead, saveAutomation, saveAutomationRun, saveAutomations, touchAutomationRunLease };
|
|
@@ -52,7 +52,7 @@ async function checkDatabaseSchema(ctx) {
|
|
|
52
52
|
id: "database-schema",
|
|
53
53
|
label: "Database schema",
|
|
54
54
|
status: "pass",
|
|
55
|
-
message: `SQLite schema v${status.dbVersion} (current release
|
|
55
|
+
message: `SQLite schema v${status.dbVersion} (current release v123).`,
|
|
56
56
|
hints: []
|
|
57
57
|
};
|
|
58
58
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { init_agent_scope, normalizeAgentId, resolveAgentWorkspaceDir } from "../agent/agent-scope.js";
|
|
2
1
|
import { resolveEffectiveAgentManifest } from "../agent-manifest/resolver.js";
|
|
3
2
|
import "../agent-manifest/index.js";
|
|
3
|
+
import { init_agent_scope, normalizeAgentId, resolveAgentWorkspaceDir } from "../agent/agent-scope.js";
|
|
4
4
|
import { init_session_key, parseSessionKey } from "../routing/session-key.js";
|
|
5
5
|
import { agentExists, getDefaultAgentId, init_resolve_route } from "../routing/resolve-route.js";
|
|
6
6
|
//#region src/config/agent-profile.ts
|
|
@@ -1537,6 +1537,7 @@ export declare const ConfigSchema: z.ZodDefault<z.ZodObject<{
|
|
|
1537
1537
|
summaryTimeoutMs: z.ZodDefault<z.ZodNumber>;
|
|
1538
1538
|
summaryRetries: z.ZodDefault<z.ZodNumber>;
|
|
1539
1539
|
qualityGuard: z.ZodDefault<z.ZodBoolean>;
|
|
1540
|
+
gapAudit: z.ZodDefault<z.ZodBoolean>;
|
|
1540
1541
|
model: z.ZodOptional<z.ZodString>;
|
|
1541
1542
|
minToolResultKeepChars: z.ZodDefault<z.ZodNumber>;
|
|
1542
1543
|
maxActiveTranscriptBytes: z.ZodDefault<z.ZodNumber>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { init_agent_scope, listAgentEntries, normalizeAgentId, resolveAgentDir, resolveAgentProfileDir, resolveAgentWorkspaceDir, resolveDefaultAgentId, resolveUserPath, validateAgentIdForNewAgent } from "../agent/agent-scope.js";
|
|
2
1
|
import { resolveCapabilityPresetLayer, resolveEffectiveAgentManifest } from "../agent-manifest/resolver.js";
|
|
2
|
+
import { init_agent_scope, listAgentEntries, normalizeAgentId, resolveAgentDir, resolveAgentProfileDir, resolveAgentWorkspaceDir, resolveDefaultAgentId, resolveUserPath, validateAgentIdForNewAgent } from "../agent/agent-scope.js";
|
|
3
3
|
import { resolveEffectiveAgentProfile } from "../config/agent-profile.js";
|
|
4
4
|
import { WORKSPACE_FILES, init_paths } from "../config/paths.js";
|
|
5
5
|
import { AGENT_PROFILE_MARKDOWN_SYSTEM_FILES, REQUIRED_AGENT_PROFILE_MARKDOWN_FILE_SET } from "../agent/context/workspace.js";
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { PrepareAutomationAgentSessionInput } from '../automations/index.js';
|
|
2
|
+
import type { ProjectService } from '../projects/index.js';
|
|
3
|
+
import type { SessionStore } from '../session/index.js';
|
|
4
|
+
export declare function prepareAutomationAgentSession(store: SessionStore, projects: ProjectService, input: PrepareAutomationAgentSessionInput): Promise<void>;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
//#region src/gateway/automation-agent-session.ts
|
|
2
|
+
async function prepareAutomationAgentSession(store, projects, input) {
|
|
3
|
+
await store.resolveTranscriptPath(input.sessionKey, { metadata: {
|
|
4
|
+
projectId: input.projectId,
|
|
5
|
+
sourceChannel: "automation",
|
|
6
|
+
sourceChatId: `default:dm:${input.peerId}`,
|
|
7
|
+
sessionType: "chat",
|
|
8
|
+
routing: {
|
|
9
|
+
agentId: input.agentId,
|
|
10
|
+
source: "automation",
|
|
11
|
+
accountId: "default",
|
|
12
|
+
peerKind: "dm",
|
|
13
|
+
peerId: input.peerId
|
|
14
|
+
}
|
|
15
|
+
} });
|
|
16
|
+
const current = await store.getMetadata(input.sessionKey);
|
|
17
|
+
await store.updateMetadata(input.sessionKey, {
|
|
18
|
+
sourceChannel: "automation",
|
|
19
|
+
sourceChatId: `default:dm:${input.peerId}`,
|
|
20
|
+
sessionType: "chat",
|
|
21
|
+
routing: {
|
|
22
|
+
agentId: input.agentId,
|
|
23
|
+
source: "automation",
|
|
24
|
+
accountId: "default",
|
|
25
|
+
peerKind: "dm",
|
|
26
|
+
peerId: input.peerId
|
|
27
|
+
},
|
|
28
|
+
tags: [...new Set([...current?.tags ?? [], "automation"])],
|
|
29
|
+
customData: {
|
|
30
|
+
...current?.customData ?? {},
|
|
31
|
+
origin: "automation",
|
|
32
|
+
automationId: input.automationId,
|
|
33
|
+
latestAutomationRunId: input.runId
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
if (input.projectId) projects.attachSession(input.sessionKey, input.projectId);
|
|
37
|
+
else if (current?.projectId) projects.detachSession(input.sessionKey);
|
|
38
|
+
}
|
|
39
|
+
//#endregion
|
|
40
|
+
export { prepareAutomationAgentSession };
|
|
@@ -41,7 +41,8 @@ async function reconcileDreamingAutomations(params) {
|
|
|
41
41
|
trigger,
|
|
42
42
|
action,
|
|
43
43
|
safety: { mode: "auto_apply" },
|
|
44
|
-
|
|
44
|
+
conversationMode: "continuous",
|
|
45
|
+
notificationPolicy: "none",
|
|
45
46
|
reliability: { disableAfterConsecutiveFailures: 3 }
|
|
46
47
|
};
|
|
47
48
|
if (!current) {
|
|
@@ -52,7 +53,7 @@ async function reconcileDreamingAutomations(params) {
|
|
|
52
53
|
result.created = true;
|
|
53
54
|
return result;
|
|
54
55
|
}
|
|
55
|
-
if (current.name !== next.name || current.description !== next.description || !current.enabled || JSON.stringify(current.trigger) !== JSON.stringify(trigger) || JSON.stringify(current.action) !== JSON.stringify(action) || current.safety?.mode !== "auto_apply" || current.
|
|
56
|
+
if (current.name !== next.name || current.description !== next.description || !current.enabled || JSON.stringify(current.trigger) !== JSON.stringify(trigger) || JSON.stringify(current.action) !== JSON.stringify(action) || current.safety?.mode !== "auto_apply" || current.conversationMode !== "continuous" || current.notificationPolicy !== "none" || current.reliability?.disableAfterConsecutiveFailures !== 3) {
|
|
56
57
|
await params.automationService.update(USER_CONTEXT_CONSOLIDATION_AUTOMATION_ID, next);
|
|
57
58
|
result.updated = true;
|
|
58
59
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { createLogger } from "../../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../../utils/logger.js";
|
|
3
3
|
import { shouldSilence, stripHeartbeatToken } from "../../heartbeat/tokens.js";
|
|
4
|
+
import { appendCronEventLines } from "../../heartbeat/event-prompt.js";
|
|
4
5
|
import { isWithinActiveHours } from "../../heartbeat/active-hours.js";
|
|
5
6
|
import { isHeartbeatContentEmpty } from "../../heartbeat/content-check.js";
|
|
6
|
-
import { appendCronEventLines } from "../../heartbeat/event-prompt.js";
|
|
7
7
|
import { createHeartbeatWake } from "../../heartbeat/wake.js";
|
|
8
8
|
import { resolveHeartbeatMdPath } from "../workspace-heartbeat-path.js";
|
|
9
9
|
import { readFile } from "fs/promises";
|
|
@@ -320,6 +320,7 @@ export declare function buildSafeWebConfigPayload(service: GatewayService, optio
|
|
|
320
320
|
summaryTimeoutMs: number;
|
|
321
321
|
summaryRetries: number;
|
|
322
322
|
qualityGuard: boolean;
|
|
323
|
+
gapAudit: boolean;
|
|
323
324
|
minToolResultKeepChars: number;
|
|
324
325
|
maxActiveTranscriptBytes: number;
|
|
325
326
|
postCompactionSections: string[];
|
|
@@ -74,9 +74,43 @@ function registerCommandsSkillsRoutes(authenticated, deps) {
|
|
|
74
74
|
}, 400);
|
|
75
75
|
}
|
|
76
76
|
});
|
|
77
|
-
authenticated.get("/api/chat/skills", (c) => {
|
|
77
|
+
authenticated.get("/api/chat/skills", async (c) => {
|
|
78
|
+
const sessionKey = c.req.query("sessionKey")?.trim();
|
|
78
79
|
const agentId = c.req.query("agentId")?.trim() || service.getConfig().agents?.default || "main";
|
|
79
|
-
const payload = service.marketplace.getAgentSkillsApi(agentId);
|
|
80
|
+
const payload = sessionKey ? await service.marketplace.getSessionSkillsApi(sessionKey) : service.marketplace.getAgentSkillsApi(agentId);
|
|
81
|
+
return c.json({
|
|
82
|
+
ok: true,
|
|
83
|
+
payload
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
authenticated.get("/api/chat/workspace-trust", async (c) => {
|
|
87
|
+
const sessionKey = c.req.query("sessionKey")?.trim();
|
|
88
|
+
if (!sessionKey) return c.json({
|
|
89
|
+
ok: false,
|
|
90
|
+
error: "Missing sessionKey"
|
|
91
|
+
}, 400);
|
|
92
|
+
const payload = await service.marketplace.getSessionWorkspaceTrustApi(sessionKey);
|
|
93
|
+
return c.json({
|
|
94
|
+
ok: true,
|
|
95
|
+
payload
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
authenticated.patch("/api/chat/workspace-trust", async (c) => {
|
|
99
|
+
let body;
|
|
100
|
+
try {
|
|
101
|
+
body = await c.req.json();
|
|
102
|
+
} catch {
|
|
103
|
+
return c.json({
|
|
104
|
+
ok: false,
|
|
105
|
+
error: "Invalid JSON"
|
|
106
|
+
}, 400);
|
|
107
|
+
}
|
|
108
|
+
const sessionKey = typeof body.sessionKey === "string" ? body.sessionKey.trim() : "";
|
|
109
|
+
if (!sessionKey || typeof body.trusted !== "boolean") return c.json({
|
|
110
|
+
ok: false,
|
|
111
|
+
error: "Expected { sessionKey: string, trusted: boolean }"
|
|
112
|
+
}, 400);
|
|
113
|
+
const payload = await service.marketplace.setSessionWorkspaceTrustApi(sessionKey, body.trusted);
|
|
80
114
|
return c.json({
|
|
81
115
|
ok: true,
|
|
82
116
|
payload
|
|
@@ -2,7 +2,7 @@ import type { Config } from '../../config/schema.js';
|
|
|
2
2
|
import type { AgentService } from '../../agent/service.js';
|
|
3
3
|
import type { ChannelManager } from '../../channels/manager.js';
|
|
4
4
|
import type { ExtensionLoader } from '../../extensions/loader.js';
|
|
5
|
-
import type { AgentSkillAvailabilityEntry, AgentSkillAvailabilityPayload, SkillCatalogEntry, SkillCatalogRuntimeMeta } from '../../agent/agent-manager.js';
|
|
5
|
+
import type { AgentSkillAvailabilityEntry, AgentSkillAvailabilityPayload, SkillCatalogEntry, SkillCatalogRuntimeMeta, WorkspaceTrustState } from '../../agent/agent-manager.js';
|
|
6
6
|
import type { ManagedSkillListItem } from '../../agent/skills/managed-store.js';
|
|
7
7
|
import type { SkillMarkdownPreviewPayload } from '../../agent/skills/types.js';
|
|
8
8
|
import type { MarketplaceCategoryOption, SkillsStoreListParams, UnifiedMarketplaceListResponse, UnifiedMarketplacePackageDetail } from '../../agent/skills/skills-marketplace.js';
|
|
@@ -73,6 +73,9 @@ export declare class GatewayMarketplaceService {
|
|
|
73
73
|
} & SkillCatalogRuntimeMeta;
|
|
74
74
|
getSkillsStatusApi(): SkillCatalogRuntimeMeta;
|
|
75
75
|
getAgentSkillsApi(agentId: string): AgentSkillAvailabilityPayload;
|
|
76
|
+
getSessionSkillsApi(sessionKey: string): Promise<AgentSkillAvailabilityPayload>;
|
|
77
|
+
getSessionWorkspaceTrustApi(sessionKey: string): Promise<WorkspaceTrustState>;
|
|
78
|
+
setSessionWorkspaceTrustApi(sessionKey: string, trusted: boolean): Promise<WorkspaceTrustState>;
|
|
76
79
|
getSkillMarkdownSource(skillName: string): SkillMarkdownPreviewPayload | null;
|
|
77
80
|
deleteSkill(skillId: string, target?: SkillInstallTarget): void;
|
|
78
81
|
installSkillZip(buffer: Buffer, opts: {
|
|
@@ -68,6 +68,15 @@ var GatewayMarketplaceService = class {
|
|
|
68
68
|
getAgentSkillsApi(agentId) {
|
|
69
69
|
return this.opts.getAgentService().getAgentSkillAvailability(agentId);
|
|
70
70
|
}
|
|
71
|
+
getSessionSkillsApi(sessionKey) {
|
|
72
|
+
return this.opts.getAgentService().getSessionSkillAvailability(sessionKey);
|
|
73
|
+
}
|
|
74
|
+
getSessionWorkspaceTrustApi(sessionKey) {
|
|
75
|
+
return this.opts.getAgentService().getSessionWorkspaceTrust(sessionKey);
|
|
76
|
+
}
|
|
77
|
+
setSessionWorkspaceTrustApi(sessionKey, trusted) {
|
|
78
|
+
return this.opts.getAgentService().setSessionWorkspaceTrust(sessionKey, trusted);
|
|
79
|
+
}
|
|
71
80
|
getSkillMarkdownSource(skillName) {
|
|
72
81
|
return this.opts.getAgentService().getSkillMarkdownSource(skillName);
|
|
73
82
|
}
|
|
@@ -187,11 +187,11 @@ async function* runGatewayAgent(deps, message, channel, chatId, origin, attachme
|
|
|
187
187
|
skipTaskReview: reviewHint?.skipTaskReview ?? false,
|
|
188
188
|
outboundMetadata: {}
|
|
189
189
|
});
|
|
190
|
-
} catch (
|
|
190
|
+
} catch (completionErr) {
|
|
191
191
|
log.warn({
|
|
192
|
-
err:
|
|
192
|
+
err: completionErr,
|
|
193
193
|
sessionKey
|
|
194
|
-
}, `Session turn complete failed: ${
|
|
194
|
+
}, `Session turn complete failed: ${completionErr instanceof Error ? completionErr.message : String(completionErr)}`);
|
|
195
195
|
}
|
|
196
196
|
agentService.endInboundTurn(sessionKey);
|
|
197
197
|
}
|
|
@@ -69,6 +69,7 @@ import "../discussions/index.js";
|
|
|
69
69
|
import { EndpointToolRuntime } from "../endpoint-tools/runtime.js";
|
|
70
70
|
import "../endpoint-tools/index.js";
|
|
71
71
|
import { assertGatewayAuthConfigured, extractToken, resolveGatewayAuth, validateToken } from "./auth.js";
|
|
72
|
+
import { prepareAutomationAgentSession } from "./automation-agent-session.js";
|
|
72
73
|
import { reconcileDreamingAutomations } from "./dreaming-automation-reconciler.js";
|
|
73
74
|
import { NotesStore } from "../notes/store.js";
|
|
74
75
|
import { buildNoteAgentContext } from "../notes/agent-context.js";
|
|
@@ -495,7 +496,7 @@ var GatewayService = class {
|
|
|
495
496
|
this.automationService.setDeps({
|
|
496
497
|
agentService: this._agentService,
|
|
497
498
|
getDefaultAgentId: () => getDefaultAgentId(this.config),
|
|
498
|
-
|
|
499
|
+
prepareAgentSession: (input) => prepareAutomationAgentSession(this.sessionIndex.getStore(), this.projects, input),
|
|
499
500
|
workflowRunService: this.createWorkflowRunService(),
|
|
500
501
|
browserRecipeService: this.browserRecipes,
|
|
501
502
|
executeTaskCommand: ({ taskId, idempotencyKey, command }) => {
|
|
@@ -865,6 +866,7 @@ var GatewayService = class {
|
|
|
865
866
|
this.automationService.setDeps({
|
|
866
867
|
agentService: this.agentService,
|
|
867
868
|
getDefaultAgentId: () => getDefaultAgentId(this.config),
|
|
869
|
+
prepareAgentSession: (input) => prepareAutomationAgentSession(this.sessionIndex.getStore(), this.projects, input),
|
|
868
870
|
workflowRunService: this.createWorkflowRunService(),
|
|
869
871
|
browserRecipeService: this.browserRecipes,
|
|
870
872
|
executeTaskCommand: ({ taskId, idempotencyKey, command }) => {
|
|
@@ -1502,7 +1504,22 @@ var GatewayService = class {
|
|
|
1502
1504
|
this.createMobileNotificationService().handleGatewayEvent(type, payload);
|
|
1503
1505
|
}
|
|
1504
1506
|
handleAutomationRunCompleted(run) {
|
|
1505
|
-
this.
|
|
1507
|
+
this.automationService.get(run.automationId).then((automation) => {
|
|
1508
|
+
if (!automation) return;
|
|
1509
|
+
const requiresAttention = run.status !== "succeeded" || (automation.safety?.mode ?? "auto_apply") !== "auto_apply";
|
|
1510
|
+
this.emit("automation.run.completed", {
|
|
1511
|
+
run,
|
|
1512
|
+
notificationPolicy: automation.notificationPolicy,
|
|
1513
|
+
requiresAttention,
|
|
1514
|
+
projectId: automation.projectId
|
|
1515
|
+
});
|
|
1516
|
+
}).catch((err) => {
|
|
1517
|
+
log.warn({
|
|
1518
|
+
err,
|
|
1519
|
+
automationId: run.automationId,
|
|
1520
|
+
runId: run.id
|
|
1521
|
+
}, "Automation completion event failed");
|
|
1522
|
+
});
|
|
1506
1523
|
}
|
|
1507
1524
|
startAutomationProductEventBridge() {
|
|
1508
1525
|
this.stopAutomationProductEventBridge?.();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DEFAULT_ACK_MAX_CHARS, HEARTBEAT_OK, NO_REPLY, shouldSilence, stripHeartbeatToken } from "./tokens.js";
|
|
2
|
+
import { appendCronEventLines } from "./event-prompt.js";
|
|
2
3
|
import { isWithinActiveHours } from "./active-hours.js";
|
|
3
4
|
import { isHeartbeatContentEmpty } from "./content-check.js";
|
|
4
|
-
import { appendCronEventLines } from "./event-prompt.js";
|
|
5
5
|
import { createHeartbeatWake } from "./wake.js";
|
|
6
6
|
export { DEFAULT_ACK_MAX_CHARS, HEARTBEAT_OK, NO_REPLY, appendCronEventLines, createHeartbeatWake, isHeartbeatContentEmpty, isWithinActiveHours, shouldSilence, stripHeartbeatToken };
|
|
@@ -40,10 +40,13 @@ function taskEvent(payload) {
|
|
|
40
40
|
}
|
|
41
41
|
function automationEvent(payload) {
|
|
42
42
|
if (!payload || typeof payload !== "object") return null;
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
const event = payload;
|
|
44
|
+
if (event.notificationPolicy === "none") return null;
|
|
45
|
+
if (event.notificationPolicy === "attention" && event.requiresAttention !== true) return null;
|
|
46
|
+
const run = event.run;
|
|
45
47
|
if (!run || run.status !== "failed" && run.status !== "timeout" && run.status !== "succeeded") return null;
|
|
46
48
|
const type = run.status === "succeeded" ? "automation.completed" : "automation.failed";
|
|
49
|
+
const route = `/automations?automation=${encodeURIComponent(run.automationId)}&run=${encodeURIComponent(run.id)}`;
|
|
47
50
|
return {
|
|
48
51
|
type,
|
|
49
52
|
entity: {
|
|
@@ -53,9 +56,9 @@ function automationEvent(payload) {
|
|
|
53
56
|
priority: type === "automation.failed" ? "high" : "normal",
|
|
54
57
|
title: type === "automation.failed" ? "Automation failed" : "Automation completed",
|
|
55
58
|
body: run.automationName.slice(0, 120),
|
|
56
|
-
deepLink:
|
|
59
|
+
deepLink: route,
|
|
57
60
|
payload: {
|
|
58
|
-
route
|
|
61
|
+
route,
|
|
59
62
|
automationId: run.automationId,
|
|
60
63
|
runId: run.id,
|
|
61
64
|
eventType: type
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export declare const HANDOVER_ITEM_KINDS: readonly ["objective", "decision", "pending_user_ask", "todo", "constraint", "file_change", "tool_outcome", "failure", "current_state", "next_action"];
|
|
2
|
+
export type HandoverItemKind = typeof HANDOVER_ITEM_KINDS[number];
|
|
3
|
+
export type HandoverItemStatus = 'active' | 'completed' | 'superseded';
|
|
4
|
+
export interface CompactionSourceRef {
|
|
5
|
+
entryId: string;
|
|
6
|
+
seq: number;
|
|
7
|
+
}
|
|
8
|
+
export interface CompactionHandoverItem {
|
|
9
|
+
id: string;
|
|
10
|
+
kind: HandoverItemKind;
|
|
11
|
+
text: string;
|
|
12
|
+
status: HandoverItemStatus;
|
|
13
|
+
sources: CompactionSourceRef[];
|
|
14
|
+
identifiers: string[];
|
|
15
|
+
}
|
|
16
|
+
export interface CompactionHandover {
|
|
17
|
+
version: 1;
|
|
18
|
+
sourceThroughSeq: number;
|
|
19
|
+
previousBoundaryId?: string;
|
|
20
|
+
items: CompactionHandoverItem[];
|
|
21
|
+
}
|
|
22
|
+
export interface CompactionAudit {
|
|
23
|
+
status: 'passed' | 'degraded' | 'disabled';
|
|
24
|
+
mode: 'structural' | 'risk' | 'full';
|
|
25
|
+
missingItemsFound: number;
|
|
26
|
+
repaired: boolean;
|
|
27
|
+
auditModelRef?: string;
|
|
28
|
+
}
|
|
29
|
+
export declare function isCompactionHandover(value: unknown): value is CompactionHandover;
|
|
30
|
+
export declare function isCompactionAudit(value: unknown): value is CompactionAudit;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
//#region src/session/compaction-types.ts
|
|
2
|
+
const HANDOVER_ITEM_KINDS = [
|
|
3
|
+
"objective",
|
|
4
|
+
"decision",
|
|
5
|
+
"pending_user_ask",
|
|
6
|
+
"todo",
|
|
7
|
+
"constraint",
|
|
8
|
+
"file_change",
|
|
9
|
+
"tool_outcome",
|
|
10
|
+
"failure",
|
|
11
|
+
"current_state",
|
|
12
|
+
"next_action"
|
|
13
|
+
];
|
|
14
|
+
function isCompactionHandover(value) {
|
|
15
|
+
if (!value || typeof value !== "object") return false;
|
|
16
|
+
const handover = value;
|
|
17
|
+
const sourceThroughSeq = Number(handover.sourceThroughSeq);
|
|
18
|
+
if (handover.version !== 1 || !Number.isInteger(handover.sourceThroughSeq) || sourceThroughSeq < 0 || handover.previousBoundaryId !== void 0 && typeof handover.previousBoundaryId !== "string" || !Array.isArray(handover.items)) return false;
|
|
19
|
+
return handover.items.every((item) => {
|
|
20
|
+
if (!item || typeof item !== "object") return false;
|
|
21
|
+
const record = item;
|
|
22
|
+
return typeof record.id === "string" && record.id.length > 0 && HANDOVER_ITEM_KINDS.includes(record.kind) && typeof record.text === "string" && record.text.length > 0 && (record.status === "active" || record.status === "completed" || record.status === "superseded") && Array.isArray(record.sources) && record.sources.length > 0 && record.sources.every((source) => {
|
|
23
|
+
if (!source || typeof source !== "object") return false;
|
|
24
|
+
const ref = source;
|
|
25
|
+
return typeof ref.entryId === "string" && ref.entryId.length > 0 && Number.isInteger(ref.seq) && Number(ref.seq) > 0 && Number(ref.seq) <= sourceThroughSeq;
|
|
26
|
+
}) && Array.isArray(record.identifiers) && record.identifiers.every((identifier) => typeof identifier === "string");
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
function isCompactionAudit(value) {
|
|
30
|
+
if (!value || typeof value !== "object") return false;
|
|
31
|
+
const audit = value;
|
|
32
|
+
return (audit.status === "passed" || audit.status === "degraded" || audit.status === "disabled") && (audit.mode === "structural" || audit.mode === "risk" || audit.mode === "full") && Number.isInteger(audit.missingItemsFound) && typeof audit.repaired === "boolean" && (audit.auditModelRef === void 0 || typeof audit.auditModelRef === "string");
|
|
33
|
+
}
|
|
34
|
+
//#endregion
|
|
35
|
+
export { HANDOVER_ITEM_KINDS, isCompactionAudit, isCompactionHandover };
|
|
@@ -185,6 +185,9 @@ export declare class SessionIndex extends EventEmitter {
|
|
|
185
185
|
compactionCount: number;
|
|
186
186
|
totalTokensBefore: number;
|
|
187
187
|
totalTokensAfter: number;
|
|
188
|
+
auditPassedCount: number;
|
|
189
|
+
auditDegradedCount: number;
|
|
190
|
+
auditMissingItemsFound: number;
|
|
188
191
|
lastCompactionAt: string;
|
|
189
192
|
}>;
|
|
190
193
|
listCompactionBoundaries(key: string): Promise<import("./types.js").CompactionBoundarySummary[]>;
|