@xopcai/xopc 0.0.268 → 0.0.270
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-Bhyy6ENz.js → activity-store-D_0FmdRj.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-B9WObxjr.js → agent-avatar-dicebear-IZvEXak_.js} +1 -1
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-CE3ygr3l.js +1 -0
- package/dist/gateway/static/root/assets/{agents-BJuTIRPD.js → agents-DzG2qw-c.js} +1 -1
- package/dist/gateway/static/root/assets/{api-B2y7ZjZk.js → api-O3TTQ4qN.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-Bbn9mDfL.js → app-management-settings-panel-Cqqsbzri.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-Deo5EsIc.js → appearance-settings-DaJyf32s.js} +1 -1
- package/dist/gateway/static/root/assets/{apps-page-Cz4d7ErX.js → apps-page-B4lX6yoT.js} +1 -1
- package/dist/gateway/static/root/assets/{archive-plugin-CxJTU8MU.js → archive-plugin-kDPnDTJI.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-C71Cukgp.js → attachment-load-CJ3VceKS.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-_J7UZ55Q.js → automations-page-JwMtU8XB.js} +1 -1
- package/dist/gateway/static/root/assets/automations-workspace-BiNBewg0.js +6 -0
- package/dist/gateway/static/root/assets/{binary-plugins-CX8fC8Zt.js → binary-plugins-DzyZXLBX.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-Ci9fjoQL.js → block-editor-kTt3gYIJ.js} +3 -3
- package/dist/gateway/static/root/assets/{browser-automation-inputs-s5I78Iko.js → browser-automation-inputs-BKohPYR4.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-automations-page-rDSx0ozx.js → browser-automations-page-ktQfFPk-.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-settings-page-B9RA6x4x.js → browser-settings-page-Dgdt5uVL.js} +3 -3
- package/dist/gateway/static/root/assets/capabilities-settings-panel-BpDW-R9f.js +7 -0
- package/dist/gateway/static/root/assets/{channels-settings-CEhVLJNa.js → channels-settings-DU4EQnR0.js} +1 -1
- package/dist/gateway/static/root/assets/{channels-status-swr-_OsWr_vS.js → channels-status-swr-DrqzYmDr.js} +1 -1
- package/dist/gateway/static/root/assets/{chat-terminal-dock-DMSl8KxS.js → chat-terminal-dock-CIFGGLGa.js} +2 -2
- package/dist/gateway/static/root/assets/connectors-page-CfJqy284.js +2 -0
- package/dist/gateway/static/root/assets/{cron-expression-BByq6Uh8.js → cron-expression-BNwbnrEb.js} +1 -1
- package/dist/gateway/static/root/assets/{date-picker-m6JZCUEW.js → date-picker-DKyirU4K.js} +1 -1
- package/dist/gateway/static/root/assets/{dependency-picker-CwCAjbaJ.js → dependency-picker-D3vNIjRI.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-DSmeEREd.js → desktop-pet-fQwRb_3p.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-MfKceMoe.js → desktop-pet-settings-DfOJ-GvT.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-CwvWy26h.js → extension-debug-page-Cn53jB5-.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-DLrbVBHM.js → extension-page-IDpLCxpC.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-BI6C4PM-.js → extension-settings-page-B1dds2bP.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-swr-OObCK8jM.js → gateway-config-swr-B7dcmP7Q.js} +1 -1
- package/dist/gateway/static/root/assets/gateway-settings-pp9jN0wl.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-startup-retry-D_TxKN_A.js → gateway-startup-retry-JGhGMhVZ.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-settings-CUl832Tb.js → heartbeat-settings-B8_zTyev.js} +1 -1
- package/dist/gateway/static/root/assets/home-page-g1KdAdLb.js +1 -0
- package/dist/gateway/static/root/assets/{image-generation-api-fPU9yGsw.js → image-generation-api-BJLX7Qrh.js} +1 -1
- package/dist/gateway/static/root/assets/index-1zRt56Zt.css +2 -0
- package/dist/gateway/static/root/assets/{index-wKE8Q2FX.js → index-OMnem2nr.js} +47 -47
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-r4DCS19O.js → keyboard-shortcuts-settings-CBvMTFFx.js} +1 -1
- package/dist/gateway/static/root/assets/{local-app-workbench-page-qwLuir8A.js → local-app-workbench-page-bj75v2ZE.js} +2 -2
- package/dist/gateway/static/root/assets/{local-apps-page-DkfCRLUh.js → local-apps-page-APCMNDvU.js} +1 -1
- package/dist/gateway/static/root/assets/{locale-store-DFQX9kTl.js → locale-store-BThkG0W5.js} +1 -1
- package/dist/gateway/static/root/assets/logs-page-BX7n39zV.js +2 -0
- package/dist/gateway/static/root/assets/{management-settings-Cfx4ATTa.js → management-settings-CM62j8ZX.js} +1 -1
- package/dist/gateway/static/root/assets/{markdown-view-D-5jHRWg.js → markdown-view-BwjpJVPs.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-DOLjWd3y.js → media-plugins-C10byeaa.js} +1 -1
- package/dist/gateway/static/root/assets/{messages-Dj8QuS6e.js → messages-D0V_bgRP.js} +2 -2
- package/dist/gateway/static/root/assets/{mobile-pairing-wizard-BGW9joAb.js → mobile-pairing-wizard-BCWfwVx3.js} +1 -1
- package/dist/gateway/static/root/assets/note-detail-panel-koOqb0gX.js +5 -0
- package/dist/gateway/static/root/assets/notes-page-BH54rY3B.js +8 -0
- package/dist/gateway/static/root/assets/{page-tabs-_SGXMT2O.js → page-tabs-qQ36zncF.js} +1 -1
- package/dist/gateway/static/root/assets/{preview-open-alternatives-lVetfCWk.js → preview-open-alternatives-BiAJvvCo.js} +1 -1
- package/dist/gateway/static/root/assets/proactive-card-CcNBqHoH.js +1 -0
- package/dist/gateway/static/root/assets/proactive-page-C3K61jve.js +1 -0
- package/dist/gateway/static/root/assets/{product-open-page-CIGLPFm7.js → product-open-page-CunnDP4w.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-SL2g8MZY.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-BtxazT5J.js +1 -0
- package/dist/gateway/static/root/assets/{registry-api-CsZLatKo.js → registry-api-0JSegbNl.js} +1 -1
- package/dist/gateway/static/root/assets/remote-access-hub-BSb7b67A.js +1 -0
- package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-BDqVrUEj.js → runtime-tools-settings-panel-bu_mwBTr.js} +1 -1
- package/dist/gateway/static/root/assets/{schema-form-8RQgFJJO.js → schema-form-BE0sgZyz.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-ljcS2KVz.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-CR9Y9LQm.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-j4UjGM-f.js → settings-form-section-CBo517lV.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-lMi50B_s.js → settings-page-DBPimx93.js} +1 -1
- package/dist/gateway/static/root/assets/{setup-status-panel-Dx4Fy3rU.js → setup-status-panel-J3AnooPW.js} +1 -1
- package/dist/gateway/static/root/assets/{share-preview-page-aSyKRH5y.js → share-preview-page-DdV75VTe.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-AAm4Iwcp.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-pRCjP5sm.js +1 -0
- package/dist/gateway/static/root/assets/{skills-page-C2_CAvxW.js → skills-page-Cn_-nvRo.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page.utils-B00e4Q30.js → skills-page.utils-CfVAc_lu.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-CulAkrsV.js → system-settings-panel-B-pzalp-.js} +1 -1
- package/dist/gateway/static/root/assets/task-detail-page-CmrLy3PO.js +1 -0
- package/dist/gateway/static/root/assets/{theme-store-zRT6vaZc.js → theme-store-1wryLgBQ.js} +1 -1
- package/dist/gateway/static/root/assets/{tunnel-api-C01xgCWR.js → tunnel-api-Cgpnm2fL.js} +1 -1
- package/dist/gateway/static/root/assets/{use-autosave-DfSJ3c2p.js → use-autosave-N_lm4FdD.js} +1 -1
- package/dist/gateway/static/root/assets/user-model-page-u3QLDX6L.js +2 -0
- package/dist/gateway/static/root/assets/{voice-api-key-field-9v-miN8o.js → voice-api-key-field-DMsyVfri.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-config-api-DpJEu2RQ.js → voice-config-api-QWVmiAp3.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-overlay-CREYgh-1.js → work-discovery-overlay-BC0vAxp1.js} +1 -1
- package/dist/gateway/static/root/assets/workflow-run-setup-panel-Cz9jQIlP.js +3 -0
- package/dist/gateway/static/root/assets/workflows-page-DA6OOK6X.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 +120 -0
- package/dist/packages/realtime-protocol/src/voice.js +2 -1
- package/dist/src/agent/tool-manuals/xopc-use.d.ts +1 -1
- package/dist/src/agent/tool-manuals/xopc-use.js +19 -1
- package/dist/src/agent/tools/factory.js +1 -0
- package/dist/src/agent/tools/xopc-use-tool.d.ts +3 -2
- package/dist/src/agent/tools/xopc-use-tool.js +48 -4
- package/dist/src/agent/workflow/subagent-runner.d.ts +1 -0
- package/dist/src/agent/workflow/subagent-runner.js +2 -2
- package/dist/src/browser/automations/schema.d.ts +1 -1
- package/dist/src/browser/automations/service.d.ts +1 -1
- package/dist/src/cli/bin.js +2 -2
- package/dist/src/cli/commands/agent.js +2 -2
- package/dist/src/cli/commands/auth.js +1 -1
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/cli/commands/extension-dev.js +1 -1
- package/dist/src/cli/commands/extension-marketplace.js +1 -1
- package/dist/src/cli/commands/extension.js +1 -1
- package/dist/src/cli/commands/gateway/lifecycle.js +1 -1
- package/dist/src/cli/commands/gateway-ssh-tunnel.js +1 -1
- package/dist/src/cli/commands/models.js +2 -2
- package/dist/src/cli/commands/onboard.js +1 -1
- package/dist/src/cli/commands/platform.js +1 -1
- package/dist/src/cli/commands/profile.js +1 -1
- package/dist/src/cli/commands/tunnel.js +1 -1
- package/dist/src/cli/commands/update.js +1 -1
- package/dist/src/cli/extension-cli-register.js +1 -1
- package/dist/src/config/index.js +1 -1
- package/dist/src/connectors/connected-source-normalizers.js +3 -0
- 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/proactive-control.d.ts +3 -0
- package/dist/src/gateway/hono/routes/proactive-control.js +168 -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/run-loop.js +1 -1
- package/dist/src/gateway/security/gateway-scopes.js +5 -0
- package/dist/src/gateway/server.js +1 -1
- package/dist/src/gateway/service.d.ts +0 -1
- package/dist/src/gateway/service.js +21 -23
- 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 +12 -2
- 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 +5 -0
- package/dist/src/proactive/execution/authorization.js +61 -0
- package/dist/src/proactive/execution/context.d.ts +4 -0
- package/dist/src/proactive/execution/context.js +51 -14
- package/dist/src/proactive/execution/insight.d.ts +7 -0
- package/dist/src/proactive/execution/insight.js +36 -3
- package/dist/src/proactive/execution/repository.d.ts +2 -0
- package/dist/src/proactive/execution/repository.js +53 -9
- package/dist/src/proactive/execution/types.d.ts +7 -0
- package/dist/src/proactive/execution/worker.js +43 -7
- package/dist/src/proactive/experience.d.ts +69 -0
- package/dist/src/proactive/experience.js +90 -0
- package/dist/src/proactive/follow-ups.d.ts +123 -0
- package/dist/src/proactive/follow-ups.js +169 -0
- package/dist/src/proactive/inbox/cards.d.ts +21 -0
- package/dist/src/proactive/inbox/cards.js +266 -0
- package/dist/src/proactive/inbox/delivery.d.ts +6 -0
- package/dist/src/proactive/inbox/delivery.js +54 -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 +61 -0
- package/dist/src/proactive/inbox/notification-policy.d.ts +1 -0
- package/dist/src/proactive/inbox/notification-policy.js +22 -0
- package/dist/src/proactive/inbox/repository.d.ts +1 -0
- package/dist/src/proactive/inbox/repository.js +75 -12
- package/dist/src/proactive/inbox/types.d.ts +11 -1
- package/dist/src/proactive/inbox/worker.js +9 -3
- package/dist/src/proactive/index.js +2 -2
- package/dist/src/proactive/mail-thread.d.ts +13 -0
- package/dist/src/proactive/mail-thread.js +54 -0
- 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 +51 -0
- package/dist/src/proactive/policy/service.js +120 -0
- package/dist/src/proactive/routing/matcher.js +3 -2
- package/dist/src/proactive/scenarios/control.d.ts +87 -0
- package/dist/src/proactive/scenarios/control.js +108 -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 +4 -2
- package/dist/src/proactive/scenarios/repository.js +5 -1
- package/dist/src/proactive/service.js +1 -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.d.ts +1 -0
- package/dist/src/proactive/temporal/worker.js +24 -6
- 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/162_proactive_product.sql +7 -0
- package/dist/src/storage/sqlite/migrations/163_proactive_follow_ups.sql +29 -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/tasks/home-query-service.js +1 -1
- package/dist/src/tasks/index.js +4 -4
- package/dist/src/voice/dashscope/streaming-stt-session.js +1 -0
- package/dist/src/voice/dashscope/streaming-tts-stream.d.ts +1 -0
- package/dist/src/voice/dashscope/streaming-tts-stream.js +8 -0
- package/dist/src/voice/realtime/agentBroker.js +1 -1
- package/dist/src/voice/realtime/agentEngine.js +1 -1
- package/dist/src/voice/realtime/pcm-output-gain.d.ts +2 -0
- package/dist/src/voice/realtime/pcm-output-gain.js +16 -0
- package/dist/src/voice/realtime/runtime.d.ts +2 -1
- package/dist/src/voice/realtime/runtime.js +25 -7
- 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 +7 -5
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-J1YFNG26.js +0 -1
- package/dist/gateway/static/root/assets/automations-workspace-Bn8nwUOL.js +0 -6
- package/dist/gateway/static/root/assets/capabilities-settings-panel-C1GUih8m.js +0 -7
- package/dist/gateway/static/root/assets/connectors-page-IQAQDSmO.js +0 -2
- package/dist/gateway/static/root/assets/gateway-settings-B3H7Vfbh.js +0 -1
- package/dist/gateway/static/root/assets/home-page-CT4JL2jm.js +0 -1
- package/dist/gateway/static/root/assets/index-CRJrO4GI.css +0 -2
- package/dist/gateway/static/root/assets/logs-page-DrNaaPWc.js +0 -2
- package/dist/gateway/static/root/assets/note-detail-panel-Dbj5OvXE.js +0 -5
- package/dist/gateway/static/root/assets/notes-page-5hRB3WXc.js +0 -8
- package/dist/gateway/static/root/assets/project-detail-page-CblWLA8k.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-CGk-kzqs.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-Du8PweyU.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-BFm94dJC.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-C0H-cToA.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-CqF9s0pl.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-BBL_ZUSC.js +0 -1
- package/dist/gateway/static/root/assets/task-detail-page-D1FmRFIn.js +0 -1
- package/dist/gateway/static/root/assets/user-model-page-BGC_5baJ.js +0 -2
- package/dist/gateway/static/root/assets/workflow-run-setup-panel-BfCWdw8F.js +0 -3
- package/dist/gateway/static/root/assets/workflows-page-CvmKQkD0.js +0 -6
|
@@ -4,9 +4,9 @@ import { ExtensionLoader } from "../extensions/loader.js";
|
|
|
4
4
|
import "../extensions/index.js";
|
|
5
5
|
import { MessageBus } from "../infra/bus/queue.js";
|
|
6
6
|
import "../infra/bus/index.js";
|
|
7
|
-
import { createDefaultContext } from "./registry.js";
|
|
8
7
|
import { getWorkspacePath } from "../config/workspace-path-helpers.js";
|
|
9
8
|
import "../config/index.js";
|
|
9
|
+
import { createDefaultContext } from "./registry.js";
|
|
10
10
|
import { registerExtensionCliProgram } from "../extensions/sdk/channel-helpers.js";
|
|
11
11
|
import { join } from "path";
|
|
12
12
|
//#region src/cli/extension-cli-register.ts
|
package/dist/src/config/index.js
CHANGED
|
@@ -13,10 +13,10 @@ import { clearConfigValueCache, getAllowedCommands, getCacheStats, init_resolve_
|
|
|
13
13
|
import { CustomModelSchema, ImageGenerationCapabilitiesSchema, ImageGenerationModelSchema, ImageGenerationProviderSchema, ModelOverrideSchema, ModelsJsonSchema, OpenAICompatSchema, OpenAICompletionsCompatSchema, OpenAIResponsesCompatSchema, OpenRouterRoutingSchema, ProviderConfigSchema, VercelGatewayRoutingSchema, getDefaultModelValues, init_models_json, loadModelsJson, modelsJsonExists, saveModelsJson, validateModelsConfig } from "./models-json.js";
|
|
14
14
|
import { canonicalizeConfiguredMcpServer, isKnownCliMcpTypeAlias, normalizeConfiguredMcpServers, resolveXopcMcpTransportAlias } from "./mcp-config-normalize.js";
|
|
15
15
|
import { formatThinkingLevels, listThinkingLevels, normalizeElevatedMode, normalizeReasoningLevel, normalizeThinkLevel, normalizeVerboseLevel, thinkLevelToNumber } from "../agent/transcript/thinking-types.js";
|
|
16
|
+
import { diffConfigPaths } from "./diff.js";
|
|
16
17
|
import { getWorkspacePath } from "./workspace-path-helpers.js";
|
|
17
18
|
import { listAgentProfileMarkdownDirs, listAgentWorkspaceDirs } from "./workspace-dirs.js";
|
|
18
19
|
import { ProfileManager, createProfile, deleteProfile, getCurrentProfile, getProfileManager, getProfileNameFromDir, getSwitchCommand, listProfiles, resolveProfileStateDir } from "./profile.js";
|
|
19
|
-
import { diffConfigPaths } from "./diff.js";
|
|
20
20
|
import { BASE_RELOAD_RULES, buildReloadPlan, matchReloadRule } from "./rules.js";
|
|
21
21
|
import { ConfigHotReloader } from "./reload.js";
|
|
22
22
|
//#region src/config/index.ts
|
|
@@ -122,6 +122,9 @@ function normalizeCalendar(result) {
|
|
|
122
122
|
value: compact({
|
|
123
123
|
id: externalId,
|
|
124
124
|
title: text(event, "summary", "title", "name"),
|
|
125
|
+
description: text(event, "description"),
|
|
126
|
+
location: text(event, "location"),
|
|
127
|
+
allDay: Boolean(event.start && typeof event.start === "object" && "date" in event.start),
|
|
125
128
|
start: occurredAt,
|
|
126
129
|
end: time(event.end ?? event.endTime ?? event.end_time),
|
|
127
130
|
organizer: event.organizer,
|
|
@@ -20,7 +20,6 @@ import { registerLocalAppsRoutes } from "./local-apps.js";
|
|
|
20
20
|
import { registerWorkDiscoveryRoutes } from "./work-discovery.js";
|
|
21
21
|
import { registerContextSourceRoutes } from "./context-sources.js";
|
|
22
22
|
import { registerTaskRoutes } from "./tasks.js";
|
|
23
|
-
import { registerProactiveRoutes } from "./proactive.js";
|
|
24
23
|
import { registerMobilePrivacyRoutes } from "./mobile-privacy.js";
|
|
25
24
|
import { mountAppLazyRoutePrefixes, registerAuthenticatedLazyRouteFallback } from "./lazy-fallback.js";
|
|
26
25
|
//#region src/gateway/hono/routes/index.ts
|
|
@@ -40,7 +39,6 @@ function registerCoreAuthenticatedRoutes(authenticated, deps) {
|
|
|
40
39
|
registerWorkDiscoveryRoutes(authenticated, deps);
|
|
41
40
|
registerContextSourceRoutes(authenticated, deps);
|
|
42
41
|
registerTaskRoutes(authenticated, deps);
|
|
43
|
-
registerProactiveRoutes(authenticated, deps);
|
|
44
42
|
registerSearchRoutes(authenticated, deps);
|
|
45
43
|
registerDevicePushRoutes(authenticated);
|
|
46
44
|
registerNotificationRoutes(authenticated, deps);
|
|
@@ -3,6 +3,18 @@ function startsWithAny(path, prefixes) {
|
|
|
3
3
|
return prefixes.some((prefix) => path === prefix || path.startsWith(`${prefix}/`));
|
|
4
4
|
}
|
|
5
5
|
const AUTHENTICATED_LAZY_ROUTE_BUNDLES = [
|
|
6
|
+
{
|
|
7
|
+
id: "proactive",
|
|
8
|
+
match: (path) => startsWithAny(path, [
|
|
9
|
+
"/api/proactive",
|
|
10
|
+
"/api/inbox/judgments",
|
|
11
|
+
"/api/internal/proactive"
|
|
12
|
+
]),
|
|
13
|
+
load: async () => {
|
|
14
|
+
const { registerProactiveRoutes } = await import("./proactive.js");
|
|
15
|
+
return { register: registerProactiveRoutes };
|
|
16
|
+
}
|
|
17
|
+
},
|
|
6
18
|
{
|
|
7
19
|
id: "runtime-tools",
|
|
8
20
|
match: (path) => startsWithAny(path, ["/api/runtime-tools"]),
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { getSqliteDatabase } from "../../../storage/sqlite/transaction.js";
|
|
2
|
+
import { ProactiveConflict, proactivePreferences, updateProactivePreferences } from "../../../proactive/policy/service.js";
|
|
3
|
+
import { controlledSubscriptions, createControlledSubscription, requireSubscription, templateCatalog, updateControlledSubscription } from "../../../proactive/scenarios/control.js";
|
|
4
|
+
import { listMailFollowUps, mailFollowUpSources, startMailFollowUp, updateMailFollowUp } from "../../../proactive/follow-ups.js";
|
|
5
|
+
import { cardChanges, getCard, listCards, performCardAction } from "../../../proactive/inbox/cards.js";
|
|
6
|
+
import { checkDelegation, delegationOverview, startDelegation } from "../../../proactive/experience.js";
|
|
7
|
+
import { recordProactivePresence } from "../../../proactive/policy/presence.js";
|
|
8
|
+
import { digestCards } from "../../../proactive/inbox/digest.js";
|
|
9
|
+
import { acknowledgeBrowserProbe, listBrowserProbes, prepareBrowserPush, registerBrowserPush, testBrowserPush, unregisterBrowserPush } from "../../../notifications/web-push.js";
|
|
10
|
+
import { ReadonlyProactiveAgentExecutor } from "../../../proactive/execution/agent-executor.js";
|
|
11
|
+
import { proactiveMetrics } from "../../../proactive/metrics.js";
|
|
12
|
+
import { previewSubscription } from "../../../proactive/scenarios/preview.js";
|
|
13
|
+
import { ZodError } from "zod";
|
|
14
|
+
//#region src/gateway/hono/routes/proactive-control.ts
|
|
15
|
+
function registerProactiveControlRoutes(app, deps) {
|
|
16
|
+
app.onError((error, c) => c.json({
|
|
17
|
+
ok: false,
|
|
18
|
+
error: error instanceof ZodError ? "Invalid request" : error.message
|
|
19
|
+
}, error instanceof ProactiveConflict ? 409 : 400));
|
|
20
|
+
const workspace = () => deps.service.currentWorkspacePath;
|
|
21
|
+
app.get("/api/proactive/follow-ups/sources", (c) => c.json({
|
|
22
|
+
ok: true,
|
|
23
|
+
sources: mailFollowUpSources(workspace())
|
|
24
|
+
}));
|
|
25
|
+
app.get("/api/proactive/follow-ups", (c) => c.json({
|
|
26
|
+
ok: true,
|
|
27
|
+
followUps: listMailFollowUps(workspace())
|
|
28
|
+
}));
|
|
29
|
+
app.post("/api/proactive/follow-ups", deps.strictRateLimitMiddleware, async (c) => c.json({
|
|
30
|
+
ok: true,
|
|
31
|
+
followUp: startMailFollowUp(workspace(), await c.req.json())
|
|
32
|
+
}, 201));
|
|
33
|
+
app.patch("/api/proactive/follow-ups/:id", deps.strictRateLimitMiddleware, async (c) => c.json({
|
|
34
|
+
ok: true,
|
|
35
|
+
followUp: updateMailFollowUp(workspace(), c.req.param("id"), await c.req.json())
|
|
36
|
+
}));
|
|
37
|
+
app.get("/api/proactive/overview", (c) => c.json({
|
|
38
|
+
ok: true,
|
|
39
|
+
...delegationOverview(workspace())
|
|
40
|
+
}));
|
|
41
|
+
app.post("/api/proactive/delegations", deps.strictRateLimitMiddleware, async (c) => c.json({
|
|
42
|
+
ok: true,
|
|
43
|
+
subscription: startDelegation(workspace(), await c.req.json())
|
|
44
|
+
}, 201));
|
|
45
|
+
app.post("/api/proactive/subscriptions/:id/check", deps.strictRateLimitMiddleware, (c) => c.json({
|
|
46
|
+
ok: true,
|
|
47
|
+
...checkDelegation(workspace(), c.req.param("id"))
|
|
48
|
+
}, 202));
|
|
49
|
+
for (const path of ["/api/proactive/*", "/api/inbox/judgments/*"]) app.use(path, async (c, next) => {
|
|
50
|
+
try {
|
|
51
|
+
const id = c.req.path.match(/^\/api\/inbox\/judgments\/([^/]+)/)?.[1];
|
|
52
|
+
if (id && id !== "changes") getCard(decodeURIComponent(id), workspace());
|
|
53
|
+
await next();
|
|
54
|
+
} catch (error) {
|
|
55
|
+
return c.json({
|
|
56
|
+
ok: false,
|
|
57
|
+
error: error instanceof ZodError ? "Invalid request" : error instanceof Error ? error.message : "Request failed"
|
|
58
|
+
}, error instanceof ProactiveConflict ? 409 : 400);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
app.get("/api/proactive/web-push/probes", (c) => c.json({
|
|
62
|
+
ok: true,
|
|
63
|
+
probes: listBrowserProbes(workspace())
|
|
64
|
+
}));
|
|
65
|
+
app.post("/api/proactive/web-push/subscriptions/:id/test", deps.strictRateLimitMiddleware, async (c) => c.json({
|
|
66
|
+
ok: true,
|
|
67
|
+
...await testBrowserPush(workspace(), c.req.param("id"))
|
|
68
|
+
}));
|
|
69
|
+
app.post("/api/proactive/web-push/probes/:id/opened", deps.strictRateLimitMiddleware, (c) => {
|
|
70
|
+
acknowledgeBrowserProbe(workspace(), c.req.param("id"));
|
|
71
|
+
return c.json({ ok: true });
|
|
72
|
+
});
|
|
73
|
+
app.post("/api/proactive/web-push/prepare", deps.strictRateLimitMiddleware, (c) => c.json({
|
|
74
|
+
ok: true,
|
|
75
|
+
...prepareBrowserPush()
|
|
76
|
+
}));
|
|
77
|
+
app.post("/api/proactive/web-push/subscriptions", deps.strictRateLimitMiddleware, async (c) => c.json({
|
|
78
|
+
ok: true,
|
|
79
|
+
...registerBrowserPush(workspace(), await c.req.json())
|
|
80
|
+
}, 201));
|
|
81
|
+
app.delete("/api/proactive/web-push/subscriptions/:id", deps.strictRateLimitMiddleware, (c) => {
|
|
82
|
+
unregisterBrowserPush(workspace(), c.req.param("id"));
|
|
83
|
+
return c.json({ ok: true });
|
|
84
|
+
});
|
|
85
|
+
app.post("/api/proactive/presence", deps.strictRateLimitMiddleware, async (c) => {
|
|
86
|
+
recordProactivePresence(workspace(), await c.req.json());
|
|
87
|
+
return c.json({ ok: true });
|
|
88
|
+
});
|
|
89
|
+
app.get("/api/proactive/metrics", (c) => c.json({
|
|
90
|
+
ok: true,
|
|
91
|
+
metrics: proactiveMetrics(workspace())
|
|
92
|
+
}));
|
|
93
|
+
app.get("/api/proactive/digests/:id", (c) => c.json({
|
|
94
|
+
ok: true,
|
|
95
|
+
cards: digestCards(c.req.param("id"), workspace())
|
|
96
|
+
}));
|
|
97
|
+
app.post("/api/proactive/subscriptions/:id/preview", deps.strictRateLimitMiddleware, async (c) => c.json({
|
|
98
|
+
ok: true,
|
|
99
|
+
...await previewSubscription(workspace(), c.req.param("id"), new ReadonlyProactiveAgentExecutor(() => deps.service.getConfig()), c.req.raw.signal)
|
|
100
|
+
}));
|
|
101
|
+
app.get("/api/proactive/templates", (c) => c.json({
|
|
102
|
+
ok: true,
|
|
103
|
+
templates: templateCatalog(workspace())
|
|
104
|
+
}));
|
|
105
|
+
app.get("/api/proactive/preferences", (c) => c.json({
|
|
106
|
+
ok: true,
|
|
107
|
+
preferences: proactivePreferences(workspace())
|
|
108
|
+
}));
|
|
109
|
+
app.patch("/api/proactive/preferences", deps.strictRateLimitMiddleware, async (c) => c.json({
|
|
110
|
+
ok: true,
|
|
111
|
+
preferences: updateProactivePreferences(workspace(), await c.req.json())
|
|
112
|
+
}));
|
|
113
|
+
app.get("/api/proactive/subscriptions", (c) => c.json({
|
|
114
|
+
ok: true,
|
|
115
|
+
subscriptions: controlledSubscriptions(workspace())
|
|
116
|
+
}));
|
|
117
|
+
app.post("/api/proactive/subscriptions", deps.strictRateLimitMiddleware, async (c) => c.json({
|
|
118
|
+
ok: true,
|
|
119
|
+
subscription: createControlledSubscription(workspace(), await c.req.json())
|
|
120
|
+
}, 201));
|
|
121
|
+
app.patch("/api/proactive/subscriptions/:id", deps.strictRateLimitMiddleware, async (c) => c.json({
|
|
122
|
+
ok: true,
|
|
123
|
+
subscription: updateControlledSubscription(workspace(), c.req.param("id"), await c.req.json())
|
|
124
|
+
}));
|
|
125
|
+
app.get("/api/proactive/subscriptions/:id/runs", (c) => {
|
|
126
|
+
requireSubscription(c.req.param("id"), workspace());
|
|
127
|
+
return c.json({
|
|
128
|
+
ok: true,
|
|
129
|
+
runs: getSqliteDatabase().prepare(`SELECT run_id AS id, status, outcome_reason AS reason,
|
|
130
|
+
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"))
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
app.get("/api/proactive/cards", (c) => c.json({
|
|
134
|
+
ok: true,
|
|
135
|
+
...listCards(workspace(), {
|
|
136
|
+
status: c.req.query("status"),
|
|
137
|
+
before: c.req.query("before")
|
|
138
|
+
})
|
|
139
|
+
}));
|
|
140
|
+
app.get("/api/inbox/judgments/changes", (c) => {
|
|
141
|
+
const cursor = Number(c.req.query("cursor") ?? 0);
|
|
142
|
+
if (!Number.isSafeInteger(cursor) || cursor < 0) return c.json({
|
|
143
|
+
ok: false,
|
|
144
|
+
error: "Invalid cursor"
|
|
145
|
+
}, 400);
|
|
146
|
+
return c.json({
|
|
147
|
+
ok: true,
|
|
148
|
+
...cardChanges(workspace(), cursor)
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
app.get("/api/inbox/judgments/:itemId", (c) => c.json({
|
|
152
|
+
ok: true,
|
|
153
|
+
card: getCard(c.req.param("itemId"), workspace())
|
|
154
|
+
}));
|
|
155
|
+
app.post("/api/inbox/judgments/:itemId/actions", deps.strictRateLimitMiddleware, async (c) => {
|
|
156
|
+
const card = performCardAction(c.req.param("itemId"), workspace(), await c.req.json());
|
|
157
|
+
deps.service.emit("proactive.card.changed", {
|
|
158
|
+
cardId: card.id,
|
|
159
|
+
revision: card.revision
|
|
160
|
+
});
|
|
161
|
+
return c.json({
|
|
162
|
+
ok: true,
|
|
163
|
+
card
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
//#endregion
|
|
168
|
+
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) => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { loadConfig } from "../config/loader.js";
|
|
2
|
-
import "../config/index.js";
|
|
3
2
|
import { isRestartEnabled } from "../config/commands.flags.js";
|
|
3
|
+
import "../config/index.js";
|
|
4
4
|
import { runBootstrapMigrationsSync } from "../migrations/runner.js";
|
|
5
5
|
import { restartGatewayProcessWithFreshPid } from "./respawn.js";
|
|
6
6
|
import { acquireGatewayLock } from "./lock.js";
|
|
@@ -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,6 +1,6 @@
|
|
|
1
1
|
import { resolveGatewayBindHost, resolveGatewayListenHosts } from "../config/gateway-bind.js";
|
|
2
|
-
import { ensureXopcCliOnPath } from "../infra/path-env.js";
|
|
3
2
|
import { resolveGatewayListenPlan } from "./listen.js";
|
|
3
|
+
import { ensureXopcCliOnPath } from "../infra/path-env.js";
|
|
4
4
|
import { GatewayService } from "./service.js";
|
|
5
5
|
import { handleSiteShareUpgrade } from "../share/site-share-router.js";
|
|
6
6
|
import { createHonoApp } from "./hono/app.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;
|
|
@@ -31,11 +31,13 @@ import { resolveProjectAgentId } from "../projects/project-agent.js";
|
|
|
31
31
|
import "../projects/index.js";
|
|
32
32
|
import { resolveEffectiveGatewayPort } from "./host.js";
|
|
33
33
|
import { onSessionTranscriptUpdate } from "../session/transcript-events.js";
|
|
34
|
+
import { ProactiveScenarioService } from "../proactive/scenarios/service.js";
|
|
35
|
+
import { ProactiveEventService } from "../proactive/service.js";
|
|
36
|
+
import { TaskApplicationService } from "../tasks/task-application-service.js";
|
|
37
|
+
import { ProactiveInboxService } from "../proactive/inbox/service.js";
|
|
34
38
|
import { AutomationService } from "../automations/service/automation-service.js";
|
|
35
39
|
import { onAutomationProductEvent, publishAutomationProductEvent } from "../automations/product-events.js";
|
|
36
40
|
import "../automations/index.js";
|
|
37
|
-
import { TaskApplicationService } from "../tasks/task-application-service.js";
|
|
38
|
-
import { ProactiveScenarioService } from "../proactive/scenarios/service.js";
|
|
39
41
|
import { TaskOutboxDispatcher } from "../tasks/task-outbox-dispatcher.js";
|
|
40
42
|
import { TaskRunDispatcher } from "../tasks/task-run-dispatcher.js";
|
|
41
43
|
import { TaskSignalService } from "../tasks/task-signal-service.js";
|
|
@@ -72,6 +74,7 @@ import "../endpoint-tools/index.js";
|
|
|
72
74
|
import { assertGatewayAuthConfigured, extractToken, resolveGatewayAuth, validateToken } from "./auth.js";
|
|
73
75
|
import { prepareAutomationAgentSession } from "./automation-agent-session.js";
|
|
74
76
|
import { stopTailscaleExposure } from "./tailscale-lifecycle.js";
|
|
77
|
+
import { deliverProactiveCard } from "../proactive/inbox/delivery.js";
|
|
75
78
|
import { buildVoiceMemoryContext } from "../voice/realtime/memory-context.js";
|
|
76
79
|
import { buildVoicePersonaContext } from "../voice/realtime/persona-context.js";
|
|
77
80
|
import { voiceMemoryBudget, voicePersonaBudget } from "../voice/realtime/conversation-context.js";
|
|
@@ -106,12 +109,10 @@ import "../local-apps/index.js";
|
|
|
106
109
|
import { createRuntimeBrowserAutomationService } from "../browser/automations/runtime-service.js";
|
|
107
110
|
import "../browser/automations/index.js";
|
|
108
111
|
import { mapProductEventToProactive } from "../proactive/events/product-event-bridge.js";
|
|
109
|
-
import { ProactiveEventService } from "../proactive/service.js";
|
|
110
112
|
import { ReadonlyProactiveAgentExecutor } from "../proactive/execution/agent-executor.js";
|
|
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();
|
|
@@ -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 };
|