@assistant-ui/core 0.3.13 → 0.3.14

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 (396) hide show
  1. package/dist/adapters/speech.d.ts.map +1 -1
  2. package/dist/adapters/speech.js +9 -15
  3. package/dist/adapters/speech.js.map +1 -1
  4. package/dist/adapters/thread-history.d.ts +2 -0
  5. package/dist/adapters/thread-history.d.ts.map +1 -1
  6. package/dist/adapters/voice.d.ts.map +1 -1
  7. package/dist/adapters/voice.js +27 -15
  8. package/dist/adapters/voice.js.map +1 -1
  9. package/dist/index.d.ts +2 -2
  10. package/dist/index.js.map +1 -1
  11. package/dist/internal.d.ts +1 -1
  12. package/dist/internal.js +6 -6
  13. package/dist/model-context/frame/host.d.ts.map +1 -1
  14. package/dist/model-context/frame/host.js +2 -1
  15. package/dist/model-context/frame/host.js.map +1 -1
  16. package/dist/model-context/registry.d.ts.map +1 -1
  17. package/dist/model-context/registry.js +16 -4
  18. package/dist/model-context/registry.js.map +1 -1
  19. package/dist/react/RuntimeAdapter.d.ts +8 -1
  20. package/dist/react/RuntimeAdapter.d.ts.map +1 -1
  21. package/dist/react/RuntimeAdapter.js +23 -18
  22. package/dist/react/RuntimeAdapter.js.map +1 -1
  23. package/dist/react/adapters/LocalStorageThreadListAdapter.d.ts.map +1 -1
  24. package/dist/react/adapters/LocalStorageThreadListAdapter.js +28 -12
  25. package/dist/react/adapters/LocalStorageThreadListAdapter.js.map +1 -1
  26. package/dist/react/client/AdaptedRemoteThread.d.ts +11 -0
  27. package/dist/react/client/AdaptedRemoteThread.d.ts.map +1 -0
  28. package/dist/react/client/AdaptedRemoteThread.js +27 -0
  29. package/dist/react/client/AdaptedRemoteThread.js.map +1 -0
  30. package/dist/react/client/InMemoryThreadList.d.ts +19 -0
  31. package/dist/react/client/InMemoryThreadList.d.ts.map +1 -0
  32. package/dist/react/client/InMemoryThreadList.js +418 -0
  33. package/dist/react/client/InMemoryThreadList.js.map +1 -0
  34. package/dist/react/client/Interactables.d.ts.map +1 -1
  35. package/dist/react/client/Interactables.js +159 -102
  36. package/dist/react/client/Interactables.js.map +1 -1
  37. package/dist/react/client/RemoteThreadList.d.ts +34 -0
  38. package/dist/react/client/RemoteThreadList.d.ts.map +1 -0
  39. package/dist/react/client/RemoteThreadList.js +826 -0
  40. package/dist/react/client/RemoteThreadList.js.map +1 -0
  41. package/dist/react/client/Tools.d.ts.map +1 -1
  42. package/dist/react/client/Tools.js +38 -27
  43. package/dist/react/client/Tools.js.map +1 -1
  44. package/dist/react/index.d.ts +7 -2
  45. package/dist/react/index.js +5 -2
  46. package/dist/react/interactables-legacy/Interactables.d.ts.map +1 -1
  47. package/dist/react/interactables-legacy/Interactables.js +145 -110
  48. package/dist/react/interactables-legacy/Interactables.js.map +1 -1
  49. package/dist/react/primitive-hooks/useActionBarCopy.d.ts.map +1 -1
  50. package/dist/react/primitive-hooks/useActionBarCopy.js +13 -18
  51. package/dist/react/primitive-hooks/useActionBarCopy.js.map +1 -1
  52. package/dist/react/primitive-hooks/useActionBarEdit.d.ts.map +1 -1
  53. package/dist/react/primitive-hooks/useActionBarEdit.js +2 -4
  54. package/dist/react/primitive-hooks/useActionBarEdit.js.map +1 -1
  55. package/dist/react/primitive-hooks/useActionBarReload.d.ts.map +1 -1
  56. package/dist/react/primitive-hooks/useActionBarReload.js +2 -4
  57. package/dist/react/primitive-hooks/useActionBarReload.js.map +1 -1
  58. package/dist/react/primitive-hooks/useBranchPickerNext.d.ts.map +1 -1
  59. package/dist/react/primitive-hooks/useBranchPickerNext.js +2 -6
  60. package/dist/react/primitive-hooks/useBranchPickerNext.js.map +1 -1
  61. package/dist/react/primitive-hooks/useBranchPickerPrevious.d.ts.map +1 -1
  62. package/dist/react/primitive-hooks/useBranchPickerPrevious.js +2 -6
  63. package/dist/react/primitive-hooks/useBranchPickerPrevious.js.map +1 -1
  64. package/dist/react/primitive-hooks/useComposerCancel.d.ts.map +1 -1
  65. package/dist/react/primitive-hooks/useComposerCancel.js +2 -4
  66. package/dist/react/primitive-hooks/useComposerCancel.js.map +1 -1
  67. package/dist/react/primitive-hooks/useComposerSend.d.ts.map +1 -1
  68. package/dist/react/primitive-hooks/useComposerSend.js +2 -4
  69. package/dist/react/primitive-hooks/useComposerSend.js.map +1 -1
  70. package/dist/react/primitive-hooks/useSuggestionTrigger.d.ts.map +1 -1
  71. package/dist/react/primitive-hooks/useSuggestionTrigger.js +6 -2
  72. package/dist/react/primitive-hooks/useSuggestionTrigger.js.map +1 -1
  73. package/dist/react/primitives/message/MessageParts.d.ts +13 -0
  74. package/dist/react/primitives/message/MessageParts.d.ts.map +1 -1
  75. package/dist/react/primitives/message/MessageParts.js.map +1 -1
  76. package/dist/react/primitives/thread/ThreadMessages.d.ts.map +1 -1
  77. package/dist/react/primitives/thread/ThreadMessages.js +1 -1
  78. package/dist/react/primitives/thread/ThreadMessages.js.map +1 -1
  79. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts +22 -10
  80. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts.map +1 -1
  81. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js +109 -71
  82. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js.map +1 -1
  83. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts +8 -2
  84. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
  85. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js +40 -13
  86. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js.map +1 -1
  87. package/dist/react/runtimes/RemoteThreadResource.d.ts +30 -0
  88. package/dist/react/runtimes/RemoteThreadResource.d.ts.map +1 -0
  89. package/dist/react/runtimes/RemoteThreadResource.js +134 -0
  90. package/dist/react/runtimes/RemoteThreadResource.js.map +1 -0
  91. package/dist/react/runtimes/RuntimeAdapterProvider.d.ts +3 -10
  92. package/dist/react/runtimes/RuntimeAdapterProvider.d.ts.map +1 -1
  93. package/dist/react/runtimes/RuntimeAdapterProvider.js +3 -6
  94. package/dist/react/runtimes/RuntimeAdapterProvider.js.map +1 -1
  95. package/dist/react/runtimes/assistant-transport/commandQueue.d.ts +17 -0
  96. package/dist/react/runtimes/assistant-transport/commandQueue.d.ts.map +1 -0
  97. package/dist/react/runtimes/assistant-transport/commandQueue.js +55 -0
  98. package/dist/react/runtimes/assistant-transport/commandQueue.js.map +1 -0
  99. package/dist/react/runtimes/assistant-transport/replayBoundaryStream.d.ts +11 -0
  100. package/dist/react/runtimes/assistant-transport/replayBoundaryStream.d.ts.map +1 -0
  101. package/dist/react/runtimes/assistant-transport/replayBoundaryStream.js +165 -0
  102. package/dist/react/runtimes/assistant-transport/replayBoundaryStream.js.map +1 -0
  103. package/dist/react/runtimes/assistant-transport/runManager.d.ts +15 -0
  104. package/dist/react/runtimes/assistant-transport/runManager.d.ts.map +1 -0
  105. package/dist/react/runtimes/assistant-transport/runManager.js +86 -0
  106. package/dist/react/runtimes/assistant-transport/runManager.js.map +1 -0
  107. package/dist/react/runtimes/assistant-transport/types.d.ts +130 -0
  108. package/dist/react/runtimes/assistant-transport/types.d.ts.map +1 -0
  109. package/dist/react/runtimes/assistant-transport/types.js +0 -0
  110. package/dist/react/runtimes/assistant-transport/useAssistantTransportRuntime.d.ts +14 -0
  111. package/dist/react/runtimes/assistant-transport/useAssistantTransportRuntime.d.ts.map +1 -0
  112. package/dist/react/runtimes/assistant-transport/useAssistantTransportRuntime.js +296 -0
  113. package/dist/react/runtimes/assistant-transport/useAssistantTransportRuntime.js.map +1 -0
  114. package/dist/react/runtimes/assistant-transport/useConvertedState.d.ts +7 -0
  115. package/dist/react/runtimes/assistant-transport/useConvertedState.d.ts.map +1 -0
  116. package/dist/react/runtimes/assistant-transport/useConvertedState.js +25 -0
  117. package/dist/react/runtimes/assistant-transport/useConvertedState.js.map +1 -0
  118. package/dist/react/runtimes/assistant-transport/useLatestRef.d.ts +7 -0
  119. package/dist/react/runtimes/assistant-transport/useLatestRef.d.ts.map +1 -0
  120. package/dist/react/runtimes/assistant-transport/useLatestRef.js +27 -0
  121. package/dist/react/runtimes/assistant-transport/useLatestRef.js.map +1 -0
  122. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts.map +1 -1
  123. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js +39 -13
  124. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js.map +1 -1
  125. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.d.ts +2 -1
  126. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.d.ts.map +1 -1
  127. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.js +3 -3
  128. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.js.map +1 -1
  129. package/dist/react/runtimes/cloud/auiV0.d.ts +4 -0
  130. package/dist/react/runtimes/cloud/auiV0.d.ts.map +1 -1
  131. package/dist/react/runtimes/cloud/auiV0.js +7 -0
  132. package/dist/react/runtimes/cloud/auiV0.js.map +1 -1
  133. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.d.ts.map +1 -1
  134. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js +22 -12
  135. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js.map +1 -1
  136. package/dist/react/runtimes/cloud/useCloudThreadListRuntime.d.ts +16 -0
  137. package/dist/react/runtimes/cloud/useCloudThreadListRuntime.d.ts.map +1 -0
  138. package/dist/react/runtimes/cloud/useCloudThreadListRuntime.js +36 -0
  139. package/dist/react/runtimes/cloud/useCloudThreadListRuntime.js.map +1 -0
  140. package/dist/react/runtimes/external-message-converter.js +14 -14
  141. package/dist/react/runtimes/external-message-converter.js.map +1 -1
  142. package/dist/react/runtimes/useExternalStoreRuntime.d.ts.map +1 -1
  143. package/dist/react/runtimes/useExternalStoreRuntime.js +44 -28
  144. package/dist/react/runtimes/useExternalStoreRuntime.js.map +1 -1
  145. package/dist/react/runtimes/useExternalStoreSharedOptions.js.map +1 -1
  146. package/dist/react/runtimes/useLocalRuntime.js +1 -1
  147. package/dist/react/runtimes/useRuntimeAdapters.d.ts +9 -0
  148. package/dist/react/runtimes/useRuntimeAdapters.d.ts.map +1 -0
  149. package/dist/react/runtimes/useRuntimeAdapters.js +20 -0
  150. package/dist/react/runtimes/useRuntimeAdapters.js.map +1 -0
  151. package/dist/runtime/api/composer-runtime.d.ts +5 -0
  152. package/dist/runtime/api/composer-runtime.d.ts.map +1 -1
  153. package/dist/runtime/api/composer-runtime.js.map +1 -1
  154. package/dist/runtime/api/message-runtime.js +1 -1
  155. package/dist/runtime/api/thread-list-runtime.d.ts +1 -0
  156. package/dist/runtime/api/thread-list-runtime.d.ts.map +1 -1
  157. package/dist/runtime/api/thread-list-runtime.js +4 -2
  158. package/dist/runtime/api/thread-list-runtime.js.map +1 -1
  159. package/dist/runtime/api/thread-runtime.d.ts +12 -2
  160. package/dist/runtime/api/thread-runtime.d.ts.map +1 -1
  161. package/dist/runtime/api/thread-runtime.js +8 -2
  162. package/dist/runtime/api/thread-runtime.js.map +1 -1
  163. package/dist/runtime/base/base-composer-runtime-core.d.ts.map +1 -1
  164. package/dist/runtime/base/base-composer-runtime-core.js +8 -7
  165. package/dist/runtime/base/base-composer-runtime-core.js.map +1 -1
  166. package/dist/runtime/base/base-thread-runtime-core.d.ts +1 -0
  167. package/dist/runtime/base/base-thread-runtime-core.d.ts.map +1 -1
  168. package/dist/runtime/base/base-thread-runtime-core.js +3 -3
  169. package/dist/runtime/base/base-thread-runtime-core.js.map +1 -1
  170. package/dist/runtime/base/default-thread-composer-runtime-core.d.ts +0 -1
  171. package/dist/runtime/base/default-thread-composer-runtime-core.d.ts.map +1 -1
  172. package/dist/runtime/base/default-thread-composer-runtime-core.js +10 -4
  173. package/dist/runtime/base/default-thread-composer-runtime-core.js.map +1 -1
  174. package/dist/runtime/interfaces/thread-runtime-core.d.ts +6 -0
  175. package/dist/runtime/interfaces/thread-runtime-core.d.ts.map +1 -1
  176. package/dist/runtime/internal.js +5 -5
  177. package/dist/runtime/queue/message-queue.d.ts.map +1 -1
  178. package/dist/runtime/queue/message-queue.js +2 -1
  179. package/dist/runtime/queue/message-queue.js.map +1 -1
  180. package/dist/runtime/utils/thread-runtime-lifecycle.d.ts +8 -0
  181. package/dist/runtime/utils/thread-runtime-lifecycle.d.ts.map +1 -0
  182. package/dist/runtime/utils/thread-runtime-lifecycle.js +11 -0
  183. package/dist/runtime/utils/thread-runtime-lifecycle.js.map +1 -0
  184. package/dist/runtimes/external-store/external-store-shared-options.js.map +1 -1
  185. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.d.ts.map +1 -1
  186. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js +4 -1
  187. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js.map +1 -1
  188. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts +8 -0
  189. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts.map +1 -1
  190. package/dist/runtimes/external-store/external-store-thread-runtime-core.js +35 -13
  191. package/dist/runtimes/external-store/external-store-thread-runtime-core.js.map +1 -1
  192. package/dist/runtimes/internal.d.ts +1 -1
  193. package/dist/runtimes/local/local-thread-runtime-core.d.ts +3 -0
  194. package/dist/runtimes/local/local-thread-runtime-core.d.ts.map +1 -1
  195. package/dist/runtimes/local/local-thread-runtime-core.js +53 -13
  196. package/dist/runtimes/local/local-thread-runtime-core.js.map +1 -1
  197. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.d.ts +1 -0
  198. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.d.ts.map +1 -1
  199. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.js +3 -0
  200. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.js.map +1 -1
  201. package/dist/runtimes/remote-thread-list/empty-thread-core.js +3 -0
  202. package/dist/runtimes/remote-thread-list/empty-thread-core.js.map +1 -1
  203. package/dist/runtimes/remote-thread-list/types.d.ts +29 -1
  204. package/dist/runtimes/remote-thread-list/types.d.ts.map +1 -1
  205. package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts +1 -12
  206. package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts.map +1 -1
  207. package/dist/runtimes/tool-invocations/ToolInvocationTracker.js +67 -38
  208. package/dist/runtimes/tool-invocations/ToolInvocationTracker.js.map +1 -1
  209. package/dist/store/clients/suggestions.js +2 -2
  210. package/dist/store/clients/suggestions.js.map +1 -1
  211. package/dist/store/clients/thread-selection-events.d.ts +10 -0
  212. package/dist/store/clients/thread-selection-events.d.ts.map +1 -0
  213. package/dist/store/clients/thread-selection-events.js +40 -0
  214. package/dist/store/clients/thread-selection-events.js.map +1 -0
  215. package/dist/store/env.d.ts +5 -0
  216. package/dist/store/env.d.ts.map +1 -0
  217. package/dist/store/env.js +12 -0
  218. package/dist/store/env.js.map +1 -0
  219. package/dist/store/index.d.ts +5 -3
  220. package/dist/store/index.js +4 -2
  221. package/dist/store/internal.d.ts +4 -1
  222. package/dist/store/internal.js +4 -1
  223. package/dist/store/primitive-predicates.d.ts +19 -0
  224. package/dist/store/primitive-predicates.d.ts.map +1 -0
  225. package/dist/store/primitive-predicates.js +19 -0
  226. package/dist/store/primitive-predicates.js.map +1 -0
  227. package/dist/store/runtime-clients/attachment-runtime-client.d.ts.map +1 -1
  228. package/dist/store/runtime-clients/attachment-runtime-client.js +18 -11
  229. package/dist/store/runtime-clients/attachment-runtime-client.js.map +1 -1
  230. package/dist/store/runtime-clients/handle-runtime-action.d.ts +5 -0
  231. package/dist/store/runtime-clients/handle-runtime-action.d.ts.map +1 -0
  232. package/dist/store/runtime-clients/handle-runtime-action.js +12 -0
  233. package/dist/store/runtime-clients/handle-runtime-action.js.map +1 -0
  234. package/dist/store/runtime-clients/handle-thread-list-action.d.ts +5 -0
  235. package/dist/store/runtime-clients/handle-thread-list-action.d.ts.map +1 -0
  236. package/dist/store/runtime-clients/handle-thread-list-action.js +7 -0
  237. package/dist/store/runtime-clients/handle-thread-list-action.js.map +1 -0
  238. package/dist/store/runtime-clients/thread-list-item-runtime-client.d.ts.map +1 -1
  239. package/dist/store/runtime-clients/thread-list-item-runtime-client.js +62 -29
  240. package/dist/store/runtime-clients/thread-list-item-runtime-client.js.map +1 -1
  241. package/dist/store/runtime-clients/thread-list-runtime-client.d.ts.map +1 -1
  242. package/dist/store/runtime-clients/thread-list-runtime-client.js +5 -6
  243. package/dist/store/runtime-clients/thread-list-runtime-client.js.map +1 -1
  244. package/dist/store/scopes/composer.d.ts +9 -4
  245. package/dist/store/scopes/composer.d.ts.map +1 -1
  246. package/dist/store/scopes/thread-list-item.d.ts +7 -6
  247. package/dist/store/scopes/thread-list-item.d.ts.map +1 -1
  248. package/dist/store/scopes/thread.d.ts +8 -7
  249. package/dist/store/scopes/thread.d.ts.map +1 -1
  250. package/dist/store/scopes/threads.d.ts +17 -1
  251. package/dist/store/scopes/threads.d.ts.map +1 -1
  252. package/dist/subscribable/subscribable.d.ts +2 -1
  253. package/dist/subscribable/subscribable.d.ts.map +1 -1
  254. package/dist/subscribable/subscribable.js +23 -18
  255. package/dist/subscribable/subscribable.js.map +1 -1
  256. package/dist/utils/composite-context-provider.d.ts +1 -0
  257. package/dist/utils/composite-context-provider.d.ts.map +1 -1
  258. package/dist/utils/composite-context-provider.js +25 -9
  259. package/dist/utils/composite-context-provider.js.map +1 -1
  260. package/dist/utils/notify-event-listeners.d.ts +2 -2
  261. package/dist/utils/notify-event-listeners.d.ts.map +1 -1
  262. package/dist/utils/notify-event-listeners.js +2 -2
  263. package/dist/utils/notify-event-listeners.js.map +1 -1
  264. package/package.json +7 -7
  265. package/src/adapters/speech.test.ts +118 -1
  266. package/src/adapters/speech.ts +21 -22
  267. package/src/adapters/thread-history.ts +2 -0
  268. package/src/adapters/voice.test.ts +69 -0
  269. package/src/adapters/voice.ts +27 -27
  270. package/src/index.ts +1 -0
  271. package/src/model-context/frame/host.test.ts +23 -0
  272. package/src/model-context/frame/host.ts +2 -1
  273. package/src/model-context/registry.test.ts +131 -0
  274. package/src/model-context/registry.ts +16 -6
  275. package/src/react/RuntimeAdapter.test.ts +2 -0
  276. package/src/react/RuntimeAdapter.ts +20 -8
  277. package/src/react/adapters/LocalStorageThreadListAdapter.tsx +34 -17
  278. package/src/react/client/AdaptedRemoteThread.ts +41 -0
  279. package/src/react/client/InMemoryThreadList.test.tsx +148 -0
  280. package/src/react/client/InMemoryThreadList.ts +290 -0
  281. package/src/react/client/Interactables.test.ts +326 -2
  282. package/src/react/client/Interactables.ts +227 -110
  283. package/src/react/client/RemoteThreadList.test.ts +1026 -0
  284. package/src/react/client/RemoteThreadList.ts +1067 -0
  285. package/src/react/client/Tools.ts +36 -29
  286. package/src/react/index.ts +13 -0
  287. package/src/react/interactables-legacy/Interactables.test.ts +317 -0
  288. package/src/react/interactables-legacy/Interactables.ts +204 -128
  289. package/src/react/primitive-hooks/useActionBarCopy.ts +2 -7
  290. package/src/react/primitive-hooks/useActionBarEdit.ts +2 -1
  291. package/src/react/primitive-hooks/useActionBarReload.ts +2 -6
  292. package/src/react/primitive-hooks/useBranchPickerNext.ts +2 -7
  293. package/src/react/primitive-hooks/useBranchPickerPrevious.ts +2 -7
  294. package/src/react/primitive-hooks/useComposerCancel.ts +2 -1
  295. package/src/react/primitive-hooks/useComposerSend.ts +2 -5
  296. package/src/react/primitive-hooks/useSuggestionTrigger.test.ts +11 -0
  297. package/src/react/primitive-hooks/useSuggestionTrigger.ts +4 -5
  298. package/src/react/primitives/message/MessageParts.tsx +0 -1
  299. package/src/react/primitives/thread/ThreadMessages.tsx +2 -1
  300. package/src/react/runtimes/RemoteThreadListHookInstanceManager.retry.test.tsx +116 -0
  301. package/src/react/runtimes/RemoteThreadListHookInstanceManager.running.test.tsx +1 -1
  302. package/src/react/runtimes/RemoteThreadListHookInstanceManager.test.tsx +57 -6
  303. package/src/react/runtimes/RemoteThreadListHookInstanceManager.title.test.tsx +272 -0
  304. package/src/react/runtimes/RemoteThreadListHookInstanceManager.tsx +159 -124
  305. package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.tsx +59 -20
  306. package/src/react/runtimes/RemoteThreadResource.test.ts +141 -0
  307. package/src/react/runtimes/RemoteThreadResource.ts +231 -0
  308. package/src/react/runtimes/RuntimeAdapterProvider.tsx +8 -20
  309. package/src/react/runtimes/assistant-transport/commandQueue.ts +68 -0
  310. package/src/react/runtimes/assistant-transport/replayBoundaryStream.test.ts +455 -0
  311. package/src/react/runtimes/assistant-transport/replayBoundaryStream.ts +172 -0
  312. package/src/react/runtimes/assistant-transport/runManager.ts +124 -0
  313. package/src/react/runtimes/assistant-transport/transport-delivery.test.tsx +79 -0
  314. package/src/react/runtimes/assistant-transport/transport-parentid.test.tsx +97 -0
  315. package/src/react/runtimes/assistant-transport/transport-scheduling.test.ts +414 -0
  316. package/src/react/runtimes/assistant-transport/types.ts +170 -0
  317. package/src/react/runtimes/assistant-transport/useAssistantTransport.spec.md +141 -0
  318. package/src/react/runtimes/assistant-transport/useAssistantTransportRuntime.test.tsx +625 -0
  319. package/src/react/runtimes/assistant-transport/useAssistantTransportRuntime.ts +481 -0
  320. package/src/react/runtimes/assistant-transport/useConvertedState.ts +20 -0
  321. package/src/react/runtimes/assistant-transport/useLatestRef.ts +9 -0
  322. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.test.tsx +131 -6
  323. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.ts +61 -15
  324. package/src/react/runtimes/cloud/CloudFileAttachmentAdapter.ts +6 -4
  325. package/src/react/runtimes/cloud/auiV0.ts +17 -1
  326. package/src/react/runtimes/cloud/useCloudThreadListAdapter.tsx +36 -21
  327. package/src/react/runtimes/cloud/useCloudThreadListRuntime.test.tsx +56 -0
  328. package/src/react/runtimes/cloud/useCloudThreadListRuntime.ts +31 -0
  329. package/src/react/runtimes/external-message-converter.test.ts +143 -0
  330. package/src/react/runtimes/external-message-converter.ts +41 -41
  331. package/src/react/runtimes/remote-thread-hook-on-tap.test.ts +58 -0
  332. package/src/react/runtimes/useExternalStoreRuntime.lifecycle.test.tsx +83 -0
  333. package/src/react/runtimes/useExternalStoreRuntime.suggestions.test.tsx +13 -3
  334. package/src/react/runtimes/useExternalStoreRuntime.ts +7 -0
  335. package/src/react/runtimes/useExternalStoreSharedOptions.ts +3 -1
  336. package/src/react/runtimes/useLocalRuntime.test.tsx +130 -4
  337. package/src/react/runtimes/useRuntimeAdapters.test.tsx +62 -0
  338. package/src/react/runtimes/useRuntimeAdapters.ts +28 -0
  339. package/src/runtime/api/composer-runtime.ts +5 -0
  340. package/src/runtime/api/thread-list-runtime.ts +3 -1
  341. package/src/runtime/api/thread-runtime.ts +20 -2
  342. package/src/runtime/base/base-composer-runtime-core.ts +6 -5
  343. package/src/runtime/base/base-thread-runtime-core.test.ts +191 -0
  344. package/src/runtime/base/base-thread-runtime-core.ts +11 -2
  345. package/src/runtime/base/default-thread-composer-runtime-core.ts +12 -4
  346. package/src/runtime/interfaces/thread-runtime-core.ts +6 -0
  347. package/src/runtime/queue/message-queue.ts +2 -1
  348. package/src/runtime/utils/thread-runtime-lifecycle.ts +18 -0
  349. package/src/runtimes/external-store/external-store-shared-options.ts +3 -1
  350. package/src/runtimes/external-store/external-store-thread-list-runtime-core.ts +4 -1
  351. package/src/runtimes/external-store/external-store-thread-runtime-core.ts +99 -34
  352. package/src/runtimes/local/local-thread-runtime-core.test.ts +373 -4
  353. package/src/runtimes/local/local-thread-runtime-core.ts +79 -14
  354. package/src/runtimes/readonly/ReadonlyThreadRuntimeCore.ts +4 -0
  355. package/src/runtimes/remote-thread-list/empty-thread-core.ts +4 -0
  356. package/src/runtimes/remote-thread-list/types.ts +30 -0
  357. package/src/runtimes/tool-invocations/EDGE_CASES.md +17 -6
  358. package/src/runtimes/tool-invocations/ToolInvocationTracker.test.ts +243 -0
  359. package/src/runtimes/tool-invocations/ToolInvocationTracker.ts +127 -61
  360. package/src/store/clients/model-context-client.test.ts +16 -8
  361. package/src/store/clients/suggestions.ts +2 -2
  362. package/src/store/clients/thread-selection-events.ts +21 -0
  363. package/src/store/env.ts +11 -0
  364. package/src/store/index.ts +14 -1
  365. package/src/store/internal.ts +13 -0
  366. package/src/store/primitive-predicates.test.ts +184 -0
  367. package/src/store/primitive-predicates.ts +43 -0
  368. package/src/store/runtime-clients/attachment-runtime-client.test.ts +41 -0
  369. package/src/store/runtime-clients/attachment-runtime-client.ts +2 -1
  370. package/src/store/runtime-clients/handle-runtime-action.ts +11 -0
  371. package/src/store/runtime-clients/handle-thread-list-action.test.ts +69 -0
  372. package/src/store/runtime-clients/handle-thread-list-action.ts +6 -0
  373. package/src/store/runtime-clients/thread-list-item-runtime-client.ts +15 -7
  374. package/src/store/runtime-clients/thread-list-runtime-client.ts +9 -6
  375. package/src/store/scopes/composer.ts +9 -4
  376. package/src/store/scopes/thread-list-item.ts +7 -6
  377. package/src/store/scopes/thread.ts +8 -7
  378. package/src/store/scopes/threads.ts +14 -0
  379. package/src/subscribable/subscribable.test.ts +77 -1
  380. package/src/subscribable/subscribable.ts +38 -23
  381. package/src/tests/RemoteThreadListThreadListRuntimeCore-switchToThread-unarchive.test.ts +25 -0
  382. package/src/tests/auiV0Encode.test.ts +66 -0
  383. package/src/tests/base-composer-runtime-core-send.test.ts +30 -0
  384. package/src/tests/base-composer-runtime-core.test.ts +28 -0
  385. package/src/tests/composer-can-cancel.test.ts +101 -0
  386. package/src/tests/external-store-thread-list-runtime-core.test.ts +101 -0
  387. package/src/tests/external-store-thread-runtime-core-adapter.test.ts +191 -1
  388. package/src/tests/external-store-thread-runtime-core.test.ts +124 -0
  389. package/src/tests/interactables-toolui-migration.test.tsx +66 -0
  390. package/src/tests/message-queue.test.ts +28 -0
  391. package/src/tests/session-reset-notification.test.ts +145 -0
  392. package/src/tests/thread-switch-events.test.tsx +99 -1
  393. package/src/tests/tools-scope-migration.test.tsx +58 -0
  394. package/src/utils/composite-context-provider.test.ts +139 -0
  395. package/src/utils/composite-context-provider.ts +26 -8
  396. package/src/utils/notify-event-listeners.ts +10 -5
