@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
package/dist/src/tui/tui.js
CHANGED
|
@@ -21,7 +21,7 @@ import { copyTextToClipboard } from "./clipboard-text.js";
|
|
|
21
21
|
import { createXopcTuiKeybindingsManager } from "./tui-keybindings-file.js";
|
|
22
22
|
import { isActiveRunStreamStale, markActiveRunStalled, markRunRecovering, markRunRecoveryComplete, markRunSending } from "./tui-run-state.js";
|
|
23
23
|
import { clearSeenStreamEvents, clearSeenStreamEventsForRun, dispatchAgentEvent } from "./tui-agent-events.js";
|
|
24
|
-
import {
|
|
24
|
+
import { acceptChatInputState, createEmptyChatInputState, findLastEditableChatInput } from "./tui-chat-input-state.js";
|
|
25
25
|
import { transcriptTreeEntryIdToRowNumber } from "./tui-transcript-tree.js";
|
|
26
26
|
import { formatTuiCompactionResult, formatTuiShareResult } from "./tui-command-formatters.js";
|
|
27
27
|
import { formatTuiStartupText } from "./tui-startup-text.js";
|
|
@@ -50,6 +50,8 @@ import { GatewayRealtimeBackend } from "./backends/gateway-realtime-backend.js";
|
|
|
50
50
|
import { ChatLog } from "./components/chat-log.js";
|
|
51
51
|
import { CustomEditor } from "./components/custom-editor.js";
|
|
52
52
|
import { TuiBottomBar } from "./components/tui-bottom-bar.js";
|
|
53
|
+
import { PendingInputPreview } from "./components/pending-input-preview.js";
|
|
54
|
+
import { TranscriptOverlay } from "./components/transcript-overlay.js";
|
|
53
55
|
import { TuiHeader } from "./components/tui-header.js";
|
|
54
56
|
import { loadExtensionsForTuiLocalMode } from "./extension-host/load-extensions.js";
|
|
55
57
|
import { createTuiExtensionRuntime } from "./extension-host/runtime.js";
|
|
@@ -263,6 +265,7 @@ async function runTui(opts) {
|
|
|
263
265
|
}), keybindings);
|
|
264
266
|
const statusContainer = new Container();
|
|
265
267
|
const bottomBar = new TuiBottomBar(() => state, () => opts.thinking);
|
|
268
|
+
const pendingInputPreview = new PendingInputPreview(() => state.chatInputState, keybindings);
|
|
266
269
|
const chatLog = new ChatLog(keybindings);
|
|
267
270
|
chatLog.setViewportRowsProvider(() => Math.max(8, tui.terminal.rows - 8));
|
|
268
271
|
let startupResources;
|
|
@@ -372,6 +375,7 @@ async function runTui(opts) {
|
|
|
372
375
|
root.addChild(header);
|
|
373
376
|
root.addChild(chatLog);
|
|
374
377
|
root.addChild(statusContainer);
|
|
378
|
+
root.addChild(pendingInputPreview);
|
|
375
379
|
root.addChild(editorContainer);
|
|
376
380
|
root.addChild(bottomBar);
|
|
377
381
|
tui.addChild(root);
|
|
@@ -1458,6 +1462,20 @@ async function runTui(opts) {
|
|
|
1458
1462
|
})();
|
|
1459
1463
|
};
|
|
1460
1464
|
const isAgentBusy = () => state.activeRunId != null || state.isCompacting || busyStates.has(state.activityStatus);
|
|
1465
|
+
let editingQueuedInput;
|
|
1466
|
+
const applyChatInputState = (incoming) => {
|
|
1467
|
+
if (incoming.conversationId !== state.currentConversationId) return;
|
|
1468
|
+
const next = acceptChatInputState(state.chatInputState, incoming);
|
|
1469
|
+
if (next === state.chatInputState) return;
|
|
1470
|
+
state.chatInputState = next;
|
|
1471
|
+
if (editingQueuedInput) {
|
|
1472
|
+
const edited = next.inputs.find((input) => input.id === editingQueuedInput?.id);
|
|
1473
|
+
if (!edited || edited.version !== editingQueuedInput.version) editingQueuedInput = void 0;
|
|
1474
|
+
}
|
|
1475
|
+
pendingInputPreview.invalidate();
|
|
1476
|
+
bottomBar.invalidate();
|
|
1477
|
+
tui.requestRender();
|
|
1478
|
+
};
|
|
1461
1479
|
const sendSteeringToActiveRun = (text) => {
|
|
1462
1480
|
touchStreamingActivity();
|
|
1463
1481
|
tui.requestRender();
|
|
@@ -1465,15 +1483,12 @@ async function runTui(opts) {
|
|
|
1465
1483
|
conversationId: state.currentConversationId,
|
|
1466
1484
|
message: text,
|
|
1467
1485
|
delivery: "steer"
|
|
1468
|
-
}).then(({ ok,
|
|
1486
|
+
}).then(({ ok, state: inputState }) => {
|
|
1469
1487
|
if (!ok) {
|
|
1470
1488
|
if (!editor.getText().trim()) editor.setText(text);
|
|
1471
1489
|
chatLog.addSystem(theme.dim(formatSteerUnavailableHint(keybindings)));
|
|
1472
|
-
} else
|
|
1473
|
-
|
|
1474
|
-
chatLog.addSystem(theme.dim(effectiveDelivery === "steer" ? "Added to this reply." : "Queued as the next message."));
|
|
1475
|
-
refreshPendingInputCount();
|
|
1476
|
-
}
|
|
1490
|
+
} else if (inputState) applyChatInputState(inputState);
|
|
1491
|
+
else refreshChatInputState();
|
|
1477
1492
|
tui.requestRender();
|
|
1478
1493
|
}).catch((error) => {
|
|
1479
1494
|
if (!editor.getText().trim()) editor.setText(text);
|
|
@@ -1831,15 +1846,10 @@ async function runTui(opts) {
|
|
|
1831
1846
|
applyComposerHistory(await client.getComposerInputHistory());
|
|
1832
1847
|
} catch {}
|
|
1833
1848
|
};
|
|
1834
|
-
const
|
|
1849
|
+
const refreshChatInputState = async (conversationId = state.currentConversationId) => {
|
|
1835
1850
|
try {
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
} catch {
|
|
1839
|
-
if (state.currentConversationId === conversationId) state.pendingInputCount = 0;
|
|
1840
|
-
}
|
|
1841
|
-
bottomBar.invalidate();
|
|
1842
|
-
tui.requestRender();
|
|
1851
|
+
applyChatInputState(await client.getChatInputState(conversationId));
|
|
1852
|
+
} catch {}
|
|
1843
1853
|
};
|
|
1844
1854
|
const recordChatHistory = (value) => {
|
|
1845
1855
|
const text = value.trim();
|
|
@@ -1879,10 +1889,37 @@ async function runTui(opts) {
|
|
|
1879
1889
|
}),
|
|
1880
1890
|
enabled: shouldEnableWindowsGitBashPasteFallback()
|
|
1881
1891
|
});
|
|
1882
|
-
|
|
1892
|
+
const saveEditedQueuedInput = (text) => {
|
|
1893
|
+
const target = editingQueuedInput;
|
|
1894
|
+
if (!target) return false;
|
|
1895
|
+
const content = text.trim();
|
|
1896
|
+
if (!content) return true;
|
|
1897
|
+
const conversationId = state.currentConversationId;
|
|
1898
|
+
client.updateChatInput({
|
|
1899
|
+
conversationId,
|
|
1900
|
+
inputId: target.id,
|
|
1901
|
+
version: target.version,
|
|
1902
|
+
content
|
|
1903
|
+
}).then(({ ok, state: inputState }) => {
|
|
1904
|
+
if (inputState) applyChatInputState(inputState);
|
|
1905
|
+
if (!ok) throw new Error("Queued input changed; refreshed latest state");
|
|
1906
|
+
editingQueuedInput = void 0;
|
|
1907
|
+
if (state.currentConversationId === conversationId && editor.getText().trim() === content) editor.setText("");
|
|
1908
|
+
recordChatHistory(content);
|
|
1909
|
+
tui.requestRender();
|
|
1910
|
+
}).catch((error) => {
|
|
1911
|
+
chatLog.addSystem(theme.dim(`Edit failed: ${error instanceof Error ? error.message : String(error)}`));
|
|
1912
|
+
tui.requestRender();
|
|
1913
|
+
});
|
|
1914
|
+
return true;
|
|
1915
|
+
};
|
|
1916
|
+
defaultEditor.onSubmit = (text) => {
|
|
1917
|
+
if (!saveEditedQueuedInput(text)) submitBurst(text);
|
|
1918
|
+
};
|
|
1883
1919
|
const handleFollowUp = () => {
|
|
1884
1920
|
const text = editor.getText().trim();
|
|
1885
1921
|
if (!text && pendingImageAttachments.length === 0) return;
|
|
1922
|
+
if (saveEditedQueuedInput(text)) return;
|
|
1886
1923
|
if (isAgentBusy()) {
|
|
1887
1924
|
if (pendingImageAttachments.length > 0) {
|
|
1888
1925
|
chatLog.addSystem(theme.dim("Image attachments cannot be queued while the agent is busy. Wait for this reply to finish, then send."));
|
|
@@ -1894,12 +1931,12 @@ async function runTui(opts) {
|
|
|
1894
1931
|
conversationId,
|
|
1895
1932
|
message: text,
|
|
1896
1933
|
delivery: "next"
|
|
1897
|
-
}).then(
|
|
1934
|
+
}).then(({ ok, state: inputState }) => {
|
|
1898
1935
|
if (!ok) throw new Error("Gateway did not accept the message");
|
|
1899
1936
|
recordChatHistory(text);
|
|
1900
1937
|
if (state.currentConversationId === conversationId && editor.getText().trim() === text) editor.setText("");
|
|
1901
|
-
|
|
1902
|
-
|
|
1938
|
+
if (inputState) applyChatInputState(inputState);
|
|
1939
|
+
else refreshChatInputState(conversationId);
|
|
1903
1940
|
}).catch((error) => {
|
|
1904
1941
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1905
1942
|
chatLog.addSystem(theme.dim(`Queue failed: ${errorMessage}`));
|
|
@@ -1911,8 +1948,9 @@ async function runTui(opts) {
|
|
|
1911
1948
|
};
|
|
1912
1949
|
const setConversationId = (key) => {
|
|
1913
1950
|
state.currentConversationId = resolveConversationId(key);
|
|
1914
|
-
state.
|
|
1915
|
-
|
|
1951
|
+
state.chatInputState = createEmptyChatInputState(state.currentConversationId);
|
|
1952
|
+
editingQueuedInput = void 0;
|
|
1953
|
+
refreshChatInputState(state.currentConversationId);
|
|
1916
1954
|
updateAgentFromPicker(key);
|
|
1917
1955
|
};
|
|
1918
1956
|
const updateAgentFromPicker = (key) => {
|
|
@@ -2105,6 +2143,66 @@ async function runTui(opts) {
|
|
|
2105
2143
|
})();
|
|
2106
2144
|
};
|
|
2107
2145
|
defaultEditor.onAction("app.message.followUp", handleFollowUp);
|
|
2146
|
+
defaultEditor.onAction("app.message.editQueued", () => {
|
|
2147
|
+
if (editor.getText().length > 0) return false;
|
|
2148
|
+
const target = findLastEditableChatInput(state.chatInputState);
|
|
2149
|
+
if (!target) return false;
|
|
2150
|
+
editingQueuedInput = {
|
|
2151
|
+
id: target.id,
|
|
2152
|
+
version: target.version
|
|
2153
|
+
};
|
|
2154
|
+
editor.setText(target.content);
|
|
2155
|
+
tui.requestRender();
|
|
2156
|
+
return true;
|
|
2157
|
+
});
|
|
2158
|
+
defaultEditor.onAction("app.message.deleteQueued", () => {
|
|
2159
|
+
const target = findLastEditableChatInput(state.chatInputState);
|
|
2160
|
+
if (!target) return false;
|
|
2161
|
+
const conversationId = state.currentConversationId;
|
|
2162
|
+
client.removeChatInput({
|
|
2163
|
+
conversationId,
|
|
2164
|
+
inputId: target.id,
|
|
2165
|
+
version: target.version
|
|
2166
|
+
}).then(({ ok, state: inputState }) => {
|
|
2167
|
+
if (inputState) applyChatInputState(inputState);
|
|
2168
|
+
if (!ok) throw new Error("Queued input changed; refreshed latest state");
|
|
2169
|
+
if (editingQueuedInput?.id === target.id) editingQueuedInput = void 0;
|
|
2170
|
+
tui.requestRender();
|
|
2171
|
+
}).catch((error) => {
|
|
2172
|
+
chatLog.addSystem(theme.dim(`Delete failed: ${error instanceof Error ? error.message : String(error)}`));
|
|
2173
|
+
tui.requestRender();
|
|
2174
|
+
});
|
|
2175
|
+
return true;
|
|
2176
|
+
});
|
|
2177
|
+
const openTranscriptOverlay = (initialMode) => {
|
|
2178
|
+
if (!client.loadHistoryWindow) {
|
|
2179
|
+
chatLog.addSystem("Transcript paging is unavailable for this backend.");
|
|
2180
|
+
tui.requestRender();
|
|
2181
|
+
return;
|
|
2182
|
+
}
|
|
2183
|
+
let close = () => {};
|
|
2184
|
+
const overlay = new TranscriptOverlay({
|
|
2185
|
+
keybindings,
|
|
2186
|
+
initialMode,
|
|
2187
|
+
viewportRows: () => tui.terminal.rows,
|
|
2188
|
+
onClose: () => close(),
|
|
2189
|
+
onRender: () => tui.requestRender(),
|
|
2190
|
+
loadWindow: (rowNumber) => client.loadHistoryWindow({
|
|
2191
|
+
conversationId: state.currentConversationId,
|
|
2192
|
+
rowNumber,
|
|
2193
|
+
before: 120,
|
|
2194
|
+
after: 0
|
|
2195
|
+
})
|
|
2196
|
+
});
|
|
2197
|
+
close = openEditorSelector(overlay, overlay);
|
|
2198
|
+
overlay.initialize().catch((error) => {
|
|
2199
|
+
close();
|
|
2200
|
+
chatLog.addSystem(`Transcript failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
2201
|
+
tui.requestRender();
|
|
2202
|
+
});
|
|
2203
|
+
};
|
|
2204
|
+
defaultEditor.onAction("app.transcript.open", () => openTranscriptOverlay("transcript"));
|
|
2205
|
+
defaultEditor.onAction("app.transcript.raw", () => openTranscriptOverlay("raw"));
|
|
2108
2206
|
streamWatchdogId = setInterval(() => {
|
|
2109
2207
|
const now = Date.now();
|
|
2110
2208
|
if (!isActiveRunStreamStale(state, now, 3e4)) return;
|
|
@@ -2141,11 +2239,7 @@ async function runTui(opts) {
|
|
|
2141
2239
|
client.onEvent = (evt) => {
|
|
2142
2240
|
const data = evt.data ?? {};
|
|
2143
2241
|
if (evt.event === "session.input-state") {
|
|
2144
|
-
if (data.conversationId === state.currentConversationId && Array.isArray(data.inputs))
|
|
2145
|
-
state.pendingInputCount = countPendingChatInputs(data.inputs);
|
|
2146
|
-
bottomBar.invalidate();
|
|
2147
|
-
tui.requestRender();
|
|
2148
|
-
}
|
|
2242
|
+
if (data.conversationId === state.currentConversationId && Array.isArray(data.inputs) && typeof data.revision === "number") applyChatInputState(data);
|
|
2149
2243
|
return;
|
|
2150
2244
|
}
|
|
2151
2245
|
if (evt.event === "composer-history.appended") {
|
|
@@ -2216,10 +2310,8 @@ async function runTui(opts) {
|
|
|
2216
2310
|
await refreshSessionInfoWithBorder();
|
|
2217
2311
|
persistCurrentNewSessionContext();
|
|
2218
2312
|
try {
|
|
2219
|
-
|
|
2220
|
-
} catch {
|
|
2221
|
-
state.pendingInputCount = 0;
|
|
2222
|
-
}
|
|
2313
|
+
applyChatInputState(await client.getChatInputState(state.currentConversationId));
|
|
2314
|
+
} catch {}
|
|
2223
2315
|
await refreshModelChoices();
|
|
2224
2316
|
await loadSessionHistory({ merge: true });
|
|
2225
2317
|
cleanupAbandonedTuiSessions(client, state.currentConversationId).catch(() => {});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** App-level bindings wired by xopc TUI (subset of pi coding-agent). */
|
|
2
|
-
export type XopcTuiAppKeybinding = 'app.interrupt' | 'app.clear' | 'app.exit' | 'app.suspend' | 'app.thinking.cycle' | 'app.model.cycleForward' | 'app.model.cycleBackward' | 'app.model.select' | 'app.tools.expand' | 'app.thinking.toggle' | 'app.session.resume' | 'app.session.tree' | 'app.session.fork' | 'app.session.togglePath' | 'app.session.toggleSort' | 'app.session.toggleNamedFilter' | 'app.session.rename' | 'app.session.delete' | 'app.session.deleteNoninvasive' | 'app.tree.foldOrUp' | 'app.tree.unfoldOrDown' | 'app.tree.filter.default' | 'app.tree.filter.noTools' | 'app.tree.filter.userOnly' | 'app.tree.filter.labeledOnly' | 'app.tree.filter.all' | 'app.tree.filter.cycleForward' | 'app.tree.filter.cycleBackward' | 'app.tree.editLabel' | 'app.tree.toggleLabelTimestamp' | 'app.editor.external' | 'app.clipboard.pasteImage' | 'app.message.followUp' | 'app.models.save' | 'app.models.enableAll' | 'app.models.clearAll' | 'app.models.toggleProvider' | 'app.models.reorderUp' | 'app.models.reorderDown';
|
|
2
|
+
export type XopcTuiAppKeybinding = 'app.interrupt' | 'app.clear' | 'app.exit' | 'app.suspend' | 'app.thinking.cycle' | 'app.model.cycleForward' | 'app.model.cycleBackward' | 'app.model.select' | 'app.tools.expand' | 'app.thinking.toggle' | 'app.transcript.open' | 'app.transcript.raw' | 'app.session.resume' | 'app.session.tree' | 'app.session.fork' | 'app.session.togglePath' | 'app.session.toggleSort' | 'app.session.toggleNamedFilter' | 'app.session.rename' | 'app.session.delete' | 'app.session.deleteNoninvasive' | 'app.tree.foldOrUp' | 'app.tree.unfoldOrDown' | 'app.tree.filter.default' | 'app.tree.filter.noTools' | 'app.tree.filter.userOnly' | 'app.tree.filter.labeledOnly' | 'app.tree.filter.all' | 'app.tree.filter.cycleForward' | 'app.tree.filter.cycleBackward' | 'app.tree.editLabel' | 'app.tree.toggleLabelTimestamp' | 'app.editor.external' | 'app.clipboard.pasteImage' | 'app.message.followUp' | 'app.message.editQueued' | 'app.message.deleteQueued' | 'app.models.save' | 'app.models.enableAll' | 'app.models.clearAll' | 'app.models.toggleProvider' | 'app.models.reorderUp' | 'app.models.reorderDown';
|
|
3
3
|
declare module '@earendil-works/pi-tui' {
|
|
4
4
|
interface Keybindings {
|
|
5
5
|
'app.interrupt': true;
|
|
@@ -12,6 +12,8 @@ declare module '@earendil-works/pi-tui' {
|
|
|
12
12
|
'app.model.select': true;
|
|
13
13
|
'app.tools.expand': true;
|
|
14
14
|
'app.thinking.toggle': true;
|
|
15
|
+
'app.transcript.open': true;
|
|
16
|
+
'app.transcript.raw': true;
|
|
15
17
|
'app.session.resume': true;
|
|
16
18
|
'app.session.tree': true;
|
|
17
19
|
'app.session.fork': true;
|
|
@@ -35,6 +37,8 @@ declare module '@earendil-works/pi-tui' {
|
|
|
35
37
|
'app.editor.external': true;
|
|
36
38
|
'app.clipboard.pasteImage': true;
|
|
37
39
|
'app.message.followUp': true;
|
|
40
|
+
'app.message.editQueued': true;
|
|
41
|
+
'app.message.deleteQueued': true;
|
|
38
42
|
'app.models.save': true;
|
|
39
43
|
'app.models.enableAll': true;
|
|
40
44
|
'app.models.clearAll': true;
|
|
@@ -81,9 +85,17 @@ export declare const XOPC_TUI_KEYBINDINGS: {
|
|
|
81
85
|
readonly description: "Toggle tool output";
|
|
82
86
|
};
|
|
83
87
|
readonly 'app.thinking.toggle': {
|
|
84
|
-
readonly defaultKeys:
|
|
88
|
+
readonly defaultKeys: [];
|
|
85
89
|
readonly description: "Toggle thinking block display";
|
|
86
90
|
};
|
|
91
|
+
readonly 'app.transcript.open': {
|
|
92
|
+
readonly defaultKeys: "ctrl+t";
|
|
93
|
+
readonly description: "Open transcript view";
|
|
94
|
+
};
|
|
95
|
+
readonly 'app.transcript.raw': {
|
|
96
|
+
readonly defaultKeys: "alt+r";
|
|
97
|
+
readonly description: "Open raw transcript view";
|
|
98
|
+
};
|
|
87
99
|
readonly 'app.session.resume': {
|
|
88
100
|
readonly defaultKeys: "ctrl+shift+p";
|
|
89
101
|
readonly description: "Session picker";
|
|
@@ -173,9 +185,17 @@ export declare const XOPC_TUI_KEYBINDINGS: {
|
|
|
173
185
|
readonly description: "Paste image from clipboard";
|
|
174
186
|
};
|
|
175
187
|
readonly 'app.message.followUp': {
|
|
176
|
-
readonly defaultKeys: "
|
|
188
|
+
readonly defaultKeys: "tab";
|
|
177
189
|
readonly description: "Queue message while busy (or submit when idle)";
|
|
178
190
|
};
|
|
191
|
+
readonly 'app.message.editQueued': {
|
|
192
|
+
readonly defaultKeys: "up";
|
|
193
|
+
readonly description: "Edit the last queued message when the composer is empty";
|
|
194
|
+
};
|
|
195
|
+
readonly 'app.message.deleteQueued': {
|
|
196
|
+
readonly defaultKeys: "ctrl+x";
|
|
197
|
+
readonly description: "Delete the last queued message";
|
|
198
|
+
};
|
|
179
199
|
readonly 'app.models.save': {
|
|
180
200
|
readonly defaultKeys: "ctrl+s";
|
|
181
201
|
readonly description: "Save scoped model selection";
|
|
@@ -39,9 +39,17 @@ const XOPC_TUI_KEYBINDINGS = {
|
|
|
39
39
|
description: "Toggle tool output"
|
|
40
40
|
},
|
|
41
41
|
"app.thinking.toggle": {
|
|
42
|
-
defaultKeys:
|
|
42
|
+
defaultKeys: [],
|
|
43
43
|
description: "Toggle thinking block display"
|
|
44
44
|
},
|
|
45
|
+
"app.transcript.open": {
|
|
46
|
+
defaultKeys: "ctrl+t",
|
|
47
|
+
description: "Open transcript view"
|
|
48
|
+
},
|
|
49
|
+
"app.transcript.raw": {
|
|
50
|
+
defaultKeys: "alt+r",
|
|
51
|
+
description: "Open raw transcript view"
|
|
52
|
+
},
|
|
45
53
|
"app.session.resume": {
|
|
46
54
|
defaultKeys: "ctrl+shift+p",
|
|
47
55
|
description: "Session picker"
|
|
@@ -131,9 +139,17 @@ const XOPC_TUI_KEYBINDINGS = {
|
|
|
131
139
|
description: "Paste image from clipboard"
|
|
132
140
|
},
|
|
133
141
|
"app.message.followUp": {
|
|
134
|
-
defaultKeys: "
|
|
142
|
+
defaultKeys: "tab",
|
|
135
143
|
description: "Queue message while busy (or submit when idle)"
|
|
136
144
|
},
|
|
145
|
+
"app.message.editQueued": {
|
|
146
|
+
defaultKeys: "up",
|
|
147
|
+
description: "Edit the last queued message when the composer is empty"
|
|
148
|
+
},
|
|
149
|
+
"app.message.deleteQueued": {
|
|
150
|
+
defaultKeys: "ctrl+x",
|
|
151
|
+
description: "Delete the last queued message"
|
|
152
|
+
},
|
|
137
153
|
"app.models.save": {
|
|
138
154
|
defaultKeys: "ctrl+s",
|
|
139
155
|
description: "Save scoped model selection"
|
|
@@ -191,9 +207,13 @@ const XOPC_TUI_HOTKEY_ORDER = [
|
|
|
191
207
|
"app.tree.toggleLabelTimestamp",
|
|
192
208
|
"app.tools.expand",
|
|
193
209
|
"app.thinking.toggle",
|
|
210
|
+
"app.transcript.open",
|
|
211
|
+
"app.transcript.raw",
|
|
194
212
|
"app.editor.external",
|
|
195
213
|
"app.clipboard.pasteImage",
|
|
196
214
|
"app.message.followUp",
|
|
215
|
+
"app.message.editQueued",
|
|
216
|
+
"app.message.deleteQueued",
|
|
197
217
|
"app.models.save",
|
|
198
218
|
"app.models.enableAll",
|
|
199
219
|
"app.models.clearAll",
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { Config } from '../config/schema.js';
|
|
2
|
-
import type {
|
|
2
|
+
import type { KnowledgeReadPolicy } from '../knowledge-memory/index.js';
|
|
3
3
|
export interface UserContextSessionAccess {
|
|
4
4
|
enabled: boolean;
|
|
5
5
|
userModel: boolean;
|
|
6
6
|
knowledge: boolean;
|
|
7
7
|
crossSessionHistory: boolean;
|
|
8
|
-
|
|
8
|
+
knowledgePolicy: KnowledgeReadPolicy;
|
|
9
9
|
}
|
|
10
10
|
/** One policy boundary for every shared-context read and write path. */
|
|
11
11
|
export declare function resolveUserContextSessionAccess(config: Config | undefined, conversationId: string | undefined): UserContextSessionAccess;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { getSessionConfig } from "../storage/sqlite/config-repository.js";
|
|
2
|
+
import { init_config, resolveKnowledgeReadPolicy } from "./config.js";
|
|
2
3
|
import { getConversationRouting } from "../storage/sqlite/conversation-repository.js";
|
|
3
4
|
import { init_session_key } from "../routing/session-key.js";
|
|
4
5
|
//#region src/user-context/access-policy.ts
|
|
6
|
+
init_config();
|
|
5
7
|
init_session_key();
|
|
6
8
|
/** One policy boundary for every shared-context read and write path. */
|
|
7
9
|
function resolveUserContextSessionAccess(config, conversationId) {
|
|
@@ -10,7 +12,10 @@ function resolveUserContextSessionAccess(config, conversationId) {
|
|
|
10
12
|
userModel: false,
|
|
11
13
|
knowledge: false,
|
|
12
14
|
crossSessionHistory: false,
|
|
13
|
-
|
|
15
|
+
knowledgePolicy: {
|
|
16
|
+
scopes: [],
|
|
17
|
+
contentSources: []
|
|
18
|
+
}
|
|
14
19
|
};
|
|
15
20
|
const session = getConversationRouting(conversationId);
|
|
16
21
|
const mode = getSessionConfig(conversationId)?.userContextMode ?? "enabled";
|
|
@@ -20,7 +25,10 @@ function resolveUserContextSessionAccess(config, conversationId) {
|
|
|
20
25
|
userModel: enabled && config.userContext.userModel.enabled,
|
|
21
26
|
knowledge: enabled && config.userContext.knowledgeMemory.enabled,
|
|
22
27
|
crossSessionHistory: enabled,
|
|
23
|
-
|
|
28
|
+
knowledgePolicy: enabled && config.userContext.knowledgeMemory.enabled ? resolveKnowledgeReadPolicy(config.userContext.knowledgeMemory) : {
|
|
29
|
+
scopes: [],
|
|
30
|
+
contentSources: []
|
|
31
|
+
}
|
|
24
32
|
};
|
|
25
33
|
}
|
|
26
34
|
//#endregion
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import type { KnowledgeReadPolicy } from '../knowledge-memory/domain.js';
|
|
2
3
|
export declare const DEFAULT_CONTEXT_COMPACTION_POLICY: {
|
|
3
4
|
enabled: boolean;
|
|
4
5
|
triggerThreshold: number;
|
|
@@ -75,18 +76,25 @@ export declare const UserModelConfigSchema: z.ZodDefault<z.ZodObject<{
|
|
|
75
76
|
staleRetentionDays: z.ZodDefault<z.ZodNumber>;
|
|
76
77
|
}, z.core.$strict>>;
|
|
77
78
|
}, z.core.$strict>>;
|
|
78
|
-
export declare
|
|
79
|
+
export declare function normalizeKnowledgeMemoryConfigInput(input: unknown): unknown;
|
|
80
|
+
export declare const KnowledgeMemoryConfigSchema: z.ZodDefault<z.ZodPreprocess<z.ZodObject<{
|
|
79
81
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
80
82
|
writePolicy: z.ZodDefault<z.ZodEnum<{
|
|
81
83
|
allow: "allow";
|
|
82
84
|
confirm: "confirm";
|
|
83
85
|
deny: "deny";
|
|
84
86
|
}>>;
|
|
85
|
-
|
|
87
|
+
readScopes: z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
86
88
|
project: "project";
|
|
87
89
|
session: "session";
|
|
90
|
+
agent: "agent";
|
|
88
91
|
workspace: "workspace";
|
|
92
|
+
global: "global";
|
|
93
|
+
}>>>;
|
|
94
|
+
contentSources: z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
95
|
+
memory: "memory";
|
|
89
96
|
connector: "connector";
|
|
97
|
+
local_import: "local_import";
|
|
90
98
|
}>>>;
|
|
91
99
|
searchStrategy: z.ZodDefault<z.ZodEnum<{
|
|
92
100
|
"local-first": "local-first";
|
|
@@ -95,6 +103,7 @@ export declare const KnowledgeMemoryConfigSchema: z.ZodDefault<z.ZodObject<{
|
|
|
95
103
|
"local-only": "local-only";
|
|
96
104
|
"external-only": "external-only";
|
|
97
105
|
}>>;
|
|
106
|
+
searchTimeoutMs: z.ZodDefault<z.ZodNumber>;
|
|
98
107
|
writeStrategy: z.ZodDefault<z.ZodEnum<{
|
|
99
108
|
"local-first": "local-first";
|
|
100
109
|
"external-first": "external-first";
|
|
@@ -105,7 +114,7 @@ export declare const KnowledgeMemoryConfigSchema: z.ZodDefault<z.ZodObject<{
|
|
|
105
114
|
allowExternalWrites: z.ZodDefault<z.ZodBoolean>;
|
|
106
115
|
allowedProviderIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
107
116
|
autoWriteKinds: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
108
|
-
}, z.core.$strict
|
|
117
|
+
}, z.core.$strict>>>;
|
|
109
118
|
export declare const ContextPlanningConfigSchema: z.ZodDefault<z.ZodObject<{
|
|
110
119
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
111
120
|
maxAssertions: z.ZodDefault<z.ZodNumber>;
|
|
@@ -180,18 +189,24 @@ export declare const UserContextConfigSchema: z.ZodDefault<z.ZodObject<{
|
|
|
180
189
|
staleRetentionDays: z.ZodDefault<z.ZodNumber>;
|
|
181
190
|
}, z.core.$strict>>;
|
|
182
191
|
}, z.core.$strict>>;
|
|
183
|
-
knowledgeMemory: z.ZodDefault<z.ZodObject<{
|
|
192
|
+
knowledgeMemory: z.ZodDefault<z.ZodPreprocess<z.ZodObject<{
|
|
184
193
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
185
194
|
writePolicy: z.ZodDefault<z.ZodEnum<{
|
|
186
195
|
allow: "allow";
|
|
187
196
|
confirm: "confirm";
|
|
188
197
|
deny: "deny";
|
|
189
198
|
}>>;
|
|
190
|
-
|
|
199
|
+
readScopes: z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
191
200
|
project: "project";
|
|
192
201
|
session: "session";
|
|
202
|
+
agent: "agent";
|
|
193
203
|
workspace: "workspace";
|
|
204
|
+
global: "global";
|
|
205
|
+
}>>>;
|
|
206
|
+
contentSources: z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
207
|
+
memory: "memory";
|
|
194
208
|
connector: "connector";
|
|
209
|
+
local_import: "local_import";
|
|
195
210
|
}>>>;
|
|
196
211
|
searchStrategy: z.ZodDefault<z.ZodEnum<{
|
|
197
212
|
"local-first": "local-first";
|
|
@@ -200,6 +215,7 @@ export declare const UserContextConfigSchema: z.ZodDefault<z.ZodObject<{
|
|
|
200
215
|
"local-only": "local-only";
|
|
201
216
|
"external-only": "external-only";
|
|
202
217
|
}>>;
|
|
218
|
+
searchTimeoutMs: z.ZodDefault<z.ZodNumber>;
|
|
203
219
|
writeStrategy: z.ZodDefault<z.ZodEnum<{
|
|
204
220
|
"local-first": "local-first";
|
|
205
221
|
"external-first": "external-first";
|
|
@@ -210,7 +226,7 @@ export declare const UserContextConfigSchema: z.ZodDefault<z.ZodObject<{
|
|
|
210
226
|
allowExternalWrites: z.ZodDefault<z.ZodBoolean>;
|
|
211
227
|
allowedProviderIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
212
228
|
autoWriteKinds: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
213
|
-
}, z.core.$strict
|
|
229
|
+
}, z.core.$strict>>>;
|
|
214
230
|
contextPlanning: z.ZodDefault<z.ZodObject<{
|
|
215
231
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
216
232
|
maxAssertions: z.ZodDefault<z.ZodNumber>;
|
|
@@ -240,3 +256,4 @@ export type UserContextConfig = z.infer<typeof UserContextConfigSchema>;
|
|
|
240
256
|
export type UserModelConfig = z.infer<typeof UserModelConfigSchema>;
|
|
241
257
|
export type KnowledgeMemoryConfig = z.infer<typeof KnowledgeMemoryConfigSchema>;
|
|
242
258
|
export type ContextPlanningConfig = z.infer<typeof ContextPlanningConfigSchema>;
|
|
259
|
+
export declare function resolveKnowledgeReadPolicy(config: KnowledgeMemoryConfig): KnowledgeReadPolicy;
|
|
@@ -10,6 +10,32 @@ function isValidTimeZone(value) {
|
|
|
10
10
|
return false;
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
|
+
function normalizeKnowledgeMemoryConfigInput(input) {
|
|
14
|
+
if (!input || typeof input !== "object" || Array.isArray(input)) return input;
|
|
15
|
+
const memory = input;
|
|
16
|
+
if (!Array.isArray(memory.sources)) return input;
|
|
17
|
+
const oldSources = memory.sources.filter((source) => typeof source === "string");
|
|
18
|
+
const visibilityScopes = new Set([
|
|
19
|
+
"session",
|
|
20
|
+
"workspace",
|
|
21
|
+
"project"
|
|
22
|
+
]);
|
|
23
|
+
const normalized = { ...memory };
|
|
24
|
+
if (!Array.isArray(normalized.readScopes)) normalized.readScopes = oldSources.filter((source) => visibilityScopes.has(source));
|
|
25
|
+
if (!Array.isArray(normalized.contentSources)) normalized.contentSources = [
|
|
26
|
+
...oldSources.some((source) => visibilityScopes.has(source)) ? ["memory"] : [],
|
|
27
|
+
...oldSources.includes("workspace") ? ["local_import"] : [],
|
|
28
|
+
...oldSources.includes("connector") ? ["connector"] : []
|
|
29
|
+
];
|
|
30
|
+
delete normalized.sources;
|
|
31
|
+
return normalized;
|
|
32
|
+
}
|
|
33
|
+
function resolveKnowledgeReadPolicy(config) {
|
|
34
|
+
return {
|
|
35
|
+
scopes: config.readScopes,
|
|
36
|
+
contentSources: config.contentSources
|
|
37
|
+
};
|
|
38
|
+
}
|
|
13
39
|
var DEFAULT_CONTEXT_COMPACTION_POLICY, ContextCompactionPolicySchema, WritePolicySchema, MaintenanceTimeSchema, UserModelConfigSchema, KnowledgeMemoryConfigSchema, ContextPlanningConfigSchema, UserContextConfigSchema;
|
|
14
40
|
var init_config = __esmMin((() => {
|
|
15
41
|
init_response_language();
|
|
@@ -117,15 +143,27 @@ var init_config = __esmMin((() => {
|
|
|
117
143
|
staleRetentionDays: 30
|
|
118
144
|
}
|
|
119
145
|
});
|
|
120
|
-
KnowledgeMemoryConfigSchema = z.object({
|
|
146
|
+
KnowledgeMemoryConfigSchema = z.preprocess(normalizeKnowledgeMemoryConfigInput, z.object({
|
|
121
147
|
enabled: z.boolean().default(true),
|
|
122
148
|
writePolicy: WritePolicySchema.default("confirm"),
|
|
123
|
-
|
|
124
|
-
"
|
|
149
|
+
readScopes: z.array(z.enum([
|
|
150
|
+
"global",
|
|
151
|
+
"agent",
|
|
125
152
|
"workspace",
|
|
126
153
|
"project",
|
|
154
|
+
"session"
|
|
155
|
+
])).default([
|
|
156
|
+
"global",
|
|
157
|
+
"agent",
|
|
158
|
+
"workspace",
|
|
159
|
+
"project",
|
|
160
|
+
"session"
|
|
161
|
+
]),
|
|
162
|
+
contentSources: z.array(z.enum([
|
|
163
|
+
"memory",
|
|
164
|
+
"local_import",
|
|
127
165
|
"connector"
|
|
128
|
-
])).default(["
|
|
166
|
+
])).default(["memory", "local_import"]),
|
|
129
167
|
searchStrategy: z.enum([
|
|
130
168
|
"local-first",
|
|
131
169
|
"external-first",
|
|
@@ -133,6 +171,7 @@ var init_config = __esmMin((() => {
|
|
|
133
171
|
"local-only",
|
|
134
172
|
"external-only"
|
|
135
173
|
]).default("fanout"),
|
|
174
|
+
searchTimeoutMs: z.number().int().min(100).max(3e4).default(2e3),
|
|
136
175
|
writeStrategy: z.enum([
|
|
137
176
|
"local-first",
|
|
138
177
|
"external-first",
|
|
@@ -143,11 +182,19 @@ var init_config = __esmMin((() => {
|
|
|
143
182
|
allowExternalWrites: z.boolean().default(false),
|
|
144
183
|
allowedProviderIds: z.array(z.string().min(1)).optional(),
|
|
145
184
|
autoWriteKinds: z.array(z.string().min(1)).optional()
|
|
146
|
-
}).strict().default({
|
|
185
|
+
}).strict()).default({
|
|
147
186
|
enabled: true,
|
|
148
187
|
writePolicy: "confirm",
|
|
149
|
-
|
|
188
|
+
readScopes: [
|
|
189
|
+
"global",
|
|
190
|
+
"agent",
|
|
191
|
+
"workspace",
|
|
192
|
+
"project",
|
|
193
|
+
"session"
|
|
194
|
+
],
|
|
195
|
+
contentSources: ["memory", "local_import"],
|
|
150
196
|
searchStrategy: "fanout",
|
|
197
|
+
searchTimeoutMs: 2e3,
|
|
151
198
|
writeStrategy: "local-first",
|
|
152
199
|
allowExternalWrites: false
|
|
153
200
|
});
|
|
@@ -180,4 +227,4 @@ var init_config = __esmMin((() => {
|
|
|
180
227
|
}));
|
|
181
228
|
//#endregion
|
|
182
229
|
init_config();
|
|
183
|
-
export { ContextCompactionPolicySchema, ContextPlanningConfigSchema, DEFAULT_CONTEXT_COMPACTION_POLICY, KnowledgeMemoryConfigSchema, UserContextConfigSchema, UserModelConfigSchema, init_config };
|
|
230
|
+
export { ContextCompactionPolicySchema, ContextPlanningConfigSchema, DEFAULT_CONTEXT_COMPACTION_POLICY, KnowledgeMemoryConfigSchema, UserContextConfigSchema, UserModelConfigSchema, init_config, normalizeKnowledgeMemoryConfigInput, resolveKnowledgeReadPolicy };
|
|
@@ -46,6 +46,12 @@ function connect(url, token, signal, onEvent, onFailure) {
|
|
|
46
46
|
socket,
|
|
47
47
|
close,
|
|
48
48
|
fail,
|
|
49
|
+
pause: () => {
|
|
50
|
+
if (!ended && socket.readyState === WebSocket.OPEN) socket.pause();
|
|
51
|
+
},
|
|
52
|
+
resume: () => {
|
|
53
|
+
if (!ended && socket.readyState === WebSocket.OPEN) socket.resume();
|
|
54
|
+
},
|
|
49
55
|
send: (value) => {
|
|
50
56
|
if (ended || socket.readyState !== WebSocket.OPEN) throw new Error("Platform voice is not connected");
|
|
51
57
|
if (socket.bufferedAmount > MAX_BUFFERED_BYTES) throw new Error("Platform voice backpressure limit exceeded");
|
|
@@ -180,6 +186,9 @@ async function openPlatformTts(request) {
|
|
|
180
186
|
start(value) {
|
|
181
187
|
controller = value;
|
|
182
188
|
},
|
|
189
|
+
pull(value) {
|
|
190
|
+
if ((value.desiredSize ?? 0) > 0) connection.resume();
|
|
191
|
+
},
|
|
183
192
|
cancel() {
|
|
184
193
|
ended = true;
|
|
185
194
|
clearTimeout(timer);
|
|
@@ -206,8 +215,9 @@ async function openPlatformTts(request) {
|
|
|
206
215
|
} else if (event.type === "response.audio.delta") {
|
|
207
216
|
if (!ready || typeof event.delta !== "string" || !/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(event.delta)) throw new Error("Invalid platform audio");
|
|
208
217
|
const bytes = Buffer.from(event.delta, "base64");
|
|
209
|
-
if (bytes.length % 2 ||
|
|
218
|
+
if (bytes.length % 2 || bytes.length > MAX_BUFFERED_BYTES) throw new Error("Invalid platform audio");
|
|
210
219
|
controller.enqueue(bytes);
|
|
220
|
+
if ((controller.desiredSize ?? 0) <= 0) connection.pause();
|
|
211
221
|
} else if (event.type === "session.finished") {
|
|
212
222
|
ended = true;
|
|
213
223
|
clearTimeout(timer);
|