@agents24/chat-react 0.5.36 → 0.5.37

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 (40) hide show
  1. package/dist/{chunk-INO5DSSJ.js → chunk-DWDHK4FZ.js} +3 -4
  2. package/dist/chunk-DWDHK4FZ.js.map +1 -0
  3. package/dist/generated/delegation-types.d.ts +3 -2
  4. package/dist/generated/run-usage.d.ts +11 -0
  5. package/dist/registry/agents24-chat.json +13 -13
  6. package/dist/runtime/index.cjs +25 -9
  7. package/dist/runtime/index.cjs.map +1 -1
  8. package/dist/runtime/index.js +24 -7
  9. package/dist/runtime/index.js.map +1 -1
  10. package/dist/runtime/input-contract.d.ts +1 -1
  11. package/dist/runtime/use-agent-chat-hitl.d.ts +2 -2
  12. package/dist/runtime/use-agent-chat-runtime.d.ts +4 -6
  13. package/dist/scaffold/app.d.ts +2 -2
  14. package/dist/scaffold/components/chat/chat-composer.d.ts +2 -1
  15. package/dist/scaffold/components/chat/chat-message.d.ts +2 -2
  16. package/dist/scaffold/components/chat/message-parts.d.ts +2 -2
  17. package/dist/scaffold/index.cjs +17 -13
  18. package/dist/scaffold/index.cjs.map +1 -1
  19. package/dist/scaffold/index.js +11 -7
  20. package/dist/scaffold/index.js.map +1 -1
  21. package/dist/styles.css +7 -0
  22. package/dist/ui/agent-chat-composer.d.ts +2 -1
  23. package/dist/ui/agent-chat-message.d.ts +6 -2
  24. package/dist/ui/agent-response-timeline.d.ts +11 -3
  25. package/dist/ui/ask-user-interaction.d.ts +5 -1
  26. package/dist/ui/hitl-submission-status.d.ts +22 -0
  27. package/dist/ui/index.cjs +514 -337
  28. package/dist/ui/index.cjs.map +1 -1
  29. package/dist/ui/index.d.ts +1 -0
  30. package/dist/ui/index.js +510 -335
  31. package/dist/ui/index.js.map +1 -1
  32. package/dist/ui/use-agent-chat-composer.d.ts +17 -2
  33. package/dist/ui/use-audio-recorder.d.ts +15 -2
  34. package/package.json +3 -3
  35. package/scaffold/src/app.tsx +2 -1
  36. package/scaffold/src/components/chat/chat-composer.tsx +5 -3
  37. package/scaffold/src/components/chat/chat-message.tsx +3 -3
  38. package/scaffold/src/components/chat/chat-shell.tsx +2 -1
  39. package/scaffold/src/components/chat/message-parts.tsx +6 -6
  40. package/dist/chunk-INO5DSSJ.js.map +0 -1
package/dist/ui/index.js CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  canonicalInputMimeType,
8
8
  inputMimeTypes,
9
9
  validateAgentChatSubmission
10
- } from "../chunk-INO5DSSJ.js";
10
+ } from "../chunk-DWDHK4FZ.js";
11
11
 
12
12
  // src/ui/agent-chat-composer.tsx
13
13
  import * as React6 from "react";
