@xopcai/xopc 0.0.160 → 0.0.162
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-hpcNv9MZ.js +1 -0
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-B_27aaZQ.js → agent-avatar-dicebear-Zf9UQEmQ.js} +1 -1
- package/dist/gateway/static/root/assets/agents-DfVkZlHc.js +2 -0
- package/dist/gateway/static/root/assets/{api-BbzB57CJ.js → api-Dnatri09.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-DfmyWcyh.js → app-management-settings-panel-BBTR9wJP.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-B2v0c-K-.js → appearance-settings-C2zpLCHD.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-BMtAa4Ra.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-DL5Lnx0C.js → archive-plugin-9eR_ODY1.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-InuP-ZjQ.js → attachment-load-DPuWYUeX.js} +1 -1
- package/dist/gateway/static/root/assets/{automation-suggestion-card-CahGuh7B.js → automation-suggestion-card-Dw49OJRl.js} +1 -1
- package/dist/gateway/static/root/assets/automations-page-BiSAMYTr.js +6 -0
- package/dist/gateway/static/root/assets/{binary-plugins-CdOTGYVu.js → binary-plugins-BdkJpDFm.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-D6ShK1S-.js → block-editor-CAi7SXYU.js} +47 -47
- package/dist/gateway/static/root/assets/browser-settings-page-DHmaEJS2.js +8 -0
- package/dist/gateway/static/root/assets/browser-workflow-inputs-Dx6wkGz1.js +1 -0
- package/dist/gateway/static/root/assets/browser-workflows-page-Skertc-A.js +3 -0
- package/dist/gateway/static/root/assets/capabilities-settings-panel-B5wSgf4f.js +2 -0
- package/dist/gateway/static/root/assets/{capability-presets-api-BzoLm52Z.js → capability-presets-api-CNFl7dM3.js} +1 -1
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-DyvFZwBj.js +2 -0
- package/dist/gateway/static/root/assets/{channel-recipient-api-DbgydMjl.js → channel-recipient-api-DYQyGDw4.js} +1 -1
- package/dist/gateway/static/root/assets/channels-settings-BBKEqDZn.js +1 -0
- package/dist/gateway/static/root/assets/channels-status-swr-Drk110ve.js +1 -0
- package/dist/gateway/static/root/assets/check-DUBLcKHA.js +1 -0
- package/dist/gateway/static/root/assets/circle-alert-BEjgurr2.js +1 -0
- package/dist/gateway/static/root/assets/cn-JdwAhgNB.js +1 -0
- package/dist/gateway/static/root/assets/{connector-logo-C3bJC9nt.js → connector-logo-Bng6kxYF.js} +1 -1
- package/dist/gateway/static/root/assets/connectors-page-HpgaUDQ1.js +2 -0
- package/dist/gateway/static/root/assets/createLucideIcon-DPHK1VkS.js +1 -0
- package/dist/gateway/static/root/assets/desktop-pet-Bpf6oegd.js +1 -0
- package/dist/gateway/static/root/assets/{desktop-pet-settings-BrHVvbBw.js → desktop-pet-settings-BVUyefSd.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-sprite-CFd1jGLJ.js → desktop-pet-sprite-DTqXSpqf.js} +1 -1
- package/dist/gateway/static/root/assets/{directory-picker-path-field-BPI969w-.js → directory-picker-path-field-DjSZAPz_.js} +1 -1
- package/dist/gateway/static/root/assets/{dreaming-settings-iw6QXD45.js → dreaming-settings-CAZk2AM4.js} +3 -3
- package/dist/gateway/static/root/assets/{extension-debug-page-rCHyhEr6.js → extension-debug-page-C2F6vTTd.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-C4gQsAPt.js → extension-page-AnIt4bn4.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-DB_3eik7.js → extension-settings-page-CLSc6682.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-api-Cdt38iF2.js → gateway-config-api-DLFyZv33.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-settings-DM4BgyGw.js → gateway-settings-DnQAA-qq.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-startup-retry-ChRFNjj_.js → gateway-startup-retry-DbzLyJ3R.js} +1 -1
- package/dist/gateway/static/root/assets/goal-create-dialog-DrnKFC6M.js +1 -0
- package/dist/gateway/static/root/assets/goal-detail-page-Cw1hpJkZ.js +4 -0
- package/dist/gateway/static/root/assets/{goals-config-api-RvljeEm6.js → goals-config-api-REmr3QCr.js} +1 -1
- package/dist/gateway/static/root/assets/goals-page-BDGkTVma.js +2 -0
- package/dist/gateway/static/root/assets/{goals-settings-DMGV4S4L.js → goals-settings-Dz0F3uRO.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-settings-B8r5EXc5.js → heartbeat-settings-CQFY5gYs.js} +1 -1
- package/dist/gateway/static/root/assets/index-C8JkTS6d.js +199 -0
- package/dist/gateway/static/root/assets/index-hmrG55qg.css +1 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-1-LYibQ4.js → keyboard-shortcuts-settings-BnOQXU5k.js} +1 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-Bdef1b7F.js +2 -0
- package/dist/gateway/static/root/assets/{local-apps-page-CC4vtUUI.js → local-apps-page-KsOtWOyM.js} +1 -1
- package/dist/gateway/static/root/assets/{locale-store-CPbGB_6l.js → locale-store-0lpYdNDr.js} +1 -1
- package/dist/gateway/static/root/assets/{logs-page-Bn_taxBV.js → logs-page-CwLPgrWh.js} +3 -3
- package/dist/gateway/static/root/assets/{markdown-split-CprEIf8A.js → markdown-split-D5GRg10r.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-BXt_Sj2O.js → media-plugins-C1ryULGs.js} +1 -1
- package/dist/gateway/static/root/assets/messages-BwQ3WssU.js +5 -0
- package/dist/gateway/static/root/assets/{notes-page-Wf5-eyyM.js → notes-page-CIeZ1_DT.js} +1 -1
- package/dist/gateway/static/root/assets/notes-workbench-Cf06q19x.js +4 -0
- package/dist/gateway/static/root/assets/{page-tabs-dtpK_4Fs.js → page-tabs-Caj1-E_X.js} +1 -1
- package/dist/gateway/static/root/assets/{preview-open-alternatives-DijtEVxG.js → preview-open-alternatives-DKwEce-9.js} +1 -1
- package/dist/gateway/static/root/assets/product-delivery-BTRT9kCS.js +1 -0
- package/dist/gateway/static/root/assets/product-open-page-B90ZskkN.js +1 -0
- package/dist/gateway/static/root/assets/project-detail-page-SHTurM4t.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-BcC2qUAw.js +1 -0
- package/dist/gateway/static/root/assets/remote-access-hub-6vGefBHv.js +1 -0
- package/dist/gateway/static/root/assets/save-bar-controls-BDYt53uQ.js +1 -0
- package/dist/gateway/static/root/assets/{schedule-field-AhJ50NoT.js → schedule-field-Bcdni4Pj.js} +1 -1
- package/dist/gateway/static/root/assets/{schema-form-AuJg2CXU.js → schema-form-D7oCARF7.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-C5014a53.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-CDY3ZI1K.js +1 -0
- package/dist/gateway/static/root/assets/{settings-collapsible-section-D5ganr_X.js → settings-collapsible-section-6eNF8Jey.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-form-section-Db3cKRsg.js → settings-form-section-CARTHCxH.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-loading-skeleton-D05YKT2x.js → settings-loading-skeleton-DEwYqESe.js} +1 -1
- package/dist/gateway/static/root/assets/settings-page-B6vVdHeQ.js +1 -0
- package/dist/gateway/static/root/assets/{settings-page-layout-Cv_Cu4I5.js → settings-page-layout-D3srt5Bi.js} +1 -1
- package/dist/gateway/static/root/assets/setup-status-panel-z-rF0Hdg.js +1 -0
- package/dist/gateway/static/root/assets/{share-preview-page-CYkZVuse.js → share-preview-page-Ck9SxiXw.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-CHZFXE_d.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-B7p2QNXt.js +1 -0
- package/dist/gateway/static/root/assets/skills-page-ncw3tX9P.js +2 -0
- package/dist/gateway/static/root/assets/{system-settings-panel-C1Ng5bXh.js → system-settings-panel-DLBUQSk2.js} +1 -1
- package/dist/gateway/static/root/assets/{theme-store-LMHIDR9n.js → theme-store-C1oaqeD2.js} +1 -1
- package/dist/gateway/static/root/assets/{typed-models-lib-Ch2Bdm_5.js → typed-models-lib-Divbg_C4.js} +1 -1
- package/dist/gateway/static/root/assets/{use-channel-catalog-CZnaMOeL.js → use-channel-catalog-CP9a_rAf.js} +1 -1
- package/dist/gateway/static/root/assets/user-context-page-iYfeSLKI.js +1 -0
- package/dist/gateway/static/root/assets/voice-api-key-field-CrwkicvT.js +1 -0
- package/dist/gateway/static/root/assets/work-discovery-page-BQWxyPg8.js +1 -0
- package/dist/gateway/static/root/assets/work-item-detail-page-50ZzGay5.js +1 -0
- package/dist/gateway/static/root/assets/work-page-DPqEahx7.js +1 -0
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-BFk8TvTw.js → workflow-run-setup-panel-DbDPYQwB.js} +2 -2
- package/dist/gateway/static/root/assets/workflows-page-C3eIC5HZ.js +11 -0
- package/dist/gateway/static/root/index.html +12 -10
- package/dist/package.js +1 -1
- package/dist/src/agent/agent-manager.d.ts +1 -0
- package/dist/src/agent/agent-manager.js +1 -0
- package/dist/src/agent/client-error-format.js +3 -3
- package/dist/src/agent/outcomes/task-evaluation.d.ts +20 -0
- package/dist/src/agent/outcomes/task-evaluation.js +48 -0
- package/dist/src/agent/outcomes/task-verifier.d.ts +29 -0
- package/dist/src/agent/outcomes/task-verifier.js +71 -0
- package/dist/src/agent/prompt/memory/index.js +1 -1
- package/dist/src/agent/prompt/service-prompt-builder.js +32 -1
- package/dist/src/agent/service.js +1 -0
- package/dist/src/agent/service.types.d.ts +1 -0
- package/dist/src/agent/tools/browser/tool/browser-use-tool.d.ts +1 -7
- package/dist/src/agent/tools/browser/tool/browser-use-tool.js +2 -73
- package/dist/src/agent/tools/browser/tool/schemas.d.ts +1 -13
- package/dist/src/agent/tools/browser/tool/schemas.js +1 -9
- package/dist/src/agent/tools/browser-recipe-tool.d.ts +12 -0
- package/dist/src/agent/tools/browser-recipe-tool.js +113 -0
- package/dist/src/agent/tools/factory.d.ts +2 -0
- package/dist/src/agent/tools/factory.js +2 -0
- package/dist/src/agent/tools/index.d.ts +1 -0
- package/dist/src/agent/tools/index.js +2 -1
- package/dist/src/automations/domain/types.d.ts +13 -0
- package/dist/src/automations/domain/validation.d.ts +44 -24
- package/dist/src/automations/domain/validation.js +27 -18
- package/dist/src/automations/draft/automation-draft-validator.d.ts +6 -1
- package/dist/src/automations/draft/automation-draft-validator.js +1 -0
- package/dist/src/automations/service/action-executor.d.ts +1 -0
- package/dist/src/automations/service/action-executor.js +22 -0
- package/dist/src/browser/index.d.ts +0 -1
- package/dist/src/browser/index.js +1 -2
- package/dist/src/browser/pipeline/runner.d.ts +9 -2
- package/dist/src/browser/pipeline/runner.js +151 -105
- package/dist/src/browser/pipeline/schema.d.ts +21 -15
- package/dist/src/browser/pipeline/schema.js +93 -99
- package/dist/src/browser/recipes/index.d.ts +3 -0
- package/dist/src/browser/recipes/index.js +3 -0
- package/dist/src/browser/recipes/repository.d.ts +13 -0
- package/dist/src/browser/recipes/repository.js +81 -0
- package/dist/src/browser/recipes/runtime-service.d.ts +6 -0
- package/dist/src/browser/recipes/runtime-service.js +30 -0
- package/dist/src/browser/recipes/service.d.ts +36 -0
- package/dist/src/browser/recipes/service.js +186 -0
- package/dist/src/browser/recipes/types.d.ts +36 -0
- package/dist/src/browser/recipes/types.js +1 -0
- package/dist/src/cli/commands/browser-cli-helpers.js +6 -12
- package/dist/src/cli/commands/browser.js +4 -3
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/config/schema.d.ts +3 -3
- package/dist/src/config/schema.js +21 -21
- package/dist/src/gateway/hono/lib/config-payload.d.ts +1 -1
- package/dist/src/gateway/hono/routes/browser-workflows.d.ts +3 -0
- package/dist/src/gateway/hono/routes/browser-workflows.js +78 -0
- package/dist/src/gateway/hono/routes/home.js +1 -0
- package/dist/src/gateway/hono/routes/index.js +4 -0
- package/dist/src/gateway/hono/routes/interaction-state.d.ts +3 -0
- package/dist/src/gateway/hono/routes/interaction-state.js +45 -0
- package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
- package/dist/src/gateway/hono/routes/memory.js +33 -4
- package/dist/src/gateway/hono/routes/task-outcomes.d.ts +3 -0
- package/dist/src/gateway/hono/routes/task-outcomes.js +109 -0
- package/dist/src/gateway/hono/routes/you.d.ts +10 -2
- package/dist/src/gateway/hono/routes/you.js +184 -28
- package/dist/src/gateway/hono/sse.d.ts +2 -0
- package/dist/src/gateway/hono/sse.js +10 -3
- package/dist/src/gateway/run-loop.js +17 -7
- package/dist/src/gateway/server.d.ts +1 -0
- package/dist/src/gateway/server.js +9 -0
- package/dist/src/gateway/service/run-gateway-agent.js +84 -0
- package/dist/src/gateway/service.d.ts +3 -0
- package/dist/src/gateway/service.js +14 -0
- package/dist/src/local-apps/preview-runtime-bridge.d.ts +1 -1
- package/dist/src/local-apps/preview-runtime-bridge.js +14 -11
- package/dist/src/proactive/insight-repository.d.ts +2 -0
- package/dist/src/proactive/insight-repository.js +5 -2
- package/dist/src/proactive/run-processor.js +22 -1
- package/dist/src/proactive/types.d.ts +2 -0
- package/dist/src/proactive/value-score.d.ts +13 -0
- package/dist/src/proactive/value-score.js +30 -0
- package/dist/src/share/share-types.js +5 -5
- package/dist/src/share/site-share-types.d.ts +1 -1
- package/dist/src/share/site-share-types.js +5 -5
- package/dist/src/storage/sqlite/index.d.ts +3 -0
- package/dist/src/storage/sqlite/index.js +4 -1
- package/dist/src/storage/sqlite/interaction-state-repository.d.ts +17 -0
- package/dist/src/storage/sqlite/interaction-state-repository.js +60 -0
- package/dist/src/storage/sqlite/memory-records-repository.js +1 -1
- package/dist/src/storage/sqlite/migrations/053_browser_recipes.sql +45 -0
- package/dist/src/storage/sqlite/migrations/054_task_outcomes.sql +24 -0
- package/dist/src/storage/sqlite/migrations/055_relationship_settings.sql +14 -0
- package/dist/src/storage/sqlite/migrations/056_task_verification.sql +6 -0
- package/dist/src/storage/sqlite/migrations/057_interaction_states.sql +11 -0
- package/dist/src/storage/sqlite/migrations/058_proactive_value.sql +3 -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/relationship-settings-repository.d.ts +17 -0
- package/dist/src/storage/sqlite/relationship-settings-repository.js +64 -0
- package/dist/src/storage/sqlite/schema.js +1 -1
- package/dist/src/storage/sqlite/schema.sql +46 -0
- package/dist/src/storage/sqlite/task-outcome-repository.d.ts +90 -0
- package/dist/src/storage/sqlite/task-outcome-repository.js +138 -0
- package/dist/src/user-context/interaction-state.d.ts +13 -0
- package/dist/src/user-context/interaction-state.js +69 -0
- package/dist/src/user-context/memory-use-audit.d.ts +10 -0
- package/dist/src/user-context/memory-use-audit.js +25 -0
- package/dist/src/user-context/personal-playbook.d.ts +11 -0
- package/dist/src/user-context/personal-playbook.js +41 -0
- package/dist/src/user-context/projection.d.ts +4 -0
- package/dist/src/user-context/projection.js +5 -1
- package/dist/src/user-context/relationship-continuity.d.ts +14 -0
- package/dist/src/user-context/relationship-continuity.js +51 -0
- package/package.json +1 -1
- package/dist/gateway/static/root/assets/action-boundary-settings-panel-CY3sizqC.js +0 -1
- package/dist/gateway/static/root/assets/activity-store-3Cso_2qm.js +0 -1
- package/dist/gateway/static/root/assets/agents-B1l3iii6.js +0 -2
- package/dist/gateway/static/root/assets/apps-page-DaNFLsp0.js +0 -1
- package/dist/gateway/static/root/assets/automations-page-Cd0gMx6p.js +0 -6
- package/dist/gateway/static/root/assets/browser-settings-page-BmUYDL2Z.js +0 -8
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-CE7mrWtS.js +0 -2
- package/dist/gateway/static/root/assets/channels-settings-D1_gcAHK.js +0 -1
- package/dist/gateway/static/root/assets/channels-status-swr-Cqfqv59m.js +0 -1
- package/dist/gateway/static/root/assets/check-BODqo66o.js +0 -1
- package/dist/gateway/static/root/assets/circle-alert-RzVebuX2.js +0 -1
- package/dist/gateway/static/root/assets/cn-BQ_8x0bT.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-CaLBi6Na.js +0 -2
- package/dist/gateway/static/root/assets/desktop-pet-wacrnJJ1.js +0 -1
- package/dist/gateway/static/root/assets/goal-create-dialog-BQamcEmF.js +0 -1
- package/dist/gateway/static/root/assets/goal-detail-page-DZUQ0Lf1.js +0 -4
- package/dist/gateway/static/root/assets/goals-page-BtxVD27C.js +0 -2
- package/dist/gateway/static/root/assets/index-CHKe7nwC.js +0 -197
- package/dist/gateway/static/root/assets/index-CXhfUIjh.css +0 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-CTTfyFe3.js +0 -2
- package/dist/gateway/static/root/assets/messages-DDsiqdJS.js +0 -5
- package/dist/gateway/static/root/assets/models-hub-panel-DJReXRP9.js +0 -2
- package/dist/gateway/static/root/assets/notes-workbench-BbdjzYzs.js +0 -4
- package/dist/gateway/static/root/assets/project-detail-page-BwG8SOzI.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-nUlyUtxh.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-rf7bjije.js +0 -1
- package/dist/gateway/static/root/assets/save-bar-controls-qhDisdqY.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-CSoHUe38.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-Db976IEa.js +0 -1
- package/dist/gateway/static/root/assets/settings-page-DYfXmfTx.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-wBWOFpvw.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-BAMma1-P.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-TWxFFWxM.js +0 -1
- package/dist/gateway/static/root/assets/skills-page-Ca2RA29R.js +0 -2
- package/dist/gateway/static/root/assets/user-context-page-CTumZa0y.js +0 -1
- package/dist/gateway/static/root/assets/voice-api-key-field-DdlMxeqO.js +0 -1
- package/dist/gateway/static/root/assets/work-discovery-page-CcfZhdBi.js +0 -1
- package/dist/gateway/static/root/assets/work-item-detail-page--wxLw1p_.js +0 -1
- package/dist/gateway/static/root/assets/work-page-DyS0XBpV.js +0 -1
- package/dist/gateway/static/root/assets/workflows-page-CVVJd4gy.js +0 -11
- package/dist/src/browser/pipeline/source.d.ts +0 -9
- package/dist/src/browser/pipeline/source.js +0 -77
|
@@ -78,6 +78,8 @@ import { runBootstrapMigrationsSync } from "../migrations/runner.js";
|
|
|
78
78
|
import { MobileNotificationService } from "../mobile/notification-service.js";
|
|
79
79
|
import { LocalAppService } from "../local-apps/service.js";
|
|
80
80
|
import "../local-apps/index.js";
|
|
81
|
+
import { createRuntimeBrowserRecipeService } from "../browser/recipes/runtime-service.js";
|
|
82
|
+
import "../browser/recipes/index.js";
|
|
81
83
|
import { scheduleGatewayUpdateCheck } from "../infra/update-startup.js";
|
|
82
84
|
import { resolveChannelConnectDeferSet } from "./resolve-channel-connect-defer.js";
|
|
83
85
|
import { restartGatewayProcessWithFreshPid } from "./respawn.js";
|
|
@@ -108,6 +110,7 @@ var GatewayService = class {
|
|
|
108
110
|
_agentService = null;
|
|
109
111
|
channelManager;
|
|
110
112
|
automationService;
|
|
113
|
+
browserRecipeService = null;
|
|
111
114
|
notesService;
|
|
112
115
|
extensionLoader = null;
|
|
113
116
|
extensionMetadataSnapshot = null;
|
|
@@ -126,6 +129,13 @@ var GatewayService = class {
|
|
|
126
129
|
getConfig() {
|
|
127
130
|
return this.config;
|
|
128
131
|
}
|
|
132
|
+
get browserRecipes() {
|
|
133
|
+
if (!this.browserRecipeService) this.browserRecipeService = createRuntimeBrowserRecipeService({
|
|
134
|
+
getConfig: () => this.config,
|
|
135
|
+
emit: (type, payload) => this.emit(type, payload)
|
|
136
|
+
});
|
|
137
|
+
return this.browserRecipeService;
|
|
138
|
+
}
|
|
129
139
|
stopGatewayUpdateCheck = null;
|
|
130
140
|
/** When set (e.g. by `GatewayServer`), `triggerGatewayProcessRestart` can stop HTTP then exit. */
|
|
131
141
|
gatewayShutdownForRestart = null;
|
|
@@ -322,6 +332,7 @@ var GatewayService = class {
|
|
|
322
332
|
},
|
|
323
333
|
extensionRegistry: this.extensionLoader?.getRegistry(),
|
|
324
334
|
getAutomationService: () => this.automationService,
|
|
335
|
+
getBrowserRecipeService: () => this.browserRecipes,
|
|
325
336
|
getNotesService: () => this.notesService,
|
|
326
337
|
getProjectService: () => this.projects,
|
|
327
338
|
getWorkItemService: () => new WorkItemService(),
|
|
@@ -361,6 +372,7 @@ var GatewayService = class {
|
|
|
361
372
|
getDefaultAgentId: () => getDefaultAgentId(this.config),
|
|
362
373
|
getProjectWorkspaceRoot: (projectId) => this.projects.get(projectId)?.workspaceRoot,
|
|
363
374
|
workflowRunService: this.createWorkflowRunService(),
|
|
375
|
+
browserRecipeService: this.browserRecipes,
|
|
364
376
|
onRunCompleted: (run) => this.handleAutomationRunCompleted(run)
|
|
365
377
|
});
|
|
366
378
|
this._agentService.persistentGoals.setWebchatContinuationScheduler((sessionKey, message) => {
|
|
@@ -671,6 +683,7 @@ var GatewayService = class {
|
|
|
671
683
|
agentService: this.agentService,
|
|
672
684
|
getDefaultAgentId: () => getDefaultAgentId(this.config),
|
|
673
685
|
workflowRunService: this.createWorkflowRunService(),
|
|
686
|
+
browserRecipeService: this.browserRecipes,
|
|
674
687
|
onRunCompleted: (run) => this.handleAutomationRunCompleted(run)
|
|
675
688
|
});
|
|
676
689
|
this.startAutomationProductEventBridge();
|
|
@@ -822,6 +835,7 @@ var GatewayService = class {
|
|
|
822
835
|
this.connectorMemorySyncCoordinator = null;
|
|
823
836
|
this.connectedKnowledgeCoordinator?.stop();
|
|
824
837
|
this.connectedKnowledgeCoordinator = null;
|
|
838
|
+
await this.browserRecipeService?.shutdown();
|
|
825
839
|
if (this.browserExtensionRelease) {
|
|
826
840
|
await this.browserExtensionRelease();
|
|
827
841
|
this.browserExtensionRelease = null;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { LocalAppAcceptanceConfig } from './acceptance.js';
|
|
2
|
-
export declare const LOCAL_APP_RUNTIME_BRIDGE_SCRIPT = "(() => {\n let hostPort = null;\n const
|
|
2
|
+
export declare const LOCAL_APP_RUNTIME_BRIDGE_SCRIPT = "(() => {\n let hostPort = null;\n const latest = new Map();\n const send = (type, detail) => {\n const message = { source: 'xopc-local-app-preview', version: 1, type, detail };\n latest.set(type, message);\n hostPort?.postMessage(message);\n };\n const connect = (event) => {\n const message = event.data;\n if (event.source !== parent || message?.source !== 'xopc-local-app-host' || message?.version !== 1 || message?.type !== 'connect' || !event.ports[0]) return;\n event.stopImmediatePropagation();\n hostPort?.close();\n hostPort = event.ports[0];\n hostPort.start();\n for (const message of latest.values()) hostPort.postMessage(message);\n };\n addEventListener('message', connect, true);\n const text = (value) => String(value ?? '').slice(0, 500);\n let runtimeFailure = '';\n const visible = (element) => {\n const style = getComputedStyle(element);\n const rect = element.getBoundingClientRect();\n return style.display !== 'none' && style.visibility !== 'hidden' && Number(style.opacity) !== 0 && rect.width > 0 && rect.height > 0;\n };\n const accessibleName = (element) => {\n const labelledBy = text(element.getAttribute('aria-labelledby'));\n const labelledText = labelledBy.split(/\\s+/).map((id) => document.getElementById(id)?.textContent).filter(Boolean).join(' ');\n return text(element.getAttribute('aria-label') || labelledText || element.labels?.[0]?.textContent || element.textContent || element.getAttribute('alt') || element.getAttribute('title') || element.getAttribute('placeholder') || element.getAttribute('name')).trim();\n };\n const target = (id) => Array.from(document.querySelectorAll('[data-xopc-test-id]'))\n .find((element) => element.getAttribute('data-xopc-test-id') === id);\n const settle = async () => {\n await Promise.resolve();\n await Promise.resolve();\n };\n const readCriteria = () => {\n const encoded = document.querySelector('meta[name=\"xopc-local-app-acceptance\"]')?.content;\n if (!encoded) return { schemaVersion: 1, scenarios: [] };\n const base64 = encoded.replace(/-/g, '+').replace(/_/g, '/');\n const padded = base64.padEnd(Math.ceil(base64.length / 4) * 4, '=');\n const bytes = Uint8Array.from(atob(padded), (char) => char.charCodeAt(0));\n return JSON.parse(new TextDecoder().decode(bytes));\n };\n addEventListener('error', (event) => {\n runtimeFailure = text(event.message || 'A preview resource failed to load');\n send('error', {\n kind: 'script_error',\n message: runtimeFailure,\n filename: text(event.filename),\n line: Number(event.lineno) || undefined,\n column: Number(event.colno) || undefined,\n });\n }, true);\n addEventListener('unhandledrejection', (event) => {\n runtimeFailure = text(event.reason instanceof Error ? event.reason.message : event.reason);\n send('error', { kind: 'unhandled_rejection', message: runtimeFailure });\n });\n const runAcceptance = () => {\n const checks = [];\n const bodyReady = Boolean(document.body);\n checks.push({ id: 'document', status: bodyReady ? 'passed' : 'failed', message: bodyReady ? 'Preview document loaded' : 'Preview document has no body' });\n const contentNodes = bodyReady ? Array.from(document.body.querySelectorAll('*')).slice(0, 300) : [];\n const hasVisibleContent = contentNodes.some((element) => visible(element) && (text(element.textContent).trim() || /^(IMG|SVG|CANVAS|VIDEO)$/.test(element.tagName)));\n checks.push({ id: 'content', status: hasVisibleContent ? 'passed' : 'failed', message: hasVisibleContent ? 'Visible content rendered' : 'No visible content was rendered' });\n const controls = bodyReady ? Array.from(document.body.querySelectorAll('a[href], button, input, select, textarea, [role=\"button\"], [tabindex]')).filter((element) => visible(element) && !element.disabled && element.getAttribute('aria-disabled') !== 'true') : [];\n const unnamed = controls.filter((element) => !accessibleName(element));\n let interactionStatus = controls.length ? 'passed' : 'skipped';\n let interactionMessage = controls.length ? controls.length + ' interactive control(s) are discoverable' : 'No interactive controls to exercise';\n if (unnamed.length) {\n interactionStatus = 'failed';\n interactionMessage = unnamed.length + ' interactive control(s) need an accessible name';\n } else if (controls.length) {\n const previous = document.activeElement;\n controls[0].focus({ preventScroll: true });\n if (document.activeElement !== controls[0]) {\n interactionStatus = 'failed';\n interactionMessage = 'The first interactive control could not receive focus';\n }\n if (previous && typeof previous.focus === 'function') previous.focus({ preventScroll: true });\n else controls[0].blur();\n }\n checks.push({ id: 'interaction', status: interactionStatus, message: interactionMessage });\n send('acceptance', {\n status: checks.some((check) => check.status === 'failed') ? 'failed' : 'passed',\n checks,\n interactiveCount: controls.length,\n });\n };\n const runCriteria = async () => {\n const params = new URLSearchParams(location.search);\n if (params.get('xopcAcceptance') !== '1') return;\n let config;\n try {\n config = readCriteria();\n } catch (error) {\n send('criteria', { status: 'failed', scenarioCount: 0, scenarios: [{ id: 'config', name: 'Acceptance config', status: 'failed', message: text(error instanceof Error ? error.message : error) }] });\n return;\n }\n const requestedScenario = params.get('xopcScenario');\n const selectedScenarios = requestedScenario\n ? (config.scenarios || []).filter((scenario) => scenario.id === requestedScenario)\n : config.scenarios || [];\n if (requestedScenario && !selectedScenarios.length) {\n send('criteria', { status: 'failed', scenarioCount: 1, scenarios: [{ id: requestedScenario, name: requestedScenario, status: 'failed', message: 'Requested scenario was not found' }] });\n return;\n }\n const scenarios = [];\n for (const scenario of selectedScenarios) {\n let failure = '';\n for (let index = 0; index < scenario.steps.length; index += 1) {\n const step = scenario.steps[index];\n try {\n if (step.action === 'click') {\n const element = target(step.target);\n if (!(element instanceof HTMLElement)) throw new Error('Target \"' + step.target + '\" was not found');\n if ('disabled' in element && element.disabled || element.getAttribute('aria-disabled') === 'true') throw new Error('Target \"' + step.target + '\" is disabled');\n element.click();\n await settle();\n } else if (step.action === 'fill') {\n const element = target(step.target);\n if (!(element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement || element instanceof HTMLSelectElement)) throw new Error('Target \"' + step.target + '\" cannot be filled');\n const prototype = element instanceof HTMLInputElement ? HTMLInputElement.prototype : element instanceof HTMLTextAreaElement ? HTMLTextAreaElement.prototype : HTMLSelectElement.prototype;\n const setter = Object.getOwnPropertyDescriptor(prototype, 'value')?.set;\n if (setter) setter.call(element, step.value);\n else element.value = step.value;\n element.dispatchEvent(new Event('input', { bubbles: true }));\n element.dispatchEvent(new Event('change', { bubbles: true }));\n await settle();\n } else if (step.assert === 'text_visible') {\n const found = Array.from(document.body.querySelectorAll('*')).some((element) => visible(element) && text(element.textContent).includes(step.text));\n if (!found) throw new Error('Visible text was not found: \"' + step.text + '\"');\n } else if (step.assert === 'element_exists') {\n if (!target(step.target)) throw new Error('Target \"' + step.target + '\" was not found');\n } else if (step.assert === 'value_equals') {\n const element = target(step.target);\n if (!element || !('value' in element) || element.value !== step.value) throw new Error('Target \"' + step.target + '\" does not have the expected value');\n }\n if (runtimeFailure) throw new Error(runtimeFailure);\n } catch (error) {\n failure = 'Step ' + (index + 1) + ': ' + text(error instanceof Error ? error.message : error);\n break;\n }\n }\n scenarios.push({ id: scenario.id, name: scenario.name, status: failure ? 'failed' : 'passed', message: failure || 'Scenario passed' });\n }\n send('criteria', {\n status: scenarios.some((scenario) => scenario.status === 'failed') ? 'failed' : 'passed',\n scenarioCount: scenarios.length,\n scenarios,\n });\n };\n const loaded = () => {\n send('ready', { readyState: document.readyState });\n void runCriteria();\n if (typeof requestAnimationFrame === 'function') requestAnimationFrame(() => requestAnimationFrame(runAcceptance));\n else setTimeout(runAcceptance, 0);\n };\n if (document.readyState === 'complete') queueMicrotask(loaded);\n else addEventListener('load', loaded, { once: true });\n})();";
|
|
3
3
|
export declare const LOCAL_APP_RUNTIME_BRIDGE_HASH: string;
|
|
4
4
|
export declare function injectLocalAppRuntimeBridge(html: string, acceptance?: LocalAppAcceptanceConfig): string;
|
|
@@ -3,20 +3,20 @@ import { createHash } from "node:crypto";
|
|
|
3
3
|
//#region src/local-apps/preview-runtime-bridge.ts
|
|
4
4
|
const LOCAL_APP_RUNTIME_BRIDGE_SCRIPT = `(() => {
|
|
5
5
|
let hostPort = null;
|
|
6
|
-
const
|
|
6
|
+
const latest = new Map();
|
|
7
7
|
const send = (type, detail) => {
|
|
8
8
|
const message = { source: 'xopc-local-app-preview', version: 1, type, detail };
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
latest.set(type, message);
|
|
10
|
+
hostPort?.postMessage(message);
|
|
11
11
|
};
|
|
12
12
|
const connect = (event) => {
|
|
13
13
|
const message = event.data;
|
|
14
14
|
if (event.source !== parent || message?.source !== 'xopc-local-app-host' || message?.version !== 1 || message?.type !== 'connect' || !event.ports[0]) return;
|
|
15
15
|
event.stopImmediatePropagation();
|
|
16
|
-
|
|
16
|
+
hostPort?.close();
|
|
17
17
|
hostPort = event.ports[0];
|
|
18
18
|
hostPort.start();
|
|
19
|
-
for (const
|
|
19
|
+
for (const message of latest.values()) hostPort.postMessage(message);
|
|
20
20
|
};
|
|
21
21
|
addEventListener('message', connect, true);
|
|
22
22
|
const text = (value) => String(value ?? '').slice(0, 500);
|
|
@@ -33,7 +33,10 @@ const LOCAL_APP_RUNTIME_BRIDGE_SCRIPT = `(() => {
|
|
|
33
33
|
};
|
|
34
34
|
const target = (id) => Array.from(document.querySelectorAll('[data-xopc-test-id]'))
|
|
35
35
|
.find((element) => element.getAttribute('data-xopc-test-id') === id);
|
|
36
|
-
const
|
|
36
|
+
const settle = async () => {
|
|
37
|
+
await Promise.resolve();
|
|
38
|
+
await Promise.resolve();
|
|
39
|
+
};
|
|
37
40
|
const readCriteria = () => {
|
|
38
41
|
const encoded = document.querySelector('meta[name="xopc-local-app-acceptance"]')?.content;
|
|
39
42
|
if (!encoded) return { schemaVersion: 1, scenarios: [] };
|
|
@@ -116,7 +119,7 @@ const LOCAL_APP_RUNTIME_BRIDGE_SCRIPT = `(() => {
|
|
|
116
119
|
if (!(element instanceof HTMLElement)) throw new Error('Target "' + step.target + '" was not found');
|
|
117
120
|
if ('disabled' in element && element.disabled || element.getAttribute('aria-disabled') === 'true') throw new Error('Target "' + step.target + '" is disabled');
|
|
118
121
|
element.click();
|
|
119
|
-
await
|
|
122
|
+
await settle();
|
|
120
123
|
} else if (step.action === 'fill') {
|
|
121
124
|
const element = target(step.target);
|
|
122
125
|
if (!(element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement || element instanceof HTMLSelectElement)) throw new Error('Target "' + step.target + '" cannot be filled');
|
|
@@ -126,7 +129,7 @@ const LOCAL_APP_RUNTIME_BRIDGE_SCRIPT = `(() => {
|
|
|
126
129
|
else element.value = step.value;
|
|
127
130
|
element.dispatchEvent(new Event('input', { bubbles: true }));
|
|
128
131
|
element.dispatchEvent(new Event('change', { bubbles: true }));
|
|
129
|
-
await
|
|
132
|
+
await settle();
|
|
130
133
|
} else if (step.assert === 'text_visible') {
|
|
131
134
|
const found = Array.from(document.body.querySelectorAll('*')).some((element) => visible(element) && text(element.textContent).includes(step.text));
|
|
132
135
|
if (!found) throw new Error('Visible text was not found: "' + step.text + '"');
|
|
@@ -152,9 +155,9 @@ const LOCAL_APP_RUNTIME_BRIDGE_SCRIPT = `(() => {
|
|
|
152
155
|
};
|
|
153
156
|
const loaded = () => {
|
|
154
157
|
send('ready', { readyState: document.readyState });
|
|
155
|
-
|
|
156
|
-
if (typeof requestAnimationFrame === 'function') requestAnimationFrame(() => requestAnimationFrame(
|
|
157
|
-
else setTimeout(
|
|
158
|
+
void runCriteria();
|
|
159
|
+
if (typeof requestAnimationFrame === 'function') requestAnimationFrame(() => requestAnimationFrame(runAcceptance));
|
|
160
|
+
else setTimeout(runAcceptance, 0);
|
|
158
161
|
};
|
|
159
162
|
if (document.readyState === 'complete') queueMicrotask(loaded);
|
|
160
163
|
else addEventListener('load', loaded, { once: true });
|
|
@@ -13,6 +13,8 @@ export declare function createProactiveInsight(input: {
|
|
|
13
13
|
whyItMatters: string;
|
|
14
14
|
nextAction: string;
|
|
15
15
|
evidence: ProactiveEvidence[];
|
|
16
|
+
valueScore: number;
|
|
17
|
+
valueReasons: string[];
|
|
16
18
|
nowMs?: number;
|
|
17
19
|
}): ProactiveInsight | null;
|
|
18
20
|
export declare function setProactiveInsightStatus(id: string, status: ProactiveInsightStatus, nowMs?: number, expectedStatus?: ProactiveInsightStatus): ProactiveInsight | null;
|
|
@@ -14,6 +14,8 @@ function insightFromRow(row) {
|
|
|
14
14
|
nextAction: row.next_action,
|
|
15
15
|
evidence: JSON.parse(row.evidence_json),
|
|
16
16
|
status: row.status,
|
|
17
|
+
valueScore: row.value_score,
|
|
18
|
+
valueReasons: JSON.parse(row.value_reasons_json),
|
|
17
19
|
createdAt: row.created_at,
|
|
18
20
|
updatedAt: row.updated_at
|
|
19
21
|
};
|
|
@@ -58,8 +60,9 @@ function createProactiveInsight(input) {
|
|
|
58
60
|
runSqliteWriteTransaction((db) => {
|
|
59
61
|
created = db.prepare(`INSERT OR IGNORE INTO proactive_insights (
|
|
60
62
|
insight_id, watch_id, run_id, kind, title, summary, why_it_matters,
|
|
61
|
-
next_action, evidence_json, content_hash, status,
|
|
62
|
-
|
|
63
|
+
next_action, evidence_json, content_hash, status, value_score,
|
|
64
|
+
value_reasons_json, created_at, updated_at
|
|
65
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'unread', ?, ?, ?, ?)`).run(id, input.watchId, input.runId, input.kind, input.title, input.summary, input.whyItMatters, input.nextAction, JSON.stringify(input.evidence), contentHash, input.valueScore, JSON.stringify(input.valueReasons), now, now).changes > 0;
|
|
63
66
|
});
|
|
64
67
|
return created ? listProactiveInsights({ limit: 100 }).find((item) => item.id === id) ?? null : null;
|
|
65
68
|
}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { createLogger } from "../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../utils/logger.js";
|
|
3
|
+
import { getRelationshipSettings, isProactiveSupportAllowed } from "../storage/sqlite/relationship-settings-repository.js";
|
|
4
|
+
import "../storage/sqlite/index.js";
|
|
3
5
|
import { getFocusWatchByAutomationId, recordFocusWatchRun } from "./watch-repository.js";
|
|
4
|
-
import { createProactiveInsight } from "./insight-repository.js";
|
|
6
|
+
import { createProactiveInsight, listProactiveInsights } from "./insight-repository.js";
|
|
7
|
+
import { scoreProactiveValue } from "./value-score.js";
|
|
5
8
|
//#region src/proactive/run-processor.ts
|
|
6
9
|
init_logger();
|
|
7
10
|
const log = createLogger("ProactiveRunProcessor");
|
|
@@ -105,6 +108,22 @@ function processFocusAutomationRun(run) {
|
|
|
105
108
|
nowMs: run.endedAtMs
|
|
106
109
|
})) return { handled: true };
|
|
107
110
|
if (!result.meaningful) return { handled: true };
|
|
111
|
+
if (!isProactiveSupportAllowed(getRelationshipSettings(), {
|
|
112
|
+
now: new Date(run.endedAtMs),
|
|
113
|
+
topic: watch.kind
|
|
114
|
+
})) return { handled: true };
|
|
115
|
+
const history = listProactiveInsights({
|
|
116
|
+
status: ["approved", "dismissed"],
|
|
117
|
+
limit: 50
|
|
118
|
+
});
|
|
119
|
+
const value = scoreProactiveValue({
|
|
120
|
+
kind: watch.kind,
|
|
121
|
+
evidenceCount: result.evidence.length,
|
|
122
|
+
hasNextAction: Boolean(result.nextAction),
|
|
123
|
+
approvedCount: history.filter((item) => item.status === "approved").length,
|
|
124
|
+
dismissedCount: history.filter((item) => item.status === "dismissed").length
|
|
125
|
+
});
|
|
126
|
+
if (!value.shouldDeliver) return { handled: true };
|
|
108
127
|
const insight = createProactiveInsight({
|
|
109
128
|
watchId: watch.id,
|
|
110
129
|
runId: run.id,
|
|
@@ -114,6 +133,8 @@ function processFocusAutomationRun(run) {
|
|
|
114
133
|
whyItMatters: result.whyItMatters,
|
|
115
134
|
nextAction: result.nextAction,
|
|
116
135
|
evidence: result.evidence,
|
|
136
|
+
valueScore: value.score,
|
|
137
|
+
valueReasons: value.reasons,
|
|
117
138
|
nowMs: run.endedAtMs
|
|
118
139
|
});
|
|
119
140
|
return insight ? {
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { FocusWatchKind } from './types.js';
|
|
2
|
+
export interface ProactiveValueScore {
|
|
3
|
+
score: number;
|
|
4
|
+
reasons: string[];
|
|
5
|
+
shouldDeliver: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare function scoreProactiveValue(input: {
|
|
8
|
+
kind: FocusWatchKind;
|
|
9
|
+
evidenceCount: number;
|
|
10
|
+
hasNextAction: boolean;
|
|
11
|
+
approvedCount: number;
|
|
12
|
+
dismissedCount: number;
|
|
13
|
+
}): ProactiveValueScore;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
//#region src/proactive/value-score.ts
|
|
2
|
+
function scoreProactiveValue(input) {
|
|
3
|
+
const reasons = [];
|
|
4
|
+
let score = .15;
|
|
5
|
+
if (input.evidenceCount > 0) {
|
|
6
|
+
score += Math.min(.25, input.evidenceCount * .1);
|
|
7
|
+
reasons.push("evidence_backed");
|
|
8
|
+
}
|
|
9
|
+
if (input.hasNextAction) {
|
|
10
|
+
score += .25;
|
|
11
|
+
reasons.push("actionable");
|
|
12
|
+
}
|
|
13
|
+
const urgency = input.kind === "deadline" ? .25 : input.kind === "staleness" ? .2 : .15;
|
|
14
|
+
score += urgency;
|
|
15
|
+
reasons.push(input.kind === "deadline" ? "time_sensitive" : "focus_relevant");
|
|
16
|
+
const rated = input.approvedCount + input.dismissedCount;
|
|
17
|
+
if (rated > 0) {
|
|
18
|
+
const approvalRate = input.approvedCount / rated;
|
|
19
|
+
score += (approvalRate - .5) * .4;
|
|
20
|
+
reasons.push(approvalRate >= .5 ? "historically_useful" : "historically_dismissed");
|
|
21
|
+
}
|
|
22
|
+
score = Math.max(0, Math.min(1, score));
|
|
23
|
+
return {
|
|
24
|
+
score,
|
|
25
|
+
reasons,
|
|
26
|
+
shouldDeliver: score >= .65
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
//#endregion
|
|
30
|
+
export { scoreProactiveValue };
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
const SHARE_CONFIG_DEFAULTS = {
|
|
4
4
|
enabled: true,
|
|
5
5
|
defaultTtlMs: 864e5,
|
|
6
|
-
maxTtlMs:
|
|
7
|
-
maxActiveShares:
|
|
8
|
-
maxFileSize:
|
|
6
|
+
maxTtlMs: 2592e6,
|
|
7
|
+
maxActiveShares: 500,
|
|
8
|
+
maxFileSize: 524288e3,
|
|
9
9
|
inlinePreviewMimes: [
|
|
10
10
|
"image/png",
|
|
11
11
|
"image/jpeg",
|
|
@@ -20,8 +20,8 @@ const SHARE_CONFIG_DEFAULTS = {
|
|
|
20
20
|
],
|
|
21
21
|
directory: {
|
|
22
22
|
enabled: true,
|
|
23
|
-
maxFolderSize:
|
|
24
|
-
maxFileCount:
|
|
23
|
+
maxFolderSize: 2147483648,
|
|
24
|
+
maxFileCount: 1e4,
|
|
25
25
|
maxDepth: 20,
|
|
26
26
|
listingCacheMs: 6e4,
|
|
27
27
|
zipConcurrency: 1
|
|
@@ -60,7 +60,7 @@ export interface CreateSiteShareParams {
|
|
|
60
60
|
path?: string;
|
|
61
61
|
/** Proxy: full upstream URL (must be loopback or whitelisted). */
|
|
62
62
|
upstreamUrl?: string;
|
|
63
|
-
/** Default
|
|
63
|
+
/** Default 24h. */
|
|
64
64
|
ttlMs?: number;
|
|
65
65
|
/** Optional friendly description. */
|
|
66
66
|
description?: string;
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
const SITE_SHARE_CONFIG_DEFAULTS = {
|
|
3
3
|
enabled: true,
|
|
4
4
|
publicHostSuffix: "share.xopc.ai",
|
|
5
|
-
defaultTtlMs:
|
|
6
|
-
maxTtlMs:
|
|
7
|
-
maxActiveSites:
|
|
5
|
+
defaultTtlMs: 864e5,
|
|
6
|
+
maxTtlMs: 2592e6,
|
|
7
|
+
maxActiveSites: 50,
|
|
8
8
|
static: {
|
|
9
9
|
enabled: true,
|
|
10
|
-
maxRootDirSize:
|
|
11
|
-
maxFileCount:
|
|
10
|
+
maxRootDirSize: 1073741824,
|
|
11
|
+
maxFileCount: 2e4,
|
|
12
12
|
rewriteEnabledByDefault: false
|
|
13
13
|
},
|
|
14
14
|
proxy: {
|
|
@@ -5,6 +5,9 @@ export { DatabaseSchemaMigrationGapError, DatabaseSchemaTooNewError, } from './m
|
|
|
5
5
|
export { discoverSqlMigrations, listRegisteredMigrationTargets } from './migrations/discover.js';
|
|
6
6
|
export { closeXopcDatabase, getXopcDatabase, isXopcDatabaseOpen, openXopcDatabase, requireXopcDatabase, resetXopcDatabaseSingletonForTest, type OpenXopcDatabaseOptions, type XopcDatabase, } from './connection.js';
|
|
7
7
|
export { getSqliteDatabase, runSqliteWriteTransaction } from './transaction.js';
|
|
8
|
+
export { getInteractionState, setInteractionState, updateInteractionStateFromMessage, type InteractionState, } from './interaction-state-repository.js';
|
|
9
|
+
export { buildRelationshipPrompt, getRelationshipSettings, isProactiveSupportAllowed, updateRelationshipSettings, type RelationshipSettings, type SupportMode, } from './relationship-settings-repository.js';
|
|
10
|
+
export { completeTaskOutcome, findTaskOutcomeForAssistant, getTaskOutcome, listTaskOutcomes, setTaskOutcomeFeedback, startTaskOutcome, summarizeTaskOutcomes, updateTaskOutcome, type TaskContract, type TaskEvidence, type TaskFeedbackOutcome, type TaskOutcome, type TaskOutcomeMetrics, type TaskOutcomeStatus, } from './task-outcome-repository.js';
|
|
8
11
|
export { buildDefaultSessionMetadata, type SessionMetadataSeed, } from './session-metadata.js';
|
|
9
12
|
export { buildGlobalSessionStats, classifyStoredRow, estimateTokensFromMessages, extractFtsContent, metadataToSessionInsert, sessionConfigRowToConfig, sessionRowToMetadata, transcriptEntryRowToStoredRow, type SessionConfigRow, type SessionRow, type TranscriptEntryRow, } from './row-mappers.js';
|
|
10
13
|
export { deleteSessionRecord, ensureSessionRecord, getCurrentSessionId, getGlobalSessionStats, findSessionKeyBySessionId, getSessionPersistedLevels, getSessionMetadata, incrementSessionStatsOnAppend, listSessionMetadata, listSessionsByAgent, patchSessionMetadata, resetSessionRecord, resolveSessionAgentId, updateSessionStats, } from './session-repository.js';
|
|
@@ -6,6 +6,9 @@ import { XOPC_DB_BASELINE_SCHEMA_VERSION, XOPC_DB_SCHEMA_VERSION, applyPendingMi
|
|
|
6
6
|
import { ensureXopcDatabaseSchema } from "./schema.js";
|
|
7
7
|
import { closeXopcDatabase, getXopcDatabase, isXopcDatabaseOpen, openXopcDatabase, requireXopcDatabase, resetXopcDatabaseSingletonForTest } from "./connection.js";
|
|
8
8
|
import { getSqliteDatabase, runSqliteWriteTransaction } from "./transaction.js";
|
|
9
|
+
import { getInteractionState, setInteractionState, updateInteractionStateFromMessage } from "./interaction-state-repository.js";
|
|
10
|
+
import { buildRelationshipPrompt, getRelationshipSettings, isProactiveSupportAllowed, updateRelationshipSettings } from "./relationship-settings-repository.js";
|
|
11
|
+
import { completeTaskOutcome, findTaskOutcomeForAssistant, getTaskOutcome, listTaskOutcomes, setTaskOutcomeFeedback, startTaskOutcome, summarizeTaskOutcomes, updateTaskOutcome } from "./task-outcome-repository.js";
|
|
9
12
|
import { buildDefaultSessionMetadata } from "./session-metadata.js";
|
|
10
13
|
import { buildGlobalSessionStats, classifyStoredRow, estimateTokensFromMessages, extractFtsContent, metadataToSessionInsert, sessionConfigRowToConfig, sessionRowToMetadata, transcriptEntryRowToStoredRow } from "./row-mappers.js";
|
|
11
14
|
import { deleteSessionRecord, ensureSessionRecord, findSessionKeyBySessionId, getCurrentSessionId, getGlobalSessionStats, getSessionMetadata, getSessionPersistedLevels, incrementSessionStatsOnAppend, listSessionMetadata, listSessionsByAgent, patchSessionMetadata, resetSessionRecord, resolveSessionAgentId, updateSessionStats } from "./session-repository.js";
|
|
@@ -21,4 +24,4 @@ import { appendConnectorExecutionAudit, claimConnectorWebhookDelivery, completeC
|
|
|
21
24
|
import { getUserTrustPolicy, setUserTrustPolicy } from "./user-trust-repository.js";
|
|
22
25
|
import { consumeMemoryReferenceConsent, decideMemoryReferenceConsent, ensureMemoryReferenceConsentRequest, hasMemoryReferenceConsent, listMemoryReferenceConsents, revokeMemoryReferenceConsent } from "./memory-reference-consent-repository.js";
|
|
23
26
|
import { getUserProfilePromptState, setUserProfilePromptState } from "./user-profile-setup-repository.js";
|
|
24
|
-
export { DatabaseSchemaMigrationGapError, DatabaseSchemaTooNewError, SCHEMA_META_SCHEMA_VERSION_KEY, USER_UNDERSTANDING_REMEDIATION_POLICY, XOPC_DB_BASELINE_SCHEMA_VERSION, XOPC_DB_FILENAME, XOPC_DB_SCHEMA_VERSION, appendConnectorExecutionAudit, appendMemorySignal, appendMemoryTraceEvent, appendTranscriptEntry, applyPendingMigrations, attachMemoryEvidence, buildDefaultSessionMetadata, buildGlobalSessionStats, captureCompactionCheckpoint, claimConnectorWebhookDelivery, claimKnowledgeSourceItems, classifyStoredRow, closeXopcDatabase, completeConnectorWebhookDelivery, completeKnowledgeSourceItemSynthesis, consumeConnectorApproval, consumeMemoryReferenceConsent, createConnectorApproval, createObjectLinkRecord, decideConnectorApproval, decideMemoryReferenceConsent, deleteConnectorConnection, deleteConnectorInstallation, deleteMemoryEvidenceForRecord, deleteMemoryRecord, deleteNoteAgentContextRecord, deleteNoteRecord, deleteSessionConfig, deleteSessionRecord, discoverSqlMigrations, ensureMemoryReferenceConsentRequest, ensureSessionRecord, ensureXopcDatabaseSchema, estimateTokensFromMessages, extractFtsContent, findLatestMemoryInjectTrace, findSessionKeyBySessionId, finishKnowledgeSyncRun, getActivityEventRecord, getCachedConnectorCatalogEntry, getCompactionCheckpointDetail, getConnectorApproval, getConnectorConnection, getConnectorInstallation, getCurrentSessionId, getGlobalSessionStats, getKnowledgeConsumerWatermark, getKnowledgeSourceCursor, getKnowledgeSourceItem, getMemoryProviderState, getMemoryRecord, getNoteAgentContextRecord, getNoteRecord, getSessionConfig, getSessionMetadata, getSessionPersistedLevels, getSqliteDatabase, getUserProfilePromptState, getUserTrustPolicy, getXopcDatabase, hasMemoryReferenceConsent, hasSessionConfig, hasUnresolvedMemoryConflict, incrementSessionStatsOnAppend, inspectSchemaMigrationStatus, isXopcDatabaseOpen, listActivityRecords, listCachedConnectorCatalogEntries, listCompactionCheckpoints, listConnectorActionMetadata, listConnectorApprovals, listConnectorConnections, listConnectorExecutionAudit, listConnectorInstallations, listKnowledgeSourceChanges, listKnowledgeSourceItems, listKnowledgeSyncRuns, listMemoryEvidence, listMemoryRecords, listMemoryReferenceConsents, listMemorySignals, listMemoryTraceEvents, listNoteRecords, listObjectActivityRecords, listObjectLinkRecords, listProjectActivityRecords, listRegisteredMigrationTargets, listSessionMetadata, listSessionsByAgent, loadCheckpointRows, loadLlmMessagesForSession, loadTranscriptRows, loadTranscriptRowsForSession, markMemoryRecordsConflicted, metadataToSessionInsert, openXopcDatabase, paginateTranscriptMessages, patchSessionMetadata, readSchemaVersion, readSchemaVersionForTest, recordActivityEvent, releaseConnectorWebhookDelivery, replaceConnectorCatalogEntries, replaceTranscriptRows, requireXopcDatabase, resetSessionRecord, resetXopcDatabaseSingletonForTest, resolveMigrationsDir, resolveSessionAgentId, resolveXopcDatabasePath, restoreCompactionCheckpoint, revokeMemoryReferenceConsent, runSqliteWriteTransaction, searchMemoryIndex, searchMemoryRecords, sessionConfigRowToConfig, sessionRowToMetadata, setKnowledgeConsumerWatermark, setKnowledgeSourceCursor, setKnowledgeSourceItemSynthesisStatus, setLatestMemoryInjectFeedback, setMemoryProviderState, setMemoryTraceFeedback, setSessionConfig, setUserProfilePromptState, setUserTrustPolicy, startKnowledgeSyncRun, summarizeMemoryRecallFeedback, summarizeUserUnderstandingQuality, syncMemoryIndex, transcriptEntryRowToStoredRow, updateSessionConfig, updateSessionStats, upsertConnectorActionMetadata, upsertConnectorCatalogEntry, upsertConnectorConnection, upsertConnectorInstallation, upsertKnowledgeSourceItems, upsertMemoryRecord, upsertNoteAgentContextRecord, upsertNoteRecord };
|
|
27
|
+
export { DatabaseSchemaMigrationGapError, DatabaseSchemaTooNewError, SCHEMA_META_SCHEMA_VERSION_KEY, USER_UNDERSTANDING_REMEDIATION_POLICY, XOPC_DB_BASELINE_SCHEMA_VERSION, XOPC_DB_FILENAME, XOPC_DB_SCHEMA_VERSION, appendConnectorExecutionAudit, appendMemorySignal, appendMemoryTraceEvent, appendTranscriptEntry, applyPendingMigrations, attachMemoryEvidence, buildDefaultSessionMetadata, buildGlobalSessionStats, buildRelationshipPrompt, captureCompactionCheckpoint, claimConnectorWebhookDelivery, claimKnowledgeSourceItems, classifyStoredRow, closeXopcDatabase, completeConnectorWebhookDelivery, completeKnowledgeSourceItemSynthesis, completeTaskOutcome, consumeConnectorApproval, consumeMemoryReferenceConsent, createConnectorApproval, createObjectLinkRecord, decideConnectorApproval, decideMemoryReferenceConsent, deleteConnectorConnection, deleteConnectorInstallation, deleteMemoryEvidenceForRecord, deleteMemoryRecord, deleteNoteAgentContextRecord, deleteNoteRecord, deleteSessionConfig, deleteSessionRecord, discoverSqlMigrations, ensureMemoryReferenceConsentRequest, ensureSessionRecord, ensureXopcDatabaseSchema, estimateTokensFromMessages, extractFtsContent, findLatestMemoryInjectTrace, findSessionKeyBySessionId, findTaskOutcomeForAssistant, finishKnowledgeSyncRun, getActivityEventRecord, getCachedConnectorCatalogEntry, getCompactionCheckpointDetail, getConnectorApproval, getConnectorConnection, getConnectorInstallation, getCurrentSessionId, getGlobalSessionStats, getInteractionState, getKnowledgeConsumerWatermark, getKnowledgeSourceCursor, getKnowledgeSourceItem, getMemoryProviderState, getMemoryRecord, getNoteAgentContextRecord, getNoteRecord, getRelationshipSettings, getSessionConfig, getSessionMetadata, getSessionPersistedLevels, getSqliteDatabase, getTaskOutcome, getUserProfilePromptState, getUserTrustPolicy, getXopcDatabase, hasMemoryReferenceConsent, hasSessionConfig, hasUnresolvedMemoryConflict, incrementSessionStatsOnAppend, inspectSchemaMigrationStatus, isProactiveSupportAllowed, isXopcDatabaseOpen, listActivityRecords, listCachedConnectorCatalogEntries, listCompactionCheckpoints, listConnectorActionMetadata, listConnectorApprovals, listConnectorConnections, listConnectorExecutionAudit, listConnectorInstallations, listKnowledgeSourceChanges, listKnowledgeSourceItems, listKnowledgeSyncRuns, listMemoryEvidence, listMemoryRecords, listMemoryReferenceConsents, listMemorySignals, listMemoryTraceEvents, listNoteRecords, listObjectActivityRecords, listObjectLinkRecords, listProjectActivityRecords, listRegisteredMigrationTargets, listSessionMetadata, listSessionsByAgent, listTaskOutcomes, loadCheckpointRows, loadLlmMessagesForSession, loadTranscriptRows, loadTranscriptRowsForSession, markMemoryRecordsConflicted, metadataToSessionInsert, openXopcDatabase, paginateTranscriptMessages, patchSessionMetadata, readSchemaVersion, readSchemaVersionForTest, recordActivityEvent, releaseConnectorWebhookDelivery, replaceConnectorCatalogEntries, replaceTranscriptRows, requireXopcDatabase, resetSessionRecord, resetXopcDatabaseSingletonForTest, resolveMigrationsDir, resolveSessionAgentId, resolveXopcDatabasePath, restoreCompactionCheckpoint, revokeMemoryReferenceConsent, runSqliteWriteTransaction, searchMemoryIndex, searchMemoryRecords, sessionConfigRowToConfig, sessionRowToMetadata, setInteractionState, setKnowledgeConsumerWatermark, setKnowledgeSourceCursor, setKnowledgeSourceItemSynthesisStatus, setLatestMemoryInjectFeedback, setMemoryProviderState, setMemoryTraceFeedback, setSessionConfig, setTaskOutcomeFeedback, setUserProfilePromptState, setUserTrustPolicy, startKnowledgeSyncRun, startTaskOutcome, summarizeMemoryRecallFeedback, summarizeTaskOutcomes, summarizeUserUnderstandingQuality, syncMemoryIndex, transcriptEntryRowToStoredRow, updateInteractionStateFromMessage, updateRelationshipSettings, updateSessionConfig, updateSessionStats, updateTaskOutcome, upsertConnectorActionMetadata, upsertConnectorCatalogEntry, upsertConnectorConnection, upsertConnectorInstallation, upsertKnowledgeSourceItems, upsertMemoryRecord, upsertNoteAgentContextRecord, upsertNoteRecord };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type InteractionStateSignal } from '../../user-context/interaction-state.js';
|
|
2
|
+
export interface InteractionState extends InteractionStateSignal {
|
|
3
|
+
sessionKey: string;
|
|
4
|
+
expiresAt: number;
|
|
5
|
+
updatedAt: number;
|
|
6
|
+
}
|
|
7
|
+
export declare function getInteractionState(sessionKey: string, now?: number): InteractionState | undefined;
|
|
8
|
+
export declare function setInteractionState(input: {
|
|
9
|
+
sessionKey: string;
|
|
10
|
+
signal: InteractionStateSignal;
|
|
11
|
+
now?: number;
|
|
12
|
+
}): InteractionState;
|
|
13
|
+
export declare function updateInteractionStateFromMessage(input: {
|
|
14
|
+
sessionKey: string;
|
|
15
|
+
message: string;
|
|
16
|
+
now?: number;
|
|
17
|
+
}): InteractionState;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { getSqliteDatabase, runSqliteWriteTransaction } from "./transaction.js";
|
|
2
|
+
import { inferInteractionState } from "../../user-context/interaction-state.js";
|
|
3
|
+
//#region src/storage/sqlite/interaction-state-repository.ts
|
|
4
|
+
const STATE_TTL_MS = 360 * 60 * 1e3;
|
|
5
|
+
function fromRow(row) {
|
|
6
|
+
return {
|
|
7
|
+
sessionKey: row.session_key,
|
|
8
|
+
supportNeed: row.support_need,
|
|
9
|
+
...row.emotion_hypothesis ? { emotionHypothesis: row.emotion_hypothesis } : {},
|
|
10
|
+
confidence: row.confidence,
|
|
11
|
+
source: row.source,
|
|
12
|
+
repairStatus: row.repair_status,
|
|
13
|
+
...row.repair_reason ? { repairReason: row.repair_reason } : {},
|
|
14
|
+
expiresAt: row.expires_at,
|
|
15
|
+
updatedAt: row.updated_at
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
function getInteractionState(sessionKey, now = Date.now()) {
|
|
19
|
+
const row = getSqliteDatabase().prepare(`SELECT session_key, support_need, emotion_hypothesis, confidence, source,
|
|
20
|
+
repair_status, repair_reason, expires_at, updated_at
|
|
21
|
+
FROM interaction_states WHERE session_key = ? AND expires_at > ?`).get(sessionKey, now);
|
|
22
|
+
return row ? fromRow(row) : void 0;
|
|
23
|
+
}
|
|
24
|
+
function setInteractionState(input) {
|
|
25
|
+
const now = input.now ?? Date.now();
|
|
26
|
+
const expiresAt = now + STATE_TTL_MS;
|
|
27
|
+
runSqliteWriteTransaction((db) => {
|
|
28
|
+
db.prepare(`INSERT INTO interaction_states (
|
|
29
|
+
session_key, support_need, emotion_hypothesis, confidence, source,
|
|
30
|
+
repair_status, repair_reason, expires_at, updated_at
|
|
31
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
32
|
+
ON CONFLICT(session_key) DO UPDATE SET
|
|
33
|
+
support_need = excluded.support_need,
|
|
34
|
+
emotion_hypothesis = excluded.emotion_hypothesis,
|
|
35
|
+
confidence = excluded.confidence,
|
|
36
|
+
source = excluded.source,
|
|
37
|
+
repair_status = excluded.repair_status,
|
|
38
|
+
repair_reason = excluded.repair_reason,
|
|
39
|
+
expires_at = excluded.expires_at,
|
|
40
|
+
updated_at = excluded.updated_at`).run(input.sessionKey, input.signal.supportNeed, input.signal.emotionHypothesis ?? null, input.signal.confidence, input.signal.source, input.signal.repairStatus, input.signal.repairReason ?? null, expiresAt, now);
|
|
41
|
+
});
|
|
42
|
+
return getInteractionState(input.sessionKey, now);
|
|
43
|
+
}
|
|
44
|
+
function updateInteractionStateFromMessage(input) {
|
|
45
|
+
const now = input.now ?? Date.now();
|
|
46
|
+
const previous = getInteractionState(input.sessionKey, now);
|
|
47
|
+
const inferred = inferInteractionState(input.message);
|
|
48
|
+
const signal = previous?.repairStatus === "needed" && inferred.repairStatus === "none" ? {
|
|
49
|
+
...inferred,
|
|
50
|
+
repairStatus: "needed",
|
|
51
|
+
repairReason: previous.repairReason
|
|
52
|
+
} : inferred;
|
|
53
|
+
return setInteractionState({
|
|
54
|
+
sessionKey: input.sessionKey,
|
|
55
|
+
signal,
|
|
56
|
+
now
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
//#endregion
|
|
60
|
+
export { getInteractionState, setInteractionState, updateInteractionStateFromMessage };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getSqliteDatabase, runSqliteWriteTransaction } from "./transaction.js";
|
|
2
|
-
import { buildFts5SearchQuery, fts5RankToScore, memoryLexicalSimilarity } from "./fts.js";
|
|
3
2
|
import { LOCAL_USER_ID } from "../../user-context/owner.js";
|
|
3
|
+
import { buildFts5SearchQuery, fts5RankToScore, memoryLexicalSimilarity } from "./fts.js";
|
|
4
4
|
import { randomUUID } from "node:crypto";
|
|
5
5
|
//#region src/storage/sqlite/memory-records-repository.ts
|
|
6
6
|
const USER_UNDERSTANDING_REMEDIATION_POLICY = {
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
CREATE TABLE IF NOT EXISTS browser_recipes (
|
|
2
|
+
recipe_id TEXT PRIMARY KEY,
|
|
3
|
+
revision INTEGER NOT NULL,
|
|
4
|
+
name TEXT NOT NULL,
|
|
5
|
+
description TEXT,
|
|
6
|
+
status TEXT NOT NULL CHECK (status IN ('published', 'disabled')),
|
|
7
|
+
yaml_source TEXT NOT NULL,
|
|
8
|
+
risk_level TEXT NOT NULL CHECK (risk_level IN ('read_only', 'account_write', 'sensitive')),
|
|
9
|
+
domains_json TEXT NOT NULL,
|
|
10
|
+
created_at_ms INTEGER NOT NULL,
|
|
11
|
+
updated_at_ms INTEGER NOT NULL
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
CREATE TABLE IF NOT EXISTS browser_recipe_runs (
|
|
15
|
+
run_id TEXT PRIMARY KEY,
|
|
16
|
+
recipe_id TEXT NOT NULL,
|
|
17
|
+
recipe_revision INTEGER NOT NULL,
|
|
18
|
+
recipe_yaml TEXT NOT NULL,
|
|
19
|
+
status TEXT NOT NULL CHECK (status IN ('queued', 'running', 'succeeded', 'failed', 'cancelled')),
|
|
20
|
+
args_json TEXT NOT NULL,
|
|
21
|
+
result_json TEXT,
|
|
22
|
+
error TEXT,
|
|
23
|
+
created_at_ms INTEGER NOT NULL,
|
|
24
|
+
started_at_ms INTEGER,
|
|
25
|
+
ended_at_ms INTEGER,
|
|
26
|
+
duration_ms INTEGER,
|
|
27
|
+
FOREIGN KEY (recipe_id) REFERENCES browser_recipes(recipe_id) ON DELETE CASCADE
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
CREATE INDEX IF NOT EXISTS idx_browser_recipe_runs_recipe_created
|
|
31
|
+
ON browser_recipe_runs(recipe_id, created_at_ms DESC);
|
|
32
|
+
|
|
33
|
+
CREATE TABLE IF NOT EXISTS browser_recipe_run_events (
|
|
34
|
+
event_id TEXT PRIMARY KEY,
|
|
35
|
+
run_id TEXT NOT NULL,
|
|
36
|
+
seq INTEGER NOT NULL,
|
|
37
|
+
type TEXT NOT NULL,
|
|
38
|
+
data_json TEXT,
|
|
39
|
+
created_at_ms INTEGER NOT NULL,
|
|
40
|
+
UNIQUE(run_id, seq),
|
|
41
|
+
FOREIGN KEY (run_id) REFERENCES browser_recipe_runs(run_id) ON DELETE CASCADE
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
CREATE INDEX IF NOT EXISTS idx_browser_recipe_run_events_run_seq
|
|
45
|
+
ON browser_recipe_run_events(run_id, seq ASC);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
CREATE TABLE task_outcomes (
|
|
2
|
+
run_id TEXT PRIMARY KEY,
|
|
3
|
+
session_key TEXT NOT NULL,
|
|
4
|
+
channel TEXT NOT NULL,
|
|
5
|
+
objective TEXT NOT NULL,
|
|
6
|
+
status TEXT NOT NULL CHECK (status IN ('running', 'succeeded', 'failed', 'cancelled')),
|
|
7
|
+
summary TEXT,
|
|
8
|
+
contract_json TEXT,
|
|
9
|
+
evidence_json TEXT NOT NULL DEFAULT '[]',
|
|
10
|
+
feedback_outcome TEXT CHECK (feedback_outcome IN ('helpful', 'not_helpful')),
|
|
11
|
+
feedback_reason TEXT,
|
|
12
|
+
needs_correction INTEGER CHECK (needs_correction IN (0, 1)),
|
|
13
|
+
support_fit INTEGER CHECK (support_fit IN (0, 1)),
|
|
14
|
+
started_at INTEGER NOT NULL,
|
|
15
|
+
completed_at INTEGER,
|
|
16
|
+
updated_at INTEGER NOT NULL,
|
|
17
|
+
FOREIGN KEY (session_key) REFERENCES sessions(session_key) ON DELETE CASCADE
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
CREATE INDEX idx_task_outcomes_session_started
|
|
21
|
+
ON task_outcomes(session_key, started_at DESC);
|
|
22
|
+
|
|
23
|
+
CREATE INDEX idx_task_outcomes_status_started
|
|
24
|
+
ON task_outcomes(status, started_at DESC);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
CREATE TABLE relationship_settings (
|
|
2
|
+
owner_id TEXT PRIMARY KEY CHECK (owner_id = 'local-owner'),
|
|
3
|
+
support_mode TEXT NOT NULL CHECK (support_mode IN ('efficient', 'coach', 'companion', 'auto')),
|
|
4
|
+
proactive_enabled INTEGER NOT NULL CHECK (proactive_enabled IN (0, 1)),
|
|
5
|
+
quiet_start TEXT,
|
|
6
|
+
quiet_end TEXT,
|
|
7
|
+
allowed_topics_json TEXT NOT NULL,
|
|
8
|
+
blocked_topics_json TEXT NOT NULL,
|
|
9
|
+
updated_at INTEGER NOT NULL
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
INSERT INTO relationship_settings (
|
|
13
|
+
owner_id, support_mode, proactive_enabled, allowed_topics_json, blocked_topics_json, updated_at
|
|
14
|
+
) VALUES ('local-owner', 'auto', 0, '[]', '[]', unixepoch() * 1000);
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
ALTER TABLE task_outcomes ADD COLUMN verification_status TEXT NOT NULL DEFAULT 'unverified'
|
|
2
|
+
CHECK (verification_status IN ('passed', 'failed', 'unverified'));
|
|
3
|
+
ALTER TABLE task_outcomes ADD COLUMN verification_json TEXT NOT NULL DEFAULT '{"checks":[]}';
|
|
4
|
+
ALTER TABLE task_outcomes ADD COLUMN failure_code TEXT;
|
|
5
|
+
ALTER TABLE task_outcomes ADD COLUMN failure_phase TEXT;
|
|
6
|
+
ALTER TABLE task_outcomes ADD COLUMN recovery_action TEXT;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
CREATE TABLE interaction_states (
|
|
2
|
+
session_key TEXT PRIMARY KEY REFERENCES sessions(session_key) ON DELETE CASCADE,
|
|
3
|
+
support_need TEXT NOT NULL CHECK (support_need IN ('listen', 'clarify', 'advise', 'act', 'unknown')),
|
|
4
|
+
emotion_hypothesis TEXT,
|
|
5
|
+
confidence REAL NOT NULL CHECK (confidence >= 0 AND confidence <= 1),
|
|
6
|
+
source TEXT NOT NULL CHECK (source IN ('explicit', 'inferred')),
|
|
7
|
+
repair_status TEXT NOT NULL CHECK (repair_status IN ('none', 'needed', 'repaired')),
|
|
8
|
+
repair_reason TEXT,
|
|
9
|
+
expires_at INTEGER NOT NULL,
|
|
10
|
+
updated_at INTEGER NOT NULL
|
|
11
|
+
);
|
|
@@ -3,7 +3,7 @@ import type { ApplyMigrationsOptions } from './types.js';
|
|
|
3
3
|
/** Baseline schema version applied from schema.sql on first open. */
|
|
4
4
|
export declare const XOPC_DB_BASELINE_SCHEMA_VERSION = 11;
|
|
5
5
|
/** Latest schema version this release supports (increment when adding migrations). */
|
|
6
|
-
export declare const XOPC_DB_SCHEMA_VERSION =
|
|
6
|
+
export declare const XOPC_DB_SCHEMA_VERSION = 58;
|
|
7
7
|
export declare function resolveMigrationsDir(override?: string): string;
|
|
8
8
|
/**
|
|
9
9
|
* Apply sequential SQL migrations from (currentVersion + 1) through targetVersion.
|