@assistant-ui/core 0.3.16 → 0.3.17

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 (305) hide show
  1. package/dist/index.d.ts +2 -2
  2. package/dist/index.js +2 -2
  3. package/dist/index.js.map +1 -1
  4. package/dist/internal.d.ts +2 -1
  5. package/dist/internal.js +2 -1
  6. package/dist/model-context/frame/provider.d.ts +3 -0
  7. package/dist/model-context/frame/provider.d.ts.map +1 -1
  8. package/dist/model-context/frame/provider.js +71 -21
  9. package/dist/model-context/frame/provider.js.map +1 -1
  10. package/dist/model-context/tool-call-text.d.ts +26 -0
  11. package/dist/model-context/tool-call-text.d.ts.map +1 -0
  12. package/dist/model-context/tool-call-text.js +18 -0
  13. package/dist/model-context/tool-call-text.js.map +1 -0
  14. package/dist/react/RuntimeAdapter.js +1 -1
  15. package/dist/react/adapters/LocalStorageThreadListAdapter.d.ts.map +1 -1
  16. package/dist/react/adapters/LocalStorageThreadListAdapter.js +1 -1
  17. package/dist/react/adapters/LocalStorageThreadListAdapter.js.map +1 -1
  18. package/dist/react/client/AdaptedRemoteThread.js +1 -1
  19. package/dist/react/client/InMemoryThreadList.js +1 -1
  20. package/dist/react/client/Interactables.js +1 -1
  21. package/dist/react/client/RemoteThreadList.d.ts +15 -0
  22. package/dist/react/client/RemoteThreadList.d.ts.map +1 -1
  23. package/dist/react/client/RemoteThreadList.js +240 -138
  24. package/dist/react/client/RemoteThreadList.js.map +1 -1
  25. package/dist/react/client/Tools.d.ts.map +1 -1
  26. package/dist/react/client/Tools.js +6 -2
  27. package/dist/react/client/Tools.js.map +1 -1
  28. package/dist/react/index.d.ts +2 -1
  29. package/dist/react/index.js +2 -1
  30. package/dist/react/interactables-legacy/Interactables.js +4 -4
  31. package/dist/react/interactables-legacy/Interactables.js.map +1 -1
  32. package/dist/react/model-context/toolbox.d.ts +2 -14
  33. package/dist/react/model-context/toolbox.d.ts.map +1 -1
  34. package/dist/react/model-context/toolbox.js +1 -13
  35. package/dist/react/model-context/toolbox.js.map +1 -1
  36. package/dist/react/model-context/useAssistantContext.js +37 -7
  37. package/dist/react/model-context/useAssistantContext.js.map +1 -1
  38. package/dist/react/model-context/useAuiToolOverrides.js +31 -5
  39. package/dist/react/model-context/useAuiToolOverrides.js.map +1 -1
  40. package/dist/react/model-context/useInlineRender.d.ts.map +1 -1
  41. package/dist/react/model-context/useInlineRender.js +10 -36
  42. package/dist/react/model-context/useInlineRender.js.map +1 -1
  43. package/dist/react/primitive-hooks/useMessageError.d.ts.map +1 -1
  44. package/dist/react/primitive-hooks/useMessageError.js +2 -8
  45. package/dist/react/primitive-hooks/useMessageError.js.map +1 -1
  46. package/dist/react/primitive-hooks/useThreadListLoadMore.d.ts.map +1 -1
  47. package/dist/react/primitive-hooks/useThreadListLoadMore.js +2 -4
  48. package/dist/react/primitive-hooks/useThreadListLoadMore.js.map +1 -1
  49. package/dist/react/primitives/composer/ComposerAttachments.d.ts.map +1 -1
  50. package/dist/react/primitives/composer/ComposerAttachments.js +4 -3
  51. package/dist/react/primitives/composer/ComposerAttachments.js.map +1 -1
  52. package/dist/react/primitives/composer/ComposerQueue.d.ts.map +1 -1
  53. package/dist/react/primitives/composer/ComposerQueue.js +4 -3
  54. package/dist/react/primitives/composer/ComposerQueue.js.map +1 -1
  55. package/dist/react/primitives/message/MessageAttachments.d.ts.map +1 -1
  56. package/dist/react/primitives/message/MessageAttachments.js +7 -6
  57. package/dist/react/primitives/message/MessageAttachments.js.map +1 -1
  58. package/dist/react/primitives/message/MessageGroupedParts.js +2 -2
  59. package/dist/react/primitives/message/MessageGroupedParts.js.map +1 -1
  60. package/dist/react/primitives/message/MessageParts.js +3 -3
  61. package/dist/react/primitives/message/MessageParts.js.map +1 -1
  62. package/dist/react/primitives/threadList/ThreadListItems.d.ts.map +1 -1
  63. package/dist/react/primitives/threadList/ThreadListItems.js +5 -4
  64. package/dist/react/primitives/threadList/ThreadListItems.js.map +1 -1
  65. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts +6 -4
  66. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts.map +1 -1
  67. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js +44 -22
  68. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js.map +1 -1
  69. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts +6 -5
  70. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
  71. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js +79 -62
  72. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js.map +1 -1
  73. package/dist/react/runtimes/RemoteThreadResource.d.ts +1 -6
  74. package/dist/react/runtimes/RemoteThreadResource.d.ts.map +1 -1
  75. package/dist/react/runtimes/RemoteThreadResource.js +3 -3
  76. package/dist/react/runtimes/RemoteThreadResource.js.map +1 -1
  77. package/dist/react/runtimes/assistant-transport/useLatestRef.js +2 -2
  78. package/dist/react/runtimes/assistant-transport/useLatestRef.js.map +1 -1
  79. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts.map +1 -1
  80. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js +23 -18
  81. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js.map +1 -1
  82. package/dist/react/runtimes/cloud/auiV0.d.ts +5 -1
  83. package/dist/react/runtimes/cloud/auiV0.d.ts.map +1 -1
  84. package/dist/react/runtimes/cloud/auiV0.js.map +1 -1
  85. package/dist/react/runtimes/cloud/createCloudThreadListAdapter.d.ts +29 -0
  86. package/dist/react/runtimes/cloud/createCloudThreadListAdapter.d.ts.map +1 -0
  87. package/dist/react/runtimes/cloud/createCloudThreadListAdapter.js +159 -0
  88. package/dist/react/runtimes/cloud/createCloudThreadListAdapter.js.map +1 -0
  89. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.d.ts +1 -9
  90. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.d.ts.map +1 -1
  91. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js +16 -153
  92. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js.map +1 -1
  93. package/dist/react/runtimes/external-message-converter.js +1 -1
  94. package/dist/react/runtimes/external-message-converter.js.map +1 -1
  95. package/dist/react/runtimes/useRemoteThreadListRuntime.d.ts.map +1 -1
  96. package/dist/react/runtimes/useRemoteThreadListRuntime.js +14 -6
  97. package/dist/react/runtimes/useRemoteThreadListRuntime.js.map +1 -1
  98. package/dist/react/types/MessagePartComponentTypes.d.ts +7 -3
  99. package/dist/react/types/MessagePartComponentTypes.d.ts.map +1 -1
  100. package/dist/react/types/scopes/tools.d.ts +2 -0
  101. package/dist/react/types/scopes/tools.d.ts.map +1 -1
  102. package/dist/runtime/api/message-part-runtime.d.ts +2 -2
  103. package/dist/runtime/api/message-part-runtime.d.ts.map +1 -1
  104. package/dist/runtime/api/message-part-runtime.js +1 -1
  105. package/dist/runtime/api/message-part-runtime.js.map +1 -1
  106. package/dist/runtime/api/thread-list-runtime.d.ts +9 -1
  107. package/dist/runtime/api/thread-list-runtime.d.ts.map +1 -1
  108. package/dist/runtime/api/thread-list-runtime.js +5 -0
  109. package/dist/runtime/api/thread-list-runtime.js.map +1 -1
  110. package/dist/runtime/api/thread-runtime.d.ts +1 -1
  111. package/dist/runtime/base/base-thread-runtime-core.d.ts +2 -2
  112. package/dist/runtime/base/base-thread-runtime-core.d.ts.map +1 -1
  113. package/dist/runtime/base/base-thread-runtime-core.js +2 -2
  114. package/dist/runtime/base/base-thread-runtime-core.js.map +1 -1
  115. package/dist/runtime/interfaces/thread-list-runtime-core.d.ts +14 -2
  116. package/dist/runtime/interfaces/thread-list-runtime-core.d.ts.map +1 -1
  117. package/dist/runtime/interfaces/thread-runtime-core.d.ts +15 -1
  118. package/dist/runtime/interfaces/thread-runtime-core.d.ts.map +1 -1
  119. package/dist/runtime/utils/auto-status.d.ts +1 -1
  120. package/dist/runtime/utils/auto-status.d.ts.map +1 -1
  121. package/dist/runtime/utils/auto-status.js +6 -2
  122. package/dist/runtime/utils/auto-status.js.map +1 -1
  123. package/dist/runtime/utils/external-message-conversion.d.ts +3 -2
  124. package/dist/runtime/utils/external-message-conversion.d.ts.map +1 -1
  125. package/dist/runtime/utils/external-message-conversion.js +4 -3
  126. package/dist/runtime/utils/external-message-conversion.js.map +1 -1
  127. package/dist/runtime/utils/resolveToolApprovalResponse.d.ts +6 -3
  128. package/dist/runtime/utils/resolveToolApprovalResponse.d.ts.map +1 -1
  129. package/dist/runtime/utils/resolveToolApprovalResponse.js +12 -3
  130. package/dist/runtime/utils/resolveToolApprovalResponse.js.map +1 -1
  131. package/dist/runtime/utils/thread-message-like.d.ts +2 -10
  132. package/dist/runtime/utils/thread-message-like.d.ts.map +1 -1
  133. package/dist/runtime/utils/thread-message-like.js.map +1 -1
  134. package/dist/runtime/utils/tool-call-tree.d.ts +39 -0
  135. package/dist/runtime/utils/tool-call-tree.d.ts.map +1 -0
  136. package/dist/runtime/utils/tool-call-tree.js +85 -0
  137. package/dist/runtime/utils/tool-call-tree.js.map +1 -0
  138. package/dist/runtimes/external-store/external-store-adapter.d.ts +29 -2
  139. package/dist/runtimes/external-store/external-store-adapter.d.ts.map +1 -1
  140. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts +2 -1
  141. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts.map +1 -1
  142. package/dist/runtimes/external-store/external-store-thread-runtime-core.js +34 -28
  143. package/dist/runtimes/external-store/external-store-thread-runtime-core.js.map +1 -1
  144. package/dist/runtimes/inert/InertThreadRuntimeCore.d.ts +1 -1
  145. package/dist/runtimes/inert/InertThreadRuntimeCore.d.ts.map +1 -1
  146. package/dist/runtimes/inert/InertThreadRuntimeCore.js.map +1 -1
  147. package/dist/runtimes/local/local-thread-runtime-core.d.ts +1 -1
  148. package/dist/runtimes/local/local-thread-runtime-core.d.ts.map +1 -1
  149. package/dist/runtimes/local/local-thread-runtime-core.js +3 -1
  150. package/dist/runtimes/local/local-thread-runtime-core.js.map +1 -1
  151. package/dist/runtimes/remote-thread-list/remote-thread-state.d.ts +1 -1
  152. package/dist/runtimes/remote-thread-list/remote-thread-state.d.ts.map +1 -1
  153. package/dist/runtimes/remote-thread-list/remote-thread-state.js +30 -13
  154. package/dist/runtimes/remote-thread-list/remote-thread-state.js.map +1 -1
  155. package/dist/runtimes/remote-thread-list/title.d.ts +9 -0
  156. package/dist/runtimes/remote-thread-list/title.d.ts.map +1 -0
  157. package/dist/runtimes/remote-thread-list/title.js +6 -0
  158. package/dist/runtimes/remote-thread-list/title.js.map +1 -0
  159. package/dist/runtimes/remote-thread-list/types.d.ts +6 -5
  160. package/dist/runtimes/remote-thread-list/types.d.ts.map +1 -1
  161. package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts +31 -8
  162. package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts.map +1 -1
  163. package/dist/runtimes/tool-invocations/ToolInvocationTracker.js +97 -60
  164. package/dist/runtimes/tool-invocations/ToolInvocationTracker.js.map +1 -1
  165. package/dist/store/clients/external-thread.d.ts +1 -1
  166. package/dist/store/clients/external-thread.d.ts.map +1 -1
  167. package/dist/store/clients/external-thread.js +11 -4
  168. package/dist/store/clients/external-thread.js.map +1 -1
  169. package/dist/store/clients/single-thread-list.js +1 -1
  170. package/dist/store/clients/suggestions.d.ts.map +1 -1
  171. package/dist/store/clients/suggestions.js +18 -6
  172. package/dist/store/clients/suggestions.js.map +1 -1
  173. package/dist/store/clients/thread-message-client.js +1 -1
  174. package/dist/store/clients/thread-selection-events.js +1 -1
  175. package/dist/store/index.d.ts +2 -1
  176. package/dist/store/index.js +2 -1
  177. package/dist/store/internal.d.ts +2 -2
  178. package/dist/store/internal.js +2 -2
  179. package/dist/store/primitive-predicates.d.ts +4 -1
  180. package/dist/store/primitive-predicates.d.ts.map +1 -1
  181. package/dist/store/primitive-predicates.js +9 -1
  182. package/dist/store/primitive-predicates.js.map +1 -1
  183. package/dist/store/runtime-clients/composer-runtime-client.js +1 -1
  184. package/dist/store/runtime-clients/message-runtime-client.js +1 -1
  185. package/dist/store/runtime-clients/thread-list-item-runtime-client.js +1 -1
  186. package/dist/store/runtime-clients/thread-list-runtime-client.d.ts.map +1 -1
  187. package/dist/store/runtime-clients/thread-list-runtime-client.js +124 -105
  188. package/dist/store/runtime-clients/thread-list-runtime-client.js.map +1 -1
  189. package/dist/store/runtime-clients/thread-runtime-client.js +1 -1
  190. package/dist/store/runtime-clients/useSubscribable.d.ts +3 -1
  191. package/dist/store/runtime-clients/useSubscribable.d.ts.map +1 -1
  192. package/dist/store/runtime-clients/useSubscribable.js +1 -1
  193. package/dist/store/runtime-clients/useSubscribable.js.map +1 -1
  194. package/dist/store/scopes/part.d.ts +6 -3
  195. package/dist/store/scopes/part.d.ts.map +1 -1
  196. package/dist/subscribable/subscribable.d.ts +8 -1
  197. package/dist/subscribable/subscribable.d.ts.map +1 -1
  198. package/dist/subscribable/subscribable.js +24 -16
  199. package/dist/subscribable/subscribable.js.map +1 -1
  200. package/dist/types/message.d.ts +40 -1
  201. package/dist/types/message.d.ts.map +1 -1
  202. package/dist/types/message.js +7 -1
  203. package/dist/types/message.js.map +1 -1
  204. package/package.json +12 -17
  205. package/src/index.ts +6 -1
  206. package/src/internal.ts +8 -0
  207. package/src/model-context/frame/provider.test.ts +217 -1
  208. package/src/model-context/frame/provider.ts +111 -23
  209. package/src/model-context/tool-call-text.test.ts +67 -0
  210. package/src/model-context/tool-call-text.ts +67 -0
  211. package/src/react/AssistantRuntimeProvider.test.tsx +66 -2
  212. package/src/react/adapters/LocalStorageThreadListAdapter.tsx +1 -3
  213. package/src/react/client/RemoteThreadList.background.test.ts +384 -0
  214. package/src/react/client/RemoteThreadList.concurrent.test.tsx +274 -0
  215. package/src/react/client/RemoteThreadList.test.ts +273 -1
  216. package/src/react/client/RemoteThreadList.ts +293 -83
  217. package/src/react/client/Tools.ts +7 -1
  218. package/src/react/index.ts +4 -0
  219. package/src/react/model-context/modelContextHooks.test.tsx +131 -0
  220. package/src/react/model-context/toolbox.test.ts +9 -9
  221. package/src/react/model-context/toolbox.ts +9 -36
  222. package/src/react/model-context/useAssistantContext.ts +4 -2
  223. package/src/react/model-context/useAuiToolOverrides.ts +4 -2
  224. package/src/react/model-context/useInlineRender.test.tsx +48 -0
  225. package/src/react/model-context/useInlineRender.ts +14 -10
  226. package/src/react/primitive-hooks/useMessageError.ts +2 -19
  227. package/src/react/primitive-hooks/useThreadListLoadMore.ts +2 -3
  228. package/src/react/primitives/composer/ComposerAttachments.test.tsx +76 -0
  229. package/src/react/primitives/composer/ComposerAttachments.tsx +9 -4
  230. package/src/react/primitives/composer/ComposerQueue.test.tsx +72 -0
  231. package/src/react/primitives/composer/ComposerQueue.tsx +7 -4
  232. package/src/react/primitives/message/MessageAttachments.test.tsx +107 -37
  233. package/src/react/primitives/message/MessageAttachments.tsx +10 -7
  234. package/src/react/primitives/message/MessageGroupedParts.tsx +2 -2
  235. package/src/react/primitives/message/MessageParts.tsx +3 -3
  236. package/src/react/primitives/threadList/ThreadListItems.test.tsx +99 -0
  237. package/src/react/primitives/threadList/ThreadListItems.tsx +8 -5
  238. package/src/react/runtimes/RemoteThreadListHookInstanceManager.running.test.tsx +94 -1
  239. package/src/react/runtimes/RemoteThreadListHookInstanceManager.tsx +72 -31
  240. package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.switch-delete.test.ts +169 -0
  241. package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.tsx +114 -68
  242. package/src/react/runtimes/RemoteThreadResource.ts +1 -4
  243. package/src/react/runtimes/assistant-transport/transport-scheduling.test.ts +51 -2
  244. package/src/react/runtimes/assistant-transport/useLatestRef.ts +2 -2
  245. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.test.ts +45 -0
  246. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.test.tsx +65 -1
  247. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.ts +42 -35
  248. package/src/react/runtimes/cloud/auiV0.ts +5 -0
  249. package/src/react/runtimes/cloud/createCloudThreadListAdapter.test.ts +88 -0
  250. package/src/react/runtimes/cloud/createCloudThreadListAdapter.ts +236 -0
  251. package/src/react/runtimes/cloud/useCloudThreadListAdapter.test.tsx +90 -1
  252. package/src/react/runtimes/cloud/useCloudThreadListAdapter.tsx +33 -238
  253. package/src/react/runtimes/external-message-converter.ts +1 -0
  254. package/src/react/runtimes/useRemoteThreadListRuntime.concurrent.test.tsx +216 -0
  255. package/src/react/runtimes/useRemoteThreadListRuntime.ts +24 -6
  256. package/src/react/types/MessagePartComponentTypes.ts +7 -3
  257. package/src/react/types/scopes/tools.ts +2 -0
  258. package/src/runtime/api/message-part-runtime.ts +3 -3
  259. package/src/runtime/api/thread-list-runtime.ts +25 -1
  260. package/src/runtime/base/base-thread-runtime-core.test.ts +94 -3
  261. package/src/runtime/base/base-thread-runtime-core.ts +10 -4
  262. package/src/runtime/interfaces/thread-list-runtime-core.ts +20 -1
  263. package/src/runtime/interfaces/thread-runtime-core.ts +17 -1
  264. package/src/runtime/utils/auto-status.test.ts +57 -0
  265. package/src/runtime/utils/auto-status.ts +13 -1
  266. package/src/runtime/utils/external-message-conversion.test.ts +97 -0
  267. package/src/runtime/utils/external-message-conversion.ts +17 -1
  268. package/src/runtime/utils/resolveToolApprovalResponse.test.ts +73 -0
  269. package/src/runtime/utils/resolveToolApprovalResponse.ts +27 -6
  270. package/src/runtime/utils/thread-message-like.ts +2 -10
  271. package/src/runtime/utils/tool-call-tree.test.ts +191 -0
  272. package/src/runtime/utils/tool-call-tree.ts +97 -0
  273. package/src/runtimes/external-store/external-store-adapter.ts +38 -2
  274. package/src/runtimes/external-store/external-store-thread-runtime-core.ts +56 -33
  275. package/src/runtimes/inert/InertThreadRuntimeCore.ts +1 -1
  276. package/src/runtimes/local/local-thread-runtime-core.test.ts +29 -3
  277. package/src/runtimes/local/local-thread-runtime-core.ts +5 -1
  278. package/src/runtimes/remote-thread-list/remote-thread-state.test.ts +112 -0
  279. package/src/runtimes/remote-thread-list/remote-thread-state.ts +55 -16
  280. package/src/runtimes/remote-thread-list/title.ts +3 -0
  281. package/src/runtimes/remote-thread-list/types.ts +6 -5
  282. package/src/runtimes/tool-invocations/EDGE_CASES.md +110 -5
  283. package/src/runtimes/tool-invocations/ToolInvocationTracker.test.ts +750 -136
  284. package/src/runtimes/tool-invocations/ToolInvocationTracker.ts +144 -91
  285. package/src/store/clients/external-thread.ts +14 -8
  286. package/src/store/clients/suggestions.test.ts +155 -1
  287. package/src/store/clients/suggestions.ts +42 -34
  288. package/src/store/index.ts +4 -0
  289. package/src/store/internal.ts +2 -0
  290. package/src/store/primitive-predicates.ts +35 -0
  291. package/src/store/runtime-clients/thread-list-runtime-client.ts +16 -2
  292. package/src/store/runtime-clients/useSubscribable.ts +8 -2
  293. package/src/store/scopes/part.ts +6 -3
  294. package/src/subscribable/subscribable.test.ts +50 -0
  295. package/src/subscribable/subscribable.ts +33 -21
  296. package/src/tests/RemoteThreadListThreadListRuntimeCore-load-race.test.ts +111 -0
  297. package/src/tests/RemoteThreadListThreadListRuntimeCore-loadMore.test.ts +78 -0
  298. package/src/tests/RemoteThreadListThreadListRuntimeCore-reload.test.ts +52 -0
  299. package/src/tests/external-store-optimistic-id.test.ts +79 -0
  300. package/src/tests/external-store-repository-instance.test.ts +166 -0
  301. package/src/tests/external-store-thread-runtime-core-adapter.test.ts +22 -16
  302. package/src/tests/external-thread-attachments.test.tsx +85 -1
  303. package/src/tests/remote-thread-list-adapter-switch.test.ts +66 -1
  304. package/src/tests/thread-switch-events.test.tsx +397 -2
  305. package/src/types/message.ts +50 -2
