@assistant-ui/react 0.14.13 → 0.14.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (214) hide show
  1. package/README.md +5 -1
  2. package/dist/client/ExternalThread.d.ts +2 -12
  3. package/dist/client/ExternalThread.d.ts.map +1 -1
  4. package/dist/client/ExternalThread.js +30 -29
  5. package/dist/client/ExternalThread.js.map +1 -1
  6. package/dist/client/InMemoryThreadList.d.ts.map +1 -1
  7. package/dist/client/InMemoryThreadList.js +24 -13
  8. package/dist/client/InMemoryThreadList.js.map +1 -1
  9. package/dist/client/SingleThreadList.d.ts.map +1 -1
  10. package/dist/client/SingleThreadList.js +12 -8
  11. package/dist/client/SingleThreadList.js.map +1 -1
  12. package/dist/context/providers/ThreadViewportProvider.js +1 -1
  13. package/dist/context/providers/ThreadViewportProvider.js.map +1 -1
  14. package/dist/context/react/ThreadViewportContext.js +1 -1
  15. package/dist/context/react/utils/createContextHook.js +1 -1
  16. package/dist/context/react/utils/ensureBinding.js.map +1 -1
  17. package/dist/context/react/utils/useRuntimeState.js +1 -1
  18. package/dist/context/stores/ThreadViewport.js.map +1 -1
  19. package/dist/devtools/DevToolsHooks.js.map +1 -1
  20. package/dist/index.d.ts +4 -4
  21. package/dist/index.js +3 -3
  22. package/dist/legacy-runtime/AssistantRuntimeProvider.js +1 -1
  23. package/dist/legacy-runtime/cloud/auiV0.js +1 -1
  24. package/dist/legacy-runtime/hooks/AssistantContext.js.map +1 -1
  25. package/dist/legacy-runtime/hooks/AttachmentContext.js.map +1 -1
  26. package/dist/legacy-runtime/hooks/ComposerContext.js.map +1 -1
  27. package/dist/legacy-runtime/hooks/MessageContext.js.map +1 -1
  28. package/dist/legacy-runtime/hooks/MessagePartContext.js.map +1 -1
  29. package/dist/legacy-runtime/hooks/ThreadContext.js +1 -1
  30. package/dist/legacy-runtime/hooks/ThreadContext.js.map +1 -1
  31. package/dist/legacy-runtime/hooks/ThreadListItemContext.js.map +1 -1
  32. package/dist/legacy-runtime/runtime-cores/assistant-transport/commandQueue.js +1 -1
  33. package/dist/legacy-runtime/runtime-cores/assistant-transport/replayBoundaryStream.d.ts +14 -0
  34. package/dist/legacy-runtime/runtime-cores/assistant-transport/replayBoundaryStream.d.ts.map +1 -0
  35. package/dist/legacy-runtime/runtime-cores/assistant-transport/replayBoundaryStream.js +101 -0
  36. package/dist/legacy-runtime/runtime-cores/assistant-transport/replayBoundaryStream.js.map +1 -0
  37. package/dist/legacy-runtime/runtime-cores/assistant-transport/runManager.js +1 -1
  38. package/dist/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.d.ts.map +1 -1
  39. package/dist/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.js +13 -2
  40. package/dist/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.js.map +1 -1
  41. package/dist/legacy-runtime/runtime-cores/assistant-transport/useConvertedState.js +1 -1
  42. package/dist/legacy-runtime/runtime-cores/assistant-transport/useLatestRef.js +1 -1
  43. package/dist/mcp-apps/McpAppRenderer.d.ts.map +1 -1
  44. package/dist/mcp-apps/McpAppRenderer.js +7 -7
  45. package/dist/mcp-apps/McpAppRenderer.js.map +1 -1
  46. package/dist/mcp-apps/McpAppsRemoteHost.d.ts.map +1 -1
  47. package/dist/mcp-apps/McpAppsRemoteHost.js +5 -4
  48. package/dist/mcp-apps/McpAppsRemoteHost.js.map +1 -1
  49. package/dist/mcp-apps/app-frame.d.ts +1 -1
  50. package/dist/mcp-apps/app-frame.d.ts.map +1 -1
  51. package/dist/mcp-apps/app-frame.js +82 -104
  52. package/dist/mcp-apps/app-frame.js.map +1 -1
  53. package/dist/mcp-apps/bridge.d.ts +3 -3
  54. package/dist/mcp-apps/bridge.d.ts.map +1 -1
  55. package/dist/mcp-apps/bridge.js +35 -10
  56. package/dist/mcp-apps/bridge.js.map +1 -1
  57. package/dist/mcp-apps/types.d.ts +2 -12
  58. package/dist/mcp-apps/types.d.ts.map +1 -1
  59. package/dist/mcp-apps/types.js.map +1 -1
  60. package/dist/model-context/frame/useAssistantFrameHost.js +1 -1
  61. package/dist/model-context/makeAssistantVisible.js +1 -1
  62. package/dist/model-context/makeAssistantVisible.js.map +1 -1
  63. package/dist/primitives/actionBar/ActionBarCopy.js +1 -1
  64. package/dist/primitives/actionBar/ActionBarExportMarkdown.js +1 -1
  65. package/dist/primitives/actionBar/ActionBarExportMarkdown.js.map +1 -1
  66. package/dist/primitives/actionBar/ActionBarFeedbackNegative.js +1 -1
  67. package/dist/primitives/actionBar/ActionBarFeedbackPositive.js +1 -1
  68. package/dist/primitives/actionBar/ActionBarInteractionContext.js +1 -1
  69. package/dist/primitives/actionBar/ActionBarRoot.js +1 -1
  70. package/dist/primitives/actionBar/ActionBarStopSpeaking.js +1 -1
  71. package/dist/primitives/actionBarMore/ActionBarMoreContent.js +1 -1
  72. package/dist/primitives/actionBarMore/ActionBarMoreItem.js +1 -1
  73. package/dist/primitives/actionBarMore/ActionBarMoreRoot.js +1 -1
  74. package/dist/primitives/actionBarMore/ActionBarMoreSeparator.js +1 -1
  75. package/dist/primitives/actionBarMore/ActionBarMoreTrigger.js +1 -1
  76. package/dist/primitives/assistantModal/AssistantModalAnchor.js +1 -1
  77. package/dist/primitives/assistantModal/AssistantModalContent.js +1 -1
  78. package/dist/primitives/assistantModal/AssistantModalRoot.js +1 -1
  79. package/dist/primitives/assistantModal/AssistantModalTrigger.js +1 -1
  80. package/dist/primitives/attachment/AttachmentRemove.js +1 -1
  81. package/dist/primitives/attachment/AttachmentRemove.js.map +1 -1
  82. package/dist/primitives/attachment/AttachmentRoot.js +1 -1
  83. package/dist/primitives/attachment/AttachmentThumb.js +1 -1
  84. package/dist/primitives/branchPicker/BranchPickerRoot.js +1 -1
  85. package/dist/primitives/chainOfThought/ChainOfThoughtAccordionTrigger.js +1 -1
  86. package/dist/primitives/chainOfThought/ChainOfThoughtAccordionTrigger.js.map +1 -1
  87. package/dist/primitives/chainOfThought/ChainOfThoughtRoot.js +1 -1
  88. package/dist/primitives/composer/ComposerAddAttachment.js +1 -1
  89. package/dist/primitives/composer/ComposerAddAttachment.js.map +1 -1
  90. package/dist/primitives/composer/ComposerAttachmentDropzone.js +1 -1
  91. package/dist/primitives/composer/ComposerAttachmentDropzone.js.map +1 -1
  92. package/dist/primitives/composer/ComposerDictationTranscript.js +1 -1
  93. package/dist/primitives/composer/ComposerInput.js +1 -1
  94. package/dist/primitives/composer/ComposerInput.js.map +1 -1
  95. package/dist/primitives/composer/ComposerInputPluginContext.js +1 -1
  96. package/dist/primitives/composer/ComposerQuote.js +1 -1
  97. package/dist/primitives/composer/ComposerQuote.js.map +1 -1
  98. package/dist/primitives/composer/ComposerRoot.js +1 -1
  99. package/dist/primitives/composer/ComposerSend.js +1 -1
  100. package/dist/primitives/composer/ComposerStopDictation.js +1 -1
  101. package/dist/primitives/composer/ComposerStopDictation.js.map +1 -1
  102. package/dist/primitives/composer/trigger/TriggerPopover.js +2 -2
  103. package/dist/primitives/composer/trigger/TriggerPopover.js.map +1 -1
  104. package/dist/primitives/composer/trigger/TriggerPopoverAction.js +1 -1
  105. package/dist/primitives/composer/trigger/TriggerPopoverBack.js +1 -1
  106. package/dist/primitives/composer/trigger/TriggerPopoverCategories.js +1 -1
  107. package/dist/primitives/composer/trigger/TriggerPopoverDirective.js +1 -1
  108. package/dist/primitives/composer/trigger/TriggerPopoverItems.js +1 -1
  109. package/dist/primitives/composer/trigger/TriggerPopoverResource.d.ts.map +1 -1
  110. package/dist/primitives/composer/trigger/TriggerPopoverResource.js +8 -7
  111. package/dist/primitives/composer/trigger/TriggerPopoverResource.js.map +1 -1
  112. package/dist/primitives/composer/trigger/TriggerPopoverRootContext.js +1 -1
  113. package/dist/primitives/composer/trigger/triggerDetectionResource.d.ts.map +1 -1
  114. package/dist/primitives/composer/trigger/triggerDetectionResource.js +5 -4
  115. package/dist/primitives/composer/trigger/triggerDetectionResource.js.map +1 -1
  116. package/dist/primitives/composer/trigger/triggerKeyboardResource.d.ts.map +1 -1
  117. package/dist/primitives/composer/trigger/triggerKeyboardResource.js +8 -7
  118. package/dist/primitives/composer/trigger/triggerKeyboardResource.js.map +1 -1
  119. package/dist/primitives/composer/trigger/triggerNavigationResource.d.ts.map +1 -1
  120. package/dist/primitives/composer/trigger/triggerNavigationResource.js +13 -12
  121. package/dist/primitives/composer/trigger/triggerNavigationResource.js.map +1 -1
  122. package/dist/primitives/composer/trigger/triggerSelectionResource.d.ts.map +1 -1
  123. package/dist/primitives/composer/trigger/triggerSelectionResource.js +7 -6
  124. package/dist/primitives/composer/trigger/triggerSelectionResource.js.map +1 -1
  125. package/dist/primitives/error/ErrorMessage.js +1 -1
  126. package/dist/primitives/error/ErrorRoot.js +1 -1
  127. package/dist/primitives/message/MessagePartsGrouped.js +1 -1
  128. package/dist/primitives/message/MessagePartsGrouped.js.map +1 -1
  129. package/dist/primitives/message/MessageRoot.js +1 -1
  130. package/dist/primitives/message/MessageRoot.js.map +1 -1
  131. package/dist/primitives/messagePart/MessagePartImage.js +1 -1
  132. package/dist/primitives/messagePart/MessagePartText.js +1 -1
  133. package/dist/primitives/queueItem/QueueItemRemove.js +1 -1
  134. package/dist/primitives/queueItem/QueueItemRemove.js.map +1 -1
  135. package/dist/primitives/queueItem/QueueItemSteer.js +1 -1
  136. package/dist/primitives/queueItem/QueueItemSteer.js.map +1 -1
  137. package/dist/primitives/queueItem/QueueItemText.js +1 -1
  138. package/dist/primitives/reasoning/useScrollLock.js +1 -1
  139. package/dist/primitives/reasoning/useScrollLock.js.map +1 -1
  140. package/dist/primitives/selectionToolbar/SelectionToolbarQuote.js +1 -1
  141. package/dist/primitives/selectionToolbar/SelectionToolbarQuote.js.map +1 -1
  142. package/dist/primitives/selectionToolbar/SelectionToolbarRoot.js +1 -1
  143. package/dist/primitives/selectionToolbar/SelectionToolbarRoot.js.map +1 -1
  144. package/dist/primitives/suggestion/SuggestionDescription.js +1 -1
  145. package/dist/primitives/suggestion/SuggestionTitle.js +1 -1
  146. package/dist/primitives/suggestion/SuggestionTrigger.js +1 -1
  147. package/dist/primitives/suggestion/SuggestionTrigger.js.map +1 -1
  148. package/dist/primitives/thread/ThreadRoot.js +1 -1
  149. package/dist/primitives/thread/ThreadScrollToBottom.js +1 -1
  150. package/dist/primitives/thread/ThreadScrollToBottom.js.map +1 -1
  151. package/dist/primitives/thread/ThreadViewport.js +1 -1
  152. package/dist/primitives/thread/ThreadViewport.js.map +1 -1
  153. package/dist/primitives/thread/ThreadViewportFooter.js +1 -1
  154. package/dist/primitives/thread/ThreadViewportFooter.js.map +1 -1
  155. package/dist/primitives/thread/topAnchor/topAnchorTurn.js.map +1 -1
  156. package/dist/primitives/thread/topAnchor/topAnchorUtils.js.map +1 -1
  157. package/dist/primitives/thread/topAnchor/useTopAnchorReserve.js +1 -1
  158. package/dist/primitives/thread/useThreadViewportAutoScroll.js +1 -1
  159. package/dist/primitives/thread/useThreadViewportAutoScroll.js.map +1 -1
  160. package/dist/primitives/threadList/ThreadListNew.js +1 -1
  161. package/dist/primitives/threadList/ThreadListRoot.js +1 -1
  162. package/dist/primitives/threadListItem/ThreadListItemRoot.js +1 -1
  163. package/dist/primitives/threadListItemMore/ThreadListItemMoreContent.js +1 -1
  164. package/dist/primitives/threadListItemMore/ThreadListItemMoreItem.js +1 -1
  165. package/dist/primitives/threadListItemMore/ThreadListItemMoreSeparator.js +1 -1
  166. package/dist/primitives/threadListItemMore/ThreadListItemMoreTrigger.js +1 -1
  167. package/dist/sandbox-host/SandboxHost.d.ts +50 -0
  168. package/dist/sandbox-host/SandboxHost.d.ts.map +1 -0
  169. package/dist/sandbox-host/SandboxHost.js +85 -0
  170. package/dist/sandbox-host/SandboxHost.js.map +1 -0
  171. package/dist/unstable/useMentionAdapter.d.ts +2 -2
  172. package/dist/unstable/useMentionAdapter.js +2 -2
  173. package/dist/unstable/useMentionAdapter.js.map +1 -1
  174. package/dist/unstable/useSlashCommandAdapter.js +1 -1
  175. package/dist/unstable/useSlashCommandAdapter.js.map +1 -1
  176. package/dist/utils/Primitive.js +1 -1
  177. package/dist/utils/createActionButton.js +1 -1
  178. package/dist/utils/createActionButton.js.map +1 -1
  179. package/dist/utils/hooks/useManagedRef.js +1 -1
  180. package/dist/utils/hooks/useMediaQuery.js +1 -1
  181. package/dist/utils/hooks/useMediaQuery.js.map +1 -1
  182. package/dist/utils/hooks/useOnResizeContent.js +1 -1
  183. package/dist/utils/hooks/useOnScrollToBottom.js +1 -1
  184. package/dist/utils/hooks/useSizeHandle.js +1 -1
  185. package/dist/utils/json/is-json.js.map +1 -1
  186. package/dist/utils/smooth/SmoothContext.js +1 -1
  187. package/dist/utils/smooth/SmoothContext.js.map +1 -1
  188. package/dist/utils/smooth/useSmooth.js +1 -1
  189. package/dist/utils/smooth/useSmooth.js.map +1 -1
  190. package/package.json +21 -20
  191. package/src/client/ExternalThread.ts +484 -515
  192. package/src/client/InMemoryThreadList.ts +154 -142
  193. package/src/client/SingleThreadList.ts +88 -81
  194. package/src/context/providers/ThreadViewportProvider.tsx +2 -2
  195. package/src/index.ts +18 -3
  196. package/src/legacy-runtime/runtime-cores/assistant-transport/replayBoundaryStream.test.ts +426 -0
  197. package/src/legacy-runtime/runtime-cores/assistant-transport/replayBoundaryStream.ts +146 -0
  198. package/src/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.ts +16 -1
  199. package/src/mcp-apps/McpAppRenderer.tsx +28 -35
  200. package/src/mcp-apps/McpAppsRemoteHost.ts +25 -24
  201. package/src/mcp-apps/app-frame.tsx +100 -141
  202. package/src/mcp-apps/bridge.test.ts +100 -60
  203. package/src/mcp-apps/bridge.ts +43 -21
  204. package/src/mcp-apps/types.ts +2 -12
  205. package/src/primitives/composer/trigger/TriggerPopover.tsx +1 -1
  206. package/src/primitives/composer/trigger/TriggerPopoverResource.ts +75 -76
  207. package/src/primitives/composer/trigger/triggerDetectionResource.ts +6 -5
  208. package/src/primitives/composer/trigger/triggerKeyboardResource.ts +9 -13
  209. package/src/primitives/composer/trigger/triggerNavigationResource.ts +14 -19
  210. package/src/primitives/composer/trigger/triggerSelectionResource.ts +8 -7
  211. package/src/sandbox-host/SandboxHost.test.tsx +231 -0
  212. package/src/sandbox-host/SandboxHost.tsx +185 -0
  213. package/src/tests/local-runtime-queue.test.tsx +305 -0
  214. package/src/unstable/useMentionAdapter.ts +2 -2
