@xopcai/xopc 0.0.395 → 0.0.396

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 (95) 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/{agent-avatar-dicebear-BRtkz-ZU.js → agent-avatar-dicebear-DwTaeL1e.js} +1 -1
  4. package/dist/gateway/static/root/assets/{agent-defaults-settings-panel-Dqg2NOn-.js → agent-defaults-settings-panel-D8Q9Cpge.js} +1 -1
  5. package/dist/gateway/static/root/assets/{agent-plugin-dialog-CKK95Jmr.js → agent-plugin-dialog-C-UKhDkS.js} +1 -1
  6. package/dist/gateway/static/root/assets/{agents-0zgLsfVA.js → agents-DOv68iBN.js} +3 -3
  7. package/dist/gateway/static/root/assets/{app-management-settings-panel-BZS8FvoL.js → app-management-settings-panel-B1ApwlFh.js} +1 -1
  8. package/dist/gateway/static/root/assets/{appearance-settings-RxXMAxiB.js → appearance-settings-Avd_jVji.js} +1 -1
  9. package/dist/gateway/static/root/assets/{apps-page-mGU9WLjP.js → apps-page-Da6Ar2U3.js} +1 -1
  10. package/dist/gateway/static/root/assets/{archive-plugin-DEnHq3OR.js → archive-plugin-C26WGbj9.js} +1 -1
  11. package/dist/gateway/static/root/assets/{automations-page-BwkugzB8.js → automations-page-T3FSuURJ.js} +1 -1
  12. package/dist/gateway/static/root/assets/{automations-workspace-K8aDhoYt.js → automations-workspace-B9r27rPk.js} +1 -1
  13. package/dist/gateway/static/root/assets/{binary-plugins-NWeXhh1k.js → binary-plugins-CLaLkM3M.js} +1 -1
  14. package/dist/gateway/static/root/assets/{block-editor-D_bKN3BN.js → block-editor-CB4oRyM5.js} +1 -1
  15. package/dist/gateway/static/root/assets/{browser-automation-inputs-vtPkXfJ8.js → browser-automation-inputs-0nkk3bLA.js} +1 -1
  16. package/dist/gateway/static/root/assets/{browser-automations-page-DBPbwOG8.js → browser-automations-page-KLG8IXvl.js} +1 -1
  17. package/dist/gateway/static/root/assets/{browser-settings-page-VBZDYoXD.js → browser-settings-page-Tcejw5fF.js} +1 -1
  18. package/dist/gateway/static/root/assets/{capabilities-page-CQsGp9Sx.js → capabilities-page-BJlw9rhA.js} +2 -2
  19. package/dist/gateway/static/root/assets/{capabilities-settings-panel-C_OMsW_8.js → capabilities-settings-panel-kEvUR6Yu.js} +1 -1
  20. package/dist/gateway/static/root/assets/{capability-header-actions-CMJXWq8a.js → capability-header-actions-Br5PchG2.js} +1 -1
  21. package/dist/gateway/static/root/assets/{channels-C_TVCc1N.js → channels-DRaE6_ub.js} +1 -1
  22. package/dist/gateway/static/root/assets/{chat-terminal-dock-9YRAokOl.js → chat-terminal-dock-Cl0hAav9.js} +1 -1
  23. package/dist/gateway/static/root/assets/{computer-settings-page-BPYAZ4ks.js → computer-settings-page-B6JI2S1b.js} +1 -1
  24. package/dist/gateway/static/root/assets/{connector-service-page-B81cEAEX.js → connector-service-page-AqsoqTnF.js} +1 -1
  25. package/dist/gateway/static/root/assets/{connectors-page-C0NvAP2V.js → connectors-page-cDRZ8bqm.js} +1 -1
  26. package/dist/gateway/static/root/assets/{date-picker-BvKP4P3n.js → date-picker-CyFehuto.js} +1 -1
  27. package/dist/gateway/static/root/assets/{dependency-picker-TvrNaf8y.js → dependency-picker-Vu_5QGGJ.js} +1 -1
  28. package/dist/gateway/static/root/assets/{desktop-pet-De-_QNSD.js → desktop-pet-Dw9k0Z2p.js} +1 -1
  29. package/dist/gateway/static/root/assets/{desktop-pet-settings-CRSRTIwT.js → desktop-pet-settings-DKqkhvxu.js} +1 -1
  30. package/dist/gateway/static/root/assets/{device-pairing-wizard-DnyJ8Bja.js → device-pairing-wizard-4l4ESMon.js} +1 -1
  31. package/dist/gateway/static/root/assets/{directory-picker-path-field-DOPXwYNR.js → directory-picker-path-field-7svbL2tR.js} +1 -1
  32. package/dist/gateway/static/root/assets/{extension-debug-page-DzXvpUwj.js → extension-debug-page-CFa6PCBV.js} +1 -1
  33. package/dist/gateway/static/root/assets/{extension-page-C0S1zNeP.js → extension-page-BD4nZ9sf.js} +1 -1
  34. package/dist/gateway/static/root/assets/{extension-settings-page-C3Z7bFjy.js → extension-settings-page-CxPIMrmn.js} +1 -1
  35. package/dist/gateway/static/root/assets/{gateway-settings-Btc2wTQe.js → gateway-settings-Da2CtQ7c.js} +1 -1
  36. package/dist/gateway/static/root/assets/{highlighted-body-KQOG7T2V-BFYBbh1P.js → highlighted-body-KQOG7T2V-DzEeyJpH.js} +1 -1
  37. package/dist/gateway/static/root/assets/{home-page-C5sLR47Q.js → home-page-Cp4-sTfX.js} +1 -1
  38. package/dist/gateway/static/root/assets/{image-generation-api-Vqcyqnzb.js → image-generation-api-Zo56ZmKs.js} +1 -1
  39. package/dist/gateway/static/root/assets/{imports-page-BJGHrzhX.js → imports-page-C_PPaOFv.js} +1 -1
  40. package/dist/gateway/static/root/assets/{index-BNRLzxpH.js → index-XRbEWVyZ.js} +8 -8
  41. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-BQkQoPmm.js → keyboard-shortcuts-settings-BGtrzFT6.js} +1 -1
  42. package/dist/gateway/static/root/assets/{local-app-workbench-page-DbxLz9Ms.js → local-app-workbench-page-Cu80fCA0.js} +1 -1
  43. package/dist/gateway/static/root/assets/{local-apps-page-CaatwSrK.js → local-apps-page-Zsu8FnwP.js} +1 -1
  44. package/dist/gateway/static/root/assets/{logs-page-3Wo4Lmts.js → logs-page-DlIhfEW_.js} +1 -1
  45. package/dist/gateway/static/root/assets/{management-settings-BHlbM8IM.js → management-settings-CDV-xItG.js} +1 -1
  46. package/dist/gateway/static/root/assets/{media-plugins-Cq1uLrd8.js → media-plugins-Ba1_QMmZ.js} +1 -1
  47. package/dist/gateway/static/root/assets/mermaid-MCJ5UELQ-CpK57Kgp.js +1 -0
  48. package/dist/gateway/static/root/assets/{note-detail-panel-MjKND8HC.js → note-detail-panel-BXi6BrXd.js} +3 -3
  49. package/dist/gateway/static/root/assets/{notes-page-Cv040hVD.js → notes-page-ClR9R90o.js} +1 -1
  50. package/dist/gateway/static/root/assets/{page-context-capture-button-Cp71nTq2.js → page-context-capture-button-BqNWtf_f.js} +1 -1
  51. package/dist/gateway/static/root/assets/{personal-page-CyEUWV2n.js → personal-page-CSF-sn8w.js} +1 -1
  52. package/dist/gateway/static/root/assets/{preview-open-alternatives-gzCecXc4.js → preview-open-alternatives-kkbrbiVd.js} +1 -1
  53. package/dist/gateway/static/root/assets/{product-open-page-CWFT7VuQ.js → product-open-page-Dheqo_4J.js} +1 -1
  54. package/dist/gateway/static/root/assets/{product-preview-content-Dh111Kca.js → product-preview-content-B9Y6dIuh.js} +1 -1
  55. package/dist/gateway/static/root/assets/{project-detail-page-CyhyZiTi.js → project-detail-page-l5dXxnSq.js} +1 -1
  56. package/dist/gateway/static/root/assets/{projects-page-QUdyJino.js → projects-page-95Od8gLy.js} +1 -1
  57. package/dist/gateway/static/root/assets/{remote-access-hub-Cd8P0Dxs.js → remote-access-hub-DPEpPFax.js} +1 -1
  58. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-bTjVfYm5.js → runtime-tools-settings-panel-BjyZGNP3.js} +1 -1
  59. package/dist/gateway/static/root/assets/{schema-form-BGOzfVyj.js → schema-form-DelMOLjg.js} +1 -1
  60. package/dist/gateway/static/root/assets/{sessions-page-BGMemJF6.js → sessions-page-BN0nMm0w.js} +1 -1
  61. package/dist/gateway/static/root/assets/settings-advanced-gate-BvfEKyfy.js +1 -0
  62. package/dist/gateway/static/root/assets/{settings-form-section-Bqm1IKvR.js → settings-form-section-DNWEDA71.js} +1 -1
  63. package/dist/gateway/static/root/assets/{settings-page-CniJVL-o.js → settings-page-DJ27gC7J.js} +1 -1
  64. package/dist/gateway/static/root/assets/{setup-status-panel-JPs4-QRw.js → setup-status-panel-BWA_puDN.js} +1 -1
  65. package/dist/gateway/static/root/assets/{share-preview-page-BnDGFgBR.js → share-preview-page-Du4mumVM.js} +1 -1
  66. package/dist/gateway/static/root/assets/{shares-settings-Cgp5BuLt.js → shares-settings-C0ixka9_.js} +1 -1
  67. package/dist/gateway/static/root/assets/{skill-api-CFdrz6tl.js → skill-api-zOxHjU7m.js} +1 -1
  68. package/dist/gateway/static/root/assets/{skill-reload-api-Cy5jVfms.js → skill-reload-api-743oJIiS.js} +1 -1
  69. package/dist/gateway/static/root/assets/{skills-page-CxaA3P5E.js → skills-page-DBYhEjP9.js} +1 -1
  70. package/dist/gateway/static/root/assets/{style-C_MAnir7.js → style-DsnKw5jo.js} +1 -1
  71. package/dist/gateway/static/root/assets/{system-settings-panel-BjnIlilP.js → system-settings-panel-mz9hWo_H.js} +1 -1
  72. package/dist/gateway/static/root/assets/{task-detail-page-Bg79rPnF.js → task-detail-page-Brp2wrEc.js} +1 -1
  73. package/dist/gateway/static/root/assets/{tracing-settings-page-BCI0tUbe.js → tracing-settings-page-aC-ziRbY.js} +1 -1
  74. package/dist/gateway/static/root/assets/{tunnel-api-0knnta9z.js → tunnel-api-Ch2Veztk.js} +1 -1
  75. package/dist/gateway/static/root/assets/{usage-page-D5aT1eie.js → usage-page-KfKZ2a3t.js} +1 -1
  76. package/dist/gateway/static/root/assets/{use-autosave-Ds_mbAfe.js → use-autosave-BLW3t_OK.js} +1 -1
  77. package/dist/gateway/static/root/assets/{user-model-page-D7L0-pDt.js → user-model-page-BSsT8WjA.js} +1 -1
  78. package/dist/gateway/static/root/assets/{voice-api-key-field-CPoGdarN.js → voice-api-key-field-DulF6Cm4.js} +1 -1
  79. package/dist/gateway/static/root/assets/{work-discovery-overlay-CWNguy2Z.js → work-discovery-overlay-bBMZM8tN.js} +1 -1
  80. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-BcDMFfkT.js → workflow-run-setup-panel-CsxXS1WI.js} +1 -1
  81. package/dist/gateway/static/root/assets/{workflows-page-BwZB-s4N.js → workflows-page-a-mfjQ2h.js} +1 -1
  82. package/dist/gateway/static/root/assets/{xopc-cloud-account-card-DlKr98VO.js → xopc-cloud-account-card-wwIRBFCs.js} +1 -1
  83. package/dist/gateway/static/root/index.html +1 -1
  84. package/dist/package.js +1 -1
  85. package/dist/src/cli/commands/onboard/model.js +1 -1
  86. package/dist/src/gateway/hono/routes/provider-setup.js +7 -0
  87. package/dist/src/gateway/service.js +6 -6
  88. package/dist/src/gateway/xopc-cloud-capability-setup.d.ts +4 -0
  89. package/dist/src/gateway/xopc-cloud-capability-setup.js +90 -26
  90. package/dist/src/home-intelligence/host.js +2 -2
  91. package/dist/src/providers/setup/engine.js +12 -10
  92. package/dist/src/providers/setup/voice.js +24 -6
  93. package/package.json +3 -3
  94. package/dist/gateway/static/root/assets/mermaid-MCJ5UELQ-XhlIBp5t.js +0 -1
  95. package/dist/gateway/static/root/assets/settings-advanced-gate-BiySFw1N.js +0 -1
