@xopcai/xopc 0.0.395 → 0.0.397

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 (192) hide show
  1. package/dist/browser-ext/manifest.json +1 -1
  2. package/dist/extensions/telegram/src/plugin.js +1 -1
  3. package/dist/extensions/telegram/xopc.extension.json +1 -1
  4. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-BRtkz-ZU.js → agent-avatar-dicebear-CIEGrioy.js} +1 -1
  5. package/dist/gateway/static/root/assets/{agent-defaults-settings-panel-Dqg2NOn-.js → agent-defaults-settings-panel-CzKNVkRn.js} +1 -1
  6. package/dist/gateway/static/root/assets/agent-plugin-dialog-mpA9rwYd.js +1 -0
  7. package/dist/gateway/static/root/assets/{agents-0zgLsfVA.js → agents-7VMa7Rzo.js} +3 -3
  8. package/dist/gateway/static/root/assets/{app-management-settings-panel-BZS8FvoL.js → app-management-settings-panel-DIJ0ii-n.js} +1 -1
  9. package/dist/gateway/static/root/assets/{appearance-settings-RxXMAxiB.js → appearance-settings-BGnyHS-p.js} +1 -1
  10. package/dist/gateway/static/root/assets/apps-page-CvqDUvof.js +1 -0
  11. package/dist/gateway/static/root/assets/{archive-plugin-DEnHq3OR.js → archive-plugin-CR8FcRAa.js} +1 -1
  12. package/dist/gateway/static/root/assets/{automations-page-BwkugzB8.js → automations-page-BLInZo7N.js} +1 -1
  13. package/dist/gateway/static/root/assets/{automations-workspace-K8aDhoYt.js → automations-workspace-DvTSHLt3.js} +1 -1
  14. package/dist/gateway/static/root/assets/{binary-plugins-NWeXhh1k.js → binary-plugins-DW9pu205.js} +1 -1
  15. package/dist/gateway/static/root/assets/{block-editor-D_bKN3BN.js → block-editor-ClgTc5v8.js} +1 -1
  16. package/dist/gateway/static/root/assets/{browser-automation-inputs-vtPkXfJ8.js → browser-automation-inputs-Bn7kDuUB.js} +1 -1
  17. package/dist/gateway/static/root/assets/{browser-automations-page-DBPbwOG8.js → browser-automations-page-CJGBhDnv.js} +1 -1
  18. package/dist/gateway/static/root/assets/{browser-settings-page-VBZDYoXD.js → browser-settings-page-tsi5W-cJ.js} +1 -1
  19. package/dist/gateway/static/root/assets/capabilities-page-CfbGk8q_.js +2 -0
  20. package/dist/gateway/static/root/assets/{capabilities-settings-panel-C_OMsW_8.js → capabilities-settings-panel-BkO7QEyA.js} +1 -1
  21. package/dist/gateway/static/root/assets/{capability-header-actions-CMJXWq8a.js → capability-header-actions-9ZG71-BO.js} +1 -1
  22. package/dist/gateway/static/root/assets/{channels-C_TVCc1N.js → channels-D0CwJktG.js} +1 -1
  23. package/dist/gateway/static/root/assets/{chat-terminal-dock-9YRAokOl.js → chat-terminal-dock-x1W2_hwc.js} +1 -1
  24. package/dist/gateway/static/root/assets/{computer-settings-page-BPYAZ4ks.js → computer-settings-page-D_b_bFVz.js} +1 -1
  25. package/dist/gateway/static/root/assets/{connector-service-page-B81cEAEX.js → connector-service-page-Kf8kaNm_.js} +1 -1
  26. package/dist/gateway/static/root/assets/{connectors-page-C0NvAP2V.js → connectors-page-DlpfL2Rc.js} +1 -1
  27. package/dist/gateway/static/root/assets/{date-picker-BvKP4P3n.js → date-picker-d5kiPUG0.js} +1 -1
  28. package/dist/gateway/static/root/assets/{dependency-picker-TvrNaf8y.js → dependency-picker-BcH76tQC.js} +1 -1
  29. package/dist/gateway/static/root/assets/{desktop-pet-De-_QNSD.js → desktop-pet-B-925tPX.js} +1 -1
  30. package/dist/gateway/static/root/assets/{desktop-pet-settings-CRSRTIwT.js → desktop-pet-settings-3XJ4qR65.js} +1 -1
  31. package/dist/gateway/static/root/assets/device-pairing-wizard-12m5Z9-8.js +1 -0
  32. package/dist/gateway/static/root/assets/{directory-picker-path-field-DOPXwYNR.js → directory-picker-path-field-B-qZCjGR.js} +1 -1
  33. package/dist/gateway/static/root/assets/{extension-debug-page-DzXvpUwj.js → extension-debug-page-BlQu1u6X.js} +1 -1
  34. package/dist/gateway/static/root/assets/{extension-page-C0S1zNeP.js → extension-page-CXxM1M62.js} +1 -1
  35. package/dist/gateway/static/root/assets/{extension-settings-page-C3Z7bFjy.js → extension-settings-page-AF5nvsPP.js} +1 -1
  36. package/dist/gateway/static/root/assets/{gateway-settings-Btc2wTQe.js → gateway-settings-ABXvW_yL.js} +1 -1
  37. package/dist/gateway/static/root/assets/{highlighted-body-KQOG7T2V-BFYBbh1P.js → highlighted-body-KQOG7T2V-Czdbbi0H.js} +1 -1
  38. package/dist/gateway/static/root/assets/{home-page-C5sLR47Q.js → home-page-LXGxGwVl.js} +1 -1
  39. package/dist/gateway/static/root/assets/{image-generation-api-Vqcyqnzb.js → image-generation-api-DPFPJ2ps.js} +1 -1
  40. package/dist/gateway/static/root/assets/{imports-page-BJGHrzhX.js → imports-page-Bwyotfbt.js} +1 -1
  41. package/dist/gateway/static/root/assets/index-BKHxJaGD.css +1 -0
  42. package/dist/gateway/static/root/assets/{index-BNRLzxpH.js → index-Dsp_gNdl.js} +116 -116
  43. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-BQkQoPmm.js → keyboard-shortcuts-settings-C20gl-l7.js} +1 -1
  44. package/dist/gateway/static/root/assets/{local-app-workbench-page-DbxLz9Ms.js → local-app-workbench-page-o0M_OSjC.js} +1 -1
  45. package/dist/gateway/static/root/assets/{local-apps-page-CaatwSrK.js → local-apps-page-DoWJCmOq.js} +1 -1
  46. package/dist/gateway/static/root/assets/{logs-page-3Wo4Lmts.js → logs-page-BFTL93RX.js} +1 -1
  47. package/dist/gateway/static/root/assets/{management-settings-BHlbM8IM.js → management-settings-C52cuMg1.js} +1 -1
  48. package/dist/gateway/static/root/assets/{media-plugins-Cq1uLrd8.js → media-plugins-DLrTRF0a.js} +1 -1
  49. package/dist/gateway/static/root/assets/mermaid-MCJ5UELQ-CPYJsRUJ.js +1 -0
  50. package/dist/gateway/static/root/assets/{note-detail-panel-MjKND8HC.js → note-detail-panel-CNN41byS.js} +3 -3
  51. package/dist/gateway/static/root/assets/{notes-page-Cv040hVD.js → notes-page-BsfBp_8z.js} +1 -1
  52. package/dist/gateway/static/root/assets/{page-context-capture-button-Cp71nTq2.js → page-context-capture-button-YTVWZ02-.js} +1 -1
  53. package/dist/gateway/static/root/assets/{personal-page-CyEUWV2n.js → personal-page-N4KoCZYG.js} +1 -1
  54. package/dist/gateway/static/root/assets/plugin-details-page-DcrrzQI-.js +1 -0
  55. package/dist/gateway/static/root/assets/{preview-open-alternatives-gzCecXc4.js → preview-open-alternatives-DzA__S54.js} +1 -1
  56. package/dist/gateway/static/root/assets/{product-open-page-CWFT7VuQ.js → product-open-page-DvlMKj0T.js} +1 -1
  57. package/dist/gateway/static/root/assets/{product-preview-content-Dh111Kca.js → product-preview-content-qdFyo4NG.js} +1 -1
  58. package/dist/gateway/static/root/assets/{project-detail-page-CyhyZiTi.js → project-detail-page-y67s_fA8.js} +1 -1
  59. package/dist/gateway/static/root/assets/{projects-page-QUdyJino.js → projects-page-D5iYgi0O.js} +1 -1
  60. package/dist/gateway/static/root/assets/{remote-access-hub-Cd8P0Dxs.js → remote-access-hub-DeFF7Re-.js} +1 -1
  61. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-bTjVfYm5.js → runtime-tools-settings-panel-BCHLh-KQ.js} +1 -1
  62. package/dist/gateway/static/root/assets/{schema-form-BGOzfVyj.js → schema-form-CJvaVHkx.js} +1 -1
  63. package/dist/gateway/static/root/assets/{sessions-page-BGMemJF6.js → sessions-page-DZ93_D5M.js} +1 -1
  64. package/dist/gateway/static/root/assets/settings-advanced-gate-F1WX7vxq.js +1 -0
  65. package/dist/gateway/static/root/assets/{settings-form-section-Bqm1IKvR.js → settings-form-section-B3eODxNv.js} +1 -1
  66. package/dist/gateway/static/root/assets/{settings-page-CniJVL-o.js → settings-page-Dg86uCnr.js} +1 -1
  67. package/dist/gateway/static/root/assets/{setup-status-panel-JPs4-QRw.js → setup-status-panel-ruFzAArp.js} +1 -1
  68. package/dist/gateway/static/root/assets/{share-preview-page-BnDGFgBR.js → share-preview-page-DCy1f25V.js} +1 -1
  69. package/dist/gateway/static/root/assets/{shares-settings-Cgp5BuLt.js → shares-settings-DeIVZvpJ.js} +1 -1
  70. package/dist/gateway/static/root/assets/{skill-api-CFdrz6tl.js → skill-api-RisyPAMA.js} +1 -1
  71. package/dist/gateway/static/root/assets/{skill-reload-api-Cy5jVfms.js → skill-reload-api-Dwkm1Fof.js} +1 -1
  72. package/dist/gateway/static/root/assets/{skills-page-CxaA3P5E.js → skills-page-UiTLsrFc.js} +1 -1
  73. package/dist/gateway/static/root/assets/{style-C_MAnir7.js → style-CwMX73G7.js} +1 -1
  74. package/dist/gateway/static/root/assets/{system-settings-panel-BjnIlilP.js → system-settings-panel-Cma37Pfm.js} +1 -1
  75. package/dist/gateway/static/root/assets/{task-detail-page-Bg79rPnF.js → task-detail-page-BKOF_kxS.js} +1 -1
  76. package/dist/gateway/static/root/assets/{tracing-settings-page-BCI0tUbe.js → tracing-settings-page-DC-kLysq.js} +1 -1
  77. package/dist/gateway/static/root/assets/{tunnel-api-0knnta9z.js → tunnel-api-BgdhbR1L.js} +1 -1
  78. package/dist/gateway/static/root/assets/{usage-page-D5aT1eie.js → usage-page-BSlFg3Xj.js} +1 -1
  79. package/dist/gateway/static/root/assets/{use-autosave-Ds_mbAfe.js → use-autosave-iKvZ1pvC.js} +1 -1
  80. package/dist/gateway/static/root/assets/{user-model-page-D7L0-pDt.js → user-model-page-D4GB8QsM.js} +1 -1
  81. package/dist/gateway/static/root/assets/{voice-api-key-field-CPoGdarN.js → voice-api-key-field-CESbtuwM.js} +1 -1
  82. package/dist/gateway/static/root/assets/{work-discovery-overlay-CWNguy2Z.js → work-discovery-overlay-dtPpmYyh.js} +1 -1
  83. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-BcDMFfkT.js → workflow-run-setup-panel-DmFn3E_B.js} +1 -1
  84. package/dist/gateway/static/root/assets/{workflows-page-BwZB-s4N.js → workflows-page-DEtaRuxH.js} +1 -1
  85. package/dist/gateway/static/root/assets/{xopc-cloud-account-card-DlKr98VO.js → xopc-cloud-account-card-DTZnabfg.js} +1 -1
  86. package/dist/gateway/static/root/index.html +2 -2
  87. package/dist/package.js +1 -1
  88. package/dist/src/agent/embedded/codemode-extension.d.ts +1 -0
  89. package/dist/src/agent/embedded/codemode-extension.js +6 -1
  90. package/dist/src/agent/embedded/run-for-session.js +1 -1
  91. package/dist/src/agent/embedded/run-turn.js +34 -2
  92. package/dist/src/agent/embedded/session-runner.js +1 -1
  93. package/dist/src/agent/mcp/config.d.ts +2 -0
  94. package/dist/src/agent/mcp/config.js +2 -2
  95. package/dist/src/agent/mcp/connection-setup.js +13 -1
  96. package/dist/src/agent/mcp/effective-server.d.ts +3 -0
  97. package/dist/src/agent/mcp/effective-server.js +27 -0
  98. package/dist/src/agent/mcp/native-mcp.d.ts +1 -1
  99. package/dist/src/agent/mcp/native-mcp.js +13 -4
  100. package/dist/src/agent/mcp/tool-catalog.js +2 -1
  101. package/dist/src/agent/skills/index.d.ts +1 -0
  102. package/dist/src/agent/skills/index.js +6 -2
  103. package/dist/src/agent/skills/skill-manager.d.ts +1 -0
  104. package/dist/src/agent/skills/skill-manager.js +6 -1
  105. package/dist/src/agent/skills/skill-sources.d.ts +1 -0
  106. package/dist/src/agent/skills/skill-sources.js +4 -3
  107. package/dist/src/agent/skills/types.d.ts +1 -0
  108. package/dist/src/agent/workspace-runtime/registry.js +6 -2
  109. package/dist/src/browser/native-messaging-host.js +1 -1
  110. package/dist/src/browser/providers/browser-ext-install.js +2 -2
  111. package/dist/src/channels/index.js +1 -1
  112. package/dist/src/channels/manager.js +1 -1
  113. package/dist/src/cli/commands/channels.js +1 -1
  114. package/dist/src/cli/commands/connectors.js +1 -1
  115. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  116. package/dist/src/cli/commands/extension-agent-plugin.js +92 -7
  117. package/dist/src/cli/commands/extension-marketplace.js +2 -2
  118. package/dist/src/cli/commands/extension.js +1 -1
  119. package/dist/src/cli/commands/mcp.js +6 -4
  120. package/dist/src/cli/commands/models.js +1 -1
  121. package/dist/src/cli/commands/onboard/model.js +1 -1
  122. package/dist/src/cli/commands/onboard.js +1 -1
  123. package/dist/src/extensions/agent-plugins/auth.d.ts +7 -1
  124. package/dist/src/extensions/agent-plugins/auth.js +53 -12
  125. package/dist/src/extensions/agent-plugins/branding.d.ts +6 -0
  126. package/dist/src/extensions/agent-plugins/branding.js +44 -0
  127. package/dist/src/extensions/agent-plugins/cli-authorization.d.ts +22 -0
  128. package/dist/src/extensions/agent-plugins/cli-authorization.js +198 -0
  129. package/dist/src/extensions/agent-plugins/connection-reuse.d.ts +10 -0
  130. package/dist/src/extensions/agent-plugins/connection-reuse.js +23 -0
  131. package/dist/src/extensions/agent-plugins/credentials.js +24 -1
  132. package/dist/src/extensions/agent-plugins/formats.d.ts +27 -0
  133. package/dist/src/extensions/agent-plugins/formats.js +208 -0
  134. package/dist/src/extensions/agent-plugins/inventory.d.ts +142 -2
  135. package/dist/src/extensions/agent-plugins/inventory.js +39 -5
  136. package/dist/src/extensions/agent-plugins/mcp-adapter.d.ts +2 -1
  137. package/dist/src/extensions/agent-plugins/mcp-adapter.js +42 -8
  138. package/dist/src/extensions/agent-plugins/mcp-format.d.ts +2 -0
  139. package/dist/src/extensions/agent-plugins/mcp-format.js +82 -0
  140. package/dist/src/extensions/agent-plugins/resources.d.ts +14 -0
  141. package/dist/src/extensions/agent-plugins/resources.js +112 -0
  142. package/dist/src/extensions/agent-plugins/setup-contract.d.ts +54 -0
  143. package/dist/src/extensions/agent-plugins/setup-contract.js +58 -0
  144. package/dist/src/extensions/agent-plugins/setup.d.ts +119 -0
  145. package/dist/src/extensions/agent-plugins/setup.js +491 -0
  146. package/dist/src/extensions/agent-plugins/source-catalog.d.ts +21 -0
  147. package/dist/src/extensions/agent-plugins/source-catalog.js +175 -0
  148. package/dist/src/extensions/agent-plugins/sources.d.ts +1 -1
  149. package/dist/src/extensions/agent-plugins/sources.js +12 -3
  150. package/dist/src/extensions/agent-plugins/store.d.ts +33 -2
  151. package/dist/src/extensions/agent-plugins/store.js +175 -25
  152. package/dist/src/extensions/agent-plugins/user-config.d.ts +5 -0
  153. package/dist/src/extensions/agent-plugins/user-config.js +49 -0
  154. package/dist/src/extensions/agent-plugins/validation.d.ts +26 -1
  155. package/dist/src/extensions/agent-plugins/validation.js +142 -27
  156. package/dist/src/extensions/sdk/index.js +1 -1
  157. package/dist/src/gateway/hono/app.js +1 -1
  158. package/dist/src/gateway/hono/routes/agent-plugins.js +120 -9
  159. package/dist/src/gateway/hono/routes/browser-install.js +1 -1
  160. package/dist/src/gateway/hono/routes/composer-history.js +22 -4
  161. package/dist/src/gateway/hono/routes/mcp.js +6 -4
  162. package/dist/src/gateway/hono/routes/provider-setup.js +7 -0
  163. package/dist/src/gateway/service.js +11 -9
  164. package/dist/src/gateway/session-context-summary.js +1 -1
  165. package/dist/src/gateway/xopc-cloud-capability-setup.d.ts +4 -0
  166. package/dist/src/gateway/xopc-cloud-capability-setup.js +90 -26
  167. package/dist/src/home-intelligence/host.js +2 -2
  168. package/dist/src/providers/setup/engine.js +12 -10
  169. package/dist/src/providers/setup/voice.js +24 -6
  170. package/dist/src/storage/sqlite/composer-input-history-repository.d.ts +4 -3
  171. package/dist/src/storage/sqlite/composer-input-history-repository.js +10 -8
  172. package/dist/src/storage/sqlite/device-pairing-approval.js +1 -1
  173. package/dist/src/storage/sqlite/migrations/257_session_composer_history.sql +11 -0
  174. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  175. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  176. package/dist/src/storage/sqlite/schema.js +1 -1
  177. package/dist/src/tui/backends/embedded-backend.d.ts +2 -2
  178. package/dist/src/tui/backends/embedded-backend.js +4 -4
  179. package/dist/src/tui/backends/gateway-realtime-backend.d.ts +2 -2
  180. package/dist/src/tui/backends/gateway-realtime-backend.js +7 -4
  181. package/dist/src/tui/composer-history.d.ts +14 -0
  182. package/dist/src/tui/composer-history.js +85 -0
  183. package/dist/src/tui/tui-backend.d.ts +4 -3
  184. package/dist/src/tui/tui.js +19 -46
  185. package/package.json +12 -4
  186. package/dist/gateway/static/root/assets/agent-plugin-dialog-CKK95Jmr.js +0 -1
  187. package/dist/gateway/static/root/assets/apps-page-mGU9WLjP.js +0 -1
  188. package/dist/gateway/static/root/assets/capabilities-page-CQsGp9Sx.js +0 -2
  189. package/dist/gateway/static/root/assets/device-pairing-wizard-DnyJ8Bja.js +0 -1
  190. package/dist/gateway/static/root/assets/index-zIgp-ZTu.css +0 -1
  191. package/dist/gateway/static/root/assets/mermaid-MCJ5UELQ-XhlIBp5t.js +0 -1
  192. package/dist/gateway/static/root/assets/settings-advanced-gate-BiySFw1N.js +0 -1
