@xopcai/xopc 0.0.176 → 0.0.178
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/{activity-store-DsFM1upC.js → activity-store-BzGX__8I.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-DvdMLOga.js → agent-avatar-dicebear-BzxntcaZ.js} +1 -1
- package/dist/gateway/static/root/assets/agents-DC9F12Kw.js +2 -0
- package/dist/gateway/static/root/assets/{api-BdPLCCBm.js → api-hi6f2Xtp.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-DMLDOHul.js → app-management-settings-panel-fTY1F7ac.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-DbI9foFR.js → appearance-settings-BZ-IxQfB.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-5bKr05Fa.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-Dfdxuwvb.js → archive-plugin-ZSLLG8wB.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-Dn3RlnYD.js → attachment-load-D4YktqIF.js} +1 -1
- package/dist/gateway/static/root/assets/{automation-suggestion-card-Bc0Y7A9u.js → automation-suggestion-card-B7mxFRtf.js} +1 -1
- package/dist/gateway/static/root/assets/automations-page-Dg6dmt5g.js +6 -0
- package/dist/gateway/static/root/assets/{binary-plugins-0XtB-xC0.js → binary-plugins-BIkPxfxj.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-C4fXWbEE.js → block-editor-Q3v_YQom.js} +6 -6
- package/dist/gateway/static/root/assets/{browser-settings-page-lC86-drr.js → browser-settings-page-BHoo6Rpq.js} +4 -4
- package/dist/gateway/static/root/assets/{browser-workflow-inputs-CZmzNymN.js → browser-workflow-inputs-M5lTEW1I.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-workflows-page-CBYM9HqG.js → browser-workflows-page-B3T1KYk4.js} +2 -2
- package/dist/gateway/static/root/assets/capabilities-settings-panel-BlsqN8Fu.js +7 -0
- package/dist/gateway/static/root/assets/{capability-presets-api-BiJxmmhW.js → capability-presets-api-DE09c0VB.js} +1 -1
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-DJeT8_B4.js +1 -0
- package/dist/gateway/static/root/assets/{channel-recipient-api-BKTUZDp-.js → channel-recipient-api-CFR5FBfS.js} +1 -1
- package/dist/gateway/static/root/assets/channels-settings-C4VVjYEm.js +1 -0
- package/dist/gateway/static/root/assets/channels-status-swr-vdf8kB16.js +1 -0
- package/dist/gateway/static/root/assets/{connector-logo-Pr4RIKjj.js → connector-logo-B1mD-3pM.js} +1 -1
- package/dist/gateway/static/root/assets/connectors-page-DNcrDThX.js +2 -0
- package/dist/gateway/static/root/assets/desktop-pet-B1urphOZ.js +1 -0
- package/dist/gateway/static/root/assets/{desktop-pet-settings-CEQacUDF.js → desktop-pet-settings-DTL6J3EP.js} +1 -1
- package/dist/gateway/static/root/assets/{directory-picker-path-field-DWnxdZtc.js → directory-picker-path-field-BYQJ2XUS.js} +1 -1
- package/dist/gateway/static/root/assets/{dreaming-settings-D2e2w2Ho.js → dreaming-settings-BXcb8fwx.js} +3 -3
- package/dist/gateway/static/root/assets/{extension-debug-page-BLjTGbv3.js → extension-debug-page-O1Xu1r4Q.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-D2_UC6hy.js → extension-page-C2Jraq8l.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-BsH6o_PX.js → extension-settings-page-DcXQDTpG.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-api-C-DkC6UJ.js → gateway-config-api-DmPIZrvg.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-settings-DEOGiimF.js → gateway-settings-DmObBx9b.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-startup-retry-BlSLh1TF.js → gateway-startup-retry-BZEkOdPm.js} +1 -1
- package/dist/gateway/static/root/assets/{goal-create-dialog-CSFcRE_N.js → goal-create-dialog-BRhmmBe9.js} +1 -1
- package/dist/gateway/static/root/assets/goal-detail-page-C1k7_s_O.js +4 -0
- package/dist/gateway/static/root/assets/{goals-config-api-CcdS9qek.js → goals-config-api-Fwu1wjEP.js} +1 -1
- package/dist/gateway/static/root/assets/{goals-page-BAcErdch.js → goals-page-hOu9uA3q.js} +2 -2
- package/dist/gateway/static/root/assets/{goals-settings-BY7crl0z.js → goals-settings-DY-JjvHz.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-settings-DtTkS0gs.js → heartbeat-settings-BtKu2NWT.js} +1 -1
- package/dist/gateway/static/root/assets/{image-generation-api-WGgkbwDZ.js → image-generation-api-05Gg8wsU.js} +1 -1
- package/dist/gateway/static/root/assets/{index-2UImfRDC.js → index-C0CGebQ1.js} +65 -65
- package/dist/gateway/static/root/assets/index-eqq25gvV.css +1 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-C5lpWQ3f.js → keyboard-shortcuts-settings-CfmDR9Sc.js} +1 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-EjsNT7nJ.js +2 -0
- package/dist/gateway/static/root/assets/{local-apps-page-b05wWvXG.js → local-apps-page-Df8BW1A_.js} +1 -1
- package/dist/gateway/static/root/assets/{locale-store-sToMfHX_.js → locale-store-CTwSy7yW.js} +1 -1
- package/dist/gateway/static/root/assets/{logs-page-cDE1jLJv.js → logs-page-Dswjlraa.js} +3 -3
- package/dist/gateway/static/root/assets/{markdown-split-0gPVst5y.js → markdown-split-B3FvKbaP.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-Rxyq_KTm.js → media-plugins-DsjrvvB6.js} +1 -1
- package/dist/gateway/static/root/assets/messages-DP6tPKk-.js +3 -0
- package/dist/gateway/static/root/assets/{notes-page-DRhNDl_Q.js → notes-page-tuzIwy3c.js} +1 -1
- package/dist/gateway/static/root/assets/notes-workbench-DSh3-hMY.js +4 -0
- package/dist/gateway/static/root/assets/{page-tabs-cOEOQqHh.js → page-tabs-ke9s4nYi.js} +1 -1
- package/dist/gateway/static/root/assets/{preview-open-alternatives-BopOLFvu.js → preview-open-alternatives-Cp1eI4S9.js} +1 -1
- package/dist/gateway/static/root/assets/{product-open-page-DWVPmmOq.js → product-open-page-dXQCMAtH.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-D0QPRHR_.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-CI5Vz62F.js +1 -0
- package/dist/gateway/static/root/assets/remote-access-hub-S1jpzBS5.js +1 -0
- package/dist/gateway/static/root/assets/{save-bar-controls-BfZmKe1t.js → save-bar-controls-Bl30zjHc.js} +1 -1
- package/dist/gateway/static/root/assets/{schedule-field-Cpi4jCRV.js → schedule-field-DqhmXQKo.js} +1 -1
- package/dist/gateway/static/root/assets/{schema-form-OXFkcZQe.js → schema-form-DkUCy6vf.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-CTm66k7h.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-CU52AUVD.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-BwqkZCHJ.js → settings-form-section-C6ZbNpdy.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-loading-skeleton-BbqH_S3Y.js → settings-loading-skeleton-Bk58_cr7.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-BoxC-JSa.js → settings-page-k8iE_NdX.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-layout-Ddu2iGaW.js → settings-page-layout-DgFSya2e.js} +1 -1
- package/dist/gateway/static/root/assets/{setup-status-panel-z1Lwv0js.js → setup-status-panel-B_KDlyZA.js} +1 -1
- package/dist/gateway/static/root/assets/{share-preview-page-CVazOFjy.js → share-preview-page-CV7nL_J9.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-DK6XK95e.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-Bvv_u4ii.js +1 -0
- package/dist/gateway/static/root/assets/skills-page-BGHvVbay.js +2 -0
- package/dist/gateway/static/root/assets/{skills-page.utils-DgyB1tSo.js → skills-page.utils-kahBIHg0.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-BoLSQL65.js → system-settings-panel-JV3-MG5F.js} +1 -1
- package/dist/gateway/static/root/assets/{theme-store-CBNcGOfj.js → theme-store-DFLyzoLO.js} +1 -1
- package/dist/gateway/static/root/assets/{time-picker-gochWrny.js → time-picker-XwpxdZFr.js} +1 -1
- package/dist/gateway/static/root/assets/{typed-models-lib-DvRnr7YB.js → typed-models-lib-60Aqo-UJ.js} +1 -1
- package/dist/gateway/static/root/assets/{use-channel-catalog-CA9BFVB7.js → use-channel-catalog-CnTkHDnw.js} +1 -1
- package/dist/gateway/static/root/assets/user-context-page-DBCMk-Vn.js +1 -0
- package/dist/gateway/static/root/assets/{voice-api-key-field-v8tgylEZ.js → voice-api-key-field-CNa8qUgS.js} +1 -1
- package/dist/gateway/static/root/assets/work-discovery-page-C1UIdsCl.js +1 -0
- package/dist/gateway/static/root/assets/work-item-detail-page-DEAQepB8.js +1 -0
- package/dist/gateway/static/root/assets/work-page-D5qYmCTq.js +3 -0
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-CC3cJn5k.js → workflow-run-setup-panel-yV_x595t.js} +2 -2
- package/dist/gateway/static/root/assets/workflows-page-yrK17ZZ5.js +11 -0
- package/dist/gateway/static/root/index.html +7 -7
- package/dist/package.js +1 -1
- package/dist/src/agent/embedded/model-runtime.js +3 -0
- package/dist/src/agent/embedded/run-for-session.js +18 -5
- package/dist/src/agent/embedded/run-turn.js +6 -3
- package/dist/src/agent/embedded/types.d.ts +2 -0
- package/dist/src/automations/service/automation-service.d.ts +3 -0
- package/dist/src/automations/service/automation-service.js +37 -7
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/cli/commands/gateway/lifecycle.js +1 -1
- package/dist/src/cli/commands/update.js +1 -1
- package/dist/src/connectors/composio-sessions.js +1 -1
- package/dist/src/gateway/hono/routes/home.d.ts +18 -2
- package/dist/src/gateway/hono/routes/home.js +19 -0
- package/dist/src/gateway/hono/routes/index.js +2 -2
- package/dist/src/gateway/hono/routes/local-apps.js +1 -1
- package/dist/src/gateway/hono/routes/proactive.d.ts +4 -0
- package/dist/src/gateway/hono/routes/proactive.js +157 -0
- package/dist/src/gateway/hono/routes/projects.js +2 -2
- package/dist/src/gateway/hono/routes/update.js +2 -2
- package/dist/src/gateway/index.js +1 -1
- package/dist/src/gateway/run-loop.js +1 -1
- package/dist/src/gateway/service.d.ts +10 -1
- package/dist/src/gateway/service.js +36 -36
- package/dist/src/infra/gateway-processes.js +1 -1
- package/dist/src/infra/update-restart.js +1 -1
- package/dist/src/infra/update-runner.js +2 -2
- package/dist/src/infra/update-startup.js +1 -1
- package/dist/src/mcp/channel-bridge.js +1 -1
- package/dist/src/mobile/notification-service.d.ts +1 -0
- package/dist/src/mobile/notification-service.js +38 -18
- package/dist/src/mobile/notification-types.d.ts +2 -2
- package/dist/src/proactive/events/envelope.d.ts +2 -0
- package/dist/src/proactive/events/envelope.js +54 -0
- package/dist/src/proactive/events/publisher.d.ts +4 -0
- package/dist/src/proactive/events/repository.d.ts +9 -0
- package/dist/src/proactive/events/repository.js +62 -0
- package/dist/src/proactive/events/types.d.ts +44 -0
- package/dist/src/proactive/events/types.js +15 -0
- package/dist/src/proactive/execution/agent-executor.d.ts +16 -0
- package/dist/src/proactive/execution/agent-executor.js +104 -0
- package/dist/src/proactive/execution/context.d.ts +31 -0
- package/dist/src/proactive/execution/context.js +72 -0
- package/dist/src/proactive/execution/insight.d.ts +4 -0
- package/dist/src/proactive/execution/insight.js +74 -0
- package/dist/src/proactive/execution/repository.d.ts +23 -0
- package/dist/src/proactive/execution/repository.js +122 -0
- package/dist/src/proactive/execution/types.d.ts +54 -0
- package/dist/src/proactive/execution/types.js +1 -0
- package/dist/src/proactive/execution/worker.d.ts +15 -0
- package/dist/src/proactive/execution/worker.js +96 -0
- package/dist/src/proactive/inbox/repository.d.ts +24 -0
- package/dist/src/proactive/inbox/repository.js +117 -0
- package/dist/src/proactive/inbox/service.d.ts +17 -0
- package/dist/src/proactive/inbox/service.js +22 -0
- package/dist/src/proactive/inbox/types.d.ts +38 -0
- package/dist/src/proactive/inbox/types.js +1 -0
- package/dist/src/proactive/inbox/worker.d.ts +12 -0
- package/dist/src/proactive/inbox/worker.js +56 -0
- package/dist/src/proactive/index.d.ts +17 -0
- package/dist/src/proactive/index.js +11 -0
- package/dist/src/proactive/routing/batch-repository.d.ts +27 -0
- package/dist/src/proactive/routing/batch-repository.js +56 -0
- package/dist/src/proactive/routing/matcher.d.ts +5 -0
- package/dist/src/proactive/routing/matcher.js +56 -0
- package/dist/src/proactive/routing/types.d.ts +44 -0
- package/dist/src/proactive/routing/types.js +1 -0
- package/dist/src/proactive/scenarios/prompt-composer.d.ts +14 -0
- package/dist/src/proactive/scenarios/prompt-composer.js +24 -0
- package/dist/src/proactive/scenarios/repository.d.ts +23 -0
- package/dist/src/proactive/scenarios/repository.js +162 -0
- package/dist/src/proactive/scenarios/service.d.ts +15 -0
- package/dist/src/proactive/scenarios/service.js +26 -0
- package/dist/src/proactive/scenarios/types.d.ts +36 -0
- package/dist/src/proactive/scenarios/types.js +1 -0
- package/dist/src/proactive/service.d.ts +18 -0
- package/dist/src/proactive/service.js +61 -0
- package/dist/src/projects/project-service.d.ts +3 -1
- package/dist/src/projects/project-service.js +62 -32
- package/dist/src/providers/provider-auth-service.js +3 -0
- package/dist/src/providers/register-bundled-oauth-flows.d.ts +2 -0
- package/dist/src/providers/register-bundled-oauth-flows.js +16 -0
- package/dist/src/session/store.d.ts +2 -0
- package/dist/src/session/store.js +30 -0
- package/dist/src/storage/sqlite/migrations/068_proactive_event_spine.sql +71 -0
- package/dist/src/storage/sqlite/migrations/069_proactive_scenario_control.sql +69 -0
- package/dist/src/storage/sqlite/migrations/070_proactive_execution.sql +55 -0
- package/dist/src/storage/sqlite/migrations/071_proactive_inbox.sql +45 -0
- package/dist/src/storage/sqlite/migrations/072_proactive_judgments.sql +14 -0
- package/dist/src/storage/sqlite/migrations/073_enable_default_proactive_scenarios.sql +13 -0
- package/dist/src/storage/sqlite/migrations/074_deduplicate_blocked_work_routing.sql +5 -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/thread-service.d.ts +1 -3
- package/dist/src/work-discovery/thread-service.js +13 -25
- package/dist/src/work-items/work-item-service.d.ts +3 -1
- package/dist/src/work-items/work-item-service.js +67 -36
- package/package.json +3 -11
- package/dist/gateway/static/root/assets/agents-BVjlpbeZ.js +0 -2
- package/dist/gateway/static/root/assets/api-Bop4IQRW.js +0 -1
- package/dist/gateway/static/root/assets/apps-page-njqxLWYD.js +0 -1
- package/dist/gateway/static/root/assets/automations-page-D-eweHZJ.js +0 -6
- package/dist/gateway/static/root/assets/capabilities-settings-panel-6tYNfHqJ.js +0 -7
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-Co-ymbd9.js +0 -1
- package/dist/gateway/static/root/assets/channels-settings-D46eVjaQ.js +0 -1
- package/dist/gateway/static/root/assets/channels-status-swr-BMRAO4zZ.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-Dw1eYbRi.js +0 -2
- package/dist/gateway/static/root/assets/copy-VueTIC2x.js +0 -1
- package/dist/gateway/static/root/assets/desktop-pet-B8cZuQUt.js +0 -1
- package/dist/gateway/static/root/assets/focus-detail-page-BBXUtxRB.js +0 -1
- package/dist/gateway/static/root/assets/goal-detail-page-VjRArfAJ.js +0 -4
- package/dist/gateway/static/root/assets/index-CS9sVShT.css +0 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-Cl0fcPL4.js +0 -2
- package/dist/gateway/static/root/assets/messages-CarlxqXV.js +0 -3
- package/dist/gateway/static/root/assets/notes-workbench-BKNBk0Uf.js +0 -4
- package/dist/gateway/static/root/assets/project-detail-page-BhjEXNQW.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-B80e69PH.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-CwdVob6H.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-BGt3Asj6.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-BnTdM9Nn.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-C4lXuyQj.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-DSuIDkeI.js +0 -1
- package/dist/gateway/static/root/assets/skills-page-xgZczqVe.js +0 -2
- package/dist/gateway/static/root/assets/user-context-page-CEfIy4WZ.js +0 -1
- package/dist/gateway/static/root/assets/work-discovery-page-B-3MClaf.js +0 -1
- package/dist/gateway/static/root/assets/work-item-detail-page-CEsFEdax.js +0 -1
- package/dist/gateway/static/root/assets/work-page-CT9AHnq6.js +0 -3
- package/dist/gateway/static/root/assets/workflows-page-C-1-_Zp1.js +0 -11
- package/dist/src/focuses/candidate-repository.d.ts +0 -15
- package/dist/src/focuses/candidate-repository.js +0 -91
- package/dist/src/focuses/index.d.ts +0 -7
- package/dist/src/focuses/index.js +0 -7
- package/dist/src/focuses/insight-repository.d.ts +0 -22
- package/dist/src/focuses/insight-repository.js +0 -77
- package/dist/src/focuses/prompts.d.ts +0 -2
- package/dist/src/focuses/prompts.js +0 -18
- package/dist/src/focuses/reconciler.d.ts +0 -5
- package/dist/src/focuses/reconciler.js +0 -26
- package/dist/src/focuses/repository.d.ts +0 -61
- package/dist/src/focuses/repository.js +0 -214
- package/dist/src/focuses/run-processor.d.ts +0 -18
- package/dist/src/focuses/run-processor.js +0 -162
- package/dist/src/focuses/service.d.ts +0 -42
- package/dist/src/focuses/service.js +0 -241
- package/dist/src/focuses/types.d.ts +0 -89
- package/dist/src/gateway/hono/routes/focuses.d.ts +0 -3
- package/dist/src/gateway/hono/routes/focuses.js +0 -319
- /package/dist/src/{focuses/types.js → proactive/events/publisher.js} +0 -0
|
@@ -46,15 +46,6 @@ import { startConnectedKnowledgeCoordinator } from "../knowledge/coordinator.js"
|
|
|
46
46
|
import "../knowledge/index.js";
|
|
47
47
|
import { startConnectorLearningCoordinator } from "../connectors/learning-coordinator.js";
|
|
48
48
|
import { startConnectorSupervisor } from "../connectors/supervisor.js";
|
|
49
|
-
import { FocusService } from "../focuses/service.js";
|
|
50
|
-
import { processFocusMonitorRun } from "../focuses/run-processor.js";
|
|
51
|
-
import { startFocusReconciler } from "../focuses/reconciler.js";
|
|
52
|
-
import "../focuses/index.js";
|
|
53
|
-
import { LocalAppService } from "../local-apps/service.js";
|
|
54
|
-
import "../local-apps/index.js";
|
|
55
|
-
import { scheduleGatewayUpdateCheck } from "../infra/update-startup.js";
|
|
56
|
-
import { runBootstrapMigrationsSync } from "../migrations/runner.js";
|
|
57
|
-
import { MobileNotificationService } from "../mobile/notification-service.js";
|
|
58
49
|
import { assertGatewayAuthConfigured, extractToken, resolveGatewayAuth, validateToken } from "./auth.js";
|
|
59
50
|
import { reconcileDreamingAutomations } from "./dreaming-automation-reconciler.js";
|
|
60
51
|
import { NotesStore } from "../notes/store.js";
|
|
@@ -80,8 +71,21 @@ import "./rate-limit/index.js";
|
|
|
80
71
|
import { assertGatewayRuntimeConfig } from "./runtime-config.js";
|
|
81
72
|
import { auditGatewayConfig } from "./security/audit.js";
|
|
82
73
|
import { ModelCatalogSyncService } from "../providers/model-catalog-sync-service.js";
|
|
74
|
+
import { runBootstrapMigrationsSync } from "../migrations/runner.js";
|
|
75
|
+
import { MobileNotificationService } from "../mobile/notification-service.js";
|
|
76
|
+
import { LocalAppService } from "../local-apps/service.js";
|
|
77
|
+
import "../local-apps/index.js";
|
|
83
78
|
import { createRuntimeBrowserRecipeService } from "../browser/recipes/runtime-service.js";
|
|
84
79
|
import "../browser/recipes/index.js";
|
|
80
|
+
import { ProactiveEventService } from "../proactive/service.js";
|
|
81
|
+
import { ProactiveScenarioService } from "../proactive/scenarios/service.js";
|
|
82
|
+
import { ReadonlyProactiveAgentExecutor } from "../proactive/execution/agent-executor.js";
|
|
83
|
+
import { listInsights } from "../proactive/execution/repository.js";
|
|
84
|
+
import { ProactiveWorker } from "../proactive/execution/worker.js";
|
|
85
|
+
import { ProactiveInboxService } from "../proactive/inbox/service.js";
|
|
86
|
+
import { ProactiveInboxWorker } from "../proactive/inbox/worker.js";
|
|
87
|
+
import "../proactive/index.js";
|
|
88
|
+
import { scheduleGatewayUpdateCheck } from "../infra/update-startup.js";
|
|
85
89
|
import { resolveChannelConnectDeferSet } from "./resolve-channel-connect-defer.js";
|
|
86
90
|
import { restartGatewayProcessWithFreshPid } from "./respawn.js";
|
|
87
91
|
import { GatewaySessionsApi } from "./service/sessions-api.js";
|
|
@@ -163,7 +167,6 @@ var GatewayService = class {
|
|
|
163
167
|
connectedKnowledgeCoordinator = null;
|
|
164
168
|
stopAutomationProductEventBridge = null;
|
|
165
169
|
stopSessionTranscriptAutomationEvents = null;
|
|
166
|
-
stopFocusReconciler = null;
|
|
167
170
|
/**
|
|
168
171
|
* Webchat agent invocation surface (`runAgent`, `abortAgentRun`, `steer*`,
|
|
169
172
|
* `submitClarifyResponse`, clarify-bridge dispatch). Owns the
|
|
@@ -187,14 +190,27 @@ var GatewayService = class {
|
|
|
187
190
|
marketplace;
|
|
188
191
|
/** First-class project grouping surface. */
|
|
189
192
|
projects;
|
|
193
|
+
workItems;
|
|
190
194
|
/** Local user-created apps, their coder projects, previews, and installs. */
|
|
191
195
|
localApps;
|
|
196
|
+
/** Unified durable event spine for proactive scenarios. */
|
|
197
|
+
proactiveScenarios = new ProactiveScenarioService();
|
|
198
|
+
proactive = new ProactiveEventService(() => this.proactiveScenarios.routes());
|
|
199
|
+
proactiveInbox = new ProactiveInboxService();
|
|
200
|
+
proactiveInsights = listInsights;
|
|
201
|
+
proactiveWorker;
|
|
202
|
+
proactiveInboxWorker;
|
|
192
203
|
constructor(serviceConfig = {}) {
|
|
193
204
|
this.serviceConfig = serviceConfig;
|
|
194
205
|
this.bus = new MessageBus();
|
|
195
206
|
this.configPath = serviceConfig.configPath || resolveConfigPath();
|
|
196
207
|
runBootstrapMigrationsSync(this.configPath);
|
|
197
208
|
this.config = loadConfig(this.configPath);
|
|
209
|
+
this.proactiveWorker = new ProactiveWorker(new ReadonlyProactiveAgentExecutor(() => this.config));
|
|
210
|
+
this.proactiveInboxWorker = new ProactiveInboxWorker({ deliver: async ({ inboxItem }) => {
|
|
211
|
+
this.sse.emit("proactive.inbox.created", inboxItem);
|
|
212
|
+
await this.createMobileNotificationService().deliverGatewayEvent("proactive.inbox.created", inboxItem);
|
|
213
|
+
} });
|
|
198
214
|
let bootstrapConfigChanged = initializeVoiceDefaults(this.config, inferProductLanguageFromEnvironment());
|
|
199
215
|
const starterResult = ensureStarterAgentsInitialized(this.config);
|
|
200
216
|
if (starterResult.changed) {
|
|
@@ -248,9 +264,10 @@ var GatewayService = class {
|
|
|
248
264
|
this.workspacePath = getWorkspacePath(this.config) || "./workspace";
|
|
249
265
|
this.initializeExtensionLoader();
|
|
250
266
|
this.sessionIndex = new SessionIndex({ config: this.config });
|
|
251
|
-
this.automationService = new AutomationService();
|
|
267
|
+
this.automationService = new AutomationService(this.proactive);
|
|
252
268
|
this.notesService = new NotesService(new NotesStore());
|
|
253
|
-
this.projects = new ProjectService();
|
|
269
|
+
this.projects = new ProjectService(void 0, this.proactive);
|
|
270
|
+
this.workItems = new WorkItemService(void 0, this.proactive);
|
|
254
271
|
this.localApps = new LocalAppService({
|
|
255
272
|
projects: this.projects,
|
|
256
273
|
workspaceRoot: this.workspacePath,
|
|
@@ -343,7 +360,7 @@ var GatewayService = class {
|
|
|
343
360
|
getBrowserRecipeService: () => this.browserRecipes,
|
|
344
361
|
getNotesService: () => this.notesService,
|
|
345
362
|
getProjectService: () => this.projects,
|
|
346
|
-
getWorkItemService: () =>
|
|
363
|
+
getWorkItemService: () => this.workItems,
|
|
347
364
|
getLocalAppService: () => this.localApps,
|
|
348
365
|
getWorkflowRunService: () => this.createWorkflowRunService(),
|
|
349
366
|
sourceContextResolver: async (binding) => {
|
|
@@ -357,7 +374,7 @@ var GatewayService = class {
|
|
|
357
374
|
});
|
|
358
375
|
}
|
|
359
376
|
if (binding.kind === "work_item") {
|
|
360
|
-
const item =
|
|
377
|
+
const item = this.workItems.getWorkItem(binding.sourceId);
|
|
361
378
|
return item ? await buildWorkItemAgentContext(item) : null;
|
|
362
379
|
}
|
|
363
380
|
return null;
|
|
@@ -613,6 +630,8 @@ var GatewayService = class {
|
|
|
613
630
|
openXopcDatabase();
|
|
614
631
|
this.startTime = Date.now();
|
|
615
632
|
this.running = true;
|
|
633
|
+
this.proactiveWorker.start();
|
|
634
|
+
this.proactiveInboxWorker.start();
|
|
616
635
|
prepareConfiguredLocalVoiceModel(this.config);
|
|
617
636
|
this.startupTrace = createGatewayStartupTrace();
|
|
618
637
|
this.readiness.markStarting(this.startTime);
|
|
@@ -706,7 +725,6 @@ var GatewayService = class {
|
|
|
706
725
|
});
|
|
707
726
|
await trace.measure("automations.initialize", () => this.automationService.initialize());
|
|
708
727
|
await trace.measure("dreaming.reconcile", () => this.reconcileDreamingAutomations());
|
|
709
|
-
this.stopFocusReconciler = startFocusReconciler(new FocusService(this.automationService));
|
|
710
728
|
await this.notesService.initialize();
|
|
711
729
|
this.ensureHeartbeatService().start(heartbeatRunnerConfigFromConfig(this.config));
|
|
712
730
|
this.connectorSupervisor = startConnectorSupervisor({
|
|
@@ -831,6 +849,8 @@ var GatewayService = class {
|
|
|
831
849
|
setPairingBroadcastSink(null);
|
|
832
850
|
log.debug("Stopping gateway service...");
|
|
833
851
|
this.readiness.markStarting();
|
|
852
|
+
await this.proactiveWorker.stop();
|
|
853
|
+
await this.proactiveInboxWorker.stop();
|
|
834
854
|
await stopTailscaleExposure().catch((err) => {
|
|
835
855
|
log.warn({ err }, "Tailscale exposure shutdown failed");
|
|
836
856
|
});
|
|
@@ -866,8 +886,6 @@ var GatewayService = class {
|
|
|
866
886
|
this.lastChannelConnectDeferMode = "auto";
|
|
867
887
|
this.lastChannelConnectDeferSource = "off";
|
|
868
888
|
await this.channelManager.stop();
|
|
869
|
-
await this.stopFocusReconciler?.();
|
|
870
|
-
this.stopFocusReconciler = null;
|
|
871
889
|
await this.automationService.stop();
|
|
872
890
|
this.stopAutomationProductEventBridge?.();
|
|
873
891
|
this.stopAutomationProductEventBridge = null;
|
|
@@ -1272,25 +1290,7 @@ var GatewayService = class {
|
|
|
1272
1290
|
this.createMobileNotificationService().handleGatewayEvent(type, payload);
|
|
1273
1291
|
}
|
|
1274
1292
|
handleAutomationRunCompleted(run) {
|
|
1275
|
-
|
|
1276
|
-
const focusResult = processFocusMonitorRun(run);
|
|
1277
|
-
this.emit("automation.run.completed", {
|
|
1278
|
-
run,
|
|
1279
|
-
silent: focusResult.handled
|
|
1280
|
-
});
|
|
1281
|
-
if (focusResult.handled) this.emit("focus.run.updated", {
|
|
1282
|
-
automationId: run.automationId,
|
|
1283
|
-
run
|
|
1284
|
-
});
|
|
1285
|
-
if (focusResult.insight) this.emit("focus.insight.created", { insight: focusResult.insight });
|
|
1286
|
-
} catch (err) {
|
|
1287
|
-
log.warn({
|
|
1288
|
-
err,
|
|
1289
|
-
automationId: run.automationId,
|
|
1290
|
-
runId: run.id
|
|
1291
|
-
}, "Proactive result processing failed");
|
|
1292
|
-
this.emit("automation.run.completed", { run });
|
|
1293
|
-
}
|
|
1293
|
+
this.emit("automation.run.completed", { run });
|
|
1294
1294
|
}
|
|
1295
1295
|
startAutomationProductEventBridge() {
|
|
1296
1296
|
this.stopAutomationProductEventBridge?.();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { isGatewayArgv, parseProcCmdline } from "./gateway-process-argv.js";
|
|
2
1
|
import { listPortListeners } from "../gateway/ports.js";
|
|
2
|
+
import { isGatewayArgv, parseProcCmdline } from "./gateway-process-argv.js";
|
|
3
3
|
import fs from "node:fs";
|
|
4
4
|
import { spawnSync } from "node:child_process";
|
|
5
5
|
//#region src/infra/gateway-processes.ts
|
|
@@ -4,8 +4,8 @@ import { init_paths, resolveConfigPath } from "../config/paths.js";
|
|
|
4
4
|
import { init_loader, loadConfig } from "../config/loader.js";
|
|
5
5
|
import { isRestartEnabled } from "../config/commands.flags.js";
|
|
6
6
|
import { resolveGatewayService } from "../daemon/service.js";
|
|
7
|
-
import { findVerifiedGatewayListenerPidsOnPortSync, signalVerifiedGatewayPidSync } from "./gateway-processes.js";
|
|
8
7
|
import { authorizeGatewaySigusr1Restart, writeGatewayRestartIntentSync } from "./restart.js";
|
|
8
|
+
import { findVerifiedGatewayListenerPidsOnPortSync, signalVerifiedGatewayPidSync } from "./gateway-processes.js";
|
|
9
9
|
import { refreshGatewayServiceAfterUpdate } from "./update-service-refresh.js";
|
|
10
10
|
//#region src/infra/update-restart.ts
|
|
11
11
|
init_loader();
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { runPostUpdateExtensionSync } from "../extensions/update.js";
|
|
2
|
+
import "./update-channels.js";
|
|
3
|
+
import { compareSemver, resolveNpmChannelTag } from "./update-check.js";
|
|
2
4
|
import { readPackageName, readPackageVersion } from "./package-json.js";
|
|
3
5
|
import { createDefaultCommandRunner, runCommandWithTimeout } from "./run-command.js";
|
|
4
6
|
import { XOPC_PACKAGE_NAME, cleanupGlobalRenameDirs, createGlobalInstallEnv, detectGlobalInstallManagerForRoot, resolveGlobalInstallSpec, resolveGlobalInstallTarget } from "./update-global.js";
|
|
5
7
|
import { runGlobalPackageUpdateSteps } from "./package-update-steps.js";
|
|
6
8
|
import { resolveStableNodePath } from "./stable-node-path.js";
|
|
7
|
-
import "./update-channels.js";
|
|
8
|
-
import { compareSemver, resolveNpmChannelTag } from "./update-check.js";
|
|
9
9
|
import { trimLogTail } from "./update-log.js";
|
|
10
10
|
import { maybeRestartGatewayAfterUpdate } from "./update-restart.js";
|
|
11
11
|
import path from "node:path";
|
|
@@ -3,9 +3,9 @@ import { init_paths_state, resolveUpdateCheckStatePath } from "../config/paths-s
|
|
|
3
3
|
import { createLogger } from "../utils/logger/index.js";
|
|
4
4
|
import { init_logger } from "../utils/logger.js";
|
|
5
5
|
import { init_write_file_atomic, writeTextAtomic } from "./write-file-atomic.js";
|
|
6
|
+
import { acquireUpdateLock } from "./update-lock.js";
|
|
6
7
|
import { normalizeUpdateChannel } from "./update-channels.js";
|
|
7
8
|
import { compareSemver, detectInstallKind, resolveNpmChannelTag, resolvePackageRoot } from "./update-check.js";
|
|
8
|
-
import { acquireUpdateLock } from "./update-lock.js";
|
|
9
9
|
import { createHash, randomUUID } from "node:crypto";
|
|
10
10
|
import { readFile } from "node:fs/promises";
|
|
11
11
|
//#region src/infra/update-startup.ts
|
|
@@ -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 { init_loader, loadConfig } from "../config/loader.js";
|
|
4
|
+
import { gatewayCredentialAuthorization } from "../gateway/credential.js";
|
|
4
5
|
import { loadUndiciRuntimeDeps } from "../infra/undici-fetch.js";
|
|
5
6
|
import { toConversation } from "./channel-shared.js";
|
|
6
|
-
import { gatewayCredentialAuthorization } from "../gateway/credential.js";
|
|
7
7
|
import { createGatewayHttpClientFromConfig, resolveGatewayHttpBaseUrl } from "./gateway-http-client.js";
|
|
8
8
|
//#region src/mcp/channel-bridge.ts
|
|
9
9
|
init_loader();
|
|
@@ -4,5 +4,6 @@ export declare function mobileNotificationEventFromGatewayEvent(type: string, pa
|
|
|
4
4
|
export declare class MobileNotificationService {
|
|
5
5
|
private readonly sent;
|
|
6
6
|
handleGatewayEvent(type: string, payload: unknown): void;
|
|
7
|
+
deliverGatewayEvent(type: string, payload: unknown): Promise<void>;
|
|
7
8
|
private deliver;
|
|
8
9
|
}
|
|
@@ -9,6 +9,7 @@ function shouldDeliver(type, preferences) {
|
|
|
9
9
|
if (type === "goal.needs_input") return preferences.needsInput;
|
|
10
10
|
if (type === "goal.blocked") return preferences.failed;
|
|
11
11
|
if (type === "automation.failed") return preferences.automationFailed;
|
|
12
|
+
if (type === "proactive.insight") return preferences.needsInput;
|
|
12
13
|
return preferences.completed;
|
|
13
14
|
}
|
|
14
15
|
function goalEvent(payload) {
|
|
@@ -66,10 +67,33 @@ function automationEvent(payload) {
|
|
|
66
67
|
}
|
|
67
68
|
};
|
|
68
69
|
}
|
|
70
|
+
function proactiveInsightEvent(payload) {
|
|
71
|
+
if (!payload || typeof payload !== "object") return null;
|
|
72
|
+
const item = payload;
|
|
73
|
+
if (typeof item.id !== "string" || typeof item.insight?.id !== "string" || typeof item.insight.title !== "string") return null;
|
|
74
|
+
const route = `/inbox?item=${encodeURIComponent(item.id)}`;
|
|
75
|
+
return {
|
|
76
|
+
type: "proactive.insight",
|
|
77
|
+
entity: {
|
|
78
|
+
kind: "insight",
|
|
79
|
+
id: item.insight.id
|
|
80
|
+
},
|
|
81
|
+
priority: item.insight.urgency === "high" || item.insight.urgency === "critical" ? "high" : "normal",
|
|
82
|
+
title: item.insight.title.slice(0, 120),
|
|
83
|
+
body: typeof item.insight.summary === "string" ? item.insight.summary.slice(0, 180) : void 0,
|
|
84
|
+
deepLink: route,
|
|
85
|
+
payload: {
|
|
86
|
+
route,
|
|
87
|
+
inboxItemId: item.id,
|
|
88
|
+
eventType: "proactive.insight"
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
}
|
|
69
92
|
/** Converts gateway domain events into a portable mobile activity and push payload. */
|
|
70
93
|
function mobileNotificationEventFromGatewayEvent(type, payload) {
|
|
71
94
|
if (type === "goal.status.updated") return goalEvent(payload);
|
|
72
95
|
if (type === "automation.run.completed") return automationEvent(payload);
|
|
96
|
+
if (type === "proactive.inbox.created") return proactiveInsightEvent(payload);
|
|
73
97
|
return null;
|
|
74
98
|
}
|
|
75
99
|
async function sendExpoPush(token, event) {
|
|
@@ -105,33 +129,29 @@ async function sendExpoPush(token, event) {
|
|
|
105
129
|
var MobileNotificationService = class {
|
|
106
130
|
sent = /* @__PURE__ */ new Set();
|
|
107
131
|
handleGatewayEvent(type, payload) {
|
|
132
|
+
this.deliverGatewayEvent(type, payload).catch((err) => {
|
|
133
|
+
log.warn({
|
|
134
|
+
err,
|
|
135
|
+
eventType: type
|
|
136
|
+
}, "Mobile notification delivery failed");
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
async deliverGatewayEvent(type, payload) {
|
|
108
140
|
const event = mobileNotificationEventFromGatewayEvent(type, payload);
|
|
109
141
|
if (!event) return;
|
|
110
142
|
const dedupeKey = `${event.type}:${event.entity.kind}:${event.entity.id}:${JSON.stringify(event.payload)}`;
|
|
111
143
|
if (this.sent.has(dedupeKey)) return;
|
|
112
144
|
this.sent.add(dedupeKey);
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
}, "Mobile notification delivery failed");
|
|
119
|
-
}).finally(() => this.sent.delete(dedupeKey));
|
|
145
|
+
try {
|
|
146
|
+
await this.deliver(event);
|
|
147
|
+
} finally {
|
|
148
|
+
this.sent.delete(dedupeKey);
|
|
149
|
+
}
|
|
120
150
|
}
|
|
121
151
|
async deliver(input) {
|
|
122
152
|
const event = createMobileActivityEvent(input);
|
|
123
153
|
const devices = listEnabledMobileDevices().filter((device) => shouldDeliver(event.type, device.preferences));
|
|
124
|
-
await Promise.all(devices.map(
|
|
125
|
-
try {
|
|
126
|
-
await sendExpoPush(device.pushToken, event);
|
|
127
|
-
} catch (err) {
|
|
128
|
-
log.warn({
|
|
129
|
-
err,
|
|
130
|
-
eventId: event.id,
|
|
131
|
-
deviceId: device.id
|
|
132
|
-
}, "Mobile push request failed");
|
|
133
|
-
}
|
|
134
|
-
}));
|
|
154
|
+
await Promise.all(devices.map((device) => sendExpoPush(device.pushToken, event)));
|
|
135
155
|
}
|
|
136
156
|
};
|
|
137
157
|
//#endregion
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export type MobilePlatform = 'ios' | 'android';
|
|
2
2
|
export type MobileNotificationPermission = 'granted' | 'denied' | 'unknown';
|
|
3
3
|
export type MobileNotificationPriority = 'normal' | 'high';
|
|
4
|
-
export type MobileNotificationEventType = 'goal.needs_input' | 'goal.blocked' | 'goal.completed' | 'automation.failed' | 'automation.completed';
|
|
4
|
+
export type MobileNotificationEventType = 'goal.needs_input' | 'goal.blocked' | 'goal.completed' | 'automation.failed' | 'automation.completed' | 'proactive.insight';
|
|
5
5
|
export type MobileNotificationPreferences = {
|
|
6
6
|
needsInput: boolean;
|
|
7
7
|
failed: boolean;
|
|
@@ -24,7 +24,7 @@ export type MobileActivityEvent = {
|
|
|
24
24
|
id: string;
|
|
25
25
|
type: MobileNotificationEventType;
|
|
26
26
|
entity: {
|
|
27
|
-
kind: 'goal' | 'automation';
|
|
27
|
+
kind: 'goal' | 'automation' | 'insight';
|
|
28
28
|
id: string;
|
|
29
29
|
};
|
|
30
30
|
priority: MobileNotificationPriority;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { EVENT_ACTOR_KINDS, EVENT_SENSITIVITIES } from "./types.js";
|
|
2
|
+
import { randomUUID } from "node:crypto";
|
|
3
|
+
//#region src/proactive/events/envelope.ts
|
|
4
|
+
const EVENT_TYPE_PATTERN = /^[a-z][a-z0-9_]*(?:\.[a-z][a-z0-9_]*)+\.v[1-9][0-9]*$/;
|
|
5
|
+
function required(value, field) {
|
|
6
|
+
const normalized = value.trim();
|
|
7
|
+
if (!normalized) throw new Error(`${field} is required`);
|
|
8
|
+
if (normalized.length > 300) throw new Error(`${field} is too long`);
|
|
9
|
+
return normalized;
|
|
10
|
+
}
|
|
11
|
+
function timestamp(value, field) {
|
|
12
|
+
const time = Date.parse(value);
|
|
13
|
+
if (!Number.isFinite(time)) throw new Error(`${field} must be an ISO timestamp`);
|
|
14
|
+
return new Date(time).toISOString();
|
|
15
|
+
}
|
|
16
|
+
function normalizeEventEnvelope(input, now = /* @__PURE__ */ new Date()) {
|
|
17
|
+
if (!EVENT_TYPE_PATTERN.test(input.type)) throw new Error("type must use the domain.event.vN convention");
|
|
18
|
+
if (!Number.isInteger(input.schemaVersion) || input.schemaVersion < 1) throw new Error("schemaVersion must be a positive integer");
|
|
19
|
+
if (!EVENT_ACTOR_KINDS.includes(input.actor.kind)) throw new Error("actor.kind is invalid");
|
|
20
|
+
if (!EVENT_SENSITIVITIES.includes(input.sensitivity)) throw new Error("sensitivity is invalid");
|
|
21
|
+
if (!input.payload || Array.isArray(input.payload) || typeof input.payload !== "object") throw new Error("payload must be an object");
|
|
22
|
+
return {
|
|
23
|
+
id: required(input.id ?? randomUUID(), "id"),
|
|
24
|
+
type: input.type,
|
|
25
|
+
schemaVersion: input.schemaVersion,
|
|
26
|
+
source: {
|
|
27
|
+
kind: required(input.source.kind, "source.kind"),
|
|
28
|
+
id: required(input.source.id, "source.id"),
|
|
29
|
+
...input.source.deviceId ? { deviceId: required(input.source.deviceId, "source.deviceId") } : {}
|
|
30
|
+
},
|
|
31
|
+
subject: {
|
|
32
|
+
kind: required(input.subject.kind, "subject.kind"),
|
|
33
|
+
id: required(input.subject.id, "subject.id")
|
|
34
|
+
},
|
|
35
|
+
actor: {
|
|
36
|
+
kind: input.actor.kind,
|
|
37
|
+
...input.actor.id ? { id: required(input.actor.id, "actor.id") } : {}
|
|
38
|
+
},
|
|
39
|
+
scope: {
|
|
40
|
+
workspaceId: required(input.scope.workspaceId, "scope.workspaceId"),
|
|
41
|
+
...input.scope.projectId ? { projectId: required(input.scope.projectId, "scope.projectId") } : {},
|
|
42
|
+
...input.scope.agentId ? { agentId: required(input.scope.agentId, "scope.agentId") } : {}
|
|
43
|
+
},
|
|
44
|
+
occurredAt: timestamp(input.occurredAt, "occurredAt"),
|
|
45
|
+
observedAt: timestamp(input.observedAt ?? now.toISOString(), "observedAt"),
|
|
46
|
+
correlationId: required(input.correlationId ?? randomUUID(), "correlationId"),
|
|
47
|
+
...input.causationId ? { causationId: required(input.causationId, "causationId") } : {},
|
|
48
|
+
dedupeKey: required(input.dedupeKey, "dedupeKey"),
|
|
49
|
+
sensitivity: input.sensitivity,
|
|
50
|
+
payload: input.payload
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
//#endregion
|
|
54
|
+
export { normalizeEventEnvelope };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { EventEnvelope } from './types.js';
|
|
2
|
+
export declare function getEventByDedupeKey(dedupeKey: string): EventEnvelope | null;
|
|
3
|
+
export declare function insertEvent(event: EventEnvelope): boolean;
|
|
4
|
+
export declare function isEventRouted(eventId: string): boolean;
|
|
5
|
+
export declare function markEventRouted(eventId: string, routedAt: string): void;
|
|
6
|
+
export declare function listEvents(input?: {
|
|
7
|
+
limit?: number;
|
|
8
|
+
type?: string;
|
|
9
|
+
}): EventEnvelope[];
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { getSqliteDatabase, runSqliteWriteTransaction } from "../../storage/sqlite/transaction.js";
|
|
2
|
+
//#region src/proactive/events/repository.ts
|
|
3
|
+
function fromRow(row) {
|
|
4
|
+
return {
|
|
5
|
+
id: row.event_id,
|
|
6
|
+
type: row.type,
|
|
7
|
+
schemaVersion: row.schema_version,
|
|
8
|
+
source: {
|
|
9
|
+
kind: row.source_kind,
|
|
10
|
+
id: row.source_id,
|
|
11
|
+
...row.device_id ? { deviceId: row.device_id } : {}
|
|
12
|
+
},
|
|
13
|
+
subject: {
|
|
14
|
+
kind: row.subject_kind,
|
|
15
|
+
id: row.subject_id
|
|
16
|
+
},
|
|
17
|
+
actor: {
|
|
18
|
+
kind: row.actor_kind,
|
|
19
|
+
...row.actor_id ? { id: row.actor_id } : {}
|
|
20
|
+
},
|
|
21
|
+
scope: {
|
|
22
|
+
workspaceId: row.workspace_id,
|
|
23
|
+
...row.project_id ? { projectId: row.project_id } : {},
|
|
24
|
+
...row.agent_id ? { agentId: row.agent_id } : {}
|
|
25
|
+
},
|
|
26
|
+
occurredAt: row.occurred_at,
|
|
27
|
+
observedAt: row.observed_at,
|
|
28
|
+
correlationId: row.correlation_id,
|
|
29
|
+
...row.causation_id ? { causationId: row.causation_id } : {},
|
|
30
|
+
dedupeKey: row.dedupe_key,
|
|
31
|
+
sensitivity: row.sensitivity,
|
|
32
|
+
payload: JSON.parse(row.payload_json)
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
function getEventByDedupeKey(dedupeKey) {
|
|
36
|
+
const row = getSqliteDatabase().prepare("SELECT * FROM proactive_events WHERE dedupe_key = ?").get(dedupeKey);
|
|
37
|
+
return row ? fromRow(row) : null;
|
|
38
|
+
}
|
|
39
|
+
function insertEvent(event) {
|
|
40
|
+
return runSqliteWriteTransaction((db) => {
|
|
41
|
+
return db.prepare(`INSERT OR IGNORE INTO proactive_events (
|
|
42
|
+
event_id, type, schema_version, source_kind, source_id, device_id,
|
|
43
|
+
subject_kind, subject_id, actor_kind, actor_id, workspace_id, project_id, agent_id,
|
|
44
|
+
occurred_at, observed_at, correlation_id, causation_id, dedupe_key, sensitivity, payload_json
|
|
45
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(event.id, event.type, event.schemaVersion, event.source.kind, event.source.id, event.source.deviceId ?? null, event.subject.kind, event.subject.id, event.actor.kind, event.actor.id ?? null, event.scope.workspaceId, event.scope.projectId ?? null, event.scope.agentId ?? null, event.occurredAt, event.observedAt, event.correlationId, event.causationId ?? null, event.dedupeKey, event.sensitivity, JSON.stringify(event.payload)).changes === 1;
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
function isEventRouted(eventId) {
|
|
49
|
+
const row = getSqliteDatabase().prepare("SELECT routed_at FROM proactive_events WHERE event_id = ?").get(eventId);
|
|
50
|
+
return Boolean(row?.routed_at);
|
|
51
|
+
}
|
|
52
|
+
function markEventRouted(eventId, routedAt) {
|
|
53
|
+
runSqliteWriteTransaction((db) => {
|
|
54
|
+
db.prepare("UPDATE proactive_events SET routed_at = COALESCE(routed_at, ?) WHERE event_id = ?").run(routedAt, eventId);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
function listEvents(input = {}) {
|
|
58
|
+
const limit = Math.min(200, Math.max(1, input.limit ?? 50));
|
|
59
|
+
return (input.type ? getSqliteDatabase().prepare("SELECT * FROM proactive_events WHERE type = ? ORDER BY observed_at DESC LIMIT ?").all(input.type, limit) : getSqliteDatabase().prepare("SELECT * FROM proactive_events ORDER BY observed_at DESC LIMIT ?").all(limit)).map(fromRow);
|
|
60
|
+
}
|
|
61
|
+
//#endregion
|
|
62
|
+
export { getEventByDedupeKey, insertEvent, isEventRouted, listEvents, markEventRouted };
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export declare const EVENT_SENSITIVITIES: readonly ["public", "personal", "confidential", "restricted"];
|
|
2
|
+
export type EventSensitivity = (typeof EVENT_SENSITIVITIES)[number];
|
|
3
|
+
export declare const EVENT_ACTOR_KINDS: readonly ["user", "agent", "system", "integration"];
|
|
4
|
+
export type EventActorKind = (typeof EVENT_ACTOR_KINDS)[number];
|
|
5
|
+
export interface EventEnvelope<TPayload extends Record<string, unknown> = Record<string, unknown>> {
|
|
6
|
+
id: string;
|
|
7
|
+
type: string;
|
|
8
|
+
schemaVersion: number;
|
|
9
|
+
source: {
|
|
10
|
+
kind: string;
|
|
11
|
+
id: string;
|
|
12
|
+
deviceId?: string;
|
|
13
|
+
};
|
|
14
|
+
subject: {
|
|
15
|
+
kind: string;
|
|
16
|
+
id: string;
|
|
17
|
+
};
|
|
18
|
+
actor: {
|
|
19
|
+
kind: EventActorKind;
|
|
20
|
+
id?: string;
|
|
21
|
+
};
|
|
22
|
+
scope: {
|
|
23
|
+
workspaceId: string;
|
|
24
|
+
projectId?: string;
|
|
25
|
+
agentId?: string;
|
|
26
|
+
};
|
|
27
|
+
occurredAt: string;
|
|
28
|
+
observedAt: string;
|
|
29
|
+
correlationId: string;
|
|
30
|
+
causationId?: string;
|
|
31
|
+
dedupeKey: string;
|
|
32
|
+
sensitivity: EventSensitivity;
|
|
33
|
+
payload: TPayload;
|
|
34
|
+
}
|
|
35
|
+
export type PublishEventInput<TPayload extends Record<string, unknown> = Record<string, unknown>> = Omit<EventEnvelope<TPayload>, 'id' | 'observedAt' | 'correlationId'> & {
|
|
36
|
+
id?: string;
|
|
37
|
+
observedAt?: string;
|
|
38
|
+
correlationId?: string;
|
|
39
|
+
};
|
|
40
|
+
export interface PublishedEvent {
|
|
41
|
+
event: EventEnvelope;
|
|
42
|
+
inserted: boolean;
|
|
43
|
+
batchIds: string[];
|
|
44
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
//#region src/proactive/events/types.ts
|
|
2
|
+
const EVENT_SENSITIVITIES = [
|
|
3
|
+
"public",
|
|
4
|
+
"personal",
|
|
5
|
+
"confidential",
|
|
6
|
+
"restricted"
|
|
7
|
+
];
|
|
8
|
+
const EVENT_ACTOR_KINDS = [
|
|
9
|
+
"user",
|
|
10
|
+
"agent",
|
|
11
|
+
"system",
|
|
12
|
+
"integration"
|
|
13
|
+
];
|
|
14
|
+
//#endregion
|
|
15
|
+
export { EVENT_ACTOR_KINDS, EVENT_SENSITIVITIES };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Config } from '../../config/schema.js';
|
|
2
|
+
import type { ProactiveAgentExecutor } from './types.js';
|
|
3
|
+
/** Runs an isolated, read-only agent over only the context authorized by the signal batch. */
|
|
4
|
+
export declare class ReadonlyProactiveAgentExecutor implements ProactiveAgentExecutor {
|
|
5
|
+
private readonly config;
|
|
6
|
+
constructor(config: () => Config | undefined);
|
|
7
|
+
execute(input: {
|
|
8
|
+
systemPrompt: string;
|
|
9
|
+
userPrompt: string;
|
|
10
|
+
authorizedContext: Record<string, unknown>;
|
|
11
|
+
signal?: AbortSignal;
|
|
12
|
+
}): Promise<{
|
|
13
|
+
text: string;
|
|
14
|
+
modelRef: string;
|
|
15
|
+
}>;
|
|
16
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { init_sync_provider_auth, resolveProviderApiKeySync } from "../../auth/sync-provider-auth.js";
|
|
2
|
+
import { getApiKeySync, getDefaultModelSync, init_providers, resolveModel } from "../../providers/index.js";
|
|
3
|
+
import { createExtensionAwareStreamFn } from "../../providers/extension-stream-bridge.js";
|
|
4
|
+
import { runAgentTurnWithTimeout } from "../../agent/orchestration/run-agent-turn-with-timeout.js";
|
|
5
|
+
import { isAssistantTurnAborted, isAssistantTurnFailed } from "../../agent/orchestration/llm-turn-retry.js";
|
|
6
|
+
import { Agent } from "@earendil-works/pi-agent-core";
|
|
7
|
+
import { Type } from "@sinclair/typebox";
|
|
8
|
+
//#region src/proactive/execution/agent-executor.ts
|
|
9
|
+
init_sync_provider_auth();
|
|
10
|
+
init_providers();
|
|
11
|
+
const MAX_TOOL_CALLS = 6;
|
|
12
|
+
const AGENT_TIMEOUT_MS = 9e4;
|
|
13
|
+
function assistantText(messages) {
|
|
14
|
+
for (let index = messages.length - 1; index >= 0; index -= 1) {
|
|
15
|
+
const message = messages[index];
|
|
16
|
+
if (message.role !== "assistant") continue;
|
|
17
|
+
if (Array.isArray(message.content)) return message.content.flatMap((block) => block && typeof block === "object" && block.type === "text" ? [String(block.text ?? "")] : []).join("").trim();
|
|
18
|
+
}
|
|
19
|
+
return "";
|
|
20
|
+
}
|
|
21
|
+
function inspectionTool(context) {
|
|
22
|
+
return {
|
|
23
|
+
name: "inspect_authorized_context",
|
|
24
|
+
label: "Inspect authorized work context",
|
|
25
|
+
description: "Read one authorized evidence section. This tool cannot write or trigger any action.",
|
|
26
|
+
parameters: Type.Object({ section: Type.String({ description: "A top-level section name from the availableSections list." }) }),
|
|
27
|
+
async execute(_toolCallId, args) {
|
|
28
|
+
const values = args;
|
|
29
|
+
const section = typeof values.section === "string" ? values.section : "";
|
|
30
|
+
if (!Object.prototype.hasOwnProperty.call(context, section)) return {
|
|
31
|
+
content: [{
|
|
32
|
+
type: "text",
|
|
33
|
+
text: `Unknown section. Available: ${Object.keys(context).join(", ")}`
|
|
34
|
+
}],
|
|
35
|
+
details: { found: false }
|
|
36
|
+
};
|
|
37
|
+
return {
|
|
38
|
+
content: [{
|
|
39
|
+
type: "text",
|
|
40
|
+
text: JSON.stringify({
|
|
41
|
+
section,
|
|
42
|
+
evidence: context[section]
|
|
43
|
+
}, null, 2).slice(0, 6e4)
|
|
44
|
+
}],
|
|
45
|
+
details: {
|
|
46
|
+
found: true,
|
|
47
|
+
section
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/** Runs an isolated, read-only agent over only the context authorized by the signal batch. */
|
|
54
|
+
var ReadonlyProactiveAgentExecutor = class {
|
|
55
|
+
constructor(config) {
|
|
56
|
+
this.config = config;
|
|
57
|
+
}
|
|
58
|
+
async execute(input) {
|
|
59
|
+
const model = resolveModel(getDefaultModelSync(this.config()));
|
|
60
|
+
let toolCalls = 0;
|
|
61
|
+
const agent = new Agent({
|
|
62
|
+
initialState: {
|
|
63
|
+
systemPrompt: `${input.systemPrompt}\n\nYou are an autonomous background analysis agent. You MUST inspect relevant authorized context with the provided read-only tool before reaching a conclusion. You have no mutation, messaging, shell, network, or filesystem tools.`,
|
|
64
|
+
model,
|
|
65
|
+
thinkingLevel: "low",
|
|
66
|
+
tools: [inspectionTool(input.authorizedContext)],
|
|
67
|
+
messages: []
|
|
68
|
+
},
|
|
69
|
+
streamFn: createExtensionAwareStreamFn(),
|
|
70
|
+
getApiKey: (provider) => resolveProviderApiKeySync(provider) ?? getApiKeySync(provider) ?? "",
|
|
71
|
+
beforeToolCall: async () => {
|
|
72
|
+
if (toolCalls >= MAX_TOOL_CALLS) return {
|
|
73
|
+
block: true,
|
|
74
|
+
reason: `Maximum inspection calls reached (${MAX_TOOL_CALLS}).`
|
|
75
|
+
};
|
|
76
|
+
},
|
|
77
|
+
afterToolCall: async () => {
|
|
78
|
+
toolCalls += 1;
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
const abort = () => agent.abort();
|
|
82
|
+
input.signal?.addEventListener("abort", abort, { once: true });
|
|
83
|
+
try {
|
|
84
|
+
const sections = Object.keys(input.authorizedContext);
|
|
85
|
+
await runAgentTurnWithTimeout(agent, async () => {
|
|
86
|
+
await agent.prompt(`${input.userPrompt}\n\nAvailable authorized evidence sections: ${sections.join(", ") || "(none)"}.`);
|
|
87
|
+
await agent.waitForIdle();
|
|
88
|
+
}, AGENT_TIMEOUT_MS);
|
|
89
|
+
if (isAssistantTurnAborted(agent)) throw new Error("Proactive agent execution aborted");
|
|
90
|
+
if (isAssistantTurnFailed(agent)) throw new Error("Proactive agent execution failed");
|
|
91
|
+
const text = assistantText(agent.state.messages);
|
|
92
|
+
if (!text) throw new Error("Proactive agent returned empty output");
|
|
93
|
+
if (toolCalls === 0) throw new Error("Proactive agent did not inspect authorized evidence");
|
|
94
|
+
return {
|
|
95
|
+
text,
|
|
96
|
+
modelRef: `${model.provider}/${model.id}`
|
|
97
|
+
};
|
|
98
|
+
} finally {
|
|
99
|
+
input.signal?.removeEventListener("abort", abort);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
//#endregion
|
|
104
|
+
export { ReadonlyProactiveAgentExecutor };
|