@@ -2,15 +2,20 @@ import {
2
2
  useCallback,
3
3
  useEffect,
4
4
  useMemo,
5
+ useRef,
5
6
  useState,
6
7
  useSyncExternalStore,
7
8
  } from "react";
8
- import { resource, withKey } from "@assistant-ui/tap";
9
+ import { resource, withKey, type ResourceElement } from "@assistant-ui/tap";
9
10
  import type { ClientOutput } from "@assistant-ui/store";
10
11
  import {
11
12
  attachTransformScopes,
13
+ Derived,
14
+ useAssistantContextProvider,
15
+ useAssistantContextValue,
12
16
  useClientLookup,
13
17
  useClientResource,
18
+ useConfiguredAui,
14
19
  } from "@assistant-ui/store/client";
15
20
  import { isDevelopment, useThreadSelectionEvents } from "../../store/internal";
16
21
  import { OptimisticState } from "../../runtimes/remote-thread-list/optimistic-state";
@@ -40,6 +45,7 @@ import {
40
45
  type InMemoryThreadListProps,
41
46
  } from "./InMemoryThreadList";
42
47
  import { AdaptedRemoteThread } from "./AdaptedRemoteThread";
48
+ import { isTitleSourceMessage } from "../../runtimes/remote-thread-list/title";
43
49
 
