@assistant-ui/core 0.2.18 → 0.2.19

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 (228) 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.js +1 -1
  82. package/dist/react/primitives/message/MessageAttachments.js +1 -1
  83. package/dist/react/primitives/message/MessageGroupedParts.js +1 -1
  84. package/dist/react/primitives/message/MessageParts.js +1 -1
  85. package/dist/react/primitives/message/MessageQuote.js +1 -1
  86. package/dist/react/primitives/part/PartMessages.d.ts +5 -2
  87. package/dist/react/primitives/part/PartMessages.d.ts.map +1 -1
  88. package/dist/react/primitives/part/PartMessages.js +8 -8
  89. package/dist/react/primitives/part/PartMessages.js.map +1 -1
  90. package/dist/react/primitives/thread/ThreadMessages.d.ts +31 -1
  91. package/dist/react/primitives/thread/ThreadMessages.d.ts.map +1 -1
  92. package/dist/react/primitives/thread/ThreadMessages.js +64 -2
  93. package/dist/react/primitives/thread/ThreadMessages.js.map +1 -1
  94. package/dist/react/primitives/thread/ThreadSuggestions.js +1 -1
  95. package/dist/react/primitives/threadList/ThreadListItems.js +1 -1
  96. package/dist/react/providers/MessageByIdProvider.d.ts +9 -0
  97. package/dist/react/providers/MessageByIdProvider.d.ts.map +1 -0
  98. package/dist/react/providers/MessageByIdProvider.js +57 -0
  99. package/dist/react/providers/MessageByIdProvider.js.map +1 -0
  100. package/dist/react/providers/ReadonlyThreadProvider.js +1 -1
  101. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js +1 -1
  102. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts +3 -0
  103. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
  104. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js +16 -1
  105. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js.map +1 -1
  106. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js +1 -1
  107. package/dist/react/runtimes/cloud/auiV0.js +1 -1
  108. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js +1 -1
  109. package/dist/react/runtimes/createRuntimeExtras.d.ts +20 -0
  110. package/dist/react/runtimes/createRuntimeExtras.d.ts.map +1 -0
  111. package/dist/react/runtimes/createRuntimeExtras.js +43 -0
  112. package/dist/react/runtimes/createRuntimeExtras.js.map +1 -0
  113. package/dist/react/runtimes/useLocalRuntime.js +1 -1
  114. package/dist/react/runtimes/useRemoteThreadListRuntime.d.ts.map +1 -1
  115. package/dist/react/runtimes/useRemoteThreadListRuntime.js +6 -2
  116. package/dist/react/runtimes/useRemoteThreadListRuntime.js.map +1 -1
  117. package/dist/react/runtimes/useStreamingTiming.d.ts +26 -0
  118. package/dist/react/runtimes/useStreamingTiming.d.ts.map +1 -0
  119. package/dist/react/runtimes/useStreamingTiming.js +43 -0
  120. package/dist/react/runtimes/useStreamingTiming.js.map +1 -0
  121. package/dist/react/types/scopes/interactables.d.ts +40 -24
  122. package/dist/react/types/scopes/interactables.d.ts.map +1 -1
  123. package/dist/react/types/store-augmentation.d.ts +3 -1
  124. package/dist/react/types/store-augmentation.d.ts.map +1 -1
  125. package/dist/react/utils/useJSONEqual.d.ts +11 -0
  126. package/dist/react/utils/useJSONEqual.d.ts.map +1 -0
  127. package/dist/react/utils/useJSONEqual.js +30 -0
  128. package/dist/react/utils/useJSONEqual.js.map +1 -0
  129. package/dist/runtime/base/base-composer-runtime-core.d.ts +5 -0
  130. package/dist/runtime/base/base-composer-runtime-core.d.ts.map +1 -1
  131. package/dist/runtime/base/base-composer-runtime-core.js +13 -0
  132. package/dist/runtime/base/base-composer-runtime-core.js.map +1 -1
  133. package/dist/runtime/base/default-edit-composer-runtime-core.d.ts.map +1 -1
  134. package/dist/runtime/base/default-edit-composer-runtime-core.js +6 -1
  135. package/dist/runtime/base/default-edit-composer-runtime-core.js.map +1 -1
  136. package/dist/runtime/base/default-thread-composer-runtime-core.d.ts.map +1 -1
  137. package/dist/runtime/base/default-thread-composer-runtime-core.js +4 -1
  138. package/dist/runtime/base/default-thread-composer-runtime-core.js.map +1 -1
  139. package/dist/runtime/utils/message-repository.d.ts +1 -0
  140. package/dist/runtime/utils/message-repository.d.ts.map +1 -1
  141. package/dist/runtime/utils/message-repository.js +6 -3
  142. package/dist/runtime/utils/message-repository.js.map +1 -1
  143. package/dist/runtime/utils/streaming-timing.d.ts +59 -0
  144. package/dist/runtime/utils/streaming-timing.d.ts.map +1 -0
  145. package/dist/runtime/utils/streaming-timing.js +76 -0
  146. package/dist/runtime/utils/streaming-timing.js.map +1 -0
  147. package/dist/runtime/utils/thread-message-like.js +2 -1
  148. package/dist/runtime/utils/thread-message-like.js.map +1 -1
  149. package/dist/runtimes/external-store/external-store-adapter.d.ts +26 -1
  150. package/dist/runtimes/external-store/external-store-adapter.d.ts.map +1 -1
  151. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts +9 -0
  152. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts.map +1 -1
  153. package/dist/runtimes/external-store/external-store-thread-runtime-core.js +19 -0
  154. package/dist/runtimes/external-store/external-store-thread-runtime-core.js.map +1 -1
  155. package/dist/runtimes/local/local-thread-runtime-core.d.ts.map +1 -1
  156. package/dist/runtimes/local/local-thread-runtime-core.js +1 -1
  157. package/dist/runtimes/local/local-thread-runtime-core.js.map +1 -1
  158. package/dist/runtimes/remote-thread-list/types.d.ts +12 -0
  159. package/dist/runtimes/remote-thread-list/types.d.ts.map +1 -1
  160. package/dist/store/clients/suggestions.js +1 -1
  161. package/dist/store/clients/thread-message-client.js +1 -1
  162. package/dist/store/runtime-clients/composer-runtime-client.js +1 -1
  163. package/dist/store/runtime-clients/message-runtime-client.js +1 -1
  164. package/dist/store/runtime-clients/thread-list-item-runtime-client.js +1 -1
  165. package/dist/store/runtime-clients/thread-runtime-client.js +1 -1
  166. package/dist/tests/remote-thread-list-test-helpers.d.ts +1 -1
  167. package/dist/tests/remote-thread-list-test-helpers.d.ts.map +1 -1
  168. package/dist/tests/remote-thread-list-test-helpers.js +3 -2
  169. package/dist/tests/remote-thread-list-test-helpers.js.map +1 -1
  170. package/package.json +9 -9
  171. package/src/index.ts +17 -0
  172. package/src/internal.ts +7 -0
  173. package/src/model-context/interactable-composer-metadata.test.ts +550 -0
  174. package/src/model-context/interactable-composer-metadata.ts +395 -0
  175. package/src/model-context/registry.ts +5 -0
  176. package/src/model-context/types.ts +12 -0
  177. package/src/react/client/Interactables.test.ts +358 -0
  178. package/src/react/client/Interactables.ts +339 -86
  179. package/src/react/client/interactable-model-context.test.ts +418 -0
  180. package/src/react/client/interactable-model-context.ts +252 -58
  181. package/src/react/index.ts +72 -3
  182. package/src/react/interactables-legacy/Interactables.ts +332 -0
  183. package/src/react/interactables-legacy/interactable-model-context.test.ts +54 -0
  184. package/src/react/interactables-legacy/interactable-model-context.ts +80 -0
  185. package/src/react/interactables-legacy/scopes.ts +66 -0
  186. package/src/react/{model-context → interactables-legacy}/useAssistantInteractable.ts +10 -1
  187. package/src/react/interactables-legacy/useInteractableState.ts +67 -0
  188. package/src/react/model-context/interactableTool.tsx +175 -0
  189. package/src/react/model-context/useInteractable.ts +233 -0
  190. package/src/react/model-context/useInteractableState.ts +31 -23
  191. package/src/react/model-context/useInteractableVersions.ts +48 -0
  192. package/src/react/primitive-hooks/useThreadMessageIds.ts +27 -0
  193. package/src/react/primitives/part/PartMessages.test.tsx +17 -0
  194. package/src/react/primitives/part/PartMessages.tsx +13 -8
  195. package/src/react/primitives/thread/ThreadMessages.tsx +67 -0
  196. package/src/react/providers/MessageByIdProvider.tsx +23 -0
  197. package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.tsx +21 -1
  198. package/src/react/runtimes/createRuntimeExtras.test.ts +58 -0
  199. package/src/react/runtimes/createRuntimeExtras.ts +68 -0
  200. package/src/react/runtimes/createRuntimeExtras.use.test.ts +50 -0
  201. package/src/react/runtimes/useRemoteThreadListRuntime.ts +13 -1
  202. package/src/react/runtimes/useStreamingTiming.ts +68 -0
  203. package/src/react/types/scopes/interactables.ts +45 -23
  204. package/src/react/types/store-augmentation.ts +4 -2
  205. package/src/react/utils/useJSONEqual.ts +20 -0
  206. package/src/runtime/base/base-composer-runtime-core.ts +13 -0
  207. package/src/runtime/base/default-edit-composer-runtime-core.ts +18 -1
  208. package/src/runtime/base/default-thread-composer-runtime-core.ts +11 -1
  209. package/src/runtime/utils/message-repository.ts +11 -7
  210. package/src/runtime/utils/streaming-timing.test.ts +301 -0
  211. package/src/runtime/utils/streaming-timing.ts +161 -0
  212. package/src/runtime/utils/thread-message-like.ts +2 -1
  213. package/src/runtimes/external-store/external-store-adapter.ts +28 -0
  214. package/src/runtimes/external-store/external-store-thread-runtime-core.ts +33 -1
  215. package/src/runtimes/local/local-thread-runtime-core.ts +4 -1
  216. package/src/runtimes/remote-thread-list/types.ts +13 -0
  217. package/src/tests/MessageRepository.test.ts +2 -0
  218. package/src/tests/composer-can-send.test.ts +1 -0
  219. package/src/tests/default-edit-composer-runtime-core.test.ts +78 -1
  220. package/src/tests/default-thread-composer-runtime-core.test.ts +82 -0
  221. package/src/tests/external-store-thread-runtime-core.test.ts +337 -0
  222. package/src/tests/groupParts.test.ts +32 -0
  223. package/src/tests/remote-thread-list-reactive-threadId.test.ts +90 -0
  224. package/src/tests/remote-thread-list-test-helpers.ts +2 -1
  225. package/src/tests/thread-message-like.test.ts +50 -0
  226. package/dist/react/model-context/useAssistantInteractable.d.ts +0 -22
  227. package/dist/react/model-context/useAssistantInteractable.d.ts.map +0 -1
  228. package/dist/react/model-context/useAssistantInteractable.js.map +0 -1
