@xopcai/xopc 0.0.333 → 0.0.335
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser-ext/dist/assets/{auth-DocRzRlS.js → auth-Cjj5SuoT.js} +49 -39
- package/dist/browser-ext/dist/background.js +1 -1
- package/dist/browser-ext/dist/sidepanel.html +1 -1
- package/dist/browser-ext/dist/sidepanel.js +240 -36
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-DiI2O7lC.js → agent-avatar-dicebear-DtmNsTNI.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-defaults-settings-panel-CVp3J969.js → agent-defaults-settings-panel-AvGo9fao.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-plugin-dialog-CacyndrS.js → agent-plugin-dialog-DZCh4_E1.js} +1 -1
- package/dist/gateway/static/root/assets/agents-Drt1vHf6.js +70 -0
- package/dist/gateway/static/root/assets/agents-admin-api-C82B1W9Z.js +2 -0
- package/dist/gateway/static/root/assets/{app-link-C6gA5Nck.js → app-link-DRL0YnPs.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-BcszTlqr.js → app-management-settings-panel-IKZm5_s2.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-B1XPe8qz.js → appearance-settings-DKWGkrVW.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-DY6Q7TMZ.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-MjUsJcNb.js → archive-plugin-DXGAt0G7.js} +1 -1
- package/dist/gateway/static/root/assets/attachment-load-qjPpQzYY.js +1 -0
- package/dist/gateway/static/root/assets/attachment-utils-core-BIOUBrpT.js +1 -0
- package/dist/gateway/static/root/assets/{automations-page-Dsjivdxs.js → automations-page-DzqfYcqe.js} +1 -1
- package/dist/gateway/static/root/assets/automations-workspace-qMpqvBz1.js +7 -0
- package/dist/gateway/static/root/assets/binary-plugins-Cy2FLsPv.js +2 -0
- package/dist/gateway/static/root/assets/{block-editor-Bx0uXbJP.js → block-editor-BqSpSNnv.js} +29 -29
- package/dist/gateway/static/root/assets/{browser-automation-inputs-1ZIPGDeq.js → browser-automation-inputs-CLOq1KtH.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-automations-page-CCjYipHc.js → browser-automations-page-BEeyiVEw.js} +2 -2
- package/dist/gateway/static/root/assets/browser-settings-page-D6SygxnY.js +3 -0
- package/dist/gateway/static/root/assets/capabilities-BfHgt4uk.js +1 -0
- package/dist/gateway/static/root/assets/capabilities-page-C9Od0WN-.js +2 -0
- package/dist/gateway/static/root/assets/capabilities-settings-panel-6HAVkNE4.js +8 -0
- package/dist/gateway/static/root/assets/capability-header-actions-CwcT7mjE.js +1 -0
- package/dist/gateway/static/root/assets/channels-D5HNBMLS.js +1 -0
- package/dist/gateway/static/root/assets/{chat-terminal-dock-Fnum_IEm.js → chat-terminal-dock-BsxTfU1T.js} +2 -2
- package/dist/gateway/static/root/assets/{computer-settings-page-DI1zfCTA.js → computer-settings-page-CH01h8yI.js} +1 -1
- package/dist/gateway/static/root/assets/{connector-service-page-CiGDAubm.js → connector-service-page-CTi8iaOn.js} +1 -1
- package/dist/gateway/static/root/assets/connectors-page-C3GhbPPg.js +2 -0
- package/dist/gateway/static/root/assets/{turn-outcome-D0SnyZ3Z.js → constants-Co2_smKQ.js} +1 -1
- package/dist/gateway/static/root/assets/date-picker-DTEOeiC4.js +1 -0
- package/dist/gateway/static/root/assets/{dependency-picker-DpD3xaEB.js → dependency-picker-DFA0RZ02.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-CCoDxKqh.js → desktop-pet-Txr49_Zi.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-GxndKfCx.js → desktop-pet-settings-Coi0DUai.js} +1 -1
- package/dist/gateway/static/root/assets/{device-pairing-wizard-B71w3ptm.js → device-pairing-wizard-OPY8ujCN.js} +1 -1
- package/dist/gateway/static/root/assets/{directory-picker-path-field-CUzjJvjs.js → directory-picker-path-field-B1ckH4hn.js} +1 -1
- package/dist/gateway/static/root/assets/dist-CKkafhaS.js +1 -0
- package/dist/gateway/static/root/assets/dist-io9jFpN72.js +1 -0
- package/dist/gateway/static/root/assets/{extension-debug-page-BtDY8ntX.js → extension-debug-page-6e8BCEb6.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-D9_XF-XC.js → extension-page-DgaFykYf.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-CjhUFAaC.js → extension-settings-page-B-TyR9GM.js} +1 -1
- package/dist/gateway/static/root/assets/{files-BK6enEvD.js → files-Bw4SBGdM.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-swr-CgIjCxM8.js → gateway-config-swr-Hn1vj6uI.js} +1 -1
- package/dist/gateway/static/root/assets/gateway-realtime-CGjSxzj6.js +1 -0
- package/dist/gateway/static/root/assets/gateway-realtime-store-DytaaEu8.js +1 -0
- package/dist/gateway/static/root/assets/gateway-settings-CtjGyqB2.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-startup-retry-i-1lTrwY.js → gateway-startup-retry-CtTVgB7_.js} +1 -1
- package/dist/gateway/static/root/assets/home-page-Cs5fPXcJ.js +1 -0
- package/dist/gateway/static/root/assets/{image-generation-api-gilc-u7M.js → image-generation-api-DBA-bdEM.js} +1 -1
- package/dist/gateway/static/root/assets/{imports-page-BEtq5BRU.js → imports-page-C72wCY44.js} +1 -1
- package/dist/gateway/static/root/assets/index-BkSp_1Il.js +106 -0
- package/dist/gateway/static/root/assets/index-DbLEkdNg.css +1 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-JUYY_18v.js → keyboard-shortcuts-settings-D1nzw6zI.js} +1 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-DqB0hGrZ.js +1 -0
- package/dist/gateway/static/root/assets/{local-apps-page-BlYESNqz.js → local-apps-page-D4FX0Ptx.js} +1 -1
- package/dist/gateway/static/root/assets/{local-apps-Bpja8nC6.js → local-apps-yys1VChX.js} +1 -1
- package/dist/gateway/static/root/assets/local-session-drafts-Byxxogdc.js +1 -0
- package/dist/gateway/static/root/assets/{locale-store-BY30D6tg.js → locale-store-7F4l6DRV.js} +1 -1
- package/dist/gateway/static/root/assets/logs-page-CcWD_-zy.js +2 -0
- package/dist/gateway/static/root/assets/{management-settings-c4krhYU7.js → management-settings-L9YGzLaz.js} +1 -1
- package/dist/gateway/static/root/assets/{markdown-view-BEeXMfDw.js → markdown-view-bxpOryax.js} +1 -1
- package/dist/gateway/static/root/assets/media-plugins-DqsiYyAz.js +1 -0
- package/dist/gateway/static/root/assets/{messages-_6IXbP2u.js → messages-DsUnS7rn.js} +2 -2
- package/dist/gateway/static/root/assets/note-detail-panel-DwK9Ndw1.js +5 -0
- package/dist/gateway/static/root/assets/notes-page-D2FvAV9x.js +8 -0
- package/dist/gateway/static/root/assets/page-context-capture-button-CeWnFomm.js +1 -0
- package/dist/gateway/static/root/assets/{page-tabs-BhYBCqls.js → page-tabs-B90ywILw.js} +1 -1
- package/dist/gateway/static/root/assets/popover-select-0p9PIHRy.js +1 -0
- package/dist/gateway/static/root/assets/{preview-open-alternatives-CP8agNlc.js → preview-open-alternatives-CwuY-FIE.js} +1 -1
- package/dist/gateway/static/root/assets/{product-delivery-bv3z8Xkh.js → product-delivery-BAks11S4.js} +1 -1
- package/dist/gateway/static/root/assets/{product-open-page-CU7fRhfT.js → product-open-page-CUcJOCAz.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-Blo9-zcq.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-C9rh1U9Z.js +1 -0
- package/dist/gateway/static/root/assets/{registry-api-BvVx0G1o.js → registry-api-DU915Prn.js} +1 -1
- package/dist/gateway/static/root/assets/remote-access-hub-Cw2Beq7s.js +1 -0
- package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-Czvzsuj_.js → runtime-tools-settings-panel-Cj8LnZRV.js} +2 -2
- package/dist/gateway/static/root/assets/scenes-page-BZd4VZBP.js +2 -0
- package/dist/gateway/static/root/assets/{schema-form-B9Ni5O93.js → schema-form-CNbrdYAu.js} +1 -1
- package/dist/gateway/static/root/assets/{schemas-88fK3zzl.js → schemas-CObaziC7.js} +3 -3
- package/dist/gateway/static/root/assets/session-api-C7i3UFhq.js +1 -0
- package/dist/gateway/static/root/assets/session-manager-DAck_U0C.js +16 -0
- package/dist/gateway/static/root/assets/sessions-page-BKt3Cd0a.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-BToasX5M.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-jquf1P7n.js → settings-form-section-u6ZXo3oJ.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-DPomsvba.js → settings-page-gXacaOIv.js} +1 -1
- package/dist/gateway/static/root/assets/setup-status-panel-qKaz5drv.js +1 -0
- package/dist/gateway/static/root/assets/share-preview-page-DdkQ-B5M.js +2 -0
- package/dist/gateway/static/root/assets/shares-settings-BwFn5CYE.js +1 -0
- package/dist/gateway/static/root/assets/{skill-api-Bu7-3w-L.js → skill-api-Cf3_ZQOb.js} +1 -1
- package/dist/gateway/static/root/assets/skill-reload-api-CdNp1N-Y.js +1 -0
- package/dist/gateway/static/root/assets/skills-page-fKPvwSpa.js +2 -0
- package/dist/gateway/static/root/assets/{system-settings-panel-BwFR0Uci.js → system-settings-panel-CO3l1jdd.js} +1 -1
- package/dist/gateway/static/root/assets/task-detail-page-zClWGuT5.js +1 -0
- package/dist/gateway/static/root/assets/{tasks-CDR_RVbQ.js → tasks-QQJXsiER.js} +1 -1
- package/dist/gateway/static/root/assets/{tunnel-api-PfucxMP3.js → tunnel-api-Dw6DW1j5.js} +1 -1
- package/dist/gateway/static/root/assets/{usage-page-t_zdQHcy.js → usage-page-QP_8nuHU.js} +1 -1
- package/dist/gateway/static/root/assets/{use-autosave-DLyy2wHz.js → use-autosave-ZwnXUpG4.js} +1 -1
- package/dist/gateway/static/root/assets/user-model-page-B72PRFAI.js +2 -0
- package/dist/gateway/static/root/assets/{voice-api-key-field-CQDY5EBK.js → voice-api-key-field-CbIxN5SC.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-config-api-Bwy3Al3J.js → voice-config-api-LKFent6f.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-overlay-CJzqJ47I.js → work-discovery-overlay-WIGHfEL3.js} +1 -1
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-sCOk-esV.js → workflow-run-setup-panel-Bk0Jhdeq.js} +2 -2
- package/dist/gateway/static/root/assets/workflows-page-BC385JPr.js +6 -0
- package/dist/gateway/static/root/index.html +27 -21
- package/dist/package.js +1 -1
- package/dist/packages/gateway-contract/src/capabilities.js +14 -2
- package/dist/packages/gateway-contract/src/index.js +6 -2
- package/dist/packages/gateway-contract/src/session-command-rejection.js +19 -0
- package/dist/packages/gateway-contract/src/session-input-command.js +109 -0
- package/dist/packages/gateway-contract/src/sessions.js +11 -6
- package/dist/src/agent/agent-instance-gateway.d.ts +0 -2
- package/dist/src/agent/agent-manager.d.ts +0 -2
- package/dist/src/agent/agent-manager.js +5 -36
- package/dist/src/agent/background-review/run-background-review.d.ts +0 -7
- package/dist/src/agent/background-review/run-background-review.js +3 -23
- package/dist/src/agent/bootstrap/filter-bootstrap-files.js +1 -1
- package/dist/src/agent/embedded/model-runtime.js +1 -1
- package/dist/src/agent/embedded/run-for-session.js +1 -1
- package/dist/src/agent/external-tools/endpoint-provider.js +2 -2
- package/dist/src/agent/external-tools/gateway-tools.js +2 -1
- package/dist/src/agent/image/tool-model-config.js +2 -2
- package/dist/src/agent/orchestration/agent-orchestrator.js +0 -3
- package/dist/src/agent/service/direct-turn-helpers.js +0 -3
- package/dist/src/agent/service/process-direct-streaming.js +4 -2
- package/dist/src/agent/service.js +4 -4
- package/dist/src/agent/session/session-inspector.js +1 -1
- package/dist/src/agent/tasks/task-judge-service.js +3 -3
- package/dist/src/agent/tools/xopc-use-tool.js +1 -1
- package/dist/src/agent-catalog/capabilities.js +2 -2
- package/dist/src/ai-assist/text-assist.js +1 -1
- package/dist/src/auth/credentials.js +1 -1
- package/dist/src/auth/oauth-provider-lock.js +1 -1
- package/dist/src/auth/sync-provider-auth.js +1 -1
- package/dist/src/automations/capabilities/drafts.js +1 -1
- package/dist/src/automations/capabilities/write.d.ts +11 -11
- package/dist/src/automations/domain/validation.d.ts +11 -11
- package/dist/src/automations/draft/automation-draft-validator.d.ts +1 -1
- package/dist/src/automations/events/event-dispatcher.d.ts +10 -3
- package/dist/src/automations/service/automation-service.js +0 -1
- package/dist/src/bootstrap/application-state.js +1 -1
- package/dist/src/capabilities/runtime/dispatcher.js +1 -1
- package/dist/src/capabilities/runtime/product.js +1 -1
- package/dist/src/channels/attachments/voice-stt-webchat.js +1 -1
- package/dist/src/chat-commands/agent-edit.js +1 -1
- package/dist/src/chat-commands/builtins/config.js +1 -1
- package/dist/src/cli/commands/agent.js +1 -1
- package/dist/src/cli/commands/agents.js +1 -1
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/cli/commands/doctor/checks/provider-auth.js +2 -2
- package/dist/src/cli/commands/models.js +1 -1
- package/dist/src/cli/commands/onboard/model.js +2 -2
- package/dist/src/cli/utils/init-workspace-core.js +1 -1
- package/dist/src/computer/runtime.js +1 -1
- package/dist/src/config/index.js +5 -5
- package/dist/src/config/loader.js +2 -2
- package/dist/src/config/models-json.js +1 -1
- package/dist/src/config/schema.js +1 -1
- package/dist/src/connectors/cli/authorization.d.ts +1 -1
- package/dist/src/connectors/cli/store.d.ts +1 -1
- package/dist/src/connectors/connection-candidates.js +53 -15
- package/dist/src/connectors/connection-capabilities.js +5 -1
- package/dist/src/execution-environments/local-worktree-manager.js +10 -1
- package/dist/src/execution-environments/session-environment-service.d.ts +3 -0
- package/dist/src/execution-environments/session-environment-service.js +28 -4
- package/dist/src/extensions/agent-plugins/validation.js +1 -1
- package/dist/src/gateway/agents-admin.js +2 -2
- package/dist/src/gateway/file-path-classifier.js +1 -1
- package/dist/src/gateway/hono/lib/config-payload.js +1 -1
- package/dist/src/gateway/hono/routes/agent-stream.js +6 -2
- package/dist/src/gateway/hono/routes/browser-session.js +4 -2
- package/dist/src/gateway/hono/routes/commands-skills.js +9 -2
- package/dist/src/gateway/hono/routes/config-patch/misc.js +2 -2
- package/dist/src/gateway/hono/routes/files.js +3 -0
- package/dist/src/gateway/hono/routes/models.js +17 -1
- package/dist/src/gateway/hono/routes/notes.js +2 -4
- package/dist/src/gateway/hono/routes/projects.js +2 -2
- package/dist/src/gateway/hono/routes/session-command-handler.d.ts +5 -0
- package/dist/src/gateway/hono/routes/session-command-handler.js +189 -0
- package/dist/src/gateway/hono/routes/session-input-handler.d.ts +14 -2
- package/dist/src/gateway/hono/routes/session-input-handler.js +2 -2
- package/dist/src/gateway/hono/routes/sessions.js +15 -169
- package/dist/src/gateway/hono/routes/tasks.js +1 -1
- package/dist/src/gateway/hono/routes/tui.js +2 -1
- package/dist/src/gateway/hono/routes/voice.js +9 -0
- package/dist/src/gateway/image-generation-setup.js +2 -2
- package/dist/src/gateway/lock.js +1 -1
- package/dist/src/gateway/resolve-webchat-session-key.d.ts +1 -1
- package/dist/src/gateway/resolve-webchat-session-key.js +2 -2
- package/dist/src/gateway/service/run-gateway-agent.js +1 -1
- package/dist/src/gateway/service/session-command-service.d.ts +34 -0
- package/dist/src/gateway/service/session-command-service.js +81 -0
- package/dist/src/gateway/service/session-input-coordinator.d.ts +21 -0
- package/dist/src/gateway/service/session-input-coordinator.js +41 -0
- package/dist/src/gateway/service/session-preparation-worker.d.ts +22 -0
- package/dist/src/gateway/service/session-preparation-worker.js +125 -0
- package/dist/src/gateway/service.d.ts +24 -0
- package/dist/src/gateway/service.js +29 -16
- package/dist/src/gateway/side-chat/promotion-service.js +0 -1
- package/dist/src/gateway/xopc-cloud-capability-setup.js +1 -1
- package/dist/src/home-intelligence/generator.d.ts +8 -1
- package/dist/src/home-intelligence/generator.js +26 -15
- package/dist/src/home-intelligence/host.d.ts +8 -1
- package/dist/src/home-intelligence/host.js +82 -8
- package/dist/src/home-intelligence/repository.d.ts +5 -1
- package/dist/src/home-intelligence/repository.js +16 -9
- package/dist/src/home-intelligence/snapshot.js +4 -4
- package/dist/src/local-apps/service.js +1 -1
- package/dist/src/mcp/channel-bridge.js +12 -2
- package/dist/src/notes/capabilities/read.js +2 -2
- package/dist/src/notes/service.d.ts +4 -1
- package/dist/src/notes/service.js +11 -8
- package/dist/src/providers/auth-runtime/resolve-auth.js +1 -1
- package/dist/src/providers/index.js +2 -2
- package/dist/src/providers/model-catalog-persistence.js +1 -1
- package/dist/src/providers/register-runtime-providers.js +1 -1
- package/dist/src/session/store.js +0 -1
- package/dist/src/storage/sqlite/ai-usage-repository.d.ts +3 -0
- package/dist/src/storage/sqlite/ai-usage-repository.js +25 -1
- package/dist/src/storage/sqlite/migrations/223_session_creation_receipts.sql +59 -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/schema.js +1 -1
- package/dist/src/storage/sqlite/session-creation-repository.d.ts +50 -0
- package/dist/src/storage/sqlite/session-creation-repository.js +166 -0
- package/dist/src/storage/sqlite/session-input-repository.d.ts +4 -2
- package/dist/src/storage/sqlite/session-input-repository.js +7 -1
- package/dist/src/tasks/capabilities/read.js +2 -2
- package/dist/src/tui/backends/embedded-backend.d.ts +5 -0
- package/dist/src/tui/backends/embedded-backend.js +266 -20
- package/dist/src/tui/backends/embedded-drafts.d.ts +22 -0
- package/dist/src/tui/backends/embedded-drafts.js +53 -0
- package/dist/src/tui/backends/gateway-realtime-backend.d.ts +10 -0
- package/dist/src/tui/backends/gateway-realtime-backend.js +214 -33
- package/dist/src/tui/tui-backend.d.ts +1 -1
- package/dist/src/tui/tui-chat-input-state.d.ts +1 -0
- package/dist/src/tui/tui-commands.js +1 -1
- package/dist/src/tui/tui-session-format.js +0 -1
- package/dist/src/tui/tui-startup-resources.d.ts +1 -0
- package/dist/src/tui/tui-startup-resources.js +2 -2
- package/dist/src/tui/tui-types.d.ts +0 -1
- package/dist/src/tui/tui.js +69 -29
- package/dist/src/voice/realtime/persona-context.js +1 -1
- package/dist/src/work-discovery/service.js +3 -6
- package/dist/src/workflows/service/workflow-run-service.js +1 -1
- package/package.json +5 -5
- package/dist/gateway/static/root/assets/agents-DXYZSuUV.js +0 -70
- package/dist/gateway/static/root/assets/apps-page-ZqANbUZv.js +0 -1
- package/dist/gateway/static/root/assets/attachment-load-DHa-BI9a.js +0 -1
- package/dist/gateway/static/root/assets/automations-workspace-B37vs5tk.js +0 -7
- package/dist/gateway/static/root/assets/binary-plugins-DQYcuBHP.js +0 -2
- package/dist/gateway/static/root/assets/browser-settings-page-CSv4rvmx.js +0 -3
- package/dist/gateway/static/root/assets/capabilities-BnO9LV7U.js +0 -1
- package/dist/gateway/static/root/assets/capabilities-page-BfvDvIY1.js +0 -2
- package/dist/gateway/static/root/assets/capabilities-settings-panel-CoW7-ESq.js +0 -8
- package/dist/gateway/static/root/assets/capability-header-actions-D_hbWRRF.js +0 -1
- package/dist/gateway/static/root/assets/channels-BhMaRh1x.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-Ono0Pha1.js +0 -2
- package/dist/gateway/static/root/assets/conversation-identity-Cw0n9uzK.js +0 -1
- package/dist/gateway/static/root/assets/date-picker-D-JhzZyW.js +0 -1
- package/dist/gateway/static/root/assets/dist-3h6cXXhT.js +0 -1
- package/dist/gateway/static/root/assets/dist-Che_jiQF.js +0 -1
- package/dist/gateway/static/root/assets/gateway-settings-BWaCnwT1.js +0 -1
- package/dist/gateway/static/root/assets/home-page-BTjGLngn.js +0 -1
- package/dist/gateway/static/root/assets/index-DHL16aYZ.js +0 -121
- package/dist/gateway/static/root/assets/index-N1e6PDwx.css +0 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-uI7mtoVz.js +0 -1
- package/dist/gateway/static/root/assets/logs-page-BbLQreeN.js +0 -2
- package/dist/gateway/static/root/assets/media-plugins-DEFN1I73.js +0 -1
- package/dist/gateway/static/root/assets/note-detail-panel--09xGxyE.js +0 -5
- package/dist/gateway/static/root/assets/notes-page-DsxcVBXF.js +0 -8
- package/dist/gateway/static/root/assets/page-context-capture-button-D43aVpCj.js +0 -1
- package/dist/gateway/static/root/assets/popover-select-DcsFzD_i.js +0 -1
- package/dist/gateway/static/root/assets/project-detail-page-U-EdDfAW.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-DUOKZLt7.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-fVPQe5YS.js +0 -1
- package/dist/gateway/static/root/assets/scenes-page-C0-WHOY3.js +0 -2
- package/dist/gateway/static/root/assets/sessions-page-DdXvW09N.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-BtF83fBY.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-BvVlqpHf.js +0 -1
- package/dist/gateway/static/root/assets/share-preview-page-b9DI0N1J.js +0 -2
- package/dist/gateway/static/root/assets/shares-settings-R_qwc4DN.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-CNJAQ_e-.js +0 -1
- package/dist/gateway/static/root/assets/skills-page-D7XPEQu_.js +0 -2
- package/dist/gateway/static/root/assets/task-detail-page-PFjGW2g1.js +0 -1
- package/dist/gateway/static/root/assets/user-model-page-OyfPVfB9.js +0 -2
- package/dist/gateway/static/root/assets/workflows-page-DYBGjN7C.js +0 -6
- package/dist/src/tui/tui-empty-session-cleanup.d.ts +0 -9
- package/dist/src/tui/tui-empty-session-cleanup.js +0 -19
- /package/dist/gateway/static/root/assets/{dist-CI_fqRk-.js → dist-CI_fqRk-2.js} +0 -0
|
@@ -5,10 +5,10 @@ import { currentOperationId, init_operation_context } from "../infra/operation-c
|
|
|
5
5
|
import { afterSqliteCommit, init_transaction, runSqliteWriteTransaction } from "../storage/sqlite/transaction.js";
|
|
6
6
|
import { ExtensionCapabilityBindingsSchema, extensionCapabilityPermissions } from "../../packages/gateway-contract/src/extension-capabilities.js";
|
|
7
7
|
import { init_src } from "../../packages/gateway-contract/src/index.js";
|
|
8
|
+
import { CapabilityError } from "../capabilities/runtime/errors.js";
|
|
8
9
|
import { init_paths, resolveExtensionsDir } from "../config/paths.js";
|
|
9
10
|
import { LocalAppStore } from "./store.js";
|
|
10
11
|
import { slugifyProjectName } from "../projects/project-store.js";
|
|
11
|
-
import { CapabilityError } from "../capabilities/runtime/errors.js";
|
|
12
12
|
import { DomainOutboxDispatcher } from "../infra/domain-outbox-dispatcher.js";
|
|
13
13
|
import { validateLocalAppCapabilityContracts } from "./capabilities/contracts.js";
|
|
14
14
|
import { buildLocalAppFixGuidance } from "./fix-guidance.js";
|
|
@@ -144,10 +144,20 @@ var XopcChannelBridge = class {
|
|
|
144
144
|
return null;
|
|
145
145
|
}
|
|
146
146
|
async sendMessage(params) {
|
|
147
|
-
|
|
147
|
+
const client = this.client;
|
|
148
|
+
const path = `/api/sessions/${encodeURIComponent(params.conversationId)}`;
|
|
149
|
+
const [detail, config] = await Promise.all([client.getJson(path), client.getJson(`${path}/agent-config`)]);
|
|
150
|
+
return client.postJson(`/api/sessions/${encodeURIComponent(params.conversationId)}/inputs`, {
|
|
151
|
+
kind: "append",
|
|
148
152
|
clientMessageId: crypto.randomUUID(),
|
|
153
|
+
expectedTranscriptId: detail.session.transcriptId,
|
|
154
|
+
configVersion: config.configVersion,
|
|
149
155
|
delivery: "next",
|
|
150
|
-
content: params.text
|
|
156
|
+
input: { content: params.text },
|
|
157
|
+
origin: {
|
|
158
|
+
type: "system",
|
|
159
|
+
source: "cli"
|
|
160
|
+
}
|
|
151
161
|
});
|
|
152
162
|
}
|
|
153
163
|
listPendingApprovals() {
|
|
@@ -20,8 +20,8 @@ function registerNoteReadCapabilities(dispatcher, getNotes) {
|
|
|
20
20
|
id: "xopc.notes.preview_edit",
|
|
21
21
|
description: "Build a local edit suggestion without modifying the note or calling a model.",
|
|
22
22
|
...ProductReadContracts["xopc.notes.preview_edit"],
|
|
23
|
-
async execute({ id, instruction, markdown }) {
|
|
24
|
-
const result = await getNotes().createAiEditPatch(id, instruction, markdown);
|
|
23
|
+
async execute({ id, instruction, markdown, context }) {
|
|
24
|
+
const result = await getNotes().createAiEditPatch(id, instruction, markdown, context?.range);
|
|
25
25
|
if (!result) throw new CapabilityError("NOT_FOUND", "Note not found");
|
|
26
26
|
return ProductReadContracts["xopc.notes.preview_edit"].output.parse(result);
|
|
27
27
|
}
|
|
@@ -23,7 +23,10 @@ export declare class NotesService {
|
|
|
23
23
|
note: Note | null;
|
|
24
24
|
conflict: boolean;
|
|
25
25
|
}>;
|
|
26
|
-
createAiEditPatch(id: string, instruction: string, markdownOverride?: string
|
|
26
|
+
createAiEditPatch(id: string, instruction: string, markdownOverride?: string, requestedRange?: {
|
|
27
|
+
start: number;
|
|
28
|
+
end: number;
|
|
29
|
+
}): Promise<{
|
|
27
30
|
message: string;
|
|
28
31
|
patch: NoteAiPatch;
|
|
29
32
|
} | null>;
|
|
@@ -7,8 +7,8 @@ import { init_note_markdown, parseNoteMarkdown } from "./note-markdown.js";
|
|
|
7
7
|
import { init_notes_repository, listNoteProjectSummaries } from "../storage/sqlite/notes-repository.js";
|
|
8
8
|
import { changedFieldsFromPatch, emitActivity, previewText, systemActivityActor, systemActivitySource } from "../activity/emitter.js";
|
|
9
9
|
import { getDefaultModelSync, init_providers, resolveModel } from "../providers/index.js";
|
|
10
|
-
import { DomainOutboxDispatcher } from "../infra/domain-outbox-dispatcher.js";
|
|
11
10
|
import { completeWithResolvedCredentials } from "../providers/model-call.js";
|
|
11
|
+
import { DomainOutboxDispatcher } from "../infra/domain-outbox-dispatcher.js";
|
|
12
12
|
import { partitionAttachmentsByReference } from "./note-attachment-sync.js";
|
|
13
13
|
import { buildNoteAgentContextArtifact, getCachedNoteAgentContextArtifact } from "./agent-context.js";
|
|
14
14
|
import { revokeNoteShareRecords } from "../share/note-share-revocation.js";
|
|
@@ -333,19 +333,22 @@ var NotesService = class {
|
|
|
333
333
|
throw error;
|
|
334
334
|
}
|
|
335
335
|
}
|
|
336
|
-
async createAiEditPatch(id, instruction, markdownOverride) {
|
|
336
|
+
async createAiEditPatch(id, instruction, markdownOverride, requestedRange) {
|
|
337
337
|
const note = await this.store.getNote(id);
|
|
338
338
|
if (!note) return null;
|
|
339
339
|
const source = markdownOverride ?? note.markdown;
|
|
340
|
-
const
|
|
340
|
+
const start = Math.max(0, Math.min(source.length, requestedRange?.start ?? 0));
|
|
341
|
+
const end = Math.max(start, Math.min(source.length, requestedRange?.end ?? source.length));
|
|
342
|
+
const target = source.slice(start, end);
|
|
343
|
+
const parsed = parseNoteMarkdown(target, id);
|
|
341
344
|
const wantsTodos = /待办|todo|task|行动|提醒/i.test(instruction);
|
|
342
345
|
const wantsSummary = /摘要|总结|summary|压缩/i.test(instruction);
|
|
343
346
|
let generated = "";
|
|
344
347
|
if (wantsTodos) {
|
|
345
|
-
const lines =
|
|
348
|
+
const lines = target.split(/\n|。|;|;/).map((line) => line.trim()).filter(Boolean);
|
|
346
349
|
generated = (lines.length ? lines : [parsed.plainText]).slice(0, 12).map((line) => `- [ ] ${line.replace(/^[-*\d.\s\[\]x]+/i, "").trim()}`).join("\n");
|
|
347
350
|
} else if (wantsSummary) generated = `> [!SUMMARY]\n> ${parsed.plainText.slice(0, 220)}`;
|
|
348
|
-
else generated = `${
|
|
351
|
+
else generated = `${target.trimEnd()}\n\n## AI 整理\n\n${instruction.trim()}`;
|
|
349
352
|
return {
|
|
350
353
|
message: "AI edit patch generated",
|
|
351
354
|
patch: {
|
|
@@ -353,9 +356,9 @@ var NotesService = class {
|
|
|
353
356
|
summary: instruction,
|
|
354
357
|
operations: [{
|
|
355
358
|
type: "replaceRange",
|
|
356
|
-
from:
|
|
357
|
-
to:
|
|
358
|
-
markdown: generated ||
|
|
359
|
+
from: start,
|
|
360
|
+
to: end,
|
|
361
|
+
markdown: generated || target
|
|
359
362
|
}]
|
|
360
363
|
}
|
|
361
364
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { init_sync_provider_auth, resolveProviderApiKeyForAgentSync } from "../../auth/sync-provider-auth.js";
|
|
2
1
|
import { getApiKeyFromEnv, init_env_keys } from "../env-keys.js";
|
|
2
|
+
import { init_sync_provider_auth, resolveProviderApiKeyForAgentSync } from "../../auth/sync-provider-auth.js";
|
|
3
3
|
import { getDefaultAuthProfileStore } from "./auth-profile-store.js";
|
|
4
4
|
//#region src/providers/auth-runtime/resolve-auth.ts
|
|
5
5
|
init_env_keys();
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { __esmMin, __exportAll } from "../../_virtual/_rolldown/runtime.js";
|
|
2
2
|
import { getAgentDefaultModelRef, init_schema } from "../config/schema.js";
|
|
3
|
-
import { getModelOAuthProviderIds, init_registry } from "../auth/oauth/registry.js";
|
|
4
|
-
import { hasProviderAuthOnDiskSync, init_sync_provider_auth } from "../auth/sync-provider-auth.js";
|
|
5
3
|
import { PROVIDER_ENV_MAP, getApiKeyFromEnv, init_env_keys } from "./env-keys.js";
|
|
6
4
|
import { init_model_ref, splitProviderModelRef } from "./model-ref.js";
|
|
7
5
|
import { ModelRegistry, getModelRegistry, init_model_registry, prewarmModelRegistry, resetModelRegistry } from "./model-registry.js";
|
|
6
|
+
import { getModelOAuthProviderIds, init_registry } from "../auth/oauth/registry.js";
|
|
8
7
|
import { CredentialResolver, hasCredentials, init_credentials } from "../auth/credentials.js";
|
|
8
|
+
import { hasProviderAuthOnDiskSync, init_sync_provider_auth } from "../auth/sync-provider-auth.js";
|
|
9
9
|
import { EXTENSION_PROVIDER_BASE_URL, init_constants } from "./constants.js";
|
|
10
10
|
import { applyOfficialModelMetadataCorrections, getSupplementalModels, init_model_supplements } from "./model-supplements.js";
|
|
11
11
|
import { getProviderRegistry, init_plugin_registry } from "./plugin-registry.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { __esmMin } from "../../_virtual/_rolldown/runtime.js";
|
|
2
2
|
import { init_paths_state, resolveXopcCloudCatalogCachePath } from "../config/paths-state.js";
|
|
3
|
-
import { ComputerProfileSchema, init_src } from "../../packages/computer-control-contract/src/index.js";
|
|
4
3
|
import { init_write_file_atomic, writeTextAtomic } from "../infra/write-file-atomic.js";
|
|
4
|
+
import { ComputerProfileSchema, init_src } from "../../packages/computer-control-contract/src/index.js";
|
|
5
5
|
import { voiceManifestSchema } from "../../packages/realtime-protocol/src/voice-catalog.js";
|
|
6
6
|
import { init_voice } from "../../packages/realtime-protocol/src/voice.js";
|
|
7
7
|
import { readFileSync, rmSync } from "node:fs";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { __esmMin } from "../../_virtual/_rolldown/runtime.js";
|
|
2
|
-
import { getOAuthProviderDefinition, init_registry } from "../auth/oauth/registry.js";
|
|
3
2
|
import { getModelCatalogStore, init_model_catalog_store } from "./model-catalog-store.js";
|
|
3
|
+
import { getOAuthProviderDefinition, init_registry } from "../auth/oauth/registry.js";
|
|
4
4
|
import { XOPC_CLOUD_PROVIDER_ID, init_xopc_cloud_config, resolveXopcModelRouterUrl } from "./xopc-cloud-config.js";
|
|
5
5
|
//#region src/providers/register-runtime-providers.ts
|
|
6
6
|
function registerRuntimeProvider(modelRuntime, source) {
|
|
@@ -794,7 +794,6 @@ var SessionStore = class {
|
|
|
794
794
|
customData: {
|
|
795
795
|
...sourceMetadata.customData ?? {},
|
|
796
796
|
...options.targetMetadata.customData ?? {},
|
|
797
|
-
genericNewChatShell: false,
|
|
798
797
|
forkedFromConversationId: sourceKey,
|
|
799
798
|
forkedFromTranscriptId: sourceMetadata.transcriptId,
|
|
800
799
|
forkedFromSessionName: sourceMetadata.name,
|
|
@@ -29,6 +29,9 @@ export type AiUsageTotals = {
|
|
|
29
29
|
knownCostUsd: string;
|
|
30
30
|
costCompleteness: 'complete' | 'partial' | 'unknown';
|
|
31
31
|
};
|
|
32
|
+
export type ConversationAiUsageTotals = Pick<AiUsageTotals, 'calls' | 'unknownCostCalls' | 'totalTokens' | 'knownCostUsd' | 'costCompleteness'>;
|
|
33
|
+
/** Aggregate all retained AI usage records for the requested conversations. */
|
|
34
|
+
export declare function summarizeAiUsageByConversations(conversationIds: readonly string[]): Map<string, ConversationAiUsageTotals>;
|
|
32
35
|
export declare function summarizeAiUsage(query: AiUsageQuery): {
|
|
33
36
|
totals: AiUsageTotals;
|
|
34
37
|
byCategory: Array<{
|
|
@@ -94,6 +94,30 @@ const TOTALS_SQL = `COUNT(*) AS calls,
|
|
|
94
94
|
COALESCE(SUM(cache_write_tokens), 0) AS cache_write_tokens,
|
|
95
95
|
COALESCE(SUM(total_tokens), 0) AS total_tokens,
|
|
96
96
|
COALESCE(SUM(estimated_cost_microusd), 0) AS known_cost_microusd`;
|
|
97
|
+
/** Aggregate all retained AI usage records for the requested conversations. */
|
|
98
|
+
function summarizeAiUsageByConversations(conversationIds) {
|
|
99
|
+
const uniqueIds = [...new Set(conversationIds.filter(Boolean))];
|
|
100
|
+
const result = /* @__PURE__ */ new Map();
|
|
101
|
+
const db = getSqliteDatabase();
|
|
102
|
+
for (let offset = 0; offset < uniqueIds.length; offset += 500) {
|
|
103
|
+
const batch = uniqueIds.slice(offset, offset + 500);
|
|
104
|
+
const rows = db.prepare(`SELECT conversation_id, ${TOTALS_SQL}
|
|
105
|
+
FROM ai_usage_events
|
|
106
|
+
WHERE conversation_id IN (${batch.map(() => "?").join(", ")})
|
|
107
|
+
GROUP BY conversation_id`).all(...batch);
|
|
108
|
+
for (const row of rows) {
|
|
109
|
+
const totals = totalsFromRow(row);
|
|
110
|
+
result.set(String(row.conversation_id), {
|
|
111
|
+
calls: totals.calls,
|
|
112
|
+
unknownCostCalls: totals.unknownCostCalls,
|
|
113
|
+
totalTokens: totals.totalTokens,
|
|
114
|
+
knownCostUsd: totals.knownCostUsd,
|
|
115
|
+
costCompleteness: totals.costCompleteness
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return result;
|
|
120
|
+
}
|
|
97
121
|
function summarizeAiUsage(query) {
|
|
98
122
|
const { sql, values } = queryWhere(query);
|
|
99
123
|
const db = getSqliteDatabase();
|
|
@@ -172,4 +196,4 @@ function listAiUsageTrace(traceId) {
|
|
|
172
196
|
ORDER BY started_at ASC, id ASC`).all(traceId).map(eventFromRow);
|
|
173
197
|
}
|
|
174
198
|
//#endregion
|
|
175
|
-
export { AI_USAGE_RETENTION_MS, finishAiUsageEvent, getAiUsageEvent, getAiUsageEventView, insertAiUsageEvent, listAiUsageEvents, listAiUsageTrace, markStaleAiUsageEventsUnknown, pruneAiUsageEvents, summarizeAiUsage };
|
|
199
|
+
export { AI_USAGE_RETENTION_MS, finishAiUsageEvent, getAiUsageEvent, getAiUsageEventView, insertAiUsageEvent, listAiUsageEvents, listAiUsageTrace, markStaleAiUsageEventsUnknown, pruneAiUsageEvents, summarizeAiUsage, summarizeAiUsageByConversations };
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
UPDATE sessions SET custom_data_json=json_remove(custom_data_json, '$.genericNewChatShell')
|
|
2
|
+
WHERE json_type(custom_data_json, '$.genericNewChatShell') IS NOT NULL;
|
|
3
|
+
|
|
4
|
+
CREATE TABLE session_input_receipts (
|
|
5
|
+
conversation_id TEXT NOT NULL,
|
|
6
|
+
client_message_id TEXT NOT NULL,
|
|
7
|
+
principal_id TEXT NOT NULL,
|
|
8
|
+
request_hash TEXT NOT NULL,
|
|
9
|
+
input_id TEXT,
|
|
10
|
+
transcript_id TEXT NOT NULL,
|
|
11
|
+
accepted_at INTEGER NOT NULL,
|
|
12
|
+
PRIMARY KEY (conversation_id, client_message_id)
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
CREATE TABLE session_tombstones (
|
|
16
|
+
conversation_id TEXT PRIMARY KEY,
|
|
17
|
+
deleted_at INTEGER NOT NULL
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
CREATE TABLE session_preparation_retries (
|
|
21
|
+
conversation_id TEXT NOT NULL,
|
|
22
|
+
idempotency_key TEXT NOT NULL,
|
|
23
|
+
operation_id TEXT NOT NULL,
|
|
24
|
+
expected_revision INTEGER NOT NULL,
|
|
25
|
+
principal_id TEXT NOT NULL,
|
|
26
|
+
PRIMARY KEY (conversation_id, idempotency_key)
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
CREATE TABLE session_preparations (
|
|
30
|
+
conversation_id TEXT PRIMARY KEY REFERENCES sessions(conversation_id) ON DELETE CASCADE,
|
|
31
|
+
operation_id TEXT NOT NULL UNIQUE,
|
|
32
|
+
creation_json TEXT NOT NULL CHECK(json_valid(creation_json)),
|
|
33
|
+
state TEXT NOT NULL CHECK(state IN ('preparing', 'ready', 'preparation_failed')),
|
|
34
|
+
environment_id TEXT NOT NULL,
|
|
35
|
+
base_commit TEXT,
|
|
36
|
+
revision INTEGER NOT NULL DEFAULT 1,
|
|
37
|
+
lease_until INTEGER NOT NULL DEFAULT 0,
|
|
38
|
+
last_error TEXT,
|
|
39
|
+
created_at INTEGER NOT NULL,
|
|
40
|
+
updated_at INTEGER NOT NULL
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
CREATE TABLE session_preparation_cleanup (
|
|
44
|
+
environment_id TEXT PRIMARY KEY,
|
|
45
|
+
conversation_id TEXT NOT NULL,
|
|
46
|
+
not_before INTEGER NOT NULL,
|
|
47
|
+
last_error TEXT
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
CREATE TRIGGER session_creation_tombstone BEFORE DELETE ON sessions BEGIN
|
|
51
|
+
INSERT INTO session_tombstones(conversation_id, deleted_at)
|
|
52
|
+
VALUES (OLD.conversation_id, CAST(unixepoch('subsec') * 1000 AS INTEGER))
|
|
53
|
+
ON CONFLICT(conversation_id) DO NOTHING;
|
|
54
|
+
INSERT INTO session_preparation_cleanup(environment_id, conversation_id, not_before)
|
|
55
|
+
SELECT environment_id, conversation_id, max(lease_until, CAST(unixepoch('subsec') * 1000 AS INTEGER)) + 5000
|
|
56
|
+
FROM session_preparations WHERE conversation_id=OLD.conversation_id
|
|
57
|
+
AND json_extract(creation_json, '$.execution.mode')='managed_worktree'
|
|
58
|
+
ON CONFLICT(environment_id) DO NOTHING;
|
|
59
|
+
END;
|
|
@@ -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 = 165;
|
|
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 = 223;
|
|
7
7
|
export declare function resolveMigrationsDir(override?: string): string;
|
|
8
8
|
/**
|
|
9
9
|
* Apply sequential SQL migrations from (currentVersion + 1) through targetVersion.
|
|
@@ -57,7 +57,7 @@ function applySingleMigration(db, migration, discardOldScenes = false) {
|
|
|
57
57
|
*/
|
|
58
58
|
function applyPendingMigrations(db, options = {}) {
|
|
59
59
|
db.function("xopc_operation_id", () => currentOperationId() ?? null);
|
|
60
|
-
const targetVersion = options.targetVersion ??
|
|
60
|
+
const targetVersion = options.targetVersion ?? 223;
|
|
61
61
|
let currentVersion = readSchemaVersion(db);
|
|
62
62
|
if (currentVersion > targetVersion) throw new DatabaseSchemaTooNewError(currentVersion, targetVersion);
|
|
63
63
|
if (!options.migrationsDir && currentVersion < 165) throw new DatabaseSchemaTooOldError(currentVersion, 165);
|
|
@@ -95,7 +95,7 @@ function applyPendingMigrations(db, options = {}) {
|
|
|
95
95
|
}
|
|
96
96
|
/** Inspect schema version without mutating the database. */
|
|
97
97
|
function inspectSchemaMigrationStatus(db, options = {}) {
|
|
98
|
-
const appVersion = options.targetVersion ??
|
|
98
|
+
const appVersion = options.targetVersion ?? 223;
|
|
99
99
|
const dbVersion = readSchemaVersion(db);
|
|
100
100
|
if (dbVersion > appVersion) return {
|
|
101
101
|
dbVersion,
|
|
@@ -137,7 +137,7 @@ var init_runner = __esmMin((() => {
|
|
|
137
137
|
init_errors();
|
|
138
138
|
log = createLogger("Sqlite:Migrations");
|
|
139
139
|
XOPC_DB_BASELINE_SCHEMA_VERSION = 165;
|
|
140
|
-
XOPC_DB_SCHEMA_VERSION =
|
|
140
|
+
XOPC_DB_SCHEMA_VERSION = 223;
|
|
141
141
|
}));
|
|
142
142
|
//#endregion
|
|
143
143
|
init_runner();
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { type SessionCreation, type SessionInputCommand, type SessionMaterializeCommand, type SessionPreparationState } from '@xopcai/gateway-contract';
|
|
2
|
+
import type { SessionAgentConfig } from '../../session/config-types.js';
|
|
3
|
+
import { insertSessionInput } from './session-input-repository.js';
|
|
4
|
+
export declare class SessionCommandError extends Error {
|
|
5
|
+
readonly code: 'IDEMPOTENCY_CONFLICT' | 'CONVERSATION_EXISTS' | 'SESSION_DELETED' | 'FORBIDDEN' | 'SESSION_CHANGED' | 'CONFIG_CHANGED' | 'NOT_FOUND' | 'BAD_REQUEST' | 'SESSION_BUSY' | 'QUEUE_FULL';
|
|
6
|
+
constructor(code: 'IDEMPOTENCY_CONFLICT' | 'CONVERSATION_EXISTS' | 'SESSION_DELETED' | 'FORBIDDEN' | 'SESSION_CHANGED' | 'CONFIG_CHANGED' | 'NOT_FOUND' | 'BAD_REQUEST' | 'SESSION_BUSY' | 'QUEUE_FULL', message: string);
|
|
7
|
+
}
|
|
8
|
+
export type SessionInputReceipt = {
|
|
9
|
+
conversationId: string;
|
|
10
|
+
clientMessageId: string;
|
|
11
|
+
principalId: string;
|
|
12
|
+
requestHash: string;
|
|
13
|
+
inputId: string | null;
|
|
14
|
+
transcriptId: string;
|
|
15
|
+
acceptedAt: number;
|
|
16
|
+
};
|
|
17
|
+
export type SessionPreparation = {
|
|
18
|
+
conversationId: string;
|
|
19
|
+
operationId: string;
|
|
20
|
+
creation: SessionCreation;
|
|
21
|
+
state: SessionPreparationState;
|
|
22
|
+
environmentId: string;
|
|
23
|
+
baseCommit: string | null;
|
|
24
|
+
revision: number;
|
|
25
|
+
leaseUntil: number;
|
|
26
|
+
lastError: string | null;
|
|
27
|
+
};
|
|
28
|
+
export declare function sessionCommandHash(command: SessionInputCommand | SessionMaterializeCommand): string;
|
|
29
|
+
export declare function isConversationDeleted(conversationId: string): boolean;
|
|
30
|
+
export declare function getSessionInputReceipt(conversationId: string, clientMessageId: string, principalId: string): SessionInputReceipt | undefined;
|
|
31
|
+
export declare function matchSessionInputReceipt(conversationId: string, clientMessageId: string, principalId: string, hash: string): SessionInputReceipt | undefined;
|
|
32
|
+
export declare function getSessionPreparation(conversationId: string): SessionPreparation | undefined;
|
|
33
|
+
/** Commit the identity, configuration, input and replay receipt together. All preparation happens before entry. */
|
|
34
|
+
export declare function acceptSessionCommand(input: {
|
|
35
|
+
conversationId: string;
|
|
36
|
+
principalId: string;
|
|
37
|
+
command: SessionInputCommand | SessionMaterializeCommand;
|
|
38
|
+
preparedInput?: Omit<Parameters<typeof insertSessionInput>[0], 'conversationId' | 'id' | 'clientMessageId' | 'expectedTranscriptId'>;
|
|
39
|
+
config?: SessionAgentConfig;
|
|
40
|
+
sourceChannel?: 'webchat' | 'tui';
|
|
41
|
+
attachProject?: (conversationId: string, projectId: string) => void;
|
|
42
|
+
}): SessionInputReceipt;
|
|
43
|
+
export declare function claimSessionPreparation(conversationId: string, now?: number): SessionPreparation | undefined;
|
|
44
|
+
export declare function finishSessionPreparation(operation: SessionPreparation, error?: string): boolean;
|
|
45
|
+
export declare function pendingSessionPreparations(): string[];
|
|
46
|
+
export declare function retrySessionPreparation(conversationId: string, principalId: string, input: {
|
|
47
|
+
operationId: string;
|
|
48
|
+
expectedRevision: number;
|
|
49
|
+
idempotencyKey: string;
|
|
50
|
+
}): SessionPreparation;
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { getSqliteDatabase, init_transaction, runSqliteWriteTransaction } from "./transaction.js";
|
|
2
|
+
import { sessionCommandIdentity } from "../../../packages/gateway-contract/src/session-input-command.js";
|
|
3
|
+
import { init_src } from "../../../packages/gateway-contract/src/index.js";
|
|
4
|
+
import { init_session_input_repository, insertSessionInput } from "./session-input-repository.js";
|
|
5
|
+
import { init_clarification_wait_repository, supersedeActiveClarification } from "./clarification-wait-repository.js";
|
|
6
|
+
import { init_connection_wait_repository, invalidateConnectionResumeIntent } from "./connection-wait-repository.js";
|
|
7
|
+
import { getSessionMetadata } from "./session-read-repository.js";
|
|
8
|
+
import { init_session_repository } from "./session-repository.js";
|
|
9
|
+
import { init_config_repository, setSessionConfig } from "./config-repository.js";
|
|
10
|
+
import { createConversation, init_conversation_repository } from "./conversation-repository.js";
|
|
11
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
12
|
+
//#region src/storage/sqlite/session-creation-repository.ts
|
|
13
|
+
init_src();
|
|
14
|
+
init_conversation_repository();
|
|
15
|
+
init_config_repository();
|
|
16
|
+
init_session_repository();
|
|
17
|
+
init_session_input_repository();
|
|
18
|
+
init_connection_wait_repository();
|
|
19
|
+
init_clarification_wait_repository();
|
|
20
|
+
init_transaction();
|
|
21
|
+
var SessionCommandError = class extends Error {
|
|
22
|
+
constructor(code, message) {
|
|
23
|
+
super(message);
|
|
24
|
+
this.code = code;
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
function sessionCommandHash(command) {
|
|
28
|
+
return createHash("sha256").update(sessionCommandIdentity(command)).digest("hex");
|
|
29
|
+
}
|
|
30
|
+
function isConversationDeleted(conversationId) {
|
|
31
|
+
return Boolean(getSqliteDatabase().prepare("SELECT 1 FROM session_tombstones WHERE conversation_id=?").get(conversationId));
|
|
32
|
+
}
|
|
33
|
+
function getSessionInputReceipt(conversationId, clientMessageId, principalId) {
|
|
34
|
+
const row = getSqliteDatabase().prepare(`SELECT conversation_id AS conversationId, client_message_id AS clientMessageId,
|
|
35
|
+
principal_id AS principalId, request_hash AS requestHash, input_id AS inputId,
|
|
36
|
+
transcript_id AS transcriptId, accepted_at AS acceptedAt FROM session_input_receipts
|
|
37
|
+
WHERE conversation_id=? AND client_message_id=?`).get(conversationId, clientMessageId);
|
|
38
|
+
if (row && row.principalId !== principalId) throw new SessionCommandError("FORBIDDEN", "Input belongs to another principal");
|
|
39
|
+
return row;
|
|
40
|
+
}
|
|
41
|
+
function matchSessionInputReceipt(conversationId, clientMessageId, principalId, hash) {
|
|
42
|
+
const receipt = getSessionInputReceipt(conversationId, clientMessageId, principalId);
|
|
43
|
+
if (receipt && receipt.requestHash !== hash) throw new SessionCommandError("IDEMPOTENCY_CONFLICT", "Input identity was reused with different content");
|
|
44
|
+
if (isConversationDeleted(conversationId)) throw new SessionCommandError("SESSION_DELETED", "Conversation was deleted");
|
|
45
|
+
return receipt;
|
|
46
|
+
}
|
|
47
|
+
function getSessionPreparation(conversationId) {
|
|
48
|
+
const row = getSqliteDatabase().prepare(`SELECT conversation_id AS conversationId, operation_id AS operationId,
|
|
49
|
+
creation_json AS creationJson, state, environment_id AS environmentId, base_commit AS baseCommit,
|
|
50
|
+
revision, lease_until AS leaseUntil, last_error AS lastError FROM session_preparations WHERE conversation_id=?`).get(conversationId);
|
|
51
|
+
if (!row) return void 0;
|
|
52
|
+
const { creationJson, ...rest } = row;
|
|
53
|
+
return {
|
|
54
|
+
...rest,
|
|
55
|
+
creation: JSON.parse(creationJson)
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
/** Commit the identity, configuration, input and replay receipt together. All preparation happens before entry. */
|
|
59
|
+
function acceptSessionCommand(input) {
|
|
60
|
+
return runSqliteWriteTransaction((db) => {
|
|
61
|
+
const { conversationId, command, principalId } = input;
|
|
62
|
+
const clientMessageId = "commandId" in command ? command.commandId : command.clientMessageId;
|
|
63
|
+
const requestHash = sessionCommandHash(command);
|
|
64
|
+
const existing = matchSessionInputReceipt(conversationId, clientMessageId, principalId, requestHash);
|
|
65
|
+
if (existing) return existing;
|
|
66
|
+
if ("input" in command !== Boolean(input.preparedInput)) throw new SessionCommandError("BAD_REQUEST", "Prepared input is required for input commands only");
|
|
67
|
+
const pending = db.prepare(`SELECT count(*) AS count FROM session_inputs WHERE conversation_id=?
|
|
68
|
+
AND status IN ('queued','running','injecting','interrupted')`).get(conversationId);
|
|
69
|
+
if (input.preparedInput && pending.count >= 10) throw new SessionCommandError("QUEUE_FULL", "Input queue is full");
|
|
70
|
+
const creation = "creation" in command ? command.creation : void 0;
|
|
71
|
+
let session = getSessionMetadata(conversationId);
|
|
72
|
+
if (creation) {
|
|
73
|
+
if (session) throw new SessionCommandError("CONVERSATION_EXISTS", "Conversation already exists");
|
|
74
|
+
session = createConversation({
|
|
75
|
+
agentId: creation.agentId,
|
|
76
|
+
sourceChannel: input.sourceChannel ?? "webchat",
|
|
77
|
+
sourceChatId: conversationId,
|
|
78
|
+
sessionType: "chat",
|
|
79
|
+
hiddenFromSessionList: !input.preparedInput,
|
|
80
|
+
routing: {
|
|
81
|
+
agentId: creation.agentId,
|
|
82
|
+
source: input.sourceChannel ?? "webchat",
|
|
83
|
+
accountId: "default",
|
|
84
|
+
peerKind: "direct",
|
|
85
|
+
peerId: conversationId
|
|
86
|
+
}
|
|
87
|
+
}, "", conversationId);
|
|
88
|
+
setSessionConfig(conversationId, input.config ?? {
|
|
89
|
+
modelOverride: creation.model,
|
|
90
|
+
fixedModel: true,
|
|
91
|
+
thinkingLevel: creation.thinkingLevel,
|
|
92
|
+
userContextMode: creation.temporary ? "temporary" : "enabled"
|
|
93
|
+
}, "");
|
|
94
|
+
if (creation.projectId) {
|
|
95
|
+
if (!input.attachProject) throw new Error("Project attachment is required");
|
|
96
|
+
input.attachProject(conversationId, creation.projectId);
|
|
97
|
+
}
|
|
98
|
+
if (creation.execution) db.prepare(`INSERT INTO session_preparations
|
|
99
|
+
(conversation_id,operation_id,creation_json,state,environment_id,created_at,updated_at)
|
|
100
|
+
VALUES (?,?,?,'preparing',?,?,?)`).run(conversationId, randomUUID(), JSON.stringify(creation), randomUUID(), Date.now(), Date.now());
|
|
101
|
+
} else {
|
|
102
|
+
if (!session) throw new SessionCommandError("NOT_FOUND", "Conversation not found");
|
|
103
|
+
if (!("kind" in command) || command.kind !== "append" || command.expectedTranscriptId !== session.transcriptId) throw new SessionCommandError("SESSION_CHANGED", "Conversation transcript changed");
|
|
104
|
+
if ((db.prepare("SELECT updated_at FROM session_config WHERE conversation_id=?").get(conversationId)?.updated_at ?? 0) !== command.configVersion) throw new SessionCommandError("CONFIG_CHANGED", "Model configuration changed");
|
|
105
|
+
}
|
|
106
|
+
const transcriptId = session.transcriptId;
|
|
107
|
+
const inputId = input.preparedInput ? randomUUID() : null;
|
|
108
|
+
if (input.preparedInput && inputId) insertSessionInput({
|
|
109
|
+
...input.preparedInput,
|
|
110
|
+
conversationId,
|
|
111
|
+
id: inputId,
|
|
112
|
+
clientMessageId,
|
|
113
|
+
expectedTranscriptId: transcriptId
|
|
114
|
+
});
|
|
115
|
+
if (inputId) {
|
|
116
|
+
invalidateConnectionResumeIntent(conversationId);
|
|
117
|
+
supersedeActiveClarification(conversationId);
|
|
118
|
+
}
|
|
119
|
+
const receipt = {
|
|
120
|
+
conversationId,
|
|
121
|
+
clientMessageId,
|
|
122
|
+
principalId,
|
|
123
|
+
requestHash,
|
|
124
|
+
inputId,
|
|
125
|
+
transcriptId,
|
|
126
|
+
acceptedAt: Date.now()
|
|
127
|
+
};
|
|
128
|
+
db.prepare(`INSERT INTO session_input_receipts
|
|
129
|
+
(conversation_id,client_message_id,principal_id,request_hash,input_id,transcript_id,accepted_at)
|
|
130
|
+
VALUES (?,?,?,?,?,?,?)`).run(conversationId, clientMessageId, principalId, requestHash, inputId, transcriptId, receipt.acceptedAt);
|
|
131
|
+
return receipt;
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
function claimSessionPreparation(conversationId, now = Date.now()) {
|
|
135
|
+
return runSqliteWriteTransaction((db) => {
|
|
136
|
+
return db.prepare(`UPDATE session_preparations SET lease_until=?,revision=revision+1,updated_at=?
|
|
137
|
+
WHERE conversation_id=? AND state='preparing' AND lease_until<=?`).run(now + 6e4, now, conversationId, now).changes ? getSessionPreparation(conversationId) : void 0;
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
function finishSessionPreparation(operation, error) {
|
|
141
|
+
return runSqliteWriteTransaction((db) => Boolean(db.prepare(`UPDATE session_preparations
|
|
142
|
+
SET state=?,last_error=?,lease_until=0,revision=revision+1,updated_at=?
|
|
143
|
+
WHERE conversation_id=? AND operation_id=? AND revision=? AND state='preparing'`).run(error ? "preparation_failed" : "ready", error ?? null, Date.now(), operation.conversationId, operation.operationId, operation.revision).changes));
|
|
144
|
+
}
|
|
145
|
+
function pendingSessionPreparations() {
|
|
146
|
+
return getSqliteDatabase().prepare("SELECT conversation_id FROM session_preparations WHERE state='preparing' AND lease_until<=?").all(Date.now()).map((row) => row.conversation_id);
|
|
147
|
+
}
|
|
148
|
+
function retrySessionPreparation(conversationId, principalId, input) {
|
|
149
|
+
return runSqliteWriteTransaction((db) => {
|
|
150
|
+
if (isConversationDeleted(conversationId)) throw new SessionCommandError("SESSION_DELETED", "Conversation was deleted");
|
|
151
|
+
const operation = getSessionPreparation(conversationId);
|
|
152
|
+
if (!operation) throw new SessionCommandError("NOT_FOUND", "Preparation not found");
|
|
153
|
+
if (db.prepare("SELECT principal_id FROM session_input_receipts WHERE conversation_id=? ORDER BY accepted_at LIMIT 1").get(conversationId)?.principal_id !== principalId) throw new SessionCommandError("FORBIDDEN", "Preparation belongs to another principal");
|
|
154
|
+
const previous = db.prepare("SELECT * FROM session_preparation_retries WHERE conversation_id=? AND idempotency_key=?").get(conversationId, input.idempotencyKey);
|
|
155
|
+
if (previous) {
|
|
156
|
+
if (previous.operation_id !== input.operationId || previous.expected_revision !== input.expectedRevision || previous.principal_id !== principalId) throw new SessionCommandError("IDEMPOTENCY_CONFLICT", "Retry identity was reused");
|
|
157
|
+
return operation;
|
|
158
|
+
}
|
|
159
|
+
if (!db.prepare(`UPDATE session_preparations SET state='preparing', revision=revision+1,
|
|
160
|
+
lease_until=0,last_error=NULL,updated_at=? WHERE conversation_id=? AND operation_id=? AND revision=? AND state='preparation_failed'`).run(Date.now(), conversationId, input.operationId, input.expectedRevision).changes) throw new SessionCommandError("SESSION_CHANGED", "Preparation state changed");
|
|
161
|
+
db.prepare("INSERT INTO session_preparation_retries VALUES (?,?,?,?,?)").run(conversationId, input.idempotencyKey, input.operationId, input.expectedRevision, principalId);
|
|
162
|
+
return getSessionPreparation(conversationId);
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
//#endregion
|
|
166
|
+
export { SessionCommandError, acceptSessionCommand, claimSessionPreparation, finishSessionPreparation, getSessionInputReceipt, getSessionPreparation, isConversationDeleted, matchSessionInputReceipt, pendingSessionPreparations, retrySessionPreparation, sessionCommandHash };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { getSqliteDatabase } from './transaction.js';
|
|
2
2
|
import { type TurnOrigin } from '@xopcai/endpoint-tools-protocol';
|
|
3
|
+
import type { SessionPreparationView } from '@xopcai/gateway-contract';
|
|
3
4
|
import type { AgentSourceContext, SourceContextRefSummary } from '../../agent/source-context/types.js';
|
|
4
5
|
export type SessionInputDelivery = 'next' | 'steer';
|
|
5
6
|
export type SessionInputStatus = 'queued' | 'running' | 'injecting' | 'completed' | 'cancelled' | 'failed' | 'interrupted' | 'suspended';
|
|
@@ -38,6 +39,7 @@ export type SessionInput = {
|
|
|
38
39
|
updatedAtMs: number;
|
|
39
40
|
};
|
|
40
41
|
export type SessionInputState = {
|
|
42
|
+
preparation?: SessionPreparationView;
|
|
41
43
|
conversationId: string;
|
|
42
44
|
revision: number;
|
|
43
45
|
activeRunId?: string;
|
|
@@ -83,8 +85,8 @@ export declare function insertSessionInput(input: {
|
|
|
83
85
|
origin: TurnOrigin;
|
|
84
86
|
targetRunId?: string;
|
|
85
87
|
}): SessionInput;
|
|
86
|
-
export declare function claimNextSessionInput(conversationId: string, runId: string): SessionInput | undefined;
|
|
87
|
-
export declare function finishSessionInputRun(conversationId: string, runId: string, status: 'completed' | 'failed' | 'cancelled' | 'suspended', error?: string): boolean;
|
|
88
|
+
export declare function claimNextSessionInput(conversationId: string, runId: string, expectedInputId?: string): SessionInput | undefined;
|
|
89
|
+
export declare function finishSessionInputRun(conversationId: string, runId: string, status: 'completed' | 'failed' | 'cancelled' | 'suspended' | 'interrupted', error?: string): boolean;
|
|
88
90
|
export declare function setSessionInputStatus(id: string, status: SessionInputStatus, patch?: {
|
|
89
91
|
effectiveDelivery?: SessionInputDelivery;
|
|
90
92
|
targetRunId?: string | null;
|
|
@@ -42,12 +42,14 @@ function bumpSessionInputRevision(db, conversationId) {
|
|
|
42
42
|
}
|
|
43
43
|
function getSessionInputState(conversationId) {
|
|
44
44
|
const db = getSqliteDatabase();
|
|
45
|
+
const preparation = db.prepare("SELECT operation_id AS operationId, revision, state, last_error AS lastError FROM session_preparations WHERE conversation_id=?").get(conversationId);
|
|
45
46
|
const runtime = db.prepare(`SELECT revision, active_run_id, active_input_id
|
|
46
47
|
FROM session_input_runtime WHERE conversation_id = ?`).get(conversationId);
|
|
47
48
|
const rows = db.prepare(`${SELECT_INPUTS} WHERE conversation_id = ? AND status IN
|
|
48
49
|
('queued','running','injecting','interrupted') ORDER BY position, created_at_ms, id`).all(conversationId);
|
|
49
50
|
return {
|
|
50
51
|
conversationId,
|
|
52
|
+
...preparation ? { preparation } : {},
|
|
51
53
|
revision: runtime?.revision ?? 0,
|
|
52
54
|
activeRunId: runtime?.active_run_id ?? void 0,
|
|
53
55
|
activeInputId: runtime?.active_input_id ?? void 0,
|
|
@@ -107,8 +109,11 @@ function insertSessionInput(input) {
|
|
|
107
109
|
return mapInput(db.prepare(`${SELECT_INPUTS} WHERE id = ?`).get(input.id));
|
|
108
110
|
});
|
|
109
111
|
}
|
|
110
|
-
function claimNextSessionInput(conversationId, runId) {
|
|
112
|
+
function claimNextSessionInput(conversationId, runId, expectedInputId) {
|
|
111
113
|
return runSqliteWriteTransaction((db) => {
|
|
114
|
+
const preparation = db.prepare("SELECT state FROM session_preparations WHERE conversation_id=?").get(conversationId);
|
|
115
|
+
if (preparation && preparation.state !== "ready") return void 0;
|
|
116
|
+
if (db.prepare("SELECT 1 FROM session_tombstones WHERE conversation_id=?").get(conversationId)) return void 0;
|
|
112
117
|
ensureRuntime(db, conversationId);
|
|
113
118
|
if (db.prepare(`SELECT active_run_id FROM session_input_runtime WHERE conversation_id = ?`).get(conversationId).active_run_id) return void 0;
|
|
114
119
|
if (db.prepare(`UPDATE session_inputs SET status = 'interrupted', error = 'Session changed before delivery',
|
|
@@ -117,6 +122,7 @@ function claimNextSessionInput(conversationId, runId) {
|
|
|
117
122
|
const row = db.prepare(`${SELECT_INPUTS} WHERE conversation_id = ? AND effective_delivery = 'next'
|
|
118
123
|
AND status = 'queued' ORDER BY position, created_at_ms, id LIMIT 1`).get(conversationId);
|
|
119
124
|
if (!row) return void 0;
|
|
125
|
+
if (expectedInputId && row.id !== expectedInputId) return void 0;
|
|
120
126
|
const now = Date.now();
|
|
121
127
|
db.prepare(`UPDATE session_inputs SET status = 'running', run_id = ?, version = version + 1,
|
|
122
128
|
updated_at_ms = ? WHERE id = ?`).run(runId, now, row.id);
|
|
@@ -2,10 +2,10 @@ import { ProductReadContracts } from "../../../packages/gateway-contract/src/cap
|
|
|
2
2
|
import { init_src } from "../../../packages/gateway-contract/src/index.js";
|
|
3
3
|
import { TaskRepository, init_task_repository } from "../task-repository.js";
|
|
4
4
|
import { TaskRunRepository, init_task_run_repository } from "../task-run-repository.js";
|
|
5
|
-
import { TaskConversationRepository } from "../task-conversation-repository.js";
|
|
6
|
-
import { TaskReadModelProjector } from "../task-read-model-projector.js";
|
|
7
5
|
import { CapabilityError } from "../../capabilities/runtime/errors.js";
|
|
8
6
|
import { defineReadCapability } from "../../capabilities/runtime/dispatcher.js";
|
|
7
|
+
import { TaskConversationRepository } from "../task-conversation-repository.js";
|
|
8
|
+
import { TaskReadModelProjector } from "../task-read-model-projector.js";
|
|
9
9
|
import { TaskContextRepository } from "../task-context-repository.js";
|
|
10
10
|
import { TaskDependencyService } from "../task-dependency-service.js";
|
|
11
11
|
import { TaskValueMetricsService } from "../task-value-metrics-service.js";
|