@assistant-ui/core 0.3.14 → 0.3.16

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 (341) hide show
  1. package/dist/adapters/voice.js +11 -0
  2. package/dist/adapters/voice.js.map +1 -1
  3. package/dist/index.js +1 -1
  4. package/dist/internal.d.ts +8 -2
  5. package/dist/internal.js +9 -3
  6. package/dist/model-context/frame/host.d.ts +1 -1
  7. package/dist/model-context/frame/host.d.ts.map +1 -1
  8. package/dist/model-context/frame/host.js +20 -5
  9. package/dist/model-context/frame/host.js.map +1 -1
  10. package/dist/model-context/frame/provider.d.ts +6 -0
  11. package/dist/model-context/frame/provider.d.ts.map +1 -1
  12. package/dist/model-context/frame/provider.js +126 -16
  13. package/dist/model-context/frame/provider.js.map +1 -1
  14. package/dist/model-context/frame/types.d.ts +4 -1
  15. package/dist/model-context/frame/types.d.ts.map +1 -1
  16. package/dist/model-context/frame/types.js.map +1 -1
  17. package/dist/model-context/interactable-composer-metadata.d.ts +1 -1
  18. package/dist/model-context/interactable-composer-metadata.js +1 -1
  19. package/dist/model-context/interactable-composer-metadata.js.map +1 -1
  20. package/dist/model-context/registry.d.ts +2 -2
  21. package/dist/model-context/registry.d.ts.map +1 -1
  22. package/dist/model-context/registry.js +9 -28
  23. package/dist/model-context/registry.js.map +1 -1
  24. package/dist/react/client/InMemoryThreadList.d.ts.map +1 -1
  25. package/dist/react/client/InMemoryThreadList.js +24 -20
  26. package/dist/react/client/InMemoryThreadList.js.map +1 -1
  27. package/dist/react/client/Interactables.d.ts.map +1 -1
  28. package/dist/react/client/Interactables.js +59 -177
  29. package/dist/react/client/Interactables.js.map +1 -1
  30. package/dist/react/client/RemoteThreadList.d.ts +1 -1
  31. package/dist/react/client/RemoteThreadList.d.ts.map +1 -1
  32. package/dist/react/client/RemoteThreadList.js +117 -78
  33. package/dist/react/client/RemoteThreadList.js.map +1 -1
  34. package/dist/react/index.d.ts +2 -1
  35. package/dist/react/interactables-legacy/Interactables.d.ts.map +1 -1
  36. package/dist/react/interactables-legacy/Interactables.js +56 -174
  37. package/dist/react/interactables-legacy/Interactables.js.map +1 -1
  38. package/dist/react/interactables-shared/useInteractablePersistenceQueue.d.ts +24 -0
  39. package/dist/react/interactables-shared/useInteractablePersistenceQueue.d.ts.map +1 -0
  40. package/dist/react/interactables-shared/useInteractablePersistenceQueue.js +138 -0
  41. package/dist/react/interactables-shared/useInteractablePersistenceQueue.js.map +1 -0
  42. package/dist/react/primitive-hooks/useActionBarCopy.js +7 -1
  43. package/dist/react/primitive-hooks/useActionBarCopy.js.map +1 -1
  44. package/dist/react/primitive-hooks/useThreadIsEmpty.d.ts +3 -0
  45. package/dist/react/primitive-hooks/useThreadIsEmpty.d.ts.map +1 -1
  46. package/dist/react/primitive-hooks/useThreadIsEmpty.js +3 -0
  47. package/dist/react/primitive-hooks/useThreadIsEmpty.js.map +1 -1
  48. package/dist/react/primitive-hooks/useThreadIsRunning.d.ts +3 -0
  49. package/dist/react/primitive-hooks/useThreadIsRunning.d.ts.map +1 -1
  50. package/dist/react/primitive-hooks/useThreadIsRunning.js +3 -0
  51. package/dist/react/primitive-hooks/useThreadIsRunning.js.map +1 -1
  52. package/dist/react/primitives/composer/ComposerIf.js.map +1 -1
  53. package/dist/react/primitives/composer/ComposerQueue.d.ts +2 -1
  54. package/dist/react/primitives/composer/ComposerQueue.d.ts.map +1 -1
  55. package/dist/react/primitives/message/MessageParts.js.map +1 -1
  56. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts +3 -1
  57. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts.map +1 -1
  58. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js +6 -0
  59. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js.map +1 -1
  60. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts +7 -1
  61. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
  62. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js +174 -64
  63. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js.map +1 -1
  64. package/dist/react/runtimes/RemoteThreadResource.d.ts.map +1 -1
  65. package/dist/react/runtimes/RemoteThreadResource.js +2 -0
  66. package/dist/react/runtimes/RemoteThreadResource.js.map +1 -1
  67. package/dist/react/runtimes/assistant-transport/runManager.d.ts.map +1 -1
  68. package/dist/react/runtimes/assistant-transport/runManager.js +2 -12
  69. package/dist/react/runtimes/assistant-transport/runManager.js.map +1 -1
  70. package/dist/react/runtimes/assistant-transport/useAssistantTransportRuntime.d.ts.map +1 -1
  71. package/dist/react/runtimes/assistant-transport/useAssistantTransportRuntime.js +1 -1
  72. package/dist/react/runtimes/assistant-transport/useAssistantTransportRuntime.js.map +1 -1
  73. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts +3 -10
  74. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts.map +1 -1
  75. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js +20 -67
  76. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js.map +1 -1
  77. package/dist/react/runtimes/cloud/createCloudThreadListAdapterCreateFallback.d.ts +12 -0
  78. package/dist/react/runtimes/cloud/createCloudThreadListAdapterCreateFallback.d.ts.map +1 -0
  79. package/dist/react/runtimes/cloud/createCloudThreadListAdapterCreateFallback.js +10 -0
  80. package/dist/react/runtimes/cloud/createCloudThreadListAdapterCreateFallback.js.map +1 -0
  81. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.d.ts.map +1 -1
  82. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js +38 -5
  83. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js.map +1 -1
  84. package/dist/react/runtimes/cloud/useCloudThreadListRuntime.js.map +1 -1
  85. package/dist/react/runtimes/createMessageConverter.d.ts +2 -1
  86. package/dist/react/runtimes/createMessageConverter.d.ts.map +1 -1
  87. package/dist/react/runtimes/external-message-converter.d.ts +6 -25
  88. package/dist/react/runtimes/external-message-converter.d.ts.map +1 -1
  89. package/dist/react/runtimes/external-message-converter.js +33 -233
  90. package/dist/react/runtimes/external-message-converter.js.map +1 -1
  91. package/dist/runtime/api/composer-runtime.d.ts +1 -1
  92. package/dist/runtime/api/composer-runtime.js.map +1 -1
  93. package/dist/runtime/api/thread-runtime.d.ts +1 -2
  94. package/dist/runtime/api/thread-runtime.d.ts.map +1 -1
  95. package/dist/runtime/base/base-composer-runtime-core.d.ts +1 -1
  96. package/dist/runtime/base/base-composer-runtime-core.d.ts.map +1 -1
  97. package/dist/runtime/base/base-composer-runtime-core.js +14 -29
  98. package/dist/runtime/base/base-composer-runtime-core.js.map +1 -1
  99. package/dist/runtime/base/base-thread-runtime-core.d.ts +2 -4
  100. package/dist/runtime/base/base-thread-runtime-core.d.ts.map +1 -1
  101. package/dist/runtime/base/base-thread-runtime-core.js +3 -9
  102. package/dist/runtime/base/base-thread-runtime-core.js.map +1 -1
  103. package/dist/runtime/base/default-thread-composer-runtime-core.d.ts +1 -1
  104. package/dist/runtime/base/default-thread-composer-runtime-core.d.ts.map +1 -1
  105. package/dist/runtime/base/default-thread-composer-runtime-core.js +1 -1
  106. package/dist/runtime/base/default-thread-composer-runtime-core.js.map +1 -1
  107. package/dist/runtime/interfaces/composer-runtime-core.d.ts +1 -1
  108. package/dist/runtime/interfaces/thread-runtime-core.d.ts +1 -1
  109. package/dist/runtime/internal.d.ts +2 -1
  110. package/dist/runtime/internal.js +2 -1
  111. package/dist/runtime/queue/external-thread-queue-adapter.d.ts +1 -1
  112. package/dist/runtime/queue/message-queue.d.ts.map +1 -1
  113. package/dist/runtime/queue/message-queue.js +1 -1
  114. package/dist/runtime/queue/message-queue.js.map +1 -1
  115. package/dist/runtime/queue/queue-item.d.ts +12 -0
  116. package/dist/runtime/queue/queue-item.d.ts.map +1 -0
  117. package/dist/runtime/queue/queue-item.js +6 -0
  118. package/dist/runtime/queue/queue-item.js.map +1 -0
  119. package/dist/runtime/utils/abortable-thread-load.d.ts +15 -0
  120. package/dist/runtime/utils/abortable-thread-load.d.ts.map +1 -0
  121. package/dist/runtime/utils/abortable-thread-load.js +35 -0
  122. package/dist/runtime/utils/abortable-thread-load.js.map +1 -0
  123. package/dist/runtime/utils/attachment-add-operations.d.ts +18 -0
  124. package/dist/runtime/utils/attachment-add-operations.d.ts.map +1 -0
  125. package/dist/runtime/utils/attachment-add-operations.js +43 -0
  126. package/dist/runtime/utils/attachment-add-operations.js.map +1 -0
  127. package/dist/runtime/utils/auto-status.d.ts +6 -1
  128. package/dist/runtime/utils/auto-status.d.ts.map +1 -1
  129. package/dist/runtime/utils/auto-status.js +7 -1
  130. package/dist/runtime/utils/auto-status.js.map +1 -1
  131. package/dist/runtime/utils/external-message-conversion.d.ts +47 -0
  132. package/dist/runtime/utils/external-message-conversion.d.ts.map +1 -0
  133. package/dist/runtime/utils/external-message-conversion.js +221 -0
  134. package/dist/runtime/utils/external-message-conversion.js.map +1 -0
  135. package/dist/runtime/utils/external-store-message.d.ts +2 -1
  136. package/dist/runtime/utils/external-store-message.d.ts.map +1 -1
  137. package/dist/runtime/utils/external-store-message.js +2 -1
  138. package/dist/runtime/utils/external-store-message.js.map +1 -1
  139. package/dist/runtime/utils/message-repository-session.d.ts +30 -0
  140. package/dist/runtime/utils/message-repository-session.d.ts.map +1 -0
  141. package/dist/runtime/utils/message-repository-session.js +130 -0
  142. package/dist/runtime/utils/message-repository-session.js.map +1 -0
  143. package/dist/runtime/utils/message-repository.d.ts.map +1 -1
  144. package/dist/runtime/utils/message-repository.js +30 -22
  145. package/dist/runtime/utils/message-repository.js.map +1 -1
  146. package/dist/runtime/utils/pending-tool-calls.d.ts +20 -0
  147. package/dist/runtime/utils/pending-tool-calls.d.ts.map +1 -0
  148. package/dist/runtime/utils/pending-tool-calls.js +22 -0
  149. package/dist/runtime/utils/pending-tool-calls.js.map +1 -0
  150. package/dist/runtime/utils/thread-message-like.d.ts +2 -1
  151. package/dist/runtime/utils/thread-message-like.d.ts.map +1 -1
  152. package/dist/runtime/utils/thread-message-like.js.map +1 -1
  153. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.d.ts +2 -5
  154. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.d.ts.map +1 -1
  155. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js +3 -10
  156. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js.map +1 -1
  157. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts +19 -1
  158. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts.map +1 -1
  159. package/dist/runtimes/external-store/external-store-thread-runtime-core.js +124 -20
  160. package/dist/runtimes/external-store/external-store-thread-runtime-core.js.map +1 -1
  161. package/dist/runtimes/inert/InertThreadRuntimeCore.d.ts +102 -0
  162. package/dist/runtimes/inert/InertThreadRuntimeCore.d.ts.map +1 -0
  163. package/dist/runtimes/inert/InertThreadRuntimeCore.js +156 -0
  164. package/dist/runtimes/inert/InertThreadRuntimeCore.js.map +1 -0
  165. package/dist/runtimes/local/local-thread-runtime-core.d.ts +3 -1
  166. package/dist/runtimes/local/local-thread-runtime-core.d.ts.map +1 -1
  167. package/dist/runtimes/local/local-thread-runtime-core.js +45 -8
  168. package/dist/runtimes/local/local-thread-runtime-core.js.map +1 -1
  169. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.d.ts +12 -60
  170. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.d.ts.map +1 -1
  171. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.js +10 -145
  172. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.js.map +1 -1
  173. package/dist/runtimes/remote-thread-list/adapter-changed.d.ts +9 -0
  174. package/dist/runtimes/remote-thread-list/adapter-changed.d.ts.map +1 -0
  175. package/dist/runtimes/remote-thread-list/adapter-changed.js +13 -0
  176. package/dist/runtimes/remote-thread-list/adapter-changed.js.map +1 -0
  177. package/dist/runtimes/remote-thread-list/empty-thread-core.d.ts.map +1 -1
  178. package/dist/runtimes/remote-thread-list/empty-thread-core.js +16 -155
  179. package/dist/runtimes/remote-thread-list/empty-thread-core.js.map +1 -1
  180. package/dist/runtimes/remote-thread-list/optimistic-state.d.ts +2 -0
  181. package/dist/runtimes/remote-thread-list/optimistic-state.d.ts.map +1 -1
  182. package/dist/runtimes/remote-thread-list/optimistic-state.js +11 -0
  183. package/dist/runtimes/remote-thread-list/optimistic-state.js.map +1 -1
  184. package/dist/runtimes/remote-thread-list/remote-thread-state.d.ts +12 -1
  185. package/dist/runtimes/remote-thread-list/remote-thread-state.d.ts.map +1 -1
  186. package/dist/runtimes/remote-thread-list/remote-thread-state.js +77 -1
  187. package/dist/runtimes/remote-thread-list/remote-thread-state.js.map +1 -1
  188. package/dist/runtimes/remote-thread-list/types.d.ts +3 -0
  189. package/dist/runtimes/remote-thread-list/types.d.ts.map +1 -1
  190. package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts.map +1 -1
  191. package/dist/runtimes/tool-invocations/ToolInvocationTracker.js +2 -0
  192. package/dist/runtimes/tool-invocations/ToolInvocationTracker.js.map +1 -1
  193. package/dist/store/clients/external-thread.d.ts.map +1 -1
  194. package/dist/store/clients/external-thread.js +75 -100
  195. package/dist/store/clients/external-thread.js.map +1 -1
  196. package/dist/store/clients/single-thread-list.d.ts.map +1 -1
  197. package/dist/store/clients/single-thread-list.js +1 -1
  198. package/dist/store/clients/single-thread-list.js.map +1 -1
  199. package/dist/store/clients/suggestions.d.ts.map +1 -1
  200. package/dist/store/clients/suggestions.js +16 -7
  201. package/dist/store/clients/suggestions.js.map +1 -1
  202. package/dist/store/index.d.ts +4 -2
  203. package/dist/store/runtime-clients/handle-runtime-action.d.ts.map +1 -1
  204. package/dist/store/runtime-clients/handle-runtime-action.js +2 -0
  205. package/dist/store/runtime-clients/handle-runtime-action.js.map +1 -1
  206. package/dist/store/scope-registration.d.ts +1 -1
  207. package/dist/store/scopes/composer.d.ts +2 -1
  208. package/dist/store/scopes/composer.d.ts.map +1 -1
  209. package/dist/store/scopes/message.d.ts +1 -1
  210. package/dist/store/scopes/queue-item.d.ts +2 -9
  211. package/dist/store/scopes/queue-item.d.ts.map +1 -1
  212. package/dist/store/scopes/queue-item.js +0 -6
  213. package/dist/types/message.d.ts +8 -4
  214. package/dist/types/message.d.ts.map +1 -1
  215. package/dist/types/message.js.map +1 -1
  216. package/dist/utils/data-url.d.ts +14 -1
  217. package/dist/utils/data-url.d.ts.map +1 -1
  218. package/dist/utils/data-url.js +13 -1
  219. package/dist/utils/data-url.js.map +1 -1
  220. package/dist/utils/invoke-user-callback.d.ts +5 -0
  221. package/dist/utils/invoke-user-callback.d.ts.map +1 -0
  222. package/dist/utils/invoke-user-callback.js +19 -0
  223. package/dist/utils/invoke-user-callback.js.map +1 -0
  224. package/dist/utils/normalizePartStatus.js.map +1 -1
  225. package/dist/utils/silent-runtime-action.d.ts +6 -0
  226. package/dist/utils/silent-runtime-action.d.ts.map +1 -0
  227. package/dist/utils/silent-runtime-action.js +7 -0
  228. package/dist/utils/silent-runtime-action.js.map +1 -0
  229. package/package.json +10 -10
  230. package/src/adapters/voice.test.ts +66 -1
  231. package/src/adapters/voice.ts +8 -0
  232. package/src/internal.ts +13 -0
  233. package/src/model-context/frame/host.test.ts +152 -9
  234. package/src/model-context/frame/host.ts +23 -5
  235. package/src/model-context/frame/provider.test.ts +601 -19
  236. package/src/model-context/frame/provider.ts +158 -20
  237. package/src/model-context/frame/types.ts +5 -0
  238. package/src/model-context/interactable-composer-metadata.ts +1 -1
  239. package/src/model-context/registry.test.ts +44 -0
  240. package/src/model-context/registry.ts +13 -35
  241. package/src/react/client/InMemoryThreadList.test.tsx +49 -0
  242. package/src/react/client/InMemoryThreadList.ts +7 -1
  243. package/src/react/client/Interactables.ts +19 -178
  244. package/src/react/client/RemoteThreadList.test.ts +292 -0
  245. package/src/react/client/RemoteThreadList.ts +119 -82
  246. package/src/react/interactables-legacy/Interactables.ts +20 -177
  247. package/src/react/interactables-shared/useInteractablePersistenceQueue.test.tsx +161 -0
  248. package/src/react/interactables-shared/useInteractablePersistenceQueue.ts +206 -0
  249. package/src/react/primitive-hooks/useActionBarCopy.test.ts +15 -0
  250. package/src/react/primitive-hooks/useActionBarCopy.ts +13 -3
  251. package/src/react/primitive-hooks/useThreadIsEmpty.ts +3 -0
  252. package/src/react/primitive-hooks/useThreadIsRunning.ts +3 -0
  253. package/src/react/runtimes/RemoteThreadListHookInstanceManager.tsx +12 -0
  254. package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.republish.test.ts +87 -0
  255. package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.tsx +251 -76
  256. package/src/react/runtimes/RemoteThreadResource.ts +2 -0
  257. package/src/react/runtimes/assistant-transport/runManager.ts +4 -17
  258. package/src/react/runtimes/assistant-transport/useAssistantTransportRuntime.test.tsx +58 -0
  259. package/src/react/runtimes/assistant-transport/useAssistantTransportRuntime.ts +3 -1
  260. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.test.tsx +92 -0
  261. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.ts +40 -141
  262. package/src/react/runtimes/cloud/createCloudThreadListAdapterCreateFallback.test.ts +37 -0
  263. package/src/react/runtimes/cloud/createCloudThreadListAdapterCreateFallback.ts +18 -0
  264. package/src/react/runtimes/cloud/useCloudThreadListAdapter.test.tsx +98 -3
  265. package/src/react/runtimes/cloud/useCloudThreadListAdapter.tsx +68 -6
  266. package/src/react/runtimes/external-message-converter.test.ts +0 -14
  267. package/src/react/runtimes/external-message-converter.test.tsx +77 -0
  268. package/src/react/runtimes/external-message-converter.ts +58 -481
  269. package/src/react/runtimes/useLocalRuntime.test.tsx +5 -5
  270. package/src/runtime/api/composer-runtime.ts +1 -1
  271. package/src/runtime/api/message-runtime.test.ts +28 -1
  272. package/src/runtime/base/base-composer-runtime-core.ts +20 -40
  273. package/src/runtime/base/base-thread-runtime-core.test.ts +16 -0
  274. package/src/runtime/base/base-thread-runtime-core.ts +6 -11
  275. package/src/runtime/base/default-thread-composer-runtime-core.ts +1 -4
  276. package/src/runtime/interfaces/composer-runtime-core.ts +1 -1
  277. package/src/runtime/interfaces/thread-runtime-core.ts +1 -1
  278. package/src/runtime/internal.ts +5 -0
  279. package/src/runtime/queue/external-thread-queue-adapter.ts +1 -1
  280. package/src/runtime/queue/message-queue.ts +1 -4
  281. package/src/runtime/queue/queue-item.ts +10 -0
  282. package/src/runtime/utils/abortable-thread-load.test.ts +87 -0
  283. package/src/runtime/utils/abortable-thread-load.ts +53 -0
  284. package/src/runtime/utils/attachment-add-operations.ts +59 -0
  285. package/src/runtime/utils/auto-status.ts +33 -0
  286. package/src/runtime/utils/external-message-conversion.test.ts +113 -0
  287. package/src/runtime/utils/external-message-conversion.ts +494 -0
  288. package/src/runtime/utils/external-store-message.ts +2 -0
  289. package/src/runtime/utils/message-repository-session.test.ts +195 -0
  290. package/src/runtime/utils/message-repository-session.ts +176 -0
  291. package/src/runtime/utils/message-repository.ts +33 -22
  292. package/src/runtime/utils/pending-tool-calls.test.ts +57 -0
  293. package/src/runtime/utils/pending-tool-calls.ts +35 -0
  294. package/src/runtime/utils/thread-message-like.ts +2 -0
  295. package/src/runtimes/external-store/external-store-thread-list-runtime-core.ts +6 -14
  296. package/src/runtimes/external-store/external-store-thread-runtime-core.ts +179 -28
  297. package/src/runtimes/inert/InertThreadRuntimeCore.test.ts +253 -0
  298. package/src/runtimes/inert/InertThreadRuntimeCore.ts +232 -0
  299. package/src/runtimes/local/local-thread-runtime-core.test.ts +491 -1
  300. package/src/runtimes/local/local-thread-runtime-core.ts +86 -11
  301. package/src/runtimes/readonly/ReadonlyThreadRuntimeCore.ts +17 -209
  302. package/src/runtimes/remote-thread-list/adapter-changed.ts +10 -0
  303. package/src/runtimes/remote-thread-list/empty-thread-core.ts +28 -221
  304. package/src/runtimes/remote-thread-list/optimistic-state.test.ts +18 -0
  305. package/src/runtimes/remote-thread-list/optimistic-state.ts +13 -0
  306. package/src/runtimes/remote-thread-list/remote-thread-state.test.ts +37 -0
  307. package/src/runtimes/remote-thread-list/remote-thread-state.ts +123 -0
  308. package/src/runtimes/remote-thread-list/types.ts +4 -0
  309. package/src/runtimes/tool-invocations/EDGE_CASES.md +17 -0
  310. package/src/runtimes/tool-invocations/ToolInvocationTracker.test.ts +140 -0
  311. package/src/runtimes/tool-invocations/ToolInvocationTracker.ts +3 -0
  312. package/src/store/clients/external-thread.ts +17 -62
  313. package/src/store/clients/single-thread-list.ts +4 -1
  314. package/src/store/clients/suggestions.test.ts +31 -0
  315. package/src/store/clients/suggestions.ts +18 -19
  316. package/src/store/runtime-clients/handle-runtime-action.test.ts +40 -0
  317. package/src/store/runtime-clients/handle-runtime-action.ts +3 -0
  318. package/src/store/scopes/message.ts +1 -1
  319. package/src/store/scopes/queue-item.ts +2 -9
  320. package/src/tests/MessageRepository.test.ts +125 -0
  321. package/src/tests/RemoteThreadListThreadListRuntimeCore-errors.test.ts +2 -2
  322. package/src/tests/RemoteThreadListThreadListRuntimeCore-load-race.test.ts +194 -0
  323. package/src/tests/RemoteThreadListThreadListRuntimeCore-loadMore.test.ts +8 -6
  324. package/src/tests/RemoteThreadListThreadListRuntimeCore-title-race.test.ts +158 -0
  325. package/src/tests/empty-thread-core.test.ts +6 -0
  326. package/src/tests/external-store-thread-runtime-core-adapter.test.ts +184 -0
  327. package/src/tests/external-store-thread-runtime-core.test.ts +642 -0
  328. package/src/tests/external-thread-attachments.test.tsx +173 -0
  329. package/src/tests/external-thread-isEmpty.test.tsx +100 -0
  330. package/src/tests/remote-thread-list-adapter-switch.test.ts +383 -0
  331. package/src/tests/single-thread-list-item.test.tsx +47 -0
  332. package/src/tests/thread-message-like.test.ts +39 -1
  333. package/src/tests/useRemoteThreadListRuntime-controlled.test.tsx +67 -0
  334. package/src/types/message.ts +9 -4
  335. package/src/utils/data-url.test.ts +52 -1
  336. package/src/utils/data-url.ts +21 -0
  337. package/src/utils/invoke-user-callback.test.ts +82 -0
  338. package/src/utils/invoke-user-callback.ts +31 -0
  339. package/src/utils/normalizePartStatus.ts +1 -1
  340. package/src/utils/silent-runtime-action.ts +6 -0
  341. package/dist/store/scopes/queue-item.js.map +0 -1