@@ -1,16 +1,16 @@
1
+ import { SandboxHostFrame } from "../sandbox-host/SandboxHost.js";
1
2
  import { McpAppBridgeHandlers, McpAppHostContext, McpAppHostInfo } from "./types.js";
2
- import { RenderedFrame } from "safe-content-frame";
3
3
 
4
4
  //#region src/mcp-apps/bridge.d.ts
5
- type McpAppBridgeFrame = Pick<RenderedFrame, "iframe" | "origin" | "sendMessage">;
5
+ type McpAppBridgeFrame = SandboxHostFrame;
6
6
  type CreateMcpAppBridgeOptions = {
7
7
  frame: McpAppBridgeFrame;
8
8
  handlers?: McpAppBridgeHandlers | undefined;
9
9
  hostInfo?: McpAppHostInfo | undefined;
10
10
  hostContext?: McpAppHostContext | undefined;
11
- targetWindow?: Window | undefined;
12
11
  };
13
12
  type McpAppBridge = {
13
+ onMessage: (event: MessageEvent) => void;
14
14
  dispose: () => void;
15
15
  notifyToolInput: (input: unknown) => void;
16
16
  notifyToolResult: (result: unknown) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"bridge.d.ts","names":[],"sources":["../../src/mcp-apps/bridge.ts"],"mappings":";;;;KAmBY,iBAAA,GAAoB,IAAI,CAClC,aAAA;AAAA,KAIU,yBAAA;EACV,KAAA,EAAO,iBAAA;EACP,QAAA,GAAW,oBAAA;EACX,QAAA,GAAW,cAAA;EACX,WAAA,GAAc,iBAAA;EACd,YAAA,GAAe,MAAA;AAAA;AAAA,KAGL,YAAA;EACV,OAAA;EACA,eAAA,GAAkB,KAAA;EAClB,gBAAA,GAAmB,MAAA;EACnB,wBAAA,GAA2B,WAAA,EAAa,iBAAiB;AAAA;AAAA,iBAgD3C,kBAAA,CACd,IAAA,EAAM,yBAAA,GACL,YAAY"}
1
+ {"version":3,"file":"bridge.d.ts","names":[],"sources":["../../src/mcp-apps/bridge.ts"],"mappings":";;;;KAoBY,iBAAA,GAAoB,gBAAgB;AAAA,KAEpC,yBAAA;EACV,KAAA,EAAO,iBAAA;EACP,QAAA,GAAW,oBAAA;EACX,QAAA,GAAW,cAAA;EACX,WAAA,GAAc,iBAAA;AAAA;AAAA,KAGJ,YAAA;EACV,SAAA,GAAY,KAAA,EAAO,YAAA;EACnB,OAAA;EACA,eAAA,GAAkB,KAAA;EAClB,gBAAA,GAAmB,MAAA;EACnB,wBAAA,GAA2B,WAAA,EAAa,iBAAiB;AAAA;AAAA,iBAgD3C,kBAAA,CACd,IAAA,EAAM,yBAAA,GACL,YAAY"}
@@ -1,4 +1,5 @@
1
1
  import "./types.js";
2
+ import { isRecord } from "../utils/json/is-json.js";
2
3
  //#region src/mcp-apps/bridge.ts