@@ -3,16 +3,21 @@ import { init_agent_config } from "../agent-config/index.js";
3
3
  import { AgentCatalogRepository, init_repository } from "../agent-catalog/repository.js";
4
4
  import { AgentCatalogService } from "../agent-catalog/service.js";
5
5
  import { ConfigSchema, init_schema } from "../config/schema.js";
6
+ import { init_model_policy, isComputerModel, isDedicatedComputerProfile } from "../computer/model-policy.js";
7
+ import { voiceSupportsMode } from "../../packages/realtime-protocol/src/voice-catalog.js";
8
+ import { init_voice } from "../../packages/realtime-protocol/src/voice.js";
6
9
  import { getModelCatalogStore, init_model_catalog_store } from "../providers/model-catalog-store.js";
7
10
  import { compareCatalogModels } from "../providers/model-catalog-ranking.js";
8
11
  import { prepareUpdateGlobalDefaults } from "./global-defaults-admin.js";
9
12
  //#region src/gateway/xopc-cloud-capability-setup.ts
13
+ init_voice();
14
+ init_model_policy();
10
15
  init_schema();
11
16
  init_agent_config();
12
17
  init_repository();
13
18
  init_model_catalog_store();
14
19
  function supportsCapability(model, capability) {
15
- if (model.availability !== "available") return false;
20
+ if (model.availability !== "available" || isDedicatedComputerProfile(model.computerUse?.profile)) return false;
16
21
  if (capability === "chat") return model.kind === "language" && (model.operations.includes("chat.completions") || model.operations.includes("responses"));
17
22
  if (capability === "vision") return model.kind === "language" && model.input.includes("image");
18
23
  if (capability === "image-generation") return model.kind === "image" && model.operations.includes("images.generate");
@@ -25,10 +30,10 @@ function recommendedModel(source, capability) {
25
30
  }
26
31
  function recommendedVoiceModel(source, mode) {
27
32
  const recommendation = mode === "transcription.stream" ? source.recommended?.stt : mode === "speech.stream" ? source.recommended?.tts : void 0;
28
- return source.models.filter((model) => model.availability === "available" && model.voice?.modes.includes(mode) && (mode === "transcription.stream" || Boolean(model.voice.voices.length))).sort((left, right) => compareCatalogModels(left, right, recommendation))[0];
33
+ return source.models.filter((model) => model.availability === "available" && model.voice?.modes.includes(mode) && (mode === "transcription.stream" || model.voice.voices.some((voice) => voiceSupportsMode(voice, mode)))).sort((left, right) => compareCatalogModels(left, right, recommendation))[0];
29
34
  }
30
- function selectedVoice(model) {
31
- const voices = model.voice?.voices ?? [];
35
+ function selectedVoice(model, mode) {
36
+ const voices = model.voice?.voices.filter((voice) => voiceSupportsMode(voice, mode)) ?? [];
32
37
  return voices.find((voice) => voice.id === "Cherry")?.id ?? voices.find((voice) => voice.id === model.voice?.defaultVoice)?.id ?? voices[0].id;
33
38
  }
34
39
  function selectXopcCloudCapabilities(source) {
@@ -59,15 +64,44 @@ function selectXopcCloudCapabilities(source) {
59
64
  ...realtimeStt ? { realtimeStt: realtimeStt.id } : {},
60
65
  ...realtimeTts ? { realtimeTts: {
61
66
  model: realtimeTts.id,
62
- voice: selectedVoice(realtimeTts)
67
+ voice: selectedVoice(realtimeTts, "speech.stream")
63
68
  } } : {},
64
69
  ...realtimeOmni ? { realtimeOmni: {
65
70
  model: realtimeOmni.id,
66
- voice: selectedVoice(realtimeOmni)
71
+ voice: selectedVoice(realtimeOmni, "conversation")
67
72
  } } : {}
68
73
  }
69
74
  };
70
75
  }
76
+ /** Fill model uses without enabling desktop control or replacing explicit routes. */
77
+ function completeXopcCloudModelRoutes(models, source) {
78
+ const next = structuredClone(models);
79
+ const chat = recommendedModel(source, "chat");
80
+ const vision = recommendedModel(source, "vision");
81
+ const reasoning = source.models.filter((model) => supportsCapability(model, "chat") && model.reasoning).sort((left, right) => compareCatalogModels(left, right, "advanced"))[0] ?? chat;
82
+ const route = (model) => ({
83
+ primary: `xopc-cloud/${model.id}`,
84
+ fallbacks: []
85
+ });
86
+ if (chat) {
87
+ next.background ??= route(chat);
88
+ next.intents.fast ??= route(chat);
89
+ next.intents.understanding ??= structuredClone(next.background);
90
+ }
91
+ if (reasoning) for (const intent of [
92
+ "reasoning",
93
+ "coding",
94
+ "review"
95
+ ]) next.intents[intent] ??= route(reasoning);
96
+ if (vision) next.intents.vision ??= route(vision);
97
+ const computer = source.models.filter((model) => model.availability === "available" && isComputerModel({
98
+ ...model,
99
+ provider: source.providerId,
100
+ api: source.api
101
+ })).sort((left, right) => compareCatalogModels(left, right))[0];
102
+ if (computer) next.computerUse ??= route(computer);
103
+ return next;
104
+ }
71
105
  /** Build one atomic config update for the managed XOPC Cloud chat and media capabilities. */
72
106
  function prepareXopcCloudCapabilitySetup(config, source) {
73
107
  const selected = selectXopcCloudCapabilities(source);
@@ -81,7 +115,7 @@ function prepareXopcCloudCapabilitySetup(config, source) {
81
115
  const currentModels = currentDefaults.models;
82
116
  const defaultsUpdate = prepareUpdateGlobalDefaults({ defaults: {
83
117
  ...currentDefaults,
84
- models: {
118
+ models: completeXopcCloudModelRoutes({
85
119
  ...currentModels,
86
120
  chat: {
87
121
  primary: `xopc-cloud/${selection.chat}`,
@@ -97,7 +131,7 @@ function prepareXopcCloudCapabilitySetup(config, source) {
97
131
  primary: `xopc-cloud/${selection.imageGeneration}`,
98
132
  fallbacks: currentModels.imageGeneration?.fallbacks ?? []
99
133
  }
100
- }
134
+ }, source)
101
135
  } });
102
136
  if (defaultsUpdate.ok === false) return {
103
137
  ok: false,
@@ -176,7 +210,7 @@ function prepareXopcCloudCapabilitySetup(config, source) {
176
210
  }
177
211
  };
178
212
  }
179
- async function applyXopcCloudCapabilitySetup(service) {
213
+ async function applyXopcCloudCapabilitySetup(service, options = {}) {
180
214
  const source = getModelCatalogStore().getSource("xopc-cloud");
181
215
  if (!source) return {
182
216
  configured: false,
@@ -207,49 +241,78 @@ async function applyXopcCloudCapabilitySetup(service) {
207
241
  fallbacks: [],
208
242
  autoProviderFallback: false
209
243
  };
210
- if (stt && !nextConfig.tools?.media?.audio) {
244
+ if (stt && (options.enableAvailable || !nextConfig.tools?.media?.audio)) {
211
245
  nextConfig.tools ??= {};
212
246
  nextConfig.tools.media ??= {};
247
+ const current = nextConfig.tools.media.audio;
213
248
  nextConfig.tools.media.audio = {
249
+ ...current,
214
250
  enabled: true,
215
251
  provider: "xopc-cloud",
216
252
  fallback: {
217
253
  enabled: false,
218
254
  order: ["xopc-cloud"]
219
255
  },
220
- providers: { "xopc-cloud": { model: stt.id } }
256
+ models: [{
257
+ provider: "xopc-cloud",
258
+ model: stt.id,
259
+ capabilities: ["audio"]
260
+ }],
261
+ providers: {
262
+ ...current?.providers,
263
+ "xopc-cloud": {
264
+ ...current?.providers?.["xopc-cloud"],
265
+ model: stt.id
266
+ }
267
+ }
221
268
  };
222
269
  }
223
- if (tts && tts.tts?.defaultVoice && !nextConfig.messages?.tts) {
270
+ if (tts && tts.tts?.defaultVoice && (options.enableAvailable || !nextConfig.messages?.tts)) {
224
271
  nextConfig.messages ??= {};
272
+ const current = nextConfig.messages.tts;
225
273
  nextConfig.messages.tts = {
274
+ ...current,
226
275
  enabled: true,
227
276
  provider: "xopc-cloud",
228
- trigger: "off",
277
+ trigger: current?.trigger ?? "off",
278
+ fallback: {
279
+ enabled: false,
280
+ order: []
281
+ },
229
282
  maxTextLength: 512,
230
283
  timeoutMs: 6e4,
231
- providers: { "xopc-cloud": {
232
- model: tts.id,
233
- voice: tts.tts.defaultVoice
234
- } }
284
+ providers: {
285
+ ...current?.providers,
286
+ "xopc-cloud": {
287
+ ...current?.providers?.["xopc-cloud"],
288
+ model: tts.id,
289
+ voice: tts.tts.defaultVoice
290
+ }
291
+ }
235
292
  };
236
293
  }
237
- if (!nextConfig.voice && (realtimeStt || realtimeTts || realtimeOmni)) nextConfig.voice = ConfigSchema.parse({ voice: { realtime: { enabled: true } } }).voice;
294
+ if ((options.enableAvailable || !nextConfig.voice) && (realtimeStt || realtimeTts || realtimeOmni)) nextConfig.voice = ConfigSchema.parse({ voice: {
295
+ ...nextConfig.voice,
296
+ realtime: {
297
+ ...nextConfig.voice?.realtime,
298
+ enabled: true
299
+ }
300
+ } }).voice;
238
301
  const realtime = nextConfig.voice?.realtime;
239
302
  if (realtime?.enabled) {
240
- if (realtimeStt && !realtime.stt) realtime.stt = {
303
+ if (realtimeStt && (options.enableAvailable || !realtime.stt)) realtime.stt = {
241
304
  provider: "xopc-cloud",
242
305
  model: realtimeStt.id
243
306
  };
244
- if (realtimeTts && !realtime.tts) realtime.tts = {
307
+ if (realtimeTts && (options.enableAvailable || !realtime.tts)) realtime.tts = {
245
308
  provider: "xopc-cloud",
246
309
  model: realtimeTts.id,
247
- voice: selectedVoice(realtimeTts)
310
+ voice: selectedVoice(realtimeTts, "speech.stream")
248
311
  };
249
- if (realtimeOmni && !realtime.omni) realtime.omni = {
312
+ if (realtimeOmni && (options.enableAvailable || !realtime.omni)) realtime.omni = {
250
313
  provider: "xopc-cloud",
251
314
  model: realtimeOmni.id,
252
- voice: selectedVoice(realtimeOmni),
315
+ voice: selectedVoice(realtimeOmni, "conversation"),
253
316
  instructions: "Keep replies conversational and concise. You cannot execute tools."
254
317
  };
255
318
  }
@@ -258,6 +321,7 @@ async function applyXopcCloudCapabilitySetup(service) {
258
321
  error: "XOPC Cloud published no usable models",
259
322
  missing: selection.missing
260
323
  };
324
+ nextDefaults.models = completeXopcCloudModelRoutes(nextDefaults.models, source);
261
325
  const defaultsUpdate = prepareUpdateGlobalDefaults({ defaults: nextDefaults });
262
326
  if (defaultsUpdate.ok === false) return {
263
327
  configured: false,
@@ -284,14 +348,14 @@ async function applyXopcCloudCapabilitySetup(service) {
284
348
  ...realtimeStt ? { realtimeStt: realtimeStt.id } : {},
285
349
  ...realtimeTts ? { realtimeTts: {
286
350
  model: realtimeTts.id,
287
- voice: selectedVoice(realtimeTts)
351
+ voice: selectedVoice(realtimeTts, "speech.stream")
288
352
  } } : {},
289
353
  ...realtimeOmni ? { realtimeOmni: {
290
354
  model: realtimeOmni.id,
291
- voice: selectedVoice(realtimeOmni)
355
+ voice: selectedVoice(realtimeOmni, "conversation")
292
356
  } } : {}
293
357
  }
294
358
  };
295
359
  }
296
360
  //#endregion
297
- export { applyXopcCloudCapabilitySetup, prepareXopcCloudCapabilitySetup, selectXopcCloudCapabilities };
361
+ export { applyXopcCloudCapabilitySetup, completeXopcCloudModelRoutes, prepareXopcCloudCapabilitySetup, selectXopcCloudCapabilities };
@@ -1,10 +1,10 @@
1
1
  import { createLogger } from "../utils/logger/index.js";
2
2
  import { init_logger } from "../utils/logger.js";
3
- import { HomeAdviceBudgetExceededError, isHomeProseLocalized } from "./generator.js";
4
3
  import { homePatternKey } from "./strategy.js";
5
- import { HomeAdvicePolicy } from "./policy.js";
6
4
  import { HomeIntelligenceRepository } from "./repository.js";
7
5
  import { HomeOpportunityApplicationService } from "./application-service.js";
6
+ import { HomeAdvicePolicy } from "./policy.js";
7
+ import { HomeAdviceBudgetExceededError, isHomeProseLocalized } from "./generator.js";
8
8
  import { buildHomeOpportunityNotification } from "./notification.js";
9
9
  import { createHash } from "node:crypto";
10
10
  //#region src/home-intelligence/host.ts
@@ -93,7 +93,8 @@ function previewProviderSetup(snapshot, request = {}) {
93
93
  coding: complex,
94
94
  review: complex
95
95
  } : {},
96
- ...recommended.vision ? { vision: recommended.vision } : {}
96
+ ...recommended.vision ? { vision: recommended.vision } : {},
97
+ ...recommended.background ? { understanding: recommended.background } : {}
97
98
  },
98
99
  uses: [...uses, ...snapshot.voice ? [
99
100
  "transcription",
@@ -139,15 +140,8 @@ function applyProviderSetup(snapshot, request, revision) {
139
140
  for (const use of preview.uses) {
140
141
  if (!use.selected) continue;
141
142
  if (!use.recommended) throw new Error(`Choose a model for ${use.id}`);
142
- if (use.id === "chat") {
143
- models.chat = route(use.recommended);
144
- for (const [intent, ref] of Object.entries(preview.taskModels)) {
145
- const key = intent;
146
- const existing = models.intents[key];
147
- const keep = request.mode !== "replace" && existing && snapshot.configuredProviders.has(existing.primary.split("/")[0]);
148
- if (ref && !keep && (intent !== "vision" || preview.uses.some((use) => use.id === "vision" && use.selected))) models.intents[key] = route(ref);
149
- }
150
- } else if (use.id === "vision") models.imageUnderstanding = route(use.recommended);
143
+ if (use.id === "chat") models.chat = route(use.recommended);
144
+ else if (use.id === "vision") models.imageUnderstanding = route(use.recommended);
151
145
  else if (use.id === "image") models.imageGeneration = {
152
146
  ...models.imageGeneration,
153
147
  ...route(use.recommended),
@@ -164,6 +158,14 @@ function applyProviderSetup(snapshot, request, revision) {
164
158
  });
165
159
  }
166
160
  }
161
+ for (const [intent, ref] of Object.entries(preview.taskModels)) {
162
+ const key = intent;
163
+ const useId = intent === "vision" ? "vision" : intent === "understanding" ? "background" : "chat";
164
+ if (!preview.uses.some((use) => use.id === useId && use.selected)) continue;
165
+ const existing = models.intents[key];
166
+ const keep = request.mode !== "replace" && existing && snapshot.configuredProviders.has(existing.primary.split("/")[0]);
167
+ if (ref && !keep) models.intents[key] = route(ref);
168
+ }
167
169
  return {
168
170
  defaults: {
169
171
  ...snapshot.defaults,
@@ -2,6 +2,7 @@ import { ConfigSchema, init_schema } from "../../config/schema.js";
2
2
  import { voiceSupportsMode } from "../../../packages/realtime-protocol/src/voice-catalog.js";
3
3
  import { init_voice } from "../../../packages/realtime-protocol/src/voice.js";
4
4
  import { getModelCatalogStore, init_model_catalog_store } from "../model-catalog-store.js";
5
+ import { compareCatalogModels } from "../model-catalog-ranking.js";
5
6
  import { BAILIAN_PLAN_HOST, BAILIAN_PLAN_OMNI_MODEL, BAILIAN_PLAN_OMNI_VOICE, BAILIAN_PLAN_PROVIDER, BAILIAN_PLAN_STT_MODEL, BAILIAN_PLAN_TTS_MODEL, BAILIAN_PLAN_TTS_VOICE } from "../../voice/token-plan.js";
6
7
  import { listSttProvidersForApi } from "../../voice/stt/list-providers.js";
7
8
  import { listTtsProvidersForApi } from "../../voice/tts/list-providers.js";
@@ -70,6 +71,14 @@ function readSetupVoiceState(provider, config) {
70
71
  });
71
72
  }
72
73
  }
74
+ for (const use of voiceSetupUses) {
75
+ const candidates = choices[use];
76
+ const recommendation = use === "conversation" ? void 0 : source?.recommended?.[use === "speech" ? "tts" : "stt"];
77
+ candidates.sort((left, right) => {
78
+ return compareCatalogModels(source.models.find((entry) => entry.id === left.model), source.models.find((entry) => entry.id === right.model), recommendation);
79
+ });
80
+ if (candidates[0]) candidates[0].recommended = true;
81
+ }
73
82
  }
74
83
  if (provider !== "qwen-token-plan-cn" && provider !== "xopc-cloud") for (const [use, entries] of [["transcription", listSttProvidersForApi(config).providers], ["speech", listTtsProvidersForApi(config).providers]]) {
75
84
  const entry = entries.find((entry) => entry.id === provider && entry.configured);
@@ -109,12 +118,21 @@ function readSetupVoiceState(provider, config) {
109
118
  function applySetupVoice(config, assignments) {
110
119
  let next = structuredClone(config);
111
120
  for (const { use, model } of assignments) {
112
- if (model.provider === "xopc-cloud") next = selectPlatformVoice(next, {
113
- mode: use,
114
- model: model.model,
115
- ...model.voice ? { voice: model.voice } : {}
116
- });
117
- else if (model.provider === "qwen-token-plan-cn") if (use === "speech") {
121
+ if (model.provider === "xopc-cloud") {
122
+ next = selectPlatformVoice(next, {
123
+ mode: use,
124
+ model: model.model,
125
+ ...model.voice ? { voice: model.voice } : {}
126
+ });
127
+ const streamMode = use === "speech" ? "speech.stream" : use === "transcription" ? "transcription.stream" : void 0;
128
+ if (streamMode) {
129
+ const stream = getModelCatalogStore().getSource("xopc-cloud")?.models.filter((entry) => entry.availability === "available" && entry.voice?.modes.includes(streamMode) && (use === "transcription" || entry.voice.voices.some((voice) => voiceSupportsMode(voice, streamMode)))).sort((left, right) => compareCatalogModels(left, right, model.model))[0];
130
+ if (stream) next = selectPlatformVoice(next, {
131
+ mode: streamMode,
132
+ model: stream.id
133
+ });
134
+ }
135
+ } else if (model.provider === "qwen-token-plan-cn") if (use === "speech") {
118
136
  const current = next.messages?.tts;
119
137
  const previous = current?.providers?.[model.provider];
120
138
  const voice = (!previous?.model || previous.model === model.model) && typeof previous?.voice === "string" ? previous.voice : model.voice;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xopcai/xopc",
3
- "version": "0.0.395",
3
+ "version": "0.0.396",
4
4
  "description": "Local-first personal AI with Ada, task delegation, files, projects, workflows, and automations. Use cloud or local models.",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",
@@ -168,11 +168,11 @@
168
168
  "vitest": "4.1.5",
169
169
  "vue": "^3.5.35",
170
170
  "xlsx": "file:web/vendor/xlsx-0.20.3.tgz",
171
- "@xopcai/computer-control-contract": "0.1.0",
172
171
  "@xopcai/browser-control-contract": "0.1.0",
172
+ "@xopcai/computer-control-contract": "0.1.0",
173
+ "@xopcai/endpoint-tools-protocol": "0.0.0",
173
174
  "@xopcai/endpoint-tools-client": "0.0.0",
174
175
  "@xopcai/gateway-contract": "0.0.0",
175
- "@xopcai/endpoint-tools-protocol": "0.0.0",
176
176
  "@xopcai/image-providers": "0.1.0",
177
177
  "@xopcai/realtime-client": "0.0.0",
178
178
  "@xopcai/realtime-protocol": "0.0.0"
@@ -1 +0,0 @@
1
- import{Uc as e}from"./index-BNRLzxpH.js";export{e as Mermaid};
@@ -1 +0,0 @@
1
- import{Hn as e}from"./index-BNRLzxpH.js";function t(t){let{children:n,fallback:r}=t,i=r===void 0?null:r;return e()?n:i}export{t};