@@ -81,13 +81,10 @@ import "../infra/bus/index.js";
81
81
  import { collectMediaUrisFromMessages, deleteMediaUris } from "../media/session-references.js";
82
82
  import { AgentService } from "../agent/service.js";
83
83
  import { bootstrapApplicationStateSync } from "../bootstrap/application-state.js";
84
- import { setPairingBroadcastSink } from "../channels/pairing/pairing-events.js";
85
- import { registerClarificationChannelRuntime } from "./clarify-runtime.js";
86
- import { ChannelManager } from "../channels/manager.js";
87
- import { configureGatewayHttpProxy } from "../infra/http-proxy-env.js";
88
- import "../config/index.js";
89
84
  import { ChatPreviewService } from "../chat-previews/service.js";
90
85
  import "../chat-previews/index.js";
86
+ import { configureGatewayHttpProxy } from "../infra/http-proxy-env.js";
87
+ import "../config/index.js";
91
88
  import { ManagedComposioEventPoller } from "../connectors/composio-managed-events.js";
92
89
  import { startConnectedKnowledgeCoordinator } from "../knowledge/coordinator.js";
93
90
  import "../knowledge/index.js";
@@ -103,8 +100,13 @@ import { DiscussionSealer } from "../discussions/sealer.js";
103
100
  import "../discussions/index.js";
