@assistant-ui/core 0.2.22 → 0.3.0

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 (349) hide show
  1. package/dist/adapters/thread-history.d.ts +8 -0
  2. package/dist/adapters/thread-history.d.ts.map +1 -1
  3. package/dist/internal.d.ts +3 -2
  4. package/dist/internal.js +3 -2
  5. package/dist/model-context/frame/host.d.ts.map +1 -1
  6. package/dist/model-context/frame/host.js +36 -21
  7. package/dist/model-context/frame/host.js.map +1 -1
  8. package/dist/model-context/types.d.ts.map +1 -1
  9. package/dist/model-context/types.js +13 -4
  10. package/dist/model-context/types.js.map +1 -1
  11. package/dist/react/adapters/LocalStorageThreadListAdapter.d.ts.map +1 -1
  12. package/dist/react/adapters/LocalStorageThreadListAdapter.js +3 -2
  13. package/dist/react/adapters/LocalStorageThreadListAdapter.js.map +1 -1
  14. package/dist/react/client/Tools.d.ts.map +1 -1
  15. package/dist/react/client/Tools.js +40 -55
  16. package/dist/react/client/Tools.js.map +1 -1
  17. package/dist/react/client/interactable-model-context.js +1 -0
  18. package/dist/react/client/interactable-model-context.js.map +1 -1
  19. package/dist/react/interactables-legacy/useAssistantInteractable.js +1 -1
  20. package/dist/react/interactables-legacy/useAssistantInteractable.js.map +1 -1
  21. package/dist/react/interactables-legacy/useInteractableState.js +4 -3
  22. package/dist/react/interactables-legacy/useInteractableState.js.map +1 -1
  23. package/dist/react/model-context/useAssistantContext.js +1 -1
  24. package/dist/react/model-context/useAssistantContext.js.map +1 -1
  25. package/dist/react/model-context/useAssistantDataUI.js +1 -1
  26. package/dist/react/model-context/useAssistantDataUI.js.map +1 -1
  27. package/dist/react/model-context/useAssistantInstructions.js +1 -1
  28. package/dist/react/model-context/useAssistantInstructions.js.map +1 -1
  29. package/dist/react/model-context/useAssistantTool.js +29 -25
  30. package/dist/react/model-context/useAssistantTool.js.map +1 -1
  31. package/dist/react/model-context/useAssistantToolUI.js +1 -1
  32. package/dist/react/model-context/useAssistantToolUI.js.map +1 -1
  33. package/dist/react/model-context/useAuiToolOverrides.js +1 -1
  34. package/dist/react/model-context/useAuiToolOverrides.js.map +1 -1
  35. package/dist/react/model-context/useInteractable.js +1 -1
  36. package/dist/react/model-context/useInteractable.js.map +1 -1
  37. package/dist/react/model-context/useInteractableState.js +3 -2
  38. package/dist/react/model-context/useInteractableState.js.map +1 -1
  39. package/dist/react/model-context/useInteractableVersions.js +1 -0
  40. package/dist/react/model-context/useInteractableVersions.js.map +1 -1
  41. package/dist/react/model-context/useToolArgsStatus.js +1 -0
  42. package/dist/react/model-context/useToolArgsStatus.js.map +1 -1
  43. package/dist/react/primitive-hooks/useActionBarCopy.js +4 -3
  44. package/dist/react/primitive-hooks/useActionBarCopy.js.map +1 -1
  45. package/dist/react/primitive-hooks/useActionBarEdit.js +2 -1
  46. package/dist/react/primitive-hooks/useActionBarEdit.js.map +1 -1
  47. package/dist/react/primitive-hooks/useActionBarFeedback.js +3 -2
  48. package/dist/react/primitive-hooks/useActionBarFeedback.js.map +1 -1
  49. package/dist/react/primitive-hooks/useActionBarReload.js +2 -1
  50. package/dist/react/primitive-hooks/useActionBarReload.js.map +1 -1
  51. package/dist/react/primitive-hooks/useActionBarSpeak.js +2 -1
  52. package/dist/react/primitive-hooks/useActionBarSpeak.js.map +1 -1
  53. package/dist/react/primitive-hooks/useActionBarStopSpeaking.js +2 -1
  54. package/dist/react/primitive-hooks/useActionBarStopSpeaking.js.map +1 -1
  55. package/dist/react/primitive-hooks/useBranchPickerNext.js +2 -1
  56. package/dist/react/primitive-hooks/useBranchPickerNext.js.map +1 -1
  57. package/dist/react/primitive-hooks/useBranchPickerPrevious.js +2 -1
  58. package/dist/react/primitive-hooks/useBranchPickerPrevious.js.map +1 -1
  59. package/dist/react/primitive-hooks/useComposerAddAttachment.js +2 -1
  60. package/dist/react/primitive-hooks/useComposerAddAttachment.js.map +1 -1
  61. package/dist/react/primitive-hooks/useComposerCancel.js +2 -1
  62. package/dist/react/primitive-hooks/useComposerCancel.js.map +1 -1
  63. package/dist/react/primitive-hooks/useComposerDictate.js +2 -1
  64. package/dist/react/primitive-hooks/useComposerDictate.js.map +1 -1
  65. package/dist/react/primitive-hooks/useComposerSend.js +2 -1
  66. package/dist/react/primitive-hooks/useComposerSend.js.map +1 -1
  67. package/dist/react/primitive-hooks/useEditComposerCancel.js +2 -1
  68. package/dist/react/primitive-hooks/useEditComposerCancel.js.map +1 -1
  69. package/dist/react/primitive-hooks/useEditComposerSend.js +2 -1
  70. package/dist/react/primitive-hooks/useEditComposerSend.js.map +1 -1
  71. package/dist/react/primitive-hooks/useMessageBranching.js +3 -2
  72. package/dist/react/primitive-hooks/useMessageBranching.js.map +1 -1
  73. package/dist/react/primitive-hooks/useMessageReload.js +2 -1
  74. package/dist/react/primitive-hooks/useMessageReload.js.map +1 -1
  75. package/dist/react/primitive-hooks/useSuggestionTrigger.js +8 -7
  76. package/dist/react/primitive-hooks/useSuggestionTrigger.js.map +1 -1
  77. package/dist/react/primitive-hooks/useThreadListItemArchive.js +2 -1
  78. package/dist/react/primitive-hooks/useThreadListItemArchive.js.map +1 -1
  79. package/dist/react/primitive-hooks/useThreadListItemDelete.js +2 -1
  80. package/dist/react/primitive-hooks/useThreadListItemDelete.js.map +1 -1
  81. package/dist/react/primitive-hooks/useThreadListItemTrigger.js +2 -1
  82. package/dist/react/primitive-hooks/useThreadListItemTrigger.js.map +1 -1
  83. package/dist/react/primitive-hooks/useThreadListItemUnarchive.js +2 -1
  84. package/dist/react/primitive-hooks/useThreadListItemUnarchive.js.map +1 -1
  85. package/dist/react/primitive-hooks/useThreadListLoadMore.js +2 -1
  86. package/dist/react/primitive-hooks/useThreadListLoadMore.js.map +1 -1
  87. package/dist/react/primitive-hooks/useThreadListNew.js +2 -1
  88. package/dist/react/primitive-hooks/useThreadListNew.js.map +1 -1
  89. package/dist/react/primitive-hooks/useVoice.js +5 -13
  90. package/dist/react/primitive-hooks/useVoice.js.map +1 -1
  91. package/dist/react/primitives/chainOfThought/ChainOfThoughtParts.js +1 -1
  92. package/dist/react/primitives/chainOfThought/ChainOfThoughtParts.js.map +1 -1
  93. package/dist/react/primitives/composer/ComposerAttachments.js +1 -1
  94. package/dist/react/primitives/composer/ComposerAttachments.js.map +1 -1
  95. package/dist/react/primitives/composer/ComposerQueue.d.ts.map +1 -1
  96. package/dist/react/primitives/composer/ComposerQueue.js +1 -1
  97. package/dist/react/primitives/composer/ComposerQueue.js.map +1 -1
  98. package/dist/react/primitives/message/MessageAttachments.d.ts.map +1 -1
  99. package/dist/react/primitives/message/MessageAttachments.js +1 -1
  100. package/dist/react/primitives/message/MessageAttachments.js.map +1 -1
  101. package/dist/react/primitives/message/MessageParts.js +84 -122
  102. package/dist/react/primitives/message/MessageParts.js.map +1 -1
  103. package/dist/react/primitives/thread/ThreadMessages.js +1 -1
  104. package/dist/react/primitives/thread/ThreadMessages.js.map +1 -1
  105. package/dist/react/primitives/thread/ThreadSuggestions.js +1 -1
  106. package/dist/react/primitives/thread/ThreadSuggestions.js.map +1 -1
  107. package/dist/react/primitives/threadList/ThreadListItems.js +1 -1
  108. package/dist/react/primitives/threadList/ThreadListItems.js.map +1 -1
  109. package/dist/react/providers/AttachmentByIndexProvider.js +2 -2
  110. package/dist/react/providers/AttachmentByIndexProvider.js.map +1 -1
  111. package/dist/react/providers/ChainOfThoughtByIndicesProvider.js +1 -1
  112. package/dist/react/providers/ChainOfThoughtByIndicesProvider.js.map +1 -1
  113. package/dist/react/providers/ChainOfThoughtPartByIndexProvider.d.ts.map +1 -1
  114. package/dist/react/providers/ChainOfThoughtPartByIndexProvider.js +30 -18
  115. package/dist/react/providers/ChainOfThoughtPartByIndexProvider.js.map +1 -1
  116. package/dist/react/providers/MessageByIdProvider.js +2 -2
  117. package/dist/react/providers/MessageByIdProvider.js.map +1 -1
  118. package/dist/react/providers/MessageByIndexProvider.js +2 -2
  119. package/dist/react/providers/MessageByIndexProvider.js.map +1 -1
  120. package/dist/react/providers/PartByIndexProvider.d.ts.map +1 -1
  121. package/dist/react/providers/PartByIndexProvider.js +30 -18
  122. package/dist/react/providers/PartByIndexProvider.js.map +1 -1
  123. package/dist/react/providers/QueueItemByIndexProvider.js +1 -1
  124. package/dist/react/providers/QueueItemByIndexProvider.js.map +1 -1
  125. package/dist/react/providers/ReadonlyThreadProvider.js +1 -1
  126. package/dist/react/providers/ReadonlyThreadProvider.js.map +1 -1
  127. package/dist/react/providers/SuggestionByIndexProvider.js +1 -1
  128. package/dist/react/providers/SuggestionByIndexProvider.js.map +1 -1
  129. package/dist/react/providers/TextMessagePartProvider.js +1 -0
  130. package/dist/react/providers/TextMessagePartProvider.js.map +1 -1
  131. package/dist/react/providers/ThreadListItemByIndexProvider.js +1 -1
  132. package/dist/react/providers/ThreadListItemByIndexProvider.js.map +1 -1
  133. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js +3 -3
  134. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js.map +1 -1
  135. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
  136. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js +6 -4
  137. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js.map +1 -1
  138. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts +31 -1
  139. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts.map +1 -1
  140. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js +42 -20
  141. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js.map +1 -1
  142. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.d.ts +1 -1
  143. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.d.ts.map +1 -1
  144. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.js +1 -1
  145. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.js.map +1 -1
  146. package/dist/react/runtimes/cloud/auiV0.d.ts +12 -1
  147. package/dist/react/runtimes/cloud/auiV0.d.ts.map +1 -1
  148. package/dist/react/runtimes/cloud/auiV0.js +2 -1
  149. package/dist/react/runtimes/cloud/auiV0.js.map +1 -1
  150. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js +75 -73
  151. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js.map +1 -1
  152. package/dist/react/runtimes/createRuntimeExtras.js +1 -1
  153. package/dist/react/runtimes/createRuntimeExtras.js.map +1 -1
  154. package/dist/react/runtimes/external-message-converter.js +1 -1
  155. package/dist/react/runtimes/external-message-converter.js.map +1 -1
  156. package/dist/react/runtimes/useExternalStoreSharedOptions.js +1 -0
  157. package/dist/react/runtimes/useExternalStoreSharedOptions.js.map +1 -1
  158. package/dist/react/runtimes/useLocalRuntime.d.ts +0 -1
  159. package/dist/react/runtimes/useLocalRuntime.d.ts.map +1 -1
  160. package/dist/react/types/scopes/tools.d.ts +0 -6
  161. package/dist/react/types/scopes/tools.d.ts.map +1 -1
  162. package/dist/react/utils/groupParts.d.ts +1 -3
  163. package/dist/react/utils/groupParts.d.ts.map +1 -1
  164. package/dist/react/utils/groupParts.js +1 -3
  165. package/dist/react/utils/groupParts.js.map +1 -1
  166. package/dist/runtime/api/assistant-runtime.d.ts +1 -1
  167. package/dist/runtime/api/assistant-runtime.d.ts.map +1 -1
  168. package/dist/runtime/api/assistant-runtime.js +1 -1
  169. package/dist/runtime/api/assistant-runtime.js.map +1 -1
  170. package/dist/runtime/api/attachment-runtime.d.ts +1 -1
  171. package/dist/runtime/api/attachment-runtime.d.ts.map +1 -1
  172. package/dist/runtime/api/attachment-runtime.js +1 -1
  173. package/dist/runtime/api/attachment-runtime.js.map +1 -1
  174. package/dist/runtime/api/composer-runtime.d.ts +2 -2
  175. package/dist/runtime/api/composer-runtime.d.ts.map +1 -1
  176. package/dist/runtime/api/composer-runtime.js +2 -2
  177. package/dist/runtime/api/composer-runtime.js.map +1 -1
  178. package/dist/runtime/api/message-part-runtime.d.ts +4 -4
  179. package/dist/runtime/api/message-part-runtime.d.ts.map +1 -1
  180. package/dist/runtime/api/message-part-runtime.js +3 -3
  181. package/dist/runtime/api/message-part-runtime.js.map +1 -1
  182. package/dist/runtime/api/message-runtime.d.ts +1 -1
  183. package/dist/runtime/api/message-runtime.d.ts.map +1 -1
  184. package/dist/runtime/api/message-runtime.js +2 -2
  185. package/dist/runtime/api/message-runtime.js.map +1 -1
  186. package/dist/runtime/api/thread-list-item-runtime.d.ts +1 -1
  187. package/dist/runtime/api/thread-list-item-runtime.d.ts.map +1 -1
  188. package/dist/runtime/api/thread-list-item-runtime.js +2 -2
  189. package/dist/runtime/api/thread-list-item-runtime.js.map +1 -1
  190. package/dist/runtime/api/thread-list-runtime.d.ts +1 -1
  191. package/dist/runtime/api/thread-list-runtime.d.ts.map +1 -1
  192. package/dist/runtime/api/thread-list-runtime.js +1 -1
  193. package/dist/runtime/api/thread-list-runtime.js.map +1 -1
  194. package/dist/runtime/base/base-thread-runtime-core.d.ts +1 -1
  195. package/dist/runtime/base/base-thread-runtime-core.d.ts.map +1 -1
  196. package/dist/runtime/base/base-thread-runtime-core.js +1 -1
  197. package/dist/runtime/base/base-thread-runtime-core.js.map +1 -1
  198. package/dist/runtime/base/default-edit-composer-runtime-core.d.ts +2 -2
  199. package/dist/runtime/base/default-edit-composer-runtime-core.d.ts.map +1 -1
  200. package/dist/runtime/base/default-edit-composer-runtime-core.js +2 -2
  201. package/dist/runtime/base/default-edit-composer-runtime-core.js.map +1 -1
  202. package/dist/runtime/base/default-thread-composer-runtime-core.d.ts +1 -1
  203. package/dist/runtime/base/default-thread-composer-runtime-core.d.ts.map +1 -1
  204. package/dist/runtime/base/default-thread-composer-runtime-core.js +1 -1
  205. package/dist/runtime/base/default-thread-composer-runtime-core.js.map +1 -1
  206. package/dist/runtime/utils/message-repository.d.ts.map +1 -1
  207. package/dist/runtime/utils/message-repository.js +4 -2
  208. package/dist/runtime/utils/message-repository.js.map +1 -1
  209. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.d.ts +1 -1
  210. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.d.ts.map +1 -1
  211. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js +1 -1
  212. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js.map +1 -1
  213. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts.map +1 -1
  214. package/dist/runtimes/external-store/external-store-thread-runtime-core.js +12 -0
  215. package/dist/runtimes/external-store/external-store-thread-runtime-core.js.map +1 -1
  216. package/dist/runtimes/internal.d.ts +2 -1
  217. package/dist/runtimes/internal.js +2 -1
  218. package/dist/runtimes/local/local-thread-runtime-core.d.ts +3 -0
  219. package/dist/runtimes/local/local-thread-runtime-core.d.ts.map +1 -1
  220. package/dist/runtimes/local/local-thread-runtime-core.js +44 -13
  221. package/dist/runtimes/local/local-thread-runtime-core.js.map +1 -1
  222. package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts +32 -27
  223. package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts.map +1 -1
  224. package/dist/runtimes/tool-invocations/ToolInvocationTracker.js +2 -0
  225. package/dist/runtimes/tool-invocations/ToolInvocationTracker.js.map +1 -1
  226. package/dist/store/clients/no-op-composer-client.js +1 -0
  227. package/dist/store/clients/no-op-composer-client.js.map +1 -1
  228. package/dist/store/clients/runtime-adapter.js +3 -3
  229. package/dist/store/clients/runtime-adapter.js.map +1 -1
  230. package/dist/store/runtime-clients/thread-list-runtime-client.js +1 -0
  231. package/dist/store/runtime-clients/thread-list-runtime-client.js.map +1 -1
  232. package/dist/store/runtime-clients/thread-runtime-client.d.ts.map +1 -1
  233. package/dist/store/runtime-clients/thread-runtime-client.js +17 -15
  234. package/dist/store/runtime-clients/thread-runtime-client.js.map +1 -1
  235. package/dist/store/scopes/thread.d.ts +1 -0
  236. package/dist/store/scopes/thread.d.ts.map +1 -1
  237. package/dist/subscribable/subscribable.d.ts +3 -3
  238. package/dist/subscribable/subscribable.d.ts.map +1 -1
  239. package/dist/subscribable/subscribable.js +3 -3
  240. package/dist/subscribable/subscribable.js.map +1 -1
  241. package/package.json +8 -8
  242. package/src/adapters/thread-history.ts +8 -0
  243. package/src/internal.ts +1 -1
  244. package/src/model-context/frame/host.test.ts +47 -0
  245. package/src/model-context/frame/host.ts +46 -19
  246. package/src/model-context/types.ts +16 -6
  247. package/src/react/adapters/LocalStorageThreadListAdapter.tsx +17 -7
  248. package/src/react/client/Tools.ts +0 -7
  249. package/src/react/interactables-legacy/useAssistantInteractable.ts +1 -1
  250. package/src/react/interactables-legacy/useInteractableState.ts +3 -3
  251. package/src/react/model-context/useAssistantContext.ts +1 -1
  252. package/src/react/model-context/useAssistantDataUI.ts +1 -1
  253. package/src/react/model-context/useAssistantInstructions.ts +1 -1
  254. package/src/react/model-context/useAssistantTool.ts +2 -2
  255. package/src/react/model-context/useAssistantToolUI.ts +1 -1
  256. package/src/react/model-context/useAuiToolOverrides.ts +1 -1
  257. package/src/react/model-context/useInteractable.ts +1 -1
  258. package/src/react/model-context/useInteractableState.ts +2 -2
  259. package/src/react/primitive-hooks/useActionBarCopy.test.ts +2 -2
  260. package/src/react/primitive-hooks/useActionBarCopy.ts +3 -3
  261. package/src/react/primitive-hooks/useActionBarEdit.ts +1 -1
  262. package/src/react/primitive-hooks/useActionBarFeedback.ts +2 -2
  263. package/src/react/primitive-hooks/useActionBarReload.ts +1 -1
  264. package/src/react/primitive-hooks/useActionBarSpeak.ts +1 -1
  265. package/src/react/primitive-hooks/useActionBarStopSpeaking.ts +1 -1
  266. package/src/react/primitive-hooks/useBranchPickerNext.ts +1 -1
  267. package/src/react/primitive-hooks/useBranchPickerPrevious.ts +1 -1
  268. package/src/react/primitive-hooks/useComposerAddAttachment.ts +1 -1
  269. package/src/react/primitive-hooks/useComposerCancel.ts +1 -1
  270. package/src/react/primitive-hooks/useComposerDictate.ts +1 -1
  271. package/src/react/primitive-hooks/useComposerSend.ts +1 -1
  272. package/src/react/primitive-hooks/useEditComposerCancel.ts +1 -1
  273. package/src/react/primitive-hooks/useEditComposerSend.ts +1 -1
  274. package/src/react/primitive-hooks/useMessageBranching.ts +2 -2
  275. package/src/react/primitive-hooks/useMessageReload.ts +1 -1
  276. package/src/react/primitive-hooks/useSuggestionTrigger.ts +9 -9
  277. package/src/react/primitive-hooks/useThreadListItemArchive.ts +1 -1
  278. package/src/react/primitive-hooks/useThreadListItemDelete.ts +1 -1
  279. package/src/react/primitive-hooks/useThreadListItemTrigger.ts +1 -1
  280. package/src/react/primitive-hooks/useThreadListItemUnarchive.ts +1 -1
  281. package/src/react/primitive-hooks/useThreadListLoadMore.ts +1 -1
  282. package/src/react/primitive-hooks/useThreadListNew.ts +1 -1
  283. package/src/react/primitive-hooks/useVoice.ts +5 -5
  284. package/src/react/primitives/chainOfThought/ChainOfThoughtParts.tsx +1 -1
  285. package/src/react/primitives/composer/ComposerAttachments.tsx +1 -1
  286. package/src/react/primitives/composer/ComposerQueue.tsx +1 -3
  287. package/src/react/primitives/message/MessageAttachments.tsx +1 -3
  288. package/src/react/primitives/message/MessageParts.tsx +9 -9
  289. package/src/react/primitives/thread/ThreadMessages.tsx +1 -1
  290. package/src/react/primitives/thread/ThreadSuggestions.tsx +1 -1
  291. package/src/react/primitives/threadList/ThreadListItems.tsx +1 -1
  292. package/src/react/providers/AttachmentByIndexProvider.tsx +2 -2
  293. package/src/react/providers/ChainOfThoughtByIndicesProvider.tsx +1 -1
  294. package/src/react/providers/ChainOfThoughtPartByIndexProvider.tsx +2 -19
  295. package/src/react/providers/MessageByIdProvider.tsx +2 -2
  296. package/src/react/providers/MessageByIndexProvider.tsx +2 -2
  297. package/src/react/providers/PartByIndexProvider.tsx +2 -16
  298. package/src/react/providers/QueueItemByIndexProvider.tsx +1 -1
  299. package/src/react/providers/ReadonlyThreadProvider.tsx +1 -1
  300. package/src/react/providers/SuggestionByIndexProvider.tsx +1 -1
  301. package/src/react/providers/ThreadListItemByIndexProvider.tsx +1 -1
  302. package/src/react/runtimes/RemoteThreadListHookInstanceManager.tsx +3 -3
  303. package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.tsx +20 -6
  304. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.test.ts +34 -0
  305. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.test.tsx +32 -7
  306. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.ts +47 -16
  307. package/src/react/runtimes/cloud/CloudFileAttachmentAdapter.ts +5 -1
  308. package/src/react/runtimes/cloud/auiV0.ts +14 -0
  309. package/src/react/runtimes/cloud/useCloudThreadListAdapter.tsx +90 -88
  310. package/src/react/runtimes/createRuntimeExtras.test.ts +1 -1
  311. package/src/react/runtimes/createRuntimeExtras.ts +1 -1
  312. package/src/react/runtimes/external-message-converter.test.ts +346 -0
  313. package/src/react/runtimes/external-message-converter.ts +1 -1
  314. package/src/react/runtimes/useLocalRuntime.test.tsx +43 -0
  315. package/src/react/types/scopes/tools.ts +0 -6
  316. package/src/react/utils/groupParts.ts +1 -7
  317. package/src/runtime/api/assistant-runtime.ts +4 -1
  318. package/src/runtime/api/attachment-runtime.ts +8 -2
  319. package/src/runtime/api/composer-runtime.ts +9 -5
  320. package/src/runtime/api/message-part-runtime.ts +10 -3
  321. package/src/runtime/api/message-runtime.ts +7 -2
  322. package/src/runtime/api/thread-list-item-runtime.ts +7 -2
  323. package/src/runtime/api/thread-list-runtime.ts +10 -2
  324. package/src/runtime/base/base-thread-runtime-core.ts +5 -1
  325. package/src/runtime/base/default-edit-composer-runtime-core.ts +14 -2
  326. package/src/runtime/base/default-thread-composer-runtime-core.ts +11 -1
  327. package/src/runtime/utils/message-repository.ts +19 -13
  328. package/src/runtimes/external-store/external-store-thread-list-runtime-core.ts +4 -1
  329. package/src/runtimes/external-store/external-store-thread-runtime-core.ts +15 -0
  330. package/src/runtimes/internal.ts +3 -0
  331. package/src/runtimes/local/local-thread-runtime-core.test.ts +596 -0
  332. package/src/runtimes/local/local-thread-runtime-core.ts +85 -21
  333. package/src/runtimes/local/should-continue.test.ts +122 -0
  334. package/src/runtimes/tool-invocations/ToolInvocationTracker.test.ts +9 -10
  335. package/src/runtimes/tool-invocations/ToolInvocationTracker.ts +38 -32
  336. package/src/store/clients/model-context-client.test.ts +21 -1
  337. package/src/store/clients/runtime-adapter.ts +3 -3
  338. package/src/store/runtime-clients/thread-runtime-client.ts +2 -1
  339. package/src/store/scopes/thread.ts +1 -0
  340. package/src/subscribable/subscribable.ts +16 -8
  341. package/src/tests/MessageRepository.test.ts +12 -0
  342. package/src/tests/RemoteThreadListThreadListRuntimeCore-switchToThread-position.test.ts +121 -0
  343. package/src/tests/auiV0Encode.test.ts +74 -0
  344. package/src/tests/base-composer-runtime-core.test.ts +422 -0
  345. package/src/tests/external-store-thread-list-runtime-core.test.ts +6 -6
  346. package/src/tests/external-store-thread-runtime-core-adapter.test.ts +575 -0
  347. package/src/tests/external-store-thread-runtime-core.test.ts +55 -1
  348. package/src/tests/groupParts.test.ts +3 -48
  349. package/src/tests/OptimisticState-delete-crash.test.ts +0 -208
