@assistant-ui/core 0.1.13 → 0.1.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 (330) hide show
  1. package/dist/adapters/attachment.d.ts +6 -0
  2. package/dist/adapters/attachment.d.ts.map +1 -1
  3. package/dist/adapters/attachment.js +54 -9
  4. package/dist/adapters/attachment.js.map +1 -1
  5. package/dist/adapters/{mention.d.ts → directive-formatter.d.ts} +2 -4
  6. package/dist/adapters/directive-formatter.d.ts.map +1 -0
  7. package/dist/adapters/{mention.js → directive-formatter.js} +4 -9
  8. package/dist/adapters/directive-formatter.js.map +1 -0
  9. package/dist/adapters/index.d.ts +1 -3
  10. package/dist/adapters/index.d.ts.map +1 -1
  11. package/dist/adapters/index.js +2 -1
  12. package/dist/adapters/index.js.map +1 -1
  13. package/dist/adapters/speech.d.ts.map +1 -1
  14. package/dist/adapters/speech.js +1 -3
  15. package/dist/adapters/speech.js.map +1 -1
  16. package/dist/adapters/thread-history.d.ts +1 -0
  17. package/dist/adapters/thread-history.d.ts.map +1 -1
  18. package/dist/adapters/trigger.d.ts +1 -18
  19. package/dist/adapters/trigger.d.ts.map +1 -1
  20. package/dist/index.d.ts +2 -4
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +2 -1
  23. package/dist/index.js.map +1 -1
  24. package/dist/model-context/frame/host.d.ts +1 -1
  25. package/dist/model-context/frame/host.d.ts.map +1 -1
  26. package/dist/model-context/frame/host.js +1 -0
  27. package/dist/model-context/frame/host.js.map +1 -1
  28. package/dist/model-context/frame/provider.d.ts +1 -1
  29. package/dist/model-context/frame/provider.d.ts.map +1 -1
  30. package/dist/model-context/frame/provider.js +1 -0
  31. package/dist/model-context/frame/provider.js.map +1 -1
  32. package/dist/model-context/registry.d.ts +2 -2
  33. package/dist/model-context/registry.d.ts.map +1 -1
  34. package/dist/model-context/tool.d.ts +1 -1
  35. package/dist/model-context/tool.d.ts.map +1 -1
  36. package/dist/model-context/types.d.ts +1 -1
  37. package/dist/model-context/types.d.ts.map +1 -1
  38. package/dist/model-context/types.js +0 -3
  39. package/dist/model-context/types.js.map +1 -1
  40. package/dist/react/AssistantRuntimeProvider.d.ts +1 -1
  41. package/dist/react/AssistantRuntimeProvider.d.ts.map +1 -1
  42. package/dist/react/adapters/LocalStorageThreadListAdapter.js.map +1 -1
  43. package/dist/react/client/DataRenderers.d.ts +1 -1
  44. package/dist/react/client/DataRenderers.d.ts.map +1 -1
  45. package/dist/react/client/DataRenderers.js +14 -0
  46. package/dist/react/client/DataRenderers.js.map +1 -1
  47. package/dist/react/client/Tools.d.ts +1 -1
  48. package/dist/react/client/Tools.d.ts.map +1 -1
  49. package/dist/react/client/Tools.js +1 -0
  50. package/dist/react/client/Tools.js.map +1 -1
  51. package/dist/react/model-context/makeAssistantTool.d.ts +1 -1
  52. package/dist/react/model-context/makeAssistantTool.d.ts.map +1 -1
  53. package/dist/react/model-context/makeAssistantToolUI.d.ts +1 -1
  54. package/dist/react/model-context/makeAssistantToolUI.d.ts.map +1 -1
  55. package/dist/react/model-context/useInlineRender.d.ts +2 -2
  56. package/dist/react/model-context/useInlineRender.d.ts.map +1 -1
  57. package/dist/react/model-context/useInlineRender.js +1 -0
  58. package/dist/react/model-context/useInlineRender.js.map +1 -1
  59. package/dist/react/primitives/chainOfThought/ChainOfThoughtParts.d.ts.map +1 -1
  60. package/dist/react/primitives/chainOfThought/ChainOfThoughtParts.js +1 -0
  61. package/dist/react/primitives/chainOfThought/ChainOfThoughtParts.js.map +1 -1
  62. package/dist/react/primitives/composer/ComposerAttachments.d.ts +1 -1
  63. package/dist/react/primitives/composer/ComposerAttachments.d.ts.map +1 -1
  64. package/dist/react/primitives/composer/ComposerAttachments.js +1 -1
  65. package/dist/react/primitives/composer/ComposerAttachments.js.map +1 -1
  66. package/dist/react/primitives/message/MessageAttachments.d.ts +1 -1
  67. package/dist/react/primitives/message/MessageAttachments.d.ts.map +1 -1
  68. package/dist/react/primitives/message/MessageAttachments.js +1 -1
  69. package/dist/react/primitives/message/MessageAttachments.js.map +1 -1
  70. package/dist/react/primitives/message/MessageParts.d.ts +1 -1
  71. package/dist/react/primitives/message/MessageParts.d.ts.map +1 -1
  72. package/dist/react/primitives/message/MessageParts.js +16 -17
  73. package/dist/react/primitives/message/MessageParts.js.map +1 -1
  74. package/dist/react/primitives/part/PartMessages.d.ts +1 -1
  75. package/dist/react/primitives/part/PartMessages.d.ts.map +1 -1
  76. package/dist/react/primitives/thread/ThreadMessages.d.ts +1 -1
  77. package/dist/react/primitives/thread/ThreadMessages.d.ts.map +1 -1
  78. package/dist/react/primitives/thread/ThreadMessages.js +2 -1
  79. package/dist/react/primitives/thread/ThreadMessages.js.map +1 -1
  80. package/dist/react/primitives/threadList/ThreadListItems.d.ts +1 -1
  81. package/dist/react/primitives/threadList/ThreadListItems.d.ts.map +1 -1
  82. package/dist/react/primitives/threadList/ThreadListItems.js +1 -1
  83. package/dist/react/primitives/threadList/ThreadListItems.js.map +1 -1
  84. package/dist/react/providers/AttachmentByIndexProvider.d.ts +1 -1
  85. package/dist/react/providers/AttachmentByIndexProvider.d.ts.map +1 -1
  86. package/dist/react/providers/ChainOfThoughtByIndicesProvider.d.ts +1 -1
  87. package/dist/react/providers/ChainOfThoughtByIndicesProvider.d.ts.map +1 -1
  88. package/dist/react/providers/ChainOfThoughtPartByIndexProvider.d.ts +1 -1
  89. package/dist/react/providers/ChainOfThoughtPartByIndexProvider.d.ts.map +1 -1
  90. package/dist/react/providers/MessageByIndexProvider.d.ts +1 -1
  91. package/dist/react/providers/MessageByIndexProvider.d.ts.map +1 -1
  92. package/dist/react/providers/PartByIndexProvider.d.ts +1 -1
  93. package/dist/react/providers/PartByIndexProvider.d.ts.map +1 -1
  94. package/dist/react/providers/QueueItemByIndexProvider.d.ts +1 -1
  95. package/dist/react/providers/QueueItemByIndexProvider.d.ts.map +1 -1
  96. package/dist/react/providers/SuggestionByIndexProvider.d.ts +1 -1
  97. package/dist/react/providers/SuggestionByIndexProvider.d.ts.map +1 -1
  98. package/dist/react/providers/TextMessagePartProvider.d.ts +1 -1
  99. package/dist/react/providers/TextMessagePartProvider.d.ts.map +1 -1
  100. package/dist/react/providers/ThreadListItemByIndexProvider.d.ts +1 -1
  101. package/dist/react/providers/ThreadListItemByIndexProvider.d.ts.map +1 -1
  102. package/dist/react/providers/ThreadListItemRuntimeProvider.d.ts +1 -1
  103. package/dist/react/providers/ThreadListItemRuntimeProvider.d.ts.map +1 -1
  104. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts +3 -1
  105. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts.map +1 -1
  106. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js +2 -1
  107. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js.map +1 -1
  108. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts +5 -1
  109. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
  110. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js +22 -7
  111. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js.map +1 -1
  112. package/dist/react/runtimes/RuntimeAdapterProvider.d.ts +1 -1
  113. package/dist/react/runtimes/RuntimeAdapterProvider.d.ts.map +1 -1
  114. package/dist/react/runtimes/RuntimeAdapterProvider.js.map +1 -1
  115. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts +2 -2
  116. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts.map +1 -1
  117. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js.map +1 -1
  118. package/dist/react/runtimes/cloud/auiV0.d.ts +2 -2
  119. package/dist/react/runtimes/cloud/auiV0.d.ts.map +1 -1
  120. package/dist/react/runtimes/cloud/auiV0.js.map +1 -1
  121. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.d.ts.map +1 -1
  122. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js +4 -1
  123. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js.map +1 -1
  124. package/dist/react/runtimes/useLocalRuntime.d.ts.map +1 -1
  125. package/dist/react/runtimes/useLocalRuntime.js +10 -0
  126. package/dist/react/runtimes/useLocalRuntime.js.map +1 -1
  127. package/dist/react/runtimes/useRemoteThreadListRuntime.d.ts.map +1 -1
  128. package/dist/react/runtimes/useRemoteThreadListRuntime.js +6 -0
  129. package/dist/react/runtimes/useRemoteThreadListRuntime.js.map +1 -1
  130. package/dist/react/runtimes/useToolInvocations.d.ts.map +1 -1
  131. package/dist/react/runtimes/useToolInvocations.js +2 -0
  132. package/dist/react/runtimes/useToolInvocations.js.map +1 -1
  133. package/dist/react/types/MessagePartComponentTypes.d.ts +1 -1
  134. package/dist/react/types/MessagePartComponentTypes.d.ts.map +1 -1
  135. package/dist/react/types/scopes/dataRenderers.d.ts +2 -0
  136. package/dist/react/types/scopes/dataRenderers.d.ts.map +1 -1
  137. package/dist/runtime/api/assistant-runtime.d.ts +1 -1
  138. package/dist/runtime/api/assistant-runtime.d.ts.map +1 -1
  139. package/dist/runtime/api/attachment-runtime.d.ts +0 -1
  140. package/dist/runtime/api/attachment-runtime.d.ts.map +1 -1
  141. package/dist/runtime/api/attachment-runtime.js +0 -3
  142. package/dist/runtime/api/attachment-runtime.js.map +1 -1
  143. package/dist/runtime/api/message-runtime.d.ts +6 -6
  144. package/dist/runtime/api/message-runtime.d.ts.map +1 -1
  145. package/dist/runtime/api/thread-list-runtime.d.ts +4 -2
  146. package/dist/runtime/api/thread-list-runtime.d.ts.map +1 -1
  147. package/dist/runtime/api/thread-list-runtime.js +5 -0
  148. package/dist/runtime/api/thread-list-runtime.js.map +1 -1
  149. package/dist/runtime/api/thread-runtime.d.ts +10 -9
  150. package/dist/runtime/api/thread-runtime.d.ts.map +1 -1
  151. package/dist/runtime/api/thread-runtime.js +4 -3
  152. package/dist/runtime/api/thread-runtime.js.map +1 -1
  153. package/dist/runtime/base/base-thread-runtime-core.js.map +1 -1
  154. package/dist/runtime/base/default-edit-composer-runtime-core.d.ts +2 -1
  155. package/dist/runtime/base/default-edit-composer-runtime-core.d.ts.map +1 -1
  156. package/dist/runtime/base/default-edit-composer-runtime-core.js +26 -5
  157. package/dist/runtime/base/default-edit-composer-runtime-core.js.map +1 -1
  158. package/dist/runtime/interfaces/thread-list-runtime-core.d.ts +1 -0
  159. package/dist/runtime/interfaces/thread-list-runtime-core.d.ts.map +1 -1
  160. package/dist/runtime/interfaces/thread-runtime-core.d.ts +7 -0
  161. package/dist/runtime/interfaces/thread-runtime-core.d.ts.map +1 -1
  162. package/dist/runtime/internal.d.ts.map +1 -1
  163. package/dist/runtime/internal.js +1 -4
  164. package/dist/runtime/internal.js.map +1 -1
  165. package/dist/runtime/utils/auto-status.d.ts +1 -1
  166. package/dist/runtime/utils/auto-status.d.ts.map +1 -1
  167. package/dist/runtime/utils/chat-model-adapter.d.ts +1 -1
  168. package/dist/runtime/utils/chat-model-adapter.d.ts.map +1 -1
  169. package/dist/runtime/utils/message-repository.d.ts +6 -0
  170. package/dist/runtime/utils/message-repository.d.ts.map +1 -1
  171. package/dist/runtime/utils/message-repository.js +17 -0
  172. package/dist/runtime/utils/message-repository.js.map +1 -1
  173. package/dist/runtime/utils/thread-message-like.d.ts +1 -1
  174. package/dist/runtime/utils/thread-message-like.d.ts.map +1 -1
  175. package/dist/runtime/utils/thread-message-like.js.map +1 -1
  176. package/dist/runtimes/assistant-transport/utils.d.ts +1 -1
  177. package/dist/runtimes/assistant-transport/utils.d.ts.map +1 -1
  178. package/dist/runtimes/assistant-transport/utils.js +1 -1
  179. package/dist/runtimes/assistant-transport/utils.js.map +1 -1
  180. package/dist/runtimes/external-store/external-store-adapter.d.ts +8 -0
  181. package/dist/runtimes/external-store/external-store-adapter.d.ts.map +1 -1
  182. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.d.ts +1 -1
  183. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.d.ts.map +1 -1
  184. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js +27 -25
  185. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js.map +1 -1
  186. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts +1 -0
  187. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts.map +1 -1
  188. package/dist/runtimes/external-store/external-store-thread-runtime-core.js +4 -0
  189. package/dist/runtimes/external-store/external-store-thread-runtime-core.js.map +1 -1
  190. package/dist/runtimes/remote-thread-list/adapter/in-memory.d.ts +2 -2
  191. package/dist/runtimes/remote-thread-list/adapter/in-memory.d.ts.map +1 -1
  192. package/dist/runtimes/remote-thread-list/types.d.ts +1 -1
  193. package/dist/runtimes/remote-thread-list/types.d.ts.map +1 -1
  194. package/dist/store/runtime-clients/attachment-runtime-client.d.ts +2 -2
  195. package/dist/store/runtime-clients/attachment-runtime-client.d.ts.map +1 -1
  196. package/dist/store/runtime-clients/composer-runtime-client.d.ts +1 -1
  197. package/dist/store/runtime-clients/composer-runtime-client.d.ts.map +1 -1
  198. package/dist/store/runtime-clients/message-part-runtime-client.d.ts +2 -2
  199. package/dist/store/runtime-clients/message-part-runtime-client.d.ts.map +1 -1
  200. package/dist/store/runtime-clients/message-runtime-client.d.ts +1 -1
  201. package/dist/store/runtime-clients/message-runtime-client.d.ts.map +1 -1
  202. package/dist/store/runtime-clients/thread-list-item-runtime-client.d.ts +1 -1
  203. package/dist/store/runtime-clients/thread-list-item-runtime-client.d.ts.map +1 -1
  204. package/dist/store/runtime-clients/thread-list-runtime-client.d.ts +2 -2
  205. package/dist/store/runtime-clients/thread-list-runtime-client.d.ts.map +1 -1
  206. package/dist/store/runtime-clients/thread-list-runtime-client.js +1 -0
  207. package/dist/store/runtime-clients/thread-list-runtime-client.js.map +1 -1
  208. package/dist/store/runtime-clients/thread-runtime-client.d.ts +1 -1
  209. package/dist/store/runtime-clients/thread-runtime-client.d.ts.map +1 -1
  210. package/dist/store/scopes/threads.d.ts +1 -0
  211. package/dist/store/scopes/threads.d.ts.map +1 -1
  212. package/dist/subscribable/subscribable.d.ts.map +1 -1
  213. package/dist/subscribable/subscribable.js +1 -15
  214. package/dist/subscribable/subscribable.js.map +1 -1
  215. package/dist/tests/remote-thread-list-test-helpers.d.ts +12 -0
  216. package/dist/tests/remote-thread-list-test-helpers.d.ts.map +1 -0
  217. package/dist/tests/remote-thread-list-test-helpers.js +48 -0
  218. package/dist/tests/remote-thread-list-test-helpers.js.map +1 -0
  219. package/dist/types/directive.d.ts +19 -0
  220. package/dist/types/directive.d.ts.map +1 -0
  221. package/dist/types/directive.js +2 -0
  222. package/dist/types/directive.js.map +1 -0
  223. package/dist/types/index.d.ts +1 -1
  224. package/dist/types/index.d.ts.map +1 -1
  225. package/dist/types/message.d.ts.map +1 -1
  226. package/dist/types/trigger.d.ts +2 -2
  227. package/dist/types/trigger.d.ts.map +1 -1
  228. package/dist/utils/json/is-json.d.ts +1 -1
  229. package/dist/utils/json/is-json.d.ts.map +1 -1
  230. package/package.json +12 -12
  231. package/src/adapters/attachment.ts +68 -16
  232. package/src/adapters/{mention.ts → directive-formatter.ts} +8 -20
  233. package/src/adapters/index.ts +2 -9
  234. package/src/adapters/speech.ts +1 -16
  235. package/src/adapters/thread-history.ts +1 -8
  236. package/src/adapters/trigger.ts +1 -37
  237. package/src/index.ts +3 -24
  238. package/src/model-context/frame/host.ts +6 -5
  239. package/src/model-context/frame/provider.ts +6 -5
  240. package/src/model-context/registry.ts +6 -6
  241. package/src/model-context/tool.ts +1 -1
  242. package/src/model-context/types.ts +1 -17
  243. package/src/react/AssistantRuntimeProvider.tsx +1 -1
  244. package/src/react/adapters/LocalStorageThreadListAdapter.tsx +1 -1
  245. package/src/react/client/DataRenderers.ts +19 -3
  246. package/src/react/client/Tools.ts +4 -3
  247. package/src/react/model-context/makeAssistantTool.ts +1 -1
  248. package/src/react/model-context/makeAssistantToolUI.ts +1 -1
  249. package/src/react/model-context/useInlineRender.ts +3 -2
  250. package/src/react/primitives/chainOfThought/ChainOfThoughtParts.tsx +1 -0
  251. package/src/react/primitives/composer/ComposerAttachments.tsx +7 -1
  252. package/src/react/primitives/message/MessageAttachments.tsx +7 -1
  253. package/src/react/primitives/message/MessageParts.tsx +27 -17
  254. package/src/react/primitives/part/PartMessages.tsx +1 -1
  255. package/src/react/primitives/thread/ThreadMessages.tsx +3 -2
  256. package/src/react/primitives/threadList/ThreadListItems.tsx +7 -1
  257. package/src/react/providers/AttachmentByIndexProvider.tsx +1 -1
  258. package/src/react/providers/ChainOfThoughtByIndicesProvider.tsx +1 -1
  259. package/src/react/providers/ChainOfThoughtPartByIndexProvider.tsx +1 -1
  260. package/src/react/providers/MessageByIndexProvider.tsx +1 -1
  261. package/src/react/providers/PartByIndexProvider.tsx +1 -1
  262. package/src/react/providers/QueueItemByIndexProvider.tsx +1 -1
  263. package/src/react/providers/SuggestionByIndexProvider.tsx +1 -1
  264. package/src/react/providers/TextMessagePartProvider.tsx +1 -1
  265. package/src/react/providers/ThreadListItemByIndexProvider.tsx +1 -1
  266. package/src/react/providers/ThreadListItemRuntimeProvider.tsx +1 -1
  267. package/src/react/runtimes/RemoteThreadListHookInstanceManager.tsx +7 -8
  268. package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.tsx +28 -8
  269. package/src/react/runtimes/RuntimeAdapterProvider.tsx +1 -1
  270. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.ts +3 -3
  271. package/src/react/runtimes/cloud/auiV0.ts +5 -2
  272. package/src/react/runtimes/cloud/useCloudThreadListAdapter.tsx +6 -3
  273. package/src/react/runtimes/useLocalRuntime.ts +10 -0
  274. package/src/react/runtimes/useRemoteThreadListRuntime.ts +6 -0
  275. package/src/react/runtimes/useToolInvocations.ts +2 -0
  276. package/src/react/types/MessagePartComponentTypes.ts +1 -1
  277. package/src/react/types/scopes/dataRenderers.ts +2 -0
  278. package/src/runtime/api/assistant-runtime.ts +1 -1
  279. package/src/runtime/api/attachment-runtime.ts +0 -4
  280. package/src/runtime/api/message-runtime.ts +8 -8
  281. package/src/runtime/api/thread-list-runtime.ts +13 -5
  282. package/src/runtime/api/thread-runtime.ts +13 -12
  283. package/src/runtime/base/base-thread-runtime-core.ts +1 -1
  284. package/src/runtime/base/default-edit-composer-runtime-core.ts +35 -5
  285. package/src/runtime/interfaces/thread-list-runtime-core.ts +1 -0
  286. package/src/runtime/interfaces/thread-runtime-core.ts +7 -0
  287. package/src/runtime/internal.ts +1 -4
  288. package/src/runtime/utils/auto-status.ts +1 -1
  289. package/src/runtime/utils/chat-model-adapter.ts +1 -1
  290. package/src/runtime/utils/message-repository.ts +26 -0
  291. package/src/runtime/utils/thread-message-like.ts +4 -1
  292. package/src/runtimes/assistant-transport/utils.ts +5 -1
  293. package/src/runtimes/external-store/external-store-adapter.ts +8 -0
  294. package/src/runtimes/external-store/external-store-thread-list-runtime-core.ts +35 -29
  295. package/src/runtimes/external-store/external-store-thread-runtime-core.ts +4 -0
  296. package/src/runtimes/remote-thread-list/adapter/in-memory.ts +2 -2
  297. package/src/runtimes/remote-thread-list/types.ts +1 -1
  298. package/src/store/runtime-clients/attachment-runtime-client.ts +2 -2
  299. package/src/store/runtime-clients/composer-runtime-client.ts +2 -2
  300. package/src/store/runtime-clients/message-part-runtime-client.ts +2 -2
  301. package/src/store/runtime-clients/message-runtime-client.ts +2 -2
  302. package/src/store/runtime-clients/thread-list-item-runtime-client.ts +1 -1
  303. package/src/store/runtime-clients/thread-list-runtime-client.ts +4 -3
  304. package/src/store/runtime-clients/thread-runtime-client.ts +3 -3
  305. package/src/store/scopes/threads.ts +1 -0
  306. package/src/subscribable/subscribable.ts +1 -24
  307. package/src/tests/MessageRepository.test.ts +141 -0
  308. package/src/tests/OptimisticState-list-race.test.ts +5 -9
  309. package/src/tests/RemoteThreadListThreadListRuntimeCore-reload.test.ts +209 -0
  310. package/src/tests/RemoteThreadListThreadListRuntimeCore-switchToThread-dedupe.test.ts +139 -0
  311. package/src/tests/attachment.test.ts +180 -0
  312. package/src/tests/default-edit-composer-runtime-core.test.ts +312 -0
  313. package/src/tests/{mention-formatter.test.ts → directive-formatter.test.ts} +26 -1
  314. package/src/tests/external-store-thread-list-runtime-core.test.ts +212 -0
  315. package/src/tests/get-thread-state-isRunning.test.ts +93 -0
  316. package/src/tests/remote-thread-list-isLoading.test.ts +6 -10
  317. package/src/tests/remote-thread-list-test-helpers.ts +70 -0
  318. package/src/tests/thread-list-runtime-getLoadThreadsPromise.test.ts +17 -1
  319. package/src/types/directive.ts +19 -0
  320. package/src/types/index.ts +1 -3
  321. package/src/types/message.ts +0 -12
  322. package/src/types/trigger.ts +2 -10
  323. package/src/utils/json/is-json.ts +1 -1
  324. package/dist/adapters/mention.d.ts.map +0 -1
  325. package/dist/adapters/mention.js.map +0 -1
  326. package/dist/types/mention.d.ts +0 -21
  327. package/dist/types/mention.d.ts.map +0 -1
  328. package/dist/types/mention.js +0 -2
  329. package/dist/types/mention.js.map +0 -1
  330. package/src/types/mention.ts +0 -39
