@xopcai/xopc 0.0.367 → 0.0.369

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 (263) hide show
  1. package/dist/browser-ext/_locales/en/messages.json +30 -1
  2. package/dist/browser-ext/_locales/zh_CN/messages.json +30 -1
  3. package/dist/browser-ext/dist/assets/{auth-beGtbLPS.js → page-context-BeworyNB.js} +1331 -1355
  4. package/dist/browser-ext/dist/assets/{sidepanel-BT0ojEzG.css → sidepanel-Ccl0eSa1.css} +43 -0
  5. package/dist/browser-ext/dist/background.js +680 -182
  6. package/dist/browser-ext/dist/sidepanel.html +2 -2
  7. package/dist/browser-ext/dist/sidepanel.js +372 -193
  8. package/dist/browser-ext/manifest.json +2 -8
  9. package/dist/extensions/telegram/xopc.extension.json +1 -1
  10. package/dist/gateway/static/root/assets/{activity-store-Cuf3JFFJ.js → activity-store-BQ3PMp2q.js} +1 -1
  11. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-DyATPNTe.js → agent-avatar-dicebear-Stj17S9u.js} +1 -1
  12. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-CCRfvuov.js +1 -0
  13. package/dist/gateway/static/root/assets/agent-plugin-dialog-CRlzd8El.js +1 -0
  14. package/dist/gateway/static/root/assets/agents-_ug2LCQb.js +66 -0
  15. package/dist/gateway/static/root/assets/{agents-admin-api-D842OcNo.js → agents-admin-api-HBZvVyzF.js} +1 -1
  16. package/dist/gateway/static/root/assets/app-management-settings-panel-pJFe6M6c.js +1 -0
  17. package/dist/gateway/static/root/assets/{appearance-settings-DQr0o6Lm.js → appearance-settings-BrxSpBWa.js} +1 -1
  18. package/dist/gateway/static/root/assets/{apps-page-CltMV4Xp.js → apps-page-DegSl5Lh.js} +1 -1
  19. package/dist/gateway/static/root/assets/{archive-plugin-DT8Nio-r.js → archive-plugin-BO3I9zRP.js} +1 -1
  20. package/dist/gateway/static/root/assets/{automations-page-BIfWS_3Y.js → automations-page-BZQ_VHjp.js} +1 -1
  21. package/dist/gateway/static/root/assets/automations-workspace-BQywN6nG.js +6 -0
  22. package/dist/gateway/static/root/assets/{binary-plugins-7qs3qcW9.js → binary-plugins-gFD7vH9R.js} +1 -1
  23. package/dist/gateway/static/root/assets/{block-editor-BFPUlxJ6.js → block-editor-3XjFv3kK.js} +28 -28
  24. package/dist/gateway/static/root/assets/browser-automation-inputs-DxRoKFun.js +1 -0
  25. package/dist/gateway/static/root/assets/browser-automations-page-yiEuG1v7.js +3 -0
  26. package/dist/gateway/static/root/assets/browser-settings-page-ch2_bQF0.js +3 -0
  27. package/dist/gateway/static/root/assets/{capabilities-K0Zb_lH0.js → capabilities-B48r0DDa.js} +1 -1
  28. package/dist/gateway/static/root/assets/{capabilities-BzWFO_x_.js → capabilities-DO-vfNKI.js} +1 -1
  29. package/dist/gateway/static/root/assets/capabilities-page-BEnFt_dj.js +2 -0
  30. package/dist/gateway/static/root/assets/capabilities-settings-panel-NckMsJ5N.js +8 -0
  31. package/dist/gateway/static/root/assets/{capability-header-actions-AMn_vTNv.js → capability-header-actions-CY8KCO9j.js} +1 -1
  32. package/dist/gateway/static/root/assets/channels-CHOS2CGa.js +1 -0
  33. package/dist/gateway/static/root/assets/{chat-terminal-dock-C7nAROhF.js → chat-terminal-dock-Bwknnb4c.js} +2 -2
  34. package/dist/gateway/static/root/assets/computer-settings-page-B2xeFCSt.js +1 -0
  35. package/dist/gateway/static/root/assets/{connector-service-page-CTx1B8wx.js → connector-service-page-C83DnAqK.js} +1 -1
  36. package/dist/gateway/static/root/assets/connectors-page-D6wTmWA6.js +2 -0
  37. package/dist/gateway/static/root/assets/{date-picker-Cx_xIKvN.js → date-picker-Bq9GR-DU.js} +1 -1
  38. package/dist/gateway/static/root/assets/{dependency-picker-DYm96PDu.js → dependency-picker-BTERkA9X.js} +1 -1
  39. package/dist/gateway/static/root/assets/{desktop-pet-D90OzgeR.js → desktop-pet-BwsbQw8V.js} +1 -1
  40. package/dist/gateway/static/root/assets/{desktop-pet-settings-CmdCecjm.js → desktop-pet-settings-sL9i44pP.js} +1 -1
  41. package/dist/gateway/static/root/assets/device-pairing-wizard-DI2bqaKO.js +1 -0
  42. package/dist/gateway/static/root/assets/{directory-picker-path-field-DZpaoeNa.js → directory-picker-path-field-BFlDmsS5.js} +1 -1
  43. package/dist/gateway/static/root/assets/{extension-debug-page-Bv6QE8kC.js → extension-debug-page-7Z1Tp7-w.js} +1 -1
  44. package/dist/gateway/static/root/assets/{extension-page-CEsq71Cm.js → extension-page-uGqvb8QX.js} +1 -1
  45. package/dist/gateway/static/root/assets/{extension-provider-CX-sK0Tw.js → extension-provider-xlSyz4Z6.js} +1 -1
  46. package/dist/gateway/static/root/assets/{extension-settings-page-UyOHF39P.js → extension-settings-page-CKHgrjOs.js} +1 -1
  47. package/dist/gateway/static/root/assets/{fallback-models-CKv_Wqg8.js → fallback-models-BwQg0G1D.js} +1 -1
  48. package/dist/gateway/static/root/assets/{gateway-config-swr-Cjnkle5J.js → gateway-config-swr-7RKqgU_U.js} +1 -1
  49. package/dist/gateway/static/root/assets/{gateway-realtime-DCCLdyQD.js → gateway-realtime-DDWymi-o.js} +1 -1
  50. package/dist/gateway/static/root/assets/gateway-realtime-store-BheKaO6d.js +1 -0
  51. package/dist/gateway/static/root/assets/gateway-settings-BAQnSEMJ.js +1 -0
  52. package/dist/gateway/static/root/assets/{gateway-startup-retry-CXKmdVzN.js → gateway-startup-retry-jiV5sbEX.js} +1 -1
  53. package/dist/gateway/static/root/assets/home-page-BZDjvwet.js +2 -0
  54. package/dist/gateway/static/root/assets/{image-generation-api-NLHzm4Nc.js → image-generation-api-DO4mXb6I.js} +1 -1
  55. package/dist/gateway/static/root/assets/{imports-page-C7qvlBTQ.js → imports-page-re1_Nh64.js} +1 -1
  56. package/dist/gateway/static/root/assets/index-BB1z8QxA.js +106 -0
  57. package/dist/gateway/static/root/assets/index-D9R6tU7r.css +1 -0
  58. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-pkgFWJb-.js → keyboard-shortcuts-settings-B_xja9LN.js} +1 -1
  59. package/dist/gateway/static/root/assets/{local-app-workbench-page-dMDhZXAi.js → local-app-workbench-page-CErdCrPX.js} +1 -1
  60. package/dist/gateway/static/root/assets/{local-apps-page-TpUAfOn2.js → local-apps-page-BPL2RXdK.js} +1 -1
  61. package/dist/gateway/static/root/assets/{local-session-drafts-Cvv7I0fw.js → local-session-drafts-DRPsDCj1.js} +1 -1
  62. package/dist/gateway/static/root/assets/{locale-store-C8TMD2gn.js → locale-store-COVscAqC.js} +1 -1
  63. package/dist/gateway/static/root/assets/logs-page-DL-BM0xq.js +2 -0
  64. package/dist/gateway/static/root/assets/management-settings-BOVRHhXk.js +1 -0
  65. package/dist/gateway/static/root/assets/{markdown-view-Dse7rkio.js → markdown-view-B_qnAcW2.js} +1 -1
  66. package/dist/gateway/static/root/assets/{media-plugins-BZrnzaBM.js → media-plugins-C0Pc-wSY.js} +1 -1
  67. package/dist/gateway/static/root/assets/messages-Bb2GK-Nj.js +3 -0
  68. package/dist/gateway/static/root/assets/models-hub-cache-DyPPksMP.js +1 -0
  69. package/dist/gateway/static/root/assets/note-detail-panel-DJJK2yL4.js +5 -0
  70. package/dist/gateway/static/root/assets/{notes-api-DKiVeQKG.js → notes-api-sBgBcyLW.js} +1 -1
  71. package/dist/gateway/static/root/assets/notes-page-oCxO7ZTv.js +8 -0
  72. package/dist/gateway/static/root/assets/{page-context-capture-button-Cxzd4QPB.js → page-context-capture-button-tf77xIz3.js} +1 -1
  73. package/dist/gateway/static/root/assets/personal-page-DOk9gUK5.js +1 -0
  74. package/dist/gateway/static/root/assets/{product-open-page-D4hoEWiu.js → product-open-page-Dc3Y-Y7J.js} +1 -1
  75. package/dist/gateway/static/root/assets/{product-preview-content-aR38El2E.js → product-preview-content-MG_hmVA3.js} +1 -1
  76. package/dist/gateway/static/root/assets/{project-detail-page-D20QH4YB.js → project-detail-page-3uAzbW4T.js} +1 -1
  77. package/dist/gateway/static/root/assets/{projects-page-Bf3BIcT6.js → projects-page-MllfNLGA.js} +1 -1
  78. package/dist/gateway/static/root/assets/{registry-api-AdnxowbH.js → registry-api-Bh9UBb-f.js} +1 -1
  79. package/dist/gateway/static/root/assets/remote-access-hub-Bs-C70el.js +1 -0
  80. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-CBN3raz1.js → runtime-tools-settings-panel-DpJ5jNzR.js} +1 -1
  81. package/dist/gateway/static/root/assets/scenes-page-Dpxamkw6.js +2 -0
  82. package/dist/gateway/static/root/assets/{schema-form-CxrMGsT9.js → schema-form-DUeyQ1zh.js} +1 -1
  83. package/dist/gateway/static/root/assets/{send-session-input-CgOzhDZ0.js → send-session-input-Dgn4BRk_.js} +1 -1
  84. package/dist/gateway/static/root/assets/{session-api-_HIN8or3.js → session-api-yjpEz4pP.js} +1 -1
  85. package/dist/gateway/static/root/assets/{session-manager-CzCto5zT.js → session-manager-LInoZ_Yi.js} +1 -1
  86. package/dist/gateway/static/root/assets/sessions-page-BCVlNHtq.js +1 -0
  87. package/dist/gateway/static/root/assets/settings-advanced-gate-Bz-ue9fZ.js +1 -0
  88. package/dist/gateway/static/root/assets/{settings-page-D8Q3H3-o.js → settings-page-DouHuBXt.js} +1 -1
  89. package/dist/gateway/static/root/assets/{setup-status-panel-DvLMMiuS.js → setup-status-panel-B5BoZ-1y.js} +1 -1
  90. package/dist/gateway/static/root/assets/{share-link-dialog-Dg5os066.js → share-link-dialog-DJTabLAM.js} +1 -1
  91. package/dist/gateway/static/root/assets/{share-preview-page-DMvohAyr.js → share-preview-page-jw7h4t_B.js} +1 -1
  92. package/dist/gateway/static/root/assets/{shares-api-C96IO4qJ.js → shares-api-c0dfWz6h.js} +1 -1
  93. package/dist/gateway/static/root/assets/shares-settings-BlnlzGjH.js +1 -0
  94. package/dist/gateway/static/root/assets/{skill-api-C10ML0CH.js → skill-api-CfyX_0zN.js} +1 -1
  95. package/dist/gateway/static/root/assets/{skill-reload-api-DNbJzSfB.js → skill-reload-api-Ge5XymHa.js} +1 -1
  96. package/dist/gateway/static/root/assets/{skills-page-DObMKvA6.js → skills-page-DjdTeYzm.js} +1 -1
  97. package/dist/gateway/static/root/assets/system-settings-panel-DWf256TE.js +1 -0
  98. package/dist/gateway/static/root/assets/{task-detail-page-BR2L1L8l.js → task-detail-page-DE6N1ZQe.js} +2 -2
  99. package/dist/gateway/static/root/assets/{task-expandable-content-DL2Q2gre.js → task-expandable-content-hYcgCEE3.js} +1 -1
  100. package/dist/gateway/static/root/assets/{theme-store-DQ6KJa4l.js → theme-store-BOfCKgl6.js} +1 -1
  101. package/dist/gateway/static/root/assets/{tracing-settings-page-Ed8_GYUT.js → tracing-settings-page-DDWFXcST.js} +1 -1
  102. package/dist/gateway/static/root/assets/{tunnel-api-D3X8jDwo.js → tunnel-api-BBm9esrY.js} +1 -1
  103. package/dist/gateway/static/root/assets/{usage-page-BqzRyyb9.js → usage-page-C93x89uW.js} +1 -1
  104. package/dist/gateway/static/root/assets/{use-autosave-CRFefpzO.js → use-autosave-CSckcjFx.js} +1 -1
  105. package/dist/gateway/static/root/assets/{use-composer-attachments-OLrvSjn5.js → use-composer-attachments-C7Gaaai1.js} +1 -1
  106. package/dist/gateway/static/root/assets/{use-file-preview-expanded-CJvzfQvw.js → use-file-preview-expanded-Db2VYg1b.js} +2 -2
  107. package/dist/gateway/static/root/assets/user-model-page-B74LkVbp.js +2 -0
  108. package/dist/gateway/static/root/assets/{voice-api-key-field-R9zNWYR_.js → voice-api-key-field-GEw5x2fU.js} +1 -1
  109. package/dist/gateway/static/root/assets/{voice-config-api-DLudE9Rc.js → voice-config-api-3yyVwXln.js} +1 -1
  110. package/dist/gateway/static/root/assets/{work-discovery-overlay-DVmQrolV.js → work-discovery-overlay-Bs2MKiTv.js} +1 -1
  111. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-DEkmuD3T.js → workflow-run-setup-panel-BR_U_snV.js} +2 -2
  112. package/dist/gateway/static/root/assets/{workflows-page-pqCB3sh4.js → workflows-page-Crk4SxtC.js} +3 -3
  113. package/dist/gateway/static/root/assets/{workspace-api-CdVUhyPo.js → workspace-api-Si2o3inw.js} +2 -2
  114. package/dist/gateway/static/root/index.html +27 -28
  115. package/dist/package.js +1 -1
  116. package/dist/packages/browser-control-contract/src/automation.js +213 -0
  117. package/dist/packages/browser-control-contract/src/index.js +43 -12
  118. package/dist/packages/gateway-contract/src/gateway-scopes.js +3 -1
  119. package/dist/packages/gateway-contract/src/notifications.js +1 -0
  120. package/dist/packages/realtime-protocol/src/voice-catalog.js +7 -1
  121. package/dist/packages/realtime-protocol/src/voice.js +9 -3
  122. package/dist/src/agent/coding/repository-instructions.js +8 -1
  123. package/dist/src/agent/tool-manuals/browser.d.ts +1 -1
  124. package/dist/src/agent/tool-manuals/browser.js +3 -3
  125. package/dist/src/agent/tools/browser/tool/browser-use-tool.js +1 -1
  126. package/dist/src/agent/tools/browser/tool/schemas.d.ts +0 -13
  127. package/dist/src/agent/tools/browser/tool/schemas.js +0 -4
  128. package/dist/src/agent/tools/browser-automation-tool.d.ts +74 -1
  129. package/dist/src/agent/tools/browser-automation-tool.js +52 -6
  130. package/dist/src/agent-config/schema.d.ts +1 -1
  131. package/dist/src/agent-config/schema.js +1 -1
  132. package/dist/src/automations/capabilities/write.d.ts +2 -0
  133. package/dist/src/automations/domain/types.d.ts +11 -0
  134. package/dist/src/automations/domain/validation.d.ts +4 -0
  135. package/dist/src/automations/domain/validation.js +1 -0
  136. package/dist/src/automations/draft/automation-draft-validator.d.ts +1 -0
  137. package/dist/src/automations/service/action-executor.js +11 -3
  138. package/dist/src/automations/service/automation-service.d.ts +1 -0
  139. package/dist/src/automations/service/automation-service.js +13 -1
  140. package/dist/src/bootstrap/application-state.js +3 -1
  141. package/dist/src/browser/automations/repository.d.ts +4 -0
  142. package/dist/src/browser/automations/repository.js +27 -6
  143. package/dist/src/browser/automations/runner.js +101 -9
  144. package/dist/src/browser/automations/runtime-service.js +4 -3
  145. package/dist/src/browser/automations/schema.d.ts +84 -1
  146. package/dist/src/browser/automations/schema.js +68 -2
  147. package/dist/src/browser/automations/service.d.ts +78 -1
  148. package/dist/src/browser/automations/service.js +36 -4
  149. package/dist/src/browser/automations/types.d.ts +19 -4
  150. package/dist/src/browser/drivers/extension-driver.d.ts +5 -5
  151. package/dist/src/browser/drivers/extension-driver.js +10 -10
  152. package/dist/src/browser/drivers/playwright-driver.js +46 -0
  153. package/dist/src/browser/index.d.ts +1 -2
  154. package/dist/src/browser/index.js +2 -3
  155. package/dist/src/browser/policy/browser-policy.d.ts +0 -1
  156. package/dist/src/browser/policy/browser-policy.js +1 -4
  157. package/dist/src/browser/providers/index.d.ts +1 -1
  158. package/dist/src/browser/providers/index.js +2 -2
  159. package/dist/src/browser/providers/realtime-extension.d.ts +1 -1
  160. package/dist/src/browser/providers/realtime-extension.js +5 -1
  161. package/dist/src/browser/recordings/service.d.ts +22 -0
  162. package/dist/src/browser/recordings/service.js +160 -0
  163. package/dist/src/browser/runtime/browser-runtime.d.ts +1 -1
  164. package/dist/src/browser/runtime/browser-runtime.js +19 -56
  165. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  166. package/dist/src/computer/runtime.js +2 -2
  167. package/dist/src/config/schema.d.ts +12 -12
  168. package/dist/src/config/schema.js +12 -12
  169. package/dist/src/endpoint-tools/policy.js +4 -3
  170. package/dist/src/gateway/hono/routes/browser-automations.js +23 -7
  171. package/dist/src/gateway/hono/routes/browser-recordings.d.ts +3 -0
  172. package/dist/src/gateway/hono/routes/browser-recordings.js +78 -0
  173. package/dist/src/gateway/hono/routes/browser.js +1 -34
  174. package/dist/src/gateway/hono/routes/device-push.js +1 -0
  175. package/dist/src/gateway/hono/routes/home.js +1 -1
  176. package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
  177. package/dist/src/gateway/hono/routes/personal-agent.js +35 -0
  178. package/dist/src/gateway/hono/routes/voice.js +5 -2
  179. package/dist/src/gateway/security/gateway-scopes.js +3 -1
  180. package/dist/src/gateway/service/agent-runner.js +1 -0
  181. package/dist/src/home-intelligence/generator.d.ts +2 -0
  182. package/dist/src/home-intelligence/generator.js +53 -4
  183. package/dist/src/home-intelligence/host.d.ts +2 -1
  184. package/dist/src/home-intelligence/host.js +23 -3
  185. package/dist/src/migrations/cloud-public-models.d.ts +7 -0
  186. package/dist/src/migrations/cloud-public-models.js +157 -0
  187. package/dist/src/notifications/clarification.d.ts +5 -0
  188. package/dist/src/notifications/clarification.js +66 -0
  189. package/dist/src/notifications/device-store.js +1 -0
  190. package/dist/src/notifications/harmony-push.d.ts +1 -0
  191. package/dist/src/notifications/harmony-push.js +3 -1
  192. package/dist/src/notifications/planner.d.ts +1 -0
  193. package/dist/src/notifications/service.d.ts +2 -2
  194. package/dist/src/notifications/service.js +20 -4
  195. package/dist/src/notifications/store.d.ts +2 -0
  196. package/dist/src/notifications/store.js +7 -1
  197. package/dist/src/notifications/types.d.ts +1 -0
  198. package/dist/src/notifications/types.js +1 -0
  199. package/dist/src/providers/model-catalog-persistence.js +2 -2
  200. package/dist/src/providers/presentation.js +1 -0
  201. package/dist/src/providers/xopc-cloud-model-source.js +1 -1
  202. package/dist/src/storage/sqlite/clarification-wait-repository.js +1 -0
  203. package/dist/src/storage/sqlite/migrations/238_browser_record_replay.sql +45 -0
  204. package/dist/src/storage/sqlite/migrations/239_clarification_notifications.sql +26 -0
  205. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  206. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  207. package/dist/src/storage/sqlite/schema.js +1 -1
  208. package/dist/src/tasks/home-query-service.d.ts +1 -1
  209. package/dist/src/tasks/home-query-service.js +6 -2
  210. package/dist/src/voice/dashscope/streaming-tts-stream.d.ts +2 -1
  211. package/dist/src/voice/dashscope/streaming-tts-stream.js +135 -79
  212. package/dist/src/voice/metadata/types.d.ts +1 -0
  213. package/dist/src/voice/platform-catalog.d.ts +4 -0
  214. package/dist/src/voice/platform-settings.js +1 -0
  215. package/dist/src/voice/realtime/agentEngine.js +78 -1
  216. package/dist/src/voice/realtime/speakable-segmenter.d.ts +2 -0
  217. package/dist/src/voice/realtime/speakable-segmenter.js +30 -0
  218. package/dist/src/voice/tts/providers/alibaba-speech.js +17 -1
  219. package/dist/src/voice/tts/providers/xopc-cloud-speech.js +3 -2
  220. package/dist/src/voice/tts/speak-core.d.ts +3 -0
  221. package/dist/src/voice/tts/speak-core.js +21 -1
  222. package/dist/src/voice/tts/speech-provider-types.d.ts +8 -0
  223. package/package.json +3 -3
  224. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-gT9_j4tr.js +0 -1
  225. package/dist/gateway/static/root/assets/agent-plugin-dialog-CLXCJ6JN.js +0 -1
  226. package/dist/gateway/static/root/assets/agents-BAUfOMsq.js +0 -66
  227. package/dist/gateway/static/root/assets/app-management-settings-panel-CoIFxQKH.js +0 -1
  228. package/dist/gateway/static/root/assets/automations-workspace-BCGPjsdU.js +0 -6
  229. package/dist/gateway/static/root/assets/browser-automation-inputs-BUAIKIX0.js +0 -1
  230. package/dist/gateway/static/root/assets/browser-automations-page-CSwu1U1F.js +0 -3
  231. package/dist/gateway/static/root/assets/browser-settings-page-C1ReMNqX.js +0 -3
  232. package/dist/gateway/static/root/assets/capabilities-page-BdTSqloI.js +0 -2
  233. package/dist/gateway/static/root/assets/capabilities-settings-panel-BUblBMZC.js +0 -8
  234. package/dist/gateway/static/root/assets/channels-CXCf5qO6.js +0 -1
  235. package/dist/gateway/static/root/assets/computer-settings-page-B5SuSZ3G.js +0 -1
  236. package/dist/gateway/static/root/assets/connectors-page-DfnK1crf.js +0 -2
  237. package/dist/gateway/static/root/assets/device-pairing-wizard-s2ogSa4l.js +0 -1
  238. package/dist/gateway/static/root/assets/gateway-realtime-store-C_Th8kGg.js +0 -1
  239. package/dist/gateway/static/root/assets/gateway-settings-CZ73IpbP.js +0 -1
  240. package/dist/gateway/static/root/assets/home-page-BQWq4kYi.js +0 -2
  241. package/dist/gateway/static/root/assets/index-BQgqzhQj.js +0 -106
  242. package/dist/gateway/static/root/assets/index-COB4QIJp.css +0 -1
  243. package/dist/gateway/static/root/assets/logs-page-B-Y9oZLh.js +0 -2
  244. package/dist/gateway/static/root/assets/management-settings-B2lzsw6X.js +0 -1
  245. package/dist/gateway/static/root/assets/messages-Dy26npMy.js +0 -3
  246. package/dist/gateway/static/root/assets/models-hub-cache-B1C86nRp.js +0 -1
  247. package/dist/gateway/static/root/assets/note-detail-panel-DL__qP6U.js +0 -5
  248. package/dist/gateway/static/root/assets/notes-page-DTBbg9Hs.js +0 -8
  249. package/dist/gateway/static/root/assets/oauth-api-BwpzpRwC.js +0 -1
  250. package/dist/gateway/static/root/assets/personal-page-CzaTnHeD.js +0 -1
  251. package/dist/gateway/static/root/assets/remote-access-hub-CKxqncqW.js +0 -1
  252. package/dist/gateway/static/root/assets/scenes-page-Cv_5ozfX.js +0 -2
  253. package/dist/gateway/static/root/assets/sessions-page-DZcu6NLJ.js +0 -1
  254. package/dist/gateway/static/root/assets/settings-advanced-gate-DazqeDQ7.js +0 -1
  255. package/dist/gateway/static/root/assets/shares-settings-CsDATuCw.js +0 -1
  256. package/dist/gateway/static/root/assets/system-settings-panel-Bn3khdzb.js +0 -1
  257. package/dist/gateway/static/root/assets/user-model-page-CG6wqIKP.js +0 -2
  258. package/dist/src/browser/policy/approval-store.d.ts +0 -17
  259. package/dist/src/browser/policy/approval-store.js +0 -62
  260. package/dist/src/browser/providers/extension-ws-acquire.d.ts +0 -19
  261. package/dist/src/browser/providers/extension-ws-acquire.js +0 -78
  262. package/dist/src/browser/providers/extension.d.ts +0 -61
  263. package/dist/src/browser/providers/extension.js +0 -378
