@assistant-ui/core 0.2.12 → 0.2.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (445) hide show
  1. package/dist/adapters/attachment.js.map +1 -1
  2. package/dist/adapters/directive-formatter.js.map +1 -1
  3. package/dist/adapters/speech.js.map +1 -1
  4. package/dist/adapters/thread-history.d.ts +3 -1
  5. package/dist/adapters/thread-history.d.ts.map +1 -1
  6. package/dist/adapters/voice.js.map +1 -1
  7. package/dist/index.d.ts +3 -2
  8. package/dist/index.js.map +1 -1
  9. package/dist/internal/duplicate-detection.js.map +1 -1
  10. package/dist/internal.d.ts +2 -1
  11. package/dist/internal.js +2 -1
  12. package/dist/model-context/frame/host.js.map +1 -1
  13. package/dist/model-context/frame/provider.js.map +1 -1
  14. package/dist/model-context/frame/types.js.map +1 -1
  15. package/dist/model-context/registry.js.map +1 -1
  16. package/dist/model-context/tool.js.map +1 -1
  17. package/dist/model-context/types.d.ts +1 -0
  18. package/dist/model-context/types.d.ts.map +1 -1
  19. package/dist/model-context/types.js.map +1 -1
  20. package/dist/react/AssistantProvider.js +7 -1
  21. package/dist/react/AssistantProvider.js.map +1 -1
  22. package/dist/react/AssistantRuntimeProvider.js +18 -6
  23. package/dist/react/AssistantRuntimeProvider.js.map +1 -1
  24. package/dist/react/RuntimeAdapter.d.ts +1 -1
  25. package/dist/react/RuntimeAdapter.d.ts.map +1 -1
  26. package/dist/react/RuntimeAdapter.js +35 -6
  27. package/dist/react/RuntimeAdapter.js.map +1 -1
  28. package/dist/react/adapters/LocalStorageThreadListAdapter.js +29 -7
  29. package/dist/react/adapters/LocalStorageThreadListAdapter.js.map +1 -1
  30. package/dist/react/adapters/TitleGenerationAdapter.js.map +1 -1
  31. package/dist/react/client/DataRenderers.d.ts +1 -8
  32. package/dist/react/client/DataRenderers.d.ts.map +1 -1
  33. package/dist/react/client/DataRenderers.js +56 -36
  34. package/dist/react/client/DataRenderers.js.map +1 -1
  35. package/dist/react/client/Interactables.d.ts +1 -1
  36. package/dist/react/client/Interactables.d.ts.map +1 -1
  37. package/dist/react/client/Interactables.js +71 -70
  38. package/dist/react/client/Interactables.js.map +1 -1
  39. package/dist/react/client/Tools.d.ts +2 -13
  40. package/dist/react/client/Tools.d.ts.map +1 -1
  41. package/dist/react/client/Tools.js +121 -57
  42. package/dist/react/client/Tools.js.map +1 -1
  43. package/dist/react/client/interactable-model-context.js.map +1 -1
  44. package/dist/react/model-context/define-mcp-toolkit.js.map +1 -1
  45. package/dist/react/model-context/define-toolkit.js.map +1 -1
  46. package/dist/react/model-context/external-tool.js.map +1 -1
  47. package/dist/react/model-context/human-tool.js.map +1 -1
  48. package/dist/react/model-context/makeAssistantDataUI.js.map +1 -1
  49. package/dist/react/model-context/makeAssistantTool.js.map +1 -1
  50. package/dist/react/model-context/makeAssistantToolUI.js.map +1 -1
  51. package/dist/react/model-context/provider-tool.js.map +1 -1
  52. package/dist/react/model-context/stub-tool.js.map +1 -1
  53. package/dist/react/model-context/toolbox.js.map +1 -1
  54. package/dist/react/model-context/useAssistantContext.js.map +1 -1
  55. package/dist/react/model-context/useAssistantDataUI.js +27 -8
  56. package/dist/react/model-context/useAssistantDataUI.js.map +1 -1
  57. package/dist/react/model-context/useAssistantInstructions.js +33 -10
  58. package/dist/react/model-context/useAssistantInstructions.js.map +1 -1
  59. package/dist/react/model-context/useAssistantInteractable.js.map +1 -1
  60. package/dist/react/model-context/useAssistantTool.js +59 -17
  61. package/dist/react/model-context/useAssistantTool.js.map +1 -1
  62. package/dist/react/model-context/useAssistantToolUI.js +30 -9
  63. package/dist/react/model-context/useAssistantToolUI.js.map +1 -1
  64. package/dist/react/model-context/useAuiToolOverrides.js.map +1 -1
  65. package/dist/react/model-context/useInlineRender.js +35 -8
  66. package/dist/react/model-context/useInlineRender.js.map +1 -1
  67. package/dist/react/model-context/useInteractableState.js +65 -19
  68. package/dist/react/model-context/useInteractableState.js.map +1 -1
  69. package/dist/react/model-context/useToolArgsStatus.js +42 -14
  70. package/dist/react/model-context/useToolArgsStatus.js.map +1 -1
  71. package/dist/react/primitive-hooks/useActionBarCopy.js +59 -22
  72. package/dist/react/primitive-hooks/useActionBarCopy.js.map +1 -1
  73. package/dist/react/primitive-hooks/useActionBarEdit.js +25 -7
  74. package/dist/react/primitive-hooks/useActionBarEdit.js.map +1 -1
  75. package/dist/react/primitive-hooks/useActionBarFeedback.js +49 -13
  76. package/dist/react/primitive-hooks/useActionBarFeedback.js.map +1 -1
  77. package/dist/react/primitive-hooks/useActionBarReload.js +25 -7
  78. package/dist/react/primitive-hooks/useActionBarReload.js.map +1 -1
  79. package/dist/react/primitive-hooks/useActionBarSpeak.js +28 -9
  80. package/dist/react/primitive-hooks/useActionBarSpeak.js.map +1 -1
  81. package/dist/react/primitive-hooks/useActionBarStopSpeaking.js +25 -7
  82. package/dist/react/primitive-hooks/useActionBarStopSpeaking.js.map +1 -1
  83. package/dist/react/primitive-hooks/useBranchPickerNext.js +27 -11
  84. package/dist/react/primitive-hooks/useBranchPickerNext.js.map +1 -1
  85. package/dist/react/primitive-hooks/useBranchPickerPrevious.js +27 -11
  86. package/dist/react/primitive-hooks/useBranchPickerPrevious.js.map +1 -1
  87. package/dist/react/primitive-hooks/useComposerAddAttachment.js +24 -8
  88. package/dist/react/primitive-hooks/useComposerAddAttachment.js.map +1 -1
  89. package/dist/react/primitive-hooks/useComposerCancel.js +25 -7
  90. package/dist/react/primitive-hooks/useComposerCancel.js.map +1 -1
  91. package/dist/react/primitive-hooks/useComposerDictate.js +25 -7
  92. package/dist/react/primitive-hooks/useComposerDictate.js.map +1 -1
  93. package/dist/react/primitive-hooks/useComposerSend.js +25 -7
  94. package/dist/react/primitive-hooks/useComposerSend.js.map +1 -1
  95. package/dist/react/primitive-hooks/useEditComposerCancel.js +18 -4
  96. package/dist/react/primitive-hooks/useEditComposerCancel.js.map +1 -1
  97. package/dist/react/primitive-hooks/useEditComposerSend.js +25 -7
  98. package/dist/react/primitive-hooks/useEditComposerSend.js.map +1 -1
  99. package/dist/react/primitive-hooks/useMessageBranching.js +41 -9
  100. package/dist/react/primitive-hooks/useMessageBranching.js.map +1 -1
  101. package/dist/react/primitive-hooks/useMessageError.js +4 -1
  102. package/dist/react/primitive-hooks/useMessageError.js.map +1 -1
  103. package/dist/react/primitive-hooks/useMessageReload.js +25 -7
  104. package/dist/react/primitive-hooks/useMessageReload.js.map +1 -1
  105. package/dist/react/primitive-hooks/useSuggestionTrigger.js +31 -13
  106. package/dist/react/primitive-hooks/useSuggestionTrigger.js.map +1 -1
  107. package/dist/react/primitive-hooks/useThreadIsEmpty.js +4 -1
  108. package/dist/react/primitive-hooks/useThreadIsEmpty.js.map +1 -1
  109. package/dist/react/primitive-hooks/useThreadIsRunning.js +4 -1
  110. package/dist/react/primitive-hooks/useThreadIsRunning.js.map +1 -1
  111. package/dist/react/primitive-hooks/useThreadListItemArchive.js +18 -4
  112. package/dist/react/primitive-hooks/useThreadListItemArchive.js.map +1 -1
  113. package/dist/react/primitive-hooks/useThreadListItemDelete.js +18 -4
  114. package/dist/react/primitive-hooks/useThreadListItemDelete.js.map +1 -1
  115. package/dist/react/primitive-hooks/useThreadListItemTrigger.js +18 -4
  116. package/dist/react/primitive-hooks/useThreadListItemTrigger.js.map +1 -1
  117. package/dist/react/primitive-hooks/useThreadListItemUnarchive.js +18 -4
  118. package/dist/react/primitive-hooks/useThreadListItemUnarchive.js.map +1 -1
  119. package/dist/react/primitive-hooks/useThreadListLoadMore.js +25 -7
  120. package/dist/react/primitive-hooks/useThreadListLoadMore.js.map +1 -1
  121. package/dist/react/primitive-hooks/useThreadListNew.js +18 -4
  122. package/dist/react/primitive-hooks/useThreadListNew.js.map +1 -1
  123. package/dist/react/primitive-hooks/useThreadMessages.js +4 -1
  124. package/dist/react/primitive-hooks/useThreadMessages.js.map +1 -1
  125. package/dist/react/primitive-hooks/useVoice.js +63 -13
  126. package/dist/react/primitive-hooks/useVoice.js.map +1 -1
  127. package/dist/react/primitives/chainOfThought/ChainOfThoughtParts.js +42 -7
  128. package/dist/react/primitives/chainOfThought/ChainOfThoughtParts.js.map +1 -1
  129. package/dist/react/primitives/composer/ComposerAttachments.js +67 -16
  130. package/dist/react/primitives/composer/ComposerAttachments.js.map +1 -1
  131. package/dist/react/primitives/composer/ComposerIf.js +30 -9
  132. package/dist/react/primitives/composer/ComposerIf.js.map +1 -1
  133. package/dist/react/primitives/composer/ComposerQueue.js.map +1 -1
  134. package/dist/react/primitives/generativeUI/GenerativeUI.js +55 -13
  135. package/dist/react/primitives/generativeUI/GenerativeUI.js.map +1 -1
  136. package/dist/react/primitives/message/MessageAttachments.js +68 -16
  137. package/dist/react/primitives/message/MessageAttachments.js.map +1 -1
  138. package/dist/react/primitives/message/MessageGroupedParts.d.ts +3 -2
  139. package/dist/react/primitives/message/MessageGroupedParts.d.ts.map +1 -1
  140. package/dist/react/primitives/message/MessageGroupedParts.js +6 -6
  141. package/dist/react/primitives/message/MessageGroupedParts.js.map +1 -1
  142. package/dist/react/primitives/message/MessageParts.d.ts +28 -1
  143. package/dist/react/primitives/message/MessageParts.d.ts.map +1 -1
  144. package/dist/react/primitives/message/MessageParts.js +665 -163
  145. package/dist/react/primitives/message/MessageParts.js.map +1 -1
  146. package/dist/react/primitives/message/MessageQuote.js +18 -2
  147. package/dist/react/primitives/message/MessageQuote.js.map +1 -1
  148. package/dist/react/primitives/messagePart/MessagePartInProgress.js +6 -2
  149. package/dist/react/primitives/messagePart/MessagePartInProgress.js.map +1 -1
  150. package/dist/react/primitives/part/PartMessages.js +46 -14
  151. package/dist/react/primitives/part/PartMessages.js.map +1 -1
  152. package/dist/react/primitives/thread/ThreadMessages.js +67 -10
  153. package/dist/react/primitives/thread/ThreadMessages.js.map +1 -1
  154. package/dist/react/primitives/thread/ThreadSuggestions.js +50 -10
  155. package/dist/react/primitives/thread/ThreadSuggestions.js.map +1 -1
  156. package/dist/react/primitives/threadList/ThreadListItems.js +55 -14
  157. package/dist/react/primitives/threadList/ThreadListItems.js.map +1 -1
  158. package/dist/react/primitives/threadListItem/ThreadListItemTitle.js +15 -2
  159. package/dist/react/primitives/threadListItem/ThreadListItemTitle.js.map +1 -1
  160. package/dist/react/providers/AttachmentByIndexProvider.js +57 -12
  161. package/dist/react/providers/AttachmentByIndexProvider.js.map +1 -1
  162. package/dist/react/providers/ChainOfThoughtByIndicesProvider.js +33 -11
  163. package/dist/react/providers/ChainOfThoughtByIndicesProvider.js.map +1 -1
  164. package/dist/react/providers/ChainOfThoughtPartByIndexProvider.js +29 -6
  165. package/dist/react/providers/ChainOfThoughtPartByIndexProvider.js.map +1 -1
  166. package/dist/react/providers/MessageByIndexProvider.js +49 -19
  167. package/dist/react/providers/MessageByIndexProvider.js.map +1 -1
  168. package/dist/react/providers/PartByIndexProvider.js +29 -6
  169. package/dist/react/providers/PartByIndexProvider.js.map +1 -1
  170. package/dist/react/providers/QueueItemByIndexProvider.js +29 -6
  171. package/dist/react/providers/QueueItemByIndexProvider.js.map +1 -1
  172. package/dist/react/providers/ReadonlyThreadProvider.js +83 -28
  173. package/dist/react/providers/ReadonlyThreadProvider.js.map +1 -1
  174. package/dist/react/providers/SuggestionByIndexProvider.js +29 -6
  175. package/dist/react/providers/SuggestionByIndexProvider.js.map +1 -1
  176. package/dist/react/providers/TextMessagePartProvider.d.ts.map +1 -1
  177. package/dist/react/providers/TextMessagePartProvider.js +75 -26
  178. package/dist/react/providers/TextMessagePartProvider.js.map +1 -1
  179. package/dist/react/providers/ThreadListItemByIndexProvider.js +30 -6
  180. package/dist/react/providers/ThreadListItemByIndexProvider.js.map +1 -1
  181. package/dist/react/providers/ThreadListItemRuntimeProvider.js +28 -5
  182. package/dist/react/providers/ThreadListItemRuntimeProvider.js.map +1 -1
  183. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts +2 -0
  184. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts.map +1 -1
  185. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js +19 -4
  186. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js.map +1 -1
  187. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts +2 -0
  188. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
  189. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js +1 -0
  190. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js.map +1 -1
  191. package/dist/react/runtimes/RuntimeAdapterProvider.js +27 -10
  192. package/dist/react/runtimes/RuntimeAdapterProvider.js.map +1 -1
  193. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts.map +1 -1
  194. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js +16 -1
  195. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js.map +1 -1
  196. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.js.map +1 -1
  197. package/dist/react/runtimes/cloud/auiV0.js.map +1 -1
  198. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.d.ts.map +1 -1
  199. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js +19 -17
  200. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js.map +1 -1
  201. package/dist/react/runtimes/createMessageConverter.js.map +1 -1
  202. package/dist/react/runtimes/external-message-converter.d.ts.map +1 -1
  203. package/dist/react/runtimes/external-message-converter.js +67 -30
  204. package/dist/react/runtimes/external-message-converter.js.map +1 -1
  205. package/dist/react/runtimes/useExternalStoreRuntime.js +44 -10
  206. package/dist/react/runtimes/useExternalStoreRuntime.js.map +1 -1
  207. package/dist/react/runtimes/useExternalStoreSharedOptions.js +17 -12
  208. package/dist/react/runtimes/useExternalStoreSharedOptions.js.map +1 -1
  209. package/dist/react/runtimes/useLocalRuntime.js.map +1 -1
  210. package/dist/react/runtimes/useRemoteThreadListRuntime.js +34 -6
  211. package/dist/react/runtimes/useRemoteThreadListRuntime.js.map +1 -1
  212. package/dist/react/types/MessagePartComponentTypes.d.ts +5 -6
  213. package/dist/react/types/MessagePartComponentTypes.d.ts.map +1 -1
  214. package/dist/react/utils/getMessageQuote.js.map +1 -1
  215. package/dist/react/utils/groupParts.d.ts +13 -1
  216. package/dist/react/utils/groupParts.d.ts.map +1 -1
  217. package/dist/react/utils/groupParts.js +17 -5
  218. package/dist/react/utils/groupParts.js.map +1 -1
  219. package/dist/runtime/api/assistant-runtime.js.map +1 -1
  220. package/dist/runtime/api/attachment-runtime.js.map +1 -1
  221. package/dist/runtime/api/bindings.d.ts +1 -0
  222. package/dist/runtime/api/bindings.d.ts.map +1 -1
  223. package/dist/runtime/api/composer-runtime.js.map +1 -1
  224. package/dist/runtime/api/message-part-runtime.d.ts +3 -9
  225. package/dist/runtime/api/message-part-runtime.d.ts.map +1 -1
  226. package/dist/runtime/api/message-part-runtime.js +3 -6
  227. package/dist/runtime/api/message-part-runtime.js.map +1 -1
  228. package/dist/runtime/api/message-runtime.d.ts +2 -0
  229. package/dist/runtime/api/message-runtime.d.ts.map +1 -1
  230. package/dist/runtime/api/message-runtime.js +5 -0
  231. package/dist/runtime/api/message-runtime.js.map +1 -1
  232. package/dist/runtime/api/thread-list-item-runtime.js.map +1 -1
  233. package/dist/runtime/api/thread-list-runtime.d.ts.map +1 -1
  234. package/dist/runtime/api/thread-list-runtime.js +1 -0
  235. package/dist/runtime/api/thread-list-runtime.js.map +1 -1
  236. package/dist/runtime/api/thread-runtime.d.ts +3 -0
  237. package/dist/runtime/api/thread-runtime.d.ts.map +1 -1
  238. package/dist/runtime/api/thread-runtime.js +4 -0
  239. package/dist/runtime/api/thread-runtime.js.map +1 -1
  240. package/dist/runtime/base/base-assistant-runtime-core.js.map +1 -1
  241. package/dist/runtime/base/base-composer-runtime-core.js.map +1 -1
  242. package/dist/runtime/base/base-thread-runtime-core.d.ts +1 -0
  243. package/dist/runtime/base/base-thread-runtime-core.d.ts.map +1 -1
  244. package/dist/runtime/base/base-thread-runtime-core.js.map +1 -1
  245. package/dist/runtime/base/default-edit-composer-runtime-core.js.map +1 -1
  246. package/dist/runtime/base/default-thread-composer-runtime-core.js.map +1 -1
  247. package/dist/runtime/branch/external-thread-branch-adapter.d.ts +30 -0
  248. package/dist/runtime/branch/external-thread-branch-adapter.d.ts.map +1 -0
  249. package/dist/runtime/branch/external-thread-branch-adapter.js +0 -0
  250. package/dist/runtime/interfaces/thread-list-runtime-core.d.ts +1 -0
  251. package/dist/runtime/interfaces/thread-list-runtime-core.d.ts.map +1 -1
  252. package/dist/runtime/interfaces/thread-runtime-core.d.ts +4 -1
  253. package/dist/runtime/interfaces/thread-runtime-core.d.ts.map +1 -1
  254. package/dist/runtime/queue/message-queue.js.map +1 -1
  255. package/dist/runtime/utils/auto-status.js.map +1 -1
  256. package/dist/runtime/utils/external-store-message.js.map +1 -1
  257. package/dist/runtime/utils/message-repository.js.map +1 -1
  258. package/dist/runtime/utils/resolveToolApprovalResponse.d.ts +15 -0
  259. package/dist/runtime/utils/resolveToolApprovalResponse.d.ts.map +1 -0
  260. package/dist/runtime/utils/resolveToolApprovalResponse.js +35 -0
  261. package/dist/runtime/utils/resolveToolApprovalResponse.js.map +1 -0
  262. package/dist/runtime/utils/thread-message-like.d.ts +5 -1
  263. package/dist/runtime/utils/thread-message-like.d.ts.map +1 -1
  264. package/dist/runtime/utils/thread-message-like.js.map +1 -1
  265. package/dist/runtimes/assistant-transport/utils.js.map +1 -1
  266. package/dist/runtimes/external-store/external-store-adapter.d.ts +1 -0
  267. package/dist/runtimes/external-store/external-store-adapter.d.ts.map +1 -1
  268. package/dist/runtimes/external-store/external-store-runtime-core.js.map +1 -1
  269. package/dist/runtimes/external-store/external-store-shared-options.js.map +1 -1
  270. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js.map +1 -1
  271. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts +1 -0
  272. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts.map +1 -1
  273. package/dist/runtimes/external-store/external-store-thread-runtime-core.js +13 -0
  274. package/dist/runtimes/external-store/external-store-thread-runtime-core.js.map +1 -1
  275. package/dist/runtimes/external-store/thread-message-converter.js.map +1 -1
  276. package/dist/runtimes/local/local-runtime-core.js.map +1 -1
  277. package/dist/runtimes/local/local-runtime-options.d.ts +1 -1
  278. package/dist/runtimes/local/local-thread-list-runtime-core.js.map +1 -1
  279. package/dist/runtimes/local/local-thread-runtime-core.d.ts +9 -1
  280. package/dist/runtimes/local/local-thread-runtime-core.d.ts.map +1 -1
  281. package/dist/runtimes/local/local-thread-runtime-core.js +65 -5
  282. package/dist/runtimes/local/local-thread-runtime-core.js.map +1 -1
  283. package/dist/runtimes/local/should-continue.js +4 -2
  284. package/dist/runtimes/local/should-continue.js.map +1 -1
  285. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.d.ts +2 -0
  286. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.d.ts.map +1 -1
  287. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.js +4 -0
  288. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.js.map +1 -1
  289. package/dist/runtimes/remote-thread-list/adapter/in-memory.js.map +1 -1
  290. package/dist/runtimes/remote-thread-list/empty-thread-core.d.ts.map +1 -1
  291. package/dist/runtimes/remote-thread-list/empty-thread-core.js +4 -0
  292. package/dist/runtimes/remote-thread-list/empty-thread-core.js.map +1 -1
  293. package/dist/runtimes/remote-thread-list/optimistic-state.js.map +1 -1
  294. package/dist/runtimes/remote-thread-list/remote-thread-state.d.ts +1 -0
  295. package/dist/runtimes/remote-thread-list/remote-thread-state.d.ts.map +1 -1
  296. package/dist/runtimes/remote-thread-list/remote-thread-state.js +1 -0
  297. package/dist/runtimes/remote-thread-list/remote-thread-state.js.map +1 -1
  298. package/dist/runtimes/remote-thread-list/types.d.ts +1 -0
  299. package/dist/runtimes/remote-thread-list/types.d.ts.map +1 -1
  300. package/dist/runtimes/tool-invocations/ToolInvocationTracker.js.map +1 -1
  301. package/dist/store/clients/chain-of-thought-client.d.ts +2 -7
  302. package/dist/store/clients/chain-of-thought-client.d.ts.map +1 -1
  303. package/dist/store/clients/chain-of-thought-client.js +39 -20
  304. package/dist/store/clients/chain-of-thought-client.js.map +1 -1
  305. package/dist/store/clients/model-context-client.d.ts +1 -1
  306. package/dist/store/clients/model-context-client.d.ts.map +1 -1
  307. package/dist/store/clients/model-context-client.js +67 -16
  308. package/dist/store/clients/model-context-client.js.map +1 -1
  309. package/dist/store/clients/no-op-composer-client.d.ts +2 -4
  310. package/dist/store/clients/no-op-composer-client.d.ts.map +1 -1
  311. package/dist/store/clients/no-op-composer-client.js +96 -54
  312. package/dist/store/clients/no-op-composer-client.js.map +1 -1
  313. package/dist/store/clients/runtime-adapter.d.ts +1 -3
  314. package/dist/store/clients/runtime-adapter.d.ts.map +1 -1
  315. package/dist/store/clients/runtime-adapter.js +2 -15
  316. package/dist/store/clients/runtime-adapter.js.map +1 -1
  317. package/dist/store/clients/suggestions.d.ts +1 -4
  318. package/dist/store/clients/suggestions.d.ts.map +1 -1
  319. package/dist/store/clients/suggestions.js +63 -23
  320. package/dist/store/clients/suggestions.js.map +1 -1
  321. package/dist/store/clients/thread-message-client.d.ts +1 -1
  322. package/dist/store/clients/thread-message-client.d.ts.map +1 -1
  323. package/dist/store/clients/thread-message-client.js +184 -73
  324. package/dist/store/clients/thread-message-client.js.map +1 -1
  325. package/dist/store/internal.d.ts +2 -2
  326. package/dist/store/internal.js +2 -2
  327. package/dist/store/runtime-clients/attachment-runtime-client.d.ts +2 -4
  328. package/dist/store/runtime-clients/attachment-runtime-client.d.ts.map +1 -1
  329. package/dist/store/runtime-clients/attachment-runtime-client.js +31 -7
  330. package/dist/store/runtime-clients/attachment-runtime-client.js.map +1 -1
  331. package/dist/store/runtime-clients/composer-runtime-client.d.ts +2 -10
  332. package/dist/store/runtime-clients/composer-runtime-client.d.ts.map +1 -1
  333. package/dist/store/runtime-clients/composer-runtime-client.js +195 -72
  334. package/dist/store/runtime-clients/composer-runtime-client.js.map +1 -1
  335. package/dist/store/runtime-clients/liveRef.d.ts +7 -0
  336. package/dist/store/runtime-clients/liveRef.d.ts.map +1 -0
  337. package/dist/store/runtime-clients/liveRef.js +8 -0
  338. package/dist/store/runtime-clients/liveRef.js.map +1 -0
  339. package/dist/store/runtime-clients/message-part-runtime-client.d.ts +2 -4
  340. package/dist/store/runtime-clients/message-part-runtime-client.d.ts.map +1 -1
  341. package/dist/store/runtime-clients/message-part-runtime-client.js +49 -9
  342. package/dist/store/runtime-clients/message-part-runtime-client.js.map +1 -1
  343. package/dist/store/runtime-clients/message-runtime-client.d.ts +2 -7
  344. package/dist/store/runtime-clients/message-runtime-client.d.ts.map +1 -1
  345. package/dist/store/runtime-clients/message-runtime-client.js +220 -54
  346. package/dist/store/runtime-clients/message-runtime-client.js.map +1 -1
  347. package/dist/store/runtime-clients/thread-list-item-runtime-client.d.ts +2 -4
  348. package/dist/store/runtime-clients/thread-list-item-runtime-client.d.ts.map +1 -1
  349. package/dist/store/runtime-clients/thread-list-item-runtime-client.js +71 -26
  350. package/dist/store/runtime-clients/thread-list-item-runtime-client.js.map +1 -1
  351. package/dist/store/runtime-clients/thread-list-runtime-client.d.ts +2 -5
  352. package/dist/store/runtime-clients/thread-list-runtime-client.d.ts.map +1 -1
  353. package/dist/store/runtime-clients/thread-list-runtime-client.js +141 -36
  354. package/dist/store/runtime-clients/thread-list-runtime-client.js.map +1 -1
  355. package/dist/store/runtime-clients/thread-runtime-client.d.ts +2 -4
  356. package/dist/store/runtime-clients/thread-runtime-client.d.ts.map +1 -1
  357. package/dist/store/runtime-clients/thread-runtime-client.js +196 -72
  358. package/dist/store/runtime-clients/thread-runtime-client.js.map +1 -1
  359. package/dist/store/runtime-clients/useSubscribable.js +2 -9
  360. package/dist/store/runtime-clients/useSubscribable.js.map +1 -1
  361. package/dist/store/scopes/message.d.ts +1 -0
  362. package/dist/store/scopes/message.d.ts.map +1 -1
  363. package/dist/store/scopes/part.d.ts +5 -6
  364. package/dist/store/scopes/part.d.ts.map +1 -1
  365. package/dist/store/scopes/queue-item.js.map +1 -1
  366. package/dist/store/scopes/thread-list-item.d.ts +1 -0
  367. package/dist/store/scopes/thread-list-item.d.ts.map +1 -1
  368. package/dist/store/scopes/thread.d.ts +1 -0
  369. package/dist/store/scopes/thread.d.ts.map +1 -1
  370. package/dist/subscribable/subscribable.js.map +1 -1
  371. package/dist/tests/remote-thread-list-test-helpers.js.map +1 -1
  372. package/dist/types/message.d.ts +38 -5
  373. package/dist/types/message.d.ts.map +1 -1
  374. package/dist/types/message.js.map +1 -1
  375. package/dist/utils/composite-context-provider.js.map +1 -1
  376. package/dist/utils/id.js.map +1 -1
  377. package/dist/utils/json/is-json-equal.js.map +1 -1
  378. package/dist/utils/json/is-json.js.map +1 -1
  379. package/dist/utils/text.js.map +1 -1
  380. package/package.json +6 -6
  381. package/src/adapters/thread-history.ts +2 -0
  382. package/src/index.ts +5 -0
  383. package/src/internal.ts +1 -0
  384. package/src/model-context/types.ts +1 -0
  385. package/src/react/AssistantProvider.tsx +10 -1
  386. package/src/react/RuntimeAdapter.ts +25 -8
  387. package/src/react/client/DataRenderers.ts +42 -45
  388. package/src/react/client/Interactables.ts +261 -261
  389. package/src/react/client/Tools.ts +9 -9
  390. package/src/react/primitives/message/MessageGroupedParts.tsx +19 -7
  391. package/src/react/primitives/message/MessageParts.tsx +64 -13
  392. package/src/react/providers/TextMessagePartProvider.tsx +5 -3
  393. package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.tsx +1 -0
  394. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.ts +11 -0
  395. package/src/react/runtimes/cloud/useCloudThreadListAdapter.tsx +6 -0
  396. package/src/react/runtimes/external-message-converter.ts +3 -1
  397. package/src/react/types/MessagePartComponentTypes.ts +5 -5
  398. package/src/react/utils/groupParts.ts +27 -0
  399. package/src/runtime/api/bindings.ts +1 -0
  400. package/src/runtime/api/message-part-runtime.ts +14 -11
  401. package/src/runtime/api/message-runtime.ts +7 -0
  402. package/src/runtime/api/thread-list-runtime.ts +1 -0
  403. package/src/runtime/api/thread-runtime.ts +7 -0
  404. package/src/runtime/base/base-thread-runtime-core.ts +1 -0
  405. package/src/runtime/branch/external-thread-branch-adapter.ts +26 -0
  406. package/src/runtime/interfaces/thread-list-runtime-core.ts +1 -0
  407. package/src/runtime/interfaces/thread-runtime-core.ts +4 -0
  408. package/src/runtime/utils/resolveToolApprovalResponse.test.ts +91 -0
  409. package/src/runtime/utils/resolveToolApprovalResponse.ts +55 -0
  410. package/src/runtime/utils/thread-message-like.ts +10 -1
  411. package/src/runtimes/external-store/external-store-adapter.ts +1 -0
  412. package/src/runtimes/external-store/external-store-thread-runtime-core.ts +24 -0
  413. package/src/runtimes/local/local-runtime-options.ts +1 -1
  414. package/src/runtimes/local/local-thread-runtime-core.test.ts +370 -0
  415. package/src/runtimes/local/local-thread-runtime-core.ts +113 -7
  416. package/src/runtimes/local/should-continue.ts +24 -13
  417. package/src/runtimes/readonly/ReadonlyThreadRuntimeCore.ts +5 -0
  418. package/src/runtimes/remote-thread-list/empty-thread-core.ts +5 -0
  419. package/src/runtimes/remote-thread-list/remote-thread-state.ts +2 -0
  420. package/src/runtimes/remote-thread-list/types.ts +1 -0
  421. package/src/store/clients/chain-of-thought-client.ts +5 -3
  422. package/src/store/clients/model-context-client.test.ts +5 -4
  423. package/src/store/clients/model-context-client.ts +21 -21
  424. package/src/store/clients/no-op-composer-client.ts +5 -3
  425. package/src/store/clients/runtime-adapter.ts +0 -24
  426. package/src/store/clients/suggestions.ts +12 -23
  427. package/src/store/clients/thread-message-client.ts +42 -40
  428. package/src/store/internal.ts +1 -4
  429. package/src/store/runtime-clients/attachment-runtime-client.ts +14 -14
  430. package/src/store/runtime-clients/composer-runtime-client.ts +48 -45
  431. package/src/store/runtime-clients/liveRef.ts +5 -0
  432. package/src/store/runtime-clients/message-part-runtime-client.ts +5 -3
  433. package/src/store/runtime-clients/message-runtime-client.ts +42 -40
  434. package/src/store/runtime-clients/thread-list-item-runtime-client.ts +5 -3
  435. package/src/store/runtime-clients/thread-list-runtime-client.ts +13 -11
  436. package/src/store/runtime-clients/thread-runtime-client.ts +20 -16
  437. package/src/store/runtime-clients/useSubscribable.ts +2 -10
  438. package/src/store/scopes/message.ts +1 -0
  439. package/src/store/scopes/part.ts +5 -2
  440. package/src/store/scopes/thread-list-item.ts +1 -0
  441. package/src/store/scopes/thread.ts +1 -0
  442. package/src/tests/external-store-thread-runtime-core.test.ts +57 -0
  443. package/src/tests/groupMessageParts.test.ts +84 -0
  444. package/src/tests/groupParts.test.ts +55 -0
  445. package/src/types/message.ts +45 -3
