@jingyi0605/codingns4dsh 0.2.1-beta.5 → 0.2.1-beta.6
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 +112 -161
- package/README.md +106 -263
- package/assets/provider-icons/doubao.png +0 -0
- package/data/build/dist/client/avatar/catalog-panel.d.ts +1 -1
- package/data/build/dist/client/avatar/catalog-panel.d.ts.map +1 -1
- package/data/build/dist/client/avatar/catalog-panel.js +13 -11
- package/data/build/dist/client/avatar/catalog-panel.js.map +1 -1
- package/data/build/dist/client/avatar/engine.d.ts.map +1 -1
- package/data/build/dist/client/avatar/engine.js +26 -7
- package/data/build/dist/client/avatar/engine.js.map +1 -1
- package/data/build/dist/client/avatar/manager.d.ts.map +1 -1
- package/data/build/dist/client/avatar/manager.js +5 -1
- package/data/build/dist/client/avatar/manager.js.map +1 -1
- package/data/build/dist/client/avatar/slot.d.ts.map +1 -1
- package/data/build/dist/client/avatar/slot.js +4 -1
- package/data/build/dist/client/avatar/slot.js.map +1 -1
- package/data/build/dist/client/bundle.js +49155 -99509
- package/data/build/dist/client/bundle.js.map +1 -1
- package/data/build/dist/client/cli-catalog.d.ts +2 -0
- package/data/build/dist/client/cli-catalog.d.ts.map +1 -1
- package/data/build/dist/client/cli-catalog.js +8 -0
- package/data/build/dist/client/cli-catalog.js.map +1 -1
- package/data/build/dist/client/cli-slots.js +2 -2
- package/data/build/dist/client/cli-slots.js.map +1 -1
- package/data/build/dist/client/client.assistant-configuration-view.js +4526 -0
- package/data/build/dist/client/client.assistant-configuration-view.js.map +1 -0
- package/data/build/dist/client/client.assistant-debug-workbench.js +764 -0
- package/data/build/dist/client/client.assistant-debug-workbench.js.map +1 -0
- package/data/build/dist/client/client.assistant-prompt-editor.js +76 -0
- package/data/build/dist/client/client.assistant-prompt-editor.js.map +1 -0
- package/data/build/dist/client/client.assistant-prompts.js +44 -0
- package/data/build/dist/client/client.assistant-prompts.js.map +1 -0
- package/data/build/dist/client/client.assistant-voice-sessions.js +144 -0
- package/data/build/dist/client/client.assistant-voice-sessions.js.map +1 -0
- package/data/build/dist/client/client.assistant-workbench.js +2929 -0
- package/data/build/dist/client/client.assistant-workbench.js.map +1 -0
- package/data/build/dist/client/client.delegate-command.js +1315 -0
- package/data/build/dist/client/client.delegate-command.js.map +1 -0
- package/data/build/dist/client/client.editor-engine.js +32486 -0
- package/data/build/dist/client/client.editor-engine.js.map +1 -0
- package/data/build/dist/client/client.manager.js +3454 -0
- package/data/build/dist/client/client.manager.js.map +1 -0
- package/data/build/dist/client/client.model-catalog-cache.js +543 -0
- package/data/build/dist/client/client.model-catalog-cache.js.map +1 -0
- package/data/build/dist/client/client.native-workspace-store.js +689 -0
- package/data/build/dist/client/client.native-workspace-store.js.map +1 -0
- package/data/build/dist/client/client.primitives-adapter.js +333 -0
- package/data/build/dist/client/client.primitives-adapter.js.map +1 -0
- package/data/build/dist/client/client.react-dom.js +7286 -0
- package/data/build/dist/client/client.react-dom.js.map +1 -0
- package/data/build/dist/client/client.rolldown-runtime.js +59 -0
- package/data/build/dist/client/client.theme.js +386 -0
- package/data/build/dist/client/client.theme.js.map +1 -0
- package/data/build/dist/client/client.transport.js +3323 -0
- package/data/build/dist/client/client.transport.js.map +1 -0
- package/data/build/dist/client/client.xterm-engine.js +13064 -0
- package/data/build/dist/client/client.xterm-engine.js.map +1 -0
- package/data/build/dist/client/editor-engine.d.ts +4 -0
- package/data/build/dist/client/editor-engine.d.ts.map +1 -0
- package/data/build/dist/client/editor-engine.js +50 -0
- package/data/build/dist/client/editor-engine.js.map +1 -0
- package/data/build/dist/client/engine-loader.d.ts +5 -0
- package/data/build/dist/client/engine-loader.d.ts.map +1 -0
- package/data/build/dist/client/engine-loader.js +35 -0
- package/data/build/dist/client/engine-loader.js.map +1 -0
- package/data/build/dist/client/features/assistant-configuration-loader.d.ts +14 -0
- package/data/build/dist/client/features/assistant-configuration-loader.d.ts.map +1 -0
- package/data/build/dist/client/features/assistant-configuration-loader.js +13 -0
- package/data/build/dist/client/features/assistant-configuration-loader.js.map +1 -0
- package/data/build/dist/client/features/assistant-configuration-session.d.ts.map +1 -1
- package/data/build/dist/client/features/assistant-configuration-session.js +13 -4
- package/data/build/dist/client/features/assistant-configuration-session.js.map +1 -1
- package/data/build/dist/client/features/assistant-configuration-view.d.ts +66 -0
- package/data/build/dist/client/features/assistant-configuration-view.d.ts.map +1 -0
- package/data/build/dist/client/features/assistant-configuration-view.js +133 -0
- package/data/build/dist/client/features/assistant-configuration-view.js.map +1 -0
- package/data/build/dist/client/features/assistant-debug-workbench.d.ts +4 -11
- package/data/build/dist/client/features/assistant-debug-workbench.d.ts.map +1 -1
- package/data/build/dist/client/features/assistant-debug-workbench.js +41 -68
- package/data/build/dist/client/features/assistant-debug-workbench.js.map +1 -1
- package/data/build/dist/client/features/assistant-display-store.d.ts +57 -0
- package/data/build/dist/client/features/assistant-display-store.d.ts.map +1 -0
- package/data/build/dist/client/features/assistant-display-store.js +189 -0
- package/data/build/dist/client/features/assistant-display-store.js.map +1 -0
- package/data/build/dist/client/features/assistant-prompt-editor.d.ts +12 -0
- package/data/build/dist/client/features/assistant-prompt-editor.d.ts.map +1 -0
- package/data/build/dist/client/features/assistant-prompt-editor.js +14 -0
- package/data/build/dist/client/features/assistant-prompt-editor.js.map +1 -0
- package/data/build/dist/client/features/assistant-view-loader.d.ts +17 -0
- package/data/build/dist/client/features/assistant-view-loader.d.ts.map +1 -0
- package/data/build/dist/client/features/assistant-view-loader.js +49 -0
- package/data/build/dist/client/features/assistant-view-loader.js.map +1 -0
- package/data/build/dist/client/features/assistant-workbench.d.ts +1 -60
- package/data/build/dist/client/features/assistant-workbench.d.ts.map +1 -1
- package/data/build/dist/client/features/assistant-workbench.js +41 -169
- package/data/build/dist/client/features/assistant-workbench.js.map +1 -1
- package/data/build/dist/client/features/cli-adapters.js +3 -7
- package/data/build/dist/client/features/cli-adapters.js.map +1 -1
- package/data/build/dist/client/features/global-voice-assistant.d.ts.map +1 -1
- package/data/build/dist/client/features/global-voice-assistant.js +21 -20
- package/data/build/dist/client/features/global-voice-assistant.js.map +1 -1
- package/data/build/dist/client/features/peer-host.d.ts.map +1 -1
- package/data/build/dist/client/features/peer-host.js +14 -25
- package/data/build/dist/client/features/peer-host.js.map +1 -1
- package/data/build/dist/client/file-management-dom.d.ts +3 -1
- package/data/build/dist/client/file-management-dom.d.ts.map +1 -1
- package/data/build/dist/client/file-management-dom.js +85 -79
- package/data/build/dist/client/file-management-dom.js.map +1 -1
- package/data/build/dist/client/locales/assistantAvatar.d.ts +1 -1
- package/data/build/dist/client/locales/assistantAvatar.js +2 -2
- package/data/build/dist/client/locales/assistantAvatar.js.map +1 -1
- package/data/build/dist/client/locales/fileWorkspace.d.ts.map +1 -1
- package/data/build/dist/client/locales/fileWorkspace.js +2 -0
- package/data/build/dist/client/locales/fileWorkspace.js.map +1 -1
- package/data/build/dist/client/peer-host-management-api.d.ts +2 -2
- package/data/build/dist/client/peer-host-management-api.d.ts.map +1 -1
- package/data/build/dist/client/peer-host-management-api.js +8 -5
- package/data/build/dist/client/peer-host-management-api.js.map +1 -1
- package/data/build/dist/client/provider-icon-assets.js +5 -39
- package/data/build/dist/client/provider-icon-assets.js.map +1 -1
- package/data/build/dist/client/provider-icon-bridge.d.ts +6 -0
- package/data/build/dist/client/provider-icon-bridge.d.ts.map +1 -0
- package/data/build/dist/client/provider-icon-bridge.js +65 -0
- package/data/build/dist/client/provider-icon-bridge.js.map +1 -0
- package/data/build/dist/client/provider-icons.d.ts +1 -0
- package/data/build/dist/client/provider-icons.d.ts.map +1 -1
- package/data/build/dist/client/provider-icons.js +2 -1
- package/data/build/dist/client/provider-icons.js.map +1 -1
- package/data/build/dist/client/remote-web-context.d.ts +2 -0
- package/data/build/dist/client/remote-web-context.d.ts.map +1 -1
- package/data/build/dist/client/remote-web-context.js +50 -2
- package/data/build/dist/client/remote-web-context.js.map +1 -1
- package/data/build/dist/client/serial-polling.d.ts +3 -1
- package/data/build/dist/client/serial-polling.d.ts.map +1 -1
- package/data/build/dist/client/serial-polling.js +10 -3
- package/data/build/dist/client/serial-polling.js.map +1 -1
- package/data/build/dist/client/settings-section.js +8 -2
- package/data/build/dist/client/settings-section.js.map +1 -1
- package/data/build/dist/client/terminal/xterm-engine.d.ts +4 -0
- package/data/build/dist/client/terminal/xterm-engine.d.ts.map +1 -0
- package/data/build/dist/client/terminal/xterm-engine.js +5 -0
- package/data/build/dist/client/terminal/xterm-engine.js.map +1 -0
- package/data/build/dist/client/terminal/xterm-view.d.ts.map +1 -1
- package/data/build/dist/client/terminal/xterm-view.js +33 -25
- package/data/build/dist/client/terminal/xterm-view.js.map +1 -1
- package/data/build/dist/host/avatar/temporary-previews.d.ts +3 -1
- package/data/build/dist/host/avatar/temporary-previews.d.ts.map +1 -1
- package/data/build/dist/host/avatar/temporary-previews.js +7 -2
- package/data/build/dist/host/avatar/temporary-previews.js.map +1 -1
- package/data/build/dist/host/cli-adapters/antigravity-driver.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/antigravity-driver.js +2 -2
- package/data/build/dist/host/cli-adapters/antigravity-driver.js.map +1 -1
- package/data/build/dist/host/cli-adapters/binary-detection.d.ts +19 -0
- package/data/build/dist/host/cli-adapters/binary-detection.d.ts.map +1 -0
- package/data/build/dist/host/cli-adapters/binary-detection.js +71 -0
- package/data/build/dist/host/cli-adapters/binary-detection.js.map +1 -0
- package/data/build/dist/host/cli-adapters/claude-driver.d.ts +2 -0
- package/data/build/dist/host/cli-adapters/claude-driver.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/claude-driver.js +4 -0
- package/data/build/dist/host/cli-adapters/claude-driver.js.map +1 -1
- package/data/build/dist/host/cli-adapters/claude-model-options.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/claude-model-options.js +2 -1
- package/data/build/dist/host/cli-adapters/claude-model-options.js.map +1 -1
- package/data/build/dist/host/cli-adapters/claude-process.d.ts +7 -0
- package/data/build/dist/host/cli-adapters/claude-process.d.ts.map +1 -0
- package/data/build/dist/host/cli-adapters/claude-process.js +59 -0
- package/data/build/dist/host/cli-adapters/claude-process.js.map +1 -0
- package/data/build/dist/host/cli-adapters/codebuddy-driver.d.ts +3 -0
- package/data/build/dist/host/cli-adapters/codebuddy-driver.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/codebuddy-driver.js +18 -5
- package/data/build/dist/host/cli-adapters/codebuddy-driver.js.map +1 -1
- package/data/build/dist/host/cli-adapters/command-code-driver.d.ts +0 -1
- package/data/build/dist/host/cli-adapters/command-code-driver.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/command-code-driver.js +6 -29
- package/data/build/dist/host/cli-adapters/command-code-driver.js.map +1 -1
- package/data/build/dist/host/cli-adapters/doubao-app.d.ts +27 -0
- package/data/build/dist/host/cli-adapters/doubao-app.d.ts.map +1 -0
- package/data/build/dist/host/cli-adapters/doubao-app.js +110 -0
- package/data/build/dist/host/cli-adapters/doubao-app.js.map +1 -0
- package/data/build/dist/host/cli-adapters/doubao-artifact-store.d.ts +16 -0
- package/data/build/dist/host/cli-adapters/doubao-artifact-store.d.ts.map +1 -0
- package/data/build/dist/host/cli-adapters/doubao-artifact-store.js +142 -0
- package/data/build/dist/host/cli-adapters/doubao-artifact-store.js.map +1 -0
- package/data/build/dist/host/cli-adapters/doubao-artifacts.d.ts +16 -0
- package/data/build/dist/host/cli-adapters/doubao-artifacts.d.ts.map +1 -0
- package/data/build/dist/host/cli-adapters/doubao-artifacts.js +34 -0
- package/data/build/dist/host/cli-adapters/doubao-artifacts.js.map +1 -0
- package/data/build/dist/host/cli-adapters/doubao-cdp.d.ts +49 -0
- package/data/build/dist/host/cli-adapters/doubao-cdp.d.ts.map +1 -0
- package/data/build/dist/host/cli-adapters/doubao-cdp.js +177 -0
- package/data/build/dist/host/cli-adapters/doubao-cdp.js.map +1 -0
- package/data/build/dist/host/cli-adapters/doubao-driver.d.ts +33 -0
- package/data/build/dist/host/cli-adapters/doubao-driver.d.ts.map +1 -0
- package/data/build/dist/host/cli-adapters/doubao-driver.js +291 -0
- package/data/build/dist/host/cli-adapters/doubao-driver.js.map +1 -0
- package/data/build/dist/host/cli-adapters/doubao-events.d.ts +21 -0
- package/data/build/dist/host/cli-adapters/doubao-events.d.ts.map +1 -0
- package/data/build/dist/host/cli-adapters/doubao-events.js +126 -0
- package/data/build/dist/host/cli-adapters/doubao-events.js.map +1 -0
- package/data/build/dist/host/cli-adapters/doubao-runtime.d.ts +6 -0
- package/data/build/dist/host/cli-adapters/doubao-runtime.d.ts.map +1 -0
- package/data/build/dist/host/cli-adapters/doubao-runtime.js +176 -0
- package/data/build/dist/host/cli-adapters/doubao-runtime.js.map +1 -0
- package/data/build/dist/host/cli-adapters/doubao-tools.d.ts +8 -0
- package/data/build/dist/host/cli-adapters/doubao-tools.d.ts.map +1 -0
- package/data/build/dist/host/cli-adapters/doubao-tools.js +139 -0
- package/data/build/dist/host/cli-adapters/doubao-tools.js.map +1 -0
- package/data/build/dist/host/cli-adapters/driver.d.ts +3 -2
- package/data/build/dist/host/cli-adapters/driver.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/feature.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/feature.js +2 -0
- package/data/build/dist/host/cli-adapters/feature.js.map +1 -1
- 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 +3 -1
- package/data/build/dist/host/cli-adapters/json-rpc-process.js.map +1 -1
- package/data/build/dist/host/cli-adapters/legacy-session-adapter.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/legacy-session-adapter.js +1 -0
- package/data/build/dist/host/cli-adapters/legacy-session-adapter.js.map +1 -1
- package/data/build/dist/host/cli-adapters/model-catalog.d.ts +2 -0
- package/data/build/dist/host/cli-adapters/model-catalog.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/model-catalog.js +10 -0
- package/data/build/dist/host/cli-adapters/model-catalog.js.map +1 -1
- package/data/build/dist/host/cli-adapters/opencode-driver.d.ts +1 -0
- package/data/build/dist/host/cli-adapters/opencode-driver.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/opencode-driver.js +9 -28
- package/data/build/dist/host/cli-adapters/opencode-driver.js.map +1 -1
- package/data/build/dist/host/cli-adapters/process-utils.d.ts +4 -2
- package/data/build/dist/host/cli-adapters/process-utils.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/process-utils.js +64 -11
- package/data/build/dist/host/cli-adapters/process-utils.js.map +1 -1
- package/data/build/dist/host/cli-adapters/qoder-driver.d.ts.map +1 -1
- package/data/build/dist/host/cli-adapters/qoder-driver.js +13 -33
- package/data/build/dist/host/cli-adapters/qoder-driver.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 +31 -4
- package/data/build/dist/host/cli-adapters/registry.js.map +1 -1
- package/data/build/dist/host/cli-adapters/rpc-driver-utils.d.ts +2 -11
- 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 +1 -28
- package/data/build/dist/host/cli-adapters/rpc-driver-utils.js.map +1 -1
- package/data/build/dist/host/cli-adapters/standard-stream-driver.d.ts +3 -3
- 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 +12 -37
- package/data/build/dist/host/cli-adapters/standard-stream-driver.js.map +1 -1
- package/data/build/dist/host/cli-adapters/windows-command-environment.d.ts +12 -0
- package/data/build/dist/host/cli-adapters/windows-command-environment.d.ts.map +1 -0
- package/data/build/dist/host/cli-adapters/windows-command-environment.js +53 -0
- package/data/build/dist/host/cli-adapters/windows-command-environment.js.map +1 -0
- package/data/build/dist/host/features/assistant-avatar-runtime.d.ts.map +1 -1
- package/data/build/dist/host/features/assistant-avatar-runtime.js +23 -14
- package/data/build/dist/host/features/assistant-avatar-runtime.js.map +1 -1
- package/data/build/dist/host/features/assistant-background.d.ts +44 -0
- package/data/build/dist/host/features/assistant-background.d.ts.map +1 -0
- package/data/build/dist/host/features/assistant-background.js +116 -0
- package/data/build/dist/host/features/assistant-background.js.map +1 -0
- package/data/build/dist/host/features/assistant-index-updates.d.ts +5 -0
- package/data/build/dist/host/features/assistant-index-updates.d.ts.map +1 -1
- package/data/build/dist/host/features/assistant-index-updates.js +29 -6
- package/data/build/dist/host/features/assistant-index-updates.js.map +1 -1
- package/data/build/dist/host/features/assistant-source-cache.d.ts +2 -2
- package/data/build/dist/host/features/assistant-source-cache.d.ts.map +1 -1
- package/data/build/dist/host/features/assistant-source-cache.js +4 -2
- package/data/build/dist/host/features/assistant-source-cache.js.map +1 -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 +269 -110
- package/data/build/dist/host/features/global-voice-rpc.js.map +1 -1
- package/data/build/dist/host/features/peer-host.d.ts.map +1 -1
- package/data/build/dist/host/features/peer-host.js +61 -21
- package/data/build/dist/host/features/peer-host.js.map +1 -1
- package/data/build/dist/host/features/types.d.ts +6 -4
- package/data/build/dist/host/features/types.d.ts.map +1 -1
- package/data/build/dist/host/index.d.ts.map +1 -1
- package/data/build/dist/host/index.js +29 -19
- package/data/build/dist/host/index.js.map +1 -1
- package/data/build/dist/host/provider-icon-assets.d.ts +5 -0
- package/data/build/dist/host/provider-icon-assets.d.ts.map +1 -0
- package/data/build/dist/host/provider-icon-assets.js +61 -0
- package/data/build/dist/host/provider-icon-assets.js.map +1 -0
- package/data/build/dist/host/rpc.js +1 -1
- package/data/build/dist/host/rpc.js.map +1 -1
- package/data/build/dist/host/session-migration-repair.d.ts +4 -0
- package/data/build/dist/host/session-migration-repair.d.ts.map +1 -1
- package/data/build/dist/host/session-migration-repair.js +75 -2
- package/data/build/dist/host/session-migration-repair.js.map +1 -1
- package/data/build/dist/shared/assistant-avatar-engine.d.ts +2 -0
- package/data/build/dist/shared/assistant-avatar-engine.d.ts.map +1 -1
- package/data/build/dist/shared/assistant-avatar-engine.js +11 -1
- package/data/build/dist/shared/assistant-avatar-engine.js.map +1 -1
- package/data/build/dist/shared/contracts/cli-adapter.d.ts +3 -0
- package/data/build/dist/shared/contracts/cli-adapter.d.ts.map +1 -1
- package/data/build/dist/shared/contracts/version.d.ts +1 -1
- package/data/build/dist/shared/contracts/version.js +1 -1
- package/data/build/dist/shared/provider-icon-resources.d.ts +4 -0
- package/data/build/dist/shared/provider-icon-resources.d.ts.map +1 -0
- package/data/build/dist/shared/provider-icon-resources.js +24 -0
- package/data/build/dist/shared/provider-icon-resources.js.map +1 -0
- package/package.json +2 -2
- package/profile/README.md +2 -2
- package/profile/package.json +2 -2
- package/profile/version.json +1 -1
- package/version.json +1 -1
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto';
|
|
2
|
-
import { createAssistantScope } from './assistant-scope.js';
|
|
2
|
+
import { createAssistantScope, getAssistantScopeState } from './assistant-scope.js';
|
|
3
3
|
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
7
|
import { parseAssistantIntent } from './assistant-intent.js';
|
|
8
|
-
import { AssistantIndexUpdates, assistantSessionKey } from './assistant-index-updates.js';
|
|
8
|
+
import { AssistantIndexUpdates, assistantSessionKey, isAssistantIndexEvent } from './assistant-index-updates.js';
|
|
9
|
+
import { AssistantBackground } from './assistant-background.js';
|
|
9
10
|
import { readAssistantPrompts } from '../../shared/assistant-prompts.js';
|
|
10
11
|
import { createAssistantChatSystem } from './assistant-prompts.js';
|
|
11
12
|
import { speakAssistantStructuredIndex } from './assistant-structured-index.js';
|
|
@@ -60,8 +61,13 @@ export function createGlobalVoiceRpcFeature(options = {}) {
|
|
|
60
61
|
if (diagnostics !== undefined)
|
|
61
62
|
context.resources.add(diagnostics.dispose);
|
|
62
63
|
let resetting = false;
|
|
64
|
+
let disposed = false;
|
|
65
|
+
let statusRevision = 0;
|
|
66
|
+
let indexAbort = new AbortController();
|
|
63
67
|
// 每次读取当前档案,资源准备与旧配置都不能隐式创建助理。
|
|
64
68
|
const assistantProfile = () => readAssistantProfile(context.services.settings?.get().assistant ?? DEFAULT_ASSISTANT_SETTINGS);
|
|
69
|
+
const automaticEnabled = () => !disposed && !resetting && context.services.settings?.get().modules.globalVoiceAssistant === true
|
|
70
|
+
&& assistantProfile().initialized && (context.services.settings?.get().assistant.managedWorkspaceIds.length ?? 0) > 0;
|
|
65
71
|
let lifecycleRevision = 0;
|
|
66
72
|
const tts = new AssistantTtsService(context.services, { isVoiceActive: () => coordinator.snapshot().active });
|
|
67
73
|
context.resources.add(() => tts.dispose());
|
|
@@ -92,6 +98,7 @@ export function createGlobalVoiceRpcFeature(options = {}) {
|
|
|
92
98
|
const router = new AssistantVoiceTurnRouter(dispatcher);
|
|
93
99
|
const waitingState = new AssistantWaitingState();
|
|
94
100
|
let lastSnapshot = null;
|
|
101
|
+
const indexedEntries = new Map();
|
|
95
102
|
let lastArchivedSessionIds = [];
|
|
96
103
|
let buildingIndex;
|
|
97
104
|
let buildingIndexRevision = 0;
|
|
@@ -102,13 +109,20 @@ export function createGlobalVoiceRpcFeature(options = {}) {
|
|
|
102
109
|
dispatcher,
|
|
103
110
|
snapshot: (signal) => readManagementSnapshot(signal),
|
|
104
111
|
read: async (entry, signal) => {
|
|
112
|
+
const revision = lifecycleRevision;
|
|
105
113
|
const managed = assistantSettings().managedWorkspaceIds;
|
|
106
|
-
const source = await readAssistantSource(context.services, managed, waitingState);
|
|
114
|
+
const source = await readAssistantSource(context.services, managed, waitingState, signal);
|
|
107
115
|
signal.throwIfAborted();
|
|
116
|
+
if (resetting || revision !== lifecycleRevision)
|
|
117
|
+
throw new Error('助理管理范围已变化,请重新查询');
|
|
108
118
|
const current = source.sessions.find((item) => item.hostId === entry.hostId && item.sessionId === entry.sessionId && item.workspaceId === entry.workspaceId);
|
|
109
119
|
if (current === undefined || source.archivedSessionIds.includes(entry.sessionId))
|
|
110
120
|
throw new Error('目标会话已退出助理管理范围');
|
|
111
|
-
|
|
121
|
+
const summary = await source.readSummary?.(current, signal) ?? null;
|
|
122
|
+
signal.throwIfAborted();
|
|
123
|
+
if (resetting || revision !== lifecycleRevision)
|
|
124
|
+
throw new Error('助理管理范围已变化,请重新查询');
|
|
125
|
+
return summary;
|
|
112
126
|
},
|
|
113
127
|
});
|
|
114
128
|
const managementAgent = createAssistantAgentAdapter(context.services.dshContext, context.services.dshVersion ?? minimumSupportedDshVersion(), llm, managementTools);
|
|
@@ -131,14 +145,15 @@ export function createGlobalVoiceRpcFeature(options = {}) {
|
|
|
131
145
|
return entry.activity ?? (entry.running ? 'running' : entry.completed || entry.error === true ? 'idle' : 'unknown');
|
|
132
146
|
};
|
|
133
147
|
const updates = new AssistantIndexUpdates(async () => {
|
|
134
|
-
if (
|
|
148
|
+
if (!automaticEnabled())
|
|
135
149
|
return;
|
|
136
150
|
if (indexAnalysis.read()?.state === 'running' || buildingIndex !== undefined && buildingIndexRevision === indexRevision)
|
|
137
151
|
return;
|
|
138
|
-
const snapshot = await buildIndex();
|
|
139
|
-
if (updates.hasReady(snapshot.entries) || indexAnalysis.read()?.generation !== snapshot.generation)
|
|
140
|
-
startIndexAnalysis(snapshot);
|
|
152
|
+
const snapshot = await buildIndex('automatic');
|
|
153
|
+
if (automaticEnabled() && (updates.hasReady(snapshot.entries) || indexAnalysis.read()?.generation !== snapshot.generation))
|
|
154
|
+
startIndexAnalysis(snapshot, false, true);
|
|
141
155
|
}, liveActivity);
|
|
156
|
+
updates.setEnabled(automaticEnabled());
|
|
142
157
|
context.resources.add(() => textChat.dispose());
|
|
143
158
|
context.resources.add(() => indexAnalysis.dispose());
|
|
144
159
|
context.resources.add(() => updates.dispose());
|
|
@@ -161,8 +176,8 @@ export function createGlobalVoiceRpcFeature(options = {}) {
|
|
|
161
176
|
};
|
|
162
177
|
const cancelIndexAnalysis = () => indexAnalysis.cancelActive();
|
|
163
178
|
// 正文索引立即返回,LLM 在后台生成;轮询现有调试接口即可读取进度与结果。
|
|
164
|
-
const startIndexAnalysis = (snapshot, retryFailures = false) => {
|
|
165
|
-
if (resetting || lastSnapshot !== snapshot)
|
|
179
|
+
const startIndexAnalysis = (snapshot, retryFailures = false, automatic = false) => {
|
|
180
|
+
if (disposed || resetting || lastSnapshot !== snapshot || automatic && !automaticEnabled())
|
|
166
181
|
return withIndexAnalysis(snapshot);
|
|
167
182
|
if (snapshot.entries.length === 0) {
|
|
168
183
|
cancelIndexAnalysis();
|
|
@@ -170,9 +185,10 @@ export function createGlobalVoiceRpcFeature(options = {}) {
|
|
|
170
185
|
}
|
|
171
186
|
const revision = indexRevision;
|
|
172
187
|
const prompts = readAssistantPrompts(context.services.settings?.get().assistant.prompts);
|
|
173
|
-
indexAnalysis.start(snapshot, indexSelection, prompts.index, () => lastSnapshot === snapshot && sameManagedScope(snapshot, context.services.settings?.get().assistant.managedWorkspaceIds ?? []), (run) => {
|
|
188
|
+
indexAnalysis.start(snapshot, indexSelection, prompts.index, () => !disposed && (!automatic || automaticEnabled()) && lastSnapshot === snapshot && sameManagedScope(snapshot, context.services.settings?.get().assistant.managedWorkspaceIds ?? []), (run) => {
|
|
174
189
|
if (resetting || revision !== indexRevision || lastSnapshot !== snapshot)
|
|
175
190
|
return;
|
|
191
|
+
statusRevision++;
|
|
176
192
|
journal.updateAnalysis(run);
|
|
177
193
|
for (const task of run.tasks ?? []) {
|
|
178
194
|
if (task.state === 'completed')
|
|
@@ -190,9 +206,14 @@ export function createGlobalVoiceRpcFeature(options = {}) {
|
|
|
190
206
|
return updates.canIndex(entry);
|
|
191
207
|
// 远端没有本地完成事件:每个真实模型请求前重新确认空闲和版本。
|
|
192
208
|
const managed = context.services.settings?.get().assistant.managedWorkspaceIds ?? [];
|
|
193
|
-
const source = await readAssistantSource(context.services, managed, waitingState);
|
|
209
|
+
const source = await readAssistantSource(context.services, managed, waitingState, signal);
|
|
194
210
|
signal.throwIfAborted();
|
|
211
|
+
if (disposed || resetting || revision !== indexRevision || automatic && !automaticEnabled())
|
|
212
|
+
return false;
|
|
195
213
|
const metadata = await buildAssistantSessionIndex({ sessions: source.sessions, scope: createAssistantScope(managed), archivedSessionIds: source.archivedSessionIds });
|
|
214
|
+
signal.throwIfAborted();
|
|
215
|
+
if (revision !== indexRevision)
|
|
216
|
+
return false;
|
|
196
217
|
observeVersions(metadata.entries);
|
|
197
218
|
const current = metadata.entries.find((item) => assistantSessionKey(item) === assistantSessionKey(entry));
|
|
198
219
|
return current !== undefined && current.activity === 'idle' && current.updatedAt === entry.updatedAt && updates.canIndex(entry);
|
|
@@ -217,12 +238,15 @@ export function createGlobalVoiceRpcFeature(options = {}) {
|
|
|
217
238
|
textChat.cancelActive();
|
|
218
239
|
voiceChat.clear();
|
|
219
240
|
updates.reset();
|
|
241
|
+
statusRevision++;
|
|
220
242
|
};
|
|
221
243
|
// 刷新可以清空缓存,但索引代次必须持续递增,不能每次回到 1。
|
|
222
244
|
let indexGeneration = 0;
|
|
223
245
|
let indexRevision = 0;
|
|
224
246
|
const observeVersions = (entries) => {
|
|
225
247
|
const changed = updates.observe(entries);
|
|
248
|
+
if (changed)
|
|
249
|
+
statusRevision++;
|
|
226
250
|
if (indexAnalysis.read()?.state !== 'running')
|
|
227
251
|
return changed;
|
|
228
252
|
for (const entry of lastSnapshot?.entries ?? [])
|
|
@@ -230,21 +254,26 @@ export function createGlobalVoiceRpcFeature(options = {}) {
|
|
|
230
254
|
indexAnalysis.deferSession(assistantSessionKey(entry));
|
|
231
255
|
return changed;
|
|
232
256
|
};
|
|
233
|
-
const buildIndex = async (trigger = '
|
|
234
|
-
if (resetting)
|
|
235
|
-
throw new Error('
|
|
257
|
+
const buildIndex = async (trigger = 'manual') => {
|
|
258
|
+
if (disposed || resetting || trigger === 'automatic' && !automaticEnabled())
|
|
259
|
+
throw new Error('助理后台索引已停止');
|
|
236
260
|
const managed = context.services.settings?.get().assistant?.managedWorkspaceIds ?? [];
|
|
237
261
|
const revision = indexRevision;
|
|
262
|
+
const signal = indexAbort.signal;
|
|
238
263
|
if (buildingIndex !== undefined && buildingIndexRevision === revision)
|
|
239
264
|
return buildingIndex;
|
|
240
|
-
|
|
265
|
+
if (buildingIndex !== undefined) {
|
|
266
|
+
await buildingIndex.catch(() => undefined);
|
|
267
|
+
signal.throwIfAborted();
|
|
268
|
+
}
|
|
269
|
+
const { source, metadata } = (await background.read(trigger === 'manual' || metadataDirty)).value;
|
|
270
|
+
signal.throwIfAborted();
|
|
241
271
|
if (resetting || revision !== indexRevision)
|
|
242
272
|
throw new Error('索引任务已撤销');
|
|
243
273
|
if (JSON.stringify(managed) !== JSON.stringify(context.services.settings?.get().assistant.managedWorkspaceIds ?? []))
|
|
244
|
-
|
|
274
|
+
throw new Error('索引范围已变化');
|
|
245
275
|
if (buildingIndex !== undefined && buildingIndexRevision === revision)
|
|
246
276
|
return buildingIndex;
|
|
247
|
-
const metadata = await buildAssistantSessionIndex({ sessions: source.sessions, scope: createAssistantScope(managed), archivedSessionIds: source.archivedSessionIds });
|
|
248
277
|
if (resetting || revision !== indexRevision)
|
|
249
278
|
throw new Error('索引任务已撤销');
|
|
250
279
|
observeVersions(metadata.entries);
|
|
@@ -256,6 +285,7 @@ export function createGlobalVoiceRpcFeature(options = {}) {
|
|
|
256
285
|
if (trigger !== 'manual' && lastSnapshot !== null && sameIndexMembership(lastSnapshot, metadata) && updates.matches(lastSnapshot) && materialKeys.size === 0)
|
|
257
286
|
return lastSnapshot;
|
|
258
287
|
const recordId = journal.begin(trigger, managed);
|
|
288
|
+
statusRevision++;
|
|
259
289
|
const failures = new Map();
|
|
260
290
|
const task = (async () => {
|
|
261
291
|
lastArchivedSessionIds = source.archivedSessionIds;
|
|
@@ -273,7 +303,9 @@ export function createGlobalVoiceRpcFeature(options = {}) {
|
|
|
273
303
|
if (cached !== undefined && cached.version === session.sourceVersion)
|
|
274
304
|
return cached.summary;
|
|
275
305
|
try {
|
|
276
|
-
|
|
306
|
+
signal.throwIfAborted();
|
|
307
|
+
const summary = await source.readSummary(session, signal);
|
|
308
|
+
signal.throwIfAborted();
|
|
277
309
|
if (revision === indexRevision && session.sourceVersion !== undefined && updates.canIndex(entry))
|
|
278
310
|
materials.set(key, { version: session.sourceVersion, summary });
|
|
279
311
|
return summary;
|
|
@@ -283,41 +315,147 @@ export function createGlobalVoiceRpcFeature(options = {}) {
|
|
|
283
315
|
throw error;
|
|
284
316
|
}
|
|
285
317
|
} }),
|
|
286
|
-
...(source.readWaiting === undefined ? {} : { readWaiting: (session) => materialKeys.has(assistantSessionKey(session)) ? source.readWaiting(session) : session.waiting }),
|
|
318
|
+
...(source.readWaiting === undefined ? {} : { readWaiting: (session) => materialKeys.has(assistantSessionKey(session)) ? source.readWaiting(session, signal) : session.waiting }),
|
|
287
319
|
});
|
|
288
320
|
// 构建期间若源数据已经变化,保留记录,但不能把结果误标为最新。
|
|
289
|
-
|
|
290
|
-
|
|
321
|
+
signal.throwIfAborted();
|
|
322
|
+
if (revision !== indexRevision || disposed)
|
|
323
|
+
throw new Error('索引任务已撤销');
|
|
291
324
|
lastSnapshot = snapshot;
|
|
325
|
+
indexedEntries.clear();
|
|
326
|
+
for (const entry of snapshot.entries)
|
|
327
|
+
indexedEntries.set(assistantSessionKey(entry), entry);
|
|
328
|
+
statusRevision++;
|
|
292
329
|
journal.complete(recordId, snapshot, source.warnings, failures);
|
|
293
330
|
return snapshot;
|
|
294
|
-
})().catch((error) => { if (
|
|
295
|
-
|
|
296
|
-
|
|
331
|
+
})().catch((error) => { journal.fail(recordId, error); throw error; }).finally(() => { if (buildingIndex === task) {
|
|
332
|
+
buildingIndex = undefined;
|
|
333
|
+
statusRevision++;
|
|
334
|
+
} });
|
|
297
335
|
buildingIndexRevision = revision;
|
|
298
336
|
buildingIndex = task;
|
|
299
337
|
return task;
|
|
300
338
|
};
|
|
301
|
-
const
|
|
339
|
+
const cancelIndexWork = () => {
|
|
340
|
+
indexRevision++;
|
|
341
|
+
indexAbort.abort(new Error('索引任务已撤销'));
|
|
342
|
+
indexAbort = new AbortController();
|
|
343
|
+
cancelIndexAnalysis();
|
|
344
|
+
// 保留取消证据,但不把因模块停用而撤销的版本标成已尝试。
|
|
345
|
+
const run = indexAnalysis.read();
|
|
346
|
+
if (run !== undefined)
|
|
347
|
+
journal.updateAnalysis(run);
|
|
348
|
+
statusRevision++;
|
|
349
|
+
};
|
|
350
|
+
const invalidateIndex = () => { cancelIndexWork(); textChat.cancelActive(); voiceChat.clear(); lastSnapshot = null; updates.reset(); };
|
|
351
|
+
let metadataDirty = true;
|
|
352
|
+
let membershipDirty = true;
|
|
353
|
+
const localSessionKeys = new Map();
|
|
354
|
+
const waitingOverrides = new Map();
|
|
355
|
+
const refreshMembership = () => {
|
|
356
|
+
if (!membershipDirty)
|
|
357
|
+
return;
|
|
358
|
+
membershipDirty = false;
|
|
359
|
+
localSessionKeys.clear();
|
|
360
|
+
const managed = context.services.settings?.get().assistant.managedWorkspaceIds ?? [];
|
|
361
|
+
const archived = new Set(readStringArray(readOptionalService(context.services.dshContext, 'workspaceRegistry')?.archivedSessionIds));
|
|
362
|
+
for (const workspace of readWorkspaceRecords(context.services.dshContext)) {
|
|
363
|
+
if (!managed.some((selected) => assistantWorkspaceMatches(selected, localHostId, workspace.id, true)))
|
|
364
|
+
continue;
|
|
365
|
+
for (const id of workspace.sessionIds)
|
|
366
|
+
if (!archived.has(id))
|
|
367
|
+
localSessionKeys.set(id, assistantSessionKey({ hostId: localHostId, sessionId: id }));
|
|
368
|
+
}
|
|
369
|
+
};
|
|
370
|
+
let metadataEventRevision = 0;
|
|
371
|
+
const background = new AssistantBackground({
|
|
372
|
+
read: async (signal) => {
|
|
373
|
+
const eventRevision = metadataEventRevision;
|
|
374
|
+
const managed = [...context.services.settings?.get().assistant.managedWorkspaceIds ?? []];
|
|
375
|
+
let source = await readAssistantSource(context.services, managed, waitingState, signal);
|
|
376
|
+
signal.throwIfAborted();
|
|
377
|
+
if (source.failed) {
|
|
378
|
+
// 短暂断线不是删除成员。保留同一范围已知远端元数据,但撤销空闲证明,
|
|
379
|
+
// 从而保留材料与成功结果,同时禁止把离线来源当作最新事实送进模型。
|
|
380
|
+
const current = new Set(source.sessions.map(assistantSessionKey));
|
|
381
|
+
const missing = (background.snapshot()?.value.source.sessions ?? []).filter((entry) => entry.hostId !== localHostId && !current.has(assistantSessionKey(entry)));
|
|
382
|
+
source = { ...source, sessions: [...source.sessions, ...missing.map((entry) => ({ ...entry, running: false, completed: false, activity: 'unknown' }))] };
|
|
383
|
+
}
|
|
384
|
+
const metadata = await buildAssistantSessionIndex({ sessions: source.sessions, scope: createAssistantScope(managed), archivedSessionIds: source.archivedSessionIds });
|
|
385
|
+
signal.throwIfAborted();
|
|
386
|
+
return { source, metadata, eventRevision };
|
|
387
|
+
},
|
|
388
|
+
publish: ({ metadata, eventRevision }) => {
|
|
389
|
+
metadataDirty = metadataEventRevision !== eventRevision;
|
|
390
|
+
// 成员表随成功元数据快照更新;常规会话事件不再遍历工作区和会话列表。
|
|
391
|
+
localSessionKeys.clear();
|
|
392
|
+
for (const entry of metadata.entries)
|
|
393
|
+
if (entry.hostId === localHostId)
|
|
394
|
+
localSessionKeys.set(entry.sessionId, assistantSessionKey(entry));
|
|
395
|
+
membershipDirty = metadataDirty;
|
|
396
|
+
const key = readDefaultModelKey();
|
|
397
|
+
if (key !== defaultModelKey) {
|
|
398
|
+
defaultModelKey = key;
|
|
399
|
+
if (indexSelection.provider === undefined)
|
|
400
|
+
invalidateIndex();
|
|
401
|
+
}
|
|
402
|
+
observeVersions(metadata.entries);
|
|
403
|
+
if (updates.hasReady(metadata.entries) || lastSnapshot !== null && !sameIndexMembership(lastSnapshot, metadata))
|
|
404
|
+
updates.schedule(false);
|
|
405
|
+
},
|
|
406
|
+
cadence: ({ source, metadata }) => ({
|
|
407
|
+
remote: source.volatile === true || source.failed === true || metadata.entries.some((entry) => entry.hostId !== localHostId),
|
|
408
|
+
active: metadata.entries.some((entry) => entry.hostId !== localHostId && (entry.activity !== 'idle' || entry.waiting !== null)),
|
|
409
|
+
failed: source.failed === true,
|
|
410
|
+
}),
|
|
411
|
+
});
|
|
412
|
+
let backgroundEnabled = automaticEnabled();
|
|
413
|
+
const syncBackground = () => {
|
|
414
|
+
const enabled = automaticEnabled();
|
|
415
|
+
if (backgroundEnabled && !enabled)
|
|
416
|
+
cancelIndexWork();
|
|
417
|
+
backgroundEnabled = enabled;
|
|
418
|
+
updates.setEnabled(enabled);
|
|
419
|
+
background.setEnabled(enabled);
|
|
420
|
+
};
|
|
421
|
+
const markMetadataChanged = (members = false) => {
|
|
422
|
+
metadataDirty = true;
|
|
423
|
+
metadataEventRevision++;
|
|
424
|
+
statusRevision++;
|
|
425
|
+
membershipDirty ||= members;
|
|
426
|
+
background.request(5_000);
|
|
427
|
+
};
|
|
428
|
+
background.setEnabled(backgroundEnabled);
|
|
429
|
+
context.resources.add(() => { disposed = true; cancelIndexWork(); background.dispose(); updates.dispose(); });
|
|
302
430
|
const eventDisposers = [];
|
|
303
431
|
for (const eventName of ['workspace/archive', 'workspace/unarchive', 'workspace/changed']) {
|
|
304
|
-
const disposer = context.services.events?.on(eventName, () => updates.schedule());
|
|
432
|
+
const disposer = context.services.events?.on(eventName, () => { markMetadataChanged(true); updates.schedule(); });
|
|
305
433
|
if (typeof disposer === 'function')
|
|
306
434
|
eventDisposers.push(disposer);
|
|
307
435
|
}
|
|
308
436
|
const sessionKey = (args) => {
|
|
437
|
+
if (!automaticEnabled() && lastSnapshot === null && background.snapshot() === undefined)
|
|
438
|
+
return null;
|
|
309
439
|
const id = readIndexSessionId(args);
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
return
|
|
440
|
+
if (id === null)
|
|
441
|
+
return null;
|
|
442
|
+
refreshMembership();
|
|
443
|
+
return localSessionKeys.get(id) ?? null;
|
|
314
444
|
};
|
|
315
445
|
const changedSession = (args) => { const key = sessionKey(args); if (key !== null) {
|
|
446
|
+
markMetadataChanged();
|
|
316
447
|
updates.changed(key);
|
|
317
448
|
indexAnalysis.deferSession(key);
|
|
318
449
|
} };
|
|
319
450
|
for (const eventName of ['session/update', 'session/title']) {
|
|
320
|
-
const disposer = context.services.events?.on(eventName, (...args) =>
|
|
451
|
+
const disposer = context.services.events?.on(eventName, (...args) => {
|
|
452
|
+
if (eventName === 'session/title') {
|
|
453
|
+
const id = readIndexSessionId(args);
|
|
454
|
+
if (id !== null)
|
|
455
|
+
assistantSourceCache(context.services).invalidateTitle(id);
|
|
456
|
+
}
|
|
457
|
+
changedSession(args);
|
|
458
|
+
});
|
|
321
459
|
if (typeof disposer === 'function')
|
|
322
460
|
eventDisposers.push(disposer);
|
|
323
461
|
}
|
|
@@ -327,10 +465,13 @@ export function createGlobalVoiceRpcFeature(options = {}) {
|
|
|
327
465
|
const status = readIndexRunning(eventName, args);
|
|
328
466
|
if (key === null || status === null)
|
|
329
467
|
return;
|
|
468
|
+
markMetadataChanged();
|
|
330
469
|
if (eventName === 'session/complete') {
|
|
331
470
|
const id = readIndexSessionId(args);
|
|
332
|
-
if (id !== null)
|
|
471
|
+
if (id !== null) {
|
|
333
472
|
waitingState.resolve(id);
|
|
473
|
+
waitingOverrides.set(id, null);
|
|
474
|
+
}
|
|
334
475
|
updates.changed(key);
|
|
335
476
|
}
|
|
336
477
|
updates.status(key, status);
|
|
@@ -350,8 +491,10 @@ export function createGlobalVoiceRpcFeature(options = {}) {
|
|
|
350
491
|
for (const [eventName, kind] of waitingRequests) {
|
|
351
492
|
const disposer = context.services.events?.on(eventName, (...args) => {
|
|
352
493
|
const sessionId = readWaitingSessionId(args);
|
|
353
|
-
if (sessionId !== null)
|
|
494
|
+
if (sessionId !== null) {
|
|
354
495
|
waitingState.request({ sessionId, kind });
|
|
496
|
+
waitingOverrides.set(sessionId, kind);
|
|
497
|
+
}
|
|
355
498
|
changedSession(args);
|
|
356
499
|
});
|
|
357
500
|
if (typeof disposer === 'function')
|
|
@@ -360,22 +503,27 @@ export function createGlobalVoiceRpcFeature(options = {}) {
|
|
|
360
503
|
for (const eventName of ['approval/resolve', 'approval/resolved', 'user-questions/resolve', 'user-questions/resolved', 'user-question/resolve', 'user-question/answered']) {
|
|
361
504
|
const disposer = context.services.events?.on(eventName, (...args) => {
|
|
362
505
|
const sessionId = readWaitingSessionId(args);
|
|
363
|
-
if (sessionId !== null)
|
|
506
|
+
if (sessionId !== null) {
|
|
364
507
|
waitingState.resolve(sessionId);
|
|
508
|
+
waitingOverrides.set(sessionId, null);
|
|
509
|
+
}
|
|
365
510
|
changedSession(args);
|
|
366
511
|
});
|
|
367
512
|
if (typeof disposer === 'function')
|
|
368
513
|
eventDisposers.push(disposer);
|
|
369
514
|
}
|
|
370
515
|
const onSessionEvent = (session, event) => {
|
|
516
|
+
if (!isAssistantIndexEvent(event))
|
|
517
|
+
return;
|
|
371
518
|
const record = asRecord(session);
|
|
372
519
|
const sessionId = readText(record, ['id', 'sessionId']) ?? readText(asRecord(record?.header), ['id', 'sessionId']);
|
|
373
|
-
if (sessionId !== null)
|
|
520
|
+
if (sessionId !== null && asRecord(event)?.type === 'session/title')
|
|
374
521
|
assistantSourceCache(context.services).invalidateTitle(sessionId);
|
|
375
522
|
const key = sessionKey([session]);
|
|
376
523
|
if (key === null)
|
|
377
524
|
return;
|
|
378
|
-
|
|
525
|
+
markMetadataChanged();
|
|
526
|
+
const entry = indexedEntries.get(key);
|
|
379
527
|
const before = entry === undefined ? undefined : updates.stamp(entry).sourceVersion;
|
|
380
528
|
updates.event(key, event);
|
|
381
529
|
if (entry !== undefined && before !== updates.stamp(entry).sourceVersion)
|
|
@@ -405,6 +553,7 @@ export function createGlobalVoiceRpcFeature(options = {}) {
|
|
|
405
553
|
managedScopeKey = nextKey;
|
|
406
554
|
currentPrompts = nextPrompts;
|
|
407
555
|
configuredModelKey = nextModelKey;
|
|
556
|
+
syncBackground();
|
|
408
557
|
return;
|
|
409
558
|
}
|
|
410
559
|
const scopeChanged = nextKey !== managedScopeKey;
|
|
@@ -428,8 +577,9 @@ export function createGlobalVoiceRpcFeature(options = {}) {
|
|
|
428
577
|
voiceChat.clear();
|
|
429
578
|
}
|
|
430
579
|
if (scopeChanged) {
|
|
431
|
-
|
|
432
|
-
|
|
580
|
+
cancelIndexWork();
|
|
581
|
+
background.invalidate();
|
|
582
|
+
markMetadataChanged(true);
|
|
433
583
|
lastSnapshot = null;
|
|
434
584
|
updates.schedule();
|
|
435
585
|
}
|
|
@@ -438,37 +588,12 @@ export function createGlobalVoiceRpcFeature(options = {}) {
|
|
|
438
588
|
managedScopeKey = nextKey;
|
|
439
589
|
currentPrompts = nextPrompts;
|
|
440
590
|
configuredModelKey = nextModelKey;
|
|
591
|
+
syncBackground();
|
|
592
|
+
if (scopeChanged)
|
|
593
|
+
background.request();
|
|
441
594
|
});
|
|
442
595
|
if (typeof disposeSettingsWatch === 'function')
|
|
443
596
|
eventDisposers.push(disposeSettingsWatch);
|
|
444
|
-
// 没有本地事件总线的远端也通过元数据版本发现变化;这里只读取列表,不读正文。
|
|
445
|
-
let refreshingVersions = false;
|
|
446
|
-
const refreshVersions = async () => {
|
|
447
|
-
if (resetting || !assistantProfile().initialized)
|
|
448
|
-
return;
|
|
449
|
-
if (refreshingVersions)
|
|
450
|
-
return;
|
|
451
|
-
refreshingVersions = true;
|
|
452
|
-
try {
|
|
453
|
-
const key = readDefaultModelKey();
|
|
454
|
-
if (key !== defaultModelKey) {
|
|
455
|
-
defaultModelKey = key;
|
|
456
|
-
if (indexSelection.provider === undefined)
|
|
457
|
-
invalidateIndex();
|
|
458
|
-
}
|
|
459
|
-
const managed = context.services.settings?.get().assistant.managedWorkspaceIds ?? [];
|
|
460
|
-
const source = await readAssistantSource(context.services, managed, waitingState);
|
|
461
|
-
const metadata = await buildAssistantSessionIndex({ sessions: source.sessions, scope: createAssistantScope(managed), archivedSessionIds: source.archivedSessionIds });
|
|
462
|
-
const changed = observeVersions(metadata.entries);
|
|
463
|
-
if (updates.hasReady(metadata.entries) || lastSnapshot !== null && !sameIndexMembership(lastSnapshot, metadata))
|
|
464
|
-
updates.schedule(changed);
|
|
465
|
-
}
|
|
466
|
-
finally {
|
|
467
|
-
refreshingVersions = false;
|
|
468
|
-
}
|
|
469
|
-
};
|
|
470
|
-
const versionTimer = setInterval(() => { void refreshVersions().catch(() => { }); }, 5000);
|
|
471
|
-
context.resources.add(() => clearInterval(versionTimer));
|
|
472
597
|
updates.schedule();
|
|
473
598
|
context.resources.add(() => { for (const dispose of eventDisposers.splice(0))
|
|
474
599
|
dispose(); });
|
|
@@ -496,6 +621,8 @@ export function createGlobalVoiceRpcFeature(options = {}) {
|
|
|
496
621
|
}));
|
|
497
622
|
// 两种入口共用完整结构化索引门禁,语音不能绕过待更新或失败的会话。
|
|
498
623
|
const readChatContext = () => {
|
|
624
|
+
if (background.snapshot()?.value.source.failed)
|
|
625
|
+
throw new Error('远端索引状态暂不可确认,请等待连接恢复');
|
|
499
626
|
const index = journal.snapshot().index;
|
|
500
627
|
const managed = context.services.settings?.get().assistant.managedWorkspaceIds ?? [];
|
|
501
628
|
if (index === undefined || lastSnapshot !== index || !sameManagedScope(index, managed) || !updates.matches(index))
|
|
@@ -532,10 +659,10 @@ export function createGlobalVoiceRpcFeature(options = {}) {
|
|
|
532
659
|
requireInitialized();
|
|
533
660
|
const revision = lifecycleRevision;
|
|
534
661
|
const managed = assistantSettings().managedWorkspaceIds;
|
|
535
|
-
const source = await readAssistantSource(context.services, managed, waitingState);
|
|
662
|
+
const source = await readAssistantSource(context.services, managed, waitingState, signal);
|
|
536
663
|
signal.throwIfAborted();
|
|
537
664
|
const index = await buildAssistantSessionIndex({ sessions: source.sessions.filter((entry) => !managementAgent.sessionIds.has(entry.sessionId)), scope: createAssistantScope(managed), archivedSessionIds: source.archivedSessionIds, generation: indexGeneration });
|
|
538
|
-
const workspaces =
|
|
665
|
+
const workspaces = source.workspaces;
|
|
539
666
|
signal.throwIfAborted();
|
|
540
667
|
if (resetting || revision !== lifecycleRevision || JSON.stringify(managed) !== JSON.stringify(assistantSettings().managedWorkspaceIds))
|
|
541
668
|
throw new Error('助理管理范围已变化,请重新查询');
|
|
@@ -767,8 +894,9 @@ export function createGlobalVoiceRpcFeature(options = {}) {
|
|
|
767
894
|
resetting = true;
|
|
768
895
|
lifecycleRevision++;
|
|
769
896
|
indexRevision++;
|
|
770
|
-
|
|
771
|
-
|
|
897
|
+
syncBackground();
|
|
898
|
+
background.invalidate();
|
|
899
|
+
cancelIndexWork();
|
|
772
900
|
modelAbort.abort(new Error('助理已重置'));
|
|
773
901
|
try {
|
|
774
902
|
await stopAssistant();
|
|
@@ -779,6 +907,7 @@ export function createGlobalVoiceRpcFeature(options = {}) {
|
|
|
779
907
|
indexAnalysis.clear();
|
|
780
908
|
updates.clear();
|
|
781
909
|
materials.clear();
|
|
910
|
+
waitingOverrides.clear();
|
|
782
911
|
lastSnapshot = null;
|
|
783
912
|
lastArchivedSessionIds = [];
|
|
784
913
|
indexSelection = {};
|
|
@@ -789,8 +918,31 @@ export function createGlobalVoiceRpcFeature(options = {}) {
|
|
|
789
918
|
finally {
|
|
790
919
|
modelAbort = new AbortController();
|
|
791
920
|
resetting = false;
|
|
921
|
+
syncBackground();
|
|
792
922
|
}
|
|
793
923
|
};
|
|
924
|
+
const readIndexView = () => {
|
|
925
|
+
const cached = background.snapshot();
|
|
926
|
+
const managed = context.services.settings?.get().assistant.managedWorkspaceIds ?? [];
|
|
927
|
+
const base = cached?.value.metadata ?? { generation: indexGeneration, scope: getAssistantScopeState(createAssistantScope(managed)), entries: [], unreadableCount: 0 };
|
|
928
|
+
const metadata = { ...base, entries: base.entries.map((entry) => ({ ...entry, ...(entry.hostId === localHostId && waitingOverrides.has(entry.sessionId) ? { waiting: waitingOverrides.get(entry.sessionId) } : {}) })) };
|
|
929
|
+
const history = journal.snapshot();
|
|
930
|
+
const matching = history.index !== undefined && sameManagedScope(history.index, managed) && sameIndexMembership(history.index, metadata);
|
|
931
|
+
const index = matching ? withIndexAnalysis(history.index, metadata.entries) : metadata;
|
|
932
|
+
return { cached, metadata, history, matching, index,
|
|
933
|
+
indexState: cached?.value.source.failed ? 'incomplete' : readDebugIndexState(index, { building: buildingIndex !== undefined && buildingIndexRevision === indexRevision, exists: history.index !== undefined, current: lastSnapshot === history.index && matching && updates.matches(index) }),
|
|
934
|
+
indexedAt: matching ? history.indexedAt : null, };
|
|
935
|
+
};
|
|
936
|
+
let cachedStatus;
|
|
937
|
+
const readStatus = () => {
|
|
938
|
+
const revision = statusRevision + background.version();
|
|
939
|
+
if (cachedStatus?.revision === revision)
|
|
940
|
+
return cachedStatus;
|
|
941
|
+
const view = readIndexView();
|
|
942
|
+
cachedStatus = { revision, capturedAt: view.cached?.capturedAt ?? null, indexState: view.indexState,
|
|
943
|
+
indexedAt: view.indexedAt, workspaces: view.cached?.value.source.workspaces ?? [] };
|
|
944
|
+
return cachedStatus;
|
|
945
|
+
};
|
|
794
946
|
context.resources.add(context.services.rpc.register('assistant', async (action, payload) => {
|
|
795
947
|
if (resetting && action !== 'lifecycle/read' && action !== 'voice/capabilities' && action !== 'tts/catalog')
|
|
796
948
|
throw new Error('助理正在重置,请稍后操作');
|
|
@@ -802,6 +954,7 @@ export function createGlobalVoiceRpcFeature(options = {}) {
|
|
|
802
954
|
return result;
|
|
803
955
|
}
|
|
804
956
|
switch (action) {
|
|
957
|
+
case 'status': return readStatus();
|
|
805
958
|
case 'lifecycle/read': return await lifecycleSnapshot();
|
|
806
959
|
case 'lifecycle/configure': return await configureAssistant(payload);
|
|
807
960
|
case 'lifecycle/reset': return await resetAssistant();
|
|
@@ -864,32 +1017,22 @@ export function createGlobalVoiceRpcFeature(options = {}) {
|
|
|
864
1017
|
}
|
|
865
1018
|
case 'debug': {
|
|
866
1019
|
// 查看面板只列元数据,不把“刷新视图”混同为“执行索引”。
|
|
867
|
-
|
|
868
|
-
const
|
|
869
|
-
const metadata = await buildAssistantSessionIndex({ sessions: source.sessions, scope: createAssistantScope(managed), archivedSessionIds: source.archivedSessionIds });
|
|
870
|
-
observeVersions(metadata.entries);
|
|
871
|
-
const history = journal.snapshot();
|
|
872
|
-
// 归档、空白状态或工作区成员关系变化后,旧正文不能继续冒充当前结果。
|
|
873
|
-
const matching = history.index !== undefined && sameManagedScope(history.index, managed) && sameIndexMembership(history.index, metadata);
|
|
874
|
-
if (history.index !== undefined && !matching) {
|
|
875
|
-
textChat.cancelActive();
|
|
876
|
-
updates.schedule(false);
|
|
877
|
-
}
|
|
878
|
-
const index = matching ? withIndexAnalysis(history.index, metadata.entries) : metadata;
|
|
1020
|
+
await background.read(asRecord(payload)?.refresh === true);
|
|
1021
|
+
const { cached, metadata, index, indexState, indexedAt } = readIndexView();
|
|
879
1022
|
const tasks = new Map((indexAnalysis.read()?.tasks ?? []).map((task) => [assistantSessionKey(task), task]));
|
|
880
1023
|
const summary = summarizeAssistantEntries(index.entries, index.scope, index.generation, index.unreadableCount, 0);
|
|
881
1024
|
const query = readOptionalService(context.services.dshContext, 'sessionQuery');
|
|
882
1025
|
const snapshot = {
|
|
883
|
-
capturedAt:
|
|
1026
|
+
capturedAt: cached.capturedAt,
|
|
884
1027
|
index,
|
|
885
1028
|
// 调试页不限制播报长度,复用摘要接口的范围状态和分组语义。
|
|
886
1029
|
summary: index.analysis?.state === 'completed' && index.analysis.result !== undefined ? { ...summary, speechText: sanitizeSpeechText(speakAssistantStructuredIndex(index.analysis.result)) } : summary,
|
|
887
|
-
workspaces:
|
|
1030
|
+
workspaces: cached.value.source.workspaces,
|
|
888
1031
|
modelId: readAssistantVoiceSettings(context.services).modelId ?? '',
|
|
889
|
-
warnings: source.warnings,
|
|
1032
|
+
warnings: cached.value.source.warnings,
|
|
890
1033
|
scopeSessions: metadata.entries.map((entry) => updates.stamp(entry, tasks.get(assistantSessionKey(entry)))),
|
|
891
|
-
indexState
|
|
892
|
-
indexedAt
|
|
1034
|
+
indexState,
|
|
1035
|
+
indexedAt,
|
|
893
1036
|
records: journal.snapshot().records,
|
|
894
1037
|
services: {
|
|
895
1038
|
workspaceList: typeof readOptionalService(context.services.dshContext, 'workspaceRegistry')?.list === 'function',
|
|
@@ -1210,23 +1353,25 @@ async function dispatchPrompt(services, request, signal = new AbortController().
|
|
|
1210
1353
|
}
|
|
1211
1354
|
throw new Error('DSH sessionController.prompt 不可用,无法派发任务');
|
|
1212
1355
|
}
|
|
1213
|
-
async function readAssistantSource(services, managedWorkspaceIds = [], waitingState) {
|
|
1356
|
+
async function readAssistantSource(services, managedWorkspaceIds = [], waitingState, signal) {
|
|
1357
|
+
signal?.throwIfAborted();
|
|
1214
1358
|
const ctx = services.dshContext;
|
|
1215
1359
|
const warnings = [];
|
|
1216
1360
|
const query = readOptionalService(ctx, 'sessionQuery');
|
|
1217
1361
|
const cache = assistantSourceCache(services);
|
|
1218
|
-
const
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
});
|
|
1222
|
-
warnings.push(...local.warnings);
|
|
1223
|
-
const localSessions = local.sessions;
|
|
1362
|
+
const localSessions = await readLocalAssistantSessions(services, warnings, signal);
|
|
1363
|
+
signal?.throwIfAborted();
|
|
1364
|
+
let failed = false;
|
|
1224
1365
|
const gatewayResult = services.assistantGateway === undefined || managedWorkspaceIds.length === 0
|
|
1225
1366
|
? undefined
|
|
1226
|
-
: await
|
|
1367
|
+
: await services.assistantGateway.list(managedWorkspaceIds, signal).catch((error) => {
|
|
1368
|
+
signal?.throwIfAborted();
|
|
1369
|
+
failed = true;
|
|
1227
1370
|
warnings.push(`远端 Host 状态读取失败:${sanitizeSpeechText(error instanceof Error ? error.message : String(error)).slice(0, 500)}`);
|
|
1228
1371
|
return undefined;
|
|
1229
1372
|
});
|
|
1373
|
+
signal?.throwIfAborted();
|
|
1374
|
+
warnings.push(...gatewayResult?.warnings ?? []);
|
|
1230
1375
|
const sessions = dedupeSessionRecords([
|
|
1231
1376
|
...localSessions,
|
|
1232
1377
|
...(gatewayResult?.sessions ?? []),
|
|
@@ -1315,7 +1460,7 @@ async function readAssistantSource(services, managedWorkspaceIds = [], waitingSt
|
|
|
1315
1460
|
// 也不能把远端会话误当成本地会话产生一次额外 I/O。
|
|
1316
1461
|
if (record.hostId !== hostId || !managed.has(record.workspaceId) || archivedSet.has(record.sessionId))
|
|
1317
1462
|
return record;
|
|
1318
|
-
const title = await cache.title(record.sessionId, JSON.stringify([record.
|
|
1463
|
+
const title = await cache.title(record.sessionId, JSON.stringify([record.title, record.titleEvents]), false, () => readSessionTitle(readTitle, record.sessionId, signal), signal);
|
|
1319
1464
|
return title === null ? record : { ...record, title };
|
|
1320
1465
|
}));
|
|
1321
1466
|
// workspaceRegistry 可能只暴露归档 ID,而 sessionQuery 不再返回归档记录。
|
|
@@ -1341,37 +1486,46 @@ async function readAssistantSource(services, managedWorkspaceIds = [], waitingSt
|
|
|
1341
1486
|
summary: null,
|
|
1342
1487
|
}];
|
|
1343
1488
|
}));
|
|
1489
|
+
signal?.throwIfAborted();
|
|
1490
|
+
const remoteWorkspaces = await services.assistantGateway?.workspaces?.(signal).catch((error) => { signal?.throwIfAborted(); return []; }) ?? [];
|
|
1491
|
+
signal?.throwIfAborted();
|
|
1344
1492
|
return {
|
|
1345
1493
|
sessions: [...hydratedRecords, ...archivedStubs],
|
|
1346
1494
|
archivedSessionIds: archived,
|
|
1347
1495
|
warnings,
|
|
1496
|
+
failed: failed || gatewayResult?.failed === true,
|
|
1497
|
+
workspaces: [...workspaces.map((workspace) => ({ workspaceId: workspace.id, name: workspace.name, path: workspace.path })), ...remoteWorkspaces],
|
|
1348
1498
|
...(gatewayResult?.volatile === true ? { volatile: true } : {}),
|
|
1349
1499
|
...((readSurface === undefined && gatewayResult?.readSummary === undefined) ? {} : {
|
|
1350
|
-
readSummary: async (session) => {
|
|
1500
|
+
readSummary: async (session, readSignal) => {
|
|
1501
|
+
readSignal?.throwIfAborted();
|
|
1351
1502
|
if (session.hostId === hostId && readSurface !== undefined)
|
|
1352
|
-
return readSurfaceSummary(readSurface, session.sessionId);
|
|
1503
|
+
return readSurfaceSummary(readSurface, session.sessionId, readSignal);
|
|
1353
1504
|
if (session.hostId !== hostId && gatewayResult?.readSummary !== undefined)
|
|
1354
|
-
return gatewayResult.readSummary(session);
|
|
1505
|
+
return gatewayResult.readSummary(session, readSignal);
|
|
1355
1506
|
return session.summary ?? null;
|
|
1356
1507
|
},
|
|
1357
1508
|
}),
|
|
1358
1509
|
...((gatewayResult?.readWaiting === undefined) ? {} : {
|
|
1359
|
-
readWaiting: async (session) => {
|
|
1510
|
+
readWaiting: async (session, readSignal) => {
|
|
1511
|
+
readSignal?.throwIfAborted();
|
|
1360
1512
|
if (session.hostId !== hostId)
|
|
1361
|
-
return gatewayResult.readWaiting(session);
|
|
1513
|
+
return gatewayResult.readWaiting(session, readSignal);
|
|
1362
1514
|
return session.waiting ?? null;
|
|
1363
1515
|
},
|
|
1364
1516
|
}),
|
|
1365
1517
|
};
|
|
1366
1518
|
}
|
|
1367
1519
|
/** 原生列表提供 blank/origin 投影;原始日志目录只能作为旧版本的能力回退。 */
|
|
1368
|
-
async function readLocalAssistantSessions(services, warnings) {
|
|
1520
|
+
async function readLocalAssistantSessions(services, warnings, signal) {
|
|
1521
|
+
signal?.throwIfAborted();
|
|
1369
1522
|
const controller = readOptionalService(services.dshContext, 'sessionController') ?? services.nativeSessions?.controller;
|
|
1370
1523
|
if (typeof controller?.list === 'function') {
|
|
1371
1524
|
try {
|
|
1372
|
-
return flattenSessionList(await controller.list({}));
|
|
1525
|
+
return flattenSessionList(await controller.list({}, signal));
|
|
1373
1526
|
}
|
|
1374
1527
|
catch {
|
|
1528
|
+
signal?.throwIfAborted();
|
|
1375
1529
|
// 列表失败或列表为空都不能改用全量历史,否则会重新纳入被侧栏隐藏的会话。
|
|
1376
1530
|
warnings.push('原生会话列表读取失败,暂不纳入本地会话;请刷新后重试。');
|
|
1377
1531
|
return [];
|
|
@@ -1379,12 +1533,14 @@ async function readLocalAssistantSessions(services, warnings) {
|
|
|
1379
1533
|
}
|
|
1380
1534
|
const query = readOptionalService(services.dshContext, 'sessionQuery');
|
|
1381
1535
|
if (typeof query?.listSessions === 'function')
|
|
1382
|
-
return flattenSessionList(await query.listSessions());
|
|
1383
|
-
return services.nativeSessions === undefined ? [] : flattenSessionList(await services.nativeSessions.listRemote());
|
|
1536
|
+
return flattenSessionList(await query.listSessions(signal));
|
|
1537
|
+
return services.nativeSessions === undefined ? [] : flattenSessionList(await services.nativeSessions.listRemote(signal));
|
|
1384
1538
|
}
|
|
1385
|
-
async function readSessionTitle(readTitle, sessionId) {
|
|
1539
|
+
async function readSessionTitle(readTitle, sessionId, signal) {
|
|
1386
1540
|
try {
|
|
1387
|
-
|
|
1541
|
+
signal?.throwIfAborted();
|
|
1542
|
+
const value = await readTitle(sessionId, signal);
|
|
1543
|
+
signal?.throwIfAborted();
|
|
1388
1544
|
if (typeof value === 'string' && value.trim() !== '')
|
|
1389
1545
|
return value.trim();
|
|
1390
1546
|
if (isRecord(value)) {
|
|
@@ -1403,12 +1559,15 @@ async function readSessionTitle(readTitle, sessionId) {
|
|
|
1403
1559
|
}
|
|
1404
1560
|
}
|
|
1405
1561
|
catch {
|
|
1562
|
+
signal?.throwIfAborted();
|
|
1406
1563
|
// 单个标题查询失败不阻断其余会话索引。
|
|
1407
1564
|
}
|
|
1408
1565
|
return null;
|
|
1409
1566
|
}
|
|
1410
|
-
async function readSurfaceSummary(readSurface, sessionId) {
|
|
1411
|
-
|
|
1567
|
+
async function readSurfaceSummary(readSurface, sessionId, signal) {
|
|
1568
|
+
signal?.throwIfAborted();
|
|
1569
|
+
const value = await readSurface(sessionId, signal);
|
|
1570
|
+
signal?.throwIfAborted();
|
|
1412
1571
|
if (typeof value === 'string')
|
|
1413
1572
|
return value.slice(0, 2000);
|
|
1414
1573
|
if (!isRecord(value))
|