@assistant-ui/core 0.2.18 → 0.2.20

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 (231) hide show
  1. package/dist/index.d.ts +4 -2
  2. package/dist/index.js +3 -1
  3. package/dist/index.js.map +1 -1
  4. package/dist/internal.d.ts +2 -1
  5. package/dist/internal.js +2 -1
  6. package/dist/model-context/interactable-composer-metadata.d.ts +105 -0
  7. package/dist/model-context/interactable-composer-metadata.d.ts.map +1 -0
  8. package/dist/model-context/interactable-composer-metadata.js +259 -0
  9. package/dist/model-context/interactable-composer-metadata.js.map +1 -0
  10. package/dist/model-context/registry.d.ts.map +1 -1
  11. package/dist/model-context/registry.js +1 -0
  12. package/dist/model-context/registry.js.map +1 -1
  13. package/dist/model-context/types.d.ts +6 -0
  14. package/dist/model-context/types.d.ts.map +1 -1
  15. package/dist/model-context/types.js +4 -0
  16. package/dist/model-context/types.js.map +1 -1
  17. package/dist/react/AssistantProvider.d.ts +1 -1
  18. package/dist/react/AssistantProvider.js +1 -1
  19. package/dist/react/AssistantRuntimeProvider.d.ts +1 -1
  20. package/dist/react/RuntimeAdapter.js +1 -1
  21. package/dist/react/client/Interactables.d.ts +8 -2
  22. package/dist/react/client/Interactables.d.ts.map +1 -1
  23. package/dist/react/client/Interactables.js +190 -94
  24. package/dist/react/client/Interactables.js.map +1 -1
  25. package/dist/react/client/Tools.js +1 -1
  26. package/dist/react/client/interactable-model-context.d.ts +9 -6
  27. package/dist/react/client/interactable-model-context.d.ts.map +1 -1
  28. package/dist/react/client/interactable-model-context.js +154 -32
  29. package/dist/react/client/interactable-model-context.js.map +1 -1
  30. package/dist/react/index.d.ts +15 -6
  31. package/dist/react/index.js +12 -5
  32. package/dist/react/interactables-legacy/Interactables.d.ts +12 -0
  33. package/dist/react/interactables-legacy/Interactables.d.ts.map +1 -0
  34. package/dist/react/interactables-legacy/Interactables.js +264 -0
  35. package/dist/react/interactables-legacy/Interactables.js.map +1 -0
  36. package/dist/react/interactables-legacy/interactable-model-context.d.ts +12 -0
  37. package/dist/react/interactables-legacy/interactable-model-context.d.ts.map +1 -0
  38. package/dist/react/interactables-legacy/interactable-model-context.js +54 -0
  39. package/dist/react/interactables-legacy/interactable-model-context.js.map +1 -0
  40. package/dist/react/interactables-legacy/scopes.d.ts +58 -0
  41. package/dist/react/interactables-legacy/scopes.d.ts.map +1 -0
  42. package/dist/react/interactables-legacy/scopes.js +0 -0
  43. package/dist/react/interactables-legacy/useAssistantInteractable.d.ts +31 -0
  44. package/dist/react/interactables-legacy/useAssistantInteractable.d.ts.map +1 -0
  45. package/dist/react/{model-context → interactables-legacy}/useAssistantInteractable.js +6 -2
  46. package/dist/react/interactables-legacy/useAssistantInteractable.js.map +1 -0
  47. package/dist/react/interactables-legacy/useInteractableState.d.ts +21 -0
  48. package/dist/react/interactables-legacy/useInteractableState.d.ts.map +1 -0
  49. package/dist/react/interactables-legacy/useInteractableState.js +84 -0
  50. package/dist/react/interactables-legacy/useInteractableState.js.map +1 -0
  51. package/dist/react/model-context/interactableTool.d.ts +53 -0
  52. package/dist/react/model-context/interactableTool.d.ts.map +1 -0
  53. package/dist/react/model-context/interactableTool.js +188 -0
  54. package/dist/react/model-context/interactableTool.js.map +1 -0
  55. package/dist/react/model-context/useAssistantContext.js +1 -1
  56. package/dist/react/model-context/useAssistantDataUI.js +1 -1
  57. package/dist/react/model-context/useAssistantInstructions.js +1 -1
  58. package/dist/react/model-context/useAssistantTool.js +1 -1
  59. package/dist/react/model-context/useAssistantToolUI.js +1 -1
  60. package/dist/react/model-context/useAuiToolOverrides.js +1 -1
  61. package/dist/react/model-context/useInteractable.d.ts +73 -0
  62. package/dist/react/model-context/useInteractable.d.ts.map +1 -0
  63. package/dist/react/model-context/useInteractable.js +100 -0
  64. package/dist/react/model-context/useInteractable.js.map +1 -0
  65. package/dist/react/model-context/useInteractableState.d.ts +8 -5
  66. package/dist/react/model-context/useInteractableState.d.ts.map +1 -1
  67. package/dist/react/model-context/useInteractableState.js +48 -48
  68. package/dist/react/model-context/useInteractableState.js.map +1 -1
  69. package/dist/react/model-context/useInteractableVersions.d.ts +19 -0
  70. package/dist/react/model-context/useInteractableVersions.d.ts.map +1 -0
  71. package/dist/react/model-context/useInteractableVersions.js +51 -0
  72. package/dist/react/model-context/useInteractableVersions.js.map +1 -0
  73. package/dist/react/primitive-hooks/useThreadMessageIds.d.ts +15 -0
  74. package/dist/react/primitive-hooks/useThreadMessageIds.d.ts.map +1 -0
  75. package/dist/react/primitive-hooks/useThreadMessageIds.js +26 -0
  76. package/dist/react/primitive-hooks/useThreadMessageIds.js.map +1 -0
  77. package/dist/react/primitive-hooks/useVoice.js +1 -1
  78. package/dist/react/primitives/chainOfThought/ChainOfThoughtParts.js +1 -1
  79. package/dist/react/primitives/composer/ComposerAttachments.js +1 -1
  80. package/dist/react/primitives/composer/ComposerQueue.js +1 -1
  81. package/dist/react/primitives/generativeUI/GenerativeUI.d.ts.map +1 -1
  82. package/dist/react/primitives/generativeUI/GenerativeUI.js +2 -2
  83. package/dist/react/primitives/generativeUI/GenerativeUI.js.map +1 -1
  84. package/dist/react/primitives/message/MessageAttachments.js +1 -1
  85. package/dist/react/primitives/message/MessageGroupedParts.js +1 -1
  86. package/dist/react/primitives/message/MessageParts.js +1 -1
  87. package/dist/react/primitives/message/MessageQuote.js +1 -1
  88. package/dist/react/primitives/part/PartMessages.d.ts +5 -2
  89. package/dist/react/primitives/part/PartMessages.d.ts.map +1 -1
  90. package/dist/react/primitives/part/PartMessages.js +8 -8
  91. package/dist/react/primitives/part/PartMessages.js.map +1 -1
  92. package/dist/react/primitives/thread/ThreadMessages.d.ts +31 -1
  93. package/dist/react/primitives/thread/ThreadMessages.d.ts.map +1 -1
  94. package/dist/react/primitives/thread/ThreadMessages.js +64 -2
  95. package/dist/react/primitives/thread/ThreadMessages.js.map +1 -1
  96. package/dist/react/primitives/thread/ThreadSuggestions.js +1 -1
  97. package/dist/react/primitives/threadList/ThreadListItems.js +1 -1
  98. package/dist/react/providers/MessageByIdProvider.d.ts +9 -0
  99. package/dist/react/providers/MessageByIdProvider.d.ts.map +1 -0
  100. package/dist/react/providers/MessageByIdProvider.js +57 -0
  101. package/dist/react/providers/MessageByIdProvider.js.map +1 -0
  102. package/dist/react/providers/ReadonlyThreadProvider.js +1 -1
  103. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js +1 -1
  104. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts +3 -0
  105. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
  106. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js +16 -1
  107. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js.map +1 -1
  108. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js +1 -1
  109. package/dist/react/runtimes/cloud/auiV0.js +1 -1
  110. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js +1 -1
  111. package/dist/react/runtimes/createRuntimeExtras.d.ts +20 -0
  112. package/dist/react/runtimes/createRuntimeExtras.d.ts.map +1 -0
  113. package/dist/react/runtimes/createRuntimeExtras.js +43 -0
  114. package/dist/react/runtimes/createRuntimeExtras.js.map +1 -0
  115. package/dist/react/runtimes/useLocalRuntime.js +1 -1
  116. package/dist/react/runtimes/useRemoteThreadListRuntime.d.ts.map +1 -1
  117. package/dist/react/runtimes/useRemoteThreadListRuntime.js +6 -2
  118. package/dist/react/runtimes/useRemoteThreadListRuntime.js.map +1 -1
  119. package/dist/react/runtimes/useStreamingTiming.d.ts +26 -0
  120. package/dist/react/runtimes/useStreamingTiming.d.ts.map +1 -0
  121. package/dist/react/runtimes/useStreamingTiming.js +43 -0
  122. package/dist/react/runtimes/useStreamingTiming.js.map +1 -0
  123. package/dist/react/types/scopes/interactables.d.ts +40 -24
  124. package/dist/react/types/scopes/interactables.d.ts.map +1 -1
  125. package/dist/react/types/store-augmentation.d.ts +3 -1
  126. package/dist/react/types/store-augmentation.d.ts.map +1 -1
  127. package/dist/react/utils/useJSONEqual.d.ts +11 -0
  128. package/dist/react/utils/useJSONEqual.d.ts.map +1 -0
  129. package/dist/react/utils/useJSONEqual.js +30 -0
  130. package/dist/react/utils/useJSONEqual.js.map +1 -0
  131. package/dist/runtime/base/base-composer-runtime-core.d.ts +5 -0
  132. package/dist/runtime/base/base-composer-runtime-core.d.ts.map +1 -1
  133. package/dist/runtime/base/base-composer-runtime-core.js +13 -0
  134. package/dist/runtime/base/base-composer-runtime-core.js.map +1 -1
  135. package/dist/runtime/base/default-edit-composer-runtime-core.d.ts.map +1 -1
  136. package/dist/runtime/base/default-edit-composer-runtime-core.js +6 -1
  137. package/dist/runtime/base/default-edit-composer-runtime-core.js.map +1 -1
  138. package/dist/runtime/base/default-thread-composer-runtime-core.d.ts.map +1 -1
  139. package/dist/runtime/base/default-thread-composer-runtime-core.js +4 -1
  140. package/dist/runtime/base/default-thread-composer-runtime-core.js.map +1 -1
  141. package/dist/runtime/utils/message-repository.d.ts +1 -0
  142. package/dist/runtime/utils/message-repository.d.ts.map +1 -1
  143. package/dist/runtime/utils/message-repository.js +6 -3
  144. package/dist/runtime/utils/message-repository.js.map +1 -1
  145. package/dist/runtime/utils/streaming-timing.d.ts +59 -0
  146. package/dist/runtime/utils/streaming-timing.d.ts.map +1 -0
  147. package/dist/runtime/utils/streaming-timing.js +76 -0
  148. package/dist/runtime/utils/streaming-timing.js.map +1 -0
  149. package/dist/runtime/utils/thread-message-like.js +2 -1
  150. package/dist/runtime/utils/thread-message-like.js.map +1 -1
  151. package/dist/runtimes/external-store/external-store-adapter.d.ts +26 -1
  152. package/dist/runtimes/external-store/external-store-adapter.d.ts.map +1 -1
  153. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts +9 -0
  154. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts.map +1 -1
  155. package/dist/runtimes/external-store/external-store-thread-runtime-core.js +19 -0
  156. package/dist/runtimes/external-store/external-store-thread-runtime-core.js.map +1 -1
  157. package/dist/runtimes/local/local-thread-runtime-core.d.ts.map +1 -1
  158. package/dist/runtimes/local/local-thread-runtime-core.js +1 -1
  159. package/dist/runtimes/local/local-thread-runtime-core.js.map +1 -1
  160. package/dist/runtimes/remote-thread-list/types.d.ts +12 -0
  161. package/dist/runtimes/remote-thread-list/types.d.ts.map +1 -1
  162. package/dist/store/clients/suggestions.js +1 -1
  163. package/dist/store/clients/thread-message-client.js +1 -1
  164. package/dist/store/runtime-clients/composer-runtime-client.js +1 -1
  165. package/dist/store/runtime-clients/message-runtime-client.js +1 -1
  166. package/dist/store/runtime-clients/thread-list-item-runtime-client.js +1 -1
  167. package/dist/store/runtime-clients/thread-runtime-client.js +1 -1
  168. package/dist/tests/remote-thread-list-test-helpers.d.ts +1 -1
  169. package/dist/tests/remote-thread-list-test-helpers.d.ts.map +1 -1
  170. package/dist/tests/remote-thread-list-test-helpers.js +3 -2
  171. package/dist/tests/remote-thread-list-test-helpers.js.map +1 -1
  172. package/package.json +9 -9
  173. package/src/index.ts +17 -0
  174. package/src/internal.ts +7 -0
  175. package/src/model-context/interactable-composer-metadata.test.ts +550 -0
  176. package/src/model-context/interactable-composer-metadata.ts +395 -0
  177. package/src/model-context/registry.ts +5 -0
  178. package/src/model-context/types.ts +12 -0
  179. package/src/react/client/Interactables.test.ts +358 -0
  180. package/src/react/client/Interactables.ts +339 -86
  181. package/src/react/client/interactable-model-context.test.ts +418 -0
  182. package/src/react/client/interactable-model-context.ts +252 -58
  183. package/src/react/index.ts +72 -3
  184. package/src/react/interactables-legacy/Interactables.ts +332 -0
  185. package/src/react/interactables-legacy/interactable-model-context.test.ts +54 -0
  186. package/src/react/interactables-legacy/interactable-model-context.ts +80 -0
  187. package/src/react/interactables-legacy/scopes.ts +66 -0
  188. package/src/react/{model-context → interactables-legacy}/useAssistantInteractable.ts +10 -1
  189. package/src/react/interactables-legacy/useInteractableState.ts +67 -0
  190. package/src/react/model-context/interactableTool.tsx +175 -0
  191. package/src/react/model-context/useInteractable.ts +233 -0
  192. package/src/react/model-context/useInteractableState.ts +31 -23
  193. package/src/react/model-context/useInteractableVersions.ts +48 -0
  194. package/src/react/primitive-hooks/useThreadMessageIds.ts +27 -0
  195. package/src/react/primitives/generativeUI/GenerativeUI.tsx +5 -1
  196. package/src/react/primitives/part/PartMessages.test.tsx +17 -0
  197. package/src/react/primitives/part/PartMessages.tsx +13 -8
  198. package/src/react/primitives/thread/ThreadMessages.tsx +67 -0
  199. package/src/react/providers/MessageByIdProvider.tsx +23 -0
  200. package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.tsx +21 -1
  201. package/src/react/runtimes/createRuntimeExtras.test.ts +58 -0
  202. package/src/react/runtimes/createRuntimeExtras.ts +68 -0
  203. package/src/react/runtimes/createRuntimeExtras.use.test.ts +50 -0
  204. package/src/react/runtimes/useRemoteThreadListRuntime.ts +13 -1
  205. package/src/react/runtimes/useStreamingTiming.ts +68 -0
  206. package/src/react/types/scopes/interactables.ts +45 -23
  207. package/src/react/types/store-augmentation.ts +4 -2
  208. package/src/react/utils/useJSONEqual.ts +20 -0
  209. package/src/runtime/base/base-composer-runtime-core.ts +13 -0
  210. package/src/runtime/base/default-edit-composer-runtime-core.ts +18 -1
  211. package/src/runtime/base/default-thread-composer-runtime-core.ts +11 -1
  212. package/src/runtime/utils/message-repository.ts +11 -7
  213. package/src/runtime/utils/streaming-timing.test.ts +301 -0
  214. package/src/runtime/utils/streaming-timing.ts +161 -0
  215. package/src/runtime/utils/thread-message-like.ts +2 -1
  216. package/src/runtimes/external-store/external-store-adapter.ts +28 -0
  217. package/src/runtimes/external-store/external-store-thread-runtime-core.ts +33 -1
  218. package/src/runtimes/local/local-thread-runtime-core.ts +4 -1
  219. package/src/runtimes/remote-thread-list/types.ts +13 -0
  220. package/src/tests/MessageRepository.test.ts +2 -0
  221. package/src/tests/composer-can-send.test.ts +1 -0
  222. package/src/tests/default-edit-composer-runtime-core.test.ts +78 -1
  223. package/src/tests/default-thread-composer-runtime-core.test.ts +82 -0
  224. package/src/tests/external-store-thread-runtime-core.test.ts +337 -0
  225. package/src/tests/groupParts.test.ts +32 -0
  226. package/src/tests/remote-thread-list-reactive-threadId.test.ts +90 -0
  227. package/src/tests/remote-thread-list-test-helpers.ts +2 -1
  228. package/src/tests/thread-message-like.test.ts +50 -0
  229. package/dist/react/model-context/useAssistantInteractable.d.ts +0 -22
  230. package/dist/react/model-context/useAssistantInteractable.d.ts.map +0 -1
  231. package/dist/react/model-context/useAssistantInteractable.js.map +0 -1
