@xopcai/xopc 0.0.210 → 0.0.213

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 (326) hide show
  1. package/dist/browser-ext/manifest.json +1 -1
  2. package/dist/extensions/telegram/xopc.extension.json +1 -1
  3. package/dist/gateway/static/root/assets/{activity-store-JLmEb1p0.js → activity-store-Xw-pOm9A.js} +1 -1
  4. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-CI1zQfzY.js → agent-avatar-dicebear-Ca1bciiK.js} +1 -1
  5. package/dist/gateway/static/root/assets/agents-DD3TqNrC.js +68 -0
  6. package/dist/gateway/static/root/assets/{api-C6MmWfcb.js → api-CZK-lRew.js} +1 -1
  7. package/dist/gateway/static/root/assets/{app-management-settings-panel-Cd02GGpV.js → app-management-settings-panel-BLFIG09j.js} +1 -1
  8. package/dist/gateway/static/root/assets/{appearance-settings-Db-h2I3G.js → appearance-settings-BsTWUq1i.js} +1 -1
  9. package/dist/gateway/static/root/assets/apps-page-cJkDKn72.js +1 -0
  10. package/dist/gateway/static/root/assets/{archive-plugin-CMHzJT2a.js → archive-plugin-B9LsFfEx.js} +1 -1
  11. package/dist/gateway/static/root/assets/{attachment-load-BzhI2LoH.js → attachment-load-CsWiFfmN.js} +1 -1
  12. package/dist/gateway/static/root/assets/automations-page-CbjU2e75.js +1 -0
  13. package/dist/gateway/static/root/assets/automations-workspace-C4xyo0c4.js +6 -0
  14. package/dist/gateway/static/root/assets/{binary-plugins-DsUeHvZO.js → binary-plugins-DbqhT_JB.js} +1 -1
  15. package/dist/gateway/static/root/assets/{block-editor-CFfsIeZ4.js → block-editor-BGpHwxZ5.js} +4 -4
  16. package/dist/gateway/static/root/assets/browser-settings-page-CrhpQl-e.js +8 -0
  17. package/dist/gateway/static/root/assets/{browser-workflow-inputs-BiWghvJ0.js → browser-workflow-inputs-BXlon_hL.js} +1 -1
  18. package/dist/gateway/static/root/assets/{browser-workflows-page-DPLdT6Zn.js → browser-workflows-page-B3BBDM_r.js} +2 -2
  19. package/dist/gateway/static/root/assets/capabilities-settings-panel-B9MoPW9u.js +7 -0
  20. package/dist/gateway/static/root/assets/{capability-presets-api-CTxGFvsS.js → capability-presets-api-BqvMm6UW.js} +1 -1
  21. package/dist/gateway/static/root/assets/capability-presets-settings-panel-BmwldV9R.js +3 -0
  22. package/dist/gateway/static/root/assets/{channel-recipient-api-BklVUOxC.js → channel-recipient-api-9uca5kDa.js} +1 -1
  23. package/dist/gateway/static/root/assets/channels-settings-CwLqWcy_.js +1 -0
  24. package/dist/gateway/static/root/assets/channels-status-swr-DeBw3du9.js +1 -0
  25. package/dist/gateway/static/root/assets/{chat-terminal-dock-0F4Jmma2.js → chat-terminal-dock-DJjYT3WX.js} +2 -2
  26. package/dist/gateway/static/root/assets/{chunk-KS7C4IRE-BMhrPKJC.js → chunk-KS7C4IRE-BaASWQor.js} +1 -1
  27. package/dist/gateway/static/root/assets/{connectors-api-BvIZ51ty.js → connectors-api-XCLfuDrN.js} +1 -1
  28. package/dist/gateway/static/root/assets/connectors-page-CVkGtcMS.js +2 -0
  29. package/dist/gateway/static/root/assets/{cron-expression-BHmwaMbO.js → cron-expression-DzQN7zBR.js} +1 -1
  30. package/dist/gateway/static/root/assets/{date-picker-fj_pPCv5.js → date-picker-B-r5O5qd.js} +1 -1
  31. package/dist/gateway/static/root/assets/{dependency-picker-DsWvwOv-.js → dependency-picker-Ch2XBU2s.js} +1 -1
  32. package/dist/gateway/static/root/assets/{desktop-pet-mjkF0Xxh.js → desktop-pet-BdjX8jde.js} +1 -1
  33. package/dist/gateway/static/root/assets/{desktop-pet-settings-ClwUpRYu.js → desktop-pet-settings-CzjjgMMn.js} +1 -1
  34. package/dist/gateway/static/root/assets/directory-picker-path-field-BCTgGTk4.js +1 -0
  35. package/dist/gateway/static/root/assets/{extension-debug-page-DC69wplH.js → extension-debug-page-6OGgOucD.js} +1 -1
  36. package/dist/gateway/static/root/assets/{extension-page-DCtk6zdJ.js → extension-page-Cf6MUfCF.js} +1 -1
  37. package/dist/gateway/static/root/assets/{extension-settings-page-Bkm4zzv-.js → extension-settings-page-pSY_ZvQZ.js} +1 -1
  38. package/dist/gateway/static/root/assets/{gateway-config-api-Dr_NQt7v.js → gateway-config-api-CFJMng9v.js} +1 -1
  39. package/dist/gateway/static/root/assets/{gateway-config-swr-CEfv8N1J.js → gateway-config-swr-DpiY6aub.js} +1 -1
  40. package/dist/gateway/static/root/assets/gateway-settings-aQYxNePf.js +1 -0
  41. package/dist/gateway/static/root/assets/{gateway-startup-retry-B8hebJ7s.js → gateway-startup-retry-BZ_6ChP4.js} +1 -1
  42. package/dist/gateway/static/root/assets/heartbeat-settings-CI33q9i1.js +1 -0
  43. package/dist/gateway/static/root/assets/home-page-CAIaWs6r.js +1 -0
  44. package/dist/gateway/static/root/assets/image-generation-api-DPndEWOU.js +1 -0
  45. package/dist/gateway/static/root/assets/index-BhstAl5i.js +108 -0
  46. package/dist/gateway/static/root/assets/index-DQzjgIkQ.css +2 -0
  47. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-DCQvf05d.js → keyboard-shortcuts-settings-CbLJRGXR.js} +1 -1
  48. package/dist/gateway/static/root/assets/local-app-workbench-page-BqFnCaKT.js +2 -0
  49. package/dist/gateway/static/root/assets/{local-apps-page-B3Ugd0my.js → local-apps-page-Crf6c3SK.js} +1 -1
  50. package/dist/gateway/static/root/assets/{locale-store-hDBVeG3G.js → locale-store-BYSRjM6g.js} +1 -1
  51. package/dist/gateway/static/root/assets/{logs-page-nXdF3wOT.js → logs-page-BpfLQWex.js} +2 -2
  52. package/dist/gateway/static/root/assets/{management-settings-C-S5Llq3.js → management-settings-mxyYWKgM.js} +1 -1
  53. package/dist/gateway/static/root/assets/{markdown-split-DuVq37Uh.js → markdown-split-kZaPrUTM.js} +1 -1
  54. package/dist/gateway/static/root/assets/markdown-view-DD_PgVue.css +1 -0
  55. package/dist/gateway/static/root/assets/{markdown-view-D8eO_6h3.js → markdown-view-DlsczsQ1.js} +1 -1
  56. package/dist/gateway/static/root/assets/{media-plugins-C1V6pkX3.js → media-plugins-Dk67jaG6.js} +1 -1
  57. package/dist/gateway/static/root/assets/messages-DyM8OOVG.js +3 -0
  58. package/dist/gateway/static/root/assets/notes-api-DaeeQw8A.js +1 -0
  59. package/dist/gateway/static/root/assets/{notes-page-Dn71ZV8c.js → notes-page-CQDzw8fX.js} +1 -1
  60. package/dist/gateway/static/root/assets/notes-workbench-BYiROmRJ.js +4 -0
  61. package/dist/gateway/static/root/assets/{page-tabs-B5a5aSoS.js → page-tabs-C4UkhX2U.js} +1 -1
  62. package/dist/gateway/static/root/assets/{preview-open-alternatives-5041AIBX.js → preview-open-alternatives-nzcjh6y0.js} +1 -1
  63. package/dist/gateway/static/root/assets/{product-open-page-7UkouFQU.js → product-open-page-3FvW5cHm.js} +1 -1
  64. package/dist/gateway/static/root/assets/project-detail-page-p45i1sMj.js +1 -0
  65. package/dist/gateway/static/root/assets/projects-page-Y9yXB4DX.js +1 -0
  66. package/dist/gateway/static/root/assets/registry-api-Bu6OGEY2.js +2 -0
  67. package/dist/gateway/static/root/assets/remote-access-hub-CNsGY0VS.js +1 -0
  68. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-DvaXzHYS.js → runtime-tools-settings-panel-CVqPSfUb.js} +2 -2
  69. package/dist/gateway/static/root/assets/{schema-form-Dlxl_5X0.js → schema-form-Dz6eZpqv.js} +1 -1
  70. package/dist/gateway/static/root/assets/sessions-page-BAtpgb1t.js +1 -0
  71. package/dist/gateway/static/root/assets/settings-advanced-gate-pgBQ21Oe.js +1 -0
  72. package/dist/gateway/static/root/assets/{settings-form-section-CSaiuuer.js → settings-form-section-BaWFAZv4.js} +1 -1
  73. package/dist/gateway/static/root/assets/{settings-loading-skeleton-H3mJwt3r.js → settings-loading-skeleton-BWmdZfNg.js} +1 -1
  74. package/dist/gateway/static/root/assets/{settings-page-Cs7zA4BS.js → settings-page-Btcb-Dc8.js} +1 -1
  75. package/dist/gateway/static/root/assets/setup-status-panel-BNllZUFP.js +1 -0
  76. package/dist/gateway/static/root/assets/{share-preview-page-Bdpw5m7M.js → share-preview-page-CGzY3S0N.js} +1 -1
  77. package/dist/gateway/static/root/assets/shares-settings-CncwbTHY.js +1 -0
  78. package/dist/gateway/static/root/assets/skill-reload-api-CcW2dhSW.js +1 -0
  79. package/dist/gateway/static/root/assets/{skills-page-Bup3Lg1Z.js → skills-page-Bi2IWpU0.js} +1 -1
  80. package/dist/gateway/static/root/assets/{skills-page.utils-D22ORR21.js → skills-page.utils-BancvwN2.js} +1 -1
  81. package/dist/gateway/static/root/assets/{system-settings-panel-GmtWsfjB.js → system-settings-panel-CihjIzWx.js} +1 -1
  82. package/dist/gateway/static/root/assets/task-detail-page-SSNFtY-d.js +1 -0
  83. package/dist/gateway/static/root/assets/{theme-store-CtY8RwMX.js → theme-store-D1_t_31B.js} +1 -1
  84. package/dist/gateway/static/root/assets/{typed-models-lib-C2aOdlEA.js → typed-models-lib-C2LhiQq5.js} +1 -1
  85. package/dist/gateway/static/root/assets/{use-autosave-DOj5i8d_.js → use-autosave-tf_8rxAK.js} +1 -1
  86. package/dist/gateway/static/root/assets/user-context-page-BnPTFEar.js +1 -0
  87. package/dist/gateway/static/root/assets/{voice-api-key-field-5WfurWYa.js → voice-api-key-field-DN-y7Zfe.js} +1 -1
  88. package/dist/gateway/static/root/assets/work-discovery-overlay-bqqH4aZ9.js +1 -0
  89. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-bBA8LinI.js → workflow-run-setup-panel-2H33iXOB.js} +2 -2
  90. package/dist/gateway/static/root/assets/workflows-page-BnfxRf1q.js +5 -0
  91. package/dist/gateway/static/root/index.html +13 -11
  92. package/dist/package.js +1 -1
  93. package/dist/src/agent/agent-manager.js +1 -1
  94. package/dist/src/agent/image/generation/providers/xopc-cloud.js +2 -1
  95. package/dist/src/agent/image/tool-model-config.js +15 -9
  96. package/dist/src/agent/memory/builtin-provider.js +0 -1
  97. package/dist/src/agent/memory/create-memory-manager.js +1 -1
  98. package/dist/src/agent/tools/image-generate-tool.js +23 -7
  99. package/dist/src/agent-runtime/index.js +1 -1
  100. package/dist/src/agent-runtime/runtime-profile.js +1 -1
  101. package/dist/src/auth/oauth/xopc-cloud.js +1 -1
  102. package/dist/src/capabilities/readiness/from-config.d.ts +10 -0
  103. package/dist/src/capabilities/readiness/from-config.js +128 -0
  104. package/dist/src/capabilities/readiness/index.d.ts +3 -0
  105. package/dist/src/capabilities/readiness/index.js +3 -0
  106. package/dist/src/capabilities/readiness/planner.d.ts +3 -0
  107. package/dist/src/capabilities/readiness/planner.js +56 -0
  108. package/dist/src/capabilities/readiness/types.d.ts +35 -0
  109. package/dist/src/capabilities/readiness/types.js +1 -0
  110. package/dist/src/cli/commands/agent.js +9 -0
  111. package/dist/src/cli/commands/auth.js +4 -3
  112. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  113. package/dist/src/cli/commands/models.js +2 -1
  114. package/dist/src/cli/commands/onboard/model.d.ts +3 -21
  115. package/dist/src/cli/commands/onboard/model.js +10 -86
  116. package/dist/src/cli/commands/tunnel.js +3 -3
  117. package/dist/src/cli/utils/oauth-login.d.ts +2 -0
  118. package/dist/src/cli/utils/oauth-login.js +9 -1
  119. package/dist/src/config/index.js +2 -2
  120. package/dist/src/config/paths-state.d.ts +2 -0
  121. package/dist/src/config/paths-state.js +5 -1
  122. package/dist/src/config/paths.d.ts +1 -1
  123. package/dist/src/config/paths.js +2 -2
  124. package/dist/src/config/schema.js +1 -1
  125. package/dist/src/connectors/composio-managed-client.d.ts +60 -0
  126. package/dist/src/connectors/composio-managed-client.js +135 -0
  127. package/dist/src/connectors/composio-managed-events.d.ts +41 -0
  128. package/dist/src/connectors/composio-managed-events.js +105 -0
  129. package/dist/src/connectors/composio-sessions.d.ts +3 -1
  130. package/dist/src/connectors/composio-sessions.js +15 -8
  131. package/dist/src/connectors/composio.js +10 -4
  132. package/dist/src/connectors/connected-source-cursor.d.ts +9 -0
  133. package/dist/src/connectors/connected-source-cursor.js +30 -0
  134. package/dist/src/connectors/connected-source-ingestion.js +128 -65
  135. package/dist/src/connectors/connected-source-normalizers.d.ts +1 -0
  136. package/dist/src/connectors/connected-source-normalizers.js +33 -2
  137. package/dist/src/connectors/connected-source-sanitization.d.ts +1 -0
  138. package/dist/src/connectors/connected-source-sanitization.js +21 -0
  139. package/dist/src/connectors/connector-identity.js +10 -2
  140. package/dist/src/connectors/content-enrichment.d.ts +29 -0
  141. package/dist/src/connectors/content-enrichment.js +273 -0
  142. package/dist/src/connectors/learning-coordinator.js +1 -2
  143. package/dist/src/connectors/learning-recipes.js +30 -33
  144. package/dist/src/connectors/runtime-adapter-registry.js +2 -2
  145. package/dist/src/discussions/live-worker.d.ts +1 -0
  146. package/dist/src/discussions/live-worker.js +7 -1
  147. package/dist/src/discussions/repository.js +11 -1
  148. package/dist/src/discussions/sealer.d.ts +1 -1
  149. package/dist/src/discussions/sealer.js +16 -7
  150. package/dist/src/discussions/service.js +6 -2
  151. package/dist/src/discussions/transcript.d.ts +2 -0
  152. package/dist/src/discussions/transcript.js +42 -3
  153. package/dist/src/discussions/types.d.ts +4 -0
  154. package/dist/src/extensions/install.d.ts +10 -0
  155. package/dist/src/extensions/install.js +111 -14
  156. package/dist/src/extensions/loader.js +22 -18
  157. package/dist/src/gateway/hono/app.js +8 -3
  158. package/dist/src/gateway/hono/lib/config-payload.js +1 -1
  159. package/dist/src/gateway/hono/middleware/auth.js +2 -2
  160. package/dist/src/gateway/hono/middleware/logger.js +1 -1
  161. package/dist/src/gateway/hono/middleware/strict-rate-limit.d.ts +4 -0
  162. package/dist/src/gateway/hono/middleware/strict-rate-limit.js +9 -2
  163. package/dist/src/gateway/hono/oauth-async.d.ts +11 -5
  164. package/dist/src/gateway/hono/oauth-async.js +29 -16
  165. package/dist/src/gateway/hono/oauth.d.ts +1 -3
  166. package/dist/src/gateway/hono/oauth.js +22 -22
  167. package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
  168. package/dist/src/gateway/hono/routes/config-patch/misc.js +1 -1
  169. package/dist/src/gateway/hono/routes/connectors.js +10 -3
  170. package/dist/src/gateway/hono/routes/deps.d.ts +1 -0
  171. package/dist/src/gateway/hono/routes/discussions.js +2 -1
  172. package/dist/src/gateway/hono/routes/exposure.js +1 -1
  173. package/dist/src/gateway/hono/routes/home.d.ts +1 -1
  174. package/dist/src/gateway/hono/routes/home.js +2 -2
  175. package/dist/src/gateway/hono/routes/lazy-bundles.js +2 -1
  176. package/dist/src/gateway/hono/routes/models.js +59 -5
  177. package/dist/src/gateway/hono/routes/shares.js +1 -1
  178. package/dist/src/gateway/hono/routes/tunnel.js +3 -3
  179. package/dist/src/gateway/hono/routes/understanding-sources.js +29 -0
  180. package/dist/src/gateway/hono/routes/voice.d.ts +1 -2
  181. package/dist/src/gateway/hono/routes/voice.js +16 -35
  182. package/dist/src/gateway/hono/routes/workflows.js +69 -0
  183. package/dist/src/gateway/index.js +2 -2
  184. package/dist/src/gateway/rate-limit/buckets.d.ts +3 -0
  185. package/dist/src/gateway/rate-limit/buckets.js +12 -0
  186. package/dist/src/gateway/runtime-config.js +2 -2
  187. package/dist/src/gateway/security/audit.js +2 -2
  188. package/dist/src/gateway/service/config-coordinator.js +1 -1
  189. package/dist/src/gateway/service/session-input-coordinator.js +1 -2
  190. package/dist/src/gateway/service.d.ts +1 -0
  191. package/dist/src/gateway/service.js +37 -7
  192. package/dist/src/knowledge/connected-understanding-pipeline.d.ts +1 -1
  193. package/dist/src/knowledge/connected-understanding-pipeline.js +74 -25
  194. package/dist/src/knowledge/ingestion-service.js +33 -15
  195. package/dist/src/knowledge/types.d.ts +2 -0
  196. package/dist/src/media-understanding/audio-transcription-runner.d.ts +2 -0
  197. package/dist/src/media-understanding/audio-transcription-runner.js +3 -1
  198. package/dist/src/media-understanding/runner.js +3 -1
  199. package/dist/src/media-understanding/types.d.ts +2 -0
  200. package/dist/src/notes/note-attachment-sync.js +1 -1
  201. package/dist/src/notes/service.d.ts +1 -0
  202. package/dist/src/notes/service.js +2 -1
  203. package/dist/src/notes/types.d.ts +2 -0
  204. package/dist/src/providers/model-catalog-persistence.d.ts +9 -0
  205. package/dist/src/providers/model-catalog-persistence.js +172 -0
  206. package/dist/src/providers/model-catalog-ranking.d.ts +2 -0
  207. package/dist/src/providers/model-catalog-ranking.js +17 -0
  208. package/dist/src/providers/model-catalog-store.d.ts +9 -57
  209. package/dist/src/providers/model-catalog-store.js +24 -5
  210. package/dist/src/providers/model-catalog-sync-service.d.ts +3 -3
  211. package/dist/src/providers/model-catalog-sync-service.js +12 -7
  212. package/dist/src/providers/model-catalog-types.d.ts +60 -0
  213. package/dist/src/providers/model-catalog-types.js +1 -0
  214. package/dist/src/providers/provider-auth-service.d.ts +1 -0
  215. package/dist/src/providers/provider-auth-service.js +3 -0
  216. package/dist/src/providers/provider-disconnect-core.d.ts +11 -0
  217. package/dist/src/providers/provider-disconnect-core.js +35 -0
  218. package/dist/src/providers/provider-disconnect.d.ts +3 -0
  219. package/dist/src/providers/provider-disconnect.js +11 -0
  220. package/dist/src/providers/xopc-cloud-catalog-coordinator.d.ts +56 -0
  221. package/dist/src/providers/xopc-cloud-catalog-coordinator.js +182 -0
  222. package/dist/src/providers/xopc-cloud-model-source.d.ts +6 -10
  223. package/dist/src/providers/xopc-cloud-model-source.js +49 -27
  224. package/dist/src/storage/sqlite/knowledge-repository.d.ts +1 -0
  225. package/dist/src/storage/sqlite/knowledge-repository.js +4 -0
  226. package/dist/src/storage/sqlite/migrations/124_workflow_context_snapshots.sql +15 -0
  227. package/dist/src/storage/sqlite/migrations/125_project_workflow_presets.sql +12 -0
  228. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  229. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  230. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  231. package/dist/src/storage/sqlite/schema.js +1 -1
  232. package/dist/src/storage/sqlite/user-context-quality-repository.d.ts +8 -0
  233. package/dist/src/storage/sqlite/user-context-quality-repository.js +21 -1
  234. package/dist/src/tasks/home-query-service.d.ts +12 -127
  235. package/dist/src/tasks/home-query-service.js +73 -271
  236. package/dist/src/tasks/index.js +2 -2
  237. package/dist/src/tui/backends/embedded-backend.js +11 -3
  238. package/dist/src/tui/tui-oauth-login.js +5 -0
  239. package/dist/src/tui/xopc-tui-keybindings.d.ts +2 -2
  240. package/dist/src/tunnel/index.js +2 -2
  241. package/dist/src/user-context/sources/activity-clustering.js +30 -117
  242. package/dist/src/user-context/sources/index.d.ts +1 -0
  243. package/dist/src/user-context/sources/index.js +2 -1
  244. package/dist/src/user-context/sources/signal-clustering.d.ts +18 -0
  245. package/dist/src/user-context/sources/signal-clustering.js +131 -0
  246. package/dist/src/voice/audio/normalize.d.ts +18 -0
  247. package/dist/src/voice/audio/normalize.js +175 -0
  248. package/dist/src/voice/language-profile.d.ts +1 -4
  249. package/dist/src/voice/language-profile.js +2 -25
  250. package/dist/src/voice/local/runtime-client.d.ts +2 -0
  251. package/dist/src/voice/local/runtime-client.js +20 -1
  252. package/dist/src/voice/local/runtime-worker.js +7 -13
  253. package/dist/src/voice/local/wav.d.ts +3 -0
  254. package/dist/src/voice/local/wav.js +11 -5
  255. package/dist/src/voice/stt/availability.d.ts +1 -4
  256. package/dist/src/voice/stt/availability.js +3 -15
  257. package/dist/src/voice/stt/config.js +1 -0
  258. package/dist/src/voice/stt/factory.js +23 -0
  259. package/dist/src/voice/stt/index.d.ts +1 -0
  260. package/dist/src/voice/stt/index.js +2 -2
  261. package/dist/src/voice/stt/list-providers.js +1 -1
  262. package/dist/src/voice/stt/providers/local-transcription.js +7 -3
  263. package/dist/src/voice/stt/providers/xopc-cloud-transcription.js +3 -1
  264. package/dist/src/voice/stt/transcribe-core.d.ts +5 -1
  265. package/dist/src/voice/stt/transcribe-core.js +13 -5
  266. package/dist/src/voice/stt/types.d.ts +2 -0
  267. package/dist/src/voice/tts/factory.d.ts +1 -1
  268. package/dist/src/voice/tts/factory.js +23 -1
  269. package/dist/src/voice/tts/merge-config.js +5 -3
  270. package/dist/src/voice/tts/providers/xopc-cloud-speech.js +3 -1
  271. package/dist/src/voice/tts/types.d.ts +2 -0
  272. package/dist/src/voice/tts/types.js +4 -2
  273. package/dist/src/work-discovery/evaluation.d.ts +23 -0
  274. package/dist/src/work-discovery/evaluation.js +18 -1
  275. package/dist/src/work-discovery/index.js +2 -2
  276. package/dist/src/work-discovery/service.js +6 -8
  277. package/dist/src/work-discovery/types.d.ts +2 -0
  278. package/dist/src/workflows/context/workflow-context-snapshot-repository.d.ts +21 -0
  279. package/dist/src/workflows/context/workflow-context-snapshot-repository.js +40 -0
  280. package/dist/src/workflows/context/workflow-context.d.ts +18 -0
  281. package/dist/src/workflows/context/workflow-context.js +159 -0
  282. package/dist/src/workflows/domain/run.d.ts +10 -1
  283. package/dist/src/workflows/engine/workflow-engine.d.ts +1 -0
  284. package/dist/src/workflows/engine/workflow-engine.js +2 -0
  285. package/dist/src/workflows/project-presets/project-workflow-preset-repository.d.ts +20 -0
  286. package/dist/src/workflows/project-presets/project-workflow-preset-repository.js +38 -0
  287. package/dist/src/workflows/service/workflow-run-service.d.ts +1 -0
  288. package/dist/src/workflows/service/workflow-run-service.js +107 -22
  289. package/dist/src/workflows/service/workflow-run-service.types.d.ts +1 -0
  290. package/dist/src/workflows/service/workflow-writeback-service.d.ts +9 -0
  291. package/dist/src/workflows/service/workflow-writeback-service.js +106 -0
  292. package/package.json +9 -8
  293. package/dist/gateway/static/root/assets/agents-DqGMj3QJ.js +0 -68
  294. package/dist/gateway/static/root/assets/apps-page-BT7F4WBI.js +0 -1
  295. package/dist/gateway/static/root/assets/automations-page-CwOXGV9z.js +0 -6
  296. package/dist/gateway/static/root/assets/browser-settings-page-CyRLhCod.js +0 -8
  297. package/dist/gateway/static/root/assets/capabilities-settings-panel-jRKcS7lZ.js +0 -7
  298. package/dist/gateway/static/root/assets/capability-presets-settings-panel-B3bKdtwU.js +0 -3
  299. package/dist/gateway/static/root/assets/channels-settings-yZBWH02s.js +0 -1
  300. package/dist/gateway/static/root/assets/channels-status-swr-C3zlimZd.js +0 -1
  301. package/dist/gateway/static/root/assets/connectors-page-OX4KvUkA.js +0 -2
  302. package/dist/gateway/static/root/assets/directory-picker-path-field-OkqRFyRL.js +0 -1
  303. package/dist/gateway/static/root/assets/gateway-settings-V1XVxjHa.js +0 -1
  304. package/dist/gateway/static/root/assets/heartbeat-settings-CWUBAQrE.js +0 -1
  305. package/dist/gateway/static/root/assets/home-page-D57cYRd3.js +0 -1
  306. package/dist/gateway/static/root/assets/index-DJ7HSgKs.js +0 -85
  307. package/dist/gateway/static/root/assets/index-PNBFdxHb.css +0 -2
  308. package/dist/gateway/static/root/assets/local-app-workbench-page-BbAiMZE1.js +0 -2
  309. package/dist/gateway/static/root/assets/markdown-view-B12xeflb.css +0 -1
  310. package/dist/gateway/static/root/assets/messages-1qg_hOOd.js +0 -3
  311. package/dist/gateway/static/root/assets/notes-workbench-BYPoZeRw.js +0 -4
  312. package/dist/gateway/static/root/assets/project-detail-page-D27nOKbo.js +0 -1
  313. package/dist/gateway/static/root/assets/projects-page-CdB5cJJ-.js +0 -1
  314. package/dist/gateway/static/root/assets/remote-access-hub-DFoZ3UNS.js +0 -1
  315. package/dist/gateway/static/root/assets/sessions-page-C1cbIcJ7.js +0 -1
  316. package/dist/gateway/static/root/assets/settings-advanced-gate-DnXRlQXS.js +0 -1
  317. package/dist/gateway/static/root/assets/setup-status-panel-CwgMODfJ.js +0 -1
  318. package/dist/gateway/static/root/assets/shares-settings-hlUgIkrp.js +0 -1
  319. package/dist/gateway/static/root/assets/skill-reload-api-DR31B_Gz.js +0 -1
  320. package/dist/gateway/static/root/assets/task-detail-page-CTKDpxhf.js +0 -1
  321. package/dist/gateway/static/root/assets/user-context-page-keJJYpix.js +0 -1
  322. package/dist/gateway/static/root/assets/work-discovery-overlay-D5_MH3n3.js +0 -1
  323. package/dist/gateway/static/root/assets/work-discovery-page-BcvBiebt.js +0 -1
  324. package/dist/gateway/static/root/assets/workflows-page-Cz2VpWdj.js +0 -5
  325. package/dist/src/voice/local/runtime-dispatcher.d.ts +0 -9
  326. package/dist/src/voice/local/runtime-dispatcher.js +0 -20