@@ -11,61 +11,58 @@ import type { DataMessagePartComponent } from "../types/MessagePartComponentType
11
11
  * directly for a renderer scope, or prefer {@link useAssistantDataUI} /
12
12
  * {@link makeAssistantDataUI} when registering from React components.
13
13
  */
14
- export const DataRenderers = resource(
15
- function DataRenderers(): ClientOutput<"dataRenderers"> {
16
- const [state, setState] = useState<DataRenderersState>(() => ({
17
- renderers: {},
18
- fallbacks: [],
19
- }));
14
+ const useDataRenderers = (): ClientOutput<"dataRenderers"> => {
15
+ const [state, setState] = useState<DataRenderersState>(() => ({
16
+ renderers: {},
17
+ fallbacks: [],
18
+ }));
19
+
20
+ const setDataUI = useCallback(
21
+ (name: string, render: DataMessagePartComponent) => {
22
+ setState((prev) => {
23
+ return {
24
+ ...prev,
25
+ renderers: {
26
+ ...prev.renderers,
27
+ [name]: [...(prev.renderers[name] ?? []), render],
28
+ },
29
+ };
30
+ });
20
31
 
21
- const setDataUI = useCallback(
22
- (name: string, render: DataMessagePartComponent) => {
32
+ return () => {
23
33
  setState((prev) => {
24
34
  return {
25
35
  ...prev,
26
36
  renderers: {
27
37
  ...prev.renderers,
28
- [name]: [...(prev.renderers[name] ?? []), render],
38
+ [name]: prev.renderers[name]?.filter((r) => r !== render) ?? [],
29
39
  },
30
40
  };
31
41
  });
42
+ };
43
+ },
44
+ [],
45
+ );
32
46
 
33
- return () => {
34
- setState((prev) => {
35
- return {
36
- ...prev,
37
- renderers: {
38
- ...prev.renderers,
39
- [name]: prev.renderers[name]?.filter((r) => r !== render) ?? [],
40
- },
41
- };
42
- });
43
- };
44
- },
45
- [],
46
- );
47
+ const setFallbackDataUI = useCallback((render: DataMessagePartComponent) => {
48
+ setState((prev) => ({
49
+ ...prev,
50
+ fallbacks: [...prev.fallbacks, render],
51
+ }));
47
52
 
48
- const setFallbackDataUI = useCallback(
49
- (render: DataMessagePartComponent) => {
50
- setState((prev) => ({
51
- ...prev,
52
- fallbacks: [...prev.fallbacks, render],
53
- }));
53
+ return () => {
54
+ setState((prev) => ({
55
+ ...prev,
56
+ fallbacks: prev.fallbacks.filter((r) => r !== render),
57
+ }));
58
+ };
59
+ }, []);
54
60
 
55
- return () => {
56
- setState((prev) => ({
57
- ...prev,
58
- fallbacks: prev.fallbacks.filter((r) => r !== render),
59
- }));
60
- };
61
- },
62
- [],
63
- );
61
+ return {
62
+ getState: () => state,
63
+ setDataUI,
64
+ setFallbackDataUI,
65
+ };
66
+ };
64
67
 
65
- return {
66
- getState: () => state,
67
- setDataUI,
68
- setFallbackDataUI,
69
- };
70
- },
71
- );
68
+ export const DataRenderers = resource(useDataRenderers);
@@ -18,201 +18,183 @@ import { buildInteractableModelContext } from "./interactable-model-context";
18
18
 
