@assistant-ui/react 0.15.23 → 0.15.24

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 (135) hide show
  1. package/README.md +44 -23
  2. package/dist/assistant-transport.js.map +1 -1
  3. package/dist/cloud-renderer/CloudRendererHost.js.map +1 -1
  4. package/dist/context/providers/MessageProvider.js.map +1 -1
  5. package/dist/context/providers/ThreadViewportProvider.js.map +1 -1
  6. package/dist/hooks/useToolCallElapsed.js.map +1 -1
  7. package/dist/legacy-runtime/AssistantRuntimeProvider.js.map +1 -1
  8. package/dist/mcp-apps/app-frame.js.map +1 -1
  9. package/dist/model-context/frame/useAssistantFrameHost.js.map +1 -1
  10. package/dist/model-context/makeAssistantVisible.js.map +1 -1
  11. package/dist/primitives/actionBar/ActionBarCopy.js.map +1 -1
  12. package/dist/primitives/actionBar/ActionBarEdit.js.map +1 -1
  13. package/dist/primitives/actionBar/ActionBarExportMarkdown.js.map +1 -1
  14. package/dist/primitives/actionBar/ActionBarFeedbackNegative.js.map +1 -1
  15. package/dist/primitives/actionBar/ActionBarFeedbackPositive.js.map +1 -1
  16. package/dist/primitives/actionBar/ActionBarReload.js.map +1 -1
  17. package/dist/primitives/actionBar/ActionBarRoot.js.map +1 -1
  18. package/dist/primitives/actionBar/ActionBarSpeak.js.map +1 -1
  19. package/dist/primitives/actionBar/ActionBarStopSpeaking.js.map +1 -1
  20. package/dist/primitives/actionBar/useActionBarFloatStatus.js.map +1 -1
  21. package/dist/primitives/actionBarMore/ActionBarMoreContent.js.map +1 -1
  22. package/dist/primitives/actionBarMore/ActionBarMoreItem.js.map +1 -1
  23. package/dist/primitives/actionBarMore/ActionBarMoreRoot.js.map +1 -1
  24. package/dist/primitives/actionBarMore/ActionBarMoreSeparator.js.map +1 -1
  25. package/dist/primitives/actionBarMore/ActionBarMoreTrigger.js.map +1 -1
  26. package/dist/primitives/actionBarMore/scope.js.map +1 -1
  27. package/dist/primitives/assistantModal/AssistantModalAnchor.js.map +1 -1
  28. package/dist/primitives/assistantModal/AssistantModalContent.js.map +1 -1
  29. package/dist/primitives/assistantModal/AssistantModalRoot.js.map +1 -1
  30. package/dist/primitives/assistantModal/AssistantModalTrigger.js.map +1 -1
  31. package/dist/primitives/assistantModal/popoverRenderPrimitives.js.map +1 -1
  32. package/dist/primitives/assistantModal/scope.js.map +1 -1
  33. package/dist/primitives/attachment/AttachmentName.js.map +1 -1
  34. package/dist/primitives/attachment/AttachmentRemove.js.map +1 -1
  35. package/dist/primitives/attachment/AttachmentRoot.js.map +1 -1
  36. package/dist/primitives/attachment/AttachmentThumb.js.map +1 -1
  37. package/dist/primitives/branchPicker/BranchPickerCount.js.map +1 -1
  38. package/dist/primitives/branchPicker/BranchPickerNext.js.map +1 -1
  39. package/dist/primitives/branchPicker/BranchPickerNumber.js.map +1 -1
  40. package/dist/primitives/branchPicker/BranchPickerPrevious.js.map +1 -1
  41. package/dist/primitives/branchPicker/BranchPickerRoot.js.map +1 -1
  42. package/dist/primitives/chainOfThought/ChainOfThoughtAccordionTrigger.js.map +1 -1
  43. package/dist/primitives/chainOfThought/ChainOfThoughtRoot.js.map +1 -1
  44. package/dist/primitives/composer/ComposerAddAttachment.js.map +1 -1
  45. package/dist/primitives/composer/ComposerCancel.js.map +1 -1
  46. package/dist/primitives/composer/ComposerDictate.js.map +1 -1
  47. package/dist/primitives/composer/ComposerDictationTranscript.js.map +1 -1
  48. package/dist/primitives/composer/ComposerInput.d.ts.map +1 -1
  49. package/dist/primitives/composer/ComposerInput.js +3 -2
  50. package/dist/primitives/composer/ComposerInput.js.map +1 -1
  51. package/dist/primitives/composer/ComposerInputPluginContext.js.map +1 -1
  52. package/dist/primitives/composer/ComposerQuote.js.map +1 -1
  53. package/dist/primitives/composer/ComposerRoot.js.map +1 -1
  54. package/dist/primitives/composer/ComposerSend.js.map +1 -1
  55. package/dist/primitives/composer/ComposerStopDictation.js.map +1 -1
  56. package/dist/primitives/composer/trigger/TriggerPopover.js.map +1 -1
  57. package/dist/primitives/composer/trigger/TriggerPopoverAction.js.map +1 -1
  58. package/dist/primitives/composer/trigger/TriggerPopoverBack.js.map +1 -1
  59. package/dist/primitives/composer/trigger/TriggerPopoverCategories.js.map +1 -1
  60. package/dist/primitives/composer/trigger/TriggerPopoverDirective.js.map +1 -1
  61. package/dist/primitives/composer/trigger/TriggerPopoverItems.js.map +1 -1
  62. package/dist/primitives/composer/trigger/TriggerPopoverResource.js.map +1 -1
  63. package/dist/primitives/composer/trigger/TriggerPopoverRootContext.js.map +1 -1
  64. package/dist/primitives/composer/trigger/index.js.map +1 -1
  65. package/dist/primitives/composer/trigger/triggerDetectionResource.js.map +1 -1
  66. package/dist/primitives/composer/trigger/triggerKeyboardResource.js.map +1 -1
  67. package/dist/primitives/composer/trigger/triggerNavigationResource.js.map +1 -1
  68. package/dist/primitives/composer/trigger/triggerSelectionResource.js.map +1 -1
  69. package/dist/primitives/composer/useComposerInputState.js.map +1 -1
  70. package/dist/primitives/dropdownMenuRenderPrimitives.js.map +1 -1
  71. package/dist/primitives/error/ErrorMessage.js.map +1 -1
  72. package/dist/primitives/error/ErrorRoot.js.map +1 -1
  73. package/dist/primitives/message/MessageIf.js.map +1 -1
  74. package/dist/primitives/message/MessageParts.js.map +1 -1
  75. package/dist/primitives/message/MessagePartsGrouped.d.ts.map +1 -1
  76. package/dist/primitives/message/MessagePartsGrouped.js +42 -17
  77. package/dist/primitives/message/MessagePartsGrouped.js.map +1 -1
  78. package/dist/primitives/message/MessageRoot.js.map +1 -1
  79. package/dist/primitives/messagePart/MessagePartImage.js.map +1 -1
  80. package/dist/primitives/queueItem/QueueItemRemove.js.map +1 -1
  81. package/dist/primitives/queueItem/QueueItemSteer.js.map +1 -1
  82. package/dist/primitives/queueItem/QueueItemText.js.map +1 -1
  83. package/dist/primitives/reasoning/useScrollLock.js.map +1 -1
  84. package/dist/primitives/selectionToolbar/SelectionToolbarQuote.js.map +1 -1
  85. package/dist/primitives/selectionToolbar/SelectionToolbarRoot.js.map +1 -1
  86. package/dist/primitives/suggestion/SuggestionDescription.js.map +1 -1
  87. package/dist/primitives/suggestion/SuggestionTitle.js.map +1 -1
  88. package/dist/primitives/suggestion/SuggestionTrigger.js.map +1 -1
  89. package/dist/primitives/thread/ThreadIf.js.map +1 -1
  90. package/dist/primitives/thread/ThreadRoot.d.ts.map +1 -1
  91. package/dist/primitives/thread/ThreadRoot.js +2 -0
  92. package/dist/primitives/thread/ThreadRoot.js.map +1 -1
  93. package/dist/primitives/thread/ThreadScrollToBottom.js.map +1 -1
  94. package/dist/primitives/thread/ThreadSuggestion.js.map +1 -1
  95. package/dist/primitives/thread/ThreadViewport.js.map +1 -1
  96. package/dist/primitives/thread/ThreadViewportFooter.js.map +1 -1
  97. package/dist/primitives/thread/topAnchor/useTopAnchorReserve.js.map +1 -1
  98. package/dist/primitives/threadList/ThreadListLoadMore.js.map +1 -1
  99. package/dist/primitives/threadList/ThreadListNew.js.map +1 -1
  100. package/dist/primitives/threadList/ThreadListRoot.js.map +1 -1
  101. package/dist/primitives/threadListItem/ThreadListItemArchive.js.map +1 -1
  102. package/dist/primitives/threadListItem/ThreadListItemDelete.js.map +1 -1
  103. package/dist/primitives/threadListItem/ThreadListItemRoot.js.map +1 -1
  104. package/dist/primitives/threadListItem/ThreadListItemTrigger.js.map +1 -1
  105. package/dist/primitives/threadListItem/ThreadListItemUnarchive.js.map +1 -1
  106. package/dist/primitives/threadListItemMore/ThreadListItemMoreContent.js.map +1 -1
  107. package/dist/primitives/threadListItemMore/ThreadListItemMoreItem.js.map +1 -1
  108. package/dist/primitives/threadListItemMore/ThreadListItemMoreRoot.js.map +1 -1
  109. package/dist/primitives/threadListItemMore/ThreadListItemMoreSeparator.js.map +1 -1
  110. package/dist/primitives/threadListItemMore/ThreadListItemMoreTrigger.js.map +1 -1
  111. package/dist/primitives/threadListItemMore/scope.js.map +1 -1
  112. package/dist/sandbox-host/SandboxHost.js.map +1 -1
  113. package/dist/unstable/useModelContextSnapshot.js.map +1 -1
  114. package/dist/unstable/webmcp/WebMcpRegistrationResource.js.map +1 -1
  115. package/dist/unstable/webmcp/useWebMcpProvider.js.map +1 -1
  116. package/dist/utils/Primitive.js.map +1 -1
  117. package/dist/utils/createActionButton.js.map +1 -1
  118. package/dist/utils/hooks/useManagedRef.js.map +1 -1
  119. package/dist/utils/hooks/useMediaQuery.js.map +1 -1
  120. package/dist/utils/hooks/useOnResizeContent.js.map +1 -1
  121. package/dist/utils/hooks/useOnScrollToBottom.js.map +1 -1
  122. package/dist/utils/hooks/useSizeHandle.js.map +1 -1
  123. package/dist/utils/isCompositionKey.d.ts +2 -0
  124. package/dist/utils/isCompositionKey.d.ts.map +1 -0
  125. package/dist/utils/isCompositionKey.js +6 -0
  126. package/dist/utils/isCompositionKey.js.map +1 -0
  127. package/dist/utils/smooth/SmoothContext.js.map +1 -1
  128. package/package.json +11 -11
  129. package/src/primitives/composer/ComposerInput.test.tsx +33 -1
  130. package/src/primitives/composer/ComposerInput.tsx +3 -2
  131. package/src/primitives/message/MessagePartsGrouped.test.tsx +271 -1
  132. package/src/primitives/message/MessagePartsGrouped.tsx +14 -6
  133. package/src/primitives/thread/ThreadRoot.test.tsx +33 -0
  134. package/src/primitives/thread/ThreadRoot.tsx +3 -0
  135. package/src/utils/isCompositionKey.ts +5 -0
package/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  <a href="https://www.assistant-ui.com">
2
2
  <picture>
3
- <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/assistant-ui/assistant-ui/main/.github/assets/header-dark.svg" />
4
- <source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/assistant-ui/assistant-ui/main/.github/assets/header.svg" />
5
- <img src="https://raw.githubusercontent.com/assistant-ui/assistant-ui/main/.github/assets/header.svg" alt="assistant-ui Header" width="100%" />
3
+ <source media="(prefers-color-scheme: dark)" srcset=".github/assets/header-dark.png" />
4
+ <source media="(prefers-color-scheme: light)" srcset=".github/assets/header-light.png" />
5
+ <img src=".github/assets/header-light.png" alt="assistant-ui: the frontend library for AI agents" width="100%" />
6
6
  </picture>
7
7
  </a>
8
8
 
@@ -14,18 +14,28 @@
14
14
  <a href="https://cal.com/simon-farshid/assistant-ui">Contact Sales</a>
15
15
  </p>
16
16
 
