@xopcai/xopc 0.0.242 → 0.0.244
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/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{activity-store-MU5XrVv8.js → activity-store-CAah-_8h.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-B_Wc0wuL.js → agent-avatar-dicebear-BhXGsupm.js} +1 -1
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-Blzn2H6t.js +1 -0
- package/dist/gateway/static/root/assets/agents-Cmp-z8Y_.js +1 -0
- package/dist/gateway/static/root/assets/{api-DLyc8BQp.js → api-B2tKxbcz.js} +1 -1
- package/dist/gateway/static/root/assets/app-management-settings-panel-CezjAP1K.js +1 -0
- package/dist/gateway/static/root/assets/{appearance-settings-DB5gEQhN.js → appearance-settings-C-CfS05x.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-7Y13_bqZ.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-BOx0EJZs.js → archive-plugin-BmSx7wzY.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-CYnYIyLr.js → attachment-load-DI4CoIga.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-ChTflpmA.js → automations-page-D04Xceck.js} +1 -1
- package/dist/gateway/static/root/assets/automations-workspace-wEO1OWk0.js +6 -0
- package/dist/gateway/static/root/assets/{binary-plugins-BjbLfNwG.js → binary-plugins-BJQe8TRu.js} +1 -1
- package/dist/gateway/static/root/assets/block-editor-BSzGjJC6.js +185 -0
- package/dist/gateway/static/root/assets/browser-settings-page-DjAZ_LF2.js +8 -0
- package/dist/gateway/static/root/assets/{browser-workflow-inputs-DGQxD0vD.js → browser-workflow-inputs-CRnkgZHI.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-workflows-page-B9gfdd7L.js → browser-workflows-page-CwbxA3B7.js} +2 -2
- package/dist/gateway/static/root/assets/{button-CSEbl4zT.js → button-CtTvuElV.js} +1 -1
- package/dist/gateway/static/root/assets/capabilities-settings-panel-jt9bqUMK.js +7 -0
- package/dist/gateway/static/root/assets/channels-settings-Cz_TWY3a.js +1 -0
- package/dist/gateway/static/root/assets/{channels-status-swr-TkU42f-W.js → channels-status-swr-DuY4MGxe.js} +1 -1
- package/dist/gateway/static/root/assets/{chat-terminal-dock-CWMPcnoN.js → chat-terminal-dock-D3gj2D3U.js} +2 -2
- package/dist/gateway/static/root/assets/connectors-page-Shs5vbzx.js +2 -0
- package/dist/gateway/static/root/assets/{cron-expression-3h3rR0cf.js → cron-expression-DgWHw0jX.js} +1 -1
- package/dist/gateway/static/root/assets/{date-picker-Bz1sLBEx.js → date-picker-CKg-RPbs.js} +1 -1
- package/dist/gateway/static/root/assets/{dependency-picker-p9DWR8uU.js → dependency-picker-CVYkw-NN.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-D1TDB_gR.js → desktop-pet-Bf46oXTY.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-DWPZpoB7.js → desktop-pet-settings-BJO_klc7.js} +1 -1
- package/dist/gateway/static/root/assets/dist-CpzYSoz7.js +1 -0
- package/dist/gateway/static/root/assets/{dist-DaxPZj9e.js → dist-DBS3OB8K.js} +1 -1
- package/dist/gateway/static/root/assets/dist-DLmwHyAh.js +1 -0
- package/dist/gateway/static/root/assets/es2015-BvLh9GaE.js +41 -0
- package/dist/gateway/static/root/assets/{extension-debug-page-BrRbK2rJ.js → extension-debug-page-T2PmFFOW.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-CD65czfS.js → extension-page-2wAE2RCe.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-BRDDKhpi.js → extension-settings-page-Y9ZiCJ21.js} +1 -1
- package/dist/gateway/static/root/assets/{files-DQjhZjr2.js → files-D6vf3S30.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-api-CjbBsr5M.js → gateway-config-api-DaYY1Gkn.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-swr-HT7sLeO9.js → gateway-config-swr-BC3pgb_P.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-settings-BQjmfYD4.js → gateway-settings-eO3IzW_J.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-startup-retry-iBCtaAuT.js → gateway-startup-retry-uMcSfLru.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-settings-BzZxLgrw.js → heartbeat-settings-BAgrkyHc.js} +1 -1
- package/dist/gateway/static/root/assets/home-page-GTjKH7LK.js +1 -0
- package/dist/gateway/static/root/assets/{image-generation-api-dj9TNEn2.js → image-generation-api-D1qlQA-A.js} +1 -1
- package/dist/gateway/static/root/assets/index-DUz0O54y.js +71 -0
- package/dist/gateway/static/root/assets/index-Dbh5SXyV.css +2 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-BEnuEPD3.js → keyboard-shortcuts-settings-CWGqL6o5.js} +1 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-DKJ-rks0.js +2 -0
- package/dist/gateway/static/root/assets/{local-apps-page-DXQtppWq.js → local-apps-page-Bfidv29d.js} +1 -1
- package/dist/gateway/static/root/assets/{locale-store-DVzTJSj2.js → locale-store-CMZljTJx.js} +1 -1
- package/dist/gateway/static/root/assets/logs-page-DwAHrPbF.js +2 -0
- package/dist/gateway/static/root/assets/{management-settings-DIpBMWrA.js → management-settings-BG7j1I9f.js} +1 -1
- package/dist/gateway/static/root/assets/{markdown-split-BFHyGwNF.js → markdown-split-AnmmpLs6.js} +1 -1
- package/dist/gateway/static/root/assets/{markdown-view-DR3yVwtV.js → markdown-view-PPCLt7fu.js} +3 -3
- package/dist/gateway/static/root/assets/{media-plugins-BjjMxC5_.js → media-plugins-CGS-05cE.js} +1 -1
- package/dist/gateway/static/root/assets/messages-CTSgFlE4.js +3 -0
- package/dist/gateway/static/root/assets/mobile-pairing-wizard-DoKK5GfV.js +1 -0
- package/dist/gateway/static/root/assets/models-hub-cache-ZrbGRiGY.js +1 -0
- package/dist/gateway/static/root/assets/{notes-page-BbvtelJa.js → notes-page-Lr8rsFAR.js} +1 -1
- package/dist/gateway/static/root/assets/notes-workbench-ISWnKLxO.js +4 -0
- package/dist/gateway/static/root/assets/{oauth-api-BB-VYJ5j.js → oauth-api-4VeMbkTJ.js} +1 -1
- package/dist/gateway/static/root/assets/popover-select-C-Hj-nXR.js +1 -0
- package/dist/gateway/static/root/assets/{product-delivery-dUJgmBQZ.js → product-delivery-CV4pDOtG.js} +1 -1
- package/dist/gateway/static/root/assets/product-open-page-BU0HiZtv.js +1 -0
- package/dist/gateway/static/root/assets/project-detail-page-BZqr4yam.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-Dau8733A.js +1 -0
- package/dist/gateway/static/root/assets/{registry-api-DXsR8oGN.js → registry-api-CWOtPFrE.js} +1 -1
- package/dist/gateway/static/root/assets/remote-access-hub-DdChlvGP.js +1 -0
- package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-DoEfLjPB.js → runtime-tools-settings-panel-CmZTNv1W.js} +2 -2
- package/dist/gateway/static/root/assets/{schema-form-BsqpbBDv.js → schema-form-XlVPyiVQ.js} +1 -1
- package/dist/gateway/static/root/assets/{schemas-zIBW3wiV.js → schemas-BHS7bo06.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-C3kADsd4.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-CSYy6SUa.js +1 -0
- package/dist/gateway/static/root/assets/{settings-page-CE7ZcCTK.js → settings-page-DblUeM3V.js} +1 -1
- package/dist/gateway/static/root/assets/{setup-status-panel-CGlne9i0.js → setup-status-panel-bDfRfSnq.js} +1 -1
- package/dist/gateway/static/root/assets/{share-preview-page-Bn0qMX8V.js → share-preview-page-DBMWFMN-.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-Bu6lIStj.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-BNMc4l04.js +1 -0
- package/dist/gateway/static/root/assets/{skills-page-dRkeYh5P.js → skills-page-CSOseeQe.js} +1 -1
- package/dist/gateway/static/root/assets/skills-page.utils-CniRGhkJ.js +1 -0
- package/dist/gateway/static/root/assets/{system-settings-panel-C0ZCuCM4.js → system-settings-panel-D0GqNpKy.js} +1 -1
- package/dist/gateway/static/root/assets/task-detail-page-BRCq-nR7.js +1 -0
- package/dist/gateway/static/root/assets/{theme-store-Cth-eChE.js → theme-store-uxUwr10D.js} +1 -1
- package/dist/gateway/static/root/assets/tunnel-api-BtjS2nrM.js +1 -0
- package/dist/gateway/static/root/assets/{use-autosave-PSV89QuQ.js → use-autosave-TwuAycG8.js} +1 -1
- package/dist/gateway/static/root/assets/user-context-page-CbqPu8xZ.js +1 -0
- package/dist/gateway/static/root/assets/{voice-api-key-field-DXWdJ8cR.js → voice-api-key-field-CzwG5plu.js} +1 -1
- package/dist/gateway/static/root/assets/voice-config-api-MqyI6cgq.js +1 -0
- package/dist/gateway/static/root/assets/work-discovery-overlay-DS15FzQA.js +1 -0
- package/dist/gateway/static/root/assets/workflow-run-setup-panel-C_boCemi.js +3 -0
- package/dist/gateway/static/root/assets/workflows-page-CaI2ruyy.js +5 -0
- package/dist/gateway/static/root/index.html +21 -22
- package/dist/package.js +1 -1
- package/dist/packages/realtime-protocol/src/voice-audio.js +20 -0
- package/dist/packages/realtime-protocol/src/voice.js +208 -0
- package/dist/src/agent/agent-manager.js +4 -4
- package/dist/src/agent/background-review/run-background-review.js +1 -1
- package/dist/src/agent/embedded/model-runtime.js +1 -1
- package/dist/src/agent/embedded/run-for-session.d.ts +1 -0
- package/dist/src/agent/embedded/run-for-session.js +3 -2
- package/dist/src/agent/image/tool-model-config.js +1 -1
- package/dist/src/agent/inbound/turn-dispatcher.d.ts +1 -0
- package/dist/src/agent/inbound/turn-dispatcher.js +2 -1
- package/dist/src/agent/ipc/inbox.js +1 -1
- package/dist/src/agent/mcp/oauth/mcp-oauth-store.js +1 -1
- package/dist/src/agent/prompt/voice-presentation.d.ts +2 -0
- package/dist/src/agent/prompt/voice-presentation.js +12 -0
- package/dist/src/agent/service/direct-turn-helpers.d.ts +1 -0
- package/dist/src/agent/service/direct-turn-helpers.js +1 -0
- package/dist/src/agent/service/process-direct-streaming.d.ts +1 -0
- package/dist/src/agent/service/process-direct-streaming.js +2 -1
- package/dist/src/agent/service.js +2 -2
- package/dist/src/agent/session/session-config-service.js +4 -2
- package/dist/src/agent/session/session-inspector.js +1 -1
- package/dist/src/agent/skills/hub-lock.js +1 -1
- package/dist/src/agent/tasks/task-judge-service.js +3 -3
- package/dist/src/ai-assist/text-assist.js +1 -1
- package/dist/src/auth/credentials.js +2 -2
- package/dist/src/auth/profiles/store.js +1 -1
- package/dist/src/auth/sync-provider-auth.js +2 -2
- package/dist/src/browser/providers/browser-ext-install.js +1 -1
- package/dist/src/cli/commands/agent.js +2 -2
- package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
- package/dist/src/cli/commands/gateway/lifecycle.js +1 -1
- package/dist/src/cli/commands/models.js +2 -2
- package/dist/src/cli/commands/onboard.js +1 -1
- package/dist/src/cli/commands/profile.js +1 -1
- package/dist/src/cli/commands/tunnel.js +1 -1
- package/dist/src/cli/commands/update.js +1 -1
- package/dist/src/cli/extension-cli-register.js +1 -1
- package/dist/src/config/index.js +5 -5
- package/dist/src/config/loader.js +1 -1
- package/dist/src/config/models-json.d.ts +8 -8
- package/dist/src/config/models-json.js +1 -1
- package/dist/src/config/schema.d.ts +60 -0
- package/dist/src/config/schema.js +31 -1
- package/dist/src/extensions/lockfile.js +1 -1
- package/dist/src/files/file-service.d.ts +1 -0
- package/dist/src/files/file-service.js +4 -0
- package/dist/src/gateway/agents-admin.js +1 -1
- package/dist/src/gateway/chat-stream/thinking-delta-coalescer.js +8 -3
- package/dist/src/gateway/file-path-classifier.js +1 -1
- package/dist/src/gateway/heartbeat/service.js +1 -1
- package/dist/src/gateway/hono/lib/config-payload.d.ts +1 -11
- package/dist/src/gateway/hono/lib/config-payload.js +3 -3
- package/dist/src/gateway/hono/lib/safe-voice-config.d.ts +14 -0
- package/dist/src/gateway/hono/lib/safe-voice-config.js +29 -1
- package/dist/src/gateway/hono/routes/config-patch/misc.js +2 -2
- package/dist/src/gateway/hono/routes/connectors.js +23 -23
- package/dist/src/gateway/hono/routes/files.js +7 -0
- package/dist/src/gateway/hono/routes/lazy-fallback.js +18 -4
- package/dist/src/gateway/hono/routes/models.js +1 -1
- package/dist/src/gateway/hono/routes/session-input-handler.js +14 -0
- package/dist/src/gateway/hono/routes/sessions.js +3 -0
- package/dist/src/gateway/hono/routes/voice.js +139 -2
- package/dist/src/gateway/run-loop.js +1 -1
- package/dist/src/gateway/server.js +1 -0
- package/dist/src/gateway/service/agent-runner.d.ts +1 -0
- package/dist/src/gateway/service/agent-runner.js +1 -6
- package/dist/src/gateway/service/config-coordinator.js +1 -1
- package/dist/src/gateway/service/run-gateway-agent.d.ts +1 -0
- package/dist/src/gateway/service/run-gateway-agent.js +19 -1
- package/dist/src/gateway/service.d.ts +2 -0
- package/dist/src/gateway/service.js +78 -5
- package/dist/src/heartbeat/index.js +1 -1
- package/dist/src/media-understanding/types.d.ts +61 -0
- package/dist/src/providers/auth-runtime/resolve-auth.js +1 -1
- package/dist/src/providers/index.js +2 -2
- package/dist/src/providers/model-registry.js +1 -1
- package/dist/src/providers/register-runtime-providers.js +1 -1
- package/dist/src/session/client-history.js +12 -0
- package/dist/src/session/manager.d.ts +1 -0
- package/dist/src/session/session-context-for-llm.js +8 -0
- package/dist/src/session/store.d.ts +1 -0
- package/dist/src/session/store.js +1 -0
- package/dist/src/session/stored-rows-to-file-entries.js +5 -1
- package/dist/src/session/voice-transcript.d.ts +9 -0
- package/dist/src/session/voice-transcript.js +45 -0
- package/dist/src/share/hosted-session-share.js +1 -1
- package/dist/src/storage/sqlite/config-repository.js +9 -0
- package/dist/src/storage/sqlite/remote-context-repository.d.ts +3 -0
- package/dist/src/storage/sqlite/remote-context-repository.js +40 -0
- package/dist/src/storage/sqlite/session-repository.js +13 -0
- package/dist/src/storage/sqlite/user-context-repository.d.ts +3 -1
- package/dist/src/storage/sqlite/user-context-repository.js +50 -4
- package/dist/src/tui/tui-startup-resources.js +1 -1
- package/dist/src/tui/tui.js +3 -2
- package/dist/src/user-context/automatic-context.d.ts +17 -0
- package/dist/src/user-context/automatic-context.js +85 -0
- package/dist/src/user-context/changes.d.ts +7 -0
- package/dist/src/user-context/changes.js +28 -0
- package/dist/src/user-context/planner.js +1 -24
- package/dist/src/user-context/retriever.js +10 -11
- package/dist/src/user-context/selection-policy.d.ts +20 -0
- package/dist/src/user-context/selection-policy.js +33 -0
- package/dist/src/user-context/sources/index.js +2 -2
- package/dist/src/user-context/sources/repository.d.ts +2 -1
- package/dist/src/user-context/sources/repository.js +26 -5
- package/dist/src/voice/dashscope/streaming-stt-session.d.ts +2 -0
- package/dist/src/voice/dashscope/streaming-stt-session.js +249 -0
- package/dist/src/voice/dashscope/streaming-tts-stream.d.ts +12 -0
- package/dist/src/voice/dashscope/streaming-tts-stream.js +153 -0
- package/dist/src/voice/realtime/agentEngine.d.ts +10 -0
- package/dist/src/voice/realtime/agentEngine.js +403 -0
- package/dist/src/voice/realtime/audio-playback-window.d.ts +9 -0
- package/dist/src/voice/realtime/audio-playback-window.js +49 -0
- package/dist/src/voice/realtime/conversation-context.d.ts +11 -0
- package/dist/src/voice/realtime/conversation-context.js +76 -0
- package/dist/src/voice/realtime/engine.d.ts +13 -0
- package/dist/src/voice/realtime/engine.js +1 -0
- package/dist/src/voice/realtime/memory-context.d.ts +17 -0
- package/dist/src/voice/realtime/memory-context.js +100 -0
- package/dist/src/voice/realtime/omniEngine.d.ts +18 -0
- package/dist/src/voice/realtime/omniEngine.js +443 -0
- package/dist/src/voice/realtime/omniRoute.d.ts +10 -0
- package/dist/src/voice/realtime/omniRoute.js +31 -0
- package/dist/src/voice/realtime/runtime.d.ts +99 -0
- package/dist/src/voice/realtime/runtime.js +622 -0
- package/dist/src/voice/realtime/speakable-segmenter.d.ts +10 -0
- package/dist/src/voice/realtime/speakable-segmenter.js +87 -0
- package/dist/src/voice/stt/list-providers.js +2 -1
- package/dist/src/voice/stt/providers/alibaba-transcription.js +13 -1
- package/dist/src/voice/stt/providers/xopc-cloud-transcription.js +23 -0
- package/dist/src/voice/tts/factory.js +1 -0
- package/dist/src/voice/tts/openai-compatible-speech.js +3 -1
- package/dist/src/voice/tts/providers/alibaba-speech.d.ts +1 -5
- package/dist/src/voice/tts/providers/alibaba-speech.js +25 -8
- package/dist/src/voice/tts/providers/edge-speech.js +21 -22
- package/dist/src/voice/tts/providers/minimax-speech.js +6 -3
- package/dist/src/voice/tts/providers/xopc-cloud-speech.js +26 -1
- package/dist/src/voice/tts/speak-core.d.ts +6 -2
- package/dist/src/voice/tts/speak-core.js +46 -34
- package/dist/src/voice/tts/speech-provider-types.d.ts +1 -0
- package/dist/src/workflows/service/workflow-run-service.js +1 -1
- package/package.json +7 -7
- package/dist/gateway/static/root/assets/Combination-14nmIgxH.js +0 -41
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-Cf7U2aUi.js +0 -1
- package/dist/gateway/static/root/assets/agents-Ce9oOnwE.js +0 -1
- package/dist/gateway/static/root/assets/app-chrome-BeB4KgOf.js +0 -1
- package/dist/gateway/static/root/assets/app-management-settings-panel-CACOOS-a.js +0 -1
- package/dist/gateway/static/root/assets/apps-page-BaTFOCmR.js +0 -1
- package/dist/gateway/static/root/assets/automations-workspace-DK6EreCr.js +0 -6
- package/dist/gateway/static/root/assets/block-editor-DgAs5aJc.js +0 -184
- package/dist/gateway/static/root/assets/browser-settings-page-CHStw5UW.js +0 -8
- package/dist/gateway/static/root/assets/capabilities-settings-panel-JGH6Kfkr.js +0 -7
- package/dist/gateway/static/root/assets/channels-settings-YkUaaWkY.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-BI0FG3gA.js +0 -2
- package/dist/gateway/static/root/assets/dist-BPoKqzeH.js +0 -1
- package/dist/gateway/static/root/assets/dist-DqPZM2MH.js +0 -1
- package/dist/gateway/static/root/assets/home-page--9fKq0mL.js +0 -1
- package/dist/gateway/static/root/assets/index-D499B1qS.css +0 -2
- package/dist/gateway/static/root/assets/index-J3FsIvTs.js +0 -70
- package/dist/gateway/static/root/assets/local-app-workbench-page-FqG00zS1.js +0 -2
- package/dist/gateway/static/root/assets/logs-page-c6CfZ8PA.js +0 -2
- package/dist/gateway/static/root/assets/messages-_tYhRAHD.js +0 -3
- package/dist/gateway/static/root/assets/mobile-pairing-wizard-CHnXZTwb.js +0 -1
- package/dist/gateway/static/root/assets/models-hub-cache-DiXjKuuY.js +0 -1
- package/dist/gateway/static/root/assets/notes-workbench-DIR37b-K.js +0 -4
- package/dist/gateway/static/root/assets/popover-select-DrILF6mR.js +0 -1
- package/dist/gateway/static/root/assets/product-open-page-CRm9Q66h.js +0 -1
- package/dist/gateway/static/root/assets/project-detail-page-DHiLTiRW.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-God7NCcI.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-YpF0-mx2.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-CP8O1TxR.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-DzdbK3j9.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-B7NeVl4g.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-DDTmi4a7.js +0 -1
- package/dist/gateway/static/root/assets/skills-page.utils--q8p7MAn.js +0 -1
- package/dist/gateway/static/root/assets/task-detail-page-yiMzii2b.js +0 -1
- package/dist/gateway/static/root/assets/tunnel-api-CC3jOB4n.js +0 -1
- package/dist/gateway/static/root/assets/user-context-page-Vtwg7fQc.js +0 -1
- package/dist/gateway/static/root/assets/voice-config-api-BDoeXgww.js +0 -1
- package/dist/gateway/static/root/assets/work-discovery-overlay-BV_Jj5iD.js +0 -1
- package/dist/gateway/static/root/assets/workflow-run-setup-panel-DNHbWGPq.js +0 -3
- package/dist/gateway/static/root/assets/workflows-page-BkFIbMrz.js +0 -5
|
@@ -3,6 +3,16 @@ import { APP_LAZY_ROUTE_BUNDLES, AUTHENTICATED_LAZY_ROUTE_BUNDLES, findAuthentic
|
|
|
3
3
|
import { Hono } from "hono";
|
|
4
4
|
//#region src/gateway/hono/routes/lazy-fallback.ts
|
|
5
5
|
const log = createGatewayRouteLogger("LazyRoutes");
|
|
6
|
+
const FORWARDED_VARIABLES = Symbol("gateway.forwardedVariables");
|
|
7
|
+
function createSubApp() {
|
|
8
|
+
const sub = new Hono();
|
|
9
|
+
sub.use(async (c, next) => {
|
|
10
|
+
const variables = c.env?.[FORWARDED_VARIABLES];
|
|
11
|
+
for (const [key, value] of Object.entries(variables ?? {})) c.set(key, value);
|
|
12
|
+
await next();
|
|
13
|
+
});
|
|
14
|
+
return sub;
|
|
15
|
+
}
|
|
6
16
|
const authenticatedSubApps = /* @__PURE__ */ new Map();
|
|
7
17
|
const appSubApps = /* @__PURE__ */ new Map();
|
|
8
18
|
const authenticatedLoadPromises = /* @__PURE__ */ new Map();
|
|
@@ -28,7 +38,7 @@ async function ensureAuthenticatedLazyBundle(bundleId, deps) {
|
|
|
28
38
|
if (!bundle) return null;
|
|
29
39
|
pending = (async () => {
|
|
30
40
|
const mod = await bundle.load();
|
|
31
|
-
const sub =
|
|
41
|
+
const sub = createSubApp();
|
|
32
42
|
mod.register(sub, deps);
|
|
33
43
|
authenticatedSubApps.set(bundleId, sub);
|
|
34
44
|
authenticatedLoadPromises.delete(bundleId);
|
|
@@ -47,7 +57,7 @@ async function ensureAppLazyBundle(bundleId, params) {
|
|
|
47
57
|
if (!bundle) return null;
|
|
48
58
|
pending = (async () => {
|
|
49
59
|
const mod = await bundle.load();
|
|
50
|
-
const sub =
|
|
60
|
+
const sub = createSubApp();
|
|
51
61
|
if (mod.registerOnApp) mod.registerOnApp(sub, params.service);
|
|
52
62
|
appSubApps.set(bundleId, sub);
|
|
53
63
|
appLoadPromises.delete(bundleId);
|
|
@@ -58,10 +68,14 @@ async function ensureAppLazyBundle(bundleId, params) {
|
|
|
58
68
|
return pending;
|
|
59
69
|
}
|
|
60
70
|
async function forwardToSubApp(c, sub) {
|
|
71
|
+
const env = {
|
|
72
|
+
...c.env,
|
|
73
|
+
[FORWARDED_VARIABLES]: { ...c.var }
|
|
74
|
+
};
|
|
61
75
|
try {
|
|
62
|
-
return await sub.fetch(c.req.raw,
|
|
76
|
+
return await sub.fetch(c.req.raw, env, c.executionCtx);
|
|
63
77
|
} catch (error) {
|
|
64
|
-
if (error instanceof Error && error.message.includes("ExecutionContext")) return sub.fetch(c.req.raw,
|
|
78
|
+
if (error instanceof Error && error.message.includes("ExecutionContext")) return sub.fetch(c.req.raw, env);
|
|
65
79
|
logRouteError(log, c, error, "gateway.route.lazy_forward");
|
|
66
80
|
throw error;
|
|
67
81
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { init_resolve_config_value, testApiKeyResolution } from "../../../config/resolve-config-value.js";
|
|
2
1
|
import { resolveModelsJsonPath } from "../../../config/paths.js";
|
|
2
|
+
import { init_resolve_config_value, testApiKeyResolution } from "../../../config/resolve-config-value.js";
|
|
3
3
|
import { init_models_json, loadModelsJson, saveModelsJson, validateModelsConfig } from "../../../config/models-json.js";
|
|
4
4
|
import { getModelCatalogStore, init_model_catalog_store } from "../../../providers/model-catalog-store.js";
|
|
5
5
|
import { getModelRegistry } from "../../../providers/model-registry.js";
|
|
@@ -73,6 +73,13 @@ async function submitSessionInput(c, deps, sessionKey) {
|
|
|
73
73
|
}
|
|
74
74
|
}, 400);
|
|
75
75
|
return withModelConfigLock(sessionKey, async () => {
|
|
76
|
+
if (deps.service.voiceRealtime?.hasConversation(sessionKey)) return c.json({
|
|
77
|
+
ok: false,
|
|
78
|
+
error: {
|
|
79
|
+
code: "SESSION_BUSY",
|
|
80
|
+
message: "End the voice call before sending text"
|
|
81
|
+
}
|
|
82
|
+
}, 409);
|
|
76
83
|
const selection = body.configVersion !== void 0 ? await deps.service.sessions.getAgentConfig(sessionKey) : void 0;
|
|
77
84
|
if (selection) {
|
|
78
85
|
if (!Number.isSafeInteger(body.configVersion) || selection.configVersion !== body.configVersion || !selection.fixedModel) return c.json({
|
|
@@ -181,6 +188,13 @@ async function replaceLatestSessionTurn(c, deps, sessionKey, targetTurnId) {
|
|
|
181
188
|
}
|
|
182
189
|
}, 401);
|
|
183
190
|
return withModelConfigLock(sessionKey, async () => {
|
|
191
|
+
if (deps.service.voiceRealtime?.hasConversation(sessionKey)) return c.json({
|
|
192
|
+
ok: false,
|
|
193
|
+
error: {
|
|
194
|
+
code: "SESSION_BUSY",
|
|
195
|
+
message: "End the voice call before editing a turn"
|
|
196
|
+
}
|
|
197
|
+
}, 409);
|
|
184
198
|
const selection = body.configVersion !== void 0 ? await deps.service.sessions.getAgentConfig(sessionKey) : void 0;
|
|
185
199
|
if (selection) {
|
|
186
200
|
if (!Number.isSafeInteger(body.configVersion) || selection.configVersion !== body.configVersion || !selection.fixedModel) return c.json({
|
|
@@ -785,6 +785,7 @@ function registerSessionsRoutes(authenticated, deps) {
|
|
|
785
785
|
});
|
|
786
786
|
authenticated.delete("/api/sessions/:key/messages", async (c) => {
|
|
787
787
|
const key = c.req.param("key");
|
|
788
|
+
if (service.voiceRealtime?.hasConversation(key)) return c.json({ error: "End the voice call before editing its history" }, 409);
|
|
788
789
|
const body = await c.req.json().catch(() => ({}));
|
|
789
790
|
const userRoundIndex = typeof body.userRoundIndex === "number" ? body.userRoundIndex : void 0;
|
|
790
791
|
if (userRoundIndex === void 0 || !Number.isInteger(userRoundIndex) || userRoundIndex < 0) return c.json({ error: "userRoundIndex must be a non-negative integer" }, 400);
|
|
@@ -805,6 +806,7 @@ function registerSessionsRoutes(authenticated, deps) {
|
|
|
805
806
|
const blocked = ensureGatewayReadyForSessions(c, service, "sessions.reset");
|
|
806
807
|
if (blocked) return blocked;
|
|
807
808
|
const key = c.req.param("key");
|
|
809
|
+
if (service.voiceRealtime?.hasConversation(key)) return c.json({ error: "End the voice call before resetting the session" }, 409);
|
|
808
810
|
const result = await service.sessions.reset(key);
|
|
809
811
|
if (result.ok === false) {
|
|
810
812
|
const status = result.error === "Session not found" ? 404 : 400;
|
|
@@ -824,6 +826,7 @@ function registerSessionsRoutes(authenticated, deps) {
|
|
|
824
826
|
});
|
|
825
827
|
authenticated.delete("/api/sessions/:key", async (c) => {
|
|
826
828
|
const key = c.req.param("key");
|
|
829
|
+
if (service.voiceRealtime?.hasConversation(key)) return c.json({ error: "End the voice call before deleting the session" }, 409);
|
|
827
830
|
if (environments.get(key) && service.getActiveWebchatRunId(key)) return c.json({
|
|
828
831
|
ok: false,
|
|
829
832
|
error: "Stop the active session run before deleting its environment"
|
|
@@ -2,7 +2,7 @@ import { getDefaultModelSync, init_providers, resolveModel } from "../../../prov
|
|
|
2
2
|
import { completeWithResolvedCredentials } from "../../../providers/model-call.js";
|
|
3
3
|
import { resolveTtsProviderConfigSlice } from "../../../voice/tts/config-slice.js";
|
|
4
4
|
import { isTTSAvailable, resolveSpeechProvider } from "../../../voice/tts/factory.js";
|
|
5
|
-
import { speak } from "../../../voice/tts/speak-core.js";
|
|
5
|
+
import { speak, speakStream } from "../../../voice/tts/speak-core.js";
|
|
6
6
|
import { mergeTtsConfigFromAppConfig } from "../../../voice/tts/merge-config.js";
|
|
7
7
|
import { getLocalVoiceRuntimeClient } from "../../../voice/local/runtime-client.js";
|
|
8
8
|
import { getAudioDecoderStatus } from "../../../voice/audio/normalize.js";
|
|
@@ -13,6 +13,11 @@ import { mergeSttConfigFromAppConfig } from "../../../voice/stt/config.js";
|
|
|
13
13
|
import "../../../voice/stt/index.js";
|
|
14
14
|
import { listSttProvidersForApi } from "../../../voice/stt/list-providers.js";
|
|
15
15
|
import "../../../voice/tts/index.js";
|
|
16
|
+
import { withModelConfigLock } from "../../../session/model-config-lock.js";
|
|
17
|
+
import { createVoiceSessionRequestSchema } from "../../../../packages/realtime-protocol/src/voice.js";
|
|
18
|
+
import { resolveOmniRoute } from "../../../voice/realtime/omniRoute.js";
|
|
19
|
+
import { VoiceSessionCreationError, resolveStreamingStt, resolveStreamingTts } from "../../../voice/realtime/runtime.js";
|
|
20
|
+
import { getGatewayPrincipal } from "../../security/gateway-principal.js";
|
|
16
21
|
import { createGatewayRouteLogger } from "../lib/route-logger.js";
|
|
17
22
|
import { listLocalVoiceModelStatuses, removeLocalVoiceModel, startLocalVoiceModelInstall } from "../../../voice/local/model-manager.js";
|
|
18
23
|
import { listTtsProvidersForApi } from "../../../voice/tts/list-providers.js";
|
|
@@ -107,6 +112,134 @@ async function refineTranscript(raw, config, signal) {
|
|
|
107
112
|
}
|
|
108
113
|
function registerVoiceRoutes(authenticated, deps) {
|
|
109
114
|
const { service, strictRateLimitMiddleware } = deps;
|
|
115
|
+
authenticated.get("/api/voice/realtime/status", async (c) => {
|
|
116
|
+
const config = service.currentConfig;
|
|
117
|
+
const stt = resolveStreamingStt(config);
|
|
118
|
+
const tts = resolveStreamingTts(config);
|
|
119
|
+
const omni = await resolveOmniRoute(config).catch(() => null);
|
|
120
|
+
const enabled = config.voice?.realtime?.enabled === true;
|
|
121
|
+
const availability = (configured) => ({
|
|
122
|
+
available: enabled && configured,
|
|
123
|
+
...!enabled ? { reasonCode: "VOICE_DISABLED" } : !configured ? { reasonCode: "PROVIDER_UNAVAILABLE" } : {}
|
|
124
|
+
});
|
|
125
|
+
return c.json({
|
|
126
|
+
ok: true,
|
|
127
|
+
payload: {
|
|
128
|
+
enabled,
|
|
129
|
+
capabilities: {
|
|
130
|
+
dictation: availability(Boolean(stt)),
|
|
131
|
+
agent: availability(Boolean(stt && tts)),
|
|
132
|
+
omni: availability(Boolean(omni)),
|
|
133
|
+
languages: ["zh", "en"],
|
|
134
|
+
bargeIn: config.voice?.realtime?.bargeIn ?? true
|
|
135
|
+
},
|
|
136
|
+
defaultEngine: config.voice?.realtime?.defaultEngine ?? "agent",
|
|
137
|
+
omni: omni?.route ?? null,
|
|
138
|
+
stt: stt?.route ?? null,
|
|
139
|
+
tts: tts ? {
|
|
140
|
+
...tts.route,
|
|
141
|
+
voice: tts.config.providers?.[tts.route.provider]?.voice ?? tts.provider.providerConfig.voice
|
|
142
|
+
} : null
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
authenticated.post("/api/voice/realtime/preview", strictRateLimitMiddleware, async (c) => {
|
|
147
|
+
const config = service.currentConfig;
|
|
148
|
+
const route = resolveStreamingTts(config);
|
|
149
|
+
if (!route) return c.json({
|
|
150
|
+
ok: false,
|
|
151
|
+
error: { message: "Realtime voice output is not configured" }
|
|
152
|
+
}, 503);
|
|
153
|
+
const controller = new AbortController();
|
|
154
|
+
const signal = AbortSignal.any([
|
|
155
|
+
c.req.raw.signal,
|
|
156
|
+
controller.signal,
|
|
157
|
+
AbortSignal.timeout(2e4)
|
|
158
|
+
]);
|
|
159
|
+
let result;
|
|
160
|
+
let reader;
|
|
161
|
+
try {
|
|
162
|
+
result = await speakStream(config.voice?.language === "en" ? "Hello, I am your assistant. You can talk to me naturally." : "你好,我是你的助手。现在可以和我自然对话了。", route.config, {
|
|
163
|
+
signal,
|
|
164
|
+
appConfig: config,
|
|
165
|
+
allowFallback: false,
|
|
166
|
+
parseDirectives: false
|
|
167
|
+
});
|
|
168
|
+
if (result.outputFormat !== "pcm") throw new Error("Realtime preview requires PCM audio");
|
|
169
|
+
reader = result.audioStream.getReader();
|
|
170
|
+
const chunks = [];
|
|
171
|
+
let size = 0;
|
|
172
|
+
while (true) {
|
|
173
|
+
signal.throwIfAborted();
|
|
174
|
+
const { value, done } = await reader.read();
|
|
175
|
+
if (done) break;
|
|
176
|
+
size += value.byteLength;
|
|
177
|
+
if (size > 96e4) throw new Error("Realtime preview audio exceeds the limit");
|
|
178
|
+
chunks.push(value);
|
|
179
|
+
}
|
|
180
|
+
if (size === 0 || size % 2 !== 0) throw new Error("Realtime preview returned invalid audio");
|
|
181
|
+
return c.json({
|
|
182
|
+
ok: true,
|
|
183
|
+
payload: {
|
|
184
|
+
audio: Buffer.concat(chunks).toString("base64"),
|
|
185
|
+
sampleRate: 24e3
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
} catch (error) {
|
|
189
|
+
log.warn({
|
|
190
|
+
err: error,
|
|
191
|
+
provider: route.route.provider
|
|
192
|
+
}, "Realtime voice preview failed");
|
|
193
|
+
return c.json({
|
|
194
|
+
ok: false,
|
|
195
|
+
error: { message: "Voice preview failed. Check the provider credentials and try again." }
|
|
196
|
+
}, 502);
|
|
197
|
+
} finally {
|
|
198
|
+
controller.abort();
|
|
199
|
+
await reader?.cancel().catch(() => void 0);
|
|
200
|
+
reader?.releaseLock();
|
|
201
|
+
await result?.release();
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
for (const action of ["preflight", "sessions"]) authenticated.post(`/api/voice/realtime/${action}`, strictRateLimitMiddleware, async (c) => {
|
|
205
|
+
const parsed = createVoiceSessionRequestSchema.safeParse(await c.req.json().catch(() => null));
|
|
206
|
+
if (!parsed.success) return c.json({
|
|
207
|
+
ok: false,
|
|
208
|
+
error: {
|
|
209
|
+
code: "INVALID_REQUEST",
|
|
210
|
+
message: "Invalid realtime voice session request"
|
|
211
|
+
}
|
|
212
|
+
}, 400);
|
|
213
|
+
try {
|
|
214
|
+
if (action === "preflight") {
|
|
215
|
+
await service.voiceRealtime.preflight(parsed.data);
|
|
216
|
+
return c.json({ ok: true });
|
|
217
|
+
}
|
|
218
|
+
const principal = getGatewayPrincipal(c);
|
|
219
|
+
const create = () => service.voiceRealtime.createSession(parsed.data, principal.principalId);
|
|
220
|
+
const payload = parsed.data.sessionKey ? await withModelConfigLock(parsed.data.sessionKey, create) : await create();
|
|
221
|
+
return c.json({
|
|
222
|
+
ok: true,
|
|
223
|
+
payload
|
|
224
|
+
});
|
|
225
|
+
} catch (error) {
|
|
226
|
+
const message = error instanceof Error ? error.message : "Realtime voice is unavailable";
|
|
227
|
+
if (error instanceof VoiceSessionCreationError) return c.json({
|
|
228
|
+
ok: false,
|
|
229
|
+
error: {
|
|
230
|
+
code: error.code,
|
|
231
|
+
message
|
|
232
|
+
}
|
|
233
|
+
}, error.status);
|
|
234
|
+
return c.json({
|
|
235
|
+
ok: false,
|
|
236
|
+
error: {
|
|
237
|
+
code: "PROVIDER_UNAVAILABLE",
|
|
238
|
+
message
|
|
239
|
+
}
|
|
240
|
+
}, 503);
|
|
241
|
+
}
|
|
242
|
+
});
|
|
110
243
|
authenticated.post("/api/voice/language", strictRateLimitMiddleware, async (c) => {
|
|
111
244
|
let body = {};
|
|
112
245
|
try {
|
|
@@ -153,7 +286,11 @@ function registerVoiceRoutes(authenticated, deps) {
|
|
|
153
286
|
error: { message: "provider and model are required" }
|
|
154
287
|
}, 400);
|
|
155
288
|
const config = service.currentConfig;
|
|
156
|
-
const baseConfig = mergeTtsConfigFromAppConfig(config.messages?.tts);
|
|
289
|
+
const baseConfig = c.req.query("purpose") === "realtime" ? resolveStreamingTts(config)?.config : mergeTtsConfigFromAppConfig(config.messages?.tts);
|
|
290
|
+
if (!baseConfig) return c.json({
|
|
291
|
+
ok: true,
|
|
292
|
+
payload: { voices: [] }
|
|
293
|
+
});
|
|
157
294
|
const resolved = resolveSpeechProvider(provider, {
|
|
158
295
|
...baseConfig,
|
|
159
296
|
provider,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { loadConfig } from "../config/loader.js";
|
|
2
|
-
import "../config/index.js";
|
|
3
2
|
import { isRestartEnabled } from "../config/commands.flags.js";
|
|
3
|
+
import "../config/index.js";
|
|
4
4
|
import { runBootstrapMigrationsSync } from "../migrations/runner.js";
|
|
5
5
|
import { restartGatewayProcessWithFreshPid } from "./respawn.js";
|
|
6
6
|
import { acquireGatewayLock } from "./lock.js";
|
|
@@ -68,6 +68,7 @@ var GatewayServer = class {
|
|
|
68
68
|
});
|
|
69
69
|
inner.on("upgrade", (req, socket, head) => {
|
|
70
70
|
try {
|
|
71
|
+
if (this.service.voiceRealtime.handleUpgrade(req, socket, head)) return;
|
|
71
72
|
if (this.service.realtime.handleUpgrade(req, socket, head)) return;
|
|
72
73
|
if (handleSiteShareUpgrade(this.service, req, socket, head)) return;
|
|
73
74
|
socket.destroy();
|
|
@@ -128,12 +128,7 @@ var GatewayAgentRunner = class {
|
|
|
128
128
|
completeRealtimeTopic: this.opts.completeRealtimeTopic
|
|
129
129
|
}, message, channel, chatId, origin, attachments, thinking, runOptions);
|
|
130
130
|
try {
|
|
131
|
-
|
|
132
|
-
while (!step.done) {
|
|
133
|
-
yield step.value;
|
|
134
|
-
step = await iter.next();
|
|
135
|
-
}
|
|
136
|
-
return step.value;
|
|
131
|
+
return yield* iter;
|
|
137
132
|
} finally {
|
|
138
133
|
if (trackedRunId) {
|
|
139
134
|
this.resolveRunCompletions.get(trackedRunId)?.();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createLogger } from "../../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../../utils/logger.js";
|
|
3
|
-
import { getModelRegistry } from "../../providers/model-registry.js";
|
|
4
3
|
import { loadConfig, saveConfig } from "../../config/loader.js";
|
|
4
|
+
import { getModelRegistry } from "../../providers/model-registry.js";
|
|
5
5
|
import { init_providers } from "../../providers/index.js";
|
|
6
6
|
import { disposeAllSessionMcpRuntimes } from "../../agent/mcp/bundle-mcp-runtime.js";
|
|
7
7
|
import { reloadImageGenerationProviders } from "../../agent/image/generation/provider-registry.js";
|
|
@@ -25,6 +25,7 @@ export declare function runGatewayAgent(deps: RunGatewayAgentDeps, message: stri
|
|
|
25
25
|
signal?: AbortSignal;
|
|
26
26
|
runId?: string;
|
|
27
27
|
sourceContexts?: AgentSourceContext[];
|
|
28
|
+
presentation?: 'voice';
|
|
28
29
|
}): AsyncGenerator<RunGatewayAgentYield, {
|
|
29
30
|
status: string;
|
|
30
31
|
summary: string;
|
|
@@ -131,7 +131,8 @@ async function* runGatewayAgent(deps, message, channel, chatId, origin, attachme
|
|
|
131
131
|
const eventStream = agentService.turnDispatcher.processDirectStreaming(stampedMessage, sessionKey, origin, prepared, thinking, {
|
|
132
132
|
signal: mergedSignal,
|
|
133
133
|
runId,
|
|
134
|
-
sourceContexts: runOptions?.sourceContexts
|
|
134
|
+
sourceContexts: runOptions?.sourceContexts,
|
|
135
|
+
presentation: runOptions?.presentation
|
|
135
136
|
});
|
|
136
137
|
const mappedEvents = (async function* () {
|
|
137
138
|
for await (const event of eventStream) yield* mapper.map(event);
|
|
@@ -150,6 +151,18 @@ async function* runGatewayAgent(deps, message, channel, chatId, origin, attachme
|
|
|
150
151
|
summary: mergedSignal.aborted ? "Interrupted" : "Message processed successfully"
|
|
151
152
|
};
|
|
152
153
|
} catch (error) {
|
|
154
|
+
if (mergedSignal.aborted) {
|
|
155
|
+
terminalStatus = "cancelled";
|
|
156
|
+
taskRunStatus = "cancelled";
|
|
157
|
+
taskRunSummary = "Interrupted";
|
|
158
|
+
yield* emitAndYield(mapper.end("cancelled", "Interrupted"));
|
|
159
|
+
completeRealtimeTopic(`run:${runId}`);
|
|
160
|
+
runTopicCompleted = true;
|
|
161
|
+
return {
|
|
162
|
+
status: "aborted",
|
|
163
|
+
summary: "Interrupted"
|
|
164
|
+
};
|
|
165
|
+
}
|
|
153
166
|
const em = error instanceof Error ? error.message : String(error);
|
|
154
167
|
log.error({
|
|
155
168
|
err: error,
|
|
@@ -173,6 +186,11 @@ async function* runGatewayAgent(deps, message, channel, chatId, origin, attachme
|
|
|
173
186
|
summary: streamError
|
|
174
187
|
};
|
|
175
188
|
} finally {
|
|
189
|
+
if (mergedSignal.aborted) {
|
|
190
|
+
terminalStatus = "cancelled";
|
|
191
|
+
taskRunStatus = "cancelled";
|
|
192
|
+
taskRunSummary = "Interrupted";
|
|
193
|
+
}
|
|
176
194
|
if (registeredActiveWebchatRun && activeWebchatRunBySession.get(sessionKey) === runId) {
|
|
177
195
|
activeWebchatRunBySession.delete(sessionKey);
|
|
178
196
|
publishRealtime("sessions", "run.completed", {
|
|
@@ -19,6 +19,7 @@ import { GatewaySessionsApi } from './service/sessions-api.js';
|
|
|
19
19
|
import { GatewayMarketplaceService } from './service/marketplace-service.js';
|
|
20
20
|
import { GatewayAgentRunner } from './service/agent-runner.js';
|
|
21
21
|
import { RealtimeRuntime } from '../realtime/runtime.js';
|
|
22
|
+
import { VoiceRealtimeRuntime } from '../voice/realtime/runtime.js';
|
|
22
23
|
import type { GatewayServiceConfig } from './service/types.js';
|
|
23
24
|
import { type GatewayReadinessSnapshot } from './startup-readiness.js';
|
|
24
25
|
import { type ConnectorLearningCoordinator } from '../connectors/learning-coordinator.js';
|
|
@@ -51,6 +52,7 @@ export declare class GatewayService {
|
|
|
51
52
|
private auth;
|
|
52
53
|
readonly endpointTools: EndpointToolRuntime;
|
|
53
54
|
readonly realtime: RealtimeRuntime;
|
|
55
|
+
readonly voiceRealtime: VoiceRealtimeRuntime;
|
|
54
56
|
getConfig(): Config;
|
|
55
57
|
getModelCatalogSync(): ModelCatalogSyncService;
|
|
56
58
|
get browserRecipes(): BrowserRecipeService;
|
|
@@ -6,17 +6,20 @@ import { getRuntimeLogStats } from "../utils/logger/stats.js";
|
|
|
6
6
|
import { createLogger } from "../utils/logger/index.js";
|
|
7
7
|
import { init_logger } from "../utils/logger.js";
|
|
8
8
|
import { closeXopcDatabase, openXopcDatabase } from "../storage/sqlite/connection.js";
|
|
9
|
+
import { notifyUserContextChange } from "../user-context/changes.js";
|
|
10
|
+
import { getSessionConfig } from "../storage/sqlite/config-repository.js";
|
|
9
11
|
import "../storage/sqlite/index.js";
|
|
10
12
|
import { getAgentDefaultModelRef, init_schema } from "../config/schema.js";
|
|
11
13
|
import { init_agent_scope, listAgentEntries, normalizeAgentId, resolveDefaultAgentId } from "../agent/agent-scope.js";
|
|
14
|
+
import { buildSessionKey, init_session_key, sanitizeSegment } from "../routing/session-key.js";
|
|
15
|
+
import { getDefaultAgentId, init_resolve_route } from "../routing/resolve-route.js";
|
|
16
|
+
import { resolveEffectiveAgentProfileForSession } from "../config/agent-profile.js";
|
|
12
17
|
import { init_paths, resolveAgentDir, resolveConfigPath, resolveExtensionsDir } from "../config/paths.js";
|
|
13
|
-
import { prewarmModelRegistry } from "../providers/model-registry.js";
|
|
14
18
|
import { areExtensionsGloballyDisabled } from "../extensions/discover-extensions.js";
|
|
15
19
|
import { buildExtensionMetadataSnapshot } from "../extensions/extension-metadata-snapshot.js";
|
|
16
20
|
import { buildChannelCatalogForConfig, buildChannelCatalogFromSnapshot, init_channel_catalog_service } from "../channels/catalog/channel-catalog-service.js";
|
|
17
21
|
import { loadConfig, saveConfig } from "../config/loader.js";
|
|
18
|
-
import {
|
|
19
|
-
import { getDefaultAgentId, init_resolve_route } from "../routing/resolve-route.js";
|
|
22
|
+
import { prewarmModelRegistry } from "../providers/model-registry.js";
|
|
20
23
|
import { init_providers, providers_exports } from "../providers/index.js";
|
|
21
24
|
import { TaskRepository } from "../tasks/task-repository.js";
|
|
22
25
|
import { TaskConversationRepository } from "../tasks/task-conversation-repository.js";
|
|
@@ -56,18 +59,20 @@ import "../knowledge/index.js";
|
|
|
56
59
|
import { startConnectorLearningCoordinator } from "../connectors/learning-coordinator.js";
|
|
57
60
|
import { ConnectedSourceChangePublisher } from "../connectors/source-change-publisher.js";
|
|
58
61
|
import { startConnectorSupervisor } from "../connectors/supervisor.js";
|
|
62
|
+
import { EndpointToolRuntime } from "../endpoint-tools/runtime.js";
|
|
63
|
+
import "../endpoint-tools/index.js";
|
|
59
64
|
import { DiscussionService } from "../discussions/service.js";
|
|
60
65
|
import { DiscussionOrganizer } from "../discussions/organizer.js";
|
|
61
66
|
import { DiscussionLiveWorker } from "../discussions/live-worker.js";
|
|
62
67
|
import { DiscussionOrganizerWorker } from "../discussions/organizer-worker.js";
|
|
63
68
|
import { DiscussionSealer } from "../discussions/sealer.js";
|
|
64
69
|
import "../discussions/index.js";
|
|
65
|
-
import { EndpointToolRuntime } from "../endpoint-tools/runtime.js";
|
|
66
|
-
import "../endpoint-tools/index.js";
|
|
67
70
|
import { assertGatewayAuthConfigured, extractToken, resolveGatewayAuth, validateToken } from "./auth.js";
|
|
68
71
|
import { prepareAutomationAgentSession } from "./automation-agent-session.js";
|
|
69
72
|
import { stopTailscaleExposure } from "./tailscale-lifecycle.js";
|
|
70
73
|
import { reconcileDreamingAutomations } from "./dreaming-automation-reconciler.js";
|
|
74
|
+
import { buildVoiceMemoryContext } from "../voice/realtime/memory-context.js";
|
|
75
|
+
import { voiceMemoryBudget } from "../voice/realtime/conversation-context.js";
|
|
71
76
|
import { NotesStore } from "../notes/store.js";
|
|
72
77
|
import { buildNoteAgentContext } from "../notes/agent-context.js";
|
|
73
78
|
import { NotesService } from "../notes/service.js";
|
|
@@ -114,6 +119,7 @@ import { GatewayMarketplaceService } from "./service/marketplace-service.js";
|
|
|
114
119
|
import { GatewayConfigCoordinator } from "./service/config-coordinator.js";
|
|
115
120
|
import { GatewayAgentRunner } from "./service/agent-runner.js";
|
|
116
121
|
import { RealtimeRuntime } from "../realtime/runtime.js";
|
|
122
|
+
import { VoiceRealtimeRuntime } from "../voice/realtime/runtime.js";
|
|
117
123
|
import { GatewayReadiness } from "./startup-readiness.js";
|
|
118
124
|
import { createGatewayStartupTrace } from "./startup-trace.js";
|
|
119
125
|
import { applyAutomaticVoiceLanguage, inferProductLanguageFromEnvironment, initializeVoiceDefaults } from "../voice/language-profile.js";
|
|
@@ -158,6 +164,71 @@ var GatewayService = class {
|
|
|
158
164
|
auth;
|
|
159
165
|
endpointTools = new EndpointToolRuntime();
|
|
160
166
|
realtime = new RealtimeRuntime(this.endpointTools);
|
|
167
|
+
voiceRealtime = new VoiceRealtimeRuntime({
|
|
168
|
+
getConversationContext: async (sessionKey, expectedSessionId) => {
|
|
169
|
+
if ((await this.sessionIndex.getSessionMetadata(sessionKey))?.sessionId !== expectedSessionId) throw new Error("Conversation changed before voice connection");
|
|
170
|
+
const messages = await this.sessionIndex.loadMessages(sessionKey);
|
|
171
|
+
const after = await this.sessionIndex.getSessionMetadata(sessionKey);
|
|
172
|
+
if (after?.sessionId !== expectedSessionId) throw new Error("Conversation changed while loading voice context");
|
|
173
|
+
const profile = resolveEffectiveAgentProfileForSession(this.config, sessionKey);
|
|
174
|
+
const context = {
|
|
175
|
+
identity: [`Your name is ${profile.config.profile?.name ?? profile.agentId}.`, profile.customInstructions ?? ""].join("\n"),
|
|
176
|
+
history: messages
|
|
177
|
+
};
|
|
178
|
+
const memory = buildVoiceMemoryContext({
|
|
179
|
+
getConfig: () => this.config,
|
|
180
|
+
sessionKey,
|
|
181
|
+
workspaceId: getSessionConfig(sessionKey)?.workingDirectoryOverride ?? profile.resolvedWorkspacePath,
|
|
182
|
+
projectId: after?.projectId,
|
|
183
|
+
history: messages,
|
|
184
|
+
maxChars: voiceMemoryBudget(this.config.voice.realtime.omni.instructions, context)
|
|
185
|
+
});
|
|
186
|
+
return {
|
|
187
|
+
...context,
|
|
188
|
+
...memory ? { memory } : {}
|
|
189
|
+
};
|
|
190
|
+
},
|
|
191
|
+
getSessionIdentity: async (sessionKey) => (await this.sessionIndex.getSessionMetadata(sessionKey))?.sessionId,
|
|
192
|
+
recordOmniTranscript: async (sessionKey, callId, entry, expectedSessionId) => {
|
|
193
|
+
await this.sessionIndex.appendTranscriptCustomMessageEntry(sessionKey, {
|
|
194
|
+
expectedSessionId,
|
|
195
|
+
customType: "voice_omni_transcript",
|
|
196
|
+
content: entry.text,
|
|
197
|
+
display: true,
|
|
198
|
+
details: {
|
|
199
|
+
callId,
|
|
200
|
+
itemId: entry.itemId,
|
|
201
|
+
role: entry.role,
|
|
202
|
+
interrupted: entry.interrupted,
|
|
203
|
+
engine: "omni"
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
this.emit("session.transcript_updated", { key: sessionKey });
|
|
207
|
+
},
|
|
208
|
+
getConfig: () => this.config,
|
|
209
|
+
sessionExists: async (sessionKey) => Boolean(await this.sessionIndex.getSessionMetadata(sessionKey)),
|
|
210
|
+
sessionBusy: (sessionKey) => Boolean(this.agentRunner.getActiveRunId(sessionKey)) || this.agentRunner.inputs.snapshot(sessionKey).inputs.some((input) => input.status === "queued"),
|
|
211
|
+
recordInterruption: (entry) => this.sessionIndex.appendTranscriptContextEntry(entry.sessionKey, {
|
|
212
|
+
text: "Voice response was interrupted before playback completed.",
|
|
213
|
+
data: {
|
|
214
|
+
type: "voice_response_interrupted",
|
|
215
|
+
responseId: entry.responseId,
|
|
216
|
+
reason: entry.reason,
|
|
217
|
+
generatedCharacters: entry.generatedCharacters,
|
|
218
|
+
interruptedDuring: entry.interruptedDuring
|
|
219
|
+
}
|
|
220
|
+
}),
|
|
221
|
+
runAgent: (text, sessionKey, signal) => {
|
|
222
|
+
if (this.agentRunner.hasActiveRun(sessionKey)) throw new Error("Conversation session already has an active response");
|
|
223
|
+
return this.agentRunner.runAgent(text, "webchat", sessionKey, {
|
|
224
|
+
type: "channel",
|
|
225
|
+
channel: "webchat"
|
|
226
|
+
}, void 0, void 0, {
|
|
227
|
+
signal,
|
|
228
|
+
presentation: "voice"
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
});
|
|
161
232
|
getConfig() {
|
|
162
233
|
return this.config;
|
|
163
234
|
}
|
|
@@ -1097,6 +1168,7 @@ var GatewayService = class {
|
|
|
1097
1168
|
this.endpointTools.close();
|
|
1098
1169
|
await this.sideChats.disposeAll();
|
|
1099
1170
|
this.realtime.close();
|
|
1171
|
+
this.voiceRealtime.close();
|
|
1100
1172
|
await this.proactiveWorker.stop();
|
|
1101
1173
|
await this.discussionWorker.stop();
|
|
1102
1174
|
await this.discussionSealer.stop();
|
|
@@ -1543,6 +1615,7 @@ var GatewayService = class {
|
|
|
1543
1615
|
});
|
|
1544
1616
|
}
|
|
1545
1617
|
emit(type, payload) {
|
|
1618
|
+
if (type === "config.reload") notifyUserContextChange({ kind: "policy" });
|
|
1546
1619
|
this.realtime.broker.publish("gateway", type, payload);
|
|
1547
1620
|
this.createNotificationService().handleGatewayEvent(type, payload);
|
|
1548
1621
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DEFAULT_ACK_MAX_CHARS, HEARTBEAT_OK, NO_REPLY, shouldSilence, stripHeartbeatToken } from "./tokens.js";
|
|
2
|
+
import { appendCronEventLines } from "./event-prompt.js";
|
|
2
3
|
import { isWithinActiveHours } from "./active-hours.js";
|
|
3
4
|
import { isHeartbeatContentEmpty } from "./content-check.js";
|
|
4
|
-
import { appendCronEventLines } from "./event-prompt.js";
|
|
5
5
|
import { createHeartbeatWake } from "./wake.js";
|
|
6
6
|
export { DEFAULT_ACK_MAX_CHARS, HEARTBEAT_OK, NO_REPLY, appendCronEventLines, createHeartbeatWake, isHeartbeatContentEmpty, isWithinActiveHours, shouldSilence, stripHeartbeatToken };
|
|
@@ -112,6 +112,65 @@ export interface AudioTranscriptionResult {
|
|
|
112
112
|
/** Audio duration in seconds, when reported. */
|
|
113
113
|
durationSeconds?: number;
|
|
114
114
|
}
|
|
115
|
+
export interface PcmAudioFormat {
|
|
116
|
+
encoding: 'pcm_s16le';
|
|
117
|
+
sampleRate: 16_000 | 24_000;
|
|
118
|
+
channels: 1;
|
|
119
|
+
}
|
|
120
|
+
export interface StreamingSttCapabilities {
|
|
121
|
+
inputSampleRates: readonly number[];
|
|
122
|
+
turnDetection: readonly 'server_vad'[];
|
|
123
|
+
defaultModel: string;
|
|
124
|
+
models: readonly string[];
|
|
125
|
+
}
|
|
126
|
+
export type StreamingSttEvent = {
|
|
127
|
+
type: 'ready';
|
|
128
|
+
} | {
|
|
129
|
+
type: 'speech_started';
|
|
130
|
+
utteranceId: string;
|
|
131
|
+
} | {
|
|
132
|
+
type: 'speech_stopped';
|
|
133
|
+
utteranceId: string;
|
|
134
|
+
} | {
|
|
135
|
+
type: 'transcript_delta';
|
|
136
|
+
utteranceId: string;
|
|
137
|
+
revision: number;
|
|
138
|
+
text: string;
|
|
139
|
+
} | {
|
|
140
|
+
type: 'transcript_final';
|
|
141
|
+
utteranceId: string;
|
|
142
|
+
revision: number;
|
|
143
|
+
text: string;
|
|
144
|
+
language?: string;
|
|
145
|
+
} | {
|
|
146
|
+
type: 'usage';
|
|
147
|
+
inputAudioMs: number;
|
|
148
|
+
} | {
|
|
149
|
+
type: 'error';
|
|
150
|
+
error: Error;
|
|
151
|
+
};
|
|
152
|
+
export interface StreamingSttOpenRequest {
|
|
153
|
+
model: string;
|
|
154
|
+
inputFormat: PcmAudioFormat;
|
|
155
|
+
apiKey?: string;
|
|
156
|
+
baseUrl?: string;
|
|
157
|
+
headers?: Record<string, string>;
|
|
158
|
+
language?: string;
|
|
159
|
+
prompt?: string;
|
|
160
|
+
turnDetection: {
|
|
161
|
+
mode: 'server_vad';
|
|
162
|
+
silenceDurationMs: number;
|
|
163
|
+
};
|
|
164
|
+
timeoutMs: number;
|
|
165
|
+
signal: AbortSignal;
|
|
166
|
+
onEvent: (event: StreamingSttEvent) => void;
|
|
167
|
+
}
|
|
168
|
+
export interface StreamingSttSession {
|
|
169
|
+
appendAudio(chunk: Uint8Array): void;
|
|
170
|
+
commit(): Promise<void>;
|
|
171
|
+
close(): Promise<void>;
|
|
172
|
+
abort(reason: string): void;
|
|
173
|
+
}
|
|
115
174
|
export interface ImageDescriptionRequest {
|
|
116
175
|
buffer: Buffer;
|
|
117
176
|
fileName: string;
|
|
@@ -170,6 +229,8 @@ export interface MediaUnderstandingProvider {
|
|
|
170
229
|
/** True when the provider can natively ingest PDF (no OCR pre-step needed). */
|
|
171
230
|
nativeDocumentInputs?: ReadonlyArray<'pdf'>;
|
|
172
231
|
transcribeAudio?: (req: AudioTranscriptionRequest) => Promise<AudioTranscriptionResult>;
|
|
232
|
+
streamingAudio?: StreamingSttCapabilities;
|
|
233
|
+
openAudioStream?: (req: StreamingSttOpenRequest) => Promise<StreamingSttSession>;
|
|
173
234
|
describeImage?: (req: ImageDescriptionRequest) => Promise<ImageDescriptionResult>;
|
|
174
235
|
describeVideo?: (req: VideoDescriptionRequest) => Promise<VideoDescriptionResult>;
|
|
175
236
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { getApiKeyFromEnv, init_env_keys } from "../env-keys.js";
|
|
2
1
|
import { init_sync_provider_auth, resolveProviderApiKeyForAgentSync } from "../../auth/sync-provider-auth.js";
|
|
2
|
+
import { getApiKeyFromEnv, init_env_keys } from "../env-keys.js";
|
|
3
3
|
import { getDefaultAuthProfileStore } from "./auth-profile-store.js";
|
|
4
4
|
//#region src/providers/auth-runtime/resolve-auth.ts
|
|
5
5
|
init_env_keys();
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { __esmMin, __exportAll } from "../../_virtual/_rolldown/runtime.js";
|
|
2
2
|
import { getAgentDefaultModelRef, init_schema } from "../config/schema.js";
|
|
3
|
+
import { getModelOAuthProviderIds, init_registry } from "../auth/oauth/registry.js";
|
|
4
|
+
import { hasProviderAuthOnDiskSync, init_sync_provider_auth } from "../auth/sync-provider-auth.js";
|
|
3
5
|
import { PROVIDER_ENV_MAP, getApiKeyFromEnv, init_env_keys } from "./env-keys.js";
|
|
4
6
|
import { init_model_ref, splitProviderModelRef } from "./model-ref.js";
|
|
5
7
|
import { ModelRegistry, getModelRegistry, init_model_registry, prewarmModelRegistry, resetModelRegistry } from "./model-registry.js";
|
|
6
|
-
import { getModelOAuthProviderIds, init_registry } from "../auth/oauth/registry.js";
|
|
7
8
|
import { CredentialResolver, hasCredentials, init_credentials } from "../auth/credentials.js";
|
|
8
|
-
import { hasProviderAuthOnDiskSync, init_sync_provider_auth } from "../auth/sync-provider-auth.js";
|
|
9
9
|
import { EXTENSION_PROVIDER_BASE_URL, init_constants } from "./constants.js";
|
|
10
10
|
import { applyOfficialModelMetadataCorrections, getSupplementalModels, init_model_supplements } from "./model-supplements.js";
|
|
11
11
|
import { getProviderRegistry, init_plugin_registry } from "./plugin-registry.js";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { __esmMin } from "../../_virtual/_rolldown/runtime.js";
|
|
2
2
|
import { createLogger } from "../utils/logger/index.js";
|
|
3
3
|
import { init_logger } from "../utils/logger.js";
|
|
4
|
-
import { init_resolve_config_value, resolveConfigValue, resolveHeaders } from "../config/resolve-config-value.js";
|
|
5
4
|
import { resolveModelsJsonPath } from "../config/paths.js";
|
|
5
|
+
import { init_resolve_config_value, resolveConfigValue, resolveHeaders } from "../config/resolve-config-value.js";
|
|
6
6
|
import { getDefaultModelValues, init_models_json, validateModelsConfig } from "../config/models-json.js";
|
|
7
7
|
import { getApiKeyFromEnv, init_env_keys } from "./env-keys.js";
|
|
8
8
|
import { getModelCatalogStore, init_model_catalog_store } from "./model-catalog-store.js";
|