@xopcai/xopc 0.0.252 → 0.0.254

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 (220) hide show
  1. package/dist/browser-ext/dist/background.js +59 -13
  2. package/dist/browser-ext/dist/content.js +0 -5
  3. package/dist/browser-ext/manifest.json +2 -1
  4. package/dist/extensions/telegram/src/inbound-processor.js +2 -2
  5. package/dist/extensions/telegram/src/plugin.js +3 -2
  6. package/dist/extensions/telegram/xopc.extension.json +1 -1
  7. package/dist/gateway/static/root/assets/{activity-store-w3eq3YpP.js → activity-store-Ci5Rxmi_.js} +1 -1
  8. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-k039rbUz.js → agent-avatar-dicebear-D82jpmFL.js} +1 -1
  9. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-vul32IsP.js +1 -0
  10. package/dist/gateway/static/root/assets/{agents-Bmth_bSQ.js → agents-p3kWyz1T.js} +1 -1
  11. package/dist/gateway/static/root/assets/{api-2joIfbrH.js → api-CXIzQJ2Z.js} +1 -1
  12. package/dist/gateway/static/root/assets/{app-management-settings-panel-ByJ4kiD0.js → app-management-settings-panel-mhxcQpkQ.js} +1 -1
  13. package/dist/gateway/static/root/assets/{appearance-settings-BK2Jga-B.js → appearance-settings-BIMwACUF.js} +1 -1
  14. package/dist/gateway/static/root/assets/apps-page-CJFJKNwS.js +1 -0
  15. package/dist/gateway/static/root/assets/{archive-plugin-DMDKtYpi.js → archive-plugin-C63Xp_sU.js} +1 -1
  16. package/dist/gateway/static/root/assets/{attachment-load-B764Ql3Z.js → attachment-load-D12KYOav.js} +1 -1
  17. package/dist/gateway/static/root/assets/{automations-page-D-sO8CZe.js → automations-page-DXj0o5CY.js} +1 -1
  18. package/dist/gateway/static/root/assets/automations-workspace-B2wxcpgq.js +6 -0
  19. package/dist/gateway/static/root/assets/{binary-plugins-fxtzYRpv.js → binary-plugins-Bcv8hun6.js} +1 -1
  20. package/dist/gateway/static/root/assets/{block-editor-Bcjtvckh.js → block-editor-C61LqK_-.js} +50 -50
  21. package/dist/gateway/static/root/assets/{browser-automation-inputs-BSmnusjD.js → browser-automation-inputs-CAclu735.js} +1 -1
  22. package/dist/gateway/static/root/assets/{browser-automations-page-DC_OQIBk.js → browser-automations-page-BITfKX8L.js} +2 -2
  23. package/dist/gateway/static/root/assets/browser-settings-page-BMjY8cyv.js +8 -0
  24. package/dist/gateway/static/root/assets/capabilities-settings-panel-wB3Vgmp3.js +7 -0
  25. package/dist/gateway/static/root/assets/channels-settings-U5ffzu4r.js +1 -0
  26. package/dist/gateway/static/root/assets/{channels-status-swr-BuWjIG_a.js → channels-status-swr-Cmbx0E8O.js} +1 -1
  27. package/dist/gateway/static/root/assets/{chat-terminal-dock-5SevEo_I.js → chat-terminal-dock-CNBgHN9U.js} +1 -1
  28. package/dist/gateway/static/root/assets/connectors-page-BGaF--m5.js +2 -0
  29. package/dist/gateway/static/root/assets/{cron-expression-DtsfalBM.js → cron-expression-DCTN4QAG.js} +1 -1
  30. package/dist/gateway/static/root/assets/{date-picker-tDEQV5TP.js → date-picker-BuEyUxZn.js} +1 -1
  31. package/dist/gateway/static/root/assets/{dependency-picker-HhNwg0Y2.js → dependency-picker-l6IXzk0C.js} +1 -1
  32. package/dist/gateway/static/root/assets/{desktop-pet-acU4Li-C.js → desktop-pet-cGn_20DO.js} +1 -1
  33. package/dist/gateway/static/root/assets/{desktop-pet-settings-R84AR0Pe.js → desktop-pet-settings-DIfccDKS.js} +1 -1
  34. package/dist/gateway/static/root/assets/{extension-debug-page-CrLlRkSN.js → extension-debug-page-CTS5RP_D.js} +1 -1
  35. package/dist/gateway/static/root/assets/{extension-page-BH5lmZXE.js → extension-page-Dg9YssYH.js} +1 -1
  36. package/dist/gateway/static/root/assets/{extension-settings-page-BscjNAd1.js → extension-settings-page-CWZYL8Fi.js} +1 -1
  37. package/dist/gateway/static/root/assets/{gateway-config-swr-9HidFZUd.js → gateway-config-swr-Chsr5wGH.js} +1 -1
  38. package/dist/gateway/static/root/assets/gateway-settings-vHI_Que8.js +1 -0
  39. package/dist/gateway/static/root/assets/{gateway-startup-retry-DRCPXONr.js → gateway-startup-retry-C9ynH6VV.js} +1 -1
  40. package/dist/gateway/static/root/assets/{heartbeat-settings-K5Zhl2rx.js → heartbeat-settings-WUhSfvob.js} +1 -1
  41. package/dist/gateway/static/root/assets/home-page-CYjlMzPx.js +1 -0
  42. package/dist/gateway/static/root/assets/{image-generation-api-CR6Kle8H.js → image-generation-api-D_TsVe7h.js} +1 -1
  43. package/dist/gateway/static/root/assets/index-BBlJYVxR.js +74 -0
  44. package/dist/gateway/static/root/assets/index-_I0dD2LN.css +2 -0
  45. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-B1QR49-7.js → keyboard-shortcuts-settings-DGBf6YfD.js} +1 -1
  46. package/dist/gateway/static/root/assets/local-app-workbench-page-CLlIl83V.js +2 -0
  47. package/dist/gateway/static/root/assets/{local-apps-page-C74It-T8.js → local-apps-page-DGWP_xsQ.js} +1 -1
  48. package/dist/gateway/static/root/assets/{locale-store-BfZGZKSs.js → locale-store-B2v8mNJw.js} +1 -1
  49. package/dist/gateway/static/root/assets/logs-page-DuhCigiB.js +2 -0
  50. package/dist/gateway/static/root/assets/{management-settings-1kNnYL97.js → management-settings-DUAZ-dtt.js} +1 -1
  51. package/dist/gateway/static/root/assets/markdown-view-DBWu9d_n.js +201 -0
  52. package/dist/gateway/static/root/assets/{media-plugins-B5c0AoS1.js → media-plugins-CsUjcIBy.js} +1 -1
  53. package/dist/gateway/static/root/assets/messages-ChSTFZR5.js +3 -0
  54. package/dist/gateway/static/root/assets/{mobile-pairing-wizard-CsIZqK51.js → mobile-pairing-wizard-Dxu8twiQ.js} +1 -1
  55. package/dist/gateway/static/root/assets/note-detail-panel-DMdbaTZp.js +5 -0
  56. package/dist/gateway/static/root/assets/notes-page-xe_vX0nM.js +8 -0
  57. package/dist/gateway/static/root/assets/{page-tabs-CqJN6Ljz.js → page-tabs-YeJKwV-7.js} +1 -1
  58. package/dist/gateway/static/root/assets/{preview-open-alternatives-DqRIGxf4.js → preview-open-alternatives-BfJ3jMDG.js} +1 -1
  59. package/dist/gateway/static/root/assets/{product-open-page-DE2nPE_K.js → product-open-page-B7NRGPox.js} +1 -1
  60. package/dist/gateway/static/root/assets/project-detail-page-hG7ELibZ.js +1 -0
  61. package/dist/gateway/static/root/assets/projects-page-C5G2ET4w.js +1 -0
  62. package/dist/gateway/static/root/assets/{registry-api-Bpy8XX-5.js → registry-api-B9OZUdwC.js} +1 -1
  63. package/dist/gateway/static/root/assets/{remote-access-hub-Dnd73xWt.js → remote-access-hub-DTO-faxH.js} +1 -1
  64. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-Bb4b74-P.js → runtime-tools-settings-panel-uJ8Br3ZL.js} +1 -1
  65. package/dist/gateway/static/root/assets/{schema-form-DoPU5j3J.js → schema-form-CXwn6up5.js} +1 -1
  66. package/dist/gateway/static/root/assets/sessions-page-CwzsUCgP.js +1 -0
  67. package/dist/gateway/static/root/assets/settings-advanced-gate-Djc3EdoO.js +1 -0
  68. package/dist/gateway/static/root/assets/{settings-form-section-Ci-9WajJ.js → settings-form-section-YVNYsR0U.js} +1 -1
  69. package/dist/gateway/static/root/assets/{settings-page-CL_2F95D.js → settings-page-cHqrIdVR.js} +1 -1
  70. package/dist/gateway/static/root/assets/setup-status-panel-MUAMcZLD.js +1 -0
  71. package/dist/gateway/static/root/assets/{share-preview-page-XUA3oKQX.js → share-preview-page-DnjSDQru.js} +1 -1
  72. package/dist/gateway/static/root/assets/shares-settings-C7A0aywX.js +1 -0
  73. package/dist/gateway/static/root/assets/skill-reload-api-D1xSGJAQ.js +1 -0
  74. package/dist/gateway/static/root/assets/{skills-page-sXXAZDc9.js → skills-page-DkrGEdiY.js} +1 -1
  75. package/dist/gateway/static/root/assets/{skills-page.utils-DD79Bl1I.js → skills-page.utils-CqZbiZuK.js} +1 -1
  76. package/dist/gateway/static/root/assets/{system-settings-panel-BEH64qBV.js → system-settings-panel-Dmw0RfxZ.js} +1 -1
  77. package/dist/gateway/static/root/assets/task-detail-page-BvZSCLUH.js +1 -0
  78. package/dist/gateway/static/root/assets/{theme-store-CISSxU1c.js → theme-store-CubltMKm.js} +1 -1
  79. package/dist/gateway/static/root/assets/{tunnel-api-DrKDhnJm.js → tunnel-api-CiieC6HP.js} +1 -1
  80. package/dist/gateway/static/root/assets/{use-autosave-CPYePL-Q.js → use-autosave-XQ3SuyB9.js} +1 -1
  81. package/dist/gateway/static/root/assets/user-model-page-BKJC7tyW.js +2 -0
  82. package/dist/gateway/static/root/assets/{voice-api-key-field-DKqzrCXx.js → voice-api-key-field-D4QzVgdt.js} +1 -1
  83. package/dist/gateway/static/root/assets/{voice-config-api-e9xWjwBX.js → voice-config-api-B1ZbyVmF.js} +1 -1
  84. package/dist/gateway/static/root/assets/{work-discovery-overlay-kTQug6bq.js → work-discovery-overlay-D5Tf8GRZ.js} +1 -1
  85. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-m9SKj_GT.js → workflow-run-setup-panel-BW9p8Maz.js} +2 -2
  86. package/dist/gateway/static/root/assets/workflows-page-DuqRodIc.js +5 -0
  87. package/dist/gateway/static/root/index.html +10 -10
  88. package/dist/package.js +1 -1
  89. package/dist/packages/realtime-protocol/src/voice.js +6 -1
  90. package/dist/src/agent/agent-manager.js +24 -7
  91. package/dist/src/agent/background-review/run-background-review.js +1 -1
  92. package/dist/src/agent/embedded/execution-context.d.ts +2 -1
  93. package/dist/src/agent/embedded/execution-context.js +10 -4
  94. package/dist/src/agent/embedded/index.d.ts +1 -1
  95. package/dist/src/agent/embedded/index.js +2 -2
  96. package/dist/src/agent/embedded/model-runtime.js +1 -1
  97. package/dist/src/agent/embedded/run-for-session.js +5 -4
  98. package/dist/src/agent/embedded/run-turn.js +22 -3
  99. package/dist/src/agent/embedded/types.d.ts +1 -1
  100. package/dist/src/agent/image/tool-model-config.js +1 -1
  101. package/dist/src/agent/mcp/oauth/mcp-oauth-store.js +1 -1
  102. package/dist/src/agent/service/direct-turn-helpers.js +6 -3
  103. package/dist/src/agent/service/process-direct-streaming.js +6 -3
  104. package/dist/src/agent/service.d.ts +2 -0
  105. package/dist/src/agent/service.js +23 -9
  106. package/dist/src/agent/session/session-inspector.js +1 -1
  107. package/dist/src/agent/skills/hub-lock.js +1 -1
  108. package/dist/src/agent/tasks/task-judge-service.js +3 -3
  109. package/dist/src/agent/tools/browser/tool/browser-use-tool.js +17 -2
  110. package/dist/src/agent/tools/browser/tool/schemas.d.ts +85 -1
  111. package/dist/src/agent/tools/browser/tool/schemas.js +212 -5
  112. package/dist/src/agent/tools/clarify-tool.d.ts +17 -3
  113. package/dist/src/agent/tools/clarify-tool.js +27 -32
  114. package/dist/src/agent/tools/cli-clarify.js +23 -8
  115. package/dist/src/agent/tools/factory.js +14 -4
  116. package/dist/src/ai-assist/text-assist.js +1 -1
  117. package/dist/src/auth/credentials.js +2 -2
  118. package/dist/src/auth/oauth/xopc-cloud.js +1 -1
  119. package/dist/src/auth/profiles/store.js +1 -1
  120. package/dist/src/auth/sync-provider-auth.js +2 -2
  121. package/dist/src/automations/domain/validation.d.ts +4 -4
  122. package/dist/src/automations/draft/automation-draft-validator.d.ts +1 -1
  123. package/dist/src/browser/drivers/extension-driver.d.ts +4 -4
  124. package/dist/src/browser/drivers/extension-driver.js +20 -8
  125. package/dist/src/browser/drivers/playwright-driver.js +1 -1
  126. package/dist/src/browser/providers/browser-ext-install.d.ts +3 -0
  127. package/dist/src/browser/providers/browser-ext-install.js +19 -4
  128. package/dist/src/browser/providers/extension.d.ts +14 -1
  129. package/dist/src/browser/providers/extension.js +89 -11
  130. package/dist/src/browser/providers/playwright-install.js +8 -12
  131. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  132. package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
  133. package/dist/src/cli/commands/models.js +1 -1
  134. package/dist/src/config/index.js +4 -4
  135. package/dist/src/config/loader.js +2 -2
  136. package/dist/src/config/models-json.js +1 -1
  137. package/dist/src/extensions/lockfile.js +1 -1
  138. package/dist/src/gateway/agents-admin.js +1 -1
  139. package/dist/src/gateway/chat-stream/mapper.js +5 -1
  140. package/dist/src/gateway/chat-stream/protocol.d.ts +5 -1
  141. package/dist/src/gateway/clarify-runtime.d.ts +7 -5
  142. package/dist/src/gateway/clarify-runtime.js +8 -11
  143. package/dist/src/gateway/ephemeral-clarification-waiter.d.ts +17 -0
  144. package/dist/src/gateway/ephemeral-clarification-waiter.js +46 -0
  145. package/dist/src/gateway/file-path-classifier.js +1 -1
  146. package/dist/src/gateway/heartbeat/service.js +1 -1
  147. package/dist/src/gateway/hono/lib/config-payload.js +1 -1
  148. package/dist/src/gateway/hono/routes/agent-stream.js +44 -18
  149. package/dist/src/gateway/hono/routes/browser.js +149 -27
  150. package/dist/src/gateway/hono/routes/lazy-bundles.js +1 -1
  151. package/dist/src/gateway/hono/routes/models.js +1 -1
  152. package/dist/src/gateway/hono/routes/session-input-handler.d.ts +10 -2
  153. package/dist/src/gateway/hono/routes/side-chats.js +24 -4
  154. package/dist/src/gateway/security/gateway-scopes.js +1 -1
  155. package/dist/src/gateway/service/agent-runner.d.ts +25 -36
  156. package/dist/src/gateway/service/agent-runner.js +103 -32
  157. package/dist/src/gateway/service/config-coordinator.js +1 -1
  158. package/dist/src/gateway/service/run-gateway-agent.js +5 -2
  159. package/dist/src/gateway/service/session-input-coordinator.js +4 -1
  160. package/dist/src/gateway/service/sessions-api.js +1 -1
  161. package/dist/src/gateway/service.d.ts +4 -2
  162. package/dist/src/gateway/service.js +36 -20
  163. package/dist/src/gateway/side-chat/manager.d.ts +2 -1
  164. package/dist/src/gateway/side-chat/manager.js +5 -4
  165. package/dist/src/gateway/side-chat/run-service.d.ts +5 -1
  166. package/dist/src/gateway/side-chat/run-service.js +24 -23
  167. package/dist/src/gateway/side-chat/types.d.ts +3 -1
  168. package/dist/src/heartbeat/index.js +1 -1
  169. package/dist/src/providers/auth-runtime/resolve-auth.js +1 -1
  170. package/dist/src/providers/index.js +2 -2
  171. package/dist/src/providers/model-registry.js +1 -1
  172. package/dist/src/providers/model-thinking.js +57 -20
  173. package/dist/src/providers/register-runtime-providers.js +1 -1
  174. package/dist/src/storage/sqlite/clarification-wait-repository.d.ts +41 -0
  175. package/dist/src/storage/sqlite/clarification-wait-repository.js +418 -0
  176. package/dist/src/storage/sqlite/index.d.ts +2 -1
  177. package/dist/src/storage/sqlite/index.js +2 -1
  178. package/dist/src/storage/sqlite/migrations/154_session_clarification_waits.sql +60 -0
  179. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  180. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  181. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  182. package/dist/src/storage/sqlite/schema.js +1 -1
  183. package/dist/src/storage/sqlite/session-input-repository.d.ts +11 -6
  184. package/dist/src/tui/tui-startup-resources.js +1 -1
  185. package/dist/src/tui/tui.js +1 -1
  186. package/dist/src/voice/realtime/agentEngine.js +7 -2
  187. package/dist/src/voice/realtime/runtime.types.d.ts +5 -0
  188. package/dist/src/work-discovery/service.js +1 -1
  189. package/dist/src/workflows/service/workflow-run-service.js +1 -1
  190. package/package.json +3 -3
  191. package/skills/creative/hatch-pet/SKILL.md +1 -1
  192. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-D4J4oq8p.js +0 -1
  193. package/dist/gateway/static/root/assets/apps-page-B3ky7cWU.js +0 -1
  194. package/dist/gateway/static/root/assets/automations-workspace-Ds5-_-9z.js +0 -6
  195. package/dist/gateway/static/root/assets/browser-settings-page-C1FojyG6.js +0 -3
  196. package/dist/gateway/static/root/assets/capabilities-settings-panel-Bs59UCut.js +0 -7
  197. package/dist/gateway/static/root/assets/channels-settings-CM9vNmoo.js +0 -1
  198. package/dist/gateway/static/root/assets/connectors-page-BPZ44D-V.js +0 -2
  199. package/dist/gateway/static/root/assets/gateway-settings-BxLcW6ij.js +0 -1
  200. package/dist/gateway/static/root/assets/home-page-CZAg9RBv.js +0 -1
  201. package/dist/gateway/static/root/assets/index-D4Ykja-U.js +0 -72
  202. package/dist/gateway/static/root/assets/index-zIJ3AXgR.css +0 -2
  203. package/dist/gateway/static/root/assets/local-app-workbench-page-wicoV-ti.js +0 -2
  204. package/dist/gateway/static/root/assets/logs-page-xX-7S49A.js +0 -2
  205. package/dist/gateway/static/root/assets/markdown-view-DjiwT28p.js +0 -201
  206. package/dist/gateway/static/root/assets/messages-DaIwVWar.js +0 -3
  207. package/dist/gateway/static/root/assets/note-detail-panel-CfWxopl4.js +0 -5
  208. package/dist/gateway/static/root/assets/notes-page-CYN-LCHJ.js +0 -8
  209. package/dist/gateway/static/root/assets/project-detail-page-B5G3LzDq.js +0 -1
  210. package/dist/gateway/static/root/assets/projects-page-CuVK2mKu.js +0 -1
  211. package/dist/gateway/static/root/assets/sessions-page-XL4LyKZe.js +0 -1
  212. package/dist/gateway/static/root/assets/settings-advanced-gate-0ForzDSS.js +0 -1
  213. package/dist/gateway/static/root/assets/setup-status-panel-DVws6XZc.js +0 -1
  214. package/dist/gateway/static/root/assets/shares-settings-BwDvcacF.js +0 -1
  215. package/dist/gateway/static/root/assets/skill-reload-api-BJjrATqE.js +0 -1
  216. package/dist/gateway/static/root/assets/task-detail-page-0jxMi75O.js +0 -1
  217. package/dist/gateway/static/root/assets/user-model-page-B6zLDfDl.js +0 -2
  218. package/dist/gateway/static/root/assets/workflows-page-Bcd1XqP7.js +0 -5
  219. package/dist/src/gateway/clarify-bridge.d.ts +0 -46
  220. package/dist/src/gateway/clarify-bridge.js +0 -111
