@paymanai/payman-ask-sdk 4.0.19 → 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 +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +149 -27
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +150 -27
- package/dist/index.mjs.map +1 -1
- package/dist/index.native.js +265 -120
- package/dist/index.native.js.map +1 -1
- package/dist/styles.css +3 -2
- package/dist/styles.css.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -709,7 +709,8 @@ function buildRequestBody(config, userMessage, sessionId, options) {
|
|
|
709
709
|
sessionAttributes,
|
|
710
710
|
analysisMode: options?.analysisMode,
|
|
711
711
|
locale: resolveLocale(config.locale),
|
|
712
|
-
timezone: resolveTimezone(config.timezone)
|
|
712
|
+
timezone: resolveTimezone(config.timezone),
|
|
713
|
+
...options?.attachments?.length ? { attachments: options.attachments } : {}
|
|
713
714
|
};
|
|
714
715
|
}
|
|
715
716
|
function resolveLocale(configured) {
|
|
@@ -754,6 +755,7 @@ function buildResolveImagesUrl(config) {
|
|
|
754
755
|
const basePath = normalizedEndpointPath.endsWith("/stream") ? normalizedEndpointPath.slice(0, -"/stream".length) : normalizedEndpointPath;
|
|
755
756
|
return `${config.api.baseUrl}${basePath}/resolve-image-urls`;
|
|
756
757
|
}
|
|
758
|
+
var NGROK_SKIP_BROWSER_WARNING = "ngrok-skip-browser-warning";
|
|
757
759
|
function buildRequestHeaders(config) {
|
|
758
760
|
const headers = {
|
|
759
761
|
...config.api.headers
|
|
@@ -761,6 +763,9 @@ function buildRequestHeaders(config) {
|
|
|
761
763
|
if (config.api.authToken) {
|
|
762
764
|
headers.Authorization = `Bearer ${config.api.authToken}`;
|
|
763
765
|
}
|
|
766
|
+
if (!headers[NGROK_SKIP_BROWSER_WARNING]) {
|
|
767
|
+
headers[NGROK_SKIP_BROWSER_WARNING] = "true";
|
|
768
|
+
}
|
|
764
769
|
return headers;
|
|
765
770
|
}
|
|
766
771
|
var RAG_IMAGE_REGEX = /\/api\/rag\/chunks\/[^"'\s]+\/image/;
|
|
@@ -1041,6 +1046,81 @@ function createCancelledMessageUpdate(steps, currentMessage) {
|
|
|
1041
1046
|
currentMessage: currentMessage || "Thinking..."
|
|
1042
1047
|
};
|
|
1043
1048
|
}
|
|
1049
|
+
var DEFAULT_SIGNED_URL_ENDPOINT = "/api/files/signed-url";
|
|
1050
|
+
function fileExtension(filename) {
|
|
1051
|
+
const ext = filename.split(".").pop()?.toLowerCase().replace(/^\./, "");
|
|
1052
|
+
return ext && ext.length > 0 ? ext : "bin";
|
|
1053
|
+
}
|
|
1054
|
+
function resolveMimeType(file) {
|
|
1055
|
+
if (file.type && file.type.trim().length > 0) return file.type;
|
|
1056
|
+
const ext = fileExtension(file.name);
|
|
1057
|
+
const byExt = {
|
|
1058
|
+
pdf: "application/pdf",
|
|
1059
|
+
png: "image/png",
|
|
1060
|
+
jpg: "image/jpeg",
|
|
1061
|
+
jpeg: "image/jpeg",
|
|
1062
|
+
gif: "image/gif",
|
|
1063
|
+
webp: "image/webp"
|
|
1064
|
+
};
|
|
1065
|
+
return byExt[ext] ?? "application/octet-stream";
|
|
1066
|
+
}
|
|
1067
|
+
function buildSignedUrlEndpoint(config, ext) {
|
|
1068
|
+
const endpoint = config.api.signedUrlEndpoint || DEFAULT_SIGNED_URL_ENDPOINT;
|
|
1069
|
+
const queryParams = new URLSearchParams({ extn: ext.replace(/^\./, "") });
|
|
1070
|
+
return `${config.api.baseUrl}${endpoint}?${queryParams.toString()}`;
|
|
1071
|
+
}
|
|
1072
|
+
async function requestSignedUrl(config, ext, signal) {
|
|
1073
|
+
const url = buildSignedUrlEndpoint(config, ext);
|
|
1074
|
+
const headers = buildRequestHeaders(config);
|
|
1075
|
+
const response = await fetch(url, {
|
|
1076
|
+
method: "GET",
|
|
1077
|
+
headers,
|
|
1078
|
+
signal
|
|
1079
|
+
});
|
|
1080
|
+
if (!response.ok) {
|
|
1081
|
+
const errorText = await response.text().catch(() => "");
|
|
1082
|
+
throw new Error(
|
|
1083
|
+
errorText ? `Failed to get upload URL (${response.status}): ${errorText}` : `Failed to get upload URL (${response.status})`
|
|
1084
|
+
);
|
|
1085
|
+
}
|
|
1086
|
+
const data = await response.json();
|
|
1087
|
+
if (!data.key || !data.url) {
|
|
1088
|
+
throw new Error("Signed URL response missing key or url");
|
|
1089
|
+
}
|
|
1090
|
+
return { key: data.key, url: data.url };
|
|
1091
|
+
}
|
|
1092
|
+
async function uploadToSignedUrl(signedUrl, file, mimeType, signal) {
|
|
1093
|
+
const response = await fetch(signedUrl, {
|
|
1094
|
+
method: "PUT",
|
|
1095
|
+
headers: {
|
|
1096
|
+
"Content-Type": mimeType,
|
|
1097
|
+
"x-ms-blob-type": "BlockBlob"
|
|
1098
|
+
},
|
|
1099
|
+
body: file,
|
|
1100
|
+
signal
|
|
1101
|
+
});
|
|
1102
|
+
if (!response.ok) {
|
|
1103
|
+
const errorText = await response.text().catch(() => "");
|
|
1104
|
+
throw new Error(
|
|
1105
|
+
errorText ? `Failed to upload file (${response.status}): ${errorText}` : `Failed to upload file (${response.status})`
|
|
1106
|
+
);
|
|
1107
|
+
}
|
|
1108
|
+
}
|
|
1109
|
+
async function uploadAttachment(config, file, signal) {
|
|
1110
|
+
const ext = fileExtension(file.name);
|
|
1111
|
+
const mimeType = resolveMimeType(file);
|
|
1112
|
+
const { key, url } = await requestSignedUrl(config, ext, signal);
|
|
1113
|
+
await uploadToSignedUrl(url, file, mimeType, signal);
|
|
1114
|
+
return {
|
|
1115
|
+
tempKey: key,
|
|
1116
|
+
filename: file.name,
|
|
1117
|
+
mimeType
|
|
1118
|
+
};
|
|
1119
|
+
}
|
|
1120
|
+
async function uploadAttachments(config, files, signal) {
|
|
1121
|
+
const uploads = files.map((file) => uploadAttachment(config, file, signal));
|
|
1122
|
+
return Promise.all(uploads);
|
|
1123
|
+
}
|
|
1044
1124
|
var UserActionStaleError = class extends Error {
|
|
1045
1125
|
constructor(userActionId, message = "User action is no longer actionable") {
|
|
1046
1126
|
super(message);
|
|
@@ -1077,9 +1157,6 @@ async function cancelUserAction(config, userActionId) {
|
|
|
1077
1157
|
async function resendUserAction(config, userActionId) {
|
|
1078
1158
|
return sendUserActionRequest(config, userActionId, "resend");
|
|
1079
1159
|
}
|
|
1080
|
-
async function expireUserAction(config, userActionId) {
|
|
1081
|
-
return sendUserActionRequest(config, userActionId, "expired");
|
|
1082
|
-
}
|
|
1083
1160
|
var EMPTY_USER_ACTION_STATE = { prompts: [], notifications: [] };
|
|
1084
1161
|
function upsertPrompt(prompts, req) {
|
|
1085
1162
|
const active = { ...req, status: "pending" };
|
|
@@ -1108,12 +1185,32 @@ function getStoredOrInitialMessages(config) {
|
|
|
1108
1185
|
function getSessionIdFromMessages(messages) {
|
|
1109
1186
|
return messages.find((message) => message.sessionId)?.sessionId;
|
|
1110
1187
|
}
|
|
1188
|
+
var IMAGE_EXTENSIONS = /* @__PURE__ */ new Set(["jpg", "jpeg", "png", "gif", "webp", "avif"]);
|
|
1189
|
+
function attachmentKindFromFile(file) {
|
|
1190
|
+
const ext = file.name.split(".").pop()?.toLowerCase() ?? "";
|
|
1191
|
+
if (IMAGE_EXTENSIONS.has(ext) || file.type.startsWith("image/")) return "image";
|
|
1192
|
+
return "file";
|
|
1193
|
+
}
|
|
1194
|
+
function buildMessageAttachments(files) {
|
|
1195
|
+
return files.map((file, index) => {
|
|
1196
|
+
const kind = attachmentKindFromFile(file);
|
|
1197
|
+
return {
|
|
1198
|
+
id: `att-${Date.now()}-${index}`,
|
|
1199
|
+
filename: file.name,
|
|
1200
|
+
mimeType: file.type || "application/octet-stream",
|
|
1201
|
+
// Blob URL for all local files so PDFs/docs stay previewable after send.
|
|
1202
|
+
previewUrl: URL.createObjectURL(file),
|
|
1203
|
+
kind
|
|
1204
|
+
};
|
|
1205
|
+
});
|
|
1206
|
+
}
|
|
1111
1207
|
function useChatV2(config, callbacks = {}) {
|
|
1112
1208
|
const [messages, setMessages] = useState(() => getStoredOrInitialMessages(config));
|
|
1113
1209
|
const [isWaitingForResponse, setIsWaitingForResponse] = useState(() => {
|
|
1114
1210
|
if (!config.userId) return false;
|
|
1115
1211
|
return activeStreamStore.get(config.userId)?.isWaiting ?? false;
|
|
1116
1212
|
});
|
|
1213
|
+
const [isUploadingAttachments, setIsUploadingAttachments] = useState(false);
|
|
1117
1214
|
const sessionIdRef = useRef(
|
|
1118
1215
|
getSessionIdFromMessages(getStoredOrInitialMessages(config)) ?? config.initialSessionId ?? void 0
|
|
1119
1216
|
);
|
|
@@ -1188,21 +1285,45 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1188
1285
|
);
|
|
1189
1286
|
const sendMessage = useCallback(
|
|
1190
1287
|
async (userMessage, options) => {
|
|
1191
|
-
|
|
1288
|
+
const trimmedMessage = userMessage.trim();
|
|
1289
|
+
const files = options?.files ?? [];
|
|
1290
|
+
const hasPreuploadedAttachments = (options?.attachments?.length ?? 0) > 0;
|
|
1291
|
+
if (!trimmedMessage && files.length === 0 && !hasPreuploadedAttachments) return;
|
|
1292
|
+
let streamAttachments = options?.attachments;
|
|
1293
|
+
if (!streamAttachments && files.length > 0) {
|
|
1294
|
+
setIsUploadingAttachments(true);
|
|
1295
|
+
try {
|
|
1296
|
+
streamAttachments = await uploadAttachments(configRef.current, files);
|
|
1297
|
+
} catch (error) {
|
|
1298
|
+
if (error.name !== "AbortError") {
|
|
1299
|
+
callbacksRef.current.onError?.(error);
|
|
1300
|
+
}
|
|
1301
|
+
throw error;
|
|
1302
|
+
} finally {
|
|
1303
|
+
setIsUploadingAttachments(false);
|
|
1304
|
+
}
|
|
1305
|
+
}
|
|
1192
1306
|
if (!sessionIdRef.current && configRef.current.autoGenerateSessionId !== false) {
|
|
1193
1307
|
sessionIdRef.current = generateId();
|
|
1194
1308
|
callbacksRef.current.onSessionIdChange?.(sessionIdRef.current);
|
|
1195
1309
|
}
|
|
1310
|
+
const messageAttachments = files.length > 0 ? buildMessageAttachments(files) : streamAttachments?.length ? streamAttachments.map((attachment, index) => ({
|
|
1311
|
+
id: `att-${Date.now()}-${index}`,
|
|
1312
|
+
filename: attachment.filename,
|
|
1313
|
+
mimeType: attachment.mimeType,
|
|
1314
|
+
kind: attachment.mimeType.startsWith("image/") ? "image" : "file"
|
|
1315
|
+
})) : void 0;
|
|
1196
1316
|
const userMessageId = `user-${Date.now()}`;
|
|
1197
1317
|
const userMsg = {
|
|
1198
1318
|
id: userMessageId,
|
|
1199
1319
|
sessionId: sessionIdRef.current,
|
|
1200
1320
|
role: "user",
|
|
1201
|
-
content:
|
|
1202
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1321
|
+
content: trimmedMessage,
|
|
1322
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1323
|
+
attachments: messageAttachments
|
|
1203
1324
|
};
|
|
1204
1325
|
setMessages((prev) => [...prev, userMsg]);
|
|
1205
|
-
callbacksRef.current.onMessageSent?.(
|
|
1326
|
+
callbacksRef.current.onMessageSent?.(trimmedMessage);
|
|
1206
1327
|
setIsWaitingForResponse(true);
|
|
1207
1328
|
callbacksRef.current.onStreamStart?.();
|
|
1208
1329
|
const streamingId = `assistant-${Date.now()}`;
|
|
@@ -1229,11 +1350,14 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1229
1350
|
activeStreamStore.start(userId, abortController, initialMessages);
|
|
1230
1351
|
}
|
|
1231
1352
|
const newSessionId = await startStream(
|
|
1232
|
-
|
|
1353
|
+
trimmedMessage,
|
|
1233
1354
|
streamingId,
|
|
1234
1355
|
sessionIdRef.current,
|
|
1235
1356
|
abortController,
|
|
1236
|
-
|
|
1357
|
+
{
|
|
1358
|
+
analysisMode: options?.analysisMode,
|
|
1359
|
+
attachments: streamAttachments
|
|
1360
|
+
}
|
|
1237
1361
|
);
|
|
1238
1362
|
const finalStreamUserId = streamUserIdRef.current ?? userId;
|
|
1239
1363
|
if (finalStreamUserId) {
|
|
@@ -1371,19 +1495,6 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1371
1495
|
},
|
|
1372
1496
|
[setPromptStatus]
|
|
1373
1497
|
);
|
|
1374
|
-
const expireUserAction2 = useCallback(
|
|
1375
|
-
async (userActionId) => {
|
|
1376
|
-
setPromptStatus(userActionId, "expired");
|
|
1377
|
-
try {
|
|
1378
|
-
await expireUserAction(configRef.current, userActionId);
|
|
1379
|
-
} catch (error) {
|
|
1380
|
-
if (error instanceof UserActionStaleError) return;
|
|
1381
|
-
callbacksRef.current.onError?.(error);
|
|
1382
|
-
throw error;
|
|
1383
|
-
}
|
|
1384
|
-
},
|
|
1385
|
-
[setPromptStatus]
|
|
1386
|
-
);
|
|
1387
1498
|
const dismissNotification = useCallback((id) => {
|
|
1388
1499
|
setUserActionState((prev) => ({
|
|
1389
1500
|
...prev,
|
|
@@ -1424,6 +1535,18 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1424
1535
|
setMessages(config.initialMessages);
|
|
1425
1536
|
sessionIdRef.current = getSessionIdFromMessages(config.initialMessages) ?? config.initialSessionId;
|
|
1426
1537
|
}, [config.initialMessages, config.initialSessionId, config.userId]);
|
|
1538
|
+
const hydratedSessionIdRef = useRef(void 0);
|
|
1539
|
+
useEffect(() => {
|
|
1540
|
+
if (config.userId) return;
|
|
1541
|
+
if (!config.initialMessages?.length) return;
|
|
1542
|
+
const sessionId = config.initialSessionId;
|
|
1543
|
+
if (hydratedSessionIdRef.current === sessionId && messagesRef.current.length > 0) {
|
|
1544
|
+
return;
|
|
1545
|
+
}
|
|
1546
|
+
hydratedSessionIdRef.current = sessionId;
|
|
1547
|
+
setMessages(config.initialMessages);
|
|
1548
|
+
sessionIdRef.current = getSessionIdFromMessages(config.initialMessages) ?? sessionId;
|
|
1549
|
+
}, [config.initialMessages, config.initialSessionId, config.userId]);
|
|
1427
1550
|
useEffect(() => {
|
|
1428
1551
|
const prevUserId = prevUserIdRef.current;
|
|
1429
1552
|
prevUserIdRef.current = config.userId;
|
|
@@ -1458,12 +1581,12 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1458
1581
|
getSessionId,
|
|
1459
1582
|
getMessages,
|
|
1460
1583
|
isWaitingForResponse,
|
|
1584
|
+
isUploadingAttachments,
|
|
1461
1585
|
sessionId: sessionIdRef.current,
|
|
1462
1586
|
userActionState,
|
|
1463
1587
|
submitUserAction: submitUserAction2,
|
|
1464
1588
|
cancelUserAction: cancelUserAction2,
|
|
1465
1589
|
resendUserAction: resendUserAction2,
|
|
1466
|
-
expireUserAction: expireUserAction2,
|
|
1467
1590
|
dismissNotification
|
|
1468
1591
|
};
|
|
1469
1592
|
}
|
|
@@ -6113,7 +6236,7 @@ var PaymanChatInner = forwardRef(function PaymanChatInner2({
|
|
|
6113
6236
|
const submitUserAction2 = chat.submitUserAction ?? NOOP_ASYNC;
|
|
6114
6237
|
const cancelUserAction2 = chat.cancelUserAction ?? NOOP_ASYNC;
|
|
6115
6238
|
const resendUserAction2 = chat.resendUserAction ?? NOOP_ASYNC;
|
|
6116
|
-
const
|
|
6239
|
+
const expireUserAction = chat.expireUserAction ?? NOOP_ASYNC;
|
|
6117
6240
|
const dismissNotification = chat.dismissNotification ?? NOOP;
|
|
6118
6241
|
const isUserActionSupported = typeof chat.submitUserAction === "function" && typeof chat.cancelUserAction === "function" && typeof chat.resendUserAction === "function";
|
|
6119
6242
|
const {
|
|
@@ -6514,7 +6637,7 @@ var PaymanChatInner = forwardRef(function PaymanChatInner2({
|
|
|
6514
6637
|
onSubmitUserAction: isUserActionSupported ? submitUserAction2 : void 0,
|
|
6515
6638
|
onCancelUserAction: isUserActionSupported ? cancelUserAction2 : void 0,
|
|
6516
6639
|
onResendUserAction: isUserActionSupported ? resendUserAction2 : void 0,
|
|
6517
|
-
onExpireUserAction: isUserActionSupported ?
|
|
6640
|
+
onExpireUserAction: isUserActionSupported ? expireUserAction : void 0,
|
|
6518
6641
|
onDismissNotification: dismissNotification,
|
|
6519
6642
|
onSubmitFeedback: handleSubmitFeedback
|
|
6520
6643
|
}
|
|
@@ -6598,6 +6721,6 @@ var PaymanChat = forwardRef(
|
|
|
6598
6721
|
}
|
|
6599
6722
|
);
|
|
6600
6723
|
|
|
6601
|
-
export { PaymanChat, PaymanChatContext, UserActionStaleError, cancelUserAction, captureSentryError, cn,
|
|
6724
|
+
export { PaymanChat, PaymanChatContext, UserActionStaleError, cancelUserAction, captureSentryError, cn, formatDate, resendUserAction, submitUserAction, useChatV2, usePaymanChat, useVoice };
|
|
6602
6725
|
//# sourceMappingURL=index.mjs.map
|
|
6603
6726
|
//# sourceMappingURL=index.mjs.map
|