@assistant-ui/core 0.3.13 → 0.3.15

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 (463) hide show
  1. package/dist/adapters/speech.d.ts.map +1 -1
  2. package/dist/adapters/speech.js +9 -15
  3. package/dist/adapters/speech.js.map +1 -1
  4. package/dist/adapters/thread-history.d.ts +2 -0
  5. package/dist/adapters/thread-history.d.ts.map +1 -1
  6. package/dist/adapters/voice.d.ts.map +1 -1
  7. package/dist/adapters/voice.js +38 -15
  8. package/dist/adapters/voice.js.map +1 -1
  9. package/dist/index.d.ts +2 -2
  10. package/dist/index.js +1 -1
  11. package/dist/index.js.map +1 -1
  12. package/dist/internal.d.ts +3 -2
  13. package/dist/internal.js +8 -7
  14. package/dist/model-context/frame/host.d.ts +1 -1
  15. package/dist/model-context/frame/host.d.ts.map +1 -1
  16. package/dist/model-context/frame/host.js +19 -4
  17. package/dist/model-context/frame/host.js.map +1 -1
  18. package/dist/model-context/frame/provider.d.ts +4 -0
  19. package/dist/model-context/frame/provider.d.ts.map +1 -1
  20. package/dist/model-context/frame/provider.js +50 -3
  21. package/dist/model-context/frame/provider.js.map +1 -1
  22. package/dist/model-context/frame/types.d.ts +4 -1
  23. package/dist/model-context/frame/types.d.ts.map +1 -1
  24. package/dist/model-context/frame/types.js.map +1 -1
  25. package/dist/model-context/registry.d.ts.map +1 -1
  26. package/dist/model-context/registry.js +16 -4
  27. package/dist/model-context/registry.js.map +1 -1
  28. package/dist/react/RuntimeAdapter.d.ts +8 -1
  29. package/dist/react/RuntimeAdapter.d.ts.map +1 -1
  30. package/dist/react/RuntimeAdapter.js +23 -18
  31. package/dist/react/RuntimeAdapter.js.map +1 -1
  32. package/dist/react/adapters/LocalStorageThreadListAdapter.d.ts.map +1 -1
  33. package/dist/react/adapters/LocalStorageThreadListAdapter.js +28 -12
  34. package/dist/react/adapters/LocalStorageThreadListAdapter.js.map +1 -1
  35. package/dist/react/client/AdaptedRemoteThread.d.ts +11 -0
  36. package/dist/react/client/AdaptedRemoteThread.d.ts.map +1 -0
  37. package/dist/react/client/AdaptedRemoteThread.js +27 -0
  38. package/dist/react/client/AdaptedRemoteThread.js.map +1 -0
  39. package/dist/react/client/InMemoryThreadList.d.ts +19 -0
  40. package/dist/react/client/InMemoryThreadList.d.ts.map +1 -0
  41. package/dist/react/client/InMemoryThreadList.js +418 -0
  42. package/dist/react/client/InMemoryThreadList.js.map +1 -0
  43. package/dist/react/client/Interactables.d.ts.map +1 -1
  44. package/dist/react/client/Interactables.js +159 -102
  45. package/dist/react/client/Interactables.js.map +1 -1
  46. package/dist/react/client/RemoteThreadList.d.ts +34 -0
  47. package/dist/react/client/RemoteThreadList.d.ts.map +1 -0
  48. package/dist/react/client/RemoteThreadList.js +898 -0
  49. package/dist/react/client/RemoteThreadList.js.map +1 -0
  50. package/dist/react/client/Tools.d.ts.map +1 -1
  51. package/dist/react/client/Tools.js +38 -27
  52. package/dist/react/client/Tools.js.map +1 -1
  53. package/dist/react/index.d.ts +7 -2
  54. package/dist/react/index.js +5 -2
  55. package/dist/react/interactables-legacy/Interactables.d.ts.map +1 -1
  56. package/dist/react/interactables-legacy/Interactables.js +145 -110
  57. package/dist/react/interactables-legacy/Interactables.js.map +1 -1
  58. package/dist/react/primitive-hooks/useActionBarCopy.d.ts.map +1 -1
  59. package/dist/react/primitive-hooks/useActionBarCopy.js +20 -19
  60. package/dist/react/primitive-hooks/useActionBarCopy.js.map +1 -1
  61. package/dist/react/primitive-hooks/useActionBarEdit.d.ts.map +1 -1
  62. package/dist/react/primitive-hooks/useActionBarEdit.js +2 -4
  63. package/dist/react/primitive-hooks/useActionBarEdit.js.map +1 -1
  64. package/dist/react/primitive-hooks/useActionBarReload.d.ts.map +1 -1
  65. package/dist/react/primitive-hooks/useActionBarReload.js +2 -4
  66. package/dist/react/primitive-hooks/useActionBarReload.js.map +1 -1
  67. package/dist/react/primitive-hooks/useBranchPickerNext.d.ts.map +1 -1
  68. package/dist/react/primitive-hooks/useBranchPickerNext.js +2 -6
  69. package/dist/react/primitive-hooks/useBranchPickerNext.js.map +1 -1
  70. package/dist/react/primitive-hooks/useBranchPickerPrevious.d.ts.map +1 -1
  71. package/dist/react/primitive-hooks/useBranchPickerPrevious.js +2 -6
  72. package/dist/react/primitive-hooks/useBranchPickerPrevious.js.map +1 -1
  73. package/dist/react/primitive-hooks/useComposerCancel.d.ts.map +1 -1
  74. package/dist/react/primitive-hooks/useComposerCancel.js +2 -4
  75. package/dist/react/primitive-hooks/useComposerCancel.js.map +1 -1
  76. package/dist/react/primitive-hooks/useComposerSend.d.ts.map +1 -1
  77. package/dist/react/primitive-hooks/useComposerSend.js +2 -4
  78. package/dist/react/primitive-hooks/useComposerSend.js.map +1 -1
  79. package/dist/react/primitive-hooks/useSuggestionTrigger.d.ts.map +1 -1
  80. package/dist/react/primitive-hooks/useSuggestionTrigger.js +6 -2
  81. package/dist/react/primitive-hooks/useSuggestionTrigger.js.map +1 -1
  82. package/dist/react/primitive-hooks/useThreadIsEmpty.d.ts +3 -0
  83. package/dist/react/primitive-hooks/useThreadIsEmpty.d.ts.map +1 -1
  84. package/dist/react/primitive-hooks/useThreadIsEmpty.js +3 -0
  85. package/dist/react/primitive-hooks/useThreadIsEmpty.js.map +1 -1
  86. package/dist/react/primitive-hooks/useThreadIsRunning.d.ts +3 -0
  87. package/dist/react/primitive-hooks/useThreadIsRunning.d.ts.map +1 -1
  88. package/dist/react/primitive-hooks/useThreadIsRunning.js +3 -0
  89. package/dist/react/primitive-hooks/useThreadIsRunning.js.map +1 -1
  90. package/dist/react/primitives/message/MessageParts.d.ts +13 -0
  91. package/dist/react/primitives/message/MessageParts.d.ts.map +1 -1
  92. package/dist/react/primitives/message/MessageParts.js.map +1 -1
  93. package/dist/react/primitives/thread/ThreadMessages.d.ts.map +1 -1
  94. package/dist/react/primitives/thread/ThreadMessages.js +1 -1
  95. package/dist/react/primitives/thread/ThreadMessages.js.map +1 -1
  96. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts +24 -10
  97. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts.map +1 -1
  98. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js +115 -71
  99. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js.map +1 -1
  100. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts +14 -2
  101. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
  102. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js +232 -63
  103. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js.map +1 -1
  104. package/dist/react/runtimes/RemoteThreadResource.d.ts +30 -0
  105. package/dist/react/runtimes/RemoteThreadResource.d.ts.map +1 -0
  106. package/dist/react/runtimes/RemoteThreadResource.js +136 -0
  107. package/dist/react/runtimes/RemoteThreadResource.js.map +1 -0
  108. package/dist/react/runtimes/RuntimeAdapterProvider.d.ts +3 -10
  109. package/dist/react/runtimes/RuntimeAdapterProvider.d.ts.map +1 -1
  110. package/dist/react/runtimes/RuntimeAdapterProvider.js +3 -6
  111. package/dist/react/runtimes/RuntimeAdapterProvider.js.map +1 -1
  112. package/dist/react/runtimes/assistant-transport/commandQueue.d.ts +17 -0
  113. package/dist/react/runtimes/assistant-transport/commandQueue.d.ts.map +1 -0
  114. package/dist/react/runtimes/assistant-transport/commandQueue.js +55 -0
  115. package/dist/react/runtimes/assistant-transport/commandQueue.js.map +1 -0
  116. package/dist/react/runtimes/assistant-transport/replayBoundaryStream.d.ts +11 -0
  117. package/dist/react/runtimes/assistant-transport/replayBoundaryStream.d.ts.map +1 -0
  118. package/dist/react/runtimes/assistant-transport/replayBoundaryStream.js +165 -0
  119. package/dist/react/runtimes/assistant-transport/replayBoundaryStream.js.map +1 -0
  120. package/dist/react/runtimes/assistant-transport/runManager.d.ts +15 -0
  121. package/dist/react/runtimes/assistant-transport/runManager.d.ts.map +1 -0
  122. package/dist/react/runtimes/assistant-transport/runManager.js +86 -0
  123. package/dist/react/runtimes/assistant-transport/runManager.js.map +1 -0
  124. package/dist/react/runtimes/assistant-transport/types.d.ts +130 -0
  125. package/dist/react/runtimes/assistant-transport/types.d.ts.map +1 -0
  126. package/dist/react/runtimes/assistant-transport/types.js +0 -0
  127. package/dist/react/runtimes/assistant-transport/useAssistantTransportRuntime.d.ts +14 -0
  128. package/dist/react/runtimes/assistant-transport/useAssistantTransportRuntime.d.ts.map +1 -0
  129. package/dist/react/runtimes/assistant-transport/useAssistantTransportRuntime.js +296 -0
  130. package/dist/react/runtimes/assistant-transport/useAssistantTransportRuntime.js.map +1 -0
  131. package/dist/react/runtimes/assistant-transport/useConvertedState.d.ts +7 -0
  132. package/dist/react/runtimes/assistant-transport/useConvertedState.d.ts.map +1 -0
  133. package/dist/react/runtimes/assistant-transport/useConvertedState.js +25 -0
  134. package/dist/react/runtimes/assistant-transport/useConvertedState.js.map +1 -0
  135. package/dist/react/runtimes/assistant-transport/useLatestRef.d.ts +7 -0
  136. package/dist/react/runtimes/assistant-transport/useLatestRef.d.ts.map +1 -0
  137. package/dist/react/runtimes/assistant-transport/useLatestRef.js +27 -0
  138. package/dist/react/runtimes/assistant-transport/useLatestRef.js.map +1 -0
  139. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts.map +1 -1
  140. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js +39 -13
  141. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js.map +1 -1
  142. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.d.ts +2 -1
  143. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.d.ts.map +1 -1
  144. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.js +3 -3
  145. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.js.map +1 -1
  146. package/dist/react/runtimes/cloud/auiV0.d.ts +4 -0
  147. package/dist/react/runtimes/cloud/auiV0.d.ts.map +1 -1
  148. package/dist/react/runtimes/cloud/auiV0.js +7 -0
  149. package/dist/react/runtimes/cloud/auiV0.js.map +1 -1
  150. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.d.ts.map +1 -1
  151. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js +60 -17
  152. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js.map +1 -1
  153. package/dist/react/runtimes/cloud/useCloudThreadListRuntime.d.ts +16 -0
  154. package/dist/react/runtimes/cloud/useCloudThreadListRuntime.d.ts.map +1 -0
  155. package/dist/react/runtimes/cloud/useCloudThreadListRuntime.js +36 -0
  156. package/dist/react/runtimes/cloud/useCloudThreadListRuntime.js.map +1 -0
  157. package/dist/react/runtimes/external-message-converter.js +14 -14
  158. package/dist/react/runtimes/external-message-converter.js.map +1 -1
  159. package/dist/react/runtimes/useExternalStoreRuntime.d.ts.map +1 -1
  160. package/dist/react/runtimes/useExternalStoreRuntime.js +44 -28
  161. package/dist/react/runtimes/useExternalStoreRuntime.js.map +1 -1
  162. package/dist/react/runtimes/useExternalStoreSharedOptions.js.map +1 -1
  163. package/dist/react/runtimes/useLocalRuntime.js +1 -1
  164. package/dist/react/runtimes/useRuntimeAdapters.d.ts +9 -0
  165. package/dist/react/runtimes/useRuntimeAdapters.d.ts.map +1 -0
  166. package/dist/react/runtimes/useRuntimeAdapters.js +20 -0
  167. package/dist/react/runtimes/useRuntimeAdapters.js.map +1 -0
  168. package/dist/runtime/api/composer-runtime.d.ts +5 -0
  169. package/dist/runtime/api/composer-runtime.d.ts.map +1 -1
  170. package/dist/runtime/api/composer-runtime.js.map +1 -1
  171. package/dist/runtime/api/message-runtime.js +1 -1
  172. package/dist/runtime/api/thread-list-runtime.d.ts +1 -0
  173. package/dist/runtime/api/thread-list-runtime.d.ts.map +1 -1
  174. package/dist/runtime/api/thread-list-runtime.js +4 -2
  175. package/dist/runtime/api/thread-list-runtime.js.map +1 -1
  176. package/dist/runtime/api/thread-runtime.d.ts +12 -2
  177. package/dist/runtime/api/thread-runtime.d.ts.map +1 -1
  178. package/dist/runtime/api/thread-runtime.js +8 -2
  179. package/dist/runtime/api/thread-runtime.js.map +1 -1
  180. package/dist/runtime/base/base-composer-runtime-core.d.ts.map +1 -1
  181. package/dist/runtime/base/base-composer-runtime-core.js +8 -7
  182. package/dist/runtime/base/base-composer-runtime-core.js.map +1 -1
  183. package/dist/runtime/base/base-thread-runtime-core.d.ts +1 -0
  184. package/dist/runtime/base/base-thread-runtime-core.d.ts.map +1 -1
  185. package/dist/runtime/base/base-thread-runtime-core.js +3 -3
  186. package/dist/runtime/base/base-thread-runtime-core.js.map +1 -1
  187. package/dist/runtime/base/default-thread-composer-runtime-core.d.ts +0 -1
  188. package/dist/runtime/base/default-thread-composer-runtime-core.d.ts.map +1 -1
  189. package/dist/runtime/base/default-thread-composer-runtime-core.js +10 -4
  190. package/dist/runtime/base/default-thread-composer-runtime-core.js.map +1 -1
  191. package/dist/runtime/interfaces/thread-runtime-core.d.ts +6 -0
  192. package/dist/runtime/interfaces/thread-runtime-core.d.ts.map +1 -1
  193. package/dist/runtime/internal.js +5 -5
  194. package/dist/runtime/queue/message-queue.d.ts.map +1 -1
  195. package/dist/runtime/queue/message-queue.js +2 -1
  196. package/dist/runtime/queue/message-queue.js.map +1 -1
  197. package/dist/runtime/utils/message-repository.d.ts.map +1 -1
  198. package/dist/runtime/utils/message-repository.js +27 -18
  199. package/dist/runtime/utils/message-repository.js.map +1 -1
  200. package/dist/runtime/utils/thread-runtime-lifecycle.d.ts +8 -0
  201. package/dist/runtime/utils/thread-runtime-lifecycle.d.ts.map +1 -0
  202. package/dist/runtime/utils/thread-runtime-lifecycle.js +11 -0
  203. package/dist/runtime/utils/thread-runtime-lifecycle.js.map +1 -0
  204. package/dist/runtimes/external-store/external-store-shared-options.js.map +1 -1
  205. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.d.ts.map +1 -1
  206. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js +4 -1
  207. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js.map +1 -1
  208. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts +8 -0
  209. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts.map +1 -1
  210. package/dist/runtimes/external-store/external-store-thread-runtime-core.js +37 -13
  211. package/dist/runtimes/external-store/external-store-thread-runtime-core.js.map +1 -1
  212. package/dist/runtimes/inert/InertThreadRuntimeCore.d.ts +102 -0
  213. package/dist/runtimes/inert/InertThreadRuntimeCore.d.ts.map +1 -0
  214. package/dist/runtimes/inert/InertThreadRuntimeCore.js +156 -0
  215. package/dist/runtimes/inert/InertThreadRuntimeCore.js.map +1 -0
  216. package/dist/runtimes/internal.d.ts +1 -1
  217. package/dist/runtimes/local/local-thread-runtime-core.d.ts +3 -0
  218. package/dist/runtimes/local/local-thread-runtime-core.d.ts.map +1 -1
  219. package/dist/runtimes/local/local-thread-runtime-core.js +78 -19
  220. package/dist/runtimes/local/local-thread-runtime-core.js.map +1 -1
  221. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.d.ts +12 -59
  222. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.d.ts.map +1 -1
  223. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.js +10 -142
  224. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.js.map +1 -1
  225. package/dist/runtimes/remote-thread-list/adapter-changed.d.ts +9 -0
  226. package/dist/runtimes/remote-thread-list/adapter-changed.d.ts.map +1 -0
  227. package/dist/runtimes/remote-thread-list/adapter-changed.js +13 -0
  228. package/dist/runtimes/remote-thread-list/adapter-changed.js.map +1 -0
  229. package/dist/runtimes/remote-thread-list/empty-thread-core.d.ts.map +1 -1
  230. package/dist/runtimes/remote-thread-list/empty-thread-core.js +16 -152
  231. package/dist/runtimes/remote-thread-list/empty-thread-core.js.map +1 -1
  232. package/dist/runtimes/remote-thread-list/optimistic-state.d.ts +2 -0
  233. package/dist/runtimes/remote-thread-list/optimistic-state.d.ts.map +1 -1
  234. package/dist/runtimes/remote-thread-list/optimistic-state.js +11 -0
  235. package/dist/runtimes/remote-thread-list/optimistic-state.js.map +1 -1
  236. package/dist/runtimes/remote-thread-list/types.d.ts +32 -1
  237. package/dist/runtimes/remote-thread-list/types.d.ts.map +1 -1
  238. package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts +1 -12
  239. package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts.map +1 -1
  240. package/dist/runtimes/tool-invocations/ToolInvocationTracker.js +67 -38
  241. package/dist/runtimes/tool-invocations/ToolInvocationTracker.js.map +1 -1
  242. package/dist/store/clients/external-thread.js +1 -1
  243. package/dist/store/clients/external-thread.js.map +1 -1
  244. package/dist/store/clients/suggestions.js +2 -2
  245. package/dist/store/clients/suggestions.js.map +1 -1
  246. package/dist/store/clients/thread-selection-events.d.ts +10 -0
  247. package/dist/store/clients/thread-selection-events.d.ts.map +1 -0
  248. package/dist/store/clients/thread-selection-events.js +40 -0
  249. package/dist/store/clients/thread-selection-events.js.map +1 -0
  250. package/dist/store/env.d.ts +5 -0
  251. package/dist/store/env.d.ts.map +1 -0
  252. package/dist/store/env.js +12 -0
  253. package/dist/store/env.js.map +1 -0
  254. package/dist/store/index.d.ts +5 -3
  255. package/dist/store/index.js +4 -2
  256. package/dist/store/internal.d.ts +4 -1
  257. package/dist/store/internal.js +4 -1
  258. package/dist/store/primitive-predicates.d.ts +19 -0
  259. package/dist/store/primitive-predicates.d.ts.map +1 -0
  260. package/dist/store/primitive-predicates.js +19 -0
  261. package/dist/store/primitive-predicates.js.map +1 -0
  262. package/dist/store/runtime-clients/attachment-runtime-client.d.ts.map +1 -1
  263. package/dist/store/runtime-clients/attachment-runtime-client.js +18 -11
  264. package/dist/store/runtime-clients/attachment-runtime-client.js.map +1 -1
  265. package/dist/store/runtime-clients/handle-runtime-action.d.ts +5 -0
  266. package/dist/store/runtime-clients/handle-runtime-action.d.ts.map +1 -0
  267. package/dist/store/runtime-clients/handle-runtime-action.js +14 -0
  268. package/dist/store/runtime-clients/handle-runtime-action.js.map +1 -0
  269. package/dist/store/runtime-clients/handle-thread-list-action.d.ts +5 -0
  270. package/dist/store/runtime-clients/handle-thread-list-action.d.ts.map +1 -0
  271. package/dist/store/runtime-clients/handle-thread-list-action.js +7 -0
  272. package/dist/store/runtime-clients/handle-thread-list-action.js.map +1 -0
  273. package/dist/store/runtime-clients/thread-list-item-runtime-client.d.ts.map +1 -1
  274. package/dist/store/runtime-clients/thread-list-item-runtime-client.js +62 -29
  275. package/dist/store/runtime-clients/thread-list-item-runtime-client.js.map +1 -1
  276. package/dist/store/runtime-clients/thread-list-runtime-client.d.ts.map +1 -1
  277. package/dist/store/runtime-clients/thread-list-runtime-client.js +5 -6
  278. package/dist/store/runtime-clients/thread-list-runtime-client.js.map +1 -1
  279. package/dist/store/scopes/composer.d.ts +9 -4
  280. package/dist/store/scopes/composer.d.ts.map +1 -1
  281. package/dist/store/scopes/thread-list-item.d.ts +7 -6
  282. package/dist/store/scopes/thread-list-item.d.ts.map +1 -1
  283. package/dist/store/scopes/thread.d.ts +8 -7
  284. package/dist/store/scopes/thread.d.ts.map +1 -1
  285. package/dist/store/scopes/threads.d.ts +17 -1
  286. package/dist/store/scopes/threads.d.ts.map +1 -1
  287. package/dist/subscribable/subscribable.d.ts +2 -1
  288. package/dist/subscribable/subscribable.d.ts.map +1 -1
  289. package/dist/subscribable/subscribable.js +23 -18
  290. package/dist/subscribable/subscribable.js.map +1 -1
  291. package/dist/types/message.d.ts +1 -1
  292. package/dist/types/message.js.map +1 -1
  293. package/dist/utils/composite-context-provider.d.ts +1 -0
  294. package/dist/utils/composite-context-provider.d.ts.map +1 -1
  295. package/dist/utils/composite-context-provider.js +25 -9
  296. package/dist/utils/composite-context-provider.js.map +1 -1
  297. package/dist/utils/notify-event-listeners.d.ts +2 -2
  298. package/dist/utils/notify-event-listeners.d.ts.map +1 -1
  299. package/dist/utils/notify-event-listeners.js +2 -2
  300. package/dist/utils/notify-event-listeners.js.map +1 -1
  301. package/dist/utils/silent-runtime-action.d.ts +6 -0
  302. package/dist/utils/silent-runtime-action.d.ts.map +1 -0
  303. package/dist/utils/silent-runtime-action.js +7 -0
  304. package/dist/utils/silent-runtime-action.js.map +1 -0
  305. package/package.json +8 -8
  306. package/src/adapters/speech.test.ts +118 -1
  307. package/src/adapters/speech.ts +21 -22
  308. package/src/adapters/thread-history.ts +2 -0
  309. package/src/adapters/voice.test.ts +134 -0
  310. package/src/adapters/voice.ts +35 -27
  311. package/src/index.ts +1 -0
  312. package/src/internal.ts +1 -0
  313. package/src/model-context/frame/host.test.ts +87 -5
  314. package/src/model-context/frame/host.ts +18 -4
  315. package/src/model-context/frame/provider.test.ts +347 -20
  316. package/src/model-context/frame/provider.ts +58 -2
  317. package/src/model-context/frame/types.ts +5 -0
  318. package/src/model-context/registry.test.ts +131 -0
  319. package/src/model-context/registry.ts +16 -6
  320. package/src/react/RuntimeAdapter.test.ts +2 -0
  321. package/src/react/RuntimeAdapter.ts +20 -8
  322. package/src/react/adapters/LocalStorageThreadListAdapter.tsx +34 -17
  323. package/src/react/client/AdaptedRemoteThread.ts +41 -0
  324. package/src/react/client/InMemoryThreadList.test.tsx +148 -0
  325. package/src/react/client/InMemoryThreadList.ts +290 -0
  326. package/src/react/client/Interactables.test.ts +326 -2
  327. package/src/react/client/Interactables.ts +227 -110
  328. package/src/react/client/RemoteThreadList.test.ts +1222 -0
  329. package/src/react/client/RemoteThreadList.ts +1136 -0
  330. package/src/react/client/Tools.ts +36 -29
  331. package/src/react/index.ts +13 -0
  332. package/src/react/interactables-legacy/Interactables.test.ts +317 -0
  333. package/src/react/interactables-legacy/Interactables.ts +204 -128
  334. package/src/react/primitive-hooks/useActionBarCopy.test.ts +15 -0
  335. package/src/react/primitive-hooks/useActionBarCopy.ts +15 -10
  336. package/src/react/primitive-hooks/useActionBarEdit.ts +2 -1
  337. package/src/react/primitive-hooks/useActionBarReload.ts +2 -6
  338. package/src/react/primitive-hooks/useBranchPickerNext.ts +2 -7
  339. package/src/react/primitive-hooks/useBranchPickerPrevious.ts +2 -7
  340. package/src/react/primitive-hooks/useComposerCancel.ts +2 -1
  341. package/src/react/primitive-hooks/useComposerSend.ts +2 -5
  342. package/src/react/primitive-hooks/useSuggestionTrigger.test.ts +11 -0
  343. package/src/react/primitive-hooks/useSuggestionTrigger.ts +4 -5
  344. package/src/react/primitive-hooks/useThreadIsEmpty.ts +3 -0
  345. package/src/react/primitive-hooks/useThreadIsRunning.ts +3 -0
  346. package/src/react/primitives/message/MessageParts.tsx +0 -1
  347. package/src/react/primitives/thread/ThreadMessages.tsx +2 -1
  348. package/src/react/runtimes/RemoteThreadListHookInstanceManager.retry.test.tsx +116 -0
  349. package/src/react/runtimes/RemoteThreadListHookInstanceManager.running.test.tsx +1 -1
  350. package/src/react/runtimes/RemoteThreadListHookInstanceManager.test.tsx +57 -6
  351. package/src/react/runtimes/RemoteThreadListHookInstanceManager.title.test.tsx +272 -0
  352. package/src/react/runtimes/RemoteThreadListHookInstanceManager.tsx +171 -124
  353. package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.republish.test.ts +87 -0
  354. package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.tsx +327 -83
  355. package/src/react/runtimes/RemoteThreadResource.test.ts +141 -0
  356. package/src/react/runtimes/RemoteThreadResource.ts +233 -0
  357. package/src/react/runtimes/RuntimeAdapterProvider.tsx +8 -20
  358. package/src/react/runtimes/assistant-transport/commandQueue.ts +68 -0
  359. package/src/react/runtimes/assistant-transport/replayBoundaryStream.test.ts +455 -0
  360. package/src/react/runtimes/assistant-transport/replayBoundaryStream.ts +172 -0
  361. package/src/react/runtimes/assistant-transport/runManager.ts +124 -0
  362. package/src/react/runtimes/assistant-transport/transport-delivery.test.tsx +79 -0
  363. package/src/react/runtimes/assistant-transport/transport-parentid.test.tsx +97 -0
  364. package/src/react/runtimes/assistant-transport/transport-scheduling.test.ts +414 -0
  365. package/src/react/runtimes/assistant-transport/types.ts +170 -0
  366. package/src/react/runtimes/assistant-transport/useAssistantTransport.spec.md +141 -0
  367. package/src/react/runtimes/assistant-transport/useAssistantTransportRuntime.test.tsx +683 -0
  368. package/src/react/runtimes/assistant-transport/useAssistantTransportRuntime.ts +483 -0
  369. package/src/react/runtimes/assistant-transport/useConvertedState.ts +20 -0
  370. package/src/react/runtimes/assistant-transport/useLatestRef.ts +9 -0
  371. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.test.tsx +131 -6
  372. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.ts +61 -15
  373. package/src/react/runtimes/cloud/CloudFileAttachmentAdapter.ts +6 -4
  374. package/src/react/runtimes/cloud/auiV0.ts +17 -1
  375. package/src/react/runtimes/cloud/useCloudThreadListAdapter.test.tsx +98 -3
  376. package/src/react/runtimes/cloud/useCloudThreadListAdapter.tsx +104 -27
  377. package/src/react/runtimes/cloud/useCloudThreadListRuntime.test.tsx +56 -0
  378. package/src/react/runtimes/cloud/useCloudThreadListRuntime.ts +31 -0
  379. package/src/react/runtimes/external-message-converter.test.ts +143 -0
  380. package/src/react/runtimes/external-message-converter.ts +41 -41
  381. package/src/react/runtimes/remote-thread-hook-on-tap.test.ts +58 -0
  382. package/src/react/runtimes/useExternalStoreRuntime.lifecycle.test.tsx +83 -0
  383. package/src/react/runtimes/useExternalStoreRuntime.suggestions.test.tsx +13 -3
  384. package/src/react/runtimes/useExternalStoreRuntime.ts +7 -0
  385. package/src/react/runtimes/useExternalStoreSharedOptions.ts +3 -1
  386. package/src/react/runtimes/useLocalRuntime.test.tsx +134 -8
  387. package/src/react/runtimes/useRuntimeAdapters.test.tsx +62 -0
  388. package/src/react/runtimes/useRuntimeAdapters.ts +28 -0
  389. package/src/runtime/api/composer-runtime.ts +5 -0
  390. package/src/runtime/api/thread-list-runtime.ts +3 -1
  391. package/src/runtime/api/thread-runtime.ts +20 -2
  392. package/src/runtime/base/base-composer-runtime-core.ts +6 -5
  393. package/src/runtime/base/base-thread-runtime-core.test.ts +191 -0
  394. package/src/runtime/base/base-thread-runtime-core.ts +11 -2
  395. package/src/runtime/base/default-thread-composer-runtime-core.ts +12 -4
  396. package/src/runtime/interfaces/thread-runtime-core.ts +6 -0
  397. package/src/runtime/queue/message-queue.ts +2 -1
  398. package/src/runtime/utils/message-repository.ts +26 -18
  399. package/src/runtime/utils/thread-runtime-lifecycle.ts +18 -0
  400. package/src/runtimes/external-store/external-store-shared-options.ts +3 -1
  401. package/src/runtimes/external-store/external-store-thread-list-runtime-core.ts +4 -1
  402. package/src/runtimes/external-store/external-store-thread-runtime-core.ts +103 -34
  403. package/src/runtimes/inert/InertThreadRuntimeCore.test.ts +253 -0
  404. package/src/runtimes/inert/InertThreadRuntimeCore.ts +232 -0
  405. package/src/runtimes/local/local-thread-runtime-core.test.ts +692 -4
  406. package/src/runtimes/local/local-thread-runtime-core.ts +117 -22
  407. package/src/runtimes/readonly/ReadonlyThreadRuntimeCore.ts +17 -205
  408. package/src/runtimes/remote-thread-list/adapter-changed.ts +10 -0
  409. package/src/runtimes/remote-thread-list/empty-thread-core.ts +28 -217
  410. package/src/runtimes/remote-thread-list/optimistic-state.test.ts +18 -0
  411. package/src/runtimes/remote-thread-list/optimistic-state.ts +13 -0
  412. package/src/runtimes/remote-thread-list/types.ts +34 -0
  413. package/src/runtimes/tool-invocations/EDGE_CASES.md +17 -6
  414. package/src/runtimes/tool-invocations/ToolInvocationTracker.test.ts +243 -0
  415. package/src/runtimes/tool-invocations/ToolInvocationTracker.ts +127 -61
  416. package/src/store/clients/external-thread.ts +1 -1
  417. package/src/store/clients/model-context-client.test.ts +16 -8
  418. package/src/store/clients/suggestions.ts +2 -2
  419. package/src/store/clients/thread-selection-events.ts +21 -0
  420. package/src/store/env.ts +11 -0
  421. package/src/store/index.ts +14 -1
  422. package/src/store/internal.ts +13 -0
  423. package/src/store/primitive-predicates.test.ts +184 -0
  424. package/src/store/primitive-predicates.ts +43 -0
  425. package/src/store/runtime-clients/attachment-runtime-client.test.ts +41 -0
  426. package/src/store/runtime-clients/attachment-runtime-client.ts +2 -1
  427. package/src/store/runtime-clients/handle-runtime-action.test.ts +40 -0
  428. package/src/store/runtime-clients/handle-runtime-action.ts +14 -0
  429. package/src/store/runtime-clients/handle-thread-list-action.test.ts +69 -0
  430. package/src/store/runtime-clients/handle-thread-list-action.ts +6 -0
  431. package/src/store/runtime-clients/thread-list-item-runtime-client.ts +15 -7
  432. package/src/store/runtime-clients/thread-list-runtime-client.ts +9 -6
  433. package/src/store/scopes/composer.ts +9 -4
  434. package/src/store/scopes/thread-list-item.ts +7 -6
  435. package/src/store/scopes/thread.ts +8 -7
  436. package/src/store/scopes/threads.ts +14 -0
  437. package/src/subscribable/subscribable.test.ts +77 -1
  438. package/src/subscribable/subscribable.ts +38 -23
  439. package/src/tests/MessageRepository.test.ts +48 -0
  440. package/src/tests/RemoteThreadListThreadListRuntimeCore-errors.test.ts +2 -2
  441. package/src/tests/RemoteThreadListThreadListRuntimeCore-loadMore.test.ts +8 -6
  442. package/src/tests/RemoteThreadListThreadListRuntimeCore-switchToThread-unarchive.test.ts +25 -0
  443. package/src/tests/auiV0Encode.test.ts +66 -0
  444. package/src/tests/base-composer-runtime-core-send.test.ts +30 -0
  445. package/src/tests/base-composer-runtime-core.test.ts +28 -0
  446. package/src/tests/composer-can-cancel.test.ts +101 -0
  447. package/src/tests/empty-thread-core.test.ts +6 -0
  448. package/src/tests/external-store-thread-list-runtime-core.test.ts +101 -0
  449. package/src/tests/external-store-thread-runtime-core-adapter.test.ts +211 -1
  450. package/src/tests/external-store-thread-runtime-core.test.ts +124 -0
  451. package/src/tests/external-thread-isEmpty.test.tsx +100 -0
  452. package/src/tests/interactables-toolui-migration.test.tsx +66 -0
  453. package/src/tests/message-queue.test.ts +28 -0
  454. package/src/tests/remote-thread-list-adapter-switch.test.ts +383 -0
  455. package/src/tests/session-reset-notification.test.ts +145 -0
  456. package/src/tests/thread-switch-events.test.tsx +99 -1
  457. package/src/tests/tools-scope-migration.test.tsx +58 -0
  458. package/src/tests/useRemoteThreadListRuntime-controlled.test.tsx +67 -0
  459. package/src/types/message.ts +1 -1
  460. package/src/utils/composite-context-provider.test.ts +139 -0
  461. package/src/utils/composite-context-provider.ts +26 -8
  462. package/src/utils/notify-event-listeners.ts +10 -5
  463. package/src/utils/silent-runtime-action.ts +6 -0