@@ -1,10 +1,10 @@
1
- import { generateId } from "../../utils/id.js";
2
1
  import { OptimisticState } from "../../runtimes/remote-thread-list/optimistic-state.js";
3
- import { classifyThreads, createThreadMappingId, getThreadData, normalizeCursor, updateStatusReducer } from "../../runtimes/remote-thread-list/remote-thread-state.js";
2
+ import { classifyThreads, createEmptyRemoteThreadState, createThreadMappingId, getThreadData, normalizeCursor, preserveMidLoadTransitions, seedNewThread, statusSnapshot, updateStatusReducer } from "../../runtimes/remote-thread-list/remote-thread-state.js";
4
3
  import { handleThreadListAction } from "../../store/runtime-clients/handle-thread-list-action.js";
5
4
  import { useThreadSelectionEvents } from "../../store/clients/thread-selection-events.js";
6
5
  import { isDevelopment } from "../../store/env.js";
7
6
  import { inMemoryThreadListTransformScopes } from "./InMemoryThreadList.js";
7
+ import { ThreadListAdapterChangedError } from "../../runtimes/remote-thread-list/adapter-changed.js";
8
8
  import { AdaptedRemoteThread } from "./AdaptedRemoteThread.js";
9
9
  import { AssistantMessageStream } from "assistant-stream";
