@agents24/chat-react 0.3.2 → 0.4.0
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.
- package/LICENSE +19 -0
- package/README.md +21 -66
- package/compatibility.json +54 -0
- package/dist/active-content.d.ts +10 -0
- package/dist/{chunk-EWZO4QJI.js → chunk-CHAU7FNW.js} +3 -3
- package/dist/chunk-CHAU7FNW.js.map +1 -0
- package/dist/{chunk-FFO6KEB4.js → chunk-LI67M74F.js} +98 -12
- package/dist/chunk-LI67M74F.js.map +1 -0
- package/dist/chunk-NLEOWTZG.js +1327 -0
- package/dist/chunk-NLEOWTZG.js.map +1 -0
- package/dist/index.cjs +66 -1852
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +0 -6
- package/dist/index.js +6 -1841
- package/dist/index.js.map +1 -1
- package/dist/latest-thread-scroller.d.ts +7 -7
- package/dist/mcp-oauth.d.ts +3 -1
- package/dist/renderers.d.ts +3 -3
- package/dist/styles.css +407 -0
- package/dist/templates/agent-chat-app.d.ts +18 -0
- package/dist/templates/agent-chat-layout.d.ts +69 -0
- package/dist/templates/agent-chat-shell.d.ts +1 -1
- package/dist/templates/index.cjs +1904 -18
- package/dist/templates/index.cjs.map +1 -1
- package/dist/templates/index.d.ts +2 -0
- package/dist/templates/index.js +529 -11
- package/dist/templates/index.js.map +1 -1
- package/dist/types.d.ts +12 -380
- package/dist/ui/agent-chat-actions.d.ts +1 -2
- package/dist/ui/agent-chat-composer.d.ts +2 -1
- package/dist/ui/agent-chat-message.d.ts +3 -3
- package/dist/ui/agent-response-timeline.d.ts +2 -2
- package/dist/ui/attachment.d.ts +9 -9
- package/dist/ui/bubble.d.ts +4 -4
- package/dist/ui/index.cjs +137 -43
- package/dist/ui/index.cjs.map +1 -1
- package/dist/ui/index.js +62 -1220
- package/dist/ui/index.js.map +1 -1
- package/dist/ui/marker.d.ts +3 -3
- package/dist/ui/mcp-connect-required-card.d.ts +1 -1
- package/dist/ui/message-response.d.ts +1 -1
- package/dist/ui/message.d.ts +6 -6
- package/package.json +27 -8
- package/dist/chunk-EWZO4QJI.js.map +0 -1
- package/dist/chunk-FFO6KEB4.js.map +0 -1
- package/dist/chunk-UU7OXHL3.js +0 -11
- package/dist/chunk-UU7OXHL3.js.map +0 -1
- package/dist/context-window.d.ts +0 -38
- package/dist/controller-actions.d.ts +0 -45
- package/dist/controller-helpers.d.ts +0 -27
- package/dist/controller-hitl.d.ts +0 -22
- package/dist/controller-options.d.ts +0 -15
- package/dist/controller-thread-events.d.ts +0 -7
- package/dist/controller.d.ts +0 -5
- package/dist/message-lifecycle.d.ts +0 -15
- package/dist/model.d.ts +0 -30
- package/dist/sse.d.ts +0 -5
- package/dist/transport.d.ts +0 -43
package/dist/ui/index.js
CHANGED
|
@@ -1,1206 +1,48 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
attachmentLayout = "flow",
|
|
40
|
-
className,
|
|
41
|
-
disabled = false,
|
|
42
|
-
inputToolbarContent,
|
|
43
|
-
isRunning = false,
|
|
44
|
-
onAttachmentCountChange,
|
|
45
|
-
onStop,
|
|
46
|
-
onSubmit,
|
|
47
|
-
placeholder = "Send follow-up",
|
|
48
|
-
textareaRef
|
|
49
|
-
}) {
|
|
50
|
-
const fileInputRef = React.useRef(null);
|
|
51
|
-
const filesRef = React.useRef([]);
|
|
52
|
-
const localTextareaRef = React.useRef(null);
|
|
53
|
-
const [text, setText] = React.useState("");
|
|
54
|
-
const [files, setFiles] = React.useState([]);
|
|
55
|
-
const [isSubmitting, setIsSubmitting] = React.useState(false);
|
|
56
|
-
const isExpanded = text.includes("\n") || text.length > 62;
|
|
57
|
-
const setTextareaRef = React.useCallback(
|
|
58
|
-
(node) => {
|
|
59
|
-
localTextareaRef.current = node;
|
|
60
|
-
if (typeof textareaRef === "function") {
|
|
61
|
-
textareaRef(node);
|
|
62
|
-
} else if (textareaRef) {
|
|
63
|
-
textareaRef.current = node;
|
|
64
|
-
}
|
|
65
|
-
},
|
|
66
|
-
[textareaRef]
|
|
67
|
-
);
|
|
68
|
-
React.useEffect(() => {
|
|
69
|
-
filesRef.current = files;
|
|
70
|
-
onAttachmentCountChange?.(files.length);
|
|
71
|
-
}, [files, onAttachmentCountChange]);
|
|
72
|
-
React.useEffect(() => () => revokeComposerFiles(filesRef.current), []);
|
|
73
|
-
React.useLayoutEffect(() => {
|
|
74
|
-
const textarea = localTextareaRef.current;
|
|
75
|
-
if (!textarea) return;
|
|
76
|
-
if (isExpanded) {
|
|
77
|
-
textarea.style.height = "auto";
|
|
78
|
-
const scrollHeight = textarea.scrollHeight;
|
|
79
|
-
textarea.style.height = `${Math.min(scrollHeight, 224)}px`;
|
|
80
|
-
textarea.style.overflowY = scrollHeight >= 224 ? "auto" : "hidden";
|
|
81
|
-
return;
|
|
82
|
-
}
|
|
83
|
-
textarea.style.height = "";
|
|
84
|
-
textarea.style.overflowY = "hidden";
|
|
85
|
-
}, [isExpanded, text]);
|
|
86
|
-
const canSubmit = !disabled && !isSubmitting && !isRunning && (text.trim().length > 0 || files.length > 0);
|
|
87
|
-
const handleFilesChange = (event) => {
|
|
88
|
-
const selected = Array.from(event.target.files || []).map(createComposerFile);
|
|
89
|
-
if (selected.length > 0) {
|
|
90
|
-
setFiles((current) => [...current, ...selected]);
|
|
91
|
-
}
|
|
92
|
-
event.currentTarget.value = "";
|
|
93
|
-
};
|
|
94
|
-
const removeFile = (fileId) => {
|
|
95
|
-
setFiles((current) => {
|
|
96
|
-
const target = current.find((file) => file.id === fileId);
|
|
97
|
-
if (target) revokeComposerFiles([target]);
|
|
98
|
-
return current.filter((file) => file.id !== fileId);
|
|
99
|
-
});
|
|
100
|
-
};
|
|
101
|
-
const submit = async () => {
|
|
102
|
-
if (!canSubmit) return;
|
|
103
|
-
const submittedText = text.trim();
|
|
104
|
-
const submittedFiles = files;
|
|
105
|
-
setIsSubmitting(true);
|
|
106
|
-
try {
|
|
107
|
-
await onSubmit({ text: submittedText, files: submittedFiles });
|
|
108
|
-
setText("");
|
|
109
|
-
setFiles([]);
|
|
110
|
-
revokeComposerFiles(submittedFiles);
|
|
111
|
-
} finally {
|
|
112
|
-
setIsSubmitting(false);
|
|
113
|
-
}
|
|
114
|
-
};
|
|
115
|
-
const handleKeyDown = (event) => {
|
|
116
|
-
if (event.key === "Enter" && !event.shiftKey) {
|
|
117
|
-
event.preventDefault();
|
|
118
|
-
void submit();
|
|
119
|
-
}
|
|
120
|
-
};
|
|
121
|
-
return /* @__PURE__ */ jsxs("div", { className: cn("relative mx-auto w-full max-w-3xl overflow-visible", className), children: [
|
|
122
|
-
files.length > 0 ? /* @__PURE__ */ jsx(
|
|
123
|
-
"div",
|
|
124
|
-
{
|
|
125
|
-
"data-testid": "agent-chat-composer-attachments",
|
|
126
|
-
className: cn(
|
|
127
|
-
"flex min-w-0 gap-2 py-1",
|
|
128
|
-
attachmentLayout === "overlay" ? "absolute bottom-full left-0 right-0 mb-1.5 flex-nowrap overflow-x-auto overflow-y-hidden overscroll-x-contain px-2" : "mb-2 flex-wrap px-1"
|
|
129
|
-
),
|
|
130
|
-
children: files.map((file) => /* @__PURE__ */ jsxs(
|
|
131
|
-
"div",
|
|
132
|
-
{
|
|
133
|
-
className: "group relative flex h-8 max-w-[min(20rem,calc(100vw-2rem))] cursor-default select-none items-center gap-1.5 rounded-md border border-neutral-200 bg-white px-1.5 text-sm font-medium text-foreground transition-colors hover:bg-neutral-50",
|
|
134
|
-
children: [
|
|
135
|
-
/* @__PURE__ */ jsx("span", { className: "flex size-5 shrink-0 items-center justify-center rounded bg-background text-muted-foreground", children: /* @__PURE__ */ jsx(Paperclip, { className: "size-3" }) }),
|
|
136
|
-
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate", children: file.filename }),
|
|
137
|
-
/* @__PURE__ */ jsx(
|
|
138
|
-
"button",
|
|
139
|
-
{
|
|
140
|
-
"aria-label": `Remove ${file.filename}`,
|
|
141
|
-
className: "inline-flex size-5 shrink-0 items-center justify-center rounded text-muted-foreground opacity-70 transition-colors hover:bg-muted hover:text-foreground hover:opacity-100 focus-visible:outline-none",
|
|
142
|
-
onClick: () => removeFile(file.id),
|
|
143
|
-
type: "button",
|
|
144
|
-
children: /* @__PURE__ */ jsx(X, { className: "size-3" })
|
|
145
|
-
}
|
|
146
|
-
)
|
|
147
|
-
]
|
|
148
|
-
},
|
|
149
|
-
file.id
|
|
150
|
-
))
|
|
151
|
-
}
|
|
152
|
-
) : null,
|
|
153
|
-
/* @__PURE__ */ jsx(
|
|
154
|
-
"div",
|
|
155
|
-
{
|
|
156
|
-
className: cn(
|
|
157
|
-
"relative w-full border border-neutral-200 bg-white shadow-sm transition-colors duration-200 focus-within:border-neutral-300 dark:border-neutral-700 dark:bg-card dark:focus-within:border-neutral-600",
|
|
158
|
-
isExpanded ? "rounded-[18px] p-2 pb-1.5" : "rounded-full px-2 py-[3px]"
|
|
159
|
-
),
|
|
160
|
-
children: /* @__PURE__ */ jsxs(
|
|
161
|
-
"div",
|
|
162
|
-
{
|
|
163
|
-
className: "w-full",
|
|
164
|
-
style: {
|
|
165
|
-
alignItems: "center",
|
|
166
|
-
display: "grid",
|
|
167
|
-
gridTemplateAreas: isExpanded ? `"textarea textarea textarea" "plus toolbar submit"` : `"plus textarea composer mic submit"`,
|
|
168
|
-
gridTemplateColumns: isExpanded ? "auto 1fr auto" : "auto 1fr auto auto auto",
|
|
169
|
-
gap: isExpanded ? "3px 10px" : "8px"
|
|
170
|
-
},
|
|
171
|
-
children: [
|
|
172
|
-
/* @__PURE__ */ jsxs("div", { style: { gridArea: "plus" }, className: "flex shrink-0 items-center justify-center", children: [
|
|
173
|
-
/* @__PURE__ */ jsx(
|
|
174
|
-
"input",
|
|
175
|
-
{
|
|
176
|
-
ref: fileInputRef,
|
|
177
|
-
accept,
|
|
178
|
-
"aria-label": "Attach files",
|
|
179
|
-
className: "hidden",
|
|
180
|
-
multiple: true,
|
|
181
|
-
onChange: handleFilesChange,
|
|
182
|
-
type: "file"
|
|
183
|
-
}
|
|
184
|
-
),
|
|
185
|
-
/* @__PURE__ */ jsx(
|
|
186
|
-
"button",
|
|
187
|
-
{
|
|
188
|
-
"aria-label": "Attach files",
|
|
189
|
-
className: pillButtonClass,
|
|
190
|
-
disabled: disabled || isSubmitting || isRunning || !allowAttachments,
|
|
191
|
-
onClick: () => fileInputRef.current?.click(),
|
|
192
|
-
title: "Attach files",
|
|
193
|
-
type: "button",
|
|
194
|
-
children: /* @__PURE__ */ jsx(Plus, { className: "size-4" })
|
|
195
|
-
}
|
|
196
|
-
)
|
|
197
|
-
] }),
|
|
198
|
-
/* @__PURE__ */ jsx("div", { style: { gridArea: "textarea" }, className: "min-w-0 w-full", children: /* @__PURE__ */ jsx(
|
|
199
|
-
"textarea",
|
|
200
|
-
{
|
|
201
|
-
ref: setTextareaRef,
|
|
202
|
-
"aria-label": "Message",
|
|
203
|
-
className: cn(
|
|
204
|
-
"w-full resize-none border-0 bg-transparent px-1 text-[15px] leading-relaxed text-foreground shadow-none outline-none placeholder:text-neutral-400 focus-visible:ring-0 scrollbar-thin",
|
|
205
|
-
isExpanded ? "min-h-9 max-h-[224px] py-1" : "min-h-9 h-9 max-h-9 py-2"
|
|
206
|
-
),
|
|
207
|
-
disabled: disabled || isSubmitting || isRunning,
|
|
208
|
-
onChange: (event) => setText(event.target.value),
|
|
209
|
-
onKeyDown: handleKeyDown,
|
|
210
|
-
placeholder,
|
|
211
|
-
rows: isExpanded ? 2 : 1,
|
|
212
|
-
value: text
|
|
213
|
-
}
|
|
214
|
-
) }),
|
|
215
|
-
isExpanded ? /* @__PURE__ */ jsx("div", { style: { gridArea: "toolbar" }, className: "flex min-w-0 items-center gap-1.5", children: inputToolbarContent }) : null,
|
|
216
|
-
!isExpanded ? /* @__PURE__ */ jsx("div", { style: { gridArea: "composer" }, className: "flex min-w-0 items-center gap-1.5" }) : null,
|
|
217
|
-
!isExpanded ? /* @__PURE__ */ jsx("div", { style: { gridArea: "mic" }, className: "flex shrink-0 items-center justify-end" }) : null,
|
|
218
|
-
/* @__PURE__ */ jsx("div", { style: { gridArea: "submit" }, className: "flex shrink-0 items-center justify-end", children: isRunning ? /* @__PURE__ */ jsx(
|
|
219
|
-
"button",
|
|
220
|
-
{
|
|
221
|
-
"aria-label": "Stop generating",
|
|
222
|
-
className: submitButtonClass,
|
|
223
|
-
disabled: disabled || !onStop,
|
|
224
|
-
onClick: onStop,
|
|
225
|
-
title: "Stop",
|
|
226
|
-
type: "button",
|
|
227
|
-
children: /* @__PURE__ */ jsx(Square, { className: "size-3.5 fill-current" })
|
|
228
|
-
}
|
|
229
|
-
) : /* @__PURE__ */ jsx(
|
|
230
|
-
"button",
|
|
231
|
-
{
|
|
232
|
-
"aria-label": files.length > 0 ? `Send ${formatFileCount(files)}` : "Send message",
|
|
233
|
-
className: cn(submitButtonClass, text.trim().length > 0 && "hover:scale-105"),
|
|
234
|
-
disabled: !canSubmit,
|
|
235
|
-
onClick: () => void submit(),
|
|
236
|
-
title: "Send",
|
|
237
|
-
type: "button",
|
|
238
|
-
children: /* @__PURE__ */ jsx(ArrowUp, { className: "size-4", strokeWidth: 2.5 })
|
|
239
|
-
}
|
|
240
|
-
) })
|
|
241
|
-
]
|
|
242
|
-
}
|
|
243
|
-
)
|
|
244
|
-
}
|
|
245
|
-
),
|
|
246
|
-
!isExpanded && inputToolbarContent ? /* @__PURE__ */ jsx("div", { className: "mt-2 flex items-center gap-2 px-1", children: inputToolbarContent }) : null
|
|
247
|
-
] });
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
// src/ui/agent-chat-actions.tsx
|
|
251
|
-
import { Check, Copy, RefreshCcw, ThumbsDown, ThumbsUp } from "lucide-react";
|
|
252
|
-
|
|
253
|
-
// src/ui/adapters.ts
|
|
254
|
-
import * as React2 from "react";
|
|
2
|
+
AgentChatComposer,
|
|
3
|
+
AgentChatDefaultActions,
|
|
4
|
+
AgentChatMessage,
|
|
5
|
+
AgentChatUserMessageContent,
|
|
6
|
+
AgentResponseTimeline,
|
|
7
|
+
Attachment,
|
|
8
|
+
AttachmentAction,
|
|
9
|
+
AttachmentActions,
|
|
10
|
+
AttachmentContent,
|
|
11
|
+
AttachmentDescription,
|
|
12
|
+
AttachmentGroup,
|
|
13
|
+
AttachmentMedia,
|
|
14
|
+
AttachmentTitle,
|
|
15
|
+
AttachmentTrigger,
|
|
16
|
+
ChatAttachment,
|
|
17
|
+
ChatAttachments,
|
|
18
|
+
ChatMessage,
|
|
19
|
+
ChatMessageAction,
|
|
20
|
+
ChatMessageActions,
|
|
21
|
+
ChatMessageContent,
|
|
22
|
+
DefaultPartRow,
|
|
23
|
+
Message,
|
|
24
|
+
MessageAvatar,
|
|
25
|
+
MessageContent,
|
|
26
|
+
MessageFooter,
|
|
27
|
+
MessageGroup,
|
|
28
|
+
MessageHeader,
|
|
29
|
+
MessageResponse,
|
|
30
|
+
attachmentMediaVariants,
|
|
31
|
+
attachmentVariants,
|
|
32
|
+
cn,
|
|
33
|
+
hitlActionLabel,
|
|
34
|
+
hitlTitle,
|
|
35
|
+
resolvedHitlLabel,
|
|
36
|
+
shouldCollapseUserMessage
|
|
37
|
+
} from "../chunk-NLEOWTZG.js";
|
|
38
|
+
import "../chunk-CHAU7FNW.js";
|
|
255
39
|
|
|
256
|
-
// src/ui/
|
|
40
|
+
// src/ui/bubble.tsx
|
|
257
41
|
import { cva } from "class-variance-authority";
|
|
258
42
|
import { Slot } from "@radix-ui/react-slot";
|
|
259
|
-
import { jsx
|
|
260
|
-
var attachmentVariants = cva(
|
|
261
|
-
"group/attachment relative flex w-fit max-w-full min-w-0 shrink-0 flex-wrap rounded-xl border bg-card text-card-foreground transition-colors focus-within:border-neutral-300 focus-within:ring-0 has-[>a,>button]:hover:bg-muted/50 data-[state=error]:border-destructive/30 data-[state=idle]:border-dashed",
|
|
262
|
-
{
|
|
263
|
-
variants: {
|
|
264
|
-
size: {
|
|
265
|
-
default: "gap-2 text-sm has-data-[slot=attachment-content]:px-2.5 has-data-[slot=attachment-content]:py-2 has-data-[slot=attachment-media]:p-2",
|
|
266
|
-
sm: "gap-2.5 text-xs has-data-[slot=attachment-content]:px-2 has-data-[slot=attachment-content]:py-1.5 has-data-[slot=attachment-media]:p-1.5",
|
|
267
|
-
xs: "gap-1.5 rounded-lg text-xs has-data-[slot=attachment-content]:px-1.5 has-data-[slot=attachment-content]:py-1 has-data-[slot=attachment-media]:p-1"
|
|
268
|
-
},
|
|
269
|
-
orientation: {
|
|
270
|
-
horizontal: "min-w-40 items-center",
|
|
271
|
-
vertical: "w-24 flex-col has-data-[slot=attachment-content]:w-30"
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
);
|
|
276
|
-
function Attachment({
|
|
277
|
-
className,
|
|
278
|
-
state = "done",
|
|
279
|
-
size = "default",
|
|
280
|
-
orientation = "horizontal",
|
|
281
|
-
...props
|
|
282
|
-
}) {
|
|
283
|
-
return /* @__PURE__ */ jsx2(
|
|
284
|
-
"div",
|
|
285
|
-
{
|
|
286
|
-
"data-slot": "attachment",
|
|
287
|
-
"data-state": state,
|
|
288
|
-
"data-size": size,
|
|
289
|
-
"data-orientation": orientation,
|
|
290
|
-
className: cn(attachmentVariants({ size, orientation }), className),
|
|
291
|
-
...props
|
|
292
|
-
}
|
|
293
|
-
);
|
|
294
|
-
}
|
|
295
|
-
var attachmentMediaVariants = cva(
|
|
296
|
-
"relative flex aspect-square w-10 shrink-0 items-center justify-center overflow-hidden rounded-lg bg-muted text-foreground group-data-[orientation=vertical]/attachment:w-full group-data-[size=sm]/attachment:w-8 group-data-[size=xs]/attachment:w-7 group-data-[size=xs]/attachment:rounded-md group-data-[state=error]/attachment:bg-destructive/10 group-data-[state=error]/attachment:text-destructive group-data-[orientation=vertical]/attachment:*:data-[slot=spinner]:size-6! [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 group-data-[orientation=vertical]/attachment:[&_svg:not([class*='size-'])]:size-6 group-data-[size=xs]/attachment:[&_svg:not([class*='size-'])]:size-3.5",
|
|
297
|
-
{
|
|
298
|
-
variants: {
|
|
299
|
-
variant: {
|
|
300
|
-
icon: "",
|
|
301
|
-
image: "opacity-60 group-data-[state=done]/attachment:opacity-100 group-data-[state=idle]/attachment:opacity-100 *:[img]:aspect-square *:[img]:w-full *:[img]:object-cover"
|
|
302
|
-
}
|
|
303
|
-
},
|
|
304
|
-
defaultVariants: {
|
|
305
|
-
variant: "icon"
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
);
|
|
309
|
-
function AttachmentMedia({
|
|
310
|
-
className,
|
|
311
|
-
variant = "icon",
|
|
312
|
-
...props
|
|
313
|
-
}) {
|
|
314
|
-
return /* @__PURE__ */ jsx2(
|
|
315
|
-
"div",
|
|
316
|
-
{
|
|
317
|
-
"data-slot": "attachment-media",
|
|
318
|
-
"data-variant": variant,
|
|
319
|
-
className: cn(attachmentMediaVariants({ variant }), className),
|
|
320
|
-
...props
|
|
321
|
-
}
|
|
322
|
-
);
|
|
323
|
-
}
|
|
324
|
-
function AttachmentContent({
|
|
325
|
-
className,
|
|
326
|
-
...props
|
|
327
|
-
}) {
|
|
328
|
-
return /* @__PURE__ */ jsx2(
|
|
329
|
-
"div",
|
|
330
|
-
{
|
|
331
|
-
"data-slot": "attachment-content",
|
|
332
|
-
className: cn(
|
|
333
|
-
"max-w-full min-w-0 flex-1 leading-tight group-data-[orientation=vertical]/attachment:px-1",
|
|
334
|
-
className
|
|
335
|
-
),
|
|
336
|
-
...props
|
|
337
|
-
}
|
|
338
|
-
);
|
|
339
|
-
}
|
|
340
|
-
function AttachmentTitle({
|
|
341
|
-
className,
|
|
342
|
-
...props
|
|
343
|
-
}) {
|
|
344
|
-
return /* @__PURE__ */ jsx2(
|
|
345
|
-
"span",
|
|
346
|
-
{
|
|
347
|
-
"data-slot": "attachment-title",
|
|
348
|
-
className: cn(
|
|
349
|
-
"block max-w-full min-w-0 truncate font-medium group-data-[state=processing]/attachment:shimmer group-data-[state=uploading]/attachment:shimmer",
|
|
350
|
-
className
|
|
351
|
-
),
|
|
352
|
-
...props
|
|
353
|
-
}
|
|
354
|
-
);
|
|
355
|
-
}
|
|
356
|
-
function AttachmentDescription({
|
|
357
|
-
className,
|
|
358
|
-
...props
|
|
359
|
-
}) {
|
|
360
|
-
return /* @__PURE__ */ jsx2(
|
|
361
|
-
"span",
|
|
362
|
-
{
|
|
363
|
-
"data-slot": "attachment-description",
|
|
364
|
-
className: cn(
|
|
365
|
-
"mt-0.5 block min-w-0 truncate text-xs text-muted-foreground group-data-[state=error]/attachment:text-destructive/80",
|
|
366
|
-
"max-w-full",
|
|
367
|
-
className
|
|
368
|
-
),
|
|
369
|
-
...props
|
|
370
|
-
}
|
|
371
|
-
);
|
|
372
|
-
}
|
|
373
|
-
function AttachmentActions({
|
|
374
|
-
className,
|
|
375
|
-
...props
|
|
376
|
-
}) {
|
|
377
|
-
return /* @__PURE__ */ jsx2(
|
|
378
|
-
"div",
|
|
379
|
-
{
|
|
380
|
-
"data-slot": "attachment-actions",
|
|
381
|
-
className: cn(
|
|
382
|
-
"relative z-20 flex shrink-0 items-center group-data-[orientation=vertical]/attachment:absolute group-data-[orientation=vertical]/attachment:top-3 group-data-[orientation=vertical]/attachment:right-3 group-data-[orientation=vertical]/attachment:gap-1",
|
|
383
|
-
className
|
|
384
|
-
),
|
|
385
|
-
...props
|
|
386
|
-
}
|
|
387
|
-
);
|
|
388
|
-
}
|
|
389
|
-
function AttachmentAction({
|
|
390
|
-
className,
|
|
391
|
-
type = "button",
|
|
392
|
-
...props
|
|
393
|
-
}) {
|
|
394
|
-
return /* @__PURE__ */ jsx2(
|
|
395
|
-
"button",
|
|
396
|
-
{
|
|
397
|
-
"data-slot": "attachment-action",
|
|
398
|
-
type,
|
|
399
|
-
className: cn(
|
|
400
|
-
"inline-flex size-6 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-muted hover:text-foreground focus-visible:border-neutral-300 focus-visible:outline-none focus-visible:ring-0 disabled:pointer-events-none disabled:opacity-50",
|
|
401
|
-
className
|
|
402
|
-
),
|
|
403
|
-
...props
|
|
404
|
-
}
|
|
405
|
-
);
|
|
406
|
-
}
|
|
407
|
-
function AttachmentTrigger({
|
|
408
|
-
className,
|
|
409
|
-
asChild = false,
|
|
410
|
-
type,
|
|
411
|
-
...props
|
|
412
|
-
}) {
|
|
413
|
-
const Comp = asChild ? Slot : "button";
|
|
414
|
-
return /* @__PURE__ */ jsx2(
|
|
415
|
-
Comp,
|
|
416
|
-
{
|
|
417
|
-
"data-slot": "attachment-trigger",
|
|
418
|
-
type: asChild ? void 0 : type ?? "button",
|
|
419
|
-
className: cn("absolute inset-0 z-10 outline-none", className),
|
|
420
|
-
...props
|
|
421
|
-
}
|
|
422
|
-
);
|
|
423
|
-
}
|
|
424
|
-
function AttachmentGroup({ className, ...props }) {
|
|
425
|
-
return /* @__PURE__ */ jsx2(
|
|
426
|
-
"div",
|
|
427
|
-
{
|
|
428
|
-
"data-slot": "attachment-group",
|
|
429
|
-
className: cn(
|
|
430
|
-
"flex min-w-0 scroll-fade-x snap-x snap-mandatory scroll-px-1 scrollbar-none gap-3 overflow-x-auto overscroll-x-contain py-1 *:data-[slot=attachment]:flex-none *:data-[slot=attachment]:snap-start",
|
|
431
|
-
className
|
|
432
|
-
),
|
|
433
|
-
...props
|
|
434
|
-
}
|
|
435
|
-
);
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
// src/ui/message.tsx
|
|
439
|
-
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
440
|
-
function MessageGroup({ className, ...props }) {
|
|
441
|
-
return /* @__PURE__ */ jsx3(
|
|
442
|
-
"div",
|
|
443
|
-
{
|
|
444
|
-
"data-slot": "message-group",
|
|
445
|
-
className: cn("flex min-w-0 flex-col gap-2", className),
|
|
446
|
-
...props
|
|
447
|
-
}
|
|
448
|
-
);
|
|
449
|
-
}
|
|
450
|
-
function Message({
|
|
451
|
-
className,
|
|
452
|
-
align = "start",
|
|
453
|
-
...props
|
|
454
|
-
}) {
|
|
455
|
-
return /* @__PURE__ */ jsx3(
|
|
456
|
-
"div",
|
|
457
|
-
{
|
|
458
|
-
"data-slot": "message",
|
|
459
|
-
"data-align": align,
|
|
460
|
-
className: cn(
|
|
461
|
-
"group/message relative flex w-full min-w-0 gap-2 text-sm data-[align=end]:flex-row-reverse",
|
|
462
|
-
className
|
|
463
|
-
),
|
|
464
|
-
...props
|
|
465
|
-
}
|
|
466
|
-
);
|
|
467
|
-
}
|
|
468
|
-
function MessageAvatar({ className, ...props }) {
|
|
469
|
-
return /* @__PURE__ */ jsx3(
|
|
470
|
-
"div",
|
|
471
|
-
{
|
|
472
|
-
"data-slot": "message-avatar",
|
|
473
|
-
className: cn(
|
|
474
|
-
"flex w-fit min-w-8 shrink-0 items-center justify-center self-end overflow-hidden rounded-full bg-muted group-has-data-[slot=message-footer]/message:-translate-y-8",
|
|
475
|
-
className
|
|
476
|
-
),
|
|
477
|
-
...props
|
|
478
|
-
}
|
|
479
|
-
);
|
|
480
|
-
}
|
|
481
|
-
function MessageContent({ className, ...props }) {
|
|
482
|
-
return /* @__PURE__ */ jsx3(
|
|
483
|
-
"div",
|
|
484
|
-
{
|
|
485
|
-
"data-slot": "message-content",
|
|
486
|
-
className: cn(
|
|
487
|
-
"flex w-full min-w-0 flex-col gap-2.5 wrap-break-word group-data-[align=end]/message:*:data-slot:self-end",
|
|
488
|
-
className
|
|
489
|
-
),
|
|
490
|
-
...props
|
|
491
|
-
}
|
|
492
|
-
);
|
|
493
|
-
}
|
|
494
|
-
function MessageHeader({ className, ...props }) {
|
|
495
|
-
return /* @__PURE__ */ jsx3(
|
|
496
|
-
"div",
|
|
497
|
-
{
|
|
498
|
-
"data-slot": "message-header",
|
|
499
|
-
className: cn(
|
|
500
|
-
"flex max-w-full min-w-0 items-center px-3 text-xs font-medium text-muted-foreground group-has-data-[variant=ghost]/message:px-0",
|
|
501
|
-
className
|
|
502
|
-
),
|
|
503
|
-
...props
|
|
504
|
-
}
|
|
505
|
-
);
|
|
506
|
-
}
|
|
507
|
-
function MessageFooter({ className, ...props }) {
|
|
508
|
-
return /* @__PURE__ */ jsx3(
|
|
509
|
-
"div",
|
|
510
|
-
{
|
|
511
|
-
"data-slot": "message-footer",
|
|
512
|
-
className: cn(
|
|
513
|
-
"flex max-w-full min-w-0 items-center px-3 text-xs font-medium text-muted-foreground group-has-data-[variant=ghost]/message:px-0 group-data-[align=end]/message:justify-end",
|
|
514
|
-
className
|
|
515
|
-
),
|
|
516
|
-
...props
|
|
517
|
-
}
|
|
518
|
-
);
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
// src/ui/adapters.ts
|
|
522
|
-
function ChatMessage(input) {
|
|
523
|
-
const { className, from, align, ...props } = input;
|
|
524
|
-
const isUser = from === "user";
|
|
525
|
-
const isRtl = props.dir === "rtl";
|
|
526
|
-
const resolvedAlign = align || "start";
|
|
527
|
-
const messageProps = Object.assign({}, props);
|
|
528
|
-
messageProps.align = resolvedAlign;
|
|
529
|
-
messageProps.className = cn(
|
|
530
|
-
"group flex w-full max-w-[80%] flex-col gap-2",
|
|
531
|
-
isUser ? cn("is-user justify-end", isRtl ? "mr-auto" : "ml-auto") : "is-assistant",
|
|
532
|
-
className
|
|
533
|
-
);
|
|
534
|
-
return React2.createElement(Message, messageProps);
|
|
535
|
-
}
|
|
536
|
-
function ChatMessageContent({
|
|
537
|
-
className,
|
|
538
|
-
...props
|
|
539
|
-
}) {
|
|
540
|
-
return React2.createElement("div", {
|
|
541
|
-
className: cn(
|
|
542
|
-
"is-user:dark flex w-fit max-w-full min-w-0 flex-col gap-2 overflow-hidden text-sm",
|
|
543
|
-
"group-[.is-user]:rounded-lg group-[.is-user]:bg-secondary group-[.is-user]:px-4 group-[.is-user]:py-3 group-[.is-user]:text-foreground",
|
|
544
|
-
"group-[.is-assistant]:w-full group-[.is-assistant]:max-w-full group-[.is-assistant]:text-foreground",
|
|
545
|
-
props.dir === "rtl" ? "group-[.is-user]:mr-auto" : "group-[.is-user]:ml-auto",
|
|
546
|
-
className
|
|
547
|
-
),
|
|
548
|
-
"data-slot": "message-content",
|
|
549
|
-
...props
|
|
550
|
-
});
|
|
551
|
-
}
|
|
552
|
-
function ChatMessageActions({
|
|
553
|
-
className,
|
|
554
|
-
...props
|
|
555
|
-
}) {
|
|
556
|
-
return React2.createElement("div", {
|
|
557
|
-
className: cn("flex items-center gap-1", className),
|
|
558
|
-
"data-slot": "message-actions",
|
|
559
|
-
...props
|
|
560
|
-
});
|
|
561
|
-
}
|
|
562
|
-
function ChatMessageAction({
|
|
563
|
-
children,
|
|
564
|
-
className,
|
|
565
|
-
label,
|
|
566
|
-
tooltip,
|
|
567
|
-
type = "button",
|
|
568
|
-
...props
|
|
569
|
-
}) {
|
|
570
|
-
const tooltipLabel = typeof tooltip === "string" ? tooltip : void 0;
|
|
571
|
-
return React2.createElement(
|
|
572
|
-
"button",
|
|
573
|
-
{
|
|
574
|
-
"aria-label": label || tooltipLabel,
|
|
575
|
-
className: cn(
|
|
576
|
-
"inline-flex size-8 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-muted hover:text-foreground focus-visible:border-neutral-300 focus-visible:outline-none focus-visible:ring-0 disabled:pointer-events-none disabled:opacity-50",
|
|
577
|
-
className
|
|
578
|
-
),
|
|
579
|
-
title: tooltipLabel,
|
|
580
|
-
type,
|
|
581
|
-
...props
|
|
582
|
-
},
|
|
583
|
-
children,
|
|
584
|
-
React2.createElement(
|
|
585
|
-
"span",
|
|
586
|
-
{ className: "sr-only" },
|
|
587
|
-
label || tooltipLabel
|
|
588
|
-
)
|
|
589
|
-
);
|
|
590
|
-
}
|
|
591
|
-
function ChatAttachment({
|
|
592
|
-
data,
|
|
593
|
-
onRemove,
|
|
594
|
-
orientation,
|
|
595
|
-
...props
|
|
596
|
-
}) {
|
|
597
|
-
const mediaType = data.mediaType || data.contentType || String(data.type || "application/octet-stream");
|
|
598
|
-
const filename = data.filename || data.name || "Attachment";
|
|
599
|
-
const isImage = mediaType.startsWith("image/") && Boolean(data.url);
|
|
600
|
-
return React2.createElement(
|
|
601
|
-
Attachment,
|
|
602
|
-
{
|
|
603
|
-
orientation: orientation || (isImage ? "vertical" : "horizontal"),
|
|
604
|
-
...props
|
|
605
|
-
},
|
|
606
|
-
React2.createElement(
|
|
607
|
-
AttachmentMedia,
|
|
608
|
-
{ variant: isImage ? "image" : "icon" },
|
|
609
|
-
isImage ? React2.createElement("img", {
|
|
610
|
-
alt: filename,
|
|
611
|
-
className: "size-full object-cover",
|
|
612
|
-
src: data.url
|
|
613
|
-
}) : React2.createElement(
|
|
614
|
-
"span",
|
|
615
|
-
{ "aria-hidden": "true", className: "text-sm" },
|
|
616
|
-
filename.slice(0, 1).toUpperCase()
|
|
617
|
-
)
|
|
618
|
-
),
|
|
619
|
-
React2.createElement(
|
|
620
|
-
AttachmentContent,
|
|
621
|
-
null,
|
|
622
|
-
React2.createElement(AttachmentTitle, null, filename),
|
|
623
|
-
React2.createElement(AttachmentDescription, null, mediaType)
|
|
624
|
-
),
|
|
625
|
-
onRemove ? React2.createElement(
|
|
626
|
-
"button",
|
|
627
|
-
{
|
|
628
|
-
"aria-label": "Remove attachment",
|
|
629
|
-
className: "relative z-20 mr-1 inline-flex size-6 shrink-0 items-center justify-center rounded-md text-muted-foreground hover:bg-muted hover:text-foreground",
|
|
630
|
-
onClick: (event) => {
|
|
631
|
-
event.stopPropagation();
|
|
632
|
-
onRemove();
|
|
633
|
-
},
|
|
634
|
-
type: "button"
|
|
635
|
-
},
|
|
636
|
-
React2.createElement("span", { "aria-hidden": "true" }, "x")
|
|
637
|
-
) : null
|
|
638
|
-
);
|
|
639
|
-
}
|
|
640
|
-
function ChatAttachments({
|
|
641
|
-
children,
|
|
642
|
-
className,
|
|
643
|
-
...props
|
|
644
|
-
}) {
|
|
645
|
-
if (!children) return null;
|
|
646
|
-
return React2.createElement(
|
|
647
|
-
AttachmentGroup,
|
|
648
|
-
{
|
|
649
|
-
className: cn(
|
|
650
|
-
props.dir === "rtl" ? "mr-auto" : "ml-auto",
|
|
651
|
-
"w-fit flex-wrap overflow-visible",
|
|
652
|
-
className
|
|
653
|
-
),
|
|
654
|
-
...props
|
|
655
|
-
},
|
|
656
|
-
children
|
|
657
|
-
);
|
|
658
|
-
}
|
|
659
|
-
|
|
660
|
-
// src/ui/agent-chat-actions.tsx
|
|
661
|
-
import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
662
|
-
function AgentChatDefaultActions({
|
|
663
|
-
handlers,
|
|
664
|
-
message
|
|
665
|
-
}) {
|
|
666
|
-
if (!handlers || message.role !== "assistant" || message.isFinal === false) return null;
|
|
667
|
-
return /* @__PURE__ */ jsxs2(ChatMessageActions, { children: [
|
|
668
|
-
handlers.onRetry ? /* @__PURE__ */ jsx4(
|
|
669
|
-
ChatMessageAction,
|
|
670
|
-
{
|
|
671
|
-
label: "Retry",
|
|
672
|
-
onClick: () => void handlers.onRetry?.(message),
|
|
673
|
-
tooltip: "Regenerate response",
|
|
674
|
-
children: /* @__PURE__ */ jsx4(RefreshCcw, { className: "size-4" })
|
|
675
|
-
}
|
|
676
|
-
) : null,
|
|
677
|
-
handlers.onLike ? /* @__PURE__ */ jsx4(
|
|
678
|
-
ChatMessageAction,
|
|
679
|
-
{
|
|
680
|
-
label: "Like",
|
|
681
|
-
onClick: () => void handlers.onLike?.(message),
|
|
682
|
-
tooltip: "Like this response",
|
|
683
|
-
children: /* @__PURE__ */ jsx4(ThumbsUp, { className: "size-4", fill: handlers.liked ? "currentColor" : "none" })
|
|
684
|
-
}
|
|
685
|
-
) : null,
|
|
686
|
-
handlers.onDislike ? /* @__PURE__ */ jsx4(
|
|
687
|
-
ChatMessageAction,
|
|
688
|
-
{
|
|
689
|
-
label: "Dislike",
|
|
690
|
-
onClick: () => void handlers.onDislike?.(message),
|
|
691
|
-
tooltip: "Dislike this response",
|
|
692
|
-
children: /* @__PURE__ */ jsx4(ThumbsDown, { className: "size-4", fill: handlers.disliked ? "currentColor" : "none" })
|
|
693
|
-
}
|
|
694
|
-
) : null,
|
|
695
|
-
handlers.onCopy ? /* @__PURE__ */ jsx4(
|
|
696
|
-
ChatMessageAction,
|
|
697
|
-
{
|
|
698
|
-
label: "Copy",
|
|
699
|
-
onClick: () => handlers.onCopy?.(message.content || "", message.id),
|
|
700
|
-
tooltip: handlers.copied ? "Copied!" : "Copy to clipboard",
|
|
701
|
-
children: handlers.copied ? /* @__PURE__ */ jsx4(Check, { className: "size-4 text-green-600" }) : /* @__PURE__ */ jsx4(Copy, { className: "size-4" })
|
|
702
|
-
}
|
|
703
|
-
) : null
|
|
704
|
-
] });
|
|
705
|
-
}
|
|
706
|
-
|
|
707
|
-
// src/ui/agent-chat-message.tsx
|
|
708
|
-
import * as React5 from "react";
|
|
709
|
-
import { ChevronDown as ChevronDown2, ChevronUp } from "lucide-react";
|
|
710
|
-
|
|
711
|
-
// src/ui/agent-response-timeline.tsx
|
|
712
|
-
import * as React4 from "react";
|
|
713
|
-
import { ChevronDown, ChevronRight } from "lucide-react";
|
|
714
|
-
|
|
715
|
-
// src/ui/message-response.tsx
|
|
716
|
-
import * as React3 from "react";
|
|
717
|
-
import { defaultRehypePlugins, Streamdown } from "streamdown";
|
|
718
|
-
import { Fragment, jsx as jsx5 } from "react/jsx-runtime";
|
|
719
|
-
var BLOCK_MARKDOWN_TAGS = /* @__PURE__ */ new Set([
|
|
720
|
-
"blockquote",
|
|
721
|
-
"div",
|
|
722
|
-
"h1",
|
|
723
|
-
"h2",
|
|
724
|
-
"h3",
|
|
725
|
-
"h4",
|
|
726
|
-
"h5",
|
|
727
|
-
"h6",
|
|
728
|
-
"hr",
|
|
729
|
-
"ol",
|
|
730
|
-
"pre",
|
|
731
|
-
"table",
|
|
732
|
-
"ul"
|
|
733
|
-
]);
|
|
734
|
-
function isMultilineCodeNode(node) {
|
|
735
|
-
return node?.tagName === "code" && node.position?.start?.line !== void 0 && node.position?.end?.line !== void 0 && node.position.start.line !== node.position.end.line;
|
|
736
|
-
}
|
|
737
|
-
function hasBlockMarkdownChild(child) {
|
|
738
|
-
if (!React3.isValidElement(child)) {
|
|
739
|
-
return false;
|
|
740
|
-
}
|
|
741
|
-
if (typeof child.type === "string" && BLOCK_MARKDOWN_TAGS.has(child.type)) {
|
|
742
|
-
return true;
|
|
743
|
-
}
|
|
744
|
-
const props = child.props;
|
|
745
|
-
if (BLOCK_MARKDOWN_TAGS.has(props.node?.tagName || "") || isMultilineCodeNode(props.node)) {
|
|
746
|
-
return true;
|
|
747
|
-
}
|
|
748
|
-
return React3.Children.toArray(props.children).some(hasBlockMarkdownChild);
|
|
749
|
-
}
|
|
750
|
-
function MessageMarkdownParagraph({
|
|
751
|
-
children,
|
|
752
|
-
...props
|
|
753
|
-
}) {
|
|
754
|
-
const domProps = { ...props };
|
|
755
|
-
delete domProps.node;
|
|
756
|
-
const childArray = React3.Children.toArray(children).filter(
|
|
757
|
-
(child) => child !== null && child !== ""
|
|
758
|
-
);
|
|
759
|
-
const isImageOnly = childArray.length === 1 && React3.isValidElement(childArray[0]) && childArray[0].props.node?.tagName === "img";
|
|
760
|
-
if (isImageOnly) {
|
|
761
|
-
return /* @__PURE__ */ jsx5(Fragment, { children });
|
|
762
|
-
}
|
|
763
|
-
if (childArray.some(hasBlockMarkdownChild)) {
|
|
764
|
-
return /* @__PURE__ */ jsx5("div", { ...domProps, children });
|
|
765
|
-
}
|
|
766
|
-
return /* @__PURE__ */ jsx5("p", { ...domProps, children });
|
|
767
|
-
}
|
|
768
|
-
var MESSAGE_RESPONSE_COMPONENTS = {
|
|
769
|
-
p: MessageMarkdownParagraph
|
|
770
|
-
};
|
|
771
|
-
var streamdownDefaultRehypePlugins = defaultRehypePlugins || {};
|
|
772
|
-
var streamdownHardenPlugin = Array.isArray(
|
|
773
|
-
streamdownDefaultRehypePlugins.harden
|
|
774
|
-
) ? streamdownDefaultRehypePlugins.harden[0] : streamdownDefaultRehypePlugins.harden;
|
|
775
|
-
var MESSAGE_RESPONSE_REHYPE_PLUGINS = [
|
|
776
|
-
...Object.entries(streamdownDefaultRehypePlugins).filter(([key]) => key !== "harden").map(([, plugin]) => plugin),
|
|
777
|
-
...streamdownHardenPlugin ? [
|
|
778
|
-
[
|
|
779
|
-
streamdownHardenPlugin,
|
|
780
|
-
{
|
|
781
|
-
allowDataImages: true,
|
|
782
|
-
allowedImagePrefixes: ["*"],
|
|
783
|
-
allowedLinkPrefixes: ["*"],
|
|
784
|
-
allowedProtocols: ["*", "reshet:", "source:"],
|
|
785
|
-
defaultOrigin: void 0
|
|
786
|
-
}
|
|
787
|
-
]
|
|
788
|
-
] : []
|
|
789
|
-
];
|
|
790
|
-
var MessageResponse = React3.memo(
|
|
791
|
-
({
|
|
792
|
-
children,
|
|
793
|
-
className,
|
|
794
|
-
components,
|
|
795
|
-
rehypePlugins,
|
|
796
|
-
streaming = false,
|
|
797
|
-
streamingId,
|
|
798
|
-
...props
|
|
799
|
-
}) => {
|
|
800
|
-
const text = typeof children === "string" || typeof children === "number" ? String(children) : "";
|
|
801
|
-
const streamingText = useStreamingText({
|
|
802
|
-
charsPerSecond: 120,
|
|
803
|
-
id: streamingId || text,
|
|
804
|
-
isStreaming: streaming && text.length > 0,
|
|
805
|
-
maxCatchupChars: 32,
|
|
806
|
-
text
|
|
807
|
-
});
|
|
808
|
-
const streamdownComponents = React3.useMemo(
|
|
809
|
-
() => ({ ...MESSAGE_RESPONSE_COMPONENTS, ...components }),
|
|
810
|
-
[components]
|
|
811
|
-
);
|
|
812
|
-
return /* @__PURE__ */ jsx5(
|
|
813
|
-
Streamdown,
|
|
814
|
-
{
|
|
815
|
-
className: cn("size-full [&>*:first-child]:mt-0 [&>*:last-child]:mb-0", className),
|
|
816
|
-
components: streamdownComponents,
|
|
817
|
-
rehypePlugins: rehypePlugins || MESSAGE_RESPONSE_REHYPE_PLUGINS,
|
|
818
|
-
...props,
|
|
819
|
-
children: text ? streamingText.displayedText : children
|
|
820
|
-
}
|
|
821
|
-
);
|
|
822
|
-
},
|
|
823
|
-
(prevProps, nextProps) => prevProps.children === nextProps.children && prevProps.className === nextProps.className && prevProps.streaming === nextProps.streaming && prevProps.streamingId === nextProps.streamingId && prevProps.components === nextProps.components
|
|
824
|
-
);
|
|
825
|
-
MessageResponse.displayName = "MessageResponse";
|
|
826
|
-
|
|
827
|
-
// src/ui/hitl-presentation.ts
|
|
828
|
-
function optionalString(value) {
|
|
829
|
-
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
830
|
-
}
|
|
831
|
-
function hitlActionLabel(part, action) {
|
|
832
|
-
if (action === "approve") return ["tool_review", "app_data_permission"].includes(part.hitlKind) ? "Allow once" : "Approve";
|
|
833
|
-
if (action === "reject") return ["tool_review", "app_data_permission"].includes(part.hitlKind) ? "Don\u2019t allow" : "Reject";
|
|
834
|
-
if (action === "connect") return "Connect";
|
|
835
|
-
return "Skip";
|
|
836
|
-
}
|
|
837
|
-
function hitlTitle(part) {
|
|
838
|
-
const presentation = part.presentation || {};
|
|
839
|
-
if (part.hitlKind === "tool_review") return `Run ${optionalString(presentation.tool_name) || "this tool"}?`;
|
|
840
|
-
if (part.hitlKind === "mcp_auth") return `Connect ${optionalString(presentation.server_name) || "this service"} to continue`;
|
|
841
|
-
if (part.hitlKind === "app_data_permission") return "Allow this data change?";
|
|
842
|
-
return part.message;
|
|
843
|
-
}
|
|
844
|
-
function resolvedHitlLabel(part) {
|
|
845
|
-
const outcome = String(part.resolution?.outcome || part.status).trim().toLowerCase();
|
|
846
|
-
return {
|
|
847
|
-
approved: part.hitlKind === "user_approval" ? "Approved" : "Allowed",
|
|
848
|
-
rejected: part.hitlKind === "user_approval" ? "Rejected" : "Not allowed",
|
|
849
|
-
connected: "Connected",
|
|
850
|
-
skipped: "Skipped",
|
|
851
|
-
timeout: "Timed out",
|
|
852
|
-
expired: "Timed out",
|
|
853
|
-
cancelled: "Cancelled",
|
|
854
|
-
invalidated: "No longer available",
|
|
855
|
-
policy_denied: "Not allowed"
|
|
856
|
-
}[outcome] || outcome.replace(/_/g, " ");
|
|
857
|
-
}
|
|
858
|
-
|
|
859
|
-
// src/ui/agent-response-timeline.tsx
|
|
860
|
-
import { jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
861
|
-
function optionalString2(value) {
|
|
862
|
-
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
863
|
-
}
|
|
864
|
-
function presentationValue(part, key) {
|
|
865
|
-
const presentation = part.presentation || {};
|
|
866
|
-
const snakeKey = key.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
|
|
867
|
-
return optionalString2(presentation[key]) || optionalString2(presentation[snakeKey]);
|
|
868
|
-
}
|
|
869
|
-
function groupKey(part) {
|
|
870
|
-
return presentationValue(part, "groupKey");
|
|
871
|
-
}
|
|
872
|
-
function groupLabel(part) {
|
|
873
|
-
return presentationValue(part, "groupLabel") || toolLabel(part);
|
|
874
|
-
}
|
|
875
|
-
function toolLabel(part) {
|
|
876
|
-
return presentationValue(part, "activity") || presentationValue(part, "title") || part.toolName || "Tool activity";
|
|
877
|
-
}
|
|
878
|
-
function toolDetail(part) {
|
|
879
|
-
return presentationValue(part, "detail") || part.errorText || null;
|
|
880
|
-
}
|
|
881
|
-
function isActiveTool(part, activeToolId) {
|
|
882
|
-
return part.id === activeToolId || part.toolCallId === activeToolId || part.state === "input-available" || part.state === "input-streaming";
|
|
883
|
-
}
|
|
884
|
-
function Shimmer({ children, className }) {
|
|
885
|
-
return /* @__PURE__ */ jsx6("span", { className: cn("inline-block animate-pulse", className), children });
|
|
886
|
-
}
|
|
887
|
-
function CompactTask({
|
|
888
|
-
children,
|
|
889
|
-
defaultOpen = false,
|
|
890
|
-
detail,
|
|
891
|
-
error,
|
|
892
|
-
label,
|
|
893
|
-
loading
|
|
894
|
-
}) {
|
|
895
|
-
const [open, setOpen] = React4.useState(defaultOpen);
|
|
896
|
-
const expandable = Boolean(children || detail);
|
|
897
|
-
const content = loading ? /* @__PURE__ */ jsx6(Shimmer, { children: label }) : /* @__PURE__ */ jsx6("span", { children: label });
|
|
898
|
-
if (!expandable) {
|
|
899
|
-
return /* @__PURE__ */ jsx6("div", { className: cn("flex min-w-0 items-center gap-1.5 text-sm", error ? "text-destructive" : "text-muted-foreground"), children: content });
|
|
900
|
-
}
|
|
901
|
-
return /* @__PURE__ */ jsxs3("div", { className: "w-full", children: [
|
|
902
|
-
/* @__PURE__ */ jsxs3(
|
|
903
|
-
"button",
|
|
904
|
-
{
|
|
905
|
-
"aria-expanded": open,
|
|
906
|
-
className: cn(
|
|
907
|
-
"group flex min-w-0 items-center gap-1.5 rounded-md px-0 py-0.5 text-left text-sm transition-colors hover:text-foreground",
|
|
908
|
-
error ? "text-destructive" : "text-muted-foreground"
|
|
909
|
-
),
|
|
910
|
-
onClick: () => setOpen((value) => !value),
|
|
911
|
-
type: "button",
|
|
912
|
-
children: [
|
|
913
|
-
content,
|
|
914
|
-
open ? /* @__PURE__ */ jsx6(ChevronDown, { className: "size-3" }) : /* @__PURE__ */ jsx6(ChevronRight, { className: "size-3 opacity-70" })
|
|
915
|
-
]
|
|
916
|
-
}
|
|
917
|
-
),
|
|
918
|
-
open ? /* @__PURE__ */ jsxs3("div", { className: "mt-1 pl-4 text-sm text-muted-foreground", children: [
|
|
919
|
-
detail ? /* @__PURE__ */ jsx6("div", { children: detail }) : null,
|
|
920
|
-
children
|
|
921
|
-
] }) : null
|
|
922
|
-
] });
|
|
923
|
-
}
|
|
924
|
-
function ToolPartRow({
|
|
925
|
-
activeToolId,
|
|
926
|
-
part
|
|
927
|
-
}) {
|
|
928
|
-
return /* @__PURE__ */ jsx6("div", { "data-agents24-tool-part": part.type, "data-state": part.state, children: /* @__PURE__ */ jsx6(
|
|
929
|
-
CompactTask,
|
|
930
|
-
{
|
|
931
|
-
defaultOpen: part.state === "output-error",
|
|
932
|
-
detail: toolDetail(part),
|
|
933
|
-
error: part.state === "output-error",
|
|
934
|
-
label: toolLabel(part),
|
|
935
|
-
loading: isActiveTool(part, activeToolId)
|
|
936
|
-
}
|
|
937
|
-
) });
|
|
938
|
-
}
|
|
939
|
-
function ToolGroup({
|
|
940
|
-
activeToolId,
|
|
941
|
-
parts
|
|
942
|
-
}) {
|
|
943
|
-
const loading = parts.some((part) => isActiveTool(part, activeToolId));
|
|
944
|
-
return /* @__PURE__ */ jsx6(CompactTask, { label: groupLabel(parts[0]), loading, children: /* @__PURE__ */ jsx6("div", { className: "space-y-1", children: parts.map((part) => /* @__PURE__ */ jsxs3(
|
|
945
|
-
"div",
|
|
946
|
-
{
|
|
947
|
-
className: cn("text-sm", part.state === "output-error" ? "text-destructive" : "text-muted-foreground"),
|
|
948
|
-
children: [
|
|
949
|
-
isActiveTool(part, activeToolId) ? /* @__PURE__ */ jsx6(Shimmer, { children: toolLabel(part) }) : toolLabel(part),
|
|
950
|
-
toolDetail(part) ? /* @__PURE__ */ jsx6("span", { className: "ml-1 text-xs text-muted-foreground/75", children: toolDetail(part) }) : null
|
|
951
|
-
]
|
|
952
|
-
},
|
|
953
|
-
part.id
|
|
954
|
-
)) }) });
|
|
955
|
-
}
|
|
956
|
-
function HitlPartRow({
|
|
957
|
-
getHitlActionState,
|
|
958
|
-
isLoading,
|
|
959
|
-
onHitlAction,
|
|
960
|
-
part
|
|
961
|
-
}) {
|
|
962
|
-
const state = getHitlActionState?.(part);
|
|
963
|
-
const [comment, setComment] = React4.useState("");
|
|
964
|
-
const presentation = part.presentation || {};
|
|
965
|
-
const requireComment = presentation.require_comment === true;
|
|
966
|
-
const isTerminal = part.status !== "pending";
|
|
967
|
-
if (isTerminal) {
|
|
968
|
-
return /* @__PURE__ */ jsx6("div", { className: "px-1 py-1 text-sm text-muted-foreground", children: resolvedHitlLabel(part) });
|
|
969
|
-
}
|
|
970
|
-
return /* @__PURE__ */ jsxs3("div", { className: "space-y-2.5 rounded-lg bg-muted/45 px-3 py-2.5", children: [
|
|
971
|
-
/* @__PURE__ */ jsx6("div", { className: "text-sm font-medium text-foreground text-pretty", children: hitlTitle(part) }),
|
|
972
|
-
requireComment ? /* @__PURE__ */ jsx6(
|
|
973
|
-
"textarea",
|
|
974
|
-
{
|
|
975
|
-
"aria-label": "Approval comment",
|
|
976
|
-
className: "min-h-20 w-full resize-y rounded-md border border-border/60 bg-background px-3 py-2 text-sm outline-none focus-visible:border-neutral-300 focus-visible:ring-0 dark:focus-visible:border-neutral-600",
|
|
977
|
-
onChange: (event) => setComment(event.target.value),
|
|
978
|
-
placeholder: "Comment required",
|
|
979
|
-
value: comment
|
|
980
|
-
}
|
|
981
|
-
) : null,
|
|
982
|
-
state?.error ? /* @__PURE__ */ jsx6("div", { className: "text-sm text-destructive", children: state.error }) : null,
|
|
983
|
-
/* @__PURE__ */ jsx6("div", { className: "flex flex-wrap items-center gap-1.5", children: part.allowedActions.map((action) => /* @__PURE__ */ jsx6(
|
|
984
|
-
"button",
|
|
985
|
-
{
|
|
986
|
-
"aria-label": hitlActionLabel(part, action),
|
|
987
|
-
className: cn(
|
|
988
|
-
"min-h-10 rounded-md px-3 text-sm font-medium transition-[background-color,color,opacity,transform] duration-150 ease-out active:scale-[0.96] disabled:pointer-events-none disabled:opacity-60",
|
|
989
|
-
action === "approve" || action === "connect" ? "bg-neutral-900 text-white hover:bg-neutral-800 dark:bg-neutral-100 dark:text-neutral-900 dark:hover:bg-white" : "bg-transparent text-muted-foreground hover:bg-background/80 hover:text-foreground"
|
|
990
|
-
),
|
|
991
|
-
disabled: !onHitlAction || isLoading || state?.status === "connecting" || state?.status === "resuming" || requireComment && !comment.trim(),
|
|
992
|
-
onClick: () => onHitlAction?.(part, action, comment.trim() || void 0),
|
|
993
|
-
type: "button",
|
|
994
|
-
children: hitlActionLabel(part, action)
|
|
995
|
-
},
|
|
996
|
-
action
|
|
997
|
-
)) })
|
|
998
|
-
] });
|
|
999
|
-
}
|
|
1000
|
-
function DefaultPartRow({
|
|
1001
|
-
activeToolId,
|
|
1002
|
-
getHitlActionState,
|
|
1003
|
-
isLoading,
|
|
1004
|
-
message,
|
|
1005
|
-
onHitlAction,
|
|
1006
|
-
part
|
|
1007
|
-
}) {
|
|
1008
|
-
if (part.kind === "text") return /* @__PURE__ */ jsx6(MessageResponse, { children: part.text });
|
|
1009
|
-
if (part.kind === "tool") return /* @__PURE__ */ jsx6(ToolPartRow, { activeToolId, part });
|
|
1010
|
-
if (part.kind === "reasoning") {
|
|
1011
|
-
const label = part.text || part.label || "Thinking";
|
|
1012
|
-
return part.status === "running" || part.status === "streaming" ? /* @__PURE__ */ jsx6(Shimmer, { className: "text-sm text-muted-foreground", children: label }) : /* @__PURE__ */ jsx6("div", { className: "text-sm text-muted-foreground", children: label });
|
|
1013
|
-
}
|
|
1014
|
-
if (part.kind === "ui-blocks") {
|
|
1015
|
-
if (part.state === "output-error") {
|
|
1016
|
-
return /* @__PURE__ */ jsx6("div", { className: "text-sm text-destructive", children: part.errorText || "Failed to render UI content." });
|
|
1017
|
-
}
|
|
1018
|
-
return /* @__PURE__ */ jsx6(CompactTask, { label: part.state === "input-streaming" ? "Rendering UI block" : "Rendered UI block", loading: part.state === "input-streaming" });
|
|
1019
|
-
}
|
|
1020
|
-
if (part.kind === "hitl") {
|
|
1021
|
-
return /* @__PURE__ */ jsx6(
|
|
1022
|
-
HitlPartRow,
|
|
1023
|
-
{
|
|
1024
|
-
getHitlActionState,
|
|
1025
|
-
isLoading,
|
|
1026
|
-
onHitlAction,
|
|
1027
|
-
part
|
|
1028
|
-
}
|
|
1029
|
-
);
|
|
1030
|
-
}
|
|
1031
|
-
if (part.kind === "error") return /* @__PURE__ */ jsx6("div", { className: "text-sm text-destructive", children: part.errorText });
|
|
1032
|
-
if (part.kind === "data") return /* @__PURE__ */ jsx6("div", { "data-agents24-data-part": part.name, className: "hidden", children: message.id });
|
|
1033
|
-
return null;
|
|
1034
|
-
}
|
|
1035
|
-
function AgentResponseTimeline({
|
|
1036
|
-
getHitlActionState,
|
|
1037
|
-
isLoading = false,
|
|
1038
|
-
message,
|
|
1039
|
-
onHitlAction,
|
|
1040
|
-
renderPart
|
|
1041
|
-
}) {
|
|
1042
|
-
const parts = message.parts || [];
|
|
1043
|
-
const activeToolId = [...parts].reverse().find((part) => part.kind === "tool" && (part.state === "input-available" || part.state === "input-streaming"))?.id;
|
|
1044
|
-
const rendered = [];
|
|
1045
|
-
let index = 0;
|
|
1046
|
-
while (index < parts.length) {
|
|
1047
|
-
const part = parts[index];
|
|
1048
|
-
if (part.kind === "tool" && groupKey(part)) {
|
|
1049
|
-
const key = groupKey(part);
|
|
1050
|
-
const group = [];
|
|
1051
|
-
while (index < parts.length) {
|
|
1052
|
-
const candidate = parts[index];
|
|
1053
|
-
if (candidate.kind !== "tool" || groupKey(candidate) !== key) break;
|
|
1054
|
-
group.push(candidate);
|
|
1055
|
-
index += 1;
|
|
1056
|
-
}
|
|
1057
|
-
rendered.push(group.length === 1 ? /* @__PURE__ */ jsx6(ToolPartRow, { activeToolId, part: group[0] }, group[0].id) : /* @__PURE__ */ jsx6(ToolGroup, { activeToolId, parts: group }, `tool-group-${key}-${group[0].id}`));
|
|
1058
|
-
continue;
|
|
1059
|
-
}
|
|
1060
|
-
rendered.push(
|
|
1061
|
-
/* @__PURE__ */ jsx6(React4.Fragment, { children: renderPart ? renderPart(part, message) : /* @__PURE__ */ jsx6(
|
|
1062
|
-
DefaultPartRow,
|
|
1063
|
-
{
|
|
1064
|
-
activeToolId,
|
|
1065
|
-
getHitlActionState,
|
|
1066
|
-
isLoading,
|
|
1067
|
-
message,
|
|
1068
|
-
onHitlAction,
|
|
1069
|
-
part
|
|
1070
|
-
}
|
|
1071
|
-
) }, part.id)
|
|
1072
|
-
);
|
|
1073
|
-
index += 1;
|
|
1074
|
-
}
|
|
1075
|
-
if (rendered.length === 0 && message.content) {
|
|
1076
|
-
rendered.push(/* @__PURE__ */ jsx6(MessageResponse, { children: message.content }, `${message.id}-fallback`));
|
|
1077
|
-
}
|
|
1078
|
-
if (rendered.length === 0 && isLoading) {
|
|
1079
|
-
rendered.push(/* @__PURE__ */ jsx6("div", { className: "text-sm text-muted-foreground", children: "Thinking" }, `${message.id}-thinking`));
|
|
1080
|
-
}
|
|
1081
|
-
return /* @__PURE__ */ jsx6("div", { className: "space-y-3", children: rendered });
|
|
1082
|
-
}
|
|
1083
|
-
|
|
1084
|
-
// src/ui/agent-chat-message.tsx
|
|
1085
|
-
import { jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1086
|
-
var DEFAULT_USER_MESSAGE_COLLAPSE_THRESHOLD = 360;
|
|
1087
|
-
var DEFAULT_USER_MESSAGE_COLLAPSED_LINES = 4;
|
|
1088
|
-
function shouldCollapseUserMessage(content, threshold = DEFAULT_USER_MESSAGE_COLLAPSE_THRESHOLD) {
|
|
1089
|
-
return typeof threshold === "number" && threshold > 0 && content.length > threshold;
|
|
1090
|
-
}
|
|
1091
|
-
function AgentChatUserMessageContent({
|
|
1092
|
-
collapsedLines = DEFAULT_USER_MESSAGE_COLLAPSED_LINES,
|
|
1093
|
-
collapseThreshold = DEFAULT_USER_MESSAGE_COLLAPSE_THRESHOLD,
|
|
1094
|
-
content,
|
|
1095
|
-
showLessLabel = "Show less",
|
|
1096
|
-
showMoreLabel = "Show more"
|
|
1097
|
-
}) {
|
|
1098
|
-
const [isExpanded, setIsExpanded] = React5.useState(false);
|
|
1099
|
-
const contentId = React5.useId();
|
|
1100
|
-
const shouldCollapse = shouldCollapseUserMessage(content, collapseThreshold);
|
|
1101
|
-
const Icon = isExpanded ? ChevronUp : ChevronDown2;
|
|
1102
|
-
const clampedStyle = shouldCollapse && !isExpanded ? {
|
|
1103
|
-
WebkitBoxOrient: "vertical",
|
|
1104
|
-
WebkitLineClamp: Math.max(1, collapsedLines),
|
|
1105
|
-
display: "-webkit-box",
|
|
1106
|
-
overflow: "hidden"
|
|
1107
|
-
} : void 0;
|
|
1108
|
-
return /* @__PURE__ */ jsxs4("div", { className: "flex min-w-0 flex-col gap-3", children: [
|
|
1109
|
-
/* @__PURE__ */ jsx7("div", { id: contentId, className: "min-w-0", style: clampedStyle, children: content }),
|
|
1110
|
-
shouldCollapse ? /* @__PURE__ */ jsxs4(
|
|
1111
|
-
"button",
|
|
1112
|
-
{
|
|
1113
|
-
"aria-controls": contentId,
|
|
1114
|
-
"aria-expanded": isExpanded,
|
|
1115
|
-
className: cn(
|
|
1116
|
-
"inline-flex w-fit items-center gap-1 rounded-md text-left text-sm font-medium text-muted-foreground transition-colors",
|
|
1117
|
-
"hover:text-foreground focus-visible:border-neutral-300 focus-visible:outline-none focus-visible:ring-0"
|
|
1118
|
-
),
|
|
1119
|
-
onClick: () => setIsExpanded((current) => !current),
|
|
1120
|
-
type: "button",
|
|
1121
|
-
children: [
|
|
1122
|
-
isExpanded ? showLessLabel : showMoreLabel,
|
|
1123
|
-
/* @__PURE__ */ jsx7(Icon, { "aria-hidden": "true", className: "size-4", strokeWidth: 2 })
|
|
1124
|
-
]
|
|
1125
|
-
}
|
|
1126
|
-
) : null
|
|
1127
|
-
] });
|
|
1128
|
-
}
|
|
1129
|
-
function AgentChatMessage({
|
|
1130
|
-
actionHandlers,
|
|
1131
|
-
actions,
|
|
1132
|
-
actionsClassName,
|
|
1133
|
-
className,
|
|
1134
|
-
contentClassName,
|
|
1135
|
-
dir,
|
|
1136
|
-
getHitlActionState,
|
|
1137
|
-
message,
|
|
1138
|
-
onHitlAction,
|
|
1139
|
-
renderAssistantContent,
|
|
1140
|
-
renderPart,
|
|
1141
|
-
renderUserContent,
|
|
1142
|
-
showAssistantAttachments = false,
|
|
1143
|
-
streamingMessageId,
|
|
1144
|
-
userMessageCollapsedLines,
|
|
1145
|
-
userMessageContent,
|
|
1146
|
-
userMessageCollapseThreshold,
|
|
1147
|
-
userMessageShowLessLabel,
|
|
1148
|
-
userMessageShowMoreLabel
|
|
1149
|
-
}) {
|
|
1150
|
-
const isAssistant = message.role === "assistant";
|
|
1151
|
-
const isStreaming = isAssistant && message.id === streamingMessageId;
|
|
1152
|
-
const resolvedUserContent = userMessageContent ?? message.content;
|
|
1153
|
-
const shouldRenderContent = isAssistant || Boolean(renderUserContent || resolvedUserContent);
|
|
1154
|
-
const showAttachments = Boolean(message.attachments?.length) && (message.role === "user" || showAssistantAttachments);
|
|
1155
|
-
const renderedActions = actions ?? (actionHandlers ? /* @__PURE__ */ jsx7(AgentChatDefaultActions, { handlers: actionHandlers, message }) : null);
|
|
1156
|
-
return /* @__PURE__ */ jsxs4(ChatMessage, { className, dir, from: message.role, children: [
|
|
1157
|
-
showAttachments ? /* @__PURE__ */ jsx7(ChatAttachments, { className: "mb-2", dir, children: message.attachments?.map((attachment, index) => /* @__PURE__ */ jsx7(
|
|
1158
|
-
ChatAttachment,
|
|
1159
|
-
{
|
|
1160
|
-
data: attachment,
|
|
1161
|
-
dir: "ltr"
|
|
1162
|
-
},
|
|
1163
|
-
String(attachment.url || attachment.filename || index)
|
|
1164
|
-
)) }) : null,
|
|
1165
|
-
shouldRenderContent ? /* @__PURE__ */ jsxs4(
|
|
1166
|
-
ChatMessageContent,
|
|
1167
|
-
{
|
|
1168
|
-
className: cn(isAssistant ? "bg-transparent p-0" : void 0, contentClassName),
|
|
1169
|
-
dir,
|
|
1170
|
-
children: [
|
|
1171
|
-
isAssistant ? renderAssistantContent ? renderAssistantContent({ isStreaming, message }) : /* @__PURE__ */ jsx7(
|
|
1172
|
-
AgentResponseTimeline,
|
|
1173
|
-
{
|
|
1174
|
-
getHitlActionState,
|
|
1175
|
-
isLoading: isStreaming,
|
|
1176
|
-
message,
|
|
1177
|
-
onHitlAction,
|
|
1178
|
-
renderPart
|
|
1179
|
-
}
|
|
1180
|
-
) : null,
|
|
1181
|
-
!isAssistant ? renderUserContent ? renderUserContent({ message }) : resolvedUserContent ? /* @__PURE__ */ jsx7(
|
|
1182
|
-
AgentChatUserMessageContent,
|
|
1183
|
-
{
|
|
1184
|
-
collapsedLines: userMessageCollapsedLines,
|
|
1185
|
-
collapseThreshold: userMessageCollapseThreshold,
|
|
1186
|
-
content: resolvedUserContent,
|
|
1187
|
-
showLessLabel: userMessageShowLessLabel,
|
|
1188
|
-
showMoreLabel: userMessageShowMoreLabel
|
|
1189
|
-
}
|
|
1190
|
-
) : null : null
|
|
1191
|
-
]
|
|
1192
|
-
}
|
|
1193
|
-
) : null,
|
|
1194
|
-
renderedActions ? /* @__PURE__ */ jsx7("div", { className: cn(dir === "rtl" ? "mt-1 h-9 w-full translate-x-2" : "mt-1 h-9 w-full -translate-x-2", actionsClassName), children: renderedActions }) : null
|
|
1195
|
-
] });
|
|
1196
|
-
}
|
|
1197
|
-
|
|
1198
|
-
// src/ui/bubble.tsx
|
|
1199
|
-
import { cva as cva2 } from "class-variance-authority";
|
|
1200
|
-
import { Slot as Slot2 } from "@radix-ui/react-slot";
|
|
1201
|
-
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
43
|
+
import { jsx } from "react/jsx-runtime";
|
|
1202
44
|
function BubbleGroup({ className, ...props }) {
|
|
1203
|
-
return /* @__PURE__ */
|
|
45
|
+
return /* @__PURE__ */ jsx(
|
|
1204
46
|
"div",
|
|
1205
47
|
{
|
|
1206
48
|
"data-slot": "bubble-group",
|
|
@@ -1209,7 +51,7 @@ function BubbleGroup({ className, ...props }) {
|
|
|
1209
51
|
}
|
|
1210
52
|
);
|
|
1211
53
|
}
|
|
1212
|
-
var bubbleVariants =
|
|
54
|
+
var bubbleVariants = cva(
|
|
1213
55
|
"group/bubble relative flex w-fit max-w-[80%] min-w-0 flex-col gap-1 group-data-[align=end]/message:self-end data-[align=end]:self-end data-[variant=ghost]:max-w-full",
|
|
1214
56
|
{
|
|
1215
57
|
variants: {
|
|
@@ -1234,7 +76,7 @@ function Bubble({
|
|
|
1234
76
|
className,
|
|
1235
77
|
...props
|
|
1236
78
|
}) {
|
|
1237
|
-
return /* @__PURE__ */
|
|
79
|
+
return /* @__PURE__ */ jsx(
|
|
1238
80
|
"div",
|
|
1239
81
|
{
|
|
1240
82
|
"data-slot": "bubble",
|
|
@@ -1250,8 +92,8 @@ function BubbleContent({
|
|
|
1250
92
|
className,
|
|
1251
93
|
...props
|
|
1252
94
|
}) {
|
|
1253
|
-
const Comp = asChild ?
|
|
1254
|
-
return /* @__PURE__ */
|
|
95
|
+
const Comp = asChild ? Slot : "div";
|
|
96
|
+
return /* @__PURE__ */ jsx(
|
|
1255
97
|
Comp,
|
|
1256
98
|
{
|
|
1257
99
|
"data-slot": "bubble-content",
|
|
@@ -1263,7 +105,7 @@ function BubbleContent({
|
|
|
1263
105
|
}
|
|
1264
106
|
);
|
|
1265
107
|
}
|
|
1266
|
-
var bubbleReactionsVariants =
|
|
108
|
+
var bubbleReactionsVariants = cva(
|
|
1267
109
|
"absolute z-10 flex w-fit shrink-0 items-center justify-center gap-1 rounded-full bg-muted px-1.5 py-0.5 text-sm ring-3 ring-card has-[button]:p-0",
|
|
1268
110
|
{
|
|
1269
111
|
variants: {
|
|
@@ -1288,7 +130,7 @@ function BubbleReactions({
|
|
|
1288
130
|
className,
|
|
1289
131
|
...props
|
|
1290
132
|
}) {
|
|
1291
|
-
return /* @__PURE__ */
|
|
133
|
+
return /* @__PURE__ */ jsx(
|
|
1292
134
|
"div",
|
|
1293
135
|
{
|
|
1294
136
|
"data-slot": "bubble-reactions",
|
|
@@ -1301,10 +143,10 @@ function BubbleReactions({
|
|
|
1301
143
|
}
|
|
1302
144
|
|
|
1303
145
|
// src/ui/marker.tsx
|
|
1304
|
-
import { cva as
|
|
1305
|
-
import { Slot as
|
|
1306
|
-
import { jsx as
|
|
1307
|
-
var markerVariants =
|
|
146
|
+
import { cva as cva2 } from "class-variance-authority";
|
|
147
|
+
import { Slot as Slot2 } from "@radix-ui/react-slot";
|
|
148
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
149
|
+
var markerVariants = cva2(
|
|
1308
150
|
"group/marker relative flex min-h-4 w-full items-center gap-2 text-left text-sm text-muted-foreground [&_svg:not([class*='size-'])]:size-4 [a]:underline [a]:underline-offset-3 [a]:hover:text-foreground",
|
|
1309
151
|
{
|
|
1310
152
|
variants: {
|
|
@@ -1322,8 +164,8 @@ function Marker({
|
|
|
1322
164
|
asChild = false,
|
|
1323
165
|
...props
|
|
1324
166
|
}) {
|
|
1325
|
-
const Comp = asChild ?
|
|
1326
|
-
return /* @__PURE__ */
|
|
167
|
+
const Comp = asChild ? Slot2 : "div";
|
|
168
|
+
return /* @__PURE__ */ jsx2(
|
|
1327
169
|
Comp,
|
|
1328
170
|
{
|
|
1329
171
|
"data-slot": "marker",
|
|
@@ -1334,7 +176,7 @@ function Marker({
|
|
|
1334
176
|
);
|
|
1335
177
|
}
|
|
1336
178
|
function MarkerIcon({ className, ...props }) {
|
|
1337
|
-
return /* @__PURE__ */
|
|
179
|
+
return /* @__PURE__ */ jsx2(
|
|
1338
180
|
"span",
|
|
1339
181
|
{
|
|
1340
182
|
"data-slot": "marker-icon",
|
|
@@ -1348,7 +190,7 @@ function MarkerIcon({ className, ...props }) {
|
|
|
1348
190
|
);
|
|
1349
191
|
}
|
|
1350
192
|
function MarkerContent({ className, ...props }) {
|
|
1351
|
-
return /* @__PURE__ */
|
|
193
|
+
return /* @__PURE__ */ jsx2(
|
|
1352
194
|
"span",
|
|
1353
195
|
{
|
|
1354
196
|
"data-slot": "marker-content",
|
|
@@ -1362,7 +204,7 @@ function MarkerContent({ className, ...props }) {
|
|
|
1362
204
|
}
|
|
1363
205
|
|
|
1364
206
|
// src/ui/mcp-connect-required-card.tsx
|
|
1365
|
-
import { jsx as
|
|
207
|
+
import { jsx as jsx3, jsxs } from "react/jsx-runtime";
|
|
1366
208
|
var STATUS_LABELS = {
|
|
1367
209
|
pending: "Connect",
|
|
1368
210
|
connecting: "Connecting",
|
|
@@ -1386,7 +228,7 @@ function McpConnectRequiredCard({
|
|
|
1386
228
|
const isBusy = loading || status === "connecting" || status === "resuming";
|
|
1387
229
|
const isConnected = status === "connected";
|
|
1388
230
|
const buttonDisabled = disabled || isBusy || isConnected || !onConnect;
|
|
1389
|
-
return /* @__PURE__ */
|
|
231
|
+
return /* @__PURE__ */ jsx3(
|
|
1390
232
|
"div",
|
|
1391
233
|
{
|
|
1392
234
|
"data-agents24-mcp-connect-card": true,
|
|
@@ -1396,13 +238,13 @@ function McpConnectRequiredCard({
|
|
|
1396
238
|
className
|
|
1397
239
|
),
|
|
1398
240
|
...props,
|
|
1399
|
-
children: /* @__PURE__ */
|
|
1400
|
-
/* @__PURE__ */
|
|
1401
|
-
/* @__PURE__ */
|
|
1402
|
-
/* @__PURE__ */
|
|
1403
|
-
status === "error" && error ? /* @__PURE__ */
|
|
241
|
+
children: /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-start justify-between gap-3", children: [
|
|
242
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
243
|
+
/* @__PURE__ */ jsx3("div", { className: "truncate text-sm font-medium", children: label }),
|
|
244
|
+
/* @__PURE__ */ jsx3("div", { className: "mt-1 text-sm text-muted-foreground", children: message || "Connect your account to continue." }),
|
|
245
|
+
status === "error" && error ? /* @__PURE__ */ jsx3("div", { className: "mt-2 text-sm text-destructive", children: error }) : null
|
|
1404
246
|
] }),
|
|
1405
|
-
/* @__PURE__ */
|
|
247
|
+
/* @__PURE__ */ jsx3(
|
|
1406
248
|
"button",
|
|
1407
249
|
{
|
|
1408
250
|
type: "button",
|