@@ -14,6 +14,12 @@ import {
14
14
  } from "assistant-cloud";
15
15
  import { auiV0Decode, auiV0Encode } from "./auiV0";
16
16
  import { type AssistantClient, getClientId, useAui } from "@assistant-ui/store";
17
+ import type { ThreadListItemMethods } from "../../../store/scopes/thread-list-item";
18
+
19
+ type CloudThreadListItem = Pick<
20
+ ThreadListItemMethods,
21
+ "getState" | "initialize"
22
+ >;
17
23
 
18
24
  const globalPersistence = new WeakMap<
19
25
  getClientId.ClientId,
@@ -36,8 +42,10 @@ class AssistantCloudThreadHistoryAdapter implements ThreadHistoryAdapter {
36
42
  return this.getAui();
37
43
  }
38
44
 
39
- private get _persistence(): CloudMessagePersistence {
40
- const key = getClientId(this.aui.threadListItem);
45
+ private getPersistence(
46
+ threadListItem: CloudThreadListItem = this.aui.threadListItem,
47
+ ): CloudMessagePersistence {
48
+ const key = getClientId(threadListItem);
41
49
  if (!globalPersistence.has(key)) {
42
50
  globalPersistence.set(
43
51
  key,
@@ -47,24 +55,57 @@ class AssistantCloudThreadHistoryAdapter implements ThreadHistoryAdapter {
47
55
  return globalPersistence.get(key)!;
48
56
  }
49
57
 
58
+ private get _persistence(): CloudMessagePersistence {
59
+ return this.getPersistence();
60
+ }
61
+
62
+ private tryGetKeyedThreadListItem(): CloudThreadListItem | undefined {
63
+ const live = this.aui.threadListItem;
64
+ if (!live.source) return undefined;
65
+ const id = live.getState().id;
66
+ if (id === undefined) return undefined;
67
+ return this.aui.threads.item({ id });
68
+ }
69
+
50
70
  withFormat<TMessage, TStorageFormat extends Record<string, unknown>>(
51
71
  formatAdapter: MessageFormatAdapter<TMessage, TStorageFormat>,
52
72
  ): GenericThreadHistoryAdapter<TMessage> {
53
73
  const adapter = this;
54
- const formatted = createFormattedPersistence(
55
- this._persistence,
56
- formatAdapter,
57
- );
74
+ let threadListItem: CloudThreadListItem | undefined;
75
+ const pinCurrent = () => {
76
+ const next = adapter.tryGetKeyedThreadListItem();
77
+ if (next) threadListItem = next;
78
+ return threadListItem;
79
+ };
80
+ const resolvePinned = () => threadListItem ?? pinCurrent();
81
+ const getFormatted = () =>
82
+ createFormattedPersistence(adapter._persistence, formatAdapter);
83
+ const getTargetFormatted = (item: CloudThreadListItem) =>
84
+ createFormattedPersistence(adapter.getPersistence(item), formatAdapter);
58
85
  return {
59
- // Note: callers must also call reportTelemetry() for run tracking
86
+ pin() {
87
+ pinCurrent();
88
+ },
60
89
  async append(item: MessageFormatItem<TMessage>) {
61
- const { remoteId } = await adapter.aui.threadListItem.initialize();
62
- await formatted.append(remoteId, item);
90
+ const pinned = resolvePinned();
91
+ if (!pinned) {
92
+ throw new Error(
93
+ "Cannot persist cloud history without a thread list item.",
94
+ );
95
+ }
96
+ const remoteId =
97
+ pinned.getState().remoteId ?? (await pinned.initialize()).remoteId;
98
+ await getTargetFormatted(pinned).append(remoteId, item);
63
99
  },
64
100
  async update(item: MessageFormatItem<TMessage>, localMessageId: string) {
65
- const remoteId = adapter.aui.threadListItem.getState().remoteId;
66
- if (!remoteId) return;
67
- await formatted.update?.(remoteId, item, localMessageId);
101
+ const pinned = resolvePinned();
102
+ const remoteId = pinned?.getState().remoteId;
103
+ if (!remoteId || !pinned) return;
104
+ await getTargetFormatted(pinned).update?.(
105
+ remoteId,
106
+ item,
107
+ localMessageId,
108
+ );
68
109
  },
69
110
  async delete() {
70
111
  throw new Error(
@@ -85,12 +126,15 @@ class AssistantCloudThreadHistoryAdapter implements ThreadHistoryAdapter {
85
126
  formatAdapter.format,
86
127
  encodedRunMessages,
87
128
  options,
129
+ resolvePinned(),
88
130
  );
89
131
  },
90
132
  async load(): Promise<MessageFormatRepository<TMessage>> {
91
- const remoteId = adapter.aui.threadListItem.getState().remoteId;
133
+ pinCurrent();
134
+ const live = adapter.aui.threadListItem;
135
+ const remoteId = live.source ? live.getState().remoteId : undefined;
92
136
  if (!remoteId) return { messages: [] };
93
- return formatted.load(remoteId);
137
+ return getFormatted().load(remoteId);
94
138
  },
95
139
  };
96
140
  }
@@ -153,10 +197,12 @@ class AssistantCloudThreadHistoryAdapter implements ThreadHistoryAdapter {
153
197
  durationMs?: number;
154
198
  stepTimestamps?: StepTimestamp[];
155
199
  },
200
+ threadListItem?: CloudThreadListItem,
156
201
  ) {
157
202
  if (!this.cloudRef.current.telemetry.enabled) return;
158
203
 
159
- const remoteId = this.aui.threadListItem.getState().remoteId;
204
+ const remoteId = (threadListItem ?? this.aui.threadListItem).getState()
205
+ .remoteId;
160
206
  if (!remoteId) return;
161
207
 
162
208
  const extracted = extractRunTelemetry(format, runMessages);
@@ -19,10 +19,12 @@ const guessAttachmentType = (
19
19
  export class CloudFileAttachmentAdapter implements AttachmentAdapter {
20
20
  public accept = "*";
21
21
 
22
- private cloud: AssistantCloud;
22
+ private getCloud: () => AssistantCloud;
23
23
 
24
- constructor(cloud: AssistantCloud) {
25
- this.cloud = cloud;
24
+ constructor(cloud: AssistantCloud);
25
+ constructor(getCloud: () => AssistantCloud);
26
+ constructor(cloud: AssistantCloud | (() => AssistantCloud)) {
27
+ this.getCloud = typeof cloud === "function" ? cloud : () => cloud;
26
28
  }
27
29
 
28
30
  private uploadedUrls = new Map<string, string>();
@@ -46,7 +48,7 @@ export class CloudFileAttachmentAdapter implements AttachmentAdapter {
46
48
 
47
49
  try {
48
50
  const { signedUrl, publicUrl } =
49
- await this.cloud.files.generatePresignedUploadUrl({
51
+ await this.getCloud().files.generatePresignedUploadUrl({
50
52
  filename: file.name,
51
53
  });
52
54
  const res = await fetch(signedUrl, {
@@ -79,6 +79,11 @@ type AuiV0MessagePart =
79
79
  readonly mimeType: string;
80
80
  readonly filename?: string;
81
81
  readonly sourceType?: "url" | "id";
82
+ }
83
+ | {
84
+ readonly type: "data";
85
+ readonly name: string;
86
+ readonly data: ReadonlyJSONValue;
82
87
  };
83
88
 
84
89
  type AuiV0AttachmentPart =
@@ -296,8 +301,19 @@ export function auiV0Encode(message: ThreadMessage): AuiV0Message {
296
301
  ...(part.sourceType ? { sourceType: part.sourceType } : undefined),
297
302
  };
298
303
 
304
+ case "data": {
305
+ if (!isJSONValue(part.data)) {
306
+ console.warn(`data part is not JSON! ${JSON.stringify(part)}`);
307
+ }
308
+ return {
309
+ type: "data",
310
+ name: part.name,
311
+ data: part.data as ReadonlyJSONValue,
312
+ };
313
+ }
314
+
299
315
  default: {
300
- const unhandledType: "audio" | "data" | "generative-ui" = type;
316
+ const unhandledType: "audio" | "generative-ui" = type;
301
317
  throw new Error(
302
318
  `Message part type not supported by aui/v0: ${unhandledType}`,
303
319
  );
@@ -19,7 +19,38 @@ const makeThread = (id: string) => ({
19
19
  });
20
20
 
21
21
  describe("useCloudThreadListAdapter", () => {
22
- it("exposes full Cloud pages through the remote thread cursor", async () => {
22
+ it("loads archived Cloud threads alongside regular threads", async () => {
23
+ const activeThreads = [makeThread("active-1")];
24
+ const archivedThreads = [
25
+ { ...makeThread("archived-1"), is_archived: true },
26
+ ];
27
+ const list = vi
28
+ .fn()
29
+ .mockResolvedValueOnce({ threads: activeThreads })
30
+ .mockResolvedValueOnce({ threads: archivedThreads });
31
+ const cloud = { threads: { list } } as unknown as AssistantCloud;
32
+ const { result } = renderHook(() => useCloudThreadListAdapter({ cloud }));
33
+
34
+ const page = await result.current.list();
35
+
36
+ expect(list).toHaveBeenNthCalledWith(1, { limit: 20 });
37
+ expect(list).toHaveBeenNthCalledWith(2, {
38
+ is_archived: true,
39
+ limit: 20,
40
+ });
41
+ expect(page.threads.map((thread) => thread.remoteId)).toEqual([
42
+ "active-1",
43
+ "archived-1",
44
+ ]);
45
+ expect(
46
+ page.threads.find((thread) => thread.remoteId === "active-1")?.status,
47
+ ).toBe("regular");
48
+ expect(
49
+ page.threads.find((thread) => thread.remoteId === "archived-1")?.status,
50
+ ).toBe("archived");
51
+ });
52
+
53
+ it("continues the active list once the archived list is exhausted", async () => {
23
54
  const firstPage = Array.from({ length: 20 }, (_, index) =>
24
55
  makeThread(`thread-${index + 1}`),
25
56
  );
@@ -27,17 +58,20 @@ describe("useCloudThreadListAdapter", () => {
27
58
  const list = vi
28
59
  .fn()
29
60
  .mockResolvedValueOnce({ threads: firstPage })
61
+ .mockResolvedValueOnce({ threads: [] })
30
62
  .mockResolvedValueOnce({ threads: secondPage });
31
63
  const cloud = { threads: { list } } as unknown as AssistantCloud;
32
64
  const { result } = renderHook(() => useCloudThreadListAdapter({ cloud }));
33
65
 
34
66
  const first = await result.current.list();
35
67
  expect(list).toHaveBeenNthCalledWith(1, { limit: 20 });
68
+ expect(list).toHaveBeenNthCalledWith(2, { is_archived: true, limit: 20 });
36
69
  expect(first.threads).toHaveLength(20);
37
- expect(first.nextCursor).toBe("thread-20");
70
+ expect(JSON.parse(first.nextCursor!)).toEqual({ a: "thread-20", re: true });
38
71
 
39
72
  const second = await result.current.list({ after: first.nextCursor });
40
- expect(list).toHaveBeenNthCalledWith(2, {
73
+ expect(list).toHaveBeenCalledTimes(3);
74
+ expect(list).toHaveBeenNthCalledWith(3, {
41
75
  limit: 20,
42
76
  after: "thread-20",
43
77
  });
@@ -46,4 +80,65 @@ describe("useCloudThreadListAdapter", () => {
46
80
  ]);
47
81
  expect(second.nextCursor).toBeUndefined();
48
82
  });
83
+
84
+ it("paginates both legs without dropping or duplicating items", async () => {
85
+ const activePage1 = Array.from({ length: 20 }, (_, index) =>
86
+ makeThread(`a-${index + 1}`),
87
+ );
88
+ const archivedPage1 = Array.from({ length: 20 }, (_, index) => ({
89
+ ...makeThread(`r-${index + 1}`),
90
+ is_archived: true,
91
+ }));
92
+ const activePage2 = [makeThread("a-21")];
93
+ const archivedPage2 = [{ ...makeThread("r-21"), is_archived: true }];
94
+ const list = vi
95
+ .fn()
96
+ .mockResolvedValueOnce({ threads: activePage1 })
97
+ .mockResolvedValueOnce({ threads: archivedPage1 })
98
+ .mockResolvedValueOnce({ threads: activePage2 })
99
+ .mockResolvedValueOnce({ threads: archivedPage2 });
100
+ const cloud = { threads: { list } } as unknown as AssistantCloud;
101
+ const { result } = renderHook(() => useCloudThreadListAdapter({ cloud }));
102
+
103
+ const page1 = await result.current.list();
104
+ expect(page1.threads).toHaveLength(40);
105
+ expect(JSON.parse(page1.nextCursor!)).toEqual({ a: "a-20", r: "r-20" });
106
+
107
+ const page2 = await result.current.list({ after: page1.nextCursor });
108
+ expect(list).toHaveBeenNthCalledWith(3, { limit: 20, after: "a-20" });
109
+ expect(list).toHaveBeenNthCalledWith(4, {
110
+ is_archived: true,
111
+ limit: 20,
112
+ after: "r-20",
113
+ });
114
+ expect(page2.threads.map((thread) => thread.remoteId)).toEqual([
115
+ "a-21",
116
+ "r-21",
117
+ ]);
118
+ expect(page2.nextCursor).toBeUndefined();
119
+ });
120
+
121
+ it("accepts a legacy bare-id cursor for the active list", async () => {
122
+ const activeThreads = [makeThread("thread-21")];
123
+ const list = vi
124
+ .fn()
125
+ .mockResolvedValueOnce({ threads: activeThreads })
126
+ .mockResolvedValueOnce({ threads: [] });
127
+ const cloud = { threads: { list } } as unknown as AssistantCloud;
128
+ const { result } = renderHook(() => useCloudThreadListAdapter({ cloud }));
129
+
130
+ const page = await result.current.list({ after: "thread-20" });
131
+
132
+ expect(list).toHaveBeenNthCalledWith(1, {
133
+ limit: 20,
134
+ after: "thread-20",
135
+ });
136
+ expect(list).toHaveBeenNthCalledWith(2, {
137
+ is_archived: true,
138
+ limit: 20,
139
+ });
140
+ expect(page.threads.map((thread) => thread.remoteId)).toEqual([
141
+ "thread-21",
142
+ ]);
143
+ });
49
144
  });
@@ -3,16 +3,21 @@ declare const process: { env: Record<string, string | undefined> };
3
3
  import {
4
4
  type FC,
5
5
  type PropsWithChildren,
6
+ type RefObject,
6
7
  useCallback,
7
8
  useEffect,
8
9
  useMemo,
9
10
  useRef,
11
+ useState,
10
12
  } from "react";
11
13
  import { AssistantCloud } from "assistant-cloud";
12
14
  import type { RemoteThreadListAdapter } from "../../../runtimes/remote-thread-list/types";
13
15
  import { InMemoryThreadListAdapter } from "../../../runtimes/remote-thread-list/adapter/in-memory";
14
16
  import { useAssistantCloudThreadHistoryAdapter } from "./AssistantCloudThreadHistoryAdapter";
15
- import { RuntimeAdapterProvider } from "../RuntimeAdapterProvider";
17
+ import {
18
+ RuntimeAdapterProvider,
19
+ type RuntimeAdapters,
20
+ } from "../RuntimeAdapterProvider";
16
21
  import { CloudFileAttachmentAdapter } from "./CloudFileAttachmentAdapter";
17
22
  import { isRecord } from "../../../utils/json/is-json";
18
23
 
@@ -39,6 +44,58 @@ const autoCloud = baseUrl
39
44
 
40
45
  const CLOUD_THREAD_PAGE_SIZE = 20;
41
46
 
47
+ type CloudListCursor = {
48
+ activeCursor: string | undefined;
49
+ archivedCursor: string | undefined;
50
+ activeExhausted: boolean;
51
+ archivedExhausted: boolean;
52
+ };
53
+
54
+ const parseListCursor = (after: string | undefined): CloudListCursor => {
55
+ const fallback: CloudListCursor = {
56
+ activeCursor: after,
57
+ archivedCursor: undefined,
58
+ activeExhausted: false,
59
+ archivedExhausted: false,
60
+ };
61
+ if (!after || !after.startsWith("{")) return fallback;
62
+ try {
63
+ const parsed = JSON.parse(after);
64
+ if (!isRecord(parsed)) return fallback;
65
+ return {
66
+ activeCursor: typeof parsed.a === "string" ? parsed.a : undefined,
67
+ archivedCursor: typeof parsed.r === "string" ? parsed.r : undefined,
68
+ activeExhausted: parsed.ae === true,
69
+ archivedExhausted: parsed.re === true,
70
+ };
71
+ } catch {
72
+ return fallback;
73
+ }
74
+ };
75
+
76
+ const useCloudThreadListAdapters = (
77
+ adapterRef: RefObject<CloudThreadListAdapterOptions>,
78
+ ): RuntimeAdapters => {
79
+ const history = useAssistantCloudThreadHistoryAdapter({
80
+ get current() {
81
+ return adapterRef.current.cloud ?? autoCloud!;
82
+ },
83
+ });
84
+ const [attachments] = useState(
85
+ () =>
86
+ new CloudFileAttachmentAdapter(
87
+ () => adapterRef.current.cloud ?? autoCloud!,
88
+ ),
89
+ );
90
+ return useMemo(
91
+ () => ({
92
+ history,
93
+ attachments,
94
+ }),
95
+ [history, attachments],
96
+ );
97
+ };
98
+
42
99
  export const useCloudThreadListAdapter = (
43
100
  adapter: CloudThreadListAdapterOptions,
44
101
  ): RemoteThreadListAdapter => {
@@ -47,27 +104,13 @@ export const useCloudThreadListAdapter = (
47
104
  adapterRef.current = adapter;
48
105
  }, [adapter]);
49
106
 
107
+ const unstable_useAdapters = useCallback(function useCloudAdapters() {
108
+ return useCloudThreadListAdapters(adapterRef);
109
+ }, []);
110
+
50
111
  const unstable_Provider = useCallback<FC<PropsWithChildren>>(
51
112
  function Provider({ children }) {
52
- const history = useAssistantCloudThreadHistoryAdapter({
53
- get current() {
54
- return adapterRef.current.cloud ?? autoCloud!;
55
- },
56
- });
57
- const cloudInstance = adapterRef.current.cloud ?? autoCloud!;
58
- const attachments = useMemo(
59
- () => new CloudFileAttachmentAdapter(cloudInstance),
60
- [cloudInstance],
61
- );
62
-
63
- const adapters = useMemo(
64
- () => ({
65
- history,
66
- attachments,
67
- }),
68
- [history, attachments],
69
- );
70
-
113
+ const adapters = useCloudThreadListAdapters(adapterRef);
71
114
  return (
72
115
  <RuntimeAdapterProvider adapters={adapters}>
73
116
  {children}
@@ -91,10 +134,38 @@ export const useCloudThreadListAdapter = (
91
134
 
92
135
  return {
93
136
  list: async ({ after } = {}) => {
94
- const { threads } = await cloud.threads.list({
95
- limit: CLOUD_THREAD_PAGE_SIZE,
96
- ...(after ? { after } : {}),
97
- });
137
+ const {
138
+ activeCursor,
139
+ archivedCursor,
140
+ activeExhausted,
141
+ archivedExhausted,
142
+ } = parseListCursor(after);
143
+ const [{ threads: activeThreads }, { threads: archivedThreads }] =
144
+ await Promise.all([
145
+ activeExhausted
146
+ ? Promise.resolve({ threads: [] })
147
+ : cloud.threads.list({
148
+ limit: CLOUD_THREAD_PAGE_SIZE,
149
+ ...(activeCursor ? { after: activeCursor } : {}),
150
+ }),
151
+ archivedExhausted
152
+ ? Promise.resolve({ threads: [] })
153
+ : cloud.threads.list({
154
+ is_archived: true,
155
+ limit: CLOUD_THREAD_PAGE_SIZE,
156
+ ...(archivedCursor ? { after: archivedCursor } : {}),
157
+ }),
158
+ ]);
159
+ const activeNext =
160
+ !activeExhausted && activeThreads.length === CLOUD_THREAD_PAGE_SIZE
161
+ ? activeThreads.at(-1)?.id
162
+ : undefined;
163
+ const archivedNext =
164
+ !archivedExhausted &&
165
+ archivedThreads.length === CLOUD_THREAD_PAGE_SIZE
166
+ ? archivedThreads.at(-1)?.id
167
+ : undefined;
168
+ const threads = [...activeThreads, ...archivedThreads];
98
169
  return {
99
170
  threads: threads.map((t) => ({
100
171
  status: t.is_archived ? "archived" : "regular",
@@ -107,8 +178,13 @@ export const useCloudThreadListAdapter = (
107
178
  custom: toCustom(t.metadata),
108
179
  })),
109
180
  nextCursor:
110
- threads.length === CLOUD_THREAD_PAGE_SIZE
111
- ? threads.at(-1)?.id
181
+ activeNext || archivedNext
182
+ ? JSON.stringify({
183
+ a: activeNext,
184
+ r: archivedNext,
185
+ ...(activeNext === undefined ? { ae: true } : {}),
186
+ ...(archivedNext === undefined ? { re: true } : {}),
187
+ })
112
188
  : undefined,
113
189
  };
114
190
  },
@@ -175,6 +251,7 @@ export const useCloudThreadListAdapter = (
175
251
  },
176
252
 
177
253
  unstable_Provider,
254
+ unstable_useAdapters,
178
255
  };
179
- }, [cloud, unstable_Provider]);
256
+ }, [cloud, unstable_Provider, unstable_useAdapters]);
180
257
  };
@@ -0,0 +1,56 @@
1
+ // @vitest-environment jsdom
2
+
3
+ import { renderHook } from "@testing-library/react";
4
+ import type { AssistantCloud } from "assistant-cloud";
5
+ import { describe, expect, it, vi } from "vitest";
6
+ import type { AssistantRuntime } from "../../../runtime/api/assistant-runtime";
7
+ import { useCloudThreadListRuntime } from "./useCloudThreadListRuntime";
8
+
9
+ const mocks = vi.hoisted(() => ({
10
+ useCloudThreadListAdapter: vi.fn(),
11
+ useRemoteThreadListRuntime: vi.fn(),
12
+ }));
13
+
14
+ vi.mock("./useCloudThreadListAdapter", async (importOriginal) => ({
15
+ ...(await importOriginal<typeof import("./useCloudThreadListAdapter")>()),
16
+ useCloudThreadListAdapter: mocks.useCloudThreadListAdapter,
17
+ }));
18
+
19
+ vi.mock("../useRemoteThreadListRuntime", async (importOriginal) => ({
20
+ ...(await importOriginal<typeof import("../useRemoteThreadListRuntime")>()),
21
+ useRemoteThreadListRuntime: mocks.useRemoteThreadListRuntime,
22
+ }));
23
+
24
+ describe("useCloudThreadListRuntime", () => {
25
+ it("forwards cloud options to the adapter and nests the runtime hook", () => {
26
+ const cloud = { threads: {} } as AssistantCloud;
27
+ const runtimeHook = () => ({}) as AssistantRuntime;
28
+ const create = vi.fn();
29
+ const del = vi.fn();
30
+ const adapter = { list: vi.fn() };
31
+ const runtime = { kind: "runtime" };
32
+ mocks.useCloudThreadListAdapter.mockReturnValue(adapter);
33
+ mocks.useRemoteThreadListRuntime.mockReturnValue(runtime);
34
+
35
+ const { result } = renderHook(() =>
36
+ useCloudThreadListRuntime({
37
+ cloud,
38
+ runtimeHook,
39
+ create,
40
+ delete: del,
41
+ }),
42
+ );
43
+
44
+ expect(mocks.useCloudThreadListAdapter).toHaveBeenCalledWith({
45
+ cloud,
46
+ create,
47
+ delete: del,
48
+ });
49
+ expect(mocks.useRemoteThreadListRuntime).toHaveBeenCalledWith({
50
+ runtimeHook,
51
+ adapter,
52
+ allowNesting: true,
53
+ });
54
+ expect(result.current).toBe(runtime);
55
+ });
56
+ });
@@ -0,0 +1,31 @@
1
+ "use client";
2
+
3
+ import type { AssistantCloud } from "assistant-cloud";
4
+ import type { AssistantRuntime } from "../../../runtime/api/assistant-runtime";
5
+ import { useRemoteThreadListRuntime } from "../useRemoteThreadListRuntime";
6
+ import { useCloudThreadListAdapter } from "./useCloudThreadListAdapter";
7
+
8
+ type ThreadData = {
9
+ externalId: string;
10
+ };
11
+
12
+ type CloudThreadListAdapter = {
13
+ cloud: AssistantCloud;
14
+
15
+ runtimeHook: () => AssistantRuntime;
16
+
17
+ create?(): Promise<ThreadData>;
18
+ delete?(threadId: string): Promise<void>;
19
+ };
20
+
21
+ export function useCloudThreadListRuntime({
22
+ runtimeHook,
23
+ ...adapterOptions
24
+ }: CloudThreadListAdapter) {
25
+ const adapter = useCloudThreadListAdapter(adapterOptions);
26
+ return useRemoteThreadListRuntime({
27
+ runtimeHook,
28
+ adapter,
29
+ allowNesting: true,
30
+ });
31
+ }