@assistant-ui/core 0.3.17 → 0.3.19

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 (470) hide show
  1. package/dist/adapters/attachment.d.ts.map +1 -1
  2. package/dist/adapters/attachment.js +5 -4
  3. package/dist/adapters/attachment.js.map +1 -1
  4. package/dist/adapters/speech.d.ts.map +1 -1
  5. package/dist/adapters/speech.js +13 -3
  6. package/dist/adapters/speech.js.map +1 -1
  7. package/dist/adapters/thread-history.d.ts +4 -0
  8. package/dist/adapters/thread-history.d.ts.map +1 -1
  9. package/dist/index.d.ts +3 -3
  10. package/dist/index.js.map +1 -1
  11. package/dist/internal.d.ts +4 -3
  12. package/dist/internal.js +3 -2
  13. package/dist/model-context/frame/host.d.ts.map +1 -1
  14. package/dist/model-context/frame/host.js +35 -14
  15. package/dist/model-context/frame/host.js.map +1 -1
  16. package/dist/model-context/frame/provider.d.ts +2 -0
  17. package/dist/model-context/frame/provider.d.ts.map +1 -1
  18. package/dist/model-context/frame/provider.js +30 -7
  19. package/dist/model-context/frame/provider.js.map +1 -1
  20. package/dist/model-context/interactable-composer-metadata.d.ts.map +1 -1
  21. package/dist/model-context/interactable-composer-metadata.js +27 -18
  22. package/dist/model-context/interactable-composer-metadata.js.map +1 -1
  23. package/dist/model-context/registry.d.ts.map +1 -1
  24. package/dist/model-context/registry.js +3 -5
  25. package/dist/model-context/registry.js.map +1 -1
  26. package/dist/model-context/types.d.ts.map +1 -1
  27. package/dist/model-context/types.js +5 -4
  28. package/dist/model-context/types.js.map +1 -1
  29. package/dist/react/adapters/LocalStorageThreadListAdapter.d.ts.map +1 -1
  30. package/dist/react/adapters/LocalStorageThreadListAdapter.js +45 -7
  31. package/dist/react/adapters/LocalStorageThreadListAdapter.js.map +1 -1
  32. package/dist/react/client/DataRenderers.d.ts.map +1 -1
  33. package/dist/react/client/DataRenderers.js +20 -15
  34. package/dist/react/client/DataRenderers.js.map +1 -1
  35. package/dist/react/client/InMemoryThreadList.d.ts.map +1 -1
  36. package/dist/react/client/InMemoryThreadList.js +62 -56
  37. package/dist/react/client/InMemoryThreadList.js.map +1 -1
  38. package/dist/react/client/Interactables.d.ts.map +1 -1
  39. package/dist/react/client/Interactables.js +35 -32
  40. package/dist/react/client/Interactables.js.map +1 -1
  41. package/dist/react/client/RemoteThreadList.d.ts +1 -0
  42. package/dist/react/client/RemoteThreadList.d.ts.map +1 -1
  43. package/dist/react/client/RemoteThreadList.js +154 -143
  44. package/dist/react/client/RemoteThreadList.js.map +1 -1
  45. package/dist/react/client/Tools.d.ts.map +1 -1
  46. package/dist/react/client/Tools.js +18 -16
  47. package/dist/react/client/Tools.js.map +1 -1
  48. package/dist/react/client/interactable-model-context.d.ts.map +1 -1
  49. package/dist/react/client/interactable-model-context.js +3 -2
  50. package/dist/react/client/interactable-model-context.js.map +1 -1
  51. package/dist/react/index.d.ts +2 -2
  52. package/dist/react/index.js +2 -2
  53. package/dist/react/interactables-legacy/Interactables.js +242 -121
  54. package/dist/react/interactables-legacy/Interactables.js.map +1 -1
  55. package/dist/react/interactables-legacy/useAssistantInteractable.d.ts.map +1 -1
  56. package/dist/react/interactables-legacy/useAssistantInteractable.js +3 -0
  57. package/dist/react/interactables-legacy/useAssistantInteractable.js.map +1 -1
  58. package/dist/react/interactables-shared/useInteractablePersistenceQueue.d.ts.map +1 -1
  59. package/dist/react/interactables-shared/useInteractablePersistenceQueue.js +11 -9
  60. package/dist/react/interactables-shared/useInteractablePersistenceQueue.js.map +1 -1
  61. package/dist/react/model-context/makeAssistantTool.d.ts +2 -2
  62. package/dist/react/model-context/makeAssistantTool.js +1 -1
  63. package/dist/react/model-context/makeAssistantTool.js.map +1 -1
  64. package/dist/react/model-context/useAssistantTool.d.ts +2 -2
  65. package/dist/react/model-context/useAssistantTool.js +1 -1
  66. package/dist/react/model-context/useAssistantTool.js.map +1 -1
  67. package/dist/react/model-context/useInteractable.d.ts.map +1 -1
  68. package/dist/react/model-context/useInteractable.js +4 -1
  69. package/dist/react/model-context/useInteractable.js.map +1 -1
  70. package/dist/react/model-context/useInteractableVersions.js +1 -1
  71. package/dist/react/model-context/useToolArgsStatus.d.ts.map +1 -1
  72. package/dist/react/model-context/useToolArgsStatus.js +2 -1
  73. package/dist/react/model-context/useToolArgsStatus.js.map +1 -1
  74. package/dist/react/primitives/message/MessageGroupedParts.d.ts +11 -2
  75. package/dist/react/primitives/message/MessageGroupedParts.d.ts.map +1 -1
  76. package/dist/react/primitives/message/MessageGroupedParts.js +3 -2
  77. package/dist/react/primitives/message/MessageGroupedParts.js.map +1 -1
  78. package/dist/react/primitives/part/PartMessages.d.ts +1 -0
  79. package/dist/react/primitives/part/PartMessages.d.ts.map +1 -1
  80. package/dist/react/primitives/part/PartMessages.js +1 -0
  81. package/dist/react/primitives/part/PartMessages.js.map +1 -1
  82. package/dist/react/primitives/thread/ThreadMessages.d.ts.map +1 -1
  83. package/dist/react/primitives/thread/ThreadMessages.js +6 -5
  84. package/dist/react/primitives/thread/ThreadMessages.js.map +1 -1
  85. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts.map +1 -1
  86. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js +16 -8
  87. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js.map +1 -1
  88. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts +5 -1
  89. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
  90. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js +105 -104
  91. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js.map +1 -1
  92. package/dist/react/runtimes/RemoteThreadResource.d.ts +1 -0
  93. package/dist/react/runtimes/RemoteThreadResource.d.ts.map +1 -1
  94. package/dist/react/runtimes/RemoteThreadResource.js +13 -11
  95. package/dist/react/runtimes/RemoteThreadResource.js.map +1 -1
  96. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts +5 -24
  97. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts.map +1 -1
  98. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js +354 -226
  99. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js.map +1 -1
  100. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.d.ts +1 -0
  101. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.d.ts.map +1 -1
  102. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.js +22 -2
  103. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.js.map +1 -1
  104. package/dist/react/runtimes/cloud/auiV0.d.ts +40 -15
  105. package/dist/react/runtimes/cloud/auiV0.d.ts.map +1 -1
  106. package/dist/react/runtimes/cloud/auiV0.js +62 -15
  107. package/dist/react/runtimes/cloud/auiV0.js.map +1 -1
  108. package/dist/react/runtimes/cloud/createCloudThreadListAdapter.d.ts +2 -1
  109. package/dist/react/runtimes/cloud/createCloudThreadListAdapter.d.ts.map +1 -1
  110. package/dist/react/runtimes/cloud/createCloudThreadListAdapter.js +6 -1
  111. package/dist/react/runtimes/cloud/createCloudThreadListAdapter.js.map +1 -1
  112. package/dist/react/runtimes/cloud/sdkIdentity.d.ts +6 -0
  113. package/dist/react/runtimes/cloud/sdkIdentity.d.ts.map +1 -0
  114. package/dist/react/runtimes/cloud/sdkIdentity.js +9 -0
  115. package/dist/react/runtimes/cloud/sdkIdentity.js.map +1 -0
  116. package/dist/react/runtimes/external-message-converter.d.ts +12 -2
  117. package/dist/react/runtimes/external-message-converter.d.ts.map +1 -1
  118. package/dist/react/runtimes/external-message-converter.js +26 -61
  119. package/dist/react/runtimes/external-message-converter.js.map +1 -1
  120. package/dist/react/runtimes/useExternalStoreRuntime.js +75 -46
  121. package/dist/react/runtimes/useExternalStoreRuntime.js.map +1 -1
  122. package/dist/react/runtimes/useRemoteThreadListRuntime.d.ts.map +1 -1
  123. package/dist/react/runtimes/useRemoteThreadListRuntime.js +64 -24
  124. package/dist/react/runtimes/useRemoteThreadListRuntime.js.map +1 -1
  125. package/dist/react/utils/groupParts.d.ts +6 -1
  126. package/dist/react/utils/groupParts.d.ts.map +1 -1
  127. package/dist/react/utils/groupParts.js +6 -0
  128. package/dist/react/utils/groupParts.js.map +1 -1
  129. package/dist/react/utils/useJSONEqual.d.ts +3 -1
  130. package/dist/react/utils/useJSONEqual.d.ts.map +1 -1
  131. package/dist/react/utils/useJSONEqual.js +6 -1
  132. package/dist/react/utils/useJSONEqual.js.map +1 -1
  133. package/dist/react/utils/useJSONSchemaDependency.d.ts +7 -0
  134. package/dist/react/utils/useJSONSchemaDependency.d.ts.map +1 -0
  135. package/dist/react/utils/useJSONSchemaDependency.js +20 -0
  136. package/dist/react/utils/useJSONSchemaDependency.js.map +1 -0
  137. package/dist/runtime/api/thread-list-item-runtime.d.ts +7 -3
  138. package/dist/runtime/api/thread-list-item-runtime.d.ts.map +1 -1
  139. package/dist/runtime/api/thread-list-item-runtime.js +2 -2
  140. package/dist/runtime/api/thread-list-item-runtime.js.map +1 -1
  141. package/dist/runtime/api/thread-list-runtime.d.ts +3 -0
  142. package/dist/runtime/api/thread-list-runtime.d.ts.map +1 -1
  143. package/dist/runtime/api/thread-list-runtime.js +18 -14
  144. package/dist/runtime/api/thread-list-runtime.js.map +1 -1
  145. package/dist/runtime/api/thread-runtime.d.ts +4 -0
  146. package/dist/runtime/api/thread-runtime.d.ts.map +1 -1
  147. package/dist/runtime/api/thread-runtime.js +3 -6
  148. package/dist/runtime/api/thread-runtime.js.map +1 -1
  149. package/dist/runtime/base/base-composer-runtime-core.d.ts +1 -0
  150. package/dist/runtime/base/base-composer-runtime-core.d.ts.map +1 -1
  151. package/dist/runtime/base/base-composer-runtime-core.js +62 -22
  152. package/dist/runtime/base/base-composer-runtime-core.js.map +1 -1
  153. package/dist/runtime/base/base-thread-runtime-core.d.ts +2 -0
  154. package/dist/runtime/base/base-thread-runtime-core.d.ts.map +1 -1
  155. package/dist/runtime/base/base-thread-runtime-core.js +161 -69
  156. package/dist/runtime/base/base-thread-runtime-core.js.map +1 -1
  157. package/dist/runtime/interfaces/composer-runtime-core.d.ts +12 -5
  158. package/dist/runtime/interfaces/composer-runtime-core.d.ts.map +1 -1
  159. package/dist/runtime/interfaces/thread-list-runtime-core.d.ts +4 -1
  160. package/dist/runtime/interfaces/thread-list-runtime-core.d.ts.map +1 -1
  161. package/dist/runtime/interfaces/thread-runtime-core.d.ts +6 -0
  162. package/dist/runtime/interfaces/thread-runtime-core.d.ts.map +1 -1
  163. package/dist/runtime/queue/message-queue.d.ts +5 -0
  164. package/dist/runtime/queue/message-queue.d.ts.map +1 -1
  165. package/dist/runtime/queue/message-queue.js +61 -6
  166. package/dist/runtime/queue/message-queue.js.map +1 -1
  167. package/dist/runtime/utils/auto-status.d.ts +6 -2
  168. package/dist/runtime/utils/auto-status.d.ts.map +1 -1
  169. package/dist/runtime/utils/auto-status.js +12 -4
  170. package/dist/runtime/utils/auto-status.js.map +1 -1
  171. package/dist/runtime/utils/external-message-conversion.d.ts +16 -4
  172. package/dist/runtime/utils/external-message-conversion.d.ts.map +1 -1
  173. package/dist/runtime/utils/external-message-conversion.js +49 -13
  174. package/dist/runtime/utils/external-message-conversion.js.map +1 -1
  175. package/dist/runtime/utils/message-repository.d.ts +1 -0
  176. package/dist/runtime/utils/message-repository.d.ts.map +1 -1
  177. package/dist/runtime/utils/message-repository.js +18 -9
  178. package/dist/runtime/utils/message-repository.js.map +1 -1
  179. package/dist/runtime/utils/thread-message-like.d.ts +2 -1
  180. package/dist/runtime/utils/thread-message-like.d.ts.map +1 -1
  181. package/dist/runtime/utils/thread-message-like.js +5 -3
  182. package/dist/runtime/utils/thread-message-like.js.map +1 -1
  183. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.d.ts.map +1 -1
  184. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js +21 -27
  185. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js.map +1 -1
  186. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts.map +1 -1
  187. package/dist/runtimes/external-store/external-store-thread-runtime-core.js +8 -1
  188. package/dist/runtimes/external-store/external-store-thread-runtime-core.js.map +1 -1
  189. package/dist/runtimes/internal.d.ts +3 -3
  190. package/dist/runtimes/internal.js +2 -2
  191. package/dist/runtimes/local/local-thread-runtime-core.d.ts +1 -1
  192. package/dist/runtimes/local/local-thread-runtime-core.d.ts.map +1 -1
  193. package/dist/runtimes/local/local-thread-runtime-core.js +4 -1
  194. package/dist/runtimes/local/local-thread-runtime-core.js.map +1 -1
  195. package/dist/runtimes/remote-thread-list/remote-thread-state.d.ts +18 -1
  196. package/dist/runtimes/remote-thread-list/remote-thread-state.d.ts.map +1 -1
  197. package/dist/runtimes/remote-thread-list/remote-thread-state.js +130 -42
  198. package/dist/runtimes/remote-thread-list/remote-thread-state.js.map +1 -1
  199. package/dist/runtimes/remote-thread-list/title-generation.d.ts +49 -0
  200. package/dist/runtimes/remote-thread-list/title-generation.d.ts.map +1 -0
  201. package/dist/runtimes/remote-thread-list/title-generation.js +197 -0
  202. package/dist/runtimes/remote-thread-list/title-generation.js.map +1 -0
  203. package/dist/runtimes/remote-thread-list/title.d.ts +3 -1
  204. package/dist/runtimes/remote-thread-list/title.d.ts.map +1 -1
  205. package/dist/runtimes/remote-thread-list/title.js +9 -1
  206. package/dist/runtimes/remote-thread-list/title.js.map +1 -1
  207. package/dist/runtimes/remote-thread-list/types.d.ts +10 -0
  208. package/dist/runtimes/remote-thread-list/types.d.ts.map +1 -1
  209. package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts.map +1 -1
  210. package/dist/runtimes/tool-invocations/ToolInvocationTracker.js +2 -1
  211. package/dist/runtimes/tool-invocations/ToolInvocationTracker.js.map +1 -1
  212. package/dist/store/clients/external-thread.d.ts.map +1 -1
  213. package/dist/store/clients/external-thread.js +260 -203
  214. package/dist/store/clients/external-thread.js.map +1 -1
  215. package/dist/store/clients/model-context-client.d.ts.map +1 -1
  216. package/dist/store/clients/model-context-client.js +2 -1
  217. package/dist/store/clients/model-context-client.js.map +1 -1
  218. package/dist/store/clients/single-thread-list.d.ts.map +1 -1
  219. package/dist/store/clients/single-thread-list.js +1 -0
  220. package/dist/store/clients/single-thread-list.js.map +1 -1
  221. package/dist/store/clients/suggestions.d.ts.map +1 -1
  222. package/dist/store/clients/suggestions.js +5 -4
  223. package/dist/store/clients/suggestions.js.map +1 -1
  224. package/dist/store/clients/thread-tasks.d.ts +13 -0
  225. package/dist/store/clients/thread-tasks.d.ts.map +1 -0
  226. package/dist/store/clients/thread-tasks.js +69 -0
  227. package/dist/store/clients/thread-tasks.js.map +1 -0
  228. package/dist/store/index.d.ts +3 -2
  229. package/dist/store/index.js +3 -3
  230. package/dist/store/primitive-predicates.d.ts.map +1 -1
  231. package/dist/store/primitive-predicates.js +4 -4
  232. package/dist/store/primitive-predicates.js.map +1 -1
  233. package/dist/store/runtime-clients/composer-runtime-client.d.ts +1 -0
  234. package/dist/store/runtime-clients/composer-runtime-client.d.ts.map +1 -1
  235. package/dist/store/runtime-clients/composer-runtime-client.js +97 -61
  236. package/dist/store/runtime-clients/composer-runtime-client.js.map +1 -1
  237. package/dist/store/runtime-clients/message-runtime-client.d.ts +1 -0
  238. package/dist/store/runtime-clients/message-runtime-client.d.ts.map +1 -1
  239. package/dist/store/runtime-clients/message-runtime-client.js +221 -144
  240. package/dist/store/runtime-clients/message-runtime-client.js.map +1 -1
  241. package/dist/store/runtime-clients/thread-list-item-runtime-client.d.ts.map +1 -1
  242. package/dist/store/runtime-clients/thread-list-item-runtime-client.js +1 -1
  243. package/dist/store/runtime-clients/thread-list-item-runtime-client.js.map +1 -1
  244. package/dist/store/runtime-clients/thread-list-runtime-client.d.ts.map +1 -1
  245. package/dist/store/runtime-clients/thread-list-runtime-client.js +54 -52
  246. package/dist/store/runtime-clients/thread-list-runtime-client.js.map +1 -1
  247. package/dist/store/runtime-clients/thread-runtime-client.d.ts.map +1 -1
  248. package/dist/store/runtime-clients/thread-runtime-client.js +246 -126
  249. package/dist/store/runtime-clients/thread-runtime-client.js.map +1 -1
  250. package/dist/store/scope-registration.d.ts +2 -0
  251. package/dist/store/scope-registration.d.ts.map +1 -1
  252. package/dist/store/scopes/composer.d.ts +10 -2
  253. package/dist/store/scopes/composer.d.ts.map +1 -1
  254. package/dist/store/scopes/message.d.ts +30 -1
  255. package/dist/store/scopes/message.d.ts.map +1 -1
  256. package/dist/store/scopes/task.d.ts +36 -0
  257. package/dist/store/scopes/task.d.ts.map +1 -0
  258. package/dist/store/scopes/task.js +0 -0
  259. package/dist/store/scopes/thread-list-item.d.ts +2 -2
  260. package/dist/store/scopes/thread-list-item.d.ts.map +1 -1
  261. package/dist/store/scopes/thread.d.ts +28 -0
  262. package/dist/store/scopes/thread.d.ts.map +1 -1
  263. package/dist/store/scopes/threads.d.ts +1 -0
  264. package/dist/store/scopes/threads.d.ts.map +1 -1
  265. package/dist/subscribable/subscribable.d.ts +2 -1
  266. package/dist/subscribable/subscribable.d.ts.map +1 -1
  267. package/dist/subscribable/subscribable.js +23 -15
  268. package/dist/subscribable/subscribable.js.map +1 -1
  269. package/dist/types/attachment.d.ts +2 -1
  270. package/dist/types/attachment.d.ts.map +1 -1
  271. package/dist/types/attachment.js +2 -1
  272. package/dist/types/attachment.js.map +1 -1
  273. package/dist/types/index.d.ts +2 -2
  274. package/dist/types/message.d.ts +8 -1
  275. package/dist/types/message.d.ts.map +1 -1
  276. package/dist/types/message.js.map +1 -1
  277. package/dist/utils/abortable-iterable.d.ts +19 -0
  278. package/dist/utils/abortable-iterable.d.ts.map +1 -0
  279. package/dist/utils/abortable-iterable.js +88 -0
  280. package/dist/utils/abortable-iterable.js.map +1 -0
  281. package/dist/utils/composite-context-provider.d.ts.map +1 -1
  282. package/dist/utils/composite-context-provider.js +20 -2
  283. package/dist/utils/composite-context-provider.js.map +1 -1
  284. package/dist/utils/getGroupStatus.d.ts +18 -2
  285. package/dist/utils/getGroupStatus.d.ts.map +1 -1
  286. package/dist/utils/getGroupStatus.js +32 -7
  287. package/dist/utils/getGroupStatus.js.map +1 -1
  288. package/dist/utils/record.d.ts +11 -0
  289. package/dist/utils/record.d.ts.map +1 -0
  290. package/dist/utils/record.js +12 -0
  291. package/dist/utils/record.js.map +1 -0
  292. package/dist/utils/wire-media.d.ts.map +1 -1
  293. package/dist/utils/wire-media.js +2 -2
  294. package/dist/utils/wire-media.js.map +1 -1
  295. package/package.json +11 -11
  296. package/src/adapters/attachment.test.ts +50 -1
  297. package/src/adapters/attachment.ts +7 -4
  298. package/src/adapters/speech.test.ts +236 -0
  299. package/src/adapters/speech.ts +17 -10
  300. package/src/adapters/thread-history.ts +3 -0
  301. package/src/index.ts +2 -0
  302. package/src/internal.ts +4 -0
  303. package/src/model-context/frame/host.test.ts +137 -1
  304. package/src/model-context/frame/host.ts +49 -16
  305. package/src/model-context/frame/provider.test.ts +71 -0
  306. package/src/model-context/frame/provider.ts +37 -7
  307. package/src/model-context/interactable-composer-metadata.test.ts +58 -0
  308. package/src/model-context/interactable-composer-metadata.ts +19 -13
  309. package/src/model-context/registry.test.ts +12 -0
  310. package/src/model-context/registry.ts +3 -2
  311. package/src/model-context/types.test.ts +25 -0
  312. package/src/model-context/types.ts +9 -4
  313. package/src/react/RuntimeAdapter.test.ts +34 -0
  314. package/src/react/adapters/LocalStorageThreadListAdapter.test.ts +244 -0
  315. package/src/react/adapters/LocalStorageThreadListAdapter.tsx +104 -7
  316. package/src/react/client/DataRenderers.test.tsx +45 -0
  317. package/src/react/client/DataRenderers.ts +13 -9
  318. package/src/react/client/InMemoryThreadList.ts +1 -0
  319. package/src/react/client/Interactables.test.ts +72 -1
  320. package/src/react/client/Interactables.ts +22 -14
  321. package/src/react/client/RemoteThreadList.background.test.ts +148 -6
  322. package/src/react/client/RemoteThreadList.concurrent.test.tsx +42 -1
  323. package/src/react/client/RemoteThreadList.test.ts +386 -4
  324. package/src/react/client/RemoteThreadList.ts +181 -112
  325. package/src/react/client/Tools.ts +22 -11
  326. package/src/react/client/interactable-model-context.test.ts +44 -0
  327. package/src/react/client/interactable-model-context.ts +3 -2
  328. package/src/react/index.ts +5 -1
  329. package/src/react/interactables-legacy/Interactables.ts +16 -16
  330. package/src/react/interactables-legacy/useAssistantInteractable.test.tsx +132 -0
  331. package/src/react/interactables-legacy/useAssistantInteractable.ts +10 -1
  332. package/src/react/interactables-shared/useInteractablePersistenceQueue.ts +9 -10
  333. package/src/react/model-context/makeAssistantTool.ts +2 -2
  334. package/src/react/model-context/useAssistantTool.ts +2 -2
  335. package/src/react/model-context/useInteractable.test.tsx +177 -0
  336. package/src/react/model-context/useInteractable.ts +3 -0
  337. package/src/react/model-context/useToolArgsStatus.test.tsx +30 -0
  338. package/src/react/model-context/useToolArgsStatus.ts +2 -1
  339. package/src/react/primitive-hooks/useActionBarCopy.test.ts +0 -1
  340. package/src/react/primitive-hooks/useSuggestionTrigger.test.ts +0 -1
  341. package/src/react/primitives/message/MessageGroupedParts.test.tsx +96 -0
  342. package/src/react/primitives/message/MessageGroupedParts.tsx +15 -4
  343. package/src/react/primitives/part/PartMessages.test.tsx +104 -1
  344. package/src/react/primitives/part/PartMessages.tsx +1 -0
  345. package/src/react/primitives/thread/ThreadMessages.test.tsx +142 -0
  346. package/src/react/primitives/thread/ThreadMessages.tsx +8 -5
  347. package/src/react/providers/ReadonlyThreadProvider.test.tsx +56 -0
  348. package/src/react/runtimes/RemoteThreadListHookInstanceManager.destroy.test.tsx +172 -0
  349. package/src/react/runtimes/RemoteThreadListHookInstanceManager.running.test.tsx +33 -0
  350. package/src/react/runtimes/RemoteThreadListHookInstanceManager.test.tsx +7 -1
  351. package/src/react/runtimes/RemoteThreadListHookInstanceManager.tsx +28 -5
  352. package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.load-error.test.ts +132 -0
  353. package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.switch-delete.test.ts +105 -0
  354. package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.tsx +143 -112
  355. package/src/react/runtimes/RemoteThreadResource.test.ts +9 -0
  356. package/src/react/runtimes/RemoteThreadResource.ts +19 -12
  357. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.test.ts +20 -14
  358. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.test.tsx +703 -6
  359. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.ts +492 -402
  360. package/src/react/runtimes/cloud/CloudFileAttachmentAdapter.test.ts +77 -0
  361. package/src/react/runtimes/cloud/CloudFileAttachmentAdapter.ts +27 -1
  362. package/src/react/runtimes/cloud/auiV0.ts +160 -25
  363. package/src/react/runtimes/cloud/createCloudThreadListAdapter.test.ts +36 -0
  364. package/src/react/runtimes/cloud/createCloudThreadListAdapter.ts +8 -1
  365. package/src/react/runtimes/cloud/sdkIdentity.ts +9 -0
  366. package/src/react/runtimes/cloud/useCloudThreadListAdapter.test.tsx +18 -4
  367. package/src/react/runtimes/external-message-converter.test.ts +136 -1
  368. package/src/react/runtimes/external-message-converter.ts +39 -93
  369. package/src/react/runtimes/useExternalStoreRuntime.lifecycle.test.tsx +41 -0
  370. package/src/react/runtimes/useExternalStoreRuntime.ts +10 -4
  371. package/src/react/runtimes/useLocalRuntime.test.tsx +20 -0
  372. package/src/react/runtimes/useRemoteThreadListRuntime.load-error.test.tsx +108 -0
  373. package/src/react/runtimes/useRemoteThreadListRuntime.ts +34 -1
  374. package/src/react/utils/groupParts.ts +12 -1
  375. package/src/react/utils/useJSONEqual.ts +9 -0
  376. package/src/react/utils/useJSONSchemaDependency.ts +22 -0
  377. package/src/runtime/api/message-runtime.test.ts +75 -0
  378. package/src/runtime/api/thread-list-item-runtime.ts +10 -3
  379. package/src/runtime/api/thread-list-runtime.ts +21 -11
  380. package/src/runtime/api/thread-runtime.test.ts +136 -0
  381. package/src/runtime/api/thread-runtime.ts +10 -5
  382. package/src/runtime/base/base-composer-runtime-core.ts +105 -24
  383. package/src/runtime/base/base-thread-runtime-core.test.ts +1063 -2
  384. package/src/runtime/base/base-thread-runtime-core.ts +228 -87
  385. package/src/runtime/interfaces/composer-runtime-core.ts +10 -5
  386. package/src/runtime/interfaces/thread-list-runtime-core.ts +5 -1
  387. package/src/runtime/interfaces/thread-runtime-core.ts +6 -0
  388. package/src/runtime/queue/message-queue.ts +68 -6
  389. package/src/runtime/utils/auto-status.test.ts +112 -1
  390. package/src/runtime/utils/auto-status.ts +31 -5
  391. package/src/runtime/utils/external-message-conversion.test.ts +202 -0
  392. package/src/runtime/utils/external-message-conversion.ts +123 -32
  393. package/src/runtime/utils/message-repository.test.ts +49 -0
  394. package/src/runtime/utils/message-repository.ts +32 -20
  395. package/src/runtime/utils/thread-message-like.test.ts +52 -0
  396. package/src/runtime/utils/thread-message-like.ts +5 -1
  397. package/src/runtimes/external-store/external-store-thread-list-runtime-core.ts +18 -13
  398. package/src/runtimes/external-store/external-store-thread-runtime-core.ts +31 -1
  399. package/src/runtimes/internal.ts +1 -0
  400. package/src/runtimes/local/local-thread-runtime-core.test.ts +21 -0
  401. package/src/runtimes/local/local-thread-runtime-core.ts +11 -1
  402. package/src/runtimes/remote-thread-list/remote-thread-state.test.ts +128 -2
  403. package/src/runtimes/remote-thread-list/remote-thread-state.ts +182 -42
  404. package/src/runtimes/remote-thread-list/title-generation.test.ts +602 -0
  405. package/src/runtimes/remote-thread-list/title-generation.ts +329 -0
  406. package/src/runtimes/remote-thread-list/title.test.ts +62 -0
  407. package/src/runtimes/remote-thread-list/title.ts +13 -0
  408. package/src/runtimes/remote-thread-list/types.ts +10 -0
  409. package/src/runtimes/tool-invocations/EDGE_CASES.md +2 -6
  410. package/src/runtimes/tool-invocations/ToolInvocationTracker.test.ts +133 -0
  411. package/src/runtimes/tool-invocations/ToolInvocationTracker.ts +10 -6
  412. package/src/store/clients/external-thread.ts +67 -4
  413. package/src/store/clients/model-context-client.ts +5 -1
  414. package/src/store/clients/single-thread-list.ts +1 -0
  415. package/src/store/clients/suggestions.test.ts +40 -0
  416. package/src/store/clients/suggestions.ts +13 -10
  417. package/src/store/clients/thread-tasks.test.ts +274 -0
  418. package/src/store/clients/thread-tasks.ts +138 -0
  419. package/src/store/index.ts +8 -0
  420. package/src/store/primitive-predicates.test.ts +48 -5
  421. package/src/store/primitive-predicates.ts +7 -2
  422. package/src/store/runtime-clients/composer-runtime-client.ts +42 -9
  423. package/src/store/runtime-clients/message-runtime-client.ts +54 -6
  424. package/src/store/runtime-clients/thread-list-item-runtime-client.ts +4 -2
  425. package/src/store/runtime-clients/thread-list-runtime-client.ts +1 -0
  426. package/src/store/runtime-clients/thread-runtime-client.ts +89 -11
  427. package/src/store/scope-registration.ts +2 -0
  428. package/src/store/scopes/composer.ts +16 -4
  429. package/src/store/scopes/message.ts +14 -0
  430. package/src/store/scopes/task.ts +34 -0
  431. package/src/store/scopes/thread-list-item.ts +5 -2
  432. package/src/store/scopes/thread.ts +20 -0
  433. package/src/store/scopes/threads.ts +1 -0
  434. package/src/store/thread-tasks.test.tsx +209 -0
  435. package/src/subscribable/subscribable.test.ts +156 -1
  436. package/src/subscribable/subscribable.ts +25 -15
  437. package/src/tests/MessageRepository.test.ts +117 -5
  438. package/src/tests/OptimisticState-list-race.test.ts +1 -0
  439. package/src/tests/RemoteThreadListThreadListRuntimeCore-initialize-adapter-change.test.ts +38 -0
  440. package/src/tests/RemoteThreadListThreadListRuntimeCore-load-race.test.ts +47 -0
  441. package/src/tests/RemoteThreadListThreadListRuntimeCore-title-race.test.ts +89 -0
  442. package/src/tests/attachment-adapters.test.ts +14 -0
  443. package/src/tests/auiV0Encode.test.ts +300 -0
  444. package/src/tests/base-composer-runtime-core-send.test.ts +51 -0
  445. package/src/tests/base-composer-runtime-core.test.ts +353 -2
  446. package/src/tests/external-store-thread-list-runtime-core.test.ts +83 -0
  447. package/src/tests/external-store-thread-runtime-core-adapter.test.ts +178 -18
  448. package/src/tests/external-thread-attachments.test.tsx +208 -0
  449. package/src/tests/external-thread-parity.test.tsx +57 -0
  450. package/src/tests/groupParts.test.ts +71 -0
  451. package/src/tests/message-queue.test.ts +253 -0
  452. package/src/tests/remote-thread-list-isLoading.test.ts +1 -0
  453. package/src/tests/remote-thread-list-reactive-threadId.test.ts +51 -0
  454. package/src/tests/thread-list-runtime-getLoadThreadsPromise.test.ts +1 -0
  455. package/src/tests/thread-switch-events.test.tsx +78 -0
  456. package/src/tests/tools-scope-migration.test.tsx +28 -0
  457. package/src/tests/useRemoteThreadListRuntime-controlled.test.tsx +43 -0
  458. package/src/types/attachment.ts +4 -0
  459. package/src/types/index.ts +1 -0
  460. package/src/types/message.ts +8 -0
  461. package/src/utils/abortable-iterable.test.ts +328 -0
  462. package/src/utils/abortable-iterable.ts +104 -0
  463. package/src/utils/composite-context-provider.test.ts +25 -0
  464. package/src/utils/composite-context-provider.ts +23 -2
  465. package/src/utils/getGroupStatus.test.ts +70 -4
  466. package/src/utils/getGroupStatus.ts +35 -12
  467. package/src/utils/record.test.ts +48 -0
  468. package/src/utils/record.ts +11 -0
  469. package/src/utils/wire-media.test.ts +10 -0
  470. package/src/utils/wire-media.ts +6 -2
