@agents24/chat-react 0.5.16 → 0.5.18
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 +23 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +22 -2
- package/dist/index.js.map +1 -1
- package/dist/latest-thread-scroller.d.ts +10 -2
- package/dist/runtime/index.cjs +6 -1
- package/dist/runtime/index.cjs.map +1 -1
- package/dist/runtime/index.js +6 -1
- 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/agent-response-timeline.d.ts +4 -2
- package/dist/ui/composer-attachments.d.ts +5 -1
- package/dist/ui/composer-interactions.d.ts +17 -0
- package/dist/ui/index.cjs +537 -331
- package/dist/ui/index.cjs.map +1 -1
- package/dist/ui/index.d.ts +2 -0
- package/dist/ui/index.js +522 -322
- package/dist/ui/index.js.map +1 -1
- package/dist/ui/tool-sessions.d.ts +4 -1
- package/package.json +3 -3
- 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.cjs
CHANGED
|
@@ -39,6 +39,7 @@ __export(ui_exports, {
|
|
|
39
39
|
AgentChatModelTurnRow: () => AgentChatModelTurnRow,
|
|
40
40
|
AgentChatNodeActivityRow: () => AgentChatNodeActivityRow,
|
|
41
41
|
AgentChatPart: () => AgentChatPart,
|
|
42
|
+
AgentChatQueue: () => AgentChatQueue,
|
|
42
43
|
AgentChatSubagentGroup: () => AgentChatSubagentGroup,
|
|
43
44
|
AgentChatToolGroup: () => AgentChatToolGroup,
|
|
44
45
|
AgentChatToolPart: () => AgentChatToolPart,
|
|
@@ -90,6 +91,7 @@ __export(ui_exports, {
|
|
|
90
91
|
attachmentMediaVariants: () => attachmentMediaVariants,
|
|
91
92
|
attachmentVariants: () => attachmentVariants,
|
|
92
93
|
bubbleVariants: () => bubbleVariants,
|
|
94
|
+
chatComposerAction: () => chatComposerAction,
|
|
93
95
|
cn: () => cn,
|
|
94
96
|
contextStatusMetrics: () => contextStatusMetrics,
|
|
95
97
|
createAgentChatComposerFile: () => createAgentChatComposerFile,
|
|
@@ -100,15 +102,19 @@ __export(ui_exports, {
|
|
|
100
102
|
latestRunningAgentChatToolId: () => latestRunningAgentChatToolId,
|
|
101
103
|
markerVariants: () => markerVariants,
|
|
102
104
|
partitionAgentChatToolTimeline: () => partitionAgentChatToolTimeline,
|
|
105
|
+
queuedMessageComposerFiles: () => queuedMessageComposerFiles,
|
|
103
106
|
resolvedHitlLabel: () => resolvedHitlLabel,
|
|
104
107
|
revokeAgentChatComposerFiles: () => revokeAgentChatComposerFiles,
|
|
105
108
|
shouldCollapseUserMessage: () => shouldCollapseUserMessage,
|
|
106
|
-
useAudioRecorder: () => useAudioRecorder
|
|
109
|
+
useAudioRecorder: () => useAudioRecorder,
|
|
110
|
+
useChatComposerFocus: () => useChatComposerFocus,
|
|
111
|
+
useCompletionActionEntrance: () => useCompletionActionEntrance,
|
|
112
|
+
useLiveCompletionRuns: () => useLiveCompletionRuns
|
|
107
113
|
});
|
|
108
114
|
module.exports = __toCommonJS(ui_exports);
|
|
109
115
|
|
|
110
116
|
// src/ui/agent-chat-composer.tsx
|
|
111
|
-
var
|
|
117
|
+
var React3 = __toESM(require("react"), 1);
|
|
112
118
|
var import_lucide_react2 = require("lucide-react");
|
|
113
119
|
|
|
114
120
|
// src/ui/adapters.ts
|
|
@@ -833,11 +839,50 @@ function createAgentChatComposerFile(file) {
|
|
|
833
839
|
function revokeAgentChatComposerFiles(files) {
|
|
834
840
|
files.forEach((file) => {
|
|
835
841
|
try {
|
|
836
|
-
URL.revokeObjectURL(file.url);
|
|
842
|
+
if (file.url.startsWith("blob:")) URL.revokeObjectURL(file.url);
|
|
837
843
|
} catch {
|
|
838
844
|
}
|
|
839
845
|
});
|
|
840
846
|
}
|
|
847
|
+
function queuedMessageComposerFiles(message) {
|
|
848
|
+
const byId = new Map((message.attachments || []).map((attachment) => [attachment.id, attachment]));
|
|
849
|
+
return message.attachment_ids.map((id) => {
|
|
850
|
+
const attachment = byId.get(id);
|
|
851
|
+
return {
|
|
852
|
+
id,
|
|
853
|
+
persistedAttachmentId: id,
|
|
854
|
+
type: "file",
|
|
855
|
+
url: "",
|
|
856
|
+
filename: attachment?.filename || "Attachment",
|
|
857
|
+
mediaType: attachment?.mime_type || "application/octet-stream",
|
|
858
|
+
byteSize: attachment?.byte_size || 0
|
|
859
|
+
};
|
|
860
|
+
});
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
// src/ui/composer-interactions.ts
|
|
864
|
+
var React2 = __toESM(require("react"), 1);
|
|
865
|
+
function chatComposerAction({ hasDraft, isRunning, isCancelling }) {
|
|
866
|
+
return isRunning && (!hasDraft || isCancelling) ? "stop" : "send";
|
|
867
|
+
}
|
|
868
|
+
function useChatComposerFocus({ textareaRef, disabled, focusKey, restoredDraft, onRestore }) {
|
|
869
|
+
const restoreRef = React2.useRef(onRestore);
|
|
870
|
+
restoreRef.current = onRestore;
|
|
871
|
+
const focus = React2.useCallback(() => {
|
|
872
|
+
window.requestAnimationFrame(() => textareaRef.current?.focus({ preventScroll: true }));
|
|
873
|
+
}, [textareaRef]);
|
|
874
|
+
React2.useEffect(() => {
|
|
875
|
+
if (!restoredDraft) return;
|
|
876
|
+
restoreRef.current(restoredDraft);
|
|
877
|
+
focus();
|
|
878
|
+
}, [restoredDraft?.revision, focus]);
|
|
879
|
+
React2.useEffect(() => {
|
|
880
|
+
const supportsFinePointer = typeof window.matchMedia === "function" && window.matchMedia("(hover: hover) and (pointer: fine)").matches;
|
|
881
|
+
if (disabled || !supportsFinePointer) return;
|
|
882
|
+
focus();
|
|
883
|
+
}, [disabled, focusKey, focus]);
|
|
884
|
+
return focus;
|
|
885
|
+
}
|
|
841
886
|
|
|
842
887
|
// src/ui/agent-chat-composer.tsx
|
|
843
888
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
@@ -854,24 +899,27 @@ function AgentChatComposer({
|
|
|
854
899
|
className,
|
|
855
900
|
disabled = false,
|
|
856
901
|
forceExpanded = false,
|
|
902
|
+
focusKey,
|
|
857
903
|
inputToolbarContent,
|
|
858
904
|
isRunning = false,
|
|
905
|
+
isCancelling = false,
|
|
859
906
|
onAttachmentCountChange,
|
|
860
907
|
onStop,
|
|
861
908
|
onSubmit,
|
|
862
909
|
placeholder = "Message the agent",
|
|
910
|
+
restoredDraft,
|
|
863
911
|
textareaRef
|
|
864
912
|
}) {
|
|
865
|
-
const fileInputRef =
|
|
866
|
-
const filesRef =
|
|
867
|
-
const inFlightFilesRef =
|
|
868
|
-
const localTextareaRef =
|
|
869
|
-
const draftRevisionRef =
|
|
870
|
-
const [text, setText] =
|
|
871
|
-
const [files, setFiles] =
|
|
872
|
-
const [isSubmitting, setIsSubmitting] =
|
|
913
|
+
const fileInputRef = React3.useRef(null);
|
|
914
|
+
const filesRef = React3.useRef([]);
|
|
915
|
+
const inFlightFilesRef = React3.useRef([]);
|
|
916
|
+
const localTextareaRef = React3.useRef(null);
|
|
917
|
+
const draftRevisionRef = React3.useRef(0);
|
|
918
|
+
const [text, setText] = React3.useState("");
|
|
919
|
+
const [files, setFiles] = React3.useState([]);
|
|
920
|
+
const [isSubmitting, setIsSubmitting] = React3.useState(false);
|
|
873
921
|
const isExpanded = forceExpanded || text.includes("\n") || text.length > 62;
|
|
874
|
-
const setTextareaRef =
|
|
922
|
+
const setTextareaRef = React3.useCallback(
|
|
875
923
|
(node) => {
|
|
876
924
|
localTextareaRef.current = node;
|
|
877
925
|
if (typeof textareaRef === "function") {
|
|
@@ -882,15 +930,27 @@ function AgentChatComposer({
|
|
|
882
930
|
},
|
|
883
931
|
[textareaRef]
|
|
884
932
|
);
|
|
885
|
-
|
|
933
|
+
React3.useEffect(() => {
|
|
886
934
|
filesRef.current = files;
|
|
887
935
|
onAttachmentCountChange?.(files.length);
|
|
888
936
|
}, [files, onAttachmentCountChange]);
|
|
889
|
-
|
|
937
|
+
React3.useEffect(() => () => {
|
|
890
938
|
revokeAgentChatComposerFiles(filesRef.current);
|
|
891
939
|
revokeAgentChatComposerFiles(inFlightFilesRef.current);
|
|
892
940
|
}, []);
|
|
893
|
-
|
|
941
|
+
const focusComposer = useChatComposerFocus({
|
|
942
|
+
textareaRef: localTextareaRef,
|
|
943
|
+
disabled,
|
|
944
|
+
focusKey,
|
|
945
|
+
restoredDraft,
|
|
946
|
+
onRestore: (draft) => {
|
|
947
|
+
draftRevisionRef.current += 1;
|
|
948
|
+
revokeAgentChatComposerFiles(filesRef.current);
|
|
949
|
+
setText(draft.text);
|
|
950
|
+
setFiles(draft.files);
|
|
951
|
+
}
|
|
952
|
+
});
|
|
953
|
+
React3.useLayoutEffect(() => {
|
|
894
954
|
const textarea = localTextareaRef.current;
|
|
895
955
|
if (!textarea) return;
|
|
896
956
|
if (isExpanded) {
|
|
@@ -903,7 +963,8 @@ function AgentChatComposer({
|
|
|
903
963
|
textarea.style.height = "";
|
|
904
964
|
textarea.style.overflowY = "hidden";
|
|
905
965
|
}, [isExpanded, text]);
|
|
906
|
-
const canSubmit = !disabled && !isSubmitting &&
|
|
966
|
+
const canSubmit = !disabled && !isSubmitting && (text.trim().length > 0 || files.length > 0);
|
|
967
|
+
const action = chatComposerAction({ hasDraft: text.trim().length > 0 || files.length > 0, isRunning, isCancelling });
|
|
907
968
|
const handleFilesChange = (event) => {
|
|
908
969
|
const selected = Array.from(event.target.files || []).map(createAgentChatComposerFile);
|
|
909
970
|
if (selected.length > 0) {
|
|
@@ -930,8 +991,13 @@ function AgentChatComposer({
|
|
|
930
991
|
setIsSubmitting(true);
|
|
931
992
|
setText("");
|
|
932
993
|
setFiles([]);
|
|
994
|
+
focusComposer();
|
|
933
995
|
try {
|
|
934
|
-
await onSubmit({
|
|
996
|
+
await onSubmit({
|
|
997
|
+
text: submittedText,
|
|
998
|
+
files: submittedFiles,
|
|
999
|
+
attachmentIds: submittedFiles.flatMap((file) => file.persistedAttachmentId ? [file.persistedAttachmentId] : [])
|
|
1000
|
+
});
|
|
935
1001
|
revokeAgentChatComposerFiles(submittedFiles);
|
|
936
1002
|
inFlightFilesRef.current = [];
|
|
937
1003
|
} catch {
|
|
@@ -1012,7 +1078,7 @@ function AgentChatComposer({
|
|
|
1012
1078
|
{
|
|
1013
1079
|
"aria-label": "Attach files",
|
|
1014
1080
|
className: cn("a24-composer__attach", pillButtonClass),
|
|
1015
|
-
disabled: disabled || isSubmitting ||
|
|
1081
|
+
disabled: disabled || isSubmitting || !allowAttachments,
|
|
1016
1082
|
onClick: () => fileInputRef.current?.click(),
|
|
1017
1083
|
title: "Attach files",
|
|
1018
1084
|
type: "button",
|
|
@@ -1030,7 +1096,7 @@ function AgentChatComposer({
|
|
|
1030
1096
|
"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",
|
|
1031
1097
|
isExpanded ? "min-h-9 max-h-[224px] py-1" : "min-h-9 h-9 max-h-9 py-2"
|
|
1032
1098
|
),
|
|
1033
|
-
disabled
|
|
1099
|
+
disabled,
|
|
1034
1100
|
name: "message",
|
|
1035
1101
|
onChange: (event) => {
|
|
1036
1102
|
draftRevisionRef.current += 1;
|
|
@@ -1045,27 +1111,19 @@ function AgentChatComposer({
|
|
|
1045
1111
|
isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { gridArea: "toolbar" }, className: "a24-composer__toolbar flex min-w-0 items-center gap-1.5", children: inputToolbarContent }) : null,
|
|
1046
1112
|
!isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { gridArea: "composer" }, className: "flex min-w-0 items-center gap-1.5" }) : null,
|
|
1047
1113
|
!isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { gridArea: "mic" }, className: "flex shrink-0 items-center justify-end" }) : null,
|
|
1048
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { gridArea: "submit" }, className: "a24-composer__submit-slot flex shrink-0 items-center justify-end", children:
|
|
1114
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { gridArea: "submit" }, className: "a24-composer__submit-slot flex shrink-0 items-center justify-end gap-1", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1049
1115
|
"button",
|
|
1050
1116
|
{
|
|
1051
|
-
"aria-label": "Stop generating",
|
|
1052
|
-
className: cn("a24-composer__submit", submitButtonClass),
|
|
1053
|
-
disabled: disabled || !onStop,
|
|
1054
|
-
onClick: onStop,
|
|
1055
|
-
title: "Stop",
|
|
1056
|
-
type: "button",
|
|
1057
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.Square, { className: "size-3.5 fill-current" })
|
|
1058
|
-
}
|
|
1059
|
-
) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1060
|
-
"button",
|
|
1061
|
-
{
|
|
1062
|
-
"aria-label": files.length > 0 ? `Send ${formatFileCount(files)}` : "Send message",
|
|
1117
|
+
"aria-label": isCancelling ? "Cancelling response" : action === "stop" ? "Stop generating" : files.length > 0 ? `Send ${formatFileCount(files)}` : isRunning ? "Queue message" : "Send message",
|
|
1063
1118
|
className: cn("a24-composer__submit", submitButtonClass, text.trim().length > 0 && "hover:scale-105"),
|
|
1064
|
-
disabled: !canSubmit,
|
|
1065
|
-
onClick: () =>
|
|
1066
|
-
|
|
1119
|
+
disabled: isCancelling || (action === "stop" ? disabled : !canSubmit),
|
|
1120
|
+
onClick: () => {
|
|
1121
|
+
if (action === "stop") onStop?.();
|
|
1122
|
+
else void submit();
|
|
1123
|
+
},
|
|
1124
|
+
title: action === "stop" ? "Stop" : isRunning ? "Queue message" : "Send",
|
|
1067
1125
|
type: "button",
|
|
1068
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.ArrowUp, { className: "size-4", strokeWidth: 2.5 })
|
|
1126
|
+
children: isCancelling ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.Loader2, { className: "size-3.5 animate-spin" }) : action === "stop" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.Square, { className: "size-3.5 fill-current" }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.ArrowUp, { className: "size-4", strokeWidth: 2.5 })
|
|
1069
1127
|
}
|
|
1070
1128
|
) })
|
|
1071
1129
|
]
|
|
@@ -1077,11 +1135,81 @@ function AgentChatComposer({
|
|
|
1077
1135
|
] });
|
|
1078
1136
|
}
|
|
1079
1137
|
|
|
1080
|
-
// src/ui/agent-chat-
|
|
1081
|
-
var
|
|
1138
|
+
// src/ui/agent-chat-queue.tsx
|
|
1139
|
+
var React4 = __toESM(require("react"), 1);
|
|
1082
1140
|
var import_lucide_react3 = require("lucide-react");
|
|
1083
|
-
var import_radix_ui = require("radix-ui");
|
|
1084
1141
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
1142
|
+
function QueueRow({ message, onRemove, onEdit }) {
|
|
1143
|
+
const [busy, setBusy] = React4.useState(false);
|
|
1144
|
+
const [error, setError] = React4.useState(null);
|
|
1145
|
+
const editable = message.status === "queued" || message.status === "blocked";
|
|
1146
|
+
const act = async (operation) => {
|
|
1147
|
+
setBusy(true);
|
|
1148
|
+
setError(null);
|
|
1149
|
+
try {
|
|
1150
|
+
await operation();
|
|
1151
|
+
} catch (cause) {
|
|
1152
|
+
setError(cause instanceof Error ? cause.message : "Message action failed. Try again.");
|
|
1153
|
+
} finally {
|
|
1154
|
+
setBusy(false);
|
|
1155
|
+
}
|
|
1156
|
+
};
|
|
1157
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { "data-message-id": message.id, className: "a24-queue__row min-w-0 border-b border-border/40 last:border-b-0", children: [
|
|
1158
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "a24-queue__row-content flex min-h-9 items-center gap-2 px-3 text-sm", children: [
|
|
1159
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react3.CornerDownLeft, { "aria-hidden": true, className: "size-4 shrink-0 text-muted-foreground" }),
|
|
1160
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("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"}` }),
|
|
1161
|
+
message.status === "blocked" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "shrink-0 text-xs text-amber-700", children: "Needs attention" }) : null,
|
|
1162
|
+
["steer_pending", "delivering"].includes(message.status) ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "shrink-0 text-xs text-muted-foreground", children: "Steering\u2026" }) : null,
|
|
1163
|
+
editable ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
1164
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1165
|
+
"button",
|
|
1166
|
+
{
|
|
1167
|
+
type: "button",
|
|
1168
|
+
"aria-label": "Delete queued message",
|
|
1169
|
+
disabled: busy,
|
|
1170
|
+
onClick: () => void act(() => onRemove(message)),
|
|
1171
|
+
className: "a24-queue__icon flex size-8 shrink-0 items-center justify-center text-muted-foreground hover:text-foreground disabled:opacity-50",
|
|
1172
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react3.Trash2, { "aria-hidden": true, className: "size-4" })
|
|
1173
|
+
}
|
|
1174
|
+
),
|
|
1175
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("details", { className: "a24-queue__menu relative group/queue-menu", children: [
|
|
1176
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("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__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react3.Ellipsis, { "aria-hidden": true, className: "size-4" }) }),
|
|
1177
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("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__ */ (0, import_jsx_runtime4.jsx)(
|
|
1178
|
+
"button",
|
|
1179
|
+
{
|
|
1180
|
+
type: "button",
|
|
1181
|
+
disabled: busy,
|
|
1182
|
+
onClick: () => void act(() => onEdit(message)),
|
|
1183
|
+
className: "w-full rounded px-2 py-1 text-left text-sm hover:bg-muted disabled:opacity-50",
|
|
1184
|
+
children: "Edit message"
|
|
1185
|
+
}
|
|
1186
|
+
) })
|
|
1187
|
+
] })
|
|
1188
|
+
] }) : null
|
|
1189
|
+
] }),
|
|
1190
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { role: "alert", className: "px-9 pb-2 text-xs text-destructive", children: error }) : null
|
|
1191
|
+
] });
|
|
1192
|
+
}
|
|
1193
|
+
function AgentChatQueue({ pending, queue, onRemove, onEdit, onResume, className }) {
|
|
1194
|
+
const [resumeError, setResumeError] = React4.useState(null);
|
|
1195
|
+
if (!pending.length && !queue?.paused) return null;
|
|
1196
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("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: [
|
|
1197
|
+
queue?.paused ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex min-h-9 items-center justify-between gap-2 px-3 text-xs text-muted-foreground", children: [
|
|
1198
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "Queue paused" }),
|
|
1199
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { type: "button", onClick: () => {
|
|
1200
|
+
void onResume().then(() => setResumeError(null)).catch((cause) => setResumeError(cause instanceof Error ? cause.message : "Could not resume queue"));
|
|
1201
|
+
}, className: "font-medium text-foreground hover:underline", children: "Resume queue" })
|
|
1202
|
+
] }) : null,
|
|
1203
|
+
resumeError ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { role: "alert", className: "px-3 pb-2 text-xs text-destructive", children: resumeError }) : null,
|
|
1204
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "max-h-40 overflow-y-auto", children: pending.map((message) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(QueueRow, { message, onRemove, onEdit }, message.id)) })
|
|
1205
|
+
] });
|
|
1206
|
+
}
|
|
1207
|
+
|
|
1208
|
+
// src/ui/agent-chat-actions.tsx
|
|
1209
|
+
var React5 = __toESM(require("react"), 1);
|
|
1210
|
+
var import_lucide_react4 = require("lucide-react");
|
|
1211
|
+
var import_radix_ui = require("radix-ui");
|
|
1212
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
1085
1213
|
var FEEDBACK_REASONS = [
|
|
1086
1214
|
["incorrect", "Incorrect"],
|
|
1087
1215
|
["irrelevant", "Irrelevant"],
|
|
@@ -1090,6 +1218,32 @@ var FEEDBACK_REASONS = [
|
|
|
1090
1218
|
["citation_issue", "Citation issue"],
|
|
1091
1219
|
["other", "Other"]
|
|
1092
1220
|
];
|
|
1221
|
+
var enteredCompletionRuns = /* @__PURE__ */ new Set();
|
|
1222
|
+
function useLiveCompletionRuns(runId, isRunning) {
|
|
1223
|
+
const liveRuns = React5.useRef(/* @__PURE__ */ new Set());
|
|
1224
|
+
React5.useEffect(() => {
|
|
1225
|
+
if (!runId || !isRunning) return;
|
|
1226
|
+
liveRuns.current.add(runId);
|
|
1227
|
+
if (liveRuns.current.size > 256) liveRuns.current.delete(liveRuns.current.values().next().value);
|
|
1228
|
+
}, [runId, isRunning]);
|
|
1229
|
+
return (candidate) => Boolean(candidate && liveRuns.current.has(candidate));
|
|
1230
|
+
}
|
|
1231
|
+
function useCompletionActionEntrance(isComplete, runId, wasLive = false) {
|
|
1232
|
+
const sawIncomplete = React5.useRef(!isComplete);
|
|
1233
|
+
const entered = React5.useRef(false);
|
|
1234
|
+
const shouldEnter = isComplete && !entered.current && (runId ? wasLive && !enteredCompletionRuns.has(runId) : sawIncomplete.current);
|
|
1235
|
+
React5.useEffect(() => {
|
|
1236
|
+
if (!isComplete) sawIncomplete.current = true;
|
|
1237
|
+
else if (shouldEnter) {
|
|
1238
|
+
entered.current = true;
|
|
1239
|
+
if (runId) {
|
|
1240
|
+
enteredCompletionRuns.add(runId);
|
|
1241
|
+
if (enteredCompletionRuns.size > 256) enteredCompletionRuns.delete(enteredCompletionRuns.values().next().value);
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1244
|
+
}, [isComplete, runId, shouldEnter]);
|
|
1245
|
+
return shouldEnter || entered.current;
|
|
1246
|
+
}
|
|
1093
1247
|
function formatSentAt(value) {
|
|
1094
1248
|
if (!value) return null;
|
|
1095
1249
|
const date = value instanceof Date ? value : new Date(value);
|
|
@@ -1101,21 +1255,22 @@ function formatSentAt(value) {
|
|
|
1101
1255
|
}
|
|
1102
1256
|
function AgentChatDefaultActions({
|
|
1103
1257
|
additionalActions,
|
|
1258
|
+
animateCompletion = false,
|
|
1104
1259
|
dir,
|
|
1105
1260
|
handlers,
|
|
1106
1261
|
message
|
|
1107
1262
|
}) {
|
|
1108
|
-
const [feedbackOpen, setFeedbackOpen] =
|
|
1109
|
-
const [feedbackTrigger, setFeedbackTrigger] =
|
|
1110
|
-
const [reason, setReason] =
|
|
1111
|
-
const [comment, setComment] =
|
|
1112
|
-
const [optimisticCopied, setOptimisticCopied] =
|
|
1113
|
-
const copyResetTimer =
|
|
1114
|
-
|
|
1263
|
+
const [feedbackOpen, setFeedbackOpen] = React5.useState(false);
|
|
1264
|
+
const [feedbackTrigger, setFeedbackTrigger] = React5.useState(null);
|
|
1265
|
+
const [reason, setReason] = React5.useState(handlers?.feedback?.reason ?? null);
|
|
1266
|
+
const [comment, setComment] = React5.useState(handlers?.feedback?.comment ?? "");
|
|
1267
|
+
const [optimisticCopied, setOptimisticCopied] = React5.useState(false);
|
|
1268
|
+
const copyResetTimer = React5.useRef(null);
|
|
1269
|
+
React5.useEffect(() => {
|
|
1115
1270
|
setReason(handlers?.feedback?.reason ?? null);
|
|
1116
1271
|
setComment(handlers?.feedback?.comment ?? "");
|
|
1117
1272
|
}, [handlers?.feedback?.comment, handlers?.feedback?.reason]);
|
|
1118
|
-
|
|
1273
|
+
React5.useEffect(() => () => {
|
|
1119
1274
|
if (copyResetTimer.current !== null) window.clearTimeout(copyResetTimer.current);
|
|
1120
1275
|
}, []);
|
|
1121
1276
|
const copied = handlers?.copied ?? optimisticCopied;
|
|
@@ -1132,32 +1287,32 @@ function AgentChatDefaultActions({
|
|
|
1132
1287
|
if (!handlers || message.isFinal === false) return null;
|
|
1133
1288
|
if (message.role === "user") {
|
|
1134
1289
|
const sentAt = formatSentAt(message.createdAt);
|
|
1135
|
-
return /* @__PURE__ */ (0,
|
|
1136
|
-
sentAt ? /* @__PURE__ */ (0,
|
|
1137
|
-
handlers.onCopy ? /* @__PURE__ */ (0,
|
|
1290
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(ChatMessageActions, { className: "a24-user-message-actions", children: [
|
|
1291
|
+
sentAt ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("time", { dateTime: sentAt.dateTime, children: sentAt.label }) : null,
|
|
1292
|
+
handlers.onCopy ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1138
1293
|
ChatMessageAction,
|
|
1139
1294
|
{
|
|
1140
1295
|
label: "Copy",
|
|
1141
1296
|
onClick: copyMessage,
|
|
1142
1297
|
tooltip: copied ? "Copied!" : "Copy to clipboard",
|
|
1143
1298
|
className: "a24-user-message-copy",
|
|
1144
|
-
children: copied ? /* @__PURE__ */ (0,
|
|
1299
|
+
children: copied ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react4.Check, { className: "a24-user-message-copy__check text-green-600" }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react4.Copy, { className: "a24-user-message-copy__icon" })
|
|
1145
1300
|
}
|
|
1146
1301
|
) : null
|
|
1147
1302
|
] });
|
|
1148
1303
|
}
|
|
1149
1304
|
const canWriteFeedback = Boolean(message.runId && handlers.onSetFeedback);
|
|
1150
|
-
return /* @__PURE__ */ (0,
|
|
1151
|
-
handlers.onRetry ? /* @__PURE__ */ (0,
|
|
1305
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(ChatMessageActions, { className: animateCompletion ? "a24-chat-completion-actions" : void 0, children: [
|
|
1306
|
+
handlers.onRetry ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1152
1307
|
ChatMessageAction,
|
|
1153
1308
|
{
|
|
1154
1309
|
label: "Retry",
|
|
1155
1310
|
onClick: () => void handlers.onRetry?.(message),
|
|
1156
1311
|
tooltip: "Regenerate response",
|
|
1157
|
-
children: /* @__PURE__ */ (0,
|
|
1312
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react4.RefreshCcw, { className: "size-4" })
|
|
1158
1313
|
}
|
|
1159
1314
|
) : null,
|
|
1160
|
-
canWriteFeedback ? /* @__PURE__ */ (0,
|
|
1315
|
+
canWriteFeedback ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1161
1316
|
ChatMessageAction,
|
|
1162
1317
|
{
|
|
1163
1318
|
label: "Like",
|
|
@@ -1165,11 +1320,11 @@ function AgentChatDefaultActions({
|
|
|
1165
1320
|
rating: handlers.feedback?.rating === "like" ? null : "like"
|
|
1166
1321
|
}),
|
|
1167
1322
|
tooltip: "Like this response",
|
|
1168
|
-
children: /* @__PURE__ */ (0,
|
|
1323
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react4.ThumbsUp, { className: "size-4", fill: handlers.feedback?.rating === "like" ? "currentColor" : "none" })
|
|
1169
1324
|
}
|
|
1170
1325
|
) : null,
|
|
1171
|
-
canWriteFeedback ? /* @__PURE__ */ (0,
|
|
1172
|
-
/* @__PURE__ */ (0,
|
|
1326
|
+
canWriteFeedback ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_radix_ui.Popover.Root, { onOpenChange: setFeedbackOpen, open: feedbackOpen, children: [
|
|
1327
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_radix_ui.Popover.Trigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1173
1328
|
ChatMessageAction,
|
|
1174
1329
|
{
|
|
1175
1330
|
label: "Dislike",
|
|
@@ -1181,14 +1336,14 @@ function AgentChatDefaultActions({
|
|
|
1181
1336
|
},
|
|
1182
1337
|
ref: setFeedbackTrigger,
|
|
1183
1338
|
tooltip: "Dislike this response",
|
|
1184
|
-
children: /* @__PURE__ */ (0,
|
|
1339
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react4.ThumbsDown, { className: "size-4", fill: handlers.feedback?.rating === "dislike" ? "currentColor" : "none" })
|
|
1185
1340
|
}
|
|
1186
1341
|
) }),
|
|
1187
|
-
/* @__PURE__ */ (0,
|
|
1342
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1188
1343
|
import_radix_ui.Popover.Portal,
|
|
1189
1344
|
{
|
|
1190
1345
|
container: feedbackTrigger?.closest("[data-agents24-theme-root]") ?? void 0,
|
|
1191
|
-
children: /* @__PURE__ */ (0,
|
|
1346
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
1192
1347
|
import_radix_ui.Popover.Content,
|
|
1193
1348
|
{
|
|
1194
1349
|
align: "end",
|
|
@@ -1198,8 +1353,8 @@ function AgentChatDefaultActions({
|
|
|
1198
1353
|
side: "top",
|
|
1199
1354
|
sideOffset: 8,
|
|
1200
1355
|
children: [
|
|
1201
|
-
/* @__PURE__ */ (0,
|
|
1202
|
-
/* @__PURE__ */ (0,
|
|
1356
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-sm font-medium", children: "What could be better?" }),
|
|
1357
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "mt-3 flex flex-wrap gap-1.5", children: FEEDBACK_REASONS.map(([value, label]) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1203
1358
|
"button",
|
|
1204
1359
|
{
|
|
1205
1360
|
"aria-pressed": reason === value,
|
|
@@ -1210,7 +1365,7 @@ function AgentChatDefaultActions({
|
|
|
1210
1365
|
},
|
|
1211
1366
|
value
|
|
1212
1367
|
)) }),
|
|
1213
|
-
/* @__PURE__ */ (0,
|
|
1368
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1214
1369
|
"textarea",
|
|
1215
1370
|
{
|
|
1216
1371
|
"aria-label": "Optional feedback comment",
|
|
@@ -1221,8 +1376,8 @@ function AgentChatDefaultActions({
|
|
|
1221
1376
|
value: comment
|
|
1222
1377
|
}
|
|
1223
1378
|
),
|
|
1224
|
-
/* @__PURE__ */ (0,
|
|
1225
|
-
/* @__PURE__ */ (0,
|
|
1379
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "mt-3 flex items-center justify-between gap-2", children: [
|
|
1380
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1226
1381
|
"button",
|
|
1227
1382
|
{
|
|
1228
1383
|
className: "rounded-md px-3 py-2 text-sm font-medium hover:bg-muted",
|
|
@@ -1233,7 +1388,7 @@ function AgentChatDefaultActions({
|
|
|
1233
1388
|
children: "Remove feedback"
|
|
1234
1389
|
}
|
|
1235
1390
|
),
|
|
1236
|
-
/* @__PURE__ */ (0,
|
|
1391
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1237
1392
|
"button",
|
|
1238
1393
|
{
|
|
1239
1394
|
className: "rounded-md bg-primary px-3 py-2 text-sm font-medium text-primary-foreground hover:opacity-90",
|
|
@@ -1252,24 +1407,24 @@ function AgentChatDefaultActions({
|
|
|
1252
1407
|
)
|
|
1253
1408
|
] }) : null,
|
|
1254
1409
|
additionalActions,
|
|
1255
|
-
handlers.onCopy ? /* @__PURE__ */ (0,
|
|
1410
|
+
handlers.onCopy ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1256
1411
|
ChatMessageAction,
|
|
1257
1412
|
{
|
|
1258
1413
|
label: "Copy",
|
|
1259
1414
|
onClick: copyMessage,
|
|
1260
1415
|
tooltip: copied ? "Copied!" : "Copy to clipboard",
|
|
1261
|
-
children: copied ? /* @__PURE__ */ (0,
|
|
1416
|
+
children: copied ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react4.Check, { className: "size-4 text-green-600" }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react4.Copy, { className: "size-4" })
|
|
1262
1417
|
}
|
|
1263
1418
|
) : null
|
|
1264
1419
|
] });
|
|
1265
1420
|
}
|
|
1266
1421
|
|
|
1267
1422
|
// src/ui/agent-chat-message.tsx
|
|
1268
|
-
var
|
|
1269
|
-
var
|
|
1423
|
+
var React10 = __toESM(require("react"), 1);
|
|
1424
|
+
var import_lucide_react7 = require("lucide-react");
|
|
1270
1425
|
|
|
1271
1426
|
// src/ui/agent-response-timeline.tsx
|
|
1272
|
-
var
|
|
1427
|
+
var React9 = __toESM(require("react"), 1);
|
|
1273
1428
|
|
|
1274
1429
|
// src/streaming-text.ts
|
|
1275
1430
|
var import_react = require("react");
|
|
@@ -1454,8 +1609,8 @@ function useStreamingText({
|
|
|
1454
1609
|
}
|
|
1455
1610
|
|
|
1456
1611
|
// src/ui/ask-user-interaction.tsx
|
|
1457
|
-
var
|
|
1458
|
-
var
|
|
1612
|
+
var React6 = __toESM(require("react"), 1);
|
|
1613
|
+
var import_lucide_react5 = require("lucide-react");
|
|
1459
1614
|
|
|
1460
1615
|
// src/ui/ask-user-interaction-state.ts
|
|
1461
1616
|
function emptyAskUserDrafts(questions) {
|
|
@@ -1511,7 +1666,7 @@ function askUserAnswersFromDrafts(questions, drafts) {
|
|
|
1511
1666
|
}
|
|
1512
1667
|
|
|
1513
1668
|
// src/ui/ask-user-interaction.tsx
|
|
1514
|
-
var
|
|
1669
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
1515
1670
|
function resolvedAnswerText(question, answer) {
|
|
1516
1671
|
if (!answer) return ["No response recorded"];
|
|
1517
1672
|
const labels = answer.selectedOptionIds.flatMap((optionId) => {
|
|
@@ -1525,7 +1680,7 @@ function ResolvedQuestions({
|
|
|
1525
1680
|
buttonRef,
|
|
1526
1681
|
part
|
|
1527
1682
|
}) {
|
|
1528
|
-
const [open, setOpen] =
|
|
1683
|
+
const [open, setOpen] = React6.useState(false);
|
|
1529
1684
|
const count = part.questions.length;
|
|
1530
1685
|
const answers = new Map(
|
|
1531
1686
|
(part.resolution?.answers || []).map((answer) => [
|
|
@@ -1533,8 +1688,8 @@ function ResolvedQuestions({
|
|
|
1533
1688
|
answer
|
|
1534
1689
|
])
|
|
1535
1690
|
);
|
|
1536
|
-
return /* @__PURE__ */ (0,
|
|
1537
|
-
/* @__PURE__ */ (0,
|
|
1691
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "a24-ask-user a24-ask-user--resolved w-full", children: [
|
|
1692
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1538
1693
|
"button",
|
|
1539
1694
|
{
|
|
1540
1695
|
"aria-expanded": open,
|
|
@@ -1543,14 +1698,14 @@ function ResolvedQuestions({
|
|
|
1543
1698
|
ref: buttonRef,
|
|
1544
1699
|
type: "button",
|
|
1545
1700
|
children: [
|
|
1546
|
-
/* @__PURE__ */ (0,
|
|
1701
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { children: [
|
|
1547
1702
|
"Asked ",
|
|
1548
1703
|
count,
|
|
1549
1704
|
" question",
|
|
1550
1705
|
count === 1 ? "" : "s"
|
|
1551
1706
|
] }),
|
|
1552
|
-
open ? /* @__PURE__ */ (0,
|
|
1553
|
-
|
|
1707
|
+
open ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.ChevronDown, { "aria-hidden": "true", className: "size-3.5" }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1708
|
+
import_lucide_react5.ChevronRight,
|
|
1554
1709
|
{
|
|
1555
1710
|
"aria-hidden": "true",
|
|
1556
1711
|
className: "size-3.5 opacity-70 rtl:rotate-180"
|
|
@@ -1559,12 +1714,12 @@ function ResolvedQuestions({
|
|
|
1559
1714
|
]
|
|
1560
1715
|
}
|
|
1561
1716
|
),
|
|
1562
|
-
open ? /* @__PURE__ */ (0,
|
|
1563
|
-
/* @__PURE__ */ (0,
|
|
1564
|
-
/* @__PURE__ */ (0,
|
|
1717
|
+
open ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "mt-2 space-y-3 ps-4", children: part.questions.map((question) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "min-w-0", children: [
|
|
1718
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "text-sm font-medium text-foreground", children: question.question }),
|
|
1719
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "mt-1 space-y-1 text-sm text-muted-foreground", children: resolvedAnswerText(
|
|
1565
1720
|
question,
|
|
1566
1721
|
answers.get(question.id)
|
|
1567
|
-
).map((value, index) => /* @__PURE__ */ (0,
|
|
1722
|
+
).map((value, index) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1568
1723
|
"div",
|
|
1569
1724
|
{
|
|
1570
1725
|
className: "whitespace-pre-wrap break-words",
|
|
@@ -1582,23 +1737,23 @@ function AskUserInteraction({
|
|
|
1582
1737
|
part
|
|
1583
1738
|
}) {
|
|
1584
1739
|
const questions = part.questions;
|
|
1585
|
-
const [step, setStep] =
|
|
1586
|
-
const [drafts, setDrafts] =
|
|
1740
|
+
const [step, setStep] = React6.useState(0);
|
|
1741
|
+
const [drafts, setDrafts] = React6.useState(
|
|
1587
1742
|
() => emptyAskUserDrafts(questions)
|
|
1588
1743
|
);
|
|
1589
|
-
const headingRef =
|
|
1590
|
-
const questionsRef =
|
|
1591
|
-
const resolvedButtonRef =
|
|
1592
|
-
const wasResolvedRef =
|
|
1744
|
+
const headingRef = React6.useRef(null);
|
|
1745
|
+
const questionsRef = React6.useRef(questions);
|
|
1746
|
+
const resolvedButtonRef = React6.useRef(null);
|
|
1747
|
+
const wasResolvedRef = React6.useRef(part.status !== "pending");
|
|
1593
1748
|
questionsRef.current = questions;
|
|
1594
|
-
|
|
1749
|
+
React6.useEffect(() => {
|
|
1595
1750
|
setStep(0);
|
|
1596
1751
|
setDrafts(emptyAskUserDrafts(questionsRef.current));
|
|
1597
1752
|
}, [part.interruptId]);
|
|
1598
|
-
|
|
1753
|
+
React6.useEffect(() => {
|
|
1599
1754
|
headingRef.current?.focus();
|
|
1600
1755
|
}, [step]);
|
|
1601
|
-
|
|
1756
|
+
React6.useEffect(() => {
|
|
1602
1757
|
const isResolved = part.status !== "pending";
|
|
1603
1758
|
if (isResolved && !wasResolvedRef.current) {
|
|
1604
1759
|
resolvedButtonRef.current?.focus();
|
|
@@ -1606,11 +1761,11 @@ function AskUserInteraction({
|
|
|
1606
1761
|
wasResolvedRef.current = isResolved;
|
|
1607
1762
|
}, [part.status]);
|
|
1608
1763
|
if (part.status !== "pending") {
|
|
1609
|
-
return /* @__PURE__ */ (0,
|
|
1764
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ResolvedQuestions, { buttonRef: resolvedButtonRef, part });
|
|
1610
1765
|
}
|
|
1611
1766
|
const question = questions[step];
|
|
1612
1767
|
if (!question) {
|
|
1613
|
-
return /* @__PURE__ */ (0,
|
|
1768
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "text-sm text-destructive", role: "alert", children: "This question request is unavailable." });
|
|
1614
1769
|
}
|
|
1615
1770
|
const draft = drafts[question.id] || {
|
|
1616
1771
|
customText: "",
|
|
@@ -1644,9 +1799,9 @@ function AskUserInteraction({
|
|
|
1644
1799
|
})
|
|
1645
1800
|
);
|
|
1646
1801
|
};
|
|
1647
|
-
return /* @__PURE__ */ (0,
|
|
1648
|
-
/* @__PURE__ */ (0,
|
|
1649
|
-
/* @__PURE__ */ (0,
|
|
1802
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "a24-ask-user space-y-3 rounded-xl border border-border/50 bg-background p-4 shadow-sm", children: [
|
|
1803
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex min-w-0 items-start justify-between gap-4", children: [
|
|
1804
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1650
1805
|
"h3",
|
|
1651
1806
|
{
|
|
1652
1807
|
className: "min-w-0 flex-1 text-base font-medium leading-6 text-foreground outline-none",
|
|
@@ -1655,8 +1810,8 @@ function AskUserInteraction({
|
|
|
1655
1810
|
children: question.question
|
|
1656
1811
|
}
|
|
1657
1812
|
),
|
|
1658
|
-
/* @__PURE__ */ (0,
|
|
1659
|
-
/* @__PURE__ */ (0,
|
|
1813
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex shrink-0 items-center gap-1 text-muted-foreground", children: [
|
|
1814
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1660
1815
|
"button",
|
|
1661
1816
|
{
|
|
1662
1817
|
"aria-label": "Previous question",
|
|
@@ -1664,8 +1819,8 @@ function AskUserInteraction({
|
|
|
1664
1819
|
disabled: isBusy || step === 0,
|
|
1665
1820
|
onClick: () => setStep((current) => Math.max(0, current - 1)),
|
|
1666
1821
|
type: "button",
|
|
1667
|
-
children: /* @__PURE__ */ (0,
|
|
1668
|
-
|
|
1822
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1823
|
+
import_lucide_react5.ChevronLeft,
|
|
1669
1824
|
{
|
|
1670
1825
|
"aria-hidden": "true",
|
|
1671
1826
|
className: "size-4 rtl:rotate-180"
|
|
@@ -1673,7 +1828,7 @@ function AskUserInteraction({
|
|
|
1673
1828
|
)
|
|
1674
1829
|
}
|
|
1675
1830
|
),
|
|
1676
|
-
/* @__PURE__ */ (0,
|
|
1831
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1677
1832
|
"span",
|
|
1678
1833
|
{
|
|
1679
1834
|
"aria-label": `Question ${step + 1} of ${questions.length}`,
|
|
@@ -1685,7 +1840,7 @@ function AskUserInteraction({
|
|
|
1685
1840
|
]
|
|
1686
1841
|
}
|
|
1687
1842
|
),
|
|
1688
|
-
/* @__PURE__ */ (0,
|
|
1843
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1689
1844
|
"button",
|
|
1690
1845
|
{
|
|
1691
1846
|
"aria-label": isLastQuestion ? "Submit answers" : "Next question",
|
|
@@ -1693,8 +1848,8 @@ function AskUserInteraction({
|
|
|
1693
1848
|
disabled: isBusy || !onSubmit || !canMoveForward,
|
|
1694
1849
|
onClick: () => completeStep(drafts),
|
|
1695
1850
|
type: "button",
|
|
1696
|
-
children: /* @__PURE__ */ (0,
|
|
1697
|
-
|
|
1851
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1852
|
+
import_lucide_react5.ChevronRight,
|
|
1698
1853
|
{
|
|
1699
1854
|
"aria-hidden": "true",
|
|
1700
1855
|
className: "size-4 rtl:rotate-180"
|
|
@@ -1704,10 +1859,10 @@ function AskUserInteraction({
|
|
|
1704
1859
|
)
|
|
1705
1860
|
] })
|
|
1706
1861
|
] }),
|
|
1707
|
-
/* @__PURE__ */ (0,
|
|
1862
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "space-y-1", children: [
|
|
1708
1863
|
question.options.map((option, index) => {
|
|
1709
1864
|
const selected = draft.selectedOptionIds.includes(option.id);
|
|
1710
|
-
return /* @__PURE__ */ (0,
|
|
1865
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1711
1866
|
"button",
|
|
1712
1867
|
{
|
|
1713
1868
|
"aria-pressed": selected,
|
|
@@ -1719,7 +1874,7 @@ function AskUserInteraction({
|
|
|
1719
1874
|
onClick: () => selectOption(option.id),
|
|
1720
1875
|
type: "button",
|
|
1721
1876
|
children: [
|
|
1722
|
-
/* @__PURE__ */ (0,
|
|
1877
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1723
1878
|
"span",
|
|
1724
1879
|
{
|
|
1725
1880
|
className: cn(
|
|
@@ -1729,9 +1884,9 @@ function AskUserInteraction({
|
|
|
1729
1884
|
children: index + 1
|
|
1730
1885
|
}
|
|
1731
1886
|
),
|
|
1732
|
-
/* @__PURE__ */ (0,
|
|
1733
|
-
/* @__PURE__ */ (0,
|
|
1734
|
-
|
|
1887
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "min-w-0 flex-1 font-medium text-foreground", children: option.label }),
|
|
1888
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1889
|
+
import_lucide_react5.ChevronRight,
|
|
1735
1890
|
{
|
|
1736
1891
|
"aria-hidden": "true",
|
|
1737
1892
|
className: "size-4 shrink-0 text-muted-foreground opacity-0 transition-opacity group-hover:opacity-100 group-focus-visible:opacity-100 rtl:rotate-180"
|
|
@@ -1742,9 +1897,9 @@ function AskUserInteraction({
|
|
|
1742
1897
|
option.id
|
|
1743
1898
|
);
|
|
1744
1899
|
}),
|
|
1745
|
-
/* @__PURE__ */ (0,
|
|
1746
|
-
/* @__PURE__ */ (0,
|
|
1747
|
-
/* @__PURE__ */ (0,
|
|
1900
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("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: [
|
|
1901
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("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__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react5.Pencil, { "aria-hidden": "true", className: "size-4" }) }),
|
|
1902
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1748
1903
|
"input",
|
|
1749
1904
|
{
|
|
1750
1905
|
"aria-label": "Other response",
|
|
@@ -1763,7 +1918,7 @@ function AskUserInteraction({
|
|
|
1763
1918
|
value: draft.customText
|
|
1764
1919
|
}
|
|
1765
1920
|
),
|
|
1766
|
-
draft.customText.trim() ? /* @__PURE__ */ (0,
|
|
1921
|
+
draft.customText.trim() ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1767
1922
|
"button",
|
|
1768
1923
|
{
|
|
1769
1924
|
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",
|
|
@@ -1775,12 +1930,12 @@ function AskUserInteraction({
|
|
|
1775
1930
|
) : null
|
|
1776
1931
|
] })
|
|
1777
1932
|
] }),
|
|
1778
|
-
error ? /* @__PURE__ */ (0,
|
|
1933
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "text-sm text-destructive", role: "alert", children: error }) : null
|
|
1779
1934
|
] });
|
|
1780
1935
|
}
|
|
1781
1936
|
|
|
1782
1937
|
// src/ui/agent-chat-context-compression-row.tsx
|
|
1783
|
-
var
|
|
1938
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1784
1939
|
function compressionPresentation(part) {
|
|
1785
1940
|
if (part.status === "failed") {
|
|
1786
1941
|
return { label: "Could not compact message history", status: "failed" };
|
|
@@ -1795,7 +1950,7 @@ function AgentChatContextCompressionRow({
|
|
|
1795
1950
|
part
|
|
1796
1951
|
}) {
|
|
1797
1952
|
const presentation = compressionPresentation(part);
|
|
1798
|
-
return /* @__PURE__ */ (0,
|
|
1953
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1799
1954
|
"div",
|
|
1800
1955
|
{
|
|
1801
1956
|
"aria-live": "polite",
|
|
@@ -1803,11 +1958,11 @@ function AgentChatContextCompressionRow({
|
|
|
1803
1958
|
"data-agents24-context-compression": "",
|
|
1804
1959
|
"data-status": part.status,
|
|
1805
1960
|
role: "status",
|
|
1806
|
-
children: /* @__PURE__ */ (0,
|
|
1961
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "a24-tool-trigger-row", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: cn(
|
|
1807
1962
|
"a24-tool-trigger a24-tool-trigger--root a24-tool-trigger--without-orb",
|
|
1808
1963
|
presentation.status === "failed" && "a24-tool-trigger--error",
|
|
1809
1964
|
presentation.status === "running" && "a24-tool-trigger--active"
|
|
1810
|
-
), children: /* @__PURE__ */ (0,
|
|
1965
|
+
), children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: cn(
|
|
1811
1966
|
"a24-tool-trigger__label",
|
|
1812
1967
|
presentation.status === "running" && "a24-tool-shimmer"
|
|
1813
1968
|
), children: presentation.label }) }) })
|
|
@@ -1816,7 +1971,7 @@ function AgentChatContextCompressionRow({
|
|
|
1816
1971
|
}
|
|
1817
1972
|
|
|
1818
1973
|
// src/ui/message-response.tsx
|
|
1819
|
-
var
|
|
1974
|
+
var React7 = __toESM(require("react"), 1);
|
|
1820
1975
|
var import_streamdown = require("streamdown");
|
|
1821
1976
|
|
|
1822
1977
|
// src/active-content.ts
|
|
@@ -1841,17 +1996,17 @@ function safeChatMarkdownHref(value) {
|
|
|
1841
1996
|
}
|
|
1842
1997
|
|
|
1843
1998
|
// src/ui/message-response.tsx
|
|
1844
|
-
var
|
|
1999
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1845
2000
|
function SafeMarkdownLink({ children, href, ...props }) {
|
|
1846
2001
|
const domProps = { ...props };
|
|
1847
2002
|
delete domProps.node;
|
|
1848
2003
|
const safeHref = safeChatMarkdownHref(href);
|
|
1849
|
-
if (!safeHref) return /* @__PURE__ */ (0,
|
|
1850
|
-
if (safeHref.startsWith("#")) return /* @__PURE__ */ (0,
|
|
1851
|
-
return /* @__PURE__ */ (0,
|
|
2004
|
+
if (!safeHref) return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children });
|
|
2005
|
+
if (safeHref.startsWith("#")) return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("a", { ...domProps, href: safeHref, children });
|
|
2006
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("a", { ...domProps, href: safeHref, rel: "noopener noreferrer", target: "_blank", children });
|
|
1852
2007
|
}
|
|
1853
2008
|
function BlockedMarkdownImage({ alt }) {
|
|
1854
|
-
return alt ? /* @__PURE__ */ (0,
|
|
2009
|
+
return alt ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { "aria-label": `Image blocked: ${alt}`, role: "img", children: alt }) : null;
|
|
1855
2010
|
}
|
|
1856
2011
|
var BLOCK_MARKDOWN_TAGS = /* @__PURE__ */ new Set([
|
|
1857
2012
|
"blockquote",
|
|
@@ -1872,7 +2027,7 @@ function isMultilineCodeNode(node) {
|
|
|
1872
2027
|
return node?.tagName === "code" && node.position?.start?.line !== void 0 && node.position?.end?.line !== void 0 && node.position.start.line !== node.position.end.line;
|
|
1873
2028
|
}
|
|
1874
2029
|
function hasBlockMarkdownChild(child) {
|
|
1875
|
-
if (!
|
|
2030
|
+
if (!React7.isValidElement(child)) {
|
|
1876
2031
|
return false;
|
|
1877
2032
|
}
|
|
1878
2033
|
if (typeof child.type === "string" && BLOCK_MARKDOWN_TAGS.has(child.type)) {
|
|
@@ -1882,7 +2037,7 @@ function hasBlockMarkdownChild(child) {
|
|
|
1882
2037
|
if (BLOCK_MARKDOWN_TAGS.has(props.node?.tagName || "") || isMultilineCodeNode(props.node)) {
|
|
1883
2038
|
return true;
|
|
1884
2039
|
}
|
|
1885
|
-
return
|
|
2040
|
+
return React7.Children.toArray(props.children).some(hasBlockMarkdownChild);
|
|
1886
2041
|
}
|
|
1887
2042
|
function MessageMarkdownParagraph({
|
|
1888
2043
|
children,
|
|
@@ -1890,17 +2045,17 @@ function MessageMarkdownParagraph({
|
|
|
1890
2045
|
}) {
|
|
1891
2046
|
const domProps = { ...props };
|
|
1892
2047
|
delete domProps.node;
|
|
1893
|
-
const childArray =
|
|
2048
|
+
const childArray = React7.Children.toArray(children).filter(
|
|
1894
2049
|
(child) => child !== null && child !== ""
|
|
1895
2050
|
);
|
|
1896
|
-
const isImageOnly = childArray.length === 1 &&
|
|
2051
|
+
const isImageOnly = childArray.length === 1 && React7.isValidElement(childArray[0]) && childArray[0].props.node?.tagName === "img";
|
|
1897
2052
|
if (isImageOnly) {
|
|
1898
|
-
return /* @__PURE__ */ (0,
|
|
2053
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_jsx_runtime8.Fragment, { children });
|
|
1899
2054
|
}
|
|
1900
2055
|
if (childArray.some(hasBlockMarkdownChild)) {
|
|
1901
|
-
return /* @__PURE__ */ (0,
|
|
2056
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { ...domProps, children });
|
|
1902
2057
|
}
|
|
1903
|
-
return /* @__PURE__ */ (0,
|
|
2058
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { ...domProps, children });
|
|
1904
2059
|
}
|
|
1905
2060
|
var MESSAGE_RESPONSE_COMPONENTS = {
|
|
1906
2061
|
a: SafeMarkdownLink,
|
|
@@ -1920,7 +2075,7 @@ var MESSAGE_RESPONSE_REHYPE_PLUGINS = [
|
|
|
1920
2075
|
]
|
|
1921
2076
|
] : []
|
|
1922
2077
|
];
|
|
1923
|
-
var MessageResponse =
|
|
2078
|
+
var MessageResponse = React7.memo(
|
|
1924
2079
|
({
|
|
1925
2080
|
children,
|
|
1926
2081
|
className,
|
|
@@ -1938,11 +2093,11 @@ var MessageResponse = React5.memo(
|
|
|
1938
2093
|
maxCatchupChars: 32,
|
|
1939
2094
|
text
|
|
1940
2095
|
});
|
|
1941
|
-
const streamdownComponents =
|
|
2096
|
+
const streamdownComponents = React7.useMemo(
|
|
1942
2097
|
() => ({ ...MESSAGE_RESPONSE_COMPONENTS, ...components }),
|
|
1943
2098
|
[components]
|
|
1944
2099
|
);
|
|
1945
|
-
return /* @__PURE__ */ (0,
|
|
2100
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1946
2101
|
import_streamdown.Streamdown,
|
|
1947
2102
|
{
|
|
1948
2103
|
className: cn("a24-message-response", className),
|
|
@@ -1994,10 +2149,46 @@ function resolvedHitlLabel(part) {
|
|
|
1994
2149
|
}
|
|
1995
2150
|
|
|
1996
2151
|
// src/ui/tool-sessions.tsx
|
|
1997
|
-
var
|
|
1998
|
-
var
|
|
2152
|
+
var React8 = __toESM(require("react"), 1);
|
|
2153
|
+
var import_lucide_react6 = require("lucide-react");
|
|
1999
2154
|
var import_thinking_orbs = require("thinking-orbs");
|
|
2000
|
-
var
|
|
2155
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
2156
|
+
function toolSlotContext(isActive2, label, part, slots) {
|
|
2157
|
+
return {
|
|
2158
|
+
isActive: isActive2,
|
|
2159
|
+
label,
|
|
2160
|
+
part,
|
|
2161
|
+
resourceTargets: part.resourceTargets || [],
|
|
2162
|
+
openResource: (target) => slots?.onResourceAction?.(target, part)
|
|
2163
|
+
};
|
|
2164
|
+
}
|
|
2165
|
+
function resourceTargetName(target) {
|
|
2166
|
+
const normalized = target.path.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
2167
|
+
return normalized.split("/").filter(Boolean).pop() || "workspace";
|
|
2168
|
+
}
|
|
2169
|
+
function ToolResourceAction({ context }) {
|
|
2170
|
+
const target = context.resourceTargets[0];
|
|
2171
|
+
if (!target) return null;
|
|
2172
|
+
const name = resourceTargetName(target);
|
|
2173
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2174
|
+
"button",
|
|
2175
|
+
{
|
|
2176
|
+
"aria-label": `Open ${target.kind} ${target.path}`,
|
|
2177
|
+
className: "a24-tool-resource-action",
|
|
2178
|
+
"data-agents24-resource-path": target.path,
|
|
2179
|
+
onClick: () => context.openResource(target),
|
|
2180
|
+
title: target.path,
|
|
2181
|
+
type: "button",
|
|
2182
|
+
children: name
|
|
2183
|
+
}
|
|
2184
|
+
);
|
|
2185
|
+
}
|
|
2186
|
+
function toolAccessory(context, slots) {
|
|
2187
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
|
|
2188
|
+
slots?.onResourceAction ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ToolResourceAction, { context }) : null,
|
|
2189
|
+
slots?.renderToolAccessory?.(context)
|
|
2190
|
+
] });
|
|
2191
|
+
}
|
|
2001
2192
|
function agentChatToolLabel(part) {
|
|
2002
2193
|
const presentation = part.presentation || {};
|
|
2003
2194
|
return optionalText(presentation.activity) || optionalText(presentation.title) || optionalText(part.displayName) || optionalText(part.summary) || optionalText(part.toolName) || "Tool activity";
|
|
@@ -2071,12 +2262,12 @@ function ToolActivityReel({
|
|
|
2071
2262
|
}) {
|
|
2072
2263
|
const initial = initialLabel && initialLabel !== label ? initialLabel : label;
|
|
2073
2264
|
const parsedInitialShownAt = initialShownAt ? Date.parse(initialShownAt) : Number.NaN;
|
|
2074
|
-
const [displayed, setDisplayed] =
|
|
2075
|
-
const [previous, setPrevious] =
|
|
2076
|
-
const displayedRef =
|
|
2077
|
-
const latestRef =
|
|
2078
|
-
const shownAtRef =
|
|
2079
|
-
|
|
2265
|
+
const [displayed, setDisplayed] = React8.useState(initial);
|
|
2266
|
+
const [previous, setPrevious] = React8.useState(null);
|
|
2267
|
+
const displayedRef = React8.useRef(initial);
|
|
2268
|
+
const latestRef = React8.useRef(label);
|
|
2269
|
+
const shownAtRef = React8.useRef(Number.isFinite(parsedInitialShownAt) ? parsedInitialShownAt : Date.now());
|
|
2270
|
+
React8.useEffect(() => {
|
|
2080
2271
|
latestRef.current = label;
|
|
2081
2272
|
if (displayedRef.current === label) return;
|
|
2082
2273
|
const showLatest = () => {
|
|
@@ -2096,39 +2287,39 @@ function ToolActivityReel({
|
|
|
2096
2287
|
const timer = window.setTimeout(showLatest, remaining);
|
|
2097
2288
|
return () => window.clearTimeout(timer);
|
|
2098
2289
|
}, [label]);
|
|
2099
|
-
|
|
2290
|
+
React8.useEffect(() => {
|
|
2100
2291
|
if (!previous) return;
|
|
2101
2292
|
const timer = window.setTimeout(() => setPrevious(null), 200);
|
|
2102
2293
|
return () => window.clearTimeout(timer);
|
|
2103
2294
|
}, [previous]);
|
|
2104
|
-
return /* @__PURE__ */ (0,
|
|
2105
|
-
previous ? /* @__PURE__ */ (0,
|
|
2106
|
-
/* @__PURE__ */ (0,
|
|
2295
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "a24-tool-reel", "aria-live": announce ? "polite" : "off", children: [
|
|
2296
|
+
previous ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { "aria-hidden": "true", className: "a24-tool-reel__previous", children: previous }) : null,
|
|
2297
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: previous ? "a24-tool-reel__current" : void 0, children: displayed })
|
|
2107
2298
|
] });
|
|
2108
2299
|
}
|
|
2109
2300
|
function ToolActivityOrb({ label }) {
|
|
2110
|
-
return /* @__PURE__ */ (0,
|
|
2301
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "a24-tool-orb", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_thinking_orbs.ThinkingOrb, { "aria-label": label || "Working", size: 20, speed: 0.8, state: "searching" }) });
|
|
2111
2302
|
}
|
|
2112
2303
|
function AgentChatActivityRow({
|
|
2113
2304
|
label,
|
|
2114
2305
|
modelTurnId,
|
|
2115
2306
|
onSelect
|
|
2116
2307
|
}) {
|
|
2117
|
-
const content = /* @__PURE__ */ (0,
|
|
2118
|
-
/* @__PURE__ */ (0,
|
|
2119
|
-
/* @__PURE__ */ (0,
|
|
2308
|
+
const content = /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
|
|
2309
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ToolActivityOrb, { label }),
|
|
2310
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "a24-tool-trigger__label a24-tool-shimmer", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ToolActivityReel, { label }) })
|
|
2120
2311
|
] });
|
|
2121
|
-
return /* @__PURE__ */ (0,
|
|
2312
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "a24-tool-trigger-row a24-tool-trigger-row--root", "data-agents24-model-turn": modelTurnId, role: "status", children: onSelect ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { className: "a24-tool-trigger a24-tool-trigger--root a24-tool-trigger--active", onClick: onSelect, type: "button", children: content }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "a24-tool-trigger a24-tool-trigger--root a24-tool-trigger--active", children: content }) });
|
|
2122
2313
|
}
|
|
2123
2314
|
function AgentChatModelTurnRow({ part }) {
|
|
2124
|
-
return /* @__PURE__ */ (0,
|
|
2315
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(AgentChatActivityRow, { label: "Planning next moves", modelTurnId: part.modelTurnId });
|
|
2125
2316
|
}
|
|
2126
2317
|
function AgentChatNodeActivityRow({
|
|
2127
2318
|
onSelect,
|
|
2128
2319
|
part
|
|
2129
2320
|
}) {
|
|
2130
|
-
const [open, setOpen] =
|
|
2131
|
-
const contentId =
|
|
2321
|
+
const [open, setOpen] = React8.useState(false);
|
|
2322
|
+
const contentId = React8.useId();
|
|
2132
2323
|
const running = part.status === "running";
|
|
2133
2324
|
const failed = part.status === "failed";
|
|
2134
2325
|
const failureMessage = part.failure?.message || "The node could not complete the request.";
|
|
@@ -2139,18 +2330,18 @@ function AgentChatNodeActivityRow({
|
|
|
2139
2330
|
running && "a24-tool-trigger--active",
|
|
2140
2331
|
failed && "a24-tool-trigger--error"
|
|
2141
2332
|
);
|
|
2142
|
-
const label = running ? /* @__PURE__ */ (0,
|
|
2333
|
+
const label = running ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "a24-tool-shimmer", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ToolActivityReel, { label: part.label }) }) : part.label;
|
|
2143
2334
|
if (!failed) {
|
|
2144
|
-
return /* @__PURE__ */ (0,
|
|
2145
|
-
running ? /* @__PURE__ */ (0,
|
|
2146
|
-
/* @__PURE__ */ (0,
|
|
2147
|
-
] }) : /* @__PURE__ */ (0,
|
|
2148
|
-
running ? /* @__PURE__ */ (0,
|
|
2149
|
-
/* @__PURE__ */ (0,
|
|
2335
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "a24-tool-trigger-row", role: "status", children: onSelect ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("button", { className: triggerClassName, onClick: () => onSelect(part), type: "button", children: [
|
|
2336
|
+
running ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ToolActivityOrb, { label: part.label }) : null,
|
|
2337
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "a24-tool-trigger__label", children: label })
|
|
2338
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: triggerClassName, children: [
|
|
2339
|
+
running ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ToolActivityOrb, { label: part.label }) : null,
|
|
2340
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "a24-tool-trigger__label", children: label })
|
|
2150
2341
|
] }) });
|
|
2151
2342
|
}
|
|
2152
|
-
return /* @__PURE__ */ (0,
|
|
2153
|
-
/* @__PURE__ */ (0,
|
|
2343
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "a24-tool-disclosure", children: [
|
|
2344
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "a24-tool-trigger-row", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
2154
2345
|
"button",
|
|
2155
2346
|
{
|
|
2156
2347
|
"aria-controls": contentId,
|
|
@@ -2162,17 +2353,22 @@ function AgentChatNodeActivityRow({
|
|
|
2162
2353
|
},
|
|
2163
2354
|
type: "button",
|
|
2164
2355
|
children: [
|
|
2165
|
-
/* @__PURE__ */ (0,
|
|
2166
|
-
open ? /* @__PURE__ */ (0,
|
|
2356
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "a24-tool-trigger__label", children: label }),
|
|
2357
|
+
open ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react6.ChevronDown, { "aria-hidden": "true", className: "a24-tool-trigger__chevron" }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react6.ChevronRight, { "aria-hidden": "true", className: "a24-tool-trigger__chevron" })
|
|
2167
2358
|
]
|
|
2168
2359
|
}
|
|
2169
2360
|
) }),
|
|
2170
|
-
open ? /* @__PURE__ */ (0,
|
|
2361
|
+
open ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "a24-tool-detail a24-tool-detail--error", id: contentId, children: failureMessage }) : null
|
|
2171
2362
|
] });
|
|
2172
2363
|
}
|
|
2173
|
-
function toolRowLabel(part) {
|
|
2364
|
+
function toolRowLabel(part, separateResource = false) {
|
|
2174
2365
|
const label = agentChatToolLabel(part);
|
|
2175
|
-
|
|
2366
|
+
const lifecycleLabel = isAgentChatToolRunning(part) ? label : label.replace(/^(?:running|ran)\s+/i, "");
|
|
2367
|
+
const targetPath = separateResource ? part.resourceTargets?.[0]?.path : null;
|
|
2368
|
+
if (!targetPath) return lifecycleLabel;
|
|
2369
|
+
const candidates = [targetPath, targetPath.replace(/^\/workspace\/?/, "")].filter(Boolean).sort((left, right) => right.length - left.length);
|
|
2370
|
+
const suffix = candidates.find((candidate) => lifecycleLabel.endsWith(candidate));
|
|
2371
|
+
return suffix ? lifecycleLabel.slice(0, -suffix.length).trimEnd() : lifecycleLabel;
|
|
2176
2372
|
}
|
|
2177
2373
|
function ToolDisclosure({
|
|
2178
2374
|
children,
|
|
@@ -2188,25 +2384,25 @@ function ToolDisclosure({
|
|
|
2188
2384
|
statusLabel,
|
|
2189
2385
|
accessory
|
|
2190
2386
|
}) {
|
|
2191
|
-
const [open, setOpen] =
|
|
2192
|
-
const contentId =
|
|
2193
|
-
const expandable =
|
|
2387
|
+
const [open, setOpen] = React8.useState(false);
|
|
2388
|
+
const contentId = React8.useId();
|
|
2389
|
+
const expandable = React8.Children.toArray(children).length > 0;
|
|
2194
2390
|
if (!expandable) {
|
|
2195
2391
|
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");
|
|
2196
|
-
return /* @__PURE__ */ (0,
|
|
2197
|
-
onSelect && part ? /* @__PURE__ */ (0,
|
|
2198
|
-
showOrb ? /* @__PURE__ */ (0,
|
|
2199
|
-
/* @__PURE__ */ (0,
|
|
2200
|
-
] }) : /* @__PURE__ */ (0,
|
|
2201
|
-
showOrb ? /* @__PURE__ */ (0,
|
|
2202
|
-
/* @__PURE__ */ (0,
|
|
2392
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: cn("a24-tool-trigger-row", root && "a24-tool-trigger-row--root"), children: [
|
|
2393
|
+
onSelect && part ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("button", { className: triggerClassName, onClick: () => onSelect(part), type: "button", children: [
|
|
2394
|
+
showOrb ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ToolActivityOrb, { label: statusLabel }) : null,
|
|
2395
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "a24-tool-trigger__label", children: label })
|
|
2396
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: triggerClassName, children: [
|
|
2397
|
+
showOrb ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ToolActivityOrb, { label: statusLabel }) : null,
|
|
2398
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "a24-tool-trigger__label", children: label })
|
|
2203
2399
|
] }),
|
|
2204
2400
|
accessory
|
|
2205
2401
|
] });
|
|
2206
2402
|
}
|
|
2207
|
-
return /* @__PURE__ */ (0,
|
|
2208
|
-
/* @__PURE__ */ (0,
|
|
2209
|
-
/* @__PURE__ */ (0,
|
|
2403
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "a24-tool-disclosure", children: [
|
|
2404
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: cn("a24-tool-trigger-row", root && "a24-tool-trigger-row--root"), children: [
|
|
2405
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
2210
2406
|
"button",
|
|
2211
2407
|
{
|
|
2212
2408
|
"aria-controls": contentId,
|
|
@@ -2220,25 +2416,25 @@ function ToolDisclosure({
|
|
|
2220
2416
|
},
|
|
2221
2417
|
type: "button",
|
|
2222
2418
|
children: [
|
|
2223
|
-
showOrb ? /* @__PURE__ */ (0,
|
|
2224
|
-
/* @__PURE__ */ (0,
|
|
2225
|
-
open ? /* @__PURE__ */ (0,
|
|
2419
|
+
showOrb ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ToolActivityOrb, { label: statusLabel }) : null,
|
|
2420
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "a24-tool-trigger__label", children: label }),
|
|
2421
|
+
open ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react6.ChevronDown, { "aria-hidden": "true", className: "a24-tool-trigger__chevron" }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react6.ChevronRight, { "aria-hidden": "true", className: "a24-tool-trigger__chevron" })
|
|
2226
2422
|
]
|
|
2227
2423
|
}
|
|
2228
2424
|
),
|
|
2229
2425
|
accessory
|
|
2230
2426
|
] }),
|
|
2231
|
-
open ? /* @__PURE__ */ (0,
|
|
2427
|
+
open ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "a24-tool-disclosure__content", id: contentId, children }) : null
|
|
2232
2428
|
] });
|
|
2233
2429
|
}
|
|
2234
2430
|
function ToolLabel({ active, label, part, slots }) {
|
|
2235
|
-
const rendered = slots?.renderToolLabel?.(
|
|
2236
|
-
return active ? /* @__PURE__ */ (0,
|
|
2431
|
+
const rendered = slots?.renderToolLabel?.(toolSlotContext(active, label, part, slots)) ?? label;
|
|
2432
|
+
return active ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "a24-tool-shimmer", children: rendered }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_jsx_runtime9.Fragment, { children: rendered });
|
|
2237
2433
|
}
|
|
2238
2434
|
function ToolList({ children }) {
|
|
2239
|
-
const listRef =
|
|
2240
|
-
const [fades, setFades] =
|
|
2241
|
-
const updateFades =
|
|
2435
|
+
const listRef = React8.useRef(null);
|
|
2436
|
+
const [fades, setFades] = React8.useState({ bottom: false, top: false });
|
|
2437
|
+
const updateFades = React8.useCallback(() => {
|
|
2242
2438
|
const list = listRef.current;
|
|
2243
2439
|
if (!list) return;
|
|
2244
2440
|
const next = {
|
|
@@ -2247,7 +2443,7 @@ function ToolList({ children }) {
|
|
|
2247
2443
|
};
|
|
2248
2444
|
setFades((current) => current.bottom === next.bottom && current.top === next.top ? current : next);
|
|
2249
2445
|
}, []);
|
|
2250
|
-
|
|
2446
|
+
React8.useEffect(() => {
|
|
2251
2447
|
updateFades();
|
|
2252
2448
|
const list = listRef.current;
|
|
2253
2449
|
if (!list || typeof ResizeObserver === "undefined") return;
|
|
@@ -2255,13 +2451,13 @@ function ToolList({ children }) {
|
|
|
2255
2451
|
observer.observe(list);
|
|
2256
2452
|
return () => observer.disconnect();
|
|
2257
2453
|
}, [children, updateFades]);
|
|
2258
|
-
return /* @__PURE__ */ (0,
|
|
2454
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2259
2455
|
"div",
|
|
2260
2456
|
{
|
|
2261
2457
|
className: "a24-tool-list-frame",
|
|
2262
2458
|
"data-scroll-fade-bottom": fades.bottom ? "" : void 0,
|
|
2263
2459
|
"data-scroll-fade-top": fades.top ? "" : void 0,
|
|
2264
|
-
children: /* @__PURE__ */ (0,
|
|
2460
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "a24-tool-list", onScroll: updateFades, ref: listRef, role: "list", children })
|
|
2265
2461
|
}
|
|
2266
2462
|
);
|
|
2267
2463
|
}
|
|
@@ -2277,13 +2473,13 @@ function AgentChatToolRow({
|
|
|
2277
2473
|
const failureMessage = part.failure?.message || null;
|
|
2278
2474
|
const detail = failed ? failureMessage : optionalText(part.presentation.detail);
|
|
2279
2475
|
const hostDetails = failed ? null : slots?.renderToolDetails?.(part);
|
|
2280
|
-
const context =
|
|
2281
|
-
return /* @__PURE__ */ (0,
|
|
2476
|
+
const context = toolSlotContext(active, toolRowLabel(part, Boolean(slots?.onResourceAction)), part, slots);
|
|
2477
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { "data-agents24-tool-part": part.type, "data-state": part.state, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
2282
2478
|
ToolDisclosure,
|
|
2283
2479
|
{
|
|
2284
2480
|
error: failed,
|
|
2285
|
-
accessory:
|
|
2286
|
-
label: /* @__PURE__ */ (0,
|
|
2481
|
+
accessory: toolAccessory(context, slots),
|
|
2482
|
+
label: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ToolLabel, { active, label: context.label, part, slots }),
|
|
2287
2483
|
loading: active,
|
|
2288
2484
|
onExpandedChange: slots?.onExpandedChange,
|
|
2289
2485
|
onSelect: slots?.onToolSelect,
|
|
@@ -2292,14 +2488,14 @@ function AgentChatToolRow({
|
|
|
2292
2488
|
showOrb: showOrb ?? active,
|
|
2293
2489
|
statusLabel: active ? context.label : void 0,
|
|
2294
2490
|
children: [
|
|
2295
|
-
detail ? /* @__PURE__ */ (0,
|
|
2491
|
+
detail ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: cn("a24-tool-detail", failed && "a24-tool-detail--error"), children: detail }) : null,
|
|
2296
2492
|
hostDetails
|
|
2297
2493
|
]
|
|
2298
2494
|
}
|
|
2299
2495
|
) });
|
|
2300
2496
|
}
|
|
2301
2497
|
function sessionLabel(parts, visiblePart, running) {
|
|
2302
|
-
const label =
|
|
2498
|
+
const label = toolRowLabel(visiblePart, true);
|
|
2303
2499
|
const terminalLabel = label.replace(/^(?:running|ran)\s+/i, "");
|
|
2304
2500
|
return running ? label : `Ran ${terminalLabel} + ${parts.length - 1} more`;
|
|
2305
2501
|
}
|
|
@@ -2312,23 +2508,21 @@ function AgentChatToolSession({
|
|
|
2312
2508
|
parts,
|
|
2313
2509
|
slots
|
|
2314
2510
|
}) {
|
|
2315
|
-
const presentedLiveRef =
|
|
2511
|
+
const presentedLiveRef = React8.useRef(false);
|
|
2316
2512
|
if (isLive && isLatestActivity) presentedLiveRef.current = true;
|
|
2317
2513
|
const activeIndex = parts.findLastIndex((part) => isActive(part, activeToolId));
|
|
2318
2514
|
const running = activeIndex >= 0;
|
|
2319
|
-
if (parts.length === 1 && !modelTurn && !leadingModelTurn) return /* @__PURE__ */ (0,
|
|
2515
|
+
if (parts.length === 1 && !modelTurn && !leadingModelTurn) return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(AgentChatToolRow, { activeToolId, part: parts[0], slots });
|
|
2320
2516
|
const visibleIndex = running ? activeIndex : parts.length - 1;
|
|
2321
2517
|
const visiblePart = parts[visibleIndex];
|
|
2322
2518
|
const planning = Boolean(modelTurn);
|
|
2323
2519
|
const presentingActivity = isLatestActivity && (planning || running || isLive);
|
|
2324
2520
|
const failed = isLatestActivity && (visiblePart.state === "output-error" || visiblePart.state === "cancelled");
|
|
2325
|
-
const label = planning ? "Planning next moves" : isLive && isLatestActivity ?
|
|
2326
|
-
const labelContent = presentedLiveRef.current ? /* @__PURE__ */ (0,
|
|
2327
|
-
|
|
2328
|
-
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2521
|
+
const label = planning ? "Planning next moves" : isLive && isLatestActivity ? toolRowLabel(visiblePart, true) : sessionLabel(parts, visiblePart, running);
|
|
2522
|
+
const labelContent = presentedLiveRef.current ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: presentingActivity ? "a24-tool-shimmer" : void 0, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ToolActivityReel, { initialLabel: leadingModelTurn ? "Planning next moves" : void 0, initialShownAt: leadingModelTurn?.timestamp, label }) }) : label;
|
|
2523
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2329
2524
|
ToolDisclosure,
|
|
2330
2525
|
{
|
|
2331
|
-
accessory: slots?.renderToolAccessory?.(context),
|
|
2332
2526
|
error: failed,
|
|
2333
2527
|
grouped: true,
|
|
2334
2528
|
label: labelContent,
|
|
@@ -2338,7 +2532,7 @@ function AgentChatToolSession({
|
|
|
2338
2532
|
root: true,
|
|
2339
2533
|
showOrb: isLive && isLatestActivity,
|
|
2340
2534
|
statusLabel: planning ? "Planning next moves" : label,
|
|
2341
|
-
children: /* @__PURE__ */ (0,
|
|
2535
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ToolList, { children: parts.map((part) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { role: "listitem", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(AgentChatToolRow, { activeToolId, part, root: false, showOrb: false, slots }) }, part.id)) })
|
|
2342
2536
|
}
|
|
2343
2537
|
);
|
|
2344
2538
|
}
|
|
@@ -2359,7 +2553,7 @@ function subagentLabel(part) {
|
|
|
2359
2553
|
return { label: `Agent ${name}, ran ${children.length} ${children.length === 1 ? "tool" : "tools"}`, running: false };
|
|
2360
2554
|
}
|
|
2361
2555
|
function AgentChatSubagentGroup({ isLatestActivity = true, isLive = false, part, slots }) {
|
|
2362
|
-
const presentedLiveRef =
|
|
2556
|
+
const presentedLiveRef = React8.useRef(false);
|
|
2363
2557
|
if (isLive && isLatestActivity) presentedLiveRef.current = true;
|
|
2364
2558
|
const children = part.presentation.childTools || [];
|
|
2365
2559
|
const state = subagentLabel(part);
|
|
@@ -2368,9 +2562,9 @@ function AgentChatSubagentGroup({ isLatestActivity = true, isLive = false, part,
|
|
|
2368
2562
|
const hostDetails = failed ? null : slots?.renderToolDetails?.(part);
|
|
2369
2563
|
const failureMessage = part.failure?.message || null;
|
|
2370
2564
|
const presentingActivity = isLatestActivity && state.running;
|
|
2371
|
-
const labelContent = presentedLiveRef.current ? /* @__PURE__ */ (0,
|
|
2372
|
-
const context =
|
|
2373
|
-
return /* @__PURE__ */ (0,
|
|
2565
|
+
const labelContent = presentedLiveRef.current ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: presentingActivity ? "a24-tool-shimmer" : void 0, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ToolActivityReel, { label: state.label }) }) : state.label;
|
|
2566
|
+
const context = toolSlotContext(presentingActivity, state.label, part, slots);
|
|
2567
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2374
2568
|
ToolDisclosure,
|
|
2375
2569
|
{
|
|
2376
2570
|
accessory: slots?.renderToolAccessory?.(context),
|
|
@@ -2383,12 +2577,12 @@ function AgentChatSubagentGroup({ isLatestActivity = true, isLive = false, part,
|
|
|
2383
2577
|
root: true,
|
|
2384
2578
|
showOrb: isLive && isLatestActivity,
|
|
2385
2579
|
statusLabel: state.label,
|
|
2386
|
-
children: /* @__PURE__ */ (0,
|
|
2387
|
-
children.map((child) => /* @__PURE__ */ (0,
|
|
2388
|
-
/* @__PURE__ */ (0,
|
|
2389
|
-
child.detail ? /* @__PURE__ */ (0,
|
|
2580
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(ToolList, { children: [
|
|
2581
|
+
children.map((child) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: cn("a24-child-tool", child.status === "failed" && "a24-child-tool--error"), role: "listitem", children: slots?.renderChildTool?.(child, part) ?? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
|
|
2582
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: cn(isLive && isLatestActivity && child.status === "running" && "a24-tool-shimmer"), children: childLabel(child) }),
|
|
2583
|
+
child.detail ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "a24-child-tool__detail", children: child.detail }) : null
|
|
2390
2584
|
] }) }, child.id)),
|
|
2391
|
-
failureMessage ? /* @__PURE__ */ (0,
|
|
2585
|
+
failureMessage ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "a24-tool-detail a24-tool-detail--error", children: failureMessage }) : null,
|
|
2392
2586
|
hostDetails
|
|
2393
2587
|
] })
|
|
2394
2588
|
}
|
|
@@ -2396,24 +2590,24 @@ function AgentChatSubagentGroup({ isLatestActivity = true, isLive = false, part,
|
|
|
2396
2590
|
}
|
|
2397
2591
|
|
|
2398
2592
|
// src/ui/agent-response-timeline.tsx
|
|
2399
|
-
var
|
|
2593
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
2400
2594
|
function isInternalAskUserTool(part) {
|
|
2401
2595
|
return [part.toolName, part.toolKey, part.action].some((value) => value?.trim().toLowerCase() === "runtime__ask_user");
|
|
2402
2596
|
}
|
|
2403
2597
|
function Shimmer({ children, className }) {
|
|
2404
|
-
return /* @__PURE__ */ (0,
|
|
2598
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: cn("inline-block animate-pulse", className), children });
|
|
2405
2599
|
}
|
|
2406
2600
|
function AgentChatToolPart({
|
|
2407
2601
|
activeToolId,
|
|
2408
2602
|
part
|
|
2409
2603
|
}) {
|
|
2410
|
-
return /* @__PURE__ */ (0,
|
|
2604
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(AgentChatToolRow, { activeToolId, part });
|
|
2411
2605
|
}
|
|
2412
2606
|
function AgentChatToolGroup({
|
|
2413
2607
|
activeToolId,
|
|
2414
2608
|
parts
|
|
2415
2609
|
}) {
|
|
2416
|
-
return /* @__PURE__ */ (0,
|
|
2610
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(AgentChatToolSession, { activeToolId, parts });
|
|
2417
2611
|
}
|
|
2418
2612
|
function HitlPartRow({
|
|
2419
2613
|
getHitlActionState,
|
|
@@ -2422,18 +2616,18 @@ function HitlPartRow({
|
|
|
2422
2616
|
part
|
|
2423
2617
|
}) {
|
|
2424
2618
|
const state = getHitlActionState?.(part);
|
|
2425
|
-
const [comment, setComment] =
|
|
2619
|
+
const [comment, setComment] = React9.useState("");
|
|
2426
2620
|
const presentation = part.presentation || {};
|
|
2427
2621
|
const requireComment = presentation.require_comment === true;
|
|
2428
2622
|
const isTerminal = part.status !== "pending";
|
|
2429
|
-
const resolvedRef =
|
|
2430
|
-
const wasTerminal =
|
|
2431
|
-
|
|
2623
|
+
const resolvedRef = React9.useRef(null);
|
|
2624
|
+
const wasTerminal = React9.useRef(isTerminal);
|
|
2625
|
+
React9.useEffect(() => {
|
|
2432
2626
|
if (isTerminal && !wasTerminal.current) resolvedRef.current?.focus();
|
|
2433
2627
|
wasTerminal.current = isTerminal;
|
|
2434
2628
|
}, [isTerminal]);
|
|
2435
2629
|
if (part.hitlKind === "user_input") {
|
|
2436
|
-
return /* @__PURE__ */ (0,
|
|
2630
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2437
2631
|
AskUserInteraction,
|
|
2438
2632
|
{
|
|
2439
2633
|
error: state?.error,
|
|
@@ -2451,11 +2645,11 @@ function HitlPartRow({
|
|
|
2451
2645
|
);
|
|
2452
2646
|
}
|
|
2453
2647
|
if (isTerminal) {
|
|
2454
|
-
return /* @__PURE__ */ (0,
|
|
2648
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("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) });
|
|
2455
2649
|
}
|
|
2456
|
-
return /* @__PURE__ */ (0,
|
|
2457
|
-
/* @__PURE__ */ (0,
|
|
2458
|
-
requireComment ? /* @__PURE__ */ (0,
|
|
2650
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "a24-hitl space-y-2.5 px-1 py-2", children: [
|
|
2651
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "a24-hitl__title text-sm font-medium text-foreground text-pretty", children: hitlTitle(part) }),
|
|
2652
|
+
requireComment ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2459
2653
|
"textarea",
|
|
2460
2654
|
{
|
|
2461
2655
|
"aria-label": "Approval comment",
|
|
@@ -2467,8 +2661,8 @@ function HitlPartRow({
|
|
|
2467
2661
|
value: comment
|
|
2468
2662
|
}
|
|
2469
2663
|
) : null,
|
|
2470
|
-
state?.error ? /* @__PURE__ */ (0,
|
|
2471
|
-
/* @__PURE__ */ (0,
|
|
2664
|
+
state?.error ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "a24-hitl__error text-sm text-destructive", children: state.error }) : null,
|
|
2665
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "a24-hitl__actions flex flex-wrap items-center gap-1.5", children: part.allowedActions.map((action) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2472
2666
|
"button",
|
|
2473
2667
|
{
|
|
2474
2668
|
"aria-label": hitlActionLabel(part, action),
|
|
@@ -2501,7 +2695,7 @@ function AgentChatPart({
|
|
|
2501
2695
|
toolSlots
|
|
2502
2696
|
}) {
|
|
2503
2697
|
if (part.kind === "text") {
|
|
2504
|
-
return /* @__PURE__ */ (0,
|
|
2698
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2505
2699
|
MessageResponse,
|
|
2506
2700
|
{
|
|
2507
2701
|
...responseProps,
|
|
@@ -2511,23 +2705,23 @@ function AgentChatPart({
|
|
|
2511
2705
|
}
|
|
2512
2706
|
);
|
|
2513
2707
|
}
|
|
2514
|
-
if (part.kind === "tool") return isAgentChatSubagent(part) ? /* @__PURE__ */ (0,
|
|
2515
|
-
if (part.kind === "model-turn") return /* @__PURE__ */ (0,
|
|
2708
|
+
if (part.kind === "tool") return isAgentChatSubagent(part) ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(AgentChatSubagentGroup, { part, slots: toolSlots }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(AgentChatToolRow, { activeToolId, part, slots: toolSlots });
|
|
2709
|
+
if (part.kind === "model-turn") return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(AgentChatModelTurnRow, { part });
|
|
2516
2710
|
if (part.kind === "reasoning") {
|
|
2517
2711
|
const label = part.text || part.label || "Thinking";
|
|
2518
|
-
return part.status === "running" || part.status === "streaming" ? /* @__PURE__ */ (0,
|
|
2712
|
+
return part.status === "running" || part.status === "streaming" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Shimmer, { className: "text-sm text-muted-foreground", children: label }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "text-sm text-muted-foreground", children: label });
|
|
2519
2713
|
}
|
|
2520
2714
|
if (part.kind === "context-compression") {
|
|
2521
|
-
return /* @__PURE__ */ (0,
|
|
2715
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(AgentChatContextCompressionRow, { part });
|
|
2522
2716
|
}
|
|
2523
2717
|
if (part.kind === "ui-blocks") {
|
|
2524
2718
|
if (part.state === "output-error") {
|
|
2525
|
-
return /* @__PURE__ */ (0,
|
|
2719
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "a24-timeline-error text-sm text-destructive", children: part.errorText || "Failed to render UI content." });
|
|
2526
2720
|
}
|
|
2527
|
-
return part.bundle ? /* @__PURE__ */ (0,
|
|
2721
|
+
return part.bundle ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SafeUiBlocks, { bundle: part.bundle }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "text-sm text-muted-foreground", children: part.state === "input-streaming" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Shimmer, { children: "Rendering UI block" }) : "Rendered UI block" });
|
|
2528
2722
|
}
|
|
2529
2723
|
if (part.kind === "hitl") {
|
|
2530
|
-
return /* @__PURE__ */ (0,
|
|
2724
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2531
2725
|
HitlPartRow,
|
|
2532
2726
|
{
|
|
2533
2727
|
getHitlActionState,
|
|
@@ -2537,18 +2731,18 @@ function AgentChatPart({
|
|
|
2537
2731
|
}
|
|
2538
2732
|
);
|
|
2539
2733
|
}
|
|
2540
|
-
if (part.kind === "error") return /* @__PURE__ */ (0,
|
|
2734
|
+
if (part.kind === "error") return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "a24-timeline-error text-sm text-destructive", role: "alert", children: part.errorText });
|
|
2541
2735
|
if (part.kind === "source") {
|
|
2542
2736
|
const href = safeExternalUrl(part.url);
|
|
2543
|
-
return href ? /* @__PURE__ */ (0,
|
|
2737
|
+
return href ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("a", { className: "a24-source-link", href, rel: "noopener noreferrer", target: "_blank", children: part.title }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "a24-source-link", children: part.title });
|
|
2544
2738
|
}
|
|
2545
2739
|
if (part.kind === "citation") {
|
|
2546
2740
|
const href = safeExternalUrl(part.url);
|
|
2547
2741
|
const label = part.label || "Citation";
|
|
2548
|
-
return href ? /* @__PURE__ */ (0,
|
|
2742
|
+
return href ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("a", { className: "a24-citation", href, rel: "noopener noreferrer", target: "_blank", children: label }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "a24-citation", children: label });
|
|
2549
2743
|
}
|
|
2550
|
-
if (part.kind === "attachment") return /* @__PURE__ */ (0,
|
|
2551
|
-
if (part.kind === "data") return /* @__PURE__ */ (0,
|
|
2744
|
+
if (part.kind === "attachment") return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "a24-output-attachment", children: part.attachment.filename || "Attachment" });
|
|
2745
|
+
if (part.kind === "data") return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { "data-agents24-data-part": part.name, className: "hidden", children: message.id });
|
|
2552
2746
|
return null;
|
|
2553
2747
|
}
|
|
2554
2748
|
function safeExternalUrl(value) {
|
|
@@ -2562,28 +2756,28 @@ function safeExternalUrl(value) {
|
|
|
2562
2756
|
}
|
|
2563
2757
|
function SafeUiBlocks({ bundle }) {
|
|
2564
2758
|
const rows = Array.isArray(bundle.rows) ? bundle.rows : [];
|
|
2565
|
-
return /* @__PURE__ */ (0,
|
|
2566
|
-
typeof bundle.title === "string" ? /* @__PURE__ */ (0,
|
|
2759
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("section", { "aria-label": typeof bundle.title === "string" ? bundle.title : "Agent result", className: "a24-ui-blocks", children: [
|
|
2760
|
+
typeof bundle.title === "string" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h3", { children: bundle.title }) : null,
|
|
2567
2761
|
rows.map((rawRow, rowIndex) => {
|
|
2568
2762
|
const row = rawRow && typeof rawRow === "object" && !Array.isArray(rawRow) ? rawRow : {};
|
|
2569
2763
|
const blocks = Array.isArray(row.blocks) ? row.blocks : [];
|
|
2570
|
-
return /* @__PURE__ */ (0,
|
|
2764
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "a24-ui-blocks__row", children: blocks.map((rawBlock, blockIndex) => {
|
|
2571
2765
|
const block = rawBlock && typeof rawBlock === "object" && !Array.isArray(rawBlock) ? rawBlock : {};
|
|
2572
2766
|
const title = typeof block.title === "string" ? block.title : "Result";
|
|
2573
2767
|
const kind = String(block.kind || "note");
|
|
2574
2768
|
if (kind === "table" && Array.isArray(block.columns) && Array.isArray(block.rows)) {
|
|
2575
|
-
return /* @__PURE__ */ (0,
|
|
2576
|
-
/* @__PURE__ */ (0,
|
|
2577
|
-
/* @__PURE__ */ (0,
|
|
2578
|
-
/* @__PURE__ */ (0,
|
|
2579
|
-
/* @__PURE__ */ (0,
|
|
2769
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "a24-ui-block", children: [
|
|
2770
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h4", { children: title }),
|
|
2771
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "a24-ui-table-scroll", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("table", { children: [
|
|
2772
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("tr", { children: block.columns.map((column, index) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("th", { children: String(column) }, index)) }) }),
|
|
2773
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("tbody", { children: block.rows.map((rawCells, index) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("tr", { children: (Array.isArray(rawCells) ? rawCells : []).map((cell, cellIndex) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("td", { children: String(cell) }, cellIndex)) }, index)) })
|
|
2580
2774
|
] }) })
|
|
2581
2775
|
] }, String(block.id || blockIndex));
|
|
2582
2776
|
}
|
|
2583
2777
|
const value = block.value ?? block.text ?? "";
|
|
2584
|
-
return /* @__PURE__ */ (0,
|
|
2585
|
-
/* @__PURE__ */ (0,
|
|
2586
|
-
/* @__PURE__ */ (0,
|
|
2778
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "a24-ui-block", children: [
|
|
2779
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h4", { children: title }),
|
|
2780
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { children: String(value) })
|
|
2587
2781
|
] }, String(block.id || blockIndex));
|
|
2588
2782
|
}) }, `row-${rowIndex}`);
|
|
2589
2783
|
})
|
|
@@ -2595,7 +2789,9 @@ function AgentResponseTimeline({
|
|
|
2595
2789
|
message,
|
|
2596
2790
|
nodeActivityMode = "default",
|
|
2597
2791
|
onHitlAction,
|
|
2792
|
+
onNodeSelect,
|
|
2598
2793
|
parts: displayParts,
|
|
2794
|
+
renderUiBlocks,
|
|
2599
2795
|
responseProps,
|
|
2600
2796
|
toolSlots,
|
|
2601
2797
|
toolViewMode = "closed"
|
|
@@ -2614,34 +2810,38 @@ function AgentResponseTimeline({
|
|
|
2614
2810
|
if (segment.kind === "tool") {
|
|
2615
2811
|
const isLatestActivity = segmentIndex === segments.length - 1;
|
|
2616
2812
|
const showOrb = toolViewMode === "closed" ? isLoading && isLatestActivity : Boolean(activeToolId && (segment.part.id === activeToolId || segment.part.toolCallId === activeToolId));
|
|
2617
|
-
rendered.push(/* @__PURE__ */ (0,
|
|
2813
|
+
rendered.push(/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(AgentChatToolRow, { activeToolId, part: segment.part, showOrb, slots: toolSlots }, segment.part.id));
|
|
2618
2814
|
continue;
|
|
2619
2815
|
}
|
|
2620
2816
|
if (segment.kind === "tool-session") {
|
|
2621
|
-
rendered.push(/* @__PURE__ */ (0,
|
|
2817
|
+
rendered.push(/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(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}`));
|
|
2622
2818
|
continue;
|
|
2623
2819
|
}
|
|
2624
2820
|
if (segment.kind === "subagent") {
|
|
2625
|
-
rendered.push(/* @__PURE__ */ (0,
|
|
2821
|
+
rendered.push(/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(AgentChatSubagentGroup, { isLatestActivity: segmentIndex === segments.length - 1, isLive: isLoading, part: segment.part, slots: toolSlots }, segment.part.id));
|
|
2626
2822
|
continue;
|
|
2627
2823
|
}
|
|
2628
2824
|
const part = segment.part;
|
|
2629
2825
|
if (part.kind === "model-turn") {
|
|
2630
2826
|
const key = activeActivityClaimed ? part.id : `${message.id}-active-activity`;
|
|
2631
2827
|
activeActivityClaimed = true;
|
|
2632
|
-
rendered.push(/* @__PURE__ */ (0,
|
|
2828
|
+
rendered.push(/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(AgentChatActivityRow, { label: "Planning next moves", modelTurnId: part.modelTurnId }, key));
|
|
2633
2829
|
continue;
|
|
2634
2830
|
}
|
|
2635
2831
|
if (part.kind === "node-activity") {
|
|
2636
2832
|
const key = activeActivityClaimed ? part.id : `${message.id}-active-activity`;
|
|
2637
2833
|
if (part.status === "running") activeActivityClaimed = true;
|
|
2638
2834
|
rendered.push(
|
|
2639
|
-
part.status === "running" ? /* @__PURE__ */ (0,
|
|
2835
|
+
part.status === "running" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(AgentChatActivityRow, { label: part.label, onSelect: onNodeSelect ? () => onNodeSelect(part) : void 0 }, key) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(AgentChatNodeActivityRow, { onSelect: onNodeSelect, part }, part.id)
|
|
2640
2836
|
);
|
|
2641
2837
|
continue;
|
|
2642
2838
|
}
|
|
2839
|
+
if (part.kind === "ui-blocks" && renderUiBlocks) {
|
|
2840
|
+
rendered.push(/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(React9.Fragment, { children: renderUiBlocks(part) }, part.id));
|
|
2841
|
+
continue;
|
|
2842
|
+
}
|
|
2643
2843
|
rendered.push(
|
|
2644
|
-
/* @__PURE__ */ (0,
|
|
2844
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(React9.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2645
2845
|
AgentChatPart,
|
|
2646
2846
|
{
|
|
2647
2847
|
activeToolId,
|
|
@@ -2658,16 +2858,16 @@ function AgentResponseTimeline({
|
|
|
2658
2858
|
);
|
|
2659
2859
|
}
|
|
2660
2860
|
if (rendered.length === 0 && message.content) {
|
|
2661
|
-
rendered.push(/* @__PURE__ */ (0,
|
|
2861
|
+
rendered.push(/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(MessageResponse, { children: message.content }, `${message.id}-fallback`));
|
|
2662
2862
|
}
|
|
2663
2863
|
if (rendered.length === 0 && isLoading) {
|
|
2664
|
-
rendered.push(/* @__PURE__ */ (0,
|
|
2864
|
+
rendered.push(/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(AgentChatActivityRow, { label: "Thinking" }, `${message.id}-active-activity`));
|
|
2665
2865
|
}
|
|
2666
|
-
return /* @__PURE__ */ (0,
|
|
2866
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "space-y-3", children: rendered });
|
|
2667
2867
|
}
|
|
2668
2868
|
|
|
2669
2869
|
// src/ui/agent-chat-message.tsx
|
|
2670
|
-
var
|
|
2870
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
2671
2871
|
var DEFAULT_USER_MESSAGE_COLLAPSE_THRESHOLD = 360;
|
|
2672
2872
|
var DEFAULT_USER_MESSAGE_COLLAPSED_LINES = 4;
|
|
2673
2873
|
function shouldCollapseUserMessage(content, threshold = DEFAULT_USER_MESSAGE_COLLAPSE_THRESHOLD) {
|
|
@@ -2680,19 +2880,19 @@ function AgentChatUserMessageContent({
|
|
|
2680
2880
|
showLessLabel = "Show less",
|
|
2681
2881
|
showMoreLabel = "Show more"
|
|
2682
2882
|
}) {
|
|
2683
|
-
const [isExpanded, setIsExpanded] =
|
|
2684
|
-
const contentId =
|
|
2883
|
+
const [isExpanded, setIsExpanded] = React10.useState(false);
|
|
2884
|
+
const contentId = React10.useId();
|
|
2685
2885
|
const shouldCollapse = shouldCollapseUserMessage(content, collapseThreshold);
|
|
2686
|
-
const Icon = isExpanded ?
|
|
2886
|
+
const Icon = isExpanded ? import_lucide_react7.ChevronUp : import_lucide_react7.ChevronDown;
|
|
2687
2887
|
const clampedStyle = shouldCollapse && !isExpanded ? {
|
|
2688
2888
|
WebkitBoxOrient: "vertical",
|
|
2689
2889
|
WebkitLineClamp: Math.max(1, collapsedLines),
|
|
2690
2890
|
display: "-webkit-box",
|
|
2691
2891
|
overflow: "hidden"
|
|
2692
2892
|
} : void 0;
|
|
2693
|
-
return /* @__PURE__ */ (0,
|
|
2694
|
-
/* @__PURE__ */ (0,
|
|
2695
|
-
shouldCollapse ? /* @__PURE__ */ (0,
|
|
2893
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex min-w-0 flex-col gap-3", children: [
|
|
2894
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { id: contentId, className: "min-w-0", style: clampedStyle, children: content }),
|
|
2895
|
+
shouldCollapse ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
2696
2896
|
"button",
|
|
2697
2897
|
{
|
|
2698
2898
|
"aria-controls": contentId,
|
|
@@ -2705,7 +2905,7 @@ function AgentChatUserMessageContent({
|
|
|
2705
2905
|
type: "button",
|
|
2706
2906
|
children: [
|
|
2707
2907
|
isExpanded ? showLessLabel : showMoreLabel,
|
|
2708
|
-
/* @__PURE__ */ (0,
|
|
2908
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Icon, { "aria-hidden": "true", className: "size-4", strokeWidth: 2 })
|
|
2709
2909
|
]
|
|
2710
2910
|
}
|
|
2711
2911
|
) : null
|
|
@@ -2715,9 +2915,9 @@ function AgentChatUserMessageActionRow({
|
|
|
2715
2915
|
children,
|
|
2716
2916
|
className
|
|
2717
2917
|
}) {
|
|
2718
|
-
const rowRef =
|
|
2719
|
-
const [visible, setVisible] =
|
|
2720
|
-
|
|
2918
|
+
const rowRef = React10.useRef(null);
|
|
2919
|
+
const [visible, setVisible] = React10.useState(false);
|
|
2920
|
+
React10.useEffect(() => {
|
|
2721
2921
|
const message = rowRef.current?.closest('[data-slot="message"]');
|
|
2722
2922
|
if (!message) return;
|
|
2723
2923
|
const show = () => setVisible(true);
|
|
@@ -2736,7 +2936,7 @@ function AgentChatUserMessageActionRow({
|
|
|
2736
2936
|
message.removeEventListener("focusout", hideWhenFocusLeaves);
|
|
2737
2937
|
};
|
|
2738
2938
|
}, []);
|
|
2739
|
-
return /* @__PURE__ */ (0,
|
|
2939
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2740
2940
|
"div",
|
|
2741
2941
|
{
|
|
2742
2942
|
ref: rowRef,
|
|
@@ -2775,7 +2975,7 @@ function AgentChatMessage({
|
|
|
2775
2975
|
const resolvedUserContent = userMessageContent ?? message.content;
|
|
2776
2976
|
const shouldRenderContent = isAssistant || Boolean(renderUserContent || resolvedUserContent);
|
|
2777
2977
|
const showAttachments = Boolean(message.attachments?.length) && (message.role === "user" || showAssistantAttachments);
|
|
2778
|
-
const renderedActions = actions ?? (actionHandlers ? /* @__PURE__ */ (0,
|
|
2978
|
+
const renderedActions = actions ?? (actionHandlers ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2779
2979
|
AgentChatDefaultActions,
|
|
2780
2980
|
{
|
|
2781
2981
|
additionalActions,
|
|
@@ -2785,14 +2985,14 @@ function AgentChatMessage({
|
|
|
2785
2985
|
}
|
|
2786
2986
|
) : null);
|
|
2787
2987
|
const defaultUserActions = !actions && Boolean(actionHandlers) && !isAssistant;
|
|
2788
|
-
return /* @__PURE__ */ (0,
|
|
2988
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
2789
2989
|
ChatMessage,
|
|
2790
2990
|
{
|
|
2791
2991
|
className,
|
|
2792
2992
|
dir,
|
|
2793
2993
|
from: message.role,
|
|
2794
2994
|
children: [
|
|
2795
|
-
showAttachments ? /* @__PURE__ */ (0,
|
|
2995
|
+
showAttachments ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2796
2996
|
ChatAttachmentRows,
|
|
2797
2997
|
{
|
|
2798
2998
|
attachments: message.attachments || [],
|
|
@@ -2801,14 +3001,14 @@ function AgentChatMessage({
|
|
|
2801
3001
|
resolveContent: attachmentContentResolver
|
|
2802
3002
|
}
|
|
2803
3003
|
) : null,
|
|
2804
|
-
shouldRenderContent ? /* @__PURE__ */ (0,
|
|
3004
|
+
shouldRenderContent ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
2805
3005
|
ChatMessageContent,
|
|
2806
3006
|
{
|
|
2807
3007
|
className: cn(isAssistant ? "bg-transparent p-0" : void 0, contentClassName),
|
|
2808
3008
|
dir,
|
|
2809
3009
|
from: message.role,
|
|
2810
3010
|
children: [
|
|
2811
|
-
isAssistant ? renderAssistantContent ? renderAssistantContent({ isStreaming, message }) : /* @__PURE__ */ (0,
|
|
3011
|
+
isAssistant ? renderAssistantContent ? renderAssistantContent({ isStreaming, message }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2812
3012
|
Timeline,
|
|
2813
3013
|
{
|
|
2814
3014
|
getHitlActionState,
|
|
@@ -2819,7 +3019,7 @@ function AgentChatMessage({
|
|
|
2819
3019
|
parts: message.parts
|
|
2820
3020
|
}
|
|
2821
3021
|
) : null,
|
|
2822
|
-
!isAssistant ? renderUserContent ? renderUserContent({ message }) : resolvedUserContent ? /* @__PURE__ */ (0,
|
|
3022
|
+
!isAssistant ? renderUserContent ? renderUserContent({ message }) : resolvedUserContent ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2823
3023
|
AgentChatUserMessageContent,
|
|
2824
3024
|
{
|
|
2825
3025
|
collapsedLines: userMessageCollapsedLines,
|
|
@@ -2832,15 +3032,15 @@ function AgentChatMessage({
|
|
|
2832
3032
|
]
|
|
2833
3033
|
}
|
|
2834
3034
|
) : null,
|
|
2835
|
-
renderedActions ? defaultUserActions ? /* @__PURE__ */ (0,
|
|
3035
|
+
renderedActions ? defaultUserActions ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(AgentChatUserMessageActionRow, { className: actionsClassName, children: renderedActions }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: cn(dir === "rtl" ? "mt-1 h-9 w-full" : "mt-1 h-9 w-full -translate-x-2", actionsClassName), children: renderedActions }) : null
|
|
2836
3036
|
]
|
|
2837
3037
|
}
|
|
2838
3038
|
);
|
|
2839
3039
|
}
|
|
2840
3040
|
|
|
2841
3041
|
// src/ui/agent-chat-context-status.tsx
|
|
2842
|
-
var
|
|
2843
|
-
var
|
|
3042
|
+
var React11 = __toESM(require("react"), 1);
|
|
3043
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
2844
3044
|
var COMPACT_TOKENS = new Intl.NumberFormat("en-US", { notation: "compact" });
|
|
2845
3045
|
var PERCENT = new Intl.NumberFormat("en-US", {
|
|
2846
3046
|
style: "percent",
|
|
@@ -2863,13 +3063,13 @@ function AgentChatContextStatus({
|
|
|
2863
3063
|
className,
|
|
2864
3064
|
contextWindow
|
|
2865
3065
|
}) {
|
|
2866
|
-
const tooltipId =
|
|
2867
|
-
const [open, setOpen] =
|
|
3066
|
+
const tooltipId = React11.useId();
|
|
3067
|
+
const [open, setOpen] = React11.useState(false);
|
|
2868
3068
|
const { maximum, input, admissionInput, usageRatio, admissionRatio } = contextStatusMetrics(contextWindow);
|
|
2869
3069
|
const percentage = Math.round(usageRatio * 100);
|
|
2870
3070
|
const exact = EXACT_SOURCES.has(contextWindow?.source || "unknown");
|
|
2871
3071
|
if (!Number.isFinite(maximum) || maximum <= 0) return null;
|
|
2872
|
-
return /* @__PURE__ */ (0,
|
|
3072
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
2873
3073
|
"div",
|
|
2874
3074
|
{
|
|
2875
3075
|
className: cn("a24-context-status", className),
|
|
@@ -2880,7 +3080,7 @@ function AgentChatContextStatus({
|
|
|
2880
3080
|
onMouseEnter: () => setOpen(true),
|
|
2881
3081
|
onMouseLeave: () => setOpen(false),
|
|
2882
3082
|
children: [
|
|
2883
|
-
/* @__PURE__ */ (0,
|
|
3083
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
2884
3084
|
"button",
|
|
2885
3085
|
{
|
|
2886
3086
|
"aria-describedby": open ? tooltipId : void 0,
|
|
@@ -2891,9 +3091,9 @@ function AgentChatContextStatus({
|
|
|
2891
3091
|
},
|
|
2892
3092
|
type: "button",
|
|
2893
3093
|
children: [
|
|
2894
|
-
/* @__PURE__ */ (0,
|
|
2895
|
-
/* @__PURE__ */ (0,
|
|
2896
|
-
/* @__PURE__ */ (0,
|
|
3094
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("svg", { "aria-hidden": "true", className: "a24-context-status__ring", viewBox: "0 0 24 24", children: [
|
|
3095
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("circle", { className: "a24-context-status__track", cx: "12", cy: "12", r: "10" }),
|
|
3096
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2897
3097
|
"circle",
|
|
2898
3098
|
{
|
|
2899
3099
|
className: "a24-context-status__value",
|
|
@@ -2905,20 +3105,20 @@ function AgentChatContextStatus({
|
|
|
2905
3105
|
}
|
|
2906
3106
|
)
|
|
2907
3107
|
] }),
|
|
2908
|
-
/* @__PURE__ */ (0,
|
|
3108
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { children: [
|
|
2909
3109
|
percentage,
|
|
2910
3110
|
"%"
|
|
2911
3111
|
] })
|
|
2912
3112
|
]
|
|
2913
3113
|
}
|
|
2914
3114
|
),
|
|
2915
|
-
open ? /* @__PURE__ */ (0,
|
|
2916
|
-
/* @__PURE__ */ (0,
|
|
2917
|
-
/* @__PURE__ */ (0,
|
|
3115
|
+
open ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "a24-context-status__popover", id: tooltipId, role: "tooltip", children: [
|
|
3116
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "a24-context-status__sr-only", children: "Context window" }),
|
|
3117
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("strong", { children: [
|
|
2918
3118
|
PERCENT.format(usageRatio),
|
|
2919
3119
|
" context used"
|
|
2920
3120
|
] }),
|
|
2921
|
-
/* @__PURE__ */ (0,
|
|
3121
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { children: [
|
|
2922
3122
|
exact ? "Input" : "Estimated input",
|
|
2923
3123
|
": ",
|
|
2924
3124
|
COMPACT_TOKENS.format(input),
|
|
@@ -2926,7 +3126,7 @@ function AgentChatContextStatus({
|
|
|
2926
3126
|
COMPACT_TOKENS.format(maximum),
|
|
2927
3127
|
" tokens"
|
|
2928
3128
|
] }),
|
|
2929
|
-
admissionInput !== input ? /* @__PURE__ */ (0,
|
|
3129
|
+
admissionInput !== input ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { children: [
|
|
2930
3130
|
"Safety bound: ",
|
|
2931
3131
|
COMPACT_TOKENS.format(admissionInput),
|
|
2932
3132
|
" tokens (",
|
|
@@ -2942,9 +3142,9 @@ function AgentChatContextStatus({
|
|
|
2942
3142
|
// src/ui/bubble.tsx
|
|
2943
3143
|
var import_class_variance_authority2 = require("class-variance-authority");
|
|
2944
3144
|
var import_react_slot2 = require("@radix-ui/react-slot");
|
|
2945
|
-
var
|
|
3145
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
2946
3146
|
function BubbleGroup({ className, ...props }) {
|
|
2947
|
-
return /* @__PURE__ */ (0,
|
|
3147
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2948
3148
|
"div",
|
|
2949
3149
|
{
|
|
2950
3150
|
"data-slot": "bubble-group",
|
|
@@ -2978,7 +3178,7 @@ function Bubble({
|
|
|
2978
3178
|
className,
|
|
2979
3179
|
...props
|
|
2980
3180
|
}) {
|
|
2981
|
-
return /* @__PURE__ */ (0,
|
|
3181
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2982
3182
|
"div",
|
|
2983
3183
|
{
|
|
2984
3184
|
"data-slot": "bubble",
|
|
@@ -2995,7 +3195,7 @@ function BubbleContent({
|
|
|
2995
3195
|
...props
|
|
2996
3196
|
}) {
|
|
2997
3197
|
const Comp = asChild ? import_react_slot2.Slot : "div";
|
|
2998
|
-
return /* @__PURE__ */ (0,
|
|
3198
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2999
3199
|
Comp,
|
|
3000
3200
|
{
|
|
3001
3201
|
"data-slot": "bubble-content",
|
|
@@ -3032,7 +3232,7 @@ function BubbleReactions({
|
|
|
3032
3232
|
className,
|
|
3033
3233
|
...props
|
|
3034
3234
|
}) {
|
|
3035
|
-
return /* @__PURE__ */ (0,
|
|
3235
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3036
3236
|
"div",
|
|
3037
3237
|
{
|
|
3038
3238
|
"data-slot": "bubble-reactions",
|
|
@@ -3047,7 +3247,7 @@ function BubbleReactions({
|
|
|
3047
3247
|
// src/ui/marker.tsx
|
|
3048
3248
|
var import_class_variance_authority3 = require("class-variance-authority");
|
|
3049
3249
|
var import_react_slot3 = require("@radix-ui/react-slot");
|
|
3050
|
-
var
|
|
3250
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
3051
3251
|
var markerVariants = (0, import_class_variance_authority3.cva)(
|
|
3052
3252
|
"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",
|
|
3053
3253
|
{
|
|
@@ -3067,7 +3267,7 @@ function Marker({
|
|
|
3067
3267
|
...props
|
|
3068
3268
|
}) {
|
|
3069
3269
|
const Comp = asChild ? import_react_slot3.Slot : "div";
|
|
3070
|
-
return /* @__PURE__ */ (0,
|
|
3270
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3071
3271
|
Comp,
|
|
3072
3272
|
{
|
|
3073
3273
|
"data-slot": "marker",
|
|
@@ -3078,7 +3278,7 @@ function Marker({
|
|
|
3078
3278
|
);
|
|
3079
3279
|
}
|
|
3080
3280
|
function MarkerIcon({ className, ...props }) {
|
|
3081
|
-
return /* @__PURE__ */ (0,
|
|
3281
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3082
3282
|
"span",
|
|
3083
3283
|
{
|
|
3084
3284
|
"data-slot": "marker-icon",
|
|
@@ -3092,7 +3292,7 @@ function MarkerIcon({ className, ...props }) {
|
|
|
3092
3292
|
);
|
|
3093
3293
|
}
|
|
3094
3294
|
function MarkerContent({ className, ...props }) {
|
|
3095
|
-
return /* @__PURE__ */ (0,
|
|
3295
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3096
3296
|
"span",
|
|
3097
3297
|
{
|
|
3098
3298
|
"data-slot": "marker-content",
|
|
@@ -3106,7 +3306,7 @@ function MarkerContent({ className, ...props }) {
|
|
|
3106
3306
|
}
|
|
3107
3307
|
|
|
3108
3308
|
// src/ui/mcp-connect-required-card.tsx
|
|
3109
|
-
var
|
|
3309
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
3110
3310
|
var STATUS_LABELS = {
|
|
3111
3311
|
pending: "Connect",
|
|
3112
3312
|
connecting: "Connecting",
|
|
@@ -3130,7 +3330,7 @@ function McpConnectRequiredCard({
|
|
|
3130
3330
|
const isBusy = loading || status === "connecting" || status === "resuming";
|
|
3131
3331
|
const isConnected = status === "connected";
|
|
3132
3332
|
const buttonDisabled = disabled || isBusy || isConnected || !onConnect;
|
|
3133
|
-
return /* @__PURE__ */ (0,
|
|
3333
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3134
3334
|
"div",
|
|
3135
3335
|
{
|
|
3136
3336
|
"data-agents24-mcp-connect-card": true,
|
|
@@ -3140,13 +3340,13 @@ function McpConnectRequiredCard({
|
|
|
3140
3340
|
className
|
|
3141
3341
|
),
|
|
3142
3342
|
...props,
|
|
3143
|
-
children: /* @__PURE__ */ (0,
|
|
3144
|
-
/* @__PURE__ */ (0,
|
|
3145
|
-
/* @__PURE__ */ (0,
|
|
3146
|
-
/* @__PURE__ */ (0,
|
|
3147
|
-
status === "error" && error ? /* @__PURE__ */ (0,
|
|
3343
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex min-w-0 items-start justify-between gap-3", children: [
|
|
3344
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "min-w-0", children: [
|
|
3345
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "truncate text-sm font-medium", children: label }),
|
|
3346
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "mt-1 text-sm text-muted-foreground", children: message || "Connect your account to continue." }),
|
|
3347
|
+
status === "error" && error ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "mt-2 text-sm text-destructive", children: error }) : null
|
|
3148
3348
|
] }),
|
|
3149
|
-
/* @__PURE__ */ (0,
|
|
3349
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3150
3350
|
"button",
|
|
3151
3351
|
{
|
|
3152
3352
|
type: "button",
|
|
@@ -3165,22 +3365,22 @@ function McpConnectRequiredCard({
|
|
|
3165
3365
|
}
|
|
3166
3366
|
|
|
3167
3367
|
// src/ui/use-audio-recorder.ts
|
|
3168
|
-
var
|
|
3368
|
+
var React12 = __toESM(require("react"), 1);
|
|
3169
3369
|
var RECORDING_CANDIDATES = ["audio/webm;codecs=opus", "audio/webm", "audio/mp4"];
|
|
3170
3370
|
function recordingExtension(mimeType) {
|
|
3171
3371
|
return mimeType.startsWith("audio/mp4") ? "m4a" : "webm";
|
|
3172
3372
|
}
|
|
3173
3373
|
function useAudioRecorder(onRecorded, options = {}) {
|
|
3174
|
-
const recorderRef =
|
|
3175
|
-
const streamRef =
|
|
3176
|
-
const onRecordedRef =
|
|
3177
|
-
const onStreamChangeRef =
|
|
3374
|
+
const recorderRef = React12.useRef(null);
|
|
3375
|
+
const streamRef = React12.useRef(null);
|
|
3376
|
+
const onRecordedRef = React12.useRef(onRecorded);
|
|
3377
|
+
const onStreamChangeRef = React12.useRef(options.onStreamChange);
|
|
3178
3378
|
onRecordedRef.current = onRecorded;
|
|
3179
3379
|
onStreamChangeRef.current = options.onStreamChange;
|
|
3180
|
-
const [isRecording, setIsRecording] =
|
|
3181
|
-
const [error, setError] =
|
|
3182
|
-
const stop =
|
|
3183
|
-
const start =
|
|
3380
|
+
const [isRecording, setIsRecording] = React12.useState(false);
|
|
3381
|
+
const [error, setError] = React12.useState(null);
|
|
3382
|
+
const stop = React12.useCallback(() => recorderRef.current?.stop(), []);
|
|
3383
|
+
const start = React12.useCallback(async () => {
|
|
3184
3384
|
setError(null);
|
|
3185
3385
|
if (!navigator.mediaDevices?.getUserMedia || typeof MediaRecorder === "undefined") {
|
|
3186
3386
|
setError("Audio recording is not supported in this browser.");
|
|
@@ -3218,7 +3418,7 @@ function useAudioRecorder(onRecorded, options = {}) {
|
|
|
3218
3418
|
setError("Microphone access is unavailable.");
|
|
3219
3419
|
}
|
|
3220
3420
|
}, []);
|
|
3221
|
-
|
|
3421
|
+
React12.useEffect(() => () => {
|
|
3222
3422
|
recorderRef.current?.stop();
|
|
3223
3423
|
streamRef.current?.getTracks().forEach((track) => track.stop());
|
|
3224
3424
|
onStreamChangeRef.current?.(null);
|
|
@@ -3236,6 +3436,7 @@ function useAudioRecorder(onRecorded, options = {}) {
|
|
|
3236
3436
|
AgentChatModelTurnRow,
|
|
3237
3437
|
AgentChatNodeActivityRow,
|
|
3238
3438
|
AgentChatPart,
|
|
3439
|
+
AgentChatQueue,
|
|
3239
3440
|
AgentChatSubagentGroup,
|
|
3240
3441
|
AgentChatToolGroup,
|
|
3241
3442
|
AgentChatToolPart,
|
|
@@ -3287,6 +3488,7 @@ function useAudioRecorder(onRecorded, options = {}) {
|
|
|
3287
3488
|
attachmentMediaVariants,
|
|
3288
3489
|
attachmentVariants,
|
|
3289
3490
|
bubbleVariants,
|
|
3491
|
+
chatComposerAction,
|
|
3290
3492
|
cn,
|
|
3291
3493
|
contextStatusMetrics,
|
|
3292
3494
|
createAgentChatComposerFile,
|
|
@@ -3297,9 +3499,13 @@ function useAudioRecorder(onRecorded, options = {}) {
|
|
|
3297
3499
|
latestRunningAgentChatToolId,
|
|
3298
3500
|
markerVariants,
|
|
3299
3501
|
partitionAgentChatToolTimeline,
|
|
3502
|
+
queuedMessageComposerFiles,
|
|
3300
3503
|
resolvedHitlLabel,
|
|
3301
3504
|
revokeAgentChatComposerFiles,
|
|
3302
3505
|
shouldCollapseUserMessage,
|
|
3303
|
-
useAudioRecorder
|
|
3506
|
+
useAudioRecorder,
|
|
3507
|
+
useChatComposerFocus,
|
|
3508
|
+
useCompletionActionEntrance,
|
|
3509
|
+
useLiveCompletionRuns
|
|
3304
3510
|
});
|
|
3305
3511
|
//# sourceMappingURL=index.cjs.map
|