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