@agents24/chat-react 0.5.15 → 0.5.17
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/compatibility.json +8 -8
- package/dist/index.cjs +8 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/latest-thread-scroller.d.ts +5 -0
- package/dist/runtime/index.cjs +16 -2
- package/dist/runtime/index.cjs.map +1 -1
- package/dist/runtime/index.js +16 -2
- package/dist/runtime/index.js.map +1 -1
- package/dist/runtime/use-agent-chat-runtime.d.ts +1 -0
- package/dist/scaffold/components/chat/chat-composer.d.ts +6 -1
- package/dist/scaffold/components/chat/chat-message.d.ts +2 -1
- package/dist/scaffold/index.cjs +185 -286
- package/dist/scaffold/index.cjs.map +1 -1
- package/dist/scaffold/index.js +190 -291
- package/dist/scaffold/index.js.map +1 -1
- package/dist/styles.css +34 -1
- package/dist/types.d.ts +1 -1
- package/dist/ui/agent-chat-actions.d.ts +4 -1
- package/dist/ui/agent-chat-composer.d.ts +9 -1
- package/dist/ui/agent-chat-queue.d.ts +12 -0
- package/dist/ui/composer-attachments.d.ts +5 -1
- package/dist/ui/composer-interactions.d.ts +17 -0
- package/dist/ui/index.cjs +531 -331
- package/dist/ui/index.cjs.map +1 -1
- package/dist/ui/index.d.ts +2 -0
- package/dist/ui/index.js +516 -322
- package/dist/ui/index.js.map +1 -1
- package/dist/ui/tool-sessions.d.ts +4 -1
- package/package.json +4 -4
- package/scaffold/src/components/chat/chat-composer.tsx +25 -26
- package/scaffold/src/components/chat/chat-message.tsx +7 -2
- package/scaffold/src/components/chat/chat-shell.tsx +52 -69
- package/dist/scaffold/components/ui/message-scroller.d.ts +0 -10
- package/scaffold/src/components/ui/message-scroller.tsx +0 -129
package/dist/ui/index.js
CHANGED
|
@@ -4,8 +4,8 @@ import {
|
|
|
4
4
|
} from "../chunk-SSUO4EPD.js";
|
|
5
5
|
|
|
6
6
|
// src/ui/agent-chat-composer.tsx
|
|
7
|
-
import * as
|
|
8
|
-
import { ArrowUp, Plus, Square } from "lucide-react";
|
|
7
|
+
import * as React3 from "react";
|
|
8
|
+
import { ArrowUp, Loader2, Plus, Square } from "lucide-react";
|
|
9
9
|
|
|
10
10
|
// src/ui/adapters.ts
|
|
11
11
|
import * as React from "react";
|
|
@@ -733,11 +733,50 @@ function createAgentChatComposerFile(file) {
|
|
|
733
733
|
function revokeAgentChatComposerFiles(files) {
|
|
734
734
|
files.forEach((file) => {
|
|
735
735
|
try {
|
|
736
|
-
URL.revokeObjectURL(file.url);
|
|
736
|
+
if (file.url.startsWith("blob:")) URL.revokeObjectURL(file.url);
|
|
737
737
|
} catch {
|
|
738
738
|
}
|
|
739
739
|
});
|
|
740
740
|
}
|
|
741
|
+
function queuedMessageComposerFiles(message) {
|
|
742
|
+
const byId = new Map((message.attachments || []).map((attachment) => [attachment.id, attachment]));
|
|
743
|
+
return message.attachment_ids.map((id) => {
|
|
744
|
+
const attachment = byId.get(id);
|
|
745
|
+
return {
|
|
746
|
+
id,
|
|
747
|
+
persistedAttachmentId: id,
|
|
748
|
+
type: "file",
|
|
749
|
+
url: "",
|
|
750
|
+
filename: attachment?.filename || "Attachment",
|
|
751
|
+
mediaType: attachment?.mime_type || "application/octet-stream",
|
|
752
|
+
byteSize: attachment?.byte_size || 0
|
|
753
|
+
};
|
|
754
|
+
});
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
// src/ui/composer-interactions.ts
|
|
758
|
+
import * as React2 from "react";
|
|
759
|
+
function chatComposerAction({ hasDraft, isRunning, isCancelling }) {
|
|
760
|
+
return isRunning && (!hasDraft || isCancelling) ? "stop" : "send";
|
|
761
|
+
}
|
|
762
|
+
function useChatComposerFocus({ textareaRef, disabled, focusKey, restoredDraft, onRestore }) {
|
|
763
|
+
const restoreRef = React2.useRef(onRestore);
|
|
764
|
+
restoreRef.current = onRestore;
|
|
765
|
+
const focus = React2.useCallback(() => {
|
|
766
|
+
window.requestAnimationFrame(() => textareaRef.current?.focus({ preventScroll: true }));
|
|
767
|
+
}, [textareaRef]);
|
|
768
|
+
React2.useEffect(() => {
|
|
769
|
+
if (!restoredDraft) return;
|
|
770
|
+
restoreRef.current(restoredDraft);
|
|
771
|
+
focus();
|
|
772
|
+
}, [restoredDraft?.revision, focus]);
|
|
773
|
+
React2.useEffect(() => {
|
|
774
|
+
const supportsFinePointer = typeof window.matchMedia === "function" && window.matchMedia("(hover: hover) and (pointer: fine)").matches;
|
|
775
|
+
if (disabled || !supportsFinePointer) return;
|
|
776
|
+
focus();
|
|
777
|
+
}, [disabled, focusKey, focus]);
|
|
778
|
+
return focus;
|
|
779
|
+
}
|
|
741
780
|
|
|
742
781
|
// src/ui/agent-chat-composer.tsx
|
|
743
782
|
import { jsx as jsx3, jsxs } from "react/jsx-runtime";
|
|
@@ -754,24 +793,27 @@ function AgentChatComposer({
|
|
|
754
793
|
className,
|
|
755
794
|
disabled = false,
|
|
756
795
|
forceExpanded = false,
|
|
796
|
+
focusKey,
|
|
757
797
|
inputToolbarContent,
|
|
758
798
|
isRunning = false,
|
|
799
|
+
isCancelling = false,
|
|
759
800
|
onAttachmentCountChange,
|
|
760
801
|
onStop,
|
|
761
802
|
onSubmit,
|
|
762
803
|
placeholder = "Message the agent",
|
|
804
|
+
restoredDraft,
|
|
763
805
|
textareaRef
|
|
764
806
|
}) {
|
|
765
|
-
const fileInputRef =
|
|
766
|
-
const filesRef =
|
|
767
|
-
const inFlightFilesRef =
|
|
768
|
-
const localTextareaRef =
|
|
769
|
-
const draftRevisionRef =
|
|
770
|
-
const [text, setText] =
|
|
771
|
-
const [files, setFiles] =
|
|
772
|
-
const [isSubmitting, setIsSubmitting] =
|
|
807
|
+
const fileInputRef = React3.useRef(null);
|
|
808
|
+
const filesRef = React3.useRef([]);
|
|
809
|
+
const inFlightFilesRef = React3.useRef([]);
|
|
810
|
+
const localTextareaRef = React3.useRef(null);
|
|
811
|
+
const draftRevisionRef = React3.useRef(0);
|
|
812
|
+
const [text, setText] = React3.useState("");
|
|
813
|
+
const [files, setFiles] = React3.useState([]);
|
|
814
|
+
const [isSubmitting, setIsSubmitting] = React3.useState(false);
|
|
773
815
|
const isExpanded = forceExpanded || text.includes("\n") || text.length > 62;
|
|
774
|
-
const setTextareaRef =
|
|
816
|
+
const setTextareaRef = React3.useCallback(
|
|
775
817
|
(node) => {
|
|
776
818
|
localTextareaRef.current = node;
|
|
777
819
|
if (typeof textareaRef === "function") {
|
|
@@ -782,15 +824,27 @@ function AgentChatComposer({
|
|
|
782
824
|
},
|
|
783
825
|
[textareaRef]
|
|
784
826
|
);
|
|
785
|
-
|
|
827
|
+
React3.useEffect(() => {
|
|
786
828
|
filesRef.current = files;
|
|
787
829
|
onAttachmentCountChange?.(files.length);
|
|
788
830
|
}, [files, onAttachmentCountChange]);
|
|
789
|
-
|
|
831
|
+
React3.useEffect(() => () => {
|
|
790
832
|
revokeAgentChatComposerFiles(filesRef.current);
|
|
791
833
|
revokeAgentChatComposerFiles(inFlightFilesRef.current);
|
|
792
834
|
}, []);
|
|
793
|
-
|
|
835
|
+
const focusComposer = useChatComposerFocus({
|
|
836
|
+
textareaRef: localTextareaRef,
|
|
837
|
+
disabled,
|
|
838
|
+
focusKey,
|
|
839
|
+
restoredDraft,
|
|
840
|
+
onRestore: (draft) => {
|
|
841
|
+
draftRevisionRef.current += 1;
|
|
842
|
+
revokeAgentChatComposerFiles(filesRef.current);
|
|
843
|
+
setText(draft.text);
|
|
844
|
+
setFiles(draft.files);
|
|
845
|
+
}
|
|
846
|
+
});
|
|
847
|
+
React3.useLayoutEffect(() => {
|
|
794
848
|
const textarea = localTextareaRef.current;
|
|
795
849
|
if (!textarea) return;
|
|
796
850
|
if (isExpanded) {
|
|
@@ -803,7 +857,8 @@ function AgentChatComposer({
|
|
|
803
857
|
textarea.style.height = "";
|
|
804
858
|
textarea.style.overflowY = "hidden";
|
|
805
859
|
}, [isExpanded, text]);
|
|
806
|
-
const canSubmit = !disabled && !isSubmitting &&
|
|
860
|
+
const canSubmit = !disabled && !isSubmitting && (text.trim().length > 0 || files.length > 0);
|
|
861
|
+
const action = chatComposerAction({ hasDraft: text.trim().length > 0 || files.length > 0, isRunning, isCancelling });
|
|
807
862
|
const handleFilesChange = (event) => {
|
|
808
863
|
const selected = Array.from(event.target.files || []).map(createAgentChatComposerFile);
|
|
809
864
|
if (selected.length > 0) {
|
|
@@ -830,8 +885,13 @@ function AgentChatComposer({
|
|
|
830
885
|
setIsSubmitting(true);
|
|
831
886
|
setText("");
|
|
832
887
|
setFiles([]);
|
|
888
|
+
focusComposer();
|
|
833
889
|
try {
|
|
834
|
-
await onSubmit({
|
|
890
|
+
await onSubmit({
|
|
891
|
+
text: submittedText,
|
|
892
|
+
files: submittedFiles,
|
|
893
|
+
attachmentIds: submittedFiles.flatMap((file) => file.persistedAttachmentId ? [file.persistedAttachmentId] : [])
|
|
894
|
+
});
|
|
835
895
|
revokeAgentChatComposerFiles(submittedFiles);
|
|
836
896
|
inFlightFilesRef.current = [];
|
|
837
897
|
} catch {
|
|
@@ -912,7 +972,7 @@ function AgentChatComposer({
|
|
|
912
972
|
{
|
|
913
973
|
"aria-label": "Attach files",
|
|
914
974
|
className: cn("a24-composer__attach", pillButtonClass),
|
|
915
|
-
disabled: disabled || isSubmitting ||
|
|
975
|
+
disabled: disabled || isSubmitting || !allowAttachments,
|
|
916
976
|
onClick: () => fileInputRef.current?.click(),
|
|
917
977
|
title: "Attach files",
|
|
918
978
|
type: "button",
|
|
@@ -930,7 +990,7 @@ function AgentChatComposer({
|
|
|
930
990
|
"a24-composer__textarea w-full resize-none border-0 bg-transparent px-1 text-[15px] leading-relaxed text-foreground shadow-none outline-none placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-0",
|
|
931
991
|
isExpanded ? "min-h-9 max-h-[224px] py-1" : "min-h-9 h-9 max-h-9 py-2"
|
|
932
992
|
),
|
|
933
|
-
disabled
|
|
993
|
+
disabled,
|
|
934
994
|
name: "message",
|
|
935
995
|
onChange: (event) => {
|
|
936
996
|
draftRevisionRef.current += 1;
|
|
@@ -945,27 +1005,19 @@ function AgentChatComposer({
|
|
|
945
1005
|
isExpanded ? /* @__PURE__ */ jsx3("div", { style: { gridArea: "toolbar" }, className: "a24-composer__toolbar flex min-w-0 items-center gap-1.5", children: inputToolbarContent }) : null,
|
|
946
1006
|
!isExpanded ? /* @__PURE__ */ jsx3("div", { style: { gridArea: "composer" }, className: "flex min-w-0 items-center gap-1.5" }) : null,
|
|
947
1007
|
!isExpanded ? /* @__PURE__ */ jsx3("div", { style: { gridArea: "mic" }, className: "flex shrink-0 items-center justify-end" }) : null,
|
|
948
|
-
/* @__PURE__ */ jsx3("div", { style: { gridArea: "submit" }, className: "a24-composer__submit-slot flex shrink-0 items-center justify-end", children:
|
|
949
|
-
"button",
|
|
950
|
-
{
|
|
951
|
-
"aria-label": "Stop generating",
|
|
952
|
-
className: cn("a24-composer__submit", submitButtonClass),
|
|
953
|
-
disabled: disabled || !onStop,
|
|
954
|
-
onClick: onStop,
|
|
955
|
-
title: "Stop",
|
|
956
|
-
type: "button",
|
|
957
|
-
children: /* @__PURE__ */ jsx3(Square, { className: "size-3.5 fill-current" })
|
|
958
|
-
}
|
|
959
|
-
) : /* @__PURE__ */ jsx3(
|
|
1008
|
+
/* @__PURE__ */ jsx3("div", { style: { gridArea: "submit" }, className: "a24-composer__submit-slot flex shrink-0 items-center justify-end gap-1", children: /* @__PURE__ */ jsx3(
|
|
960
1009
|
"button",
|
|
961
1010
|
{
|
|
962
|
-
"aria-label": files.length > 0 ? `Send ${formatFileCount(files)}` : "Send message",
|
|
1011
|
+
"aria-label": isCancelling ? "Cancelling response" : action === "stop" ? "Stop generating" : files.length > 0 ? `Send ${formatFileCount(files)}` : isRunning ? "Queue message" : "Send message",
|
|
963
1012
|
className: cn("a24-composer__submit", submitButtonClass, text.trim().length > 0 && "hover:scale-105"),
|
|
964
|
-
disabled: !canSubmit,
|
|
965
|
-
onClick: () =>
|
|
966
|
-
|
|
1013
|
+
disabled: isCancelling || (action === "stop" ? disabled : !canSubmit),
|
|
1014
|
+
onClick: () => {
|
|
1015
|
+
if (action === "stop") onStop?.();
|
|
1016
|
+
else void submit();
|
|
1017
|
+
},
|
|
1018
|
+
title: action === "stop" ? "Stop" : isRunning ? "Queue message" : "Send",
|
|
967
1019
|
type: "button",
|
|
968
|
-
children: /* @__PURE__ */ jsx3(ArrowUp, { className: "size-4", strokeWidth: 2.5 })
|
|
1020
|
+
children: isCancelling ? /* @__PURE__ */ jsx3(Loader2, { className: "size-3.5 animate-spin" }) : action === "stop" ? /* @__PURE__ */ jsx3(Square, { className: "size-3.5 fill-current" }) : /* @__PURE__ */ jsx3(ArrowUp, { className: "size-4", strokeWidth: 2.5 })
|
|
969
1021
|
}
|
|
970
1022
|
) })
|
|
971
1023
|
]
|
|
@@ -977,11 +1029,81 @@ function AgentChatComposer({
|
|
|
977
1029
|
] });
|
|
978
1030
|
}
|
|
979
1031
|
|
|
1032
|
+
// src/ui/agent-chat-queue.tsx
|
|
1033
|
+
import * as React4 from "react";
|
|
1034
|
+
import { CornerDownLeft, Ellipsis, Trash2 } from "lucide-react";
|
|
1035
|
+
import { Fragment, jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
1036
|
+
function QueueRow({ message, onRemove, onEdit }) {
|
|
1037
|
+
const [busy, setBusy] = React4.useState(false);
|
|
1038
|
+
const [error, setError] = React4.useState(null);
|
|
1039
|
+
const editable = message.status === "queued" || message.status === "blocked";
|
|
1040
|
+
const act = async (operation) => {
|
|
1041
|
+
setBusy(true);
|
|
1042
|
+
setError(null);
|
|
1043
|
+
try {
|
|
1044
|
+
await operation();
|
|
1045
|
+
} catch (cause) {
|
|
1046
|
+
setError(cause instanceof Error ? cause.message : "Message action failed. Try again.");
|
|
1047
|
+
} finally {
|
|
1048
|
+
setBusy(false);
|
|
1049
|
+
}
|
|
1050
|
+
};
|
|
1051
|
+
return /* @__PURE__ */ jsxs2("div", { "data-message-id": message.id, className: "a24-queue__row min-w-0 border-b border-border/40 last:border-b-0", children: [
|
|
1052
|
+
/* @__PURE__ */ jsxs2("div", { className: "a24-queue__row-content flex min-h-9 items-center gap-2 px-3 text-sm", children: [
|
|
1053
|
+
/* @__PURE__ */ jsx4(CornerDownLeft, { "aria-hidden": true, className: "size-4 shrink-0 text-muted-foreground" }),
|
|
1054
|
+
/* @__PURE__ */ jsx4("span", { className: "a24-queue__text min-w-0 flex-1 truncate text-foreground", title: message.text, children: message.text || `${message.attachment_ids.length} attachment${message.attachment_ids.length === 1 ? "" : "s"}` }),
|
|
1055
|
+
message.status === "blocked" ? /* @__PURE__ */ jsx4("span", { className: "shrink-0 text-xs text-amber-700", children: "Needs attention" }) : null,
|
|
1056
|
+
["steer_pending", "delivering"].includes(message.status) ? /* @__PURE__ */ jsx4("span", { className: "shrink-0 text-xs text-muted-foreground", children: "Steering\u2026" }) : null,
|
|
1057
|
+
editable ? /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
1058
|
+
/* @__PURE__ */ jsx4(
|
|
1059
|
+
"button",
|
|
1060
|
+
{
|
|
1061
|
+
type: "button",
|
|
1062
|
+
"aria-label": "Delete queued message",
|
|
1063
|
+
disabled: busy,
|
|
1064
|
+
onClick: () => void act(() => onRemove(message)),
|
|
1065
|
+
className: "a24-queue__icon flex size-8 shrink-0 items-center justify-center text-muted-foreground hover:text-foreground disabled:opacity-50",
|
|
1066
|
+
children: /* @__PURE__ */ jsx4(Trash2, { "aria-hidden": true, className: "size-4" })
|
|
1067
|
+
}
|
|
1068
|
+
),
|
|
1069
|
+
/* @__PURE__ */ jsxs2("details", { className: "a24-queue__menu relative group/queue-menu", children: [
|
|
1070
|
+
/* @__PURE__ */ jsx4("summary", { "aria-label": "Queued message options", className: "a24-queue__icon flex size-8 cursor-pointer list-none items-center justify-center text-muted-foreground hover:text-foreground [&::-webkit-details-marker]:hidden", children: /* @__PURE__ */ jsx4(Ellipsis, { "aria-hidden": true, className: "size-4" }) }),
|
|
1071
|
+
/* @__PURE__ */ jsx4("div", { className: "a24-queue__menu-content absolute bottom-full right-0 z-30 mb-1 min-w-28 rounded-md border bg-background p-1 shadow-md", children: /* @__PURE__ */ jsx4(
|
|
1072
|
+
"button",
|
|
1073
|
+
{
|
|
1074
|
+
type: "button",
|
|
1075
|
+
disabled: busy,
|
|
1076
|
+
onClick: () => void act(() => onEdit(message)),
|
|
1077
|
+
className: "w-full rounded px-2 py-1 text-left text-sm hover:bg-muted disabled:opacity-50",
|
|
1078
|
+
children: "Edit message"
|
|
1079
|
+
}
|
|
1080
|
+
) })
|
|
1081
|
+
] })
|
|
1082
|
+
] }) : null
|
|
1083
|
+
] }),
|
|
1084
|
+
error ? /* @__PURE__ */ jsx4("p", { role: "alert", className: "px-9 pb-2 text-xs text-destructive", children: error }) : null
|
|
1085
|
+
] });
|
|
1086
|
+
}
|
|
1087
|
+
function AgentChatQueue({ pending, queue, onRemove, onEdit, onResume, className }) {
|
|
1088
|
+
const [resumeError, setResumeError] = React4.useState(null);
|
|
1089
|
+
if (!pending.length && !queue?.paused) return null;
|
|
1090
|
+
return /* @__PURE__ */ jsxs2("section", { "aria-label": "Message queue", className: cn("a24-queue relative z-0 -mb-2 overflow-visible rounded-t-xl border border-b-0 border-border/50 bg-background pb-2", className), children: [
|
|
1091
|
+
queue?.paused ? /* @__PURE__ */ jsxs2("div", { className: "flex min-h-9 items-center justify-between gap-2 px-3 text-xs text-muted-foreground", children: [
|
|
1092
|
+
/* @__PURE__ */ jsx4("span", { children: "Queue paused" }),
|
|
1093
|
+
/* @__PURE__ */ jsx4("button", { type: "button", onClick: () => {
|
|
1094
|
+
void onResume().then(() => setResumeError(null)).catch((cause) => setResumeError(cause instanceof Error ? cause.message : "Could not resume queue"));
|
|
1095
|
+
}, className: "font-medium text-foreground hover:underline", children: "Resume queue" })
|
|
1096
|
+
] }) : null,
|
|
1097
|
+
resumeError ? /* @__PURE__ */ jsx4("p", { role: "alert", className: "px-3 pb-2 text-xs text-destructive", children: resumeError }) : null,
|
|
1098
|
+
/* @__PURE__ */ jsx4("div", { className: "max-h-40 overflow-y-auto", children: pending.map((message) => /* @__PURE__ */ jsx4(QueueRow, { message, onRemove, onEdit }, message.id)) })
|
|
1099
|
+
] });
|
|
1100
|
+
}
|
|
1101
|
+
|
|
980
1102
|
// src/ui/agent-chat-actions.tsx
|
|
981
|
-
import * as
|
|
1103
|
+
import * as React5 from "react";
|
|
982
1104
|
import { Check, Copy, RefreshCcw, ThumbsDown, ThumbsUp } from "lucide-react";
|
|
983
1105
|
import { Popover } from "radix-ui";
|
|
984
|
-
import { jsx as
|
|
1106
|
+
import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
985
1107
|
var FEEDBACK_REASONS = [
|
|
986
1108
|
["incorrect", "Incorrect"],
|
|
987
1109
|
["irrelevant", "Irrelevant"],
|
|
@@ -990,6 +1112,32 @@ var FEEDBACK_REASONS = [
|
|
|
990
1112
|
["citation_issue", "Citation issue"],
|
|
991
1113
|
["other", "Other"]
|
|
992
1114
|
];
|
|
1115
|
+
var enteredCompletionRuns = /* @__PURE__ */ new Set();
|
|
1116
|
+
function useLiveCompletionRuns(runId, isRunning) {
|
|
1117
|
+
const liveRuns = React5.useRef(/* @__PURE__ */ new Set());
|
|
1118
|
+
React5.useEffect(() => {
|
|
1119
|
+
if (!runId || !isRunning) return;
|
|
1120
|
+
liveRuns.current.add(runId);
|
|
1121
|
+
if (liveRuns.current.size > 256) liveRuns.current.delete(liveRuns.current.values().next().value);
|
|
1122
|
+
}, [runId, isRunning]);
|
|
1123
|
+
return (candidate) => Boolean(candidate && liveRuns.current.has(candidate));
|
|
1124
|
+
}
|
|
1125
|
+
function useCompletionActionEntrance(isComplete, runId, wasLive = false) {
|
|
1126
|
+
const sawIncomplete = React5.useRef(!isComplete);
|
|
1127
|
+
const entered = React5.useRef(false);
|
|
1128
|
+
const shouldEnter = isComplete && !entered.current && (runId ? wasLive && !enteredCompletionRuns.has(runId) : sawIncomplete.current);
|
|
1129
|
+
React5.useEffect(() => {
|
|
1130
|
+
if (!isComplete) sawIncomplete.current = true;
|
|
1131
|
+
else if (shouldEnter) {
|
|
1132
|
+
entered.current = true;
|
|
1133
|
+
if (runId) {
|
|
1134
|
+
enteredCompletionRuns.add(runId);
|
|
1135
|
+
if (enteredCompletionRuns.size > 256) enteredCompletionRuns.delete(enteredCompletionRuns.values().next().value);
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
}, [isComplete, runId, shouldEnter]);
|
|
1139
|
+
return shouldEnter || entered.current;
|
|
1140
|
+
}
|
|
993
1141
|
function formatSentAt(value) {
|
|
994
1142
|
if (!value) return null;
|
|
995
1143
|
const date = value instanceof Date ? value : new Date(value);
|
|
@@ -1001,21 +1149,22 @@ function formatSentAt(value) {
|
|
|
1001
1149
|
}
|
|
1002
1150
|
function AgentChatDefaultActions({
|
|
1003
1151
|
additionalActions,
|
|
1152
|
+
animateCompletion = false,
|
|
1004
1153
|
dir,
|
|
1005
1154
|
handlers,
|
|
1006
1155
|
message
|
|
1007
1156
|
}) {
|
|
1008
|
-
const [feedbackOpen, setFeedbackOpen] =
|
|
1009
|
-
const [feedbackTrigger, setFeedbackTrigger] =
|
|
1010
|
-
const [reason, setReason] =
|
|
1011
|
-
const [comment, setComment] =
|
|
1012
|
-
const [optimisticCopied, setOptimisticCopied] =
|
|
1013
|
-
const copyResetTimer =
|
|
1014
|
-
|
|
1157
|
+
const [feedbackOpen, setFeedbackOpen] = React5.useState(false);
|
|
1158
|
+
const [feedbackTrigger, setFeedbackTrigger] = React5.useState(null);
|
|
1159
|
+
const [reason, setReason] = React5.useState(handlers?.feedback?.reason ?? null);
|
|
1160
|
+
const [comment, setComment] = React5.useState(handlers?.feedback?.comment ?? "");
|
|
1161
|
+
const [optimisticCopied, setOptimisticCopied] = React5.useState(false);
|
|
1162
|
+
const copyResetTimer = React5.useRef(null);
|
|
1163
|
+
React5.useEffect(() => {
|
|
1015
1164
|
setReason(handlers?.feedback?.reason ?? null);
|
|
1016
1165
|
setComment(handlers?.feedback?.comment ?? "");
|
|
1017
1166
|
}, [handlers?.feedback?.comment, handlers?.feedback?.reason]);
|
|
1018
|
-
|
|
1167
|
+
React5.useEffect(() => () => {
|
|
1019
1168
|
if (copyResetTimer.current !== null) window.clearTimeout(copyResetTimer.current);
|
|
1020
1169
|
}, []);
|
|
1021
1170
|
const copied = handlers?.copied ?? optimisticCopied;
|
|
@@ -1032,32 +1181,32 @@ function AgentChatDefaultActions({
|
|
|
1032
1181
|
if (!handlers || message.isFinal === false) return null;
|
|
1033
1182
|
if (message.role === "user") {
|
|
1034
1183
|
const sentAt = formatSentAt(message.createdAt);
|
|
1035
|
-
return /* @__PURE__ */
|
|
1036
|
-
sentAt ? /* @__PURE__ */
|
|
1037
|
-
handlers.onCopy ? /* @__PURE__ */
|
|
1184
|
+
return /* @__PURE__ */ jsxs3(ChatMessageActions, { className: "a24-user-message-actions", children: [
|
|
1185
|
+
sentAt ? /* @__PURE__ */ jsx5("time", { dateTime: sentAt.dateTime, children: sentAt.label }) : null,
|
|
1186
|
+
handlers.onCopy ? /* @__PURE__ */ jsx5(
|
|
1038
1187
|
ChatMessageAction,
|
|
1039
1188
|
{
|
|
1040
1189
|
label: "Copy",
|
|
1041
1190
|
onClick: copyMessage,
|
|
1042
1191
|
tooltip: copied ? "Copied!" : "Copy to clipboard",
|
|
1043
1192
|
className: "a24-user-message-copy",
|
|
1044
|
-
children: copied ? /* @__PURE__ */
|
|
1193
|
+
children: copied ? /* @__PURE__ */ jsx5(Check, { className: "a24-user-message-copy__check text-green-600" }) : /* @__PURE__ */ jsx5(Copy, { className: "a24-user-message-copy__icon" })
|
|
1045
1194
|
}
|
|
1046
1195
|
) : null
|
|
1047
1196
|
] });
|
|
1048
1197
|
}
|
|
1049
1198
|
const canWriteFeedback = Boolean(message.runId && handlers.onSetFeedback);
|
|
1050
|
-
return /* @__PURE__ */
|
|
1051
|
-
handlers.onRetry ? /* @__PURE__ */
|
|
1199
|
+
return /* @__PURE__ */ jsxs3(ChatMessageActions, { className: animateCompletion ? "a24-chat-completion-actions" : void 0, children: [
|
|
1200
|
+
handlers.onRetry ? /* @__PURE__ */ jsx5(
|
|
1052
1201
|
ChatMessageAction,
|
|
1053
1202
|
{
|
|
1054
1203
|
label: "Retry",
|
|
1055
1204
|
onClick: () => void handlers.onRetry?.(message),
|
|
1056
1205
|
tooltip: "Regenerate response",
|
|
1057
|
-
children: /* @__PURE__ */
|
|
1206
|
+
children: /* @__PURE__ */ jsx5(RefreshCcw, { className: "size-4" })
|
|
1058
1207
|
}
|
|
1059
1208
|
) : null,
|
|
1060
|
-
canWriteFeedback ? /* @__PURE__ */
|
|
1209
|
+
canWriteFeedback ? /* @__PURE__ */ jsx5(
|
|
1061
1210
|
ChatMessageAction,
|
|
1062
1211
|
{
|
|
1063
1212
|
label: "Like",
|
|
@@ -1065,11 +1214,11 @@ function AgentChatDefaultActions({
|
|
|
1065
1214
|
rating: handlers.feedback?.rating === "like" ? null : "like"
|
|
1066
1215
|
}),
|
|
1067
1216
|
tooltip: "Like this response",
|
|
1068
|
-
children: /* @__PURE__ */
|
|
1217
|
+
children: /* @__PURE__ */ jsx5(ThumbsUp, { className: "size-4", fill: handlers.feedback?.rating === "like" ? "currentColor" : "none" })
|
|
1069
1218
|
}
|
|
1070
1219
|
) : null,
|
|
1071
|
-
canWriteFeedback ? /* @__PURE__ */
|
|
1072
|
-
/* @__PURE__ */
|
|
1220
|
+
canWriteFeedback ? /* @__PURE__ */ jsxs3(Popover.Root, { onOpenChange: setFeedbackOpen, open: feedbackOpen, children: [
|
|
1221
|
+
/* @__PURE__ */ jsx5(Popover.Trigger, { asChild: true, children: /* @__PURE__ */ jsx5(
|
|
1073
1222
|
ChatMessageAction,
|
|
1074
1223
|
{
|
|
1075
1224
|
label: "Dislike",
|
|
@@ -1081,14 +1230,14 @@ function AgentChatDefaultActions({
|
|
|
1081
1230
|
},
|
|
1082
1231
|
ref: setFeedbackTrigger,
|
|
1083
1232
|
tooltip: "Dislike this response",
|
|
1084
|
-
children: /* @__PURE__ */
|
|
1233
|
+
children: /* @__PURE__ */ jsx5(ThumbsDown, { className: "size-4", fill: handlers.feedback?.rating === "dislike" ? "currentColor" : "none" })
|
|
1085
1234
|
}
|
|
1086
1235
|
) }),
|
|
1087
|
-
/* @__PURE__ */
|
|
1236
|
+
/* @__PURE__ */ jsx5(
|
|
1088
1237
|
Popover.Portal,
|
|
1089
1238
|
{
|
|
1090
1239
|
container: feedbackTrigger?.closest("[data-agents24-theme-root]") ?? void 0,
|
|
1091
|
-
children: /* @__PURE__ */
|
|
1240
|
+
children: /* @__PURE__ */ jsxs3(
|
|
1092
1241
|
Popover.Content,
|
|
1093
1242
|
{
|
|
1094
1243
|
align: "end",
|
|
@@ -1098,8 +1247,8 @@ function AgentChatDefaultActions({
|
|
|
1098
1247
|
side: "top",
|
|
1099
1248
|
sideOffset: 8,
|
|
1100
1249
|
children: [
|
|
1101
|
-
/* @__PURE__ */
|
|
1102
|
-
/* @__PURE__ */
|
|
1250
|
+
/* @__PURE__ */ jsx5("p", { className: "text-sm font-medium", children: "What could be better?" }),
|
|
1251
|
+
/* @__PURE__ */ jsx5("div", { className: "mt-3 flex flex-wrap gap-1.5", children: FEEDBACK_REASONS.map(([value, label]) => /* @__PURE__ */ jsx5(
|
|
1103
1252
|
"button",
|
|
1104
1253
|
{
|
|
1105
1254
|
"aria-pressed": reason === value,
|
|
@@ -1110,7 +1259,7 @@ function AgentChatDefaultActions({
|
|
|
1110
1259
|
},
|
|
1111
1260
|
value
|
|
1112
1261
|
)) }),
|
|
1113
|
-
/* @__PURE__ */
|
|
1262
|
+
/* @__PURE__ */ jsx5(
|
|
1114
1263
|
"textarea",
|
|
1115
1264
|
{
|
|
1116
1265
|
"aria-label": "Optional feedback comment",
|
|
@@ -1121,8 +1270,8 @@ function AgentChatDefaultActions({
|
|
|
1121
1270
|
value: comment
|
|
1122
1271
|
}
|
|
1123
1272
|
),
|
|
1124
|
-
/* @__PURE__ */
|
|
1125
|
-
/* @__PURE__ */
|
|
1273
|
+
/* @__PURE__ */ jsxs3("div", { className: "mt-3 flex items-center justify-between gap-2", children: [
|
|
1274
|
+
/* @__PURE__ */ jsx5(
|
|
1126
1275
|
"button",
|
|
1127
1276
|
{
|
|
1128
1277
|
className: "rounded-md px-3 py-2 text-sm font-medium hover:bg-muted",
|
|
@@ -1133,7 +1282,7 @@ function AgentChatDefaultActions({
|
|
|
1133
1282
|
children: "Remove feedback"
|
|
1134
1283
|
}
|
|
1135
1284
|
),
|
|
1136
|
-
/* @__PURE__ */
|
|
1285
|
+
/* @__PURE__ */ jsx5(
|
|
1137
1286
|
"button",
|
|
1138
1287
|
{
|
|
1139
1288
|
className: "rounded-md bg-primary px-3 py-2 text-sm font-medium text-primary-foreground hover:opacity-90",
|
|
@@ -1152,27 +1301,27 @@ function AgentChatDefaultActions({
|
|
|
1152
1301
|
)
|
|
1153
1302
|
] }) : null,
|
|
1154
1303
|
additionalActions,
|
|
1155
|
-
handlers.onCopy ? /* @__PURE__ */
|
|
1304
|
+
handlers.onCopy ? /* @__PURE__ */ jsx5(
|
|
1156
1305
|
ChatMessageAction,
|
|
1157
1306
|
{
|
|
1158
1307
|
label: "Copy",
|
|
1159
1308
|
onClick: copyMessage,
|
|
1160
1309
|
tooltip: copied ? "Copied!" : "Copy to clipboard",
|
|
1161
|
-
children: copied ? /* @__PURE__ */
|
|
1310
|
+
children: copied ? /* @__PURE__ */ jsx5(Check, { className: "size-4 text-green-600" }) : /* @__PURE__ */ jsx5(Copy, { className: "size-4" })
|
|
1162
1311
|
}
|
|
1163
1312
|
) : null
|
|
1164
1313
|
] });
|
|
1165
1314
|
}
|
|
1166
1315
|
|
|
1167
1316
|
// src/ui/agent-chat-message.tsx
|
|
1168
|
-
import * as
|
|
1317
|
+
import * as React10 from "react";
|
|
1169
1318
|
import { ChevronDown as ChevronDown3, ChevronUp } from "lucide-react";
|
|
1170
1319
|
|
|
1171
1320
|
// src/ui/agent-response-timeline.tsx
|
|
1172
|
-
import * as
|
|
1321
|
+
import * as React9 from "react";
|
|
1173
1322
|
|
|
1174
1323
|
// src/ui/ask-user-interaction.tsx
|
|
1175
|
-
import * as
|
|
1324
|
+
import * as React6 from "react";
|
|
1176
1325
|
import {
|
|
1177
1326
|
ChevronDown,
|
|
1178
1327
|
ChevronLeft,
|
|
@@ -1234,7 +1383,7 @@ function askUserAnswersFromDrafts(questions, drafts) {
|
|
|
1234
1383
|
}
|
|
1235
1384
|
|
|
1236
1385
|
// src/ui/ask-user-interaction.tsx
|
|
1237
|
-
import { jsx as
|
|
1386
|
+
import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1238
1387
|
function resolvedAnswerText(question, answer) {
|
|
1239
1388
|
if (!answer) return ["No response recorded"];
|
|
1240
1389
|
const labels = answer.selectedOptionIds.flatMap((optionId) => {
|
|
@@ -1248,7 +1397,7 @@ function ResolvedQuestions({
|
|
|
1248
1397
|
buttonRef,
|
|
1249
1398
|
part
|
|
1250
1399
|
}) {
|
|
1251
|
-
const [open, setOpen] =
|
|
1400
|
+
const [open, setOpen] = React6.useState(false);
|
|
1252
1401
|
const count = part.questions.length;
|
|
1253
1402
|
const answers = new Map(
|
|
1254
1403
|
(part.resolution?.answers || []).map((answer) => [
|
|
@@ -1256,8 +1405,8 @@ function ResolvedQuestions({
|
|
|
1256
1405
|
answer
|
|
1257
1406
|
])
|
|
1258
1407
|
);
|
|
1259
|
-
return /* @__PURE__ */
|
|
1260
|
-
/* @__PURE__ */
|
|
1408
|
+
return /* @__PURE__ */ jsxs4("div", { className: "a24-ask-user a24-ask-user--resolved w-full", children: [
|
|
1409
|
+
/* @__PURE__ */ jsxs4(
|
|
1261
1410
|
"button",
|
|
1262
1411
|
{
|
|
1263
1412
|
"aria-expanded": open,
|
|
@@ -1266,13 +1415,13 @@ function ResolvedQuestions({
|
|
|
1266
1415
|
ref: buttonRef,
|
|
1267
1416
|
type: "button",
|
|
1268
1417
|
children: [
|
|
1269
|
-
/* @__PURE__ */
|
|
1418
|
+
/* @__PURE__ */ jsxs4("span", { children: [
|
|
1270
1419
|
"Asked ",
|
|
1271
1420
|
count,
|
|
1272
1421
|
" question",
|
|
1273
1422
|
count === 1 ? "" : "s"
|
|
1274
1423
|
] }),
|
|
1275
|
-
open ? /* @__PURE__ */
|
|
1424
|
+
open ? /* @__PURE__ */ jsx6(ChevronDown, { "aria-hidden": "true", className: "size-3.5" }) : /* @__PURE__ */ jsx6(
|
|
1276
1425
|
ChevronRight,
|
|
1277
1426
|
{
|
|
1278
1427
|
"aria-hidden": "true",
|
|
@@ -1282,12 +1431,12 @@ function ResolvedQuestions({
|
|
|
1282
1431
|
]
|
|
1283
1432
|
}
|
|
1284
1433
|
),
|
|
1285
|
-
open ? /* @__PURE__ */
|
|
1286
|
-
/* @__PURE__ */
|
|
1287
|
-
/* @__PURE__ */
|
|
1434
|
+
open ? /* @__PURE__ */ jsx6("div", { className: "mt-2 space-y-3 ps-4", children: part.questions.map((question) => /* @__PURE__ */ jsxs4("div", { className: "min-w-0", children: [
|
|
1435
|
+
/* @__PURE__ */ jsx6("div", { className: "text-sm font-medium text-foreground", children: question.question }),
|
|
1436
|
+
/* @__PURE__ */ jsx6("div", { className: "mt-1 space-y-1 text-sm text-muted-foreground", children: resolvedAnswerText(
|
|
1288
1437
|
question,
|
|
1289
1438
|
answers.get(question.id)
|
|
1290
|
-
).map((value, index) => /* @__PURE__ */
|
|
1439
|
+
).map((value, index) => /* @__PURE__ */ jsx6(
|
|
1291
1440
|
"div",
|
|
1292
1441
|
{
|
|
1293
1442
|
className: "whitespace-pre-wrap break-words",
|
|
@@ -1305,23 +1454,23 @@ function AskUserInteraction({
|
|
|
1305
1454
|
part
|
|
1306
1455
|
}) {
|
|
1307
1456
|
const questions = part.questions;
|
|
1308
|
-
const [step, setStep] =
|
|
1309
|
-
const [drafts, setDrafts] =
|
|
1457
|
+
const [step, setStep] = React6.useState(0);
|
|
1458
|
+
const [drafts, setDrafts] = React6.useState(
|
|
1310
1459
|
() => emptyAskUserDrafts(questions)
|
|
1311
1460
|
);
|
|
1312
|
-
const headingRef =
|
|
1313
|
-
const questionsRef =
|
|
1314
|
-
const resolvedButtonRef =
|
|
1315
|
-
const wasResolvedRef =
|
|
1461
|
+
const headingRef = React6.useRef(null);
|
|
1462
|
+
const questionsRef = React6.useRef(questions);
|
|
1463
|
+
const resolvedButtonRef = React6.useRef(null);
|
|
1464
|
+
const wasResolvedRef = React6.useRef(part.status !== "pending");
|
|
1316
1465
|
questionsRef.current = questions;
|
|
1317
|
-
|
|
1466
|
+
React6.useEffect(() => {
|
|
1318
1467
|
setStep(0);
|
|
1319
1468
|
setDrafts(emptyAskUserDrafts(questionsRef.current));
|
|
1320
1469
|
}, [part.interruptId]);
|
|
1321
|
-
|
|
1470
|
+
React6.useEffect(() => {
|
|
1322
1471
|
headingRef.current?.focus();
|
|
1323
1472
|
}, [step]);
|
|
1324
|
-
|
|
1473
|
+
React6.useEffect(() => {
|
|
1325
1474
|
const isResolved = part.status !== "pending";
|
|
1326
1475
|
if (isResolved && !wasResolvedRef.current) {
|
|
1327
1476
|
resolvedButtonRef.current?.focus();
|
|
@@ -1329,11 +1478,11 @@ function AskUserInteraction({
|
|
|
1329
1478
|
wasResolvedRef.current = isResolved;
|
|
1330
1479
|
}, [part.status]);
|
|
1331
1480
|
if (part.status !== "pending") {
|
|
1332
|
-
return /* @__PURE__ */
|
|
1481
|
+
return /* @__PURE__ */ jsx6(ResolvedQuestions, { buttonRef: resolvedButtonRef, part });
|
|
1333
1482
|
}
|
|
1334
1483
|
const question = questions[step];
|
|
1335
1484
|
if (!question) {
|
|
1336
|
-
return /* @__PURE__ */
|
|
1485
|
+
return /* @__PURE__ */ jsx6("div", { className: "text-sm text-destructive", role: "alert", children: "This question request is unavailable." });
|
|
1337
1486
|
}
|
|
1338
1487
|
const draft = drafts[question.id] || {
|
|
1339
1488
|
customText: "",
|
|
@@ -1367,9 +1516,9 @@ function AskUserInteraction({
|
|
|
1367
1516
|
})
|
|
1368
1517
|
);
|
|
1369
1518
|
};
|
|
1370
|
-
return /* @__PURE__ */
|
|
1371
|
-
/* @__PURE__ */
|
|
1372
|
-
/* @__PURE__ */
|
|
1519
|
+
return /* @__PURE__ */ jsxs4("div", { className: "a24-ask-user space-y-3 rounded-xl border border-border/50 bg-background p-4 shadow-sm", children: [
|
|
1520
|
+
/* @__PURE__ */ jsxs4("div", { className: "flex min-w-0 items-start justify-between gap-4", children: [
|
|
1521
|
+
/* @__PURE__ */ jsx6(
|
|
1373
1522
|
"h3",
|
|
1374
1523
|
{
|
|
1375
1524
|
className: "min-w-0 flex-1 text-base font-medium leading-6 text-foreground outline-none",
|
|
@@ -1378,8 +1527,8 @@ function AskUserInteraction({
|
|
|
1378
1527
|
children: question.question
|
|
1379
1528
|
}
|
|
1380
1529
|
),
|
|
1381
|
-
/* @__PURE__ */
|
|
1382
|
-
/* @__PURE__ */
|
|
1530
|
+
/* @__PURE__ */ jsxs4("div", { className: "flex shrink-0 items-center gap-1 text-muted-foreground", children: [
|
|
1531
|
+
/* @__PURE__ */ jsx6(
|
|
1383
1532
|
"button",
|
|
1384
1533
|
{
|
|
1385
1534
|
"aria-label": "Previous question",
|
|
@@ -1387,7 +1536,7 @@ function AskUserInteraction({
|
|
|
1387
1536
|
disabled: isBusy || step === 0,
|
|
1388
1537
|
onClick: () => setStep((current) => Math.max(0, current - 1)),
|
|
1389
1538
|
type: "button",
|
|
1390
|
-
children: /* @__PURE__ */
|
|
1539
|
+
children: /* @__PURE__ */ jsx6(
|
|
1391
1540
|
ChevronLeft,
|
|
1392
1541
|
{
|
|
1393
1542
|
"aria-hidden": "true",
|
|
@@ -1396,7 +1545,7 @@ function AskUserInteraction({
|
|
|
1396
1545
|
)
|
|
1397
1546
|
}
|
|
1398
1547
|
),
|
|
1399
|
-
/* @__PURE__ */
|
|
1548
|
+
/* @__PURE__ */ jsxs4(
|
|
1400
1549
|
"span",
|
|
1401
1550
|
{
|
|
1402
1551
|
"aria-label": `Question ${step + 1} of ${questions.length}`,
|
|
@@ -1408,7 +1557,7 @@ function AskUserInteraction({
|
|
|
1408
1557
|
]
|
|
1409
1558
|
}
|
|
1410
1559
|
),
|
|
1411
|
-
/* @__PURE__ */
|
|
1560
|
+
/* @__PURE__ */ jsx6(
|
|
1412
1561
|
"button",
|
|
1413
1562
|
{
|
|
1414
1563
|
"aria-label": isLastQuestion ? "Submit answers" : "Next question",
|
|
@@ -1416,7 +1565,7 @@ function AskUserInteraction({
|
|
|
1416
1565
|
disabled: isBusy || !onSubmit || !canMoveForward,
|
|
1417
1566
|
onClick: () => completeStep(drafts),
|
|
1418
1567
|
type: "button",
|
|
1419
|
-
children: /* @__PURE__ */
|
|
1568
|
+
children: /* @__PURE__ */ jsx6(
|
|
1420
1569
|
ChevronRight,
|
|
1421
1570
|
{
|
|
1422
1571
|
"aria-hidden": "true",
|
|
@@ -1427,10 +1576,10 @@ function AskUserInteraction({
|
|
|
1427
1576
|
)
|
|
1428
1577
|
] })
|
|
1429
1578
|
] }),
|
|
1430
|
-
/* @__PURE__ */
|
|
1579
|
+
/* @__PURE__ */ jsxs4("div", { className: "space-y-1", children: [
|
|
1431
1580
|
question.options.map((option, index) => {
|
|
1432
1581
|
const selected = draft.selectedOptionIds.includes(option.id);
|
|
1433
|
-
return /* @__PURE__ */
|
|
1582
|
+
return /* @__PURE__ */ jsxs4(
|
|
1434
1583
|
"button",
|
|
1435
1584
|
{
|
|
1436
1585
|
"aria-pressed": selected,
|
|
@@ -1442,7 +1591,7 @@ function AskUserInteraction({
|
|
|
1442
1591
|
onClick: () => selectOption(option.id),
|
|
1443
1592
|
type: "button",
|
|
1444
1593
|
children: [
|
|
1445
|
-
/* @__PURE__ */
|
|
1594
|
+
/* @__PURE__ */ jsx6(
|
|
1446
1595
|
"span",
|
|
1447
1596
|
{
|
|
1448
1597
|
className: cn(
|
|
@@ -1452,8 +1601,8 @@ function AskUserInteraction({
|
|
|
1452
1601
|
children: index + 1
|
|
1453
1602
|
}
|
|
1454
1603
|
),
|
|
1455
|
-
/* @__PURE__ */
|
|
1456
|
-
/* @__PURE__ */
|
|
1604
|
+
/* @__PURE__ */ jsx6("span", { className: "min-w-0 flex-1 font-medium text-foreground", children: option.label }),
|
|
1605
|
+
/* @__PURE__ */ jsx6(
|
|
1457
1606
|
ChevronRight,
|
|
1458
1607
|
{
|
|
1459
1608
|
"aria-hidden": "true",
|
|
@@ -1465,9 +1614,9 @@ function AskUserInteraction({
|
|
|
1465
1614
|
option.id
|
|
1466
1615
|
);
|
|
1467
1616
|
}),
|
|
1468
|
-
/* @__PURE__ */
|
|
1469
|
-
/* @__PURE__ */
|
|
1470
|
-
/* @__PURE__ */
|
|
1617
|
+
/* @__PURE__ */ jsxs4("div", { className: "flex min-h-11 items-center gap-2 rounded-xl bg-muted px-2.5 py-1.5 focus-within:ring-1 focus-within:ring-ring", children: [
|
|
1618
|
+
/* @__PURE__ */ jsx6("span", { className: "flex size-8 shrink-0 items-center justify-center rounded-full border border-border/70 bg-background/70 text-muted-foreground", children: /* @__PURE__ */ jsx6(Pencil, { "aria-hidden": "true", className: "size-4" }) }),
|
|
1619
|
+
/* @__PURE__ */ jsx6(
|
|
1471
1620
|
"input",
|
|
1472
1621
|
{
|
|
1473
1622
|
"aria-label": "Other response",
|
|
@@ -1486,7 +1635,7 @@ function AskUserInteraction({
|
|
|
1486
1635
|
value: draft.customText
|
|
1487
1636
|
}
|
|
1488
1637
|
),
|
|
1489
|
-
draft.customText.trim() ? /* @__PURE__ */
|
|
1638
|
+
draft.customText.trim() ? /* @__PURE__ */ jsx6(
|
|
1490
1639
|
"button",
|
|
1491
1640
|
{
|
|
1492
1641
|
className: "h-8 shrink-0 rounded-full bg-foreground px-4 text-sm font-medium text-background transition-colors hover:opacity-85 disabled:opacity-50",
|
|
@@ -1498,12 +1647,12 @@ function AskUserInteraction({
|
|
|
1498
1647
|
) : null
|
|
1499
1648
|
] })
|
|
1500
1649
|
] }),
|
|
1501
|
-
error ? /* @__PURE__ */
|
|
1650
|
+
error ? /* @__PURE__ */ jsx6("div", { className: "text-sm text-destructive", role: "alert", children: error }) : null
|
|
1502
1651
|
] });
|
|
1503
1652
|
}
|
|
1504
1653
|
|
|
1505
1654
|
// src/ui/agent-chat-context-compression-row.tsx
|
|
1506
|
-
import { jsx as
|
|
1655
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
1507
1656
|
function compressionPresentation(part) {
|
|
1508
1657
|
if (part.status === "failed") {
|
|
1509
1658
|
return { label: "Could not compact message history", status: "failed" };
|
|
@@ -1518,7 +1667,7 @@ function AgentChatContextCompressionRow({
|
|
|
1518
1667
|
part
|
|
1519
1668
|
}) {
|
|
1520
1669
|
const presentation = compressionPresentation(part);
|
|
1521
|
-
return /* @__PURE__ */
|
|
1670
|
+
return /* @__PURE__ */ jsx7(
|
|
1522
1671
|
"div",
|
|
1523
1672
|
{
|
|
1524
1673
|
"aria-live": "polite",
|
|
@@ -1526,11 +1675,11 @@ function AgentChatContextCompressionRow({
|
|
|
1526
1675
|
"data-agents24-context-compression": "",
|
|
1527
1676
|
"data-status": part.status,
|
|
1528
1677
|
role: "status",
|
|
1529
|
-
children: /* @__PURE__ */
|
|
1678
|
+
children: /* @__PURE__ */ jsx7("div", { className: "a24-tool-trigger-row", children: /* @__PURE__ */ jsx7("div", { className: cn(
|
|
1530
1679
|
"a24-tool-trigger a24-tool-trigger--root a24-tool-trigger--without-orb",
|
|
1531
1680
|
presentation.status === "failed" && "a24-tool-trigger--error",
|
|
1532
1681
|
presentation.status === "running" && "a24-tool-trigger--active"
|
|
1533
|
-
), children: /* @__PURE__ */
|
|
1682
|
+
), children: /* @__PURE__ */ jsx7("span", { className: cn(
|
|
1534
1683
|
"a24-tool-trigger__label",
|
|
1535
1684
|
presentation.status === "running" && "a24-tool-shimmer"
|
|
1536
1685
|
), children: presentation.label }) }) })
|
|
@@ -1539,7 +1688,7 @@ function AgentChatContextCompressionRow({
|
|
|
1539
1688
|
}
|
|
1540
1689
|
|
|
1541
1690
|
// src/ui/message-response.tsx
|
|
1542
|
-
import * as
|
|
1691
|
+
import * as React7 from "react";
|
|
1543
1692
|
import { defaultRehypePlugins, Streamdown } from "streamdown";
|
|
1544
1693
|
|
|
1545
1694
|
// src/active-content.ts
|
|
@@ -1564,17 +1713,17 @@ function safeChatMarkdownHref(value) {
|
|
|
1564
1713
|
}
|
|
1565
1714
|
|
|
1566
1715
|
// src/ui/message-response.tsx
|
|
1567
|
-
import { Fragment, jsx as
|
|
1716
|
+
import { Fragment as Fragment2, jsx as jsx8 } from "react/jsx-runtime";
|
|
1568
1717
|
function SafeMarkdownLink({ children, href, ...props }) {
|
|
1569
1718
|
const domProps = { ...props };
|
|
1570
1719
|
delete domProps.node;
|
|
1571
1720
|
const safeHref = safeChatMarkdownHref(href);
|
|
1572
|
-
if (!safeHref) return /* @__PURE__ */
|
|
1573
|
-
if (safeHref.startsWith("#")) return /* @__PURE__ */
|
|
1574
|
-
return /* @__PURE__ */
|
|
1721
|
+
if (!safeHref) return /* @__PURE__ */ jsx8("span", { children });
|
|
1722
|
+
if (safeHref.startsWith("#")) return /* @__PURE__ */ jsx8("a", { ...domProps, href: safeHref, children });
|
|
1723
|
+
return /* @__PURE__ */ jsx8("a", { ...domProps, href: safeHref, rel: "noopener noreferrer", target: "_blank", children });
|
|
1575
1724
|
}
|
|
1576
1725
|
function BlockedMarkdownImage({ alt }) {
|
|
1577
|
-
return alt ? /* @__PURE__ */
|
|
1726
|
+
return alt ? /* @__PURE__ */ jsx8("span", { "aria-label": `Image blocked: ${alt}`, role: "img", children: alt }) : null;
|
|
1578
1727
|
}
|
|
1579
1728
|
var BLOCK_MARKDOWN_TAGS = /* @__PURE__ */ new Set([
|
|
1580
1729
|
"blockquote",
|
|
@@ -1595,7 +1744,7 @@ function isMultilineCodeNode(node) {
|
|
|
1595
1744
|
return node?.tagName === "code" && node.position?.start?.line !== void 0 && node.position?.end?.line !== void 0 && node.position.start.line !== node.position.end.line;
|
|
1596
1745
|
}
|
|
1597
1746
|
function hasBlockMarkdownChild(child) {
|
|
1598
|
-
if (!
|
|
1747
|
+
if (!React7.isValidElement(child)) {
|
|
1599
1748
|
return false;
|
|
1600
1749
|
}
|
|
1601
1750
|
if (typeof child.type === "string" && BLOCK_MARKDOWN_TAGS.has(child.type)) {
|
|
@@ -1605,7 +1754,7 @@ function hasBlockMarkdownChild(child) {
|
|
|
1605
1754
|
if (BLOCK_MARKDOWN_TAGS.has(props.node?.tagName || "") || isMultilineCodeNode(props.node)) {
|
|
1606
1755
|
return true;
|
|
1607
1756
|
}
|
|
1608
|
-
return
|
|
1757
|
+
return React7.Children.toArray(props.children).some(hasBlockMarkdownChild);
|
|
1609
1758
|
}
|
|
1610
1759
|
function MessageMarkdownParagraph({
|
|
1611
1760
|
children,
|
|
@@ -1613,17 +1762,17 @@ function MessageMarkdownParagraph({
|
|
|
1613
1762
|
}) {
|
|
1614
1763
|
const domProps = { ...props };
|
|
1615
1764
|
delete domProps.node;
|
|
1616
|
-
const childArray =
|
|
1765
|
+
const childArray = React7.Children.toArray(children).filter(
|
|
1617
1766
|
(child) => child !== null && child !== ""
|
|
1618
1767
|
);
|
|
1619
|
-
const isImageOnly = childArray.length === 1 &&
|
|
1768
|
+
const isImageOnly = childArray.length === 1 && React7.isValidElement(childArray[0]) && childArray[0].props.node?.tagName === "img";
|
|
1620
1769
|
if (isImageOnly) {
|
|
1621
|
-
return /* @__PURE__ */
|
|
1770
|
+
return /* @__PURE__ */ jsx8(Fragment2, { children });
|
|
1622
1771
|
}
|
|
1623
1772
|
if (childArray.some(hasBlockMarkdownChild)) {
|
|
1624
|
-
return /* @__PURE__ */
|
|
1773
|
+
return /* @__PURE__ */ jsx8("div", { ...domProps, children });
|
|
1625
1774
|
}
|
|
1626
|
-
return /* @__PURE__ */
|
|
1775
|
+
return /* @__PURE__ */ jsx8("p", { ...domProps, children });
|
|
1627
1776
|
}
|
|
1628
1777
|
var MESSAGE_RESPONSE_COMPONENTS = {
|
|
1629
1778
|
a: SafeMarkdownLink,
|
|
@@ -1643,7 +1792,7 @@ var MESSAGE_RESPONSE_REHYPE_PLUGINS = [
|
|
|
1643
1792
|
]
|
|
1644
1793
|
] : []
|
|
1645
1794
|
];
|
|
1646
|
-
var MessageResponse =
|
|
1795
|
+
var MessageResponse = React7.memo(
|
|
1647
1796
|
({
|
|
1648
1797
|
children,
|
|
1649
1798
|
className,
|
|
@@ -1661,11 +1810,11 @@ var MessageResponse = React5.memo(
|
|
|
1661
1810
|
maxCatchupChars: 32,
|
|
1662
1811
|
text
|
|
1663
1812
|
});
|
|
1664
|
-
const streamdownComponents =
|
|
1813
|
+
const streamdownComponents = React7.useMemo(
|
|
1665
1814
|
() => ({ ...MESSAGE_RESPONSE_COMPONENTS, ...components }),
|
|
1666
1815
|
[components]
|
|
1667
1816
|
);
|
|
1668
|
-
return /* @__PURE__ */
|
|
1817
|
+
return /* @__PURE__ */ jsx8(
|
|
1669
1818
|
Streamdown,
|
|
1670
1819
|
{
|
|
1671
1820
|
className: cn("a24-message-response", className),
|
|
@@ -1717,10 +1866,46 @@ function resolvedHitlLabel(part) {
|
|
|
1717
1866
|
}
|
|
1718
1867
|
|
|
1719
1868
|
// src/ui/tool-sessions.tsx
|
|
1720
|
-
import * as
|
|
1869
|
+
import * as React8 from "react";
|
|
1721
1870
|
import { ChevronDown as ChevronDown2, ChevronRight as ChevronRight2 } from "lucide-react";
|
|
1722
1871
|
import { ThinkingOrb } from "thinking-orbs";
|
|
1723
|
-
import { Fragment as
|
|
1872
|
+
import { Fragment as Fragment3, jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1873
|
+
function toolSlotContext(isActive2, label, part, slots) {
|
|
1874
|
+
return {
|
|
1875
|
+
isActive: isActive2,
|
|
1876
|
+
label,
|
|
1877
|
+
part,
|
|
1878
|
+
resourceTargets: part.resourceTargets || [],
|
|
1879
|
+
openResource: (target) => slots?.onResourceAction?.(target, part)
|
|
1880
|
+
};
|
|
1881
|
+
}
|
|
1882
|
+
function resourceTargetName(target) {
|
|
1883
|
+
const normalized = target.path.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
1884
|
+
return normalized.split("/").filter(Boolean).pop() || "workspace";
|
|
1885
|
+
}
|
|
1886
|
+
function ToolResourceAction({ context }) {
|
|
1887
|
+
const target = context.resourceTargets[0];
|
|
1888
|
+
if (!target) return null;
|
|
1889
|
+
const name = resourceTargetName(target);
|
|
1890
|
+
return /* @__PURE__ */ jsx9(
|
|
1891
|
+
"button",
|
|
1892
|
+
{
|
|
1893
|
+
"aria-label": `Open ${target.kind} ${target.path}`,
|
|
1894
|
+
className: "a24-tool-resource-action",
|
|
1895
|
+
"data-agents24-resource-path": target.path,
|
|
1896
|
+
onClick: () => context.openResource(target),
|
|
1897
|
+
title: target.path,
|
|
1898
|
+
type: "button",
|
|
1899
|
+
children: name
|
|
1900
|
+
}
|
|
1901
|
+
);
|
|
1902
|
+
}
|
|
1903
|
+
function toolAccessory(context, slots) {
|
|
1904
|
+
return /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
1905
|
+
slots?.onResourceAction ? /* @__PURE__ */ jsx9(ToolResourceAction, { context }) : null,
|
|
1906
|
+
slots?.renderToolAccessory?.(context)
|
|
1907
|
+
] });
|
|
1908
|
+
}
|
|
1724
1909
|
function agentChatToolLabel(part) {
|
|
1725
1910
|
const presentation = part.presentation || {};
|
|
1726
1911
|
return optionalText(presentation.activity) || optionalText(presentation.title) || optionalText(part.displayName) || optionalText(part.summary) || optionalText(part.toolName) || "Tool activity";
|
|
@@ -1794,12 +1979,12 @@ function ToolActivityReel({
|
|
|
1794
1979
|
}) {
|
|
1795
1980
|
const initial = initialLabel && initialLabel !== label ? initialLabel : label;
|
|
1796
1981
|
const parsedInitialShownAt = initialShownAt ? Date.parse(initialShownAt) : Number.NaN;
|
|
1797
|
-
const [displayed, setDisplayed] =
|
|
1798
|
-
const [previous, setPrevious] =
|
|
1799
|
-
const displayedRef =
|
|
1800
|
-
const latestRef =
|
|
1801
|
-
const shownAtRef =
|
|
1802
|
-
|
|
1982
|
+
const [displayed, setDisplayed] = React8.useState(initial);
|
|
1983
|
+
const [previous, setPrevious] = React8.useState(null);
|
|
1984
|
+
const displayedRef = React8.useRef(initial);
|
|
1985
|
+
const latestRef = React8.useRef(label);
|
|
1986
|
+
const shownAtRef = React8.useRef(Number.isFinite(parsedInitialShownAt) ? parsedInitialShownAt : Date.now());
|
|
1987
|
+
React8.useEffect(() => {
|
|
1803
1988
|
latestRef.current = label;
|
|
1804
1989
|
if (displayedRef.current === label) return;
|
|
1805
1990
|
const showLatest = () => {
|
|
@@ -1819,39 +2004,39 @@ function ToolActivityReel({
|
|
|
1819
2004
|
const timer = window.setTimeout(showLatest, remaining);
|
|
1820
2005
|
return () => window.clearTimeout(timer);
|
|
1821
2006
|
}, [label]);
|
|
1822
|
-
|
|
2007
|
+
React8.useEffect(() => {
|
|
1823
2008
|
if (!previous) return;
|
|
1824
2009
|
const timer = window.setTimeout(() => setPrevious(null), 200);
|
|
1825
2010
|
return () => window.clearTimeout(timer);
|
|
1826
2011
|
}, [previous]);
|
|
1827
|
-
return /* @__PURE__ */
|
|
1828
|
-
previous ? /* @__PURE__ */
|
|
1829
|
-
/* @__PURE__ */
|
|
2012
|
+
return /* @__PURE__ */ jsxs5("span", { className: "a24-tool-reel", "aria-live": announce ? "polite" : "off", children: [
|
|
2013
|
+
previous ? /* @__PURE__ */ jsx9("span", { "aria-hidden": "true", className: "a24-tool-reel__previous", children: previous }) : null,
|
|
2014
|
+
/* @__PURE__ */ jsx9("span", { className: previous ? "a24-tool-reel__current" : void 0, children: displayed })
|
|
1830
2015
|
] });
|
|
1831
2016
|
}
|
|
1832
2017
|
function ToolActivityOrb({ label }) {
|
|
1833
|
-
return /* @__PURE__ */
|
|
2018
|
+
return /* @__PURE__ */ jsx9("span", { className: "a24-tool-orb", children: /* @__PURE__ */ jsx9(ThinkingOrb, { "aria-label": label || "Working", size: 20, speed: 0.8, state: "searching" }) });
|
|
1834
2019
|
}
|
|
1835
2020
|
function AgentChatActivityRow({
|
|
1836
2021
|
label,
|
|
1837
2022
|
modelTurnId,
|
|
1838
2023
|
onSelect
|
|
1839
2024
|
}) {
|
|
1840
|
-
const content = /* @__PURE__ */
|
|
1841
|
-
/* @__PURE__ */
|
|
1842
|
-
/* @__PURE__ */
|
|
2025
|
+
const content = /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
2026
|
+
/* @__PURE__ */ jsx9(ToolActivityOrb, { label }),
|
|
2027
|
+
/* @__PURE__ */ jsx9("span", { className: "a24-tool-trigger__label a24-tool-shimmer", children: /* @__PURE__ */ jsx9(ToolActivityReel, { label }) })
|
|
1843
2028
|
] });
|
|
1844
|
-
return /* @__PURE__ */
|
|
2029
|
+
return /* @__PURE__ */ jsx9("div", { className: "a24-tool-trigger-row a24-tool-trigger-row--root", "data-agents24-model-turn": modelTurnId, role: "status", children: onSelect ? /* @__PURE__ */ jsx9("button", { className: "a24-tool-trigger a24-tool-trigger--root a24-tool-trigger--active", onClick: onSelect, type: "button", children: content }) : /* @__PURE__ */ jsx9("div", { className: "a24-tool-trigger a24-tool-trigger--root a24-tool-trigger--active", children: content }) });
|
|
1845
2030
|
}
|
|
1846
2031
|
function AgentChatModelTurnRow({ part }) {
|
|
1847
|
-
return /* @__PURE__ */
|
|
2032
|
+
return /* @__PURE__ */ jsx9(AgentChatActivityRow, { label: "Planning next moves", modelTurnId: part.modelTurnId });
|
|
1848
2033
|
}
|
|
1849
2034
|
function AgentChatNodeActivityRow({
|
|
1850
2035
|
onSelect,
|
|
1851
2036
|
part
|
|
1852
2037
|
}) {
|
|
1853
|
-
const [open, setOpen] =
|
|
1854
|
-
const contentId =
|
|
2038
|
+
const [open, setOpen] = React8.useState(false);
|
|
2039
|
+
const contentId = React8.useId();
|
|
1855
2040
|
const running = part.status === "running";
|
|
1856
2041
|
const failed = part.status === "failed";
|
|
1857
2042
|
const failureMessage = part.failure?.message || "The node could not complete the request.";
|
|
@@ -1862,18 +2047,18 @@ function AgentChatNodeActivityRow({
|
|
|
1862
2047
|
running && "a24-tool-trigger--active",
|
|
1863
2048
|
failed && "a24-tool-trigger--error"
|
|
1864
2049
|
);
|
|
1865
|
-
const label = running ? /* @__PURE__ */
|
|
2050
|
+
const label = running ? /* @__PURE__ */ jsx9("span", { className: "a24-tool-shimmer", children: /* @__PURE__ */ jsx9(ToolActivityReel, { label: part.label }) }) : part.label;
|
|
1866
2051
|
if (!failed) {
|
|
1867
|
-
return /* @__PURE__ */
|
|
1868
|
-
running ? /* @__PURE__ */
|
|
1869
|
-
/* @__PURE__ */
|
|
1870
|
-
] }) : /* @__PURE__ */
|
|
1871
|
-
running ? /* @__PURE__ */
|
|
1872
|
-
/* @__PURE__ */
|
|
2052
|
+
return /* @__PURE__ */ jsx9("div", { className: "a24-tool-trigger-row", role: "status", children: onSelect ? /* @__PURE__ */ jsxs5("button", { className: triggerClassName, onClick: () => onSelect(part), type: "button", children: [
|
|
2053
|
+
running ? /* @__PURE__ */ jsx9(ToolActivityOrb, { label: part.label }) : null,
|
|
2054
|
+
/* @__PURE__ */ jsx9("span", { className: "a24-tool-trigger__label", children: label })
|
|
2055
|
+
] }) : /* @__PURE__ */ jsxs5("div", { className: triggerClassName, children: [
|
|
2056
|
+
running ? /* @__PURE__ */ jsx9(ToolActivityOrb, { label: part.label }) : null,
|
|
2057
|
+
/* @__PURE__ */ jsx9("span", { className: "a24-tool-trigger__label", children: label })
|
|
1873
2058
|
] }) });
|
|
1874
2059
|
}
|
|
1875
|
-
return /* @__PURE__ */
|
|
1876
|
-
/* @__PURE__ */
|
|
2060
|
+
return /* @__PURE__ */ jsxs5("div", { className: "a24-tool-disclosure", children: [
|
|
2061
|
+
/* @__PURE__ */ jsx9("div", { className: "a24-tool-trigger-row", children: /* @__PURE__ */ jsxs5(
|
|
1877
2062
|
"button",
|
|
1878
2063
|
{
|
|
1879
2064
|
"aria-controls": contentId,
|
|
@@ -1885,17 +2070,22 @@ function AgentChatNodeActivityRow({
|
|
|
1885
2070
|
},
|
|
1886
2071
|
type: "button",
|
|
1887
2072
|
children: [
|
|
1888
|
-
/* @__PURE__ */
|
|
1889
|
-
open ? /* @__PURE__ */
|
|
2073
|
+
/* @__PURE__ */ jsx9("span", { className: "a24-tool-trigger__label", children: label }),
|
|
2074
|
+
open ? /* @__PURE__ */ jsx9(ChevronDown2, { "aria-hidden": "true", className: "a24-tool-trigger__chevron" }) : /* @__PURE__ */ jsx9(ChevronRight2, { "aria-hidden": "true", className: "a24-tool-trigger__chevron" })
|
|
1890
2075
|
]
|
|
1891
2076
|
}
|
|
1892
2077
|
) }),
|
|
1893
|
-
open ? /* @__PURE__ */
|
|
2078
|
+
open ? /* @__PURE__ */ jsx9("div", { className: "a24-tool-detail a24-tool-detail--error", id: contentId, children: failureMessage }) : null
|
|
1894
2079
|
] });
|
|
1895
2080
|
}
|
|
1896
|
-
function toolRowLabel(part) {
|
|
2081
|
+
function toolRowLabel(part, separateResource = false) {
|
|
1897
2082
|
const label = agentChatToolLabel(part);
|
|
1898
|
-
|
|
2083
|
+
const lifecycleLabel = isAgentChatToolRunning(part) ? label : label.replace(/^(?:running|ran)\s+/i, "");
|
|
2084
|
+
const targetPath = separateResource ? part.resourceTargets?.[0]?.path : null;
|
|
2085
|
+
if (!targetPath) return lifecycleLabel;
|
|
2086
|
+
const candidates = [targetPath, targetPath.replace(/^\/workspace\/?/, "")].filter(Boolean).sort((left, right) => right.length - left.length);
|
|
2087
|
+
const suffix = candidates.find((candidate) => lifecycleLabel.endsWith(candidate));
|
|
2088
|
+
return suffix ? lifecycleLabel.slice(0, -suffix.length).trimEnd() : lifecycleLabel;
|
|
1899
2089
|
}
|
|
1900
2090
|
function ToolDisclosure({
|
|
1901
2091
|
children,
|
|
@@ -1911,25 +2101,25 @@ function ToolDisclosure({
|
|
|
1911
2101
|
statusLabel,
|
|
1912
2102
|
accessory
|
|
1913
2103
|
}) {
|
|
1914
|
-
const [open, setOpen] =
|
|
1915
|
-
const contentId =
|
|
1916
|
-
const expandable =
|
|
2104
|
+
const [open, setOpen] = React8.useState(false);
|
|
2105
|
+
const contentId = React8.useId();
|
|
2106
|
+
const expandable = React8.Children.toArray(children).length > 0;
|
|
1917
2107
|
if (!expandable) {
|
|
1918
2108
|
const triggerClassName = cn("a24-tool-trigger", root && "a24-tool-trigger--root", root && !showOrb && "a24-tool-trigger--without-orb", error && "a24-tool-trigger--error", loading && "a24-tool-trigger--active");
|
|
1919
|
-
return /* @__PURE__ */
|
|
1920
|
-
onSelect && part ? /* @__PURE__ */
|
|
1921
|
-
showOrb ? /* @__PURE__ */
|
|
1922
|
-
/* @__PURE__ */
|
|
1923
|
-
] }) : /* @__PURE__ */
|
|
1924
|
-
showOrb ? /* @__PURE__ */
|
|
1925
|
-
/* @__PURE__ */
|
|
2109
|
+
return /* @__PURE__ */ jsxs5("div", { className: cn("a24-tool-trigger-row", root && "a24-tool-trigger-row--root"), children: [
|
|
2110
|
+
onSelect && part ? /* @__PURE__ */ jsxs5("button", { className: triggerClassName, onClick: () => onSelect(part), type: "button", children: [
|
|
2111
|
+
showOrb ? /* @__PURE__ */ jsx9(ToolActivityOrb, { label: statusLabel }) : null,
|
|
2112
|
+
/* @__PURE__ */ jsx9("span", { className: "a24-tool-trigger__label", children: label })
|
|
2113
|
+
] }) : /* @__PURE__ */ jsxs5("div", { className: triggerClassName, children: [
|
|
2114
|
+
showOrb ? /* @__PURE__ */ jsx9(ToolActivityOrb, { label: statusLabel }) : null,
|
|
2115
|
+
/* @__PURE__ */ jsx9("span", { className: "a24-tool-trigger__label", children: label })
|
|
1926
2116
|
] }),
|
|
1927
2117
|
accessory
|
|
1928
2118
|
] });
|
|
1929
2119
|
}
|
|
1930
|
-
return /* @__PURE__ */
|
|
1931
|
-
/* @__PURE__ */
|
|
1932
|
-
/* @__PURE__ */
|
|
2120
|
+
return /* @__PURE__ */ jsxs5("div", { className: "a24-tool-disclosure", children: [
|
|
2121
|
+
/* @__PURE__ */ jsxs5("div", { className: cn("a24-tool-trigger-row", root && "a24-tool-trigger-row--root"), children: [
|
|
2122
|
+
/* @__PURE__ */ jsxs5(
|
|
1933
2123
|
"button",
|
|
1934
2124
|
{
|
|
1935
2125
|
"aria-controls": contentId,
|
|
@@ -1943,25 +2133,25 @@ function ToolDisclosure({
|
|
|
1943
2133
|
},
|
|
1944
2134
|
type: "button",
|
|
1945
2135
|
children: [
|
|
1946
|
-
showOrb ? /* @__PURE__ */
|
|
1947
|
-
/* @__PURE__ */
|
|
1948
|
-
open ? /* @__PURE__ */
|
|
2136
|
+
showOrb ? /* @__PURE__ */ jsx9(ToolActivityOrb, { label: statusLabel }) : null,
|
|
2137
|
+
/* @__PURE__ */ jsx9("span", { className: "a24-tool-trigger__label", children: label }),
|
|
2138
|
+
open ? /* @__PURE__ */ jsx9(ChevronDown2, { "aria-hidden": "true", className: "a24-tool-trigger__chevron" }) : /* @__PURE__ */ jsx9(ChevronRight2, { "aria-hidden": "true", className: "a24-tool-trigger__chevron" })
|
|
1949
2139
|
]
|
|
1950
2140
|
}
|
|
1951
2141
|
),
|
|
1952
2142
|
accessory
|
|
1953
2143
|
] }),
|
|
1954
|
-
open ? /* @__PURE__ */
|
|
2144
|
+
open ? /* @__PURE__ */ jsx9("div", { className: "a24-tool-disclosure__content", id: contentId, children }) : null
|
|
1955
2145
|
] });
|
|
1956
2146
|
}
|
|
1957
2147
|
function ToolLabel({ active, label, part, slots }) {
|
|
1958
|
-
const rendered = slots?.renderToolLabel?.(
|
|
1959
|
-
return active ? /* @__PURE__ */
|
|
2148
|
+
const rendered = slots?.renderToolLabel?.(toolSlotContext(active, label, part, slots)) ?? label;
|
|
2149
|
+
return active ? /* @__PURE__ */ jsx9("span", { className: "a24-tool-shimmer", children: rendered }) : /* @__PURE__ */ jsx9(Fragment3, { children: rendered });
|
|
1960
2150
|
}
|
|
1961
2151
|
function ToolList({ children }) {
|
|
1962
|
-
const listRef =
|
|
1963
|
-
const [fades, setFades] =
|
|
1964
|
-
const updateFades =
|
|
2152
|
+
const listRef = React8.useRef(null);
|
|
2153
|
+
const [fades, setFades] = React8.useState({ bottom: false, top: false });
|
|
2154
|
+
const updateFades = React8.useCallback(() => {
|
|
1965
2155
|
const list = listRef.current;
|
|
1966
2156
|
if (!list) return;
|
|
1967
2157
|
const next = {
|
|
@@ -1970,7 +2160,7 @@ function ToolList({ children }) {
|
|
|
1970
2160
|
};
|
|
1971
2161
|
setFades((current) => current.bottom === next.bottom && current.top === next.top ? current : next);
|
|
1972
2162
|
}, []);
|
|
1973
|
-
|
|
2163
|
+
React8.useEffect(() => {
|
|
1974
2164
|
updateFades();
|
|
1975
2165
|
const list = listRef.current;
|
|
1976
2166
|
if (!list || typeof ResizeObserver === "undefined") return;
|
|
@@ -1978,13 +2168,13 @@ function ToolList({ children }) {
|
|
|
1978
2168
|
observer.observe(list);
|
|
1979
2169
|
return () => observer.disconnect();
|
|
1980
2170
|
}, [children, updateFades]);
|
|
1981
|
-
return /* @__PURE__ */
|
|
2171
|
+
return /* @__PURE__ */ jsx9(
|
|
1982
2172
|
"div",
|
|
1983
2173
|
{
|
|
1984
2174
|
className: "a24-tool-list-frame",
|
|
1985
2175
|
"data-scroll-fade-bottom": fades.bottom ? "" : void 0,
|
|
1986
2176
|
"data-scroll-fade-top": fades.top ? "" : void 0,
|
|
1987
|
-
children: /* @__PURE__ */
|
|
2177
|
+
children: /* @__PURE__ */ jsx9("div", { className: "a24-tool-list", onScroll: updateFades, ref: listRef, role: "list", children })
|
|
1988
2178
|
}
|
|
1989
2179
|
);
|
|
1990
2180
|
}
|
|
@@ -2000,13 +2190,13 @@ function AgentChatToolRow({
|
|
|
2000
2190
|
const failureMessage = part.failure?.message || null;
|
|
2001
2191
|
const detail = failed ? failureMessage : optionalText(part.presentation.detail);
|
|
2002
2192
|
const hostDetails = failed ? null : slots?.renderToolDetails?.(part);
|
|
2003
|
-
const context =
|
|
2004
|
-
return /* @__PURE__ */
|
|
2193
|
+
const context = toolSlotContext(active, toolRowLabel(part, Boolean(slots?.onResourceAction)), part, slots);
|
|
2194
|
+
return /* @__PURE__ */ jsx9("div", { "data-agents24-tool-part": part.type, "data-state": part.state, children: /* @__PURE__ */ jsxs5(
|
|
2005
2195
|
ToolDisclosure,
|
|
2006
2196
|
{
|
|
2007
2197
|
error: failed,
|
|
2008
|
-
accessory:
|
|
2009
|
-
label: /* @__PURE__ */
|
|
2198
|
+
accessory: toolAccessory(context, slots),
|
|
2199
|
+
label: /* @__PURE__ */ jsx9(ToolLabel, { active, label: context.label, part, slots }),
|
|
2010
2200
|
loading: active,
|
|
2011
2201
|
onExpandedChange: slots?.onExpandedChange,
|
|
2012
2202
|
onSelect: slots?.onToolSelect,
|
|
@@ -2015,14 +2205,14 @@ function AgentChatToolRow({
|
|
|
2015
2205
|
showOrb: showOrb ?? active,
|
|
2016
2206
|
statusLabel: active ? context.label : void 0,
|
|
2017
2207
|
children: [
|
|
2018
|
-
detail ? /* @__PURE__ */
|
|
2208
|
+
detail ? /* @__PURE__ */ jsx9("div", { className: cn("a24-tool-detail", failed && "a24-tool-detail--error"), children: detail }) : null,
|
|
2019
2209
|
hostDetails
|
|
2020
2210
|
]
|
|
2021
2211
|
}
|
|
2022
2212
|
) });
|
|
2023
2213
|
}
|
|
2024
2214
|
function sessionLabel(parts, visiblePart, running) {
|
|
2025
|
-
const label =
|
|
2215
|
+
const label = toolRowLabel(visiblePart, true);
|
|
2026
2216
|
const terminalLabel = label.replace(/^(?:running|ran)\s+/i, "");
|
|
2027
2217
|
return running ? label : `Ran ${terminalLabel} + ${parts.length - 1} more`;
|
|
2028
2218
|
}
|
|
@@ -2035,23 +2225,21 @@ function AgentChatToolSession({
|
|
|
2035
2225
|
parts,
|
|
2036
2226
|
slots
|
|
2037
2227
|
}) {
|
|
2038
|
-
const presentedLiveRef =
|
|
2228
|
+
const presentedLiveRef = React8.useRef(false);
|
|
2039
2229
|
if (isLive && isLatestActivity) presentedLiveRef.current = true;
|
|
2040
2230
|
const activeIndex = parts.findLastIndex((part) => isActive(part, activeToolId));
|
|
2041
2231
|
const running = activeIndex >= 0;
|
|
2042
|
-
if (parts.length === 1 && !modelTurn && !leadingModelTurn) return /* @__PURE__ */
|
|
2232
|
+
if (parts.length === 1 && !modelTurn && !leadingModelTurn) return /* @__PURE__ */ jsx9(AgentChatToolRow, { activeToolId, part: parts[0], slots });
|
|
2043
2233
|
const visibleIndex = running ? activeIndex : parts.length - 1;
|
|
2044
2234
|
const visiblePart = parts[visibleIndex];
|
|
2045
2235
|
const planning = Boolean(modelTurn);
|
|
2046
2236
|
const presentingActivity = isLatestActivity && (planning || running || isLive);
|
|
2047
2237
|
const failed = isLatestActivity && (visiblePart.state === "output-error" || visiblePart.state === "cancelled");
|
|
2048
|
-
const label = planning ? "Planning next moves" : isLive && isLatestActivity ?
|
|
2049
|
-
const labelContent = presentedLiveRef.current ? /* @__PURE__ */
|
|
2050
|
-
|
|
2051
|
-
return /* @__PURE__ */ jsx8(
|
|
2238
|
+
const label = planning ? "Planning next moves" : isLive && isLatestActivity ? toolRowLabel(visiblePart, true) : sessionLabel(parts, visiblePart, running);
|
|
2239
|
+
const labelContent = presentedLiveRef.current ? /* @__PURE__ */ jsx9("span", { className: presentingActivity ? "a24-tool-shimmer" : void 0, children: /* @__PURE__ */ jsx9(ToolActivityReel, { initialLabel: leadingModelTurn ? "Planning next moves" : void 0, initialShownAt: leadingModelTurn?.timestamp, label }) }) : label;
|
|
2240
|
+
return /* @__PURE__ */ jsx9(
|
|
2052
2241
|
ToolDisclosure,
|
|
2053
2242
|
{
|
|
2054
|
-
accessory: slots?.renderToolAccessory?.(context),
|
|
2055
2243
|
error: failed,
|
|
2056
2244
|
grouped: true,
|
|
2057
2245
|
label: labelContent,
|
|
@@ -2061,7 +2249,7 @@ function AgentChatToolSession({
|
|
|
2061
2249
|
root: true,
|
|
2062
2250
|
showOrb: isLive && isLatestActivity,
|
|
2063
2251
|
statusLabel: planning ? "Planning next moves" : label,
|
|
2064
|
-
children: /* @__PURE__ */
|
|
2252
|
+
children: /* @__PURE__ */ jsx9(ToolList, { children: parts.map((part) => /* @__PURE__ */ jsx9("div", { role: "listitem", children: /* @__PURE__ */ jsx9(AgentChatToolRow, { activeToolId, part, root: false, showOrb: false, slots }) }, part.id)) })
|
|
2065
2253
|
}
|
|
2066
2254
|
);
|
|
2067
2255
|
}
|
|
@@ -2082,7 +2270,7 @@ function subagentLabel(part) {
|
|
|
2082
2270
|
return { label: `Agent ${name}, ran ${children.length} ${children.length === 1 ? "tool" : "tools"}`, running: false };
|
|
2083
2271
|
}
|
|
2084
2272
|
function AgentChatSubagentGroup({ isLatestActivity = true, isLive = false, part, slots }) {
|
|
2085
|
-
const presentedLiveRef =
|
|
2273
|
+
const presentedLiveRef = React8.useRef(false);
|
|
2086
2274
|
if (isLive && isLatestActivity) presentedLiveRef.current = true;
|
|
2087
2275
|
const children = part.presentation.childTools || [];
|
|
2088
2276
|
const state = subagentLabel(part);
|
|
@@ -2091,9 +2279,9 @@ function AgentChatSubagentGroup({ isLatestActivity = true, isLive = false, part,
|
|
|
2091
2279
|
const hostDetails = failed ? null : slots?.renderToolDetails?.(part);
|
|
2092
2280
|
const failureMessage = part.failure?.message || null;
|
|
2093
2281
|
const presentingActivity = isLatestActivity && state.running;
|
|
2094
|
-
const labelContent = presentedLiveRef.current ? /* @__PURE__ */
|
|
2095
|
-
const context =
|
|
2096
|
-
return /* @__PURE__ */
|
|
2282
|
+
const labelContent = presentedLiveRef.current ? /* @__PURE__ */ jsx9("span", { className: presentingActivity ? "a24-tool-shimmer" : void 0, children: /* @__PURE__ */ jsx9(ToolActivityReel, { label: state.label }) }) : state.label;
|
|
2283
|
+
const context = toolSlotContext(presentingActivity, state.label, part, slots);
|
|
2284
|
+
return /* @__PURE__ */ jsx9(
|
|
2097
2285
|
ToolDisclosure,
|
|
2098
2286
|
{
|
|
2099
2287
|
accessory: slots?.renderToolAccessory?.(context),
|
|
@@ -2106,12 +2294,12 @@ function AgentChatSubagentGroup({ isLatestActivity = true, isLive = false, part,
|
|
|
2106
2294
|
root: true,
|
|
2107
2295
|
showOrb: isLive && isLatestActivity,
|
|
2108
2296
|
statusLabel: state.label,
|
|
2109
|
-
children: /* @__PURE__ */
|
|
2110
|
-
children.map((child) => /* @__PURE__ */
|
|
2111
|
-
/* @__PURE__ */
|
|
2112
|
-
child.detail ? /* @__PURE__ */
|
|
2297
|
+
children: /* @__PURE__ */ jsxs5(ToolList, { children: [
|
|
2298
|
+
children.map((child) => /* @__PURE__ */ jsx9("div", { className: cn("a24-child-tool", child.status === "failed" && "a24-child-tool--error"), role: "listitem", children: slots?.renderChildTool?.(child, part) ?? /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
2299
|
+
/* @__PURE__ */ jsx9("span", { className: cn(isLive && isLatestActivity && child.status === "running" && "a24-tool-shimmer"), children: childLabel(child) }),
|
|
2300
|
+
child.detail ? /* @__PURE__ */ jsx9("span", { className: "a24-child-tool__detail", children: child.detail }) : null
|
|
2113
2301
|
] }) }, child.id)),
|
|
2114
|
-
failureMessage ? /* @__PURE__ */
|
|
2302
|
+
failureMessage ? /* @__PURE__ */ jsx9("div", { className: "a24-tool-detail a24-tool-detail--error", children: failureMessage }) : null,
|
|
2115
2303
|
hostDetails
|
|
2116
2304
|
] })
|
|
2117
2305
|
}
|
|
@@ -2119,24 +2307,24 @@ function AgentChatSubagentGroup({ isLatestActivity = true, isLive = false, part,
|
|
|
2119
2307
|
}
|
|
2120
2308
|
|
|
2121
2309
|
// src/ui/agent-response-timeline.tsx
|
|
2122
|
-
import { jsx as
|
|
2310
|
+
import { jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
2123
2311
|
function isInternalAskUserTool(part) {
|
|
2124
2312
|
return [part.toolName, part.toolKey, part.action].some((value) => value?.trim().toLowerCase() === "runtime__ask_user");
|
|
2125
2313
|
}
|
|
2126
2314
|
function Shimmer({ children, className }) {
|
|
2127
|
-
return /* @__PURE__ */
|
|
2315
|
+
return /* @__PURE__ */ jsx10("span", { className: cn("inline-block animate-pulse", className), children });
|
|
2128
2316
|
}
|
|
2129
2317
|
function AgentChatToolPart({
|
|
2130
2318
|
activeToolId,
|
|
2131
2319
|
part
|
|
2132
2320
|
}) {
|
|
2133
|
-
return /* @__PURE__ */
|
|
2321
|
+
return /* @__PURE__ */ jsx10(AgentChatToolRow, { activeToolId, part });
|
|
2134
2322
|
}
|
|
2135
2323
|
function AgentChatToolGroup({
|
|
2136
2324
|
activeToolId,
|
|
2137
2325
|
parts
|
|
2138
2326
|
}) {
|
|
2139
|
-
return /* @__PURE__ */
|
|
2327
|
+
return /* @__PURE__ */ jsx10(AgentChatToolSession, { activeToolId, parts });
|
|
2140
2328
|
}
|
|
2141
2329
|
function HitlPartRow({
|
|
2142
2330
|
getHitlActionState,
|
|
@@ -2145,18 +2333,18 @@ function HitlPartRow({
|
|
|
2145
2333
|
part
|
|
2146
2334
|
}) {
|
|
2147
2335
|
const state = getHitlActionState?.(part);
|
|
2148
|
-
const [comment, setComment] =
|
|
2336
|
+
const [comment, setComment] = React9.useState("");
|
|
2149
2337
|
const presentation = part.presentation || {};
|
|
2150
2338
|
const requireComment = presentation.require_comment === true;
|
|
2151
2339
|
const isTerminal = part.status !== "pending";
|
|
2152
|
-
const resolvedRef =
|
|
2153
|
-
const wasTerminal =
|
|
2154
|
-
|
|
2340
|
+
const resolvedRef = React9.useRef(null);
|
|
2341
|
+
const wasTerminal = React9.useRef(isTerminal);
|
|
2342
|
+
React9.useEffect(() => {
|
|
2155
2343
|
if (isTerminal && !wasTerminal.current) resolvedRef.current?.focus();
|
|
2156
2344
|
wasTerminal.current = isTerminal;
|
|
2157
2345
|
}, [isTerminal]);
|
|
2158
2346
|
if (part.hitlKind === "user_input") {
|
|
2159
|
-
return /* @__PURE__ */
|
|
2347
|
+
return /* @__PURE__ */ jsx10(
|
|
2160
2348
|
AskUserInteraction,
|
|
2161
2349
|
{
|
|
2162
2350
|
error: state?.error,
|
|
@@ -2174,11 +2362,11 @@ function HitlPartRow({
|
|
|
2174
2362
|
);
|
|
2175
2363
|
}
|
|
2176
2364
|
if (isTerminal) {
|
|
2177
|
-
return /* @__PURE__ */
|
|
2365
|
+
return /* @__PURE__ */ jsx10("div", { className: "a24-hitl a24-hitl--resolved px-1 py-1 text-sm text-muted-foreground", ref: resolvedRef, role: "status", tabIndex: -1, children: resolvedHitlLabel(part) });
|
|
2178
2366
|
}
|
|
2179
|
-
return /* @__PURE__ */
|
|
2180
|
-
/* @__PURE__ */
|
|
2181
|
-
requireComment ? /* @__PURE__ */
|
|
2367
|
+
return /* @__PURE__ */ jsxs6("div", { className: "a24-hitl space-y-2.5 px-1 py-2", children: [
|
|
2368
|
+
/* @__PURE__ */ jsx10("div", { className: "a24-hitl__title text-sm font-medium text-foreground text-pretty", children: hitlTitle(part) }),
|
|
2369
|
+
requireComment ? /* @__PURE__ */ jsx10(
|
|
2182
2370
|
"textarea",
|
|
2183
2371
|
{
|
|
2184
2372
|
"aria-label": "Approval comment",
|
|
@@ -2190,8 +2378,8 @@ function HitlPartRow({
|
|
|
2190
2378
|
value: comment
|
|
2191
2379
|
}
|
|
2192
2380
|
) : null,
|
|
2193
|
-
state?.error ? /* @__PURE__ */
|
|
2194
|
-
/* @__PURE__ */
|
|
2381
|
+
state?.error ? /* @__PURE__ */ jsx10("div", { className: "a24-hitl__error text-sm text-destructive", children: state.error }) : null,
|
|
2382
|
+
/* @__PURE__ */ jsx10("div", { className: "a24-hitl__actions flex flex-wrap items-center gap-1.5", children: part.allowedActions.map((action) => /* @__PURE__ */ jsx10(
|
|
2195
2383
|
"button",
|
|
2196
2384
|
{
|
|
2197
2385
|
"aria-label": hitlActionLabel(part, action),
|
|
@@ -2224,7 +2412,7 @@ function AgentChatPart({
|
|
|
2224
2412
|
toolSlots
|
|
2225
2413
|
}) {
|
|
2226
2414
|
if (part.kind === "text") {
|
|
2227
|
-
return /* @__PURE__ */
|
|
2415
|
+
return /* @__PURE__ */ jsx10(
|
|
2228
2416
|
MessageResponse,
|
|
2229
2417
|
{
|
|
2230
2418
|
...responseProps,
|
|
@@ -2234,23 +2422,23 @@ function AgentChatPart({
|
|
|
2234
2422
|
}
|
|
2235
2423
|
);
|
|
2236
2424
|
}
|
|
2237
|
-
if (part.kind === "tool") return isAgentChatSubagent(part) ? /* @__PURE__ */
|
|
2238
|
-
if (part.kind === "model-turn") return /* @__PURE__ */
|
|
2425
|
+
if (part.kind === "tool") return isAgentChatSubagent(part) ? /* @__PURE__ */ jsx10(AgentChatSubagentGroup, { part, slots: toolSlots }) : /* @__PURE__ */ jsx10(AgentChatToolRow, { activeToolId, part, slots: toolSlots });
|
|
2426
|
+
if (part.kind === "model-turn") return /* @__PURE__ */ jsx10(AgentChatModelTurnRow, { part });
|
|
2239
2427
|
if (part.kind === "reasoning") {
|
|
2240
2428
|
const label = part.text || part.label || "Thinking";
|
|
2241
|
-
return part.status === "running" || part.status === "streaming" ? /* @__PURE__ */
|
|
2429
|
+
return part.status === "running" || part.status === "streaming" ? /* @__PURE__ */ jsx10(Shimmer, { className: "text-sm text-muted-foreground", children: label }) : /* @__PURE__ */ jsx10("div", { className: "text-sm text-muted-foreground", children: label });
|
|
2242
2430
|
}
|
|
2243
2431
|
if (part.kind === "context-compression") {
|
|
2244
|
-
return /* @__PURE__ */
|
|
2432
|
+
return /* @__PURE__ */ jsx10(AgentChatContextCompressionRow, { part });
|
|
2245
2433
|
}
|
|
2246
2434
|
if (part.kind === "ui-blocks") {
|
|
2247
2435
|
if (part.state === "output-error") {
|
|
2248
|
-
return /* @__PURE__ */
|
|
2436
|
+
return /* @__PURE__ */ jsx10("div", { className: "a24-timeline-error text-sm text-destructive", children: part.errorText || "Failed to render UI content." });
|
|
2249
2437
|
}
|
|
2250
|
-
return part.bundle ? /* @__PURE__ */
|
|
2438
|
+
return part.bundle ? /* @__PURE__ */ jsx10(SafeUiBlocks, { bundle: part.bundle }) : /* @__PURE__ */ jsx10("div", { className: "text-sm text-muted-foreground", children: part.state === "input-streaming" ? /* @__PURE__ */ jsx10(Shimmer, { children: "Rendering UI block" }) : "Rendered UI block" });
|
|
2251
2439
|
}
|
|
2252
2440
|
if (part.kind === "hitl") {
|
|
2253
|
-
return /* @__PURE__ */
|
|
2441
|
+
return /* @__PURE__ */ jsx10(
|
|
2254
2442
|
HitlPartRow,
|
|
2255
2443
|
{
|
|
2256
2444
|
getHitlActionState,
|
|
@@ -2260,18 +2448,18 @@ function AgentChatPart({
|
|
|
2260
2448
|
}
|
|
2261
2449
|
);
|
|
2262
2450
|
}
|
|
2263
|
-
if (part.kind === "error") return /* @__PURE__ */
|
|
2451
|
+
if (part.kind === "error") return /* @__PURE__ */ jsx10("div", { className: "a24-timeline-error text-sm text-destructive", role: "alert", children: part.errorText });
|
|
2264
2452
|
if (part.kind === "source") {
|
|
2265
2453
|
const href = safeExternalUrl(part.url);
|
|
2266
|
-
return href ? /* @__PURE__ */
|
|
2454
|
+
return href ? /* @__PURE__ */ jsx10("a", { className: "a24-source-link", href, rel: "noopener noreferrer", target: "_blank", children: part.title }) : /* @__PURE__ */ jsx10("span", { className: "a24-source-link", children: part.title });
|
|
2267
2455
|
}
|
|
2268
2456
|
if (part.kind === "citation") {
|
|
2269
2457
|
const href = safeExternalUrl(part.url);
|
|
2270
2458
|
const label = part.label || "Citation";
|
|
2271
|
-
return href ? /* @__PURE__ */
|
|
2459
|
+
return href ? /* @__PURE__ */ jsx10("a", { className: "a24-citation", href, rel: "noopener noreferrer", target: "_blank", children: label }) : /* @__PURE__ */ jsx10("span", { className: "a24-citation", children: label });
|
|
2272
2460
|
}
|
|
2273
|
-
if (part.kind === "attachment") return /* @__PURE__ */
|
|
2274
|
-
if (part.kind === "data") return /* @__PURE__ */
|
|
2461
|
+
if (part.kind === "attachment") return /* @__PURE__ */ jsx10("div", { className: "a24-output-attachment", children: part.attachment.filename || "Attachment" });
|
|
2462
|
+
if (part.kind === "data") return /* @__PURE__ */ jsx10("div", { "data-agents24-data-part": part.name, className: "hidden", children: message.id });
|
|
2275
2463
|
return null;
|
|
2276
2464
|
}
|
|
2277
2465
|
function safeExternalUrl(value) {
|
|
@@ -2285,28 +2473,28 @@ function safeExternalUrl(value) {
|
|
|
2285
2473
|
}
|
|
2286
2474
|
function SafeUiBlocks({ bundle }) {
|
|
2287
2475
|
const rows = Array.isArray(bundle.rows) ? bundle.rows : [];
|
|
2288
|
-
return /* @__PURE__ */
|
|
2289
|
-
typeof bundle.title === "string" ? /* @__PURE__ */
|
|
2476
|
+
return /* @__PURE__ */ jsxs6("section", { "aria-label": typeof bundle.title === "string" ? bundle.title : "Agent result", className: "a24-ui-blocks", children: [
|
|
2477
|
+
typeof bundle.title === "string" ? /* @__PURE__ */ jsx10("h3", { children: bundle.title }) : null,
|
|
2290
2478
|
rows.map((rawRow, rowIndex) => {
|
|
2291
2479
|
const row = rawRow && typeof rawRow === "object" && !Array.isArray(rawRow) ? rawRow : {};
|
|
2292
2480
|
const blocks = Array.isArray(row.blocks) ? row.blocks : [];
|
|
2293
|
-
return /* @__PURE__ */
|
|
2481
|
+
return /* @__PURE__ */ jsx10("div", { className: "a24-ui-blocks__row", children: blocks.map((rawBlock, blockIndex) => {
|
|
2294
2482
|
const block = rawBlock && typeof rawBlock === "object" && !Array.isArray(rawBlock) ? rawBlock : {};
|
|
2295
2483
|
const title = typeof block.title === "string" ? block.title : "Result";
|
|
2296
2484
|
const kind = String(block.kind || "note");
|
|
2297
2485
|
if (kind === "table" && Array.isArray(block.columns) && Array.isArray(block.rows)) {
|
|
2298
|
-
return /* @__PURE__ */
|
|
2299
|
-
/* @__PURE__ */
|
|
2300
|
-
/* @__PURE__ */
|
|
2301
|
-
/* @__PURE__ */
|
|
2302
|
-
/* @__PURE__ */
|
|
2486
|
+
return /* @__PURE__ */ jsxs6("div", { className: "a24-ui-block", children: [
|
|
2487
|
+
/* @__PURE__ */ jsx10("h4", { children: title }),
|
|
2488
|
+
/* @__PURE__ */ jsx10("div", { className: "a24-ui-table-scroll", children: /* @__PURE__ */ jsxs6("table", { children: [
|
|
2489
|
+
/* @__PURE__ */ jsx10("thead", { children: /* @__PURE__ */ jsx10("tr", { children: block.columns.map((column, index) => /* @__PURE__ */ jsx10("th", { children: String(column) }, index)) }) }),
|
|
2490
|
+
/* @__PURE__ */ jsx10("tbody", { children: block.rows.map((rawCells, index) => /* @__PURE__ */ jsx10("tr", { children: (Array.isArray(rawCells) ? rawCells : []).map((cell, cellIndex) => /* @__PURE__ */ jsx10("td", { children: String(cell) }, cellIndex)) }, index)) })
|
|
2303
2491
|
] }) })
|
|
2304
2492
|
] }, String(block.id || blockIndex));
|
|
2305
2493
|
}
|
|
2306
2494
|
const value = block.value ?? block.text ?? "";
|
|
2307
|
-
return /* @__PURE__ */
|
|
2308
|
-
/* @__PURE__ */
|
|
2309
|
-
/* @__PURE__ */
|
|
2495
|
+
return /* @__PURE__ */ jsxs6("div", { className: "a24-ui-block", children: [
|
|
2496
|
+
/* @__PURE__ */ jsx10("h4", { children: title }),
|
|
2497
|
+
/* @__PURE__ */ jsx10("p", { children: String(value) })
|
|
2310
2498
|
] }, String(block.id || blockIndex));
|
|
2311
2499
|
}) }, `row-${rowIndex}`);
|
|
2312
2500
|
})
|
|
@@ -2337,34 +2525,34 @@ function AgentResponseTimeline({
|
|
|
2337
2525
|
if (segment.kind === "tool") {
|
|
2338
2526
|
const isLatestActivity = segmentIndex === segments.length - 1;
|
|
2339
2527
|
const showOrb = toolViewMode === "closed" ? isLoading && isLatestActivity : Boolean(activeToolId && (segment.part.id === activeToolId || segment.part.toolCallId === activeToolId));
|
|
2340
|
-
rendered.push(/* @__PURE__ */
|
|
2528
|
+
rendered.push(/* @__PURE__ */ jsx10(AgentChatToolRow, { activeToolId, part: segment.part, showOrb, slots: toolSlots }, segment.part.id));
|
|
2341
2529
|
continue;
|
|
2342
2530
|
}
|
|
2343
2531
|
if (segment.kind === "tool-session") {
|
|
2344
|
-
rendered.push(/* @__PURE__ */
|
|
2532
|
+
rendered.push(/* @__PURE__ */ jsx10(AgentChatToolSession, { activeToolId, isLatestActivity: segmentIndex === segments.length - 1, isLive: isLoading, leadingModelTurn: segment.leadingModelTurn, modelTurn: segment.modelTurn, parts: segment.parts, slots: toolSlots }, `tool-session-${segment.parts[0].id}`));
|
|
2345
2533
|
continue;
|
|
2346
2534
|
}
|
|
2347
2535
|
if (segment.kind === "subagent") {
|
|
2348
|
-
rendered.push(/* @__PURE__ */
|
|
2536
|
+
rendered.push(/* @__PURE__ */ jsx10(AgentChatSubagentGroup, { isLatestActivity: segmentIndex === segments.length - 1, isLive: isLoading, part: segment.part, slots: toolSlots }, segment.part.id));
|
|
2349
2537
|
continue;
|
|
2350
2538
|
}
|
|
2351
2539
|
const part = segment.part;
|
|
2352
2540
|
if (part.kind === "model-turn") {
|
|
2353
2541
|
const key = activeActivityClaimed ? part.id : `${message.id}-active-activity`;
|
|
2354
2542
|
activeActivityClaimed = true;
|
|
2355
|
-
rendered.push(/* @__PURE__ */
|
|
2543
|
+
rendered.push(/* @__PURE__ */ jsx10(AgentChatActivityRow, { label: "Planning next moves", modelTurnId: part.modelTurnId }, key));
|
|
2356
2544
|
continue;
|
|
2357
2545
|
}
|
|
2358
2546
|
if (part.kind === "node-activity") {
|
|
2359
2547
|
const key = activeActivityClaimed ? part.id : `${message.id}-active-activity`;
|
|
2360
2548
|
if (part.status === "running") activeActivityClaimed = true;
|
|
2361
2549
|
rendered.push(
|
|
2362
|
-
part.status === "running" ? /* @__PURE__ */
|
|
2550
|
+
part.status === "running" ? /* @__PURE__ */ jsx10(AgentChatActivityRow, { label: part.label }, key) : /* @__PURE__ */ jsx10(AgentChatNodeActivityRow, { part }, part.id)
|
|
2363
2551
|
);
|
|
2364
2552
|
continue;
|
|
2365
2553
|
}
|
|
2366
2554
|
rendered.push(
|
|
2367
|
-
/* @__PURE__ */
|
|
2555
|
+
/* @__PURE__ */ jsx10(React9.Fragment, { children: /* @__PURE__ */ jsx10(
|
|
2368
2556
|
AgentChatPart,
|
|
2369
2557
|
{
|
|
2370
2558
|
activeToolId,
|
|
@@ -2381,16 +2569,16 @@ function AgentResponseTimeline({
|
|
|
2381
2569
|
);
|
|
2382
2570
|
}
|
|
2383
2571
|
if (rendered.length === 0 && message.content) {
|
|
2384
|
-
rendered.push(/* @__PURE__ */
|
|
2572
|
+
rendered.push(/* @__PURE__ */ jsx10(MessageResponse, { children: message.content }, `${message.id}-fallback`));
|
|
2385
2573
|
}
|
|
2386
2574
|
if (rendered.length === 0 && isLoading) {
|
|
2387
|
-
rendered.push(/* @__PURE__ */
|
|
2575
|
+
rendered.push(/* @__PURE__ */ jsx10(AgentChatActivityRow, { label: "Thinking" }, `${message.id}-active-activity`));
|
|
2388
2576
|
}
|
|
2389
|
-
return /* @__PURE__ */
|
|
2577
|
+
return /* @__PURE__ */ jsx10("div", { className: "space-y-3", children: rendered });
|
|
2390
2578
|
}
|
|
2391
2579
|
|
|
2392
2580
|
// src/ui/agent-chat-message.tsx
|
|
2393
|
-
import { jsx as
|
|
2581
|
+
import { jsx as jsx11, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
2394
2582
|
var DEFAULT_USER_MESSAGE_COLLAPSE_THRESHOLD = 360;
|
|
2395
2583
|
var DEFAULT_USER_MESSAGE_COLLAPSED_LINES = 4;
|
|
2396
2584
|
function shouldCollapseUserMessage(content, threshold = DEFAULT_USER_MESSAGE_COLLAPSE_THRESHOLD) {
|
|
@@ -2403,8 +2591,8 @@ function AgentChatUserMessageContent({
|
|
|
2403
2591
|
showLessLabel = "Show less",
|
|
2404
2592
|
showMoreLabel = "Show more"
|
|
2405
2593
|
}) {
|
|
2406
|
-
const [isExpanded, setIsExpanded] =
|
|
2407
|
-
const contentId =
|
|
2594
|
+
const [isExpanded, setIsExpanded] = React10.useState(false);
|
|
2595
|
+
const contentId = React10.useId();
|
|
2408
2596
|
const shouldCollapse = shouldCollapseUserMessage(content, collapseThreshold);
|
|
2409
2597
|
const Icon = isExpanded ? ChevronUp : ChevronDown3;
|
|
2410
2598
|
const clampedStyle = shouldCollapse && !isExpanded ? {
|
|
@@ -2413,9 +2601,9 @@ function AgentChatUserMessageContent({
|
|
|
2413
2601
|
display: "-webkit-box",
|
|
2414
2602
|
overflow: "hidden"
|
|
2415
2603
|
} : void 0;
|
|
2416
|
-
return /* @__PURE__ */
|
|
2417
|
-
/* @__PURE__ */
|
|
2418
|
-
shouldCollapse ? /* @__PURE__ */
|
|
2604
|
+
return /* @__PURE__ */ jsxs7("div", { className: "flex min-w-0 flex-col gap-3", children: [
|
|
2605
|
+
/* @__PURE__ */ jsx11("div", { id: contentId, className: "min-w-0", style: clampedStyle, children: content }),
|
|
2606
|
+
shouldCollapse ? /* @__PURE__ */ jsxs7(
|
|
2419
2607
|
"button",
|
|
2420
2608
|
{
|
|
2421
2609
|
"aria-controls": contentId,
|
|
@@ -2428,7 +2616,7 @@ function AgentChatUserMessageContent({
|
|
|
2428
2616
|
type: "button",
|
|
2429
2617
|
children: [
|
|
2430
2618
|
isExpanded ? showLessLabel : showMoreLabel,
|
|
2431
|
-
/* @__PURE__ */
|
|
2619
|
+
/* @__PURE__ */ jsx11(Icon, { "aria-hidden": "true", className: "size-4", strokeWidth: 2 })
|
|
2432
2620
|
]
|
|
2433
2621
|
}
|
|
2434
2622
|
) : null
|
|
@@ -2438,9 +2626,9 @@ function AgentChatUserMessageActionRow({
|
|
|
2438
2626
|
children,
|
|
2439
2627
|
className
|
|
2440
2628
|
}) {
|
|
2441
|
-
const rowRef =
|
|
2442
|
-
const [visible, setVisible] =
|
|
2443
|
-
|
|
2629
|
+
const rowRef = React10.useRef(null);
|
|
2630
|
+
const [visible, setVisible] = React10.useState(false);
|
|
2631
|
+
React10.useEffect(() => {
|
|
2444
2632
|
const message = rowRef.current?.closest('[data-slot="message"]');
|
|
2445
2633
|
if (!message) return;
|
|
2446
2634
|
const show = () => setVisible(true);
|
|
@@ -2459,7 +2647,7 @@ function AgentChatUserMessageActionRow({
|
|
|
2459
2647
|
message.removeEventListener("focusout", hideWhenFocusLeaves);
|
|
2460
2648
|
};
|
|
2461
2649
|
}, []);
|
|
2462
|
-
return /* @__PURE__ */
|
|
2650
|
+
return /* @__PURE__ */ jsx11(
|
|
2463
2651
|
"div",
|
|
2464
2652
|
{
|
|
2465
2653
|
ref: rowRef,
|
|
@@ -2498,7 +2686,7 @@ function AgentChatMessage({
|
|
|
2498
2686
|
const resolvedUserContent = userMessageContent ?? message.content;
|
|
2499
2687
|
const shouldRenderContent = isAssistant || Boolean(renderUserContent || resolvedUserContent);
|
|
2500
2688
|
const showAttachments = Boolean(message.attachments?.length) && (message.role === "user" || showAssistantAttachments);
|
|
2501
|
-
const renderedActions = actions ?? (actionHandlers ? /* @__PURE__ */
|
|
2689
|
+
const renderedActions = actions ?? (actionHandlers ? /* @__PURE__ */ jsx11(
|
|
2502
2690
|
AgentChatDefaultActions,
|
|
2503
2691
|
{
|
|
2504
2692
|
additionalActions,
|
|
@@ -2508,14 +2696,14 @@ function AgentChatMessage({
|
|
|
2508
2696
|
}
|
|
2509
2697
|
) : null);
|
|
2510
2698
|
const defaultUserActions = !actions && Boolean(actionHandlers) && !isAssistant;
|
|
2511
|
-
return /* @__PURE__ */
|
|
2699
|
+
return /* @__PURE__ */ jsxs7(
|
|
2512
2700
|
ChatMessage,
|
|
2513
2701
|
{
|
|
2514
2702
|
className,
|
|
2515
2703
|
dir,
|
|
2516
2704
|
from: message.role,
|
|
2517
2705
|
children: [
|
|
2518
|
-
showAttachments ? /* @__PURE__ */
|
|
2706
|
+
showAttachments ? /* @__PURE__ */ jsx11(
|
|
2519
2707
|
ChatAttachmentRows,
|
|
2520
2708
|
{
|
|
2521
2709
|
attachments: message.attachments || [],
|
|
@@ -2524,14 +2712,14 @@ function AgentChatMessage({
|
|
|
2524
2712
|
resolveContent: attachmentContentResolver
|
|
2525
2713
|
}
|
|
2526
2714
|
) : null,
|
|
2527
|
-
shouldRenderContent ? /* @__PURE__ */
|
|
2715
|
+
shouldRenderContent ? /* @__PURE__ */ jsxs7(
|
|
2528
2716
|
ChatMessageContent,
|
|
2529
2717
|
{
|
|
2530
2718
|
className: cn(isAssistant ? "bg-transparent p-0" : void 0, contentClassName),
|
|
2531
2719
|
dir,
|
|
2532
2720
|
from: message.role,
|
|
2533
2721
|
children: [
|
|
2534
|
-
isAssistant ? renderAssistantContent ? renderAssistantContent({ isStreaming, message }) : /* @__PURE__ */
|
|
2722
|
+
isAssistant ? renderAssistantContent ? renderAssistantContent({ isStreaming, message }) : /* @__PURE__ */ jsx11(
|
|
2535
2723
|
Timeline,
|
|
2536
2724
|
{
|
|
2537
2725
|
getHitlActionState,
|
|
@@ -2542,7 +2730,7 @@ function AgentChatMessage({
|
|
|
2542
2730
|
parts: message.parts
|
|
2543
2731
|
}
|
|
2544
2732
|
) : null,
|
|
2545
|
-
!isAssistant ? renderUserContent ? renderUserContent({ message }) : resolvedUserContent ? /* @__PURE__ */
|
|
2733
|
+
!isAssistant ? renderUserContent ? renderUserContent({ message }) : resolvedUserContent ? /* @__PURE__ */ jsx11(
|
|
2546
2734
|
AgentChatUserMessageContent,
|
|
2547
2735
|
{
|
|
2548
2736
|
collapsedLines: userMessageCollapsedLines,
|
|
@@ -2555,15 +2743,15 @@ function AgentChatMessage({
|
|
|
2555
2743
|
]
|
|
2556
2744
|
}
|
|
2557
2745
|
) : null,
|
|
2558
|
-
renderedActions ? defaultUserActions ? /* @__PURE__ */
|
|
2746
|
+
renderedActions ? defaultUserActions ? /* @__PURE__ */ jsx11(AgentChatUserMessageActionRow, { className: actionsClassName, children: renderedActions }) : /* @__PURE__ */ jsx11("div", { className: cn(dir === "rtl" ? "mt-1 h-9 w-full" : "mt-1 h-9 w-full -translate-x-2", actionsClassName), children: renderedActions }) : null
|
|
2559
2747
|
]
|
|
2560
2748
|
}
|
|
2561
2749
|
);
|
|
2562
2750
|
}
|
|
2563
2751
|
|
|
2564
2752
|
// src/ui/agent-chat-context-status.tsx
|
|
2565
|
-
import * as
|
|
2566
|
-
import { jsx as
|
|
2753
|
+
import * as React11 from "react";
|
|
2754
|
+
import { jsx as jsx12, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
2567
2755
|
var COMPACT_TOKENS = new Intl.NumberFormat("en-US", { notation: "compact" });
|
|
2568
2756
|
var PERCENT = new Intl.NumberFormat("en-US", {
|
|
2569
2757
|
style: "percent",
|
|
@@ -2586,13 +2774,13 @@ function AgentChatContextStatus({
|
|
|
2586
2774
|
className,
|
|
2587
2775
|
contextWindow
|
|
2588
2776
|
}) {
|
|
2589
|
-
const tooltipId =
|
|
2590
|
-
const [open, setOpen] =
|
|
2777
|
+
const tooltipId = React11.useId();
|
|
2778
|
+
const [open, setOpen] = React11.useState(false);
|
|
2591
2779
|
const { maximum, input, admissionInput, usageRatio, admissionRatio } = contextStatusMetrics(contextWindow);
|
|
2592
2780
|
const percentage = Math.round(usageRatio * 100);
|
|
2593
2781
|
const exact = EXACT_SOURCES.has(contextWindow?.source || "unknown");
|
|
2594
2782
|
if (!Number.isFinite(maximum) || maximum <= 0) return null;
|
|
2595
|
-
return /* @__PURE__ */
|
|
2783
|
+
return /* @__PURE__ */ jsxs8(
|
|
2596
2784
|
"div",
|
|
2597
2785
|
{
|
|
2598
2786
|
className: cn("a24-context-status", className),
|
|
@@ -2603,7 +2791,7 @@ function AgentChatContextStatus({
|
|
|
2603
2791
|
onMouseEnter: () => setOpen(true),
|
|
2604
2792
|
onMouseLeave: () => setOpen(false),
|
|
2605
2793
|
children: [
|
|
2606
|
-
/* @__PURE__ */
|
|
2794
|
+
/* @__PURE__ */ jsxs8(
|
|
2607
2795
|
"button",
|
|
2608
2796
|
{
|
|
2609
2797
|
"aria-describedby": open ? tooltipId : void 0,
|
|
@@ -2614,9 +2802,9 @@ function AgentChatContextStatus({
|
|
|
2614
2802
|
},
|
|
2615
2803
|
type: "button",
|
|
2616
2804
|
children: [
|
|
2617
|
-
/* @__PURE__ */
|
|
2618
|
-
/* @__PURE__ */
|
|
2619
|
-
/* @__PURE__ */
|
|
2805
|
+
/* @__PURE__ */ jsxs8("svg", { "aria-hidden": "true", className: "a24-context-status__ring", viewBox: "0 0 24 24", children: [
|
|
2806
|
+
/* @__PURE__ */ jsx12("circle", { className: "a24-context-status__track", cx: "12", cy: "12", r: "10" }),
|
|
2807
|
+
/* @__PURE__ */ jsx12(
|
|
2620
2808
|
"circle",
|
|
2621
2809
|
{
|
|
2622
2810
|
className: "a24-context-status__value",
|
|
@@ -2628,20 +2816,20 @@ function AgentChatContextStatus({
|
|
|
2628
2816
|
}
|
|
2629
2817
|
)
|
|
2630
2818
|
] }),
|
|
2631
|
-
/* @__PURE__ */
|
|
2819
|
+
/* @__PURE__ */ jsxs8("span", { children: [
|
|
2632
2820
|
percentage,
|
|
2633
2821
|
"%"
|
|
2634
2822
|
] })
|
|
2635
2823
|
]
|
|
2636
2824
|
}
|
|
2637
2825
|
),
|
|
2638
|
-
open ? /* @__PURE__ */
|
|
2639
|
-
/* @__PURE__ */
|
|
2640
|
-
/* @__PURE__ */
|
|
2826
|
+
open ? /* @__PURE__ */ jsxs8("div", { className: "a24-context-status__popover", id: tooltipId, role: "tooltip", children: [
|
|
2827
|
+
/* @__PURE__ */ jsx12("span", { className: "a24-context-status__sr-only", children: "Context window" }),
|
|
2828
|
+
/* @__PURE__ */ jsxs8("strong", { children: [
|
|
2641
2829
|
PERCENT.format(usageRatio),
|
|
2642
2830
|
" context used"
|
|
2643
2831
|
] }),
|
|
2644
|
-
/* @__PURE__ */
|
|
2832
|
+
/* @__PURE__ */ jsxs8("span", { children: [
|
|
2645
2833
|
exact ? "Input" : "Estimated input",
|
|
2646
2834
|
": ",
|
|
2647
2835
|
COMPACT_TOKENS.format(input),
|
|
@@ -2649,7 +2837,7 @@ function AgentChatContextStatus({
|
|
|
2649
2837
|
COMPACT_TOKENS.format(maximum),
|
|
2650
2838
|
" tokens"
|
|
2651
2839
|
] }),
|
|
2652
|
-
admissionInput !== input ? /* @__PURE__ */
|
|
2840
|
+
admissionInput !== input ? /* @__PURE__ */ jsxs8("span", { children: [
|
|
2653
2841
|
"Safety bound: ",
|
|
2654
2842
|
COMPACT_TOKENS.format(admissionInput),
|
|
2655
2843
|
" tokens (",
|
|
@@ -2665,9 +2853,9 @@ function AgentChatContextStatus({
|
|
|
2665
2853
|
// src/ui/bubble.tsx
|
|
2666
2854
|
import { cva as cva2 } from "class-variance-authority";
|
|
2667
2855
|
import { Slot as Slot2 } from "@radix-ui/react-slot";
|
|
2668
|
-
import { jsx as
|
|
2856
|
+
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
2669
2857
|
function BubbleGroup({ className, ...props }) {
|
|
2670
|
-
return /* @__PURE__ */
|
|
2858
|
+
return /* @__PURE__ */ jsx13(
|
|
2671
2859
|
"div",
|
|
2672
2860
|
{
|
|
2673
2861
|
"data-slot": "bubble-group",
|
|
@@ -2701,7 +2889,7 @@ function Bubble({
|
|
|
2701
2889
|
className,
|
|
2702
2890
|
...props
|
|
2703
2891
|
}) {
|
|
2704
|
-
return /* @__PURE__ */
|
|
2892
|
+
return /* @__PURE__ */ jsx13(
|
|
2705
2893
|
"div",
|
|
2706
2894
|
{
|
|
2707
2895
|
"data-slot": "bubble",
|
|
@@ -2718,7 +2906,7 @@ function BubbleContent({
|
|
|
2718
2906
|
...props
|
|
2719
2907
|
}) {
|
|
2720
2908
|
const Comp = asChild ? Slot2 : "div";
|
|
2721
|
-
return /* @__PURE__ */
|
|
2909
|
+
return /* @__PURE__ */ jsx13(
|
|
2722
2910
|
Comp,
|
|
2723
2911
|
{
|
|
2724
2912
|
"data-slot": "bubble-content",
|
|
@@ -2755,7 +2943,7 @@ function BubbleReactions({
|
|
|
2755
2943
|
className,
|
|
2756
2944
|
...props
|
|
2757
2945
|
}) {
|
|
2758
|
-
return /* @__PURE__ */
|
|
2946
|
+
return /* @__PURE__ */ jsx13(
|
|
2759
2947
|
"div",
|
|
2760
2948
|
{
|
|
2761
2949
|
"data-slot": "bubble-reactions",
|
|
@@ -2770,7 +2958,7 @@ function BubbleReactions({
|
|
|
2770
2958
|
// src/ui/marker.tsx
|
|
2771
2959
|
import { cva as cva3 } from "class-variance-authority";
|
|
2772
2960
|
import { Slot as Slot3 } from "@radix-ui/react-slot";
|
|
2773
|
-
import { jsx as
|
|
2961
|
+
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
2774
2962
|
var markerVariants = cva3(
|
|
2775
2963
|
"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",
|
|
2776
2964
|
{
|
|
@@ -2790,7 +2978,7 @@ function Marker({
|
|
|
2790
2978
|
...props
|
|
2791
2979
|
}) {
|
|
2792
2980
|
const Comp = asChild ? Slot3 : "div";
|
|
2793
|
-
return /* @__PURE__ */
|
|
2981
|
+
return /* @__PURE__ */ jsx14(
|
|
2794
2982
|
Comp,
|
|
2795
2983
|
{
|
|
2796
2984
|
"data-slot": "marker",
|
|
@@ -2801,7 +2989,7 @@ function Marker({
|
|
|
2801
2989
|
);
|
|
2802
2990
|
}
|
|
2803
2991
|
function MarkerIcon({ className, ...props }) {
|
|
2804
|
-
return /* @__PURE__ */
|
|
2992
|
+
return /* @__PURE__ */ jsx14(
|
|
2805
2993
|
"span",
|
|
2806
2994
|
{
|
|
2807
2995
|
"data-slot": "marker-icon",
|
|
@@ -2815,7 +3003,7 @@ function MarkerIcon({ className, ...props }) {
|
|
|
2815
3003
|
);
|
|
2816
3004
|
}
|
|
2817
3005
|
function MarkerContent({ className, ...props }) {
|
|
2818
|
-
return /* @__PURE__ */
|
|
3006
|
+
return /* @__PURE__ */ jsx14(
|
|
2819
3007
|
"span",
|
|
2820
3008
|
{
|
|
2821
3009
|
"data-slot": "marker-content",
|
|
@@ -2829,7 +3017,7 @@ function MarkerContent({ className, ...props }) {
|
|
|
2829
3017
|
}
|
|
2830
3018
|
|
|
2831
3019
|
// src/ui/mcp-connect-required-card.tsx
|
|
2832
|
-
import { jsx as
|
|
3020
|
+
import { jsx as jsx15, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
2833
3021
|
var STATUS_LABELS = {
|
|
2834
3022
|
pending: "Connect",
|
|
2835
3023
|
connecting: "Connecting",
|
|
@@ -2853,7 +3041,7 @@ function McpConnectRequiredCard({
|
|
|
2853
3041
|
const isBusy = loading || status === "connecting" || status === "resuming";
|
|
2854
3042
|
const isConnected = status === "connected";
|
|
2855
3043
|
const buttonDisabled = disabled || isBusy || isConnected || !onConnect;
|
|
2856
|
-
return /* @__PURE__ */
|
|
3044
|
+
return /* @__PURE__ */ jsx15(
|
|
2857
3045
|
"div",
|
|
2858
3046
|
{
|
|
2859
3047
|
"data-agents24-mcp-connect-card": true,
|
|
@@ -2863,13 +3051,13 @@ function McpConnectRequiredCard({
|
|
|
2863
3051
|
className
|
|
2864
3052
|
),
|
|
2865
3053
|
...props,
|
|
2866
|
-
children: /* @__PURE__ */
|
|
2867
|
-
/* @__PURE__ */
|
|
2868
|
-
/* @__PURE__ */
|
|
2869
|
-
/* @__PURE__ */
|
|
2870
|
-
status === "error" && error ? /* @__PURE__ */
|
|
3054
|
+
children: /* @__PURE__ */ jsxs9("div", { className: "flex min-w-0 items-start justify-between gap-3", children: [
|
|
3055
|
+
/* @__PURE__ */ jsxs9("div", { className: "min-w-0", children: [
|
|
3056
|
+
/* @__PURE__ */ jsx15("div", { className: "truncate text-sm font-medium", children: label }),
|
|
3057
|
+
/* @__PURE__ */ jsx15("div", { className: "mt-1 text-sm text-muted-foreground", children: message || "Connect your account to continue." }),
|
|
3058
|
+
status === "error" && error ? /* @__PURE__ */ jsx15("div", { className: "mt-2 text-sm text-destructive", children: error }) : null
|
|
2871
3059
|
] }),
|
|
2872
|
-
/* @__PURE__ */
|
|
3060
|
+
/* @__PURE__ */ jsx15(
|
|
2873
3061
|
"button",
|
|
2874
3062
|
{
|
|
2875
3063
|
type: "button",
|
|
@@ -2888,22 +3076,22 @@ function McpConnectRequiredCard({
|
|
|
2888
3076
|
}
|
|
2889
3077
|
|
|
2890
3078
|
// src/ui/use-audio-recorder.ts
|
|
2891
|
-
import * as
|
|
3079
|
+
import * as React12 from "react";
|
|
2892
3080
|
var RECORDING_CANDIDATES = ["audio/webm;codecs=opus", "audio/webm", "audio/mp4"];
|
|
2893
3081
|
function recordingExtension(mimeType) {
|
|
2894
3082
|
return mimeType.startsWith("audio/mp4") ? "m4a" : "webm";
|
|
2895
3083
|
}
|
|
2896
3084
|
function useAudioRecorder(onRecorded, options = {}) {
|
|
2897
|
-
const recorderRef =
|
|
2898
|
-
const streamRef =
|
|
2899
|
-
const onRecordedRef =
|
|
2900
|
-
const onStreamChangeRef =
|
|
3085
|
+
const recorderRef = React12.useRef(null);
|
|
3086
|
+
const streamRef = React12.useRef(null);
|
|
3087
|
+
const onRecordedRef = React12.useRef(onRecorded);
|
|
3088
|
+
const onStreamChangeRef = React12.useRef(options.onStreamChange);
|
|
2901
3089
|
onRecordedRef.current = onRecorded;
|
|
2902
3090
|
onStreamChangeRef.current = options.onStreamChange;
|
|
2903
|
-
const [isRecording, setIsRecording] =
|
|
2904
|
-
const [error, setError] =
|
|
2905
|
-
const stop =
|
|
2906
|
-
const start =
|
|
3091
|
+
const [isRecording, setIsRecording] = React12.useState(false);
|
|
3092
|
+
const [error, setError] = React12.useState(null);
|
|
3093
|
+
const stop = React12.useCallback(() => recorderRef.current?.stop(), []);
|
|
3094
|
+
const start = React12.useCallback(async () => {
|
|
2907
3095
|
setError(null);
|
|
2908
3096
|
if (!navigator.mediaDevices?.getUserMedia || typeof MediaRecorder === "undefined") {
|
|
2909
3097
|
setError("Audio recording is not supported in this browser.");
|
|
@@ -2941,7 +3129,7 @@ function useAudioRecorder(onRecorded, options = {}) {
|
|
|
2941
3129
|
setError("Microphone access is unavailable.");
|
|
2942
3130
|
}
|
|
2943
3131
|
}, []);
|
|
2944
|
-
|
|
3132
|
+
React12.useEffect(() => () => {
|
|
2945
3133
|
recorderRef.current?.stop();
|
|
2946
3134
|
streamRef.current?.getTracks().forEach((track) => track.stop());
|
|
2947
3135
|
onStreamChangeRef.current?.(null);
|
|
@@ -2958,6 +3146,7 @@ export {
|
|
|
2958
3146
|
AgentChatModelTurnRow,
|
|
2959
3147
|
AgentChatNodeActivityRow,
|
|
2960
3148
|
AgentChatPart,
|
|
3149
|
+
AgentChatQueue,
|
|
2961
3150
|
AgentChatSubagentGroup,
|
|
2962
3151
|
AgentChatToolGroup,
|
|
2963
3152
|
AgentChatToolPart,
|
|
@@ -3009,6 +3198,7 @@ export {
|
|
|
3009
3198
|
attachmentMediaVariants,
|
|
3010
3199
|
attachmentVariants,
|
|
3011
3200
|
bubbleVariants,
|
|
3201
|
+
chatComposerAction,
|
|
3012
3202
|
cn,
|
|
3013
3203
|
contextStatusMetrics,
|
|
3014
3204
|
createAgentChatComposerFile,
|
|
@@ -3019,9 +3209,13 @@ export {
|
|
|
3019
3209
|
latestRunningAgentChatToolId,
|
|
3020
3210
|
markerVariants,
|
|
3021
3211
|
partitionAgentChatToolTimeline,
|
|
3212
|
+
queuedMessageComposerFiles,
|
|
3022
3213
|
resolvedHitlLabel,
|
|
3023
3214
|
revokeAgentChatComposerFiles,
|
|
3024
3215
|
shouldCollapseUserMessage,
|
|
3025
|
-
useAudioRecorder
|
|
3216
|
+
useAudioRecorder,
|
|
3217
|
+
useChatComposerFocus,
|
|
3218
|
+
useCompletionActionEntrance,
|
|
3219
|
+
useLiveCompletionRuns
|
|
3026
3220
|
};
|
|
3027
3221
|
//# sourceMappingURL=index.js.map
|