@paymanai/payman-ask-sdk 4.0.20 → 4.0.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +26 -93
- package/dist/index.d.ts +26 -93
- package/dist/index.js +389 -1734
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +392 -1726
- package/dist/index.mjs.map +1 -1
- package/dist/index.native.js +3703 -0
- package/dist/index.native.js.map +1 -0
- package/dist/styles.css +28 -486
- package/dist/styles.css.map +1 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { createContext, forwardRef, useCallback, useRef, useState,
|
|
1
|
+
import { createContext, forwardRef, useCallback, useRef, useState, useMemo, useEffect, useImperativeHandle, useLayoutEffect, useContext } from 'react';
|
|
2
2
|
import { AnimatePresence, motion } from 'framer-motion';
|
|
3
3
|
import { clsx } from 'clsx';
|
|
4
4
|
import { twMerge } from 'tailwind-merge';
|
|
5
5
|
import * as Sentry from '@sentry/react';
|
|
6
|
-
import { ArrowDown,
|
|
6
|
+
import { ArrowDown, Pencil, X, RotateCcw, Telescope, Zap, Plus, ImagePlus, Paperclip, Mic, ArrowUp, Check, AlertCircle, Copy, WifiOff, ThumbsUp, ThumbsDown, Binoculars, Info, Download, Loader2, ChevronDown, User, Clock, Sparkles, ImageOff, Eye, ChevronRight, ShieldCheck } from 'lucide-react';
|
|
7
7
|
import ReactMarkdown from 'react-markdown';
|
|
8
8
|
import remarkGfm from 'remark-gfm';
|
|
9
9
|
import { createPortal } from 'react-dom';
|
|
@@ -13,10 +13,7 @@ import { DotLottieReact } from '@lottiefiles/dotlottie-react';
|
|
|
13
13
|
|
|
14
14
|
var __defProp = Object.defineProperty;
|
|
15
15
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
16
|
-
var __publicField = (obj, key, value) => __defNormalProp(obj,
|
|
17
|
-
var __defProp2 = Object.defineProperty;
|
|
18
|
-
var __defNormalProp2 = (obj, key, value) => key in obj ? __defProp2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
19
|
-
var __publicField2 = (obj, key, value) => __defNormalProp2(obj, key + "", value);
|
|
16
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, key + "", value);
|
|
20
17
|
function generateId() {
|
|
21
18
|
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
|
|
22
19
|
const r = Math.random() * 16 | 0;
|
|
@@ -712,8 +709,7 @@ function buildRequestBody(config, userMessage, sessionId, options) {
|
|
|
712
709
|
sessionAttributes,
|
|
713
710
|
analysisMode: options?.analysisMode,
|
|
714
711
|
locale: resolveLocale(config.locale),
|
|
715
|
-
timezone: resolveTimezone(config.timezone)
|
|
716
|
-
...options?.attachments?.length ? { attachments: options.attachments } : {}
|
|
712
|
+
timezone: resolveTimezone(config.timezone)
|
|
717
713
|
};
|
|
718
714
|
}
|
|
719
715
|
function resolveLocale(configured) {
|
|
@@ -758,7 +754,6 @@ function buildResolveImagesUrl(config) {
|
|
|
758
754
|
const basePath = normalizedEndpointPath.endsWith("/stream") ? normalizedEndpointPath.slice(0, -"/stream".length) : normalizedEndpointPath;
|
|
759
755
|
return `${config.api.baseUrl}${basePath}/resolve-image-urls`;
|
|
760
756
|
}
|
|
761
|
-
var NGROK_SKIP_BROWSER_WARNING = "ngrok-skip-browser-warning";
|
|
762
757
|
function buildRequestHeaders(config) {
|
|
763
758
|
const headers = {
|
|
764
759
|
...config.api.headers
|
|
@@ -766,9 +761,6 @@ function buildRequestHeaders(config) {
|
|
|
766
761
|
if (config.api.authToken) {
|
|
767
762
|
headers.Authorization = `Bearer ${config.api.authToken}`;
|
|
768
763
|
}
|
|
769
|
-
if (!headers[NGROK_SKIP_BROWSER_WARNING]) {
|
|
770
|
-
headers[NGROK_SKIP_BROWSER_WARNING] = "true";
|
|
771
|
-
}
|
|
772
764
|
return headers;
|
|
773
765
|
}
|
|
774
766
|
var RAG_IMAGE_REGEX = /\/api\/rag\/chunks\/[^"'\s]+\/image/;
|
|
@@ -1049,85 +1041,10 @@ function createCancelledMessageUpdate(steps, currentMessage) {
|
|
|
1049
1041
|
currentMessage: currentMessage || "Thinking..."
|
|
1050
1042
|
};
|
|
1051
1043
|
}
|
|
1052
|
-
var DEFAULT_SIGNED_URL_ENDPOINT = "/api/files/signed-url";
|
|
1053
|
-
function fileExtension(filename) {
|
|
1054
|
-
const ext = filename.split(".").pop()?.toLowerCase().replace(/^\./, "");
|
|
1055
|
-
return ext && ext.length > 0 ? ext : "bin";
|
|
1056
|
-
}
|
|
1057
|
-
function resolveMimeType(file) {
|
|
1058
|
-
if (file.type && file.type.trim().length > 0) return file.type;
|
|
1059
|
-
const ext = fileExtension(file.name);
|
|
1060
|
-
const byExt = {
|
|
1061
|
-
pdf: "application/pdf",
|
|
1062
|
-
png: "image/png",
|
|
1063
|
-
jpg: "image/jpeg",
|
|
1064
|
-
jpeg: "image/jpeg",
|
|
1065
|
-
gif: "image/gif",
|
|
1066
|
-
webp: "image/webp"
|
|
1067
|
-
};
|
|
1068
|
-
return byExt[ext] ?? "application/octet-stream";
|
|
1069
|
-
}
|
|
1070
|
-
function buildSignedUrlEndpoint(config, ext) {
|
|
1071
|
-
const endpoint = config.api.signedUrlEndpoint || DEFAULT_SIGNED_URL_ENDPOINT;
|
|
1072
|
-
const queryParams = new URLSearchParams({ extn: ext.replace(/^\./, "") });
|
|
1073
|
-
return `${config.api.baseUrl}${endpoint}?${queryParams.toString()}`;
|
|
1074
|
-
}
|
|
1075
|
-
async function requestSignedUrl(config, ext, signal) {
|
|
1076
|
-
const url = buildSignedUrlEndpoint(config, ext);
|
|
1077
|
-
const headers = buildRequestHeaders(config);
|
|
1078
|
-
const response = await fetch(url, {
|
|
1079
|
-
method: "GET",
|
|
1080
|
-
headers,
|
|
1081
|
-
signal
|
|
1082
|
-
});
|
|
1083
|
-
if (!response.ok) {
|
|
1084
|
-
const errorText = await response.text().catch(() => "");
|
|
1085
|
-
throw new Error(
|
|
1086
|
-
errorText ? `Failed to get upload URL (${response.status}): ${errorText}` : `Failed to get upload URL (${response.status})`
|
|
1087
|
-
);
|
|
1088
|
-
}
|
|
1089
|
-
const data = await response.json();
|
|
1090
|
-
if (!data.key || !data.url) {
|
|
1091
|
-
throw new Error("Signed URL response missing key or url");
|
|
1092
|
-
}
|
|
1093
|
-
return { key: data.key, url: data.url };
|
|
1094
|
-
}
|
|
1095
|
-
async function uploadToSignedUrl(signedUrl, file, mimeType, signal) {
|
|
1096
|
-
const response = await fetch(signedUrl, {
|
|
1097
|
-
method: "PUT",
|
|
1098
|
-
headers: {
|
|
1099
|
-
"Content-Type": mimeType,
|
|
1100
|
-
"x-ms-blob-type": "BlockBlob"
|
|
1101
|
-
},
|
|
1102
|
-
body: file,
|
|
1103
|
-
signal
|
|
1104
|
-
});
|
|
1105
|
-
if (!response.ok) {
|
|
1106
|
-
const errorText = await response.text().catch(() => "");
|
|
1107
|
-
throw new Error(
|
|
1108
|
-
errorText ? `Failed to upload file (${response.status}): ${errorText}` : `Failed to upload file (${response.status})`
|
|
1109
|
-
);
|
|
1110
|
-
}
|
|
1111
|
-
}
|
|
1112
|
-
async function uploadAttachment(config, file, signal) {
|
|
1113
|
-
const ext = fileExtension(file.name);
|
|
1114
|
-
const mimeType = resolveMimeType(file);
|
|
1115
|
-
const { key, url } = await requestSignedUrl(config, ext, signal);
|
|
1116
|
-
await uploadToSignedUrl(url, file, mimeType, signal);
|
|
1117
|
-
return {
|
|
1118
|
-
tempKey: key,
|
|
1119
|
-
filename: file.name,
|
|
1120
|
-
mimeType
|
|
1121
|
-
};
|
|
1122
|
-
}
|
|
1123
|
-
async function uploadAttachments(config, files, signal) {
|
|
1124
|
-
const uploads = files.map((file) => uploadAttachment(config, file, signal));
|
|
1125
|
-
return Promise.all(uploads);
|
|
1126
|
-
}
|
|
1127
1044
|
var UserActionStaleError = class extends Error {
|
|
1128
1045
|
constructor(userActionId, message = "User action is no longer actionable") {
|
|
1129
1046
|
super(message);
|
|
1130
|
-
|
|
1047
|
+
__publicField(this, "userActionId");
|
|
1131
1048
|
this.name = "UserActionStaleError";
|
|
1132
1049
|
this.userActionId = userActionId;
|
|
1133
1050
|
}
|
|
@@ -1160,6 +1077,9 @@ async function cancelUserAction(config, userActionId) {
|
|
|
1160
1077
|
async function resendUserAction(config, userActionId) {
|
|
1161
1078
|
return sendUserActionRequest(config, userActionId, "resend");
|
|
1162
1079
|
}
|
|
1080
|
+
async function expireUserAction(config, userActionId) {
|
|
1081
|
+
return sendUserActionRequest(config, userActionId, "expired");
|
|
1082
|
+
}
|
|
1163
1083
|
var EMPTY_USER_ACTION_STATE = { prompts: [], notifications: [] };
|
|
1164
1084
|
function upsertPrompt(prompts, req) {
|
|
1165
1085
|
const active = { ...req, status: "pending" };
|
|
@@ -1188,32 +1108,12 @@ function getStoredOrInitialMessages(config) {
|
|
|
1188
1108
|
function getSessionIdFromMessages(messages) {
|
|
1189
1109
|
return messages.find((message) => message.sessionId)?.sessionId;
|
|
1190
1110
|
}
|
|
1191
|
-
var IMAGE_EXTENSIONS = /* @__PURE__ */ new Set(["jpg", "jpeg", "png", "gif", "webp", "avif"]);
|
|
1192
|
-
function attachmentKindFromFile(file) {
|
|
1193
|
-
const ext = file.name.split(".").pop()?.toLowerCase() ?? "";
|
|
1194
|
-
if (IMAGE_EXTENSIONS.has(ext) || file.type.startsWith("image/")) return "image";
|
|
1195
|
-
return "file";
|
|
1196
|
-
}
|
|
1197
|
-
function buildMessageAttachments(files) {
|
|
1198
|
-
return files.map((file, index) => {
|
|
1199
|
-
const kind = attachmentKindFromFile(file);
|
|
1200
|
-
return {
|
|
1201
|
-
id: `att-${Date.now()}-${index}`,
|
|
1202
|
-
filename: file.name,
|
|
1203
|
-
mimeType: file.type || "application/octet-stream",
|
|
1204
|
-
// Blob URL for all local files so PDFs/docs stay previewable after send.
|
|
1205
|
-
previewUrl: URL.createObjectURL(file),
|
|
1206
|
-
kind
|
|
1207
|
-
};
|
|
1208
|
-
});
|
|
1209
|
-
}
|
|
1210
1111
|
function useChatV2(config, callbacks = {}) {
|
|
1211
1112
|
const [messages, setMessages] = useState(() => getStoredOrInitialMessages(config));
|
|
1212
1113
|
const [isWaitingForResponse, setIsWaitingForResponse] = useState(() => {
|
|
1213
1114
|
if (!config.userId) return false;
|
|
1214
1115
|
return activeStreamStore.get(config.userId)?.isWaiting ?? false;
|
|
1215
1116
|
});
|
|
1216
|
-
const [isUploadingAttachments, setIsUploadingAttachments] = useState(false);
|
|
1217
1117
|
const sessionIdRef = useRef(
|
|
1218
1118
|
getSessionIdFromMessages(getStoredOrInitialMessages(config)) ?? config.initialSessionId ?? void 0
|
|
1219
1119
|
);
|
|
@@ -1288,45 +1188,21 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1288
1188
|
);
|
|
1289
1189
|
const sendMessage = useCallback(
|
|
1290
1190
|
async (userMessage, options) => {
|
|
1291
|
-
|
|
1292
|
-
const files = options?.files ?? [];
|
|
1293
|
-
const hasPreuploadedAttachments = (options?.attachments?.length ?? 0) > 0;
|
|
1294
|
-
if (!trimmedMessage && files.length === 0 && !hasPreuploadedAttachments) return;
|
|
1295
|
-
let streamAttachments = options?.attachments;
|
|
1296
|
-
if (!streamAttachments && files.length > 0) {
|
|
1297
|
-
setIsUploadingAttachments(true);
|
|
1298
|
-
try {
|
|
1299
|
-
streamAttachments = await uploadAttachments(configRef.current, files);
|
|
1300
|
-
} catch (error) {
|
|
1301
|
-
if (error.name !== "AbortError") {
|
|
1302
|
-
callbacksRef.current.onError?.(error);
|
|
1303
|
-
}
|
|
1304
|
-
throw error;
|
|
1305
|
-
} finally {
|
|
1306
|
-
setIsUploadingAttachments(false);
|
|
1307
|
-
}
|
|
1308
|
-
}
|
|
1191
|
+
if (!userMessage.trim()) return;
|
|
1309
1192
|
if (!sessionIdRef.current && configRef.current.autoGenerateSessionId !== false) {
|
|
1310
1193
|
sessionIdRef.current = generateId();
|
|
1311
1194
|
callbacksRef.current.onSessionIdChange?.(sessionIdRef.current);
|
|
1312
1195
|
}
|
|
1313
|
-
const messageAttachments = files.length > 0 ? buildMessageAttachments(files) : streamAttachments?.length ? streamAttachments.map((attachment, index) => ({
|
|
1314
|
-
id: `att-${Date.now()}-${index}`,
|
|
1315
|
-
filename: attachment.filename,
|
|
1316
|
-
mimeType: attachment.mimeType,
|
|
1317
|
-
kind: attachment.mimeType.startsWith("image/") ? "image" : "file"
|
|
1318
|
-
})) : void 0;
|
|
1319
1196
|
const userMessageId = `user-${Date.now()}`;
|
|
1320
1197
|
const userMsg = {
|
|
1321
1198
|
id: userMessageId,
|
|
1322
1199
|
sessionId: sessionIdRef.current,
|
|
1323
1200
|
role: "user",
|
|
1324
|
-
content:
|
|
1325
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1326
|
-
attachments: messageAttachments
|
|
1201
|
+
content: userMessage,
|
|
1202
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1327
1203
|
};
|
|
1328
1204
|
setMessages((prev) => [...prev, userMsg]);
|
|
1329
|
-
callbacksRef.current.onMessageSent?.(
|
|
1205
|
+
callbacksRef.current.onMessageSent?.(userMessage);
|
|
1330
1206
|
setIsWaitingForResponse(true);
|
|
1331
1207
|
callbacksRef.current.onStreamStart?.();
|
|
1332
1208
|
const streamingId = `assistant-${Date.now()}`;
|
|
@@ -1353,14 +1229,11 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1353
1229
|
activeStreamStore.start(userId, abortController, initialMessages);
|
|
1354
1230
|
}
|
|
1355
1231
|
const newSessionId = await startStream(
|
|
1356
|
-
|
|
1232
|
+
userMessage,
|
|
1357
1233
|
streamingId,
|
|
1358
1234
|
sessionIdRef.current,
|
|
1359
1235
|
abortController,
|
|
1360
|
-
|
|
1361
|
-
analysisMode: options?.analysisMode,
|
|
1362
|
-
attachments: streamAttachments
|
|
1363
|
-
}
|
|
1236
|
+
options
|
|
1364
1237
|
);
|
|
1365
1238
|
const finalStreamUserId = streamUserIdRef.current ?? userId;
|
|
1366
1239
|
if (finalStreamUserId) {
|
|
@@ -1498,6 +1371,19 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1498
1371
|
},
|
|
1499
1372
|
[setPromptStatus]
|
|
1500
1373
|
);
|
|
1374
|
+
const expireUserAction2 = useCallback(
|
|
1375
|
+
async (userActionId) => {
|
|
1376
|
+
setPromptStatus(userActionId, "expired");
|
|
1377
|
+
try {
|
|
1378
|
+
await expireUserAction(configRef.current, userActionId);
|
|
1379
|
+
} catch (error) {
|
|
1380
|
+
if (error instanceof UserActionStaleError) return;
|
|
1381
|
+
callbacksRef.current.onError?.(error);
|
|
1382
|
+
throw error;
|
|
1383
|
+
}
|
|
1384
|
+
},
|
|
1385
|
+
[setPromptStatus]
|
|
1386
|
+
);
|
|
1501
1387
|
const dismissNotification = useCallback((id) => {
|
|
1502
1388
|
setUserActionState((prev) => ({
|
|
1503
1389
|
...prev,
|
|
@@ -1538,18 +1424,6 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1538
1424
|
setMessages(config.initialMessages);
|
|
1539
1425
|
sessionIdRef.current = getSessionIdFromMessages(config.initialMessages) ?? config.initialSessionId;
|
|
1540
1426
|
}, [config.initialMessages, config.initialSessionId, config.userId]);
|
|
1541
|
-
const hydratedSessionIdRef = useRef(void 0);
|
|
1542
|
-
useEffect(() => {
|
|
1543
|
-
if (config.userId) return;
|
|
1544
|
-
if (!config.initialMessages?.length) return;
|
|
1545
|
-
const sessionId = config.initialSessionId;
|
|
1546
|
-
if (hydratedSessionIdRef.current === sessionId && messagesRef.current.length > 0) {
|
|
1547
|
-
return;
|
|
1548
|
-
}
|
|
1549
|
-
hydratedSessionIdRef.current = sessionId;
|
|
1550
|
-
setMessages(config.initialMessages);
|
|
1551
|
-
sessionIdRef.current = getSessionIdFromMessages(config.initialMessages) ?? sessionId;
|
|
1552
|
-
}, [config.initialMessages, config.initialSessionId, config.userId]);
|
|
1553
1427
|
useEffect(() => {
|
|
1554
1428
|
const prevUserId = prevUserIdRef.current;
|
|
1555
1429
|
prevUserIdRef.current = config.userId;
|
|
@@ -1584,12 +1458,12 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1584
1458
|
getSessionId,
|
|
1585
1459
|
getMessages,
|
|
1586
1460
|
isWaitingForResponse,
|
|
1587
|
-
isUploadingAttachments,
|
|
1588
1461
|
sessionId: sessionIdRef.current,
|
|
1589
1462
|
userActionState,
|
|
1590
1463
|
submitUserAction: submitUserAction2,
|
|
1591
1464
|
cancelUserAction: cancelUserAction2,
|
|
1592
1465
|
resendUserAction: resendUserAction2,
|
|
1466
|
+
expireUserAction: expireUserAction2,
|
|
1593
1467
|
dismissNotification
|
|
1594
1468
|
};
|
|
1595
1469
|
}
|
|
@@ -1808,102 +1682,6 @@ function useVoice(config = {}, callbacks = {}) {
|
|
|
1808
1682
|
reset
|
|
1809
1683
|
};
|
|
1810
1684
|
}
|
|
1811
|
-
function useAttachmentUpload(config) {
|
|
1812
|
-
const configRef = useRef(config);
|
|
1813
|
-
configRef.current = config;
|
|
1814
|
-
const [entries, setEntries] = useState(/* @__PURE__ */ new Map());
|
|
1815
|
-
const [orderedIds, setOrderedIds] = useState([]);
|
|
1816
|
-
const abortControllersRef = useRef(/* @__PURE__ */ new Map());
|
|
1817
|
-
const activeIdsRef = useRef(/* @__PURE__ */ new Set());
|
|
1818
|
-
const startUpload = useCallback((id, file) => {
|
|
1819
|
-
if (activeIdsRef.current.has(id)) return;
|
|
1820
|
-
activeIdsRef.current.add(id);
|
|
1821
|
-
const controller = new AbortController();
|
|
1822
|
-
abortControllersRef.current.set(id, controller);
|
|
1823
|
-
setEntries((prev) => {
|
|
1824
|
-
const next = new Map(prev);
|
|
1825
|
-
next.set(id, { id, status: "uploading" });
|
|
1826
|
-
return next;
|
|
1827
|
-
});
|
|
1828
|
-
void uploadAttachment(configRef.current, file, controller.signal).then((payload) => {
|
|
1829
|
-
if (controller.signal.aborted) return;
|
|
1830
|
-
setEntries((prev) => {
|
|
1831
|
-
const next = new Map(prev);
|
|
1832
|
-
next.set(id, { id, status: "done", payload });
|
|
1833
|
-
return next;
|
|
1834
|
-
});
|
|
1835
|
-
}).catch((error) => {
|
|
1836
|
-
if (error.name === "AbortError") return;
|
|
1837
|
-
setEntries((prev) => {
|
|
1838
|
-
const next = new Map(prev);
|
|
1839
|
-
next.set(id, {
|
|
1840
|
-
id,
|
|
1841
|
-
status: "error",
|
|
1842
|
-
error: error.message || "Upload failed"
|
|
1843
|
-
});
|
|
1844
|
-
return next;
|
|
1845
|
-
});
|
|
1846
|
-
}).finally(() => {
|
|
1847
|
-
abortControllersRef.current.delete(id);
|
|
1848
|
-
});
|
|
1849
|
-
}, []);
|
|
1850
|
-
const syncAttachments = useCallback(
|
|
1851
|
-
(attachments) => {
|
|
1852
|
-
const nextIds = attachments.map((attachment) => attachment.id);
|
|
1853
|
-
setOrderedIds(nextIds);
|
|
1854
|
-
const nextIdSet = new Set(nextIds);
|
|
1855
|
-
for (const id of activeIdsRef.current) {
|
|
1856
|
-
if (nextIdSet.has(id)) continue;
|
|
1857
|
-
abortControllersRef.current.get(id)?.abort();
|
|
1858
|
-
abortControllersRef.current.delete(id);
|
|
1859
|
-
activeIdsRef.current.delete(id);
|
|
1860
|
-
}
|
|
1861
|
-
setEntries((prev) => {
|
|
1862
|
-
const next = new Map(prev);
|
|
1863
|
-
for (const id of next.keys()) {
|
|
1864
|
-
if (!nextIdSet.has(id)) next.delete(id);
|
|
1865
|
-
}
|
|
1866
|
-
return next;
|
|
1867
|
-
});
|
|
1868
|
-
for (const attachment of attachments) {
|
|
1869
|
-
startUpload(attachment.id, attachment.file);
|
|
1870
|
-
}
|
|
1871
|
-
},
|
|
1872
|
-
[startUpload]
|
|
1873
|
-
);
|
|
1874
|
-
const clearAll = useCallback(() => {
|
|
1875
|
-
for (const controller of abortControllersRef.current.values()) {
|
|
1876
|
-
controller.abort();
|
|
1877
|
-
}
|
|
1878
|
-
abortControllersRef.current.clear();
|
|
1879
|
-
activeIdsRef.current.clear();
|
|
1880
|
-
setOrderedIds([]);
|
|
1881
|
-
setEntries(/* @__PURE__ */ new Map());
|
|
1882
|
-
}, []);
|
|
1883
|
-
const entryList = useMemo(
|
|
1884
|
-
() => orderedIds.map((id) => entries.get(id)).filter((entry) => entry != null),
|
|
1885
|
-
[entries, orderedIds]
|
|
1886
|
-
);
|
|
1887
|
-
const isUploading = entryList.some((entry) => entry.status === "uploading");
|
|
1888
|
-
const hasErrors = entryList.some((entry) => entry.status === "error");
|
|
1889
|
-
const allReady = orderedIds.length === 0 || orderedIds.every((id) => entries.get(id)?.status === "done");
|
|
1890
|
-
const payloads = entryList.filter((entry) => entry.status === "done" && entry.payload).map((entry) => entry.payload);
|
|
1891
|
-
const statusById = useMemo(
|
|
1892
|
-
() => Object.fromEntries(
|
|
1893
|
-
entryList.map((entry) => [entry.id, entry.status])
|
|
1894
|
-
),
|
|
1895
|
-
[entryList]
|
|
1896
|
-
);
|
|
1897
|
-
return {
|
|
1898
|
-
syncAttachments,
|
|
1899
|
-
clearAll,
|
|
1900
|
-
isUploading,
|
|
1901
|
-
hasErrors,
|
|
1902
|
-
allReady,
|
|
1903
|
-
payloads,
|
|
1904
|
-
statusById
|
|
1905
|
-
};
|
|
1906
|
-
}
|
|
1907
1685
|
function classifyField(field) {
|
|
1908
1686
|
if (!field) return "text";
|
|
1909
1687
|
if (Array.isArray(field.oneOf) && field.oneOf.length > 0) return "select";
|
|
@@ -2020,66 +1798,6 @@ function buildContent(schema, values) {
|
|
|
2020
1798
|
}
|
|
2021
1799
|
return content;
|
|
2022
1800
|
}
|
|
2023
|
-
var ATTACHMENTS_SUFFIX_RE = /\n\n\[Attachments:[^\]]*\]\s*$/;
|
|
2024
|
-
function stripAttachmentsSuffixFromIntent(intent) {
|
|
2025
|
-
return intent.replace(ATTACHMENTS_SUFFIX_RE, "").trimEnd();
|
|
2026
|
-
}
|
|
2027
|
-
function mapFeedback(feedback) {
|
|
2028
|
-
if (!feedback?.feedback) return null;
|
|
2029
|
-
return feedback.feedback === "POSITIVE" ? "up" : "down";
|
|
2030
|
-
}
|
|
2031
|
-
function mapHistoryAttachments(executionId, attachments) {
|
|
2032
|
-
const mapped = (attachments ?? []).map((attachment, index) => ({
|
|
2033
|
-
id: `${executionId}:att:${index}`,
|
|
2034
|
-
filename: attachment.filename,
|
|
2035
|
-
mimeType: attachment.mimeType,
|
|
2036
|
-
url: attachment.url ?? void 0,
|
|
2037
|
-
kind: attachment.mimeType.startsWith("image/") ? "image" : "file"
|
|
2038
|
-
}));
|
|
2039
|
-
return mapped.length > 0 ? mapped : void 0;
|
|
2040
|
-
}
|
|
2041
|
-
function mapExecutionHistoryToChatMessages(message) {
|
|
2042
|
-
const timestamp = message.startTime || message.endTime || (/* @__PURE__ */ new Date()).toISOString();
|
|
2043
|
-
const executionId = message.executionId ?? message.traceId ?? message.id;
|
|
2044
|
-
const attachments = mapHistoryAttachments(message.id, message.attachments);
|
|
2045
|
-
const rows = [
|
|
2046
|
-
{
|
|
2047
|
-
id: `${message.id}:user`,
|
|
2048
|
-
role: "user",
|
|
2049
|
-
content: stripAttachmentsSuffixFromIntent(message.sessionUserIntent),
|
|
2050
|
-
timestamp,
|
|
2051
|
-
attachments
|
|
2052
|
-
}
|
|
2053
|
-
];
|
|
2054
|
-
if (message.agentResponse) {
|
|
2055
|
-
rows.push({
|
|
2056
|
-
id: `${message.id}:assistant`,
|
|
2057
|
-
role: "assistant",
|
|
2058
|
-
content: message.agentResponse,
|
|
2059
|
-
timestamp: message.endTime || timestamp,
|
|
2060
|
-
isError: message.status === "FAILED",
|
|
2061
|
-
executionId,
|
|
2062
|
-
feedback: mapFeedback(message.feedback)
|
|
2063
|
-
});
|
|
2064
|
-
}
|
|
2065
|
-
return rows;
|
|
2066
|
-
}
|
|
2067
|
-
function mapExecutionHistoryPageToChatMessages(messages) {
|
|
2068
|
-
return messages.flatMap(mapExecutionHistoryToChatMessages);
|
|
2069
|
-
}
|
|
2070
|
-
function attachmentDisplayUrl(attachment) {
|
|
2071
|
-
return attachment.previewUrl ?? attachment.url;
|
|
2072
|
-
}
|
|
2073
|
-
function isImageAttachment(attachment) {
|
|
2074
|
-
const displayUrl = attachmentDisplayUrl(attachment);
|
|
2075
|
-
return attachment.kind === "image" || Boolean(displayUrl) && attachment.mimeType.startsWith("image/");
|
|
2076
|
-
}
|
|
2077
|
-
function isPdfAttachmentMeta(attachment) {
|
|
2078
|
-
return attachment.mimeType === "application/pdf" || /\.pdf$/i.test(attachment.filename);
|
|
2079
|
-
}
|
|
2080
|
-
function isPdfFile(file) {
|
|
2081
|
-
return file.type === "application/pdf" || /\.pdf$/i.test(file.name);
|
|
2082
|
-
}
|
|
2083
1801
|
var PaymanChatContext = createContext(void 0);
|
|
2084
1802
|
function usePaymanChat() {
|
|
2085
1803
|
const context = useContext(PaymanChatContext);
|
|
@@ -2190,111 +1908,6 @@ function subscribeToCfRay(urlPattern, listener) {
|
|
|
2190
1908
|
};
|
|
2191
1909
|
}
|
|
2192
1910
|
|
|
2193
|
-
// src/utils/attachmentConfig.ts
|
|
2194
|
-
var DEFAULT_IMAGE_EXTENSIONS = ["png", "jpg", "jpeg", "gif", "webp"];
|
|
2195
|
-
var DEFAULT_DOCUMENT_EXTENSIONS = ["pdf", "docx", "xlsx", "xls"];
|
|
2196
|
-
function resolveChatAttachmentConfig(config) {
|
|
2197
|
-
const nested = config.attachments;
|
|
2198
|
-
const enabled = nested?.enabled ?? config.showAttachmentButton ?? true;
|
|
2199
|
-
const uploadImage = nested?.uploadImage ?? config.showUploadImageButton ?? true;
|
|
2200
|
-
const attachFile = nested?.attachFile ?? config.showAttachFileButton ?? true;
|
|
2201
|
-
return {
|
|
2202
|
-
showAttachmentButton: enabled && (uploadImage || attachFile),
|
|
2203
|
-
showUploadImageButton: enabled && uploadImage,
|
|
2204
|
-
showAttachFileButton: enabled && attachFile,
|
|
2205
|
-
maxCount: nested?.maxCount ?? nested?.maxImages ?? nested?.maxDocuments,
|
|
2206
|
-
maxFileBytes: nested?.maxFileBytes,
|
|
2207
|
-
maxTotalBytes: nested?.maxTotalBytes,
|
|
2208
|
-
allowedImageExtensions: nested?.imageExtensions ?? DEFAULT_IMAGE_EXTENSIONS,
|
|
2209
|
-
allowedFileExtensions: nested?.documentExtensions ?? DEFAULT_DOCUMENT_EXTENSIONS
|
|
2210
|
-
};
|
|
2211
|
-
}
|
|
2212
|
-
|
|
2213
|
-
// src/utils/formatAttachmentBytes.ts
|
|
2214
|
-
function formatAttachmentBytes(bytes) {
|
|
2215
|
-
if (!Number.isFinite(bytes) || bytes <= 0) return "0 B";
|
|
2216
|
-
const units = ["B", "KB", "MB", "GB"];
|
|
2217
|
-
let value = bytes;
|
|
2218
|
-
let unitIndex = 0;
|
|
2219
|
-
while (value >= 1024 && unitIndex < units.length - 1) {
|
|
2220
|
-
value /= 1024;
|
|
2221
|
-
unitIndex += 1;
|
|
2222
|
-
}
|
|
2223
|
-
const rounded = unitIndex === 0 ? String(Math.round(value)) : value >= 10 ? value.toFixed(0) : value.toFixed(1).replace(/\.0$/, "");
|
|
2224
|
-
return `${rounded} ${units[unitIndex]}`;
|
|
2225
|
-
}
|
|
2226
|
-
|
|
2227
|
-
// src/utils/pdfLink.ts
|
|
2228
|
-
function filenameFromContentDisposition(value) {
|
|
2229
|
-
if (!value) return void 0;
|
|
2230
|
-
let decoded = value;
|
|
2231
|
-
try {
|
|
2232
|
-
decoded = decodeURIComponent(value);
|
|
2233
|
-
} catch {
|
|
2234
|
-
decoded = value;
|
|
2235
|
-
}
|
|
2236
|
-
const quoted = decoded.match(/filename\*=(?:UTF-8''([^;]+)|"([^"]+)")/i);
|
|
2237
|
-
if (quoted?.[1] || quoted?.[2]) {
|
|
2238
|
-
return (quoted[1] ?? quoted[2])?.trim();
|
|
2239
|
-
}
|
|
2240
|
-
const unquoted = decoded.match(/filename=([^;]+)/i);
|
|
2241
|
-
return unquoted?.[1]?.replace(/"/g, "").trim();
|
|
2242
|
-
}
|
|
2243
|
-
function filenameFromUrlPath(href) {
|
|
2244
|
-
try {
|
|
2245
|
-
const parts = new URL(href).pathname.split("/").filter(Boolean);
|
|
2246
|
-
const last = parts[parts.length - 1];
|
|
2247
|
-
return last ? decodeURIComponent(last) : void 0;
|
|
2248
|
-
} catch {
|
|
2249
|
-
return void 0;
|
|
2250
|
-
}
|
|
2251
|
-
}
|
|
2252
|
-
function isPdfUrl(href) {
|
|
2253
|
-
if (!href) return false;
|
|
2254
|
-
const lower = href.toLowerCase();
|
|
2255
|
-
if (lower.includes(".pdf")) return true;
|
|
2256
|
-
try {
|
|
2257
|
-
const url = new URL(href);
|
|
2258
|
-
if (url.pathname.toLowerCase().endsWith(".pdf")) return true;
|
|
2259
|
-
const filename = url.searchParams.get("filename");
|
|
2260
|
-
if (filename?.toLowerCase().includes(".pdf")) return true;
|
|
2261
|
-
for (const key of ["rscd", "response-content-disposition"]) {
|
|
2262
|
-
const fromDisposition = filenameFromContentDisposition(
|
|
2263
|
-
url.searchParams.get(key)
|
|
2264
|
-
);
|
|
2265
|
-
if (fromDisposition?.toLowerCase().includes(".pdf")) return true;
|
|
2266
|
-
}
|
|
2267
|
-
} catch {
|
|
2268
|
-
return lower.endsWith(".pdf");
|
|
2269
|
-
}
|
|
2270
|
-
return false;
|
|
2271
|
-
}
|
|
2272
|
-
function getPdfTitleFromUrl(href, linkText) {
|
|
2273
|
-
const text = linkText?.trim();
|
|
2274
|
-
if (text) return text;
|
|
2275
|
-
try {
|
|
2276
|
-
const url = new URL(href);
|
|
2277
|
-
const filename = url.searchParams.get("filename");
|
|
2278
|
-
if (filename) {
|
|
2279
|
-
return filename.replace(/\.pdf$/i, "").replace(/[-_]+/g, " ").trim();
|
|
2280
|
-
}
|
|
2281
|
-
for (const key of ["rscd", "response-content-disposition"]) {
|
|
2282
|
-
const fromDisposition = filenameFromContentDisposition(
|
|
2283
|
-
url.searchParams.get(key)
|
|
2284
|
-
);
|
|
2285
|
-
if (fromDisposition) {
|
|
2286
|
-
return fromDisposition.replace(/\.pdf$/i, "").replace(/[-_]+/g, " ").trim();
|
|
2287
|
-
}
|
|
2288
|
-
}
|
|
2289
|
-
} catch {
|
|
2290
|
-
}
|
|
2291
|
-
const fromPath = filenameFromUrlPath(href);
|
|
2292
|
-
if (fromPath) {
|
|
2293
|
-
return fromPath.replace(/\.pdf$/i, "").replace(/[-_]+/g, " ").trim();
|
|
2294
|
-
}
|
|
2295
|
-
return "Document";
|
|
2296
|
-
}
|
|
2297
|
-
|
|
2298
1911
|
// src/utils/slashCommands.ts
|
|
2299
1912
|
var DEFAULT_SLASH_COMMANDS = [
|
|
2300
1913
|
{
|
|
@@ -3446,108 +3059,6 @@ function ActionTooltipV2({ label, children }) {
|
|
|
3446
3059
|
] }) })
|
|
3447
3060
|
] });
|
|
3448
3061
|
}
|
|
3449
|
-
function FilePreviewShell({
|
|
3450
|
-
filename,
|
|
3451
|
-
typeLabel,
|
|
3452
|
-
onClick,
|
|
3453
|
-
thumbnail,
|
|
3454
|
-
className,
|
|
3455
|
-
"aria-label": ariaLabel
|
|
3456
|
-
}) {
|
|
3457
|
-
const shellClass = cn(
|
|
3458
|
-
"payman-v2-file-preview-shell",
|
|
3459
|
-
"payman-v2-file-preview-shell-sent",
|
|
3460
|
-
onClick && "payman-v2-file-preview-shell-clickable",
|
|
3461
|
-
className
|
|
3462
|
-
);
|
|
3463
|
-
const body = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3464
|
-
/* @__PURE__ */ jsx("div", { className: "payman-v2-file-preview-thumb", children: thumbnail ?? /* @__PURE__ */ jsx(
|
|
3465
|
-
FileText,
|
|
3466
|
-
{
|
|
3467
|
-
size: 16,
|
|
3468
|
-
strokeWidth: 1.75,
|
|
3469
|
-
className: "payman-v2-file-preview-doc-icon"
|
|
3470
|
-
}
|
|
3471
|
-
) }),
|
|
3472
|
-
/* @__PURE__ */ jsxs("div", { className: "payman-v2-file-preview-info", children: [
|
|
3473
|
-
/* @__PURE__ */ jsx("span", { className: "payman-v2-file-preview-name", children: filename }),
|
|
3474
|
-
/* @__PURE__ */ jsx("span", { className: "payman-v2-file-preview-type", children: typeLabel })
|
|
3475
|
-
] })
|
|
3476
|
-
] });
|
|
3477
|
-
if (onClick) {
|
|
3478
|
-
return /* @__PURE__ */ jsx(
|
|
3479
|
-
"button",
|
|
3480
|
-
{
|
|
3481
|
-
type: "button",
|
|
3482
|
-
className: shellClass,
|
|
3483
|
-
onClick,
|
|
3484
|
-
"aria-label": ariaLabel ?? `Open ${filename}`,
|
|
3485
|
-
children: body
|
|
3486
|
-
}
|
|
3487
|
-
);
|
|
3488
|
-
}
|
|
3489
|
-
return /* @__PURE__ */ jsx("div", { className: shellClass, children: body });
|
|
3490
|
-
}
|
|
3491
|
-
function FilePreviewBlockLayout({
|
|
3492
|
-
children,
|
|
3493
|
-
className,
|
|
3494
|
-
...rest
|
|
3495
|
-
}) {
|
|
3496
|
-
return /* @__PURE__ */ jsx("div", { className: cn("payman-v2-file-preview-item", className), ...rest, children });
|
|
3497
|
-
}
|
|
3498
|
-
function attachmentTypeLabel(attachment) {
|
|
3499
|
-
if (isImageAttachment(attachment)) {
|
|
3500
|
-
return "Image";
|
|
3501
|
-
}
|
|
3502
|
-
const ext = attachment.filename.split(".").pop()?.toUpperCase();
|
|
3503
|
-
return ext || "Document";
|
|
3504
|
-
}
|
|
3505
|
-
function isPdfAttachment(attachment) {
|
|
3506
|
-
const displayUrl = attachmentDisplayUrl(attachment);
|
|
3507
|
-
return isPdfAttachmentMeta(attachment) || Boolean(displayUrl) && isPdfUrl(displayUrl);
|
|
3508
|
-
}
|
|
3509
|
-
function AttachmentPreviewBlock({
|
|
3510
|
-
attachment,
|
|
3511
|
-
onImageClick
|
|
3512
|
-
}) {
|
|
3513
|
-
const chatContext = useContext(PaymanChatContext);
|
|
3514
|
-
const displayUrl = attachmentDisplayUrl(attachment);
|
|
3515
|
-
const typeLabel = attachmentTypeLabel(attachment);
|
|
3516
|
-
const isImage = isImageAttachment(attachment) && displayUrl;
|
|
3517
|
-
const openAttachment = () => {
|
|
3518
|
-
if (!displayUrl) return;
|
|
3519
|
-
if (isImageAttachment(attachment)) {
|
|
3520
|
-
onImageClick?.(displayUrl, attachment.filename);
|
|
3521
|
-
return;
|
|
3522
|
-
}
|
|
3523
|
-
if (isPdfAttachment(attachment)) {
|
|
3524
|
-
chatContext?.openPdfSheet(displayUrl, attachment.filename);
|
|
3525
|
-
return;
|
|
3526
|
-
}
|
|
3527
|
-
window.open(displayUrl, "_blank", "noopener,noreferrer");
|
|
3528
|
-
};
|
|
3529
|
-
if (isImage) {
|
|
3530
|
-
return /* @__PURE__ */ jsx(FilePreviewBlockLayout, { children: /* @__PURE__ */ jsx(
|
|
3531
|
-
FilePreviewShell,
|
|
3532
|
-
{
|
|
3533
|
-
filename: attachment.filename,
|
|
3534
|
-
typeLabel,
|
|
3535
|
-
onClick: openAttachment,
|
|
3536
|
-
"aria-label": `Preview ${attachment.filename}`,
|
|
3537
|
-
thumbnail: /* @__PURE__ */ jsx("img", { src: displayUrl, alt: "", draggable: false })
|
|
3538
|
-
}
|
|
3539
|
-
) });
|
|
3540
|
-
}
|
|
3541
|
-
return /* @__PURE__ */ jsx(FilePreviewBlockLayout, { children: /* @__PURE__ */ jsx(
|
|
3542
|
-
FilePreviewShell,
|
|
3543
|
-
{
|
|
3544
|
-
filename: attachment.filename,
|
|
3545
|
-
typeLabel,
|
|
3546
|
-
onClick: displayUrl ? openAttachment : void 0,
|
|
3547
|
-
"aria-label": `Open ${attachment.filename}`
|
|
3548
|
-
}
|
|
3549
|
-
) });
|
|
3550
|
-
}
|
|
3551
3062
|
function formatMessageTime(timestamp) {
|
|
3552
3063
|
const value = new Date(timestamp);
|
|
3553
3064
|
if (Number.isNaN(value.getTime())) return "";
|
|
@@ -3560,7 +3071,6 @@ function UserMessageV2({
|
|
|
3560
3071
|
message,
|
|
3561
3072
|
onEdit,
|
|
3562
3073
|
onRetry,
|
|
3563
|
-
onImageClick,
|
|
3564
3074
|
retryDisabled = false,
|
|
3565
3075
|
actions
|
|
3566
3076
|
}) {
|
|
@@ -3643,15 +3153,7 @@ function UserMessageV2({
|
|
|
3643
3153
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3644
3154
|
toastPortal,
|
|
3645
3155
|
/* @__PURE__ */ jsx("div", { className: "payman-v2-user-msg payman-v2-fade-in", children: /* @__PURE__ */ jsxs("div", { className: "payman-v2-user-msg-group", children: [
|
|
3646
|
-
|
|
3647
|
-
AttachmentPreviewBlock,
|
|
3648
|
-
{
|
|
3649
|
-
attachment,
|
|
3650
|
-
onImageClick
|
|
3651
|
-
},
|
|
3652
|
-
attachment.id
|
|
3653
|
-
)) }),
|
|
3654
|
-
(message.content.trim().length > 0 || !message.attachments?.length) && /* @__PURE__ */ jsx("div", { className: "payman-v2-user-msg-bubble", children: parsedCommand ? /* @__PURE__ */ jsxs("div", { className: "payman-v2-user-msg-command", children: [
|
|
3156
|
+
/* @__PURE__ */ jsx("div", { className: "payman-v2-user-msg-bubble", children: parsedCommand ? /* @__PURE__ */ jsxs("div", { className: "payman-v2-user-msg-command", children: [
|
|
3655
3157
|
/* @__PURE__ */ jsx("span", { className: "payman-v2-user-msg-command-chip", children: parsedCommand.command }),
|
|
3656
3158
|
parsedCommand.body.trim() ? /* @__PURE__ */ jsx("p", { className: "payman-v2-user-msg-text", children: parsedCommand.body }) : null
|
|
3657
3159
|
] }) : /* @__PURE__ */ jsx("p", { className: "payman-v2-user-msg-text", children: message.content }) }),
|
|
@@ -3876,44 +3378,9 @@ function MarkdownImageV2({
|
|
|
3876
3378
|
}
|
|
3877
3379
|
) });
|
|
3878
3380
|
}
|
|
3879
|
-
function
|
|
3880
|
-
const autoOpenedHrefRef = useRef(null);
|
|
3881
|
-
useEffect(() => {
|
|
3882
|
-
if (!autoOpen || autoOpenedHrefRef.current === href) return;
|
|
3883
|
-
autoOpenedHrefRef.current = href;
|
|
3884
|
-
onOpen(href, title, { auto: true });
|
|
3885
|
-
}, [href, autoOpen]);
|
|
3886
|
-
return /* @__PURE__ */ jsx(FilePreviewBlockLayout, { "data-payman-file-block": true, children: /* @__PURE__ */ jsx(
|
|
3887
|
-
FilePreviewShell,
|
|
3888
|
-
{
|
|
3889
|
-
filename: title,
|
|
3890
|
-
typeLabel: "PDF",
|
|
3891
|
-
onClick: () => onOpen(href, title),
|
|
3892
|
-
"aria-label": `Open PDF: ${title}`
|
|
3893
|
-
}
|
|
3894
|
-
) });
|
|
3895
|
-
}
|
|
3896
|
-
function childrenToText(children) {
|
|
3897
|
-
if (typeof children === "string") return children;
|
|
3898
|
-
if (typeof children === "number") return String(children);
|
|
3899
|
-
if (Array.isArray(children)) return children.map(childrenToText).join("");
|
|
3900
|
-
if (children && typeof children === "object" && "props" in children) {
|
|
3901
|
-
return childrenToText(children.props.children);
|
|
3902
|
-
}
|
|
3903
|
-
return "";
|
|
3904
|
-
}
|
|
3905
|
-
function isFileBlockChild(child) {
|
|
3906
|
-
return isValidElement(child) && typeof child.props === "object" && child.props !== null && "data-payman-file-block" in child.props;
|
|
3907
|
-
}
|
|
3908
|
-
function buildComponents(onImageClick, isResolvingRef, onPdfClick, autoOpenPdf) {
|
|
3381
|
+
function buildComponents(onImageClick, isResolvingRef) {
|
|
3909
3382
|
return {
|
|
3910
|
-
p: ({ children }) => {
|
|
3911
|
-
const childArray = Children.toArray(children);
|
|
3912
|
-
if (childArray.length === 1 && isFileBlockChild(childArray[0])) {
|
|
3913
|
-
return childArray[0];
|
|
3914
|
-
}
|
|
3915
|
-
return /* @__PURE__ */ jsx("p", { children });
|
|
3916
|
-
},
|
|
3383
|
+
p: ({ children }) => /* @__PURE__ */ jsx("p", { children }),
|
|
3917
3384
|
code: ({ children }) => /* @__PURE__ */ jsx("code", { children }),
|
|
3918
3385
|
pre: ({ children }) => /* @__PURE__ */ jsx("div", { className: "payman-v2-markdown-pre", children: /* @__PURE__ */ jsx("pre", { children }) }),
|
|
3919
3386
|
ul: ({ children }) => /* @__PURE__ */ jsx("ul", { children }),
|
|
@@ -3926,15 +3393,7 @@ function buildComponents(onImageClick, isResolvingRef, onPdfClick, autoOpenPdf)
|
|
|
3926
3393
|
em: ({ children }) => /* @__PURE__ */ jsx("em", { children }),
|
|
3927
3394
|
blockquote: ({ children }) => /* @__PURE__ */ jsx("blockquote", { children }),
|
|
3928
3395
|
hr: () => /* @__PURE__ */ jsx("hr", {}),
|
|
3929
|
-
a: ({ href, children }) => {
|
|
3930
|
-
const url = href ?? "";
|
|
3931
|
-
if (onPdfClick && isPdfUrl(url)) {
|
|
3932
|
-
const linkText = childrenToText(children).trim();
|
|
3933
|
-
const title = getPdfTitleFromUrl(url, linkText);
|
|
3934
|
-
return /* @__PURE__ */ jsx(PdfBlockV2, { href: url, title, onOpen: onPdfClick, autoOpen: autoOpenPdf });
|
|
3935
|
-
}
|
|
3936
|
-
return /* @__PURE__ */ jsx("a", { href, target: "_blank", rel: "noopener noreferrer", children });
|
|
3937
|
-
},
|
|
3396
|
+
a: ({ href, children }) => /* @__PURE__ */ jsx("a", { href, target: "_blank", rel: "noopener noreferrer", children }),
|
|
3938
3397
|
img: ({ src, alt }) => /* @__PURE__ */ jsx(
|
|
3939
3398
|
MarkdownImageV2,
|
|
3940
3399
|
{
|
|
@@ -3955,15 +3414,13 @@ function MarkdownRendererV2({
|
|
|
3955
3414
|
content,
|
|
3956
3415
|
isStreaming,
|
|
3957
3416
|
isResolvingImages,
|
|
3958
|
-
onImageClick
|
|
3959
|
-
onPdfClick,
|
|
3960
|
-
autoOpenPdf
|
|
3417
|
+
onImageClick
|
|
3961
3418
|
}) {
|
|
3962
3419
|
const isResolvingRef = useRef(isResolvingImages);
|
|
3963
3420
|
isResolvingRef.current = isResolvingImages;
|
|
3964
3421
|
const components = useMemo(
|
|
3965
|
-
() => buildComponents(onImageClick, isResolvingRef
|
|
3966
|
-
[onImageClick
|
|
3422
|
+
() => buildComponents(onImageClick, isResolvingRef),
|
|
3423
|
+
[onImageClick]
|
|
3967
3424
|
);
|
|
3968
3425
|
return /* @__PURE__ */ jsx(
|
|
3969
3426
|
"div",
|
|
@@ -4332,17 +3789,6 @@ function stripIncompleteImageToken(text) {
|
|
|
4332
3789
|
if (/^!\[[^\]]*\]\([^)]*\)/.test(after)) return text;
|
|
4333
3790
|
return text.slice(0, lastBang);
|
|
4334
3791
|
}
|
|
4335
|
-
function stripIncompleteLinkToken(text) {
|
|
4336
|
-
const lastBracket = text.lastIndexOf("[");
|
|
4337
|
-
if (lastBracket === -1) return text;
|
|
4338
|
-
if (lastBracket > 0 && text[lastBracket - 1] === "!") return text;
|
|
4339
|
-
const after = text.slice(lastBracket);
|
|
4340
|
-
if (/^\[[^\]]*\]\([^)]*\)/.test(after)) return text;
|
|
4341
|
-
return text.slice(0, lastBracket);
|
|
4342
|
-
}
|
|
4343
|
-
function stripIncompleteMarkdownTokens(text) {
|
|
4344
|
-
return stripIncompleteLinkToken(stripIncompleteImageToken(text));
|
|
4345
|
-
}
|
|
4346
3792
|
function getFeedbackState(message) {
|
|
4347
3793
|
const feedback = message.feedback;
|
|
4348
3794
|
if (feedback === "up" || feedback === "down") return feedback;
|
|
@@ -4366,12 +3812,6 @@ function AssistantMessageV2({
|
|
|
4366
3812
|
() => getFeedbackState(message)
|
|
4367
3813
|
);
|
|
4368
3814
|
const [reasonModalOpen, setReasonModalOpen] = useState(false);
|
|
4369
|
-
const chatContext = useContext(PaymanChatContext);
|
|
4370
|
-
const chatContextRef = useRef(chatContext);
|
|
4371
|
-
chatContextRef.current = chatContext;
|
|
4372
|
-
const handlePdfClick = useCallback((href, title, options) => {
|
|
4373
|
-
chatContextRef.current?.openPdfSheet(href, title, options);
|
|
4374
|
-
}, []);
|
|
4375
3815
|
const canSubmitFeedback = !!onSubmitFeedback && !!message.executionId;
|
|
4376
3816
|
const [toast, setToast] = useState(null);
|
|
4377
3817
|
const copyResetTimerRef = useRef(null);
|
|
@@ -4396,7 +3836,7 @@ function AssistantMessageV2({
|
|
|
4396
3836
|
const raw = message.isStreaming ? message.streamingContent || message.content : message.content;
|
|
4397
3837
|
if (!raw) return "";
|
|
4398
3838
|
const normalized = raw.replace(/\\n/g, "\n");
|
|
4399
|
-
return message.isStreaming ?
|
|
3839
|
+
return message.isStreaming ? stripIncompleteImageToken(normalized) : normalized;
|
|
4400
3840
|
})();
|
|
4401
3841
|
const isThinkingStreaming = !!message.isStreaming && !rawResponseContent && !message.isError;
|
|
4402
3842
|
const responseTypingEnabled = hasEverStreamed.current && Boolean(rawResponseContent) && !message.isError;
|
|
@@ -4566,12 +4006,10 @@ function AssistantMessageV2({
|
|
|
4566
4006
|
/* @__PURE__ */ jsx("div", { className: "payman-v2-assistant-msg-content-area", children: displayContent ? /* @__PURE__ */ jsx(
|
|
4567
4007
|
MarkdownRendererV2,
|
|
4568
4008
|
{
|
|
4569
|
-
content:
|
|
4009
|
+
content: displayContent,
|
|
4570
4010
|
isStreaming: message.isStreaming && !isCancelled || isResponseTyping,
|
|
4571
4011
|
isResolvingImages: message.isResolvingImages,
|
|
4572
|
-
onImageClick
|
|
4573
|
-
onPdfClick: handlePdfClick,
|
|
4574
|
-
autoOpenPdf: hasEverStreamed.current
|
|
4012
|
+
onImageClick
|
|
4575
4013
|
}
|
|
4576
4014
|
) : !isThinkingStreaming ? /* @__PURE__ */ jsx("span", { className: "payman-v2-assistant-msg-placeholder", children: "..." }) : null }),
|
|
4577
4015
|
isCancelled && message.isStreaming && /* @__PURE__ */ jsxs("div", { className: "payman-v2-assistant-msg-paused", children: [
|
|
@@ -4788,6 +4226,7 @@ function VerificationInline({
|
|
|
4788
4226
|
const [code, setCode] = useState("");
|
|
4789
4227
|
const [errored, setErrored] = useState(false);
|
|
4790
4228
|
const [resendSec, setResendSec] = useState(0);
|
|
4229
|
+
const [hiddenAfterResend, setHiddenAfterResend] = useState(false);
|
|
4791
4230
|
const lastSubmittedRef = useRef(null);
|
|
4792
4231
|
const resendTimerRef = useRef(void 0);
|
|
4793
4232
|
const status = prompt.status;
|
|
@@ -4801,6 +4240,9 @@ function VerificationInline({
|
|
|
4801
4240
|
lastSubmittedRef.current = null;
|
|
4802
4241
|
}
|
|
4803
4242
|
}, [prompt.subAction, prompt.userActionId]);
|
|
4243
|
+
useEffect(() => {
|
|
4244
|
+
setHiddenAfterResend(false);
|
|
4245
|
+
}, [prompt.expirySeconds, prompt.message, prompt.subAction, prompt.userActionId]);
|
|
4804
4246
|
useEffect(() => {
|
|
4805
4247
|
if (code.length < codeLen) lastSubmittedRef.current = null;
|
|
4806
4248
|
}, [code, codeLen]);
|
|
@@ -4851,11 +4293,13 @@ function VerificationInline({
|
|
|
4851
4293
|
if (locked || resendSec > 0) return;
|
|
4852
4294
|
setErrored(false);
|
|
4853
4295
|
setCode("");
|
|
4296
|
+
setHiddenAfterResend(true);
|
|
4854
4297
|
lastSubmittedRef.current = null;
|
|
4855
4298
|
try {
|
|
4856
4299
|
await onResend(prompt.userActionId);
|
|
4857
4300
|
startResendCooldown();
|
|
4858
4301
|
} catch {
|
|
4302
|
+
setHiddenAfterResend(false);
|
|
4859
4303
|
}
|
|
4860
4304
|
}, [locked, onResend, prompt.userActionId, resendSec, startResendCooldown]);
|
|
4861
4305
|
const handleCancel = useCallback(() => {
|
|
@@ -4863,6 +4307,7 @@ function VerificationInline({
|
|
|
4863
4307
|
void onCancel(prompt.userActionId);
|
|
4864
4308
|
}, [busy, onCancel, prompt.userActionId]);
|
|
4865
4309
|
const description = prompt.message?.trim() || (isNumeric ? `Enter the ${codeLen}-digit code to continue` : "Enter the verification code to continue");
|
|
4310
|
+
if (hiddenAfterResend) return null;
|
|
4866
4311
|
return /* @__PURE__ */ jsxs("div", { className: "payman-v2-ua", role: "group", "aria-label": "Verification required", children: [
|
|
4867
4312
|
/* @__PURE__ */ jsxs("div", { className: "payman-v2-ua-head", children: [
|
|
4868
4313
|
/* @__PURE__ */ jsx(ShieldCheck, { className: "payman-v2-ua-icon", size: 15, strokeWidth: 1.75, "aria-hidden": true }),
|
|
@@ -4958,6 +4403,9 @@ function SchemaFormInline({
|
|
|
4958
4403
|
const busy = status === "submitting";
|
|
4959
4404
|
const stale = status === "stale";
|
|
4960
4405
|
const locked = busy || stale || expired;
|
|
4406
|
+
const isUserConfirmation = prompt.subAction === "UserConfirmation";
|
|
4407
|
+
const messageFormat = prompt.metadata?.["payman/messageFormat"];
|
|
4408
|
+
const renderMarkdown = messageFormat === "markdown";
|
|
4961
4409
|
const setValue = (key, value) => {
|
|
4962
4410
|
setValues((prev) => ({ ...prev, [key]: value }));
|
|
4963
4411
|
setErrors((prev) => {
|
|
@@ -4983,8 +4431,8 @@ function SchemaFormInline({
|
|
|
4983
4431
|
/* @__PURE__ */ jsx("span", { className: "payman-v2-ua-title", children: "Action required" }),
|
|
4984
4432
|
typeof secondsLeft === "number" && !stale && /* @__PURE__ */ jsx("span", { className: "payman-v2-ua-timer", children: expired ? "Expired" : `${secondsLeft}s` })
|
|
4985
4433
|
] }),
|
|
4986
|
-
prompt.message?.trim() && /* @__PURE__ */ jsx("p", { className: "payman-v2-ua-desc", children: prompt.message }),
|
|
4987
|
-
stale ? /* @__PURE__ */ jsx("p", { className: "payman-v2-ua-stale", children: "This request is no longer available." }) : fields.length === 0 ?
|
|
4434
|
+
prompt.message?.trim() && (renderMarkdown ? /* @__PURE__ */ jsx("div", { className: "payman-v2-ua-markdown", children: /* @__PURE__ */ jsx(MarkdownRendererV2, { content: prompt.message }) }) : /* @__PURE__ */ jsx("p", { className: "payman-v2-ua-desc", children: prompt.message })),
|
|
4435
|
+
stale ? /* @__PURE__ */ jsx("p", { className: "payman-v2-ua-stale", children: "This request is no longer available." }) : fields.length === 0 ? null : /* @__PURE__ */ jsx("div", { className: "payman-v2-ua-form", children: fields.map(([key, field]) => {
|
|
4988
4436
|
const widget = classifyField(field);
|
|
4989
4437
|
const label = field.title || key;
|
|
4990
4438
|
const required = isRequired(schema, key);
|
|
@@ -5057,7 +4505,7 @@ function SchemaFormInline({
|
|
|
5057
4505
|
className: "payman-v2-ua-btn payman-v2-ua-btn-primary",
|
|
5058
4506
|
disabled: locked,
|
|
5059
4507
|
onClick: handleSubmit,
|
|
5060
|
-
children: busy ? "Submitting\u2026" : "Submit"
|
|
4508
|
+
children: busy ? "Submitting\u2026" : isUserConfirmation ? "Confirm" : "Submit"
|
|
5061
4509
|
}
|
|
5062
4510
|
),
|
|
5063
4511
|
/* @__PURE__ */ jsx(
|
|
@@ -5097,26 +4545,51 @@ function useExpiryCountdown(prompt) {
|
|
|
5097
4545
|
setSecondsLeft(void 0);
|
|
5098
4546
|
return;
|
|
5099
4547
|
}
|
|
5100
|
-
|
|
5101
|
-
|
|
5102
|
-
|
|
5103
|
-
|
|
5104
|
-
|
|
5105
|
-
|
|
5106
|
-
|
|
5107
|
-
|
|
5108
|
-
|
|
5109
|
-
}
|
|
5110
|
-
}
|
|
5111
|
-
|
|
4548
|
+
const deadlineMs = Date.now() + initial * 1e3;
|
|
4549
|
+
let intervalId;
|
|
4550
|
+
const remaining = () => Math.max(0, Math.ceil((deadlineMs - Date.now()) / 1e3));
|
|
4551
|
+
const sync = () => {
|
|
4552
|
+
const next = remaining();
|
|
4553
|
+
setSecondsLeft(next);
|
|
4554
|
+
if (next === 0 && intervalId !== void 0) {
|
|
4555
|
+
window.clearInterval(intervalId);
|
|
4556
|
+
intervalId = void 0;
|
|
4557
|
+
}
|
|
4558
|
+
};
|
|
4559
|
+
sync();
|
|
4560
|
+
intervalId = window.setInterval(sync, 1e3);
|
|
4561
|
+
document.addEventListener("visibilitychange", sync);
|
|
4562
|
+
window.addEventListener("focus", sync);
|
|
4563
|
+
window.addEventListener("pageshow", sync);
|
|
4564
|
+
return () => {
|
|
4565
|
+
if (intervalId !== void 0) window.clearInterval(intervalId);
|
|
4566
|
+
document.removeEventListener("visibilitychange", sync);
|
|
4567
|
+
window.removeEventListener("focus", sync);
|
|
4568
|
+
window.removeEventListener("pageshow", sync);
|
|
4569
|
+
};
|
|
5112
4570
|
}, [prompt.userActionId, prompt.subAction, initial]);
|
|
5113
4571
|
const expired = initial !== void 0 && secondsLeft === 0;
|
|
5114
4572
|
return [secondsLeft, expired];
|
|
5115
4573
|
}
|
|
5116
|
-
function UserActionInline({
|
|
4574
|
+
function UserActionInline({
|
|
4575
|
+
prompt,
|
|
4576
|
+
onSubmit,
|
|
4577
|
+
onCancel,
|
|
4578
|
+
onResend,
|
|
4579
|
+
onExpired
|
|
4580
|
+
}) {
|
|
5117
4581
|
const [secondsLeft, expired] = useExpiryCountdown(prompt);
|
|
4582
|
+
useEffect(() => {
|
|
4583
|
+
if (expired && prompt.kind !== "notification") onExpired?.();
|
|
4584
|
+
}, [expired, onExpired, prompt.kind]);
|
|
5118
4585
|
let body;
|
|
5119
|
-
if (prompt.kind
|
|
4586
|
+
if (expired && prompt.kind !== "notification") {
|
|
4587
|
+
const note = {
|
|
4588
|
+
id: `${prompt.userActionId}-expired`,
|
|
4589
|
+
message: prompt.kind === "verification" ? "Verification Request Expired" : "User Form Expired"
|
|
4590
|
+
};
|
|
4591
|
+
body = /* @__PURE__ */ jsx(NotificationInline, { notification: note });
|
|
4592
|
+
} else if (prompt.kind === "verification") {
|
|
5120
4593
|
body = /* @__PURE__ */ jsx(
|
|
5121
4594
|
VerificationInline,
|
|
5122
4595
|
{
|
|
@@ -5156,10 +4629,23 @@ function UserActionInline({ prompt, onSubmit, onCancel, onResend }) {
|
|
|
5156
4629
|
}
|
|
5157
4630
|
var SCROLL_THRESHOLD2 = 100;
|
|
5158
4631
|
var USER_SCROLL_UP_EPSILON = 4;
|
|
4632
|
+
var PROMPT_KEY_SEPARATOR = "";
|
|
4633
|
+
function getPromptSlotKey(prompt) {
|
|
4634
|
+
return prompt.toolCallId || prompt.userActionId;
|
|
4635
|
+
}
|
|
4636
|
+
function getPromptViewKey(prompt) {
|
|
4637
|
+
return [
|
|
4638
|
+
getPromptSlotKey(prompt),
|
|
4639
|
+
prompt.userActionId,
|
|
4640
|
+
prompt.subAction ?? "",
|
|
4641
|
+
prompt.expirySeconds ?? "",
|
|
4642
|
+
prompt.message ?? ""
|
|
4643
|
+
].join(PROMPT_KEY_SEPARATOR);
|
|
4644
|
+
}
|
|
5159
4645
|
var MessageListV2 = forwardRef(
|
|
5160
4646
|
function MessageListV22({
|
|
5161
4647
|
messages,
|
|
5162
|
-
isStreaming
|
|
4648
|
+
isStreaming = false,
|
|
5163
4649
|
onEditUserMessage,
|
|
5164
4650
|
onRetryUserMessage,
|
|
5165
4651
|
onImageClick,
|
|
@@ -5171,10 +4657,10 @@ var MessageListV2 = forwardRef(
|
|
|
5171
4657
|
onSubmitUserAction,
|
|
5172
4658
|
onCancelUserAction,
|
|
5173
4659
|
onResendUserAction,
|
|
4660
|
+
onExpireUserAction,
|
|
5174
4661
|
onDismissNotification,
|
|
5175
4662
|
onSubmitFeedback,
|
|
5176
|
-
typingSpeed = 4
|
|
5177
|
-
sidePanelOpen = false
|
|
4663
|
+
typingSpeed = 4
|
|
5178
4664
|
}, ref) {
|
|
5179
4665
|
const noop = useCallback(async () => {
|
|
5180
4666
|
}, []);
|
|
@@ -5182,11 +4668,11 @@ var MessageListV2 = forwardRef(
|
|
|
5182
4668
|
const scrollInnerRef = useRef(null);
|
|
5183
4669
|
const isNearBottomRef = useRef(true);
|
|
5184
4670
|
const [showScrollBtn, setShowScrollBtn] = useState(false);
|
|
4671
|
+
const [expiredPromptViewState, setExpiredPromptViewState] = useState({});
|
|
4672
|
+
const expiredUserActionIdsRef = useRef(/* @__PURE__ */ new Set());
|
|
5185
4673
|
const prevCountRef = useRef(messages.length);
|
|
5186
4674
|
const pauseStickUntilUserMessageRef = useRef(false);
|
|
5187
4675
|
const followingBottomRef = useRef(true);
|
|
5188
|
-
const sidePanelOpenRef = useRef(sidePanelOpen);
|
|
5189
|
-
sidePanelOpenRef.current = sidePanelOpen;
|
|
5190
4676
|
const lastPinAtRef = useRef(0);
|
|
5191
4677
|
const prevScrollTopRef = useRef(0);
|
|
5192
4678
|
const getDistanceFromBottom = useCallback(() => {
|
|
@@ -5194,6 +4680,92 @@ var MessageListV2 = forwardRef(
|
|
|
5194
4680
|
if (!el) return 0;
|
|
5195
4681
|
return el.scrollHeight - el.scrollTop - el.clientHeight;
|
|
5196
4682
|
}, []);
|
|
4683
|
+
const messageActivityFingerprint = useMemo(() => {
|
|
4684
|
+
const last = messages[messages.length - 1];
|
|
4685
|
+
const promptFingerprint = (userActionPrompts ?? []).map((prompt) => `${getPromptViewKey(prompt)}:${prompt.status}`).join(PROMPT_KEY_SEPARATOR);
|
|
4686
|
+
const notificationFingerprint = (notifications ?? []).map((notification) => notification.id).join(PROMPT_KEY_SEPARATOR);
|
|
4687
|
+
if (!last) {
|
|
4688
|
+
return [
|
|
4689
|
+
0,
|
|
4690
|
+
isStreaming ? "streaming" : "idle",
|
|
4691
|
+
promptFingerprint,
|
|
4692
|
+
notificationFingerprint
|
|
4693
|
+
].join(PROMPT_KEY_SEPARATOR);
|
|
4694
|
+
}
|
|
4695
|
+
return [
|
|
4696
|
+
messages.length,
|
|
4697
|
+
isStreaming ? "streaming" : "idle",
|
|
4698
|
+
last.id,
|
|
4699
|
+
last.role,
|
|
4700
|
+
last.content ?? "",
|
|
4701
|
+
last.isStreaming ? "streaming" : "done",
|
|
4702
|
+
last.streamProgress ?? "",
|
|
4703
|
+
last.steps?.length ?? 0,
|
|
4704
|
+
last.errorDetails ?? "",
|
|
4705
|
+
promptFingerprint,
|
|
4706
|
+
notificationFingerprint
|
|
4707
|
+
].join(PROMPT_KEY_SEPARATOR);
|
|
4708
|
+
}, [isStreaming, messages, notifications, userActionPrompts]);
|
|
4709
|
+
const handleUserActionExpired = useCallback(
|
|
4710
|
+
(promptKey, userActionId) => {
|
|
4711
|
+
setExpiredPromptViewState((prev) => {
|
|
4712
|
+
if (prev[promptKey]) return prev;
|
|
4713
|
+
return {
|
|
4714
|
+
...prev,
|
|
4715
|
+
[promptKey]: { baseline: messageActivityFingerprint, hidden: false }
|
|
4716
|
+
};
|
|
4717
|
+
});
|
|
4718
|
+
if (!expiredUserActionIdsRef.current.has(userActionId)) {
|
|
4719
|
+
expiredUserActionIdsRef.current.add(userActionId);
|
|
4720
|
+
void onExpireUserAction?.(userActionId)?.catch(() => {
|
|
4721
|
+
});
|
|
4722
|
+
}
|
|
4723
|
+
},
|
|
4724
|
+
[messageActivityFingerprint, onExpireUserAction]
|
|
4725
|
+
);
|
|
4726
|
+
useEffect(() => {
|
|
4727
|
+
setExpiredPromptViewState((prev) => {
|
|
4728
|
+
let changed = false;
|
|
4729
|
+
const next = {};
|
|
4730
|
+
for (const [key, state] of Object.entries(prev)) {
|
|
4731
|
+
if (!state.hidden && state.baseline !== messageActivityFingerprint) {
|
|
4732
|
+
next[key] = { ...state, hidden: true };
|
|
4733
|
+
changed = true;
|
|
4734
|
+
} else {
|
|
4735
|
+
next[key] = state;
|
|
4736
|
+
}
|
|
4737
|
+
}
|
|
4738
|
+
return changed ? next : prev;
|
|
4739
|
+
});
|
|
4740
|
+
}, [messageActivityFingerprint]);
|
|
4741
|
+
useEffect(() => {
|
|
4742
|
+
const livePromptKeys = new Set((userActionPrompts ?? []).map(getPromptViewKey));
|
|
4743
|
+
const liveUserActionIds = new Set((userActionPrompts ?? []).map((p) => p.userActionId));
|
|
4744
|
+
for (const userActionId of expiredUserActionIdsRef.current) {
|
|
4745
|
+
if (!liveUserActionIds.has(userActionId)) {
|
|
4746
|
+
expiredUserActionIdsRef.current.delete(userActionId);
|
|
4747
|
+
}
|
|
4748
|
+
}
|
|
4749
|
+
setExpiredPromptViewState((prev) => {
|
|
4750
|
+
let changed = false;
|
|
4751
|
+
const next = {};
|
|
4752
|
+
for (const [key, state] of Object.entries(prev)) {
|
|
4753
|
+
if (livePromptKeys.has(key)) {
|
|
4754
|
+
next[key] = state;
|
|
4755
|
+
} else {
|
|
4756
|
+
changed = true;
|
|
4757
|
+
}
|
|
4758
|
+
}
|
|
4759
|
+
return changed ? next : prev;
|
|
4760
|
+
});
|
|
4761
|
+
}, [userActionPrompts]);
|
|
4762
|
+
const visibleUserActionPrompts = useMemo(
|
|
4763
|
+
() => userActionPrompts?.filter((prompt) => {
|
|
4764
|
+
const promptKey = getPromptViewKey(prompt);
|
|
4765
|
+
return !expiredPromptViewState[promptKey]?.hidden;
|
|
4766
|
+
}),
|
|
4767
|
+
[expiredPromptViewState, userActionPrompts]
|
|
4768
|
+
);
|
|
5197
4769
|
const pinToBottom = useCallback((behavior = "instant") => {
|
|
5198
4770
|
const el = scrollRef.current;
|
|
5199
4771
|
if (!el) return;
|
|
@@ -5234,25 +4806,17 @@ var MessageListV2 = forwardRef(
|
|
|
5234
4806
|
const nearBottom = distance <= SCROLL_THRESHOLD2;
|
|
5235
4807
|
isNearBottomRef.current = nearBottom;
|
|
5236
4808
|
setShowScrollBtn(!nearBottom);
|
|
4809
|
+
const sincePin = performance.now() - lastPinAtRef.current;
|
|
4810
|
+
if (sincePin < 250) return;
|
|
5237
4811
|
const scrolledUp = currentScrollTop < prevScrollTop - USER_SCROLL_UP_EPSILON;
|
|
5238
4812
|
if (scrolledUp) {
|
|
5239
4813
|
followingBottomRef.current = false;
|
|
5240
4814
|
pauseStickUntilUserMessageRef.current = true;
|
|
5241
|
-
|
|
5242
|
-
}
|
|
5243
|
-
const sincePin = performance.now() - lastPinAtRef.current;
|
|
5244
|
-
if (sincePin < 250) return;
|
|
5245
|
-
if (nearBottom) {
|
|
4815
|
+
} else if (nearBottom) {
|
|
5246
4816
|
followingBottomRef.current = true;
|
|
5247
4817
|
pauseStickUntilUserMessageRef.current = false;
|
|
5248
4818
|
}
|
|
5249
4819
|
}, [getDistanceFromBottom]);
|
|
5250
|
-
const handleWheel = useCallback((e) => {
|
|
5251
|
-
if (e.deltaY < 0) {
|
|
5252
|
-
followingBottomRef.current = false;
|
|
5253
|
-
pauseStickUntilUserMessageRef.current = true;
|
|
5254
|
-
}
|
|
5255
|
-
}, []);
|
|
5256
4820
|
useEffect(() => {
|
|
5257
4821
|
const prevCount = prevCountRef.current;
|
|
5258
4822
|
prevCountRef.current = messages.length;
|
|
@@ -5262,7 +4826,7 @@ var MessageListV2 = forwardRef(
|
|
|
5262
4826
|
pauseStickUntilUserMessageRef.current = false;
|
|
5263
4827
|
followingBottomRef.current = true;
|
|
5264
4828
|
requestAnimationFrame(() => scrollToBottom());
|
|
5265
|
-
} else if (!
|
|
4829
|
+
} else if (!pauseStickUntilUserMessageRef.current && followingBottomRef.current) {
|
|
5266
4830
|
requestAnimationFrame(() => scrollToBottom("instant"));
|
|
5267
4831
|
}
|
|
5268
4832
|
}
|
|
@@ -5271,16 +4835,27 @@ var MessageListV2 = forwardRef(
|
|
|
5271
4835
|
const inner = scrollInnerRef.current;
|
|
5272
4836
|
if (!inner) return;
|
|
5273
4837
|
const pinIfFollowing = () => {
|
|
5274
|
-
if (sidePanelOpenRef.current) return;
|
|
5275
4838
|
if (pauseStickUntilUserMessageRef.current) return;
|
|
5276
4839
|
if (!followingBottomRef.current) return;
|
|
5277
|
-
if (getDistanceFromBottom() > SCROLL_THRESHOLD2) return;
|
|
5278
4840
|
pinToBottom("instant");
|
|
5279
4841
|
};
|
|
5280
|
-
const ro = new ResizeObserver(
|
|
4842
|
+
const ro = new ResizeObserver(() => {
|
|
4843
|
+
pinIfFollowing();
|
|
4844
|
+
});
|
|
5281
4845
|
ro.observe(inner);
|
|
5282
|
-
|
|
5283
|
-
|
|
4846
|
+
const mo = new MutationObserver(() => {
|
|
4847
|
+
pinIfFollowing();
|
|
4848
|
+
});
|
|
4849
|
+
mo.observe(inner, {
|
|
4850
|
+
childList: true,
|
|
4851
|
+
subtree: true,
|
|
4852
|
+
characterData: true
|
|
4853
|
+
});
|
|
4854
|
+
return () => {
|
|
4855
|
+
ro.disconnect();
|
|
4856
|
+
mo.disconnect();
|
|
4857
|
+
};
|
|
4858
|
+
}, [pinToBottom]);
|
|
5284
4859
|
useEffect(() => {
|
|
5285
4860
|
if (messages.length > 0) {
|
|
5286
4861
|
setTimeout(() => scrollToBottom("instant"), 50);
|
|
@@ -5292,7 +4867,6 @@ var MessageListV2 = forwardRef(
|
|
|
5292
4867
|
{
|
|
5293
4868
|
ref: scrollRef,
|
|
5294
4869
|
onScroll: handleScroll,
|
|
5295
|
-
onWheel: handleWheel,
|
|
5296
4870
|
className: "payman-v2-message-scroll payman-v2-scrollbar",
|
|
5297
4871
|
children: /* @__PURE__ */ jsxs(
|
|
5298
4872
|
"div",
|
|
@@ -5306,7 +4880,6 @@ var MessageListV2 = forwardRef(
|
|
|
5306
4880
|
message,
|
|
5307
4881
|
onEdit: onEditUserMessage,
|
|
5308
4882
|
onRetry: onRetryUserMessage,
|
|
5309
|
-
onImageClick,
|
|
5310
4883
|
retryDisabled,
|
|
5311
4884
|
actions: messageActions?.userMessageActions
|
|
5312
4885
|
}
|
|
@@ -5329,16 +4902,20 @@ var MessageListV2 = forwardRef(
|
|
|
5329
4902
|
},
|
|
5330
4903
|
note.id
|
|
5331
4904
|
)),
|
|
5332
|
-
|
|
5333
|
-
|
|
5334
|
-
|
|
5335
|
-
|
|
5336
|
-
|
|
5337
|
-
|
|
5338
|
-
|
|
5339
|
-
|
|
5340
|
-
|
|
5341
|
-
|
|
4905
|
+
visibleUserActionPrompts?.map((prompt) => {
|
|
4906
|
+
const promptKey = getPromptViewKey(prompt);
|
|
4907
|
+
return /* @__PURE__ */ jsx(
|
|
4908
|
+
UserActionInline,
|
|
4909
|
+
{
|
|
4910
|
+
prompt,
|
|
4911
|
+
onSubmit: onSubmitUserAction ?? noop,
|
|
4912
|
+
onCancel: onCancelUserAction ?? noop,
|
|
4913
|
+
onResend: onResendUserAction ?? noop,
|
|
4914
|
+
onExpired: () => handleUserActionExpired(promptKey, prompt.userActionId)
|
|
4915
|
+
},
|
|
4916
|
+
promptKey
|
|
4917
|
+
);
|
|
4918
|
+
})
|
|
5342
4919
|
]
|
|
5343
4920
|
}
|
|
5344
4921
|
)
|
|
@@ -5368,121 +4945,11 @@ var MessageListV2 = forwardRef(
|
|
|
5368
4945
|
] });
|
|
5369
4946
|
}
|
|
5370
4947
|
);
|
|
5371
|
-
function FilePreviewModal({ src, name, onClose }) {
|
|
5372
|
-
const [isMounted, setIsMounted] = useState(false);
|
|
5373
|
-
const [isLoaded, setIsLoaded] = useState(false);
|
|
5374
|
-
useEffect(() => {
|
|
5375
|
-
setIsMounted(true);
|
|
5376
|
-
return () => setIsMounted(false);
|
|
5377
|
-
}, []);
|
|
5378
|
-
useEffect(() => {
|
|
5379
|
-
setIsLoaded(false);
|
|
5380
|
-
}, [src]);
|
|
5381
|
-
const handleKeyDown = useCallback(
|
|
5382
|
-
(e) => {
|
|
5383
|
-
if (e.key === "Escape") onClose();
|
|
5384
|
-
},
|
|
5385
|
-
[onClose]
|
|
5386
|
-
);
|
|
5387
|
-
useEffect(() => {
|
|
5388
|
-
if (!src || typeof document === "undefined") return;
|
|
5389
|
-
document.addEventListener("keydown", handleKeyDown);
|
|
5390
|
-
const prev = document.body.style.overflow;
|
|
5391
|
-
document.body.style.overflow = "hidden";
|
|
5392
|
-
return () => {
|
|
5393
|
-
document.removeEventListener("keydown", handleKeyDown);
|
|
5394
|
-
document.body.style.overflow = prev;
|
|
5395
|
-
};
|
|
5396
|
-
}, [src, handleKeyDown]);
|
|
5397
|
-
if (!isMounted || typeof document === "undefined") return null;
|
|
5398
|
-
return createPortal(
|
|
5399
|
-
/* @__PURE__ */ jsx(AnimatePresence, { children: src ? /* @__PURE__ */ jsxs(
|
|
5400
|
-
motion.div,
|
|
5401
|
-
{
|
|
5402
|
-
className: "payman-v2-file-preview-overlay",
|
|
5403
|
-
initial: { opacity: 0 },
|
|
5404
|
-
animate: { opacity: 1 },
|
|
5405
|
-
exit: { opacity: 0 },
|
|
5406
|
-
transition: { duration: 0.18 },
|
|
5407
|
-
onClick: onClose,
|
|
5408
|
-
role: "dialog",
|
|
5409
|
-
"aria-modal": "true",
|
|
5410
|
-
"aria-label": `Preview: ${name}`,
|
|
5411
|
-
children: [
|
|
5412
|
-
/* @__PURE__ */ jsx(
|
|
5413
|
-
"button",
|
|
5414
|
-
{
|
|
5415
|
-
type: "button",
|
|
5416
|
-
className: "payman-v2-file-preview-close",
|
|
5417
|
-
"aria-label": "Close preview",
|
|
5418
|
-
onClick: (e) => {
|
|
5419
|
-
e.stopPropagation();
|
|
5420
|
-
onClose();
|
|
5421
|
-
},
|
|
5422
|
-
children: /* @__PURE__ */ jsx(X, { size: 18, strokeWidth: 2 })
|
|
5423
|
-
}
|
|
5424
|
-
),
|
|
5425
|
-
/* @__PURE__ */ jsx(
|
|
5426
|
-
motion.div,
|
|
5427
|
-
{
|
|
5428
|
-
className: "payman-v2-file-preview-inner",
|
|
5429
|
-
initial: { scale: 0.93, opacity: 0 },
|
|
5430
|
-
animate: { scale: isLoaded ? 1 : 0.93, opacity: isLoaded ? 1 : 0 },
|
|
5431
|
-
exit: { scale: 0.93, opacity: 0 },
|
|
5432
|
-
transition: { duration: 0.2 },
|
|
5433
|
-
onClick: (e) => e.stopPropagation(),
|
|
5434
|
-
children: /* @__PURE__ */ jsx(
|
|
5435
|
-
"img",
|
|
5436
|
-
{
|
|
5437
|
-
src,
|
|
5438
|
-
alt: name,
|
|
5439
|
-
className: "payman-v2-file-preview-img",
|
|
5440
|
-
draggable: false,
|
|
5441
|
-
onLoad: () => setIsLoaded(true)
|
|
5442
|
-
}
|
|
5443
|
-
)
|
|
5444
|
-
}
|
|
5445
|
-
)
|
|
5446
|
-
]
|
|
5447
|
-
},
|
|
5448
|
-
"file-preview"
|
|
5449
|
-
) : null }),
|
|
5450
|
-
document.body
|
|
5451
|
-
);
|
|
5452
|
-
}
|
|
5453
|
-
function normalizeExtension(ext) {
|
|
5454
|
-
return ext.replace(/^\./, "").toLowerCase();
|
|
5455
|
-
}
|
|
5456
|
-
function extOf(filename) {
|
|
5457
|
-
return filename.split(".").pop()?.toLowerCase() ?? "";
|
|
5458
|
-
}
|
|
5459
|
-
function isAllowedImage(file, allowedExtensions) {
|
|
5460
|
-
const allowed = new Set(allowedExtensions.map(normalizeExtension));
|
|
5461
|
-
const ext = extOf(file.name);
|
|
5462
|
-
if (allowed.has(ext)) return true;
|
|
5463
|
-
if (!file.type.startsWith("image/")) return false;
|
|
5464
|
-
const mimeSubtype = file.type.slice("image/".length).toLowerCase();
|
|
5465
|
-
return allowed.has(mimeSubtype) || mimeSubtype === "jpeg" && allowed.has("jpg");
|
|
5466
|
-
}
|
|
5467
|
-
function isAllowedDocument(file, allowedExtensions) {
|
|
5468
|
-
const allowed = new Set(allowedExtensions.map(normalizeExtension));
|
|
5469
|
-
return allowed.has(extOf(file.name));
|
|
5470
|
-
}
|
|
5471
|
-
function fileTypeLabel(file, kind) {
|
|
5472
|
-
if (kind === "image") return "Image";
|
|
5473
|
-
const ext = extOf(file.name);
|
|
5474
|
-
return ext ? ext.toUpperCase() : "Document";
|
|
5475
|
-
}
|
|
5476
4948
|
var ChatInputV2 = forwardRef(
|
|
5477
4949
|
function ChatInputV22({
|
|
5478
4950
|
onSend,
|
|
5479
4951
|
disabled = false,
|
|
5480
4952
|
isStreaming = false,
|
|
5481
|
-
isUploadingAttachments = false,
|
|
5482
|
-
attachmentsReady = true,
|
|
5483
|
-
hasAttachmentUploadErrors = false,
|
|
5484
|
-
attachmentUploadStatusById = {},
|
|
5485
|
-
uploadedAttachmentPayloads = [],
|
|
5486
4953
|
placeholder = "Reply...",
|
|
5487
4954
|
enableVoice = false,
|
|
5488
4955
|
voiceAvailable = false,
|
|
@@ -5496,13 +4963,6 @@ var ChatInputV2 = forwardRef(
|
|
|
5496
4963
|
showAttachFileButton = true,
|
|
5497
4964
|
onUploadImageClick,
|
|
5498
4965
|
onAttachFileClick,
|
|
5499
|
-
allowedImageExtensions = ["png", "jpg", "jpeg", "gif", "webp"],
|
|
5500
|
-
allowedFileExtensions = ["pdf", "docx", "xlsx", "xls"],
|
|
5501
|
-
maxCount,
|
|
5502
|
-
maxFileBytes,
|
|
5503
|
-
maxTotalBytes,
|
|
5504
|
-
onFilesChange,
|
|
5505
|
-
onAttachmentsChange,
|
|
5506
4966
|
editingMessageId = null,
|
|
5507
4967
|
onClearEditing,
|
|
5508
4968
|
analysisMode,
|
|
@@ -5516,133 +4976,14 @@ var ChatInputV2 = forwardRef(
|
|
|
5516
4976
|
const [selectedCommandIndex, setSelectedCommandIndex] = useState(0);
|
|
5517
4977
|
const [inlineHint, setInlineHint] = useState(null);
|
|
5518
4978
|
const [commandMenuDismissed, setCommandMenuDismissed] = useState(false);
|
|
5519
|
-
const [attachedFiles, setAttachedFiles] = useState([]);
|
|
5520
|
-
const [previewFile, setPreviewFile] = useState(null);
|
|
5521
|
-
const [isSending, setIsSending] = useState(false);
|
|
5522
4979
|
const textareaRef = useRef(null);
|
|
5523
4980
|
const actionsRef = useRef(null);
|
|
5524
|
-
const imageInputRef = useRef(null);
|
|
5525
|
-
const fileInputRef = useRef(null);
|
|
5526
4981
|
const preRecordTextRef = useRef("");
|
|
5527
4982
|
const voiceTooltipTimerRef = useRef(
|
|
5528
4983
|
null
|
|
5529
4984
|
);
|
|
5530
4985
|
const voiceDraftSyncActiveRef = useRef(false);
|
|
5531
|
-
const
|
|
5532
|
-
useEffect(() => {
|
|
5533
|
-
return () => {
|
|
5534
|
-
attachedFiles.forEach((f) => URL.revokeObjectURL(f.objectUrl));
|
|
5535
|
-
};
|
|
5536
|
-
}, []);
|
|
5537
|
-
const notifyAttachmentList = useCallback(
|
|
5538
|
-
(files) => {
|
|
5539
|
-
onFilesChange?.(files.map((f) => f.file));
|
|
5540
|
-
onAttachmentsChange?.(files.map((f) => ({ id: f.id, file: f.file })));
|
|
5541
|
-
},
|
|
5542
|
-
[onAttachmentsChange, onFilesChange]
|
|
5543
|
-
);
|
|
5544
|
-
const clearAttachmentsFromInput = useCallback(() => {
|
|
5545
|
-
setAttachedFiles((prev) => {
|
|
5546
|
-
prev.forEach((f) => URL.revokeObjectURL(f.objectUrl));
|
|
5547
|
-
return [];
|
|
5548
|
-
});
|
|
5549
|
-
setPreviewFile(null);
|
|
5550
|
-
onFilesChange?.([]);
|
|
5551
|
-
onAttachmentsChange?.([]);
|
|
5552
|
-
}, [onAttachmentsChange, onFilesChange]);
|
|
5553
|
-
const addFiles = useCallback(
|
|
5554
|
-
(incoming, source) => {
|
|
5555
|
-
const isImage = source === "image";
|
|
5556
|
-
const allowedExtensions = isImage ? allowedImageExtensions : allowedFileExtensions;
|
|
5557
|
-
const isAllowed = isImage ? isAllowedImage : isAllowedDocument;
|
|
5558
|
-
const kindLabel = isImage ? "image" : "document";
|
|
5559
|
-
setAttachedFiles((prev) => {
|
|
5560
|
-
const accepted = [];
|
|
5561
|
-
let rejectedType = false;
|
|
5562
|
-
let hitCountLimit = false;
|
|
5563
|
-
let hitFileSizeLimit = false;
|
|
5564
|
-
let hitTotalSizeLimit = false;
|
|
5565
|
-
let oversizedName = "";
|
|
5566
|
-
const currentTotalBytes = prev.reduce(
|
|
5567
|
-
(sum, item) => sum + item.file.size,
|
|
5568
|
-
0
|
|
5569
|
-
);
|
|
5570
|
-
let addedBytes = 0;
|
|
5571
|
-
for (const file of incoming) {
|
|
5572
|
-
if (!isAllowed(file, allowedExtensions)) {
|
|
5573
|
-
rejectedType = true;
|
|
5574
|
-
continue;
|
|
5575
|
-
}
|
|
5576
|
-
if (maxFileBytes != null && file.size > maxFileBytes) {
|
|
5577
|
-
hitFileSizeLimit = true;
|
|
5578
|
-
oversizedName = file.name;
|
|
5579
|
-
continue;
|
|
5580
|
-
}
|
|
5581
|
-
if (maxTotalBytes != null && currentTotalBytes + addedBytes + file.size > maxTotalBytes) {
|
|
5582
|
-
hitTotalSizeLimit = true;
|
|
5583
|
-
break;
|
|
5584
|
-
}
|
|
5585
|
-
if (maxCount != null && prev.length + accepted.length >= maxCount) {
|
|
5586
|
-
hitCountLimit = true;
|
|
5587
|
-
break;
|
|
5588
|
-
}
|
|
5589
|
-
accepted.push({
|
|
5590
|
-
id: `${Date.now()}-${Math.random()}`,
|
|
5591
|
-
file,
|
|
5592
|
-
kind: source,
|
|
5593
|
-
objectUrl: URL.createObjectURL(file)
|
|
5594
|
-
});
|
|
5595
|
-
addedBytes += file.size;
|
|
5596
|
-
}
|
|
5597
|
-
if (rejectedType) {
|
|
5598
|
-
setInlineHint(
|
|
5599
|
-
`Unsupported ${kindLabel} type. Allowed: ${allowedExtensions.map(normalizeExtension).join(", ")}.`
|
|
5600
|
-
);
|
|
5601
|
-
} else if (hitFileSizeLimit) {
|
|
5602
|
-
setInlineHint(
|
|
5603
|
-
maxFileBytes != null ? `"${oversizedName}" exceeds the ${formatAttachmentBytes(maxFileBytes)} per-file limit.` : "File exceeds the maximum allowed size."
|
|
5604
|
-
);
|
|
5605
|
-
} else if (hitTotalSizeLimit) {
|
|
5606
|
-
setInlineHint(
|
|
5607
|
-
maxTotalBytes != null ? `Total attachment size would exceed ${formatAttachmentBytes(maxTotalBytes)}.` : "Total attachment size exceeds the limit."
|
|
5608
|
-
);
|
|
5609
|
-
} else if (hitCountLimit) {
|
|
5610
|
-
setInlineHint(
|
|
5611
|
-
maxCount === 1 ? "Only 1 attachment is allowed per message." : `Maximum ${maxCount} attachments allowed per message.`
|
|
5612
|
-
);
|
|
5613
|
-
}
|
|
5614
|
-
if (accepted.length === 0) return prev;
|
|
5615
|
-
const updated = [...prev, ...accepted];
|
|
5616
|
-
notifyAttachmentList(updated);
|
|
5617
|
-
return updated;
|
|
5618
|
-
});
|
|
5619
|
-
},
|
|
5620
|
-
[
|
|
5621
|
-
allowedFileExtensions,
|
|
5622
|
-
allowedImageExtensions,
|
|
5623
|
-
maxCount,
|
|
5624
|
-
maxFileBytes,
|
|
5625
|
-
maxTotalBytes,
|
|
5626
|
-
notifyAttachmentList
|
|
5627
|
-
]
|
|
5628
|
-
);
|
|
5629
|
-
const removeFile = useCallback(
|
|
5630
|
-
(id) => {
|
|
5631
|
-
setAttachedFiles((prev) => {
|
|
5632
|
-
const target = prev.find((f) => f.id === id);
|
|
5633
|
-
if (target) URL.revokeObjectURL(target.objectUrl);
|
|
5634
|
-
const updated = prev.filter((f) => f.id !== id);
|
|
5635
|
-
notifyAttachmentList(updated);
|
|
5636
|
-
return updated;
|
|
5637
|
-
});
|
|
5638
|
-
setPreviewFile((p) => p?.id === id ? null : p);
|
|
5639
|
-
},
|
|
5640
|
-
[notifyAttachmentList]
|
|
5641
|
-
);
|
|
5642
|
-
const imageAccept = allowedImageExtensions.map((e) => `.${e.replace(/^\./, "")}`).join(",");
|
|
5643
|
-
const fileAccept = allowedFileExtensions.map((e) => `.${e.replace(/^\./, "")}`).join(",");
|
|
5644
|
-
const isInputBusy = isSending || isUploadingAttachments;
|
|
5645
|
-
const isInputLocked = disabled || isRecording || isInputBusy;
|
|
4986
|
+
const isInputLocked = disabled || isRecording;
|
|
5646
4987
|
const hasAttachmentOptions = showUploadImageButton || showAttachFileButton;
|
|
5647
4988
|
const showAttachmentMenuButton = showAttachmentButton && hasAttachmentOptions;
|
|
5648
4989
|
const showVoiceButton = enableVoice && onVoicePress != null;
|
|
@@ -5682,10 +5023,9 @@ var ChatInputV2 = forwardRef(
|
|
|
5682
5023
|
const end = message.length;
|
|
5683
5024
|
textarea.setSelectionRange(end, end);
|
|
5684
5025
|
});
|
|
5685
|
-
}
|
|
5686
|
-
clearAttachments: clearAttachmentsFromInput
|
|
5026
|
+
}
|
|
5687
5027
|
}),
|
|
5688
|
-
[disabled
|
|
5028
|
+
[disabled]
|
|
5689
5029
|
);
|
|
5690
5030
|
useEffect(() => {
|
|
5691
5031
|
if (!showActions) return;
|
|
@@ -5719,23 +5059,8 @@ var ChatInputV2 = forwardRef(
|
|
|
5719
5059
|
const separator = base && !base.endsWith(" ") && transcribedText ? " " : "";
|
|
5720
5060
|
setValue(`${base}${separator}${transcribedText}`);
|
|
5721
5061
|
}, [isRecording, transcribedText]);
|
|
5722
|
-
|
|
5723
|
-
if (
|
|
5724
|
-
if (status === "error") return "Upload failed";
|
|
5725
|
-
return fileTypeLabel(file, kind);
|
|
5726
|
-
}
|
|
5727
|
-
const handleSend = useCallback(async () => {
|
|
5728
|
-
const hasText = value.trim().length > 0;
|
|
5729
|
-
const hasFiles = attachedFiles.length > 0;
|
|
5730
|
-
if (!hasText && !hasFiles || disabled || isSending || isUploadingAttachments) return;
|
|
5731
|
-
if (hasFiles && !attachmentsReady) {
|
|
5732
|
-
setInlineHint("Waiting for attachments to finish uploading.");
|
|
5733
|
-
return;
|
|
5734
|
-
}
|
|
5735
|
-
if (hasFiles && hasAttachmentUploadErrors) {
|
|
5736
|
-
setInlineHint("Remove or re-add attachments that failed to upload.");
|
|
5737
|
-
return;
|
|
5738
|
-
}
|
|
5062
|
+
const handleSend = useCallback(() => {
|
|
5063
|
+
if (!value.trim() || disabled) return;
|
|
5739
5064
|
const commandHint = getSlashCommandValidationHint(value);
|
|
5740
5065
|
if (commandHint) {
|
|
5741
5066
|
setInlineHint(commandHint);
|
|
@@ -5745,38 +5070,15 @@ var ChatInputV2 = forwardRef(
|
|
|
5745
5070
|
preRecordTextRef.current = "";
|
|
5746
5071
|
setInlineHint(null);
|
|
5747
5072
|
onClearEditing?.();
|
|
5748
|
-
|
|
5749
|
-
const filesToSend = attachedFiles.map((f) => f.file);
|
|
5750
|
-
const attachmentsToSend = [...uploadedAttachmentPayloads];
|
|
5073
|
+
onSend(value.trim());
|
|
5751
5074
|
setValue("");
|
|
5752
|
-
clearAttachmentsFromInput();
|
|
5753
5075
|
requestAnimationFrame(() => {
|
|
5754
5076
|
if (textareaRef.current) {
|
|
5755
5077
|
textareaRef.current.style.height = "auto";
|
|
5756
5078
|
textareaRef.current.focus();
|
|
5757
5079
|
}
|
|
5758
5080
|
});
|
|
5759
|
-
|
|
5760
|
-
try {
|
|
5761
|
-
await onSend(textToSend, filesToSend, attachmentsToSend);
|
|
5762
|
-
} catch {
|
|
5763
|
-
setInlineHint("Failed to send message. Please try again.");
|
|
5764
|
-
} finally {
|
|
5765
|
-
setIsSending(false);
|
|
5766
|
-
}
|
|
5767
|
-
}, [
|
|
5768
|
-
value,
|
|
5769
|
-
attachedFiles,
|
|
5770
|
-
uploadedAttachmentPayloads,
|
|
5771
|
-
disabled,
|
|
5772
|
-
isSending,
|
|
5773
|
-
isUploadingAttachments,
|
|
5774
|
-
attachmentsReady,
|
|
5775
|
-
hasAttachmentUploadErrors,
|
|
5776
|
-
onClearEditing,
|
|
5777
|
-
onSend,
|
|
5778
|
-
clearAttachmentsFromInput
|
|
5779
|
-
]);
|
|
5081
|
+
}, [value, disabled, onClearEditing, onSend]);
|
|
5780
5082
|
const selectCommand = useCallback(
|
|
5781
5083
|
(command) => {
|
|
5782
5084
|
const insertText = command.insertText ?? `${command.name} `;
|
|
@@ -5821,30 +5123,18 @@ var ChatInputV2 = forwardRef(
|
|
|
5821
5123
|
}
|
|
5822
5124
|
if (e.key === "Enter" && !e.shiftKey) {
|
|
5823
5125
|
e.preventDefault();
|
|
5824
|
-
if (isStreaming
|
|
5825
|
-
|
|
5126
|
+
if (isStreaming) return;
|
|
5127
|
+
handleSend();
|
|
5826
5128
|
}
|
|
5827
5129
|
};
|
|
5828
5130
|
const handleUploadImageClick = () => {
|
|
5829
|
-
imageInputRef.current?.click();
|
|
5830
5131
|
onUploadImageClick?.();
|
|
5831
5132
|
setShowActions(false);
|
|
5832
5133
|
};
|
|
5833
5134
|
const handleAttachFileClick = () => {
|
|
5834
|
-
fileInputRef.current?.click();
|
|
5835
5135
|
onAttachFileClick?.();
|
|
5836
5136
|
setShowActions(false);
|
|
5837
5137
|
};
|
|
5838
|
-
const handleImageFilesSelected = (e) => {
|
|
5839
|
-
const files = Array.from(e.target.files ?? []);
|
|
5840
|
-
if (files.length) addFiles(files, "image");
|
|
5841
|
-
e.target.value = "";
|
|
5842
|
-
};
|
|
5843
|
-
const handleDocFilesSelected = (e) => {
|
|
5844
|
-
const files = Array.from(e.target.files ?? []);
|
|
5845
|
-
if (files.length) addFiles(files, "file");
|
|
5846
|
-
e.target.value = "";
|
|
5847
|
-
};
|
|
5848
5138
|
const hideVoiceTooltip = useCallback(() => {
|
|
5849
5139
|
if (voiceTooltipTimerRef.current) {
|
|
5850
5140
|
clearTimeout(voiceTooltipTimerRef.current);
|
|
@@ -5872,39 +5162,9 @@ var ChatInputV2 = forwardRef(
|
|
|
5872
5162
|
}
|
|
5873
5163
|
onVoicePress();
|
|
5874
5164
|
};
|
|
5875
|
-
const canSend =
|
|
5876
|
-
const sendDisabled = !canSend || isStreaming
|
|
5165
|
+
const canSend = value.trim().length > 0 && !disabled;
|
|
5166
|
+
const sendDisabled = !canSend || isStreaming;
|
|
5877
5167
|
return /* @__PURE__ */ jsxs("div", { className: "payman-v2-input-container", children: [
|
|
5878
|
-
/* @__PURE__ */ jsx(
|
|
5879
|
-
"input",
|
|
5880
|
-
{
|
|
5881
|
-
ref: imageInputRef,
|
|
5882
|
-
type: "file",
|
|
5883
|
-
accept: imageAccept,
|
|
5884
|
-
multiple: maxCount == null || maxCount > 1,
|
|
5885
|
-
style: { display: "none" },
|
|
5886
|
-
onChange: handleImageFilesSelected
|
|
5887
|
-
}
|
|
5888
|
-
),
|
|
5889
|
-
/* @__PURE__ */ jsx(
|
|
5890
|
-
"input",
|
|
5891
|
-
{
|
|
5892
|
-
ref: fileInputRef,
|
|
5893
|
-
type: "file",
|
|
5894
|
-
accept: fileAccept,
|
|
5895
|
-
multiple: maxCount == null || maxCount > 1,
|
|
5896
|
-
style: { display: "none" },
|
|
5897
|
-
onChange: handleDocFilesSelected
|
|
5898
|
-
}
|
|
5899
|
-
),
|
|
5900
|
-
/* @__PURE__ */ jsx(
|
|
5901
|
-
FilePreviewModal,
|
|
5902
|
-
{
|
|
5903
|
-
src: previewFile?.kind === "image" ? previewFile.objectUrl : null,
|
|
5904
|
-
name: previewFile?.file.name ?? "",
|
|
5905
|
-
onClose: () => setPreviewFile(null)
|
|
5906
|
-
}
|
|
5907
|
-
),
|
|
5908
5168
|
/* @__PURE__ */ jsx(AnimatePresence, { children: showCommandSuggestions && /* @__PURE__ */ jsx(
|
|
5909
5169
|
motion.div,
|
|
5910
5170
|
{
|
|
@@ -5943,115 +5203,6 @@ var ChatInputV2 = forwardRef(
|
|
|
5943
5203
|
),
|
|
5944
5204
|
children: [
|
|
5945
5205
|
/* @__PURE__ */ jsxs("div", { className: "payman-v2-input-body", children: [
|
|
5946
|
-
/* @__PURE__ */ jsx(AnimatePresence, { initial: false, children: attachedFiles.length > 0 && /* @__PURE__ */ jsx(
|
|
5947
|
-
motion.div,
|
|
5948
|
-
{
|
|
5949
|
-
initial: { opacity: 0, height: 0 },
|
|
5950
|
-
animate: { opacity: 1, height: "auto" },
|
|
5951
|
-
exit: { opacity: 0, height: 0 },
|
|
5952
|
-
transition: { duration: 0.15, ease: "easeOut" },
|
|
5953
|
-
className: "payman-v2-file-preview",
|
|
5954
|
-
children: attachedFiles.map((af) => {
|
|
5955
|
-
const uploadStatus = attachmentUploadStatusById[af.id];
|
|
5956
|
-
const isUploadingFile = uploadStatus === "uploading";
|
|
5957
|
-
const hasUploadError = uploadStatus === "error";
|
|
5958
|
-
return /* @__PURE__ */ jsxs("div", { className: "payman-v2-file-preview-item", children: [
|
|
5959
|
-
af.kind === "image" ? /* @__PURE__ */ jsxs(
|
|
5960
|
-
"button",
|
|
5961
|
-
{
|
|
5962
|
-
type: "button",
|
|
5963
|
-
className: cn(
|
|
5964
|
-
"payman-v2-file-preview-shell payman-v2-file-preview-shell-clickable",
|
|
5965
|
-
hasUploadError && "payman-v2-file-preview-shell-error"
|
|
5966
|
-
),
|
|
5967
|
-
onClick: () => setPreviewFile(af),
|
|
5968
|
-
disabled: isUploadingFile,
|
|
5969
|
-
"aria-label": `Preview ${af.file.name}`,
|
|
5970
|
-
children: [
|
|
5971
|
-
/* @__PURE__ */ jsxs("div", { className: "payman-v2-file-preview-thumb", children: [
|
|
5972
|
-
/* @__PURE__ */ jsx(
|
|
5973
|
-
"img",
|
|
5974
|
-
{
|
|
5975
|
-
src: af.objectUrl,
|
|
5976
|
-
alt: "",
|
|
5977
|
-
draggable: false
|
|
5978
|
-
}
|
|
5979
|
-
),
|
|
5980
|
-
isUploadingFile && /* @__PURE__ */ jsx("div", { className: "payman-v2-file-preview-uploading", children: /* @__PURE__ */ jsx(Loader2, { size: 14, className: "payman-v2-spin" }) })
|
|
5981
|
-
] }),
|
|
5982
|
-
/* @__PURE__ */ jsxs("div", { className: "payman-v2-file-preview-info", children: [
|
|
5983
|
-
/* @__PURE__ */ jsx("p", { className: "payman-v2-file-preview-name", children: af.file.name }),
|
|
5984
|
-
/* @__PURE__ */ jsx("p", { className: "payman-v2-file-preview-type", children: uploadStatusLabel(uploadStatus, af.file, af.kind) })
|
|
5985
|
-
] })
|
|
5986
|
-
]
|
|
5987
|
-
}
|
|
5988
|
-
) : isPdfFile(af.file) ? /* @__PURE__ */ jsxs(
|
|
5989
|
-
"button",
|
|
5990
|
-
{
|
|
5991
|
-
type: "button",
|
|
5992
|
-
className: cn(
|
|
5993
|
-
"payman-v2-file-preview-shell payman-v2-file-preview-shell-clickable",
|
|
5994
|
-
hasUploadError && "payman-v2-file-preview-shell-error"
|
|
5995
|
-
),
|
|
5996
|
-
onClick: () => chatContext?.openPdfSheet(
|
|
5997
|
-
af.objectUrl,
|
|
5998
|
-
af.file.name
|
|
5999
|
-
),
|
|
6000
|
-
disabled: isUploadingFile,
|
|
6001
|
-
"aria-label": `Preview ${af.file.name}`,
|
|
6002
|
-
children: [
|
|
6003
|
-
/* @__PURE__ */ jsx("div", { className: "payman-v2-file-preview-thumb", children: isUploadingFile ? /* @__PURE__ */ jsx(Loader2, { size: 16, className: "payman-v2-spin payman-v2-file-preview-doc-icon" }) : /* @__PURE__ */ jsx(
|
|
6004
|
-
FileText,
|
|
6005
|
-
{
|
|
6006
|
-
size: 16,
|
|
6007
|
-
strokeWidth: 1.75,
|
|
6008
|
-
className: "payman-v2-file-preview-doc-icon"
|
|
6009
|
-
}
|
|
6010
|
-
) }),
|
|
6011
|
-
/* @__PURE__ */ jsxs("div", { className: "payman-v2-file-preview-info", children: [
|
|
6012
|
-
/* @__PURE__ */ jsx("p", { className: "payman-v2-file-preview-name", children: af.file.name }),
|
|
6013
|
-
/* @__PURE__ */ jsx("p", { className: "payman-v2-file-preview-type", children: uploadStatusLabel(uploadStatus, af.file, af.kind) })
|
|
6014
|
-
] })
|
|
6015
|
-
]
|
|
6016
|
-
}
|
|
6017
|
-
) : /* @__PURE__ */ jsxs(
|
|
6018
|
-
"div",
|
|
6019
|
-
{
|
|
6020
|
-
className: cn(
|
|
6021
|
-
"payman-v2-file-preview-shell",
|
|
6022
|
-
hasUploadError && "payman-v2-file-preview-shell-error"
|
|
6023
|
-
),
|
|
6024
|
-
children: [
|
|
6025
|
-
/* @__PURE__ */ jsx("div", { className: "payman-v2-file-preview-thumb", children: isUploadingFile ? /* @__PURE__ */ jsx(Loader2, { size: 16, className: "payman-v2-spin payman-v2-file-preview-doc-icon" }) : /* @__PURE__ */ jsx(
|
|
6026
|
-
FileText,
|
|
6027
|
-
{
|
|
6028
|
-
size: 16,
|
|
6029
|
-
strokeWidth: 1.75,
|
|
6030
|
-
className: "payman-v2-file-preview-doc-icon"
|
|
6031
|
-
}
|
|
6032
|
-
) }),
|
|
6033
|
-
/* @__PURE__ */ jsxs("div", { className: "payman-v2-file-preview-info", children: [
|
|
6034
|
-
/* @__PURE__ */ jsx("p", { className: "payman-v2-file-preview-name", children: af.file.name }),
|
|
6035
|
-
/* @__PURE__ */ jsx("p", { className: "payman-v2-file-preview-type", children: uploadStatusLabel(uploadStatus, af.file, af.kind) })
|
|
6036
|
-
] })
|
|
6037
|
-
]
|
|
6038
|
-
}
|
|
6039
|
-
),
|
|
6040
|
-
/* @__PURE__ */ jsx(
|
|
6041
|
-
"button",
|
|
6042
|
-
{
|
|
6043
|
-
type: "button",
|
|
6044
|
-
className: "payman-v2-file-preview-remove",
|
|
6045
|
-
onClick: () => removeFile(af.id),
|
|
6046
|
-
"aria-label": `Remove ${af.file.name}`,
|
|
6047
|
-
children: /* @__PURE__ */ jsx(X, { size: 12, strokeWidth: 2.5 })
|
|
6048
|
-
}
|
|
6049
|
-
)
|
|
6050
|
-
] }, af.id);
|
|
6051
|
-
})
|
|
6052
|
-
},
|
|
6053
|
-
"file-preview"
|
|
6054
|
-
) }),
|
|
6055
5206
|
/* @__PURE__ */ jsx(AnimatePresence, { initial: false, children: editingMessageId && /* @__PURE__ */ jsxs(
|
|
6056
5207
|
motion.div,
|
|
6057
5208
|
{
|
|
@@ -6283,13 +5434,13 @@ var ChatInputV2 = forwardRef(
|
|
|
6283
5434
|
"button",
|
|
6284
5435
|
{
|
|
6285
5436
|
type: "button",
|
|
6286
|
-
onClick:
|
|
5437
|
+
onClick: handleSend,
|
|
6287
5438
|
disabled: sendDisabled,
|
|
6288
5439
|
className: cn(
|
|
6289
5440
|
"payman-v2-input-send-btn",
|
|
6290
5441
|
sendDisabled && "payman-v2-input-send-btn-disabled"
|
|
6291
5442
|
),
|
|
6292
|
-
"aria-label":
|
|
5443
|
+
"aria-label": "Send message",
|
|
6293
5444
|
children: /* @__PURE__ */ jsx(
|
|
6294
5445
|
ArrowUp,
|
|
6295
5446
|
{
|
|
@@ -6824,389 +5975,6 @@ function TimelineBars({
|
|
|
6824
5975
|
)
|
|
6825
5976
|
] });
|
|
6826
5977
|
}
|
|
6827
|
-
|
|
6828
|
-
// src/utils/pdfPreview.ts
|
|
6829
|
-
var PdfPreviewError = class extends Error {
|
|
6830
|
-
constructor(kind, title, userMessage) {
|
|
6831
|
-
super(userMessage);
|
|
6832
|
-
__publicField(this, "kind");
|
|
6833
|
-
__publicField(this, "title");
|
|
6834
|
-
__publicField(this, "userMessage");
|
|
6835
|
-
this.name = "PdfPreviewError";
|
|
6836
|
-
this.kind = kind;
|
|
6837
|
-
this.title = title;
|
|
6838
|
-
this.userMessage = userMessage;
|
|
6839
|
-
}
|
|
6840
|
-
};
|
|
6841
|
-
function classifyErrorBody(body, status) {
|
|
6842
|
-
const text = body.replace(/\s+/g, " ").trim();
|
|
6843
|
-
if (/signed expiry time|must be after signed start time|expired|expir/i.test(text)) {
|
|
6844
|
-
return new PdfPreviewError(
|
|
6845
|
-
"expired",
|
|
6846
|
-
"Link expired",
|
|
6847
|
-
"This download link has expired. Ask the assistant to generate a new copy of the document."
|
|
6848
|
-
);
|
|
6849
|
-
}
|
|
6850
|
-
if (/AuthenticationFailed|authorization header|formed correctly including the signature/i.test(
|
|
6851
|
-
text
|
|
6852
|
-
)) {
|
|
6853
|
-
return new PdfPreviewError(
|
|
6854
|
-
"forbidden",
|
|
6855
|
-
"Link no longer valid",
|
|
6856
|
-
"This preview link is no longer valid. Request a fresh download link and try again."
|
|
6857
|
-
);
|
|
6858
|
-
}
|
|
6859
|
-
if (status === 404 || /BlobNotFound|ResourceNotFound|The specified blob does not exist/i.test(text)) {
|
|
6860
|
-
return new PdfPreviewError(
|
|
6861
|
-
"not_found",
|
|
6862
|
-
"Document not found",
|
|
6863
|
-
"The file is no longer available. It may have been removed or the link is incorrect."
|
|
6864
|
-
);
|
|
6865
|
-
}
|
|
6866
|
-
if (status === 403) {
|
|
6867
|
-
return new PdfPreviewError(
|
|
6868
|
-
"forbidden",
|
|
6869
|
-
"Can't open document",
|
|
6870
|
-
"You may not have access to this file, or the link has expired."
|
|
6871
|
-
);
|
|
6872
|
-
}
|
|
6873
|
-
if (status === 401) {
|
|
6874
|
-
return new PdfPreviewError(
|
|
6875
|
-
"forbidden",
|
|
6876
|
-
"Access denied",
|
|
6877
|
-
"This preview link could not be verified. Request a new download link."
|
|
6878
|
-
);
|
|
6879
|
-
}
|
|
6880
|
-
return new PdfPreviewError(
|
|
6881
|
-
"unknown",
|
|
6882
|
-
"Can't preview document",
|
|
6883
|
-
"Something went wrong while opening this file. Try downloading it or request a new link."
|
|
6884
|
-
);
|
|
6885
|
-
}
|
|
6886
|
-
function normalizePdfPreviewError(error) {
|
|
6887
|
-
if (error instanceof PdfPreviewError) return error;
|
|
6888
|
-
if (error instanceof TypeError) {
|
|
6889
|
-
return new PdfPreviewError(
|
|
6890
|
-
"network",
|
|
6891
|
-
"Connection problem",
|
|
6892
|
-
"Could not load the document. Check your connection and try again."
|
|
6893
|
-
);
|
|
6894
|
-
}
|
|
6895
|
-
return new PdfPreviewError(
|
|
6896
|
-
"unknown",
|
|
6897
|
-
"Can't preview document",
|
|
6898
|
-
"Something went wrong while opening this file. Try downloading it or request a new link."
|
|
6899
|
-
);
|
|
6900
|
-
}
|
|
6901
|
-
async function assertPdfBlob(blob, status) {
|
|
6902
|
-
if (!blob.size) {
|
|
6903
|
-
return Promise.reject(
|
|
6904
|
-
new PdfPreviewError(
|
|
6905
|
-
"empty",
|
|
6906
|
-
"Document unavailable",
|
|
6907
|
-
"The file response was empty. Request a new download link and try again."
|
|
6908
|
-
)
|
|
6909
|
-
);
|
|
6910
|
-
}
|
|
6911
|
-
const head = await blob.slice(0, Math.min(blob.size, 1024)).text();
|
|
6912
|
-
if (head.startsWith("%PDF")) {
|
|
6913
|
-
return blob;
|
|
6914
|
-
}
|
|
6915
|
-
throw classifyErrorBody(head, status);
|
|
6916
|
-
}
|
|
6917
|
-
async function fetchPdfBlob(src) {
|
|
6918
|
-
let response;
|
|
6919
|
-
try {
|
|
6920
|
-
response = await fetch(src, {
|
|
6921
|
-
method: "GET",
|
|
6922
|
-
headers: { Accept: "application/pdf,*/*" }
|
|
6923
|
-
});
|
|
6924
|
-
} catch {
|
|
6925
|
-
throw new PdfPreviewError(
|
|
6926
|
-
"network",
|
|
6927
|
-
"Connection problem",
|
|
6928
|
-
"Could not load the document. Check your connection and try again."
|
|
6929
|
-
);
|
|
6930
|
-
}
|
|
6931
|
-
const blob = await response.blob();
|
|
6932
|
-
if (!response.ok) {
|
|
6933
|
-
const body = await blob.text().catch(() => "");
|
|
6934
|
-
throw classifyErrorBody(body, response.status);
|
|
6935
|
-
}
|
|
6936
|
-
return assertPdfBlob(blob, response.status);
|
|
6937
|
-
}
|
|
6938
|
-
var MIN_WIDTH = 320;
|
|
6939
|
-
var MAX_WIDTH_RATIO = 0.6;
|
|
6940
|
-
var DEFAULT_WIDTH = 520;
|
|
6941
|
-
var SPRING = { type: "spring", stiffness: 340, damping: 34, mass: 0.85 };
|
|
6942
|
-
var SHEET_EXIT = { duration: 0.22, ease: [0.4, 0, 1, 1] };
|
|
6943
|
-
function pdfDownloadName(title) {
|
|
6944
|
-
const base = title.trim() || "document";
|
|
6945
|
-
return base.toLowerCase().endsWith(".pdf") ? base : `${base}.pdf`;
|
|
6946
|
-
}
|
|
6947
|
-
function clampSplitWidth(w) {
|
|
6948
|
-
const maxW = Math.floor(window.innerWidth * MAX_WIDTH_RATIO);
|
|
6949
|
-
return Math.max(MIN_WIDTH, Math.min(maxW, w));
|
|
6950
|
-
}
|
|
6951
|
-
function PdfSheetV2({
|
|
6952
|
-
src,
|
|
6953
|
-
title,
|
|
6954
|
-
onClose,
|
|
6955
|
-
mode = "split"
|
|
6956
|
-
}) {
|
|
6957
|
-
return /* @__PURE__ */ jsx(AnimatePresence, { children: src && /* @__PURE__ */ jsx(
|
|
6958
|
-
PdfSheetPanel,
|
|
6959
|
-
{
|
|
6960
|
-
src,
|
|
6961
|
-
title,
|
|
6962
|
-
onClose,
|
|
6963
|
-
mode
|
|
6964
|
-
},
|
|
6965
|
-
"pdf-panel"
|
|
6966
|
-
) });
|
|
6967
|
-
}
|
|
6968
|
-
function PdfSheetPanel({
|
|
6969
|
-
src,
|
|
6970
|
-
title,
|
|
6971
|
-
onClose,
|
|
6972
|
-
mode
|
|
6973
|
-
}) {
|
|
6974
|
-
const isSheet = mode === "sheet";
|
|
6975
|
-
const [isLoaded, setIsLoaded] = useState(false);
|
|
6976
|
-
const [isDownloading, setIsDownloading] = useState(false);
|
|
6977
|
-
const [previewUrl, setPreviewUrl] = useState(null);
|
|
6978
|
-
const [previewError, setPreviewError] = useState(null);
|
|
6979
|
-
const [loadAttempt, setLoadAttempt] = useState(0);
|
|
6980
|
-
const blobRef = useRef(null);
|
|
6981
|
-
const objectUrlRef = useRef(null);
|
|
6982
|
-
const [panelWidth, setPanelWidth] = useState(DEFAULT_WIDTH);
|
|
6983
|
-
const [splitOpened, setSplitOpened] = useState(false);
|
|
6984
|
-
const [isDragging, setIsDragging] = useState(false);
|
|
6985
|
-
useEffect(() => {
|
|
6986
|
-
setIsLoaded(false);
|
|
6987
|
-
setPreviewUrl(null);
|
|
6988
|
-
setPreviewError(null);
|
|
6989
|
-
setPanelWidth(DEFAULT_WIDTH);
|
|
6990
|
-
setSplitOpened(false);
|
|
6991
|
-
blobRef.current = null;
|
|
6992
|
-
if (objectUrlRef.current) {
|
|
6993
|
-
URL.revokeObjectURL(objectUrlRef.current);
|
|
6994
|
-
objectUrlRef.current = null;
|
|
6995
|
-
}
|
|
6996
|
-
let cancelled = false;
|
|
6997
|
-
const loadPreview = async () => {
|
|
6998
|
-
try {
|
|
6999
|
-
const blob = await fetchPdfBlob(src);
|
|
7000
|
-
if (cancelled) return;
|
|
7001
|
-
blobRef.current = blob;
|
|
7002
|
-
const objectUrl = URL.createObjectURL(blob);
|
|
7003
|
-
objectUrlRef.current = objectUrl;
|
|
7004
|
-
setPreviewUrl(objectUrl);
|
|
7005
|
-
} catch (error) {
|
|
7006
|
-
if (!cancelled) {
|
|
7007
|
-
setPreviewError(normalizePdfPreviewError(error));
|
|
7008
|
-
}
|
|
7009
|
-
}
|
|
7010
|
-
};
|
|
7011
|
-
void loadPreview();
|
|
7012
|
-
return () => {
|
|
7013
|
-
cancelled = true;
|
|
7014
|
-
if (objectUrlRef.current) {
|
|
7015
|
-
URL.revokeObjectURL(objectUrlRef.current);
|
|
7016
|
-
objectUrlRef.current = null;
|
|
7017
|
-
}
|
|
7018
|
-
blobRef.current = null;
|
|
7019
|
-
};
|
|
7020
|
-
}, [src, loadAttempt]);
|
|
7021
|
-
useEffect(() => {
|
|
7022
|
-
if (isSheet) return;
|
|
7023
|
-
const onWindowResize = () => setPanelWidth((size) => clampSplitWidth(size));
|
|
7024
|
-
window.addEventListener("resize", onWindowResize);
|
|
7025
|
-
return () => window.removeEventListener("resize", onWindowResize);
|
|
7026
|
-
}, [isSheet]);
|
|
7027
|
-
const handleKeyDown = useCallback(
|
|
7028
|
-
(e) => {
|
|
7029
|
-
if (e.key === "Escape") onClose();
|
|
7030
|
-
},
|
|
7031
|
-
[onClose]
|
|
7032
|
-
);
|
|
7033
|
-
useEffect(() => {
|
|
7034
|
-
document.addEventListener("keydown", handleKeyDown);
|
|
7035
|
-
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
7036
|
-
}, [handleKeyDown]);
|
|
7037
|
-
const canDownload = isLoaded && previewUrl != null && !previewError;
|
|
7038
|
-
const handleDownload = async () => {
|
|
7039
|
-
const filename = pdfDownloadName(title);
|
|
7040
|
-
setIsDownloading(true);
|
|
7041
|
-
try {
|
|
7042
|
-
const blob = blobRef.current ?? await fetchPdfBlob(src);
|
|
7043
|
-
const objectUrl = URL.createObjectURL(blob);
|
|
7044
|
-
const a = document.createElement("a");
|
|
7045
|
-
a.href = objectUrl;
|
|
7046
|
-
a.download = filename;
|
|
7047
|
-
a.target = "_blank";
|
|
7048
|
-
a.rel = "noopener noreferrer";
|
|
7049
|
-
document.body.appendChild(a);
|
|
7050
|
-
a.click();
|
|
7051
|
-
a.remove();
|
|
7052
|
-
URL.revokeObjectURL(objectUrl);
|
|
7053
|
-
} catch (error) {
|
|
7054
|
-
setPreviewError(normalizePdfPreviewError(error));
|
|
7055
|
-
} finally {
|
|
7056
|
-
setIsDownloading(false);
|
|
7057
|
-
}
|
|
7058
|
-
};
|
|
7059
|
-
const handleRetry = () => {
|
|
7060
|
-
setPreviewError(null);
|
|
7061
|
-
setIsLoaded(false);
|
|
7062
|
-
setPreviewUrl(null);
|
|
7063
|
-
setLoadAttempt((attempt) => attempt + 1);
|
|
7064
|
-
};
|
|
7065
|
-
const handleOpenInNewTab = () => {
|
|
7066
|
-
window.open(src, "_blank", "noopener,noreferrer");
|
|
7067
|
-
};
|
|
7068
|
-
const onResizeMouseDown = (e) => {
|
|
7069
|
-
if (e.button !== 0) return;
|
|
7070
|
-
e.preventDefault();
|
|
7071
|
-
const startX = e.clientX;
|
|
7072
|
-
const startW = panelWidth;
|
|
7073
|
-
setIsDragging(true);
|
|
7074
|
-
const onMove = (ev) => {
|
|
7075
|
-
setPanelWidth(clampSplitWidth(startW + (startX - ev.clientX)));
|
|
7076
|
-
};
|
|
7077
|
-
const onUp = () => {
|
|
7078
|
-
setIsDragging(false);
|
|
7079
|
-
document.removeEventListener("mousemove", onMove);
|
|
7080
|
-
document.removeEventListener("mouseup", onUp);
|
|
7081
|
-
};
|
|
7082
|
-
document.addEventListener("mousemove", onMove);
|
|
7083
|
-
document.addEventListener("mouseup", onUp);
|
|
7084
|
-
};
|
|
7085
|
-
return /* @__PURE__ */ jsxs(
|
|
7086
|
-
motion.div,
|
|
7087
|
-
{
|
|
7088
|
-
className: cn(
|
|
7089
|
-
"payman-v2-root payman-v2-pdf-sheet-panel",
|
|
7090
|
-
isSheet && "payman-v2-pdf-sheet-panel--sheet"
|
|
7091
|
-
),
|
|
7092
|
-
style: { minWidth: 0 },
|
|
7093
|
-
initial: isSheet ? { x: "100%", opacity: 0 } : { width: 0, opacity: 0 },
|
|
7094
|
-
animate: isSheet ? { x: 0, opacity: 1 } : { width: panelWidth, opacity: 1 },
|
|
7095
|
-
exit: isSheet ? { x: "100%", opacity: 0, transition: { x: SHEET_EXIT, opacity: SHEET_EXIT } } : { width: 0, opacity: 0, transition: { width: SHEET_EXIT, opacity: SHEET_EXIT } },
|
|
7096
|
-
transition: isSheet ? { x: SPRING, opacity: SPRING } : {
|
|
7097
|
-
width: splitOpened ? { duration: 0 } : SPRING,
|
|
7098
|
-
opacity: SPRING
|
|
7099
|
-
},
|
|
7100
|
-
onAnimationComplete: () => {
|
|
7101
|
-
if (!isSheet && !splitOpened) setSplitOpened(true);
|
|
7102
|
-
},
|
|
7103
|
-
children: [
|
|
7104
|
-
!isSheet && /* @__PURE__ */ jsx(
|
|
7105
|
-
"div",
|
|
7106
|
-
{
|
|
7107
|
-
className: "payman-v2-pdf-sheet-resize-handle",
|
|
7108
|
-
onMouseDown: onResizeMouseDown,
|
|
7109
|
-
"aria-hidden": "true",
|
|
7110
|
-
children: /* @__PURE__ */ jsx("div", { className: "payman-v2-pdf-sheet-resize-grip" })
|
|
7111
|
-
}
|
|
7112
|
-
),
|
|
7113
|
-
/* @__PURE__ */ jsxs("div", { className: "payman-v2-pdf-sheet-header", children: [
|
|
7114
|
-
/* @__PURE__ */ jsxs("div", { className: "payman-v2-pdf-sheet-header-left", children: [
|
|
7115
|
-
/* @__PURE__ */ jsx("div", { className: "payman-v2-pdf-sheet-file-icon", children: /* @__PURE__ */ jsx(FileText, { size: 14, strokeWidth: 1.75 }) }),
|
|
7116
|
-
/* @__PURE__ */ jsx("span", { className: "payman-v2-pdf-sheet-title", title, children: title || "Document" })
|
|
7117
|
-
] }),
|
|
7118
|
-
/* @__PURE__ */ jsxs("div", { className: "payman-v2-pdf-sheet-header-actions", children: [
|
|
7119
|
-
/* @__PURE__ */ jsxs(
|
|
7120
|
-
"button",
|
|
7121
|
-
{
|
|
7122
|
-
type: "button",
|
|
7123
|
-
className: "payman-v2-pdf-sheet-download-btn",
|
|
7124
|
-
"aria-label": "Download PDF",
|
|
7125
|
-
disabled: !canDownload || isDownloading,
|
|
7126
|
-
onClick: () => void handleDownload(),
|
|
7127
|
-
children: [
|
|
7128
|
-
isDownloading ? /* @__PURE__ */ jsx(Loader2, { size: 13, strokeWidth: 2, style: { animation: "payman-v2-spin 0.65s linear infinite" } }) : /* @__PURE__ */ jsx(Download, { size: 13, strokeWidth: 2 }),
|
|
7129
|
-
/* @__PURE__ */ jsx("span", { children: isDownloading ? "Downloading\u2026" : "Download" })
|
|
7130
|
-
]
|
|
7131
|
-
}
|
|
7132
|
-
),
|
|
7133
|
-
/* @__PURE__ */ jsx(
|
|
7134
|
-
"button",
|
|
7135
|
-
{
|
|
7136
|
-
type: "button",
|
|
7137
|
-
className: "payman-v2-pdf-sheet-close-btn",
|
|
7138
|
-
"aria-label": "Close preview",
|
|
7139
|
-
onClick: (e) => {
|
|
7140
|
-
e.stopPropagation();
|
|
7141
|
-
onClose();
|
|
7142
|
-
},
|
|
7143
|
-
children: /* @__PURE__ */ jsx(X, { size: 15, strokeWidth: 2.25 })
|
|
7144
|
-
}
|
|
7145
|
-
)
|
|
7146
|
-
] })
|
|
7147
|
-
] }),
|
|
7148
|
-
/* @__PURE__ */ jsx("div", { className: "payman-v2-pdf-sheet-body", children: previewError ? /* @__PURE__ */ jsxs("div", { className: "payman-v2-pdf-sheet-error", role: "alert", children: [
|
|
7149
|
-
/* @__PURE__ */ jsx("div", { className: "payman-v2-pdf-sheet-error-icon", children: /* @__PURE__ */ jsx(AlertCircle, { size: 22, strokeWidth: 1.75 }) }),
|
|
7150
|
-
/* @__PURE__ */ jsx("p", { className: "payman-v2-pdf-sheet-error-title", children: previewError.title }),
|
|
7151
|
-
/* @__PURE__ */ jsx("p", { className: "payman-v2-pdf-sheet-error-message", children: previewError.userMessage }),
|
|
7152
|
-
/* @__PURE__ */ jsxs("div", { className: "payman-v2-pdf-sheet-error-actions", children: [
|
|
7153
|
-
previewError.kind === "network" && /* @__PURE__ */ jsxs(
|
|
7154
|
-
"button",
|
|
7155
|
-
{
|
|
7156
|
-
type: "button",
|
|
7157
|
-
className: "payman-v2-pdf-sheet-error-btn",
|
|
7158
|
-
onClick: handleRetry,
|
|
7159
|
-
children: [
|
|
7160
|
-
/* @__PURE__ */ jsx(RefreshCw, { size: 14, strokeWidth: 2 }),
|
|
7161
|
-
/* @__PURE__ */ jsx("span", { children: "Try again" })
|
|
7162
|
-
]
|
|
7163
|
-
}
|
|
7164
|
-
),
|
|
7165
|
-
(previewError.kind === "network" || previewError.kind === "unknown") && /* @__PURE__ */ jsxs(
|
|
7166
|
-
"button",
|
|
7167
|
-
{
|
|
7168
|
-
type: "button",
|
|
7169
|
-
className: "payman-v2-pdf-sheet-error-btn payman-v2-pdf-sheet-error-btn-secondary",
|
|
7170
|
-
onClick: handleOpenInNewTab,
|
|
7171
|
-
children: [
|
|
7172
|
-
/* @__PURE__ */ jsx(ExternalLink, { size: 14, strokeWidth: 2 }),
|
|
7173
|
-
/* @__PURE__ */ jsx("span", { children: "Open link" })
|
|
7174
|
-
]
|
|
7175
|
-
}
|
|
7176
|
-
)
|
|
7177
|
-
] })
|
|
7178
|
-
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
7179
|
-
(!isLoaded || !previewUrl) && /* @__PURE__ */ jsxs("div", { className: "payman-v2-pdf-sheet-loading", children: [
|
|
7180
|
-
/* @__PURE__ */ jsx(
|
|
7181
|
-
Loader2,
|
|
7182
|
-
{
|
|
7183
|
-
size: 20,
|
|
7184
|
-
strokeWidth: 2,
|
|
7185
|
-
style: { animation: "payman-v2-spin 0.65s linear infinite", color: "var(--payman-v2-text-3)" }
|
|
7186
|
-
}
|
|
7187
|
-
),
|
|
7188
|
-
/* @__PURE__ */ jsx("p", { className: "payman-v2-pdf-sheet-loading-text", children: previewUrl ? "Preparing preview\u2026" : "Opening document\u2026" })
|
|
7189
|
-
] }),
|
|
7190
|
-
previewUrl && /* @__PURE__ */ jsx(
|
|
7191
|
-
"iframe",
|
|
7192
|
-
{
|
|
7193
|
-
src: previewUrl,
|
|
7194
|
-
title: title || "PDF Preview",
|
|
7195
|
-
className: "payman-v2-pdf-sheet-iframe",
|
|
7196
|
-
style: {
|
|
7197
|
-
opacity: isLoaded ? 1 : 0,
|
|
7198
|
-
transition: "opacity 0.3s ease",
|
|
7199
|
-
pointerEvents: isDragging ? "none" : "auto"
|
|
7200
|
-
},
|
|
7201
|
-
onLoad: () => setIsLoaded(true)
|
|
7202
|
-
},
|
|
7203
|
-
previewUrl
|
|
7204
|
-
)
|
|
7205
|
-
] }) })
|
|
7206
|
-
]
|
|
7207
|
-
}
|
|
7208
|
-
);
|
|
7209
|
-
}
|
|
7210
5978
|
var DEFAULT_USER_ACTION_STATE = {
|
|
7211
5979
|
prompts: [],
|
|
7212
5980
|
notifications: []
|
|
@@ -7301,8 +6069,7 @@ var PaymanChatInner = forwardRef(function PaymanChatInner2({
|
|
|
7301
6069
|
onLoadMoreMessages,
|
|
7302
6070
|
isLoadingMoreMessages = false,
|
|
7303
6071
|
hasMoreMessages = false,
|
|
7304
|
-
chat
|
|
7305
|
-
attachmentUpload
|
|
6072
|
+
chat
|
|
7306
6073
|
}, ref) {
|
|
7307
6074
|
const [inputValue, setInputValue] = useState("");
|
|
7308
6075
|
const prevInputValueRef = useRef(inputValue);
|
|
@@ -7356,6 +6123,7 @@ var PaymanChatInner = forwardRef(function PaymanChatInner2({
|
|
|
7356
6123
|
const submitUserAction2 = chat.submitUserAction ?? NOOP_ASYNC;
|
|
7357
6124
|
const cancelUserAction2 = chat.cancelUserAction ?? NOOP_ASYNC;
|
|
7358
6125
|
const resendUserAction2 = chat.resendUserAction ?? NOOP_ASYNC;
|
|
6126
|
+
const expireUserAction2 = chat.expireUserAction ?? NOOP_ASYNC;
|
|
7359
6127
|
const dismissNotification = chat.dismissNotification ?? NOOP;
|
|
7360
6128
|
const isUserActionSupported = typeof chat.submitUserAction === "function" && typeof chat.cancelUserAction === "function" && typeof chat.resendUserAction === "function";
|
|
7361
6129
|
const {
|
|
@@ -7381,19 +6149,6 @@ var PaymanChatInner = forwardRef(function PaymanChatInner2({
|
|
|
7381
6149
|
}
|
|
7382
6150
|
}
|
|
7383
6151
|
);
|
|
7384
|
-
const [pdfSheet, setPdfSheet] = useState(null);
|
|
7385
|
-
const autoOpenedPdfHrefsRef = useRef(/* @__PURE__ */ new Set());
|
|
7386
|
-
const pdfPreviewMode = config.pdfPreviewMode ?? "split";
|
|
7387
|
-
const openPdfSheet = useCallback((href, title, options) => {
|
|
7388
|
-
if (options?.auto) {
|
|
7389
|
-
if (autoOpenedPdfHrefsRef.current.has(href)) return;
|
|
7390
|
-
autoOpenedPdfHrefsRef.current.add(href);
|
|
7391
|
-
}
|
|
7392
|
-
setPdfSheet({ href, title });
|
|
7393
|
-
}, []);
|
|
7394
|
-
const closePdfSheet = useCallback(() => {
|
|
7395
|
-
setPdfSheet(null);
|
|
7396
|
-
}, []);
|
|
7397
6152
|
const contextValue = useMemo(
|
|
7398
6153
|
() => ({
|
|
7399
6154
|
resetSession,
|
|
@@ -7402,8 +6157,7 @@ var PaymanChatInner = forwardRef(function PaymanChatInner2({
|
|
|
7402
6157
|
cancelStream,
|
|
7403
6158
|
getSessionId,
|
|
7404
6159
|
getMessages,
|
|
7405
|
-
isWaitingForResponse
|
|
7406
|
-
openPdfSheet
|
|
6160
|
+
isWaitingForResponse
|
|
7407
6161
|
}),
|
|
7408
6162
|
[
|
|
7409
6163
|
resetSession,
|
|
@@ -7412,8 +6166,7 @@ var PaymanChatInner = forwardRef(function PaymanChatInner2({
|
|
|
7412
6166
|
cancelStream,
|
|
7413
6167
|
getSessionId,
|
|
7414
6168
|
getMessages,
|
|
7415
|
-
isWaitingForResponse
|
|
7416
|
-
openPdfSheet
|
|
6169
|
+
isWaitingForResponse
|
|
7417
6170
|
]
|
|
7418
6171
|
);
|
|
7419
6172
|
const {
|
|
@@ -7469,10 +6222,7 @@ var PaymanChatInner = forwardRef(function PaymanChatInner2({
|
|
|
7469
6222
|
setInputValue("");
|
|
7470
6223
|
setLightboxSrc(null);
|
|
7471
6224
|
setLightboxAlt("");
|
|
7472
|
-
setPdfSheet(null);
|
|
7473
|
-
autoOpenedPdfHrefsRef.current.clear();
|
|
7474
6225
|
chatInputV2Ref.current?.setDraft("");
|
|
7475
|
-
chatInputV2Ref.current?.clearAttachments();
|
|
7476
6226
|
clearTranscript();
|
|
7477
6227
|
if (isRecording) {
|
|
7478
6228
|
stopRecording();
|
|
@@ -7523,20 +6273,14 @@ var PaymanChatInner = forwardRef(function PaymanChatInner2({
|
|
|
7523
6273
|
emptyStateComponent,
|
|
7524
6274
|
showResetSession = false,
|
|
7525
6275
|
enableDeepModeToggle = true,
|
|
6276
|
+
showAttachmentButton = true,
|
|
6277
|
+
showUploadImageButton = true,
|
|
6278
|
+
showAttachFileButton = true,
|
|
7526
6279
|
messageActions: messageActionsConfig,
|
|
7527
6280
|
enableSlashCommands = true,
|
|
7528
6281
|
slashCommands: slashCommandsConfig,
|
|
7529
6282
|
commandPermissions
|
|
7530
6283
|
} = config;
|
|
7531
|
-
const attachmentSettings = useMemo(
|
|
7532
|
-
() => resolveChatAttachmentConfig(config),
|
|
7533
|
-
[
|
|
7534
|
-
config.attachments,
|
|
7535
|
-
config.showAttachmentButton,
|
|
7536
|
-
config.showUploadImageButton,
|
|
7537
|
-
config.showAttachFileButton
|
|
7538
|
-
]
|
|
7539
|
-
);
|
|
7540
6284
|
const messageActions = useMemo(
|
|
7541
6285
|
() => ({
|
|
7542
6286
|
userMessageActions: {
|
|
@@ -7624,22 +6368,11 @@ var PaymanChatInner = forwardRef(function PaymanChatInner2({
|
|
|
7624
6368
|
};
|
|
7625
6369
|
const userActionPrompts = isUserActionSupported ? userActionState.prompts : void 0;
|
|
7626
6370
|
const notifications = userActionState.notifications;
|
|
7627
|
-
const
|
|
7628
|
-
(attachments) => {
|
|
7629
|
-
attachmentUpload.syncAttachments(attachments);
|
|
7630
|
-
},
|
|
7631
|
-
[attachmentUpload]
|
|
7632
|
-
);
|
|
7633
|
-
const handleV2Send = (text, files = [], attachments = []) => {
|
|
6371
|
+
const handleV2Send = (text) => {
|
|
7634
6372
|
if (isRecording) stopRecording();
|
|
7635
|
-
if (
|
|
7636
|
-
if (files.length > 0 && attachments.length === 0) return;
|
|
6373
|
+
if (text.trim() && !disableInput && isSessionParamsConfigured) {
|
|
7637
6374
|
setEditingMessageId(null);
|
|
7638
|
-
void sendMessage(text.trim(), {
|
|
7639
|
-
analysisMode: effectiveAnalysisMode,
|
|
7640
|
-
attachments,
|
|
7641
|
-
files
|
|
7642
|
-
});
|
|
6375
|
+
void sendMessage(text.trim(), { analysisMode: effectiveAnalysisMode });
|
|
7643
6376
|
}
|
|
7644
6377
|
};
|
|
7645
6378
|
const handleVoicePress = useCallback(async () => {
|
|
@@ -7687,214 +6420,156 @@ var PaymanChatInner = forwardRef(function PaymanChatInner2({
|
|
|
7687
6420
|
style,
|
|
7688
6421
|
children: [
|
|
7689
6422
|
children,
|
|
7690
|
-
/* @__PURE__ */
|
|
7691
|
-
|
|
6423
|
+
/* @__PURE__ */ jsx(AnimatePresence, { mode: "wait", children: isEmpty && !hasEverSentMessage ? /* @__PURE__ */ jsx(
|
|
6424
|
+
motion.div,
|
|
7692
6425
|
{
|
|
7693
|
-
|
|
7694
|
-
|
|
7695
|
-
|
|
7696
|
-
|
|
7697
|
-
|
|
7698
|
-
|
|
7699
|
-
|
|
7700
|
-
|
|
7701
|
-
initial: { opacity: 1 },
|
|
7702
|
-
exit: { opacity: 0 },
|
|
7703
|
-
transition: { duration: 0.3 },
|
|
7704
|
-
className: "payman-v2-chat-layout",
|
|
7705
|
-
style: { justifyContent: "center", alignItems: "center" },
|
|
7706
|
-
children: /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", flex: 1, width: "100%" }, children: [
|
|
7707
|
-
/* @__PURE__ */ jsx(
|
|
7708
|
-
MessageList,
|
|
7709
|
-
{
|
|
7710
|
-
messages,
|
|
7711
|
-
isLoading: false,
|
|
7712
|
-
emptyStateText,
|
|
7713
|
-
showEmptyStateIcon,
|
|
7714
|
-
emptyStateComponent,
|
|
7715
|
-
layout,
|
|
7716
|
-
showTimestamps,
|
|
7717
|
-
stage: config.stage || "DEVELOPMENT",
|
|
7718
|
-
animated,
|
|
7719
|
-
showAgentName,
|
|
7720
|
-
agentName,
|
|
7721
|
-
showAvatars,
|
|
7722
|
-
showUserAvatar,
|
|
7723
|
-
showAssistantAvatar,
|
|
7724
|
-
showExecutionSteps,
|
|
7725
|
-
showStreamingDot,
|
|
7726
|
-
streamingStepsText,
|
|
7727
|
-
completedStepsText,
|
|
7728
|
-
onExecutionTraceClick,
|
|
7729
|
-
onLoadMoreMessages,
|
|
7730
|
-
isLoadingMoreMessages,
|
|
7731
|
-
hasMoreMessages
|
|
7732
|
-
}
|
|
7733
|
-
),
|
|
7734
|
-
/* @__PURE__ */ jsx(
|
|
7735
|
-
motion.div,
|
|
7736
|
-
{
|
|
7737
|
-
initial: { opacity: 0, y: 12 },
|
|
7738
|
-
animate: { opacity: 1, y: 0 },
|
|
7739
|
-
transition: { delay: 0.2, duration: 0.4, ease: [0.25, 0.46, 0.45, 0.94] },
|
|
7740
|
-
style: { width: "100%" },
|
|
7741
|
-
children: hasAskPermission && /* @__PURE__ */ jsx(
|
|
7742
|
-
ChatInputV2,
|
|
7743
|
-
{
|
|
7744
|
-
ref: chatInputV2Ref,
|
|
7745
|
-
onSend: handleV2Send,
|
|
7746
|
-
onCancel: cancelStream,
|
|
7747
|
-
disabled: isV2InputDisabled,
|
|
7748
|
-
isStreaming: isWaitingForResponse,
|
|
7749
|
-
isUploadingAttachments: attachmentUpload.isUploading,
|
|
7750
|
-
attachmentsReady: attachmentUpload.allReady,
|
|
7751
|
-
hasAttachmentUploadErrors: attachmentUpload.hasErrors,
|
|
7752
|
-
attachmentUploadStatusById: attachmentUpload.statusById,
|
|
7753
|
-
uploadedAttachmentPayloads: attachmentUpload.payloads,
|
|
7754
|
-
onAttachmentsChange: handleAttachmentsChange,
|
|
7755
|
-
placeholder: isRecording ? "Listening..." : placeholder,
|
|
7756
|
-
enableVoice: config.enableVoice === true,
|
|
7757
|
-
transcribedText: config.enableVoice === true ? transcribedText : "",
|
|
7758
|
-
voiceAvailable: config.enableVoice === true && voiceAvailable,
|
|
7759
|
-
isRecording,
|
|
7760
|
-
onVoicePress: config.enableVoice === true ? handleVoicePress : void 0,
|
|
7761
|
-
onCancelRecording: handleCancelRecording,
|
|
7762
|
-
onConfirmRecording: handleConfirmRecording,
|
|
7763
|
-
showResetSession,
|
|
7764
|
-
onResetSession: requestResetSession,
|
|
7765
|
-
showAttachmentButton: attachmentSettings.showAttachmentButton,
|
|
7766
|
-
showUploadImageButton: attachmentSettings.showUploadImageButton,
|
|
7767
|
-
showAttachFileButton: attachmentSettings.showAttachFileButton,
|
|
7768
|
-
allowedImageExtensions: attachmentSettings.allowedImageExtensions,
|
|
7769
|
-
allowedFileExtensions: attachmentSettings.allowedFileExtensions,
|
|
7770
|
-
maxCount: attachmentSettings.maxCount,
|
|
7771
|
-
maxFileBytes: attachmentSettings.maxFileBytes,
|
|
7772
|
-
maxTotalBytes: attachmentSettings.maxTotalBytes,
|
|
7773
|
-
onUploadImageClick,
|
|
7774
|
-
onAttachFileClick,
|
|
7775
|
-
editingMessageId,
|
|
7776
|
-
onClearEditing: handleClearEditing,
|
|
7777
|
-
analysisMode: enableDeepModeToggle ? analysisMode : void 0,
|
|
7778
|
-
onAnalysisModeChange: enableDeepModeToggle ? setAnalysisMode : void 0,
|
|
7779
|
-
slashCommands
|
|
7780
|
-
}
|
|
7781
|
-
)
|
|
7782
|
-
}
|
|
7783
|
-
)
|
|
7784
|
-
] })
|
|
7785
|
-
},
|
|
7786
|
-
"v2-empty"
|
|
7787
|
-
) : /* @__PURE__ */ jsxs(
|
|
7788
|
-
motion.div,
|
|
7789
|
-
{
|
|
7790
|
-
initial: hasEverSentMessage ? { opacity: 0 } : false,
|
|
7791
|
-
animate: { opacity: 1 },
|
|
7792
|
-
transition: { duration: 0.3 },
|
|
7793
|
-
className: "payman-v2-chat-layout",
|
|
7794
|
-
children: [
|
|
7795
|
-
/* @__PURE__ */ jsx(
|
|
7796
|
-
MessageListV2,
|
|
7797
|
-
{
|
|
7798
|
-
ref: messageListV2Ref,
|
|
7799
|
-
messages,
|
|
7800
|
-
isStreaming: isWaitingForResponse,
|
|
7801
|
-
sidePanelOpen: !!pdfSheet,
|
|
7802
|
-
onEditUserMessage: handleEditMessageDraft,
|
|
7803
|
-
onRetryUserMessage: handleRetryUserMessage,
|
|
7804
|
-
onImageClick: handleImageClick,
|
|
7805
|
-
onExecutionTraceClick,
|
|
7806
|
-
messageActions,
|
|
7807
|
-
retryDisabled: isWaitingForResponse,
|
|
7808
|
-
typingSpeed: config.typingSpeed ?? 4,
|
|
7809
|
-
userActionPrompts,
|
|
7810
|
-
notifications,
|
|
7811
|
-
onSubmitUserAction: isUserActionSupported ? submitUserAction2 : void 0,
|
|
7812
|
-
onCancelUserAction: isUserActionSupported ? cancelUserAction2 : void 0,
|
|
7813
|
-
onResendUserAction: isUserActionSupported ? resendUserAction2 : void 0,
|
|
7814
|
-
onDismissNotification: dismissNotification,
|
|
7815
|
-
onSubmitFeedback: handleSubmitFeedback
|
|
7816
|
-
}
|
|
7817
|
-
),
|
|
7818
|
-
/* @__PURE__ */ jsx(
|
|
7819
|
-
StreamingIndicatorV2,
|
|
7820
|
-
{
|
|
7821
|
-
isStreaming: isWaitingForResponse,
|
|
7822
|
-
loadingAnimation: config.loadingAnimation
|
|
7823
|
-
}
|
|
7824
|
-
),
|
|
7825
|
-
hasAskPermission && /* @__PURE__ */ jsx(
|
|
7826
|
-
ChatInputV2,
|
|
7827
|
-
{
|
|
7828
|
-
ref: chatInputV2Ref,
|
|
7829
|
-
onSend: handleV2Send,
|
|
7830
|
-
onCancel: cancelStream,
|
|
7831
|
-
disabled: isV2InputDisabled,
|
|
7832
|
-
isStreaming: isWaitingForResponse,
|
|
7833
|
-
isUploadingAttachments: attachmentUpload.isUploading,
|
|
7834
|
-
attachmentsReady: attachmentUpload.allReady,
|
|
7835
|
-
hasAttachmentUploadErrors: attachmentUpload.hasErrors,
|
|
7836
|
-
attachmentUploadStatusById: attachmentUpload.statusById,
|
|
7837
|
-
uploadedAttachmentPayloads: attachmentUpload.payloads,
|
|
7838
|
-
onAttachmentsChange: handleAttachmentsChange,
|
|
7839
|
-
placeholder: isRecording ? "Listening..." : placeholder,
|
|
7840
|
-
enableVoice: config.enableVoice === true,
|
|
7841
|
-
transcribedText: config.enableVoice === true ? transcribedText : "",
|
|
7842
|
-
voiceAvailable: config.enableVoice === true && voiceAvailable,
|
|
7843
|
-
isRecording,
|
|
7844
|
-
onVoicePress: config.enableVoice === true ? handleVoicePress : void 0,
|
|
7845
|
-
onCancelRecording: handleCancelRecording,
|
|
7846
|
-
onConfirmRecording: handleConfirmRecording,
|
|
7847
|
-
showResetSession,
|
|
7848
|
-
onResetSession: requestResetSession,
|
|
7849
|
-
showAttachmentButton: attachmentSettings.showAttachmentButton,
|
|
7850
|
-
showUploadImageButton: attachmentSettings.showUploadImageButton,
|
|
7851
|
-
showAttachFileButton: attachmentSettings.showAttachFileButton,
|
|
7852
|
-
allowedImageExtensions: attachmentSettings.allowedImageExtensions,
|
|
7853
|
-
allowedFileExtensions: attachmentSettings.allowedFileExtensions,
|
|
7854
|
-
maxCount: attachmentSettings.maxCount,
|
|
7855
|
-
maxFileBytes: attachmentSettings.maxFileBytes,
|
|
7856
|
-
maxTotalBytes: attachmentSettings.maxTotalBytes,
|
|
7857
|
-
onUploadImageClick,
|
|
7858
|
-
onAttachFileClick,
|
|
7859
|
-
editingMessageId,
|
|
7860
|
-
onClearEditing: handleClearEditing,
|
|
7861
|
-
analysisMode: enableDeepModeToggle ? analysisMode : void 0,
|
|
7862
|
-
onAnalysisModeChange: enableDeepModeToggle ? setAnalysisMode : void 0,
|
|
7863
|
-
slashCommands
|
|
7864
|
-
}
|
|
7865
|
-
)
|
|
7866
|
-
]
|
|
7867
|
-
},
|
|
7868
|
-
"v2-chat"
|
|
7869
|
-
) }) }),
|
|
7870
|
-
pdfPreviewMode === "split" && /* @__PURE__ */ jsx(
|
|
7871
|
-
PdfSheetV2,
|
|
6426
|
+
initial: { opacity: 1 },
|
|
6427
|
+
exit: { opacity: 0 },
|
|
6428
|
+
transition: { duration: 0.3 },
|
|
6429
|
+
className: "payman-v2-chat-layout",
|
|
6430
|
+
style: { justifyContent: "center", alignItems: "center" },
|
|
6431
|
+
children: /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", flex: 1, width: "100%" }, children: [
|
|
6432
|
+
/* @__PURE__ */ jsx(
|
|
6433
|
+
MessageList,
|
|
7872
6434
|
{
|
|
7873
|
-
|
|
7874
|
-
|
|
7875
|
-
|
|
7876
|
-
|
|
6435
|
+
messages,
|
|
6436
|
+
isLoading: false,
|
|
6437
|
+
emptyStateText,
|
|
6438
|
+
showEmptyStateIcon,
|
|
6439
|
+
emptyStateComponent,
|
|
6440
|
+
layout,
|
|
6441
|
+
showTimestamps,
|
|
6442
|
+
stage: config.stage || "DEVELOPMENT",
|
|
6443
|
+
animated,
|
|
6444
|
+
showAgentName,
|
|
6445
|
+
agentName,
|
|
6446
|
+
showAvatars,
|
|
6447
|
+
showUserAvatar,
|
|
6448
|
+
showAssistantAvatar,
|
|
6449
|
+
showExecutionSteps,
|
|
6450
|
+
showStreamingDot,
|
|
6451
|
+
streamingStepsText,
|
|
6452
|
+
completedStepsText,
|
|
6453
|
+
onExecutionTraceClick,
|
|
6454
|
+
onLoadMoreMessages,
|
|
6455
|
+
isLoadingMoreMessages,
|
|
6456
|
+
hasMoreMessages
|
|
7877
6457
|
}
|
|
7878
6458
|
),
|
|
7879
|
-
|
|
7880
|
-
|
|
6459
|
+
/* @__PURE__ */ jsx(
|
|
6460
|
+
motion.div,
|
|
7881
6461
|
{
|
|
7882
|
-
|
|
7883
|
-
|
|
7884
|
-
|
|
7885
|
-
|
|
6462
|
+
initial: { opacity: 0, y: 12 },
|
|
6463
|
+
animate: { opacity: 1, y: 0 },
|
|
6464
|
+
transition: { delay: 0.2, duration: 0.4, ease: [0.25, 0.46, 0.45, 0.94] },
|
|
6465
|
+
style: { width: "100%" },
|
|
6466
|
+
children: hasAskPermission && /* @__PURE__ */ jsx(
|
|
6467
|
+
ChatInputV2,
|
|
7886
6468
|
{
|
|
7887
|
-
|
|
7888
|
-
|
|
7889
|
-
|
|
7890
|
-
|
|
6469
|
+
ref: chatInputV2Ref,
|
|
6470
|
+
onSend: handleV2Send,
|
|
6471
|
+
onCancel: cancelStream,
|
|
6472
|
+
disabled: isV2InputDisabled,
|
|
6473
|
+
isStreaming: isWaitingForResponse,
|
|
6474
|
+
placeholder: isRecording ? "Listening..." : placeholder,
|
|
6475
|
+
enableVoice: config.enableVoice === true,
|
|
6476
|
+
transcribedText: config.enableVoice === true ? transcribedText : "",
|
|
6477
|
+
voiceAvailable: config.enableVoice === true && voiceAvailable,
|
|
6478
|
+
isRecording,
|
|
6479
|
+
onVoicePress: config.enableVoice === true ? handleVoicePress : void 0,
|
|
6480
|
+
onCancelRecording: handleCancelRecording,
|
|
6481
|
+
onConfirmRecording: handleConfirmRecording,
|
|
6482
|
+
showResetSession,
|
|
6483
|
+
onResetSession: requestResetSession,
|
|
6484
|
+
showAttachmentButton,
|
|
6485
|
+
showUploadImageButton,
|
|
6486
|
+
showAttachFileButton,
|
|
6487
|
+
onUploadImageClick,
|
|
6488
|
+
onAttachFileClick,
|
|
6489
|
+
editingMessageId,
|
|
6490
|
+
onClearEditing: handleClearEditing,
|
|
6491
|
+
analysisMode: enableDeepModeToggle ? analysisMode : void 0,
|
|
6492
|
+
onAnalysisModeChange: enableDeepModeToggle ? setAnalysisMode : void 0,
|
|
6493
|
+
slashCommands
|
|
7891
6494
|
}
|
|
7892
6495
|
)
|
|
7893
6496
|
}
|
|
7894
6497
|
)
|
|
6498
|
+
] })
|
|
6499
|
+
},
|
|
6500
|
+
"v2-empty"
|
|
6501
|
+
) : /* @__PURE__ */ jsxs(
|
|
6502
|
+
motion.div,
|
|
6503
|
+
{
|
|
6504
|
+
initial: hasEverSentMessage ? { opacity: 0 } : false,
|
|
6505
|
+
animate: { opacity: 1 },
|
|
6506
|
+
transition: { duration: 0.3 },
|
|
6507
|
+
className: "payman-v2-chat-layout",
|
|
6508
|
+
children: [
|
|
6509
|
+
/* @__PURE__ */ jsx(
|
|
6510
|
+
MessageListV2,
|
|
6511
|
+
{
|
|
6512
|
+
ref: messageListV2Ref,
|
|
6513
|
+
messages,
|
|
6514
|
+
isStreaming: isWaitingForResponse,
|
|
6515
|
+
onEditUserMessage: handleEditMessageDraft,
|
|
6516
|
+
onRetryUserMessage: handleRetryUserMessage,
|
|
6517
|
+
onImageClick: handleImageClick,
|
|
6518
|
+
onExecutionTraceClick,
|
|
6519
|
+
messageActions,
|
|
6520
|
+
retryDisabled: isWaitingForResponse,
|
|
6521
|
+
typingSpeed: config.typingSpeed ?? 4,
|
|
6522
|
+
userActionPrompts,
|
|
6523
|
+
notifications,
|
|
6524
|
+
onSubmitUserAction: isUserActionSupported ? submitUserAction2 : void 0,
|
|
6525
|
+
onCancelUserAction: isUserActionSupported ? cancelUserAction2 : void 0,
|
|
6526
|
+
onResendUserAction: isUserActionSupported ? resendUserAction2 : void 0,
|
|
6527
|
+
onExpireUserAction: isUserActionSupported ? expireUserAction2 : void 0,
|
|
6528
|
+
onDismissNotification: dismissNotification,
|
|
6529
|
+
onSubmitFeedback: handleSubmitFeedback
|
|
6530
|
+
}
|
|
6531
|
+
),
|
|
6532
|
+
/* @__PURE__ */ jsx(
|
|
6533
|
+
StreamingIndicatorV2,
|
|
6534
|
+
{
|
|
6535
|
+
isStreaming: isWaitingForResponse,
|
|
6536
|
+
loadingAnimation: config.loadingAnimation
|
|
6537
|
+
}
|
|
6538
|
+
),
|
|
6539
|
+
hasAskPermission && /* @__PURE__ */ jsx(
|
|
6540
|
+
ChatInputV2,
|
|
6541
|
+
{
|
|
6542
|
+
ref: chatInputV2Ref,
|
|
6543
|
+
onSend: handleV2Send,
|
|
6544
|
+
onCancel: cancelStream,
|
|
6545
|
+
disabled: isV2InputDisabled,
|
|
6546
|
+
isStreaming: isWaitingForResponse,
|
|
6547
|
+
placeholder: isRecording ? "Listening..." : placeholder,
|
|
6548
|
+
enableVoice: config.enableVoice === true,
|
|
6549
|
+
transcribedText: config.enableVoice === true ? transcribedText : "",
|
|
6550
|
+
voiceAvailable: config.enableVoice === true && voiceAvailable,
|
|
6551
|
+
isRecording,
|
|
6552
|
+
onVoicePress: config.enableVoice === true ? handleVoicePress : void 0,
|
|
6553
|
+
onCancelRecording: handleCancelRecording,
|
|
6554
|
+
onConfirmRecording: handleConfirmRecording,
|
|
6555
|
+
showResetSession,
|
|
6556
|
+
onResetSession: requestResetSession,
|
|
6557
|
+
showAttachmentButton,
|
|
6558
|
+
showUploadImageButton,
|
|
6559
|
+
showAttachFileButton,
|
|
6560
|
+
onUploadImageClick,
|
|
6561
|
+
onAttachFileClick,
|
|
6562
|
+
editingMessageId,
|
|
6563
|
+
onClearEditing: handleClearEditing,
|
|
6564
|
+
analysisMode: enableDeepModeToggle ? analysisMode : void 0,
|
|
6565
|
+
onAnalysisModeChange: enableDeepModeToggle ? setAnalysisMode : void 0,
|
|
6566
|
+
slashCommands
|
|
6567
|
+
}
|
|
6568
|
+
)
|
|
7895
6569
|
]
|
|
7896
|
-
}
|
|
7897
|
-
|
|
6570
|
+
},
|
|
6571
|
+
"v2-chat"
|
|
6572
|
+
) }),
|
|
7898
6573
|
/* @__PURE__ */ jsx(
|
|
7899
6574
|
ImageLightboxV2,
|
|
7900
6575
|
{
|
|
@@ -7929,19 +6604,10 @@ var PaymanChat = forwardRef(
|
|
|
7929
6604
|
function PaymanChat2(props, ref) {
|
|
7930
6605
|
const mergedCallbacks = useSentryChatCallbacks(props.callbacks, props.config);
|
|
7931
6606
|
const chat = useChatV2(props.config, mergedCallbacks);
|
|
7932
|
-
|
|
7933
|
-
return /* @__PURE__ */ jsx(
|
|
7934
|
-
PaymanChatInner,
|
|
7935
|
-
{
|
|
7936
|
-
...props,
|
|
7937
|
-
chat,
|
|
7938
|
-
attachmentUpload,
|
|
7939
|
-
ref
|
|
7940
|
-
}
|
|
7941
|
-
);
|
|
6607
|
+
return /* @__PURE__ */ jsx(PaymanChatInner, { ...props, chat, ref });
|
|
7942
6608
|
}
|
|
7943
6609
|
);
|
|
7944
6610
|
|
|
7945
|
-
export { PaymanChat, PaymanChatContext,
|
|
6611
|
+
export { PaymanChat, PaymanChatContext, UserActionStaleError, cancelUserAction, captureSentryError, cn, formatDate, resendUserAction, submitUserAction, useChatV2, usePaymanChat, useVoice };
|
|
7946
6612
|
//# sourceMappingURL=index.mjs.map
|
|
7947
6613
|
//# sourceMappingURL=index.mjs.map
|