44
50
  const RESOLVED_PROMISE = Promise.resolve();
45
51
 
@@ -62,6 +68,18 @@ export type RemoteThreadListProps = {
62
68
  onSwitchToThread?: ((threadId: string) => void) | undefined;
63
69
  onSwitchToNewThread?: (() => void) | undefined;
64
70
  onDelete?: ((threadId: string) => void) | undefined;
71
+ /**
72
+ * Keeps every thread the session switched to mounted, so a run continues
73
+ * after the user switches away, per-item `isRunning` reflects background
74
+ * runs, and a freshly initialized thread generates its title automatically.
75
+ * A body unmounts on delete, detach, or an adapter replacement (`reload()`
76
+ * after swapping the adapter); visited threads otherwise stay mounted for
77
+ * the client's lifetime. Each body reads its own thread through the ambient
78
+ * `threadListItem` scope, and `unstable_useAdapters` runs once per mounted
79
+ * body. Off (the default), only the visible thread is mounted and a switch
80
+ * unmounts it. The mode is fixed at mount.
81
+ */
82
+ backgroundThreads?: boolean | undefined;
65
83
  };
66
84
 
67
85
  const threadNotFoundError = (threadIdOrRemoteId: string, action: string) =>
@@ -202,9 +220,96 @@ const isSameThread = (
202
220
  return data !== undefined && itemMatchesId(data, listState, right);
203
221
  };
