@xopcai/xopc 0.0.269 → 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-DcwCSY6s.js → activity-store-D_0FmdRj.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-D0NBOWC4.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-DzG2qw-c.js +1 -0
- package/dist/gateway/static/root/assets/{api-eaPO-mdr.js → api-O3TTQ4qN.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-E3xm2teY.js → app-management-settings-panel-Cqqsbzri.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-CiZOjgls.js → appearance-settings-DaJyf32s.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-B4lX6yoT.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-D09yo_Hc.js → archive-plugin-kDPnDTJI.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-CNYb8Qru.js → attachment-load-CJ3VceKS.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-DsrfW5ii.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-OWlaGqlY.js → binary-plugins-DzyZXLBX.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-CVND3M6r.js → block-editor-kTt3gYIJ.js} +3 -3
- package/dist/gateway/static/root/assets/{browser-automation-inputs-D7IzVK_J.js → browser-automation-inputs-BKohPYR4.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-automations-page-CQ6cCpIv.js → browser-automations-page-ktQfFPk-.js} +2 -2
- package/dist/gateway/static/root/assets/browser-settings-page-Dgdt5uVL.js +8 -0
- package/dist/gateway/static/root/assets/capabilities-settings-panel-BpDW-R9f.js +7 -0
- package/dist/gateway/static/root/assets/channels-settings-DU4EQnR0.js +1 -0
- package/dist/gateway/static/root/assets/{channels-status-swr-D4JrgJKa.js → channels-status-swr-DrqzYmDr.js} +1 -1
- package/dist/gateway/static/root/assets/{chat-terminal-dock-BUjnhT7C.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-DlyRIyUn.js → cron-expression-BNwbnrEb.js} +1 -1
- package/dist/gateway/static/root/assets/{date-picker-CU-ij_yE.js → date-picker-DKyirU4K.js} +1 -1
- package/dist/gateway/static/root/assets/{dependency-picker-Z6Nf0Wjq.js → dependency-picker-D3vNIjRI.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-C0F5Iqnc.js → desktop-pet-fQwRb_3p.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-Bj_W6HL1.js → desktop-pet-settings-DfOJ-GvT.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-Ba09EnAn.js → extension-debug-page-Cn53jB5-.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-C88aGXJs.js → extension-page-IDpLCxpC.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-CMyt0A32.js → extension-settings-page-B1dds2bP.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-swr-bjzk_4hn.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-DrbIzFyB.js → gateway-startup-retry-JGhGMhVZ.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-settings-BnrMRKaZ.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-CBWU9Ner.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-CfyyA9-g.js → index-OMnem2nr.js} +47 -47
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-B8Z7kKQY.js → keyboard-shortcuts-settings-CBvMTFFx.js} +1 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-bj75v2ZE.js +2 -0
- package/dist/gateway/static/root/assets/{local-apps-page-CLSfzkRp.js → local-apps-page-APCMNDvU.js} +1 -1
- package/dist/gateway/static/root/assets/{locale-store-BQ2HKTWb.js → locale-store-BThkG0W5.js} +1 -1
- package/dist/gateway/static/root/assets/{logs-page-CWDU1AGN.js → logs-page-BX7n39zV.js} +2 -2
- package/dist/gateway/static/root/assets/{management-settings-CuFNgQUy.js → management-settings-CM62j8ZX.js} +1 -1
- package/dist/gateway/static/root/assets/{markdown-view-DIcfrLmG.js → markdown-view-BwjpJVPs.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-CSv6-xTA.js → media-plugins-C10byeaa.js} +1 -1
- package/dist/gateway/static/root/assets/{messages-BRjoarIr.js → messages-D0V_bgRP.js} +2 -2
- package/dist/gateway/static/root/assets/{mobile-pairing-wizard-C7d_ztgp.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-BfV-PQa5.js → page-tabs-qQ36zncF.js} +1 -1
- package/dist/gateway/static/root/assets/{preview-open-alternatives-DQS7NFpg.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-BIhjZLKg.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-CwveUfe8.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-DMQ0wpNg.js → runtime-tools-settings-panel-bu_mwBTr.js} +2 -2
- package/dist/gateway/static/root/assets/{schema-form-C91g2PRU.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-Cem6L49Y.js → settings-form-section-CBo517lV.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-afDUxqlV.js → settings-page-DBPimx93.js} +1 -1
- package/dist/gateway/static/root/assets/{setup-status-panel-Cc_iP_vv.js → setup-status-panel-J3AnooPW.js} +1 -1
- package/dist/gateway/static/root/assets/{share-preview-page-CVEVHksg.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-CNrq1W6C.js → skills-page-Cn_-nvRo.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page.utils-D1wGfm22.js → skills-page.utils-CfVAc_lu.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-BLE8PxWE.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-BejLVjIT.js → theme-store-1wryLgBQ.js} +1 -1
- package/dist/gateway/static/root/assets/{tunnel-api-Dur80zSQ.js → tunnel-api-Cgpnm2fL.js} +1 -1
- package/dist/gateway/static/root/assets/{use-autosave-DmgEA8Qb.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-sZ0J83SF.js → voice-api-key-field-DMsyVfri.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-config-api-BEbz3avx.js → voice-config-api-QWVmiAp3.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-overlay-BXnAlbmO.js → work-discovery-overlay-BC0vAxp1.js} +1 -1
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-BkwFey0a.js → workflow-run-setup-panel-Cz9jQIlP.js} +2 -2
- package/dist/gateway/static/root/assets/workflows-page-DA6OOK6X.js +6 -0
- package/dist/gateway/static/root/index.html +10 -10
- package/dist/package.js +1 -1
- package/dist/packages/gateway-contract/src/notifications.js +2 -2
- package/dist/packages/gateway-contract/src/proactive.js +22 -6
- 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/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/connectors.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-ingestion.js +1 -1
- package/dist/src/connectors/connected-source-normalizers.js +3 -0
- package/dist/src/connectors/connection-recovery-service.js +1 -1
- package/dist/src/connectors/health.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/mcp.js +1 -1
- package/dist/src/gateway/hono/routes/proactive-control.js +31 -24
- package/dist/src/gateway/run-loop.js +1 -1
- package/dist/src/gateway/server.js +1 -1
- package/dist/src/gateway/service.js +10 -10
- package/dist/src/notifications/web-push.js +1 -1
- package/dist/src/proactive/actions/service.js +4 -2
- package/dist/src/proactive/execution/authorization.d.ts +2 -0
- package/dist/src/proactive/execution/authorization.js +39 -1
- package/dist/src/proactive/execution/context.d.ts +4 -0
- package/dist/src/proactive/execution/context.js +51 -5
- package/dist/src/proactive/execution/insight.js +3 -1
- package/dist/src/proactive/execution/repository.js +15 -5
- package/dist/src/proactive/execution/types.d.ts +2 -0
- package/dist/src/proactive/execution/worker.js +7 -2
- 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.js +35 -6
- package/dist/src/proactive/inbox/delivery.js +4 -2
- package/dist/src/proactive/inbox/digest.js +2 -2
- package/dist/src/proactive/inbox/lifecycle.js +4 -1
- package/dist/src/proactive/inbox/notification-policy.js +4 -2
- package/dist/src/proactive/inbox/repository.js +17 -11
- package/dist/src/proactive/inbox/types.d.ts +2 -0
- package/dist/src/proactive/inbox/worker.js +1 -1
- 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/policy/service.d.ts +2 -4
- package/dist/src/proactive/policy/service.js +3 -5
- package/dist/src/proactive/scenarios/control.d.ts +4 -7
- package/dist/src/proactive/scenarios/control.js +3 -4
- package/dist/src/proactive/scenarios/preview.js +1 -1
- package/dist/src/proactive/scenarios/prompt-composer.js +2 -0
- package/dist/src/proactive/service.js +1 -1
- package/dist/src/proactive/temporal/worker.d.ts +1 -0
- package/dist/src/proactive/temporal/worker.js +18 -4
- 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/tui/tui-startup-resources.js +1 -1
- 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.js +4 -2
- package/dist/src/workflows/service/workflow-run-service.js +1 -1
- package/package.json +2 -2
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-qKCezlBg.js +0 -1
- package/dist/gateway/static/root/assets/agents-BMhnZKhP.js +0 -1
- package/dist/gateway/static/root/assets/apps-page-DduJDWGY.js +0 -1
- package/dist/gateway/static/root/assets/automations-workspace-X7hNHCjW.js +0 -6
- package/dist/gateway/static/root/assets/browser-settings-page-BZ7nK_pN.js +0 -8
- package/dist/gateway/static/root/assets/capabilities-settings-panel-BfKvJO1C.js +0 -7
- package/dist/gateway/static/root/assets/channels-settings-D1UDxJuA.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-C2nuqs_O.js +0 -2
- package/dist/gateway/static/root/assets/gateway-settings-ogv8ZbvG.js +0 -1
- package/dist/gateway/static/root/assets/home-page-CbcJCREd.js +0 -1
- package/dist/gateway/static/root/assets/index-7PZ6jmhy.css +0 -2
- package/dist/gateway/static/root/assets/local-app-workbench-page-D5XVZnK1.js +0 -2
- package/dist/gateway/static/root/assets/note-detail-panel-D5JuBLyt.js +0 -5
- package/dist/gateway/static/root/assets/notes-page-C5-ccCi4.js +0 -8
- package/dist/gateway/static/root/assets/proactive-page-fHjPigmx.js +0 -1
- package/dist/gateway/static/root/assets/project-detail-page-6v_khvEt.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-CCy1aK4V.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-pkqKRnch.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-Cr4E4cap.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-D1JRDRyL.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-BrMECMAB.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-DuqIDYjc.js +0 -1
- package/dist/gateway/static/root/assets/task-detail-page-m0oXUKl2.js +0 -1
- package/dist/gateway/static/root/assets/user-model-page-Dl10D_5q.js +0 -2
- package/dist/gateway/static/root/assets/workflows-page-CswgoIFU.js +0 -6
- package/dist/src/proactive/actions/workflow.d.ts +0 -15
- package/dist/src/proactive/actions/workflow.js +0 -88
|
@@ -1,26 +1,51 @@
|
|
|
1
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
2
|
import { ProactiveConflict, proactivePreferences, updateProactivePreferences } from "../../../proactive/policy/service.js";
|
|
6
|
-
import { recordProactivePresence } from "../../../proactive/policy/presence.js";
|
|
7
3
|
import { controlledSubscriptions, createControlledSubscription, requireSubscription, templateCatalog, updateControlledSubscription } from "../../../proactive/scenarios/control.js";
|
|
4
|
+
import { listMailFollowUps, mailFollowUpSources, startMailFollowUp, updateMailFollowUp } from "../../../proactive/follow-ups.js";
|
|
8
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";
|
|
9
8
|
import { digestCards } from "../../../proactive/inbox/digest.js";
|
|
10
9
|
import { acknowledgeBrowserProbe, listBrowserProbes, prepareBrowserPush, registerBrowserPush, testBrowserPush, unregisterBrowserPush } from "../../../notifications/web-push.js";
|
|
11
10
|
import { ReadonlyProactiveAgentExecutor } from "../../../proactive/execution/agent-executor.js";
|
|
12
11
|
import { proactiveMetrics } from "../../../proactive/metrics.js";
|
|
13
|
-
import { prepareCardWorkflow, workflowForCard } from "../../../proactive/actions/workflow.js";
|
|
14
12
|
import { previewSubscription } from "../../../proactive/scenarios/preview.js";
|
|
15
13
|
import { ZodError } from "zod";
|
|
16
14
|
//#region src/gateway/hono/routes/proactive-control.ts
|
|
17
|
-
init_resolve_route();
|
|
18
15
|
function registerProactiveControlRoutes(app, deps) {
|
|
19
16
|
app.onError((error, c) => c.json({
|
|
20
17
|
ok: false,
|
|
21
18
|
error: error instanceof ZodError ? "Invalid request" : error.message
|
|
22
19
|
}, error instanceof ProactiveConflict ? 409 : 400));
|
|
23
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));
|
|
24
49
|
for (const path of ["/api/proactive/*", "/api/inbox/judgments/*"]) app.use(path, async (c, next) => {
|
|
25
50
|
try {
|
|
26
51
|
const id = c.req.path.match(/^\/api\/inbox\/judgments\/([^/]+)/)?.[1];
|
|
@@ -57,24 +82,6 @@ function registerProactiveControlRoutes(app, deps) {
|
|
|
57
82
|
unregisterBrowserPush(workspace(), c.req.param("id"));
|
|
58
83
|
return c.json({ ok: true });
|
|
59
84
|
});
|
|
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
85
|
app.post("/api/proactive/presence", deps.strictRateLimitMiddleware, async (c) => {
|
|
79
86
|
recordProactivePresence(workspace(), await c.req.json());
|
|
80
87
|
return c.json({ ok: true });
|
|
@@ -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";
|
|
@@ -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";
|
|
@@ -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";
|
|
@@ -54,12 +56,6 @@ import { registerClarificationChannelRuntime } from "./clarify-runtime.js";
|
|
|
54
56
|
import { ChannelManager } from "../channels/manager.js";
|
|
55
57
|
import { getWorkspacePath } from "../config/workspace-path-helpers.js";
|
|
56
58
|
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";
|
|
63
59
|
import { ManagedComposioEventPoller } from "../connectors/composio-managed-events.js";
|
|
64
60
|
import { startConnectedKnowledgeCoordinator } from "../knowledge/coordinator.js";
|
|
65
61
|
import "../knowledge/index.js";
|
|
@@ -67,12 +63,17 @@ import { ConnectionRecoveryService } from "../connectors/connection-recovery-ser
|
|
|
67
63
|
import { startConnectorLearningCoordinator } from "../connectors/learning-coordinator.js";
|
|
68
64
|
import { ConnectedSourceChangePublisher } from "../connectors/source-change-publisher.js";
|
|
69
65
|
import { startConnectorSupervisor } from "../connectors/supervisor.js";
|
|
66
|
+
import { DiscussionService } from "../discussions/service.js";
|
|
67
|
+
import { DiscussionOrganizer } from "../discussions/organizer.js";
|
|
68
|
+
import { DiscussionLiveWorker } from "../discussions/live-worker.js";
|
|
69
|
+
import { DiscussionOrganizerWorker } from "../discussions/organizer-worker.js";
|
|
70
|
+
import { DiscussionSealer } from "../discussions/sealer.js";
|
|
71
|
+
import "../discussions/index.js";
|
|
70
72
|
import { EndpointToolRuntime } from "../endpoint-tools/runtime.js";
|
|
71
73
|
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";
|
|
75
|
-
import { ProactiveInboxService } from "../proactive/inbox/service.js";
|
|
76
77
|
import { deliverProactiveCard } from "../proactive/inbox/delivery.js";
|
|
77
78
|
import { buildVoiceMemoryContext } from "../voice/realtime/memory-context.js";
|
|
78
79
|
import { buildVoicePersonaContext } from "../voice/realtime/persona-context.js";
|
|
@@ -108,7 +109,6 @@ import "../local-apps/index.js";
|
|
|
108
109
|
import { createRuntimeBrowserAutomationService } from "../browser/automations/runtime-service.js";
|
|
109
110
|
import "../browser/automations/index.js";
|
|
110
111
|
import { mapProductEventToProactive } from "../proactive/events/product-event-bridge.js";
|
|
111
|
-
import { ProactiveEventService } from "../proactive/service.js";
|
|
112
112
|
import { ReadonlyProactiveAgentExecutor } from "../proactive/execution/agent-executor.js";
|
|
113
113
|
import { listInsights } from "../proactive/execution/repository.js";
|
|
114
114
|
import { ProactiveWorker } from "../proactive/execution/worker.js";
|
|
@@ -152,7 +152,7 @@ async function testBrowserPush(workspaceId, subscriptionId, send = webPush.sendN
|
|
|
152
152
|
id,
|
|
153
153
|
title: "xopc 推送测试 / Push test",
|
|
154
154
|
body: "点击此通知确认打开 / Tap to confirm opening",
|
|
155
|
-
route: `/
|
|
155
|
+
route: `/assistant-work?probe=${encodeURIComponent(id)}`
|
|
156
156
|
}), {
|
|
157
157
|
vapidDetails: {
|
|
158
158
|
subject: "https://xopc.ai",
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { getSqliteDatabase, runSqliteWriteTransaction } from "../../storage/sqlite/transaction.js";
|
|
2
|
-
import {
|
|
2
|
+
import { insightSourcesAuthorized, insightSourcesChanged } from "../execution/authorization.js";
|
|
3
3
|
import { effectiveProactivePolicy } from "../policy/service.js";
|
|
4
|
-
import { insightSourcesAuthorized } from "../execution/authorization.js";
|
|
5
4
|
import { insightCorrelation } from "../inbox/lifecycle.js";
|
|
5
|
+
import { TaskApplicationService } from "../../tasks/task-application-service.js";
|
|
6
6
|
//#region src/proactive/actions/service.ts
|
|
7
7
|
function projectIdFromAggregationKey(value) {
|
|
8
8
|
if (!value.startsWith("project:") || value.length === 8) throw new Error("Proactive action has no project scope");
|
|
@@ -13,6 +13,7 @@ function executeClaimedAction(row, now = /* @__PURE__ */ new Date()) {
|
|
|
13
13
|
try {
|
|
14
14
|
if (getSqliteDatabase().prepare("SELECT 1 FROM proactive_inbox_items WHERE insight_id = ? AND withdrawn_at IS NOT NULL").get(row.insight_id)) throw new Error("Card was withdrawn");
|
|
15
15
|
if (!insightSourcesAuthorized(row.insight_id)) throw new Error("Source permission is no longer available");
|
|
16
|
+
if (insightSourcesChanged(row.insight_id)) throw new Error("Source changed; review updated work before acting");
|
|
16
17
|
if (!effectiveProactivePolicy(row.subscription_id).enabled) throw new Error("Proactive subscription paused");
|
|
17
18
|
const permission = getSqliteDatabase().prepare(`SELECT mode, allowed_actions_json FROM project_monitoring_policies WHERE project_id = ?`).get(projectIdFromAggregationKey(row.aggregation_key));
|
|
18
19
|
if (!getSqliteDatabase().prepare(`SELECT 1 FROM proactive_decisions d JOIN proactive_inbox_items i USING(inbox_item_id) WHERE i.insight_id = ? AND d.choice = 'approve'`).get(row.insight_id) && !(permission?.mode === "auto_low_risk" && JSON.parse(permission.allowed_actions_json).includes(action.id))) throw new Error("Action permission is no longer available");
|
|
@@ -48,6 +49,7 @@ function executeClaimedAction(row, now = /* @__PURE__ */ new Date()) {
|
|
|
48
49
|
getSqliteDatabase().prepare(`UPDATE proactive_insights
|
|
49
50
|
SET action_status = 'completed', action_result_json = ?, action_error = NULL, action_updated_at = ?
|
|
50
51
|
WHERE insight_id = ? AND action_status = 'executing'`).run(JSON.stringify({ taskId: result.model.task.id }), now.toISOString(), row.insight_id);
|
|
52
|
+
getSqliteDatabase().prepare("UPDATE proactive_inbox_items SET status = 'read', resolution = NULL, updated_at = ? WHERE insight_id = ?").run(now.toISOString(), row.insight_id);
|
|
51
53
|
} catch (error) {
|
|
52
54
|
getSqliteDatabase().prepare(`UPDATE proactive_insights
|
|
53
55
|
SET action_status = 'failed', action_error = ?, action_updated_at = ?
|
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
/** Recheck connector consent for stored cards and actions, not just model input. */
|
|
2
2
|
export declare function insightSourcesAuthorized(insightId: string): boolean;
|
|
3
|
+
/** Compare versions, not generated prose, before showing or executing prepared work. */
|
|
4
|
+
export declare function insightSourcesChanged(insightId: string): boolean;
|
|
3
5
|
export declare function authorizedConnectedSource(itemId: string, workspaceId: string, scenarioKey: string, agentId?: string | null): import("../../knowledge/types.js").KnowledgeSourceItem;
|
|
@@ -1,14 +1,52 @@
|
|
|
1
1
|
import { getSqliteDatabase } from "../../storage/sqlite/transaction.js";
|
|
2
2
|
import { getKnowledgeSourceItem } from "../../storage/sqlite/knowledge-repository.js";
|
|
3
3
|
import { getConnectorSyncPolicyForConnection } from "../../storage/sqlite/connector-sync-policy-repository.js";
|
|
4
|
+
import { readMailThread } from "../mail-thread.js";
|
|
4
5
|
//#region src/proactive/execution/authorization.ts
|
|
5
6
|
/** Recheck connector consent for stored cards and actions, not just model input. */
|
|
6
7
|
function insightSourcesAuthorized(insightId) {
|
|
8
|
+
const snapshot = getSqliteDatabase().prepare(`SELECT s.workspace_id, x.scenario_key, c.evidence_ids_json
|
|
9
|
+
FROM proactive_insights x JOIN proactive_scenario_subscriptions s USING(subscription_id)
|
|
10
|
+
JOIN proactive_runs r USING(run_id) LEFT JOIN proactive_context_snapshots c ON c.snapshot_id = r.context_snapshot_id
|
|
11
|
+
WHERE x.insight_id = ?`).get(insightId);
|
|
12
|
+
if (snapshot?.evidence_ids_json) {
|
|
13
|
+
if (JSON.parse(snapshot.evidence_ids_json).some((id) => id.startsWith("source-item:") && !authorizedConnectedSource(id.slice(12), snapshot.workspace_id, snapshot.scenario_key))) return false;
|
|
14
|
+
}
|
|
7
15
|
return getSqliteDatabase().prepare(`SELECT e.subject_id, e.workspace_id, x.scenario_key
|
|
8
16
|
FROM proactive_insights x JOIN proactive_runs r USING(run_id)
|
|
9
17
|
JOIN proactive_batch_events be ON be.batch_id = r.batch_id JOIN proactive_events e USING(event_id)
|
|
10
18
|
WHERE x.insight_id = ? AND e.type LIKE 'connected_source.%'`).all(insightId).every((row) => Boolean(authorizedConnectedSource(row.subject_id, row.workspace_id, row.scenario_key)));
|
|
11
19
|
}
|
|
20
|
+
/** Compare versions, not generated prose, before showing or executing prepared work. */
|
|
21
|
+
function insightSourcesChanged(insightId) {
|
|
22
|
+
const db = getSqliteDatabase();
|
|
23
|
+
const row = db.prepare(`SELECT c.content_json FROM proactive_insights x JOIN proactive_runs r USING(run_id)
|
|
24
|
+
JOIN proactive_context_snapshots c ON c.snapshot_id = r.context_snapshot_id WHERE x.insight_id = ?`).get(insightId);
|
|
25
|
+
if (!row) return false;
|
|
26
|
+
const snapshot = JSON.parse(row.content_json);
|
|
27
|
+
if (snapshot.follow_up?.followUpId) {
|
|
28
|
+
const follow = db.prepare("SELECT source_item_id, revision, status, due_at FROM proactive_follow_ups WHERE id = ?").get(snapshot.follow_up.followUpId);
|
|
29
|
+
if (!follow || follow.status !== "watching" || follow.revision !== snapshot.follow_up.revision || Date.parse(follow.due_at) <= Date.now() !== snapshot.follow_up.deadlinePassed || readMailThread(follow.source_item_id)?.fingerprint !== snapshot.follow_up.fingerprint) return true;
|
|
30
|
+
}
|
|
31
|
+
for (const source of [...snapshot.connected_source?.items ?? [], ...snapshot.follow_up?.items ?? []]) {
|
|
32
|
+
const current = getKnowledgeSourceItem(source.sourceItemId);
|
|
33
|
+
if (!current || current.deletedAt || current.contentHash !== source.contentHash || current.occurredAt !== source.occurredAt) return true;
|
|
34
|
+
}
|
|
35
|
+
const project = snapshot.project_state?.project;
|
|
36
|
+
if (project) {
|
|
37
|
+
const current = db.prepare("SELECT updated_at FROM projects WHERE project_id = ?").get(project.project_id);
|
|
38
|
+
if (!current || current.updated_at !== project.updated_at) return true;
|
|
39
|
+
}
|
|
40
|
+
for (const task of [...snapshot.project_state?.activeTasks ?? [], ...snapshot.meeting_workspace?.activeTasks ?? []]) {
|
|
41
|
+
const current = db.prepare("SELECT updated_at FROM tasks WHERE task_id = ?").get(task.task_id);
|
|
42
|
+
if (!current || current.updated_at !== task.updated_at) return true;
|
|
43
|
+
}
|
|
44
|
+
for (const note of snapshot.meeting_workspace?.recentNotes ?? []) {
|
|
45
|
+
const current = db.prepare("SELECT updated_at FROM notes WHERE note_id = ?").get(note.note_id);
|
|
46
|
+
if (!current || current.updated_at !== note.updated_at) return true;
|
|
47
|
+
}
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
12
50
|
function authorizedConnectedSource(itemId, workspaceId, scenarioKey, agentId) {
|
|
13
51
|
const item = getKnowledgeSourceItem(itemId);
|
|
14
52
|
if (!item || item.deletedAt || item.metadata.workspaceId !== workspaceId || item.sensitivity === "secret" || item.sensitivity === "regulated") return null;
|
|
@@ -20,4 +58,4 @@ function authorizedConnectedSource(itemId, workspaceId, scenarioKey, agentId) {
|
|
|
20
58
|
return policy?.scanEnabled && policy.proactiveEnabled && (!policy.allowedScenarioKeys.length || policy.allowedScenarioKeys.includes(scenarioKey)) ? item : null;
|
|
21
59
|
}
|
|
22
60
|
//#endregion
|
|
23
|
-
export { authorizedConnectedSource, insightSourcesAuthorized };
|
|
61
|
+
export { authorizedConnectedSource, insightSourcesAuthorized, insightSourcesChanged };
|
|
@@ -33,6 +33,10 @@ export declare class DiscussionContextProvider implements ContextProvider {
|
|
|
33
33
|
readonly id = "discussion";
|
|
34
34
|
collect(input: ContextInput): Promise<ResolvedContext>;
|
|
35
35
|
}
|
|
36
|
+
export declare class MailFollowUpContextProvider implements ContextProvider {
|
|
37
|
+
readonly id = "follow_up";
|
|
38
|
+
collect(input: ContextInput): Promise<ResolvedContext>;
|
|
39
|
+
}
|
|
36
40
|
export declare class ContextProviderRegistry {
|
|
37
41
|
private readonly providers;
|
|
38
42
|
constructor(providers?: ContextProvider[]);
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { getSqliteDatabase } from "../../storage/sqlite/transaction.js";
|
|
2
2
|
import { getAssertionSlot, listUserAssertions } from "../../user-model/repository.js";
|
|
3
3
|
import "../../user-model/index.js";
|
|
4
|
-
import { getDiscussionCapture, getLatestDiscussionOrganization } from "../../discussions/repository.js";
|
|
5
4
|
import { authorizedConnectedSource } from "./authorization.js";
|
|
5
|
+
import { authorizedMailThread, requireMailFollowUp } from "../follow-ups.js";
|
|
6
|
+
import { getDiscussionCapture, getLatestDiscussionOrganization } from "../../discussions/repository.js";
|
|
6
7
|
import { wrapExternalContent } from "../../gateway/security/external-content.js";
|
|
7
8
|
//#region src/proactive/execution/context.ts
|
|
8
9
|
const MAX_EVENT_COUNT = 50;
|
|
@@ -27,7 +28,12 @@ function emptyContext() {
|
|
|
27
28
|
};
|
|
28
29
|
}
|
|
29
30
|
function authorizedConnectedSourceItem(event, scenarioKey) {
|
|
30
|
-
|
|
31
|
+
const item = authorizedConnectedSource(event.subject_id, event.workspace_id, scenarioKey, event.agent_id);
|
|
32
|
+
if (item && event.type === "connected_source.calendar_window.v1") {
|
|
33
|
+
const payload = JSON.parse(event.payload_json);
|
|
34
|
+
if (payload.meetingStartsAt !== item.occurredAt || payload.contentHash && payload.contentHash !== item.contentHash) return null;
|
|
35
|
+
}
|
|
36
|
+
return item;
|
|
31
37
|
}
|
|
32
38
|
var EventBatchContextProvider = class {
|
|
33
39
|
id = "event_batch";
|
|
@@ -53,11 +59,13 @@ var ConnectedSourceContextProvider = class {
|
|
|
53
59
|
async collect(input) {
|
|
54
60
|
const items = [];
|
|
55
61
|
const snapshotItems = [];
|
|
62
|
+
const seen = /* @__PURE__ */ new Set();
|
|
56
63
|
const evidenceIds = [];
|
|
57
64
|
for (const event of eventRows(input.eventIds)) {
|
|
58
65
|
if (!event.type.startsWith("connected_source.") || event.type.includes("_deleted.")) continue;
|
|
59
66
|
const item = authorizedConnectedSourceItem(event, input.scenarioKey);
|
|
60
|
-
if (!item) continue;
|
|
67
|
+
if (!item || seen.has(item.id)) continue;
|
|
68
|
+
seen.add(item.id);
|
|
61
69
|
const evidenceId = `source-item:${item.id}`;
|
|
62
70
|
const common = {
|
|
63
71
|
evidenceId,
|
|
@@ -325,6 +333,43 @@ var DiscussionContextProvider = class {
|
|
|
325
333
|
};
|
|
326
334
|
}
|
|
327
335
|
};
|
|
336
|
+
var MailFollowUpContextProvider = class {
|
|
337
|
+
id = "follow_up";
|
|
338
|
+
async collect(input) {
|
|
339
|
+
const event = eventRows(input.eventIds).findLast((row) => row.subject_kind === "mail_follow_up");
|
|
340
|
+
if (!event) return emptyContext();
|
|
341
|
+
const follow = requireMailFollowUp(event.workspace_id, event.subject_id);
|
|
342
|
+
const thread = authorizedMailThread(follow);
|
|
343
|
+
if (!thread || follow.status !== "watching") return emptyContext();
|
|
344
|
+
const common = {
|
|
345
|
+
followUpId: follow.id,
|
|
346
|
+
revision: follow.revision,
|
|
347
|
+
fingerprint: thread.fingerprint,
|
|
348
|
+
dueAt: follow.due_at,
|
|
349
|
+
deadlinePassed: Date.parse(follow.due_at) <= Date.now()
|
|
350
|
+
};
|
|
351
|
+
return {
|
|
352
|
+
content: {
|
|
353
|
+
...common,
|
|
354
|
+
instructions: follow.instructions,
|
|
355
|
+
items: thread.items.map((item) => ({
|
|
356
|
+
evidenceId: `source-item:${item.id}`,
|
|
357
|
+
occurredAt: item.occurredAt,
|
|
358
|
+
content: wrapExternalContent(item.normalizedText?.slice(0, 4e3) ?? "", { source: "email" })
|
|
359
|
+
}))
|
|
360
|
+
},
|
|
361
|
+
snapshotContent: {
|
|
362
|
+
...common,
|
|
363
|
+
items: thread.items.map((item) => ({
|
|
364
|
+
sourceItemId: item.id,
|
|
365
|
+
contentHash: item.contentHash,
|
|
366
|
+
occurredAt: item.occurredAt
|
|
367
|
+
}))
|
|
368
|
+
},
|
|
369
|
+
evidenceIds: thread.items.map((item) => `source-item:${item.id}`)
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
};
|
|
328
373
|
var ContextProviderRegistry = class {
|
|
329
374
|
constructor(providers = [
|
|
330
375
|
new EventBatchContextProvider(),
|
|
@@ -334,7 +379,8 @@ var ContextProviderRegistry = class {
|
|
|
334
379
|
new MeetingWorkspaceContextProvider(),
|
|
335
380
|
new ProjectStateContextProvider(),
|
|
336
381
|
new AutomationStateContextProvider(),
|
|
337
|
-
new DiscussionContextProvider()
|
|
382
|
+
new DiscussionContextProvider(),
|
|
383
|
+
new MailFollowUpContextProvider()
|
|
338
384
|
]) {
|
|
339
385
|
this.providers = providers;
|
|
340
386
|
}
|
|
@@ -357,4 +403,4 @@ var ContextProviderRegistry = class {
|
|
|
357
403
|
}
|
|
358
404
|
};
|
|
359
405
|
//#endregion
|
|
360
|
-
export { AutomationStateContextProvider, ConnectedSourceContextProvider, ContextProviderRegistry, DiscussionContextProvider, EventBatchContextProvider, InternalObjectContextProvider, MeetingWorkspaceContextProvider, ProjectStateContextProvider, UserModelContextProvider };
|
|
406
|
+
export { AutomationStateContextProvider, ConnectedSourceContextProvider, ContextProviderRegistry, DiscussionContextProvider, EventBatchContextProvider, InternalObjectContextProvider, MailFollowUpContextProvider, MeetingWorkspaceContextProvider, ProjectStateContextProvider, UserModelContextProvider };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ProactiveArtifactSchema } from "../../../packages/gateway-contract/src/proactive.js";
|
|
1
2
|
import { stripCodeFences } from "../../providers/model-response.js";
|
|
2
3
|
//#region src/proactive/execution/insight.ts
|
|
3
4
|
const URGENCY = new Set([
|
|
@@ -65,6 +66,7 @@ function parseInsightCandidate(raw, allowedEvidenceIds) {
|
|
|
65
66
|
const proposedAction = parseProposedAction(row.proposedAction);
|
|
66
67
|
if (proposedAction && (!decision || decision.options.length !== 2 || decision.options[0]?.id !== "approve" || decision.options[1]?.id !== "reject")) throw new Error("Insight proposedAction requires approve and reject decision options");
|
|
67
68
|
return {
|
|
69
|
+
...row.artifact != null ? { artifact: ProactiveArtifactSchema.parse(row.artifact) } : {},
|
|
68
70
|
title: boundedText(row.title, "title", 160),
|
|
69
71
|
summary: boundedText(row.summary, "summary", 1200),
|
|
70
72
|
whyNow: boundedText(row.whyNow, "whyNow", 800),
|
|
@@ -91,7 +93,7 @@ function isValuableInsight(candidate, policy = {
|
|
|
91
93
|
minConfidence: .65,
|
|
92
94
|
minScore: .6
|
|
93
95
|
}) {
|
|
94
|
-
return candidate.confidence >= policy.minConfidence && candidate.urgency !== "low" && scoreInsight(candidate) >= policy.minScore;
|
|
96
|
+
return candidate.confidence >= policy.minConfidence && (candidate.urgency !== "low" || Boolean(candidate.artifact)) && scoreInsight(candidate) >= policy.minScore;
|
|
95
97
|
}
|
|
96
98
|
function parseAnalysisResult(raw, allowedEvidenceIds) {
|
|
97
99
|
let value;
|
|
@@ -107,11 +107,19 @@ function finishRun(input, now = /* @__PURE__ */ new Date()) {
|
|
|
107
107
|
JOIN proactive_events e ON e.event_id = be.event_id
|
|
108
108
|
WHERE be.batch_id = ?
|
|
109
109
|
ORDER BY e.subject_kind, e.subject_id`).all(input.run.batchId).map((row) => `${str(row, "subject_kind")}:${str(row, "subject_id")}`);
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
110
|
+
const snapshot = db.prepare(`SELECT c.content_json FROM proactive_runs r JOIN proactive_context_snapshots c
|
|
111
|
+
ON c.snapshot_id = r.context_snapshot_id WHERE r.run_id = ?`).get(input.run.id);
|
|
112
|
+
const sourceVersions = snapshot ? JSON.parse(snapshot.content_json) : {};
|
|
113
|
+
const fingerprint = input.candidate ? createHash("sha256").update([
|
|
114
|
+
...subjectScope,
|
|
115
|
+
JSON.stringify(input.candidate.artifact ?? null),
|
|
116
|
+
JSON.stringify(sourceVersions.connected_source ?? sourceVersions.project_state ?? sourceVersions.follow_up ?? null),
|
|
117
|
+
...[
|
|
118
|
+
input.candidate.title,
|
|
119
|
+
input.candidate.summary,
|
|
120
|
+
input.candidate.recommendation
|
|
121
|
+
].map((value) => value.trim().toLowerCase().replace(/\s+/g, " "))
|
|
122
|
+
].join("\n")).digest("hex") : void 0;
|
|
115
123
|
const duplicate = fingerprint ? db.prepare(`SELECT 1 FROM proactive_insights
|
|
116
124
|
WHERE subscription_id = ? AND scenario_key = ? AND content_fingerprint = ? AND created_at >= ? LIMIT 1`).get(input.run.subscriptionId, input.run.scenarioKey, fingerprint, (/* @__PURE__ */ new Date(now.getTime() - (input.cooldownSeconds ?? 10080 * 60) * 1e3)).toISOString()) : void 0;
|
|
117
125
|
const valuable = Boolean(input.candidate) && !duplicate;
|
|
@@ -141,6 +149,7 @@ function finishRun(input, now = /* @__PURE__ */ new Date()) {
|
|
|
141
149
|
why_now, impact, recommendation, work_done, decision_json, proposed_action_json, urgency, confidence, value_score,
|
|
142
150
|
evidence_ids_json, content_fingerprint, created_at)
|
|
143
151
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(insight.id, insight.runId, insight.subscriptionId, insight.scenarioKey, insight.title, insight.summary, insight.whyNow, insight.impact, insight.recommendation, insight.workDone, insight.decision ? JSON.stringify(insight.decision) : null, insight.proposedAction ? JSON.stringify(insight.proposedAction) : null, insight.urgency, insight.confidence, insight.valueScore, JSON.stringify(insight.evidenceIds), fingerprint, insight.createdAt);
|
|
152
|
+
if (insight.artifact) db.prepare("UPDATE proactive_insights SET artifact_json = ? WHERE insight_id = ?").run(JSON.stringify(insight.artifact), insight.id);
|
|
144
153
|
return insight;
|
|
145
154
|
});
|
|
146
155
|
}
|
|
@@ -165,6 +174,7 @@ function listInsights(limit = 50) {
|
|
|
165
174
|
impact: str(row, "impact"),
|
|
166
175
|
recommendation: str(row, "recommendation"),
|
|
167
176
|
workDone: str(row, "work_done"),
|
|
177
|
+
...row.artifact_json ? { artifact: JSON.parse(str(row, "artifact_json")) } : {},
|
|
168
178
|
...row.decision_json ? { decision: JSON.parse(str(row, "decision_json")) } : {},
|
|
169
179
|
...row.proposed_action_json ? { proposedAction: JSON.parse(str(row, "proposed_action_json")) } : {},
|
|
170
180
|
urgency: str(row, "urgency"),
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ProactiveArtifact } from '@xopcai/gateway-contract';
|
|
1
2
|
export interface ContextSnapshot {
|
|
2
3
|
id: string;
|
|
3
4
|
batchId: string;
|
|
@@ -6,6 +7,7 @@ export interface ContextSnapshot {
|
|
|
6
7
|
createdAt: string;
|
|
7
8
|
}
|
|
8
9
|
export interface InsightCandidate {
|
|
10
|
+
artifact?: ProactiveArtifact;
|
|
9
11
|
title: string;
|
|
10
12
|
summary: string;
|
|
11
13
|
whyNow: string;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createLogger } from "../../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../../utils/logger.js";
|
|
3
3
|
import { getSqliteDatabase } from "../../storage/sqlite/transaction.js";
|
|
4
|
+
import { authorizedConnectedSource } from "./authorization.js";
|
|
4
5
|
import { effectiveProactivePolicy } from "../policy/service.js";
|
|
5
6
|
import { getPromptRevision, getScenario } from "../scenarios/repository.js";
|
|
6
7
|
import { composeScenarioPrompt } from "../scenarios/prompt-composer.js";
|
|
@@ -9,6 +10,7 @@ import { ContextProviderRegistry } from "./context.js";
|
|
|
9
10
|
import { attachSnapshot, claimNextRun, eventIdsForBatch, failRun, finishRun, saveSnapshot } from "./repository.js";
|
|
10
11
|
import { isValuableInsight, parseAnalysisResult, scoreInsight } from "./insight.js";
|
|
11
12
|
import { randomUUID } from "node:crypto";
|
|
13
|
+
import { isDeepStrictEqual } from "node:util";
|
|
12
14
|
//#region src/proactive/execution/worker.ts
|
|
13
15
|
init_logger();
|
|
14
16
|
const log = createLogger("ProactiveWorker");
|
|
@@ -86,11 +88,14 @@ var ProactiveWorker = class {
|
|
|
86
88
|
subscriptionId: run.subscriptionId
|
|
87
89
|
});
|
|
88
90
|
const revoked = context.evidenceIds.some((id) => !latestContext.evidenceIds.includes(id));
|
|
89
|
-
const
|
|
91
|
+
const changed = !isDeepStrictEqual(context.snapshotContent ?? context.content, latestContext.snapshotContent ?? latestContext.content);
|
|
92
|
+
const unavailable = context.evidenceIds.some((id) => id.startsWith("source-item:") && !authorizedConnectedSource(id.slice(12), effectiveProactivePolicy(run.subscriptionId).workspaceId, run.scenarioKey));
|
|
93
|
+
const result = revoked || changed ? {
|
|
90
94
|
result: "no_insight",
|
|
91
|
-
reason: "source_unavailable"
|
|
95
|
+
reason: unavailable ? "source_unavailable" : "source_changed"
|
|
92
96
|
} : parseAnalysisResult(output.text, new Set(latestContext.evidenceIds));
|
|
93
97
|
const candidate = result.result === "insight" ? result.candidate : void 0;
|
|
98
|
+
if (run.scenarioKey === "communication_follow_up" && (candidate?.decision || candidate?.proposedAction)) throw new Error("Communication preparation must return a draft or update; actions require the conversation confirmation flow");
|
|
94
99
|
const valueScore = candidate ? scoreInsight(candidate) : 0;
|
|
95
100
|
const enabled = effectiveProactivePolicy(run.subscriptionId).enabled;
|
|
96
101
|
const valuable = enabled && candidate && isValuableInsight(candidate, scenario.valuePolicy);
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
export declare function startDelegation(workspace: string, value: unknown): {
|
|
2
|
+
effectiveLevel: "off" | "active" | "quiet" | "balanced";
|
|
3
|
+
schedule: Record<string, import("node:sqlite").SQLOutputValue>;
|
|
4
|
+
revision: number;
|
|
5
|
+
level: "off" | "active" | "quiet" | "balanced";
|
|
6
|
+
delivery: "digest" | "inbox" | "important";
|
|
7
|
+
completedAt: string;
|
|
8
|
+
scanIntervalMinutes: number;
|
|
9
|
+
userInstructions: string;
|
|
10
|
+
id: string;
|
|
11
|
+
scenarioKey: string;
|
|
12
|
+
workspaceId: string;
|
|
13
|
+
scopeKind: "workspace" | "project";
|
|
14
|
+
scopeId: string;
|
|
15
|
+
enabled: boolean;
|
|
16
|
+
activePromptRevisionId?: string;
|
|
17
|
+
createdAt: string;
|
|
18
|
+
updatedAt: string;
|
|
19
|
+
};
|
|
20
|
+
/** Queue work in the existing worker; HTTP and conversation requests do not own model runs. */
|
|
21
|
+
export declare function checkDelegation(workspace: string, id: string): {
|
|
22
|
+
status: "queued";
|
|
23
|
+
};
|
|
24
|
+
export declare function delegationOverview(workspace: string): {
|
|
25
|
+
followUps: {
|
|
26
|
+
id: string;
|
|
27
|
+
subscriptionId: string;
|
|
28
|
+
instructions: string;
|
|
29
|
+
dueAt: string;
|
|
30
|
+
status: "completed" | "paused" | "watching";
|
|
31
|
+
revision: number;
|
|
32
|
+
lastCheckedAt: string;
|
|
33
|
+
sessionKey: string;
|
|
34
|
+
sourceAvailable: boolean;
|
|
35
|
+
enabled: boolean;
|
|
36
|
+
subject: string;
|
|
37
|
+
latestMessageAt: string;
|
|
38
|
+
latestDirection: string;
|
|
39
|
+
lastSyncedAt: string;
|
|
40
|
+
syncFailed: boolean;
|
|
41
|
+
}[];
|
|
42
|
+
needsDecision: import("@xopcai/gateway-contract/src/proactive.js").ProactiveCard[];
|
|
43
|
+
prepared: import("@xopcai/gateway-contract/src/proactive.js").ProactiveCard[];
|
|
44
|
+
updates: import("@xopcai/gateway-contract/src/proactive.js").ProactiveCard[];
|
|
45
|
+
delegations: {
|
|
46
|
+
effectiveEnabled: boolean;
|
|
47
|
+
project: Record<string, import("node:sqlite").SQLOutputValue>;
|
|
48
|
+
latestRun: Record<string, import("node:sqlite").SQLOutputValue>;
|
|
49
|
+
pending: boolean;
|
|
50
|
+
effectiveLevel: "off" | "active" | "quiet" | "balanced";
|
|
51
|
+
schedule: Record<string, import("node:sqlite").SQLOutputValue>;
|
|
52
|
+
revision: number;
|
|
53
|
+
level: "off" | "active" | "quiet" | "balanced";
|
|
54
|
+
delivery: "digest" | "inbox" | "important";
|
|
55
|
+
completedAt: string;
|
|
56
|
+
scanIntervalMinutes: number;
|
|
57
|
+
userInstructions: string;
|
|
58
|
+
id: string;
|
|
59
|
+
scenarioKey: string;
|
|
60
|
+
workspaceId: string;
|
|
61
|
+
scopeKind: "workspace" | "project";
|
|
62
|
+
scopeId: string;
|
|
63
|
+
enabled: boolean;
|
|
64
|
+
activePromptRevisionId?: string;
|
|
65
|
+
createdAt: string;
|
|
66
|
+
updatedAt: string;
|
|
67
|
+
}[];
|
|
68
|
+
};
|
|
69
|
+
export declare function completeDeliveredProjects(now?: Date): void;
|