10
10
  import { c } from "@assistant-ui/tap/react-shim/compiler-runtime";
@@ -13,16 +13,7 @@ import { resource, withKey } from "@assistant-ui/tap";
13
13
  import { attachTransformScopes, useClientLookup, useClientResource } from "@assistant-ui/store/client";
14
14
  //#region src/react/client/RemoteThreadList.ts
15
15
  const RESOLVED_PROMISE = Promise.resolve();
16
- const EMPTY_LIST = {
17
- isLoading: true,
18
- isLoadingMore: false,
19
- cursor: void 0,
20
- newThreadId: void 0,
21
- threadIds: [],
22
- archivedThreadIds: [],
23
- threadIdMap: {},
24
- threadData: {}
25
- };
16
+ const EMPTY_LIST = createEmptyRemoteThreadState();
26
17
  const threadNotFoundError = (threadIdOrRemoteId, action) => /* @__PURE__ */ new Error(`Thread "${threadIdOrRemoteId}" was not found while ${action}.`);
27
18
  const threadStatusError = (threadIdOrRemoteId, status, action) => /* @__PURE__ */ new Error(`Thread "${threadIdOrRemoteId}" has status "${status}", so it cannot ${action}.`);
28
19
  const toInitializeResult = (result) => ({
@@ -31,36 +22,7 @@ const toInitializeResult = (result) => ({
31
22
  });
32
23
  const applyTitleStream = async (stream, onTitle) => {
33
24
  const messageStream = AssistantMessageStream.fromAssistantStream(stream);
34
- for await (const result of messageStream) onTitle(result.parts.filter((part) => part.type === "text")[0]?.text);
35
- };
36
- const seedNewThread = (state) => {
37
- let id;
38
- do
39
- id = `__LOCALID_${generateId()}`;
40
- while (state.threadIdMap[id]);
41
- const mappingId = createThreadMappingId(id);
42
- return {
43
- id,
44
- state: {
45
- ...state,
46
- newThreadId: id,
47
- threadIdMap: {
48
- ...state.threadIdMap,
49
- [id]: mappingId
50
- },
51
- threadData: {
52
- ...state.threadData,
53
- [mappingId]: {
54
- status: "new",
55
- id,
56
- remoteId: void 0,
57
- externalId: void 0,
58
- title: void 0,
59
- custom: void 0
60
- }
61
- }
62
- }
63
- };
25
+ for await (const result of messageStream) await onTitle(result.parts.filter((part) => part.type === "text")[0]?.text);
64
26
  };
65
27
  const useThreadListItemClient = (props) => {
66
28
  const $ = c(22);
@@ -255,6 +217,8 @@ const useRemoteThreadList = (props) => {
255
217
  initialMainId: seeded.id,
256
218
  session: {
257
219
  adapter,
220
+ adapterAtLoad: adapter,
221
+ adapterGeneration: 0,
258
222
  loadGeneration: 0,
259
223
  switchGeneration: 0,
260
224
  loadPromise: void 0,
@@ -270,6 +234,7 @@ const useRemoteThreadList = (props) => {
270
234
  }
271
235
  };
272
236
  });
237
+ session.adapter = adapter;
273
238
  const listState = useSyncExternalStore((onStoreChange) => store.subscribe(onStoreChange), () => store.value, () => store.value);
274
239
  const [mainThreadId, setMainThreadId] = useState(initialMainId);
275
240
  const assignMainThreadId = useCallback((id) => {
@@ -299,21 +264,24 @@ const useRemoteThreadList = (props) => {
299
264
  const getLoadThreadsPromise = useCallback(() => {
300
265
  if (session.loadPromise) return session.loadPromise;
301
266
  const generation = session.loadGeneration;
267
+ const adapter_0 = session.adapter;
268
+ const statusAtRequest = statusSnapshot(store.baseValue);
302
269
  session.loadPromise = store.optimisticUpdate({
303
- execute: () => session.adapter.list(),
270
+ execute: () => adapter_0.list(),
304
271
  loading: (state) => ({
305
272
  ...state,
306
273
  isLoading: true
307
274
  }),
308
275
  then: (state_0, page) => {
309
276
  if (generation !== session.loadGeneration) return state_0;
277
+ session.adapterAtLoad = adapter_0;
310
278
  const fresh = classifyThreads(page.threads, {
311
279
  threadIds: [],
312
280
  archivedThreadIds: [],
313
281
  threadIdMap: {},
314
282
  threadData: {}
315
283
  });
316
- return {
284
+ const merged = {
317
285
  ...state_0,
318
286
  isLoading: false,
319
287
  cursor: normalizeCursor(page.nextCursor),
@@ -328,6 +296,7 @@ const useRemoteThreadList = (props) => {
328
296
  ...fresh.threadData
329
297
  }
330
298
  };
299
+ return preserveMidLoadTransitions(merged, state_0, statusAtRequest);
331
300
  }
332
301
  }).catch((error) => {
333
302
  if (generation !== session.loadGeneration) return;
@@ -341,16 +310,32 @@ const useRemoteThreadList = (props) => {
341
310
  return session.loadPromise;
342
311
  }, [session, store]);
343
312
  const reload = useCallback(() => {
313
+ const adapterChanged = adapter !== session.adapterAtLoad;
344
314
  session.loadGeneration++;
345
315
  session.loadPromise = void 0;
346
316
  session.loadMorePromise = void 0;
347
- store.update({
317
+ if (adapterChanged) {
318
+ session.adapterGeneration++;
319
+ session.switchGeneration++;
320
+ session.switchTask = void 0;
321
+ session.adapterAtLoad = adapter;
322
+ const seeded_0 = seedNewThread(EMPTY_LIST);
323
+ store.reset({
324
+ ...seeded_0.state,
325
+ isLoading: true
326
+ });
327
+ assignMainThreadId(seeded_0.id);
328
+ notifyRemoteId(void 0, true);
329
+ } else store.update({
348
330
  ...store.baseValue,
349
331
  cursor: void 0
350
332
  });
351
333
  return getLoadThreadsPromise();
352
334
  }, [
335
+ adapter,
336
+ assignMainThreadId,
353
337
  getLoadThreadsPromise,
338
+ notifyRemoteId,
354
339
  session,
355
340
  store
356
341
  ]);
@@ -395,6 +380,7 @@ const useRemoteThreadList = (props) => {
395
380
  };
396
381
  }
397
382
  }).catch((error_0) => {
383
+ if (generation_0 !== session.loadGeneration) return;
398
384
  console.error("[assistant-ui] thread list loadMore failed:", error_0);
399
385
  }).then(() => {
400
386
  if (session.loadMorePromise === task) session.loadMorePromise = void 0;
@@ -490,10 +476,10 @@ const useRemoteThreadList = (props) => {
490
476
  session.onSwitchToNewThread?.();
491
477
  return;
492
478
  }
493
- const seeded_0 = seedNewThread(store.baseValue);
494
- store.update(seeded_0.state);
479
+ const seeded_1 = seedNewThread(store.baseValue);
480
+ store.update(seeded_1.state);
495
481
  if (generation_3 !== session.switchGeneration) return;
496
- assignMainThreadId(seeded_0.id);
482
+ assignMainThreadId(seeded_1.id);
497
483
  notifyRemoteId(void 0, emitThreadIdChange_0);
498
484
  session.onSwitchToNewThread?.();
499
485
  }), [
@@ -522,15 +508,25 @@ const useRemoteThreadList = (props) => {
522
508
  store,
523
509
  switchToNewThread
524
510
  ]);
511
+ const requireAdapterGeneration = useCallback((generation_4) => {
512
+ if (generation_4 !== session.adapterGeneration) throw new ThreadListAdapterChangedError();
513
+ }, [session]);
525
514
  const initialize = useCallback(async (threadId_1) => {
515
+ const currentAdapter_0 = session.adapter;
516
+ const adapterGeneration = session.adapterGeneration;
526
517
  if (store.value.newThreadId !== threadId_1) {
527
518
  const data_0 = getThreadData(store.value, threadId_1);
528
519
  if (!data_0) throw threadNotFoundError(threadId_1, "initializing it");
529
520
  if (data_0.status === "new") throw threadStatusError(threadId_1, data_0.status, "be initialized here");
530
- return toInitializeResult(await data_0.initializeTask);
521
+ const result = toInitializeResult(await data_0.initializeTask);
522
+ requireAdapterGeneration(adapterGeneration);
523
+ return result;
531
524
  }
532
- const result = await store.optimisticUpdate({
533
- execute: () => session.adapter.initialize(threadId_1),
525
+ const result_0 = await store.optimisticUpdate({
526
+ execute: () => {
527
+ requireAdapterGeneration(adapterGeneration);
528
+ return currentAdapter_0.initialize(threadId_1);
529
+ },
534
530
  optimistic: (state_5) => updateStatusReducer(state_5, threadId_1, "regular"),
535
531
  loading: (state_6, task_1) => {
536
532
  const mappingId_0 = createThreadMappingId(threadId_1);
@@ -546,6 +542,7 @@ const useRemoteThreadList = (props) => {
546
542
  };
547
543
  },
548
544
  then: (state_7, { remoteId: remoteId_1, externalId }) => {
545
+ if (adapterGeneration !== session.adapterGeneration) return state_7;
549
546
  const data_1 = getThreadData(state_7, threadId_1);
550
547
  if (!data_1) return state_7;
551
548
  const mappingId_1 = createThreadMappingId(threadId_1);
@@ -570,21 +567,26 @@ const useRemoteThreadList = (props) => {
570
567
  };
571
568
  }
572
569
  });
573
- if (threadId_1 === session.mainThreadId) notifyRemoteId(result.remoteId, true);
574
- return toInitializeResult(result);
570
+ requireAdapterGeneration(adapterGeneration);
571
+ if (threadId_1 === session.mainThreadId) notifyRemoteId(result_0.remoteId, true);
572
+ return toInitializeResult(result_0);
575
573
  }, [
576
574
  notifyRemoteId,
575
+ requireAdapterGeneration,
577
576
  session,
578
577
  store
579
578
  ]);
580
579
  const rename = useCallback((threadIdOrRemoteId_0, newTitle) => {
580
+ const currentAdapter_1 = session.adapter;
581
+ const adapterGeneration_0 = session.adapterGeneration;
581
582
  const data_2 = getThreadData(store.value, threadIdOrRemoteId_0);
582
583
  if (!data_2) throw threadNotFoundError(threadIdOrRemoteId_0, "renaming it");
583
584
  if (data_2.status === "new") throw threadStatusError(threadIdOrRemoteId_0, data_2.status, "be renamed");
584
585
  return store.optimisticUpdate({
585
586
  execute: async () => {
586
587
  const { remoteId: remoteId_2 } = await data_2.initializeTask;
587
- return session.adapter.rename(remoteId_2, newTitle);
588
+ requireAdapterGeneration(adapterGeneration_0);
589
+ return currentAdapter_1.rename(remoteId_2, newTitle);
588
590
  },
589
591
  optimistic: (state_8) => {
590
592
  const current_0 = getThreadData(state_8, threadIdOrRemoteId_0);
@@ -601,18 +603,24 @@ const useRemoteThreadList = (props) => {
601
603
  };
602
604
  }
603
605
  });
604
- }, [session, store]);
606
+ }, [
607
+ requireAdapterGeneration,
608
+ session,
609
+ store
610
+ ]);
605
611
  const updateCustom = useCallback((threadIdOrRemoteId_1, custom) => {
612
+ const currentAdapter_2 = session.adapter;
613
+ const adapterGeneration_1 = session.adapterGeneration;
606
614
  const data_3 = getThreadData(store.value, threadIdOrRemoteId_1);
607
615
  if (!data_3) throw threadNotFoundError(threadIdOrRemoteId_1, "updating its custom metadata");
608
616
  if (data_3.status === "new") throw threadStatusError(threadIdOrRemoteId_1, data_3.status, "update custom metadata");
609
- if (!session.adapter.updateCustom) throw new Error("Remote thread list adapter does not support updating custom metadata");
617
+ if (!currentAdapter_2.updateCustom) throw new Error("Remote thread list adapter does not support updating custom metadata");
610
618
  return store.optimisticUpdate({
611
619
  execute: async () => {
612
620
  const { remoteId: remoteId_3 } = await data_3.initializeTask;
613
- const currentAdapter_0 = session.adapter;
614
- if (!currentAdapter_0.updateCustom) throw new Error("Remote thread list adapter does not support updating custom metadata");
615
- return currentAdapter_0.updateCustom(remoteId_3, custom);
621
+ requireAdapterGeneration(adapterGeneration_1);
622
+ if (!currentAdapter_2.updateCustom) throw new Error("Remote thread list adapter does not support updating custom metadata");
623
+ return currentAdapter_2.updateCustom(remoteId_3, custom);
616
624
  },
617
625
  optimistic: (state_9) => {
618
626
  const current_1 = getThreadData(state_9, threadIdOrRemoteId_1);
@@ -629,25 +637,36 @@ const useRemoteThreadList = (props) => {
629
637
  };
630
638
  }
631
639
  });
632
- }, [session, store]);
640
+ }, [
641
+ requireAdapterGeneration,
642
+ session,
643
+ store
644
+ ]);
633
645
  const archive = useCallback(async (threadIdOrRemoteId_2) => {
646
+ const currentAdapter_3 = session.adapter;
647
+ const adapterGeneration_2 = session.adapterGeneration;
634
648
  const data_4 = getThreadData(store.value, threadIdOrRemoteId_2);
635
649
  if (!data_4) throw threadNotFoundError(threadIdOrRemoteId_2, "archiving it");
636
650
  if (data_4.status !== "regular") throw threadStatusError(threadIdOrRemoteId_2, data_4.status, "be archived");
637
651
  await ensureNotMain(data_4.id);
652
+ requireAdapterGeneration(adapterGeneration_2);
638
653
  return store.optimisticUpdate({
639
654
  execute: async () => {
640
655
  const { remoteId: remoteId_4 } = await data_4.initializeTask;
641
- return session.adapter.archive(remoteId_4);
656
+ requireAdapterGeneration(adapterGeneration_2);
657
+ return currentAdapter_3.archive(remoteId_4);
642
658
  },
643
659
  optimistic: (state_10) => updateStatusReducer(state_10, data_4.id, "archived")
644
660
  });
645
661
  }, [
646
662
  ensureNotMain,
663
+ requireAdapterGeneration,
647
664
  session,
648
665
  store
649
666
  ]);
650
667
  const unarchive = useCallback((threadIdOrRemoteId_3) => {
668
+ const currentAdapter_4 = session.adapter;
669
+ const adapterGeneration_3 = session.adapterGeneration;
651
670
  const data_5 = getThreadData(store.value, threadIdOrRemoteId_3);
652
671
  if (!data_5) throw threadNotFoundError(threadIdOrRemoteId_3, "unarchiving it");
653
672
  if (data_5.status !== "archived") throw threadStatusError(threadIdOrRemoteId_3, data_5.status, "be unarchived");
@@ -655,9 +674,10 @@ const useRemoteThreadList = (props) => {
655
674
  execute: async () => {
656
675
  try {
657
676
  const { remoteId: remoteId_5 } = await data_5.initializeTask;
658
- return await session.adapter.unarchive(remoteId_5);
677
+ requireAdapterGeneration(adapterGeneration_3);
678
+ return await currentAdapter_4.unarchive(remoteId_5);
659
679
  } catch (error_4) {
660
- await ensureNotMain(data_5.id);
680
+ if (adapterGeneration_3 === session.adapterGeneration) await ensureNotMain(data_5.id);
661
681
  throw error_4;
662
682
  }
663
683
  },
@@ -665,52 +685,71 @@ const useRemoteThreadList = (props) => {
665
685
  });
666
686
  }, [
667
687
  ensureNotMain,
688
+ requireAdapterGeneration,
668
689
  session,
669
690
  store
670
691
  ]);
671
692
  const deleteThread = useCallback(async (threadIdOrRemoteId_4) => {
693
+ const currentAdapter_5 = session.adapter;
694
+ const adapterGeneration_4 = session.adapterGeneration;
672
695
  const data_6 = getThreadData(store.value, threadIdOrRemoteId_4);
673
696
  if (!data_6) throw threadNotFoundError(threadIdOrRemoteId_4, "deleting it");
674
697
  if (data_6.status !== "regular" && data_6.status !== "archived") throw threadStatusError(threadIdOrRemoteId_4, data_6.status, "be deleted");
675
698
  await ensureNotMain(data_6.id);
699
+ requireAdapterGeneration(adapterGeneration_4);
676
700
  onDelete?.(data_6.id);
677
701
  return store.optimisticUpdate({
678
702
  execute: async () => {
679
703
  const { remoteId: remoteId_6 } = await data_6.initializeTask;
680
- return session.adapter.delete(remoteId_6);
704
+ requireAdapterGeneration(adapterGeneration_4);
705
+ return currentAdapter_5.delete(remoteId_6);
681
706
  },
682
707
  optimistic: (state_12) => updateStatusReducer(state_12, data_6.id, "deleted")
683
708
  });
684
709
  }, [
685
710
  ensureNotMain,
686
711
  onDelete,
712
+ requireAdapterGeneration,
687
713
  session,
688
714
  store
689
715
  ]);
690
716
  const generateTitle = useCallback(async (threadIdOrRemoteId_5, messages) => {
717
+ const currentAdapter_6 = session.adapter;
718
+ const adapterGeneration_5 = session.adapterGeneration;
691
719
  const data_7 = getThreadData(store.value, threadIdOrRemoteId_5);
692
720
  if (!data_7) throw threadNotFoundError(threadIdOrRemoteId_5, "generating its title");
693
721
  if (data_7.status === "new") throw threadStatusError(threadIdOrRemoteId_5, data_7.status, "generate a title");
694
722
  const { remoteId: remoteId_7 } = await data_7.initializeTask;
723
+ requireAdapterGeneration(adapterGeneration_5);
695
724
  if (!isSameThread(store.value, data_7.id, session.mainThreadId)) return;
696
725
  if (!messages) return;
697
- const stream = await session.adapter.generateTitle(remoteId_7, messages);
698
- await applyTitleStream(stream, (newTitle_0) => {
699
- const state_13 = store.baseValue;
700
- const current_2 = getThreadData(state_13, data_7.id);
701
- if (!current_2) return;
702
- store.update({
703
- ...state_13,
704
- threadData: {
705
- ...state_13.threadData,
706
- [current_2.id]: {
707
- ...current_2,
708
- title: newTitle_0
709
- }
726
+ const stream = await currentAdapter_6.generateTitle(remoteId_7, messages);
727
+ requireAdapterGeneration(adapterGeneration_5);
728
+ await applyTitleStream(stream, async (newTitle_0) => {
729
+ await store.optimisticUpdate({
730
+ execute: async () => {},
731
+ optimistic: (state_13) => {
732
+ if (adapterGeneration_5 !== session.adapterGeneration) return state_13;
733
+ const current_2 = getThreadData(state_13, data_7.id);
734
+ if (!current_2) return state_13;
735
+ return {
736
+ ...state_13,
737
+ threadData: {
738
+ ...state_13.threadData,
739
+ [current_2.id]: {
740
+ ...current_2,
741
+ title: newTitle_0
742
+ }
743
+ }
744
+ };
710
745
  }
711
746
  });
712
747
  });
713
- }, [session, store]);
748
+ }, [
749
+ requireAdapterGeneration,
750
+ session,
751
+ store
752
+ ]);
714
753
  const { mainThreadClient, itemOrder, threadListItems } = useRemoteThreadListView({
715
754
  listState,
716
755
  mainThreadId,