@@ -0,0 +1,46 @@
1
+ //#region src/gateway/ephemeral-clarification-waiter.ts
2
+ /** In-memory waiter exclusively for caller-owned ephemeral runs such as side chat. */
3
+ var EphemeralClarificationWaiter = class {
4
+ pending = /* @__PURE__ */ new Map();
5
+ start(input) {
6
+ const requestId = crypto.randomUUID();
7
+ return new Promise((resolve, reject) => {
8
+ this.pending.set(requestId, {
9
+ runId: input.runId,
10
+ resolve,
11
+ reject,
12
+ beforeResponse: input.beforeResponse
13
+ });
14
+ input.publish({
15
+ type: "clarify_request",
16
+ requestId,
17
+ kind: input.request.kind ?? "input",
18
+ question: input.request.question,
19
+ choices: input.request.choices,
20
+ suggestedAnswer: input.request.suggestedAnswer,
21
+ version: 1,
22
+ createdAt: Date.now()
23
+ });
24
+ });
25
+ }
26
+ answer(requestId, answer) {
27
+ const pending = this.pending.get(requestId);
28
+ if (!pending || pending.beforeResponse?.() === false) return false;
29
+ this.pending.delete(requestId);
30
+ pending.resolve(answer.trim());
31
+ return true;
32
+ }
33
+ cancelForRun(runId) {
34
+ for (const [requestId, pending] of this.pending) {
35
+ if (pending.runId !== runId) continue;
36
+ this.pending.delete(requestId);
37
+ pending.reject(/* @__PURE__ */ new Error("Ephemeral clarification cancelled"));
38
+ }
39
+ }
40
+ dispose() {
41
+ for (const pending of this.pending.values()) pending.reject(/* @__PURE__ */ new Error("Gateway shutting down"));
42
+ this.pending.clear();
43
+ }
44
+ };
45
+ //#endregion
46
+ export { EphemeralClarificationWaiter };
@@ -1,7 +1,7 @@
1
1
  import { init_paths_state, resolveStateDir } from "../config/paths-state.js";