@@ -0,0 +1,180 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import {
3
+ attachmentsEqual,
4
+ liftNonTextParts,
5
+ partToCompleteAttachment,
6
+ } from "../adapters/attachment";
7
+ import type { CompleteAttachment } from "../types/attachment";
8
+
9
+ const makeAttachment = (id: string): CompleteAttachment => ({
10
+ id,
11
+ type: "document",
12
+ name: "file.pdf",
13
+ content: [
14
+ { type: "file", data: "data", mimeType: "application/pdf", filename: id },
15
+ ],
16
+ status: { type: "complete" },
17
+ });
18
+
19
+ describe("attachmentsEqual", () => {
20
+ it("returns true for two empty arrays", () => {
21
+ expect(attachmentsEqual([], [])).toBe(true);
22
+ });
23
+
24
+ it("returns false when lengths differ", () => {
25
+ expect(attachmentsEqual([makeAttachment("a")], [])).toBe(false);
26
+ });
27
+
28
+ it("returns true when all ids match in order", () => {
29
+ const a = makeAttachment("a");
30
+ const b = makeAttachment("b");
31
+ expect(attachmentsEqual([a, b], [a, b])).toBe(true);
32
+ });
33
+
34
+ it("returns false when ids differ at the same length", () => {
35
+ expect(attachmentsEqual([makeAttachment("a")], [makeAttachment("b")])).toBe(
36
+ false,
37
+ );
38
+ });
39
+ });
40
+
41
+ describe("partToCompleteAttachment", () => {
42
+ it("converts an image part using the filename as name", () => {
43
+ const result = partToCompleteAttachment({
44
+ type: "image",
45
+ image: "https://example.com/x.png",
46
+ filename: "x.png",
47
+ });
48
+ expect(result).toMatchObject({
49
+ type: "image",
50
+ name: "x.png",
51
+ status: { type: "complete" },
52
+ });
53
+ expect(result.content).toEqual([
54
+ {
55
+ type: "image",
56
+ image: "https://example.com/x.png",
57
+ filename: "x.png",
58
+ },
59
+ ]);
60
+ });
61
+
62
+ it("falls back to 'image' when the image part has no filename", () => {
63
+ const result = partToCompleteAttachment({
64
+ type: "image",
65
+ image: "blob",
66
+ });
67
+ expect(result.name).toBe("image");
68
+ });
69
+
70
+ it("converts a file part to a document attachment with contentType", () => {
71
+ const result = partToCompleteAttachment({
72
+ type: "file",
73
+ data: "blob",
74
+ mimeType: "application/pdf",
75
+ filename: "report.pdf",
76
+ });
77
+ expect(result).toMatchObject({
78
+ type: "document",
79
+ name: "report.pdf",
80
+ contentType: "application/pdf",
81
+ });
82
+ });
83
+
84
+ it("falls back to 'document' when the file part has no filename", () => {
85
+ const result = partToCompleteAttachment({
86
+ type: "file",
87
+ data: "blob",
88
+ mimeType: "application/pdf",
89
+ });
90
+ expect(result.name).toBe("document");
91
+ });
92
+
93
+ it("converts an audio part with derived name and contentType", () => {
94
+ const mp3 = partToCompleteAttachment({
95
+ type: "audio",
96
+ audio: { data: "blob", format: "mp3" },
97
+ });
98
+ expect(mp3).toMatchObject({
99
+ type: "audio",
100
+ name: "audio.mp3",
101
+ contentType: "audio/mp3",
102
+ });
103
+
104
+ const wav = partToCompleteAttachment({
105
+ type: "audio",
106
+ audio: { data: "blob", format: "wav" },
107
+ });
108
+ expect(wav.name).toBe("audio.wav");
109
+ expect(wav.contentType).toBe("audio/wav");
110
+ });
111
+
112
+ it("converts a data part using its name", () => {
113
+ const result = partToCompleteAttachment({
114
+ type: "data",
115
+ name: "weather-widget",
116
+ data: { temp: 20 },
117
+ });
118
+ expect(result).toMatchObject({
119
+ type: "data",
120
+ name: "weather-widget",
121
+ });
122
+ expect(result.contentType).toBeUndefined();
123
+ });
124
+
125
+ it("generates a unique id for each call", () => {
126
+ const a = partToCompleteAttachment({
127
+ type: "file",
128
+ data: "x",
129
+ mimeType: "application/pdf",
130
+ });
131
+ const b = partToCompleteAttachment({
132
+ type: "file",
133
+ data: "x",
134
+ mimeType: "application/pdf",
135
+ });
136
+ expect(a.id).not.toBe(b.id);
137
+ });
138
+ });
139
+
140
+ describe("liftNonTextParts", () => {
141
+ it("returns an empty array for content of only text parts", () => {
142
+ expect(
143
+ liftNonTextParts([
144
+ { type: "text", text: "hello" },
145
+ { type: "text", text: "world" },
146
+ ]),
147
+ ).toEqual([]);
148
+ });
149
+
150
+ it("lifts mixed non-text types preserving order", () => {
151
+ const result = liftNonTextParts([
152
+ { type: "text", text: "mix" },
153
+ {
154
+ type: "image",
155
+ image: "url",
156
+ filename: "pic.png",
157
+ },
158
+ {
159
+ type: "file",
160
+ data: "d",
161
+ mimeType: "application/pdf",
162
+ filename: "doc.pdf",
163
+ },
164
+ { type: "audio", audio: { data: "a", format: "mp3" } },
165
+ { type: "data", name: "widget", data: {} },
166
+ ]);
167
+ expect(result.map((a) => a.type)).toEqual([
168
+ "image",
169
+ "document",
170
+ "audio",
171
+ "data",
172
+ ]);
173
+ expect(result.map((a) => a.name)).toEqual([
174
+ "pic.png",
175
+ "doc.pdf",
176
+ "audio.mp3",
177
+ "widget",
178
+ ]);
179
+ });
180
+ });
@@ -0,0 +1,312 @@
1
+ import { describe, expect, it, vi } from "vitest";
2
+ import { DefaultEditComposerRuntimeCore } from "../runtime/base/default-edit-composer-runtime-core";
3
+ import type { AppendMessage, ThreadMessage } from "../types/message";
4
+ import type { CompleteAttachment } from "../types/attachment";
5
+ import type { ThreadRuntimeCore } from "../runtime/interfaces/thread-runtime-core";
6
+
7
+ const makeRuntime = () => {
8
+ const append = vi.fn();
9
+ const runtime = {
10
+ append,
11
+ composer: { runConfig: {} },
12
+ } as unknown as ThreadRuntimeCore & { adapters?: undefined };
13
+ return { runtime, append };
14
+ };
15
+
16
+ const makeUserMessage = (overrides?: Partial<ThreadMessage>): ThreadMessage =>
17
+ ({
18
+ id: "msg-1",
19
+ role: "user",
20
+ createdAt: new Date(),
21
+ content: [{ type: "text", text: "hello" }],
22
+ attachments: [],
23
+ metadata: { custom: {} },
24
+ ...overrides,
25
+ }) as ThreadMessage;
26
+
27
+ const makeCompleteAttachment = (
28
+ id: string,
29
+ name = "file.pdf",
30
+ ): CompleteAttachment => ({
31
+ id,
32
+ type: "document",
33
+ name,
34
+ contentType: "application/pdf",
35
+ content: [
36
+ { type: "file", data: "blob", mimeType: "application/pdf", filename: name },
37
+ ],
38
+ status: { type: "complete" },
39
+ });
40
+
41
+ describe("DefaultEditComposerRuntimeCore", () => {
42
+ describe("construction", () => {
43
+ it("seeds composer text from the edited message", () => {
44
+ const { runtime } = makeRuntime();
45
+ const composer = new DefaultEditComposerRuntimeCore(runtime, () => {}, {
46
+ parentId: null,
47
+ message: makeUserMessage({
48
+ content: [{ type: "text", text: "original" }],
49
+ }),
50
+ });
51
+ expect(composer.text).toBe("original");
52
+ });
53
+
54
+ it("seeds attachments from message.attachments", () => {
55
+ const { runtime } = makeRuntime();
56
+ const attachment = makeCompleteAttachment("att-1");
57
+ const composer = new DefaultEditComposerRuntimeCore(runtime, () => {}, {
58
+ parentId: null,
59
+ message: makeUserMessage({ attachments: [attachment] }),
60
+ });
61
+ expect(composer.attachments).toEqual([attachment]);
62
+ });
63
+
64
+ it("lifts non-text content parts into attachments", () => {
65
+ const { runtime } = makeRuntime();
66
+ const composer = new DefaultEditComposerRuntimeCore(runtime, () => {}, {
67
+ parentId: null,
68
+ message: makeUserMessage({
69
+ content: [
70
+ { type: "text", text: "here is a file" },
71
+ {
72
+ type: "file",
73
+ data: "blob",
74
+ mimeType: "application/pdf",
75
+ filename: "report.pdf",
76
+ },
77
+ ],
78
+ }),
79
+ });
80
+ expect(composer.attachments).toHaveLength(1);
81
+ expect(composer.attachments[0]).toMatchObject({
82
+ type: "document",
83
+ name: "report.pdf",
84
+ contentType: "application/pdf",
85
+ status: { type: "complete" },
86
+ });
87
+ });
88
+
89
+ it("merges message.attachments with lifted content parts", () => {
90
+ const { runtime } = makeRuntime();
91
+ const attachment = makeCompleteAttachment("att-1", "existing.pdf");
92
+ const composer = new DefaultEditComposerRuntimeCore(runtime, () => {}, {
93
+ parentId: null,
94
+ message: makeUserMessage({
95
+ attachments: [attachment],
96
+ content: [
97
+ { type: "text", text: "x" },
98
+ {
99
+ type: "file",
100
+ data: "b",
101
+ mimeType: "application/pdf",
102
+ filename: "inline.pdf",
103
+ },
104
+ ],
105
+ }),
106
+ });
107
+ expect(composer.attachments).toHaveLength(2);
108
+ expect(composer.attachments[0]).toBe(attachment);
109
+ expect(composer.attachments[1]).toMatchObject({ name: "inline.pdf" });
110
+ });
111
+
112
+ it("exposes parentId and sourceId", () => {
113
+ const { runtime } = makeRuntime();
114
+ const composer = new DefaultEditComposerRuntimeCore(runtime, () => {}, {
115
+ parentId: "parent-7",
116
+ message: makeUserMessage(),
117
+ });
118
+ expect(composer.parentId).toBe("parent-7");
119
+ expect(composer.sourceId).toBe("msg-1");
120
+ });
121
+ });
122
+
123
+ describe("send behavior", () => {
124
+ it("does not call append when nothing changed", async () => {
125
+ const { runtime, append } = makeRuntime();
126
+ const composer = new DefaultEditComposerRuntimeCore(runtime, () => {}, {
127
+ parentId: "p1",
128
+ message: makeUserMessage({
129
+ content: [{ type: "text", text: "same" }],
130
+ }),
131
+ });
132
+ await composer.send();
133
+ expect(append).not.toHaveBeenCalled();
134
+ });
135
+
136
+ it("calls append when text changes", async () => {
137
+ const { runtime, append } = makeRuntime();
138
+ const composer = new DefaultEditComposerRuntimeCore(runtime, () => {}, {
139
+ parentId: "p1",
140
+ message: makeUserMessage({
141
+ content: [{ type: "text", text: "old" }],
142
+ }),
143
+ });
144
+ composer.setText("new");
145
+ await composer.send();
146
+ expect(append).toHaveBeenCalledTimes(1);
147
+ const appended = append.mock.calls[0]![0] as AppendMessage;
148
+ expect(appended.content).toEqual([{ type: "text", text: "new" }]);
149
+ expect(appended.parentId).toBe("p1");
150
+ expect(appended.sourceId).toBe("msg-1");
151
+ });
152
+
153
+ it("drops a removed attachment from the sent message", async () => {
154
+ const { runtime, append } = makeRuntime();
155
+ const composer = new DefaultEditComposerRuntimeCore(runtime, () => {}, {
156
+ parentId: null,
157
+ message: makeUserMessage({
158
+ content: [
159
+ { type: "text", text: "original" },
160
+ {
161
+ type: "file",
162
+ data: "blob",
163
+ mimeType: "application/pdf",
164
+ filename: "doc.pdf",
165
+ },
166
+ ],
167
+ }),
168
+ });
169
+ expect(composer.attachments).toHaveLength(1);
170
+ await composer.removeAttachment(composer.attachments[0]!.id);
171
+ await composer.send();
172
+ expect(append).toHaveBeenCalledTimes(1);
173
+ const appended = append.mock.calls[0]![0] as AppendMessage;
174
+ expect(appended.attachments).toHaveLength(0);
175
+ expect(appended.content).toEqual([{ type: "text", text: "original" }]);
176
+ });
177
+
178
+ it("preserves the attachment without duplicating it when only text changes", async () => {
179
+ const { runtime, append } = makeRuntime();
180
+ const composer = new DefaultEditComposerRuntimeCore(runtime, () => {}, {
181
+ parentId: null,
182
+ message: makeUserMessage({
183
+ content: [
184
+ { type: "text", text: "old" },
185
+ {
186
+ type: "file",
187
+ data: "blob",
188
+ mimeType: "application/pdf",
189
+ filename: "doc.pdf",
190
+ },
191
+ ],
192
+ }),
193
+ });
194
+ composer.setText("new text");
195
+ await composer.send();
196
+ const appended = append.mock.calls[0]![0] as AppendMessage;
197
+ expect(appended.content).toEqual([{ type: "text", text: "new text" }]);
198
+ expect(appended.attachments).toHaveLength(1);
199
+ expect(appended.attachments![0]).toMatchObject({ name: "doc.pdf" });
200
+ });
201
+
202
+ it("forwards startRun even when text and attachments are unchanged", async () => {
203
+ const { runtime, append } = makeRuntime();
204
+ const composer = new DefaultEditComposerRuntimeCore(runtime, () => {}, {
205
+ parentId: null,
206
+ message: makeUserMessage({
207
+ content: [{ type: "text", text: "same" }],
208
+ }),
209
+ });
210
+ await composer.send({ startRun: true });
211
+ expect(append).toHaveBeenCalledTimes(1);
212
+ const appended = append.mock.calls[0]![0] as AppendMessage;
213
+ expect(appended.startRun).toBe(true);
214
+ });
215
+ });
216
+
217
+ describe("non-user messages", () => {
218
+ it("does not lift non-text parts for assistant messages", () => {
219
+ const { runtime } = makeRuntime();
220
+ const composer = new DefaultEditComposerRuntimeCore(runtime, () => {}, {
221
+ parentId: null,
222
+ message: {
223
+ id: "msg-a",
224
+ role: "assistant",
225
+ createdAt: new Date(),
226
+ content: [
227
+ { type: "text", text: "answer" },
228
+ {
229
+ type: "file",
230
+ data: "blob",
231
+ mimeType: "application/pdf",
232
+ filename: "doc.pdf",
233
+ },
234
+ ],
235
+ status: { type: "complete", reason: "stop" },
236
+ metadata: {
237
+ unstable_state: null,
238
+ unstable_annotations: [],
239
+ unstable_data: [],
240
+ steps: [],
241
+ custom: {},
242
+ },
243
+ } as ThreadMessage,
244
+ });
245
+ expect(composer.attachments).toHaveLength(0);
246
+ });
247
+
248
+ it("preserves non-text content parts of assistant messages on send", async () => {
249
+ const { runtime, append } = makeRuntime();
250
+ const fileParts = [
251
+ {
252
+ type: "file" as const,
253
+ data: "blob",
254
+ mimeType: "application/pdf",
255
+ filename: "doc.pdf",
256
+ },
257
+ { type: "reasoning" as const, text: "chain of thought" },
258
+ ];
259
+ const composer = new DefaultEditComposerRuntimeCore(runtime, () => {}, {
260
+ parentId: null,
261
+ message: {
262
+ id: "msg-a",
263
+ role: "assistant",
264
+ createdAt: new Date(),
265
+ content: [{ type: "text", text: "old answer" }, ...fileParts],
266
+ status: { type: "complete", reason: "stop" },
267
+ metadata: {
268
+ unstable_state: null,
269
+ unstable_annotations: [],
270
+ unstable_data: [],
271
+ steps: [],
272
+ custom: {},
273
+ },
274
+ } as ThreadMessage,
275
+ });
276
+ composer.setText("new answer");
277
+ await composer.send();
278
+ expect(append).toHaveBeenCalledTimes(1);
279
+ const appended = append.mock.calls[0]![0] as AppendMessage;
280
+ expect(appended.content).toEqual([
281
+ { type: "text", text: "new answer" },
282
+ ...fileParts,
283
+ ]);
284
+ expect(appended.attachments ?? []).toHaveLength(0);
285
+ });
286
+ });
287
+
288
+ describe("lifecycle", () => {
289
+ it("invokes endEditCallback after send", async () => {
290
+ const endEdit = vi.fn();
291
+ const { runtime } = makeRuntime();
292
+ const composer = new DefaultEditComposerRuntimeCore(runtime, endEdit, {
293
+ parentId: null,
294
+ message: makeUserMessage(),
295
+ });
296
+ composer.setText("changed");
297
+ await composer.send();
298
+ expect(endEdit).toHaveBeenCalledTimes(1);
299
+ });
300
+
301
+ it("invokes endEditCallback on cancel", () => {
302
+ const endEdit = vi.fn();
303
+ const { runtime } = makeRuntime();
304
+ const composer = new DefaultEditComposerRuntimeCore(runtime, endEdit, {
305
+ parentId: null,
306
+ message: makeUserMessage(),
307
+ });
308
+ composer.cancel();
309
+ expect(endEdit).toHaveBeenCalledTimes(1);
310
+ });
311
+ });
312
+ });
@@ -1,5 +1,5 @@
1
1
  import { describe, it, expect } from "vitest";
2
- import { unstable_defaultDirectiveFormatter } from "../adapters/mention";
2
+ import { unstable_defaultDirectiveFormatter } from "../adapters/directive-formatter";
3
3
 
4
4
  describe("unstable_defaultDirectiveFormatter", () => {
5
5
  describe("serialize", () => {
@@ -109,4 +109,29 @@ describe("unstable_defaultDirectiveFormatter", () => {
109
109
  ]);
110
110
  });
111
111
  });
112
+
113
+ describe("unicode support", () => {
114
+ it("serializes a directive with a CJK label", () => {
115
+ expect(
116
+ unstable_defaultDirectiveFormatter.serialize({
117
+ id: "天气",
118
+ type: "tool",
119
+ label: "天气",
120
+ }),
121
+ ).toBe(":tool[天气]");
122
+ });
123
+
124
+ it("parses a directive with a CJK label and name attr", () => {
125
+ expect(
126
+ unstable_defaultDirectiveFormatter.parse(":tool[天气]{name=w1}"),
127
+ ).toEqual([
128
+ {
129
+ kind: "mention",
130
+ type: "tool",
131
+ label: "天气",
132
+ id: "w1",
133
+ },
134
+ ]);
135
+ });
136
+ });
112
137
  });