204
222
 
223
+ const useRemoteThreadBody = ({
224
+ id,
225
+ status,
226
+ remoteId,
227
+ item,
228
+ thread,
229
+ }: {
230
+ id: string;
231
+ status: RemoteThreadData["status"];
232
+ remoteId: string | undefined;
233
+ item: (isRunning: boolean) => ResourceElement<ClientOutput<"threadListItem">>;
234
+ thread: ResourceElement<ClientOutput<"thread">>;
235
+ }): ClientOutput<"thread"> => {
236
+ const parent = useAssistantContextValue();
237
+ const [isRunning, setIsRunning] = useState(false);
238
+ // The item client is mounted inside the body and served to the subtree
239
+ // through a Derived scope, which keeps the graft on the derived-only (no
240
+ // nested client host) path; resolving `parent.threads` here instead would
241
+ // read the threads scope during its own construction.
242
+ const itemHandle = useClientResource(item(isRunning));
243
+ const { client } = useConfiguredAui(parent, {
244
+ threadListItem: Derived({
245
+ source: "threads",
246
+ query: { type: "id", id },
247
+ get: () => itemHandle.methods,
248
+ }),
249
+ });
250
+ // Auto-title arms only for a thread born "new" in this body's lifetime;
251
+ // threads loaded or fetched from the adapter already carry their title. The
252
+ // settled (non-optimistic) initialize is what writes remoteId, so its
253
+ // arrival is the initialization signal.
254
+ const bornNewRef = useRef(status === "new");
255
+ const titleFiredRef = useRef(false);
256
+ return useAssistantContextProvider(client, function useBoundRemoteBody() {
257
+ const body = useClientResource(thread);
258
+ const bodyRunning = body.state.isRunning === true;
259
+ useEffect(() => {
260
+ setIsRunning(bodyRunning);
261
+ }, [bodyRunning]);
262
+ const armed =
263
+ bornNewRef.current && !titleFiredRef.current && remoteId !== undefined;
264
+ const hasTitleSource =
265
+ armed &&
266
+ (
267
+ body.state.messages as readonly {
268
+ status?: { type: string } | undefined;
269
+ }[]
270
+ ).some(isTitleSourceMessage);
271
+ useEffect(() => {
272
+ if (!hasTitleSource || titleFiredRef.current) return;
273
+ titleFiredRef.current = true;
274
+ client.threadListItem.generateTitle();
275
+ }, [hasTitleSource]);
276
+ return body.methods;
277
+ });
278
+ };
279
+
280
+ const RemoteThreadBody = resource(useRemoteThreadBody);
281
+
282
+ // `thread("main")` keeps one identity across switches, like the single
283
+ // useClientResource slot it replaced: consumers (the ambient `thread` scope,
284
+ // captured clients) hold the facade while it delegates to whichever body is
285
+ // currently main. Publishing the target during commit keeps abandoned
286
+ // concurrent renders from changing the facade observed by committed consumers.
287
+ const useMainThreadFacade = (
288
+ current: ClientOutput<"thread">,
289
+ ): ClientOutput<"thread"> => {
290
+ const currentRef = useRef(current);
291
+ useEffect(() => {
292
+ currentRef.current = current;
293
+ }, [current]);
294
+ const [facade] = useState(
295
+ () =>
296
+ new Proxy({} as ClientOutput<"thread">, {
297
+ get: (_, prop) =>
298
+ (currentRef.current as unknown as Record<PropertyKey, unknown>)[prop],
299
+ has: (_, prop) => prop in (currentRef.current as object),
300
+ ownKeys: () => Reflect.ownKeys(currentRef.current as object),
301
+ getOwnPropertyDescriptor: (_, prop) =>
302
+ Reflect.getOwnPropertyDescriptor(currentRef.current as object, prop),
303
+ }),
304
+ );
305
+ return facade;
306
+ };
307
+
205
308
  const useRemoteThreadListView = ({
206
309
  listState,
207
310
  mainThreadId,
311
+ startedIds,
312
+ backgroundThreads,
208
313
  threadFactory,
209
314
  useAdapters,
210
315
  onSwitchTo,
@@ -219,6 +324,8 @@ const useRemoteThreadListView = ({
219
324
  }: {
220
325
  listState: RemoteThreadState;
221
326
  mainThreadId: string;
327
+ startedIds: readonly string[];
328
+ backgroundThreads: boolean;
222
329
  threadFactory: RemoteThreadListProps["thread"];
223
330
  useAdapters: RemoteThreadListAdapter["unstable_useAdapters"];
224
331
  onSwitchTo: (
@@ -243,17 +350,102 @@ const useRemoteThreadListView = ({
243
350
  }>;
244
351
  onDetach: (threadId: string) => Promise<void>;
245
352
  }) => {
246
- const thread = threadFactory(mainThreadId);
247
- const wrapped =
248
- useAdapters === undefined
249
- ? thread
250
- : AdaptedRemoteThread({
251
- useAdapters,
252
- thread,
253
- });
254
- const mainThreadClient = useClientResource(
255
- thread.key === undefined ? wrapped : withKey(thread.key, wrapped),
353
+ const bodyIds = useMemo(() => {
354
+ if (!backgroundThreads) return [mainThreadId];
355
+ const seen = new Set<string>();
356
+ const seenRemoteIds = new Set<string>();
357
+ const ids: string[] = [];
358
+ for (const id of startedIds) {
359
+ const data = getThreadData(listState, id);
360
+ if (!data || seen.has(data.id)) continue;
361
+ if (data.remoteId !== undefined && seenRemoteIds.has(data.remoteId)) {
362
+ continue;
363
+ }
364
+ seen.add(data.id);
365
+ if (data.remoteId !== undefined) seenRemoteIds.add(data.remoteId);
366
+ ids.push(data.id);
367
+ }
368
+ return ids;
369
+ }, [backgroundThreads, listState, mainThreadId, startedIds]);
370
+
371
+ const itemElementFor = (data: RemoteThreadData, isRunning: boolean) =>
372
+ ThreadListItemClient({
373
+ data,
374
+ isRunning,
375
+ onSwitchTo: (options) =>
376
+ handleThreadListAction("switch", () => onSwitchTo(data.id, options)),
377
+ onRename: (title) =>
378
+ handleThreadListAction("rename", () => onRename(data.id, title)),
379
+ onUpdateCustom: (custom) =>
380
+ handleThreadListAction("update custom metadata", () =>
381
+ onUpdateCustom(data.id, custom),
382
+ ),
383
+ onArchive: () =>
384
+ handleThreadListAction("archive", () => onArchive(data.id)),
385
+ onUnarchive: () =>
386
+ handleThreadListAction("unarchive", () => onUnarchive(data.id)),
387
+ onDelete: () => handleThreadListAction("delete", () => onDelete(data.id)),
388
+ onGenerateTitle: () =>
389
+ handleThreadListAction("generate title", () =>
390
+ onGenerateTitle(
391
+ data.id,
392
+ (backgroundThreads
393
+ ? bodyStateOf(data.id)?.messages
394
+ : mainThreadClient.state.messages) as
395
+ | readonly ThreadMessage[]
396
+ | undefined,
397
+ ),
398
+ ),
399
+ onInitialize: () => onInitialize(data.id),
400
+ onDetach: () => handleThreadListAction("detach", () => onDetach(data.id)),
401
+ });
402
+
403
+ const bodies = useClientLookup(
404
+ bodyIds.map((id) => {
405
+ const made = threadFactory(id);
406
+ // Background bodies never change occupant, so an unkeyed factory
407
+ // element is keyed by the mapping id here; per-body history loads
408
+ // without requiring the factory to key itself.
409
+ const thread =
410
+ backgroundThreads && made.key === undefined ? withKey(id, made) : made;
411
+ const wrapped =
412
+ useAdapters === undefined
413
+ ? thread
414
+ : AdaptedRemoteThread({
415
+ useAdapters,
416
+ thread,
417
+ });
418
+ const data = getThreadData(listState, id);
419
+ const element =
420
+ backgroundThreads && data !== undefined
421
+ ? RemoteThreadBody({
422
+ id,
423
+ status: data.status,
424
+ remoteId: data.remoteId,
425
+ item: (isRunning) => itemElementFor(data, isRunning),
426
+ thread: wrapped,
427
+ })
428
+ : wrapped;
429
+ return withKey(backgroundThreads ? id : (made.key ?? "main"), element);
430
+ }),
256
431
  );
432
+ // A reload can remap a local thread id to its remote identity while the
433
+ // body stays keyed by the original mapping id, so lookups fall back to
434
+ // remote-identity matching.
435
+ const bodyIndexOf = (id: string) => {
436
+ const direct = bodyIds.indexOf(id);
437
+ if (direct !== -1) return direct;
438
+ return bodyIds.findIndex((bodyId) => isSameThread(listState, bodyId, id));
439
+ };
440
+ const bodyStateOf = (id: string) => {
441
+ const index = bodyIndexOf(id);
442
+ return index === -1 ? undefined : bodies.state[index];
443
+ };
444
+ const mainIndex = bodyIndexOf(mainThreadId);
445
+ const mainThreadClient = {
446
+ state: bodies.state[mainIndex]!,
447
+ methods: useMainThreadFacade(bodies.get({ index: mainIndex })),
448
+ };
257
449
  const itemOrder = useMemo(
258
450
  () => collectItemOrder(listState, mainThreadId),
259
451
  [listState, mainThreadId],
@@ -262,40 +454,13 @@ const useRemoteThreadListView = ({
262
454
  itemOrder.map((data) =>
263
455
  withKey(
264
456
  data.id,
265
- ThreadListItemClient({
457
+ itemElementFor(
266
458
  data,
267
- isRunning:
268
- itemMatchesId(data, listState, mainThreadId) &&
269
- mainThreadClient.state.isRunning,
270
- onSwitchTo: (options) =>
271
- handleThreadListAction("switch", () =>
272
- onSwitchTo(data.id, options),
273
- ),
274
- onRename: (title) =>
275
- handleThreadListAction("rename", () => onRename(data.id, title)),
276
- onUpdateCustom: (custom) =>
277
- handleThreadListAction("update custom metadata", () =>
278
- onUpdateCustom(data.id, custom),
279
- ),
280
- onArchive: () =>
281
- handleThreadListAction("archive", () => onArchive(data.id)),
282
- onUnarchive: () =>
283
- handleThreadListAction("unarchive", () => onUnarchive(data.id)),
284
- onDelete: () =>
285
- handleThreadListAction("delete", () => onDelete(data.id)),
286
- onGenerateTitle: () =>
287
- handleThreadListAction("generate title", () =>
288
- onGenerateTitle(
289
- data.id,
290
- mainThreadClient.state.messages as
291
- | readonly ThreadMessage[]
292
- | undefined,
293
- ),
294
- ),
295
- onInitialize: () => onInitialize(data.id),
296
- onDetach: () =>
297
- handleThreadListAction("detach", () => onDetach(data.id)),
298
- }),
459
+ backgroundThreads
460
+ ? (bodyStateOf(data.id)?.isRunning ?? false)
461
+ : itemMatchesId(data, listState, mainThreadId) &&
462
+ mainThreadClient.state.isRunning,
463
+ ),
299
464
  ),
300
465
  ),
301
466
  );
@@ -340,9 +505,6 @@ const useRemoteThreadList = (
340
505
  };
341
506
  });
342
507
 
343
- // Config updates can invoke `reload()` in the same turn as the re-render, before the effect below runs.
344
- session.adapter = adapter;
345
-
346
508
  const listState = useSyncExternalStore(
347
509
  (onStoreChange) => store.subscribe(onStoreChange),
348
510
  () => store.value,
@@ -350,15 +512,21 @@ const useRemoteThreadList = (
350
512
  );
351
513
 
352
514
  const [mainThreadId, setMainThreadId] = useState(initialMainId);
515
+ const [startedIds, setStartedIds] = useState<readonly string[]>([
516
+ initialMainId,
517
+ ]);
518
+ const [backgroundThreads] = useState(props.backgroundThreads === true);
353
519
  const assignMainThreadId = useCallback(
354
520
  (id: string) => {
355
521
  session.mainThreadId = id;
356
522
  setMainThreadId(id);
523
+ setStartedIds((prev) => (prev.includes(id) ? prev : [...prev, id]));
357
524
  },
358
525
  [session],
359
526
  );
360
527
  useThreadSelectionEvents(mainThreadId);
361
528
  useEffect(() => {
529
+ // Publishing after commit keeps imperative actions on the adapter the committed tree renders with; an abandoned render must not reach them.
362
530
  session.adapter = adapter;
363
531
  session.mainThreadId = mainThreadId;
364
532
  session.onThreadIdChange = onThreadIdChange;
@@ -390,15 +558,18 @@ const useRemoteThreadList = (
390
558
  session.loadPromise = store
391
559
  .optimisticUpdate({
392
560
  execute: () => adapter.list(),
393
- loading: (state) => ({ ...state, isLoading: true }),
561
+ loading: (state) => {
562
+ if (generation !== session.loadGeneration) return state;
563
+ return { ...state, isLoading: true };
564
+ },
394
565
  then: (state, page) => {
395
566
  if (generation !== session.loadGeneration) return state;
396
567
  session.adapterAtLoad = adapter;
397
568
  const fresh = classifyThreads(page.threads, {
398
569
  threadIds: [],
399
570
  archivedThreadIds: [],
400
- threadIdMap: {},
401
- threadData: {},
571
+ threadIdMap: { ...state.threadIdMap },
572
+ threadData: { ...state.threadData },
402
573
  });
403
574
  const merged = {
404
575
  ...state,
@@ -406,14 +577,8 @@ const useRemoteThreadList = (
406
577
  cursor: normalizeCursor(page.nextCursor),
407
578
  threadIds: fresh.threadIds,
408
579
  archivedThreadIds: fresh.archivedThreadIds,
409
- threadIdMap: {
410
- ...state.threadIdMap,
411
- ...fresh.threadIdMap,
412
- },
413
- threadData: {
414
- ...state.threadData,
415
- ...fresh.threadData,
416
- },
580
+ threadIdMap: fresh.threadIdMap,
581
+ threadData: fresh.threadData,
417
582
  };
418
583
  return preserveMidLoadTransitions(merged, state, statusAtRequest);
419
584
  },
@@ -444,6 +609,7 @@ const useRemoteThreadList = (
444
609
  const seeded = seedNewThread(EMPTY_LIST);
445
610
  store.reset({ ...seeded.state, isLoading: true });
446
611
  assignMainThreadId(seeded.id);
612
+ setStartedIds([seeded.id]);
447
613
  notifyRemoteId(undefined, true);
448
614
  } else {
449
615
  store.update({
@@ -486,7 +652,10 @@ const useRemoteThreadList = (
486
652
  const task = store
487
653
  .optimisticUpdate({
488
654
  execute: () => currentAdapter.list({ after: cursor }),
489
- loading: (state) => ({ ...state, isLoadingMore: true }),
655
+ loading: (state) => {
656
+ if (generation !== session.loadGeneration) return state;
657
+ return { ...state, isLoadingMore: true };
658
+ },
490
659
  then: (state, page) => {
491
660
  if (generation !== session.loadGeneration) return state;
492
661
  const appended = classifyThreads(page.threads, {
@@ -604,22 +773,30 @@ const useRemoteThreadList = (
604
773
  throw threadNotFoundError(threadIdOrRemoteId, "switching to it");
605
774
  }
606
775
  if (isSameThread(store.value, data.id, session.mainThreadId)) return;
607
- if (data.status === "archived" && options?.unarchive !== false) {
608
- const current = data;
776
+
777
+ const targetId = data.id;
778
+ let current: RemoteThreadData | undefined = data;
779
+
780
+ if (current.status === "archived" && options?.unarchive !== false) {
609
781
  const { remoteId } = await current.initializeTask;
610
782
  if (generation !== session.switchGeneration) return;
611
- await store.optimisticUpdate({
612
- execute: () => session.adapter.unarchive(remoteId),
613
- optimistic: (state) =>
614
- updateStatusReducer(state, current.id, "regular"),
615
- });
616
- if (generation !== session.switchGeneration) return;
617
- data = getThreadData(store.value, current.id) ?? current;
783
+ current = getThreadData(store.value, targetId);
784
+ if (current?.id !== targetId) return;
785
+ if (current.status === "archived") {
786
+ await store.optimisticUpdate({
787
+ execute: () => session.adapter.unarchive(remoteId),
788
+ optimistic: (state) =>
789
+ updateStatusReducer(state, targetId, "regular"),
790
+ });
791
+ if (generation !== session.switchGeneration) return;
792
+ current = getThreadData(store.value, targetId);
793
+ if (current?.id !== targetId) return;
794
+ }
618
795
  }
619
796
  if (generation !== session.switchGeneration) return;
620
- assignMainThreadId(data.id);
621
- notifyRemoteId(data.remoteId, emitThreadIdChange);
622
- session.onSwitchToThread?.(data.id);
797
+ assignMainThreadId(current.id);
798
+ notifyRemoteId(current.remoteId, emitThreadIdChange);
799
+ session.onSwitchToThread?.(current.id);
623
800
  }),
624
801
  [assignMainThreadId, notifyRemoteId, session, startSwitch, store],
625
802
  );
@@ -728,21 +905,36 @@ const useRemoteThreadList = (
728
905
  const data = getThreadData(state, threadId);
729
906
  if (!data) return state;
730
907
  const mappingId = createThreadMappingId(threadId);
908
+ // A list() response that landed while this initialize was in flight
909
+ // could not know the remote id yet, so it may have minted its own
910
+ // slot for it; that slot collapses into this one.
911
+ const listedMappingId = state.threadIdMap[remoteId];
912
+ const orphan =
913
+ listedMappingId !== undefined && listedMappingId !== mappingId
914
+ ? state.threadData[listedMappingId]
915
+ : undefined;
916
+
917
+ const threadData = { ...state.threadData };
918
+ if (orphan !== undefined) delete threadData[listedMappingId!];
919
+ threadData[mappingId] = {
920
+ ...data,
921
+ initializeTask: Promise.resolve({ remoteId, externalId }),
922
+ remoteId,
923
+ externalId,
924
+ } as RemoteThreadData;
925
+
926
+ const rewire = (ids: readonly string[]) =>
927
+ orphan === undefined ? ids : ids.filter((id) => id !== orphan.id);
928
+
731
929
  return {
732
930
  ...state,
931
+ threadIds: rewire(state.threadIds),
932
+ archivedThreadIds: rewire(state.archivedThreadIds),
733
933
  threadIdMap: {
734
934
  ...state.threadIdMap,
735
935
  [remoteId]: mappingId,
736
936
  },
737
- threadData: {
738
- ...state.threadData,
739
- [mappingId]: {
740
- ...data,
741
- initializeTask: Promise.resolve({ remoteId, externalId }),
742
- remoteId,
743
- externalId,
744
- },
745
- },
937
+ threadData,
746
938
  };
747
939
  },
748
940
  });
@@ -945,7 +1137,12 @@ const useRemoteThreadList = (
945
1137
  }
946
1138
  const { remoteId } = await data.initializeTask;
947
1139
  requireAdapterGeneration(adapterGeneration);
948
- if (!isSameThread(store.value, data.id, session.mainThreadId)) return;
1140
+ if (
1141
+ !backgroundThreads &&
1142
+ !isSameThread(store.value, data.id, session.mainThreadId)
1143
+ ) {
1144
+ return;
1145
+ }
949
1146
  if (!messages) return;
950
1147
  const stream = await currentAdapter.generateTitle(remoteId, messages);
951
1148
  requireAdapterGeneration(adapterGeneration);
@@ -970,13 +1167,23 @@ const useRemoteThreadList = (
970
1167
  });
971
1168
  });
972
1169
  },
973
- [requireAdapterGeneration, session, store],
1170
+ [backgroundThreads, requireAdapterGeneration, session, store],
1171
+ );
1172
+
1173
+ const detach = useCallback(
1174
+ async (threadId: string) => {
1175
+ await ensureNotMain(threadId);
1176
+ setStartedIds((prev) => prev.filter((id) => id !== threadId));
1177
+ },
1178
+ [ensureNotMain],
974
1179
  );
975
1180
 
976
1181
  const { mainThreadClient, itemOrder, threadListItems } =
977
1182
  useRemoteThreadListView({
978
1183
  listState,
979
1184
  mainThreadId,
1185
+ startedIds,
1186
+ backgroundThreads,
980
1187
  threadFactory,
981
1188
  useAdapters: adapter.unstable_useAdapters,
982
1189
  onSwitchTo: (id, options) => switchToThread(id, options),
@@ -987,7 +1194,7 @@ const useRemoteThreadList = (
987
1194
  onDelete: (id) => deleteThread(id),
988
1195
  onGenerateTitle: (id, messages) => generateTitle(id, messages),
989
1196
  onInitialize: async (id) => toInitializeResult(await initialize(id)),
990
- onDetach: (id) => ensureNotMain(id),
1197
+ onDetach: (id) => detach(id),
991
1198
  });
992
1199
 
993
1200
  const mainRemoteId = getThreadData(listState, mainThreadId)?.remoteId;
@@ -1098,6 +1305,9 @@ const useRemoteThreadList = (
1098
1305
  * and attachments come from `unstable_useAdapters`. `useRemoteThreadListRuntime`
1099
1306
  * uses the same hook when `unstable_Provider` is omitted. Key the factory
1100
1307
  * with `withKey` so history reloads when the visible thread changes.
1308
+ * With `backgroundThreads`, every visited thread stays mounted: runs continue
1309
+ * across switches, per-item `isRunning` is live, and freshly initialized
1310
+ * threads title themselves.
1101
1311
  */
1102
1312
  export const RemoteThreadList = resource(useRemoteThreadList);
1103
1313
 
@@ -16,6 +16,7 @@ import type { Tool } from "assistant-stream";
16
16
  import {
17
17
  isStandaloneToolDisplay,
18
18
  makeToolCallTextComponent,
19
+ type ToolCallText,
19
20
  type Toolkit,
20
21
  } from "../model-context/toolbox";
21
22
  import type { ToolCallMessagePartComponent } from "../types/MessagePartComponentTypes";
@@ -59,12 +60,16 @@ const useTools = ({
59
60
  (
60
61
  toolName: string,
61
62
  render: ToolCallMessagePartComponent,
62
- options?: { standalone?: boolean },
63
+ options?: {
64
+ standalone?: boolean;
65
+ renderText?: ToolCallText<any, any> | undefined;
66
+ },
63
67
  ) => {
64
68
  // One registration object per call; identity is the removal key, so
65
69
  // the per-name list stays correctly ref-counted across re-registers.
66
70
  const registration = {
67
71
  render,
72
+ renderText: options?.renderText,
68
73
  standalone: options?.standalone ?? false,
69
74
  };
70
75
 
@@ -105,6 +110,7 @@ const useTools = ({
105
110
  unsubscribes.push(
106
111
  setToolUI(toolName, render, {
107
112
  standalone: isStandaloneToolDisplay(tool),
113
+ renderText: toolRenderText,
108
114
  }),
109
115
  );
110
116
  }
@@ -235,6 +235,10 @@ export { RemoteThreadListHookInstanceManager } from "./runtimes/RemoteThreadList
235
235
  export { RemoteThreadListThreadListRuntimeCore } from "./runtimes/RemoteThreadListThreadListRuntimeCore";
236
236
  export { useRemoteThreadListRuntime } from "./runtimes/useRemoteThreadListRuntime";
237
237
  export { useCloudThreadListAdapter } from "./runtimes/cloud/useCloudThreadListAdapter";
238
+ export {
239
+ createCloudThreadListAdapter,
240
+ type CloudThreadListAdapterOptions,
241
+ } from "./runtimes/cloud/createCloudThreadListAdapter";
238
242
  export { useCloudThreadListRuntime } from "./runtimes/cloud/useCloudThreadListRuntime";
239
243
  export {
240
244
  useAssistantTransportRuntime,