2
2
  import { init_agent_scope, resolveAgentProfileDir } from "../agent/agent-scope.js";
3
- import { extractProfileAgentId } from "../config/agent-profile.js";
4
3
  import { init_paths, resolveConfigPath, resolveSkillsDir } from "../config/paths.js";
4
+ import { extractProfileAgentId } from "../config/agent-profile.js";
5
5
  import { isBareProfileMarkdownFileName, resolveProfileMarkdownPathIfBareName } from "../agent/tools/tool-paths.js";
6
6
  import { isPathUnderWorkspace, resolveWorkspaceSafePath } from "./workspace-editor-path.js";
7
7
  import { basename, isAbsolute, resolve } from "node:path";
@@ -1,9 +1,9 @@
1
1
  import { createLogger } from "../../utils/logger/index.js";
2
2
  import { init_logger } from "../../utils/logger.js";
3
3
  import { shouldSilence, stripHeartbeatToken } from "../../heartbeat/tokens.js";
4
- import { appendCronEventLines } from "../../heartbeat/event-prompt.js";
5
4
  import { isWithinActiveHours } from "../../heartbeat/active-hours.js";
6
5
  import { isHeartbeatContentEmpty } from "../../heartbeat/content-check.js";
6
+ import { appendCronEventLines } from "../../heartbeat/event-prompt.js";
7
7
  import { createHeartbeatWake } from "../../heartbeat/wake.js";