@@ -801,47 +801,69 @@ function useChatComposerFocus({ textareaRef, disabled, focusKey, restoredDraft,
801
801
 
802
802
  // src/ui/use-audio-recorder.ts
803
803
  import * as React3 from "react";
804
+ import { normalizeAttachmentMimeType as normalizeAttachmentMimeType2 } from "@agents24/client";
804
805
  var RECORDING_CANDIDATES = ["audio/webm;codecs=opus", "audio/webm", "audio/mp4"];
805
806
  function useAudioRecorder(onRecorded, options = {}) {
806
807
  const recorderRef = React3.useRef(null);
807
808
  const streamRef = React3.useRef(null);
809
+ const operationRef = React3.useRef(null);
808
810
  const pendingRef = React3.useRef(false);
809
- const generationRef = React3.useRef(0);
810
- const onRecordedRef = React3.useRef(onRecorded);
811
- const onStreamChangeRef = React3.useRef(options.onStreamChange);
812
- React3.useEffect(() => {
813
- onRecordedRef.current = onRecorded;
814
- onStreamChangeRef.current = options.onStreamChange;
811
+ const callbacksRef = React3.useRef({ onRecorded, onStreamChange: options.onStreamChange, acceptedMimeTypes: options.acceptedMimeTypes });
812
+ React3.useLayoutEffect(() => {
813
+ callbacksRef.current = { onRecorded, onStreamChange: options.onStreamChange, acceptedMimeTypes: options.acceptedMimeTypes };
815
814
  });
816
815
  const [isRecording, setIsRecording] = React3.useState(false);
816
+ const [isStarting, setIsStarting] = React3.useState(false);
817
+ const [isProcessing, setIsProcessing] = React3.useState(false);
817
818
  const [error, setError] = React3.useState(null);
818
819
  const release = React3.useCallback(() => {
819
820
  streamRef.current?.getTracks().forEach((track) => track.stop());
820
821
  streamRef.current = null;
821
822
  recorderRef.current = null;
822
- onStreamChangeRef.current?.(null);
823
+ callbacksRef.current.onStreamChange?.(null);
823
824
  }, []);
825
+ const discard = React3.useCallback(() => {
826
+ operationRef.current?.controller.abort();
827
+ operationRef.current = null;
828
+ pendingRef.current = false;
829
+ const recorder = recorderRef.current;
830
+ if (recorder) {
831
+ recorder.onstop = null;
832
+ recorder.onerror = null;
833
+ recorder.ondataavailable = null;
834
+ if (recorder.state !== "inactive") recorder.stop();
835
+ }
836
+ release();
837
+ }, [release]);
838
+ const cancel = React3.useCallback(() => {
839
+ discard();
840
+ setIsStarting(false);
841
+ setIsRecording(false);
842
+ setIsProcessing(false);
843
+ setError(null);
844
+ }, [discard]);
824
845
  const stop = React3.useCallback(() => {
825
846
  const recorder = recorderRef.current;
826
847
  if (recorder && recorder.state !== "inactive") recorder.stop();
827
848
  }, []);
828
- const start = React3.useCallback(async () => {
829
- if (pendingRef.current || recorderRef.current) return;
849
+ const isCapturing = React3.useCallback(() => pendingRef.current || recorderRef.current !== null, []);
850
+ const start = React3.useCallback(async (startOptions = {}) => {
851
+ if (operationRef.current) return;
830
852
  setError(null);
831
853
  if (!navigator.mediaDevices?.getUserMedia || typeof MediaRecorder === "undefined") {
832
854
  setError("Audio recording is not supported in this browser.");
833
855
  return;
834
856
  }
857
+ const controller = new AbortController();
858
+ const operation = { operationId: startOptions.operationId ?? crypto.randomUUID(), signal: controller.signal, controller };
859
+ operationRef.current = operation;
835
860
  pendingRef.current = true;
836
- const generation = generationRef.current;
861
+ setIsStarting(true);
837
862
  try {
838
- const mimeType = RECORDING_CANDIDATES.find((candidate) => MediaRecorder.isTypeSupported(candidate));
839
- if (!mimeType) {
840
- setError("Audio recording is not supported in this browser.");
841
- return;
842
- }
863
+ const mimeType = RECORDING_CANDIDATES.find((candidate) => MediaRecorder.isTypeSupported(candidate) && (callbacksRef.current.acceptedMimeTypes === void 0 || callbacksRef.current.acceptedMimeTypes.includes(normalizeAttachmentMimeType2(candidate))));
864
+ if (!mimeType) throw new Error("unsupported");
843
865
  const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
844
- if (generation !== generationRef.current) {
866
+ if (operation.signal.aborted) {
845
867
  stream.getTracks().forEach((track) => track.stop());
846
868
  return;
847
869
  }
@@ -853,48 +875,54 @@ function useAudioRecorder(onRecorded, options = {}) {
853
875
  if (event.data.size) chunks.push(event.data);
854
876
  };
855
877
  recorder.onstop = () => {
856
- if (generation !== generationRef.current) return;
878
+ if (operation.signal.aborted) return;
857
879
  const actualType = recorder.mimeType || mimeType;
858
- const extension = actualType.startsWith("audio/mp4") ? "m4a" : "webm";
859
- try {
860
- onRecordedRef.current(new File([new Blob(chunks, { type: actualType })], `recording-${Date.now()}.${extension}`, { type: actualType }));
861
- } finally {
862
- release();
863
- setIsRecording(false);
880
+ const accepted = callbacksRef.current.acceptedMimeTypes;
881
+ if (accepted !== void 0 && !accepted.includes(normalizeAttachmentMimeType2(actualType))) {
882
+ cancel();
883
+ setError("This Agent does not accept the recorded audio format.");
884
+ return;
864
885
  }
865
- };
866
- recorder.onerror = () => {
867
- recorder.onstop = null;
868
- if (recorder.state !== "inactive") recorder.stop();
886
+ const extension = actualType.startsWith("audio/mp4") ? "m4a" : "webm";
887
+ const file = new File(chunks, `recording-${Date.now()}.${extension}`, { type: actualType });
869
888
  release();
870
889
  setIsRecording(false);
890
+ setIsProcessing(true);
891
+ void Promise.resolve().then(() => {
892
+ if (!operation.signal.aborted) return callbacksRef.current.onRecorded(file, operation);
893
+ }).catch(() => {
894
+ if (!operation.signal.aborted) setError("Recording processing failed.");
895
+ }).finally(() => {
896
+ if (operationRef.current === operation) {
897
+ operationRef.current = null;
898
+ setIsProcessing(false);
899
+ }
900
+ });
901
+ };
902
+ recorder.onerror = () => {
903
+ cancel();
871
904
  setError("Audio recording failed. Try again.");
872
905
  };
873
906
  recorder.start();
874
907
  setIsRecording(true);
875
- onStreamChangeRef.current?.(stream);
908
+ callbacksRef.current.onStreamChange?.(stream);
876
909
  } catch {
877
- if (generation === generationRef.current) {
878
- release();
879
- setIsRecording(false);
880
- setError("Microphone access is unavailable.");
910
+ if (!operation.signal.aborted) {
911
+ cancel();
912
+ setError("Microphone access or audio recording is unavailable.");
881
913
  }
882
914
  } finally {
883
- if (generation === generationRef.current) pendingRef.current = false;
884
- }
885
- }, [release]);
886
- React3.useEffect(() => () => {
887
- generationRef.current += 1;
888
- pendingRef.current = false;
889
- const recorder = recorderRef.current;
890
- if (recorder) {
891
- recorder.onstop = null;
892
- recorder.onerror = null;
893
- if (recorder.state !== "inactive") recorder.stop();
915
+ if (!operation.signal.aborted) {
916
+ pendingRef.current = false;
917
+ setIsStarting(false);
918
+ }
894
919
  }
895
- release();
896
- }, [release]);
897
- return { error, isRecording, start, stop };
920
+ }, [cancel, discard, release]);
921
+ React3.useLayoutEffect(() => {
922
+ cancel();
923
+ return discard;
924
+ }, [options.scopeKey, cancel, discard]);
925
+ return { error, isRecording, isStarting, isProcessing, isCapturing, start, stop, cancel };
898
926
  }
899
927
 
900
928
  // src/ui/use-agent-chat-composer.ts
@@ -906,16 +934,29 @@ function useAgentChatComposer(options) {
906
934
  const localTextareaRef = React4.useRef(null);
907
935
  const textareaRef = options.textareaRef ?? localTextareaRef;
908
936
  const filesRef = React4.useRef(files);
909
- const inFlightFilesRef = React4.useRef([]);
937
+ const inFlightFilesRef = React4.useRef(/* @__PURE__ */ new Map());
910
938
  const revisionRef = React4.useRef(0);
911
939
  const submittingRef = React4.useRef(false);
912
- React4.useEffect(() => {
913
- filesRef.current = files;
914
- }, [files]);
940
+ const generationRef = React4.useRef(0);
941
+ const mountedRef = React4.useRef(true);
942
+ const textRef = React4.useRef(text);
943
+ React4.useLayoutEffect(() => {
944
+ mountedRef.current = true;
945
+ submittingRef.current = false;
946
+ setIsSubmitting(false);
947
+ return () => {
948
+ mountedRef.current = false;
949
+ generationRef.current += 1;
950
+ };
951
+ }, [options.scopeKey]);
915
952
  React4.useEffect(() => () => {
916
953
  revokeAgentChatComposerFiles(filesRef.current);
917
- revokeAgentChatComposerFiles(inFlightFilesRef.current);
954
+ revokeAgentChatComposerFiles([...inFlightFilesRef.current.values()].flat());
918
955
  }, []);
956
+ const revokeUnownedFiles = (candidates) => {
957
+ const retained = new Set([...filesRef.current, ...[...inFlightFilesRef.current.values()].flat()].map((file) => file.url));
958
+ revokeAgentChatComposerFiles(candidates.filter((file) => !retained.has(file.url)));
959
+ };
919
960
  const focusComposer = useChatComposerFocus({
920
961
  textareaRef,
921
962
  disabled: Boolean(options.disabled),
@@ -923,7 +964,10 @@ function useAgentChatComposer(options) {
923
964
  restoredDraft: options.restoredDraft,
924
965
  onRestore: (draft) => {
925
966
  revisionRef.current += 1;
926
- revokeAgentChatComposerFiles(filesRef.current);
967
+ const previousFiles = filesRef.current;
968
+ textRef.current = draft.text;
969
+ filesRef.current = draft.files;
970
+ revokeUnownedFiles(previousFiles);
927
971
  setTextState(draft.text);
928
972
  setFiles(draft.files);
929
973
  }
@@ -931,52 +975,80 @@ function useAgentChatComposer(options) {
931
975
  const attachmentMimeTypes = inputMimeTypes(options.inputContract);
932
976
  const setText = (value) => {
933
977
  revisionRef.current += 1;
978
+ textRef.current = value;
934
979
  setTextState(value);
935
980
  };
936
981
  const addFiles = (selected) => {
937
982
  const accepted = selected.filter((file) => attachmentMimeTypes.includes(canonicalInputMimeType(file.type, file.name)));
938
983
  revisionRef.current += 1;
939
- const additions = accepted.map(createAgentChatComposerFile);
940
- setFiles((current) => [...current, ...additions]);
984
+ const additions = selected.map(createAgentChatComposerFile);
985
+ filesRef.current = [...filesRef.current, ...additions];
986
+ setFiles(filesRef.current);
941
987
  setAttachmentError(accepted.length === selected.length ? null : "One or more selected file types are not supported by this Agent.");
942
988
  };
943
989
  const removeFile = (id) => {
944
990
  revisionRef.current += 1;
945
991
  const removed = filesRef.current.find((file) => file.id === id);
946
- if (removed) revokeAgentChatComposerFiles([removed]);
947
- setFiles((current) => current.filter((file) => file.id !== id));
992
+ filesRef.current = filesRef.current.filter((file) => file.id !== id);
993
+ if (removed) revokeUnownedFiles([removed]);
994
+ setFiles(filesRef.current);
948
995
  };
949
- const recorder = useAudioRecorder((file) => addFiles([file]), { onStreamChange: options.onRecordingStreamChange });
996
+ const recorder = useAudioRecorder(
997
+ (file, context) => options.onRecordingComplete ? options.onRecordingComplete(file, context) : addFiles([file]),
998
+ {
999
+ onStreamChange: options.onRecordingStreamChange,
1000
+ scopeKey: options.scopeKey,
1001
+ acceptedMimeTypes: options.onRecordingComplete ? void 0 : options.inputContract?.modalities.audio.allowed_mime_types ?? []
1002
+ }
1003
+ );
950
1004
  const validationError = options.inputContract ? validateAgentChatSubmission(
951
1005
  options.inputContract,
952
1006
  text,
953
1007
  files.map((file) => ({ data: file.source || new Uint8Array(), mediaType: file.mediaType, name: file.filename, byteSize: file.byteSize }))
954
1008
  ) : null;
955
- const canSubmit = Boolean(text.trim() || files.length) && !options.disabled && !options.isCancelling && !isSubmitting && !recorder.isRecording && !validationError;
956
- const submit = async () => {
957
- if (!canSubmit || submittingRef.current) return;
958
- const value = text;
959
- const selectedFiles = files;
1009
+ const canSubmit = Boolean(text.trim() || files.length) && !options.disabled && !options.isCancelling && !isSubmitting && !recorder.isRecording && !recorder.isStarting && !recorder.isProcessing && !validationError;
1010
+ const submit = async (submission) => {
1011
+ const value = submission?.text ?? textRef.current;
1012
+ const selectedFiles = submission?.files ?? filesRef.current;
1013
+ const suppliedError = options.inputContract ? validateAgentChatSubmission(
1014
+ options.inputContract,
1015
+ value,
1016
+ selectedFiles.map((file) => ({ data: file.source || new Uint8Array(), mediaType: file.mediaType, name: file.filename, byteSize: file.byteSize }))
1017
+ ) : null;
1018
+ if (!mountedRef.current || !value.trim() && !selectedFiles.length || options.disabled || options.isCancelling || submittingRef.current || recorder.isCapturing() || !submission && recorder.isProcessing || suppliedError) return false;
1019
+ const generation = generationRef.current;
960
1020
  const clearedRevision = ++revisionRef.current;
961
1021
  submittingRef.current = true;
962
1022
  setIsSubmitting(true);
963
- inFlightFilesRef.current = selectedFiles;
1023
+ const selectedUrls = new Set(selectedFiles.map((file) => file.url));
1024
+ const replacedFiles = filesRef.current.filter((file) => !selectedUrls.has(file.url));
1025
+ const submissionId = /* @__PURE__ */ Symbol();
1026
+ inFlightFilesRef.current.set(submissionId, selectedFiles);
1027
+ textRef.current = "";
1028
+ filesRef.current = [];
1029
+ revokeUnownedFiles(replacedFiles);
964
1030
  setTextState("");
965
1031
  setFiles([]);
966
1032
  focusComposer();
967
1033
  try {
968
1034
  await options.onSubmit(value, selectedFiles);
969
- revokeAgentChatComposerFiles(selectedFiles);
1035
+ return true;
970
1036
  } catch {
971
- if (revisionRef.current === clearedRevision) {
1037
+ if (mountedRef.current && generationRef.current === generation && revisionRef.current === clearedRevision) {
972
1038
  revisionRef.current += 1;
1039
+ textRef.current = value;
1040
+ filesRef.current = selectedFiles;
973
1041
  setTextState(value);
974
1042
  setFiles(selectedFiles);
975
- } else revokeAgentChatComposerFiles(selectedFiles);
1043
+ }
1044
+ return false;
976
1045
  } finally {
977
- inFlightFilesRef.current = [];
978
- submittingRef.current = false;
979
- setIsSubmitting(false);
1046
+ inFlightFilesRef.current.delete(submissionId);
1047
+ revokeUnownedFiles(selectedFiles);
1048
+ if (mountedRef.current && generationRef.current === generation) {
1049
+ submittingRef.current = false;
1050
+ setIsSubmitting(false);
1051
+ }
980
1052
  }
981
1053
  };
982
1054
  return {
@@ -993,6 +1065,7 @@ function useAgentChatComposer(options) {
993
1065
  attachmentMimeTypes,
994
1066
  validationError,
995
1067
  recorder,
1068
+ isProcessing: recorder.isProcessing,
996
1069
  recordingAllowed: options.recordingEnabled ?? options.inputContract?.modalities.audio.recording_enabled ?? false,
997
1070
  fileAccept: attachmentFileAccept(attachmentMimeTypes),
998
1071
  onKeyDown: (event) => {
@@ -1126,6 +1199,7 @@ function AgentChatComposer({
1126
1199
  disabled = false,
1127
1200
  forceExpanded = false,
1128
1201
  focusKey,
1202
+ scopeKey,
1129
1203
  inputToolbarContent,
1130
1204
  isRunning = false,
1131
1205
  isCancelling = false,
@@ -1144,6 +1218,7 @@ function AgentChatComposer({
1144
1218
  disabled,
1145
1219
  isRunning,
1146
1220
  isCancelling,
1221
+ scopeKey,
1147
1222
  focusKey,
1148
1223
  restoredDraft,
1149
1224
  textareaRef: localTextareaRef,
@@ -1625,14 +1700,71 @@ function AgentChatDefaultActions({
1625
1700
  }
1626
1701
 
1627
1702
  // src/ui/agent-chat-message.tsx
1628
- import * as React16 from "react";
1703
+ import * as React17 from "react";
1629
1704
  import { ChevronDown as ChevronDown3, ChevronUp } from "lucide-react";
1630
1705
 
1706
+ // src/ui/hitl-submission-status.tsx
1707
+ import * as React9 from "react";
1708
+ import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
1709
+ var defaultHitlSubmissionLabels = {
1710
+ submitting: "Submitting\u2026",
1711
+ checking: "Checking submission\u2026",
1712
+ uncertain: "Submission could not be confirmed.",
1713
+ retry: "Retry submission",
1714
+ accepted: "Accepted; agent continuing",
1715
+ approved: "Approved; agent continuing",
1716
+ rejected: "Rejected"
1717
+ };
1718
+ function isHitlSubmissionCompact(state) {
1719
+ return ["submitting", "resuming", "checking", "uncertain", "accepted"].includes(state?.status || "");
1720
+ }
1721
+ function HitlSubmissionStatus({ state, labels: overrides, onPaint }) {
1722
+ const labels = { ...defaultHitlSubmissionLabels, ...overrides };
1723
+ const started = React9.useRef(performance.now());
1724
+ const ref = React9.useRef(null);
1725
+ const paintCallback = React9.useRef(onPaint);
1726
+ paintCallback.current = onPaint;
1727
+ React9.useEffect(() => {
1728
+ const frame = requestAnimationFrame(() => paintCallback.current?.(performance.now() - started.current));
1729
+ return () => cancelAnimationFrame(frame);
1730
+ }, []);
1731
+ React9.useEffect(() => {
1732
+ ref.current?.focus({ preventScroll: true });
1733
+ }, []);
1734
+ const text = state.status === "checking" ? labels.checking : state.status === "uncertain" ? labels.uncertain : state.status === "accepted" ? state.action === "approve" ? labels.approved : state.action === "reject" ? labels.rejected : labels.accepted : labels.submitting;
1735
+ return /* @__PURE__ */ jsxs5(
1736
+ "div",
1737
+ {
1738
+ ref,
1739
+ tabIndex: -1,
1740
+ role: "status",
1741
+ "aria-live": "polite",
1742
+ "aria-atomic": "true",
1743
+ "data-hitl-submission": state.status,
1744
+ className: "a24-hitl-submission flex items-center gap-2 py-1 text-start text-sm text-muted-foreground outline-none",
1745
+ children: [
1746
+ /* @__PURE__ */ jsx7("span", { children: text }),
1747
+ state.status === "uncertain" && state.retry && /* @__PURE__ */ jsx7(
1748
+ "button",
1749
+ {
1750
+ type: "button",
1751
+ className: "rounded px-2 py-1 text-foreground underline underline-offset-2",
1752
+ onClick: () => {
1753
+ void state.retry?.().catch(() => void 0);
1754
+ },
1755
+ children: labels.retry
1756
+ }
1757
+ )
1758
+ ]
1759
+ }
1760
+ );
1761
+ }
1762
+
1631
1763
  // src/ui/agent-response-timeline.tsx
1632
- import * as React15 from "react";
1764
+ import * as React16 from "react";
1633
1765
 
1634
1766
  // src/ui/ask-user-interaction.tsx
1635
- import * as React9 from "react";
1767
+ import * as React10 from "react";
1636
1768
  import {
1637
1769
  ChevronDown,
1638
1770
  ChevronLeft,
@@ -1694,7 +1826,7 @@ function askUserAnswersFromDrafts(questions, drafts) {
1694
1826
  }
1695
1827
 
1696
1828
  // src/ui/ask-user-interaction.tsx
1697
- import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
1829
+ import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
1698
1830
  function resolvedAnswerText(question, answer) {
1699
1831
  if (!answer) return ["No response recorded"];
1700
1832
  const labels = answer.selectedOptionIds.flatMap((optionId) => {
@@ -1708,7 +1840,7 @@ function ResolvedQuestions({
1708
1840
  buttonRef,
1709
1841
  part
1710
1842
  }) {
1711
- const [open, setOpen] = React9.useState(false);
1843
+ const [open, setOpen] = React10.useState(false);
1712
1844
  const count = part.questions.length;
1713
1845
  const answers = new Map(
1714
1846
  (part.resolution?.answers || []).map((answer) => [
@@ -1716,8 +1848,8 @@ function ResolvedQuestions({
1716
1848
  answer
1717
1849
  ])
1718
1850
  );
1719
- return /* @__PURE__ */ jsxs5("div", { className: "a24-ask-user a24-ask-user--resolved w-full", children: [
1720
- /* @__PURE__ */ jsxs5(
1851
+ return /* @__PURE__ */ jsxs6("div", { className: "a24-ask-user a24-ask-user--resolved w-full", children: [
1852
+ /* @__PURE__ */ jsxs6(
1721
1853
  "button",
1722
1854
  {
1723
1855
  "aria-expanded": open,
@@ -1726,13 +1858,13 @@ function ResolvedQuestions({
1726
1858
  ref: buttonRef,
1727
1859
  type: "button",
1728
1860
  children: [
1729
- /* @__PURE__ */ jsxs5("span", { children: [
1861
+ /* @__PURE__ */ jsxs6("span", { children: [
1730
1862
  "Asked ",
1731
1863
  count,
1732
1864
  " question",
1733
1865
  count === 1 ? "" : "s"
1734
1866
  ] }),
1735
- open ? /* @__PURE__ */ jsx7(ChevronDown, { "aria-hidden": "true", className: "size-3.5" }) : /* @__PURE__ */ jsx7(
1867
+ open ? /* @__PURE__ */ jsx8(ChevronDown, { "aria-hidden": "true", className: "size-3.5" }) : /* @__PURE__ */ jsx8(
1736
1868
  ChevronRight,
1737
1869
  {
1738
1870
  "aria-hidden": "true",
@@ -1742,12 +1874,12 @@ function ResolvedQuestions({
1742
1874
  ]
1743
1875
  }
1744
1876
  ),
1745
- open ? /* @__PURE__ */ jsx7("div", { className: "mt-2 space-y-3 ps-4", children: part.questions.map((question) => /* @__PURE__ */ jsxs5("div", { className: "min-w-0", children: [
1746
- /* @__PURE__ */ jsx7("div", { className: "text-sm font-medium text-foreground", children: question.question }),
1747
- /* @__PURE__ */ jsx7("div", { className: "mt-1 space-y-1 text-sm text-muted-foreground", children: resolvedAnswerText(
1877
+ open ? /* @__PURE__ */ jsx8("div", { className: "mt-2 space-y-3 ps-4", children: part.questions.map((question) => /* @__PURE__ */ jsxs6("div", { className: "min-w-0", children: [
1878
+ /* @__PURE__ */ jsx8("div", { className: "text-sm font-medium text-foreground", children: question.question }),
1879
+ /* @__PURE__ */ jsx8("div", { className: "mt-1 space-y-1 text-sm text-muted-foreground", children: resolvedAnswerText(
1748
1880
  question,
1749
1881
  answers.get(question.id)
1750
- ).map((value, index) => /* @__PURE__ */ jsx7(
1882
+ ).map((value, index) => /* @__PURE__ */ jsx8(
1751
1883
  "div",
1752
1884
  {
1753
1885
  className: "whitespace-pre-wrap break-words",
@@ -1760,40 +1892,50 @@ function ResolvedQuestions({
1760
1892
  }
1761
1893
  function AskUserInteraction({
1762
1894
  error,
1895
+ submission,
1896
+ submissionLabels,
1897
+ onSubmissionPaint,
1763
1898
  isBusy = false,
1764
1899
  onSubmit,
1765
1900
  part
1766
1901
  }) {
1767
1902
  const questions = part.questions;
1768
- const [step, setStep] = React9.useState(0);
1769
- const [drafts, setDrafts] = React9.useState(
1903
+ const [step, setStep] = React10.useState(0);
1904
+ const [drafts, setDrafts] = React10.useState(
1770
1905
  () => emptyAskUserDrafts(questions)
1771
1906
  );
1772
- const headingRef = React9.useRef(null);
1773
- const questionsRef = React9.useRef(questions);
1774
- const resolvedButtonRef = React9.useRef(null);
1775
- const wasResolvedRef = React9.useRef(part.status !== "pending");
1907
+ const otherRef = React10.useRef(null);
1908
+ const headingRef = React10.useRef(null);
1909
+ const questionsRef = React10.useRef(questions);
1910
+ const resolvedButtonRef = React10.useRef(null);
1911
+ const wasResolvedRef = React10.useRef(part.status !== "pending");
1776
1912
  questionsRef.current = questions;
1777
- React9.useEffect(() => {
1913
+ React10.useEffect(() => {
1778
1914
  setStep(0);
1779
1915
  setDrafts(emptyAskUserDrafts(questionsRef.current));
1780
1916
  }, [part.interruptId]);
1781
- React9.useEffect(() => {
1917
+ React10.useEffect(() => {
1782
1918
  headingRef.current?.focus();
1783
1919
  }, [step]);
1784
- React9.useEffect(() => {
1920
+ React10.useEffect(() => {
1785
1921
  const isResolved = part.status !== "pending";
1786
1922
  if (isResolved && !wasResolvedRef.current) {
1787
1923
  resolvedButtonRef.current?.focus();
1788
1924
  }
1789
1925
  wasResolvedRef.current = isResolved;
1790
1926
  }, [part.status]);
1927
+ React10.useEffect(() => {
1928
+ if (submission?.status === "error") (otherRef.current?.value ? otherRef.current : headingRef.current)?.focus();
1929
+ }, [submission?.status]);
1930
+ if (part.status === "pending" && isHitlSubmissionCompact(submission)) {
1931
+ return /* @__PURE__ */ jsx8(HitlSubmissionStatus, { state: submission, labels: submissionLabels, onPaint: onSubmissionPaint });
1932
+ }
1791
1933
  if (part.status !== "pending") {
1792
- return /* @__PURE__ */ jsx7(ResolvedQuestions, { buttonRef: resolvedButtonRef, part });
1934
+ return /* @__PURE__ */ jsx8(ResolvedQuestions, { buttonRef: resolvedButtonRef, part });
1793
1935
  }
1794
1936
  const question = questions[step];
1795
1937
  if (!question) {
1796
- return /* @__PURE__ */ jsx7("div", { className: "text-sm text-destructive", role: "alert", children: "This question request is unavailable." });
1938
+ return /* @__PURE__ */ jsx8("div", { className: "text-sm text-destructive", role: "alert", children: "This question request is unavailable." });
1797
1939
  }
1798
1940
  const draft = drafts[question.id] || {
1799
1941
  customText: "",
@@ -1827,9 +1969,9 @@ function AskUserInteraction({
1827
1969
  })
1828
1970
  );
1829
1971
  };
1830
- return /* @__PURE__ */ jsxs5("div", { className: "a24-ask-user space-y-3 rounded-xl border border-border/50 bg-background p-4 shadow-sm", children: [
1831
- /* @__PURE__ */ jsxs5("div", { className: "flex min-w-0 items-start justify-between gap-4", children: [
1832
- /* @__PURE__ */ jsx7(
1972
+ return /* @__PURE__ */ jsxs6("div", { className: "a24-ask-user space-y-3 rounded-xl border border-border/50 bg-background p-4 shadow-sm", children: [
1973
+ /* @__PURE__ */ jsxs6("div", { className: "flex min-w-0 items-start justify-between gap-4", children: [
1974
+ /* @__PURE__ */ jsx8(
1833
1975
  "h3",
1834
1976
  {
1835
1977
  className: "min-w-0 flex-1 text-base font-medium leading-6 text-foreground outline-none",
@@ -1838,8 +1980,8 @@ function AskUserInteraction({
1838
1980
  children: question.question
1839
1981
  }
1840
1982
  ),
1841
- /* @__PURE__ */ jsxs5("div", { className: "flex shrink-0 items-center gap-1 text-muted-foreground", children: [
1842
- /* @__PURE__ */ jsx7(
1983
+ /* @__PURE__ */ jsxs6("div", { className: "flex shrink-0 items-center gap-1 text-muted-foreground", children: [
1984
+ /* @__PURE__ */ jsx8(
1843
1985
  "button",
1844
1986
  {
1845
1987
  "aria-label": "Previous question",
@@ -1847,7 +1989,7 @@ function AskUserInteraction({
1847
1989
  disabled: isBusy || step === 0,
1848
1990
  onClick: () => setStep((current) => Math.max(0, current - 1)),
1849
1991
  type: "button",
1850
- children: /* @__PURE__ */ jsx7(
1992
+ children: /* @__PURE__ */ jsx8(
1851
1993
  ChevronLeft,
1852
1994
  {
1853
1995
  "aria-hidden": "true",
@@ -1856,7 +1998,7 @@ function AskUserInteraction({
1856
1998
  )
1857
1999
  }
1858
2000
  ),
1859
- /* @__PURE__ */ jsxs5(
2001
+ /* @__PURE__ */ jsxs6(
1860
2002
  "span",
1861
2003
  {
1862
2004
  "aria-label": `Question ${step + 1} of ${questions.length}`,
@@ -1868,7 +2010,7 @@ function AskUserInteraction({
1868
2010
  ]
1869
2011
  }
1870
2012
  ),
1871
- /* @__PURE__ */ jsx7(
2013
+ /* @__PURE__ */ jsx8(
1872
2014
  "button",
1873
2015
  {
1874
2016
  "aria-label": isLastQuestion ? "Submit answers" : "Next question",
@@ -1876,7 +2018,7 @@ function AskUserInteraction({
1876
2018
  disabled: isBusy || !onSubmit || !canMoveForward,
1877
2019
  onClick: () => completeStep(drafts),
1878
2020
  type: "button",
1879
- children: /* @__PURE__ */ jsx7(
2021
+ children: /* @__PURE__ */ jsx8(
1880
2022
  ChevronRight,
1881
2023
  {
1882
2024
  "aria-hidden": "true",
@@ -1887,10 +2029,10 @@ function AskUserInteraction({
1887
2029
  )
1888
2030
  ] })
1889
2031
  ] }),
1890
- /* @__PURE__ */ jsxs5("div", { className: "space-y-1", children: [
2032
+ /* @__PURE__ */ jsxs6("div", { className: "space-y-1", children: [
1891
2033
  question.options.map((option, index) => {
1892
2034
  const selected = draft.selectedOptionIds.includes(option.id);
1893
- return /* @__PURE__ */ jsxs5(
2035
+ return /* @__PURE__ */ jsxs6(
1894
2036
  "button",
1895
2037
  {
1896
2038
  "aria-pressed": selected,
@@ -1902,7 +2044,7 @@ function AskUserInteraction({
1902
2044
  onClick: () => selectOption(option.id),
1903
2045
  type: "button",
1904
2046
  children: [
1905
- /* @__PURE__ */ jsx7(
2047
+ /* @__PURE__ */ jsx8(
1906
2048
  "span",
1907
2049
  {
1908
2050
  className: cn(
@@ -1912,8 +2054,8 @@ function AskUserInteraction({
1912
2054
  children: index + 1
1913
2055
  }
1914
2056
  ),
1915
- /* @__PURE__ */ jsx7("span", { className: "min-w-0 flex-1 font-medium text-foreground", children: option.label }),
1916
- /* @__PURE__ */ jsx7(
2057
+ /* @__PURE__ */ jsx8("span", { className: "min-w-0 flex-1 font-medium text-foreground", children: option.label }),
2058
+ /* @__PURE__ */ jsx8(
1917
2059
  ChevronRight,
1918
2060
  {
1919
2061
  "aria-hidden": "true",
@@ -1925,11 +2067,12 @@ function AskUserInteraction({
1925
2067
  option.id
1926
2068
  );
1927
2069
  }),
1928
- /* @__PURE__ */ jsxs5("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: [
1929
- /* @__PURE__ */ jsx7("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__ */ jsx7(Pencil, { "aria-hidden": "true", className: "size-4" }) }),
1930
- /* @__PURE__ */ jsx7(
2070
+ /* @__PURE__ */ jsxs6("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: [
2071
+ /* @__PURE__ */ jsx8("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__ */ jsx8(Pencil, { "aria-hidden": "true", className: "size-4" }) }),
2072
+ /* @__PURE__ */ jsx8(
1931
2073
  "input",
1932
2074
  {
2075
+ ref: otherRef,
1933
2076
  "aria-label": "Other response",
1934
2077
  autoComplete: "off",
1935
2078
  className: "h-8 min-w-0 flex-1 bg-transparent px-1 text-sm text-foreground outline-none placeholder:text-muted-foreground",
@@ -1946,7 +2089,7 @@ function AskUserInteraction({
1946
2089
  value: draft.customText
1947
2090
  }
1948
2091
  ),
1949
- draft.customText.trim() ? /* @__PURE__ */ jsx7(
2092
+ draft.customText.trim() ? /* @__PURE__ */ jsx8(
1950
2093
  "button",
1951
2094
  {
1952
2095
  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",
@@ -1958,12 +2101,12 @@ function AskUserInteraction({
1958
2101
  ) : null
1959
2102
  ] })
1960
2103
  ] }),
1961
- error ? /* @__PURE__ */ jsx7("div", { className: "text-sm text-destructive", role: "alert", children: error }) : null
2104
+ error ? /* @__PURE__ */ jsx8("div", { className: "text-sm text-destructive", role: "alert", children: error }) : null
1962
2105
  ] });
1963
2106
  }
1964
2107
 
1965
2108
  // src/ui/agent-chat-context-compression-row.tsx
1966
- import { jsx as jsx8 } from "react/jsx-runtime";
2109
+ import { jsx as jsx9 } from "react/jsx-runtime";
1967
2110
  function compressionPresentation(part) {
1968
2111
  if (part.status === "failed") {
1969
2112
  return { label: "Could not compact message history", status: "failed" };
@@ -1978,7 +2121,7 @@ function AgentChatContextCompressionRow({
1978
2121
  part
1979
2122
  }) {
1980
2123
  const presentation = compressionPresentation(part);
1981
- return /* @__PURE__ */ jsx8(
2124
+ return /* @__PURE__ */ jsx9(
1982
2125
  "div",
1983
2126
  {
1984
2127
  "aria-live": "polite",
@@ -1986,11 +2129,11 @@ function AgentChatContextCompressionRow({
1986
2129
  "data-agents24-context-compression": "",
1987
2130
  "data-status": part.status,
1988
2131
  role: "status",
1989
- children: /* @__PURE__ */ jsx8("div", { className: "a24-tool-trigger-row", children: /* @__PURE__ */ jsx8("div", { className: cn(
2132
+ children: /* @__PURE__ */ jsx9("div", { className: "a24-tool-trigger-row", children: /* @__PURE__ */ jsx9("div", { className: cn(
1990
2133
  "a24-tool-trigger a24-tool-trigger--root a24-tool-trigger--without-orb",
1991
2134
  presentation.status === "failed" && "a24-tool-trigger--error",
1992
2135
  presentation.status === "running" && "a24-tool-trigger--active"
1993
- ), children: /* @__PURE__ */ jsx8("span", { className: cn(
2136
+ ), children: /* @__PURE__ */ jsx9("span", { className: cn(
1994
2137
  "a24-tool-trigger__label",
1995
2138
  presentation.status === "running" && "a24-tool-shimmer"
1996
2139
  ), children: presentation.label }) }) })
@@ -1999,7 +2142,7 @@ function AgentChatContextCompressionRow({
1999
2142
  }
2000
2143
 
2001
2144
  // src/ui/message-response.tsx
2002
- import * as React13 from "react";
2145
+ import * as React14 from "react";
2003
2146
  import { defaultRehypePlugins, Streamdown } from "streamdown";
2004
2147
 
2005
2148
  // src/active-content.ts
@@ -2024,14 +2167,14 @@ function safeChatMarkdownHref(value) {
2024
2167
  }
2025
2168
 
2026
2169
  // src/ui/message-code.tsx
2027
- import * as React12 from "react";
2170
+ import * as React13 from "react";
2028
2171
  import { FileCode2Icon } from "lucide-react";
2029
2172
 
2030
2173
  // src/ui/code-block.tsx
2031
- import * as React10 from "react";
2174
+ import * as React11 from "react";
2032
2175
  import { cva as cva2 } from "class-variance-authority";
2033
2176
  import { CheckIcon, CopyIcon, DownloadIcon, WrapTextIcon } from "lucide-react";
2034
- import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
2177
+ import { Fragment as Fragment2, jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
2035
2178
  var codeBlockVariants = cva2(
2036
2179
  "a24-code-block",
2037
2180
  {
@@ -2052,7 +2195,7 @@ function CodeBlock({
2052
2195
  size = "default",
2053
2196
  ...props
2054
2197
  }) {
2055
- return /* @__PURE__ */ jsx9(
2198
+ return /* @__PURE__ */ jsx10(
2056
2199
  "div",
2057
2200
  {
2058
2201
  "data-slot": "code-block",
@@ -2064,7 +2207,7 @@ function CodeBlock({
2064
2207
  );
2065
2208
  }
2066
2209
  function CodeBlockHeader({ className, ...props }) {
2067
- return /* @__PURE__ */ jsx9(
2210
+ return /* @__PURE__ */ jsx10(
2068
2211
  "div",
2069
2212
  {
2070
2213
  "data-slot": "code-block-header",
@@ -2077,7 +2220,7 @@ function CodeBlockHeader({ className, ...props }) {
2077
2220
  );
2078
2221
  }
2079
2222
  function CodeBlockTitle({ className, ...props }) {
2080
- return /* @__PURE__ */ jsx9(
2223
+ return /* @__PURE__ */ jsx10(
2081
2224
  "div",
2082
2225
  {
2083
2226
  "data-slot": "code-block-title",
@@ -2093,7 +2236,7 @@ function CodeBlockActions({
2093
2236
  className,
2094
2237
  ...props
2095
2238
  }) {
2096
- return /* @__PURE__ */ jsx9(
2239
+ return /* @__PURE__ */ jsx10(
2097
2240
  "div",
2098
2241
  {
2099
2242
  "data-slot": "code-block-actions",
@@ -2111,16 +2254,16 @@ function CodeBlockCopyButton({
2111
2254
  onClick,
2112
2255
  ...props
2113
2256
  }) {
2114
- const [copied, setCopied] = React10.useState(false);
2115
- React10.useEffect(() => {
2257
+ const [copied, setCopied] = React11.useState(false);
2258
+ React11.useEffect(() => {
2116
2259
  if (!copied) {
2117
2260
  return;
2118
2261
  }
2119
2262
  const timeout = setTimeout(() => setCopied(false), 2e3);
2120
2263
  return () => clearTimeout(timeout);
2121
2264
  }, [copied]);
2122
- return /* @__PURE__ */ jsxs6(Fragment2, { children: [
2123
- /* @__PURE__ */ jsx9(
2265
+ return /* @__PURE__ */ jsxs7(Fragment2, { children: [
2266
+ /* @__PURE__ */ jsx10(
2124
2267
  "button",
2125
2268
  {
2126
2269
  type: "button",
@@ -2136,10 +2279,10 @@ function CodeBlockCopyButton({
2136
2279
  });
2137
2280
  },
2138
2281
  ...props,
2139
- children: copied ? /* @__PURE__ */ jsx9(CheckIcon, { size: 12, strokeWidth: 1.5 }) : /* @__PURE__ */ jsx9(CopyIcon, { size: 12, strokeWidth: 1.5 })
2282
+ children: copied ? /* @__PURE__ */ jsx10(CheckIcon, { size: 12, strokeWidth: 1.5 }) : /* @__PURE__ */ jsx10(CopyIcon, { size: 12, strokeWidth: 1.5 })
2140
2283
  }
2141
2284
  ),
2142
- /* @__PURE__ */ jsx9("span", { "aria-live": "polite", className: "a24-code-block__announcement", children: copied ? "Copied" : "" })
2285
+ /* @__PURE__ */ jsx10("span", { "aria-live": "polite", className: "a24-code-block__announcement", children: copied ? "Copied" : "" })
2143
2286
  ] });
2144
2287
  }
2145
2288
  function CodeBlockWrapButton({
@@ -2149,7 +2292,7 @@ function CodeBlockWrapButton({
2149
2292
  onClick,
2150
2293
  ...props
2151
2294
  }) {
2152
- return /* @__PURE__ */ jsx9(
2295
+ return /* @__PURE__ */ jsx10(
2153
2296
  "button",
2154
2297
  {
2155
2298
  type: "button",
@@ -2163,7 +2306,7 @@ function CodeBlockWrapButton({
2163
2306
  if (!event.defaultPrevented) onWrapChange(!wrap);
2164
2307
  },
2165
2308
  ...props,
2166
- children: /* @__PURE__ */ jsx9(WrapTextIcon, { size: 12, strokeWidth: 1.5 })
2309
+ children: /* @__PURE__ */ jsx10(WrapTextIcon, { size: 12, strokeWidth: 1.5 })
2167
2310
  }
2168
2311
  );
2169
2312
  }
@@ -2174,7 +2317,7 @@ function CodeBlockDownloadButton({
2174
2317
  onClick,
2175
2318
  ...props
2176
2319
  }) {
2177
- return /* @__PURE__ */ jsx9(
2320
+ return /* @__PURE__ */ jsx10(
2178
2321
  "button",
2179
2322
  {
2180
2323
  type: "button",
@@ -2195,7 +2338,7 @@ function CodeBlockDownloadButton({
2195
2338
  setTimeout(() => URL.revokeObjectURL(url), 1e3);
2196
2339
  },
2197
2340
  ...props,
2198
- children: /* @__PURE__ */ jsx9(DownloadIcon, { size: 12, strokeWidth: 1.5 })
2341
+ children: /* @__PURE__ */ jsx10(DownloadIcon, { size: 12, strokeWidth: 1.5 })
2199
2342
  }
2200
2343
  );
2201
2344
  }
@@ -2208,7 +2351,7 @@ function CodeBlockContent({
2208
2351
  startLine = 1,
2209
2352
  ...props
2210
2353
  }) {
2211
- return /* @__PURE__ */ jsx9(
2354
+ return /* @__PURE__ */ jsx10(
2212
2355
  "pre",
2213
2356
  {
2214
2357
  "data-slot": "code-block-content",
@@ -2222,12 +2365,12 @@ function CodeBlockContent({
2222
2365
  className
2223
2366
  ),
2224
2367
  ...props,
2225
- children: /* @__PURE__ */ jsx9(
2368
+ children: /* @__PURE__ */ jsx10(
2226
2369
  "code",
2227
2370
  {
2228
2371
  "data-slot": "code-block-code",
2229
2372
  className: "a24-code-block__code",
2230
- children: lineNumbers && typeof children === "string" ? children.replace(/\n$/, "").split("\n").map((line, index) => /* @__PURE__ */ jsx9(CodeBlockLine, { children: line }, index)) : children
2373
+ children: lineNumbers && typeof children === "string" ? children.replace(/\n$/, "").split("\n").map((line, index) => /* @__PURE__ */ jsx10(CodeBlockLine, { children: line }, index)) : children
2231
2374
  }
2232
2375
  )
2233
2376
  }
@@ -2256,19 +2399,19 @@ function CodeBlockLine({
2256
2399
  ...props
2257
2400
  }) {
2258
2401
  const empty = children === void 0 || children === null || children === "" || Array.isArray(children) && children.length === 0;
2259
- return /* @__PURE__ */ jsx9(
2402
+ return /* @__PURE__ */ jsx10(
2260
2403
  "span",
2261
2404
  {
2262
2405
  "data-slot": "code-block-line",
2263
2406
  "data-variant": variant,
2264
2407
  className: cn(codeBlockLineVariants({ variant }), className),
2265
2408
  ...props,
2266
- children: /* @__PURE__ */ jsx9("span", { "data-slot": "code-block-line-content", className: "a24-code-block__line-content", children: empty ? "\n" : children })
2409
+ children: /* @__PURE__ */ jsx10("span", { "data-slot": "code-block-line-content", className: "a24-code-block__line-content", children: empty ? "\n" : children })
2267
2410
  }
2268
2411
  );
2269
2412
  }
2270
2413
  function CodeBlockFooter({ className, ...props }) {
2271
- return /* @__PURE__ */ jsx9(
2414
+ return /* @__PURE__ */ jsx10(
2272
2415
  "div",
2273
2416
  {
2274
2417
  "data-slot": "code-block-footer",
@@ -2282,7 +2425,7 @@ function CodeBlockFooter({ className, ...props }) {
2282
2425
  }
2283
2426
 
2284
2427
  // src/ui/use-highlighted-code.ts
2285
- import * as React11 from "react";
2428
+ import * as React12 from "react";
2286
2429
 
2287
2430
  // src/ui/code-highlighter.tsx
2288
2431
  import {
@@ -2290,7 +2433,7 @@ import {
2290
2433
  } from "shiki/core";
2291
2434
  import { createJavaScriptRegexEngine } from "shiki/engine/javascript";
2292
2435
  import { bundledLanguages, bundledLanguagesAlias } from "shiki/langs";
2293
- import { jsx as jsx10 } from "react/jsx-runtime";
2436
+ import { jsx as jsx11 } from "react/jsx-runtime";
2294
2437
  var languageLoaders = {
2295
2438
  ...bundledLanguages,
2296
2439
  ...bundledLanguagesAlias
@@ -2335,7 +2478,7 @@ async function loadHighlighter(language) {
2335
2478
  const tokens = lang === "ansi" ? code.split("\n").flatMap((line) => tokenize(line)) : tokenize(code);
2336
2479
  return {
2337
2480
  lines: tokens.map(
2338
- (line) => line.map((token, index) => /* @__PURE__ */ jsx10(
2481
+ (line) => line.map((token, index) => /* @__PURE__ */ jsx11(
2339
2482
  "span",
2340
2483
  {
2341
2484
  style: token.htmlStyle,
@@ -2354,9 +2497,9 @@ async function loadHighlighter(language) {
2354
2497
  // src/ui/use-highlighted-code.ts
2355
2498
  function useHighlightedCode(value, language) {
2356
2499
  const code = value.endsWith("\n") ? value.slice(0, -1) : value;
2357
- const [loaded, setLoaded] = React11.useState(null);
2500
+ const [loaded, setLoaded] = React12.useState(null);
2358
2501
  const highlighter2 = loaded?.language === language ? loaded.highlighter : null;
2359
- React11.useEffect(() => {
2502
+ React12.useEffect(() => {
2360
2503
  let cancelled = false;
2361
2504
  loadHighlighter(language).then((next2) => {
2362
2505
  if (!cancelled) {
@@ -2368,7 +2511,7 @@ function useHighlightedCode(value, language) {
2368
2511
  cancelled = true;
2369
2512
  };
2370
2513
  }, [language]);
2371
- const [done, setDone] = React11.useState({ highlighter: null, text: "", lines: [] });
2514
+ const [done, setDone] = React12.useState({ highlighter: null, text: "", lines: [] });
2372
2515
  let next = done;
2373
2516
  if (next.highlighter !== highlighter2 || !code.startsWith(next.text)) {
2374
2517
  next = { highlighter: highlighter2, text: "", lines: [] };
@@ -2390,7 +2533,7 @@ function useHighlightedCode(value, language) {
2390
2533
  setDone(next);
2391
2534
  }
2392
2535
  const tail = code.slice(end);
2393
- return React11.useMemo(() => {
2536
+ return React12.useMemo(() => {
2394
2537
  if (!highlighter2) {
2395
2538
  return code.split("\n");
2396
2539
  }
@@ -2399,7 +2542,7 @@ function useHighlightedCode(value, language) {
2399
2542
  }
2400
2543
 
2401
2544
  // src/ui/message-code.tsx
2402
- import { jsx as jsx11, jsxs as jsxs7 } from "react/jsx-runtime";
2545
+ import { jsx as jsx12, jsxs as jsxs8 } from "react/jsx-runtime";
2403
2546
  var CODE_EXTENSIONS = {
2404
2547
  bash: "sh",
2405
2548
  shell: "sh",
@@ -2441,32 +2584,32 @@ var CODE_EXTENSIONS = {
2441
2584
  plaintext: "txt"
2442
2585
  };
2443
2586
  function MessageCodeBlock({ code, language = "text" }) {
2444
- const [wrap, setWrap] = React12.useState(false);
2587
+ const [wrap, setWrap] = React13.useState(false);
2445
2588
  const lines = useHighlightedCode(code, language);
2446
2589
  const extension = Object.prototype.hasOwnProperty.call(CODE_EXTENSIONS, language.toLowerCase()) ? CODE_EXTENSIONS[language.toLowerCase()] : "txt";
2447
- return /* @__PURE__ */ jsxs7(CodeBlock, { children: [
2448
- /* @__PURE__ */ jsxs7(CodeBlockHeader, { children: [
2449
- /* @__PURE__ */ jsxs7(CodeBlockTitle, { children: [
2450
- /* @__PURE__ */ jsx11(FileCode2Icon, { size: 14, strokeWidth: 1.5, "aria-hidden": "true" }),
2451
- /* @__PURE__ */ jsx11("span", { children: language })
2590
+ return /* @__PURE__ */ jsxs8(CodeBlock, { children: [
2591
+ /* @__PURE__ */ jsxs8(CodeBlockHeader, { children: [
2592
+ /* @__PURE__ */ jsxs8(CodeBlockTitle, { children: [
2593
+ /* @__PURE__ */ jsx12(FileCode2Icon, { size: 14, strokeWidth: 1.5, "aria-hidden": "true" }),
2594
+ /* @__PURE__ */ jsx12("span", { children: language })
2452
2595
  ] }),
2453
- /* @__PURE__ */ jsxs7(CodeBlockActions, { children: [
2454
- /* @__PURE__ */ jsx11(CodeBlockWrapButton, { wrap, onWrapChange: setWrap }),
2455
- /* @__PURE__ */ jsx11(CodeBlockDownloadButton, { value: code, filename: `code.${extension}` }),
2456
- /* @__PURE__ */ jsx11(CodeBlockCopyButton, { value: code })
2596
+ /* @__PURE__ */ jsxs8(CodeBlockActions, { children: [
2597
+ /* @__PURE__ */ jsx12(CodeBlockWrapButton, { wrap, onWrapChange: setWrap }),
2598
+ /* @__PURE__ */ jsx12(CodeBlockDownloadButton, { value: code, filename: `code.${extension}` }),
2599
+ /* @__PURE__ */ jsx12(CodeBlockCopyButton, { value: code })
2457
2600
  ] })
2458
2601
  ] }),
2459
- /* @__PURE__ */ jsx11(CodeBlockContent, { "aria-label": `${language} code`, lineNumbers: true, wrap, children: lines.map((line, index) => /* @__PURE__ */ jsx11(CodeBlockLine, { children: line }, index)) })
2602
+ /* @__PURE__ */ jsx12(CodeBlockContent, { "aria-label": `${language} code`, lineNumbers: true, wrap, children: lines.map((line, index) => /* @__PURE__ */ jsx12(CodeBlockLine, { children: line }, index)) })
2460
2603
  ] });
2461
2604
  }
2462
2605
  function MessageMarkdownCode({ children, className, node, ...props }) {
2463
2606
  const language = className?.match(/(?:^|\s)language-([^\s]+)/)?.[1];
2464
2607
  const multiline = node?.position?.start?.line !== node?.position?.end?.line;
2465
2608
  if (props["data-block"] === void 0 && !language && !multiline) {
2466
- return /* @__PURE__ */ jsx11("code", { ...props, className: cn("a24-inline-code", className), "data-streamdown": "inline-code", children });
2609
+ return /* @__PURE__ */ jsx12("code", { ...props, className: cn("a24-inline-code", className), "data-streamdown": "inline-code", children });
2467
2610
  }
2468
2611
  const code = typeof children === "string" ? children.replace(/\n$/, "") : "";
2469
- return /* @__PURE__ */ jsx11(MessageCodeBlock, { code, language });
2612
+ return /* @__PURE__ */ jsx12(MessageCodeBlock, { code, language });
2470
2613
  }
2471
2614
  function formatMessageJson(text) {
2472
2615
  const trimmed = text.trim();
@@ -2500,17 +2643,17 @@ ${" ".repeat(depth)}`;
2500
2643
  }
2501
2644
 
2502
2645
  // src/ui/message-response.tsx
2503
- import { Fragment as Fragment3, jsx as jsx12 } from "react/jsx-runtime";
2646
+ import { Fragment as Fragment3, jsx as jsx13 } from "react/jsx-runtime";
2504
2647
  function SafeMarkdownLink({ children, href, ...props }) {
2505
2648
  const domProps = { ...props };
2506
2649
  delete domProps.node;
2507
2650
  const safeHref = safeChatMarkdownHref(href);
2508
- if (!safeHref) return /* @__PURE__ */ jsx12("span", { children });
2509
- if (safeHref.startsWith("#")) return /* @__PURE__ */ jsx12("a", { ...domProps, href: safeHref, children });
2510
- return /* @__PURE__ */ jsx12("a", { ...domProps, href: safeHref, rel: "noopener noreferrer", target: "_blank", children });
2651
+ if (!safeHref) return /* @__PURE__ */ jsx13("span", { children });
2652
+ if (safeHref.startsWith("#")) return /* @__PURE__ */ jsx13("a", { ...domProps, href: safeHref, children });
2653
+ return /* @__PURE__ */ jsx13("a", { ...domProps, href: safeHref, rel: "noopener noreferrer", target: "_blank", children });
2511
2654
  }
2512
2655
  function BlockedMarkdownImage({ alt }) {
2513
- return alt ? /* @__PURE__ */ jsx12("span", { "aria-label": `Image blocked: ${alt}`, role: "img", children: alt }) : null;
2656
+ return alt ? /* @__PURE__ */ jsx13("span", { "aria-label": `Image blocked: ${alt}`, role: "img", children: alt }) : null;
2514
2657
  }
2515
2658
  var BLOCK_MARKDOWN_TAGS = /* @__PURE__ */ new Set([
2516
2659
  "blockquote",
@@ -2531,7 +2674,7 @@ function isMultilineCodeNode(node) {
2531
2674
  return node?.tagName === "code" && node.position?.start?.line !== void 0 && node.position?.end?.line !== void 0 && node.position.start.line !== node.position.end.line;
2532
2675
  }
2533
2676
  function hasBlockMarkdownChild(child) {
2534
- if (!React13.isValidElement(child)) {
2677
+ if (!React14.isValidElement(child)) {
2535
2678
  return false;
2536
2679
  }
2537
2680
  if (typeof child.type === "string" && BLOCK_MARKDOWN_TAGS.has(child.type)) {
@@ -2541,7 +2684,7 @@ function hasBlockMarkdownChild(child) {
2541
2684
  if (BLOCK_MARKDOWN_TAGS.has(props.node?.tagName || "") || isMultilineCodeNode(props.node)) {
2542
2685
  return true;
2543
2686
  }
2544
- return React13.Children.toArray(props.children).some(hasBlockMarkdownChild);
2687
+ return React14.Children.toArray(props.children).some(hasBlockMarkdownChild);
2545
2688
  }
2546
2689
  function MessageMarkdownParagraph({
2547
2690
  children,
@@ -2549,17 +2692,17 @@ function MessageMarkdownParagraph({
2549
2692
  }) {
2550
2693
  const domProps = { ...props };
2551
2694
  delete domProps.node;
2552
- const childArray = React13.Children.toArray(children).filter(
2695
+ const childArray = React14.Children.toArray(children).filter(
2553
2696
  (child) => child !== null && child !== ""
2554
2697
  );
2555
- const isImageOnly = childArray.length === 1 && React13.isValidElement(childArray[0]) && childArray[0].props.node?.tagName === "img";
2698
+ const isImageOnly = childArray.length === 1 && React14.isValidElement(childArray[0]) && childArray[0].props.node?.tagName === "img";
2556
2699
  if (isImageOnly) {
2557
- return /* @__PURE__ */ jsx12(Fragment3, { children });
2700
+ return /* @__PURE__ */ jsx13(Fragment3, { children });
2558
2701
  }
2559
2702
  if (childArray.some(hasBlockMarkdownChild)) {
2560
- return /* @__PURE__ */ jsx12("div", { ...domProps, children });
2703
+ return /* @__PURE__ */ jsx13("div", { ...domProps, children });
2561
2704
  }
2562
- return /* @__PURE__ */ jsx12("p", { ...domProps, children });
2705
+ return /* @__PURE__ */ jsx13("p", { ...domProps, children });
2563
2706
  }
2564
2707
  var MESSAGE_RESPONSE_COMPONENTS = {
2565
2708
  a: SafeMarkdownLink,
@@ -2580,7 +2723,7 @@ var MESSAGE_RESPONSE_REHYPE_PLUGINS = [
2580
2723
  ]
2581
2724
  ] : []
2582
2725
  ];
2583
- var MessageResponse = React13.memo(
2726
+ var MessageResponse = React14.memo(
2584
2727
  ({
2585
2728
  children,
2586
2729
  className,
@@ -2598,13 +2741,13 @@ var MessageResponse = React13.memo(
2598
2741
  maxCatchupChars: 32,
2599
2742
  text
2600
2743
  });
2601
- const streamdownComponents = React13.useMemo(
2744
+ const streamdownComponents = React14.useMemo(
2602
2745
  () => ({ ...MESSAGE_RESPONSE_COMPONENTS, ...components }),
2603
2746
  [components]
2604
2747
  );
2605
- const json = React13.useMemo(() => formatMessageJson(text), [text]);
2748
+ const json = React14.useMemo(() => formatMessageJson(text), [text]);
2606
2749
  if (json !== null && !components?.code) {
2607
- return /* @__PURE__ */ jsx12("div", { className: cn("a24-message-response", className), children: /* @__PURE__ */ jsx12(
2750
+ return /* @__PURE__ */ jsx13("div", { className: cn("a24-message-response", className), children: /* @__PURE__ */ jsx13(
2608
2751
  MessageCodeBlock,
2609
2752
  {
2610
2753
  code: streaming || streamingText.isAnimating ? streamingText.displayedText : json,
@@ -2612,7 +2755,7 @@ var MessageResponse = React13.memo(
2612
2755
  }
2613
2756
  ) });
2614
2757
  }
2615
- return /* @__PURE__ */ jsx12(
2758
+ return /* @__PURE__ */ jsx13(
2616
2759
  Streamdown,
2617
2760
  {
2618
2761
  className: cn("a24-message-response", className),
@@ -2664,10 +2807,10 @@ function resolvedHitlLabel(part) {
2664
2807
  }
2665
2808
 
2666
2809
  // src/ui/tool-sessions.tsx
2667
- import * as React14 from "react";
2810
+ import * as React15 from "react";
2668
2811
  import { ChevronDown as ChevronDown2, ChevronRight as ChevronRight2 } from "lucide-react";
2669
2812
  import { ThinkingOrb } from "thinking-orbs";
2670
- import { Fragment as Fragment4, jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
2813
+ import { Fragment as Fragment4, jsx as jsx14, jsxs as jsxs9 } from "react/jsx-runtime";
2671
2814
  function toolSlotContext(isActive2, label, part, slots) {
2672
2815
  return {
2673
2816
  isActive: isActive2,
@@ -2685,7 +2828,7 @@ function ToolResourceAction({ context }) {
2685
2828
  const target = context.resourceTargets[0];
2686
2829
  if (!target) return null;
2687
2830
  const name = resourceTargetName(target);
2688
- return /* @__PURE__ */ jsx13(
2831
+ return /* @__PURE__ */ jsx14(
2689
2832
  "button",
2690
2833
  {
2691
2834
  "aria-label": `Open ${target.kind} ${target.path}`,
@@ -2699,8 +2842,8 @@ function ToolResourceAction({ context }) {
2699
2842
  );
2700
2843
  }
2701
2844
  function toolAccessory(context, slots) {
2702
- return /* @__PURE__ */ jsxs8(Fragment4, { children: [
2703
- slots?.onResourceAction ? /* @__PURE__ */ jsx13(ToolResourceAction, { context }) : null,
2845
+ return /* @__PURE__ */ jsxs9(Fragment4, { children: [
2846
+ slots?.onResourceAction ? /* @__PURE__ */ jsx14(ToolResourceAction, { context }) : null,
2704
2847
  slots?.renderToolAccessory?.(context)
2705
2848
  ] });
2706
2849
  }
@@ -2777,12 +2920,12 @@ function ToolActivityReel({
2777
2920
  }) {
2778
2921
  const initial = initialLabel && initialLabel !== label ? initialLabel : label;
2779
2922
  const parsedInitialShownAt = initialShownAt ? Date.parse(initialShownAt) : Number.NaN;
2780
- const [displayed, setDisplayed] = React14.useState(initial);
2781
- const [previous, setPrevious] = React14.useState(null);
2782
- const displayedRef = React14.useRef(initial);
2783
- const latestRef = React14.useRef(label);
2784
- const shownAtRef = React14.useRef(Number.isFinite(parsedInitialShownAt) ? parsedInitialShownAt : Date.now());
2785
- React14.useEffect(() => {
2923
+ const [displayed, setDisplayed] = React15.useState(initial);
2924
+ const [previous, setPrevious] = React15.useState(null);
2925
+ const displayedRef = React15.useRef(initial);
2926
+ const latestRef = React15.useRef(label);
2927
+ const shownAtRef = React15.useRef(Number.isFinite(parsedInitialShownAt) ? parsedInitialShownAt : Date.now());
2928
+ React15.useEffect(() => {
2786
2929
  latestRef.current = label;
2787
2930
  if (displayedRef.current === label) return;
2788
2931
  const showLatest = () => {
@@ -2802,18 +2945,18 @@ function ToolActivityReel({
2802
2945
  const timer = window.setTimeout(showLatest, remaining);
2803
2946
  return () => window.clearTimeout(timer);
2804
2947
  }, [label]);
2805
- React14.useEffect(() => {
2948
+ React15.useEffect(() => {
2806
2949
  if (!previous) return;
2807
2950
  const timer = window.setTimeout(() => setPrevious(null), 200);
2808
2951
  return () => window.clearTimeout(timer);
2809
2952
  }, [previous]);
2810
- return /* @__PURE__ */ jsxs8("span", { className: "a24-tool-reel", "aria-live": announce ? "polite" : "off", children: [
2811
- previous ? /* @__PURE__ */ jsx13("span", { "aria-hidden": "true", className: "a24-tool-reel__previous", children: previous }) : null,
2812
- /* @__PURE__ */ jsx13("span", { className: previous ? "a24-tool-reel__current" : void 0, children: displayed })
2953
+ return /* @__PURE__ */ jsxs9("span", { className: "a24-tool-reel", "aria-live": announce ? "polite" : "off", children: [
2954
+ previous ? /* @__PURE__ */ jsx14("span", { "aria-hidden": "true", className: "a24-tool-reel__previous", children: previous }) : null,
2955
+ /* @__PURE__ */ jsx14("span", { className: previous ? "a24-tool-reel__current" : void 0, children: displayed })
2813
2956
  ] });
2814
2957
  }
2815
2958
  function ToolActivityOrb({ label = "Working", kind = "tool", part, renderActivityIcon }) {
2816
- return /* @__PURE__ */ jsx13("span", { className: "a24-tool-orb", children: renderActivityIcon ? renderActivityIcon({ label, kind, part }) : /* @__PURE__ */ jsx13(ThinkingOrb, { "aria-label": label, size: 20, speed: 0.8, state: "searching" }) });
2959
+ return /* @__PURE__ */ jsx14("span", { className: "a24-tool-orb", children: renderActivityIcon ? renderActivityIcon({ label, kind, part }) : /* @__PURE__ */ jsx14(ThinkingOrb, { "aria-label": label, size: 20, speed: 0.8, state: "searching" }) });
2817
2960
  }
2818
2961
  function AgentChatActivityRow({
2819
2962
  label,
@@ -2821,22 +2964,22 @@ function AgentChatActivityRow({
2821
2964
  renderActivityIcon,
2822
2965
  onSelect
2823
2966
  }) {
2824
- const content = /* @__PURE__ */ jsxs8(Fragment4, { children: [
2825
- /* @__PURE__ */ jsx13(ToolActivityOrb, { label, kind: "planning", renderActivityIcon }),
2826
- /* @__PURE__ */ jsx13("span", { className: "a24-tool-trigger__label a24-tool-shimmer", children: /* @__PURE__ */ jsx13(ToolActivityReel, { label }) })
2967
+ const content = /* @__PURE__ */ jsxs9(Fragment4, { children: [
2968
+ /* @__PURE__ */ jsx14(ToolActivityOrb, { label, kind: "planning", renderActivityIcon }),
2969
+ /* @__PURE__ */ jsx14("span", { className: "a24-tool-trigger__label a24-tool-shimmer", children: /* @__PURE__ */ jsx14(ToolActivityReel, { label }) })
2827
2970
  ] });
2828
- return /* @__PURE__ */ jsx13("div", { className: "a24-tool-trigger-row a24-tool-trigger-row--root", "data-agents24-model-turn": modelTurnId, role: "status", children: onSelect ? /* @__PURE__ */ jsx13("button", { className: "a24-tool-trigger a24-tool-trigger--root a24-tool-trigger--active", onClick: onSelect, type: "button", children: content }) : /* @__PURE__ */ jsx13("div", { className: "a24-tool-trigger a24-tool-trigger--root a24-tool-trigger--active", children: content }) });
2971
+ return /* @__PURE__ */ jsx14("div", { className: "a24-tool-trigger-row a24-tool-trigger-row--root", "data-agents24-model-turn": modelTurnId, role: "status", children: onSelect ? /* @__PURE__ */ jsx14("button", { className: "a24-tool-trigger a24-tool-trigger--root a24-tool-trigger--active", onClick: onSelect, type: "button", children: content }) : /* @__PURE__ */ jsx14("div", { className: "a24-tool-trigger a24-tool-trigger--root a24-tool-trigger--active", children: content }) });
2829
2972
  }
2830
2973
  function AgentChatModelTurnRow({ part }) {
2831
- return /* @__PURE__ */ jsx13(AgentChatActivityRow, { label: "Planning next moves", modelTurnId: part.modelTurnId });
2974
+ return /* @__PURE__ */ jsx14(AgentChatActivityRow, { label: "Planning next moves", modelTurnId: part.modelTurnId });
2832
2975
  }
2833
2976
  function AgentChatNodeActivityRow({
2834
2977
  renderActivityIcon,
2835
2978
  onSelect,
2836
2979
  part
2837
2980
  }) {
2838
- const [open, setOpen] = React14.useState(false);
2839
- const contentId = React14.useId();
2981
+ const [open, setOpen] = React15.useState(false);
2982
+ const contentId = React15.useId();
2840
2983
  const running = part.status === "running";
2841
2984
  const failed = part.status === "failed";
2842
2985
  const failureMessage = part.failure?.message || "The node could not complete the request.";
@@ -2847,18 +2990,18 @@ function AgentChatNodeActivityRow({
2847
2990
  running && "a24-tool-trigger--active",
2848
2991
  failed && "a24-tool-trigger--error"
2849
2992
  );
2850
- const label = running ? /* @__PURE__ */ jsx13("span", { className: "a24-tool-shimmer", children: /* @__PURE__ */ jsx13(ToolActivityReel, { label: part.label }) }) : part.label;
2993
+ const label = running ? /* @__PURE__ */ jsx14("span", { className: "a24-tool-shimmer", children: /* @__PURE__ */ jsx14(ToolActivityReel, { label: part.label }) }) : part.label;
2851
2994
  if (!failed) {
2852
- return /* @__PURE__ */ jsx13("div", { className: "a24-tool-trigger-row", role: "status", children: onSelect ? /* @__PURE__ */ jsxs8("button", { className: triggerClassName, onClick: () => onSelect(part), type: "button", children: [
2853
- running ? /* @__PURE__ */ jsx13(ToolActivityOrb, { label: part.label, kind: "node", part, renderActivityIcon }) : null,
2854
- /* @__PURE__ */ jsx13("span", { className: "a24-tool-trigger__label", children: label })
2855
- ] }) : /* @__PURE__ */ jsxs8("div", { className: triggerClassName, children: [
2856
- running ? /* @__PURE__ */ jsx13(ToolActivityOrb, { label: part.label, kind: "node", part, renderActivityIcon }) : null,
2857
- /* @__PURE__ */ jsx13("span", { className: "a24-tool-trigger__label", children: label })
2995
+ return /* @__PURE__ */ jsx14("div", { className: "a24-tool-trigger-row", role: "status", children: onSelect ? /* @__PURE__ */ jsxs9("button", { className: triggerClassName, onClick: () => onSelect(part), type: "button", children: [
2996
+ running ? /* @__PURE__ */ jsx14(ToolActivityOrb, { label: part.label, kind: "node", part, renderActivityIcon }) : null,
2997
+ /* @__PURE__ */ jsx14("span", { className: "a24-tool-trigger__label", children: label })
2998
+ ] }) : /* @__PURE__ */ jsxs9("div", { className: triggerClassName, children: [
2999
+ running ? /* @__PURE__ */ jsx14(ToolActivityOrb, { label: part.label, kind: "node", part, renderActivityIcon }) : null,
3000
+ /* @__PURE__ */ jsx14("span", { className: "a24-tool-trigger__label", children: label })
2858
3001
  ] }) });
2859
3002
  }
2860
- return /* @__PURE__ */ jsxs8("div", { className: "a24-tool-disclosure", children: [
2861
- /* @__PURE__ */ jsx13("div", { className: "a24-tool-trigger-row", children: /* @__PURE__ */ jsxs8(
3003
+ return /* @__PURE__ */ jsxs9("div", { className: "a24-tool-disclosure", children: [
3004
+ /* @__PURE__ */ jsx14("div", { className: "a24-tool-trigger-row", children: /* @__PURE__ */ jsxs9(
2862
3005
  "button",
2863
3006
  {
2864
3007
  "aria-controls": contentId,
@@ -2870,12 +3013,12 @@ function AgentChatNodeActivityRow({
2870
3013
  },
2871
3014
  type: "button",
2872
3015
  children: [
2873
- /* @__PURE__ */ jsx13("span", { className: "a24-tool-trigger__label", children: label }),
2874
- open ? /* @__PURE__ */ jsx13(ChevronDown2, { "aria-hidden": "true", className: "a24-tool-trigger__chevron" }) : /* @__PURE__ */ jsx13(ChevronRight2, { "aria-hidden": "true", className: "a24-tool-trigger__chevron" })
3016
+ /* @__PURE__ */ jsx14("span", { className: "a24-tool-trigger__label", children: label }),
3017
+ open ? /* @__PURE__ */ jsx14(ChevronDown2, { "aria-hidden": "true", className: "a24-tool-trigger__chevron" }) : /* @__PURE__ */ jsx14(ChevronRight2, { "aria-hidden": "true", className: "a24-tool-trigger__chevron" })
2875
3018
  ]
2876
3019
  }
2877
3020
  ) }),
2878
- open ? /* @__PURE__ */ jsx13("div", { className: "a24-tool-detail a24-tool-detail--error", id: contentId, children: failureMessage }) : null
3021
+ open ? /* @__PURE__ */ jsx14("div", { className: "a24-tool-detail a24-tool-detail--error", id: contentId, children: failureMessage }) : null
2879
3022
  ] });
2880
3023
  }
2881
3024
  function toolRowLabel(part, separateResource = false) {
@@ -2902,25 +3045,25 @@ function ToolDisclosure({
2902
3045
  renderActivityIcon,
2903
3046
  accessory
2904
3047
  }) {
2905
- const [open, setOpen] = React14.useState(false);
2906
- const contentId = React14.useId();
2907
- const expandable = React14.Children.toArray(children).length > 0;
3048
+ const [open, setOpen] = React15.useState(false);
3049
+ const contentId = React15.useId();
3050
+ const expandable = React15.Children.toArray(children).length > 0;
2908
3051
  if (!expandable) {
2909
3052
  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");
2910
- return /* @__PURE__ */ jsxs8("div", { className: cn("a24-tool-trigger-row", root && "a24-tool-trigger-row--root"), children: [
2911
- onSelect && part ? /* @__PURE__ */ jsxs8("button", { className: triggerClassName, onClick: () => onSelect(part), type: "button", children: [
2912
- showOrb ? /* @__PURE__ */ jsx13(ToolActivityOrb, { label: statusLabel || "Working", kind: grouped ? "group" : "tool", part, renderActivityIcon }) : null,
2913
- /* @__PURE__ */ jsx13("span", { className: "a24-tool-trigger__label", children: label })
2914
- ] }) : /* @__PURE__ */ jsxs8("div", { className: triggerClassName, children: [
2915
- showOrb ? /* @__PURE__ */ jsx13(ToolActivityOrb, { label: statusLabel || "Working", kind: grouped ? "group" : "tool", part, renderActivityIcon }) : null,
2916
- /* @__PURE__ */ jsx13("span", { className: "a24-tool-trigger__label", children: label })
3053
+ return /* @__PURE__ */ jsxs9("div", { className: cn("a24-tool-trigger-row", root && "a24-tool-trigger-row--root"), children: [
3054
+ onSelect && part ? /* @__PURE__ */ jsxs9("button", { className: triggerClassName, onClick: () => onSelect(part), type: "button", children: [
3055
+ showOrb ? /* @__PURE__ */ jsx14(ToolActivityOrb, { label: statusLabel || "Working", kind: grouped ? "group" : "tool", part, renderActivityIcon }) : null,
3056
+ /* @__PURE__ */ jsx14("span", { className: "a24-tool-trigger__label", children: label })
3057
+ ] }) : /* @__PURE__ */ jsxs9("div", { className: triggerClassName, children: [
3058
+ showOrb ? /* @__PURE__ */ jsx14(ToolActivityOrb, { label: statusLabel || "Working", kind: grouped ? "group" : "tool", part, renderActivityIcon }) : null,
3059
+ /* @__PURE__ */ jsx14("span", { className: "a24-tool-trigger__label", children: label })
2917
3060
  ] }),
2918
3061
  accessory
2919
3062
  ] });
2920
3063
  }
2921
- return /* @__PURE__ */ jsxs8("div", { className: "a24-tool-disclosure", children: [
2922
- /* @__PURE__ */ jsxs8("div", { className: cn("a24-tool-trigger-row", root && "a24-tool-trigger-row--root"), children: [
2923
- /* @__PURE__ */ jsxs8(
3064
+ return /* @__PURE__ */ jsxs9("div", { className: "a24-tool-disclosure", children: [
3065
+ /* @__PURE__ */ jsxs9("div", { className: cn("a24-tool-trigger-row", root && "a24-tool-trigger-row--root"), children: [
3066
+ /* @__PURE__ */ jsxs9(
2924
3067
  "button",
2925
3068
  {
2926
3069
  "aria-controls": contentId,
@@ -2934,25 +3077,25 @@ function ToolDisclosure({
2934
3077
  },
2935
3078
  type: "button",
2936
3079
  children: [
2937
- showOrb ? /* @__PURE__ */ jsx13(ToolActivityOrb, { label: statusLabel || "Working", kind: grouped ? "group" : "tool", part, renderActivityIcon }) : null,
2938
- /* @__PURE__ */ jsx13("span", { className: "a24-tool-trigger__label", children: label }),
2939
- open ? /* @__PURE__ */ jsx13(ChevronDown2, { "aria-hidden": "true", className: "a24-tool-trigger__chevron" }) : /* @__PURE__ */ jsx13(ChevronRight2, { "aria-hidden": "true", className: "a24-tool-trigger__chevron" })
3080
+ showOrb ? /* @__PURE__ */ jsx14(ToolActivityOrb, { label: statusLabel || "Working", kind: grouped ? "group" : "tool", part, renderActivityIcon }) : null,
3081
+ /* @__PURE__ */ jsx14("span", { className: "a24-tool-trigger__label", children: label }),
3082
+ open ? /* @__PURE__ */ jsx14(ChevronDown2, { "aria-hidden": "true", className: "a24-tool-trigger__chevron" }) : /* @__PURE__ */ jsx14(ChevronRight2, { "aria-hidden": "true", className: "a24-tool-trigger__chevron" })
2940
3083
  ]
2941
3084
  }
2942
3085
  ),
2943
3086
  accessory
2944
3087
  ] }),
2945
- open ? /* @__PURE__ */ jsx13("div", { className: "a24-tool-disclosure__content", id: contentId, children }) : null
3088
+ open ? /* @__PURE__ */ jsx14("div", { className: "a24-tool-disclosure__content", id: contentId, children }) : null
2946
3089
  ] });
2947
3090
  }
2948
3091
  function ToolLabel({ active, label, part, slots }) {
2949
3092
  const rendered = slots?.renderToolLabel?.(toolSlotContext(active, label, part, slots)) ?? label;
2950
- return active ? /* @__PURE__ */ jsx13("span", { className: "a24-tool-shimmer", children: rendered }) : /* @__PURE__ */ jsx13(Fragment4, { children: rendered });
3093
+ return active ? /* @__PURE__ */ jsx14("span", { className: "a24-tool-shimmer", children: rendered }) : /* @__PURE__ */ jsx14(Fragment4, { children: rendered });
2951
3094
  }
2952
3095
  function ToolList({ children }) {
2953
- const listRef = React14.useRef(null);
2954
- const [fades, setFades] = React14.useState({ bottom: false, top: false });
2955
- const updateFades = React14.useCallback(() => {
3096
+ const listRef = React15.useRef(null);
3097
+ const [fades, setFades] = React15.useState({ bottom: false, top: false });
3098
+ const updateFades = React15.useCallback(() => {
2956
3099
  const list = listRef.current;
2957
3100
  if (!list) return;
2958
3101
  const next = {
@@ -2961,7 +3104,7 @@ function ToolList({ children }) {
2961
3104
  };
2962
3105
  setFades((current) => current.bottom === next.bottom && current.top === next.top ? current : next);
2963
3106
  }, []);
2964
- React14.useEffect(() => {
3107
+ React15.useEffect(() => {
2965
3108
  updateFades();
2966
3109
  const list = listRef.current;
2967
3110
  if (!list || typeof ResizeObserver === "undefined") return;
@@ -2969,13 +3112,13 @@ function ToolList({ children }) {
2969
3112
  observer.observe(list);
2970
3113
  return () => observer.disconnect();
2971
3114
  }, [children, updateFades]);
2972
- return /* @__PURE__ */ jsx13(
3115
+ return /* @__PURE__ */ jsx14(
2973
3116
  "div",
2974
3117
  {
2975
3118
  className: "a24-tool-list-frame",
2976
3119
  "data-scroll-fade-bottom": fades.bottom ? "" : void 0,
2977
3120
  "data-scroll-fade-top": fades.top ? "" : void 0,
2978
- children: /* @__PURE__ */ jsx13("div", { className: "a24-tool-list", onScroll: updateFades, ref: listRef, role: "list", children })
3121
+ children: /* @__PURE__ */ jsx14("div", { className: "a24-tool-list", onScroll: updateFades, ref: listRef, role: "list", children })
2979
3122
  }
2980
3123
  );
2981
3124
  }
@@ -2992,13 +3135,13 @@ function AgentChatToolRow({
2992
3135
  const detail = failed ? failureMessage : optionalText(part.presentation.detail);
2993
3136
  const hostDetails = failed ? null : slots?.renderToolDetails?.(part);
2994
3137
  const context = toolSlotContext(active, toolRowLabel(part, Boolean(slots?.onResourceAction)), part, slots);
2995
- return /* @__PURE__ */ jsx13("div", { "data-agents24-tool-part": part.type, "data-state": part.state, children: /* @__PURE__ */ jsxs8(
3138
+ return /* @__PURE__ */ jsx14("div", { "data-agents24-tool-part": part.type, "data-state": part.state, children: /* @__PURE__ */ jsxs9(
2996
3139
  ToolDisclosure,
2997
3140
  {
2998
3141
  renderActivityIcon: slots?.renderActivityIcon,
2999
3142
  error: failed,
3000
3143
  accessory: toolAccessory(context, slots),
3001
- label: /* @__PURE__ */ jsx13(ToolLabel, { active, label: context.label, part, slots }),
3144
+ label: /* @__PURE__ */ jsx14(ToolLabel, { active, label: context.label, part, slots }),
3002
3145
  loading: active,
3003
3146
  onExpandedChange: slots?.onExpandedChange,
3004
3147
  onSelect: slots?.onToolSelect,
@@ -3007,7 +3150,7 @@ function AgentChatToolRow({
3007
3150
  showOrb: showOrb ?? active,
3008
3151
  statusLabel: active ? context.label : void 0,
3009
3152
  children: [
3010
- detail ? /* @__PURE__ */ jsx13("div", { className: cn("a24-tool-detail", failed && "a24-tool-detail--error"), children: detail }) : null,
3153
+ detail ? /* @__PURE__ */ jsx14("div", { className: cn("a24-tool-detail", failed && "a24-tool-detail--error"), children: detail }) : null,
3011
3154
  hostDetails
3012
3155
  ]
3013
3156
  }
@@ -3027,19 +3170,19 @@ function AgentChatToolSession({
3027
3170
  parts,
3028
3171
  slots
3029
3172
  }) {
3030
- const presentedLiveRef = React14.useRef(false);
3173
+ const presentedLiveRef = React15.useRef(false);
3031
3174
  if (isLive && isLatestActivity) presentedLiveRef.current = true;
3032
3175
  const activeIndex = parts.findLastIndex((part) => isActive(part, activeToolId));
3033
3176
  const running = activeIndex >= 0;
3034
- if (parts.length === 1 && !modelTurn && !leadingModelTurn) return /* @__PURE__ */ jsx13(AgentChatToolRow, { activeToolId, part: parts[0], slots });
3177
+ if (parts.length === 1 && !modelTurn && !leadingModelTurn) return /* @__PURE__ */ jsx14(AgentChatToolRow, { activeToolId, part: parts[0], slots });
3035
3178
  const visibleIndex = running ? activeIndex : parts.length - 1;
3036
3179
  const visiblePart = parts[visibleIndex];
3037
3180
  const planning = Boolean(modelTurn);
3038
3181
  const presentingActivity = isLatestActivity && (planning || running || isLive);
3039
3182
  const failed = isLatestActivity && (visiblePart.state === "output-error" || visiblePart.state === "cancelled");
3040
3183
  const label = planning ? "Planning next moves" : isLive && isLatestActivity ? toolRowLabel(visiblePart, true) : sessionLabel(parts, visiblePart, running);
3041
- const labelContent = presentedLiveRef.current ? /* @__PURE__ */ jsx13("span", { className: presentingActivity ? "a24-tool-shimmer" : void 0, children: /* @__PURE__ */ jsx13(ToolActivityReel, { initialLabel: leadingModelTurn ? "Planning next moves" : void 0, initialShownAt: leadingModelTurn?.timestamp, label }) }) : label;
3042
- return /* @__PURE__ */ jsx13(
3184
+ const labelContent = presentedLiveRef.current ? /* @__PURE__ */ jsx14("span", { className: presentingActivity ? "a24-tool-shimmer" : void 0, children: /* @__PURE__ */ jsx14(ToolActivityReel, { initialLabel: leadingModelTurn ? "Planning next moves" : void 0, initialShownAt: leadingModelTurn?.timestamp, label }) }) : label;
3185
+ return /* @__PURE__ */ jsx14(
3043
3186
  ToolDisclosure,
3044
3187
  {
3045
3188
  renderActivityIcon: slots?.renderActivityIcon,
@@ -3052,7 +3195,7 @@ function AgentChatToolSession({
3052
3195
  root: true,
3053
3196
  showOrb: isLive && isLatestActivity,
3054
3197
  statusLabel: planning ? "Planning next moves" : label,
3055
- children: /* @__PURE__ */ jsx13(ToolList, { children: parts.map((part) => /* @__PURE__ */ jsx13("div", { role: "listitem", children: /* @__PURE__ */ jsx13(AgentChatToolRow, { activeToolId, part, root: false, showOrb: false, slots }) }, part.id)) })
3198
+ children: /* @__PURE__ */ jsx14(ToolList, { children: parts.map((part) => /* @__PURE__ */ jsx14("div", { role: "listitem", children: /* @__PURE__ */ jsx14(AgentChatToolRow, { activeToolId, part, root: false, showOrb: false, slots }) }, part.id)) })
3056
3199
  }
3057
3200
  );
3058
3201
  }
@@ -3073,7 +3216,7 @@ function subagentLabel(part) {
3073
3216
  return { label: `Agent ${name}, ran ${children.length} ${children.length === 1 ? "tool" : "tools"}`, running: false };
3074
3217
  }
3075
3218
  function AgentChatSubagentGroup({ isLatestActivity = true, isLive = false, part, slots }) {
3076
- const presentedLiveRef = React14.useRef(false);
3219
+ const presentedLiveRef = React15.useRef(false);
3077
3220
  if (isLive && isLatestActivity) presentedLiveRef.current = true;
3078
3221
  const children = part.presentation.childTools || [];
3079
3222
  const state = subagentLabel(part);
@@ -3082,9 +3225,9 @@ function AgentChatSubagentGroup({ isLatestActivity = true, isLive = false, part,
3082
3225
  const hostDetails = failed ? null : slots?.renderToolDetails?.(part);
3083
3226
  const failureMessage = part.failure?.message || null;
3084
3227
  const presentingActivity = isLatestActivity && state.running;
3085
- const labelContent = presentedLiveRef.current ? /* @__PURE__ */ jsx13("span", { className: presentingActivity ? "a24-tool-shimmer" : void 0, children: /* @__PURE__ */ jsx13(ToolActivityReel, { label: state.label }) }) : state.label;
3228
+ const labelContent = presentedLiveRef.current ? /* @__PURE__ */ jsx14("span", { className: presentingActivity ? "a24-tool-shimmer" : void 0, children: /* @__PURE__ */ jsx14(ToolActivityReel, { label: state.label }) }) : state.label;
3086
3229
  const context = toolSlotContext(presentingActivity, state.label, part, slots);
3087
- return /* @__PURE__ */ jsx13(
3230
+ return /* @__PURE__ */ jsx14(
3088
3231
  ToolDisclosure,
3089
3232
  {
3090
3233
  renderActivityIcon: slots?.renderActivityIcon,
@@ -3098,12 +3241,12 @@ function AgentChatSubagentGroup({ isLatestActivity = true, isLive = false, part,
3098
3241
  root: true,
3099
3242
  showOrb: isLive && isLatestActivity,
3100
3243
  statusLabel: state.label,
3101
- children: /* @__PURE__ */ jsxs8(ToolList, { children: [
3102
- children.map((child) => /* @__PURE__ */ jsx13("div", { className: cn("a24-child-tool", child.status === "failed" && "a24-child-tool--error"), role: "listitem", children: slots?.renderChildTool?.(child, part) ?? /* @__PURE__ */ jsxs8(Fragment4, { children: [
3103
- /* @__PURE__ */ jsx13("span", { className: cn(isLive && isLatestActivity && child.status === "running" && "a24-tool-shimmer"), children: childLabel(child) }),
3104
- child.detail ? /* @__PURE__ */ jsx13("span", { className: "a24-child-tool__detail", children: child.detail }) : null
3244
+ children: /* @__PURE__ */ jsxs9(ToolList, { children: [
3245
+ children.map((child) => /* @__PURE__ */ jsx14("div", { className: cn("a24-child-tool", child.status === "failed" && "a24-child-tool--error"), role: "listitem", children: slots?.renderChildTool?.(child, part) ?? /* @__PURE__ */ jsxs9(Fragment4, { children: [
3246
+ /* @__PURE__ */ jsx14("span", { className: cn(isLive && isLatestActivity && child.status === "running" && "a24-tool-shimmer"), children: childLabel(child) }),
3247
+ child.detail ? /* @__PURE__ */ jsx14("span", { className: "a24-child-tool__detail", children: child.detail }) : null
3105
3248
  ] }) }, child.id)),
3106
- failureMessage ? /* @__PURE__ */ jsx13("div", { className: "a24-tool-detail a24-tool-detail--error", children: failureMessage }) : null,
3249
+ failureMessage ? /* @__PURE__ */ jsx14("div", { className: "a24-tool-detail a24-tool-detail--error", children: failureMessage }) : null,
3107
3250
  hostDetails
3108
3251
  ] })
3109
3252
  }
@@ -3111,41 +3254,51 @@ function AgentChatSubagentGroup({ isLatestActivity = true, isLive = false, part,
3111
3254
  }
3112
3255
 
3113
3256
  // src/ui/agent-response-timeline.tsx
3114
- import { jsx as jsx14, jsxs as jsxs9 } from "react/jsx-runtime";
3257
+ import { jsx as jsx15, jsxs as jsxs10 } from "react/jsx-runtime";
3115
3258
  function isInternalAskUserTool(part) {
3116
3259
  return [part.toolName, part.toolKey, part.action].some((value) => value?.trim().toLowerCase() === "runtime__ask_user");
3117
3260
  }
3118
3261
  function Shimmer({ children, className }) {
3119
- return /* @__PURE__ */ jsx14("span", { className: cn("inline-block animate-pulse", className), children });
3262
+ return /* @__PURE__ */ jsx15("span", { className: cn("inline-block animate-pulse", className), children });
3120
3263
  }
3121
3264
  function AgentChatToolPart({
3122
3265
  activeToolId,
3123
3266
  part
3124
3267
  }) {
3125
- return /* @__PURE__ */ jsx14(AgentChatToolRow, { activeToolId, part });
3268
+ return /* @__PURE__ */ jsx15(AgentChatToolRow, { activeToolId, part });
3126
3269
  }
3127
3270
  function AgentChatToolGroup({
3128
3271
  activeToolId,
3129
3272
  parts
3130
3273
  }) {
3131
- return /* @__PURE__ */ jsx14(AgentChatToolSession, { activeToolId, parts });
3274
+ return /* @__PURE__ */ jsx15(AgentChatToolSession, { activeToolId, parts });
3132
3275
  }
3133
3276
  function HitlPartRow({
3134
3277
  getHitlActionState,
3278
+ hitlLabels,
3279
+ onHitlPaint,
3135
3280
  isLoading,
3136
3281
  onHitlAction,
3137
3282
  part
3138
3283
  }) {
3139
3284
  const state = getHitlActionState?.(part);
3140
- const [comment, setComment] = React15.useState("");
3285
+ const [comment, setComment] = React16.useState("");
3286
+ const commentRef = React16.useRef(null);
3287
+ const retryActionRef = React16.useRef(null);
3288
+ React16.useEffect(() => {
3289
+ if (state?.status === "error") (commentRef.current || retryActionRef.current)?.focus();
3290
+ }, [state?.status]);
3141
3291
  const presentation = part.presentation || {};
3142
3292
  const requireComment = presentation.require_comment === true;
3143
3293
  const isTerminal = part.status !== "pending";
3144
3294
  if (part.hitlKind === "user_input") {
3145
- return /* @__PURE__ */ jsx14(
3295
+ return /* @__PURE__ */ jsx15(
3146
3296
  AskUserInteraction,
3147
3297
  {
3148
3298
  error: state?.error,
3299
+ submission: state,
3300
+ submissionLabels: hitlLabels,
3301
+ onSubmissionPaint: onHitlPaint,
3149
3302
  isBusy: isLoading || state?.status === "resuming",
3150
3303
  onSubmit: onHitlAction ? (answers) => onHitlAction(part, {
3151
3304
  action: "respond",
@@ -3159,12 +3312,14 @@ function HitlPartRow({
3159
3312
  }
3160
3313
  );
3161
3314
  }
3315
+ if (isHitlSubmissionCompact(state)) return /* @__PURE__ */ jsx15(HitlSubmissionStatus, { state, labels: hitlLabels, onPaint: onHitlPaint });
3162
3316
  if (isTerminal) return null;
3163
- return /* @__PURE__ */ jsxs9("div", { className: "a24-hitl space-y-2.5 px-1 py-2", children: [
3164
- /* @__PURE__ */ jsx14("div", { className: "a24-hitl__title text-sm font-medium text-foreground text-pretty", children: hitlTitle(part) }),
3165
- requireComment ? /* @__PURE__ */ jsx14(
3317
+ return /* @__PURE__ */ jsxs10("div", { className: "a24-hitl space-y-2.5 px-1 py-2", children: [
3318
+ /* @__PURE__ */ jsx15("div", { className: "a24-hitl__title text-sm font-medium text-foreground text-pretty", children: hitlTitle(part) }),
3319
+ requireComment ? /* @__PURE__ */ jsx15(
3166
3320
  "textarea",
3167
3321
  {
3322
+ ref: commentRef,
3168
3323
  "aria-label": "Approval comment",
3169
3324
  autoComplete: "off",
3170
3325
  className: "a24-hitl__comment min-h-20 w-full resize-y rounded-md border border-border/60 bg-background px-3 py-2 text-sm outline-none focus-visible:border-neutral-300 focus-visible:ring-0 dark:focus-visible:border-neutral-600",
@@ -3174,10 +3329,11 @@ function HitlPartRow({
3174
3329
  value: comment
3175
3330
  }
3176
3331
  ) : null,
3177
- state?.error ? /* @__PURE__ */ jsx14("div", { className: "a24-hitl__error text-sm text-destructive", children: state.error }) : null,
3178
- /* @__PURE__ */ jsx14("div", { className: "a24-hitl__actions flex flex-wrap items-center gap-1.5", children: part.allowedActions.map((action) => /* @__PURE__ */ jsx14(
3332
+ state?.error ? /* @__PURE__ */ jsx15("div", { className: "a24-hitl__error text-sm text-destructive", children: state.error }) : null,
3333
+ /* @__PURE__ */ jsx15("div", { className: "a24-hitl__actions flex flex-wrap items-center gap-1.5", children: part.allowedActions.map((action) => /* @__PURE__ */ jsx15(
3179
3334
  "button",
3180
3335
  {
3336
+ ref: state?.action === action || !state?.action && action === part.allowedActions[0] ? retryActionRef : void 0,
3181
3337
  "aria-label": hitlActionLabel(part, action),
3182
3338
  className: cn(
3183
3339
  "a24-hitl__action min-h-10 rounded-md px-3 text-sm font-medium transition-[background-color,color,opacity,transform] duration-150 ease-out active:scale-[0.96] disabled:pointer-events-none disabled:opacity-60",
@@ -3199,6 +3355,8 @@ function HitlPartRow({
3199
3355
  function AgentChatPart({
3200
3356
  activeToolId,
3201
3357
  getHitlActionState,
3358
+ hitlLabels,
3359
+ onHitlPaint,
3202
3360
  isLoading,
3203
3361
  isTextStreaming,
3204
3362
  message,
@@ -3208,7 +3366,7 @@ function AgentChatPart({
3208
3366
  toolSlots
3209
3367
  }) {
3210
3368
  if (part.kind === "text") {
3211
- return /* @__PURE__ */ jsx14(
3369
+ return /* @__PURE__ */ jsx15(
3212
3370
  MessageResponse,
3213
3371
  {
3214
3372
  ...responseProps,
@@ -3218,44 +3376,46 @@ function AgentChatPart({
3218
3376
  }
3219
3377
  );
3220
3378
  }
3221
- if (part.kind === "tool") return isAgentChatSubagent(part) ? /* @__PURE__ */ jsx14(AgentChatSubagentGroup, { part, slots: toolSlots }) : /* @__PURE__ */ jsx14(AgentChatToolRow, { activeToolId, part, slots: toolSlots });
3222
- if (part.kind === "model-turn") return /* @__PURE__ */ jsx14(AgentChatModelTurnRow, { part });
3379
+ if (part.kind === "tool") return isAgentChatSubagent(part) ? /* @__PURE__ */ jsx15(AgentChatSubagentGroup, { part, slots: toolSlots }) : /* @__PURE__ */ jsx15(AgentChatToolRow, { activeToolId, part, slots: toolSlots });
3380
+ if (part.kind === "model-turn") return /* @__PURE__ */ jsx15(AgentChatModelTurnRow, { part });
3223
3381
  if (part.kind === "reasoning") {
3224
3382
  const label = part.text || part.label || "Thinking";
3225
- return part.status === "running" || part.status === "streaming" ? /* @__PURE__ */ jsx14(Shimmer, { className: "text-sm text-muted-foreground", children: label }) : /* @__PURE__ */ jsx14("div", { className: "text-sm text-muted-foreground", children: label });
3383
+ return part.status === "running" || part.status === "streaming" ? /* @__PURE__ */ jsx15(Shimmer, { className: "text-sm text-muted-foreground", children: label }) : /* @__PURE__ */ jsx15("div", { className: "text-sm text-muted-foreground", children: label });
3226
3384
  }
3227
3385
  if (part.kind === "context-compression") {
3228
- return /* @__PURE__ */ jsx14(AgentChatContextCompressionRow, { part });
3386
+ return /* @__PURE__ */ jsx15(AgentChatContextCompressionRow, { part });
3229
3387
  }
3230
3388
  if (part.kind === "ui-blocks") {
3231
3389
  if (part.state === "output-error") {
3232
- return /* @__PURE__ */ jsx14("div", { className: "a24-timeline-error text-sm text-destructive", children: part.errorText || "Failed to render UI content." });
3390
+ return /* @__PURE__ */ jsx15("div", { className: "a24-timeline-error text-sm text-destructive", children: part.errorText || "Failed to render UI content." });
3233
3391
  }
3234
- return part.bundle ? /* @__PURE__ */ jsx14(SafeUiBlocks, { bundle: part.bundle }) : /* @__PURE__ */ jsx14("div", { className: "text-sm text-muted-foreground", children: part.state === "input-streaming" ? /* @__PURE__ */ jsx14(Shimmer, { children: "Rendering UI block" }) : "Rendered UI block" });
3392
+ return part.bundle ? /* @__PURE__ */ jsx15(SafeUiBlocks, { bundle: part.bundle }) : /* @__PURE__ */ jsx15("div", { className: "text-sm text-muted-foreground", children: part.state === "input-streaming" ? /* @__PURE__ */ jsx15(Shimmer, { children: "Rendering UI block" }) : "Rendered UI block" });
3235
3393
  }
3236
3394
  if (part.kind === "hitl") {
3237
- return /* @__PURE__ */ jsx14(
3395
+ return /* @__PURE__ */ jsx15(
3238
3396
  HitlPartRow,
3239
3397
  {
3240
3398
  getHitlActionState,
3399
+ hitlLabels,
3400
+ onHitlPaint,
3241
3401
  isLoading,
3242
3402
  onHitlAction,
3243
3403
  part
3244
3404
  }
3245
3405
  );
3246
3406
  }
3247
- if (part.kind === "error") return /* @__PURE__ */ jsx14("div", { className: "a24-timeline-error text-sm text-destructive", role: "alert", children: part.errorText });
3407
+ if (part.kind === "error") return /* @__PURE__ */ jsx15("div", { className: "a24-timeline-error text-sm text-destructive", role: "alert", children: part.errorText });
3248
3408
  if (part.kind === "source") {
3249
3409
  const href = safeExternalUrl(part.url);
3250
- return href ? /* @__PURE__ */ jsx14("a", { className: "a24-source-link", href, rel: "noopener noreferrer", target: "_blank", children: part.title }) : /* @__PURE__ */ jsx14("span", { className: "a24-source-link", children: part.title });
3410
+ return href ? /* @__PURE__ */ jsx15("a", { className: "a24-source-link", href, rel: "noopener noreferrer", target: "_blank", children: part.title }) : /* @__PURE__ */ jsx15("span", { className: "a24-source-link", children: part.title });
3251
3411
  }
3252
3412
  if (part.kind === "citation") {
3253
3413
  const href = safeExternalUrl(part.url);
3254
3414
  const label = part.label || "Citation";
3255
- return href ? /* @__PURE__ */ jsx14("a", { className: "a24-citation", href, rel: "noopener noreferrer", target: "_blank", children: label }) : /* @__PURE__ */ jsx14("span", { className: "a24-citation", children: label });
3415
+ return href ? /* @__PURE__ */ jsx15("a", { className: "a24-citation", href, rel: "noopener noreferrer", target: "_blank", children: label }) : /* @__PURE__ */ jsx15("span", { className: "a24-citation", children: label });
3256
3416
  }
3257
- if (part.kind === "attachment") return /* @__PURE__ */ jsx14("div", { className: "a24-output-attachment", children: part.attachment.filename || "Attachment" });
3258
- if (part.kind === "data") return /* @__PURE__ */ jsx14("div", { "data-agents24-data-part": part.name, className: "hidden", children: message.id });
3417
+ if (part.kind === "attachment") return /* @__PURE__ */ jsx15("div", { className: "a24-output-attachment", children: part.attachment.filename || "Attachment" });
3418
+ if (part.kind === "data") return /* @__PURE__ */ jsx15("div", { "data-agents24-data-part": part.name, className: "hidden", children: message.id });
3259
3419
  return null;
3260
3420
  }
3261
3421
  function safeExternalUrl(value) {
@@ -3269,28 +3429,28 @@ function safeExternalUrl(value) {
3269
3429
  }
3270
3430
  function SafeUiBlocks({ bundle }) {
3271
3431
  const rows = Array.isArray(bundle.rows) ? bundle.rows : [];
3272
- return /* @__PURE__ */ jsxs9("section", { "aria-label": typeof bundle.title === "string" ? bundle.title : "Agent result", className: "a24-ui-blocks", children: [
3273
- typeof bundle.title === "string" ? /* @__PURE__ */ jsx14("h3", { children: bundle.title }) : null,
3432
+ return /* @__PURE__ */ jsxs10("section", { "aria-label": typeof bundle.title === "string" ? bundle.title : "Agent result", className: "a24-ui-blocks", children: [
3433
+ typeof bundle.title === "string" ? /* @__PURE__ */ jsx15("h3", { children: bundle.title }) : null,
3274
3434
  rows.map((rawRow, rowIndex) => {
3275
3435
  const row = rawRow && typeof rawRow === "object" && !Array.isArray(rawRow) ? rawRow : {};
3276
3436
  const blocks = Array.isArray(row.blocks) ? row.blocks : [];
3277
- return /* @__PURE__ */ jsx14("div", { className: "a24-ui-blocks__row", children: blocks.map((rawBlock, blockIndex) => {
3437
+ return /* @__PURE__ */ jsx15("div", { className: "a24-ui-blocks__row", children: blocks.map((rawBlock, blockIndex) => {
3278
3438
  const block = rawBlock && typeof rawBlock === "object" && !Array.isArray(rawBlock) ? rawBlock : {};
3279
3439
  const title = typeof block.title === "string" ? block.title : "Result";
3280
3440
  const kind = String(block.kind || "note");
3281
3441
  if (kind === "table" && Array.isArray(block.columns) && Array.isArray(block.rows)) {
3282
- return /* @__PURE__ */ jsxs9("div", { className: "a24-ui-block", children: [
3283
- /* @__PURE__ */ jsx14("h4", { children: title }),
3284
- /* @__PURE__ */ jsx14("div", { className: "a24-ui-table-scroll", children: /* @__PURE__ */ jsxs9("table", { children: [
3285
- /* @__PURE__ */ jsx14("thead", { children: /* @__PURE__ */ jsx14("tr", { children: block.columns.map((column, index) => /* @__PURE__ */ jsx14("th", { children: String(column) }, index)) }) }),
3286
- /* @__PURE__ */ jsx14("tbody", { children: block.rows.map((rawCells, index) => /* @__PURE__ */ jsx14("tr", { children: (Array.isArray(rawCells) ? rawCells : []).map((cell, cellIndex) => /* @__PURE__ */ jsx14("td", { children: String(cell) }, cellIndex)) }, index)) })
3442
+ return /* @__PURE__ */ jsxs10("div", { className: "a24-ui-block", children: [
3443
+ /* @__PURE__ */ jsx15("h4", { children: title }),
3444
+ /* @__PURE__ */ jsx15("div", { className: "a24-ui-table-scroll", children: /* @__PURE__ */ jsxs10("table", { children: [
3445
+ /* @__PURE__ */ jsx15("thead", { children: /* @__PURE__ */ jsx15("tr", { children: block.columns.map((column, index) => /* @__PURE__ */ jsx15("th", { children: String(column) }, index)) }) }),
3446
+ /* @__PURE__ */ jsx15("tbody", { children: block.rows.map((rawCells, index) => /* @__PURE__ */ jsx15("tr", { children: (Array.isArray(rawCells) ? rawCells : []).map((cell, cellIndex) => /* @__PURE__ */ jsx15("td", { children: String(cell) }, cellIndex)) }, index)) })
3287
3447
  ] }) })
3288
3448
  ] }, String(block.id || blockIndex));
3289
3449
  }
3290
3450
  const value = block.value ?? block.text ?? "";
3291
- return /* @__PURE__ */ jsxs9("div", { className: "a24-ui-block", children: [
3292
- /* @__PURE__ */ jsx14("h4", { children: title }),
3293
- /* @__PURE__ */ jsx14("p", { children: String(value) })
3451
+ return /* @__PURE__ */ jsxs10("div", { className: "a24-ui-block", children: [
3452
+ /* @__PURE__ */ jsx15("h4", { children: title }),
3453
+ /* @__PURE__ */ jsx15("p", { children: String(value) })
3294
3454
  ] }, String(block.id || blockIndex));
3295
3455
  }) }, `row-${rowIndex}`);
3296
3456
  })
@@ -3298,6 +3458,8 @@ function SafeUiBlocks({ bundle }) {
3298
3458
  }
3299
3459
  function AgentResponseTimeline({
3300
3460
  getHitlActionState,
3461
+ hitlLabels,
3462
+ onHitlPaint,
3301
3463
  isLoading = false,
3302
3464
  message,
3303
3465
  nodeActivityMode = "default",
@@ -3310,7 +3472,7 @@ function AgentResponseTimeline({
3310
3472
  toolViewMode = "closed"
3311
3473
  }) {
3312
3474
  isLoading = isLoading && !message.responseCompletion;
3313
- const parts = (displayParts || message.parts || []).filter((part) => (part.kind !== "tool" || !isInternalAskUserTool(part)) && (part.kind !== "hitl" || part.hitlKind === "user_input" || part.status === "pending") && (part.kind !== "model-turn" || part.turnKind === "agent") && (part.kind !== "node-activity" || nodeActivityMode === "all" || nodeActivityMode === "default" && part.defaultChatVisible));
3475
+ const parts = (displayParts || message.parts || []).filter((part) => (part.kind !== "tool" || !isInternalAskUserTool(part)) && (part.kind !== "hitl" || part.hitlKind === "user_input" || part.status === "pending" || getHitlActionState?.(part)?.status === "accepted") && (part.kind !== "model-turn" || part.turnKind === "agent") && (part.kind !== "node-activity" || nodeActivityMode === "all" || nodeActivityMode === "default" && part.defaultChatVisible));
3314
3476
  const toolParts = parts.filter((part) => part.kind === "tool");
3315
3477
  const activeToolId = latestRunningAgentChatToolId(toolParts);
3316
3478
  const activeTextPartId = getActiveStreamingTextPartId(
@@ -3324,42 +3486,44 @@ function AgentResponseTimeline({
3324
3486
  if (segment.kind === "tool") {
3325
3487
  const isLatestActivity = segmentIndex === segments.length - 1;
3326
3488
  const showOrb = toolViewMode === "closed" ? isLoading && isLatestActivity : Boolean(activeToolId && (segment.part.id === activeToolId || segment.part.toolCallId === activeToolId));
3327
- rendered.push(/* @__PURE__ */ jsx14(AgentChatToolRow, { activeToolId, part: segment.part, showOrb, slots: toolSlots }, segment.part.id));
3489
+ rendered.push(/* @__PURE__ */ jsx15(AgentChatToolRow, { activeToolId, part: segment.part, showOrb, slots: toolSlots }, segment.part.id));
3328
3490
  continue;
3329
3491
  }
3330
3492
  if (segment.kind === "tool-session") {
3331
- rendered.push(/* @__PURE__ */ jsx14(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}`));
3493
+ rendered.push(/* @__PURE__ */ jsx15(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}`));
3332
3494
  continue;
3333
3495
  }
3334
3496
  if (segment.kind === "subagent") {
3335
- rendered.push(/* @__PURE__ */ jsx14(AgentChatSubagentGroup, { isLatestActivity: segmentIndex === segments.length - 1, isLive: isLoading, part: segment.part, slots: toolSlots }, segment.part.id));
3497
+ rendered.push(/* @__PURE__ */ jsx15(AgentChatSubagentGroup, { isLatestActivity: segmentIndex === segments.length - 1, isLive: isLoading, part: segment.part, slots: toolSlots }, segment.part.id));
3336
3498
  continue;
3337
3499
  }
3338
3500
  const part = segment.part;
3339
3501
  if (part.kind === "model-turn") {
3340
3502
  const key = activeActivityClaimed ? part.id : `${message.id}-active-activity`;
3341
3503
  activeActivityClaimed = true;
3342
- rendered.push(/* @__PURE__ */ jsx14(AgentChatActivityRow, { renderActivityIcon: toolSlots?.renderActivityIcon, label: "Planning next moves", modelTurnId: part.modelTurnId }, key));
3504
+ rendered.push(/* @__PURE__ */ jsx15(AgentChatActivityRow, { renderActivityIcon: toolSlots?.renderActivityIcon, label: "Planning next moves", modelTurnId: part.modelTurnId }, key));
3343
3505
  continue;
3344
3506
  }
3345
3507
  if (part.kind === "node-activity") {
3346
3508
  const key = activeActivityClaimed ? part.id : `${message.id}-active-activity`;
3347
3509
  if (part.status === "running") activeActivityClaimed = true;
3348
3510
  rendered.push(
3349
- part.status === "running" ? /* @__PURE__ */ jsx14(AgentChatActivityRow, { renderActivityIcon: toolSlots?.renderActivityIcon, label: part.label, onSelect: onNodeSelect ? () => onNodeSelect(part) : void 0 }, key) : /* @__PURE__ */ jsx14(AgentChatNodeActivityRow, { renderActivityIcon: toolSlots?.renderActivityIcon, onSelect: onNodeSelect, part }, part.id)
3511
+ part.status === "running" ? /* @__PURE__ */ jsx15(AgentChatActivityRow, { renderActivityIcon: toolSlots?.renderActivityIcon, label: part.label, onSelect: onNodeSelect ? () => onNodeSelect(part) : void 0 }, key) : /* @__PURE__ */ jsx15(AgentChatNodeActivityRow, { renderActivityIcon: toolSlots?.renderActivityIcon, onSelect: onNodeSelect, part }, part.id)
3350
3512
  );
3351
3513
  continue;
3352
3514
  }
3353
3515
  if (part.kind === "ui-blocks" && renderUiBlocks) {
3354
- rendered.push(/* @__PURE__ */ jsx14(React15.Fragment, { children: renderUiBlocks(part) }, part.id));
3516
+ rendered.push(/* @__PURE__ */ jsx15(React16.Fragment, { children: renderUiBlocks(part) }, part.id));
3355
3517
  continue;
3356
3518
  }
3357
3519
  rendered.push(
3358
- /* @__PURE__ */ jsx14(React15.Fragment, { children: /* @__PURE__ */ jsx14(
3520
+ /* @__PURE__ */ jsx15(React16.Fragment, { children: /* @__PURE__ */ jsx15(
3359
3521
  AgentChatPart,
3360
3522
  {
3361
3523
  activeToolId,
3362
3524
  getHitlActionState,
3525
+ hitlLabels,
3526
+ onHitlPaint,
3363
3527
  isLoading,
3364
3528
  isTextStreaming: part.kind === "text" && part.id === activeTextPartId,
3365
3529
  message,
@@ -3372,16 +3536,16 @@ function AgentResponseTimeline({
3372
3536
  );
3373
3537
  }
3374
3538
  if (rendered.length === 0 && message.content) {
3375
- rendered.push(/* @__PURE__ */ jsx14(MessageResponse, { children: message.content }, `${message.id}-fallback`));
3539
+ rendered.push(/* @__PURE__ */ jsx15(MessageResponse, { children: message.content }, `${message.id}-fallback`));
3376
3540
  }
3377
3541
  if (rendered.length === 0 && isLoading) {
3378
- rendered.push(/* @__PURE__ */ jsx14(AgentChatActivityRow, { renderActivityIcon: toolSlots?.renderActivityIcon, label: "Thinking" }, `${message.id}-active-activity`));
3542
+ rendered.push(/* @__PURE__ */ jsx15(AgentChatActivityRow, { renderActivityIcon: toolSlots?.renderActivityIcon, label: "Thinking" }, `${message.id}-active-activity`));
3379
3543
  }
3380
- return /* @__PURE__ */ jsx14("div", { className: "space-y-3", children: rendered });
3544
+ return /* @__PURE__ */ jsx15("div", { className: "space-y-3", children: rendered });
3381
3545
  }
3382
3546
 
3383
3547
  // src/ui/agent-chat-message.tsx
3384
- import { jsx as jsx15, jsxs as jsxs10 } from "react/jsx-runtime";
3548
+ import { jsx as jsx16, jsxs as jsxs11 } from "react/jsx-runtime";
3385
3549
  var DEFAULT_USER_MESSAGE_COLLAPSE_THRESHOLD = 360;
3386
3550
  var DEFAULT_USER_MESSAGE_COLLAPSED_LINES = 4;
3387
3551
  function shouldCollapseUserMessage(content, threshold = DEFAULT_USER_MESSAGE_COLLAPSE_THRESHOLD) {
@@ -3394,8 +3558,8 @@ function AgentChatUserMessageContent({
3394
3558
  showLessLabel = "Show less",
3395
3559
  showMoreLabel = "Show more"
3396
3560
  }) {
3397
- const [isExpanded, setIsExpanded] = React16.useState(false);
3398
- const contentId = React16.useId();
3561
+ const [isExpanded, setIsExpanded] = React17.useState(false);
3562
+ const contentId = React17.useId();
3399
3563
  const shouldCollapse = shouldCollapseUserMessage(content, collapseThreshold);
3400
3564
  const Icon = isExpanded ? ChevronUp : ChevronDown3;
3401
3565
  const clampedStyle = shouldCollapse && !isExpanded ? {
@@ -3404,9 +3568,9 @@ function AgentChatUserMessageContent({
3404
3568
  display: "-webkit-box",
3405
3569
  overflow: "hidden"
3406
3570
  } : void 0;
3407
- return /* @__PURE__ */ jsxs10("div", { className: "flex min-w-0 flex-col gap-3", children: [
3408
- /* @__PURE__ */ jsx15("div", { id: contentId, className: "min-w-0", style: clampedStyle, children: content }),
3409
- shouldCollapse ? /* @__PURE__ */ jsxs10(
3571
+ return /* @__PURE__ */ jsxs11("div", { className: "flex min-w-0 flex-col gap-3", children: [
3572
+ /* @__PURE__ */ jsx16("div", { id: contentId, className: "min-w-0", style: clampedStyle, children: content }),
3573
+ shouldCollapse ? /* @__PURE__ */ jsxs11(
3410
3574
  "button",
3411
3575
  {
3412
3576
  "aria-controls": contentId,
@@ -3419,7 +3583,7 @@ function AgentChatUserMessageContent({
3419
3583
  type: "button",
3420
3584
  children: [
3421
3585
  isExpanded ? showLessLabel : showMoreLabel,
3422
- /* @__PURE__ */ jsx15(Icon, { "aria-hidden": "true", className: "size-4", strokeWidth: 2 })
3586
+ /* @__PURE__ */ jsx16(Icon, { "aria-hidden": "true", className: "size-4", strokeWidth: 2 })
3423
3587
  ]
3424
3588
  }
3425
3589
  ) : null
@@ -3429,9 +3593,9 @@ function AgentChatUserMessageActionRow({
3429
3593
  children,
3430
3594
  className
3431
3595
  }) {
3432
- const rowRef = React16.useRef(null);
3433
- const [visible, setVisible] = React16.useState(false);
3434
- React16.useEffect(() => {
3596
+ const rowRef = React17.useRef(null);
3597
+ const [visible, setVisible] = React17.useState(false);
3598
+ React17.useEffect(() => {
3435
3599
  const message = rowRef.current?.closest('[data-slot="message"]');
3436
3600
  if (!message) return;
3437
3601
  const show = () => setVisible(true);
@@ -3450,7 +3614,7 @@ function AgentChatUserMessageActionRow({
3450
3614
  message.removeEventListener("focusout", hideWhenFocusLeaves);
3451
3615
  };
3452
3616
  }, []);
3453
- return /* @__PURE__ */ jsx15(
3617
+ return /* @__PURE__ */ jsx16(
3454
3618
  "div",
3455
3619
  {
3456
3620
  ref: rowRef,
@@ -3470,6 +3634,8 @@ function AgentChatMessage({
3470
3634
  contentClassName,
3471
3635
  dir,
3472
3636
  getHitlActionState,
3637
+ hitlLabels,
3638
+ onHitlPaint,
3473
3639
  message,
3474
3640
  nodeActivityMode,
3475
3641
  onHitlAction,
@@ -3489,7 +3655,7 @@ function AgentChatMessage({
3489
3655
  const resolvedUserContent = userMessageContent ?? message.content;
3490
3656
  const shouldRenderContent = isAssistant || Boolean(renderUserContent || resolvedUserContent);
3491
3657
  const showAttachments = Boolean(message.attachments?.length) && (message.role === "user" || showAssistantAttachments);
3492
- const renderedActions = actions ?? (actionHandlers ? /* @__PURE__ */ jsx15(
3658
+ const renderedActions = actions ?? (actionHandlers ? /* @__PURE__ */ jsx16(
3493
3659
  AgentChatDefaultActions,
3494
3660
  {
3495
3661
  additionalActions,
@@ -3499,14 +3665,14 @@ function AgentChatMessage({
3499
3665
  }
3500
3666
  ) : null);
3501
3667
  const defaultUserActions = !actions && Boolean(actionHandlers) && !isAssistant;
3502
- return /* @__PURE__ */ jsxs10(
3668
+ return /* @__PURE__ */ jsxs11(
3503
3669
  ChatMessage,
3504
3670
  {
3505
3671
  className,
3506
3672
  dir,
3507
3673
  from: message.role,
3508
3674
  children: [
3509
- showAttachments ? /* @__PURE__ */ jsx15(
3675
+ showAttachments ? /* @__PURE__ */ jsx16(
3510
3676
  ChatAttachmentRows,
3511
3677
  {
3512
3678
  attachments: message.attachments || [],
@@ -3515,17 +3681,19 @@ function AgentChatMessage({
3515
3681
  resolveContent: attachmentContentResolver
3516
3682
  }
3517
3683
  ) : null,
3518
- shouldRenderContent ? /* @__PURE__ */ jsxs10(
3684
+ shouldRenderContent ? /* @__PURE__ */ jsxs11(
3519
3685
  ChatMessageContent,
3520
3686
  {
3521
3687
  className: cn(isAssistant ? "bg-transparent p-0" : void 0, contentClassName),
3522
3688
  dir,
3523
3689
  from: message.role,
3524
3690
  children: [
3525
- isAssistant ? renderAssistantContent ? renderAssistantContent({ isStreaming, message }) : /* @__PURE__ */ jsx15(
3691
+ isAssistant ? renderAssistantContent ? renderAssistantContent({ isStreaming, message }) : /* @__PURE__ */ jsx16(
3526
3692
  Timeline,
3527
3693
  {
3528
3694
  getHitlActionState,
3695
+ hitlLabels,
3696
+ onHitlPaint,
3529
3697
  isLoading: isStreaming,
3530
3698
  message,
3531
3699
  nodeActivityMode,
@@ -3533,7 +3701,7 @@ function AgentChatMessage({
3533
3701
  parts: message.parts
3534
3702
  }
3535
3703
  ) : null,
3536
- !isAssistant ? renderUserContent ? renderUserContent({ message }) : resolvedUserContent ? /* @__PURE__ */ jsx15(
3704
+ !isAssistant ? renderUserContent ? renderUserContent({ message }) : resolvedUserContent ? /* @__PURE__ */ jsx16(
3537
3705
  AgentChatUserMessageContent,
3538
3706
  {
3539
3707
  collapsedLines: userMessageCollapsedLines,
@@ -3546,7 +3714,11 @@ function AgentChatMessage({
3546
3714
  ]
3547
3715
  }
3548
3716
  ) : null,
3549
- renderedActions ? defaultUserActions ? /* @__PURE__ */ jsx15(AgentChatUserMessageActionRow, { className: actionsClassName, children: renderedActions }) : /* @__PURE__ */ jsx15("div", { className: cn(dir === "rtl" ? "mt-1 h-9 w-full" : "mt-1 h-9 w-full -translate-x-2", actionsClassName), children: renderedActions }) : null
3717
+ renderedActions ? defaultUserActions ? /* @__PURE__ */ jsx16(AgentChatUserMessageActionRow, { className: actionsClassName, children: renderedActions }) : /* @__PURE__ */ jsx16("div", { className: cn(
3718
+ dir === "rtl" ? "mt-1 h-9 w-full" : "mt-1 h-9 w-full -translate-x-2",
3719
+ isAssistant && "a24-chat-message-action-row--assistant",
3720
+ actionsClassName
3721
+ ), children: renderedActions }) : null
3550
3722
  ]
3551
3723
  }
3552
3724
  );
@@ -3555,9 +3727,9 @@ function AgentChatMessage({
3555
3727
  // src/ui/bubble.tsx
3556
3728
  import { cva as cva3 } from "class-variance-authority";
3557
3729
  import { Slot as Slot2 } from "@radix-ui/react-slot";
3558
- import { jsx as jsx16 } from "react/jsx-runtime";
3730
+ import { jsx as jsx17 } from "react/jsx-runtime";
3559
3731
  function BubbleGroup({ className, ...props }) {
3560
- return /* @__PURE__ */ jsx16(
3732
+ return /* @__PURE__ */ jsx17(
3561
3733
  "div",
3562
3734
  {
3563
3735
  "data-slot": "bubble-group",
@@ -3591,7 +3763,7 @@ function Bubble({
3591
3763
  className,
3592
3764
  ...props
3593
3765
  }) {
3594
- return /* @__PURE__ */ jsx16(
3766
+ return /* @__PURE__ */ jsx17(
3595
3767
  "div",
3596
3768
  {
3597
3769
  "data-slot": "bubble",
@@ -3608,7 +3780,7 @@ function BubbleContent({
3608
3780
  ...props
3609
3781
  }) {
3610
3782
  const Comp = asChild ? Slot2 : "div";
3611
- return /* @__PURE__ */ jsx16(
3783
+ return /* @__PURE__ */ jsx17(
3612
3784
  Comp,
3613
3785
  {
3614
3786
  "data-slot": "bubble-content",
@@ -3645,7 +3817,7 @@ function BubbleReactions({
3645
3817
  className,
3646
3818
  ...props
3647
3819
  }) {
3648
- return /* @__PURE__ */ jsx16(
3820
+ return /* @__PURE__ */ jsx17(
3649
3821
  "div",
3650
3822
  {
3651
3823
  "data-slot": "bubble-reactions",
@@ -3660,7 +3832,7 @@ function BubbleReactions({
3660
3832
  // src/ui/marker.tsx
3661
3833
  import { cva as cva4 } from "class-variance-authority";
3662
3834
  import { Slot as Slot3 } from "@radix-ui/react-slot";
3663
- import { jsx as jsx17 } from "react/jsx-runtime";
3835
+ import { jsx as jsx18 } from "react/jsx-runtime";
3664
3836
  var markerVariants = cva4(
3665
3837
  "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",
3666
3838
  {
@@ -3680,7 +3852,7 @@ function Marker({
3680
3852
  ...props
3681
3853
  }) {
3682
3854
  const Comp = asChild ? Slot3 : "div";
3683
- return /* @__PURE__ */ jsx17(
3855
+ return /* @__PURE__ */ jsx18(
3684
3856
  Comp,
3685
3857
  {
3686
3858
  "data-slot": "marker",
@@ -3691,7 +3863,7 @@ function Marker({
3691
3863
  );
3692
3864
  }
3693
3865
  function MarkerIcon({ className, ...props }) {
3694
- return /* @__PURE__ */ jsx17(
3866
+ return /* @__PURE__ */ jsx18(
3695
3867
  "span",
3696
3868
  {
3697
3869
  "data-slot": "marker-icon",
@@ -3705,7 +3877,7 @@ function MarkerIcon({ className, ...props }) {
3705
3877
  );
3706
3878
  }
3707
3879
  function MarkerContent({ className, ...props }) {
3708
- return /* @__PURE__ */ jsx17(
3880
+ return /* @__PURE__ */ jsx18(
3709
3881
  "span",
3710
3882
  {
3711
3883
  "data-slot": "marker-content",
@@ -3719,7 +3891,7 @@ function MarkerContent({ className, ...props }) {
3719
3891
  }
3720
3892
 
3721
3893
  // src/ui/mcp-connect-required-card.tsx
3722
- import { jsx as jsx18, jsxs as jsxs11 } from "react/jsx-runtime";
3894
+ import { jsx as jsx19, jsxs as jsxs12 } from "react/jsx-runtime";
3723
3895
  var STATUS_LABELS = {
3724
3896
  pending: "Connect",
3725
3897
  connecting: "Connecting",
@@ -3743,7 +3915,7 @@ function McpConnectRequiredCard({
3743
3915
  const isBusy = loading || status === "connecting" || status === "resuming";
3744
3916
  const isConnected = status === "connected";
3745
3917
  const buttonDisabled = disabled || isBusy || isConnected || !onConnect;
3746
- return /* @__PURE__ */ jsx18(
3918
+ return /* @__PURE__ */ jsx19(
3747
3919
  "div",
3748
3920
  {
3749
3921
  "data-agents24-mcp-connect-card": true,
@@ -3753,13 +3925,13 @@ function McpConnectRequiredCard({
3753
3925
  className
3754
3926
  ),
3755
3927
  ...props,
3756
- children: /* @__PURE__ */ jsxs11("div", { className: "flex min-w-0 items-start justify-between gap-3", children: [
3757
- /* @__PURE__ */ jsxs11("div", { className: "min-w-0", children: [
3758
- /* @__PURE__ */ jsx18("div", { className: "truncate text-sm font-medium", children: label }),
3759
- /* @__PURE__ */ jsx18("div", { className: "mt-1 text-sm text-muted-foreground", children: message || "Connect your account to continue." }),
3760
- status === "error" && error ? /* @__PURE__ */ jsx18("div", { className: "mt-2 text-sm text-destructive", children: error }) : null
3928
+ children: /* @__PURE__ */ jsxs12("div", { className: "flex min-w-0 items-start justify-between gap-3", children: [
3929
+ /* @__PURE__ */ jsxs12("div", { className: "min-w-0", children: [
3930
+ /* @__PURE__ */ jsx19("div", { className: "truncate text-sm font-medium", children: label }),
3931
+ /* @__PURE__ */ jsx19("div", { className: "mt-1 text-sm text-muted-foreground", children: message || "Connect your account to continue." }),
3932
+ status === "error" && error ? /* @__PURE__ */ jsx19("div", { className: "mt-2 text-sm text-destructive", children: error }) : null
3761
3933
  ] }),
3762
- /* @__PURE__ */ jsx18(
3934
+ /* @__PURE__ */ jsx19(
3763
3935
  "button",
3764
3936
  {
3765
3937
  type: "button",
@@ -3826,6 +3998,7 @@ export {
3826
3998
  CodeBlockLine,
3827
3999
  CodeBlockTitle,
3828
4000
  CodeBlockWrapButton,
4001
+ HitlSubmissionStatus,
3829
4002
  Marker,
3830
4003
  MarkerContent,
3831
4004
  MarkerIcon,
@@ -3852,10 +4025,12 @@ export {
3852
4025
  cn,
3853
4026
  contextStatusMetrics,
3854
4027
  createAgentChatComposerFile,
4028
+ defaultHitlSubmissionLabels,
3855
4029
  hitlActionLabel,
3856
4030
  hitlTitle,
3857
4031
  isAgentChatSubagent,
3858
4032
  isAgentChatToolRunning,
4033
+ isHitlSubmissionCompact,
3859
4034
  latestRunningAgentChatToolId,
3860
4035
  markerVariants,
3861
4036
  partitionAgentChatToolTimeline,