@@ -185,6 +185,7 @@ function createClarificationWait(input) {
185
185
  id, principal_id, conversation_id, transcript_id, status, version, data_json,
186
186
  origin_run_id, origin_tool_call_id
187
187
  ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(wait.id, wait.principalId, wait.conversationId, wait.transcriptId, wait.status, wait.version, JSON.stringify(wait), wait.originRunId, wait.originToolCallId);
188
+ db.prepare("INSERT INTO clarification_notification_outbox(wait_id, created_at) VALUES (?, ?)").run(wait.id, wait.createdAt);
188
189
  markTaskWaiting(wait);
189
190
  bumpSessionInputRevision(db, input.conversationId);
190
191
  return wait;
@@ -0,0 +1,45 @@
1
+ CREATE TABLE browser_automation_versions (
2
+ automation_id TEXT NOT NULL REFERENCES browser_automations(automation_id) ON DELETE CASCADE,
3
+ revision INTEGER NOT NULL,
4
+ definition_json TEXT NOT NULL,
5
+ created_at_ms INTEGER NOT NULL,
6
+ PRIMARY KEY (automation_id, revision)
7
+ );
8
+ INSERT INTO browser_automation_versions SELECT automation_id, revision, definition_json, updated_at_ms FROM browser_automations;
9
+
10
+ CREATE TABLE browser_automation_verifications (
11
+ automation_id TEXT NOT NULL,
12
+ revision INTEGER NOT NULL,
13
+ run_id TEXT NOT NULL REFERENCES browser_automation_runs(run_id) ON DELETE CASCADE,
14
+ verified_at_ms INTEGER NOT NULL,
15
+ PRIMARY KEY (automation_id, revision),
16
+ FOREIGN KEY (automation_id, revision) REFERENCES browser_automation_versions(automation_id, revision) ON DELETE CASCADE
17
+ );
18
+ ALTER TABLE browser_automation_runs ADD COLUMN client_request_id TEXT;
19
+ ALTER TABLE browser_automation_runs ADD COLUMN business_outcome TEXT;
20
+ CREATE UNIQUE INDEX idx_browser_run_request ON browser_automation_runs(client_request_id) WHERE client_request_id IS NOT NULL;
21
+
22
+ CREATE TABLE browser_recordings (
23
+ recording_id TEXT PRIMARY KEY,
24
+ principal_id TEXT NOT NULL,
25
+ state TEXT NOT NULL,
26
+ ack_seq INTEGER NOT NULL DEFAULT 0,
27
+ final_seq INTEGER,
28
+ automation_id TEXT REFERENCES browser_automations(automation_id) ON DELETE CASCADE,
29
+ error TEXT,
30
+ created_at_ms INTEGER NOT NULL,
31
+ updated_at_ms INTEGER NOT NULL
32
+ );
33
+ CREATE TABLE browser_recording_events (
34
+ recording_id TEXT NOT NULL REFERENCES browser_recordings(recording_id) ON DELETE CASCADE,
35
+ seq INTEGER NOT NULL,
36
+ event_id TEXT NOT NULL UNIQUE,
37
+ payload_json TEXT NOT NULL,
38
+ PRIMARY KEY (recording_id, seq)
39
+ );
40
+
41
+ UPDATE automations SET action_json=json_set(action_json, '$.revision', COALESCE((SELECT revision FROM browser_automations WHERE automation_id=json_extract(automations.action_json, '$.automationId')), 1)), enabled=0
42
+ WHERE json_extract(action_json, '$.kind')='browser_automation';
43
+
44
+ UPDATE devices SET scopes_json=json_insert(scopes_json, '$[#]', 'automations.read') WHERE platform='chrome' AND NOT EXISTS(SELECT 1 FROM json_each(scopes_json) WHERE value='automations.read');
45
+ UPDATE devices SET scopes_json=json_insert(scopes_json, '$[#]', 'automations.write') WHERE platform='chrome' AND NOT EXISTS(SELECT 1 FROM json_each(scopes_json) WHERE value='automations.write');
@@ -0,0 +1,26 @@
1
+ CREATE TABLE clarification_notification_outbox (
2
+ wait_id TEXT PRIMARY KEY REFERENCES session_clarification_waits(id) ON DELETE CASCADE,
3
+ status TEXT NOT NULL DEFAULT 'pending' CHECK(status IN ('pending', 'settled')),
4
+ created_at INTEGER NOT NULL
5
+ );
6
+ CREATE INDEX idx_clarification_notification_pending ON clarification_notification_outbox(status, created_at);
7
+ INSERT INTO clarification_notification_outbox(wait_id, created_at)
8
+ SELECT id, CAST(json_extract(data_json, '$.createdAt') AS INTEGER)
9
+ FROM session_clarification_waits WHERE status = 'open';
10
+
11
+ ALTER TABLE notification_deliveries RENAME TO notification_deliveries_old;
12
+ CREATE TABLE notification_deliveries (
13
+ event_id TEXT NOT NULL REFERENCES notification_events(event_id) ON DELETE CASCADE,
14
+ device_id TEXT NOT NULL REFERENCES device_push_endpoints(device_id) ON DELETE CASCADE,
15
+ status TEXT NOT NULL CHECK(status IN ('pending', 'accepted', 'delivered', 'dead', 'cancelled')),
16
+ attempts INTEGER NOT NULL DEFAULT 0,
17
+ next_attempt_at INTEGER NOT NULL,
18
+ provider_ticket_id TEXT,
19
+ last_error TEXT,
20
+ updated_at INTEGER NOT NULL,
21
+ PRIMARY KEY(event_id, device_id)
22
+ );
23
+ INSERT INTO notification_deliveries SELECT * FROM notification_deliveries_old;
24
+ DROP TABLE notification_deliveries_old;
25
+ CREATE INDEX idx_notification_deliveries_due ON notification_deliveries(status, next_attempt_at);
26
+ CREATE INDEX idx_notification_deliveries_device ON notification_deliveries(device_id);
@@ -3,7 +3,7 @@ import type { ApplyMigrationsOptions } from './types.js';
3
3
  /** Baseline schema version applied from schema.sql on first open. */
4
4
  export declare const XOPC_DB_BASELINE_SCHEMA_VERSION = 165;
5
5
  /** Latest schema version this release supports (increment when adding migrations). */
6
- export declare const XOPC_DB_SCHEMA_VERSION = 237;
6
+ export declare const XOPC_DB_SCHEMA_VERSION = 239;
7
7
  export declare function resolveMigrationsDir(override?: string): string;
8
8
  /**
9
9
  * Apply sequential SQL migrations from (currentVersion + 1) through targetVersion.
@@ -57,7 +57,7 @@ function applySingleMigration(db, migration, discardOldScenes = false) {
57
57
  */
58
58
  function applyPendingMigrations(db, options = {}) {
59
59
  db.function("xopc_operation_id", () => currentOperationId() ?? null);
60
- const targetVersion = options.targetVersion ?? 237;
60
+ const targetVersion = options.targetVersion ?? 239;
61
61
  let currentVersion = readSchemaVersion(db);
62
62
  if (currentVersion > targetVersion) throw new DatabaseSchemaTooNewError(currentVersion, targetVersion);
63
63
  if (!options.migrationsDir && currentVersion < 165) throw new DatabaseSchemaTooOldError(currentVersion, 165);
@@ -95,7 +95,7 @@ function applyPendingMigrations(db, options = {}) {
95
95
  }
96
96
  /** Inspect schema version without mutating the database. */
97
97
  function inspectSchemaMigrationStatus(db, options = {}) {
98
- const appVersion = options.targetVersion ?? 237;
98
+ const appVersion = options.targetVersion ?? 239;
99
99
  const dbVersion = readSchemaVersion(db);
100
100
  if (dbVersion > appVersion) return {
101
101
  dbVersion,
@@ -137,7 +137,7 @@ var init_runner = __esmMin((() => {
137
137
  init_errors();
138
138
  log = createLogger("Sqlite:Migrations");
139
139
  XOPC_DB_BASELINE_SCHEMA_VERSION = 165;
140
- XOPC_DB_SCHEMA_VERSION = 237;
140
+ XOPC_DB_SCHEMA_VERSION = 239;
141
141
  }));
142
142
  //#endregion
143
143
  init_runner();
@@ -28,7 +28,7 @@ function ensureXopcDatabaseSchema(db, options = {}) {
28
28
  currentVersion = 165;
29
29
  }
30
30
  applyPendingMigrations(db, {
31
- targetVersion: 237,
31
+ targetVersion: 239,
32
32
  databasePath: fresh ? void 0 : options.databasePath
33
33
  });
34
34
  }
@@ -58,7 +58,7 @@ export declare class HomeQueryService {
58
58
  #private;
59
59
  private readonly service;
60
60
  private readonly getAdvisor;
61
- constructor(service: HomeGatewayPort, getAdvisor?: () => HomeAdvisor);
61
+ constructor(service: HomeGatewayPort, getAdvisor?: (locale?: string) => HomeAdvisor);
62
62
  getSnapshot(locale?: string): Promise<HomeResponse>;
63
63
  }
64
64
  export {};
@@ -104,7 +104,11 @@ function decisionFromTask(model, projectName, locale) {
104
104
  },
105
105
  kind: "task",
106
106
  title: task.title,
107
- detail: item.summary,
107
+ detail: isChinese ? {
108
+ "Agent run returned no result or evidence": "本次执行没有返回结果或依据,请重试。",
109
+ "The latest run failed": "最近一次执行失败,请查看详情后重试。",
110
+ "Task is overdue": "任务已逾期。"
111
+ }[item.summary] ?? item.summary : item.summary,
108
112
  reason,
109
113
  urgency: "now",
110
114
  href: `/tasks/${encodeURIComponent(task.id)}`,
@@ -412,7 +416,7 @@ var HomeQueryService = class {
412
416
  }),
413
417
  runningConversations,
414
418
  decisions,
415
- advisor: this.getAdvisor(),
419
+ advisor: this.getAdvisor(locale),
416
420
  attentionPolicy: governed.policy
417
421
  };
418
422
  }