8
8
  import { resolveHeartbeatMdPath } from "../workspace-heartbeat-path.js";
9
9
  import { readFile } from "fs/promises";
@@ -1,9 +1,9 @@
1
1
  import { ContextPlanningConfigSchema, KnowledgeMemoryConfigSchema, UserModelConfigSchema, init_config } from "../../../user-context/config.js";
2
2
  import { init_agent_scope, listAgentEntries, normalizeAgentId, resolveDefaultAgentId } from "../../../agent/agent-scope.js";
3
3
  import { resolveModelsJsonPath } from "../../../config/paths.js";
4
- import { buildChannelCatalogForConfig, buildChannelCatalogFromSnapshot, getChannelSetupStatus, init_channel_catalog_service } from "../../../channels/catalog/channel-catalog-service.js";
5
4
  import { init_models_json, loadModelsJson } from "../../../config/models-json.js";
6
5
  import { CredentialResolver, init_credentials } from "../../../auth/credentials.js";
6
+ import { buildChannelCatalogForConfig, buildChannelCatalogFromSnapshot, getChannelSetupStatus, init_channel_catalog_service } from "../../../channels/catalog/channel-catalog-service.js";
7
7
  import { getProviderRegistry, init_plugin_registry } from "../../../providers/plugin-registry.js";
8
8
  import { getAllProviders, init_providers, isProviderConfigured } from "../../../providers/index.js";
9
9
  import { normalizeConfiguredMcpServers } from "../../../config/mcp-config-normalize.js";
@@ -122,38 +122,64 @@ function registerAgentStreamRoutes(authenticated, deps) {
122
122
  payload: result.state
123
123
  }, 409);
124
124
  });
