@agents24/chat-react 0.5.15 → 0.5.17

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