@assistant-ui/core 0.3.16 → 0.3.18

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 (474) hide show
  1. package/dist/adapters/attachment.d.ts.map +1 -1
  2. package/dist/adapters/attachment.js +5 -4
  3. package/dist/adapters/attachment.js.map +1 -1
  4. package/dist/index.d.ts +3 -3
  5. package/dist/index.js +2 -2
  6. package/dist/index.js.map +1 -1
  7. package/dist/internal.d.ts +4 -2
  8. package/dist/internal.js +4 -2
  9. package/dist/model-context/frame/host.d.ts.map +1 -1
  10. package/dist/model-context/frame/host.js +10 -4
  11. package/dist/model-context/frame/host.js.map +1 -1
  12. package/dist/model-context/frame/provider.d.ts +5 -0
  13. package/dist/model-context/frame/provider.d.ts.map +1 -1
  14. package/dist/model-context/frame/provider.js +101 -28
  15. package/dist/model-context/frame/provider.js.map +1 -1
  16. package/dist/model-context/interactable-composer-metadata.d.ts.map +1 -1
  17. package/dist/model-context/interactable-composer-metadata.js +16 -9
  18. package/dist/model-context/interactable-composer-metadata.js.map +1 -1
  19. package/dist/model-context/registry.d.ts.map +1 -1
  20. package/dist/model-context/registry.js +3 -5
  21. package/dist/model-context/registry.js.map +1 -1
  22. package/dist/model-context/tool-call-text.d.ts +26 -0
  23. package/dist/model-context/tool-call-text.d.ts.map +1 -0
  24. package/dist/model-context/tool-call-text.js +18 -0
  25. package/dist/model-context/tool-call-text.js.map +1 -0
  26. package/dist/model-context/types.d.ts.map +1 -1
  27. package/dist/model-context/types.js +5 -4
  28. package/dist/model-context/types.js.map +1 -1
  29. package/dist/react/RuntimeAdapter.js +1 -1
  30. package/dist/react/adapters/LocalStorageThreadListAdapter.d.ts.map +1 -1
  31. package/dist/react/adapters/LocalStorageThreadListAdapter.js +1 -1
  32. package/dist/react/adapters/LocalStorageThreadListAdapter.js.map +1 -1
  33. package/dist/react/client/AdaptedRemoteThread.js +1 -1
  34. package/dist/react/client/InMemoryThreadList.d.ts.map +1 -1
  35. package/dist/react/client/InMemoryThreadList.js +63 -57
  36. package/dist/react/client/InMemoryThreadList.js.map +1 -1
  37. package/dist/react/client/Interactables.d.ts.map +1 -1
  38. package/dist/react/client/Interactables.js +25 -28
  39. package/dist/react/client/Interactables.js.map +1 -1
  40. package/dist/react/client/RemoteThreadList.d.ts +16 -0
  41. package/dist/react/client/RemoteThreadList.d.ts.map +1 -1
  42. package/dist/react/client/RemoteThreadList.js +354 -242
  43. package/dist/react/client/RemoteThreadList.js.map +1 -1
  44. package/dist/react/client/Tools.d.ts.map +1 -1
  45. package/dist/react/client/Tools.js +24 -18
  46. package/dist/react/client/Tools.js.map +1 -1
  47. package/dist/react/index.d.ts +2 -1
  48. package/dist/react/index.js +2 -1
  49. package/dist/react/interactables-legacy/Interactables.js +246 -125
  50. package/dist/react/interactables-legacy/Interactables.js.map +1 -1
  51. package/dist/react/interactables-shared/useInteractablePersistenceQueue.d.ts.map +1 -1
  52. package/dist/react/interactables-shared/useInteractablePersistenceQueue.js +11 -9
  53. package/dist/react/interactables-shared/useInteractablePersistenceQueue.js.map +1 -1
  54. package/dist/react/model-context/makeAssistantTool.d.ts +2 -2
  55. package/dist/react/model-context/makeAssistantTool.js +1 -1
  56. package/dist/react/model-context/makeAssistantTool.js.map +1 -1
  57. package/dist/react/model-context/toolbox.d.ts +2 -14
  58. package/dist/react/model-context/toolbox.d.ts.map +1 -1
  59. package/dist/react/model-context/toolbox.js +1 -13
  60. package/dist/react/model-context/toolbox.js.map +1 -1
  61. package/dist/react/model-context/useAssistantContext.js +37 -7
  62. package/dist/react/model-context/useAssistantContext.js.map +1 -1
  63. package/dist/react/model-context/useAssistantTool.d.ts +2 -2
  64. package/dist/react/model-context/useAssistantTool.js +1 -1
  65. package/dist/react/model-context/useAssistantTool.js.map +1 -1
  66. package/dist/react/model-context/useAuiToolOverrides.js +31 -5
  67. package/dist/react/model-context/useAuiToolOverrides.js.map +1 -1
  68. package/dist/react/model-context/useInlineRender.d.ts.map +1 -1
  69. package/dist/react/model-context/useInlineRender.js +10 -36
  70. package/dist/react/model-context/useInlineRender.js.map +1 -1
  71. package/dist/react/model-context/useToolArgsStatus.d.ts.map +1 -1
  72. package/dist/react/model-context/useToolArgsStatus.js +2 -1
  73. package/dist/react/model-context/useToolArgsStatus.js.map +1 -1
  74. package/dist/react/primitive-hooks/useMessageError.d.ts.map +1 -1
  75. package/dist/react/primitive-hooks/useMessageError.js +2 -8
  76. package/dist/react/primitive-hooks/useMessageError.js.map +1 -1
  77. package/dist/react/primitive-hooks/useThreadListLoadMore.d.ts.map +1 -1
  78. package/dist/react/primitive-hooks/useThreadListLoadMore.js +2 -4
  79. package/dist/react/primitive-hooks/useThreadListLoadMore.js.map +1 -1
  80. package/dist/react/primitives/composer/ComposerAttachments.d.ts.map +1 -1
  81. package/dist/react/primitives/composer/ComposerAttachments.js +4 -3
  82. package/dist/react/primitives/composer/ComposerAttachments.js.map +1 -1
  83. package/dist/react/primitives/composer/ComposerQueue.d.ts.map +1 -1
  84. package/dist/react/primitives/composer/ComposerQueue.js +4 -3
  85. package/dist/react/primitives/composer/ComposerQueue.js.map +1 -1
  86. package/dist/react/primitives/message/MessageAttachments.d.ts.map +1 -1
  87. package/dist/react/primitives/message/MessageAttachments.js +7 -6
  88. package/dist/react/primitives/message/MessageAttachments.js.map +1 -1
  89. package/dist/react/primitives/message/MessageGroupedParts.js +2 -2
  90. package/dist/react/primitives/message/MessageGroupedParts.js.map +1 -1
  91. package/dist/react/primitives/message/MessageParts.js +3 -3
  92. package/dist/react/primitives/message/MessageParts.js.map +1 -1
  93. package/dist/react/primitives/threadList/ThreadListItems.d.ts.map +1 -1
  94. package/dist/react/primitives/threadList/ThreadListItems.js +5 -4
  95. package/dist/react/primitives/threadList/ThreadListItems.js.map +1 -1
  96. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts +6 -4
  97. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts.map +1 -1
  98. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js +59 -29
  99. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js.map +1 -1
  100. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts +11 -6
  101. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
  102. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js +160 -143
  103. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js.map +1 -1
  104. package/dist/react/runtimes/RemoteThreadResource.d.ts +2 -6
  105. package/dist/react/runtimes/RemoteThreadResource.d.ts.map +1 -1
  106. package/dist/react/runtimes/RemoteThreadResource.js +15 -13
  107. package/dist/react/runtimes/RemoteThreadResource.js.map +1 -1
  108. package/dist/react/runtimes/assistant-transport/useLatestRef.js +2 -2
  109. package/dist/react/runtimes/assistant-transport/useLatestRef.js.map +1 -1
  110. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts +4 -1
  111. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts.map +1 -1
  112. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js +424 -52
  113. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js.map +1 -1
  114. package/dist/react/runtimes/cloud/auiV0.d.ts +5 -1
  115. package/dist/react/runtimes/cloud/auiV0.d.ts.map +1 -1
  116. package/dist/react/runtimes/cloud/auiV0.js.map +1 -1
  117. package/dist/react/runtimes/cloud/createCloudThreadListAdapter.d.ts +29 -0
  118. package/dist/react/runtimes/cloud/createCloudThreadListAdapter.d.ts.map +1 -0
  119. package/dist/react/runtimes/cloud/createCloudThreadListAdapter.js +160 -0
  120. package/dist/react/runtimes/cloud/createCloudThreadListAdapter.js.map +1 -0
  121. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.d.ts +1 -9
  122. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.d.ts.map +1 -1
  123. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js +16 -153
  124. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js.map +1 -1
  125. package/dist/react/runtimes/external-message-converter.js +1 -1
  126. package/dist/react/runtimes/external-message-converter.js.map +1 -1
  127. package/dist/react/runtimes/useExternalStoreRuntime.js +75 -46
  128. package/dist/react/runtimes/useExternalStoreRuntime.js.map +1 -1
  129. package/dist/react/runtimes/useRemoteThreadListRuntime.d.ts.map +1 -1
  130. package/dist/react/runtimes/useRemoteThreadListRuntime.js +77 -29
  131. package/dist/react/runtimes/useRemoteThreadListRuntime.js.map +1 -1
  132. package/dist/react/types/MessagePartComponentTypes.d.ts +7 -3
  133. package/dist/react/types/MessagePartComponentTypes.d.ts.map +1 -1
  134. package/dist/react/types/scopes/tools.d.ts +2 -0
  135. package/dist/react/types/scopes/tools.d.ts.map +1 -1
  136. package/dist/runtime/api/message-part-runtime.d.ts +2 -2
  137. package/dist/runtime/api/message-part-runtime.d.ts.map +1 -1
  138. package/dist/runtime/api/message-part-runtime.js +1 -1
  139. package/dist/runtime/api/message-part-runtime.js.map +1 -1
  140. package/dist/runtime/api/thread-list-item-runtime.d.ts +7 -3
  141. package/dist/runtime/api/thread-list-item-runtime.d.ts.map +1 -1
  142. package/dist/runtime/api/thread-list-item-runtime.js +2 -2
  143. package/dist/runtime/api/thread-list-item-runtime.js.map +1 -1
  144. package/dist/runtime/api/thread-list-runtime.d.ts +12 -1
  145. package/dist/runtime/api/thread-list-runtime.d.ts.map +1 -1
  146. package/dist/runtime/api/thread-list-runtime.js +23 -14
  147. package/dist/runtime/api/thread-list-runtime.js.map +1 -1
  148. package/dist/runtime/api/thread-runtime.d.ts +5 -1
  149. package/dist/runtime/api/thread-runtime.d.ts.map +1 -1
  150. package/dist/runtime/api/thread-runtime.js +1 -1
  151. package/dist/runtime/api/thread-runtime.js.map +1 -1
  152. package/dist/runtime/base/base-composer-runtime-core.d.ts.map +1 -1
  153. package/dist/runtime/base/base-composer-runtime-core.js +16 -12
  154. package/dist/runtime/base/base-composer-runtime-core.js.map +1 -1
  155. package/dist/runtime/base/base-thread-runtime-core.d.ts +2 -2
  156. package/dist/runtime/base/base-thread-runtime-core.d.ts.map +1 -1
  157. package/dist/runtime/base/base-thread-runtime-core.js +8 -7
  158. package/dist/runtime/base/base-thread-runtime-core.js.map +1 -1
  159. package/dist/runtime/interfaces/composer-runtime-core.d.ts +12 -5
  160. package/dist/runtime/interfaces/composer-runtime-core.d.ts.map +1 -1
  161. package/dist/runtime/interfaces/thread-list-runtime-core.d.ts +18 -3
  162. package/dist/runtime/interfaces/thread-list-runtime-core.d.ts.map +1 -1
  163. package/dist/runtime/interfaces/thread-runtime-core.d.ts +15 -1
  164. package/dist/runtime/interfaces/thread-runtime-core.d.ts.map +1 -1
  165. package/dist/runtime/utils/auto-status.d.ts +1 -1
  166. package/dist/runtime/utils/auto-status.d.ts.map +1 -1
  167. package/dist/runtime/utils/auto-status.js +6 -2
  168. package/dist/runtime/utils/auto-status.js.map +1 -1
  169. package/dist/runtime/utils/external-message-conversion.d.ts +3 -2
  170. package/dist/runtime/utils/external-message-conversion.d.ts.map +1 -1
  171. package/dist/runtime/utils/external-message-conversion.js +5 -4
  172. package/dist/runtime/utils/external-message-conversion.js.map +1 -1
  173. package/dist/runtime/utils/message-repository.d.ts +1 -0
  174. package/dist/runtime/utils/message-repository.d.ts.map +1 -1
  175. package/dist/runtime/utils/message-repository.js +15 -6
  176. package/dist/runtime/utils/message-repository.js.map +1 -1
  177. package/dist/runtime/utils/resolveToolApprovalResponse.d.ts +6 -3
  178. package/dist/runtime/utils/resolveToolApprovalResponse.d.ts.map +1 -1
  179. package/dist/runtime/utils/resolveToolApprovalResponse.js +12 -3
  180. package/dist/runtime/utils/resolveToolApprovalResponse.js.map +1 -1
  181. package/dist/runtime/utils/thread-message-like.d.ts +2 -10
  182. package/dist/runtime/utils/thread-message-like.d.ts.map +1 -1
  183. package/dist/runtime/utils/thread-message-like.js +1 -1
  184. package/dist/runtime/utils/thread-message-like.js.map +1 -1
  185. package/dist/runtime/utils/tool-call-tree.d.ts +39 -0
  186. package/dist/runtime/utils/tool-call-tree.d.ts.map +1 -0
  187. package/dist/runtime/utils/tool-call-tree.js +85 -0
  188. package/dist/runtime/utils/tool-call-tree.js.map +1 -0
  189. package/dist/runtimes/external-store/external-store-adapter.d.ts +29 -2
  190. package/dist/runtimes/external-store/external-store-adapter.d.ts.map +1 -1
  191. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.d.ts.map +1 -1
  192. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js +21 -27
  193. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js.map +1 -1
  194. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts +2 -1
  195. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts.map +1 -1
  196. package/dist/runtimes/external-store/external-store-thread-runtime-core.js +34 -28
  197. package/dist/runtimes/external-store/external-store-thread-runtime-core.js.map +1 -1
  198. package/dist/runtimes/inert/InertThreadRuntimeCore.d.ts +1 -1
  199. package/dist/runtimes/inert/InertThreadRuntimeCore.d.ts.map +1 -1
  200. package/dist/runtimes/inert/InertThreadRuntimeCore.js.map +1 -1
  201. package/dist/runtimes/internal.d.ts +2 -2
  202. package/dist/runtimes/internal.js +2 -2
  203. package/dist/runtimes/local/local-thread-runtime-core.d.ts +1 -1
  204. package/dist/runtimes/local/local-thread-runtime-core.d.ts.map +1 -1
  205. package/dist/runtimes/local/local-thread-runtime-core.js +3 -1
  206. package/dist/runtimes/local/local-thread-runtime-core.js.map +1 -1
  207. package/dist/runtimes/remote-thread-list/remote-thread-state.d.ts +18 -1
  208. package/dist/runtimes/remote-thread-list/remote-thread-state.d.ts.map +1 -1
  209. package/dist/runtimes/remote-thread-list/remote-thread-state.js +148 -43
  210. package/dist/runtimes/remote-thread-list/remote-thread-state.js.map +1 -1
  211. package/dist/runtimes/remote-thread-list/title-generation.d.ts +49 -0
  212. package/dist/runtimes/remote-thread-list/title-generation.d.ts.map +1 -0
  213. package/dist/runtimes/remote-thread-list/title-generation.js +197 -0
  214. package/dist/runtimes/remote-thread-list/title-generation.js.map +1 -0
  215. package/dist/runtimes/remote-thread-list/title.d.ts +11 -0
  216. package/dist/runtimes/remote-thread-list/title.d.ts.map +1 -0
  217. package/dist/runtimes/remote-thread-list/title.js +14 -0
  218. package/dist/runtimes/remote-thread-list/title.js.map +1 -0
  219. package/dist/runtimes/remote-thread-list/types.d.ts +16 -5
  220. package/dist/runtimes/remote-thread-list/types.d.ts.map +1 -1
  221. package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts +31 -8
  222. package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts.map +1 -1
  223. package/dist/runtimes/tool-invocations/ToolInvocationTracker.js +97 -60
  224. package/dist/runtimes/tool-invocations/ToolInvocationTracker.js.map +1 -1
  225. package/dist/store/clients/external-thread.d.ts +1 -1
  226. package/dist/store/clients/external-thread.d.ts.map +1 -1
  227. package/dist/store/clients/external-thread.js +30 -7
  228. package/dist/store/clients/external-thread.js.map +1 -1
  229. package/dist/store/clients/model-context-client.d.ts.map +1 -1
  230. package/dist/store/clients/model-context-client.js +2 -1
  231. package/dist/store/clients/model-context-client.js.map +1 -1
  232. package/dist/store/clients/single-thread-list.d.ts.map +1 -1
  233. package/dist/store/clients/single-thread-list.js +2 -1
  234. package/dist/store/clients/single-thread-list.js.map +1 -1
  235. package/dist/store/clients/suggestions.d.ts.map +1 -1
  236. package/dist/store/clients/suggestions.js +19 -6
  237. package/dist/store/clients/suggestions.js.map +1 -1
  238. package/dist/store/clients/thread-message-client.js +1 -1
  239. package/dist/store/clients/thread-selection-events.js +1 -1
  240. package/dist/store/index.d.ts +2 -1
  241. package/dist/store/index.js +2 -1
  242. package/dist/store/internal.d.ts +2 -2
  243. package/dist/store/internal.js +2 -2
  244. package/dist/store/primitive-predicates.d.ts +4 -1
  245. package/dist/store/primitive-predicates.d.ts.map +1 -1
  246. package/dist/store/primitive-predicates.js +9 -1
  247. package/dist/store/primitive-predicates.js.map +1 -1
  248. package/dist/store/runtime-clients/composer-runtime-client.d.ts +1 -0
  249. package/dist/store/runtime-clients/composer-runtime-client.d.ts.map +1 -1
  250. package/dist/store/runtime-clients/composer-runtime-client.js +98 -62
  251. package/dist/store/runtime-clients/composer-runtime-client.js.map +1 -1
  252. package/dist/store/runtime-clients/message-runtime-client.d.ts +1 -0
  253. package/dist/store/runtime-clients/message-runtime-client.d.ts.map +1 -1
  254. package/dist/store/runtime-clients/message-runtime-client.js +221 -144
  255. package/dist/store/runtime-clients/message-runtime-client.js.map +1 -1
  256. package/dist/store/runtime-clients/thread-list-item-runtime-client.d.ts.map +1 -1
  257. package/dist/store/runtime-clients/thread-list-item-runtime-client.js +2 -2
  258. package/dist/store/runtime-clients/thread-list-item-runtime-client.js.map +1 -1
  259. package/dist/store/runtime-clients/thread-list-runtime-client.d.ts.map +1 -1
  260. package/dist/store/runtime-clients/thread-list-runtime-client.js +128 -107
  261. package/dist/store/runtime-clients/thread-list-runtime-client.js.map +1 -1
  262. package/dist/store/runtime-clients/thread-runtime-client.d.ts.map +1 -1
  263. package/dist/store/runtime-clients/thread-runtime-client.js +194 -122
  264. package/dist/store/runtime-clients/thread-runtime-client.js.map +1 -1
  265. package/dist/store/runtime-clients/useSubscribable.d.ts +3 -1
  266. package/dist/store/runtime-clients/useSubscribable.d.ts.map +1 -1
  267. package/dist/store/runtime-clients/useSubscribable.js +1 -1
  268. package/dist/store/runtime-clients/useSubscribable.js.map +1 -1
  269. package/dist/store/scopes/composer.d.ts +10 -2
  270. package/dist/store/scopes/composer.d.ts.map +1 -1
  271. package/dist/store/scopes/message.d.ts +30 -1
  272. package/dist/store/scopes/message.d.ts.map +1 -1
  273. package/dist/store/scopes/part.d.ts +6 -3
  274. package/dist/store/scopes/part.d.ts.map +1 -1
  275. package/dist/store/scopes/thread-list-item.d.ts +2 -2
  276. package/dist/store/scopes/thread-list-item.d.ts.map +1 -1
  277. package/dist/store/scopes/thread.d.ts +8 -0
  278. package/dist/store/scopes/thread.d.ts.map +1 -1
  279. package/dist/store/scopes/threads.d.ts +1 -0
  280. package/dist/store/scopes/threads.d.ts.map +1 -1
  281. package/dist/subscribable/subscribable.d.ts +8 -1
  282. package/dist/subscribable/subscribable.d.ts.map +1 -1
  283. package/dist/subscribable/subscribable.js +24 -16
  284. package/dist/subscribable/subscribable.js.map +1 -1
  285. package/dist/types/attachment.d.ts +2 -1
  286. package/dist/types/attachment.d.ts.map +1 -1
  287. package/dist/types/attachment.js +2 -1
  288. package/dist/types/attachment.js.map +1 -1
  289. package/dist/types/message.d.ts +40 -1
  290. package/dist/types/message.d.ts.map +1 -1
  291. package/dist/types/message.js +7 -1
  292. package/dist/types/message.js.map +1 -1
  293. package/dist/utils/abortable-iterable.d.ts +19 -0
  294. package/dist/utils/abortable-iterable.d.ts.map +1 -0
  295. package/dist/utils/abortable-iterable.js +72 -0
  296. package/dist/utils/abortable-iterable.js.map +1 -0
  297. package/dist/utils/composite-context-provider.d.ts.map +1 -1
  298. package/dist/utils/composite-context-provider.js +20 -2
  299. package/dist/utils/composite-context-provider.js.map +1 -1
  300. package/dist/utils/record.d.ts +11 -0
  301. package/dist/utils/record.d.ts.map +1 -0
  302. package/dist/utils/record.js +12 -0
  303. package/dist/utils/record.js.map +1 -0
  304. package/package.json +12 -17
  305. package/src/adapters/attachment.test.ts +50 -1
  306. package/src/adapters/attachment.ts +7 -4
  307. package/src/index.ts +7 -1
  308. package/src/internal.ts +12 -0
  309. package/src/model-context/frame/host.test.ts +24 -0
  310. package/src/model-context/frame/host.ts +10 -4
  311. package/src/model-context/frame/provider.test.ts +288 -1
  312. package/src/model-context/frame/provider.ts +148 -30
  313. package/src/model-context/interactable-composer-metadata.test.ts +28 -0
  314. package/src/model-context/interactable-composer-metadata.ts +9 -3
  315. package/src/model-context/registry.test.ts +12 -0
  316. package/src/model-context/registry.ts +3 -2
  317. package/src/model-context/tool-call-text.test.ts +67 -0
  318. package/src/model-context/tool-call-text.ts +67 -0
  319. package/src/model-context/types.test.ts +25 -0
  320. package/src/model-context/types.ts +9 -4
  321. package/src/react/AssistantRuntimeProvider.test.tsx +66 -2
  322. package/src/react/RuntimeAdapter.test.ts +34 -0
  323. package/src/react/adapters/LocalStorageThreadListAdapter.tsx +1 -3
  324. package/src/react/client/InMemoryThreadList.ts +1 -0
  325. package/src/react/client/Interactables.test.ts +28 -0
  326. package/src/react/client/Interactables.ts +15 -13
  327. package/src/react/client/RemoteThreadList.background.test.ts +526 -0
  328. package/src/react/client/RemoteThreadList.concurrent.test.tsx +315 -0
  329. package/src/react/client/RemoteThreadList.test.ts +617 -3
  330. package/src/react/client/RemoteThreadList.ts +433 -167
  331. package/src/react/client/Tools.ts +29 -12
  332. package/src/react/index.ts +4 -0
  333. package/src/react/interactables-legacy/Interactables.ts +16 -16
  334. package/src/react/interactables-shared/useInteractablePersistenceQueue.ts +9 -10
  335. package/src/react/model-context/makeAssistantTool.ts +2 -2
  336. package/src/react/model-context/modelContextHooks.test.tsx +131 -0
  337. package/src/react/model-context/toolbox.test.ts +9 -9
  338. package/src/react/model-context/toolbox.ts +9 -36
  339. package/src/react/model-context/useAssistantContext.ts +4 -2
  340. package/src/react/model-context/useAssistantTool.ts +2 -2
  341. package/src/react/model-context/useAuiToolOverrides.ts +4 -2
  342. package/src/react/model-context/useInlineRender.test.tsx +48 -0
  343. package/src/react/model-context/useInlineRender.ts +14 -10
  344. package/src/react/model-context/useToolArgsStatus.test.tsx +30 -0
  345. package/src/react/model-context/useToolArgsStatus.ts +2 -1
  346. package/src/react/primitive-hooks/useMessageError.ts +2 -19
  347. package/src/react/primitive-hooks/useThreadListLoadMore.ts +2 -3
  348. package/src/react/primitives/composer/ComposerAttachments.test.tsx +76 -0
  349. package/src/react/primitives/composer/ComposerAttachments.tsx +9 -4
  350. package/src/react/primitives/composer/ComposerQueue.test.tsx +72 -0
  351. package/src/react/primitives/composer/ComposerQueue.tsx +7 -4
  352. package/src/react/primitives/message/MessageAttachments.test.tsx +107 -37
  353. package/src/react/primitives/message/MessageAttachments.tsx +10 -7
  354. package/src/react/primitives/message/MessageGroupedParts.tsx +2 -2
  355. package/src/react/primitives/message/MessageParts.tsx +3 -3
  356. package/src/react/primitives/threadList/ThreadListItems.test.tsx +99 -0
  357. package/src/react/primitives/threadList/ThreadListItems.tsx +8 -5
  358. package/src/react/runtimes/RemoteThreadListHookInstanceManager.destroy.test.tsx +172 -0
  359. package/src/react/runtimes/RemoteThreadListHookInstanceManager.running.test.tsx +127 -1
  360. package/src/react/runtimes/RemoteThreadListHookInstanceManager.test.tsx +7 -1
  361. package/src/react/runtimes/RemoteThreadListHookInstanceManager.tsx +99 -35
  362. package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.load-error.test.ts +132 -0
  363. package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.switch-delete.test.ts +274 -0
  364. package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.tsx +223 -152
  365. package/src/react/runtimes/RemoteThreadResource.test.ts +9 -0
  366. package/src/react/runtimes/RemoteThreadResource.ts +20 -16
  367. package/src/react/runtimes/assistant-transport/transport-scheduling.test.ts +51 -2
  368. package/src/react/runtimes/assistant-transport/useLatestRef.ts +2 -2
  369. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.test.ts +45 -0
  370. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.test.tsx +546 -5
  371. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.ts +546 -103
  372. package/src/react/runtimes/cloud/auiV0.ts +5 -0
  373. package/src/react/runtimes/cloud/createCloudThreadListAdapter.test.ts +103 -0
  374. package/src/react/runtimes/cloud/createCloudThreadListAdapter.ts +237 -0
  375. package/src/react/runtimes/cloud/useCloudThreadListAdapter.test.tsx +90 -1
  376. package/src/react/runtimes/cloud/useCloudThreadListAdapter.tsx +33 -238
  377. package/src/react/runtimes/external-message-converter.ts +1 -0
  378. package/src/react/runtimes/useExternalStoreRuntime.lifecycle.test.tsx +41 -0
  379. package/src/react/runtimes/useExternalStoreRuntime.ts +10 -4
  380. package/src/react/runtimes/useLocalRuntime.test.tsx +20 -0
  381. package/src/react/runtimes/useRemoteThreadListRuntime.concurrent.test.tsx +216 -0
  382. package/src/react/runtimes/useRemoteThreadListRuntime.load-error.test.tsx +108 -0
  383. package/src/react/runtimes/useRemoteThreadListRuntime.ts +57 -6
  384. package/src/react/types/MessagePartComponentTypes.ts +7 -3
  385. package/src/react/types/scopes/tools.ts +2 -0
  386. package/src/runtime/api/message-part-runtime.ts +3 -3
  387. package/src/runtime/api/message-runtime.test.ts +75 -0
  388. package/src/runtime/api/thread-list-item-runtime.ts +10 -3
  389. package/src/runtime/api/thread-list-runtime.ts +46 -12
  390. package/src/runtime/api/thread-runtime.test.ts +78 -0
  391. package/src/runtime/api/thread-runtime.ts +8 -1
  392. package/src/runtime/base/base-composer-runtime-core.ts +36 -8
  393. package/src/runtime/base/base-thread-runtime-core.test.ts +149 -4
  394. package/src/runtime/base/base-thread-runtime-core.ts +16 -8
  395. package/src/runtime/interfaces/composer-runtime-core.ts +10 -5
  396. package/src/runtime/interfaces/thread-list-runtime-core.ts +25 -2
  397. package/src/runtime/interfaces/thread-runtime-core.ts +17 -1
  398. package/src/runtime/utils/auto-status.test.ts +57 -0
  399. package/src/runtime/utils/auto-status.ts +13 -1
  400. package/src/runtime/utils/external-message-conversion.test.ts +165 -0
  401. package/src/runtime/utils/external-message-conversion.ts +18 -2
  402. package/src/runtime/utils/message-repository.ts +29 -17
  403. package/src/runtime/utils/resolveToolApprovalResponse.test.ts +73 -0
  404. package/src/runtime/utils/resolveToolApprovalResponse.ts +27 -6
  405. package/src/runtime/utils/thread-message-like.ts +3 -11
  406. package/src/runtime/utils/tool-call-tree.test.ts +191 -0
  407. package/src/runtime/utils/tool-call-tree.ts +97 -0
  408. package/src/runtimes/external-store/external-store-adapter.ts +38 -2
  409. package/src/runtimes/external-store/external-store-thread-list-runtime-core.ts +18 -13
  410. package/src/runtimes/external-store/external-store-thread-runtime-core.ts +56 -33
  411. package/src/runtimes/inert/InertThreadRuntimeCore.ts +1 -1
  412. package/src/runtimes/internal.ts +1 -0
  413. package/src/runtimes/local/local-thread-runtime-core.test.ts +29 -3
  414. package/src/runtimes/local/local-thread-runtime-core.ts +5 -1
  415. package/src/runtimes/remote-thread-list/remote-thread-state.test.ts +238 -0
  416. package/src/runtimes/remote-thread-list/remote-thread-state.ts +223 -44
  417. package/src/runtimes/remote-thread-list/title-generation.test.ts +602 -0
  418. package/src/runtimes/remote-thread-list/title-generation.ts +329 -0
  419. package/src/runtimes/remote-thread-list/title.test.ts +62 -0
  420. package/src/runtimes/remote-thread-list/title.ts +16 -0
  421. package/src/runtimes/remote-thread-list/types.ts +16 -5
  422. package/src/runtimes/tool-invocations/EDGE_CASES.md +110 -5
  423. package/src/runtimes/tool-invocations/ToolInvocationTracker.test.ts +750 -136
  424. package/src/runtimes/tool-invocations/ToolInvocationTracker.ts +144 -91
  425. package/src/store/clients/external-thread.ts +62 -11
  426. package/src/store/clients/model-context-client.ts +5 -1
  427. package/src/store/clients/single-thread-list.ts +1 -0
  428. package/src/store/clients/suggestions.test.ts +195 -1
  429. package/src/store/clients/suggestions.ts +45 -34
  430. package/src/store/index.ts +4 -0
  431. package/src/store/internal.ts +2 -0
  432. package/src/store/primitive-predicates.ts +35 -0
  433. package/src/store/runtime-clients/composer-runtime-client.ts +42 -9
  434. package/src/store/runtime-clients/message-runtime-client.ts +54 -6
  435. package/src/store/runtime-clients/thread-list-item-runtime-client.ts +4 -2
  436. package/src/store/runtime-clients/thread-list-runtime-client.ts +17 -2
  437. package/src/store/runtime-clients/thread-runtime-client.ts +58 -10
  438. package/src/store/runtime-clients/useSubscribable.ts +8 -2
  439. package/src/store/scopes/composer.ts +16 -4
  440. package/src/store/scopes/message.ts +14 -0
  441. package/src/store/scopes/part.ts +6 -3
  442. package/src/store/scopes/thread-list-item.ts +5 -2
  443. package/src/store/scopes/thread.ts +4 -0
  444. package/src/store/scopes/threads.ts +1 -0
  445. package/src/subscribable/subscribable.test.ts +50 -0
  446. package/src/subscribable/subscribable.ts +33 -21
  447. package/src/tests/MessageRepository.test.ts +116 -0
  448. package/src/tests/OptimisticState-list-race.test.ts +1 -0
  449. package/src/tests/RemoteThreadListThreadListRuntimeCore-initialize-adapter-change.test.ts +38 -0
  450. package/src/tests/RemoteThreadListThreadListRuntimeCore-load-race.test.ts +158 -0
  451. package/src/tests/RemoteThreadListThreadListRuntimeCore-loadMore.test.ts +78 -0
  452. package/src/tests/RemoteThreadListThreadListRuntimeCore-reload.test.ts +52 -0
  453. package/src/tests/RemoteThreadListThreadListRuntimeCore-title-race.test.ts +89 -0
  454. package/src/tests/attachment-adapters.test.ts +14 -0
  455. package/src/tests/base-composer-runtime-core.test.ts +39 -0
  456. package/src/tests/external-store-optimistic-id.test.ts +79 -0
  457. package/src/tests/external-store-repository-instance.test.ts +166 -0
  458. package/src/tests/external-store-thread-list-runtime-core.test.ts +83 -0
  459. package/src/tests/external-store-thread-runtime-core-adapter.test.ts +49 -34
  460. package/src/tests/external-thread-attachments.test.tsx +224 -1
  461. package/src/tests/external-thread-parity.test.tsx +23 -0
  462. package/src/tests/remote-thread-list-adapter-switch.test.ts +66 -1
  463. package/src/tests/remote-thread-list-isLoading.test.ts +1 -0
  464. package/src/tests/thread-list-runtime-getLoadThreadsPromise.test.ts +1 -0
  465. package/src/tests/thread-switch-events.test.tsx +475 -2
  466. package/src/tests/tools-scope-migration.test.tsx +28 -0
  467. package/src/types/attachment.ts +4 -0
  468. package/src/types/message.ts +50 -2
  469. package/src/utils/abortable-iterable.test.ts +213 -0
  470. package/src/utils/abortable-iterable.ts +93 -0
  471. package/src/utils/composite-context-provider.test.ts +25 -0
  472. package/src/utils/composite-context-provider.ts +23 -2
  473. package/src/utils/record.test.ts +48 -0
  474. package/src/utils/record.ts +11 -0
