@ai-matrx/chat 0.4.0 → 0.4.7

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 (226) hide show
  1. package/CHANGELOG.md +80 -0
  2. package/dist/agent-copy/RichCopySplit.d.ts +17 -0
  3. package/dist/agent-copy/RichCopySplit.js +34 -0
  4. package/dist/agents/addressing/useAgentHref.js +4 -1
  5. package/dist/agents/api/submit-tool-results.js +11 -1
  6. package/dist/agents/components/agent-widgets/chat-assistant/AssistantMessageCard.js +1 -1
  7. package/dist/agents/components/chat/ConversationRecordsChip.js +1 -1
  8. package/dist/agents/components/chat/useCanvasScopedToConversation.js +1 -1
  9. package/dist/agents/components/context-items/bodies/WorkingDocumentBody.d.ts +5 -2
  10. package/dist/agents/components/context-items/bodies/WorkingDocumentBody.js +6 -1
  11. package/dist/agents/components/context-policies-display/ContextValueBody.js +1 -1
  12. package/dist/agents/components/context-preview/ContextCompareView.js +1 -1
  13. package/dist/agents/components/custom-agent/CustomAgentWindow.js +1 -1
  14. package/dist/agents/components/inputs/smart-input/AgentTextarea.d.ts +6 -1
  15. package/dist/agents/components/inputs/smart-input/AgentTextarea.js +2 -2
  16. package/dist/agents/components/inputs/smart-input/ComposerToolsNotice.d.ts +1 -0
  17. package/dist/agents/components/inputs/smart-input/ComposerToolsNotice.js +5 -0
  18. package/dist/agents/components/inputs/smart-input/ConversationContextRail.d.ts +5 -1
  19. package/dist/agents/components/inputs/smart-input/ConversationContextRail.js +6 -1
  20. package/dist/agents/components/inputs/smart-input/InboxQueueStrip.d.ts +6 -1
  21. package/dist/agents/components/inputs/smart-input/InboxQueueStrip.js +6 -1
  22. package/dist/agents/components/inputs/smart-input/InputActionButtons.js +8 -6
  23. package/dist/agents/components/inputs/smart-input/SmartInputFileDropTarget.d.ts +5 -1
  24. package/dist/agents/components/inputs/smart-input/SmartInputFileDropTarget.js +8 -1
  25. package/dist/agents/components/inputs/smart-input/composer/ComposerAgentPill.js +2 -2
  26. package/dist/agents/components/inputs/smart-input/composer/ComposerChipsRow.d.ts +5 -2
  27. package/dist/agents/components/inputs/smart-input/composer/ComposerChipsRow.js +6 -1
  28. package/dist/agents/components/inputs/smart-input/composer/ComposerMetaRow.d.ts +6 -8
  29. package/dist/agents/components/inputs/smart-input/composer/ComposerMetaRow.js +13 -1
  30. package/dist/agents/components/inputs/smart-input/composer/useOutputShapeCatalog.d.ts +1 -1
  31. package/dist/agents/components/inputs/smart-input/composer/useOutputShapeCatalog.js +1 -1
  32. package/dist/agents/components/live-run/LiveRunDisplay.js +1 -1
  33. package/dist/agents/components/live-run/RunSetDisplay.js +1 -1
  34. package/dist/agents/components/memory/components/AgentMemoryAllView.js +1 -1
  35. package/dist/agents/components/messages-display/AgentConversationDisplay.js +4 -1
  36. package/dist/agents/components/messages-display/assistant/AgentAssistantMessage.d.ts +1 -0
  37. package/dist/agents/components/messages-display/assistant/AgentAssistantMessage.js +4 -3
  38. package/dist/agents/components/messages-display/assistant/AgentEmptyMessageDisplay.js +1 -1
  39. package/dist/agents/components/messages-display/assistant/AssistantMessageFooter.d.ts +2 -2
  40. package/dist/agents/components/messages-display/assistant/AssistantMessageFooter.js +4 -7
  41. package/dist/agents/components/messages-display/assistant/InPlaceAnswerEditor.js +2 -2
  42. package/dist/agents/components/messages-display/citations/MessageSourcesRow.js +1 -1
  43. package/dist/agents/components/messages-display/rich-document/chat-message-source.d.ts +2 -0
  44. package/dist/agents/components/messages-display/rich-document/chat-message-source.js +41 -0
  45. package/dist/agents/components/messages-display/rich-document/chatMessageActions.d.ts +31 -0
  46. package/dist/agents/components/messages-display/rich-document/chatMessageActions.js +39 -0
  47. package/dist/agents/components/messages-display/user/AgentUserMessage.d.ts +1 -0
  48. package/dist/agents/components/messages-display/user/AgentUserMessage.js +7 -4
  49. package/dist/agents/components/messages-display/user/CollabNoteMessage.js +1 -1
  50. package/dist/agents/components/messages-display/user/UserActionBar.js +49 -39
  51. package/dist/agents/components/run-controls/panels/shared.d.ts +1 -0
  52. package/dist/agents/components/shared/AgentConversationColumn.js +3 -2
  53. package/dist/agents/components/working-document/WorkingDocumentEditor.d.ts +1 -1
  54. package/dist/agents/components/working-document/WorkingDocumentPanel.js +2 -1
  55. package/dist/agents/components/working-document/workingDocumentSurface.d.ts +1 -1
  56. package/dist/agents/identity/model-catalog.js +5 -3
  57. package/dist/agents/identity/run-tier-store.js +3 -0
  58. package/dist/agents/redux/agent-definition/cache-bust-middleware.js +2 -0
  59. package/dist/agents/redux/agent-definition/selectors.d.ts +237 -0
  60. package/dist/agents/redux/agent-settings/agentSettingsSlice.d.ts +0 -4
  61. package/dist/agents/redux/agent-settings/agentSettingsSlice.js +12 -5
  62. package/dist/agents/redux/agent-settings/selectors.d.ts +12 -0
  63. package/dist/agents/redux/agent-shortcut-categories/selectors.d.ts +50 -0
  64. package/dist/agents/redux/agent-shortcuts/selectors.d.ts +147 -0
  65. package/dist/agents/redux/conversation-history/selectors.d.ts +16 -0
  66. package/dist/agents/redux/conversation-list/conversation-list.selectors.d.ts +2 -0
  67. package/dist/agents/redux/execution-system/active-requests/active-requests.selectors.d.ts +54 -0
  68. package/dist/agents/redux/execution-system/context-state/context-state.selectors.d.ts +14 -0
  69. package/dist/agents/redux/execution-system/conversations/conversations.selectors.d.ts +5 -0
  70. package/dist/agents/redux/execution-system/host-conversations/conversation-abilities.d.ts +12 -0
  71. package/dist/agents/redux/execution-system/host-conversations/conversation-abilities.js +25 -0
  72. package/dist/agents/redux/execution-system/host-conversations/host-conversation.thunks.d.ts +53 -0
  73. package/dist/agents/redux/execution-system/host-conversations/host-conversation.thunks.js +412 -0
  74. package/dist/agents/redux/execution-system/host-conversations/host-conversations.selectors.d.ts +28 -0
  75. package/dist/agents/redux/execution-system/host-conversations/host-conversations.selectors.js +41 -0
  76. package/dist/agents/redux/execution-system/host-conversations/host-conversations.slice.d.ts +43 -0
  77. package/dist/agents/redux/execution-system/host-conversations/host-conversations.slice.js +38 -0
  78. package/dist/agents/redux/execution-system/host-conversations/source-registry.d.ts +9 -0
  79. package/dist/agents/redux/execution-system/host-conversations/source-registry.js +15 -0
  80. package/dist/agents/redux/execution-system/host-conversations/useHostConversation.d.ts +4 -0
  81. package/dist/agents/redux/execution-system/host-conversations/useHostConversation.js +24 -0
  82. package/dist/agents/redux/execution-system/inbox/inbox-turn-end.middleware.js +2 -1
  83. package/dist/agents/redux/execution-system/instance-context/instance-context.selectors.d.ts +3 -0
  84. package/dist/agents/redux/execution-system/instance-resources/default-remark-durability.d.ts +22 -0
  85. package/dist/agents/redux/execution-system/instance-resources/default-remark-durability.js +164 -0
  86. package/dist/agents/redux/execution-system/instance-resources/instance-resources.selectors.d.ts +8 -0
  87. package/dist/agents/redux/execution-system/instance-ui-state/instance-ui-state.selectors.d.ts +5 -0
  88. package/dist/agents/redux/execution-system/instance-ui-state/run-configuration-persist.js +2 -0
  89. package/dist/agents/redux/execution-system/instance-user-input/composer-draft-store.js +20 -0
  90. package/dist/agents/redux/execution-system/instance-user-input/useComposerDraftRestore.js +2 -1
  91. package/dist/agents/redux/execution-system/instance-variable-values/instance-variable-values.selectors.d.ts +7 -0
  92. package/dist/agents/redux/execution-system/messages/messages.selectors.d.ts +1 -0
  93. package/dist/agents/redux/execution-system/messages/messages.selectors.js +1 -1
  94. package/dist/agents/redux/execution-system/observability/observability.selectors.d.ts +7 -0
  95. package/dist/agents/redux/execution-system/observational-memory/observational-memory.selectors.d.ts +1 -0
  96. package/dist/agents/redux/execution-system/selectors/aggregate.selectors.d.ts +14 -0
  97. package/dist/agents/redux/execution-system/thunks/execute-instance.thunk.js +8 -1
  98. package/dist/agents/redux/execution-system/thunks/execute-manual-instance.thunk.js +2 -1
  99. package/dist/agents/redux/execution-system/thunks/load-conversation.thunk.js +6 -0
  100. package/dist/agents/redux/execution-system/thunks/load-older-messages.thunk.js +12 -0
  101. package/dist/agents/redux/execution-system/thunks/process-stream.js +6 -4
  102. package/dist/agents/redux/execution-system/thunks/resolve-base-url.js +1 -1
  103. package/dist/agents/redux/execution-system/thunks/smart-execute.thunk.js +43 -0
  104. package/dist/agents/redux/execution-system/utils/assemble-cx-content-blocks.js +2 -1
  105. package/dist/agents/redux/execution-system/utils/continuation-body.d.ts +1 -0
  106. package/dist/agents/redux/execution-system/utils/continuation-body.js +2 -1
  107. package/dist/agents/redux/execution-system/utils/inbound-render-block.d.ts +8 -0
  108. package/dist/agents/redux/execution-system/utils/inbound-render-block.js +17 -2
  109. package/dist/agents/redux/execution-system/utils/normalize-content-blocks.js +1 -1
  110. package/dist/agents/redux/execution-system/utils/progress-data-block.d.ts +11 -0
  111. package/dist/agents/redux/execution-system/utils/progress-data-block.js +37 -0
  112. package/dist/agents/redux/execution-system/utils/stream-block-accumulator.js +10 -8
  113. package/dist/agents/redux/mcp/mcp.slice.js +15 -7
  114. package/dist/agents/redux/proposed-directives/proposedDirectivesSlice.d.ts +1 -0
  115. package/dist/agents/redux/tools/tools.selectors.d.ts +1 -0
  116. package/dist/agents/redux/tools/tools.thunks.js +3 -0
  117. package/dist/agents/resources/default-picker-items.d.ts +17 -0
  118. package/dist/agents/resources/default-picker-items.js +48 -0
  119. package/dist/agents/runtime-reconnect/ServerOperationBanner.d.ts +6 -1
  120. package/dist/agents/runtime-reconnect/ServerOperationBanner.js +6 -1
  121. package/dist/agents/types/instance.types.d.ts +2 -1
  122. package/dist/agents/ui-first-tools/redux/agent-lists.selectors.d.ts +2 -0
  123. package/dist/agents/ui-first-tools/ui/ApprovalCard.js +1 -1
  124. package/dist/agents/ui-first-tools/ui/AskCard.js +1 -1
  125. package/dist/agents/ui-first-tools/ui/lists/TaskPanel.js +1 -1
  126. package/dist/conversation/hooks/useDomCapturePrint.js +1 -1
  127. package/dist/conversation/utils/markdown-print.js +1 -1
  128. package/dist/cx-chat/components/SsrSidebarChats.js +1 -1
  129. package/dist/cx-chat/components/messages/AssistantMessage.js +3 -5
  130. package/dist/cx-chat/components/sidebar/SidebarUserFooter.js +1 -1
  131. package/dist/cx-conversation/AssistantMessage.js +3 -5
  132. package/dist/host/app-data-slots.d.ts +85 -0
  133. package/dist/host/app-data-slots.js +42 -0
  134. package/dist/host/app-identity.d.ts +20 -0
  135. package/dist/host/app-identity.js +21 -0
  136. package/dist/host/bare-host-chrome.d.ts +14 -0
  137. package/dist/host/bare-host-chrome.js +45 -0
  138. package/dist/host/configure.d.ts +9 -1
  139. package/dist/host/configure.js +44 -8
  140. package/dist/host/contract.d.ts +39 -2
  141. package/dist/host/db-types.d.ts +99 -1
  142. package/dist/host/defaults/navigation-hooks.d.ts +2 -0
  143. package/dist/host/defaults/navigation-hooks.js +7 -1
  144. package/dist/host/defaults/navigation.d.ts +4 -3
  145. package/dist/host/defaults/navigation.js +38 -7
  146. package/dist/host/defaults/org.d.ts +12 -4
  147. package/dist/host/defaults/org.js +39 -1
  148. package/dist/host/defaults/prefs.d.ts +11 -0
  149. package/dist/host/defaults/prefs.js +43 -0
  150. package/dist/host/defaults/workspace-gate.d.ts +16 -0
  151. package/dist/host/defaults/workspace-gate.js +89 -0
  152. package/dist/host/diagnostics.d.ts +7 -2
  153. package/dist/host/diagnostics.js +6 -0
  154. package/dist/host/identity.js +2 -1
  155. package/dist/host/index.d.ts +6 -3
  156. package/dist/host/index.js +23 -2
  157. package/dist/host/no-database.d.ts +38 -0
  158. package/dist/host/no-database.js +107 -0
  159. package/dist/host/react.d.ts +1 -0
  160. package/dist/host/react.js +40 -2
  161. package/dist/host/registered-source.js +2 -2
  162. package/dist/host/source.d.ts +130 -0
  163. package/dist/host/source.js +86 -0
  164. package/dist/host/ui-slots.d.ts +9 -31
  165. package/dist/host/ui-slots.js +5 -37
  166. package/dist/mandates/useMandate.js +13 -0
  167. package/dist/public-chat/components/PublicMessageOptionsMenu.js +3 -2
  168. package/dist/store/create-chat-store.d.ts +4 -2
  169. package/dist/store/middlewares.d.ts +5 -0
  170. package/dist/store/slices.d.ts +1 -0
  171. package/dist/store/slices.js +4 -1
  172. package/dist/surfaces/redux/selectors.d.ts +2 -0
  173. package/dist/surfaces/redux/surfaceConfigSlice.js +2 -0
  174. package/dist/surfaces/redux/userStateSlice.js +3 -1
  175. package/dist/surfaces/runtime/agent-offer.js +1 -1
  176. package/dist/surfaces/runtime/surface-writeback.js +1 -1
  177. package/dist/testing/turn-harness.d.ts +35 -0
  178. package/dist/testing/turn-harness.js +85 -0
  179. package/dist/tool-call-visualization/db-renderer/fetchToolRendererRow.js +2 -0
  180. package/dist/tool-call-visualization/redux/selectors.d.ts +1 -0
  181. package/dist/tool-call-visualization/renderers/agent-call/AgentCallInline.js +1 -1
  182. package/dist/tool-call-visualization/renderers/agent-call/CollabCallCard.js +1 -1
  183. package/dist/tool-call-visualization/renderers/fs/FsInline.js +1 -1
  184. package/dist/tool-call-visualization/renderers/random-wheel/RandomWheelInline.js +1 -1
  185. package/dist/tool-call-visualization/renderers/research/ResearchOverlay.js +4 -4
  186. package/dist/tool-call-visualization/renderers/research/SubagentReportBlock.js +2 -2
  187. package/dist/tool-call-visualization/renderers/scrape/ScrapeOverlay.js +1 -1
  188. package/dist/tool-call-visualization/renderers/search/SearchInline.js +1 -1
  189. package/dist/tool-call-visualization/renderers/search/SearchOverlay.js +1 -1
  190. package/dist/tool-call-visualization/renderers/sql/SqlInline.js +1 -1
  191. package/dist/tool-call-visualization/result-fields/KeyValueGrid.js +1 -1
  192. package/dist/tool-call-visualization/result-fields/ResultMarkdown.js +1 -1
  193. package/dist/tool-call-visualization/result-fields/ResultValue.js +1 -1
  194. package/dist/tool-call-visualization/surface-write/SurfaceWriteDiff.js +1 -1
  195. package/dist/ui/AudioOutputBlockSkeleton.d.ts +17 -0
  196. package/dist/ui/AudioOutputBlockSkeleton.js +78 -0
  197. package/dist/ui/chat-protocol-from-stream.d.ts +60 -0
  198. package/dist/ui/chat-protocol-from-stream.js +135 -0
  199. package/dist/ui/markdown-stream/EnhancedChatMarkdown.d.ts +59 -0
  200. package/dist/ui/markdown-stream/EnhancedChatMarkdown.js +1108 -0
  201. package/dist/ui/markdown-stream/MarkdownStream.d.ts +88 -0
  202. package/dist/ui/markdown-stream/MarkdownStream.js +14 -0
  203. package/dist/ui/markdown-stream/MarkdownStreamImpl.d.ts +4 -0
  204. package/dist/ui/markdown-stream/MarkdownStreamImpl.js +86 -0
  205. package/dist/ui/markdown-stream/StreamAwareChatMarkdown.d.ts +58 -0
  206. package/dist/ui/markdown-stream/StreamAwareChatMarkdown.js +294 -0
  207. package/dist/ui/markdown-stream/internal-handlers/AgentCallChildTrace.d.ts +22 -0
  208. package/dist/ui/markdown-stream/internal-handlers/AgentCallChildTrace.js +128 -0
  209. package/dist/ui/markdown-stream/internal-handlers/InlineAssistantError.d.ts +3 -0
  210. package/dist/ui/markdown-stream/internal-handlers/InlineAssistantError.js +26 -0
  211. package/dist/ui/markdown-stream/internal-handlers/InlineThinkingSlot.d.ts +14 -0
  212. package/dist/ui/markdown-stream/internal-handlers/InlineThinkingSlot.js +23 -0
  213. package/dist/ui/markdown-stream/internal-handlers/ToolHandlers.d.ts +42 -0
  214. package/dist/ui/markdown-stream/internal-handlers/ToolHandlers.js +109 -0
  215. package/dist/ui/markdown-stream/useBoundAgentOutputSchema.d.ts +2 -0
  216. package/dist/ui/markdown-stream/useBoundAgentOutputSchema.js +33 -0
  217. package/dist/window-panels/windows/agents/AgentAssistantMarkdownDebugWindow.js +1 -1
  218. package/package.json +10 -5
  219. package/dist/host/content-ir-slots.d.ts +0 -231
  220. package/dist/host/content-ir-slots.js +0 -131
  221. package/dist/host/markdown-slots.d.ts +0 -53
  222. package/dist/host/markdown-slots.js +0 -32
  223. package/dist/host/rich-document-slots.d.ts +0 -123
  224. package/dist/host/rich-document-slots.js +0 -36
  225. package/dist/utils/content-ir/report-kind-at-raw-renderer.d.ts +0 -19
  226. package/dist/utils/content-ir/report-kind-at-raw-renderer.js +0 -32
