@arbidocs/blocks 0.4.2 → 0.4.4

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 (156) hide show
  1. package/README.md +42 -0
  2. package/dist/agents/definitions/AgentCreator.d.ts +11 -2
  3. package/dist/agents/definitions/index.d.ts +1 -0
  4. package/dist/agents/definitions/persona.d.ts +16 -0
  5. package/dist/agents/index.cjs +199 -146
  6. package/dist/agents/index.js +3 -2
  7. package/dist/agents/tasks/TaskRunsDialog.d.ts +15 -3
  8. package/dist/agents/tasks/index.d.ts +1 -0
  9. package/dist/agents/tasks/taskRequest.d.ts +61 -0
  10. package/dist/chat/AssistantDock.d.ts +39 -0
  11. package/dist/chat/ChatDocuments.d.ts +17 -0
  12. package/dist/chat/ChatPage.d.ts +16 -0
  13. package/dist/chat/ChatThreads.d.ts +28 -0
  14. package/dist/chat/chat-page-types.d.ts +121 -0
  15. package/dist/chat/chat-surface.d.ts +9 -0
  16. package/dist/chat/index.cjs +247 -205
  17. package/dist/chat/index.d.ts +6 -0
  18. package/dist/chat/index.js +4 -2
  19. package/dist/{chunk-OBLSURHV.js → chunk-2NNTQLBY.js} +3 -3
  20. package/dist/{chunk-OBLSURHV.js.map → chunk-2NNTQLBY.js.map} +1 -1
  21. package/dist/chunk-2VBJ763Y.js +296 -0
  22. package/dist/chunk-2VBJ763Y.js.map +1 -0
  23. package/dist/{chunk-2ORA62OF.js → chunk-67MKU5U7.js} +3 -3
  24. package/dist/{chunk-2ORA62OF.js.map → chunk-67MKU5U7.js.map} +1 -1
  25. package/dist/{chunk-AE5FHFZ5.cjs → chunk-6CHMNKXC.cjs} +6 -6
  26. package/dist/{chunk-AE5FHFZ5.cjs.map → chunk-6CHMNKXC.cjs.map} +1 -1
  27. package/dist/{chunk-TYZUCAT7.js → chunk-7YADKWZT.js} +43 -6
  28. package/dist/chunk-7YADKWZT.js.map +1 -0
  29. package/dist/chunk-ATXPAD6S.cjs +1952 -0
  30. package/dist/chunk-ATXPAD6S.cjs.map +1 -0
  31. package/dist/{chunk-YBXCZEWS.js → chunk-B673CCW5.js} +29 -6
  32. package/dist/chunk-B673CCW5.js.map +1 -0
  33. package/dist/{chunk-ITGHMJOM.js → chunk-BBEMPS6C.js} +169 -26
  34. package/dist/chunk-BBEMPS6C.js.map +1 -0
  35. package/dist/{chunk-XNBAXRY7.cjs → chunk-DGVKBOY5.cjs} +188 -32
  36. package/dist/chunk-DGVKBOY5.cjs.map +1 -0
  37. package/dist/{chunk-2K33YGM6.cjs → chunk-DN3NFNIA.cjs} +63 -294
  38. package/dist/chunk-DN3NFNIA.cjs.map +1 -0
  39. package/dist/{chunk-XQ7PKKDY.cjs → chunk-G4YOH5DU.cjs} +3 -3
  40. package/dist/{chunk-XQ7PKKDY.cjs.map → chunk-G4YOH5DU.cjs.map} +1 -1
  41. package/dist/{chunk-AXIZ2MDV.js → chunk-HER7MTRR.js} +3 -3
  42. package/dist/{chunk-AXIZ2MDV.js.map → chunk-HER7MTRR.js.map} +1 -1
  43. package/dist/{chunk-SYDHKKRZ.cjs → chunk-IZHWP6WQ.cjs} +47 -5
  44. package/dist/chunk-IZHWP6WQ.cjs.map +1 -0
  45. package/dist/chunk-JPO3F4J7.js +1899 -0
  46. package/dist/chunk-JPO3F4J7.js.map +1 -0
  47. package/dist/{chunk-WJMEXTVD.cjs → chunk-KDG6FER6.cjs} +28 -2
  48. package/dist/chunk-KDG6FER6.cjs.map +1 -0
  49. package/dist/chunk-KHX2BX3S.cjs +307 -0
  50. package/dist/chunk-KHX2BX3S.cjs.map +1 -0
  51. package/dist/{chunk-WTNMWEBC.js → chunk-NJL4LIXX.js} +4 -3
  52. package/dist/chunk-NJL4LIXX.js.map +1 -0
  53. package/dist/{chunk-J2BGSWXM.cjs → chunk-O637DUKS.cjs} +27 -27
  54. package/dist/{chunk-J2BGSWXM.cjs.map → chunk-O637DUKS.cjs.map} +1 -1
  55. package/dist/{chunk-WW6EOVZA.js → chunk-OXF2IFXG.js} +26 -3
  56. package/dist/chunk-OXF2IFXG.js.map +1 -0
  57. package/dist/{chunk-6HIPFEID.cjs → chunk-PBS5MFIY.cjs} +4 -4
  58. package/dist/{chunk-6HIPFEID.cjs.map → chunk-PBS5MFIY.cjs.map} +1 -1
  59. package/dist/{chunk-AZQDNYH4.js → chunk-RCP6THBS.js} +9 -1249
  60. package/dist/chunk-RCP6THBS.js.map +1 -0
  61. package/dist/{chunk-GDFWJ73C.cjs → chunk-RIL7G7AS.cjs} +4 -1286
  62. package/dist/chunk-RIL7G7AS.cjs.map +1 -0
  63. package/dist/{chunk-DREI7EQ2.cjs → chunk-SS23F63U.cjs} +9 -9
  64. package/dist/{chunk-DREI7EQ2.cjs.map → chunk-SS23F63U.cjs.map} +1 -1
  65. package/dist/{chunk-7PEELPMA.js → chunk-TI4UTYRL.js} +62 -285
  66. package/dist/chunk-TI4UTYRL.js.map +1 -0
  67. package/dist/{chunk-6P6AEQJB.js → chunk-WJZBJUPX.js} +4 -4
  68. package/dist/{chunk-6P6AEQJB.js.map → chunk-WJZBJUPX.js.map} +1 -1
  69. package/dist/{chunk-UFHMLHIR.cjs → chunk-XAJIKT6Y.cjs} +32 -11
  70. package/dist/chunk-XAJIKT6Y.cjs.map +1 -0
  71. package/dist/{chunk-G3G7LZPM.cjs → chunk-XKKGGUU2.cjs} +29 -3
  72. package/dist/chunk-XKKGGUU2.cjs.map +1 -0
  73. package/dist/{chunk-UWGIB3VQ.js → chunk-XNOASBGW.js} +33 -12
  74. package/dist/chunk-XNOASBGW.js.map +1 -0
  75. package/dist/{chunk-CTZ5745I.js → chunk-XQKGYGCJ.js} +3 -3
  76. package/dist/{chunk-CTZ5745I.js.map → chunk-XQKGYGCJ.js.map} +1 -1
  77. package/dist/{chunk-54Q3RNJU.cjs → chunk-ZVPTFTGV.cjs} +4 -3
  78. package/dist/chunk-ZVPTFTGV.cjs.map +1 -0
  79. package/dist/citations/index.cjs +11 -11
  80. package/dist/citations/index.js +2 -2
  81. package/dist/collaboration/contacts/AddContactsParts.d.ts +9 -4
  82. package/dist/collaboration/contacts/index.d.ts +1 -0
  83. package/dist/collaboration/contacts/parseEmails.d.ts +26 -0
  84. package/dist/collaboration/index.cjs +51 -31
  85. package/dist/collaboration/index.js +1 -1
  86. package/dist/components/MemberAvatarStack.d.ts +7 -2
  87. package/dist/connect/index.cjs +41 -12
  88. package/dist/connect/index.cjs.map +1 -1
  89. package/dist/connect/index.d.ts +3 -2
  90. package/dist/connect/index.js +20 -4
  91. package/dist/connect/index.js.map +1 -1
  92. package/dist/connection/ConnectionProvider.d.ts +2 -0
  93. package/dist/connection/ai.d.ts +13 -1
  94. package/dist/connection/useConnectedShellWorkspaces.d.ts +15 -0
  95. package/dist/facts/index.cjs +3 -3
  96. package/dist/facts/index.cjs.map +1 -1
  97. package/dist/facts/index.js +2 -2
  98. package/dist/facts/index.js.map +1 -1
  99. package/dist/files/index.cjs +4 -3
  100. package/dist/files/index.cjs.map +1 -1
  101. package/dist/files/index.js +4 -3
  102. package/dist/files/index.js.map +1 -1
  103. package/dist/home/index.cjs +18 -17
  104. package/dist/home/index.cjs.map +1 -1
  105. package/dist/home/index.js +3 -2
  106. package/dist/home/index.js.map +1 -1
  107. package/dist/index.cjs +824 -695
  108. package/dist/index.cjs.map +1 -1
  109. package/dist/index.d.ts +1 -1
  110. package/dist/index.js +16 -15
  111. package/dist/index.js.map +1 -1
  112. package/dist/lib/format.d.ts +31 -0
  113. package/dist/retrieval/index.cjs +36 -36
  114. package/dist/retrieval/index.js +1 -1
  115. package/dist/settings/index.cjs +13 -11
  116. package/dist/settings/index.cjs.map +1 -1
  117. package/dist/settings/index.js +13 -11
  118. package/dist/settings/index.js.map +1 -1
  119. package/dist/shell/SplitLayout.d.ts +32 -0
  120. package/dist/shell/index.cjs +72 -68
  121. package/dist/shell/index.d.ts +1 -0
  122. package/dist/shell/index.js +2 -2
  123. package/dist/site/index.cjs +71 -71
  124. package/dist/site/index.js +3 -3
  125. package/dist/studio/index.cjs +79 -76
  126. package/dist/studio/index.cjs.map +1 -1
  127. package/dist/studio/index.js +9 -6
  128. package/dist/studio/index.js.map +1 -1
  129. package/dist/workspaces/WorkspaceGallery.d.ts +42 -0
  130. package/dist/workspaces/index.cjs +74 -7
  131. package/dist/workspaces/index.cjs.map +1 -1
  132. package/dist/workspaces/index.d.ts +2 -0
  133. package/dist/workspaces/index.js +73 -7
  134. package/dist/workspaces/index.js.map +1 -1
  135. package/package.json +3 -3
  136. package/src/blocks.css +10 -13
  137. package/dist/chunk-2K33YGM6.cjs.map +0 -1
  138. package/dist/chunk-54Q3RNJU.cjs.map +0 -1
  139. package/dist/chunk-7PEELPMA.js.map +0 -1
  140. package/dist/chunk-AZQDNYH4.js.map +0 -1
  141. package/dist/chunk-G3G7LZPM.cjs.map +0 -1
  142. package/dist/chunk-GDFWJ73C.cjs.map +0 -1
  143. package/dist/chunk-ITGHMJOM.js.map +0 -1
  144. package/dist/chunk-SCFYPAG6.cjs +0 -18
  145. package/dist/chunk-SCFYPAG6.cjs.map +0 -1
  146. package/dist/chunk-SYDHKKRZ.cjs.map +0 -1
  147. package/dist/chunk-TYZUCAT7.js.map +0 -1
  148. package/dist/chunk-UFHMLHIR.cjs.map +0 -1
  149. package/dist/chunk-UWGIB3VQ.js.map +0 -1
  150. package/dist/chunk-WJMEXTVD.cjs.map +0 -1
  151. package/dist/chunk-WTNMWEBC.js.map +0 -1
  152. package/dist/chunk-WW6EOVZA.js.map +0 -1
  153. package/dist/chunk-XNBAXRY7.cjs.map +0 -1
  154. package/dist/chunk-YBXCZEWS.js.map +0 -1
  155. package/dist/chunk-YDHO4AVL.js +0 -16
  156. package/dist/chunk-YDHO4AVL.js.map +0 -1