104
101
  import { EndpointToolRuntime } from "../endpoint-tools/runtime.js";
105
102
  import "../endpoint-tools/index.js";
103
+ import { HomeCapabilityPreflightService } from "../home-intelligence/capability-preflight.js";
104
+ import { HomeAdviceGenerator } from "../home-intelligence/generator.js";
105
+ import { HomeIntelligenceHost } from "../home-intelligence/host.js";
106
+ import { HomeSnapshotBuilder } from "../home-intelligence/snapshot.js";
106
107
  import { assertGatewayAuthConfigured, extractToken, resolveGatewayAuth, validateToken } from "./auth.js";
107
108
  import { prepareAutomationAgentSession } from "./automation-agent-session.js";
109
+ import { registerClarificationChannelRuntime } from "./clarify-runtime.js";
108
110
  import { stopTailscaleExposure } from "./tailscale-lifecycle.js";
109
111
  import { getGatewayFileSpaceService } from "./file-space-service.js";
110
112
  import { reconcileHomeIntelligenceAutomation } from "./home-intelligence-automation-reconciler.js";
@@ -118,6 +120,8 @@ import { WorkDiscoveryService } from "../work-discovery/service.js";
118
120
  import { buildVoiceMemoryContext } from "../voice/realtime/memory-context.js";