@@ -1,16 +1,17 @@
1
1
  import { OptimisticState } from "../../runtimes/remote-thread-list/optimistic-state.js";
2
- import { classifyThreads, createEmptyRemoteThreadState, createThreadMappingId, getThreadData, normalizeCursor, preserveMidLoadTransitions, seedNewThread, statusSnapshot, updateStatusReducer } from "../../runtimes/remote-thread-list/remote-thread-state.js";
2
+ import { classifyThreads, createEmptyRemoteThreadState, createThreadMappingId, getThreadData, normalizeCursor, preserveMidLoadTransitions, promoteNewThreadReducer, reconcileInitializedThread, seedNewThread, statusSnapshot, updateStatusReducer } from "../../runtimes/remote-thread-list/remote-thread-state.js";
3
3
  import { handleThreadListAction } from "../../store/runtime-clients/handle-thread-list-action.js";
4
4
  import { useThreadSelectionEvents } from "../../store/clients/thread-selection-events.js";
5
5
  import { isDevelopment } from "../../store/env.js";
6
6
  import { inMemoryThreadListTransformScopes } from "./InMemoryThreadList.js";
7
7
  import { ThreadListAdapterChangedError } from "../../runtimes/remote-thread-list/adapter-changed.js";
8
8
  import { AdaptedRemoteThread } from "./AdaptedRemoteThread.js";
