@assistant-ui/react 0.11.53 → 0.11.55

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 (219) hide show
  1. package/README.md +6 -3
  2. package/dist/client/NoOpComposerClient.d.ts +1 -1
  3. package/dist/client/NoOpComposerClient.d.ts.map +1 -1
  4. package/dist/client/NoOpComposerClient.js +7 -0
  5. package/dist/client/NoOpComposerClient.js.map +1 -1
  6. package/dist/client/types/Composer.d.ts +18 -3
  7. package/dist/client/types/Composer.d.ts.map +1 -1
  8. package/dist/client/types/Message.d.ts +17 -3
  9. package/dist/client/types/Message.d.ts.map +1 -1
  10. package/dist/legacy-runtime/client/ComposerRuntimeClient.d.ts.map +1 -1
  11. package/dist/legacy-runtime/client/ComposerRuntimeClient.js +3 -0
  12. package/dist/legacy-runtime/client/ComposerRuntimeClient.js.map +1 -1
  13. package/dist/legacy-runtime/hooks/AssistantContext.d.ts +2 -2
  14. package/dist/legacy-runtime/hooks/AssistantContext.js +1 -1
  15. package/dist/legacy-runtime/hooks/AttachmentContext.d.ts +2 -2
  16. package/dist/legacy-runtime/hooks/AttachmentContext.js +1 -1
  17. package/dist/legacy-runtime/hooks/ComposerContext.d.ts +2 -2
  18. package/dist/legacy-runtime/hooks/ComposerContext.js +1 -1
  19. package/dist/legacy-runtime/hooks/MessageContext.d.ts +3 -3
  20. package/dist/legacy-runtime/hooks/MessageContext.js +2 -2
  21. package/dist/legacy-runtime/hooks/MessagePartContext.d.ts +2 -2
  22. package/dist/legacy-runtime/hooks/MessagePartContext.js +1 -1
  23. package/dist/legacy-runtime/hooks/ThreadContext.d.ts +4 -4
  24. package/dist/legacy-runtime/hooks/ThreadContext.js +2 -2
  25. package/dist/legacy-runtime/hooks/ThreadListItemContext.d.ts +2 -2
  26. package/dist/legacy-runtime/hooks/ThreadListItemContext.js +1 -1
  27. package/dist/legacy-runtime/runtime/ComposerRuntime.d.ts +22 -6
  28. package/dist/legacy-runtime/runtime/ComposerRuntime.d.ts.map +1 -1
  29. package/dist/legacy-runtime/runtime/ComposerRuntime.js +18 -2
  30. package/dist/legacy-runtime/runtime/ComposerRuntime.js.map +1 -1
  31. package/dist/legacy-runtime/runtime/ThreadRuntime.d.ts +3 -0
  32. package/dist/legacy-runtime/runtime/ThreadRuntime.d.ts.map +1 -1
  33. package/dist/legacy-runtime/runtime-cores/adapters/speech/SpeechAdapterTypes.d.ts +25 -3
  34. package/dist/legacy-runtime/runtime-cores/adapters/speech/SpeechAdapterTypes.d.ts.map +1 -1
  35. package/dist/legacy-runtime/runtime-cores/adapters/speech/WebSpeechDictationAdapter.d.ts +61 -0
  36. package/dist/legacy-runtime/runtime-cores/adapters/speech/WebSpeechDictationAdapter.d.ts.map +1 -0
  37. package/dist/legacy-runtime/runtime-cores/adapters/speech/WebSpeechDictationAdapter.js +152 -0
  38. package/dist/legacy-runtime/runtime-cores/adapters/speech/WebSpeechDictationAdapter.js.map +1 -0
  39. package/dist/legacy-runtime/runtime-cores/adapters/speech/index.d.ts +2 -1
  40. package/dist/legacy-runtime/runtime-cores/adapters/speech/index.d.ts.map +1 -1
  41. package/dist/legacy-runtime/runtime-cores/adapters/speech/index.js +1 -0
  42. package/dist/legacy-runtime/runtime-cores/adapters/speech/index.js.map +1 -1
  43. package/dist/legacy-runtime/runtime-cores/assistant-transport/types.d.ts +1 -1
  44. package/dist/legacy-runtime/runtime-cores/assistant-transport/types.d.ts.map +1 -1
  45. package/dist/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.d.ts.map +1 -1
  46. package/dist/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.js +4 -1
  47. package/dist/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.js.map +1 -1
  48. package/dist/legacy-runtime/runtime-cores/composer/BaseComposerRuntimeCore.d.ts +20 -5
  49. package/dist/legacy-runtime/runtime-cores/composer/BaseComposerRuntimeCore.d.ts.map +1 -1
  50. package/dist/legacy-runtime/runtime-cores/composer/BaseComposerRuntimeCore.js +140 -0
  51. package/dist/legacy-runtime/runtime-cores/composer/BaseComposerRuntimeCore.js.map +1 -1
  52. package/dist/legacy-runtime/runtime-cores/composer/DefaultEditComposerRuntimeCore.d.ts +6 -3
  53. package/dist/legacy-runtime/runtime-cores/composer/DefaultEditComposerRuntimeCore.d.ts.map +1 -1
  54. package/dist/legacy-runtime/runtime-cores/composer/DefaultEditComposerRuntimeCore.js +3 -0
  55. package/dist/legacy-runtime/runtime-cores/composer/DefaultEditComposerRuntimeCore.js.map +1 -1
  56. package/dist/legacy-runtime/runtime-cores/composer/DefaultThreadComposerRuntimeCore.d.ts +7 -4
  57. package/dist/legacy-runtime/runtime-cores/composer/DefaultThreadComposerRuntimeCore.d.ts.map +1 -1
  58. package/dist/legacy-runtime/runtime-cores/composer/DefaultThreadComposerRuntimeCore.js +3 -0
  59. package/dist/legacy-runtime/runtime-cores/composer/DefaultThreadComposerRuntimeCore.js.map +1 -1
  60. package/dist/legacy-runtime/runtime-cores/core/ComposerRuntimeCore.d.ts +35 -1
  61. package/dist/legacy-runtime/runtime-cores/core/ComposerRuntimeCore.d.ts.map +1 -1
  62. package/dist/legacy-runtime/runtime-cores/core/ThreadRuntimeCore.d.ts +1 -0
  63. package/dist/legacy-runtime/runtime-cores/core/ThreadRuntimeCore.d.ts.map +1 -1
  64. package/dist/legacy-runtime/runtime-cores/core/index.d.ts +1 -0
  65. package/dist/legacy-runtime/runtime-cores/core/index.d.ts.map +1 -1
  66. package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreAdapter.d.ts +8 -7
  67. package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreAdapter.d.ts.map +1 -1
  68. package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadRuntimeCore.d.ts +7 -6
  69. package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadRuntimeCore.d.ts.map +1 -1
  70. package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadRuntimeCore.js +4 -2
  71. package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadRuntimeCore.js.map +1 -1
  72. package/dist/legacy-runtime/runtime-cores/local/LocalRuntimeOptions.d.ts +10 -8
  73. package/dist/legacy-runtime/runtime-cores/local/LocalRuntimeOptions.d.ts.map +1 -1
  74. package/dist/legacy-runtime/runtime-cores/local/LocalRuntimeOptions.js.map +1 -1
  75. package/dist/legacy-runtime/runtime-cores/local/LocalThreadRuntimeCore.d.ts +5 -3
  76. package/dist/legacy-runtime/runtime-cores/local/LocalThreadRuntimeCore.d.ts.map +1 -1
  77. package/dist/legacy-runtime/runtime-cores/local/LocalThreadRuntimeCore.js +6 -0
  78. package/dist/legacy-runtime/runtime-cores/local/LocalThreadRuntimeCore.js.map +1 -1
  79. package/dist/legacy-runtime/runtime-cores/remote-thread-list/EMPTY_THREAD_CORE.d.ts +1 -1
  80. package/dist/legacy-runtime/runtime-cores/remote-thread-list/EMPTY_THREAD_CORE.d.ts.map +1 -1
  81. package/dist/legacy-runtime/runtime-cores/remote-thread-list/EMPTY_THREAD_CORE.js +8 -0
  82. package/dist/legacy-runtime/runtime-cores/remote-thread-list/EMPTY_THREAD_CORE.js.map +1 -1
  83. package/dist/legacy-runtime/runtime-cores/remote-thread-list/adapter/cloud.d.ts.map +1 -1
  84. package/dist/legacy-runtime/runtime-cores/remote-thread-list/adapter/cloud.js +8 -1
  85. package/dist/legacy-runtime/runtime-cores/remote-thread-list/adapter/cloud.js.map +1 -1
  86. package/dist/primitives/actionBarMore/ActionBarMoreContent.d.ts +12 -0
  87. package/dist/primitives/actionBarMore/ActionBarMoreContent.d.ts.map +1 -0
  88. package/dist/primitives/actionBarMore/ActionBarMoreContent.js +11 -0
  89. package/dist/primitives/actionBarMore/ActionBarMoreContent.js.map +1 -0
  90. package/dist/primitives/actionBarMore/ActionBarMoreItem.d.ts +8 -0
  91. package/dist/primitives/actionBarMore/ActionBarMoreItem.d.ts.map +1 -0
  92. package/dist/primitives/actionBarMore/ActionBarMoreItem.js +11 -0
  93. package/dist/primitives/actionBarMore/ActionBarMoreItem.js.map +1 -0
  94. package/dist/primitives/actionBarMore/ActionBarMoreRoot.d.ts +7 -0
  95. package/dist/primitives/actionBarMore/ActionBarMoreRoot.d.ts.map +1 -0
  96. package/dist/primitives/actionBarMore/ActionBarMoreRoot.js +10 -0
  97. package/dist/primitives/actionBarMore/ActionBarMoreRoot.js.map +1 -0
  98. package/dist/primitives/actionBarMore/ActionBarMoreSeparator.d.ts +8 -0
  99. package/dist/primitives/actionBarMore/ActionBarMoreSeparator.d.ts.map +1 -0
  100. package/dist/primitives/actionBarMore/ActionBarMoreSeparator.js +12 -0
  101. package/dist/primitives/actionBarMore/ActionBarMoreSeparator.js.map +1 -0
  102. package/dist/primitives/actionBarMore/ActionBarMoreTrigger.d.ts +8 -0
  103. package/dist/primitives/actionBarMore/ActionBarMoreTrigger.d.ts.map +1 -0
  104. package/dist/primitives/actionBarMore/ActionBarMoreTrigger.js +11 -0
  105. package/dist/primitives/actionBarMore/ActionBarMoreTrigger.js.map +1 -0
  106. package/dist/primitives/actionBarMore/index.d.ts +6 -0
  107. package/dist/primitives/actionBarMore/index.d.ts.map +1 -0
  108. package/dist/primitives/actionBarMore/index.js +6 -0
  109. package/dist/primitives/actionBarMore/index.js.map +1 -0
  110. package/dist/primitives/actionBarMore/scope.d.ts +7 -0
  111. package/dist/primitives/actionBarMore/scope.d.ts.map +1 -0
  112. package/dist/primitives/actionBarMore/scope.js +3 -0
  113. package/dist/primitives/actionBarMore/scope.js.map +1 -0
  114. package/dist/primitives/composer/ComposerDictate.d.ts +23 -0
  115. package/dist/primitives/composer/ComposerDictate.d.ts.map +1 -0
  116. package/dist/primitives/composer/ComposerDictate.js +30 -0
  117. package/dist/primitives/composer/ComposerDictate.js.map +1 -0
  118. package/dist/primitives/composer/ComposerDictationTranscript.d.ts +25 -0
  119. package/dist/primitives/composer/ComposerDictationTranscript.d.ts.map +1 -0
  120. package/dist/primitives/composer/ComposerDictationTranscript.js +29 -0
  121. package/dist/primitives/composer/ComposerDictationTranscript.js.map +1 -0
  122. package/dist/primitives/composer/ComposerIf.d.ts +3 -0
  123. package/dist/primitives/composer/ComposerIf.d.ts.map +1 -1
  124. package/dist/primitives/composer/ComposerIf.js +5 -0
  125. package/dist/primitives/composer/ComposerIf.js.map +1 -1
  126. package/dist/primitives/composer/ComposerInput.d.ts.map +1 -1
  127. package/dist/primitives/composer/ComposerInput.js +1 -1
  128. package/dist/primitives/composer/ComposerInput.js.map +1 -1
  129. package/dist/primitives/composer/ComposerStopDictation.d.ts +23 -0
  130. package/dist/primitives/composer/ComposerStopDictation.d.ts.map +1 -0
  131. package/dist/primitives/composer/ComposerStopDictation.js +28 -0
  132. package/dist/primitives/composer/ComposerStopDictation.js.map +1 -0
  133. package/dist/primitives/composer/index.d.ts +3 -0
  134. package/dist/primitives/composer/index.d.ts.map +1 -1
  135. package/dist/primitives/composer/index.js +3 -0
  136. package/dist/primitives/composer/index.js.map +1 -1
  137. package/dist/primitives/index.d.ts +2 -0
  138. package/dist/primitives/index.d.ts.map +1 -1
  139. package/dist/primitives/index.js +2 -0
  140. package/dist/primitives/index.js.map +1 -1
  141. package/dist/primitives/threadListItemMore/ThreadListItemMoreContent.d.ts +12 -0
  142. package/dist/primitives/threadListItemMore/ThreadListItemMoreContent.d.ts.map +1 -0
  143. package/dist/primitives/threadListItemMore/ThreadListItemMoreContent.js +12 -0
  144. package/dist/primitives/threadListItemMore/ThreadListItemMoreContent.js.map +1 -0
  145. package/dist/primitives/threadListItemMore/ThreadListItemMoreItem.d.ts +8 -0
  146. package/dist/primitives/threadListItemMore/ThreadListItemMoreItem.d.ts.map +1 -0
  147. package/dist/primitives/threadListItemMore/ThreadListItemMoreItem.js +12 -0
  148. package/dist/primitives/threadListItemMore/ThreadListItemMoreItem.js.map +1 -0
  149. package/dist/primitives/threadListItemMore/ThreadListItemMoreRoot.d.ts +7 -0
  150. package/dist/primitives/threadListItemMore/ThreadListItemMoreRoot.d.ts.map +1 -0
  151. package/dist/primitives/threadListItemMore/ThreadListItemMoreRoot.js +11 -0
  152. package/dist/primitives/threadListItemMore/ThreadListItemMoreRoot.js.map +1 -0
  153. package/dist/primitives/threadListItemMore/ThreadListItemMoreSeparator.d.ts +8 -0
  154. package/dist/primitives/threadListItemMore/ThreadListItemMoreSeparator.d.ts.map +1 -0
  155. package/dist/primitives/threadListItemMore/ThreadListItemMoreSeparator.js +12 -0
  156. package/dist/primitives/threadListItemMore/ThreadListItemMoreSeparator.js.map +1 -0
  157. package/dist/primitives/threadListItemMore/ThreadListItemMoreTrigger.d.ts +8 -0
  158. package/dist/primitives/threadListItemMore/ThreadListItemMoreTrigger.d.ts.map +1 -0
  159. package/dist/primitives/threadListItemMore/ThreadListItemMoreTrigger.js +12 -0
  160. package/dist/primitives/threadListItemMore/ThreadListItemMoreTrigger.js.map +1 -0
  161. package/dist/primitives/threadListItemMore/index.d.ts +6 -0
  162. package/dist/primitives/threadListItemMore/index.d.ts.map +1 -0
  163. package/dist/primitives/threadListItemMore/index.js +6 -0
  164. package/dist/primitives/threadListItemMore/index.js.map +1 -0
  165. package/dist/primitives/threadListItemMore/scope.d.ts +7 -0
  166. package/dist/primitives/threadListItemMore/scope.d.ts.map +1 -0
  167. package/dist/primitives/threadListItemMore/scope.js +3 -0
  168. package/dist/primitives/threadListItemMore/scope.js.map +1 -0
  169. package/package.json +6 -5
  170. package/src/client/NoOpComposerClient.tsx +8 -1
  171. package/src/client/types/Composer.ts +21 -4
  172. package/src/client/types/Message.ts +17 -3
  173. package/src/legacy-runtime/client/ComposerRuntimeClient.ts +4 -0
  174. package/src/legacy-runtime/hooks/AssistantContext.ts +2 -2
  175. package/src/legacy-runtime/hooks/AttachmentContext.ts +2 -2
  176. package/src/legacy-runtime/hooks/ComposerContext.ts +2 -2
  177. package/src/legacy-runtime/hooks/MessageContext.ts +3 -3
  178. package/src/legacy-runtime/hooks/MessagePartContext.ts +2 -2
  179. package/src/legacy-runtime/hooks/ThreadContext.ts +4 -4
  180. package/src/legacy-runtime/hooks/ThreadListItemContext.ts +2 -2
  181. package/src/legacy-runtime/runtime/ComposerRuntime.ts +51 -14
  182. package/src/legacy-runtime/runtime-cores/adapters/speech/SpeechAdapterTypes.ts +26 -3
  183. package/src/legacy-runtime/runtime-cores/adapters/speech/WebSpeechDictationAdapter.ts +255 -0
  184. package/src/legacy-runtime/runtime-cores/adapters/speech/index.ts +5 -1
  185. package/src/legacy-runtime/runtime-cores/assistant-transport/types.ts +1 -1
  186. package/src/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.tsx +5 -1
  187. package/src/legacy-runtime/runtime-cores/composer/BaseComposerRuntimeCore.tsx +171 -5
  188. package/src/legacy-runtime/runtime-cores/composer/DefaultEditComposerRuntimeCore.tsx +14 -4
  189. package/src/legacy-runtime/runtime-cores/composer/DefaultThreadComposerRuntimeCore.tsx +15 -5
  190. package/src/legacy-runtime/runtime-cores/core/ComposerRuntimeCore.tsx +39 -1
  191. package/src/legacy-runtime/runtime-cores/core/ThreadRuntimeCore.tsx +1 -0
  192. package/src/legacy-runtime/runtime-cores/core/index.ts +2 -0
  193. package/src/legacy-runtime/runtime-cores/external-store/ExternalStoreAdapter.tsx +11 -7
  194. package/src/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadRuntimeCore.tsx +12 -7
  195. package/src/legacy-runtime/runtime-cores/local/LocalRuntimeOptions.tsx +12 -8
  196. package/src/legacy-runtime/runtime-cores/local/LocalThreadRuntimeCore.tsx +11 -4
  197. package/src/legacy-runtime/runtime-cores/remote-thread-list/EMPTY_THREAD_CORE.tsx +12 -1
  198. package/src/legacy-runtime/runtime-cores/remote-thread-list/adapter/cloud.tsx +11 -1
  199. package/src/primitives/actionBarMore/ActionBarMoreContent.tsx +46 -0
  200. package/src/primitives/actionBarMore/ActionBarMoreItem.tsx +31 -0
  201. package/src/primitives/actionBarMore/ActionBarMoreRoot.tsx +22 -0
  202. package/src/primitives/actionBarMore/ActionBarMoreSeparator.tsx +32 -0
  203. package/src/primitives/actionBarMore/ActionBarMoreTrigger.tsx +31 -0
  204. package/src/primitives/actionBarMore/index.ts +5 -0
  205. package/src/primitives/actionBarMore/scope.tsx +8 -0
  206. package/src/primitives/composer/ComposerDictate.tsx +48 -0
  207. package/src/primitives/composer/ComposerDictationTranscript.tsx +45 -0
  208. package/src/primitives/composer/ComposerIf.tsx +7 -0
  209. package/src/primitives/composer/ComposerInput.tsx +4 -1
  210. package/src/primitives/composer/ComposerStopDictation.tsx +45 -0
  211. package/src/primitives/composer/index.ts +3 -0
  212. package/src/primitives/index.ts +2 -0
  213. package/src/primitives/threadListItemMore/ThreadListItemMoreContent.tsx +47 -0
  214. package/src/primitives/threadListItemMore/ThreadListItemMoreItem.tsx +32 -0
  215. package/src/primitives/threadListItemMore/ThreadListItemMoreRoot.tsx +23 -0
  216. package/src/primitives/threadListItemMore/ThreadListItemMoreSeparator.tsx +32 -0
  217. package/src/primitives/threadListItemMore/ThreadListItemMoreTrigger.tsx +32 -0
  218. package/src/primitives/threadListItemMore/index.ts +5 -0
  219. package/src/primitives/threadListItemMore/scope.tsx +8 -0
