@qduc/term2 0.14.0 → 0.15.0

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 (903) hide show
  1. package/dist/agent.d.ts +2 -0
  2. package/dist/agent.d.ts.map +1 -1
  3. package/dist/agent.js +17 -7
  4. package/dist/agent.js.map +1 -1
  5. package/dist/app-helpers.d.ts +4 -0
  6. package/dist/app-helpers.d.ts.map +1 -1
  7. package/dist/app-helpers.js +6 -0
  8. package/dist/app-helpers.js.map +1 -1
  9. package/dist/app.d.ts +1 -1
  10. package/dist/app.d.ts.map +1 -1
  11. package/dist/app.js +141 -13
  12. package/dist/app.js.map +1 -1
  13. package/dist/cli.js +112 -28
  14. package/dist/cli.js.map +1 -1
  15. package/dist/commands/auto-approve-command.js +3 -3
  16. package/dist/commands/auto-approve-command.js.map +1 -1
  17. package/dist/commands/guarded-settings-command.d.ts +3 -1
  18. package/dist/commands/guarded-settings-command.d.ts.map +1 -1
  19. package/dist/commands/guarded-settings-command.js +21 -5
  20. package/dist/commands/guarded-settings-command.js.map +1 -1
  21. package/dist/commands/mode-commands.d.ts +9 -2
  22. package/dist/commands/mode-commands.d.ts.map +1 -1
  23. package/dist/commands/mode-commands.js +12 -3
  24. package/dist/commands/mode-commands.js.map +1 -1
  25. package/dist/commands/usage-command.d.ts +10 -1
  26. package/dist/commands/usage-command.d.ts.map +1 -1
  27. package/dist/commands/usage-command.js +11 -1
  28. package/dist/commands/usage-command.js.map +1 -1
  29. package/dist/components/InputBox.js +14 -1
  30. package/dist/components/InputBox.js.map +1 -1
  31. package/dist/components/input/FirstRunSetupPrompt.js +1 -1
  32. package/dist/components/input/FirstRunSetupPrompt.js.map +1 -1
  33. package/dist/components/input/PendingQueueList.d.ts.map +1 -1
  34. package/dist/components/input/PendingQueueList.js +22 -5
  35. package/dist/components/input/PendingQueueList.js.map +1 -1
  36. package/dist/components/input/ProviderMenuSession.d.ts.map +1 -1
  37. package/dist/components/input/ProviderMenuSession.js +1 -0
  38. package/dist/components/input/ProviderMenuSession.js.map +1 -1
  39. package/dist/components/input/SettingsValueMenuSession.d.ts.map +1 -1
  40. package/dist/components/input/SettingsValueMenuSession.js +6 -0
  41. package/dist/components/input/SettingsValueMenuSession.js.map +1 -1
  42. package/dist/components/layout/BackgroundTaskManager.d.ts +2 -0
  43. package/dist/components/layout/BackgroundTaskManager.d.ts.map +1 -1
  44. package/dist/components/layout/BackgroundTaskManager.js +156 -64
  45. package/dist/components/layout/BackgroundTaskManager.js.map +1 -1
  46. package/dist/components/layout/BackgroundTasksPanel.d.ts +10 -1
  47. package/dist/components/layout/BackgroundTasksPanel.d.ts.map +1 -1
  48. package/dist/components/layout/BackgroundTasksPanel.js +193 -59
  49. package/dist/components/layout/BackgroundTasksPanel.js.map +1 -1
  50. package/dist/components/layout/BottomArea.d.ts +11 -1
  51. package/dist/components/layout/BottomArea.d.ts.map +1 -1
  52. package/dist/components/layout/BottomArea.js +30 -13
  53. package/dist/components/layout/BottomArea.js.map +1 -1
  54. package/dist/components/layout/StatusBar.d.ts +5 -0
  55. package/dist/components/layout/StatusBar.d.ts.map +1 -1
  56. package/dist/components/layout/StatusBar.js +45 -3
  57. package/dist/components/layout/StatusBar.js.map +1 -1
  58. package/dist/components/layout/live-task-rows.d.ts +16 -0
  59. package/dist/components/layout/live-task-rows.d.ts.map +1 -0
  60. package/dist/components/layout/live-task-rows.js +28 -0
  61. package/dist/components/layout/live-task-rows.js.map +1 -0
  62. package/dist/components/layout/terminal-text-budget.d.ts +4 -0
  63. package/dist/components/layout/terminal-text-budget.d.ts.map +1 -0
  64. package/dist/components/layout/terminal-text-budget.js +18 -0
  65. package/dist/components/layout/terminal-text-budget.js.map +1 -0
  66. package/dist/components/menu/ModelSelectionMenu.d.ts.map +1 -1
  67. package/dist/components/menu/ModelSelectionMenu.js +18 -5
  68. package/dist/components/menu/ModelSelectionMenu.js.map +1 -1
  69. package/dist/components/menu/ProviderSelectionMenu.d.ts.map +1 -1
  70. package/dist/components/menu/ProviderSelectionMenu.js +27 -2
  71. package/dist/components/menu/ProviderSelectionMenu.js.map +1 -1
  72. package/dist/components/menu/SettingsSelectionMenu.d.ts.map +1 -1
  73. package/dist/components/menu/SettingsSelectionMenu.js +5 -0
  74. package/dist/components/menu/SettingsSelectionMenu.js.map +1 -1
  75. package/dist/components/message/CommandGroupSummary.d.ts +9 -0
  76. package/dist/components/message/CommandGroupSummary.d.ts.map +1 -0
  77. package/dist/components/message/CommandGroupSummary.js +31 -0
  78. package/dist/components/message/CommandGroupSummary.js.map +1 -0
  79. package/dist/components/message/CommandMessage.d.ts +8 -0
  80. package/dist/components/message/CommandMessage.d.ts.map +1 -1
  81. package/dist/components/message/CommandMessage.js +54 -25
  82. package/dist/components/message/CommandMessage.js.map +1 -1
  83. package/dist/components/message/MessageList.d.ts +6 -2
  84. package/dist/components/message/MessageList.d.ts.map +1 -1
  85. package/dist/components/message/MessageList.js +64 -10
  86. package/dist/components/message/MessageList.js.map +1 -1
  87. package/dist/components/message/SubagentActivityMessage.js +4 -2
  88. package/dist/components/message/SubagentActivityMessage.js.map +1 -1
  89. package/dist/components/message/command-grouping.d.ts +43 -0
  90. package/dist/components/message/command-grouping.d.ts.map +1 -0
  91. package/dist/components/message/command-grouping.js +142 -0
  92. package/dist/components/message/command-grouping.js.map +1 -0
  93. package/dist/components/message/command-message-helpers.d.ts +6 -5
  94. package/dist/components/message/command-message-helpers.d.ts.map +1 -1
  95. package/dist/components/message/command-message-helpers.js +36 -0
  96. package/dist/components/message/command-message-helpers.js.map +1 -1
  97. package/dist/components/prompt/ApprovalPrompt.d.ts +1 -1
  98. package/dist/components/prompt/ApprovalPrompt.d.ts.map +1 -1
  99. package/dist/components/prompt/ApprovalPrompt.js +136 -90
  100. package/dist/components/prompt/ApprovalPrompt.js.map +1 -1
  101. package/dist/components/prompt/ModeSwitchConfirmationPrompt.d.ts +11 -0
  102. package/dist/components/prompt/ModeSwitchConfirmationPrompt.d.ts.map +1 -0
  103. package/dist/components/prompt/ModeSwitchConfirmationPrompt.js +50 -0
  104. package/dist/components/prompt/ModeSwitchConfirmationPrompt.js.map +1 -0
  105. package/dist/components/prompt/QueuePausedPrompt.d.ts.map +1 -1
  106. package/dist/components/prompt/QueuePausedPrompt.js +14 -8
  107. package/dist/components/prompt/QueuePausedPrompt.js.map +1 -1
  108. package/dist/contracts/application-stream.d.ts +7 -0
  109. package/dist/contracts/application-stream.d.ts.map +1 -1
  110. package/dist/contracts/conversation.d.ts +24 -1
  111. package/dist/contracts/conversation.d.ts.map +1 -1
  112. package/dist/contracts/conversation.js +8 -0
  113. package/dist/contracts/conversation.js.map +1 -1
  114. package/dist/contracts/streamed-model-turn.d.ts +22 -1
  115. package/dist/contracts/streamed-model-turn.d.ts.map +1 -1
  116. package/dist/core/index.d.ts +9 -0
  117. package/dist/core/index.d.ts.map +1 -0
  118. package/dist/core/index.js +8 -0
  119. package/dist/core/index.js.map +1 -0
  120. package/dist/core/session-runtime.d.ts +10 -0
  121. package/dist/core/session-runtime.d.ts.map +1 -0
  122. package/dist/core/session-runtime.js +9 -0
  123. package/dist/core/session-runtime.js.map +1 -0
  124. package/dist/gateway/assertion.d.ts +38 -0
  125. package/dist/gateway/assertion.d.ts.map +1 -0
  126. package/dist/gateway/assertion.js +146 -0
  127. package/dist/gateway/assertion.js.map +1 -0
  128. package/dist/gateway/contracts.d.ts +124 -0
  129. package/dist/gateway/contracts.d.ts.map +1 -0
  130. package/dist/gateway/contracts.js +13 -0
  131. package/dist/gateway/contracts.js.map +1 -0
  132. package/dist/gateway/gateway.d.ts +72 -0
  133. package/dist/gateway/gateway.d.ts.map +1 -0
  134. package/dist/gateway/gateway.js +1277 -0
  135. package/dist/gateway/gateway.js.map +1 -0
  136. package/dist/gateway/index.d.ts +22 -0
  137. package/dist/gateway/index.d.ts.map +1 -0
  138. package/dist/gateway/index.js +22 -0
  139. package/dist/gateway/index.js.map +1 -0
  140. package/dist/gateway/interaction-protocol.d.ts +76 -0
  141. package/dist/gateway/interaction-protocol.d.ts.map +1 -0
  142. package/dist/gateway/interaction-protocol.js +548 -0
  143. package/dist/gateway/interaction-protocol.js.map +1 -0
  144. package/dist/gateway/launcher.d.ts +8 -0
  145. package/dist/gateway/launcher.d.ts.map +1 -0
  146. package/dist/gateway/launcher.js +20 -0
  147. package/dist/gateway/launcher.js.map +1 -0
  148. package/dist/gateway/lifecycle.d.ts +12 -0
  149. package/dist/gateway/lifecycle.d.ts.map +1 -0
  150. package/dist/gateway/lifecycle.js +38 -0
  151. package/dist/gateway/lifecycle.js.map +1 -0
  152. package/dist/gateway/persistence/admission-persistence.d.ts +82 -0
  153. package/dist/gateway/persistence/admission-persistence.d.ts.map +1 -0
  154. package/dist/gateway/persistence/admission-persistence.js +215 -0
  155. package/dist/gateway/persistence/admission-persistence.js.map +1 -0
  156. package/dist/gateway/persistence/contracts.d.ts +94 -0
  157. package/dist/gateway/persistence/contracts.d.ts.map +1 -0
  158. package/dist/gateway/persistence/contracts.js +32 -0
  159. package/dist/gateway/persistence/contracts.js.map +1 -0
  160. package/dist/gateway/persistence/coordinator.d.ts +25 -0
  161. package/dist/gateway/persistence/coordinator.d.ts.map +1 -0
  162. package/dist/gateway/persistence/coordinator.js +181 -0
  163. package/dist/gateway/persistence/coordinator.js.map +1 -0
  164. package/dist/gateway/persistence/event-journal.d.ts +31 -0
  165. package/dist/gateway/persistence/event-journal.d.ts.map +1 -0
  166. package/dist/gateway/persistence/event-journal.js +378 -0
  167. package/dist/gateway/persistence/event-journal.js.map +1 -0
  168. package/dist/gateway/persistence/interaction-checkpoint.d.ts +17 -0
  169. package/dist/gateway/persistence/interaction-checkpoint.d.ts.map +1 -0
  170. package/dist/gateway/persistence/interaction-checkpoint.js +75 -0
  171. package/dist/gateway/persistence/interaction-checkpoint.js.map +1 -0
  172. package/dist/gateway/persistence/projection.d.ts +53 -0
  173. package/dist/gateway/persistence/projection.d.ts.map +1 -0
  174. package/dist/gateway/persistence/projection.js +226 -0
  175. package/dist/gateway/persistence/projection.js.map +1 -0
  176. package/dist/gateway/persistence/retention.d.ts +16 -0
  177. package/dist/gateway/persistence/retention.d.ts.map +1 -0
  178. package/dist/gateway/persistence/retention.js +93 -0
  179. package/dist/gateway/persistence/retention.js.map +1 -0
  180. package/dist/gateway/persistence/session-index.d.ts +34 -0
  181. package/dist/gateway/persistence/session-index.d.ts.map +1 -0
  182. package/dist/gateway/persistence/session-index.js +348 -0
  183. package/dist/gateway/persistence/session-index.js.map +1 -0
  184. package/dist/gateway/persistence/session-persistence.d.ts +68 -0
  185. package/dist/gateway/persistence/session-persistence.d.ts.map +1 -0
  186. package/dist/gateway/persistence/session-persistence.js +165 -0
  187. package/dist/gateway/persistence/session-persistence.js.map +1 -0
  188. package/dist/gateway/persistence/storage.d.ts +13 -0
  189. package/dist/gateway/persistence/storage.d.ts.map +1 -0
  190. package/dist/gateway/persistence/storage.js +87 -0
  191. package/dist/gateway/persistence/storage.js.map +1 -0
  192. package/dist/gateway/replay-ledger.d.ts +30 -0
  193. package/dist/gateway/replay-ledger.d.ts.map +1 -0
  194. package/dist/gateway/replay-ledger.js +83 -0
  195. package/dist/gateway/replay-ledger.js.map +1 -0
  196. package/dist/gateway/runtime-factory.d.ts +84 -0
  197. package/dist/gateway/runtime-factory.d.ts.map +1 -0
  198. package/dist/gateway/runtime-factory.js +213 -0
  199. package/dist/gateway/runtime-factory.js.map +1 -0
  200. package/dist/gateway/safe-log.d.ts +15 -0
  201. package/dist/gateway/safe-log.d.ts.map +1 -0
  202. package/dist/gateway/safe-log.js +89 -0
  203. package/dist/gateway/safe-log.js.map +1 -0
  204. package/dist/gateway/server-session.d.ts +65 -0
  205. package/dist/gateway/server-session.d.ts.map +1 -0
  206. package/dist/gateway/server-session.js +252 -0
  207. package/dist/gateway/server-session.js.map +1 -0
  208. package/dist/gateway/server.d.ts +42 -0
  209. package/dist/gateway/server.d.ts.map +1 -0
  210. package/dist/gateway/server.js +126 -0
  211. package/dist/gateway/server.js.map +1 -0
  212. package/dist/gateway/worker-boundary.d.ts +40 -0
  213. package/dist/gateway/worker-boundary.d.ts.map +1 -0
  214. package/dist/gateway/worker-boundary.js +149 -0
  215. package/dist/gateway/worker-boundary.js.map +1 -0
  216. package/dist/gateway/workspace-admission.d.ts +37 -0
  217. package/dist/gateway/workspace-admission.d.ts.map +1 -0
  218. package/dist/gateway/workspace-admission.js +285 -0
  219. package/dist/gateway/workspace-admission.js.map +1 -0
  220. package/dist/hooks/conversation-ui-reducer.d.ts +6 -0
  221. package/dist/hooks/conversation-ui-reducer.d.ts.map +1 -1
  222. package/dist/hooks/conversation-ui-reducer.js +3 -0
  223. package/dist/hooks/conversation-ui-reducer.js.map +1 -1
  224. package/dist/hooks/settings-completion-config.d.ts.map +1 -1
  225. package/dist/hooks/settings-completion-config.js +30 -2
  226. package/dist/hooks/settings-completion-config.js.map +1 -1
  227. package/dist/hooks/use-app-commands.d.ts +4 -1
  228. package/dist/hooks/use-app-commands.d.ts.map +1 -1
  229. package/dist/hooks/use-app-commands.js +14 -3
  230. package/dist/hooks/use-app-commands.js.map +1 -1
  231. package/dist/hooks/use-app-keyboard-shortcuts.d.ts +5 -0
  232. package/dist/hooks/use-app-keyboard-shortcuts.d.ts.map +1 -1
  233. package/dist/hooks/use-app-keyboard-shortcuts.js +11 -0
  234. package/dist/hooks/use-app-keyboard-shortcuts.js.map +1 -1
  235. package/dist/hooks/use-conversation.d.ts +1 -0
  236. package/dist/hooks/use-conversation.d.ts.map +1 -1
  237. package/dist/hooks/use-conversation.js +14 -3
  238. package/dist/hooks/use-conversation.js.map +1 -1
  239. package/dist/hooks/use-grok-credit-usage.d.ts +20 -0
  240. package/dist/hooks/use-grok-credit-usage.d.ts.map +1 -0
  241. package/dist/hooks/use-grok-credit-usage.js +48 -0
  242. package/dist/hooks/use-grok-credit-usage.js.map +1 -0
  243. package/dist/hooks/use-provider-selection.d.ts +10 -0
  244. package/dist/hooks/use-provider-selection.d.ts.map +1 -1
  245. package/dist/hooks/use-provider-selection.js +105 -6
  246. package/dist/hooks/use-provider-selection.js.map +1 -1
  247. package/dist/hooks/use-settings-value-completion.d.ts.map +1 -1
  248. package/dist/hooks/use-settings-value-completion.js +10 -2
  249. package/dist/hooks/use-settings-value-completion.js.map +1 -1
  250. package/dist/lib/agent-client.d.ts +10 -3
  251. package/dist/lib/agent-client.d.ts.map +1 -1
  252. package/dist/lib/agent-client.js +115 -23
  253. package/dist/lib/agent-client.js.map +1 -1
  254. package/dist/lib/agent-configuration.d.ts +2 -0
  255. package/dist/lib/agent-configuration.d.ts.map +1 -1
  256. package/dist/lib/agent-configuration.js +6 -2
  257. package/dist/lib/agent-configuration.js.map +1 -1
  258. package/dist/lib/agent-factory.d.ts +2 -0
  259. package/dist/lib/agent-factory.d.ts.map +1 -1
  260. package/dist/lib/agent-factory.js +28 -10
  261. package/dist/lib/agent-factory.js.map +1 -1
  262. package/dist/lib/editor-impl.d.ts.map +1 -1
  263. package/dist/lib/editor-impl.js +14 -17
  264. package/dist/lib/editor-impl.js.map +1 -1
  265. package/dist/lib/harness-input-idle.d.ts +16 -0
  266. package/dist/lib/harness-input-idle.d.ts.map +1 -0
  267. package/dist/lib/harness-input-idle.js +51 -0
  268. package/dist/lib/harness-input-idle.js.map +1 -0
  269. package/dist/lib/input-owner.d.ts +3 -0
  270. package/dist/lib/input-owner.d.ts.map +1 -1
  271. package/dist/lib/input-owner.js +2 -0
  272. package/dist/lib/input-owner.js.map +1 -1
  273. package/dist/lib/subagent-bridge.d.ts +3 -3
  274. package/dist/lib/subagent-bridge.d.ts.map +1 -1
  275. package/dist/lib/subagent-bridge.js +16 -9
  276. package/dist/lib/subagent-bridge.js.map +1 -1
  277. package/dist/lib/tool-invoke.d.ts +2 -0
  278. package/dist/lib/tool-invoke.d.ts.map +1 -1
  279. package/dist/lib/tool-invoke.js +3 -0
  280. package/dist/lib/tool-invoke.js.map +1 -1
  281. package/dist/non-interactive.d.ts.map +1 -1
  282. package/dist/non-interactive.js +5 -0
  283. package/dist/non-interactive.js.map +1 -1
  284. package/dist/prompts/explorer-delegation-contract.test.ts +22 -0
  285. package/dist/prompts/gpt-5.6.md +1 -1
  286. package/dist/prompts/kimi.md +1 -1
  287. package/dist/prompts/orchestrator.md +10 -1
  288. package/dist/prompts/plan-mode-info.md +3 -3
  289. package/dist/prompts/plan-mode-stub.md +7 -0
  290. package/dist/prompts/prefix-quality.test.ts +102 -0
  291. package/dist/prompts/prompt-constructor.d.ts.map +1 -1
  292. package/dist/prompts/prompt-constructor.js +4 -1
  293. package/dist/prompts/prompt-constructor.js.map +1 -1
  294. package/dist/prompts/prompt-constructor.test.ts +12 -4
  295. package/dist/prompts/prompt-constructor.ts +4 -1
  296. package/dist/prompts/subagents/explorer.md +7 -1
  297. package/dist/prompts/subagents/librarian.md +2 -0
  298. package/dist/prompts/subagents/mentor.md +2 -0
  299. package/dist/prompts/subagents/worker.md +2 -0
  300. package/dist/providers/ai-sdk-streamed-model.d.ts +5 -0
  301. package/dist/providers/ai-sdk-streamed-model.d.ts.map +1 -1
  302. package/dist/providers/ai-sdk-streamed-model.js +64 -1
  303. package/dist/providers/ai-sdk-streamed-model.js.map +1 -1
  304. package/dist/providers/chained-wire-state.d.ts +6 -0
  305. package/dist/providers/chained-wire-state.d.ts.map +1 -1
  306. package/dist/providers/chained-wire-state.js +1 -3
  307. package/dist/providers/chained-wire-state.js.map +1 -1
  308. package/dist/providers/codex-auth.d.ts +73 -2
  309. package/dist/providers/codex-auth.d.ts.map +1 -1
  310. package/dist/providers/codex-auth.js +166 -2
  311. package/dist/providers/codex-auth.js.map +1 -1
  312. package/dist/providers/codex-responses-model.d.ts +3 -0
  313. package/dist/providers/codex-responses-model.d.ts.map +1 -1
  314. package/dist/providers/codex-responses-model.js +295 -162
  315. package/dist/providers/codex-responses-model.js.map +1 -1
  316. package/dist/providers/codex-turn-converter.d.ts.map +1 -1
  317. package/dist/providers/codex-turn-converter.js +7 -1
  318. package/dist/providers/codex-turn-converter.js.map +1 -1
  319. package/dist/providers/codex.provider.d.ts +25 -2
  320. package/dist/providers/codex.provider.d.ts.map +1 -1
  321. package/dist/providers/codex.provider.js +83 -71
  322. package/dist/providers/codex.provider.js.map +1 -1
  323. package/dist/providers/common/provider-errors.d.ts +20 -0
  324. package/dist/providers/common/provider-errors.d.ts.map +1 -1
  325. package/dist/providers/common/provider-errors.js +35 -0
  326. package/dist/providers/common/provider-errors.js.map +1 -1
  327. package/dist/providers/grok-auth.d.ts +105 -0
  328. package/dist/providers/grok-auth.d.ts.map +1 -0
  329. package/dist/providers/grok-auth.js +316 -0
  330. package/dist/providers/grok-auth.js.map +1 -0
  331. package/dist/providers/grok-credit-usage.d.ts +53 -0
  332. package/dist/providers/grok-credit-usage.d.ts.map +1 -0
  333. package/dist/providers/grok-credit-usage.js +108 -0
  334. package/dist/providers/grok-credit-usage.js.map +1 -0
  335. package/dist/providers/grok.provider.d.ts +24 -0
  336. package/dist/providers/grok.provider.d.ts.map +1 -0
  337. package/dist/providers/grok.provider.js +153 -0
  338. package/dist/providers/grok.provider.js.map +1 -0
  339. package/dist/providers/index.d.ts +1 -0
  340. package/dist/providers/index.d.ts.map +1 -1
  341. package/dist/providers/index.js +1 -0
  342. package/dist/providers/index.js.map +1 -1
  343. package/dist/providers/jwt-claims.d.ts +12 -0
  344. package/dist/providers/jwt-claims.d.ts.map +1 -0
  345. package/dist/providers/jwt-claims.js +25 -0
  346. package/dist/providers/jwt-claims.js.map +1 -0
  347. package/dist/providers/luna-responses-lite-wire-protocol.d.ts +1 -0
  348. package/dist/providers/luna-responses-lite-wire-protocol.d.ts.map +1 -1
  349. package/dist/providers/luna-responses-lite-wire-protocol.js +19 -0
  350. package/dist/providers/luna-responses-lite-wire-protocol.js.map +1 -1
  351. package/dist/providers/model-catalog/catalog.generated.d.ts +360 -232
  352. package/dist/providers/model-catalog/catalog.generated.d.ts.map +1 -1
  353. package/dist/providers/model-catalog/catalog.generated.js +360 -232
  354. package/dist/providers/model-catalog/catalog.generated.js.map +1 -1
  355. package/dist/providers/model-catalog/generate-catalog.d.ts.map +1 -1
  356. package/dist/providers/model-catalog/generate-catalog.js +21 -1
  357. package/dist/providers/model-catalog/generate-catalog.js.map +1 -1
  358. package/dist/providers/oauth-account-store.d.ts +84 -0
  359. package/dist/providers/oauth-account-store.d.ts.map +1 -0
  360. package/dist/providers/oauth-account-store.js +142 -0
  361. package/dist/providers/oauth-account-store.js.map +1 -0
  362. package/dist/providers/oauth-accounts.d.ts +24 -0
  363. package/dist/providers/oauth-accounts.d.ts.map +1 -0
  364. package/dist/providers/oauth-accounts.js +37 -0
  365. package/dist/providers/oauth-accounts.js.map +1 -0
  366. package/dist/providers/oauth-pkce.d.ts +53 -0
  367. package/dist/providers/oauth-pkce.d.ts.map +1 -0
  368. package/dist/providers/oauth-pkce.js +200 -0
  369. package/dist/providers/oauth-pkce.js.map +1 -0
  370. package/dist/providers/oauth-session-account.d.ts +5 -0
  371. package/dist/providers/oauth-session-account.d.ts.map +1 -0
  372. package/dist/providers/oauth-session-account.js +24 -0
  373. package/dist/providers/oauth-session-account.js.map +1 -0
  374. package/dist/providers/openai-chat-completions-model.d.ts.map +1 -1
  375. package/dist/providers/openai-chat-completions-model.js +37 -16
  376. package/dist/providers/openai-chat-completions-model.js.map +1 -1
  377. package/dist/providers/openai-compatible-lazy.js.map +1 -1
  378. package/dist/providers/openai-compatible.provider.d.ts +5 -0
  379. package/dist/providers/openai-compatible.provider.d.ts.map +1 -1
  380. package/dist/providers/openai-compatible.provider.js +32 -2
  381. package/dist/providers/openai-compatible.provider.js.map +1 -1
  382. package/dist/providers/openai-responses-model.d.ts +13 -3
  383. package/dist/providers/openai-responses-model.d.ts.map +1 -1
  384. package/dist/providers/openai-responses-model.js +92 -39
  385. package/dist/providers/openai-responses-model.js.map +1 -1
  386. package/dist/providers/openai.provider.d.ts.map +1 -1
  387. package/dist/providers/openai.provider.js +23 -2
  388. package/dist/providers/openai.provider.js.map +1 -1
  389. package/dist/providers/opencode-routing.d.ts +2 -0
  390. package/dist/providers/opencode-routing.d.ts.map +1 -1
  391. package/dist/providers/opencode-routing.js +12 -6
  392. package/dist/providers/opencode-routing.js.map +1 -1
  393. package/dist/providers/opencode-transport-discovery.d.ts +18 -0
  394. package/dist/providers/opencode-transport-discovery.d.ts.map +1 -0
  395. package/dist/providers/opencode-transport-discovery.js +115 -0
  396. package/dist/providers/opencode-transport-discovery.js.map +1 -0
  397. package/dist/providers/openrouter.provider.js.map +1 -1
  398. package/dist/providers/provider-opaque-compatibility.d.ts +58 -0
  399. package/dist/providers/provider-opaque-compatibility.d.ts.map +1 -0
  400. package/dist/providers/provider-opaque-compatibility.js +80 -0
  401. package/dist/providers/provider-opaque-compatibility.js.map +1 -0
  402. package/dist/providers/provider-service.d.ts +1 -1
  403. package/dist/providers/provider-service.d.ts.map +1 -1
  404. package/dist/providers/provider-service.js.map +1 -1
  405. package/dist/providers/registry.d.ts +10 -1
  406. package/dist/providers/registry.d.ts.map +1 -1
  407. package/dist/providers/registry.js.map +1 -1
  408. package/dist/providers/responses-websocket-sessions.d.ts +25 -0
  409. package/dist/providers/responses-websocket-sessions.d.ts.map +1 -0
  410. package/dist/providers/responses-websocket-sessions.js +102 -0
  411. package/dist/providers/responses-websocket-sessions.js.map +1 -0
  412. package/dist/providers/websocket-close-evidence.d.ts +45 -0
  413. package/dist/providers/websocket-close-evidence.d.ts.map +1 -0
  414. package/dist/providers/websocket-close-evidence.js +78 -0
  415. package/dist/providers/websocket-close-evidence.js.map +1 -0
  416. package/dist/providers/websocket-receive-watchdog.d.ts +9 -1
  417. package/dist/providers/websocket-receive-watchdog.d.ts.map +1 -1
  418. package/dist/providers/websocket-receive-watchdog.js +27 -1
  419. package/dist/providers/websocket-receive-watchdog.js.map +1 -1
  420. package/dist/providers/websocket-request-dispatch.d.ts +35 -0
  421. package/dist/providers/websocket-request-dispatch.d.ts.map +1 -0
  422. package/dist/providers/websocket-request-dispatch.js +23 -0
  423. package/dist/providers/websocket-request-dispatch.js.map +1 -0
  424. package/dist/scripts/eval-context-compaction/runner.js +1 -1
  425. package/dist/scripts/eval-context-compaction/runner.js.map +1 -1
  426. package/dist/services/agent-runtime/agent-handle.d.ts.map +1 -1
  427. package/dist/services/agent-runtime/agent-handle.js +8 -5
  428. package/dist/services/agent-runtime/agent-handle.js.map +1 -1
  429. package/dist/services/agent-runtime/agent-runtime.d.ts +1 -1
  430. package/dist/services/agent-runtime/agent-runtime.js +1 -1
  431. package/dist/services/agent-runtime/application-run-loop.d.ts +33 -9
  432. package/dist/services/agent-runtime/application-run-loop.d.ts.map +1 -1
  433. package/dist/services/agent-runtime/application-run-loop.js +300 -87
  434. package/dist/services/agent-runtime/application-run-loop.js.map +1 -1
  435. package/dist/services/agent-runtime/context-compaction/local-context-compactor.d.ts +6 -1
  436. package/dist/services/agent-runtime/context-compaction/local-context-compactor.d.ts.map +1 -1
  437. package/dist/services/agent-runtime/context-compaction/local-context-compactor.js +72 -4
  438. package/dist/services/agent-runtime/context-compaction/local-context-compactor.js.map +1 -1
  439. package/dist/services/agent-runtime/executor.d.ts +1 -1
  440. package/dist/services/agent-runtime/executor.d.ts.map +1 -1
  441. package/dist/services/agent-runtime/executor.js +5 -5
  442. package/dist/services/agent-runtime/executor.js.map +1 -1
  443. package/dist/services/agent-runtime/generation-guard.d.ts +2 -1
  444. package/dist/services/agent-runtime/generation-guard.d.ts.map +1 -1
  445. package/dist/services/agent-runtime/generation-guard.js +7 -2
  446. package/dist/services/agent-runtime/generation-guard.js.map +1 -1
  447. package/dist/services/agent-runtime/run-budget.d.ts +131 -0
  448. package/dist/services/agent-runtime/run-budget.d.ts.map +1 -0
  449. package/dist/services/agent-runtime/run-budget.js +268 -0
  450. package/dist/services/agent-runtime/run-budget.js.map +1 -0
  451. package/dist/services/agent-runtime/tool-invocation-context.d.ts +12 -0
  452. package/dist/services/agent-runtime/tool-invocation-context.d.ts.map +1 -1
  453. package/dist/services/agent-runtime/tool-invocation-context.js.map +1 -1
  454. package/dist/services/agent-runtime/types.d.ts +5 -4
  455. package/dist/services/agent-runtime/types.d.ts.map +1 -1
  456. package/dist/services/agent-stream.d.ts.map +1 -1
  457. package/dist/services/agent-stream.js +2 -1
  458. package/dist/services/agent-stream.js.map +1 -1
  459. package/dist/services/approval/approval-decision-executor.d.ts +6 -1
  460. package/dist/services/approval/approval-decision-executor.d.ts.map +1 -1
  461. package/dist/services/approval/approval-decision-executor.js +15 -3
  462. package/dist/services/approval/approval-decision-executor.js.map +1 -1
  463. package/dist/services/approval/approval-decision-policy.d.ts.map +1 -1
  464. package/dist/services/approval/approval-decision-policy.js +3 -0
  465. package/dist/services/approval/approval-decision-policy.js.map +1 -1
  466. package/dist/services/approval/approval-flow-coordinator.d.ts +2 -0
  467. package/dist/services/approval/approval-flow-coordinator.d.ts.map +1 -1
  468. package/dist/services/approval/approval-flow-coordinator.js +14 -2
  469. package/dist/services/approval/approval-flow-coordinator.js.map +1 -1
  470. package/dist/services/approval/background-subagent-approval-controller.d.ts +3 -1
  471. package/dist/services/approval/background-subagent-approval-controller.d.ts.map +1 -1
  472. package/dist/services/approval/background-subagent-approval-controller.js +7 -4
  473. package/dist/services/approval/background-subagent-approval-controller.js.map +1 -1
  474. package/dist/services/approval/shell-auto-approval-resolver.d.ts +5 -0
  475. package/dist/services/approval/shell-auto-approval-resolver.d.ts.map +1 -1
  476. package/dist/services/approval/shell-auto-approval-resolver.js +8 -0
  477. package/dist/services/approval/shell-auto-approval-resolver.js.map +1 -1
  478. package/dist/services/approval/tool-approval-batch-coordinator.d.ts.map +1 -1
  479. package/dist/services/approval/tool-approval-batch-coordinator.js +20 -11
  480. package/dist/services/approval/tool-approval-batch-coordinator.js.map +1 -1
  481. package/dist/services/approval/tool-ownership-registry.d.ts +5 -1
  482. package/dist/services/approval/tool-ownership-registry.d.ts.map +1 -1
  483. package/dist/services/approval/tool-ownership-registry.js +5 -22
  484. package/dist/services/approval/tool-ownership-registry.js.map +1 -1
  485. package/dist/services/background-task-activity.d.ts +79 -0
  486. package/dist/services/background-task-activity.d.ts.map +1 -0
  487. package/dist/services/background-task-activity.js +34 -0
  488. package/dist/services/background-task-activity.js.map +1 -0
  489. package/dist/services/command-message-streaming.d.ts +4 -2
  490. package/dist/services/command-message-streaming.d.ts.map +1 -1
  491. package/dist/services/command-message-streaming.js +2 -2
  492. package/dist/services/command-message-streaming.js.map +1 -1
  493. package/dist/services/conversation/conversation-adapter-factory.d.ts +6 -2
  494. package/dist/services/conversation/conversation-adapter-factory.d.ts.map +1 -1
  495. package/dist/services/conversation/conversation-adapter-factory.js +5 -1
  496. package/dist/services/conversation/conversation-adapter-factory.js.map +1 -1
  497. package/dist/services/conversation/conversation-adapter.d.ts +41 -9
  498. package/dist/services/conversation/conversation-adapter.d.ts.map +1 -1
  499. package/dist/services/conversation/conversation-adapter.js +218 -37
  500. package/dist/services/conversation/conversation-adapter.js.map +1 -1
  501. package/dist/services/conversation/conversation-decoder.d.ts.map +1 -1
  502. package/dist/services/conversation/conversation-decoder.js +4 -0
  503. package/dist/services/conversation/conversation-decoder.js.map +1 -1
  504. package/dist/services/conversation/conversation-events.d.ts +55 -2
  505. package/dist/services/conversation/conversation-events.d.ts.map +1 -1
  506. package/dist/services/conversation/conversation-orchestrator.d.ts.map +1 -1
  507. package/dist/services/conversation/conversation-orchestrator.js +103 -11
  508. package/dist/services/conversation/conversation-orchestrator.js.map +1 -1
  509. package/dist/services/conversation/conversation-orchestrator.types.d.ts +3 -0
  510. package/dist/services/conversation/conversation-orchestrator.types.d.ts.map +1 -1
  511. package/dist/services/conversation/conversation-persistence.d.ts +38 -2
  512. package/dist/services/conversation/conversation-persistence.d.ts.map +1 -1
  513. package/dist/services/conversation/conversation-persistence.js +160 -16
  514. package/dist/services/conversation/conversation-persistence.js.map +1 -1
  515. package/dist/services/conversation/conversation-replay.d.ts.map +1 -1
  516. package/dist/services/conversation/conversation-replay.js +27 -0
  517. package/dist/services/conversation/conversation-replay.js.map +1 -1
  518. package/dist/services/conversation/conversation-result-builder.d.ts +6 -2
  519. package/dist/services/conversation/conversation-result-builder.d.ts.map +1 -1
  520. package/dist/services/conversation/conversation-result-builder.js +60 -1
  521. package/dist/services/conversation/conversation-result-builder.js.map +1 -1
  522. package/dist/services/conversation/conversation-runtime-factory.d.ts +9 -1
  523. package/dist/services/conversation/conversation-runtime-factory.d.ts.map +1 -1
  524. package/dist/services/conversation/conversation-runtime-factory.js +5 -1
  525. package/dist/services/conversation/conversation-runtime-factory.js.map +1 -1
  526. package/dist/services/conversation/conversation-service.d.ts +32 -3
  527. package/dist/services/conversation/conversation-service.d.ts.map +1 -1
  528. package/dist/services/conversation/conversation-service.js +82 -8
  529. package/dist/services/conversation/conversation-service.js.map +1 -1
  530. package/dist/services/conversation/conversation-state-projector.d.ts +2 -1
  531. package/dist/services/conversation/conversation-state-projector.d.ts.map +1 -1
  532. package/dist/services/conversation/conversation-state-projector.js +31 -3
  533. package/dist/services/conversation/conversation-state-projector.js.map +1 -1
  534. package/dist/services/conversation/run-item-normalizer.d.ts.map +1 -1
  535. package/dist/services/conversation/run-item-normalizer.js +24 -1
  536. package/dist/services/conversation/run-item-normalizer.js.map +1 -1
  537. package/dist/services/conversation-agent-client.d.ts +21 -2
  538. package/dist/services/conversation-agent-client.d.ts.map +1 -1
  539. package/dist/services/cost/model-cost.d.ts +13 -1
  540. package/dist/services/cost/model-cost.d.ts.map +1 -1
  541. package/dist/services/cost/model-cost.js +59 -0
  542. package/dist/services/cost/model-cost.js.map +1 -1
  543. package/dist/services/cost/subscription-providers.d.ts +2 -0
  544. package/dist/services/cost/subscription-providers.d.ts.map +1 -0
  545. package/dist/services/cost/subscription-providers.js +14 -0
  546. package/dist/services/cost/subscription-providers.js.map +1 -0
  547. package/dist/services/grok/grok-credit-usage-service.d.ts +62 -0
  548. package/dist/services/grok/grok-credit-usage-service.d.ts.map +1 -0
  549. package/dist/services/grok/grok-credit-usage-service.js +137 -0
  550. package/dist/services/grok/grok-credit-usage-service.js.map +1 -0
  551. package/dist/services/history-service.d.ts +9 -0
  552. package/dist/services/history-service.d.ts.map +1 -1
  553. package/dist/services/history-service.js +49 -2
  554. package/dist/services/history-service.js.map +1 -1
  555. package/dist/services/hooks/hook-composition.d.ts +17 -0
  556. package/dist/services/hooks/hook-composition.d.ts.map +1 -0
  557. package/dist/services/hooks/hook-composition.js +19 -0
  558. package/dist/services/hooks/hook-composition.js.map +1 -0
  559. package/dist/services/logging/conversation-log-events.d.ts +35 -1
  560. package/dist/services/logging/conversation-log-events.d.ts.map +1 -1
  561. package/dist/services/logging/conversation-log-events.js +17 -0
  562. package/dist/services/logging/conversation-log-events.js.map +1 -1
  563. package/dist/services/logging/conversation-log-writer.d.ts +8 -1
  564. package/dist/services/logging/conversation-log-writer.d.ts.map +1 -1
  565. package/dist/services/logging/conversation-log-writer.js +145 -10
  566. package/dist/services/logging/conversation-log-writer.js.map +1 -1
  567. package/dist/services/logging/conversation-logger.d.ts.map +1 -1
  568. package/dist/services/logging/conversation-logger.js +18 -0
  569. package/dist/services/logging/conversation-logger.js.map +1 -1
  570. package/dist/services/logging/logging-service.d.ts +6 -6
  571. package/dist/services/logging/logging-service.d.ts.map +1 -1
  572. package/dist/services/logging/logging-service.js.map +1 -1
  573. package/dist/services/logging/provider-traffic.d.ts +17 -1
  574. package/dist/services/logging/provider-traffic.d.ts.map +1 -1
  575. package/dist/services/logging/provider-traffic.js +283 -139
  576. package/dist/services/logging/provider-traffic.js.map +1 -1
  577. package/dist/services/memory/memory-capabilities.d.ts.map +1 -1
  578. package/dist/services/memory/memory-capabilities.js +20 -1
  579. package/dist/services/memory/memory-capabilities.js.map +1 -1
  580. package/dist/services/mode-notices.d.ts +1 -6
  581. package/dist/services/mode-notices.d.ts.map +1 -1
  582. package/dist/services/mode-notices.js +16 -3
  583. package/dist/services/mode-notices.js.map +1 -1
  584. package/dist/services/model-service.d.ts +2 -2
  585. package/dist/services/model-service.d.ts.map +1 -1
  586. package/dist/services/model-service.js.map +1 -1
  587. package/dist/services/queue/queue-controller.d.ts +1 -1
  588. package/dist/services/queue/queue-controller.d.ts.map +1 -1
  589. package/dist/services/queue/queue-controller.js +19 -5
  590. package/dist/services/queue/queue-controller.js.map +1 -1
  591. package/dist/services/retry/chain-recovery-fingerprint.d.ts +10 -0
  592. package/dist/services/retry/chain-recovery-fingerprint.d.ts.map +1 -0
  593. package/dist/services/retry/chain-recovery-fingerprint.js +23 -0
  594. package/dist/services/retry/chain-recovery-fingerprint.js.map +1 -0
  595. package/dist/services/retry/recovery-executor.d.ts.map +1 -1
  596. package/dist/services/retry/recovery-executor.js +2 -0
  597. package/dist/services/retry/recovery-executor.js.map +1 -1
  598. package/dist/services/retry/recovery-policy.d.ts.map +1 -1
  599. package/dist/services/retry/recovery-policy.js +4 -0
  600. package/dist/services/retry/recovery-policy.js.map +1 -1
  601. package/dist/services/retry/retry-classifier.d.ts.map +1 -1
  602. package/dist/services/retry/retry-classifier.js +34 -2
  603. package/dist/services/retry/retry-classifier.js.map +1 -1
  604. package/dist/services/retry/retry-contracts.d.ts +14 -0
  605. package/dist/services/retry/retry-contracts.d.ts.map +1 -1
  606. package/dist/services/retry/retry-error-classification.d.ts +17 -3
  607. package/dist/services/retry/retry-error-classification.d.ts.map +1 -1
  608. package/dist/services/retry/retry-error-classification.js +48 -7
  609. package/dist/services/retry/retry-error-classification.js.map +1 -1
  610. package/dist/services/retry/retry-errors.d.ts +4 -0
  611. package/dist/services/retry/retry-errors.d.ts.map +1 -1
  612. package/dist/services/retry/retry-errors.js +7 -0
  613. package/dist/services/retry/retry-errors.js.map +1 -1
  614. package/dist/services/retry/retry-event-presenter.d.ts.map +1 -1
  615. package/dist/services/retry/retry-event-presenter.js +20 -0
  616. package/dist/services/retry/retry-event-presenter.js.map +1 -1
  617. package/dist/services/runtime-setting-router.d.ts.map +1 -1
  618. package/dist/services/runtime-setting-router.js +6 -0
  619. package/dist/services/runtime-setting-router.js.map +1 -1
  620. package/dist/services/service-interfaces.d.ts +96 -13
  621. package/dist/services/service-interfaces.d.ts.map +1 -1
  622. package/dist/services/session/background-task-control.d.ts +6 -0
  623. package/dist/services/session/background-task-control.d.ts.map +1 -1
  624. package/dist/services/session/background-task-control.js +31 -6
  625. package/dist/services/session/background-task-control.js.map +1 -1
  626. package/dist/services/session/background-task-liveness.d.ts +2 -18
  627. package/dist/services/session/background-task-liveness.d.ts.map +1 -1
  628. package/dist/services/session/background-task-liveness.js +7 -22
  629. package/dist/services/session/background-task-liveness.js.map +1 -1
  630. package/dist/services/session/continuation-plan-applier.d.ts.map +1 -1
  631. package/dist/services/session/continuation-plan-applier.js +23 -0
  632. package/dist/services/session/continuation-plan-applier.js.map +1 -1
  633. package/dist/services/session/continuation-recovery-handler.d.ts +2 -0
  634. package/dist/services/session/continuation-recovery-handler.d.ts.map +1 -1
  635. package/dist/services/session/continuation-recovery-handler.js +7 -1
  636. package/dist/services/session/continuation-recovery-handler.js.map +1 -1
  637. package/dist/services/session/initial-turn-recovery-handler.d.ts +1 -0
  638. package/dist/services/session/initial-turn-recovery-handler.d.ts.map +1 -1
  639. package/dist/services/session/initial-turn-recovery-handler.js +12 -2
  640. package/dist/services/session/initial-turn-recovery-handler.js.map +1 -1
  641. package/dist/services/session/session-client-factory.d.ts +3 -1
  642. package/dist/services/session/session-client-factory.d.ts.map +1 -1
  643. package/dist/services/session/session-client-factory.js +2 -2
  644. package/dist/services/session/session-client-factory.js.map +1 -1
  645. package/dist/services/session/session-composition.d.ts +3 -0
  646. package/dist/services/session/session-composition.d.ts.map +1 -1
  647. package/dist/services/session/session-composition.js +52 -8
  648. package/dist/services/session/session-composition.js.map +1 -1
  649. package/dist/services/session/session-stream-processor.d.ts +2 -0
  650. package/dist/services/session/session-stream-processor.d.ts.map +1 -1
  651. package/dist/services/session/session-stream-processor.js +4 -0
  652. package/dist/services/session/session-stream-processor.js.map +1 -1
  653. package/dist/services/session/terminal-result-collector.d.ts +2 -2
  654. package/dist/services/session/terminal-result-collector.d.ts.map +1 -1
  655. package/dist/services/session/terminal-result-collector.js +2 -1
  656. package/dist/services/session/terminal-result-collector.js.map +1 -1
  657. package/dist/services/session/turn-attempt-factory.d.ts +1 -0
  658. package/dist/services/session/turn-attempt-factory.d.ts.map +1 -1
  659. package/dist/services/session/turn-attempt-factory.js.map +1 -1
  660. package/dist/services/session/turn-coordinator.d.ts +1 -1
  661. package/dist/services/session/turn-coordinator.d.ts.map +1 -1
  662. package/dist/services/session/turn-coordinator.js +31 -6
  663. package/dist/services/session/turn-coordinator.js.map +1 -1
  664. package/dist/services/session/turn-workflow.d.ts +4 -1
  665. package/dist/services/session/turn-workflow.d.ts.map +1 -1
  666. package/dist/services/session/turn-workflow.js +48 -7
  667. package/dist/services/session/turn-workflow.js.map +1 -1
  668. package/dist/services/settings/settings-persistence.d.ts +33 -0
  669. package/dist/services/settings/settings-persistence.d.ts.map +1 -1
  670. package/dist/services/settings/settings-persistence.js +102 -4
  671. package/dist/services/settings/settings-persistence.js.map +1 -1
  672. package/dist/services/settings/settings-schema.d.ts +70 -2
  673. package/dist/services/settings/settings-schema.d.ts.map +1 -1
  674. package/dist/services/settings/settings-schema.js +92 -6
  675. package/dist/services/settings/settings-schema.js.map +1 -1
  676. package/dist/services/settings/settings-service.d.ts +57 -3
  677. package/dist/services/settings/settings-service.d.ts.map +1 -1
  678. package/dist/services/settings/settings-service.js +171 -28
  679. package/dist/services/settings/settings-service.js.map +1 -1
  680. package/dist/services/settings/settings-service.mock.d.ts +1 -1
  681. package/dist/services/settings/settings-service.mock.d.ts.map +1 -1
  682. package/dist/services/settings/settings-service.mock.js +3 -6
  683. package/dist/services/settings/settings-service.mock.js.map +1 -1
  684. package/dist/services/settings/settings-sources.d.ts.map +1 -1
  685. package/dist/services/settings/settings-sources.js +16 -0
  686. package/dist/services/settings/settings-sources.js.map +1 -1
  687. package/dist/services/settings/test-helpers/settings-consumer-inventory.d.ts +27 -0
  688. package/dist/services/settings/test-helpers/settings-consumer-inventory.d.ts.map +1 -0
  689. package/dist/services/settings/test-helpers/settings-consumer-inventory.js +165 -0
  690. package/dist/services/settings/test-helpers/settings-consumer-inventory.js.map +1 -0
  691. package/dist/services/shell/background-shell-registry.d.ts +10 -0
  692. package/dist/services/shell/background-shell-registry.d.ts.map +1 -1
  693. package/dist/services/shell/background-shell-registry.js +9 -1
  694. package/dist/services/shell/background-shell-registry.js.map +1 -1
  695. package/dist/services/shell/background-shell-watches.d.ts +28 -3
  696. package/dist/services/shell/background-shell-watches.d.ts.map +1 -1
  697. package/dist/services/shell/background-shell-watches.js +41 -9
  698. package/dist/services/shell/background-shell-watches.js.map +1 -1
  699. package/dist/services/ssh-service.d.ts +81 -9
  700. package/dist/services/ssh-service.d.ts.map +1 -1
  701. package/dist/services/ssh-service.js +211 -37
  702. package/dist/services/ssh-service.js.map +1 -1
  703. package/dist/services/stream-event-processor.d.ts +2 -0
  704. package/dist/services/stream-event-processor.d.ts.map +1 -1
  705. package/dist/services/stream-event-processor.js +17 -7
  706. package/dist/services/stream-event-processor.js.map +1 -1
  707. package/dist/services/subagents/execution-runner.d.ts +1 -1
  708. package/dist/services/subagents/execution-runner.d.ts.map +1 -1
  709. package/dist/services/subagents/execution-runner.js +34 -22
  710. package/dist/services/subagents/execution-runner.js.map +1 -1
  711. package/dist/services/subagents/foreground-subagent-lease.d.ts +11 -1
  712. package/dist/services/subagents/foreground-subagent-lease.d.ts.map +1 -1
  713. package/dist/services/subagents/foreground-subagent-lease.js +10 -1
  714. package/dist/services/subagents/foreground-subagent-lease.js.map +1 -1
  715. package/dist/services/subagents/mentor-runner.d.ts +1 -1
  716. package/dist/services/subagents/mentor-runner.d.ts.map +1 -1
  717. package/dist/services/subagents/mentor-runner.js +10 -3
  718. package/dist/services/subagents/mentor-runner.js.map +1 -1
  719. package/dist/services/subagents/nested-runner.d.ts +11 -1
  720. package/dist/services/subagents/nested-runner.d.ts.map +1 -1
  721. package/dist/services/subagents/nested-runner.js +45 -10
  722. package/dist/services/subagents/nested-runner.js.map +1 -1
  723. package/dist/services/subagents/runtime.d.ts.map +1 -1
  724. package/dist/services/subagents/runtime.js +7 -0
  725. package/dist/services/subagents/runtime.js.map +1 -1
  726. package/dist/services/subagents/subagent-async-registry.d.ts +4 -0
  727. package/dist/services/subagents/subagent-async-registry.d.ts.map +1 -1
  728. package/dist/services/subagents/subagent-async-registry.js +80 -16
  729. package/dist/services/subagents/subagent-async-registry.js.map +1 -1
  730. package/dist/services/subagents/subagent-manager.d.ts +1 -1
  731. package/dist/services/subagents/subagent-manager.d.ts.map +1 -1
  732. package/dist/services/subagents/subagent-manager.js +4 -4
  733. package/dist/services/subagents/subagent-manager.js.map +1 -1
  734. package/dist/services/subagents/subagent-notification-store.d.ts +19 -1
  735. package/dist/services/subagents/subagent-notification-store.d.ts.map +1 -1
  736. package/dist/services/subagents/subagent-notification-store.js +22 -0
  737. package/dist/services/subagents/subagent-notification-store.js.map +1 -1
  738. package/dist/services/subagents/subagent-run-control.d.ts +9 -1
  739. package/dist/services/subagents/subagent-run-control.d.ts.map +1 -1
  740. package/dist/services/subagents/subagent-run-control.js +12 -13
  741. package/dist/services/subagents/subagent-run-control.js.map +1 -1
  742. package/dist/services/subagents/tool-policy.d.ts.map +1 -1
  743. package/dist/services/subagents/tool-policy.js +11 -3
  744. package/dist/services/subagents/tool-policy.js.map +1 -1
  745. package/dist/services/subagents/types.d.ts +25 -2
  746. package/dist/services/subagents/types.d.ts.map +1 -1
  747. package/dist/services/subagents/types.js.map +1 -1
  748. package/dist/services/subagents/utils.d.ts +3 -1
  749. package/dist/services/subagents/utils.d.ts.map +1 -1
  750. package/dist/services/subagents/utils.js +4 -2
  751. package/dist/services/subagents/utils.js.map +1 -1
  752. package/dist/services/workspace/active-workspace-root.d.ts +6 -0
  753. package/dist/services/workspace/active-workspace-root.d.ts.map +1 -1
  754. package/dist/services/workspace/active-workspace-root.js +22 -0
  755. package/dist/services/workspace/active-workspace-root.js.map +1 -1
  756. package/dist/test-helpers/ink-testing.d.ts.map +1 -1
  757. package/dist/test-helpers/ink-testing.js +4 -1
  758. package/dist/test-helpers/ink-testing.js.map +1 -1
  759. package/dist/test-helpers/terminal-e2e.d.ts.map +1 -1
  760. package/dist/test-helpers/terminal-e2e.js +12 -2
  761. package/dist/test-helpers/terminal-e2e.js.map +1 -1
  762. package/dist/tools/agent/activate-skill.d.ts.map +1 -1
  763. package/dist/tools/agent/activate-skill.js +2 -2
  764. package/dist/tools/agent/activate-skill.js.map +1 -1
  765. package/dist/tools/agent/ask-mentor.d.ts.map +1 -1
  766. package/dist/tools/agent/ask-mentor.js +2 -2
  767. package/dist/tools/agent/ask-mentor.js.map +1 -1
  768. package/dist/tools/agent/ask-user-constants.d.ts +2 -2
  769. package/dist/tools/agent/ask-user-constants.d.ts.map +1 -1
  770. package/dist/tools/agent/ask-user-constants.js +1 -1
  771. package/dist/tools/agent/ask-user-constants.js.map +1 -1
  772. package/dist/tools/agent/run-subagent-async.d.ts +2 -11
  773. package/dist/tools/agent/run-subagent-async.d.ts.map +1 -1
  774. package/dist/tools/agent/run-subagent-async.js +8 -2
  775. package/dist/tools/agent/run-subagent-async.js.map +1 -1
  776. package/dist/tools/agent/run-subagent.d.ts.map +1 -1
  777. package/dist/tools/agent/run-subagent.js +8 -9
  778. package/dist/tools/agent/run-subagent.js.map +1 -1
  779. package/dist/tools/file/apply-patch.d.ts +2 -0
  780. package/dist/tools/file/apply-patch.d.ts.map +1 -1
  781. package/dist/tools/file/apply-patch.js +58 -14
  782. package/dist/tools/file/apply-patch.js.map +1 -1
  783. package/dist/tools/file/code-context.d.ts +5 -0
  784. package/dist/tools/file/code-context.d.ts.map +1 -1
  785. package/dist/tools/file/code-context.js +18 -6
  786. package/dist/tools/file/code-context.js.map +1 -1
  787. package/dist/tools/file/create-file.d.ts.map +1 -1
  788. package/dist/tools/file/create-file.js +11 -5
  789. package/dist/tools/file/create-file.js.map +1 -1
  790. package/dist/tools/file/edit-healing.d.ts +7 -0
  791. package/dist/tools/file/edit-healing.d.ts.map +1 -1
  792. package/dist/tools/file/edit-healing.js +7 -7
  793. package/dist/tools/file/edit-healing.js.map +1 -1
  794. package/dist/tools/file/glob.d.ts +3 -0
  795. package/dist/tools/file/glob.d.ts.map +1 -1
  796. package/dist/tools/file/glob.js +9 -3
  797. package/dist/tools/file/glob.js.map +1 -1
  798. package/dist/tools/file/grep.d.ts +5 -0
  799. package/dist/tools/file/grep.d.ts.map +1 -1
  800. package/dist/tools/file/grep.js +10 -6
  801. package/dist/tools/file/grep.js.map +1 -1
  802. package/dist/tools/file/patch-healing.d.ts +31 -0
  803. package/dist/tools/file/patch-healing.d.ts.map +1 -0
  804. package/dist/tools/file/patch-healing.js +231 -0
  805. package/dist/tools/file/patch-healing.js.map +1 -0
  806. package/dist/tools/file/read-file.d.ts +3 -0
  807. package/dist/tools/file/read-file.d.ts.map +1 -1
  808. package/dist/tools/file/read-file.js +9 -3
  809. package/dist/tools/file/read-file.js.map +1 -1
  810. package/dist/tools/file/search-replace.d.ts.map +1 -1
  811. package/dist/tools/file/search-replace.js +24 -6
  812. package/dist/tools/file/search-replace.js.map +1 -1
  813. package/dist/tools/format-helpers.d.ts +6 -0
  814. package/dist/tools/format-helpers.d.ts.map +1 -1
  815. package/dist/tools/format-helpers.js +23 -0
  816. package/dist/tools/format-helpers.js.map +1 -1
  817. package/dist/tools/memory/memory-tools.d.ts.map +1 -1
  818. package/dist/tools/memory/memory-tools.js +2 -2
  819. package/dist/tools/memory/memory-tools.js.map +1 -1
  820. package/dist/tools/system/shell.d.ts +16 -1
  821. package/dist/tools/system/shell.d.ts.map +1 -1
  822. package/dist/tools/system/shell.js +90 -25
  823. package/dist/tools/system/shell.js.map +1 -1
  824. package/dist/tools/types.d.ts +4 -0
  825. package/dist/tools/types.d.ts.map +1 -1
  826. package/dist/tools/types.js.map +1 -1
  827. package/dist/tools/web/web-fetch.d.ts.map +1 -1
  828. package/dist/tools/web/web-fetch.js +2 -2
  829. package/dist/tools/web/web-fetch.js.map +1 -1
  830. package/dist/tools/web/web-search.d.ts.map +1 -1
  831. package/dist/tools/web/web-search.js +2 -2
  832. package/dist/tools/web/web-search.js.map +1 -1
  833. package/dist/types/message.d.ts +1 -1
  834. package/dist/types/message.d.ts.map +1 -1
  835. package/dist/utils/ai/provider-credentials.d.ts +1 -1
  836. package/dist/utils/ai/provider-credentials.d.ts.map +1 -1
  837. package/dist/utils/ai/provider-credentials.js +18 -2
  838. package/dist/utils/ai/provider-credentials.js.map +1 -1
  839. package/dist/utils/ai/token-usage.d.ts +3 -1
  840. package/dist/utils/ai/token-usage.d.ts.map +1 -1
  841. package/dist/utils/ai/token-usage.js +7 -2
  842. package/dist/utils/ai/token-usage.js.map +1 -1
  843. package/dist/utils/apply-diff.d.ts.map +1 -1
  844. package/dist/utils/apply-diff.js +8 -0
  845. package/dist/utils/apply-diff.js.map +1 -1
  846. package/dist/utils/conversation/conversation-event-handler.d.ts.map +1 -1
  847. package/dist/utils/conversation/conversation-event-handler.js +60 -2
  848. package/dist/utils/conversation/conversation-event-handler.js.map +1 -1
  849. package/dist/utils/error-helpers.d.ts.map +1 -1
  850. package/dist/utils/error-helpers.js +8 -0
  851. package/dist/utils/error-helpers.js.map +1 -1
  852. package/dist/utils/inject-warning-into-tool-output.d.ts +30 -0
  853. package/dist/utils/inject-warning-into-tool-output.d.ts.map +1 -1
  854. package/dist/utils/inject-warning-into-tool-output.js +39 -0
  855. package/dist/utils/inject-warning-into-tool-output.js.map +1 -1
  856. package/dist/utils/output/tty-osc.d.ts +1 -1
  857. package/dist/utils/output/tty-osc.js +1 -1
  858. package/dist/utils/settings-command.d.ts.map +1 -1
  859. package/dist/utils/settings-command.js +105 -6
  860. package/dist/utils/settings-command.js.map +1 -1
  861. package/dist/utils/shell/execute-shell.d.ts +8 -0
  862. package/dist/utils/shell/execute-shell.d.ts.map +1 -1
  863. package/dist/utils/shell/execute-shell.js +36 -30
  864. package/dist/utils/shell/execute-shell.js.map +1 -1
  865. package/dist/utils/shell/sandbox/sandbox-env.d.ts +1 -0
  866. package/dist/utils/shell/sandbox/sandbox-env.d.ts.map +1 -1
  867. package/dist/utils/shell/sandbox/sandbox-env.js +2 -0
  868. package/dist/utils/shell/sandbox/sandbox-env.js.map +1 -1
  869. package/dist/utils/shell/sandbox/sandbox-policy.d.ts +2 -0
  870. package/dist/utils/shell/sandbox/sandbox-policy.d.ts.map +1 -1
  871. package/dist/utils/shell/sandbox/sandbox-policy.js +1 -1
  872. package/dist/utils/shell/sandbox/sandbox-policy.js.map +1 -1
  873. package/dist/utils/shell/sandbox/shell-sandbox-runner.d.ts.map +1 -1
  874. package/dist/utils/shell/sandbox/shell-sandbox-runner.js +1 -2
  875. package/dist/utils/shell/sandbox/shell-sandbox-runner.js.map +1 -1
  876. package/dist/utils/shell/shell-child-registry.d.ts +11 -0
  877. package/dist/utils/shell/shell-child-registry.d.ts.map +1 -0
  878. package/dist/utils/shell/shell-child-registry.js +40 -0
  879. package/dist/utils/shell/shell-child-registry.js.map +1 -0
  880. package/dist/utils/shell/shell-output.d.ts.map +1 -1
  881. package/dist/utils/shell/shell-output.js +10 -6
  882. package/dist/utils/shell/shell-output.js.map +1 -1
  883. package/dist/utils/shell/temp-sweep.d.ts +28 -0
  884. package/dist/utils/shell/temp-sweep.d.ts.map +1 -0
  885. package/dist/utils/shell/temp-sweep.js +140 -0
  886. package/dist/utils/shell/temp-sweep.js.map +1 -0
  887. package/dist/utils/streaming/extract-command-messages.d.ts +12 -5
  888. package/dist/utils/streaming/extract-command-messages.d.ts.map +1 -1
  889. package/dist/utils/streaming/extract-command-messages.js +29 -33
  890. package/dist/utils/streaming/extract-command-messages.js.map +1 -1
  891. package/dist/utils/streaming/streaming-session-factory.d.ts +8 -0
  892. package/dist/utils/streaming/streaming-session-factory.d.ts.map +1 -1
  893. package/dist/utils/streaming/streaming-session-factory.js +3 -0
  894. package/dist/utils/streaming/streaming-session-factory.js.map +1 -1
  895. package/dist/utils/value-suggestions.d.ts +8 -0
  896. package/dist/utils/value-suggestions.d.ts.map +1 -1
  897. package/dist/utils/value-suggestions.js +71 -0
  898. package/dist/utils/value-suggestions.js.map +1 -1
  899. package/package.json +14 -10
  900. package/dist/utils/output/synchronized-output.d.ts +0 -35
  901. package/dist/utils/output/synchronized-output.d.ts.map +0 -1
  902. package/dist/utils/output/synchronized-output.js +0 -66
  903. package/dist/utils/output/synchronized-output.js.map +0 -1