@@ -52,6 +52,7 @@ export declare const selectContextState: (conversationId: string) => ((state: {
52
52
  agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
53
53
  conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
54
54
  chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
55
+ hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
55
56
  } & import("../../../../store/root-state.js").ChatHostReadSlices) => ContextStateEntry | null) & {
56
57
  clearCache: () => void;
57
58
  resultsCount: () => number;
@@ -122,6 +123,7 @@ export declare const selectEstimatedTokens: (conversationId: string) => ((state:
122
123
  agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
123
124
  conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
124
125
  chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
126
+ hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
125
127
  } & import("../../../../store/root-state.js").ChatHostReadSlices) => number) & {
126
128
  clearCache: () => void;
127
129
  resultsCount: () => number;
@@ -177,6 +179,7 @@ export declare const selectEstimatedTokens: (conversationId: string) => ((state:
177
179
  agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
178
180
  conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
179
181
  chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
182
+ hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
180
183
  } & import("../../../../store/root-state.js").ChatHostReadSlices) => ContextStateEntry | null) & {
181
184
  clearCache: () => void;
182
185
  resultsCount: () => number;
@@ -253,6 +256,7 @@ export declare const selectContextFillRatio: (conversationId: string, windowToke
253
256
  agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
254
257
  conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
255
258
  chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
259
+ hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
256
260
  } & import("../../../../store/root-state.js").ChatHostReadSlices) => number) & {
257
261
  clearCache: () => void;
258
262
  resultsCount: () => number;
@@ -308,6 +312,7 @@ export declare const selectContextFillRatio: (conversationId: string, windowToke
308
312
  agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
309
313
  conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
310
314
  chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
315
+ hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
311
316
  } & import("../../../../store/root-state.js").ChatHostReadSlices) => number) & {
312
317
  clearCache: () => void;
313
318
  resultsCount: () => number;
@@ -363,6 +368,7 @@ export declare const selectContextFillRatio: (conversationId: string, windowToke
363
368
  agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
364
369
  conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
365
370
  chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
371
+ hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
366
372
  } & import("../../../../store/root-state.js").ChatHostReadSlices) => ContextStateEntry | null) & {
367
373
  clearCache: () => void;
368
374
  resultsCount: () => number;
@@ -444,6 +450,7 @@ export declare const selectCacheLikelyAlive: (conversationId: string) => ((state
444
450
  agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
445
451
  conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
446
452
  chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
453
+ hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
447
454
  } & import("../../../../store/root-state.js").ChatHostReadSlices) => boolean) & {
448
455
  clearCache: () => void;
449
456
  resultsCount: () => number;
@@ -499,6 +506,7 @@ export declare const selectCacheLikelyAlive: (conversationId: string) => ((state
499
506
  agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
500
507
  conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
501
508
  chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
509
+ hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
502
510
  } & import("../../../../store/root-state.js").ChatHostReadSlices) => ContextStateEntry | null) & {
503
511
  clearCache: () => void;
504
512
  resultsCount: () => number;
@@ -572,6 +580,7 @@ export declare const selectCacheSecondsRemaining: (conversationId: string) => ((
572
580
  agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
573
581
  conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
574
582
  chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
583
+ hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
575
584
  } & import("../../../../store/root-state.js").ChatHostReadSlices) => number) & {
576
585
  clearCache: () => void;
577
586
  resultsCount: () => number;
@@ -627,6 +636,7 @@ export declare const selectCacheSecondsRemaining: (conversationId: string) => ((
627
636
  agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
628
637
  conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
629
638
  chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
639
+ hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
630
640
  } & import("../../../../store/root-state.js").ChatHostReadSlices) => ContextStateEntry | null) & {
631
641
  clearCache: () => void;
632
642
  resultsCount: () => number;
@@ -699,6 +709,7 @@ export declare const selectLastTrimSummary: (conversationId: string) => ((state:
699
709
  agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
700
710
  conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
701
711
  chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
712
+ hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
702
713
  } & import("../../../../store/root-state.js").ChatHostReadSlices) => import("./context-state.slice.js").TrimSummary | null) & {
703
714
  clearCache: () => void;
704
715
  resultsCount: () => number;
@@ -754,6 +765,7 @@ export declare const selectLastTrimSummary: (conversationId: string) => ((state:
754
765
  agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
755
766
  conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
756
767
  chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
768
+ hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
757
769
  } & import("../../../../store/root-state.js").ChatHostReadSlices) => ContextStateEntry | null) & {
758
770
  clearCache: () => void;
759
771
  resultsCount: () => number;
@@ -826,6 +838,7 @@ export declare const selectLastRawUsage: (conversationId: string) => ((state: {
826
838
  agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
827
839
  conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
828
840
  chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
841
+ hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
829
842
  } & import("../../../../store/root-state.js").ChatHostReadSlices) => Record<string, unknown> | null) & {
830
843
  clearCache: () => void;
831
844
  resultsCount: () => number;
@@ -881,6 +894,7 @@ export declare const selectLastRawUsage: (conversationId: string) => ((state: {
881
894
  agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
882
895
  conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
883
896
  chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
897
+ hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
884
898
  } & import("../../../../store/root-state.js").ChatHostReadSlices) => ContextStateEntry | null) & {
885
899
  clearCache: () => void;
886
900
  resultsCount: () => number;
@@ -49,6 +49,7 @@ export declare const selectConversationIdsByAgent: ((state: {
49
49
  agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
50
50
  conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
51
51
  chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
52
+ hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
52
53
  } & import("../../../../store/root-state.js").ChatHostReadSlices) => Record<string, string[]>) & {
53
54
  clearCache: () => void;
54
55
  resultsCount: () => number;
@@ -113,6 +114,7 @@ export declare const selectInstancesByAgent: (agentId: string) => ((state: {
113
114
  agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
114
115
  conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
115
116
  chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
117
+ hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
116
118
  } & import("../../../../store/root-state.js").ChatHostReadSlices) => ExecutionInstance[]) & {
117
119
  clearCache: () => void;
118
120
  resultsCount: () => number;
@@ -182,6 +184,7 @@ export declare const selectConversationSurfaceOwnsOutput: ((state: {
182
184
  agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
183
185
  conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
184
186
  chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
187
+ hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
185
188
  } & import("../../../../store/root-state.js").ChatHostReadSlices, conversationId: string | null | undefined) => boolean) & {
186
189
  clearCache: () => void;
187
190
  resultsCount: () => number;
@@ -247,6 +250,7 @@ export declare const selectRunningInstances: ((state: {
247
250
  agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
248
251
  conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
249
252
  chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
253
+ hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
250
254
  } & import("../../../../store/root-state.js").ChatHostReadSlices) => ExecutionInstance[]) & {
251
255
  clearCache: () => void;
252
256
  resultsCount: () => number;
@@ -340,6 +344,7 @@ export declare const selectConversationScopeIds: (conversationId: string) => ((s
340
344
  agentSettings: import("../../agent-settings/types.js").AgentSettingsState;
341
345
  conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
342
346
  chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
347
+ hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
343
348
  } & import("../../../../store/root-state.js").ChatHostReadSlices) => {
344
349
  organizationId: string | null;
345
350
  projectId: string | null;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * The conversation's abilities, provided ONCE by `AgentConversationColumn` (HOST-OWNED-SOURCE-PLAN
3
+ * §2.3). Every database-backed control reads `useConversationAbilities()` and is ABSENT when the
4
+ * ability is false — never a dead button. Outside a column: a database-backed conversation.
5
+ */
6
+ import { type ReactNode } from "react";
7
+ import { type ConversationAbilities } from "./host-conversations.selectors.js";
8
+ export declare function ConversationAbilitiesProvider({ conversationId, children, }: {
9
+ conversationId: string;
10
+ children?: ReactNode;
11
+ }): import("react").JSX.Element;
12
+ export declare function useConversationAbilities(): ConversationAbilities;
@@ -0,0 +1,25 @@
1
+ "use client";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { createContext, useContext } from "react";
4
+ import { useAppSelector } from "../../../../store/hooks.js";
5
+ import {
6
+ FULL_CONVERSATION_ABILITIES,
7
+ selectConversationAbilities
8
+ } from "./host-conversations.selectors.js";
9
+ const ConversationAbilitiesContext = createContext(
10
+ FULL_CONVERSATION_ABILITIES
11
+ );
12
+ function ConversationAbilitiesProvider({
13
+ conversationId,
14
+ children
15
+ }) {
16
+ const abilities = useAppSelector(selectConversationAbilities(conversationId));
17
+ return /* @__PURE__ */ jsx(ConversationAbilitiesContext.Provider, { value: abilities, children });
18
+ }
19
+ function useConversationAbilities() {
20
+ return useContext(ConversationAbilitiesContext);
21
+ }
22
+ export {
23
+ ConversationAbilitiesProvider,
24
+ useConversationAbilities
25
+ };
@@ -0,0 +1,53 @@
1
+ /**
2
+ * The engine half of a host-owned conversation (HOST-OWNED-SOURCE-PLAN §2.3, P28b).
3
+ *
4
+ * ONE store, ONE stream parser, ONE renderer serve both kinds of conversation:
5
+ * - binding creates the same instance every conversation has (`createInstanceFull`, endpoint
6
+ * mode "host"), registers the source, and hydrates its history through `hydrateMessages`;
7
+ * - every live turn — sent here or started by the host — runs through `processStream`
8
+ * unchanged (typed events are wrapped as the platform's NDJSON `Response`);
9
+ * - message ids are minted by the client (no `record_reserved` ever arrives), and whether the
10
+ * conversation is SAVED comes from `source.persistence`, never from that.
11
+ *
12
+ * Nothing here reaches `host/db` or the server port.
13
+ */
14
+ import type { ChatDispatch, ChatRootState } from "../../../../store/root-state.js";
15
+ import { type ChatMessageSource, type HostMessageRecord, type HostToolCall, type HostTurn } from "../../../../host/source.js";
16
+ import { type CxToolCallRecord } from "../observability/observability.slice.js";
17
+ import { type MessageRecord } from "../messages/messages.slice.js";
18
+ type Dispatch = ChatDispatch;
19
+ type GetState = () => ChatRootState;
20
+ export declare function hostRecordToMessageRecord(conversationId: string, record: HostMessageRecord): MessageRecord;
21
+ /** A host's tool call as the record a saved `tool_call` part's card reads (no database row). */
22
+ export declare function hostToolCallToRecord(conversationId: string, call: HostToolCall): CxToolCallRecord;
23
+ /** Read (or re-read) the host's history into the store. The host's sentence on failure. */
24
+ export declare function loadHostHistory(dispatch: Dispatch, getState: GetState, conversationId: string, options?: {
25
+ older?: boolean;
26
+ }): Promise<void>;
27
+ /**
28
+ * Run one host turn through the ONE stream parser. `user` is the person's message when the host
29
+ * started the turn; a turn this tab sent already shows it (no second copy).
30
+ */
31
+ export declare function runHostTurn(dispatch: Dispatch, getState: GetState, conversationId: string, turn: HostTurn): Promise<void>;
32
+ /**
33
+ * The person's send on a host conversation. Resolves when the host accepted it (the turn then
34
+ * streams, here or through `sink.turn`); rejects with the host's refusal so the caller puts the
35
+ * words back in the box.
36
+ */
37
+ export declare function sendToHost(dispatch: Dispatch, getState: GetState, conversationId: string, text: string, mode: "send" | "queue" | "steer"): Promise<void>;
38
+ /** Stop: the host ends its run; our read of the turn ends now either way. */
39
+ export declare function stopHostTurn(conversationId: string): Promise<void>;
40
+ export declare function answerHostAsk(conversationId: string, askId: string, value: unknown): Promise<void>;
41
+ /**
42
+ * Bind a conversation to a host-owned source: the instance, the plain-data entry, the
43
+ * subscription, and the first history read. Returns the unbind.
44
+ */
45
+ export declare function bindHostConversation(dispatch: Dispatch, getState: GetState, args: {
46
+ conversationId: string;
47
+ source: ChatMessageSource;
48
+ database: boolean;
49
+ surfaceKey?: string;
50
+ }): () => void;
51
+ /** For thunks that only hold state: is this conversation hosted (branch first, never reach a db). */
52
+ export declare function hostConversationOf(state: ChatRootState, conversationId: string): import("./host-conversations.slice.js").HostConversationEntry | null;
53
+ export {};
@@ -0,0 +1,412 @@
1
+ import { v4 as uuidv4 } from "uuid";
2
+ import { mintClientTempId } from "@ai-matrx/kit/ids";
3
+ import {
4
+ hostTurnResponse
5
+ } from "../../../../host/source.js";
6
+ import { upsertToolCall } from "../observability/observability.slice.js";
7
+ import { createInstanceFull } from "../create-instance-full.js";
8
+ import {
9
+ addOptimisticUserMessage,
10
+ hydrateMessages,
11
+ prependMessages,
12
+ removeMessage,
13
+ reserveMessage,
14
+ setMessagesHydrationFailure,
15
+ updateMessageRecord,
16
+ setOlderLoading
17
+ } from "../messages/messages.slice.js";
18
+ import { selectNextMessagePosition } from "../messages/messages.selectors.js";
19
+ import { createRequest, setRequestStatus } from "../active-requests/active-requests.slice.js";
20
+ import { setInstanceStatus } from "../conversations/conversations.slice.js";
21
+ import { processStream } from "../thunks/process-stream.js";
22
+ import {
23
+ registerAbortController,
24
+ unregisterAbortController
25
+ } from "../thunks/abort-registry.js";
26
+ import {
27
+ hostConversationBound,
28
+ hostConversationHeld,
29
+ hostConversationUnavailable,
30
+ hostConversationUnbound
31
+ } from "./host-conversations.slice.js";
32
+ import { getHostSource, registerHostSource, unregisterHostSource } from "./source-registry.js";
33
+ import { selectHostConversation } from "./host-conversations.selectors.js";
34
+ const localEcho = /* @__PURE__ */ new Map();
35
+ const liveTurn = /* @__PURE__ */ new Map();
36
+ function hostRecordToMessageRecord(conversationId, record) {
37
+ return {
38
+ id: record.id,
39
+ conversationId,
40
+ agentId: null,
41
+ role: record.role,
42
+ content: record.content,
43
+ contentHistory: null,
44
+ userContent: null,
45
+ position: record.position,
46
+ source: "host",
47
+ status: "active",
48
+ isVisibleToModel: true,
49
+ isVisibleToUser: true,
50
+ metadata: {},
51
+ createdAt: record.createdAt,
52
+ deletedAt: null,
53
+ error: record.error ? { type: record.error.code ?? "host_error", message: record.error.message } : null
54
+ };
55
+ }
56
+ function hostToolCallToRecord(conversationId, call) {
57
+ const at = (/* @__PURE__ */ new Date(0)).toISOString();
58
+ return {
59
+ id: `host-tool-${conversationId}-${call.callId}`,
60
+ conversationId,
61
+ userRequestId: null,
62
+ messageId: call.messageId ?? null,
63
+ userId: "",
64
+ callId: call.callId,
65
+ toolName: call.name,
66
+ toolNameAsCalled: call.displayName ?? null,
67
+ toolType: "host",
68
+ iteration: 0,
69
+ status: call.status,
70
+ success: call.status === "completed" && !call.isError,
71
+ isError: call.isError,
72
+ errorType: call.isError ? "tool_error" : null,
73
+ errorMessage: call.isError ? call.output : null,
74
+ arguments: call.arguments,
75
+ output: call.isError ? null : call.output,
76
+ outputChars: call.output?.length ?? 0,
77
+ outputPreview: null,
78
+ outputType: null,
79
+ inputTokens: null,
80
+ outputTokens: null,
81
+ totalTokens: null,
82
+ costUsd: null,
83
+ durationMs: 0,
84
+ startedAt: at,
85
+ completedAt: at,
86
+ parentCallId: null,
87
+ retryCount: null,
88
+ persistKey: null,
89
+ filePath: null,
90
+ executionEvents: call.displayName ? [{ event: "tool_started", call_id: call.callId, tool_name: call.name, data: { display_name: call.displayName } }] : null,
91
+ metadata: {},
92
+ createdAt: at,
93
+ deletedAt: null
94
+ };
95
+ }
96
+ function applyHistory(dispatch, conversationId, page, older) {
97
+ const records = page.records.map((r) => hostRecordToMessageRecord(conversationId, r));
98
+ const oldestPosition = records.reduce(
99
+ (min, r) => min === null || r.position < min ? r.position : min,
100
+ null
101
+ );
102
+ const pagination = { oldestPosition, hasMoreOlder: page.hasMoreOlder };
103
+ for (const call of page.toolCalls ?? []) {
104
+ dispatch(upsertToolCall(hostToolCallToRecord(conversationId, call)));
105
+ }
106
+ if (older) dispatch(prependMessages({ conversationId, messages: records, pagination }));
107
+ else dispatch(hydrateMessages({ conversationId, messages: records, pagination }));
108
+ dispatch(hostConversationUnavailable({ conversationId, reason: page.unavailable ?? null }));
109
+ dispatch(
110
+ setMessagesHydrationFailure({
111
+ conversationId,
112
+ failure: page.unavailable && records.length === 0 ? page.unavailable : null
113
+ })
114
+ );
115
+ }
116
+ async function loadHostHistory(dispatch, getState, conversationId, options = {}) {
117
+ const source = getHostSource(conversationId);
118
+ if (!source) return;
119
+ const entry = getState().messages.byConversationId[conversationId];
120
+ if (options.older) {
121
+ if (!entry?.hasMoreOlder || entry.isLoadingOlder) return;
122
+ dispatch(setOlderLoading({ conversationId, loading: true }));
123
+ }
124
+ try {
125
+ const page = await source.load(
126
+ conversationId,
127
+ options.older ? { before: entry?.oldestPosition ?? null } : void 0
128
+ );
129
+ if (getHostSource(conversationId) !== source) return;
130
+ applyHistory(dispatch, conversationId, page, Boolean(options.older));
131
+ } catch (error) {
132
+ const reason = error instanceof Error && error.message ? error.message : "This chat's history could not be read.";
133
+ dispatch(setMessagesHydrationFailure({ conversationId, failure: reason }));
134
+ dispatch(hostConversationUnavailable({ conversationId, reason }));
135
+ } finally {
136
+ if (options.older) dispatch(setOlderLoading({ conversationId, loading: false }));
137
+ }
138
+ }
139
+ const DROPPED_EVENTS = /* @__PURE__ */ new Set(["record_reserved", "record_update"]);
140
+ const DROPPED_TABLES = /* @__PURE__ */ new Set(["message", "cx_message", "conversation", "cx_conversation"]);
141
+ function hostTurnBody(response, signal) {
142
+ const body = response.body;
143
+ if (!body) return response;
144
+ const reader = body.getReader();
145
+ const decoder = new TextDecoder();
146
+ const encoder = new TextEncoder();
147
+ let carry = "";
148
+ const keep = (line) => {
149
+ if (!line.trim()) return false;
150
+ try {
151
+ const frame = JSON.parse(line);
152
+ return !(typeof frame.event === "string" && DROPPED_EVENTS.has(frame.event) && typeof frame.data?.table === "string" && DROPPED_TABLES.has(frame.data.table));
153
+ } catch {
154
+ return true;
155
+ }
156
+ };
157
+ const stream = new ReadableStream({
158
+ start(controller) {
159
+ signal.addEventListener("abort", () => {
160
+ try {
161
+ controller.close();
162
+ } catch {
163
+ }
164
+ void reader.cancel().catch(() => {
165
+ });
166
+ });
167
+ },
168
+ async pull(controller) {
169
+ for (; ; ) {
170
+ if (signal.aborted) return;
171
+ let chunk;
172
+ try {
173
+ chunk = await reader.read();
174
+ } catch (error) {
175
+ if (!signal.aborted) controller.error(error);
176
+ return;
177
+ }
178
+ if (signal.aborted) return;
179
+ if (chunk.done) {
180
+ if (keep(carry)) controller.enqueue(encoder.encode(`${carry}
181
+ `));
182
+ carry = "";
183
+ controller.close();
184
+ return;
185
+ }
186
+ const lines = (carry + decoder.decode(chunk.value, { stream: true })).split("\n");
187
+ carry = lines.pop() ?? "";
188
+ const kept = lines.filter(keep);
189
+ if (kept.length > 0) {
190
+ controller.enqueue(encoder.encode(`${kept.join("\n")}
191
+ `));
192
+ return;
193
+ }
194
+ }
195
+ },
196
+ cancel() {
197
+ void reader.cancel().catch(() => {
198
+ });
199
+ }
200
+ });
201
+ return new Response(stream, { status: response.status, headers: response.headers });
202
+ }
203
+ async function runHostTurn(dispatch, getState, conversationId, turn) {
204
+ const { requestId } = turn;
205
+ let userMessageClientTempId;
206
+ const echoes = localEcho.get(conversationId) ?? 0;
207
+ if (echoes > 0) {
208
+ if (echoes === 1) localEcho.delete(conversationId);
209
+ else localEcho.set(conversationId, echoes - 1);
210
+ } else if (turn.user && turn.user.length > 0) {
211
+ userMessageClientTempId = addUserMessage(dispatch, getState, conversationId, turn.user, requestId);
212
+ settleUserMessage(dispatch, conversationId, userMessageClientTempId);
213
+ }
214
+ const controller = new AbortController();
215
+ liveTurn.set(conversationId, { requestId, controller });
216
+ registerAbortController(conversationId, controller);
217
+ dispatch(createRequest({ requestId, conversationId }));
218
+ dispatch(
219
+ reserveMessage({
220
+ conversationId,
221
+ messageId: mintClientTempId("assistant", requestId),
222
+ role: "assistant",
223
+ position: selectNextMessagePosition(conversationId)(getState()),
224
+ requestId,
225
+ streamSlotStart: 0
226
+ })
227
+ );
228
+ dispatch(setInstanceStatus({ conversationId, status: "running" }));
229
+ dispatch(setInstanceStatus({ conversationId, status: "streaming" }));
230
+ dispatch(setRequestStatus({ requestId, status: "streaming" }));
231
+ try {
232
+ await processStream({
233
+ requestId,
234
+ conversationId,
235
+ response: hostTurnBody(hostTurnResponse(turn), controller.signal),
236
+ submitAt: performance.now(),
237
+ conversationIdAt: null,
238
+ dispatch,
239
+ getState,
240
+ userMessageClientTempId,
241
+ // The host's events may name its own conversation id (a CLI session id); everything
242
+ // lands on the bound conversation.
243
+ forceLocalConversationId: true
244
+ });
245
+ } catch (error) {
246
+ dispatch(
247
+ setRequestStatus({
248
+ requestId,
249
+ status: "error",
250
+ error: {
251
+ error_type: "client_error",
252
+ message: error instanceof Error ? error.message : String(error)
253
+ }
254
+ })
255
+ );
256
+ dispatch(setInstanceStatus({ conversationId, status: "error" }));
257
+ } finally {
258
+ if (liveTurn.get(conversationId)?.controller === controller) liveTurn.delete(conversationId);
259
+ unregisterAbortController(conversationId, controller);
260
+ if (controller.signal.aborted) {
261
+ dispatch(setInstanceStatus({ conversationId, status: "cancelled" }));
262
+ }
263
+ }
264
+ }
265
+ function dropLastOptimisticUser(dispatch, getState, conversationId, text) {
266
+ const entry = getState().messages.byConversationId[conversationId];
267
+ if (!entry) return;
268
+ for (let i = entry.orderedIds.length - 1; i >= 0; i -= 1) {
269
+ const record = entry.byId[entry.orderedIds[i]];
270
+ if (record?.role !== "user" || record._clientStatus !== "pending") continue;
271
+ const parts = record.content;
272
+ if (Array.isArray(parts) && parts.some((p) => p?.type === "text" && p.text === text)) {
273
+ dispatch(removeMessage({ conversationId, messageId: record.id }));
274
+ }
275
+ return;
276
+ }
277
+ }
278
+ function addUserMessage(dispatch, getState, conversationId, content, requestId) {
279
+ const clientTempId = mintClientTempId("user", uuidv4());
280
+ dispatch(
281
+ addOptimisticUserMessage({
282
+ conversationId,
283
+ clientTempId,
284
+ content,
285
+ position: selectNextMessagePosition(conversationId)(getState()),
286
+ ...requestId ? { requestId } : {}
287
+ })
288
+ );
289
+ return clientTempId;
290
+ }
291
+ async function sendToHost(dispatch, getState, conversationId, text, mode) {
292
+ const source = getHostSource(conversationId);
293
+ if (!source?.send) throw new Error("This chat is read-only here.");
294
+ const controller = new AbortController();
295
+ const shown = mode === "send";
296
+ let shownId = null;
297
+ if (shown) {
298
+ shownId = addUserMessage(dispatch, getState, conversationId, [{ type: "text", text }], void 0);
299
+ localEcho.set(conversationId, (localEcho.get(conversationId) ?? 0) + 1);
300
+ }
301
+ let turn;
302
+ try {
303
+ turn = await source.send({ conversationId, text, mode }, controller.signal);
304
+ } catch (error) {
305
+ if (shown) {
306
+ const left = (localEcho.get(conversationId) ?? 1) - 1;
307
+ if (left > 0) localEcho.set(conversationId, left);
308
+ else localEcho.delete(conversationId);
309
+ dropLastOptimisticUser(dispatch, getState, conversationId, text);
310
+ }
311
+ throw error;
312
+ }
313
+ if (shownId) settleUserMessage(dispatch, conversationId, shownId);
314
+ if (turn) await runHostTurn(dispatch, getState, conversationId, turn);
315
+ }
316
+ function settleUserMessage(dispatch, conversationId, messageId) {
317
+ dispatch(
318
+ updateMessageRecord({ conversationId, messageId, patch: { _clientStatus: "complete" } })
319
+ );
320
+ }
321
+ async function stopHostTurn(conversationId) {
322
+ const source = getHostSource(conversationId);
323
+ const live = liveTurn.get(conversationId);
324
+ try {
325
+ await source?.stop?.(conversationId, live?.requestId ?? null);
326
+ } finally {
327
+ live?.controller.abort();
328
+ }
329
+ }
330
+ async function answerHostAsk(conversationId, askId, value) {
331
+ const source = getHostSource(conversationId);
332
+ if (!source?.answer) throw new Error("Answers are not taken here.");
333
+ await source.answer(conversationId, askId, value);
334
+ }
335
+ function bindHostConversation(dispatch, getState, args) {
336
+ const { conversationId, source, database, surfaceKey } = args;
337
+ registerHostSource(conversationId, source);
338
+ if (!getState().conversations.byConversationId[conversationId]) {
339
+ dispatch(
340
+ createInstanceFull({
341
+ conversationId,
342
+ agentId: "",
343
+ agentType: "user",
344
+ origin: "manual",
345
+ ...surfaceKey ? { surfaceKey } : {},
346
+ overrides: {},
347
+ inputCapabilities: { base: {} },
348
+ variables: {},
349
+ userInput: {},
350
+ clientTools: {},
351
+ uiState: {},
352
+ messages: { apiEndpointMode: "host" }
353
+ })
354
+ );
355
+ }
356
+ dispatch(
357
+ hostConversationBound({
358
+ conversationId,
359
+ entry: {
360
+ sourceId: source.id,
361
+ whileBusy: source.whileBusy,
362
+ persistence: source.persistence,
363
+ held: null,
364
+ unavailable: null,
365
+ database,
366
+ canSend: typeof source.send === "function",
367
+ canStop: typeof source.stop === "function",
368
+ canRetry: typeof source.retry === "function",
369
+ canAnswer: typeof source.answer === "function",
370
+ hasConversationList: Boolean(source.conversations)
371
+ }
372
+ })
373
+ );
374
+ const unsubscribe = source.subscribe(conversationId, {
375
+ turn: (turn) => {
376
+ if (getHostSource(conversationId) !== source) return;
377
+ void runHostTurn(dispatch, getState, conversationId, turn);
378
+ },
379
+ history: () => {
380
+ if (getHostSource(conversationId) !== source) return;
381
+ void loadHostHistory(dispatch, getState, conversationId);
382
+ },
383
+ held: (reason) => {
384
+ if (getHostSource(conversationId) !== source) return;
385
+ dispatch(hostConversationHeld({ conversationId, reason }));
386
+ }
387
+ });
388
+ void loadHostHistory(dispatch, getState, conversationId);
389
+ return () => {
390
+ unsubscribe();
391
+ if (getHostSource(conversationId) === source) {
392
+ liveTurn.get(conversationId)?.controller.abort();
393
+ unregisterHostSource(conversationId, source);
394
+ dispatch(hostConversationUnbound(conversationId));
395
+ localEcho.delete(conversationId);
396
+ }
397
+ };
398
+ }
399
+ function hostConversationOf(state, conversationId) {
400
+ return selectHostConversation(conversationId)(state);
401
+ }
402
+ export {
403
+ answerHostAsk,
404
+ bindHostConversation,
405
+ hostConversationOf,
406
+ hostRecordToMessageRecord,
407
+ hostToolCallToRecord,
408
+ loadHostHistory,
409
+ runHostTurn,
410
+ sendToHost,
411
+ stopHostTurn
412
+ };