125
- authenticated.post("/api/clarify/:requestId", chatRateLimitMiddleware, async (c) => {
126
- const requestId = c.req.param("requestId")?.trim() ?? "";
127
- if (!requestId) return c.json({
128
- ok: false,
129
- error: {
130
- code: "BAD_REQUEST",
131
- message: "Missing requestId"
132
- }
133
- }, 400);
134
- const body = await c.req.json().catch(() => null);
135
- const skip = body && typeof body === "object" && body.skip === true;
136
- const rawAnswer = body && typeof body === "object" && typeof body.answer === "string" ? body.answer : "";
137
- const answer = typeof rawAnswer === "string" ? rawAnswer.trim() : "";
138
- if (!skip && !answer) return c.json({
125
+ authenticated.get("/api/sessions/:sessionKey/clarification", (c) => {
126
+ const sessionKey = (c.req.param("sessionKey") ?? "").trim();
127
+ if (!sessionKey) return c.json({
139
128
  ok: false,
140
129
  error: {
141
130
  code: "BAD_REQUEST",
142
- message: "Missing answer field"
131
+ message: "Missing sessionKey"
143
132
  }
144
133
  }, 400);
145
- if (!service.submitClarifyResponse(requestId, skip ? "" : answer)) return c.json({
134
+ const snapshot = service.getClarificationState(sessionKey);
135
+ if (!snapshot) return c.json({
146
136
  ok: false,
147
137
  error: {
148
138
  code: "NOT_FOUND",
149
- message: "No pending clarification with this ID"
139
+ message: "Session not found"
150
140
  }
151
141
  }, 404);
152
142
  return c.json({
153
143
  ok: true,
154
- payload: { received: true }
144
+ payload: snapshot
155
145
  });
156
146
  });
147
+ authenticated.post("/api/clarifications/:id/responses", chatRateLimitMiddleware, async (c) => {
148
+ const id = c.req.param("id")?.trim() ?? "";
149
+ const body = await c.req.json().catch(() => null);
150
+ const record = body && typeof body === "object" ? body : {};
151
+ const action = record.action;
152
+ const expectedVersion = record.expectedVersion;
153
+ const idempotencyKey = typeof record.idempotencyKey === "string" ? record.idempotencyKey.trim() : "";
154
+ if (!id || !idempotencyKey || typeof expectedVersion !== "number" || !Number.isInteger(expectedVersion) || action !== "answer" && action !== "agent_decide" && action !== "cancel") return c.json({
155
+ ok: false,
156
+ error: {
157
+ code: "BAD_REQUEST",
158
+ message: "Invalid clarification response"
159
+ }
160
+ }, 400);
161
+ const result = service.resolveClarificationResponse({
162
+ id,
163
+ expectedVersion,
164
+ idempotencyKey,
165
+ action,
166
+ answer: typeof record.answer === "string" ? record.answer : void 0
167
+ });
168
+ if (result.ok === true) return c.json({
169
+ ok: true,
170
+ payload: result
171
+ }, result.queued ? 202 : 200);
172
+ const status = result.code === "NOT_FOUND" ? 404 : result.code === "EXPIRED" ? 410 : result.code === "INVALID" ? 400 : 409;
173
+ const message = result.code === "NOT_FOUND" ? "This clarification is no longer active" : result.code === "EXPIRED" ? "This approval has expired" : result.code === "INVALID" ? "The clarification response is invalid" : "The clarification changed; reload and try again";
174
+ return c.json({
175
+ ok: false,
176
+ error: {
177
+ code: result.code,
178
+ message
179
+ },
180
+ payload: result.clarification
181
+ }, status);
182
+ });
157
183
  authenticated.post("/api/send", chatRateLimitMiddleware, async (c) => {
158
184
  const body = await c.req.json().catch(() => null);
159
185
  const channel = typeof body?.channel === "string" ? body.channel : "";
@@ -1,9 +1,52 @@
1
1
  import { decideBrowserApproval, listBrowserApprovals } from "../../../browser/policy/approval-store.js";
2
+ import { createBrowserDriver } from "../../../browser/drivers/create-driver.js";
3
+ import { checkBrowserReadiness } from "../../../browser/readiness.js";
2
4
  import { isLoopbackClientIp } from "../../security/loopback.js";
3
5
  import { getConnInfo } from "@hono/node-server/conninfo";
4
6
  //#region src/gateway/hono/routes/browser.ts
5
7
  /** Browser Control status, approvals, and driver diagnostics. */
6
8
  const EXTENSION_ENDPOINT = "http://127.0.0.1:19820/";
9
+ async function extensionStatus() {
10
+ const { getExtensionBrowserServerSnapshot } = await import("../../../browser/providers/extension-ws-acquire.js");
11
+ const snapshot = getExtensionBrowserServerSnapshot();
12
+ let running = snapshot.active;
13
+ let socketConnected = false;
14
+ let connected = false;
15
+ let protocolVersion = null;
16
+ let expectedProtocolVersion = null;
17
+ let extensionVersion = null;
18
+ try {
19
+ const payload = await (await fetch(EXTENSION_ENDPOINT, { signal: AbortSignal.timeout(2e3) })).json();
20
+ running ||= payload.ok === true;
21
+ socketConnected = payload.socketConnected ?? payload.connected === true;
22
+ connected = payload.connected === true;
23
+ protocolVersion = typeof payload.protocolVersion === "number" ? payload.protocolVersion : null;
24
+ expectedProtocolVersion = typeof payload.expectedProtocolVersion === "number" ? payload.expectedProtocolVersion : null;
25
+ extensionVersion = typeof payload.extensionVersion === "string" ? payload.extensionVersion : null;
26
+ } catch {}
27
+ const { browserExtDoctor } = await import("../../../browser/providers/browser-ext-install.js");
28
+ const doctor = await browserExtDoctor({ runtimeExtensionVersion: extensionVersion ?? void 0 });
29
+ return {
30
+ running,
31
+ socketConnected,
32
+ connected,
33
+ driverKind: "extension",
34
+ protocolVersion,
35
+ expectedProtocolVersion,
36
+ extensionVersion,
37
+ artifacts: {
38
+ installed: doctor.installed,
39
+ bundledAvailable: doctor.bundledAvailable,
40
+ extensionDir: doctor.extensionDir,
41
+ xopcVersion: doctor.xopcVersion,
42
+ installedVersion: doctor.installedVersion,
43
+ needsRefresh: doctor.needsRefresh,
44
+ needsChromeReload: doctor.needsChromeReload || socketConnected && !connected
45
+ },
46
+ bridgeHeld: snapshot.active,
47
+ refCount: snapshot.refCount
48
+ };
49
+ }
7
50
  function isLocalOwnerRequest(c, service) {
8
51
  if (service.currentConfig.gateway?.bind === "loopback") return true;
9
52
  try {
@@ -15,37 +58,116 @@ function isLocalOwnerRequest(c, service) {
15
58
  function registerBrowserRoutes(authenticated, deps) {
16
59
  const { service, strictRateLimitMiddleware } = deps;
17
60
  authenticated.get("/api/browser/extension-status", async (c) => {
18
- const { getExtensionBrowserServerSnapshot } = await import("../../../browser/providers/extension-ws-acquire.js");
19
- const snapshot = getExtensionBrowserServerSnapshot();
20
- let running = snapshot.active;
21
- let connected = false;
22
61
  try {
23
- const payload = await (await fetch(EXTENSION_ENDPOINT, { signal: AbortSignal.timeout(2e3) })).json();
24
- running ||= payload.ok === true;
25
- connected = payload.connected === true;
26
- } catch {}
27
- let artifacts;
28
- try {
29
- const { browserExtDoctor } = await import("../../../browser/providers/browser-ext-install.js");
30
- const doctor = await browserExtDoctor();
31
- artifacts = {
32
- installed: doctor.installed,
33
- extensionDir: doctor.extensionDir,
34
- xopcVersion: doctor.xopcVersion,
35
- installedVersion: doctor.installedVersion,
36
- needsRefresh: doctor.needsRefresh,
37
- needsChromeReload: doctor.needsChromeReload
38
- };
39
- } catch {}
62
+ return c.json(await extensionStatus());
63
+ } catch (error) {
64
+ return c.json({
65
+ running: false,
66
+ connected: false,
67
+ driverKind: "extension",
68
+ error: error instanceof Error ? error.message : String(error)
69
+ });
70
+ }
71
+ });
72
+ authenticated.get("/api/browser/status", async (c) => {
73
+ const config = service.currentConfig.browser;
74
+ if (!config.enabled) return c.json({
75
+ ok: true,
76
+ payload: {
77
+ enabled: false,
78
+ driverKind: config.driver.kind,
79
+ state: "disabled"
80
+ }
81
+ });
82
+ const readiness = await checkBrowserReadiness(service.currentConfig);
83
+ const driverStatus = config.driver.kind === "extension" ? await extensionStatus().catch((error) => ({ error: error instanceof Error ? error.message : String(error) })) : config.driver.kind === "playwright" ? await import("../../../browser/providers/playwright-doctor.js").then(({ playwrightChromiumDoctor }) => playwrightChromiumDoctor()) : void 0;
84
+ const extensionConnected = config.driver.kind === "extension" ? driverStatus.connected === true : true;
85
+ const extensionProtocolDetail = config.driver.kind === "extension" && "socketConnected" in driverStatus && driverStatus.socketConnected && !driverStatus.connected ? `Chrome extension protocol ${driverStatus.protocolVersion ?? "unknown"} does not match ${driverStatus.expectedProtocolVersion ?? "the gateway"}. Reload the extension in Chrome.` : void 0;
40
86
  return c.json({
41
- running,
42
- connected,
43
- driverKind: "extension",
44
- artifacts,
45
- bridgeHeld: snapshot.active,
46
- refCount: snapshot.refCount
87
+ ok: true,
88
+ payload: {
89
+ enabled: true,
90
+ driverKind: config.driver.kind,
91
+ state: !readiness && extensionConnected ? "ready" : "needs_attention",
92
+ reason: readiness?.hint.reason ?? (extensionConnected ? void 0 : "extension_not_connected"),
93
+ detail: readiness?.hint.detail ?? extensionProtocolDetail,
94
+ driverStatus
95
+ }
47
96
  });
48
97
  });
98
+ authenticated.post("/api/browser/test", strictRateLimitMiddleware, async (c) => {
99
+ if (!isLocalOwnerRequest(c, service)) return c.json({
100
+ ok: false,
101
+ error: "Local owner access required."
102
+ }, 403);
103
+ if (!service.currentConfig.browser.enabled) return c.json({
104
+ ok: false,
105
+ error: "Browser Control is disabled."
106
+ }, 400);
107
+ const startedAt = Date.now();
108
+ let driver;
109
+ try {
110
+ driver = await createBrowserDriver(service.currentConfig.browser);
111
+ await driver.connect();
112
+ return c.json({
113
+ ok: true,
114
+ payload: {
115
+ driverKind: service.currentConfig.browser.driver.kind,
116
+ durationMs: Date.now() - startedAt
117
+ }
118
+ });
119
+ } catch (error) {
120
+ return c.json({
121
+ ok: false,
122
+ error: error instanceof Error ? error.message : String(error)
123
+ }, 400);
124
+ } finally {
125
+ await driver?.disconnect().catch(() => {});
126
+ }
127
+ });
128
+ authenticated.post("/api/browser/extension/install", strictRateLimitMiddleware, async (c) => {
129
+ if (!isLocalOwnerRequest(c, service)) return c.json({
130
+ ok: false,
131
+ error: "Local owner access required."
132
+ }, 403);
133
+ const body = await c.req.json().catch(() => ({}));
134
+ try {
135
+ const { browserExtDoctor, ensureBrowserExtensionArtifacts } = await import("../../../browser/providers/browser-ext-install.js");
136
+ const result = await ensureBrowserExtensionArtifacts({ force: body.force === true });
137
+ return c.json({
138
+ ok: true,
139
+ payload: {
140
+ ...result,
141
+ doctor: await browserExtDoctor()
142
+ }
143
+ });
144
+ } catch (error) {
145
+ return c.json({
146
+ ok: false,
147
+ error: error instanceof Error ? error.message : String(error)
148
+ }, 500);
149
+ }
150
+ });
151
+ authenticated.post("/api/browser/extension/open", strictRateLimitMiddleware, async (c) => {
152
+ if (!isLocalOwnerRequest(c, service)) return c.json({
153
+ ok: false,
154
+ error: "Local owner access required."
155
+ }, 403);
156
+ const body = await c.req.json().catch(() => ({}));
157
+ const action = body.action === "chrome" || body.action === "folder" || body.action === "both" ? body.action : "both";
158
+ try {
159
+ const { openBrowserExtensionInstallUi } = await import("../../../browser/providers/browser-ext-install.js");
160
+ return c.json({
161
+ ok: true,
162
+ payload: await openBrowserExtensionInstallUi({ action })
163
+ });
164
+ } catch (error) {
165
+ return c.json({
166
+ ok: false,
167
+ error: error instanceof Error ? error.message : String(error)
168
+ }, 400);
169
+ }
170
+ });
49
171
  authenticated.get("/api/browser/approvals", (c) => {
50
172
  if (!isLocalOwnerRequest(c, service)) return c.json({
51
173
  ok: false,
@@ -53,7 +53,7 @@ const AUTHENTICATED_LAZY_ROUTE_BUNDLES = [
53
53
  },
54
54
  {
55
55
  id: "browser-install",
56
- match: (path) => path === "/api/browser/playwright/install/stream",
56
+ match: (path) => path === "/api/browser/playwright/install/stream" || path === "/api/browser/playwright/install/cancel",
57
57
  load: async () => {
58
58
  const { registerBrowserInstallRoutes } = await import("./browser-install.js");
59
59
  return { register: registerBrowserInstallRoutes };
@@ -1,5 +1,5 @@
1
- import { resolveModelsJsonPath } from "../../../config/paths.js";
2
1
  import { init_resolve_config_value, testApiKeyResolution } from "../../../config/resolve-config-value.js";
2
+ import { resolveModelsJsonPath } from "../../../config/paths.js";
3
3
  import { init_models_json, loadModelsJson, saveModelsJson, validateModelsConfig } from "../../../config/models-json.js";
4
4
  import { getModelCatalogStore, init_model_catalog_store } from "../../../providers/model-catalog-store.js";
5
5
  import { getModelRegistry } from "../../../providers/model-registry.js";
@@ -45,11 +45,15 @@ export declare function submitSessionInput(c: Context, deps: AuthenticatedRouteD
45
45
  status: import("../../../storage/sqlite/session-input-repository.js").SessionInputStatus;
46
46
  content: string;
47
47
  taskRunId?: string;
48
- kind: "message" | "connection_resume";
48
+ kind: "message" | "connection_resume" | "clarification_resume";
49
49
  payload?: {
50
50
  waitId: string;
51
51
  objectiveRevision: number;
52
52
  resolution: "continued" | "skipped";
53
+ } | {
54
+ waitId: string;
55
+ objectiveRevision: number;
56
+ resolution: "answered" | "agent_decide" | "cancelled";
53
57
  };
54
58
  attachments?: import("hono/dist/types/utils/types.js").JSONValue[];
55
59
  contextRefs?: {
@@ -141,11 +145,15 @@ export declare function replaceLatestSessionTurn(c: Context, deps: Authenticated
141
145
  status: import("../../../storage/sqlite/session-input-repository.js").SessionInputStatus;
142
146
  content: string;
143
147
  taskRunId?: string;
144
- kind: "message" | "connection_resume";
148
+ kind: "message" | "connection_resume" | "clarification_resume";
145
149
  payload?: {
146
150
  waitId: string;
147
151
  objectiveRevision: number;
148
152
  resolution: "continued" | "skipped";
153
+ } | {
154
+ waitId: string;
155
+ objectiveRevision: number;
156
+ resolution: "answered" | "agent_decide" | "cancelled";
149
157
  };
150
158
  attachments?: import("hono/dist/types/utils/types.js").JSONValue[];
151
159
  contextRefs?: {
@@ -1,9 +1,13 @@
1
- import { validateWebchatContent } from "../../chat-limits.js";
1
+ import { chooseModelThinking } from "../../../../packages/gateway-contract/src/model-selection.js";
2
+ import { init_providers, resolveModel } from "../../../providers/index.js";
3
+ import { getModelThinking } from "../../../providers/model-thinking.js";
4
+ import { validateWebchatAttachments, validateWebchatContent } from "../../chat-limits.js";
2
5
  import { validateSideChatSelections } from "../../side-chat/context-snapshot.js";
3
6
  import { SideChatError, parseThinkingLevel } from "../../side-chat/manager.js";
4
7
  import "../../side-chat/index.js";
5
8
  import { createGatewayRouteLogger, logRouteError } from "../lib/route-logger.js";
6
9
  //#region src/gateway/hono/routes/side-chats.ts
10
+ init_providers();
7
11
  const CLIENT_HEADER = "x-xopc-client-instance-id";
8
12
  const log = createGatewayRouteLogger("SideChats");
9
13
  function registerSideChatRoutes(authenticated, deps) {
@@ -64,9 +68,18 @@ function registerSideChatRoutes(authenticated, deps) {
64
68
  const body = await c.req.json().catch(() => ({}));
65
69
  if (body.modelRef !== void 0 && typeof body.modelRef !== "string") throw new SideChatError("modelRef must be a string", "INVALID_REQUEST");
66
70
  const modelRef = typeof body.modelRef === "string" ? body.modelRef : void 0;
71
+ const current = service.sideChats.get(c.req.param("sideChatId"), readClientInstanceId(c, body.clientInstanceId));
72
+ const nextModelRef = modelRef ?? current.config.modelRef;
73
+ let thinking;
74
+ try {
75
+ thinking = getModelThinking(resolveModel(nextModelRef));
76
+ } catch {
77
+ throw new SideChatError(`Model unavailable: ${nextModelRef}`, "INVALID_REQUEST");
78
+ }
79
+ const requestedThinking = parseThinkingLevel(body.thinkingLevel);
67
80
  const sideChat = service.sideChats.updateConfig(c.req.param("sideChatId"), readClientInstanceId(c, body.clientInstanceId), {
68
- modelRef,
69
- thinkingLevel: parseThinkingLevel(body.thinkingLevel)
81
+ modelRef: nextModelRef,
82
+ thinkingLevel: chooseModelThinking(thinking, requestedThinking ?? current.config.thinkingLevel)
70
83
  });
71
84
  return c.json({
72
85
  ok: true,
@@ -101,9 +114,16 @@ function registerSideChatRoutes(authenticated, deps) {
101
114
  try {
102
115
  const body = await c.req.json().catch(() => ({}));
103
116
  const content = typeof body.content === "string" ? body.content : "";
117
+ const attachments = Array.isArray(body.attachments) ? body.attachments : void 0;
104
118
  const contentError = validateWebchatContent(content);
105
119
  if (contentError) throw new SideChatError(contentError, "INVALID_REQUEST");
106
- const result = service.sideChatRuns.submit(c.req.param("sideChatId"), readClientInstanceId(c, body.clientInstanceId), content);
120
+ const attachmentError = validateWebchatAttachments(attachments);
121
+ if (attachmentError) throw new SideChatError(attachmentError, "INVALID_REQUEST");
122
+ if (!content.trim() && !attachments?.length) throw new SideChatError("content or attachments are required", "INVALID_REQUEST");
123
+ const result = service.sideChatRuns.submit(c.req.param("sideChatId"), readClientInstanceId(c, body.clientInstanceId), {
124
+ content,
125
+ attachments
126
+ });
107
127
  return c.json({
108
128
  ok: true,
109
129
  payload: result
@@ -57,7 +57,7 @@ function requiredGatewayScope(method, path) {
57
57
  if (path.startsWith("/api/home") || path.startsWith("/api/inbox")) return methodScope(method, "tasks.read", "tasks.write");
58
58
  if (path.startsWith("/api/automations") || path.startsWith("/api/automation-runs")) return methodScope(method, "automations.read", "automations.write");
59
59
  if (path.startsWith("/api/workflows")) return methodScope(method, "automations.read", "automations.write");
60
- if (path.startsWith("/api/voice") || path.startsWith("/api/media") || path.startsWith("/api/clarify")) return "sessions.write";
60
+ if (path.startsWith("/api/voice") || path.startsWith("/api/media") || path.startsWith("/api/clarifications")) return "sessions.write";
61
61
  if (path.startsWith("/api/commands") || path.startsWith("/api/skills")) return methodScope(method, "agents.read", "gateway.admin");
62
62
  if (path.startsWith("/api/workspace") || path.startsWith("/api/files") || path.startsWith("/api/projects") || path.startsWith("/api/notes") || path.startsWith("/api/shares")) return methodScope(method, "workspace.read", "workspace.write");
63
63
  return "gateway.admin";
@@ -1,31 +1,12 @@
1
1
  import type { TurnOrigin } from '@xopcai/endpoint-tools-protocol';
2
- /**
3
- * GatewayAgentRunner — webchat agent invocation and the surrounding control
4
- * surface (abort, steer, clarify-bridge plumbing, scheduled Task continuations).
5
- *
6
- * Was 200 lines of `GatewayService` covering seven concerns that all hung off
7
- * the same handful of fields (`activeWebchatRunBySession`, `runAbortControllers`,
8
- * `clarifyBridge`, `runRelay`):
9
- *
10
- * - `runAgent(message, channel, chatId, ...)` — wraps {@link runGatewayAgent}
11
- * - `abortAgentRun(runId)` — POST /api/agent/abort + cleanup
12
- * - `submitClarifyResponse(requestId, answer)` — UI answers a `clarify` call
13
- * - `runScheduledWebchatTurn(sk, userTurn)` — background webchat user turn
14
- * - `drainScheduledWebchatContinuation(sk, msg)` — background Task continuation
15
- * - `clarifyForSession({ sessionKey, request })` — clarify-bridge dispatch
16
- * used by `gatewayClarify.requestClarification` in AgentService
17
- *
18
- * Owns the two state maps (`activeWebchatRunBySession`, `runAbortControllers`)
19
- * directly so peer coordinators (sessions-api, marketplace, config) cannot
20
- * accidentally mutate them.
21
- */
2
+ import type { ClarificationResponseAction } from '@xopcai/gateway-contract';
22
3
  import type { Config } from '../../config/schema.js';
23
4
  import type { MessageBus } from '../../infra/bus/index.js';
24
5
  import type { AgentService } from '../../agent/service.js';
25
6
  import type { ChannelManager } from '../../channels/manager.js';
26
7
  import type { SessionIndex } from '../../session/index.js';
27
- import type { ClarifyStreamEvent } from '../clarify-bridge.js';
28
- import { ClarifyBridge, type ClarifyBridgeRequest } from '../clarify-bridge.js';
8
+ import { type ClarificationStreamEvent } from '../ephemeral-clarification-waiter.js';
9
+ import type { ClarifyRequestPayload, ClarifyRequestResult } from '../../agent/tools/clarify-tool.js';
29
10
  import type { UserTurnAttachment, UserTurnInput } from '../user-turn-input.js';
30
11
  import type { AgentSourceContext, TurnContextRef } from '../../agent/source-context/types.js';
31
12
  import { SessionInputCoordinator, type ReplaceLatestTurnInput, type SubmitSessionInput } from './session-input-coordinator.js';
@@ -49,11 +30,10 @@ export declare class GatewayAgentRunner {
49
30
  private readonly runAbortControllers;
50
31
  private readonly runCompletions;
51
32
  private readonly resolveRunCompletions;
52
- private readonly clarifyBridge;
33
+ private readonly ephemeralClarifications;
53
34
  /** Maps webchat session key → active `runId` for `clarify` tool routing. */
54
35
  private readonly activeWebchatRunBySession;
55
36
  private readonly externalStreamBySession;
56
- private readonly externalClarificationTimeouts;
57
37
  private readonly externalClarificationResponses;
58
38
  readonly inputs: SessionInputCoordinator;
59
39
  private readonly unsubscribeConnectionWait;
@@ -65,11 +45,8 @@ export declare class GatewayAgentRunner {
65
45
  sessionKey: string;
66
46
  runId: string;
67
47
  }>;
68
- getClarifyBridge(): ClarifyBridge;
69
- /** Called from `GatewayService.stop()` so the bridge gets cleaned up. */
70
- disposeClarifyBridge(): void;
71
- registerExternalWebchatRun(sessionKey: string, runId: string, publish: (event: ClarifyStreamEvent) => void, options?: {
72
- clarificationTimeoutMs?: number | null;
48
+ disposeClarifications(): void;
49
+ registerExternalWebchatRun(sessionKey: string, runId: string, publish: (event: ClarificationStreamEvent) => void, options?: {
73
50
  beforeClarificationResponse?: () => boolean;
74
51
  }): void;
75
52
  unregisterExternalWebchatRun(sessionKey: string, runId: string): void;
@@ -126,16 +103,26 @@ export declare class GatewayAgentRunner {
126
103
  aborted: boolean;
127
104
  idle: boolean;
128
105
  }>;
129
- /** Deliver a user's answer to a pending `clarify` tool call. */
130
- submitClarifyResponse(requestId: string, answer: string): boolean;
106
+ answerEphemeralClarification(requestId: string, answer: string): boolean;
107
+ getClarificationState(sessionKey: string): import("@xopcai/gateway-contract").ClarificationWaitSnapshot;
108
+ resolveClarificationResponse(input: {
109
+ id: string;
110
+ expectedVersion: number;
111
+ idempotencyKey: string;
112
+ action: ClarificationResponseAction;
113
+ answer?: string;
114
+ }): import("../../storage/sqlite/clarification-wait-repository.js").ResolveClarificationResult;
115
+ getClarificationById(id: string): import("@xopcai/gateway-contract").ClarificationWait;
116
+ answerClarificationChoice(requestId: string, choiceIndex: number, idempotencyKey: string): boolean;
117
+ answerClarificationText(sessionKey: string, answer: string, idempotencyKey: string): boolean;
131
118
  /** Same execution path as scheduled continuation, but lets callers observe failures. */
132
119
  runScheduledWebchatTurn(sessionKey: string, userTurn: UserTurnInput): Promise<void>;
133
120
  runScheduledWebchatContinuation(sessionKey: string, message: string): Promise<void>;
134
121
  /** Background drain for extension-initiated webchat turns (`scheduleWebchatContinuation`). */
135
122
  drainScheduledWebchatContinuation(sessionKey: string, message: string): Promise<void>;
136
123
  /**
137
- * Resolve clarify-bridge config for `sessionKey`: who delivers the question
138
- * (webchat stream, Telegram message, or both), then start the bridge request.
124
+ * Persist normal clarification waits and use the lifecycle-bound waiter only
125
+ * for caller-owned ephemeral sessions.
139
126
  * Rejects when neither path is available (e.g. CLI without webchat or TG).
140
127
  *
141
128
  * `publishStreamFor(runId)` is the bridge into AgentService's
@@ -144,8 +131,10 @@ export declare class GatewayAgentRunner {
144
131
  */
145
132
  requestClarification(opts: {
146
133
  sessionKey: string;
147
- request: ClarifyBridgeRequest;
148
- publishStreamFor: (runId: string) => (event: ClarifyStreamEvent) => void;
149
- }): Promise<string>;
134
+ runId: string;
135
+ toolCallId: string;
136
+ request: ClarifyRequestPayload;
137
+ publishStreamFor: (runId: string) => (event: ClarificationStreamEvent) => void;
138
+ }): Promise<ClarifyRequestResult>;
150
139
  private deliverTelegramClarify;
151
140
  }