@@ -1,1051 +1,12 @@
1
1
  "use client";
2
- import { BlocksTooltipProvider } from './chunk-YDHO4AVL.js';
3
- import { testIdOr, prefixedTestId } from './chunk-7F6CBP3Z.js';
4
- import { forwardRef, useState, useRef, memo, useId, useEffect, useCallback, useMemo, Fragment as Fragment$1 } from 'react';
5
- import { FileText, ChevronDown, Globe, BookOpen, ChevronsUpDown, Search, Pencil, SquareSlash, Sparkles, ChevronUp, MoreHorizontal, RotateCw, AlertCircle, ArrowLeft, Edit3, Send, Loader2, Square, Mic, ArrowDown, Pin, X, GanttChartSquare, ArrowUpRight, Network, ArrowRight, Crown, Glasses, Zap, Check, Settings, Plus, Bot, Download, MessageCircleQuestion, Clock, Play, Pause, MessageSquare, CheckCircle, Tag, FileUp, User } from 'lucide-react';
6
- import { cn, Textarea, Button, HoverCardContent, Input, Badge, PopoverTrigger, Popover, PopoverAnchor, PopoverContent, DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, Tooltip, TooltipTrigger, TooltipContent, PassageCard, Tabs, TabsList, TabsTrigger, TabsContent } from '@arbidocs/react/ui';
7
- import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
+ import { BlocksTooltipProvider } from './chunk-2VBJ763Y.js';
3
+ import { prefixedTestId, testIdOr } from './chunk-7F6CBP3Z.js';
4
+ import { memo, useId, useRef, useEffect, forwardRef, useState, useCallback, useMemo, Fragment as Fragment$1 } from 'react';
5
+ import { Globe, BookOpen, ChevronsUpDown, Search, SquareSlash, Pin, X, Network, ArrowLeft, ArrowRight, Crown, Glasses, Zap, Sparkles, Check, Settings, Plus, Bot, Download, MessageCircleQuestion, Clock, Play, Pause, Loader2, MessageSquare, CheckCircle, Tag, User } from 'lucide-react';
6
+ import { cn, Button, HoverCardContent, Input, Badge, Tooltip, TooltipTrigger, TooltipContent, Popover, PopoverTrigger, PopoverContent, PassageCard, Tabs, TabsList, TabsTrigger, TabsContent } from '@arbidocs/react/ui';
7
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
8
8
  import DOMPurify from 'dompurify';
9
9
 