3
4
  const VALID_DISPLAY_MODES = [
4
5
  "inline",
@@ -38,8 +39,7 @@ function isNotification(msg) {
38
39
  return !("id" in msg);
39
40
  }
40
41
  function createMcpAppBridge(opts) {
41
- const { frame, handlers = {}, hostInfo = DEFAULT_HOST_INFO, hostContext = {}, targetWindow = typeof window !== "undefined" ? window : void 0 } = opts;
42
- if (!targetWindow) throw new Error("createMcpAppBridge requires a window context");
42
+ const { frame, handlers = {}, hostInfo = DEFAULT_HOST_INFO, hostContext = {} } = opts;
43
43
  const post = (msg) => {
44
44
  frame.sendMessage(msg);
45
45
  };
@@ -61,10 +61,12 @@ function createMcpAppBridge(opts) {
61
61
  try {
62
62
  const params = req.params;
63
63
  switch (normalizeMethod(req.method)) {
64
- case "ui/initialize":
64
+ case "ui/initialize": {
65
+ const requestedProtocolVersion = isRecord(params) && typeof params.protocolVersion === "string" ? params.protocolVersion : "0.1";
65
66
  respond(req.id, { result: {
66
- protocolVersion: "0.1",
67
+ protocolVersion: requestedProtocolVersion,
67
68
  host: hostInfo,
69
+ hostInfo,
68
70
  hostContext,
69
71
  capabilities: {
70
72
  tools: handlers.callTool ? {} : void 0,
@@ -75,9 +77,18 @@ function createMcpAppBridge(opts) {
75
77
  requestDisplayMode: !!handlers.requestDisplayMode,
76
78
  updateModelContext: !!handlers.updateModelContext
77
79
  }
80
+ },
81
+ hostCapabilities: {
82
+ ...handlers.openLink ? { openLinks: {} } : {},
83
+ ...handlers.callTool ? { serverTools: {} } : {},
84
+ ...handlers.readResource || handlers.listResources ? { serverResources: {} } : {},
85
+ ...handlers.updateModelContext ? { updateModelContext: { text: {} } } : {},
86
+ ...handlers.sendMessage ? { message: { text: {} } } : {},
87
+ ...handlers.onLog ? { logging: {} } : {}
78
88
  }
79
89
  } });
80
90
  return;
91
+ }
81
92
  case "tools/call": {
82
93
  if (!handlers.callTool) {
83
94
  errorResponse(req.id, JSONRPC_ERROR.methodNotFound, "tools/call is not supported by this host");
@@ -214,24 +225,25 @@ function createMcpAppBridge(opts) {
214
225
  }
215
226
  };
216
227
  const onMessage = (event) => {
217
- if (event.source !== frame.iframe.contentWindow) return;
218
- if (event.origin !== frame.origin) return;
219
228
  if (!isJsonRpcMessage(event.data)) return;
220
229
  const msg = event.data;
221
230
  if (isRequest(msg)) handleRequest(msg);
222
231
  else if (isNotification(msg)) handleNotification(msg);
223
232
  };
224
- targetWindow.addEventListener("message", onMessage);
225
233
  return {
226
- dispose: () => {
227
- targetWindow.removeEventListener("message", onMessage);
228
- },
234
+ onMessage,
235
+ dispose: () => {},
229
236
  notifyToolInput: (input) => {
230
237
  post({
231
238
  jsonrpc: "2.0",
232
239
  method: "notifications/tools/call/input",
233
240
  params: { input }
234
241
  });
242
+ post({
243
+ jsonrpc: "2.0",
244
+ method: "ui/notifications/tool-input",
245
+ params: isRecord(input) ? { arguments: input } : {}
246
+ });
235
247
  },
236
248
  notifyToolResult: (result) => {
237
249
  post({
@@ -239,6 +251,14 @@ function createMcpAppBridge(opts) {
239
251
  method: "notifications/tools/call/result",
240
252
  params: { result }
241
253
  });
254
+ post({
255
+ jsonrpc: "2.0",
256
+ method: "ui/notifications/tool-result",
257
+ params: isRecord(result) ? result : { content: [{
258
+ type: "text",
259
+ text: String(result)
260
+ }] }
261
+ });
242
262
  },
243
263
  notifyHostContextChanged: (ctx) => {
244
264
  post({
@@ -246,6 +266,11 @@ function createMcpAppBridge(opts) {
246
266
  method: "notifications/host_context/changed",
247
267
  params: ctx
248
268
  });
269
+ post({
270
+ jsonrpc: "2.0",
271
+ method: "ui/notifications/host-context-changed",
272
+ params: ctx
273
+ });
249
274
  }
250
275
  };
251
276
  }
@@ -1 +1 @@
1
- {"version":3,"file":"bridge.js","names":[],"sources":["../../src/mcp-apps/bridge.ts"],"sourcesContent":["import type { RenderedFrame } from \"safe-content-frame\";\nimport {\n MCP_APP_PROTOCOL_VERSION,\n type McpAppBridgeHandlers,\n type McpAppDisplayMode,\n type McpAppHostContext,\n type McpAppHostInfo,\n type McpAppJsonRpcMessage,\n type McpAppJsonRpcNotification,\n type McpAppJsonRpcRequest,\n type McpAppJsonRpcResponse,\n} from \"./types\";\n\nconst VALID_DISPLAY_MODES = [\n \"inline\",\n \"fullscreen\",\n \"pip\",\n] as const satisfies readonly McpAppDisplayMode[];\n\nexport type McpAppBridgeFrame = Pick<\n RenderedFrame,\n \"iframe\" | \"origin\" | \"sendMessage\"\n>;\n\nexport type CreateMcpAppBridgeOptions = {\n frame: McpAppBridgeFrame;\n handlers?: McpAppBridgeHandlers | undefined;\n hostInfo?: McpAppHostInfo | undefined;\n hostContext?: McpAppHostContext | undefined;\n targetWindow?: Window | undefined;\n};\n\nexport type McpAppBridge = {\n dispose: () => void;\n notifyToolInput: (input: unknown) => void;\n notifyToolResult: (result: unknown) => void;\n notifyHostContextChanged: (hostContext: McpAppHostContext) => void;\n};\n\nconst DEFAULT_HOST_INFO: McpAppHostInfo = {\n name: \"assistant-ui\",\n version: \"0.1\",\n};\n\n// Accept both the legacy method names and the MCP-UI 2026-01-26 names that\n// `ui/*` capable widgets (e.g. xmcp's host-bridge) emit. Normalize on input\n// so downstream switch statements only need to know the legacy names.\nconst METHOD_ALIASES: Record<string, string> = {\n \"ui/notifications/initialized\": \"notifications/initialized\",\n \"ui/notifications/size-changed\": \"notifications/size_changed\",\n \"ui/request-display-mode\": \"requestDisplayMode\",\n \"ui/open-link\": \"openLink\",\n \"ui/update-model-context\": \"updateModelContext\",\n \"ui/message\": \"sendMessage\",\n \"notifications/message\": \"notifications/log\",\n};\n\nconst normalizeMethod = (method: string): string =>\n METHOD_ALIASES[method] ?? method;\n\nconst JSONRPC_ERROR = {\n parseError: -32700,\n invalidRequest: -32600,\n methodNotFound: -32601,\n invalidParams: -32602,\n internalError: -32603,\n} as const;\n\nfunction isJsonRpcMessage(value: unknown): value is McpAppJsonRpcMessage {\n if (!value || typeof value !== \"object\") return false;\n const v = value as Record<string, unknown>;\n return v.jsonrpc === \"2.0\" && typeof v.method === \"string\";\n}\n\nfunction isRequest(msg: McpAppJsonRpcMessage): msg is McpAppJsonRpcRequest {\n return \"id\" in msg;\n}\n\nfunction isNotification(\n msg: McpAppJsonRpcMessage,\n): msg is McpAppJsonRpcNotification {\n return !(\"id\" in msg);\n}\n\nexport function createMcpAppBridge(\n opts: CreateMcpAppBridgeOptions,\n): McpAppBridge {\n const {\n frame,\n handlers = {},\n hostInfo = DEFAULT_HOST_INFO,\n hostContext = {},\n targetWindow = typeof window !== \"undefined\" ? window : undefined,\n } = opts;\n\n if (!targetWindow) {\n throw new Error(\"createMcpAppBridge requires a window context\");\n }\n\n const post = (msg: McpAppJsonRpcMessage) => {\n frame.sendMessage(msg);\n };\n\n const respond = (\n id: McpAppJsonRpcRequest[\"id\"],\n payload:\n | { result: unknown }\n | { error: { code: number; message: string; data?: unknown } },\n ) => {\n const res: McpAppJsonRpcResponse = {\n jsonrpc: \"2.0\",\n id,\n ...payload,\n };\n post(res);\n };\n\n const errorResponse = (\n id: McpAppJsonRpcRequest[\"id\"],\n code: number,\n message: string,\n data?: unknown,\n ) => {\n respond(id, {\n error: {\n code,\n message,\n ...(data !== undefined ? { data } : {}),\n },\n });\n };\n\n const handleRequest = async (req: McpAppJsonRpcRequest) => {\n try {\n const params = req.params;\n\n switch (normalizeMethod(req.method)) {\n case \"ui/initialize\": {\n respond(req.id, {\n result: {\n protocolVersion: MCP_APP_PROTOCOL_VERSION,\n host: hostInfo,\n hostContext,\n capabilities: {\n tools: handlers.callTool ? {} : undefined,\n resources:\n handlers.readResource || handlers.listResources\n ? {}\n : undefined,\n ui: {\n sendMessage: !!handlers.sendMessage,\n openLink: !!handlers.openLink,\n requestDisplayMode: !!handlers.requestDisplayMode,\n updateModelContext: !!handlers.updateModelContext,\n },\n },\n },\n });\n return;\n }\n\n case \"tools/call\": {\n if (!handlers.callTool) {\n errorResponse(\n req.id,\n JSONRPC_ERROR.methodNotFound,\n \"tools/call is not supported by this host\",\n );\n return;\n }\n const callParams = (params ?? {}) as {\n name?: unknown;\n arguments?: unknown;\n };\n if (typeof callParams.name !== \"string\") {\n errorResponse(\n req.id,\n JSONRPC_ERROR.invalidParams,\n \"tools/call requires a string 'name'\",\n );\n return;\n }\n if (\n handlers.allowedTools &&\n !handlers.allowedTools.includes(callParams.name)\n ) {\n errorResponse(\n req.id,\n JSONRPC_ERROR.invalidParams,\n `tool '${callParams.name}' is not allowed for this app`,\n );\n return;\n }\n let callArgs: Record<string, unknown> | undefined;\n if (callParams.arguments !== undefined) {\n if (\n callParams.arguments === null ||\n typeof callParams.arguments !== \"object\" ||\n Array.isArray(callParams.arguments)\n ) {\n errorResponse(\n req.id,\n JSONRPC_ERROR.invalidParams,\n \"tools/call 'arguments' must be an object\",\n );\n return;\n }\n callArgs = callParams.arguments as Record<string, unknown>;\n }\n const result = await handlers.callTool({\n name: callParams.name,\n ...(callArgs !== undefined ? { arguments: callArgs } : {}),\n });\n respond(req.id, { result });\n return;\n }\n\n case \"resources/read\": {\n if (!handlers.readResource) {\n errorResponse(\n req.id,\n JSONRPC_ERROR.methodNotFound,\n \"resources/read is not supported by this host\",\n );\n return;\n }\n const readParams = (params ?? {}) as { uri?: unknown };\n if (typeof readParams.uri !== \"string\") {\n errorResponse(\n req.id,\n JSONRPC_ERROR.invalidParams,\n \"resources/read requires a string 'uri'\",\n );\n return;\n }\n respond(req.id, {\n result: await handlers.readResource({ uri: readParams.uri }),\n });\n return;\n }\n\n case \"resources/list\": {\n if (!handlers.listResources) {\n errorResponse(\n req.id,\n JSONRPC_ERROR.methodNotFound,\n \"resources/list is not supported by this host\",\n );\n return;\n }\n respond(req.id, {\n result: (await handlers.listResources(params)) ?? null,\n });\n return;\n }\n\n case \"openLink\": {\n if (!handlers.openLink) {\n errorResponse(\n req.id,\n JSONRPC_ERROR.methodNotFound,\n \"openLink is not supported by this host\",\n );\n return;\n }\n const linkParams = (params ?? {}) as { url?: unknown };\n if (typeof linkParams.url !== \"string\") {\n errorResponse(\n req.id,\n JSONRPC_ERROR.invalidParams,\n \"openLink requires a string 'url'\",\n );\n return;\n }\n let linkProtocol: string;\n try {\n linkProtocol = new URL(linkParams.url).protocol;\n } catch {\n errorResponse(\n req.id,\n JSONRPC_ERROR.invalidParams,\n \"openLink requires a valid URL\",\n );\n return;\n }\n if (linkProtocol !== \"https:\" && linkProtocol !== \"http:\") {\n errorResponse(\n req.id,\n JSONRPC_ERROR.invalidParams,\n \"openLink only accepts http(s) URLs\",\n );\n return;\n }\n respond(req.id, {\n result: await handlers.openLink({ url: linkParams.url }),\n });\n return;\n }\n\n case \"sendMessage\": {\n if (!handlers.sendMessage) {\n errorResponse(\n req.id,\n JSONRPC_ERROR.methodNotFound,\n \"sendMessage is not supported by this host\",\n );\n return;\n }\n respond(req.id, {\n result: (await handlers.sendMessage(params)) ?? null,\n });\n return;\n }\n\n case \"updateModelContext\": {\n if (!handlers.updateModelContext) {\n errorResponse(\n req.id,\n JSONRPC_ERROR.methodNotFound,\n \"updateModelContext is not supported by this host\",\n );\n return;\n }\n respond(req.id, {\n result: (await handlers.updateModelContext(params)) ?? null,\n });\n return;\n }\n\n case \"requestDisplayMode\": {\n if (!handlers.requestDisplayMode) {\n errorResponse(\n req.id,\n JSONRPC_ERROR.methodNotFound,\n \"requestDisplayMode is not supported by this host\",\n );\n return;\n }\n const modeParams = (params ?? {}) as { mode?: unknown };\n if (\n typeof modeParams.mode !== \"string\" ||\n !VALID_DISPLAY_MODES.includes(modeParams.mode as McpAppDisplayMode)\n ) {\n errorResponse(\n req.id,\n JSONRPC_ERROR.invalidParams,\n \"requestDisplayMode requires a valid 'mode'\",\n );\n return;\n }\n respond(req.id, {\n result: await handlers.requestDisplayMode({\n mode: modeParams.mode as McpAppDisplayMode,\n }),\n });\n return;\n }\n\n default: {\n errorResponse(\n req.id,\n JSONRPC_ERROR.methodNotFound,\n `Unknown method: ${req.method}`,\n );\n }\n }\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n handlers.onError?.(error);\n errorResponse(req.id, JSONRPC_ERROR.internalError, error.message);\n }\n };\n\n const handleNotification = (note: McpAppJsonRpcNotification) => {\n switch (normalizeMethod(note.method)) {\n case \"notifications/initialized\": {\n handlers.onInitialized?.();\n return;\n }\n case \"notifications/size_changed\": {\n const p = (note.params ?? {}) as { width?: number; height?: number };\n handlers.onSizeChange?.({\n ...(typeof p.width === \"number\" ? { width: p.width } : {}),\n ...(typeof p.height === \"number\" ? { height: p.height } : {}),\n });\n return;\n }\n case \"notifications/log\": {\n handlers.onLog?.(note.params);\n return;\n }\n case \"notifications/request_teardown\": {\n handlers.onRequestTeardown?.(note.params);\n return;\n }\n case \"notifications/error\": {\n const p = (note.params ?? {}) as { message?: string };\n handlers.onError?.(\n new Error(typeof p.message === \"string\" ? p.message : \"Widget error\"),\n );\n return;\n }\n default:\n return;\n }\n };\n\n // Cross-origin guard: ignore any postMessage not originating from this\n // app's iframe contentWindow at the SafeContentFrame-issued origin.\n const onMessage = (event: MessageEvent) => {\n if (event.source !== frame.iframe.contentWindow) return;\n if (event.origin !== frame.origin) return;\n if (!isJsonRpcMessage(event.data)) return;\n\n const msg = event.data;\n if (isRequest(msg)) {\n void handleRequest(msg);\n } else if (isNotification(msg)) {\n handleNotification(msg);\n }\n };\n\n targetWindow.addEventListener(\"message\", onMessage);\n\n return {\n dispose: () => {\n targetWindow.removeEventListener(\"message\", onMessage);\n },\n notifyToolInput: (input: unknown) => {\n post({\n jsonrpc: \"2.0\",\n method: \"notifications/tools/call/input\",\n params: { input },\n });\n },\n notifyToolResult: (result: unknown) => {\n post({\n jsonrpc: \"2.0\",\n method: \"notifications/tools/call/result\",\n params: { result },\n });\n },\n notifyHostContextChanged: (ctx: McpAppHostContext) => {\n post({\n jsonrpc: \"2.0\",\n method: \"notifications/host_context/changed\",\n params: ctx,\n });\n },\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"bridge.js","names":[],"sources":["../../src/mcp-apps/bridge.ts"],"sourcesContent":["import type { SandboxHostFrame } from \"../sandbox-host/SandboxHost\";\nimport {\n MCP_APP_PROTOCOL_VERSION,\n type McpAppBridgeHandlers,\n type McpAppDisplayMode,\n type McpAppHostContext,\n type McpAppHostInfo,\n type McpAppJsonRpcMessage,\n type McpAppJsonRpcNotification,\n type McpAppJsonRpcRequest,\n type McpAppJsonRpcResponse,\n} from \"./types\";\nimport { isRecord } from \"../utils/json/is-json\";\n\nconst VALID_DISPLAY_MODES = [\n \"inline\",\n \"fullscreen\",\n \"pip\",\n] as const satisfies readonly McpAppDisplayMode[];\n\nexport type McpAppBridgeFrame = SandboxHostFrame;\n\nexport type CreateMcpAppBridgeOptions = {\n frame: McpAppBridgeFrame;\n handlers?: McpAppBridgeHandlers | undefined;\n hostInfo?: McpAppHostInfo | undefined;\n hostContext?: McpAppHostContext | undefined;\n};\n\nexport type McpAppBridge = {\n onMessage: (event: MessageEvent) => void;\n dispose: () => void;\n notifyToolInput: (input: unknown) => void;\n notifyToolResult: (result: unknown) => void;\n notifyHostContextChanged: (hostContext: McpAppHostContext) => void;\n};\n\nconst DEFAULT_HOST_INFO: McpAppHostInfo = {\n name: \"assistant-ui\",\n version: \"0.1\",\n};\n\n// Accept both the legacy method names and the MCP-UI 2026-01-26 names that\n// `ui/*` capable widgets (e.g. xmcp's host-bridge) emit. Normalize on input\n// so downstream switch statements only need to know the legacy names.\nconst METHOD_ALIASES: Record<string, string> = {\n \"ui/notifications/initialized\": \"notifications/initialized\",\n \"ui/notifications/size-changed\": \"notifications/size_changed\",\n \"ui/request-display-mode\": \"requestDisplayMode\",\n \"ui/open-link\": \"openLink\",\n \"ui/update-model-context\": \"updateModelContext\",\n \"ui/message\": \"sendMessage\",\n \"notifications/message\": \"notifications/log\",\n};\n\nconst normalizeMethod = (method: string): string =>\n METHOD_ALIASES[method] ?? method;\n\nconst JSONRPC_ERROR = {\n parseError: -32700,\n invalidRequest: -32600,\n methodNotFound: -32601,\n invalidParams: -32602,\n internalError: -32603,\n} as const;\n\nfunction isJsonRpcMessage(value: unknown): value is McpAppJsonRpcMessage {\n if (!value || typeof value !== \"object\") return false;\n const v = value as Record<string, unknown>;\n return v.jsonrpc === \"2.0\" && typeof v.method === \"string\";\n}\n\nfunction isRequest(msg: McpAppJsonRpcMessage): msg is McpAppJsonRpcRequest {\n return \"id\" in msg;\n}\n\nfunction isNotification(\n msg: McpAppJsonRpcMessage,\n): msg is McpAppJsonRpcNotification {\n return !(\"id\" in msg);\n}\n\nexport function createMcpAppBridge(\n opts: CreateMcpAppBridgeOptions,\n): McpAppBridge {\n const {\n frame,\n handlers = {},\n hostInfo = DEFAULT_HOST_INFO,\n hostContext = {},\n } = opts;\n\n const post = (msg: McpAppJsonRpcMessage) => {\n frame.sendMessage(msg);\n };\n\n const respond = (\n id: McpAppJsonRpcRequest[\"id\"],\n payload:\n | { result: unknown }\n | { error: { code: number; message: string; data?: unknown } },\n ) => {\n const res: McpAppJsonRpcResponse = {\n jsonrpc: \"2.0\",\n id,\n ...payload,\n };\n post(res);\n };\n\n const errorResponse = (\n id: McpAppJsonRpcRequest[\"id\"],\n code: number,\n message: string,\n data?: unknown,\n ) => {\n respond(id, {\n error: {\n code,\n message,\n ...(data !== undefined ? { data } : {}),\n },\n });\n };\n\n const handleRequest = async (req: McpAppJsonRpcRequest) => {\n try {\n const params = req.params;\n\n switch (normalizeMethod(req.method)) {\n case \"ui/initialize\": {\n const requestedProtocolVersion =\n isRecord(params) && typeof params.protocolVersion === \"string\"\n ? params.protocolVersion\n : MCP_APP_PROTOCOL_VERSION;\n respond(req.id, {\n result: {\n protocolVersion: requestedProtocolVersion,\n host: hostInfo,\n hostInfo,\n hostContext,\n capabilities: {\n tools: handlers.callTool ? {} : undefined,\n resources:\n handlers.readResource || handlers.listResources\n ? {}\n : undefined,\n ui: {\n sendMessage: !!handlers.sendMessage,\n openLink: !!handlers.openLink,\n requestDisplayMode: !!handlers.requestDisplayMode,\n updateModelContext: !!handlers.updateModelContext,\n },\n },\n hostCapabilities: {\n ...(handlers.openLink ? { openLinks: {} } : {}),\n ...(handlers.callTool ? { serverTools: {} } : {}),\n ...(handlers.readResource || handlers.listResources\n ? { serverResources: {} }\n : {}),\n ...(handlers.updateModelContext\n ? { updateModelContext: { text: {} } }\n : {}),\n ...(handlers.sendMessage ? { message: { text: {} } } : {}),\n ...(handlers.onLog ? { logging: {} } : {}),\n },\n },\n });\n return;\n }\n\n case \"tools/call\": {\n if (!handlers.callTool) {\n errorResponse(\n req.id,\n JSONRPC_ERROR.methodNotFound,\n \"tools/call is not supported by this host\",\n );\n return;\n }\n const callParams = (params ?? {}) as {\n name?: unknown;\n arguments?: unknown;\n };\n if (typeof callParams.name !== \"string\") {\n errorResponse(\n req.id,\n JSONRPC_ERROR.invalidParams,\n \"tools/call requires a string 'name'\",\n );\n return;\n }\n if (\n handlers.allowedTools &&\n !handlers.allowedTools.includes(callParams.name)\n ) {\n errorResponse(\n req.id,\n JSONRPC_ERROR.invalidParams,\n `tool '${callParams.name}' is not allowed for this app`,\n );\n return;\n }\n let callArgs: Record<string, unknown> | undefined;\n if (callParams.arguments !== undefined) {\n if (\n callParams.arguments === null ||\n typeof callParams.arguments !== \"object\" ||\n Array.isArray(callParams.arguments)\n ) {\n errorResponse(\n req.id,\n JSONRPC_ERROR.invalidParams,\n \"tools/call 'arguments' must be an object\",\n );\n return;\n }\n callArgs = callParams.arguments as Record<string, unknown>;\n }\n const result = await handlers.callTool({\n name: callParams.name,\n ...(callArgs !== undefined ? { arguments: callArgs } : {}),\n });\n respond(req.id, { result });\n return;\n }\n\n case \"resources/read\": {\n if (!handlers.readResource) {\n errorResponse(\n req.id,\n JSONRPC_ERROR.methodNotFound,\n \"resources/read is not supported by this host\",\n );\n return;\n }\n const readParams = (params ?? {}) as { uri?: unknown };\n if (typeof readParams.uri !== \"string\") {\n errorResponse(\n req.id,\n JSONRPC_ERROR.invalidParams,\n \"resources/read requires a string 'uri'\",\n );\n return;\n }\n respond(req.id, {\n result: await handlers.readResource({ uri: readParams.uri }),\n });\n return;\n }\n\n case \"resources/list\": {\n if (!handlers.listResources) {\n errorResponse(\n req.id,\n JSONRPC_ERROR.methodNotFound,\n \"resources/list is not supported by this host\",\n );\n return;\n }\n respond(req.id, {\n result: (await handlers.listResources(params)) ?? null,\n });\n return;\n }\n\n case \"openLink\": {\n if (!handlers.openLink) {\n errorResponse(\n req.id,\n JSONRPC_ERROR.methodNotFound,\n \"openLink is not supported by this host\",\n );\n return;\n }\n const linkParams = (params ?? {}) as { url?: unknown };\n if (typeof linkParams.url !== \"string\") {\n errorResponse(\n req.id,\n JSONRPC_ERROR.invalidParams,\n \"openLink requires a string 'url'\",\n );\n return;\n }\n let linkProtocol: string;\n try {\n linkProtocol = new URL(linkParams.url).protocol;\n } catch {\n errorResponse(\n req.id,\n JSONRPC_ERROR.invalidParams,\n \"openLink requires a valid URL\",\n );\n return;\n }\n if (linkProtocol !== \"https:\" && linkProtocol !== \"http:\") {\n errorResponse(\n req.id,\n JSONRPC_ERROR.invalidParams,\n \"openLink only accepts http(s) URLs\",\n );\n return;\n }\n respond(req.id, {\n result: await handlers.openLink({ url: linkParams.url }),\n });\n return;\n }\n\n case \"sendMessage\": {\n if (!handlers.sendMessage) {\n errorResponse(\n req.id,\n JSONRPC_ERROR.methodNotFound,\n \"sendMessage is not supported by this host\",\n );\n return;\n }\n respond(req.id, {\n result: (await handlers.sendMessage(params)) ?? null,\n });\n return;\n }\n\n case \"updateModelContext\": {\n if (!handlers.updateModelContext) {\n errorResponse(\n req.id,\n JSONRPC_ERROR.methodNotFound,\n \"updateModelContext is not supported by this host\",\n );\n return;\n }\n respond(req.id, {\n result: (await handlers.updateModelContext(params)) ?? null,\n });\n return;\n }\n\n case \"requestDisplayMode\": {\n if (!handlers.requestDisplayMode) {\n errorResponse(\n req.id,\n JSONRPC_ERROR.methodNotFound,\n \"requestDisplayMode is not supported by this host\",\n );\n return;\n }\n const modeParams = (params ?? {}) as { mode?: unknown };\n if (\n typeof modeParams.mode !== \"string\" ||\n !VALID_DISPLAY_MODES.includes(modeParams.mode as McpAppDisplayMode)\n ) {\n errorResponse(\n req.id,\n JSONRPC_ERROR.invalidParams,\n \"requestDisplayMode requires a valid 'mode'\",\n );\n return;\n }\n respond(req.id, {\n result: await handlers.requestDisplayMode({\n mode: modeParams.mode as McpAppDisplayMode,\n }),\n });\n return;\n }\n\n default: {\n errorResponse(\n req.id,\n JSONRPC_ERROR.methodNotFound,\n `Unknown method: ${req.method}`,\n );\n }\n }\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n handlers.onError?.(error);\n errorResponse(req.id, JSONRPC_ERROR.internalError, error.message);\n }\n };\n\n const handleNotification = (note: McpAppJsonRpcNotification) => {\n switch (normalizeMethod(note.method)) {\n case \"notifications/initialized\": {\n handlers.onInitialized?.();\n return;\n }\n case \"notifications/size_changed\": {\n const p = (note.params ?? {}) as { width?: number; height?: number };\n handlers.onSizeChange?.({\n ...(typeof p.width === \"number\" ? { width: p.width } : {}),\n ...(typeof p.height === \"number\" ? { height: p.height } : {}),\n });\n return;\n }\n case \"notifications/log\": {\n handlers.onLog?.(note.params);\n return;\n }\n case \"notifications/request_teardown\": {\n handlers.onRequestTeardown?.(note.params);\n return;\n }\n case \"notifications/error\": {\n const p = (note.params ?? {}) as { message?: string };\n handlers.onError?.(\n new Error(typeof p.message === \"string\" ? p.message : \"Widget error\"),\n );\n return;\n }\n default:\n return;\n }\n };\n\n // The host applies the cross-origin guard before delegating; this only\n // validates the JSON-RPC envelope.\n const onMessage = (event: MessageEvent) => {\n if (!isJsonRpcMessage(event.data)) return;\n\n const msg = event.data;\n if (isRequest(msg)) {\n void handleRequest(msg);\n } else if (isNotification(msg)) {\n handleNotification(msg);\n }\n };\n\n return {\n onMessage,\n dispose: () => {},\n notifyToolInput: (input: unknown) => {\n post({\n jsonrpc: \"2.0\",\n method: \"notifications/tools/call/input\",\n params: { input },\n });\n post({\n jsonrpc: \"2.0\",\n method: \"ui/notifications/tool-input\",\n params: isRecord(input) ? { arguments: input } : {},\n });\n },\n notifyToolResult: (result: unknown) => {\n post({\n jsonrpc: \"2.0\",\n method: \"notifications/tools/call/result\",\n params: { result },\n });\n post({\n jsonrpc: \"2.0\",\n method: \"ui/notifications/tool-result\",\n params: isRecord(result)\n ? result\n : { content: [{ type: \"text\", text: String(result) }] },\n });\n },\n notifyHostContextChanged: (ctx: McpAppHostContext) => {\n post({\n jsonrpc: \"2.0\",\n method: \"notifications/host_context/changed\",\n params: ctx,\n });\n post({\n jsonrpc: \"2.0\",\n method: \"ui/notifications/host-context-changed\",\n params: ctx,\n });\n },\n };\n}\n"],"mappings":"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"}
@@ -1,6 +1,5 @@
1
+ import { SandboxHostConfig } from "../sandbox-host/SandboxHost.js";
1
2
  import { McpAppMetadata, ToolCallMessagePartMcpMetadata } from "@assistant-ui/core";
2
- import { CSSProperties } from "react";
3
- import { SandboxOption } from "safe-content-frame";
4
3
 
5
4
  //#region src/mcp-apps/types.d.ts
6
5
  declare const MCP_APP_MIME_TYPE: "text/html;profile=mcp-app";
@@ -94,16 +93,7 @@ type McpAppBridgeHandlers = {
94
93
  onLog?: (params: unknown) => void;
95
94
  onError?: (error: Error) => void;
96
95
  };
97
- type McpAppSandboxConfig = {
98
- sandbox?: SandboxOption[];
99
- useShadowDom?: boolean;
100
- enableBrowserCaching?: boolean;
101
- salt?: string;
102
- product?: string;
103
- className?: string;
104
- style?: CSSProperties;
105
- unsafeDocumentWrite?: boolean;
106
- };
96
+ type McpAppSandboxConfig = SandboxHostConfig;
107
97
  type McpAppFrameProps = {
108
98
  app: McpAppMetadata;
109
99
  resource: McpAppResource;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","names":[],"sources":["../../src/mcp-apps/types.ts"],"mappings":";;;;;cASa,iBAAA;AAAA,cAEA,wBAAA;AAAA,KAED,iBAAA;EACV,cAAA;EACA,eAAA;EACA,YAAA;EAAA,CACC,CAAA;AAAA;AAAA,KAGS,kBAAA;EACV,aAAA;EACA,GAAA,GAAM,iBAAA;EACN,WAAA,GAAc,MAAM;EAAA,CACnB,CAAA;AAAA;AAAA,KAGS,cAAA;EACV,GAAA;EACA,QAAA,SAAiB,iBAAA;EACjB,IAAA;EACA,IAAA,GAAO,kBAAkB;AAAA;AAAA,KAGf,iBAAA;AAAA,KAEA,iBAAA;EACV,KAAA;EACA,WAAA,GAAc,iBAAA;EACd,qBAAA,GAAwB,iBAAiB;EAAA,CACxC,CAAA;AAAA;AAAA,KAGS,cAAA;EACV,IAAA;EACA,OAAO;AAAA;;AArBG;AAGZ;;;KA0BY,WAAA;EACV,YAAA,GAAe,MAAA;IAAU,GAAA;EAAA,MAAkB,OAAA,CAAQ,cAAA;EACnD,QAAA,GAAW,MAAA,EAAQ,oBAAA,KAAyB,OAAA;EAC5C,YAAA,GAAe,MAAA;IAAU,GAAA;EAAA,MAAkB,OAAA;EAC3C,aAAA,GAAgB,MAAA,eAAqB,OAAA;AAAA;;;;AAvBV;AAE7B;;;;KAgCY,wBAAA;EACV,GAAA;EACA,KAAA,UAAe,KAAA;EACf,OAAA,GACI,MAAA,0BACO,MAAA,mBAAyB,OAAA,CAAQ,MAAA;AAAA;AAAA,KAGlC,oBAAA;EACV,IAAA;EACA,SAAA,GAAY,MAAM;AAAA;AAAA,KAGR,oBAAA;EACV,YAAA;EACA,QAAA,IAAY,MAAA,EAAQ,oBAAA,KAAyB,OAAA;EAC7C,YAAA,IAAgB,MAAA;IAAU,GAAA;EAAA,MAAkB,OAAA;EAC5C,aAAA,IAAiB,MAAA,eAAqB,OAAA;EACtC,QAAA,IAAY,MAAA;IAAU,GAAA;EAAA,MAAkB,OAAA;EACxC,WAAA,IAAe,MAAA,cAAoB,OAAA;EACnC,kBAAA,IAAsB,MAAA,cAAoB,OAAA;EAC1C,kBAAA,IAAsB,MAAA;IACpB,IAAA,EAAM,iBAAA;EAAA,MACF,OAAA;IAAU,IAAA,EAAM,iBAAA;EAAA;IAAyB,IAAA,EAAM,iBAAA;EAAA;EACrD,YAAA,IAAgB,MAAA;IAAU,KAAA;IAAgB,MAAA;EAAA;EAC1C,aAAA;EACA,iBAAA,IAAqB,MAAA;EACrB,KAAA,IAAS,MAAA;EACT,OAAA,IAAW,KAAA,EAAO,KAAA;AAAA;AAAA,KAGR,mBAAA;EACV,OAAA,GAAU,aAAA;EACV,YAAA;EACA,oBAAA;EACA,IAAA;EACA,OAAA;EACA,SAAA;EACA,KAAA,GAAQ,aAAa;EACrB,mBAAA;AAAA;AAAA,KAGU,gBAAA;EACV,GAAA,EAAK,cAAA;EACL,QAAA,EAAU,cAAA;EACV,KAAA;EACA,MAAA;EACA,OAAA,GAAU,mBAAA;EACV,QAAA,GAAW,oBAAA;EACX,QAAA,GAAW,cAAA;EACX,WAAA,GAAc,iBAAA;EA9CV;;;;EAmDJ,SAAA;AAAA;AAAA,KAGU,oBAAA;EACV,OAAA;EACA,EAAA;EACA,MAAA;EACA,MAAA;AAAA;AAAA,KAGU,yBAAA;EACV,OAAA;EACA,MAAA;EACA,MAAA;AAAA;AAAA,KAGU,kBAAA;EACV,IAAA;EACA,OAAA;EACA,IAAA;AAAA;AAAA,KAGU,qBAAA;EAEN,OAAA;EACA,EAAA;EACA,MAAA;EACA,KAAA;AAAA;EAGA,OAAA;EACA,EAAA;EACA,MAAA;EACA,KAAA,EAAO,kBAAkB;AAAA;AAAA,KAGnB,oBAAA,GACR,oBAAA,GACA,yBAAA,GACA,qBAAA"}
1
+ {"version":3,"file":"types.d.ts","names":[],"sources":["../../src/mcp-apps/types.ts"],"mappings":";;;;cAQa,iBAAA;AAAA,cAEA,wBAAA;AAAA,KAED,iBAAA;EACV,cAAA;EACA,eAAA;EACA,YAAA;EAAA,CACC,CAAA;AAAA;AAAA,KAGS,kBAAA;EACV,aAAA;EACA,GAAA,GAAM,iBAAA;EACN,WAAA,GAAc,MAAM;EAAA,CACnB,CAAA;AAAA;AAAA,KAGS,cAAA;EACV,GAAA;EACA,QAAA,SAAiB,iBAAA;EACjB,IAAA;EACA,IAAA,GAAO,kBAAkB;AAAA;AAAA,KAGf,iBAAA;AAAA,KAEA,iBAAA;EACV,KAAA;EACA,WAAA,GAAc,iBAAA;EACd,qBAAA,GAAwB,iBAAiB;EAAA,CACxC,CAAA;AAAA;AAAA,KAGS,cAAA;EACV,IAAA;EACA,OAAO;AAAA;;AArBG;AAGZ;;;KA0BY,WAAA;EACV,YAAA,GAAe,MAAA;IAAU,GAAA;EAAA,MAAkB,OAAA,CAAQ,cAAA;EACnD,QAAA,GAAW,MAAA,EAAQ,oBAAA,KAAyB,OAAA;EAC5C,YAAA,GAAe,MAAA;IAAU,GAAA;EAAA,MAAkB,OAAA;EAC3C,aAAA,GAAgB,MAAA,eAAqB,OAAA;AAAA;;;;AAvBV;AAE7B;;;;KAgCY,wBAAA;EACV,GAAA;EACA,KAAA,UAAe,KAAA;EACf,OAAA,GACI,MAAA,0BACO,MAAA,mBAAyB,OAAA,CAAQ,MAAA;AAAA;AAAA,KAGlC,oBAAA;EACV,IAAA;EACA,SAAA,GAAY,MAAM;AAAA;AAAA,KAGR,oBAAA;EACV,YAAA;EACA,QAAA,IAAY,MAAA,EAAQ,oBAAA,KAAyB,OAAA;EAC7C,YAAA,IAAgB,MAAA;IAAU,GAAA;EAAA,MAAkB,OAAA;EAC5C,aAAA,IAAiB,MAAA,eAAqB,OAAA;EACtC,QAAA,IAAY,MAAA;IAAU,GAAA;EAAA,MAAkB,OAAA;EACxC,WAAA,IAAe,MAAA,cAAoB,OAAA;EACnC,kBAAA,IAAsB,MAAA,cAAoB,OAAA;EAC1C,kBAAA,IAAsB,MAAA;IACpB,IAAA,EAAM,iBAAA;EAAA,MACF,OAAA;IAAU,IAAA,EAAM,iBAAA;EAAA;IAAyB,IAAA,EAAM,iBAAA;EAAA;EACrD,YAAA,IAAgB,MAAA;IAAU,KAAA;IAAgB,MAAA;EAAA;EAC1C,aAAA;EACA,iBAAA,IAAqB,MAAA;EACrB,KAAA,IAAS,MAAA;EACT,OAAA,IAAW,KAAA,EAAO,KAAA;AAAA;AAAA,KAGR,mBAAA,GAAsB,iBAAiB;AAAA,KAEvC,gBAAA;EACV,GAAA,EAAK,cAAA;EACL,QAAA,EAAU,cAAA;EACV,KAAA;EACA,MAAA;EACA,OAAA,GAAU,mBAAA;EACV,QAAA,GAAW,oBAAA;EACX,QAAA,GAAW,cAAA;EACX,WAAA,GAAc,iBAAA;EApCH;;;;EAyCX,SAAA;AAAA;AAAA,KAGU,oBAAA;EACV,OAAA;EACA,EAAA;EACA,MAAA;EACA,MAAA;AAAA;AAAA,KAGU,yBAAA;EACV,OAAA;EACA,MAAA;EACA,MAAA;AAAA;AAAA,KAGU,kBAAA;EACV,IAAA;EACA,OAAA;EACA,IAAA;AAAA;AAAA,KAGU,qBAAA;EAEN,OAAA;EACA,EAAA;EACA,MAAA;EACA,KAAA;AAAA;EAGA,OAAA;EACA,EAAA;EACA,MAAA;EACA,KAAA,EAAO,kBAAkB;AAAA;AAAA,KAGnB,oBAAA,GACR,oBAAA,GACA,yBAAA,GACA,qBAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","names":[],"sources":["../../src/mcp-apps/types.ts"],"sourcesContent":["import type { CSSProperties } from \"react\";\nimport type {\n McpAppMetadata,\n ToolCallMessagePartMcpMetadata,\n} from \"@assistant-ui/core\";\nimport type { SandboxOption } from \"safe-content-frame\";\n\nexport type { McpAppMetadata, ToolCallMessagePartMcpMetadata };\n\nexport const MCP_APP_MIME_TYPE = \"text/html;profile=mcp-app\" as const;\n\nexport const MCP_APP_PROTOCOL_VERSION = \"0.1\" as const;\n\nexport type McpAppResourceCSP = {\n connectDomains?: string[];\n resourceDomains?: string[];\n frameDomains?: string[];\n [k: string]: unknown;\n};\n\nexport type McpAppResourceMeta = {\n prefersBorder?: boolean;\n csp?: McpAppResourceCSP;\n permissions?: Record<string, unknown>;\n [k: string]: unknown;\n};\n\nexport type McpAppResource = {\n uri: string;\n mimeType: typeof MCP_APP_MIME_TYPE;\n html: string;\n meta?: McpAppResourceMeta;\n};\n\nexport type McpAppDisplayMode = \"inline\" | \"fullscreen\" | \"pip\";\n\nexport type McpAppHostContext = {\n theme?: \"light\" | \"dark\";\n displayMode?: McpAppDisplayMode;\n availableDisplayModes?: McpAppDisplayMode[];\n [k: string]: unknown;\n};\n\nexport type McpAppHostInfo = {\n name: string;\n version: string;\n};\n\n/**\n * What `McpAppRenderer` needs from its host — the data-plane operations\n * the widget can request. Provided by a host resource like\n * `McpAppsRemoteHost`.\n */\nexport type McpAppsHost = {\n loadResource: (params: { uri: string }) => Promise<McpAppResource>;\n callTool: (params: McpAppToolCallParams) => Promise<unknown>;\n readResource: (params: { uri: string }) => Promise<unknown>;\n listResources: (params?: unknown) => Promise<unknown>;\n};\n\n/**\n * Options for `McpAppsRemoteHost`. The host POSTs `{ method, params }` to\n * `url` and expects JSON responses. Method names sent:\n * - `mcp-apps/read-resource` (`{ uri }`) → `McpAppResource`\n * - `tools/call` (`{ name, arguments? }`) → tool result\n * - `resources/read` (`{ uri }`) → resource read result\n * - `resources/list` (`params?`) → list result\n */\nexport type McpAppsRemoteHostOptions = {\n url: string;\n fetch?: typeof fetch;\n headers?:\n | Record<string, string>\n | (() => Record<string, string> | Promise<Record<string, string>>);\n};\n\nexport type McpAppToolCallParams = {\n name: string;\n arguments?: Record<string, unknown>;\n};\n\nexport type McpAppBridgeHandlers = {\n allowedTools?: readonly string[];\n callTool?: (params: McpAppToolCallParams) => Promise<unknown> | unknown;\n readResource?: (params: { uri: string }) => Promise<unknown> | unknown;\n listResources?: (params?: unknown) => Promise<unknown> | unknown;\n openLink?: (params: { url: string }) => Promise<unknown> | unknown;\n sendMessage?: (params: unknown) => Promise<unknown> | unknown;\n updateModelContext?: (params: unknown) => Promise<unknown> | unknown;\n requestDisplayMode?: (params: {\n mode: McpAppDisplayMode;\n }) => Promise<{ mode: McpAppDisplayMode }> | { mode: McpAppDisplayMode };\n onSizeChange?: (params: { width?: number; height?: number }) => void;\n onInitialized?: () => void;\n onRequestTeardown?: (params: unknown) => void;\n onLog?: (params: unknown) => void;\n onError?: (error: Error) => void;\n};\n\nexport type McpAppSandboxConfig = {\n sandbox?: SandboxOption[];\n useShadowDom?: boolean;\n enableBrowserCaching?: boolean;\n salt?: string;\n product?: string;\n className?: string;\n style?: CSSProperties;\n unsafeDocumentWrite?: boolean;\n};\n\nexport type McpAppFrameProps = {\n app: McpAppMetadata;\n resource: McpAppResource;\n input?: unknown;\n output?: unknown;\n sandbox?: McpAppSandboxConfig | undefined;\n handlers?: McpAppBridgeHandlers | undefined;\n hostInfo?: McpAppHostInfo | undefined;\n hostContext?: McpAppHostContext | undefined;\n /**\n * Upper bound (in pixels) for the auto-resize height driven by the widget's\n * `notifications/size_changed`. Defaults to 800.\n */\n maxHeight?: number | undefined;\n};\n\nexport type McpAppJsonRpcRequest = {\n jsonrpc: \"2.0\";\n id: string | number;\n method: string;\n params?: unknown;\n};\n\nexport type McpAppJsonRpcNotification = {\n jsonrpc: \"2.0\";\n method: string;\n params?: unknown;\n};\n\nexport type McpAppJsonRpcError = {\n code: number;\n message: string;\n data?: unknown;\n};\n\nexport type McpAppJsonRpcResponse =\n | {\n jsonrpc: \"2.0\";\n id: string | number;\n result: unknown;\n error?: never;\n }\n | {\n jsonrpc: \"2.0\";\n id: string | number;\n result?: never;\n error: McpAppJsonRpcError;\n };\n\nexport type McpAppJsonRpcMessage =\n | McpAppJsonRpcRequest\n | McpAppJsonRpcNotification\n | McpAppJsonRpcResponse;\n"],"mappings":";AASA,MAAa,oBAAoB;AAEjC,MAAa,2BAA2B"}
1
+ {"version":3,"file":"types.js","names":[],"sources":["../../src/mcp-apps/types.ts"],"sourcesContent":["import type {\n McpAppMetadata,\n ToolCallMessagePartMcpMetadata,\n} from \"@assistant-ui/core\";\nimport type { SandboxHostConfig } from \"../sandbox-host/SandboxHost\";\n\nexport type { McpAppMetadata, ToolCallMessagePartMcpMetadata };\n\nexport const MCP_APP_MIME_TYPE = \"text/html;profile=mcp-app\" as const;\n\nexport const MCP_APP_PROTOCOL_VERSION = \"0.1\" as const;\n\nexport type McpAppResourceCSP = {\n connectDomains?: string[];\n resourceDomains?: string[];\n frameDomains?: string[];\n [k: string]: unknown;\n};\n\nexport type McpAppResourceMeta = {\n prefersBorder?: boolean;\n csp?: McpAppResourceCSP;\n permissions?: Record<string, unknown>;\n [k: string]: unknown;\n};\n\nexport type McpAppResource = {\n uri: string;\n mimeType: typeof MCP_APP_MIME_TYPE;\n html: string;\n meta?: McpAppResourceMeta;\n};\n\nexport type McpAppDisplayMode = \"inline\" | \"fullscreen\" | \"pip\";\n\nexport type McpAppHostContext = {\n theme?: \"light\" | \"dark\";\n displayMode?: McpAppDisplayMode;\n availableDisplayModes?: McpAppDisplayMode[];\n [k: string]: unknown;\n};\n\nexport type McpAppHostInfo = {\n name: string;\n version: string;\n};\n\n/**\n * What `McpAppRenderer` needs from its host — the data-plane operations\n * the widget can request. Provided by a host resource like\n * `McpAppsRemoteHost`.\n */\nexport type McpAppsHost = {\n loadResource: (params: { uri: string }) => Promise<McpAppResource>;\n callTool: (params: McpAppToolCallParams) => Promise<unknown>;\n readResource: (params: { uri: string }) => Promise<unknown>;\n listResources: (params?: unknown) => Promise<unknown>;\n};\n\n/**\n * Options for `McpAppsRemoteHost`. The host POSTs `{ method, params }` to\n * `url` and expects JSON responses. Method names sent:\n * - `mcp-apps/read-resource` (`{ uri }`) → `McpAppResource`\n * - `tools/call` (`{ name, arguments? }`) → tool result\n * - `resources/read` (`{ uri }`) → resource read result\n * - `resources/list` (`params?`) → list result\n */\nexport type McpAppsRemoteHostOptions = {\n url: string;\n fetch?: typeof fetch;\n headers?:\n | Record<string, string>\n | (() => Record<string, string> | Promise<Record<string, string>>);\n};\n\nexport type McpAppToolCallParams = {\n name: string;\n arguments?: Record<string, unknown>;\n};\n\nexport type McpAppBridgeHandlers = {\n allowedTools?: readonly string[];\n callTool?: (params: McpAppToolCallParams) => Promise<unknown> | unknown;\n readResource?: (params: { uri: string }) => Promise<unknown> | unknown;\n listResources?: (params?: unknown) => Promise<unknown> | unknown;\n openLink?: (params: { url: string }) => Promise<unknown> | unknown;\n sendMessage?: (params: unknown) => Promise<unknown> | unknown;\n updateModelContext?: (params: unknown) => Promise<unknown> | unknown;\n requestDisplayMode?: (params: {\n mode: McpAppDisplayMode;\n }) => Promise<{ mode: McpAppDisplayMode }> | { mode: McpAppDisplayMode };\n onSizeChange?: (params: { width?: number; height?: number }) => void;\n onInitialized?: () => void;\n onRequestTeardown?: (params: unknown) => void;\n onLog?: (params: unknown) => void;\n onError?: (error: Error) => void;\n};\n\nexport type McpAppSandboxConfig = SandboxHostConfig;\n\nexport type McpAppFrameProps = {\n app: McpAppMetadata;\n resource: McpAppResource;\n input?: unknown;\n output?: unknown;\n sandbox?: McpAppSandboxConfig | undefined;\n handlers?: McpAppBridgeHandlers | undefined;\n hostInfo?: McpAppHostInfo | undefined;\n hostContext?: McpAppHostContext | undefined;\n /**\n * Upper bound (in pixels) for the auto-resize height driven by the widget's\n * `notifications/size_changed`. Defaults to 800.\n */\n maxHeight?: number | undefined;\n};\n\nexport type McpAppJsonRpcRequest = {\n jsonrpc: \"2.0\";\n id: string | number;\n method: string;\n params?: unknown;\n};\n\nexport type McpAppJsonRpcNotification = {\n jsonrpc: \"2.0\";\n method: string;\n params?: unknown;\n};\n\nexport type McpAppJsonRpcError = {\n code: number;\n message: string;\n data?: unknown;\n};\n\nexport type McpAppJsonRpcResponse =\n | {\n jsonrpc: \"2.0\";\n id: string | number;\n result: unknown;\n error?: never;\n }\n | {\n jsonrpc: \"2.0\";\n id: string | number;\n result?: never;\n error: McpAppJsonRpcError;\n };\n\nexport type McpAppJsonRpcMessage =\n | McpAppJsonRpcRequest\n | McpAppJsonRpcNotification\n | McpAppJsonRpcResponse;\n"],"mappings":";AAQA,MAAa,oBAAoB;AAEjC,MAAa,2BAA2B"}
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { AssistantFrameHost } from "@assistant-ui/core";
3
- import { useEffect } from "react";
3
+ import { useEffect } from "@assistant-ui/tap/react-shim";
4
4
  //#region src/model-context/frame/useAssistantFrameHost.ts
5
5
  /**
6
6
  * React hook that manages the lifecycle of an AssistantFrameHost and its binding to the current AssistantRuntime.
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { useAui } from "@assistant-ui/store";
3
3
  import { tool } from "@assistant-ui/core";
4
- import { createContext, forwardRef, useContext, useEffect, useId, useRef } from "react";
4
+ import { createContext, forwardRef, useContext, useEffect, useId, useRef } from "@assistant-ui/tap/react-shim";
5
5
  import { jsx } from "react/jsx-runtime";
6
6
  import { useComposedRefs } from "@radix-ui/react-compose-refs";
7
7
  //#region src/model-context/makeAssistantVisible.tsx
@@ -1 +1 @@
1
- {"version":3,"file":"makeAssistantVisible.js","names":[],"sources":["../../src/model-context/makeAssistantVisible.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n useEffect,\n useRef,\n forwardRef,\n type ComponentType,\n type ForwardedRef,\n type PropsWithoutRef,\n useId,\n createContext,\n useContext,\n} from \"react\";\nimport { useAui } from \"@assistant-ui/store\";\nimport { useComposedRefs } from \"@radix-ui/react-compose-refs\";\nimport { tool } from \"@assistant-ui/core\";\n\nconst click = tool({\n parameters: {\n type: \"object\",\n properties: {\n clickId: {\n type: \"string\",\n },\n },\n required: [\"clickId\"],\n },\n execute: async ({ clickId }: { clickId: string }) => {\n const escapedClickId = CSS.escape(clickId);\n const el = document.querySelector(`[data-click-id='${escapedClickId}']`);\n if (el instanceof HTMLElement) {\n el.click();\n\n // todo make adjustable\n await new Promise((resolve) => setTimeout(resolve, 2000));\n return {};\n } else {\n return \"Element not found\";\n }\n },\n});\n\nconst edit = tool({\n parameters: {\n type: \"object\",\n properties: {\n editId: {\n type: \"string\",\n },\n value: {\n type: \"string\",\n },\n },\n required: [\"editId\", \"value\"],\n },\n execute: async ({ editId, value }: { editId: string; value: string }) => {\n const escapedEditId = CSS.escape(editId);\n const el = document.querySelector(`[data-edit-id='${escapedEditId}']`);\n if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement) {\n el.value = value;\n el.dispatchEvent(new Event(\"input\", { bubbles: true }));\n el.dispatchEvent(new Event(\"change\", { bubbles: true }));\n\n // todo make adjustable\n await new Promise((resolve) => setTimeout(resolve, 2000));\n return {};\n } else {\n return \"Element not found\";\n }\n },\n});\n\nconst ReadableContext = createContext<boolean>(false);\n\nexport const makeAssistantVisible = <T extends ComponentType<any>>(\n Component: T,\n config?: { clickable?: boolean | undefined; editable?: boolean | undefined },\n) => {\n const ReadableComponent = forwardRef(\n (props: PropsWithoutRef<T>, outerRef: ForwardedRef<any>) => {\n const isNestedReadable = useContext(ReadableContext);\n\n const clickId = useId();\n const componentRef = useRef<HTMLElement>(null);\n\n const aui = useAui();\n\n const { clickable, editable } = config ?? {};\n useEffect(() => {\n return aui.modelContext().register({\n getModelContext: () => {\n return {\n tools: {\n ...(clickable ? { click } : {}),\n ...(editable ? { edit } : {}),\n },\n system: !isNestedReadable // only pass content if this readable isn't nested in another readable\n ? componentRef.current?.outerHTML\n : undefined,\n };\n },\n });\n }, [isNestedReadable, aui, clickable, editable]);\n\n const ref = useComposedRefs(componentRef, outerRef);\n\n return (\n <ReadableContext.Provider value={true}>\n <Component\n {...(props as any)}\n {...(config?.clickable ? { \"data-click-id\": clickId } : {})}\n {...(config?.editable ? { \"data-edit-id\": clickId } : {})}\n ref={ref}\n />\n </ReadableContext.Provider>\n );\n },\n );\n\n ReadableComponent.displayName = Component.displayName;\n\n return ReadableComponent as unknown as T;\n};\n\nexport default makeAssistantVisible;\n"],"mappings":";;;;;;;AAiBA,MAAM,QAAQ,KAAK;CACjB,YAAY;EACV,MAAM;EACN,YAAY,EACV,SAAS,EACP,MAAM,SACR,EACF;EACA,UAAU,CAAC,SAAS;CACtB;CACA,SAAS,OAAO,EAAE,cAAmC;EACnD,MAAM,iBAAiB,IAAI,OAAO,OAAO;EACzC,MAAM,KAAK,SAAS,cAAc,mBAAmB,eAAe,GAAG;EACvE,IAAI,cAAc,aAAa;GAC7B,GAAG,MAAM;GAGT,MAAM,IAAI,SAAS,YAAY,WAAW,SAAS,GAAI,CAAC;GACxD,OAAO,CAAC;EACV,OACE,OAAO;CAEX;AACF,CAAC;AAED,MAAM,OAAO,KAAK;CAChB,YAAY;EACV,MAAM;EACN,YAAY;GACV,QAAQ,EACN,MAAM,SACR;GACA,OAAO,EACL,MAAM,SACR;EACF;EACA,UAAU,CAAC,UAAU,OAAO;CAC9B;CACA,SAAS,OAAO,EAAE,QAAQ,YAA+C;EACvE,MAAM,gBAAgB,IAAI,OAAO,MAAM;EACvC,MAAM,KAAK,SAAS,cAAc,kBAAkB,cAAc,GAAG;EACrE,IAAI,cAAc,oBAAoB,cAAc,qBAAqB;GACvE,GAAG,QAAQ;GACX,GAAG,cAAc,IAAI,MAAM,SAAS,EAAE,SAAS,KAAK,CAAC,CAAC;GACtD,GAAG,cAAc,IAAI,MAAM,UAAU,EAAE,SAAS,KAAK,CAAC,CAAC;GAGvD,MAAM,IAAI,SAAS,YAAY,WAAW,SAAS,GAAI,CAAC;GACxD,OAAO,CAAC;EACV,OACE,OAAO;CAEX;AACF,CAAC;AAED,MAAM,kBAAkB,cAAuB,KAAK;AAEpD,MAAa,wBACX,WACA,WACG;CACH,MAAM,oBAAoB,YACvB,OAA2B,aAAgC;EAC1D,MAAM,mBAAmB,WAAW,eAAe;EAEnD,MAAM,UAAU,MAAM;EACtB,MAAM,eAAe,OAAoB,IAAI;EAE7C,MAAM,MAAM,OAAO;EAEnB,MAAM,EAAE,WAAW,aAAa,UAAU,CAAC;EAC3C,gBAAgB;GACd,OAAO,IAAI,aAAa,EAAE,SAAS,EACjC,uBAAuB;IACrB,OAAO;KACL,OAAO;MACL,GAAI,YAAY,EAAE,MAAM,IAAI,CAAC;MAC7B,GAAI,WAAW,EAAE,KAAK,IAAI,CAAC;KAC7B;KACA,QAAQ,CAAC,mBACL,aAAa,SAAS,YACtB,KAAA;IACN;GACF,EACF,CAAC;EACH,GAAG;GAAC;GAAkB;GAAK;GAAW;EAAQ,CAAC;EAE/C,MAAM,MAAM,gBAAgB,cAAc,QAAQ;EAElD,OACE,oBAAC,gBAAgB,UAAjB;GAA0B,OAAO;aAC/B,oBAAC,WAAD;IACE,GAAK;IACL,GAAK,QAAQ,YAAY,EAAE,iBAAiB,QAAQ,IAAI,CAAC;IACzD,GAAK,QAAQ,WAAW,EAAE,gBAAgB,QAAQ,IAAI,CAAC;IAClD;GACN,CAAA;EACuB,CAAA;CAE9B,CACF;CAEA,kBAAkB,cAAc,UAAU;CAE1C,OAAO;AACT"}
1
+ {"version":3,"file":"makeAssistantVisible.js","names":[],"sources":["../../src/model-context/makeAssistantVisible.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n useEffect,\n useRef,\n forwardRef,\n type ComponentType,\n type ForwardedRef,\n type PropsWithoutRef,\n useId,\n createContext,\n useContext,\n} from \"react\";\nimport { useAui } from \"@assistant-ui/store\";\nimport { useComposedRefs } from \"@radix-ui/react-compose-refs\";\nimport { tool } from \"@assistant-ui/core\";\n\nconst click = tool({\n parameters: {\n type: \"object\",\n properties: {\n clickId: {\n type: \"string\",\n },\n },\n required: [\"clickId\"],\n },\n execute: async ({ clickId }: { clickId: string }) => {\n const escapedClickId = CSS.escape(clickId);\n const el = document.querySelector(`[data-click-id='${escapedClickId}']`);\n if (el instanceof HTMLElement) {\n el.click();\n\n // todo make adjustable\n await new Promise((resolve) => setTimeout(resolve, 2000));\n return {};\n } else {\n return \"Element not found\";\n }\n },\n});\n\nconst edit = tool({\n parameters: {\n type: \"object\",\n properties: {\n editId: {\n type: \"string\",\n },\n value: {\n type: \"string\",\n },\n },\n required: [\"editId\", \"value\"],\n },\n execute: async ({ editId, value }: { editId: string; value: string }) => {\n const escapedEditId = CSS.escape(editId);\n const el = document.querySelector(`[data-edit-id='${escapedEditId}']`);\n if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement) {\n el.value = value;\n el.dispatchEvent(new Event(\"input\", { bubbles: true }));\n el.dispatchEvent(new Event(\"change\", { bubbles: true }));\n\n // todo make adjustable\n await new Promise((resolve) => setTimeout(resolve, 2000));\n return {};\n } else {\n return \"Element not found\";\n }\n },\n});\n\nconst ReadableContext = createContext<boolean>(false);\n\nexport const makeAssistantVisible = <T extends ComponentType<any>>(\n Component: T,\n config?: { clickable?: boolean | undefined; editable?: boolean | undefined },\n) => {\n const ReadableComponent = forwardRef(\n (props: PropsWithoutRef<T>, outerRef: ForwardedRef<any>) => {\n const isNestedReadable = useContext(ReadableContext);\n\n const clickId = useId();\n const componentRef = useRef<HTMLElement>(null);\n\n const aui = useAui();\n\n const { clickable, editable } = config ?? {};\n useEffect(() => {\n return aui.modelContext().register({\n getModelContext: () => {\n return {\n tools: {\n ...(clickable ? { click } : {}),\n ...(editable ? { edit } : {}),\n },\n system: !isNestedReadable // only pass content if this readable isn't nested in another readable\n ? componentRef.current?.outerHTML\n : undefined,\n };\n },\n });\n }, [isNestedReadable, aui, clickable, editable]);\n\n const ref = useComposedRefs(componentRef, outerRef);\n\n return (\n <ReadableContext.Provider value={true}>\n <Component\n {...(props as any)}\n {...(config?.clickable ? { \"data-click-id\": clickId } : {})}\n {...(config?.editable ? { \"data-edit-id\": clickId } : {})}\n ref={ref}\n />\n </ReadableContext.Provider>\n );\n },\n );\n\n ReadableComponent.displayName = Component.displayName;\n\n return ReadableComponent as unknown as T;\n};\n\nexport default makeAssistantVisible;\n"],"mappings":";;;;;;;AAiBA,MAAM,QAAQ,KAAK;CACjB,YAAY;EACV,MAAM;EACN,YAAY,EACV,SAAS,EACP,MAAM,SACR,EACF;EACA,UAAU,CAAC,SAAS;CACtB;CACA,SAAS,OAAO,EAAE,cAAmC;EACnD,MAAM,iBAAiB,IAAI,OAAO,OAAO;EACzC,MAAM,KAAK,SAAS,cAAc,mBAAmB,eAAe,GAAG;EACvE,IAAI,cAAc,aAAa;GAC7B,GAAG,MAAM;GAGT,MAAM,IAAI,SAAS,YAAY,WAAW,SAAS,GAAI,CAAC;GACxD,OAAO,CAAC;EACV,OACE,OAAO;CAEX;AACF,CAAC;AAED,MAAM,OAAO,KAAK;CAChB,YAAY;EACV,MAAM;EACN,YAAY;GACV,QAAQ,EACN,MAAM,SACR;GACA,OAAO,EACL,MAAM,SACR;EACF;EACA,UAAU,CAAC,UAAU,OAAO;CAC9B;CACA,SAAS,OAAO,EAAE,QAAQ,YAA+C;EACvE,MAAM,gBAAgB,IAAI,OAAO,MAAM;EACvC,MAAM,KAAK,SAAS,cAAc,kBAAkB,cAAc,GAAG;EACrE,IAAI,cAAc,oBAAoB,cAAc,qBAAqB;GACvE,GAAG,QAAQ;GACX,GAAG,cAAc,IAAI,MAAM,SAAS,EAAE,SAAS,KAAK,CAAC,CAAC;GACtD,GAAG,cAAc,IAAI,MAAM,UAAU,EAAE,SAAS,KAAK,CAAC,CAAC;GAGvD,MAAM,IAAI,SAAS,YAAY,WAAW,SAAS,GAAI,CAAC;GACxD,OAAO,CAAC;EACV,OACE,OAAO;CAEX;AACF,CAAC;AAED,MAAM,kBAAkB,cAAuB,KAAK;AAEpD,MAAa,wBACX,WACA,WACG;CACH,MAAM,oBAAoB,YACvB,OAA2B,aAAgC;EAC1D,MAAM,mBAAmB,WAAW,eAAe;EAEnD,MAAM,UAAU,MAAM;EACtB,MAAM,eAAe,OAAoB,IAAI;EAE7C,MAAM,MAAM,OAAO;EAEnB,MAAM,EAAE,WAAW,aAAa,UAAU,CAAC;EAC3C,gBAAgB;GACd,OAAO,IAAI,aAAa,CAAC,CAAC,SAAS,EACjC,uBAAuB;IACrB,OAAO;KACL,OAAO;MACL,GAAI,YAAY,EAAE,MAAM,IAAI,CAAC;MAC7B,GAAI,WAAW,EAAE,KAAK,IAAI,CAAC;KAC7B;KACA,QAAQ,CAAC,mBACL,aAAa,SAAS,YACtB,KAAA;IACN;GACF,EACF,CAAC;EACH,GAAG;GAAC;GAAkB;GAAK;GAAW;EAAQ,CAAC;EAE/C,MAAM,MAAM,gBAAgB,cAAc,QAAQ;EAElD,OACE,oBAAC,gBAAgB,UAAjB;GAA0B,OAAO;aAC/B,oBAAC,WAAD;IACE,GAAK;IACL,GAAK,QAAQ,YAAY,EAAE,iBAAiB,QAAQ,IAAI,CAAC;IACzD,GAAK,QAAQ,WAAW,EAAE,gBAAgB,QAAQ,IAAI,CAAC;IAClD;GACN,CAAA;EACuB,CAAA;CAE9B,CACF;CAEA,kBAAkB,cAAc,UAAU;CAE1C,OAAO;AACT"}
@@ -2,7 +2,7 @@
2
2
  import { Primitive } from "../../utils/Primitive.js";
3
3
  import { useAuiState } from "@assistant-ui/store";
4
4
  import { useActionBarCopy } from "@assistant-ui/core/react";
5
- import { forwardRef } from "react";
5
+ import { forwardRef } from "@assistant-ui/tap/react-shim";
6
6
  import { jsx } from "react/jsx-runtime";
7
7
  import { composeEventHandlers } from "@radix-ui/primitive";
8
8
  //#region src/primitives/actionBar/ActionBarCopy.tsx
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { Primitive } from "../../utils/Primitive.js";
3
3
  import { useAui, useAuiState } from "@assistant-ui/store";
4
- import { forwardRef, useCallback } from "react";
4
+ import { forwardRef, useCallback } from "@assistant-ui/tap/react-shim";
5
5
  import { jsx } from "react/jsx-runtime";
6
6
  import { composeEventHandlers } from "@radix-ui/primitive";
7
7
  //#region src/primitives/actionBar/ActionBarExportMarkdown.tsx
@@ -1 +1 @@
1
- {"version":3,"file":"ActionBarExportMarkdown.js","names":[],"sources":["../../../src/primitives/actionBar/ActionBarExportMarkdown.tsx"],"sourcesContent":["\"use client\";\n\nimport { forwardRef, useCallback } from \"react\";\nimport type { ActionButtonProps } from \"../../utils/createActionButton\";\nimport { composeEventHandlers } from \"@radix-ui/primitive\";\nimport { Primitive } from \"../../utils/Primitive\";\nimport { useAuiState, useAui } from \"@assistant-ui/store\";\n\nconst useActionBarExportMarkdown = ({\n filename,\n onExport,\n}: {\n filename?: string | undefined;\n onExport?: ((content: string) => void | Promise<void>) | undefined;\n} = {}) => {\n const aui = useAui();\n const hasExportableContent = useAuiState((s) => {\n return (\n (s.message.role !== \"assistant\" ||\n s.message.status?.type !== \"running\") &&\n s.message.parts.some((c) => c.type === \"text\" && c.text.length > 0)\n );\n });\n\n const callback = useCallback(async () => {\n const content = aui.message().getCopyText();\n if (!content) return;\n\n if (onExport) {\n await onExport(content);\n return;\n }\n\n const blob = new Blob([content], { type: \"text/markdown\" });\n const url = URL.createObjectURL(blob);\n const a = document.createElement(\"a\");\n a.href = url;\n a.download = filename ?? `message-${Date.now()}.md`;\n a.click();\n URL.revokeObjectURL(url);\n }, [aui, filename, onExport]);\n\n if (!hasExportableContent) return null;\n return callback;\n};\n\nexport namespace ActionBarPrimitiveExportMarkdown {\n export type Element = HTMLButtonElement;\n export type Props = ActionButtonProps<typeof useActionBarExportMarkdown>;\n}\n\nexport const ActionBarPrimitiveExportMarkdown = forwardRef<\n ActionBarPrimitiveExportMarkdown.Element,\n ActionBarPrimitiveExportMarkdown.Props\n>(({ filename, onExport, onClick, disabled, ...props }, forwardedRef) => {\n const callback = useActionBarExportMarkdown({ filename, onExport });\n return (\n <Primitive.button\n type=\"button\"\n {...props}\n ref={forwardedRef}\n disabled={disabled || !callback}\n onClick={composeEventHandlers(onClick, () => {\n callback?.();\n })}\n />\n );\n});\n\nActionBarPrimitiveExportMarkdown.displayName =\n \"ActionBarPrimitive.ExportMarkdown\";\n"],"mappings":";;;;;;;AAQA,MAAM,8BAA8B,EAClC,UACA,aAIE,CAAC,MAAM;CACT,MAAM,MAAM,OAAO;CACnB,MAAM,uBAAuB,aAAa,MAAM;EAC9C,QACG,EAAE,QAAQ,SAAS,eAClB,EAAE,QAAQ,QAAQ,SAAS,cAC7B,EAAE,QAAQ,MAAM,MAAM,MAAM,EAAE,SAAS,UAAU,EAAE,KAAK,SAAS,CAAC;CAEtE,CAAC;CAED,MAAM,WAAW,YAAY,YAAY;EACvC,MAAM,UAAU,IAAI,QAAQ,EAAE,YAAY;EAC1C,IAAI,CAAC,SAAS;EAEd,IAAI,UAAU;GACZ,MAAM,SAAS,OAAO;GACtB;EACF;EAEA,MAAM,OAAO,IAAI,KAAK,CAAC,OAAO,GAAG,EAAE,MAAM,gBAAgB,CAAC;EAC1D,MAAM,MAAM,IAAI,gBAAgB,IAAI;EACpC,MAAM,IAAI,SAAS,cAAc,GAAG;EACpC,EAAE,OAAO;EACT,EAAE,WAAW,YAAY,WAAW,KAAK,IAAI,EAAE;EAC/C,EAAE,MAAM;EACR,IAAI,gBAAgB,GAAG;CACzB,GAAG;EAAC;EAAK;EAAU;CAAQ,CAAC;CAE5B,IAAI,CAAC,sBAAsB,OAAO;CAClC,OAAO;AACT;AAOA,MAAa,mCAAmC,YAG7C,EAAE,UAAU,UAAU,SAAS,UAAU,GAAG,SAAS,iBAAiB;CACvE,MAAM,WAAW,2BAA2B;EAAE;EAAU;CAAS,CAAC;CAClE,OACE,oBAAC,UAAU,QAAX;EACE,MAAK;EACL,GAAI;EACJ,KAAK;EACL,UAAU,YAAY,CAAC;EACvB,SAAS,qBAAqB,eAAe;GAC3C,WAAW;EACb,CAAC;CACF,CAAA;AAEL,CAAC;AAED,iCAAiC,cAC/B"}
1
+ {"version":3,"file":"ActionBarExportMarkdown.js","names":[],"sources":["../../../src/primitives/actionBar/ActionBarExportMarkdown.tsx"],"sourcesContent":["\"use client\";\n\nimport { forwardRef, useCallback } from \"react\";\nimport type { ActionButtonProps } from \"../../utils/createActionButton\";\nimport { composeEventHandlers } from \"@radix-ui/primitive\";\nimport { Primitive } from \"../../utils/Primitive\";\nimport { useAuiState, useAui } from \"@assistant-ui/store\";\n\nconst useActionBarExportMarkdown = ({\n filename,\n onExport,\n}: {\n filename?: string | undefined;\n onExport?: ((content: string) => void | Promise<void>) | undefined;\n} = {}) => {\n const aui = useAui();\n const hasExportableContent = useAuiState((s) => {\n return (\n (s.message.role !== \"assistant\" ||\n s.message.status?.type !== \"running\") &&\n s.message.parts.some((c) => c.type === \"text\" && c.text.length > 0)\n );\n });\n\n const callback = useCallback(async () => {\n const content = aui.message().getCopyText();\n if (!content) return;\n\n if (onExport) {\n await onExport(content);\n return;\n }\n\n const blob = new Blob([content], { type: \"text/markdown\" });\n const url = URL.createObjectURL(blob);\n const a = document.createElement(\"a\");\n a.href = url;\n a.download = filename ?? `message-${Date.now()}.md`;\n a.click();\n URL.revokeObjectURL(url);\n }, [aui, filename, onExport]);\n\n if (!hasExportableContent) return null;\n return callback;\n};\n\nexport namespace ActionBarPrimitiveExportMarkdown {\n export type Element = HTMLButtonElement;\n export type Props = ActionButtonProps<typeof useActionBarExportMarkdown>;\n}\n\nexport const ActionBarPrimitiveExportMarkdown = forwardRef<\n ActionBarPrimitiveExportMarkdown.Element,\n ActionBarPrimitiveExportMarkdown.Props\n>(({ filename, onExport, onClick, disabled, ...props }, forwardedRef) => {\n const callback = useActionBarExportMarkdown({ filename, onExport });\n return (\n <Primitive.button\n type=\"button\"\n {...props}\n ref={forwardedRef}\n disabled={disabled || !callback}\n onClick={composeEventHandlers(onClick, () => {\n callback?.();\n })}\n />\n );\n});\n\nActionBarPrimitiveExportMarkdown.displayName =\n \"ActionBarPrimitive.ExportMarkdown\";\n"],"mappings":";;;;;;;AAQA,MAAM,8BAA8B,EAClC,UACA,aAIE,CAAC,MAAM;CACT,MAAM,MAAM,OAAO;CACnB,MAAM,uBAAuB,aAAa,MAAM;EAC9C,QACG,EAAE,QAAQ,SAAS,eAClB,EAAE,QAAQ,QAAQ,SAAS,cAC7B,EAAE,QAAQ,MAAM,MAAM,MAAM,EAAE,SAAS,UAAU,EAAE,KAAK,SAAS,CAAC;CAEtE,CAAC;CAED,MAAM,WAAW,YAAY,YAAY;EACvC,MAAM,UAAU,IAAI,QAAQ,CAAC,CAAC,YAAY;EAC1C,IAAI,CAAC,SAAS;EAEd,IAAI,UAAU;GACZ,MAAM,SAAS,OAAO;GACtB;EACF;EAEA,MAAM,OAAO,IAAI,KAAK,CAAC,OAAO,GAAG,EAAE,MAAM,gBAAgB,CAAC;EAC1D,MAAM,MAAM,IAAI,gBAAgB,IAAI;EACpC,MAAM,IAAI,SAAS,cAAc,GAAG;EACpC,EAAE,OAAO;EACT,EAAE,WAAW,YAAY,WAAW,KAAK,IAAI,EAAE;EAC/C,EAAE,MAAM;EACR,IAAI,gBAAgB,GAAG;CACzB,GAAG;EAAC;EAAK;EAAU;CAAQ,CAAC;CAE5B,IAAI,CAAC,sBAAsB,OAAO;CAClC,OAAO;AACT;AAOA,MAAa,mCAAmC,YAG7C,EAAE,UAAU,UAAU,SAAS,UAAU,GAAG,SAAS,iBAAiB;CACvE,MAAM,WAAW,2BAA2B;EAAE;EAAU;CAAS,CAAC;CAClE,OACE,oBAAC,UAAU,QAAX;EACE,MAAK;EACL,GAAI;EACJ,KAAK;EACL,UAAU,YAAY,CAAC;EACvB,SAAS,qBAAqB,eAAe;GAC3C,WAAW;EACb,CAAC;CACF,CAAA;AAEL,CAAC;AAED,iCAAiC,cAC/B"}
@@ -2,7 +2,7 @@
2
2
  import { Primitive } from "../../utils/Primitive.js";
3
3
  import { useAuiState } from "@assistant-ui/store";
4
4
  import { useActionBarFeedbackNegative } from "@assistant-ui/core/react";
5
- import { forwardRef } from "react";
5
+ import { forwardRef } from "@assistant-ui/tap/react-shim";
6
6
  import { jsx } from "react/jsx-runtime";
7
7
  import { composeEventHandlers } from "@radix-ui/primitive";
8
8
  //#region src/primitives/actionBar/ActionBarFeedbackNegative.tsx
@@ -2,7 +2,7 @@
2
2
  import { Primitive } from "../../utils/Primitive.js";
3
3
  import { useAuiState } from "@assistant-ui/store";
4
4
  import { useActionBarFeedbackPositive } from "@assistant-ui/core/react";
5
- import { forwardRef } from "react";
5
+ import { forwardRef } from "@assistant-ui/tap/react-shim";
6
6
  import { jsx } from "react/jsx-runtime";
7
7
  import { composeEventHandlers } from "@radix-ui/primitive";
8
8
  //#region src/primitives/actionBar/ActionBarFeedbackPositive.tsx
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { createContext, useContext } from "react";
2
+ import { createContext, useContext } from "@assistant-ui/tap/react-shim";
3
3
  //#region src/primitives/actionBar/ActionBarInteractionContext.ts
4
4
  const ActionBarInteractionContext = createContext(null);
5
5
  const useActionBarInteractionContext = () => useContext(ActionBarInteractionContext);
@@ -2,7 +2,7 @@
2
2
  import { Primitive } from "../../utils/Primitive.js";
3
3
  import { useActionBarFloatStatus } from "./useActionBarFloatStatus.js";
4
4
  import { ActionBarInteractionContext } from "./ActionBarInteractionContext.js";
5
- import { forwardRef, useCallback, useMemo, useState } from "react";
5
+ import { forwardRef, useCallback, useMemo, useState } from "@assistant-ui/tap/react-shim";
6
6
  import { jsx } from "react/jsx-runtime";
7
7
  //#region src/primitives/actionBar/ActionBarRoot.tsx
8
8
  /**
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { Primitive } from "../../utils/Primitive.js";
3
3
  import { useActionBarStopSpeaking } from "@assistant-ui/core/react";
4
- import { forwardRef } from "react";
4
+ import { forwardRef } from "@assistant-ui/tap/react-shim";
5
5
  import { jsx } from "react/jsx-runtime";
6
6
  import { composeEventHandlers } from "@radix-ui/primitive";
7
7
  import { useEscapeKeydown } from "@radix-ui/react-use-escape-keydown";
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { useDropdownMenuScope } from "./scope.js";
3
3
  import { DropdownMenuRenderContent } from "../dropdownMenuRenderPrimitives.js";
4
- import { forwardRef } from "react";
4
+ import { forwardRef } from "@assistant-ui/tap/react-shim";
5
5
  import { jsx } from "react/jsx-runtime";
6
6
  import { DropdownMenu } from "radix-ui";
7
7
  //#region src/primitives/actionBarMore/ActionBarMoreContent.tsx
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { useDropdownMenuScope } from "./scope.js";
3
3
  import { DropdownMenuRenderItem } from "../dropdownMenuRenderPrimitives.js";
4
- import { forwardRef } from "react";
4
+ import { forwardRef } from "@assistant-ui/tap/react-shim";
5
5
  import { jsx } from "react/jsx-runtime";
6
6
  //#region src/primitives/actionBarMore/ActionBarMoreItem.tsx
7
7
  const ActionBarMorePrimitiveItem = forwardRef(({ __scopeActionBarMore, ...rest }, ref) => {
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { useActionBarInteractionContext } from "../actionBar/ActionBarInteractionContext.js";
3
3
  import { useDropdownMenuScope } from "./scope.js";
4
- import { useCallback, useEffect, useRef } from "react";
4
+ import { useCallback, useEffect, useRef } from "@assistant-ui/tap/react-shim";
5
5
  import { jsx } from "react/jsx-runtime";
6
6
  import { DropdownMenu } from "radix-ui";
7
7
  //#region src/primitives/actionBarMore/ActionBarMoreRoot.tsx
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { useDropdownMenuScope } from "./scope.js";
3
3
  import { DropdownMenuRenderSeparator } from "../dropdownMenuRenderPrimitives.js";
4
- import { forwardRef } from "react";
4
+ import { forwardRef } from "@assistant-ui/tap/react-shim";
5
5
  import { jsx } from "react/jsx-runtime";
6
6
  //#region src/primitives/actionBarMore/ActionBarMoreSeparator.tsx
7
7
  const ActionBarMorePrimitiveSeparator = forwardRef(({ __scopeActionBarMore, ...rest }, ref) => {
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { useDropdownMenuScope } from "./scope.js";
3
3
  import { DropdownMenuRenderTrigger } from "../dropdownMenuRenderPrimitives.js";
4
- import { forwardRef } from "react";
4
+ import { forwardRef } from "@assistant-ui/tap/react-shim";
5
5
  import { jsx } from "react/jsx-runtime";
6
6
  //#region src/primitives/actionBarMore/ActionBarMoreTrigger.tsx
7
7
  const ActionBarMorePrimitiveTrigger = forwardRef(({ __scopeActionBarMore, ...rest }, ref) => {
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { usePopoverScope } from "./scope.js";
3
- import { forwardRef } from "react";
3
+ import { forwardRef } from "@assistant-ui/tap/react-shim";
4
4
  import { jsx } from "react/jsx-runtime";
5
5
  import { Popover } from "radix-ui";
6
6
  //#region src/primitives/assistantModal/AssistantModalAnchor.tsx
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { usePopoverScope } from "./scope.js";
3
- import { forwardRef } from "react";
3
+ import { forwardRef } from "@assistant-ui/tap/react-shim";
4
4
  import { jsx } from "react/jsx-runtime";
5
5
  import { composeEventHandlers } from "@radix-ui/primitive";
6
6
  import { Popover } from "radix-ui";
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { usePopoverScope } from "./scope.js";
3
3
  import { useAui } from "@assistant-ui/store";
4
- import { useEffect, useState } from "react";
4
+ import { useEffect, useState } from "@assistant-ui/tap/react-shim";
5
5
  import { jsx } from "react/jsx-runtime";
6
6
  import { Popover } from "radix-ui";
7
7
  //#region src/primitives/assistantModal/AssistantModalRoot.tsx
@@ -1,5 +1,5 @@
1
1
  import { usePopoverScope } from "./scope.js";
2
- import { forwardRef } from "react";
2
+ import { forwardRef } from "@assistant-ui/tap/react-shim";
3
3
  import { jsx } from "react/jsx-runtime";
4
4
  import { Popover } from "radix-ui";
5
5
  //#region src/primitives/assistantModal/AssistantModalTrigger.tsx
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { createActionButton } from "../../utils/createActionButton.js";
3
3
  import { useAui } from "@assistant-ui/store";
4
- import { useCallback } from "react";
4
+ import { useCallback } from "@assistant-ui/tap/react-shim";
5
5
  //#region src/primitives/attachment/AttachmentRemove.ts
6
6
  const useAttachmentRemove = () => {
7
7
  const aui = useAui();
@@ -1 +1 @@
1
- {"version":3,"file":"AttachmentRemove.js","names":[],"sources":["../../../src/primitives/attachment/AttachmentRemove.ts"],"sourcesContent":["\"use client\";\n\nimport {\n type ActionButtonElement,\n type ActionButtonProps,\n createActionButton,\n} from \"../../utils/createActionButton\";\nimport { useCallback } from \"react\";\nimport { useAui } from \"@assistant-ui/store\";\n\nconst useAttachmentRemove = () => {\n const aui = useAui();\n\n const handleRemoveAttachment = useCallback(() => {\n aui.attachment().remove();\n }, [aui]);\n\n return handleRemoveAttachment;\n};\n\nexport namespace AttachmentPrimitiveRemove {\n export type Element = ActionButtonElement;\n export type Props = ActionButtonProps<typeof useAttachmentRemove>;\n}\n\nexport const AttachmentPrimitiveRemove = createActionButton(\n \"AttachmentPrimitive.Remove\",\n useAttachmentRemove,\n);\n"],"mappings":";;;;;AAUA,MAAM,4BAA4B;CAChC,MAAM,MAAM,OAAO;CAMnB,OAJ+B,kBAAkB;EAC/C,IAAI,WAAW,EAAE,OAAO;CAC1B,GAAG,CAAC,GAAG,CAEqB;AAC9B;AAOA,MAAa,4BAA4B,mBACvC,8BACA,mBACF"}
1
+ {"version":3,"file":"AttachmentRemove.js","names":[],"sources":["../../../src/primitives/attachment/AttachmentRemove.ts"],"sourcesContent":["\"use client\";\n\nimport {\n type ActionButtonElement,\n type ActionButtonProps,\n createActionButton,\n} from \"../../utils/createActionButton\";\nimport { useCallback } from \"react\";\nimport { useAui } from \"@assistant-ui/store\";\n\nconst useAttachmentRemove = () => {\n const aui = useAui();\n\n const handleRemoveAttachment = useCallback(() => {\n aui.attachment().remove();\n }, [aui]);\n\n return handleRemoveAttachment;\n};\n\nexport namespace AttachmentPrimitiveRemove {\n export type Element = ActionButtonElement;\n export type Props = ActionButtonProps<typeof useAttachmentRemove>;\n}\n\nexport const AttachmentPrimitiveRemove = createActionButton(\n \"AttachmentPrimitive.Remove\",\n useAttachmentRemove,\n);\n"],"mappings":";;;;;AAUA,MAAM,4BAA4B;CAChC,MAAM,MAAM,OAAO;CAMnB,OAJ+B,kBAAkB;EAC/C,IAAI,WAAW,CAAC,CAAC,OAAO;CAC1B,GAAG,CAAC,GAAG,CAEqB;AAC9B;AAOA,MAAa,4BAA4B,mBACvC,8BACA,mBACF"}
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { Primitive } from "../../utils/Primitive.js";
3
- import { forwardRef } from "react";
3
+ import { forwardRef } from "@assistant-ui/tap/react-shim";
4
4
  import { jsx } from "react/jsx-runtime";
5
5
  //#region src/primitives/attachment/AttachmentRoot.tsx
6
6
  /**
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { Primitive } from "../../utils/Primitive.js";
3
3
  import { useAuiState } from "@assistant-ui/store";
4
- import { forwardRef } from "react";
4
+ import { forwardRef } from "@assistant-ui/tap/react-shim";
5
5
  import { jsxs } from "react/jsx-runtime";
6
6
  //#region src/primitives/attachment/AttachmentThumb.tsx
7
7
  const AttachmentPrimitiveThumb = forwardRef((props, ref) => {
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { Primitive } from "../../utils/Primitive.js";
3
3
  import { MessagePrimitiveIf } from "../message/MessageIf.js";
4
- import { forwardRef } from "react";
4
+ import { forwardRef } from "@assistant-ui/tap/react-shim";
5
5
  import { jsx } from "react/jsx-runtime";
6
6
  //#region src/primitives/branchPicker/BranchPickerRoot.tsx
7
7
  /**
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { createActionButton } from "../../utils/createActionButton.js";
3
3
  import { useAui, useAuiState } from "@assistant-ui/store";
4
- import { useCallback } from "react";
4
+ import { useCallback } from "@assistant-ui/tap/react-shim";
5
5
  //#region src/primitives/chainOfThought/ChainOfThoughtAccordionTrigger.ts
6
6
  const useChainOfThoughtAccordionTrigger = () => {
7
7
  const aui = useAui();
@@ -1 +1 @@
1
- {"version":3,"file":"ChainOfThoughtAccordionTrigger.js","names":[],"sources":["../../../src/primitives/chainOfThought/ChainOfThoughtAccordionTrigger.ts"],"sourcesContent":["\"use client\";\n\nimport {\n type ActionButtonElement,\n type ActionButtonProps,\n createActionButton,\n} from \"../../utils/createActionButton\";\nimport { useCallback } from \"react\";\nimport { useAuiState, useAui } from \"@assistant-ui/store\";\n\nconst useChainOfThoughtAccordionTrigger = () => {\n const aui = useAui();\n const collapsed = useAuiState((s) => s.chainOfThought.collapsed);\n\n const callback = useCallback(() => {\n aui.chainOfThought().setCollapsed(!collapsed);\n }, [aui, collapsed]);\n\n return callback;\n};\n\nexport namespace ChainOfThoughtPrimitiveAccordionTrigger {\n export type Element = ActionButtonElement;\n /**\n * Props for the ChainOfThoughtPrimitive.AccordionTrigger component.\n * Inherits all button element props and action button functionality.\n */\n export type Props = ActionButtonProps<\n typeof useChainOfThoughtAccordionTrigger\n >;\n}\n\n/**\n * A button component that toggles the collapsed state of the chain of thought accordion.\n *\n * This component automatically handles the toggle functionality, expanding or collapsing\n * the chain of thought parts when clicked.\n *\n * @example\n * ```tsx\n * <ChainOfThoughtPrimitive.AccordionTrigger>\n * Toggle Reasoning\n * </ChainOfThoughtPrimitive.AccordionTrigger>\n * ```\n */\nexport const ChainOfThoughtPrimitiveAccordionTrigger = createActionButton(\n \"ChainOfThoughtPrimitive.AccordionTrigger\",\n useChainOfThoughtAccordionTrigger,\n);\n"],"mappings":";;;;;AAUA,MAAM,0CAA0C;CAC9C,MAAM,MAAM,OAAO;CACnB,MAAM,YAAY,aAAa,MAAM,EAAE,eAAe,SAAS;CAM/D,OAJiB,kBAAkB;EACjC,IAAI,eAAe,EAAE,aAAa,CAAC,SAAS;CAC9C,GAAG,CAAC,KAAK,SAAS,CAEJ;AAChB;;;;;;;;;;;;;;AA0BA,MAAa,0CAA0C,mBACrD,4CACA,iCACF"}
1
+ {"version":3,"file":"ChainOfThoughtAccordionTrigger.js","names":[],"sources":["../../../src/primitives/chainOfThought/ChainOfThoughtAccordionTrigger.ts"],"sourcesContent":["\"use client\";\n\nimport {\n type ActionButtonElement,\n type ActionButtonProps,\n createActionButton,\n} from \"../../utils/createActionButton\";\nimport { useCallback } from \"react\";\nimport { useAuiState, useAui } from \"@assistant-ui/store\";\n\nconst useChainOfThoughtAccordionTrigger = () => {\n const aui = useAui();\n const collapsed = useAuiState((s) => s.chainOfThought.collapsed);\n\n const callback = useCallback(() => {\n aui.chainOfThought().setCollapsed(!collapsed);\n }, [aui, collapsed]);\n\n return callback;\n};\n\nexport namespace ChainOfThoughtPrimitiveAccordionTrigger {\n export type Element = ActionButtonElement;\n /**\n * Props for the ChainOfThoughtPrimitive.AccordionTrigger component.\n * Inherits all button element props and action button functionality.\n */\n export type Props = ActionButtonProps<\n typeof useChainOfThoughtAccordionTrigger\n >;\n}\n\n/**\n * A button component that toggles the collapsed state of the chain of thought accordion.\n *\n * This component automatically handles the toggle functionality, expanding or collapsing\n * the chain of thought parts when clicked.\n *\n * @example\n * ```tsx\n * <ChainOfThoughtPrimitive.AccordionTrigger>\n * Toggle Reasoning\n * </ChainOfThoughtPrimitive.AccordionTrigger>\n * ```\n */\nexport const ChainOfThoughtPrimitiveAccordionTrigger = createActionButton(\n \"ChainOfThoughtPrimitive.AccordionTrigger\",\n useChainOfThoughtAccordionTrigger,\n);\n"],"mappings":";;;;;AAUA,MAAM,0CAA0C;CAC9C,MAAM,MAAM,OAAO;CACnB,MAAM,YAAY,aAAa,MAAM,EAAE,eAAe,SAAS;CAM/D,OAJiB,kBAAkB;EACjC,IAAI,eAAe,CAAC,CAAC,aAAa,CAAC,SAAS;CAC9C,GAAG,CAAC,KAAK,SAAS,CAEJ;AAChB;;;;;;;;;;;;;;AA0BA,MAAa,0CAA0C,mBACrD,4CACA,iCACF"}
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { Primitive } from "../../utils/Primitive.js";
3
- import { forwardRef } from "react";
3
+ import { forwardRef } from "@assistant-ui/tap/react-shim";
4
4
  import { jsx } from "react/jsx-runtime";
5
5
  //#region src/primitives/chainOfThought/ChainOfThoughtRoot.tsx
6
6
  /**