@jingyi0605/codingns4dsh 0.2.1-beta.3 → 0.2.1-beta.5
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.en.md +30 -6
- package/README.md +121 -10
- package/THIRD_PARTY_NOTICES +141 -0
- package/assets/assistant-basics/female-v1.png +0 -0
- package/assets/assistant-basics/male-v1.png +0 -0
- package/assets/desktop-assistant/20261008-WebView2/345/210/206/345/217/221/350/257/264/346/230/216.md +14 -0
- package/assets/desktop-assistant/webview2/LICENSE.txt +27 -0
- package/assets/desktop-assistant/webview2/Microsoft.Web.WebView2.Core.dll +0 -0
- package/assets/desktop-assistant/webview2/Microsoft.Web.WebView2.Wpf.dll +0 -0
- package/assets/desktop-assistant/webview2/NOTICE.txt +85 -0
- package/assets/desktop-assistant/webview2/arm64/WebView2Loader.dll +0 -0
- package/assets/desktop-assistant/webview2/x64/WebView2Loader.dll +0 -0
- package/assets/desktop-assistant/webview2/x86/WebView2Loader.dll +0 -0
- package/assets/moss/LICENSE +201 -0
- package/assets/moss/ort_cpu_runtime.py +839 -0
- package/assets/moss/worker.py +278 -0
- package/assets/voice/bilingual-zh-en-bpe.vocab +500 -0
- package/avatar-packages/catalog.json +259 -0
- package/avatar-packages/manifests/bubu-codebrew-bear.avatar.json +13 -0
- package/avatar-packages/manifests/ds-whale-live2d.avatar.json +27 -0
- package/avatar-packages/manifests/ds-whale-sprite.avatar.json +13 -0
- package/avatar-packages/manifests/live2d-haru.avatar.json +13 -0
- package/avatar-packages/manifests/live2d-hiyori.avatar.json +13 -0
- package/avatar-packages/manifests/live2d-mao.avatar.json +13 -0
- package/avatar-packages/manifests/live2d-mark.avatar.json +13 -0
- package/avatar-packages/manifests/live2d-rice.avatar.json +13 -0
- package/avatar-packages/manifests/live2d-wanko.avatar.json +13 -0
- package/avatar-packages/manifests/nastya.avatar.json +13 -0
- package/avatar-packages/manifests/scout-corgi.avatar.json +13 -0
- package/avatar-packages/manifests/xiaoman.avatar.json +13 -0
- package/data/build/dist/client/account-bar.d.ts +1 -1
- package/data/build/dist/client/account-bar.d.ts.map +1 -1
- package/data/build/dist/client/account-bar.js +22 -14
- package/data/build/dist/client/account-bar.js.map +1 -1
- package/data/build/dist/client/adapter-catalog-watch.d.ts +8 -0
- package/data/build/dist/client/adapter-catalog-watch.d.ts.map +1 -0
- package/data/build/dist/client/adapter-catalog-watch.js +79 -0
- package/data/build/dist/client/adapter-catalog-watch.js.map +1 -0
- package/data/build/dist/client/assistant-settings-styles.d.ts +7 -0
- package/data/build/dist/client/assistant-settings-styles.d.ts.map +1 -0
- package/data/build/dist/client/assistant-settings-styles.js +6 -0
- package/data/build/dist/client/assistant-settings-styles.js.map +1 -0
- package/data/build/dist/client/avatar/builtin.d.ts +5 -0
- package/data/build/dist/client/avatar/builtin.d.ts.map +1 -0
- package/data/build/dist/client/avatar/builtin.js +9 -0
- package/data/build/dist/client/avatar/builtin.js.map +1 -0
- package/data/build/dist/client/avatar/cache-status.d.ts +4 -0
- package/data/build/dist/client/avatar/cache-status.d.ts.map +1 -0
- package/data/build/dist/client/avatar/cache-status.js +40 -0
- package/data/build/dist/client/avatar/cache-status.js.map +1 -0
- package/data/build/dist/client/avatar/catalog-panel.d.ts +49 -0
- package/data/build/dist/client/avatar/catalog-panel.d.ts.map +1 -0
- package/data/build/dist/client/avatar/catalog-panel.js +245 -0
- package/data/build/dist/client/avatar/catalog-panel.js.map +1 -0
- package/data/build/dist/client/avatar/catalog-picker.d.ts +38 -0
- package/data/build/dist/client/avatar/catalog-picker.d.ts.map +1 -0
- package/data/build/dist/client/avatar/catalog-picker.js +65 -0
- package/data/build/dist/client/avatar/catalog-picker.js.map +1 -0
- package/data/build/dist/client/avatar/desktop-bridge.d.ts +21 -0
- package/data/build/dist/client/avatar/desktop-bridge.d.ts.map +1 -0
- package/data/build/dist/client/avatar/desktop-bridge.js +109 -0
- package/data/build/dist/client/avatar/desktop-bridge.js.map +1 -0
- package/data/build/dist/client/avatar/desktop-entry.d.ts +2 -0
- package/data/build/dist/client/avatar/desktop-entry.d.ts.map +1 -0
- package/data/build/dist/client/avatar/desktop-entry.js +34 -0
- package/data/build/dist/client/avatar/desktop-entry.js.map +1 -0
- package/data/build/dist/client/avatar/desktop-view.d.ts +23 -0
- package/data/build/dist/client/avatar/desktop-view.d.ts.map +1 -0
- package/data/build/dist/client/avatar/desktop-view.js +72 -0
- package/data/build/dist/client/avatar/desktop-view.js.map +1 -0
- package/data/build/dist/client/avatar/engine.d.ts +45 -0
- package/data/build/dist/client/avatar/engine.d.ts.map +1 -0
- package/data/build/dist/client/avatar/engine.js +165 -0
- package/data/build/dist/client/avatar/engine.js.map +1 -0
- package/data/build/dist/client/avatar/floating.d.ts +20 -0
- package/data/build/dist/client/avatar/floating.d.ts.map +1 -0
- package/data/build/dist/client/avatar/floating.js +99 -0
- package/data/build/dist/client/avatar/floating.js.map +1 -0
- package/data/build/dist/client/avatar/image.d.ts +5 -0
- package/data/build/dist/client/avatar/image.d.ts.map +1 -0
- package/data/build/dist/client/avatar/image.js +22 -0
- package/data/build/dist/client/avatar/image.js.map +1 -0
- package/data/build/dist/client/avatar/live2d.d.ts +67 -0
- package/data/build/dist/client/avatar/live2d.d.ts.map +1 -0
- package/data/build/dist/client/avatar/live2d.js +288 -0
- package/data/build/dist/client/avatar/live2d.js.map +1 -0
- package/data/build/dist/client/avatar/loading.d.ts +27 -0
- package/data/build/dist/client/avatar/loading.d.ts.map +1 -0
- package/data/build/dist/client/avatar/loading.js +74 -0
- package/data/build/dist/client/avatar/loading.js.map +1 -0
- package/data/build/dist/client/avatar/manager.d.ts +71 -0
- package/data/build/dist/client/avatar/manager.d.ts.map +1 -0
- package/data/build/dist/client/avatar/manager.js +323 -0
- package/data/build/dist/client/avatar/manager.js.map +1 -0
- package/data/build/dist/client/avatar/portrait-capture.d.ts +30 -0
- package/data/build/dist/client/avatar/portrait-capture.d.ts.map +1 -0
- package/data/build/dist/client/avatar/portrait-capture.js +233 -0
- package/data/build/dist/client/avatar/portrait-capture.js.map +1 -0
- package/data/build/dist/client/avatar/portrait-editor.d.ts +14 -0
- package/data/build/dist/client/avatar/portrait-editor.d.ts.map +1 -0
- package/data/build/dist/client/avatar/portrait-editor.js +105 -0
- package/data/build/dist/client/avatar/portrait-editor.js.map +1 -0
- package/data/build/dist/client/avatar/portrait-service.d.ts +51 -0
- package/data/build/dist/client/avatar/portrait-service.d.ts.map +1 -0
- package/data/build/dist/client/avatar/portrait-service.js +244 -0
- package/data/build/dist/client/avatar/portrait-service.js.map +1 -0
- package/data/build/dist/client/avatar/portrait.d.ts +28 -0
- package/data/build/dist/client/avatar/portrait.d.ts.map +1 -0
- package/data/build/dist/client/avatar/portrait.js +56 -0
- package/data/build/dist/client/avatar/portrait.js.map +1 -0
- package/data/build/dist/client/avatar/preview-capture.d.ts +4 -0
- package/data/build/dist/client/avatar/preview-capture.d.ts.map +1 -0
- package/data/build/dist/client/avatar/preview-capture.js +100 -0
- package/data/build/dist/client/avatar/preview-capture.js.map +1 -0
- package/data/build/dist/client/avatar/preview-store.d.ts +41 -0
- package/data/build/dist/client/avatar/preview-store.d.ts.map +1 -0
- package/data/build/dist/client/avatar/preview-store.js +171 -0
- package/data/build/dist/client/avatar/preview-store.js.map +1 -0
- package/data/build/dist/client/avatar/preview.d.ts +14 -0
- package/data/build/dist/client/avatar/preview.d.ts.map +1 -0
- package/data/build/dist/client/avatar/preview.js +56 -0
- package/data/build/dist/client/avatar/preview.js.map +1 -0
- package/data/build/dist/client/avatar/registration.d.ts +2 -0
- package/data/build/dist/client/avatar/registration.d.ts.map +1 -0
- package/data/build/dist/client/avatar/registration.js +2 -0
- package/data/build/dist/client/avatar/registration.js.map +1 -0
- package/data/build/dist/client/avatar/registry.d.ts +45 -0
- package/data/build/dist/client/avatar/registry.d.ts.map +1 -0
- package/data/build/dist/client/avatar/registry.js +34 -0
- package/data/build/dist/client/avatar/registry.js.map +1 -0
- package/data/build/dist/client/avatar/settings-panel.d.ts +21 -0
- package/data/build/dist/client/avatar/settings-panel.d.ts.map +1 -0
- package/data/build/dist/client/avatar/settings-panel.js +169 -0
- package/data/build/dist/client/avatar/settings-panel.js.map +1 -0
- package/data/build/dist/client/avatar/slot.d.ts +17 -0
- package/data/build/dist/client/avatar/slot.d.ts.map +1 -0
- package/data/build/dist/client/avatar/slot.js +70 -0
- package/data/build/dist/client/avatar/slot.js.map +1 -0
- package/data/build/dist/client/avatar/spritesheet.d.ts +19 -0
- package/data/build/dist/client/avatar/spritesheet.d.ts.map +1 -0
- package/data/build/dist/client/avatar/spritesheet.js +91 -0
- package/data/build/dist/client/avatar/spritesheet.js.map +1 -0
- package/data/build/dist/client/avatar/temporary-preview.d.ts +25 -0
- package/data/build/dist/client/avatar/temporary-preview.d.ts.map +1 -0
- package/data/build/dist/client/avatar/temporary-preview.js +61 -0
- package/data/build/dist/client/avatar/temporary-preview.js.map +1 -0
- package/data/build/dist/client/bundle.js +25603 -3080
- package/data/build/dist/client/bundle.js.map +1 -1
- package/data/build/dist/client/cli-catalog.d.ts +3 -0
- package/data/build/dist/client/cli-catalog.d.ts.map +1 -1
- package/data/build/dist/client/cli-catalog.js +7 -0
- package/data/build/dist/client/cli-catalog.js.map +1 -1
- package/data/build/dist/client/cli-slots.d.ts.map +1 -1
- package/data/build/dist/client/cli-slots.js +14 -52
- package/data/build/dist/client/cli-slots.js.map +1 -1
- package/data/build/dist/client/debug/ui.d.ts.map +1 -1
- package/data/build/dist/client/debug/ui.js +14 -5
- package/data/build/dist/client/debug/ui.js.map +1 -1
- package/data/build/dist/client/desktop-assistant.js +8599 -0
- package/data/build/dist/client/features/assistant-composer-input.d.ts +10 -0
- package/data/build/dist/client/features/assistant-composer-input.d.ts.map +1 -0
- package/data/build/dist/client/features/assistant-composer-input.js +40 -0
- package/data/build/dist/client/features/assistant-composer-input.js.map +1 -0
- package/data/build/dist/client/features/assistant-configuration-session.d.ts +45 -0
- package/data/build/dist/client/features/assistant-configuration-session.d.ts.map +1 -0
- package/data/build/dist/client/features/assistant-configuration-session.js +252 -0
- package/data/build/dist/client/features/assistant-configuration-session.js.map +1 -0
- package/data/build/dist/client/features/assistant-configuration-tabs.d.ts +34 -0
- package/data/build/dist/client/features/assistant-configuration-tabs.d.ts.map +1 -0
- package/data/build/dist/client/features/assistant-configuration-tabs.js +48 -0
- package/data/build/dist/client/features/assistant-configuration-tabs.js.map +1 -0
- package/data/build/dist/client/features/assistant-conversation-message.d.ts +27 -0
- package/data/build/dist/client/features/assistant-conversation-message.d.ts.map +1 -0
- package/data/build/dist/client/features/assistant-conversation-message.js +55 -0
- package/data/build/dist/client/features/assistant-conversation-message.js.map +1 -0
- package/data/build/dist/client/features/assistant-debug-dialog.d.ts +3 -0
- package/data/build/dist/client/features/assistant-debug-dialog.d.ts.map +1 -0
- package/data/build/dist/client/features/assistant-debug-dialog.js +3 -0
- package/data/build/dist/client/features/assistant-debug-dialog.js.map +1 -0
- package/data/build/dist/client/features/assistant-debug-workbench.d.ts +48 -0
- package/data/build/dist/client/features/assistant-debug-workbench.d.ts.map +1 -0
- package/data/build/dist/client/features/assistant-debug-workbench.js +376 -0
- package/data/build/dist/client/features/assistant-debug-workbench.js.map +1 -0
- package/data/build/dist/client/features/assistant-floating-call.d.ts +33 -0
- package/data/build/dist/client/features/assistant-floating-call.d.ts.map +1 -0
- package/data/build/dist/client/features/assistant-floating-call.js +67 -0
- package/data/build/dist/client/features/assistant-floating-call.js.map +1 -0
- package/data/build/dist/client/features/assistant-panel.d.ts +2 -2
- package/data/build/dist/client/features/assistant-panel.d.ts.map +1 -1
- package/data/build/dist/client/features/assistant-panel.js +10 -123
- package/data/build/dist/client/features/assistant-panel.js.map +1 -1
- package/data/build/dist/client/features/assistant-realtime-call.d.ts +57 -0
- package/data/build/dist/client/features/assistant-realtime-call.d.ts.map +1 -0
- package/data/build/dist/client/features/assistant-realtime-call.js +131 -0
- package/data/build/dist/client/features/assistant-realtime-call.js.map +1 -0
- package/data/build/dist/client/features/assistant-record-style.d.ts +5 -0
- package/data/build/dist/client/features/assistant-record-style.d.ts.map +1 -0
- package/data/build/dist/client/features/assistant-record-style.js +25 -0
- package/data/build/dist/client/features/assistant-record-style.js.map +1 -0
- package/data/build/dist/client/features/assistant-voice-initialization.d.ts +26 -0
- package/data/build/dist/client/features/assistant-voice-initialization.d.ts.map +1 -0
- package/data/build/dist/client/features/assistant-voice-initialization.js +138 -0
- package/data/build/dist/client/features/assistant-voice-initialization.js.map +1 -0
- package/data/build/dist/client/features/assistant-voice-settings-group.d.ts +19 -0
- package/data/build/dist/client/features/assistant-voice-settings-group.d.ts.map +1 -0
- package/data/build/dist/client/features/assistant-voice-settings-group.js +34 -0
- package/data/build/dist/client/features/assistant-voice-settings-group.js.map +1 -0
- package/data/build/dist/client/features/assistant-voice-settings.d.ts +13 -0
- package/data/build/dist/client/features/assistant-voice-settings.d.ts.map +1 -0
- package/data/build/dist/client/features/assistant-voice-settings.js +184 -0
- package/data/build/dist/client/features/assistant-voice-settings.js.map +1 -0
- package/data/build/dist/client/features/assistant-workbench-controls.d.ts +72 -0
- package/data/build/dist/client/features/assistant-workbench-controls.d.ts.map +1 -0
- package/data/build/dist/client/features/assistant-workbench-controls.js +145 -0
- package/data/build/dist/client/features/assistant-workbench-controls.js.map +1 -0
- package/data/build/dist/client/features/assistant-workbench-entry.d.ts +4 -0
- package/data/build/dist/client/features/assistant-workbench-entry.d.ts.map +1 -0
- package/data/build/dist/client/features/assistant-workbench-entry.js +7 -0
- package/data/build/dist/client/features/assistant-workbench-entry.js.map +1 -0
- package/data/build/dist/client/features/assistant-workbench.d.ts +109 -0
- package/data/build/dist/client/features/assistant-workbench.d.ts.map +1 -0
- package/data/build/dist/client/features/assistant-workbench.js +568 -0
- package/data/build/dist/client/features/assistant-workbench.js.map +1 -0
- package/data/build/dist/client/features/cli-adapters.d.ts.map +1 -1
- package/data/build/dist/client/features/cli-adapters.js +48 -13
- package/data/build/dist/client/features/cli-adapters.js.map +1 -1
- package/data/build/dist/client/features/global-voice-assistant.d.ts.map +1 -1
- package/data/build/dist/client/features/global-voice-assistant.js +100 -39
- package/data/build/dist/client/features/global-voice-assistant.js.map +1 -1
- package/data/build/dist/client/features/lan-access.js +2 -2
- package/data/build/dist/client/features/lan-access.js.map +1 -1
- package/data/build/dist/client/features/mobile-access.d.ts.map +1 -1
- package/data/build/dist/client/features/mobile-access.js +9 -0
- package/data/build/dist/client/features/mobile-access.js.map +1 -1
- package/data/build/dist/client/features/peer-host.d.ts +4 -1
- package/data/build/dist/client/features/peer-host.d.ts.map +1 -1
- package/data/build/dist/client/features/peer-host.js +176 -106
- package/data/build/dist/client/features/peer-host.js.map +1 -1
- package/data/build/dist/client/features/types.d.ts +4 -0
- package/data/build/dist/client/features/types.d.ts.map +1 -1
- package/data/build/dist/client/features/voice-conversation-dialog.d.ts +9 -2
- package/data/build/dist/client/features/voice-conversation-dialog.d.ts.map +1 -1
- package/data/build/dist/client/features/voice-conversation-dialog.js +29 -7
- package/data/build/dist/client/features/voice-conversation-dialog.js.map +1 -1
- package/data/build/dist/client/features/voice-initialization-dialog.d.ts +42 -2
- package/data/build/dist/client/features/voice-initialization-dialog.d.ts.map +1 -1
- package/data/build/dist/client/features/voice-initialization-dialog.js +181 -67
- package/data/build/dist/client/features/voice-initialization-dialog.js.map +1 -1
- package/data/build/dist/client/features/workspace-session-enhancement.d.ts.map +1 -1
- package/data/build/dist/client/features/workspace-session-enhancement.js +37 -10
- package/data/build/dist/client/features/workspace-session-enhancement.js.map +1 -1
- package/data/build/dist/client/git-management.d.ts +1 -1
- package/data/build/dist/client/git-management.d.ts.map +1 -1
- package/data/build/dist/client/git-management.js +46 -27
- package/data/build/dist/client/git-management.js.map +1 -1
- package/data/build/dist/client/global-voice-runtime-registry.d.ts +4 -0
- package/data/build/dist/client/global-voice-runtime-registry.d.ts.map +1 -1
- package/data/build/dist/client/global-voice-runtime-registry.js.map +1 -1
- package/data/build/dist/client/index.d.ts +11 -0
- package/data/build/dist/client/index.d.ts.map +1 -1
- package/data/build/dist/client/index.js +10 -0
- package/data/build/dist/client/index.js.map +1 -1
- package/data/build/dist/client/locale.d.ts.map +1 -1
- package/data/build/dist/client/locale.js +61 -14
- package/data/build/dist/client/locale.js.map +1 -1
- package/data/build/dist/client/locales/assistantAvatar.d.ts +138 -0
- package/data/build/dist/client/locales/assistantAvatar.d.ts.map +1 -0
- package/data/build/dist/client/locales/assistantAvatar.js +273 -0
- package/data/build/dist/client/locales/assistantAvatar.js.map +1 -0
- package/data/build/dist/client/locales/assistantDebug.d.ts +4 -0
- package/data/build/dist/client/locales/assistantDebug.d.ts.map +1 -0
- package/data/build/dist/client/locales/assistantDebug.js +362 -0
- package/data/build/dist/client/locales/assistantDebug.js.map +1 -0
- package/data/build/dist/client/locales/assistantTts.d.ts +80 -0
- package/data/build/dist/client/locales/assistantTts.d.ts.map +1 -0
- package/data/build/dist/client/locales/assistantTts.js +76 -0
- package/data/build/dist/client/locales/assistantTts.js.map +1 -0
- package/data/build/dist/client/locales/assistantWorkbench.d.ts +126 -0
- package/data/build/dist/client/locales/assistantWorkbench.d.ts.map +1 -0
- package/data/build/dist/client/locales/assistantWorkbench.js +96 -0
- package/data/build/dist/client/locales/assistantWorkbench.js.map +1 -0
- package/data/build/dist/client/locales/peerHost.d.ts.map +1 -1
- package/data/build/dist/client/locales/peerHost.js +4 -0
- package/data/build/dist/client/locales/peerHost.js.map +1 -1
- package/data/build/dist/client/locales/peerHostWorkspace.js +2 -2
- package/data/build/dist/client/locales/peerHostWorkspace.js.map +1 -1
- package/data/build/dist/client/locales/terminalAuth.d.ts.map +1 -1
- package/data/build/dist/client/locales/terminalAuth.js +80 -0
- package/data/build/dist/client/locales/terminalAuth.js.map +1 -1
- package/data/build/dist/client/locales/usage.d.ts.map +1 -1
- package/data/build/dist/client/locales/usage.js +4 -0
- package/data/build/dist/client/locales/usage.js.map +1 -1
- package/data/build/dist/client/locales/voiceModels.d.ts +45 -0
- package/data/build/dist/client/locales/voiceModels.d.ts.map +1 -0
- package/data/build/dist/client/locales/voiceModels.js +85 -0
- package/data/build/dist/client/locales/voiceModels.js.map +1 -0
- package/data/build/dist/client/mobile-rightbar-tabs-dom.d.ts +29 -0
- package/data/build/dist/client/mobile-rightbar-tabs-dom.d.ts.map +1 -0
- package/data/build/dist/client/mobile-rightbar-tabs-dom.js +93 -0
- package/data/build/dist/client/mobile-rightbar-tabs-dom.js.map +1 -0
- package/data/build/dist/client/mobile-rightbar-visibility.d.ts +32 -0
- package/data/build/dist/client/mobile-rightbar-visibility.d.ts.map +1 -0
- package/data/build/dist/client/mobile-rightbar-visibility.js +188 -0
- package/data/build/dist/client/mobile-rightbar-visibility.js.map +1 -0
- package/data/build/dist/client/mobile-session-interaction.d.ts +9 -19
- package/data/build/dist/client/mobile-session-interaction.d.ts.map +1 -1
- package/data/build/dist/client/mobile-session-interaction.js +25 -169
- package/data/build/dist/client/mobile-session-interaction.js.map +1 -1
- package/data/build/dist/client/mobile-sidebar-gestures.d.ts +4 -0
- package/data/build/dist/client/mobile-sidebar-gestures.d.ts.map +1 -1
- package/data/build/dist/client/mobile-sidebar-gestures.js +17 -9
- package/data/build/dist/client/mobile-sidebar-gestures.js.map +1 -1
- package/data/build/dist/client/model-catalog-cache.d.ts +4 -4
- package/data/build/dist/client/model-catalog-cache.d.ts.map +1 -1
- package/data/build/dist/client/model-catalog-cache.js +66 -34
- package/data/build/dist/client/model-catalog-cache.js.map +1 -1
- package/data/build/dist/client/moss-voice-output.d.ts +39 -0
- package/data/build/dist/client/moss-voice-output.d.ts.map +1 -0
- package/data/build/dist/client/moss-voice-output.js +241 -0
- package/data/build/dist/client/moss-voice-output.js.map +1 -0
- package/data/build/dist/client/rpc-call.d.ts +4 -0
- package/data/build/dist/client/rpc-call.d.ts.map +1 -0
- package/data/build/dist/client/rpc-call.js +23 -0
- package/data/build/dist/client/rpc-call.js.map +1 -0
- package/data/build/dist/client/serial-polling.d.ts +13 -0
- package/data/build/dist/client/serial-polling.d.ts.map +1 -0
- package/data/build/dist/client/serial-polling.js +41 -0
- package/data/build/dist/client/serial-polling.js.map +1 -0
- package/data/build/dist/client/session-adapter-cache.d.ts.map +1 -1
- package/data/build/dist/client/session-adapter-cache.js +11 -1
- package/data/build/dist/client/session-adapter-cache.js.map +1 -1
- package/data/build/dist/client/settings-bridge.d.ts +1 -0
- package/data/build/dist/client/settings-bridge.d.ts.map +1 -1
- package/data/build/dist/client/settings-bridge.js +9 -1
- package/data/build/dist/client/settings-bridge.js.map +1 -1
- package/data/build/dist/client/sherpa-voice-adapter.d.ts +23 -2
- package/data/build/dist/client/sherpa-voice-adapter.d.ts.map +1 -1
- package/data/build/dist/client/sherpa-voice-adapter.js +386 -93
- package/data/build/dist/client/sherpa-voice-adapter.js.map +1 -1
- package/data/build/dist/client/streaming-sentence-queue.d.ts +20 -0
- package/data/build/dist/client/streaming-sentence-queue.d.ts.map +1 -0
- package/data/build/dist/client/streaming-sentence-queue.js +130 -0
- package/data/build/dist/client/streaming-sentence-queue.js.map +1 -0
- package/data/build/dist/client/subscription-slot.d.ts +11 -0
- package/data/build/dist/client/subscription-slot.d.ts.map +1 -1
- package/data/build/dist/client/subscription-slot.js +42 -15
- package/data/build/dist/client/subscription-slot.js.map +1 -1
- package/data/build/dist/client/terminal/log-preview.d.ts +14 -0
- package/data/build/dist/client/terminal/log-preview.d.ts.map +1 -0
- package/data/build/dist/client/terminal/log-preview.js +23 -0
- package/data/build/dist/client/terminal/log-preview.js.map +1 -0
- package/data/build/dist/client/terminal/model.d.ts +38 -7
- package/data/build/dist/client/terminal/model.d.ts.map +1 -1
- package/data/build/dist/client/terminal/model.js +188 -32
- package/data/build/dist/client/terminal/model.js.map +1 -1
- package/data/build/dist/client/terminal/recovery.d.ts +7 -3
- package/data/build/dist/client/terminal/recovery.d.ts.map +1 -1
- package/data/build/dist/client/terminal/recovery.js +45 -41
- package/data/build/dist/client/terminal/recovery.js.map +1 -1
- package/data/build/dist/client/terminal/selection-actions.d.ts +63 -0
- package/data/build/dist/client/terminal/selection-actions.d.ts.map +1 -0
- package/data/build/dist/client/terminal/selection-actions.js +132 -0
- package/data/build/dist/client/terminal/selection-actions.js.map +1 -0
- package/data/build/dist/client/terminal/share-menu.d.ts +17 -0
- package/data/build/dist/client/terminal/share-menu.d.ts.map +1 -0
- package/data/build/dist/client/terminal/share-menu.js +131 -0
- package/data/build/dist/client/terminal/share-menu.js.map +1 -0
- package/data/build/dist/client/terminal/sharing.d.ts +42 -0
- package/data/build/dist/client/terminal/sharing.d.ts.map +1 -0
- package/data/build/dist/client/terminal/sharing.js +144 -0
- package/data/build/dist/client/terminal/sharing.js.map +1 -0
- package/data/build/dist/client/terminal/snapshot.d.ts +32 -0
- package/data/build/dist/client/terminal/snapshot.d.ts.map +1 -0
- package/data/build/dist/client/terminal/snapshot.js +108 -0
- package/data/build/dist/client/terminal/snapshot.js.map +1 -0
- package/data/build/dist/client/terminal/styles.d.ts +14 -0
- package/data/build/dist/client/terminal/styles.d.ts.map +1 -1
- package/data/build/dist/client/terminal/styles.js +39 -1
- package/data/build/dist/client/terminal/styles.js.map +1 -1
- package/data/build/dist/client/terminal/surface-cache.d.ts +10 -0
- package/data/build/dist/client/terminal/surface-cache.d.ts.map +1 -0
- package/data/build/dist/client/terminal/surface-cache.js +19 -0
- package/data/build/dist/client/terminal/surface-cache.js.map +1 -0
- package/data/build/dist/client/terminal/ui.d.ts.map +1 -1
- package/data/build/dist/client/terminal/ui.js +78 -21
- package/data/build/dist/client/terminal/ui.js.map +1 -1
- package/data/build/dist/client/terminal/xterm-view.d.ts +5 -2
- package/data/build/dist/client/terminal/xterm-view.d.ts.map +1 -1
- package/data/build/dist/client/terminal/xterm-view.js +429 -397
- package/data/build/dist/client/terminal/xterm-view.js.map +1 -1
- package/data/build/dist/client/touch-input-focus.d.ts +30 -0
- package/data/build/dist/client/touch-input-focus.d.ts.map +1 -0
- package/data/build/dist/client/touch-input-focus.js +190 -0
- package/data/build/dist/client/touch-input-focus.js.map +1 -0
- package/data/build/dist/client/voice-capture.d.ts +9 -0
- package/data/build/dist/client/voice-capture.d.ts.map +1 -1
- package/data/build/dist/client/voice-capture.js +35 -1
- package/data/build/dist/client/voice-capture.js.map +1 -1
- package/data/build/dist/client/voice-chat-updates.d.ts +12 -0
- package/data/build/dist/client/voice-chat-updates.d.ts.map +1 -0
- package/data/build/dist/client/voice-chat-updates.js +39 -0
- package/data/build/dist/client/voice-chat-updates.js.map +1 -0
- package/data/build/dist/client/voice-diagnostics.d.ts +19 -0
- package/data/build/dist/client/voice-diagnostics.d.ts.map +1 -0
- package/data/build/dist/client/voice-diagnostics.js +73 -0
- package/data/build/dist/client/voice-diagnostics.js.map +1 -0
- package/data/build/dist/client/voice-model-setup-progress.d.ts +8 -0
- package/data/build/dist/client/voice-model-setup-progress.d.ts.map +1 -0
- package/data/build/dist/client/voice-model-setup-progress.js +27 -0
- package/data/build/dist/client/voice-model-setup-progress.js.map +1 -0
- package/data/build/dist/client/voice-stream-uploader.d.ts +41 -0
- package/data/build/dist/client/voice-stream-uploader.d.ts.map +1 -0
- package/data/build/dist/client/voice-stream-uploader.js +154 -0
- package/data/build/dist/client/voice-stream-uploader.js.map +1 -0
- package/data/build/dist/dsh-capabilities/client/config-forms-adapter.d.ts +4 -0
- package/data/build/dist/dsh-capabilities/client/config-forms-adapter.d.ts.map +1 -1
- package/data/build/dist/dsh-capabilities/client/config-forms-adapter.js +9 -0
- package/data/build/dist/dsh-capabilities/client/config-forms-adapter.js.map +1 -1
- package/data/build/dist/dsh-capabilities/client/primitives-adapter.d.ts +5 -1
- package/data/build/dist/dsh-capabilities/client/primitives-adapter.d.ts.map +1 -1
- package/data/build/dist/dsh-capabilities/client/primitives-adapter.js +25 -0
- package/data/build/dist/dsh-capabilities/client/primitives-adapter.js.map +1 -1
- package/data/build/dist/dsh-capabilities/client/terminal-sharing-adapter.d.ts +33 -0
- package/data/build/dist/dsh-capabilities/client/terminal-sharing-adapter.d.ts.map +1 -0
- package/data/build/dist/dsh-capabilities/client/terminal-sharing-adapter.js +187 -0
- package/data/build/dist/dsh-capabilities/client/terminal-sharing-adapter.js.map +1 -0
- package/data/build/dist/dsh-capabilities/host/assistant-agent-adapter.d.ts +55 -0
- package/data/build/dist/dsh-capabilities/host/assistant-agent-adapter.d.ts.map +1 -0
- package/data/build/dist/dsh-capabilities/host/assistant-agent-adapter.js +264 -0
- package/data/build/dist/dsh-capabilities/host/assistant-agent-adapter.js.map +1 -0
- package/data/build/dist/dsh-capabilities/host/assistant-attachment-adapter.d.ts +16 -0
- package/data/build/dist/dsh-capabilities/host/assistant-attachment-adapter.d.ts.map +1 -0
- package/data/build/dist/dsh-capabilities/host/assistant-attachment-adapter.js +69 -0
- package/data/build/dist/dsh-capabilities/host/assistant-attachment-adapter.js.map +1 -0
- package/data/build/dist/dsh-capabilities/host/assistant-llm-adapter.d.ts +36 -0
- package/data/build/dist/dsh-capabilities/host/assistant-llm-adapter.d.ts.map +1 -0
- package/data/build/dist/dsh-capabilities/host/assistant-llm-adapter.js +112 -0
- package/data/build/dist/dsh-capabilities/host/assistant-llm-adapter.js.map +1 -0
- package/data/build/dist/dsh-capabilities/host/assistant-web-search-adapter.d.ts +4 -0
- package/data/build/dist/dsh-capabilities/host/assistant-web-search-adapter.d.ts.map +1 -0
- package/data/build/dist/dsh-capabilities/host/assistant-web-search-adapter.js +41 -0
- package/data/build/dist/dsh-capabilities/host/assistant-web-search-adapter.js.map +1 -0
- package/data/build/dist/dsh-capabilities/matrix.d.ts.map +1 -1
- package/data/build/dist/dsh-capabilities/matrix.js +3 -0
- package/data/build/dist/dsh-capabilities/matrix.js.map +1 -1
- package/data/build/dist/dsh-capabilities/routes.d.ts.map +1 -1
- package/data/build/dist/dsh-capabilities/routes.js +18 -0
- package/data/build/dist/dsh-capabilities/routes.js.map +1 -1
- package/data/build/dist/dsh-capabilities/settings-store.d.ts +2 -0
- package/data/build/dist/dsh-capabilities/settings-store.d.ts.map +1 -1
- package/data/build/dist/dsh-capabilities/settings-store.js.map +1 -1
- package/data/build/dist/dsh-capabilities/types.d.ts +1 -1
- package/data/build/dist/dsh-capabilities/types.d.ts.map +1 -1
- package/data/build/dist/dsh-capabilities/types.js.map +1 -1
- package/data/build/dist/host/avatar/catalog.d.ts +21 -0
- package/data/build/dist/host/avatar/catalog.d.ts.map +1 -0
- package/data/build/dist/host/avatar/catalog.js +123 -0
- package/data/build/dist/host/avatar/catalog.js.map +1 -0
- package/data/build/dist/host/avatar/engine.d.ts +42 -0
- package/data/build/dist/host/avatar/engine.d.ts.map +1 -0
- package/data/build/dist/host/avatar/engine.js +167 -0
- package/data/build/dist/host/avatar/engine.js.map +1 -0
- package/data/build/dist/host/avatar/materials.d.ts +28 -0
- package/data/build/dist/host/avatar/materials.d.ts.map +1 -0
- package/data/build/dist/host/avatar/materials.js +183 -0
- package/data/build/dist/host/avatar/materials.js.map +1 -0
- package/data/build/dist/host/avatar/packages.d.ts +34 -0
- package/data/build/dist/host/avatar/packages.d.ts.map +1 -0
- package/data/build/dist/host/avatar/packages.js +200 -0
- package/data/build/dist/host/avatar/packages.js.map +1 -0
- package/data/build/dist/host/avatar/registry.d.ts +12 -0
- package/data/build/dist/host/avatar/registry.d.ts.map +1 -0
- package/data/build/dist/host/avatar/registry.js +22 -0
- package/data/build/dist/host/avatar/registry.js.map +1 -0
- package/data/build/dist/host/avatar/remote.d.ts +18 -0
- package/data/build/dist/host/avatar/remote.d.ts.map +1 -0
- package/data/build/dist/host/avatar/remote.js +103 -0
- package/data/build/dist/host/avatar/remote.js.map +1 -0
- package/data/build/dist/host/avatar/sources.d.ts +11 -0
- package/data/build/dist/host/avatar/sources.d.ts.map +1 -0
- package/data/build/dist/host/avatar/sources.js +78 -0
- package/data/build/dist/host/avatar/sources.js.map +1 -0
- package/data/build/dist/host/avatar/temporary-previews.d.ts +26 -0
- package/data/build/dist/host/avatar/temporary-previews.d.ts.map +1 -0
- package/data/build/dist/host/avatar/temporary-previews.js +139 -0
- package/data/build/dist/host/avatar/temporary-previews.js.map +1 -0
- package/data/build/dist/host/cli-adapters/acp-cli-driver.d.ts +1 -1
- package/data/build/dist/host/cli-adapters/acp-cli-driver.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/acp-cli-driver.js +3 -10
- package/data/build/dist/host/cli-adapters/acp-cli-driver.js.map +1 -1
- package/data/build/dist/host/cli-adapters/antigravity-subscription.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/antigravity-subscription.js +10 -10
- package/data/build/dist/host/cli-adapters/antigravity-subscription.js.map +1 -1
- package/data/build/dist/host/cli-adapters/claude-driver.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/claude-driver.js +7 -5
- package/data/build/dist/host/cli-adapters/claude-driver.js.map +1 -1
- package/data/build/dist/host/cli-adapters/codebuddy-driver.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/codebuddy-driver.js +8 -7
- package/data/build/dist/host/cli-adapters/codebuddy-driver.js.map +1 -1
- package/data/build/dist/host/cli-adapters/codex-driver.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/codex-driver.js +10 -3
- package/data/build/dist/host/cli-adapters/codex-driver.js.map +1 -1
- package/data/build/dist/host/cli-adapters/command-code-driver.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/command-code-driver.js +9 -8
- package/data/build/dist/host/cli-adapters/command-code-driver.js.map +1 -1
- package/data/build/dist/host/cli-adapters/cursor-driver.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/cursor-driver.js +4 -3
- package/data/build/dist/host/cli-adapters/cursor-driver.js.map +1 -1
- package/data/build/dist/host/cli-adapters/delegate-dispatch.js +1 -1
- package/data/build/dist/host/cli-adapters/delegate-dispatch.js.map +1 -1
- package/data/build/dist/host/cli-adapters/delegation-mention-rewrite.d.ts +2 -0
- package/data/build/dist/host/cli-adapters/delegation-mention-rewrite.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/delegation-mention-rewrite.js +5 -0
- package/data/build/dist/host/cli-adapters/delegation-mention-rewrite.js.map +1 -1
- package/data/build/dist/host/cli-adapters/desktop-app-runtime.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/desktop-app-runtime.js +2 -4
- package/data/build/dist/host/cli-adapters/desktop-app-runtime.js.map +1 -1
- package/data/build/dist/host/cli-adapters/driver.d.ts +1 -1
- package/data/build/dist/host/cli-adapters/feature.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/feature.js +28 -36
- package/data/build/dist/host/cli-adapters/feature.js.map +1 -1
- package/data/build/dist/host/cli-adapters/grok-driver.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/grok-driver.js +2 -1
- package/data/build/dist/host/cli-adapters/grok-driver.js.map +1 -1
- package/data/build/dist/host/cli-adapters/kimi-driver.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/kimi-driver.js +4 -3
- package/data/build/dist/host/cli-adapters/kimi-driver.js.map +1 -1
- package/data/build/dist/host/cli-adapters/legacy-session-adapter.d.ts +2 -0
- package/data/build/dist/host/cli-adapters/legacy-session-adapter.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/legacy-session-adapter.js +10 -0
- package/data/build/dist/host/cli-adapters/legacy-session-adapter.js.map +1 -1
- package/data/build/dist/host/cli-adapters/log-files.d.ts +3 -0
- package/data/build/dist/host/cli-adapters/log-files.d.ts.map +1 -0
- package/data/build/dist/host/cli-adapters/log-files.js +32 -0
- package/data/build/dist/host/cli-adapters/log-files.js.map +1 -0
- package/data/build/dist/host/cli-adapters/native-team-subagent.js +1 -1
- package/data/build/dist/host/cli-adapters/native-team-subagent.js.map +1 -1
- package/data/build/dist/host/cli-adapters/opencode-driver.d.ts +10 -0
- package/data/build/dist/host/cli-adapters/opencode-driver.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/opencode-driver.js +128 -26
- package/data/build/dist/host/cli-adapters/opencode-driver.js.map +1 -1
- package/data/build/dist/host/cli-adapters/opencode-v2-protocol.d.ts +29 -0
- package/data/build/dist/host/cli-adapters/opencode-v2-protocol.d.ts.map +1 -0
- package/data/build/dist/host/cli-adapters/opencode-v2-protocol.js +471 -0
- package/data/build/dist/host/cli-adapters/opencode-v2-protocol.js.map +1 -0
- package/data/build/dist/host/cli-adapters/pi-driver.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/pi-driver.js +2 -1
- package/data/build/dist/host/cli-adapters/pi-driver.js.map +1 -1
- package/data/build/dist/host/cli-adapters/process-utils.d.ts +8 -2
- package/data/build/dist/host/cli-adapters/process-utils.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/process-utils.js +90 -9
- package/data/build/dist/host/cli-adapters/process-utils.js.map +1 -1
- package/data/build/dist/host/cli-adapters/qoder-driver.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/qoder-driver.js +55 -72
- package/data/build/dist/host/cli-adapters/qoder-driver.js.map +1 -1
- package/data/build/dist/host/cli-adapters/qoder-subscription.d.ts +6 -1
- package/data/build/dist/host/cli-adapters/qoder-subscription.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/qoder-subscription.js +37 -10
- package/data/build/dist/host/cli-adapters/qoder-subscription.js.map +1 -1
- package/data/build/dist/host/cli-adapters/registry.d.ts +13 -21
- package/data/build/dist/host/cli-adapters/registry.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/registry.js +71 -127
- package/data/build/dist/host/cli-adapters/registry.js.map +1 -1
- package/data/build/dist/host/cli-adapters/rpc-driver-utils.d.ts +1 -0
- package/data/build/dist/host/cli-adapters/rpc-driver-utils.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/rpc-driver-utils.js +6 -6
- package/data/build/dist/host/cli-adapters/rpc-driver-utils.js.map +1 -1
- package/data/build/dist/host/cli-adapters/session-store.d.ts +5 -1
- package/data/build/dist/host/cli-adapters/session-store.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/session-store.js +68 -11
- package/data/build/dist/host/cli-adapters/session-store.js.map +1 -1
- package/data/build/dist/host/cli-adapters/standard-stream-driver.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/standard-stream-driver.js +4 -3
- package/data/build/dist/host/cli-adapters/standard-stream-driver.js.map +1 -1
- package/data/build/dist/host/cli-bridge/dispatch.js +1 -1
- package/data/build/dist/host/cli-bridge/dispatch.js.map +1 -1
- package/data/build/dist/host/debug.d.ts.map +1 -1
- package/data/build/dist/host/debug.js +5 -4
- package/data/build/dist/host/debug.js.map +1 -1
- package/data/build/dist/host/desktop-assistant/controller.d.ts +44 -0
- package/data/build/dist/host/desktop-assistant/controller.d.ts.map +1 -0
- package/data/build/dist/host/desktop-assistant/controller.js +150 -0
- package/data/build/dist/host/desktop-assistant/controller.js.map +1 -0
- package/data/build/dist/host/desktop-assistant/feature.d.ts +9 -0
- package/data/build/dist/host/desktop-assistant/feature.d.ts.map +1 -0
- package/data/build/dist/host/desktop-assistant/feature.js +102 -0
- package/data/build/dist/host/desktop-assistant/feature.js.map +1 -0
- package/data/build/dist/host/desktop-assistant/launcher.d.ts +5 -0
- package/data/build/dist/host/desktop-assistant/launcher.d.ts.map +1 -0
- package/data/build/dist/host/desktop-assistant/launcher.js +84 -0
- package/data/build/dist/host/desktop-assistant/launcher.js.map +1 -0
- package/data/build/dist/host/desktop-assistant/mac-agent.d.ts +5 -0
- package/data/build/dist/host/desktop-assistant/mac-agent.d.ts.map +1 -0
- package/data/build/dist/host/desktop-assistant/mac-agent.js +122 -0
- package/data/build/dist/host/desktop-assistant/mac-agent.js.map +1 -0
- package/data/build/dist/host/desktop-assistant/process.d.ts +4 -0
- package/data/build/dist/host/desktop-assistant/process.d.ts.map +1 -0
- package/data/build/dist/host/desktop-assistant/process.js +25 -0
- package/data/build/dist/host/desktop-assistant/process.js.map +1 -0
- package/data/build/dist/host/desktop-assistant/server.d.ts +12 -0
- package/data/build/dist/host/desktop-assistant/server.d.ts.map +1 -0
- package/data/build/dist/host/desktop-assistant/server.js +74 -0
- package/data/build/dist/host/desktop-assistant/server.js.map +1 -0
- package/data/build/dist/host/desktop-assistant/win-agent.d.ts +2 -0
- package/data/build/dist/host/desktop-assistant/win-agent.d.ts.map +1 -0
- package/data/build/dist/host/desktop-assistant/win-agent.js +197 -0
- package/data/build/dist/host/desktop-assistant/win-agent.js.map +1 -0
- package/data/build/dist/host/dsh-runtime-version.d.ts +1 -1
- package/data/build/dist/host/dsh-runtime-version.d.ts.map +1 -1
- package/data/build/dist/host/dsh-runtime-version.js +22 -17
- package/data/build/dist/host/dsh-runtime-version.js.map +1 -1
- package/data/build/dist/host/features/assistant-avatar-assets.d.ts +3 -0
- package/data/build/dist/host/features/assistant-avatar-assets.d.ts.map +1 -0
- package/data/build/dist/host/features/assistant-avatar-assets.js +3 -0
- package/data/build/dist/host/features/assistant-avatar-assets.js.map +1 -0
- package/data/build/dist/host/features/assistant-avatar-basics.d.ts +3 -0
- package/data/build/dist/host/features/assistant-avatar-basics.d.ts.map +1 -0
- package/data/build/dist/host/features/assistant-avatar-basics.js +34 -0
- package/data/build/dist/host/features/assistant-avatar-basics.js.map +1 -0
- package/data/build/dist/host/features/assistant-avatar-legacy-assets.d.ts +6 -0
- package/data/build/dist/host/features/assistant-avatar-legacy-assets.d.ts.map +1 -0
- package/data/build/dist/host/features/assistant-avatar-legacy-assets.js +146 -0
- package/data/build/dist/host/features/assistant-avatar-legacy-assets.js.map +1 -0
- package/data/build/dist/host/features/assistant-avatar-runtime.d.ts +20 -0
- package/data/build/dist/host/features/assistant-avatar-runtime.d.ts.map +1 -0
- package/data/build/dist/host/features/assistant-avatar-runtime.js +250 -0
- package/data/build/dist/host/features/assistant-avatar-runtime.js.map +1 -0
- package/data/build/dist/host/features/assistant-conversation-storage.d.ts +8 -0
- package/data/build/dist/host/features/assistant-conversation-storage.d.ts.map +1 -0
- package/data/build/dist/host/features/assistant-conversation-storage.js +38 -0
- package/data/build/dist/host/features/assistant-conversation-storage.js.map +1 -0
- package/data/build/dist/host/features/assistant-conversation.d.ts +57 -0
- package/data/build/dist/host/features/assistant-conversation.d.ts.map +1 -0
- package/data/build/dist/host/features/assistant-conversation.js +364 -0
- package/data/build/dist/host/features/assistant-conversation.js.map +1 -0
- package/data/build/dist/host/features/assistant-dispatch.d.ts +2 -2
- package/data/build/dist/host/features/assistant-dispatch.d.ts.map +1 -1
- package/data/build/dist/host/features/assistant-dispatch.js +4 -3
- package/data/build/dist/host/features/assistant-dispatch.js.map +1 -1
- package/data/build/dist/host/features/assistant-index-analysis.d.ts +49 -0
- package/data/build/dist/host/features/assistant-index-analysis.d.ts.map +1 -0
- package/data/build/dist/host/features/assistant-index-analysis.js +255 -0
- package/data/build/dist/host/features/assistant-index-analysis.js.map +1 -0
- package/data/build/dist/host/features/assistant-index-journal.d.ts +20 -0
- package/data/build/dist/host/features/assistant-index-journal.d.ts.map +1 -0
- package/data/build/dist/host/features/assistant-index-journal.js +40 -0
- package/data/build/dist/host/features/assistant-index-journal.js.map +1 -0
- package/data/build/dist/host/features/assistant-index-retry.d.ts +12 -0
- package/data/build/dist/host/features/assistant-index-retry.d.ts.map +1 -0
- package/data/build/dist/host/features/assistant-index-retry.js +54 -0
- package/data/build/dist/host/features/assistant-index-retry.js.map +1 -0
- package/data/build/dist/host/features/assistant-index-updates.d.ts +40 -0
- package/data/build/dist/host/features/assistant-index-updates.d.ts.map +1 -0
- package/data/build/dist/host/features/assistant-index-updates.js +183 -0
- package/data/build/dist/host/features/assistant-index-updates.js.map +1 -0
- package/data/build/dist/host/features/assistant-lifecycle-settings.d.ts +5 -0
- package/data/build/dist/host/features/assistant-lifecycle-settings.d.ts.map +1 -0
- package/data/build/dist/host/features/assistant-lifecycle-settings.js +72 -0
- package/data/build/dist/host/features/assistant-lifecycle-settings.js.map +1 -0
- package/data/build/dist/host/features/assistant-management-tools.d.ts +34 -0
- package/data/build/dist/host/features/assistant-management-tools.d.ts.map +1 -0
- package/data/build/dist/host/features/assistant-management-tools.js +69 -0
- package/data/build/dist/host/features/assistant-management-tools.js.map +1 -0
- package/data/build/dist/host/features/assistant-prompts.d.ts +6 -0
- package/data/build/dist/host/features/assistant-prompts.d.ts.map +1 -0
- package/data/build/dist/host/features/assistant-prompts.js +62 -0
- package/data/build/dist/host/features/assistant-prompts.js.map +1 -0
- package/data/build/dist/host/features/assistant-session-index.d.ts +6 -1
- package/data/build/dist/host/features/assistant-session-index.d.ts.map +1 -1
- package/data/build/dist/host/features/assistant-session-index.js +11 -12
- package/data/build/dist/host/features/assistant-session-index.js.map +1 -1
- package/data/build/dist/host/features/assistant-source-cache.d.ts +12 -0
- package/data/build/dist/host/features/assistant-source-cache.d.ts.map +1 -0
- package/data/build/dist/host/features/assistant-source-cache.js +56 -0
- package/data/build/dist/host/features/assistant-source-cache.js.map +1 -0
- package/data/build/dist/host/features/assistant-structured-index.d.ts +21 -0
- package/data/build/dist/host/features/assistant-structured-index.d.ts.map +1 -0
- package/data/build/dist/host/features/assistant-structured-index.js +138 -0
- package/data/build/dist/host/features/assistant-structured-index.js.map +1 -0
- package/data/build/dist/host/features/assistant-summary.d.ts.map +1 -1
- package/data/build/dist/host/features/assistant-summary.js +7 -1
- package/data/build/dist/host/features/assistant-summary.js.map +1 -1
- package/data/build/dist/host/features/assistant-text-chat.d.ts +29 -0
- package/data/build/dist/host/features/assistant-text-chat.d.ts.map +1 -0
- package/data/build/dist/host/features/assistant-text-chat.js +195 -0
- package/data/build/dist/host/features/assistant-text-chat.js.map +1 -0
- package/data/build/dist/host/features/assistant-tts-service.d.ts +47 -0
- package/data/build/dist/host/features/assistant-tts-service.d.ts.map +1 -0
- package/data/build/dist/host/features/assistant-tts-service.js +507 -0
- package/data/build/dist/host/features/assistant-tts-service.js.map +1 -0
- package/data/build/dist/host/features/assistant-voice-chat.d.ts +35 -0
- package/data/build/dist/host/features/assistant-voice-chat.d.ts.map +1 -0
- package/data/build/dist/host/features/assistant-voice-chat.js +133 -0
- package/data/build/dist/host/features/assistant-voice-chat.js.map +1 -0
- package/data/build/dist/host/features/assistant-voice-hotwords.d.ts +33 -0
- package/data/build/dist/host/features/assistant-voice-hotwords.d.ts.map +1 -0
- package/data/build/dist/host/features/assistant-voice-hotwords.js +114 -0
- package/data/build/dist/host/features/assistant-voice-hotwords.js.map +1 -0
- package/data/build/dist/host/features/assistant-voice-initialization.d.ts +26 -0
- package/data/build/dist/host/features/assistant-voice-initialization.d.ts.map +1 -0
- package/data/build/dist/host/features/assistant-voice-initialization.js +68 -0
- package/data/build/dist/host/features/assistant-voice-initialization.js.map +1 -0
- package/data/build/dist/host/features/assistant-voice-sources.d.ts +13 -0
- package/data/build/dist/host/features/assistant-voice-sources.d.ts.map +1 -0
- package/data/build/dist/host/features/assistant-voice-sources.js +72 -0
- package/data/build/dist/host/features/assistant-voice-sources.js.map +1 -0
- package/data/build/dist/host/features/assistant-voice-stream.d.ts +10 -0
- package/data/build/dist/host/features/assistant-voice-stream.d.ts.map +1 -1
- package/data/build/dist/host/features/assistant-voice-stream.js +208 -5
- package/data/build/dist/host/features/assistant-voice-stream.js.map +1 -1
- package/data/build/dist/host/features/global-voice-coordinator.d.ts.map +1 -1
- package/data/build/dist/host/features/global-voice-coordinator.js +15 -10
- package/data/build/dist/host/features/global-voice-coordinator.js.map +1 -1
- package/data/build/dist/host/features/global-voice-rpc.d.ts +8 -1
- package/data/build/dist/host/features/global-voice-rpc.d.ts.map +1 -1
- package/data/build/dist/host/features/global-voice-rpc.js +1076 -159
- package/data/build/dist/host/features/global-voice-rpc.js.map +1 -1
- package/data/build/dist/host/features/index.d.ts.map +1 -1
- package/data/build/dist/host/features/index.js +4 -0
- package/data/build/dist/host/features/index.js.map +1 -1
- package/data/build/dist/host/features/moss-tts-worker.d.ts +32 -0
- package/data/build/dist/host/features/moss-tts-worker.d.ts.map +1 -0
- package/data/build/dist/host/features/moss-tts-worker.js +216 -0
- package/data/build/dist/host/features/moss-tts-worker.js.map +1 -0
- package/data/build/dist/host/features/peer-host.d.ts.map +1 -1
- package/data/build/dist/host/features/peer-host.js +15 -7
- package/data/build/dist/host/features/peer-host.js.map +1 -1
- package/data/build/dist/host/features/sherpa-voice-runtime.d.ts +11 -0
- package/data/build/dist/host/features/sherpa-voice-runtime.d.ts.map +1 -1
- package/data/build/dist/host/features/sherpa-voice-runtime.js +72 -17
- package/data/build/dist/host/features/sherpa-voice-runtime.js.map +1 -1
- package/data/build/dist/host/features/sherpa-voice-worker.d.ts +18 -0
- package/data/build/dist/host/features/sherpa-voice-worker.d.ts.map +1 -0
- package/data/build/dist/host/features/sherpa-voice-worker.js +40 -0
- package/data/build/dist/host/features/sherpa-voice-worker.js.map +1 -0
- package/data/build/dist/host/features/sherpa-worker-runtime.d.ts +41 -0
- package/data/build/dist/host/features/sherpa-worker-runtime.d.ts.map +1 -0
- package/data/build/dist/host/features/sherpa-worker-runtime.js +200 -0
- package/data/build/dist/host/features/sherpa-worker-runtime.js.map +1 -0
- package/data/build/dist/host/features/types.d.ts +9 -1
- package/data/build/dist/host/features/types.d.ts.map +1 -1
- package/data/build/dist/host/features/voice-model-management.d.ts +22 -0
- package/data/build/dist/host/features/voice-model-management.d.ts.map +1 -0
- package/data/build/dist/host/features/voice-model-management.js +178 -0
- package/data/build/dist/host/features/voice-model-management.js.map +1 -0
- package/data/build/dist/host/features/voice-model-probe.d.ts +8 -0
- package/data/build/dist/host/features/voice-model-probe.d.ts.map +1 -0
- package/data/build/dist/host/features/voice-model-probe.js +76 -0
- package/data/build/dist/host/features/voice-model-probe.js.map +1 -0
- package/data/build/dist/host/features/voice-model-setup.d.ts +5 -2
- package/data/build/dist/host/features/voice-model-setup.d.ts.map +1 -1
- package/data/build/dist/host/features/voice-model-setup.js +40 -13
- package/data/build/dist/host/features/voice-model-setup.js.map +1 -1
- package/data/build/dist/host/features/voice-process-environment.d.ts +3 -0
- package/data/build/dist/host/features/voice-process-environment.d.ts.map +1 -0
- package/data/build/dist/host/features/voice-process-environment.js +16 -0
- package/data/build/dist/host/features/voice-process-environment.js.map +1 -0
- package/data/build/dist/host/features/voice-python-runtime.d.ts +21 -0
- package/data/build/dist/host/features/voice-python-runtime.d.ts.map +1 -0
- package/data/build/dist/host/features/voice-python-runtime.js +189 -0
- package/data/build/dist/host/features/voice-python-runtime.js.map +1 -0
- package/data/build/dist/host/index-injection.d.ts.map +1 -1
- package/data/build/dist/host/index-injection.js +5 -1
- package/data/build/dist/host/index-injection.js.map +1 -1
- package/data/build/dist/host/index.d.ts +6 -1
- package/data/build/dist/host/index.d.ts.map +1 -1
- package/data/build/dist/host/index.js +32 -14
- package/data/build/dist/host/index.js.map +1 -1
- package/data/build/dist/host/lan-access-dsh.d.ts.map +1 -1
- package/data/build/dist/host/lan-access-dsh.js +7 -23
- package/data/build/dist/host/lan-access-dsh.js.map +1 -1
- package/data/build/dist/host/modules/peer-host/host-api-proxy-service.d.ts +6 -46
- package/data/build/dist/host/modules/peer-host/host-api-proxy-service.d.ts.map +1 -1
- package/data/build/dist/host/modules/peer-host/host-api-proxy-service.js +48 -28
- package/data/build/dist/host/modules/peer-host/host-api-proxy-service.js.map +1 -1
- package/data/build/dist/host/modules/peer-host/peer-host-aggregate-service.d.ts +1 -0
- package/data/build/dist/host/modules/peer-host/peer-host-aggregate-service.d.ts.map +1 -1
- package/data/build/dist/host/modules/peer-host/peer-host-aggregate-service.js +1 -0
- package/data/build/dist/host/modules/peer-host/peer-host-aggregate-service.js.map +1 -1
- package/data/build/dist/host/modules/peer-host/peer-host-diagnostics.d.ts.map +1 -1
- package/data/build/dist/host/modules/peer-host/peer-host-diagnostics.js +1 -0
- package/data/build/dist/host/modules/peer-host/peer-host-diagnostics.js.map +1 -1
- package/data/build/dist/host/modules/peer-host/peer-host-handshake.d.ts.map +1 -1
- package/data/build/dist/host/modules/peer-host/peer-host-handshake.js +4 -1
- package/data/build/dist/host/modules/peer-host/peer-host-handshake.js.map +1 -1
- package/data/build/dist/host/modules/peer-host/peer-host-remote-summary-source.js +12 -0
- package/data/build/dist/host/modules/peer-host/peer-host-remote-summary-source.js.map +1 -1
- package/data/build/dist/host/modules/peer-host/peer-host-session.d.ts +7 -1
- package/data/build/dist/host/modules/peer-host/peer-host-session.d.ts.map +1 -1
- package/data/build/dist/host/modules/peer-host/peer-host-session.js +40 -13
- package/data/build/dist/host/modules/peer-host/peer-host-session.js.map +1 -1
- package/data/build/dist/host/rpc.d.ts.map +1 -1
- package/data/build/dist/host/rpc.js +46 -5
- package/data/build/dist/host/rpc.js.map +1 -1
- package/data/build/dist/host/settings.d.ts +2 -1
- package/data/build/dist/host/settings.d.ts.map +1 -1
- package/data/build/dist/host/settings.js +77 -13
- package/data/build/dist/host/settings.js.map +1 -1
- package/data/build/dist/host/stage0-dev-hmr.d.ts +6 -0
- package/data/build/dist/host/stage0-dev-hmr.d.ts.map +1 -0
- package/data/build/dist/host/stage0-dev-hmr.js +20 -0
- package/data/build/dist/host/stage0-dev-hmr.js.map +1 -0
- package/data/build/dist/host/tar-archive.d.ts +8 -0
- package/data/build/dist/host/tar-archive.d.ts.map +1 -0
- package/data/build/dist/host/tar-archive.js +17 -0
- package/data/build/dist/host/tar-archive.js.map +1 -0
- package/data/build/dist/host/terminal/backends/tmux-backend.d.ts +1 -1
- package/data/build/dist/host/terminal/backends/tmux-backend.d.ts.map +1 -1
- package/data/build/dist/host/terminal/backends/tmux-backend.js +15 -14
- package/data/build/dist/host/terminal/backends/tmux-backend.js.map +1 -1
- package/data/build/dist/host/voice-diagnostics.d.ts +34 -0
- package/data/build/dist/host/voice-diagnostics.d.ts.map +1 -0
- package/data/build/dist/host/voice-diagnostics.js +124 -0
- package/data/build/dist/host/voice-diagnostics.js.map +1 -0
- package/data/build/dist/shared/assistant-attachments.d.ts +27 -0
- package/data/build/dist/shared/assistant-attachments.d.ts.map +1 -0
- package/data/build/dist/shared/assistant-attachments.js +45 -0
- package/data/build/dist/shared/assistant-attachments.js.map +1 -0
- package/data/build/dist/shared/assistant-avatar-adapters.d.ts +18 -0
- package/data/build/dist/shared/assistant-avatar-adapters.d.ts.map +1 -0
- package/data/build/dist/shared/assistant-avatar-adapters.js +119 -0
- package/data/build/dist/shared/assistant-avatar-adapters.js.map +1 -0
- package/data/build/dist/shared/assistant-avatar-catalog.d.ts +37 -0
- package/data/build/dist/shared/assistant-avatar-catalog.d.ts.map +1 -0
- package/data/build/dist/shared/assistant-avatar-catalog.js +21 -0
- package/data/build/dist/shared/assistant-avatar-catalog.js.map +1 -0
- package/data/build/dist/shared/assistant-avatar-engine.d.ts +34 -0
- package/data/build/dist/shared/assistant-avatar-engine.d.ts.map +1 -0
- package/data/build/dist/shared/assistant-avatar-engine.js +32 -0
- package/data/build/dist/shared/assistant-avatar-engine.js.map +1 -0
- package/data/build/dist/shared/assistant-avatar-installation.d.ts +17 -0
- package/data/build/dist/shared/assistant-avatar-installation.d.ts.map +1 -0
- package/data/build/dist/shared/assistant-avatar-installation.js +7 -0
- package/data/build/dist/shared/assistant-avatar-installation.js.map +1 -0
- package/data/build/dist/shared/assistant-avatar-legacy-resources.d.ts +6 -0
- package/data/build/dist/shared/assistant-avatar-legacy-resources.d.ts.map +1 -0
- package/data/build/dist/shared/assistant-avatar-legacy-resources.js +20 -0
- package/data/build/dist/shared/assistant-avatar-legacy-resources.js.map +1 -0
- package/data/build/dist/shared/assistant-avatar-legacy.d.ts +15 -0
- package/data/build/dist/shared/assistant-avatar-legacy.d.ts.map +1 -0
- package/data/build/dist/shared/assistant-avatar-legacy.js +34 -0
- package/data/build/dist/shared/assistant-avatar-legacy.js.map +1 -0
- package/data/build/dist/shared/assistant-avatar-presets.d.ts +3 -0
- package/data/build/dist/shared/assistant-avatar-presets.d.ts.map +1 -0
- package/data/build/dist/shared/assistant-avatar-presets.js +3 -0
- package/data/build/dist/shared/assistant-avatar-presets.js.map +1 -0
- package/data/build/dist/shared/assistant-avatar-registration.d.ts +16 -0
- package/data/build/dist/shared/assistant-avatar-registration.d.ts.map +1 -0
- package/data/build/dist/shared/assistant-avatar-registration.js +33 -0
- package/data/build/dist/shared/assistant-avatar-registration.js.map +1 -0
- package/data/build/dist/shared/assistant-avatar-resources.d.ts +26 -0
- package/data/build/dist/shared/assistant-avatar-resources.d.ts.map +1 -0
- package/data/build/dist/shared/assistant-avatar-resources.js +4 -0
- package/data/build/dist/shared/assistant-avatar-resources.js.map +1 -0
- package/data/build/dist/shared/assistant-avatar.d.ts +103 -0
- package/data/build/dist/shared/assistant-avatar.d.ts.map +1 -0
- package/data/build/dist/shared/assistant-avatar.js +240 -0
- package/data/build/dist/shared/assistant-avatar.js.map +1 -0
- package/data/build/dist/shared/assistant-commands.d.ts +3 -0
- package/data/build/dist/shared/assistant-commands.d.ts.map +1 -0
- package/data/build/dist/shared/assistant-commands.js +3 -0
- package/data/build/dist/shared/assistant-commands.js.map +1 -0
- package/data/build/dist/shared/assistant-lifecycle.d.ts +17 -0
- package/data/build/dist/shared/assistant-lifecycle.d.ts.map +1 -0
- package/data/build/dist/shared/assistant-lifecycle.js +45 -0
- package/data/build/dist/shared/assistant-lifecycle.js.map +1 -0
- package/data/build/dist/shared/assistant-message-timeline.d.ts +13 -0
- package/data/build/dist/shared/assistant-message-timeline.d.ts.map +1 -0
- package/data/build/dist/shared/assistant-message-timeline.js +22 -0
- package/data/build/dist/shared/assistant-message-timeline.js.map +1 -0
- package/data/build/dist/shared/assistant-prompts.d.ts +12 -0
- package/data/build/dist/shared/assistant-prompts.d.ts.map +1 -0
- package/data/build/dist/shared/assistant-prompts.js +32 -0
- package/data/build/dist/shared/assistant-prompts.js.map +1 -0
- package/data/build/dist/shared/assistant-tts.d.ts +93 -0
- package/data/build/dist/shared/assistant-tts.d.ts.map +1 -0
- package/data/build/dist/shared/assistant-tts.js +80 -0
- package/data/build/dist/shared/assistant-tts.js.map +1 -0
- package/data/build/dist/shared/assistant-voice-sessions.d.ts +13 -0
- package/data/build/dist/shared/assistant-voice-sessions.d.ts.map +1 -0
- package/data/build/dist/shared/assistant-voice-sessions.js +16 -0
- package/data/build/dist/shared/assistant-voice-sessions.js.map +1 -0
- package/data/build/dist/shared/contracts/assistant.d.ts +206 -0
- package/data/build/dist/shared/contracts/assistant.d.ts.map +1 -1
- package/data/build/dist/shared/contracts/cli-adapter.d.ts +3 -0
- package/data/build/dist/shared/contracts/cli-adapter.d.ts.map +1 -1
- package/data/build/dist/shared/contracts/config.d.ts +23 -0
- package/data/build/dist/shared/contracts/config.d.ts.map +1 -1
- package/data/build/dist/shared/contracts/config.js +2 -0
- package/data/build/dist/shared/contracts/config.js.map +1 -1
- package/data/build/dist/shared/contracts/errors.d.ts +1 -0
- package/data/build/dist/shared/contracts/errors.d.ts.map +1 -1
- package/data/build/dist/shared/contracts/errors.js +1 -0
- package/data/build/dist/shared/contracts/errors.js.map +1 -1
- package/data/build/dist/shared/contracts/peer-host.d.ts +3 -0
- package/data/build/dist/shared/contracts/peer-host.d.ts.map +1 -1
- package/data/build/dist/shared/contracts/peer-host.js +1 -0
- package/data/build/dist/shared/contracts/peer-host.js.map +1 -1
- package/data/build/dist/shared/contracts/terminal-share.d.ts +27 -0
- package/data/build/dist/shared/contracts/terminal-share.d.ts.map +1 -0
- package/data/build/dist/shared/contracts/terminal-share.js +2 -0
- package/data/build/dist/shared/contracts/terminal-share.js.map +1 -0
- package/data/build/dist/shared/contracts/version.d.ts +3 -1
- package/data/build/dist/shared/contracts/version.d.ts.map +1 -1
- package/data/build/dist/shared/contracts/version.js +20 -7
- package/data/build/dist/shared/contracts/version.js.map +1 -1
- package/data/build/dist/shared/contracts/voice-runtime.d.ts +15 -1
- package/data/build/dist/shared/contracts/voice-runtime.d.ts.map +1 -1
- package/data/build/dist/shared/contracts/voice-runtime.js.map +1 -1
- package/data/build/dist/shared/desktop-assistant.d.ts +35 -0
- package/data/build/dist/shared/desktop-assistant.d.ts.map +1 -0
- package/data/build/dist/shared/desktop-assistant.js +27 -0
- package/data/build/dist/shared/desktop-assistant.js.map +1 -0
- package/data/build/dist/shared/index.d.ts +16 -2
- package/data/build/dist/shared/index.d.ts.map +1 -1
- package/data/build/dist/shared/index.js +10 -0
- package/data/build/dist/shared/index.js.map +1 -1
- package/data/build/dist/shared/peer-host-http-routes.d.ts +62 -0
- package/data/build/dist/shared/peer-host-http-routes.d.ts.map +1 -0
- package/data/build/dist/shared/peer-host-http-routes.js +31 -0
- package/data/build/dist/shared/peer-host-http-routes.js.map +1 -0
- package/data/build/dist/shared/runtime-environment.d.ts +5 -0
- package/data/build/dist/shared/runtime-environment.d.ts.map +1 -0
- package/data/build/dist/shared/runtime-environment.js +7 -0
- package/data/build/dist/shared/runtime-environment.js.map +1 -0
- package/data/build/dist/shared/voice-diagnostics.d.ts +18 -0
- package/data/build/dist/shared/voice-diagnostics.d.ts.map +1 -0
- package/data/build/dist/shared/voice-diagnostics.js +57 -0
- package/data/build/dist/shared/voice-diagnostics.js.map +1 -0
- package/data/build/dist/shared/voice-initialization.d.ts +22 -0
- package/data/build/dist/shared/voice-initialization.d.ts.map +1 -0
- package/data/build/dist/shared/voice-initialization.js +4 -0
- package/data/build/dist/shared/voice-initialization.js.map +1 -0
- package/data/build/dist/shared/voice-models.d.ts +43 -0
- package/data/build/dist/shared/voice-models.d.ts.map +1 -1
- package/data/build/dist/shared/voice-models.js +23 -8
- package/data/build/dist/shared/voice-models.js.map +1 -1
- package/data/build/dist/shared/voice-stream.d.ts +12 -1
- package/data/build/dist/shared/voice-stream.d.ts.map +1 -1
- package/data/build/dist/shared/voice-stream.js +8 -1
- package/data/build/dist/shared/voice-stream.js.map +1 -1
- package/package.json +19 -3
- package/profile/README.md +2 -2
- package/profile/package.json +2 -2
- package/profile/version.json +1 -1
- package/version.json +1 -1
|
@@ -4,22 +4,48 @@ import { AssistantDispatcher } from './assistant-dispatch.js';
|
|
|
4
4
|
import { AssistantVoiceTurnRouter } from './assistant-voice-turn.js';
|
|
5
5
|
import { buildAssistantSessionIndex } from './assistant-session-index.js';
|
|
6
6
|
import { sanitizeSpeechText, summarizeAssistantEntries } from './assistant-summary.js';
|
|
7
|
+
import { parseAssistantIntent } from './assistant-intent.js';
|
|
8
|
+
import { AssistantIndexUpdates, assistantSessionKey } from './assistant-index-updates.js';
|
|
9
|
+
import { readAssistantPrompts } from '../../shared/assistant-prompts.js';
|
|
10
|
+
import { createAssistantChatSystem } from './assistant-prompts.js';
|
|
11
|
+
import { speakAssistantStructuredIndex } from './assistant-structured-index.js';
|
|
12
|
+
import { AssistantIndexAnalysis } from './assistant-index-analysis.js';
|
|
13
|
+
import { AssistantIndexJournal } from './assistant-index-journal.js';
|
|
14
|
+
import { AssistantTextChat } from './assistant-text-chat.js';
|
|
15
|
+
import { AssistantVoiceChat } from './assistant-voice-chat.js';
|
|
16
|
+
import { createAssistantLlmAdapter } from '../../dsh-capabilities/host/assistant-llm-adapter.js';
|
|
17
|
+
import { createAssistantAgentAdapter, ASSISTANT_AGENT_PREFIX } from '../../dsh-capabilities/host/assistant-agent-adapter.js';
|
|
18
|
+
import { readAssistantAttachmentStore } from '../../dsh-capabilities/host/assistant-attachment-adapter.js';
|
|
19
|
+
import { readAssistantAttachmentUploads } from '../../shared/assistant-attachments.js';
|
|
20
|
+
import { createAssistantManagementTools } from './assistant-management-tools.js';
|
|
21
|
+
import { minimumSupportedDshVersion } from '../../shared/contracts/version.js';
|
|
7
22
|
import { GlobalVoiceCoordinator } from './global-voice-coordinator.js';
|
|
8
23
|
import { VoiceAgentService } from './voice-agent-service.js';
|
|
9
24
|
import { createAssistantVoiceActionBridge } from './voice-agent-actions.js';
|
|
10
25
|
import { AssistantWaitingState } from './assistant-waiting-state.js';
|
|
11
26
|
import { debugInfo } from '../../shared/debug.js';
|
|
12
27
|
import { createAssistantVoiceStreamHandler } from './assistant-voice-stream.js';
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
28
|
+
import { SherpaWorkerRuntime } from './sherpa-worker-runtime.js';
|
|
29
|
+
import { buildAssistantVoiceHotwords, readAssistantVoiceHotwords } from './assistant-voice-hotwords.js';
|
|
30
|
+
import { DEFAULT_ASSISTANT_SETTINGS, DEFAULT_ASSISTANT_VOICE_SETTINGS } from '../../shared/contracts/config.js';
|
|
31
|
+
import { AssistantVoiceModelManager } from './voice-model-management.js';
|
|
32
|
+
import { AssistantTtsService } from './assistant-tts-service.js';
|
|
33
|
+
import { AssistantConversation } from './assistant-conversation.js';
|
|
34
|
+
import { createAssistantConversationStorage } from './assistant-conversation-storage.js';
|
|
35
|
+
import { DEFAULT_ASSISTANT_NAME, assistantWorkspaceMatches, readAssistantProfile, readAssistantPersonality, validateAssistantModel, validateAssistantPersonality } from '../../shared/assistant-lifecycle.js';
|
|
36
|
+
import { createVirtualWorkspaceId } from '../../shared/contracts/peer-host.js';
|
|
37
|
+
import { configureAssistantSettings } from './assistant-lifecycle-settings.js';
|
|
38
|
+
import { AssistantVoiceInitialization } from './assistant-voice-initialization.js';
|
|
39
|
+
import { installVoiceDiagnostics } from '../voice-diagnostics.js';
|
|
40
|
+
import { measureVoice, traceVoice, sanitizeVoiceDiagnosticFields } from '../../shared/voice-diagnostics.js';
|
|
41
|
+
import { assistantSourceCache } from './assistant-source-cache.js';
|
|
16
42
|
/**
|
|
17
43
|
* 全局智能助理 Host 边界。
|
|
18
44
|
*
|
|
19
45
|
* 这里故意不接收 sessionId:会话索引、意图和派发各自通过快照协作,语音租约
|
|
20
46
|
* 只属于 Host。这样刷新页面或切换当前对话不会改变助理的目标范围。
|
|
21
47
|
*/
|
|
22
|
-
export function createGlobalVoiceRpcFeature() {
|
|
48
|
+
export function createGlobalVoiceRpcFeature(options = {}) {
|
|
23
49
|
return {
|
|
24
50
|
descriptor: {
|
|
25
51
|
name: 'globalVoiceRpc',
|
|
@@ -27,9 +53,19 @@ export function createGlobalVoiceRpcFeature() {
|
|
|
27
53
|
enabledByDefault: true,
|
|
28
54
|
dependencies: [],
|
|
29
55
|
runtime: 'host',
|
|
56
|
+
requires: [{ capability: 'assistant.agent', required: false, fallback: 'degrade' }],
|
|
30
57
|
},
|
|
31
58
|
start(context) {
|
|
32
|
-
const
|
|
59
|
+
const diagnostics = installVoiceDiagnostics(() => coordinator.snapshot().active);
|
|
60
|
+
if (diagnostics !== undefined)
|
|
61
|
+
context.resources.add(diagnostics.dispose);
|
|
62
|
+
let resetting = false;
|
|
63
|
+
// 每次读取当前档案,资源准备与旧配置都不能隐式创建助理。
|
|
64
|
+
const assistantProfile = () => readAssistantProfile(context.services.settings?.get().assistant ?? DEFAULT_ASSISTANT_SETTINGS);
|
|
65
|
+
let lifecycleRevision = 0;
|
|
66
|
+
const tts = new AssistantTtsService(context.services, { isVoiceActive: () => coordinator.snapshot().active });
|
|
67
|
+
context.resources.add(() => tts.dispose());
|
|
68
|
+
const runtime = new SherpaWorkerRuntime({
|
|
33
69
|
env: buildSherpaRuntimeEnvironment(readAssistantVoiceSettings(context.services)),
|
|
34
70
|
});
|
|
35
71
|
const agent = new VoiceAgentService({
|
|
@@ -44,52 +80,263 @@ export function createGlobalVoiceRpcFeature() {
|
|
|
44
80
|
audioInput: runtime.capabilities.streamingInput,
|
|
45
81
|
wakeWord: runtime.capabilities.wakeWord,
|
|
46
82
|
bargeIn: runtime.capabilities.bargeIn,
|
|
47
|
-
streamingAudio: runtime.capabilities.streamingOutput,
|
|
48
|
-
readAloud: runtime.capabilities.textToSpeech,
|
|
49
|
-
voices: runtime.capabilities.textToSpeech,
|
|
83
|
+
streamingAudio: tts.outputReady || runtime.capabilities.streamingOutput,
|
|
84
|
+
readAloud: tts.outputReady || runtime.capabilities.textToSpeech,
|
|
85
|
+
voices: tts.outputReady || runtime.capabilities.textToSpeech,
|
|
50
86
|
});
|
|
51
87
|
};
|
|
52
88
|
const disposeVoiceAgent = provideHostVoiceAgentService(context.services.dshContext, agent);
|
|
53
89
|
if (disposeVoiceAgent !== undefined)
|
|
54
90
|
context.resources.add(disposeVoiceAgent);
|
|
55
|
-
const dispatcher = new AssistantDispatcher((request) => dispatchPrompt(context.services, request));
|
|
91
|
+
const dispatcher = new AssistantDispatcher((request, signal) => dispatchPrompt(context.services, request, signal));
|
|
56
92
|
const router = new AssistantVoiceTurnRouter(dispatcher);
|
|
57
93
|
const waitingState = new AssistantWaitingState();
|
|
58
94
|
let lastSnapshot = null;
|
|
59
95
|
let lastArchivedSessionIds = [];
|
|
60
|
-
let lastIndexKey = '';
|
|
61
|
-
let lastIndexVolatile = false;
|
|
62
96
|
let buildingIndex;
|
|
63
|
-
|
|
97
|
+
let buildingIndexRevision = 0;
|
|
98
|
+
const journal = new AssistantIndexJournal();
|
|
99
|
+
const llm = createAssistantLlmAdapter(context.services.dshContext, context.services.dshVersion ?? minimumSupportedDshVersion());
|
|
100
|
+
const textChat = new AssistantTextChat(llm);
|
|
101
|
+
const managementTools = createAssistantManagementTools({
|
|
102
|
+
dispatcher,
|
|
103
|
+
snapshot: (signal) => readManagementSnapshot(signal),
|
|
104
|
+
read: async (entry, signal) => {
|
|
105
|
+
const managed = assistantSettings().managedWorkspaceIds;
|
|
106
|
+
const source = await readAssistantSource(context.services, managed, waitingState);
|
|
107
|
+
signal.throwIfAborted();
|
|
108
|
+
const current = source.sessions.find((item) => item.hostId === entry.hostId && item.sessionId === entry.sessionId && item.workspaceId === entry.workspaceId);
|
|
109
|
+
if (current === undefined || source.archivedSessionIds.includes(entry.sessionId))
|
|
110
|
+
throw new Error('目标会话已退出助理管理范围');
|
|
111
|
+
return await source.readSummary?.(current) ?? null;
|
|
112
|
+
},
|
|
113
|
+
});
|
|
114
|
+
const managementAgent = createAssistantAgentAdapter(context.services.dshContext, context.services.dshVersion ?? minimumSupportedDshVersion(), llm, managementTools);
|
|
115
|
+
// 正式文字和语音共用连续对话;租约只约束收音和当前语音轮次。
|
|
116
|
+
const voiceTextChat = new AssistantTextChat(options.conversationAdapter ?? managementAgent, '助理 Agent 对话');
|
|
117
|
+
const conversation = new AssistantConversation(voiceTextChat, llm, options.conversationStorage ?? createAssistantConversationStorage(), readAssistantAttachmentStore(context.services.dshContext));
|
|
118
|
+
const previewChat = new AssistantTextChat(llm, '助理预览');
|
|
119
|
+
const voiceChat = new AssistantVoiceChat(voiceTextChat, conversation);
|
|
120
|
+
context.resources.add(async () => { conversation.dispose(); voiceChat.clear(); voiceTextChat.dispose(); previewChat.dispose(); await managementAgent.dispose(); });
|
|
121
|
+
const indexAnalysis = new AssistantIndexAnalysis(llm);
|
|
122
|
+
let indexSelection = { ...context.services.settings?.get().assistant.model };
|
|
123
|
+
const readDefaultModelKey = () => { const model = readOptionalService(context.services.dshContext, 'agentDefaultModel')?.currentSelection?.(); return JSON.stringify([model?.provider ?? '', model?.model ?? '']); };
|
|
124
|
+
let defaultModelKey = readDefaultModelKey();
|
|
125
|
+
const materials = new Map();
|
|
126
|
+
const localHostId = process.env.CODINGNS4DSH_HOST_ID?.trim() || 'local-host';
|
|
127
|
+
const liveActivity = (entry) => {
|
|
128
|
+
const agent = entry.hostId === localHostId ? readOptionalService(context.services.dshContext, 'agents')?.get?.(entry.sessionId) : undefined;
|
|
129
|
+
if (agent?.status === 'running' || agent?.status === 'idle')
|
|
130
|
+
return agent.status;
|
|
131
|
+
return entry.activity ?? (entry.running ? 'running' : entry.completed || entry.error === true ? 'idle' : 'unknown');
|
|
132
|
+
};
|
|
133
|
+
const updates = new AssistantIndexUpdates(async () => {
|
|
134
|
+
if (resetting || !assistantProfile().initialized)
|
|
135
|
+
return;
|
|
136
|
+
if (indexAnalysis.read()?.state === 'running' || buildingIndex !== undefined && buildingIndexRevision === indexRevision)
|
|
137
|
+
return;
|
|
138
|
+
const snapshot = await buildIndex();
|
|
139
|
+
if (updates.hasReady(snapshot.entries) || indexAnalysis.read()?.generation !== snapshot.generation)
|
|
140
|
+
startIndexAnalysis(snapshot);
|
|
141
|
+
}, liveActivity);
|
|
142
|
+
context.resources.add(() => textChat.dispose());
|
|
143
|
+
context.resources.add(() => indexAnalysis.dispose());
|
|
144
|
+
context.resources.add(() => updates.dispose());
|
|
145
|
+
const withIndexAnalysis = (snapshot, metadata = snapshot.entries) => {
|
|
146
|
+
const run = indexAnalysis.read();
|
|
147
|
+
const tasks = new Map((run?.tasks ?? []).map((task) => [assistantSessionKey(task), task]));
|
|
148
|
+
const liveEntries = new Map(metadata.map((entry) => [assistantSessionKey(entry), entry]));
|
|
149
|
+
const entries = snapshot.entries.map((entry) => {
|
|
150
|
+
// 同步运行状态与索引进度,但保留正文实际来自的版本,不能把旧材料伪装成新版本。
|
|
151
|
+
const live = liveEntries.get(assistantSessionKey(entry)) ?? entry;
|
|
152
|
+
const { sourceVersion: _currentVersion, ...current } = updates.stamp({ ...entry, waiting: live.waiting, error: live.error ?? false }, tasks.get(assistantSessionKey(entry)));
|
|
153
|
+
return { ...current, ...(entry.sourceVersion === undefined ? {} : { sourceVersion: entry.sourceVersion }) };
|
|
154
|
+
});
|
|
155
|
+
if (run === undefined || run.generation !== snapshot.generation)
|
|
156
|
+
return { ...snapshot, entries };
|
|
157
|
+
// 模型提取的进展证据保持原样,Host 填充的执行状态跟随当前会话同步。
|
|
158
|
+
const statuses = new Map(entries.map((entry) => [assistantSessionKey(entry), entry.status]));
|
|
159
|
+
const analysis = run.result === undefined ? run : { ...run, result: { ...run.result, sessions: run.result.sessions.map((session) => ({ ...session, sourceStatus: statuses.get(assistantSessionKey(session)) ?? session.sourceStatus })) } };
|
|
160
|
+
return { ...snapshot, entries, analysis };
|
|
161
|
+
};
|
|
162
|
+
const cancelIndexAnalysis = () => indexAnalysis.cancelActive();
|
|
163
|
+
// 正文索引立即返回,LLM 在后台生成;轮询现有调试接口即可读取进度与结果。
|
|
164
|
+
const startIndexAnalysis = (snapshot, retryFailures = false) => {
|
|
165
|
+
if (resetting || lastSnapshot !== snapshot)
|
|
166
|
+
return withIndexAnalysis(snapshot);
|
|
167
|
+
if (snapshot.entries.length === 0) {
|
|
168
|
+
cancelIndexAnalysis();
|
|
169
|
+
return snapshot;
|
|
170
|
+
}
|
|
171
|
+
const revision = indexRevision;
|
|
172
|
+
const prompts = readAssistantPrompts(context.services.settings?.get().assistant.prompts);
|
|
173
|
+
indexAnalysis.start(snapshot, indexSelection, prompts.index, () => lastSnapshot === snapshot && sameManagedScope(snapshot, context.services.settings?.get().assistant.managedWorkspaceIds ?? []), (run) => {
|
|
174
|
+
if (resetting || revision !== indexRevision || lastSnapshot !== snapshot)
|
|
175
|
+
return;
|
|
176
|
+
journal.updateAnalysis(run);
|
|
177
|
+
for (const task of run.tasks ?? []) {
|
|
178
|
+
if (task.state === 'completed')
|
|
179
|
+
updates.complete(task);
|
|
180
|
+
if (['completed', 'failed', 'cancelled'].includes(task.state)) {
|
|
181
|
+
const entry = snapshot.entries.find((item) => assistantSessionKey(item) === assistantSessionKey(task));
|
|
182
|
+
if (entry !== undefined)
|
|
183
|
+
updates.attempted(entry);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
if (run.state !== 'running' && updates.hasReady(snapshot.entries))
|
|
187
|
+
updates.schedule();
|
|
188
|
+
}, (entry) => updates.canIndex(entry), async (entry, signal) => {
|
|
189
|
+
if (entry.hostId === localHostId)
|
|
190
|
+
return updates.canIndex(entry);
|
|
191
|
+
// 远端没有本地完成事件:每个真实模型请求前重新确认空闲和版本。
|
|
192
|
+
const managed = context.services.settings?.get().assistant.managedWorkspaceIds ?? [];
|
|
193
|
+
const source = await readAssistantSource(context.services, managed, waitingState);
|
|
194
|
+
signal.throwIfAborted();
|
|
195
|
+
const metadata = await buildAssistantSessionIndex({ sessions: source.sessions, scope: createAssistantScope(managed), archivedSessionIds: source.archivedSessionIds });
|
|
196
|
+
observeVersions(metadata.entries);
|
|
197
|
+
const current = metadata.entries.find((item) => assistantSessionKey(item) === assistantSessionKey(entry));
|
|
198
|
+
return current !== undefined && current.activity === 'idle' && current.updatedAt === entry.updatedAt && updates.canIndex(entry);
|
|
199
|
+
}, retryFailures);
|
|
200
|
+
return withIndexAnalysis(snapshot);
|
|
201
|
+
};
|
|
202
|
+
const chooseIndexModel = (payload) => {
|
|
203
|
+
const value = asRecord(payload);
|
|
204
|
+
const provider = readText(value, ['provider']);
|
|
205
|
+
const model = readText(value, ['model']);
|
|
206
|
+
if (provider === null && model === null)
|
|
207
|
+
return;
|
|
208
|
+
if (provider === null || model === null)
|
|
209
|
+
throw new Error('索引模型必须同时指定提供商和模型');
|
|
210
|
+
const current = indexSelection.provider === undefined ? indexAnalysis.read() : indexSelection;
|
|
211
|
+
if (current?.provider === provider && current.model === model) {
|
|
212
|
+
indexSelection = { provider, model };
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
indexSelection = { provider, model };
|
|
216
|
+
cancelIndexAnalysis();
|
|
217
|
+
textChat.cancelActive();
|
|
218
|
+
voiceChat.clear();
|
|
219
|
+
updates.reset();
|
|
220
|
+
};
|
|
221
|
+
// 刷新可以清空缓存,但索引代次必须持续递增,不能每次回到 1。
|
|
222
|
+
let indexGeneration = 0;
|
|
223
|
+
let indexRevision = 0;
|
|
224
|
+
const observeVersions = (entries) => {
|
|
225
|
+
const changed = updates.observe(entries);
|
|
226
|
+
if (indexAnalysis.read()?.state !== 'running')
|
|
227
|
+
return changed;
|
|
228
|
+
for (const entry of lastSnapshot?.entries ?? [])
|
|
229
|
+
if (!updates.canIndex(entry))
|
|
230
|
+
indexAnalysis.deferSession(assistantSessionKey(entry));
|
|
231
|
+
return changed;
|
|
232
|
+
};
|
|
233
|
+
const buildIndex = async (trigger = 'automatic') => {
|
|
234
|
+
if (resetting)
|
|
235
|
+
throw new Error('助理正在重置,请稍后操作');
|
|
64
236
|
const managed = context.services.settings?.get().assistant?.managedWorkspaceIds ?? [];
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
if (lastSnapshot !== null && key === lastIndexKey && !lastIndexVolatile)
|
|
68
|
-
return lastSnapshot;
|
|
69
|
-
if (buildingIndex !== undefined)
|
|
237
|
+
const revision = indexRevision;
|
|
238
|
+
if (buildingIndex !== undefined && buildingIndexRevision === revision)
|
|
70
239
|
return buildingIndex;
|
|
71
|
-
|
|
72
|
-
|
|
240
|
+
const source = await readAssistantSource(context.services, managed, waitingState);
|
|
241
|
+
if (resetting || revision !== indexRevision)
|
|
242
|
+
throw new Error('索引任务已撤销');
|
|
243
|
+
if (JSON.stringify(managed) !== JSON.stringify(context.services.settings?.get().assistant.managedWorkspaceIds ?? []))
|
|
244
|
+
return buildIndex(trigger);
|
|
245
|
+
if (buildingIndex !== undefined && buildingIndexRevision === revision)
|
|
246
|
+
return buildingIndex;
|
|
247
|
+
const metadata = await buildAssistantSessionIndex({ sessions: source.sessions, scope: createAssistantScope(managed), archivedSessionIds: source.archivedSessionIds });
|
|
248
|
+
if (resetting || revision !== indexRevision)
|
|
249
|
+
throw new Error('索引任务已撤销');
|
|
250
|
+
observeVersions(metadata.entries);
|
|
251
|
+
const members = new Set(metadata.entries.map(assistantSessionKey));
|
|
252
|
+
for (const key of materials.keys())
|
|
253
|
+
if (!members.has(key))
|
|
254
|
+
materials.delete(key);
|
|
255
|
+
const materialKeys = new Set(metadata.entries.filter((value) => { const entry = updates.stamp(value); return updates.canIndex(entry) && materials.get(assistantSessionKey(entry))?.version !== entry.sourceVersion; }).map(assistantSessionKey));
|
|
256
|
+
if (trigger !== 'manual' && lastSnapshot !== null && sameIndexMembership(lastSnapshot, metadata) && updates.matches(lastSnapshot) && materialKeys.size === 0)
|
|
257
|
+
return lastSnapshot;
|
|
258
|
+
const recordId = journal.begin(trigger, managed);
|
|
259
|
+
const failures = new Map();
|
|
260
|
+
const task = (async () => {
|
|
73
261
|
lastArchivedSessionIds = source.archivedSessionIds;
|
|
74
262
|
const snapshot = await buildAssistantSessionIndex({
|
|
75
|
-
sessions: source.sessions,
|
|
263
|
+
sessions: source.sessions.map((session) => updates.stamp({ ...session, title: session.title ?? null })),
|
|
76
264
|
scope: createAssistantScope(managed),
|
|
77
265
|
archivedSessionIds: source.archivedSessionIds,
|
|
78
|
-
generation:
|
|
79
|
-
...(source.readSummary === undefined ? {} : { readSummary:
|
|
80
|
-
|
|
266
|
+
generation: ++indexGeneration,
|
|
267
|
+
...(source.readSummary === undefined ? {} : { readSummary: async (session) => {
|
|
268
|
+
const key = assistantSessionKey(session);
|
|
269
|
+
const cached = materials.get(key);
|
|
270
|
+
const entry = { ...session, title: session.title ?? null };
|
|
271
|
+
if (!updates.canIndex(entry))
|
|
272
|
+
return cached?.summary ?? null;
|
|
273
|
+
if (cached !== undefined && cached.version === session.sourceVersion)
|
|
274
|
+
return cached.summary;
|
|
275
|
+
try {
|
|
276
|
+
const summary = await source.readSummary(session);
|
|
277
|
+
if (revision === indexRevision && session.sourceVersion !== undefined && updates.canIndex(entry))
|
|
278
|
+
materials.set(key, { version: session.sourceVersion, summary });
|
|
279
|
+
return summary;
|
|
280
|
+
}
|
|
281
|
+
catch (error) {
|
|
282
|
+
failures.set(`${session.hostId}:${session.sessionId}`, sanitizeSpeechText(error instanceof Error ? error.message : String(error)).slice(0, 500));
|
|
283
|
+
throw error;
|
|
284
|
+
}
|
|
285
|
+
} }),
|
|
286
|
+
...(source.readWaiting === undefined ? {} : { readWaiting: (session) => materialKeys.has(assistantSessionKey(session)) ? source.readWaiting(session) : session.waiting }),
|
|
81
287
|
});
|
|
288
|
+
// 构建期间若源数据已经变化,保留记录,但不能把结果误标为最新。
|
|
289
|
+
if (revision !== indexRevision)
|
|
290
|
+
return snapshot;
|
|
82
291
|
lastSnapshot = snapshot;
|
|
83
|
-
|
|
84
|
-
lastIndexVolatile = source.volatile === true;
|
|
292
|
+
journal.complete(recordId, snapshot, source.warnings, failures);
|
|
85
293
|
return snapshot;
|
|
86
|
-
})().
|
|
87
|
-
|
|
294
|
+
})().catch((error) => { if (revision === indexRevision)
|
|
295
|
+
journal.fail(recordId, error); throw error; }).finally(() => { if (buildingIndex === task)
|
|
296
|
+
buildingIndex = undefined; });
|
|
297
|
+
buildingIndexRevision = revision;
|
|
298
|
+
buildingIndex = task;
|
|
299
|
+
return task;
|
|
88
300
|
};
|
|
89
|
-
const invalidateIndex = () => {
|
|
301
|
+
const invalidateIndex = () => { cancelIndexAnalysis(); textChat.cancelActive(); voiceChat.clear(); indexRevision += 1; lastSnapshot = null; updates.reset(); };
|
|
90
302
|
const eventDisposers = [];
|
|
91
|
-
for (const eventName of ['
|
|
92
|
-
const disposer = context.services.events?.on(eventName,
|
|
303
|
+
for (const eventName of ['workspace/archive', 'workspace/unarchive', 'workspace/changed']) {
|
|
304
|
+
const disposer = context.services.events?.on(eventName, () => updates.schedule());
|
|
305
|
+
if (typeof disposer === 'function')
|
|
306
|
+
eventDisposers.push(disposer);
|
|
307
|
+
}
|
|
308
|
+
const sessionKey = (args) => {
|
|
309
|
+
const id = readIndexSessionId(args);
|
|
310
|
+
const managed = context.services.settings?.get().assistant.managedWorkspaceIds ?? [];
|
|
311
|
+
const workspace = readWorkspaceRecords(context.services.dshContext).find((item) => item.sessionIds.includes(id ?? '') && managed.some((selected) => assistantWorkspaceMatches(selected, localHostId, item.id, true)));
|
|
312
|
+
const archived = readStringArray(readOptionalService(context.services.dshContext, 'workspaceRegistry')?.archivedSessionIds);
|
|
313
|
+
return id === null || workspace === undefined || archived.includes(id) ? null : assistantSessionKey({ hostId: localHostId, sessionId: id });
|
|
314
|
+
};
|
|
315
|
+
const changedSession = (args) => { const key = sessionKey(args); if (key !== null) {
|
|
316
|
+
updates.changed(key);
|
|
317
|
+
indexAnalysis.deferSession(key);
|
|
318
|
+
} };
|
|
319
|
+
for (const eventName of ['session/update', 'session/title']) {
|
|
320
|
+
const disposer = context.services.events?.on(eventName, (...args) => changedSession(args));
|
|
321
|
+
if (typeof disposer === 'function')
|
|
322
|
+
eventDisposers.push(disposer);
|
|
323
|
+
}
|
|
324
|
+
for (const eventName of ['agent/status', 'api-session/status', 'session/status', 'session/complete']) {
|
|
325
|
+
const disposer = context.services.events?.on(eventName, (...args) => {
|
|
326
|
+
const key = sessionKey(args);
|
|
327
|
+
const status = readIndexRunning(eventName, args);
|
|
328
|
+
if (key === null || status === null)
|
|
329
|
+
return;
|
|
330
|
+
if (eventName === 'session/complete') {
|
|
331
|
+
const id = readIndexSessionId(args);
|
|
332
|
+
if (id !== null)
|
|
333
|
+
waitingState.resolve(id);
|
|
334
|
+
updates.changed(key);
|
|
335
|
+
}
|
|
336
|
+
updates.status(key, status);
|
|
337
|
+
if (status)
|
|
338
|
+
indexAnalysis.deferSession(key);
|
|
339
|
+
});
|
|
93
340
|
if (typeof disposer === 'function')
|
|
94
341
|
eventDisposers.push(disposer);
|
|
95
342
|
}
|
|
@@ -105,30 +352,124 @@ export function createGlobalVoiceRpcFeature() {
|
|
|
105
352
|
const sessionId = readWaitingSessionId(args);
|
|
106
353
|
if (sessionId !== null)
|
|
107
354
|
waitingState.request({ sessionId, kind });
|
|
108
|
-
|
|
355
|
+
changedSession(args);
|
|
109
356
|
});
|
|
110
357
|
if (typeof disposer === 'function')
|
|
111
358
|
eventDisposers.push(disposer);
|
|
112
359
|
}
|
|
113
|
-
for (const eventName of ['approval/resolve', 'approval/resolved', 'user-questions/resolve', 'user-questions/resolved', 'user-question/resolve', 'user-question/answered'
|
|
360
|
+
for (const eventName of ['approval/resolve', 'approval/resolved', 'user-questions/resolve', 'user-questions/resolved', 'user-question/resolve', 'user-question/answered']) {
|
|
114
361
|
const disposer = context.services.events?.on(eventName, (...args) => {
|
|
115
362
|
const sessionId = readWaitingSessionId(args);
|
|
116
363
|
if (sessionId !== null)
|
|
117
364
|
waitingState.resolve(sessionId);
|
|
118
|
-
|
|
365
|
+
changedSession(args);
|
|
119
366
|
});
|
|
120
367
|
if (typeof disposer === 'function')
|
|
121
368
|
eventDisposers.push(disposer);
|
|
122
369
|
}
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
370
|
+
const onSessionEvent = (session, event) => {
|
|
371
|
+
const record = asRecord(session);
|
|
372
|
+
const sessionId = readText(record, ['id', 'sessionId']) ?? readText(asRecord(record?.header), ['id', 'sessionId']);
|
|
373
|
+
if (sessionId !== null)
|
|
374
|
+
assistantSourceCache(context.services).invalidateTitle(sessionId);
|
|
375
|
+
const key = sessionKey([session]);
|
|
376
|
+
if (key === null)
|
|
377
|
+
return;
|
|
378
|
+
const entry = lastSnapshot?.entries.find((item) => assistantSessionKey(item) === key);
|
|
379
|
+
const before = entry === undefined ? undefined : updates.stamp(entry).sourceVersion;
|
|
380
|
+
updates.event(key, event);
|
|
381
|
+
if (entry !== undefined && before !== updates.stamp(entry).sourceVersion)
|
|
382
|
+
indexAnalysis.deferSession(key);
|
|
383
|
+
};
|
|
384
|
+
const onSessionFlush = (session) => { if (sessionKey([session]) !== null)
|
|
385
|
+
updates.schedule(false); };
|
|
386
|
+
const nativeSessionDisposer = context.services.nativeSessions?.subscribe({ onEvent: onSessionEvent, onFlush: onSessionFlush });
|
|
127
387
|
if (typeof nativeSessionDisposer === 'function')
|
|
128
388
|
eventDisposers.push(nativeSessionDisposer);
|
|
129
|
-
|
|
389
|
+
if (context.services.nativeSessions === undefined) {
|
|
390
|
+
for (const [event, handler] of [['session/event', onSessionEvent], ['session/flush', onSessionFlush]]) {
|
|
391
|
+
const disposer = context.services.events?.on(event, handler);
|
|
392
|
+
if (typeof disposer === 'function')
|
|
393
|
+
eventDisposers.push(disposer);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
let managedScopeKey = JSON.stringify([...(context.services.settings?.get().assistant.managedWorkspaceIds ?? [])].sort());
|
|
397
|
+
let currentPrompts = readAssistantPrompts(context.services.settings?.get().assistant.prompts);
|
|
398
|
+
let configuredModelKey = JSON.stringify(context.services.settings?.get().assistant.model ?? {});
|
|
399
|
+
const disposeSettingsWatch = context.services.settings?.watch?.(() => {
|
|
400
|
+
const nextKey = JSON.stringify([...(context.services.settings?.get().assistant.managedWorkspaceIds ?? [])].sort());
|
|
401
|
+
const nextPrompts = readAssistantPrompts(context.services.settings?.get().assistant.prompts);
|
|
402
|
+
const model = context.services.settings?.get().assistant.model;
|
|
403
|
+
const nextModelKey = JSON.stringify(model ?? {});
|
|
404
|
+
if (resetting) {
|
|
405
|
+
managedScopeKey = nextKey;
|
|
406
|
+
currentPrompts = nextPrompts;
|
|
407
|
+
configuredModelKey = nextModelKey;
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
const scopeChanged = nextKey !== managedScopeKey;
|
|
411
|
+
if (scopeChanged) {
|
|
412
|
+
lifecycleRevision++;
|
|
413
|
+
void conversation.invalidateContext().catch(() => undefined);
|
|
414
|
+
}
|
|
415
|
+
if (nextPrompts.chat !== currentPrompts.chat) {
|
|
416
|
+
lifecycleRevision++;
|
|
417
|
+
conversation.cancelActive();
|
|
418
|
+
previewChat.cancelActive();
|
|
419
|
+
}
|
|
420
|
+
if (configuredModelKey !== nextModelKey) {
|
|
421
|
+
indexSelection = { ...model };
|
|
422
|
+
lifecycleRevision++;
|
|
423
|
+
conversation.cancelActive();
|
|
424
|
+
invalidateIndex();
|
|
425
|
+
}
|
|
426
|
+
if (scopeChanged || nextPrompts.chat !== currentPrompts.chat) {
|
|
427
|
+
textChat.cancelActive();
|
|
428
|
+
voiceChat.clear();
|
|
429
|
+
}
|
|
430
|
+
if (scopeChanged) {
|
|
431
|
+
cancelIndexAnalysis();
|
|
432
|
+
indexRevision++;
|
|
433
|
+
lastSnapshot = null;
|
|
434
|
+
updates.schedule();
|
|
435
|
+
}
|
|
436
|
+
if (nextPrompts.index !== currentPrompts.index)
|
|
437
|
+
invalidateIndex();
|
|
438
|
+
managedScopeKey = nextKey;
|
|
439
|
+
currentPrompts = nextPrompts;
|
|
440
|
+
configuredModelKey = nextModelKey;
|
|
441
|
+
});
|
|
130
442
|
if (typeof disposeSettingsWatch === 'function')
|
|
131
443
|
eventDisposers.push(disposeSettingsWatch);
|
|
444
|
+
// 没有本地事件总线的远端也通过元数据版本发现变化;这里只读取列表,不读正文。
|
|
445
|
+
let refreshingVersions = false;
|
|
446
|
+
const refreshVersions = async () => {
|
|
447
|
+
if (resetting || !assistantProfile().initialized)
|
|
448
|
+
return;
|
|
449
|
+
if (refreshingVersions)
|
|
450
|
+
return;
|
|
451
|
+
refreshingVersions = true;
|
|
452
|
+
try {
|
|
453
|
+
const key = readDefaultModelKey();
|
|
454
|
+
if (key !== defaultModelKey) {
|
|
455
|
+
defaultModelKey = key;
|
|
456
|
+
if (indexSelection.provider === undefined)
|
|
457
|
+
invalidateIndex();
|
|
458
|
+
}
|
|
459
|
+
const managed = context.services.settings?.get().assistant.managedWorkspaceIds ?? [];
|
|
460
|
+
const source = await readAssistantSource(context.services, managed, waitingState);
|
|
461
|
+
const metadata = await buildAssistantSessionIndex({ sessions: source.sessions, scope: createAssistantScope(managed), archivedSessionIds: source.archivedSessionIds });
|
|
462
|
+
const changed = observeVersions(metadata.entries);
|
|
463
|
+
if (updates.hasReady(metadata.entries) || lastSnapshot !== null && !sameIndexMembership(lastSnapshot, metadata))
|
|
464
|
+
updates.schedule(changed);
|
|
465
|
+
}
|
|
466
|
+
finally {
|
|
467
|
+
refreshingVersions = false;
|
|
468
|
+
}
|
|
469
|
+
};
|
|
470
|
+
const versionTimer = setInterval(() => { void refreshVersions().catch(() => { }); }, 5000);
|
|
471
|
+
context.resources.add(() => clearInterval(versionTimer));
|
|
472
|
+
updates.schedule();
|
|
132
473
|
context.resources.add(() => { for (const dispose of eventDisposers.splice(0))
|
|
133
474
|
dispose(); });
|
|
134
475
|
const actionBridge = createAssistantVoiceActionBridge({
|
|
@@ -141,20 +482,432 @@ export function createGlobalVoiceRpcFeature() {
|
|
|
141
482
|
// 语音运行时只提交 action 事件;动作本身再次读取索引并经过派发器复核。
|
|
142
483
|
actionBridge.register();
|
|
143
484
|
const coordinator = new GlobalVoiceCoordinator({ adapter: runtime });
|
|
485
|
+
let previousLease = coordinator.snapshot();
|
|
486
|
+
context.resources.add(coordinator.subscribe((lease) => {
|
|
487
|
+
if (previousLease.active && (!lease.active || lease.ownerId !== previousLease.ownerId) && previousLease.ownerId !== null) {
|
|
488
|
+
tts.endVoiceSession();
|
|
489
|
+
void conversation.endVoiceSession(previousLease.ownerId).catch(() => undefined);
|
|
490
|
+
}
|
|
491
|
+
if (!lease.active || lease.ownerId !== previousLease.ownerId)
|
|
492
|
+
voiceChat.clear();
|
|
493
|
+
else if (lease.epoch !== previousLease.epoch)
|
|
494
|
+
voiceChat.cancelActive();
|
|
495
|
+
previousLease = lease;
|
|
496
|
+
}));
|
|
497
|
+
// 两种入口共用完整结构化索引门禁,语音不能绕过待更新或失败的会话。
|
|
498
|
+
const readChatContext = () => {
|
|
499
|
+
const index = journal.snapshot().index;
|
|
500
|
+
const managed = context.services.settings?.get().assistant.managedWorkspaceIds ?? [];
|
|
501
|
+
if (index === undefined || lastSnapshot !== index || !sameManagedScope(index, managed) || !updates.matches(index))
|
|
502
|
+
throw new Error('索引尚未生成或已经过期,请等待会话完成后自动更新索引');
|
|
503
|
+
const current = withIndexAnalysis(index);
|
|
504
|
+
if (current.analysis?.state === 'running')
|
|
505
|
+
throw new Error('索引总结正在生成,请稍后再进行对话');
|
|
506
|
+
if (current.analysis?.state !== 'completed' || current.analysis.result?.sessions.length !== index.entries.length || !updates.fresh(index))
|
|
507
|
+
throw new Error('结构化索引未生成或有会话待更新,请等待会话完成后自动索引,失败项可手动重试');
|
|
508
|
+
const prompts = readAssistantPrompts(context.services.settings?.get().assistant.prompts);
|
|
509
|
+
return {
|
|
510
|
+
index: current, provider: current.analysis.provider, model: current.analysis.model, prompt: prompts.chat,
|
|
511
|
+
isCurrent: () => lastSnapshot === index && updates.matches(index) && updates.fresh(index) && indexAnalysis.read()?.state === 'completed' && indexAnalysis.read()?.generation === index.generation && sameManagedScope(index, context.services.settings?.get().assistant.managedWorkspaceIds ?? []) && prompts.chat === readAssistantPrompts(context.services.settings?.get().assistant.prompts).chat,
|
|
512
|
+
createSystem: (facts) => createAssistantChatSystem(facts, prompts.chat),
|
|
513
|
+
};
|
|
514
|
+
};
|
|
515
|
+
const readVoiceChatLease = (payload) => {
|
|
516
|
+
const ownerId = readOwner(payload);
|
|
517
|
+
coordinator.assertOwner(ownerId);
|
|
518
|
+
const lease = coordinator.snapshot();
|
|
519
|
+
if (isRecord(payload) && payload.epoch !== undefined && payload.epoch !== lease.epoch)
|
|
520
|
+
throw new Error('语音对话轮次已失效,请重新说话');
|
|
521
|
+
return { ownerId, epoch: lease.epoch };
|
|
522
|
+
};
|
|
523
|
+
const assistantSettings = () => context.services.settings?.get().assistant ?? DEFAULT_ASSISTANT_SETTINGS;
|
|
524
|
+
const readRemoteWorkspaces = () => (context.services.assistantGateway?.workspaces?.() ?? Promise.resolve([])).catch(() => []);
|
|
525
|
+
const lifecycleSnapshot = async () => {
|
|
526
|
+
const snapshot = await conversation.snapshot();
|
|
527
|
+
return { profile: assistantProfile(), conversation: snapshot };
|
|
528
|
+
};
|
|
529
|
+
const requireInitialized = () => { if (!assistantProfile().initialized)
|
|
530
|
+
throw new Error('请先创建智能助理'); };
|
|
531
|
+
const readManagementSnapshot = async (signal) => {
|
|
532
|
+
requireInitialized();
|
|
533
|
+
const revision = lifecycleRevision;
|
|
534
|
+
const managed = assistantSettings().managedWorkspaceIds;
|
|
535
|
+
const source = await readAssistantSource(context.services, managed, waitingState);
|
|
536
|
+
signal.throwIfAborted();
|
|
537
|
+
const index = await buildAssistantSessionIndex({ sessions: source.sessions.filter((entry) => !managementAgent.sessionIds.has(entry.sessionId)), scope: createAssistantScope(managed), archivedSessionIds: source.archivedSessionIds, generation: indexGeneration });
|
|
538
|
+
const workspaces = [...readWorkspaceRecords(context.services.dshContext).map((item) => ({ workspaceId: item.id, name: item.name, path: item.path })), ...await readRemoteWorkspaces()];
|
|
539
|
+
signal.throwIfAborted();
|
|
540
|
+
if (resetting || revision !== lifecycleRevision || JSON.stringify(managed) !== JSON.stringify(assistantSettings().managedWorkspaceIds))
|
|
541
|
+
throw new Error('助理管理范围已变化,请重新查询');
|
|
542
|
+
return { scope: createAssistantScope(managed), archivedSessionIds: source.archivedSessionIds, entries: index.entries, indexGeneration: index.generation,
|
|
543
|
+
warnings: source.warnings, workspaces: workspaces.filter((item) => managed.includes(item.workspaceId)) };
|
|
544
|
+
};
|
|
545
|
+
const readConversationContext = async (draft) => {
|
|
546
|
+
const revision = lifecycleRevision;
|
|
547
|
+
const settings = assistantSettings();
|
|
548
|
+
const prompts = readAssistantPrompts(settings.prompts);
|
|
549
|
+
const selected = draft !== undefined && 'model' in draft ? draft.model : settings.model;
|
|
550
|
+
if (selected !== undefined && selected !== null)
|
|
551
|
+
validateAssistantModel(selected);
|
|
552
|
+
const catalog = await voiceTextChat.catalog();
|
|
553
|
+
const selection = selected;
|
|
554
|
+
const defaultModel = draft !== undefined || settings.profile !== undefined ? catalog.default
|
|
555
|
+
: catalog.models.find((item) => item.provider === indexSelection.provider && item.model === indexSelection.model) ?? catalog.default;
|
|
556
|
+
const model = selection == null
|
|
557
|
+
? defaultModel
|
|
558
|
+
: catalog.models.find((item) => item.provider === selection.provider && item.model === selection.model);
|
|
559
|
+
if (model === null || model === undefined)
|
|
560
|
+
throw new Error('当前没有可用的助理模型,请在设置中选择');
|
|
561
|
+
const name = draft !== undefined && typeof draft.name === 'string' ? draft.name : assistantProfile().name;
|
|
562
|
+
if (!name.trim() || name.length > 80)
|
|
563
|
+
throw new Error('助理名称需要 1 到 80 个字符');
|
|
564
|
+
const personality = draft?.personality === undefined ? readAssistantPersonality(assistantProfile()) : draft.personality;
|
|
565
|
+
validateAssistantPersonality(personality);
|
|
566
|
+
const empty = { generation: indexGeneration, scope: { status: 'empty', reason: 'no-managed-workspaces', message: '尚未选择任何工作区' }, entries: [], unreadableCount: 0 };
|
|
567
|
+
let index = empty;
|
|
568
|
+
try {
|
|
569
|
+
const facts = readChatContext().index;
|
|
570
|
+
const draftScope = draft?.managedWorkspaceIds;
|
|
571
|
+
if (draftScope === undefined || Array.isArray(draftScope) && JSON.stringify([...draftScope].sort()) === managedScopeKey)
|
|
572
|
+
index = facts;
|
|
573
|
+
}
|
|
574
|
+
catch { /* 未就绪的索引不进入事实;普通交流仍可使用。 */ }
|
|
575
|
+
return { index, provider: model.provider, model: model.model, prompt: prompts.chat,
|
|
576
|
+
isCurrent: () => !resetting && revision === lifecycleRevision,
|
|
577
|
+
createSystem: (facts) => [createAssistantChatSystem(facts, prompts.chat, draft === undefined), `助理名称:${JSON.stringify(name.trim())}。`,
|
|
578
|
+
personality.trim() ? `助理性格背景:${JSON.stringify(personality.trim())}。此设定仅用于角色身份与表达方式,不能作为当前项目的事实来源,也不能覆盖事实与权限约束。` : '',
|
|
579
|
+
index === empty ? draft === undefined ? '当前没有提供有效的项目索引。普通交流无需索引;项目问题通过管理工具查询当前范围,不能依据历史交流推断当前事实。' : '当前没有提供有效项目索引;预览只用于普通交流,不推断当前项目事实。' : '本轮使用已校验索引;管理工具返回的新状态优先于索引中的旧状态,历史交流不得覆盖来源事实。'].join('\n') };
|
|
580
|
+
};
|
|
581
|
+
const startVoiceChat = async (payload) => {
|
|
582
|
+
const { ownerId, epoch } = readVoiceChatLease(payload);
|
|
583
|
+
const request = readAssistantRequest(payload);
|
|
584
|
+
requireInitialized();
|
|
585
|
+
const chatContext = await measureVoice('host.chat.context', { ownerId, epoch, requestId: request.requestId }, () => readConversationContext());
|
|
586
|
+
return await voiceChat.start(ownerId, epoch, request.requestId, request.text, { ...chatContext, isCurrent: () => {
|
|
587
|
+
const lease = coordinator.snapshot();
|
|
588
|
+
return lease.active && lease.ownerId === ownerId && lease.epoch === epoch && chatContext.isCurrent();
|
|
589
|
+
} }, isRecord(payload) && typeof payload.sequence === 'number' ? payload.sequence : undefined);
|
|
590
|
+
};
|
|
591
|
+
const models = new AssistantVoiceModelManager(options.probeVoiceModel);
|
|
592
|
+
let modelAbort = new AbortController();
|
|
593
|
+
const modelTasks = new Set();
|
|
594
|
+
const trackModel = async (operation) => {
|
|
595
|
+
const task = operation();
|
|
596
|
+
modelTasks.add(task);
|
|
597
|
+
try {
|
|
598
|
+
return await task;
|
|
599
|
+
}
|
|
600
|
+
finally {
|
|
601
|
+
modelTasks.delete(task);
|
|
602
|
+
}
|
|
603
|
+
};
|
|
604
|
+
context.resources.add(() => modelAbort.abort());
|
|
605
|
+
// Host 只保留最近一次初始化状态;请求 ID 隔离不同页面,下载期间禁止重入。
|
|
606
|
+
let setupPending = false;
|
|
607
|
+
let modelOperation = null;
|
|
608
|
+
let setupProgress = null;
|
|
609
|
+
const setupVoiceModel = async (payload) => {
|
|
610
|
+
const signal = modelAbort.signal;
|
|
611
|
+
const modelId = readVoiceModelId(payload);
|
|
612
|
+
if (setupPending)
|
|
613
|
+
throw new Error('语音模型正在下载或初始化,请等待完成');
|
|
614
|
+
if (coordinator.snapshot().active || runtime.running)
|
|
615
|
+
throw new Error('请先停止当前实时语音,再更换语音模型');
|
|
616
|
+
const settings = context.services.settings;
|
|
617
|
+
if (settings === undefined)
|
|
618
|
+
throw new Error('当前 Host 不支持保存语音设置');
|
|
619
|
+
const requestId = readVoiceSetupRequestId(payload) ?? randomUUID();
|
|
620
|
+
const repair = isRecord(payload) && payload.repair === true;
|
|
621
|
+
setupPending = true;
|
|
622
|
+
modelOperation = { modelId, kind: repair ? 'repair' : 'setup' };
|
|
623
|
+
setupProgress = null;
|
|
624
|
+
try {
|
|
625
|
+
const installed = await models.prepare(modelId, readAssistantVoiceSettings(context.services), (progress) => {
|
|
626
|
+
setupProgress = { requestId, progress };
|
|
627
|
+
}, signal, repair);
|
|
628
|
+
signal.throwIfAborted();
|
|
629
|
+
const next = {
|
|
630
|
+
...DEFAULT_ASSISTANT_VOICE_SETTINGS,
|
|
631
|
+
...readAssistantVoiceSettings(context.services),
|
|
632
|
+
initialized: true,
|
|
633
|
+
provider: 'sherpa-onnx',
|
|
634
|
+
modelId,
|
|
635
|
+
asrEncoder: installed.paths.asrEncoder,
|
|
636
|
+
asrDecoder: installed.paths.asrDecoder,
|
|
637
|
+
asrJoiner: installed.paths.asrJoiner,
|
|
638
|
+
asrTokens: installed.paths.asrTokens,
|
|
639
|
+
// 实时对话使用浏览器输出;不让历史配置中的离线 VAD/TTS 偷偷生效。
|
|
640
|
+
vadModel: '',
|
|
641
|
+
ttsModel: '',
|
|
642
|
+
ttsTokens: '',
|
|
643
|
+
ttsLexicon: '',
|
|
644
|
+
};
|
|
645
|
+
const prepareOnly = isRecord(payload) && payload.prepareOnly === true;
|
|
646
|
+
if (!prepareOnly) {
|
|
647
|
+
await settings.update({ assistant: { ...settings.get().assistant, voice: next } });
|
|
648
|
+
runtime.configureEnvironment(buildSherpaRuntimeEnvironment(next));
|
|
649
|
+
updateVoiceAgentCapabilities();
|
|
650
|
+
}
|
|
651
|
+
setupProgress = {
|
|
652
|
+
requestId,
|
|
653
|
+
progress: { modelId, phase: 'completed', fileName: null, fileIndex: installed.model.files.length,
|
|
654
|
+
fileCount: installed.model.files.length, downloadedBytes: 0, totalBytes: null },
|
|
655
|
+
};
|
|
656
|
+
return { modelId, downloaded: installed.downloaded, ...(prepareOnly ? { voice: next } : {}) };
|
|
657
|
+
}
|
|
658
|
+
catch (error) {
|
|
659
|
+
setupProgress = null;
|
|
660
|
+
throw error;
|
|
661
|
+
}
|
|
662
|
+
finally {
|
|
663
|
+
setupPending = false;
|
|
664
|
+
modelOperation = null;
|
|
665
|
+
}
|
|
666
|
+
};
|
|
667
|
+
const verifyVoiceModel = async (payload) => {
|
|
668
|
+
const signal = modelAbort.signal;
|
|
669
|
+
const modelId = readVoiceModelId(payload);
|
|
670
|
+
if (setupPending)
|
|
671
|
+
throw new Error('已有模型操作正在进行,请等待完成');
|
|
672
|
+
setupPending = true;
|
|
673
|
+
modelOperation = { modelId, kind: 'verify' };
|
|
674
|
+
try {
|
|
675
|
+
return await models.verify(modelId, readAssistantVoiceSettings(context.services), signal);
|
|
676
|
+
}
|
|
677
|
+
finally {
|
|
678
|
+
setupPending = false;
|
|
679
|
+
modelOperation = null;
|
|
680
|
+
}
|
|
681
|
+
};
|
|
682
|
+
const initialization = new AssistantVoiceInitialization({
|
|
683
|
+
readModels: async () => {
|
|
684
|
+
const voice = readAssistantVoiceSettings(context.services);
|
|
685
|
+
const snapshot = await models.snapshot(voice, {
|
|
686
|
+
running: runtime.running, ready: runtime.capabilities.realtime, operation: modelOperation,
|
|
687
|
+
});
|
|
688
|
+
// 旧手工路径配置没有目录 ID,不能把它当作新用户并静默替换。
|
|
689
|
+
return snapshot.currentModelId === null && validateAssistantVoiceSettings(voice) === undefined
|
|
690
|
+
? { ...snapshot, currentModelId: 'custom' } : snapshot;
|
|
691
|
+
},
|
|
692
|
+
readTts: () => tts.snapshot(),
|
|
693
|
+
prepareModel: (modelId) => setupVoiceModel({ modelId }),
|
|
694
|
+
prepareTts: () => tts.handle('tts/setup', {}),
|
|
695
|
+
selectTts: (id) => tts.handle('tts/select', { id, backend: 'moss-onnx' }),
|
|
696
|
+
modelProgress: () => setupProgress?.progress ?? null,
|
|
697
|
+
active: () => coordinator.snapshot().active || runtime.running,
|
|
698
|
+
});
|
|
144
699
|
if (context.services.registerAssistantVoiceStreamRoute !== undefined) {
|
|
145
|
-
context.resources.add(context.services.registerAssistantVoiceStreamRoute(createAssistantVoiceStreamHandler({ coordinator })));
|
|
700
|
+
context.resources.add(context.services.registerAssistantVoiceStreamRoute(createAssistantVoiceStreamHandler({ coordinator, chat: voiceChat, tts: (request) => tts.http(request) })));
|
|
146
701
|
}
|
|
147
702
|
context.resources.add(async () => {
|
|
148
703
|
await actionBridge.dispose();
|
|
149
704
|
coordinator.dispose();
|
|
705
|
+
runtime.dispose();
|
|
150
706
|
});
|
|
707
|
+
let configuring = false;
|
|
708
|
+
const stopAssistant = async () => {
|
|
709
|
+
conversation.cancelActive();
|
|
710
|
+
previewChat.cancelActive();
|
|
711
|
+
textChat.cancelActive();
|
|
712
|
+
voiceChat.clear();
|
|
713
|
+
const lease = coordinator.snapshot();
|
|
714
|
+
if (lease.active && lease.ownerId !== null)
|
|
715
|
+
await coordinator.stop(lease.ownerId);
|
|
716
|
+
};
|
|
717
|
+
const configureAssistant = async (payload) => {
|
|
718
|
+
if (configuring)
|
|
719
|
+
throw new Error('助理配置正在保存,请稍后操作');
|
|
720
|
+
const settings = context.services.settings;
|
|
721
|
+
if (settings === undefined || context.services.settingsProvider?.writable === false)
|
|
722
|
+
throw new Error('当前助理设置不可写');
|
|
723
|
+
const revision = lifecycleRevision;
|
|
724
|
+
configuring = true;
|
|
725
|
+
try {
|
|
726
|
+
const [catalog, remoteWorkspaces] = await Promise.all([textChat.catalog(), isRecord(payload) && payload.managedWorkspaceIds !== undefined ? readRemoteWorkspaces() : Promise.resolve([])]);
|
|
727
|
+
if (revision !== lifecycleRevision || resetting)
|
|
728
|
+
throw new Error('助理配置已变化,请重新保存');
|
|
729
|
+
const workspaceIds = () => [...readWorkspaceRecords(context.services.dshContext).flatMap((workspace) => [workspace.id, createVirtualWorkspaceId(localHostId, workspace.id), createVirtualWorkspaceId('local', workspace.id)]), ...remoteWorkspaces.map((workspace) => workspace.workspaceId)];
|
|
730
|
+
let next = configureAssistantSettings(settings.get().assistant, payload, catalog, workspaceIds());
|
|
731
|
+
if (next.tts?.backend === 'moss-onnx' && !(await tts.handle('tts/catalog', {})).status.ready)
|
|
732
|
+
throw new Error('请先在更多设置中初始化 MOSS,再选择音色');
|
|
733
|
+
await stopAssistant();
|
|
734
|
+
if (revision !== lifecycleRevision || resetting)
|
|
735
|
+
throw new Error('助理配置已变化,请重新保存');
|
|
736
|
+
// 收音停止可能等待异步资源释放,重新合并期间保存的音色、形象和模型文件设置。
|
|
737
|
+
next = configureAssistantSettings(settings.get().assistant, payload, catalog, workspaceIds());
|
|
738
|
+
const scopeChanged = JSON.stringify([...settings.get().assistant.managedWorkspaceIds].sort()) !== JSON.stringify([...next.managedWorkspaceIds].sort());
|
|
739
|
+
lifecycleRevision++;
|
|
740
|
+
await settings.update({ assistant: next });
|
|
741
|
+
if (isRecord(payload) && payload.configurationPatch !== undefined) {
|
|
742
|
+
runtime.configureEnvironment(buildSherpaRuntimeEnvironment(next.voice));
|
|
743
|
+
updateVoiceAgentCapabilities();
|
|
744
|
+
}
|
|
745
|
+
if (scopeChanged && typeof settings.watch !== 'function') {
|
|
746
|
+
await conversation.invalidateContext();
|
|
747
|
+
invalidateIndex();
|
|
748
|
+
}
|
|
749
|
+
const selectionChanged = JSON.stringify(indexSelection) !== JSON.stringify(next.model ?? {});
|
|
750
|
+
indexSelection = { ...next.model };
|
|
751
|
+
if (selectionChanged)
|
|
752
|
+
invalidateIndex();
|
|
753
|
+
if (next.managedWorkspaceIds.length > 0)
|
|
754
|
+
updates.schedule();
|
|
755
|
+
return await lifecycleSnapshot();
|
|
756
|
+
}
|
|
757
|
+
finally {
|
|
758
|
+
configuring = false;
|
|
759
|
+
}
|
|
760
|
+
};
|
|
761
|
+
const resetAssistant = async () => {
|
|
762
|
+
const settings = context.services.settings;
|
|
763
|
+
if (settings === undefined || context.services.settingsProvider?.writable === false)
|
|
764
|
+
throw new Error('当前助理设置不可写');
|
|
765
|
+
if (configuring)
|
|
766
|
+
throw new Error('请等待助理配置保存完成,再重置');
|
|
767
|
+
resetting = true;
|
|
768
|
+
lifecycleRevision++;
|
|
769
|
+
indexRevision++;
|
|
770
|
+
updates.pause();
|
|
771
|
+
cancelIndexAnalysis();
|
|
772
|
+
modelAbort.abort(new Error('助理已重置'));
|
|
773
|
+
try {
|
|
774
|
+
await stopAssistant();
|
|
775
|
+
await Promise.all([tts.cancelPending(), ...[...modelTasks].map((task) => task.catch(() => undefined))]);
|
|
776
|
+
await conversation.clear(true);
|
|
777
|
+
await settings.update({ assistant: { ...structuredClone(DEFAULT_ASSISTANT_SETTINGS), profile: { name: DEFAULT_ASSISTANT_NAME, initialized: false, createdAt: null } } });
|
|
778
|
+
journal.clear();
|
|
779
|
+
indexAnalysis.clear();
|
|
780
|
+
updates.clear();
|
|
781
|
+
materials.clear();
|
|
782
|
+
lastSnapshot = null;
|
|
783
|
+
lastArchivedSessionIds = [];
|
|
784
|
+
indexSelection = {};
|
|
785
|
+
setupProgress = null;
|
|
786
|
+
initialization.reset();
|
|
787
|
+
return await lifecycleSnapshot();
|
|
788
|
+
}
|
|
789
|
+
finally {
|
|
790
|
+
modelAbort = new AbortController();
|
|
791
|
+
resetting = false;
|
|
792
|
+
}
|
|
793
|
+
};
|
|
151
794
|
context.resources.add(context.services.rpc.register('assistant', async (action, payload) => {
|
|
795
|
+
if (resetting && action !== 'lifecycle/read' && action !== 'voice/capabilities' && action !== 'tts/catalog')
|
|
796
|
+
throw new Error('助理正在重置,请稍后操作');
|
|
797
|
+
if (action.startsWith('tts/')) {
|
|
798
|
+
if (initialization.busy && action !== 'tts/catalog')
|
|
799
|
+
throw new Error('请等待语音初次配置完成');
|
|
800
|
+
const result = await tts.handle(action, payload);
|
|
801
|
+
updateVoiceAgentCapabilities();
|
|
802
|
+
return result;
|
|
803
|
+
}
|
|
152
804
|
switch (action) {
|
|
805
|
+
case 'lifecycle/read': return await lifecycleSnapshot();
|
|
806
|
+
case 'lifecycle/configure': return await configureAssistant(payload);
|
|
807
|
+
case 'lifecycle/reset': return await resetAssistant();
|
|
808
|
+
case 'conversation/start': {
|
|
809
|
+
requireInitialized();
|
|
810
|
+
const request = readAssistantRequest(payload);
|
|
811
|
+
const attachments = readAssistantAttachmentUploads(asRecord(payload)?.attachments);
|
|
812
|
+
return await conversation.start(request.requestId, request.text, await readConversationContext(), 'text', attachments);
|
|
813
|
+
}
|
|
814
|
+
case 'conversation/preview': {
|
|
815
|
+
const request = readAssistantRequest(payload);
|
|
816
|
+
const draft = asRecord(asRecord(payload)?.draft) ?? {};
|
|
817
|
+
const facts = await readConversationContext(draft);
|
|
818
|
+
await previewChat.catalog();
|
|
819
|
+
return await previewChat.start({ requestId: request.requestId, provider: facts.provider, model: facts.model, generation: facts.index.generation, messages: [{ role: 'user', text: request.text }] }, facts.index, facts.isCurrent, facts.createSystem, true);
|
|
820
|
+
}
|
|
821
|
+
case 'conversation/read': return asRecord(payload)?.preview === true ? previewChat.read(readChatRequestId(payload)) : conversation.read(readChatRequestId(payload));
|
|
822
|
+
case 'conversation/cancel': return asRecord(payload)?.preview === true ? previewChat.revoke(readChatRequestId(payload)) : conversation.cancel(readChatRequestId(payload));
|
|
823
|
+
case 'conversation/clear':
|
|
824
|
+
await stopAssistant();
|
|
825
|
+
await conversation.clear();
|
|
826
|
+
return await lifecycleSnapshot();
|
|
827
|
+
case 'conversation/compress': {
|
|
828
|
+
requireInitialized();
|
|
829
|
+
await stopAssistant();
|
|
830
|
+
await conversation.compress(await readConversationContext());
|
|
831
|
+
return await lifecycleSnapshot();
|
|
832
|
+
}
|
|
153
833
|
case 'index':
|
|
154
|
-
return await buildIndex();
|
|
834
|
+
return withIndexAnalysis(await buildIndex());
|
|
835
|
+
case 'index/rebuild':
|
|
836
|
+
chooseIndexModel(payload);
|
|
837
|
+
return startIndexAnalysis(await buildIndex('manual'), true);
|
|
838
|
+
case 'index/configure':
|
|
839
|
+
chooseIndexModel(payload);
|
|
840
|
+
return { configured: true };
|
|
841
|
+
case 'index/cancel': {
|
|
842
|
+
updates.pause();
|
|
843
|
+
const id = readChatRequestId(payload);
|
|
844
|
+
return indexAnalysis.cancel(id);
|
|
845
|
+
}
|
|
846
|
+
case 'chat/models':
|
|
847
|
+
return await textChat.catalog();
|
|
848
|
+
case 'chat/start': {
|
|
849
|
+
const chatContext = readChatContext();
|
|
850
|
+
return await textChat.start(payload, chatContext.index, chatContext.isCurrent, chatContext.createSystem);
|
|
851
|
+
}
|
|
852
|
+
case 'chat/read': {
|
|
853
|
+
const index = journal.snapshot().index;
|
|
854
|
+
if (index === undefined || !sameManagedScope(index, context.services.settings?.get().assistant.managedWorkspaceIds ?? []))
|
|
855
|
+
textChat.cancelActive();
|
|
856
|
+
return textChat.read(readChatRequestId(payload));
|
|
857
|
+
}
|
|
858
|
+
case 'chat/cancel':
|
|
859
|
+
return textChat.cancel(readChatRequestId(payload));
|
|
155
860
|
case 'summary': {
|
|
861
|
+
const snapshot = withIndexAnalysis(await buildIndex());
|
|
862
|
+
const summary = summarizeAssistantEntries(snapshot.entries, snapshot.scope, snapshot.generation, snapshot.unreadableCount);
|
|
863
|
+
return snapshot.analysis?.state === 'completed' && snapshot.analysis.result !== undefined ? { ...summary, speechText: sanitizeSpeechText(speakAssistantStructuredIndex(snapshot.analysis.result)) } : summary;
|
|
864
|
+
}
|
|
865
|
+
case 'debug': {
|
|
866
|
+
// 查看面板只列元数据,不把“刷新视图”混同为“执行索引”。
|
|
867
|
+
const managed = context.services.settings?.get().assistant.managedWorkspaceIds ?? [];
|
|
868
|
+
const source = await readAssistantSource(context.services, managed, waitingState);
|
|
869
|
+
const metadata = await buildAssistantSessionIndex({ sessions: source.sessions, scope: createAssistantScope(managed), archivedSessionIds: source.archivedSessionIds });
|
|
870
|
+
observeVersions(metadata.entries);
|
|
871
|
+
const history = journal.snapshot();
|
|
872
|
+
// 归档、空白状态或工作区成员关系变化后,旧正文不能继续冒充当前结果。
|
|
873
|
+
const matching = history.index !== undefined && sameManagedScope(history.index, managed) && sameIndexMembership(history.index, metadata);
|
|
874
|
+
if (history.index !== undefined && !matching) {
|
|
875
|
+
textChat.cancelActive();
|
|
876
|
+
updates.schedule(false);
|
|
877
|
+
}
|
|
878
|
+
const index = matching ? withIndexAnalysis(history.index, metadata.entries) : metadata;
|
|
879
|
+
const tasks = new Map((indexAnalysis.read()?.tasks ?? []).map((task) => [assistantSessionKey(task), task]));
|
|
880
|
+
const summary = summarizeAssistantEntries(index.entries, index.scope, index.generation, index.unreadableCount, 0);
|
|
881
|
+
const query = readOptionalService(context.services.dshContext, 'sessionQuery');
|
|
882
|
+
const snapshot = {
|
|
883
|
+
capturedAt: Date.now(),
|
|
884
|
+
index,
|
|
885
|
+
// 调试页不限制播报长度,复用摘要接口的范围状态和分组语义。
|
|
886
|
+
summary: index.analysis?.state === 'completed' && index.analysis.result !== undefined ? { ...summary, speechText: sanitizeSpeechText(speakAssistantStructuredIndex(index.analysis.result)) } : summary,
|
|
887
|
+
workspaces: [...readWorkspaceRecords(context.services.dshContext).map((workspace) => ({ workspaceId: workspace.id, name: workspace.name, path: workspace.path })), ...await readRemoteWorkspaces()],
|
|
888
|
+
modelId: readAssistantVoiceSettings(context.services).modelId ?? '',
|
|
889
|
+
warnings: source.warnings,
|
|
890
|
+
scopeSessions: metadata.entries.map((entry) => updates.stamp(entry, tasks.get(assistantSessionKey(entry)))),
|
|
891
|
+
indexState: readDebugIndexState(index, { building: buildingIndex !== undefined && buildingIndexRevision === indexRevision, exists: history.index !== undefined, current: lastSnapshot === history.index && matching && updates.matches(index) }),
|
|
892
|
+
indexedAt: matching ? history.indexedAt : null,
|
|
893
|
+
records: journal.snapshot().records,
|
|
894
|
+
services: {
|
|
895
|
+
workspaceList: typeof readOptionalService(context.services.dshContext, 'workspaceRegistry')?.list === 'function',
|
|
896
|
+
sessionList: typeof readOptionalService(context.services.dshContext, 'sessionController')?.list === 'function' || typeof query?.listSessions === 'function' || context.services.nativeSessions !== undefined,
|
|
897
|
+
summaryRead: typeof query?.readSurface === 'function',
|
|
898
|
+
taskDispatch: typeof readOptionalService(context.services.dshContext, 'sessionController')?.prompt === 'function',
|
|
899
|
+
remoteGateway: context.services.assistantGateway !== undefined,
|
|
900
|
+
},
|
|
901
|
+
};
|
|
902
|
+
return snapshot;
|
|
903
|
+
}
|
|
904
|
+
case 'preview': {
|
|
905
|
+
const request = readAssistantRequest(payload);
|
|
156
906
|
const snapshot = await buildIndex();
|
|
157
|
-
return
|
|
907
|
+
return {
|
|
908
|
+
generation: snapshot.generation,
|
|
909
|
+
intent: parseAssistantIntent(request.text, snapshot.entries, { indexGeneration: snapshot.generation, excludedTargets: snapshot.excludedTargets ?? [] }),
|
|
910
|
+
};
|
|
158
911
|
}
|
|
159
912
|
case 'turn': {
|
|
160
913
|
const request = readAssistantRequest(payload);
|
|
@@ -174,48 +927,60 @@ export function createGlobalVoiceRpcFeature() {
|
|
|
174
927
|
});
|
|
175
928
|
return result;
|
|
176
929
|
}
|
|
177
|
-
case 'voice/capabilities':
|
|
930
|
+
case 'voice/capabilities': {
|
|
931
|
+
await tts.snapshot();
|
|
932
|
+
updateVoiceAgentCapabilities();
|
|
178
933
|
return {
|
|
179
934
|
...coordinator.snapshot(),
|
|
935
|
+
capabilities: { ...runtime.capabilities, textToSpeech: tts.outputReady || runtime.capabilities.textToSpeech, streamingOutput: tts.outputReady || runtime.capabilities.streamingOutput },
|
|
180
936
|
voiceAgent: agent.capabilities(),
|
|
181
937
|
};
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
const current = readAssistantVoiceSettings(context.services);
|
|
189
|
-
const next = {
|
|
190
|
-
...DEFAULT_ASSISTANT_VOICE_SETTINGS,
|
|
191
|
-
...current,
|
|
192
|
-
initialized: true,
|
|
193
|
-
provider: 'sherpa-onnx',
|
|
194
|
-
modelId,
|
|
195
|
-
asrEncoder: installed.paths.asrEncoder,
|
|
196
|
-
asrDecoder: installed.paths.asrDecoder,
|
|
197
|
-
asrJoiner: installed.paths.asrJoiner,
|
|
198
|
-
asrTokens: installed.paths.asrTokens,
|
|
199
|
-
// 实时对话使用浏览器输出;不让历史配置中的离线 VAD/TTS 偷偷生效。
|
|
200
|
-
vadModel: '',
|
|
201
|
-
ttsModel: '',
|
|
202
|
-
ttsTokens: '',
|
|
203
|
-
ttsLexicon: '',
|
|
204
|
-
};
|
|
205
|
-
if (context.services.settings === undefined)
|
|
206
|
-
throw new Error('当前 Host 不支持保存语音设置');
|
|
207
|
-
await context.services.settings.update({
|
|
208
|
-
assistant: {
|
|
209
|
-
...context.services.settings.get().assistant,
|
|
210
|
-
voice: next,
|
|
211
|
-
},
|
|
938
|
+
}
|
|
939
|
+
case 'configuration/capabilities':
|
|
940
|
+
return { prepareOnly: true };
|
|
941
|
+
case 'voice/models':
|
|
942
|
+
return await models.snapshot(readAssistantVoiceSettings(context.services), {
|
|
943
|
+
running: runtime.running, ready: runtime.capabilities.realtime, operation: modelOperation,
|
|
212
944
|
});
|
|
213
|
-
|
|
945
|
+
case 'voice/initialization':
|
|
946
|
+
return await initialization.snapshot();
|
|
947
|
+
case 'voice/initialize': {
|
|
948
|
+
if (context.services.settings === undefined || context.services.settingsProvider?.writable === false)
|
|
949
|
+
throw new Error('当前语音设置不可写');
|
|
950
|
+
if (setupPending)
|
|
951
|
+
throw new Error('请等待当前识别模型操作完成');
|
|
952
|
+
if (isRecord(payload) && payload.prepareOnly === true) {
|
|
953
|
+
// 配置窗口只准备资源;识别路径和播报后端由统一保存提交。
|
|
954
|
+
const current = await initialization.snapshot();
|
|
955
|
+
const modelId = typeof payload.modelId === 'string' ? payload.modelId : current.modelId;
|
|
956
|
+
const prepared = current.recognitionReady && modelId === current.modelId ? { voice: readAssistantVoiceSettings(context.services) }
|
|
957
|
+
: await setupVoiceModel({ modelId, prepareOnly: true });
|
|
958
|
+
if (!current.tts.status.ready)
|
|
959
|
+
await tts.handle('tts/setup', { prepareOnly: true });
|
|
960
|
+
const ready = await initialization.snapshot();
|
|
961
|
+
return { ...ready, ready: true, recognitionReady: true, voice: prepared.voice,
|
|
962
|
+
tts: { ...ready.tts, settings: { ...ready.tts.settings, backend: 'moss-onnx' } } };
|
|
963
|
+
}
|
|
964
|
+
const result = await trackModel(() => initialization.initialize(modelAbort.signal));
|
|
214
965
|
updateVoiceAgentCapabilities();
|
|
215
|
-
return
|
|
966
|
+
return result;
|
|
967
|
+
}
|
|
968
|
+
case 'voice/model/verify':
|
|
969
|
+
if (initialization.busy)
|
|
970
|
+
throw new Error('请等待语音初次配置完成');
|
|
971
|
+
return await trackModel(() => verifyVoiceModel(payload));
|
|
972
|
+
case 'voice/setup':
|
|
973
|
+
if (initialization.busy)
|
|
974
|
+
throw new Error('请等待语音初次配置完成');
|
|
975
|
+
return await trackModel(() => setupVoiceModel(payload));
|
|
976
|
+
case 'voice/setup-progress': {
|
|
977
|
+
const requestId = readVoiceSetupRequestId(payload);
|
|
978
|
+
return requestId !== undefined && setupProgress?.requestId === requestId ? setupProgress.progress : null;
|
|
216
979
|
}
|
|
217
980
|
case 'voice/start':
|
|
218
981
|
{
|
|
982
|
+
if (setupPending || initialization.busy)
|
|
983
|
+
throw new Error('请等待语音模型初始化完成,再启动实时语音');
|
|
219
984
|
const ownerId = readOwner(payload);
|
|
220
985
|
if (isRecord(payload) && payload.mode === 'fallback') {
|
|
221
986
|
return {
|
|
@@ -242,10 +1007,30 @@ export function createGlobalVoiceRpcFeature() {
|
|
|
242
1007
|
}
|
|
243
1008
|
if (!coordinator.snapshot().active) {
|
|
244
1009
|
runtime.configureEnvironment(buildSherpaRuntimeEnvironment(voiceSettings));
|
|
1010
|
+
// 只读最新元数据,不等 LLM 索引总结,也不读取会话正文;失败仍保留领域词。
|
|
1011
|
+
let hotwords = buildAssistantVoiceHotwords([], []);
|
|
1012
|
+
try {
|
|
1013
|
+
hotwords = await readAssistantVoiceHotwords(readManagementSnapshot);
|
|
1014
|
+
}
|
|
1015
|
+
catch (error) {
|
|
1016
|
+
traceVoice('host.asr.hotwords_source_error', { errorName: error instanceof Error ? error.name : 'UnknownError' });
|
|
1017
|
+
}
|
|
1018
|
+
runtime.configureHotwords(hotwords);
|
|
245
1019
|
}
|
|
246
1020
|
const snapshot = await coordinator.start(ownerId);
|
|
1021
|
+
tts.beginVoiceSession(ownerId);
|
|
1022
|
+
if (isRecord(payload) && typeof payload.voiceSessionId === 'string') {
|
|
1023
|
+
try {
|
|
1024
|
+
await conversation.beginVoiceSession(ownerId, payload.voiceSessionId);
|
|
1025
|
+
}
|
|
1026
|
+
catch (error) {
|
|
1027
|
+
await coordinator.stop(ownerId);
|
|
1028
|
+
throw error;
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
247
1031
|
updateVoiceAgentCapabilities();
|
|
248
|
-
|
|
1032
|
+
traceVoice('host.call.started', { ownerId, epoch: snapshot.epoch, callId: isRecord(payload) && typeof payload.voiceSessionId === 'string' ? payload.voiceSessionId : undefined });
|
|
1033
|
+
return { ...snapshot, diagnosticsEnabled: diagnostics !== undefined };
|
|
249
1034
|
}
|
|
250
1035
|
catch (error) {
|
|
251
1036
|
if (isVoiceRuntimeUnavailableError(error)) {
|
|
@@ -258,12 +1043,20 @@ export function createGlobalVoiceRpcFeature() {
|
|
|
258
1043
|
throw error;
|
|
259
1044
|
}
|
|
260
1045
|
}
|
|
261
|
-
case 'voice/stop':
|
|
1046
|
+
case 'voice/stop': {
|
|
1047
|
+
traceVoice('host.call.stopping', { ownerId: readOwner(payload), epoch: coordinator.snapshot().epoch });
|
|
1048
|
+
coordinator.assertOwner(readOwner(payload));
|
|
1049
|
+
await conversation.endVoiceSession(readOwner(payload));
|
|
1050
|
+
voiceChat.clear();
|
|
262
1051
|
return await coordinator.stop(readOwner(payload));
|
|
1052
|
+
}
|
|
263
1053
|
case 'voice/heartbeat':
|
|
264
1054
|
return coordinator.heartbeat(readOwner(payload));
|
|
265
|
-
case 'voice/interrupt':
|
|
1055
|
+
case 'voice/interrupt': {
|
|
1056
|
+
coordinator.assertOwner(readOwner(payload));
|
|
1057
|
+
voiceChat.cancelActive();
|
|
266
1058
|
return await coordinator.interrupt(readOwner(payload));
|
|
1059
|
+
}
|
|
267
1060
|
case 'voice/register-client': {
|
|
268
1061
|
const ownerId = readOwner(payload);
|
|
269
1062
|
const capabilities = readVoiceRuntimeCapabilities(payload);
|
|
@@ -281,21 +1074,49 @@ export function createGlobalVoiceRpcFeature() {
|
|
|
281
1074
|
const sequence = isRecord(payload) && typeof payload.sequence === 'number' && Number.isFinite(payload.sequence) ? payload.sequence : undefined;
|
|
282
1075
|
return coordinator.acceptClientEvent(ownerId, event, sequence);
|
|
283
1076
|
}
|
|
284
|
-
case 'voice/
|
|
1077
|
+
case 'voice/chat/start':
|
|
1078
|
+
return await measureVoice('host.chat.start', { requestId: readChatRequestId(payload), ownerId: readOwner(payload) }, () => startVoiceChat(payload));
|
|
1079
|
+
case 'voice/diagnostics': {
|
|
1080
|
+
if (diagnostics === undefined)
|
|
1081
|
+
return { recorded: 0 };
|
|
285
1082
|
const ownerId = readOwner(payload);
|
|
286
|
-
|
|
287
|
-
const
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
1083
|
+
const value = asRecord(payload);
|
|
1084
|
+
const records = value?.records;
|
|
1085
|
+
if (!Array.isArray(records) || records.length > 64)
|
|
1086
|
+
throw new Error('语音诊断每批最多 64 条记录');
|
|
1087
|
+
let recorded = 0;
|
|
1088
|
+
for (const item of records) {
|
|
1089
|
+
if (!isRecord(item) || typeof item.event !== 'string' || !item.event.startsWith('client.') || typeof item.timestamp !== 'number' || !Number.isFinite(item.timestamp) || Math.abs(item.timestamp - Date.now()) > 86400_000)
|
|
1090
|
+
continue;
|
|
1091
|
+
diagnostics.writer.record({ timestamp: item.timestamp, event: item.event, fields: { ...sanitizeVoiceDiagnosticFields(item.fields), ownerId } }, 'client');
|
|
1092
|
+
recorded++;
|
|
1093
|
+
}
|
|
1094
|
+
if (typeof value?.dropped === 'number' && value.dropped > 0)
|
|
1095
|
+
traceVoice('diagnostics.client_dropped', { ownerId, dropped: value.dropped });
|
|
1096
|
+
return { recorded };
|
|
1097
|
+
}
|
|
1098
|
+
case 'voice/chat/read': {
|
|
1099
|
+
const { ownerId, epoch } = readVoiceChatLease(payload);
|
|
1100
|
+
return voiceChat.read(ownerId, epoch, readChatRequestId(payload));
|
|
1101
|
+
}
|
|
1102
|
+
case 'voice/chat/cancel': {
|
|
1103
|
+
const { ownerId, epoch } = readVoiceChatLease(payload);
|
|
1104
|
+
voiceChat.cancel(ownerId, epoch, readChatRequestId(payload));
|
|
1105
|
+
return { cancelled: true };
|
|
1106
|
+
}
|
|
1107
|
+
case 'voice/chat/clear':
|
|
1108
|
+
readVoiceChatLease(payload);
|
|
1109
|
+
voiceChat.clear();
|
|
1110
|
+
await conversation.clear();
|
|
1111
|
+
return { cleared: true };
|
|
1112
|
+
case 'voice/text': {
|
|
1113
|
+
// 兼容旧客户端,但识别话语统一走 LLM,不再隐式触发关键词派发。
|
|
1114
|
+
const { ownerId, epoch } = readVoiceChatLease(payload);
|
|
1115
|
+
const run = await startVoiceChat(payload);
|
|
1116
|
+
const result = await voiceChat.wait(ownerId, epoch, run.requestId);
|
|
1117
|
+
if (result.state !== 'completed')
|
|
1118
|
+
throw new Error(result.error ?? '语音 LLM 对话已停止');
|
|
1119
|
+
return { kind: 'chat', speechText: result.text, requestId: result.requestId };
|
|
299
1120
|
}
|
|
300
1121
|
default:
|
|
301
1122
|
throw new Error(`未知全局语音 RPC: assistant/${action}`);
|
|
@@ -304,6 +1125,20 @@ export function createGlobalVoiceRpcFeature() {
|
|
|
304
1125
|
},
|
|
305
1126
|
};
|
|
306
1127
|
}
|
|
1128
|
+
/** 原始材料就绪和完整结构化索引就绪分别表示,失败时不启用问答。 */
|
|
1129
|
+
function readDebugIndexState(index, state) {
|
|
1130
|
+
if (state.building || index.analysis?.state === 'running')
|
|
1131
|
+
return 'building';
|
|
1132
|
+
if (!state.exists)
|
|
1133
|
+
return 'not-built';
|
|
1134
|
+
if (!state.current)
|
|
1135
|
+
return 'stale';
|
|
1136
|
+
if (index.entries.some((entry) => entry.indexState !== undefined && entry.indexState !== 'completed'))
|
|
1137
|
+
return 'incomplete';
|
|
1138
|
+
if (index.entries.length > 0 && (index.analysis?.state !== 'completed' || index.analysis.result?.sessions.length !== index.entries.length || index.analysis.tasks?.some((task) => task.state === 'deferred')))
|
|
1139
|
+
return 'incomplete';
|
|
1140
|
+
return 'ready';
|
|
1141
|
+
}
|
|
307
1142
|
/**
|
|
308
1143
|
* 在 Host Context 注册 CodingNS 自己的 voiceAgent 服务。
|
|
309
1144
|
*
|
|
@@ -358,39 +1193,52 @@ function readAssistantRequest(payload) {
|
|
|
358
1193
|
const requestId = typeof payload.requestId === 'string' && payload.requestId.trim() !== '' ? payload.requestId.trim() : `assistant-${randomUUID()}`;
|
|
359
1194
|
return { text: payload.text.trim(), requestId };
|
|
360
1195
|
}
|
|
361
|
-
async function dispatchPrompt(services, request) {
|
|
1196
|
+
async function dispatchPrompt(services, request, signal = new AbortController().signal) {
|
|
362
1197
|
const localHostId = process.env.CODINGNS4DSH_HOST_ID?.trim() || 'local-host';
|
|
363
|
-
|
|
364
|
-
|
|
1198
|
+
signal.throwIfAborted();
|
|
1199
|
+
if (request.hostId !== undefined && request.hostId !== localHostId) {
|
|
1200
|
+
if (services.assistantGateway === undefined)
|
|
1201
|
+
throw new Error('远端会话管理网关不可用');
|
|
1202
|
+
await services.assistantGateway.dispatch({ ...request, hostId: request.hostId }, signal);
|
|
365
1203
|
return;
|
|
366
1204
|
}
|
|
367
1205
|
const controller = readOptionalService(services.dshContext, 'sessionController');
|
|
368
1206
|
if (controller !== undefined && typeof controller.prompt === 'function') {
|
|
369
|
-
|
|
1207
|
+
const { hostId: _hostId, ...prompt } = request;
|
|
1208
|
+
await controller.prompt(prompt, signal);
|
|
370
1209
|
return;
|
|
371
1210
|
}
|
|
372
1211
|
throw new Error('DSH sessionController.prompt 不可用,无法派发任务');
|
|
373
1212
|
}
|
|
374
1213
|
async function readAssistantSource(services, managedWorkspaceIds = [], waitingState) {
|
|
375
1214
|
const ctx = services.dshContext;
|
|
1215
|
+
const warnings = [];
|
|
376
1216
|
const query = readOptionalService(ctx, 'sessionQuery');
|
|
377
|
-
const
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
1217
|
+
const cache = assistantSourceCache(services);
|
|
1218
|
+
const local = await cache.share('local-sessions', async () => {
|
|
1219
|
+
const warnings = [];
|
|
1220
|
+
return { sessions: await readLocalAssistantSessions(services, warnings), warnings };
|
|
1221
|
+
});
|
|
1222
|
+
warnings.push(...local.warnings);
|
|
1223
|
+
const localSessions = local.sessions;
|
|
384
1224
|
const gatewayResult = services.assistantGateway === undefined || managedWorkspaceIds.length === 0
|
|
385
1225
|
? undefined
|
|
386
|
-
: await services.assistantGateway.list(managedWorkspaceIds).catch(() =>
|
|
1226
|
+
: await cache.share(`gateway:${JSON.stringify([...managedWorkspaceIds].sort())}`, () => services.assistantGateway.list(managedWorkspaceIds)).catch((error) => {
|
|
1227
|
+
warnings.push(`远端 Host 状态读取失败:${sanitizeSpeechText(error instanceof Error ? error.message : String(error)).slice(0, 500)}`);
|
|
1228
|
+
return undefined;
|
|
1229
|
+
});
|
|
387
1230
|
const sessions = dedupeSessionRecords([
|
|
388
|
-
...
|
|
389
|
-
...(primaryRecords.length === 0 ? flattenSessionList(bridgeSessions) : []),
|
|
1231
|
+
...localSessions,
|
|
390
1232
|
...(gatewayResult?.sessions ?? []),
|
|
391
1233
|
]);
|
|
392
1234
|
const workspaces = readWorkspaceRecords(ctx);
|
|
393
1235
|
const workspaceById = new Map(workspaces.map((workspace) => [workspace.id, workspace]));
|
|
1236
|
+
const workspaceBySession = new Map();
|
|
1237
|
+
for (const workspace of workspaces) {
|
|
1238
|
+
for (const sessionId of workspace.sessionIds)
|
|
1239
|
+
if (!workspaceBySession.has(sessionId))
|
|
1240
|
+
workspaceBySession.set(sessionId, workspace.id);
|
|
1241
|
+
}
|
|
394
1242
|
const archived = [...new Set([
|
|
395
1243
|
...readStringArray(readOptionalService(ctx, 'workspaceRegistry')?.archivedSessionIds),
|
|
396
1244
|
...(gatewayResult?.archivedSessionIds ?? []),
|
|
@@ -401,35 +1249,51 @@ async function readAssistantSource(services, managedWorkspaceIds = [], waitingSt
|
|
|
401
1249
|
for (const [sessionId, kind] of waitingState?.snapshot() ?? [])
|
|
402
1250
|
waitingBySession.set(sessionId, kind);
|
|
403
1251
|
const hostId = process.env.CODINGNS4DSH_HOST_ID?.trim() || 'local-host';
|
|
1252
|
+
const managedByWorkspace = new Map(workspaces.map((workspace) => [workspace.id,
|
|
1253
|
+
managedWorkspaceIds.find((selected) => assistantWorkspaceMatches(selected, hostId, workspace.id, true)) ?? workspace.id,
|
|
1254
|
+
]));
|
|
1255
|
+
let unmappedSessionCount = 0;
|
|
404
1256
|
const records = sessions.flatMap((raw) => {
|
|
405
1257
|
const value = asRecord(raw);
|
|
406
1258
|
const header = asRecord(value?.header) ?? value;
|
|
407
1259
|
const sessionId = readText(header, ['sessionId', 'id', 'key']);
|
|
408
1260
|
if (sessionId === null)
|
|
409
1261
|
return [];
|
|
410
|
-
//
|
|
411
|
-
|
|
412
|
-
const workspaceId = readText(value, ['workspaceId']) ?? findWorkspaceId(sessionId, header, workspaces);
|
|
413
|
-
if (workspaceId === null || !managed.has(workspaceId) || archivedSet.has(sessionId))
|
|
1262
|
+
// 子代理属于父会话,空白会话只是新会话占位;两者都不是可索引的独立对话。
|
|
1263
|
+
if (header?.origin === 'subagent' || value?.origin === 'subagent' || value?.blank === true || sessionId.startsWith(ASSISTANT_AGENT_PREFIX))
|
|
414
1264
|
return [];
|
|
415
|
-
const workspace = workspaceById.get(workspaceId);
|
|
416
|
-
const sourceWorkspaceName = readText(value, ['workspaceName', 'workspaceDisplayName']);
|
|
417
1265
|
const sourceHostId = readText(value, ['hostId', 'sourceHostId']) ?? hostId;
|
|
1266
|
+
// 本地工作区成员关系由 Registry 决定,cwd 相同不意味着它是工作区成员。
|
|
1267
|
+
// Gateway 已在远端按同一成员关系投影,保留其 workspaceId/hostId。
|
|
1268
|
+
const originalWorkspaceId = sourceHostId === hostId ? workspaceBySession.get(sessionId) ?? null : readText(value, ['workspaceId']);
|
|
1269
|
+
// 保留范围外和归档会话的元数据,索引构建器统一决定纳入/排除。
|
|
1270
|
+
// 不能提前丢掉这些记录,否则调试页和目标澄清都无法解释排除原因。
|
|
1271
|
+
if (originalWorkspaceId === null) {
|
|
1272
|
+
unmappedSessionCount += 1;
|
|
1273
|
+
return [];
|
|
1274
|
+
}
|
|
1275
|
+
const workspaceId = sourceHostId === hostId ? managedByWorkspace.get(originalWorkspaceId) ?? originalWorkspaceId : originalWorkspaceId;
|
|
1276
|
+
const workspace = workspaceById.get(originalWorkspaceId);
|
|
1277
|
+
const sourceWorkspaceName = readText(value, ['workspaceName', 'workspaceDisplayName']);
|
|
1278
|
+
const agent = sourceHostId === hostId ? readOptionalService(ctx, 'agents')?.get?.(sessionId) : undefined;
|
|
418
1279
|
const state = readText(value, ['state', 'status']) ?? '';
|
|
419
|
-
|
|
420
|
-
const running =
|
|
421
|
-
//
|
|
422
|
-
|
|
423
|
-
|
|
1280
|
+
// live 只说明存在内存实例;真实运行状态从原生列表或 Agent 状态读取。
|
|
1281
|
+
const running = value?.running === true || /^(running|active|working|queued)$/iu.test(state);
|
|
1282
|
+
// persisted/live 只表示可用性;本轮完成由明确的空闲状态证明。
|
|
1283
|
+
const completed = value?.completed === true || /^(completed|complete|done|success)$/iu.test(state);
|
|
1284
|
+
// 实时 Agent 和 Gateway 的明确 activity 优先于可能滞后的列表布尔值。
|
|
1285
|
+
const activity = agent?.status === 'running' || agent?.status === 'idle' ? agent.status
|
|
1286
|
+
: ['running', 'idle', 'unknown'].includes(value?.activity) ? value.activity : running ? 'running' : value?.running === false || completed || /^(idle|error|failed|cancelled|canceled|stopped)$/iu.test(state) ? 'idle' : 'unknown';
|
|
424
1287
|
return [{
|
|
425
1288
|
sessionId,
|
|
426
1289
|
workspaceId,
|
|
427
1290
|
workspaceName: sourceWorkspaceName ?? workspace?.name ?? workspaceId,
|
|
428
1291
|
hostId: sourceHostId,
|
|
429
|
-
running:
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
1292
|
+
running: activity === 'running',
|
|
1293
|
+
activity,
|
|
1294
|
+
completed: activity === 'idle',
|
|
1295
|
+
error: value?.error === true || /^(error|failed)$/iu.test(state),
|
|
1296
|
+
updatedAt: readTimestamp(value, ['updatedAt', 'updated', 'lastUpdatedAt']) ?? readTimestamp(header, ['updatedAt', 'updated', 'lastUpdatedAt']),
|
|
433
1297
|
waiting: readWaiting(value) ?? waitingBySession.get(sessionId) ?? null,
|
|
434
1298
|
title: readText(value, ['title', 'name', 'displayName']),
|
|
435
1299
|
titleEvents: readStringArray(value?.titleEvents),
|
|
@@ -437,6 +1301,8 @@ async function readAssistantSource(services, managedWorkspaceIds = [], waitingSt
|
|
|
437
1301
|
}];
|
|
438
1302
|
});
|
|
439
1303
|
const readSurface = query !== undefined && typeof query.readSurface === 'function' ? query.readSurface.bind(query) : undefined;
|
|
1304
|
+
if (unmappedSessionCount > 0)
|
|
1305
|
+
warnings.push(`有${unmappedSessionCount}个会话无法确定所属工作区,未纳入索引,请检查工作区成员关系。`);
|
|
440
1306
|
const readTitle = query !== undefined && typeof query.readTitle === 'function'
|
|
441
1307
|
? query.readTitle.bind(query)
|
|
442
1308
|
: query !== undefined && typeof query.readTitleSnapshot === 'function'
|
|
@@ -447,15 +1313,18 @@ async function readAssistantSource(services, managedWorkspaceIds = [], waitingSt
|
|
|
447
1313
|
: await Promise.all(records.map(async (record) => {
|
|
448
1314
|
// Gateway 已经携带远端标题;本地 query 不能读取远端 Host 的 sessionId,
|
|
449
1315
|
// 也不能把远端会话误当成本地会话产生一次额外 I/O。
|
|
450
|
-
if (record.hostId !== hostId)
|
|
1316
|
+
if (record.hostId !== hostId || !managed.has(record.workspaceId) || archivedSet.has(record.sessionId))
|
|
451
1317
|
return record;
|
|
452
|
-
const title = await readSessionTitle(readTitle, record.sessionId);
|
|
1318
|
+
const title = await cache.title(record.sessionId, JSON.stringify([record.updatedAt, record.title, record.titleEvents]), record.updatedAt !== null, () => readSessionTitle(readTitle, record.sessionId));
|
|
453
1319
|
return title === null ? record : { ...record, title };
|
|
454
1320
|
}));
|
|
455
1321
|
// workspaceRegistry 可能只暴露归档 ID,而 sessionQuery 不再返回归档记录。
|
|
456
1322
|
// 为了给用户明确的“已归档”诊断,这里只建立没有正文的元数据占位,不读取归档日志。
|
|
457
1323
|
const knownSessionIds = new Set(records.map((record) => `${record.hostId}:${record.sessionId}`));
|
|
458
|
-
const archivedStubs = workspaces.flatMap((workspace) =>
|
|
1324
|
+
const archivedStubs = workspaces.flatMap((workspace) => [...new Set([
|
|
1325
|
+
...workspace.archivedSessionIds,
|
|
1326
|
+
...workspace.sessionIds.filter((sessionId) => archivedSet.has(sessionId)),
|
|
1327
|
+
])].flatMap((sessionId) => {
|
|
459
1328
|
const key = `${hostId}:${sessionId}`;
|
|
460
1329
|
if (knownSessionIds.has(key))
|
|
461
1330
|
return [];
|
|
@@ -471,31 +1340,11 @@ async function readAssistantSource(services, managedWorkspaceIds = [], waitingSt
|
|
|
471
1340
|
title: null,
|
|
472
1341
|
summary: null,
|
|
473
1342
|
}];
|
|
474
|
-
})).concat(sessions.flatMap((raw) => {
|
|
475
|
-
const value = asRecord(raw);
|
|
476
|
-
const header = asRecord(value?.header) ?? value;
|
|
477
|
-
const sessionId = readText(header, ['sessionId', 'id', 'key']);
|
|
478
|
-
const workspaceId = readText(value, ['workspaceId']);
|
|
479
|
-
const sourceHostId = readText(value, ['hostId', 'sourceHostId']) ?? hostId;
|
|
480
|
-
if (sessionId === null || workspaceId === null || sourceHostId === hostId || !managed.has(workspaceId) || !archivedSet.has(sessionId))
|
|
481
|
-
return [];
|
|
482
|
-
const workspace = workspaceById.get(workspaceId);
|
|
483
|
-
return [{
|
|
484
|
-
sessionId,
|
|
485
|
-
workspaceId,
|
|
486
|
-
workspaceName: readText(value, ['workspaceName', 'workspaceDisplayName']) ?? workspace?.name ?? workspaceId,
|
|
487
|
-
hostId: sourceHostId,
|
|
488
|
-
running: false,
|
|
489
|
-
completed: false,
|
|
490
|
-
updatedAt: null,
|
|
491
|
-
waiting: null,
|
|
492
|
-
title: readText(value, ['title', 'name', 'displayName']),
|
|
493
|
-
summary: null,
|
|
494
|
-
}];
|
|
495
1343
|
}));
|
|
496
1344
|
return {
|
|
497
1345
|
sessions: [...hydratedRecords, ...archivedStubs],
|
|
498
1346
|
archivedSessionIds: archived,
|
|
1347
|
+
warnings,
|
|
499
1348
|
...(gatewayResult?.volatile === true ? { volatile: true } : {}),
|
|
500
1349
|
...((readSurface === undefined && gatewayResult?.readSummary === undefined) ? {} : {
|
|
501
1350
|
readSummary: async (session) => {
|
|
@@ -515,6 +1364,24 @@ async function readAssistantSource(services, managedWorkspaceIds = [], waitingSt
|
|
|
515
1364
|
}),
|
|
516
1365
|
};
|
|
517
1366
|
}
|
|
1367
|
+
/** 原生列表提供 blank/origin 投影;原始日志目录只能作为旧版本的能力回退。 */
|
|
1368
|
+
async function readLocalAssistantSessions(services, warnings) {
|
|
1369
|
+
const controller = readOptionalService(services.dshContext, 'sessionController') ?? services.nativeSessions?.controller;
|
|
1370
|
+
if (typeof controller?.list === 'function') {
|
|
1371
|
+
try {
|
|
1372
|
+
return flattenSessionList(await controller.list({}));
|
|
1373
|
+
}
|
|
1374
|
+
catch {
|
|
1375
|
+
// 列表失败或列表为空都不能改用全量历史,否则会重新纳入被侧栏隐藏的会话。
|
|
1376
|
+
warnings.push('原生会话列表读取失败,暂不纳入本地会话;请刷新后重试。');
|
|
1377
|
+
return [];
|
|
1378
|
+
}
|
|
1379
|
+
}
|
|
1380
|
+
const query = readOptionalService(services.dshContext, 'sessionQuery');
|
|
1381
|
+
if (typeof query?.listSessions === 'function')
|
|
1382
|
+
return flattenSessionList(await query.listSessions());
|
|
1383
|
+
return services.nativeSessions === undefined ? [] : flattenSessionList(await services.nativeSessions.listRemote());
|
|
1384
|
+
}
|
|
518
1385
|
async function readSessionTitle(readTitle, sessionId) {
|
|
519
1386
|
try {
|
|
520
1387
|
const value = await readTitle(sessionId);
|
|
@@ -567,9 +1434,12 @@ export function summarizeSurfaceEvents(events) {
|
|
|
567
1434
|
continue;
|
|
568
1435
|
const type = readText(event, ['type', 'kind', 'event']) ?? '';
|
|
569
1436
|
const data = asRecord(event.data);
|
|
570
|
-
const
|
|
1437
|
+
const message = asRecord(data?.message) ?? asRecord(event.message) ?? data ?? event;
|
|
1438
|
+
const text = readEventText(message);
|
|
571
1439
|
if (type === 'user/message' || type === 'user.message' || type === 'message/user') {
|
|
572
|
-
|
|
1440
|
+
// v4 把运行时上下文也放在 user/message;只提取真实用户的消息。
|
|
1441
|
+
const source = asRecord(message.source);
|
|
1442
|
+
if ((source === null || source.kind === 'user') && text !== null)
|
|
573
1443
|
latestUser = text;
|
|
574
1444
|
}
|
|
575
1445
|
else if (type === 'assistant/message' || type === 'assistant.message' || type === 'message/assistant') {
|
|
@@ -600,7 +1470,7 @@ function readEventText(value) {
|
|
|
600
1470
|
if (typeof item === 'string')
|
|
601
1471
|
return item;
|
|
602
1472
|
const record = asRecord(item);
|
|
603
|
-
return record === null ? '' : readText(record, ['text', 'content', 'value']) ?? '';
|
|
1473
|
+
return record === null || (record.type !== undefined && record.type !== 'text') ? '' : readText(record, ['text', 'content', 'value']) ?? '';
|
|
604
1474
|
})
|
|
605
1475
|
.join(' ')
|
|
606
1476
|
.trim();
|
|
@@ -653,6 +1523,43 @@ function readWaitingSessionId(args) {
|
|
|
653
1523
|
}
|
|
654
1524
|
return null;
|
|
655
1525
|
}
|
|
1526
|
+
/** 原生状态事件携带 Agent.session,旧 API 使用第一个 sessionId 字符串。 */
|
|
1527
|
+
function readIndexSessionId(args) {
|
|
1528
|
+
for (const item of args) {
|
|
1529
|
+
if (typeof item === 'string' && item !== '')
|
|
1530
|
+
return item;
|
|
1531
|
+
const value = asRecord(item);
|
|
1532
|
+
if (value === null)
|
|
1533
|
+
continue;
|
|
1534
|
+
const session = asRecord(value.session) ?? asRecord(asRecord(value.agent)?.session);
|
|
1535
|
+
const id = readText(value, ['sessionId', 'session_id']) ?? readText(session, ['id', 'sessionId']) ?? readText(asRecord(session?.header), ['id']) ?? readText(asRecord(value.header), ['id']);
|
|
1536
|
+
if (id !== null)
|
|
1537
|
+
return id;
|
|
1538
|
+
if (value.agent === undefined && value.request === undefined) {
|
|
1539
|
+
const direct = readText(value, ['id']);
|
|
1540
|
+
if (direct !== null)
|
|
1541
|
+
return direct;
|
|
1542
|
+
}
|
|
1543
|
+
}
|
|
1544
|
+
return null;
|
|
1545
|
+
}
|
|
1546
|
+
function readIndexRunning(event, args) {
|
|
1547
|
+
if (event === 'session/complete')
|
|
1548
|
+
return false;
|
|
1549
|
+
for (const item of args) {
|
|
1550
|
+
if (typeof item === 'boolean')
|
|
1551
|
+
return item;
|
|
1552
|
+
const value = asRecord(item);
|
|
1553
|
+
if (typeof value?.running === 'boolean')
|
|
1554
|
+
return value.running;
|
|
1555
|
+
const status = readText(value, ['status', 'state']) ?? (typeof item === 'string' && item !== args[0] ? item : '');
|
|
1556
|
+
if (/^(running|active|working|queued)$/iu.test(status))
|
|
1557
|
+
return true;
|
|
1558
|
+
if (/^(idle|completed|complete|done|success|error|failed|cancelled|canceled|stopped)$/iu.test(status))
|
|
1559
|
+
return false;
|
|
1560
|
+
}
|
|
1561
|
+
return null;
|
|
1562
|
+
}
|
|
656
1563
|
function readWorkspaceRecords(ctx) {
|
|
657
1564
|
const registry = readOptionalService(ctx, 'workspaceRegistry');
|
|
658
1565
|
const list = registry !== undefined && typeof registry.list === 'function' ? registry.list() : [];
|
|
@@ -707,15 +1614,19 @@ function dedupeSessionRecords(values) {
|
|
|
707
1614
|
}
|
|
708
1615
|
return result;
|
|
709
1616
|
}
|
|
710
|
-
function
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
1617
|
+
function sameManagedScope(index, managed) {
|
|
1618
|
+
const indexed = index.scope.status === 'empty' ? [] : index.scope.managedWorkspaceIds;
|
|
1619
|
+
return JSON.stringify([...new Set(indexed)].sort()) === JSON.stringify([...new Set(managed)].sort());
|
|
1620
|
+
}
|
|
1621
|
+
function sameIndexMembership(left, right) {
|
|
1622
|
+
const keys = (index) => index.entries.map((entry) => JSON.stringify([entry.hostId, entry.workspaceId, entry.sessionId])).sort();
|
|
1623
|
+
return JSON.stringify(keys(left)) === JSON.stringify(keys(right));
|
|
1624
|
+
}
|
|
1625
|
+
function readChatRequestId(payload) {
|
|
1626
|
+
const id = asRecord(payload)?.requestId;
|
|
1627
|
+
if (typeof id !== 'string' || id.length === 0 || id.length > 200)
|
|
1628
|
+
throw new Error('文本调试请求标识无效');
|
|
1629
|
+
return id;
|
|
719
1630
|
}
|
|
720
1631
|
function readAssistantVoiceSettings(services) {
|
|
721
1632
|
const configured = services.settings?.get().assistant?.voice;
|
|
@@ -730,6 +1641,11 @@ function readVoiceModelId(payload) {
|
|
|
730
1641
|
}
|
|
731
1642
|
return payload.modelId.trim();
|
|
732
1643
|
}
|
|
1644
|
+
/** 老客户端没有请求 ID 时仍可初始化;进度查询只接受具体请求的 ID。 */
|
|
1645
|
+
function readVoiceSetupRequestId(payload) {
|
|
1646
|
+
return isRecord(payload) && typeof payload.requestId === 'string' && payload.requestId.trim() !== ''
|
|
1647
|
+
? payload.requestId.trim() : undefined;
|
|
1648
|
+
}
|
|
733
1649
|
function validateAssistantVoiceSettings(settings) {
|
|
734
1650
|
if (!settings.initialized)
|
|
735
1651
|
return '请先完成全局语音助理初始化配置';
|
|
@@ -778,8 +1694,9 @@ function readOptionalService(ctx, name) {
|
|
|
778
1694
|
function asRecord(value) {
|
|
779
1695
|
return typeof value === 'object' && value !== null && !Array.isArray(value) ? value : null;
|
|
780
1696
|
}
|
|
1697
|
+
/** 原生列表缺失元数据时,null 和 Map.get() 返回的 undefined 都表示没有字段。 */
|
|
781
1698
|
function readText(value, keys) {
|
|
782
|
-
if (value === null)
|
|
1699
|
+
if (value === null || value === undefined)
|
|
783
1700
|
return null;
|
|
784
1701
|
for (const key of keys)
|
|
785
1702
|
if (typeof value[key] === 'string' && value[key].trim() !== '')
|
|
@@ -817,7 +1734,7 @@ function readVoiceRuntimeEvent(payload) {
|
|
|
817
1734
|
const epoch = value !== null && typeof value.epoch === 'number' && Number.isFinite(value.epoch) ? value.epoch : null;
|
|
818
1735
|
if (value === null || epoch === null || typeof value.type !== 'string')
|
|
819
1736
|
throw new TypeError('全局语音 RPC 的 event 无效');
|
|
820
|
-
const states = ['disabled', 'loading', 'standby', 'listening', 'speaking', 'interrupted', 'error'];
|
|
1737
|
+
const states = ['disabled', 'loading', 'standby', 'listening', 'thinking', 'speaking', 'interrupted', 'error'];
|
|
821
1738
|
if (value.type === 'state' && states.includes(value.state))
|
|
822
1739
|
return { type: 'state', state: value.state, epoch };
|
|
823
1740
|
if (value.type === 'wake')
|
|
@@ -843,7 +1760,7 @@ function readWaiting(value) {
|
|
|
843
1760
|
return null;
|
|
844
1761
|
}
|
|
845
1762
|
function readTimestamp(value, keys) {
|
|
846
|
-
if (value === null)
|
|
1763
|
+
if (value === null || value === undefined)
|
|
847
1764
|
return null;
|
|
848
1765
|
for (const key of keys) {
|
|
849
1766
|
if (typeof value[key] === 'number' && Number.isFinite(value[key]))
|