@@ -13,7 +13,7 @@ export const useActionBarSpeak = () => {
13
13
  });
14
14
 
15
15
  const speak = useCallback(async () => {
16
- aui.message().speak();
16
+ aui.message.speak();
17
17
  }, [aui]);
18
18
 
19
19
  return { speak, disabled };
@@ -6,7 +6,7 @@ export const useActionBarStopSpeaking = () => {
6
6
  const disabled = useAuiState((s) => s.message.speech == null);
7
7
 
8
8
  const stopSpeaking = useCallback(() => {
9
- aui.message().stopSpeaking();
9
+ aui.message.stopSpeaking();
10
10
  }, [aui]);
11
11
 
12
12
  return { stopSpeaking, disabled };
@@ -12,7 +12,7 @@ export const useBranchPickerNext = () => {
12
12
  });
13
13
 
14
14
  const next = useCallback(() => {
15
- aui.message().switchToBranch({ position: "next" });
15
+ aui.message.switchToBranch({ position: "next" });
16
16
  }, [aui]);
17
17
 
18
18
  return { next, disabled };
@@ -12,7 +12,7 @@ export const useBranchPickerPrevious = () => {
12
12
  });
13
13
 
14
14
  const previous = useCallback(() => {
15
- aui.message().switchToBranch({ position: "previous" });
15
+ aui.message.switchToBranch({ position: "previous" });
16
16
  }, [aui]);