@@ -1,10 +1,11 @@
1
1
  import { findModelKnownState, interactableToolName } from "../../model-context/interactable-composer-metadata.js";
2
+ import { notifySubscribers } from "../../subscribable/subscribable.js";
2
3
  import { ModelContext } from "../../store/clients/model-context-client.js";
3
4
  import { buildInteractableModelContext } from "./interactable-model-context.js";
4
5
  import { toJSONSchema, toPartialJSONSchema } from "assistant-stream";
5
6
  import { useCallback, useEffect, useMemo, useRef, useState } from "@assistant-ui/tap/react-shim";
6
7
  import { resource } from "@assistant-ui/tap";
7
- import { attachTransformScopes, useAssistantClientRef } from "@assistant-ui/store/client";
8
+ import { attachTransformScopes, useAssistantClientRef, useAssistantScopeEffect } from "@assistant-ui/store/client";
8
9
  //#region src/react/client/Interactables.ts
9
10
  const PERSISTENCE_DEBOUNCE_MS = 500;
10
11
  const hasInteractableCreateCall = (messages, id, name) => messages.some((message) => message.role === "assistant" && message.content?.some((part) => {
@@ -31,9 +32,12 @@ const useInteractablesResource = ({ persistence } = {}) => {
31
32
  const adapterRef = useRef(void 0);
32
33
  const debounceTimerRef = useRef(void 0);
33
34
  const syncSeqRef = useRef(0);
34
- const hasPendingLocalChangeRef = useRef(false);
35
+ const latestSyncSeqByIdRef = useRef(/* @__PURE__ */ new Map());
36
+ const inFlightPersistenceRef = useRef(0);
35
37
  const flushResolversRef = useRef([]);
36
38
  const dirtyIdsRef = useRef(/* @__PURE__ */ new Set());
39
+ const outgoingQueueRef = useRef([]);
40
+ const runPersistenceRef = useRef(() => {});
37
41
  const setStateAndRef = useCallback((updater) => {
38
42
  const next = updater(stateRef.current);
39
43
  stateRef.current = next;
@@ -50,93 +54,135 @@ const useInteractablesResource = ({ persistence } = {}) => {
50
54
  }
51
55
  return result;
52
56
  }, []);
53
- const runPersistence = useCallback(async () => {
54
- const adapter = adapterRef.current;
55
- if (!adapter) {
56
- for (const resolve of flushResolversRef.current) resolve();
57
- flushResolversRef.current = [];
58
- return;
59
- }
60
- const seq = ++syncSeqRef.current;
57
+ const takeDirtyBatch = useCallback((adapter) => {
58
+ if (dirtyIdsRef.current.size === 0) return;
61
59
  const dirtyIds = new Set(dirtyIdsRef.current);
62
60
  dirtyIdsRef.current.clear();
63
- hasPendingLocalChangeRef.current = true;
64
- const payload = exportState();
61
+ const seq = ++syncSeqRef.current;
62
+ for (const id_0 of dirtyIds) latestSyncSeqByIdRef.current.set(id_0, seq);
63
+ return {
64
+ adapter,
65
+ payload: exportState(),
66
+ dirtyIds,
67
+ seq
68
+ };
69
+ }, [exportState]);
70
+ const enqueuePersistence = useCallback((adapter_0) => {
71
+ const batch = takeDirtyBatch(adapter_0);
72
+ if (!batch) return;
73
+ if (inFlightPersistenceRef.current === 0) runPersistenceRef.current(batch);
74
+ else outgoingQueueRef.current.push(batch);
75
+ }, [takeDirtyBatch]);
76
+ const runPersistence = useCallback(async (batch_0) => {
77
+ const resolved = batch_0 ?? (adapterRef.current ? takeDirtyBatch(adapterRef.current) : void 0);
78
+ if (!resolved) {
79
+ if (inFlightPersistenceRef.current === 0) {
80
+ for (const resolve of flushResolversRef.current) resolve();
81
+ flushResolversRef.current = [];
82
+ }
83
+ return;
84
+ }
85
+ const { adapter: adapter_1, payload, dirtyIds: dirtyIds_0, seq: seq_0 } = resolved;
86
+ inFlightPersistenceRef.current += 1;
65
87
  setStateAndRef((prev) => ({
66
88
  ...prev,
67
89
  persistence: {
68
90
  ...prev.persistence,
69
- ...Object.fromEntries([...dirtyIds].map((id_0) => [id_0, {
91
+ ...Object.fromEntries([...dirtyIds_0].map((id_1) => [id_1, {
70
92
  isPending: true,
71
93
  error: void 0
72
94
  }]))
73
95
  }
74
96
  }));
75
97
  try {
76
- await adapter.save(payload);
77
- if (syncSeqRef.current === seq) {
78
- hasPendingLocalChangeRef.current = false;
79
- setStateAndRef((prev_1) => {
80
- const persistence_0 = { ...prev_1.persistence };
81
- for (const id_2 of dirtyIds) delete persistence_0[id_2];
82
- return {
83
- ...prev_1,
84
- persistence: persistence_0
85
- };
86
- });
87
- }
98
+ await adapter_1.save(payload);
99
+ setStateAndRef((prev_1) => {
100
+ let changed_0 = false;
101
+ const persistence_1 = { ...prev_1.persistence };
102
+ for (const id_3 of dirtyIds_0) {
103
+ if (latestSyncSeqByIdRef.current.get(id_3) !== seq_0 || dirtyIdsRef.current.has(id_3)) continue;
104
+ latestSyncSeqByIdRef.current.delete(id_3);
105
+ delete persistence_1[id_3];
106
+ changed_0 = true;
107
+ }
108
+ return changed_0 ? {
109
+ ...prev_1,
110
+ persistence: persistence_1
111
+ } : prev_1;
112
+ });
88
113
  } catch (e) {
89
- if (syncSeqRef.current === seq) {
90
- hasPendingLocalChangeRef.current = false;
91
- setStateAndRef((prev_0) => ({
114
+ setStateAndRef((prev_0) => {
115
+ let changed = false;
116
+ const persistence_0 = { ...prev_0.persistence };
117
+ for (const id_2 of dirtyIds_0) {
118
+ if (latestSyncSeqByIdRef.current.get(id_2) !== seq_0 || dirtyIdsRef.current.has(id_2)) continue;
119
+ latestSyncSeqByIdRef.current.delete(id_2);
120
+ persistence_0[id_2] = {
121
+ isPending: false,
122
+ error: e
123
+ };
124
+ changed = true;
125
+ }
126
+ return changed ? {
92
127
  ...prev_0,
93
- persistence: {
94
- ...prev_0.persistence,
95
- ...Object.fromEntries([...dirtyIds].map((id_1) => [id_1, {
96
- isPending: false,
97
- error: e
98
- }]))
99
- }
100
- }));
101
- }
128
+ persistence: persistence_0
129
+ } : prev_0;
130
+ });
102
131
  } finally {
103
- if (dirtyIdsRef.current.size > 0 && adapterRef.current) runPersistence();
104
- else {
132
+ inFlightPersistenceRef.current -= 1;
133
+ const next = outgoingQueueRef.current.shift() ?? (adapterRef.current && dirtyIdsRef.current.size > 0 ? takeDirtyBatch(adapterRef.current) : void 0);
134
+ if (next) {
135
+ if (debounceTimerRef.current !== void 0) {
136
+ clearTimeout(debounceTimerRef.current);
137
+ debounceTimerRef.current = void 0;
138
+ }
139
+ runPersistenceRef.current(next);
140
+ } else if (inFlightPersistenceRef.current === 0) {
105
141
  for (const resolve of flushResolversRef.current) resolve();
106
142
  flushResolversRef.current = [];
107
143
  }
108
144
  }
109
- }, [exportState, setStateAndRef]);
110
- const schedulePersistence = useCallback((id_3) => {
145
+ }, [setStateAndRef, takeDirtyBatch]);
146
+ runPersistenceRef.current = (nextBatch) => {
147
+ runPersistence(nextBatch);
148
+ };
149
+ const flushIfPending = useCallback(() => {
150
+ if (debounceTimerRef.current !== void 0) {
151
+ clearTimeout(debounceTimerRef.current);
152
+ debounceTimerRef.current = void 0;
153
+ }
154
+ if (adapterRef.current) enqueuePersistence(adapterRef.current);
155
+ }, [enqueuePersistence]);
156
+ const schedulePersistence = useCallback((id_4) => {
111
157
  if (!adapterRef.current) return;
112
- dirtyIdsRef.current.add(id_3);
158
+ dirtyIdsRef.current.add(id_4);
113
159
  if (debounceTimerRef.current !== void 0) clearTimeout(debounceTimerRef.current);
114
160
  debounceTimerRef.current = setTimeout(() => {
115
161
  debounceTimerRef.current = void 0;
116
- if (!hasPendingLocalChangeRef.current) runPersistence();
162
+ if (inFlightPersistenceRef.current === 0 && adapterRef.current) enqueuePersistence(adapterRef.current);
117
163
  else debounceTimerRef.current = setTimeout(() => {
118
164
  debounceTimerRef.current = void 0;
119
- runPersistence();
165
+ if (adapterRef.current) enqueuePersistence(adapterRef.current);
120
166
  }, PERSISTENCE_DEBOUNCE_MS);
121
167
  }, PERSISTENCE_DEBOUNCE_MS);
122
- }, [runPersistence]);
168
+ }, [enqueuePersistence]);
123
169
  const restorePersistedState = useCallback((saved, options) => {
124
170
  const shouldStash = options.shouldStash ?? (() => true);
125
171
  const shouldApply = options.shouldApply ?? (() => true);
126
- for (const [id_4, entry] of Object.entries(saved)) if (shouldStash(id_4)) options.stash.set(id_4, entry.state);
172
+ for (const [id_5, entry] of Object.entries(saved)) if (shouldStash(id_5)) options.stash.set(id_5, entry.state);
127
173
  setStateAndRef((prev_2) => {
128
- let changed = false;
174
+ let changed_1 = false;
129
175
  const definitions = { ...prev_2.definitions };
130
- for (const [id_5, entry_0] of Object.entries(saved)) {
131
- const def_0 = definitions[id_5];
132
- if (!def_0 || !shouldApply(id_5, def_0)) continue;
133
- definitions[id_5] = {
176
+ for (const [id_6, entry_0] of Object.entries(saved)) {
177
+ const def_0 = definitions[id_6];
178
+ if (!def_0 || !shouldApply(id_6, def_0)) continue;
179
+ definitions[id_6] = {
134
180
  ...def_0,
135
181
  state: entry_0.state
136
182
  };
137
- changed = true;
183
+ changed_1 = true;
138
184
  }
139
- if (!changed) return prev_2;
185
+ if (!changed_1) return prev_2;
140
186
  return {
141
187
  ...prev_2,
142
188
  definitions
@@ -149,24 +195,25 @@ const useInteractablesResource = ({ persistence } = {}) => {
149
195
  const applyLoadedState = useCallback((saved_1) => {
150
196
  restorePersistedState(saved_1, {
151
197
  stash: loadedStateRef.current,
152
- shouldStash: (id_6) => !touchedIdsRef.current.has(id_6),
153
- shouldApply: (id_7, def_1) => !touchedIdsRef.current.has(id_7) && def_1.scope !== "thread"
198
+ shouldStash: (id_7) => !touchedIdsRef.current.has(id_7),
199
+ shouldApply: (id_8, def_1) => !touchedIdsRef.current.has(id_8) && def_1.scope !== "thread"
154
200
  });
155
201
  }, [restorePersistedState]);
156
- const loadFromAdapter = useCallback(async (adapter_0) => {
157
- if (!adapter_0.load) return;
202
+ const loadFromAdapter = useCallback(async (adapter_2) => {
203
+ if (!adapter_2.load) return;
158
204
  try {
159
- const saved_2 = await adapter_0.load();
160
- if (!saved_2 || adapterRef.current !== adapter_0) return;
205
+ const saved_2 = await adapter_2.load();
206
+ if (!saved_2 || adapterRef.current !== adapter_2) return;
161
207
  applyLoadedState(saved_2);
162
208
  } catch (e_0) {
163
209
  console.warn("[Interactables] Persistence load failed.", e_0);
164
210
  }
165
211
  }, [applyLoadedState]);
166
- const setPersistenceAdapter = useCallback((adapter_1) => {
167
- adapterRef.current = adapter_1;
168
- if (adapter_1) loadFromAdapter(adapter_1);
169
- }, [loadFromAdapter]);
212
+ const setPersistenceAdapter = useCallback((adapter_3) => {
213
+ if (adapterRef.current !== adapter_3) flushIfPending();
214
+ adapterRef.current = adapter_3;
215
+ if (adapter_3) loadFromAdapter(adapter_3);
216
+ }, [flushIfPending, loadFromAdapter]);
170
217
  const getCurrentThreadId = useCallback(() => {
171
218
  const client = clientRef.current;
172
219
  if (!client) return void 0;
@@ -179,7 +226,7 @@ const useInteractablesResource = ({ persistence } = {}) => {
179
226
  if (!persistence) return;
180
227
  setPersistenceAdapter(persistence);
181
228
  return () => {
182
- if (adapterRef.current === persistence) adapterRef.current = void 0;
229
+ if (adapterRef.current === persistence) setPersistenceAdapter(void 0);
183
230
  };
184
231
  }, [persistence, setPersistenceAdapter]);
185
232
  const flush = useCallback(async () => {
@@ -187,38 +234,30 @@ const useInteractablesResource = ({ persistence } = {}) => {
187
234
  clearTimeout(debounceTimerRef.current);
188
235
  debounceTimerRef.current = void 0;
189
236
  }
190
- if (!adapterRef.current) return;
191
- if (!hasPendingLocalChangeRef.current && dirtyIdsRef.current.size === 0) return;
237
+ if (!(inFlightPersistenceRef.current > 0 || dirtyIdsRef.current.size > 0 || outgoingQueueRef.current.length > 0)) return;
192
238
  const p = new Promise((resolve_0) => {
193
239
  flushResolversRef.current.push(resolve_0);
194
240
  });
195
- if (!hasPendingLocalChangeRef.current) runPersistence();
241
+ if (adapterRef.current) enqueuePersistence(adapterRef.current);
196
242
  return p;
197
- }, [runPersistence]);
198
- const flushIfPending = useCallback(() => {
199
- if (adapterRef.current && debounceTimerRef.current !== void 0) {
200
- clearTimeout(debounceTimerRef.current);
201
- debounceTimerRef.current = void 0;
202
- runPersistence();
203
- }
204
- }, [runPersistence]);
205
- const setDefState = useCallback((id_8, updater_0) => {
206
- touchedIdsRef.current.add(id_8);
243
+ }, [enqueuePersistence]);
244
+ const setDefState = useCallback((id_9, updater_0) => {
245
+ touchedIdsRef.current.add(id_9);
207
246
  setStateAndRef((prev_3) => {
208
- const existing = prev_3.definitions[id_8];
247
+ const existing = prev_3.definitions[id_9];
209
248
  if (!existing) return prev_3;
210
249
  return {
211
250
  ...prev_3,
212
251
  definitions: {
213
252
  ...prev_3.definitions,
214
- [id_8]: {
253
+ [id_9]: {
215
254
  ...existing,
216
255
  state: updater_0(existing.state)
217
256
  }
218
257
  }
219
258
  };
220
259
  });
221
- if (stateRef.current.definitions[id_8]?.scope !== "thread") schedulePersistence(id_8);
260
+ if (stateRef.current.definitions[id_9]?.scope !== "thread") schedulePersistence(id_9);
222
261
  }, [schedulePersistence, setStateAndRef]);
223
262
  const provider = useMemo(() => ({
224
263
  getModelContext: () => {
@@ -233,11 +272,28 @@ const useInteractablesResource = ({ persistence } = {}) => {
233
272
  }
234
273
  }), [setDefState]);
235
274
  useEffect(() => {
236
- for (const cb of subscribersRef.current) cb();
275
+ notifySubscribers(subscribersRef.current);
237
276
  }, [state]);
238
- useEffect(() => {
239
- return clientRef.current.modelContext().register(provider);
240
- }, [clientRef, provider]);
277
+ useAssistantScopeEffect("modelContext", () => clientRef.current.modelContext().register(provider), [provider]);
278
+ const installUpdateToolUI = useCallback((name, entry_1) => {
279
+ const toolsAccessor = clientRef.current?.tools;
280
+ if (!toolsAccessor || toolsAccessor.source == null) return false;
281
+ entry_1.unsubscribe = toolsAccessor().setToolUI(interactableToolName(name), entry_1.render, { standalone: true });
282
+ return true;
283
+ }, [clientRef]);
284
+ useAssistantScopeEffect("tools", () => {
285
+ for (const [name_0, entry_2] of updateToolUIsRef.current) {
286
+ entry_2.unsubscribe?.();
287
+ entry_2.unsubscribe = void 0;
288
+ installUpdateToolUI(name_0, entry_2);
289
+ }
290
+ return () => {
291
+ for (const entry_3 of updateToolUIsRef.current.values()) {
292
+ entry_3.unsubscribe?.();
293
+ entry_3.unsubscribe = void 0;
294
+ }
295
+ };
296
+ }, [installUpdateToolUI]);
241
297
  return {
242
298
  getState: () => stateRef.current,
243
299
  register: useCallback((def_2) => {
@@ -248,24 +304,24 @@ const useInteractablesResource = ({ persistence } = {}) => {
248
304
  registrationCountsRef.current.set(def_2.id, (registrationCountsRef.current.get(def_2.id) ?? 0) + 1);
249
305
  let releaseUpdateToolUI;
250
306
  if (def_2.updateRender) {
251
- const toolsAccessor = clientRef.current?.tools;
252
- if (toolsAccessor && toolsAccessor.source != null) {
253
- const toolName = interactableToolName(def_2.name);
254
- const existing_0 = updateToolUIsRef.current.get(def_2.name);
255
- if (existing_0) existing_0.count++;
256
- else updateToolUIsRef.current.set(def_2.name, {
257
- count: 1,
258
- unsubscribe: toolsAccessor().setToolUI(toolName, def_2.updateRender, { standalone: true })
259
- });
260
- releaseUpdateToolUI = () => {
261
- const entry_1 = updateToolUIsRef.current.get(def_2.name);
262
- if (!entry_1) return;
263
- if (--entry_1.count === 0) {
264
- updateToolUIsRef.current.delete(def_2.name);
265
- entry_1.unsubscribe();
266
- }
267
- };
268
- } else if (process.env.NODE_ENV !== "production") console.warn(`[Interactables] "${def_2.name}" supplied an updateRender, but no tools scope is available to install it into.`);
307
+ const existing_0 = updateToolUIsRef.current.get(def_2.name);
308
+ const entry_4 = existing_0 ?? {
309
+ count: 0,
310
+ render: def_2.updateRender,
311
+ unsubscribe: void 0
312
+ };
313
+ entry_4.count++;
314
+ if (!existing_0) updateToolUIsRef.current.set(def_2.name, entry_4);
315
+ if (!entry_4.unsubscribe && !installUpdateToolUI(def_2.name, entry_4) && process.env.NODE_ENV !== "production") console.warn(`[Interactables] "${def_2.name}" supplied an updateRender, but no tools scope is available yet; it will be installed once one appears.`);
316
+ releaseUpdateToolUI = () => {
317
+ const entry_5 = updateToolUIsRef.current.get(def_2.name);
318
+ if (!entry_5) return;
319
+ if (--entry_5.count === 0) {
320
+ updateToolUIsRef.current.delete(def_2.name);
321
+ entry_5.unsubscribe?.();
322
+ entry_5.unsubscribe = void 0;
323
+ }
324
+ };
269
325
  }
270
326
  if (!partialSchemaCacheRef.current.has(def_2.id)) try {
271
327
  const jsonSchema = toJSONSchema(def_2.stateSchema);
@@ -333,6 +389,7 @@ const useInteractablesResource = ({ persistence } = {}) => {
333
389
  flushIfPending,
334
390
  clientRef,
335
391
  getCurrentThreadId,
392
+ installUpdateToolUI,
336
393
  setStateAndRef
337
394
  ]),
338
395
  setState: setDefState,
@@ -1 +1 @@
1
- {"version":3,"file":"Interactables.js","names":["useState","useEffect","useCallback","useRef","useMemo","resource","ClientOutput","attachTransformScopes","useAssistantClientRef","Unstable_InteractablesState","Unstable_InteractableRegistration","Unstable_InteractablePersistedState","Unstable_InteractablePersistenceAdapter","Unstable_InteractablesConfig","toJSONSchema","toPartialJSONSchema","ModelContext","buildInteractableModelContext","PartialJSONSchema","findModelKnownState","interactableToolName","PERSISTENCE_DEBOUNCE_MS","RestorePersistedStateOptions","stash","Map","shouldStash","id","shouldApply","def","ToolCallLikePart","type","toolCallId","toolName","MessageLike","role","content","InternalInteractableRegistration","scope","hasInteractableCreateCall","messages","name","some","message","part","p","useInteractablesResource","persistence","state","setState","definitions","clientRef","stateRef","subscribersRef","Set","partialSchemaCacheRef","streamBaselinesRef","targetId","detachedAppStateRef","detachedThreadStateRef","registrationCountsRef","updateToolUIsRef","count","unsubscribe","loadedStateRef","touchedIdsRef","adapterRef","undefined","debounceTimerRef","ReturnType","setTimeout","syncSeqRef","hasPendingLocalChangeRef","flushResolversRef","Array","dirtyIdsRef","setStateAndRef","updater","prev","next","current","exportState","result","Object","entries","runPersistence","adapter","resolve","seq","dirtyIds","clear","payload","fromEntries","map","isPending","error","save","e","size","schedulePersistence","add","clearTimeout","restorePersistedState","saved","options","entry","set","changed","importState","applyLoadedState","has","loadFromAdapter","load","console","warn","setPersistenceAdapter","getCurrentThreadId","client","threadListItem","source","getState","threads","mainThreadId","flush","Promise","push","flushIfPending","setDefState","existing","provider","getModelContext","defs","subscribe","callback","delete","cb","modelContext","register","threadAccessor","thread","threadMessages","process","env","NODE_ENV","get","releaseUpdateToolUI","updateRender","toolsAccessor","tools","setToolUI","standalone","jsonSchema","stateSchema","threadId","detached","loaded","known","description","initialState","remaining","stateById","_","rest","__","restPersistence","unstable_Interactables","scopes","parent"],"sources":["../../../src/react/client/Interactables.ts"],"sourcesContent":["import { useState, useEffect, useCallback, useRef, useMemo } from \"react\";\nimport { resource } from \"@assistant-ui/tap\";\nimport type { ClientOutput } from \"@assistant-ui/store\";\nimport {\n attachTransformScopes,\n useAssistantClientRef,\n} from \"@assistant-ui/store/client\";\nimport type {\n Unstable_InteractablesState,\n Unstable_InteractableRegistration,\n Unstable_InteractablePersistedState,\n Unstable_InteractablePersistenceAdapter,\n Unstable_InteractablesConfig,\n} from \"../types/scopes/interactables\";\nimport { toJSONSchema, toPartialJSONSchema } from \"assistant-stream\";\nimport { ModelContext } from \"../../store/clients/model-context-client\";\nimport {\n buildInteractableModelContext,\n type PartialJSONSchema,\n} from \"./interactable-model-context\";\nimport {\n findModelKnownState,\n interactableToolName,\n} from \"../../model-context/interactable-composer-metadata\";\n\nconst PERSISTENCE_DEBOUNCE_MS = 500;\n\ntype RestorePersistedStateOptions = {\n stash: Map<string, unknown>;\n shouldStash?: (id: string) => boolean;\n shouldApply?: (\n id: string,\n def: Unstable_InteractablesState[\"definitions\"][string],\n ) => boolean;\n};\n\ntype ToolCallLikePart = {\n type?: string;\n toolCallId?: string;\n toolName?: string;\n};\n\ntype MessageLike = {\n role?: string;\n content?: readonly unknown[] | undefined;\n};\n\ntype InternalInteractableRegistration = Unstable_InteractableRegistration & {\n scope?: \"thread\" | undefined;\n};\n\nconst hasInteractableCreateCall = (\n messages: readonly MessageLike[],\n id: string,\n name: string,\n) =>\n messages.some(\n (message) =>\n message.role === \"assistant\" &&\n message.content?.some((part) => {\n if (!part || typeof part !== \"object\") return false;\n const p = part as ToolCallLikePart;\n return (\n p.type === \"tool-call\" && p.toolCallId === id && p.toolName === name\n );\n }),\n );\n\nconst useInteractablesResource = ({\n persistence,\n}: Unstable_InteractablesConfig = {}): ClientOutput<\"unstable_interactables\"> => {\n const [state, setState] = useState<Unstable_InteractablesState>(() => ({\n definitions: {},\n persistence: {},\n }));\n\n const clientRef = useAssistantClientRef();\n\n const stateRef = useRef(state);\n\n const subscribersRef = useRef(new Set<() => void>());\n const partialSchemaCacheRef = useRef(new Map<string, PartialJSONSchema>());\n const streamBaselinesRef = useRef(\n new Map<string, { targetId: string; state: unknown }>(),\n );\n const detachedAppStateRef = useRef(new Map<string, unknown>());\n const detachedThreadStateRef = useRef(\n new Map<string, Map<string, unknown>>(),\n );\n // An instance may be registered from several anchors (its creating tool\n // call plus update_* calls); the definition lives until the last one leaves.\n const registrationCountsRef = useRef(new Map<string, number>());\n // One update-tool UI per interactable name, alive while any registrant\n // that supplied an updateRender is mounted.\n const updateToolUIsRef = useRef(\n new Map<string, { count: number; unsubscribe: () => void }>(),\n );\n // App-scoped state restored via adapter.load(), consumed as components register.\n const loadedStateRef = useRef(new Map<string, unknown>());\n // Ids edited locally this session — a local edit always wins over a slow load.\n const touchedIdsRef = useRef(new Set<string>());\n\n const adapterRef = useRef<\n Unstable_InteractablePersistenceAdapter | undefined\n >(undefined);\n const debounceTimerRef = useRef<ReturnType<typeof setTimeout> | undefined>(\n undefined,\n );\n const syncSeqRef = useRef(0);\n const hasPendingLocalChangeRef = useRef(false);\n const flushResolversRef = useRef<Array<() => void>>([]);\n const dirtyIdsRef = useRef(new Set<string>());\n\n const setStateAndRef = useCallback(\n (\n updater: (\n prev: Unstable_InteractablesState,\n ) => Unstable_InteractablesState,\n ) => {\n const next = updater(stateRef.current);\n stateRef.current = next;\n setState(next);\n },\n [],\n );\n\n const exportState = useCallback((): Unstable_InteractablePersistedState => {\n const result: Unstable_InteractablePersistedState = {};\n for (const [id, def] of Object.entries(stateRef.current.definitions)) {\n if (def.scope === \"thread\") continue; // thread items persist via snapshot, not the adapter\n result[id] = { name: def.name, state: def.state };\n }\n return result;\n }, []);\n\n const runPersistence = useCallback(async () => {\n const adapter = adapterRef.current;\n if (!adapter) {\n for (const resolve of flushResolversRef.current) resolve();\n flushResolversRef.current = [];\n return;\n }\n\n const seq = ++syncSeqRef.current;\n const dirtyIds = new Set(dirtyIdsRef.current);\n dirtyIdsRef.current.clear();\n hasPendingLocalChangeRef.current = true;\n\n // Snapshot before any await so unregistered definitions are still included.\n const payload = exportState();\n\n setStateAndRef((prev) => ({\n ...prev,\n persistence: {\n ...prev.persistence,\n ...Object.fromEntries(\n [...dirtyIds].map((id) => [\n id,\n { isPending: true, error: undefined },\n ]),\n ),\n },\n }));\n\n try {\n await adapter.save(payload);\n if (syncSeqRef.current === seq) {\n hasPendingLocalChangeRef.current = false;\n setStateAndRef((prev) => {\n const persistence = { ...prev.persistence };\n for (const id of dirtyIds) delete persistence[id];\n return { ...prev, persistence };\n });\n }\n } catch (e) {\n if (syncSeqRef.current === seq) {\n hasPendingLocalChangeRef.current = false;\n setStateAndRef((prev) => ({\n ...prev,\n persistence: {\n ...prev.persistence,\n ...Object.fromEntries(\n [...dirtyIds].map((id) => [id, { isPending: false, error: e }]),\n ),\n },\n }));\n }\n } finally {\n if (dirtyIdsRef.current.size > 0 && adapterRef.current) {\n runPersistence();\n } else {\n for (const resolve of flushResolversRef.current) resolve();\n flushResolversRef.current = [];\n }\n }\n }, [exportState, setStateAndRef]);\n\n const schedulePersistence = useCallback(\n (id: string) => {\n if (!adapterRef.current) return;\n dirtyIdsRef.current.add(id);\n if (debounceTimerRef.current !== undefined) {\n clearTimeout(debounceTimerRef.current);\n }\n debounceTimerRef.current = setTimeout(() => {\n debounceTimerRef.current = undefined;\n if (!hasPendingLocalChangeRef.current) {\n runPersistence();\n } else {\n debounceTimerRef.current = setTimeout(() => {\n debounceTimerRef.current = undefined;\n runPersistence();\n }, PERSISTENCE_DEBOUNCE_MS);\n }\n }, PERSISTENCE_DEBOUNCE_MS);\n },\n [runPersistence],\n );\n\n const restorePersistedState = useCallback(\n (\n saved: Unstable_InteractablePersistedState,\n options: RestorePersistedStateOptions,\n ) => {\n const shouldStash = options.shouldStash ?? (() => true);\n const shouldApply = options.shouldApply ?? (() => true);\n\n for (const [id, entry] of Object.entries(saved)) {\n if (shouldStash(id)) options.stash.set(id, entry.state);\n }\n setStateAndRef((prev) => {\n let changed = false;\n const definitions = { ...prev.definitions };\n for (const [id, entry] of Object.entries(saved)) {\n const def = definitions[id];\n if (!def || !shouldApply(id, def)) continue;\n definitions[id] = { ...def, state: entry.state };\n changed = true;\n }\n if (!changed) return prev;\n return { ...prev, definitions };\n });\n },\n [setStateAndRef],\n );\n\n const importState = useCallback(\n (saved: Unstable_InteractablePersistedState) => {\n restorePersistedState(saved, { stash: detachedAppStateRef.current });\n },\n [restorePersistedState],\n );\n\n // Applies adapter.load() output: a local edit made while the load was in\n // flight wins, and thread-scoped items never restore from the adapter.\n const applyLoadedState = useCallback(\n (saved: Unstable_InteractablePersistedState) => {\n restorePersistedState(saved, {\n stash: loadedStateRef.current,\n shouldStash: (id) => !touchedIdsRef.current.has(id),\n shouldApply: (id, def) =>\n !touchedIdsRef.current.has(id) && def.scope !== \"thread\",\n });\n },\n [restorePersistedState],\n );\n\n const loadFromAdapter = useCallback(\n async (adapter: Unstable_InteractablePersistenceAdapter) => {\n if (!adapter.load) return;\n try {\n const saved = await adapter.load();\n if (!saved || adapterRef.current !== adapter) return;\n applyLoadedState(saved);\n } catch (e) {\n console.warn(\"[Interactables] Persistence load failed.\", e);\n }\n },\n [applyLoadedState],\n );\n\n const setPersistenceAdapter = useCallback(\n (adapter: Unstable_InteractablePersistenceAdapter | undefined) => {\n adapterRef.current = adapter;\n if (adapter) void loadFromAdapter(adapter);\n },\n [loadFromAdapter],\n );\n\n const getCurrentThreadId = useCallback((): string | undefined => {\n const client = clientRef.current;\n if (!client) return undefined;\n\n const threadListItem = client.threadListItem;\n if (threadListItem.source != null) {\n return threadListItem().getState().id;\n }\n\n const threads = client.threads;\n if (threads.source != null) {\n return threads().getState().mainThreadId;\n }\n\n return undefined;\n }, [clientRef]);\n\n useEffect(() => {\n if (!persistence) return;\n setPersistenceAdapter(persistence);\n return () => {\n if (adapterRef.current === persistence) {\n adapterRef.current = undefined;\n }\n };\n }, [persistence, setPersistenceAdapter]);\n\n const flush = useCallback(async () => {\n if (debounceTimerRef.current !== undefined) {\n clearTimeout(debounceTimerRef.current);\n debounceTimerRef.current = undefined;\n }\n if (!adapterRef.current) return;\n if (!hasPendingLocalChangeRef.current && dirtyIdsRef.current.size === 0)\n return;\n const p = new Promise<void>((resolve) => {\n flushResolversRef.current.push(resolve);\n });\n if (!hasPendingLocalChangeRef.current) {\n runPersistence();\n }\n return p;\n }, [runPersistence]);\n\n const flushIfPending = useCallback(() => {\n if (adapterRef.current && debounceTimerRef.current !== undefined) {\n clearTimeout(debounceTimerRef.current);\n debounceTimerRef.current = undefined;\n runPersistence();\n }\n }, [runPersistence]);\n\n const setDefState = useCallback(\n (id: string, updater: (prev: unknown) => unknown) => {\n touchedIdsRef.current.add(id);\n setStateAndRef((prev) => {\n const existing = prev.definitions[id];\n if (!existing) return prev;\n return {\n ...prev,\n definitions: {\n ...prev.definitions,\n [id]: { ...existing, state: updater(existing.state) },\n },\n };\n });\n if (stateRef.current.definitions[id]?.scope !== \"thread\") {\n schedulePersistence(id);\n }\n },\n [schedulePersistence, setStateAndRef],\n );\n\n const provider = useMemo(\n () => ({\n getModelContext: () => {\n const defs = stateRef.current.definitions;\n return (\n buildInteractableModelContext(\n defs,\n partialSchemaCacheRef.current,\n setDefState,\n streamBaselinesRef.current,\n ) ?? {}\n );\n },\n subscribe: (callback: () => void) => {\n subscribersRef.current.add(callback);\n return () => {\n subscribersRef.current.delete(callback);\n };\n },\n }),\n [setDefState],\n );\n\n useEffect(() => {\n for (const cb of subscribersRef.current) cb();\n }, [state]);\n\n useEffect(() => {\n return clientRef.current!.modelContext().register(provider);\n }, [clientRef, provider]);\n\n const register = useCallback(\n (def: InternalInteractableRegistration) => {\n const threadAccessor = clientRef.current?.thread;\n const threadMessages =\n threadAccessor && threadAccessor.source != null\n ? (threadAccessor().getState().messages ?? [])\n : [];\n const scope =\n def.scope ??\n (hasInteractableCreateCall(threadMessages, def.id, def.name)\n ? \"thread\"\n : \"app\");\n\n if (\n process.env.NODE_ENV !== \"production\" &&\n stateRef.current.definitions[def.id] &&\n scope !== \"thread\"\n ) {\n console.warn(\n `[Interactables] \"${def.name}\" (${def.id}) is already registered. ` +\n `Register an app-scoped interactable once (unstable_useInteractable) and ` +\n `read it from other components with unstable_useInteractableState.`,\n );\n }\n\n registrationCountsRef.current.set(\n def.id,\n (registrationCountsRef.current.get(def.id) ?? 0) + 1,\n );\n\n let releaseUpdateToolUI: (() => void) | undefined;\n if (def.updateRender) {\n const toolsAccessor = clientRef.current?.tools;\n if (toolsAccessor && toolsAccessor.source != null) {\n const toolName = interactableToolName(def.name);\n const existing = updateToolUIsRef.current.get(def.name);\n if (existing) {\n existing.count++;\n } else {\n updateToolUIsRef.current.set(def.name, {\n count: 1,\n unsubscribe: toolsAccessor().setToolUI(\n toolName,\n def.updateRender,\n { standalone: true },\n ),\n });\n }\n releaseUpdateToolUI = () => {\n const entry = updateToolUIsRef.current.get(def.name);\n if (!entry) return;\n if (--entry.count === 0) {\n updateToolUIsRef.current.delete(def.name);\n entry.unsubscribe();\n }\n };\n } else if (process.env.NODE_ENV !== \"production\") {\n console.warn(\n `[Interactables] \"${def.name}\" supplied an updateRender, but no ` +\n `tools scope is available to install it into.`,\n );\n }\n }\n\n // The same id re-registers once per anchor (its create call + each update_*).\n if (!partialSchemaCacheRef.current.has(def.id)) {\n try {\n const jsonSchema = toJSONSchema(def.stateSchema);\n partialSchemaCacheRef.current.set(\n def.id,\n toPartialJSONSchema(jsonSchema),\n );\n } catch (e) {\n console.warn(\n `[Interactables] Failed to create partial schema for \"${def.name}\". The update tool will accept arbitrary fields without validation.`,\n e,\n );\n }\n }\n\n const threadId = scope === \"thread\" ? getCurrentThreadId() : undefined;\n const detached =\n scope === \"thread\"\n ? threadId\n ? detachedThreadStateRef.current.get(threadId)?.get(def.id)\n : undefined\n : detachedAppStateRef.current.get(def.id);\n if (scope === \"thread\") {\n if (threadId)\n detachedThreadStateRef.current.get(threadId)?.delete(def.id);\n } else {\n detachedAppStateRef.current.delete(def.id);\n }\n const loaded =\n scope === \"thread\" ? undefined : loadedStateRef.current.get(def.id);\n\n // Tool-created items restore from what the model already knows in this\n // thread (the creating call's args, sent snapshots, and the model's own\n // update_* calls) on a fresh reload; detached (in-session remount) still\n // wins so an unsent edit survives a scroll/virtualization cycle.\n const known =\n scope === \"thread\"\n ? findModelKnownState(threadMessages, def.id, def.name)\n : undefined;\n\n setStateAndRef((prev) => ({\n ...prev,\n definitions: {\n ...prev.definitions,\n [def.id]: {\n id: def.id,\n name: def.name,\n description: def.description,\n stateSchema: def.stateSchema,\n initialState: def.initialState,\n scope,\n state:\n prev.definitions[def.id]?.state ??\n detached ??\n known?.state ??\n loaded ??\n def.initialState,\n },\n },\n }));\n\n return () => {\n releaseUpdateToolUI?.();\n\n const remaining = (registrationCountsRef.current.get(def.id) ?? 1) - 1;\n if (remaining > 0) {\n registrationCountsRef.current.set(def.id, remaining);\n return;\n }\n registrationCountsRef.current.delete(def.id);\n\n flushIfPending();\n setStateAndRef((prev) => {\n const existing = prev.definitions[def.id];\n if (existing) {\n if (existing.scope === \"thread\") {\n const threadId = getCurrentThreadId();\n if (threadId) {\n let stateById = detachedThreadStateRef.current.get(threadId);\n if (!stateById) {\n stateById = new Map();\n detachedThreadStateRef.current.set(threadId, stateById);\n }\n stateById.set(def.id, existing.state);\n }\n } else {\n detachedAppStateRef.current.set(def.id, existing.state);\n }\n }\n partialSchemaCacheRef.current.delete(def.id);\n const { [def.id]: _, ...rest } = prev.definitions;\n const { [def.id]: __, ...restPersistence } = prev.persistence;\n return { ...prev, definitions: rest, persistence: restPersistence };\n });\n };\n },\n [flushIfPending, clientRef, getCurrentThreadId, setStateAndRef],\n );\n\n return {\n getState: () => stateRef.current,\n register,\n setState: setDefState,\n exportState,\n importState,\n setPersistenceAdapter,\n flush,\n };\n};\n\n/**\n * Registers the unstable interactables store scope.\n *\n * @deprecated Unstable / Experimental (not actually removed).\n */\nexport const unstable_Interactables = resource(useInteractablesResource);\n\nattachTransformScopes(useInteractablesResource, (scopes, parent) => {\n if (!scopes.modelContext && parent.modelContext.source === null) {\n scopes.modelContext = ModelContext();\n }\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"Interactables.js","names":["useState","useEffect","useCallback","useRef","useMemo","resource","ClientOutput","attachTransformScopes","useAssistantClientRef","useAssistantScopeEffect","Unstable_InteractablesState","Unstable_InteractableRegistration","Unstable_InteractablePersistedState","Unstable_InteractablePersistenceAdapter","Unstable_InteractablesConfig","toJSONSchema","toPartialJSONSchema","ModelContext","buildInteractableModelContext","PartialJSONSchema","findModelKnownState","interactableToolName","notifySubscribers","notifyStateSubscribers","PERSISTENCE_DEBOUNCE_MS","RestorePersistedStateOptions","stash","Map","shouldStash","id","shouldApply","def","ToolCallLikePart","type","toolCallId","toolName","MessageLike","role","content","InternalInteractableRegistration","scope","UpdateToolUIEntry","count","render","NonNullable","unsubscribe","hasInteractableCreateCall","messages","name","some","message","part","p","useInteractablesResource","persistence","state","setState","definitions","clientRef","stateRef","subscribersRef","Set","partialSchemaCacheRef","streamBaselinesRef","targetId","detachedAppStateRef","detachedThreadStateRef","registrationCountsRef","updateToolUIsRef","loadedStateRef","touchedIdsRef","adapterRef","undefined","debounceTimerRef","ReturnType","setTimeout","syncSeqRef","latestSyncSeqByIdRef","inFlightPersistenceRef","flushResolversRef","Array","dirtyIdsRef","PersistenceBatch","adapter","payload","dirtyIds","seq","outgoingQueueRef","runPersistenceRef","batch","setStateAndRef","updater","prev","next","current","exportState","result","Object","entries","takeDirtyBatch","size","clear","set","enqueuePersistence","push","runPersistence","resolved","resolve","fromEntries","map","isPending","error","save","changed","get","has","delete","e","shift","clearTimeout","nextBatch","flushIfPending","schedulePersistence","add","restorePersistedState","saved","options","entry","importState","applyLoadedState","loadFromAdapter","load","console","warn","setPersistenceAdapter","getCurrentThreadId","client","threadListItem","source","getState","threads","mainThreadId","flush","hasWork","length","Promise","setDefState","existing","provider","getModelContext","defs","subscribe","callback","modelContext","register","installUpdateToolUI","toolsAccessor","tools","setToolUI","standalone","values","threadAccessor","thread","threadMessages","process","env","NODE_ENV","releaseUpdateToolUI","updateRender","jsonSchema","stateSchema","threadId","detached","loaded","known","description","initialState","remaining","stateById","_","rest","__","restPersistence","unstable_Interactables","scopes","parent"],"sources":["../../../src/react/client/Interactables.ts"],"sourcesContent":["import { useState, useEffect, useCallback, useRef, useMemo } from \"react\";\nimport { resource } from \"@assistant-ui/tap\";\nimport type { ClientOutput } from \"@assistant-ui/store\";\nimport {\n attachTransformScopes,\n useAssistantClientRef,\n useAssistantScopeEffect,\n} from \"@assistant-ui/store/client\";\nimport type {\n Unstable_InteractablesState,\n Unstable_InteractableRegistration,\n Unstable_InteractablePersistedState,\n Unstable_InteractablePersistenceAdapter,\n Unstable_InteractablesConfig,\n} from \"../types/scopes/interactables\";\nimport { toJSONSchema, toPartialJSONSchema } from \"assistant-stream\";\nimport { ModelContext } from \"../../store/clients/model-context-client\";\nimport {\n buildInteractableModelContext,\n type PartialJSONSchema,\n} from \"./interactable-model-context\";\nimport {\n findModelKnownState,\n interactableToolName,\n} from \"../../model-context/interactable-composer-metadata\";\nimport { notifySubscribers as notifyStateSubscribers } from \"../../subscribable/subscribable\";\n\nconst PERSISTENCE_DEBOUNCE_MS = 500;\n\ntype RestorePersistedStateOptions = {\n stash: Map<string, unknown>;\n shouldStash?: (id: string) => boolean;\n shouldApply?: (\n id: string,\n def: Unstable_InteractablesState[\"definitions\"][string],\n ) => boolean;\n};\n\ntype ToolCallLikePart = {\n type?: string;\n toolCallId?: string;\n toolName?: string;\n};\n\ntype MessageLike = {\n role?: string;\n content?: readonly unknown[] | undefined;\n};\n\ntype InternalInteractableRegistration = Unstable_InteractableRegistration & {\n scope?: \"thread\" | undefined;\n};\n\ntype UpdateToolUIEntry = {\n count: number;\n render: NonNullable<Unstable_InteractableRegistration[\"updateRender\"]>;\n unsubscribe: (() => void) | undefined;\n};\n\nconst hasInteractableCreateCall = (\n messages: readonly MessageLike[],\n id: string,\n name: string,\n) =>\n messages.some(\n (message) =>\n message.role === \"assistant\" &&\n message.content?.some((part) => {\n if (!part || typeof part !== \"object\") return false;\n const p = part as ToolCallLikePart;\n return (\n p.type === \"tool-call\" && p.toolCallId === id && p.toolName === name\n );\n }),\n );\n\nconst useInteractablesResource = ({\n persistence,\n}: Unstable_InteractablesConfig = {}): ClientOutput<\"unstable_interactables\"> => {\n const [state, setState] = useState<Unstable_InteractablesState>(() => ({\n definitions: {},\n persistence: {},\n }));\n\n const clientRef = useAssistantClientRef();\n\n const stateRef = useRef(state);\n\n const subscribersRef = useRef(new Set<() => void>());\n const partialSchemaCacheRef = useRef(new Map<string, PartialJSONSchema>());\n const streamBaselinesRef = useRef(\n new Map<string, { targetId: string; state: unknown }>(),\n );\n const detachedAppStateRef = useRef(new Map<string, unknown>());\n const detachedThreadStateRef = useRef(\n new Map<string, Map<string, unknown>>(),\n );\n // An instance may be registered from several anchors (its creating tool\n // call plus update_* calls); the definition lives until the last one leaves.\n const registrationCountsRef = useRef(new Map<string, number>());\n // One update-tool UI per interactable name, alive while any registrant\n // that supplied an updateRender is mounted.\n const updateToolUIsRef = useRef(new Map<string, UpdateToolUIEntry>());\n // App-scoped state restored via adapter.load(), consumed as components register.\n const loadedStateRef = useRef(new Map<string, unknown>());\n // Ids edited locally this session — a local edit always wins over a slow load.\n const touchedIdsRef = useRef(new Set<string>());\n\n const adapterRef = useRef<\n Unstable_InteractablePersistenceAdapter | undefined\n >(undefined);\n const debounceTimerRef = useRef<ReturnType<typeof setTimeout> | undefined>(\n undefined,\n );\n const syncSeqRef = useRef(0);\n const latestSyncSeqByIdRef = useRef(new Map<string, number>());\n const inFlightPersistenceRef = useRef(0);\n const flushResolversRef = useRef<Array<() => void>>([]);\n const dirtyIdsRef = useRef(new Set<string>());\n\n type PersistenceBatch = {\n adapter: Unstable_InteractablePersistenceAdapter;\n payload: Unstable_InteractablePersistedState;\n dirtyIds: Set<string>;\n seq: number;\n };\n\n const outgoingQueueRef = useRef<PersistenceBatch[]>([]);\n const runPersistenceRef = useRef<(batch?: PersistenceBatch) => void>(\n () => {},\n );\n\n const setStateAndRef = useCallback(\n (\n updater: (\n prev: Unstable_InteractablesState,\n ) => Unstable_InteractablesState,\n ) => {\n const next = updater(stateRef.current);\n stateRef.current = next;\n setState(next);\n },\n [],\n );\n\n const exportState = useCallback((): Unstable_InteractablePersistedState => {\n const result: Unstable_InteractablePersistedState = {};\n for (const [id, def] of Object.entries(stateRef.current.definitions)) {\n if (def.scope === \"thread\") continue; // thread items persist via snapshot, not the adapter\n result[id] = { name: def.name, state: def.state };\n }\n return result;\n }, []);\n\n const takeDirtyBatch = useCallback(\n (\n adapter: Unstable_InteractablePersistenceAdapter,\n ): PersistenceBatch | undefined => {\n if (dirtyIdsRef.current.size === 0) return;\n const dirtyIds = new Set(dirtyIdsRef.current);\n dirtyIdsRef.current.clear();\n const seq = ++syncSeqRef.current;\n for (const id of dirtyIds) latestSyncSeqByIdRef.current.set(id, seq);\n return { adapter, payload: exportState(), dirtyIds, seq };\n },\n [exportState],\n );\n\n const enqueuePersistence = useCallback(\n (adapter: Unstable_InteractablePersistenceAdapter) => {\n const batch = takeDirtyBatch(adapter);\n if (!batch) return;\n if (inFlightPersistenceRef.current === 0) {\n runPersistenceRef.current(batch);\n } else {\n outgoingQueueRef.current.push(batch);\n }\n },\n [takeDirtyBatch],\n );\n\n const runPersistence = useCallback(\n async (batch?: PersistenceBatch) => {\n const resolved =\n batch ??\n (adapterRef.current ? takeDirtyBatch(adapterRef.current) : undefined);\n if (!resolved) {\n if (inFlightPersistenceRef.current === 0) {\n for (const resolve of flushResolversRef.current) resolve();\n flushResolversRef.current = [];\n }\n return;\n }\n\n const { adapter, payload, dirtyIds, seq } = resolved;\n inFlightPersistenceRef.current += 1;\n\n setStateAndRef((prev) => ({\n ...prev,\n persistence: {\n ...prev.persistence,\n ...Object.fromEntries(\n [...dirtyIds].map((id) => [\n id,\n { isPending: true, error: undefined },\n ]),\n ),\n },\n }));\n\n try {\n await adapter.save(payload);\n setStateAndRef((prev) => {\n let changed = false;\n const persistence = { ...prev.persistence };\n for (const id of dirtyIds) {\n if (\n latestSyncSeqByIdRef.current.get(id) !== seq ||\n dirtyIdsRef.current.has(id)\n )\n continue;\n latestSyncSeqByIdRef.current.delete(id);\n delete persistence[id];\n changed = true;\n }\n return changed ? { ...prev, persistence } : prev;\n });\n } catch (e) {\n setStateAndRef((prev) => {\n let changed = false;\n const persistence = { ...prev.persistence };\n for (const id of dirtyIds) {\n if (\n latestSyncSeqByIdRef.current.get(id) !== seq ||\n dirtyIdsRef.current.has(id)\n )\n continue;\n latestSyncSeqByIdRef.current.delete(id);\n persistence[id] = { isPending: false, error: e };\n changed = true;\n }\n return changed ? { ...prev, persistence } : prev;\n });\n } finally {\n inFlightPersistenceRef.current -= 1;\n const next =\n outgoingQueueRef.current.shift() ??\n (adapterRef.current && dirtyIdsRef.current.size > 0\n ? takeDirtyBatch(adapterRef.current)\n : undefined);\n if (next) {\n if (debounceTimerRef.current !== undefined) {\n clearTimeout(debounceTimerRef.current);\n debounceTimerRef.current = undefined;\n }\n runPersistenceRef.current(next);\n } else if (inFlightPersistenceRef.current === 0) {\n for (const resolve of flushResolversRef.current) resolve();\n flushResolversRef.current = [];\n }\n }\n },\n [setStateAndRef, takeDirtyBatch],\n );\n runPersistenceRef.current = (nextBatch) => {\n void runPersistence(nextBatch);\n };\n\n const flushIfPending = useCallback(() => {\n if (debounceTimerRef.current !== undefined) {\n clearTimeout(debounceTimerRef.current);\n debounceTimerRef.current = undefined;\n }\n if (adapterRef.current) enqueuePersistence(adapterRef.current);\n }, [enqueuePersistence]);\n\n const schedulePersistence = useCallback(\n (id: string) => {\n if (!adapterRef.current) return;\n dirtyIdsRef.current.add(id);\n if (debounceTimerRef.current !== undefined) {\n clearTimeout(debounceTimerRef.current);\n }\n debounceTimerRef.current = setTimeout(() => {\n debounceTimerRef.current = undefined;\n if (inFlightPersistenceRef.current === 0 && adapterRef.current) {\n enqueuePersistence(adapterRef.current);\n } else {\n debounceTimerRef.current = setTimeout(() => {\n debounceTimerRef.current = undefined;\n if (adapterRef.current) enqueuePersistence(adapterRef.current);\n }, PERSISTENCE_DEBOUNCE_MS);\n }\n }, PERSISTENCE_DEBOUNCE_MS);\n },\n [enqueuePersistence],\n );\n\n const restorePersistedState = useCallback(\n (\n saved: Unstable_InteractablePersistedState,\n options: RestorePersistedStateOptions,\n ) => {\n const shouldStash = options.shouldStash ?? (() => true);\n const shouldApply = options.shouldApply ?? (() => true);\n\n for (const [id, entry] of Object.entries(saved)) {\n if (shouldStash(id)) options.stash.set(id, entry.state);\n }\n setStateAndRef((prev) => {\n let changed = false;\n const definitions = { ...prev.definitions };\n for (const [id, entry] of Object.entries(saved)) {\n const def = definitions[id];\n if (!def || !shouldApply(id, def)) continue;\n definitions[id] = { ...def, state: entry.state };\n changed = true;\n }\n if (!changed) return prev;\n return { ...prev, definitions };\n });\n },\n [setStateAndRef],\n );\n\n const importState = useCallback(\n (saved: Unstable_InteractablePersistedState) => {\n restorePersistedState(saved, { stash: detachedAppStateRef.current });\n },\n [restorePersistedState],\n );\n\n // Applies adapter.load() output: a local edit made while the load was in\n // flight wins, and thread-scoped items never restore from the adapter.\n const applyLoadedState = useCallback(\n (saved: Unstable_InteractablePersistedState) => {\n restorePersistedState(saved, {\n stash: loadedStateRef.current,\n shouldStash: (id) => !touchedIdsRef.current.has(id),\n shouldApply: (id, def) =>\n !touchedIdsRef.current.has(id) && def.scope !== \"thread\",\n });\n },\n [restorePersistedState],\n );\n\n const loadFromAdapter = useCallback(\n async (adapter: Unstable_InteractablePersistenceAdapter) => {\n if (!adapter.load) return;\n try {\n const saved = await adapter.load();\n if (!saved || adapterRef.current !== adapter) return;\n applyLoadedState(saved);\n } catch (e) {\n console.warn(\"[Interactables] Persistence load failed.\", e);\n }\n },\n [applyLoadedState],\n );\n\n const setPersistenceAdapter = useCallback(\n (adapter: Unstable_InteractablePersistenceAdapter | undefined) => {\n if (adapterRef.current !== adapter) flushIfPending();\n adapterRef.current = adapter;\n if (adapter) void loadFromAdapter(adapter);\n },\n [flushIfPending, loadFromAdapter],\n );\n\n const getCurrentThreadId = useCallback((): string | undefined => {\n const client = clientRef.current;\n if (!client) return undefined;\n\n const threadListItem = client.threadListItem;\n if (threadListItem.source != null) {\n return threadListItem().getState().id;\n }\n\n const threads = client.threads;\n if (threads.source != null) {\n return threads().getState().mainThreadId;\n }\n\n return undefined;\n }, [clientRef]);\n\n useEffect(() => {\n if (!persistence) return;\n setPersistenceAdapter(persistence);\n return () => {\n if (adapterRef.current === persistence) {\n setPersistenceAdapter(undefined);\n }\n };\n }, [persistence, setPersistenceAdapter]);\n\n const flush = useCallback(async () => {\n if (debounceTimerRef.current !== undefined) {\n clearTimeout(debounceTimerRef.current);\n debounceTimerRef.current = undefined;\n }\n const hasWork =\n inFlightPersistenceRef.current > 0 ||\n dirtyIdsRef.current.size > 0 ||\n outgoingQueueRef.current.length > 0;\n if (!hasWork) return;\n const p = new Promise<void>((resolve) => {\n flushResolversRef.current.push(resolve);\n });\n if (adapterRef.current) enqueuePersistence(adapterRef.current);\n return p;\n }, [enqueuePersistence]);\n\n const setDefState = useCallback(\n (id: string, updater: (prev: unknown) => unknown) => {\n touchedIdsRef.current.add(id);\n setStateAndRef((prev) => {\n const existing = prev.definitions[id];\n if (!existing) return prev;\n return {\n ...prev,\n definitions: {\n ...prev.definitions,\n [id]: { ...existing, state: updater(existing.state) },\n },\n };\n });\n if (stateRef.current.definitions[id]?.scope !== \"thread\") {\n schedulePersistence(id);\n }\n },\n [schedulePersistence, setStateAndRef],\n );\n\n const provider = useMemo(\n () => ({\n getModelContext: () => {\n const defs = stateRef.current.definitions;\n return (\n buildInteractableModelContext(\n defs,\n partialSchemaCacheRef.current,\n setDefState,\n streamBaselinesRef.current,\n ) ?? {}\n );\n },\n subscribe: (callback: () => void) => {\n subscribersRef.current.add(callback);\n return () => {\n subscribersRef.current.delete(callback);\n };\n },\n }),\n [setDefState],\n );\n\n useEffect(() => {\n notifyStateSubscribers(subscribersRef.current);\n }, [state]);\n\n useAssistantScopeEffect(\n \"modelContext\",\n () => clientRef.current!.modelContext().register(provider),\n [provider],\n );\n\n const installUpdateToolUI = useCallback(\n (name: string, entry: UpdateToolUIEntry) => {\n const toolsAccessor = clientRef.current?.tools;\n if (!toolsAccessor || toolsAccessor.source == null) return false;\n entry.unsubscribe = toolsAccessor().setToolUI(\n interactableToolName(name),\n entry.render,\n { standalone: true },\n );\n return true;\n },\n [clientRef],\n );\n\n // register() installs update-tool UIs against the tools instance bound at\n // call time; this re-applies the retained entries when that instance is\n // structurally replaced and installs entries recorded while no tools\n // scope was available. Each re-apply releases the entry's previous\n // install first, so it is an orphaned no-op against a replaced instance\n // and an idempotent replacement against a live one.\n useAssistantScopeEffect(\n \"tools\",\n () => {\n for (const [name, entry] of updateToolUIsRef.current) {\n entry.unsubscribe?.();\n entry.unsubscribe = undefined;\n installUpdateToolUI(name, entry);\n }\n return () => {\n for (const entry of updateToolUIsRef.current.values()) {\n entry.unsubscribe?.();\n entry.unsubscribe = undefined;\n }\n };\n },\n [installUpdateToolUI],\n );\n\n const register = useCallback(\n (def: InternalInteractableRegistration) => {\n const threadAccessor = clientRef.current?.thread;\n const threadMessages =\n threadAccessor && threadAccessor.source != null\n ? (threadAccessor().getState().messages ?? [])\n : [];\n const scope =\n def.scope ??\n (hasInteractableCreateCall(threadMessages, def.id, def.name)\n ? \"thread\"\n : \"app\");\n\n if (\n process.env.NODE_ENV !== \"production\" &&\n stateRef.current.definitions[def.id] &&\n scope !== \"thread\"\n ) {\n console.warn(\n `[Interactables] \"${def.name}\" (${def.id}) is already registered. ` +\n `Register an app-scoped interactable once (unstable_useInteractable) and ` +\n `read it from other components with unstable_useInteractableState.`,\n );\n }\n\n registrationCountsRef.current.set(\n def.id,\n (registrationCountsRef.current.get(def.id) ?? 0) + 1,\n );\n\n let releaseUpdateToolUI: (() => void) | undefined;\n if (def.updateRender) {\n const existing = updateToolUIsRef.current.get(def.name);\n const entry = existing ?? {\n count: 0,\n render: def.updateRender,\n unsubscribe: undefined,\n };\n entry.count++;\n if (!existing) updateToolUIsRef.current.set(def.name, entry);\n\n if (\n !entry.unsubscribe &&\n !installUpdateToolUI(def.name, entry) &&\n process.env.NODE_ENV !== \"production\"\n ) {\n console.warn(\n `[Interactables] \"${def.name}\" supplied an updateRender, but no ` +\n `tools scope is available yet; it will be installed once one appears.`,\n );\n }\n\n releaseUpdateToolUI = () => {\n const entry = updateToolUIsRef.current.get(def.name);\n if (!entry) return;\n if (--entry.count === 0) {\n updateToolUIsRef.current.delete(def.name);\n entry.unsubscribe?.();\n entry.unsubscribe = undefined;\n }\n };\n }\n\n // The same id re-registers once per anchor (its create call + each update_*).\n if (!partialSchemaCacheRef.current.has(def.id)) {\n try {\n const jsonSchema = toJSONSchema(def.stateSchema);\n partialSchemaCacheRef.current.set(\n def.id,\n toPartialJSONSchema(jsonSchema),\n );\n } catch (e) {\n console.warn(\n `[Interactables] Failed to create partial schema for \"${def.name}\". The update tool will accept arbitrary fields without validation.`,\n e,\n );\n }\n }\n\n const threadId = scope === \"thread\" ? getCurrentThreadId() : undefined;\n const detached =\n scope === \"thread\"\n ? threadId\n ? detachedThreadStateRef.current.get(threadId)?.get(def.id)\n : undefined\n : detachedAppStateRef.current.get(def.id);\n if (scope === \"thread\") {\n if (threadId)\n detachedThreadStateRef.current.get(threadId)?.delete(def.id);\n } else {\n detachedAppStateRef.current.delete(def.id);\n }\n const loaded =\n scope === \"thread\" ? undefined : loadedStateRef.current.get(def.id);\n\n // Tool-created items restore from what the model already knows in this\n // thread (the creating call's args, sent snapshots, and the model's own\n // update_* calls) on a fresh reload; detached (in-session remount) still\n // wins so an unsent edit survives a scroll/virtualization cycle.\n const known =\n scope === \"thread\"\n ? findModelKnownState(threadMessages, def.id, def.name)\n : undefined;\n\n setStateAndRef((prev) => ({\n ...prev,\n definitions: {\n ...prev.definitions,\n [def.id]: {\n id: def.id,\n name: def.name,\n description: def.description,\n stateSchema: def.stateSchema,\n initialState: def.initialState,\n scope,\n state:\n prev.definitions[def.id]?.state ??\n detached ??\n known?.state ??\n loaded ??\n def.initialState,\n },\n },\n }));\n\n return () => {\n releaseUpdateToolUI?.();\n\n const remaining = (registrationCountsRef.current.get(def.id) ?? 1) - 1;\n if (remaining > 0) {\n registrationCountsRef.current.set(def.id, remaining);\n return;\n }\n registrationCountsRef.current.delete(def.id);\n\n flushIfPending();\n setStateAndRef((prev) => {\n const existing = prev.definitions[def.id];\n if (existing) {\n if (existing.scope === \"thread\") {\n const threadId = getCurrentThreadId();\n if (threadId) {\n let stateById = detachedThreadStateRef.current.get(threadId);\n if (!stateById) {\n stateById = new Map();\n detachedThreadStateRef.current.set(threadId, stateById);\n }\n stateById.set(def.id, existing.state);\n }\n } else {\n detachedAppStateRef.current.set(def.id, existing.state);\n }\n }\n partialSchemaCacheRef.current.delete(def.id);\n const { [def.id]: _, ...rest } = prev.definitions;\n const { [def.id]: __, ...restPersistence } = prev.persistence;\n return { ...prev, definitions: rest, persistence: restPersistence };\n });\n };\n },\n [\n flushIfPending,\n clientRef,\n getCurrentThreadId,\n installUpdateToolUI,\n setStateAndRef,\n ],\n );\n\n return {\n getState: () => stateRef.current,\n register,\n setState: setDefState,\n exportState,\n importState,\n setPersistenceAdapter,\n flush,\n };\n};\n\n/**\n * Registers the unstable interactables store scope.\n *\n * @deprecated Unstable / Experimental (not actually removed).\n */\nexport const unstable_Interactables = resource(useInteractablesResource);\n\nattachTransformScopes(useInteractablesResource, (scopes, parent) => {\n if (!scopes.modelContext && parent.modelContext.source === null) {\n scopes.modelContext = ModelContext();\n }\n});\n"],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import { InMemoryThreadListProps } from "./InMemoryThreadList.js";
2
+ import { RemoteThreadListAdapter } from "../../runtimes/remote-thread-list/types.js";
3
+ import { ClientOutput } from "@assistant-ui/store";
4
+ //#region src/react/client/RemoteThreadList.d.ts
5
+ type RemoteThreadListProps = {
6
+ /**
7
+ * Swapping this to a different backing store does not reload the list. Call `reload()` after a genuine swap. A recreated object for the same store is a no-op.
8
+ */
9
+ adapter: RemoteThreadListAdapter;
10
+ /**
11
+ * Factory for the visible thread. Per-thread history reload requires a
12
+ * resource keyed by thread id (`withKey(id, thread(...))`). An unkeyed
13
+ * factory keeps one instance across switches, so a mount-once history
14
+ * loader will not fetch the next thread.
15
+ */
16
+ thread: InMemoryThreadListProps["thread"];
17
+ threadId?: string | undefined;
18
+ onThreadIdChange?: ((threadId: string | undefined) => void) | undefined;
19
+ onSwitchToThread?: ((threadId: string) => void) | undefined;
20
+ onSwitchToNewThread?: (() => void) | undefined;
21
+ onDelete?: ((threadId: string) => void) | undefined;
22
+ };
23
+ /**
24
+ * `AuiConfig` `threads` entry backed by a `RemoteThreadListAdapter`. Thread
25
+ * bodies are born from the `thread` factory inside the client tree, so any
26
+ * `AssistantClient` host can run a remote or cloud list. Per-thread history
27
+ * and attachments come from `unstable_useAdapters`. `useRemoteThreadListRuntime`
28
+ * uses the same hook when `unstable_Provider` is omitted. Key the factory
29
+ * with `withKey` so history reloads when the visible thread changes.
30
+ */
31
+ declare const RemoteThreadList: import("@assistant-ui/tap").Resource<ClientOutput<"threads">, [props: RemoteThreadListProps]>;
32
+ //#endregion
33
+ export { RemoteThreadList, RemoteThreadListProps };
34
+ //# sourceMappingURL=RemoteThreadList.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RemoteThreadList.d.ts","names":[],"sources":["../../../src/react/client/RemoteThreadList.ts"],"mappings":";;;;KAoDY;;;;EAIV,SAAS;;;;;;;EAOT,QAAQ;EACR;EACA,qBAAqB;EACrB,qBAAqB;EACrB;EACA,aAAa;;;;;;;;;;cAo+BF,8CAAgB,SAAA,0BAAA,OAAA"}