19
19
  const PERSISTENCE_DEBOUNCE_MS = 500;
20
20
 
21
- export const Interactables = resource(
22
- function Interactables(): ClientOutput<"interactables"> {
23
- const [state, setState] = useState<InteractablesState>(() => ({
24
- definitions: {},
25
- persistence: {},
26
- }));
21
+ const useInteractables = (): ClientOutput<"interactables"> => {
22
+ const [state, setState] = useState<InteractablesState>(() => ({
23
+ definitions: {},
24
+ persistence: {},
25
+ }));
26
+
27
+ const clientRef = useAssistantClientRef();
28
+
29
+ const stateRef = useRef(state);
30
+ useEffect(() => {
31
+ stateRef.current = state;
32
+ }, [state]);
27
33
 
28
- const clientRef = useAssistantClientRef();
34
+ const subscribersRef = useRef(new Set<() => void>());
35
+ const partialSchemaCacheRef = useRef(
36
+ new Map<string, InteractableStateSchema>(),
37
+ );
38
+ const detachedStateRef = useRef(new Map<string, unknown>());
29
39
 
30
- const stateRef = useRef(state);
31
- useEffect(() => {
32
- stateRef.current = state;
33
- }, [state]);
40
+ const adapterRef = useRef<InteractablePersistenceAdapter | undefined>(
41
+ undefined,
42
+ );
43
+ const debounceTimerRef = useRef<ReturnType<typeof setTimeout> | undefined>(
44
+ undefined,
45
+ );
46
+ const syncSeqRef = useRef(0);
47
+ const hasPendingLocalChangeRef = useRef(false);
48
+ const flushResolversRef = useRef<Array<() => void>>([]);
49
+ const dirtyIdsRef = useRef(new Set<string>());
34
50
 
35
- const subscribersRef = useRef(new Set<() => void>());
36
- const partialSchemaCacheRef = useRef(
37
- new Map<string, InteractableStateSchema>(),
38
- );
39
- const detachedStateRef = useRef(new Map<string, unknown>());
51
+ const runPersistence = useCallback(async () => {
52
+ const adapter = adapterRef.current;
53
+ if (!adapter) {
54
+ for (const resolve of flushResolversRef.current) resolve();
55
+ flushResolversRef.current = [];
56
+ return;
57
+ }
40
58
 
41
- const adapterRef = useRef<InteractablePersistenceAdapter | undefined>(
42
- undefined,
43
- );
44
- const debounceTimerRef = useRef<ReturnType<typeof setTimeout> | undefined>(
45
- undefined,
46
- );
47
- const syncSeqRef = useRef(0);
48
- const hasPendingLocalChangeRef = useRef(false);
49
- const flushResolversRef = useRef<Array<() => void>>([]);
50
- const dirtyIdsRef = useRef(new Set<string>());
59
+ const seq = ++syncSeqRef.current;
60
+ const dirtyIds = new Set(dirtyIdsRef.current);
61
+ dirtyIdsRef.current.clear();
62
+ hasPendingLocalChangeRef.current = true;
51
63
 
52
- const runPersistence = useCallback(async () => {
53
- const adapter = adapterRef.current;
54
- if (!adapter) {
64
+ // Snapshot before any await so unregistered definitions are still included.
65
+ const exported = stateRef.current.definitions;
66
+ const payload: InteractablePersistedState = {};
67
+ for (const [id, def] of Object.entries(exported)) {
68
+ payload[id] = { name: def.name, state: def.state };
69
+ }
70
+
71
+ setState((prev) => ({
72
+ ...prev,
73
+ persistence: {
74
+ ...prev.persistence,
75
+ ...Object.fromEntries(
76
+ [...dirtyIds].map((id) => [
77
+ id,
78
+ { isPending: true, error: undefined },
79
+ ]),
80
+ ),
81
+ },
82
+ }));
83
+
84
+ try {
85
+ await adapter.save(payload);
86
+ if (syncSeqRef.current === seq) {
87
+ hasPendingLocalChangeRef.current = false;
88
+ setState((prev) => {
89
+ const persistence = { ...prev.persistence };
90
+ for (const id of dirtyIds) delete persistence[id];
91
+ return { ...prev, persistence };
92
+ });
93
+ }
94
+ } catch (e) {
95
+ if (syncSeqRef.current === seq) {
96
+ hasPendingLocalChangeRef.current = false;
97
+ setState((prev) => ({
98
+ ...prev,
99
+ persistence: {
100
+ ...prev.persistence,
101
+ ...Object.fromEntries(
102
+ [...dirtyIds].map((id) => [id, { isPending: false, error: e }]),
103
+ ),
104
+ },
105
+ }));
106
+ }
107
+ } finally {
108
+ if (dirtyIdsRef.current.size > 0 && adapterRef.current) {
109
+ runPersistence();
110
+ } else {
55
111
  for (const resolve of flushResolversRef.current) resolve();
56
112
  flushResolversRef.current = [];
57
- return;
58
113
  }
114
+ }
115
+ }, []);
59
116
 
60
- const seq = ++syncSeqRef.current;
61
- const dirtyIds = new Set(dirtyIdsRef.current);
62
- dirtyIdsRef.current.clear();
63
- hasPendingLocalChangeRef.current = true;
64
-
65
- // Snapshot before any await so unregistered definitions are still included.
66
- const exported = stateRef.current.definitions;
67
- const payload: InteractablePersistedState = {};
68
- for (const [id, def] of Object.entries(exported)) {
69
- payload[id] = { name: def.name, state: def.state };
117
+ const schedulePersistence = useCallback(
118
+ (id: string) => {
119
+ if (!adapterRef.current) return;
120
+ dirtyIdsRef.current.add(id);
121
+ if (debounceTimerRef.current !== undefined) {
122
+ clearTimeout(debounceTimerRef.current);
70
123
  }
71
-
72
- setState((prev) => ({
73
- ...prev,
74
- persistence: {
75
- ...prev.persistence,
76
- ...Object.fromEntries(
77
- [...dirtyIds].map((id) => [
78
- id,
79
- { isPending: true, error: undefined },
80
- ]),
81
- ),
82
- },
83
- }));
84
-
85
- try {
86
- await adapter.save(payload);
87
- if (syncSeqRef.current === seq) {
88
- hasPendingLocalChangeRef.current = false;
89
- setState((prev) => {
90
- const persistence = { ...prev.persistence };
91
- for (const id of dirtyIds) delete persistence[id];
92
- return { ...prev, persistence };
93
- });
94
- }
95
- } catch (e) {
96
- if (syncSeqRef.current === seq) {
97
- hasPendingLocalChangeRef.current = false;
98
- setState((prev) => ({
99
- ...prev,
100
- persistence: {
101
- ...prev.persistence,
102
- ...Object.fromEntries(
103
- [...dirtyIds].map((id) => [id, { isPending: false, error: e }]),
104
- ),
105
- },
106
- }));
107
- }
108
- } finally {
109
- if (dirtyIdsRef.current.size > 0 && adapterRef.current) {
124
+ debounceTimerRef.current = setTimeout(() => {
125
+ debounceTimerRef.current = undefined;
126
+ if (!hasPendingLocalChangeRef.current) {
110
127
  runPersistence();
111
128
  } else {
112
- for (const resolve of flushResolversRef.current) resolve();
113
- flushResolversRef.current = [];
114
- }
115
- }
116
- }, []);
117
-
118
- const schedulePersistence = useCallback(
119
- (id: string) => {
120
- if (!adapterRef.current) return;
121
- dirtyIdsRef.current.add(id);
122
- if (debounceTimerRef.current !== undefined) {
123
- clearTimeout(debounceTimerRef.current);
124
- }
125
- debounceTimerRef.current = setTimeout(() => {
126
- debounceTimerRef.current = undefined;
127
- if (!hasPendingLocalChangeRef.current) {
129
+ debounceTimerRef.current = setTimeout(() => {
130
+ debounceTimerRef.current = undefined;
128
131
  runPersistence();
129
- } else {
130
- debounceTimerRef.current = setTimeout(() => {
131
- debounceTimerRef.current = undefined;
132
- runPersistence();
133
- }, PERSISTENCE_DEBOUNCE_MS);
134
- }
135
- }, PERSISTENCE_DEBOUNCE_MS);
136
- },
137
- [runPersistence],
138
- );
132
+ }, PERSISTENCE_DEBOUNCE_MS);
133
+ }
134
+ }, PERSISTENCE_DEBOUNCE_MS);
135
+ },
136
+ [runPersistence],
137
+ );
139
138
 
140
- const exportState = useCallback((): InteractablePersistedState => {
141
- const result: InteractablePersistedState = {};
142
- for (const [id, def] of Object.entries(stateRef.current.definitions)) {
143
- result[id] = { name: def.name, state: def.state };
144
- }
145
- return result;
146
- }, []);
139
+ const exportState = useCallback((): InteractablePersistedState => {
140
+ const result: InteractablePersistedState = {};
141
+ for (const [id, def] of Object.entries(stateRef.current.definitions)) {
142
+ result[id] = { name: def.name, state: def.state };
143
+ }
144
+ return result;
145
+ }, []);
147
146
 
148
- const importState = useCallback((saved: InteractablePersistedState) => {
147
+ const importState = useCallback((saved: InteractablePersistedState) => {
148
+ for (const [id, entry] of Object.entries(saved)) {
149
+ detachedStateRef.current.set(id, entry.state);
150
+ }
151
+ setState((prev) => {
152
+ let changed = false;
153
+ const definitions = { ...prev.definitions };
149
154
  for (const [id, entry] of Object.entries(saved)) {
150
- detachedStateRef.current.set(id, entry.state);
151
- }
152
- setState((prev) => {
153
- let changed = false;
154
- const definitions = { ...prev.definitions };
155
- for (const [id, entry] of Object.entries(saved)) {
156
- if (definitions[id]) {
157
- definitions[id] = { ...definitions[id], state: entry.state };
158
- changed = true;
159
- }
155
+ if (definitions[id]) {
156
+ definitions[id] = { ...definitions[id], state: entry.state };
157
+ changed = true;
160
158
  }
161
- return changed ? { ...prev, definitions } : prev;
162
- });
163
- }, []);
164
-
165
- const setPersistenceAdapter = useCallback(
166
- (adapter: InteractablePersistenceAdapter | undefined) => {
167
- adapterRef.current = adapter;
168
- },
169
- [],
170
- );
171
-
172
- const flush = useCallback(async () => {
173
- if (debounceTimerRef.current !== undefined) {
174
- clearTimeout(debounceTimerRef.current);
175
- debounceTimerRef.current = undefined;
176
159
  }
177
- if (!adapterRef.current) return;
178
- if (!hasPendingLocalChangeRef.current && dirtyIdsRef.current.size === 0)
179
- return;
180
- const p = new Promise<void>((resolve) => {
181
- flushResolversRef.current.push(resolve);
182
- });
183
- if (!hasPendingLocalChangeRef.current) {
184
- runPersistence();
185
- }
186
- return p;
187
- }, [runPersistence]);
160
+ return changed ? { ...prev, definitions } : prev;
161
+ });
162
+ }, []);
188
163
 
189
- const flushIfPending = useCallback(() => {
190
- if (adapterRef.current && debounceTimerRef.current !== undefined) {
191
- clearTimeout(debounceTimerRef.current);
192
- debounceTimerRef.current = undefined;
193
- runPersistence();
194
- }
195
- }, [runPersistence]);
164
+ const setPersistenceAdapter = useCallback(
165
+ (adapter: InteractablePersistenceAdapter | undefined) => {
166
+ adapterRef.current = adapter;
167
+ },
168
+ [],
169
+ );
196
170
 
197
- const setDefState = useCallback(
198
- (id: string, updater: (prev: unknown) => unknown) => {
199
- setState((prev) => {
200
- const existing = prev.definitions[id];
201
- if (!existing) return prev;
202
- return {
203
- ...prev,
204
- definitions: {
205
- ...prev.definitions,
206
- [id]: { ...existing, state: updater(existing.state) },
207
- },
208
- };
209
- });
210
- if (stateRef.current.definitions[id]) schedulePersistence(id);
211
- },
212
- [schedulePersistence],
213
- );
171
+ const flush = useCallback(async () => {
172
+ if (debounceTimerRef.current !== undefined) {
173
+ clearTimeout(debounceTimerRef.current);
174
+ debounceTimerRef.current = undefined;
175
+ }
176
+ if (!adapterRef.current) return;
177
+ if (!hasPendingLocalChangeRef.current && dirtyIdsRef.current.size === 0)
178
+ return;
179
+ const p = new Promise<void>((resolve) => {
180
+ flushResolversRef.current.push(resolve);
181
+ });
182
+ if (!hasPendingLocalChangeRef.current) {
183
+ runPersistence();
184
+ }
185
+ return p;
186
+ }, [runPersistence]);
187
+
188
+ const flushIfPending = useCallback(() => {
189
+ if (adapterRef.current && debounceTimerRef.current !== undefined) {
190
+ clearTimeout(debounceTimerRef.current);
191
+ debounceTimerRef.current = undefined;
192
+ runPersistence();
193
+ }
194
+ }, [runPersistence]);
214
195
 
215
- const setDefSelected = useCallback((id: string, selected: boolean) => {
196
+ const setDefState = useCallback(
197
+ (id: string, updater: (prev: unknown) => unknown) => {
216
198
  setState((prev) => {
217
199
  const existing = prev.definitions[id];
218
200
  if (!existing) return prev;
@@ -220,107 +202,125 @@ export const Interactables = resource(
220
202
  ...prev,
221
203
  definitions: {
222
204
  ...prev.definitions,
223
- [id]: { ...existing, selected },
205
+ [id]: { ...existing, state: updater(existing.state) },
224
206
  },
225
207
  };
226
208
  });
227
- }, []);
209
+ if (stateRef.current.definitions[id]) schedulePersistence(id);
210
+ },
211
+ [schedulePersistence],
212
+ );
228
213
 
229
- const provider = useMemo(
230
- () => ({
231
- getModelContext: () => {
232
- const defs = stateRef.current.definitions;
233
- return (
234
- buildInteractableModelContext(
235
- defs,
236
- partialSchemaCacheRef.current,
237
- setDefState,
238
- ) ?? {}
239
- );
240
- },
241
- subscribe: (callback: () => void) => {
242
- subscribersRef.current.add(callback);
243
- return () => {
244
- subscribersRef.current.delete(callback);
245
- };
214
+ const setDefSelected = useCallback((id: string, selected: boolean) => {
215
+ setState((prev) => {
216
+ const existing = prev.definitions[id];
217
+ if (!existing) return prev;
218
+ return {
219
+ ...prev,
220
+ definitions: {
221
+ ...prev.definitions,
222
+ [id]: { ...existing, selected },
246
223
  },
247
- }),
248
- [setDefState],
249
- );
224
+ };
225
+ });
226
+ }, []);
227
+
228
+ const provider = useMemo(
229
+ () => ({
230
+ getModelContext: () => {
231
+ const defs = stateRef.current.definitions;
232
+ return (
233
+ buildInteractableModelContext(
234
+ defs,
235
+ partialSchemaCacheRef.current,
236
+ setDefState,
237
+ ) ?? {}
238
+ );
239
+ },
240
+ subscribe: (callback: () => void) => {
241
+ subscribersRef.current.add(callback);
242
+ return () => {
243
+ subscribersRef.current.delete(callback);
244
+ };
245
+ },
246
+ }),
247
+ [setDefState],
248
+ );
250
249
 
251
- useEffect(() => {
252
- for (const cb of subscribersRef.current) cb();
253
- }, [state]);
250
+ useEffect(() => {
251
+ for (const cb of subscribersRef.current) cb();
252
+ }, [state]);
254
253
 
255
- useEffect(() => {
256
- return clientRef.current!.modelContext().register(provider);
257
- }, [clientRef, provider]);
254
+ useEffect(() => {
255
+ return clientRef.current!.modelContext().register(provider);
256
+ }, [clientRef, provider]);
258
257
 
259
- const register = useCallback(
260
- (def: InteractableRegistration) => {
261
- try {
262
- const jsonSchema = toJSONSchema(def.stateSchema);
263
- partialSchemaCacheRef.current.set(
264
- def.id,
265
- toPartialJSONSchema(jsonSchema),
266
- );
267
- } catch (e) {
268
- console.warn(
269
- `[Interactables] Failed to create partial schema for "${def.name}". The update tool will require all fields.`,
270
- e,
271
- );
272
- }
258
+ const register = useCallback(
259
+ (def: InteractableRegistration) => {
260
+ try {
261
+ const jsonSchema = toJSONSchema(def.stateSchema);
262
+ partialSchemaCacheRef.current.set(
263
+ def.id,
264
+ toPartialJSONSchema(jsonSchema),
265
+ );
266
+ } catch (e) {
267
+ console.warn(
268
+ `[Interactables] Failed to create partial schema for "${def.name}". The update tool will require all fields.`,
269
+ e,
270
+ );
271
+ }
273
272
 
274
- const detached = detachedStateRef.current.get(def.id);
275
- detachedStateRef.current.delete(def.id);
273
+ const detached = detachedStateRef.current.get(def.id);
274
+ detachedStateRef.current.delete(def.id);
276
275
 
277
- setState((prev) => ({
278
- ...prev,
279
- definitions: {
280
- ...prev.definitions,
281
- [def.id]: {
282
- id: def.id,
283
- name: def.name,
284
- description: def.description,
285
- stateSchema: def.stateSchema,
286
- state:
287
- prev.definitions[def.id]?.state ?? detached ?? def.initialState,
288
- selected: def.selected,
289
- },
276
+ setState((prev) => ({
277
+ ...prev,
278
+ definitions: {
279
+ ...prev.definitions,
280
+ [def.id]: {
281
+ id: def.id,
282
+ name: def.name,
283
+ description: def.description,
284
+ stateSchema: def.stateSchema,
285
+ state:
286
+ prev.definitions[def.id]?.state ?? detached ?? def.initialState,
287
+ selected: def.selected,
290
288
  },
291
- }));
289
+ },
290
+ }));
292
291
 
293
- return () => {
294
- flushIfPending();
295
- setState((prev) => {
296
- const existing = prev.definitions[def.id];
297
- if (existing) {
298
- detachedStateRef.current.set(def.id, existing.state);
299
- }
300
- partialSchemaCacheRef.current.delete(def.id);
301
- const { [def.id]: _, ...rest } = prev.definitions;
302
- const { [def.id]: __, ...restPersistence } = prev.persistence;
303
- return { ...prev, definitions: rest, persistence: restPersistence };
304
- });
305
- };
306
- },
307
- [flushIfPending],
308
- );
292
+ return () => {
293
+ flushIfPending();
294
+ setState((prev) => {
295
+ const existing = prev.definitions[def.id];
296
+ if (existing) {
297
+ detachedStateRef.current.set(def.id, existing.state);
298
+ }
299
+ partialSchemaCacheRef.current.delete(def.id);
300
+ const { [def.id]: _, ...rest } = prev.definitions;
301
+ const { [def.id]: __, ...restPersistence } = prev.persistence;
302
+ return { ...prev, definitions: rest, persistence: restPersistence };
303
+ });
304
+ };
305
+ },
306
+ [flushIfPending],
307
+ );
308
+
309
+ return {
310
+ getState: () => state,
311
+ register,
312
+ setState: setDefState,
313
+ setSelected: setDefSelected,
314
+ exportState,
315
+ importState,
316
+ setPersistenceAdapter,
317
+ flush,
318
+ };
319
+ };
309
320
 
310
- return {
311
- getState: () => state,
312
- register,
313
- setState: setDefState,
314
- setSelected: setDefSelected,
315
- exportState,
316
- importState,
317
- setPersistenceAdapter,
318
- flush,
319
- };
320
- },
321
- );
321
+ export const Interactables = resource(useInteractables);
322
322
 
323
- attachTransformScopes(Interactables, (scopes, parent) => {
323
+ attachTransformScopes(useInteractables, (scopes, parent) => {
324
324
  if (!scopes.modelContext && parent.modelContext.source === null) {
325
325
  scopes.modelContext = ModelContext();
326
326
  }