@@ -0,0 +1,53 @@
1
+ import { Unstable_InteractableStateSchema } from "../types/scopes/interactables.js";
2
+ import { ToolDefinition } from "./toolbox.js";
3
+ import { Unstable_InferInteractableState, Unstable_InteractableVersionInfo } from "./useInteractable.js";
4
+ import { ReactNode } from "react";
5
+
6
+ //#region src/react/model-context/interactableTool.d.ts
7
+ type Unstable_InteractableToolRenderProps<TState> = {
8
+ /**
9
+ * The live state. While `streaming` is true, fields the model has not
10
+ * finished generating may still be missing.
11
+ */
12
+ state: TState;
13
+ setState: (updater: TState | ((prev: TState) => TState)) => void;
14
+ /**
15
+ * This message's version of the instance: its state as of this point in the
16
+ * conversation, whether it is the most recent edit, and a `restore()` back
17
+ * to it. `undefined` while streaming.
18
+ */
19
+ version: Unstable_InteractableVersionInfo<TState> | undefined;
20
+ id: string; /** True while the tool call's arguments are still streaming in. */
21
+ streaming: boolean;
22
+ };
23
+ type Unstable_InteractableToolConfig<TSchema extends Unstable_InteractableStateSchema> = {
24
+ description: string;
25
+ stateSchema: TSchema;
26
+ render: (props: Unstable_InteractableToolRenderProps<Unstable_InferInteractableState<TSchema>>) => ReactNode;
27
+ };
28
+ /**
29
+ * Defines a tool that creates a thread-scoped interactable from its arguments,
30
+ * for assignment to a toolkit entry — the entry key is the interactable name:
31
+ *
32
+ * ```tsx
33
+ * notepad: unstable_interactableTool({
34
+ * description: "A notepad the user can read and edit.",
35
+ * stateSchema: notepadSchema,
36
+ * render: (props) => <Notepad {...props} />,
37
+ * }),
38
+ * ```
39
+ *
40
+ * `render` shows at the creating call and — installed automatically — at every
41
+ * `update_{name}` call, with streaming previews, instance-id wiring, and
42
+ * registration handled. It receives the live `state`/`setState` plus this
43
+ * message's `version`; whether older messages render frozen history or stay
44
+ * live-editable is the render function's choice.
45
+ *
46
+ * @deprecated Unstable / Experimental (not actually removed).
47
+ */
48
+ declare const unstable_interactableTool: <TSchema extends Unstable_InteractableStateSchema>(config: Unstable_InteractableToolConfig<TSchema>) => ToolDefinition<Record<string, unknown>, {
49
+ success: true;
50
+ }>;
51
+ //#endregion
52
+ export { Unstable_InteractableToolConfig, Unstable_InteractableToolRenderProps, unstable_interactableTool };
53
+ //# sourceMappingURL=interactableTool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interactableTool.d.ts","names":[],"sources":["../../../src/react/model-context/interactableTool.tsx"],"mappings":";;;;;;KAWY,oCAAA;;AAAZ;;;EAKE,KAAA,EAAO,MAAA;EACP,QAAA,GAAW,OAAA,EAAS,MAAA,KAAW,IAAA,EAAM,MAAA,KAAW,MAAA;EAAX;;;;;EAMrC,OAAA,EAAS,gCAAA,CAAiC,MAAA;EAC1C,EAAA,UARA;EAUA,SAAA;AAAA;AAAA,KAGU,+BAAA,iBACM,gCAAA;EAEhB,WAAA;EACA,WAAA,EAAa,OAAA;EACb,MAAA,GACE,KAAA,EAAO,oCAAA,CACL,+BAAA,CAAgC,OAAA,OAE/B,SAAA;AAAA;;;;;;;AAZI;AAGX;;;;;;;;;;;;;cAoCa,yBAAA,mBACK,gCAAA,EAEhB,MAAA,EAAQ,+BAAA,CAAgC,OAAA,MACvC,cAAA,CAAe,MAAA;EAA2B,OAAA;AAAA"}
@@ -0,0 +1,188 @@
1
+ import { unstable_useInteractableState } from "./useInteractableState.js";
2
+ import { unstable_useInteractable } from "./useInteractable.js";
3
+ import { c } from "@assistant-ui/tap/react-shim/compiler-runtime";
4
+ import { Fragment, jsx } from "react/jsx-runtime";
5
+ //#region src/react/model-context/interactableTool.tsx
6
+ const noop = () => {};
7
+ /**
8
+ * Defines a tool that creates a thread-scoped interactable from its arguments,
9
+ * for assignment to a toolkit entry — the entry key is the interactable name:
10
+ *
11
+ * ```tsx
12
+ * notepad: unstable_interactableTool({
13
+ * description: "A notepad the user can read and edit.",
14
+ * stateSchema: notepadSchema,
15
+ * render: (props) => <Notepad {...props} />,
16
+ * }),
17
+ * ```
18
+ *
19
+ * `render` shows at the creating call and — installed automatically — at every
20
+ * `update_{name}` call, with streaming previews, instance-id wiring, and
21
+ * registration handled. It receives the live `state`/`setState` plus this
22
+ * message's `version`; whether older messages render frozen history or stay
23
+ * live-editable is the render function's choice.
24
+ *
25
+ * @deprecated Unstable / Experimental (not actually removed).
26
+ */
27
+ const unstable_interactableTool = (config) => {
28
+ const Anchor = (t0) => {
29
+ const $ = c(10);
30
+ const { name, id, initial } = t0;
31
+ let t1;
32
+ if ($[0] !== id || $[1] !== initial) {
33
+ t1 = {
34
+ id,
35
+ description: config.description,
36
+ stateSchema: config.stateSchema,
37
+ initialState: initial,
38
+ updateRender: UpdateToolUI
39
+ };
40
+ $[0] = id;
41
+ $[1] = initial;
42
+ $[2] = t1;
43
+ } else t1 = $[2];
44
+ const [state, t2] = unstable_useInteractable(name, t1);
45
+ const { id: resolvedId, setState, version } = t2;
46
+ let t3;
47
+ if ($[3] !== resolvedId || $[4] !== setState || $[5] !== state || $[6] !== version) {
48
+ t3 = config.render({
49
+ state,
50
+ setState,
51
+ version,
52
+ id: resolvedId,
53
+ streaming: false
54
+ });
55
+ $[3] = resolvedId;
56
+ $[4] = setState;
57
+ $[5] = state;
58
+ $[6] = version;
59
+ $[7] = t3;
60
+ } else t3 = $[7];
61
+ let t4;
62
+ if ($[8] !== t3) {
63
+ t4 = /* @__PURE__ */ jsx(Fragment, { children: t3 });
64
+ $[8] = t3;
65
+ $[9] = t4;
66
+ } else t4 = $[9];
67
+ return t4;
68
+ };
69
+ const StreamingUpdate = (t0) => {
70
+ const $ = c(6);
71
+ const { id } = t0;
72
+ const [state, t1] = unstable_useInteractableState(id);
73
+ const { setState } = t1;
74
+ if (state === void 0) return null;
75
+ let t2;
76
+ if ($[0] !== id || $[1] !== setState || $[2] !== state) {
77
+ t2 = config.render({
78
+ state,
79
+ setState,
80
+ version: void 0,
81
+ id,
82
+ streaming: true
83
+ });
84
+ $[0] = id;
85
+ $[1] = setState;
86
+ $[2] = state;
87
+ $[3] = t2;
88
+ } else t2 = $[3];
89
+ let t3;
90
+ if ($[4] !== t2) {
91
+ t3 = /* @__PURE__ */ jsx(Fragment, { children: t2 });
92
+ $[4] = t2;
93
+ $[5] = t3;
94
+ } else t3 = $[5];
95
+ return t3;
96
+ };
97
+ const UpdateToolUI = (t0) => {
98
+ const $ = c(9);
99
+ const { toolName, args, result } = t0;
100
+ if (!result) {
101
+ let t1;
102
+ if ($[0] !== args.id) {
103
+ t1 = typeof args.id === "string" ? /* @__PURE__ */ jsx(StreamingUpdate, { id: args.id }) : null;
104
+ $[0] = args.id;
105
+ $[1] = t1;
106
+ } else t1 = $[1];
107
+ return t1;
108
+ }
109
+ if (!result.success) return null;
110
+ let partial;
111
+ if ($[2] !== args) {
112
+ const { id: _id, ...t1 } = args;
113
+ partial = t1;
114
+ $[2] = args;
115
+ $[3] = partial;
116
+ } else partial = $[3];
117
+ let t1;
118
+ if ($[4] !== toolName) {
119
+ t1 = toolName.slice(7);
120
+ $[4] = toolName;
121
+ $[5] = t1;
122
+ } else t1 = $[5];
123
+ const t2 = partial;
124
+ let t3;
125
+ if ($[6] !== t1 || $[7] !== t2) {
126
+ t3 = /* @__PURE__ */ jsx(Anchor, {
127
+ name: t1,
128
+ initial: t2
129
+ });
130
+ $[6] = t1;
131
+ $[7] = t2;
132
+ $[8] = t3;
133
+ } else t3 = $[8];
134
+ return t3;
135
+ };
136
+ const InteractableToolUI = (t0) => {
137
+ const $ = c(9);
138
+ const { toolName, toolCallId, args, result } = t0;
139
+ const state = args;
140
+ if (!result) {
141
+ let t1;
142
+ if ($[0] !== state || $[1] !== toolCallId) {
143
+ t1 = config.render({
144
+ state,
145
+ setState: noop,
146
+ version: void 0,
147
+ id: toolCallId,
148
+ streaming: true
149
+ });
150
+ $[0] = state;
151
+ $[1] = toolCallId;
152
+ $[2] = t1;
153
+ } else t1 = $[2];
154
+ let t2;
155
+ if ($[3] !== t1) {
156
+ t2 = /* @__PURE__ */ jsx(Fragment, { children: t1 });
157
+ $[3] = t1;
158
+ $[4] = t2;
159
+ } else t2 = $[4];
160
+ return t2;
161
+ }
162
+ let t1;
163
+ if ($[5] !== state || $[6] !== toolCallId || $[7] !== toolName) {
164
+ t1 = /* @__PURE__ */ jsx(Anchor, {
165
+ name: toolName,
166
+ id: toolCallId,
167
+ initial: state
168
+ });
169
+ $[5] = state;
170
+ $[6] = toolCallId;
171
+ $[7] = toolName;
172
+ $[8] = t1;
173
+ } else t1 = $[8];
174
+ return t1;
175
+ };
176
+ return {
177
+ type: "frontend",
178
+ description: config.description,
179
+ parameters: config.stateSchema,
180
+ display: "standalone",
181
+ execute: async () => ({ success: true }),
182
+ render: InteractableToolUI
183
+ };
184
+ };
185
+ //#endregion
186
+ export { unstable_interactableTool };
187
+
188
+ //# sourceMappingURL=interactableTool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interactableTool.js","names":["ReactNode","Unstable_InteractableStateSchema","ToolDefinition","ToolCallMessagePartComponent","unstable_useInteractable","useInteractable","Unstable_InferInteractableState","Unstable_InteractableVersionInfo","unstable_useInteractableState","useInteractableState","Unstable_InteractableToolRenderProps","state","TState","setState","updater","prev","version","id","streaming","Unstable_InteractableToolConfig","description","stateSchema","TSchema","render","props","noop","UPDATE_TOOL_PREFIX","unstable_interactableTool","config","Record","success","UpdateArgs","UpdateResult","error","Anchor","t0","$","_c","name","initial","t1","initialState","updateRender","UpdateToolUI","t2","resolvedId","t3","t4","StreamingUpdate","undefined","toolName","args","result","partial","_id","slice","length","InteractableToolUI","toolCallId","type","parameters","display","execute","const"],"sources":["../../../src/react/model-context/interactableTool.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport type { Unstable_InteractableStateSchema } from \"../types/scopes/interactables\";\nimport type { ToolDefinition } from \"./toolbox\";\nimport type { ToolCallMessagePartComponent } from \"../types/MessagePartComponentTypes\";\nimport {\n unstable_useInteractable as useInteractable,\n type Unstable_InferInteractableState,\n type Unstable_InteractableVersionInfo,\n} from \"./useInteractable\";\nimport { unstable_useInteractableState as useInteractableState } from \"./useInteractableState\";\n\nexport type Unstable_InteractableToolRenderProps<TState> = {\n /**\n * The live state. While `streaming` is true, fields the model has not\n * finished generating may still be missing.\n */\n state: TState;\n setState: (updater: TState | ((prev: TState) => TState)) => void;\n /**\n * This message's version of the instance: its state as of this point in the\n * conversation, whether it is the most recent edit, and a `restore()` back\n * to it. `undefined` while streaming.\n */\n version: Unstable_InteractableVersionInfo<TState> | undefined;\n id: string;\n /** True while the tool call's arguments are still streaming in. */\n streaming: boolean;\n};\n\nexport type Unstable_InteractableToolConfig<\n TSchema extends Unstable_InteractableStateSchema,\n> = {\n description: string;\n stateSchema: TSchema;\n render: (\n props: Unstable_InteractableToolRenderProps<\n Unstable_InferInteractableState<TSchema>\n >,\n ) => ReactNode;\n};\n\nconst noop = () => {};\n\nconst UPDATE_TOOL_PREFIX = \"update_\";\n\n/**\n * Defines a tool that creates a thread-scoped interactable from its arguments,\n * for assignment to a toolkit entry — the entry key is the interactable name:\n *\n * ```tsx\n * notepad: unstable_interactableTool({\n * description: \"A notepad the user can read and edit.\",\n * stateSchema: notepadSchema,\n * render: (props) => <Notepad {...props} />,\n * }),\n * ```\n *\n * `render` shows at the creating call and — installed automatically — at every\n * `update_{name}` call, with streaming previews, instance-id wiring, and\n * registration handled. It receives the live `state`/`setState` plus this\n * message's `version`; whether older messages render frozen history or stay\n * live-editable is the render function's choice.\n *\n * @deprecated Unstable / Experimental (not actually removed).\n */\nexport const unstable_interactableTool = <\n TSchema extends Unstable_InteractableStateSchema,\n>(\n config: Unstable_InteractableToolConfig<TSchema>,\n): ToolDefinition<Record<string, unknown>, { success: true }> => {\n type TState = Unstable_InferInteractableState<TSchema>;\n type UpdateArgs = { id?: string | undefined } & Record<string, unknown>;\n type UpdateResult =\n | { success: true; id: string }\n | { success: false; error: string };\n\n const Anchor = ({\n name,\n id,\n initial,\n }: {\n name: string;\n id?: string | undefined;\n initial: TState;\n }) => {\n const [state, { id: resolvedId, setState, version }] = useInteractable(\n name,\n {\n id,\n description: config.description,\n stateSchema: config.stateSchema,\n initialState: initial,\n updateRender: UpdateToolUI,\n },\n );\n return (\n <>\n {config.render({\n state,\n setState,\n version,\n id: resolvedId,\n streaming: false,\n })}\n </>\n );\n };\n\n const StreamingUpdate = ({ id }: { id: string }) => {\n const [state, { setState }] = useInteractableState<TState>(id);\n if (state === undefined) return null;\n return (\n <>\n {config.render({\n state,\n setState,\n version: undefined,\n id,\n streaming: true,\n })}\n </>\n );\n };\n\n const UpdateToolUI: ToolCallMessagePartComponent<\n UpdateArgs,\n UpdateResult\n > = ({ toolName, args, result }) => {\n if (!result) {\n return typeof args.id === \"string\" ? (\n <StreamingUpdate id={args.id} />\n ) : null;\n }\n if (!result.success) return null;\n const { id: _id, ...partial } = args;\n // The interactable name is the creating tool's name (the toolkit entry\n // key), so the update tool's name reverses by stripping the prefix.\n return (\n <Anchor\n name={toolName.slice(UPDATE_TOOL_PREFIX.length)}\n initial={partial as TState}\n />\n );\n };\n\n const InteractableToolUI: ToolCallMessagePartComponent<\n Record<string, unknown>,\n { success: true }\n > = ({ toolName, toolCallId, args, result }) => {\n const state = args as TState;\n if (!result) {\n return (\n <>\n {config.render({\n state,\n setState: noop,\n version: undefined,\n id: toolCallId,\n streaming: true,\n })}\n </>\n );\n }\n return <Anchor name={toolName} id={toolCallId} initial={state} />;\n };\n\n return {\n type: \"frontend\",\n description: config.description,\n parameters: config.stateSchema,\n display: \"standalone\",\n execute: async () => ({ success: true as const }),\n render: InteractableToolUI,\n };\n};\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import { useEffect, useRef } from "@assistant-ui/tap/react-shim";
2
1
  import { useAui } from "@assistant-ui/store";
