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