@@ -4,7 +4,7 @@ import { AssistantRuntimeImpl } from "../../runtime/api/assistant-runtime.js";
4
4
  import { useSubscribable } from "../../store/runtime-clients/useSubscribable.js";
5
5
  import { RemoteThreadListThreadListRuntimeCore } from "./RemoteThreadListThreadListRuntimeCore.js";
6
6
  import { c } from "@assistant-ui/tap/react-shim/compiler-runtime";
7
- import { useCallback, useEffect, useEffectEvent, useMemo, useRef, useState } from "@assistant-ui/tap/react-shim";
7
+ import { useCallback, useEffect, useEffectEvent, useInsertionEffect, useMemo, useRef, useState } from "@assistant-ui/tap/react-shim";
8
8
  import { useAui } from "@assistant-ui/store";
9
9
  //#region src/react/runtimes/useRemoteThreadListRuntime.ts
10
10
  var RemoteThreadListRuntimeCore = class extends BaseAssistantRuntimeCore {
@@ -18,7 +18,7 @@ var RemoteThreadListRuntimeCore = class extends BaseAssistantRuntimeCore {
18
18
  }
19
19
  };
20
20
  const useRemoteThreadListRuntimeImpl = (options) => {
21
- const $ = c(10);
21
+ const $ = c(18);
22
22
  let t0;
23
23
  if ($[0] !== options) {
24
24
  t0 = () => new RemoteThreadListRuntimeCore(options);
@@ -27,30 +27,70 @@ const useRemoteThreadListRuntimeImpl = (options) => {
27
27
  } else t0 = $[1];
28
28
  const [runtime] = useState(t0);
29
29
  let t1;
30
- if ($[2] !== options || $[3] !== runtime.threads) {
31
- t1 = () => {
30
+ if ($[2] !== runtime.threads) {
31
+ t1 = () => () => queueMicrotask(() => runtime.threads.__internal_dispose());
32
+ $[2] = runtime.threads;
33
+ $[3] = t1;
34
+ } else t1 = $[3];
35
+ let t2;
36
+ if ($[4] !== runtime) {
37
+ t2 = [runtime];
38
+ $[4] = runtime;
39
+ $[5] = t2;
40
+ } else t2 = $[5];
41
+ useInsertionEffect(t1, t2);
42
+ let t3;
43
+ if ($[6] !== options || $[7] !== runtime.threads) {
44
+ t3 = () => {
32
45
  runtime.threads.__internal_setOptions(options);
33
46
  runtime.threads.__internal_load();
34
47
  };
35
- $[2] = options;
36
- $[3] = runtime.threads;
37
- $[4] = t1;
38
- } else t1 = $[4];
39
- let t2;
40
- if ($[5] !== options || $[6] !== runtime) {
41
- t2 = [runtime, options];
42
- $[5] = options;
43
- $[6] = runtime;
44
- $[7] = t2;
45
- } else t2 = $[7];
46
- useEffect(t1, t2);
47
- let t3;
48
- if ($[8] !== runtime) {
49
- t3 = new AssistantRuntimeImpl(runtime);
50
- $[8] = runtime;
51
- $[9] = t3;
52
- } else t3 = $[9];
53
- return t3;
48
+ $[6] = options;
49
+ $[7] = runtime.threads;
50
+ $[8] = t3;
51
+ } else t3 = $[8];
52
+ let t4;
53
+ if ($[9] !== options || $[10] !== runtime) {
54
+ t4 = [runtime, options];
55
+ $[9] = options;
56
+ $[10] = runtime;
57
+ $[11] = t4;
58
+ } else t4 = $[11];
59
+ useEffect(t3, t4);
60
+ let t5;
61
+ if ($[12] !== runtime.threads) {
62
+ t5 = () => {
63
+ if (typeof window === "undefined" || typeof document === "undefined") return;
64
+ const reloadAfterError = () => {
65
+ if (runtime.threads.loadError !== void 0) runtime.threads.reload();
66
+ };
67
+ const reloadAfterVisible = () => {
68
+ if (document.visibilityState === "visible") reloadAfterError();
69
+ };
70
+ window.addEventListener("online", reloadAfterError);
71
+ document.addEventListener("visibilitychange", reloadAfterVisible);
72
+ return () => {
73
+ window.removeEventListener("online", reloadAfterError);
74
+ document.removeEventListener("visibilitychange", reloadAfterVisible);
75
+ };
76
+ };
77
+ $[12] = runtime.threads;
78
+ $[13] = t5;
79
+ } else t5 = $[13];
80
+ let t6;
81
+ if ($[14] !== runtime) {
82
+ t6 = [runtime];
83
+ $[14] = runtime;
84
+ $[15] = t6;
85
+ } else t6 = $[15];
86
+ useEffect(t5, t6);
87
+ let t7;
88
+ if ($[16] !== runtime) {
89
+ t7 = new AssistantRuntimeImpl(runtime);
90
+ $[16] = runtime;
91
+ $[17] = t7;
92
+ } else t7 = $[17];
93
+ return t7;
54
94
  };
55
95
  const useRemoteThreadListRuntime = (options) => {
56
96
  const [runtimeHookStore] = useState(() => new WritableSubscribable(options.runtimeHook));
@@ -66,7 +106,7 @@ const useRemoteThreadListRuntime = (options) => {
66
106
  })();
67
107
  }, [runtimeHookStore]);
