@xopcai/xopc 0.0.267 → 0.0.269
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/dist/assets/{auth-D_IL6naL.js → auth-cwEj8rFb.js} +140 -29
- package/dist/browser-ext/dist/assets/sidepanel-C86O7q5Y.css +299 -0
- package/dist/browser-ext/dist/background.js +2 -2
- package/dist/browser-ext/dist/sidepanel.html +2 -2
- package/dist/browser-ext/dist/sidepanel.js +9501 -427
- 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-Bhyy6ENz.js → activity-store-DcwCSY6s.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-ZrSAMchm.js → agent-avatar-dicebear-D0NBOWC4.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-defaults-settings-panel-DiNFN8qS.js → agent-defaults-settings-panel-qKCezlBg.js} +1 -1
- package/dist/gateway/static/root/assets/agents-BMhnZKhP.js +1 -0
- package/dist/gateway/static/root/assets/{api-B2y7ZjZk.js → api-eaPO-mdr.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-D-L6yjS7.js → app-management-settings-panel-E3xm2teY.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-BW5eb53j.js → appearance-settings-CiZOjgls.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-DduJDWGY.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-DwXvu1p9.js → archive-plugin-D09yo_Hc.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-DqU2BYBp.js → attachment-load-CNYb8Qru.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-C7qoj9Sd.js → automations-page-DsrfW5ii.js} +1 -1
- package/dist/gateway/static/root/assets/automations-workspace-X7hNHCjW.js +6 -0
- package/dist/gateway/static/root/assets/{binary-plugins-CfplDak2.js → binary-plugins-OWlaGqlY.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-CzLs38ru.js → block-editor-CVND3M6r.js} +3 -3
- package/dist/gateway/static/root/assets/{browser-automation-inputs-s5I78Iko.js → browser-automation-inputs-D7IzVK_J.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-automations-page-_SKi8s9b.js → browser-automations-page-CQ6cCpIv.js} +2 -2
- package/dist/gateway/static/root/assets/browser-settings-page-BZ7nK_pN.js +8 -0
- package/dist/gateway/static/root/assets/capabilities-settings-panel-BfKvJO1C.js +7 -0
- package/dist/gateway/static/root/assets/channels-settings-D1UDxJuA.js +1 -0
- package/dist/gateway/static/root/assets/{channels-status-swr-_OsWr_vS.js → channels-status-swr-D4JrgJKa.js} +1 -1
- package/dist/gateway/static/root/assets/{chat-terminal-dock-snvAu3hJ.js → chat-terminal-dock-BUjnhT7C.js} +2 -2
- package/dist/gateway/static/root/assets/connectors-page-C2nuqs_O.js +2 -0
- package/dist/gateway/static/root/assets/{cron-expression-BhGZSbT6.js → cron-expression-DlyRIyUn.js} +1 -1
- package/dist/gateway/static/root/assets/{date-picker-Cep5f9b-.js → date-picker-CU-ij_yE.js} +1 -1
- package/dist/gateway/static/root/assets/{dependency-picker-BzSEBQku.js → dependency-picker-Z6Nf0Wjq.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-BwX_6Gah.js → desktop-pet-C0F5Iqnc.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-WrbVsU2b.js → desktop-pet-settings-Bj_W6HL1.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-BdXSwtAZ.js → extension-debug-page-Ba09EnAn.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-I95ukbRb.js → extension-page-C88aGXJs.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-8zUisBay.js → extension-settings-page-CMyt0A32.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-swr-OObCK8jM.js → gateway-config-swr-bjzk_4hn.js} +1 -1
- package/dist/gateway/static/root/assets/gateway-settings-ogv8ZbvG.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-startup-retry-D_TxKN_A.js → gateway-startup-retry-DrbIzFyB.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-settings-BGQxU-Ug.js → heartbeat-settings-BnrMRKaZ.js} +1 -1
- package/dist/gateway/static/root/assets/home-page-CbcJCREd.js +1 -0
- package/dist/gateway/static/root/assets/{image-generation-api-fPU9yGsw.js → image-generation-api-CBWU9Ner.js} +1 -1
- package/dist/gateway/static/root/assets/index-7PZ6jmhy.css +2 -0
- package/dist/gateway/static/root/assets/{index-D2OtD9Wa.js → index-CfyyA9-g.js} +47 -47
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-BUe_om99.js → keyboard-shortcuts-settings-B8Z7kKQY.js} +1 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-D5XVZnK1.js +2 -0
- package/dist/gateway/static/root/assets/{local-apps-page-BZaLzfms.js → local-apps-page-CLSfzkRp.js} +1 -1
- package/dist/gateway/static/root/assets/{locale-store-DFQX9kTl.js → locale-store-BQ2HKTWb.js} +1 -1
- package/dist/gateway/static/root/assets/logs-page-CWDU1AGN.js +2 -0
- package/dist/gateway/static/root/assets/{management-settings-Duf8w-Bl.js → management-settings-CuFNgQUy.js} +1 -1
- package/dist/gateway/static/root/assets/{markdown-view-D-5jHRWg.js → markdown-view-DIcfrLmG.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-2-QfzHmg.js → media-plugins-CSv6-xTA.js} +1 -1
- package/dist/gateway/static/root/assets/{messages-Dj8QuS6e.js → messages-BRjoarIr.js} +2 -2
- package/dist/gateway/static/root/assets/{mobile-pairing-wizard-DRaVIAt1.js → mobile-pairing-wizard-C7d_ztgp.js} +1 -1
- package/dist/gateway/static/root/assets/note-detail-panel-D5JuBLyt.js +5 -0
- package/dist/gateway/static/root/assets/notes-page-C5-ccCi4.js +8 -0
- package/dist/gateway/static/root/assets/{page-tabs-DaZ7QpNO.js → page-tabs-BfV-PQa5.js} +1 -1
- package/dist/gateway/static/root/assets/{preview-open-alternatives-CWEuqCmv.js → preview-open-alternatives-DQS7NFpg.js} +1 -1
- package/dist/gateway/static/root/assets/proactive-page-fHjPigmx.js +1 -0
- package/dist/gateway/static/root/assets/{product-open-page-CIGLPFm7.js → product-open-page-BIhjZLKg.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-6v_khvEt.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-CCy1aK4V.js +1 -0
- package/dist/gateway/static/root/assets/{registry-api-CsZLatKo.js → registry-api-CwveUfe8.js} +1 -1
- package/dist/gateway/static/root/assets/remote-access-hub-pkqKRnch.js +1 -0
- package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-CslkSM-m.js → runtime-tools-settings-panel-DMQ0wpNg.js} +2 -2
- package/dist/gateway/static/root/assets/{schema-form-B2gvVrBq.js → schema-form-C91g2PRU.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-Cr4E4cap.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-D1JRDRyL.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-CmlnuSO3.js → settings-form-section-Cem6L49Y.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-DWWgyelT.js → settings-page-afDUxqlV.js} +1 -1
- package/dist/gateway/static/root/assets/{setup-status-panel-CJrN3m1o.js → setup-status-panel-Cc_iP_vv.js} +1 -1
- package/dist/gateway/static/root/assets/{share-preview-page-C12oyIKk.js → share-preview-page-CVEVHksg.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-BrMECMAB.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-DuqIDYjc.js +1 -0
- package/dist/gateway/static/root/assets/{skills-page-yhW7LLqk.js → skills-page-CNrq1W6C.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page.utils-FaTlq8t-.js → skills-page.utils-D1wGfm22.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-CMrkoJLN.js → system-settings-panel-BLE8PxWE.js} +1 -1
- package/dist/gateway/static/root/assets/task-detail-page-m0oXUKl2.js +1 -0
- package/dist/gateway/static/root/assets/{theme-store-zRT6vaZc.js → theme-store-BejLVjIT.js} +1 -1
- package/dist/gateway/static/root/assets/{tunnel-api-C2tAZaJz.js → tunnel-api-Dur80zSQ.js} +1 -1
- package/dist/gateway/static/root/assets/{use-autosave-BsDRt4QI.js → use-autosave-DmgEA8Qb.js} +1 -1
- package/dist/gateway/static/root/assets/user-model-page-Dl10D_5q.js +2 -0
- package/dist/gateway/static/root/assets/{voice-api-key-field-CS5heYMP.js → voice-api-key-field-sZ0J83SF.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-config-api-DpJEu2RQ.js → voice-config-api-BEbz3avx.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-overlay-BeSz5Th5.js → work-discovery-overlay-BXnAlbmO.js} +1 -1
- package/dist/gateway/static/root/assets/workflow-run-setup-panel-BkwFey0a.js +3 -0
- package/dist/gateway/static/root/assets/workflows-page-CswgoIFU.js +6 -0
- package/dist/gateway/static/root/index.html +10 -10
- package/dist/gateway/static/root/notification-sw.js +15 -0
- package/dist/package.js +1 -1
- package/dist/packages/gateway-contract/src/notifications.js +15 -1
- package/dist/packages/gateway-contract/src/proactive.js +104 -0
- package/dist/packages/realtime-protocol/src/voice.js +2 -1
- package/dist/src/agent/agent-manager.js +4 -4
- package/dist/src/agent/background-review/run-background-review.js +1 -1
- package/dist/src/agent/embedded/model-runtime.js +1 -1
- package/dist/src/agent/embedded/run-for-session.js +1 -1
- package/dist/src/agent/image/tool-model-config.js +1 -1
- package/dist/src/agent/mcp/oauth/mcp-oauth-store.js +1 -1
- package/dist/src/agent/service.js +2 -2
- package/dist/src/agent/session/session-inspector.js +1 -1
- package/dist/src/agent/skills/hub-lock.js +1 -1
- package/dist/src/agent/tasks/task-judge-service.js +3 -3
- package/dist/src/agent/workflow/subagent-runner.d.ts +1 -0
- package/dist/src/agent/workflow/subagent-runner.js +2 -2
- package/dist/src/ai-assist/text-assist.js +1 -1
- package/dist/src/auth/credentials.js +2 -2
- package/dist/src/auth/oauth/xopc-cloud.js +1 -1
- package/dist/src/auth/profiles/store.js +1 -1
- package/dist/src/auth/sync-provider-auth.js +2 -2
- package/dist/src/browser/providers/browser-ext-install.js +1 -1
- package/dist/src/browser/runtime/browser-runtime.js +3 -2
- package/dist/src/cli/commands/connectors.js +1 -1
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
- package/dist/src/cli/commands/models.js +1 -1
- package/dist/src/config/index.js +4 -4
- package/dist/src/config/loader.js +2 -2
- package/dist/src/config/models-json.js +1 -1
- package/dist/src/connectors/connected-source-ingestion.js +1 -1
- package/dist/src/connectors/connection-recovery-service.js +1 -1
- package/dist/src/connectors/health.js +1 -1
- package/dist/src/extensions/lockfile.js +1 -1
- package/dist/src/gateway/agents-admin.js +1 -1
- package/dist/src/gateway/file-path-classifier.js +1 -1
- package/dist/src/gateway/heartbeat/service.js +1 -1
- package/dist/src/gateway/hono/lib/config-payload.js +1 -1
- package/dist/src/gateway/hono/routes/capabilities.js +1 -1
- package/dist/src/gateway/hono/routes/connectors.js +1 -1
- package/dist/src/gateway/hono/routes/index.js +0 -2
- package/dist/src/gateway/hono/routes/lazy-bundles.js +12 -0
- package/dist/src/gateway/hono/routes/mcp.js +1 -1
- package/dist/src/gateway/hono/routes/models.js +1 -1
- package/dist/src/gateway/hono/routes/proactive-control.d.ts +3 -0
- package/dist/src/gateway/hono/routes/proactive-control.js +161 -0
- package/dist/src/gateway/hono/routes/proactive.d.ts +1 -1
- package/dist/src/gateway/hono/routes/proactive.js +12 -5
- package/dist/src/gateway/hono/routes/voice.js +1 -1
- package/dist/src/gateway/security/gateway-scopes.js +5 -0
- package/dist/src/gateway/service/config-coordinator.js +1 -1
- package/dist/src/gateway/service.d.ts +0 -1
- package/dist/src/gateway/service.js +28 -30
- package/dist/src/heartbeat/index.js +1 -1
- package/dist/src/notifications/planner.js +4 -3
- package/dist/src/notifications/proactive-channel.d.ts +8 -0
- package/dist/src/notifications/proactive-channel.js +57 -0
- package/dist/src/notifications/proactive-policy.d.ts +3 -0
- package/dist/src/notifications/proactive-policy.js +32 -0
- package/dist/src/notifications/service.d.ts +78 -0
- package/dist/src/notifications/service.js +71 -13
- package/dist/src/notifications/store.d.ts +2 -0
- package/dist/src/notifications/store.js +8 -1
- package/dist/src/notifications/web-push.d.ts +19 -0
- package/dist/src/notifications/web-push.js +182 -0
- package/dist/src/proactive/actions/service.js +10 -2
- package/dist/src/proactive/actions/workflow.d.ts +15 -0
- package/dist/src/proactive/actions/workflow.js +88 -0
- package/dist/src/proactive/execution/agent-executor.d.ts +5 -0
- package/dist/src/proactive/execution/agent-executor.js +21 -0
- package/dist/src/proactive/execution/authorization.d.ts +3 -0
- package/dist/src/proactive/execution/authorization.js +23 -0
- package/dist/src/proactive/execution/context.js +2 -11
- package/dist/src/proactive/execution/insight.d.ts +7 -0
- package/dist/src/proactive/execution/insight.js +33 -2
- package/dist/src/proactive/execution/repository.d.ts +2 -0
- package/dist/src/proactive/execution/repository.js +38 -4
- package/dist/src/proactive/execution/types.d.ts +5 -0
- package/dist/src/proactive/execution/worker.js +38 -7
- package/dist/src/proactive/inbox/cards.d.ts +21 -0
- package/dist/src/proactive/inbox/cards.js +237 -0
- package/dist/src/proactive/inbox/delivery.d.ts +6 -0
- package/dist/src/proactive/inbox/delivery.js +52 -0
- package/dist/src/proactive/inbox/digest.d.ts +8 -0
- package/dist/src/proactive/inbox/digest.js +112 -0
- package/dist/src/proactive/inbox/lifecycle.d.ts +4 -0
- package/dist/src/proactive/inbox/lifecycle.js +58 -0
- package/dist/src/proactive/inbox/notification-policy.d.ts +1 -0
- package/dist/src/proactive/inbox/notification-policy.js +20 -0
- package/dist/src/proactive/inbox/repository.d.ts +1 -0
- package/dist/src/proactive/inbox/repository.js +68 -11
- package/dist/src/proactive/inbox/types.d.ts +9 -1
- package/dist/src/proactive/inbox/worker.js +9 -3
- package/dist/src/proactive/index.js +1 -1
- package/dist/src/proactive/maintenance.js +7 -0
- package/dist/src/proactive/metrics.d.ts +10 -0
- package/dist/src/proactive/metrics.js +27 -0
- package/dist/src/proactive/policy/presence.d.ts +2 -0
- package/dist/src/proactive/policy/presence.js +27 -0
- package/dist/src/proactive/policy/service.d.ts +53 -0
- package/dist/src/proactive/policy/service.js +122 -0
- package/dist/src/proactive/routing/matcher.js +3 -2
- package/dist/src/proactive/scenarios/control.d.ts +90 -0
- package/dist/src/proactive/scenarios/control.js +109 -0
- package/dist/src/proactive/scenarios/preview.d.ts +13 -0
- package/dist/src/proactive/scenarios/preview.js +81 -0
- package/dist/src/proactive/scenarios/prompt-composer.js +2 -2
- package/dist/src/proactive/scenarios/repository.js +5 -1
- package/dist/src/proactive/temporal/schedule.d.ts +3 -0
- package/dist/src/proactive/temporal/schedule.js +67 -0
- package/dist/src/proactive/temporal/worker.js +8 -4
- package/dist/src/providers/auth-runtime/resolve-auth.js +1 -1
- package/dist/src/providers/index.js +2 -2
- package/dist/src/providers/model-registry.js +1 -1
- package/dist/src/providers/register-runtime-providers.js +1 -1
- package/dist/src/storage/sqlite/migrations/159_proactive_controls.sql +68 -0
- package/dist/src/storage/sqlite/migrations/160_proactive_web_push.sql +27 -0
- package/dist/src/storage/sqlite/migrations/161_proactive_delivery_and_lifecycle.sql +51 -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/tui/tui-startup-resources.js +2 -2
- package/dist/src/tui/tui.js +1 -1
- package/dist/src/voice/realtime/runtime.d.ts +2 -1
- package/dist/src/voice/realtime/runtime.js +21 -5
- package/dist/src/work-discovery/service.js +1 -1
- package/dist/src/workflows/domain/run.d.ts +1 -0
- package/dist/src/workflows/index.js +2 -2
- package/dist/src/workflows/service/workflow-run-service.d.ts +3 -0
- package/dist/src/workflows/service/workflow-run-service.js +27 -6
- package/dist/src/workflows/service/workflow-run-service.types.d.ts +1 -0
- package/package.json +3 -1
- package/dist/browser-ext/dist/assets/sidepanel-CEPaVLjr.css +0 -155
- package/dist/gateway/static/root/assets/agents-Bu6Hf59K.js +0 -1
- package/dist/gateway/static/root/assets/apps-page-CiQIdz3N.js +0 -1
- package/dist/gateway/static/root/assets/automations-workspace-CIARTLHO.js +0 -6
- package/dist/gateway/static/root/assets/browser-settings-page-DTdx66sX.js +0 -8
- package/dist/gateway/static/root/assets/capabilities-settings-panel-Ck9U0Olx.js +0 -7
- package/dist/gateway/static/root/assets/channels-settings-I_vDpbnl.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-BmKTnzo1.js +0 -2
- package/dist/gateway/static/root/assets/gateway-settings-DGj5b9Yv.js +0 -1
- package/dist/gateway/static/root/assets/home-page-BZPpK0A3.js +0 -1
- package/dist/gateway/static/root/assets/index-CRJrO4GI.css +0 -2
- package/dist/gateway/static/root/assets/local-app-workbench-page-CbQnffS9.js +0 -2
- package/dist/gateway/static/root/assets/logs-page-WWCHqW_x.js +0 -2
- package/dist/gateway/static/root/assets/note-detail-panel-BT-fWGxX.js +0 -5
- package/dist/gateway/static/root/assets/notes-page-C4705PzN.js +0 -8
- package/dist/gateway/static/root/assets/project-detail-page-BZegJ6an.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-B7hUHeLI.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-BE9hZpdh.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-DmAAPMo1.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-CvBocGDA.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-D4BtSiLq.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-CzKGn056.js +0 -1
- package/dist/gateway/static/root/assets/task-detail-page-BUaO62cy.js +0 -1
- package/dist/gateway/static/root/assets/user-model-page-Dy8h1SSJ.js +0 -2
- package/dist/gateway/static/root/assets/workflow-run-setup-panel-BebW0CDK.js +0 -3
- package/dist/gateway/static/root/assets/workflows-page-CU8jFgPF.js +0 -6
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { init_resolve_config_value, testApiKeyResolution } from "../../../config/resolve-config-value.js";
|
|
2
1
|
import { resolveModelsJsonPath } from "../../../config/paths.js";
|
|
2
|
+
import { init_resolve_config_value, testApiKeyResolution } from "../../../config/resolve-config-value.js";
|
|
3
3
|
import { init_models_json, loadModelsJson, saveModelsJson, validateModelsConfig } from "../../../config/models-json.js";
|
|
4
4
|
import { getModelCatalogStore, init_model_catalog_store } from "../../../providers/model-catalog-store.js";
|
|
5
5
|
import { getModelRegistry } from "../../../providers/model-registry.js";
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { getSqliteDatabase } from "../../../storage/sqlite/transaction.js";
|
|
2
|
+
import { getDefaultAgentId, init_resolve_route } from "../../../routing/resolve-route.js";
|
|
3
|
+
import { resolveProjectAgentId } from "../../../projects/project-agent.js";
|
|
4
|
+
import "../../../projects/index.js";
|
|
5
|
+
import { ProactiveConflict, proactivePreferences, updateProactivePreferences } from "../../../proactive/policy/service.js";
|
|
6
|
+
import { recordProactivePresence } from "../../../proactive/policy/presence.js";
|
|
7
|
+
import { controlledSubscriptions, createControlledSubscription, requireSubscription, templateCatalog, updateControlledSubscription } from "../../../proactive/scenarios/control.js";
|
|
8
|
+
import { cardChanges, getCard, listCards, performCardAction } from "../../../proactive/inbox/cards.js";
|
|
9
|
+
import { digestCards } from "../../../proactive/inbox/digest.js";
|
|
10
|
+
import { acknowledgeBrowserProbe, listBrowserProbes, prepareBrowserPush, registerBrowserPush, testBrowserPush, unregisterBrowserPush } from "../../../notifications/web-push.js";
|
|
11
|
+
import { ReadonlyProactiveAgentExecutor } from "../../../proactive/execution/agent-executor.js";
|
|
12
|
+
import { proactiveMetrics } from "../../../proactive/metrics.js";
|
|
13
|
+
import { prepareCardWorkflow, workflowForCard } from "../../../proactive/actions/workflow.js";
|
|
14
|
+
import { previewSubscription } from "../../../proactive/scenarios/preview.js";
|
|
15
|
+
import { ZodError } from "zod";
|
|
16
|
+
//#region src/gateway/hono/routes/proactive-control.ts
|
|
17
|
+
init_resolve_route();
|
|
18
|
+
function registerProactiveControlRoutes(app, deps) {
|
|
19
|
+
app.onError((error, c) => c.json({
|
|
20
|
+
ok: false,
|
|
21
|
+
error: error instanceof ZodError ? "Invalid request" : error.message
|
|
22
|
+
}, error instanceof ProactiveConflict ? 409 : 400));
|
|
23
|
+
const workspace = () => deps.service.currentWorkspacePath;
|
|
24
|
+
for (const path of ["/api/proactive/*", "/api/inbox/judgments/*"]) app.use(path, async (c, next) => {
|
|
25
|
+
try {
|
|
26
|
+
const id = c.req.path.match(/^\/api\/inbox\/judgments\/([^/]+)/)?.[1];
|
|
27
|
+
if (id && id !== "changes") getCard(decodeURIComponent(id), workspace());
|
|
28
|
+
await next();
|
|
29
|
+
} catch (error) {
|
|
30
|
+
return c.json({
|
|
31
|
+
ok: false,
|
|
32
|
+
error: error instanceof ZodError ? "Invalid request" : error instanceof Error ? error.message : "Request failed"
|
|
33
|
+
}, error instanceof ProactiveConflict ? 409 : 400);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
app.get("/api/proactive/web-push/probes", (c) => c.json({
|
|
37
|
+
ok: true,
|
|
38
|
+
probes: listBrowserProbes(workspace())
|
|
39
|
+
}));
|
|
40
|
+
app.post("/api/proactive/web-push/subscriptions/:id/test", deps.strictRateLimitMiddleware, async (c) => c.json({
|
|
41
|
+
ok: true,
|
|
42
|
+
...await testBrowserPush(workspace(), c.req.param("id"))
|
|
43
|
+
}));
|
|
44
|
+
app.post("/api/proactive/web-push/probes/:id/opened", deps.strictRateLimitMiddleware, (c) => {
|
|
45
|
+
acknowledgeBrowserProbe(workspace(), c.req.param("id"));
|
|
46
|
+
return c.json({ ok: true });
|
|
47
|
+
});
|
|
48
|
+
app.post("/api/proactive/web-push/prepare", deps.strictRateLimitMiddleware, (c) => c.json({
|
|
49
|
+
ok: true,
|
|
50
|
+
...prepareBrowserPush()
|
|
51
|
+
}));
|
|
52
|
+
app.post("/api/proactive/web-push/subscriptions", deps.strictRateLimitMiddleware, async (c) => c.json({
|
|
53
|
+
ok: true,
|
|
54
|
+
...registerBrowserPush(workspace(), await c.req.json())
|
|
55
|
+
}, 201));
|
|
56
|
+
app.delete("/api/proactive/web-push/subscriptions/:id", deps.strictRateLimitMiddleware, (c) => {
|
|
57
|
+
unregisterBrowserPush(workspace(), c.req.param("id"));
|
|
58
|
+
return c.json({ ok: true });
|
|
59
|
+
});
|
|
60
|
+
app.get("/api/inbox/judgments/:itemId/workflow", async (c) => c.json({
|
|
61
|
+
ok: true,
|
|
62
|
+
workflow: await workflowForCard(c.req.param("itemId"), workspace(), deps.service.createWorkflowRunService())
|
|
63
|
+
}));
|
|
64
|
+
app.post("/api/inbox/judgments/:itemId/prepare", deps.strictRateLimitMiddleware, async (c) => {
|
|
65
|
+
const card = getCard(c.req.param("itemId"), workspace());
|
|
66
|
+
const sub = requireSubscription(card.subscriptionId, workspace());
|
|
67
|
+
const config = deps.service.currentConfig;
|
|
68
|
+
const agentId = sub.scopeKind === "project" ? resolveProjectAgentId({
|
|
69
|
+
config,
|
|
70
|
+
projects: deps.service.projects,
|
|
71
|
+
projectId: sub.scopeId
|
|
72
|
+
}) : getDefaultAgentId(config);
|
|
73
|
+
return c.json({
|
|
74
|
+
ok: true,
|
|
75
|
+
workflow: await prepareCardWorkflow(workspace(), card.id, await c.req.json(), agentId, deps.service.createWorkflowRunService())
|
|
76
|
+
}, 202);
|
|
77
|
+
});
|
|
78
|
+
app.post("/api/proactive/presence", deps.strictRateLimitMiddleware, async (c) => {
|
|
79
|
+
recordProactivePresence(workspace(), await c.req.json());
|
|
80
|
+
return c.json({ ok: true });
|
|
81
|
+
});
|
|
82
|
+
app.get("/api/proactive/metrics", (c) => c.json({
|
|
83
|
+
ok: true,
|
|
84
|
+
metrics: proactiveMetrics(workspace())
|
|
85
|
+
}));
|
|
86
|
+
app.get("/api/proactive/digests/:id", (c) => c.json({
|
|
87
|
+
ok: true,
|
|
88
|
+
cards: digestCards(c.req.param("id"), workspace())
|
|
89
|
+
}));
|
|
90
|
+
app.post("/api/proactive/subscriptions/:id/preview", deps.strictRateLimitMiddleware, async (c) => c.json({
|
|
91
|
+
ok: true,
|
|
92
|
+
...await previewSubscription(workspace(), c.req.param("id"), new ReadonlyProactiveAgentExecutor(() => deps.service.getConfig()), c.req.raw.signal)
|
|
93
|
+
}));
|
|
94
|
+
app.get("/api/proactive/templates", (c) => c.json({
|
|
95
|
+
ok: true,
|
|
96
|
+
templates: templateCatalog(workspace())
|
|
97
|
+
}));
|
|
98
|
+
app.get("/api/proactive/preferences", (c) => c.json({
|
|
99
|
+
ok: true,
|
|
100
|
+
preferences: proactivePreferences(workspace())
|
|
101
|
+
}));
|
|
102
|
+
app.patch("/api/proactive/preferences", deps.strictRateLimitMiddleware, async (c) => c.json({
|
|
103
|
+
ok: true,
|
|
104
|
+
preferences: updateProactivePreferences(workspace(), await c.req.json())
|
|
105
|
+
}));
|
|
106
|
+
app.get("/api/proactive/subscriptions", (c) => c.json({
|
|
107
|
+
ok: true,
|
|
108
|
+
subscriptions: controlledSubscriptions(workspace())
|
|
109
|
+
}));
|
|
110
|
+
app.post("/api/proactive/subscriptions", deps.strictRateLimitMiddleware, async (c) => c.json({
|
|
111
|
+
ok: true,
|
|
112
|
+
subscription: createControlledSubscription(workspace(), await c.req.json())
|
|
113
|
+
}, 201));
|
|
114
|
+
app.patch("/api/proactive/subscriptions/:id", deps.strictRateLimitMiddleware, async (c) => c.json({
|
|
115
|
+
ok: true,
|
|
116
|
+
subscription: updateControlledSubscription(workspace(), c.req.param("id"), await c.req.json())
|
|
117
|
+
}));
|
|
118
|
+
app.get("/api/proactive/subscriptions/:id/runs", (c) => {
|
|
119
|
+
requireSubscription(c.req.param("id"), workspace());
|
|
120
|
+
return c.json({
|
|
121
|
+
ok: true,
|
|
122
|
+
runs: getSqliteDatabase().prepare(`SELECT run_id AS id, status, outcome_reason AS reason,
|
|
123
|
+
started_at AS startedAt, completed_at AS completedAt, error_message AS error FROM proactive_runs WHERE subscription_id = ? ORDER BY started_at DESC LIMIT 30`).all(c.req.param("id"))
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
app.get("/api/proactive/cards", (c) => c.json({
|
|
127
|
+
ok: true,
|
|
128
|
+
...listCards(workspace(), {
|
|
129
|
+
status: c.req.query("status"),
|
|
130
|
+
before: c.req.query("before")
|
|
131
|
+
})
|
|
132
|
+
}));
|
|
133
|
+
app.get("/api/inbox/judgments/changes", (c) => {
|
|
134
|
+
const cursor = Number(c.req.query("cursor") ?? 0);
|
|
135
|
+
if (!Number.isSafeInteger(cursor) || cursor < 0) return c.json({
|
|
136
|
+
ok: false,
|
|
137
|
+
error: "Invalid cursor"
|
|
138
|
+
}, 400);
|
|
139
|
+
return c.json({
|
|
140
|
+
ok: true,
|
|
141
|
+
...cardChanges(workspace(), cursor)
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
app.get("/api/inbox/judgments/:itemId", (c) => c.json({
|
|
145
|
+
ok: true,
|
|
146
|
+
card: getCard(c.req.param("itemId"), workspace())
|
|
147
|
+
}));
|
|
148
|
+
app.post("/api/inbox/judgments/:itemId/actions", deps.strictRateLimitMiddleware, async (c) => {
|
|
149
|
+
const card = performCardAction(c.req.param("itemId"), workspace(), await c.req.json());
|
|
150
|
+
deps.service.emit("proactive.card.changed", {
|
|
151
|
+
cardId: card.id,
|
|
152
|
+
revision: card.revision
|
|
153
|
+
});
|
|
154
|
+
return c.json({
|
|
155
|
+
ok: true,
|
|
156
|
+
card
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
//#endregion
|
|
161
|
+
export { registerProactiveControlRoutes };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { Hono } from 'hono';
|
|
2
2
|
import type { AuthenticatedRouteDeps } from './deps.js';
|
|
3
|
-
/**
|
|
3
|
+
/** Proactive controls, cards and internal diagnostics. */
|
|
4
4
|
export declare function registerProactiveRoutes(authenticated: Hono, deps: AuthenticatedRouteDeps): void;
|
|
@@ -1,10 +1,14 @@
|
|
|
1
|
+
import { getInboxItem } from "../../../proactive/inbox/repository.js";
|
|
2
|
+
import { listCards } from "../../../proactive/inbox/cards.js";
|
|
3
|
+
import { registerProactiveControlRoutes } from "./proactive-control.js";
|
|
1
4
|
//#region src/gateway/hono/routes/proactive.ts
|
|
2
5
|
function positiveInt(value, fallback) {
|
|
3
6
|
const parsed = Number(value);
|
|
4
7
|
return Number.isInteger(parsed) && parsed > 0 ? parsed : fallback;
|
|
5
8
|
}
|
|
6
|
-
/**
|
|
9
|
+
/** Proactive controls, cards and internal diagnostics. */
|
|
7
10
|
function registerProactiveRoutes(authenticated, deps) {
|
|
11
|
+
registerProactiveControlRoutes(authenticated, deps);
|
|
8
12
|
authenticated.get("/api/inbox/judgments", (c) => {
|
|
9
13
|
const status = c.req.query("status");
|
|
10
14
|
if (status && ![
|
|
@@ -16,12 +20,15 @@ function registerProactiveRoutes(authenticated, deps) {
|
|
|
16
20
|
ok: false,
|
|
17
21
|
error: "Invalid inbox status"
|
|
18
22
|
}, 400);
|
|
23
|
+
const page = listCards(deps.service.currentWorkspacePath, {
|
|
24
|
+
status,
|
|
25
|
+
limit: positiveInt(c.req.query("limit"), 50),
|
|
26
|
+
before: c.req.query("before")
|
|
27
|
+
});
|
|
19
28
|
return c.json({
|
|
20
29
|
ok: true,
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
limit: positiveInt(c.req.query("limit"), 50)
|
|
24
|
-
})
|
|
30
|
+
...page,
|
|
31
|
+
items: page.cards.map((card) => getInboxItem(card.id))
|
|
25
32
|
});
|
|
26
33
|
});
|
|
27
34
|
authenticated.post("/api/inbox/judgments/:itemId/transition", deps.strictRateLimitMiddleware, async (c) => {
|
|
@@ -256,7 +256,7 @@ function registerVoiceRoutes(authenticated, deps) {
|
|
|
256
256
|
}
|
|
257
257
|
}, 400);
|
|
258
258
|
const principal = getGatewayPrincipal(c);
|
|
259
|
-
service.voiceRealtime.cancelSession(parsed.data.sessionId, parsed.data.ticket, principal.principalId);
|
|
259
|
+
await service.voiceRealtime.cancelSession(parsed.data.sessionId, parsed.data.ticket, principal.principalId);
|
|
260
260
|
return c.json({ ok: true });
|
|
261
261
|
});
|
|
262
262
|
authenticated.post("/api/voice/language", strictRateLimitMiddleware, async (c) => {
|
|
@@ -63,6 +63,11 @@ function requiredGatewayScope(method, path) {
|
|
|
63
63
|
if (path.startsWith("/api/agents") || path.startsWith("/api/models")) return methodScope(method, "agents.read", "gateway.admin");
|
|
64
64
|
if (path.startsWith("/api/sessions") || path.startsWith("/api/side-chats")) return methodScope(method, "sessions.read", "sessions.write");
|
|
65
65
|
if (path.startsWith("/api/tasks")) return methodScope(method, "tasks.read", "tasks.write");
|
|
66
|
+
if (method === "POST" && /^\/api\/proactive\/subscriptions\/[^/]+\/preview$/.test(path)) return "agents.run";
|
|
67
|
+
if (/^\/api\/inbox\/judgments\/[^/]+\/workflow$/.test(path)) return methodScope(method, "automations.read", "automations.write");
|
|
68
|
+
if (method === "POST" && /^\/api\/inbox\/judgments\/[^/]+\/prepare$/.test(path)) return "automations.write";
|
|
69
|
+
if (path.startsWith("/api/proactive/web-push")) return "notifications.self";
|
|
70
|
+
if (path === "/api/proactive" || path.startsWith("/api/proactive/")) return methodScope(method, "tasks.read", "tasks.write");
|
|
66
71
|
if (path.startsWith("/api/home") || path.startsWith("/api/inbox")) return methodScope(method, "tasks.read", "tasks.write");
|
|
67
72
|
if (path.startsWith("/api/automations") || path.startsWith("/api/automation-runs")) return methodScope(method, "automations.read", "automations.write");
|
|
68
73
|
if (path.startsWith("/api/workflows")) return methodScope(method, "automations.read", "automations.write");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createLogger } from "../../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../../utils/logger.js";
|
|
3
|
-
import { getModelRegistry } from "../../providers/model-registry.js";
|
|
4
3
|
import { loadConfig, saveConfig } from "../../config/loader.js";
|
|
4
|
+
import { getModelRegistry } from "../../providers/model-registry.js";
|
|
5
5
|
import { init_providers } from "../../providers/index.js";
|
|
6
6
|
import { disposeAllSessionMcpRuntimes } from "../../agent/mcp/bundle-mcp-runtime.js";
|
|
7
7
|
import { reloadImageGenerationProviders } from "../../agent/image/generation/provider-registry.js";
|
|
@@ -179,7 +179,6 @@ export declare class GatewayService {
|
|
|
179
179
|
private schedulePostReadySidecars;
|
|
180
180
|
private runPostReadySidecars;
|
|
181
181
|
start(): Promise<void>;
|
|
182
|
-
private ensureDefaultProactiveScenarioSubscriptions;
|
|
183
182
|
/** Called when the HTTP listener is bound (before deferred channel work). */
|
|
184
183
|
markHttpListening(): void;
|
|
185
184
|
isGatewayReady(): boolean;
|
|
@@ -12,16 +12,16 @@ import { getSessionConfig } from "../storage/sqlite/config-repository.js";
|
|
|
12
12
|
import "../storage/sqlite/index.js";
|
|
13
13
|
import { getAgentDefaultModelRef, init_schema } from "../config/schema.js";
|
|
14
14
|
import { init_agent_scope, listAgentEntries, normalizeAgentId, resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../agent/agent-scope.js";
|
|
15
|
+
import { buildSessionKey, init_session_key, sanitizeSegment } from "../routing/session-key.js";
|
|
16
|
+
import { getDefaultAgentId, init_resolve_route } from "../routing/resolve-route.js";
|
|
17
|
+
import { resolveEffectiveAgentProfileForSession } from "../config/agent-profile.js";
|
|
15
18
|
import { init_paths, resolveConfigPath, resolveExtensionsDir } from "../config/paths.js";
|
|
16
|
-
import { prewarmModelRegistry } from "../providers/model-registry.js";
|
|
17
19
|
import { areExtensionsGloballyDisabled } from "../extensions/discover-extensions.js";
|
|
18
20
|
import { buildExtensionMetadataSnapshot } from "../extensions/extension-metadata-snapshot.js";
|
|
19
21
|
import { buildChannelCatalogForConfig, buildChannelCatalogFromSnapshot, init_channel_catalog_service } from "../channels/catalog/channel-catalog-service.js";
|
|
20
22
|
import { loadConfig, saveConfig } from "../config/loader.js";
|
|
21
|
-
import {
|
|
22
|
-
import { getDefaultAgentId, init_resolve_route } from "../routing/resolve-route.js";
|
|
23
|
+
import { prewarmModelRegistry } from "../providers/model-registry.js";
|
|
23
24
|
import { init_providers, providers_exports } from "../providers/index.js";
|
|
24
|
-
import { resolveEffectiveAgentProfileForSession } from "../config/agent-profile.js";
|
|
25
25
|
import { TaskRepository } from "../tasks/task-repository.js";
|
|
26
26
|
import { TaskConversationRepository } from "../tasks/task-conversation-repository.js";
|
|
27
27
|
import { getEmbeddedExecutionSession } from "../agent/embedded/execution-context.js";
|
|
@@ -54,6 +54,12 @@ import { registerClarificationChannelRuntime } from "./clarify-runtime.js";
|
|
|
54
54
|
import { ChannelManager } from "../channels/manager.js";
|
|
55
55
|
import { getWorkspacePath } from "../config/workspace-path-helpers.js";
|
|
56
56
|
import "../config/index.js";
|
|
57
|
+
import { DiscussionService } from "../discussions/service.js";
|
|
58
|
+
import { DiscussionOrganizer } from "../discussions/organizer.js";
|
|
59
|
+
import { DiscussionLiveWorker } from "../discussions/live-worker.js";
|
|
60
|
+
import { DiscussionOrganizerWorker } from "../discussions/organizer-worker.js";
|
|
61
|
+
import { DiscussionSealer } from "../discussions/sealer.js";
|
|
62
|
+
import "../discussions/index.js";
|
|
57
63
|
import { ManagedComposioEventPoller } from "../connectors/composio-managed-events.js";
|
|
58
64
|
import { startConnectedKnowledgeCoordinator } from "../knowledge/coordinator.js";
|
|
59
65
|
import "../knowledge/index.js";
|
|
@@ -61,17 +67,13 @@ import { ConnectionRecoveryService } from "../connectors/connection-recovery-ser
|
|
|
61
67
|
import { startConnectorLearningCoordinator } from "../connectors/learning-coordinator.js";
|
|
62
68
|
import { ConnectedSourceChangePublisher } from "../connectors/source-change-publisher.js";
|
|
63
69
|
import { startConnectorSupervisor } from "../connectors/supervisor.js";
|
|
64
|
-
import { DiscussionService } from "../discussions/service.js";
|
|
65
|
-
import { DiscussionOrganizer } from "../discussions/organizer.js";
|
|
66
|
-
import { DiscussionLiveWorker } from "../discussions/live-worker.js";
|
|
67
|
-
import { DiscussionOrganizerWorker } from "../discussions/organizer-worker.js";
|
|
68
|
-
import { DiscussionSealer } from "../discussions/sealer.js";
|
|
69
|
-
import "../discussions/index.js";
|
|
70
70
|
import { EndpointToolRuntime } from "../endpoint-tools/runtime.js";
|
|
71
71
|
import "../endpoint-tools/index.js";
|
|
72
72
|
import { assertGatewayAuthConfigured, extractToken, resolveGatewayAuth, validateToken } from "./auth.js";
|
|
73
73
|
import { prepareAutomationAgentSession } from "./automation-agent-session.js";
|
|
74
74
|
import { stopTailscaleExposure } from "./tailscale-lifecycle.js";
|
|
75
|
+
import { ProactiveInboxService } from "../proactive/inbox/service.js";
|
|
76
|
+
import { deliverProactiveCard } from "../proactive/inbox/delivery.js";
|
|
75
77
|
import { buildVoiceMemoryContext } from "../voice/realtime/memory-context.js";
|
|
76
78
|
import { buildVoicePersonaContext } from "../voice/realtime/persona-context.js";
|
|
77
79
|
import { voiceMemoryBudget, voicePersonaBudget } from "../voice/realtime/conversation-context.js";
|
|
@@ -111,7 +113,6 @@ import { ReadonlyProactiveAgentExecutor } from "../proactive/execution/agent-exe
|
|
|
111
113
|
import { listInsights } from "../proactive/execution/repository.js";
|
|
112
114
|
import { ProactiveWorker } from "../proactive/execution/worker.js";
|
|
113
115
|
import { ProactiveTemporalWorker } from "../proactive/temporal/worker.js";
|
|
114
|
-
import { ProactiveInboxService } from "../proactive/inbox/service.js";
|
|
115
116
|
import { ProactiveInboxWorker } from "../proactive/inbox/worker.js";
|
|
116
117
|
import "../proactive/index.js";
|
|
117
118
|
import { scheduleGatewayUpdateCheck } from "../infra/update-startup.js";
|
|
@@ -317,7 +318,7 @@ var GatewayService = class {
|
|
|
317
318
|
this.proactiveWorker = new ProactiveWorker(new ReadonlyProactiveAgentExecutor(() => this.config));
|
|
318
319
|
this.proactiveTemporalWorker = new ProactiveTemporalWorker(this.proactive);
|
|
319
320
|
this.proactiveInboxWorker = new ProactiveInboxWorker({ deliver: async ({ inboxItem }) => {
|
|
320
|
-
this.
|
|
321
|
+
return deliverProactiveCard(inboxItem, this.createNotificationService(), (type, payload) => this.realtime.broker.publish("gateway", type, payload));
|
|
321
322
|
} });
|
|
322
323
|
let bootstrapConfigChanged = initializeVoiceDefaults(this.config, inferProductLanguageFromEnvironment());
|
|
323
324
|
const starterResult = ensureStarterAgentsInitialized(this.config);
|
|
@@ -680,7 +681,21 @@ var GatewayService = class {
|
|
|
680
681
|
return this.taskRunDispatcher;
|
|
681
682
|
}
|
|
682
683
|
createNotificationService() {
|
|
683
|
-
if (!this.notificationService) this.notificationService = new NotificationService({
|
|
684
|
+
if (!this.notificationService) this.notificationService = new NotificationService({
|
|
685
|
+
publish: (type, payload) => this.realtime.broker.publish("gateway", type, payload),
|
|
686
|
+
sendChannel: async (target, text) => {
|
|
687
|
+
const outbound = this.channelManager.getPlugin("telegram")?.outbound;
|
|
688
|
+
if (!outbound?.sendText || !this.channelManager.getRunningChannels().includes("telegram")) throw new Error("Telegram is not connected");
|
|
689
|
+
const result = await outbound.sendText({
|
|
690
|
+
cfg: this.config,
|
|
691
|
+
to: target.chatId,
|
|
692
|
+
accountId: target.accountId,
|
|
693
|
+
text
|
|
694
|
+
});
|
|
695
|
+
if (!result.success) throw new Error("Telegram delivery failed");
|
|
696
|
+
return { messageId: result.messageId };
|
|
697
|
+
}
|
|
698
|
+
});
|
|
684
699
|
return this.notificationService;
|
|
685
700
|
}
|
|
686
701
|
dispatchTaskRuns() {
|
|
@@ -921,7 +936,6 @@ var GatewayService = class {
|
|
|
921
936
|
this.running = true;
|
|
922
937
|
this.taskRunDispatchTimer = setInterval(() => this.dispatchTaskRuns(), 1e3);
|
|
923
938
|
this.taskRunDispatchTimer.unref?.();
|
|
924
|
-
this.ensureDefaultProactiveScenarioSubscriptions();
|
|
925
939
|
this.proactiveWorker.start();
|
|
926
940
|
this.proactiveTemporalWorker.start();
|
|
927
941
|
this.proactiveInboxWorker.start();
|
|
@@ -1115,22 +1129,6 @@ var GatewayService = class {
|
|
|
1115
1129
|
else trace.mark("service.started-awaiting-http");
|
|
1116
1130
|
log.debug("Gateway service started");
|
|
1117
1131
|
}
|
|
1118
|
-
ensureDefaultProactiveScenarioSubscriptions() {
|
|
1119
|
-
for (const scenarioKey of [
|
|
1120
|
-
"automation_failure_impact",
|
|
1121
|
-
"meeting_preparation",
|
|
1122
|
-
"discussion_follow_up"
|
|
1123
|
-
]) {
|
|
1124
|
-
if (this.proactiveScenarios.subscriptions(scenarioKey).some((subscription) => subscription.workspaceId === this.currentWorkspacePath)) continue;
|
|
1125
|
-
this.proactiveScenarios.subscribe({
|
|
1126
|
-
scenarioKey,
|
|
1127
|
-
workspaceId: this.currentWorkspacePath,
|
|
1128
|
-
scopeKind: "workspace",
|
|
1129
|
-
scopeId: this.currentWorkspacePath,
|
|
1130
|
-
enabled: true
|
|
1131
|
-
});
|
|
1132
|
-
}
|
|
1133
|
-
}
|
|
1134
1132
|
/** Called when the HTTP listener is bound (before deferred channel work). */
|
|
1135
1133
|
markHttpListening() {
|
|
1136
1134
|
this.readiness.markHttpListening();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DEFAULT_ACK_MAX_CHARS, HEARTBEAT_OK, NO_REPLY, shouldSilence, stripHeartbeatToken } from "./tokens.js";
|
|
2
|
-
import { appendCronEventLines } from "./event-prompt.js";
|
|
3
2
|
import { isWithinActiveHours } from "./active-hours.js";
|
|
4
3
|
import { isHeartbeatContentEmpty } from "./content-check.js";
|
|
4
|
+
import { appendCronEventLines } from "./event-prompt.js";
|
|
5
5
|
import { createHeartbeatWake } from "./wake.js";
|
|
6
6
|
export { DEFAULT_ACK_MAX_CHARS, HEARTBEAT_OK, NO_REPLY, appendCronEventLines, createHeartbeatWake, isHeartbeatContentEmpty, isWithinActiveHours, shouldSilence, stripHeartbeatToken };
|
|
@@ -122,7 +122,7 @@ function automationPlan(payload) {
|
|
|
122
122
|
function proactivePlan(payload) {
|
|
123
123
|
if (!payload || typeof payload !== "object") return null;
|
|
124
124
|
const item = payload;
|
|
125
|
-
if (typeof item.id !== "string" || typeof item.insightId !== "string" || typeof item.insight
|
|
125
|
+
if (typeof item.id !== "string" || typeof item.insightId !== "string" || typeof item.insight?.title !== "string") return null;
|
|
126
126
|
const requiresDecision = item.insight.attentionKind === "decision";
|
|
127
127
|
const highUrgency = item.insight.urgency === "high" || item.insight.urgency === "critical";
|
|
128
128
|
if (item.insight.attentionKind === "receipt") return null;
|
|
@@ -130,7 +130,7 @@ function proactivePlan(payload) {
|
|
|
130
130
|
const title = item.insight.title.trim().slice(0, 120);
|
|
131
131
|
const summary = typeof item.insight.summary === "string" ? item.insight.summary.trim().slice(0, 180) : "";
|
|
132
132
|
return {
|
|
133
|
-
dedupeKey: `proactive.insight:${item.id}`,
|
|
133
|
+
dedupeKey: `proactive.insight:${item.id}${item.notificationRevision && item.notificationRevision > 1 ? `:${item.notificationRevision}` : ""}`,
|
|
134
134
|
notification: {
|
|
135
135
|
type: "proactive.insight",
|
|
136
136
|
target: {
|
|
@@ -148,7 +148,8 @@ function proactivePlan(payload) {
|
|
|
148
148
|
} } : {},
|
|
149
149
|
payload: {
|
|
150
150
|
inboxItemId: item.id,
|
|
151
|
-
insightId: item.insightId
|
|
151
|
+
insightId: item.insightId,
|
|
152
|
+
notificationRevision: item.notificationRevision ?? 1
|
|
152
153
|
}
|
|
153
154
|
}
|
|
154
155
|
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ProductNotification, ProactivePreferences } from '@xopcai/gateway-contract';
|
|
2
|
+
type Target = NonNullable<ProactivePreferences['telegram']>;
|
|
3
|
+
export type ProactiveChannelSender = (target: Target, text: string) => Promise<{
|
|
4
|
+
messageId: string;
|
|
5
|
+
}>;
|
|
6
|
+
export declare function enqueueChannelNotification(notification: ProductNotification, workspace: string): void;
|
|
7
|
+
export declare function drainChannelNotifications(send: ProactiveChannelSender): Promise<void>;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { getSqliteDatabase, runSqliteWriteTransaction } from "../storage/sqlite/transaction.js";
|
|
2
|
+
import { notificationTargetRoute } from "../../packages/gateway-contract/src/notifications.js";
|
|
3
|
+
import { proactivePreferences } from "../proactive/policy/service.js";
|
|
4
|
+
import { recheckNotificationDelivery } from "./proactive-policy.js";
|
|
5
|
+
import { getNotificationEvent } from "./store.js";
|
|
6
|
+
//#region src/notifications/proactive-channel.ts
|
|
7
|
+
function enqueueChannelNotification(notification, workspace) {
|
|
8
|
+
const target = proactivePreferences(workspace).telegram;
|
|
9
|
+
if (!target) throw new Error("Configure a Telegram destination before selecting it");
|
|
10
|
+
getSqliteDatabase().prepare("INSERT OR IGNORE INTO proactive_channel_deliveries(notification_id, workspace_id, target_json, next_attempt_at) VALUES (?, ?, ?, ?)").run(notification.id, workspace, JSON.stringify(target), Date.now());
|
|
11
|
+
}
|
|
12
|
+
async function drainChannelNotifications(send) {
|
|
13
|
+
const db = getSqliteDatabase();
|
|
14
|
+
const claim = runSqliteWriteTransaction((tx) => {
|
|
15
|
+
tx.prepare("UPDATE proactive_channel_deliveries SET status = 'failed', last_error = 'Lease exhausted' WHERE status = 'sending' AND lease_until <= ? AND attempt >= 5").run(Date.now());
|
|
16
|
+
const row = tx.prepare(`SELECT * FROM proactive_channel_deliveries WHERE (status = 'pending' AND next_attempt_at <= ?) OR (status = 'sending' AND lease_until <= ?) ORDER BY next_attempt_at LIMIT 1`).get(Date.now(), Date.now());
|
|
17
|
+
if (!row) return null;
|
|
18
|
+
tx.prepare("UPDATE proactive_channel_deliveries SET status = 'sending', attempt = attempt + 1, lease_until = ? WHERE notification_id = ?").run(Date.now() + 12e4, row.notification_id);
|
|
19
|
+
return {
|
|
20
|
+
...row,
|
|
21
|
+
attempt: row.attempt + 1
|
|
22
|
+
};
|
|
23
|
+
});
|
|
24
|
+
if (!claim) return;
|
|
25
|
+
const finish = (status, nextAt, messageId = null, error = null) => {
|
|
26
|
+
db.prepare(`UPDATE proactive_channel_deliveries SET status = ?, next_attempt_at = ?, provider_message_id = ?, last_error = ?, lease_until = NULL
|
|
27
|
+
WHERE notification_id = ? AND status = 'sending' AND attempt = ?`).run(status, nextAt, messageId, error, claim.notification_id, claim.attempt);
|
|
28
|
+
};
|
|
29
|
+
try {
|
|
30
|
+
const notification = getNotificationEvent(claim.notification_id);
|
|
31
|
+
const current = proactivePreferences(claim.workspace_id);
|
|
32
|
+
if (!notification || current.preferredChannel !== "telegram" || JSON.stringify(current.telegram) !== claim.target_json) {
|
|
33
|
+
finish("cancelled", Date.now());
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const policy = recheckNotificationDelivery(notification, "telegram");
|
|
37
|
+
if (policy === "cancel") {
|
|
38
|
+
finish("cancelled", Date.now());
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
if (policy instanceof Date) {
|
|
42
|
+
finish("pending", policy.getTime());
|
|
43
|
+
db.prepare("UPDATE proactive_channel_deliveries SET attempt = attempt - 1 WHERE notification_id = ? AND attempt = ?").run(claim.notification_id, claim.attempt);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const target = JSON.parse(claim.target_json);
|
|
47
|
+
const url = new URL(target.publicUrl);
|
|
48
|
+
url.hash = notificationTargetRoute(notification.target, "web");
|
|
49
|
+
const result = await send(target, `${notification.target.kind === "proactive_digest" ? "你的工作摘要已就绪 / Your work digest is ready." : "有一项工作需要查看 / A work update is ready."}\n${url.toString()}`);
|
|
50
|
+
if (!result.messageId) throw new Error("No delivery receipt");
|
|
51
|
+
finish("sent", Date.now(), result.messageId);
|
|
52
|
+
} catch {
|
|
53
|
+
finish(claim.attempt >= 5 ? "failed" : "pending", Date.now() + Math.min(36e5, 3e4 * 2 ** claim.attempt), null, "Telegram delivery failed");
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
//#endregion
|
|
57
|
+
export { drainChannelNotifications, enqueueChannelNotification };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { ProductNotification } from '@xopcai/gateway-contract';
|
|
2
|
+
export declare function proactiveNotificationWorkspace(notification: Pick<ProductNotification, 'target'>): string | null;
|
|
3
|
+
export declare function recheckNotificationDelivery(notification: ProductNotification, channel: 'browser' | 'mobile' | 'telegram', now?: Date): 'send' | 'cancel' | Date;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { getSqliteDatabase } from "../storage/sqlite/transaction.js";
|
|
2
|
+
import { proactivePreferences, quietHoursEnd } from "../proactive/policy/service.js";
|
|
3
|
+
import { viewingProactiveCards } from "../proactive/policy/presence.js";
|
|
4
|
+
import { digestCards } from "../proactive/inbox/digest.js";
|
|
5
|
+
import { recheckProactiveNotification } from "../proactive/inbox/notification-policy.js";
|
|
6
|
+
//#region src/notifications/proactive-policy.ts
|
|
7
|
+
function proactiveNotificationWorkspace(notification) {
|
|
8
|
+
const target = notification.target;
|
|
9
|
+
const db = getSqliteDatabase();
|
|
10
|
+
return (target.kind === "insight" ? db.prepare(`SELECT s.workspace_id FROM proactive_inbox_items i JOIN proactive_insights x USING(insight_id) JOIN proactive_scenario_subscriptions s USING(subscription_id) WHERE i.inbox_item_id = ?`).get(target.inboxItemId) : target.kind === "proactive_digest" ? db.prepare("SELECT workspace_id FROM proactive_digests WHERE digest_id = ?").get(target.digestId) : null)?.workspace_id ?? null;
|
|
11
|
+
}
|
|
12
|
+
function recheckNotificationDelivery(notification, channel, now = /* @__PURE__ */ new Date()) {
|
|
13
|
+
if (notification.type !== "proactive.insight") return "send";
|
|
14
|
+
const workspace = proactiveNotificationWorkspace(notification);
|
|
15
|
+
if (!workspace) return "cancel";
|
|
16
|
+
const preferences = proactivePreferences(workspace);
|
|
17
|
+
if (![
|
|
18
|
+
"all",
|
|
19
|
+
"auto",
|
|
20
|
+
channel
|
|
21
|
+
].includes(preferences.preferredChannel)) return "cancel";
|
|
22
|
+
if (preferences.level === "off" || preferences.pausedUntil && Date.parse(preferences.pausedUntil) > now.getTime()) return "cancel";
|
|
23
|
+
if (preferences.suppressWhileViewing && viewingProactiveCards(workspace, now.getTime())) return "cancel";
|
|
24
|
+
if (notification.target.kind === "insight") return recheckProactiveNotification(notification.target.inboxItemId, now, notification.payload.notificationRevision);
|
|
25
|
+
if (notification.target.kind === "proactive_digest") {
|
|
26
|
+
if (!digestCards(notification.target.digestId, workspace).length) return "cancel";
|
|
27
|
+
return quietHoursEnd(preferences, now) ?? "send";
|
|
28
|
+
}
|
|
29
|
+
return "cancel";
|
|
30
|
+
}
|
|
31
|
+
//#endregion
|
|
32
|
+
export { proactiveNotificationWorkspace, recheckNotificationDelivery };
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { type ProactiveChannelSender } from './proactive-channel.js';
|
|
2
|
+
import { type NotificationPlan } from './planner.js';
|
|
1
3
|
export declare class NotificationService {
|
|
2
4
|
private readonly options;
|
|
3
5
|
private timer;
|
|
@@ -6,10 +8,86 @@ export declare class NotificationService {
|
|
|
6
8
|
constructor(options: {
|
|
7
9
|
publish: (type: string, payload: unknown) => void;
|
|
8
10
|
fetch?: typeof fetch;
|
|
11
|
+
sendChannel?: ProactiveChannelSender;
|
|
9
12
|
});
|
|
10
13
|
start(): void;
|
|
11
14
|
stop(): void;
|
|
12
15
|
handleGatewayEvent(type: string, payload: unknown): void;
|
|
16
|
+
/** Throws on persistence failure so durable producers can retry the handoff. */
|
|
17
|
+
persistGatewayEvent(type: string, payload: unknown): {
|
|
18
|
+
schemaVersion: 1;
|
|
19
|
+
id: string;
|
|
20
|
+
type: "work_discovery.failed" | "chat.completed" | "chat.failed" | "task.needs_input" | "task.blocked" | "task.failed" | "task.completed" | "automation.completed" | "automation.failed" | "proactive.insight" | "work_discovery.review_ready";
|
|
21
|
+
priority: "normal" | "high";
|
|
22
|
+
title: {
|
|
23
|
+
en: string;
|
|
24
|
+
zh: string;
|
|
25
|
+
};
|
|
26
|
+
payload: Record<string, unknown>;
|
|
27
|
+
createdAt: number;
|
|
28
|
+
target?: {
|
|
29
|
+
kind: "chat";
|
|
30
|
+
sessionKey: string;
|
|
31
|
+
} | {
|
|
32
|
+
kind: "task";
|
|
33
|
+
taskId: string;
|
|
34
|
+
} | {
|
|
35
|
+
kind: "automation_run";
|
|
36
|
+
automationId: string;
|
|
37
|
+
runId: string;
|
|
38
|
+
} | {
|
|
39
|
+
kind: "proactive_digest";
|
|
40
|
+
digestId: string;
|
|
41
|
+
} | {
|
|
42
|
+
kind: "insight";
|
|
43
|
+
inboxItemId: string;
|
|
44
|
+
} | {
|
|
45
|
+
kind: "work_discovery";
|
|
46
|
+
runId: string;
|
|
47
|
+
sessionKey: string;
|
|
48
|
+
};
|
|
49
|
+
body?: {
|
|
50
|
+
en: string;
|
|
51
|
+
zh: string;
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
persistPlan(plan: NotificationPlan): {
|
|
55
|
+
schemaVersion: 1;
|
|
56
|
+
id: string;
|
|
57
|
+
type: "work_discovery.failed" | "chat.completed" | "chat.failed" | "task.needs_input" | "task.blocked" | "task.failed" | "task.completed" | "automation.completed" | "automation.failed" | "proactive.insight" | "work_discovery.review_ready";
|
|
58
|
+
priority: "normal" | "high";
|
|
59
|
+
title: {
|
|
60
|
+
en: string;
|
|
61
|
+
zh: string;
|
|
62
|
+
};
|
|
63
|
+
payload: Record<string, unknown>;
|
|
64
|
+
createdAt: number;
|
|
65
|
+
target?: {
|
|
66
|
+
kind: "chat";
|
|
67
|
+
sessionKey: string;
|
|
68
|
+
} | {
|
|
69
|
+
kind: "task";
|
|
70
|
+
taskId: string;
|
|
71
|
+
} | {
|
|
72
|
+
kind: "automation_run";
|
|
73
|
+
automationId: string;
|
|
74
|
+
runId: string;
|
|
75
|
+
} | {
|
|
76
|
+
kind: "proactive_digest";
|
|
77
|
+
digestId: string;
|
|
78
|
+
} | {
|
|
79
|
+
kind: "insight";
|
|
80
|
+
inboxItemId: string;
|
|
81
|
+
} | {
|
|
82
|
+
kind: "work_discovery";
|
|
83
|
+
runId: string;
|
|
84
|
+
sessionKey: string;
|
|
85
|
+
};
|
|
86
|
+
body?: {
|
|
87
|
+
en: string;
|
|
88
|
+
zh: string;
|
|
89
|
+
};
|
|
90
|
+
};
|
|
13
91
|
drain(): Promise<void>;
|
|
14
92
|
private deliverPending;
|
|
15
93
|
private send;
|