9
- import { AssistantMessageStream } from "assistant-stream";
9
+ import { applyTitleStream, isTitleSourceMessage } from "../../runtimes/remote-thread-list/title.js";
10
+ import { clearThreadTitleState, finishThreadTitleRename, runThreadTitleGeneration, startThreadTitleRename } from "../../runtimes/remote-thread-list/title-generation.js";
11
+ import { Derived, attachTransformScopes, useAssistantContextProvider, useAssistantContextValue, useClientLookup, useClientResource, useConfiguredAui } from "@assistant-ui/store/client";
10
12
  import { c } from "@assistant-ui/tap/react-shim/compiler-runtime";
11
- import { useCallback, useEffect, useMemo, useState, useSyncExternalStore } from "@assistant-ui/tap/react-shim";
13
+ import { useCallback, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "@assistant-ui/tap/react-shim";
12
14
  import { resource, withKey } from "@assistant-ui/tap";
13
- import { attachTransformScopes, useClientLookup, useClientResource } from "@assistant-ui/store/client";
14
15
  //#region src/react/client/RemoteThreadList.ts
15
16
  const RESOLVED_PROMISE = Promise.resolve();
16
17
  const EMPTY_LIST = createEmptyRemoteThreadState();
@@ -20,10 +21,6 @@ const toInitializeResult = (result) => ({
20
21
  remoteId: result.remoteId,
21
22
  externalId: result.externalId
22
23
  });
23
- const applyTitleStream = async (stream, onTitle) => {
24
- const messageStream = AssistantMessageStream.fromAssistantStream(stream);
25
- for await (const result of messageStream) await onTitle(result.parts.filter((part) => part.type === "text")[0]?.text);
26
- };
27
24
  const useThreadListItemClient = (props) => {
28
25
  const $ = c(22);
29
26
  const { data, isRunning, onSwitchTo, onRename, onUpdateCustom, onArchive, onUnarchive, onDelete, onGenerateTitle, onInitialize, onDetach } = props;
@@ -115,98 +112,175 @@ const isSameThread = (listState, left, right) => {
115
112
  const data = getThreadData(listState, left);
116
113
  return data !== void 0 && itemMatchesId(data, listState, right);
117
114
  };
115
+ const useRemoteThreadBody = ({ id, status, remoteId, item, thread }) => {
116
+ const parent = useAssistantContextValue();
117
+ const [isRunning, setIsRunning] = useState(false);
118
+ const itemHandle = useClientResource(item(isRunning));
119
+ const { client } = useConfiguredAui(parent, { threadListItem: Derived({
120
+ source: "threads",
121
+ query: {
122
+ type: "id",
123
+ id
124
+ },
125
+ get: () => itemHandle.methods
126
+ }) });
127
+ const bornNewRef = useRef(status === "new");
128
+ const titleFiredRef = useRef(false);
129
+ return useAssistantContextProvider(client, function useBoundRemoteBody() {
130
+ const body = useClientResource(thread);
131
+ const bodyRunning = body.state.isRunning === true;
132
+ useEffect(() => {
133
+ setIsRunning(bodyRunning);
134
+ }, [bodyRunning]);
135
+ const hasTitleSource = bornNewRef.current && !titleFiredRef.current && remoteId !== void 0 && body.state.messages.some(isTitleSourceMessage);
136
+ useEffect(() => {
137
+ if (!hasTitleSource || titleFiredRef.current) return;
138
+ titleFiredRef.current = true;
139
+ client.threadListItem.generateTitle({ automatic: true });
140
+ }, [hasTitleSource]);
141
+ return body.methods;
142
+ });
143
+ };
144
+ const RemoteThreadBody = resource(useRemoteThreadBody);
145
+ const useMainThreadFacade = (current) => {
146
+ const currentRef = useRef(current);
147
+ useEffect(() => {
148
+ currentRef.current = current;
149
+ }, [current]);
150
+ const [facade] = useState(() => new Proxy({}, {
151
+ get: (_, prop) => currentRef.current[prop],
152
+ has: (__0, prop_0) => prop_0 in currentRef.current,
153
+ ownKeys: () => Reflect.ownKeys(currentRef.current),
154
+ getOwnPropertyDescriptor: (__1, prop_1) => Reflect.getOwnPropertyDescriptor(currentRef.current, prop_1)
155
+ }));
156
+ return facade;
157
+ };
118
158
  const useRemoteThreadListView = (t0) => {
119
- const $ = c(39);
120
- const { listState, mainThreadId, threadFactory, useAdapters, onSwitchTo, onRename, onUpdateCustom, onArchive, onUnarchive, onDelete, onGenerateTitle, onInitialize, onDetach } = t0;
159
+ const $ = c(21);
160
+ const { listState, mainThreadId, startedIds, backgroundThreads, threadFactory, useAdapters, onSwitchTo, onRename, onUpdateCustom, onArchive, onUnarchive, onDelete, onGenerateTitle, onInitialize, onDetach } = t0;
121
161
  let t1;
122
- let t2;
123
- if ($[0] !== mainThreadId || $[1] !== threadFactory || $[2] !== useAdapters) {
124
- const thread = threadFactory(mainThreadId);
162
+ bb0: {
163
+ if (!backgroundThreads) {
164
+ let t2;
165
+ if ($[0] !== mainThreadId) {
166
+ t2 = [mainThreadId];
167
+ $[0] = mainThreadId;
168
+ $[1] = t2;
169
+ } else t2 = $[1];
170
+ t1 = t2;
171
+ break bb0;
172
+ }
173
+ let ids;
174
+ if ($[2] !== listState || $[3] !== startedIds) {
175
+ const seen = /* @__PURE__ */ new Set();
176
+ const seenRemoteIds = /* @__PURE__ */ new Set();
177
+ ids = [];
178
+ for (const id of startedIds) {
179
+ const data = getThreadData(listState, id);
180
+ if (!data || seen.has(data.id)) continue;
181
+ if (data.remoteId !== void 0 && seenRemoteIds.has(data.remoteId)) continue;
182
+ seen.add(data.id);
183
+ if (data.remoteId !== void 0) seenRemoteIds.add(data.remoteId);
184
+ ids.push(data.id);
185
+ }
186
+ $[2] = listState;
187
+ $[3] = startedIds;
188
+ $[4] = ids;
189
+ } else ids = $[4];
190
+ t1 = ids;
191
+ }
192
+ const bodyIds = t1;
193
+ const itemElementFor = (data_0, isRunning) => ThreadListItemClient({
194
+ data: data_0,
195
+ isRunning,
196
+ onSwitchTo: (options) => handleThreadListAction("switch", () => onSwitchTo(data_0.id, options)),
197
+ onRename: (title) => handleThreadListAction("rename", () => onRename(data_0.id, title)),
198
+ onUpdateCustom: (custom) => handleThreadListAction("update custom metadata", () => onUpdateCustom(data_0.id, custom)),
199
+ onArchive: () => handleThreadListAction("archive", () => onArchive(data_0.id)),
200
+ onUnarchive: () => handleThreadListAction("unarchive", () => onUnarchive(data_0.id)),
201
+ onDelete: () => handleThreadListAction("delete", () => onDelete(data_0.id)),
202
+ onGenerateTitle: (options_0) => handleThreadListAction("generate title", () => onGenerateTitle(data_0.id, backgroundThreads ? bodyStateOf(data_0.id)?.messages : mainThreadClient.state.messages, options_0)),
203
+ onInitialize: () => onInitialize(data_0.id),
204
+ onDetach: () => handleThreadListAction("detach", () => onDetach(data_0.id))
205
+ });
206
+ const bodies = useClientLookup(bodyIds.map((id_0) => {
207
+ const made = threadFactory(id_0);
208
+ const thread = backgroundThreads && made.key === void 0 ? withKey(id_0, made) : made;
125
209
  const wrapped = useAdapters === void 0 ? thread : AdaptedRemoteThread({
126
210
  useAdapters,
127
211
  thread
128
212
  });
129
- t1 = useClientResource;
130
- t2 = thread.key === void 0 ? wrapped : withKey(thread.key, wrapped);
131
- $[0] = mainThreadId;
132
- $[1] = threadFactory;
133
- $[2] = useAdapters;
134
- $[3] = t1;
135
- $[4] = t2;
136
- } else {
137
- t1 = $[3];
138
- t2 = $[4];
139
- }
140
- const mainThreadClient = t1(t2);
213
+ const data_1 = getThreadData(listState, id_0);
214
+ const element = backgroundThreads && data_1 !== void 0 ? RemoteThreadBody({
215
+ id: id_0,
216
+ status: data_1.status,
217
+ remoteId: data_1.remoteId,
218
+ item: (isRunning_0) => itemElementFor(data_1, isRunning_0),
219
+ thread: wrapped
220
+ }) : wrapped;
221
+ return withKey(backgroundThreads ? id_0 : made.key ?? "main", element);
222
+ }));
223
+ let t2;
224
+ if ($[5] !== bodyIds || $[6] !== listState) {
225
+ t2 = (id_1) => {
226
+ const direct = bodyIds.indexOf(id_1);
227
+ if (direct !== -1) return direct;
228
+ return bodyIds.findIndex((bodyId) => isSameThread(listState, bodyId, id_1));
229
+ };
230
+ $[5] = bodyIds;
231
+ $[6] = listState;
232
+ $[7] = t2;
233
+ } else t2 = $[7];
234
+ const bodyIndexOf = t2;
235
+ const bodyStateOf = (id_2) => {
236
+ const index = bodyIndexOf(id_2);
237
+ return index === -1 ? void 0 : bodies.state[index];
238
+ };
141
239
  let t3;
142
- if ($[5] !== listState || $[6] !== mainThreadId) {
143
- t3 = collectItemOrder(listState, mainThreadId);
144
- $[5] = listState;
145
- $[6] = mainThreadId;
146
- $[7] = t3;
147
- } else t3 = $[7];
148
- const itemOrder = t3;
149
240
  let t4;
150
- if ($[8] !== itemOrder || $[9] !== listState || $[10] !== mainThreadClient || $[11] !== mainThreadId || $[12] !== onArchive || $[13] !== onDelete || $[14] !== onDetach || $[15] !== onGenerateTitle || $[16] !== onInitialize || $[17] !== onRename || $[18] !== onSwitchTo || $[19] !== onUnarchive || $[20] !== onUpdateCustom) {
151
- let t5;
152
- if ($[22] !== listState || $[23] !== mainThreadClient || $[24] !== mainThreadId || $[25] !== onArchive || $[26] !== onDelete || $[27] !== onDetach || $[28] !== onGenerateTitle || $[29] !== onInitialize || $[30] !== onRename || $[31] !== onSwitchTo || $[32] !== onUnarchive || $[33] !== onUpdateCustom) {
153
- t5 = (data) => withKey(data.id, ThreadListItemClient({
154
- data,
155
- isRunning: itemMatchesId(data, listState, mainThreadId) && mainThreadClient.state.isRunning,
156
- onSwitchTo: (options) => handleThreadListAction("switch", () => onSwitchTo(data.id, options)),
157
- onRename: (title) => handleThreadListAction("rename", () => onRename(data.id, title)),
158
- onUpdateCustom: (custom) => handleThreadListAction("update custom metadata", () => onUpdateCustom(data.id, custom)),
159
- onArchive: () => handleThreadListAction("archive", () => onArchive(data.id)),
160
- onUnarchive: () => handleThreadListAction("unarchive", () => onUnarchive(data.id)),
161
- onDelete: () => handleThreadListAction("delete", () => onDelete(data.id)),
162
- onGenerateTitle: () => handleThreadListAction("generate title", () => onGenerateTitle(data.id, mainThreadClient.state.messages)),
163
- onInitialize: () => onInitialize(data.id),
164
- onDetach: () => handleThreadListAction("detach", () => onDetach(data.id))
165
- }));
166
- $[22] = listState;
167
- $[23] = mainThreadClient;
168
- $[24] = mainThreadId;
169
- $[25] = onArchive;
170
- $[26] = onDelete;
171
- $[27] = onDetach;
172
- $[28] = onGenerateTitle;
173
- $[29] = onInitialize;
174
- $[30] = onRename;
175
- $[31] = onSwitchTo;
176
- $[32] = onUnarchive;
177
- $[33] = onUpdateCustom;
178
- $[34] = t5;
179
- } else t5 = $[34];
180
- t4 = itemOrder.map(t5);
181
- $[8] = itemOrder;
182
- $[9] = listState;
183
- $[10] = mainThreadClient;
184
- $[11] = mainThreadId;
185
- $[12] = onArchive;
186
- $[13] = onDelete;
187
- $[14] = onDetach;
188
- $[15] = onGenerateTitle;
189
- $[16] = onInitialize;
190
- $[17] = onRename;
191
- $[18] = onSwitchTo;
192
- $[19] = onUnarchive;
193
- $[20] = onUpdateCustom;
194
- $[21] = t4;
195
- } else t4 = $[21];
196
- const threadListItems = useClientLookup(t4);
197
241
  let t5;
198
- if ($[35] !== itemOrder || $[36] !== mainThreadClient || $[37] !== threadListItems) {
199
- t5 = {
242
+ if ($[8] !== bodies || $[9] !== bodyIndexOf || $[10] !== mainThreadId) {
243
+ const mainIndex = bodyIndexOf(mainThreadId);
244
+ t5 = bodies.state[mainIndex];
245
+ t3 = useMainThreadFacade;
246
+ t4 = bodies.get({ index: mainIndex });
247
+ $[8] = bodies;
248
+ $[9] = bodyIndexOf;
249
+ $[10] = mainThreadId;
250
+ $[11] = t3;
251
+ $[12] = t4;
252
+ $[13] = t5;
253
+ } else {
254
+ t3 = $[11];
255
+ t4 = $[12];
256
+ t5 = $[13];
257
+ }
258
+ const mainThreadClient = {
259
+ state: t5,
260
+ methods: t3(t4)
261
+ };
262
+ let t6;
263
+ if ($[14] !== listState || $[15] !== mainThreadId) {
264
+ t6 = collectItemOrder(listState, mainThreadId);
265
+ $[14] = listState;
266
+ $[15] = mainThreadId;
267
+ $[16] = t6;
268
+ } else t6 = $[16];
269
+ const itemOrder = t6;
270
+ const threadListItems = useClientLookup(itemOrder.map((data_2) => withKey(data_2.id, itemElementFor(data_2, backgroundThreads ? bodyStateOf(data_2.id)?.isRunning ?? false : itemMatchesId(data_2, listState, mainThreadId) && mainThreadClient.state.isRunning))));
271
+ let t7;
272
+ if ($[17] !== itemOrder || $[18] !== mainThreadClient || $[19] !== threadListItems) {
273
+ t7 = {
200
274
  mainThreadClient,
201
275
  itemOrder,
202
276
  threadListItems
203
277
  };
204
- $[35] = itemOrder;
205
- $[36] = mainThreadClient;
206
- $[37] = threadListItems;
207
- $[38] = t5;
208
- } else t5 = $[38];
209
- return t5;
278
+ $[17] = itemOrder;
279
+ $[18] = mainThreadClient;
280
+ $[19] = threadListItems;
281
+ $[20] = t7;
282
+ } else t7 = $[20];
283
+ return t7;
210
284
  };
211
285
  const useRemoteThreadList = (props) => {
212
286
  const { adapter, thread: threadFactory, threadId, onThreadIdChange, onSwitchToThread, onSwitchToNewThread, onDelete } = props;
@@ -219,6 +293,7 @@ const useRemoteThreadList = (props) => {
219
293
  adapter,
220
294
  adapterAtLoad: adapter,
221
295
  adapterGeneration: 0,
296
+ titleStates: /* @__PURE__ */ new Map(),
222
297
  loadGeneration: 0,
223
298
  switchGeneration: 0,
224
299
  loadPromise: void 0,
@@ -234,12 +309,14 @@ const useRemoteThreadList = (props) => {
234
309
  }
235
310
  };
236
311
  });
237
- session.adapter = adapter;
238
312
  const listState = useSyncExternalStore((onStoreChange) => store.subscribe(onStoreChange), () => store.value, () => store.value);
239
313
  const [mainThreadId, setMainThreadId] = useState(initialMainId);
314
+ const [startedIds, setStartedIds] = useState([initialMainId]);
315
+ const [backgroundThreads] = useState(props.backgroundThreads === true);
240
316
  const assignMainThreadId = useCallback((id) => {
241
317
  session.mainThreadId = id;
242
318
  setMainThreadId(id);
319
+ setStartedIds((prev) => prev.includes(id) ? prev : [...prev, id]);
243
320
  }, [session]);
244
321
  useThreadSelectionEvents(mainThreadId);
245
322
  useEffect(() => {
@@ -268,33 +345,32 @@ const useRemoteThreadList = (props) => {
268
345
  const statusAtRequest = statusSnapshot(store.baseValue);
269
346
  session.loadPromise = store.optimisticUpdate({
270
347
  execute: () => adapter_0.list(),
271
- loading: (state) => ({
272
- ...state,
273
- isLoading: true
274
- }),
348
+ loading: (state) => {
349
+ if (generation !== session.loadGeneration) return state;
350
+ return {
351
+ ...state,
352
+ isLoading: true,
353
+ loadError: void 0
354
+ };
355
+ },
275
356
  then: (state_0, page) => {
276
357
  if (generation !== session.loadGeneration) return state_0;
277
358
  session.adapterAtLoad = adapter_0;
278
359
  const fresh = classifyThreads(page.threads, {
279
360
  threadIds: [],
280
361
  archivedThreadIds: [],
281
- threadIdMap: {},
282
- threadData: {}
362
+ threadIdMap: { ...state_0.threadIdMap },
363
+ threadData: { ...state_0.threadData }
283
364
  });
284
365
  const merged = {
285
366
  ...state_0,
286
367
  isLoading: false,
368
+ loadError: void 0,
287
369
  cursor: normalizeCursor(page.nextCursor),
288
370
  threadIds: fresh.threadIds,
289
371
  archivedThreadIds: fresh.archivedThreadIds,
290
- threadIdMap: {
291
- ...state_0.threadIdMap,
292
- ...fresh.threadIdMap
293
- },
294
- threadData: {
295
- ...state_0.threadData,
296
- ...fresh.threadData
297
- }
372
+ threadIdMap: fresh.threadIdMap,
373
+ threadData: fresh.threadData
298
374
  };
299
375
  return preserveMidLoadTransitions(merged, state_0, statusAtRequest);
300
376
  }
@@ -304,7 +380,8 @@ const useRemoteThreadList = (props) => {
304
380
  session.loadPromise = void 0;
305
381
  store.update({
306
382
  ...store.baseValue,
307
- isLoading: false
383
+ isLoading: false,
384
+ loadError: error
308
385
  });
309
386
  }).then(() => {});
310
387
  return session.loadPromise;
@@ -316,6 +393,7 @@ const useRemoteThreadList = (props) => {
316
393
  session.loadMorePromise = void 0;
317
394
  if (adapterChanged) {
318
395
  session.adapterGeneration++;
396
+ session.titleStates.clear();
319
397
  session.switchGeneration++;
320
398
  session.switchTask = void 0;
321
399
  session.adapterAtLoad = adapter;
@@ -325,6 +403,7 @@ const useRemoteThreadList = (props) => {
325
403
  isLoading: true
326
404
  });
327
405
  assignMainThreadId(seeded_0.id);
406
+ setStartedIds([seeded_0.id]);
328
407
  notifyRemoteId(void 0, true);
329
408
  } else store.update({
330
409
  ...store.baseValue,
@@ -339,6 +418,21 @@ const useRemoteThreadList = (props) => {
339
418
  session,
340
419
  store
341
420
  ]);
421
+ useEffect(() => {
422
+ if (typeof window === "undefined" || typeof document === "undefined") return;
423
+ const retryAfterError = () => {
424
+ if (store.value.loadError !== void 0) getLoadThreadsPromise();
425
+ };
426
+ const retryAfterVisible = () => {
427
+ if (document.visibilityState === "visible") retryAfterError();
428
+ };
429
+ window.addEventListener("online", retryAfterError);
430
+ document.addEventListener("visibilitychange", retryAfterVisible);
431
+ return () => {
432
+ window.removeEventListener("online", retryAfterError);
433
+ document.removeEventListener("visibilitychange", retryAfterVisible);
434
+ };
435
+ }, [getLoadThreadsPromise, store]);
342
436
  useEffect(() => {
343
437
  getLoadThreadsPromise();
344
438
  }, [getLoadThreadsPromise]);
@@ -357,10 +451,13 @@ const useRemoteThreadList = (props) => {
357
451
  const currentAdapter = session.adapter;
358
452
  const task = store.optimisticUpdate({
359
453
  execute: () => currentAdapter.list({ after: cursor }),
360
- loading: (state_1) => ({
361
- ...state_1,
362
- isLoadingMore: true
363
- }),
454
+ loading: (state_1) => {
455
+ if (generation_0 !== session.loadGeneration) return state_1;
456
+ return {
457
+ ...state_1,
458
+ isLoadingMore: true
459
+ };
460
+ },
364
461
  then: (state_2, page_0) => {
365
462
  if (generation_0 !== session.loadGeneration) return state_2;
366
463
  const appended = classifyThreads(page_0.threads, {
@@ -440,21 +537,27 @@ const useRemoteThreadList = (props) => {
440
537
  }
441
538
  if (!data) throw threadNotFoundError(threadIdOrRemoteId, "switching to it");
442
539
  if (isSameThread(store.value, data.id, session.mainThreadId)) return;
443
- if (data.status === "archived" && options?.unarchive !== false) {
444
- const current = data;
540
+ const targetId = data.id;
541
+ let current = data;
542
+ if (current.status === "archived" && options?.unarchive !== false) {
445
543
  const { remoteId: remoteId_0 } = await current.initializeTask;
446
544
  if (generation_2 !== session.switchGeneration) return;
447
- await store.optimisticUpdate({
448
- execute: () => session.adapter.unarchive(remoteId_0),
449
- optimistic: (state_4) => updateStatusReducer(state_4, current.id, "regular")
450
- });
451
- if (generation_2 !== session.switchGeneration) return;
452
- data = getThreadData(store.value, current.id) ?? current;
545
+ current = getThreadData(store.value, targetId);
546
+ if (current?.id !== targetId) return;
547
+ if (current.status === "archived") {
548
+ await store.optimisticUpdate({
549
+ execute: () => session.adapter.unarchive(remoteId_0),
550
+ optimistic: (state_4) => updateStatusReducer(state_4, targetId, "regular")
551
+ });
552
+ if (generation_2 !== session.switchGeneration) return;
553
+ current = getThreadData(store.value, targetId);
554
+ if (current?.id !== targetId) return;
555
+ }
453
556
  }
454
557
  if (generation_2 !== session.switchGeneration) return;
455
- assignMainThreadId(data.id);
456
- notifyRemoteId(data.remoteId, emitThreadIdChange);
457
- session.onSwitchToThread?.(data.id);
558
+ assignMainThreadId(current.id);
559
+ notifyRemoteId(current.remoteId, emitThreadIdChange);
560
+ session.onSwitchToThread?.(current.id);
458
561
  }), [
459
562
  assignMainThreadId,
460
563
  notifyRemoteId,
@@ -522,55 +625,30 @@ const useRemoteThreadList = (props) => {
522
625
  requireAdapterGeneration(adapterGeneration);
523
626
  return result;
524
627
  }
628
+ requireAdapterGeneration(adapterGeneration);
629
+ const initializeTask = currentAdapter_0.initialize(threadId_1);
630
+ let removedMappingId;
631
+ let replacementMainThreadId;
525
632
  const result_0 = await store.optimisticUpdate({
526
- execute: () => {
527
- requireAdapterGeneration(adapterGeneration);
528
- return currentAdapter_0.initialize(threadId_1);
529
- },
530
- optimistic: (state_5) => updateStatusReducer(state_5, threadId_1, "regular"),
531
- loading: (state_6, task_1) => {
532
- const mappingId_0 = createThreadMappingId(threadId_1);
533
- return {
534
- ...state_6,
535
- threadData: {
536
- ...state_6.threadData,
537
- [mappingId_0]: {
538
- ...state_6.threadData[mappingId_0],
539
- initializeTask: task_1
540
- }
541
- }
542
- };
543
- },
544
- then: (state_7, { remoteId: remoteId_1, externalId }) => {
545
- if (adapterGeneration !== session.adapterGeneration) return state_7;
546
- const data_1 = getThreadData(state_7, threadId_1);
547
- if (!data_1) return state_7;
548
- const mappingId_1 = createThreadMappingId(threadId_1);
549
- return {
550
- ...state_7,
551
- threadIdMap: {
552
- ...state_7.threadIdMap,
553
- [remoteId_1]: mappingId_1
554
- },
555
- threadData: {
556
- ...state_7.threadData,
557
- [mappingId_1]: {
558
- ...data_1,
559
- initializeTask: Promise.resolve({
560
- remoteId: remoteId_1,
561
- externalId
562
- }),
563
- remoteId: remoteId_1,
564
- externalId
565
- }
566
- }
567
- };
633
+ execute: () => initializeTask,
634
+ optimistic: (state_5) => promoteNewThreadReducer(state_5, threadId_1, initializeTask),
635
+ then: (state_6, { remoteId: remoteId_1, externalId }) => {
636
+ if (adapterGeneration !== session.adapterGeneration) return state_6;
637
+ const retainedThreadId = backgroundThreads ? threadId_1 : session.mainThreadId;
638
+ const reconciliation = reconcileInitializedThread(state_6, threadId_1, remoteId_1, externalId, retainedThreadId);
639
+ removedMappingId = reconciliation.removedMappingId;
640
+ if (removedMappingId === session.mainThreadId) replacementMainThreadId = reconciliation.survivorMappingId;
641
+ return reconciliation.state;
568
642
  }
569
643
  });
570
644
  requireAdapterGeneration(adapterGeneration);
645
+ if (removedMappingId !== void 0) setStartedIds((prev_0) => prev_0.filter((startedId) => startedId !== removedMappingId));
646
+ if (replacementMainThreadId !== void 0 && session.mainThreadId === removedMappingId) assignMainThreadId(replacementMainThreadId);
571
647
  if (threadId_1 === session.mainThreadId) notifyRemoteId(result_0.remoteId, true);
572
648
  return toInitializeResult(result_0);
573
649
  }, [
650
+ assignMainThreadId,
651
+ backgroundThreads,
574
652
  notifyRemoteId,
575
653
  requireAdapterGeneration,
576
654
  session,
@@ -579,22 +657,23 @@ const useRemoteThreadList = (props) => {
579
657
  const rename = useCallback((threadIdOrRemoteId_0, newTitle) => {
580
658
  const currentAdapter_1 = session.adapter;
581
659
  const adapterGeneration_0 = session.adapterGeneration;
582
- const data_2 = getThreadData(store.value, threadIdOrRemoteId_0);
583
- if (!data_2) throw threadNotFoundError(threadIdOrRemoteId_0, "renaming it");
584
- if (data_2.status === "new") throw threadStatusError(threadIdOrRemoteId_0, data_2.status, "be renamed");
660
+ const data_1 = getThreadData(store.value, threadIdOrRemoteId_0);
661
+ if (!data_1) throw threadNotFoundError(threadIdOrRemoteId_0, "renaming it");
662
+ if (data_1.status === "new") throw threadStatusError(threadIdOrRemoteId_0, data_1.status, "be renamed");
663
+ const claim = startThreadTitleRename(session.titleStates, data_1.id, newTitle);
585
664
  return store.optimisticUpdate({
586
665
  execute: async () => {
587
- const { remoteId: remoteId_2 } = await data_2.initializeTask;
666
+ const { remoteId: remoteId_2 } = await data_1.initializeTask;
588
667
  requireAdapterGeneration(adapterGeneration_0);
589
668
  return currentAdapter_1.rename(remoteId_2, newTitle);
590
669
  },
591
- optimistic: (state_8) => {
592
- const current_0 = getThreadData(state_8, threadIdOrRemoteId_0);
593
- if (!current_0) return state_8;
670
+ optimistic: (state_7) => {
671
+ const current_0 = getThreadData(state_7, threadIdOrRemoteId_0);
672
+ if (!current_0) return state_7;
594
673
  return {
595
- ...state_8,
674
+ ...state_7,
596
675
  threadData: {
597
- ...state_8.threadData,
676
+ ...state_7.threadData,
598
677
  [current_0.id]: {
599
678
  ...current_0,
600
679
  title: newTitle
@@ -602,6 +681,12 @@ const useRemoteThreadList = (props) => {
602
681
  }
603
682
  };
604
683
  }
684
+ }).then((result_1) => {
685
+ finishThreadTitleRename(session.titleStates, data_1.id, claim, true);
686
+ return result_1;
687
+ }, (error_4) => {
688
+ finishThreadTitleRename(session.titleStates, data_1.id, claim, false);
689
+ throw error_4;
605
690
  });
606
691
  }, [
607
692
  requireAdapterGeneration,
@@ -611,24 +696,24 @@ const useRemoteThreadList = (props) => {
611
696
  const updateCustom = useCallback((threadIdOrRemoteId_1, custom) => {
612
697
  const currentAdapter_2 = session.adapter;
613
698
  const adapterGeneration_1 = session.adapterGeneration;
614
- const data_3 = getThreadData(store.value, threadIdOrRemoteId_1);
615
- if (!data_3) throw threadNotFoundError(threadIdOrRemoteId_1, "updating its custom metadata");
616
- if (data_3.status === "new") throw threadStatusError(threadIdOrRemoteId_1, data_3.status, "update custom metadata");
699
+ const data_2 = getThreadData(store.value, threadIdOrRemoteId_1);
700
+ if (!data_2) throw threadNotFoundError(threadIdOrRemoteId_1, "updating its custom metadata");
701
+ if (data_2.status === "new") throw threadStatusError(threadIdOrRemoteId_1, data_2.status, "update custom metadata");
617
702
  if (!currentAdapter_2.updateCustom) throw new Error("Remote thread list adapter does not support updating custom metadata");
618
703
  return store.optimisticUpdate({
619
704
  execute: async () => {
620
- const { remoteId: remoteId_3 } = await data_3.initializeTask;
705
+ const { remoteId: remoteId_3 } = await data_2.initializeTask;
621
706
  requireAdapterGeneration(adapterGeneration_1);
622
707
  if (!currentAdapter_2.updateCustom) throw new Error("Remote thread list adapter does not support updating custom metadata");
623
708
  return currentAdapter_2.updateCustom(remoteId_3, custom);
624
709
  },
625
- optimistic: (state_9) => {
626
- const current_1 = getThreadData(state_9, threadIdOrRemoteId_1);
627
- if (!current_1) return state_9;
710
+ optimistic: (state_8) => {
711
+ const current_1 = getThreadData(state_8, threadIdOrRemoteId_1);
712
+ if (!current_1) return state_8;
628
713
  return {
629
- ...state_9,
714
+ ...state_8,
630
715
  threadData: {
631
- ...state_9.threadData,
716
+ ...state_8.threadData,
632
717
  [current_1.id]: {
633
718
  ...current_1,
634
719
  custom
@@ -645,18 +730,18 @@ const useRemoteThreadList = (props) => {
645
730
  const archive = useCallback(async (threadIdOrRemoteId_2) => {
646
731
  const currentAdapter_3 = session.adapter;
647
732
  const adapterGeneration_2 = session.adapterGeneration;
648
- const data_4 = getThreadData(store.value, threadIdOrRemoteId_2);
649
- if (!data_4) throw threadNotFoundError(threadIdOrRemoteId_2, "archiving it");
650
- if (data_4.status !== "regular") throw threadStatusError(threadIdOrRemoteId_2, data_4.status, "be archived");
651
- await ensureNotMain(data_4.id);
733
+ const data_3 = getThreadData(store.value, threadIdOrRemoteId_2);
734
+ if (!data_3) throw threadNotFoundError(threadIdOrRemoteId_2, "archiving it");
735
+ if (data_3.status !== "regular") throw threadStatusError(threadIdOrRemoteId_2, data_3.status, "be archived");
736
+ await ensureNotMain(data_3.id);
652
737
  requireAdapterGeneration(adapterGeneration_2);
653
738
  return store.optimisticUpdate({
654
739
  execute: async () => {
655
- const { remoteId: remoteId_4 } = await data_4.initializeTask;
740
+ const { remoteId: remoteId_4 } = await data_3.initializeTask;
656
741
  requireAdapterGeneration(adapterGeneration_2);
657
742
  return currentAdapter_3.archive(remoteId_4);
658
743
  },
659
- optimistic: (state_10) => updateStatusReducer(state_10, data_4.id, "archived")
744
+ optimistic: (state_9) => updateStatusReducer(state_9, data_3.id, "archived")
660
745
  });
661
746
  }, [
662
747
  ensureNotMain,
@@ -667,21 +752,21 @@ const useRemoteThreadList = (props) => {
667
752
  const unarchive = useCallback((threadIdOrRemoteId_3) => {
668
753
  const currentAdapter_4 = session.adapter;
669
754
  const adapterGeneration_3 = session.adapterGeneration;
670
- const data_5 = getThreadData(store.value, threadIdOrRemoteId_3);
671
- if (!data_5) throw threadNotFoundError(threadIdOrRemoteId_3, "unarchiving it");
672
- if (data_5.status !== "archived") throw threadStatusError(threadIdOrRemoteId_3, data_5.status, "be unarchived");
755
+ const data_4 = getThreadData(store.value, threadIdOrRemoteId_3);
756
+ if (!data_4) throw threadNotFoundError(threadIdOrRemoteId_3, "unarchiving it");
757
+ if (data_4.status !== "archived") throw threadStatusError(threadIdOrRemoteId_3, data_4.status, "be unarchived");
673
758
  return store.optimisticUpdate({
674
759
  execute: async () => {
675
760
  try {
676
- const { remoteId: remoteId_5 } = await data_5.initializeTask;
761
+ const { remoteId: remoteId_5 } = await data_4.initializeTask;
677
762
  requireAdapterGeneration(adapterGeneration_3);
678
763
  return await currentAdapter_4.unarchive(remoteId_5);
679
- } catch (error_4) {
680
- if (adapterGeneration_3 === session.adapterGeneration) await ensureNotMain(data_5.id);
681
- throw error_4;
764
+ } catch (error_5) {
765
+ if (adapterGeneration_3 === session.adapterGeneration) await ensureNotMain(data_4.id);
766
+ throw error_5;
682
767
  }
683
768
  },
684
- optimistic: (state_11) => updateStatusReducer(state_11, data_5.id, "regular")
769
+ optimistic: (state_10) => updateStatusReducer(state_10, data_4.id, "regular")
685
770
  });
686
771
  }, [
687
772
  ensureNotMain,
@@ -692,20 +777,23 @@ const useRemoteThreadList = (props) => {
692
777
  const deleteThread = useCallback(async (threadIdOrRemoteId_4) => {
693
778
  const currentAdapter_5 = session.adapter;
694
779
  const adapterGeneration_4 = session.adapterGeneration;
695
- const data_6 = getThreadData(store.value, threadIdOrRemoteId_4);
696
- if (!data_6) throw threadNotFoundError(threadIdOrRemoteId_4, "deleting it");
697
- if (data_6.status !== "regular" && data_6.status !== "archived") throw threadStatusError(threadIdOrRemoteId_4, data_6.status, "be deleted");
698
- await ensureNotMain(data_6.id);
780
+ const data_5 = getThreadData(store.value, threadIdOrRemoteId_4);
781
+ if (!data_5) throw threadNotFoundError(threadIdOrRemoteId_4, "deleting it");
782
+ if (data_5.status !== "regular" && data_5.status !== "archived") throw threadStatusError(threadIdOrRemoteId_4, data_5.status, "be deleted");
783
+ await ensureNotMain(data_5.id);
699
784
  requireAdapterGeneration(adapterGeneration_4);
700
- onDelete?.(data_6.id);
701
- return store.optimisticUpdate({
785
+ const result_2 = await store.optimisticUpdate({
702
786
  execute: async () => {
703
- const { remoteId: remoteId_6 } = await data_6.initializeTask;
787
+ const { remoteId: remoteId_6 } = await data_5.initializeTask;
704
788
  requireAdapterGeneration(adapterGeneration_4);
705
789
  return currentAdapter_5.delete(remoteId_6);
706
790
  },
707
- optimistic: (state_12) => updateStatusReducer(state_12, data_6.id, "deleted")
791
+ optimistic: (state_11) => updateStatusReducer(state_11, data_5.id, "deleted")
708
792
  });
793
+ if (getThreadData(store.value, data_5.id) !== void 0) return result_2;
794
+ clearThreadTitleState(session.titleStates, data_5.id);
795
+ onDelete?.(data_5.id);
796
+ return result_2;
709
797
  }, [
710
798
  ensureNotMain,
711
799
  onDelete,
@@ -713,57 +801,76 @@ const useRemoteThreadList = (props) => {
713
801
  session,
714
802
  store
715
803
  ]);
716
- const generateTitle = useCallback(async (threadIdOrRemoteId_5, messages) => {
804
+ const generateTitle = useCallback(async (threadIdOrRemoteId_5, messages, options_0) => {
717
805
  const currentAdapter_6 = session.adapter;
718
806
  const adapterGeneration_5 = session.adapterGeneration;
719
- const data_7 = getThreadData(store.value, threadIdOrRemoteId_5);
720
- if (!data_7) throw threadNotFoundError(threadIdOrRemoteId_5, "generating its title");
721
- if (data_7.status === "new") throw threadStatusError(threadIdOrRemoteId_5, data_7.status, "generate a title");
722
- const { remoteId: remoteId_7 } = await data_7.initializeTask;
807
+ const data_6 = getThreadData(store.value, threadIdOrRemoteId_5);
808
+ if (!data_6) throw threadNotFoundError(threadIdOrRemoteId_5, "generating its title");
809
+ if (data_6.status === "new") throw threadStatusError(threadIdOrRemoteId_5, data_6.status, "generate a title");
810
+ const { remoteId: remoteId_7 } = await data_6.initializeTask;
723
811
  requireAdapterGeneration(adapterGeneration_5);
724
- if (!isSameThread(store.value, data_7.id, session.mainThreadId)) return;
812
+ if (!backgroundThreads && !isSameThread(store.value, data_6.id, session.mainThreadId)) return;
725
813
  if (!messages) return;
726
- const stream = await currentAdapter_6.generateTitle(remoteId_7, messages);
727
- requireAdapterGeneration(adapterGeneration_5);
728
- await applyTitleStream(stream, async (newTitle_0) => {
729
- await store.optimisticUpdate({
730
- execute: async () => {},
731
- optimistic: (state_13) => {
732
- if (adapterGeneration_5 !== session.adapterGeneration) return state_13;
733
- const current_2 = getThreadData(state_13, data_7.id);
734
- if (!current_2) return state_13;
735
- return {
736
- ...state_13,
737
- threadData: {
738
- ...state_13.threadData,
739
- [current_2.id]: {
740
- ...current_2,
741
- title: newTitle_0
814
+ await runThreadTitleGeneration({
815
+ states: session.titleStates,
816
+ threadId: data_6.id,
817
+ automatic: options_0?.automatic === true,
818
+ generate: async (onTitle) => {
819
+ const stream = await currentAdapter_6.generateTitle(remoteId_7, messages);
820
+ requireAdapterGeneration(adapterGeneration_5);
821
+ await applyTitleStream(stream, onTitle);
822
+ },
823
+ rename: async (title) => {
824
+ requireAdapterGeneration(adapterGeneration_5);
825
+ await currentAdapter_6.rename(remoteId_7, title);
826
+ },
827
+ applyTitle: async (title_0) => {
828
+ await store.optimisticUpdate({
829
+ execute: async () => {},
830
+ optimistic: (state_12) => {
831
+ if (adapterGeneration_5 !== session.adapterGeneration) return state_12;
832
+ const current_2 = getThreadData(state_12, data_6.id);
833
+ if (!current_2) return state_12;
834
+ return {
835
+ ...state_12,
836
+ threadData: {
837
+ ...state_12.threadData,
838
+ [current_2.id]: {
839
+ ...current_2,
840
+ title: title_0
841
+ }
742
842
  }
743
- }
744
- };
745
- }
746
- });
843
+ };
844
+ }
845
+ });
846
+ }
747
847
  });
748
848
  }, [
849
+ backgroundThreads,
749
850
  requireAdapterGeneration,
750
851
  session,
751
852
  store
752
853
  ]);
854
+ const detach = useCallback(async (threadId_2) => {
855
+ await ensureNotMain(threadId_2);
856
+ setStartedIds((prev_1) => prev_1.filter((id_2) => id_2 !== threadId_2));
857
+ }, [ensureNotMain]);
753
858
  const { mainThreadClient, itemOrder, threadListItems } = useRemoteThreadListView({
754
859
  listState,
755
860
  mainThreadId,
861
+ startedIds,
862
+ backgroundThreads,
756
863
  threadFactory,
757
864
  useAdapters: adapter.unstable_useAdapters,
758
- onSwitchTo: (id_2, options_0) => switchToThread(id_2, options_0),
759
- onRename: (id_3, title) => rename(id_3, title),
760
- onUpdateCustom: (id_4, custom_0) => updateCustom(id_4, custom_0),
761
- onArchive: (id_5) => archive(id_5),
762
- onUnarchive: (id_6) => unarchive(id_6),
763
- onDelete: (id_7) => deleteThread(id_7),
764
- onGenerateTitle: (id_8, messages_0) => generateTitle(id_8, messages_0),
765
- onInitialize: async (id_9) => toInitializeResult(await initialize(id_9)),
766
- onDetach: (id_10) => ensureNotMain(id_10)
865
+ onSwitchTo: (id_3, options_1) => switchToThread(id_3, options_1),
866
+ onRename: (id_4, title_1) => rename(id_4, title_1),
867
+ onUpdateCustom: (id_5, custom_0) => updateCustom(id_5, custom_0),
868
+ onArchive: (id_6) => archive(id_6),
869
+ onUnarchive: (id_7) => unarchive(id_7),
870
+ onDelete: (id_8) => deleteThread(id_8),
871
+ onGenerateTitle: (id_9, messages_0, options_2) => generateTitle(id_9, messages_0, options_2),
872
+ onInitialize: async (id_10) => toInitializeResult(await initialize(id_10)),
873
+ onDetach: (id_11) => detach(id_11)
767
874
  });
768
875
  const mainRemoteId = getThreadData(listState, mainThreadId)?.remoteId;
769
876
  useEffect(() => {
@@ -796,10 +903,11 @@ const useRemoteThreadList = (props) => {
796
903
  switchToThread,
797
904
  threadId
798
905
  ]);
799
- const state_14 = useMemo(() => ({
906
+ const state_13 = useMemo(() => ({
800
907
  mainThreadId,
801
908
  newThreadId: listState.newThreadId ?? null,
802
909
  isLoading: listState.isLoading,
910
+ loadError: listState.loadError,
803
911
  isLoadingMore: listState.isLoadingMore,
804
912
  hasMore: listState.cursor !== void 0,
805
913
  threadIds: listState.threadIds,
@@ -810,6 +918,7 @@ const useRemoteThreadList = (props) => {
810
918
  listState.archivedThreadIds,
811
919
  listState.cursor,
812
920
  listState.isLoading,
921
+ listState.loadError,
813
922
  listState.isLoadingMore,
814
923
  listState.newThreadId,
815
924
  listState.threadIds,
@@ -818,9 +927,9 @@ const useRemoteThreadList = (props) => {
818
927
  threadListItems.state
819
928
  ]);
820
929
  return {
821
- getState: () => state_14,
822
- switchToThread: (id_11, options_1) => {
823
- handleThreadListAction("switch", () => switchToThread(id_11, options_1));
930
+ getState: () => state_13,
931
+ switchToThread: (id_12, options_3) => {
932
+ handleThreadListAction("switch", () => switchToThread(id_12, options_3));
824
933
  },
825
934
  switchToNewThread: () => {
826
935
  handleThreadListAction("create", () => switchToNewThread());
@@ -841,9 +950,9 @@ const useRemoteThreadList = (props) => {
841
950
  const index_0 = itemOrder.findIndex((item_0) => itemMatchesId(item_0, listState, selector.id));
842
951
  return threadListItems.get({ index: index_0 });
843
952
  }
844
- const id_12 = (selector.archived ? listState.archivedThreadIds : listState.threadIds)[selector.index];
845
- if (id_12 === void 0) return threadListItems.get({ index: -1 });
846
- const index_1 = itemOrder.findIndex((item_1) => itemMatchesId(item_1, listState, id_12));
953
+ const id_13 = (selector.archived ? listState.archivedThreadIds : listState.threadIds)[selector.index];
954
+ if (id_13 === void 0) return threadListItems.get({ index: -1 });
955
+ const index_1 = itemOrder.findIndex((item_1) => itemMatchesId(item_1, listState, id_13));
847
956
  return threadListItems.get({ index: index_1 });
848
957
  },
849
958
  thread: () => mainThreadClient.methods
@@ -856,6 +965,9 @@ const useRemoteThreadList = (props) => {
856
965
  * and attachments come from `unstable_useAdapters`. `useRemoteThreadListRuntime`
857
966
  * uses the same hook when `unstable_Provider` is omitted. Key the factory
858
967
  * with `withKey` so history reloads when the visible thread changes.
968
+ * With `backgroundThreads`, every visited thread stays mounted: runs continue
969
+ * across switches, per-item `isRunning` is live, and freshly initialized
970
+ * threads title themselves.
859
971
  */
860
972
  const RemoteThreadList = resource(useRemoteThreadList);
861
973
  attachTransformScopes(useRemoteThreadList, inMemoryThreadListTransformScopes);