@paymanai/payman-ask-sdk 4.0.20 → 4.0.21
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 +350 -1582
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +353 -1574
- package/dist/index.mjs.map +1 -1
- package/dist/index.native.js +3826 -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 +1 -1
package/dist/index.js
CHANGED
|
@@ -40,10 +40,7 @@ var remarkBreaks__default = /*#__PURE__*/_interopDefault(remarkBreaks);
|
|
|
40
40
|
|
|
41
41
|
var __defProp = Object.defineProperty;
|
|
42
42
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
43
|
-
var __publicField = (obj, key, value) => __defNormalProp(obj,
|
|
44
|
-
var __defProp2 = Object.defineProperty;
|
|
45
|
-
var __defNormalProp2 = (obj, key, value) => key in obj ? __defProp2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
46
|
-
var __publicField2 = (obj, key, value) => __defNormalProp2(obj, key + "", value);
|
|
43
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, key + "", value);
|
|
47
44
|
function generateId() {
|
|
48
45
|
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
|
|
49
46
|
const r = Math.random() * 16 | 0;
|
|
@@ -1154,7 +1151,7 @@ async function uploadAttachments(config, files, signal) {
|
|
|
1154
1151
|
var UserActionStaleError = class extends Error {
|
|
1155
1152
|
constructor(userActionId, message = "User action is no longer actionable") {
|
|
1156
1153
|
super(message);
|
|
1157
|
-
|
|
1154
|
+
__publicField(this, "userActionId");
|
|
1158
1155
|
this.name = "UserActionStaleError";
|
|
1159
1156
|
this.userActionId = userActionId;
|
|
1160
1157
|
}
|
|
@@ -1835,102 +1832,6 @@ function useVoice(config = {}, callbacks = {}) {
|
|
|
1835
1832
|
reset
|
|
1836
1833
|
};
|
|
1837
1834
|
}
|
|
1838
|
-
function useAttachmentUpload(config) {
|
|
1839
|
-
const configRef = react.useRef(config);
|
|
1840
|
-
configRef.current = config;
|
|
1841
|
-
const [entries, setEntries] = react.useState(/* @__PURE__ */ new Map());
|
|
1842
|
-
const [orderedIds, setOrderedIds] = react.useState([]);
|
|
1843
|
-
const abortControllersRef = react.useRef(/* @__PURE__ */ new Map());
|
|
1844
|
-
const activeIdsRef = react.useRef(/* @__PURE__ */ new Set());
|
|
1845
|
-
const startUpload = react.useCallback((id, file) => {
|
|
1846
|
-
if (activeIdsRef.current.has(id)) return;
|
|
1847
|
-
activeIdsRef.current.add(id);
|
|
1848
|
-
const controller = new AbortController();
|
|
1849
|
-
abortControllersRef.current.set(id, controller);
|
|
1850
|
-
setEntries((prev) => {
|
|
1851
|
-
const next = new Map(prev);
|
|
1852
|
-
next.set(id, { id, status: "uploading" });
|
|
1853
|
-
return next;
|
|
1854
|
-
});
|
|
1855
|
-
void uploadAttachment(configRef.current, file, controller.signal).then((payload) => {
|
|
1856
|
-
if (controller.signal.aborted) return;
|
|
1857
|
-
setEntries((prev) => {
|
|
1858
|
-
const next = new Map(prev);
|
|
1859
|
-
next.set(id, { id, status: "done", payload });
|
|
1860
|
-
return next;
|
|
1861
|
-
});
|
|
1862
|
-
}).catch((error) => {
|
|
1863
|
-
if (error.name === "AbortError") return;
|
|
1864
|
-
setEntries((prev) => {
|
|
1865
|
-
const next = new Map(prev);
|
|
1866
|
-
next.set(id, {
|
|
1867
|
-
id,
|
|
1868
|
-
status: "error",
|
|
1869
|
-
error: error.message || "Upload failed"
|
|
1870
|
-
});
|
|
1871
|
-
return next;
|
|
1872
|
-
});
|
|
1873
|
-
}).finally(() => {
|
|
1874
|
-
abortControllersRef.current.delete(id);
|
|
1875
|
-
});
|
|
1876
|
-
}, []);
|
|
1877
|
-
const syncAttachments = react.useCallback(
|
|
1878
|
-
(attachments) => {
|
|
1879
|
-
const nextIds = attachments.map((attachment) => attachment.id);
|
|
1880
|
-
setOrderedIds(nextIds);
|
|
1881
|
-
const nextIdSet = new Set(nextIds);
|
|
1882
|
-
for (const id of activeIdsRef.current) {
|
|
1883
|
-
if (nextIdSet.has(id)) continue;
|
|
1884
|
-
abortControllersRef.current.get(id)?.abort();
|
|
1885
|
-
abortControllersRef.current.delete(id);
|
|
1886
|
-
activeIdsRef.current.delete(id);
|
|
1887
|
-
}
|
|
1888
|
-
setEntries((prev) => {
|
|
1889
|
-
const next = new Map(prev);
|
|
1890
|
-
for (const id of next.keys()) {
|
|
1891
|
-
if (!nextIdSet.has(id)) next.delete(id);
|
|
1892
|
-
}
|
|
1893
|
-
return next;
|
|
1894
|
-
});
|
|
1895
|
-
for (const attachment of attachments) {
|
|
1896
|
-
startUpload(attachment.id, attachment.file);
|
|
1897
|
-
}
|
|
1898
|
-
},
|
|
1899
|
-
[startUpload]
|
|
1900
|
-
);
|
|
1901
|
-
const clearAll = react.useCallback(() => {
|
|
1902
|
-
for (const controller of abortControllersRef.current.values()) {
|
|
1903
|
-
controller.abort();
|
|
1904
|
-
}
|
|
1905
|
-
abortControllersRef.current.clear();
|
|
1906
|
-
activeIdsRef.current.clear();
|
|
1907
|
-
setOrderedIds([]);
|
|
1908
|
-
setEntries(/* @__PURE__ */ new Map());
|
|
1909
|
-
}, []);
|
|
1910
|
-
const entryList = react.useMemo(
|
|
1911
|
-
() => orderedIds.map((id) => entries.get(id)).filter((entry) => entry != null),
|
|
1912
|
-
[entries, orderedIds]
|
|
1913
|
-
);
|
|
1914
|
-
const isUploading = entryList.some((entry) => entry.status === "uploading");
|
|
1915
|
-
const hasErrors = entryList.some((entry) => entry.status === "error");
|
|
1916
|
-
const allReady = orderedIds.length === 0 || orderedIds.every((id) => entries.get(id)?.status === "done");
|
|
1917
|
-
const payloads = entryList.filter((entry) => entry.status === "done" && entry.payload).map((entry) => entry.payload);
|
|
1918
|
-
const statusById = react.useMemo(
|
|
1919
|
-
() => Object.fromEntries(
|
|
1920
|
-
entryList.map((entry) => [entry.id, entry.status])
|
|
1921
|
-
),
|
|
1922
|
-
[entryList]
|
|
1923
|
-
);
|
|
1924
|
-
return {
|
|
1925
|
-
syncAttachments,
|
|
1926
|
-
clearAll,
|
|
1927
|
-
isUploading,
|
|
1928
|
-
hasErrors,
|
|
1929
|
-
allReady,
|
|
1930
|
-
payloads,
|
|
1931
|
-
statusById
|
|
1932
|
-
};
|
|
1933
|
-
}
|
|
1934
1835
|
function classifyField(field) {
|
|
1935
1836
|
if (!field) return "text";
|
|
1936
1837
|
if (Array.isArray(field.oneOf) && field.oneOf.length > 0) return "select";
|
|
@@ -2047,66 +1948,6 @@ function buildContent(schema, values) {
|
|
|
2047
1948
|
}
|
|
2048
1949
|
return content;
|
|
2049
1950
|
}
|
|
2050
|
-
var ATTACHMENTS_SUFFIX_RE = /\n\n\[Attachments:[^\]]*\]\s*$/;
|
|
2051
|
-
function stripAttachmentsSuffixFromIntent(intent) {
|
|
2052
|
-
return intent.replace(ATTACHMENTS_SUFFIX_RE, "").trimEnd();
|
|
2053
|
-
}
|
|
2054
|
-
function mapFeedback(feedback) {
|
|
2055
|
-
if (!feedback?.feedback) return null;
|
|
2056
|
-
return feedback.feedback === "POSITIVE" ? "up" : "down";
|
|
2057
|
-
}
|
|
2058
|
-
function mapHistoryAttachments(executionId, attachments) {
|
|
2059
|
-
const mapped = (attachments ?? []).map((attachment, index) => ({
|
|
2060
|
-
id: `${executionId}:att:${index}`,
|
|
2061
|
-
filename: attachment.filename,
|
|
2062
|
-
mimeType: attachment.mimeType,
|
|
2063
|
-
url: attachment.url ?? void 0,
|
|
2064
|
-
kind: attachment.mimeType.startsWith("image/") ? "image" : "file"
|
|
2065
|
-
}));
|
|
2066
|
-
return mapped.length > 0 ? mapped : void 0;
|
|
2067
|
-
}
|
|
2068
|
-
function mapExecutionHistoryToChatMessages(message) {
|
|
2069
|
-
const timestamp = message.startTime || message.endTime || (/* @__PURE__ */ new Date()).toISOString();
|
|
2070
|
-
const executionId = message.executionId ?? message.traceId ?? message.id;
|
|
2071
|
-
const attachments = mapHistoryAttachments(message.id, message.attachments);
|
|
2072
|
-
const rows = [
|
|
2073
|
-
{
|
|
2074
|
-
id: `${message.id}:user`,
|
|
2075
|
-
role: "user",
|
|
2076
|
-
content: stripAttachmentsSuffixFromIntent(message.sessionUserIntent),
|
|
2077
|
-
timestamp,
|
|
2078
|
-
attachments
|
|
2079
|
-
}
|
|
2080
|
-
];
|
|
2081
|
-
if (message.agentResponse) {
|
|
2082
|
-
rows.push({
|
|
2083
|
-
id: `${message.id}:assistant`,
|
|
2084
|
-
role: "assistant",
|
|
2085
|
-
content: message.agentResponse,
|
|
2086
|
-
timestamp: message.endTime || timestamp,
|
|
2087
|
-
isError: message.status === "FAILED",
|
|
2088
|
-
executionId,
|
|
2089
|
-
feedback: mapFeedback(message.feedback)
|
|
2090
|
-
});
|
|
2091
|
-
}
|
|
2092
|
-
return rows;
|
|
2093
|
-
}
|
|
2094
|
-
function mapExecutionHistoryPageToChatMessages(messages) {
|
|
2095
|
-
return messages.flatMap(mapExecutionHistoryToChatMessages);
|
|
2096
|
-
}
|
|
2097
|
-
function attachmentDisplayUrl(attachment) {
|
|
2098
|
-
return attachment.previewUrl ?? attachment.url;
|
|
2099
|
-
}
|
|
2100
|
-
function isImageAttachment(attachment) {
|
|
2101
|
-
const displayUrl = attachmentDisplayUrl(attachment);
|
|
2102
|
-
return attachment.kind === "image" || Boolean(displayUrl) && attachment.mimeType.startsWith("image/");
|
|
2103
|
-
}
|
|
2104
|
-
function isPdfAttachmentMeta(attachment) {
|
|
2105
|
-
return attachment.mimeType === "application/pdf" || /\.pdf$/i.test(attachment.filename);
|
|
2106
|
-
}
|
|
2107
|
-
function isPdfFile(file) {
|
|
2108
|
-
return file.type === "application/pdf" || /\.pdf$/i.test(file.name);
|
|
2109
|
-
}
|
|
2110
1951
|
var PaymanChatContext = react.createContext(void 0);
|
|
2111
1952
|
function usePaymanChat() {
|
|
2112
1953
|
const context = react.useContext(PaymanChatContext);
|
|
@@ -2217,111 +2058,6 @@ function subscribeToCfRay(urlPattern, listener) {
|
|
|
2217
2058
|
};
|
|
2218
2059
|
}
|
|
2219
2060
|
|
|
2220
|
-
// src/utils/attachmentConfig.ts
|
|
2221
|
-
var DEFAULT_IMAGE_EXTENSIONS = ["png", "jpg", "jpeg", "gif", "webp"];
|
|
2222
|
-
var DEFAULT_DOCUMENT_EXTENSIONS = ["pdf", "docx", "xlsx", "xls"];
|
|
2223
|
-
function resolveChatAttachmentConfig(config) {
|
|
2224
|
-
const nested = config.attachments;
|
|
2225
|
-
const enabled = nested?.enabled ?? config.showAttachmentButton ?? true;
|
|
2226
|
-
const uploadImage = nested?.uploadImage ?? config.showUploadImageButton ?? true;
|
|
2227
|
-
const attachFile = nested?.attachFile ?? config.showAttachFileButton ?? true;
|
|
2228
|
-
return {
|
|
2229
|
-
showAttachmentButton: enabled && (uploadImage || attachFile),
|
|
2230
|
-
showUploadImageButton: enabled && uploadImage,
|
|
2231
|
-
showAttachFileButton: enabled && attachFile,
|
|
2232
|
-
maxCount: nested?.maxCount ?? nested?.maxImages ?? nested?.maxDocuments,
|
|
2233
|
-
maxFileBytes: nested?.maxFileBytes,
|
|
2234
|
-
maxTotalBytes: nested?.maxTotalBytes,
|
|
2235
|
-
allowedImageExtensions: nested?.imageExtensions ?? DEFAULT_IMAGE_EXTENSIONS,
|
|
2236
|
-
allowedFileExtensions: nested?.documentExtensions ?? DEFAULT_DOCUMENT_EXTENSIONS
|
|
2237
|
-
};
|
|
2238
|
-
}
|
|
2239
|
-
|
|
2240
|
-
// src/utils/formatAttachmentBytes.ts
|
|
2241
|
-
function formatAttachmentBytes(bytes) {
|
|
2242
|
-
if (!Number.isFinite(bytes) || bytes <= 0) return "0 B";
|
|
2243
|
-
const units = ["B", "KB", "MB", "GB"];
|
|
2244
|
-
let value = bytes;
|
|
2245
|
-
let unitIndex = 0;
|
|
2246
|
-
while (value >= 1024 && unitIndex < units.length - 1) {
|
|
2247
|
-
value /= 1024;
|
|
2248
|
-
unitIndex += 1;
|
|
2249
|
-
}
|
|
2250
|
-
const rounded = unitIndex === 0 ? String(Math.round(value)) : value >= 10 ? value.toFixed(0) : value.toFixed(1).replace(/\.0$/, "");
|
|
2251
|
-
return `${rounded} ${units[unitIndex]}`;
|
|
2252
|
-
}
|
|
2253
|
-
|
|
2254
|
-
// src/utils/pdfLink.ts
|
|
2255
|
-
function filenameFromContentDisposition(value) {
|
|
2256
|
-
if (!value) return void 0;
|
|
2257
|
-
let decoded = value;
|
|
2258
|
-
try {
|
|
2259
|
-
decoded = decodeURIComponent(value);
|
|
2260
|
-
} catch {
|
|
2261
|
-
decoded = value;
|
|
2262
|
-
}
|
|
2263
|
-
const quoted = decoded.match(/filename\*=(?:UTF-8''([^;]+)|"([^"]+)")/i);
|
|
2264
|
-
if (quoted?.[1] || quoted?.[2]) {
|
|
2265
|
-
return (quoted[1] ?? quoted[2])?.trim();
|
|
2266
|
-
}
|
|
2267
|
-
const unquoted = decoded.match(/filename=([^;]+)/i);
|
|
2268
|
-
return unquoted?.[1]?.replace(/"/g, "").trim();
|
|
2269
|
-
}
|
|
2270
|
-
function filenameFromUrlPath(href) {
|
|
2271
|
-
try {
|
|
2272
|
-
const parts = new URL(href).pathname.split("/").filter(Boolean);
|
|
2273
|
-
const last = parts[parts.length - 1];
|
|
2274
|
-
return last ? decodeURIComponent(last) : void 0;
|
|
2275
|
-
} catch {
|
|
2276
|
-
return void 0;
|
|
2277
|
-
}
|
|
2278
|
-
}
|
|
2279
|
-
function isPdfUrl(href) {
|
|
2280
|
-
if (!href) return false;
|
|
2281
|
-
const lower = href.toLowerCase();
|
|
2282
|
-
if (lower.includes(".pdf")) return true;
|
|
2283
|
-
try {
|
|
2284
|
-
const url = new URL(href);
|
|
2285
|
-
if (url.pathname.toLowerCase().endsWith(".pdf")) return true;
|
|
2286
|
-
const filename = url.searchParams.get("filename");
|
|
2287
|
-
if (filename?.toLowerCase().includes(".pdf")) return true;
|
|
2288
|
-
for (const key of ["rscd", "response-content-disposition"]) {
|
|
2289
|
-
const fromDisposition = filenameFromContentDisposition(
|
|
2290
|
-
url.searchParams.get(key)
|
|
2291
|
-
);
|
|
2292
|
-
if (fromDisposition?.toLowerCase().includes(".pdf")) return true;
|
|
2293
|
-
}
|
|
2294
|
-
} catch {
|
|
2295
|
-
return lower.endsWith(".pdf");
|
|
2296
|
-
}
|
|
2297
|
-
return false;
|
|
2298
|
-
}
|
|
2299
|
-
function getPdfTitleFromUrl(href, linkText) {
|
|
2300
|
-
const text = linkText?.trim();
|
|
2301
|
-
if (text) return text;
|
|
2302
|
-
try {
|
|
2303
|
-
const url = new URL(href);
|
|
2304
|
-
const filename = url.searchParams.get("filename");
|
|
2305
|
-
if (filename) {
|
|
2306
|
-
return filename.replace(/\.pdf$/i, "").replace(/[-_]+/g, " ").trim();
|
|
2307
|
-
}
|
|
2308
|
-
for (const key of ["rscd", "response-content-disposition"]) {
|
|
2309
|
-
const fromDisposition = filenameFromContentDisposition(
|
|
2310
|
-
url.searchParams.get(key)
|
|
2311
|
-
);
|
|
2312
|
-
if (fromDisposition) {
|
|
2313
|
-
return fromDisposition.replace(/\.pdf$/i, "").replace(/[-_]+/g, " ").trim();
|
|
2314
|
-
}
|
|
2315
|
-
}
|
|
2316
|
-
} catch {
|
|
2317
|
-
}
|
|
2318
|
-
const fromPath = filenameFromUrlPath(href);
|
|
2319
|
-
if (fromPath) {
|
|
2320
|
-
return fromPath.replace(/\.pdf$/i, "").replace(/[-_]+/g, " ").trim();
|
|
2321
|
-
}
|
|
2322
|
-
return "Document";
|
|
2323
|
-
}
|
|
2324
|
-
|
|
2325
2061
|
// src/utils/slashCommands.ts
|
|
2326
2062
|
var DEFAULT_SLASH_COMMANDS = [
|
|
2327
2063
|
{
|
|
@@ -3473,108 +3209,6 @@ function ActionTooltipV2({ label, children }) {
|
|
|
3473
3209
|
] }) })
|
|
3474
3210
|
] });
|
|
3475
3211
|
}
|
|
3476
|
-
function FilePreviewShell({
|
|
3477
|
-
filename,
|
|
3478
|
-
typeLabel,
|
|
3479
|
-
onClick,
|
|
3480
|
-
thumbnail,
|
|
3481
|
-
className,
|
|
3482
|
-
"aria-label": ariaLabel
|
|
3483
|
-
}) {
|
|
3484
|
-
const shellClass = cn(
|
|
3485
|
-
"payman-v2-file-preview-shell",
|
|
3486
|
-
"payman-v2-file-preview-shell-sent",
|
|
3487
|
-
onClick && "payman-v2-file-preview-shell-clickable",
|
|
3488
|
-
className
|
|
3489
|
-
);
|
|
3490
|
-
const body = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3491
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "payman-v2-file-preview-thumb", children: thumbnail ?? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3492
|
-
lucideReact.FileText,
|
|
3493
|
-
{
|
|
3494
|
-
size: 16,
|
|
3495
|
-
strokeWidth: 1.75,
|
|
3496
|
-
className: "payman-v2-file-preview-doc-icon"
|
|
3497
|
-
}
|
|
3498
|
-
) }),
|
|
3499
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "payman-v2-file-preview-info", children: [
|
|
3500
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "payman-v2-file-preview-name", children: filename }),
|
|
3501
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "payman-v2-file-preview-type", children: typeLabel })
|
|
3502
|
-
] })
|
|
3503
|
-
] });
|
|
3504
|
-
if (onClick) {
|
|
3505
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3506
|
-
"button",
|
|
3507
|
-
{
|
|
3508
|
-
type: "button",
|
|
3509
|
-
className: shellClass,
|
|
3510
|
-
onClick,
|
|
3511
|
-
"aria-label": ariaLabel ?? `Open ${filename}`,
|
|
3512
|
-
children: body
|
|
3513
|
-
}
|
|
3514
|
-
);
|
|
3515
|
-
}
|
|
3516
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: shellClass, children: body });
|
|
3517
|
-
}
|
|
3518
|
-
function FilePreviewBlockLayout({
|
|
3519
|
-
children,
|
|
3520
|
-
className,
|
|
3521
|
-
...rest
|
|
3522
|
-
}) {
|
|
3523
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("payman-v2-file-preview-item", className), ...rest, children });
|
|
3524
|
-
}
|
|
3525
|
-
function attachmentTypeLabel(attachment) {
|
|
3526
|
-
if (isImageAttachment(attachment)) {
|
|
3527
|
-
return "Image";
|
|
3528
|
-
}
|
|
3529
|
-
const ext = attachment.filename.split(".").pop()?.toUpperCase();
|
|
3530
|
-
return ext || "Document";
|
|
3531
|
-
}
|
|
3532
|
-
function isPdfAttachment(attachment) {
|
|
3533
|
-
const displayUrl = attachmentDisplayUrl(attachment);
|
|
3534
|
-
return isPdfAttachmentMeta(attachment) || Boolean(displayUrl) && isPdfUrl(displayUrl);
|
|
3535
|
-
}
|
|
3536
|
-
function AttachmentPreviewBlock({
|
|
3537
|
-
attachment,
|
|
3538
|
-
onImageClick
|
|
3539
|
-
}) {
|
|
3540
|
-
const chatContext = react.useContext(PaymanChatContext);
|
|
3541
|
-
const displayUrl = attachmentDisplayUrl(attachment);
|
|
3542
|
-
const typeLabel = attachmentTypeLabel(attachment);
|
|
3543
|
-
const isImage = isImageAttachment(attachment) && displayUrl;
|
|
3544
|
-
const openAttachment = () => {
|
|
3545
|
-
if (!displayUrl) return;
|
|
3546
|
-
if (isImageAttachment(attachment)) {
|
|
3547
|
-
onImageClick?.(displayUrl, attachment.filename);
|
|
3548
|
-
return;
|
|
3549
|
-
}
|
|
3550
|
-
if (isPdfAttachment(attachment)) {
|
|
3551
|
-
chatContext?.openPdfSheet(displayUrl, attachment.filename);
|
|
3552
|
-
return;
|
|
3553
|
-
}
|
|
3554
|
-
window.open(displayUrl, "_blank", "noopener,noreferrer");
|
|
3555
|
-
};
|
|
3556
|
-
if (isImage) {
|
|
3557
|
-
return /* @__PURE__ */ jsxRuntime.jsx(FilePreviewBlockLayout, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3558
|
-
FilePreviewShell,
|
|
3559
|
-
{
|
|
3560
|
-
filename: attachment.filename,
|
|
3561
|
-
typeLabel,
|
|
3562
|
-
onClick: openAttachment,
|
|
3563
|
-
"aria-label": `Preview ${attachment.filename}`,
|
|
3564
|
-
thumbnail: /* @__PURE__ */ jsxRuntime.jsx("img", { src: displayUrl, alt: "", draggable: false })
|
|
3565
|
-
}
|
|
3566
|
-
) });
|
|
3567
|
-
}
|
|
3568
|
-
return /* @__PURE__ */ jsxRuntime.jsx(FilePreviewBlockLayout, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3569
|
-
FilePreviewShell,
|
|
3570
|
-
{
|
|
3571
|
-
filename: attachment.filename,
|
|
3572
|
-
typeLabel,
|
|
3573
|
-
onClick: displayUrl ? openAttachment : void 0,
|
|
3574
|
-
"aria-label": `Open ${attachment.filename}`
|
|
3575
|
-
}
|
|
3576
|
-
) });
|
|
3577
|
-
}
|
|
3578
3212
|
function formatMessageTime(timestamp) {
|
|
3579
3213
|
const value = new Date(timestamp);
|
|
3580
3214
|
if (Number.isNaN(value.getTime())) return "";
|
|
@@ -3587,7 +3221,6 @@ function UserMessageV2({
|
|
|
3587
3221
|
message,
|
|
3588
3222
|
onEdit,
|
|
3589
3223
|
onRetry,
|
|
3590
|
-
onImageClick,
|
|
3591
3224
|
retryDisabled = false,
|
|
3592
3225
|
actions
|
|
3593
3226
|
}) {
|
|
@@ -3670,15 +3303,7 @@ function UserMessageV2({
|
|
|
3670
3303
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3671
3304
|
toastPortal,
|
|
3672
3305
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "payman-v2-user-msg payman-v2-fade-in", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "payman-v2-user-msg-group", children: [
|
|
3673
|
-
|
|
3674
|
-
AttachmentPreviewBlock,
|
|
3675
|
-
{
|
|
3676
|
-
attachment,
|
|
3677
|
-
onImageClick
|
|
3678
|
-
},
|
|
3679
|
-
attachment.id
|
|
3680
|
-
)) }),
|
|
3681
|
-
(message.content.trim().length > 0 || !message.attachments?.length) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "payman-v2-user-msg-bubble", children: parsedCommand ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "payman-v2-user-msg-command", children: [
|
|
3306
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "payman-v2-user-msg-bubble", children: parsedCommand ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "payman-v2-user-msg-command", children: [
|
|
3682
3307
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "payman-v2-user-msg-command-chip", children: parsedCommand.command }),
|
|
3683
3308
|
parsedCommand.body.trim() ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "payman-v2-user-msg-text", children: parsedCommand.body }) : null
|
|
3684
3309
|
] }) : /* @__PURE__ */ jsxRuntime.jsx("p", { className: "payman-v2-user-msg-text", children: message.content }) }),
|
|
@@ -3903,44 +3528,9 @@ function MarkdownImageV2({
|
|
|
3903
3528
|
}
|
|
3904
3529
|
) });
|
|
3905
3530
|
}
|
|
3906
|
-
function
|
|
3907
|
-
const autoOpenedHrefRef = react.useRef(null);
|
|
3908
|
-
react.useEffect(() => {
|
|
3909
|
-
if (!autoOpen || autoOpenedHrefRef.current === href) return;
|
|
3910
|
-
autoOpenedHrefRef.current = href;
|
|
3911
|
-
onOpen(href, title, { auto: true });
|
|
3912
|
-
}, [href, autoOpen]);
|
|
3913
|
-
return /* @__PURE__ */ jsxRuntime.jsx(FilePreviewBlockLayout, { "data-payman-file-block": true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3914
|
-
FilePreviewShell,
|
|
3915
|
-
{
|
|
3916
|
-
filename: title,
|
|
3917
|
-
typeLabel: "PDF",
|
|
3918
|
-
onClick: () => onOpen(href, title),
|
|
3919
|
-
"aria-label": `Open PDF: ${title}`
|
|
3920
|
-
}
|
|
3921
|
-
) });
|
|
3922
|
-
}
|
|
3923
|
-
function childrenToText(children) {
|
|
3924
|
-
if (typeof children === "string") return children;
|
|
3925
|
-
if (typeof children === "number") return String(children);
|
|
3926
|
-
if (Array.isArray(children)) return children.map(childrenToText).join("");
|
|
3927
|
-
if (children && typeof children === "object" && "props" in children) {
|
|
3928
|
-
return childrenToText(children.props.children);
|
|
3929
|
-
}
|
|
3930
|
-
return "";
|
|
3931
|
-
}
|
|
3932
|
-
function isFileBlockChild(child) {
|
|
3933
|
-
return react.isValidElement(child) && typeof child.props === "object" && child.props !== null && "data-payman-file-block" in child.props;
|
|
3934
|
-
}
|
|
3935
|
-
function buildComponents(onImageClick, isResolvingRef, onPdfClick, autoOpenPdf) {
|
|
3531
|
+
function buildComponents(onImageClick, isResolvingRef) {
|
|
3936
3532
|
return {
|
|
3937
|
-
p: ({ children }) => {
|
|
3938
|
-
const childArray = react.Children.toArray(children);
|
|
3939
|
-
if (childArray.length === 1 && isFileBlockChild(childArray[0])) {
|
|
3940
|
-
return childArray[0];
|
|
3941
|
-
}
|
|
3942
|
-
return /* @__PURE__ */ jsxRuntime.jsx("p", { children });
|
|
3943
|
-
},
|
|
3533
|
+
p: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("p", { children }),
|
|
3944
3534
|
code: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("code", { children }),
|
|
3945
3535
|
pre: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "payman-v2-markdown-pre", children: /* @__PURE__ */ jsxRuntime.jsx("pre", { children }) }),
|
|
3946
3536
|
ul: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("ul", { children }),
|
|
@@ -3953,15 +3543,7 @@ function buildComponents(onImageClick, isResolvingRef, onPdfClick, autoOpenPdf)
|
|
|
3953
3543
|
em: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("em", { children }),
|
|
3954
3544
|
blockquote: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("blockquote", { children }),
|
|
3955
3545
|
hr: () => /* @__PURE__ */ jsxRuntime.jsx("hr", {}),
|
|
3956
|
-
a: ({ href, children }) => {
|
|
3957
|
-
const url = href ?? "";
|
|
3958
|
-
if (onPdfClick && isPdfUrl(url)) {
|
|
3959
|
-
const linkText = childrenToText(children).trim();
|
|
3960
|
-
const title = getPdfTitleFromUrl(url, linkText);
|
|
3961
|
-
return /* @__PURE__ */ jsxRuntime.jsx(PdfBlockV2, { href: url, title, onOpen: onPdfClick, autoOpen: autoOpenPdf });
|
|
3962
|
-
}
|
|
3963
|
-
return /* @__PURE__ */ jsxRuntime.jsx("a", { href, target: "_blank", rel: "noopener noreferrer", children });
|
|
3964
|
-
},
|
|
3546
|
+
a: ({ href, children }) => /* @__PURE__ */ jsxRuntime.jsx("a", { href, target: "_blank", rel: "noopener noreferrer", children }),
|
|
3965
3547
|
img: ({ src, alt }) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
3966
3548
|
MarkdownImageV2,
|
|
3967
3549
|
{
|
|
@@ -3982,15 +3564,13 @@ function MarkdownRendererV2({
|
|
|
3982
3564
|
content,
|
|
3983
3565
|
isStreaming,
|
|
3984
3566
|
isResolvingImages,
|
|
3985
|
-
onImageClick
|
|
3986
|
-
onPdfClick,
|
|
3987
|
-
autoOpenPdf
|
|
3567
|
+
onImageClick
|
|
3988
3568
|
}) {
|
|
3989
3569
|
const isResolvingRef = react.useRef(isResolvingImages);
|
|
3990
3570
|
isResolvingRef.current = isResolvingImages;
|
|
3991
3571
|
const components = react.useMemo(
|
|
3992
|
-
() => buildComponents(onImageClick, isResolvingRef
|
|
3993
|
-
[onImageClick
|
|
3572
|
+
() => buildComponents(onImageClick, isResolvingRef),
|
|
3573
|
+
[onImageClick]
|
|
3994
3574
|
);
|
|
3995
3575
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3996
3576
|
"div",
|
|
@@ -4359,17 +3939,6 @@ function stripIncompleteImageToken(text) {
|
|
|
4359
3939
|
if (/^!\[[^\]]*\]\([^)]*\)/.test(after)) return text;
|
|
4360
3940
|
return text.slice(0, lastBang);
|
|
4361
3941
|
}
|
|
4362
|
-
function stripIncompleteLinkToken(text) {
|
|
4363
|
-
const lastBracket = text.lastIndexOf("[");
|
|
4364
|
-
if (lastBracket === -1) return text;
|
|
4365
|
-
if (lastBracket > 0 && text[lastBracket - 1] === "!") return text;
|
|
4366
|
-
const after = text.slice(lastBracket);
|
|
4367
|
-
if (/^\[[^\]]*\]\([^)]*\)/.test(after)) return text;
|
|
4368
|
-
return text.slice(0, lastBracket);
|
|
4369
|
-
}
|
|
4370
|
-
function stripIncompleteMarkdownTokens(text) {
|
|
4371
|
-
return stripIncompleteLinkToken(stripIncompleteImageToken(text));
|
|
4372
|
-
}
|
|
4373
3942
|
function getFeedbackState(message) {
|
|
4374
3943
|
const feedback = message.feedback;
|
|
4375
3944
|
if (feedback === "up" || feedback === "down") return feedback;
|
|
@@ -4393,12 +3962,6 @@ function AssistantMessageV2({
|
|
|
4393
3962
|
() => getFeedbackState(message)
|
|
4394
3963
|
);
|
|
4395
3964
|
const [reasonModalOpen, setReasonModalOpen] = react.useState(false);
|
|
4396
|
-
const chatContext = react.useContext(PaymanChatContext);
|
|
4397
|
-
const chatContextRef = react.useRef(chatContext);
|
|
4398
|
-
chatContextRef.current = chatContext;
|
|
4399
|
-
const handlePdfClick = react.useCallback((href, title, options) => {
|
|
4400
|
-
chatContextRef.current?.openPdfSheet(href, title, options);
|
|
4401
|
-
}, []);
|
|
4402
3965
|
const canSubmitFeedback = !!onSubmitFeedback && !!message.executionId;
|
|
4403
3966
|
const [toast, setToast] = react.useState(null);
|
|
4404
3967
|
const copyResetTimerRef = react.useRef(null);
|
|
@@ -4423,7 +3986,7 @@ function AssistantMessageV2({
|
|
|
4423
3986
|
const raw = message.isStreaming ? message.streamingContent || message.content : message.content;
|
|
4424
3987
|
if (!raw) return "";
|
|
4425
3988
|
const normalized = raw.replace(/\\n/g, "\n");
|
|
4426
|
-
return message.isStreaming ?
|
|
3989
|
+
return message.isStreaming ? stripIncompleteImageToken(normalized) : normalized;
|
|
4427
3990
|
})();
|
|
4428
3991
|
const isThinkingStreaming = !!message.isStreaming && !rawResponseContent && !message.isError;
|
|
4429
3992
|
const responseTypingEnabled = hasEverStreamed.current && Boolean(rawResponseContent) && !message.isError;
|
|
@@ -4593,12 +4156,10 @@ function AssistantMessageV2({
|
|
|
4593
4156
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "payman-v2-assistant-msg-content-area", children: displayContent ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
4594
4157
|
MarkdownRendererV2,
|
|
4595
4158
|
{
|
|
4596
|
-
content:
|
|
4159
|
+
content: displayContent,
|
|
4597
4160
|
isStreaming: message.isStreaming && !isCancelled || isResponseTyping,
|
|
4598
4161
|
isResolvingImages: message.isResolvingImages,
|
|
4599
|
-
onImageClick
|
|
4600
|
-
onPdfClick: handlePdfClick,
|
|
4601
|
-
autoOpenPdf: hasEverStreamed.current
|
|
4162
|
+
onImageClick
|
|
4602
4163
|
}
|
|
4603
4164
|
) : !isThinkingStreaming ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "payman-v2-assistant-msg-placeholder", children: "..." }) : null }),
|
|
4604
4165
|
isCancelled && message.isStreaming && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "payman-v2-assistant-msg-paused", children: [
|
|
@@ -4815,6 +4376,7 @@ function VerificationInline({
|
|
|
4815
4376
|
const [code, setCode] = react.useState("");
|
|
4816
4377
|
const [errored, setErrored] = react.useState(false);
|
|
4817
4378
|
const [resendSec, setResendSec] = react.useState(0);
|
|
4379
|
+
const [hiddenAfterResend, setHiddenAfterResend] = react.useState(false);
|
|
4818
4380
|
const lastSubmittedRef = react.useRef(null);
|
|
4819
4381
|
const resendTimerRef = react.useRef(void 0);
|
|
4820
4382
|
const status = prompt.status;
|
|
@@ -4828,6 +4390,9 @@ function VerificationInline({
|
|
|
4828
4390
|
lastSubmittedRef.current = null;
|
|
4829
4391
|
}
|
|
4830
4392
|
}, [prompt.subAction, prompt.userActionId]);
|
|
4393
|
+
react.useEffect(() => {
|
|
4394
|
+
setHiddenAfterResend(false);
|
|
4395
|
+
}, [prompt.expirySeconds, prompt.message, prompt.subAction, prompt.userActionId]);
|
|
4831
4396
|
react.useEffect(() => {
|
|
4832
4397
|
if (code.length < codeLen) lastSubmittedRef.current = null;
|
|
4833
4398
|
}, [code, codeLen]);
|
|
@@ -4878,11 +4443,13 @@ function VerificationInline({
|
|
|
4878
4443
|
if (locked || resendSec > 0) return;
|
|
4879
4444
|
setErrored(false);
|
|
4880
4445
|
setCode("");
|
|
4446
|
+
setHiddenAfterResend(true);
|
|
4881
4447
|
lastSubmittedRef.current = null;
|
|
4882
4448
|
try {
|
|
4883
4449
|
await onResend(prompt.userActionId);
|
|
4884
4450
|
startResendCooldown();
|
|
4885
4451
|
} catch {
|
|
4452
|
+
setHiddenAfterResend(false);
|
|
4886
4453
|
}
|
|
4887
4454
|
}, [locked, onResend, prompt.userActionId, resendSec, startResendCooldown]);
|
|
4888
4455
|
const handleCancel = react.useCallback(() => {
|
|
@@ -4890,6 +4457,7 @@ function VerificationInline({
|
|
|
4890
4457
|
void onCancel(prompt.userActionId);
|
|
4891
4458
|
}, [busy, onCancel, prompt.userActionId]);
|
|
4892
4459
|
const description = prompt.message?.trim() || (isNumeric ? `Enter the ${codeLen}-digit code to continue` : "Enter the verification code to continue");
|
|
4460
|
+
if (hiddenAfterResend) return null;
|
|
4893
4461
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "payman-v2-ua", role: "group", "aria-label": "Verification required", children: [
|
|
4894
4462
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "payman-v2-ua-head", children: [
|
|
4895
4463
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ShieldCheck, { className: "payman-v2-ua-icon", size: 15, strokeWidth: 1.75, "aria-hidden": true }),
|
|
@@ -4985,6 +4553,9 @@ function SchemaFormInline({
|
|
|
4985
4553
|
const busy = status === "submitting";
|
|
4986
4554
|
const stale = status === "stale";
|
|
4987
4555
|
const locked = busy || stale || expired;
|
|
4556
|
+
const isUserConfirmation = prompt.subAction === "UserConfirmation";
|
|
4557
|
+
const messageFormat = prompt.metadata?.["payman/messageFormat"];
|
|
4558
|
+
const renderMarkdown = messageFormat === "markdown";
|
|
4988
4559
|
const setValue = (key, value) => {
|
|
4989
4560
|
setValues((prev) => ({ ...prev, [key]: value }));
|
|
4990
4561
|
setErrors((prev) => {
|
|
@@ -5010,8 +4581,8 @@ function SchemaFormInline({
|
|
|
5010
4581
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "payman-v2-ua-title", children: "Action required" }),
|
|
5011
4582
|
typeof secondsLeft === "number" && !stale && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "payman-v2-ua-timer", children: expired ? "Expired" : `${secondsLeft}s` })
|
|
5012
4583
|
] }),
|
|
5013
|
-
prompt.message?.trim() && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "payman-v2-ua-desc", children: prompt.message }),
|
|
5014
|
-
stale ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "payman-v2-ua-stale", children: "This request is no longer available." }) : fields.length === 0 ?
|
|
4584
|
+
prompt.message?.trim() && (renderMarkdown ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "payman-v2-ua-markdown", children: /* @__PURE__ */ jsxRuntime.jsx(MarkdownRendererV2, { content: prompt.message }) }) : /* @__PURE__ */ jsxRuntime.jsx("p", { className: "payman-v2-ua-desc", children: prompt.message })),
|
|
4585
|
+
stale ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "payman-v2-ua-stale", children: "This request is no longer available." }) : fields.length === 0 ? null : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "payman-v2-ua-form", children: fields.map(([key, field]) => {
|
|
5015
4586
|
const widget = classifyField(field);
|
|
5016
4587
|
const label = field.title || key;
|
|
5017
4588
|
const required = isRequired(schema, key);
|
|
@@ -5084,7 +4655,7 @@ function SchemaFormInline({
|
|
|
5084
4655
|
className: "payman-v2-ua-btn payman-v2-ua-btn-primary",
|
|
5085
4656
|
disabled: locked,
|
|
5086
4657
|
onClick: handleSubmit,
|
|
5087
|
-
children: busy ? "Submitting\u2026" : "Submit"
|
|
4658
|
+
children: busy ? "Submitting\u2026" : isUserConfirmation ? "Confirm" : "Submit"
|
|
5088
4659
|
}
|
|
5089
4660
|
),
|
|
5090
4661
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -5140,10 +4711,25 @@ function useExpiryCountdown(prompt) {
|
|
|
5140
4711
|
const expired = initial !== void 0 && secondsLeft === 0;
|
|
5141
4712
|
return [secondsLeft, expired];
|
|
5142
4713
|
}
|
|
5143
|
-
function UserActionInline({
|
|
4714
|
+
function UserActionInline({
|
|
4715
|
+
prompt,
|
|
4716
|
+
onSubmit,
|
|
4717
|
+
onCancel,
|
|
4718
|
+
onResend,
|
|
4719
|
+
onExpired
|
|
4720
|
+
}) {
|
|
5144
4721
|
const [secondsLeft, expired] = useExpiryCountdown(prompt);
|
|
4722
|
+
react.useEffect(() => {
|
|
4723
|
+
if (expired && prompt.kind !== "notification") onExpired?.();
|
|
4724
|
+
}, [expired, onExpired, prompt.kind]);
|
|
5145
4725
|
let body;
|
|
5146
|
-
if (prompt.kind
|
|
4726
|
+
if (expired && prompt.kind !== "notification") {
|
|
4727
|
+
const note = {
|
|
4728
|
+
id: `${prompt.userActionId}-expired`,
|
|
4729
|
+
message: prompt.kind === "verification" ? "Verification Request Expired" : "User Form Expired"
|
|
4730
|
+
};
|
|
4731
|
+
body = /* @__PURE__ */ jsxRuntime.jsx(NotificationInline, { notification: note });
|
|
4732
|
+
} else if (prompt.kind === "verification") {
|
|
5147
4733
|
body = /* @__PURE__ */ jsxRuntime.jsx(
|
|
5148
4734
|
VerificationInline,
|
|
5149
4735
|
{
|
|
@@ -5183,10 +4769,23 @@ function UserActionInline({ prompt, onSubmit, onCancel, onResend }) {
|
|
|
5183
4769
|
}
|
|
5184
4770
|
var SCROLL_THRESHOLD2 = 100;
|
|
5185
4771
|
var USER_SCROLL_UP_EPSILON = 4;
|
|
4772
|
+
var PROMPT_KEY_SEPARATOR = "";
|
|
4773
|
+
function getPromptSlotKey(prompt) {
|
|
4774
|
+
return prompt.toolCallId || prompt.userActionId;
|
|
4775
|
+
}
|
|
4776
|
+
function getPromptViewKey(prompt) {
|
|
4777
|
+
return [
|
|
4778
|
+
getPromptSlotKey(prompt),
|
|
4779
|
+
prompt.userActionId,
|
|
4780
|
+
prompt.subAction ?? "",
|
|
4781
|
+
prompt.expirySeconds ?? "",
|
|
4782
|
+
prompt.message ?? ""
|
|
4783
|
+
].join(PROMPT_KEY_SEPARATOR);
|
|
4784
|
+
}
|
|
5186
4785
|
var MessageListV2 = react.forwardRef(
|
|
5187
4786
|
function MessageListV22({
|
|
5188
4787
|
messages,
|
|
5189
|
-
isStreaming
|
|
4788
|
+
isStreaming = false,
|
|
5190
4789
|
onEditUserMessage,
|
|
5191
4790
|
onRetryUserMessage,
|
|
5192
4791
|
onImageClick,
|
|
@@ -5198,10 +4797,10 @@ var MessageListV2 = react.forwardRef(
|
|
|
5198
4797
|
onSubmitUserAction,
|
|
5199
4798
|
onCancelUserAction,
|
|
5200
4799
|
onResendUserAction,
|
|
4800
|
+
onExpireUserAction,
|
|
5201
4801
|
onDismissNotification,
|
|
5202
4802
|
onSubmitFeedback,
|
|
5203
|
-
typingSpeed = 4
|
|
5204
|
-
sidePanelOpen = false
|
|
4803
|
+
typingSpeed = 4
|
|
5205
4804
|
}, ref) {
|
|
5206
4805
|
const noop = react.useCallback(async () => {
|
|
5207
4806
|
}, []);
|
|
@@ -5209,11 +4808,11 @@ var MessageListV2 = react.forwardRef(
|
|
|
5209
4808
|
const scrollInnerRef = react.useRef(null);
|
|
5210
4809
|
const isNearBottomRef = react.useRef(true);
|
|
5211
4810
|
const [showScrollBtn, setShowScrollBtn] = react.useState(false);
|
|
4811
|
+
const [expiredPromptViewState, setExpiredPromptViewState] = react.useState({});
|
|
4812
|
+
const expiredUserActionIdsRef = react.useRef(/* @__PURE__ */ new Set());
|
|
5212
4813
|
const prevCountRef = react.useRef(messages.length);
|
|
5213
4814
|
const pauseStickUntilUserMessageRef = react.useRef(false);
|
|
5214
4815
|
const followingBottomRef = react.useRef(true);
|
|
5215
|
-
const sidePanelOpenRef = react.useRef(sidePanelOpen);
|
|
5216
|
-
sidePanelOpenRef.current = sidePanelOpen;
|
|
5217
4816
|
const lastPinAtRef = react.useRef(0);
|
|
5218
4817
|
const prevScrollTopRef = react.useRef(0);
|
|
5219
4818
|
const getDistanceFromBottom = react.useCallback(() => {
|
|
@@ -5221,6 +4820,92 @@ var MessageListV2 = react.forwardRef(
|
|
|
5221
4820
|
if (!el) return 0;
|
|
5222
4821
|
return el.scrollHeight - el.scrollTop - el.clientHeight;
|
|
5223
4822
|
}, []);
|
|
4823
|
+
const messageActivityFingerprint = react.useMemo(() => {
|
|
4824
|
+
const last = messages[messages.length - 1];
|
|
4825
|
+
const promptFingerprint = (userActionPrompts ?? []).map((prompt) => `${getPromptViewKey(prompt)}:${prompt.status}`).join(PROMPT_KEY_SEPARATOR);
|
|
4826
|
+
const notificationFingerprint = (notifications ?? []).map((notification) => notification.id).join(PROMPT_KEY_SEPARATOR);
|
|
4827
|
+
if (!last) {
|
|
4828
|
+
return [
|
|
4829
|
+
0,
|
|
4830
|
+
isStreaming ? "streaming" : "idle",
|
|
4831
|
+
promptFingerprint,
|
|
4832
|
+
notificationFingerprint
|
|
4833
|
+
].join(PROMPT_KEY_SEPARATOR);
|
|
4834
|
+
}
|
|
4835
|
+
return [
|
|
4836
|
+
messages.length,
|
|
4837
|
+
isStreaming ? "streaming" : "idle",
|
|
4838
|
+
last.id,
|
|
4839
|
+
last.role,
|
|
4840
|
+
last.content ?? "",
|
|
4841
|
+
last.isStreaming ? "streaming" : "done",
|
|
4842
|
+
last.streamProgress ?? "",
|
|
4843
|
+
last.steps?.length ?? 0,
|
|
4844
|
+
last.errorDetails ?? "",
|
|
4845
|
+
promptFingerprint,
|
|
4846
|
+
notificationFingerprint
|
|
4847
|
+
].join(PROMPT_KEY_SEPARATOR);
|
|
4848
|
+
}, [isStreaming, messages, notifications, userActionPrompts]);
|
|
4849
|
+
const handleUserActionExpired = react.useCallback(
|
|
4850
|
+
(promptKey, userActionId) => {
|
|
4851
|
+
setExpiredPromptViewState((prev) => {
|
|
4852
|
+
if (prev[promptKey]) return prev;
|
|
4853
|
+
return {
|
|
4854
|
+
...prev,
|
|
4855
|
+
[promptKey]: { baseline: messageActivityFingerprint, hidden: false }
|
|
4856
|
+
};
|
|
4857
|
+
});
|
|
4858
|
+
if (!expiredUserActionIdsRef.current.has(userActionId)) {
|
|
4859
|
+
expiredUserActionIdsRef.current.add(userActionId);
|
|
4860
|
+
void onExpireUserAction?.(userActionId)?.catch(() => {
|
|
4861
|
+
});
|
|
4862
|
+
}
|
|
4863
|
+
},
|
|
4864
|
+
[messageActivityFingerprint, onExpireUserAction]
|
|
4865
|
+
);
|
|
4866
|
+
react.useEffect(() => {
|
|
4867
|
+
setExpiredPromptViewState((prev) => {
|
|
4868
|
+
let changed = false;
|
|
4869
|
+
const next = {};
|
|
4870
|
+
for (const [key, state] of Object.entries(prev)) {
|
|
4871
|
+
if (!state.hidden && state.baseline !== messageActivityFingerprint) {
|
|
4872
|
+
next[key] = { ...state, hidden: true };
|
|
4873
|
+
changed = true;
|
|
4874
|
+
} else {
|
|
4875
|
+
next[key] = state;
|
|
4876
|
+
}
|
|
4877
|
+
}
|
|
4878
|
+
return changed ? next : prev;
|
|
4879
|
+
});
|
|
4880
|
+
}, [messageActivityFingerprint]);
|
|
4881
|
+
react.useEffect(() => {
|
|
4882
|
+
const livePromptKeys = new Set((userActionPrompts ?? []).map(getPromptViewKey));
|
|
4883
|
+
const liveUserActionIds = new Set((userActionPrompts ?? []).map((p) => p.userActionId));
|
|
4884
|
+
for (const userActionId of expiredUserActionIdsRef.current) {
|
|
4885
|
+
if (!liveUserActionIds.has(userActionId)) {
|
|
4886
|
+
expiredUserActionIdsRef.current.delete(userActionId);
|
|
4887
|
+
}
|
|
4888
|
+
}
|
|
4889
|
+
setExpiredPromptViewState((prev) => {
|
|
4890
|
+
let changed = false;
|
|
4891
|
+
const next = {};
|
|
4892
|
+
for (const [key, state] of Object.entries(prev)) {
|
|
4893
|
+
if (livePromptKeys.has(key)) {
|
|
4894
|
+
next[key] = state;
|
|
4895
|
+
} else {
|
|
4896
|
+
changed = true;
|
|
4897
|
+
}
|
|
4898
|
+
}
|
|
4899
|
+
return changed ? next : prev;
|
|
4900
|
+
});
|
|
4901
|
+
}, [userActionPrompts]);
|
|
4902
|
+
const visibleUserActionPrompts = react.useMemo(
|
|
4903
|
+
() => userActionPrompts?.filter((prompt) => {
|
|
4904
|
+
const promptKey = getPromptViewKey(prompt);
|
|
4905
|
+
return !expiredPromptViewState[promptKey]?.hidden;
|
|
4906
|
+
}),
|
|
4907
|
+
[expiredPromptViewState, userActionPrompts]
|
|
4908
|
+
);
|
|
5224
4909
|
const pinToBottom = react.useCallback((behavior = "instant") => {
|
|
5225
4910
|
const el = scrollRef.current;
|
|
5226
4911
|
if (!el) return;
|
|
@@ -5261,25 +4946,17 @@ var MessageListV2 = react.forwardRef(
|
|
|
5261
4946
|
const nearBottom = distance <= SCROLL_THRESHOLD2;
|
|
5262
4947
|
isNearBottomRef.current = nearBottom;
|
|
5263
4948
|
setShowScrollBtn(!nearBottom);
|
|
4949
|
+
const sincePin = performance.now() - lastPinAtRef.current;
|
|
4950
|
+
if (sincePin < 250) return;
|
|
5264
4951
|
const scrolledUp = currentScrollTop < prevScrollTop - USER_SCROLL_UP_EPSILON;
|
|
5265
4952
|
if (scrolledUp) {
|
|
5266
4953
|
followingBottomRef.current = false;
|
|
5267
4954
|
pauseStickUntilUserMessageRef.current = true;
|
|
5268
|
-
|
|
5269
|
-
}
|
|
5270
|
-
const sincePin = performance.now() - lastPinAtRef.current;
|
|
5271
|
-
if (sincePin < 250) return;
|
|
5272
|
-
if (nearBottom) {
|
|
4955
|
+
} else if (nearBottom) {
|
|
5273
4956
|
followingBottomRef.current = true;
|
|
5274
4957
|
pauseStickUntilUserMessageRef.current = false;
|
|
5275
4958
|
}
|
|
5276
4959
|
}, [getDistanceFromBottom]);
|
|
5277
|
-
const handleWheel = react.useCallback((e) => {
|
|
5278
|
-
if (e.deltaY < 0) {
|
|
5279
|
-
followingBottomRef.current = false;
|
|
5280
|
-
pauseStickUntilUserMessageRef.current = true;
|
|
5281
|
-
}
|
|
5282
|
-
}, []);
|
|
5283
4960
|
react.useEffect(() => {
|
|
5284
4961
|
const prevCount = prevCountRef.current;
|
|
5285
4962
|
prevCountRef.current = messages.length;
|
|
@@ -5289,7 +4966,7 @@ var MessageListV2 = react.forwardRef(
|
|
|
5289
4966
|
pauseStickUntilUserMessageRef.current = false;
|
|
5290
4967
|
followingBottomRef.current = true;
|
|
5291
4968
|
requestAnimationFrame(() => scrollToBottom());
|
|
5292
|
-
} else if (!
|
|
4969
|
+
} else if (!pauseStickUntilUserMessageRef.current && followingBottomRef.current) {
|
|
5293
4970
|
requestAnimationFrame(() => scrollToBottom("instant"));
|
|
5294
4971
|
}
|
|
5295
4972
|
}
|
|
@@ -5298,16 +4975,27 @@ var MessageListV2 = react.forwardRef(
|
|
|
5298
4975
|
const inner = scrollInnerRef.current;
|
|
5299
4976
|
if (!inner) return;
|
|
5300
4977
|
const pinIfFollowing = () => {
|
|
5301
|
-
if (sidePanelOpenRef.current) return;
|
|
5302
4978
|
if (pauseStickUntilUserMessageRef.current) return;
|
|
5303
4979
|
if (!followingBottomRef.current) return;
|
|
5304
|
-
if (getDistanceFromBottom() > SCROLL_THRESHOLD2) return;
|
|
5305
4980
|
pinToBottom("instant");
|
|
5306
4981
|
};
|
|
5307
|
-
const ro = new ResizeObserver(
|
|
4982
|
+
const ro = new ResizeObserver(() => {
|
|
4983
|
+
pinIfFollowing();
|
|
4984
|
+
});
|
|
5308
4985
|
ro.observe(inner);
|
|
5309
|
-
|
|
5310
|
-
|
|
4986
|
+
const mo = new MutationObserver(() => {
|
|
4987
|
+
pinIfFollowing();
|
|
4988
|
+
});
|
|
4989
|
+
mo.observe(inner, {
|
|
4990
|
+
childList: true,
|
|
4991
|
+
subtree: true,
|
|
4992
|
+
characterData: true
|
|
4993
|
+
});
|
|
4994
|
+
return () => {
|
|
4995
|
+
ro.disconnect();
|
|
4996
|
+
mo.disconnect();
|
|
4997
|
+
};
|
|
4998
|
+
}, [pinToBottom]);
|
|
5311
4999
|
react.useEffect(() => {
|
|
5312
5000
|
if (messages.length > 0) {
|
|
5313
5001
|
setTimeout(() => scrollToBottom("instant"), 50);
|
|
@@ -5319,7 +5007,6 @@ var MessageListV2 = react.forwardRef(
|
|
|
5319
5007
|
{
|
|
5320
5008
|
ref: scrollRef,
|
|
5321
5009
|
onScroll: handleScroll,
|
|
5322
|
-
onWheel: handleWheel,
|
|
5323
5010
|
className: "payman-v2-message-scroll payman-v2-scrollbar",
|
|
5324
5011
|
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5325
5012
|
"div",
|
|
@@ -5333,7 +5020,6 @@ var MessageListV2 = react.forwardRef(
|
|
|
5333
5020
|
message,
|
|
5334
5021
|
onEdit: onEditUserMessage,
|
|
5335
5022
|
onRetry: onRetryUserMessage,
|
|
5336
|
-
onImageClick,
|
|
5337
5023
|
retryDisabled,
|
|
5338
5024
|
actions: messageActions?.userMessageActions
|
|
5339
5025
|
}
|
|
@@ -5356,16 +5042,20 @@ var MessageListV2 = react.forwardRef(
|
|
|
5356
5042
|
},
|
|
5357
5043
|
note.id
|
|
5358
5044
|
)),
|
|
5359
|
-
|
|
5360
|
-
|
|
5361
|
-
|
|
5362
|
-
|
|
5363
|
-
|
|
5364
|
-
|
|
5365
|
-
|
|
5366
|
-
|
|
5367
|
-
|
|
5368
|
-
|
|
5045
|
+
visibleUserActionPrompts?.map((prompt) => {
|
|
5046
|
+
const promptKey = getPromptViewKey(prompt);
|
|
5047
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5048
|
+
UserActionInline,
|
|
5049
|
+
{
|
|
5050
|
+
prompt,
|
|
5051
|
+
onSubmit: onSubmitUserAction ?? noop,
|
|
5052
|
+
onCancel: onCancelUserAction ?? noop,
|
|
5053
|
+
onResend: onResendUserAction ?? noop,
|
|
5054
|
+
onExpired: () => handleUserActionExpired(promptKey, prompt.userActionId)
|
|
5055
|
+
},
|
|
5056
|
+
promptKey
|
|
5057
|
+
);
|
|
5058
|
+
})
|
|
5369
5059
|
]
|
|
5370
5060
|
}
|
|
5371
5061
|
)
|
|
@@ -5395,121 +5085,11 @@ var MessageListV2 = react.forwardRef(
|
|
|
5395
5085
|
] });
|
|
5396
5086
|
}
|
|
5397
5087
|
);
|
|
5398
|
-
function FilePreviewModal({ src, name, onClose }) {
|
|
5399
|
-
const [isMounted, setIsMounted] = react.useState(false);
|
|
5400
|
-
const [isLoaded, setIsLoaded] = react.useState(false);
|
|
5401
|
-
react.useEffect(() => {
|
|
5402
|
-
setIsMounted(true);
|
|
5403
|
-
return () => setIsMounted(false);
|
|
5404
|
-
}, []);
|
|
5405
|
-
react.useEffect(() => {
|
|
5406
|
-
setIsLoaded(false);
|
|
5407
|
-
}, [src]);
|
|
5408
|
-
const handleKeyDown = react.useCallback(
|
|
5409
|
-
(e) => {
|
|
5410
|
-
if (e.key === "Escape") onClose();
|
|
5411
|
-
},
|
|
5412
|
-
[onClose]
|
|
5413
|
-
);
|
|
5414
|
-
react.useEffect(() => {
|
|
5415
|
-
if (!src || typeof document === "undefined") return;
|
|
5416
|
-
document.addEventListener("keydown", handleKeyDown);
|
|
5417
|
-
const prev = document.body.style.overflow;
|
|
5418
|
-
document.body.style.overflow = "hidden";
|
|
5419
|
-
return () => {
|
|
5420
|
-
document.removeEventListener("keydown", handleKeyDown);
|
|
5421
|
-
document.body.style.overflow = prev;
|
|
5422
|
-
};
|
|
5423
|
-
}, [src, handleKeyDown]);
|
|
5424
|
-
if (!isMounted || typeof document === "undefined") return null;
|
|
5425
|
-
return reactDom.createPortal(
|
|
5426
|
-
/* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: src ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5427
|
-
framerMotion.motion.div,
|
|
5428
|
-
{
|
|
5429
|
-
className: "payman-v2-file-preview-overlay",
|
|
5430
|
-
initial: { opacity: 0 },
|
|
5431
|
-
animate: { opacity: 1 },
|
|
5432
|
-
exit: { opacity: 0 },
|
|
5433
|
-
transition: { duration: 0.18 },
|
|
5434
|
-
onClick: onClose,
|
|
5435
|
-
role: "dialog",
|
|
5436
|
-
"aria-modal": "true",
|
|
5437
|
-
"aria-label": `Preview: ${name}`,
|
|
5438
|
-
children: [
|
|
5439
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5440
|
-
"button",
|
|
5441
|
-
{
|
|
5442
|
-
type: "button",
|
|
5443
|
-
className: "payman-v2-file-preview-close",
|
|
5444
|
-
"aria-label": "Close preview",
|
|
5445
|
-
onClick: (e) => {
|
|
5446
|
-
e.stopPropagation();
|
|
5447
|
-
onClose();
|
|
5448
|
-
},
|
|
5449
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { size: 18, strokeWidth: 2 })
|
|
5450
|
-
}
|
|
5451
|
-
),
|
|
5452
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5453
|
-
framerMotion.motion.div,
|
|
5454
|
-
{
|
|
5455
|
-
className: "payman-v2-file-preview-inner",
|
|
5456
|
-
initial: { scale: 0.93, opacity: 0 },
|
|
5457
|
-
animate: { scale: isLoaded ? 1 : 0.93, opacity: isLoaded ? 1 : 0 },
|
|
5458
|
-
exit: { scale: 0.93, opacity: 0 },
|
|
5459
|
-
transition: { duration: 0.2 },
|
|
5460
|
-
onClick: (e) => e.stopPropagation(),
|
|
5461
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5462
|
-
"img",
|
|
5463
|
-
{
|
|
5464
|
-
src,
|
|
5465
|
-
alt: name,
|
|
5466
|
-
className: "payman-v2-file-preview-img",
|
|
5467
|
-
draggable: false,
|
|
5468
|
-
onLoad: () => setIsLoaded(true)
|
|
5469
|
-
}
|
|
5470
|
-
)
|
|
5471
|
-
}
|
|
5472
|
-
)
|
|
5473
|
-
]
|
|
5474
|
-
},
|
|
5475
|
-
"file-preview"
|
|
5476
|
-
) : null }),
|
|
5477
|
-
document.body
|
|
5478
|
-
);
|
|
5479
|
-
}
|
|
5480
|
-
function normalizeExtension(ext) {
|
|
5481
|
-
return ext.replace(/^\./, "").toLowerCase();
|
|
5482
|
-
}
|
|
5483
|
-
function extOf(filename) {
|
|
5484
|
-
return filename.split(".").pop()?.toLowerCase() ?? "";
|
|
5485
|
-
}
|
|
5486
|
-
function isAllowedImage(file, allowedExtensions) {
|
|
5487
|
-
const allowed = new Set(allowedExtensions.map(normalizeExtension));
|
|
5488
|
-
const ext = extOf(file.name);
|
|
5489
|
-
if (allowed.has(ext)) return true;
|
|
5490
|
-
if (!file.type.startsWith("image/")) return false;
|
|
5491
|
-
const mimeSubtype = file.type.slice("image/".length).toLowerCase();
|
|
5492
|
-
return allowed.has(mimeSubtype) || mimeSubtype === "jpeg" && allowed.has("jpg");
|
|
5493
|
-
}
|
|
5494
|
-
function isAllowedDocument(file, allowedExtensions) {
|
|
5495
|
-
const allowed = new Set(allowedExtensions.map(normalizeExtension));
|
|
5496
|
-
return allowed.has(extOf(file.name));
|
|
5497
|
-
}
|
|
5498
|
-
function fileTypeLabel(file, kind) {
|
|
5499
|
-
if (kind === "image") return "Image";
|
|
5500
|
-
const ext = extOf(file.name);
|
|
5501
|
-
return ext ? ext.toUpperCase() : "Document";
|
|
5502
|
-
}
|
|
5503
5088
|
var ChatInputV2 = react.forwardRef(
|
|
5504
5089
|
function ChatInputV22({
|
|
5505
5090
|
onSend,
|
|
5506
5091
|
disabled = false,
|
|
5507
5092
|
isStreaming = false,
|
|
5508
|
-
isUploadingAttachments = false,
|
|
5509
|
-
attachmentsReady = true,
|
|
5510
|
-
hasAttachmentUploadErrors = false,
|
|
5511
|
-
attachmentUploadStatusById = {},
|
|
5512
|
-
uploadedAttachmentPayloads = [],
|
|
5513
5093
|
placeholder = "Reply...",
|
|
5514
5094
|
enableVoice = false,
|
|
5515
5095
|
voiceAvailable = false,
|
|
@@ -5523,13 +5103,6 @@ var ChatInputV2 = react.forwardRef(
|
|
|
5523
5103
|
showAttachFileButton = true,
|
|
5524
5104
|
onUploadImageClick,
|
|
5525
5105
|
onAttachFileClick,
|
|
5526
|
-
allowedImageExtensions = ["png", "jpg", "jpeg", "gif", "webp"],
|
|
5527
|
-
allowedFileExtensions = ["pdf", "docx", "xlsx", "xls"],
|
|
5528
|
-
maxCount,
|
|
5529
|
-
maxFileBytes,
|
|
5530
|
-
maxTotalBytes,
|
|
5531
|
-
onFilesChange,
|
|
5532
|
-
onAttachmentsChange,
|
|
5533
5106
|
editingMessageId = null,
|
|
5534
5107
|
onClearEditing,
|
|
5535
5108
|
analysisMode,
|
|
@@ -5543,140 +5116,21 @@ var ChatInputV2 = react.forwardRef(
|
|
|
5543
5116
|
const [selectedCommandIndex, setSelectedCommandIndex] = react.useState(0);
|
|
5544
5117
|
const [inlineHint, setInlineHint] = react.useState(null);
|
|
5545
5118
|
const [commandMenuDismissed, setCommandMenuDismissed] = react.useState(false);
|
|
5546
|
-
const [attachedFiles, setAttachedFiles] = react.useState([]);
|
|
5547
|
-
const [previewFile, setPreviewFile] = react.useState(null);
|
|
5548
|
-
const [isSending, setIsSending] = react.useState(false);
|
|
5549
5119
|
const textareaRef = react.useRef(null);
|
|
5550
5120
|
const actionsRef = react.useRef(null);
|
|
5551
|
-
const imageInputRef = react.useRef(null);
|
|
5552
|
-
const fileInputRef = react.useRef(null);
|
|
5553
5121
|
const preRecordTextRef = react.useRef("");
|
|
5554
5122
|
const voiceTooltipTimerRef = react.useRef(
|
|
5555
5123
|
null
|
|
5556
5124
|
);
|
|
5557
5125
|
const voiceDraftSyncActiveRef = react.useRef(false);
|
|
5558
|
-
const
|
|
5559
|
-
|
|
5560
|
-
|
|
5561
|
-
|
|
5562
|
-
|
|
5563
|
-
|
|
5564
|
-
const
|
|
5565
|
-
(
|
|
5566
|
-
onFilesChange?.(files.map((f) => f.file));
|
|
5567
|
-
onAttachmentsChange?.(files.map((f) => ({ id: f.id, file: f.file })));
|
|
5568
|
-
},
|
|
5569
|
-
[onAttachmentsChange, onFilesChange]
|
|
5570
|
-
);
|
|
5571
|
-
const clearAttachmentsFromInput = react.useCallback(() => {
|
|
5572
|
-
setAttachedFiles((prev) => {
|
|
5573
|
-
prev.forEach((f) => URL.revokeObjectURL(f.objectUrl));
|
|
5574
|
-
return [];
|
|
5575
|
-
});
|
|
5576
|
-
setPreviewFile(null);
|
|
5577
|
-
onFilesChange?.([]);
|
|
5578
|
-
onAttachmentsChange?.([]);
|
|
5579
|
-
}, [onAttachmentsChange, onFilesChange]);
|
|
5580
|
-
const addFiles = react.useCallback(
|
|
5581
|
-
(incoming, source) => {
|
|
5582
|
-
const isImage = source === "image";
|
|
5583
|
-
const allowedExtensions = isImage ? allowedImageExtensions : allowedFileExtensions;
|
|
5584
|
-
const isAllowed = isImage ? isAllowedImage : isAllowedDocument;
|
|
5585
|
-
const kindLabel = isImage ? "image" : "document";
|
|
5586
|
-
setAttachedFiles((prev) => {
|
|
5587
|
-
const accepted = [];
|
|
5588
|
-
let rejectedType = false;
|
|
5589
|
-
let hitCountLimit = false;
|
|
5590
|
-
let hitFileSizeLimit = false;
|
|
5591
|
-
let hitTotalSizeLimit = false;
|
|
5592
|
-
let oversizedName = "";
|
|
5593
|
-
const currentTotalBytes = prev.reduce(
|
|
5594
|
-
(sum, item) => sum + item.file.size,
|
|
5595
|
-
0
|
|
5596
|
-
);
|
|
5597
|
-
let addedBytes = 0;
|
|
5598
|
-
for (const file of incoming) {
|
|
5599
|
-
if (!isAllowed(file, allowedExtensions)) {
|
|
5600
|
-
rejectedType = true;
|
|
5601
|
-
continue;
|
|
5602
|
-
}
|
|
5603
|
-
if (maxFileBytes != null && file.size > maxFileBytes) {
|
|
5604
|
-
hitFileSizeLimit = true;
|
|
5605
|
-
oversizedName = file.name;
|
|
5606
|
-
continue;
|
|
5607
|
-
}
|
|
5608
|
-
if (maxTotalBytes != null && currentTotalBytes + addedBytes + file.size > maxTotalBytes) {
|
|
5609
|
-
hitTotalSizeLimit = true;
|
|
5610
|
-
break;
|
|
5611
|
-
}
|
|
5612
|
-
if (maxCount != null && prev.length + accepted.length >= maxCount) {
|
|
5613
|
-
hitCountLimit = true;
|
|
5614
|
-
break;
|
|
5615
|
-
}
|
|
5616
|
-
accepted.push({
|
|
5617
|
-
id: `${Date.now()}-${Math.random()}`,
|
|
5618
|
-
file,
|
|
5619
|
-
kind: source,
|
|
5620
|
-
objectUrl: URL.createObjectURL(file)
|
|
5621
|
-
});
|
|
5622
|
-
addedBytes += file.size;
|
|
5623
|
-
}
|
|
5624
|
-
if (rejectedType) {
|
|
5625
|
-
setInlineHint(
|
|
5626
|
-
`Unsupported ${kindLabel} type. Allowed: ${allowedExtensions.map(normalizeExtension).join(", ")}.`
|
|
5627
|
-
);
|
|
5628
|
-
} else if (hitFileSizeLimit) {
|
|
5629
|
-
setInlineHint(
|
|
5630
|
-
maxFileBytes != null ? `"${oversizedName}" exceeds the ${formatAttachmentBytes(maxFileBytes)} per-file limit.` : "File exceeds the maximum allowed size."
|
|
5631
|
-
);
|
|
5632
|
-
} else if (hitTotalSizeLimit) {
|
|
5633
|
-
setInlineHint(
|
|
5634
|
-
maxTotalBytes != null ? `Total attachment size would exceed ${formatAttachmentBytes(maxTotalBytes)}.` : "Total attachment size exceeds the limit."
|
|
5635
|
-
);
|
|
5636
|
-
} else if (hitCountLimit) {
|
|
5637
|
-
setInlineHint(
|
|
5638
|
-
maxCount === 1 ? "Only 1 attachment is allowed per message." : `Maximum ${maxCount} attachments allowed per message.`
|
|
5639
|
-
);
|
|
5640
|
-
}
|
|
5641
|
-
if (accepted.length === 0) return prev;
|
|
5642
|
-
const updated = [...prev, ...accepted];
|
|
5643
|
-
notifyAttachmentList(updated);
|
|
5644
|
-
return updated;
|
|
5645
|
-
});
|
|
5646
|
-
},
|
|
5647
|
-
[
|
|
5648
|
-
allowedFileExtensions,
|
|
5649
|
-
allowedImageExtensions,
|
|
5650
|
-
maxCount,
|
|
5651
|
-
maxFileBytes,
|
|
5652
|
-
maxTotalBytes,
|
|
5653
|
-
notifyAttachmentList
|
|
5654
|
-
]
|
|
5655
|
-
);
|
|
5656
|
-
const removeFile = react.useCallback(
|
|
5657
|
-
(id) => {
|
|
5658
|
-
setAttachedFiles((prev) => {
|
|
5659
|
-
const target = prev.find((f) => f.id === id);
|
|
5660
|
-
if (target) URL.revokeObjectURL(target.objectUrl);
|
|
5661
|
-
const updated = prev.filter((f) => f.id !== id);
|
|
5662
|
-
notifyAttachmentList(updated);
|
|
5663
|
-
return updated;
|
|
5664
|
-
});
|
|
5665
|
-
setPreviewFile((p) => p?.id === id ? null : p);
|
|
5666
|
-
},
|
|
5667
|
-
[notifyAttachmentList]
|
|
5668
|
-
);
|
|
5669
|
-
const imageAccept = allowedImageExtensions.map((e) => `.${e.replace(/^\./, "")}`).join(",");
|
|
5670
|
-
const fileAccept = allowedFileExtensions.map((e) => `.${e.replace(/^\./, "")}`).join(",");
|
|
5671
|
-
const isInputBusy = isSending || isUploadingAttachments;
|
|
5672
|
-
const isInputLocked = disabled || isRecording || isInputBusy;
|
|
5673
|
-
const hasAttachmentOptions = showUploadImageButton || showAttachFileButton;
|
|
5674
|
-
const showAttachmentMenuButton = showAttachmentButton && hasAttachmentOptions;
|
|
5675
|
-
const showVoiceButton = enableVoice && onVoicePress != null;
|
|
5676
|
-
const isVoiceButtonDisabled = disabled || !voiceAvailable;
|
|
5677
|
-
const commandQuery = value.startsWith("/") && !value.includes("\n") && !/\s/.test(value) ? value.toLowerCase() : null;
|
|
5678
|
-
const commandSuggestions = commandQuery == null ? [] : slashCommands.filter(
|
|
5679
|
-
(command) => command.name.toLowerCase().startsWith(commandQuery)
|
|
5126
|
+
const isInputLocked = disabled || isRecording;
|
|
5127
|
+
const hasAttachmentOptions = showUploadImageButton || showAttachFileButton;
|
|
5128
|
+
const showAttachmentMenuButton = showAttachmentButton && hasAttachmentOptions;
|
|
5129
|
+
const showVoiceButton = enableVoice && onVoicePress != null;
|
|
5130
|
+
const isVoiceButtonDisabled = disabled || !voiceAvailable;
|
|
5131
|
+
const commandQuery = value.startsWith("/") && !value.includes("\n") && !/\s/.test(value) ? value.toLowerCase() : null;
|
|
5132
|
+
const commandSuggestions = commandQuery == null ? [] : slashCommands.filter(
|
|
5133
|
+
(command) => command.name.toLowerCase().startsWith(commandQuery)
|
|
5680
5134
|
);
|
|
5681
5135
|
const showCommandSuggestions = !commandMenuDismissed && !isRecording && !disabled && commandSuggestions.length > 0;
|
|
5682
5136
|
react.useEffect(() => {
|
|
@@ -5709,10 +5163,9 @@ var ChatInputV2 = react.forwardRef(
|
|
|
5709
5163
|
const end = message.length;
|
|
5710
5164
|
textarea.setSelectionRange(end, end);
|
|
5711
5165
|
});
|
|
5712
|
-
}
|
|
5713
|
-
clearAttachments: clearAttachmentsFromInput
|
|
5166
|
+
}
|
|
5714
5167
|
}),
|
|
5715
|
-
[disabled
|
|
5168
|
+
[disabled]
|
|
5716
5169
|
);
|
|
5717
5170
|
react.useEffect(() => {
|
|
5718
5171
|
if (!showActions) return;
|
|
@@ -5746,23 +5199,8 @@ var ChatInputV2 = react.forwardRef(
|
|
|
5746
5199
|
const separator = base && !base.endsWith(" ") && transcribedText ? " " : "";
|
|
5747
5200
|
setValue(`${base}${separator}${transcribedText}`);
|
|
5748
5201
|
}, [isRecording, transcribedText]);
|
|
5749
|
-
|
|
5750
|
-
if (
|
|
5751
|
-
if (status === "error") return "Upload failed";
|
|
5752
|
-
return fileTypeLabel(file, kind);
|
|
5753
|
-
}
|
|
5754
|
-
const handleSend = react.useCallback(async () => {
|
|
5755
|
-
const hasText = value.trim().length > 0;
|
|
5756
|
-
const hasFiles = attachedFiles.length > 0;
|
|
5757
|
-
if (!hasText && !hasFiles || disabled || isSending || isUploadingAttachments) return;
|
|
5758
|
-
if (hasFiles && !attachmentsReady) {
|
|
5759
|
-
setInlineHint("Waiting for attachments to finish uploading.");
|
|
5760
|
-
return;
|
|
5761
|
-
}
|
|
5762
|
-
if (hasFiles && hasAttachmentUploadErrors) {
|
|
5763
|
-
setInlineHint("Remove or re-add attachments that failed to upload.");
|
|
5764
|
-
return;
|
|
5765
|
-
}
|
|
5202
|
+
const handleSend = react.useCallback(() => {
|
|
5203
|
+
if (!value.trim() || disabled) return;
|
|
5766
5204
|
const commandHint = getSlashCommandValidationHint(value);
|
|
5767
5205
|
if (commandHint) {
|
|
5768
5206
|
setInlineHint(commandHint);
|
|
@@ -5772,38 +5210,15 @@ var ChatInputV2 = react.forwardRef(
|
|
|
5772
5210
|
preRecordTextRef.current = "";
|
|
5773
5211
|
setInlineHint(null);
|
|
5774
5212
|
onClearEditing?.();
|
|
5775
|
-
|
|
5776
|
-
const filesToSend = attachedFiles.map((f) => f.file);
|
|
5777
|
-
const attachmentsToSend = [...uploadedAttachmentPayloads];
|
|
5213
|
+
onSend(value.trim());
|
|
5778
5214
|
setValue("");
|
|
5779
|
-
clearAttachmentsFromInput();
|
|
5780
5215
|
requestAnimationFrame(() => {
|
|
5781
5216
|
if (textareaRef.current) {
|
|
5782
5217
|
textareaRef.current.style.height = "auto";
|
|
5783
5218
|
textareaRef.current.focus();
|
|
5784
5219
|
}
|
|
5785
5220
|
});
|
|
5786
|
-
|
|
5787
|
-
try {
|
|
5788
|
-
await onSend(textToSend, filesToSend, attachmentsToSend);
|
|
5789
|
-
} catch {
|
|
5790
|
-
setInlineHint("Failed to send message. Please try again.");
|
|
5791
|
-
} finally {
|
|
5792
|
-
setIsSending(false);
|
|
5793
|
-
}
|
|
5794
|
-
}, [
|
|
5795
|
-
value,
|
|
5796
|
-
attachedFiles,
|
|
5797
|
-
uploadedAttachmentPayloads,
|
|
5798
|
-
disabled,
|
|
5799
|
-
isSending,
|
|
5800
|
-
isUploadingAttachments,
|
|
5801
|
-
attachmentsReady,
|
|
5802
|
-
hasAttachmentUploadErrors,
|
|
5803
|
-
onClearEditing,
|
|
5804
|
-
onSend,
|
|
5805
|
-
clearAttachmentsFromInput
|
|
5806
|
-
]);
|
|
5221
|
+
}, [value, disabled, onClearEditing, onSend]);
|
|
5807
5222
|
const selectCommand = react.useCallback(
|
|
5808
5223
|
(command) => {
|
|
5809
5224
|
const insertText = command.insertText ?? `${command.name} `;
|
|
@@ -5848,30 +5263,18 @@ var ChatInputV2 = react.forwardRef(
|
|
|
5848
5263
|
}
|
|
5849
5264
|
if (e.key === "Enter" && !e.shiftKey) {
|
|
5850
5265
|
e.preventDefault();
|
|
5851
|
-
if (isStreaming
|
|
5852
|
-
|
|
5266
|
+
if (isStreaming) return;
|
|
5267
|
+
handleSend();
|
|
5853
5268
|
}
|
|
5854
5269
|
};
|
|
5855
5270
|
const handleUploadImageClick = () => {
|
|
5856
|
-
imageInputRef.current?.click();
|
|
5857
5271
|
onUploadImageClick?.();
|
|
5858
5272
|
setShowActions(false);
|
|
5859
5273
|
};
|
|
5860
5274
|
const handleAttachFileClick = () => {
|
|
5861
|
-
fileInputRef.current?.click();
|
|
5862
5275
|
onAttachFileClick?.();
|
|
5863
5276
|
setShowActions(false);
|
|
5864
5277
|
};
|
|
5865
|
-
const handleImageFilesSelected = (e) => {
|
|
5866
|
-
const files = Array.from(e.target.files ?? []);
|
|
5867
|
-
if (files.length) addFiles(files, "image");
|
|
5868
|
-
e.target.value = "";
|
|
5869
|
-
};
|
|
5870
|
-
const handleDocFilesSelected = (e) => {
|
|
5871
|
-
const files = Array.from(e.target.files ?? []);
|
|
5872
|
-
if (files.length) addFiles(files, "file");
|
|
5873
|
-
e.target.value = "";
|
|
5874
|
-
};
|
|
5875
5278
|
const hideVoiceTooltip = react.useCallback(() => {
|
|
5876
5279
|
if (voiceTooltipTimerRef.current) {
|
|
5877
5280
|
clearTimeout(voiceTooltipTimerRef.current);
|
|
@@ -5899,39 +5302,9 @@ var ChatInputV2 = react.forwardRef(
|
|
|
5899
5302
|
}
|
|
5900
5303
|
onVoicePress();
|
|
5901
5304
|
};
|
|
5902
|
-
const canSend =
|
|
5903
|
-
const sendDisabled = !canSend || isStreaming
|
|
5305
|
+
const canSend = value.trim().length > 0 && !disabled;
|
|
5306
|
+
const sendDisabled = !canSend || isStreaming;
|
|
5904
5307
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "payman-v2-input-container", children: [
|
|
5905
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5906
|
-
"input",
|
|
5907
|
-
{
|
|
5908
|
-
ref: imageInputRef,
|
|
5909
|
-
type: "file",
|
|
5910
|
-
accept: imageAccept,
|
|
5911
|
-
multiple: maxCount == null || maxCount > 1,
|
|
5912
|
-
style: { display: "none" },
|
|
5913
|
-
onChange: handleImageFilesSelected
|
|
5914
|
-
}
|
|
5915
|
-
),
|
|
5916
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5917
|
-
"input",
|
|
5918
|
-
{
|
|
5919
|
-
ref: fileInputRef,
|
|
5920
|
-
type: "file",
|
|
5921
|
-
accept: fileAccept,
|
|
5922
|
-
multiple: maxCount == null || maxCount > 1,
|
|
5923
|
-
style: { display: "none" },
|
|
5924
|
-
onChange: handleDocFilesSelected
|
|
5925
|
-
}
|
|
5926
|
-
),
|
|
5927
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5928
|
-
FilePreviewModal,
|
|
5929
|
-
{
|
|
5930
|
-
src: previewFile?.kind === "image" ? previewFile.objectUrl : null,
|
|
5931
|
-
name: previewFile?.file.name ?? "",
|
|
5932
|
-
onClose: () => setPreviewFile(null)
|
|
5933
|
-
}
|
|
5934
|
-
),
|
|
5935
5308
|
/* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: showCommandSuggestions && /* @__PURE__ */ jsxRuntime.jsx(
|
|
5936
5309
|
framerMotion.motion.div,
|
|
5937
5310
|
{
|
|
@@ -5970,115 +5343,6 @@ var ChatInputV2 = react.forwardRef(
|
|
|
5970
5343
|
),
|
|
5971
5344
|
children: [
|
|
5972
5345
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "payman-v2-input-body", children: [
|
|
5973
|
-
/* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { initial: false, children: attachedFiles.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
5974
|
-
framerMotion.motion.div,
|
|
5975
|
-
{
|
|
5976
|
-
initial: { opacity: 0, height: 0 },
|
|
5977
|
-
animate: { opacity: 1, height: "auto" },
|
|
5978
|
-
exit: { opacity: 0, height: 0 },
|
|
5979
|
-
transition: { duration: 0.15, ease: "easeOut" },
|
|
5980
|
-
className: "payman-v2-file-preview",
|
|
5981
|
-
children: attachedFiles.map((af) => {
|
|
5982
|
-
const uploadStatus = attachmentUploadStatusById[af.id];
|
|
5983
|
-
const isUploadingFile = uploadStatus === "uploading";
|
|
5984
|
-
const hasUploadError = uploadStatus === "error";
|
|
5985
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "payman-v2-file-preview-item", children: [
|
|
5986
|
-
af.kind === "image" ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5987
|
-
"button",
|
|
5988
|
-
{
|
|
5989
|
-
type: "button",
|
|
5990
|
-
className: cn(
|
|
5991
|
-
"payman-v2-file-preview-shell payman-v2-file-preview-shell-clickable",
|
|
5992
|
-
hasUploadError && "payman-v2-file-preview-shell-error"
|
|
5993
|
-
),
|
|
5994
|
-
onClick: () => setPreviewFile(af),
|
|
5995
|
-
disabled: isUploadingFile,
|
|
5996
|
-
"aria-label": `Preview ${af.file.name}`,
|
|
5997
|
-
children: [
|
|
5998
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "payman-v2-file-preview-thumb", children: [
|
|
5999
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6000
|
-
"img",
|
|
6001
|
-
{
|
|
6002
|
-
src: af.objectUrl,
|
|
6003
|
-
alt: "",
|
|
6004
|
-
draggable: false
|
|
6005
|
-
}
|
|
6006
|
-
),
|
|
6007
|
-
isUploadingFile && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "payman-v2-file-preview-uploading", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { size: 14, className: "payman-v2-spin" }) })
|
|
6008
|
-
] }),
|
|
6009
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "payman-v2-file-preview-info", children: [
|
|
6010
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "payman-v2-file-preview-name", children: af.file.name }),
|
|
6011
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "payman-v2-file-preview-type", children: uploadStatusLabel(uploadStatus, af.file, af.kind) })
|
|
6012
|
-
] })
|
|
6013
|
-
]
|
|
6014
|
-
}
|
|
6015
|
-
) : isPdfFile(af.file) ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6016
|
-
"button",
|
|
6017
|
-
{
|
|
6018
|
-
type: "button",
|
|
6019
|
-
className: cn(
|
|
6020
|
-
"payman-v2-file-preview-shell payman-v2-file-preview-shell-clickable",
|
|
6021
|
-
hasUploadError && "payman-v2-file-preview-shell-error"
|
|
6022
|
-
),
|
|
6023
|
-
onClick: () => chatContext?.openPdfSheet(
|
|
6024
|
-
af.objectUrl,
|
|
6025
|
-
af.file.name
|
|
6026
|
-
),
|
|
6027
|
-
disabled: isUploadingFile,
|
|
6028
|
-
"aria-label": `Preview ${af.file.name}`,
|
|
6029
|
-
children: [
|
|
6030
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "payman-v2-file-preview-thumb", children: isUploadingFile ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { size: 16, className: "payman-v2-spin payman-v2-file-preview-doc-icon" }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
6031
|
-
lucideReact.FileText,
|
|
6032
|
-
{
|
|
6033
|
-
size: 16,
|
|
6034
|
-
strokeWidth: 1.75,
|
|
6035
|
-
className: "payman-v2-file-preview-doc-icon"
|
|
6036
|
-
}
|
|
6037
|
-
) }),
|
|
6038
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "payman-v2-file-preview-info", children: [
|
|
6039
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "payman-v2-file-preview-name", children: af.file.name }),
|
|
6040
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "payman-v2-file-preview-type", children: uploadStatusLabel(uploadStatus, af.file, af.kind) })
|
|
6041
|
-
] })
|
|
6042
|
-
]
|
|
6043
|
-
}
|
|
6044
|
-
) : /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6045
|
-
"div",
|
|
6046
|
-
{
|
|
6047
|
-
className: cn(
|
|
6048
|
-
"payman-v2-file-preview-shell",
|
|
6049
|
-
hasUploadError && "payman-v2-file-preview-shell-error"
|
|
6050
|
-
),
|
|
6051
|
-
children: [
|
|
6052
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "payman-v2-file-preview-thumb", children: isUploadingFile ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { size: 16, className: "payman-v2-spin payman-v2-file-preview-doc-icon" }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
6053
|
-
lucideReact.FileText,
|
|
6054
|
-
{
|
|
6055
|
-
size: 16,
|
|
6056
|
-
strokeWidth: 1.75,
|
|
6057
|
-
className: "payman-v2-file-preview-doc-icon"
|
|
6058
|
-
}
|
|
6059
|
-
) }),
|
|
6060
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "payman-v2-file-preview-info", children: [
|
|
6061
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "payman-v2-file-preview-name", children: af.file.name }),
|
|
6062
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "payman-v2-file-preview-type", children: uploadStatusLabel(uploadStatus, af.file, af.kind) })
|
|
6063
|
-
] })
|
|
6064
|
-
]
|
|
6065
|
-
}
|
|
6066
|
-
),
|
|
6067
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6068
|
-
"button",
|
|
6069
|
-
{
|
|
6070
|
-
type: "button",
|
|
6071
|
-
className: "payman-v2-file-preview-remove",
|
|
6072
|
-
onClick: () => removeFile(af.id),
|
|
6073
|
-
"aria-label": `Remove ${af.file.name}`,
|
|
6074
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { size: 12, strokeWidth: 2.5 })
|
|
6075
|
-
}
|
|
6076
|
-
)
|
|
6077
|
-
] }, af.id);
|
|
6078
|
-
})
|
|
6079
|
-
},
|
|
6080
|
-
"file-preview"
|
|
6081
|
-
) }),
|
|
6082
5346
|
/* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { initial: false, children: editingMessageId && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6083
5347
|
framerMotion.motion.div,
|
|
6084
5348
|
{
|
|
@@ -6310,13 +5574,13 @@ var ChatInputV2 = react.forwardRef(
|
|
|
6310
5574
|
"button",
|
|
6311
5575
|
{
|
|
6312
5576
|
type: "button",
|
|
6313
|
-
onClick:
|
|
5577
|
+
onClick: handleSend,
|
|
6314
5578
|
disabled: sendDisabled,
|
|
6315
5579
|
className: cn(
|
|
6316
5580
|
"payman-v2-input-send-btn",
|
|
6317
5581
|
sendDisabled && "payman-v2-input-send-btn-disabled"
|
|
6318
5582
|
),
|
|
6319
|
-
"aria-label":
|
|
5583
|
+
"aria-label": "Send message",
|
|
6320
5584
|
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6321
5585
|
lucideReact.ArrowUp,
|
|
6322
5586
|
{
|
|
@@ -6851,389 +6115,6 @@ function TimelineBars({
|
|
|
6851
6115
|
)
|
|
6852
6116
|
] });
|
|
6853
6117
|
}
|
|
6854
|
-
|
|
6855
|
-
// src/utils/pdfPreview.ts
|
|
6856
|
-
var PdfPreviewError = class extends Error {
|
|
6857
|
-
constructor(kind, title, userMessage) {
|
|
6858
|
-
super(userMessage);
|
|
6859
|
-
__publicField(this, "kind");
|
|
6860
|
-
__publicField(this, "title");
|
|
6861
|
-
__publicField(this, "userMessage");
|
|
6862
|
-
this.name = "PdfPreviewError";
|
|
6863
|
-
this.kind = kind;
|
|
6864
|
-
this.title = title;
|
|
6865
|
-
this.userMessage = userMessage;
|
|
6866
|
-
}
|
|
6867
|
-
};
|
|
6868
|
-
function classifyErrorBody(body, status) {
|
|
6869
|
-
const text = body.replace(/\s+/g, " ").trim();
|
|
6870
|
-
if (/signed expiry time|must be after signed start time|expired|expir/i.test(text)) {
|
|
6871
|
-
return new PdfPreviewError(
|
|
6872
|
-
"expired",
|
|
6873
|
-
"Link expired",
|
|
6874
|
-
"This download link has expired. Ask the assistant to generate a new copy of the document."
|
|
6875
|
-
);
|
|
6876
|
-
}
|
|
6877
|
-
if (/AuthenticationFailed|authorization header|formed correctly including the signature/i.test(
|
|
6878
|
-
text
|
|
6879
|
-
)) {
|
|
6880
|
-
return new PdfPreviewError(
|
|
6881
|
-
"forbidden",
|
|
6882
|
-
"Link no longer valid",
|
|
6883
|
-
"This preview link is no longer valid. Request a fresh download link and try again."
|
|
6884
|
-
);
|
|
6885
|
-
}
|
|
6886
|
-
if (status === 404 || /BlobNotFound|ResourceNotFound|The specified blob does not exist/i.test(text)) {
|
|
6887
|
-
return new PdfPreviewError(
|
|
6888
|
-
"not_found",
|
|
6889
|
-
"Document not found",
|
|
6890
|
-
"The file is no longer available. It may have been removed or the link is incorrect."
|
|
6891
|
-
);
|
|
6892
|
-
}
|
|
6893
|
-
if (status === 403) {
|
|
6894
|
-
return new PdfPreviewError(
|
|
6895
|
-
"forbidden",
|
|
6896
|
-
"Can't open document",
|
|
6897
|
-
"You may not have access to this file, or the link has expired."
|
|
6898
|
-
);
|
|
6899
|
-
}
|
|
6900
|
-
if (status === 401) {
|
|
6901
|
-
return new PdfPreviewError(
|
|
6902
|
-
"forbidden",
|
|
6903
|
-
"Access denied",
|
|
6904
|
-
"This preview link could not be verified. Request a new download link."
|
|
6905
|
-
);
|
|
6906
|
-
}
|
|
6907
|
-
return new PdfPreviewError(
|
|
6908
|
-
"unknown",
|
|
6909
|
-
"Can't preview document",
|
|
6910
|
-
"Something went wrong while opening this file. Try downloading it or request a new link."
|
|
6911
|
-
);
|
|
6912
|
-
}
|
|
6913
|
-
function normalizePdfPreviewError(error) {
|
|
6914
|
-
if (error instanceof PdfPreviewError) return error;
|
|
6915
|
-
if (error instanceof TypeError) {
|
|
6916
|
-
return new PdfPreviewError(
|
|
6917
|
-
"network",
|
|
6918
|
-
"Connection problem",
|
|
6919
|
-
"Could not load the document. Check your connection and try again."
|
|
6920
|
-
);
|
|
6921
|
-
}
|
|
6922
|
-
return new PdfPreviewError(
|
|
6923
|
-
"unknown",
|
|
6924
|
-
"Can't preview document",
|
|
6925
|
-
"Something went wrong while opening this file. Try downloading it or request a new link."
|
|
6926
|
-
);
|
|
6927
|
-
}
|
|
6928
|
-
async function assertPdfBlob(blob, status) {
|
|
6929
|
-
if (!blob.size) {
|
|
6930
|
-
return Promise.reject(
|
|
6931
|
-
new PdfPreviewError(
|
|
6932
|
-
"empty",
|
|
6933
|
-
"Document unavailable",
|
|
6934
|
-
"The file response was empty. Request a new download link and try again."
|
|
6935
|
-
)
|
|
6936
|
-
);
|
|
6937
|
-
}
|
|
6938
|
-
const head = await blob.slice(0, Math.min(blob.size, 1024)).text();
|
|
6939
|
-
if (head.startsWith("%PDF")) {
|
|
6940
|
-
return blob;
|
|
6941
|
-
}
|
|
6942
|
-
throw classifyErrorBody(head, status);
|
|
6943
|
-
}
|
|
6944
|
-
async function fetchPdfBlob(src) {
|
|
6945
|
-
let response;
|
|
6946
|
-
try {
|
|
6947
|
-
response = await fetch(src, {
|
|
6948
|
-
method: "GET",
|
|
6949
|
-
headers: { Accept: "application/pdf,*/*" }
|
|
6950
|
-
});
|
|
6951
|
-
} catch {
|
|
6952
|
-
throw new PdfPreviewError(
|
|
6953
|
-
"network",
|
|
6954
|
-
"Connection problem",
|
|
6955
|
-
"Could not load the document. Check your connection and try again."
|
|
6956
|
-
);
|
|
6957
|
-
}
|
|
6958
|
-
const blob = await response.blob();
|
|
6959
|
-
if (!response.ok) {
|
|
6960
|
-
const body = await blob.text().catch(() => "");
|
|
6961
|
-
throw classifyErrorBody(body, response.status);
|
|
6962
|
-
}
|
|
6963
|
-
return assertPdfBlob(blob, response.status);
|
|
6964
|
-
}
|
|
6965
|
-
var MIN_WIDTH = 320;
|
|
6966
|
-
var MAX_WIDTH_RATIO = 0.6;
|
|
6967
|
-
var DEFAULT_WIDTH = 520;
|
|
6968
|
-
var SPRING = { type: "spring", stiffness: 340, damping: 34, mass: 0.85 };
|
|
6969
|
-
var SHEET_EXIT = { duration: 0.22, ease: [0.4, 0, 1, 1] };
|
|
6970
|
-
function pdfDownloadName(title) {
|
|
6971
|
-
const base = title.trim() || "document";
|
|
6972
|
-
return base.toLowerCase().endsWith(".pdf") ? base : `${base}.pdf`;
|
|
6973
|
-
}
|
|
6974
|
-
function clampSplitWidth(w) {
|
|
6975
|
-
const maxW = Math.floor(window.innerWidth * MAX_WIDTH_RATIO);
|
|
6976
|
-
return Math.max(MIN_WIDTH, Math.min(maxW, w));
|
|
6977
|
-
}
|
|
6978
|
-
function PdfSheetV2({
|
|
6979
|
-
src,
|
|
6980
|
-
title,
|
|
6981
|
-
onClose,
|
|
6982
|
-
mode = "split"
|
|
6983
|
-
}) {
|
|
6984
|
-
return /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: src && /* @__PURE__ */ jsxRuntime.jsx(
|
|
6985
|
-
PdfSheetPanel,
|
|
6986
|
-
{
|
|
6987
|
-
src,
|
|
6988
|
-
title,
|
|
6989
|
-
onClose,
|
|
6990
|
-
mode
|
|
6991
|
-
},
|
|
6992
|
-
"pdf-panel"
|
|
6993
|
-
) });
|
|
6994
|
-
}
|
|
6995
|
-
function PdfSheetPanel({
|
|
6996
|
-
src,
|
|
6997
|
-
title,
|
|
6998
|
-
onClose,
|
|
6999
|
-
mode
|
|
7000
|
-
}) {
|
|
7001
|
-
const isSheet = mode === "sheet";
|
|
7002
|
-
const [isLoaded, setIsLoaded] = react.useState(false);
|
|
7003
|
-
const [isDownloading, setIsDownloading] = react.useState(false);
|
|
7004
|
-
const [previewUrl, setPreviewUrl] = react.useState(null);
|
|
7005
|
-
const [previewError, setPreviewError] = react.useState(null);
|
|
7006
|
-
const [loadAttempt, setLoadAttempt] = react.useState(0);
|
|
7007
|
-
const blobRef = react.useRef(null);
|
|
7008
|
-
const objectUrlRef = react.useRef(null);
|
|
7009
|
-
const [panelWidth, setPanelWidth] = react.useState(DEFAULT_WIDTH);
|
|
7010
|
-
const [splitOpened, setSplitOpened] = react.useState(false);
|
|
7011
|
-
const [isDragging, setIsDragging] = react.useState(false);
|
|
7012
|
-
react.useEffect(() => {
|
|
7013
|
-
setIsLoaded(false);
|
|
7014
|
-
setPreviewUrl(null);
|
|
7015
|
-
setPreviewError(null);
|
|
7016
|
-
setPanelWidth(DEFAULT_WIDTH);
|
|
7017
|
-
setSplitOpened(false);
|
|
7018
|
-
blobRef.current = null;
|
|
7019
|
-
if (objectUrlRef.current) {
|
|
7020
|
-
URL.revokeObjectURL(objectUrlRef.current);
|
|
7021
|
-
objectUrlRef.current = null;
|
|
7022
|
-
}
|
|
7023
|
-
let cancelled = false;
|
|
7024
|
-
const loadPreview = async () => {
|
|
7025
|
-
try {
|
|
7026
|
-
const blob = await fetchPdfBlob(src);
|
|
7027
|
-
if (cancelled) return;
|
|
7028
|
-
blobRef.current = blob;
|
|
7029
|
-
const objectUrl = URL.createObjectURL(blob);
|
|
7030
|
-
objectUrlRef.current = objectUrl;
|
|
7031
|
-
setPreviewUrl(objectUrl);
|
|
7032
|
-
} catch (error) {
|
|
7033
|
-
if (!cancelled) {
|
|
7034
|
-
setPreviewError(normalizePdfPreviewError(error));
|
|
7035
|
-
}
|
|
7036
|
-
}
|
|
7037
|
-
};
|
|
7038
|
-
void loadPreview();
|
|
7039
|
-
return () => {
|
|
7040
|
-
cancelled = true;
|
|
7041
|
-
if (objectUrlRef.current) {
|
|
7042
|
-
URL.revokeObjectURL(objectUrlRef.current);
|
|
7043
|
-
objectUrlRef.current = null;
|
|
7044
|
-
}
|
|
7045
|
-
blobRef.current = null;
|
|
7046
|
-
};
|
|
7047
|
-
}, [src, loadAttempt]);
|
|
7048
|
-
react.useEffect(() => {
|
|
7049
|
-
if (isSheet) return;
|
|
7050
|
-
const onWindowResize = () => setPanelWidth((size) => clampSplitWidth(size));
|
|
7051
|
-
window.addEventListener("resize", onWindowResize);
|
|
7052
|
-
return () => window.removeEventListener("resize", onWindowResize);
|
|
7053
|
-
}, [isSheet]);
|
|
7054
|
-
const handleKeyDown = react.useCallback(
|
|
7055
|
-
(e) => {
|
|
7056
|
-
if (e.key === "Escape") onClose();
|
|
7057
|
-
},
|
|
7058
|
-
[onClose]
|
|
7059
|
-
);
|
|
7060
|
-
react.useEffect(() => {
|
|
7061
|
-
document.addEventListener("keydown", handleKeyDown);
|
|
7062
|
-
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
7063
|
-
}, [handleKeyDown]);
|
|
7064
|
-
const canDownload = isLoaded && previewUrl != null && !previewError;
|
|
7065
|
-
const handleDownload = async () => {
|
|
7066
|
-
const filename = pdfDownloadName(title);
|
|
7067
|
-
setIsDownloading(true);
|
|
7068
|
-
try {
|
|
7069
|
-
const blob = blobRef.current ?? await fetchPdfBlob(src);
|
|
7070
|
-
const objectUrl = URL.createObjectURL(blob);
|
|
7071
|
-
const a = document.createElement("a");
|
|
7072
|
-
a.href = objectUrl;
|
|
7073
|
-
a.download = filename;
|
|
7074
|
-
a.target = "_blank";
|
|
7075
|
-
a.rel = "noopener noreferrer";
|
|
7076
|
-
document.body.appendChild(a);
|
|
7077
|
-
a.click();
|
|
7078
|
-
a.remove();
|
|
7079
|
-
URL.revokeObjectURL(objectUrl);
|
|
7080
|
-
} catch (error) {
|
|
7081
|
-
setPreviewError(normalizePdfPreviewError(error));
|
|
7082
|
-
} finally {
|
|
7083
|
-
setIsDownloading(false);
|
|
7084
|
-
}
|
|
7085
|
-
};
|
|
7086
|
-
const handleRetry = () => {
|
|
7087
|
-
setPreviewError(null);
|
|
7088
|
-
setIsLoaded(false);
|
|
7089
|
-
setPreviewUrl(null);
|
|
7090
|
-
setLoadAttempt((attempt) => attempt + 1);
|
|
7091
|
-
};
|
|
7092
|
-
const handleOpenInNewTab = () => {
|
|
7093
|
-
window.open(src, "_blank", "noopener,noreferrer");
|
|
7094
|
-
};
|
|
7095
|
-
const onResizeMouseDown = (e) => {
|
|
7096
|
-
if (e.button !== 0) return;
|
|
7097
|
-
e.preventDefault();
|
|
7098
|
-
const startX = e.clientX;
|
|
7099
|
-
const startW = panelWidth;
|
|
7100
|
-
setIsDragging(true);
|
|
7101
|
-
const onMove = (ev) => {
|
|
7102
|
-
setPanelWidth(clampSplitWidth(startW + (startX - ev.clientX)));
|
|
7103
|
-
};
|
|
7104
|
-
const onUp = () => {
|
|
7105
|
-
setIsDragging(false);
|
|
7106
|
-
document.removeEventListener("mousemove", onMove);
|
|
7107
|
-
document.removeEventListener("mouseup", onUp);
|
|
7108
|
-
};
|
|
7109
|
-
document.addEventListener("mousemove", onMove);
|
|
7110
|
-
document.addEventListener("mouseup", onUp);
|
|
7111
|
-
};
|
|
7112
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7113
|
-
framerMotion.motion.div,
|
|
7114
|
-
{
|
|
7115
|
-
className: cn(
|
|
7116
|
-
"payman-v2-root payman-v2-pdf-sheet-panel",
|
|
7117
|
-
isSheet && "payman-v2-pdf-sheet-panel--sheet"
|
|
7118
|
-
),
|
|
7119
|
-
style: { minWidth: 0 },
|
|
7120
|
-
initial: isSheet ? { x: "100%", opacity: 0 } : { width: 0, opacity: 0 },
|
|
7121
|
-
animate: isSheet ? { x: 0, opacity: 1 } : { width: panelWidth, opacity: 1 },
|
|
7122
|
-
exit: isSheet ? { x: "100%", opacity: 0, transition: { x: SHEET_EXIT, opacity: SHEET_EXIT } } : { width: 0, opacity: 0, transition: { width: SHEET_EXIT, opacity: SHEET_EXIT } },
|
|
7123
|
-
transition: isSheet ? { x: SPRING, opacity: SPRING } : {
|
|
7124
|
-
width: splitOpened ? { duration: 0 } : SPRING,
|
|
7125
|
-
opacity: SPRING
|
|
7126
|
-
},
|
|
7127
|
-
onAnimationComplete: () => {
|
|
7128
|
-
if (!isSheet && !splitOpened) setSplitOpened(true);
|
|
7129
|
-
},
|
|
7130
|
-
children: [
|
|
7131
|
-
!isSheet && /* @__PURE__ */ jsxRuntime.jsx(
|
|
7132
|
-
"div",
|
|
7133
|
-
{
|
|
7134
|
-
className: "payman-v2-pdf-sheet-resize-handle",
|
|
7135
|
-
onMouseDown: onResizeMouseDown,
|
|
7136
|
-
"aria-hidden": "true",
|
|
7137
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "payman-v2-pdf-sheet-resize-grip" })
|
|
7138
|
-
}
|
|
7139
|
-
),
|
|
7140
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "payman-v2-pdf-sheet-header", children: [
|
|
7141
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "payman-v2-pdf-sheet-header-left", children: [
|
|
7142
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "payman-v2-pdf-sheet-file-icon", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileText, { size: 14, strokeWidth: 1.75 }) }),
|
|
7143
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "payman-v2-pdf-sheet-title", title, children: title || "Document" })
|
|
7144
|
-
] }),
|
|
7145
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "payman-v2-pdf-sheet-header-actions", children: [
|
|
7146
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
7147
|
-
"button",
|
|
7148
|
-
{
|
|
7149
|
-
type: "button",
|
|
7150
|
-
className: "payman-v2-pdf-sheet-download-btn",
|
|
7151
|
-
"aria-label": "Download PDF",
|
|
7152
|
-
disabled: !canDownload || isDownloading,
|
|
7153
|
-
onClick: () => void handleDownload(),
|
|
7154
|
-
children: [
|
|
7155
|
-
isDownloading ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { size: 13, strokeWidth: 2, style: { animation: "payman-v2-spin 0.65s linear infinite" } }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Download, { size: 13, strokeWidth: 2 }),
|
|
7156
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { children: isDownloading ? "Downloading\u2026" : "Download" })
|
|
7157
|
-
]
|
|
7158
|
-
}
|
|
7159
|
-
),
|
|
7160
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7161
|
-
"button",
|
|
7162
|
-
{
|
|
7163
|
-
type: "button",
|
|
7164
|
-
className: "payman-v2-pdf-sheet-close-btn",
|
|
7165
|
-
"aria-label": "Close preview",
|
|
7166
|
-
onClick: (e) => {
|
|
7167
|
-
e.stopPropagation();
|
|
7168
|
-
onClose();
|
|
7169
|
-
},
|
|
7170
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { size: 15, strokeWidth: 2.25 })
|
|
7171
|
-
}
|
|
7172
|
-
)
|
|
7173
|
-
] })
|
|
7174
|
-
] }),
|
|
7175
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "payman-v2-pdf-sheet-body", children: previewError ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "payman-v2-pdf-sheet-error", role: "alert", children: [
|
|
7176
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "payman-v2-pdf-sheet-error-icon", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertCircle, { size: 22, strokeWidth: 1.75 }) }),
|
|
7177
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "payman-v2-pdf-sheet-error-title", children: previewError.title }),
|
|
7178
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "payman-v2-pdf-sheet-error-message", children: previewError.userMessage }),
|
|
7179
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "payman-v2-pdf-sheet-error-actions", children: [
|
|
7180
|
-
previewError.kind === "network" && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7181
|
-
"button",
|
|
7182
|
-
{
|
|
7183
|
-
type: "button",
|
|
7184
|
-
className: "payman-v2-pdf-sheet-error-btn",
|
|
7185
|
-
onClick: handleRetry,
|
|
7186
|
-
children: [
|
|
7187
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { size: 14, strokeWidth: 2 }),
|
|
7188
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Try again" })
|
|
7189
|
-
]
|
|
7190
|
-
}
|
|
7191
|
-
),
|
|
7192
|
-
(previewError.kind === "network" || previewError.kind === "unknown") && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7193
|
-
"button",
|
|
7194
|
-
{
|
|
7195
|
-
type: "button",
|
|
7196
|
-
className: "payman-v2-pdf-sheet-error-btn payman-v2-pdf-sheet-error-btn-secondary",
|
|
7197
|
-
onClick: handleOpenInNewTab,
|
|
7198
|
-
children: [
|
|
7199
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ExternalLink, { size: 14, strokeWidth: 2 }),
|
|
7200
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Open link" })
|
|
7201
|
-
]
|
|
7202
|
-
}
|
|
7203
|
-
)
|
|
7204
|
-
] })
|
|
7205
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
7206
|
-
(!isLoaded || !previewUrl) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "payman-v2-pdf-sheet-loading", children: [
|
|
7207
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7208
|
-
lucideReact.Loader2,
|
|
7209
|
-
{
|
|
7210
|
-
size: 20,
|
|
7211
|
-
strokeWidth: 2,
|
|
7212
|
-
style: { animation: "payman-v2-spin 0.65s linear infinite", color: "var(--payman-v2-text-3)" }
|
|
7213
|
-
}
|
|
7214
|
-
),
|
|
7215
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "payman-v2-pdf-sheet-loading-text", children: previewUrl ? "Preparing preview\u2026" : "Opening document\u2026" })
|
|
7216
|
-
] }),
|
|
7217
|
-
previewUrl && /* @__PURE__ */ jsxRuntime.jsx(
|
|
7218
|
-
"iframe",
|
|
7219
|
-
{
|
|
7220
|
-
src: previewUrl,
|
|
7221
|
-
title: title || "PDF Preview",
|
|
7222
|
-
className: "payman-v2-pdf-sheet-iframe",
|
|
7223
|
-
style: {
|
|
7224
|
-
opacity: isLoaded ? 1 : 0,
|
|
7225
|
-
transition: "opacity 0.3s ease",
|
|
7226
|
-
pointerEvents: isDragging ? "none" : "auto"
|
|
7227
|
-
},
|
|
7228
|
-
onLoad: () => setIsLoaded(true)
|
|
7229
|
-
},
|
|
7230
|
-
previewUrl
|
|
7231
|
-
)
|
|
7232
|
-
] }) })
|
|
7233
|
-
]
|
|
7234
|
-
}
|
|
7235
|
-
);
|
|
7236
|
-
}
|
|
7237
6118
|
var DEFAULT_USER_ACTION_STATE = {
|
|
7238
6119
|
prompts: [],
|
|
7239
6120
|
notifications: []
|
|
@@ -7328,8 +6209,7 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
|
|
|
7328
6209
|
onLoadMoreMessages,
|
|
7329
6210
|
isLoadingMoreMessages = false,
|
|
7330
6211
|
hasMoreMessages = false,
|
|
7331
|
-
chat
|
|
7332
|
-
attachmentUpload
|
|
6212
|
+
chat
|
|
7333
6213
|
}, ref) {
|
|
7334
6214
|
const [inputValue, setInputValue] = react.useState("");
|
|
7335
6215
|
const prevInputValueRef = react.useRef(inputValue);
|
|
@@ -7383,6 +6263,7 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
|
|
|
7383
6263
|
const submitUserAction2 = chat.submitUserAction ?? NOOP_ASYNC;
|
|
7384
6264
|
const cancelUserAction2 = chat.cancelUserAction ?? NOOP_ASYNC;
|
|
7385
6265
|
const resendUserAction2 = chat.resendUserAction ?? NOOP_ASYNC;
|
|
6266
|
+
const expireUserAction = chat.expireUserAction ?? NOOP_ASYNC;
|
|
7386
6267
|
const dismissNotification = chat.dismissNotification ?? NOOP;
|
|
7387
6268
|
const isUserActionSupported = typeof chat.submitUserAction === "function" && typeof chat.cancelUserAction === "function" && typeof chat.resendUserAction === "function";
|
|
7388
6269
|
const {
|
|
@@ -7408,19 +6289,6 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
|
|
|
7408
6289
|
}
|
|
7409
6290
|
}
|
|
7410
6291
|
);
|
|
7411
|
-
const [pdfSheet, setPdfSheet] = react.useState(null);
|
|
7412
|
-
const autoOpenedPdfHrefsRef = react.useRef(/* @__PURE__ */ new Set());
|
|
7413
|
-
const pdfPreviewMode = config.pdfPreviewMode ?? "split";
|
|
7414
|
-
const openPdfSheet = react.useCallback((href, title, options) => {
|
|
7415
|
-
if (options?.auto) {
|
|
7416
|
-
if (autoOpenedPdfHrefsRef.current.has(href)) return;
|
|
7417
|
-
autoOpenedPdfHrefsRef.current.add(href);
|
|
7418
|
-
}
|
|
7419
|
-
setPdfSheet({ href, title });
|
|
7420
|
-
}, []);
|
|
7421
|
-
const closePdfSheet = react.useCallback(() => {
|
|
7422
|
-
setPdfSheet(null);
|
|
7423
|
-
}, []);
|
|
7424
6292
|
const contextValue = react.useMemo(
|
|
7425
6293
|
() => ({
|
|
7426
6294
|
resetSession,
|
|
@@ -7429,8 +6297,7 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
|
|
|
7429
6297
|
cancelStream,
|
|
7430
6298
|
getSessionId,
|
|
7431
6299
|
getMessages,
|
|
7432
|
-
isWaitingForResponse
|
|
7433
|
-
openPdfSheet
|
|
6300
|
+
isWaitingForResponse
|
|
7434
6301
|
}),
|
|
7435
6302
|
[
|
|
7436
6303
|
resetSession,
|
|
@@ -7439,8 +6306,7 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
|
|
|
7439
6306
|
cancelStream,
|
|
7440
6307
|
getSessionId,
|
|
7441
6308
|
getMessages,
|
|
7442
|
-
isWaitingForResponse
|
|
7443
|
-
openPdfSheet
|
|
6309
|
+
isWaitingForResponse
|
|
7444
6310
|
]
|
|
7445
6311
|
);
|
|
7446
6312
|
const {
|
|
@@ -7496,10 +6362,7 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
|
|
|
7496
6362
|
setInputValue("");
|
|
7497
6363
|
setLightboxSrc(null);
|
|
7498
6364
|
setLightboxAlt("");
|
|
7499
|
-
setPdfSheet(null);
|
|
7500
|
-
autoOpenedPdfHrefsRef.current.clear();
|
|
7501
6365
|
chatInputV2Ref.current?.setDraft("");
|
|
7502
|
-
chatInputV2Ref.current?.clearAttachments();
|
|
7503
6366
|
clearTranscript();
|
|
7504
6367
|
if (isRecording) {
|
|
7505
6368
|
stopRecording();
|
|
@@ -7550,20 +6413,14 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
|
|
|
7550
6413
|
emptyStateComponent,
|
|
7551
6414
|
showResetSession = false,
|
|
7552
6415
|
enableDeepModeToggle = true,
|
|
6416
|
+
showAttachmentButton = true,
|
|
6417
|
+
showUploadImageButton = true,
|
|
6418
|
+
showAttachFileButton = true,
|
|
7553
6419
|
messageActions: messageActionsConfig,
|
|
7554
6420
|
enableSlashCommands = true,
|
|
7555
6421
|
slashCommands: slashCommandsConfig,
|
|
7556
6422
|
commandPermissions
|
|
7557
6423
|
} = config;
|
|
7558
|
-
const attachmentSettings = react.useMemo(
|
|
7559
|
-
() => resolveChatAttachmentConfig(config),
|
|
7560
|
-
[
|
|
7561
|
-
config.attachments,
|
|
7562
|
-
config.showAttachmentButton,
|
|
7563
|
-
config.showUploadImageButton,
|
|
7564
|
-
config.showAttachFileButton
|
|
7565
|
-
]
|
|
7566
|
-
);
|
|
7567
6424
|
const messageActions = react.useMemo(
|
|
7568
6425
|
() => ({
|
|
7569
6426
|
userMessageActions: {
|
|
@@ -7651,22 +6508,11 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
|
|
|
7651
6508
|
};
|
|
7652
6509
|
const userActionPrompts = isUserActionSupported ? userActionState.prompts : void 0;
|
|
7653
6510
|
const notifications = userActionState.notifications;
|
|
7654
|
-
const
|
|
7655
|
-
(attachments) => {
|
|
7656
|
-
attachmentUpload.syncAttachments(attachments);
|
|
7657
|
-
},
|
|
7658
|
-
[attachmentUpload]
|
|
7659
|
-
);
|
|
7660
|
-
const handleV2Send = (text, files = [], attachments = []) => {
|
|
6511
|
+
const handleV2Send = (text) => {
|
|
7661
6512
|
if (isRecording) stopRecording();
|
|
7662
|
-
if (
|
|
7663
|
-
if (files.length > 0 && attachments.length === 0) return;
|
|
6513
|
+
if (text.trim() && !disableInput && isSessionParamsConfigured) {
|
|
7664
6514
|
setEditingMessageId(null);
|
|
7665
|
-
void sendMessage(text.trim(), {
|
|
7666
|
-
analysisMode: effectiveAnalysisMode,
|
|
7667
|
-
attachments,
|
|
7668
|
-
files
|
|
7669
|
-
});
|
|
6515
|
+
void sendMessage(text.trim(), { analysisMode: effectiveAnalysisMode });
|
|
7670
6516
|
}
|
|
7671
6517
|
};
|
|
7672
6518
|
const handleVoicePress = react.useCallback(async () => {
|
|
@@ -7714,214 +6560,156 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
|
|
|
7714
6560
|
style,
|
|
7715
6561
|
children: [
|
|
7716
6562
|
children,
|
|
7717
|
-
/* @__PURE__ */ jsxRuntime.
|
|
7718
|
-
|
|
6563
|
+
/* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { mode: "wait", children: isEmpty && !hasEverSentMessage ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
6564
|
+
framerMotion.motion.div,
|
|
7719
6565
|
{
|
|
7720
|
-
|
|
7721
|
-
|
|
7722
|
-
|
|
7723
|
-
|
|
7724
|
-
|
|
7725
|
-
|
|
7726
|
-
|
|
7727
|
-
|
|
7728
|
-
initial: { opacity: 1 },
|
|
7729
|
-
exit: { opacity: 0 },
|
|
7730
|
-
transition: { duration: 0.3 },
|
|
7731
|
-
className: "payman-v2-chat-layout",
|
|
7732
|
-
style: { justifyContent: "center", alignItems: "center" },
|
|
7733
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", flex: 1, width: "100%" }, children: [
|
|
7734
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7735
|
-
MessageList,
|
|
7736
|
-
{
|
|
7737
|
-
messages,
|
|
7738
|
-
isLoading: false,
|
|
7739
|
-
emptyStateText,
|
|
7740
|
-
showEmptyStateIcon,
|
|
7741
|
-
emptyStateComponent,
|
|
7742
|
-
layout,
|
|
7743
|
-
showTimestamps,
|
|
7744
|
-
stage: config.stage || "DEVELOPMENT",
|
|
7745
|
-
animated,
|
|
7746
|
-
showAgentName,
|
|
7747
|
-
agentName,
|
|
7748
|
-
showAvatars,
|
|
7749
|
-
showUserAvatar,
|
|
7750
|
-
showAssistantAvatar,
|
|
7751
|
-
showExecutionSteps,
|
|
7752
|
-
showStreamingDot,
|
|
7753
|
-
streamingStepsText,
|
|
7754
|
-
completedStepsText,
|
|
7755
|
-
onExecutionTraceClick,
|
|
7756
|
-
onLoadMoreMessages,
|
|
7757
|
-
isLoadingMoreMessages,
|
|
7758
|
-
hasMoreMessages
|
|
7759
|
-
}
|
|
7760
|
-
),
|
|
7761
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7762
|
-
framerMotion.motion.div,
|
|
7763
|
-
{
|
|
7764
|
-
initial: { opacity: 0, y: 12 },
|
|
7765
|
-
animate: { opacity: 1, y: 0 },
|
|
7766
|
-
transition: { delay: 0.2, duration: 0.4, ease: [0.25, 0.46, 0.45, 0.94] },
|
|
7767
|
-
style: { width: "100%" },
|
|
7768
|
-
children: hasAskPermission && /* @__PURE__ */ jsxRuntime.jsx(
|
|
7769
|
-
ChatInputV2,
|
|
7770
|
-
{
|
|
7771
|
-
ref: chatInputV2Ref,
|
|
7772
|
-
onSend: handleV2Send,
|
|
7773
|
-
onCancel: cancelStream,
|
|
7774
|
-
disabled: isV2InputDisabled,
|
|
7775
|
-
isStreaming: isWaitingForResponse,
|
|
7776
|
-
isUploadingAttachments: attachmentUpload.isUploading,
|
|
7777
|
-
attachmentsReady: attachmentUpload.allReady,
|
|
7778
|
-
hasAttachmentUploadErrors: attachmentUpload.hasErrors,
|
|
7779
|
-
attachmentUploadStatusById: attachmentUpload.statusById,
|
|
7780
|
-
uploadedAttachmentPayloads: attachmentUpload.payloads,
|
|
7781
|
-
onAttachmentsChange: handleAttachmentsChange,
|
|
7782
|
-
placeholder: isRecording ? "Listening..." : placeholder,
|
|
7783
|
-
enableVoice: config.enableVoice === true,
|
|
7784
|
-
transcribedText: config.enableVoice === true ? transcribedText : "",
|
|
7785
|
-
voiceAvailable: config.enableVoice === true && voiceAvailable,
|
|
7786
|
-
isRecording,
|
|
7787
|
-
onVoicePress: config.enableVoice === true ? handleVoicePress : void 0,
|
|
7788
|
-
onCancelRecording: handleCancelRecording,
|
|
7789
|
-
onConfirmRecording: handleConfirmRecording,
|
|
7790
|
-
showResetSession,
|
|
7791
|
-
onResetSession: requestResetSession,
|
|
7792
|
-
showAttachmentButton: attachmentSettings.showAttachmentButton,
|
|
7793
|
-
showUploadImageButton: attachmentSettings.showUploadImageButton,
|
|
7794
|
-
showAttachFileButton: attachmentSettings.showAttachFileButton,
|
|
7795
|
-
allowedImageExtensions: attachmentSettings.allowedImageExtensions,
|
|
7796
|
-
allowedFileExtensions: attachmentSettings.allowedFileExtensions,
|
|
7797
|
-
maxCount: attachmentSettings.maxCount,
|
|
7798
|
-
maxFileBytes: attachmentSettings.maxFileBytes,
|
|
7799
|
-
maxTotalBytes: attachmentSettings.maxTotalBytes,
|
|
7800
|
-
onUploadImageClick,
|
|
7801
|
-
onAttachFileClick,
|
|
7802
|
-
editingMessageId,
|
|
7803
|
-
onClearEditing: handleClearEditing,
|
|
7804
|
-
analysisMode: enableDeepModeToggle ? analysisMode : void 0,
|
|
7805
|
-
onAnalysisModeChange: enableDeepModeToggle ? setAnalysisMode : void 0,
|
|
7806
|
-
slashCommands
|
|
7807
|
-
}
|
|
7808
|
-
)
|
|
7809
|
-
}
|
|
7810
|
-
)
|
|
7811
|
-
] })
|
|
7812
|
-
},
|
|
7813
|
-
"v2-empty"
|
|
7814
|
-
) : /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7815
|
-
framerMotion.motion.div,
|
|
7816
|
-
{
|
|
7817
|
-
initial: hasEverSentMessage ? { opacity: 0 } : false,
|
|
7818
|
-
animate: { opacity: 1 },
|
|
7819
|
-
transition: { duration: 0.3 },
|
|
7820
|
-
className: "payman-v2-chat-layout",
|
|
7821
|
-
children: [
|
|
7822
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7823
|
-
MessageListV2,
|
|
7824
|
-
{
|
|
7825
|
-
ref: messageListV2Ref,
|
|
7826
|
-
messages,
|
|
7827
|
-
isStreaming: isWaitingForResponse,
|
|
7828
|
-
sidePanelOpen: !!pdfSheet,
|
|
7829
|
-
onEditUserMessage: handleEditMessageDraft,
|
|
7830
|
-
onRetryUserMessage: handleRetryUserMessage,
|
|
7831
|
-
onImageClick: handleImageClick,
|
|
7832
|
-
onExecutionTraceClick,
|
|
7833
|
-
messageActions,
|
|
7834
|
-
retryDisabled: isWaitingForResponse,
|
|
7835
|
-
typingSpeed: config.typingSpeed ?? 4,
|
|
7836
|
-
userActionPrompts,
|
|
7837
|
-
notifications,
|
|
7838
|
-
onSubmitUserAction: isUserActionSupported ? submitUserAction2 : void 0,
|
|
7839
|
-
onCancelUserAction: isUserActionSupported ? cancelUserAction2 : void 0,
|
|
7840
|
-
onResendUserAction: isUserActionSupported ? resendUserAction2 : void 0,
|
|
7841
|
-
onDismissNotification: dismissNotification,
|
|
7842
|
-
onSubmitFeedback: handleSubmitFeedback
|
|
7843
|
-
}
|
|
7844
|
-
),
|
|
7845
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7846
|
-
StreamingIndicatorV2,
|
|
7847
|
-
{
|
|
7848
|
-
isStreaming: isWaitingForResponse,
|
|
7849
|
-
loadingAnimation: config.loadingAnimation
|
|
7850
|
-
}
|
|
7851
|
-
),
|
|
7852
|
-
hasAskPermission && /* @__PURE__ */ jsxRuntime.jsx(
|
|
7853
|
-
ChatInputV2,
|
|
7854
|
-
{
|
|
7855
|
-
ref: chatInputV2Ref,
|
|
7856
|
-
onSend: handleV2Send,
|
|
7857
|
-
onCancel: cancelStream,
|
|
7858
|
-
disabled: isV2InputDisabled,
|
|
7859
|
-
isStreaming: isWaitingForResponse,
|
|
7860
|
-
isUploadingAttachments: attachmentUpload.isUploading,
|
|
7861
|
-
attachmentsReady: attachmentUpload.allReady,
|
|
7862
|
-
hasAttachmentUploadErrors: attachmentUpload.hasErrors,
|
|
7863
|
-
attachmentUploadStatusById: attachmentUpload.statusById,
|
|
7864
|
-
uploadedAttachmentPayloads: attachmentUpload.payloads,
|
|
7865
|
-
onAttachmentsChange: handleAttachmentsChange,
|
|
7866
|
-
placeholder: isRecording ? "Listening..." : placeholder,
|
|
7867
|
-
enableVoice: config.enableVoice === true,
|
|
7868
|
-
transcribedText: config.enableVoice === true ? transcribedText : "",
|
|
7869
|
-
voiceAvailable: config.enableVoice === true && voiceAvailable,
|
|
7870
|
-
isRecording,
|
|
7871
|
-
onVoicePress: config.enableVoice === true ? handleVoicePress : void 0,
|
|
7872
|
-
onCancelRecording: handleCancelRecording,
|
|
7873
|
-
onConfirmRecording: handleConfirmRecording,
|
|
7874
|
-
showResetSession,
|
|
7875
|
-
onResetSession: requestResetSession,
|
|
7876
|
-
showAttachmentButton: attachmentSettings.showAttachmentButton,
|
|
7877
|
-
showUploadImageButton: attachmentSettings.showUploadImageButton,
|
|
7878
|
-
showAttachFileButton: attachmentSettings.showAttachFileButton,
|
|
7879
|
-
allowedImageExtensions: attachmentSettings.allowedImageExtensions,
|
|
7880
|
-
allowedFileExtensions: attachmentSettings.allowedFileExtensions,
|
|
7881
|
-
maxCount: attachmentSettings.maxCount,
|
|
7882
|
-
maxFileBytes: attachmentSettings.maxFileBytes,
|
|
7883
|
-
maxTotalBytes: attachmentSettings.maxTotalBytes,
|
|
7884
|
-
onUploadImageClick,
|
|
7885
|
-
onAttachFileClick,
|
|
7886
|
-
editingMessageId,
|
|
7887
|
-
onClearEditing: handleClearEditing,
|
|
7888
|
-
analysisMode: enableDeepModeToggle ? analysisMode : void 0,
|
|
7889
|
-
onAnalysisModeChange: enableDeepModeToggle ? setAnalysisMode : void 0,
|
|
7890
|
-
slashCommands
|
|
7891
|
-
}
|
|
7892
|
-
)
|
|
7893
|
-
]
|
|
7894
|
-
},
|
|
7895
|
-
"v2-chat"
|
|
7896
|
-
) }) }),
|
|
7897
|
-
pdfPreviewMode === "split" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
7898
|
-
PdfSheetV2,
|
|
6566
|
+
initial: { opacity: 1 },
|
|
6567
|
+
exit: { opacity: 0 },
|
|
6568
|
+
transition: { duration: 0.3 },
|
|
6569
|
+
className: "payman-v2-chat-layout",
|
|
6570
|
+
style: { justifyContent: "center", alignItems: "center" },
|
|
6571
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", flex: 1, width: "100%" }, children: [
|
|
6572
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6573
|
+
MessageList,
|
|
7899
6574
|
{
|
|
7900
|
-
|
|
7901
|
-
|
|
7902
|
-
|
|
7903
|
-
|
|
6575
|
+
messages,
|
|
6576
|
+
isLoading: false,
|
|
6577
|
+
emptyStateText,
|
|
6578
|
+
showEmptyStateIcon,
|
|
6579
|
+
emptyStateComponent,
|
|
6580
|
+
layout,
|
|
6581
|
+
showTimestamps,
|
|
6582
|
+
stage: config.stage || "DEVELOPMENT",
|
|
6583
|
+
animated,
|
|
6584
|
+
showAgentName,
|
|
6585
|
+
agentName,
|
|
6586
|
+
showAvatars,
|
|
6587
|
+
showUserAvatar,
|
|
6588
|
+
showAssistantAvatar,
|
|
6589
|
+
showExecutionSteps,
|
|
6590
|
+
showStreamingDot,
|
|
6591
|
+
streamingStepsText,
|
|
6592
|
+
completedStepsText,
|
|
6593
|
+
onExecutionTraceClick,
|
|
6594
|
+
onLoadMoreMessages,
|
|
6595
|
+
isLoadingMoreMessages,
|
|
6596
|
+
hasMoreMessages
|
|
7904
6597
|
}
|
|
7905
6598
|
),
|
|
7906
|
-
|
|
7907
|
-
|
|
6599
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6600
|
+
framerMotion.motion.div,
|
|
7908
6601
|
{
|
|
7909
|
-
|
|
7910
|
-
|
|
7911
|
-
|
|
7912
|
-
|
|
6602
|
+
initial: { opacity: 0, y: 12 },
|
|
6603
|
+
animate: { opacity: 1, y: 0 },
|
|
6604
|
+
transition: { delay: 0.2, duration: 0.4, ease: [0.25, 0.46, 0.45, 0.94] },
|
|
6605
|
+
style: { width: "100%" },
|
|
6606
|
+
children: hasAskPermission && /* @__PURE__ */ jsxRuntime.jsx(
|
|
6607
|
+
ChatInputV2,
|
|
7913
6608
|
{
|
|
7914
|
-
|
|
7915
|
-
|
|
7916
|
-
|
|
7917
|
-
|
|
6609
|
+
ref: chatInputV2Ref,
|
|
6610
|
+
onSend: handleV2Send,
|
|
6611
|
+
onCancel: cancelStream,
|
|
6612
|
+
disabled: isV2InputDisabled,
|
|
6613
|
+
isStreaming: isWaitingForResponse,
|
|
6614
|
+
placeholder: isRecording ? "Listening..." : placeholder,
|
|
6615
|
+
enableVoice: config.enableVoice === true,
|
|
6616
|
+
transcribedText: config.enableVoice === true ? transcribedText : "",
|
|
6617
|
+
voiceAvailable: config.enableVoice === true && voiceAvailable,
|
|
6618
|
+
isRecording,
|
|
6619
|
+
onVoicePress: config.enableVoice === true ? handleVoicePress : void 0,
|
|
6620
|
+
onCancelRecording: handleCancelRecording,
|
|
6621
|
+
onConfirmRecording: handleConfirmRecording,
|
|
6622
|
+
showResetSession,
|
|
6623
|
+
onResetSession: requestResetSession,
|
|
6624
|
+
showAttachmentButton,
|
|
6625
|
+
showUploadImageButton,
|
|
6626
|
+
showAttachFileButton,
|
|
6627
|
+
onUploadImageClick,
|
|
6628
|
+
onAttachFileClick,
|
|
6629
|
+
editingMessageId,
|
|
6630
|
+
onClearEditing: handleClearEditing,
|
|
6631
|
+
analysisMode: enableDeepModeToggle ? analysisMode : void 0,
|
|
6632
|
+
onAnalysisModeChange: enableDeepModeToggle ? setAnalysisMode : void 0,
|
|
6633
|
+
slashCommands
|
|
7918
6634
|
}
|
|
7919
6635
|
)
|
|
7920
6636
|
}
|
|
7921
6637
|
)
|
|
6638
|
+
] })
|
|
6639
|
+
},
|
|
6640
|
+
"v2-empty"
|
|
6641
|
+
) : /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6642
|
+
framerMotion.motion.div,
|
|
6643
|
+
{
|
|
6644
|
+
initial: hasEverSentMessage ? { opacity: 0 } : false,
|
|
6645
|
+
animate: { opacity: 1 },
|
|
6646
|
+
transition: { duration: 0.3 },
|
|
6647
|
+
className: "payman-v2-chat-layout",
|
|
6648
|
+
children: [
|
|
6649
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6650
|
+
MessageListV2,
|
|
6651
|
+
{
|
|
6652
|
+
ref: messageListV2Ref,
|
|
6653
|
+
messages,
|
|
6654
|
+
isStreaming: isWaitingForResponse,
|
|
6655
|
+
onEditUserMessage: handleEditMessageDraft,
|
|
6656
|
+
onRetryUserMessage: handleRetryUserMessage,
|
|
6657
|
+
onImageClick: handleImageClick,
|
|
6658
|
+
onExecutionTraceClick,
|
|
6659
|
+
messageActions,
|
|
6660
|
+
retryDisabled: isWaitingForResponse,
|
|
6661
|
+
typingSpeed: config.typingSpeed ?? 4,
|
|
6662
|
+
userActionPrompts,
|
|
6663
|
+
notifications,
|
|
6664
|
+
onSubmitUserAction: isUserActionSupported ? submitUserAction2 : void 0,
|
|
6665
|
+
onCancelUserAction: isUserActionSupported ? cancelUserAction2 : void 0,
|
|
6666
|
+
onResendUserAction: isUserActionSupported ? resendUserAction2 : void 0,
|
|
6667
|
+
onExpireUserAction: isUserActionSupported ? expireUserAction : void 0,
|
|
6668
|
+
onDismissNotification: dismissNotification,
|
|
6669
|
+
onSubmitFeedback: handleSubmitFeedback
|
|
6670
|
+
}
|
|
6671
|
+
),
|
|
6672
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6673
|
+
StreamingIndicatorV2,
|
|
6674
|
+
{
|
|
6675
|
+
isStreaming: isWaitingForResponse,
|
|
6676
|
+
loadingAnimation: config.loadingAnimation
|
|
6677
|
+
}
|
|
6678
|
+
),
|
|
6679
|
+
hasAskPermission && /* @__PURE__ */ jsxRuntime.jsx(
|
|
6680
|
+
ChatInputV2,
|
|
6681
|
+
{
|
|
6682
|
+
ref: chatInputV2Ref,
|
|
6683
|
+
onSend: handleV2Send,
|
|
6684
|
+
onCancel: cancelStream,
|
|
6685
|
+
disabled: isV2InputDisabled,
|
|
6686
|
+
isStreaming: isWaitingForResponse,
|
|
6687
|
+
placeholder: isRecording ? "Listening..." : placeholder,
|
|
6688
|
+
enableVoice: config.enableVoice === true,
|
|
6689
|
+
transcribedText: config.enableVoice === true ? transcribedText : "",
|
|
6690
|
+
voiceAvailable: config.enableVoice === true && voiceAvailable,
|
|
6691
|
+
isRecording,
|
|
6692
|
+
onVoicePress: config.enableVoice === true ? handleVoicePress : void 0,
|
|
6693
|
+
onCancelRecording: handleCancelRecording,
|
|
6694
|
+
onConfirmRecording: handleConfirmRecording,
|
|
6695
|
+
showResetSession,
|
|
6696
|
+
onResetSession: requestResetSession,
|
|
6697
|
+
showAttachmentButton,
|
|
6698
|
+
showUploadImageButton,
|
|
6699
|
+
showAttachFileButton,
|
|
6700
|
+
onUploadImageClick,
|
|
6701
|
+
onAttachFileClick,
|
|
6702
|
+
editingMessageId,
|
|
6703
|
+
onClearEditing: handleClearEditing,
|
|
6704
|
+
analysisMode: enableDeepModeToggle ? analysisMode : void 0,
|
|
6705
|
+
onAnalysisModeChange: enableDeepModeToggle ? setAnalysisMode : void 0,
|
|
6706
|
+
slashCommands
|
|
6707
|
+
}
|
|
6708
|
+
)
|
|
7922
6709
|
]
|
|
7923
|
-
}
|
|
7924
|
-
|
|
6710
|
+
},
|
|
6711
|
+
"v2-chat"
|
|
6712
|
+
) }),
|
|
7925
6713
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7926
6714
|
ImageLightboxV2,
|
|
7927
6715
|
{
|
|
@@ -7956,39 +6744,19 @@ var PaymanChat = react.forwardRef(
|
|
|
7956
6744
|
function PaymanChat2(props, ref) {
|
|
7957
6745
|
const mergedCallbacks = useSentryChatCallbacks(props.callbacks, props.config);
|
|
7958
6746
|
const chat = useChatV2(props.config, mergedCallbacks);
|
|
7959
|
-
|
|
7960
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
7961
|
-
PaymanChatInner,
|
|
7962
|
-
{
|
|
7963
|
-
...props,
|
|
7964
|
-
chat,
|
|
7965
|
-
attachmentUpload,
|
|
7966
|
-
ref
|
|
7967
|
-
}
|
|
7968
|
-
);
|
|
6747
|
+
return /* @__PURE__ */ jsxRuntime.jsx(PaymanChatInner, { ...props, chat, ref });
|
|
7969
6748
|
}
|
|
7970
6749
|
);
|
|
7971
6750
|
|
|
7972
6751
|
exports.PaymanChat = PaymanChat;
|
|
7973
6752
|
exports.PaymanChatContext = PaymanChatContext;
|
|
7974
|
-
exports.PdfSheetV2 = PdfSheetV2;
|
|
7975
6753
|
exports.UserActionStaleError = UserActionStaleError;
|
|
7976
|
-
exports.buildSignedUrlEndpoint = buildSignedUrlEndpoint;
|
|
7977
6754
|
exports.cancelUserAction = cancelUserAction;
|
|
7978
6755
|
exports.captureSentryError = captureSentryError;
|
|
7979
6756
|
exports.cn = cn;
|
|
7980
|
-
exports.formatAttachmentBytes = formatAttachmentBytes;
|
|
7981
6757
|
exports.formatDate = formatDate;
|
|
7982
|
-
exports.getPdfTitleFromUrl = getPdfTitleFromUrl;
|
|
7983
|
-
exports.isPdfUrl = isPdfUrl;
|
|
7984
|
-
exports.mapExecutionHistoryPageToChatMessages = mapExecutionHistoryPageToChatMessages;
|
|
7985
|
-
exports.mapExecutionHistoryToChatMessages = mapExecutionHistoryToChatMessages;
|
|
7986
6758
|
exports.resendUserAction = resendUserAction;
|
|
7987
|
-
exports.stripAttachmentsSuffixFromIntent = stripAttachmentsSuffixFromIntent;
|
|
7988
6759
|
exports.submitUserAction = submitUserAction;
|
|
7989
|
-
exports.uploadAttachment = uploadAttachment;
|
|
7990
|
-
exports.uploadAttachments = uploadAttachments;
|
|
7991
|
-
exports.useAttachmentUpload = useAttachmentUpload;
|
|
7992
6760
|
exports.useChatV2 = useChatV2;
|
|
7993
6761
|
exports.usePaymanChat = usePaymanChat;
|
|
7994
6762
|
exports.useVoice = useVoice;
|