@agents24/chat-react 0.5.36 → 0.5.38

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 (42) hide show
  1. package/README.md +31 -1
  2. package/compatibility.json +5 -5
  3. package/dist/{chunk-INO5DSSJ.js → chunk-DWDHK4FZ.js} +3 -4
  4. package/dist/chunk-DWDHK4FZ.js.map +1 -0
  5. package/dist/generated/delegation-types.d.ts +3 -2
  6. package/dist/generated/run-usage.d.ts +11 -0
  7. package/dist/registry/agents24-chat.json +13 -13
  8. package/dist/runtime/index.cjs +25 -9
  9. package/dist/runtime/index.cjs.map +1 -1
  10. package/dist/runtime/index.js +24 -7
  11. package/dist/runtime/index.js.map +1 -1
  12. package/dist/runtime/input-contract.d.ts +1 -1
  13. package/dist/runtime/use-agent-chat-hitl.d.ts +2 -2
  14. package/dist/runtime/use-agent-chat-runtime.d.ts +4 -6
  15. package/dist/scaffold/app.d.ts +2 -2
  16. package/dist/scaffold/components/chat/chat-composer.d.ts +2 -1
  17. package/dist/scaffold/components/chat/chat-message.d.ts +2 -2
  18. package/dist/scaffold/components/chat/message-parts.d.ts +2 -2
  19. package/dist/scaffold/index.cjs +17 -13
  20. package/dist/scaffold/index.cjs.map +1 -1
  21. package/dist/scaffold/index.js +11 -7
  22. package/dist/scaffold/index.js.map +1 -1
  23. package/dist/styles.css +7 -0
  24. package/dist/ui/agent-chat-composer.d.ts +9 -1
  25. package/dist/ui/agent-chat-message.d.ts +6 -2
  26. package/dist/ui/agent-response-timeline.d.ts +11 -3
  27. package/dist/ui/ask-user-interaction.d.ts +5 -1
  28. package/dist/ui/hitl-submission-status.d.ts +22 -0
  29. package/dist/ui/index.cjs +540 -340
  30. package/dist/ui/index.cjs.map +1 -1
  31. package/dist/ui/index.d.ts +1 -0
  32. package/dist/ui/index.js +536 -338
  33. package/dist/ui/index.js.map +1 -1
  34. package/dist/ui/use-agent-chat-composer.d.ts +28 -3
  35. package/dist/ui/use-audio-recorder.d.ts +15 -2
  36. package/package.json +3 -3
  37. package/scaffold/src/app.tsx +2 -1
  38. package/scaffold/src/components/chat/chat-composer.tsx +5 -3
  39. package/scaffold/src/components/chat/chat-message.tsx +3 -3
  40. package/scaffold/src/components/chat/chat-shell.tsx +2 -1
  41. package/scaffold/src/components/chat/message-parts.tsx +6 -6
  42. package/dist/chunk-INO5DSSJ.js.map +0 -1