10
- var DEFAULT_MESSAGE_LABELS = {
11
- subagentBadge: "sub-agent",
12
- hideSteps: "Hide steps",
13
- showSteps: "Show steps",
14
- stepCount: (count) => `${count} step${count !== 1 ? "s" : ""}`,
15
- openSource: (num, title) => `Open source ${num}: ${title}`,
16
- openSourceAria: (num, title, page) => `Open source ${num}: ${title}${page != null ? `, page ${page}` : ""}`,
17
- page: (page) => `p. ${page}`,
18
- pages: (pages) => `pp. ${pages.join(", ")}`,
19
- moreActionsTitle: "More actions",
20
- moreActionsAria: "More message actions"
21
- };
22
- function MessageRoot({
23
- role,
24
- messageId,
25
- tone = "default",
26
- testId = `message-${messageId}`,
27
- className,
28
- children,
29
- ...rest
30
- }) {
31
- return /* @__PURE__ */ jsx(
32
- "div",
33
- {
34
- "data-slot": "message",
35
- "data-testid": testId,
36
- "data-message-role": role,
37
- className: cn(
38
- "group mx-auto mb-1 flex w-full max-w-[46rem] justify-center",
39
- tone === "error" ? "rounded-lg bg-red-bg" : tone === "subagent" ? "rounded-lg bg-muted/40" : "bg-background",
40
- className
41
- ),
42
- ...rest,
43
- children
44
- }
45
- );
46
- }
47
- function MessageContent({
48
- role,
49
- messageId,
50
- testId = `message-content-${messageId}`,
51
- className,
52
- children,
53
- ...rest
54
- }) {
55
- return /* @__PURE__ */ jsx(
56
- "div",
57
- {
58
- "data-slot": "message-content",
59
- "data-testid": testId,
60
- className: cn(
61
- "w-full max-w-full overflow-hidden text-chat",
62
- role === "user" && "flex flex-col items-end",
63
- className
64
- ),
65
- ...rest,
66
- children
67
- }
68
- );
69
- }
70
- var MessageBubble = forwardRef(function MessageBubble2({ role, messageId, isEditing, isQueued, testId, className, children, ...rest }, ref) {
71
- const isUser = role === "user";
72
- return /* @__PURE__ */ jsx(
73
- "div",
74
- {
75
- ref,
76
- "data-slot": "message-bubble",
77
- "data-testid": testId ?? (isUser ? `user-message-${messageId}` : `assistant-message-${messageId}`),
78
- className: cn(
79
- "overflow-hidden transition-colors",
80
- isUser && "max-w-[80%] rounded-lg bg-muted",
81
- isEditing && "ring-2 ring-inset ring-primary/30",
82
- className
83
- ),
84
- ...rest,
85
- children: /* @__PURE__ */ jsx(
86
- "div",
87
- {
88
- className: cn(
89
- isUser ? "px-4 py-2.5" : "px-4 py-3 sm:pl-9 sm:pr-0",
90
- isQueued && "opacity-70"
91
- ),
92
- children
93
- }
94
- )
95
- }
96
- );
97
- });
98
- function MessageByline({
99
- messageId,
100
- identity,
101
- timeLabel,
102
- isSettled,
103
- isFailed,
104
- statusLabel,
105
- className,
106
- testId = `assistant-byline-${messageId}`,
107
- statusTestId
108
- }) {
109
- return /* @__PURE__ */ jsxs(
110
- "div",
111
- {
112
- "data-slot": "message-byline",
113
- "data-testid": testId,
114
- className: cn("mb-2 flex min-w-0 items-center gap-2 text-sm sm:-ml-9", className),
115
- children: [
116
- /* @__PURE__ */ jsx(
117
- "span",
118
- {
119
- className: "flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-ai-soft text-ai-ink",
120
- "aria-hidden": "true",
121
- children: /* @__PURE__ */ jsx(Sparkles, { size: 14 })
122
- }
123
- ),
124
- identity,
125
- /* @__PURE__ */ jsx("span", { className: "truncate text-xs text-muted-foreground", children: timeLabel }),
126
- isSettled && /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", "aria-hidden": "true", children: "\xB7" }),
127
- isSettled && /* @__PURE__ */ jsx(
128
- "span",
129
- {
130
- className: cn(
131
- "shrink-0 text-xs",
132
- isFailed ? "font-medium text-red-text" : "text-muted-foreground"
133
- ),
134
- "data-testid": testIdOr(statusTestId, { testId: "assistant-status" }),
135
- children: statusLabel
136
- }
137
- )
138
- ]
139
- }
140
- );
141
- }
142
- function MessageSubagentBadge({
143
- messageId,
144
- children,
145
- labels,
146
- className,
147
- testId = `subagent-task-badge-${messageId}`
148
- }) {
149
- const l = { ...DEFAULT_MESSAGE_LABELS, ...labels };
150
- return /* @__PURE__ */ jsx(
151
- "span",
152
- {
153
- "data-slot": "message-subagent-badge",
154
- className: cn(
155
- "mb-2 inline-block rounded bg-muted px-1 py-0.5 text-xs font-semibold uppercase leading-none tracking-wide text-muted-foreground",
156
- className
157
- ),
158
- "data-testid": testId,
159
- children: children ?? l.subagentBadge
160
- }
161
- );
162
- }
163
- function MessageBody({
164
- messageId,
165
- className,
166
- children,
167
- testId = `message-body-${messageId}`
168
- }) {
169
- return /* @__PURE__ */ jsx(
170
- "div",
171
- {
172
- "data-slot": "message-body",
173
- className: cn("markdown-content m-0 p-0 text-base leading-relaxed", className),
174
- "data-testid": testId,
175
- children
176
- }
177
- );
178
- }
179
- function MessageNarration({
180
- messageId,
181
- children,
182
- className,
183
- testId = `message-narration-${messageId}`
184
- }) {
185
- return /* @__PURE__ */ jsx(
186
- "div",
187
- {
188
- "data-slot": "message-narration",
189
- className: cn("opacity-50 transition-opacity duration-300", className),
190
- "data-provisional": "true",
191
- "data-testid": testId,
192
- children
193
- }
194
- );
195
- }
196
- function SourceChip({
197
- num,
198
- title,
199
- page,
200
- pages,
201
- onOpen,
202
- className,
203
- labels,
204
- testId = `source-chip-${num}`
205
- }) {
206
- const l = { ...DEFAULT_MESSAGE_LABELS, ...labels };
207
- const pageText = pages && pages.length > 1 ? l.pages(pages) : page != null ? l.page(page) : null;
208
- return /* @__PURE__ */ jsxs(
209
- "button",
210
- {
211
- type: "button",
212
- "data-slot": "source-chip",
213
- onClick: onOpen,
214
- className: cn(
215
- "inline-flex min-h-8 max-w-full items-center gap-2 rounded-md bg-muted px-2 py-1 text-sm text-foreground transition-colors hover:bg-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring pointer-coarse:min-h-11",
216
- className
217
- ),
218
- title: l.openSource(num, title),
219
- "aria-label": l.openSourceAria(num, title, page),
220
- "data-testid": testId,
221
- children: [
222
- /* @__PURE__ */ jsx("span", { className: "inline-flex h-5 min-w-5 items-center justify-center rounded-sm bg-ai-soft px-1 text-xs font-semibold text-ai-ink", children: num }),
223
- /* @__PURE__ */ jsx("span", { className: "min-w-0 truncate", children: title }),
224
- pageText && /* @__PURE__ */ jsx("span", { className: "shrink-0 text-xs text-muted-foreground", children: pageText })
225
- ]
226
- }
227
- );
228
- }
229
- function mergeSourcesByFile(sources) {
230
- const byTitle = /* @__PURE__ */ new Map();
231
- for (const s of sources) {
232
- const group = byTitle.get(s.title) ?? { nums: [], title: s.title, pages: [] };
233
- group.nums.push(s.num);
234
- if (s.page != null && !group.pages.includes(s.page)) group.pages.push(s.page);
235
- byTitle.set(s.title, group);
236
- }
237
- return [...byTitle.values()];
238
- }
239
- function MessageSources({
240
- messageId,
241
- sources,
242
- onOpenSource,
243
- className,
244
- labels,
245
- testId = `source-chips-${messageId}`
246
- }) {
247
- if (sources.length === 0) return null;
248
- return /* @__PURE__ */ jsx(
249
- "div",
250
- {
251
- "data-slot": "message-sources",
252
- className: cn("mt-3 flex flex-wrap gap-2", className),
253
- "data-testid": testId,
254
- children: mergeSourcesByFile(sources).map((g) => /* @__PURE__ */ jsx(
255
- SourceChip,
256
- {
257
- num: g.nums.join(", "),
258
- testId: `source-chip-${g.nums[0]}`,
259
- title: g.title,
260
- page: g.pages[0],
261
- pages: g.pages,
262
- onOpen: () => onOpenSource(g.nums[0]),
263
- labels
264
- },
265
- g.nums[0]
266
- ))
267
- }
268
- );
269
- }
270
- function MessageFooter({
271
- role,
272
- leading,
273
- actions,
274
- steps,
275
- className,
276
- labels,
277
- stepsToggleTestId
278
- }) {
279
- const l = { ...DEFAULT_MESSAGE_LABELS, ...labels };
280
- const isUser = role === "user";
281
- const showSteps = !isUser && !!steps && steps.count > 0;
282
- const row = /* @__PURE__ */ jsxs(
283
- "div",
284
- {
285
- className: cn(
286
- "flex items-center text-sm",
287
- isUser ? "justify-end gap-2 text-xs" : "justify-between"
288
- ),
289
- children: [
290
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
291
- leading,
292
- showSteps && /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
293
- "button",
294
- {
295
- type: "button",
296
- className: "flex items-center gap-1 text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring pointer-coarse:min-h-11",
297
- "aria-expanded": steps.open,
298
- "aria-label": steps.open ? l.hideSteps : l.showSteps,
299
- "data-testid": testIdOr(stepsToggleTestId, { testId: "steps-toggle" }),
300
- children: [
301
- steps.open ? /* @__PURE__ */ jsx(ChevronDown, { size: 14 }) : /* @__PURE__ */ jsx(ChevronUp, { size: 14 }),
302
- /* @__PURE__ */ jsx("span", { className: "tabular-nums", children: l.stepCount(steps.count) })
303
- ]
304
- }
305
- ) })
306
- ] }),
307
- /* @__PURE__ */ jsx("div", { className: "flex items-center gap-1", children: actions })
308
- ]
309
- }
310
- );
311
- return /* @__PURE__ */ jsx(
312
- "div",
313
- {
314
- "data-slot": "message-footer",
315
- className: cn(
316
- "text-muted-foreground",
317
- isUser ? "mt-1 max-w-full self-end" : "mt-3",
318
- className
319
- ),
320
- children: steps ? /* @__PURE__ */ jsxs(Popover, { open: steps.open, onOpenChange: steps.onOpenChange, children: [
321
- /* @__PURE__ */ jsx(PopoverAnchor, { asChild: true, children: row }),
322
- !isUser && steps.count > 0 && /* @__PURE__ */ jsx(
323
- PopoverContent,
324
- {
325
- side: "top",
326
- align: "start",
327
- sideOffset: 8,
328
- className: "max-h-[min(60vh,32rem)] w-[var(--radix-popover-trigger-width)] overflow-y-auto rounded-lg border border-border bg-popover p-0 shadow-lg",
329
- children: steps.panel
330
- }
331
- )
332
- ] }) : row
333
- }
334
- );
335
- }
336
- var MessageActionButton = forwardRef(
337
- function MessageActionButton2({ isDone, className, type = "button", ...rest }, ref) {
338
- return /* @__PURE__ */ jsx(
339
- "button",
340
- {
341
- ref,
342
- type,
343
- "data-slot": "message-action",
344
- className: cn(
345
- "inline-flex h-8 w-8 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:opacity-50 pointer-coarse:h-11 pointer-coarse:w-11",
346
- isDone && "text-green-text",
347
- className
348
- ),
349
- ...rest
350
- }
351
- );
352
- }
353
- );
354
- function MessageActionMenu({
355
- items,
356
- testId,
357
- label,
358
- labels,
359
- className
360
- }) {
361
- const l = { ...DEFAULT_MESSAGE_LABELS, ...labels };
362
- return /* @__PURE__ */ jsxs(DropdownMenu, { children: [
363
- /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
364
- MessageActionButton,
365
- {
366
- onClick: (e) => e.stopPropagation(),
367
- className,
368
- title: l.moreActionsTitle,
369
- "aria-label": label ?? l.moreActionsAria,
370
- "data-testid": testId,
371
- children: /* @__PURE__ */ jsx(MoreHorizontal, { size: 16 })
372
- }
373
- ) }),
374
- /* @__PURE__ */ jsx(DropdownMenuContent, { align: "end", children: items.map((item) => /* @__PURE__ */ jsxs(
375
- DropdownMenuItem,
376
- {
377
- onClick: (e) => {
378
- e.stopPropagation();
379
- item.onSelect();
380
- },
381
- className: item.tone === "danger" ? "text-red-text focus:text-red-text" : void 0,
382
- "data-testid": item.testId,
383
- children: [
384
- item.icon,
385
- item.label
386
- ]
387
- },
388
- item.id
389
- )) })
390
- ] });
391
- }
392
- var Message = {
393
- Root: MessageRoot,
394
- Content: MessageContent,
395
- Bubble: MessageBubble,
396
- Byline: MessageByline,
397
- SubagentBadge: MessageSubagentBadge,
398
- Body: MessageBody,
399
- Narration: MessageNarration,
400
- Sources: MessageSources,
401
- Footer: MessageFooter,
402
- ActionButton: MessageActionButton,
403
- ActionMenu: MessageActionMenu
404
- };
405
- var DEFAULT_MESSAGE_ALERT_LABELS = {
406
- retrying: "Retrying...",
407
- retry: "Retry"
408
- };
409
- function MessageAlert({
410
- title,
411
- description,
412
- isBusy = false,
413
- busyTitle,
414
- labels,
415
- onActivate,
416
- actions,
417
- className,
418
- testId = "message-alert"
419
- }) {
420
- const l = { ...DEFAULT_MESSAGE_ALERT_LABELS, ...labels };
421
- return /* @__PURE__ */ jsx(
422
- "div",
423
- {
424
- "data-slot": "message-alert",
425
- role: isBusy ? "status" : "alert",
426
- "aria-busy": isBusy,
427
- className: cn(
428
- "mb-3 rounded-lg border border-red-border bg-red-bg px-4 py-2 transition-colors",
429
- className
430
- ),
431
- "data-testid": testId,
432
- children: /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3", children: [
433
- isBusy ? /* @__PURE__ */ jsx(
434
- RotateCw,
435
- {
436
- "aria-hidden": "true",
437
- className: "mt-0.5 h-5 w-5 shrink-0 animate-spin text-red-text motion-reduce:animate-none"
438
- }
439
- ) : /* @__PURE__ */ jsx(AlertCircle, { "aria-hidden": "true", className: "mt-0.5 h-5 w-5 shrink-0 text-red-text" }),
440
- /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
441
- /* @__PURE__ */ jsx("p", { className: "mb-1 text-base font-medium text-red-text", children: isBusy ? busyTitle ?? l.retrying : title }),
442
- /* @__PURE__ */ jsx("p", { className: "mb-1 text-sm text-muted-foreground", children: description }),
443
- (actions || onActivate) && /* @__PURE__ */ jsxs("div", { className: "mt-2 flex flex-wrap gap-2", children: [
444
- actions,
445
- onActivate && /* @__PURE__ */ jsxs(
446
- Button,
447
- {
448
- type: "button",
449
- size: "sm",
450
- variant: "outline",
451
- className: "pointer-coarse:min-h-11",
452
- disabled: isBusy,
453
- onClick: onActivate,
454
- "data-testid": `${testId}-retry`,
455
- children: [
456
- /* @__PURE__ */ jsx(RotateCw, { "aria-hidden": "true", className: "mr-2 h-4 w-4" }),
457
- l.retry
458
- ]
459
- }
460
- )
461
- ] })
462
- ] })
463
- ] })
464
- }
465
- );
466
- }
467
- var DEFAULT_MESSAGE_LIST_LABELS = {
468
- messageList: "Message list",
469
- startConversation: "Start a new conversation",
470
- backToConversation: "Back to conversation \u2014 this is a sub-agent's delegated thread",
471
- conversationMessages: "Conversation messages",
472
- responding: "Assistant is responding",
473
- responseComplete: (text) => text ? `Response complete: ${text}` : "Response complete"
474
- };
475
- function MessageListRoot({
476
- className,
477
- children,
478
- isBusy = false,
479
- labels,
480
- testId = "message-list",
481
- ...rest
482
- }) {
483
- const l = { ...DEFAULT_MESSAGE_LIST_LABELS, ...labels };
484
- return /* @__PURE__ */ jsx(
485
- "div",
486
- {
487
- "data-slot": "message-list",
488
- style: { containerType: "inline-size" },
489
- "data-testid": testId,
490
- role: "log",
491
- "aria-live": "off",
492
- "aria-busy": isBusy,
493
- "aria-label": l.messageList,
494
- className,
495
- ...rest,
496
- children
497
- }
498
- );
499
- }
500
- function MessageListStatus({
501
- message,
502
- testId = "message-list-status"
503
- }) {
504
- return /* @__PURE__ */ jsx(
505
- "div",
506
- {
507
- "data-slot": "message-list-status",
508
- role: "status",
509
- "aria-live": "polite",
510
- "aria-atomic": "true",
511
- className: "sr-only",
512
- "data-testid": testId,
513
- children: message
514
- }
515
- );
516
- }
517
- function MessageListEmpty({
518
- children,
519
- labels,
520
- className,
521
- testId = "message-list-empty"
522
- }) {
523
- const l = { ...DEFAULT_MESSAGE_LIST_LABELS, ...labels };
524
- return /* @__PURE__ */ jsx("div", { className: cn("flex h-64 items-center justify-center", className), "data-testid": testId, children: /* @__PURE__ */ jsx("p", { className: "text-muted-foreground", children: children ?? l.startConversation }) });
525
- }
526
- function MessageListBanner({
527
- onBack,
528
- children,
529
- labels,
530
- className,
531
- testId = "back-to-conversation-button"
532
- }) {
533
- const l = { ...DEFAULT_MESSAGE_LIST_LABELS, ...labels };
534
- return /* @__PURE__ */ jsx(
535
- "div",
536
- {
537
- "data-slot": "message-list-banner",
538
- className: cn(
539
- "sticky top-0 z-10 border-b border-border/40 bg-background px-3 py-2 sm:px-6",
540
- className
541
- ),
542
- children: /* @__PURE__ */ jsxs(
543
- "button",
544
- {
545
- type: "button",
546
- onClick: onBack,
547
- className: "flex items-center gap-1.5 rounded-md px-2 py-1 text-sm font-medium text-primary transition-colors hover:bg-muted/60 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring pointer-coarse:min-h-11",
548
- "data-testid": testId,
549
- children: [
550
- /* @__PURE__ */ jsx(ArrowLeft, { size: 14 }),
551
- children ?? l.backToConversation
552
- ]
553
- }
554
- )
555
- }
556
- );
557
- }
558
- function MessageListRows({
559
- totalSize,
560
- className,
561
- children,
562
- labels,
563
- ...rest
564
- }) {
565
- const l = { ...DEFAULT_MESSAGE_LIST_LABELS, ...labels };
566
- return /* @__PURE__ */ jsx(
567
- "div",
568
- {
569
- "data-slot": "message-list-rows",
570
- style: { height: totalSize, position: "relative" },
571
- role: "list",
572
- "aria-label": l.conversationMessages,
573
- className,
574
- ...rest,
575
- children
576
- }
577
- );
578
- }
579
- var MessageListRow = forwardRef(
580
- function MessageListRow2({ index, start, messageId, setSize, className, children, ...rest }, ref) {
581
- const style = {
582
- position: "absolute",
583
- top: 0,
584
- left: 0,
585
- width: "100%",
586
- transform: `translateY(${start}px)`
587
- };
588
- return /* @__PURE__ */ jsx(
589
- "div",
590
- {
591
- ref,
592
- "data-slot": "message-list-row",
593
- "data-index": index,
594
- "data-message-id": messageId,
595
- role: "listitem",
596
- "aria-posinset": setSize === void 0 ? void 0 : index + 1,
597
- "aria-setsize": setSize,
598
- style,
599
- className,
600
- ...rest,
601
- children: /* @__PURE__ */ jsx("div", { className: cn("w-full px-3 sm:px-6"), children })
602
- }
603
- );
604
- }
605
- );
606
- function MessageListTail() {
607
- return /* @__PURE__ */ jsx("div", { className: "h-12 sm:h-32", "aria-hidden": "true", children: /* @__PURE__ */ jsx("div", { className: "pointer-events-none h-8 bg-gradient-to-b from-background to-transparent sm:h-20" }) });
608
- }
609
- var MessageList = {
610
- Root: MessageListRoot,
611
- Empty: MessageListEmpty,
612
- Banner: MessageListBanner,
613
- Status: MessageListStatus,
614
- Rows: MessageListRows,
615
- Row: MessageListRow,
616
- Tail: MessageListTail
617
- };
618
- function toSpeakableText(markdown, maxLength = 600) {
619
- const flat = markdown.replace(/```[\s\S]*?```/g, " ").replace(/<[^>]+>/g, " ").replace(/!?\[([^\]]*)\]\([^)]*\)/g, "$1").replace(/[*_`#>~|]/g, "").replace(/\s+/g, " ").trim();
620
- if (flat.length <= maxLength) return flat;
621
- const cut = flat.slice(0, maxLength);
622
- const lastSpace = cut.lastIndexOf(" ");
623
- return `${(lastSpace > maxLength / 2 ? cut.slice(0, lastSpace) : cut).trimEnd()}\u2026`;
624
- }
625
- function useStreamAnnouncement({
626
- isStreaming,
627
- text,
628
- resetKey,
629
- maxLength,
630
- labels
631
- }) {
632
- const l = { ...DEFAULT_MESSAGE_LIST_LABELS, ...labels };
633
- const [message, setMessage] = useState("");
634
- const wasStreaming = useRef(isStreaming);
635
- const textRef = useRef(text);
636
- textRef.current = text;
637
- const lastKey = useRef(resetKey);
638
- useEffect(() => {
639
- if (lastKey.current !== resetKey) {
640
- lastKey.current = resetKey;
641
- wasStreaming.current = isStreaming;
642
- setMessage("");
643
- return;
644
- }
645
- if (isStreaming === wasStreaming.current) return;
646
- wasStreaming.current = isStreaming;
647
- setMessage(
648
- isStreaming ? l.responding : l.responseComplete(toSpeakableText(textRef.current, maxLength))
649
- );
650
- }, [isStreaming, resetKey]);
651
- return message;
652
- }
653
- var DEFAULT_COMPOSER_LABELS = {
654
- branchingNotice: "Editing message. Submit to send, or cancel to go back.",
655
- cancel: "Cancel",
656
- inputAriaLabel: "Write your prompt here",
657
- pastedText: "Pasted text",
658
- pasteSummary: (lines, characters) => `${lines} lines \xB7 ${characters} characters`,
659
- expand: "Expand",
660
- retryMessage: "Retry message",
661
- sendMessage: "Send message",
662
- voiceButton: "Press and hold to speak",
663
- jumpToBottom: "Jump to bottom"
664
- };
665
- function ComposerRoot({
666
- onSubmit,
667
- notice,
668
- isBranching,
669
- formRef,
670
- testId = "message-input",
671
- formTestId,
672
- className,
673
- children,
674
- ...rest
675
- }) {
676
- return /* @__PURE__ */ jsxs(
677
- "div",
678
- {
679
- "data-slot": "composer",
680
- className: cn("relative z-[20] shrink-0", isBranching && "bg-muted/30"),
681
- "data-testid": testId,
682
- children: [
683
- notice,
684
- /* @__PURE__ */ jsx(
685
- "form",
686
- {
687
- ref: formRef,
688
- onSubmit,
689
- ...rest,
690
- className: cn("relative w-full", className),
691
- "data-testid": testIdOr(formTestId, { testId: "message-input-form" }),
692
- children
693
- }
694
- )
695
- ]
696
- }
697
- );
698
- }
699
- function ComposerBranchingNotice({
700
- onCancel,
701
- children,
702
- labels,
703
- testId = "message-input-branching-indicator",
704
- cancelTestId,
705
- className,
706
- ...rest
707
- }) {
708
- const l = { ...DEFAULT_COMPOSER_LABELS, ...labels };
709
- return /* @__PURE__ */ jsxs(
710
- "div",
711
- {
712
- ...rest,
713
- "data-slot": "composer-notice",
714
- className: cn("mb-2 flex items-center rounded-md bg-muted px-3 py-1.5 text-sm", className),
715
- "data-testid": testId,
716
- children: [
717
- /* @__PURE__ */ jsx(Edit3, { size: 16, className: "mr-2 text-muted-foreground" }),
718
- /* @__PURE__ */ jsx("span", { className: "flex-1 text-muted-foreground", children: children ?? l.branchingNotice }),
719
- onCancel && /* @__PURE__ */ jsx(
720
- Button,
721
- {
722
- type: "button",
723
- variant: "outline",
724
- size: "sm",
725
- className: "ml-2",
726
- onClick: onCancel,
727
- "data-testid": testIdOr(cancelTestId, { testId: "cancel-branching-button" }),
728
- children: l.cancel
729
- }
730
- )
731
- ]
732
- }
733
- );
734
- }
735
- var INTERACTIVE = 'button, a, input, textarea, select, [role="button"], [contenteditable="true"]';
736
- function ComposerFrame({ className, children, ...rest }) {
737
- return /* @__PURE__ */ jsx(
738
- "div",
739
- {
740
- "data-slot": "composer-frame",
741
- className: cn(
742
- "relative flex w-full flex-col rounded-lg border border-border bg-background px-4 py-3 shadow-lg transition-shadow focus-within:shadow-xl",
743
- className
744
- ),
745
- onMouseDown: (e) => {
746
- const target = e.target;
747
- if (target.closest(INTERACTIVE)) return;
748
- e.preventDefault();
749
- e.currentTarget.querySelector("textarea")?.focus();
750
- },
751
- ...rest,
752
- children
753
- }
754
- );
755
- }
756
- function scrollToLastContentLine(textarea) {
757
- if (!textarea) return;
758
- const text = textarea.value;
759
- const lines = text.split("\n");
760
- const trimmedLines = text.trimEnd().split("\n");
761
- if (lines.length - trimmedLines.length > 0 && trimmedLines.length > 0) {
762
- const lineHeight = parseFloat(getComputedStyle(textarea).lineHeight) || 24;
763
- textarea.scrollTop = (trimmedLines.length - 1) * lineHeight;
764
- } else {
765
- textarea.scrollTop = textarea.scrollHeight;
766
- }
767
- }
768
- var ComposerInput = forwardRef(
769
- function ComposerInput2({
770
- value,
771
- onValueChange,
772
- onKeyDown,
773
- submitOnEnter = true,
774
- onPaste,
775
- placeholder,
776
- textareaRef,
777
- isSuggestion,
778
- isRoomy,
779
- isPasteCollapsed,
780
- onExpandPaste,
781
- ariaLabel,
782
- textareaProps,
783
- className,
784
- labels,
785
- testId = "message-input-textarea",
786
- pasteChipTestId
787
- }, forwardedRef) {
788
- const l = { ...DEFAULT_COMPOSER_LABELS, ...labels };
789
- const [isFocused, setIsFocused] = useState(false);
790
- const [isHovered, setIsHovered] = useState(false);
791
- const innerRef = useRef(null);
792
- const setRefs = (node) => {
793
- innerRef.current = node;
794
- for (const ref of [forwardedRef, textareaRef]) {
795
- if (typeof ref === "function") ref(node);
796
- else if (ref) ref.current = node;
797
- }
798
- };
799
- const handleKeyDown = (event) => {
800
- onKeyDown?.(event);
801
- if (event.defaultPrevented || !submitOnEnter) return;
802
- if (event.key !== "Enter" || event.shiftKey || event.altKey) return;
803
- if (event.nativeEvent.isComposing || event.keyCode === 229) return;
804
- event.preventDefault();
805
- event.currentTarget.form?.requestSubmit();
806
- };
807
- if (isPasteCollapsed) {
808
- const lineCount = value.split("\n").length;
809
- return /* @__PURE__ */ jsxs(
810
- "button",
811
- {
812
- type: "button",
813
- "data-slot": "composer-paste-chip",
814
- onClick: onExpandPaste,
815
- className: "flex w-full items-center gap-2 rounded-md bg-muted/50 px-3 py-2 text-left transition-colors hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/40",
816
- "data-testid": testIdOr(pasteChipTestId, { testId: "long-paste-placeholder" }),
817
- "data-full-length": value.length,
818
- children: [
819
- /* @__PURE__ */ jsx(FileText, { className: "h-4 w-4 shrink-0 text-muted-foreground", "aria-hidden": "true" }),
820
- /* @__PURE__ */ jsxs("span", { className: "min-w-0 flex-1", children: [
821
- /* @__PURE__ */ jsx("span", { className: "block text-sm font-medium text-foreground", children: l.pastedText }),
822
- /* @__PURE__ */ jsx("span", { className: "block text-xs text-muted-foreground", children: l.pasteSummary(lineCount, value.length.toLocaleString()) })
823
- ] }),
824
- /* @__PURE__ */ jsxs("span", { className: "flex shrink-0 items-center gap-1 text-xs font-medium text-muted-foreground", children: [
825
- l.expand,
826
- /* @__PURE__ */ jsx(ChevronDown, { className: "h-3.5 w-3.5", "aria-hidden": "true" })
827
- ] })
828
- ]
829
- }
830
- );
831
- }
832
- return /* @__PURE__ */ jsx(
833
- Textarea,
834
- {
835
- ...textareaProps,
836
- "aria-label": ariaLabel ?? l.inputAriaLabel,
837
- placeholder,
838
- "data-suggested-query": isSuggestion ? "true" : void 0,
839
- rows: 1,
840
- ref: setRefs,
841
- value,
842
- onChange: (event) => onValueChange(event.target.value),
843
- onPaste,
844
- onKeyDown: handleKeyDown,
845
- disabled: false,
846
- className: cn(
847
- "scrollbar-subtle !min-h-0 pointer-coarse:!min-h-11 pointer-coarse:py-2.5 w-full resize-none border-0 bg-transparent p-0 !text-base leading-relaxed text-foreground shadow-none placeholder:text-muted-foreground/50 focus-visible:ring-0 focus-visible:ring-offset-0 md:!text-base",
848
- className
849
- ),
850
- style: {
851
- fieldSizing: "content",
852
- maxHeight: isFocused || isHovered ? "40vh" : value ? "6.5em" : isRoomy ? "4em" : "1.7em",
853
- overflowY: value ? "auto" : "hidden",
854
- scrollbarGutter: "stable"
855
- },
856
- onFocus: () => {
857
- setIsFocused(true);
858
- requestAnimationFrame(() => {
859
- const ta = innerRef.current;
860
- if (ta) {
861
- ta.setSelectionRange(ta.value.length, ta.value.length);
862
- ta.scrollTop = ta.scrollHeight;
863
- }
864
- });
865
- },
866
- onBlur: () => {
867
- setIsFocused(false);
868
- if (!isHovered) requestAnimationFrame(() => scrollToLastContentLine(innerRef.current));
869
- },
870
- onMouseEnter: () => setIsHovered(true),
871
- onMouseLeave: () => {
872
- setIsHovered(false);
873
- if (!isFocused) requestAnimationFrame(() => scrollToLastContentLine(innerRef.current));
874
- },
875
- "data-testid": testId
876
- }
877
- );
878
- }
879
- );
880
- function ComposerToolbar({ leading, trailing, className }) {
881
- return /* @__PURE__ */ jsxs(
882
- "div",
883
- {
884
- "data-slot": "composer-toolbar",
885
- className: cn(
886
- "mt-2 flex flex-wrap items-center justify-between gap-x-1 gap-y-0.5",
887
- className
888
- ),
889
- children: [
890
- /* @__PURE__ */ jsx("div", { className: "flex shrink-0 items-center gap-1", children: leading }),
891
- /* @__PURE__ */ jsx("div", { className: "ml-auto flex min-w-0 items-center justify-end gap-1", children: trailing })
892
- ]
893
- }
894
- );
895
- }
896
- function ComposerSend({
897
- onSend,
898
- disabled,
899
- isRetry,
900
- labels,
901
- className,
902
- testIds
903
- }) {
904
- const l = { ...DEFAULT_COMPOSER_LABELS, ...labels };
905
- const sendTestId = testIdOr(testIds?.send, { testId: "send-message-button" });
906
- const retryTestId = testIdOr(testIds?.retry, { testId: "retry-button" });
907
- return /* @__PURE__ */ jsx(
908
- Button,
909
- {
910
- type: "button",
911
- size: "icon",
912
- className: cn(
913
- "h-9 w-9 shrink-0 pointer-coarse:h-11 pointer-coarse:w-11",
914
- // A faded primary is unreadable; a flat muted chip reads as "not available yet" at 4.5:1.
915
- "disabled:bg-muted disabled:text-muted-foreground disabled:opacity-100",
916
- className
917
- ),
918
- "aria-label": isRetry ? l.retryMessage : l.sendMessage,
919
- disabled,
920
- onClick: onSend,
921
- "data-testid": isRetry ? retryTestId : sendTestId,
922
- children: isRetry ? /* @__PURE__ */ jsx(RotateCw, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsx(Send, { className: "h-3.5 w-3.5" })
923
- }
924
- );
925
- }
926
- function ComposerVoiceButton({
927
- isRecording,
928
- isBusy,
929
- onPressStart,
930
- onPressEnd,
931
- label,
932
- labels,
933
- className,
934
- testIds
935
- }) {
936
- const text = label ?? { ...DEFAULT_COMPOSER_LABELS, ...labels }.voiceButton;
937
- const startTestId = testIdOr(testIds?.start, { testId: "start-recording-button" });
938
- const recordingTestId = testIdOr(testIds?.recording, { testId: "recording-mic-button" });
939
- return /* @__PURE__ */ jsxs(Tooltip, { children: [
940
- /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
941
- Button,
942
- {
943
- type: "button",
944
- variant: "ghost",
945
- size: "sm",
946
- "aria-label": text,
947
- onPointerDown: (e) => {
948
- e.preventDefault();
949
- onPressStart();
950
- },
951
- onPointerUp: onPressEnd,
952
- onPointerLeave: onPressEnd,
953
- onPointerCancel: onPressEnd,
954
- disabled: isBusy,
955
- className: cn(
956
- "h-8 w-8 shrink-0 p-0 hover:bg-muted pointer-coarse:h-11 pointer-coarse:w-11",
957
- isRecording && "bg-red-bg",
958
- className
959
- ),
960
- "data-testid": isRecording ? recordingTestId : startTestId,
961
- children: isBusy ? /* @__PURE__ */ jsx(Loader2, { className: "h-3.5 w-3.5 animate-spin text-muted-foreground" }) : isRecording ? /* @__PURE__ */ jsx(Square, { className: "h-3 w-3 fill-red-text text-red-text" }) : /* @__PURE__ */ jsx(Mic, { className: "h-4 w-4 text-muted-foreground" })
962
- }
963
- ) }),
964
- /* @__PURE__ */ jsx(TooltipContent, { side: "top", children: text })
965
- ] });
966
- }
967
- function ComposerContainer({
968
- className,
969
- children,
970
- testId = "message-input-container",
971
- ...rest
972
- }) {
973
- return /* @__PURE__ */ jsx(
974
- "div",
975
- {
976
- ...rest,
977
- "data-slot": "composer-container",
978
- className: cn("w-full bg-background py-1", className),
979
- "data-testid": testId,
980
- children
981
- }
982
- );
983
- }
984
- function ComposerDock({ children, floating }) {
985
- return /* @__PURE__ */ jsxs(
986
- "div",
987
- {
988
- "data-slot": "composer-dock",
989
- className: "sticky bottom-0 z-40 w-full pb-4 sm:pb-[max(1rem,env(safe-area-inset-bottom))]",
990
- children: [
991
- /* @__PURE__ */ jsx(
992
- "div",
993
- {
994
- className: "pointer-events-none absolute bottom-full left-0 right-0 h-16 bg-gradient-to-b from-transparent to-background/70",
995
- "aria-hidden": "true"
996
- }
997
- ),
998
- /* @__PURE__ */ jsx(
999
- "div",
1000
- {
1001
- className: "pointer-events-none absolute bottom-0 left-0 right-0 h-4 bg-gradient-to-b from-transparent to-background/60 backdrop-blur-sm",
1002
- "aria-hidden": "true"
1003
- }
1004
- ),
1005
- floating,
1006
- children
1007
- ]
1008
- }
1009
- );
1010
- }
1011
- function ScrollToBottom({
1012
- show,
1013
- onClick,
1014
- label,
1015
- labels,
1016
- className,
1017
- testId = "scroll-to-bottom-button"
1018
- }) {
1019
- if (!show) return null;
1020
- const text = label ?? { ...DEFAULT_COMPOSER_LABELS, ...labels }.jumpToBottom;
1021
- return /* @__PURE__ */ jsx(
1022
- Button,
1023
- {
1024
- onClick,
1025
- variant: "outline",
1026
- size: "icon",
1027
- className: cn(
1028
- "absolute -top-12 left-1/2 z-[15] h-10 w-10 -translate-x-1/2 shadow-lg pointer-coarse:h-11 pointer-coarse:w-11",
1029
- className
1030
- ),
1031
- title: text,
1032
- "aria-label": text,
1033
- "data-testid": testId,
1034
- children: /* @__PURE__ */ jsx(ArrowDown, { size: 20 })
1035
- }
1036
- );
1037
- }
1038
- var Composer = {
1039
- Root: ComposerRoot,
1040
- Notice: ComposerBranchingNotice,
1041
- Frame: ComposerFrame,
1042
- Input: ComposerInput,
1043
- Toolbar: ComposerToolbar,
1044
- Send: ComposerSend,
1045
- VoiceButton: ComposerVoiceButton,
1046
- Container: ComposerContainer,
1047
- Dock: ComposerDock
1048
- };
1049
10
  function listOptionId(listboxId, index) {
1050
11
  return `${listboxId}-option-${index}`;
1051
12
  }
@@ -1301,141 +262,6 @@ function PinnedDocChip({
1301
262
  }
1302
263
  );
1303
264
  }
1304
- var DEFAULT_CONVERSATION_EMPTY_LABELS = {
1305
- title: "Ask ARBI about your documents",
1306
- description: "Ask a question and verify every answer against the source.",
1307
- dropDocuments: "Drop documents here to add them"
1308
- };
1309
- function AddDocumentsArea({
1310
- onAddDocuments,
1311
- label,
1312
- testId
1313
- }) {
1314
- return /* @__PURE__ */ jsxs(
1315
- "button",
1316
- {
1317
- type: "button",
1318
- onClick: () => onAddDocuments(),
1319
- onDragOver: (e) => {
1320
- if (e.dataTransfer.types.includes("Files")) {
1321
- e.preventDefault();
1322
- e.dataTransfer.dropEffect = "copy";
1323
- }
1324
- },
1325
- onDrop: (e) => {
1326
- const files = Array.from(e.dataTransfer.files ?? []);
1327
- if (files.length > 0) {
1328
- e.preventDefault();
1329
- onAddDocuments(files);
1330
- }
1331
- },
1332
- "data-testid": testId,
1333
- className: "mx-auto flex w-full max-w-sm items-center justify-center gap-2 rounded-lg bg-muted px-3 py-2.5 text-sm text-muted-foreground transition-colors hover:bg-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring pointer-coarse:min-h-11",
1334
- children: [
1335
- /* @__PURE__ */ jsx(FileUp, { className: "h-4 w-4 shrink-0" }),
1336
- /* @__PURE__ */ jsx("span", { children: label })
1337
- ]
1338
- }
1339
- );
1340
- }
1341
- var BELOW = "mx-auto w-full max-w-4xl text-left";
1342
- var CHIP = "group inline-flex items-center rounded-full bg-muted px-3.5 py-2 text-left text-sm text-foreground transition-colors hover:bg-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring pointer-coarse:min-h-11";
1343
- function ConversationEmpty({
1344
- hasDocuments,
1345
- prompts,
1346
- shortcut,
1347
- onUsePrompt,
1348
- onAddDocuments,
1349
- noDocuments,
1350
- below,
1351
- title,
1352
- description,
1353
- className,
1354
- labels,
1355
- testIds
1356
- }) {
1357
- const l = { ...DEFAULT_CONVERSATION_EMPTY_LABELS, ...labels };
1358
- const rootTestId = testIdOr(testIds?.root, { testId: "conversation-empty-state" });
1359
- const uploadTestId = testIdOr(testIds?.upload, { testId: "conversation-empty-upload" });
1360
- const shortcutTestId = testIdOr(testIds?.shortcut, {
1361
- testId: "conversation-shortcut-main-events"
1362
- });
1363
- const promptTestId = testIdOr(testIds?.prompt, { testId: "conversation-example-prompt" });
1364
- if (!hasDocuments) {
1365
- return /* @__PURE__ */ jsx(
1366
- "div",
1367
- {
1368
- "data-slot": "conversation-empty",
1369
- className: cn(
1370
- "absolute inset-0 flex flex-col items-center overflow-y-auto px-6 py-8 pb-28",
1371
- className
1372
- ),
1373
- "data-testid": rootTestId,
1374
- children: /* @__PURE__ */ jsxs("div", { className: "my-auto flex w-full flex-col items-center gap-8", children: [
1375
- /* @__PURE__ */ jsx("div", { className: "flex w-full max-w-xl flex-col items-center gap-3", children: noDocuments }),
1376
- below && /* @__PURE__ */ jsx("div", { className: BELOW, children: below })
1377
- ] })
1378
- }
1379
- );
1380
- }
1381
- return /* @__PURE__ */ jsx(
1382
- "div",
1383
- {
1384
- "data-slot": "conversation-empty",
1385
- className: cn("absolute inset-0 flex overflow-y-auto p-6 pb-28", className),
1386
- "data-testid": rootTestId,
1387
- children: /* @__PURE__ */ jsxs("div", { className: "m-auto flex w-full flex-col", children: [
1388
- /* @__PURE__ */ jsxs("div", { className: "mx-auto w-full max-w-xl text-center", children: [
1389
- /* @__PURE__ */ jsx("div", { className: "mx-auto mb-4 flex h-12 w-12 items-center justify-center rounded-lg bg-ai-soft text-ai-ink", children: /* @__PURE__ */ jsx(Sparkles, { className: "h-6 w-6" }) }),
1390
- /* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold text-foreground", children: title ?? l.title }),
1391
- /* @__PURE__ */ jsx("p", { className: "mt-1.5 text-sm text-muted-foreground", children: description ?? l.description })
1392
- ] }),
1393
- below && /* @__PURE__ */ jsx("div", { className: cn(BELOW, "mt-6"), children: below }),
1394
- /* @__PURE__ */ jsxs("div", { className: "mx-auto w-full max-w-xl text-center", children: [
1395
- /* @__PURE__ */ jsxs("div", { className: cn("flex flex-wrap justify-center gap-2", below ? "mt-8" : "mt-5"), children: [
1396
- shortcut && /* @__PURE__ */ jsxs(
1397
- "button",
1398
- {
1399
- type: "button",
1400
- onClick: () => onUsePrompt(shortcut.prompt),
1401
- title: shortcut.prompt,
1402
- className: cn(CHIP, "gap-2 font-medium"),
1403
- "data-testid": shortcutTestId,
1404
- children: [
1405
- /* @__PURE__ */ jsx(GanttChartSquare, { className: "h-4 w-4 shrink-0 text-ai-ink" }),
1406
- /* @__PURE__ */ jsx("span", { children: shortcut.label }),
1407
- /* @__PURE__ */ jsx(ArrowUpRight, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" })
1408
- ]
1409
- }
1410
- ),
1411
- prompts.map((prompt) => /* @__PURE__ */ jsxs(
1412
- "button",
1413
- {
1414
- type: "button",
1415
- onClick: () => onUsePrompt(prompt),
1416
- className: cn(CHIP, "gap-1.5"),
1417
- "data-testid": promptTestId,
1418
- children: [
1419
- prompt,
1420
- /* @__PURE__ */ jsx(ArrowUpRight, { className: "h-3.5 w-3.5 text-muted-foreground" })
1421
- ]
1422
- },
1423
- prompt
1424
- ))
1425
- ] }),
1426
- /* @__PURE__ */ jsx("div", { className: "mt-5", children: /* @__PURE__ */ jsx(
1427
- AddDocumentsArea,
1428
- {
1429
- onAddDocuments,
1430
- label: l.dropDocuments,
1431
- testId: uploadTestId
1432
- }
1433
- ) })
1434
- ] })
1435
- ] })
1436
- }
1437
- );
1438
- }
1439
265
  var DEFAULT_CONVERSATION_LAYOUT_LABELS = {
1440
266
  loadingMessages: "Loading messages..."
1441
267
  };
@@ -2700,72 +1526,6 @@ function ContextPanelTabs({
2700
1526
  tabs.map((t) => /* @__PURE__ */ jsx(TabsContent, { value: t.value, className: "mt-3", children: t.content }, t.value))
2701
1527
  ] });
2702
1528
  }
2703
- function canHover() {
2704
- return typeof window !== "undefined" && !!window.matchMedia?.("(hover: hover)").matches;
2705
- }
2706
- function isFocusVisible(el) {
2707
- try {
2708
- return el.matches(":focus-visible");
2709
- } catch {
2710
- return true;
2711
- }
2712
- }
2713
- var ContextChip = forwardRef(function ContextChip2({
2714
- count,
2715
- label,
2716
- isOpen = false,
2717
- children,
2718
- className,
2719
- onMouseEnter,
2720
- onMouseLeave,
2721
- onFocus,
2722
- onBlur,
2723
- ...props
2724
- }, ref) {
2725
- const [isHovered, setIsHovered] = useState(false);
2726
- const [isFocused, setIsFocused] = useState(false);
2727
- const isEditing = isHovered || isFocused || isOpen;
2728
- const Icon = isEditing ? Pencil : FileText;
2729
- return /* @__PURE__ */ jsxs(
2730
- Button,
2731
- {
2732
- ref,
2733
- type: "button",
2734
- variant: "outline",
2735
- "aria-label": label,
2736
- "aria-haspopup": "dialog",
2737
- "aria-expanded": isOpen,
2738
- "data-slot": "context-chip",
2739
- "data-icon": isEditing ? "edit" : "document",
2740
- className: cn(
2741
- "flex h-8 min-w-0 max-w-[280px] flex-shrink-0 items-center gap-1.5 rounded-md px-2.5",
2742
- className
2743
- ),
2744
- ...props,
2745
- onMouseEnter: (e) => {
2746
- onMouseEnter?.(e);
2747
- if (canHover()) setIsHovered(true);
2748
- },
2749
- onMouseLeave: (e) => {
2750
- onMouseLeave?.(e);
2751
- setIsHovered(false);
2752
- },
2753
- onFocus: (e) => {
2754
- onFocus?.(e);
2755
- setIsFocused(isFocusVisible(e.currentTarget));
2756
- },
2757
- onBlur: (e) => {
2758
- onBlur?.(e);
2759
- setIsFocused(false);
2760
- },
2761
- children: [
2762
- /* @__PURE__ */ jsx(Icon, { className: "h-3.5 w-3.5 flex-shrink-0", "aria-hidden": "true" }),
2763
- /* @__PURE__ */ jsx("span", { className: "flex-shrink-0 text-sm font-medium", "data-testid": "context-chip-count", children: count >= 1e3 ? "999+" : count }),
2764
- children
2765
- ]
2766
- }
2767
- );
2768
- });
2769
1529
  function useDismissibleCard({
2770
1530
  isOpen,
2771
1531
  onClose,
@@ -2860,6 +1620,6 @@ function LabelPinRow({
2860
1620
  );
2861
1621
  }
2862
1622
 
2863
- export { BranchControls, Composer, ComposerAccessories, ComposerBranchingNotice, ComposerContainer, ComposerDock, ComposerFrame, ComposerInput, ComposerRoot, ComposerSend, ComposerToolbar, ComposerTools, ComposerVoiceButton, ContextActionButton, ContextCheckRow, ContextChip, ContextPanelContent, ContextPanelFooter, ContextPanelTabs, ContextPickerList, ContextPickerRow, ContextSearchInput, ContextSelectList, ContextSelectRow, Conversation, ConversationBody, ConversationEmpty, ConversationHeader, ConversationHeaderActions, ConversationHistoryPane, ConversationLoading, ConversationMain, ConversationRoot, ConversationSearchView, ConversationSettingsButton, DEFAULT_BRANCH_CONTROLS_LABELS, DEFAULT_COMPOSER_LABELS, DEFAULT_CONVERSATION_EMPTY_LABELS, DEFAULT_CONVERSATION_LAYOUT_LABELS, DEFAULT_CONVERSATION_PARTS_LABELS, DEFAULT_CONVERSATION_SEARCH_LABELS, DEFAULT_LABEL_PIN_ROW_LABELS, DEFAULT_MESSAGE_ALERT_LABELS, DEFAULT_MESSAGE_LABELS, DEFAULT_MESSAGE_LIST_LABELS, DEFAULT_MODEL_PRICING_TIP_LABELS, DEFAULT_PENDING_ANSWER_BAR_LABELS, DEFAULT_PINNED_DOC_CHIP_LABELS, DEFAULT_SLASH_MENU_LABELS, DEFAULT_THREAD_MAP_LABELS, LabelPinRow, Message, MessageActionButton, MessageActionMenu, MessageAlert, MessageBody, MessageBubble, MessageByline, MessageContent, MessageFooter, MessageList, MessageListBanner, MessageListEmpty, MessageListRoot, MessageListRow, MessageListRows, MessageListStatus, MessageListTail, MessageNarration, MessageRoot, MessageSources, MessageSubagentBadge, ModelAutoIcon, ModelConfigureButton, ModelDot, ModelMenuDivider, ModelMenuMessage, ModelOption, ModelOptionLabel, ModelPickerPopover, ModelPickerTrigger, ModelPricingTip, ModelTierIcon, ModelTierOption, ModelTriggerContent, NewChatButton, NewPaChatButton, PaModeBadge, PendingAnswerBar, PinnedDocChip, ScrollToBottom, SlashMenu, SourceChip, ThreadMap, ThreadMapDiagram, ThreadMapError, ThreadMapLoading, isLongPastedText, toSpeakableText, useDismissibleCard, useListKeyNav, useLongPaste, useStreamAnnouncement };
2864
- //# sourceMappingURL=chunk-AZQDNYH4.js.map
2865
- //# sourceMappingURL=chunk-AZQDNYH4.js.map
1623
+ export { BranchControls, ComposerAccessories, ComposerTools, ContextActionButton, ContextCheckRow, ContextPanelContent, ContextPanelFooter, ContextPanelTabs, ContextPickerList, ContextPickerRow, ContextSearchInput, ContextSelectList, ContextSelectRow, Conversation, ConversationBody, ConversationHeader, ConversationHeaderActions, ConversationHistoryPane, ConversationLoading, ConversationMain, ConversationRoot, ConversationSearchView, ConversationSettingsButton, DEFAULT_BRANCH_CONTROLS_LABELS, DEFAULT_CONVERSATION_LAYOUT_LABELS, DEFAULT_CONVERSATION_PARTS_LABELS, DEFAULT_CONVERSATION_SEARCH_LABELS, DEFAULT_LABEL_PIN_ROW_LABELS, DEFAULT_MODEL_PRICING_TIP_LABELS, DEFAULT_PENDING_ANSWER_BAR_LABELS, DEFAULT_PINNED_DOC_CHIP_LABELS, DEFAULT_SLASH_MENU_LABELS, DEFAULT_THREAD_MAP_LABELS, LabelPinRow, ModelAutoIcon, ModelConfigureButton, ModelDot, ModelMenuDivider, ModelMenuMessage, ModelOption, ModelOptionLabel, ModelPickerPopover, ModelPickerTrigger, ModelPricingTip, ModelTierIcon, ModelTierOption, ModelTriggerContent, NewChatButton, NewPaChatButton, PaModeBadge, PendingAnswerBar, PinnedDocChip, SlashMenu, ThreadMap, ThreadMapDiagram, ThreadMapError, ThreadMapLoading, isLongPastedText, useDismissibleCard, useListKeyNav, useLongPaste };
1624
+ //# sourceMappingURL=chunk-RCP6THBS.js.map
1625
+ //# sourceMappingURL=chunk-RCP6THBS.js.map