@xopcai/xopc 0.0.389 → 0.0.390

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.
Files changed (302) hide show
  1. package/dist/browser-ext/manifest.json +1 -1
  2. package/dist/extensions/telegram/src/plugin.js +1 -1
  3. package/dist/extensions/telegram/xopc.extension.json +1 -1
  4. package/dist/gateway/static/root/assets/{activity-store-dvik6t7Z.js → activity-store-DGMAYkw8.js} +1 -1
  5. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-bWMd5TDC.js → agent-avatar-dicebear-B4AsZzJR.js} +1 -1
  6. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-9NUY1sO3.js +1 -0
  7. package/dist/gateway/static/root/assets/agent-plugin-dialog-CNc6ntzP.js +1 -0
  8. package/dist/gateway/static/root/assets/agents-QNY9Vkrf.js +77 -0
  9. package/dist/gateway/static/root/assets/{agents-admin-api-BlNGyXpm.js → agents-admin-api-DxdaiFWn.js} +1 -1
  10. package/dist/gateway/static/root/assets/app-management-settings-panel-DHRfLkYD.js +1 -0
  11. package/dist/gateway/static/root/assets/{appearance-settings-CUAdx44v.js → appearance-settings-DtKSapgb.js} +1 -1
  12. package/dist/gateway/static/root/assets/{apps-page-D5zDB6gp.js → apps-page-B9kuRt_z.js} +1 -1
  13. package/dist/gateway/static/root/assets/{archive-plugin-Du6dJNcl.js → archive-plugin-AgySTXp_.js} +1 -1
  14. package/dist/gateway/static/root/assets/{automations-page-BO8Ig5Z4.js → automations-page-D1o7ZtUW.js} +1 -1
  15. package/dist/gateway/static/root/assets/automations-workspace-BJenz0P1.js +6 -0
  16. package/dist/gateway/static/root/assets/{binary-plugins-D7VJjwnr.js → binary-plugins-A1AXOsO6.js} +1 -1
  17. package/dist/gateway/static/root/assets/{block-editor-CaJlWTAn.js → block-editor-DUNLkLKF.js} +3 -3
  18. package/dist/gateway/static/root/assets/{browser-automation-inputs-iyMBJmQX.js → browser-automation-inputs-BvUC6OiW.js} +1 -1
  19. package/dist/gateway/static/root/assets/browser-automations-page-Dq2LlVMh.js +3 -0
  20. package/dist/gateway/static/root/assets/browser-settings-page-BOZ-1g51.js +3 -0
  21. package/dist/gateway/static/root/assets/{capabilities-MCKRMZDK.js → capabilities-BkCutK0V.js} +1 -1
  22. package/dist/gateway/static/root/assets/{capabilities-CEH1AnXc.js → capabilities-D61uSJPy.js} +1 -1
  23. package/dist/gateway/static/root/assets/capabilities-page-BDP6gzlv.js +2 -0
  24. package/dist/gateway/static/root/assets/capabilities-settings-panel-D6PL3Mfl.js +8 -0
  25. package/dist/gateway/static/root/assets/{capability-header-actions-BIA0Lwt5.js → capability-header-actions-D9uGs4Pw.js} +1 -1
  26. package/dist/gateway/static/root/assets/channels-xb7n8rwF.js +1 -0
  27. package/dist/gateway/static/root/assets/chat-terminal-dock-Dgn09YDs.js +36 -0
  28. package/dist/gateway/static/root/assets/{computer-settings-page-DvY3zgyY.js → computer-settings-page-C66P4ifT.js} +1 -1
  29. package/dist/gateway/static/root/assets/{connector-service-page-St2-Fj3y.js → connector-service-page-Dp35XdYf.js} +1 -1
  30. package/dist/gateway/static/root/assets/connectors-page-BHcRxYib.js +1 -0
  31. package/dist/gateway/static/root/assets/{date-picker-C0-D80ny.js → date-picker-CddHY982.js} +1 -1
  32. package/dist/gateway/static/root/assets/{dependency-picker-CNd7mwMU.js → dependency-picker-Ob6BZTqv.js} +1 -1
  33. package/dist/gateway/static/root/assets/{desktop-pet-C-2wDANn.js → desktop-pet-dmwCV-I4.js} +1 -1
  34. package/dist/gateway/static/root/assets/{desktop-pet-settings-DyhxLrdJ.js → desktop-pet-settings-B-TBkZAZ.js} +1 -1
  35. package/dist/gateway/static/root/assets/device-pairing-wizard-SWHwRgG3.js +1 -0
  36. package/dist/gateway/static/root/assets/{directory-picker-path-field-CNivVIPT.js → directory-picker-path-field-6VZa4fT1.js} +1 -1
  37. package/dist/gateway/static/root/assets/{extension-debug-page-CGYO3JPw.js → extension-debug-page-C0_njMva.js} +1 -1
  38. package/dist/gateway/static/root/assets/{extension-page-Dc51ALAg.js → extension-page-BeBLMFmW.js} +1 -1
  39. package/dist/gateway/static/root/assets/{extension-provider-BXPILdlw.js → extension-provider-DWI0KAKT.js} +1 -1
  40. package/dist/gateway/static/root/assets/extension-settings-page-BiLUwoKx.js +1 -0
  41. package/dist/gateway/static/root/assets/{gateway-config-swr-Bc2MytsF.js → gateway-config-swr-CmYcOqhb.js} +1 -1
  42. package/dist/gateway/static/root/assets/{gateway-realtime-BFK-vlME.js → gateway-realtime-Ci1Jst5g.js} +1 -1
  43. package/dist/gateway/static/root/assets/gateway-realtime-store-BMUiUQMk.js +1 -0
  44. package/dist/gateway/static/root/assets/gateway-settings-CzWT_v09.js +1 -0
  45. package/dist/gateway/static/root/assets/{gateway-startup-retry-BDPMttPx.js → gateway-startup-retry-C-BG5M7H.js} +1 -1
  46. package/dist/gateway/static/root/assets/{highlighted-body-KQOG7T2V-DAlRGMge.js → highlighted-body-KQOG7T2V-CsA7lCVc.js} +1 -1
  47. package/dist/gateway/static/root/assets/home-page-BeXJfxsg.js +2 -0
  48. package/dist/gateway/static/root/assets/image-generation-api-B_DqCwtV.js +1 -0
  49. package/dist/gateway/static/root/assets/imports-page-oAvAF9QS.js +1 -0
  50. package/dist/gateway/static/root/assets/index-W9ls-0Yd.css +1 -0
  51. package/dist/gateway/static/root/assets/index-xTL-vb51.js +260 -0
  52. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-BYYC9Qmw.js → keyboard-shortcuts-settings--MjYe-Pb.js} +1 -1
  53. package/dist/gateway/static/root/assets/{local-app-workbench-page-BKZfn-MS.js → local-app-workbench-page-DL33dtd7.js} +1 -1
  54. package/dist/gateway/static/root/assets/{local-apps-page-BU8pUsVM.js → local-apps-page-DOa7mxjB.js} +1 -1
  55. package/dist/gateway/static/root/assets/{local-session-drafts-kFc_MAA9.js → local-session-drafts-DAtLkTPg.js} +1 -1
  56. package/dist/gateway/static/root/assets/{locale-store-Dr43FCty.js → locale-store-DMy9W6IG.js} +1 -1
  57. package/dist/gateway/static/root/assets/logs-page-C-GbTYsM.js +2 -0
  58. package/dist/gateway/static/root/assets/management-settings-C0TzuD3-.js +1 -0
  59. package/dist/gateway/static/root/assets/{markdown-view-CdKlPjJM.js → markdown-view-wyOHdXEg.js} +1 -1
  60. package/dist/gateway/static/root/assets/{media-plugins-DE9zt88i.js → media-plugins-Pb2zr_-L.js} +1 -1
  61. package/dist/gateway/static/root/assets/mermaid-MCJ5UELQ-BxyGGa4D.js +1 -0
  62. package/dist/gateway/static/root/assets/messages-O0BEUKnx.js +3 -0
  63. package/dist/gateway/static/root/assets/models-hub-cache-DdH1MODX.js +1 -0
  64. package/dist/gateway/static/root/assets/note-detail-panel-BFpEqskQ.js +5 -0
  65. package/dist/gateway/static/root/assets/{notes-api-BHouNL6-.js → notes-api-CYt2pGsm.js} +1 -1
  66. package/dist/gateway/static/root/assets/notes-page-h-qqFJ6Z.js +8 -0
  67. package/dist/gateway/static/root/assets/{page-context-capture-button-TQr8NnSc.js → page-context-capture-button-3uj5EcQC.js} +1 -1
  68. package/dist/gateway/static/root/assets/personal-page-BGyW6cdt.js +1 -0
  69. package/dist/gateway/static/root/assets/{product-open-page-BEl6syFp.js → product-open-page-hI13tPS1.js} +1 -1
  70. package/dist/gateway/static/root/assets/{product-preview-content-BxSHnbqz.js → product-preview-content-lT_in0-Q.js} +1 -1
  71. package/dist/gateway/static/root/assets/project-detail-page-Baj7fQ7N.js +1 -0
  72. package/dist/gateway/static/root/assets/projects-page-D7DyQFU3.js +1 -0
  73. package/dist/gateway/static/root/assets/{registry-api-BD5IgDOA.js → registry-api-CgQrCqL6.js} +1 -1
  74. package/dist/gateway/static/root/assets/remote-access-hub-DU_d93Tm.js +1 -0
  75. package/dist/gateway/static/root/assets/{runtime-tools-api-CjTRoQWT.js → runtime-tools-api-D12qVKeC.js} +1 -1
  76. package/dist/gateway/static/root/assets/runtime-tools-settings-panel-DOSPOfCU.js +1 -0
  77. package/dist/gateway/static/root/assets/scenes-page-swyUIF5A.js +2 -0
  78. package/dist/gateway/static/root/assets/{schema-form-ByG-R6N2.js → schema-form-CwOFgsyh.js} +1 -1
  79. package/dist/gateway/static/root/assets/{send-session-input-UAVStisp.js → send-session-input-nH8Cw0US.js} +1 -1
  80. package/dist/gateway/static/root/assets/{session-api-DvgEiNRS.js → session-api-B9HrwF-c.js} +1 -1
  81. package/dist/gateway/static/root/assets/{session-manager-BOb1tC_Z.js → session-manager-aXqXuqDX.js} +1 -1
  82. package/dist/gateway/static/root/assets/sessions-page-CI_PJmlX.js +1 -0
  83. package/dist/gateway/static/root/assets/settings-advanced-gate-DCVaeBLW.js +1 -0
  84. package/dist/gateway/static/root/assets/{settings-page-C1e9m23j.js → settings-page-BN70wE6R.js} +1 -1
  85. package/dist/gateway/static/root/assets/setup-status-panel-CHzcVRi-.js +1 -0
  86. package/dist/gateway/static/root/assets/{share-link-dialog-kE_6v5Dp.js → share-link-dialog-B1TDyhPt.js} +1 -1
  87. package/dist/gateway/static/root/assets/{share-preview-page-BT-_yR1h.js → share-preview-page-Br-eAZaP.js} +1 -1
  88. package/dist/gateway/static/root/assets/{shares-api-Dg_SqHQE.js → shares-api-Bl1ZBh5S.js} +1 -1
  89. package/dist/gateway/static/root/assets/shares-settings-jgCC_E4Y.js +1 -0
  90. package/dist/gateway/static/root/assets/{skill-api-BslUYMnX.js → skill-api-ClUw3SRC.js} +1 -1
  91. package/dist/gateway/static/root/assets/{skill-reload-api-BQ2rTOP1.js → skill-reload-api--1BfIPzb.js} +1 -1
  92. package/dist/gateway/static/root/assets/skills-page-C9oRZSuL.js +2 -0
  93. package/dist/gateway/static/root/assets/{system-settings-panel-GpbPfWwo.js → system-settings-panel-tWrqu7ai.js} +1 -1
  94. package/dist/gateway/static/root/assets/{task-detail-page-5B5ZVAu0.js → task-detail-page-BYRW7Rrr.js} +2 -2
  95. package/dist/gateway/static/root/assets/{task-expandable-content-DJrrEBB4.js → task-expandable-content-D2t4ahzR.js} +1 -1
  96. package/dist/gateway/static/root/assets/{theme-store-BKpYnggg.js → theme-store-BBLjE0fi.js} +1 -1
  97. package/dist/gateway/static/root/assets/{tracing-settings-page-D71w7dwV.js → tracing-settings-page-5ATxQH5c.js} +1 -1
  98. package/dist/gateway/static/root/assets/{tunnel-api-BV46CvS8.js → tunnel-api-CF1Qh4wU.js} +1 -1
  99. package/dist/gateway/static/root/assets/{usage-page-rMuwNpJi.js → usage-page-CuEHzXil.js} +1 -1
  100. package/dist/gateway/static/root/assets/{use-autosave-CzyqRffr.js → use-autosave-tY3keIbm.js} +1 -1
  101. package/dist/gateway/static/root/assets/{use-composer-attachments-Dviq-1f6.js → use-composer-attachments-CXsocZjt.js} +1 -1
  102. package/dist/gateway/static/root/assets/{use-file-preview-expanded-D5Kk7Hon.js → use-file-preview-expanded-CEsxnDnQ.js} +2 -2
  103. package/dist/gateway/static/root/assets/user-model-page-Dvt5TIZ6.js +2 -0
  104. package/dist/gateway/static/root/assets/{voice-api-key-field-DWtbmacd.js → voice-api-key-field-COTNLUU3.js} +1 -1
  105. package/dist/gateway/static/root/assets/{voice-config-api-DnIjZm_9.js → voice-config-api-DrxBjSja.js} +1 -1
  106. package/dist/gateway/static/root/assets/voice-transcribe-api-B47j0_xA.js +1 -0
  107. package/dist/gateway/static/root/assets/{work-discovery-overlay-ChEG71hz.js → work-discovery-overlay-PByMJrhV.js} +1 -1
  108. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-pdiRKLxP.js → workflow-run-setup-panel-CSUkMo63.js} +2 -2
  109. package/dist/gateway/static/root/assets/{workflows-page-D9LMxINt.js → workflows-page-BUDvFo3R.js} +3 -3
  110. package/dist/gateway/static/root/assets/{workspace-api-CZDvu7uA.js → workspace-api-Bmx1O449.js} +2 -2
  111. package/dist/gateway/static/root/assets/{xopc-cloud-account-card-CbUgg1SK.js → xopc-cloud-account-card-DVsAbvwP.js} +1 -1
  112. package/dist/gateway/static/root/index.html +28 -27
  113. package/dist/package.js +1 -1
  114. package/dist/packages/gateway-contract/src/discussions.js +3 -2
  115. package/dist/packages/gateway-contract/src/index.js +4 -0
  116. package/dist/packages/gateway-contract/src/provider-setup.js +6 -0
  117. package/dist/packages/gateway-contract/src/recording-outcome.js +6 -0
  118. package/dist/packages/image-providers/src/catalog.js +10 -0
  119. package/dist/packages/image-providers/src/execute.js +5 -1
  120. package/dist/packages/image-providers/src/validation.js +19 -1
  121. package/dist/src/agent/background-review/run-background-review.d.ts +0 -1
  122. package/dist/src/agent/background-review/run-background-review.js +10 -2
  123. package/dist/src/agent/embedded/run-for-session.js +26 -3
  124. package/dist/src/agent/embedded/run-turn.js +12 -0
  125. package/dist/src/agent/embedded/xopc-stream-bridge.js +3 -0
  126. package/dist/src/agent/image/generation/runtime.js +12 -14
  127. package/dist/src/agent/image/understanding/runtime.js +5 -0
  128. package/dist/src/agent/inbound/inbound-loop.d.ts +1 -15
  129. package/dist/src/agent/inbound/inbound-loop.js +5 -0
  130. package/dist/src/agent/mcp/connection-errors.d.ts +3 -0
  131. package/dist/src/agent/mcp/connection-errors.js +32 -0
  132. package/dist/src/agent/mcp/connection-setup.d.ts +2 -0
  133. package/dist/src/agent/mcp/connection-setup.js +38 -18
  134. package/dist/src/agent/memory/compaction.js +5 -1
  135. package/dist/src/agent/memory/idle-compaction-scheduler.js +3 -1
  136. package/dist/src/agent/models/manager.d.ts +1 -0
  137. package/dist/src/agent/models/manager.js +4 -2
  138. package/dist/src/agent/orchestration/agent-orchestrator.d.ts +1 -6
  139. package/dist/src/agent/orchestration/agent-orchestrator.js +5 -0
  140. package/dist/src/agent/service/process-direct-one-shot.js +5 -0
  141. package/dist/src/agent/service/process-direct-streaming.d.ts +1 -0
  142. package/dist/src/agent/service/process-direct-streaming.js +17 -1
  143. package/dist/src/agent/tools/image-generate-tool.js +5 -1
  144. package/dist/src/agent-config/resolver.js +5 -0
  145. package/dist/src/agent-config/schema.d.ts +26 -6
  146. package/dist/src/agent-config/schema.js +2 -0
  147. package/dist/src/ai-assist/text-assist.js +5 -16
  148. package/dist/src/automations/service/action-executor.js +3 -1
  149. package/dist/src/channels/index.js +1 -1
  150. package/dist/src/channels/manager.js +1 -1
  151. package/dist/src/cli/commands/channels.js +1 -1
  152. package/dist/src/cli/commands/connectors.js +1 -1
  153. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  154. package/dist/src/cli/commands/extension-marketplace.js +1 -1
  155. package/dist/src/cli/commands/models.js +1 -1
  156. package/dist/src/cli/commands/onboard.js +1 -1
  157. package/dist/src/config/agent-model-intents.js +4 -1
  158. package/dist/src/config/schema.d.ts +11 -5
  159. package/dist/src/config/schema.js +11 -3
  160. package/dist/src/discussions/analyzer.d.ts +2 -0
  161. package/dist/src/discussions/analyzer.js +38 -9
  162. package/dist/src/discussions/audio-clip.d.ts +3 -0
  163. package/dist/src/discussions/audio-clip.js +72 -0
  164. package/dist/src/discussions/live-worker.js +3 -1
  165. package/dist/src/discussions/long-review.d.ts +17 -0
  166. package/dist/src/discussions/long-review.js +278 -0
  167. package/dist/src/discussions/media-timeline.d.ts +21 -0
  168. package/dist/src/discussions/media-timeline.js +134 -0
  169. package/dist/src/discussions/organizer-worker.d.ts +4 -1
  170. package/dist/src/discussions/organizer-worker.js +17 -12
  171. package/dist/src/discussions/organizer.js +2 -0
  172. package/dist/src/discussions/processing.d.ts +43 -0
  173. package/dist/src/discussions/processing.js +125 -0
  174. package/dist/src/discussions/recording.js +202 -42
  175. package/dist/src/discussions/recordingJobs.js +2 -0
  176. package/dist/src/discussions/repository.js +4 -2
  177. package/dist/src/discussions/review.d.ts +8 -0
  178. package/dist/src/discussions/review.js +183 -0
  179. package/dist/src/discussions/sealer.d.ts +7 -1
  180. package/dist/src/discussions/sealer.js +163 -87
  181. package/dist/src/discussions/service.d.ts +7 -1
  182. package/dist/src/discussions/service.js +51 -15
  183. package/dist/src/discussions/types.d.ts +2 -1
  184. package/dist/src/extensions/sdk/index.js +1 -1
  185. package/dist/src/gateway/agent-builtin-tools.d.ts +1 -1
  186. package/dist/src/gateway/global-defaults-admin.d.ts +3 -1
  187. package/dist/src/gateway/global-defaults-admin.js +14 -2
  188. package/dist/src/gateway/hono/lib/config-payload.d.ts +11 -2
  189. package/dist/src/gateway/hono/lib/config-payload.js +2 -0
  190. package/dist/src/gateway/hono/lib/voice-settings-revisions.d.ts +5 -0
  191. package/dist/src/gateway/hono/lib/voice-settings-revisions.js +23 -0
  192. package/dist/src/gateway/hono/routes/config-patch/misc.js +8 -1
  193. package/dist/src/gateway/hono/routes/config.js +12 -0
  194. package/dist/src/gateway/hono/routes/discussions.js +63 -1
  195. package/dist/src/gateway/hono/routes/global-defaults.js +8 -1
  196. package/dist/src/gateway/hono/routes/models.js +12 -4
  197. package/dist/src/gateway/hono/routes/provider-setup.d.ts +3 -0
  198. package/dist/src/gateway/hono/routes/provider-setup.js +106 -0
  199. package/dist/src/gateway/hono/routes/status.js +2 -0
  200. package/dist/src/gateway/hono/routes/voice.js +23 -10
  201. package/dist/src/gateway/provider-model-setup.d.ts +4 -0
  202. package/dist/src/gateway/provider-model-setup.js +56 -0
  203. package/dist/src/gateway/service/config-coordinator.d.ts +2 -2
  204. package/dist/src/gateway/service.js +7 -7
  205. package/dist/src/home-intelligence/host.js +2 -2
  206. package/dist/src/media-shared/http/provider-http.d.ts +0 -6
  207. package/dist/src/media-shared/http/provider-http.js +5 -4
  208. package/dist/src/media-understanding/runner.d.ts +0 -28
  209. package/dist/src/media-understanding/runner.js +4 -0
  210. package/dist/src/platform/client.d.ts +1 -1
  211. package/dist/src/platform/contracts.d.ts +1 -1
  212. package/dist/src/providers/env-keys.js +3 -0
  213. package/dist/src/providers/extension-stream-bridge.js +3 -0
  214. package/dist/src/providers/index.js +15 -0
  215. package/dist/src/providers/model-call.d.ts +5 -2
  216. package/dist/src/providers/model-call.js +13 -2
  217. package/dist/src/providers/model-reference-auditor.js +1 -0
  218. package/dist/src/providers/model-response.js +1 -1
  219. package/dist/src/providers/model-usage.d.ts +15 -0
  220. package/dist/src/providers/model-usage.js +50 -0
  221. package/dist/src/providers/presentation.js +8 -0
  222. package/dist/src/providers/setup/engine.d.ts +37 -0
  223. package/dist/src/providers/setup/engine.js +177 -0
  224. package/dist/src/providers/setup/profiles.d.ts +4 -0
  225. package/dist/src/providers/setup/profiles.js +94 -0
  226. package/dist/src/providers/setup/voice.d.ts +23 -0
  227. package/dist/src/providers/setup/voice.js +234 -0
  228. package/dist/src/scenes/agentExecutor.d.ts +1 -0
  229. package/dist/src/scenes/agentExecutor.js +5 -0
  230. package/dist/src/storage/sqlite/migrations/253_discussion_processing_recovery.sql +20 -0
  231. package/dist/src/storage/sqlite/migrations/254_discussion_annotations.sql +17 -0
  232. package/dist/src/storage/sqlite/migrations/255_discussion_chapter_progress.sql +10 -0
  233. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  234. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  235. package/dist/src/storage/sqlite/schema.js +1 -1
  236. package/dist/src/usage/recorder.js +2 -1
  237. package/dist/src/usage/scenario-registry.js +128 -123
  238. package/dist/src/voice/dashscope/streaming-stt-session.js +3 -0
  239. package/dist/src/voice/dashscope/streaming-tts-stream.js +3 -0
  240. package/dist/src/voice/dictation.d.ts +12 -0
  241. package/dist/src/voice/dictation.js +22 -0
  242. package/dist/src/voice/metadata/builtin.js +54 -0
  243. package/dist/src/voice/platform-streams.js +3 -0
  244. package/dist/src/voice/realtime/omniEngine.js +3 -0
  245. package/dist/src/voice/realtime/omniRoute.js +3 -2
  246. package/dist/src/voice/realtime/runtime.js +4 -2
  247. package/dist/src/voice/stt/factory.js +9 -3
  248. package/dist/src/voice/stt/providers/bailian-plan-transcription.d.ts +2 -0
  249. package/dist/src/voice/stt/providers/bailian-plan-transcription.js +32 -0
  250. package/dist/src/voice/stt/providers/index.d.ts +1 -0
  251. package/dist/src/voice/stt/providers/index.js +2 -1
  252. package/dist/src/voice/token-plan.d.ts +8 -0
  253. package/dist/src/voice/token-plan.js +11 -0
  254. package/dist/src/voice/tts/factory.js +4 -1
  255. package/dist/src/voice/tts/providers/bailian-plan-speech.d.ts +2 -0
  256. package/dist/src/voice/tts/providers/bailian-plan-speech.js +84 -0
  257. package/dist/src/voice/tts/providers/index.d.ts +1 -0
  258. package/dist/src/voice/tts/providers/index.js +2 -1
  259. package/dist/src/voice/tts/speak-core.js +10 -1
  260. package/package.json +4 -4
  261. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-Ds0Ue2FB.js +0 -1
  262. package/dist/gateway/static/root/assets/agent-plugin-dialog-UunIxc1q.js +0 -1
  263. package/dist/gateway/static/root/assets/agents-BLRM4o-U.js +0 -77
  264. package/dist/gateway/static/root/assets/app-management-settings-panel-Dmy828Pe.js +0 -1
  265. package/dist/gateway/static/root/assets/automations-workspace-UcCneEs3.js +0 -6
  266. package/dist/gateway/static/root/assets/browser-automations-page-BjvQnYfO.js +0 -3
  267. package/dist/gateway/static/root/assets/browser-settings-page-D5ZghI28.js +0 -3
  268. package/dist/gateway/static/root/assets/capabilities-page-MC8qIrXo.js +0 -2
  269. package/dist/gateway/static/root/assets/capabilities-settings-panel-Blz3hEzp.js +0 -8
  270. package/dist/gateway/static/root/assets/channels-DSg_iCVC.js +0 -1
  271. package/dist/gateway/static/root/assets/chat-terminal-dock-C97SJEwd.js +0 -36
  272. package/dist/gateway/static/root/assets/connectors-page-DXk-GAsd.js +0 -1
  273. package/dist/gateway/static/root/assets/device-pairing-wizard-BeSuq__I.js +0 -1
  274. package/dist/gateway/static/root/assets/extension-settings-page-jYu6qpY2.js +0 -1
  275. package/dist/gateway/static/root/assets/fallback-models-CoyzvDo7.js +0 -1
  276. package/dist/gateway/static/root/assets/gateway-realtime-store-C3vH-Iup.js +0 -1
  277. package/dist/gateway/static/root/assets/gateway-settings-JlT1dlSj.js +0 -1
  278. package/dist/gateway/static/root/assets/home-page-DOVl8s-1.js +0 -2
  279. package/dist/gateway/static/root/assets/image-generation-api-BZBiYDmV.js +0 -1
  280. package/dist/gateway/static/root/assets/imports-page-DgdBTp_0.js +0 -1
  281. package/dist/gateway/static/root/assets/index-CmC8JkSM.js +0 -260
  282. package/dist/gateway/static/root/assets/index-Dgzc0oBu.css +0 -1
  283. package/dist/gateway/static/root/assets/logs-page-BSepiACn.js +0 -2
  284. package/dist/gateway/static/root/assets/management-settings-dE_ykPNY.js +0 -1
  285. package/dist/gateway/static/root/assets/mermaid-MCJ5UELQ-65SE6j-_.js +0 -1
  286. package/dist/gateway/static/root/assets/messages-DlTNQI92.js +0 -3
  287. package/dist/gateway/static/root/assets/models-hub-cache-C7FAsEe_.js +0 -1
  288. package/dist/gateway/static/root/assets/note-detail-panel-D9oqhdyk.js +0 -5
  289. package/dist/gateway/static/root/assets/notes-page-Bd4_7ph8.js +0 -8
  290. package/dist/gateway/static/root/assets/personal-page-BvWzq4Wp.js +0 -1
  291. package/dist/gateway/static/root/assets/project-detail-page-D-qkIXVT.js +0 -1
  292. package/dist/gateway/static/root/assets/projects-page-BQtw1Dfn.js +0 -1
  293. package/dist/gateway/static/root/assets/remote-access-hub-CYFNz0Jc.js +0 -1
  294. package/dist/gateway/static/root/assets/runtime-tools-settings-panel-Qq_NyYx_.js +0 -1
  295. package/dist/gateway/static/root/assets/scenes-page-hGr-ppYk.js +0 -2
  296. package/dist/gateway/static/root/assets/sessions-page-CpX1Rluw.js +0 -1
  297. package/dist/gateway/static/root/assets/settings-advanced-gate-D2s_MlxR.js +0 -1
  298. package/dist/gateway/static/root/assets/settings-loading-skeleton-BTqvr_Fw.js +0 -1
  299. package/dist/gateway/static/root/assets/setup-status-panel-BiHRYDHq.js +0 -1
  300. package/dist/gateway/static/root/assets/shares-settings-DfcAu08T.js +0 -1
  301. package/dist/gateway/static/root/assets/skills-page-CvKc5nBN.js +0 -2
  302. package/dist/gateway/static/root/assets/user-model-page-Dhqw3v_u.js +0 -2