119
121
  import { buildVoicePersonaContext } from "../voice/realtime/persona-context.js";
120
122
  import { voiceMemoryBudget, voicePersonaBudget } from "../voice/realtime/conversation-context.js";
123
+ import { setPairingBroadcastSink } from "../channels/pairing/pairing-events.js";
124
+ import { ChannelManager } from "../channels/manager.js";
121
125
  import "../notes/index.js";
122
126
  import { buildWorkflowChildTools } from "../agent/workflow/workflow-child-tools.js";
123
127
  import { WorkflowRunService } from "../workflows/service/workflow-run-service.js";
@@ -163,10 +167,6 @@ import { TaskMainUpdateDecisionService } from "../tasks/task-main-update-decisio
163
167
  import { selectTaskMainUpdateAttempt, submitAndConfirmTaskMainUpdate } from "../tasks/task-main-update-input.js";
164
168
  import { checkAppContextAccess, prepareAppContext } from "./service/app-context-access.js";
165
169
  import { applyAutomaticVoiceLanguage, inferProductLanguageFromEnvironment, initializeVoiceDefaults } from "../voice/language-profile.js";
166
- import { HomeAdviceGenerator } from "../home-intelligence/generator.js";
167
- import { HomeIntelligenceHost } from "../home-intelligence/host.js";
168
- import { HomeSnapshotBuilder } from "../home-intelligence/snapshot.js";
169
- import { HomeCapabilityPreflightService } from "../home-intelligence/capability-preflight.js";
170
170
  import crypto from "node:crypto";