@@ -0,0 +1,264 @@
1
+ import { ModelContext } from "../../store/clients/model-context-client.js";
2
+ import { buildInteractableModelContext } from "./interactable-model-context.js";
3
+ import { toJSONSchema, toPartialJSONSchema } from "assistant-stream";
4
+ import { attachTransformScopes, useAssistantClientRef } from "@assistant-ui/store";
5
+ import { useCallback, useEffect, useMemo, useRef, useState } from "@assistant-ui/tap/react-shim";
6
+ import { resource } from "@assistant-ui/tap";
7
+ //#region src/react/interactables-legacy/Interactables.ts
8
+ const PERSISTENCE_DEBOUNCE_MS = 500;
9
+ const useInteractables = () => {
10
+ const [state, setState] = useState(() => ({
11
+ definitions: {},
12
+ persistence: {}
13
+ }));
14
+ const clientRef = useAssistantClientRef();
15
+ const stateRef = useRef(state);
16
+ useEffect(() => {
17
+ stateRef.current = state;
18
+ }, [state]);
19
+ const subscribersRef = useRef(/* @__PURE__ */ new Set());
20
+ const partialSchemaCacheRef = useRef(/* @__PURE__ */ new Map());
21
+ const detachedStateRef = useRef(/* @__PURE__ */ new Map());
22
+ const adapterRef = useRef(void 0);
23
+ const debounceTimerRef = useRef(void 0);
24
+ const syncSeqRef = useRef(0);
25
+ const hasPendingLocalChangeRef = useRef(false);
26
+ const flushResolversRef = useRef([]);
27
+ const dirtyIdsRef = useRef(/* @__PURE__ */ new Set());
28
+ const runPersistence = useCallback(async () => {
29
+ const adapter = adapterRef.current;
30
+ if (!adapter) {
31
+ for (const resolve of flushResolversRef.current) resolve();
32
+ flushResolversRef.current = [];
33
+ return;
34
+ }
35
+ const seq = ++syncSeqRef.current;
36
+ const dirtyIds = new Set(dirtyIdsRef.current);
37
+ dirtyIdsRef.current.clear();
38
+ hasPendingLocalChangeRef.current = true;
39
+ const exported = stateRef.current.definitions;
40
+ const payload = {};
41
+ for (const [id, def] of Object.entries(exported)) payload[id] = {
42
+ name: def.name,
43
+ state: def.state
44
+ };
45
+ setState((prev) => ({
46
+ ...prev,
47
+ persistence: {
48
+ ...prev.persistence,
49
+ ...Object.fromEntries([...dirtyIds].map((id_0) => [id_0, {
50
+ isPending: true,
51
+ error: void 0
52
+ }]))
53
+ }
54
+ }));
55
+ try {
56
+ await adapter.save(payload);
57
+ if (syncSeqRef.current === seq) {
58
+ hasPendingLocalChangeRef.current = false;
59
+ setState((prev_1) => {
60
+ const persistence = { ...prev_1.persistence };
61
+ for (const id_2 of dirtyIds) delete persistence[id_2];
62
+ return {
63
+ ...prev_1,
64
+ persistence
65
+ };
66
+ });
67
+ }
68
+ } catch (e) {
69
+ if (syncSeqRef.current === seq) {
70
+ hasPendingLocalChangeRef.current = false;
71
+ setState((prev_0) => ({
72
+ ...prev_0,
73
+ persistence: {
74
+ ...prev_0.persistence,
75
+ ...Object.fromEntries([...dirtyIds].map((id_1) => [id_1, {
76
+ isPending: false,
77
+ error: e
78
+ }]))
79
+ }
80
+ }));
81
+ }
82
+ } finally {
83
+ if (dirtyIdsRef.current.size > 0 && adapterRef.current) runPersistence();
84
+ else {
85
+ for (const resolve of flushResolversRef.current) resolve();
86
+ flushResolversRef.current = [];
87
+ }
88
+ }
89
+ }, []);
90
+ const schedulePersistence = useCallback((id_3) => {
91
+ if (!adapterRef.current) return;
92
+ dirtyIdsRef.current.add(id_3);
93
+ if (debounceTimerRef.current !== void 0) clearTimeout(debounceTimerRef.current);
94
+ debounceTimerRef.current = setTimeout(() => {
95
+ debounceTimerRef.current = void 0;
96
+ if (!hasPendingLocalChangeRef.current) runPersistence();
97
+ else debounceTimerRef.current = setTimeout(() => {
98
+ debounceTimerRef.current = void 0;
99
+ runPersistence();
100
+ }, PERSISTENCE_DEBOUNCE_MS);
101
+ }, PERSISTENCE_DEBOUNCE_MS);
102
+ }, [runPersistence]);
103
+ const exportState = useCallback(() => {
104
+ const result = {};
105
+ for (const [id_4, def_0] of Object.entries(stateRef.current.definitions)) result[id_4] = {
106
+ name: def_0.name,
107
+ state: def_0.state
108
+ };
109
+ return result;
110
+ }, []);
111
+ const importState = useCallback((saved) => {
112
+ for (const [id_5, entry] of Object.entries(saved)) detachedStateRef.current.set(id_5, entry.state);
113
+ setState((prev_2) => {
114
+ let changed = false;
115
+ const definitions = { ...prev_2.definitions };
116
+ for (const [id_6, entry_0] of Object.entries(saved)) if (definitions[id_6]) {
117
+ definitions[id_6] = {
118
+ ...definitions[id_6],
119
+ state: entry_0.state
120
+ };
121
+ changed = true;
122
+ }
123
+ return changed ? {
124
+ ...prev_2,
125
+ definitions
126
+ } : prev_2;
127
+ });
128
+ }, []);
129
+ const setPersistenceAdapter = useCallback((adapter_0) => {
130
+ adapterRef.current = adapter_0;
131
+ }, []);
132
+ const flush = useCallback(async () => {
133
+ if (debounceTimerRef.current !== void 0) {
134
+ clearTimeout(debounceTimerRef.current);
135
+ debounceTimerRef.current = void 0;
136
+ }
137
+ if (!adapterRef.current) return;
138
+ if (!hasPendingLocalChangeRef.current && dirtyIdsRef.current.size === 0) return;
139
+ const p = new Promise((resolve_0) => {
140
+ flushResolversRef.current.push(resolve_0);
141
+ });
142
+ if (!hasPendingLocalChangeRef.current) runPersistence();
143
+ return p;
144
+ }, [runPersistence]);
145
+ const flushIfPending = useCallback(() => {
146
+ if (adapterRef.current && debounceTimerRef.current !== void 0) {
147
+ clearTimeout(debounceTimerRef.current);
148
+ debounceTimerRef.current = void 0;
149
+ runPersistence();
150
+ }
151
+ }, [runPersistence]);
152
+ const setDefState = useCallback((id_7, updater) => {
153
+ setState((prev_3) => {
154
+ const existing = prev_3.definitions[id_7];
155
+ if (!existing) return prev_3;
156
+ return {
157
+ ...prev_3,
158
+ definitions: {
159
+ ...prev_3.definitions,
160
+ [id_7]: {
161
+ ...existing,
162
+ state: updater(existing.state)
163
+ }
164
+ }
165
+ };
166
+ });
167
+ if (stateRef.current.definitions[id_7]) schedulePersistence(id_7);
168
+ }, [schedulePersistence]);
169
+ const setDefSelected = useCallback((id_8, selected) => {
170
+ setState((prev_4) => {
171
+ const existing_0 = prev_4.definitions[id_8];
172
+ if (!existing_0) return prev_4;
173
+ return {
174
+ ...prev_4,
175
+ definitions: {
176
+ ...prev_4.definitions,
177
+ [id_8]: {
178
+ ...existing_0,
179
+ selected
180
+ }
181
+ }
182
+ };
183
+ });
184
+ }, []);
185
+ const provider = useMemo(() => ({
186
+ getModelContext: () => {
187
+ const defs = stateRef.current.definitions;
188
+ return buildInteractableModelContext(defs, partialSchemaCacheRef.current, setDefState) ?? {};
189
+ },
190
+ subscribe: (callback) => {
191
+ subscribersRef.current.add(callback);
192
+ return () => {
193
+ subscribersRef.current.delete(callback);
194
+ };
195
+ }
196
+ }), [setDefState]);
197
+ useEffect(() => {
198
+ for (const cb of subscribersRef.current) cb();
199
+ }, [state]);
200
+ useEffect(() => {
201
+ return clientRef.current.modelContext().register(provider);
202
+ }, [clientRef, provider]);
203
+ return {
204
+ getState: () => state,
205
+ register: useCallback((def_1) => {
206
+ try {
207
+ const jsonSchema = toJSONSchema(def_1.stateSchema);
208
+ partialSchemaCacheRef.current.set(def_1.id, toPartialJSONSchema(jsonSchema));
209
+ } catch (e_0) {
210
+ console.warn(`[Interactables] Failed to create partial schema for "${def_1.name}". The update tool will require all fields.`, e_0);
211
+ }
212
+ const detached = detachedStateRef.current.get(def_1.id);
213
+ detachedStateRef.current.delete(def_1.id);
214
+ setState((prev_5) => ({
215
+ ...prev_5,
216
+ definitions: {
217
+ ...prev_5.definitions,
218
+ [def_1.id]: {
219
+ id: def_1.id,
220
+ name: def_1.name,
221
+ description: def_1.description,
222
+ stateSchema: def_1.stateSchema,
223
+ state: prev_5.definitions[def_1.id]?.state ?? detached ?? def_1.initialState,
224
+ selected: def_1.selected
225
+ }
226
+ }
227
+ }));
228
+ return () => {
229
+ flushIfPending();
230
+ setState((prev_6) => {
231
+ const existing_1 = prev_6.definitions[def_1.id];
232
+ if (existing_1) detachedStateRef.current.set(def_1.id, existing_1.state);
233
+ partialSchemaCacheRef.current.delete(def_1.id);
234
+ const { [def_1.id]: _, ...rest } = prev_6.definitions;
235
+ const { [def_1.id]: __, ...restPersistence } = prev_6.persistence;
236
+ return {
237
+ ...prev_6,
238
+ definitions: rest,
239
+ persistence: restPersistence
240
+ };
241
+ });
242
+ };
243
+ }, [flushIfPending]),
244
+ setState: setDefState,
245
+ setSelected: setDefSelected,
246
+ exportState,
247
+ importState,
248
+ setPersistenceAdapter,
249
+ flush
250
+ };
251
+ };
252
+ /**
253
+ * @deprecated Since 2026-06-14 — migrate to the Unstable / Experimental API.
254
+ * Scheduled for removal on/after 2026-09-14. See
255
+ * {@link https://www.assistant-ui.com/docs/tools/interactables#migrating-from-the-previous-api | Interactables migration guide}.
256
+ */
257
+ const Interactables = resource(useInteractables);
258
+ attachTransformScopes(useInteractables, (scopes, parent) => {
259
+ if (!scopes.modelContext && parent.modelContext.source === null) scopes.modelContext = ModelContext();
260
+ });
261
+ //#endregion
262
+ export { Interactables };
263
+
264
+ //# sourceMappingURL=Interactables.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Interactables.js","names":["useState","useEffect","useCallback","useRef","useMemo","resource","useAssistantClientRef","ClientOutput","attachTransformScopes","InteractablesState","InteractableRegistration","InteractableStateSchema","InteractablePersistedState","InteractablePersistenceAdapter","toJSONSchema","toPartialJSONSchema","ModelContext","buildInteractableModelContext","PERSISTENCE_DEBOUNCE_MS","useInteractables","state","setState","definitions","persistence","clientRef","stateRef","current","subscribersRef","Set","partialSchemaCacheRef","Map","detachedStateRef","adapterRef","undefined","debounceTimerRef","ReturnType","setTimeout","syncSeqRef","hasPendingLocalChangeRef","flushResolversRef","Array","dirtyIdsRef","runPersistence","adapter","resolve","seq","dirtyIds","clear","exported","payload","id","def","Object","entries","name","prev","fromEntries","map","isPending","error","save","e","size","schedulePersistence","add","clearTimeout","exportState","result","importState","saved","entry","set","changed","setPersistenceAdapter","flush","p","Promise","push","flushIfPending","setDefState","updater","existing","setDefSelected","selected","provider","getModelContext","defs","subscribe","callback","delete","cb","modelContext","register","jsonSchema","stateSchema","console","warn","detached","get","description","initialState","_","rest","__","restPersistence","getState","setSelected","Interactables","scopes","parent","source"],"sources":["../../../src/react/interactables-legacy/Interactables.ts"],"sourcesContent":["import { useState, useEffect, useCallback, useRef, useMemo } from \"react\";\nimport { resource } from \"@assistant-ui/tap\";\nimport {\n useAssistantClientRef,\n type ClientOutput,\n attachTransformScopes,\n} from \"@assistant-ui/store\";\nimport type {\n InteractablesState,\n InteractableRegistration,\n InteractableStateSchema,\n InteractablePersistedState,\n InteractablePersistenceAdapter,\n} from \"./scopes\";\nimport { toJSONSchema, toPartialJSONSchema } from \"assistant-stream\";\nimport { ModelContext } from \"../../store\";\nimport { buildInteractableModelContext } from \"./interactable-model-context\";\n\nconst PERSISTENCE_DEBOUNCE_MS = 500;\n\nconst useInteractables = (): ClientOutput<\"interactables\"> => {\n const [state, setState] = useState<InteractablesState>(() => ({\n definitions: {},\n persistence: {},\n }));\n\n const clientRef = useAssistantClientRef();\n\n const stateRef = useRef(state);\n useEffect(() => {\n stateRef.current = state;\n }, [state]);\n\n const subscribersRef = useRef(new Set<() => void>());\n const partialSchemaCacheRef = useRef(\n new Map<string, InteractableStateSchema>(),\n );\n const detachedStateRef = useRef(new Map<string, unknown>());\n\n const adapterRef = useRef<InteractablePersistenceAdapter | undefined>(\n undefined,\n );\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 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 exported = stateRef.current.definitions;\n const payload: InteractablePersistedState = {};\n for (const [id, def] of Object.entries(exported)) {\n payload[id] = { name: def.name, state: def.state };\n }\n\n setState((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 setState((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 setState((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 }, []);\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 exportState = useCallback((): InteractablePersistedState => {\n const result: InteractablePersistedState = {};\n for (const [id, def] of Object.entries(stateRef.current.definitions)) {\n result[id] = { name: def.name, state: def.state };\n }\n return result;\n }, []);\n\n const importState = useCallback((saved: InteractablePersistedState) => {\n for (const [id, entry] of Object.entries(saved)) {\n detachedStateRef.current.set(id, entry.state);\n }\n setState((prev) => {\n let changed = false;\n const definitions = { ...prev.definitions };\n for (const [id, entry] of Object.entries(saved)) {\n if (definitions[id]) {\n definitions[id] = { ...definitions[id], state: entry.state };\n changed = true;\n }\n }\n return changed ? { ...prev, definitions } : prev;\n });\n }, []);\n\n const setPersistenceAdapter = useCallback(\n (adapter: InteractablePersistenceAdapter | undefined) => {\n adapterRef.current = adapter;\n },\n [],\n );\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 setState((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]) schedulePersistence(id);\n },\n [schedulePersistence],\n );\n\n const setDefSelected = useCallback((id: string, selected: boolean) => {\n setState((prev) => {\n const existing = prev.definitions[id];\n if (!existing) return prev;\n return {\n ...prev,\n definitions: {\n ...prev.definitions,\n [id]: { ...existing, selected },\n },\n };\n });\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 ) ?? {}\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: InteractableRegistration) => {\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 require all fields.`,\n e,\n );\n }\n\n const detached = detachedStateRef.current.get(def.id);\n detachedStateRef.current.delete(def.id);\n\n setState((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 state:\n prev.definitions[def.id]?.state ?? detached ?? def.initialState,\n selected: def.selected,\n },\n },\n }));\n\n return () => {\n flushIfPending();\n setState((prev) => {\n const existing = prev.definitions[def.id];\n if (existing) {\n detachedStateRef.current.set(def.id, existing.state);\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],\n );\n\n return {\n getState: () => state,\n register,\n setState: setDefState,\n setSelected: setDefSelected,\n exportState,\n importState,\n setPersistenceAdapter,\n flush,\n };\n};\n\n/**\n * @deprecated Since 2026-06-14 — migrate to the Unstable / Experimental API.\n * Scheduled for removal on/after 2026-09-14. See\n * {@link https://www.assistant-ui.com/docs/tools/interactables#migrating-from-the-previous-api | Interactables migration guide}.\n */\nexport const Interactables = resource(useInteractables);\n\nattachTransformScopes(useInteractables, (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,12 @@
1
+ import { InteractableDefinition, InteractableStateSchema } from "./scopes.js";
2
+ import { Tool } from "assistant-stream";
3
+
4
+ //#region src/react/interactables-legacy/interactable-model-context.d.ts
5
+ declare function shallowMerge(prev: unknown, partial: unknown): unknown;
6
+ declare function buildInteractableModelContext(definitions: Record<string, InteractableDefinition>, partialSchemaCache: Map<string, InteractableStateSchema>, setDefState: (id: string, updater: (prev: unknown) => unknown) => void): {
7
+ system: string;
8
+ tools: Record<string, Tool<any, any>>;
9
+ } | undefined;
10
+ //#endregion
11
+ export { buildInteractableModelContext, shallowMerge };
12
+ //# sourceMappingURL=interactable-model-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interactable-model-context.d.ts","names":[],"sources":["../../../src/react/interactables-legacy/interactable-model-context.ts"],"mappings":";;;;iBAGgB,YAAA,CAAa,IAAA,WAAe,OAAgB;AAAA,iBAiB5C,6BAAA,CACd,WAAA,EAAa,MAAA,SAAe,sBAAA,GAC5B,kBAAA,EAAoB,GAAA,SAAY,uBAAA,GAChC,WAAA,GAAc,EAAA,UAAY,OAAA,GAAU,IAAA;EACjC,MAAA;EAAgB,KAAA,EAAO,MAAA,SAAe,IAAA;AAAA"}
@@ -0,0 +1,54 @@
1
+ //#region src/react/interactables-legacy/interactable-model-context.ts
2
+ function shallowMerge(prev, partial) {
3
+ if (typeof prev !== "object" || prev === null || typeof partial !== "object" || partial === null || Array.isArray(prev) || Array.isArray(partial)) return partial;
4
+ return {
5
+ ...prev,
6
+ ...partial
7
+ };
8
+ }
9
+ function buildInteractableModelContext(definitions, partialSchemaCache, setDefState) {
10
+ const entries = Object.values(definitions);
11
+ if (entries.length === 0) return void 0;
12
+ const byName = /* @__PURE__ */ new Map();
13
+ for (const def of entries) {
14
+ const list = byName.get(def.name) ?? [];
15
+ list.push(def);
16
+ byName.set(def.name, list);
17
+ }
18
+ const systemParts = [];
19
+ const tools = {};
20
+ for (const [name, instances] of byName) {
21
+ const isMulti = instances.length > 1;
22
+ for (const def of instances) {
23
+ const selectedTag = def.selected ? " (SELECTED)" : "";
24
+ const idTag = isMulti ? ` [id="${def.id}"]` : "";
25
+ systemParts.push(`Interactable component "${name}"${idTag}${selectedTag} (${def.description}). Current state: ${JSON.stringify(def.state)}`);
26
+ const safeName = name.replace(/[^a-zA-Z0-9_-]/g, "_");
27
+ const safeId = def.id.replace(/[^a-zA-Z0-9_-]/g, "_");
28
+ const toolName = isMulti ? `update_${safeName}_${safeId}` : `update_${safeName}`;
29
+ const partialSchema = partialSchemaCache.get(def.id) ?? def.stateSchema;
30
+ tools[toolName] = {
31
+ type: "frontend",
32
+ description: `Update the state of interactable component "${name}"${isMulti ? ` (id: ${def.id})` : ""}. Only include the fields you want to change; omitted fields keep their current values. ${def.description}`,
33
+ parameters: partialSchema,
34
+ streamCall: async (reader) => {
35
+ try {
36
+ for await (const partialArgs of reader.args.streamValues()) setDefState(def.id, (prev) => shallowMerge(prev, partialArgs));
37
+ } catch {}
38
+ },
39
+ execute: async (partialState) => {
40
+ setDefState(def.id, (prev) => shallowMerge(prev, partialState));
41
+ return { success: true };
42
+ }
43
+ };
44
+ }
45
+ }
46
+ return {
47
+ system: systemParts.join("\n"),
48
+ tools
49
+ };
50
+ }
51
+ //#endregion
52
+ export { buildInteractableModelContext, shallowMerge };
53
+
54
+ //# sourceMappingURL=interactable-model-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interactable-model-context.js","names":["Tool","InteractableDefinition","InteractableStateSchema","shallowMerge","prev","partial","Array","isArray","Record","buildInteractableModelContext","definitions","partialSchemaCache","Map","setDefState","id","updater","system","tools","entries","Object","values","length","undefined","byName","def","list","get","name","push","set","systemParts","instances","isMulti","selectedTag","selected","idTag","description","JSON","stringify","state","safeName","replace","safeId","toolName","partialSchema","stateSchema","type","const","parameters","streamCall","reader","partialArgs","args","streamValues","execute","partialState","success","join"],"sources":["../../../src/react/interactables-legacy/interactable-model-context.ts"],"sourcesContent":["import type { Tool } from \"assistant-stream\";\nimport type { InteractableDefinition, InteractableStateSchema } from \"./scopes\";\n\nexport function shallowMerge(prev: unknown, partial: unknown): unknown {\n if (\n typeof prev !== \"object\" ||\n prev === null ||\n typeof partial !== \"object\" ||\n partial === null ||\n Array.isArray(prev) ||\n Array.isArray(partial)\n ) {\n return partial;\n }\n return {\n ...(prev as Record<string, unknown>),\n ...(partial as Record<string, unknown>),\n };\n}\n\nexport function buildInteractableModelContext(\n definitions: Record<string, InteractableDefinition>,\n partialSchemaCache: Map<string, InteractableStateSchema>,\n setDefState: (id: string, updater: (prev: unknown) => unknown) => void,\n): { system: string; tools: Record<string, Tool<any, any>> } | undefined {\n const entries = Object.values(definitions);\n if (entries.length === 0) return undefined;\n\n const byName = new Map<string, InteractableDefinition[]>();\n for (const def of entries) {\n const list = byName.get(def.name) ?? [];\n list.push(def);\n byName.set(def.name, list);\n }\n\n const systemParts: string[] = [];\n const tools: Record<string, Tool<any, any>> = {};\n\n for (const [name, instances] of byName) {\n const isMulti = instances.length > 1;\n\n for (const def of instances) {\n const selectedTag = def.selected ? \" (SELECTED)\" : \"\";\n const idTag = isMulti ? ` [id=\"${def.id}\"]` : \"\";\n\n systemParts.push(\n `Interactable component \"${name}\"${idTag}${selectedTag} (${def.description}). Current state: ${JSON.stringify(def.state)}`,\n );\n\n const safeName = name.replace(/[^a-zA-Z0-9_-]/g, \"_\");\n const safeId = def.id.replace(/[^a-zA-Z0-9_-]/g, \"_\");\n const toolName = isMulti\n ? `update_${safeName}_${safeId}`\n : `update_${safeName}`;\n\n const partialSchema = partialSchemaCache.get(def.id) ?? def.stateSchema;\n\n tools[toolName] = {\n type: \"frontend\" as const,\n description: `Update the state of interactable component \"${name}\"${isMulti ? ` (id: ${def.id})` : \"\"}. Only include the fields you want to change; omitted fields keep their current values. ${def.description}`,\n parameters: partialSchema,\n streamCall: async (reader) => {\n try {\n for await (const partialArgs of reader.args.streamValues()) {\n setDefState(def.id, (prev) => shallowMerge(prev, partialArgs));\n }\n } catch {\n // Non-fatal: execute handles the final state\n }\n },\n execute: async (partialState: unknown) => {\n setDefState(def.id, (prev) => shallowMerge(prev, partialState));\n return { success: true };\n },\n };\n }\n }\n\n return { system: systemParts.join(\"\\n\"), tools };\n}\n"],"mappings":";AAGA,SAAgBG,aAAaC,MAAeC,SAA2B;CACrE,IACE,OAAOD,SAAS,YAChBA,SAAS,QACT,OAAOC,YAAY,YACnBA,YAAY,QACZC,MAAMC,QAAQH,IAAI,KAClBE,MAAMC,QAAQF,OAAO,GAErB,OAAOA;CAET,OAAO;EACL,GAAID;EACJ,GAAIC;CACN;AACF;AAEA,SAAgBI,8BACdC,aACAC,oBACAE,aACuE;CACvE,MAAMK,UAAUC,OAAOC,OAAOV,WAAW;CACzC,IAAIQ,QAAQG,WAAW,GAAG,OAAOC,KAAAA;CAEjC,MAAMC,yBAAS,IAAIX,IAAsC;CACzD,KAAK,MAAMY,OAAON,SAAS;EACzB,MAAMO,OAAOF,OAAOG,IAAIF,IAAIG,IAAI,KAAK,CAAA;EACrCF,KAAKG,KAAKJ,GAAG;EACbD,OAAOM,IAAIL,IAAIG,MAAMF,IAAI;CAC3B;CAEA,MAAMK,cAAwB,CAAA;CAC9B,MAAMb,QAAwC,CAAC;CAE/C,KAAK,MAAM,CAACU,MAAMI,cAAcR,QAAQ;EACtC,MAAMS,UAAUD,UAAUV,SAAS;EAEnC,KAAK,MAAMG,OAAOO,WAAW;GAC3B,MAAME,cAAcT,IAAIU,WAAW,gBAAgB;GACnD,MAAMC,QAAQH,UAAU,SAASR,IAAIV,GAAE,MAAO;GAE9CgB,YAAYF,KACV,2BAA2BD,KAAI,GAAIQ,QAAQF,YAAW,IAAKT,IAAIY,YAAW,oBAAqBC,KAAKC,UAAUd,IAAIe,KAAK,GACzH;GAEA,MAAMC,WAAWb,KAAKc,QAAQ,mBAAmB,GAAG;GACpD,MAAMC,SAASlB,IAAIV,GAAG2B,QAAQ,mBAAmB,GAAG;GACpD,MAAME,WAAWX,UACb,UAAUQ,SAAQ,GAAIE,WACtB,UAAUF;GAEd,MAAMI,gBAAgBjC,mBAAmBe,IAAIF,IAAIV,EAAE,KAAKU,IAAIqB;GAE5D5B,MAAM0B,YAAY;IAChBG,MAAM;IACNV,aAAa,+CAA+CT,KAAI,GAAIK,UAAU,SAASR,IAAIV,GAAE,KAAM,GAAE,0FAA2FU,IAAIY;IACpMY,YAAYJ;IACZK,YAAY,OAAOC,WAAW;KAC5B,IAAI;MACF,WAAW,MAAMC,eAAeD,OAAOE,KAAKC,aAAa,GACvDxC,YAAYW,IAAIV,KAAKV,SAASD,aAAaC,MAAM+C,WAAW,CAAC;KAEjE,QAAQ,CACN;IAEJ;IACAG,SAAS,OAAOC,iBAA0B;KACxC1C,YAAYW,IAAIV,KAAKV,SAASD,aAAaC,MAAMmD,YAAY,CAAC;KAC9D,OAAO,EAAEC,SAAS,KAAK;IACzB;GACF;EACF;CACF;CAEA,OAAO;EAAExC,QAAQc,YAAY2B,KAAK,IAAI;EAAGxC;CAAM;AACjD"}
@@ -0,0 +1,58 @@
1
+ import { Unsubscribe } from "../../types/unsubscribe.js";
2
+ import { Tool } from "assistant-stream";
3
+
4
+ //#region src/react/interactables-legacy/scopes.d.ts
5
+ /**
6
+ * Schema type matching Tool["parameters"] from assistant-stream.
7
+ * Accepts both StandardSchemaV1 and JSONSchema7.
8
+ */
9
+ type InteractableStateSchema = NonNullable<Extract<Tool, {
10
+ parameters: unknown;
11
+ }>["parameters"]>;
12
+ type InteractableDefinition = {
13
+ id: string;
14
+ name: string;
15
+ description: string;
16
+ stateSchema: InteractableStateSchema;
17
+ state: unknown;
18
+ selected?: boolean | undefined;
19
+ };
20
+ type InteractableRegistration = {
21
+ id: string;
22
+ name: string;
23
+ description: string;
24
+ stateSchema: InteractableStateSchema;
25
+ initialState: unknown;
26
+ selected?: boolean | undefined;
27
+ };
28
+ type InteractablePersistenceStatus = {
29
+ isPending: boolean;
30
+ error: unknown;
31
+ };
32
+ type InteractablesState = {
33
+ /** Keyed by instance id */definitions: Record<string, InteractableDefinition>; /** Per-id persistence sync status */
34
+ persistence: Record<string, InteractablePersistenceStatus>;
35
+ };
36
+ type InteractablePersistedState = Record<string, {
37
+ name: string;
38
+ state: unknown;
39
+ }>;
40
+ type InteractablePersistenceAdapter = {
41
+ save(state: InteractablePersistedState): void | Promise<void>;
42
+ };
43
+ type InteractablesMethods = {
44
+ getState(): InteractablesState;
45
+ register(def: InteractableRegistration): Unsubscribe;
46
+ setState(id: string, updater: (prev: unknown) => unknown): void;
47
+ setSelected(id: string, selected: boolean): void;
48
+ exportState(): InteractablePersistedState;
49
+ importState(saved: InteractablePersistedState): void;
50
+ setPersistenceAdapter(adapter: InteractablePersistenceAdapter | undefined): void;
51
+ flush(): Promise<void>;
52
+ };
53
+ type InteractablesClientSchema = {
54
+ methods: InteractablesMethods;
55
+ };
56
+ //#endregion
57
+ export { InteractableDefinition, InteractablePersistedState, InteractablePersistenceAdapter, InteractablePersistenceStatus, InteractableRegistration, InteractableStateSchema, InteractablesClientSchema, InteractablesMethods, InteractablesState };
58
+ //# sourceMappingURL=scopes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scopes.d.ts","names":[],"sources":["../../../src/react/interactables-legacy/scopes.ts"],"mappings":";;;;;;;AAOA;KAAY,uBAAA,GAA0B,WAAA,CACpC,OAAA,CAAQ,IAAA;EAAQ,UAAA;AAAA;AAAA,KAGN,sBAAA;EACV,EAAA;EACA,IAAA;EACA,WAAA;EACA,WAAA,EAAa,uBAAuB;EACpC,KAAA;EACA,QAAA;AAAA;AAAA,KAGU,wBAAA;EACV,EAAA;EACA,IAAA;EACA,WAAA;EACA,WAAA,EAAa,uBAAuB;EACpC,YAAA;EACA,QAAA;AAAA;AAAA,KAGU,6BAAA;EACV,SAAA;EACA,KAAK;AAAA;AAAA,KAGK,kBAAA;EAjBF,2BAmBR,WAAA,EAAa,MAAA,SAAe,sBAAA,GAhBlB;EAkBV,WAAA,EAAa,MAAA,SAAe,6BAAA;AAAA;AAAA,KAGlB,0BAAA,GAA6B,MAAM;EAE3C,IAAA;EAAc,KAAA;AAAA;AAAA,KAGN,8BAAA;EACV,IAAA,CAAK,KAAA,EAAO,0BAAA,UAAoC,OAAO;AAAA;AAAA,KAG7C,oBAAA;EACV,QAAA,IAAY,kBAAA;EACZ,QAAA,CAAS,GAAA,EAAK,wBAAA,GAA2B,WAAA;EACzC,QAAA,CAAS,EAAA,UAAY,OAAA,GAAU,IAAA;EAC/B,WAAA,CAAY,EAAA,UAAY,QAAA;EACxB,WAAA,IAAe,0BAAA;EACf,WAAA,CAAY,KAAA,EAAO,0BAAA;EACnB,qBAAA,CACE,OAAA,EAAS,8BAAA;EAEX,KAAA,IAAS,OAAA;AAAA;AAAA,KAGC,yBAAA;EACV,OAAA,EAAS,oBAAoB;AAAA"}
File without changes
@@ -0,0 +1,31 @@
1
+ import { InteractableStateSchema } from "./scopes.js";
2
+
3
+ //#region src/react/interactables-legacy/useAssistantInteractable.d.ts
4
+ /**
5
+ * @deprecated Since 2026-06-14 — migrate to the Unstable / Experimental API.
6
+ * Scheduled for removal on/after 2026-09-14. See
7
+ * {@link https://www.assistant-ui.com/docs/tools/interactables#migrating-from-the-previous-api | Interactables migration guide}.
8
+ */
9
+ type AssistantInteractableProps = {
10
+ description: string;
11
+ stateSchema: InteractableStateSchema;
12
+ initialState: unknown;
13
+ id?: string;
14
+ selected?: boolean;
15
+ };
16
+ /**
17
+ * @deprecated Since 2026-06-14 — migrate to the Unstable / Experimental API.
18
+ * Scheduled for removal on/after 2026-09-14. See
19
+ * {@link https://www.assistant-ui.com/docs/tools/interactables#migrating-from-the-previous-api | Interactables migration guide}.
20
+ *
21
+ * Registers an interactable with the AI assistant.
22
+ *
23
+ * This hook handles registration only. To read and write the interactable's
24
+ * state, use {@link useInteractableState} with the returned id.
25
+ *
26
+ * @returns The interactable instance id.
27
+ */
28
+ declare const useAssistantInteractable: (name: string, config: AssistantInteractableProps) => string;
29
+ //#endregion
30
+ export { AssistantInteractableProps, useAssistantInteractable };
31
+ //# sourceMappingURL=useAssistantInteractable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useAssistantInteractable.d.ts","names":[],"sources":["../../../src/react/interactables-legacy/useAssistantInteractable.ts"],"mappings":";;;;;AASA;;;KAAY,0BAAA;EACV,WAAA;EACA,WAAA,EAAa,uBAAuB;EACpC,YAAA;EACA,EAAA;EACA,QAAA;AAAA;;AAAQ;AAeV;;;;;;;;AAEoC;;cAFvB,wBAAA,GACX,IAAA,UACA,MAAA,EAAQ,0BAA0B"}
@@ -1,7 +1,11 @@
1
- import { useEffect, useId, useRef } from "@assistant-ui/tap/react-shim";
2
1
  import { useAui } from "@assistant-ui/store";