17
17
 
18
18
  return { previous, disabled };
@@ -8,7 +8,7 @@ export const useComposerAddAttachment = () => {
8
8
 
9
9
  const addAttachment = useCallback(
10
10
  (file: File | CreateAttachment) => {
11
- return aui.composer().addAttachment(file);
11
+ return aui.composer.addAttachment(file);
12
12
  },
13
13
  [aui],
14
14
  );
@@ -6,7 +6,7 @@ export const useComposerCancel = () => {
6
6
  const disabled = useAuiState((s) => !s.composer.canCancel);
7
7
 
8
8
  const cancel = useCallback(() => {
9
- aui.composer().cancel();
9
+ aui.composer.cancel();
10
10
  }, [aui]);
11
11
 
12
12
  return { cancel, disabled };
@@ -11,7 +11,7 @@ export const useComposerDictate = () => {
11
11
  );
12
12
 
13
13
  const startDictation = useCallback(() => {
14
- aui.composer().startDictation();
14
+ aui.composer.startDictation();
15
15
  }, [aui]);
16
16
 
17
17
  return { startDictation, disabled };
@@ -12,7 +12,7 @@ export const useComposerSend = () => {
12
12
 
13
13
  const send = useCallback(
14
14
  (opts?: ComposerSendOptions) => {
15
- aui.composer().send(opts);
15
+ aui.composer.send(opts);
16
16
  },
17
17
  [aui],
18
18
  );
@@ -5,7 +5,7 @@ export const useEditComposerCancel = () => {
5
5
  const aui = useAui();
6
6
 
7
7
  const cancel = useCallback(() => {
8
- aui.composer().cancel();
8
+ aui.composer.cancel();
9
9
  }, [aui]);
10
10
 
11
11
  return { cancel };
@@ -6,7 +6,7 @@ export const useEditComposerSend = () => {
6
6
  const disabled = useAuiState((s) => s.composer.isEmpty);
7
7
 
8
8
  const send = useCallback(() => {
9
- aui.composer().send();
9
+ aui.composer.send();
10
10
  }, [aui]);
11
11
 
12
12
  return { send, disabled };
@@ -7,11 +7,11 @@ export const useMessageBranching = () => {
7
7
  const branchCount = useAuiState((s) => s.message.branchCount);
8
8
 
9
9
  const goToPrev = useCallback(() => {
10
- aui.message().switchToBranch({ position: "previous" });
10
+ aui.message.switchToBranch({ position: "previous" });
11
11
  }, [aui]);
12
12
 
13
13
  const goToNext = useCallback(() => {
14
- aui.message().switchToBranch({ position: "next" });
14
+ aui.message.switchToBranch({ position: "next" });
15
15
  }, [aui]);
16
16
 
17
17
  return { branchNumber, branchCount, goToPrev, goToNext };
@@ -6,7 +6,7 @@ export const useMessageReload = () => {
6
6
  const canReload = useAuiState((s) => s.message.role === "assistant");
7
7
 
8
8
  const reload = useCallback(() => {
9
- aui.message().reload();
9
+ aui.message.reload();
10
10
  }, [aui]);
11
11
 
12
12
  return { reload, canReload };
@@ -17,24 +17,24 @@ export const useSuggestionTrigger = ({
17
17
  const resolvedSend = send ?? false;
18
18
 
19
19
  const trigger = useCallback(() => {
20
- const isRunning = aui.thread().getState().isRunning;
20
+ const isRunning = aui.thread.getState().isRunning;
21
21
 
22
22
  if (resolvedSend && !isRunning) {
23
- aui.thread().append({
23
+ aui.thread.append({
24
24
  content: [{ type: "text", text: prompt }],
25
- runConfig: aui.composer().getState().runConfig,
25
+ runConfig: aui.composer.getState().runConfig,
26
26
  });
27
27
  if (clearComposer) {
28
- aui.composer().setText("");
28
+ aui.composer.setText("");
29
29
  }
30
30
  } else {
31
31
  if (clearComposer) {
32
- aui.composer().setText(prompt);
32
+ aui.composer.setText(prompt);
33
33
  } else {
34
- const currentText = aui.composer().getState().text;
35
- aui
36
- .composer()
37
- .setText(currentText.trim() ? `${currentText} ${prompt}` : prompt);
34
+ const currentText = aui.composer.getState().text;
35
+ aui.composer.setText(
36
+ currentText.trim() ? `${currentText} ${prompt}` : prompt,
37
+ );
38
38
  }
39
39
  }
40
40
  }, [aui, resolvedSend, clearComposer, prompt]);
@@ -5,7 +5,7 @@ export const useThreadListItemArchive = () => {
5
5
  const aui = useAui();
6
6
 
7
7
  const archive = useCallback(() => {
8
- aui.threadListItem().archive();
8
+ aui.threadListItem.archive();
9
9
  }, [aui]);
10
10
 
11
11
  return { archive };
@@ -5,7 +5,7 @@ export const useThreadListItemDelete = () => {
5
5
  const aui = useAui();
6
6
 
7
7
  const deleteThread = useCallback(() => {
8
- aui.threadListItem().delete();
8
+ aui.threadListItem.delete();
9
9
  }, [aui]);
10
10
 
11
11
  return { delete: deleteThread };
@@ -5,7 +5,7 @@ export const useThreadListItemTrigger = () => {
5
5
  const aui = useAui();
6
6
 
7
7
  const switchTo = useCallback(() => {
8
- aui.threadListItem().switchTo();
8
+ aui.threadListItem.switchTo();
9
9
  }, [aui]);
10
10
 
11
11
  return { switchTo };
@@ -5,7 +5,7 @@ export const useThreadListItemUnarchive = () => {
5
5
  const aui = useAui();
6
6
 
7
7
  const unarchive = useCallback(() => {
8
- aui.threadListItem().unarchive();
8
+ aui.threadListItem.unarchive();
9
9
  }, [aui]);
10
10
 
11
11
  return { unarchive };
@@ -8,7 +8,7 @@ export const useThreadListLoadMore = () => {
8
8
  );
9
9
 
10
10
  const loadMore = useCallback(() => {
11
- aui.threads().loadMore();
11
+ aui.threads.loadMore();
12
12
  }, [aui]);
13
13
 
14
14
  return { loadMore, disabled };
@@ -5,7 +5,7 @@ export const useThreadListNew = () => {
5
5
  const aui = useAui();
6
6
 
7
7
  const switchToNewThread = useCallback(() => {
8
- aui.threads().switchToNewThread();
8
+ aui.threads.switchToNewThread();
9
9
  }, [aui]);
10
10
 
11
11
  return { switchToNewThread };
@@ -10,7 +10,7 @@ const getServerVolume = () => 0;
10
10
 
11
11
  export const useVoiceVolume = (): number => {
12
12
  const aui = useAui();
13
- const thread = aui.thread();
13
+ const thread = aui.thread;
14
14
  return useSyncExternalStore(
15
15
  thread.subscribeVoiceVolume,
16
16
  thread.getVoiceVolume,
@@ -22,19 +22,19 @@ export const useVoiceControls = () => {
22
22
  const aui = useAui();
23
23
 
24
24
  const connect = useCallback(() => {
25
- aui.thread().connectVoice();
25
+ aui.thread.connectVoice();
26
26
  }, [aui]);
27
27
 
28
28
  const disconnect = useCallback(() => {
29
- aui.thread().disconnectVoice();
29
+ aui.thread.disconnectVoice();
30
30
  }, [aui]);
31
31
 
32
32
  const mute = useCallback(() => {
33
- aui.thread().muteVoice();
33
+ aui.thread.muteVoice();
34
34
  }, [aui]);
35
35
 
36
36
  const unmute = useCallback(() => {
37
- aui.thread().unmuteVoice();
37
+ aui.thread.unmuteVoice();
38
38
  }, [aui]);
39
39
 
40
40
  return { connect, disconnect, mute, unmute };
@@ -51,7 +51,7 @@ const ChainOfThoughtPrimitivePartsInner: FC<{
51
51
  Array.from({ length: partsLength }, (_, index) => (
52
52
  <ChainOfThoughtPartByIndexProvider key={index} index={index}>
53
53
  <RenderChildrenWithAccessor
54
- getItemState={(aui) => aui.part().getState()}
54
+ getItemState={(aui) => aui.part.getState()}
55
55
  >
56
56
  {(getItem) =>
57
57
  children({
@@ -99,7 +99,7 @@ const ComposerPrimitiveAttachmentsInner: FC<{
99
99
  <ComposerAttachmentByIndexProvider key={index} index={index}>
100
100
  <RenderChildrenWithAccessor
101
101
  getItemState={(aui) =>
102
- aui.composer().attachment({ index }).getState()
102
+ aui.composer.attachment({ index }).getState()
103
103
  }
104
104
  >
105
105
  {(getItem) =>
@@ -20,9 +20,7 @@ const ComposerPrimitiveQueueInner: FC<{
20
20
  Array.from({ length: queue }, (_, index) => (
21
21
  <QueueItemByIndexProvider key={index} index={index}>
22
22
  <RenderChildrenWithAccessor
23
- getItemState={(aui) =>
24
- aui.composer().queueItem({ index }).getState()
25
- }
23
+ getItemState={(aui) => aui.composer.queueItem({ index }).getState()}
26
24
  >
27
25
  {(getItem) =>
28
26
  children({
@@ -101,9 +101,7 @@ const MessagePrimitiveAttachmentsInner: FC<{
101
101
  Array.from({ length: attachmentsCount }, (_, index) => (
102
102
  <MessageAttachmentByIndexProvider key={index} index={index}>
103
103
  <RenderChildrenWithAccessor
104
- getItemState={(aui) =>
105
- aui.message().attachment({ index }).getState()
106
- }
104
+ getItemState={(aui) => aui.message.attachment({ index }).getState()}
107
105
  >
108
106
  {(getItem) =>
109
107
  children({
@@ -415,9 +415,9 @@ export const MessagePartComponent: FC<MessagePartComponentProps> = ({
415
415
 
416
416
  const type = part.type;
417
417
  if (type === "tool-call") {
418
- const addResult = aui.part().addToolResult;
419
- const resume = aui.part().resumeToolCall;
420
- const respondToApproval = aui.part().respondToToolApproval;
418
+ const addResult = aui.part.addToolResult;
419
+ const resume = aui.part.resumeToolCall;
420
+ const respondToApproval = aui.part.respondToToolApproval;
421
421
  if ("Override" in tools)
422
422
  return (
423
423
  <tools.Override
@@ -636,9 +636,9 @@ const RegisteredToolUI: FC = () => {
636
636
  return (
637
637
  <Render
638
638
  {...part}
639
- addResult={aui.part().addToolResult}
640
- resume={aui.part().resumeToolCall}
641
- respondToApproval={aui.part().respondToToolApproval}
639
+ addResult={aui.part.addToolResult}
640
+ resume={aui.part.resumeToolCall}
641
+ respondToApproval={aui.part.respondToToolApproval}
642
642
  />
643
643
  );
644
644
  };
@@ -743,16 +743,16 @@ const MessagePartChildrenInner: FC<
743
743
 
744
744
  return (
745
745
  <RenderChildrenWithAccessor
746
- getItemState={(client) => client.part().getState()}
746
+ getItemState={(client) => client.part.getState()}
747
747
  >
748
748
  {(getItem) =>
749
749
  children({
750
750
  get part() {
751
751
  const state = getItem();
752
752
  if (state.type === "tool-call") {
753
- const toolsState = aui.tools().getState();
753
+ const toolsState = aui.tools.getState();
754
754
  const hasUI = resolveToolRender(toolsState, state) !== null;
755
- const partMethods = aui.part();
755
+ const partMethods = aui.part;
756
756
  return {
757
757
  ...state,
758
758
  toolUI: hasUI ? <RegisteredToolUI /> : null,
@@ -247,7 +247,7 @@ const ThreadPrimitiveMessagesInner: FC<{
247
247
  return Array.from({ length: messagesLength }, (_, index) => (
248
248
  <MessageByIndexProvider key={index} index={index}>
249
249
  <RenderChildrenWithAccessor
250
- getItemState={(aui) => aui.thread().message({ index }).getState()}
250
+ getItemState={(aui) => aui.thread.message({ index }).getState()}
251
251
  >
252
252
  {(getItem) =>
253
253
  children({
@@ -77,7 +77,7 @@ const ThreadPrimitiveSuggestionsInner: FC<{
77
77
  <SuggestionByIndexProvider key={index} index={index}>
78
78
  <RenderChildrenWithAccessor
79
79
  getItemState={(aui) =>
80
- aui.suggestions().suggestion({ index }).getState()
80
+ aui.suggestions.suggestion({ index }).getState()
81
81
  }
82
82
  >
83
83
  {(getItem) =>
@@ -78,7 +78,7 @@ const ThreadListPrimitiveItemsInner: FC<{
78
78
  >
79
79
  <RenderChildrenWithAccessor
80
80
  getItemState={(aui) =>
81
- aui.threads().item({ index, archived }).getState()
81
+ aui.threads.item({ index, archived }).getState()
82
82
  }
83
83
  >
84
84
  {(getItem) =>
@@ -10,7 +10,7 @@ export const MessageAttachmentByIndexProvider: FC<
10
10
  attachment: Derived({
11
11
  source: "message",
12
12
  query: { type: "index", index },
13
- get: (aui) => aui.message().attachment({ index }),
13
+ get: (aui) => aui.message.attachment({ index }),
14
14
  }),
15
15
  });
16
16
 
@@ -26,7 +26,7 @@ export const ComposerAttachmentByIndexProvider: FC<
26
26
  attachment: Derived({
27
27
  source: "composer",
28
28
  query: { type: "index", index },
29
- get: (aui) => aui.composer().attachment({ index }),
29
+ get: (aui) => aui.composer.attachment({ index }),
30
30
  }),
31
31
  });
32
32
 
@@ -25,7 +25,7 @@ export const ChainOfThoughtByIndicesProvider: FC<
25
25
  `ChainOfThought part index ${index} is out of bounds (0..${parts.length - 1})`,
26
26
  );
27
27
  }
28
- return parentAui.message().part({ index: startIndex + index });
28
+ return parentAui.message.part({ index: startIndex + index });
29
29
  },
30
30
  }),
31
31
  });
@@ -1,33 +1,16 @@
1
- import { useMemo, type FC, type PropsWithChildren } from "react";
1
+ import type { FC, PropsWithChildren } from "react";
2
2
  import { useAui, AuiProvider, Derived } from "@assistant-ui/store";
3
- import type { PartMethods } from "../../store/scopes/part";
4
3
 
5
4
  export const ChainOfThoughtPartByIndexProvider: FC<
6
5
  PropsWithChildren<{
7
6
  index: number;
8
7
  }>
9
8
  > = ({ index, children }) => {
10
- const lastPartRef = useMemo(
11
- () => ({ index, current: null as PartMethods | null }),
12
- [index],
13
- );
14
9
  const aui = useAui({
15
10
  part: Derived({
16
11
  source: "chainOfThought",
17
12
  query: { type: "index", index },
18
- get: (aui) => {
19
- const chainOfThought = aui.chainOfThought();
20
- if (
21
- index >= chainOfThought.getState().parts.length &&
22
- lastPartRef.current
23
- ) {
24
- return lastPartRef.current;
25
- }
26
-
27
- const part = chainOfThought.part({ index });
28
- lastPartRef.current = part;
29
- return part;
30
- },
13
+ get: (aui) => aui.chainOfThought.part({ index }),
31
14
  }),
32
15
  });
33
16
 
@@ -10,12 +10,12 @@ export const MessageByIdProvider: FC<
10
10
  message: Derived({
11
11
  source: "thread",
12
12
  query: { type: "id", id },
13
- get: (aui) => aui.thread().message({ id }),
13
+ get: (aui) => aui.thread.message({ id }),
14
14
  }),
15
15
  composer: Derived({
16
16
  source: "message",
17
17
  query: {},
18
- get: (aui) => aui.thread().message({ id }).composer(),
18
+ get: (aui) => aui.thread.message({ id }).composer(),
19
19
  }),
20
20
  });
21
21
 
@@ -10,12 +10,12 @@ export const MessageByIndexProvider: FC<
10
10
  message: Derived({
11
11
  source: "thread",
12
12
  query: { type: "index", index },
13
- get: (aui) => aui.thread().message({ index }),
13
+ get: (aui) => aui.thread.message({ index }),
14
14
  }),
15
15
  composer: Derived({
16
16
  source: "message",
17
17
  query: {},
18
- get: (aui) => aui.thread().message({ index }).composer(),
18
+ get: (aui) => aui.thread.message({ index }).composer(),
19
19
  }),
20
20
  });
21
21
 
@@ -1,30 +1,16 @@
1
- import { useMemo, type FC, type PropsWithChildren } from "react";
1
+ import type { FC, PropsWithChildren } from "react";
2
2
  import { useAui, AuiProvider, Derived } from "@assistant-ui/store";
3
- import type { PartMethods } from "../../store/scopes/part";
4
3
 
5
4
  export const PartByIndexProvider: FC<
6
5
  PropsWithChildren<{
7
6
  index: number;
8
7
  }>
9
8
  > = ({ index, children }) => {
10
- const lastPartRef = useMemo(
11
- () => ({ index, current: null as PartMethods | null }),
12
- [index],
13
- );
14
9
  const aui = useAui({
15
10
  part: Derived({
16
11
  source: "message",
17
12
  query: { type: "index", index },
18
- get: (aui) => {
19
- const message = aui.message();
20
- if (index >= message.getState().parts.length && lastPartRef.current) {
21
- return lastPartRef.current;
22
- }
23
-
24
- const part = message.part({ index });
25
- lastPartRef.current = part;
26
- return part;
27
- },
13
+ get: (aui) => aui.message.part({ index }),
28
14
  }),
29
15
  });
30
16
 
@@ -13,7 +13,7 @@ export const QueueItemByIndexProvider: FC<QueueItemByIndexProviderProps> = ({
13
13
  queueItem: Derived({
14
14
  source: "composer",
15
15
  query: { index },
16
- get: (aui) => aui.composer().queueItem({ index }),
16
+ get: (aui) => aui.composer.queueItem({ index }),
17
17
  }),
18
18
  });
19
19
 
@@ -76,7 +76,7 @@ export const ReadonlyThreadProvider: FC<ReadonlyThreadProvider.Props> = ({
76
76
  composer: Derived({
77
77
  source: "thread",
78
78
  query: {},
79
- get: (aui) => aui.thread().composer(),
79
+ get: (aui) => aui.thread.composer(),
80
80
  }),
81
81
  });
82
82
 
@@ -13,7 +13,7 @@ export const SuggestionByIndexProvider: FC<SuggestionByIndexProviderProps> = ({
13
13
  suggestion: Derived({
14
14
  source: "suggestions",
15
15
  query: { index },
16
- get: (aui) => aui.suggestions().suggestion({ index }),
16
+ get: (aui) => aui.suggestions.suggestion({ index }),
17
17
  }),
18
18
  });
19
19
 
@@ -11,7 +11,7 @@ export const ThreadListItemByIndexProvider: FC<
11
11
  threadListItem: Derived({
12
12
  source: "threads",
13
13
  query: { type: "index", index, archived },
14
- get: (aui) => aui.threads().item({ index, archived }),
14
+ get: (aui) => aui.threads.item({ index, archived }),
15
15
  }),
16
16
  });
17
17
 
@@ -147,15 +147,15 @@ export class RemoteThreadListHookInstanceManager extends BaseSubscribable {
147
147
  return runtime.threads.main.unstable_on("initialize", () => {
148
148
  if (hasInitializedRef.current) return;
149
149
 
150
- const state = aui.threadListItem().getState();
150
+ const state = aui.threadListItem.getState();
151
151
  if (state.status !== "new") return;
152
152
  hasInitializedRef.current = true;
153
153
 
154
- initPromiseRef.current = aui.threadListItem().initialize();
154
+ initPromiseRef.current = aui.threadListItem.initialize();
155
155
 
156
156
  const dispose = runtime.thread.unstable_on("runEnd", () => {
157
157
  dispose();
158
- aui.threadListItem().generateTitle();
158
+ aui.threadListItem.generateTitle();
159
159
  });
160
160
  });
161
161
  }, [runtime, aui]);
@@ -356,22 +356,36 @@ export class RemoteThreadListThreadListRuntimeCore
356
356
  [remoteMetadata.remoteId]: mappingId,
357
357
  };
358
358
 
359
- // Filter both arrays first so a concurrent `list()` can't leave the id
360
- // duplicated or under the wrong status.
359
+ // A concurrent `list()` may already have placed this thread; keep that
360
+ // position and only merge metadata. A genuinely absent thread stays
361
+ // appended: it may live on an unloaded page, and a prepend would pin it
362
+ // above newer threads permanently since `classifyThreads` skips ids it
363
+ // has already seen. Filtering both arrays first still prevents
364
+ // duplication or a wrong-status entry from `list()`.
365
+ const remoteId = remoteMetadata.remoteId;
366
+ const wasInTarget =
367
+ remoteMetadata.status === "regular"
368
+ ? state.threadIds.includes(remoteId)
369
+ : state.archivedThreadIds.includes(remoteId);
370
+
361
371
  const threadIdsWithoutRemote = state.threadIds.filter(
362
- (id) => id !== remoteMetadata.remoteId,
372
+ (id) => id !== remoteId,
363
373
  );
364
374
  const archivedThreadIdsWithoutRemote = state.archivedThreadIds.filter(
365
- (id) => id !== remoteMetadata.remoteId,
375
+ (id) => id !== remoteId,
366
376
  );
367
377
 
368
378
  const newThreadIds =
369
379
  remoteMetadata.status === "regular"
370
- ? [...threadIdsWithoutRemote, remoteMetadata.remoteId]
380
+ ? wasInTarget
381
+ ? state.threadIds
382
+ : [...threadIdsWithoutRemote, remoteId]
371
383
  : threadIdsWithoutRemote;
372
384
  const newArchivedThreadIds =
373
385
  remoteMetadata.status === "archived"
374
- ? [...archivedThreadIdsWithoutRemote, remoteMetadata.remoteId]
386
+ ? wasInTarget
387
+ ? state.archivedThreadIds
388
+ : [...archivedThreadIdsWithoutRemote, remoteId]
375
389
  : archivedThreadIdsWithoutRemote;
376
390
 
377
391
  this._state.update({
@@ -0,0 +1,34 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { extractAuiV0 } from "./AssistantCloudThreadHistoryAdapter";
3
+
4
+ const auiV0Message = (status: { type: string; reason?: string }) => ({
5
+ role: "assistant",
6
+ status,
7
+ content: [
8
+ {
9
+ type: "tool-call",
10
+ toolCallId: "call-1",
11
+ toolName: "send_email",
12
+ args: {},
13
+ argsText: "{}",
14
+ },
15
+ ],
16
+ metadata: { steps: [{ usage: { inputTokens: 1, outputTokens: 2 } }] },
17
+ });
18
+
19
+ describe("extractAuiV0", () => {
20
+ it("returns null for a requires-action message so paused writes never report", () => {
21
+ expect(
22
+ extractAuiV0(
23
+ auiV0Message({ type: "requires-action", reason: "tool-calls" }),
24
+ ),
25
+ ).toBeNull();
26
+ });
27
+
28
+ it("reports a terminal message once with its usage", () => {
29
+ const result = extractAuiV0(auiV0Message({ type: "complete" }));
30
+ expect(result?.status).toBe("completed");
31
+ expect(result?.inputTokens).toBe(1);
32
+ expect(result?.outputTokens).toBe(2);
33
+ });
34
+ });