@@ -1,4 +1,4 @@
1
- import type { SpeechSynthesisStreamResult } from '../tts/speech-provider-types.js';
1
+ import type { SpeechStreamSession, SpeechSynthesisStreamResult } from '../tts/speech-provider-types.js';
2
2
  export interface DashScopeStreamingTtsRequest {
3
3
  apiKey: string;
4
4
  baseUrl?: string;
@@ -11,3 +11,4 @@ export interface DashScopeStreamingTtsRequest {
11
11
  timeoutMs: number;
12
12
  }
13
13
  export declare function openDashScopeStreamingTts(request: DashScopeStreamingTtsRequest): Promise<SpeechSynthesisStreamResult>;
14
+ export declare function openDashScopeTtsSession(request: Omit<DashScopeStreamingTtsRequest, 'text'>): Promise<SpeechStreamSession>;
@@ -47,6 +47,18 @@ function event(type, extra = {}) {
47
47
  });
48
48
  }
49
49
  async function openDashScopeStreamingTts(request) {
50
+ const session = await openDashScopeTtsSession(request);
51
+ try {
52
+ return {
53
+ ...await session.synthesize(request.text),
54
+ release: () => session.close()
55
+ };
56
+ } catch (error) {
57
+ await session.close();
58
+ throw error;
59
+ }
60
+ }
61
+ async function openDashScopeTtsSession(request) {
50
62
  const volume = request.volume ?? DEFAULT_REALTIME_VOLUME;
51
63
  if (!Number.isInteger(volume) || volume < 0 || volume > 100) throw new Error("DashScope realtime TTS volume must be an integer from 0 to 100");
52
64
  request = {
@@ -79,58 +91,48 @@ async function openDashScopeStreamingTts(request) {
79
91
  }
80
92
  async function openStreamingTtsAttempt(request) {
81
93
  if (!request.apiKey) throw new Error("DashScope TTS API key is unavailable");
82
- if (request.signal.aborted) throw request.signal.reason;
94
+ request.signal.throwIfAborted();
95
+ const startedAt = Date.now();
83
96
  const socket = new WebSocket(realtimeUrl(request.baseUrl, request.model), {
84
97
  headers: { Authorization: `Bearer ${request.apiKey}` },
85
98
  perMessageDeflate: false
86
99
  });
87
- let controller;
88
100
  let settled = false;
89
- let streamClosed = false;
101
+ let closed = false;
102
+ let failure;
103
+ let active;
90
104
  let resolveReady;
91
105
  let rejectReady;
92
- const readyPromise = new Promise((resolve, reject) => {
106
+ const ready = new Promise((resolve, reject) => {
93
107
  resolveReady = resolve;
94
108
  rejectReady = reject;
95
109
  });
96
- const audioStream = new ReadableStream({
97
- start(next) {
98
- controller = next;
99
- },
100
- cancel() {
101
- streamClosed = true;
102
- socket.close(1e3, "Consumer cancelled");
103
- }
104
- });
105
- const fail = (error, closeSocket = true) => {
110
+ const closeSocket = (code, reason) => {
111
+ request.signal.removeEventListener("abort", onAbort);
112
+ if (socket.readyState === WebSocket.OPEN) socket.close(code, reason);
113
+ else if (socket.readyState === WebSocket.CONNECTING) socket.terminate();
114
+ };
115
+ const fail = (error, code = 1011) => {
116
+ if (closed) return;
117
+ failure = error;
118
+ closed = true;
106
119
  if (!settled) rejectReady(error);
107
- if (!streamClosed) {
108
- streamClosed = true;
109
- controller?.error(error);
110
- }
111
- if (closeSocket) {
112
- if (socket.readyState === WebSocket.OPEN) socket.close(1011, "Provider stream failed");
113
- else if (socket.readyState === WebSocket.CONNECTING) socket.terminate();
120
+ if (active) {
121
+ clearTimeout(active.timer);
122
+ if (!active.audioDone) active.controller.error(error);
123
+ active.reject(error);
114
124
  }
125
+ closeSocket(code, code === 1e3 ? "Aborted" : "Provider stream failed");
115
126
  };
116
- const finishStream = () => {
117
- if (streamClosed) return;
118
- streamClosed = true;
119
- controller?.close();
120
- };
121
- const onAbort = () => {
122
- fail(request.signal.reason instanceof Error ? request.signal.reason : new DOMException("Realtime TTS aborted", "AbortError"), false);
123
- if (socket.readyState === WebSocket.OPEN) socket.close(1e3, "Aborted");
124
- else if (socket.readyState === WebSocket.CONNECTING) socket.terminate();
125
- };
127
+ const onAbort = () => fail(request.signal.reason instanceof Error ? request.signal.reason : new DOMException("Realtime TTS aborted", "AbortError"), 1e3);
126
128
  request.signal.addEventListener("abort", onAbort, { once: true });
129
+ if (request.signal.aborted) onAbort();
127
130
  socket.on("unexpected-response", (_request, response) => {
128
131
  fail(new TtsHandshakeError(response.statusCode ?? 0, parseRetryAfter(response.headers["retry-after"])));
129
132
  response.destroy();
130
133
  });
131
134
  socket.on("message", (data, isBinary) => {
132
- if (streamClosed || request.signal.aborted) return;
133
- if (isBinary) return;
135
+ if (closed || isBinary) return;
134
136
  let message;
135
137
  try {
136
138
  message = JSON.parse(rawText(data));
@@ -138,43 +140,54 @@ async function openStreamingTtsAttempt(request) {
138
140
  fail(/* @__PURE__ */ new Error("DashScope realtime TTS returned invalid JSON"));
139
141
  return;
140
142
  }
141
- if (message.type === "session.created") {
142
- socket.send(event("session.update", { session: {
143
- voice: request.voice,
144
- mode: "commit",
145
- language_type: "Auto",
146
- response_format: "pcm",
147
- sample_rate: 24e3,
148
- volume: request.volume,
149
- ...request.instructions ? {
150
- instructions: request.instructions,
151
- optimize_instructions: false
152
- } : {}
153
- } }));
154
- return;
155
- }
156
- if (message.type === "session.updated") {
143
+ if (message.type === "session.created") socket.send(event("session.update", { session: {
144
+ voice: request.voice,
145
+ mode: "commit",
146
+ language_type: "Auto",
147
+ response_format: "pcm",
148
+ sample_rate: 24e3,
149
+ volume: request.volume,
150
+ ...request.instructions ? {
151
+ instructions: request.instructions,
152
+ optimize_instructions: false
153
+ } : {}
154
+ } }));
155
+ else if (message.type === "session.updated" && !settled) {
157
156
  settled = true;
157
+ log.info({
158
+ model: request.model,
159
+ phase: "tts_connection_ready",
160
+ setupMs: Date.now() - startedAt
161
+ }, "Realtime TTS connection ready");
158
162
  resolveReady();
159
- socket.send(event("input_text_buffer.append", { text: request.text }));
160
- socket.send(event("input_text_buffer.commit"));
161
- return;
162
- }
163
- if (message.type === "response.audio.delta") {
164
- if (streamClosed) return;
163
+ } else if (message.type === "response.audio.delta" && active && !active.audioDone) {
165
164
  if (typeof message.delta !== "string") {
166
165
  fail(/* @__PURE__ */ new Error("DashScope realtime TTS returned invalid audio"));
167
166
  return;
168
167
  }
169
- controller?.enqueue(Buffer.from(message.delta, "base64"));
170
- return;
171
- }
172
- if (message.type === "response.audio.done") {
173
- finishStream();
174
- socket.send(event("session.finish"));
175
- return;
176
- }
177
- if (message.type === "error") {
168
+ const bytes = Buffer.from(message.delta, "base64");
169
+ if (!bytes.byteLength) return;
170
+ if (!active.firstAudio) {
171
+ active.firstAudio = true;
172
+ log.info({
173
+ model: request.model,
174
+ phase: "tts_first_audio",
175
+ synthesisMs: Date.now() - active.submittedAt
176
+ }, "Realtime TTS first audio received");
177
+ }
178
+ active.controller.enqueue(bytes);
179
+ } else if (message.type === "response.audio.done" && active && !active.audioDone) {
180
+ active.audioDone = true;
181
+ active.controller.close();
182
+ } else if (message.type === "response.done" && active) {
183
+ if (!active.audioDone) {
184
+ active.audioDone = true;
185
+ active.controller.close();
186
+ }
187
+ clearTimeout(active.timer);
188
+ active.resolve();
189
+ active = void 0;
190
+ } else if (message.type === "error") {
178
191
  const code = typeof message.error?.code === "string" ? message.error.code : void 0;
179
192
  const detail = typeof message.error?.message === "string" ? message.error.message : void 0;
180
193
  fail(new Error([code, detail].filter(Boolean).join(": ") || "DashScope realtime TTS failed"));
@@ -183,28 +196,71 @@ async function openStreamingTtsAttempt(request) {
183
196
  socket.on("error", (error) => fail(error));
184
197
  socket.on("close", () => {
185
198
  request.signal.removeEventListener("abort", onAbort);
186
- if (!streamClosed) fail(/* @__PURE__ */ new Error("DashScope realtime TTS connection closed unexpectedly"));
199
+ if (!closed) fail(/* @__PURE__ */ new Error("DashScope realtime TTS connection closed unexpectedly"));
187
200
  });
188
- const timeout = setTimeout(() => {
189
- fail(/* @__PURE__ */ new Error("DashScope realtime TTS setup timed out"));
190
- socket.close(1011, "Setup timeout");
191
- }, request.timeoutMs);
201
+ const timeout = setTimeout(() => fail(/* @__PURE__ */ new Error("DashScope realtime TTS setup timed out")), request.timeoutMs);
192
202
  try {
193
- await readyPromise;
203
+ await ready;
194
204
  } finally {
195
205
  clearTimeout(timeout);
196
206
  }
197
207
  return {
198
- audioStream,
199
- outputFormat: "pcm",
200
- fileExtension: "pcm",
201
- voiceCompatible: false,
202
- release: async () => {
203
- request.signal.removeEventListener("abort", onAbort);
204
- finishStream();
205
- if (socket.readyState === WebSocket.OPEN) socket.close(1e3, "Released");
208
+ async synthesize(text) {
209
+ request.signal.throwIfAborted();
210
+ if (closed) throw failure ?? /* @__PURE__ */ new Error("Realtime TTS session closed");
211
+ if (active) throw new Error("Realtime TTS synthesis already active");
212
+ let resolve;
213
+ let reject;
214
+ const done = new Promise((yes, no) => {
215
+ resolve = yes;
216
+ reject = no;
217
+ });
218
+ done.catch(() => {});
219
+ const audioStream = new ReadableStream({
220
+ start(controller) {
221
+ active = {
222
+ controller,
223
+ audioDone: false,
224
+ done,
225
+ resolve,
226
+ reject,
227
+ submittedAt: Date.now(),
228
+ firstAudio: false,
229
+ timer: setTimeout(() => fail(/* @__PURE__ */ new Error("Realtime TTS synthesis timed out")), request.timeoutMs)
230
+ };
231
+ },
232
+ cancel() {
233
+ fail(new DOMException("Realtime TTS consumer cancelled", "AbortError"), 1e3);
234
+ }
235
+ });
236
+ socket.send(event("input_text_buffer.append", { text }));
237
+ socket.send(event("input_text_buffer.commit"));
238
+ return {
239
+ audioStream,
240
+ outputFormat: "pcm",
241
+ fileExtension: "pcm",
242
+ voiceCompatible: false,
243
+ release: async () => {
244
+ await done;
245
+ }
246
+ };
247
+ },
248
+ async close() {
249
+ if (closed) return;
250
+ if (active && !active.audioDone) {
251
+ fail(new DOMException("Realtime TTS session released", "AbortError"), 1e3);
252
+ return;
253
+ }
254
+ if (active) {
255
+ clearTimeout(active.timer);
256
+ active.resolve();
257
+ active = void 0;
258
+ }
259
+ closed = true;
260
+ if (socket.readyState === WebSocket.OPEN) socket.send(event("session.finish"));
261
+ closeSocket(1e3, "Released");
206
262
  }
207
263
  };
208
264
  }
209
265
  //#endregion
210
- export { openDashScopeStreamingTts };
266
+ export { openDashScopeStreamingTts, openDashScopeTtsSession };
@@ -3,6 +3,7 @@ export type VoiceConfigFieldType = 'string' | 'password' | 'number' | 'boolean'
3
3
  export interface VoiceOptionMetadata {
4
4
  id: string;
5
5
  name: string;
6
+ displayNames?: Partial<Record<'zh-CN' | 'en', string>>;
6
7
  description?: string;
7
8
  gender?: string;
8
9
  style?: string;
@@ -24,6 +24,10 @@ export declare function requirePlatformVoiceModel(id: string, mode: VoiceModeCap
24
24
  id: string;
25
25
  name: string;
26
26
  languages: string[];
27
+ displayNames?: {
28
+ 'zh-CN'?: string;
29
+ en?: string;
30
+ };
27
31
  gender?: "female" | "male";
28
32
  style?: string;
29
33
  description?: string;
@@ -39,6 +39,7 @@ function voiceSettingsCatalog(config) {
39
39
  models: (source?.models ?? []).flatMap((model) => model.availability === "available" && model.voice ? [{
40
40
  id: model.id,
41
41
  name: model.name,
42
+ ...model.displayNames ? { displayNames: model.displayNames } : {},
42
43
  voice: model.voice
43
44
  }] : [])
44
45
  };
@@ -1,6 +1,6 @@
1
1
  import { createLogger } from "../../utils/logger/index.js";
2
2
  import { init_logger } from "../../utils/logger.js";
3
- import { speakStream } from "../tts/speak-core.js";
3
+ import { prepareSpeechStreamSession, speakStream } from "../tts/speak-core.js";
4
4
  import { AudioPlaybackWindow } from "./audio-playback-window.js";
5
5
  import { TurnCoordinator } from "./turnPolicy.js";
6
6
  import { PlaybackEchoCandidates } from "./playback-echo.js";
@@ -12,6 +12,7 @@ init_logger();
12
12
  const log = createLogger("Voice:Agent");
13
13
  const AGENT_TTS_MAX_SEGMENT_CHARACTERS = 180;
14
14
  const AGENT_TTS_MIN_SEGMENT_CHARACTERS = 24;
15
+ const FIRST_PHRASE_WAIT_MS = 300;
15
16
  const PLAYBACK_ECHO_TAIL_MS = 3e3;
16
17
  const TASK_UPDATE_QUIET_MS = 1500;
17
18
  function createAgentVoiceEngine(options) {
@@ -101,6 +102,7 @@ function createAgentVoiceEngine(options) {
101
102
  expiresAt: Date.now() + PLAYBACK_ECHO_TAIL_MS
102
103
  };
103
104
  activeResponse = void 0;
105
+ clearTimeout(response.firstPhraseTimer);
104
106
  response.abortController.abort(reason);
105
107
  send("response.cancelled", {
106
108
  responseId: response.id,
@@ -124,6 +126,42 @@ function createAgentVoiceEngine(options) {
124
126
  }
125
127
  function openSpeech(response, job) {
126
128
  if (job.opening) return job.opening;
129
+ if (response.firstSynthesisAtMs === void 0) {
130
+ response.firstSynthesisAtMs = Date.now();
131
+ log.info({
132
+ sessionId: claim.sessionId,
133
+ responseId: response.id,
134
+ conversationId: claim.request.conversationId,
135
+ phase: "first_synthesis_requested",
136
+ textToSynthesisMs: response.firstTextAtMs === void 0 ? void 0 : response.firstSynthesisAtMs - response.firstTextAtMs
137
+ }, "Realtime voice first synthesis requested");
138
+ }
139
+ if (response.preparedSpeech) {
140
+ job.opening = response.preparedSpeech.then(async (prepared) => {
141
+ if ("error" in prepared) return prepared;
142
+ response.abortController.signal.throwIfAborted();
143
+ if (response.firstSubmitAtMs === void 0) {
144
+ response.firstSubmitAtMs = Date.now();
145
+ log.info({
146
+ sessionId: claim.sessionId,
147
+ responseId: response.id,
148
+ conversationId: claim.request.conversationId,
149
+ phase: "first_tts_text_submitted",
150
+ phraseToSubmitMs: response.firstPhraseAtMs === void 0 ? void 0 : response.firstSubmitAtMs - response.firstPhraseAtMs
151
+ }, "Realtime voice first TTS text submitted");
152
+ }
153
+ const result = await prepared.session.synthesize(job.phrase);
154
+ return { result: {
155
+ ...result,
156
+ provider: claim.tts.config.provider,
157
+ release: result.release ?? (async () => {}),
158
+ ttsText: job.phrase,
159
+ wasPreprocessed: false,
160
+ wasSummarized: false
161
+ } };
162
+ }).catch((error) => ({ error }));
163
+ return job.opening;
164
+ }
127
165
  job.opening = speakStream(job.phrase, claim.tts.config, {
128
166
  appConfig: claim.config,
129
167
  parseDirectives: false,
@@ -133,6 +171,7 @@ function createAgentVoiceEngine(options) {
133
171
  return job.opening;
134
172
  }
135
173
  function prefetchNextSpeech(response) {
174
+ if (response.preparedSpeech) return;
136
175
  const next = response.speechQueue[0];
137
176
  if (!next || next.opening || response.abortController.signal.aborted) return;
138
177
  openSpeech(response, next);
@@ -165,6 +204,9 @@ function createAgentVoiceEngine(options) {
165
204
  phase: "first_response_audio",
166
205
  latencyMs: Date.now() - response.startedAt,
167
206
  inputToAudioMs: Date.now() - response.inputReceivedAtMs,
207
+ submitToAudioMs: response.firstSubmitAtMs === void 0 ? void 0 : Date.now() - response.firstSubmitAtMs,
208
+ synthesisToAudioMs: response.firstSynthesisAtMs === void 0 ? void 0 : Date.now() - response.firstSynthesisAtMs,
209
+ phraseToAudioMs: response.firstPhraseAtMs === void 0 ? void 0 : Date.now() - response.firstPhraseAtMs,
168
210
  textToAudioMs: response.firstTextAtMs === void 0 ? void 0 : Date.now() - response.firstTextAtMs
169
211
  }, "Realtime voice first audio ready");
170
212
  send("response.audio.started", {
@@ -233,6 +275,18 @@ function createAgentVoiceEngine(options) {
233
275
  function queuePhrases(response, phrases) {
234
276
  for (const phrase of phrases) {
235
277
  if (response.speechError || response.abortController.signal.aborted) return;
278
+ if (response.firstPhraseAtMs === void 0) {
279
+ response.firstPhraseAtMs = Date.now();
280
+ clearTimeout(response.firstPhraseTimer);
281
+ log.info({
282
+ sessionId: claim.sessionId,
283
+ responseId: response.id,
284
+ conversationId: claim.request.conversationId,
285
+ phase: "first_speech_phrase",
286
+ characters: phrase.length,
287
+ textToPhraseMs: response.firstTextAtMs === void 0 ? void 0 : response.firstPhraseAtMs - response.firstTextAtMs
288
+ }, "Realtime voice first speech phrase ready");
289
+ }
236
290
  if (response.queuedSpeechCharacters + phrase.length > 8e3) {
237
291
  response.speechError = /* @__PURE__ */ new Error("Voice synthesis queue limit reached");
238
292
  return;
@@ -275,6 +329,21 @@ function createAgentVoiceEngine(options) {
275
329
  activeResponse = response;
276
330
  send("response.created", { responseId: response.id });
277
331
  try {
332
+ const opening = prepareSpeechStreamSession(claim.tts.config, {
333
+ appConfig: claim.config,
334
+ signal: response.abortController.signal,
335
+ allowFallback: false
336
+ });
337
+ if (opening) response.preparedSpeech = opening.then((session) => {
338
+ log.info({
339
+ sessionId: claim.sessionId,
340
+ responseId: response.id,
341
+ conversationId: claim.request.conversationId,
342
+ phase: "response_tts_ready",
343
+ setupMs: Date.now() - response.startedAt
344
+ }, "Realtime voice TTS prepared");
345
+ return { session };
346
+ }, (error) => ({ error }));
278
347
  await interruptionWrites;
279
348
  if (response.abortController.signal.aborted || closed) return taskUpdateExposed();
280
349
  if (!claim.conversationSessionId) throw new Error("Conversation identity is unavailable");
@@ -320,6 +389,10 @@ function createAgentVoiceEngine(options) {
320
389
  delta: event.payload.delta
321
390
  });
322
391
  queuePhrases(response, response.segmenter.push(event.payload.delta));
392
+ if (response.firstPhraseAtMs === void 0 && response.firstPhraseTimer === void 0) response.firstPhraseTimer = setTimeout(() => {
393
+ response.firstPhraseTimer = void 0;
394
+ if (activeResponse === response && !response.abortController.signal.aborted) queuePhrases(response, response.segmenter.flushFirstPhrase());
395
+ }, FIRST_PHRASE_WAIT_MS);
323
396
  }
324
397
  if (event.type === "tool_start") queuePhrases(response, response.segmenter.flush());
325
398
  if ((event.type === "tool_start" || event.type === "tool_end") && typeof event.payload?.toolCallId === "string" && typeof event.payload?.toolName === "string") send("task.activity", {
@@ -410,7 +483,11 @@ function createAgentVoiceEngine(options) {
410
483
  if (activeResponse === response) activeResponse = void 0;
411
484
  return taskUpdateExposed();
412
485
  } finally {
486
+ clearTimeout(response.firstPhraseTimer);
413
487
  await waitForSpeech(response);
488
+ response.abortController.abort("response_finished");
489
+ const prepared = await response.preparedSpeech;
490
+ if (prepared && "session" in prepared) await prepared.session.close();
414
491
  }
415
492
  }
416
493
  async function openSttSession(consumed) {
@@ -8,6 +8,8 @@ export declare class SpeakableSegmenter {
8
8
  private emitted;
9
9
  constructor(maxCharacters?: number, minCharacters?: number, firstMinCharacters?: number);
10
10
  push(delta: string): string[];
11
+ /** Releases only a complete short phrase; never cuts a word or Markdown construct. */
12
+ flushFirstPhrase(): string[];
11
13
  flush(): string[];
12
14
  private toSpeech;
13
15
  }