3
- //#region src/react/model-context/useAssistantInteractable.ts
2
+ import { useEffect, useId, useRef } from "@assistant-ui/tap/react-shim";
3
+ //#region src/react/interactables-legacy/useAssistantInteractable.ts
4
4
  /**
5
+ * @deprecated Since 2026-06-14 — migrate to the Unstable / Experimental API.
6
+ * Scheduled for removal on/after 2026-09-14. See
7
+ * {@link https://www.assistant-ui.com/docs/tools/interactables#migrating-from-the-previous-api | Interactables migration guide}.
8
+ *
5
9
  * Registers an interactable with the AI assistant.
6
10
  *
7
11
  * This hook handles registration only. To read and write the interactable's
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useAssistantInteractable.js","names":["useEffect","useId","useRef","useAui","InteractableStateSchema","AssistantInteractableProps","description","stateSchema","initialState","id","selected","useAssistantInteractable","name","config","aui","autoId","replace","stateSchemaRef","current","initialStateRef","interactables","register"],"sources":["../../../src/react/interactables-legacy/useAssistantInteractable.ts"],"sourcesContent":["import { useEffect, useId, useRef } from \"react\";\nimport { useAui } from \"@assistant-ui/store\";\nimport type { InteractableStateSchema } from \"./scopes\";\n\n/**\n * @deprecated Since 2026-06-14 — migrate to the Unstable / Experimental API.\n * Scheduled for removal on/after 2026-09-14. See\n * {@link https://www.assistant-ui.com/docs/tools/interactables#migrating-from-the-previous-api | Interactables migration guide}.\n */\nexport type AssistantInteractableProps = {\n description: string;\n stateSchema: InteractableStateSchema;\n initialState: unknown;\n id?: string;\n selected?: boolean;\n};\n\n/**\n * @deprecated Since 2026-06-14 — migrate to the Unstable / Experimental API.\n * Scheduled for removal on/after 2026-09-14. See\n * {@link https://www.assistant-ui.com/docs/tools/interactables#migrating-from-the-previous-api | Interactables migration guide}.\n *\n * Registers an interactable with the AI assistant.\n *\n * This hook handles registration only. To read and write the interactable's\n * state, use {@link useInteractableState} with the returned id.\n *\n * @returns The interactable instance id.\n */\nexport const useAssistantInteractable = (\n name: string,\n config: AssistantInteractableProps,\n): string => {\n const aui = useAui();\n\n const autoId = useId().replace(/[^a-zA-Z0-9]/g, \"\");\n const id = config.id ?? autoId;\n\n const stateSchemaRef = useRef(config.stateSchema);\n stateSchemaRef.current = config.stateSchema;\n const initialStateRef = useRef(config.initialState);\n initialStateRef.current = config.initialState;\n\n useEffect(() => {\n return aui.interactables().register({\n id,\n name,\n description: config.description,\n stateSchema: stateSchemaRef.current,\n initialState: initialStateRef.current,\n selected: config.selected,\n });\n }, [aui, id, name, config.description, config.selected]);\n\n return id;\n};\n"],"mappings":";;;;;;;;;;;;;;;AA6BA,MAAaW,4BACXC,MACAC,WACW;CACX,MAAMC,MAAMX,OAAO;CAEnB,MAAMY,SAASd,MAAM,CAAC,CAACe,QAAQ,iBAAiB,EAAE;CAClD,MAAMP,KAAKI,OAAOJ,MAAMM;CAExB,MAAME,iBAAiBf,OAAOW,OAAON,WAAW;CAChDU,eAAeC,UAAUL,OAAON;CAChC,MAAMY,kBAAkBjB,OAAOW,OAAOL,YAAY;CAClDW,gBAAgBD,UAAUL,OAAOL;CAEjCR,gBAAgB;EACd,OAAOc,IAAIM,cAAc,CAAC,CAACC,SAAS;GAClCZ;GACAG;GACAN,aAAaO,OAAOP;GACpBC,aAAaU,eAAeC;GAC5BV,cAAcW,gBAAgBD;GAC9BR,UAAUG,OAAOH;EACnB,CAAC;CACH,GAAG;EAACI;EAAKL;EAAIG;EAAMC,OAAOP;EAAaO,OAAOH;CAAQ,CAAC;CAEvD,OAAOD;AACT"}
@@ -0,0 +1,21 @@
1
+ //#region src/react/interactables-legacy/useInteractableState.d.ts
2
+ type StateUpdater<TState> = TState | ((prev: TState) => TState);
3
+ /**
4
+ * Reads and writes the state of a registered interactable.
5
+ *
6
+ * Pair with {@link useAssistantInteractable} which handles registration.
7
+ *
8
+ * @deprecated Since 2026-06-14 — migrate to the Unstable / Experimental API.
9
+ * Scheduled for removal on/after 2026-09-14. See
10
+ * {@link https://www.assistant-ui.com/docs/tools/interactables#migrating-from-the-previous-api | Interactables migration guide}.
11
+ */
12
+ declare const useInteractableState: <TState>(id: string, fallback: TState) => [TState, {
13
+ setState: (updater: StateUpdater<TState>) => void;
14
+ setSelected: (selected: boolean) => void;
15
+ isPending: boolean;
16
+ error: unknown;
17
+ flush: () => Promise<void>;
18
+ }];
19
+ //#endregion
20
+ export { useInteractableState };
21
+ //# sourceMappingURL=useInteractableState.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useInteractableState.d.ts","names":[],"sources":["../../../src/react/interactables-legacy/useInteractableState.ts"],"mappings":";KAGK,YAAA,WAAuB,MAAA,KAAW,IAAA,EAAM,MAAA,KAAW,MAAA;;;;;;;;;;cAW3C,oBAAA,WACX,EAAA,UACA,QAAA,EAAU,MAAA,MAEV,MAAA;EAEE,QAAA,GAAW,OAAA,EAAS,YAAA,CAAa,MAAA;EACjC,WAAA,GAAc,QAAA;EACd,SAAA;EACA,KAAA;EACA,KAAA,QAAa,OAAA;AAAA"}
@@ -0,0 +1,84 @@
1
+ import { useAui, useAuiState } from "@assistant-ui/store";
2
+ import { c } from "@assistant-ui/tap/react-shim/compiler-runtime";
3
+ //#region src/react/interactables-legacy/useInteractableState.ts
4
+ /**
5
+ * Reads and writes the state of a registered interactable.
6
+ *
7
+ * Pair with {@link useAssistantInteractable} which handles registration.
8
+ *
9
+ * @deprecated Since 2026-06-14 — migrate to the Unstable / Experimental API.
10
+ * Scheduled for removal on/after 2026-09-14. See
11
+ * {@link https://www.assistant-ui.com/docs/tools/interactables#migrating-from-the-previous-api | Interactables migration guide}.
12
+ */
13
+ const useInteractableState = (id, fallback) => {
14
+ const $ = c(19);
15
+ const aui = useAui();
16
+ const state = useAuiState((s) => s.interactables.definitions[id]?.state) ?? fallback;
17
+ let t0;
18
+ if ($[0] !== id) {
19
+ t0 = (s_0) => s_0.interactables.persistence[id];
20
+ $[0] = id;
21
+ $[1] = t0;
22
+ } else t0 = $[1];
23
+ const persistenceStatus = useAuiState(t0);
24
+ let t1;
25
+ if ($[2] !== aui || $[3] !== id) {
26
+ t1 = (updater) => {
27
+ aui.interactables().setState(id, (prev) => {
28
+ if (typeof updater === "function") return updater(prev);
29
+ return updater;
30
+ });
31
+ };
32
+ $[2] = aui;
33
+ $[3] = id;
34
+ $[4] = t1;
35
+ } else t1 = $[4];
36
+ const setState = t1;
37
+ let t2;
38
+ if ($[5] !== aui || $[6] !== id) {
39
+ t2 = (selected) => {
40
+ aui.interactables().setSelected(id, selected);
41
+ };
42
+ $[5] = aui;
43
+ $[6] = id;
44
+ $[7] = t2;
45
+ } else t2 = $[7];
46
+ const setSelected = t2;
47
+ let t3;
48
+ if ($[8] !== aui) {
49
+ t3 = () => aui.interactables().flush();
50
+ $[8] = aui;
51
+ $[9] = t3;
52
+ } else t3 = $[9];
53
+ const flush = t3;
54
+ const t4 = persistenceStatus?.isPending ?? false;
55
+ const t5 = persistenceStatus?.error;
56
+ let t6;
57
+ if ($[10] !== flush || $[11] !== setSelected || $[12] !== setState || $[13] !== t4 || $[14] !== t5) {
58
+ t6 = {
59
+ setState,
60
+ setSelected,
61
+ isPending: t4,
62
+ error: t5,
63
+ flush
64
+ };
65
+ $[10] = flush;
66
+ $[11] = setSelected;
67
+ $[12] = setState;
68
+ $[13] = t4;
69
+ $[14] = t5;
70
+ $[15] = t6;
71
+ } else t6 = $[15];
72
+ let t7;
73
+ if ($[16] !== state || $[17] !== t6) {
74
+ t7 = [state, t6];
75
+ $[16] = state;
76
+ $[17] = t6;
77
+ $[18] = t7;
78
+ } else t7 = $[18];
79
+ return t7;
80
+ };
81
+ //#endregion
82
+ export { useInteractableState };
83
+
84
+ //# sourceMappingURL=useInteractableState.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useInteractableState.js","names":["useCallback","useAui","useAuiState","StateUpdater","TState","prev","useInteractableState","id","fallback","$","_c","aui","state","s","interactables","definitions","t0","s_0","persistence","persistenceStatus","t1","updater","setState","t2","selected","setSelected","t3","flush","t4","isPending","t5","error","t6","t7"],"sources":["../../../src/react/interactables-legacy/useInteractableState.ts"],"sourcesContent":["import { useCallback } from \"react\";\nimport { useAui, useAuiState } from \"@assistant-ui/store\";\n\ntype StateUpdater<TState> = TState | ((prev: TState) => TState);\n\n/**\n * Reads and writes the state of a registered interactable.\n *\n * Pair with {@link useAssistantInteractable} which handles registration.\n *\n * @deprecated Since 2026-06-14 — migrate to the Unstable / Experimental API.\n * Scheduled for removal on/after 2026-09-14. See\n * {@link https://www.assistant-ui.com/docs/tools/interactables#migrating-from-the-previous-api | Interactables migration guide}.\n */\nexport const useInteractableState = <TState>(\n id: string,\n fallback: TState,\n): [\n TState,\n {\n setState: (updater: StateUpdater<TState>) => void;\n setSelected: (selected: boolean) => void;\n isPending: boolean;\n error: unknown;\n flush: () => Promise<void>;\n },\n] => {\n const aui = useAui();\n\n const state =\n (useAuiState((s) => s.interactables.definitions[id]?.state) as TState) ??\n (fallback as TState);\n\n const persistenceStatus = useAuiState((s) => s.interactables.persistence[id]);\n\n const setState = useCallback(\n (updater: StateUpdater<TState>) => {\n aui.interactables().setState(id, (prev) => {\n if (typeof updater === \"function\") {\n return (updater as (prev: TState) => TState)(prev as TState);\n }\n return updater;\n });\n },\n [aui, id],\n );\n\n const setSelected = useCallback(\n (selected: boolean) => {\n aui.interactables().setSelected(id, selected);\n },\n [aui, id],\n );\n\n const flush = useCallback(() => aui.interactables().flush(), [aui]);\n\n return [\n state,\n {\n setState,\n setSelected,\n isPending: persistenceStatus?.isPending ?? false,\n error: persistenceStatus?.error,\n flush,\n },\n ];\n};\n"],"mappings":";;;;;;;;;;;;AAcA,MAAaM,wBAAuBC,IAAAC,aAAA;CAAA,MAAAC,IAAAC,EAAA,EAAA;CAalC,MAAAC,MAAYV,OAAO;CAEnB,MAAAW,QACGV,aAAYW,MAAOA,EAACC,cAAcC,YAAaR,GAAU,EAAAK,KAAA,KACzDJ;CAAoB,IAAAQ;CAAA,IAAAP,EAAA,OAAAF,IAAA;EAEeS,MAAAC,QAAOJ,IAACC,cAAcI,YAAaX;EAAGE,EAAA,KAAAF;EAAAE,EAAA,KAAAO;CAAA,OAAAA,KAAAP,EAAA;CAA5E,MAAAU,oBAA0BjB,YAAYc,EAAsC;CAAE,IAAAI;CAAA,IAAAX,EAAA,OAAAE,OAAAF,EAAA,OAAAF,IAAA;EAG5Ea,MAAAC,YAAA;GACEV,IAAGG,cAAe,CAAC,CAAAQ,SAAUf,KAAIF,SAAA;IAC/B,IAAI,OAAOgB,YAAY,YAAU,OACvBA,QAAqChB,IAAc;IAC5D,OACMgB;GAAO,CACf;EAAC;EACHZ,EAAA,KAAAE;EAAAF,EAAA,KAAAF;EAAAE,EAAA,KAAAW;CAAA,OAAAA,KAAAX,EAAA;CARH,MAAAa,WAAiBF;CAUf,IAAAG;CAAA,IAAAd,EAAA,OAAAE,OAAAF,EAAA,OAAAF,IAAA;EAGAgB,MAAAC,aAAA;GACEb,IAAGG,cAAe,CAAC,CAAAW,YAAalB,IAAIiB,QAAQ;EAAC;EAC9Cf,EAAA,KAAAE;EAAAF,EAAA,KAAAF;EAAAE,EAAA,KAAAc;CAAA,OAAAA,KAAAd,EAAA;CAHH,MAAAgB,cAAoBF;CAKlB,IAAAG;CAAA,IAAAjB,EAAA,OAAAE,KAAA;EAEwBe,WAAMf,IAAGG,cAAe,CAAC,CAAAa,MAAO;EAAClB,EAAA,KAAAE;EAAAF,EAAA,KAAAiB;CAAA,OAAAA,KAAAjB,EAAA;CAA3D,MAAAkB,QAAcD;CAOC,MAAAE,KAAAT,mBAAiBU,aAAjB;CACJ,MAAAC,KAAAX,mBAAiBY;CAAO,IAAAC;CAAA,IAAAvB,EAAA,QAAAkB,SAAAlB,EAAA,QAAAgB,eAAAhB,EAAA,QAAAa,YAAAb,EAAA,QAAAmB,MAAAnB,EAAA,QAAAqB,IAAA;EAJjCE,KAAA;GAAAV;GAAAG;GAAAI,WAGaD;GAAqCG,OACzCD;GAAwBH;EAEjC;EAAClB,EAAA,MAAAkB;EAAAlB,EAAA,MAAAgB;EAAAhB,EAAA,MAAAa;EAAAb,EAAA,MAAAmB;EAAAnB,EAAA,MAAAqB;EAAArB,EAAA,MAAAuB;CAAA,OAAAA,KAAAvB,EAAA;CAAA,IAAAwB;CAAA,IAAAxB,EAAA,QAAAG,SAAAH,EAAA,QAAAuB,IAAA;EARIC,KAAA,CACLrB,OACAoB,EAMC;EACFvB,EAAA,MAAAG;EAAAH,EAAA,MAAAuB;EAAAvB,EAAA,MAAAwB;CAAA,OAAAA,KAAAxB,EAAA;CAAA,OATMwB;AASN"}