package/dist/ui/index.cjs CHANGED
@@ -79,6 +79,7 @@ __export(ui_exports, {
79
79
  CodeBlockLine: () => CodeBlockLine,
80
80
  CodeBlockTitle: () => CodeBlockTitle,
81
81
  CodeBlockWrapButton: () => CodeBlockWrapButton,
82
+ HitlSubmissionStatus: () => HitlSubmissionStatus,
82
83
  Marker: () => Marker,
83
84
  MarkerContent: () => MarkerContent,
84
85
  MarkerIcon: () => MarkerIcon,
@@ -105,10 +106,12 @@ __export(ui_exports, {
105
106
  cn: () => cn,
106
107
  contextStatusMetrics: () => contextStatusMetrics,
107
108
  createAgentChatComposerFile: () => createAgentChatComposerFile,
109
+ defaultHitlSubmissionLabels: () => defaultHitlSubmissionLabels,
108
110
  hitlActionLabel: () => hitlActionLabel,
109
111
  hitlTitle: () => hitlTitle,
110
112
  isAgentChatSubagent: () => isAgentChatSubagent,
111
113
  isAgentChatToolRunning: () => isAgentChatToolRunning,
114
+ isHitlSubmissionCompact: () => isHitlSubmissionCompact,
112
115
  latestRunningAgentChatToolId: () => latestRunningAgentChatToolId,
113
116
  markerVariants: () => markerVariants,
114
117
  partitionAgentChatToolTimeline: () => partitionAgentChatToolTimeline,
@@ -861,13 +864,12 @@ function uploadByteSize(data) {
861
864
  function inputMimeTypes(contract) {
862
865
  if (!contract) return [];
863
866
  return [
864
- ...contract.modalities.files.allowed_mime_types,
865
- ...contract.modalities.images.allowed_mime_types,
866
- ...contract.modalities.audio.allowed_mime_types
867
+ ...["files", "images", "audio"].flatMap((key) => contract.modalities[key].enabled ? contract.modalities[key].allowed_mime_types : [])
867
868
  ];
868
869
  }
869
870
  function validateAgentChatSubmission(contract, text, files) {
870
871
  const { modalities, limits } = contract;
872
+ if (files.length && contract.validation_issues?.length) return contract.validation_issues[0].message;
871
873
  const normalizedText = text.trim();
872
874
  if (normalizedText && !modalities.text.enabled) return "This agent does not accept text input.";
873
875
  if (modalities.text.required && !normalizedText) return "Text input is required.";
@@ -958,47 +960,69 @@ function useChatComposerFocus({ textareaRef, disabled, focusKey, restoredDraft,
958
960
 
959
961
  // src/ui/use-audio-recorder.ts
960
962
  var React3 = __toESM(require("react"), 1);
963
+ var import_client4 = require("@agents24/client");
961
964
  var RECORDING_CANDIDATES = ["audio/webm;codecs=opus", "audio/webm", "audio/mp4"];
962
965
  function useAudioRecorder(onRecorded, options = {}) {
963
966
  const recorderRef = React3.useRef(null);
964
967
  const streamRef = React3.useRef(null);
968
+ const operationRef = React3.useRef(null);
965
969
  const pendingRef = React3.useRef(false);
966
- const generationRef = React3.useRef(0);
967
- const onRecordedRef = React3.useRef(onRecorded);
968
- const onStreamChangeRef = React3.useRef(options.onStreamChange);
969
- React3.useEffect(() => {
970
- onRecordedRef.current = onRecorded;
971
- onStreamChangeRef.current = options.onStreamChange;
970
+ const callbacksRef = React3.useRef({ onRecorded, onStreamChange: options.onStreamChange, acceptedMimeTypes: options.acceptedMimeTypes });
971
+ React3.useLayoutEffect(() => {
972
+ callbacksRef.current = { onRecorded, onStreamChange: options.onStreamChange, acceptedMimeTypes: options.acceptedMimeTypes };
972
973
  });
973
974
  const [isRecording, setIsRecording] = React3.useState(false);
975
+ const [isStarting, setIsStarting] = React3.useState(false);
976
+ const [isProcessing, setIsProcessing] = React3.useState(false);
974
977
  const [error, setError] = React3.useState(null);
975
978
  const release = React3.useCallback(() => {
976
979
  streamRef.current?.getTracks().forEach((track) => track.stop());
977
980
  streamRef.current = null;
978
981
  recorderRef.current = null;
979
- onStreamChangeRef.current?.(null);
982
+ callbacksRef.current.onStreamChange?.(null);
980
983
  }, []);
984
+ const discard = React3.useCallback(() => {
985
+ operationRef.current?.controller.abort();
986
+ operationRef.current = null;
987
+ pendingRef.current = false;
988
+ const recorder = recorderRef.current;
989
+ if (recorder) {
990
+ recorder.onstop = null;
991
+ recorder.onerror = null;
992
+ recorder.ondataavailable = null;
993
+ if (recorder.state !== "inactive") recorder.stop();
994
+ }
995
+ release();
996
+ }, [release]);
997
+ const cancel = React3.useCallback(() => {
998
+ discard();
999
+ setIsStarting(false);
1000
+ setIsRecording(false);
1001
+ setIsProcessing(false);
1002
+ setError(null);
1003
+ }, [discard]);
981
1004
  const stop = React3.useCallback(() => {
982
1005
  const recorder = recorderRef.current;
983
1006
  if (recorder && recorder.state !== "inactive") recorder.stop();
984
1007
  }, []);
985
- const start = React3.useCallback(async () => {
986
- if (pendingRef.current || recorderRef.current) return;
1008
+ const isCapturing = React3.useCallback(() => pendingRef.current || recorderRef.current !== null, []);
1009
+ const start = React3.useCallback(async (startOptions = {}) => {
1010
+ if (operationRef.current) return;
987
1011
  setError(null);
988
1012
  if (!navigator.mediaDevices?.getUserMedia || typeof MediaRecorder === "undefined") {
989
1013
  setError("Audio recording is not supported in this browser.");
990
1014
  return;
991
1015
  }
1016
+ const controller = new AbortController();
1017
+ const operation = { operationId: startOptions.operationId ?? crypto.randomUUID(), signal: controller.signal, controller };
1018
+ operationRef.current = operation;
992
1019
  pendingRef.current = true;
993
- const generation = generationRef.current;
1020
+ setIsStarting(true);
994
1021
  try {
995
- const mimeType = RECORDING_CANDIDATES.find((candidate) => MediaRecorder.isTypeSupported(candidate));
996
- if (!mimeType) {
997
- setError("Audio recording is not supported in this browser.");
998
- return;
999
- }
1022
+ const mimeType = RECORDING_CANDIDATES.find((candidate) => MediaRecorder.isTypeSupported(candidate) && (callbacksRef.current.acceptedMimeTypes === void 0 || callbacksRef.current.acceptedMimeTypes.includes((0, import_client4.normalizeAttachmentMimeType)(candidate))));
1023
+ if (!mimeType) throw new Error("unsupported");
1000
1024
  const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
1001
- if (generation !== generationRef.current) {
1025
+ if (operation.signal.aborted) {
1002
1026
  stream.getTracks().forEach((track) => track.stop());
1003
1027
  return;
1004
1028
  }
@@ -1010,48 +1034,54 @@ function useAudioRecorder(onRecorded, options = {}) {
1010
1034
  if (event.data.size) chunks.push(event.data);
1011
1035
  };
1012
1036
  recorder.onstop = () => {
1013
- if (generation !== generationRef.current) return;
1037
+ if (operation.signal.aborted) return;
1014
1038
  const actualType = recorder.mimeType || mimeType;
1015
- const extension = actualType.startsWith("audio/mp4") ? "m4a" : "webm";
1016
- try {
1017
- onRecordedRef.current(new File([new Blob(chunks, { type: actualType })], `recording-${Date.now()}.${extension}`, { type: actualType }));
1018
- } finally {
1019
- release();
1020
- setIsRecording(false);
1039
+ const accepted = callbacksRef.current.acceptedMimeTypes;
1040
+ if (accepted !== void 0 && !accepted.includes((0, import_client4.normalizeAttachmentMimeType)(actualType))) {
1041
+ cancel();
1042
+ setError("This Agent does not accept the recorded audio format.");
1043
+ return;
1021
1044
  }
1022
- };
1023
- recorder.onerror = () => {
1024
- recorder.onstop = null;
1025
- if (recorder.state !== "inactive") recorder.stop();
1045
+ const extension = actualType.startsWith("audio/mp4") ? "m4a" : "webm";
1046
+ const file = new File(chunks, `recording-${Date.now()}.${extension}`, { type: actualType });
1026
1047
  release();
1027
1048
  setIsRecording(false);
1049
+ setIsProcessing(true);
1050
+ void Promise.resolve().then(() => {
1051
+ if (!operation.signal.aborted) return callbacksRef.current.onRecorded(file, operation);
1052
+ }).catch(() => {
1053
+ if (!operation.signal.aborted) setError("Recording processing failed.");
1054
+ }).finally(() => {
1055
+ if (operationRef.current === operation) {
1056
+ operationRef.current = null;
1057
+ setIsProcessing(false);
1058
+ }
1059
+ });
1060
+ };
1061
+ recorder.onerror = () => {
1062
+ cancel();
1028
1063
  setError("Audio recording failed. Try again.");
1029
1064
  };
1030
1065
  recorder.start();
1031
1066
  setIsRecording(true);
1032
- onStreamChangeRef.current?.(stream);
1067
+ callbacksRef.current.onStreamChange?.(stream);
1033
1068
  } catch {
1034
- if (generation === generationRef.current) {
1035
- release();
1036
- setIsRecording(false);
1037
- setError("Microphone access is unavailable.");
1069
+ if (!operation.signal.aborted) {
1070
+ cancel();
1071
+ setError("Microphone access or audio recording is unavailable.");
1038
1072
  }
1039
1073
  } finally {
1040
- if (generation === generationRef.current) pendingRef.current = false;
1041
- }
1042
- }, [release]);
1043
- React3.useEffect(() => () => {
1044
- generationRef.current += 1;
1045
- pendingRef.current = false;
1046
- const recorder = recorderRef.current;
1047
- if (recorder) {
1048
- recorder.onstop = null;
1049
- recorder.onerror = null;
1050
- if (recorder.state !== "inactive") recorder.stop();
1074
+ if (!operation.signal.aborted) {
1075
+ pendingRef.current = false;
1076
+ setIsStarting(false);
1077
+ }
1051
1078
  }
1052
- release();
1053
- }, [release]);
1054
- return { error, isRecording, start, stop };
1079
+ }, [cancel, discard, release]);
1080
+ React3.useLayoutEffect(() => {
1081
+ cancel();
1082
+ return discard;
1083
+ }, [options.scopeKey, cancel, discard]);
1084
+ return { error, isRecording, isStarting, isProcessing, isCapturing, start, stop, cancel };
1055
1085
  }
1056
1086
 
1057
1087
  // src/ui/use-agent-chat-composer.ts
@@ -1063,16 +1093,47 @@ function useAgentChatComposer(options) {
1063
1093
  const localTextareaRef = React4.useRef(null);
1064
1094
  const textareaRef = options.textareaRef ?? localTextareaRef;
1065
1095
  const filesRef = React4.useRef(files);
1066
- const inFlightFilesRef = React4.useRef([]);
1096
+ const inFlightFilesRef = React4.useRef(/* @__PURE__ */ new Map());
1067
1097
  const revisionRef = React4.useRef(0);
1068
1098
  const submittingRef = React4.useRef(false);
1069
- React4.useEffect(() => {
1070
- filesRef.current = files;
1071
- }, [files]);
1099
+ const generationRef = React4.useRef(0);
1100
+ const mountedRef = React4.useRef(true);
1101
+ const textRef = React4.useRef(text);
1102
+ const scope = React4.useMemo(() => ({ active: false }), [options.scopeKey]);
1103
+ const [textInteraction, setTextInteraction] = React4.useState(null);
1104
+ const handledTextInteractionRef = React4.useRef(textInteraction);
1105
+ React4.useLayoutEffect(() => {
1106
+ scope.active = true;
1107
+ mountedRef.current = true;
1108
+ submittingRef.current = false;
1109
+ setIsSubmitting(false);
1110
+ return () => {
1111
+ scope.active = false;
1112
+ mountedRef.current = false;
1113
+ generationRef.current += 1;
1114
+ };
1115
+ }, [scope]);
1116
+ React4.useLayoutEffect(() => {
1117
+ if (handledTextInteractionRef.current === textInteraction) return;
1118
+ handledTextInteractionRef.current = textInteraction;
1119
+ if (!textInteraction || textInteraction.scope !== scope || !scope.active || textInteraction.revision !== revisionRef.current || options.disabled) return;
1120
+ const textarea = textareaRef.current;
1121
+ if (!textarea) return;
1122
+ if (textInteraction.options.focus) textarea.focus({ preventScroll: true });
1123
+ const selection = textInteraction.options.selection;
1124
+ if (selection) {
1125
+ const clamp = (offset) => Math.max(0, Math.min(textRef.current.length, offset));
1126
+ textarea.setSelectionRange(clamp(selection.start), clamp(selection.end), selection.direction);
1127
+ }
1128
+ }, [textInteraction, scope, textareaRef, options.disabled]);
1072
1129
  React4.useEffect(() => () => {
1073
1130
  revokeAgentChatComposerFiles(filesRef.current);
1074
- revokeAgentChatComposerFiles(inFlightFilesRef.current);
1131
+ revokeAgentChatComposerFiles([...inFlightFilesRef.current.values()].flat());
1075
1132
  }, []);
1133
+ const revokeUnownedFiles = (candidates) => {
1134
+ const retained = new Set([...filesRef.current, ...[...inFlightFilesRef.current.values()].flat()].map((file) => file.url));
1135
+ revokeAgentChatComposerFiles(candidates.filter((file) => !retained.has(file.url)));
1136
+ };
1076
1137
  const focusComposer = useChatComposerFocus({
1077
1138
  textareaRef,
1078
1139
  disabled: Boolean(options.disabled),
@@ -1080,60 +1141,94 @@ function useAgentChatComposer(options) {
1080
1141
  restoredDraft: options.restoredDraft,
1081
1142
  onRestore: (draft) => {
1082
1143
  revisionRef.current += 1;
1083
- revokeAgentChatComposerFiles(filesRef.current);
1144
+ const previousFiles = filesRef.current;
1145
+ textRef.current = draft.text;
1146
+ filesRef.current = draft.files;
1147
+ revokeUnownedFiles(previousFiles);
1084
1148
  setTextState(draft.text);
1085
1149
  setFiles(draft.files);
1086
1150
  }
1087
1151
  });
1088
1152
  const attachmentMimeTypes = inputMimeTypes(options.inputContract);
1089
- const setText = (value) => {
1090
- revisionRef.current += 1;
1153
+ const setText = React4.useCallback((value, interaction = {}) => {
1154
+ if (!scope.active) return false;
1155
+ const revision = ++revisionRef.current;
1156
+ textRef.current = value;
1091
1157
  setTextState(value);
1092
- };
1158
+ setTextInteraction({ scope, revision, options: interaction });
1159
+ return true;
1160
+ }, [scope]);
1093
1161
  const addFiles = (selected) => {
1094
1162
  const accepted = selected.filter((file) => attachmentMimeTypes.includes(canonicalInputMimeType(file.type, file.name)));
1095
1163
  revisionRef.current += 1;
1096
- const additions = accepted.map(createAgentChatComposerFile);
1097
- setFiles((current) => [...current, ...additions]);
1164
+ const additions = selected.map(createAgentChatComposerFile);
1165
+ filesRef.current = [...filesRef.current, ...additions];
1166
+ setFiles(filesRef.current);
1098
1167
  setAttachmentError(accepted.length === selected.length ? null : "One or more selected file types are not supported by this Agent.");
1099
1168
  };
1100
1169
  const removeFile = (id) => {
1101
1170
  revisionRef.current += 1;
1102
1171
  const removed = filesRef.current.find((file) => file.id === id);
1103
- if (removed) revokeAgentChatComposerFiles([removed]);
1104
- setFiles((current) => current.filter((file) => file.id !== id));
1172
+ filesRef.current = filesRef.current.filter((file) => file.id !== id);
1173
+ if (removed) revokeUnownedFiles([removed]);
1174
+ setFiles(filesRef.current);
1105
1175
  };
1106
- const recorder = useAudioRecorder((file) => addFiles([file]), { onStreamChange: options.onRecordingStreamChange });
1176
+ const recorder = useAudioRecorder(
1177
+ (file, context) => options.onRecordingComplete ? options.onRecordingComplete(file, context) : addFiles([file]),
1178
+ {
1179
+ onStreamChange: options.onRecordingStreamChange,
1180
+ scopeKey: options.scopeKey,
1181
+ acceptedMimeTypes: options.onRecordingComplete ? void 0 : options.inputContract?.modalities.audio.allowed_mime_types ?? []
1182
+ }
1183
+ );
1107
1184
  const validationError = options.inputContract ? validateAgentChatSubmission(
1108
1185
  options.inputContract,
1109
1186
  text,
1110
1187
  files.map((file) => ({ data: file.source || new Uint8Array(), mediaType: file.mediaType, name: file.filename, byteSize: file.byteSize }))
1111
1188
  ) : null;
1112
- const canSubmit = Boolean(text.trim() || files.length) && !options.disabled && !options.isCancelling && !isSubmitting && !recorder.isRecording && !validationError;
1113
- const submit = async () => {
1114
- if (!canSubmit || submittingRef.current) return;
1115
- const value = text;
1116
- const selectedFiles = files;
1189
+ const canSubmit = Boolean(text.trim() || files.length) && !options.disabled && !options.isCancelling && !isSubmitting && !recorder.isRecording && !recorder.isStarting && !recorder.isProcessing && !validationError;
1190
+ const submit = async (submission) => {
1191
+ const value = submission?.text ?? textRef.current;
1192
+ const selectedFiles = submission?.files ?? filesRef.current;
1193
+ const suppliedError = options.inputContract ? validateAgentChatSubmission(
1194
+ options.inputContract,
1195
+ value,
1196
+ selectedFiles.map((file) => ({ data: file.source || new Uint8Array(), mediaType: file.mediaType, name: file.filename, byteSize: file.byteSize }))
1197
+ ) : null;
1198
+ if (!mountedRef.current || !value.trim() && !selectedFiles.length || options.disabled || options.isCancelling || submittingRef.current || recorder.isCapturing() || !submission && recorder.isProcessing || suppliedError) return false;
1199
+ const generation = generationRef.current;
1117
1200
  const clearedRevision = ++revisionRef.current;
1118
1201
  submittingRef.current = true;
1119
1202
  setIsSubmitting(true);
1120
- inFlightFilesRef.current = selectedFiles;
1203
+ const selectedUrls = new Set(selectedFiles.map((file) => file.url));
1204
+ const replacedFiles = filesRef.current.filter((file) => !selectedUrls.has(file.url));
1205
+ const submissionId = /* @__PURE__ */ Symbol();
1206
+ inFlightFilesRef.current.set(submissionId, selectedFiles);
1207
+ textRef.current = "";
1208
+ filesRef.current = [];
1209
+ revokeUnownedFiles(replacedFiles);
1121
1210
  setTextState("");
1122
1211
  setFiles([]);
1123
1212
  focusComposer();
1124
1213
  try {
1125
1214
  await options.onSubmit(value, selectedFiles);
1126
- revokeAgentChatComposerFiles(selectedFiles);
1215
+ return true;
1127
1216
  } catch {
1128
- if (revisionRef.current === clearedRevision) {
1217
+ if (mountedRef.current && generationRef.current === generation && revisionRef.current === clearedRevision) {
1129
1218
  revisionRef.current += 1;
1219
+ textRef.current = value;
1220
+ filesRef.current = selectedFiles;
1130
1221
  setTextState(value);
1131
1222
  setFiles(selectedFiles);
1132
- } else revokeAgentChatComposerFiles(selectedFiles);
1223
+ }
1224
+ return false;
1133
1225
  } finally {
1134
- inFlightFilesRef.current = [];
1135
- submittingRef.current = false;
1136
- setIsSubmitting(false);
1226
+ inFlightFilesRef.current.delete(submissionId);
1227
+ revokeUnownedFiles(selectedFiles);
1228
+ if (mountedRef.current && generationRef.current === generation) {
1229
+ submittingRef.current = false;
1230
+ setIsSubmitting(false);
1231
+ }
1137
1232
  }
1138
1233
  };
1139
1234
  return {
@@ -1150,6 +1245,7 @@ function useAgentChatComposer(options) {
1150
1245
  attachmentMimeTypes,
1151
1246
  validationError,
1152
1247
  recorder,
1248
+ isProcessing: recorder.isProcessing,
1153
1249
  recordingAllowed: options.recordingEnabled ?? options.inputContract?.modalities.audio.recording_enabled ?? false,
1154
1250
  fileAccept: (0, import_client2.attachmentFileAccept)(attachmentMimeTypes),
1155
1251
  onKeyDown: (event) => {
@@ -1274,6 +1370,7 @@ function formatFileCount(files) {
1274
1370
  var pillButtonClass = "inline-flex size-8 shrink-0 items-center justify-center gap-2 rounded-lg border-0 bg-muted text-sm text-muted-foreground shadow-none transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-0 disabled:pointer-events-none disabled:opacity-50";
1275
1371
  var submitButtonClass = "inline-flex size-9 shrink-0 items-center justify-center gap-2 rounded-lg border-0 bg-primary text-sm text-primary-foreground shadow-none transition-[background-color,color,opacity,transform] duration-200 hover:bg-primary/90 focus-visible:outline-none focus-visible:ring-0 disabled:pointer-events-none disabled:opacity-50";
1276
1372
  function AgentChatComposer({
1373
+ ref,
1277
1374
  inputContract,
1278
1375
  recordingEnabled,
1279
1376
  contextWindow,
@@ -1283,6 +1380,7 @@ function AgentChatComposer({
1283
1380
  disabled = false,
1284
1381
  forceExpanded = false,
1285
1382
  focusKey,
1383
+ scopeKey,
1286
1384
  inputToolbarContent,
1287
1385
  isRunning = false,
1288
1386
  isCancelling = false,
@@ -1301,12 +1399,14 @@ function AgentChatComposer({
1301
1399
  disabled,
1302
1400
  isRunning,
1303
1401
  isCancelling,
1402
+ scopeKey,
1304
1403
  focusKey,
1305
1404
  restoredDraft,
1306
1405
  textareaRef: localTextareaRef,
1307
1406
  onSubmit: (text2, files2) => onSubmit({ text: text2.trim(), files: files2, attachmentIds: files2.flatMap((file) => file.id ? [file.id] : []) })
1308
1407
  });
1309
1408
  const { text, files, setText, isSubmitting, canSubmit, action, submit } = composer;
1409
+ React6.useImperativeHandle(ref, () => ({ setText }), [setText]);
1310
1410
  const isExpanded = forceExpanded || text.includes("\n") || text.length > 62;
1311
1411
  const setTextareaRef = React6.useCallback(
1312
1412
  (node) => {
@@ -1782,11 +1882,68 @@ function AgentChatDefaultActions({
1782
1882
  }
1783
1883
 
1784
1884
  // src/ui/agent-chat-message.tsx
1785
- var React16 = __toESM(require("react"), 1);
1885
+ var React17 = __toESM(require("react"), 1);
1786
1886
  var import_lucide_react9 = require("lucide-react");
1787
1887
 
1888
+ // src/ui/hitl-submission-status.tsx
1889
+ var React9 = __toESM(require("react"), 1);
1890
+ var import_jsx_runtime7 = require("react/jsx-runtime");
1891
+ var defaultHitlSubmissionLabels = {
1892
+ submitting: "Submitting\u2026",
1893
+ checking: "Checking submission\u2026",
1894
+ uncertain: "Submission could not be confirmed.",
1895
+ retry: "Retry submission",
1896
+ accepted: "Accepted; agent continuing",
1897
+ approved: "Approved; agent continuing",
1898
+ rejected: "Rejected"
1899
+ };
1900
+ function isHitlSubmissionCompact(state) {
1901
+ return ["submitting", "resuming", "checking", "uncertain", "accepted"].includes(state?.status || "");
1902
+ }
1903
+ function HitlSubmissionStatus({ state, labels: overrides, onPaint }) {
1904
+ const labels = { ...defaultHitlSubmissionLabels, ...overrides };
1905
+ const started = React9.useRef(performance.now());
1906
+ const ref = React9.useRef(null);
1907
+ const paintCallback = React9.useRef(onPaint);
1908
+ paintCallback.current = onPaint;
1909
+ React9.useEffect(() => {
1910
+ const frame = requestAnimationFrame(() => paintCallback.current?.(performance.now() - started.current));
1911
+ return () => cancelAnimationFrame(frame);
1912
+ }, []);
1913
+ React9.useEffect(() => {
1914
+ ref.current?.focus({ preventScroll: true });
1915
+ }, []);
1916
+ 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;
1917
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1918
+ "div",
1919
+ {
1920
+ ref,
1921
+ tabIndex: -1,
1922
+ role: "status",
1923
+ "aria-live": "polite",
1924
+ "aria-atomic": "true",
1925
+ "data-hitl-submission": state.status,
1926
+ className: "a24-hitl-submission flex items-center gap-2 py-1 text-start text-sm text-muted-foreground outline-none",
1927
+ children: [
1928
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: text }),
1929
+ state.status === "uncertain" && state.retry && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1930
+ "button",
1931
+ {
1932
+ type: "button",
1933
+ className: "rounded px-2 py-1 text-foreground underline underline-offset-2",
1934
+ onClick: () => {
1935
+ void state.retry?.().catch(() => void 0);
1936
+ },
1937
+ children: labels.retry
1938
+ }
1939
+ )
1940
+ ]
1941
+ }
1942
+ );
1943
+ }
1944
+
1788
1945
  // src/ui/agent-response-timeline.tsx
1789
- var React15 = __toESM(require("react"), 1);
1946
+ var React16 = __toESM(require("react"), 1);
1790
1947
 
1791
1948
  // src/streaming-text.ts
1792
1949
  var import_react = require("react");
@@ -1971,7 +2128,7 @@ function useStreamingText({
1971
2128
  }
1972
2129
 
1973
2130
  // src/ui/ask-user-interaction.tsx
1974
- var React9 = __toESM(require("react"), 1);
2131
+ var React10 = __toESM(require("react"), 1);
1975
2132
  var import_lucide_react5 = require("lucide-react");
1976
2133
 
1977
2134
  // src/ui/ask-user-interaction-state.ts
@@ -2028,7 +2185,7 @@ function askUserAnswersFromDrafts(questions, drafts) {
2028
2185
  }
2029
2186
 
2030
2187
  // src/ui/ask-user-interaction.tsx
2031
- var import_jsx_runtime7 = require("react/jsx-runtime");
2188
+ var import_jsx_runtime8 = require("react/jsx-runtime");
2032
2189
  function resolvedAnswerText(question, answer) {
2033
2190
  if (!answer) return ["No response recorded"];
2034
2191
  const labels = answer.selectedOptionIds.flatMap((optionId) => {
@@ -2042,7 +2199,7 @@ function ResolvedQuestions({
2042
2199
  buttonRef,
2043
2200
  part
2044
2201
  }) {
2045
- const [open, setOpen] = React9.useState(false);
2202
+ const [open, setOpen] = React10.useState(false);
2046
2203
  const count = part.questions.length;
2047
2204
  const answers = new Map(
2048
2205
  (part.resolution?.answers || []).map((answer) => [
@@ -2050,8 +2207,8 @@ function ResolvedQuestions({
2050
2207
  answer
2051
2208
  ])
2052
2209
  );
2053
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "a24-ask-user a24-ask-user--resolved w-full", children: [
2054
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
2210
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "a24-ask-user a24-ask-user--resolved w-full", children: [
2211
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
2055
2212
  "button",
2056
2213
  {
2057
2214
  "aria-expanded": open,
@@ -2060,13 +2217,13 @@ function ResolvedQuestions({
2060
2217
  ref: buttonRef,
2061
2218
  type: "button",
2062
2219
  children: [
2063
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { children: [
2220
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { children: [
2064
2221
  "Asked ",
2065
2222
  count,
2066
2223
  " question",
2067
2224
  count === 1 ? "" : "s"
2068
2225
  ] }),
2069
- open ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_lucide_react5.ChevronDown, { "aria-hidden": "true", className: "size-3.5" }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2226
+ open ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react5.ChevronDown, { "aria-hidden": "true", className: "size-3.5" }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2070
2227
  import_lucide_react5.ChevronRight,
2071
2228
  {
2072
2229
  "aria-hidden": "true",
@@ -2076,12 +2233,12 @@ function ResolvedQuestions({
2076
2233
  ]
2077
2234
  }
2078
2235
  ),
2079
- open ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "mt-2 space-y-3 ps-4", children: part.questions.map((question) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "min-w-0", children: [
2080
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "text-sm font-medium text-foreground", children: question.question }),
2081
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "mt-1 space-y-1 text-sm text-muted-foreground", children: resolvedAnswerText(
2236
+ open ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "mt-2 space-y-3 ps-4", children: part.questions.map((question) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "min-w-0", children: [
2237
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "text-sm font-medium text-foreground", children: question.question }),
2238
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "mt-1 space-y-1 text-sm text-muted-foreground", children: resolvedAnswerText(
2082
2239
  question,
2083
2240
  answers.get(question.id)
2084
- ).map((value, index) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2241
+ ).map((value, index) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2085
2242
  "div",
2086
2243
  {
2087
2244
  className: "whitespace-pre-wrap break-words",
@@ -2094,40 +2251,50 @@ function ResolvedQuestions({
2094
2251
  }
2095
2252
  function AskUserInteraction({
2096
2253
  error,
2254
+ submission,
2255
+ submissionLabels,
2256
+ onSubmissionPaint,
2097
2257
  isBusy = false,
2098
2258
  onSubmit,
2099
2259
  part
2100
2260
  }) {
2101
2261
  const questions = part.questions;
2102
- const [step, setStep] = React9.useState(0);
2103
- const [drafts, setDrafts] = React9.useState(
2262
+ const [step, setStep] = React10.useState(0);
2263
+ const [drafts, setDrafts] = React10.useState(
2104
2264
  () => emptyAskUserDrafts(questions)
2105
2265
  );
2106
- const headingRef = React9.useRef(null);
2107
- const questionsRef = React9.useRef(questions);
2108
- const resolvedButtonRef = React9.useRef(null);
2109
- const wasResolvedRef = React9.useRef(part.status !== "pending");
2266
+ const otherRef = React10.useRef(null);
2267
+ const headingRef = React10.useRef(null);
2268
+ const questionsRef = React10.useRef(questions);
2269
+ const resolvedButtonRef = React10.useRef(null);
2270
+ const wasResolvedRef = React10.useRef(part.status !== "pending");
2110
2271
  questionsRef.current = questions;
2111
- React9.useEffect(() => {
2272
+ React10.useEffect(() => {
2112
2273
  setStep(0);
2113
2274
  setDrafts(emptyAskUserDrafts(questionsRef.current));
2114
2275
  }, [part.interruptId]);
2115
- React9.useEffect(() => {
2276
+ React10.useEffect(() => {
2116
2277
  headingRef.current?.focus();
2117
2278
  }, [step]);
2118
- React9.useEffect(() => {
2279
+ React10.useEffect(() => {
2119
2280
  const isResolved = part.status !== "pending";
2120
2281
  if (isResolved && !wasResolvedRef.current) {
2121
2282
  resolvedButtonRef.current?.focus();
2122
2283
  }
2123
2284
  wasResolvedRef.current = isResolved;
2124
2285
  }, [part.status]);
2286
+ React10.useEffect(() => {
2287
+ if (submission?.status === "error") (otherRef.current?.value ? otherRef.current : headingRef.current)?.focus();
2288
+ }, [submission?.status]);
2289
+ if (part.status === "pending" && isHitlSubmissionCompact(submission)) {
2290
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(HitlSubmissionStatus, { state: submission, labels: submissionLabels, onPaint: onSubmissionPaint });
2291
+ }
2125
2292
  if (part.status !== "pending") {
2126
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ResolvedQuestions, { buttonRef: resolvedButtonRef, part });
2293
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ResolvedQuestions, { buttonRef: resolvedButtonRef, part });
2127
2294
  }
2128
2295
  const question = questions[step];
2129
2296
  if (!question) {
2130
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "text-sm text-destructive", role: "alert", children: "This question request is unavailable." });
2297
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "text-sm text-destructive", role: "alert", children: "This question request is unavailable." });
2131
2298
  }
2132
2299
  const draft = drafts[question.id] || {
2133
2300
  customText: "",
@@ -2161,9 +2328,9 @@ function AskUserInteraction({
2161
2328
  })
2162
2329
  );
2163
2330
  };
2164
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "a24-ask-user space-y-3 rounded-xl border border-border/50 bg-background p-4 shadow-sm", children: [
2165
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex min-w-0 items-start justify-between gap-4", children: [
2166
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2331
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "a24-ask-user space-y-3 rounded-xl border border-border/50 bg-background p-4 shadow-sm", children: [
2332
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex min-w-0 items-start justify-between gap-4", children: [
2333
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2167
2334
  "h3",
2168
2335
  {
2169
2336
  className: "min-w-0 flex-1 text-base font-medium leading-6 text-foreground outline-none",
@@ -2172,8 +2339,8 @@ function AskUserInteraction({
2172
2339
  children: question.question
2173
2340
  }
2174
2341
  ),
2175
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex shrink-0 items-center gap-1 text-muted-foreground", children: [
2176
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2342
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex shrink-0 items-center gap-1 text-muted-foreground", children: [
2343
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2177
2344
  "button",
2178
2345
  {
2179
2346
  "aria-label": "Previous question",
@@ -2181,7 +2348,7 @@ function AskUserInteraction({
2181
2348
  disabled: isBusy || step === 0,
2182
2349
  onClick: () => setStep((current) => Math.max(0, current - 1)),
2183
2350
  type: "button",
2184
- children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2351
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2185
2352
  import_lucide_react5.ChevronLeft,
2186
2353
  {
2187
2354
  "aria-hidden": "true",
@@ -2190,7 +2357,7 @@ function AskUserInteraction({
2190
2357
  )
2191
2358
  }
2192
2359
  ),
2193
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
2360
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
2194
2361
  "span",
2195
2362
  {
2196
2363
  "aria-label": `Question ${step + 1} of ${questions.length}`,
@@ -2202,7 +2369,7 @@ function AskUserInteraction({
2202
2369
  ]
2203
2370
  }
2204
2371
  ),
2205
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2372
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2206
2373
  "button",
2207
2374
  {
2208
2375
  "aria-label": isLastQuestion ? "Submit answers" : "Next question",
@@ -2210,7 +2377,7 @@ function AskUserInteraction({
2210
2377
  disabled: isBusy || !onSubmit || !canMoveForward,
2211
2378
  onClick: () => completeStep(drafts),
2212
2379
  type: "button",
2213
- children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2380
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2214
2381
  import_lucide_react5.ChevronRight,
2215
2382
  {
2216
2383
  "aria-hidden": "true",
@@ -2221,10 +2388,10 @@ function AskUserInteraction({
2221
2388
  )
2222
2389
  ] })
2223
2390
  ] }),
2224
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "space-y-1", children: [
2391
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "space-y-1", children: [
2225
2392
  question.options.map((option, index) => {
2226
2393
  const selected = draft.selectedOptionIds.includes(option.id);
2227
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
2394
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
2228
2395
  "button",
2229
2396
  {
2230
2397
  "aria-pressed": selected,
@@ -2236,7 +2403,7 @@ function AskUserInteraction({
2236
2403
  onClick: () => selectOption(option.id),
2237
2404
  type: "button",
2238
2405
  children: [
2239
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2406
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2240
2407
  "span",
2241
2408
  {
2242
2409
  className: cn(
@@ -2246,8 +2413,8 @@ function AskUserInteraction({
2246
2413
  children: index + 1
2247
2414
  }
2248
2415
  ),
2249
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "min-w-0 flex-1 font-medium text-foreground", children: option.label }),
2250
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2416
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "min-w-0 flex-1 font-medium text-foreground", children: option.label }),
2417
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2251
2418
  import_lucide_react5.ChevronRight,
2252
2419
  {
2253
2420
  "aria-hidden": "true",
@@ -2259,11 +2426,12 @@ function AskUserInteraction({
2259
2426
  option.id
2260
2427
  );
2261
2428
  }),
2262
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex min-h-11 items-center gap-2 rounded-xl bg-muted px-2.5 py-1.5 focus-within:ring-1 focus-within:ring-ring", children: [
2263
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "flex size-8 shrink-0 items-center justify-center rounded-full border border-border/70 bg-background/70 text-muted-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_lucide_react5.Pencil, { "aria-hidden": "true", className: "size-4" }) }),
2264
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2429
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex min-h-11 items-center gap-2 rounded-xl bg-muted px-2.5 py-1.5 focus-within:ring-1 focus-within:ring-ring", children: [
2430
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "flex size-8 shrink-0 items-center justify-center rounded-full border border-border/70 bg-background/70 text-muted-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react5.Pencil, { "aria-hidden": "true", className: "size-4" }) }),
2431
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2265
2432
  "input",
2266
2433
  {
2434
+ ref: otherRef,
2267
2435
  "aria-label": "Other response",
2268
2436
  autoComplete: "off",
2269
2437
  className: "h-8 min-w-0 flex-1 bg-transparent px-1 text-sm text-foreground outline-none placeholder:text-muted-foreground",
@@ -2280,7 +2448,7 @@ function AskUserInteraction({
2280
2448
  value: draft.customText
2281
2449
  }
2282
2450
  ),
2283
- draft.customText.trim() ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2451
+ draft.customText.trim() ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2284
2452
  "button",
2285
2453
  {
2286
2454
  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",
@@ -2292,12 +2460,12 @@ function AskUserInteraction({
2292
2460
  ) : null
2293
2461
  ] })
2294
2462
  ] }),
2295
- error ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "text-sm text-destructive", role: "alert", children: error }) : null
2463
+ error ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "text-sm text-destructive", role: "alert", children: error }) : null
2296
2464
  ] });
2297
2465
  }
2298
2466
 
2299
2467
  // src/ui/agent-chat-context-compression-row.tsx
2300
- var import_jsx_runtime8 = require("react/jsx-runtime");
2468
+ var import_jsx_runtime9 = require("react/jsx-runtime");
2301
2469
  function compressionPresentation(part) {
2302
2470
  if (part.status === "failed") {
2303
2471
  return { label: "Could not compact message history", status: "failed" };
@@ -2312,7 +2480,7 @@ function AgentChatContextCompressionRow({
2312
2480
  part
2313
2481
  }) {
2314
2482
  const presentation = compressionPresentation(part);
2315
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2483
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2316
2484
  "div",
2317
2485
  {
2318
2486
  "aria-live": "polite",
@@ -2320,11 +2488,11 @@ function AgentChatContextCompressionRow({
2320
2488
  "data-agents24-context-compression": "",
2321
2489
  "data-status": part.status,
2322
2490
  role: "status",
2323
- children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "a24-tool-trigger-row", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: cn(
2491
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "a24-tool-trigger-row", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: cn(
2324
2492
  "a24-tool-trigger a24-tool-trigger--root a24-tool-trigger--without-orb",
2325
2493
  presentation.status === "failed" && "a24-tool-trigger--error",
2326
2494
  presentation.status === "running" && "a24-tool-trigger--active"
2327
- ), children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: cn(
2495
+ ), children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: cn(
2328
2496
  "a24-tool-trigger__label",
2329
2497
  presentation.status === "running" && "a24-tool-shimmer"
2330
2498
  ), children: presentation.label }) }) })
@@ -2333,7 +2501,7 @@ function AgentChatContextCompressionRow({
2333
2501
  }
2334
2502
 
2335
2503
  // src/ui/message-response.tsx
2336
- var React13 = __toESM(require("react"), 1);
2504
+ var React14 = __toESM(require("react"), 1);
2337
2505
  var import_streamdown = require("streamdown");
2338
2506
 
2339
2507
  // src/active-content.ts
@@ -2358,14 +2526,14 @@ function safeChatMarkdownHref(value) {
2358
2526
  }
2359
2527
 
2360
2528
  // src/ui/message-code.tsx
2361
- var React12 = __toESM(require("react"), 1);
2529
+ var React13 = __toESM(require("react"), 1);
2362
2530
  var import_lucide_react7 = require("lucide-react");
2363
2531
 
2364
2532
  // src/ui/code-block.tsx
2365
- var React10 = __toESM(require("react"), 1);
2533
+ var React11 = __toESM(require("react"), 1);
2366
2534
  var import_class_variance_authority2 = require("class-variance-authority");
2367
2535
  var import_lucide_react6 = require("lucide-react");
2368
- var import_jsx_runtime9 = require("react/jsx-runtime");
2536
+ var import_jsx_runtime10 = require("react/jsx-runtime");
2369
2537
  var codeBlockVariants = (0, import_class_variance_authority2.cva)(
2370
2538
  "a24-code-block",
2371
2539
  {
@@ -2386,7 +2554,7 @@ function CodeBlock({
2386
2554
  size = "default",
2387
2555
  ...props
2388
2556
  }) {
2389
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2557
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2390
2558
  "div",
2391
2559
  {
2392
2560
  "data-slot": "code-block",
@@ -2398,7 +2566,7 @@ function CodeBlock({
2398
2566
  );
2399
2567
  }
2400
2568
  function CodeBlockHeader({ className, ...props }) {
2401
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2569
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2402
2570
  "div",
2403
2571
  {
2404
2572
  "data-slot": "code-block-header",
@@ -2411,7 +2579,7 @@ function CodeBlockHeader({ className, ...props }) {
2411
2579
  );
2412
2580
  }
2413
2581
  function CodeBlockTitle({ className, ...props }) {
2414
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2582
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2415
2583
  "div",
2416
2584
  {
2417
2585
  "data-slot": "code-block-title",
@@ -2427,7 +2595,7 @@ function CodeBlockActions({
2427
2595
  className,
2428
2596
  ...props
2429
2597
  }) {
2430
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2598
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2431
2599
  "div",
2432
2600
  {
2433
2601
  "data-slot": "code-block-actions",
@@ -2445,16 +2613,16 @@ function CodeBlockCopyButton({
2445
2613
  onClick,
2446
2614
  ...props
2447
2615
  }) {
2448
- const [copied, setCopied] = React10.useState(false);
2449
- React10.useEffect(() => {
2616
+ const [copied, setCopied] = React11.useState(false);
2617
+ React11.useEffect(() => {
2450
2618
  if (!copied) {
2451
2619
  return;
2452
2620
  }
2453
2621
  const timeout = setTimeout(() => setCopied(false), 2e3);
2454
2622
  return () => clearTimeout(timeout);
2455
2623
  }, [copied]);
2456
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
2457
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2624
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
2625
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2458
2626
  "button",
2459
2627
  {
2460
2628
  type: "button",
@@ -2470,10 +2638,10 @@ function CodeBlockCopyButton({
2470
2638
  });
2471
2639
  },
2472
2640
  ...props,
2473
- children: copied ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react6.CheckIcon, { size: 12, strokeWidth: 1.5 }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react6.CopyIcon, { size: 12, strokeWidth: 1.5 })
2641
+ children: copied ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react6.CheckIcon, { size: 12, strokeWidth: 1.5 }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react6.CopyIcon, { size: 12, strokeWidth: 1.5 })
2474
2642
  }
2475
2643
  ),
2476
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { "aria-live": "polite", className: "a24-code-block__announcement", children: copied ? "Copied" : "" })
2644
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { "aria-live": "polite", className: "a24-code-block__announcement", children: copied ? "Copied" : "" })
2477
2645
  ] });
2478
2646
  }
2479
2647
  function CodeBlockWrapButton({
@@ -2483,7 +2651,7 @@ function CodeBlockWrapButton({
2483
2651
  onClick,
2484
2652
  ...props
2485
2653
  }) {
2486
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2654
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2487
2655
  "button",
2488
2656
  {
2489
2657
  type: "button",
@@ -2497,7 +2665,7 @@ function CodeBlockWrapButton({
2497
2665
  if (!event.defaultPrevented) onWrapChange(!wrap);
2498
2666
  },
2499
2667
  ...props,
2500
- children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react6.WrapTextIcon, { size: 12, strokeWidth: 1.5 })
2668
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react6.WrapTextIcon, { size: 12, strokeWidth: 1.5 })
2501
2669
  }
2502
2670
  );
2503
2671
  }
@@ -2508,7 +2676,7 @@ function CodeBlockDownloadButton({
2508
2676
  onClick,
2509
2677
  ...props
2510
2678
  }) {
2511
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2679
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2512
2680
  "button",
2513
2681
  {
2514
2682
  type: "button",
@@ -2529,7 +2697,7 @@ function CodeBlockDownloadButton({
2529
2697
  setTimeout(() => URL.revokeObjectURL(url), 1e3);
2530
2698
  },
2531
2699
  ...props,
2532
- children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react6.DownloadIcon, { size: 12, strokeWidth: 1.5 })
2700
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react6.DownloadIcon, { size: 12, strokeWidth: 1.5 })
2533
2701
  }
2534
2702
  );
2535
2703
  }
@@ -2542,7 +2710,7 @@ function CodeBlockContent({
2542
2710
  startLine = 1,
2543
2711
  ...props
2544
2712
  }) {
2545
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2713
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2546
2714
  "pre",
2547
2715
  {
2548
2716
  "data-slot": "code-block-content",
@@ -2556,12 +2724,12 @@ function CodeBlockContent({
2556
2724
  className
2557
2725
  ),
2558
2726
  ...props,
2559
- children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2727
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2560
2728
  "code",
2561
2729
  {
2562
2730
  "data-slot": "code-block-code",
2563
2731
  className: "a24-code-block__code",
2564
- children: lineNumbers && typeof children === "string" ? children.replace(/\n$/, "").split("\n").map((line, index) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(CodeBlockLine, { children: line }, index)) : children
2732
+ children: lineNumbers && typeof children === "string" ? children.replace(/\n$/, "").split("\n").map((line, index) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(CodeBlockLine, { children: line }, index)) : children
2565
2733
  }
2566
2734
  )
2567
2735
  }
@@ -2590,19 +2758,19 @@ function CodeBlockLine({
2590
2758
  ...props
2591
2759
  }) {
2592
2760
  const empty = children === void 0 || children === null || children === "" || Array.isArray(children) && children.length === 0;
2593
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2761
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2594
2762
  "span",
2595
2763
  {
2596
2764
  "data-slot": "code-block-line",
2597
2765
  "data-variant": variant,
2598
2766
  className: cn(codeBlockLineVariants({ variant }), className),
2599
2767
  ...props,
2600
- children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { "data-slot": "code-block-line-content", className: "a24-code-block__line-content", children: empty ? "\n" : children })
2768
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { "data-slot": "code-block-line-content", className: "a24-code-block__line-content", children: empty ? "\n" : children })
2601
2769
  }
2602
2770
  );
2603
2771
  }
2604
2772
  function CodeBlockFooter({ className, ...props }) {
2605
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2773
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2606
2774
  "div",
2607
2775
  {
2608
2776
  "data-slot": "code-block-footer",
@@ -2616,13 +2784,13 @@ function CodeBlockFooter({ className, ...props }) {
2616
2784
  }
2617
2785
 
2618
2786
  // src/ui/use-highlighted-code.ts
2619
- var React11 = __toESM(require("react"), 1);
2787
+ var React12 = __toESM(require("react"), 1);
2620
2788
 
2621
2789
  // src/ui/code-highlighter.tsx
2622
2790
  var import_core = require("shiki/core");
2623
2791
  var import_javascript = require("shiki/engine/javascript");
2624
2792
  var import_langs = require("shiki/langs");
2625
- var import_jsx_runtime10 = require("react/jsx-runtime");
2793
+ var import_jsx_runtime11 = require("react/jsx-runtime");
2626
2794
  var languageLoaders = {
2627
2795
  ...import_langs.bundledLanguages,
2628
2796
  ...import_langs.bundledLanguagesAlias
@@ -2667,7 +2835,7 @@ async function loadHighlighter(language) {
2667
2835
  const tokens = lang === "ansi" ? code.split("\n").flatMap((line) => tokenize(line)) : tokenize(code);
2668
2836
  return {
2669
2837
  lines: tokens.map(
2670
- (line) => line.map((token, index) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2838
+ (line) => line.map((token, index) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2671
2839
  "span",
2672
2840
  {
2673
2841
  style: token.htmlStyle,
@@ -2686,9 +2854,9 @@ async function loadHighlighter(language) {
2686
2854
  // src/ui/use-highlighted-code.ts
2687
2855
  function useHighlightedCode(value, language) {
2688
2856
  const code = value.endsWith("\n") ? value.slice(0, -1) : value;
2689
- const [loaded, setLoaded] = React11.useState(null);
2857
+ const [loaded, setLoaded] = React12.useState(null);
2690
2858
  const highlighter2 = loaded?.language === language ? loaded.highlighter : null;
2691
- React11.useEffect(() => {
2859
+ React12.useEffect(() => {
2692
2860
  let cancelled = false;
2693
2861
  loadHighlighter(language).then((next2) => {
2694
2862
  if (!cancelled) {
@@ -2700,7 +2868,7 @@ function useHighlightedCode(value, language) {
2700
2868
  cancelled = true;
2701
2869
  };
2702
2870
  }, [language]);
2703
- const [done, setDone] = React11.useState({ highlighter: null, text: "", lines: [] });
2871
+ const [done, setDone] = React12.useState({ highlighter: null, text: "", lines: [] });
2704
2872
  let next = done;
2705
2873
  if (next.highlighter !== highlighter2 || !code.startsWith(next.text)) {
2706
2874
  next = { highlighter: highlighter2, text: "", lines: [] };
@@ -2722,7 +2890,7 @@ function useHighlightedCode(value, language) {
2722
2890
  setDone(next);
2723
2891
  }
2724
2892
  const tail = code.slice(end);
2725
- return React11.useMemo(() => {
2893
+ return React12.useMemo(() => {
2726
2894
  if (!highlighter2) {
2727
2895
  return code.split("\n");
2728
2896
  }
@@ -2731,7 +2899,7 @@ function useHighlightedCode(value, language) {
2731
2899
  }
2732
2900
 
2733
2901
  // src/ui/message-code.tsx
2734
- var import_jsx_runtime11 = require("react/jsx-runtime");
2902
+ var import_jsx_runtime12 = require("react/jsx-runtime");
2735
2903
  var CODE_EXTENSIONS = {
2736
2904
  bash: "sh",
2737
2905
  shell: "sh",
@@ -2773,32 +2941,32 @@ var CODE_EXTENSIONS = {
2773
2941
  plaintext: "txt"
2774
2942
  };
2775
2943
  function MessageCodeBlock({ code, language = "text" }) {
2776
- const [wrap, setWrap] = React12.useState(false);
2944
+ const [wrap, setWrap] = React13.useState(false);
2777
2945
  const lines = useHighlightedCode(code, language);
2778
2946
  const extension = Object.prototype.hasOwnProperty.call(CODE_EXTENSIONS, language.toLowerCase()) ? CODE_EXTENSIONS[language.toLowerCase()] : "txt";
2779
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(CodeBlock, { children: [
2780
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(CodeBlockHeader, { children: [
2781
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(CodeBlockTitle, { children: [
2782
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react7.FileCode2Icon, { size: 14, strokeWidth: 1.5, "aria-hidden": "true" }),
2783
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: language })
2947
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(CodeBlock, { children: [
2948
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(CodeBlockHeader, { children: [
2949
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(CodeBlockTitle, { children: [
2950
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react7.FileCode2Icon, { size: 14, strokeWidth: 1.5, "aria-hidden": "true" }),
2951
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: language })
2784
2952
  ] }),
2785
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(CodeBlockActions, { children: [
2786
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(CodeBlockWrapButton, { wrap, onWrapChange: setWrap }),
2787
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(CodeBlockDownloadButton, { value: code, filename: `code.${extension}` }),
2788
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(CodeBlockCopyButton, { value: code })
2953
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(CodeBlockActions, { children: [
2954
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(CodeBlockWrapButton, { wrap, onWrapChange: setWrap }),
2955
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(CodeBlockDownloadButton, { value: code, filename: `code.${extension}` }),
2956
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(CodeBlockCopyButton, { value: code })
2789
2957
  ] })
2790
2958
  ] }),
2791
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(CodeBlockContent, { "aria-label": `${language} code`, lineNumbers: true, wrap, children: lines.map((line, index) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(CodeBlockLine, { children: line }, index)) })
2959
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(CodeBlockContent, { "aria-label": `${language} code`, lineNumbers: true, wrap, children: lines.map((line, index) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(CodeBlockLine, { children: line }, index)) })
2792
2960
  ] });
2793
2961
  }
2794
2962
  function MessageMarkdownCode({ children, className, node, ...props }) {
2795
2963
  const language = className?.match(/(?:^|\s)language-([^\s]+)/)?.[1];
2796
2964
  const multiline = node?.position?.start?.line !== node?.position?.end?.line;
2797
2965
  if (props["data-block"] === void 0 && !language && !multiline) {
2798
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("code", { ...props, className: cn("a24-inline-code", className), "data-streamdown": "inline-code", children });
2966
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("code", { ...props, className: cn("a24-inline-code", className), "data-streamdown": "inline-code", children });
2799
2967
  }
2800
2968
  const code = typeof children === "string" ? children.replace(/\n$/, "") : "";
2801
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(MessageCodeBlock, { code, language });
2969
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(MessageCodeBlock, { code, language });
2802
2970
  }
2803
2971
  function formatMessageJson(text) {
2804
2972
  const trimmed = text.trim();
@@ -2832,17 +3000,17 @@ ${" ".repeat(depth)}`;
2832
3000
  }
2833
3001
 
2834
3002
  // src/ui/message-response.tsx
2835
- var import_jsx_runtime12 = require("react/jsx-runtime");
3003
+ var import_jsx_runtime13 = require("react/jsx-runtime");
2836
3004
  function SafeMarkdownLink({ children, href, ...props }) {
2837
3005
  const domProps = { ...props };
2838
3006
  delete domProps.node;
2839
3007
  const safeHref = safeChatMarkdownHref(href);
2840
- if (!safeHref) return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children });
2841
- if (safeHref.startsWith("#")) return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("a", { ...domProps, href: safeHref, children });
2842
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("a", { ...domProps, href: safeHref, rel: "noopener noreferrer", target: "_blank", children });
3008
+ if (!safeHref) return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children });
3009
+ if (safeHref.startsWith("#")) return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("a", { ...domProps, href: safeHref, children });
3010
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("a", { ...domProps, href: safeHref, rel: "noopener noreferrer", target: "_blank", children });
2843
3011
  }
2844
3012
  function BlockedMarkdownImage({ alt }) {
2845
- return alt ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { "aria-label": `Image blocked: ${alt}`, role: "img", children: alt }) : null;
3013
+ return alt ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { "aria-label": `Image blocked: ${alt}`, role: "img", children: alt }) : null;
2846
3014
  }
2847
3015
  var BLOCK_MARKDOWN_TAGS = /* @__PURE__ */ new Set([
2848
3016
  "blockquote",
@@ -2863,7 +3031,7 @@ function isMultilineCodeNode(node) {
2863
3031
  return node?.tagName === "code" && node.position?.start?.line !== void 0 && node.position?.end?.line !== void 0 && node.position.start.line !== node.position.end.line;
2864
3032
  }
2865
3033
  function hasBlockMarkdownChild(child) {
2866
- if (!React13.isValidElement(child)) {
3034
+ if (!React14.isValidElement(child)) {
2867
3035
  return false;
2868
3036
  }
2869
3037
  if (typeof child.type === "string" && BLOCK_MARKDOWN_TAGS.has(child.type)) {
@@ -2873,7 +3041,7 @@ function hasBlockMarkdownChild(child) {
2873
3041
  if (BLOCK_MARKDOWN_TAGS.has(props.node?.tagName || "") || isMultilineCodeNode(props.node)) {
2874
3042
  return true;
2875
3043
  }
2876
- return React13.Children.toArray(props.children).some(hasBlockMarkdownChild);
3044
+ return React14.Children.toArray(props.children).some(hasBlockMarkdownChild);
2877
3045
  }
2878
3046
  function MessageMarkdownParagraph({
2879
3047
  children,
@@ -2881,17 +3049,17 @@ function MessageMarkdownParagraph({
2881
3049
  }) {
2882
3050
  const domProps = { ...props };
2883
3051
  delete domProps.node;
2884
- const childArray = React13.Children.toArray(children).filter(
3052
+ const childArray = React14.Children.toArray(children).filter(
2885
3053
  (child) => child !== null && child !== ""
2886
3054
  );
2887
- const isImageOnly = childArray.length === 1 && React13.isValidElement(childArray[0]) && childArray[0].props.node?.tagName === "img";
3055
+ const isImageOnly = childArray.length === 1 && React14.isValidElement(childArray[0]) && childArray[0].props.node?.tagName === "img";
2888
3056
  if (isImageOnly) {
2889
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_jsx_runtime12.Fragment, { children });
3057
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_jsx_runtime13.Fragment, { children });
2890
3058
  }
2891
3059
  if (childArray.some(hasBlockMarkdownChild)) {
2892
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { ...domProps, children });
3060
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { ...domProps, children });
2893
3061
  }
2894
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { ...domProps, children });
3062
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { ...domProps, children });
2895
3063
  }
2896
3064
  var MESSAGE_RESPONSE_COMPONENTS = {
2897
3065
  a: SafeMarkdownLink,
@@ -2912,7 +3080,7 @@ var MESSAGE_RESPONSE_REHYPE_PLUGINS = [
2912
3080
  ]
2913
3081
  ] : []
2914
3082
  ];
2915
- var MessageResponse = React13.memo(
3083
+ var MessageResponse = React14.memo(
2916
3084
  ({
2917
3085
  children,
2918
3086
  className,
@@ -2930,13 +3098,13 @@ var MessageResponse = React13.memo(
2930
3098
  maxCatchupChars: 32,
2931
3099
  text
2932
3100
  });
2933
- const streamdownComponents = React13.useMemo(
3101
+ const streamdownComponents = React14.useMemo(
2934
3102
  () => ({ ...MESSAGE_RESPONSE_COMPONENTS, ...components }),
2935
3103
  [components]
2936
3104
  );
2937
- const json = React13.useMemo(() => formatMessageJson(text), [text]);
3105
+ const json = React14.useMemo(() => formatMessageJson(text), [text]);
2938
3106
  if (json !== null && !components?.code) {
2939
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: cn("a24-message-response", className), children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
3107
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: cn("a24-message-response", className), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2940
3108
  MessageCodeBlock,
2941
3109
  {
2942
3110
  code: streaming || streamingText.isAnimating ? streamingText.displayedText : json,
@@ -2944,7 +3112,7 @@ var MessageResponse = React13.memo(
2944
3112
  }
2945
3113
  ) });
2946
3114
  }
2947
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
3115
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2948
3116
  import_streamdown.Streamdown,
2949
3117
  {
2950
3118
  className: cn("a24-message-response", className),
@@ -2996,10 +3164,10 @@ function resolvedHitlLabel(part) {
2996
3164
  }
2997
3165
 
2998
3166
  // src/ui/tool-sessions.tsx
2999
- var React14 = __toESM(require("react"), 1);
3167
+ var React15 = __toESM(require("react"), 1);
3000
3168
  var import_lucide_react8 = require("lucide-react");
3001
3169
  var import_thinking_orbs = require("thinking-orbs");
3002
- var import_jsx_runtime13 = require("react/jsx-runtime");
3170
+ var import_jsx_runtime14 = require("react/jsx-runtime");
3003
3171
  function toolSlotContext(isActive2, label, part, slots) {
3004
3172
  return {
3005
3173
  isActive: isActive2,
@@ -3017,7 +3185,7 @@ function ToolResourceAction({ context }) {
3017
3185
  const target = context.resourceTargets[0];
3018
3186
  if (!target) return null;
3019
3187
  const name = resourceTargetName(target);
3020
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3188
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3021
3189
  "button",
3022
3190
  {
3023
3191
  "aria-label": `Open ${target.kind} ${target.path}`,
@@ -3031,8 +3199,8 @@ function ToolResourceAction({ context }) {
3031
3199
  );
3032
3200
  }
3033
3201
  function toolAccessory(context, slots) {
3034
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
3035
- slots?.onResourceAction ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ToolResourceAction, { context }) : null,
3202
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
3203
+ slots?.onResourceAction ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ToolResourceAction, { context }) : null,
3036
3204
  slots?.renderToolAccessory?.(context)
3037
3205
  ] });
3038
3206
  }
@@ -3109,12 +3277,12 @@ function ToolActivityReel({
3109
3277
  }) {
3110
3278
  const initial = initialLabel && initialLabel !== label ? initialLabel : label;
3111
3279
  const parsedInitialShownAt = initialShownAt ? Date.parse(initialShownAt) : Number.NaN;
3112
- const [displayed, setDisplayed] = React14.useState(initial);
3113
- const [previous, setPrevious] = React14.useState(null);
3114
- const displayedRef = React14.useRef(initial);
3115
- const latestRef = React14.useRef(label);
3116
- const shownAtRef = React14.useRef(Number.isFinite(parsedInitialShownAt) ? parsedInitialShownAt : Date.now());
3117
- React14.useEffect(() => {
3280
+ const [displayed, setDisplayed] = React15.useState(initial);
3281
+ const [previous, setPrevious] = React15.useState(null);
3282
+ const displayedRef = React15.useRef(initial);
3283
+ const latestRef = React15.useRef(label);
3284
+ const shownAtRef = React15.useRef(Number.isFinite(parsedInitialShownAt) ? parsedInitialShownAt : Date.now());
3285
+ React15.useEffect(() => {
3118
3286
  latestRef.current = label;
3119
3287
  if (displayedRef.current === label) return;
3120
3288
  const showLatest = () => {
@@ -3134,18 +3302,18 @@ function ToolActivityReel({
3134
3302
  const timer = window.setTimeout(showLatest, remaining);
3135
3303
  return () => window.clearTimeout(timer);
3136
3304
  }, [label]);
3137
- React14.useEffect(() => {
3305
+ React15.useEffect(() => {
3138
3306
  if (!previous) return;
3139
3307
  const timer = window.setTimeout(() => setPrevious(null), 200);
3140
3308
  return () => window.clearTimeout(timer);
3141
3309
  }, [previous]);
3142
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "a24-tool-reel", "aria-live": announce ? "polite" : "off", children: [
3143
- previous ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { "aria-hidden": "true", className: "a24-tool-reel__previous", children: previous }) : null,
3144
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: previous ? "a24-tool-reel__current" : void 0, children: displayed })
3310
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "a24-tool-reel", "aria-live": announce ? "polite" : "off", children: [
3311
+ previous ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { "aria-hidden": "true", className: "a24-tool-reel__previous", children: previous }) : null,
3312
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: previous ? "a24-tool-reel__current" : void 0, children: displayed })
3145
3313
  ] });
3146
3314
  }
3147
3315
  function ToolActivityOrb({ label = "Working", kind = "tool", part, renderActivityIcon }) {
3148
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "a24-tool-orb", children: renderActivityIcon ? renderActivityIcon({ label, kind, part }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_thinking_orbs.ThinkingOrb, { "aria-label": label, size: 20, speed: 0.8, state: "searching" }) });
3316
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "a24-tool-orb", children: renderActivityIcon ? renderActivityIcon({ label, kind, part }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_thinking_orbs.ThinkingOrb, { "aria-label": label, size: 20, speed: 0.8, state: "searching" }) });
3149
3317
  }
3150
3318
  function AgentChatActivityRow({
3151
3319
  label,
@@ -3153,22 +3321,22 @@ function AgentChatActivityRow({
3153
3321
  renderActivityIcon,
3154
3322
  onSelect
3155
3323
  }) {
3156
- const content = /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
3157
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ToolActivityOrb, { label, kind: "planning", renderActivityIcon }),
3158
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "a24-tool-trigger__label a24-tool-shimmer", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ToolActivityReel, { label }) })
3324
+ const content = /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
3325
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ToolActivityOrb, { label, kind: "planning", renderActivityIcon }),
3326
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "a24-tool-trigger__label a24-tool-shimmer", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ToolActivityReel, { label }) })
3159
3327
  ] });
3160
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "a24-tool-trigger-row a24-tool-trigger-row--root", "data-agents24-model-turn": modelTurnId, role: "status", children: onSelect ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { className: "a24-tool-trigger a24-tool-trigger--root a24-tool-trigger--active", onClick: onSelect, type: "button", children: content }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "a24-tool-trigger a24-tool-trigger--root a24-tool-trigger--active", children: content }) });
3328
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "a24-tool-trigger-row a24-tool-trigger-row--root", "data-agents24-model-turn": modelTurnId, role: "status", children: onSelect ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { className: "a24-tool-trigger a24-tool-trigger--root a24-tool-trigger--active", onClick: onSelect, type: "button", children: content }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "a24-tool-trigger a24-tool-trigger--root a24-tool-trigger--active", children: content }) });
3161
3329
  }
3162
3330
  function AgentChatModelTurnRow({ part }) {
3163
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(AgentChatActivityRow, { label: "Planning next moves", modelTurnId: part.modelTurnId });
3331
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(AgentChatActivityRow, { label: "Planning next moves", modelTurnId: part.modelTurnId });
3164
3332
  }
3165
3333
  function AgentChatNodeActivityRow({
3166
3334
  renderActivityIcon,
3167
3335
  onSelect,
3168
3336
  part
3169
3337
  }) {
3170
- const [open, setOpen] = React14.useState(false);
3171
- const contentId = React14.useId();
3338
+ const [open, setOpen] = React15.useState(false);
3339
+ const contentId = React15.useId();
3172
3340
  const running = part.status === "running";
3173
3341
  const failed = part.status === "failed";
3174
3342
  const failureMessage = part.failure?.message || "The node could not complete the request.";
@@ -3179,18 +3347,18 @@ function AgentChatNodeActivityRow({
3179
3347
  running && "a24-tool-trigger--active",
3180
3348
  failed && "a24-tool-trigger--error"
3181
3349
  );
3182
- const label = running ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "a24-tool-shimmer", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ToolActivityReel, { label: part.label }) }) : part.label;
3350
+ const label = running ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "a24-tool-shimmer", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ToolActivityReel, { label: part.label }) }) : part.label;
3183
3351
  if (!failed) {
3184
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "a24-tool-trigger-row", role: "status", children: onSelect ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("button", { className: triggerClassName, onClick: () => onSelect(part), type: "button", children: [
3185
- running ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ToolActivityOrb, { label: part.label, kind: "node", part, renderActivityIcon }) : null,
3186
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "a24-tool-trigger__label", children: label })
3187
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: triggerClassName, children: [
3188
- running ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ToolActivityOrb, { label: part.label, kind: "node", part, renderActivityIcon }) : null,
3189
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "a24-tool-trigger__label", children: label })
3352
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "a24-tool-trigger-row", role: "status", children: onSelect ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("button", { className: triggerClassName, onClick: () => onSelect(part), type: "button", children: [
3353
+ running ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ToolActivityOrb, { label: part.label, kind: "node", part, renderActivityIcon }) : null,
3354
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "a24-tool-trigger__label", children: label })
3355
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: triggerClassName, children: [
3356
+ running ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ToolActivityOrb, { label: part.label, kind: "node", part, renderActivityIcon }) : null,
3357
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "a24-tool-trigger__label", children: label })
3190
3358
  ] }) });
3191
3359
  }
3192
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "a24-tool-disclosure", children: [
3193
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "a24-tool-trigger-row", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
3360
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "a24-tool-disclosure", children: [
3361
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "a24-tool-trigger-row", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
3194
3362
  "button",
3195
3363
  {
3196
3364
  "aria-controls": contentId,
@@ -3202,12 +3370,12 @@ function AgentChatNodeActivityRow({
3202
3370
  },
3203
3371
  type: "button",
3204
3372
  children: [
3205
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "a24-tool-trigger__label", children: label }),
3206
- open ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react8.ChevronDown, { "aria-hidden": "true", className: "a24-tool-trigger__chevron" }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react8.ChevronRight, { "aria-hidden": "true", className: "a24-tool-trigger__chevron" })
3373
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "a24-tool-trigger__label", children: label }),
3374
+ open ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react8.ChevronDown, { "aria-hidden": "true", className: "a24-tool-trigger__chevron" }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react8.ChevronRight, { "aria-hidden": "true", className: "a24-tool-trigger__chevron" })
3207
3375
  ]
3208
3376
  }
3209
3377
  ) }),
3210
- open ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "a24-tool-detail a24-tool-detail--error", id: contentId, children: failureMessage }) : null
3378
+ open ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "a24-tool-detail a24-tool-detail--error", id: contentId, children: failureMessage }) : null
3211
3379
  ] });
3212
3380
  }
3213
3381
  function toolRowLabel(part, separateResource = false) {
@@ -3234,25 +3402,25 @@ function ToolDisclosure({
3234
3402
  renderActivityIcon,
3235
3403
  accessory
3236
3404
  }) {
3237
- const [open, setOpen] = React14.useState(false);
3238
- const contentId = React14.useId();
3239
- const expandable = React14.Children.toArray(children).length > 0;
3405
+ const [open, setOpen] = React15.useState(false);
3406
+ const contentId = React15.useId();
3407
+ const expandable = React15.Children.toArray(children).length > 0;
3240
3408
  if (!expandable) {
3241
3409
  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");
3242
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: cn("a24-tool-trigger-row", root && "a24-tool-trigger-row--root"), children: [
3243
- onSelect && part ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("button", { className: triggerClassName, onClick: () => onSelect(part), type: "button", children: [
3244
- showOrb ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ToolActivityOrb, { label: statusLabel || "Working", kind: grouped ? "group" : "tool", part, renderActivityIcon }) : null,
3245
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "a24-tool-trigger__label", children: label })
3246
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: triggerClassName, children: [
3247
- showOrb ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ToolActivityOrb, { label: statusLabel || "Working", kind: grouped ? "group" : "tool", part, renderActivityIcon }) : null,
3248
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "a24-tool-trigger__label", children: label })
3410
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: cn("a24-tool-trigger-row", root && "a24-tool-trigger-row--root"), children: [
3411
+ onSelect && part ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("button", { className: triggerClassName, onClick: () => onSelect(part), type: "button", children: [
3412
+ showOrb ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ToolActivityOrb, { label: statusLabel || "Working", kind: grouped ? "group" : "tool", part, renderActivityIcon }) : null,
3413
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "a24-tool-trigger__label", children: label })
3414
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: triggerClassName, children: [
3415
+ showOrb ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ToolActivityOrb, { label: statusLabel || "Working", kind: grouped ? "group" : "tool", part, renderActivityIcon }) : null,
3416
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "a24-tool-trigger__label", children: label })
3249
3417
  ] }),
3250
3418
  accessory
3251
3419
  ] });
3252
3420
  }
3253
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "a24-tool-disclosure", children: [
3254
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: cn("a24-tool-trigger-row", root && "a24-tool-trigger-row--root"), children: [
3255
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
3421
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "a24-tool-disclosure", children: [
3422
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: cn("a24-tool-trigger-row", root && "a24-tool-trigger-row--root"), children: [
3423
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
3256
3424
  "button",
3257
3425
  {
3258
3426
  "aria-controls": contentId,
@@ -3266,25 +3434,25 @@ function ToolDisclosure({
3266
3434
  },
3267
3435
  type: "button",
3268
3436
  children: [
3269
- showOrb ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ToolActivityOrb, { label: statusLabel || "Working", kind: grouped ? "group" : "tool", part, renderActivityIcon }) : null,
3270
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "a24-tool-trigger__label", children: label }),
3271
- open ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react8.ChevronDown, { "aria-hidden": "true", className: "a24-tool-trigger__chevron" }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react8.ChevronRight, { "aria-hidden": "true", className: "a24-tool-trigger__chevron" })
3437
+ showOrb ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ToolActivityOrb, { label: statusLabel || "Working", kind: grouped ? "group" : "tool", part, renderActivityIcon }) : null,
3438
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "a24-tool-trigger__label", children: label }),
3439
+ open ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react8.ChevronDown, { "aria-hidden": "true", className: "a24-tool-trigger__chevron" }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react8.ChevronRight, { "aria-hidden": "true", className: "a24-tool-trigger__chevron" })
3272
3440
  ]
3273
3441
  }
3274
3442
  ),
3275
3443
  accessory
3276
3444
  ] }),
3277
- open ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "a24-tool-disclosure__content", id: contentId, children }) : null
3445
+ open ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "a24-tool-disclosure__content", id: contentId, children }) : null
3278
3446
  ] });
3279
3447
  }
3280
3448
  function ToolLabel({ active, label, part, slots }) {
3281
3449
  const rendered = slots?.renderToolLabel?.(toolSlotContext(active, label, part, slots)) ?? label;
3282
- return active ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "a24-tool-shimmer", children: rendered }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_jsx_runtime13.Fragment, { children: rendered });
3450
+ return active ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "a24-tool-shimmer", children: rendered }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_jsx_runtime14.Fragment, { children: rendered });
3283
3451
  }
3284
3452
  function ToolList({ children }) {
3285
- const listRef = React14.useRef(null);
3286
- const [fades, setFades] = React14.useState({ bottom: false, top: false });
3287
- const updateFades = React14.useCallback(() => {
3453
+ const listRef = React15.useRef(null);
3454
+ const [fades, setFades] = React15.useState({ bottom: false, top: false });
3455
+ const updateFades = React15.useCallback(() => {
3288
3456
  const list = listRef.current;
3289
3457
  if (!list) return;
3290
3458
  const next = {
@@ -3293,7 +3461,7 @@ function ToolList({ children }) {
3293
3461
  };
3294
3462
  setFades((current) => current.bottom === next.bottom && current.top === next.top ? current : next);
3295
3463
  }, []);
3296
- React14.useEffect(() => {
3464
+ React15.useEffect(() => {
3297
3465
  updateFades();
3298
3466
  const list = listRef.current;
3299
3467
  if (!list || typeof ResizeObserver === "undefined") return;
@@ -3301,13 +3469,13 @@ function ToolList({ children }) {
3301
3469
  observer.observe(list);
3302
3470
  return () => observer.disconnect();
3303
3471
  }, [children, updateFades]);
3304
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3472
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3305
3473
  "div",
3306
3474
  {
3307
3475
  className: "a24-tool-list-frame",
3308
3476
  "data-scroll-fade-bottom": fades.bottom ? "" : void 0,
3309
3477
  "data-scroll-fade-top": fades.top ? "" : void 0,
3310
- children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "a24-tool-list", onScroll: updateFades, ref: listRef, role: "list", children })
3478
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "a24-tool-list", onScroll: updateFades, ref: listRef, role: "list", children })
3311
3479
  }
3312
3480
  );
3313
3481
  }
@@ -3324,13 +3492,13 @@ function AgentChatToolRow({
3324
3492
  const detail = failed ? failureMessage : optionalText(part.presentation.detail);
3325
3493
  const hostDetails = failed ? null : slots?.renderToolDetails?.(part);
3326
3494
  const context = toolSlotContext(active, toolRowLabel(part, Boolean(slots?.onResourceAction)), part, slots);
3327
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { "data-agents24-tool-part": part.type, "data-state": part.state, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
3495
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { "data-agents24-tool-part": part.type, "data-state": part.state, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
3328
3496
  ToolDisclosure,
3329
3497
  {
3330
3498
  renderActivityIcon: slots?.renderActivityIcon,
3331
3499
  error: failed,
3332
3500
  accessory: toolAccessory(context, slots),
3333
- label: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ToolLabel, { active, label: context.label, part, slots }),
3501
+ label: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ToolLabel, { active, label: context.label, part, slots }),
3334
3502
  loading: active,
3335
3503
  onExpandedChange: slots?.onExpandedChange,
3336
3504
  onSelect: slots?.onToolSelect,
@@ -3339,7 +3507,7 @@ function AgentChatToolRow({
3339
3507
  showOrb: showOrb ?? active,
3340
3508
  statusLabel: active ? context.label : void 0,
3341
3509
  children: [
3342
- detail ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: cn("a24-tool-detail", failed && "a24-tool-detail--error"), children: detail }) : null,
3510
+ detail ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: cn("a24-tool-detail", failed && "a24-tool-detail--error"), children: detail }) : null,
3343
3511
  hostDetails
3344
3512
  ]
3345
3513
  }
@@ -3359,19 +3527,19 @@ function AgentChatToolSession({
3359
3527
  parts,
3360
3528
  slots
3361
3529
  }) {
3362
- const presentedLiveRef = React14.useRef(false);
3530
+ const presentedLiveRef = React15.useRef(false);
3363
3531
  if (isLive && isLatestActivity) presentedLiveRef.current = true;
3364
3532
  const activeIndex = parts.findLastIndex((part) => isActive(part, activeToolId));
3365
3533
  const running = activeIndex >= 0;
3366
- if (parts.length === 1 && !modelTurn && !leadingModelTurn) return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(AgentChatToolRow, { activeToolId, part: parts[0], slots });
3534
+ if (parts.length === 1 && !modelTurn && !leadingModelTurn) return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(AgentChatToolRow, { activeToolId, part: parts[0], slots });
3367
3535
  const visibleIndex = running ? activeIndex : parts.length - 1;
3368
3536
  const visiblePart = parts[visibleIndex];
3369
3537
  const planning = Boolean(modelTurn);
3370
3538
  const presentingActivity = isLatestActivity && (planning || running || isLive);
3371
3539
  const failed = isLatestActivity && (visiblePart.state === "output-error" || visiblePart.state === "cancelled");
3372
3540
  const label = planning ? "Planning next moves" : isLive && isLatestActivity ? toolRowLabel(visiblePart, true) : sessionLabel(parts, visiblePart, running);
3373
- const labelContent = presentedLiveRef.current ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: presentingActivity ? "a24-tool-shimmer" : void 0, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ToolActivityReel, { initialLabel: leadingModelTurn ? "Planning next moves" : void 0, initialShownAt: leadingModelTurn?.timestamp, label }) }) : label;
3374
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3541
+ const labelContent = presentedLiveRef.current ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: presentingActivity ? "a24-tool-shimmer" : void 0, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ToolActivityReel, { initialLabel: leadingModelTurn ? "Planning next moves" : void 0, initialShownAt: leadingModelTurn?.timestamp, label }) }) : label;
3542
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3375
3543
  ToolDisclosure,
3376
3544
  {
3377
3545
  renderActivityIcon: slots?.renderActivityIcon,
@@ -3384,7 +3552,7 @@ function AgentChatToolSession({
3384
3552
  root: true,
3385
3553
  showOrb: isLive && isLatestActivity,
3386
3554
  statusLabel: planning ? "Planning next moves" : label,
3387
- children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ToolList, { children: parts.map((part) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { role: "listitem", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(AgentChatToolRow, { activeToolId, part, root: false, showOrb: false, slots }) }, part.id)) })
3555
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ToolList, { children: parts.map((part) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { role: "listitem", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(AgentChatToolRow, { activeToolId, part, root: false, showOrb: false, slots }) }, part.id)) })
3388
3556
  }
3389
3557
  );
3390
3558
  }
@@ -3405,7 +3573,7 @@ function subagentLabel(part) {
3405
3573
  return { label: `Agent ${name}, ran ${children.length} ${children.length === 1 ? "tool" : "tools"}`, running: false };
3406
3574
  }
3407
3575
  function AgentChatSubagentGroup({ isLatestActivity = true, isLive = false, part, slots }) {
3408
- const presentedLiveRef = React14.useRef(false);
3576
+ const presentedLiveRef = React15.useRef(false);
3409
3577
  if (isLive && isLatestActivity) presentedLiveRef.current = true;
3410
3578
  const children = part.presentation.childTools || [];
3411
3579
  const state = subagentLabel(part);
@@ -3414,9 +3582,9 @@ function AgentChatSubagentGroup({ isLatestActivity = true, isLive = false, part,
3414
3582
  const hostDetails = failed ? null : slots?.renderToolDetails?.(part);
3415
3583
  const failureMessage = part.failure?.message || null;
3416
3584
  const presentingActivity = isLatestActivity && state.running;
3417
- const labelContent = presentedLiveRef.current ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: presentingActivity ? "a24-tool-shimmer" : void 0, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ToolActivityReel, { label: state.label }) }) : state.label;
3585
+ const labelContent = presentedLiveRef.current ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: presentingActivity ? "a24-tool-shimmer" : void 0, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ToolActivityReel, { label: state.label }) }) : state.label;
3418
3586
  const context = toolSlotContext(presentingActivity, state.label, part, slots);
3419
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3587
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3420
3588
  ToolDisclosure,
3421
3589
  {
3422
3590
  renderActivityIcon: slots?.renderActivityIcon,
@@ -3430,12 +3598,12 @@ function AgentChatSubagentGroup({ isLatestActivity = true, isLive = false, part,
3430
3598
  root: true,
3431
3599
  showOrb: isLive && isLatestActivity,
3432
3600
  statusLabel: state.label,
3433
- children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(ToolList, { children: [
3434
- children.map((child) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: cn("a24-child-tool", child.status === "failed" && "a24-child-tool--error"), role: "listitem", children: slots?.renderChildTool?.(child, part) ?? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
3435
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: cn(isLive && isLatestActivity && child.status === "running" && "a24-tool-shimmer"), children: childLabel(child) }),
3436
- child.detail ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "a24-child-tool__detail", children: child.detail }) : null
3601
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(ToolList, { children: [
3602
+ children.map((child) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: cn("a24-child-tool", child.status === "failed" && "a24-child-tool--error"), role: "listitem", children: slots?.renderChildTool?.(child, part) ?? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
3603
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: cn(isLive && isLatestActivity && child.status === "running" && "a24-tool-shimmer"), children: childLabel(child) }),
3604
+ child.detail ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "a24-child-tool__detail", children: child.detail }) : null
3437
3605
  ] }) }, child.id)),
3438
- failureMessage ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "a24-tool-detail a24-tool-detail--error", children: failureMessage }) : null,
3606
+ failureMessage ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "a24-tool-detail a24-tool-detail--error", children: failureMessage }) : null,
3439
3607
  hostDetails
3440
3608
  ] })
3441
3609
  }
@@ -3443,41 +3611,51 @@ function AgentChatSubagentGroup({ isLatestActivity = true, isLive = false, part,
3443
3611
  }
3444
3612
 
3445
3613
  // src/ui/agent-response-timeline.tsx
3446
- var import_jsx_runtime14 = require("react/jsx-runtime");
3614
+ var import_jsx_runtime15 = require("react/jsx-runtime");
3447
3615
  function isInternalAskUserTool(part) {
3448
3616
  return [part.toolName, part.toolKey, part.action].some((value) => value?.trim().toLowerCase() === "runtime__ask_user");
3449
3617
  }
3450
3618
  function Shimmer({ children, className }) {
3451
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: cn("inline-block animate-pulse", className), children });
3619
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: cn("inline-block animate-pulse", className), children });
3452
3620
  }
3453
3621
  function AgentChatToolPart({
3454
3622
  activeToolId,
3455
3623
  part
3456
3624
  }) {
3457
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(AgentChatToolRow, { activeToolId, part });
3625
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(AgentChatToolRow, { activeToolId, part });
3458
3626
  }
3459
3627
  function AgentChatToolGroup({
3460
3628
  activeToolId,
3461
3629
  parts
3462
3630
  }) {
3463
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(AgentChatToolSession, { activeToolId, parts });
3631
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(AgentChatToolSession, { activeToolId, parts });
3464
3632
  }
3465
3633
  function HitlPartRow({
3466
3634
  getHitlActionState,
3635
+ hitlLabels,
3636
+ onHitlPaint,
3467
3637
  isLoading,
3468
3638
  onHitlAction,
3469
3639
  part
3470
3640
  }) {
3471
3641
  const state = getHitlActionState?.(part);
3472
- const [comment, setComment] = React15.useState("");
3642
+ const [comment, setComment] = React16.useState("");
3643
+ const commentRef = React16.useRef(null);
3644
+ const retryActionRef = React16.useRef(null);
3645
+ React16.useEffect(() => {
3646
+ if (state?.status === "error") (commentRef.current || retryActionRef.current)?.focus();
3647
+ }, [state?.status]);
3473
3648
  const presentation = part.presentation || {};
3474
3649
  const requireComment = presentation.require_comment === true;
3475
3650
  const isTerminal = part.status !== "pending";
3476
3651
  if (part.hitlKind === "user_input") {
3477
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3652
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3478
3653
  AskUserInteraction,
3479
3654
  {
3480
3655
  error: state?.error,
3656
+ submission: state,
3657
+ submissionLabels: hitlLabels,
3658
+ onSubmissionPaint: onHitlPaint,
3481
3659
  isBusy: isLoading || state?.status === "resuming",
3482
3660
  onSubmit: onHitlAction ? (answers) => onHitlAction(part, {
3483
3661
  action: "respond",
@@ -3491,12 +3669,14 @@ function HitlPartRow({
3491
3669
  }
3492
3670
  );
3493
3671
  }
3672
+ if (isHitlSubmissionCompact(state)) return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(HitlSubmissionStatus, { state, labels: hitlLabels, onPaint: onHitlPaint });
3494
3673
  if (isTerminal) return null;
3495
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "a24-hitl space-y-2.5 px-1 py-2", children: [
3496
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "a24-hitl__title text-sm font-medium text-foreground text-pretty", children: hitlTitle(part) }),
3497
- requireComment ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3674
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "a24-hitl space-y-2.5 px-1 py-2", children: [
3675
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "a24-hitl__title text-sm font-medium text-foreground text-pretty", children: hitlTitle(part) }),
3676
+ requireComment ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3498
3677
  "textarea",
3499
3678
  {
3679
+ ref: commentRef,
3500
3680
  "aria-label": "Approval comment",
3501
3681
  autoComplete: "off",
3502
3682
  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",
@@ -3506,10 +3686,11 @@ function HitlPartRow({
3506
3686
  value: comment
3507
3687
  }
3508
3688
  ) : null,
3509
- state?.error ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "a24-hitl__error text-sm text-destructive", children: state.error }) : null,
3510
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "a24-hitl__actions flex flex-wrap items-center gap-1.5", children: part.allowedActions.map((action) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3689
+ state?.error ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "a24-hitl__error text-sm text-destructive", children: state.error }) : null,
3690
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "a24-hitl__actions flex flex-wrap items-center gap-1.5", children: part.allowedActions.map((action) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3511
3691
  "button",
3512
3692
  {
3693
+ ref: state?.action === action || !state?.action && action === part.allowedActions[0] ? retryActionRef : void 0,
3513
3694
  "aria-label": hitlActionLabel(part, action),
3514
3695
  className: cn(
3515
3696
  "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",
@@ -3531,6 +3712,8 @@ function HitlPartRow({
3531
3712
  function AgentChatPart({
3532
3713
  activeToolId,
3533
3714
  getHitlActionState,
3715
+ hitlLabels,
3716
+ onHitlPaint,
3534
3717
  isLoading,
3535
3718
  isTextStreaming,
3536
3719
  message,
@@ -3540,7 +3723,7 @@ function AgentChatPart({
3540
3723
  toolSlots
3541
3724
  }) {
3542
3725
  if (part.kind === "text") {
3543
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3726
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3544
3727
  MessageResponse,
3545
3728
  {
3546
3729
  ...responseProps,
@@ -3550,44 +3733,46 @@ function AgentChatPart({
3550
3733
  }
3551
3734
  );
3552
3735
  }
3553
- if (part.kind === "tool") return isAgentChatSubagent(part) ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(AgentChatSubagentGroup, { part, slots: toolSlots }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(AgentChatToolRow, { activeToolId, part, slots: toolSlots });
3554
- if (part.kind === "model-turn") return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(AgentChatModelTurnRow, { part });
3736
+ if (part.kind === "tool") return isAgentChatSubagent(part) ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(AgentChatSubagentGroup, { part, slots: toolSlots }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(AgentChatToolRow, { activeToolId, part, slots: toolSlots });
3737
+ if (part.kind === "model-turn") return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(AgentChatModelTurnRow, { part });
3555
3738
  if (part.kind === "reasoning") {
3556
3739
  const label = part.text || part.label || "Thinking";
3557
- return part.status === "running" || part.status === "streaming" ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Shimmer, { className: "text-sm text-muted-foreground", children: label }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "text-sm text-muted-foreground", children: label });
3740
+ return part.status === "running" || part.status === "streaming" ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Shimmer, { className: "text-sm text-muted-foreground", children: label }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "text-sm text-muted-foreground", children: label });
3558
3741
  }
3559
3742
  if (part.kind === "context-compression") {
3560
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(AgentChatContextCompressionRow, { part });
3743
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(AgentChatContextCompressionRow, { part });
3561
3744
  }
3562
3745
  if (part.kind === "ui-blocks") {
3563
3746
  if (part.state === "output-error") {
3564
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "a24-timeline-error text-sm text-destructive", children: part.errorText || "Failed to render UI content." });
3747
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "a24-timeline-error text-sm text-destructive", children: part.errorText || "Failed to render UI content." });
3565
3748
  }
3566
- return part.bundle ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(SafeUiBlocks, { bundle: part.bundle }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "text-sm text-muted-foreground", children: part.state === "input-streaming" ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Shimmer, { children: "Rendering UI block" }) : "Rendered UI block" });
3749
+ return part.bundle ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(SafeUiBlocks, { bundle: part.bundle }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "text-sm text-muted-foreground", children: part.state === "input-streaming" ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Shimmer, { children: "Rendering UI block" }) : "Rendered UI block" });
3567
3750
  }
3568
3751
  if (part.kind === "hitl") {
3569
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3752
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3570
3753
  HitlPartRow,
3571
3754
  {
3572
3755
  getHitlActionState,
3756
+ hitlLabels,
3757
+ onHitlPaint,
3573
3758
  isLoading,
3574
3759
  onHitlAction,
3575
3760
  part
3576
3761
  }
3577
3762
  );
3578
3763
  }
3579
- if (part.kind === "error") return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "a24-timeline-error text-sm text-destructive", role: "alert", children: part.errorText });
3764
+ if (part.kind === "error") return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "a24-timeline-error text-sm text-destructive", role: "alert", children: part.errorText });
3580
3765
  if (part.kind === "source") {
3581
3766
  const href = safeExternalUrl(part.url);
3582
- return href ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("a", { className: "a24-source-link", href, rel: "noopener noreferrer", target: "_blank", children: part.title }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "a24-source-link", children: part.title });
3767
+ return href ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("a", { className: "a24-source-link", href, rel: "noopener noreferrer", target: "_blank", children: part.title }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "a24-source-link", children: part.title });
3583
3768
  }
3584
3769
  if (part.kind === "citation") {
3585
3770
  const href = safeExternalUrl(part.url);
3586
3771
  const label = part.label || "Citation";
3587
- return href ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("a", { className: "a24-citation", href, rel: "noopener noreferrer", target: "_blank", children: label }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "a24-citation", children: label });
3772
+ return href ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("a", { className: "a24-citation", href, rel: "noopener noreferrer", target: "_blank", children: label }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "a24-citation", children: label });
3588
3773
  }
3589
- if (part.kind === "attachment") return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "a24-output-attachment", children: part.attachment.filename || "Attachment" });
3590
- if (part.kind === "data") return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { "data-agents24-data-part": part.name, className: "hidden", children: message.id });
3774
+ if (part.kind === "attachment") return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "a24-output-attachment", children: part.attachment.filename || "Attachment" });
3775
+ if (part.kind === "data") return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { "data-agents24-data-part": part.name, className: "hidden", children: message.id });
3591
3776
  return null;
3592
3777
  }
3593
3778
  function safeExternalUrl(value) {
@@ -3601,28 +3786,28 @@ function safeExternalUrl(value) {
3601
3786
  }
3602
3787
  function SafeUiBlocks({ bundle }) {
3603
3788
  const rows = Array.isArray(bundle.rows) ? bundle.rows : [];
3604
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("section", { "aria-label": typeof bundle.title === "string" ? bundle.title : "Agent result", className: "a24-ui-blocks", children: [
3605
- typeof bundle.title === "string" ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("h3", { children: bundle.title }) : null,
3789
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("section", { "aria-label": typeof bundle.title === "string" ? bundle.title : "Agent result", className: "a24-ui-blocks", children: [
3790
+ typeof bundle.title === "string" ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("h3", { children: bundle.title }) : null,
3606
3791
  rows.map((rawRow, rowIndex) => {
3607
3792
  const row = rawRow && typeof rawRow === "object" && !Array.isArray(rawRow) ? rawRow : {};
3608
3793
  const blocks = Array.isArray(row.blocks) ? row.blocks : [];
3609
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "a24-ui-blocks__row", children: blocks.map((rawBlock, blockIndex) => {
3794
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "a24-ui-blocks__row", children: blocks.map((rawBlock, blockIndex) => {
3610
3795
  const block = rawBlock && typeof rawBlock === "object" && !Array.isArray(rawBlock) ? rawBlock : {};
3611
3796
  const title = typeof block.title === "string" ? block.title : "Result";
3612
3797
  const kind = String(block.kind || "note");
3613
3798
  if (kind === "table" && Array.isArray(block.columns) && Array.isArray(block.rows)) {
3614
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "a24-ui-block", children: [
3615
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("h4", { children: title }),
3616
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "a24-ui-table-scroll", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("table", { children: [
3617
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("tr", { children: block.columns.map((column, index) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("th", { children: String(column) }, index)) }) }),
3618
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("tbody", { children: block.rows.map((rawCells, index) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("tr", { children: (Array.isArray(rawCells) ? rawCells : []).map((cell, cellIndex) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("td", { children: String(cell) }, cellIndex)) }, index)) })
3799
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "a24-ui-block", children: [
3800
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("h4", { children: title }),
3801
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "a24-ui-table-scroll", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("table", { children: [
3802
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("tr", { children: block.columns.map((column, index) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("th", { children: String(column) }, index)) }) }),
3803
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("tbody", { children: block.rows.map((rawCells, index) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("tr", { children: (Array.isArray(rawCells) ? rawCells : []).map((cell, cellIndex) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("td", { children: String(cell) }, cellIndex)) }, index)) })
3619
3804
  ] }) })
3620
3805
  ] }, String(block.id || blockIndex));
3621
3806
  }
3622
3807
  const value = block.value ?? block.text ?? "";
3623
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "a24-ui-block", children: [
3624
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("h4", { children: title }),
3625
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { children: String(value) })
3808
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "a24-ui-block", children: [
3809
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("h4", { children: title }),
3810
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { children: String(value) })
3626
3811
  ] }, String(block.id || blockIndex));
3627
3812
  }) }, `row-${rowIndex}`);
3628
3813
  })
@@ -3630,6 +3815,8 @@ function SafeUiBlocks({ bundle }) {
3630
3815
  }
3631
3816
  function AgentResponseTimeline({
3632
3817
  getHitlActionState,
3818
+ hitlLabels,
3819
+ onHitlPaint,
3633
3820
  isLoading = false,
3634
3821
  message,
3635
3822
  nodeActivityMode = "default",
@@ -3642,7 +3829,7 @@ function AgentResponseTimeline({
3642
3829
  toolViewMode = "closed"
3643
3830
  }) {
3644
3831
  isLoading = isLoading && !message.responseCompletion;
3645
- 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));
3832
+ 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));
3646
3833
  const toolParts = parts.filter((part) => part.kind === "tool");
3647
3834
  const activeToolId = latestRunningAgentChatToolId(toolParts);
3648
3835
  const activeTextPartId = getActiveStreamingTextPartId(
@@ -3656,42 +3843,44 @@ function AgentResponseTimeline({
3656
3843
  if (segment.kind === "tool") {
3657
3844
  const isLatestActivity = segmentIndex === segments.length - 1;
3658
3845
  const showOrb = toolViewMode === "closed" ? isLoading && isLatestActivity : Boolean(activeToolId && (segment.part.id === activeToolId || segment.part.toolCallId === activeToolId));
3659
- rendered.push(/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(AgentChatToolRow, { activeToolId, part: segment.part, showOrb, slots: toolSlots }, segment.part.id));
3846
+ rendered.push(/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(AgentChatToolRow, { activeToolId, part: segment.part, showOrb, slots: toolSlots }, segment.part.id));
3660
3847
  continue;
3661
3848
  }
3662
3849
  if (segment.kind === "tool-session") {
3663
- rendered.push(/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(AgentChatToolSession, { activeToolId, isLatestActivity: segmentIndex === segments.length - 1, isLive: isLoading, leadingModelTurn: segment.leadingModelTurn, modelTurn: segment.modelTurn, parts: segment.parts, slots: toolSlots }, `tool-session-${segment.parts[0].id}`));
3850
+ rendered.push(/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(AgentChatToolSession, { activeToolId, isLatestActivity: segmentIndex === segments.length - 1, isLive: isLoading, leadingModelTurn: segment.leadingModelTurn, modelTurn: segment.modelTurn, parts: segment.parts, slots: toolSlots }, `tool-session-${segment.parts[0].id}`));
3664
3851
  continue;
3665
3852
  }
3666
3853
  if (segment.kind === "subagent") {
3667
- rendered.push(/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(AgentChatSubagentGroup, { isLatestActivity: segmentIndex === segments.length - 1, isLive: isLoading, part: segment.part, slots: toolSlots }, segment.part.id));
3854
+ rendered.push(/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(AgentChatSubagentGroup, { isLatestActivity: segmentIndex === segments.length - 1, isLive: isLoading, part: segment.part, slots: toolSlots }, segment.part.id));
3668
3855
  continue;
3669
3856
  }
3670
3857
  const part = segment.part;
3671
3858
  if (part.kind === "model-turn") {
3672
3859
  const key = activeActivityClaimed ? part.id : `${message.id}-active-activity`;
3673
3860
  activeActivityClaimed = true;
3674
- rendered.push(/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(AgentChatActivityRow, { renderActivityIcon: toolSlots?.renderActivityIcon, label: "Planning next moves", modelTurnId: part.modelTurnId }, key));
3861
+ rendered.push(/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(AgentChatActivityRow, { renderActivityIcon: toolSlots?.renderActivityIcon, label: "Planning next moves", modelTurnId: part.modelTurnId }, key));
3675
3862
  continue;
3676
3863
  }
3677
3864
  if (part.kind === "node-activity") {
3678
3865
  const key = activeActivityClaimed ? part.id : `${message.id}-active-activity`;
3679
3866
  if (part.status === "running") activeActivityClaimed = true;
3680
3867
  rendered.push(
3681
- part.status === "running" ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(AgentChatActivityRow, { renderActivityIcon: toolSlots?.renderActivityIcon, label: part.label, onSelect: onNodeSelect ? () => onNodeSelect(part) : void 0 }, key) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(AgentChatNodeActivityRow, { renderActivityIcon: toolSlots?.renderActivityIcon, onSelect: onNodeSelect, part }, part.id)
3868
+ part.status === "running" ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(AgentChatActivityRow, { renderActivityIcon: toolSlots?.renderActivityIcon, label: part.label, onSelect: onNodeSelect ? () => onNodeSelect(part) : void 0 }, key) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(AgentChatNodeActivityRow, { renderActivityIcon: toolSlots?.renderActivityIcon, onSelect: onNodeSelect, part }, part.id)
3682
3869
  );
3683
3870
  continue;
3684
3871
  }
3685
3872
  if (part.kind === "ui-blocks" && renderUiBlocks) {
3686
- rendered.push(/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(React15.Fragment, { children: renderUiBlocks(part) }, part.id));
3873
+ rendered.push(/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(React16.Fragment, { children: renderUiBlocks(part) }, part.id));
3687
3874
  continue;
3688
3875
  }
3689
3876
  rendered.push(
3690
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(React15.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3877
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(React16.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3691
3878
  AgentChatPart,
3692
3879
  {
3693
3880
  activeToolId,
3694
3881
  getHitlActionState,
3882
+ hitlLabels,
3883
+ onHitlPaint,
3695
3884
  isLoading,
3696
3885
  isTextStreaming: part.kind === "text" && part.id === activeTextPartId,
3697
3886
  message,
@@ -3704,16 +3893,16 @@ function AgentResponseTimeline({
3704
3893
  );
3705
3894
  }
3706
3895
  if (rendered.length === 0 && message.content) {
3707
- rendered.push(/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(MessageResponse, { children: message.content }, `${message.id}-fallback`));
3896
+ rendered.push(/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(MessageResponse, { children: message.content }, `${message.id}-fallback`));
3708
3897
  }
3709
3898
  if (rendered.length === 0 && isLoading) {
3710
- rendered.push(/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(AgentChatActivityRow, { renderActivityIcon: toolSlots?.renderActivityIcon, label: "Thinking" }, `${message.id}-active-activity`));
3899
+ rendered.push(/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(AgentChatActivityRow, { renderActivityIcon: toolSlots?.renderActivityIcon, label: "Thinking" }, `${message.id}-active-activity`));
3711
3900
  }
3712
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "space-y-3", children: rendered });
3901
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "space-y-3", children: rendered });
3713
3902
  }
3714
3903
 
3715
3904
  // src/ui/agent-chat-message.tsx
3716
- var import_jsx_runtime15 = require("react/jsx-runtime");
3905
+ var import_jsx_runtime16 = require("react/jsx-runtime");
3717
3906
  var DEFAULT_USER_MESSAGE_COLLAPSE_THRESHOLD = 360;
3718
3907
  var DEFAULT_USER_MESSAGE_COLLAPSED_LINES = 4;
3719
3908
  function shouldCollapseUserMessage(content, threshold = DEFAULT_USER_MESSAGE_COLLAPSE_THRESHOLD) {
@@ -3726,8 +3915,8 @@ function AgentChatUserMessageContent({
3726
3915
  showLessLabel = "Show less",
3727
3916
  showMoreLabel = "Show more"
3728
3917
  }) {
3729
- const [isExpanded, setIsExpanded] = React16.useState(false);
3730
- const contentId = React16.useId();
3918
+ const [isExpanded, setIsExpanded] = React17.useState(false);
3919
+ const contentId = React17.useId();
3731
3920
  const shouldCollapse = shouldCollapseUserMessage(content, collapseThreshold);
3732
3921
  const Icon = isExpanded ? import_lucide_react9.ChevronUp : import_lucide_react9.ChevronDown;
3733
3922
  const clampedStyle = shouldCollapse && !isExpanded ? {
@@ -3736,9 +3925,9 @@ function AgentChatUserMessageContent({
3736
3925
  display: "-webkit-box",
3737
3926
  overflow: "hidden"
3738
3927
  } : void 0;
3739
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex min-w-0 flex-col gap-3", children: [
3740
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { id: contentId, className: "min-w-0", style: clampedStyle, children: content }),
3741
- shouldCollapse ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
3928
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex min-w-0 flex-col gap-3", children: [
3929
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { id: contentId, className: "min-w-0", style: clampedStyle, children: content }),
3930
+ shouldCollapse ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
3742
3931
  "button",
3743
3932
  {
3744
3933
  "aria-controls": contentId,
@@ -3751,7 +3940,7 @@ function AgentChatUserMessageContent({
3751
3940
  type: "button",
3752
3941
  children: [
3753
3942
  isExpanded ? showLessLabel : showMoreLabel,
3754
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Icon, { "aria-hidden": "true", className: "size-4", strokeWidth: 2 })
3943
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Icon, { "aria-hidden": "true", className: "size-4", strokeWidth: 2 })
3755
3944
  ]
3756
3945
  }
3757
3946
  ) : null
@@ -3761,9 +3950,9 @@ function AgentChatUserMessageActionRow({
3761
3950
  children,
3762
3951
  className
3763
3952
  }) {
3764
- const rowRef = React16.useRef(null);
3765
- const [visible, setVisible] = React16.useState(false);
3766
- React16.useEffect(() => {
3953
+ const rowRef = React17.useRef(null);
3954
+ const [visible, setVisible] = React17.useState(false);
3955
+ React17.useEffect(() => {
3767
3956
  const message = rowRef.current?.closest('[data-slot="message"]');
3768
3957
  if (!message) return;
3769
3958
  const show = () => setVisible(true);
@@ -3782,7 +3971,7 @@ function AgentChatUserMessageActionRow({
3782
3971
  message.removeEventListener("focusout", hideWhenFocusLeaves);
3783
3972
  };
3784
3973
  }, []);
3785
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3974
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3786
3975
  "div",
3787
3976
  {
3788
3977
  ref: rowRef,
@@ -3802,6 +3991,8 @@ function AgentChatMessage({
3802
3991
  contentClassName,
3803
3992
  dir,
3804
3993
  getHitlActionState,
3994
+ hitlLabels,
3995
+ onHitlPaint,
3805
3996
  message,
3806
3997
  nodeActivityMode,
3807
3998
  onHitlAction,
@@ -3821,7 +4012,7 @@ function AgentChatMessage({
3821
4012
  const resolvedUserContent = userMessageContent ?? message.content;
3822
4013
  const shouldRenderContent = isAssistant || Boolean(renderUserContent || resolvedUserContent);
3823
4014
  const showAttachments = Boolean(message.attachments?.length) && (message.role === "user" || showAssistantAttachments);
3824
- const renderedActions = actions ?? (actionHandlers ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
4015
+ const renderedActions = actions ?? (actionHandlers ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3825
4016
  AgentChatDefaultActions,
3826
4017
  {
3827
4018
  additionalActions,
@@ -3831,14 +4022,14 @@ function AgentChatMessage({
3831
4022
  }
3832
4023
  ) : null);
3833
4024
  const defaultUserActions = !actions && Boolean(actionHandlers) && !isAssistant;
3834
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
4025
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
3835
4026
  ChatMessage,
3836
4027
  {
3837
4028
  className,
3838
4029
  dir,
3839
4030
  from: message.role,
3840
4031
  children: [
3841
- showAttachments ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
4032
+ showAttachments ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3842
4033
  ChatAttachmentRows,
3843
4034
  {
3844
4035
  attachments: message.attachments || [],
@@ -3847,17 +4038,19 @@ function AgentChatMessage({
3847
4038
  resolveContent: attachmentContentResolver
3848
4039
  }
3849
4040
  ) : null,
3850
- shouldRenderContent ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
4041
+ shouldRenderContent ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
3851
4042
  ChatMessageContent,
3852
4043
  {
3853
4044
  className: cn(isAssistant ? "bg-transparent p-0" : void 0, contentClassName),
3854
4045
  dir,
3855
4046
  from: message.role,
3856
4047
  children: [
3857
- isAssistant ? renderAssistantContent ? renderAssistantContent({ isStreaming, message }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
4048
+ isAssistant ? renderAssistantContent ? renderAssistantContent({ isStreaming, message }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3858
4049
  Timeline,
3859
4050
  {
3860
4051
  getHitlActionState,
4052
+ hitlLabels,
4053
+ onHitlPaint,
3861
4054
  isLoading: isStreaming,
3862
4055
  message,
3863
4056
  nodeActivityMode,
@@ -3865,7 +4058,7 @@ function AgentChatMessage({
3865
4058
  parts: message.parts
3866
4059
  }
3867
4060
  ) : null,
3868
- !isAssistant ? renderUserContent ? renderUserContent({ message }) : resolvedUserContent ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
4061
+ !isAssistant ? renderUserContent ? renderUserContent({ message }) : resolvedUserContent ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3869
4062
  AgentChatUserMessageContent,
3870
4063
  {
3871
4064
  collapsedLines: userMessageCollapsedLines,
@@ -3878,7 +4071,11 @@ function AgentChatMessage({
3878
4071
  ]
3879
4072
  }
3880
4073
  ) : null,
3881
- renderedActions ? defaultUserActions ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(AgentChatUserMessageActionRow, { className: actionsClassName, children: renderedActions }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: cn(dir === "rtl" ? "mt-1 h-9 w-full" : "mt-1 h-9 w-full -translate-x-2", actionsClassName), children: renderedActions }) : null
4074
+ renderedActions ? defaultUserActions ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(AgentChatUserMessageActionRow, { className: actionsClassName, children: renderedActions }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: cn(
4075
+ dir === "rtl" ? "mt-1 h-9 w-full" : "mt-1 h-9 w-full -translate-x-2",
4076
+ isAssistant && "a24-chat-message-action-row--assistant",
4077
+ actionsClassName
4078
+ ), children: renderedActions }) : null
3882
4079
  ]
3883
4080
  }
3884
4081
  );
@@ -3887,9 +4084,9 @@ function AgentChatMessage({
3887
4084
  // src/ui/bubble.tsx
3888
4085
  var import_class_variance_authority3 = require("class-variance-authority");
3889
4086
  var import_react_slot2 = require("@radix-ui/react-slot");
3890
- var import_jsx_runtime16 = require("react/jsx-runtime");
4087
+ var import_jsx_runtime17 = require("react/jsx-runtime");
3891
4088
  function BubbleGroup({ className, ...props }) {
3892
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
4089
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3893
4090
  "div",
3894
4091
  {
3895
4092
  "data-slot": "bubble-group",
@@ -3923,7 +4120,7 @@ function Bubble({
3923
4120
  className,
3924
4121
  ...props
3925
4122
  }) {
3926
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
4123
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3927
4124
  "div",
3928
4125
  {
3929
4126
  "data-slot": "bubble",
@@ -3940,7 +4137,7 @@ function BubbleContent({
3940
4137
  ...props
3941
4138
  }) {
3942
4139
  const Comp = asChild ? import_react_slot2.Slot : "div";
3943
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
4140
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3944
4141
  Comp,
3945
4142
  {
3946
4143
  "data-slot": "bubble-content",
@@ -3977,7 +4174,7 @@ function BubbleReactions({
3977
4174
  className,
3978
4175
  ...props
3979
4176
  }) {
3980
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
4177
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3981
4178
  "div",
3982
4179
  {
3983
4180
  "data-slot": "bubble-reactions",
@@ -3992,7 +4189,7 @@ function BubbleReactions({
3992
4189
  // src/ui/marker.tsx
3993
4190
  var import_class_variance_authority4 = require("class-variance-authority");
3994
4191
  var import_react_slot3 = require("@radix-ui/react-slot");
3995
- var import_jsx_runtime17 = require("react/jsx-runtime");
4192
+ var import_jsx_runtime18 = require("react/jsx-runtime");
3996
4193
  var markerVariants = (0, import_class_variance_authority4.cva)(
3997
4194
  "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",
3998
4195
  {
@@ -4012,7 +4209,7 @@ function Marker({
4012
4209
  ...props
4013
4210
  }) {
4014
4211
  const Comp = asChild ? import_react_slot3.Slot : "div";
4015
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
4212
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
4016
4213
  Comp,
4017
4214
  {
4018
4215
  "data-slot": "marker",
@@ -4023,7 +4220,7 @@ function Marker({
4023
4220
  );
4024
4221
  }
4025
4222
  function MarkerIcon({ className, ...props }) {
4026
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
4223
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
4027
4224
  "span",
4028
4225
  {
4029
4226
  "data-slot": "marker-icon",
@@ -4037,7 +4234,7 @@ function MarkerIcon({ className, ...props }) {
4037
4234
  );
4038
4235
  }
4039
4236
  function MarkerContent({ className, ...props }) {
4040
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
4237
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
4041
4238
  "span",
4042
4239
  {
4043
4240
  "data-slot": "marker-content",
@@ -4051,7 +4248,7 @@ function MarkerContent({ className, ...props }) {
4051
4248
  }
4052
4249
 
4053
4250
  // src/ui/mcp-connect-required-card.tsx
4054
- var import_jsx_runtime18 = require("react/jsx-runtime");
4251
+ var import_jsx_runtime19 = require("react/jsx-runtime");
4055
4252
  var STATUS_LABELS = {
4056
4253
  pending: "Connect",
4057
4254
  connecting: "Connecting",
@@ -4075,7 +4272,7 @@ function McpConnectRequiredCard({
4075
4272
  const isBusy = loading || status === "connecting" || status === "resuming";
4076
4273
  const isConnected = status === "connected";
4077
4274
  const buttonDisabled = disabled || isBusy || isConnected || !onConnect;
4078
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
4275
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4079
4276
  "div",
4080
4277
  {
4081
4278
  "data-agents24-mcp-connect-card": true,
@@ -4085,13 +4282,13 @@ function McpConnectRequiredCard({
4085
4282
  className
4086
4283
  ),
4087
4284
  ...props,
4088
- children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex min-w-0 items-start justify-between gap-3", children: [
4089
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "min-w-0", children: [
4090
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "truncate text-sm font-medium", children: label }),
4091
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "mt-1 text-sm text-muted-foreground", children: message || "Connect your account to continue." }),
4092
- status === "error" && error ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "mt-2 text-sm text-destructive", children: error }) : null
4285
+ children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex min-w-0 items-start justify-between gap-3", children: [
4286
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "min-w-0", children: [
4287
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "truncate text-sm font-medium", children: label }),
4288
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "mt-1 text-sm text-muted-foreground", children: message || "Connect your account to continue." }),
4289
+ status === "error" && error ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "mt-2 text-sm text-destructive", children: error }) : null
4093
4290
  ] }),
4094
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
4291
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4095
4292
  "button",
4096
4293
  {
4097
4294
  type: "button",
@@ -4159,6 +4356,7 @@ function McpConnectRequiredCard({
4159
4356
  CodeBlockLine,
4160
4357
  CodeBlockTitle,
4161
4358
  CodeBlockWrapButton,
4359
+ HitlSubmissionStatus,
4162
4360
  Marker,
4163
4361
  MarkerContent,
4164
4362
  MarkerIcon,
@@ -4185,10 +4383,12 @@ function McpConnectRequiredCard({
4185
4383
  cn,
4186
4384
  contextStatusMetrics,
4187
4385
  createAgentChatComposerFile,
4386
+ defaultHitlSubmissionLabels,
4188
4387
  hitlActionLabel,
4189
4388
  hitlTitle,
4190
4389
  isAgentChatSubagent,
4191
4390
  isAgentChatToolRunning,
4391
+ isHitlSubmissionCompact,
4192
4392
  latestRunningAgentChatToolId,
4193
4393
  markerVariants,
4194
4394
  partitionAgentChatToolTimeline,