@xopcai/xopc 0.0.303 → 0.0.306
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/README.md +4 -4
- package/README.zh-CN.md +4 -4
- package/dist/browser-ext/dist/assets/{auth-B_9ZuGDx.js → auth-C3yV1y_l.js} +67 -22
- package/dist/browser-ext/dist/background.js +4 -4
- package/dist/browser-ext/dist/sidepanel.html +1 -1
- package/dist/browser-ext/dist/sidepanel.js +3 -3
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/feishu/xopc.extension.json +0 -3
- package/dist/extensions/telegram/xopc.extension.json +1 -4
- package/dist/extensions/weixin/xopc.extension.json +0 -3
- package/dist/gateway/static/root/assets/{activity-store-DCi5rh4e.js → activity-store-DLtim-_I.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-Ch3DzUvP.js → agent-avatar-dicebear-iQXtiilH.js} +1 -1
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-CxOv4ivK.js +1 -0
- package/dist/gateway/static/root/assets/agents-DzKx7z3k.js +1 -0
- package/dist/gateway/static/root/assets/{api-CAV9PN9i.js → api-DfSU0-lD.js} +1 -1
- package/dist/gateway/static/root/assets/api-gpHh07OL.js +1 -0
- package/dist/gateway/static/root/assets/app-management-settings-panel-BpYFKz7B.js +1 -0
- package/dist/gateway/static/root/assets/{appearance-settings-izNAyDhW.js → appearance-settings-BQfR5vrq.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-BceB7JHZ.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-BKGzaVvM.js → archive-plugin-BxOvZ-ZX.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-8bARdLnp.js → attachment-load-B0FzTMAJ.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-BAEenyzx.js → automations-page-BpXuPaPg.js} +1 -1
- package/dist/gateway/static/root/assets/automations-workspace-Cn_p8zY_.js +6 -0
- package/dist/gateway/static/root/assets/{binary-plugins-Cv3GS9Eo.js → binary-plugins-BP7wfpqy.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-D4ZIVQbk.css → block-editor-BdOTO0Yo.css} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-DUeb92LG.js → block-editor-oMLvdnOQ.js} +3 -3
- package/dist/gateway/static/root/assets/{browser-automation-inputs-BGT0xoTv.js → browser-automation-inputs-DTxSZ00u.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-automations-page-D1O22WIf.js → browser-automations-page-IbJnwEY4.js} +2 -2
- package/dist/gateway/static/root/assets/browser-settings-page-CCUO3G23.js +3 -0
- package/dist/gateway/static/root/assets/button-CS04eWY9.js +1 -0
- package/dist/gateway/static/root/assets/capabilities-settings-panel-BjMb5H2_.js +8 -0
- package/dist/gateway/static/root/assets/channels-settings-P22-_i13.js +1 -0
- package/dist/gateway/static/root/assets/{channels-status-swr-C_icwbWj.js → channels-status-swr-D2AmAoty.js} +1 -1
- package/dist/gateway/static/root/assets/{chat-terminal-dock-D-JYPVYl.js → chat-terminal-dock-B-yI3Mi1.js} +2 -2
- package/dist/gateway/static/root/assets/{computer-settings-page-Bcfp948A.js → computer-settings-page-CWx_jnng.js} +1 -1
- package/dist/gateway/static/root/assets/connectors-page-BLgPORmH.js +2 -0
- package/dist/gateway/static/root/assets/cron-expression-DMRRL4Zg.js +2 -0
- package/dist/gateway/static/root/assets/date-picker-BSwL0e6E.js +1 -0
- package/dist/gateway/static/root/assets/{dependency-picker-UtoUm57Q.js → dependency-picker-BQTspLzC.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-Bryx7gRM.js → desktop-pet-C3lFxDF6.js} +1 -1
- package/dist/gateway/static/root/assets/desktop-pet-settings-Y8pjpXFE.js +1 -0
- package/dist/gateway/static/root/assets/device-pairing-wizard-DM4_GMzo.js +1 -0
- package/dist/gateway/static/root/assets/{extension-debug-page-DQlFTVBx.js → extension-debug-page-CVGiGVcR.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-BSsqRDXh.js → extension-page-g3JtCP_y.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-DbVZv9ve.js → extension-settings-page-CjpoKV1f.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-swr-D5AM8cyQ.js → gateway-config-swr-BSvXXpKM.js} +1 -1
- package/dist/gateway/static/root/assets/gateway-realtime-BDCpS7U1.js +1 -0
- package/dist/gateway/static/root/assets/gateway-realtime-store-BGmP1obI.js +1 -0
- package/dist/gateway/static/root/assets/gateway-settings-CYG9WCZn.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-startup-retry-CSJWdnFs.js → gateway-startup-retry-Caf8g3sC.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-settings-Cxowc29b.js → heartbeat-settings-Cl834-SS.js} +1 -1
- package/dist/gateway/static/root/assets/home-page-CB_XVtIM.js +1 -0
- package/dist/gateway/static/root/assets/{image-generation-api-BNh604hw.js → image-generation-api-BwEWBUVC.js} +1 -1
- package/dist/gateway/static/root/assets/imports-page-CoMlgSIA.js +1 -0
- package/dist/gateway/static/root/assets/index-CI37dTAn.css +1 -0
- package/dist/gateway/static/root/assets/index-Do9MltC4.js +79 -0
- package/dist/gateway/static/root/assets/keyboard-shortcuts-settings-CNq5D4pe.js +1 -0
- package/dist/gateway/static/root/assets/local-app-workbench-page-BxQlEje6.js +2 -0
- package/dist/gateway/static/root/assets/{local-apps-page-CXPaPDGm.js → local-apps-page-DQnRA598.js} +1 -1
- package/dist/gateway/static/root/assets/{locale-store-DLK05Y1a.js → locale-store-D16nmbaN.js} +1 -1
- package/dist/gateway/static/root/assets/logs-page-CT5GrcMs.js +2 -0
- package/dist/gateway/static/root/assets/management-settings-DKcO5fQ-.js +1 -0
- package/dist/gateway/static/root/assets/{markdown-view-B8maDRWh.js → markdown-view-DCp4BlZP.js} +2 -2
- package/dist/gateway/static/root/assets/{media-plugins-tSJ0CvcX.js → media-plugins-Cy64sn_C.js} +1 -1
- package/dist/gateway/static/root/assets/messages-C-9oo69N.js +3 -0
- package/dist/gateway/static/root/assets/note-detail-panel-5dc3LKTL.js +5 -0
- package/dist/gateway/static/root/assets/notes-page-AbwxgXuG.js +8 -0
- package/dist/gateway/static/root/assets/{page-tabs-CQx6H-GS.js → page-tabs-CgEoHSVT.js} +1 -1
- package/dist/gateway/static/root/assets/{popover-select-DldSX8GX.js → popover-select-9i-ZtHXL.js} +1 -1
- package/dist/gateway/static/root/assets/{preview-open-alternatives-A3-bVtdy.js → preview-open-alternatives-Ck2uKTbf.js} +1 -1
- package/dist/gateway/static/root/assets/{proactive-page-D46cR3sf.js → proactive-page-Dr1mCJhZ.js} +1 -1
- package/dist/gateway/static/root/assets/{product-open-page-CujZXOea.js → product-open-page-DbZvJ5GE.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-DnE1zI1c.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-BD0nLYxk.js +1 -0
- package/dist/gateway/static/root/assets/{registry-api-BMFL4vis.js → registry-api-DcQdwpPu.js} +1 -1
- package/dist/gateway/static/root/assets/remote-access-hub-TYuE6A3S.js +1 -0
- package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-CR0qvq9C.js → runtime-tools-settings-panel-CPwdgWKo.js} +2 -2
- package/dist/gateway/static/root/assets/{schema-form-BUD9lLEE.js → schema-form-8psK4cFO.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-BcWDQQFX.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-DzGQX6Hq.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-BZPCUH6a.js → settings-form-section-D_Gsz5rl.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-XoHmqIdm.js → settings-page-C_Tj_mkZ.js} +1 -1
- package/dist/gateway/static/root/assets/setup-status-panel-CE2X89qN.js +1 -0
- package/dist/gateway/static/root/assets/share-preview-page-B_M_oPsT.js +2 -0
- package/dist/gateway/static/root/assets/shares-settings-BL4H9Iym.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-WMKIgUOp.js +1 -0
- package/dist/gateway/static/root/assets/skills-page-DYgwzl5B.js +2 -0
- package/dist/gateway/static/root/assets/{skills-page.utils-CH-quGxZ.js → skills-page.utils-Cuh6s2HM.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-CGC7eBso.js → system-settings-panel-aassGyNb.js} +1 -1
- package/dist/gateway/static/root/assets/task-detail-page-BjeRslap.js +1 -0
- package/dist/gateway/static/root/assets/theme-store-RUBQBsFP.js +1 -0
- package/dist/gateway/static/root/assets/tunnel-api-DJYcPWIV.js +1 -0
- package/dist/gateway/static/root/assets/{use-autosave-BydB6x2K.js → use-autosave-QGYG7oMZ.js} +1 -1
- package/dist/gateway/static/root/assets/user-model-page-PrRsd4go.js +2 -0
- package/dist/gateway/static/root/assets/{voice-api-key-field-CPUDBcag.js → voice-api-key-field-D1s0gIRW.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-config-api-bZqN8-UF.js → voice-config-api-D2goEn5e.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-overlay-D_FmJbGH.js → work-discovery-overlay-DkFW9aJ6.js} +1 -1
- package/dist/gateway/static/root/assets/workflow-run-setup-panel-BYToUPUY.js +3 -0
- package/dist/gateway/static/root/assets/workflows-page-Z8iZe9YP.js +6 -0
- package/dist/gateway/static/root/index.html +14 -12
- package/dist/package.js +1 -1
- package/dist/packages/gateway-contract/src/device-pairing.js +100 -7
- package/dist/packages/gateway-contract/src/gateway-scopes.js +53 -0
- package/dist/packages/gateway-contract/src/index.js +2 -0
- package/dist/packages/realtime-client/src/index.js +14 -2
- package/dist/packages/realtime-protocol/src/index.js +18 -14
- package/dist/src/agent/agent-instance-gateway.d.ts +2 -0
- package/dist/src/agent/agent-manager.d.ts +2 -0
- package/dist/src/agent/agent-manager.js +40 -12
- package/dist/src/agent/agent-scope.d.ts +4 -1
- package/dist/src/agent/agent-scope.js +19 -3
- package/dist/src/agent/commands/command-isolation.js +11 -9
- package/dist/src/agent/commands/command-registry.js +18 -33
- package/dist/src/agent/context/audit.js +12 -2
- package/dist/src/agent/context/coordinator.d.ts +13 -3
- package/dist/src/agent/context/coordinator.js +27 -11
- package/dist/src/agent/context/execution-context.js +42 -22
- package/dist/src/agent/context/execution-context.types.d.ts +4 -2
- package/dist/src/agent/context/execution-scope.d.ts +2 -2
- package/dist/src/agent/context/execution-scope.js +1 -1
- package/dist/src/agent/context/project-context.d.ts +2 -2
- package/dist/src/agent/context/project-context.js +3 -3
- package/dist/src/agent/embedded/run-for-session.d.ts +1 -0
- package/dist/src/agent/embedded/run-for-session.js +7 -1
- package/dist/src/agent/inbound/attachment-pipeline.d.ts +2 -0
- package/dist/src/agent/inbound/attachment-pipeline.js +3 -3
- package/dist/src/agent/inbound/inbound-loop.js +1 -0
- package/dist/src/agent/inbound/turn-dispatcher.js +3 -3
- package/dist/src/agent/mcp/mcp-stdio-transport.js +5 -2
- package/dist/src/agent/memory/compaction-promotion.js +7 -2
- package/dist/src/agent/memory/create-memory-manager.js +1 -0
- package/dist/src/agent/memory/manager.d.ts +6 -0
- package/dist/src/agent/memory/manager.js +74 -39
- package/dist/src/agent/memory/runtime.d.ts +3 -3
- package/dist/src/agent/memory/runtime.js +11 -4
- package/dist/src/agent/orchestration/agent-orchestrator.js +4 -1
- package/dist/src/agent/prompt/cache-boundary.d.ts +2 -0
- package/dist/src/agent/prompt/cache-boundary.js +10 -1
- package/dist/src/agent/service/build-direct-message-content.d.ts +1 -0
- package/dist/src/agent/service/build-direct-message-content.js +2 -1
- package/dist/src/agent/service/direct-turn-helpers.js +3 -2
- package/dist/src/agent/service/process-direct-streaming.d.ts +3 -1
- package/dist/src/agent/service/process-direct-streaming.js +3 -2
- package/dist/src/agent/service/webchat-tts.d.ts +0 -4
- package/dist/src/agent/service/webchat-tts.js +20 -19
- package/dist/src/agent/tools/factory.js +3 -3
- package/dist/src/agent/tools/knowledge-memory-tool.d.ts +2 -2
- package/dist/src/agent/tools/knowledge-memory-tool.js +7 -7
- package/dist/src/browser/native-messaging-host.js +2 -2
- package/dist/src/channels/attachments/voice-stt-webchat.d.ts +3 -0
- package/dist/src/channels/attachments/voice-stt-webchat.js +22 -9
- package/dist/src/cli/commands/agent.js +2 -0
- package/dist/src/cli/commands/config.js +8 -9
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/cli/commands/extension-marketplace.js +69 -44
- package/dist/src/cli/commands/extension-pack.js +0 -2
- package/dist/src/cli/commands/extension.js +4 -25
- package/dist/src/cli/commands/gateway/lifecycle.js +1 -1
- package/dist/src/cli/commands/onboard/gateway.js +2 -1
- package/dist/src/cli/commands/update.js +1 -1
- package/dist/src/cli/utils/init-workspace-core.js +5 -2
- package/dist/src/config/index.js +2 -2
- package/dist/src/config/loader.d.ts +1 -0
- package/dist/src/config/loader.js +14 -1
- package/dist/src/config/schema.d.ts +10 -3
- package/dist/src/config/schema.js +9 -1
- package/dist/src/execution-environments/local-worktree-manager.js +17 -15
- package/dist/src/execution-environments/store.js +4 -2
- package/dist/src/execution-environments/types.d.ts +3 -0
- package/dist/src/execution-environments/types.js +2 -1
- package/dist/src/execution-environments/worktree-safety.d.ts +8 -0
- package/dist/src/execution-environments/worktree-safety.js +43 -0
- package/dist/src/extensions/activation-planner.d.ts +1 -1
- package/dist/src/extensions/activation-planner.js +1 -1
- package/dist/src/extensions/api-version.d.ts +4 -0
- package/dist/src/extensions/api-version.js +15 -0
- package/dist/src/extensions/api.d.ts +3 -9
- package/dist/src/extensions/api.js +26 -32
- package/dist/src/extensions/config-validation.d.ts +8 -0
- package/dist/src/extensions/config-validation.js +25 -0
- package/dist/src/extensions/extension-registry-impl.d.ts +20 -9
- package/dist/src/extensions/extension-registry-impl.js +79 -11
- package/dist/src/extensions/hooks.d.ts +1 -1
- package/dist/src/extensions/index.d.ts +2 -1
- package/dist/src/extensions/install-transaction.d.ts +2 -0
- package/dist/src/extensions/install-transaction.js +32 -21
- package/dist/src/extensions/install.js +18 -1
- package/dist/src/extensions/loader.d.ts +5 -5
- package/dist/src/extensions/loader.js +109 -47
- package/dist/src/extensions/lockfile.d.ts +3 -5
- package/dist/src/extensions/lockfile.js +41 -14
- package/dist/src/extensions/normalize-manifest.js +6 -60
- package/dist/src/extensions/sdk/index.d.ts +3 -2
- package/dist/src/extensions/sdk/index.js +2 -2
- package/dist/src/extensions/sdk/testing.js +0 -4
- package/dist/src/extensions/security.js +5 -7
- package/dist/src/extensions/types/core.d.ts +0 -5
- package/dist/src/extensions/types/index.d.ts +1 -1
- package/dist/src/extensions/types/manifest.d.ts +1 -25
- package/dist/src/extensions/types/providers.d.ts +1 -1
- package/dist/src/extensions/types/registration.d.ts +0 -12
- package/dist/src/extensions/update.js +71 -30
- package/dist/src/gateway/heartbeat/service.js +2 -2
- package/dist/src/gateway/hono/lib/config-payload.d.ts +3 -1
- package/dist/src/gateway/hono/routes/auth-registry-extensions.js +47 -10
- package/dist/src/gateway/hono/routes/devices.js +10 -7
- package/dist/src/gateway/hono/routes/endpoint-compatibility.js +6 -0
- package/dist/src/gateway/hono/routes/extension-gateway.js +0 -33
- package/dist/src/gateway/hono/routes/imports.js +1 -1
- package/dist/src/gateway/hono/routes/lazy-bundles.js +0 -1
- package/dist/src/gateway/hono/routes/local-apps.js +1 -1
- package/dist/src/gateway/hono/routes/realtime.js +30 -8
- package/dist/src/gateway/hono/routes/update.js +2 -2
- package/dist/src/gateway/hono/routes/user-model.js +25 -6
- package/dist/src/gateway/index.js +5 -2
- package/dist/src/gateway/lock.d.ts +2 -0
- package/dist/src/gateway/lock.js +31 -14
- package/dist/src/gateway/run-loop.js +3 -2
- package/dist/src/gateway/security/gateway-scopes.d.ts +2 -5
- package/dist/src/gateway/security/gateway-scopes.js +3 -45
- package/dist/src/gateway/security/index.js +2 -1
- package/dist/src/gateway/service.js +11 -7
- package/dist/src/heartbeat/index.js +1 -1
- package/dist/src/imports/importService.d.ts +1 -1
- package/dist/src/imports/inventory.js +16 -2
- package/dist/src/imports/productImport.js +5 -5
- package/dist/src/imports/types.d.ts +3 -3
- package/dist/src/infra/exec.d.ts +2 -2
- package/dist/src/infra/exec.js +32 -27
- package/dist/src/infra/gateway-processes.js +1 -1
- package/dist/src/infra/run-command.js +15 -50
- package/dist/src/infra/update-restart.js +1 -1
- package/dist/src/infra/update-runner.js +2 -2
- package/dist/src/infra/update-startup.js +1 -1
- package/dist/src/knowledge/connected-knowledge-pipeline.js +13 -3
- package/dist/src/knowledge-memory/domain.d.ts +17 -1
- package/dist/src/knowledge-memory/index.js +2 -2
- package/dist/src/knowledge-memory/repository.d.ts +26 -4
- package/dist/src/knowledge-memory/repository.js +171 -36
- package/dist/src/mcp/channel-bridge.js +7 -3
- package/dist/src/media-understanding/registry.js +6 -1
- package/dist/src/migrations/knowledge-memory-read-policy-config.d.ts +2 -0
- package/dist/src/migrations/knowledge-memory-read-policy-config.js +48 -0
- package/dist/src/migrations/runner.js +2 -1
- package/dist/src/process/bounded-output.d.ts +10 -0
- package/dist/src/process/bounded-output.js +41 -0
- package/dist/src/process/kill-tree.d.ts +6 -17
- package/dist/src/process/kill-tree.js +43 -75
- package/dist/src/process/process-spec.d.ts +39 -0
- package/dist/src/process/process-spec.js +13 -0
- package/dist/src/process/run-process.d.ts +4 -0
- package/dist/src/process/run-process.js +97 -0
- package/dist/src/providers/plugin-registry.d.ts +1 -1
- package/dist/src/providers/plugin-registry.js +6 -0
- package/dist/src/realtime/runtime.js +3 -1
- package/dist/src/session/store.js +1 -1
- package/dist/src/storage/sqlite/device-pairing-approval.js +1 -1
- package/dist/src/storage/sqlite/index.d.ts +1 -1
- package/dist/src/storage/sqlite/index.js +2 -2
- package/dist/src/storage/sqlite/migrations/180_execution_environment_ownership.sql +7 -0
- package/dist/src/storage/sqlite/migrations/181_knowledge_item_status_events.sql +12 -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/schema.sql +13 -0
- package/dist/src/storage/sqlite/transcript-repository.d.ts +4 -0
- package/dist/src/storage/sqlite/transcript-repository.js +36 -1
- package/dist/src/tui/backends/embedded-backend.d.ts +24 -8
- package/dist/src/tui/backends/embedded-backend.js +114 -10
- package/dist/src/tui/backends/gateway-realtime-backend.d.ts +18 -0
- package/dist/src/tui/backends/gateway-realtime-backend.js +32 -5
- package/dist/src/tui/components/assistant-message.d.ts +4 -1
- package/dist/src/tui/components/assistant-message.js +10 -2
- package/dist/src/tui/components/cell-render-mode.d.ts +4 -0
- package/dist/src/tui/components/cell-render-mode.js +1 -0
- package/dist/src/tui/components/chat-log.d.ts +17 -4
- package/dist/src/tui/components/chat-log.js +68 -50
- package/dist/src/tui/components/custom-editor.d.ts +2 -2
- package/dist/src/tui/components/custom-editor.js +5 -1
- package/dist/src/tui/components/pending-input-preview.d.ts +9 -0
- package/dist/src/tui/components/pending-input-preview.js +33 -0
- package/dist/src/tui/components/semantic-cell.d.ts +17 -0
- package/dist/src/tui/components/semantic-cell.js +29 -0
- package/dist/src/tui/components/tool-execution.d.ts +5 -1
- package/dist/src/tui/components/tool-execution.js +33 -10
- package/dist/src/tui/components/transcript-overlay.d.ts +29 -0
- package/dist/src/tui/components/transcript-overlay.js +114 -0
- package/dist/src/tui/components/tui-bottom-bar.js +3 -1
- package/dist/src/tui/components/user-message.d.ts +5 -1
- package/dist/src/tui/components/user-message.js +12 -1
- package/dist/src/tui/extension-host/load-extensions.d.ts +1 -1
- package/dist/src/tui/extension-host/runtime-context.js +2 -1
- package/dist/src/tui/extension-host/runtime.d.ts +1 -1
- package/dist/src/tui/format-tui-hotkeys.js +8 -1
- package/dist/src/tui/tui-agent-events.js +31 -0
- package/dist/src/tui/tui-backend.d.ts +23 -11
- package/dist/src/tui/tui-backend.js +1 -9
- package/dist/src/tui/tui-chat-input-state.d.ts +25 -0
- package/dist/src/tui/tui-chat-input-state.js +36 -0
- package/dist/src/tui/tui-command-formatters.js +2 -1
- package/dist/src/tui/tui-commands.js +1 -1
- package/dist/src/tui/tui-types.d.ts +2 -1
- package/dist/src/tui/tui-types.js +2 -1
- package/dist/src/tui/tui.js +122 -30
- package/dist/src/tui/xopc-tui-keybindings.d.ts +23 -3
- package/dist/src/tui/xopc-tui-keybindings.js +22 -2
- package/dist/src/user-context/access-policy.d.ts +2 -2
- package/dist/src/user-context/access-policy.js +10 -2
- package/dist/src/user-context/config.d.ts +23 -6
- package/dist/src/user-context/config.js +54 -7
- package/dist/src/voice/platform-streams.js +11 -1
- package/dist/src/voice/realtime/omniEngine.js +13 -1
- package/dist/src/voice/realtime/runtime.js +2 -1
- package/dist/src/voice/tts/audio.js +1 -1
- package/dist/src/voice/tts/speech-registry.js +6 -1
- package/package.json +7 -5
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-4oGrNj3m.js +0 -1
- package/dist/gateway/static/root/assets/agents-DXHD-ST3.js +0 -1
- package/dist/gateway/static/root/assets/api-fPapljyb.js +0 -1
- package/dist/gateway/static/root/assets/app-management-settings-panel-CdXnNtTg.js +0 -1
- package/dist/gateway/static/root/assets/apps-page-BQb3RCga.js +0 -1
- package/dist/gateway/static/root/assets/automations-workspace-5vTl4x0h.js +0 -6
- package/dist/gateway/static/root/assets/browser-settings-page-CH9prS-f.js +0 -3
- package/dist/gateway/static/root/assets/button-CGlRPNzi.js +0 -1
- package/dist/gateway/static/root/assets/capabilities-settings-panel-DMURlZbj.js +0 -8
- package/dist/gateway/static/root/assets/channels-settings-CFBS3Yqy.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-DI1c3BMz.js +0 -2
- package/dist/gateway/static/root/assets/cron-expression-BJMBFKCh.js +0 -2
- package/dist/gateway/static/root/assets/date-picker-BFRIn5y9.js +0 -1
- package/dist/gateway/static/root/assets/desktop-pet-settings-DFsyEJUr.js +0 -1
- package/dist/gateway/static/root/assets/device-pairing-wizard-C3TQVPRy.js +0 -1
- package/dist/gateway/static/root/assets/gateway-settings-DUqVsB3X.js +0 -1
- package/dist/gateway/static/root/assets/home-page-CLkumXdN.js +0 -1
- package/dist/gateway/static/root/assets/imports-page-DXNfRmk9.js +0 -1
- package/dist/gateway/static/root/assets/index-BLRIcVQa.css +0 -1
- package/dist/gateway/static/root/assets/index-gheM453N.js +0 -79
- package/dist/gateway/static/root/assets/keyboard-shortcuts-settings-5Hcec8Xf.js +0 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-BDg1-fcw.js +0 -2
- package/dist/gateway/static/root/assets/logs-page-BWZc5jwO.js +0 -2
- package/dist/gateway/static/root/assets/management-settings-COa3PhMs.js +0 -1
- package/dist/gateway/static/root/assets/messages-C9h8SImu.js +0 -3
- package/dist/gateway/static/root/assets/note-detail-panel-D_YGzNcR.js +0 -5
- package/dist/gateway/static/root/assets/notes-page-D1f2oI2-.js +0 -8
- package/dist/gateway/static/root/assets/project-detail-page-CRlD_Rwv.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-mmX0SavY.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-Cqr3K6T5.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-CPkvbdJP.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-Cu0DAbeH.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-D8fQF1jZ.js +0 -1
- package/dist/gateway/static/root/assets/share-preview-page-BgHqwTuT.js +0 -2
- package/dist/gateway/static/root/assets/shares-settings-Id4vRHzI.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-BB2Fj_di.js +0 -1
- package/dist/gateway/static/root/assets/skills-page-BAwF4LpS.js +0 -2
- package/dist/gateway/static/root/assets/task-detail-page-BVjw812D.js +0 -1
- package/dist/gateway/static/root/assets/theme-store-KfFEGMlp.js +0 -1
- package/dist/gateway/static/root/assets/tunnel-api-Do98Xk05.js +0 -1
- package/dist/gateway/static/root/assets/user-model-page-Nv68a4ak.js +0 -2
- package/dist/gateway/static/root/assets/workflow-run-setup-panel-1lZ_btki.js +0 -3
- package/dist/gateway/static/root/assets/workflows-page-DFOhccm3.js +0 -6
- package/dist/src/extensions/when-context.d.ts +0 -6
- package/dist/src/extensions/when-context.js +0 -26
- package/dist/src/extensions/when-expression.d.ts +0 -11
- package/dist/src/extensions/when-expression.js +0 -213
|
@@ -5,6 +5,12 @@ import { randomUUID } from "node:crypto";
|
|
|
5
5
|
//#region src/knowledge-memory/repository.ts
|
|
6
6
|
init_fts();
|
|
7
7
|
init_transaction();
|
|
8
|
+
var KnowledgeReviewConflictError = class extends Error {
|
|
9
|
+
constructor(message) {
|
|
10
|
+
super(message);
|
|
11
|
+
this.name = "KnowledgeReviewConflictError";
|
|
12
|
+
}
|
|
13
|
+
};
|
|
8
14
|
function fromRow(row) {
|
|
9
15
|
return {
|
|
10
16
|
id: row.knowledge_id,
|
|
@@ -37,6 +43,14 @@ function fromRow(row) {
|
|
|
37
43
|
function bounded(value, field) {
|
|
38
44
|
if (!Number.isFinite(value) || value < 0 || value > 1) throw new Error(`${field} must be between 0 and 1.`);
|
|
39
45
|
}
|
|
46
|
+
function statusActorForOrigin(origin) {
|
|
47
|
+
return origin === "owner" ? "user" : origin === "agent" ? "agent" : "runtime";
|
|
48
|
+
}
|
|
49
|
+
function insertStatusEvent(db, input) {
|
|
50
|
+
db.prepare(`INSERT INTO knowledge_item_status_events (
|
|
51
|
+
event_id, knowledge_id, from_status, to_status, actor_type, reason, created_at
|
|
52
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?)`).run(randomUUID(), input.knowledgeId, input.fromStatus, input.toStatus, input.actor, input.reason, input.now);
|
|
53
|
+
}
|
|
40
54
|
function writeKnowledgeItem(input) {
|
|
41
55
|
validateScope(input.scope);
|
|
42
56
|
bounded(input.confidence, "confidence");
|
|
@@ -67,25 +81,43 @@ function writeKnowledgeItem(input) {
|
|
|
67
81
|
created: false
|
|
68
82
|
};
|
|
69
83
|
if (existing) {
|
|
84
|
+
const nextStatus = input.status ?? (input.originClass === "owner" ? "active" : "candidate");
|
|
70
85
|
db.prepare(`UPDATE knowledge_items SET kind = ?, content = ?, record_class = ?, status = ?, confidence = ?,
|
|
71
86
|
importance = ?, valid_from = ?, valid_to = ?, expires_at = ?, review_at = ?,
|
|
72
87
|
origin_class = ?, source_agent_id = ?, source_conversation_id = ?, source_turn_id = ?,
|
|
73
|
-
derived_from_recalled_context = ?, source_json = ?, updated_at = ? WHERE knowledge_id = ?`).run(input.kind, input.content.trim(), input.recordClass ?? "memory",
|
|
88
|
+
derived_from_recalled_context = ?, source_json = ?, updated_at = ? WHERE knowledge_id = ?`).run(input.kind, input.content.trim(), input.recordClass ?? "memory", nextStatus, input.confidence, input.importance, input.validFrom ?? null, input.validTo ?? null, input.expiresAt ?? null, input.reviewAt ?? null, input.originClass, input.sourceAgentId ?? null, input.sourceConversationId ?? null, input.sourceTurnId ?? null, input.derivedFromRecalledContext ? 1 : 0, JSON.stringify(input.source ?? {}), now, existing.knowledge_id);
|
|
74
89
|
db.prepare("DELETE FROM knowledge_items_fts WHERE knowledge_id = ?").run(existing.knowledge_id);
|
|
75
90
|
db.prepare("INSERT INTO knowledge_items_fts(content, knowledge_id) VALUES (?, ?)").run(input.content.trim(), existing.knowledge_id);
|
|
91
|
+
if (existing.status !== nextStatus) insertStatusEvent(db, {
|
|
92
|
+
knowledgeId: existing.knowledge_id,
|
|
93
|
+
fromStatus: existing.status,
|
|
94
|
+
toStatus: nextStatus,
|
|
95
|
+
actor: statusActorForOrigin(input.originClass),
|
|
96
|
+
reason: "Knowledge replaced from its source.",
|
|
97
|
+
now
|
|
98
|
+
});
|
|
76
99
|
return {
|
|
77
100
|
item: fromRow(db.prepare("SELECT * FROM knowledge_items WHERE knowledge_id = ?").get(existing.knowledge_id)),
|
|
78
101
|
created: false
|
|
79
102
|
};
|
|
80
103
|
}
|
|
81
104
|
const id = randomUUID();
|
|
105
|
+
const status = input.status ?? (input.originClass === "owner" ? "active" : "candidate");
|
|
82
106
|
db.prepare(`INSERT INTO knowledge_items (
|
|
83
107
|
knowledge_id, principal_id, kind, scope_type, scope_id, content, canonical_key, record_class,
|
|
84
108
|
status, confidence, importance, valid_from, valid_to, expires_at, review_at,
|
|
85
109
|
origin_class, source_agent_id, source_conversation_id, source_turn_id,
|
|
86
110
|
derived_from_recalled_context, source_json, created_at, updated_at
|
|
87
|
-
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(id, principalId, input.kind, input.scope.type, input.scope.id ?? null, input.content.trim(), input.canonicalKey.trim(), input.recordClass ?? "memory",
|
|
111
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(id, principalId, input.kind, input.scope.type, input.scope.id ?? null, input.content.trim(), input.canonicalKey.trim(), input.recordClass ?? "memory", status, input.confidence, input.importance, input.validFrom ?? null, input.validTo ?? null, input.expiresAt ?? null, input.reviewAt ?? null, input.originClass, input.sourceAgentId ?? null, input.sourceConversationId ?? null, input.sourceTurnId ?? null, input.derivedFromRecalledContext ? 1 : 0, JSON.stringify(input.source ?? {}), now, now);
|
|
88
112
|
db.prepare("INSERT INTO knowledge_items_fts(content, knowledge_id) VALUES (?, ?)").run(input.content.trim(), id);
|
|
113
|
+
insertStatusEvent(db, {
|
|
114
|
+
knowledgeId: id,
|
|
115
|
+
fromStatus: null,
|
|
116
|
+
toStatus: status,
|
|
117
|
+
actor: statusActorForOrigin(input.originClass),
|
|
118
|
+
reason: "Knowledge admitted.",
|
|
119
|
+
now
|
|
120
|
+
});
|
|
89
121
|
return {
|
|
90
122
|
item: fromRow(db.prepare("SELECT * FROM knowledge_items WHERE knowledge_id = ?").get(id)),
|
|
91
123
|
created: true
|
|
@@ -112,46 +144,146 @@ function listKnowledgeItems(input = {}) {
|
|
|
112
144
|
${input.canonicalKey ? "AND canonical_key = ?" : ""}
|
|
113
145
|
ORDER BY importance DESC, updated_at DESC LIMIT ?`).all(input.principalId ?? "local-owner", ...statuses, ...input.recordClass ? [input.recordClass] : [], ...input.scope ? [input.scope.type, input.scope.id ?? null] : [], ...input.canonicalKey ? [input.canonicalKey] : [], Math.max(1, Math.min(2e3, input.limit ?? 200))).map(fromRow);
|
|
114
146
|
}
|
|
115
|
-
function
|
|
116
|
-
|
|
117
|
-
|
|
147
|
+
function transitionKnowledgeStatus(input) {
|
|
148
|
+
const reason = input.reason.trim();
|
|
149
|
+
if (!reason) throw new Error("A knowledge status change reason is required.");
|
|
150
|
+
const content = input.content?.trim();
|
|
151
|
+
if (input.content !== void 0 && !content) throw new Error("Knowledge content is required.");
|
|
152
|
+
const now = input.now ?? Date.now();
|
|
153
|
+
return runSqliteWriteTransaction((db) => {
|
|
154
|
+
const current = db.prepare("SELECT * FROM knowledge_items WHERE knowledge_id = ?").get(input.id);
|
|
155
|
+
if (!current) return void 0;
|
|
156
|
+
if (input.expectedStatus && current.status !== input.expectedStatus) throw new KnowledgeReviewConflictError(`Knowledge status changed from ${input.expectedStatus} to ${current.status}.`);
|
|
157
|
+
db.prepare(`UPDATE knowledge_items SET status = ?, content = COALESCE(?, content), updated_at = ?
|
|
158
|
+
WHERE knowledge_id = ?`).run(input.status, content ?? null, now, input.id);
|
|
159
|
+
if (content !== void 0) {
|
|
160
|
+
db.prepare("DELETE FROM knowledge_items_fts WHERE knowledge_id = ?").run(input.id);
|
|
161
|
+
db.prepare("INSERT INTO knowledge_items_fts(content, knowledge_id) VALUES (?, ?)").run(content, input.id);
|
|
162
|
+
}
|
|
163
|
+
insertStatusEvent(db, {
|
|
164
|
+
knowledgeId: input.id,
|
|
165
|
+
fromStatus: current.status,
|
|
166
|
+
toStatus: input.status,
|
|
167
|
+
actor: input.actor,
|
|
168
|
+
reason,
|
|
169
|
+
now
|
|
170
|
+
});
|
|
171
|
+
return fromRow(db.prepare("SELECT * FROM knowledge_items WHERE knowledge_id = ?").get(input.id));
|
|
172
|
+
});
|
|
118
173
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
174
|
+
const REVIEW_TRANSITIONS = {
|
|
175
|
+
approve: {
|
|
176
|
+
from: [
|
|
177
|
+
"candidate",
|
|
178
|
+
"needs_review",
|
|
179
|
+
"stale"
|
|
180
|
+
],
|
|
181
|
+
to: "active"
|
|
182
|
+
},
|
|
183
|
+
edit_and_approve: {
|
|
184
|
+
from: [
|
|
185
|
+
"candidate",
|
|
186
|
+
"needs_review",
|
|
187
|
+
"stale"
|
|
188
|
+
],
|
|
189
|
+
to: "active",
|
|
190
|
+
requiresContent: true
|
|
191
|
+
},
|
|
192
|
+
reject: {
|
|
193
|
+
from: [
|
|
194
|
+
"candidate",
|
|
195
|
+
"needs_review",
|
|
196
|
+
"stale"
|
|
197
|
+
],
|
|
198
|
+
to: "rejected"
|
|
199
|
+
},
|
|
200
|
+
archive: {
|
|
201
|
+
from: [
|
|
202
|
+
"candidate",
|
|
203
|
+
"needs_review",
|
|
204
|
+
"stale",
|
|
205
|
+
"active"
|
|
206
|
+
],
|
|
207
|
+
to: "archived"
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
function reviewKnowledgeItem(input) {
|
|
211
|
+
const current = getKnowledgeItem(input.id);
|
|
212
|
+
if (!current) return void 0;
|
|
213
|
+
const transition = REVIEW_TRANSITIONS[input.action];
|
|
214
|
+
if (!transition.from.includes(current.status)) throw new KnowledgeReviewConflictError(`Cannot ${input.action} knowledge with status ${current.status}.`);
|
|
215
|
+
if (transition.requiresContent && !input.content?.trim()) throw new Error("Edited knowledge content is required.");
|
|
216
|
+
return transitionKnowledgeStatus({
|
|
217
|
+
id: input.id,
|
|
218
|
+
status: transition.to,
|
|
219
|
+
actor: input.actor,
|
|
220
|
+
reason: input.reason,
|
|
221
|
+
expectedStatus: input.expectedStatus ?? current.status,
|
|
222
|
+
...input.content === void 0 ? {} : { content: input.content },
|
|
223
|
+
...input.now === void 0 ? {} : { now: input.now }
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
function listKnowledgeStatusEvents(knowledgeId) {
|
|
227
|
+
return getSqliteDatabase().prepare(`SELECT event_id, knowledge_id, from_status, to_status,
|
|
228
|
+
actor_type, reason, created_at FROM knowledge_item_status_events
|
|
229
|
+
WHERE knowledge_id = ? ORDER BY created_at ASC, event_id ASC`).all(knowledgeId).map((row) => ({
|
|
230
|
+
id: row.event_id,
|
|
231
|
+
knowledgeId: row.knowledge_id,
|
|
232
|
+
...row.from_status === null ? {} : { fromStatus: row.from_status },
|
|
233
|
+
toStatus: row.to_status,
|
|
234
|
+
actor: row.actor_type,
|
|
235
|
+
reason: row.reason,
|
|
236
|
+
createdAt: row.created_at
|
|
237
|
+
}));
|
|
238
|
+
}
|
|
239
|
+
function visibilityClause(context, policy) {
|
|
240
|
+
const allowed = new Set(policy?.scopes ?? [
|
|
241
|
+
"global",
|
|
242
|
+
"agent",
|
|
243
|
+
"workspace",
|
|
244
|
+
"project",
|
|
245
|
+
"session"
|
|
246
|
+
]);
|
|
247
|
+
const parts = [];
|
|
248
|
+
const values = [];
|
|
249
|
+
if (allowed.has("global")) parts.push("k.scope_type = 'global'");
|
|
250
|
+
if (allowed.has("agent")) {
|
|
251
|
+
parts.push("(k.scope_type = 'agent' AND k.scope_id = ?)");
|
|
252
|
+
values.push(context.agentId ?? "");
|
|
253
|
+
}
|
|
254
|
+
if (allowed.has("workspace")) {
|
|
255
|
+
parts.push("(k.scope_type = 'workspace' AND k.scope_id = ?)");
|
|
256
|
+
values.push(context.workspaceId ?? "");
|
|
257
|
+
}
|
|
258
|
+
if (allowed.has("session")) {
|
|
259
|
+
parts.push("(k.scope_type = 'session' AND k.scope_id = ?)");
|
|
260
|
+
values.push(context.conversationId ?? "");
|
|
261
|
+
}
|
|
262
|
+
if (allowed.has("project") && context.projectId) {
|
|
132
263
|
parts.push("(k.scope_type = 'project' AND k.scope_id = ?)");
|
|
133
264
|
values.push(context.projectId);
|
|
134
265
|
}
|
|
135
266
|
return {
|
|
136
|
-
sql: `(${parts.join(" OR ")})`,
|
|
267
|
+
sql: `(${parts.length ? parts.join(" OR ") : "0"})`,
|
|
137
268
|
values
|
|
138
269
|
};
|
|
139
270
|
}
|
|
271
|
+
function contentSourceClause(policy) {
|
|
272
|
+
if (!policy) return "1";
|
|
273
|
+
const allowed = new Set(policy.contentSources);
|
|
274
|
+
const importedSource = "COALESCE(json_extract(k.source_json, '$.kind'), '') = 'product_import'";
|
|
275
|
+
const parts = [];
|
|
276
|
+
if (allowed.has("memory")) parts.push("k.record_class = 'memory'");
|
|
277
|
+
if (allowed.has("local_import")) parts.push(`(k.record_class = 'source_index' AND ${importedSource})`);
|
|
278
|
+
if (allowed.has("connector")) parts.push(`(k.record_class = 'source_index' AND NOT (${importedSource}))`);
|
|
279
|
+
return `(${parts.length ? parts.join(" OR ") : "0"})`;
|
|
280
|
+
}
|
|
140
281
|
function searchKnowledgeItems(input) {
|
|
141
282
|
const principalId = input.principalId ?? "local-owner";
|
|
142
283
|
const asOf = input.asOf ?? Date.now();
|
|
143
284
|
const limit = Math.max(1, Math.min(100, input.limit ?? 12));
|
|
144
|
-
const visible = visibilityClause(input.context);
|
|
145
|
-
const
|
|
146
|
-
const sourceValues = [];
|
|
147
|
-
const importedSource = "COALESCE(json_extract(k.source_json, '$.kind'), '') = 'product_import'";
|
|
148
|
-
if (input.sources?.includes("connector")) sourceParts.push(`(k.record_class = 'source_index' AND NOT (${importedSource}))`);
|
|
149
|
-
if (input.sources?.includes("workspace")) sourceParts.push(`(k.record_class = 'source_index' AND ${importedSource})`);
|
|
150
|
-
const memoryScopes = input.sources?.filter((source) => source !== "connector") ?? [];
|
|
151
|
-
if (memoryScopes.length) {
|
|
152
|
-
sourceParts.push(`(k.record_class = 'memory' AND k.scope_type IN (${memoryScopes.map(() => "?").join(", ")}))`);
|
|
153
|
-
sourceValues.push(...memoryScopes);
|
|
154
|
-
}
|
|
285
|
+
const visible = visibilityClause(input.context, input.policy);
|
|
286
|
+
const contentSource = contentSourceClause(input.policy);
|
|
155
287
|
const fts = buildFts5SearchQuery(input.query);
|
|
156
288
|
if (!fts) return [];
|
|
157
289
|
return getSqliteDatabase().prepare(`SELECT k.*, bm25(knowledge_items_fts) AS rank
|
|
@@ -162,13 +294,16 @@ function searchKnowledgeItems(input) {
|
|
|
162
294
|
AND (k.expires_at IS NULL OR k.expires_at >= ?)
|
|
163
295
|
${input.recordClass ? "AND k.record_class = ?" : ""}
|
|
164
296
|
${input.trustedOnly ? "AND k.origin_class != 'untrusted'" : ""}
|
|
165
|
-
|
|
297
|
+
AND ${contentSource}
|
|
166
298
|
AND ${visible.sql}
|
|
167
|
-
ORDER BY rank ASC, k.importance DESC, k.updated_at DESC LIMIT ?`).all(fts, principalId, asOf, asOf, asOf, ...input.recordClass ? [input.recordClass] : [], ...
|
|
299
|
+
ORDER BY rank ASC, k.importance DESC, k.updated_at DESC LIMIT ?`).all(fts, principalId, asOf, asOf, asOf, ...input.recordClass ? [input.recordClass] : [], ...visible.values, limit).map(fromRow);
|
|
300
|
+
}
|
|
301
|
+
function classifyKnowledgeContentSource(item) {
|
|
302
|
+
if (item.recordClass === "memory") return "memory";
|
|
303
|
+
return item.source.kind === "product_import" ? "local_import" : "connector";
|
|
168
304
|
}
|
|
169
|
-
function
|
|
170
|
-
|
|
171
|
-
return item.scope.type === "session" ? sources.includes("session") : item.scope.type === "workspace" ? sources.includes("workspace") : item.scope.type === "project" ? sources.includes("project") : false;
|
|
305
|
+
function knowledgeItemAllowed(item, policy) {
|
|
306
|
+
return policy.scopes.includes(item.scope.type) && policy.contentSources.includes(classifyKnowledgeContentSource(item));
|
|
172
307
|
}
|
|
173
308
|
//#endregion
|
|
174
|
-
export { getKnowledgeItem,
|
|
309
|
+
export { KnowledgeReviewConflictError, classifyKnowledgeContentSource, getKnowledgeItem, knowledgeItemAllowed, listKnowledgeItems, listKnowledgeStatusEvents, reviewKnowledgeItem, searchKnowledgeItems, transitionKnowledgeStatus, writeKnowledgeItem };
|
|
@@ -62,10 +62,14 @@ var XopcChannelBridge = class {
|
|
|
62
62
|
issueTicket: async () => {
|
|
63
63
|
const response = await this.client.postJson("/api/realtime/tickets", {
|
|
64
64
|
clientId: this.realtimeClientId,
|
|
65
|
-
clientKind: "mcp"
|
|
65
|
+
clientKind: "mcp",
|
|
66
|
+
protocolVersion: 2
|
|
66
67
|
});
|
|
67
|
-
if (!response.payload?.ticket) throw new Error(response.error?.message ?? "Realtime ticket response is invalid");
|
|
68
|
-
return
|
|
68
|
+
if (!response.payload?.ticket || !response.payload.realtime) throw new Error(response.error?.message ?? "Realtime ticket response is invalid");
|
|
69
|
+
return {
|
|
70
|
+
ticket: response.payload.ticket,
|
|
71
|
+
realtime: response.payload.realtime
|
|
72
|
+
};
|
|
69
73
|
},
|
|
70
74
|
createWebSocket: (url) => new WebSocket(url),
|
|
71
75
|
onEvent: (event) => this.handleRealtimeEvent(event),
|
|
@@ -14,6 +14,7 @@ function indexProvider(provider) {
|
|
|
14
14
|
}
|
|
15
15
|
function registerMediaUnderstandingProvider(provider) {
|
|
16
16
|
const keys = indexProvider(provider);
|
|
17
|
+
const previous = new Map(keys.map((key) => [key, registry.get(key)]));
|
|
17
18
|
const conflicts = keys.filter((key) => registry.has(key));
|
|
18
19
|
if (conflicts.length > 0) log.warn({
|
|
19
20
|
providerId: provider.id,
|
|
@@ -21,7 +22,11 @@ function registerMediaUnderstandingProvider(provider) {
|
|
|
21
22
|
}, `Media-understanding provider "${provider.id}" overrides existing registration(s): ${conflicts.join(", ")}`);
|
|
22
23
|
for (const key of keys) registry.set(key, provider);
|
|
23
24
|
return () => {
|
|
24
|
-
for (const key of keys) if (registry.get(key) === provider)
|
|
25
|
+
for (const key of keys) if (registry.get(key) === provider) {
|
|
26
|
+
const prior = previous.get(key);
|
|
27
|
+
if (prior) registry.set(key, prior);
|
|
28
|
+
else registry.delete(key);
|
|
29
|
+
}
|
|
25
30
|
};
|
|
26
31
|
}
|
|
27
32
|
function getMediaUnderstandingProvider(id) {
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { init_config, normalizeKnowledgeMemoryConfigInput } from "../user-context/config.js";
|
|
2
|
+
import { init_lock, isGatewayConfigLockedByAnotherProcessSync } from "../gateway/lock.js";
|
|
3
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
4
|
+
//#region src/migrations/knowledge-memory-read-policy-config.ts
|
|
5
|
+
init_lock();
|
|
6
|
+
init_config();
|
|
7
|
+
const id = "knowledge-memory-read-policy-config";
|
|
8
|
+
function convertedConfig(ctx) {
|
|
9
|
+
if (!existsSync(ctx.configPath)) return null;
|
|
10
|
+
const config = JSON.parse(readFileSync(ctx.configPath, "utf8"));
|
|
11
|
+
const userContext = config.userContext;
|
|
12
|
+
if (!userContext || typeof userContext !== "object" || Array.isArray(userContext)) return null;
|
|
13
|
+
const knowledgeMemory = userContext.knowledgeMemory;
|
|
14
|
+
if (!knowledgeMemory || typeof knowledgeMemory !== "object" || Array.isArray(knowledgeMemory)) return null;
|
|
15
|
+
const memory = knowledgeMemory;
|
|
16
|
+
if (!Array.isArray(memory.sources)) return null;
|
|
17
|
+
userContext.knowledgeMemory = normalizeKnowledgeMemoryConfigInput(memory);
|
|
18
|
+
return config;
|
|
19
|
+
}
|
|
20
|
+
function item(status) {
|
|
21
|
+
return {
|
|
22
|
+
id,
|
|
23
|
+
title: "Knowledge memory read policy configuration",
|
|
24
|
+
kind: "config",
|
|
25
|
+
safety: "auto",
|
|
26
|
+
status,
|
|
27
|
+
message: "Split knowledge memory visibility scopes from content sources."
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
const knowledgeMemoryReadPolicyConfigMigration = {
|
|
31
|
+
id,
|
|
32
|
+
kind: "config",
|
|
33
|
+
safety: "auto",
|
|
34
|
+
detect: (ctx) => convertedConfig(ctx) ? item("planned") : null,
|
|
35
|
+
apply: (ctx) => {
|
|
36
|
+
if (isGatewayConfigLockedByAnotherProcessSync(ctx.configPath)) return {
|
|
37
|
+
...item("skipped"),
|
|
38
|
+
message: "Deferred knowledge memory config migration until the running gateway restarts."
|
|
39
|
+
};
|
|
40
|
+
const config = convertedConfig(ctx);
|
|
41
|
+
return config ? {
|
|
42
|
+
...item("applied"),
|
|
43
|
+
details: { config }
|
|
44
|
+
} : item("not_needed");
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
//#endregion
|
|
48
|
+
export { knowledgeMemoryReadPolicyConfigMigration };
|
|
@@ -3,6 +3,7 @@ import { init_logger } from "../utils/logger.js";
|
|
|
3
3
|
import { ConfigSchema, init_schema } from "../config/schema.js";
|
|
4
4
|
import { listRegisteredMigrations } from "./registry.js";
|
|
5
5
|
import { conversationRoutingConfigMigration } from "./conversation-routing-config.js";
|
|
6
|
+
import { knowledgeMemoryReadPolicyConfigMigration } from "./knowledge-memory-read-policy-config.js";
|
|
6
7
|
import { dirname, join } from "node:path";
|
|
7
8
|
import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
|
|
8
9
|
//#region src/migrations/runner.ts
|
|
@@ -11,7 +12,7 @@ init_logger();
|
|
|
11
12
|
const log = createLogger("Migrations");
|
|
12
13
|
const MIGRATION_LEDGER_FILENAME = "migrations.json";
|
|
13
14
|
const CONFIG_BACKUP_COUNT = 10;
|
|
14
|
-
const CORE_MIGRATIONS = [conversationRoutingConfigMigration];
|
|
15
|
+
const CORE_MIGRATIONS = [conversationRoutingConfigMigration, knowledgeMemoryReadPolicyConfigMigration];
|
|
15
16
|
function listAllMigrations() {
|
|
16
17
|
return [...CORE_MIGRATIONS, ...listRegisteredMigrations().map((entry) => entry.migration)];
|
|
17
18
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface BoundedOutput {
|
|
2
|
+
readonly text: string;
|
|
3
|
+
readonly totalBytes: number;
|
|
4
|
+
readonly truncated: boolean;
|
|
5
|
+
}
|
|
6
|
+
/** Keeps the newest bytes so failures retain their most useful tail output. */
|
|
7
|
+
export declare function createBoundedOutput(maxBytes: number): {
|
|
8
|
+
append(chunk: Buffer | string): void;
|
|
9
|
+
snapshot(): BoundedOutput;
|
|
10
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
//#region src/process/bounded-output.ts
|
|
2
|
+
/** Keeps the newest bytes so failures retain their most useful tail output. */
|
|
3
|
+
function createBoundedOutput(maxBytes) {
|
|
4
|
+
const limit = Math.max(0, Math.floor(maxBytes));
|
|
5
|
+
let chunks = [];
|
|
6
|
+
let capturedBytes = 0;
|
|
7
|
+
let totalBytes = 0;
|
|
8
|
+
return {
|
|
9
|
+
append(chunk) {
|
|
10
|
+
const value = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
11
|
+
totalBytes += value.byteLength;
|
|
12
|
+
if (limit === 0) {
|
|
13
|
+
chunks = [];
|
|
14
|
+
capturedBytes = 0;
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
chunks.push(value);
|
|
18
|
+
capturedBytes += value.byteLength;
|
|
19
|
+
while (capturedBytes > limit && chunks.length > 0) {
|
|
20
|
+
const excess = capturedBytes - limit;
|
|
21
|
+
const first = chunks[0];
|
|
22
|
+
if (first.byteLength <= excess) {
|
|
23
|
+
chunks.shift();
|
|
24
|
+
capturedBytes -= first.byteLength;
|
|
25
|
+
} else {
|
|
26
|
+
chunks[0] = first.subarray(excess);
|
|
27
|
+
capturedBytes -= excess;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
snapshot() {
|
|
32
|
+
return {
|
|
33
|
+
text: Buffer.concat(chunks, capturedBytes).toString("utf8"),
|
|
34
|
+
totalBytes,
|
|
35
|
+
truncated: totalBytes > capturedBytes
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
//#endregion
|
|
41
|
+
export { createBoundedOutput };
|
|
@@ -1,18 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
* - Unix: send SIGTERM to process group first, wait grace period, then SIGKILL.
|
|
6
|
-
*
|
|
7
|
-
* This gives child processes a chance to clean up (close connections, remove
|
|
8
|
-
* temp files, terminate their own children) before being hard-killed.
|
|
9
|
-
*
|
|
10
|
-
* When the child was spawned with `detached: false` (e.g. service-managed
|
|
11
|
-
* runtime under launchd/systemd), pass `detached: false` to skip the Unix
|
|
12
|
-
* `process.kill(-pid, ...)` group-kill — it would otherwise target the
|
|
13
|
-
* gateway's own process group and SIGTERM the gateway itself. (#71662)
|
|
14
|
-
*/
|
|
15
|
-
export declare function killProcessTree(pid: number, opts?: {
|
|
16
|
-
graceMs?: number;
|
|
1
|
+
import { type ChildProcess } from 'node:child_process';
|
|
2
|
+
/** Terminates a child and optionally its process tree, escalating after a grace period. */
|
|
3
|
+
export declare function terminateProcess(child: ChildProcess, options?: {
|
|
4
|
+
tree?: boolean;
|
|
17
5
|
detached?: boolean;
|
|
18
|
-
|
|
6
|
+
graceMs?: number;
|
|
7
|
+
}): Promise<boolean>;
|
|
@@ -1,35 +1,7 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
2
|
//#region src/process/kill-tree.ts
|
|
3
3
|
const DEFAULT_GRACE_MS = 3e3;
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Best-effort process-tree termination with graceful shutdown.
|
|
7
|
-
* - Windows: use taskkill /T to include descendants. Sends SIGTERM-equivalent
|
|
8
|
-
* first (without /F), then force-kills if process survives.
|
|
9
|
-
* - Unix: send SIGTERM to process group first, wait grace period, then SIGKILL.
|
|
10
|
-
*
|
|
11
|
-
* This gives child processes a chance to clean up (close connections, remove
|
|
12
|
-
* temp files, terminate their own children) before being hard-killed.
|
|
13
|
-
*
|
|
14
|
-
* When the child was spawned with `detached: false` (e.g. service-managed
|
|
15
|
-
* runtime under launchd/systemd), pass `detached: false` to skip the Unix
|
|
16
|
-
* `process.kill(-pid, ...)` group-kill — it would otherwise target the
|
|
17
|
-
* gateway's own process group and SIGTERM the gateway itself. (#71662)
|
|
18
|
-
*/
|
|
19
|
-
function killProcessTree(pid, opts) {
|
|
20
|
-
if (!Number.isFinite(pid) || pid <= 0) return;
|
|
21
|
-
const graceMs = normalizeGraceMs(opts?.graceMs);
|
|
22
|
-
if (process.platform === "win32") {
|
|
23
|
-
killProcessTreeWindows(pid, graceMs);
|
|
24
|
-
return;
|
|
25
|
-
}
|
|
26
|
-
killProcessTreeUnix(pid, graceMs, opts?.detached !== false);
|
|
27
|
-
}
|
|
28
|
-
function normalizeGraceMs(value) {
|
|
29
|
-
if (typeof value !== "number" || !Number.isFinite(value)) return DEFAULT_GRACE_MS;
|
|
30
|
-
return Math.max(0, Math.min(MAX_GRACE_MS, Math.floor(value)));
|
|
31
|
-
}
|
|
32
|
-
function isProcessAlive(pid) {
|
|
4
|
+
function processAlive(pid) {
|
|
33
5
|
try {
|
|
34
6
|
process.kill(pid, 0);
|
|
35
7
|
return true;
|
|
@@ -37,56 +9,52 @@ function isProcessAlive(pid) {
|
|
|
37
9
|
return false;
|
|
38
10
|
}
|
|
39
11
|
}
|
|
40
|
-
function
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}
|
|
44
|
-
try {
|
|
45
|
-
process.kill(pid, "SIGTERM");
|
|
46
|
-
} catch {
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
else try {
|
|
51
|
-
process.kill(pid, "SIGTERM");
|
|
52
|
-
} catch {
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
setTimeout(() => {
|
|
56
|
-
if (useGroupKill && isProcessAlive(-pid)) try {
|
|
57
|
-
process.kill(-pid, "SIGKILL");
|
|
58
|
-
return;
|
|
59
|
-
} catch {}
|
|
60
|
-
if (!isProcessAlive(pid)) return;
|
|
61
|
-
try {
|
|
62
|
-
process.kill(pid, "SIGKILL");
|
|
63
|
-
} catch {}
|
|
64
|
-
}, graceMs).unref();
|
|
12
|
+
function delay(ms) {
|
|
13
|
+
return new Promise((resolve) => {
|
|
14
|
+
setTimeout(resolve, ms).unref();
|
|
15
|
+
});
|
|
65
16
|
}
|
|
66
|
-
function
|
|
67
|
-
|
|
68
|
-
spawn("taskkill",
|
|
17
|
+
function taskkill(pid, force) {
|
|
18
|
+
return new Promise((resolve) => {
|
|
19
|
+
const child = spawn("taskkill", [
|
|
20
|
+
...force ? ["/F"] : [],
|
|
21
|
+
"/T",
|
|
22
|
+
"/PID",
|
|
23
|
+
String(pid)
|
|
24
|
+
], {
|
|
69
25
|
stdio: "ignore",
|
|
70
|
-
detached: true,
|
|
71
26
|
windowsHide: true
|
|
72
27
|
});
|
|
73
|
-
|
|
28
|
+
child.once("error", () => resolve());
|
|
29
|
+
child.once("close", () => resolve());
|
|
30
|
+
});
|
|
74
31
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
if (
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}
|
|
32
|
+
/** Terminates a child and optionally its process tree, escalating after a grace period. */
|
|
33
|
+
async function terminateProcess(child, options = {}) {
|
|
34
|
+
const pid = child.pid;
|
|
35
|
+
if (!pid || child.exitCode !== null || child.signalCode !== null) return true;
|
|
36
|
+
const graceMs = Math.max(0, Math.min(6e4, Math.floor(options.graceMs ?? DEFAULT_GRACE_MS)));
|
|
37
|
+
if (process.platform === "win32" && options.tree) {
|
|
38
|
+
await taskkill(pid, false);
|
|
39
|
+
if (graceMs > 0 && processAlive(pid)) await delay(graceMs);
|
|
40
|
+
if (processAlive(pid)) await taskkill(pid, true);
|
|
41
|
+
return !processAlive(pid);
|
|
42
|
+
}
|
|
43
|
+
const target = options.tree && options.detached ? -pid : pid;
|
|
44
|
+
try {
|
|
45
|
+
process.kill(target, "SIGTERM");
|
|
46
|
+
} catch {
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
if (graceMs > 0 && processAlive(pid)) await delay(graceMs);
|
|
50
|
+
if (processAlive(pid)) try {
|
|
51
|
+
process.kill(target, "SIGKILL");
|
|
52
|
+
} catch {
|
|
53
|
+
try {
|
|
54
|
+
child.kill("SIGKILL");
|
|
55
|
+
} catch {}
|
|
56
|
+
}
|
|
57
|
+
return !processAlive(pid);
|
|
90
58
|
}
|
|
91
59
|
//#endregion
|
|
92
|
-
export {
|
|
60
|
+
export { terminateProcess };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { ChildProcess, SpawnOptions } from 'node:child_process';
|
|
2
|
+
export interface ProcessSpec {
|
|
3
|
+
program: string;
|
|
4
|
+
args?: readonly string[];
|
|
5
|
+
cwd?: string;
|
|
6
|
+
env?: NodeJS.ProcessEnv;
|
|
7
|
+
input?: string | Buffer;
|
|
8
|
+
keepStdinOpen?: boolean;
|
|
9
|
+
timeoutMs?: number | null;
|
|
10
|
+
maxOutputBytes?: number;
|
|
11
|
+
signal?: AbortSignal;
|
|
12
|
+
detached?: boolean;
|
|
13
|
+
windowsHide?: boolean;
|
|
14
|
+
shell?: SpawnOptions['shell'];
|
|
15
|
+
terminationPolicy?: 'root' | 'tree';
|
|
16
|
+
onOutput?: (stream: 'stdout' | 'stderr', chunk: Buffer) => void;
|
|
17
|
+
}
|
|
18
|
+
export interface ProcessResult {
|
|
19
|
+
exitCode: number | null;
|
|
20
|
+
spawnErrorCode?: string;
|
|
21
|
+
signal: NodeJS.Signals | null;
|
|
22
|
+
stdout: string;
|
|
23
|
+
stderr: string;
|
|
24
|
+
timedOut: boolean;
|
|
25
|
+
aborted: boolean;
|
|
26
|
+
outputTruncated: boolean;
|
|
27
|
+
terminationVerified: boolean;
|
|
28
|
+
}
|
|
29
|
+
export interface ProcessHandle {
|
|
30
|
+
readonly child: ChildProcess;
|
|
31
|
+
readonly completion: Promise<ProcessResult>;
|
|
32
|
+
terminate(reason?: 'cancelled' | 'timed_out'): void;
|
|
33
|
+
}
|
|
34
|
+
export declare class ProcessExitError extends Error {
|
|
35
|
+
readonly spec: ProcessSpec;
|
|
36
|
+
readonly result: ProcessResult;
|
|
37
|
+
readonly code: number | string | null;
|
|
38
|
+
constructor(spec: ProcessSpec, result: ProcessResult);
|
|
39
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//#region src/process/process-spec.ts
|
|
2
|
+
var ProcessExitError = class extends Error {
|
|
3
|
+
code;
|
|
4
|
+
constructor(spec, result) {
|
|
5
|
+
super(result.stderr.trim() || `Process exited with code ${String(result.exitCode)}`);
|
|
6
|
+
this.spec = spec;
|
|
7
|
+
this.result = result;
|
|
8
|
+
this.name = "ProcessExitError";
|
|
9
|
+
this.code = result.spawnErrorCode ?? result.exitCode;
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
//#endregion
|
|
13
|
+
export { ProcessExitError };
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { type ProcessHandle, type ProcessResult, type ProcessSpec } from './process-spec.js';
|
|
2
|
+
export declare function spawnProcess(spec: ProcessSpec): ProcessHandle;
|
|
3
|
+
export declare function runProcess(spec: ProcessSpec): Promise<ProcessResult>;
|
|
4
|
+
export declare function runProcessChecked(spec: ProcessSpec): Promise<ProcessResult>;
|