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