@@ -1,6 +1,5 @@
1
1
  import { getLocalVoiceModel, resolveLocalVoiceModelDir } from "./models.js";
2
2
  import { downloadLocalVoiceModelFiles } from "./model-files.js";
3
- import { createRuntimeDispatcher } from "./runtime-dispatcher.js";
4
3
  import { join, resolve, sep } from "node:path";
5
4
  import { mkdir, rm } from "node:fs/promises";
6
5
  import { EnvHttpProxyAgent, RetryAgent, setGlobalDispatcher } from "undici";
@@ -230,17 +229,6 @@ async function handle(request) {
230
229
  throw new Error(`Unknown local voice runtime method: ${request.method}`);
231
230
  }
232
231
  const lines = createInterface({ input: process.stdin });
233
- const dispatch = createRuntimeDispatcher({
234
- execute: handle,
235
- sendResult: (request, result) => send({
236
- id: request.id,
237
- result
238
- }),
239
- sendError: (request, error) => send({
240
- id: request.id,
241
- error: serializeError(error)
242
- })
243
- });
244
232
  lines.on("line", (line) => {
245
233
  let request;
246
234
  try {
@@ -248,7 +236,13 @@ lines.on("line", (line) => {
248
236
  } catch {
249
237
  return;
250
238
  }
251
- dispatch(request);
239
+ handle(request).then((result) => send({
240
+ id: request.id,
241
+ result
242
+ }), (error) => send({
243
+ id: request.id,
244
+ error: serializeError(error)
245
+ }));
252
246
  });
253
247
  lines.once("close", () => {
254
248
  networkAgent.close().finally(() => process.exit(0));
@@ -3,4 +3,7 @@ export interface DecodedPcmAudio {
3
3
  sampleRate: number;
4
4
  durationSeconds: number;
5
5
  }
6
+ export declare class UnsupportedWavEncodingError extends Error {
7
+ constructor(message: string);
8
+ }
6
9
  export declare function decodeWavToMonoFloat32(buffer: Buffer, targetRate?: number): DecodedPcmAudio;
@@ -1,4 +1,10 @@
1
1
  //#region src/voice/local/wav.ts
2
+ var UnsupportedWavEncodingError = class extends Error {
3
+ constructor(message) {
4
+ super(message);
5
+ this.name = "UnsupportedWavEncodingError";
6
+ }
7
+ };
2
8
  function readChunkId(buffer, offset) {
3
9
  return buffer.toString("ascii", offset, offset + 4);
4
10
  }
@@ -17,7 +23,7 @@ function resampleLinear(input, sourceRate, targetRate) {
17
23
  return output;
18
24
  }
19
25
  function decodeWavToMonoFloat32(buffer, targetRate = 16e3) {
20
- if (buffer.length < 44 || readChunkId(buffer, 0) !== "RIFF" || readChunkId(buffer, 8) !== "WAVE") throw new Error("Local STT currently requires PCM WAV audio");
26
+ if (buffer.length < 44 || readChunkId(buffer, 0) !== "RIFF" || readChunkId(buffer, 8) !== "WAVE") throw new Error("Unsupported or corrupt WAV audio");
21
27
  let offset = 12;
22
28
  let format;
23
29
  let dataOffset = -1;
@@ -41,9 +47,9 @@ function decodeWavToMonoFloat32(buffer, targetRate = 16e3) {
41
47
  offset = bodyOffset + length + length % 2;
42
48
  }
43
49
  if (!format || dataOffset < 0 || dataLength === 0) throw new Error("WAV audio is missing format or data chunks");
44
- if (format.channels < 1 || format.channels > 8 || format.sampleRate < 8e3) throw new Error("Unsupported WAV channel count or sample rate");
50
+ if (format.channels < 1 || format.channels > 8 || format.sampleRate < 8e3) throw new UnsupportedWavEncodingError("Unsupported WAV channel count or sample rate");
45
51
  const bytesPerSample = format.bitsPerSample / 8;
46
- if (!Number.isInteger(bytesPerSample) || bytesPerSample < 2) throw new Error(`Unsupported WAV bit depth: ${format.bitsPerSample}`);
52
+ if (!Number.isInteger(bytesPerSample) || bytesPerSample < 2) throw new UnsupportedWavEncodingError(`Unsupported WAV bit depth: ${format.bitsPerSample}`);
47
53
  const frameBytes = bytesPerSample * format.channels;
48
54
  const frameCount = Math.floor(dataLength / frameBytes);
49
55
  const mono = new Float32Array(frameCount);
@@ -53,7 +59,7 @@ function decodeWavToMonoFloat32(buffer, targetRate = 16e3) {
53
59
  const sampleOffset = dataOffset + frame * frameBytes + channel * bytesPerSample;
54
60
  if (format.audioFormat === 1 && format.bitsPerSample === 16) sum += buffer.readInt16LE(sampleOffset) / 32768;
55
61
  else if (format.audioFormat === 3 && format.bitsPerSample === 32) sum += buffer.readFloatLE(sampleOffset);
56
- else throw new Error(`Unsupported WAV encoding: format ${format.audioFormat}, ${format.bitsPerSample}-bit`);
62
+ else throw new UnsupportedWavEncodingError(`Unsupported WAV encoding: format ${format.audioFormat}, ${format.bitsPerSample}-bit`);
57
63
  }
58
64
  mono[frame] = Math.max(-1, Math.min(1, sum / format.channels));
59
65
  }
@@ -64,4 +70,4 @@ function decodeWavToMonoFloat32(buffer, targetRate = 16e3) {
64
70
  };
65
71
  }
66
72
  //#endregion
67
- export { decodeWavToMonoFloat32 };
73
+ export { UnsupportedWavEncodingError, decodeWavToMonoFloat32 };
@@ -1,8 +1,5 @@
1
1
  import type { STTConfig } from './types.js';
2
2
  /**
3
- * Lightweight availability check for channel routing. Do not import the STT
4
- * factory/provider registry here; channel plugins call this at startup and the
5
- * provider registry pulls optional SDKs (e.g. openai) into Electron's dynamic
6
- * extension runtime path.
3
+ * Runtime-truth availability check shared by channels and the gateway.
7
4
  */
8
5
  export declare function isSTTAvailable(config?: STTConfig): boolean;
@@ -1,23 +1,11 @@
1
- import { getVoiceProviderMetadata } from "../metadata/registry.js";
2
- import "../metadata/index.js";
1
+ import { resolveSTTProviderChain } from "./factory.js";
3
2
  //#region src/voice/stt/availability.ts
4
- function providerHasConfig(config, providerId) {
5
- const provider = config.providers?.[providerId];
6
- if (provider && Object.keys(provider).length > 0) return true;
7
- if ([...config.models ?? [], ...config.sharedModels ?? []].some((entry) => entry.provider === providerId && entry.capabilities?.includes("audio"))) return true;
8
- return getVoiceProviderMetadata("stt", providerId)?.diagnostics.requiresApiKey === false;
9
- }
10
3
  /**
11
- * Lightweight availability check for channel routing. Do not import the STT
12
- * factory/provider registry here; channel plugins call this at startup and the
13
- * provider registry pulls optional SDKs (e.g. openai) into Electron's dynamic
14
- * extension runtime path.
4
+ * Runtime-truth availability check shared by channels and the gateway.
15
5
  */
16
6
  function isSTTAvailable(config) {
17
7
  if (!config?.enabled) return false;
18
- if (providerHasConfig(config, config.provider)) return true;
19
- if (config.fallback?.enabled) return config.fallback.order.some((providerId) => providerHasConfig(config, providerId));
20
- return false;
8
+ return resolveSTTProviderChain(config).length > 0;
21
9
  }
22
10
  //#endregion
23
11
  export { isSTTAvailable };
@@ -14,6 +14,7 @@ function mergeSttConfigFromAppConfig(stt, toolsMedia) {
14
14
  return {
15
15
  ...DEFAULT_STT_CONFIG,
16
16
  ...patch,
17
+ managedAuto: stt === void 0,
17
18
  providers: mergeSttProviders(DEFAULT_STT_CONFIG.providers, patch.providers),
18
19
  fallback: {
19
20
  ...DEFAULT_STT_CONFIG.fallback,
@@ -1,11 +1,14 @@
1
1
  import { createLogger } from "../../utils/logger/index.js";
2
2
  import { init_logger } from "../../utils/logger.js";
3
+ import { getModelCatalogStore, init_model_catalog_store } from "../../providers/model-catalog-store.js";
4
+ import { compareCatalogModels } from "../../providers/model-catalog-ranking.js";
3
5
  import { getMediaUnderstandingProvider, listMediaUnderstandingProviders } from "../../media-understanding/registry.js";
4
6
  import "./providers/index.js";
5
7
  import { resolveModelEntries } from "../../media-understanding/resolve-entries.js";
6
8
  import { readSttProviderFields, resolveSttProviderConfigSlice } from "./config-slice.js";
7
9
  //#region src/voice/stt/factory.ts
8
10
  init_logger();
11
+ init_model_catalog_store();
9
12
  const log = createLogger("STT:Factory");
10
13
  function resolveApiKey(providerId, fields, envKey) {
11
14
  return fields.apiKey ?? (envKey ? process.env[envKey] : void 0);
@@ -54,6 +57,7 @@ function resolveSTTProviderOrder(primary, fallback, config) {
54
57
  for (const providerId of fallback.order) if (providerId !== primary && !order.includes(providerId)) order.push(providerId);
55
58
  return order;
56
59
  }
60
+ if (!config.managedAuto) return [primary];
57
61
  const configured = sortAudioProvidersByAutoPriority(listMediaUnderstandingProviders()).filter((providerId) => resolveSTTProviderConfig(providerId, config) !== null);
58
62
  const order = [primary];
59
63
  for (const providerId of configured) if (providerId !== primary && !order.includes(providerId)) order.push(providerId);
@@ -72,8 +76,23 @@ function resolveModelEntryChain(config) {
72
76
  const resolved = resolveSTTProviderConfig(providerId, config, entry);
73
77
  if (resolved) chain.push(resolved);
74
78
  }
79
+ if (chain.some((entry) => entry.id === "xopc-cloud")) appendManagedCloudModels(chain, config);
75
80
  return chain;
76
81
  }
82
+ function appendManagedCloudModels(chain, config) {
83
+ const seen = new Set(chain.filter((entry) => entry.id === "xopc-cloud" && entry.model).map((entry) => entry.model));
84
+ const source = getModelCatalogStore().getSource("xopc-cloud");
85
+ const models = [...source?.models ?? []].sort((left, right) => compareCatalogModels(left, right, source?.recommended?.stt));
86
+ for (const model of models) {
87
+ if (model.availability !== "available" || model.kind !== "stt" || !model.operations.includes("audio.transcription") || seen.has(model.id)) continue;
88
+ const resolved = resolveSTTProviderConfig("xopc-cloud", config, {
89
+ provider: "xopc-cloud",
90
+ model: model.id,
91
+ capabilities: ["audio"]
92
+ });
93
+ if (resolved) chain.push(resolved);
94
+ }
95
+ }
77
96
  /** Build the full chain of resolved provider configs in priority order. */
78
97
  function resolveSTTProviderChain(config) {
79
98
  if (!config.enabled) return [];
@@ -82,6 +101,10 @@ function resolveSTTProviderChain(config) {
82
101
  const order = resolveSTTProviderOrder(config.provider, config.fallback, config);
83
102
  const chain = [];
84
103
  for (const providerId of order) {
104
+ if (providerId === "xopc-cloud") {
105
+ appendManagedCloudModels(chain, config);
106
+ continue;
107
+ }
85
108
  const resolved = resolveSTTProviderConfig(providerId, config);
86
109
  if (resolved) chain.push(resolved);
87
110
  }
@@ -7,6 +7,7 @@
7
7
  import './providers/index.js';
8
8
  import type { STTConfig, STTOptions, STTResult } from './types.js';
9
9
  export { transcribe } from './transcribe-core.js';
10
+ export { STTTranscriptionError } from './transcribe-core.js';
10
11
  export { isSTTAvailable } from './availability.js';
11
12
  export { mergeSttConfigFromAppConfig } from './config.js';
12
13
  /**
@@ -2,7 +2,7 @@ import { openAiTranscriptionProvider } from "./providers/openai-transcription.js
2
2
  import { alibabaTranscriptionProvider } from "./providers/alibaba-transcription.js";
3
3
  import "./providers/index.js";
4
4
  import { resolveSTTProviderChain, resolveSTTProviderConfig, resolveSTTProviderOrder } from "./factory.js";
5
- import { transcribe } from "./transcribe-core.js";
5
+ import { STTTranscriptionError, transcribe } from "./transcribe-core.js";
6
6
  import { isSTTAvailable } from "./availability.js";
7
7
  import { mergeSttConfigFromAppConfig } from "./config.js";
8
8
  import { checkMentionInTranscription } from "./mention.js";
@@ -29,4 +29,4 @@ async function transcribeWithProvider(audioBuffer, providerName, config, options
29
29
  };
30
30
  }
31
31
  //#endregion
32
- export { alibabaTranscriptionProvider, audioPreflightTranscribe, checkMentionInTranscription, isSTTAvailable, mergeSttConfigFromAppConfig, openAiTranscriptionProvider, resolveSTTProviderChain, resolveSTTProviderConfig, resolveSTTProviderOrder, transcribe, transcribeWithProvider };
32
+ export { STTTranscriptionError, alibabaTranscriptionProvider, audioPreflightTranscribe, checkMentionInTranscription, isSTTAvailable, mergeSttConfigFromAppConfig, openAiTranscriptionProvider, resolveSTTProviderChain, resolveSTTProviderConfig, resolveSTTProviderOrder, transcribe, transcribeWithProvider };
@@ -1,8 +1,8 @@
1
1
  import { listMediaUnderstandingProviders } from "../../media-understanding/registry.js";
2
2
  import { resolveSTTProviderConfig } from "./factory.js";
3
+ import { mergeSttConfigFromAppConfig } from "./config.js";
3
4
  import { getVoiceProviderMetadata } from "../metadata/registry.js";
4
5
  import "../metadata/index.js";
5
- import { mergeSttConfigFromAppConfig } from "./config.js";
6
6
  //#region src/voice/stt/list-providers.ts
7
7
  function fallbackMetadata(providerId, aliases) {
8
8
  return {
@@ -1,16 +1,19 @@
1
1
  import { createLogger } from "../../../utils/logger/index.js";
2
2
  import { init_logger } from "../../../utils/logger.js";
3
- import { registerMediaUnderstandingProvider } from "../../../media-understanding/registry.js";
4
3
  import { DEFAULT_LOCAL_VOICE_MODEL_ID, getLocalVoiceModel, hasInstalledLocalVoiceModel, isLocalVoiceModelInstalled } from "../../local/models.js";
4
+ import { registerMediaUnderstandingProvider } from "../../../media-understanding/registry.js";
5
5
  import { getLocalVoiceRuntimeClient } from "../../local/runtime-client.js";
6
- import { decodeWavToMonoFloat32 } from "../../local/wav.js";
6
+ import { decodeAudioToMonoFloat32 } from "../../audio/normalize.js";
7
7
  //#region src/voice/stt/providers/local-transcription.ts
8
8
  init_logger();
9
9
  const log = createLogger("STT:Local");
10
10
  async function transcribeAudio(req) {
11
11
  const model = getLocalVoiceModel(req.model);
12
12
  if (!isLocalVoiceModelInstalled(model.id)) throw new Error(`Local voice model "${model.id}" is not installed`);
13
- const decoded = decodeWavToMonoFloat32(req.buffer);
13
+ const decoded = await decodeAudioToMonoFloat32({
14
+ buffer: req.buffer,
15
+ signal: req.signal
16
+ });
14
17
  const audioBytes = Buffer.from(decoded.samples.buffer, decoded.samples.byteOffset, decoded.samples.byteLength);
15
18
  const startedAt = Date.now();
16
19
  const result = await getLocalVoiceRuntimeClient().request("transcribe", {
@@ -25,6 +28,7 @@ async function transcribeAudio(req) {
25
28
  model: model.id,
26
29
  audioDurationSeconds: decoded.durationSeconds,
27
30
  latencyMs: Date.now() - startedAt,
31
+ realTimeFactor: decoded.durationSeconds > 0 ? (Date.now() - startedAt) / 1e3 / decoded.durationSeconds : void 0,
28
32
  textLength: result.text.length
29
33
  }, "Local transcription completed");
30
34
  return {
@@ -1,13 +1,15 @@
1
1
  import { getModelCatalogStore, init_model_catalog_store } from "../../../providers/model-catalog-store.js";
2
2
  import { init_xopc_cloud_config, resolveXopcModelRouterUrl } from "../../../providers/xopc-cloud-config.js";
3
3
  import { getProviderAuthService, init_provider_auth_service } from "../../../providers/provider-auth-service.js";
4
+ import { compareCatalogModels } from "../../../providers/model-catalog-ranking.js";
4
5
  import { registerMediaUnderstandingProvider } from "../../../media-understanding/registry.js";
5
6
  //#region src/voice/stt/providers/xopc-cloud-transcription.ts
6
7
  init_model_catalog_store();
7
8
  init_provider_auth_service();
8
9
  init_xopc_cloud_config();
9
10
  function defaultModel() {
10
- return getModelCatalogStore().getSource("xopc-cloud")?.models.find((model) => model.availability === "available" && model.kind === "stt")?.id;
11
+ const source = getModelCatalogStore().getSource("xopc-cloud");
12
+ return source?.models.filter((model) => model.availability === "available" && model.kind === "stt").sort((left, right) => compareCatalogModels(left, right, source.recommended?.stt))[0]?.id;
11
13
  }
12
14
  const xopcCloudTranscriptionProvider = {
13
15
  id: "xopc-cloud",
@@ -11,5 +11,9 @@
11
11
  * wrap the input as a single CapabilityAttachmentInput and unpack the first
12
12
  * output. Multi-attachment cases go through `runAudioTranscription` directly.
13
13
  */
14
- import type { STTConfig, STTOptions, STTResultWithTracking } from './types.js';
14
+ import type { STTConfig, STTOptions, STTProviderFailureReason, STTResultWithTracking } from './types.js';
15
+ export declare class STTTranscriptionError extends Error {
16
+ readonly reasonCode: STTProviderFailureReason;
17
+ constructor(message: string, reasonCode: STTProviderFailureReason);
18
+ }
15
19
  export declare function transcribe(audioBuffer: Buffer, config: STTConfig, options?: STTOptions): Promise<STTResultWithTracking>;
@@ -10,9 +10,16 @@ function classifyFailureReason(reason) {
10
10
  const lower = reason.toLowerCase();
11
11
  if (lower.includes("not configured") || lower.includes("api key") || lower.includes("missing")) return "not_configured";
12
12
  if (lower.includes("timeout") || lower.includes("timed out") || lower.includes("aborted")) return "timeout";
13
- if (lower.includes("unsupported") || lower.includes("format")) return "unsupported_format";
13
+ if (lower.includes("unsupported") || lower.includes("format") || lower.includes("audio decoder")) return "unsupported_format";
14
14
  return "provider_error";
15
15
  }
16
+ var STTTranscriptionError = class extends Error {
17
+ constructor(message, reasonCode) {
18
+ super(message);
19
+ this.reasonCode = reasonCode;
20
+ this.name = "STTTranscriptionError";
21
+ }
22
+ };
16
23
  function toAttempt(attempt) {
17
24
  return {
18
25
  provider: attempt.provider ?? "unknown",
@@ -49,8 +56,8 @@ async function transcribe(audioBuffer, config, options) {
49
56
  attempts,
50
57
  attemptedProviders
51
58
  }, "All STT providers failed");
52
- const lastError = attempts.find((a) => a.task === "failed")?.error;
53
- throw new Error(lastError ?? "All STT providers failed");
59
+ const lastFailure = attempts.findLast((attempt) => attempt.task === "failed");
60
+ throw new STTTranscriptionError(lastFailure?.error ?? "All STT providers failed", lastFailure?.reasonCode ?? "unknown");
54
61
  }
55
62
  const chosen = attachmentDecision.chosen;
56
63
  const output = result.outputs[0];
@@ -60,11 +67,12 @@ async function transcribe(audioBuffer, config, options) {
60
67
  return {
61
68
  text: output.text,
62
69
  provider: chosen.provider ?? "unknown",
63
- ...chosen.model ? { language: options?.language } : {},
70
+ ...output.durationSeconds !== void 0 ? { duration: output.durationSeconds } : {},
71
+ ...output.language || options?.language ? { language: output.language ?? options?.language } : {},
64
72
  attempts,
65
73
  ...fallbackFrom ? { fallbackFrom } : {},
66
74
  attemptedProviders
67
75
  };
68
76
  }
69
77
  //#endregion
70
- export { transcribe };
78
+ export { STTTranscriptionError, transcribe };
@@ -31,6 +31,8 @@ import type { MediaUnderstandingModelEntry } from '../../media-understanding/typ
31
31
  export interface STTConfig {
32
32
  enabled: boolean;
33
33
  provider: string;
34
+ /** Runtime-only flag: absent app config enables managed provider selection. */
35
+ managedAuto?: boolean;
34
36
  /** Capability-local model chain (`tools.media.audio.models`). */
35
37
  models?: MediaUnderstandingModelEntry[];
36
38
  /** Shared model entries merged from `tools.media.models` at runtime. */
@@ -23,7 +23,7 @@ export interface ResolvedSpeechProvider {
23
23
  timeoutMs: number;
24
24
  }
25
25
  /** Resolve a single provider id → plugin + per-call config, or null if unavailable. */
26
- export declare function resolveSpeechProvider(providerId: TTSProvider, config: TTSConfig): ResolvedSpeechProvider | null;
26
+ export declare function resolveSpeechProvider(providerId: TTSProvider, config: TTSConfig, providerOverride?: Record<string, unknown>): ResolvedSpeechProvider | null;
27
27
  /** Order providers: explicit fallback when enabled, otherwise auto-select by registry order. */
28
28
  export declare function resolveProviderOrder(primary: TTSProvider, fallback: TTSConfig['fallback'] | undefined, config: TTSConfig): TTSProvider[];
29
29
  /** Resolve the full provider chain in priority order; only configured plugins included. */
@@ -1,19 +1,26 @@
1
1
  import { createLogger } from "../../utils/logger/index.js";
2
2
  import { init_logger } from "../../utils/logger.js";
3
+ import { getModelCatalogStore, init_model_catalog_store } from "../../providers/model-catalog-store.js";
4
+ import { compareCatalogModels } from "../../providers/model-catalog-ranking.js";
3
5
  import { getSpeechProvider, listSpeechProviders } from "./speech-registry.js";
4
6
  import "./providers/index.js";
5
7
  import { buildTtsResolveRawConfig } from "./config-slice.js";
6
8
  //#region src/voice/tts/factory.ts
7
9
  init_logger();
10
+ init_model_catalog_store();
8
11
  const log = createLogger("TTS:Factory");
9
12
  /** Resolve a single provider id → plugin + per-call config, or null if unavailable. */
10
- function resolveSpeechProvider(providerId, config) {
13
+ function resolveSpeechProvider(providerId, config, providerOverride) {
11
14
  const plugin = getSpeechProvider(providerId);
12
15
  if (!plugin) {
13
16
  log.warn({ providerId }, `Unknown TTS provider "${providerId}" (not registered)`);
14
17
  return null;
15
18
  }
16
19
  const rawConfig = buildTtsResolveRawConfig(providerId, config);
20
+ if (providerOverride) rawConfig[providerId] = {
21
+ ...rawConfig[providerId] ?? {},
22
+ ...providerOverride
23
+ };
17
24
  const timeoutMs = config.timeoutMs ?? 3e4;
18
25
  const providerConfig = plugin.resolveConfig({
19
26
  cfg: void 0,
@@ -41,6 +48,7 @@ function resolveProviderOrder(primary, fallback, config) {
41
48
  for (const provider of fallback.order) if (provider !== primary && !order.includes(provider)) order.push(provider);
42
49
  return order;
43
50
  }
51
+ if (!config.managedAuto) return [primary];
44
52
  const configured = listSpeechProviders().map((plugin) => {
45
53
  return resolveSpeechProvider(plugin.id, config) ? plugin : null;
46
54
  }).filter((plugin) => plugin !== null).sort((left, right) => {
@@ -59,6 +67,20 @@ function resolveSpeechProviderChain(config) {
59
67
  const order = resolveProviderOrder(config.provider, config.fallback, config);
60
68
  const chain = [];
61
69
  for (const providerId of order) {
70
+ if (providerId === "xopc-cloud") {
71
+ const configuredModel = typeof config.providers?.["xopc-cloud"]?.model === "string" ? config.providers["xopc-cloud"].model : void 0;
72
+ const source = getModelCatalogStore().getSource("xopc-cloud");
73
+ const models = source?.models.filter((model) => model.availability === "available" && model.kind === "tts" && model.operations.includes("audio.speech") && Boolean(model.tts?.defaultVoice)).sort((left, right) => {
74
+ if (left.id === configuredModel) return -1;
75
+ if (right.id === configuredModel) return 1;
76
+ return compareCatalogModels(left, right, source.recommended?.tts);
77
+ }) ?? [];
78
+ for (const model of models) {
79
+ const resolved = resolveSpeechProvider(providerId, config, { model: model.id });
80
+ if (resolved) chain.push(resolved);
81
+ }
82
+ continue;
83
+ }
62
84
  const resolved = resolveSpeechProvider(providerId, config);
63
85
  if (resolved) chain.push(resolved);
64
86
  }
@@ -24,15 +24,17 @@ function mergeProviderEntries(base, patch) {
24
24
  }
25
25
  function mergeTtsConfigFromAppConfig(tts) {
26
26
  const p = tts ?? {};
27
+ const managedAuto = tts === void 0;
27
28
  return {
28
29
  ...DEFAULT_TTS_CONFIG,
29
30
  ...p,
31
+ managedAuto,
30
32
  enabled: p.enabled ?? DEFAULT_TTS_CONFIG.enabled,
31
33
  provider: normalizeTtsProvider(p.provider),
32
34
  trigger: normalizeTtsTrigger(p.trigger ?? DEFAULT_TTS_CONFIG.trigger),
33
- fallback: {
34
- ...DEFAULT_TTS_CONFIG.fallback,
35
- ...p.fallback
35
+ fallback: managedAuto ? { ...DEFAULT_TTS_CONFIG.fallback } : p.fallback ? { ...p.fallback } : {
36
+ enabled: false,
37
+ order: []
36
38
  },
37
39
  modelOverrides: {
38
40
  ...DEFAULT_TTS_CONFIG.modelOverrides,
@@ -1,13 +1,15 @@
1
1
  import { getModelCatalogStore, init_model_catalog_store } from "../../../providers/model-catalog-store.js";
2
2
  import { init_xopc_cloud_config, resolveXopcModelRouterUrl } from "../../../providers/xopc-cloud-config.js";
3
3
  import { getProviderAuthService, init_provider_auth_service } from "../../../providers/provider-auth-service.js";
4
+ import { compareCatalogModels } from "../../../providers/model-catalog-ranking.js";
4
5
  import { registerSpeechProvider } from "../speech-registry.js";
5
6
  //#region src/voice/tts/providers/xopc-cloud-speech.ts
6
7
  init_model_catalog_store();
7
8
  init_provider_auth_service();
8
9
  init_xopc_cloud_config();
9
10
  function availableModels() {
10
- return getModelCatalogStore().getSource("xopc-cloud")?.models.filter((model) => model.availability === "available" && model.kind === "tts") ?? [];
11
+ const source = getModelCatalogStore().getSource("xopc-cloud");
12
+ return source?.models.filter((model) => model.availability === "available" && model.kind === "tts").sort((left, right) => compareCatalogModels(left, right, source.recommended?.tts)) ?? [];
11
13
  }
12
14
  function readConfig(config) {
13
15
  return config;
@@ -57,6 +57,8 @@ export interface TTSModelOverrideConfig {
57
57
  export interface TTSConfig {
58
58
  enabled: boolean;
59
59
  provider: TTSProvider;
60
+ /** Runtime-only flag: absent app config enables managed provider selection. */
61
+ managedAuto?: boolean;
60
62
  /** Trigger mode for automatic voice replies. */
61
63
  trigger: TTSAutoMode;
62
64
  /** Fallback configuration */
@@ -1,11 +1,12 @@
1
1
  //#region src/voice/tts/types.ts
2
2
  const DEFAULT_TTS_CONFIG = {
3
3
  enabled: true,
4
- provider: "edge",
5
- trigger: "inbound",
4
+ provider: "xopc-cloud",
5
+ trigger: "off",
6
6
  fallback: {
7
7
  enabled: true,
8
8
  order: [
9
+ "xopc-cloud",
9
10
  "openai",
10
11
  "alibaba",
11
12
  "minimax",
@@ -26,6 +27,7 @@ const DEFAULT_TTS_CONFIG = {
26
27
  allowSeed: false
27
28
  },
28
29
  providers: {
30
+ "xopc-cloud": {},
29
31
  alibaba: {
30
32
  model: "qwen-tts",
31
33
  voice: "Cherry"
@@ -9,3 +9,26 @@ export declare function evaluateWorkUnderstandingCase(input: WorkUnderstandingEv
9
9
  evidenceCoverage: number;
10
10
  f1: number;
11
11
  };
12
+ export interface QuickUnderstandingEvaluationCase extends WorkUnderstandingEvaluationCase {
13
+ expectedSourceIds: string[];
14
+ observedSourceIds: string[];
15
+ startedAtMs: number;
16
+ firstCandidateAtMs?: number;
17
+ timeBudgetMs: number;
18
+ }
19
+ export type QuickUnderstandingGate = {
20
+ minPrecision: number;
21
+ minRecall: number;
22
+ minEvidenceCoverage: number;
23
+ minSourceCoverage: number;
24
+ };
25
+ export declare function evaluateQuickUnderstandingCase(input: QuickUnderstandingEvaluationCase): {
26
+ sourceCoverage: number;
27
+ timeToFirstCandidateMs: number;
28
+ withinTimeBudget: boolean;
29
+ precision: number;
30
+ recall: number;
31
+ evidenceCoverage: number;
32
+ f1: number;
33
+ };
34
+ export declare function meetsQuickUnderstandingGate(metrics: ReturnType<typeof evaluateQuickUnderstandingCase>, gate: QuickUnderstandingGate): boolean;
@@ -13,5 +13,22 @@ function evaluateWorkUnderstandingCase(input) {
13
13
  f1: precision + recall ? 2 * precision * recall / (precision + recall) : 0
14
14
  };
15
15
  }
16
+ function evaluateQuickUnderstandingCase(input) {
17
+ const topic = evaluateWorkUnderstandingCase(input);
18
+ const expectedSources = new Set(input.expectedSourceIds);
19
+ const observedSources = new Set(input.observedSourceIds);
20
+ const coveredSources = [...expectedSources].filter((sourceId) => observedSources.has(sourceId)).length;
21
+ const sourceCoverage = expectedSources.size ? coveredSources / expectedSources.size : 1;
22
+ const timeToFirstCandidateMs = input.firstCandidateAtMs === void 0 ? null : Math.max(0, input.firstCandidateAtMs - input.startedAtMs);
23
+ return {
24
+ ...topic,
25
+ sourceCoverage,
26
+ timeToFirstCandidateMs,
27
+ withinTimeBudget: timeToFirstCandidateMs !== null && timeToFirstCandidateMs <= input.timeBudgetMs
28
+ };
29
+ }
30
+ function meetsQuickUnderstandingGate(metrics, gate) {
31
+ return metrics.precision >= gate.minPrecision && metrics.recall >= gate.minRecall && metrics.evidenceCoverage >= gate.minEvidenceCoverage && metrics.sourceCoverage >= gate.minSourceCoverage && metrics.withinTimeBudget;
32
+ }
16
33
  //#endregion
17
- export { evaluateWorkUnderstandingCase };
34
+ export { evaluateQuickUnderstandingCase, evaluateWorkUnderstandingCase, meetsQuickUnderstandingGate };
@@ -9,5 +9,5 @@ import { DEFAULT_WORK_INVESTIGATION_BUDGET, investigateWorkContext } from "./inv
9
9
  import { persistWorkThreadsFromDiscovery } from "./thread-service.js";
10
10
  import { getWorkDiscoveryDirectorySource, listWorkDiscoveryDirectorySources, revokeWorkDiscoveryDirectorySource, upsertWorkDiscoveryDirectorySource } from "./source-repository.js";
11
11
  import { WorkDiscoveryService } from "./service.js";
12
- import { evaluateWorkUnderstandingCase } from "./evaluation.js";
13
- export { DEFAULT_WORK_INVESTIGATION_BUDGET, WORK_DISCOVERY_SCAN_POLICY_VERSION, WorkDiscoveryService, analyzeUnderstandingSources, analyzeWorkContext, appendWorkUnderstandingEvidence, canonicalWorkDiscoveryRoot, createWorkDiscoveryRun, createWorkUnderstandingInvestigation, discoverWorkCandidates, evaluateWorkUnderstandingCase, findActiveWorkDiscoverySourceRefresh, getWorkDiscoveryDirectorySource, getWorkDiscoveryOnboardingState, getWorkDiscoveryRun, getWorkDiscoveryRunByIdempotencyKey, getWorkUnderstandingInvestigation, getWorkUnderstandingInvestigationForRun, investigateWorkContext, listWorkDiscoveryDirectorySources, listWorkDiscoverySourceRefreshes, listWorkUnderstandingEvidence, persistWorkThreadsFromDiscovery, previewWorkDiscoveryRoot, probeWorkDiscoveryRoot, readWorkDiscoveryTextExcerpt, recordWorkDiscoverySourceRefresh, resetWorkUnderstandingInvestigation, resolvePersonalWorkRoots, revokeWorkDiscoveryDirectorySource, searchWorkDiscoveryText, setWorkDiscoveryFeedback, setWorkDiscoveryOnboardingState, summarizeWorkContextSnapshot, updateWorkDiscoveryRun, updateWorkDiscoverySourceRefreshForRun, updateWorkUnderstandingEvidenceObservation, updateWorkUnderstandingInvestigation, upsertWorkDiscoveryDirectorySource, workDiscoveryFingerprintsEqual, workDiscoveryResultMarkdown };
12
+ import { evaluateQuickUnderstandingCase, evaluateWorkUnderstandingCase, meetsQuickUnderstandingGate } from "./evaluation.js";
13
+ export { DEFAULT_WORK_INVESTIGATION_BUDGET, WORK_DISCOVERY_SCAN_POLICY_VERSION, WorkDiscoveryService, analyzeUnderstandingSources, analyzeWorkContext, appendWorkUnderstandingEvidence, canonicalWorkDiscoveryRoot, createWorkDiscoveryRun, createWorkUnderstandingInvestigation, discoverWorkCandidates, evaluateQuickUnderstandingCase, evaluateWorkUnderstandingCase, findActiveWorkDiscoverySourceRefresh, getWorkDiscoveryDirectorySource, getWorkDiscoveryOnboardingState, getWorkDiscoveryRun, getWorkDiscoveryRunByIdempotencyKey, getWorkUnderstandingInvestigation, getWorkUnderstandingInvestigationForRun, investigateWorkContext, listWorkDiscoveryDirectorySources, listWorkDiscoverySourceRefreshes, listWorkUnderstandingEvidence, meetsQuickUnderstandingGate, persistWorkThreadsFromDiscovery, previewWorkDiscoveryRoot, probeWorkDiscoveryRoot, readWorkDiscoveryTextExcerpt, recordWorkDiscoverySourceRefresh, resetWorkUnderstandingInvestigation, resolvePersonalWorkRoots, revokeWorkDiscoveryDirectorySource, searchWorkDiscoveryText, setWorkDiscoveryFeedback, setWorkDiscoveryOnboardingState, summarizeWorkContextSnapshot, updateWorkDiscoveryRun, updateWorkDiscoverySourceRefreshForRun, updateWorkUnderstandingEvidenceObservation, updateWorkUnderstandingInvestigation, upsertWorkDiscoveryDirectorySource, workDiscoveryFingerprintsEqual, workDiscoveryResultMarkdown };
@@ -6,7 +6,7 @@ import { ActivityService } from "../activity/service.js";
6
6
  import { getAgentDefaultModelRef, init_schema } from "../config/schema.js";
7
7
  import { buildSessionKey, init_session_key } from "../routing/session-key.js";
8
8
  import { getDefaultAgentId, init_resolve_route } from "../routing/resolve-route.js";
9
- import { createUnderstandingSourceRun, getUnderstandingSourceRun, listUserFocuses, setUserFocusStatus, updateUnderstandingSourceGrantCheckpoint, updateUnderstandingSourceRun, upsertUnderstandingSourceGrant, upsertUserFocus } from "../user-context/sources/repository.js";
9
+ import { createUnderstandingSourceRun, getUnderstandingSourceRun, updateUnderstandingSourceGrantCheckpoint, updateUnderstandingSourceRun, upsertUnderstandingSourceGrant, upsertUserFocus } from "../user-context/sources/repository.js";
10
10
  import { previewWorkDiscoveryRoot, probeWorkDiscoveryRoot, summarizeWorkContextSnapshot } from "./probe.js";
11
11
  import { clusterActivityTopics } from "../user-context/sources/activity-clustering.js";
12
12
  import { isLocalUnderstandingSourceId } from "../user-context/sources/local-source-contract.js";
@@ -766,7 +766,7 @@ var WorkDiscoveryService = class {
766
766
  snapshot: investigatedSnapshot,
767
767
  evidence: unifiedEvidence
768
768
  });
769
- for (const thread of workThreads) upsertUserFocus({
769
+ const focusCandidates = workThreads.map((thread) => upsertUserFocus({
770
770
  canonicalKey: `work-focus:${thread.canonicalKey}`,
771
771
  title: thread.title,
772
772
  summary: thread.summary,
@@ -775,10 +775,11 @@ var WorkDiscoveryService = class {
775
775
  confidence: thread.confidence,
776
776
  projectId: run.projectId,
777
777
  evidenceRefs: thread.evidenceIds
778
- });
778
+ }));
779
779
  const result = this.persistProfileCandidates(run, {
780
780
  ...baseResult,
781
- ...workThreads.length ? { workThreads } : {}
781
+ ...workThreads.length ? { workThreads } : {},
782
+ ...focusCandidates.length ? { focusCandidates } : {}
782
783
  });
783
784
  current = updateWorkDiscoveryRun(run.id, {
784
785
  status: "analyzing",
@@ -1000,10 +1001,7 @@ var WorkDiscoveryService = class {
1000
1001
  recognitionDecision: input.decision,
1001
1002
  ...correctedIntent ? { correctedIntent } : {}
1002
1003
  });
1003
- if (input.decision === "confirmed") {
1004
- const focusKeys = new Set((run.result.workThreads ?? []).map((thread) => `work-focus:${thread.canonicalKey}`));
1005
- for (const focus of listUserFocuses(["candidate"])) if (focusKeys.has(focus.canonicalKey)) setUserFocusStatus(focus.id, "active");
1006
- } else if ((input.decision === "corrected" || input.decision === "different_goal") && correctedIntent) upsertUserFocus({
1004
+ if ((input.decision === "corrected" || input.decision === "different_goal") && correctedIntent) upsertUserFocus({
1007
1005
  canonicalKey: `user-focus:${createHash("sha256").update(correctedIntent.toLocaleLowerCase()).digest("hex").slice(0, 20)}`,
1008
1006
  title: correctedIntent.slice(0, 120),
1009
1007
  summary: correctedIntent,
@@ -1,3 +1,4 @@
1
+ import type { UserFocus } from '../user-context/sources/types.js';
1
2
  export type WorkDiscoveryOnboardingStatus = 'not_started' | 'in_progress' | 'completed' | 'dismissed';
2
3
  export interface WorkDiscoveryOnboardingState {
3
4
  status: WorkDiscoveryOnboardingStatus;
@@ -158,6 +159,7 @@ export interface WorkDiscoveryResult {
158
159
  };
159
160
  workThreadCandidates?: WorkUnderstandingThreadCandidate[];
160
161
  workThreads?: WorkUnderstandingThread[];
162
+ focusCandidates?: UserFocus[];
161
163
  }
162
164
  export interface WorkDiscoveryProfileCandidate {
163
165
  id: string;