@@ -0,0 +1,1277 @@
1
+ import crypto from 'node:crypto';
2
+ import { createGatewayAssertion } from './assertion.js';
3
+ import { GatewayLifecycle } from './lifecycle.js';
4
+ import { loadGatewayManifest, WorkspaceAdmission, WorkspaceAdmissionError, } from './workspace-admission.js';
5
+ import { assertProviderBrokerReady, composeGatewaySession, } from './worker-boundary.js';
6
+ import { createSafeLogMetadata, GatewayAuditLog } from './safe-log.js';
7
+ import { AssertionVerifier } from './assertion.js';
8
+ import { SqliteReplayLedger } from './replay-ledger.js';
9
+ import { GatewayServer } from './server.js';
10
+ import { FROZEN_AGENT_EVENT_TYPES, GatewayPersistenceError, TERMINAL_AGENT_EVENT_TYPES, } from './persistence/contracts.js';
11
+ import { createSessionProjectionSource, } from './persistence/projection.js';
12
+ import { decideInteraction, InteractionProtocolError, projectPendingInteraction, validatePendingInteractionDto, } from './interaction-protocol.js';
13
+ import { GatewayAdmissionPersistence } from './persistence/admission-persistence.js';
14
+ import { GATEWAY_EVENT_HEARTBEAT_INTERVAL_MS, GATEWAY_EVENT_STREAM_CONTENT_TYPE, GATEWAY_EVENT_STREAM_HEARTBEAT, } from './server.js';
15
+ import { ServerSession } from './server-session.js';
16
+ import { ServerSessionError } from './server-session.js';
17
+ const MAX_BUFFERED_SSE_EVENTS = 256;
18
+ const NONCRITICAL_RUNTIME_EVENT_TYPES = new Set(['text_delta', 'reasoning_delta']);
19
+ const isCriticalRuntimeEvent = (event) => !NONCRITICAL_RUNTIME_EVENT_TYPES.has(event.type);
20
+ const INTERACTION_METRICS = [
21
+ 'interaction_presented',
22
+ 'interaction_updated',
23
+ 'interaction_resolved',
24
+ 'interaction_stale',
25
+ 'interaction_duplicate',
26
+ 'interaction_sanitization_rejected',
27
+ 'interaction_continuation_failed',
28
+ ];
29
+ const PUBLIC_EVENT_PAYLOAD_KEYS = new Set([
30
+ 'turnId',
31
+ 'clientRequestId',
32
+ 'messageId',
33
+ 'delta',
34
+ 'callId',
35
+ 'toolName',
36
+ 'message',
37
+ 'interaction',
38
+ 'interactionId',
39
+ 'outcome',
40
+ 'reason',
41
+ 'variant',
42
+ 'revision',
43
+ 'text',
44
+ 'usage',
45
+ 'inputTokens',
46
+ 'outputTokens',
47
+ 'totalTokens',
48
+ 'version',
49
+ 'kind',
50
+ 'descriptor',
51
+ 'choices',
52
+ 'askUser',
53
+ 'questions',
54
+ 'answers',
55
+ 'currentQuestionIndex',
56
+ 'index',
57
+ 'question',
58
+ 'options',
59
+ 'multiSelect',
60
+ 'label',
61
+ 'description',
62
+ 'destructive',
63
+ 'id',
64
+ 'role',
65
+ 'agentName',
66
+ 'argumentsText',
67
+ 'checkIn',
68
+ 'display',
69
+ 'target',
70
+ 'scope',
71
+ 'warning',
72
+ 'displayPath',
73
+ 'displayParent',
74
+ 'sensitive',
75
+ 'llmAdvisory',
76
+ 'reasoning',
77
+ 'approved',
78
+ 'model',
79
+ 'riskLevel',
80
+ 'deniedRead',
81
+ 'runBudgetEvidence',
82
+ ]);
83
+ export class GatewayStartupError extends Error {
84
+ constructor() {
85
+ super('gateway prerequisites unavailable');
86
+ this.name = 'GatewayStartupError';
87
+ }
88
+ }
89
+ export function assertGatewayStartup(config, manifest) {
90
+ if (!config.socketPath.startsWith('/') || !config.issuer || !config.audience || !config.replayDbPath)
91
+ throw new GatewayStartupError();
92
+ if (!config.publicKeys ||
93
+ (config.publicKeys instanceof Map ? config.publicKeys.size === 0 : Object.keys(config.publicKeys).length === 0))
94
+ throw new GatewayStartupError();
95
+ if (!manifest)
96
+ throw new GatewayStartupError();
97
+ if (!config.manifestSha256 || !/^[a-f0-9]{64}$/i.test(config.manifestSha256))
98
+ throw new GatewayStartupError();
99
+ if (!config.providerBroker || !config.providerProbe?.available || !config.providerProbe.secretFree)
100
+ throw new GatewayStartupError();
101
+ if (config.workerSandboxAvailable !== true || typeof config.workspaceBoundaryProbe !== 'function')
102
+ throw new GatewayStartupError();
103
+ if (config.sshEnabled || config.autoApprove || config.allowUnsandboxed)
104
+ throw new GatewayStartupError();
105
+ if (typeof config.auditWriter !== 'function')
106
+ throw new GatewayStartupError();
107
+ assertProviderBrokerReady(config.providerBroker, config.providerProbe);
108
+ if (!config.tmpDir?.startsWith('/'))
109
+ throw new GatewayStartupError();
110
+ return manifest;
111
+ }
112
+ /** Gateway control plane. Runtime/session protocols remain private RPC consumers. */
113
+ export class Term2Gateway {
114
+ #config;
115
+ #manifest;
116
+ #replay;
117
+ #admission;
118
+ #verifier;
119
+ #lifecycle = new GatewayLifecycle();
120
+ #audit;
121
+ #sessions = new Map();
122
+ #persisted = new Map();
123
+ #admissions;
124
+ #interactionBindings = new Map();
125
+ #interactionCounters = new Map();
126
+ #eventPersistenceTails = new Map();
127
+ #shutdownInProgress = false;
128
+ #server;
129
+ constructor(config, manifest) {
130
+ this.#config = config;
131
+ this.#manifest = manifest;
132
+ this.#replay = new SqliteReplayLedger(config.replayDbPath);
133
+ this.#admission = new WorkspaceAdmission(manifest, {
134
+ allowWrite: config.allowWrite === true,
135
+ boundaryProbe: config.workspaceBoundaryProbe,
136
+ });
137
+ this.#verifier = new AssertionVerifier({
138
+ issuer: config.issuer,
139
+ audience: config.audience,
140
+ publicKeys: config.publicKeys,
141
+ replayLedger: this.#replay,
142
+ });
143
+ this.#audit = new GatewayAuditLog(config.auditWriter);
144
+ this.#admissions = config.persistence ? new GatewayAdmissionPersistence(config.persistence.index) : null;
145
+ this.#server = new GatewayServer({
146
+ socketPath: config.socketPath,
147
+ verifier: this.#verifier,
148
+ lifecycle: this.#lifecycle,
149
+ handler: (input) => this.#handleRpc(input),
150
+ });
151
+ }
152
+ async #handleRpc(input) {
153
+ const { claims, url } = input;
154
+ const route = matchPrivateRoute(input.request.method ?? 'GET', url.pathname);
155
+ if (!route || (route.legacy && claims.purpose !== 'session_create')) {
156
+ return publicError(404, 'not_found', 'gateway route not found');
157
+ }
158
+ if (!route.legacy && route.sessionId && route.sessionId !== claims.sessionId)
159
+ return publicError(400, 'protocol_conflict', 'gateway path and assertion session do not match');
160
+ if (!route.legacy && route.purpose !== claims.purpose)
161
+ return publicError(400, 'protocol_conflict', 'gateway purpose does not match route');
162
+ try {
163
+ if (claims.purpose === 'workspace_list') {
164
+ await this.#audit.write(createSafeLogMetadata({
165
+ operation: 'workspace_list',
166
+ outcome: 'allowed',
167
+ reasonCode: 'accepted',
168
+ ...(input.correlationId ? { correlationId: input.correlationId } : {}),
169
+ }));
170
+ const limit = parseQueryLimit(url.searchParams.get('limit')) ?? 20;
171
+ if (limit < 1 || limit > 50 || url.searchParams.get('cursor') !== null)
172
+ return publicError(400, 'invalid_cursor', 'workspace cursor is invalid');
173
+ return {
174
+ status: 200,
175
+ body: { workspaces: this.#admission.listAliases(claims.sub).slice(0, limit), nextCursor: null },
176
+ };
177
+ }
178
+ if (claims.purpose === 'session_create') {
179
+ if (hasDeferredModelSelectionField(input.body))
180
+ return publicError(422, 'model_selection_deferred', 'Model selection is not available');
181
+ if (!isSessionCreateBody(input.body, claims.workspaceId, route.legacy))
182
+ return publicError(400, 'validation_error', 'session request is invalid');
183
+ const session = await this.createSession(claims, undefined, input.correlationId);
184
+ if (this.#config.persistence) {
185
+ const projection = await this.#projectionFor(claims.sub, session.sessionId);
186
+ return { status: 201, body: { session: toSessionProjection(projection) } };
187
+ }
188
+ return {
189
+ status: 201,
190
+ body: { sessionId: session.sessionId, workspaceId: session.binding.workspaceId, accepted: true },
191
+ };
192
+ }
193
+ if (claims.purpose === 'session_list') {
194
+ if (!this.#config.persistence)
195
+ return publicError(503, 'gateway_unavailable', 'gateway persistence unavailable', true);
196
+ const limit = parseQueryLimit(url.searchParams.get('limit'));
197
+ const cursor = url.searchParams.get('cursor') ?? undefined;
198
+ try {
199
+ return { status: 200, body: this.#config.persistence.index.list(claims.sub, { limit, cursor }) };
200
+ }
201
+ catch (error) {
202
+ if (error instanceof GatewayPersistenceError && error.code === 'cursor_invalid')
203
+ return publicError(400, 'invalid_cursor', 'session cursor is invalid');
204
+ throw error;
205
+ }
206
+ }
207
+ if (!claims.sessionId)
208
+ return publicError(400, 'protocol_conflict', 'session assertion is incomplete');
209
+ if (claims.purpose === 'session_read') {
210
+ const projection = await this.#projectionFor(claims.sub, claims.sessionId);
211
+ return { status: 200, body: { session: toSessionProjection(projection) } };
212
+ }
213
+ if (claims.purpose === 'message_submit')
214
+ return await this.#submitMessage(claims, input.body);
215
+ if (claims.purpose === 'abort')
216
+ return await this.#abortSession(claims, input.body);
217
+ if (claims.purpose === 'interaction_resolve')
218
+ return await this.#resolveInteraction(claims, route.interactionId, input.body);
219
+ if (claims.purpose === 'events_connect')
220
+ return await this.#eventsResponse(claims, url, input.request);
221
+ return publicError(403, 'gateway_unavailable', 'gateway operation is unavailable');
222
+ }
223
+ catch (error) {
224
+ return this.#mapError(error);
225
+ }
226
+ }
227
+ #interactionBindingFor(sessionId, snapshot, turnId) {
228
+ const current = this.#interactionBindings.get(sessionId);
229
+ if (current && current.expectedInteractionId === snapshot.interactionId)
230
+ return current;
231
+ const publicInteractionId = crypto.randomUUID();
232
+ const dto = projectPendingInteraction(snapshot.approval, publicInteractionId, 1);
233
+ const binding = {
234
+ publicInteractionId,
235
+ expectedInteractionId: snapshot.interactionId,
236
+ continuationGeneration: crypto.randomUUID(),
237
+ revision: 1,
238
+ turnId,
239
+ variant: dto.variant,
240
+ dto,
241
+ };
242
+ this.#interactionBindings.set(sessionId, binding);
243
+ this.#countInteraction('interaction_presented');
244
+ return binding;
245
+ }
246
+ #countInteraction(metric) {
247
+ this.#interactionCounters.set(metric, (this.#interactionCounters.get(metric) ?? 0) + 1);
248
+ }
249
+ async #ensurePersistedSession(ownerUserId, sessionId) {
250
+ const existing = this.#persisted.get(sessionId);
251
+ if (existing) {
252
+ if (existing.record.ownerUserId !== ownerUserId)
253
+ throw new GatewayPersistenceError('owner_mismatch');
254
+ return existing;
255
+ }
256
+ const persistence = this.#config.persistence;
257
+ if (!persistence)
258
+ throw new GatewayPersistenceError('not_found', 'session not found');
259
+ const record = persistence.index.getForOwner(ownerUserId, sessionId);
260
+ const grantVersion = Number(record.grantVersion);
261
+ if (!Number.isSafeInteger(grantVersion))
262
+ throw new GatewayPersistenceError('readonly', 'session grant version is invalid');
263
+ let binding;
264
+ try {
265
+ binding = this.#admission.restore(sessionId, ownerUserId, record.workspaceId, grantVersion);
266
+ }
267
+ catch {
268
+ throw new GatewayPersistenceError('not_found', 'session not found');
269
+ }
270
+ try {
271
+ const reopened = await persistence.open(binding);
272
+ this.#persisted.set(sessionId, reopened);
273
+ return reopened;
274
+ }
275
+ catch (error) {
276
+ this.#admission.remove(sessionId);
277
+ throw error;
278
+ }
279
+ }
280
+ async #projectionFor(ownerUserId, sessionId) {
281
+ const persistence = this.#config.persistence;
282
+ const persisted = await this.#ensurePersistedSession(ownerUserId, sessionId);
283
+ if (!persistence)
284
+ throw new GatewayPersistenceError('not_found', 'session not found');
285
+ return await createSessionProjectionSource({
286
+ index: persistence.index,
287
+ layout: persistence.layout,
288
+ ownerUserId,
289
+ sessionId,
290
+ journal: persisted.persistence.journal,
291
+ liveInteraction: () => {
292
+ const session = this.#sessions.get(sessionId);
293
+ if (!(session instanceof ServerSession))
294
+ return null;
295
+ const snapshot = session.service.getPendingInteractionSnapshot();
296
+ if (!snapshot)
297
+ return null;
298
+ const existingBinding = this.#interactionBindings.get(sessionId);
299
+ const turnId = session.activeTurnId ?? existingBinding?.turnId;
300
+ if (!turnId)
301
+ return null;
302
+ // A projection/read is observational. Only the approval event path
303
+ // may create a public binding; reconnects must never mint or replace
304
+ // the ID that the first viewport was given.
305
+ if (!existingBinding || existingBinding.expectedInteractionId !== snapshot.interactionId)
306
+ return null;
307
+ const binding = existingBinding;
308
+ return Promise.resolve({
309
+ state: 'pending',
310
+ interaction: interactionDtoFromSnapshot(snapshot, binding.publicInteractionId, binding.revision),
311
+ turnId: binding.turnId,
312
+ });
313
+ },
314
+ });
315
+ }
316
+ async #submitMessage(claims, body) {
317
+ if (hasAttachments(body))
318
+ return publicError(422, 'attachments_not_enabled', 'Attachments are not available');
319
+ if (!this.#admissions || !this.#config.persistence)
320
+ return publicError(503, 'persistence_unavailable', 'gateway persistence unavailable', true);
321
+ if (!isMessageBody(body))
322
+ return publicError(400, 'validation_error', 'message request is invalid');
323
+ const session = this.#sessions.get(claims.sessionId);
324
+ const persisted = this.#persisted.get(claims.sessionId);
325
+ if (!(session instanceof ServerSession) || !persisted)
326
+ return publicError(409, 'session_not_admitting', 'session is not admitting messages');
327
+ const turnId = crypto.randomUUID();
328
+ try {
329
+ const result = await this.#admissions.admit({
330
+ ownerUserId: claims.sub,
331
+ sessionId: claims.sessionId,
332
+ clientRequestId: body.clientRequestId,
333
+ body,
334
+ turnId,
335
+ runtime: session,
336
+ persistence: persisted.persistence.critical,
337
+ term2Fact: { type: 'user_message', message: { id: turnId, sender: 'user', text: body.text } },
338
+ acceptedEvent: {
339
+ sessionId: claims.sessionId,
340
+ type: 'user_message_accepted',
341
+ payload: { turnId, clientRequestId: body.clientRequestId, messageId: turnId },
342
+ },
343
+ beforeCommit: () => this.#enqueueEventPersistence(claims.sessionId, async () => {
344
+ await persisted.persistence.critical.appendJournalCritical({
345
+ sessionId: claims.sessionId,
346
+ type: 'assistant_started',
347
+ payload: { turnId },
348
+ });
349
+ }),
350
+ });
351
+ if (result.kind === 'rejected') {
352
+ return result.reason === 'queue_full'
353
+ ? publicError(429, 'queue_full', 'message queue is full', true)
354
+ : publicError(409, 'session_not_admitting', 'session is not admitting messages');
355
+ }
356
+ return {
357
+ status: 202,
358
+ body: {
359
+ sessionId: claims.sessionId,
360
+ clientRequestId: body.clientRequestId,
361
+ turnId: result.record.turnId,
362
+ accepted: true,
363
+ replayed: result.replayed,
364
+ },
365
+ };
366
+ }
367
+ catch (error) {
368
+ return this.#mapError(error);
369
+ }
370
+ }
371
+ async #abortSession(claims, body) {
372
+ if (!isTurnBody(body))
373
+ return publicError(400, 'validation_error', 'abort request is invalid');
374
+ const session = this.#sessions.get(claims.sessionId);
375
+ if (!(session instanceof ServerSession))
376
+ return publicError(409, 'session_not_admitting', 'session is not admitting');
377
+ const outcome = await session.abort(body.turnId);
378
+ if (outcome.kind === 'aborted') {
379
+ const persisted = this.#persisted.get(claims.sessionId);
380
+ if (persisted) {
381
+ await this.#enqueueEventPersistence(claims.sessionId, async () => {
382
+ const admissions = this.#config.persistence?.index.listAdmissions(claims.sub, claims.sessionId) ?? [];
383
+ for (const discardedTurnId of outcome.discardedTurnIds) {
384
+ if (hasTerminalTurnEvent(persisted.persistence.journal.events(), discardedTurnId))
385
+ continue;
386
+ const admission = admissions.find((candidate) => candidate.turnId === discardedTurnId);
387
+ await persisted.persistence.journal.append({
388
+ sessionId: claims.sessionId,
389
+ type: 'user_message_rejected',
390
+ payload: {
391
+ turnId: discardedTurnId,
392
+ ...(admission ? { clientRequestId: admission.clientRequestId } : {}),
393
+ reason: 'queue_discarded',
394
+ },
395
+ }, { durability: 'critical' });
396
+ if (admission) {
397
+ this.#config.persistence?.index.updateAdmission(claims.sub, claims.sessionId, admission.clientRequestId, {
398
+ state: 'rejected',
399
+ result: 'queue_discarded',
400
+ });
401
+ }
402
+ }
403
+ await persisted.persistence.journal.append({
404
+ sessionId: claims.sessionId,
405
+ type: 'turn_aborted',
406
+ payload: { turnId: body.turnId, outcome: 'aborted' },
407
+ }, { durability: 'critical' });
408
+ });
409
+ }
410
+ return { status: 202, body: { sessionId: claims.sessionId, turnId: body.turnId, accepted: true } };
411
+ }
412
+ if (outcome.kind === 'already_settled' || outcome.kind === 'no_op')
413
+ return {
414
+ status: 200,
415
+ body: { sessionId: claims.sessionId, turnId: body.turnId, accepted: false, alreadySettled: true },
416
+ };
417
+ return publicError(409, 'session_not_admitting', 'session is interrupted');
418
+ }
419
+ async #resolveInteraction(claims, interactionId, body) {
420
+ if (!isInteractionResolveRequest(body))
421
+ return publicError(400, 'validation_error', 'interaction request is invalid');
422
+ const projection = await this.#projectionFor(claims.sub, claims.sessionId);
423
+ const session = this.#sessions.get(claims.sessionId);
424
+ const binding = this.#interactionBindings.get(claims.sessionId);
425
+ const snapshot = session instanceof ServerSession ? session.service.getPendingInteractionSnapshot() : null;
426
+ // A live runtime owns the current interaction. A public ID from an older
427
+ // presentation is stale even when the durable journal still says the
428
+ // interaction was recovered during startup.
429
+ if (snapshot !== null && (!binding || binding.publicInteractionId !== interactionId)) {
430
+ this.#countInteraction('interaction_stale');
431
+ return publicError(409, 'stale_interaction', 'interaction is stale');
432
+ }
433
+ if (projection.interaction?.state === 'recovered' && snapshot === null)
434
+ return publicError(409, 'interaction_not_resolvable', 'interaction is not resolvable');
435
+ if (!(session instanceof ServerSession))
436
+ return publicError(404, 'not_found', 'session not found');
437
+ if (projection.resolvedInteractionIds.has(interactionId)) {
438
+ this.#countInteraction('interaction_duplicate');
439
+ return publicError(409, 'interaction_already_resolved', 'interaction is already resolved');
440
+ }
441
+ if (!binding || binding.publicInteractionId !== interactionId) {
442
+ this.#countInteraction('interaction_stale');
443
+ return publicError(409, 'stale_interaction', 'interaction is stale');
444
+ }
445
+ const resolutionCode = classifyInteractionResolution(projection.interaction, snapshot !== null);
446
+ if (resolutionCode) {
447
+ this.#countInteraction(resolutionCode === 'interaction_already_resolved' ? 'interaction_duplicate' : 'interaction_stale');
448
+ return publicError(409, resolutionCode, resolutionCode === 'interaction_not_resolvable'
449
+ ? 'interaction is not resolvable'
450
+ : 'interaction is already resolved');
451
+ }
452
+ if (!snapshot) {
453
+ this.#countInteraction('interaction_duplicate');
454
+ return publicError(409, 'interaction_already_resolved', 'interaction is already resolved');
455
+ }
456
+ if (body.revision !== binding.revision) {
457
+ this.#countInteraction('interaction_stale');
458
+ return publicError(409, 'stale_interaction', 'interaction revision is stale');
459
+ }
460
+ const continuationAbortGeneration = session.abortGeneration;
461
+ let decision;
462
+ try {
463
+ decision = decideInteraction(binding.dto, body);
464
+ }
465
+ catch (error) {
466
+ if (error instanceof InteractionProtocolError) {
467
+ this.#countInteraction('interaction_sanitization_rejected');
468
+ return publicError(400, 'validation_error', 'interaction decision is invalid');
469
+ }
470
+ throw error;
471
+ }
472
+ try {
473
+ const result = session.resolvePendingInteraction({
474
+ expectedInteractionId: binding.expectedInteractionId,
475
+ answer: decision.answer,
476
+ rejectionReason: decision.rejectionReason,
477
+ approvalAnswer: decision.approvalAnswer,
478
+ });
479
+ if (result.kind === 'awaiting_next_question') {
480
+ binding.revision += 1;
481
+ binding.dto = projectPendingInteraction(result.snapshot.approval, binding.publicInteractionId, binding.revision, result.snapshot.askUserAnswers, result.snapshot.currentAskUserQuestionIndex);
482
+ await this.#enqueueEventPersistence(claims.sessionId, async () => {
483
+ const persisted = this.#persisted.get(claims.sessionId);
484
+ if (!persisted)
485
+ throw new GatewayPersistenceError('not_found', 'session persistence is unavailable');
486
+ persisted.persistence.interactionCheckpoint.save({
487
+ turnId: binding.turnId,
488
+ interaction: binding.dto,
489
+ revision: binding.revision,
490
+ generation: binding.continuationGeneration,
491
+ });
492
+ await persisted.persistence.journal.append({
493
+ sessionId: claims.sessionId,
494
+ type: 'interaction_updated',
495
+ payload: { turnId: binding.turnId, interaction: binding.dto },
496
+ }, { durability: 'critical' });
497
+ });
498
+ this.#countInteraction('interaction_updated');
499
+ return { status: 200, body: { accepted: false, interaction: binding.dto } };
500
+ }
501
+ if (result.kind === 'none')
502
+ return publicError(409, 'interaction_already_resolved', 'interaction is already resolved');
503
+ if (result.kind === 'stale_interaction')
504
+ return publicError(409, 'stale_interaction', 'interaction is stale');
505
+ await this.#enqueueEventPersistence(claims.sessionId, async () => {
506
+ const persisted = this.#persisted.get(claims.sessionId);
507
+ if (!persisted)
508
+ throw new GatewayPersistenceError('not_found', 'session persistence is unavailable');
509
+ await persisted.persistence.journal.append({
510
+ sessionId: claims.sessionId,
511
+ type: 'interaction_resolved',
512
+ payload: {
513
+ turnId: binding.turnId,
514
+ interactionId: binding.publicInteractionId,
515
+ outcome: decision.outcome,
516
+ variant: binding.variant,
517
+ },
518
+ }, { durability: 'critical' });
519
+ persisted.persistence.interactionCheckpoint.clear();
520
+ });
521
+ this.#interactionBindings.delete(claims.sessionId);
522
+ this.#countInteraction('interaction_resolved');
523
+ try {
524
+ if (session.abortGeneration !== continuationAbortGeneration || session.activeTurnId !== binding.turnId) {
525
+ throw new ServerSessionError('interrupted');
526
+ }
527
+ await session.service.handleApprovalDecision(decision.answer, decision.rejectionReason, {
528
+ approvalAnswer: decision.approvalAnswer,
529
+ });
530
+ }
531
+ catch (error) {
532
+ this.#countInteraction('interaction_continuation_failed');
533
+ await this.#recordContinuationFailure(claims.sessionId, binding);
534
+ throw error;
535
+ }
536
+ return {
537
+ status: 202,
538
+ body: {
539
+ sessionId: claims.sessionId,
540
+ turnId: binding.turnId,
541
+ interactionId: binding.publicInteractionId,
542
+ accepted: true,
543
+ },
544
+ };
545
+ }
546
+ catch (error) {
547
+ if (error instanceof ServerSessionError && error.code === 'stale_interaction')
548
+ return publicError(409, 'stale_interaction', 'interaction is stale');
549
+ throw error;
550
+ }
551
+ }
552
+ async #eventsResponse(claims, url, request) {
553
+ const queryCursor = url.searchParams.get('after');
554
+ const headerCursor = typeof request.headers['last-event-id'] === 'string' ? request.headers['last-event-id'] : null;
555
+ if (queryCursor !== null && headerCursor !== null && queryCursor !== headerCursor)
556
+ return publicError(400, 'protocol_conflict', 'event cursors do not match');
557
+ const after = parseEventCursor(queryCursor ?? headerCursor);
558
+ if (after.error)
559
+ return publicError(400, after.error, 'event cursor is invalid');
560
+ const source = await this.#projectionFor(claims.sub, claims.sessionId);
561
+ let activeResponse = null;
562
+ let closed = false;
563
+ let buffered = [];
564
+ let unsubscribe = () => undefined;
565
+ const closeSlowSubscriber = () => {
566
+ if (closed)
567
+ return;
568
+ closed = true;
569
+ unsubscribe();
570
+ if (activeResponse && !activeResponse.writableEnded)
571
+ activeResponse.destroy();
572
+ };
573
+ const writeEvent = (response, event) => {
574
+ if (!isPublicEventEnvelope(event))
575
+ return closeSlowSubscriber();
576
+ const accepted = response.write(`id: ${event.id}\ndata: ${JSON.stringify(event)}\n\n`);
577
+ if (!accepted)
578
+ closeSlowSubscriber();
579
+ };
580
+ const live = source.subscribeFrom(after.value, (event) => {
581
+ if (closed)
582
+ return;
583
+ if (!activeResponse) {
584
+ if (buffered.length >= MAX_BUFFERED_SSE_EVENTS)
585
+ return closeSlowSubscriber();
586
+ buffered.push(event);
587
+ return;
588
+ }
589
+ writeEvent(activeResponse, event);
590
+ });
591
+ if (live.kind === 'reload_required') {
592
+ const status = live.reason === 'cursor_compacted' ? 410 : 503;
593
+ const code = live.reason === 'cursor_compacted' ? 'cursor_compacted' : 'gateway_unavailable';
594
+ return publicError(status, code, 'event replay requires a session reload', true, {
595
+ reloadRequired: true,
596
+ session: toSessionProjection(source),
597
+ latestSequence: live.latestSequence,
598
+ });
599
+ }
600
+ unsubscribe = live.unsubscribe;
601
+ if (live.replay.some((event) => !isPublicEventEnvelope(event))) {
602
+ live.unsubscribe();
603
+ return publicError(503, 'gateway_unavailable', 'event stream is unavailable', true);
604
+ }
605
+ return {
606
+ status: 200,
607
+ body: null,
608
+ headers: {
609
+ 'content-type': GATEWAY_EVENT_STREAM_CONTENT_TYPE,
610
+ 'cache-control': 'no-cache',
611
+ connection: 'keep-alive',
612
+ 'x-accel-buffering': 'no',
613
+ },
614
+ stream: {
615
+ start: async (response, request) => {
616
+ activeResponse = response;
617
+ for (const event of live.replay) {
618
+ if (closed)
619
+ break;
620
+ writeEvent(response, event);
621
+ }
622
+ const queued = buffered;
623
+ buffered = [];
624
+ for (const event of queued) {
625
+ if (closed)
626
+ break;
627
+ writeEvent(response, event);
628
+ }
629
+ const heartbeat = setInterval(() => {
630
+ if (!response.writableEnded) {
631
+ const accepted = response.write(`${GATEWAY_EVENT_STREAM_HEARTBEAT} ${new Date().toISOString()}\n\n`);
632
+ if (!accepted)
633
+ closeSlowSubscriber();
634
+ }
635
+ }, GATEWAY_EVENT_HEARTBEAT_INTERVAL_MS);
636
+ heartbeat.unref?.();
637
+ await new Promise((resolve) => {
638
+ const close = () => {
639
+ clearInterval(heartbeat);
640
+ unsubscribe();
641
+ activeResponse = null;
642
+ closed = true;
643
+ resolve();
644
+ };
645
+ request.once('close', close);
646
+ response.once('close', close);
647
+ });
648
+ },
649
+ },
650
+ };
651
+ }
652
+ async #recordContinuationFailure(sessionId, binding) {
653
+ try {
654
+ await this.#enqueueEventPersistence(sessionId, async () => {
655
+ const persisted = this.#persisted.get(sessionId);
656
+ if (!persisted)
657
+ throw new GatewayPersistenceError('not_found', 'session persistence is unavailable');
658
+ await persisted.persistence.journal.append({
659
+ sessionId,
660
+ type: 'turn_failed',
661
+ payload: { turnId: binding.turnId, outcome: 'failed', reason: 'interaction_continuation_failed' },
662
+ }, { durability: 'critical' });
663
+ persisted.persistence.interactionCheckpoint.clear();
664
+ });
665
+ }
666
+ catch {
667
+ // If the truthful terminal fact cannot be appended, retain a sanitized
668
+ // checkpoint so restart recovery does not lose the interaction entirely.
669
+ try {
670
+ this.#persisted.get(sessionId)?.persistence.interactionCheckpoint.save({
671
+ turnId: binding.turnId,
672
+ interaction: binding.dto,
673
+ revision: binding.revision,
674
+ generation: binding.continuationGeneration,
675
+ });
676
+ }
677
+ catch {
678
+ // The gateway owns this persistence failure boundary; admission
679
+ // remains fail-closed rather than fabricating a recovery fact.
680
+ }
681
+ }
682
+ }
683
+ #enqueueEventPersistence(sessionId, work) {
684
+ const previous = this.#eventPersistenceTails.get(sessionId) ?? Promise.resolve();
685
+ const next = previous.catch(() => undefined).then(work);
686
+ this.#eventPersistenceTails.set(sessionId, next);
687
+ void next.then(() => {
688
+ if (this.#eventPersistenceTails.get(sessionId) === next)
689
+ this.#eventPersistenceTails.delete(sessionId);
690
+ }, () => {
691
+ if (this.#eventPersistenceTails.get(sessionId) === next)
692
+ this.#eventPersistenceTails.delete(sessionId);
693
+ });
694
+ return next;
695
+ }
696
+ async #persistConversationEvent(sessionId, event, context) {
697
+ return this.#enqueueEventPersistence(sessionId, async () => {
698
+ const persisted = this.#persisted.get(sessionId);
699
+ if (!persisted)
700
+ return;
701
+ const admissions = this.#config.persistence?.index.listAdmissions(persisted.record.ownerUserId, sessionId) ?? [];
702
+ for (const discardedTurnId of new Set(context.discardedTurnIds)) {
703
+ if (hasTerminalTurnEvent(persisted.persistence.journal.events(), discardedTurnId))
704
+ continue;
705
+ const admission = admissions.find((candidate) => candidate.turnId === discardedTurnId);
706
+ await persisted.persistence.journal.append({
707
+ sessionId,
708
+ type: 'user_message_rejected',
709
+ payload: {
710
+ turnId: discardedTurnId,
711
+ ...(admission ? { clientRequestId: admission.clientRequestId } : {}),
712
+ reason: 'queue_discarded',
713
+ },
714
+ }, { durability: 'critical' });
715
+ if (admission)
716
+ this.#config.persistence?.index.updateAdmission(persisted.record.ownerUserId, sessionId, admission.clientRequestId, { state: 'rejected', result: 'queue_discarded' });
717
+ }
718
+ if (!context.turnId)
719
+ return;
720
+ const session = this.#sessions.get(sessionId);
721
+ const snapshot = session instanceof ServerSession ? session.service.getPendingInteractionSnapshot() : null;
722
+ const binding = event.type === 'approval_required' && snapshot
723
+ ? this.#interactionBindingFor(sessionId, snapshot, context.turnId)
724
+ : undefined;
725
+ // An ask_user answer can advance the live binding before the original
726
+ // awaitable approval sink reaches this queue. Do not republish that
727
+ // old presentation as a second approval after interaction_updated.
728
+ if (event.type === 'approval_required' && binding?.revision && binding.revision > 1)
729
+ return;
730
+ const mapped = mapConversationEvent(event, context.turnId, sessionId, binding, snapshot ?? undefined);
731
+ if (!mapped)
732
+ return;
733
+ const transcriptFact = terminalTranscriptFact(event, context.turnId);
734
+ if (transcriptFact)
735
+ await persisted.persistence.critical.appendTranscriptCritical(transcriptFact);
736
+ if ((mapped.type === 'approval_required' || mapped.type === 'interaction_updated') && binding) {
737
+ persisted.persistence.interactionCheckpoint.save({
738
+ turnId: binding.turnId,
739
+ interaction: mapped.payload.interaction,
740
+ revision: binding.revision,
741
+ generation: binding.continuationGeneration,
742
+ });
743
+ }
744
+ await persisted.persistence.journal.append(mapped, {
745
+ durability: mapped.type === 'text_delta' || mapped.type === 'reasoning_delta' ? 'stream' : 'critical',
746
+ });
747
+ if (event.type === 'final' || event.type === 'error') {
748
+ const admission = admissions.find((candidate) => candidate.turnId === context.turnId);
749
+ if (admission && (admission.state === 'accepted' || admission.state === 'committed')) {
750
+ try {
751
+ this.#admissions?.markTerminal(persisted.record.ownerUserId, sessionId, admission.clientRequestId, event.type === 'final' ? 'accepted' : 'failed');
752
+ }
753
+ catch (error) {
754
+ if (!(error instanceof GatewayPersistenceError) || error.code !== 'not_found')
755
+ throw error;
756
+ }
757
+ }
758
+ }
759
+ });
760
+ }
761
+ #mapError(error) {
762
+ if (error instanceof WorkspaceAdmissionError) {
763
+ return publicError(error.code === 'workspace_session_exists' ? 409 : 403, error.code === 'workspace_session_exists' ? 'protocol_conflict' : 'workspace_forbidden', 'workspace access denied');
764
+ }
765
+ if (error instanceof GatewayPersistenceError) {
766
+ if (error.code === 'not_found' || error.code === 'owner_mismatch')
767
+ return publicError(404, 'not_found', 'session not found');
768
+ if (error.code === 'cursor_invalid')
769
+ return publicError(400, 'invalid_cursor', 'cursor is invalid');
770
+ if (error.code === 'conflict')
771
+ return publicError(409, 'idempotency_conflict', 'request conflicts with an existing admission');
772
+ return publicError(503, 'persistence_unavailable', 'gateway persistence unavailable', true);
773
+ }
774
+ if (error instanceof ServerSessionError) {
775
+ if (error.code === 'stale_interaction')
776
+ return publicError(409, 'stale_interaction', 'interaction is stale');
777
+ return publicError(409, 'session_not_admitting', 'session is not admitting');
778
+ }
779
+ return publicError(503, 'gateway_unavailable', 'gateway unavailable', true);
780
+ }
781
+ static create(config) {
782
+ let manifest;
783
+ try {
784
+ manifest = loadGatewayManifest(config.manifestPath, config.manifestSha256);
785
+ }
786
+ catch {
787
+ throw new GatewayStartupError();
788
+ }
789
+ assertGatewayStartup(config, manifest);
790
+ return new Term2Gateway(config, manifest);
791
+ }
792
+ get server() {
793
+ return this.#server;
794
+ }
795
+ get admission() {
796
+ return this.#admission;
797
+ }
798
+ get lifecycle() {
799
+ return this.#lifecycle;
800
+ }
801
+ get manifestVersion() {
802
+ return this.#manifest.version;
803
+ }
804
+ get interactionMetrics() {
805
+ return Object.freeze(Object.fromEntries(INTERACTION_METRICS.map((metric) => [metric, this.#interactionCounters.get(metric) ?? 0])));
806
+ }
807
+ async start() {
808
+ if (!this.#config.enabled)
809
+ return;
810
+ // Prove the audit path before binding the socket; a non-awaitable or
811
+ // failing writer must never leave a seemingly-ready gateway behind.
812
+ await this.#audit.write(createSafeLogMetadata({ operation: 'startup', outcome: 'allowed', reasonCode: 'accepted' }));
813
+ await this.#server.start();
814
+ }
815
+ async createSession(claims, options, correlationId) {
816
+ this.#lifecycle.assertAccepting();
817
+ if (!this.#config.enabled)
818
+ throw new GatewayStartupError();
819
+ const binding = this.#admission.admit(claims);
820
+ if (this.#config.runtimeFactory) {
821
+ let persisted;
822
+ try {
823
+ persisted = await this.#config.persistence?.open(binding);
824
+ const session = await this.#config.runtimeFactory.create(binding, {
825
+ eventSink: (event, context) => {
826
+ const persistence = this.#persistConversationEvent(binding.sessionId, event, context);
827
+ if (isCriticalRuntimeEvent(event))
828
+ return persistence;
829
+ // Streaming deltas remain observationally non-blocking, but their
830
+ // persistence failure must be consumed so it cannot become an
831
+ // unhandled rejection. A later critical event observes the
832
+ // journal's failure latch and is awaited by the runtime.
833
+ void persistence.catch(() => undefined);
834
+ return undefined;
835
+ },
836
+ });
837
+ if (persisted) {
838
+ this.#persisted.set(binding.sessionId, persisted);
839
+ session.addDisposeHook(async () => {
840
+ await persisted.persistence.close();
841
+ this.#persisted.delete(binding.sessionId);
842
+ this.#interactionBindings.delete(binding.sessionId);
843
+ await this.#config.persistence?.close(binding.sessionId, this.#shutdownInProgress ? 'interrupted' : 'closed');
844
+ });
845
+ }
846
+ const release = this.#lifecycle.registerWorker({ close: () => session.dispose() });
847
+ session.addDisposeHook(() => {
848
+ release();
849
+ this.#admission.remove(binding.sessionId);
850
+ this.#sessions.delete(binding.sessionId);
851
+ this.#persisted.delete(binding.sessionId);
852
+ this.#interactionBindings.delete(binding.sessionId);
853
+ });
854
+ this.#sessions.set(binding.sessionId, session);
855
+ await this.#audit.write(createSafeLogMetadata({
856
+ operation: 'session_create',
857
+ outcome: 'allowed',
858
+ reasonCode: 'accepted',
859
+ sessionId: binding.sessionId,
860
+ workspaceId: binding.workspaceId,
861
+ grantVersion: binding.grantVersion,
862
+ access: binding.access,
863
+ ...(correlationId ? { correlationId } : {}),
864
+ }));
865
+ return session;
866
+ }
867
+ catch (error) {
868
+ try {
869
+ await persisted?.persistence.close();
870
+ await this.#config.persistence?.close(binding.sessionId, 'interrupted');
871
+ }
872
+ catch {
873
+ // Preserve the admission failure; persistence keeps its evidence.
874
+ }
875
+ this.#admission.remove(binding.sessionId);
876
+ throw error;
877
+ }
878
+ }
879
+ const providerProbe = this.#config.providerProbe;
880
+ if (!providerProbe)
881
+ throw new GatewayStartupError();
882
+ const providerBroker = assertProviderBrokerReady(this.#config.providerBroker, providerProbe);
883
+ const session = composeGatewaySession({
884
+ binding,
885
+ providerBroker,
886
+ providerProbe,
887
+ tmpDir: options?.tmpDir ?? this.#config.tmpDir,
888
+ env: options?.env,
889
+ sandboxAvailable: options?.sandboxAvailable ?? this.#config.workerSandboxAvailable,
890
+ createRuntime: options?.createRuntime,
891
+ });
892
+ const release = this.#lifecycle.registerWorker({ close: () => session.dispose() });
893
+ const originalDispose = session.dispose;
894
+ session.dispose = () => {
895
+ release();
896
+ originalDispose();
897
+ this.#admission.remove(binding.sessionId);
898
+ this.#sessions.delete(binding.sessionId);
899
+ };
900
+ this.#sessions.set(binding.sessionId, session);
901
+ await this.#audit.write(createSafeLogMetadata({
902
+ operation: 'session_create',
903
+ outcome: 'allowed',
904
+ reasonCode: 'accepted',
905
+ sessionId: binding.sessionId,
906
+ workspaceId: binding.workspaceId,
907
+ grantVersion: binding.grantVersion,
908
+ access: binding.access,
909
+ ...(correlationId ? { correlationId } : {}),
910
+ }));
911
+ return session;
912
+ }
913
+ async shutdown(graceMs = 5_000) {
914
+ this.#shutdownInProgress = true;
915
+ await this.#server.shutdown(graceMs);
916
+ await Promise.all([...this.#sessions.values()].map((session) => Promise.resolve(session.dispose())));
917
+ this.#sessions.clear();
918
+ this.#replay.close();
919
+ await this.#audit.write(createSafeLogMetadata({ operation: 'shutdown', outcome: 'interrupted', reasonCode: 'shutdown' }));
920
+ }
921
+ }
922
+ function matchPrivateRoute(method, pathname) {
923
+ if (method === 'POST' && pathname === '/')
924
+ return { purpose: 'session_create', legacy: true };
925
+ // GET is canonical for workspace_list; POST is a tested compatibility alias for the pinned BFF wire.
926
+ if ((method === 'GET' || method === 'POST') && pathname === '/private/agent/v1/workspaces')
927
+ return { purpose: 'workspace_list' };
928
+ if (method === 'POST' && pathname === '/private/agent/v1/sessions')
929
+ return { purpose: 'session_create' };
930
+ if (method === 'GET' && pathname === '/private/agent/v1/sessions')
931
+ return { purpose: 'session_list' };
932
+ const match = pathname.match(/^\/private\/agent\/v1\/sessions\/([A-Za-z0-9_-]{1,256})(?:\/(messages|abort|events|interactions\/([A-Za-z0-9_-]{1,256})))?$/);
933
+ if (!match)
934
+ return null;
935
+ const sessionId = match[1];
936
+ if (method === 'POST' && !match[2])
937
+ return { purpose: 'session_read', sessionId };
938
+ if (method === 'POST' && match[2] === 'messages')
939
+ return { purpose: 'message_submit', sessionId };
940
+ if (method === 'POST' && match[2] === 'abort')
941
+ return { purpose: 'abort', sessionId };
942
+ if (method === 'GET' && match[2] === 'events')
943
+ return { purpose: 'events_connect', sessionId };
944
+ if (method === 'POST' && match[2]?.startsWith('interactions/'))
945
+ return { purpose: 'interaction_resolve', sessionId, interactionId: match[3] };
946
+ return null;
947
+ }
948
+ export function classifyInteractionResolution(interaction, hasLiveSnapshot) {
949
+ if (hasLiveSnapshot)
950
+ return null;
951
+ if (interaction?.state === 'recovered')
952
+ return 'interaction_not_resolvable';
953
+ return 'interaction_already_resolved';
954
+ }
955
+ function hasDeferredModelSelectionField(body) {
956
+ if (!body || typeof body !== 'object' || Array.isArray(body))
957
+ return false;
958
+ return Object.keys(body).some((key) => ['model', 'reasoningEffort', 'mode'].includes(key));
959
+ }
960
+ function isSessionCreateBody(body, workspaceId, legacy = false) {
961
+ if (legacy && body === null)
962
+ return true;
963
+ if (!body || typeof body !== 'object' || Array.isArray(body))
964
+ return false;
965
+ const keys = Object.keys(body);
966
+ if (keys.some((key) => key !== 'workspaceId'))
967
+ return false;
968
+ const requested = body.workspaceId;
969
+ return typeof requested === 'string' && requested === workspaceId;
970
+ }
971
+ function isOpaqueId(value) {
972
+ return typeof value === 'string' && /^[A-Za-z0-9_-]{1,256}$/.test(value);
973
+ }
974
+ function hasAttachments(body) {
975
+ if (!body || typeof body !== 'object' || Array.isArray(body))
976
+ return false;
977
+ return Object.keys(body).some((key) => ['images', 'attachments', 'attachmentIds'].includes(key));
978
+ }
979
+ function isMessageBody(body) {
980
+ if (!body || typeof body !== 'object' || Array.isArray(body))
981
+ return false;
982
+ const value = body;
983
+ return (Object.keys(value).every((key) => key === 'text' || key === 'clientRequestId') &&
984
+ typeof value.text === 'string' &&
985
+ value.text.length > 0 &&
986
+ value.text.length <= 128_000 &&
987
+ isOpaqueId(value.clientRequestId));
988
+ }
989
+ function isTurnBody(body) {
990
+ return (!!body &&
991
+ typeof body === 'object' &&
992
+ !Array.isArray(body) &&
993
+ Object.keys(body).length === 1 &&
994
+ isOpaqueId(body.turnId));
995
+ }
996
+ export function isInteractionResolveRequest(body) {
997
+ if (!body || typeof body !== 'object' || Array.isArray(body))
998
+ return false;
999
+ const value = body;
1000
+ return (Object.keys(value).every((key) => ['revision', 'answer', 'rejectionReason', 'approvalAnswer'].includes(key)) &&
1001
+ typeof value.revision === 'number' &&
1002
+ Number.isSafeInteger(value.revision) &&
1003
+ value.revision >= 1 &&
1004
+ typeof value.answer === 'string' &&
1005
+ value.answer.length <= 16_384 &&
1006
+ (value.rejectionReason === undefined || typeof value.rejectionReason === 'string') &&
1007
+ (value.approvalAnswer === undefined || typeof value.approvalAnswer === 'string'));
1008
+ }
1009
+ function parseQueryLimit(value) {
1010
+ if (value === null)
1011
+ return undefined;
1012
+ if (!/^[0-9]{1,3}$/.test(value))
1013
+ throw new GatewayPersistenceError('cursor_invalid', 'limit is invalid');
1014
+ return Number(value);
1015
+ }
1016
+ function parseEventCursor(value) {
1017
+ if (value === null)
1018
+ return { value: null };
1019
+ if (!/^(?:0|[1-9][0-9]{0,14})$/.test(value))
1020
+ return { value: null, error: 'cursor_invalid' };
1021
+ const parsed = Number(value);
1022
+ return Number.isSafeInteger(parsed) ? { value: parsed } : { value: null, error: 'cursor_invalid' };
1023
+ }
1024
+ function publicError(status, code, message, retryable, details) {
1025
+ return {
1026
+ status,
1027
+ body: {
1028
+ error: { code, message, ...(retryable === undefined ? {} : { retryable }), ...(details ? { details } : {}) },
1029
+ },
1030
+ };
1031
+ }
1032
+ function isPublicEventEnvelope(event) {
1033
+ if (event.schemaVersion !== 1 ||
1034
+ !Number.isSafeInteger(event.id) ||
1035
+ !isOpaqueId(event.sessionId) ||
1036
+ !FROZEN_AGENT_EVENT_TYPES.includes(event.type) ||
1037
+ typeof event.occurredAt !== 'string' ||
1038
+ !event.payload ||
1039
+ typeof event.payload !== 'object' ||
1040
+ Array.isArray(event.payload))
1041
+ return false;
1042
+ try {
1043
+ if (event.type === 'approval_required' ||
1044
+ event.type === 'interaction_updated' ||
1045
+ event.type === 'interaction_recovered') {
1046
+ if (!event.payload.interaction ||
1047
+ typeof event.payload.interaction !== 'object' ||
1048
+ !validatePendingInteractionDto(event.payload.interaction))
1049
+ return false;
1050
+ if (event.type === 'interaction_recovered' &&
1051
+ !['daemon_restart', 'forced_shutdown', 'persistence_recovery'].includes(String(event.payload.reason)))
1052
+ return false;
1053
+ }
1054
+ if (event.type === 'interaction_resolved') {
1055
+ const keys = Object.keys(event.payload).sort();
1056
+ if (keys.join(',') !== 'interactionId,outcome,turnId,variant')
1057
+ return false;
1058
+ if (!isOpaqueId(event.payload.interactionId) ||
1059
+ !['approved', 'rejected', 'cancelled', 'continued'].includes(String(event.payload.outcome)))
1060
+ return false;
1061
+ }
1062
+ }
1063
+ catch {
1064
+ return false;
1065
+ }
1066
+ const visit = (value, depth = 0) => {
1067
+ if (depth > 8)
1068
+ return false;
1069
+ if (value === null || typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean')
1070
+ return typeof value !== 'string' || value.length <= 32_000;
1071
+ if (Array.isArray(value))
1072
+ return value.length <= 512 && value.every((item) => visit(item, depth + 1));
1073
+ if (typeof value !== 'object')
1074
+ return false;
1075
+ return Object.entries(value).every(([key, child]) => PUBLIC_EVENT_PAYLOAD_KEYS.has(key) && visit(child, depth + 1));
1076
+ };
1077
+ return visit(event.payload);
1078
+ }
1079
+ function boundedText(value, max = 8_192) {
1080
+ return typeof value === 'string' ? value.slice(0, max) : '';
1081
+ }
1082
+ function interactionDtoFromApproval(approval, interactionId, revision) {
1083
+ return projectPendingInteraction(approval, interactionId, revision);
1084
+ }
1085
+ function interactionDtoFromSnapshot(snapshot, interactionId, revision) {
1086
+ return projectPendingInteraction(snapshot.approval, interactionId, revision, snapshot.askUserAnswers, snapshot.currentAskUserQuestionIndex);
1087
+ }
1088
+ function sanitizePublicInteraction(value) {
1089
+ return validatePendingInteractionDto(value);
1090
+ }
1091
+ const PROJECTION_COMMAND_STATUSES = new Set(['completed', 'failed', 'aborted', 'unknown']);
1092
+ function projectTranscriptMessages(transcript, journalCommands) {
1093
+ if (!transcript)
1094
+ return [];
1095
+ const commandsByTurn = new Map();
1096
+ const addCommand = (turnId, command) => {
1097
+ const commands = commandsByTurn.get(turnId) ?? [];
1098
+ if (!commands.some((candidate) => candidate.callId === command.callId))
1099
+ commands.push(command);
1100
+ commandsByTurn.set(turnId, commands.slice(0, 64));
1101
+ };
1102
+ for (const command of transcript.toolLedger) {
1103
+ if (!PROJECTION_COMMAND_STATUSES.has(command.status))
1104
+ continue;
1105
+ addCommand(command.turnId, {
1106
+ callId: boundedText(command.callId, 256),
1107
+ toolName: boundedText(command.toolName, 256),
1108
+ status: boundedText(command.status, 32),
1109
+ });
1110
+ }
1111
+ for (const [turnId, commands] of journalCommands) {
1112
+ for (const command of commands) {
1113
+ const existing = commandsByTurn.get(turnId)?.find((candidate) => candidate.callId === command.callId);
1114
+ if (existing) {
1115
+ const current = commandsByTurn.get(turnId);
1116
+ commandsByTurn.set(turnId, current.map((candidate) => (candidate.callId === command.callId ? command : candidate)));
1117
+ }
1118
+ else {
1119
+ addCommand(turnId, command);
1120
+ }
1121
+ }
1122
+ }
1123
+ const projected = [];
1124
+ let currentTurnId = null;
1125
+ const attachedTurns = new Set();
1126
+ for (const message of transcript.messages) {
1127
+ const record = message;
1128
+ const sender = typeof record.sender === 'string' ? record.sender : record.role;
1129
+ if (sender === 'user') {
1130
+ currentTurnId = typeof record.id === 'string' ? record.id : null;
1131
+ }
1132
+ if (sender === 'command' || sender === 'reasoning') {
1133
+ if (sender === 'command' &&
1134
+ currentTurnId &&
1135
+ typeof record.callId === 'string' &&
1136
+ typeof record.toolName === 'string' &&
1137
+ typeof record.status === 'string' &&
1138
+ !commandsByTurn.get(currentTurnId)?.some((command) => command.callId === record.callId)) {
1139
+ addCommand(currentTurnId, {
1140
+ callId: boundedText(record.callId, 256),
1141
+ toolName: boundedText(record.toolName, 256),
1142
+ status: boundedText(record.status, 32),
1143
+ });
1144
+ }
1145
+ continue;
1146
+ }
1147
+ const role = sender === 'user' ? 'user' : 'bot';
1148
+ const projectedMessage = {
1149
+ id: boundedText(record.id, 256),
1150
+ role,
1151
+ text: boundedText(record.text, 16_384),
1152
+ };
1153
+ const commands = role === 'bot' && currentTurnId ? commandsByTurn.get(currentTurnId) : undefined;
1154
+ if (commands && commands.length > 0 && !attachedTurns.has(currentTurnId)) {
1155
+ projectedMessage.commands = commands;
1156
+ attachedTurns.add(currentTurnId);
1157
+ }
1158
+ projected.push(projectedMessage);
1159
+ }
1160
+ return projected.slice(-200);
1161
+ }
1162
+ /**
1163
+ * Session transcript wire shape: messages have `id`, `role` (`user` or `bot`),
1164
+ * and bounded `text`. A completed turn's first bot message may carry a bounded
1165
+ * `commands` array of `{callId, toolName, status}` entries for its tool cards.
1166
+ */
1167
+ function toSessionProjection(source) {
1168
+ const transcript = source.transcript;
1169
+ const messages = projectTranscriptMessages(transcript, source.journalCommands);
1170
+ const interaction = source.interaction
1171
+ ? {
1172
+ ...source.interaction,
1173
+ interaction: sanitizePublicInteraction(source.interaction.interaction),
1174
+ }
1175
+ : null;
1176
+ return {
1177
+ id: source.session.id,
1178
+ workspaceId: source.session.workspaceId,
1179
+ status: source.session.status === 'initializing' ? 'idle' : source.session.status,
1180
+ createdAt: source.session.createdAt,
1181
+ updatedAt: source.session.updatedAt,
1182
+ latestSequence: source.latestSequence,
1183
+ earliestReplayableSequence: source.earliestReplayableSequence,
1184
+ projectionSequence: source.projectionSequence,
1185
+ transcript: { messages, ...(transcript?.updatedAt ? { updatedAt: transcript.updatedAt } : {}) },
1186
+ interaction,
1187
+ };
1188
+ }
1189
+ // Terminal runtime final/error events have two durable representations: the
1190
+ // public journal and the replay transcript. Aborts intentionally settle only
1191
+ // the journal so replay retains interruption semantics.
1192
+ function hasTerminalTurnEvent(events, turnId) {
1193
+ return events.some((event) => TERMINAL_AGENT_EVENT_TYPES.has(event.type) && event.payload.turnId === turnId);
1194
+ }
1195
+ function terminalTranscriptFact(event, turnId) {
1196
+ if (event.type === 'final') {
1197
+ const items = event.turnItems ? [...event.turnItems] : [];
1198
+ if (!items.some((item) => item.type === 'assistant_text')) {
1199
+ items.push({ type: 'assistant_text', text: boundedText(event.finalText, 16_384) });
1200
+ }
1201
+ return { type: 'assistant_turn', turnId, turn: { items } };
1202
+ }
1203
+ if (event.type === 'error') {
1204
+ return {
1205
+ type: 'assistant_turn',
1206
+ turnId,
1207
+ turn: { items: [{ type: 'assistant_text', text: boundedText(event.finalText ?? event.message, 16_384) }] },
1208
+ };
1209
+ }
1210
+ return null;
1211
+ }
1212
+ function mapConversationEvent(event, turnId, sessionId, interactionBinding, interactionSnapshot) {
1213
+ const base = { sessionId, payload: { turnId } };
1214
+ switch (event.type) {
1215
+ // The gateway-owned assistant_started admission marker is appended before
1216
+ // runtime commit in #submitMessage. ConversationEvent still has no provider
1217
+ // first-token signal, so this mapper never invents one from a delta.
1218
+ case 'text_delta':
1219
+ return { ...base, type: 'text_delta', payload: { turnId, delta: boundedText(event.delta) } };
1220
+ case 'reasoning_delta':
1221
+ return { ...base, type: 'reasoning_delta', payload: { turnId, delta: boundedText(event.delta) } };
1222
+ case 'tool_started':
1223
+ return {
1224
+ ...base,
1225
+ type: 'tool_started',
1226
+ payload: { turnId, callId: event.toolCallId, toolName: boundedText(event.toolName, 256) },
1227
+ };
1228
+ case 'command_message':
1229
+ return {
1230
+ ...base,
1231
+ type: 'command_message',
1232
+ payload: {
1233
+ turnId,
1234
+ message: {
1235
+ id: boundedText(event.message.id, 256),
1236
+ role: boundedText(event.message.sender ?? event.message.role, 32),
1237
+ text: boundedText(event.message.text, 16_384),
1238
+ },
1239
+ },
1240
+ };
1241
+ case 'approval_required': {
1242
+ if (!interactionBinding)
1243
+ return null;
1244
+ return {
1245
+ ...base,
1246
+ type: 'approval_required',
1247
+ payload: {
1248
+ turnId,
1249
+ interaction: interactionSnapshot
1250
+ ? interactionDtoFromSnapshot(interactionSnapshot, interactionBinding.publicInteractionId, interactionBinding.revision)
1251
+ : interactionDtoFromApproval(event.approval, interactionBinding.publicInteractionId, interactionBinding.revision),
1252
+ },
1253
+ };
1254
+ }
1255
+ case 'usage_update':
1256
+ return {
1257
+ ...base,
1258
+ type: 'usage_update',
1259
+ payload: {
1260
+ turnId,
1261
+ usage: { inputTokens: event.usage.prompt_tokens, outputTokens: event.usage.completion_tokens },
1262
+ },
1263
+ };
1264
+ case 'final':
1265
+ return {
1266
+ ...base,
1267
+ type: 'turn_completed',
1268
+ payload: { turnId, outcome: 'completed', text: boundedText(event.finalText, 16_384) },
1269
+ };
1270
+ case 'error':
1271
+ return { ...base, type: 'turn_failed', payload: { turnId, outcome: 'failed', reason: 'runtime_error' } };
1272
+ default:
1273
+ return null;
1274
+ }
1275
+ }
1276
+ export { createGatewayAssertion, interactionDtoFromSnapshot, isPublicEventEnvelope };
1277
+ //# sourceMappingURL=gateway.js.map