68
108
  const onThreadIdChange = useEffectEvent((threadId) => {
69
- options.onThreadIdChange?.(threadId);
109
+ return options.onThreadIdChange?.(threadId);
70
110
  });
71
111
  const stableOptions = useMemo(() => ({
72
112
  adapter: options.adapter,
@@ -1 +1 @@
1
- {"version":3,"file":"useRemoteThreadListRuntime.js","names":["useState","useEffect","useMemo","useRef","useCallback","useEffectEvent","BaseAssistantRuntimeCore","AssistantRuntimeImpl","RemoteThreadListOptions","AssistantRuntimeCore","AssistantRuntime","RemoteThreadListThreadListRuntimeCore","WritableSubscribable","useSubscribable","useAui","RemoteThreadListRuntimeCore","threads","constructor","options","_contextProvider","RenderComponent","__internal_RenderComponent","useRemoteThreadListRuntimeImpl","$","_c","t0","runtime","t1","__internal_setOptions","__internal_load","t2","t3","useRemoteThreadListRuntime","runtimeHookStore","runtimeHook","setState","initialThreadIdRef","initialThreadId","stableRuntimeHook","useCommittedRuntimeHook","subscribe","getState","getServerSnapshot","onThreadIdChange","threadId","stableOptions","adapter","allowNesting","current","aui","isNested","threadListItem","source","Error"],"sources":["../../../src/react/runtimes/useRemoteThreadListRuntime.ts"],"sourcesContent":["import {\n useState,\n useEffect,\n useMemo,\n useRef,\n useCallback,\n useEffectEvent,\n} from \"react\";\nimport { BaseAssistantRuntimeCore } from \"../../runtime/base/base-assistant-runtime-core\";\nimport { AssistantRuntimeImpl } from \"../../runtime/api/assistant-runtime\";\nimport type { RemoteThreadListOptions } from \"../../runtimes/remote-thread-list/types\";\nimport type { AssistantRuntimeCore } from \"../../runtime/interfaces/assistant-runtime-core\";\nimport type { AssistantRuntime } from \"../../runtime/api/assistant-runtime\";\nimport { RemoteThreadListThreadListRuntimeCore } from \"./RemoteThreadListThreadListRuntimeCore\";\nimport { WritableSubscribable } from \"../../subscribable/subscribable\";\nimport { useSubscribable } from \"../../store/runtime-clients/useSubscribable\";\nimport { useAui } from \"@assistant-ui/store\";\n\nclass RemoteThreadListRuntimeCore\n extends BaseAssistantRuntimeCore\n implements AssistantRuntimeCore\n{\n public readonly threads;\n\n constructor(options: RemoteThreadListOptions) {\n super();\n this.threads = new RemoteThreadListThreadListRuntimeCore(\n options,\n this._contextProvider,\n );\n }\n\n public get RenderComponent() {\n return this.threads.__internal_RenderComponent;\n }\n}\n\nconst useRemoteThreadListRuntimeImpl = (\n options: RemoteThreadListOptions,\n): AssistantRuntime => {\n const [runtime] = useState(() => new RemoteThreadListRuntimeCore(options));\n useEffect(() => {\n runtime.threads.__internal_setOptions(options);\n runtime.threads.__internal_load();\n }, [runtime, options]);\n\n return useMemo(() => new AssistantRuntimeImpl(runtime), [runtime]);\n};\n\nexport const useRemoteThreadListRuntime = (\n options: RemoteThreadListOptions,\n): AssistantRuntime => {\n const [runtimeHookStore] = useState(\n () => new WritableSubscribable(options.runtimeHook),\n );\n useEffect(() => {\n runtimeHookStore.setState(options.runtimeHook);\n }, [runtimeHookStore, options.runtimeHook]);\n\n const initialThreadIdRef = useRef(options.initialThreadId);\n\n // Thread resources subscribe to the store rather than reading a ref, so a\n // hook published at commit reaches exactly the resources that use it and an\n // abandoned render publishes nothing. The store pins its server snapshot to\n // the constructor value for hydration, which tap reads on any never-mounted\n // fiber, so the live state serves as the server snapshot here.\n const stableRuntimeHook = useCallback(\n function useCommittedRuntimeHook() {\n return useSubscribable({\n subscribe: runtimeHookStore.subscribe,\n getState: runtimeHookStore.getState,\n getServerSnapshot: runtimeHookStore.getState,\n })();\n },\n [runtimeHookStore],\n );\n\n const onThreadIdChange = useEffectEvent((threadId: string | undefined) => {\n options.onThreadIdChange?.(threadId);\n });\n\n const stableOptions = useMemo<RemoteThreadListOptions>(\n () => ({\n adapter: options.adapter,\n allowNesting: options.allowNesting,\n threadId: options.threadId,\n initialThreadId: initialThreadIdRef.current,\n runtimeHook: stableRuntimeHook,\n onThreadIdChange,\n }),\n [\n options.adapter,\n options.allowNesting,\n options.threadId,\n stableRuntimeHook,\n ],\n );\n\n const aui = useAui();\n const isNested = aui.threadListItem.source !== null;\n\n if (isNested) {\n if (!stableOptions.allowNesting) {\n throw new Error(\n \"useRemoteThreadListRuntime cannot be nested inside another RemoteThreadListRuntime. \" +\n \"Set allowNesting: true to allow nesting (the inner runtime will become a no-op).\",\n );\n }\n\n // If allowNesting is true and already inside a thread list context,\n // just call the runtimeHook directly (no-op behavior)\n return options.runtimeHook();\n }\n\n const runtime = useRemoteThreadListRuntimeImpl(stableOptions);\n\n return runtime;\n};\n"],"mappings":";;;;;;;;;AAkBA,IAAMe,8BAAN,cACUT,yBAEV;CACE;CAEAW,YAAYC,SAAkC;EAC5C,MAAM;EACN,KAAKF,UAAU,IAAIL,sCACjBO,SACA,KAAKC,gBACP;CACF;CAEA,IAAWC,kBAAkB;EAC3B,OAAO,KAAKJ,QAAQK;CACtB;AACF;AAEA,MAAMC,kCAAiCJ,YAAA;CAAA,MAAAK,IAAAC,EAAA,EAAA;CAAA,IAAAC;CAAA,IAAAF,EAAA,OAAAL,SAAA;EAGVO,WAAM,IAAIV,4BAA4BG,OAAO;EAACK,EAAA,KAAAL;EAAAK,EAAA,KAAAE;CAAA,OAAAA,KAAAF,EAAA;CAAzE,MAAA,CAAAG,WAAkB1B,SAASyB,EAA8C;CAAE,IAAAE;CAAA,IAAAJ,EAAA,OAAAL,WAAAK,EAAA,OAAAG,QAAAV,SAAA;EACjEW,WAAA;GACRD,QAAOV,QAAQY,sBAAuBV,OAAO;GAC7CQ,QAAOV,QAAQa,gBAAiB;EAAC;EAClCN,EAAA,KAAAL;EAAAK,EAAA,KAAAG,QAAAV;EAAAO,EAAA,KAAAI;CAAA,OAAAA,KAAAJ,EAAA;CAAA,IAAAO;CAAA,IAAAP,EAAA,OAAAL,WAAAK,EAAA,OAAAG,SAAA;EAAEI,KAAA,CAACJ,SAASR,OAAO;EAACK,EAAA,KAAAL;EAAAK,EAAA,KAAAG;EAAAH,EAAA,KAAAO;CAAA,OAAAA,KAAAP,EAAA;CAHrBtB,UAAU0B,IAGPG,EAAkB;CAAC,IAAAC;CAAA,IAAAR,EAAA,OAAAG,SAAA;EAEDK,KAAA,IAAIxB,qBAAqBmB,OAAO;EAACH,EAAA,KAAAG;EAAAH,EAAA,KAAAQ;CAAA,OAAAA,KAAAR,EAAA;CAAA,OAAjCQ;AAAiC;AAGxD,MAAaC,8BACXd,YACqB;CACrB,MAAM,CAACe,oBAAoBjC,eACnB,IAAIY,qBAAqBM,QAAQgB,WAAW,CACpD;CACAjC,gBAAgB;EACdgC,iBAAiBE,SAASjB,QAAQgB,WAAW;CAC/C,GAAG,CAACD,kBAAkBf,QAAQgB,WAAW,CAAC;CAE1C,MAAME,qBAAqBjC,OAAOe,QAAQmB,eAAe;CAOzD,MAAMC,oBAAoBlC,YACxB,SAASmC,0BAA0B;EACjC,OAAO1B,gBAAgB;GACrB2B,WAAWP,iBAAiBO;GAC5BC,UAAUR,iBAAiBQ;GAC3BC,mBAAmBT,iBAAiBQ;EACtC,CAAC,CAAC,CAAC;CACL,GACA,CAACR,gBAAgB,CACnB;CAEA,MAAMU,mBAAmBtC,gBAAgBuC,aAAiC;EACxE1B,QAAQyB,mBAAmBC,QAAQ;CACrC,CAAC;CAED,MAAMC,gBAAgB3C,eACb;EACL4C,SAAS5B,QAAQ4B;EACjBC,cAAc7B,QAAQ6B;EACtBH,UAAU1B,QAAQ0B;EAClBP,iBAAiBD,mBAAmBY;EACpCd,aAAaI;EACbK;CACF,IACA;EACEzB,QAAQ4B;EACR5B,QAAQ6B;EACR7B,QAAQ0B;EACRN;CAAiB,CAErB;CAKA,IAHYxB,OACKmC,CAAG,CAACE,eAAeC,WAAW,MAEjC;EACZ,IAAI,CAACP,cAAcE,cACjB,MAAM,IAAIM,MACR,sKAEF;EAKF,OAAOnC,QAAQgB,YAAY;CAC7B;CAIA,OAFgBZ,+BAA+BuB,aAExCnB;AACT"}
1
+ {"version":3,"file":"useRemoteThreadListRuntime.js","names":["useState","useEffect","useInsertionEffect","useMemo","useRef","useCallback","useEffectEvent","BaseAssistantRuntimeCore","AssistantRuntimeImpl","RemoteThreadListOptions","AssistantRuntimeCore","AssistantRuntime","RemoteThreadListThreadListRuntimeCore","WritableSubscribable","useSubscribable","useAui","RemoteThreadListRuntimeCore","threads","constructor","options","_contextProvider","RenderComponent","__internal_RenderComponent","useRemoteThreadListRuntimeImpl","$","_c","t0","runtime","t1","queueMicrotask","__internal_dispose","t2","t3","__internal_setOptions","__internal_load","t4","t5","window","document","reloadAfterError","loadError","undefined","reload","reloadAfterVisible","visibilityState","addEventListener","removeEventListener","t6","t7","useRemoteThreadListRuntime","runtimeHookStore","runtimeHook","setState","initialThreadIdRef","initialThreadId","stableRuntimeHook","useCommittedRuntimeHook","subscribe","getState","getServerSnapshot","onThreadIdChange","threadId","stableOptions","adapter","allowNesting","current","aui","isNested","threadListItem","source","Error"],"sources":["../../../src/react/runtimes/useRemoteThreadListRuntime.ts"],"sourcesContent":["import {\n useState,\n useEffect,\n useInsertionEffect,\n useMemo,\n useRef,\n useCallback,\n useEffectEvent,\n} from \"react\";\nimport { BaseAssistantRuntimeCore } from \"../../runtime/base/base-assistant-runtime-core\";\nimport { AssistantRuntimeImpl } from \"../../runtime/api/assistant-runtime\";\nimport type { RemoteThreadListOptions } from \"../../runtimes/remote-thread-list/types\";\nimport type { AssistantRuntimeCore } from \"../../runtime/interfaces/assistant-runtime-core\";\nimport type { AssistantRuntime } from \"../../runtime/api/assistant-runtime\";\nimport { RemoteThreadListThreadListRuntimeCore } from \"./RemoteThreadListThreadListRuntimeCore\";\nimport { WritableSubscribable } from \"../../subscribable/subscribable\";\nimport { useSubscribable } from \"../../store/runtime-clients/useSubscribable\";\nimport { useAui } from \"@assistant-ui/store\";\n\nclass RemoteThreadListRuntimeCore\n extends BaseAssistantRuntimeCore\n implements AssistantRuntimeCore\n{\n public readonly threads;\n\n constructor(options: RemoteThreadListOptions) {\n super();\n this.threads = new RemoteThreadListThreadListRuntimeCore(\n options,\n this._contextProvider,\n );\n }\n\n public get RenderComponent() {\n return this.threads.__internal_RenderComponent;\n }\n}\n\nconst useRemoteThreadListRuntimeImpl = (\n options: RemoteThreadListOptions,\n): AssistantRuntime => {\n const [runtime] = useState(() => new RemoteThreadListRuntimeCore(options));\n\n // Insertion-effect cleanup runs only when React deletes the fiber, so a\n // hidden <Activity> or a re-suspended boundary keeps the threads alive; the\n // disposal is deferred to a microtask because it notifies subscribers and\n // React forbids scheduling updates from an insertion effect.\n useInsertionEffect(\n () => () => queueMicrotask(() => runtime.threads.__internal_dispose()),\n [runtime],\n );\n\n useEffect(() => {\n runtime.threads.__internal_setOptions(options);\n runtime.threads.__internal_load();\n }, [runtime, options]);\n\n useEffect(() => {\n if (typeof window === \"undefined\" || typeof document === \"undefined\") {\n return;\n }\n\n const reloadAfterError = () => {\n if (runtime.threads.loadError !== undefined) {\n void runtime.threads.reload();\n }\n };\n const reloadAfterVisible = () => {\n if (document.visibilityState === \"visible\") reloadAfterError();\n };\n\n window.addEventListener(\"online\", reloadAfterError);\n document.addEventListener(\"visibilitychange\", reloadAfterVisible);\n return () => {\n window.removeEventListener(\"online\", reloadAfterError);\n document.removeEventListener(\"visibilitychange\", reloadAfterVisible);\n };\n }, [runtime]);\n\n return useMemo(() => new AssistantRuntimeImpl(runtime), [runtime]);\n};\n\nexport const useRemoteThreadListRuntime = (\n options: RemoteThreadListOptions,\n): AssistantRuntime => {\n const [runtimeHookStore] = useState(\n () => new WritableSubscribable(options.runtimeHook),\n );\n useEffect(() => {\n runtimeHookStore.setState(options.runtimeHook);\n }, [runtimeHookStore, options.runtimeHook]);\n\n const initialThreadIdRef = useRef(options.initialThreadId);\n\n // Thread resources subscribe to the store rather than reading a ref, so a\n // hook published at commit reaches exactly the resources that use it and an\n // abandoned render publishes nothing. The store pins its server snapshot to\n // the constructor value for hydration, which tap reads on any never-mounted\n // fiber, so the live state serves as the server snapshot here.\n const stableRuntimeHook = useCallback(\n function useCommittedRuntimeHook() {\n return useSubscribable({\n subscribe: runtimeHookStore.subscribe,\n getState: runtimeHookStore.getState,\n getServerSnapshot: runtimeHookStore.getState,\n })();\n },\n [runtimeHookStore],\n );\n\n const onThreadIdChange = useEffectEvent((threadId: string | undefined) => {\n return options.onThreadIdChange?.(threadId);\n });\n\n const stableOptions = useMemo<RemoteThreadListOptions>(\n () => ({\n adapter: options.adapter,\n allowNesting: options.allowNesting,\n threadId: options.threadId,\n initialThreadId: initialThreadIdRef.current,\n runtimeHook: stableRuntimeHook,\n onThreadIdChange,\n }),\n [\n options.adapter,\n options.allowNesting,\n options.threadId,\n stableRuntimeHook,\n ],\n );\n\n const aui = useAui();\n const isNested = aui.threadListItem.source !== null;\n\n if (isNested) {\n if (!stableOptions.allowNesting) {\n throw new Error(\n \"useRemoteThreadListRuntime cannot be nested inside another RemoteThreadListRuntime. \" +\n \"Set allowNesting: true to allow nesting (the inner runtime will become a no-op).\",\n );\n }\n\n // If allowNesting is true and already inside a thread list context,\n // just call the runtimeHook directly (no-op behavior)\n return options.runtimeHook();\n }\n\n const runtime = useRemoteThreadListRuntimeImpl(stableOptions);\n\n return runtime;\n};\n"],"mappings":"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"}
@@ -41,8 +41,10 @@ declare const GROUPBY_MEMO_KEY: unique symbol;
41
41
  * `display: "standalone"`). Resolving the registry-driven cases reads the
42
42
  * {@link GroupByContext} passed to the `groupBy` function. Takes precedence
43
43
  * over the `"tool-call"` entry.
44
+ *
45
+ * A `"tool-call:<name>"` entry matches tool calls by tool name and takes precedence over the plain `"tool-call"` entry, while `"standalone-tool-call"` still wins first.
44
46
  */
45
- type GroupPartType = PartState["type"] | "standalone-tool-call";
47
+ type GroupPartType = PartState["type"] | "standalone-tool-call" | `tool-call:${string}`;
46
48
  /**
47
49
  * Build a `groupBy` from a `part.type → group-key path` lookup.
48
50
  * Parts whose type isn't in the map are left ungrouped. The returned
@@ -56,11 +58,14 @@ type GroupPartType = PartState["type"] | "standalone-tool-call";
56
58
  * {@link GroupByContext} that `<MessagePrimitive.GroupedParts>` passes to the
57
59
  * `groupBy` function — the helper needs nothing threaded into it.
58
60
  *
61
+ * A `"tool-call:<name>"` entry matches tool calls by tool name and takes precedence over the plain `"tool-call"` entry, while `"standalone-tool-call"` still wins first.
62
+ *
59
63
  * @example
60
64
  * ```tsx
61
65
  * <MessagePrimitive.GroupedParts
62
66
  * groupBy={groupPartByType({
63
67
  * reasoning: ["group-thought", "group-reasoning"],
68
+ * "tool-call:task": ["group-subagents"],
64
69
  * "tool-call": ["group-thought", "group-tool"],
65
70
  * "standalone-tool-call": [],
66
71
  * })}
@@ -1 +1 @@
1
- {"version":3,"file":"groupParts.d.ts","names":[],"sources":["../../../src/react/utils/groupParts.ts"],"mappings":";;;;;;;;;KAUY;;WAED,UAAU;;;;;;;;;;;;;;;;;;;;cAsBR;;;;;;;;;;;;;KAgBR,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;cA4BR,kBAAmB,gCAC9B,KAAK,QAAQ,SAAS,OAAO,wBAAwB,gBAClD,MAAM,WAAW,UAAU,4BAA4B;KA2BhD,YAAY,iBAAiB;UAExB;WACN;;WAEA;;WAEA;;;;;WAKA;;WAEA;WACA,mBAAmB;;UAGb;WACN;;WAEA;;WAEA;;;;;WAKA;;;;;;;;;cAiCE,iBACX,uCACA,uDACU"}
1
+ {"version":3,"file":"groupParts.d.ts","names":[],"sources":["../../../src/react/utils/groupParts.ts"],"mappings":";;;;;;;;;KAUY;;WAED,UAAU;;;;;;;;;;;;;;;;;;;;cAsBR;;;;;;;;;;;;;;;KAkBR,gBACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAiCS,kBAAmB,gCAC9B,KAAK,QAAQ,SAAS,OAAO,wBAAwB,gBAClD,MAAM,WAAW,UAAU,4BAA4B;KA8BhD,YAAY,iBAAiB;UAExB;WACN;;WAEA;;WAEA;;;;;WAKA;;WAEA;WACA,mBAAmB;;UAGb;WACN;;WAEA;;WAEA;;;;;WAKA;;;;;;;;;cAiCE,iBACX,uCACA,uDACU"}
@@ -32,11 +32,14 @@ const GROUPBY_MEMO_KEY = Symbol.for("@assistant-ui/groupBy.memoKey");
32
32
  * {@link GroupByContext} that `<MessagePrimitive.GroupedParts>` passes to the
33
33
  * `groupBy` function — the helper needs nothing threaded into it.
34
34
  *
35
+ * A `"tool-call:<name>"` entry matches tool calls by tool name and takes precedence over the plain `"tool-call"` entry, while `"standalone-tool-call"` still wins first.
36
+ *
35
37
  * @example
36
38
  * ```tsx
37
39
  * <MessagePrimitive.GroupedParts
38
40
  * groupBy={groupPartByType({
39
41
  * reasoning: ["group-thought", "group-reasoning"],
42
+ * "tool-call:task": ["group-subagents"],
40
43
  * "tool-call": ["group-thought", "group-tool"],
41
44
  * "standalone-tool-call": [],
42
45
  * })}
@@ -50,6 +53,9 @@ const groupPartByType = (map) => {
50
53
  const fn = ((part, context) => {
51
54
  if (part.type === "tool-call") {
52
55
  if ((isMcpAppUri(part.mcp?.app?.resourceUri) || (context?.toolUIs?.[part.toolName]?.[0]?.standalone ?? false)) && lookup["standalone-tool-call"] !== void 0) return lookup["standalone-tool-call"];
56
+ const toolCallPath = lookup[`tool-call:${part.toolName}`];
57
+ if (toolCallPath !== void 0) return toolCallPath;
58
+ return lookup["tool-call"] ?? [];
53
59
  }
54
60
  return lookup[part.type] ?? [];
55
61
  });
@@ -1 +1 @@
1
- {"version":3,"file":"groupParts.js","names":["isMcpAppUri","PartState","ToolsState","GroupByContext","toolUIs","GROUPBY_MEMO_KEY","Symbol","for","GroupPartType","groupPartByType","map","Partial","Readonly","Record","TKey","part","context","lookup","fn","type","isMcpApp","mcp","app","resourceUri","isStandalone","toolName","standalone","undefined","sortedKeys","Object","keys","sort","sortedEntries","k","JSON","stringify","GroupNode","GroupNodeGroup","GroupNodePart","key","nodeKey","idKey","indices","children","index","BuildFrame","nextChildIdx","claimed","Set","makeChildNodeKey","parent","idx","String","claimIdKey","frame","id","has","add","buildGroupTree","paths","partIds","root","stack","closeTop","closing","pop","length","push","i","path","common","top","s"],"sources":["../../../src/react/utils/groupParts.ts"],"sourcesContent":["import { isMcpAppUri } from \"../../types/message\";\nimport type { PartState } from \"../../store/scopes/part\";\nimport type { ToolsState } from \"../types/scopes/tools\";\n\n/**\n * Registry context passed to a `groupBy` function as its second argument by\n * `<MessagePrimitive.GroupedParts>`. Carries the live tool-UI registry so a\n * `groupBy` can resolve registry-driven grouping (e.g. standalone tool calls)\n * without the part itself having to carry that information.\n */\nexport type GroupByContext = {\n /** Tool UIs registered in the tool-UI registry, keyed by tool name. */\n readonly toolUIs?: ToolsState[\"toolUIs\"];\n};\n\n/**\n * Hierarchical adjacent-coalescing grouping for message parts.\n *\n * Given a group path per part (from `groupBy`), builds a tree of group\n * nodes wrapping individual parts. Adjacent parts sharing a path prefix\n * coalesce into the same group; ungrouped parts are direct children of\n * the root.\n *\n * Each node gets a structural `nodeKey` built from sibling indices\n * (`\"0.1.0\"`), stable under append-only streaming.\n */\n\n/**\n * Symbol attached to memoizable `groupBy` functions (e.g. those returned\n * by {@link groupPartByType}). Carries a string fingerprint of the config\n * so `MessagePrimitive.GroupedParts` can memo the tree on\n * `[parts, memoKey]` across renders — even when the helper call site\n * reconstructs the function each render.\n */\nexport const GROUPBY_MEMO_KEY: unique symbol = Symbol.for(\n \"@assistant-ui/groupBy.memoKey\",\n);\n\n/**\n * Synthetic part-type keys recognized by {@link groupPartByType}, in\n * addition to real {@link PartState} types:\n *\n * - `\"standalone-tool-call\"` — a tool-call whose UI should be presented on its\n * own, outside the chain-of-thought grouping. Matches MCP-app tool calls plus\n * any tool-call whose registered UI opts into standalone display (human\n * tools, the built-in generative-UI tool, and tools that set\n * `display: \"standalone\"`). Resolving the registry-driven cases reads the\n * {@link GroupByContext} passed to the `groupBy` function. Takes precedence\n * over the `\"tool-call\"` entry.\n */\ntype GroupPartType = PartState[\"type\"] | \"standalone-tool-call\";\n\n/**\n * Build a `groupBy` from a `part.type → group-key path` lookup.\n * Parts whose type isn't in the map are left ungrouped. The returned\n * function carries a stable {@link GROUPBY_MEMO_KEY} fingerprint so\n * `<MessagePrimitive.GroupedParts>` can memoize its tree across renders.\n *\n * The synthetic `\"standalone-tool-call\"` key matches tool calls that should\n * render outside the chain-of-thought grouping. MCP-app calls are detected from\n * the part alone; the registry-driven cases (human tools, the generative-UI\n * tool, `display: \"standalone\"` opt-ins) are resolved from the\n * {@link GroupByContext} that `<MessagePrimitive.GroupedParts>` passes to the\n * `groupBy` function — the helper needs nothing threaded into it.\n *\n * @example\n * ```tsx\n * <MessagePrimitive.GroupedParts\n * groupBy={groupPartByType({\n * reasoning: [\"group-thought\", \"group-reasoning\"],\n * \"tool-call\": [\"group-thought\", \"group-tool\"],\n * \"standalone-tool-call\": [],\n * })}\n * >\n * {({ part, children }) => { ... }}\n * </MessagePrimitive.GroupedParts>\n * ```\n */\nexport const groupPartByType = <TKey extends `group-${string}`>(\n map: Partial<Readonly<Record<GroupPartType, readonly TKey[]>>>,\n): ((part: PartState, context?: GroupByContext) => readonly TKey[]) => {\n const lookup = map as Readonly<Record<string, readonly TKey[] | undefined>>;\n const fn = ((part, context) => {\n if (part.type === \"tool-call\") {\n const isMcpApp = isMcpAppUri(part.mcp?.app?.resourceUri);\n // Read the first registration's flag — the same one `resolveToolRender`\n // renders — so grouping and rendering never disagree for a tool name.\n const isStandalone =\n isMcpApp ||\n (context?.toolUIs?.[part.toolName]?.[0]?.standalone ?? false);\n if (isStandalone && lookup[\"standalone-tool-call\"] !== undefined) {\n return lookup[\"standalone-tool-call\"]!;\n }\n }\n return lookup[part.type] ?? [];\n }) as ((part: PartState, context?: GroupByContext) => readonly TKey[]) & {\n [GROUPBY_MEMO_KEY]?: string;\n };\n // Sort keys so the fingerprint is insensitive to map insertion order —\n // two maps with the same key/value pairs but different declaration order\n // would otherwise hash differently and invalidate the memo unnecessarily.\n const sortedKeys = Object.keys(map).sort();\n const sortedEntries = sortedKeys.map((k) => [k, map[k as keyof typeof map]]);\n fn[GROUPBY_MEMO_KEY] = `groupPartByType:${JSON.stringify(sortedEntries)}`;\n return fn;\n};\n\nexport type GroupNode = GroupNodeGroup | GroupNodePart;\n\nexport interface GroupNodeGroup {\n readonly type: \"group\";\n /** Current-level group key (last segment of the path). */\n readonly key: string;\n /** Structural React key: sibling-index path, e.g. `\"0.1.0\"`. */\n readonly nodeKey: string;\n /**\n * Identity key (`\"id:<partId>\"`) from the group's first part; undefined\n * when absent or already claimed by an earlier sibling.\n */\n readonly idKey: string | undefined;\n /** Indices of parts in this subtree, in order. */\n readonly indices: readonly number[];\n readonly children: readonly GroupNode[];\n}\n\nexport interface GroupNodePart {\n readonly type: \"part\";\n /** Index of the part in the message. */\n readonly index: number;\n /** Structural React key: sibling-index path within parent. */\n readonly nodeKey: string;\n /**\n * Identity key (`\"id:<partId>\"`); undefined when absent or already\n * claimed by an earlier sibling.\n */\n readonly idKey: string | undefined;\n}\n\ninterface BuildFrame {\n key: string;\n nodeKey: string;\n indices: number[];\n children: GroupNode[];\n nextChildIdx: number;\n claimed: Set<string>;\n}\n\nconst makeChildNodeKey = (parent: BuildFrame): string => {\n const idx = parent.nextChildIdx++;\n return parent.nodeKey === \"\" ? String(idx) : `${parent.nodeKey}.${idx}`;\n};\n\nconst claimIdKey = (\n frame: BuildFrame,\n id: string | undefined,\n): string | undefined => {\n if (id === undefined || frame.claimed.has(id)) return undefined;\n frame.claimed.add(id);\n return `id:${id}`;\n};\n\n/**\n * Build the group tree from an array of normalized group paths.\n * `paths[i]` is the path for part `i`. The output tree contains one\n * `part` node per part and one `group` node per coalesced run.\n * `partIds[i]` optionally carries a stable identity for part `i` (e.g. a\n * tool call id), from which nodes derive an `idKey`.\n */\nexport const buildGroupTree = (\n paths: readonly (readonly string[])[],\n partIds?: readonly (string | undefined)[],\n): readonly GroupNode[] => {\n const root: BuildFrame = {\n key: \"\",\n nodeKey: \"\",\n indices: [],\n children: [],\n nextChildIdx: 0,\n claimed: new Set(),\n };\n const stack: BuildFrame[] = [root];\n\n const closeTop = (): void => {\n const closing = stack.pop()!;\n const parent = stack[stack.length - 1]!;\n parent.children.push({\n type: \"group\",\n key: closing.key,\n nodeKey: closing.nodeKey,\n idKey: claimIdKey(parent, partIds?.[closing.indices[0]!]),\n indices: closing.indices,\n children: closing.children,\n });\n };\n\n for (let i = 0; i < paths.length; i++) {\n const path = paths[i]!;\n\n // Find the longest prefix shared between currently-open groups\n // (excluding root) and this part's path.\n let common = 0;\n while (\n common < stack.length - 1 &&\n common < path.length &&\n stack[common + 1]!.key === path[common]\n ) {\n common++;\n }\n\n // Close groups not on this path.\n while (stack.length - 1 > common) {\n closeTop();\n }\n\n // Open new groups down to the part's depth.\n while (stack.length - 1 < path.length) {\n const parent = stack[stack.length - 1]!;\n stack.push({\n key: path[stack.length - 1]!,\n nodeKey: makeChildNodeKey(parent),\n indices: [],\n children: [],\n nextChildIdx: 0,\n claimed: new Set(),\n });\n }\n\n // Push this part as a leaf in the deepest open group (or root).\n const top = stack[stack.length - 1]!;\n top.children.push({\n type: \"part\",\n index: i,\n nodeKey: makeChildNodeKey(top),\n idKey: claimIdKey(top, partIds?.[i]),\n });\n\n // Record the part index in every open ancestor group.\n for (let s = 1; s < stack.length; s++) {\n stack[s]!.indices.push(i);\n }\n }\n\n // Close any still-open groups.\n while (stack.length > 1) {\n closeTop();\n }\n\n return root.children;\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"groupParts.js","names":["isMcpAppUri","PartState","ToolsState","GroupByContext","toolUIs","GROUPBY_MEMO_KEY","Symbol","for","GroupPartType","groupPartByType","map","Partial","Readonly","Record","TKey","part","context","lookup","fn","type","isMcpApp","mcp","app","resourceUri","isStandalone","toolName","standalone","undefined","toolCallPath","sortedKeys","Object","keys","sort","sortedEntries","k","JSON","stringify","GroupNode","GroupNodeGroup","GroupNodePart","key","nodeKey","idKey","indices","children","index","BuildFrame","nextChildIdx","claimed","Set","makeChildNodeKey","parent","idx","String","claimIdKey","frame","id","has","add","buildGroupTree","paths","partIds","root","stack","closeTop","closing","pop","length","push","i","path","common","top","s"],"sources":["../../../src/react/utils/groupParts.ts"],"sourcesContent":["import { isMcpAppUri } from \"../../types/message\";\nimport type { PartState } from \"../../store/scopes/part\";\nimport type { ToolsState } from \"../types/scopes/tools\";\n\n/**\n * Registry context passed to a `groupBy` function as its second argument by\n * `<MessagePrimitive.GroupedParts>`. Carries the live tool-UI registry so a\n * `groupBy` can resolve registry-driven grouping (e.g. standalone tool calls)\n * without the part itself having to carry that information.\n */\nexport type GroupByContext = {\n /** Tool UIs registered in the tool-UI registry, keyed by tool name. */\n readonly toolUIs?: ToolsState[\"toolUIs\"];\n};\n\n/**\n * Hierarchical adjacent-coalescing grouping for message parts.\n *\n * Given a group path per part (from `groupBy`), builds a tree of group\n * nodes wrapping individual parts. Adjacent parts sharing a path prefix\n * coalesce into the same group; ungrouped parts are direct children of\n * the root.\n *\n * Each node gets a structural `nodeKey` built from sibling indices\n * (`\"0.1.0\"`), stable under append-only streaming.\n */\n\n/**\n * Symbol attached to memoizable `groupBy` functions (e.g. those returned\n * by {@link groupPartByType}). Carries a string fingerprint of the config\n * so `MessagePrimitive.GroupedParts` can memo the tree on\n * `[parts, memoKey]` across renders — even when the helper call site\n * reconstructs the function each render.\n */\nexport const GROUPBY_MEMO_KEY: unique symbol = Symbol.for(\n \"@assistant-ui/groupBy.memoKey\",\n);\n\n/**\n * Synthetic part-type keys recognized by {@link groupPartByType}, in\n * addition to real {@link PartState} types:\n *\n * - `\"standalone-tool-call\"` — a tool-call whose UI should be presented on its\n * own, outside the chain-of-thought grouping. Matches MCP-app tool calls plus\n * any tool-call whose registered UI opts into standalone display (human\n * tools, the built-in generative-UI tool, and tools that set\n * `display: \"standalone\"`). Resolving the registry-driven cases reads the\n * {@link GroupByContext} passed to the `groupBy` function. Takes precedence\n * over the `\"tool-call\"` entry.\n *\n * A `\"tool-call:<name>\"` entry matches tool calls by tool name and takes precedence over the plain `\"tool-call\"` entry, while `\"standalone-tool-call\"` still wins first.\n */\ntype GroupPartType =\n | PartState[\"type\"]\n | \"standalone-tool-call\"\n | `tool-call:${string}`;\n\n/**\n * Build a `groupBy` from a `part.type → group-key path` lookup.\n * Parts whose type isn't in the map are left ungrouped. The returned\n * function carries a stable {@link GROUPBY_MEMO_KEY} fingerprint so\n * `<MessagePrimitive.GroupedParts>` can memoize its tree across renders.\n *\n * The synthetic `\"standalone-tool-call\"` key matches tool calls that should\n * render outside the chain-of-thought grouping. MCP-app calls are detected from\n * the part alone; the registry-driven cases (human tools, the generative-UI\n * tool, `display: \"standalone\"` opt-ins) are resolved from the\n * {@link GroupByContext} that `<MessagePrimitive.GroupedParts>` passes to the\n * `groupBy` function — the helper needs nothing threaded into it.\n *\n * A `\"tool-call:<name>\"` entry matches tool calls by tool name and takes precedence over the plain `\"tool-call\"` entry, while `\"standalone-tool-call\"` still wins first.\n *\n * @example\n * ```tsx\n * <MessagePrimitive.GroupedParts\n * groupBy={groupPartByType({\n * reasoning: [\"group-thought\", \"group-reasoning\"],\n * \"tool-call:task\": [\"group-subagents\"],\n * \"tool-call\": [\"group-thought\", \"group-tool\"],\n * \"standalone-tool-call\": [],\n * })}\n * >\n * {({ part, children }) => { ... }}\n * </MessagePrimitive.GroupedParts>\n * ```\n */\nexport const groupPartByType = <TKey extends `group-${string}`>(\n map: Partial<Readonly<Record<GroupPartType, readonly TKey[]>>>,\n): ((part: PartState, context?: GroupByContext) => readonly TKey[]) => {\n const lookup = map as Readonly<Record<string, readonly TKey[] | undefined>>;\n const fn = ((part, context) => {\n if (part.type === \"tool-call\") {\n const isMcpApp = isMcpAppUri(part.mcp?.app?.resourceUri);\n // Read the first registration's flag — the same one `resolveToolRender`\n // renders — so grouping and rendering never disagree for a tool name.\n const isStandalone =\n isMcpApp ||\n (context?.toolUIs?.[part.toolName]?.[0]?.standalone ?? false);\n if (isStandalone && lookup[\"standalone-tool-call\"] !== undefined) {\n return lookup[\"standalone-tool-call\"]!;\n }\n const toolCallPath = lookup[`tool-call:${part.toolName}`];\n if (toolCallPath !== undefined) return toolCallPath;\n return lookup[\"tool-call\"] ?? [];\n }\n return lookup[part.type] ?? [];\n }) as ((part: PartState, context?: GroupByContext) => readonly TKey[]) & {\n [GROUPBY_MEMO_KEY]?: string;\n };\n // Sort keys so the fingerprint is insensitive to map insertion order —\n // two maps with the same key/value pairs but different declaration order\n // would otherwise hash differently and invalidate the memo unnecessarily.\n const sortedKeys = Object.keys(map).sort();\n const sortedEntries = sortedKeys.map((k) => [k, map[k as keyof typeof map]]);\n fn[GROUPBY_MEMO_KEY] = `groupPartByType:${JSON.stringify(sortedEntries)}`;\n return fn;\n};\n\nexport type GroupNode = GroupNodeGroup | GroupNodePart;\n\nexport interface GroupNodeGroup {\n readonly type: \"group\";\n /** Current-level group key (last segment of the path). */\n readonly key: string;\n /** Structural React key: sibling-index path, e.g. `\"0.1.0\"`. */\n readonly nodeKey: string;\n /**\n * Identity key (`\"id:<partId>\"`) from the group's first part; undefined\n * when absent or already claimed by an earlier sibling.\n */\n readonly idKey: string | undefined;\n /** Indices of parts in this subtree, in order. */\n readonly indices: readonly number[];\n readonly children: readonly GroupNode[];\n}\n\nexport interface GroupNodePart {\n readonly type: \"part\";\n /** Index of the part in the message. */\n readonly index: number;\n /** Structural React key: sibling-index path within parent. */\n readonly nodeKey: string;\n /**\n * Identity key (`\"id:<partId>\"`); undefined when absent or already\n * claimed by an earlier sibling.\n */\n readonly idKey: string | undefined;\n}\n\ninterface BuildFrame {\n key: string;\n nodeKey: string;\n indices: number[];\n children: GroupNode[];\n nextChildIdx: number;\n claimed: Set<string>;\n}\n\nconst makeChildNodeKey = (parent: BuildFrame): string => {\n const idx = parent.nextChildIdx++;\n return parent.nodeKey === \"\" ? String(idx) : `${parent.nodeKey}.${idx}`;\n};\n\nconst claimIdKey = (\n frame: BuildFrame,\n id: string | undefined,\n): string | undefined => {\n if (id === undefined || frame.claimed.has(id)) return undefined;\n frame.claimed.add(id);\n return `id:${id}`;\n};\n\n/**\n * Build the group tree from an array of normalized group paths.\n * `paths[i]` is the path for part `i`. The output tree contains one\n * `part` node per part and one `group` node per coalesced run.\n * `partIds[i]` optionally carries a stable identity for part `i` (e.g. a\n * tool call id), from which nodes derive an `idKey`.\n */\nexport const buildGroupTree = (\n paths: readonly (readonly string[])[],\n partIds?: readonly (string | undefined)[],\n): readonly GroupNode[] => {\n const root: BuildFrame = {\n key: \"\",\n nodeKey: \"\",\n indices: [],\n children: [],\n nextChildIdx: 0,\n claimed: new Set(),\n };\n const stack: BuildFrame[] = [root];\n\n const closeTop = (): void => {\n const closing = stack.pop()!;\n const parent = stack[stack.length - 1]!;\n parent.children.push({\n type: \"group\",\n key: closing.key,\n nodeKey: closing.nodeKey,\n idKey: claimIdKey(parent, partIds?.[closing.indices[0]!]),\n indices: closing.indices,\n children: closing.children,\n });\n };\n\n for (let i = 0; i < paths.length; i++) {\n const path = paths[i]!;\n\n // Find the longest prefix shared between currently-open groups\n // (excluding root) and this part's path.\n let common = 0;\n while (\n common < stack.length - 1 &&\n common < path.length &&\n stack[common + 1]!.key === path[common]\n ) {\n common++;\n }\n\n // Close groups not on this path.\n while (stack.length - 1 > common) {\n closeTop();\n }\n\n // Open new groups down to the part's depth.\n while (stack.length - 1 < path.length) {\n const parent = stack[stack.length - 1]!;\n stack.push({\n key: path[stack.length - 1]!,\n nodeKey: makeChildNodeKey(parent),\n indices: [],\n children: [],\n nextChildIdx: 0,\n claimed: new Set(),\n });\n }\n\n // Push this part as a leaf in the deepest open group (or root).\n const top = stack[stack.length - 1]!;\n top.children.push({\n type: \"part\",\n index: i,\n nodeKey: makeChildNodeKey(top),\n idKey: claimIdKey(top, partIds?.[i]),\n });\n\n // Record the part index in every open ancestor group.\n for (let s = 1; s < stack.length; s++) {\n stack[s]!.indices.push(i);\n }\n }\n\n // Close any still-open groups.\n while (stack.length > 1) {\n closeTop();\n }\n\n return root.children;\n};\n"],"mappings":"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"}
@@ -1,4 +1,6 @@
1
+ import { ReadonlyJSONValue } from "assistant-stream/utils";
1
2
  //#region src/react/utils/useJSONEqual.d.ts
3
+ declare function useJSONEqualValue<T extends ReadonlyJSONValue>(value: T): T;
2
4
  /**
3
5
  * Like `useShallow`, but with JSON deep-equality. Use when a selector derives an
4
6
  * equal-but-fresh value on every store update — e.g. folding over
@@ -7,5 +9,5 @@
7
9
  */
8
10
  declare function useJSONEqual<S, U>(selector: (state: S) => U): (state: S) => U;
9
11
  //#endregion
10
- export { useJSONEqual };
12
+ export { useJSONEqual, useJSONEqualValue };
11
13
  //# sourceMappingURL=useJSONEqual.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useJSONEqual.d.ts","names":[],"sources":["../../../src/react/utils/useJSONEqual.ts"],"mappings":";;;;;;;iBASgB,aAAa,GAAG,GAAG,WAAW,OAAO,MAAM,KAAK,OAAO,MAAM"}
1
+ {"version":3,"file":"useJSONEqual.d.ts","names":[],"sources":["../../../src/react/utils/useJSONEqual.ts"],"mappings":";;iBAIgB,kBAAkB,UAAU,mBAAmB,OAAO,IAAI;;;;;;;iBAc1D,aAAa,GAAG,GAAG,WAAW,OAAO,MAAM,KAAK,OAAO,MAAM"}
@@ -2,6 +2,11 @@ import { isJSONValueEqual } from "../../utils/json/is-json-equal.js";
2
2
  import { c } from "@assistant-ui/tap/react-shim/compiler-runtime";
3
3
  import { useRef } from "@assistant-ui/tap/react-shim";
4
4
  //#region src/react/utils/useJSONEqual.ts
5
+ function useJSONEqualValue(value) {
6
+ const prev = useRef(value);
7
+ if (prev.current !== value && !isJSONValueEqual(prev.current, value)) prev.current = value;
8
+ return prev.current;
9
+ }
5
10
  /**
6
11
  * Like `useShallow`, but with JSON deep-equality. Use when a selector derives an
7
12
  * equal-but-fresh value on every store update — e.g. folding over
@@ -25,6 +30,6 @@ function useJSONEqual(selector) {
25
30
  return t0;
26
31
  }
27
32
  //#endregion
28
- export { useJSONEqual };
33
+ export { useJSONEqual, useJSONEqualValue };
29
34
 
30
35
  //# sourceMappingURL=useJSONEqual.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useJSONEqual.js","names":["useRef","isJSONValueEqual","useJSONEqual","selector","$","_c","prev","undefined","t0","state","next","current"],"sources":["../../../src/react/utils/useJSONEqual.ts"],"sourcesContent":["import { useRef } from \"react\";\nimport { isJSONValueEqual } from \"../../utils/json/is-json-equal\";\n\n/**\n * Like `useShallow`, but with JSON deep-equality. Use when a selector derives an\n * equal-but-fresh value on every store update — e.g. folding over\n * `thread.messages`, whose identity changes on every streaming token — where a\n * shallow compare would re-render regardless.\n */\nexport function useJSONEqual<S, U>(selector: (state: S) => U): (state: S) => U {\n const prev = useRef<U | undefined>(undefined);\n return (state) => {\n const next = selector(state);\n if (prev.current !== undefined && isJSONValueEqual(prev.current, next)) {\n return prev.current;\n }\n prev.current = next;\n return next;\n };\n}\n"],"mappings":";;;;;;;;;;AASA,SAAOE,aAAAC,UAAA;CAAA,MAAAC,IAAAC,EAAA,CAAA;CACL,MAAAC,OAAaN,OAAsBO,KAAAA,CAAS;CAAE,IAAAC;CAAA,IAAAJ,EAAA,OAAAD,UAAA;EACvCK,MAAAC,UAAA;GACL,MAAAC,OAAaP,SAASM,KAAK;GAC3B,IAAIH,KAAIK,YAAaJ,KAAAA,KAAaN,iBAAiBK,KAAIK,SAAUD,IAAI,GAAC,OAC7DJ,KAAIK;GAEbL,KAAIK,UAAWD;GAAH,OACLA;EAAI;EACZN,EAAA,KAAAD;EAAAC,EAAA,KAAAI;CAAA,OAAAA,KAAAJ,EAAA;CAAA,OAPMI;AAON"}
1
+ {"version":3,"file":"useJSONEqual.js","names":["useRef","ReadonlyJSONValue","isJSONValueEqual","useJSONEqualValue","value","T","prev","current","useJSONEqual","selector","$","_c","undefined","t0","state","next"],"sources":["../../../src/react/utils/useJSONEqual.ts"],"sourcesContent":["import { useRef } from \"react\";\nimport type { ReadonlyJSONValue } from \"assistant-stream/utils\";\nimport { isJSONValueEqual } from \"../../utils/json/is-json-equal\";\n\nexport function useJSONEqualValue<T extends ReadonlyJSONValue>(value: T): T {\n const prev = useRef(value);\n if (prev.current !== value && !isJSONValueEqual(prev.current, value)) {\n prev.current = value;\n }\n return prev.current;\n}\n\n/**\n * Like `useShallow`, but with JSON deep-equality. Use when a selector derives an\n * equal-but-fresh value on every store update — e.g. folding over\n * `thread.messages`, whose identity changes on every streaming token — where a\n * shallow compare would re-render regardless.\n */\nexport function useJSONEqual<S, U>(selector: (state: S) => U): (state: S) => U {\n const prev = useRef<U | undefined>(undefined);\n return (state) => {\n const next = selector(state);\n if (prev.current !== undefined && isJSONValueEqual(prev.current, next)) {\n return prev.current;\n }\n prev.current = next;\n return next;\n };\n}\n"],"mappings":";;;;AAIA,SAAgBG,kBAA+CC,OAAa;CAC1E,MAAME,OAAON,OAAOI,KAAK;CACzB,IAAIE,KAAKC,YAAYH,SAAS,CAACF,iBAAiBI,KAAKC,SAASH,KAAK,GACjEE,KAAKC,UAAUH;CAEjB,OAAOE,KAAKC;AACd;;;;;;;AAQA,SAAOC,aAAAC,UAAA;CAAA,MAAAC,IAAAC,EAAA,CAAA;CACL,MAAAL,OAAaN,OAAsBY,KAAAA,CAAS;CAAE,IAAAC;CAAA,IAAAH,EAAA,OAAAD,UAAA;EACvCI,MAAAC,UAAA;GACL,MAAAC,OAAaN,SAASK,KAAK;GAC3B,IAAIR,KAAIC,YAAaK,KAAAA,KAAaV,iBAAiBI,KAAIC,SAAUQ,IAAI,GAAC,OAC7DT,KAAIC;GAEbD,KAAIC,UAAWQ;GAAH,OACLA;EAAI;EACZL,EAAA,KAAAD;EAAAC,EAAA,KAAAG;CAAA,OAAAA,KAAAH,EAAA;CAAA,OAPMG;AAON"}
@@ -0,0 +1,7 @@
1
+ import { Unstable_InteractableStateSchema } from "../types/scopes/interactables.js";
2
+ import { ReadonlyJSONValue } from "assistant-stream/utils";
3
+ //#region src/react/utils/useJSONSchemaDependency.d.ts
4
+ declare function useJSONSchemaDependency(schema: Unstable_InteractableStateSchema): ReadonlyJSONValue;
5
+ //#endregion
6
+ export { useJSONSchemaDependency };
7
+ //# sourceMappingURL=useJSONSchemaDependency.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useJSONSchemaDependency.d.ts","names":[],"sources":["../../../src/react/utils/useJSONSchemaDependency.ts"],"mappings":";;;iBAOgB,wBACd,QAAQ,mCACP"}
@@ -0,0 +1,20 @@
1
+ import { isJSONValue } from "../../utils/json/is-json.js";
2
+ import { useJSONEqualValue } from "./useJSONEqual.js";
3
+ import { toJSONSchema } from "assistant-stream";
4
+ import { useMemo } from "@assistant-ui/tap/react-shim";
5
+ //#region src/react/utils/useJSONSchemaDependency.ts
6
+ function useJSONSchemaDependency(schema) {
7
+ const normalizedSchema = useMemo(() => {
8
+ try {
9
+ const jsonSchema = toJSONSchema(schema);
10
+ return isJSONValue(jsonSchema) ? jsonSchema : null;
11
+ } catch {
12
+ return null;
13
+ }
14
+ }, [schema]);
15
+ return useJSONEqualValue(normalizedSchema);
16
+ }
17
+ //#endregion
18
+ export { useJSONSchemaDependency };
19
+
20
+ //# sourceMappingURL=useJSONSchemaDependency.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useJSONSchemaDependency.js","names":["useMemo","toJSONSchema","ReadonlyJSONValue","isJSONValue","Unstable_InteractableStateSchema","useJSONEqualValue","useJSONSchemaDependency","schema","normalizedSchema","jsonSchema"],"sources":["../../../src/react/utils/useJSONSchemaDependency.ts"],"sourcesContent":["import { useMemo } from \"react\";\nimport { toJSONSchema } from \"assistant-stream\";\nimport type { ReadonlyJSONValue } from \"assistant-stream/utils\";\nimport { isJSONValue } from \"../../utils/json/is-json\";\nimport type { Unstable_InteractableStateSchema } from \"../types/scopes/interactables\";\nimport { useJSONEqualValue } from \"./useJSONEqual\";\n\nexport function useJSONSchemaDependency(\n schema: Unstable_InteractableStateSchema,\n): ReadonlyJSONValue {\n const normalizedSchema = useMemo(() => {\n try {\n const jsonSchema = toJSONSchema(schema);\n return isJSONValue(jsonSchema) ? jsonSchema : null;\n } catch {\n // Opaque schemas share one fallback so rebuilt instances do not churn registration.\n return null;\n }\n }, [schema]);\n\n return useJSONEqualValue(normalizedSchema);\n}\n"],"mappings":";;;;;AAOA,SAAgBM,wBACdC,QACmB;CACnB,MAAMC,mBAAmBR,cAAc;EACrC,IAAI;GACF,MAAMS,aAAaR,aAAaM,MAAM;GACtC,OAAOJ,YAAYM,UAAU,IAAIA,aAAa;EAChD,QAAQ;GAEN,OAAO;EACT;CACF,GAAG,CAACF,MAAM,CAAC;CAEX,OAAOF,kBAAkBG,gBAAgB;AAC3C"}
@@ -21,6 +21,10 @@ type ThreadListItemEventPayload = {
21
21
  };
22
22
  type ThreadListItemEventType = keyof ThreadListItemEventPayload;
23
23
  type ThreadListItemEventCallback<E extends ThreadListItemEventType> = (payload: ThreadListItemEventPayload[E]) => void;
24
+ type ThreadListItemGenerateTitleOptions = {
25
+ /** Marks a generation started by the automatic title trigger. */
26
+ automatic?: boolean;
27
+ };
24
28
  type ThreadListItemRuntime = {
25
29
  readonly path: ThreadListItemRuntimePath;
26
30
  getState(): ThreadListItemState;
@@ -28,7 +32,7 @@ type ThreadListItemRuntime = {
28
32
  remoteId: string;
29
33
  externalId: string | undefined;
30
34
  }>;
31
- generateTitle(): Promise<void>;
35
+ generateTitle(options?: ThreadListItemGenerateTitleOptions): Promise<void>;
32
36
  switchTo(options?: {
33
37
  unarchive?: boolean;
34
38
  }): Promise<void>;
@@ -62,12 +66,12 @@ declare class ThreadListItemRuntimeImpl implements ThreadListItemRuntime {
62
66
  remoteId: string;
63
67
  externalId: string | undefined;
64
68
  }>;
65
- generateTitle(): Promise<void>;
69
+ generateTitle(options?: ThreadListItemGenerateTitleOptions): Promise<void>;
66
70
  unstable_on<E extends ThreadListItemEventType>(event: E, callback: ThreadListItemEventCallback<E>): Unsubscribe;
67
71
  subscribe(callback: () => void): Unsubscribe;
68
72
  detach(): void;
69
73
  __internal_getRuntime(): ThreadListItemRuntime;
70
74
  }
71
75
  //#endregion
72
- export { ThreadListItemEventCallback, ThreadListItemEventPayload, ThreadListItemEventType, ThreadListItemRuntime, ThreadListItemRuntimeImpl, type ThreadListItemState, ThreadListItemStateBinding, type ThreadListItemStatus };
76
+ export { ThreadListItemEventCallback, ThreadListItemEventPayload, ThreadListItemEventType, ThreadListItemGenerateTitleOptions, ThreadListItemRuntime, ThreadListItemRuntimeImpl, type ThreadListItemState, ThreadListItemStateBinding, type ThreadListItemStatus };
73
77
  //# sourceMappingURL=thread-list-item-runtime.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"thread-list-item-runtime.d.ts","names":[],"sources":["../../../src/runtime/api/thread-list-item-runtime.ts"],"mappings":";;;;;;;KAMY;;;;;;EAMV,YAAY;;;;;;EAMZ,cAAc;;KAGJ,gCAAgC;KAEhC,4BAA4B,UAAU,4BAChD,SAAS,2BAA2B;KAQ1B;WACD,MAAM;EACf,YAAY;EAEZ,cAAc;IAAU;IAAkB;;EAC1C,iBAAiB;EAEjB,SAAS;IAAY;MAAwB;EAC7C,OAAO,mBAAmB;EAC1B,aAAa,QAAQ,sCAAsC;EAC3D,WAAW;EACX,aAAa;EACb,UAAU;EAEV;EAEA,UAAU,uBAAuB;EAEjC,YAAY,UAAU,yBACpB,OAAO,GACP,UAAU,4BAA4B,KACrC;EAEH,yBAAyB;;KAGf,6BAA6B,sBACvC,qBACA;cAGW,qCAAqC;MACrC,QAAI;UAIP;UACA;EAGN,YAAA,OAAO,4BACP,oBAAoB;YAOZ;EAeH,YAAY;EAIZ,SAAS;IAAY;MAAwB;EAK7C,OAAO,mBAAmB;EAM1B,aACL,QAAQ,sCACP;EAWI,WAAW;EAMX,aAAa;EAMb,UAAU;EAMV,cAAc;IACnB;IACA;;EAMK,iBAAiB;EAKjB,YAAY,UAAU,yBAC3B,OAAO,GACP,UAAU,4BAA4B,KAAE;EAsBnC,UAAU,uBAAuB;EAIjC;EAMA,yBAAyB"}
1
+ {"version":3,"file":"thread-list-item-runtime.d.ts","names":[],"sources":["../../../src/runtime/api/thread-list-item-runtime.ts"],"mappings":";;;;;;;KAMY;;;;;;EAMV,YAAY;;;;;;EAMZ,cAAc;;KAGJ,gCAAgC;KAEhC,4BAA4B,UAAU,4BAChD,SAAS,2BAA2B;KAQ1B;;EAEV;;KAGU;WACD,MAAM;EACf,YAAY;EAEZ,cAAc;IAAU;IAAkB;;EAC1C,cAAc,UAAU,qCAAqC;EAE7D,SAAS;IAAY;MAAwB;EAC7C,OAAO,mBAAmB;EAC1B,aAAa,QAAQ,sCAAsC;EAC3D,WAAW;EACX,aAAa;EACb,UAAU;EAEV;EAEA,UAAU,uBAAuB;EAEjC,YAAY,UAAU,yBACpB,OAAO,GACP,UAAU,4BAA4B,KACrC;EAEH,yBAAyB;;KAGf,6BAA6B,sBACvC,qBACA;cAGW,qCAAqC;MACrC,QAAI;UAIP;UACA;EAGN,YAAA,OAAO,4BACP,oBAAoB;YAOZ;EAeH,YAAY;EAIZ,SAAS;IAAY;MAAwB;EAK7C,OAAO,mBAAmB;EAM1B,aACL,QAAQ,sCACP;EAWI,WAAW;EAMX,aAAa;EAMb,UAAU;EAMV,cAAc;IACnB;IACA;;EAMK,cACL,UAAU,qCACT;EAKI,YAAY,UAAU,yBAC3B,OAAO,GACP,UAAU,4BAA4B,KAAE;EAsBnC,UAAU,uBAAuB;EAIjC;EAMA,yBAAyB"}
@@ -57,9 +57,9 @@ var ThreadListItemRuntimeImpl = class {
57
57
  const state = this._core.getState();
58
58
  return this._threadListBinding.initialize(state.id);
59
59
  }
60
- generateTitle() {
60
+ generateTitle(options) {
61
61
  const state = this._core.getState();
62
- return this._threadListBinding.generateTitle(state.id);
62
+ return this._threadListBinding.generateTitle(state.id, options);
63
63
  }
64
64
  unstable_on(event, callback) {
65
65
  let prevIsMain = this._core.getState().isMain;
@@ -1 +1 @@
1
- {"version":3,"file":"thread-list-item-runtime.js","names":["Unsubscribe","SubscribableWithState","ThreadListItemRuntimePath","ThreadListRuntimeCoreBinding","notifyEventListeners","ThreadListItemEventPayload","switchedTo","Record","switchedAway","ThreadListItemEventType","ThreadListItemEventCallback","payload","E","ThreadListItemState","ThreadListItemStatus","ThreadListItemRuntime","path","getState","initialize","Promise","remoteId","externalId","generateTitle","switchTo","options","unarchive","rename","newTitle","updateCustom","custom","archive","delete","detach","subscribe","callback","unstable_on","event","__internal_getRuntime","ThreadListItemStateBinding","ThreadListItemRuntimeImpl","_core","_threadListBinding","constructor","__internal_bindMethods","bind","state","switchToThread","id","Error","prevIsMain","isMain","prevThreadId","currentState","newIsMain","newThreadId"],"sources":["../../../src/runtime/api/thread-list-item-runtime.ts"],"sourcesContent":["import type { Unsubscribe } from \"../../types/unsubscribe\";\nimport type { SubscribableWithState } from \"../../subscribable/subscribable\";\nimport type { ThreadListItemRuntimePath } from \"./paths\";\nimport type { ThreadListRuntimeCoreBinding } from \"./thread-list-runtime\";\nimport { notifyEventListeners } from \"../../utils/notify-event-listeners\";\n\nexport type ThreadListItemEventPayload = {\n /**\n * @deprecated State-derivable. Compare `s.threads.mainThreadId` against the\n * item's `s.threadListItem.id` via `useAuiState` instead. Kept for backward\n * compatibility.\n */\n switchedTo: Record<string, never>;\n /**\n * @deprecated State-derivable. Compare `s.threads.mainThreadId` against the\n * item's `s.threadListItem.id` via `useAuiState` instead. Kept for backward\n * compatibility.\n */\n switchedAway: Record<string, never>;\n};\n\nexport type ThreadListItemEventType = keyof ThreadListItemEventPayload;\n\nexport type ThreadListItemEventCallback<E extends ThreadListItemEventType> = (\n payload: ThreadListItemEventPayload[E],\n) => void;\n\nimport type { ThreadListItemState } from \"./bindings\";\nimport type { ThreadListItemStatus } from \"../interfaces/thread-list-runtime-core\";\n\nexport type { ThreadListItemState, ThreadListItemStatus };\n\nexport type ThreadListItemRuntime = {\n readonly path: ThreadListItemRuntimePath;\n getState(): ThreadListItemState;\n\n initialize(): Promise<{ remoteId: string; externalId: string | undefined }>;\n generateTitle(): Promise<void>;\n\n switchTo(options?: { unarchive?: boolean }): Promise<void>;\n rename(newTitle: string): Promise<void>;\n updateCustom(custom: Record<string, unknown> | undefined): Promise<void>;\n archive(): Promise<void>;\n unarchive(): Promise<void>;\n delete(): Promise<void>;\n\n detach(): void;\n\n subscribe(callback: () => void): Unsubscribe;\n\n unstable_on<E extends ThreadListItemEventType>(\n event: E,\n callback: ThreadListItemEventCallback<E>,\n ): Unsubscribe;\n\n __internal_getRuntime(): ThreadListItemRuntime;\n};\n\nexport type ThreadListItemStateBinding = SubscribableWithState<\n ThreadListItemState,\n ThreadListItemRuntimePath\n>;\n\nexport class ThreadListItemRuntimeImpl implements ThreadListItemRuntime {\n public get path() {\n return this._core.path;\n }\n\n private _core: ThreadListItemStateBinding;\n private _threadListBinding: ThreadListRuntimeCoreBinding;\n\n constructor(\n _core: ThreadListItemStateBinding,\n _threadListBinding: ThreadListRuntimeCoreBinding,\n ) {\n this._core = _core;\n this._threadListBinding = _threadListBinding;\n this.__internal_bindMethods();\n }\n\n protected __internal_bindMethods() {\n this.switchTo = this.switchTo.bind(this);\n this.rename = this.rename.bind(this);\n this.updateCustom = this.updateCustom.bind(this);\n this.archive = this.archive.bind(this);\n this.unarchive = this.unarchive.bind(this);\n this.delete = this.delete.bind(this);\n this.initialize = this.initialize.bind(this);\n this.generateTitle = this.generateTitle.bind(this);\n this.subscribe = this.subscribe.bind(this);\n this.unstable_on = this.unstable_on.bind(this);\n this.getState = this.getState.bind(this);\n this.detach = this.detach.bind(this);\n }\n\n public getState(): ThreadListItemState {\n return this._core.getState();\n }\n\n public switchTo(options?: { unarchive?: boolean }): Promise<void> {\n const state = this._core.getState();\n return this._threadListBinding.switchToThread(state.id, options);\n }\n\n public rename(newTitle: string): Promise<void> {\n const state = this._core.getState();\n\n return this._threadListBinding.rename(state.id, newTitle);\n }\n\n public updateCustom(\n custom: Record<string, unknown> | undefined,\n ): Promise<void> {\n const state = this._core.getState();\n if (!this._threadListBinding.updateCustom) {\n throw new Error(\n \"Thread list runtime does not support updating custom metadata\",\n );\n }\n\n return this._threadListBinding.updateCustom(state.id, custom);\n }\n\n public archive(): Promise<void> {\n const state = this._core.getState();\n\n return this._threadListBinding.archive(state.id);\n }\n\n public unarchive(): Promise<void> {\n const state = this._core.getState();\n\n return this._threadListBinding.unarchive(state.id);\n }\n\n public delete(): Promise<void> {\n const state = this._core.getState();\n\n return this._threadListBinding.delete(state.id);\n }\n\n public initialize(): Promise<{\n remoteId: string;\n externalId: string | undefined;\n }> {\n const state = this._core.getState();\n return this._threadListBinding.initialize(state.id);\n }\n\n public generateTitle(): Promise<void> {\n const state = this._core.getState();\n return this._threadListBinding.generateTitle(state.id);\n }\n\n public unstable_on<E extends ThreadListItemEventType>(\n event: E,\n callback: ThreadListItemEventCallback<E>,\n ) {\n let prevIsMain = this._core.getState().isMain;\n let prevThreadId = this._core.getState().id;\n return this.subscribe(() => {\n const currentState = this._core.getState();\n const newIsMain = currentState.isMain;\n const newThreadId = currentState.id;\n if (prevIsMain === newIsMain && prevThreadId === newThreadId) return;\n prevIsMain = newIsMain;\n prevThreadId = newThreadId;\n\n if (event === \"switchedTo\" && !newIsMain) return;\n if (event === \"switchedAway\" && newIsMain) return;\n notifyEventListeners(\n [callback as (payload?: unknown) => void],\n {},\n `Thread list item \"${event}\"`,\n );\n });\n }\n\n public subscribe(callback: () => void): Unsubscribe {\n return this._core.subscribe(callback);\n }\n\n public detach(): void {\n const state = this._core.getState();\n\n this._threadListBinding.detach(state.id);\n }\n\n public __internal_getRuntime(): ThreadListItemRuntime {\n return this;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"thread-list-item-runtime.js","names":["Unsubscribe","SubscribableWithState","ThreadListItemRuntimePath","ThreadListRuntimeCoreBinding","notifyEventListeners","ThreadListItemEventPayload","switchedTo","Record","switchedAway","ThreadListItemEventType","ThreadListItemEventCallback","payload","E","ThreadListItemState","ThreadListItemStatus","ThreadListItemGenerateTitleOptions","automatic","ThreadListItemRuntime","path","getState","initialize","Promise","remoteId","externalId","generateTitle","options","switchTo","unarchive","rename","newTitle","updateCustom","custom","archive","delete","detach","subscribe","callback","unstable_on","event","__internal_getRuntime","ThreadListItemStateBinding","ThreadListItemRuntimeImpl","_core","_threadListBinding","constructor","__internal_bindMethods","bind","state","switchToThread","id","Error","prevIsMain","isMain","prevThreadId","currentState","newIsMain","newThreadId"],"sources":["../../../src/runtime/api/thread-list-item-runtime.ts"],"sourcesContent":["import type { Unsubscribe } from \"../../types/unsubscribe\";\nimport type { SubscribableWithState } from \"../../subscribable/subscribable\";\nimport type { ThreadListItemRuntimePath } from \"./paths\";\nimport type { ThreadListRuntimeCoreBinding } from \"./thread-list-runtime\";\nimport { notifyEventListeners } from \"../../utils/notify-event-listeners\";\n\nexport type ThreadListItemEventPayload = {\n /**\n * @deprecated State-derivable. Compare `s.threads.mainThreadId` against the\n * item's `s.threadListItem.id` via `useAuiState` instead. Kept for backward\n * compatibility.\n */\n switchedTo: Record<string, never>;\n /**\n * @deprecated State-derivable. Compare `s.threads.mainThreadId` against the\n * item's `s.threadListItem.id` via `useAuiState` instead. Kept for backward\n * compatibility.\n */\n switchedAway: Record<string, never>;\n};\n\nexport type ThreadListItemEventType = keyof ThreadListItemEventPayload;\n\nexport type ThreadListItemEventCallback<E extends ThreadListItemEventType> = (\n payload: ThreadListItemEventPayload[E],\n) => void;\n\nimport type { ThreadListItemState } from \"./bindings\";\nimport type { ThreadListItemStatus } from \"../interfaces/thread-list-runtime-core\";\n\nexport type { ThreadListItemState, ThreadListItemStatus };\n\nexport type ThreadListItemGenerateTitleOptions = {\n /** Marks a generation started by the automatic title trigger. */\n automatic?: boolean;\n};\n\nexport type ThreadListItemRuntime = {\n readonly path: ThreadListItemRuntimePath;\n getState(): ThreadListItemState;\n\n initialize(): Promise<{ remoteId: string; externalId: string | undefined }>;\n generateTitle(options?: ThreadListItemGenerateTitleOptions): Promise<void>;\n\n switchTo(options?: { unarchive?: boolean }): Promise<void>;\n rename(newTitle: string): Promise<void>;\n updateCustom(custom: Record<string, unknown> | undefined): Promise<void>;\n archive(): Promise<void>;\n unarchive(): Promise<void>;\n delete(): Promise<void>;\n\n detach(): void;\n\n subscribe(callback: () => void): Unsubscribe;\n\n unstable_on<E extends ThreadListItemEventType>(\n event: E,\n callback: ThreadListItemEventCallback<E>,\n ): Unsubscribe;\n\n __internal_getRuntime(): ThreadListItemRuntime;\n};\n\nexport type ThreadListItemStateBinding = SubscribableWithState<\n ThreadListItemState,\n ThreadListItemRuntimePath\n>;\n\nexport class ThreadListItemRuntimeImpl implements ThreadListItemRuntime {\n public get path() {\n return this._core.path;\n }\n\n private _core: ThreadListItemStateBinding;\n private _threadListBinding: ThreadListRuntimeCoreBinding;\n\n constructor(\n _core: ThreadListItemStateBinding,\n _threadListBinding: ThreadListRuntimeCoreBinding,\n ) {\n this._core = _core;\n this._threadListBinding = _threadListBinding;\n this.__internal_bindMethods();\n }\n\n protected __internal_bindMethods() {\n this.switchTo = this.switchTo.bind(this);\n this.rename = this.rename.bind(this);\n this.updateCustom = this.updateCustom.bind(this);\n this.archive = this.archive.bind(this);\n this.unarchive = this.unarchive.bind(this);\n this.delete = this.delete.bind(this);\n this.initialize = this.initialize.bind(this);\n this.generateTitle = this.generateTitle.bind(this);\n this.subscribe = this.subscribe.bind(this);\n this.unstable_on = this.unstable_on.bind(this);\n this.getState = this.getState.bind(this);\n this.detach = this.detach.bind(this);\n }\n\n public getState(): ThreadListItemState {\n return this._core.getState();\n }\n\n public switchTo(options?: { unarchive?: boolean }): Promise<void> {\n const state = this._core.getState();\n return this._threadListBinding.switchToThread(state.id, options);\n }\n\n public rename(newTitle: string): Promise<void> {\n const state = this._core.getState();\n\n return this._threadListBinding.rename(state.id, newTitle);\n }\n\n public updateCustom(\n custom: Record<string, unknown> | undefined,\n ): Promise<void> {\n const state = this._core.getState();\n if (!this._threadListBinding.updateCustom) {\n throw new Error(\n \"Thread list runtime does not support updating custom metadata\",\n );\n }\n\n return this._threadListBinding.updateCustom(state.id, custom);\n }\n\n public archive(): Promise<void> {\n const state = this._core.getState();\n\n return this._threadListBinding.archive(state.id);\n }\n\n public unarchive(): Promise<void> {\n const state = this._core.getState();\n\n return this._threadListBinding.unarchive(state.id);\n }\n\n public delete(): Promise<void> {\n const state = this._core.getState();\n\n return this._threadListBinding.delete(state.id);\n }\n\n public initialize(): Promise<{\n remoteId: string;\n externalId: string | undefined;\n }> {\n const state = this._core.getState();\n return this._threadListBinding.initialize(state.id);\n }\n\n public generateTitle(\n options?: ThreadListItemGenerateTitleOptions,\n ): Promise<void> {\n const state = this._core.getState();\n return this._threadListBinding.generateTitle(state.id, options);\n }\n\n public unstable_on<E extends ThreadListItemEventType>(\n event: E,\n callback: ThreadListItemEventCallback<E>,\n ) {\n let prevIsMain = this._core.getState().isMain;\n let prevThreadId = this._core.getState().id;\n return this.subscribe(() => {\n const currentState = this._core.getState();\n const newIsMain = currentState.isMain;\n const newThreadId = currentState.id;\n if (prevIsMain === newIsMain && prevThreadId === newThreadId) return;\n prevIsMain = newIsMain;\n prevThreadId = newThreadId;\n\n if (event === \"switchedTo\" && !newIsMain) return;\n if (event === \"switchedAway\" && newIsMain) return;\n notifyEventListeners(\n [callback as (payload?: unknown) => void],\n {},\n `Thread list item \"${event}\"`,\n );\n });\n }\n\n public subscribe(callback: () => void): Unsubscribe {\n return this._core.subscribe(callback);\n }\n\n public detach(): void {\n const state = this._core.getState();\n\n this._threadListBinding.detach(state.id);\n }\n\n public __internal_getRuntime(): ThreadListItemRuntime {\n return this;\n }\n}\n"],"mappings":"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"}
@@ -10,6 +10,8 @@ type ThreadListState = {
10
10
  readonly threadIds: readonly string[];
11
11
  readonly archivedThreadIds: readonly string[];
12
12
  readonly isLoading: boolean;
13
+ /** The error thrown by the most recent thread list load that failed, cleared when a later load starts. */
14
+ readonly loadError: unknown;
13
15
  readonly isLoadingMore: boolean;
14
16
  readonly hasMore: boolean;
15
17
  readonly threadItems: Readonly<Record<string, Omit<ThreadListItemState, "isMain" | "threadId" | "isRunning">>>;
@@ -72,6 +74,7 @@ declare class ThreadListRuntimeImpl implements ThreadListRuntime {
72
74
  private _mainThreadListItemRuntime;
73
75
  readonly main: ThreadRuntime;
74
76
  get mainItem(): ThreadListItemRuntimeImpl;
77
+ private _createItemStateBinding;
75
78
  getById(threadId: string): ThreadRuntime;
76
79
  getItemByIndex(idx: number): ThreadListItemRuntimeImpl;
77
80
  getArchivedItemByIndex(idx: number): ThreadListItemRuntimeImpl;
@@ -1 +1 @@
1
- {"version":3,"file":"thread-list-runtime.d.ts","names":[],"sources":["../../../src/runtime/api/thread-list-runtime.ts"],"mappings":";;;;;;KA4BY;WACD;WACA;WACA;WACA;WACA;WACA;WACA;WACA,aAAa,SACpB,eAEE,KAAK;;KAKC;EACV,YAAY;EAEZ,UAAU,uBAAuB;WAExB,MAAM;EACf,QAAQ,mBAAmB;WAElB,UAAU;EACnB,YAAY,mBAAmB;EAC/B,eAAe,cAAc;EAC7B,uBAAuB,cAAc;EAErC,eACE,kBACA;IAAY;MACX;EACH,qBAAqB;;;;;;;EAQrB,+BACE,WAAW,OAAO,kCACjB;EAEH,yBAAyB;EACzB,UAAU;;;;;;;;;;;;EAYV,oBAAoB;EACpB,YAAY;;KAuCF,+BAA+B;cAE9B,iCAAiC;UACpC;UACA;UACA;UACA;EAMN,YAAA,OAAO,8BACP,uBACE,SAAS,0BACT,uBAAuB,iCACpB;YA0CG;EAiBH,eACL,kBACA;IAAY;MACX;EAII,qBAAqB;EAIrB,+BACL,WAAW,OAAO,kCACjB;EAMI,yBAAyB;EAIzB,UAAU;EAIV,oBAAoB;EAIpB,YAAY;EAIZ,YAAY;EAIZ,UAAU,uBAAuB;UAIhC;WAEQ,MAAM;MAEX,YAAQ;EAIZ,QAAQ,mBAAgB;EAcxB,eAAe,cAAW;EAgB1B,uBAAuB,cAAW;EAmBlC,YAAY,mBAAgB"}
1
+ {"version":3,"file":"thread-list-runtime.d.ts","names":[],"sources":["../../../src/runtime/api/thread-list-runtime.ts"],"mappings":";;;;;;KA6BY;WACD;WACA;WACA;WACA;WACA;;WAEA;WACA;WACA;WACA,aAAa,SACpB,eAEE,KAAK;;KAKC;EACV,YAAY;EAEZ,UAAU,uBAAuB;WAExB,MAAM;EACf,QAAQ,mBAAmB;WAElB,UAAU;EACnB,YAAY,mBAAmB;EAC/B,eAAe,cAAc;EAC7B,uBAAuB,cAAc;EAErC,eACE,kBACA;IAAY;MACX;EACH,qBAAqB;;;;;;;EAQrB,+BACE,WAAW,OAAO,kCACjB;EAEH,yBAAyB;EACzB,UAAU;;;;;;;;;;;;EAYV,oBAAoB;EACpB,YAAY;;KAwCF,+BAA+B;cAE9B,iCAAiC;UACpC;UACA;UACA;UACA;EAMN,YAAA,OAAO,8BACP,uBACE,SAAS,0BACT,uBAAuB,iCACpB;YA0CG;EAiBH,eACL,kBACA;IAAY;MACX;EAII,qBAAqB;EAIrB,+BACL,WAAW,OAAO,kCACjB;EAMI,yBAAyB;EAIzB,UAAU;EAIV,oBAAoB;EAIpB,YAAY;EAIZ,YAAY;EAIZ,UAAU,uBAAuB;UAIhC;WAEQ,MAAM;MAEX,YAAQ;UAIX;EAeD,QAAQ,mBAAgB;EAcxB,eAAe,cAAW;EAgB1B,uBAAuB,cAAW;EAmBlC,YAAY,mBAAgB"}
@@ -11,6 +11,7 @@ const getThreadListState = (threadList) => {
11
11
  threadIds: threadList.threadIds,
12
12
  archivedThreadIds: threadList.archivedThreadIds,
13
13
  isLoading: threadList.isLoading,
14
+ loadError: threadList.loadError,
14
15
  isLoadingMore: threadList.isLoadingMore ?? false,
15
16
  hasMore: threadList.hasMore ?? false,
16
17
  threadItems: threadList.threadItems
@@ -114,6 +115,21 @@ var ThreadListRuntimeImpl = class {
114
115
  get mainItem() {
115
116
  return this._mainThreadListItemRuntime;
116
117
  }
118
+ _createItemStateBinding(threadId) {
119
+ return new ShallowMemoizeSubject({
120
+ path: {
121
+ ref: `threadItems[threadId=${threadId}]`,
122
+ threadSelector: {
123
+ type: "threadId",
124
+ threadId
125
+ }
126
+ },
127
+ getState: () => {
128
+ return getThreadListItemState(this._core, threadId);
129
+ },
130
+ subscribe: (callback) => this._core.subscribe(callback)
131
+ });
132
+ }
117
133
  getById(threadId) {
118
134
  return new this._runtimeFactory(new NestedSubscriptionSubject({
119
135
  path: {
@@ -125,7 +141,7 @@ var ThreadListRuntimeImpl = class {
125
141
  },
126
142
  getState: () => this._core.getThreadRuntimeCore(threadId),
127
143
  subscribe: (callback) => this._core.subscribe(callback)
128
- }), this.mainItem);
144
+ }), this._createItemStateBinding(threadId));
129
145
  }
130
146
  getItemByIndex(idx) {
131
147
  return new ThreadListItemRuntimeImpl(new ShallowMemoizeSubject({
@@ -158,19 +174,7 @@ var ThreadListRuntimeImpl = class {
158
174
  }), this._core);
159
175
  }
160
176
  getItemById(threadId) {
161
- return new ThreadListItemRuntimeImpl(new ShallowMemoizeSubject({
162
- path: {
163
- ref: `threadItems[threadId=${threadId}]`,
164
- threadSelector: {
165
- type: "threadId",
166
- threadId
167
- }
168
- },
169
- getState: () => {
170
- return getThreadListItemState(this._core, threadId);
171
- },
172
- subscribe: (callback) => this._core.subscribe(callback)
173
- }), this._core);
177
+ return new ThreadListItemRuntimeImpl(this._createItemStateBinding(threadId), this._core);
174
178
  }
175
179
  };
176
180
  //#endregion