@@ -14,6 +14,7 @@ import { buildChannelCatalogForConfig, buildChannelCatalogFromSnapshot, getChann
14
14
  import { resolveSessionConfigForWeb, resolveUpdateConfigForWeb } from "../../../config/web-patch.js";
15
15
  import { GENERIC_MASKED_SECRET, maskSecretLength } from "./mask-secret-length.js";
16
16
  import { safeToolsWebForGet } from "../../config-tools-web.js";
17
+ import { voiceSettingsRevisions } from "./voice-settings-revisions.js";
17
18
  import { buildSafeProvidersConfigForWeb } from "./safe-providers-config.js";
18
19
  import { maskRealtimeVoiceConfigForWeb, maskSttConfigForWeb, maskTtsConfigForWeb } from "./safe-voice-config.js";
19
20
  //#region src/gateway/hono/lib/config-payload.ts
@@ -155,6 +156,7 @@ async function buildSafeWebConfigPayload(service, options = {}) {
155
156
  transport: { tls: "broker_terminated" }
156
157
  },
157
158
  update: { ...resolveUpdateConfigForWeb(config) },
159
+ voiceSettingsRevisions: voiceSettingsRevisions(config),
158
160
  stt: maskSttConfigForWeb(config.tools?.media?.audio),
159
161
  tts: maskTtsConfigForWeb(config.messages?.tts),
160
162
  voice: maskRealtimeVoiceConfigForWeb(config.voice),
@@ -0,0 +1,5 @@
1
+ import type { Config } from '../../../config/schema.js';
2
+ export declare const VOICE_SETTING_SCOPES: readonly ["transcription", "speech", "conversation"];
3
+ export type VoiceSettingScope = typeof VOICE_SETTING_SCOPES[number];
4
+ /** Opaque per-capability versions; credentials never appear in the public snapshot. */
5
+ export declare function voiceSettingsRevisions(config: Config): Record<VoiceSettingScope, string>;
@@ -0,0 +1,23 @@
1
+ import { createHmac, randomBytes } from "node:crypto";
2
+ //#region src/gateway/hono/lib/voice-settings-revisions.ts
3
+ const revisionKey = randomBytes(32);
4
+ const VOICE_SETTING_SCOPES = [
5
+ "transcription",
6
+ "speech",
7
+ "conversation"
8
+ ];
9
+ /** Opaque per-capability versions; credentials never appear in the public snapshot. */
10
+ function voiceSettingsRevisions(config) {
11
+ const values = {
12
+ transcription: {
13
+ stt: config.tools?.media?.audio,
14
+ language: config.voice?.language,
15
+ languageMode: config.voice?.languageMode
16
+ },
17
+ speech: config.messages?.tts,
18
+ conversation: config.voice?.realtime
19
+ };
20
+ return Object.fromEntries(VOICE_SETTING_SCOPES.map((scope) => [scope, createHmac("sha256", revisionKey).update(JSON.stringify(values[scope]) ?? "null").digest("hex")]));
21
+ }
22
+ //#endregion
23
+ export { VOICE_SETTING_SCOPES, voiceSettingsRevisions };
@@ -216,7 +216,14 @@ async function applyMiscPatch(config, body) {
216
216
  config.messages.tts = mergeTtsConfigPatch(config.messages.tts, body.tts);
217
217
  }
218
218
  if (body.voice !== void 0) {
219
- const parsed = VoiceConfigSchema.safeParse(mergeRealtimeVoiceConfigPatch(config.voice, body.voice));
219
+ if (!body.voice || typeof body.voice !== "object" || Array.isArray(body.voice)) return patchError("voice must be an object");
220
+ if (body.voice.realtime !== void 0 && (!body.voice.realtime || typeof body.voice.realtime !== "object" || Array.isArray(body.voice.realtime))) return patchError("voice.realtime must be an object");
221
+ if (body.voicePatchMode !== void 0 && body.voicePatchMode !== "merge") return patchError("Invalid voice patch mode");
222
+ const voicePatch = body.voicePatchMode === "merge" ? {
223
+ ...config.voice,
224
+ ...body.voice
225
+ } : body.voice;
226
+ const parsed = VoiceConfigSchema.safeParse(mergeRealtimeVoiceConfigPatch(config.voice, voicePatch));
220
227
  if (!parsed.success) return patchError(parsed.error.issues.map((i) => i.message).join("; "));
221
228
  config.voice = parsed.data;
222
229
  }
@@ -1,5 +1,6 @@
1
1
  import { enumerateLanGatewayCandidates, init_host } from "../../host.js";
2
2
  import { getTunnelService } from "../../../tunnel/tunnel-service.js";
3
+ import { VOICE_SETTING_SCOPES, voiceSettingsRevisions } from "../lib/voice-settings-revisions.js";
3
4
  import { buildSafeWebConfigPayload } from "../lib/config-payload.js";
4
5
  import { withGatewayConfigWriteLock } from "../lib/config-write-lock.js";
5
6
  import { applyChannelsPatch } from "./config-patch/channels.js";
@@ -39,6 +40,17 @@ function registerConfigRoutes(authenticated, deps) {
39
40
  const body = await c.req.json();
40
41
  const expectedConfig = structuredClone(service.currentConfig);
41
42
  const config = structuredClone(expectedConfig);
43
+ if (body.expectedVoiceRevision !== void 0) {
44
+ const guard = body.expectedVoiceRevision;
45
+ if (!guard || typeof guard !== "object" || !VOICE_SETTING_SCOPES.includes(guard.capability) || typeof guard.revision !== "string" || !/^[a-f0-9]{64}$/.test(guard.revision)) return c.json({
46
+ ok: false,
47
+ error: "Invalid voice settings revision"
48
+ }, 400);
49
+ if (voiceSettingsRevisions(expectedConfig)[guard.capability] !== guard.revision) return c.json({
50
+ ok: false,
51
+ error: "Voice settings changed. Reload before saving to preserve the current model."
52
+ }, 409);
53
+ }
42
54
  applyChannelsPatch(config, body);
43
55
  const gatewayResult = applyGatewayPatch(config, body);
44
56
  if (gatewayResult.ok === false) return c.json({
@@ -79,10 +79,67 @@ function registerDiscussionRoutes(authenticated, deps) {
79
79
  const detail = await service.discussions.getByNoteId(c.req.param("noteId"));
80
80
  return detail ? c.json(detail) : c.json({ error: "Discussion not found" }, 404);
81
81
  });
82
+ authenticated.get("/api/discussions/:id/review", async (c) => {
83
+ try {
84
+ return c.json(await service.discussions.review(c.req.param("id"), {
85
+ query: c.req.query("q"),
86
+ offset: Number(c.req.query("offset") ?? 0),
87
+ limit: Number(c.req.query("limit") ?? 20),
88
+ version: c.req.query("version")
89
+ }));
90
+ } catch (error) {
91
+ const response = errorResponse(error);
92
+ if (response) return c.json(response.body, response.status);
93
+ throw error;
94
+ }
95
+ });
82
96
  authenticated.get("/api/discussions/:id", async (c) => {
83
97
  const detail = await service.discussions.get(c.req.param("id"));
84
98
  return detail ? c.json(detail) : c.json({ error: "Discussion not found" }, 404);
85
99
  });
100
+ authenticated.get("/api/discussions/:id/audio-clip", mediaRateLimitMiddleware, async (c) => {
101
+ try {
102
+ const bytes = await service.discussions.audioClip(c.req.param("id"), Number(c.req.query("startMs")), Number(c.req.query("endMs")), c.req.raw.signal);
103
+ c.header("Cache-Control", "no-store");
104
+ c.header("Content-Type", "audio/wav");
105
+ return c.body(new Uint8Array(bytes));
106
+ } catch (error) {
107
+ const response = errorResponse(error);
108
+ if (response) return c.json(response.body, response.status);
109
+ throw error;
110
+ }
111
+ });
112
+ authenticated.get("/api/discussions/:id/annotations", async (c) => {
113
+ try {
114
+ return c.json(await service.discussions.annotations(c.req.param("id")));
115
+ } catch (error) {
116
+ const response = errorResponse(error);
117
+ if (response) return c.json(response.body, response.status);
118
+ throw error;
119
+ }
120
+ });
121
+ authenticated.put("/api/discussions/:id/annotations/:annotationId", strictRateLimitMiddleware, async (c) => {
122
+ const body = await c.req.json().catch(() => ({}));
123
+ try {
124
+ return c.json(service.discussions.saveAnnotation(c.req.param("id"), {
125
+ ...body,
126
+ id: c.req.param("annotationId")
127
+ }));
128
+ } catch (error) {
129
+ const response = errorResponse(error);
130
+ if (response) return c.json(response.body, response.status);
131
+ throw error;
132
+ }
133
+ });
134
+ authenticated.get("/api/discussions/:id/evidence", async (c) => {
135
+ try {
136
+ return c.json(await service.discussions.evidence(c.req.param("id"), Number(c.req.query("revision")), (c.req.query("segments") ?? "").split(",").filter(Boolean).map(Number)));
137
+ } catch (error) {
138
+ const response = errorResponse(error);
139
+ if (response) return c.json(response.body, response.status);
140
+ throw error;
141
+ }
142
+ });
86
143
  authenticated.get("/api/discussions/:id/transcript", (c) => {
87
144
  const transcript = service.discussions.transcript(c.req.param("id"), c.req.query("revision") === void 0 ? void 0 : Number(c.req.query("revision")));
88
145
  return transcript ? c.json(transcript) : c.json({ error: "Discussion not found" }, 404);
@@ -243,6 +300,8 @@ function registerDiscussionRoutes(authenticated, deps) {
243
300
  chunkCount: Number(body.chunkCount),
244
301
  mimeType: typeof body.mimeType === "string" ? body.mimeType : "",
245
302
  fileName: typeof body.fileName === "string" ? body.fileName : "",
303
+ ...body.events !== void 0 ? { events: body.events } : {},
304
+ ...body.epochs !== void 0 ? { epochs: body.epochs } : {},
246
305
  ...body.containerMode === "independent_wav" ? { containerMode: "independent_wav" } : {}
247
306
  }), 202);
248
307
  } catch (error) {
@@ -252,8 +311,11 @@ function registerDiscussionRoutes(authenticated, deps) {
252
311
  }
253
312
  });
254
313
  authenticated.post("/api/discussions/:id/retry", strictRateLimitMiddleware, async (c) => {
314
+ const body = await c.req.json().catch(() => ({}));
315
+ if (!body || typeof body !== "object" || Array.isArray(body)) return c.json({ error: "Invalid retry request" }, 400);
316
+ if (body.mode !== void 0 && body.mode !== "resume" && body.mode !== "from_audio") return c.json({ error: "Invalid retry mode" }, 400);
255
317
  try {
256
- const detail = await service.discussions.retry(c.req.param("id"));
318
+ const detail = await service.discussions.retry(c.req.param("id"), body.mode === "from_audio" ? "from_audio" : "resume");
257
319
  return detail ? c.json(detail) : c.json({ error: "Discussion not found" }, 404);
258
320
  } catch (error) {
259
321
  const response = errorResponse(error);
@@ -6,8 +6,15 @@ init_agent_config();
6
6
  function parsePatchBody(raw) {
7
7
  if (raw === null || typeof raw !== "object" || Array.isArray(raw)) return { error: "body must be an object" };
8
8
  const body = raw;
9
+ if (body.scope !== void 0 && body.scope !== "models" && body.scope !== "agent") return { error: "scope must be models or agent" };
10
+ const expected = body.expectedModels === void 0 ? void 0 : AgentDefaultsSchema.shape.models.safeParse(body.expectedModels);
11
+ if (expected && !expected.success) return { error: "expectedModels is invalid" };
9
12
  const parsed = AgentDefaultsSchema.safeParse(body.defaults);
10
- return parsed.success ? { defaults: parsed.data } : { error: `defaults ${parsed.error.issues[0]?.message ?? "is invalid"}` };
13
+ return parsed.success ? {
14
+ defaults: parsed.data,
15
+ ...body.scope ? { scope: body.scope } : {},
16
+ ...expected?.success ? { expectedModels: expected.data } : {}
17
+ } : { error: `defaults ${parsed.error.issues[0]?.message ?? "is invalid"}` };
11
18
  }
12
19
  function isParseError(value) {
13
20
  return typeof value === "object" && value !== null && "error" in value && typeof value.error === "string";
@@ -1,3 +1,5 @@
1
+ import { getProviderSetupProfile, init_profiles } from "../../../providers/setup/profiles.js";
2
+ import { init_model_usage, withModelUsageOrigin } from "../../../providers/model-usage.js";
1
3
  import { resolveEffectiveAgentConfigForAgent } from "../../../config/agent-profile.js";
2
4
  import { init_resolve_config_value, testApiKeyResolution } from "../../../config/resolve-config-value.js";
3
5
  import { resolveModelsJsonPath } from "../../../config/paths.js";
@@ -20,11 +22,14 @@ import { applyImageGenerationCatalogUpdate, getAgentImageGenerationConfig, getDe
20
22
  import { discoverProviderModels, isProviderApiDiscoverable } from "../../../providers/model-discovery.js";
21
23
  import { getXopcCloudCatalogCoordinator } from "../../../providers/xopc-cloud-catalog-coordinator.js";
22
24
  import { respondStartupUnavailable } from "../lib/startup-unavailable.js";
23
- import { dismissXopcCloudOnboarding, getXopcCloudOnboardingStatus } from "../../xopc-cloud-onboarding.js";
24
25
  import { getDomesticProviderPreset, getDomesticProviderPresetIds } from "../../../providers/domestic-presets.js";
25
- import { auditModelReferences } from "../../../providers/model-reference-auditor.js";
26
26
  import { getOnboardingFeaturedProviders, getProviderHint, getRecommendedModelsForProvider, isRecommendedModel, sortModelsForPicker, sortProvidersForPicker } from "../../../providers/presentation.js";
27
+ import { dismissXopcCloudOnboarding, getXopcCloudOnboardingStatus } from "../../xopc-cloud-onboarding.js";
28
+ import { auditModelReferences } from "../../../providers/model-reference-auditor.js";
29
+ import { registerProviderSetupRoutes } from "./provider-setup.js";
27
30
  //#region src/gateway/hono/routes/models.ts
31
+ init_model_usage();
32
+ init_profiles();
28
33
  init_model_policy();
29
34
  init_models_json();
30
35
  init_resolve_config_value();
@@ -83,6 +88,7 @@ function mapPluginModel(providerId, model, available) {
83
88
  };
84
89
  }
85
90
  function registerModelsRoutes(authenticated, deps) {
91
+ registerProviderSetupRoutes(authenticated, deps);
86
92
  const { service, strictRateLimitMiddleware } = deps;
87
93
  const catalogSync = service.getModelCatalogSync();
88
94
  const xopcCloudAccount = new XopcCloudAccountService();
@@ -518,14 +524,14 @@ function registerModelsRoutes(authenticated, deps) {
518
524
  }, 400);
519
525
  const prompt = typeof body.prompt === "string" && body.prompt.trim() ? body.prompt.trim() : "A simple blue circle centered on a white background.";
520
526
  try {
521
- const result = await provider.generateImage({
527
+ const result = await withModelUsageOrigin("interactive", () => provider.generateImage({
522
528
  provider: providerId,
523
529
  model: modelId,
524
530
  prompt,
525
531
  count: 1,
526
532
  cfg: service.currentConfig,
527
533
  timeoutMs: 12e4
528
- });
534
+ }));
529
535
  return c.json({
530
536
  ok: true,
531
537
  payload: {
@@ -744,6 +750,7 @@ function registerModelsRoutes(authenticated, deps) {
744
750
  const registryModelCount = getAllModels().filter((m) => m.provider === provider).length;
745
751
  return {
746
752
  id: provider,
753
+ setupProfile: getProviderSetupProfile(provider, PROVIDER_META[provider]?.name ?? domesticPreset?.displayName ?? provider, PROVIDER_META[provider]?.supportsOAuth, resolveProviderApiBaseUrl(provider)),
747
754
  name: plugin?.name ?? domesticPreset?.displayName ?? PROVIDER_META[provider]?.name ?? provider,
748
755
  category: plugin ? "extension" : PROVIDER_META[provider]?.category || (domesticPreset ? "domestic" : "specialty"),
749
756
  supportsOAuth: plugin ? false : PROVIDER_META[provider]?.supportsOAuth ?? false,
@@ -766,6 +773,7 @@ function registerModelsRoutes(authenticated, deps) {
766
773
  const extensionId = resolveExtensionIdForProvider(service, plugin.id);
767
774
  meta.push({
768
775
  id: plugin.id,
776
+ setupProfile: getProviderSetupProfile(plugin.id, plugin.name),
769
777
  name: plugin.name,
770
778
  category: "extension",
771
779
  supportsOAuth: false,
@@ -0,0 +1,3 @@
1
+ import type { Hono } from 'hono';
2
+ import type { AuthenticatedRouteDeps } from './deps.js';
3
+ export declare function registerProviderSetupRoutes(app: Hono, deps: AuthenticatedRouteDeps): void;
@@ -0,0 +1,106 @@
1
+ import { listGlobalDefaults, prepareUpdateGlobalDefaults, updateGlobalDefaults } from "../../global-defaults-admin.js";
2
+ import { applySetupVoice } from "../../../providers/setup/voice.js";
3
+ import { loadProviderSetupSnapshot } from "../../provider-model-setup.js";
4
+ import { SetupConflictError, applyProviderSetup, previewProviderSetup } from "../../../providers/setup/engine.js";
5
+ import { withGatewayConfigWriteLock } from "../lib/config-write-lock.js";
6
+ import { isDeepStrictEqual } from "node:util";
7
+ import { z } from "zod";
8
+ //#region src/gateway/hono/routes/provider-setup.ts
9
+ const use = z.enum([
10
+ "chat",
11
+ "vision",
12
+ "image",
13
+ "background",
14
+ "speech",
15
+ "transcription",
16
+ "conversation"
17
+ ]);
18
+ const requestSchema = z.object({
19
+ mode: z.enum(["fill", "replace"]).optional(),
20
+ selected: z.array(use).max(7).optional(),
21
+ overrides: z.partialRecord(use, z.string().min(1).max(512)).optional(),
22
+ modelIds: z.array(z.string().min(1).max(512)).max(500).optional()
23
+ }).strict();
24
+ const applySchema = requestSchema.extend({ revision: z.string().regex(/^[a-f0-9]{64}$/) });
25
+ function registerProviderSetupRoutes(app, deps) {
26
+ app.get("/api/models/setup/:providerId", async (c) => {
27
+ try {
28
+ return c.json({
29
+ ok: true,
30
+ payload: previewProviderSetup(await loadProviderSetupSnapshot(c.req.param("providerId"), deps.service.currentConfig))
31
+ });
32
+ } catch (error) {
33
+ return c.json({
34
+ ok: false,
35
+ error: { message: error instanceof Error ? error.message : String(error) }
36
+ }, 400);
37
+ }
38
+ });
39
+ app.post("/api/models/setup/:providerId/preview", deps.strictRateLimitMiddleware, async (c) => {
40
+ const parsed = requestSchema.safeParse(await c.req.json().catch(() => null));
41
+ if (!parsed.success) return c.json({
42
+ ok: false,
43
+ error: { message: "Invalid setup preview request" }
44
+ }, 400);
45
+ try {
46
+ return c.json({
47
+ ok: true,
48
+ payload: previewProviderSetup(await loadProviderSetupSnapshot(c.req.param("providerId"), deps.service.currentConfig), parsed.data)
49
+ });
50
+ } catch (error) {
51
+ return c.json({
52
+ ok: false,
53
+ error: { message: error instanceof Error ? error.message : String(error) }
54
+ }, 400);
55
+ }
56
+ });
57
+ app.post("/api/models/setup/:providerId/apply", deps.strictRateLimitMiddleware, async (c) => withGatewayConfigWriteLock(deps.service, async () => {
58
+ const parsed = applySchema.safeParse(await c.req.json().catch(() => null));
59
+ if (!parsed.success) return c.json({
60
+ ok: false,
61
+ error: { message: "Invalid setup apply request" }
62
+ }, 400);
63
+ let voiceSaved = false;
64
+ try {
65
+ const expectedConfig = structuredClone(deps.service.currentConfig);
66
+ const snapshot = await loadProviderSetupSnapshot(c.req.param("providerId"), expectedConfig);
67
+ if (!isDeepStrictEqual(deps.service.currentConfig, expectedConfig)) throw new SetupConflictError("Configuration changed while preparing setup. Review and retry.");
68
+ const applied = applyProviderSetup(snapshot, parsed.data, parsed.data.revision);
69
+ const prepared = prepareUpdateGlobalDefaults({ defaults: applied.defaults });
70
+ if (prepared.ok === false) return c.json({
71
+ ok: false,
72
+ error: { message: prepared.error }
73
+ }, prepared.status ?? 400);
74
+ if (applied.voiceAssignments.length) {
75
+ const next = applySetupVoice(expectedConfig, applied.voiceAssignments);
76
+ const saved = await deps.service.saveConfig(next, expectedConfig);
77
+ if (!saved.saved) return c.json({
78
+ ok: false,
79
+ error: { message: `${saved.persisted ? "Voice settings persisted but runtime reload failed" : "Voice settings were not saved"}: ${saved.error ?? "Configuration write failed"}` }
80
+ }, saved.conflict ? 409 : 500);
81
+ voiceSaved = true;
82
+ if (!isDeepStrictEqual(listGlobalDefaults().defaults, snapshot.defaults)) return c.json({
83
+ ok: false,
84
+ error: { message: "Voice settings saved; model defaults changed concurrently. Review the refreshed configuration before applying model uses." }
85
+ }, 409);
86
+ }
87
+ const result = updateGlobalDefaults({ defaults: applied.defaults });
88
+ if (result.ok === false) return c.json({
89
+ ok: false,
90
+ error: { message: result.error }
91
+ }, result.status ?? 400);
92
+ if (result.data.changed) deps.service.refreshAgentCatalog();
93
+ return c.json({
94
+ ok: true,
95
+ payload: applied.preview
96
+ });
97
+ } catch (error) {
98
+ return c.json({
99
+ ok: false,
100
+ error: { message: (voiceSaved ? "Voice settings saved; model setup incomplete. " : "") + (error instanceof Error ? error.message : String(error)) }
101
+ }, error instanceof SetupConflictError ? 409 : 400);
102
+ }
103
+ }));
104
+ }
105
+ //#endregion
106
+ export { registerProviderSetupRoutes };
@@ -3,6 +3,7 @@ import { isSTTAvailable } from "../../../voice/stt/availability.js";
3
3
  import { mergeSttConfigFromAppConfig } from "../../../voice/stt/config.js";
4
4
  import "../../../voice/stt/index.js";
5
5
  import { getGatewayAgentEffectiveConfig } from "../../agents-admin.js";
6
+ import { resolveDictationRoute } from "../../../voice/dictation.js";
6
7
  import { createHash } from "node:crypto";
7
8
  //#region src/gateway/hono/routes/status.ts
8
9
  init_providers();
@@ -82,6 +83,7 @@ function buildStatusPayload(service) {
82
83
  sttAvailable: sttConfig ? isSTTAvailable(sttConfig) : false,
83
84
  sttEnabled: sttConfig?.enabled === true,
84
85
  sttProvider: sttConfig?.provider ?? null,
86
+ dictation: config ? resolveDictationRoute(config) : { mode: "unavailable" },
85
87
  refineAvailable: isRefineAvailable(config)
86
88
  }
87
89
  };
@@ -1,3 +1,4 @@
1
+ import { init_model_usage, withModelUsageOrigin } from "../../../providers/model-usage.js";
1
2
  import { voiceSelectionSchema } from "../../../../packages/realtime-protocol/src/voice-catalog.js";
2
3
  import { VOICE_TIMING_METRICS, createVoiceSessionRequestSchema, init_voice } from "../../../../packages/realtime-protocol/src/voice.js";
3
4
  import { getDefaultModelSync, init_providers, resolveModel } from "../../../providers/index.js";
@@ -5,6 +6,7 @@ import { completeWithResolvedCredentials } from "../../../providers/model-call.j
5
6
  import { isPersonalConversation } from "../../../personal-agent/repository.js";
6
7
  import { PlatformVoiceError } from "../../../voice/platform-streams.js";
7
8
  import { resolveSttProviderConfigSlice } from "../../../voice/stt/config-slice.js";
9
+ import { resolveSTTProviderChain } from "../../../voice/stt/factory.js";
8
10
  import { STTTranscriptionError, transcribe } from "../../../voice/stt/transcribe-core.js";
9
11
  import { isSTTAvailable } from "../../../voice/stt/availability.js";
10
12
  import { mergeSttConfigFromAppConfig } from "../../../voice/stt/config.js";
@@ -21,10 +23,11 @@ import { resolveOmniRoute } from "../../../voice/realtime/omniRoute.js";
21
23
  import { VoiceSessionCreationError, resolveStreamingStt, resolveStreamingTts } from "../../../voice/realtime/runtime.js";
22
24
  import { getGatewayPrincipal } from "../../security/gateway-principal.js";
23
25
  import { createGatewayRouteLogger } from "../lib/route-logger.js";
24
- import { selectPlatformVoice, voiceSettingsCatalog } from "../../../voice/platform-settings.js";
25
26
  import { listTtsProvidersForApi } from "../../../voice/tts/list-providers.js";
27
+ import { selectPlatformVoice, voiceSettingsCatalog } from "../../../voice/platform-settings.js";
26
28
  import { z } from "zod";
27
29
  //#region src/gateway/hono/routes/voice.ts
30
+ init_model_usage();
28
31
  init_voice();
29
32
  init_providers();
30
33
  const log = createGatewayRouteLogger("Voice");
@@ -104,7 +107,10 @@ async function refineTranscript(raw, config, signal) {
104
107
  maxTokens: Math.min(raw.length * 3, 4096),
105
108
  temperature: .2,
106
109
  signal: mergedSignal
107
- }, void 0, { operation: "voice.select" });
110
+ }, void 0, {
111
+ operation: "voice.select",
112
+ trigger: "user"
113
+ });
108
114
  let out = "";
109
115
  if (Array.isArray(result.content)) {
110
116
  for (const c of result.content) if (c && typeof c === "object" && c.type === "text") out += String(c.text || "");
@@ -246,12 +252,13 @@ function registerVoiceRoutes(authenticated, deps) {
246
252
  let result;
247
253
  let reader;
248
254
  try {
249
- result = await speakStream(config.voice?.language === "en" ? "Hello, I am your assistant. You can talk to me naturally." : "你好,我是你的助手。现在可以和我自然对话了。", previewConfig, {
255
+ const text = config.voice?.language === "en" ? "Hello, I am your assistant. You can talk to me naturally." : "你好,我是你的助手。现在可以和我自然对话了。";
256
+ result = await withModelUsageOrigin("interactive", () => speakStream(text, previewConfig, {
250
257
  signal,
251
258
  appConfig: config,
252
259
  allowFallback: false,
253
260
  parseDirectives: false
254
- });
261
+ }));
255
262
  if (result.outputFormat !== "pcm") throw new Error("Realtime preview requires PCM audio");
256
263
  reader = result.audioStream.getReader();
257
264
  const chunks = [];
@@ -551,12 +558,12 @@ function registerVoiceRoutes(authenticated, deps) {
551
558
  error: { message: `TTS provider \"${provider}\" is not configured.` }
552
559
  }, 503);
553
560
  try {
554
- const result = await speak(text, ttsConfig, {
561
+ const result = await withModelUsageOrigin("interactive", () => speak(text, ttsConfig, {
555
562
  appConfig: config,
556
563
  parseDirectives: false,
557
564
  signal: c.req.raw.signal,
558
565
  tts: voice ? { voice } : void 0
559
- });
566
+ }));
560
567
  if (!result.audio.length) throw new Error(`TTS provider \"${result.provider}\" returned empty audio`);
561
568
  return new Response(new Uint8Array(result.audio), { headers: {
562
569
  "Content-Type": speechMimeType(result.format),
@@ -630,14 +637,14 @@ function registerVoiceRoutes(authenticated, deps) {
630
637
  }, 503);
631
638
  try {
632
639
  const startedAt = Date.now();
633
- const result = await speak(text, ttsConfig, {
640
+ const result = await withModelUsageOrigin("interactive", () => speak(text, ttsConfig, {
634
641
  appConfig: config,
635
642
  parseDirectives: false,
636
643
  tts: {
637
644
  ...typeof body.model === "string" && body.model.trim() ? { model: body.model.trim() } : {},
638
645
  ...typeof body.voice === "string" && body.voice.trim() ? { voice: body.voice.trim() } : {}
639
646
  }
640
- });
647
+ }));
641
648
  if (!result.audio.length) throw new Error(`TTS provider "${result.provider}" returned empty audio`);
642
649
  const mimeType = result.format === "opus" || result.format === "ogg" ? "audio/ogg" : result.format === "mp3" || result.format === "mpeg" ? "audio/mpeg" : result.format === "wav" ? "audio/wav" : `audio/${result.format}`;
643
650
  return c.json({
@@ -678,18 +685,22 @@ function registerVoiceRoutes(authenticated, deps) {
678
685
  }, 400);
679
686
  const config = service.currentConfig;
680
687
  const sttConfig = mergeSttConfigFromAppConfig(config.tools?.media?.audio, config.tools?.media);
688
+ if (input.expectedProvider && input.expectedProvider !== resolveSTTProviderChain(sttConfig)[0]?.id) return c.json({
689
+ ok: false,
690
+ error: { message: "Speech recognition provider changed during recording. Restore the previous model or start a new recording." }
691
+ }, 409);
681
692
  if (!isSTTAvailable(sttConfig)) return c.json({
682
693
  ok: false,
683
694
  error: { message: "STT is not configured. Enable STT in gateway config (tools.media.audio)." }
684
695
  }, 503);
685
696
  const startedAt = Date.now();
686
697
  try {
687
- const result = await transcribe(input.audioBuffer, sttConfig, {
698
+ const result = await withModelUsageOrigin("interactive", () => transcribe(input.audioBuffer, sttConfig, {
688
699
  language: input.language,
689
700
  mime: input.mimeType,
690
701
  fileName: input.fileName,
691
702
  signal: c.req.raw.signal
692
- });
703
+ }));
693
704
  const detectedLanguage = result.language ?? input.language;
694
705
  const refinementAvailable = (config.voice?.input?.refinement?.mode ?? "off") !== "off";
695
706
  return c.json({
@@ -769,12 +780,14 @@ function registerVoiceRoutes(authenticated, deps) {
769
780
  error: { message: "Missing required file field: audio" }
770
781
  }, 400);
771
782
  const languageValue = form.get("language");
783
+ const expectedProvider = form.get("expectedProvider");
772
784
  const language = typeof languageValue === "string" && languageValue.trim() ? languageValue.trim() : void 0;
773
785
  const fileName = "name" in audio && typeof audio.name === "string" && audio.name.trim() ? audio.name.trim() : `audio-${Date.now()}`;
774
786
  return runTranscription(c, {
775
787
  audioBuffer: Buffer.from(await audio.arrayBuffer()),
776
788
  mimeType: audio.type || "audio/webm",
777
789
  fileName,
790
+ ...typeof expectedProvider === "string" && expectedProvider ? { expectedProvider } : {},
778
791
  ...language ? { language } : {}
779
792
  });
780
793
  });
@@ -0,0 +1,4 @@
1
+ import type { SetupSnapshot } from '../providers/setup/engine.js';
2
+ import type { Config } from '../config/schema.js';
3
+ export declare function loadProviderSetupSnapshot(provider: string, config?: Config): Promise<SetupSnapshot>;
4
+ export declare function readProviderSetupSnapshot(provider: string, configured: boolean, config?: Config): SetupSnapshot;
@@ -0,0 +1,56 @@
1
+ import { getProviderSetupProfile, init_profiles, isInteractiveOnlyProvider } from "../providers/setup/profiles.js";
2
+ import { getModelCatalogStore, init_model_catalog_store } from "../providers/model-catalog-store.js";
3
+ import { getAllModels, getAllProviders, getModelsByProvider, getProviderDisplayName, init_providers, isProviderConfigured, isProviderConfiguredSync, providerSupportsOAuth } from "../providers/index.js";
4
+ import { getImageGenerationProvider } from "../agent/image/generation/provider-registry.js";
5
+ import { listSttProvidersForApi } from "../voice/stt/list-providers.js";
6
+ import { listGlobalDefaults } from "./global-defaults-admin.js";
7
+ import { getRecommendedModelsForProvider } from "../providers/presentation.js";
8
+ import { listTtsProvidersForApi } from "../voice/tts/list-providers.js";
9
+ import { readSetupVoiceState } from "../providers/setup/voice.js";
10
+ //#region src/gateway/provider-model-setup.ts
11
+ init_providers();
12
+ init_model_catalog_store();
13
+ init_profiles();
14
+ async function loadProviderSetupSnapshot(provider, config) {
15
+ const languageProvider = getAllProviders().includes(provider);
16
+ const mediaProvider = getImageGenerationProvider(provider) || listSttProvidersForApi(config).providers.some((entry) => entry.id === provider) || listTtsProvidersForApi(config).providers.some((entry) => entry.id === provider);
17
+ if (!languageProvider && !mediaProvider) throw new Error(`Unknown model provider: ${provider}`);
18
+ return readProviderSetupSnapshot(provider, languageProvider && await isProviderConfigured(provider), config);
19
+ }
20
+ function readProviderSetupSnapshot(provider, configured, config) {
21
+ const languageProvider = getAllProviders().includes(provider);
22
+ const models = (languageProvider ? getModelsByProvider(provider) : []).filter((model) => !("computerUse" in model && model.computerUse));
23
+ const recommended = new Set((languageProvider ? getRecommendedModelsForProvider(provider) : []).map((model) => model.ref));
24
+ const source = getModelCatalogStore().getSource(provider);
25
+ const image = getImageGenerationProvider(provider);
26
+ const images = image?.models.filter((id) => provider !== "xopc-cloud" || source?.models.some((model) => model.id === id && model.availability === "available")) ?? [];
27
+ const configuredProviders = new Set(getAllProviders().filter(isProviderConfiguredSync));
28
+ const backgroundRestrictedModels = new Set(getAllModels().filter((model) => isInteractiveOnlyProvider(model.provider, model.baseUrl)).map((model) => `${model.provider}/${model.id}`));
29
+ for (const model of models) if (/^https?:\/\/(localhost|127\.0\.0\.1|\[::1\])(?=[:/]|$)/.test(model.baseUrl)) configuredProviders.add(provider);
30
+ const voice = config ? readSetupVoiceState(provider, config) : void 0;
31
+ const imageConfigured = image?.isConfigured({ cfg: config }) ?? false;
32
+ const nativeVoiceConfigured = Boolean(!["qwen-token-plan-cn", "xopc-cloud"].includes(provider) && voice && Object.values(voice.choices).some((choices) => choices.length));
33
+ return {
34
+ ...config ? { voice } : {},
35
+ configured: configured || configuredProviders.has(provider) || imageConfigured || nativeVoiceConfigured,
36
+ configuredProviders,
37
+ backgroundRestrictedModels,
38
+ defaults: listGlobalDefaults().defaults,
39
+ profile: getProviderSetupProfile(provider, getProviderDisplayName(provider), providerSupportsOAuth(provider), models[0]?.baseUrl),
40
+ models: (!configured && !configuredProviders.has(provider) && (nativeVoiceConfigured || imageConfigured) ? [] : models).map((model) => ({
41
+ ref: `${provider}/${model.id}`,
42
+ name: model.name,
43
+ vision: model.input.includes("image"),
44
+ reasoning: model.reasoning,
45
+ baseUrl: model.baseUrl,
46
+ api: model.api,
47
+ recommended: recommended.has(`${provider}/${model.id}`)
48
+ })),
49
+ images: (nativeVoiceConfigured && !imageConfigured && !configured ? [] : images).map((id) => ({
50
+ ref: `${provider}/${id}`,
51
+ name: id
52
+ }))
53
+ };
54
+ }
55
+ //#endregion
56
+ export { loadProviderSetupSnapshot, readProviderSetupSnapshot };
@@ -612,12 +612,12 @@ export declare class GatewayConfigCoordinator {
612
612
  model: string;
613
613
  };
614
614
  tts?: {
615
- provider: "alibaba" | "xopc-cloud";
615
+ provider: "xopc-cloud" | "alibaba";
616
616
  model?: string;
617
617
  voice?: string;
618
618
  };
619
619
  omni?: {
620
- provider: "alibaba" | "xopc-cloud";
620
+ provider: "qwen-token-plan-cn" | "xopc-cloud" | "alibaba";
621
621
  model: string;
622
622
  voice: string;
623
623
  instructions: string;
@@ -81,9 +81,6 @@ import "../infra/bus/index.js";
81
81
  import { collectMediaUrisFromMessages, deleteMediaUris } from "../media/session-references.js";
82
82
  import { AgentService } from "../agent/service.js";
83
83
  import { bootstrapApplicationStateSync } from "../bootstrap/application-state.js";
84
- import { setPairingBroadcastSink } from "../channels/pairing/pairing-events.js";
85
- import { registerClarificationChannelRuntime } from "./clarify-runtime.js";
86
- import { ChannelManager } from "../channels/manager.js";
87
84
  import { ChatPreviewService } from "../chat-previews/service.js";
88
85
  import "../chat-previews/index.js";
89
86
  import "../config/index.js";
@@ -102,8 +99,13 @@ import { DiscussionSealer } from "../discussions/sealer.js";
102
99
  import "../discussions/index.js";
103
100
  import { EndpointToolRuntime } from "../endpoint-tools/runtime.js";
104
101
  import "../endpoint-tools/index.js";
102
+ import { HomeCapabilityPreflightService } from "../home-intelligence/capability-preflight.js";
103
+ import { HomeAdviceGenerator } from "../home-intelligence/generator.js";
104
+ import { HomeIntelligenceHost } from "../home-intelligence/host.js";
105
+ import { HomeSnapshotBuilder } from "../home-intelligence/snapshot.js";
105
106
  import { assertGatewayAuthConfigured, extractToken, resolveGatewayAuth, validateToken } from "./auth.js";
106
107
  import { prepareAutomationAgentSession } from "./automation-agent-session.js";
108
+ import { registerClarificationChannelRuntime } from "./clarify-runtime.js";
107
109
  import { stopTailscaleExposure } from "./tailscale-lifecycle.js";
108
110
  import { getGatewayFileSpaceService } from "./file-space-service.js";
109
111
  import { reconcileHomeIntelligenceAutomation } from "./home-intelligence-automation-reconciler.js";
@@ -117,6 +119,8 @@ import { WorkDiscoveryService } from "../work-discovery/service.js";
117
119
  import { buildVoiceMemoryContext } from "../voice/realtime/memory-context.js";
118
120
  import { buildVoicePersonaContext } from "../voice/realtime/persona-context.js";
119
121
  import { voiceMemoryBudget, voicePersonaBudget } from "../voice/realtime/conversation-context.js";
122
+ import { setPairingBroadcastSink } from "../channels/pairing/pairing-events.js";
123
+ import { ChannelManager } from "../channels/manager.js";
120
124
  import "../notes/index.js";
121
125
  import { buildWorkflowChildTools } from "../agent/workflow/workflow-child-tools.js";
122
126
  import { WorkflowRunService } from "../workflows/service/workflow-run-service.js";
@@ -162,10 +166,6 @@ import { TaskMainUpdateDecisionService } from "../tasks/task-main-update-decisio
162
166
  import { selectTaskMainUpdateAttempt, submitAndConfirmTaskMainUpdate } from "../tasks/task-main-update-input.js";
163
167
  import { checkAppContextAccess, prepareAppContext } from "./service/app-context-access.js";
164
168
  import { applyAutomaticVoiceLanguage, inferProductLanguageFromEnvironment, initializeVoiceDefaults } from "../voice/language-profile.js";
165
- import { HomeAdviceGenerator } from "../home-intelligence/generator.js";
166
- import { HomeIntelligenceHost } from "../home-intelligence/host.js";
167
- import { HomeSnapshotBuilder } from "../home-intelligence/snapshot.js";
168
- import { HomeCapabilityPreflightService } from "../home-intelligence/capability-preflight.js";
169
169
  import crypto from "node:crypto";
170
170
  //#region src/gateway/service.ts
171
171
  init_session_repository();