@agents24/chat-react 0.5.16 → 0.5.18

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