17
- [![npm version](https://img.shields.io/npm/v/@assistant-ui/react)](https://www.npmjs.com/package/@assistant-ui/react)
18
- [![npm downloads](https://img.shields.io/npm/dm/@assistant-ui/react)](https://www.npmjs.com/package/@assistant-ui/react)
19
- [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/assistant-ui/assistant-ui)
20
- [![Weave Badge](https://img.shields.io/endpoint?url=https%3A%2F%2Fapp.workweave.ai%2Fapi%2Frepository%2Fbadge%2Forg_GhSIrtWo37b5B3Mv0At3wQ1Q%2F722184017&cacheSeconds=3600)](https://app.workweave.ai/reports/repository/org_GhSIrtWo37b5B3Mv0At3wQ1Q/722184017)
21
- ![GitHub License](https://img.shields.io/github/license/assistant-ui/assistant-ui)
22
- [![GitHub stars](https://img.shields.io/github/stars/assistant-ui/assistant-ui)](https://github.com/assistant-ui/assistant-ui)
23
- ![Backed by Y Combinator](https://img.shields.io/badge/Backed_by-Y_Combinator-orange)
17
+ <p align="center">
18
+ <a href="https://www.npmjs.com/package/@assistant-ui/react"><img src="https://img.shields.io/npm/v/@assistant-ui/react" alt="npm version"></a>
19
+ <a href="https://www.npmjs.com/package/@assistant-ui/react"><img src="https://img.shields.io/npm/dm/@assistant-ui/react" alt="npm downloads"></a>
20
+ <a href="https://deepwiki.com/assistant-ui/assistant-ui"><img src="https://img.shields.io/badge/Ask-DeepWiki-1f6feb" alt="Ask DeepWiki"></a>
21
+ <a href="https://app.workweave.ai/reports/repository/org_GhSIrtWo37b5B3Mv0At3wQ1Q/722184017"><img src="https://img.shields.io/endpoint?url=https%3A%2F%2Fapp.workweave.ai%2Fapi%2Frepository%2Fbadge%2Forg_GhSIrtWo37b5B3Mv0At3wQ1Q%2F722184017&amp;cacheSeconds=3600" alt="Weave Badge"></a>
22
+ <img src="https://img.shields.io/github/license/assistant-ui/assistant-ui" alt="GitHub License">
23
+ <a href="https://github.com/assistant-ui/assistant-ui"><img src="https://img.shields.io/github/stars/assistant-ui/assistant-ui" alt="GitHub stars"></a>
24
+ <img src="https://img.shields.io/badge/Backed_by-Y_Combinator-orange" alt="Backed by Y Combinator">
25
+ </p>
24
26
 
25
27
  ## The UX of ChatGPT in your React app 💬🚀
26
28
 
27
29
  **assistant-ui** is an open-source TypeScript/React library to build production-grade AI chat experiences fast.
28
30
 
31
+ <a href="https://www.assistant-ui.com">
32
+ <picture>
33
+ <source media="(prefers-color-scheme: dark)" srcset=".github/assets/demo.webp" />
34
+ <source media="(prefers-color-scheme: light)" srcset=".github/assets/demo-light.webp" />
35
+ <img src=".github/assets/demo-light.webp" alt="An assistant-ui chat: a hotel search tool call, a streamed reply, an approval card that the user allows, and follow-up suggestions" width="100%" />
36
+ </picture>
37
+ </a>
38
+
29
39
  ## Installation
30
40
 
31
41
  The fastest path is the CLI, which scaffolds a Next.js app or adds the styled components to an existing project:
@@ -41,6 +51,12 @@ Or install the packages directly:
41
51
  npm install @assistant-ui/react @assistant-ui/ai-sdk ai
42
52
  ```
43
53
 
54
+ <picture>
55
+ <source media="(prefers-color-scheme: dark)" srcset=".github/assets/cli-init.webp" />
56
+ <source media="(prefers-color-scheme: light)" srcset=".github/assets/cli-init-light.webp" />
57
+ <img src=".github/assets/cli-init-light.webp" alt="Running npx assistant-ui@latest init in a terminal" width="100%" />
58
+ </picture>
59
+
44
60
  ## Usage
45
61
 
46
62
  ```tsx
@@ -62,8 +78,6 @@ export function Chat() {
62
78
 
63
79
  `useChatRuntime` connects to the Vercel AI SDK out of the box. Swap it for `useLangGraphRuntime`, `useDataStreamRuntime`, or any custom runtime to integrate with your own backend.
64
80
 
65
- [![assistant-ui starter template](https://raw.githubusercontent.com/assistant-ui/assistant-ui/main/.github/assets/assistant-ui-starter.gif)](https://youtu.be/k6Dc8URmLjk)
66
-
67
81
  ## What you get
68
82
 
69
83
  - **Composable primitives**: build any chat UX from `Thread`, `Message`, `Composer`, `ThreadList`, `ActionBar`, and friends. Style every pixel yourself, or start from a polished shadcn/ui theme that the CLI copies into your project.
@@ -71,6 +85,12 @@ export function Chat() {
71
85
  - **Generative UI**: render tool calls and JSON as React components, collect inline human approvals, and expose safe frontend actions to the model.
72
86
  - **Strong TypeScript**: typed runtime APIs, tool schemas, message parts, and adapters end to end.
73
87
 
88
+ <picture>
89
+ <source media="(prefers-color-scheme: dark)" srcset=".github/assets/generative-ui.png" />
90
+ <source media="(prefers-color-scheme: light)" srcset=".github/assets/generative-ui-light.png" />
91
+ <img src=".github/assets/generative-ui-light.png" alt="A get_weather tool call rendered as a weather card inside an assistant-ui chat" width="100%" />
92
+ </picture>
93
+
74
94
  ## Backends
75
95
 
76
96
  | Integration | Package |
@@ -88,15 +108,21 @@ Broad model support out of the box (OpenAI, Anthropic, Google Gemini, Mistral, P
88
108
 
89
109
  Instead of a single monolithic chat component, you compose primitives and bring your own styles. The CLI ships a great starter in your choice of Base UI (the default) or Radix UI flavor; you control everything else.
90
110
 
91
- ![Overview of components](https://raw.githubusercontent.com/assistant-ui/assistant-ui/main/.github/assets/components.png)
92
-
93
- Sample customization to make a Perplexity lookalike:
94
-
95
- ![Perplexity clone created with assistant-ui](https://raw.githubusercontent.com/assistant-ui/assistant-ui/main/.github/assets/perplexity.gif)
111
+ <picture>
112
+ <source media="(prefers-color-scheme: dark)" srcset=".github/assets/anatomy.webp" />
113
+ <source media="(prefers-color-scheme: light)" srcset=".github/assets/anatomy-light.webp" />
114
+ <img src=".github/assets/anatomy-light.webp" alt="A chat UI annotated with the primitives that build it: ThreadPrimitive.Viewport, MessagePrimitive.Root and Parts, makeAssistantToolUI, ActionBarPrimitive, BranchPickerPrimitive, and ComposerPrimitive.Input, Send and AddAttachment" width="100%" />
115
+ </picture>
96
116
 
97
117
  ## Used in production by
98
118
 
99
- <a href="https://mastra.ai/?ref=assistant-ui" target="_blank" rel="noopener noreferrer"><img src="https://raw.githubusercontent.com/assistant-ui/assistant-ui/main/.github/assets/logos/Mastra.svg" height="20" alt="Mastra"></a>, <a href="https://langchain.com/?ref=assistant-ui" target="_blank" rel="noopener noreferrer"><img src="https://raw.githubusercontent.com/assistant-ui/assistant-ui/main/.github/assets/logos/LangChain.svg" height="20" alt="LangChain"></a>, <a href="https://athenaintelligence.ai/?ref=assistant-ui" target="_blank" rel="noopener noreferrer"><img src="https://raw.githubusercontent.com/assistant-ui/assistant-ui/main/.github/assets/logos/Athena-Intelligence.svg" height="20" alt="Athena Intelligence"></a>, <a href="https://browser-use.com/?ref=assistant-ui" target="_blank" rel="noopener noreferrer"><img src="https://raw.githubusercontent.com/assistant-ui/assistant-ui/main/.github/assets/logos/Browser-Use.svg" height="20" alt="Browser Use"></a>, <a href="https://stack-ai.com/?ref=assistant-ui" target="_blank" rel="noopener noreferrer"><img src="https://raw.githubusercontent.com/assistant-ui/assistant-ui/main/.github/assets/logos/Stack.svg" height="20" alt="Stack"></a>, <a href="https://inconvo.com/?ref=assistant-ui" target="_blank" rel="noopener noreferrer"><img src="https://raw.githubusercontent.com/assistant-ui/assistant-ui/main/.github/assets/logos/Inconvo.svg" height="20" alt="Inconvo"></a>, <a href="https://iterable.com/?ref=assistant-ui" target="_blank" rel="noopener noreferrer"><img src="https://raw.githubusercontent.com/assistant-ui/assistant-ui/main/.github/assets/logos/Iterable.svg" height="20" alt="Iterable"></a>, <a href="https://helicone.ai/?ref=assistant-ui" target="_blank" rel="noopener noreferrer"><img src="https://raw.githubusercontent.com/assistant-ui/assistant-ui/main/.github/assets/logos/helicone.svg" height="20" alt="Helicone"></a>, <a href="https://getgram.ai/?ref=assistant-ui" target="_blank" rel="noopener noreferrer"><img src="https://raw.githubusercontent.com/assistant-ui/assistant-ui/main/.github/assets/logos/gram.svg" height="20" alt="Gram"></a>, <a href="https://coreviz.io/?ref=assistant-ui" target="_blank" rel="noopener noreferrer"><img src="https://raw.githubusercontent.com/assistant-ui/assistant-ui/main/.github/assets/logos/Coreviz.svg" height="20" alt="Coreviz"></a>, and many more.
119
+ <p align="center">
120
+ <a href="https://mastra.ai/?ref=assistant-ui"><img src=".github/assets/logos/Mastra.svg" height="24" alt="Mastra"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="https://langchain.com/?ref=assistant-ui"><img src=".github/assets/logos/LangChain.svg" height="24" alt="LangChain"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="https://athenaintelligence.ai/?ref=assistant-ui"><img src=".github/assets/logos/Athena-Intelligence.svg" height="24" alt="Athena Intelligence"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="https://browser-use.com/?ref=assistant-ui"><img src=".github/assets/logos/Browser-Use.svg" height="24" alt="Browser Use"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="https://stack-ai.com/?ref=assistant-ui"><img src=".github/assets/logos/Stack.svg" height="24" alt="Stack"></a>
121
+ <br /><br />
122
+ <a href="https://inconvo.com/?ref=assistant-ui"><img src=".github/assets/logos/Inconvo.svg" height="24" alt="Inconvo"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="https://iterable.com/?ref=assistant-ui"><img src=".github/assets/logos/Iterable.svg" height="24" alt="Iterable"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="https://helicone.ai/?ref=assistant-ui"><img src=".github/assets/logos/helicone.svg" height="24" alt="Helicone"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="https://getgram.ai/?ref=assistant-ui"><img src=".github/assets/logos/gram.svg" height="24" alt="Gram"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="https://coreviz.io/?ref=assistant-ui"><img src=".github/assets/logos/Coreviz.svg" height="24" alt="Coreviz"></a>
123
+ </p>
124
+
125
+ <p align="center"><sub>…and many more.</sub></p>
100
126
 
101
127
  <a href="https://www.assistant-ui.com/traction">
102
128
  <picture>
@@ -130,11 +156,6 @@ Sample customization to make a Perplexity lookalike:
130
156
  - [Discord](https://discord.com/invite/S9dwgCNEFs)
131
157
  - [Book a sales call](https://cal.com/simon-farshid/assistant-ui)
132
158
 
133
- ## For other platforms
134
-
135
- - React Native: [`@assistant-ui/react-native`](https://www.npmjs.com/package/@assistant-ui/react-native)
136
- - Terminal (Ink): [`@assistant-ui/react-ink`](https://www.npmjs.com/package/@assistant-ui/react-ink)
137
-
138
159
  ## License
139
160
 
140
161
  MIT, with optional Assistant Cloud for managed thread persistence and analytics.
@@ -1 +1 @@
1
- {"version":3,"file":"assistant-transport.js","names":["c","_c","AssistantRuntime","UserCommands","CoreUserCommands","UserExternalState","CoreUserExternalState","useAssistantTransportRuntime","useCoreAssistantTransportRuntime","useAssistantTransportSendCommand","useCoreAssistantTransportSendCommand","useAssistantTransportState","useCoreAssistantTransportState","AssistantTransportCommand","CoreAssistantTransportCommand","AssistantTransportConnectionMetadata","CoreAssistantTransportConnectionMetadata","AssistantTransportOptions","CoreAssistantTransportOptions","AssistantTransportProtocol","SendCommandsRequestBody","CoreSendCommandsRequestBody","K","commands","Exclude","Omit","pendingCommands","AssistantTransportStateConverter","state","T","connectionMetadata","ReturnType","converter","prepareSendCommandsRequest","body","Record","Promise","onError","error","Error","params","updateState","updater","onCancel","options","$","send","t0","command","selector"],"sources":["../src/assistant-transport.ts"],"sourcesContent":["\"use client\";\n\nimport type {\n AssistantRuntime,\n UserCommands as CoreUserCommands,\n UserExternalState as CoreUserExternalState,\n} from \"@assistant-ui/core\";\nimport {\n useAssistantTransportRuntime as useCoreAssistantTransportRuntime,\n useAssistantTransportSendCommand as useCoreAssistantTransportSendCommand,\n useAssistantTransportState as useCoreAssistantTransportState,\n} from \"@assistant-ui/core/react\";\nimport type {\n AssistantTransportCommand as CoreAssistantTransportCommand,\n AssistantTransportConnectionMetadata as CoreAssistantTransportConnectionMetadata,\n AssistantTransportOptions as CoreAssistantTransportOptions,\n AssistantTransportProtocol,\n SendCommandsRequestBody as CoreSendCommandsRequestBody,\n} from \"@assistant-ui/core/react\";\nimport type { UserCommands, UserExternalState } from \"./augmentations\";\n\nexport type { AssistantTransportProtocol };\n\nexport type SendCommandsRequestBody = {\n [\n K in keyof CoreSendCommandsRequestBody as K extends \"commands\" ? never : K\n ]: CoreSendCommandsRequestBody[K];\n} & {\n commands: AssistantTransportCommand[];\n};\n\nexport type AssistantTransportCommand =\n | Exclude<CoreAssistantTransportCommand, CoreUserCommands>\n | UserCommands;\n\nexport type AssistantTransportConnectionMetadata = Omit<\n CoreAssistantTransportConnectionMetadata,\n \"pendingCommands\"\n> & {\n pendingCommands: AssistantTransportCommand[];\n};\n\nexport type AssistantTransportStateConverter<T> = (\n state: T,\n connectionMetadata: AssistantTransportConnectionMetadata,\n) => ReturnType<CoreAssistantTransportOptions<T>[\"converter\"]>;\n\nexport type AssistantTransportOptions<T> = Omit<\n CoreAssistantTransportOptions<T>,\n \"converter\" | \"prepareSendCommandsRequest\" | \"onError\" | \"onCancel\"\n> & {\n converter: AssistantTransportStateConverter<T>;\n prepareSendCommandsRequest?: (\n body: SendCommandsRequestBody,\n ) => Record<string, unknown> | Promise<Record<string, unknown>>;\n onError?: (\n error: Error,\n params: {\n commands: AssistantTransportCommand[];\n updateState: (updater: (state: T) => T) => void;\n },\n ) => void | Promise<void>;\n onCancel?: (params: {\n commands: AssistantTransportCommand[];\n updateState: (updater: (state: T) => T) => void;\n error?: Error;\n }) => void;\n};\n\nexport const useAssistantTransportRuntime = <T>(\n options: AssistantTransportOptions<T>,\n): AssistantRuntime => {\n return useCoreAssistantTransportRuntime(\n options as CoreAssistantTransportOptions<T>,\n );\n};\n\nexport const useAssistantTransportSendCommand = () => {\n const send = useCoreAssistantTransportSendCommand();\n return (command: AssistantTransportCommand) => {\n send(command as CoreAssistantTransportCommand);\n };\n};\n\nexport function useAssistantTransportState(): UserExternalState;\nexport function useAssistantTransportState<T>(\n selector: (state: UserExternalState) => T,\n): T;\nexport function useAssistantTransportState<T>(\n selector: (state: UserExternalState) => T = (state) => state as T,\n): T | UserExternalState {\n return useCoreAssistantTransportState(\n selector as (state: CoreUserExternalState) => T,\n );\n}\n"],"mappings":";;;;AAqEA,MAAaO,gCAA+BqC,YAAA;CAAA,OAGnCpC,+BACLoC,OACF;AAAC;AAGH,MAAanC,yCAAmC;CAAA,MAAAoC,IAAA5C,EAAA,CAAA;CAC9C,MAAA6C,OAAapC,mCAAqC;CAAE,IAAAqC;CAAA,IAAAF,EAAA,OAAAC,MAAA;EAC7CC,MAAAC,YAAA;GACLF,KAAKE,OAAwC;EAAC;EAC/CH,EAAA,KAAAC;EAAAD,EAAA,KAAAE;CAAA,OAAAA,KAAAF,EAAA;CAAA,OAFME;AAEN;AAOH,SAAgBpC,2BACdsC,YAA6CrB,UAAUA,OAChC;CACvB,OAAOhB,6BACLqC,QACF;AACF"}
1
+ {"version":3,"file":"assistant-transport.js","names":["c","_c","AssistantRuntime","UserCommands","CoreUserCommands","UserExternalState","CoreUserExternalState","useAssistantTransportRuntime","useCoreAssistantTransportRuntime","useAssistantTransportSendCommand","useCoreAssistantTransportSendCommand","useAssistantTransportState","useCoreAssistantTransportState","AssistantTransportCommand","CoreAssistantTransportCommand","AssistantTransportConnectionMetadata","CoreAssistantTransportConnectionMetadata","AssistantTransportOptions","CoreAssistantTransportOptions","AssistantTransportProtocol","SendCommandsRequestBody","CoreSendCommandsRequestBody","K","commands","Exclude","Omit","pendingCommands","AssistantTransportStateConverter","state","T","connectionMetadata","ReturnType","converter","prepareSendCommandsRequest","body","Record","Promise","onError","error","Error","params","updateState","updater","onCancel","options","$","send","t0","command","selector","useCoreAssistantTransportRuntime","_c","useCoreAssistantTransportSendCommand","useCoreAssistantTransportState"],"sources":["../src/assistant-transport.ts"],"sourcesContent":["\"use client\";\n\nimport type {\n AssistantRuntime,\n UserCommands as CoreUserCommands,\n UserExternalState as CoreUserExternalState,\n} from \"@assistant-ui/core\";\nimport {\n useAssistantTransportRuntime as useCoreAssistantTransportRuntime,\n useAssistantTransportSendCommand as useCoreAssistantTransportSendCommand,\n useAssistantTransportState as useCoreAssistantTransportState,\n} from \"@assistant-ui/core/react\";\nimport type {\n AssistantTransportCommand as CoreAssistantTransportCommand,\n AssistantTransportConnectionMetadata as CoreAssistantTransportConnectionMetadata,\n AssistantTransportOptions as CoreAssistantTransportOptions,\n AssistantTransportProtocol,\n SendCommandsRequestBody as CoreSendCommandsRequestBody,\n} from \"@assistant-ui/core/react\";\nimport type { UserCommands, UserExternalState } from \"./augmentations\";\n\nexport type { AssistantTransportProtocol };\n\nexport type SendCommandsRequestBody = {\n [\n K in keyof CoreSendCommandsRequestBody as K extends \"commands\" ? never : K\n ]: CoreSendCommandsRequestBody[K];\n} & {\n commands: AssistantTransportCommand[];\n};\n\nexport type AssistantTransportCommand =\n | Exclude<CoreAssistantTransportCommand, CoreUserCommands>\n | UserCommands;\n\nexport type AssistantTransportConnectionMetadata = Omit<\n CoreAssistantTransportConnectionMetadata,\n \"pendingCommands\"\n> & {\n pendingCommands: AssistantTransportCommand[];\n};\n\nexport type AssistantTransportStateConverter<T> = (\n state: T,\n connectionMetadata: AssistantTransportConnectionMetadata,\n) => ReturnType<CoreAssistantTransportOptions<T>[\"converter\"]>;\n\nexport type AssistantTransportOptions<T> = Omit<\n CoreAssistantTransportOptions<T>,\n \"converter\" | \"prepareSendCommandsRequest\" | \"onError\" | \"onCancel\"\n> & {\n converter: AssistantTransportStateConverter<T>;\n prepareSendCommandsRequest?: (\n body: SendCommandsRequestBody,\n ) => Record<string, unknown> | Promise<Record<string, unknown>>;\n onError?: (\n error: Error,\n params: {\n commands: AssistantTransportCommand[];\n updateState: (updater: (state: T) => T) => void;\n },\n ) => void | Promise<void>;\n onCancel?: (params: {\n commands: AssistantTransportCommand[];\n updateState: (updater: (state: T) => T) => void;\n error?: Error;\n }) => void;\n};\n\nexport const useAssistantTransportRuntime = <T>(\n options: AssistantTransportOptions<T>,\n): AssistantRuntime => {\n return useCoreAssistantTransportRuntime(\n options as CoreAssistantTransportOptions<T>,\n );\n};\n\nexport const useAssistantTransportSendCommand = () => {\n const send = useCoreAssistantTransportSendCommand();\n return (command: AssistantTransportCommand) => {\n send(command as CoreAssistantTransportCommand);\n };\n};\n\nexport function useAssistantTransportState(): UserExternalState;\nexport function useAssistantTransportState<T>(\n selector: (state: UserExternalState) => T,\n): T;\nexport function useAssistantTransportState<T>(\n selector: (state: UserExternalState) => T = (state) => state as T,\n): T | UserExternalState {\n return useCoreAssistantTransportState(\n selector as (state: CoreUserExternalState) => T,\n );\n}\n"],"mappings":";;;;AAqEA,MAAaO,gCAA+BqC,YAAA;CAAA,OAGnCpC,+BACLoC,OACF;AAAC;AAGH,MAAanC,yCAAmC;CAAA,MAAAoC,IAAA5C,EAAA,CAAA;CAC9C,MAAA6C,OAAapC,mCAAqC;CAAE,IAAAqC;CAAA,IAAAF,EAAA,OAAAC,MAAA;EAC7CC,MAAAC,YAAA;GACLF,KAAKE,OAAwC;EAAC;EAC/CH,EAAA,KAAAC;EAAAD,EAAA,KAAAE;CAAA,OAAAA,KAAAF,EAAA;CAAA,OAFME;AAEN;AAOH,SAAgBpC,2BACdsC,YAA6CrB,UAAUA,OAChC;CACvB,OAAOhB,6BACLqC,QACF;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"CloudRendererHost.js","names":["c","_c","Component","ErrorInfo","ReactNode","useEffect","useMemo","useRef","useState","useSyncExternalStore","AuiConfig","AuiProvider","useAui","AssistantClient","resource","ReadonlyThreadProvider","ThreadMessage","AssistantRuntimeProvider","useExternalStoreRuntime","CHANNEL","toOrigin","value","url","URL","protocol","origin","undefined","DEFAULT_ALLOWED_ORIGINS","INERT_STORE","messages","isDisabled","onNew","HostMessage","channel","version","type","height","message","CloudRendererHostProps","children","allowedOrigins","aui","Props","config","RenderBoundary","onError","error","Error","failed","state","getDerivedStateFromError","componentDidCatch","_info","props","render","useReadonlyTools","$","tools","subscribe","getState","t0","mcpApp","t1","t2","setToolUI","ReadonlyTools","SuppressMcpApps","ReadonlyConversation","runtime","t3","t4","CloudRendererHost","rootRef","connectedOrigin","setRender","flatMap","_temp","join","originsKey","origins","split","current","includes","post","_temp2","origin_0","onMessage","event","source","window","parent","data","message_0","Record","Array","isArray","previous","revision","addEventListener","removeEventListener","t5","t6","root","frame","report","requestAnimationFrame","origin_1","getBoundingClientRect","Number","isFinite","postMessage","observer","ResizeObserver","observe","disconnect","cancelAnimationFrame","t7","Symbol","for","origin_2","reportError","t8","t9","node","inert","width","t10","t11"],"sources":["../../src/cloud-renderer/CloudRendererHost.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n Component,\n type ErrorInfo,\n type ReactNode,\n useEffect,\n useMemo,\n useRef,\n useState,\n useSyncExternalStore,\n} from \"react\";\nimport {\n AuiConfig,\n AuiProvider,\n useAui,\n type AssistantClient,\n} from \"@assistant-ui/store\";\nimport { resource } from \"@assistant-ui/tap\";\nimport { ReadonlyThreadProvider } from \"@assistant-ui/core/react\";\nimport type { ThreadMessage } from \"@assistant-ui/core\";\nimport { AssistantRuntimeProvider } from \"../legacy-runtime/AssistantRuntimeProvider\";\nimport { useExternalStoreRuntime } from \"../legacy-runtime/runtime-cores/external-store/useExternalStoreRuntime\";\n\nconst CHANNEL = \"assistant-ui/cloud-renderer\";\n\nconst toOrigin = (value: string) => {\n try {\n const url = new URL(value);\n return url.protocol === \"https:\" || url.protocol === \"http:\"\n ? url.origin\n : undefined;\n } catch {\n return undefined;\n }\n};\nconst DEFAULT_ALLOWED_ORIGINS = [\"https://cloud.assistant-ui.com\"];\nconst INERT_STORE = {\n messages: [] as ThreadMessage[],\n isDisabled: true,\n onNew: async () => {},\n};\n\ntype HostMessage =\n | { channel: typeof CHANNEL; version: 1; type: \"ready\" }\n | { channel: typeof CHANNEL; version: 1; type: \"size\"; height: number }\n | { channel: typeof CHANNEL; version: 1; type: \"error\"; message: string };\n\nexport type CloudRendererHostProps = {\n /** The app's thread UI, usually its own `<Thread />`. */\n children: ReactNode;\n /** Dashboard origins allowed to send a conversation. Defaults to Assistant Cloud's dashboard. */\n allowedOrigins?: readonly string[] | undefined;\n /** The same client or config the app passes to AssistantRuntimeProvider, so tool UIs, data UIs and generative UI render as they do in the app. */\n aui?: AssistantRuntimeProvider.Props[\"aui\"];\n config?: AssistantRuntimeProvider.Props[\"config\"];\n};\n\nclass RenderBoundary extends Component<\n { children: ReactNode; onError: (error: Error) => void },\n { failed: boolean }\n> {\n override state = { failed: false };\n\n static getDerivedStateFromError() {\n return { failed: true };\n }\n\n override componentDidCatch(error: Error, _info: ErrorInfo) {\n this.props.onError(error);\n }\n\n override render() {\n return this.state.failed ? null : this.props.children;\n }\n}\n\nconst useReadonlyTools = (aui: AssistantClient) => {\n const tools = useSyncExternalStore(aui.subscribe, aui.tools.getState);\n const state = useMemo(() => ({ ...tools, mcpApp: undefined }), [tools]);\n return {\n getState: () => state,\n setToolUI: aui.tools.setToolUI,\n };\n};\n\nconst ReadonlyTools = resource(useReadonlyTools);\n\nconst SuppressMcpApps = ({ children }: { children: ReactNode }) => {\n const aui = useAui();\n return (\n <AuiProvider\n extends={aui}\n config={AuiConfig({ tools: ReadonlyTools(aui) })}\n >\n {children}\n </AuiProvider>\n );\n};\n\nconst ReadonlyConversation = ({\n messages,\n children,\n aui,\n config,\n}: {\n messages: readonly ThreadMessage[];\n children: ReactNode;\n aui: CloudRendererHostProps[\"aui\"];\n config: CloudRendererHostProps[\"config\"];\n}) => {\n const runtime = useExternalStoreRuntime<ThreadMessage>(INERT_STORE);\n\n return (\n <AssistantRuntimeProvider\n runtime={runtime}\n {...(aui !== undefined && { aui })}\n {...(config !== undefined && { config })}\n >\n <SuppressMcpApps>\n <ReadonlyThreadProvider messages={messages}>\n {children}\n </ReadonlyThreadProvider>\n </SuppressMcpApps>\n </AssistantRuntimeProvider>\n );\n};\n\nexport function CloudRendererHost({\n children,\n allowedOrigins = DEFAULT_ALLOWED_ORIGINS,\n aui,\n config,\n}: CloudRendererHostProps): ReactNode {\n const rootRef = useRef<HTMLDivElement>(null);\n const connectedOrigin = useRef<string | null>(null);\n const [render, setRender] = useState<{\n messages: readonly ThreadMessage[];\n revision: number;\n } | null>(null);\n\n const originsKey = allowedOrigins\n .flatMap((value) => toOrigin(value) ?? [])\n .join(\" \");\n\n useEffect(() => {\n const origins = originsKey ? originsKey.split(\" \") : [];\n if (\n connectedOrigin.current !== null &&\n !origins.includes(connectedOrigin.current)\n ) {\n connectedOrigin.current = null;\n }\n const post = (origin: string, message: HostMessage) =>\n window.parent.postMessage(message, origin);\n\n for (const origin of origins) {\n post(origin, { channel: CHANNEL, version: 1, type: \"ready\" });\n }\n\n const onMessage = (event: MessageEvent) => {\n if (event.source !== window.parent || !origins.includes(event.origin))\n return;\n const data: unknown = event.data;\n if (typeof data !== \"object\" || data === null) return;\n const message = data as Record<string, unknown>;\n if (\n message.channel !== CHANNEL ||\n message.version !== 1 ||\n message.type !== \"render\" ||\n !Array.isArray(message.messages)\n )\n return;\n if (\n connectedOrigin.current !== null &&\n connectedOrigin.current !== event.origin\n )\n return;\n\n connectedOrigin.current = event.origin;\n setRender((previous) => ({\n messages: message.messages as ThreadMessage[],\n revision: (previous?.revision ?? 0) + 1,\n }));\n };\n\n window.addEventListener(\"message\", onMessage);\n return () => window.removeEventListener(\"message\", onMessage);\n }, [originsKey]);\n\n useEffect(() => {\n if (!render || !rootRef.current) return;\n const root = rootRef.current;\n let frame = 0;\n const report = () => {\n if (frame) return;\n frame = requestAnimationFrame(() => {\n frame = 0;\n const origin = connectedOrigin.current;\n const height = root.getBoundingClientRect().height;\n if (origin && Number.isFinite(height) && height >= 0) {\n window.parent.postMessage(\n { channel: CHANNEL, version: 1, type: \"size\", height },\n origin,\n );\n }\n });\n };\n const observer = new ResizeObserver(report);\n observer.observe(root);\n report();\n return () => {\n observer.disconnect();\n cancelAnimationFrame(frame);\n };\n }, [render]);\n\n const reportError = (error: Error) => {\n const origin = connectedOrigin.current;\n if (origin) {\n window.parent.postMessage(\n { channel: CHANNEL, version: 1, type: \"error\", message: error.message },\n origin,\n );\n }\n };\n\n return (\n <div\n ref={(node) => {\n rootRef.current = node;\n if (node) node.inert = true;\n }}\n style={{ width: \"100%\" }}\n >\n {render && (\n <RenderBoundary key={render.revision} onError={reportError}>\n <ReadonlyConversation\n messages={render.messages}\n aui={aui}\n config={config}\n >\n {children}\n </ReadonlyConversation>\n </RenderBoundary>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"CloudRendererHost.js","names":["c","_c","Component","ErrorInfo","ReactNode","useEffect","useMemo","useRef","useState","useSyncExternalStore","AuiConfig","AuiProvider","useAui","AssistantClient","resource","ReadonlyThreadProvider","ThreadMessage","AssistantRuntimeProvider","useExternalStoreRuntime","CHANNEL","toOrigin","value","url","URL","protocol","origin","undefined","DEFAULT_ALLOWED_ORIGINS","INERT_STORE","messages","isDisabled","onNew","HostMessage","channel","version","type","height","message","CloudRendererHostProps","children","allowedOrigins","aui","Props","config","RenderBoundary","onError","error","Error","failed","state","getDerivedStateFromError","componentDidCatch","_info","props","render","useReadonlyTools","$","tools","subscribe","getState","t0","mcpApp","t1","t2","setToolUI","ReadonlyTools","SuppressMcpApps","ReadonlyConversation","runtime","t3","t4","CloudRendererHost","rootRef","connectedOrigin","setRender","flatMap","_temp","join","originsKey","origins","split","current","includes","post","_temp2","origin_0","onMessage","event","source","window","parent","data","message_0","Record","Array","isArray","previous","revision","addEventListener","removeEventListener","t5","t6","root","frame","report","requestAnimationFrame","origin_1","getBoundingClientRect","Number","isFinite","postMessage","observer","ResizeObserver","observe","disconnect","cancelAnimationFrame","t7","Symbol","for","origin_2","reportError","t8","t9","node","inert","width","t10","t11","_c"],"sources":["../../src/cloud-renderer/CloudRendererHost.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n Component,\n type ErrorInfo,\n type ReactNode,\n useEffect,\n useMemo,\n useRef,\n useState,\n useSyncExternalStore,\n} from \"react\";\nimport {\n AuiConfig,\n AuiProvider,\n useAui,\n type AssistantClient,\n} from \"@assistant-ui/store\";\nimport { resource } from \"@assistant-ui/tap\";\nimport { ReadonlyThreadProvider } from \"@assistant-ui/core/react\";\nimport type { ThreadMessage } from \"@assistant-ui/core\";\nimport { AssistantRuntimeProvider } from \"../legacy-runtime/AssistantRuntimeProvider\";\nimport { useExternalStoreRuntime } from \"../legacy-runtime/runtime-cores/external-store/useExternalStoreRuntime\";\n\nconst CHANNEL = \"assistant-ui/cloud-renderer\";\n\nconst toOrigin = (value: string) => {\n try {\n const url = new URL(value);\n return url.protocol === \"https:\" || url.protocol === \"http:\"\n ? url.origin\n : undefined;\n } catch {\n return undefined;\n }\n};\nconst DEFAULT_ALLOWED_ORIGINS = [\"https://cloud.assistant-ui.com\"];\nconst INERT_STORE = {\n messages: [] as ThreadMessage[],\n isDisabled: true,\n onNew: async () => {},\n};\n\ntype HostMessage =\n | { channel: typeof CHANNEL; version: 1; type: \"ready\" }\n | { channel: typeof CHANNEL; version: 1; type: \"size\"; height: number }\n | { channel: typeof CHANNEL; version: 1; type: \"error\"; message: string };\n\nexport type CloudRendererHostProps = {\n /** The app's thread UI, usually its own `<Thread />`. */\n children: ReactNode;\n /** Dashboard origins allowed to send a conversation. Defaults to Assistant Cloud's dashboard. */\n allowedOrigins?: readonly string[] | undefined;\n /** The same client or config the app passes to AssistantRuntimeProvider, so tool UIs, data UIs and generative UI render as they do in the app. */\n aui?: AssistantRuntimeProvider.Props[\"aui\"];\n config?: AssistantRuntimeProvider.Props[\"config\"];\n};\n\nclass RenderBoundary extends Component<\n { children: ReactNode; onError: (error: Error) => void },\n { failed: boolean }\n> {\n override state = { failed: false };\n\n static getDerivedStateFromError() {\n return { failed: true };\n }\n\n override componentDidCatch(error: Error, _info: ErrorInfo) {\n this.props.onError(error);\n }\n\n override render() {\n return this.state.failed ? null : this.props.children;\n }\n}\n\nconst useReadonlyTools = (aui: AssistantClient) => {\n const tools = useSyncExternalStore(aui.subscribe, aui.tools.getState);\n const state = useMemo(() => ({ ...tools, mcpApp: undefined }), [tools]);\n return {\n getState: () => state,\n setToolUI: aui.tools.setToolUI,\n };\n};\n\nconst ReadonlyTools = resource(useReadonlyTools);\n\nconst SuppressMcpApps = ({ children }: { children: ReactNode }) => {\n const aui = useAui();\n return (\n <AuiProvider\n extends={aui}\n config={AuiConfig({ tools: ReadonlyTools(aui) })}\n >\n {children}\n </AuiProvider>\n );\n};\n\nconst ReadonlyConversation = ({\n messages,\n children,\n aui,\n config,\n}: {\n messages: readonly ThreadMessage[];\n children: ReactNode;\n aui: CloudRendererHostProps[\"aui\"];\n config: CloudRendererHostProps[\"config\"];\n}) => {\n const runtime = useExternalStoreRuntime<ThreadMessage>(INERT_STORE);\n\n return (\n <AssistantRuntimeProvider\n runtime={runtime}\n {...(aui !== undefined && { aui })}\n {...(config !== undefined && { config })}\n >\n <SuppressMcpApps>\n <ReadonlyThreadProvider messages={messages}>\n {children}\n </ReadonlyThreadProvider>\n </SuppressMcpApps>\n </AssistantRuntimeProvider>\n );\n};\n\nexport function CloudRendererHost({\n children,\n allowedOrigins = DEFAULT_ALLOWED_ORIGINS,\n aui,\n config,\n}: CloudRendererHostProps): ReactNode {\n const rootRef = useRef<HTMLDivElement>(null);\n const connectedOrigin = useRef<string | null>(null);\n const [render, setRender] = useState<{\n messages: readonly ThreadMessage[];\n revision: number;\n } | null>(null);\n\n const originsKey = allowedOrigins\n .flatMap((value) => toOrigin(value) ?? [])\n .join(\" \");\n\n useEffect(() => {\n const origins = originsKey ? originsKey.split(\" \") : [];\n if (\n connectedOrigin.current !== null &&\n !origins.includes(connectedOrigin.current)\n ) {\n connectedOrigin.current = null;\n }\n const post = (origin: string, message: HostMessage) =>\n window.parent.postMessage(message, origin);\n\n for (const origin of origins) {\n post(origin, { channel: CHANNEL, version: 1, type: \"ready\" });\n }\n\n const onMessage = (event: MessageEvent) => {\n if (event.source !== window.parent || !origins.includes(event.origin))\n return;\n const data: unknown = event.data;\n if (typeof data !== \"object\" || data === null) return;\n const message = data as Record<string, unknown>;\n if (\n message.channel !== CHANNEL ||\n message.version !== 1 ||\n message.type !== \"render\" ||\n !Array.isArray(message.messages)\n )\n return;\n if (\n connectedOrigin.current !== null &&\n connectedOrigin.current !== event.origin\n )\n return;\n\n connectedOrigin.current = event.origin;\n setRender((previous) => ({\n messages: message.messages as ThreadMessage[],\n revision: (previous?.revision ?? 0) + 1,\n }));\n };\n\n window.addEventListener(\"message\", onMessage);\n return () => window.removeEventListener(\"message\", onMessage);\n }, [originsKey]);\n\n useEffect(() => {\n if (!render || !rootRef.current) return;\n const root = rootRef.current;\n let frame = 0;\n const report = () => {\n if (frame) return;\n frame = requestAnimationFrame(() => {\n frame = 0;\n const origin = connectedOrigin.current;\n const height = root.getBoundingClientRect().height;\n if (origin && Number.isFinite(height) && height >= 0) {\n window.parent.postMessage(\n { channel: CHANNEL, version: 1, type: \"size\", height },\n origin,\n );\n }\n });\n };\n const observer = new ResizeObserver(report);\n observer.observe(root);\n report();\n return () => {\n observer.disconnect();\n cancelAnimationFrame(frame);\n };\n }, [render]);\n\n const reportError = (error: Error) => {\n const origin = connectedOrigin.current;\n if (origin) {\n window.parent.postMessage(\n { channel: CHANNEL, version: 1, type: \"error\", message: error.message },\n origin,\n );\n }\n };\n\n return (\n <div\n ref={(node) => {\n rootRef.current = node;\n if (node) node.inert = true;\n }}\n style={{ width: \"100%\" }}\n >\n {render && (\n <RenderBoundary key={render.revision} onError={reportError}>\n <ReadonlyConversation\n messages={render.messages}\n aui={aui}\n config={config}\n >\n {children}\n </ReadonlyConversation>\n </RenderBoundary>\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;AAwBA,MAAMmB,UAAU;AAEhB,MAAMC,YAAYC,UAAkB;CAClC,IAAI;EACF,MAAMC,MAAM,IAAIC,IAAIF,KAAK;EACzB,OAAOC,IAAIE,aAAa,YAAYF,IAAIE,aAAa,UACjDF,IAAIG,SACJC,KAAAA;CACN,QAAQ;EACN;CACF;AACF;AACA,MAAMC,0BAA0B,CAAC,gCAAgC;AACjE,MAAMC,cAAc;CAClBC,UAAU,CAAA;CACVC,YAAY;CACZC,OAAO,YAAY,CAAC;AACtB;AAiBA,IAAMa,iBAAN,cAA6B1C,UAG3B;CACA,QAAiB,EAAE8C,QAAQ,MAAM;CAEjC,OAAOE,2BAA2B;EAChC,OAAO,EAAEF,QAAQ,KAAK;CACxB;CAEA,kBAA2BF,OAAcM,OAAkB;EACzD,KAAKC,MAAMR,QAAQC,KAAK;CAC1B;CAEA,SAAkB;EAChB,OAAO,KAAKG,MAAMD,SAAS,OAAO,KAAKK,MAAMd;CAC/C;AACF;AAEA,MAAMgB,oBAAmBd,QAAA;CAAA,MAAAe,IAAAvD,EAAA,CAAA;CACvB,MAAAwD,QAAchD,qBAAqBgC,IAAGiB,WAAYjB,IAAGgB,MAAME,QAAS;CAAE,IAAAC;CAAA,IAAAJ,EAAA,OAAAC,OAAA;EACzCG,KAAA;GAAA,GAAKH;GAAKI,QAAUnC,KAAAA;EAAU;EAAC8B,EAAA,KAAAC;EAAAD,EAAA,KAAAI;CAAA,OAAAA,KAAAJ,EAAA;CAA5D,MAAAP,QAA6BW;CAA2C,IAAAE;CAAA,IAAAN,EAAA,OAAAP,OAAA;EAE5Da,WAAMb;EAAKO,EAAA,KAAAP;EAAAO,EAAA,KAAAM;CAAA,OAAAA,KAAAN,EAAA;CAAA,IAAAO;CAAA,IAAAP,EAAA,OAAAf,IAAAgB,MAAAO,aAAAR,EAAA,OAAAM,IAAA;EADhBC,KAAA;GAAAJ,UACKG;GAAWE,WACVvB,IAAGgB,MAAMO;EACtB;EAACR,EAAA,KAAAf,IAAAgB,MAAAO;EAAAR,EAAA,KAAAM;EAAAN,EAAA,KAAAO;CAAA,OAAAA,KAAAP,EAAA;CAAA,OAHMO;AAGN;AAGH,MAAME,gBAAgBnD,SAASyC,gBAAgB;AAE/C,MAAMW,mBAAkBN,OAAA;CAAA,MAAAJ,IAAAvD,EAAA,CAAA;CAAC,MAAA,EAAAsC,aAAAqB;CACvB,MAAAnB,MAAY7B,OAAO;CAAE,IAAAkD;CAAA,IAAAN,EAAA,OAAAf,KAAA;EAITqB,KAAApD,UAAU,EAAA+C,OAASQ,cAAcxB,GAAG,EAAE,CAAC;EAACe,EAAA,KAAAf;EAAAe,EAAA,KAAAM;CAAA,OAAAA,KAAAN,EAAA;CAAA,IAAAO;CAAA,IAAAP,EAAA,OAAAf,OAAAe,EAAA,OAAAjB,YAAAiB,EAAA,OAAAM,IAAA;EAFlDC,KAAA,oBAAC,aAAD;GACWtB,SAAAA;GACD,QAAAqB;GAEPvB;EAJS,CAAA;EAKEiB,EAAA,KAAAf;EAAAe,EAAA,KAAAjB;EAAAiB,EAAA,KAAAM;EAAAN,EAAA,KAAAO;CAAA,OAAAA,KAAAP,EAAA;CAAA,OALdO;AAKc;AAIlB,MAAMI,wBAAuBP,OAAA;CAAA,MAAAJ,IAAAvD,EAAA,EAAA;CAAC,MAAA,EAAA4B,UAAAU,UAAAE,KAAAE,WAAAiB;CAW5B,MAAAQ,UAAgBlD,wBAAuCU,WAAW;CAAE,IAAAkC;CAAA,IAAAN,EAAA,OAAAf,KAAA;EAK3DqB,KAAArB,QAAQf,KAAAA,KAAR,EAAAe,IAA2B;EAACe,EAAA,KAAAf;EAAAe,EAAA,KAAAM;CAAA,OAAAA,KAAAN,EAAA;CAAA,IAAAO;CAAA,IAAAP,EAAA,OAAAb,QAAA;EAC5BoB,KAAApB,WAAWjB,KAAAA,KAAX,EAAAiB,OAAiC;EAACa,EAAA,KAAAb;EAAAa,EAAA,KAAAO;CAAA,OAAAA,KAAAP,EAAA;CAAA,IAAAa;CAAA,IAAAb,EAAA,OAAAjB,YAAAiB,EAAA,OAAA3B,UAAA;EAEvCwC,KAAA,oBAAC,iBAAD,EAAA,UACE,oBAAC,wBAAD;GAAkCxC;GAC/BU;EADoB,CAAA,EADT,CAAA;EAIEiB,EAAA,KAAAjB;EAAAiB,EAAA,KAAA3B;EAAA2B,EAAA,KAAAa;CAAA,OAAAA,KAAAb,EAAA;CAAA,IAAAc;CAAA,IAAAd,EAAA,OAAAY,WAAAZ,EAAA,OAAAM,MAAAN,EAAA,OAAAO,MAAAP,EAAA,QAAAa,IAAA;EATpBC,KAAA,oBAAC,0BAAD;GACWF;GAAO,GACXN;GAA4B,GAC5BC;GAELM,UAAAA;EALuB,CAAA;EAUEb,EAAA,KAAAY;EAAAZ,EAAA,KAAAM;EAAAN,EAAA,KAAAO;EAAAP,EAAA,MAAAa;EAAAb,EAAA,MAAAc;CAAA,OAAAA,KAAAd,EAAA;CAAA,OAV3Bc;AAU2B;AAI/B,SAAOC,kBAAAX,IAAA;CAAA,MAAAJ,IAAAvD,EAAA,EAAA;CAA2B,MAAA,EAAAsC,UAAAC,gBAAAsB,IAAArB,KAAAE,WAAAiB;CAEhC,MAAApB,iBAAAsB,OAAApC,KAAAA,IAAAC,0BAAAmC;CAIA,MAAAU,UAAgBjE,OAAuB,IAAI;CAC3C,MAAAkE,kBAAwBlE,OAAsB,IAAI;CAClD,MAAA,CAAA+C,QAAAoB,aAA4BlE,SAGlB,IAAI;CAAE,IAAAuD;CAAA,IAAAP,EAAA,OAAAhB,gBAAA;EAEGuB,KAAAvB,eAAcmC,QACtBC,KAAgC,CAAC,CAAAC,KACpC,GAAG;EAACrB,EAAA,KAAAhB;EAAAgB,EAAA,KAAAO;CAAA,OAAAA,KAAAP,EAAA;CAFZ,MAAAsB,aAAmBf;CAEN,IAAAM;CAAA,IAAAC;CAAA,IAAAd,EAAA,OAAAsB,YAAA;EAEHT,WAAA;GACR,MAAAU,UAAgBD,aAAaA,WAAUE,MAAO,GAAQ,IAAtC,CAAA;GAChB,IACEP,gBAAeQ,YAAa,QAA5B,CACCF,QAAOG,SAAUT,gBAAeQ,OAAQ,GAEzCR,gBAAeQ,UAAW;GAE5B,MAAAE,OAAaC;GAGb,KAAK,MAAAC,YAAgBN,SACnBI,KAAK1D,UAAQ;IAAAQ,SAAWd;IAAOe,SAAW;IAACC,MAAQ;GAAQ,CAAC;GAG9D,MAAAmD,aAAkBC,UAAA;IAChB,IAAIA,MAAKC,WAAYC,OAAMC,UAAvB,CAAmCX,QAAOG,SAAUK,MAAK9D,MAAO,GAAC;IAErE,MAAAkE,OAAsBJ,MAAKI;IAC3B,IAAI,OAAOA,SAAS,YAAYA,SAAS,MAAI;IAC7C,MAAAC,YAAgBD;IAChB,IACEtD,UAAOJ,YAAad,WACpBkB,UAAOH,YAAa,KACpBG,UAAOF,SAAU,YAFjB,CAGC2D,MAAKC,QAAS1D,UAAOR,QAAS,GAAC;IAGlC,IACE4C,gBAAeQ,YAAa,QAC5BR,gBAAeQ,YAAaM,MAAK9D,QAAO;IAI1CgD,gBAAeQ,UAAWM,MAAK9D;IAC/BiD,WAAUsB,cAAe;KAAAnE,UACbQ,UAAOR;KAA4BoE,WAClCD,UAAQC,YAAR,KAA2B;IACxC,EAAE;GAAC;GAGLR,OAAMS,iBAAkB,WAAWZ,SAAS;GAAC,aAChCG,OAAMU,oBAAqB,WAAWb,SAAS;EAAC;EAC5DhB,KAAA,CAACQ,UAAU;EAACtB,EAAA,KAAAsB;EAAAtB,EAAA,KAAAa;EAAAb,EAAA,KAAAc;CAAA,OAAA;EAAAD,KAAAb,EAAA;EAAAc,KAAAd,EAAA;CAAA;CA3CfnD,UAAUgE,IA2CPC,EAAY;CAAC,IAAA8B;CAAA,IAAAC;CAAA,IAAA7C,EAAA,OAAAF,QAAA;EAEN8C,WAAA;GACR,IAAI,CAAC9C,UAAD,CAAYkB,QAAOS,SAAQ;GAC/B,MAAAqB,OAAa9B,QAAOS;GACpB,IAAAsB,QAAY;GACZ,MAAAC,eAAe;IACb,IAAID,OAAK;IACTA,QAAQE,4BAAsB;KAC5BF,QAAQA;KACR,MAAAG,WAAejC,gBAAeQ;KAC9B,MAAA7C,SAAekE,KAAIK,sBAAuB,CAAC,CAAAvE;KAC3C,IAAIsE,YAAUE,OAAMC,SAAUzE,MAAM,KAAKA,UAAU,GACjDqD,OAAMC,OAAOoB,YACX;MAAA7E,SAAWd;MAAOe,SAAW;MAACC,MAAQ;MAAMC;KAAS,GACrDX,QACF;IACD,CACF;GAVI;GAYP,MAAAsF,WAAiB,IAAIC,eAAeR,MAAM;GAC1CO,SAAQE,QAASX,IAAI;GACrBE,OAAO;GAAC,aACD;IACLO,SAAQG,WAAY;IACpBC,qBAAqBZ,KAAK;GAAC;EAC5B;EACAF,KAAA,CAAC/C,MAAM;EAACE,EAAA,KAAAF;EAAAE,EAAA,KAAA4C;EAAA5C,EAAA,KAAA6C;CAAA,OAAA;EAAAD,KAAA5C,EAAA;EAAA6C,KAAA7C,EAAA;CAAA;CAzBXnD,UAAU+F,IAyBPC,EAAQ;CAAC,IAAAe;CAAA,IAAA5D,EAAA,OAAA6D,OAAAC,IAAA,2BAAA,GAAA;EAEQF,MAAAtE,UAAA;GAClB,MAAAyE,WAAe9C,gBAAeQ;GAC9B,IAAIxD,UACFgE,OAAMC,OAAOoB,YACX;IAAA7E,SAAWd;IAAOe,SAAW;IAACC,MAAQ;IAAOE,SAAWS,MAAKT;GAAS,GACtEZ,QACF;EACD;EACF+B,EAAA,KAAA4D;CAAA,OAAAA,KAAA5D,EAAA;CARD,MAAAgE,cAAoBJ;CAQlB,IAAAK;CAAA,IAAAC;CAAA,IAAAlE,EAAA,OAAA6D,OAAAC,IAAA,2BAAA,GAAA;EAIOG,MAAAE,SAAA;GACHnD,QAAOS,UAAW0C;GAClB,IAAIA,MAAMA,KAAIC,QAAS;EAAK;EAEvBF,KAAA,EAAAG,OAAS,OAAO;EAACrE,EAAA,KAAAiE;EAAAjE,EAAA,MAAAkE;CAAA,OAAA;EAAAD,KAAAjE,EAAA;EAAAkE,KAAAlE,EAAA;CAAA;CAAA,IAAAsE;CAAA,IAAAtE,EAAA,QAAAf,OAAAe,EAAA,QAAAjB,YAAAiB,EAAA,QAAAb,UAAAa,EAAA,QAAAF,QAAA;EAEvBwE,MAAAxE,UACC,oBAAC,gBAAD;GAA+CkE,SAAAA;GAC7C,UAAA,oBAAC,sBAAD;IACY,UAAAlE,OAAMzB;IACXY;IACGE;IAEPJ;GALkB,CAAA;EADR,GAAMe,OAAM2C,QAAZ;EAShBzC,EAAA,MAAAf;EAAAe,EAAA,MAAAjB;EAAAiB,EAAA,MAAAb;EAAAa,EAAA,MAAAF;EAAAE,EAAA,MAAAsE;CAAA,OAAAA,MAAAtE,EAAA;CAAA,IAAAuE;CAAA,IAAAvE,EAAA,QAAAsE,KAAA;EAjBHC,MAAA,oBAAA,OAAA;GACO,KAAAN;GAIE,OAAAC;GAENI,UAAAA;EAWG,CAAA;EAAAtE,EAAA,MAAAsE;EAAAtE,EAAA,MAAAuE;CAAA,OAAAA,MAAAvE,EAAA;CAAA,OAlBNuE;AAkBM;AAtHH,SAAA3C,OAAA3D,QAAAY,SAAA;CAAA,OA0BDoD,OAAMC,OAAOoB,YAAazE,SAASZ,MAAM;AAAC;AA1BzC,SAAAmD,MAAAvD,OAAA;CAAA,OAciBD,SAASC,KAAW,KAApB,CAAA;AAAqB"}
@@ -1 +1 @@
1
- {"version":3,"file":"MessageProvider.js","names":["c","_c","FC","PropsWithChildren","useAui","AuiConfig","AuiProvider","ThreadMessageClientProps","ThreadMessageClient","MessageProvider","t0","$","children","props","aui","config","message","t1"],"sources":["../../../src/context/providers/MessageProvider.tsx"],"sourcesContent":["\"use client\";\n\nimport type { FC, PropsWithChildren } from \"react\";\nimport { useAui, AuiConfig, AuiProvider } from \"@assistant-ui/store\";\nimport {\n type ThreadMessageClientProps,\n ThreadMessageClient,\n} from \"@assistant-ui/core/store\";\n\nexport const MessageProvider: FC<\n PropsWithChildren<ThreadMessageClientProps>\n> = ({ children, ...props }) => {\n const aui = useAui();\n const config = AuiConfig({ message: ThreadMessageClient(props) });\n return (\n <AuiProvider extends={aui} config={config}>\n {children}\n </AuiProvider>\n );\n};\n"],"mappings":";;;;;;AASA,MAAaS,mBAETC,OAAA;CAAA,MAAAC,IAAAV,EAAA,CAAA;CAAC,MAAA,EAAAW,UAAA,GAAAC,UAAAH;CACH,MAAAI,MAAYV,OAAO;CACnB,MAAAW,SAAeV,UAAU,EAAAW,SAAWR,oBAAoBK,KAAK,EAAE,CAAC;CAAE,IAAAI;CAAA,IAAAN,EAAA,OAAAG,OAAAH,EAAA,OAAAC,YAAAD,EAAA,OAAAI,QAAA;EAEhEE,KAAA,oBAAC,aAAD;GAAsBH,SAAAA;GAAaC;GAChCH;EADS,CAAA;EAEED,EAAA,KAAAG;EAAAH,EAAA,KAAAC;EAAAD,EAAA,KAAAI;EAAAJ,EAAA,KAAAM;CAAA,OAAAA,KAAAN,EAAA;CAAA,OAFdM;AAEc"}
1
+ {"version":3,"file":"MessageProvider.js","names":["c","_c","FC","PropsWithChildren","useAui","AuiConfig","AuiProvider","ThreadMessageClientProps","ThreadMessageClient","MessageProvider","t0","$","children","props","aui","config","message","t1","_c"],"sources":["../../../src/context/providers/MessageProvider.tsx"],"sourcesContent":["\"use client\";\n\nimport type { FC, PropsWithChildren } from \"react\";\nimport { useAui, AuiConfig, AuiProvider } from \"@assistant-ui/store\";\nimport {\n type ThreadMessageClientProps,\n ThreadMessageClient,\n} from \"@assistant-ui/core/store\";\n\nexport const MessageProvider: FC<\n PropsWithChildren<ThreadMessageClientProps>\n> = ({ children, ...props }) => {\n const aui = useAui();\n const config = AuiConfig({ message: ThreadMessageClient(props) });\n return (\n <AuiProvider extends={aui} config={config}>\n {children}\n </AuiProvider>\n );\n};\n"],"mappings":";;;;;;AASA,MAAaS,mBAETC,OAAA;CAAA,MAAAC,IAAAV,EAAA,CAAA;CAAC,MAAA,EAAAW,UAAA,GAAAC,UAAAH;CACH,MAAAI,MAAYV,OAAO;CACnB,MAAAW,SAAeV,UAAU,EAAAW,SAAWR,oBAAoBK,KAAK,EAAE,CAAC;CAAE,IAAAI;CAAA,IAAAN,EAAA,OAAAG,OAAAH,EAAA,OAAAC,YAAAD,EAAA,OAAAI,QAAA;EAEhEE,KAAA,oBAAC,aAAD;GAAsBH,SAAAA;GAAaC;GAChCH;EADS,CAAA;EAEED,EAAA,KAAAG;EAAAH,EAAA,KAAAC;EAAAD,EAAA,KAAAI;EAAAJ,EAAA,KAAAM;CAAA,OAAAA,KAAAN,EAAA;CAAA,OAFdM;AAEc"}
@@ -1 +1 @@
1
- {"version":3,"file":"ThreadViewportProvider.js","names":["c","_c","FC","PropsWithChildren","useEffect","useState","makeThreadViewportStore","ThreadViewportStoreOptions","ThreadViewportContext","ThreadViewportContextValue","useThreadViewportStore","writableStore","ThreadViewportProviderProps","options","useThreadViewportStoreValue","$","t0","Symbol","for","optional","outerViewport","t1","store","t2","t3","getState","onScrollToBottom","config","scrollToBottom","t4","t5","subscribe","state","isAtBottom","setState","ThreadPrimitiveViewportProvider","children","undefined","useThreadViewport","context"],"sources":["../../../src/context/providers/ThreadViewportProvider.tsx"],"sourcesContent":["\"use client\";\n\nimport { type FC, type PropsWithChildren, useEffect, useState } from \"react\";\n\nimport {\n makeThreadViewportStore,\n type ThreadViewportStoreOptions,\n} from \"../stores/ThreadViewport\";\nimport {\n ThreadViewportContext,\n type ThreadViewportContextValue,\n useThreadViewportStore,\n} from \"../react/ThreadViewportContext\";\nimport { writableStore } from \"../ReadonlyStore\";\n\nexport type ThreadViewportProviderProps = PropsWithChildren<{\n options?: ThreadViewportStoreOptions;\n}>;\n\nconst useThreadViewportStoreValue = (options: ThreadViewportStoreOptions) => {\n const outerViewport = useThreadViewportStore({ optional: true });\n // Viewport options are initial configuration. Keeping them non-reactive avoids\n // fanout through every message in long threads when anchoring config changes.\n const [store] = useState(() => makeThreadViewportStore(options));\n\n // Forward scrollToBottom from outer viewport to inner viewport\n useEffect(() => {\n return outerViewport?.getState().onScrollToBottom((config) => {\n store.getState().scrollToBottom(config);\n });\n }, [outerViewport, store]);\n\n useEffect(() => {\n if (!outerViewport) return;\n return store.subscribe((state) => {\n if (outerViewport.getState().isAtBottom !== state.isAtBottom) {\n writableStore(outerViewport).setState({ isAtBottom: state.isAtBottom });\n }\n });\n }, [store, outerViewport]);\n\n return store;\n};\n\nexport const ThreadPrimitiveViewportProvider: FC<\n ThreadViewportProviderProps\n> = ({ children, options = {} }) => {\n const useThreadViewport = useThreadViewportStoreValue(options);\n\n const [context] = useState<ThreadViewportContextValue>(() => {\n return {\n useThreadViewport,\n };\n });\n\n return (\n <ThreadViewportContext.Provider value={context}>\n {children}\n </ThreadViewportContext.Provider>\n );\n};\n"],"mappings":";;;;;;;;AAmBA,MAAMc,+BAA8BD,YAAA;CAAA,MAAAE,IAAAd,EAAA,EAAA;CAAA,IAAAe;CAAA,IAAAD,EAAA,OAAAE,OAAAC,IAAA,2BAAA,GAAA;EACWF,KAAA,EAAAG,UAAY,KAAK;EAACJ,EAAA,KAAAC;CAAA,OAAAA,KAAAD,EAAA;CAA/D,MAAAK,gBAAsBV,uBAAuBM,EAAkB;CAAE,IAAAK;CAAA,IAAAN,EAAA,OAAAF,SAAA;EAGxCQ,WAAMf,wBAAwBO,OAAO;EAACE,EAAA,KAAAF;EAAAE,EAAA,KAAAM;CAAA,OAAAA,KAAAN,EAAA;CAA/D,MAAA,CAAAO,SAAgBjB,SAASgB,EAAsC;CAAE,IAAAE;CAAA,IAAAC;CAAA,IAAAT,EAAA,OAAAK,iBAAAL,EAAA,OAAAO,OAAA;EAGvDC,WACDH,eAAaK,SAA4B,CAAC,CAAAC,kBAACC,WAAA;GAChDL,MAAKG,SAAU,CAAC,CAAAG,eAAgBD,MAAM;EAAC,CACxC;EACAH,KAAA,CAACJ,eAAeE,KAAK;EAACP,EAAA,KAAAK;EAAAL,EAAA,KAAAO;EAAAP,EAAA,KAAAQ;EAAAR,EAAA,KAAAS;CAAA,OAAA;EAAAD,KAAAR,EAAA;EAAAS,KAAAT,EAAA;CAAA;CAJzBX,UAAUmB,IAIPC,EAAsB;CAAC,IAAAK;CAAA,IAAAC;CAAA,IAAAf,EAAA,OAAAK,iBAAAL,EAAA,OAAAO,OAAA;EAEhBO,WAAA;GACR,IAAI,CAACT,eAAa;GAAS,OACpBE,MAAKS,WAAWC,UAAA;IACrB,IAAIZ,cAAaK,SAAU,CAAC,CAAAQ,eAAgBD,MAAKC,YAC/CtB,cAAcS,aAAa,CAAC,CAAAc,SAAU,EAAAD,YAAcD,MAAKC,WAAY,CAAC;GACvE,CACF;EAAC;EACDH,KAAA,CAACR,OAAOF,aAAa;EAACL,EAAA,KAAAK;EAAAL,EAAA,KAAAO;EAAAP,EAAA,KAAAc;EAAAd,EAAA,MAAAe;CAAA,OAAA;EAAAD,KAAAd,EAAA;EAAAe,KAAAf,EAAA;CAAA;CAPzBX,UAAUyB,IAOPC,EAAsB;CAAC,OAEnBR;AAAK;AAGd,MAAaa,mCAETnB,OAAA;CAAA,MAAAD,IAAAd,EAAA,CAAA;CAAC,MAAA,EAAAmC,UAAAvB,SAAAQ,OAAAL;CAA0B,IAAAO;CAAA,IAAAR,EAAA,OAAAM,IAAA;EAAdE,KAAAF,OAAAgB,KAAAA,IAAA,CAAW,IAAXhB;EAAYN,EAAA,KAAAM;EAAAN,EAAA,KAAAQ;CAAA,OAAAA,KAAAR,EAAA;CAC3B,MAAAuB,oBAA0BxB,4BAA4BD,EAAO;CAAE,IAAAW;CAAA,IAAAT,EAAA,OAAAuB,mBAAA;EAERd,YAC9C,EAAAc,kBAEP;EACDvB,EAAA,KAAAuB;EAAAvB,EAAA,KAAAS;CAAA,OAAAA,KAAAT,EAAA;CAJD,MAAA,CAAAwB,WAAkBlC,SAAqCmB,EAItD;CAAE,IAAAK;CAAA,IAAAd,EAAA,OAAAqB,YAAArB,EAAA,OAAAwB,SAAA;EAGDV,KAAA,oBAAA,sBAAA,UAAA;GAAuCU,OAAAA;GACpCH;EACH,CAAA;EAAiCrB,EAAA,KAAAqB;EAAArB,EAAA,KAAAwB;EAAAxB,EAAA,KAAAc;CAAA,OAAAA,KAAAd,EAAA;CAAA,OAFjCc;AAEiC"}
1
+ {"version":3,"file":"ThreadViewportProvider.js","names":["c","_c","FC","PropsWithChildren","useEffect","useState","makeThreadViewportStore","ThreadViewportStoreOptions","ThreadViewportContext","ThreadViewportContextValue","useThreadViewportStore","writableStore","ThreadViewportProviderProps","options","useThreadViewportStoreValue","$","t0","Symbol","for","optional","outerViewport","t1","store","t2","t3","getState","onScrollToBottom","config","scrollToBottom","t4","t5","subscribe","state","isAtBottom","setState","ThreadPrimitiveViewportProvider","children","undefined","useThreadViewport","context","_c","options"],"sources":["../../../src/context/providers/ThreadViewportProvider.tsx"],"sourcesContent":["\"use client\";\n\nimport { type FC, type PropsWithChildren, useEffect, useState } from \"react\";\n\nimport {\n makeThreadViewportStore,\n type ThreadViewportStoreOptions,\n} from \"../stores/ThreadViewport\";\nimport {\n ThreadViewportContext,\n type ThreadViewportContextValue,\n useThreadViewportStore,\n} from \"../react/ThreadViewportContext\";\nimport { writableStore } from \"../ReadonlyStore\";\n\nexport type ThreadViewportProviderProps = PropsWithChildren<{\n options?: ThreadViewportStoreOptions;\n}>;\n\nconst useThreadViewportStoreValue = (options: ThreadViewportStoreOptions) => {\n const outerViewport = useThreadViewportStore({ optional: true });\n // Viewport options are initial configuration. Keeping them non-reactive avoids\n // fanout through every message in long threads when anchoring config changes.\n const [store] = useState(() => makeThreadViewportStore(options));\n\n // Forward scrollToBottom from outer viewport to inner viewport\n useEffect(() => {\n return outerViewport?.getState().onScrollToBottom((config) => {\n store.getState().scrollToBottom(config);\n });\n }, [outerViewport, store]);\n\n useEffect(() => {\n if (!outerViewport) return;\n return store.subscribe((state) => {\n if (outerViewport.getState().isAtBottom !== state.isAtBottom) {\n writableStore(outerViewport).setState({ isAtBottom: state.isAtBottom });\n }\n });\n }, [store, outerViewport]);\n\n return store;\n};\n\nexport const ThreadPrimitiveViewportProvider: FC<\n ThreadViewportProviderProps\n> = ({ children, options = {} }) => {\n const useThreadViewport = useThreadViewportStoreValue(options);\n\n const [context] = useState<ThreadViewportContextValue>(() => {\n return {\n useThreadViewport,\n };\n });\n\n return (\n <ThreadViewportContext.Provider value={context}>\n {children}\n </ThreadViewportContext.Provider>\n );\n};\n"],"mappings":";;;;;;;;AAmBA,MAAMc,+BAA8BD,YAAA;CAAA,MAAAE,IAAAd,EAAA,EAAA;CAAA,IAAAe;CAAA,IAAAD,EAAA,OAAAE,OAAAC,IAAA,2BAAA,GAAA;EACWF,KAAA,EAAAG,UAAY,KAAK;EAACJ,EAAA,KAAAC;CAAA,OAAAA,KAAAD,EAAA;CAA/D,MAAAK,gBAAsBV,uBAAuBM,EAAkB;CAAE,IAAAK;CAAA,IAAAN,EAAA,OAAAF,SAAA;EAGxCQ,WAAMf,wBAAwBO,OAAO;EAACE,EAAA,KAAAF;EAAAE,EAAA,KAAAM;CAAA,OAAAA,KAAAN,EAAA;CAA/D,MAAA,CAAAO,SAAgBjB,SAASgB,EAAsC;CAAE,IAAAE;CAAA,IAAAC;CAAA,IAAAT,EAAA,OAAAK,iBAAAL,EAAA,OAAAO,OAAA;EAGvDC,WACDH,eAAaK,SAA4B,CAAC,CAAAC,kBAACC,WAAA;GAChDL,MAAKG,SAAU,CAAC,CAAAG,eAAgBD,MAAM;EAAC,CACxC;EACAH,KAAA,CAACJ,eAAeE,KAAK;EAACP,EAAA,KAAAK;EAAAL,EAAA,KAAAO;EAAAP,EAAA,KAAAQ;EAAAR,EAAA,KAAAS;CAAA,OAAA;EAAAD,KAAAR,EAAA;EAAAS,KAAAT,EAAA;CAAA;CAJzBX,UAAUmB,IAIPC,EAAsB;CAAC,IAAAK;CAAA,IAAAC;CAAA,IAAAf,EAAA,OAAAK,iBAAAL,EAAA,OAAAO,OAAA;EAEhBO,WAAA;GACR,IAAI,CAACT,eAAa;GAAS,OACpBE,MAAKS,WAAWC,UAAA;IACrB,IAAIZ,cAAaK,SAAU,CAAC,CAAAQ,eAAgBD,MAAKC,YAC/CtB,cAAcS,aAAa,CAAC,CAAAc,SAAU,EAAAD,YAAcD,MAAKC,WAAY,CAAC;GACvE,CACF;EAAC;EACDH,KAAA,CAACR,OAAOF,aAAa;EAACL,EAAA,KAAAK;EAAAL,EAAA,KAAAO;EAAAP,EAAA,KAAAc;EAAAd,EAAA,MAAAe;CAAA,OAAA;EAAAD,KAAAd,EAAA;EAAAe,KAAAf,EAAA;CAAA;CAPzBX,UAAUyB,IAOPC,EAAsB;CAAC,OAEnBR;AAAK;AAGd,MAAaa,mCAETnB,OAAA;CAAA,MAAAD,IAAAd,EAAA,CAAA;CAAC,MAAA,EAAAmC,UAAAvB,SAAAQ,OAAAL;CAA0B,IAAAO;CAAA,IAAAR,EAAA,OAAAM,IAAA;EAAdE,KAAAF,OAAAgB,KAAAA,IAAA,CAAW,IAAXhB;EAAYN,EAAA,KAAAM;EAAAN,EAAA,KAAAQ;CAAA,OAAAA,KAAAR,EAAA;CAC3B,MAAAuB,oBAA0BxB,4BAA4BD,EAAO;CAAE,IAAAW;CAAA,IAAAT,EAAA,OAAAuB,mBAAA;EAERd,YAC9C,EAAAc,kBAEP;EACDvB,EAAA,KAAAuB;EAAAvB,EAAA,KAAAS;CAAA,OAAAA,KAAAT,EAAA;CAJD,MAAA,CAAAwB,WAAkBlC,SAAqCmB,EAItD;CAAE,IAAAK;CAAA,IAAAd,EAAA,OAAAqB,YAAArB,EAAA,OAAAwB,SAAA;EAGDV,KAAA,oBAAA,sBAAA,UAAA;GAAuCU,OAAAA;GACpCH;EACH,CAAA;EAAiCrB,EAAA,KAAAqB;EAAArB,EAAA,KAAAwB;EAAAxB,EAAA,KAAAc;CAAA,OAAAA,KAAAd,EAAA;CAAA,OAFjCc;AAEiC"}
@@ -1 +1 @@
1
- {"version":3,"file":"useToolCallElapsed.js","names":["c","_c","useEffect","useState","useAuiState","useToolCallElapsed","$","timing","_temp","partRunning","_temp2","running","undefined","completedAt","now","setNow","_temp3","t0","t1","Date","id","setInterval","clearInterval","Math","max","startedAt","s","part","optional","type","s_0","part_0","status"],"sources":["../../src/hooks/useToolCallElapsed.ts"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport { useAuiState } from \"@assistant-ui/store\";\n\n/**\n * Hook that returns the elapsed wall-clock time of the current tool call in\n * milliseconds, ticking once per second while the call runs.\n *\n * Reads `part.timing`. Returns `undefined` when the part is not a tool call,\n * carries no timing, ended without a recorded completion (the duration is\n * unknown), or when no message part scope is available (so kit components\n * stay renderable standalone, e.g. in docs previews).\n *\n * @example\n * ```tsx\n * function ToolDuration() {\n * const elapsedMs = useToolCallElapsed();\n * if (elapsedMs === undefined) return null;\n * return <span>{(elapsedMs / 1000).toFixed(1)}s</span>;\n * }\n * ```\n */\nexport const useToolCallElapsed = (): number | undefined => {\n const timing = useAuiState((s) => {\n const part = s.optional.part;\n return part?.type === \"tool-call\" ? part.timing : undefined;\n });\n const partRunning = useAuiState((s) => {\n const part = s.optional.part;\n return part?.type === \"tool-call\" && part.status.type === \"running\";\n });\n const running =\n timing !== undefined && timing.completedAt === undefined && partRunning;\n const [now, setNow] = useState(() => Date.now());\n\n useEffect(() => {\n if (!running) return undefined;\n // The clock is an external source; this catches the elapsed value up before\n // the interval takes over.\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setNow(Date.now());\n const id = setInterval(() => setNow(Date.now()), 1000);\n return () => clearInterval(id);\n }, [running]);\n\n if (timing === undefined) return undefined;\n if (timing.completedAt !== undefined)\n return Math.max(0, timing.completedAt - timing.startedAt);\n if (!running) return undefined;\n return Math.max(0, now - timing.startedAt);\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAuBA,MAAaK,2BAAqB;CAAA,MAAAC,IAAAL,EAAA,CAAA;CAChC,MAAAM,SAAeH,YAAYI,KAG1B;CACD,MAAAC,cAAoBL,YAAYM,MAG/B;CACD,MAAAC,UACEJ,WAAWK,KAAAA,KAAaL,OAAMM,gBAAiBD,KAAAA,KAA/CH;CACF,MAAA,CAAAK,KAAAC,UAAsBZ,SAASa,MAAgB;CAAE,IAAAC;CAAA,IAAAC;CAAA,IAAAZ,EAAA,OAAAK,SAAA;EAEvCM,WAAA;GACR,IAAI,CAACN,SAAO;GAIZI,OAAOI,KAAIL,IAAK,CAAC;GACjB,MAAAM,KAAWC,kBAAkBN,OAAOI,KAAIL,IAAK,CAAC,GAAG,GAAI;GAAE,aAC1CQ,cAAcF,EAAE;EAAC;EAC7BF,KAAA,CAACP,OAAO;EAACL,EAAA,KAAAK;EAAAL,EAAA,KAAAW;EAAAX,EAAA,KAAAY;CAAA,OAAA;EAAAD,KAAAX,EAAA;EAAAY,KAAAZ,EAAA;CAAA;CARZJ,UAAUe,IAQPC,EAAS;CAEZ,IAAIX,WAAWK,KAAAA,GAAS;CACxB,IAAIL,OAAMM,gBAAiBD,KAAAA,GAAS,OAC3BW,KAAIC,IAAK,GAAGjB,OAAMM,cAAeN,OAAMkB,SAAU;CAC1D,IAAI,CAACd,SAAO;CAAmB,OACxBY,KAAIC,IAAK,GAAGV,MAAMP,OAAMkB,SAAU;AAAC;AA3BV,SAAAjB,MAAAkB,GAAA;CAE9B,MAAAC,OAAaD,EAACE,SAASD;CAAM,OACtBA,MAAIE,SAAW,cAAcF,KAAIpB,SAAjCK,KAAAA;AAAoD;AAH7B,SAAAF,OAAAoB,KAAA;CAM9B,MAAAC,SAAaL,IAACE,SAASD;CAAM,OACtBA,QAAIE,SAAW,eAAeF,OAAIK,OAAOH,SAAU;AAAS;AAPrC,SAAAb,SAAA;CAAA,OAWKG,KAAIL,IAAK;AAAC"}
1
+ {"version":3,"file":"useToolCallElapsed.js","names":["c","_c","useEffect","useState","useAuiState","useToolCallElapsed","$","timing","_temp","partRunning","_temp2","running","undefined","completedAt","now","setNow","_temp3","t0","t1","Date","id","setInterval","clearInterval","Math","max","startedAt","s","part","optional","type","s_0","part_0","status","_c"],"sources":["../../src/hooks/useToolCallElapsed.ts"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport { useAuiState } from \"@assistant-ui/store\";\n\n/**\n * Hook that returns the elapsed wall-clock time of the current tool call in\n * milliseconds, ticking once per second while the call runs.\n *\n * Reads `part.timing`. Returns `undefined` when the part is not a tool call,\n * carries no timing, ended without a recorded completion (the duration is\n * unknown), or when no message part scope is available (so kit components\n * stay renderable standalone, e.g. in docs previews).\n *\n * @example\n * ```tsx\n * function ToolDuration() {\n * const elapsedMs = useToolCallElapsed();\n * if (elapsedMs === undefined) return null;\n * return <span>{(elapsedMs / 1000).toFixed(1)}s</span>;\n * }\n * ```\n */\nexport const useToolCallElapsed = (): number | undefined => {\n const timing = useAuiState((s) => {\n const part = s.optional.part;\n return part?.type === \"tool-call\" ? part.timing : undefined;\n });\n const partRunning = useAuiState((s) => {\n const part = s.optional.part;\n return part?.type === \"tool-call\" && part.status.type === \"running\";\n });\n const running =\n timing !== undefined && timing.completedAt === undefined && partRunning;\n const [now, setNow] = useState(() => Date.now());\n\n useEffect(() => {\n if (!running) return undefined;\n // The clock is an external source; this catches the elapsed value up before\n // the interval takes over.\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setNow(Date.now());\n const id = setInterval(() => setNow(Date.now()), 1000);\n return () => clearInterval(id);\n }, [running]);\n\n if (timing === undefined) return undefined;\n if (timing.completedAt !== undefined)\n return Math.max(0, timing.completedAt - timing.startedAt);\n if (!running) return undefined;\n return Math.max(0, now - timing.startedAt);\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAuBA,MAAaK,2BAAqB;CAAA,MAAAC,IAAAL,EAAA,CAAA;CAChC,MAAAM,SAAeH,YAAYI,KAG1B;CACD,MAAAC,cAAoBL,YAAYM,MAG/B;CACD,MAAAC,UACEJ,WAAWK,KAAAA,KAAaL,OAAMM,gBAAiBD,KAAAA,KAA/CH;CACF,MAAA,CAAAK,KAAAC,UAAsBZ,SAASa,MAAgB;CAAE,IAAAC;CAAA,IAAAC;CAAA,IAAAZ,EAAA,OAAAK,SAAA;EAEvCM,WAAA;GACR,IAAI,CAACN,SAAO;GAIZI,OAAOI,KAAIL,IAAK,CAAC;GACjB,MAAAM,KAAWC,kBAAkBN,OAAOI,KAAIL,IAAK,CAAC,GAAG,GAAI;GAAE,aAC1CQ,cAAcF,EAAE;EAAC;EAC7BF,KAAA,CAACP,OAAO;EAACL,EAAA,KAAAK;EAAAL,EAAA,KAAAW;EAAAX,EAAA,KAAAY;CAAA,OAAA;EAAAD,KAAAX,EAAA;EAAAY,KAAAZ,EAAA;CAAA;CARZJ,UAAUe,IAQPC,EAAS;CAEZ,IAAIX,WAAWK,KAAAA,GAAS;CACxB,IAAIL,OAAMM,gBAAiBD,KAAAA,GAAS,OAC3BW,KAAIC,IAAK,GAAGjB,OAAMM,cAAeN,OAAMkB,SAAU;CAC1D,IAAI,CAACd,SAAO;CAAmB,OACxBY,KAAIC,IAAK,GAAGV,MAAMP,OAAMkB,SAAU;AAAC;AA3BV,SAAAjB,MAAAkB,GAAA;CAE9B,MAAAC,OAAaD,EAACE,SAASD;CAAM,OACtBA,MAAIE,SAAW,cAAcF,KAAIpB,SAAjCK,KAAAA;AAAoD;AAH7B,SAAAF,OAAAoB,KAAA;CAM9B,MAAAC,SAAaL,IAACE,SAASD;CAAM,OACtBA,QAAIE,SAAW,eAAeF,OAAIK,OAAOH,SAAU;AAAS;AAPrC,SAAAb,SAAA;CAAA,OAWKG,KAAIL,IAAK;AAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantRuntimeProvider.js","names":["c","_c","FC","memo","PropsWithChildren","useEffect","AssistantClient","AuiConfig","useAui","AssistantRuntime","AssistantProviderBase","ThreadPrimitiveViewportProvider","DevToolsProviderApi","AssistantRuntimeProvider","Props","runtime","aui","config","DevToolsRegistration","$","t0","t1","process","env","NODE_ENV","register","AssistantRuntimeProviderImpl","children","t2","Symbol","for","t3","t4"],"sources":["../../src/legacy-runtime/AssistantRuntimeProvider.tsx"],"sourcesContent":["\"use client\";\n\nimport { type FC, memo, type PropsWithChildren, useEffect } from \"react\";\nimport {\n type AssistantClient,\n type AuiConfig,\n useAui,\n} from \"@assistant-ui/store\";\nimport type { AssistantRuntime } from \"./runtime/AssistantRuntime\";\nimport { AssistantProviderBase } from \"@assistant-ui/core/react\";\nimport { ThreadPrimitiveViewportProvider } from \"../context/providers/ThreadViewportProvider\";\nimport { DevToolsProviderApi } from \"../devtools/DevToolsHooks\";\n\nexport namespace AssistantRuntimeProvider {\n export type Props = PropsWithChildren<{\n /**\n * The assistant runtime to expose to descendants. Build one with\n * `useLocalRuntime`, `useExternalStoreRuntime`, or\n * `useAssistantTransportRuntime`.\n */\n runtime: AssistantRuntime;\n\n /**\n * Optional parent `AssistantClient` whose scopes are inherited by the\n * client created for this runtime. Use this when nesting an\n * `AssistantRuntimeProvider` inside another assistant context. Omit this\n * prop when there is no parent client.\n * @defaultValue undefined\n */\n aui?: AssistantClient;\n\n /**\n * Optional extra scopes provided alongside the runtime's `threads`\n * scope; build with `AuiConfig`.\n */\n config?: AuiConfig;\n }>;\n}\n\nconst DevToolsRegistration: FC = () => {\n const aui = useAui();\n useEffect(() => {\n if (typeof process === \"undefined\" || process.env.NODE_ENV === \"production\")\n return;\n return DevToolsProviderApi.register(aui);\n }, [aui]);\n return null;\n};\n\nexport const AssistantRuntimeProviderImpl: FC<\n AssistantRuntimeProvider.Props\n> = ({ children, aui, config, runtime }) => {\n return (\n <AssistantProviderBase runtime={runtime} aui={aui ?? null} config={config}>\n <DevToolsRegistration />\n {/* TODO temporarily allow accessing viewport state from outside the viewport */}\n {/* TODO figure out if this behavior should be deprecated, since it is quite hacky */}\n <ThreadPrimitiveViewportProvider>\n {children}\n </ThreadPrimitiveViewportProvider>\n </AssistantProviderBase>\n );\n};\n\nexport const AssistantRuntimeProvider = memo(AssistantRuntimeProviderImpl);\n"],"mappings":";;;;;;;;;AAuCA,MAAMkB,6BAA2B;CAAA,MAAAC,IAAAlB,EAAA,CAAA;CAC/B,MAAAe,MAAYR,OAAO;CAAE,IAAAY;CAAA,IAAAC;CAAA,IAAAF,EAAA,OAAAH,KAAA;EACXI,WAAA;GACR,IAAI,OAAOE,YAAY,eAAeA,QAAOC,IAAIC,aAAc,cAAY;GAClE,OACFZ,oBAAmBa,SAAUT,GAAG;EAAC;EACvCK,KAAA,CAACL,GAAG;EAACG,EAAA,KAAAH;EAAAG,EAAA,KAAAC;EAAAD,EAAA,KAAAE;CAAA,OAAA;EAAAD,KAAAD,EAAA;EAAAE,KAAAF,EAAA;CAAA;CAJRd,UAAUe,IAIPC,EAAK;CAAC,OACF;AAAI;AAGb,MAAaK,gCAETN,OAAA;CAAA,MAAAD,IAAAlB,EAAA,CAAA;CAAC,MAAA,EAAA0B,UAAAX,KAAAC,QAAAF,YAAAK;CAE6C,MAAAC,KAAAL,OAAA;CAAW,IAAAY;CAAA,IAAAT,EAAA,OAAAU,OAAAC,IAAA,2BAAA,GAAA;EACvDF,KAAA,oBAAC,sBAAD,CAAqB,CAAA;EAAGT,EAAA,KAAAS;CAAA,OAAAA,KAAAT,EAAA;CAAA,IAAAY;CAAA,IAAAZ,EAAA,OAAAQ,UAAA;EAGxBI,KAAA,oBAAC,iCAAD,EACGJ,SAD6B,CAAA;EAEER,EAAA,KAAAQ;EAAAR,EAAA,KAAAY;CAAA,OAAAA,KAAAZ,EAAA;CAAA,IAAAa;CAAA,IAAAb,EAAA,OAAAF,UAAAE,EAAA,OAAAJ,WAAAI,EAAA,OAAAE,MAAAF,EAAA,OAAAY,IAAA;EANpCC,KAAA,qBAAC,uBAAD;GAAgCjB;GAAc,KAAAM;GAAqBJ;GAAnE,UAAA,CACEW,IAGAG,EAJoB;;EAOEZ,EAAA,KAAAF;EAAAE,EAAA,KAAAJ;EAAAI,EAAA,KAAAE;EAAAF,EAAA,KAAAY;EAAAZ,EAAA,KAAAa;CAAA,OAAAA,KAAAb,EAAA;CAAA,OAPxBa;AAOwB;AAI5B,MAAanB,2BAA2BV,KAAKuB,4BAA4B"}
1
+ {"version":3,"file":"AssistantRuntimeProvider.js","names":["c","_c","FC","memo","PropsWithChildren","useEffect","AssistantClient","AuiConfig","useAui","AssistantRuntime","AssistantProviderBase","ThreadPrimitiveViewportProvider","DevToolsProviderApi","AssistantRuntimeProvider","Props","runtime","aui","config","DevToolsRegistration","$","t0","t1","process","env","NODE_ENV","register","AssistantRuntimeProviderImpl","children","t2","Symbol","for","t3","t4","_c"],"sources":["../../src/legacy-runtime/AssistantRuntimeProvider.tsx"],"sourcesContent":["\"use client\";\n\nimport { type FC, memo, type PropsWithChildren, useEffect } from \"react\";\nimport {\n type AssistantClient,\n type AuiConfig,\n useAui,\n} from \"@assistant-ui/store\";\nimport type { AssistantRuntime } from \"./runtime/AssistantRuntime\";\nimport { AssistantProviderBase } from \"@assistant-ui/core/react\";\nimport { ThreadPrimitiveViewportProvider } from \"../context/providers/ThreadViewportProvider\";\nimport { DevToolsProviderApi } from \"../devtools/DevToolsHooks\";\n\nexport namespace AssistantRuntimeProvider {\n export type Props = PropsWithChildren<{\n /**\n * The assistant runtime to expose to descendants. Build one with\n * `useLocalRuntime`, `useExternalStoreRuntime`, or\n * `useAssistantTransportRuntime`.\n */\n runtime: AssistantRuntime;\n\n /**\n * Optional parent `AssistantClient` whose scopes are inherited by the\n * client created for this runtime. Use this when nesting an\n * `AssistantRuntimeProvider` inside another assistant context. Omit this\n * prop when there is no parent client.\n * @defaultValue undefined\n */\n aui?: AssistantClient;\n\n /**\n * Optional extra scopes provided alongside the runtime's `threads`\n * scope; build with `AuiConfig`.\n */\n config?: AuiConfig;\n }>;\n}\n\nconst DevToolsRegistration: FC = () => {\n const aui = useAui();\n useEffect(() => {\n if (typeof process === \"undefined\" || process.env.NODE_ENV === \"production\")\n return;\n return DevToolsProviderApi.register(aui);\n }, [aui]);\n return null;\n};\n\nexport const AssistantRuntimeProviderImpl: FC<\n AssistantRuntimeProvider.Props\n> = ({ children, aui, config, runtime }) => {\n return (\n <AssistantProviderBase runtime={runtime} aui={aui ?? null} config={config}>\n <DevToolsRegistration />\n {/* TODO temporarily allow accessing viewport state from outside the viewport */}\n {/* TODO figure out if this behavior should be deprecated, since it is quite hacky */}\n <ThreadPrimitiveViewportProvider>\n {children}\n </ThreadPrimitiveViewportProvider>\n </AssistantProviderBase>\n );\n};\n\nexport const AssistantRuntimeProvider = memo(AssistantRuntimeProviderImpl);\n"],"mappings":";;;;;;;;;AAuCA,MAAMkB,6BAA2B;CAAA,MAAAC,IAAAlB,EAAA,CAAA;CAC/B,MAAAe,MAAYR,OAAO;CAAE,IAAAY;CAAA,IAAAC;CAAA,IAAAF,EAAA,OAAAH,KAAA;EACXI,WAAA;GACR,IAAI,OAAOE,YAAY,eAAeA,QAAOC,IAAIC,aAAc,cAAY;GAClE,OACFZ,oBAAmBa,SAAUT,GAAG;EAAC;EACvCK,KAAA,CAACL,GAAG;EAACG,EAAA,KAAAH;EAAAG,EAAA,KAAAC;EAAAD,EAAA,KAAAE;CAAA,OAAA;EAAAD,KAAAD,EAAA;EAAAE,KAAAF,EAAA;CAAA;CAJRd,UAAUe,IAIPC,EAAK;CAAC,OACF;AAAI;AAGb,MAAaK,gCAETN,OAAA;CAAA,MAAAD,IAAAlB,EAAA,CAAA;CAAC,MAAA,EAAA0B,UAAAX,KAAAC,QAAAF,YAAAK;CAE6C,MAAAC,KAAAL,OAAA;CAAW,IAAAY;CAAA,IAAAT,EAAA,OAAAU,OAAAC,IAAA,2BAAA,GAAA;EACvDF,KAAA,oBAAC,sBAAD,CAAqB,CAAA;EAAGT,EAAA,KAAAS;CAAA,OAAAA,KAAAT,EAAA;CAAA,IAAAY;CAAA,IAAAZ,EAAA,OAAAQ,UAAA;EAGxBI,KAAA,oBAAC,iCAAD,EACGJ,SAD6B,CAAA;EAEER,EAAA,KAAAQ;EAAAR,EAAA,KAAAY;CAAA,OAAAA,KAAAZ,EAAA;CAAA,IAAAa;CAAA,IAAAb,EAAA,OAAAF,UAAAE,EAAA,OAAAJ,WAAAI,EAAA,OAAAE,MAAAF,EAAA,OAAAY,IAAA;EANpCC,KAAA,qBAAC,uBAAD;GAAgCjB;GAAc,KAAAM;GAAqBJ;GAAnE,UAAA,CACEW,IAGAG,EAJoB;;EAOEZ,EAAA,KAAAF;EAAAE,EAAA,KAAAJ;EAAAI,EAAA,KAAAE;EAAAF,EAAA,KAAAY;EAAAZ,EAAA,KAAAa;CAAA,OAAAA,KAAAb,EAAA;CAAA,OAPxBa;AAOwB;AAI5B,MAAanB,2BAA2BV,KAAKuB,4BAA4B"}
@@ -1 +1 @@
1
- {"version":3,"file":"app-frame.js","names":["c","_c","MutableRefObject","useEffect","useLayoutEffect","useRef","McpAppBridge","createMcpAppBridge","SandboxHost","SandboxBridge","SandboxHostApi","SandboxHostFrame","McpAppBridgeHandlers","McpAppFrameProps","McpAppHostContext","isRecord","DEFAULT_PRODUCT","INIT_TIMEOUT_MS","DEFAULT_MAX_HEIGHT","isPlainObject","value","Record","prototype","Object","getPrototypeOf","isSameHostContext","a","b","depth","is","Array","isArray","length","i","aKeys","keys","every","key","hasOwn","useBridgeNotify","bridgeRef","widgetReadyRef","pendingRef","lastSentRef","notify","t0","$","isEqual","undefined","t1","current","t2","LiveSnapshot","handlers","hostInfo","hostContext","input","output","FrameLifecycle","onInitialized","onSizeChange","params","width","height","buildLiveHandlers","initial","liveRef","lifecycle","live","has","K","out","defineProperty","get","allowedTools","enumerable","configurable","liveCall","NonNullable","p","fn","Error","callTool","readResource","listResources","openLink","sendMessage","updateModelContext","requestDisplayMode","onRequestTeardown","onLog","onError","e","McpAppFrame","app","resource","sandbox","maxHeight","lastSentInputRef","lastSentOutputRef","lastSentHostContextRef","pendingInputRef","pendingOutputRef","pendingHostContextRef","t3","t4","t5","Symbol","for","frame","host","initTimeoutId","flushPending","notifyToolInput","notifyToolResult","notifyHostContextChanged","wrappedHandlers","clearTimeout","setHeight","setTimeout","bridge","onMessage","dispose","createBridge","_temp","_temp2","_temp3","t6","html","t7","serverId","uri","t8","product","t9","t10","err","t11","meta","prefersBorder","t12","resourceUri","t13","b_2","v_1","v","b_1","v_0","b_0"],"sources":["../../src/mcp-apps/app-frame.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n type MutableRefObject,\n useEffect,\n useLayoutEffect,\n useRef,\n} from \"react\";\nimport { type McpAppBridge, createMcpAppBridge } from \"./bridge\";\nimport {\n SandboxHost,\n type SandboxBridge,\n type SandboxHostApi,\n type SandboxHostFrame,\n} from \"../sandbox-host/SandboxHost\";\nimport type {\n McpAppBridgeHandlers,\n McpAppFrameProps,\n McpAppHostContext,\n} from \"./types\";\nimport { isRecord } from \"@assistant-ui/core/internal\";\n\nconst DEFAULT_PRODUCT = \"assistant-ui-mcp-app\";\nconst INIT_TIMEOUT_MS = 5000;\nconst DEFAULT_MAX_HEIGHT = 800;\n\n// Only a plain object can be compared by its own keys. Structured clone carries\n// a Date, Map, or class instance to the widget intact, and those expose no\n// enumerable keys, so walking them would report two different values as equal.\nconst isPlainObject = (value: unknown): value is Record<string, unknown> => {\n if (!isRecord(value)) return false;\n const prototype = Object.getPrototypeOf(value);\n return prototype === null || prototype === Object.prototype;\n};\n\n// Hosts commonly rebuild an equal context object on every render, and the\n// widget cannot tell a repeated notification apart from a real change. The\n// open index signature on McpAppHostContext admits values JSON rejects (an\n// undefined property value is enough), so leaves the walk cannot compare fall\n// back to identity rather than failing the whole comparison.\nconst isSameHostContext = (a: unknown, b: unknown, depth = 0): boolean => {\n if (Object.is(a, b)) return true;\n if (depth > 100) return false;\n if (Array.isArray(a) || Array.isArray(b)) {\n if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length)\n return false;\n for (let i = 0; i < a.length; i++) {\n if (!isSameHostContext(a[i], b[i], depth + 1)) return false;\n }\n return true;\n }\n if (!isPlainObject(a) || !isPlainObject(b)) return false;\n const aKeys = Object.keys(a);\n return (\n aKeys.length === Object.keys(b).length &&\n aKeys.every(\n (key) =>\n Object.hasOwn(b, key) && isSameHostContext(a[key], b[key], depth + 1),\n )\n );\n};\n\nfunction useBridgeNotify<T>(\n value: T | undefined,\n bridgeRef: MutableRefObject<McpAppBridge | null>,\n widgetReadyRef: MutableRefObject<boolean>,\n pendingRef: MutableRefObject<T | undefined>,\n lastSentRef: MutableRefObject<T | undefined>,\n notify: (bridge: McpAppBridge, v: T) => void,\n isEqual: (sent: T | undefined, next: T) => boolean = Object.is,\n) {\n useEffect(() => {\n if (!bridgeRef.current) return;\n // Nothing to deliver, either because there is no value or because the\n // widget already holds it; a queued value here is superseded and would\n // otherwise flush after initialization as a stale update.\n if (value === undefined || isEqual(lastSentRef.current, value)) {\n pendingRef.current = undefined;\n return;\n }\n if (!widgetReadyRef.current) {\n pendingRef.current = value;\n return;\n }\n notify(bridgeRef.current, value);\n lastSentRef.current = value;\n // oxlint-disable-next-line react/exhaustive-deps -- refs are stable; notify and isEqual are assumed stable; re-run only when value changes\n }, [value]);\n}\n\ntype LiveSnapshot = {\n handlers: McpAppBridgeHandlers | undefined;\n hostInfo: McpAppFrameProps[\"hostInfo\"];\n hostContext: McpAppFrameProps[\"hostContext\"];\n input: unknown;\n output: unknown;\n};\n\ntype FrameLifecycle = {\n onInitialized: () => void;\n onSizeChange: (params: { width?: number; height?: number }) => void;\n};\n\n// Proxy each per-call handler through liveRef so the bridge always dispatches\n// to the latest handler reference (e.g. inline callbacks closing over state).\n// Capability presence is snapshot at mount: a handler added later requires a\n// remount (keyed on resource URI) to expose the capability to the widget.\n// allowedTools is the exception: it is never advertised in the ui/initialize\n// response, so it stays a live getter, which means this object must reach the\n// bridge uncopied and the frame passes its lifecycle work in rather than\n// wrapping the result.\nfunction buildLiveHandlers(\n initial: McpAppBridgeHandlers | undefined,\n liveRef: { readonly current: LiveSnapshot },\n lifecycle: FrameLifecycle,\n): McpAppBridgeHandlers {\n const live = () => liveRef.current.handlers;\n const has = <K extends keyof McpAppBridgeHandlers>(key: K) =>\n initial?.[key] !== undefined;\n const out: McpAppBridgeHandlers = {};\n Object.defineProperty(out, \"allowedTools\", {\n get: () => live()?.allowedTools,\n enumerable: true,\n configurable: true,\n });\n const liveCall = <K extends keyof McpAppBridgeHandlers>(\n key: K,\n ): NonNullable<McpAppBridgeHandlers[K]> =>\n ((p: unknown) => {\n const fn = live()?.[key] as ((p: unknown) => unknown) | undefined;\n if (!fn) {\n throw new Error(`${key} handler is no longer available`);\n }\n return fn(p);\n }) as NonNullable<McpAppBridgeHandlers[K]>;\n if (has(\"callTool\")) out.callTool = liveCall(\"callTool\");\n if (has(\"readResource\")) out.readResource = liveCall(\"readResource\");\n if (has(\"listResources\")) out.listResources = liveCall(\"listResources\");\n if (has(\"openLink\")) out.openLink = liveCall(\"openLink\");\n if (has(\"sendMessage\")) out.sendMessage = liveCall(\"sendMessage\");\n if (has(\"updateModelContext\"))\n out.updateModelContext = liveCall(\"updateModelContext\");\n if (has(\"requestDisplayMode\"))\n out.requestDisplayMode = liveCall(\"requestDisplayMode\");\n out.onSizeChange = (p) => {\n lifecycle.onSizeChange(p);\n live()?.onSizeChange?.(p);\n };\n out.onInitialized = () => {\n lifecycle.onInitialized();\n live()?.onInitialized?.();\n };\n out.onRequestTeardown = (p) => live()?.onRequestTeardown?.(p);\n out.onLog = (p) => live()?.onLog?.(p);\n out.onError = (e) => live()?.onError?.(e);\n return out;\n}\n\nexport function McpAppFrame({\n app,\n resource,\n input,\n output,\n sandbox,\n handlers,\n hostInfo,\n hostContext,\n maxHeight = DEFAULT_MAX_HEIGHT,\n}: McpAppFrameProps) {\n const bridgeRef = useRef<McpAppBridge | null>(null);\n const lastSentInputRef = useRef<unknown>(undefined);\n const lastSentOutputRef = useRef<unknown>(undefined);\n const lastSentHostContextRef = useRef<McpAppHostContext | undefined>(\n undefined,\n );\n // Per MCP Apps spec, the host should defer notifications until the widget\n // signals readiness via `notifications/initialized`. Until then, we record\n // pending values and flush them on init.\n const widgetReadyRef = useRef(false);\n const pendingInputRef = useRef<unknown>(undefined);\n const pendingOutputRef = useRef<unknown>(undefined);\n const pendingHostContextRef = useRef<McpAppHostContext | undefined>(\n undefined,\n );\n\n const liveRef = useRef<LiveSnapshot>({\n handlers,\n hostInfo,\n hostContext,\n input,\n output,\n });\n useLayoutEffect(() => {\n liveRef.current = {\n handlers,\n hostInfo,\n hostContext,\n input,\n output,\n };\n }, [handlers, hostInfo, hostContext, input, output]);\n\n const createBridge = (\n frame: SandboxHostFrame,\n host: SandboxHostApi,\n ): SandboxBridge => {\n const current = liveRef.current;\n let initTimeoutId: ReturnType<typeof setTimeout> | null = null;\n\n const flushPending = () => {\n if (widgetReadyRef.current) return;\n widgetReadyRef.current = true;\n const b = bridgeRef.current;\n if (!b) return;\n if (pendingInputRef.current !== undefined) {\n b.notifyToolInput(pendingInputRef.current);\n lastSentInputRef.current = pendingInputRef.current;\n pendingInputRef.current = undefined;\n }\n if (pendingOutputRef.current !== undefined) {\n b.notifyToolResult(pendingOutputRef.current);\n lastSentOutputRef.current = pendingOutputRef.current;\n pendingOutputRef.current = undefined;\n }\n if (pendingHostContextRef.current !== undefined) {\n b.notifyHostContextChanged(pendingHostContextRef.current);\n lastSentHostContextRef.current = pendingHostContextRef.current;\n pendingHostContextRef.current = undefined;\n }\n };\n\n const wrappedHandlers = buildLiveHandlers(current.handlers, liveRef, {\n onInitialized: () => {\n if (initTimeoutId !== null) {\n clearTimeout(initTimeoutId);\n initTimeoutId = null;\n }\n flushPending();\n },\n onSizeChange: (p) => {\n if (p.height != null) host.setHeight(p.height);\n },\n });\n\n // Safety net: if the widget never sends notifications/initialized (broken\n // or non-spec-compliant), flush the queue anyway so the host doesn't\n // appear hung.\n initTimeoutId = setTimeout(() => {\n initTimeoutId = null;\n flushPending();\n }, INIT_TIMEOUT_MS);\n\n const bridge = createMcpAppBridge({\n frame,\n handlers: wrappedHandlers,\n hostInfo: current.hostInfo,\n hostContext: current.hostContext,\n });\n bridgeRef.current = bridge;\n\n if (current.input !== undefined) pendingInputRef.current = current.input;\n if (current.output !== undefined) pendingOutputRef.current = current.output;\n // hostContext is delivered inside the ui/initialize response, where the\n // bridge defaults it to {}; recording that same normalized value keeps the\n // first later change from repeating what the widget already holds.\n lastSentHostContextRef.current = current.hostContext ?? {};\n\n return {\n onMessage: bridge.onMessage,\n dispose: () => {\n if (initTimeoutId !== null) {\n clearTimeout(initTimeoutId);\n initTimeoutId = null;\n }\n bridge.dispose();\n bridgeRef.current = null;\n lastSentInputRef.current = undefined;\n lastSentOutputRef.current = undefined;\n lastSentHostContextRef.current = undefined;\n widgetReadyRef.current = false;\n pendingInputRef.current = undefined;\n pendingOutputRef.current = undefined;\n pendingHostContextRef.current = undefined;\n },\n };\n };\n\n useBridgeNotify(\n input,\n bridgeRef,\n widgetReadyRef,\n pendingInputRef,\n lastSentInputRef,\n (b, v) => b.notifyToolInput(v),\n );\n useBridgeNotify(\n output,\n bridgeRef,\n widgetReadyRef,\n pendingOutputRef,\n lastSentOutputRef,\n (b, v) => b.notifyToolResult(v),\n );\n useBridgeNotify(\n hostContext,\n bridgeRef,\n widgetReadyRef,\n pendingHostContextRef,\n lastSentHostContextRef,\n (b, v) => b.notifyHostContextChanged(v),\n isSameHostContext,\n );\n\n return (\n <SandboxHost\n content={{ html: resource.html }}\n contentKey={\n app.serverId ? `${app.serverId} ${resource.uri}` : resource.uri\n }\n sandbox={{ ...sandbox, product: sandbox?.product ?? DEFAULT_PRODUCT }}\n maxHeight={maxHeight}\n createBridge={createBridge}\n onError={(err) => liveRef.current.handlers?.onError?.(err)}\n containerProps={{\n \"data-mcp-app-resource\": app.resourceUri,\n \"data-mcp-app-prefers-border\": resource.meta?.prefersBorder\n ? \"\"\n : undefined,\n }}\n />\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"app-frame.js","names":["c","_c","MutableRefObject","useEffect","useLayoutEffect","useRef","McpAppBridge","createMcpAppBridge","SandboxHost","SandboxBridge","SandboxHostApi","SandboxHostFrame","McpAppBridgeHandlers","McpAppFrameProps","McpAppHostContext","isRecord","DEFAULT_PRODUCT","INIT_TIMEOUT_MS","DEFAULT_MAX_HEIGHT","isPlainObject","value","Record","prototype","Object","getPrototypeOf","isSameHostContext","a","b","depth","is","Array","isArray","length","i","aKeys","keys","every","key","hasOwn","useBridgeNotify","bridgeRef","widgetReadyRef","pendingRef","lastSentRef","notify","t0","$","isEqual","undefined","t1","current","t2","LiveSnapshot","handlers","hostInfo","hostContext","input","output","FrameLifecycle","onInitialized","onSizeChange","params","width","height","buildLiveHandlers","initial","liveRef","lifecycle","live","has","K","out","defineProperty","get","allowedTools","enumerable","configurable","liveCall","NonNullable","p","fn","Error","callTool","readResource","listResources","openLink","sendMessage","updateModelContext","requestDisplayMode","onRequestTeardown","onLog","onError","e","McpAppFrame","app","resource","sandbox","maxHeight","lastSentInputRef","lastSentOutputRef","lastSentHostContextRef","pendingInputRef","pendingOutputRef","pendingHostContextRef","t3","t4","t5","Symbol","for","frame","host","initTimeoutId","flushPending","notifyToolInput","notifyToolResult","notifyHostContextChanged","wrappedHandlers","clearTimeout","setHeight","setTimeout","bridge","onMessage","dispose","createBridge","_temp","_temp2","_temp3","t6","html","t7","serverId","uri","t8","product","t9","t10","err","t11","meta","prefersBorder","t12","resourceUri","t13","b_2","v_1","v","b_1","v_0","b_0","_c"],"sources":["../../src/mcp-apps/app-frame.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n type MutableRefObject,\n useEffect,\n useLayoutEffect,\n useRef,\n} from \"react\";\nimport { type McpAppBridge, createMcpAppBridge } from \"./bridge\";\nimport {\n SandboxHost,\n type SandboxBridge,\n type SandboxHostApi,\n type SandboxHostFrame,\n} from \"../sandbox-host/SandboxHost\";\nimport type {\n McpAppBridgeHandlers,\n McpAppFrameProps,\n McpAppHostContext,\n} from \"./types\";\nimport { isRecord } from \"@assistant-ui/core/internal\";\n\nconst DEFAULT_PRODUCT = \"assistant-ui-mcp-app\";\nconst INIT_TIMEOUT_MS = 5000;\nconst DEFAULT_MAX_HEIGHT = 800;\n\n// Only a plain object can be compared by its own keys. Structured clone carries\n// a Date, Map, or class instance to the widget intact, and those expose no\n// enumerable keys, so walking them would report two different values as equal.\nconst isPlainObject = (value: unknown): value is Record<string, unknown> => {\n if (!isRecord(value)) return false;\n const prototype = Object.getPrototypeOf(value);\n return prototype === null || prototype === Object.prototype;\n};\n\n// Hosts commonly rebuild an equal context object on every render, and the\n// widget cannot tell a repeated notification apart from a real change. The\n// open index signature on McpAppHostContext admits values JSON rejects (an\n// undefined property value is enough), so leaves the walk cannot compare fall\n// back to identity rather than failing the whole comparison.\nconst isSameHostContext = (a: unknown, b: unknown, depth = 0): boolean => {\n if (Object.is(a, b)) return true;\n if (depth > 100) return false;\n if (Array.isArray(a) || Array.isArray(b)) {\n if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length)\n return false;\n for (let i = 0; i < a.length; i++) {\n if (!isSameHostContext(a[i], b[i], depth + 1)) return false;\n }\n return true;\n }\n if (!isPlainObject(a) || !isPlainObject(b)) return false;\n const aKeys = Object.keys(a);\n return (\n aKeys.length === Object.keys(b).length &&\n aKeys.every(\n (key) =>\n Object.hasOwn(b, key) && isSameHostContext(a[key], b[key], depth + 1),\n )\n );\n};\n\nfunction useBridgeNotify<T>(\n value: T | undefined,\n bridgeRef: MutableRefObject<McpAppBridge | null>,\n widgetReadyRef: MutableRefObject<boolean>,\n pendingRef: MutableRefObject<T | undefined>,\n lastSentRef: MutableRefObject<T | undefined>,\n notify: (bridge: McpAppBridge, v: T) => void,\n isEqual: (sent: T | undefined, next: T) => boolean = Object.is,\n) {\n useEffect(() => {\n if (!bridgeRef.current) return;\n // Nothing to deliver, either because there is no value or because the\n // widget already holds it; a queued value here is superseded and would\n // otherwise flush after initialization as a stale update.\n if (value === undefined || isEqual(lastSentRef.current, value)) {\n pendingRef.current = undefined;\n return;\n }\n if (!widgetReadyRef.current) {\n pendingRef.current = value;\n return;\n }\n notify(bridgeRef.current, value);\n lastSentRef.current = value;\n // oxlint-disable-next-line react/exhaustive-deps -- refs are stable; notify and isEqual are assumed stable; re-run only when value changes\n }, [value]);\n}\n\ntype LiveSnapshot = {\n handlers: McpAppBridgeHandlers | undefined;\n hostInfo: McpAppFrameProps[\"hostInfo\"];\n hostContext: McpAppFrameProps[\"hostContext\"];\n input: unknown;\n output: unknown;\n};\n\ntype FrameLifecycle = {\n onInitialized: () => void;\n onSizeChange: (params: { width?: number; height?: number }) => void;\n};\n\n// Proxy each per-call handler through liveRef so the bridge always dispatches\n// to the latest handler reference (e.g. inline callbacks closing over state).\n// Capability presence is snapshot at mount: a handler added later requires a\n// remount (keyed on resource URI) to expose the capability to the widget.\n// allowedTools is the exception: it is never advertised in the ui/initialize\n// response, so it stays a live getter, which means this object must reach the\n// bridge uncopied and the frame passes its lifecycle work in rather than\n// wrapping the result.\nfunction buildLiveHandlers(\n initial: McpAppBridgeHandlers | undefined,\n liveRef: { readonly current: LiveSnapshot },\n lifecycle: FrameLifecycle,\n): McpAppBridgeHandlers {\n const live = () => liveRef.current.handlers;\n const has = <K extends keyof McpAppBridgeHandlers>(key: K) =>\n initial?.[key] !== undefined;\n const out: McpAppBridgeHandlers = {};\n Object.defineProperty(out, \"allowedTools\", {\n get: () => live()?.allowedTools,\n enumerable: true,\n configurable: true,\n });\n const liveCall = <K extends keyof McpAppBridgeHandlers>(\n key: K,\n ): NonNullable<McpAppBridgeHandlers[K]> =>\n ((p: unknown) => {\n const fn = live()?.[key] as ((p: unknown) => unknown) | undefined;\n if (!fn) {\n throw new Error(`${key} handler is no longer available`);\n }\n return fn(p);\n }) as NonNullable<McpAppBridgeHandlers[K]>;\n if (has(\"callTool\")) out.callTool = liveCall(\"callTool\");\n if (has(\"readResource\")) out.readResource = liveCall(\"readResource\");\n if (has(\"listResources\")) out.listResources = liveCall(\"listResources\");\n if (has(\"openLink\")) out.openLink = liveCall(\"openLink\");\n if (has(\"sendMessage\")) out.sendMessage = liveCall(\"sendMessage\");\n if (has(\"updateModelContext\"))\n out.updateModelContext = liveCall(\"updateModelContext\");\n if (has(\"requestDisplayMode\"))\n out.requestDisplayMode = liveCall(\"requestDisplayMode\");\n out.onSizeChange = (p) => {\n lifecycle.onSizeChange(p);\n live()?.onSizeChange?.(p);\n };\n out.onInitialized = () => {\n lifecycle.onInitialized();\n live()?.onInitialized?.();\n };\n out.onRequestTeardown = (p) => live()?.onRequestTeardown?.(p);\n out.onLog = (p) => live()?.onLog?.(p);\n out.onError = (e) => live()?.onError?.(e);\n return out;\n}\n\nexport function McpAppFrame({\n app,\n resource,\n input,\n output,\n sandbox,\n handlers,\n hostInfo,\n hostContext,\n maxHeight = DEFAULT_MAX_HEIGHT,\n}: McpAppFrameProps) {\n const bridgeRef = useRef<McpAppBridge | null>(null);\n const lastSentInputRef = useRef<unknown>(undefined);\n const lastSentOutputRef = useRef<unknown>(undefined);\n const lastSentHostContextRef = useRef<McpAppHostContext | undefined>(\n undefined,\n );\n // Per MCP Apps spec, the host should defer notifications until the widget\n // signals readiness via `notifications/initialized`. Until then, we record\n // pending values and flush them on init.\n const widgetReadyRef = useRef(false);\n const pendingInputRef = useRef<unknown>(undefined);\n const pendingOutputRef = useRef<unknown>(undefined);\n const pendingHostContextRef = useRef<McpAppHostContext | undefined>(\n undefined,\n );\n\n const liveRef = useRef<LiveSnapshot>({\n handlers,\n hostInfo,\n hostContext,\n input,\n output,\n });\n useLayoutEffect(() => {\n liveRef.current = {\n handlers,\n hostInfo,\n hostContext,\n input,\n output,\n };\n }, [handlers, hostInfo, hostContext, input, output]);\n\n const createBridge = (\n frame: SandboxHostFrame,\n host: SandboxHostApi,\n ): SandboxBridge => {\n const current = liveRef.current;\n let initTimeoutId: ReturnType<typeof setTimeout> | null = null;\n\n const flushPending = () => {\n if (widgetReadyRef.current) return;\n widgetReadyRef.current = true;\n const b = bridgeRef.current;\n if (!b) return;\n if (pendingInputRef.current !== undefined) {\n b.notifyToolInput(pendingInputRef.current);\n lastSentInputRef.current = pendingInputRef.current;\n pendingInputRef.current = undefined;\n }\n if (pendingOutputRef.current !== undefined) {\n b.notifyToolResult(pendingOutputRef.current);\n lastSentOutputRef.current = pendingOutputRef.current;\n pendingOutputRef.current = undefined;\n }\n if (pendingHostContextRef.current !== undefined) {\n b.notifyHostContextChanged(pendingHostContextRef.current);\n lastSentHostContextRef.current = pendingHostContextRef.current;\n pendingHostContextRef.current = undefined;\n }\n };\n\n const wrappedHandlers = buildLiveHandlers(current.handlers, liveRef, {\n onInitialized: () => {\n if (initTimeoutId !== null) {\n clearTimeout(initTimeoutId);\n initTimeoutId = null;\n }\n flushPending();\n },\n onSizeChange: (p) => {\n if (p.height != null) host.setHeight(p.height);\n },\n });\n\n // Safety net: if the widget never sends notifications/initialized (broken\n // or non-spec-compliant), flush the queue anyway so the host doesn't\n // appear hung.\n initTimeoutId = setTimeout(() => {\n initTimeoutId = null;\n flushPending();\n }, INIT_TIMEOUT_MS);\n\n const bridge = createMcpAppBridge({\n frame,\n handlers: wrappedHandlers,\n hostInfo: current.hostInfo,\n hostContext: current.hostContext,\n });\n bridgeRef.current = bridge;\n\n if (current.input !== undefined) pendingInputRef.current = current.input;\n if (current.output !== undefined) pendingOutputRef.current = current.output;\n // hostContext is delivered inside the ui/initialize response, where the\n // bridge defaults it to {}; recording that same normalized value keeps the\n // first later change from repeating what the widget already holds.\n lastSentHostContextRef.current = current.hostContext ?? {};\n\n return {\n onMessage: bridge.onMessage,\n dispose: () => {\n if (initTimeoutId !== null) {\n clearTimeout(initTimeoutId);\n initTimeoutId = null;\n }\n bridge.dispose();\n bridgeRef.current = null;\n lastSentInputRef.current = undefined;\n lastSentOutputRef.current = undefined;\n lastSentHostContextRef.current = undefined;\n widgetReadyRef.current = false;\n pendingInputRef.current = undefined;\n pendingOutputRef.current = undefined;\n pendingHostContextRef.current = undefined;\n },\n };\n };\n\n useBridgeNotify(\n input,\n bridgeRef,\n widgetReadyRef,\n pendingInputRef,\n lastSentInputRef,\n (b, v) => b.notifyToolInput(v),\n );\n useBridgeNotify(\n output,\n bridgeRef,\n widgetReadyRef,\n pendingOutputRef,\n lastSentOutputRef,\n (b, v) => b.notifyToolResult(v),\n );\n useBridgeNotify(\n hostContext,\n bridgeRef,\n widgetReadyRef,\n pendingHostContextRef,\n lastSentHostContextRef,\n (b, v) => b.notifyHostContextChanged(v),\n isSameHostContext,\n );\n\n return (\n <SandboxHost\n content={{ html: resource.html }}\n contentKey={\n app.serverId ? `${app.serverId} ${resource.uri}` : resource.uri\n }\n sandbox={{ ...sandbox, product: sandbox?.product ?? DEFAULT_PRODUCT }}\n maxHeight={maxHeight}\n createBridge={createBridge}\n onError={(err) => liveRef.current.handlers?.onError?.(err)}\n containerProps={{\n \"data-mcp-app-resource\": app.resourceUri,\n \"data-mcp-app-prefers-border\": resource.meta?.prefersBorder\n ? \"\"\n : undefined,\n }}\n />\n );\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"useAssistantFrameHost.js","names":["c","_c","Unsubscribe","useEffect","RefObject","AssistantFrameHost","UseAssistantFrameHostOptions","iframeRef","Readonly","HTMLIFrameElement","targetOrigin","register","frameHost","useAssistantFrameHost","t0","$","t1","t2","iframeWindow","current","contentWindow","unsubscribe","cleanupFailed","cleanupError","dispose","t3","error","t4","console"],"sources":["../../../src/model-context/frame/useAssistantFrameHost.ts"],"sourcesContent":["\"use client\";\n\nimport type { Unsubscribe } from \"@assistant-ui/core\";\nimport { useEffect, type RefObject } from \"react\";\nimport { AssistantFrameHost } from \"@assistant-ui/core\";\n\ntype UseAssistantFrameHostOptions = {\n iframeRef: Readonly<RefObject<HTMLIFrameElement | null | undefined>>;\n targetOrigin?: string;\n register: (frameHost: AssistantFrameHost) => Unsubscribe;\n};\n\n/**\n * React hook that manages the lifecycle of an AssistantFrameHost and its binding to the current AssistantRuntime.\n *\n * Usage example:\n * ```typescript\n * function MyComponent() {\n * const iframeRef = useRef<HTMLIFrameElement>(null);\n *\n * useAssistantFrameHost({\n * iframeRef,\n * targetOrigin: \"https://trusted-domain.com\",\n * });\n *\n * return <iframe ref={iframeRef} src=\"...\" />;\n * }\n * ```\n */\nexport const useAssistantFrameHost = ({\n iframeRef,\n targetOrigin,\n register,\n}: UseAssistantFrameHostOptions): void => {\n useEffect(() => {\n const iframeWindow = iframeRef.current?.contentWindow;\n if (!iframeWindow) return;\n\n const frameHost = new AssistantFrameHost(iframeWindow, targetOrigin);\n\n const unsubscribe = register(frameHost);\n\n return () => {\n let cleanupFailed = false;\n let cleanupError: unknown;\n\n try {\n frameHost.dispose();\n } catch (error) {\n cleanupFailed = true;\n cleanupError = error;\n }\n\n try {\n unsubscribe();\n } catch (error) {\n if (cleanupFailed) {\n console.error(\n \"[assistant-ui] AssistantFrameHost unregistration failed.\",\n error,\n );\n } else {\n cleanupFailed = true;\n cleanupError = error;\n }\n }\n\n if (cleanupFailed) throw cleanupError;\n };\n }, [iframeRef, targetOrigin, register]);\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AA6BA,MAAaa,yBAAwBC,OAAA;CAAA,MAAAC,IAAAd,EAAA,CAAA;CAAC,MAAA,EAAAM,WAAAG,cAAAC,aAAAG;CAIP,IAAAE;CAAA,IAAAC;CAAA,IAAAF,EAAA,OAAAR,aAAAQ,EAAA,OAAAJ,YAAAI,EAAA,OAAAL,cAAA;EACnBM,WAAA;GACR,MAAAE,eAAqBX,UAASY,SAAuBC;GACrD,IAAI,CAACF,cAAY;GAEjB,MAAAN,YAAkB,IAAIP,mBAAmBa,cAAcR,YAAY;GAEnE,MAAAW,cAAoBV,SAASC,SAAS;GAAE,aAEjC;IACL,IAAAU,gBAAoB;IAChBC,IAAAA;IAEJ,IAAA;KACEX,UAASY,QAAS;IAAC,SAAAC,IAAA;KACZC,MAAAA,QAAAA;KACPJ,gBAAgBA;KAChBC,eAAeG;IAAH;IAGd,IAAA;KACEL,YAAY;IAAC,SAAAM,IAAA;KACND,MAAAA,UAAAA;KACP,IAAIJ,eACFM,QAAOF,MACL,4DACAA,OACF;UAAC;MAEDJ,gBAAgBA;MAChBC,eAAeG;KAAH;IACb;IAGH,IAAIJ,eAAe,MAAMC;GAAa;EACvC;EACAN,KAAA;GAACV;GAAWG;GAAcC;EAAQ;EAACI,EAAA,KAAAR;EAAAQ,EAAA,KAAAJ;EAAAI,EAAA,KAAAL;EAAAK,EAAA,KAAAC;EAAAD,EAAA,KAAAE;CAAA,OAAA;EAAAD,KAAAD,EAAA;EAAAE,KAAAF,EAAA;CAAA;CAnCtCZ,UAAUa,IAmCPC,EAAmC;AAAC"}
1
+ {"version":3,"file":"useAssistantFrameHost.js","names":["c","_c","Unsubscribe","useEffect","RefObject","AssistantFrameHost","UseAssistantFrameHostOptions","iframeRef","Readonly","HTMLIFrameElement","targetOrigin","register","frameHost","useAssistantFrameHost","t0","$","t1","t2","iframeWindow","current","contentWindow","unsubscribe","cleanupFailed","cleanupError","dispose","t3","error","t4","console","_c"],"sources":["../../../src/model-context/frame/useAssistantFrameHost.ts"],"sourcesContent":["\"use client\";\n\nimport type { Unsubscribe } from \"@assistant-ui/core\";\nimport { useEffect, type RefObject } from \"react\";\nimport { AssistantFrameHost } from \"@assistant-ui/core\";\n\ntype UseAssistantFrameHostOptions = {\n iframeRef: Readonly<RefObject<HTMLIFrameElement | null | undefined>>;\n targetOrigin?: string;\n register: (frameHost: AssistantFrameHost) => Unsubscribe;\n};\n\n/**\n * React hook that manages the lifecycle of an AssistantFrameHost and its binding to the current AssistantRuntime.\n *\n * Usage example:\n * ```typescript\n * function MyComponent() {\n * const iframeRef = useRef<HTMLIFrameElement>(null);\n *\n * useAssistantFrameHost({\n * iframeRef,\n * targetOrigin: \"https://trusted-domain.com\",\n * });\n *\n * return <iframe ref={iframeRef} src=\"...\" />;\n * }\n * ```\n */\nexport const useAssistantFrameHost = ({\n iframeRef,\n targetOrigin,\n register,\n}: UseAssistantFrameHostOptions): void => {\n useEffect(() => {\n const iframeWindow = iframeRef.current?.contentWindow;\n if (!iframeWindow) return;\n\n const frameHost = new AssistantFrameHost(iframeWindow, targetOrigin);\n\n const unsubscribe = register(frameHost);\n\n return () => {\n let cleanupFailed = false;\n let cleanupError: unknown;\n\n try {\n frameHost.dispose();\n } catch (error) {\n cleanupFailed = true;\n cleanupError = error;\n }\n\n try {\n unsubscribe();\n } catch (error) {\n if (cleanupFailed) {\n console.error(\n \"[assistant-ui] AssistantFrameHost unregistration failed.\",\n error,\n );\n } else {\n cleanupFailed = true;\n cleanupError = error;\n }\n }\n\n if (cleanupFailed) throw cleanupError;\n };\n }, [iframeRef, targetOrigin, register]);\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AA6BA,MAAaa,yBAAwBC,OAAA;CAAA,MAAAC,IAAAd,EAAA,CAAA;CAAC,MAAA,EAAAM,WAAAG,cAAAC,aAAAG;CAIP,IAAAE;CAAA,IAAAC;CAAA,IAAAF,EAAA,OAAAR,aAAAQ,EAAA,OAAAJ,YAAAI,EAAA,OAAAL,cAAA;EACnBM,WAAA;GACR,MAAAE,eAAqBX,UAASY,SAAuBC;GACrD,IAAI,CAACF,cAAY;GAEjB,MAAAN,YAAkB,IAAIP,mBAAmBa,cAAcR,YAAY;GAEnE,MAAAW,cAAoBV,SAASC,SAAS;GAAE,aAEjC;IACL,IAAAU,gBAAoB;IAChBC,IAAAA;IAEJ,IAAA;KACEX,UAASY,QAAS;IAAC,SAAAC,IAAA;KACZC,MAAAA,QAAAA;KACPJ,gBAAgBA;KAChBC,eAAeG;IAAH;IAGd,IAAA;KACEL,YAAY;IAAC,SAAAM,IAAA;KACND,MAAAA,UAAAA;KACP,IAAIJ,eACFM,QAAOF,MACL,4DACAA,OACF;UAAC;MAEDJ,gBAAgBA;MAChBC,eAAeG;KAAH;IACb;IAGH,IAAIJ,eAAe,MAAMC;GAAa;EACvC;EACAN,KAAA;GAACV;GAAWG;GAAcC;EAAQ;EAACI,EAAA,KAAAR;EAAAQ,EAAA,KAAAJ;EAAAI,EAAA,KAAAL;EAAAK,EAAA,KAAAC;EAAAD,EAAA,KAAAE;CAAA,OAAA;EAAAD,KAAAD,EAAA;EAAAE,KAAAF,EAAA;CAAA;CAnCtCZ,UAAUa,IAmCPC,EAAmC;AAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"makeAssistantVisible.js","names":["c","_c","useEffect","useRef","forwardRef","ComponentType","ForwardedRef","PropsWithoutRef","useId","createContext","useContext","useAui","useComposedRefs","tool","click","parameters","type","properties","clickId","required","execute","escapedClickId","CSS","escape","el","document","querySelector","HTMLElement","Promise","resolve","setTimeout","setNativeValue","element","HTMLInputElement","HTMLTextAreaElement","value","prototype","setter","Object","getOwnPropertyDescriptor","set","call","edit","editId","escapedEditId","dispatchEvent","Event","bubbles","ReadableContext","makeAssistantVisible","Component","T","config","clickable","editable","ReadableComponent","props","outerRef","$","isNestedReadable","componentRef","aui","t0","Symbol","for","t1","modelContext","register","getModelContext","tools","system","current","outerHTML","undefined","t2","ref","t3","t4","t5","t6","displayName"],"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/internal\";\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 setNativeValue = (\n element: HTMLInputElement | HTMLTextAreaElement,\n value: string,\n) => {\n const prototype =\n element instanceof HTMLInputElement\n ? HTMLInputElement.prototype\n : HTMLTextAreaElement.prototype;\n const setter = Object.getOwnPropertyDescriptor(prototype, \"value\")?.set;\n\n if (setter) {\n setter.call(element, value);\n } else {\n element.value = value;\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 setNativeValue(el, 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":"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"}
1
+ {"version":3,"file":"makeAssistantVisible.js","names":["c","_c","useEffect","useRef","forwardRef","ComponentType","ForwardedRef","PropsWithoutRef","useId","createContext","useContext","useAui","useComposedRefs","tool","click","parameters","type","properties","clickId","required","execute","escapedClickId","CSS","escape","el","document","querySelector","HTMLElement","Promise","resolve","setTimeout","setNativeValue","element","HTMLInputElement","HTMLTextAreaElement","value","prototype","setter","Object","getOwnPropertyDescriptor","set","call","edit","editId","escapedEditId","dispatchEvent","Event","bubbles","ReadableContext","makeAssistantVisible","Component","T","config","clickable","editable","ReadableComponent","props","outerRef","$","isNestedReadable","componentRef","aui","t0","Symbol","for","t1","modelContext","register","getModelContext","tools","system","current","outerHTML","undefined","t2","ref","t3","t4","t5","t6","displayName","_c"],"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/internal\";\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 setNativeValue = (\n element: HTMLInputElement | HTMLTextAreaElement,\n value: string,\n) => {\n const prototype =\n element instanceof HTMLInputElement\n ? HTMLInputElement.prototype\n : HTMLTextAreaElement.prototype;\n const setter = Object.getOwnPropertyDescriptor(prototype, \"value\")?.set;\n\n if (setter) {\n setter.call(element, value);\n } else {\n element.value = value;\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 setNativeValue(el, 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":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ActionBarCopy.js","names":["c","_c","forwardRef","ActionButtonProps","composeEventHandlers","Primitive","useActionBarCopy","useAuiState","useActionBarPrimitiveCopy","t0","$","t1","undefined","copiedDuration","t2","t3","copyToClipboard","_temp","copy","disabled","ActionBarPrimitiveCopy","Element","HTMLButtonElement","Props","forwardedRef","onClick","props","isCopied","_temp2","callback","t4","t5","t6","displayName","text","navigator","clipboard","Promise","reject","Error","writeText","s","message"],"sources":["../../../src/primitives/actionBar/ActionBarCopy.tsx"],"sourcesContent":["\"use client\";\n\nimport { forwardRef } from \"react\";\nimport type { ActionButtonProps } from \"../../utils/createActionButton\";\nimport { composeEventHandlers } from \"radix-ui/internal\";\nimport { Primitive } from \"../../utils/Primitive\";\nimport { useActionBarCopy } from \"@assistant-ui/core/react\";\nimport { useAuiState } from \"@assistant-ui/store\";\n\n/**\n * Hook that provides copy functionality for action bar buttons.\n *\n * This hook returns a callback function that copies message content to the clipboard,\n * or null if copying is not available. It handles both regular message content and\n * composer text when in editing mode.\n *\n * @param options Configuration options\n * @param options.copiedDuration Duration in milliseconds to show the copied state\n * @returns A copy callback function, or null if copying is disabled\n *\n * @example\n * ```tsx\n * function CustomCopyButton() {\n * const copy = useActionBarPrimitiveCopy({ copiedDuration: 2000 });\n *\n * return (\n * <button onClick={copy} disabled={!copy}>\n * {copy ? \"Copy\" : \"Cannot Copy\"}\n * </button>\n * );\n * }\n * ```\n */\nconst useActionBarPrimitiveCopy = ({\n copiedDuration = 3000,\n}: {\n copiedDuration?: number | undefined;\n} = {}) => {\n const { copy, disabled } = useActionBarCopy({\n copiedDuration,\n copyToClipboard: (text) => {\n if (typeof navigator === \"undefined\" || !navigator.clipboard) {\n return Promise.reject(new Error(\"Clipboard API is unavailable\"));\n }\n return navigator.clipboard.writeText(text);\n },\n });\n if (disabled) return null;\n return copy;\n};\n\nexport namespace ActionBarPrimitiveCopy {\n export type Element = HTMLButtonElement;\n /**\n * Props for the ActionBarPrimitive.Copy component.\n * Inherits all button element props and action button functionality.\n */\n export type Props = ActionButtonProps<typeof useActionBarPrimitiveCopy>;\n}\n\n/**\n * A button component that copies message content to the clipboard.\n *\n * This component automatically handles copying message text to the clipboard\n * and provides visual feedback through the data-copied attribute. It's disabled\n * when there's no copyable content available.\n *\n * @example\n * ```tsx\n * <ActionBarPrimitive.Copy copiedDuration={2000}>\n * Copy Message\n * </ActionBarPrimitive.Copy>\n * ```\n */\nexport const ActionBarPrimitiveCopy = forwardRef<\n ActionBarPrimitiveCopy.Element,\n ActionBarPrimitiveCopy.Props\n>(({ copiedDuration, onClick, disabled, ...props }, forwardedRef) => {\n const isCopied = useAuiState((s) => s.message.isCopied);\n const callback = useActionBarPrimitiveCopy({ copiedDuration });\n return (\n <Primitive.button\n type=\"button\"\n {...(isCopied ? { \"data-copied\": \"true\" } : {})}\n {...props}\n ref={forwardedRef}\n disabled={disabled || !callback}\n onClick={composeEventHandlers(onClick, () => {\n callback?.();\n })}\n />\n );\n});\n\nActionBarPrimitiveCopy.displayName = \"ActionBarPrimitive.Copy\";\n"],"mappings":"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"}
1
+ {"version":3,"file":"ActionBarCopy.js","names":["c","_c","forwardRef","ActionButtonProps","composeEventHandlers","Primitive","useActionBarCopy","useAuiState","useActionBarPrimitiveCopy","t0","$","t1","undefined","copiedDuration","t2","t3","copyToClipboard","_temp","copy","disabled","ActionBarPrimitiveCopy","Element","HTMLButtonElement","Props","forwardedRef","onClick","props","isCopied","_temp2","callback","t4","t5","t6","displayName","text","navigator","clipboard","Promise","reject","Error","writeText","s","message","_c","Primitive"],"sources":["../../../src/primitives/actionBar/ActionBarCopy.tsx"],"sourcesContent":["\"use client\";\n\nimport { forwardRef } from \"react\";\nimport type { ActionButtonProps } from \"../../utils/createActionButton\";\nimport { composeEventHandlers } from \"radix-ui/internal\";\nimport { Primitive } from \"../../utils/Primitive\";\nimport { useActionBarCopy } from \"@assistant-ui/core/react\";\nimport { useAuiState } from \"@assistant-ui/store\";\n\n/**\n * Hook that provides copy functionality for action bar buttons.\n *\n * This hook returns a callback function that copies message content to the clipboard,\n * or null if copying is not available. It handles both regular message content and\n * composer text when in editing mode.\n *\n * @param options Configuration options\n * @param options.copiedDuration Duration in milliseconds to show the copied state\n * @returns A copy callback function, or null if copying is disabled\n *\n * @example\n * ```tsx\n * function CustomCopyButton() {\n * const copy = useActionBarPrimitiveCopy({ copiedDuration: 2000 });\n *\n * return (\n * <button onClick={copy} disabled={!copy}>\n * {copy ? \"Copy\" : \"Cannot Copy\"}\n * </button>\n * );\n * }\n * ```\n */\nconst useActionBarPrimitiveCopy = ({\n copiedDuration = 3000,\n}: {\n copiedDuration?: number | undefined;\n} = {}) => {\n const { copy, disabled } = useActionBarCopy({\n copiedDuration,\n copyToClipboard: (text) => {\n if (typeof navigator === \"undefined\" || !navigator.clipboard) {\n return Promise.reject(new Error(\"Clipboard API is unavailable\"));\n }\n return navigator.clipboard.writeText(text);\n },\n });\n if (disabled) return null;\n return copy;\n};\n\nexport namespace ActionBarPrimitiveCopy {\n export type Element = HTMLButtonElement;\n /**\n * Props for the ActionBarPrimitive.Copy component.\n * Inherits all button element props and action button functionality.\n */\n export type Props = ActionButtonProps<typeof useActionBarPrimitiveCopy>;\n}\n\n/**\n * A button component that copies message content to the clipboard.\n *\n * This component automatically handles copying message text to the clipboard\n * and provides visual feedback through the data-copied attribute. It's disabled\n * when there's no copyable content available.\n *\n * @example\n * ```tsx\n * <ActionBarPrimitive.Copy copiedDuration={2000}>\n * Copy Message\n * </ActionBarPrimitive.Copy>\n * ```\n */\nexport const ActionBarPrimitiveCopy = forwardRef<\n ActionBarPrimitiveCopy.Element,\n ActionBarPrimitiveCopy.Props\n>(({ copiedDuration, onClick, disabled, ...props }, forwardedRef) => {\n const isCopied = useAuiState((s) => s.message.isCopied);\n const callback = useActionBarPrimitiveCopy({ copiedDuration });\n return (\n <Primitive.button\n type=\"button\"\n {...(isCopied ? { \"data-copied\": \"true\" } : {})}\n {...props}\n ref={forwardedRef}\n disabled={disabled || !callback}\n onClick={composeEventHandlers(onClick, () => {\n callback?.();\n })}\n />\n );\n});\n\nActionBarPrimitiveCopy.displayName = \"ActionBarPrimitive.Copy\";\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ActionBarEdit.js","names":["ActionButtonElement","ActionButtonProps","createActionButton","useActionBarEdit","useActionBarEditBehavior","disabled","edit","ActionBarPrimitiveEdit","Element","Props"],"sources":["../../../src/primitives/actionBar/ActionBarEdit.ts"],"sourcesContent":["\"use client\";\n\nimport {\n type ActionButtonElement,\n type ActionButtonProps,\n createActionButton,\n} from \"../../utils/createActionButton\";\nimport { useActionBarEdit as useActionBarEditBehavior } from \"@assistant-ui/core/react\";\n\n/**\n * Hook that provides edit functionality for action bar buttons.\n *\n * This hook returns a callback function that starts editing the current message,\n * or null if editing is not available (e.g., already in editing mode).\n *\n * @returns An edit callback function, or null if editing is disabled\n *\n * @example\n * ```tsx\n * function CustomEditButton() {\n * const edit = useActionBarEdit();\n *\n * return (\n * <button onClick={edit} disabled={!edit}>\n * {edit ? \"Edit Message\" : \"Cannot Edit\"}\n * </button>\n * );\n * }\n * ```\n */\nconst useActionBarEdit = () => {\n const { disabled, edit } = useActionBarEditBehavior();\n if (disabled) return null;\n return edit;\n};\n\nexport namespace ActionBarPrimitiveEdit {\n export type Element = ActionButtonElement;\n /**\n * Props for the ActionBarPrimitive.Edit component.\n * Inherits all button element props and action button functionality.\n */\n export type Props = ActionButtonProps<typeof useActionBarEdit>;\n}\n\n/**\n * A button component that starts editing the current message.\n *\n * This component automatically handles starting the edit mode for the current message\n * and is disabled when editing is not available (e.g., already in editing mode).\n *\n * @example\n * ```tsx\n * <ActionBarPrimitive.Edit>\n * Edit Message\n * </ActionBarPrimitive.Edit>\n * ```\n */\nexport const ActionBarPrimitiveEdit = createActionButton(\n \"ActionBarPrimitive.Edit\",\n useActionBarEdit,\n);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AA8BA,MAAMG,2BAAmB;CACvB,MAAA,EAAAE,UAAAC,SAA2BF,iBAAyB;CACpD,IAAIC,UAAQ,OAAS;CAAK,OACnBC;AAAI;;;;;;;;;;;;;;AAyBb,MAAaC,yBAAyBL,mBACpC,2BACAC,kBACF"}
1
+ {"version":3,"file":"ActionBarEdit.js","names":["ActionButtonElement","ActionButtonProps","createActionButton","useActionBarEdit","useActionBarEditBehavior","disabled","edit","ActionBarPrimitiveEdit","Element","Props","useActionBarEdit","useActionBarEditBehavior"],"sources":["../../../src/primitives/actionBar/ActionBarEdit.ts"],"sourcesContent":["\"use client\";\n\nimport {\n type ActionButtonElement,\n type ActionButtonProps,\n createActionButton,\n} from \"../../utils/createActionButton\";\nimport { useActionBarEdit as useActionBarEditBehavior } from \"@assistant-ui/core/react\";\n\n/**\n * Hook that provides edit functionality for action bar buttons.\n *\n * This hook returns a callback function that starts editing the current message,\n * or null if editing is not available (e.g., already in editing mode).\n *\n * @returns An edit callback function, or null if editing is disabled\n *\n * @example\n * ```tsx\n * function CustomEditButton() {\n * const edit = useActionBarEdit();\n *\n * return (\n * <button onClick={edit} disabled={!edit}>\n * {edit ? \"Edit Message\" : \"Cannot Edit\"}\n * </button>\n * );\n * }\n * ```\n */\nconst useActionBarEdit = () => {\n const { disabled, edit } = useActionBarEditBehavior();\n if (disabled) return null;\n return edit;\n};\n\nexport namespace ActionBarPrimitiveEdit {\n export type Element = ActionButtonElement;\n /**\n * Props for the ActionBarPrimitive.Edit component.\n * Inherits all button element props and action button functionality.\n */\n export type Props = ActionButtonProps<typeof useActionBarEdit>;\n}\n\n/**\n * A button component that starts editing the current message.\n *\n * This component automatically handles starting the edit mode for the current message\n * and is disabled when editing is not available (e.g., already in editing mode).\n *\n * @example\n * ```tsx\n * <ActionBarPrimitive.Edit>\n * Edit Message\n * </ActionBarPrimitive.Edit>\n * ```\n */\nexport const ActionBarPrimitiveEdit = createActionButton(\n \"ActionBarPrimitive.Edit\",\n useActionBarEdit,\n);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AA8BA,MAAMG,2BAAmB;CACvB,MAAA,EAAAE,UAAAC,SAA2BF,iBAAyB;CACpD,IAAIC,UAAQ,OAAS;CAAK,OACnBC;AAAI;;;;;;;;;;;;;;AAyBb,MAAaC,yBAAyBL,mBACpC,2BACAC,kBACF"}