@@ -1,16 +1,18 @@
1
- import {
1
+ import type {
2
2
  Attachment,
3
3
  CompleteAttachment,
4
4
  PendingAttachment,
5
5
  } from "../../../types/AttachmentTypes";
6
- import { AppendMessage } from "../../../types";
7
- import { AttachmentAdapter } from "../adapters/attachment";
8
- import {
6
+ import type { AppendMessage, Unsubscribe } from "../../../types";
7
+ import type { AttachmentAdapter } from "../adapters/attachment";
8
+ import type {
9
9
  ComposerRuntimeCore,
10
10
  ComposerRuntimeEventType,
11
+ DictationState,
11
12
  } from "../core/ComposerRuntimeCore";
12
- import { MessageRole, RunConfig } from "../../../types/AssistantTypes";
13
+ import type { MessageRole, RunConfig } from "../../../types/AssistantTypes";
13
14
  import { BaseSubscribable } from "../remote-thread-list/BaseSubscribable";
15
+ import type { DictationAdapter } from "../adapters/speech/SpeechAdapterTypes";
14
16
 
15
17
  const isAttachmentComplete = (a: Attachment): a is CompleteAttachment =>
16
18
  a.status.type === "complete";
@@ -22,6 +24,7 @@ export abstract class BaseComposerRuntimeCore
22
24
  public readonly isEditing = true;
23
25
 
24
26
  protected abstract getAttachmentAdapter(): AttachmentAdapter | undefined;
27
+ protected abstract getDictationAdapter(): DictationAdapter | undefined;
25
28
 
26
29
  public get attachmentAccept(): string {
27
30
  return this.getAttachmentAdapter()?.accept ?? "*";
@@ -65,6 +68,15 @@ export abstract class BaseComposerRuntimeCore
65
68
  if (this._text === value) return;
66
69
 
67
70
  this._text = value;
71
+ // When dictation is active and the user manually edits the composer text,
72
+ // treat the new text as the updated base so speech results are appended
73
+ // instead of overwriting manual edits.
74
+ if (this._dictation) {
75
+ this._dictationBaseText = value;
76
+ this._currentInterimText = "";
77
+ const { status, inputDisabled } = this._dictation;
78
+ this._dictation = inputDisabled ? { status, inputDisabled } : { status };
79
+ }
68
80
  this._notifySubscribers();
69
81
  }
70
82
 
@@ -121,6 +133,11 @@ export abstract class BaseComposerRuntimeCore
121
133
  }
122
134
 
123
135
  public async send() {
136
+ if (this._dictationSession) {
137
+ this._dictationSession.cancel();
138
+ this._cleanupDictation();
139
+ }
140
+
124
141
  const adapter = this.getAttachmentAdapter();
125
142
  const attachments =
126
143
  adapter && this.attachments.length > 0
@@ -209,6 +226,155 @@ export abstract class BaseComposerRuntimeCore
209
226
  this._notifySubscribers();
210
227
  }
211
228
 
229
+ private _dictation: DictationState | undefined;
230
+ private _dictationSession: DictationAdapter.Session | undefined;
231
+ private _dictationUnsubscribes: Unsubscribe[] = [];
232
+ private _dictationBaseText = "";
233
+ private _currentInterimText = "";
234
+ private _dictationSessionIdCounter = 0;
235
+ private _activeDictationSessionId: number | undefined;
236
+ private _isCleaningDictation = false;
237
+
238
+ public get dictation(): DictationState | undefined {
239
+ return this._dictation;
240
+ }
241
+
242
+ private _isActiveSession(
243
+ sessionId: number,
244
+ session: DictationAdapter.Session,
245
+ ): boolean {
246
+ return (
247
+ this._activeDictationSessionId === sessionId &&
248
+ this._dictationSession === session
249
+ );
250
+ }
251
+
252
+ public startDictation(): void {
253
+ const adapter = this.getDictationAdapter();
254
+ if (!adapter) {
255
+ throw new Error("Dictation adapter not configured");
256
+ }
257
+
258
+ if (this._dictationSession) {
259
+ for (const unsub of this._dictationUnsubscribes) {
260
+ unsub();
261
+ }
262
+ this._dictationUnsubscribes = [];
263
+ const oldSession = this._dictationSession;
264
+ oldSession.stop().catch(() => {});
265
+ this._dictationSession = undefined;
266
+ }
267
+
268
+ const inputDisabled = adapter.disableInputDuringDictation ?? false;
269
+
270
+ this._dictationBaseText = this._text;
271
+ this._currentInterimText = "";
272
+
273
+ const session = adapter.listen();
274
+ this._dictationSession = session;
275
+ const sessionId = ++this._dictationSessionIdCounter;
276
+ this._activeDictationSessionId = sessionId;
277
+ this._dictation = { status: session.status, inputDisabled };
278
+ this._notifySubscribers();
279
+
280
+ const unsubSpeech = session.onSpeech((result) => {
281
+ if (!this._isActiveSession(sessionId, session)) return;
282
+ const isFinal = result.isFinal !== false;
283
+
284
+ const needsSeparator =
285
+ this._dictationBaseText &&
286
+ !this._dictationBaseText.endsWith(" ") &&
287
+ result.transcript;
288
+ const separator = needsSeparator ? " " : "";
289
+
290
+ if (isFinal) {
291
+ this._dictationBaseText =
292
+ this._dictationBaseText + separator + result.transcript;
293
+ this._currentInterimText = "";
294
+ this._text = this._dictationBaseText;
295
+
296
+ if (this._dictation) {
297
+ const { transcript: _, ...rest } = this._dictation;
298
+ this._dictation = rest;
299
+ }
300
+ this._notifySubscribers();
301
+ } else {
302
+ this._currentInterimText = separator + result.transcript;
303
+ this._text = this._dictationBaseText + this._currentInterimText;
304
+
305
+ if (this._dictation) {
306
+ this._dictation = {
307
+ ...this._dictation,
308
+ transcript: result.transcript,
309
+ };
310
+ }
311
+ this._notifySubscribers();
312
+ }
313
+ });
314
+ this._dictationUnsubscribes.push(unsubSpeech);
315
+
316
+ const unsubStart = session.onSpeechStart(() => {
317
+ if (!this._isActiveSession(sessionId, session)) return;
318
+
319
+ this._dictation = {
320
+ status: { type: "running" },
321
+ inputDisabled,
322
+ ...(this._dictation?.transcript && {
323
+ transcript: this._dictation.transcript,
324
+ }),
325
+ };
326
+ this._notifySubscribers();
327
+ });
328
+ this._dictationUnsubscribes.push(unsubStart);
329
+
330
+ const unsubEnd = session.onSpeechEnd(() => {
331
+ this._cleanupDictation({ sessionId });
332
+ });
333
+ this._dictationUnsubscribes.push(unsubEnd);
334
+
335
+ const statusInterval = setInterval(() => {
336
+ if (!this._isActiveSession(sessionId, session)) return;
337
+
338
+ if (session.status.type === "ended") {
339
+ this._cleanupDictation({ sessionId });
340
+ }
341
+ }, 100);
342
+ this._dictationUnsubscribes.push(() => clearInterval(statusInterval));
343
+ }
344
+
345
+ public stopDictation(): void {
346
+ if (!this._dictationSession) return;
347
+
348
+ const session = this._dictationSession;
349
+ const sessionId = this._activeDictationSessionId;
350
+ session.stop().finally(() => {
351
+ this._cleanupDictation({ sessionId });
352
+ });
353
+ }
354
+
355
+ private _cleanupDictation(options?: { sessionId: number | undefined }): void {
356
+ const isStaleSession =
357
+ options?.sessionId !== undefined &&
358
+ options.sessionId !== this._activeDictationSessionId;
359
+ if (isStaleSession || this._isCleaningDictation) return;
360
+
361
+ this._isCleaningDictation = true;
362
+ try {
363
+ for (const unsub of this._dictationUnsubscribes) {
364
+ unsub();
365
+ }
366
+ this._dictationUnsubscribes = [];
367
+ this._dictationSession = undefined;
368
+ this._activeDictationSessionId = undefined;
369
+ this._dictation = undefined;
370
+ this._dictationBaseText = "";
371
+ this._currentInterimText = "";
372
+ this._notifySubscribers();
373
+ } finally {
374
+ this._isCleaningDictation = false;
375
+ }
376
+ }
377
+
212
378
  private _eventSubscribers = new Map<
213
379
  ComposerRuntimeEventType,
214
380
  Set<() => void>
@@ -1,7 +1,8 @@
1
- import { AppendMessage, ThreadMessage } from "../../../types";
1
+ import type { AppendMessage, ThreadMessage } from "../../../types";
2
2
  import { getThreadMessageText } from "../../../utils/getThreadMessageText";
3
- import { AttachmentAdapter } from "../adapters/attachment";
4
- import { ThreadRuntimeCore } from "../core/ThreadRuntimeCore";
3
+ import type { AttachmentAdapter } from "../adapters/attachment";
4
+ import type { DictationAdapter } from "../adapters/speech/SpeechAdapterTypes";
5
+ import type { ThreadRuntimeCore } from "../core/ThreadRuntimeCore";
5
6
  import { BaseComposerRuntimeCore } from "./BaseComposerRuntimeCore";
6
7
 
7
8
  export class DefaultEditComposerRuntimeCore extends BaseComposerRuntimeCore {
@@ -13,13 +14,22 @@ export class DefaultEditComposerRuntimeCore extends BaseComposerRuntimeCore {
13
14
  return this.runtime.adapters?.attachments;
14
15
  }
15
16
 
17
+ protected getDictationAdapter() {
18
+ return this.runtime.adapters?.dictation;
19
+ }
20
+
16
21
  private _nonTextParts;
17
22
  private _previousText;
18
23
  private _parentId;
19
24
  private _sourceId;
20
25
  constructor(
21
26
  private runtime: ThreadRuntimeCore & {
22
- adapters?: { attachments?: AttachmentAdapter | undefined } | undefined;
27
+ adapters?:
28
+ | {
29
+ attachments?: AttachmentAdapter | undefined;
30
+ dictation?: DictationAdapter | undefined;
31
+ }
32
+ | undefined;
23
33
  },
24
34
  private endEditCallback: () => void,
25
35
  { parentId, message }: { parentId: string | null; message: ThreadMessage },
@@ -1,7 +1,8 @@
1
- import { AppendMessage, PendingAttachment } from "../../../types";
2
- import { AttachmentAdapter } from "../adapters/attachment";
3
- import { ThreadComposerRuntimeCore } from "../core/ComposerRuntimeCore";
4
- import { ThreadRuntimeCore } from "../core/ThreadRuntimeCore";
1
+ import type { AppendMessage, PendingAttachment } from "../../../types";
2
+ import type { AttachmentAdapter } from "../adapters/attachment";
3
+ import type { DictationAdapter } from "../adapters/speech/SpeechAdapterTypes";
4
+ import type { ThreadComposerRuntimeCore } from "../core/ComposerRuntimeCore";
5
+ import type { ThreadRuntimeCore } from "../core/ThreadRuntimeCore";
5
6
  import { BaseComposerRuntimeCore } from "./BaseComposerRuntimeCore";
6
7
 
7
8
  export class DefaultThreadComposerRuntimeCore
@@ -21,9 +22,18 @@ export class DefaultThreadComposerRuntimeCore
21
22
  return this.runtime.adapters?.attachments;
22
23
  }
23
24
 
25
+ protected getDictationAdapter() {
26
+ return this.runtime.adapters?.dictation;
27
+ }
28
+
24
29
  constructor(
25
30
  private runtime: Omit<ThreadRuntimeCore, "composer"> & {
26
- adapters?: { attachments?: AttachmentAdapter | undefined } | undefined;
31
+ adapters?:
32
+ | {
33
+ attachments?: AttachmentAdapter | undefined;
34
+ dictation?: DictationAdapter | undefined;
35
+ }
36
+ | undefined;
27
37
  },
28
38
  ) {
29
39
  super();
@@ -3,10 +3,31 @@ import type {
3
3
  PendingAttachment,
4
4
  Unsubscribe,
5
5
  } from "../../../types";
6
- import { MessageRole, RunConfig } from "../../../types/AssistantTypes";
6
+ import type { MessageRole, RunConfig } from "../../../types/AssistantTypes";
7
+ import type { DictationAdapter } from "../adapters/speech/SpeechAdapterTypes";
7
8
 
8
9
  export type ComposerRuntimeEventType = "send" | "attachment-add";
9
10
 
11
+ /**
12
+ * State representing an active dictation session.
13
+ */
14
+ export type DictationState = {
15
+ readonly status: DictationAdapter.Status;
16
+ /**
17
+ * The current interim (partial) transcript being recognized.
18
+ * This is a preview of what the user is saying and may change
19
+ * as dictation refines its prediction.
20
+ *
21
+ * Note: By default, interim transcripts are shown directly in the composer
22
+ * input field (like native dictation). This property is provided for
23
+ * advanced customization when you want to display or style the interim
24
+ * transcript separately.
25
+ */
26
+ readonly transcript?: string;
27
+ /** Whether text input is disabled during this dictation session. */
28
+ readonly inputDisabled?: boolean;
29
+ };
30
+
10
31
  export type ComposerRuntimeCore = Readonly<{
11
32
  isEditing: boolean;
12
33
 
@@ -34,6 +55,23 @@ export type ComposerRuntimeCore = Readonly<{
34
55
  send: () => void;
35
56
  cancel: () => void;
36
57
 
58
+ /**
59
+ * The current state of dictation.
60
+ * Undefined when dictation is not active.
61
+ */
62
+ dictation: DictationState | undefined;
63
+
64
+ /**
65
+ * Start dictation to convert voice to text input.
66
+ * Requires a DictationAdapter to be configured.
67
+ */
68
+ startDictation: () => void;
69
+
70
+ /**
71
+ * Stop the current dictation session.
72
+ */
73
+ stopDictation: () => void;
74
+
37
75
  subscribe: (callback: () => void) => Unsubscribe;
38
76
 
39
77
  unstable_on: (
@@ -20,6 +20,7 @@ export type RuntimeCapabilities = {
20
20
  readonly cancel: boolean;
21
21
  readonly unstable_copy: boolean;
22
22
  readonly speech: boolean;
23
+ readonly dictation: boolean;
23
24
  readonly attachments: boolean;
24
25
  readonly feedback: boolean;
25
26
  };
@@ -3,3 +3,5 @@ export type {
3
3
  SubmitFeedbackOptions,
4
4
  ThreadSuggestion,
5
5
  } from "./ThreadRuntimeCore";
6
+
7
+ export type { DictationState } from "./ComposerRuntimeCore";
@@ -1,15 +1,18 @@
1
- import { AppendMessage, ThreadMessage } from "../../../types";
2
- import { AttachmentAdapter } from "../adapters/attachment";
3
- import {
1
+ import type { AppendMessage, ThreadMessage } from "../../../types";
2
+ import type { AttachmentAdapter } from "../adapters/attachment";
3
+ import type {
4
4
  AddToolResultOptions,
5
5
  ResumeRunConfig,
6
6
  StartRunConfig,
7
7
  ThreadSuggestion,
8
8
  } from "../core/ThreadRuntimeCore";
9
- import { FeedbackAdapter } from "../adapters/feedback/FeedbackAdapter";
10
- import { SpeechSynthesisAdapter } from "../adapters/speech/SpeechAdapterTypes";
11
- import { ThreadMessageLike } from "./ThreadMessageLike";
12
- import { ExportedMessageRepository } from "../utils/MessageRepository";
9
+ import type { FeedbackAdapter } from "../adapters/feedback/FeedbackAdapter";
10
+ import type {
11
+ SpeechSynthesisAdapter,
12
+ DictationAdapter,
13
+ } from "../adapters/speech/SpeechAdapterTypes";
14
+ import type { ThreadMessageLike } from "./ThreadMessageLike";
15
+ import type { ExportedMessageRepository } from "../utils/MessageRepository";
13
16
  import type { ReadonlyJSONValue } from "assistant-stream/utils";
14
17
 
15
18
  export type ExternalStoreThreadData<TState extends "regular" | "archived"> = {
@@ -85,6 +88,7 @@ type ExternalStoreAdapterBase<T> = {
85
88
  | {
86
89
  attachments?: AttachmentAdapter | undefined;
87
90
  speech?: SpeechSynthesisAdapter | undefined;
91
+ dictation?: DictationAdapter | undefined;
88
92
  feedback?: FeedbackAdapter | undefined;
89
93
  /**
90
94
  * @deprecated This API is still under active development and might change without notice.
@@ -1,4 +1,4 @@
1
- import {
1
+ import type {
2
2
  AddToolResultOptions,
3
3
  ResumeRunConfig,
4
4
  ResumeToolCallOptions,
@@ -6,22 +6,25 @@ import {
6
6
  ThreadSuggestion,
7
7
  } from "../core/ThreadRuntimeCore";
8
8
 
9
- import { AppendMessage, ThreadMessage } from "../../../types";
10
- import { ExternalStoreAdapter } from "./ExternalStoreAdapter";
9
+ import type { AppendMessage, ThreadMessage } from "../../../types";
10
+ import type { ExternalStoreAdapter } from "./ExternalStoreAdapter";
11
11
  import {
12
12
  getExternalStoreMessage,
13
13
  symbolInnerMessage,
14
14
  } from "./getExternalStoreMessage";
15
15
  import { ThreadMessageConverter } from "./ThreadMessageConverter";
16
16
  import { getAutoStatus, isAutoStatus } from "./auto-status";
17
- import { fromThreadMessageLike, ThreadMessageLike } from "./ThreadMessageLike";
18
- import { getThreadMessageText } from "../../../utils/getThreadMessageText";
19
17
  import {
18
+ fromThreadMessageLike,
19
+ type ThreadMessageLike,
20
+ } from "./ThreadMessageLike";
21
+ import { getThreadMessageText } from "../../../utils/getThreadMessageText";
22
+ import type {
20
23
  RuntimeCapabilities,
21
24
  ThreadRuntimeCore,
22
25
  } from "../core/ThreadRuntimeCore";
23
26
  import { BaseThreadRuntimeCore } from "../core/BaseThreadRuntimeCore";
24
- import { ModelContextProvider } from "../../../model-context";
27
+ import type { ModelContextProvider } from "../../../model-context";
25
28
  import {
26
29
  ExportedMessageRepository,
27
30
  MessageRepository,
@@ -50,6 +53,7 @@ export class ExternalStoreThreadRuntimeCore
50
53
  cancel: false,
51
54
  unstable_copy: false,
52
55
  speech: false,
56
+ dictation: false,
53
57
  attachments: false,
54
58
  feedback: false,
55
59
  };
@@ -115,6 +119,7 @@ export class ExternalStoreThreadRuntimeCore
115
119
  reload: this._store.onReload !== undefined,
116
120
  cancel: this._store.onCancel !== undefined,
117
121
  speech: this._store.adapters?.speech !== undefined,
122
+ dictation: this._store.adapters?.dictation !== undefined,
118
123
  unstable_copy: this._store.unstable_capabilities?.copy !== false, // default true
119
124
  attachments: !!this._store.adapters?.attachments,
120
125
  feedback: !!this._store.adapters?.feedback,
@@ -161,7 +166,7 @@ export class ExternalStoreThreadRuntimeCore
161
166
  : this._converter.convertMessages(store.messages, (cache, m, idx) => {
162
167
  if (!store.convertMessage) return m;
163
168
 
164
- const isLast = idx === store.messages!.length - 1;
169
+ const isLast = idx === (store.messages?.length ?? 0) - 1;
165
170
  const autoStatus = getAutoStatus(
166
171
  isLast,
167
172
  isRunning,
@@ -1,11 +1,14 @@
1
- import { ThreadHistoryAdapter } from "../adapters/thread-history/ThreadHistoryAdapter";
2
- import { AttachmentAdapter } from "../adapters/attachment/AttachmentAdapter";
3
- import { ThreadMessageLike } from "../external-store";
4
- import { FeedbackAdapter } from "../adapters/feedback/FeedbackAdapter";
5
- import { SpeechSynthesisAdapter } from "../adapters/speech/SpeechAdapterTypes";
6
- import { ChatModelAdapter } from "./ChatModelAdapter";
7
- import { AssistantCloud } from "assistant-cloud";
8
- import { SuggestionAdapter } from "../adapters";
1
+ import type { ThreadHistoryAdapter } from "../adapters/thread-history/ThreadHistoryAdapter";
2
+ import type { AttachmentAdapter } from "../adapters/attachment/AttachmentAdapter";
3
+ import type { ThreadMessageLike } from "../external-store";
4
+ import type { FeedbackAdapter } from "../adapters/feedback/FeedbackAdapter";
5
+ import type {
6
+ SpeechSynthesisAdapter,
7
+ DictationAdapter,
8
+ } from "../adapters/speech/SpeechAdapterTypes";
9
+ import type { ChatModelAdapter } from "./ChatModelAdapter";
10
+ import type { AssistantCloud } from "assistant-cloud";
11
+ import type { SuggestionAdapter } from "../adapters";
9
12
 
10
13
  export type LocalRuntimeOptionsBase = {
11
14
  maxSteps?: number | undefined;
@@ -14,6 +17,7 @@ export type LocalRuntimeOptionsBase = {
14
17
  history?: ThreadHistoryAdapter | undefined;
15
18
  attachments?: AttachmentAdapter | undefined;
16
19
  speech?: SpeechSynthesisAdapter | undefined;
20
+ dictation?: DictationAdapter | undefined;
17
21
  feedback?: FeedbackAdapter | undefined;
18
22
  suggestion?: SuggestionAdapter | undefined;
19
23
  };
@@ -2,8 +2,8 @@ import { fromThreadMessageLike, generateId } from "../../../internal";
2
2
  import type { AppendMessage, ThreadAssistantMessage } from "../../../types";
3
3
  import type { ChatModelAdapter, ChatModelRunResult } from "./ChatModelAdapter";
4
4
  import { shouldContinue } from "./shouldContinue";
5
- import { LocalRuntimeOptionsBase } from "./LocalRuntimeOptions";
6
- import {
5
+ import type { LocalRuntimeOptionsBase } from "./LocalRuntimeOptions";
6
+ import type {
7
7
  AddToolResultOptions,
8
8
  ResumeToolCallOptions,
9
9
  ThreadSuggestion,
@@ -12,8 +12,8 @@ import {
12
12
  ResumeRunConfig,
13
13
  } from "../core/ThreadRuntimeCore";
14
14
  import { BaseThreadRuntimeCore } from "../core/BaseThreadRuntimeCore";
15
- import { RunConfig } from "../../../types/AssistantTypes";
16
- import { ModelContextProvider } from "../../../model-context";
15
+ import type { RunConfig } from "../../../types/AssistantTypes";
16
+ import type { ModelContextProvider } from "../../../model-context";
17
17
 
18
18
  class AbortError extends Error {
19
19
  override name = "AbortError";
@@ -37,6 +37,7 @@ export class LocalThreadRuntimeCore
37
37
  cancel: true,
38
38
  unstable_copy: true,
39
39
  speech: false,
40
+ dictation: false,
40
41
  attachments: false,
41
42
  feedback: false,
42
43
  };
@@ -89,6 +90,12 @@ export class LocalThreadRuntimeCore
89
90
  hasUpdates = true;
90
91
  }
91
92
 
93
+ const canDictate = options.adapters?.dictation !== undefined;
94
+ if (this.capabilities.dictation !== canDictate) {
95
+ this.capabilities.dictation = canDictate;
96
+ hasUpdates = true;
97
+ }
98
+
92
99
  const canAttach = options.adapters?.attachments !== undefined;
93
100
  if (this.capabilities.attachments !== canAttach) {
94
101
  this.capabilities.attachments = canAttach;
@@ -1,4 +1,4 @@
1
- import { ThreadRuntimeCore } from "../../../internal";
1
+ import type { ThreadRuntimeCore } from "../../../internal";
2
2
 
3
3
  const EMPTY_THREAD_ERROR = new Error(
4
4
  "This is the empty thread, a placeholder for the main thread. You cannot perform any actions on this thread instance. This error is probably because you tried to call a thread method in your render function. Call the method inside a `useEffect` hook instead.",
@@ -111,6 +111,16 @@ export const EMPTY_THREAD_CORE: ThreadRuntimeCore = {
111
111
  // noop
112
112
  },
113
113
 
114
+ dictation: undefined,
115
+
116
+ startDictation() {
117
+ throw EMPTY_THREAD_ERROR;
118
+ },
119
+
120
+ stopDictation() {
121
+ // noop
122
+ },
123
+
114
124
  subscribe() {
115
125
  return () => {};
116
126
  },
@@ -138,6 +148,7 @@ export const EMPTY_THREAD_CORE: ThreadRuntimeCore = {
138
148
  cancel: false,
139
149
  unstable_copy: false,
140
150
  speech: false,
151
+ dictation: false,
141
152
  attachments: false,
142
153
  feedback: false,
143
154
  },
@@ -114,10 +114,20 @@ export const useCloudThreadListAdapter = (
114
114
  },
115
115
 
116
116
  generateTitle: async (threadId, messages) => {
117
+ // Filter messages to only include content types the title generator understands
118
+ // (reasoning, source, etc. are not needed for title generation)
119
+ // TODO serialize these to a more efficient format
120
+ const filteredMessages = messages.map((msg) => ({
121
+ ...msg,
122
+ content: msg.content.filter(
123
+ (part) => part.type === "text" || part.type === "tool-call",
124
+ ),
125
+ }));
126
+
117
127
  return cloud.runs.stream({
118
128
  thread_id: threadId,
119
129
  assistant_id: "system/thread_title",
120
- messages: messages, // TODO serialize these to a more efficient format
130
+ messages: filteredMessages,
121
131
  });
122
132
  },
123
133
 
@@ -0,0 +1,46 @@
1
+ "use client";
2
+
3
+ import { ComponentPropsWithoutRef, ComponentRef, forwardRef } from "react";
4
+ import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
5
+ import { ScopedProps, useDropdownMenuScope } from "./scope";
6
+
7
+ export namespace ActionBarMorePrimitiveContent {
8
+ export type Element = ComponentRef<typeof DropdownMenuPrimitive.Content>;
9
+ export type Props = ComponentPropsWithoutRef<
10
+ typeof DropdownMenuPrimitive.Content
11
+ > & {
12
+ portalProps?:
13
+ | ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Portal>
14
+ | undefined;
15
+ };
16
+ }
17
+
18
+ export const ActionBarMorePrimitiveContent = forwardRef<
19
+ ActionBarMorePrimitiveContent.Element,
20
+ ActionBarMorePrimitiveContent.Props
21
+ >(
22
+ (
23
+ {
24
+ __scopeActionBarMore,
25
+ portalProps,
26
+ sideOffset = 4,
27
+ ...props
28
+ }: ScopedProps<ActionBarMorePrimitiveContent.Props>,
29
+ forwardedRef,
30
+ ) => {
31
+ const scope = useDropdownMenuScope(__scopeActionBarMore);
32
+
33
+ return (
34
+ <DropdownMenuPrimitive.Portal {...scope} {...portalProps}>
35
+ <DropdownMenuPrimitive.Content
36
+ {...scope}
37
+ {...props}
38
+ ref={forwardedRef}
39
+ sideOffset={sideOffset}
40
+ />
41
+ </DropdownMenuPrimitive.Portal>
42
+ );
43
+ },
44
+ );
45
+
46
+ ActionBarMorePrimitiveContent.displayName = "ActionBarMorePrimitive.Content";
@@ -0,0 +1,31 @@
1
+ "use client";
2
+
3
+ import { ComponentPropsWithoutRef, ComponentRef, forwardRef } from "react";
4
+ import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
5
+ import { ScopedProps, useDropdownMenuScope } from "./scope";
6
+
7
+ export namespace ActionBarMorePrimitiveItem {
8
+ export type Element = ComponentRef<typeof DropdownMenuPrimitive.Item>;
9
+ export type Props = ComponentPropsWithoutRef<
10
+ typeof DropdownMenuPrimitive.Item
11
+ >;
12
+ }
13
+
14
+ export const ActionBarMorePrimitiveItem = forwardRef<
15
+ ActionBarMorePrimitiveItem.Element,
16
+ ActionBarMorePrimitiveItem.Props
17
+ >(
18
+ (
19
+ {
20
+ __scopeActionBarMore,
21
+ ...rest
22
+ }: ScopedProps<ActionBarMorePrimitiveItem.Props>,
23
+ ref,
24
+ ) => {
25
+ const scope = useDropdownMenuScope(__scopeActionBarMore);
26
+
27
+ return <DropdownMenuPrimitive.Item {...scope} {...rest} ref={ref} />;
28
+ },
29
+ );
30
+
31
+ ActionBarMorePrimitiveItem.displayName = "ActionBarMorePrimitive.Item";