171
171
  //#region src/gateway/service.ts
172
172
  init_session_repository();
@@ -1572,6 +1572,8 @@ var GatewayService = class {
1572
1572
  await flushTracing();
1573
1573
  if (!this.running) return;
1574
1574
  this.stopping = true;
1575
+ const { cancelAllPluginCliAuthorizations } = await import("../extensions/agent-plugins/cli-authorization.js");
1576
+ cancelAllPluginCliAuthorizations();
1575
1577
  this.taskAllocationDispatcher?.stop();
1576
1578
  this.taskRunDispatcher?.stop();
1577
1579
  if (this.taskRunDispatchTimer) {
@@ -11,8 +11,8 @@ import { effectiveWorkspacePathForSession } from "../session/session-workspace.j
11
11
  import { ProjectStore } from "../projects/project-store.js";
12
12
  import { TaskOriginRepository } from "../tasks/task-origin-repository.js";
13
13
  import { TaskConversationRepository } from "../tasks/task-conversation-repository.js";
14
- import { TaskCollaborationRepository } from "../tasks/task-collaboration-repository.js";
15
14
  import { runExec } from "../infra/exec.js";
15
+ import { TaskCollaborationRepository } from "../tasks/task-collaboration-repository.js";
16
16
  import { isSessionSourceBinding } from "../agent/source-context/types.js";
17
17
  import { realpath, stat } from "node:fs/promises";
18
18
  //#region src/gateway/session-context-summary.ts
@@ -42,6 +42,8 @@ export declare function selectXopcCloudCapabilities(source: CatalogSource): {
42
42
  selection?: XopcCloudCapabilitySelection;
43
43
  missing: CloudCapability[];
44
44
  };
45
+ /** Fill model uses without enabling desktop control or replacing explicit routes. */
46
+ export declare function completeXopcCloudModelRoutes(models: AgentDefaults['models'], source: CatalogSource): AgentDefaults['models'];
45
47
  /** Build one atomic config update for the managed XOPC Cloud chat and media capabilities. */
46
48
  export declare function prepareXopcCloudCapabilitySetup(config: Config, source: CatalogSource): PrepareXopcCloudCapabilitySetupResult;
47
49
  export declare function applyXopcCloudCapabilitySetup(service: {
@@ -50,5 +52,7 @@ export declare function applyXopcCloudCapabilitySetup(service: {
50
52
  saved: boolean;
51
53
  error?: string;
52
54
  }>;
55
+ }, options?: {
56
+ enableAvailable?: boolean;
53
57
  }): Promise<ApplyXopcCloudCapabilitySetupResult>;
54
58
  export {};
@@ -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;
@@ -1,12 +1,13 @@
1
1
  export declare const COMPOSER_INPUT_HISTORY_LIMIT = 100;
2
2
  export interface ComposerInputHistoryItem {
3
+ conversationId: string;
3
4
  id: number;
4
5
  text: string;
5
6
  createdAt: number;
6
7
  }
7
- export declare function listComposerInputHistory(limit?: number): ComposerInputHistoryItem[];
8
- export declare function appendComposerInputHistory(text: string, now?: number): {
8
+ export declare function listComposerInputHistory(conversationId: string, limit?: number): ComposerInputHistoryItem[];
9
+ export declare function appendComposerInputHistory(conversationId: string, text: string, now?: number): {
9
10
  item: ComposerInputHistoryItem;
10
11
  inserted: boolean;
11
12
  };
12
- export declare function clearComposerInputHistory(): number;
13
+ export declare function clearComposerInputHistory(conversationId: string): number;
@@ -3,30 +3,32 @@ import { getSqliteDatabase, init_transaction, runSqliteWriteTransaction } from "
3
3
  //#region src/storage/sqlite/composer-input-history-repository.ts
4
4
  function fromRow(row) {
5
5
  return {
6
+ conversationId: row.conversation_id,
6
7
  id: row.id,
7
8
  text: row.text,
8
9
  createdAt: row.created_at
9
10
  };
10
11
  }
11
- function listComposerInputHistory(limit = 100) {
12
+ function listComposerInputHistory(conversationId, limit = 100) {
12
13
  const boundedLimit = Number.isFinite(limit) ? Math.min(100, Math.max(1, Math.trunc(limit))) : 100;
13
- return getSqliteDatabase().prepare("SELECT id, text, created_at FROM composer_input_history ORDER BY id DESC LIMIT ?").all(boundedLimit).map(fromRow);
14
+ return getSqliteDatabase().prepare("SELECT conversation_id, id, text, created_at FROM composer_input_history WHERE conversation_id = ? ORDER BY id DESC LIMIT ?").all(conversationId, boundedLimit).map(fromRow);
14
15
  }
15
- function appendComposerInputHistory(text, now = Date.now()) {
16
+ function appendComposerInputHistory(conversationId, text, now = Date.now()) {
16
17
  const normalized = text.trim();
17
18
  if (!normalized) throw new Error("Composer history text is required");
18
19
  return runSqliteWriteTransaction((db) => {
19
- const latest = db.prepare("SELECT id, text, created_at FROM composer_input_history ORDER BY id DESC LIMIT 1").get();
20
+ const latest = db.prepare("SELECT conversation_id, id, text, created_at FROM composer_input_history WHERE conversation_id = ? ORDER BY id DESC LIMIT 1").get(conversationId);
20
21
  if (latest?.text === normalized) return {
21
22
  item: fromRow(latest),
22
23
  inserted: false
23
24
  };
24
- const result = db.prepare("INSERT INTO composer_input_history (text, created_at) VALUES (?, ?)").run(normalized, now);
25
+ const result = db.prepare("INSERT INTO composer_input_history (conversation_id, text, created_at) VALUES (?, ?, ?)").run(conversationId, normalized, now);
25
26
  const id = Number(result.lastInsertRowid);
26
27
  db.prepare(`DELETE FROM composer_input_history
27
- WHERE id NOT IN (SELECT id FROM composer_input_history ORDER BY id DESC LIMIT ?)`).run(100);
28
+ WHERE conversation_id = ? AND id NOT IN (SELECT id FROM composer_input_history WHERE conversation_id = ? ORDER BY id DESC LIMIT ?)`).run(conversationId, conversationId, 100);
28
29
  return {
29
30
  item: {
31
+ conversationId,
30
32
  id,
31
33
  text: normalized,
32
34
  createdAt: now
@@ -35,8 +37,8 @@ function appendComposerInputHistory(text, now = Date.now()) {
35
37
  };
36
38
  });
37
39
  }
38
- function clearComposerInputHistory() {
39
- return Number(runSqliteWriteTransaction((db) => db.prepare("DELETE FROM composer_input_history").run().changes));
40
+ function clearComposerInputHistory(conversationId) {
41
+ return Number(runSqliteWriteTransaction((db) => db.prepare("DELETE FROM composer_input_history WHERE conversation_id = ?").run(conversationId).changes));
40
42
  }
41
43
  var COMPOSER_INPUT_HISTORY_LIMIT;
42
44
  var init_composer_input_history_repository = __esmMin((() => {
@@ -5,8 +5,8 @@ import { init_src } from "../../../packages/gateway-contract/src/index.js";
5
5
  import { init_gateway_scopes } from "../../gateway/security/gateway-scopes.js";
6
6
  import { createDevice, getDevice, init_device_access_repository, registerInitialDeviceRefreshToken, revokeDevice } from "./device-access-repository.js";
7
7
  import { getOrCreateGatewayIdentity, init_gateway_identity_repository } from "./gateway-identity-repository.js";
8
- import { browserEnrollmentPublicKeyThumbprint } from "../../browser/enrollment.js";
9
8
  import "../../browser/extension-identity.js";
9
+ import { browserEnrollmentPublicKeyThumbprint } from "../../browser/enrollment.js";
10
10
  import crypto from "node:crypto";
11
11
  //#region src/storage/sqlite/device-pairing-approval.ts
12
12
  init_src();
@@ -0,0 +1,11 @@
1
+ -- Keep unscoped legacy entries out of session recall.
2
+ ALTER TABLE composer_input_history RENAME TO composer_input_history_legacy;
3
+ DROP INDEX idx_composer_input_history_recent;
4
+ CREATE TABLE composer_input_history (
5
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
6
+ conversation_id TEXT NOT NULL REFERENCES sessions(conversation_id) ON DELETE CASCADE,
7
+ text TEXT NOT NULL,
8
+ created_at INTEGER NOT NULL
9
+ );
10
+ CREATE INDEX idx_composer_input_history_recent
11
+ ON composer_input_history(conversation_id, id DESC);
@@ -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 = 217;
5
5
  /** Latest schema version this release supports (increment when adding migrations). */
6
- export declare const XOPC_DB_SCHEMA_VERSION = 256;
6
+ export declare const XOPC_DB_SCHEMA_VERSION = 257;
7
7
  export declare function resolveMigrationsDir(override?: string): string;
8
8
  /**
9
9
  * Apply sequential SQL migrations from (currentVersion + 1) through targetVersion.
@@ -48,7 +48,7 @@ function applySingleMigration(db, migration) {
48
48
  function applyPendingMigrations(db, options = {}) {
49
49
  db.function("xopc_memory_search_text", { deterministic: true }, (value) => memorySearchText(String(value ?? "")));
50
50
  db.function("xopc_operation_id", () => currentOperationId() ?? null);
51
- const targetVersion = options.targetVersion ?? 256;
51
+ const targetVersion = options.targetVersion ?? 257;
52
52
  let currentVersion = readSchemaVersion(db);
53
53
  if (currentVersion > targetVersion) throw new DatabaseSchemaTooNewError(currentVersion, targetVersion);
54
54
  if (!options.migrationsDir && currentVersion < 217) throw new DatabaseSchemaTooOldError(currentVersion, 217);
@@ -65,7 +65,7 @@ function applyPendingMigrations(db, options = {}) {
65
65
  }
66
66
  /** Inspect schema version without mutating the database. */
67
67
  function inspectSchemaMigrationStatus(db, options = {}) {
68
- const appVersion = options.targetVersion ?? 256;
68
+ const appVersion = options.targetVersion ?? 257;
69
69
  const dbVersion = readSchemaVersion(db);
70
70
  if (dbVersion > appVersion) return {
71
71
  dbVersion,
@@ -105,7 +105,7 @@ var init_runner = __esmMin((() => {
105
105
  init_errors();
106
106
  log = createLogger("Sqlite:Migrations");
107
107
  XOPC_DB_BASELINE_SCHEMA_VERSION = 217;
108
- XOPC_DB_SCHEMA_VERSION = 256;
108
+ XOPC_DB_SCHEMA_VERSION = 257;
109
109
  }));
110
110
  //#endregion
111
111
  init_runner();
@@ -26,7 +26,7 @@ function ensureXopcDatabaseSchema(db) {
26
26
  bootstrapFreshDatabase(db);
27
27
  currentVersion = 217;
28
28
  }
29
- applyPendingMigrations(db, { targetVersion: 256 });
29
+ applyPendingMigrations(db, { targetVersion: 257 });
30
30
  }
31
31
  var init_schema = __esmMin((() => {
32
32
  init_sql_assets();
@@ -36,9 +36,9 @@ export declare class EmbeddedBackend implements TuiBackend {
36
36
  onDisconnected?: (reason: string) => void;
37
37
  constructor(opts?: EmbeddedBackendOptions);
38
38
  get connectionLabel(): string;
39
- getComposerInputHistory(): Promise<TuiComposerHistoryItem[]>;
39
+ getComposerInputHistory(conversationId: string): Promise<TuiComposerHistoryItem[]>;
40
40
  getComposerDraftDirectory(): Promise<string>;
41
- recordComposerInputHistory(text: string): Promise<TuiComposerHistoryItem>;
41
+ recordComposerInputHistory(conversationId: string, text: string): Promise<TuiComposerHistoryItem>;
42
42
  start(): void;
43
43
  private ensureAgent;
44
44
  private createAgent;
@@ -104,14 +104,14 @@ var EmbeddedBackend = class {
104
104
  get connectionLabel() {
105
105
  return "local embedded";
106
106
  }
107
- async getComposerInputHistory() {
108
- return listComposerInputHistory();
107
+ async getComposerInputHistory(conversationId) {
108
+ return listComposerInputHistory(conversationId);
109
109
  }
110
110
  async getComposerDraftDirectory() {
111
111
  return join(resolveStateDir(), "client-drafts", "embedded", "composers");
112
112
  }
113
- async recordComposerInputHistory(text) {
114
- return appendComposerInputHistory(text).item;
113
+ async recordComposerInputHistory(conversationId, text) {
114
+ return appendComposerInputHistory(conversationId, text).item;
115
115
  }
116
116
  start() {
117
117
  if (this.running) return;
@@ -42,8 +42,8 @@ export declare class GatewayRealtimeBackend implements TuiBackend {
42
42
  start(): void;
43
43
  stop(): void;
44
44
  getActiveSignal(): AbortSignal | undefined;
45
- getComposerInputHistory(): Promise<TuiComposerHistoryItem[]>;
46
- recordComposerInputHistory(text: string): Promise<TuiComposerHistoryItem>;
45
+ getComposerInputHistory(conversationId: string): Promise<TuiComposerHistoryItem[]>;
46
+ recordComposerInputHistory(conversationId: string, text: string): Promise<TuiComposerHistoryItem>;
47
47
  private acceptReceipt;
48
48
  private reconcileInput;
49
49
  private prepareInput;
@@ -133,15 +133,18 @@ var GatewayRealtimeBackend = class {
133
133
  const signal = this.chatAbort?.signal;
134
134
  return signal && !signal.aborted ? signal : void 0;
135
135
  }
136
- async getComposerInputHistory() {
137
- const res = await gatewayFetch(this.baseUrl, "/api/composer-history", this.credential);
136
+ async getComposerInputHistory(conversationId) {
137
+ const res = await gatewayFetch(this.baseUrl, `/api/composer-history?conversationId=${encodeURIComponent(conversationId)}`, this.credential);
138
138
  if (!res.ok) throw new Error(`Failed to load composer history (${res.status})`);
139
139
  return (await res.json()).items ?? [];
140
140
  }
141
- async recordComposerInputHistory(text) {
141
+ async recordComposerInputHistory(conversationId, text) {
142
142
  const res = await gatewayFetch(this.baseUrl, "/api/composer-history", this.credential, {
143
143
  method: "POST",
144
- body: JSON.stringify({ text })
144
+ body: JSON.stringify({
145
+ conversationId,
146
+ text
147
+ })
145
148
  });
146
149
  if (!res.ok) throw new Error(`Failed to save composer history (${res.status})`);
147
150
  return (await res.json()).item;