@xopcai/xopc 0.0.159 → 0.0.160
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{action-boundary-settings-panel-CaRK2vIy.js → action-boundary-settings-panel-CY3sizqC.js} +1 -1
- package/dist/gateway/static/root/assets/{activity-store-C-57rvkX.js → activity-store-3Cso_2qm.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-BeVf03hx.js → agent-avatar-dicebear-B_27aaZQ.js} +1 -1
- package/dist/gateway/static/root/assets/agents-B1l3iii6.js +2 -0
- package/dist/gateway/static/root/assets/{api-BjcBIV2O.js → api-BbzB57CJ.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-BG2ulMYw.js → app-management-settings-panel-DfmyWcyh.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-0Kjenr2T.js → appearance-settings-B2v0c-K-.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-DaNFLsp0.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-ChiNnH1e.js → archive-plugin-DL5Lnx0C.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-pbBlQR-g.js → attachment-load-InuP-ZjQ.js} +1 -1
- package/dist/gateway/static/root/assets/{automation-suggestion-card-CTZDOyDy.js → automation-suggestion-card-CahGuh7B.js} +1 -1
- package/dist/gateway/static/root/assets/automations-page-Cd0gMx6p.js +6 -0
- package/dist/gateway/static/root/assets/{binary-plugins-BeZGzpGF.js → binary-plugins-CdOTGYVu.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-BnDmhN5Z.js → block-editor-D6ShK1S-.js} +3 -3
- package/dist/gateway/static/root/assets/browser-settings-page-BmUYDL2Z.js +8 -0
- package/dist/gateway/static/root/assets/{capability-presets-api-Ii36j_7v.js → capability-presets-api-BzoLm52Z.js} +1 -1
- package/dist/gateway/static/root/assets/{capability-presets-settings-panel-Cl3dw4yh.js → capability-presets-settings-panel-CE7mrWtS.js} +2 -2
- package/dist/gateway/static/root/assets/{channel-recipient-api-CFqrSi5K.js → channel-recipient-api-DbgydMjl.js} +1 -1
- package/dist/gateway/static/root/assets/channels-settings-D1_gcAHK.js +1 -0
- package/dist/gateway/static/root/assets/channels-status-swr-Cqfqv59m.js +1 -0
- package/dist/gateway/static/root/assets/{connector-logo-CiLxuZ8S.js → connector-logo-C3bJC9nt.js} +1 -1
- package/dist/gateway/static/root/assets/connectors-page-CaLBi6Na.js +2 -0
- package/dist/gateway/static/root/assets/desktop-pet-settings-BrHVvbBw.js +1 -0
- package/dist/gateway/static/root/assets/desktop-pet-sprite-CFd1jGLJ.js +1 -0
- package/dist/gateway/static/root/assets/desktop-pet-wacrnJJ1.js +1 -0
- package/dist/gateway/static/root/assets/{directory-picker-path-field-CC2VL5Mc.js → directory-picker-path-field-BPI969w-.js} +1 -1
- package/dist/gateway/static/root/assets/{dreaming-settings-KY7ZfVsy.js → dreaming-settings-iw6QXD45.js} +3 -3
- package/dist/gateway/static/root/assets/{extension-debug-page-C8KBeucs.js → extension-debug-page-rCHyhEr6.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-CV-5Kcyk.js → extension-page-C4gQsAPt.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-DvUtDrAu.js → extension-settings-page-DB_3eik7.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-api-DXfVeJLc.js → gateway-config-api-Cdt38iF2.js} +1 -1
- package/dist/gateway/static/root/assets/gateway-settings-DM4BgyGw.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-startup-retry-cxQ94qMm.js → gateway-startup-retry-ChRFNjj_.js} +1 -1
- package/dist/gateway/static/root/assets/goal-create-dialog-BQamcEmF.js +1 -0
- package/dist/gateway/static/root/assets/goal-detail-page-DZUQ0Lf1.js +4 -0
- package/dist/gateway/static/root/assets/{goals-config-api-P8VhLqYF.js → goals-config-api-RvljeEm6.js} +1 -1
- package/dist/gateway/static/root/assets/goals-page-BtxVD27C.js +2 -0
- package/dist/gateway/static/root/assets/{goals-settings-DHXyaH_O.js → goals-settings-DMGV4S4L.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-settings-CNckP_Dv.js → heartbeat-settings-B8r5EXc5.js} +1 -1
- package/dist/gateway/static/root/assets/index-CHKe7nwC.js +197 -0
- package/dist/gateway/static/root/assets/index-CXhfUIjh.css +1 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-jXmv1RVX.js → keyboard-shortcuts-settings-1-LYibQ4.js} +1 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-CTTfyFe3.js +2 -0
- package/dist/gateway/static/root/assets/{local-apps-page-Cs5LKjtc.js → local-apps-page-CC4vtUUI.js} +1 -1
- package/dist/gateway/static/root/assets/{locale-store-C_M71MK9.js → locale-store-CPbGB_6l.js} +1 -1
- package/dist/gateway/static/root/assets/logs-page-Bn_taxBV.js +7 -0
- package/dist/gateway/static/root/assets/{markdown-split-BFqeSNte.js → markdown-split-CprEIf8A.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-Cc8379gq.js → media-plugins-BXt_Sj2O.js} +1 -1
- package/dist/gateway/static/root/assets/{messages-BuT0SR1R.js → messages-DDsiqdJS.js} +4 -4
- package/dist/gateway/static/root/assets/models-hub-panel-DJReXRP9.js +2 -0
- package/dist/gateway/static/root/assets/{notes-page-DlGU4ipo.js → notes-page-Wf5-eyyM.js} +1 -1
- package/dist/gateway/static/root/assets/notes-workbench-BbdjzYzs.js +4 -0
- package/dist/gateway/static/root/assets/{page-tabs-kFOswGlG.js → page-tabs-dtpK_4Fs.js} +1 -1
- package/dist/gateway/static/root/assets/{preview-open-alternatives-CvjuvABg.js → preview-open-alternatives-DijtEVxG.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-BwG8SOzI.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-nUlyUtxh.js +1 -0
- package/dist/gateway/static/root/assets/remote-access-hub-rf7bjije.js +1 -0
- package/dist/gateway/static/root/assets/{save-bar-controls-DwrD7ODx.js → save-bar-controls-qhDisdqY.js} +1 -1
- package/dist/gateway/static/root/assets/{schedule-field-Ba4WzTmE.js → schedule-field-AhJ50NoT.js} +1 -1
- package/dist/gateway/static/root/assets/{schema-form-DvydL8eF.js → schema-form-AuJg2CXU.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-CSoHUe38.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-Db976IEa.js +1 -0
- package/dist/gateway/static/root/assets/{settings-collapsible-section-LaQqGGej.js → settings-collapsible-section-D5ganr_X.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-form-section-DruI__qO.js → settings-form-section-Db3cKRsg.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-loading-skeleton-UvA-eDhF.js → settings-loading-skeleton-D05YKT2x.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-5oCGSebm.js → settings-page-DYfXmfTx.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-layout-DG-XMIPu.js → settings-page-layout-Cv_Cu4I5.js} +1 -1
- package/dist/gateway/static/root/assets/setup-status-panel-wBWOFpvw.js +1 -0
- package/dist/gateway/static/root/assets/{share-preview-page-FLVeTrRt.js → share-preview-page-CYkZVuse.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-BAMma1-P.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-TWxFFWxM.js +1 -0
- package/dist/gateway/static/root/assets/skills-page-Ca2RA29R.js +2 -0
- package/dist/gateway/static/root/assets/{system-settings-panel-CeK93xVi.js → system-settings-panel-C1Ng5bXh.js} +1 -1
- package/dist/gateway/static/root/assets/{theme-store-C8ohIHhw.js → theme-store-LMHIDR9n.js} +1 -1
- package/dist/gateway/static/root/assets/{typed-models-lib-D1Lr2gG0.js → typed-models-lib-Ch2Bdm_5.js} +1 -1
- package/dist/gateway/static/root/assets/{use-channel-catalog-BWzou5ar.js → use-channel-catalog-CZnaMOeL.js} +1 -1
- package/dist/gateway/static/root/assets/user-context-page-CTumZa0y.js +1 -0
- package/dist/gateway/static/root/assets/voice-api-key-field-DdlMxeqO.js +1 -0
- package/dist/gateway/static/root/assets/work-discovery-page-CcfZhdBi.js +1 -0
- package/dist/gateway/static/root/assets/work-item-detail-page--wxLw1p_.js +1 -0
- package/dist/gateway/static/root/assets/work-page-DyS0XBpV.js +1 -0
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-Bynqe4kV.js → workflow-run-setup-panel-BFk8TvTw.js} +2 -2
- package/dist/gateway/static/root/assets/workflows-page-CVVJd4gy.js +11 -0
- package/dist/gateway/static/root/index.html +7 -7
- package/dist/package.js +1 -1
- package/dist/src/automations/service/action-executor.js +1 -1
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/gateway/chat-stream/mapper.d.ts +1 -0
- package/dist/src/gateway/chat-stream/mapper.js +43 -7
- package/dist/src/gateway/hono/routes/home.js +15 -2
- package/dist/src/gateway/hono/routes/work-discovery.js +451 -0
- package/dist/src/gateway/service.d.ts +2 -0
- package/dist/src/gateway/service.js +27 -2
- package/dist/src/mobile/notification-service.js +1 -0
- package/dist/src/pets/factory.js +23 -26
- package/dist/src/pets/manifest.d.ts +2 -1
- package/dist/src/pets/manifest.js +15 -8
- package/dist/src/pets/validator.js +8 -3
- package/dist/src/proactive/calendar-signals.d.ts +4 -0
- package/dist/src/proactive/calendar-signals.js +120 -0
- package/dist/src/proactive/focus-service.d.ts +62 -0
- package/dist/src/proactive/focus-service.js +173 -0
- package/dist/src/proactive/index.d.ts +7 -0
- package/dist/src/proactive/index.js +7 -0
- package/dist/src/proactive/insight-repository.d.ts +19 -0
- package/dist/src/proactive/insight-repository.js +106 -0
- package/dist/src/proactive/run-processor.d.ts +19 -0
- package/dist/src/proactive/run-processor.js +125 -0
- package/dist/src/proactive/trial-expiry-reconciler.d.ts +5 -0
- package/dist/src/proactive/trial-expiry-reconciler.js +30 -0
- package/dist/src/proactive/types.d.ts +64 -0
- package/dist/src/proactive/types.js +1 -0
- package/dist/src/proactive/watch-repository.d.ts +28 -0
- package/dist/src/proactive/watch-repository.js +129 -0
- package/dist/src/storage/sqlite/knowledge-repository.d.ts +1 -0
- package/dist/src/storage/sqlite/knowledge-repository.js +4 -0
- package/dist/src/storage/sqlite/migrations/047_work_discovery_sources.sql +16 -0
- package/dist/src/storage/sqlite/migrations/048_work_understanding_investigations.sql +40 -0
- package/dist/src/storage/sqlite/migrations/049_work_understanding_threads.sql +52 -0
- package/dist/src/storage/sqlite/migrations/050_work_discovery_source_refreshes.sql +15 -0
- package/dist/src/storage/sqlite/migrations/051_focus_watches.sql +26 -0
- package/dist/src/storage/sqlite/migrations/052_proactive_insights.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/work-discovery/analyzer.d.ts +12 -1
- package/dist/src/work-discovery/analyzer.js +126 -7
- package/dist/src/work-discovery/candidate-discovery.d.ts +17 -0
- package/dist/src/work-discovery/candidate-discovery.js +279 -0
- package/dist/src/work-discovery/evaluation.d.ts +11 -0
- package/dist/src/work-discovery/evaluation.js +17 -0
- package/dist/src/work-discovery/governance.d.ts +25 -0
- package/dist/src/work-discovery/governance.js +96 -0
- package/dist/src/work-discovery/incremental-repository.d.ts +13 -0
- package/dist/src/work-discovery/incremental-repository.js +55 -0
- package/dist/src/work-discovery/incremental.d.ts +2 -0
- package/dist/src/work-discovery/incremental.js +7 -0
- package/dist/src/work-discovery/index.d.ts +10 -0
- package/dist/src/work-discovery/index.js +13 -3
- package/dist/src/work-discovery/investigation-repository.d.ts +16 -0
- package/dist/src/work-discovery/investigation-repository.js +122 -0
- package/dist/src/work-discovery/investigator.d.ts +55 -0
- package/dist/src/work-discovery/investigator.js +358 -0
- package/dist/src/work-discovery/probe.d.ts +22 -0
- package/dist/src/work-discovery/probe.js +88 -1
- package/dist/src/work-discovery/service.d.ts +110 -1
- package/dist/src/work-discovery/service.js +578 -8
- package/dist/src/work-discovery/source-repository.d.ts +13 -0
- package/dist/src/work-discovery/source-repository.js +72 -0
- package/dist/src/work-discovery/thread-repository.d.ts +34 -0
- package/dist/src/work-discovery/thread-repository.js +112 -0
- package/dist/src/work-discovery/thread-service.d.ts +8 -0
- package/dist/src/work-discovery/thread-service.js +104 -0
- package/dist/src/work-discovery/types.d.ts +145 -0
- package/package.json +1 -1
- package/skills/creative/hatch-pet/SKILL.md +2 -2
- package/dist/gateway/static/root/assets/agents-P05C4A-3.js +0 -2
- package/dist/gateway/static/root/assets/apps-page-DANGrBpN.js +0 -1
- package/dist/gateway/static/root/assets/automations-page-BXfGL_cm.js +0 -6
- package/dist/gateway/static/root/assets/browser-settings-page-534luV0B.js +0 -8
- package/dist/gateway/static/root/assets/channels-settings-M91zFJVi.js +0 -1
- package/dist/gateway/static/root/assets/channels-status-swr-vooEF4lG.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-CV5UulW6.js +0 -2
- package/dist/gateway/static/root/assets/desktop-pet-Cil2eSpW.js +0 -1
- package/dist/gateway/static/root/assets/desktop-pet-settings-DwsC6l5F.js +0 -1
- package/dist/gateway/static/root/assets/desktop-pet-sprite-DqZ6fbIj.js +0 -1
- package/dist/gateway/static/root/assets/gateway-settings-BpJ0v56l.js +0 -1
- package/dist/gateway/static/root/assets/goal-create-dialog-lMHD-2CX.js +0 -1
- package/dist/gateway/static/root/assets/goal-detail-page-yPmF-G7b.js +0 -4
- package/dist/gateway/static/root/assets/goals-page-BHTCKobG.js +0 -2
- package/dist/gateway/static/root/assets/index-BgZhEOkN.css +0 -1
- package/dist/gateway/static/root/assets/index-BuqGh2SW.js +0 -193
- package/dist/gateway/static/root/assets/local-app-workbench-page-zpp_wciE.js +0 -2
- package/dist/gateway/static/root/assets/logs-page-B4CRYqYR.js +0 -7
- package/dist/gateway/static/root/assets/models-hub-panel-1hdoAoB_.js +0 -2
- package/dist/gateway/static/root/assets/notes-workbench-DQEAZTA5.js +0 -4
- package/dist/gateway/static/root/assets/project-detail-page-Bp9bC7A6.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-RNorFXTw.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-BqRTcM_6.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-B2EfW1cm.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-CklL85T4.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-D3my1HgB.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-DVxgjrsP.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-Bcu58ZaF.js +0 -1
- package/dist/gateway/static/root/assets/skills-page-CDd-84FE.js +0 -2
- package/dist/gateway/static/root/assets/sliding-segmented-uWmrxE3P.js +0 -1
- package/dist/gateway/static/root/assets/user-context-page-1OyJnTyR.js +0 -1
- package/dist/gateway/static/root/assets/voice-api-key-field-B2ncRwHS.js +0 -1
- package/dist/gateway/static/root/assets/work-discovery-page-BZlY4PZL.js +0 -1
- package/dist/gateway/static/root/assets/work-item-detail-page-DPXMrneY.js +0 -1
- package/dist/gateway/static/root/assets/work-page-CTERoqyv.js +0 -1
- package/dist/gateway/static/root/assets/workflows-page-CLgsnqFQ.js +0 -11
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { getAgentDefaultModelRef, init_schema } from "../../../config/schema.js";
|
|
2
2
|
import { init_providers, resolveModel } from "../../../providers/index.js";
|
|
3
3
|
import { isLocalModelBaseUrl } from "../../../providers/model-call.js";
|
|
4
|
+
import { listFocusCalendarSignals } from "../../../proactive/calendar-signals.js";
|
|
5
|
+
import { FocusService } from "../../../proactive/focus-service.js";
|
|
6
|
+
import { claimProactiveInsightApproval, getProactiveInsight, setProactiveInsightStatus } from "../../../proactive/insight-repository.js";
|
|
7
|
+
import "../../../proactive/index.js";
|
|
4
8
|
import { previewWorkDiscoveryRoot } from "../../../work-discovery/probe.js";
|
|
5
9
|
import { WorkDiscoveryService } from "../../../work-discovery/service.js";
|
|
6
10
|
//#region src/gateway/hono/routes/work-discovery.ts
|
|
@@ -26,6 +30,7 @@ function stringField(body, field) {
|
|
|
26
30
|
}
|
|
27
31
|
function registerWorkDiscoveryRoutes(authenticated, deps) {
|
|
28
32
|
const service = workDiscoveryService(deps);
|
|
33
|
+
const focuses = new FocusService(deps.service.automationServiceInstance);
|
|
29
34
|
const limited = deps.strictRateLimitMiddleware;
|
|
30
35
|
authenticated.get("/api/onboarding/work-discovery", (c) => c.json({
|
|
31
36
|
enabled: service.isEnabled(),
|
|
@@ -77,6 +82,178 @@ function registerWorkDiscoveryRoutes(authenticated, deps) {
|
|
|
77
82
|
}, 400);
|
|
78
83
|
}
|
|
79
84
|
});
|
|
85
|
+
authenticated.post("/api/work-discovery/candidates", limited, async (c) => {
|
|
86
|
+
if (!service.isEnabled()) return c.json({
|
|
87
|
+
ok: false,
|
|
88
|
+
error: "Work discovery is disabled"
|
|
89
|
+
}, 404);
|
|
90
|
+
try {
|
|
91
|
+
const candidates = await service.discoverCandidates(c.req.raw.signal);
|
|
92
|
+
return c.json({
|
|
93
|
+
ok: true,
|
|
94
|
+
candidates
|
|
95
|
+
});
|
|
96
|
+
} catch (error) {
|
|
97
|
+
return c.json({
|
|
98
|
+
ok: false,
|
|
99
|
+
error: error instanceof Error ? error.message : String(error)
|
|
100
|
+
}, 500);
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
authenticated.get("/api/work-discovery/sources/directories", (c) => c.json({
|
|
104
|
+
ok: true,
|
|
105
|
+
sources: service.listDirectorySources()
|
|
106
|
+
}));
|
|
107
|
+
authenticated.post("/api/work-discovery/sources/directories", limited, async (c) => {
|
|
108
|
+
const rootPath = stringField(await c.req.json().catch(() => null), "rootPath");
|
|
109
|
+
if (!rootPath) return c.json({
|
|
110
|
+
ok: false,
|
|
111
|
+
error: "Missing rootPath"
|
|
112
|
+
}, 400);
|
|
113
|
+
try {
|
|
114
|
+
const source = await service.grantDirectorySource(rootPath);
|
|
115
|
+
return c.json({
|
|
116
|
+
ok: true,
|
|
117
|
+
source
|
|
118
|
+
}, 201);
|
|
119
|
+
} catch (error) {
|
|
120
|
+
return c.json({
|
|
121
|
+
ok: false,
|
|
122
|
+
error: error instanceof Error ? error.message : String(error)
|
|
123
|
+
}, 400);
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
authenticated.delete("/api/work-discovery/sources/directories/:sourceId", limited, (c) => {
|
|
127
|
+
const source = service.revokeDirectorySource(c.req.param("sourceId"));
|
|
128
|
+
return source ? c.json({
|
|
129
|
+
ok: true,
|
|
130
|
+
source
|
|
131
|
+
}) : c.json({
|
|
132
|
+
ok: false,
|
|
133
|
+
error: "Source not found"
|
|
134
|
+
}, 404);
|
|
135
|
+
});
|
|
136
|
+
authenticated.post("/api/work-discovery/sources/directories/:sourceId/runs", limited, async (c) => {
|
|
137
|
+
const idempotencyKey = stringField(await c.req.json().catch(() => null), "idempotencyKey");
|
|
138
|
+
if (!idempotencyKey) return c.json({
|
|
139
|
+
ok: false,
|
|
140
|
+
error: "Missing idempotencyKey"
|
|
141
|
+
}, 400);
|
|
142
|
+
try {
|
|
143
|
+
const run = await service.rescanDirectorySource({
|
|
144
|
+
id: c.req.param("sourceId"),
|
|
145
|
+
idempotencyKey
|
|
146
|
+
});
|
|
147
|
+
return c.json({
|
|
148
|
+
ok: true,
|
|
149
|
+
run
|
|
150
|
+
}, 202);
|
|
151
|
+
} catch (error) {
|
|
152
|
+
return c.json({
|
|
153
|
+
ok: false,
|
|
154
|
+
error: error instanceof Error ? error.message : String(error)
|
|
155
|
+
}, 400);
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
authenticated.post("/api/work-discovery/sources/directories/check", limited, async (c) => {
|
|
159
|
+
return c.json({
|
|
160
|
+
ok: true,
|
|
161
|
+
checks: await service.checkDirectorySources()
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
authenticated.post("/api/work-discovery/sources/directories/:sourceId/refresh-if-changed", limited, async (c) => {
|
|
165
|
+
const idempotencyKey = stringField(await c.req.json().catch(() => null), "idempotencyKey");
|
|
166
|
+
if (!idempotencyKey) return c.json({
|
|
167
|
+
ok: false,
|
|
168
|
+
error: "Missing idempotencyKey"
|
|
169
|
+
}, 400);
|
|
170
|
+
try {
|
|
171
|
+
const result = await service.refreshDirectorySourceIfChanged({
|
|
172
|
+
id: c.req.param("sourceId"),
|
|
173
|
+
idempotencyKey
|
|
174
|
+
});
|
|
175
|
+
return c.json({
|
|
176
|
+
ok: true,
|
|
177
|
+
...result
|
|
178
|
+
}, result.changed ? 202 : 200);
|
|
179
|
+
} catch (error) {
|
|
180
|
+
return c.json({
|
|
181
|
+
ok: false,
|
|
182
|
+
error: error instanceof Error ? error.message : String(error)
|
|
183
|
+
}, 400);
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
authenticated.post("/api/work-discovery/personal-context/import", limited, async (c) => {
|
|
187
|
+
if (!service.isEnabled()) return c.json({
|
|
188
|
+
ok: false,
|
|
189
|
+
error: "Work discovery is disabled"
|
|
190
|
+
}, 404);
|
|
191
|
+
const body = await c.req.json().catch(() => null);
|
|
192
|
+
const items = body && typeof body === "object" && Array.isArray(body.items) ? body.items.slice(0, 150) : [];
|
|
193
|
+
const runId = stringField(body, "runId");
|
|
194
|
+
if (!items.length) return c.json({
|
|
195
|
+
ok: false,
|
|
196
|
+
error: "No personal context was provided"
|
|
197
|
+
}, 400);
|
|
198
|
+
try {
|
|
199
|
+
const result = await service.importPersonalContext(items, c.req.raw.signal, runId || void 0);
|
|
200
|
+
return c.json({
|
|
201
|
+
ok: true,
|
|
202
|
+
...result
|
|
203
|
+
}, 201);
|
|
204
|
+
} catch (error) {
|
|
205
|
+
return c.json({
|
|
206
|
+
ok: false,
|
|
207
|
+
error: error instanceof Error ? error.message : String(error)
|
|
208
|
+
}, 400);
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
authenticated.post("/api/work-discovery/personal-context/profile", limited, async (c) => {
|
|
212
|
+
const body = await c.req.json().catch(() => null);
|
|
213
|
+
const decisions = (body && typeof body === "object" && Array.isArray(body.decisions) ? body.decisions : []).flatMap((value) => {
|
|
214
|
+
if (!value || typeof value !== "object") return [];
|
|
215
|
+
const item = value;
|
|
216
|
+
const memoryRecordId = typeof item.memoryRecordId === "string" ? item.memoryRecordId.trim() : "";
|
|
217
|
+
const status = item.status === "accepted" || item.status === "edited" || item.status === "rejected" ? item.status : void 0;
|
|
218
|
+
if (!memoryRecordId || !status) return [];
|
|
219
|
+
return [{
|
|
220
|
+
memoryRecordId,
|
|
221
|
+
status,
|
|
222
|
+
...typeof item.statement === "string" ? { statement: item.statement } : {}
|
|
223
|
+
}];
|
|
224
|
+
}).slice(0, 10);
|
|
225
|
+
if (!decisions.length) return c.json({
|
|
226
|
+
ok: false,
|
|
227
|
+
error: "At least one valid decision is required"
|
|
228
|
+
}, 400);
|
|
229
|
+
return c.json({
|
|
230
|
+
ok: true,
|
|
231
|
+
decisions: service.updatePersonalContextProfile({ decisions })
|
|
232
|
+
});
|
|
233
|
+
});
|
|
234
|
+
authenticated.post("/api/work-discovery/quick-runs", limited, async (c) => {
|
|
235
|
+
if (!service.isEnabled()) return c.json({
|
|
236
|
+
ok: false,
|
|
237
|
+
error: "Work discovery is disabled"
|
|
238
|
+
}, 404);
|
|
239
|
+
const idempotencyKey = stringField(await c.req.json().catch(() => null), "idempotencyKey");
|
|
240
|
+
if (!idempotencyKey) return c.json({
|
|
241
|
+
ok: false,
|
|
242
|
+
error: "Missing idempotencyKey"
|
|
243
|
+
}, 400);
|
|
244
|
+
try {
|
|
245
|
+
const run = await service.startQuickRun({ idempotencyKey });
|
|
246
|
+
return c.json({
|
|
247
|
+
ok: true,
|
|
248
|
+
run
|
|
249
|
+
}, 202);
|
|
250
|
+
} catch (error) {
|
|
251
|
+
return c.json({
|
|
252
|
+
ok: false,
|
|
253
|
+
error: error instanceof Error ? error.message : String(error)
|
|
254
|
+
}, 400);
|
|
255
|
+
}
|
|
256
|
+
});
|
|
80
257
|
authenticated.post("/api/work-discovery/runs", limited, async (c) => {
|
|
81
258
|
if (!service.isEnabled()) return c.json({
|
|
82
259
|
ok: false,
|
|
@@ -117,6 +294,250 @@ function registerWorkDiscoveryRoutes(authenticated, deps) {
|
|
|
117
294
|
error: "Run not found"
|
|
118
295
|
}, 404);
|
|
119
296
|
});
|
|
297
|
+
authenticated.get("/api/work-discovery/runs/:runId/investigation", (c) => {
|
|
298
|
+
const result = service.getInvestigation(c.req.param("runId"));
|
|
299
|
+
return result ? c.json({
|
|
300
|
+
ok: true,
|
|
301
|
+
...result
|
|
302
|
+
}) : c.json({
|
|
303
|
+
ok: false,
|
|
304
|
+
error: "Investigation not found"
|
|
305
|
+
}, 404);
|
|
306
|
+
});
|
|
307
|
+
authenticated.get("/api/work-understanding/threads", (c) => {
|
|
308
|
+
const projectId = c.req.query("projectId")?.trim();
|
|
309
|
+
const limit = Number(c.req.query("limit"));
|
|
310
|
+
return c.json({
|
|
311
|
+
ok: true,
|
|
312
|
+
threads: service.listWorkThreads({
|
|
313
|
+
...projectId ? { projectId } : {},
|
|
314
|
+
...Number.isFinite(limit) ? { limit } : {}
|
|
315
|
+
})
|
|
316
|
+
});
|
|
317
|
+
});
|
|
318
|
+
authenticated.get("/api/work-understanding/metrics", (c) => c.json({
|
|
319
|
+
ok: true,
|
|
320
|
+
metrics: service.getUnderstandingMetrics()
|
|
321
|
+
}));
|
|
322
|
+
authenticated.get("/api/work-understanding/sources/:sourceId/lineage", (c) => {
|
|
323
|
+
const lineage = service.getSourceLineage(c.req.param("sourceId"));
|
|
324
|
+
return lineage ? c.json({
|
|
325
|
+
ok: true,
|
|
326
|
+
lineage
|
|
327
|
+
}) : c.json({
|
|
328
|
+
ok: false,
|
|
329
|
+
error: "Source not found"
|
|
330
|
+
}, 404);
|
|
331
|
+
});
|
|
332
|
+
authenticated.delete("/api/work-understanding/sources/:sourceId/derived-data", limited, (c) => {
|
|
333
|
+
const deleted = service.deleteSourceDerivedData(c.req.param("sourceId"));
|
|
334
|
+
return deleted ? c.json({
|
|
335
|
+
ok: true,
|
|
336
|
+
deleted
|
|
337
|
+
}) : c.json({
|
|
338
|
+
ok: false,
|
|
339
|
+
error: "Source not found"
|
|
340
|
+
}, 404);
|
|
341
|
+
});
|
|
342
|
+
authenticated.get("/api/work-understanding/threads/:threadId", (c) => {
|
|
343
|
+
const thread = service.getWorkThread(c.req.param("threadId"));
|
|
344
|
+
return thread ? c.json({
|
|
345
|
+
ok: true,
|
|
346
|
+
thread
|
|
347
|
+
}) : c.json({
|
|
348
|
+
ok: false,
|
|
349
|
+
error: "Work thread not found"
|
|
350
|
+
}, 404);
|
|
351
|
+
});
|
|
352
|
+
authenticated.patch("/api/work-understanding/threads/:threadId", limited, async (c) => {
|
|
353
|
+
const body = await c.req.json().catch(() => null);
|
|
354
|
+
const decision = stringField(body, "decision");
|
|
355
|
+
if (![
|
|
356
|
+
"confirmed",
|
|
357
|
+
"corrected",
|
|
358
|
+
"rejected",
|
|
359
|
+
"paused",
|
|
360
|
+
"completed"
|
|
361
|
+
].includes(decision)) return c.json({
|
|
362
|
+
ok: false,
|
|
363
|
+
error: "Invalid work thread decision"
|
|
364
|
+
}, 400);
|
|
365
|
+
const thread = service.updateWorkThread({
|
|
366
|
+
id: c.req.param("threadId"),
|
|
367
|
+
decision,
|
|
368
|
+
...stringField(body, "correctedTitle") ? { correctedTitle: stringField(body, "correctedTitle") } : {},
|
|
369
|
+
...stringField(body, "correctedSummary") ? { correctedSummary: stringField(body, "correctedSummary") } : {}
|
|
370
|
+
});
|
|
371
|
+
return thread ? c.json({
|
|
372
|
+
ok: true,
|
|
373
|
+
thread
|
|
374
|
+
}) : c.json({
|
|
375
|
+
ok: false,
|
|
376
|
+
error: "Work thread not found"
|
|
377
|
+
}, 404);
|
|
378
|
+
});
|
|
379
|
+
authenticated.get("/api/focuses", (c) => {
|
|
380
|
+
return c.json({
|
|
381
|
+
ok: true,
|
|
382
|
+
focuses: focuses.list({ includeUnreviewed: c.req.query("includeUnreviewed") === "true" })
|
|
383
|
+
});
|
|
384
|
+
});
|
|
385
|
+
authenticated.post("/api/focuses/:focusId/confirm", limited, (c) => {
|
|
386
|
+
const focus = focuses.confirm(c.req.param("focusId"));
|
|
387
|
+
return focus ? c.json({
|
|
388
|
+
ok: true,
|
|
389
|
+
focus
|
|
390
|
+
}) : c.json({
|
|
391
|
+
ok: false,
|
|
392
|
+
error: "Focus not found"
|
|
393
|
+
}, 404);
|
|
394
|
+
});
|
|
395
|
+
authenticated.post("/api/focuses/:focusId/watches/trial", limited, async (c) => {
|
|
396
|
+
const requestedKind = stringField(await c.req.json().catch(() => null), "kind");
|
|
397
|
+
const kind = [
|
|
398
|
+
"progress",
|
|
399
|
+
"staleness",
|
|
400
|
+
"deadline",
|
|
401
|
+
"intelligence"
|
|
402
|
+
].includes(requestedKind) ? requestedKind : void 0;
|
|
403
|
+
try {
|
|
404
|
+
const result = await focuses.activateTrial({
|
|
405
|
+
threadId: c.req.param("focusId"),
|
|
406
|
+
...kind ? { kind } : {}
|
|
407
|
+
});
|
|
408
|
+
return c.json({
|
|
409
|
+
ok: true,
|
|
410
|
+
...result
|
|
411
|
+
}, 201);
|
|
412
|
+
} catch (error) {
|
|
413
|
+
return c.json({
|
|
414
|
+
ok: false,
|
|
415
|
+
error: error instanceof Error ? error.message : String(error)
|
|
416
|
+
}, 400);
|
|
417
|
+
}
|
|
418
|
+
});
|
|
419
|
+
authenticated.post("/api/focuses/:focusId/watches/:watchId/pause", limited, async (c) => {
|
|
420
|
+
const watch = focuses.list({ includeUnreviewed: true }).find((item) => item.id === c.req.param("focusId"))?.watches.find((item) => item.id === c.req.param("watchId"));
|
|
421
|
+
if (!watch) return c.json({
|
|
422
|
+
ok: false,
|
|
423
|
+
error: "Watch not found"
|
|
424
|
+
}, 404);
|
|
425
|
+
const paused = await focuses.pauseWatch(watch.id);
|
|
426
|
+
return c.json({
|
|
427
|
+
ok: true,
|
|
428
|
+
watch: paused
|
|
429
|
+
});
|
|
430
|
+
});
|
|
431
|
+
authenticated.patch("/api/proactive/insights/:insightId", limited, async (c) => {
|
|
432
|
+
const requested = stringField(await c.req.json().catch(() => null), "status");
|
|
433
|
+
const status = requested === "read" || requested === "dismissed" ? requested : void 0;
|
|
434
|
+
if (!status) return c.json({
|
|
435
|
+
ok: false,
|
|
436
|
+
error: "Status must be read or dismissed"
|
|
437
|
+
}, 400);
|
|
438
|
+
const insight = setProactiveInsightStatus(c.req.param("insightId"), status, Date.now(), "unread");
|
|
439
|
+
if (!insight) return c.json({
|
|
440
|
+
ok: false,
|
|
441
|
+
error: "Insight was already handled or not found"
|
|
442
|
+
}, 409);
|
|
443
|
+
if (status === "dismissed") await focuses.recordInsightFeedback(insight.watchId, false);
|
|
444
|
+
return c.json({
|
|
445
|
+
ok: true,
|
|
446
|
+
insight
|
|
447
|
+
});
|
|
448
|
+
});
|
|
449
|
+
authenticated.post("/api/proactive/insights/:insightId/approve", limited, async (c) => {
|
|
450
|
+
const insight = getProactiveInsight(c.req.param("insightId"));
|
|
451
|
+
if (!insight) return c.json({
|
|
452
|
+
ok: false,
|
|
453
|
+
error: "Insight not found"
|
|
454
|
+
}, 404);
|
|
455
|
+
if (insight.status !== "unread") return c.json({
|
|
456
|
+
ok: false,
|
|
457
|
+
error: `Insight is ${insight.status}`
|
|
458
|
+
}, 409);
|
|
459
|
+
const focus = focuses.list({ includeUnreviewed: true }).find((item) => item.watches.some((watch) => watch.id === insight.watchId));
|
|
460
|
+
if (!focus) return c.json({
|
|
461
|
+
ok: false,
|
|
462
|
+
error: "Focus not found"
|
|
463
|
+
}, 404);
|
|
464
|
+
if (!claimProactiveInsightApproval(insight.id)) return c.json({
|
|
465
|
+
ok: false,
|
|
466
|
+
error: "Insight was already handled"
|
|
467
|
+
}, 409);
|
|
468
|
+
let automationId;
|
|
469
|
+
try {
|
|
470
|
+
const automation = await deps.service.automationServiceInstance.create({
|
|
471
|
+
name: `Investigate: ${insight.title}`.slice(0, 200),
|
|
472
|
+
description: `User-approved read-only proposal from proactive insight ${insight.id}.`,
|
|
473
|
+
...focus.projectIds[0] ? { projectId: focus.projectIds[0] } : {},
|
|
474
|
+
trigger: { kind: "manual" },
|
|
475
|
+
action: {
|
|
476
|
+
kind: "agent",
|
|
477
|
+
instruction: [
|
|
478
|
+
"The user approved this evidence-backed proposal for read-only investigation and preparation.",
|
|
479
|
+
`Focus: ${focus.title}`,
|
|
480
|
+
`Observed change: ${insight.summary}`,
|
|
481
|
+
`Why it matters: ${insight.whyItMatters}`,
|
|
482
|
+
`Approved next step: ${insight.nextAction}`,
|
|
483
|
+
`Evidence: ${JSON.stringify(insight.evidence)}`,
|
|
484
|
+
"Investigate or prepare the requested material. Return a concise result with evidence. Do not modify files or external systems."
|
|
485
|
+
].join("\n"),
|
|
486
|
+
timeoutSeconds: 300
|
|
487
|
+
},
|
|
488
|
+
safety: { mode: "suggest_only" },
|
|
489
|
+
afterRun: { kind: "none" },
|
|
490
|
+
reliability: {
|
|
491
|
+
timeoutSeconds: 300,
|
|
492
|
+
disableAfterConsecutiveFailures: 1
|
|
493
|
+
}
|
|
494
|
+
});
|
|
495
|
+
automationId = automation.id;
|
|
496
|
+
const run = await deps.service.automationServiceInstance.runNow(automation.id);
|
|
497
|
+
await focuses.recordInsightFeedback(insight.watchId, true);
|
|
498
|
+
return c.json({
|
|
499
|
+
ok: true,
|
|
500
|
+
automationId: automation.id,
|
|
501
|
+
runId: run.id
|
|
502
|
+
}, 202);
|
|
503
|
+
} catch (error) {
|
|
504
|
+
if (automationId) await deps.service.automationServiceInstance.remove(automationId);
|
|
505
|
+
setProactiveInsightStatus(insight.id, "unread", Date.now(), "approved");
|
|
506
|
+
return c.json({
|
|
507
|
+
ok: false,
|
|
508
|
+
error: error instanceof Error ? error.message : String(error)
|
|
509
|
+
}, 500);
|
|
510
|
+
}
|
|
511
|
+
});
|
|
512
|
+
authenticated.post("/api/focuses/:focusId/calendar/:signalId/prepare", limited, async (c) => {
|
|
513
|
+
const focus = focuses.list().find((item) => item.id === c.req.param("focusId"));
|
|
514
|
+
if (!focus) return c.json({
|
|
515
|
+
ok: false,
|
|
516
|
+
error: "Focus not found"
|
|
517
|
+
}, 404);
|
|
518
|
+
const signal = listFocusCalendarSignals([focus]).find((item) => item.id === c.req.param("signalId"));
|
|
519
|
+
if (!signal) return c.json({
|
|
520
|
+
ok: false,
|
|
521
|
+
error: "Calendar event not found"
|
|
522
|
+
}, 404);
|
|
523
|
+
const eventContext = `${signal.title} at ${new Date(signal.startsAt).toISOString()}`;
|
|
524
|
+
try {
|
|
525
|
+
const result = await focuses.activateTrial({
|
|
526
|
+
threadId: focus.id,
|
|
527
|
+
kind: "deadline",
|
|
528
|
+
eventContext
|
|
529
|
+
});
|
|
530
|
+
return c.json({
|
|
531
|
+
ok: true,
|
|
532
|
+
...result
|
|
533
|
+
});
|
|
534
|
+
} catch (error) {
|
|
535
|
+
return c.json({
|
|
536
|
+
ok: false,
|
|
537
|
+
error: error instanceof Error ? error.message : String(error)
|
|
538
|
+
}, 500);
|
|
539
|
+
}
|
|
540
|
+
});
|
|
120
541
|
authenticated.post("/api/work-discovery/runs/:runId/cancel", (c) => {
|
|
121
542
|
const run = service.cancelRun(c.req.param("runId"));
|
|
122
543
|
return run ? c.json({
|
|
@@ -169,6 +590,36 @@ function registerWorkDiscoveryRoutes(authenticated, deps) {
|
|
|
169
590
|
}, 400);
|
|
170
591
|
}
|
|
171
592
|
});
|
|
593
|
+
authenticated.post("/api/work-discovery/runs/:runId/profile", limited, async (c) => {
|
|
594
|
+
const body = await c.req.json().catch(() => null);
|
|
595
|
+
const decisions = (body && typeof body === "object" && Array.isArray(body.decisions) ? body.decisions : []).flatMap((value) => {
|
|
596
|
+
if (!value || typeof value !== "object") return [];
|
|
597
|
+
const item = value;
|
|
598
|
+
const id = typeof item.id === "string" ? item.id.trim() : "";
|
|
599
|
+
const status = item.status === "accepted" || item.status === "edited" || item.status === "rejected" ? item.status : void 0;
|
|
600
|
+
if (!id || !status) return [];
|
|
601
|
+
return [{
|
|
602
|
+
id,
|
|
603
|
+
status,
|
|
604
|
+
...typeof item.statement === "string" ? { statement: item.statement } : {}
|
|
605
|
+
}];
|
|
606
|
+
}).slice(0, 10);
|
|
607
|
+
if (!decisions.length) return c.json({
|
|
608
|
+
ok: false,
|
|
609
|
+
error: "At least one valid decision is required"
|
|
610
|
+
}, 400);
|
|
611
|
+
const run = service.updateProfileCandidates({
|
|
612
|
+
runId: c.req.param("runId"),
|
|
613
|
+
decisions
|
|
614
|
+
});
|
|
615
|
+
return run ? c.json({
|
|
616
|
+
ok: true,
|
|
617
|
+
run
|
|
618
|
+
}) : c.json({
|
|
619
|
+
ok: false,
|
|
620
|
+
error: "Profile candidates not found"
|
|
621
|
+
}, 404);
|
|
622
|
+
});
|
|
172
623
|
authenticated.post("/api/work-discovery/runs/:runId/suggestions/:suggestionId/select", (c) => {
|
|
173
624
|
return service.selectSuggestion(c.req.param("runId"), c.req.param("suggestionId")) ? c.json({ ok: true }) : c.json({
|
|
174
625
|
ok: false,
|
|
@@ -61,6 +61,7 @@ export declare class GatewayService {
|
|
|
61
61
|
private connectedKnowledgeCoordinator;
|
|
62
62
|
private stopAutomationProductEventBridge;
|
|
63
63
|
private stopSessionTranscriptAutomationEvents;
|
|
64
|
+
private stopFocusTrialExpiryReconciler;
|
|
64
65
|
/**
|
|
65
66
|
* Webchat agent invocation surface (`runAgent`, `abortAgentRun`, `steer*`,
|
|
66
67
|
* `submitClarifyResponse`, clarify-bridge dispatch). Owns the
|
|
@@ -267,6 +268,7 @@ export declare class GatewayService {
|
|
|
267
268
|
processDirect(content: string, sessionKey?: string): Promise<string>;
|
|
268
269
|
subscribe(sessionId: string, listener: (event: ServiceEvent) => Promise<void> | void): () => void;
|
|
269
270
|
emit(type: string, payload: unknown): void;
|
|
271
|
+
private handleAutomationRunCompleted;
|
|
270
272
|
private startAutomationProductEventBridge;
|
|
271
273
|
/** Replay events since `lastEventId` for SSE reconnection. */
|
|
272
274
|
getEventsSince(sessionId: string, lastEventId: string): ServiceEvent[];
|
|
@@ -48,6 +48,10 @@ import { startConnectorMemorySyncCoordinator } from "../connectors/memory-sync-c
|
|
|
48
48
|
import { startConnectorSupervisor } from "../connectors/supervisor.js";
|
|
49
49
|
import { assertGatewayAuthConfigured, extractToken, resolveGatewayAuth, validateToken } from "./auth.js";
|
|
50
50
|
import { reconcileDreamingAutomations } from "./dreaming-automation-reconciler.js";
|
|
51
|
+
import { FocusService } from "../proactive/focus-service.js";
|
|
52
|
+
import { processFocusAutomationRun } from "../proactive/run-processor.js";
|
|
53
|
+
import { startTrialExpiryReconciler } from "../proactive/trial-expiry-reconciler.js";
|
|
54
|
+
import "../proactive/index.js";
|
|
51
55
|
import { NotesStore } from "../notes/store.js";
|
|
52
56
|
import { buildNoteAgentContext } from "../notes/agent-context.js";
|
|
53
57
|
import { NotesService } from "../notes/service.js";
|
|
@@ -141,6 +145,7 @@ var GatewayService = class {
|
|
|
141
145
|
connectedKnowledgeCoordinator = null;
|
|
142
146
|
stopAutomationProductEventBridge = null;
|
|
143
147
|
stopSessionTranscriptAutomationEvents = null;
|
|
148
|
+
stopFocusTrialExpiryReconciler = null;
|
|
144
149
|
/**
|
|
145
150
|
* Webchat agent invocation surface (`runAgent`, `abortAgentRun`, `steer*`,
|
|
146
151
|
* `submitClarifyResponse`, clarify-bridge dispatch). Owns the
|
|
@@ -356,7 +361,7 @@ var GatewayService = class {
|
|
|
356
361
|
getDefaultAgentId: () => getDefaultAgentId(this.config),
|
|
357
362
|
getProjectWorkspaceRoot: (projectId) => this.projects.get(projectId)?.workspaceRoot,
|
|
358
363
|
workflowRunService: this.createWorkflowRunService(),
|
|
359
|
-
onRunCompleted: (run) => this.
|
|
364
|
+
onRunCompleted: (run) => this.handleAutomationRunCompleted(run)
|
|
360
365
|
});
|
|
361
366
|
this._agentService.persistentGoals.setWebchatContinuationScheduler((sessionKey, message) => {
|
|
362
367
|
const scheduleWhenIdle = () => {
|
|
@@ -666,7 +671,7 @@ var GatewayService = class {
|
|
|
666
671
|
agentService: this.agentService,
|
|
667
672
|
getDefaultAgentId: () => getDefaultAgentId(this.config),
|
|
668
673
|
workflowRunService: this.createWorkflowRunService(),
|
|
669
|
-
onRunCompleted: (run) => this.
|
|
674
|
+
onRunCompleted: (run) => this.handleAutomationRunCompleted(run)
|
|
670
675
|
});
|
|
671
676
|
this.startAutomationProductEventBridge();
|
|
672
677
|
await trace.measure("workflows.reconcile", () => this.reconcileInterruptedWorkflowRuns());
|
|
@@ -679,6 +684,7 @@ var GatewayService = class {
|
|
|
679
684
|
});
|
|
680
685
|
await trace.measure("automations.initialize", () => this.automationService.initialize());
|
|
681
686
|
await trace.measure("dreaming.reconcile", () => this.reconcileDreamingAutomations());
|
|
687
|
+
this.stopFocusTrialExpiryReconciler = startTrialExpiryReconciler(new FocusService(this.automationService));
|
|
682
688
|
await this.notesService.initialize();
|
|
683
689
|
this.ensureHeartbeatService().start(heartbeatRunnerConfigFromConfig(this.config));
|
|
684
690
|
this.connectorSupervisor = startConnectorSupervisor({
|
|
@@ -834,6 +840,8 @@ var GatewayService = class {
|
|
|
834
840
|
this.lastChannelConnectDeferMode = "auto";
|
|
835
841
|
this.lastChannelConnectDeferSource = "off";
|
|
836
842
|
await this.channelManager.stop();
|
|
843
|
+
await this.stopFocusTrialExpiryReconciler?.();
|
|
844
|
+
this.stopFocusTrialExpiryReconciler = null;
|
|
837
845
|
await this.automationService.stop();
|
|
838
846
|
this.stopAutomationProductEventBridge?.();
|
|
839
847
|
this.stopAutomationProductEventBridge = null;
|
|
@@ -1234,6 +1242,23 @@ var GatewayService = class {
|
|
|
1234
1242
|
this.createGoalNotificationService().handleGatewayEvent(type, payload);
|
|
1235
1243
|
this.createMobileNotificationService().handleGatewayEvent(type, payload);
|
|
1236
1244
|
}
|
|
1245
|
+
handleAutomationRunCompleted(run) {
|
|
1246
|
+
try {
|
|
1247
|
+
const proactive = processFocusAutomationRun(run);
|
|
1248
|
+
this.emit("automation.run.completed", {
|
|
1249
|
+
run,
|
|
1250
|
+
silent: proactive.handled
|
|
1251
|
+
});
|
|
1252
|
+
if (proactive.insight) this.emit("proactive.insight.created", { insight: proactive.insight });
|
|
1253
|
+
} catch (err) {
|
|
1254
|
+
log.warn({
|
|
1255
|
+
err,
|
|
1256
|
+
automationId: run.automationId,
|
|
1257
|
+
runId: run.id
|
|
1258
|
+
}, "Proactive result processing failed");
|
|
1259
|
+
this.emit("automation.run.completed", { run });
|
|
1260
|
+
}
|
|
1261
|
+
}
|
|
1237
1262
|
startAutomationProductEventBridge() {
|
|
1238
1263
|
this.stopAutomationProductEventBridge?.();
|
|
1239
1264
|
this.stopSessionTranscriptAutomationEvents?.();
|
|
@@ -44,6 +44,7 @@ function goalEvent(payload) {
|
|
|
44
44
|
}
|
|
45
45
|
function automationEvent(payload) {
|
|
46
46
|
if (!payload || typeof payload !== "object") return null;
|
|
47
|
+
if (payload.silent === true) return null;
|
|
47
48
|
const run = payload.run;
|
|
48
49
|
if (!run || run.status !== "failed" && run.status !== "timeout" && run.status !== "succeeded") return null;
|
|
49
50
|
const type = run.status === "succeeded" ? "automation.completed" : "automation.failed";
|