2
+ import { useEffect, useRef } from "@assistant-ui/tap/react-shim";
3
3
  //#region src/react/model-context/useAssistantContext.ts
4
4
  const useAssistantContext = (config) => {
5
5
  const { getContext, disabled = false } = config;
@@ -1,5 +1,5 @@
1
- import { useEffect } from "@assistant-ui/tap/react-shim";
2
1
  import { useAui } from "@assistant-ui/store";
2
+ import { useEffect } from "@assistant-ui/tap/react-shim";
3
3
  import { c } from "@assistant-ui/tap/react-shim/compiler-runtime";
4
4
  //#region src/react/model-context/useAssistantDataUI.ts
5
5
  /**
@@ -1,5 +1,5 @@
1
- import { useEffect } from "@assistant-ui/tap/react-shim";
2
1
  import { useAui } from "@assistant-ui/store";
2
+ import { useEffect } from "@assistant-ui/tap/react-shim";
3
3
  import { c } from "@assistant-ui/tap/react-shim/compiler-runtime";
4
4
  //#region src/react/model-context/useAssistantInstructions.ts
5
5
  const getInstructions = (instruction) => {
@@ -1,6 +1,6 @@
1
1
  import { isStandaloneToolDisplay, makeToolCallTextComponent } from "./toolbox.js";
2
- import { useEffect } from "@assistant-ui/tap/react-shim";
3
2
  import { useAui } from "@assistant-ui/store";
3
+ import { useEffect } from "@assistant-ui/tap/react-shim";
4
4
  import { c } from "@assistant-ui/tap/react-shim/compiler-runtime";
5
5
  //#region src/react/model-context/useAssistantTool.ts
6
6
  /**
@@ -1,5 +1,5 @@
1
- import { useEffect } from "@assistant-ui/tap/react-shim";
2
1
  import { useAui } from "@assistant-ui/store";
2
+ import { useEffect } from "@assistant-ui/tap/react-shim";
3
3
  import { c } from "@assistant-ui/tap/react-shim/compiler-runtime";
4
4
  //#region src/react/model-context/useAssistantToolUI.ts
5
5
  /**
@@ -1,5 +1,5 @@
1
- import { useEffect, useRef } from "@assistant-ui/tap/react-shim";
2
1
  import { useAui } from "@assistant-ui/store";
2
+ import { useEffect, useRef } from "@assistant-ui/tap/react-shim";
3
3
  //#region src/react/model-context/useAuiToolOverrides.ts
4
4
  /**
5
5
  * Overrides toolkit entries for the current assistant scope.
@@ -0,0 +1,73 @@
1
+ import { ToolCallMessagePartComponent } from "../types/MessagePartComponentTypes.js";
2
+ import { Unstable_InteractableStateSchema } from "../types/scopes/interactables.js";
3
+
4
+ //#region src/react/model-context/useInteractable.d.ts
5
+ /**
6
+ * The state type described by an interactable's `stateSchema`. Resolves the
7
+ * output type of a StandardSchemaV1 schema (e.g. Zod); plain JSON Schema
8
+ * falls back to `unknown`.
9
+ */
10
+ type Unstable_InferInteractableState<TSchema> = TSchema extends {
11
+ "~standard": {
12
+ types?: {
13
+ output: infer TOutput;
14
+ } | undefined;
15
+ };
16
+ } ? TOutput : unknown;
17
+ /**
18
+ * One message's version of an interactable, for components rendered inside
19
+ * tool-call parts. Show `state` to display history; call `restore()` to set
20
+ * the live instance back to it.
21
+ */
22
+ type Unstable_InteractableVersionInfo<TState> = {
23
+ /** The interactable's state as it was at this message. */state: TState; /** Whether this message holds the instance's most recent tool-driven version. */
24
+ isLatest: boolean; /** Sets the live state back to this version. */
25
+ restore: () => void;
26
+ };
27
+ /**
28
+ * Unstable / Experimental — the interactables API is still evolving and may change in any release.
29
+ * @deprecated Unstable / Experimental (not actually removed).
30
+ */
31
+ type Unstable_InteractableConfig<TSchema extends Unstable_InteractableStateSchema> = {
32
+ description: string;
33
+ stateSchema: TSchema;
34
+ initialState: Unstable_InferInteractableState<TSchema>; /** Unique instance ID; required to address this instance when multiple interactables share a name. Auto-generated if omitted. */
35
+ id?: string | undefined;
36
+ /**
37
+ * Component installed as the tool UI for this interactable's `update_{name}`
38
+ * tool calls, so a model edit re-renders the interactable at the message
39
+ * that made it instead of only mutating an earlier one. Prefer
40
+ * `unstable_interactableTool`, which wires this up. Pass a stable component reference;
41
+ * changing identity re-registers the tool UI.
42
+ */
43
+ updateRender?: ToolCallMessagePartComponent | undefined;
44
+ };
45
+ /**
46
+ * Registers an interactable with the AI assistant and returns its live state,
47
+ * like `useState` that the model can also read and update.
48
+ *
49
+ * Call this once per place that shows the interactable. Other components can
50
+ * read and write the same instance by passing its `id` to
51
+ * `unstable_useInteractableState`.
52
+ *
53
+ * For tool-created interactables rendered inside tool-call message parts,
54
+ * `version` carries this message's version of the instance — its state as of
55
+ * that point in the conversation, whether it is the most recent tool-driven
56
+ * version, and a `restore()` back to it. Whether older messages render frozen history or stay
57
+ * live-editable is the component's choice. Inside an `update_{name}` part the
58
+ * instance `id` is inferred from the call, so the same component works at the
59
+ * creating call and at update calls.
60
+ *
61
+ * @deprecated Unstable / Experimental (not actually removed).
62
+ */
63
+ declare const unstable_useInteractable: <TSchema extends Unstable_InteractableStateSchema>(name: string, config: Unstable_InteractableConfig<TSchema>) => readonly [Unstable_InferInteractableState<TSchema>, {
64
+ id: string;
65
+ version: Unstable_InteractableVersionInfo<Unstable_InferInteractableState<TSchema>> | undefined;
66
+ setState: (updater: Unstable_InferInteractableState<TSchema> | ((prev: Unstable_InferInteractableState<TSchema>) => Unstable_InferInteractableState<TSchema>)) => void;
67
+ isPending: boolean;
68
+ error: unknown;
69
+ flush: () => Promise<void>;
70
+ }];
71
+ //#endregion
72
+ export { Unstable_InferInteractableState, Unstable_InteractableConfig, Unstable_InteractableVersionInfo, unstable_useInteractable };
73
+ //# sourceMappingURL=useInteractable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useInteractable.d.ts","names":[],"sources":["../../../src/react/model-context/useInteractable.ts"],"mappings":";;;;;;AAkBA;;;KAAY,+BAAA,YAA2C,OAAO;EAC5D,WAAA;IAAe,KAAA;MAAU,MAAA;IAAA;EAAA;AAAA,IAEvB,OAAA;;;AAAO;AAQX;;KAAY,gCAAA;EAEG,0DAAb,KAAA,EAAO,MAAM,EAAb;EAEA,QAAA;EAEA,OAAA;AAAA;AAAO;AAOT;;;AAPS,KAOG,2BAAA,iBACM,gCAAA;EAEhB,WAAA;EACA,WAAA,EAAa,OAAA;EACb,YAAA,EAAc,+BAAA,CAAgC,OAAA,GAU/B;EARf,EAAA;EAQ2C;;;;;;;EAA3C,YAAA,GAAe,4BAAA;AAAA;;;;;AAA4B;AAsJ7C;;;;;;;;;;;;;cAAa,wBAAA,mBACK,gCAAA,EAEhB,IAAA,UACA,MAAA,EAAQ,2BAAA,CAA4B,OAAA,gBAEpC,+BAAA,CAAgC,OAAA;EAE9B,EAAA;EACA,OAAA,EACI,gCAAA,CACE,+BAAA,CAAgC,OAAA;EAGtC,QAAA,GACE,OAAA,EACI,+BAAA,CAAgC,OAAA,MAE9B,IAAA,EAAM,+BAAA,CAAgC,OAAA,MACnC,+BAAA,CAAgC,OAAA;EAE3C,SAAA;EACA,KAAA;EACA,KAAA,QAAa,OAAA;AAAA"}
@@ -0,0 +1,100 @@
1
+ "use client";
2
+ import { interactableToolName, unstable_getInteractableVersions } from "../../model-context/interactable-composer-metadata.js";
3
+ import { unstable_useInteractableState } from "./useInteractableState.js";
4
+ import { useJSONEqual } from "../utils/useJSONEqual.js";
5
+ import { useAui, useAuiState } from "@assistant-ui/store";
6
+ import { useEffect, useId, useMemo, useRef } from "@assistant-ui/tap/react-shim";
7
+ //#region src/react/model-context/useInteractable.ts
8
+ const useInteractable = (name, config) => {
9
+ const aui = useAui();
10
+ const autoId = useId().replace(/[^a-zA-Z0-9]/g, "");
11
+ const inPart = aui.part.source != null;
12
+ const updateToolName = interactableToolName(name);
13
+ const part = useAuiState((s) => {
14
+ if (!inPart) return void 0;
15
+ const p = s.part;
16
+ return p.type === "tool-call" ? p : void 0;
17
+ });
18
+ let inferredId;
19
+ if (part?.toolName === updateToolName) {
20
+ const result = part.result;
21
+ const args = part.args;
22
+ if (result?.success !== false) {
23
+ if (typeof result?.id === "string") inferredId = result.id;
24
+ else if (typeof args?.id === "string") inferredId = args.id;
25
+ }
26
+ }
27
+ const id = config.id ?? inferredId ?? autoId;
28
+ const internalScope = part?.toolName === name || part?.toolName === updateToolName ? "thread" : void 0;
29
+ const stateSchemaRef = useRef(config.stateSchema);
30
+ stateSchemaRef.current = config.stateSchema;
31
+ const initialStateRef = useRef(config.initialState);
32
+ initialStateRef.current = config.initialState;
33
+ const interactables = useAuiState(() => aui.unstable_interactables());
34
+ useEffect(() => {
35
+ return interactables.register({
36
+ id,
37
+ name,
38
+ description: config.description,
39
+ stateSchema: stateSchemaRef.current,
40
+ initialState: initialStateRef.current,
41
+ updateRender: config.updateRender,
42
+ ...internalScope ? { scope: internalScope } : {}
43
+ });
44
+ }, [
45
+ interactables,
46
+ id,
47
+ name,
48
+ config.description,
49
+ internalScope,
50
+ config.updateRender
51
+ ]);
52
+ const myToolCallId = part?.toolCallId;
53
+ const [registeredState, methods] = unstable_useInteractableState(id);
54
+ const { setState } = methods;
55
+ const versionValue = useAuiState(useJSONEqual((s_0) => {
56
+ if (!internalScope || !myToolCallId) return void 0;
57
+ const versions = unstable_getInteractableVersions(s_0.thread.messages, id, name);
58
+ if (!versions.some((v) => v.origin === "create" && v.toolCallId === id)) return;
59
+ const mine = versions.find((v_0) => v_0.toolCallId === myToolCallId);
60
+ if (!mine) return void 0;
61
+ const latestToolCallId = versions.findLast((v_1) => v_1.toolCallId !== void 0)?.toolCallId;
62
+ return {
63
+ state: mine.state,
64
+ isLatest: latestToolCallId === myToolCallId
65
+ };
66
+ }));
67
+ const version = useMemo(() => versionValue && {
68
+ state: versionValue.state,
69
+ isLatest: versionValue.isLatest,
70
+ restore: () => setState(versionValue.state)
71
+ }, [versionValue, setState]);
72
+ return [registeredState === void 0 ? config.initialState : registeredState, {
73
+ id,
74
+ version,
75
+ ...methods
76
+ }];
77
+ };
78
+ /**
79
+ * Registers an interactable with the AI assistant and returns its live state,
80
+ * like `useState` that the model can also read and update.
81
+ *
82
+ * Call this once per place that shows the interactable. Other components can
83
+ * read and write the same instance by passing its `id` to
84
+ * `unstable_useInteractableState`.
85
+ *
86
+ * For tool-created interactables rendered inside tool-call message parts,
87
+ * `version` carries this message's version of the instance — its state as of
88
+ * that point in the conversation, whether it is the most recent tool-driven
89
+ * version, and a `restore()` back to it. Whether older messages render frozen history or stay
90
+ * live-editable is the component's choice. Inside an `update_{name}` part the
91
+ * instance `id` is inferred from the call, so the same component works at the
92
+ * creating call and at update calls.
93
+ *
94
+ * @deprecated Unstable / Experimental (not actually removed).
95
+ */
96
+ const unstable_useInteractable = useInteractable;
97
+ //#endregion
98
+ export { unstable_useInteractable };
99
+
100
+ //# sourceMappingURL=useInteractable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useInteractable.js","names":["useEffect","useId","useMemo","useRef","useAui","useAuiState","Unstable_InteractableStateSchema","ToolCallMessagePartComponent","unstable_getInteractableVersions","getInteractableVersions","interactableToolName","unstable_useInteractableState","useInteractableState","useJSONEqual","Unstable_InferInteractableState","TSchema","types","output","TOutput","Unstable_InteractableVersionInfo","state","TState","isLatest","restore","Unstable_InteractableConfig","description","stateSchema","initialState","id","updateRender","useInteractable","name","config","version","setState","updater","prev","isPending","error","flush","Promise","aui","autoId","replace","inPart","part","source","updateToolName","s","undefined","p","type","inferredId","toolName","result","Record","args","success","internalScope","stateSchemaRef","current","initialStateRef","interactables","unstable_interactables","register","scope","Parameters","myToolCallId","toolCallId","registeredState","methods","versionValue","versions","thread","messages","some","v","origin","mine","find","latestToolCallId","findLast","const","unstable_useInteractable"],"sources":["../../../src/react/model-context/useInteractable.ts"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useId, useMemo, useRef } from \"react\";\nimport { useAui, useAuiState } from \"@assistant-ui/store\";\nimport type { Unstable_InteractableStateSchema } from \"../types/scopes/interactables\";\nimport type { ToolCallMessagePartComponent } from \"../types/MessagePartComponentTypes\";\nimport {\n unstable_getInteractableVersions as getInteractableVersions,\n interactableToolName,\n} from \"../../model-context/interactable-composer-metadata\";\nimport { unstable_useInteractableState as useInteractableState } from \"./useInteractableState\";\nimport { useJSONEqual } from \"../utils/useJSONEqual\";\n\n/**\n * The state type described by an interactable's `stateSchema`. Resolves the\n * output type of a StandardSchemaV1 schema (e.g. Zod); plain JSON Schema\n * falls back to `unknown`.\n */\nexport type Unstable_InferInteractableState<TSchema> = TSchema extends {\n \"~standard\": { types?: { output: infer TOutput } | undefined };\n}\n ? TOutput\n : unknown;\n\n/**\n * One message's version of an interactable, for components rendered inside\n * tool-call parts. Show `state` to display history; call `restore()` to set\n * the live instance back to it.\n */\nexport type Unstable_InteractableVersionInfo<TState> = {\n /** The interactable's state as it was at this message. */\n state: TState;\n /** Whether this message holds the instance's most recent tool-driven version. */\n isLatest: boolean;\n /** Sets the live state back to this version. */\n restore: () => void;\n};\n\n/**\n * Unstable / Experimental — the interactables API is still evolving and may change in any release.\n * @deprecated Unstable / Experimental (not actually removed).\n */\nexport type Unstable_InteractableConfig<\n TSchema extends Unstable_InteractableStateSchema,\n> = {\n description: string;\n stateSchema: TSchema;\n initialState: Unstable_InferInteractableState<TSchema>;\n /** Unique instance ID; required to address this instance when multiple interactables share a name. Auto-generated if omitted. */\n id?: string | undefined;\n /**\n * Component installed as the tool UI for this interactable's `update_{name}`\n * tool calls, so a model edit re-renders the interactable at the message\n * that made it instead of only mutating an earlier one. Prefer\n * `unstable_interactableTool`, which wires this up. Pass a stable component reference;\n * changing identity re-registers the tool UI.\n */\n updateRender?: ToolCallMessagePartComponent | undefined;\n};\n\nconst useInteractable = <TSchema extends Unstable_InteractableStateSchema>(\n name: string,\n config: Unstable_InteractableConfig<TSchema>,\n): readonly [\n Unstable_InferInteractableState<TSchema>,\n {\n id: string;\n /**\n * This message's version of the instance, when rendered inside a\n * tool-created interactable message part; `undefined` elsewhere.\n */\n version:\n | Unstable_InteractableVersionInfo<\n Unstable_InferInteractableState<TSchema>\n >\n | undefined;\n setState: (\n updater:\n | Unstable_InferInteractableState<TSchema>\n | ((\n prev: Unstable_InferInteractableState<TSchema>,\n ) => Unstable_InferInteractableState<TSchema>),\n ) => void;\n isPending: boolean;\n error: unknown;\n flush: () => Promise<void>;\n },\n] => {\n const aui = useAui();\n\n const autoId = useId().replace(/[^a-zA-Z0-9]/g, \"\");\n\n // Whether this component renders inside a message part is fixed for its\n // lifetime, so conditioning the selectors on it is safe.\n const inPart = aui.part.source != null;\n const updateToolName = interactableToolName(name);\n const part = useAuiState((s) => {\n if (!inPart) return undefined;\n const p = s.part;\n return p.type === \"tool-call\" ? p : undefined;\n });\n\n // Inside an update_{name} part, the instance id comes from the call itself:\n // the result's resolved id (covers id-less calls), or the id argument.\n let inferredId: string | undefined;\n if (part?.toolName === updateToolName) {\n const result = part.result as Record<string, unknown> | undefined;\n const args = part.args as Record<string, unknown> | undefined;\n if (result?.success !== false) {\n if (typeof result?.id === \"string\") inferredId = result.id;\n else if (typeof args?.id === \"string\") inferredId = args.id;\n }\n }\n\n const id = config.id ?? inferredId ?? autoId;\n const internalScope =\n part?.toolName === name || part?.toolName === updateToolName\n ? \"thread\"\n : undefined;\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 const interactables = useAuiState(() => aui.unstable_interactables());\n\n useEffect(() => {\n return interactables.register({\n id,\n name,\n description: config.description,\n stateSchema: stateSchemaRef.current,\n initialState: initialStateRef.current,\n updateRender: config.updateRender,\n ...(internalScope ? { scope: internalScope } : {}),\n } as Parameters<typeof interactables.register>[0] & {\n scope?: \"thread\" | undefined;\n });\n }, [\n interactables,\n id,\n name,\n config.description,\n internalScope,\n config.updateRender,\n ]);\n\n const myToolCallId = part?.toolCallId;\n\n const [registeredState, methods] =\n useInteractableState<Unstable_InferInteractableState<TSchema>>(id);\n const { setState } = methods;\n\n const versionValue = useAuiState(\n useJSONEqual((s) => {\n if (!internalScope || !myToolCallId) return undefined;\n const versions = getInteractableVersions(s.thread.messages, id, name);\n if (!versions.some((v) => v.origin === \"create\" && v.toolCallId === id)) {\n return undefined;\n }\n const mine = versions.find((v) => v.toolCallId === myToolCallId);\n if (!mine) return undefined;\n const latestToolCallId = versions.findLast(\n (v) => v.toolCallId !== undefined,\n )?.toolCallId;\n return { state: mine.state, isLatest: latestToolCallId === myToolCallId };\n }),\n );\n\n const version = useMemo(\n () =>\n versionValue && {\n state: versionValue.state as Unstable_InferInteractableState<TSchema>,\n isLatest: versionValue.isLatest,\n restore: () =>\n setState(\n versionValue.state as Unstable_InferInteractableState<TSchema>,\n ),\n },\n [versionValue, setState],\n );\n\n const state =\n registeredState === undefined ? config.initialState : registeredState;\n\n return [state, { id, version, ...methods }] as const;\n};\n\n/**\n * Registers an interactable with the AI assistant and returns its live state,\n * like `useState` that the model can also read and update.\n *\n * Call this once per place that shows the interactable. Other components can\n * read and write the same instance by passing its `id` to\n * `unstable_useInteractableState`.\n *\n * For tool-created interactables rendered inside tool-call message parts,\n * `version` carries this message's version of the instance — its state as of\n * that point in the conversation, whether it is the most recent tool-driven\n * version, and a `restore()` back to it. Whether older messages render frozen history or stay\n * live-editable is the component's choice. Inside an `update_{name}` part the\n * instance `id` is inferred from the call, so the same component works at the\n * creating call and at update calls.\n *\n * @deprecated Unstable / Experimental (not actually removed).\n */\nexport const unstable_useInteractable: <\n TSchema extends Unstable_InteractableStateSchema,\n>(\n name: string,\n config: Unstable_InteractableConfig<TSchema>,\n) => readonly [\n Unstable_InferInteractableState<TSchema>,\n {\n id: string;\n version:\n | Unstable_InteractableVersionInfo<\n Unstable_InferInteractableState<TSchema>\n >\n | undefined;\n setState: (\n updater:\n | Unstable_InferInteractableState<TSchema>\n | ((\n prev: Unstable_InferInteractableState<TSchema>,\n ) => Unstable_InferInteractableState<TSchema>),\n ) => void;\n isPending: boolean;\n error: unknown;\n flush: () => Promise<void>;\n },\n] = useInteractable;\n"],"mappings":";;;;;;;AA4DA,MAAM8B,mBACJC,MACAC,WAyBG;CACH,MAAMS,MAAMrC,OAAO;CAEnB,MAAMsC,SAASzC,MAAM,CAAC,CAAC0C,QAAQ,iBAAiB,EAAE;CAIlD,MAAMC,SAASH,IAAII,KAAKC,UAAU;CAClC,MAAMC,iBAAiBrC,qBAAqBqB,IAAI;CAChD,MAAMc,OAAOxC,aAAa2C,MAAM;EAC9B,IAAI,CAACJ,QAAQ,OAAOK,KAAAA;EACpB,MAAMC,IAAIF,EAAEH;EACZ,OAAOK,EAAEC,SAAS,cAAcD,IAAID,KAAAA;CACtC,CAAC;CAID,IAAIG;CACJ,IAAIP,MAAMQ,aAAaN,gBAAgB;EACrC,MAAMO,SAAST,KAAKS;EACpB,MAAME,OAAOX,KAAKW;EAClB,IAAIF,QAAQG,YAAY;OAClB,OAAOH,QAAQ1B,OAAO,UAAUwB,aAAaE,OAAO1B;QACnD,IAAI,OAAO4B,MAAM5B,OAAO,UAAUwB,aAAaI,KAAK5B;EAAAA;CAE7D;CAEA,MAAMA,KAAKI,OAAOJ,MAAMwB,cAAcV;CACtC,MAAMgB,gBACJb,MAAMQ,aAAatB,QAAQc,MAAMQ,aAAaN,iBAC1C,WACAE,KAAAA;CAEN,MAAMU,iBAAiBxD,OAAO6B,OAAON,WAAW;CAChDiC,eAAeC,UAAU5B,OAAON;CAChC,MAAMmC,kBAAkB1D,OAAO6B,OAAOL,YAAY;CAClDkC,gBAAgBD,UAAU5B,OAAOL;CAEjC,MAAMmC,gBAAgBzD,kBAAkBoC,IAAIsB,uBAAuB,CAAC;CAEpE/D,gBAAgB;EACd,OAAO8D,cAAcE,SAAS;GAC5BpC;GACAG;GACAN,aAAaO,OAAOP;GACpBC,aAAaiC,eAAeC;GAC5BjC,cAAckC,gBAAgBD;GAC9B/B,cAAcG,OAAOH;GACrB,GAAI6B,gBAAgB,EAAEO,OAAOP,cAAc,IAAI,CAAC;EAClD,CAEC;CACH,GAAG;EACDI;EACAlC;EACAG;EACAC,OAAOP;EACPiC;EACA1B,OAAOH;CAAY,CACpB;CAED,MAAMsC,eAAetB,MAAMuB;CAE3B,MAAM,CAACC,iBAAiBC,WACtB1D,8BAA+DgB,EAAE;CACnE,MAAM,EAAEM,aAAaoC;CAErB,MAAMC,eAAelE,YACnBQ,cAAcmC,QAAM;EAClB,IAAI,CAACU,iBAAiB,CAACS,cAAc,OAAOlB,KAAAA;EAC5C,MAAMuB,WAAW/D,iCAAwBuC,IAAEyB,OAAOC,UAAU9C,IAAIG,IAAI;EACpE,IAAI,CAACyC,SAASG,MAAMC,MAAMA,EAAEC,WAAW,YAAYD,EAAER,eAAexC,EAAE,GACpE;EAEF,MAAMkD,OAAON,SAASO,MAAMH,QAAMA,IAAER,eAAeD,YAAY;EAC/D,IAAI,CAACW,MAAM,OAAO7B,KAAAA;EAClB,MAAM+B,mBAAmBR,SAASS,UAC/BL,QAAMA,IAAER,eAAenB,KAAAA,CAC1B,CAAC,EAAEmB;EACH,OAAO;GAAEhD,OAAO0D,KAAK1D;GAAOE,UAAU0D,qBAAqBb;EAAa;CAC1E,CAAC,CACH;CAEA,MAAMlC,UAAU/B,cAEZqE,gBAAgB;EACdnD,OAAOmD,aAAanD;EACpBE,UAAUiD,aAAajD;EACvBC,eACEW,SACEqC,aAAanD,KACf;CACJ,GACF,CAACmD,cAAcrC,QAAQ,CACzB;CAKA,OAAO,CAFLmC,oBAAoBpB,KAAAA,IAAYjB,OAAOL,eAAe0C,iBAEzC;EAAEzC;EAAIK;EAAS,GAAGqC;CAAQ,CAAC;AAC5C;;;;;;;;;;;;;;;;;;;AAoBA,MAAaa,2BAyBTrD"}
@@ -1,17 +1,20 @@
1
1
  //#region src/react/model-context/useInteractableState.d.ts
2
2
  type StateUpdater<TState> = TState | ((prev: TState) => TState);
3
3
  /**
4
- * Reads and writes the state of a registered interactable.
4
+ * Reads and writes the state of an interactable registered elsewhere, by id.
5
5
  *
6
- * Pair with {@link useAssistantInteractable} which handles registration.
6
+ * Use this from secondary readers (children, siblings); the owning component
7
+ * registers with `unstable_useInteractable`, which returns state directly. Returns
8
+ * `undefined` until the owning interactable is registered.
9
+ *
10
+ * @deprecated Unstable / Experimental (not actually removed).
7
11
  */
8
- declare const useInteractableState: <TState>(id: string, fallback: TState) => [TState, {
12
+ declare const unstable_useInteractableState: <TState>(id: string) => [TState | undefined, {
9
13
  setState: (updater: StateUpdater<TState>) => void;
10
- setSelected: (selected: boolean) => void;
11
14
  isPending: boolean;
12
15
  error: unknown;
13
16
  flush: () => Promise<void>;
14
17
  }];
15
18
  //#endregion
16
- export { useInteractableState };
19
+ export { unstable_useInteractableState };
17
20
  //# sourceMappingURL=useInteractableState.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useInteractableState.d.ts","names":[],"sources":["../../../src/react/model-context/useInteractableState.ts"],"mappings":";KAGK,YAAA,WAAuB,MAAA,KAAW,IAAA,EAAM,MAAA,KAAW,MAAA;;;;;;cAO3C,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"}
1
+ {"version":3,"file":"useInteractableState.d.ts","names":[],"sources":["../../../src/react/model-context/useInteractableState.ts"],"mappings":";KAKK,YAAA,WAAuB,MAAA,KAAW,IAAA,EAAM,MAAA,KAAW,MAAA;;;;;;;;;;cAyD3C,6BAAA,WAAwC,EAAA,cACnD,MAAA;EAEE,QAAA,GAAW,OAAA,EAAS,YAAA,CAAa,MAAA;EACjC,SAAA;EACA,KAAA;EACA,KAAA,QAAa,OAAA;AAAA"}