@agents24/chat-react 0.5.5 → 0.5.6
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/dist/runtime/index.cjs +17 -11
- package/dist/runtime/index.cjs.map +1 -1
- package/dist/runtime/index.js +17 -11
- package/dist/runtime/index.js.map +1 -1
- package/dist/runtime/use-agent-chat-runtime.d.ts +7 -2
- package/dist/scaffold/components/chat/chat-composer.d.ts +2 -1
- package/dist/scaffold/components/chat/chat-message.d.ts +3 -1
- package/dist/scaffold/index.cjs +57 -27
- package/dist/scaffold/index.cjs.map +1 -1
- package/dist/scaffold/index.js +68 -32
- package/dist/scaffold/index.js.map +1 -1
- package/dist/styles.css +14 -2
- package/dist/ui/adapters.d.ts +14 -2
- package/dist/ui/agent-chat-composer.d.ts +2 -9
- package/dist/ui/agent-chat-message.d.ts +3 -1
- package/dist/ui/composer-attachments.d.ts +11 -0
- package/dist/ui/index.cjs +647 -341
- package/dist/ui/index.cjs.map +1 -1
- package/dist/ui/index.d.ts +1 -0
- package/dist/ui/index.js +632 -326
- package/dist/ui/index.js.map +1 -1
- package/package.json +4 -3
- package/scaffold/src/components/chat/chat-composer.tsx +43 -19
- package/scaffold/src/components/chat/chat-message.tsx +8 -9
- package/scaffold/src/components/chat/chat-shell.tsx +12 -9
package/dist/scaffold/index.js
CHANGED
|
@@ -10,12 +10,18 @@ import {
|
|
|
10
10
|
import {
|
|
11
11
|
agentChatRuntimeErrorMessage
|
|
12
12
|
} from "@agents24/chat-react/runtime";
|
|
13
|
-
import { CircleAlert, LoaderCircle as LoaderCircle3, SquarePen as SquarePen2, X
|
|
13
|
+
import { CircleAlert, LoaderCircle as LoaderCircle3, SquarePen as SquarePen2, X } from "lucide-react";
|
|
14
14
|
|
|
15
15
|
// scaffold/src/components/chat/chat-composer.tsx
|
|
16
|
-
import { ArrowUp, ChevronDown, LoaderCircle, Mic, Square
|
|
16
|
+
import { ArrowUp, ChevronDown, LoaderCircle, Mic, Square } from "lucide-react";
|
|
17
17
|
import * as React2 from "react";
|
|
18
|
-
import {
|
|
18
|
+
import {
|
|
19
|
+
AgentChatContextStatus,
|
|
20
|
+
ChatAttachmentRows,
|
|
21
|
+
createAgentChatComposerFile,
|
|
22
|
+
revokeAgentChatComposerFiles,
|
|
23
|
+
useAudioRecorder
|
|
24
|
+
} from "@agents24/chat-react/ui";
|
|
19
25
|
import { canonicalInputMimeType, inputMimeTypes, validateAgentChatSubmission } from "@agents24/chat-react/runtime";
|
|
20
26
|
|
|
21
27
|
// scaffold/src/components/ui/button.tsx
|
|
@@ -491,11 +497,20 @@ function ChatComposer({
|
|
|
491
497
|
const [attachmentError, setAttachmentError] = React2.useState(null);
|
|
492
498
|
const inputRef = React2.useRef(null);
|
|
493
499
|
const textareaRef = React2.useRef(null);
|
|
500
|
+
const filesRef = React2.useRef([]);
|
|
501
|
+
const inFlightFilesRef = React2.useRef([]);
|
|
494
502
|
const submittingRef = React2.useRef(false);
|
|
495
503
|
const draftRevisionRef = React2.useRef(0);
|
|
496
504
|
const attachmentMimeTypes = inputMimeTypes(inputContract);
|
|
497
505
|
const allowAttachments = attachmentMimeTypes.length > 0;
|
|
498
506
|
const recordingAllowed = inputContract.modalities.audio.recording_enabled;
|
|
507
|
+
React2.useEffect(() => {
|
|
508
|
+
filesRef.current = files;
|
|
509
|
+
}, [files]);
|
|
510
|
+
React2.useEffect(() => () => {
|
|
511
|
+
revokeAgentChatComposerFiles(filesRef.current);
|
|
512
|
+
revokeAgentChatComposerFiles(inFlightFilesRef.current);
|
|
513
|
+
}, []);
|
|
499
514
|
React2.useEffect(() => {
|
|
500
515
|
if (disabled || isRunning) return;
|
|
501
516
|
const frame = window.requestAnimationFrame(() => textareaRef.current?.focus({ preventScroll: true }));
|
|
@@ -503,14 +518,14 @@ function ChatComposer({
|
|
|
503
518
|
}, [disabled, focusKey, isRunning]);
|
|
504
519
|
const addRecording = React2.useCallback((file) => {
|
|
505
520
|
draftRevisionRef.current += 1;
|
|
506
|
-
setFiles((current) => [...current, file]);
|
|
521
|
+
setFiles((current) => [...current, createAgentChatComposerFile(file)]);
|
|
507
522
|
}, []);
|
|
508
523
|
const recorder = useAudioRecorder(addRecording);
|
|
509
524
|
const isExpanded = forceExpanded || text.includes("\n") || text.length > 62;
|
|
510
525
|
const validationError = validateAgentChatSubmission(
|
|
511
526
|
inputContract,
|
|
512
527
|
text,
|
|
513
|
-
files.map((file) => ({ data: file, mediaType: file.
|
|
528
|
+
files.map((file) => ({ data: file.source, mediaType: file.mediaType }))
|
|
514
529
|
);
|
|
515
530
|
const selectedAgent = agents.find((item) => item.id === agentId);
|
|
516
531
|
const selectedModel = models.find((item) => item.id === modelId);
|
|
@@ -558,16 +573,23 @@ function ChatComposer({
|
|
|
558
573
|
const clearedRevision = draftRevisionRef.current + 1;
|
|
559
574
|
draftRevisionRef.current = clearedRevision;
|
|
560
575
|
submittingRef.current = true;
|
|
576
|
+
inFlightFilesRef.current = selectedFiles;
|
|
561
577
|
setText("");
|
|
562
578
|
setFiles([]);
|
|
563
579
|
textareaRef.current?.focus();
|
|
564
580
|
try {
|
|
565
581
|
await onSubmit(value, selectedFiles);
|
|
582
|
+
revokeAgentChatComposerFiles(selectedFiles);
|
|
583
|
+
inFlightFilesRef.current = [];
|
|
566
584
|
} catch {
|
|
567
585
|
if (draftRevisionRef.current === clearedRevision) {
|
|
568
586
|
draftRevisionRef.current += 1;
|
|
569
587
|
setText(value);
|
|
570
588
|
setFiles(selectedFiles);
|
|
589
|
+
inFlightFilesRef.current = [];
|
|
590
|
+
} else {
|
|
591
|
+
revokeAgentChatComposerFiles(selectedFiles);
|
|
592
|
+
inFlightFilesRef.current = [];
|
|
571
593
|
}
|
|
572
594
|
} finally {
|
|
573
595
|
submittingRef.current = false;
|
|
@@ -579,13 +601,21 @@ function ChatComposer({
|
|
|
579
601
|
className: "mx-auto w-full max-w-3xl px-4 pb-[max(1rem,env(safe-area-inset-bottom))] sm:px-6",
|
|
580
602
|
"data-agents24-chat-composer": "",
|
|
581
603
|
children: [
|
|
582
|
-
allowAttachments && files.length > 0 && /* @__PURE__ */ jsx7("div", { className: "mb-2
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
604
|
+
allowAttachments && files.length > 0 && /* @__PURE__ */ jsx7("div", { className: "mb-2 min-w-0", children: /* @__PURE__ */ jsx7(
|
|
605
|
+
ChatAttachmentRows,
|
|
606
|
+
{
|
|
607
|
+
attachments: files,
|
|
608
|
+
onRemove: (attachment) => {
|
|
609
|
+
if (!attachment.id) return;
|
|
610
|
+
draftRevisionRef.current += 1;
|
|
611
|
+
setFiles((current) => {
|
|
612
|
+
const removed = current.find((file) => file.id === attachment.id);
|
|
613
|
+
if (removed) revokeAgentChatComposerFiles([removed]);
|
|
614
|
+
return current.filter((file) => file.id !== attachment.id);
|
|
615
|
+
});
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
) }),
|
|
589
619
|
attachmentError || recorder.error ? /* @__PURE__ */ jsx7("p", { className: "mb-2 text-xs text-destructive", role: "alert", children: attachmentError || recorder.error }) : null,
|
|
590
620
|
/* @__PURE__ */ jsxs3(
|
|
591
621
|
"div",
|
|
@@ -609,7 +639,7 @@ function ChatComposer({
|
|
|
609
639
|
const selected = Array.from(event.target.files ?? []);
|
|
610
640
|
const accepted = selected.filter((file) => attachmentMimeTypes.includes(canonicalInputMimeType(file.type)));
|
|
611
641
|
draftRevisionRef.current += 1;
|
|
612
|
-
setFiles((current) => [...current, ...accepted]);
|
|
642
|
+
setFiles((current) => [...current, ...accepted.map(createAgentChatComposerFile)]);
|
|
613
643
|
setAttachmentError(
|
|
614
644
|
accepted.length === selected.length ? null : "One or more selected file types are not supported by this Agent."
|
|
615
645
|
);
|
|
@@ -696,7 +726,7 @@ function ChatComposer({
|
|
|
696
726
|
}
|
|
697
727
|
|
|
698
728
|
// scaffold/src/components/chat/chat-message.tsx
|
|
699
|
-
import { AgentChatDefaultActions,
|
|
729
|
+
import { AgentChatDefaultActions, ChatAttachmentRows as ChatAttachmentRows2 } from "@agents24/chat-react/ui";
|
|
700
730
|
|
|
701
731
|
// scaffold/src/components/chat/message-parts.tsx
|
|
702
732
|
import {
|
|
@@ -1104,17 +1134,19 @@ function ChatMessage({
|
|
|
1104
1134
|
onHitlAction,
|
|
1105
1135
|
onRegenerate,
|
|
1106
1136
|
onSetFeedback,
|
|
1137
|
+
resolveAttachmentContent,
|
|
1107
1138
|
Timeline
|
|
1108
1139
|
}) {
|
|
1109
1140
|
const isUser = message.role === "user";
|
|
1110
1141
|
return /* @__PURE__ */ jsx14(Message, { align: isUser ? "end" : "start", children: /* @__PURE__ */ jsxs8(MessageContent, { children: [
|
|
1111
|
-
isUser && message.attachments?.length ? /* @__PURE__ */ jsx14(
|
|
1112
|
-
|
|
1142
|
+
isUser && message.attachments?.length ? /* @__PURE__ */ jsx14(
|
|
1143
|
+
ChatAttachmentRows2,
|
|
1113
1144
|
{
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1145
|
+
attachments: message.attachments,
|
|
1146
|
+
className: "mb-2",
|
|
1147
|
+
resolveContent: resolveAttachmentContent
|
|
1148
|
+
}
|
|
1149
|
+
) : null,
|
|
1118
1150
|
/* @__PURE__ */ jsx14(Bubble, { variant: isUser ? "secondary" : "ghost", align: isUser ? "end" : "start", className: isUser ? "max-w-[min(75%,42rem)]" : "max-w-full overflow-visible", children: /* @__PURE__ */ jsx14(BubbleContent, { className: isUser ? "px-4 py-2.5" : "w-full overflow-visible", children: /* @__PURE__ */ jsx14(
|
|
1119
1151
|
MessageParts,
|
|
1120
1152
|
{
|
|
@@ -2142,7 +2174,7 @@ function OperationErrorNotice({ runtime }) {
|
|
|
2142
2174
|
onClick: runtime.operationError ? runtime.clearOperationError : runtime.controller.clearBackgroundError,
|
|
2143
2175
|
size: "icon-xs",
|
|
2144
2176
|
variant: "ghost",
|
|
2145
|
-
children: /* @__PURE__ */ jsx25(
|
|
2177
|
+
children: /* @__PURE__ */ jsx25(X, {})
|
|
2146
2178
|
}
|
|
2147
2179
|
)
|
|
2148
2180
|
] }) });
|
|
@@ -2154,7 +2186,8 @@ function ChatShell({
|
|
|
2154
2186
|
sidebar
|
|
2155
2187
|
}) {
|
|
2156
2188
|
const { controller } = runtime;
|
|
2157
|
-
const isRunning = controller.runState === "streaming" || controller.runState === "reconnecting" || controller.runState === "paused" || controller.runState === "cancelling"
|
|
2189
|
+
const isRunning = controller.runState === "streaming" || controller.runState === "reconnecting" || controller.runState === "paused" || controller.runState === "cancelling";
|
|
2190
|
+
const isUploading = controller.runState === "uploading" || runtime.isUploading;
|
|
2158
2191
|
const isCancelling = controller.runState === "cancelling";
|
|
2159
2192
|
const activeTitle = controller.threads.find((thread) => thread.id === controller.activeThreadId)?.title;
|
|
2160
2193
|
const hasBlockingError = Boolean(runtime.fatalError && controller.messages.length === 0);
|
|
@@ -2210,7 +2243,7 @@ function ChatShell({
|
|
|
2210
2243
|
{
|
|
2211
2244
|
inputContract: runtime.inputContract || LOADING_INPUT_CONTRACT,
|
|
2212
2245
|
contextWindow: runtime.contextWindow,
|
|
2213
|
-
disabled: runtime.isBootstrapping || runtime.isChangingAgent,
|
|
2246
|
+
disabled: runtime.isBootstrapping || runtime.isChangingAgent || isUploading,
|
|
2214
2247
|
focusKey: controller.activeThreadId,
|
|
2215
2248
|
forceExpanded: true,
|
|
2216
2249
|
isCancelling,
|
|
@@ -2229,10 +2262,11 @@ function ChatShell({
|
|
|
2229
2262
|
onSubmit: (text, files) => runtime.submit({
|
|
2230
2263
|
text,
|
|
2231
2264
|
files: files.map((file) => ({
|
|
2232
|
-
data: file,
|
|
2233
|
-
mediaType: file.
|
|
2234
|
-
name: file.
|
|
2235
|
-
}))
|
|
2265
|
+
data: file.source,
|
|
2266
|
+
mediaType: file.mediaType,
|
|
2267
|
+
name: file.filename
|
|
2268
|
+
})),
|
|
2269
|
+
attachments: files
|
|
2236
2270
|
})
|
|
2237
2271
|
}
|
|
2238
2272
|
)
|
|
@@ -2285,6 +2319,7 @@ function ChatShell({
|
|
|
2285
2319
|
onHitlAction: runtime.onHitlAction,
|
|
2286
2320
|
onRegenerate: () => controller.regenerate(message),
|
|
2287
2321
|
onSetFeedback: (input) => controller.setFeedback(message, input),
|
|
2322
|
+
resolveAttachmentContent: runtime.resolveAttachmentContent,
|
|
2288
2323
|
Timeline: components?.Timeline
|
|
2289
2324
|
}
|
|
2290
2325
|
)
|
|
@@ -2304,7 +2339,7 @@ function ChatShell({
|
|
|
2304
2339
|
{
|
|
2305
2340
|
inputContract: runtime.inputContract || LOADING_INPUT_CONTRACT,
|
|
2306
2341
|
contextWindow: runtime.contextWindow,
|
|
2307
|
-
disabled: runtime.isBootstrapping || runtime.isChangingAgent || hasBlockingError,
|
|
2342
|
+
disabled: runtime.isBootstrapping || runtime.isChangingAgent || hasBlockingError || isUploading,
|
|
2308
2343
|
focusKey: controller.activeThreadId,
|
|
2309
2344
|
isCancelling,
|
|
2310
2345
|
isRunning,
|
|
@@ -2322,10 +2357,11 @@ function ChatShell({
|
|
|
2322
2357
|
onSubmit: (text, files) => runtime.submit({
|
|
2323
2358
|
text,
|
|
2324
2359
|
files: files.map((file) => ({
|
|
2325
|
-
data: file,
|
|
2326
|
-
mediaType: file.
|
|
2327
|
-
name: file.
|
|
2328
|
-
}))
|
|
2360
|
+
data: file.source,
|
|
2361
|
+
mediaType: file.mediaType,
|
|
2362
|
+
name: file.filename
|
|
2363
|
+
})),
|
|
2364
|
+
attachments: files
|
|
2329
2365
|
}),
|
|
2330
2366
|
utilityRow: "below"
|
|
2331
2367
|
}
|