@paymanai/payman-ask-sdk 4.0.22 → 4.0.24
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.js +279 -83
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +279 -83
- package/dist/index.mjs.map +1 -1
- package/dist/index.native.js +241 -46
- package/dist/index.native.js.map +1 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -495,9 +495,9 @@ function processStreamEventV2(rawEvent, state) {
|
|
|
495
495
|
state.hasError = true;
|
|
496
496
|
state.errorMessage = "WORKFLOW_FAILED";
|
|
497
497
|
}
|
|
498
|
-
state.steps.forEach((
|
|
499
|
-
if (
|
|
500
|
-
|
|
498
|
+
state.steps.forEach((step2) => {
|
|
499
|
+
if (step2.status === "in_progress") {
|
|
500
|
+
step2.status = "completed";
|
|
501
501
|
}
|
|
502
502
|
});
|
|
503
503
|
state.lastEventType = eventType;
|
|
@@ -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/;
|
|
@@ -912,11 +917,11 @@ function useStreamManagerV2(config, callbacks, setMessages, setIsWaitingForRespo
|
|
|
912
917
|
errorDetails: isAborted ? void 0 : error.message,
|
|
913
918
|
content: isAborted ? state.finalResponse || "" : state.finalResponse || FRIENDLY_ERROR_MESSAGE,
|
|
914
919
|
currentMessage: isAborted ? "Thinking..." : void 0,
|
|
915
|
-
steps: [...state.steps].map((
|
|
916
|
-
if (
|
|
917
|
-
return { ...
|
|
920
|
+
steps: [...state.steps].map((step2) => {
|
|
921
|
+
if (step2.status === "in_progress" && isAborted) {
|
|
922
|
+
return { ...step2, status: "pending" };
|
|
918
923
|
}
|
|
919
|
-
return
|
|
924
|
+
return step2;
|
|
920
925
|
}),
|
|
921
926
|
currentExecutingStepId: void 0
|
|
922
927
|
} : msg
|
|
@@ -1002,11 +1007,11 @@ function useStreamManagerV2(config, callbacks, setMessages, setIsWaitingForRespo
|
|
|
1002
1007
|
isCancelled: isAborted,
|
|
1003
1008
|
errorDetails: isAborted ? void 0 : error.message,
|
|
1004
1009
|
content: isAborted ? state.finalResponse || "" : state.finalResponse || FRIENDLY_ERROR_MESSAGE,
|
|
1005
|
-
steps: [...state.steps].map((
|
|
1006
|
-
if (
|
|
1007
|
-
return { ...
|
|
1010
|
+
steps: [...state.steps].map((step2) => {
|
|
1011
|
+
if (step2.status === "in_progress" && isAborted) {
|
|
1012
|
+
return { ...step2, status: "pending" };
|
|
1008
1013
|
}
|
|
1009
|
-
return
|
|
1014
|
+
return step2;
|
|
1010
1015
|
}),
|
|
1011
1016
|
currentExecutingStepId: void 0
|
|
1012
1017
|
} : msg
|
|
@@ -1027,11 +1032,11 @@ function useStreamManagerV2(config, callbacks, setMessages, setIsWaitingForRespo
|
|
|
1027
1032
|
};
|
|
1028
1033
|
}
|
|
1029
1034
|
function createCancelledMessageUpdate(steps, currentMessage) {
|
|
1030
|
-
const updatedSteps = steps.map((
|
|
1031
|
-
if (
|
|
1032
|
-
return { ...
|
|
1035
|
+
const updatedSteps = steps.map((step2) => {
|
|
1036
|
+
if (step2.status === "in_progress") {
|
|
1037
|
+
return { ...step2, status: "pending" };
|
|
1033
1038
|
}
|
|
1034
|
-
return
|
|
1039
|
+
return step2;
|
|
1035
1040
|
});
|
|
1036
1041
|
return {
|
|
1037
1042
|
isStreaming: false,
|
|
@@ -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
|
}
|
|
@@ -2268,7 +2391,7 @@ function createMarkdownComponents(options = {}) {
|
|
|
2268
2391
|
},
|
|
2269
2392
|
pre: ({ children }) => /* @__PURE__ */ jsx("pre", { className: "my-2 max-w-full overflow-x-auto rounded-lg", children }),
|
|
2270
2393
|
ul: ({ children }) => /* @__PURE__ */ jsx("ul", { className: "mb-3 ml-4 list-disc space-y-1 text-sm", children }),
|
|
2271
|
-
ol: ({ children }) => /* @__PURE__ */ jsx("ol", { className: "mb-3 ml-4 list-decimal space-y-1 text-sm", children }),
|
|
2394
|
+
ol: ({ children, start }) => /* @__PURE__ */ jsx("ol", { className: "mb-3 ml-4 list-decimal space-y-1 text-sm", start, children }),
|
|
2272
2395
|
li: ({ children }) => /* @__PURE__ */ jsx("li", { className: "text-sm leading-relaxed", children }),
|
|
2273
2396
|
h1: ({ children }) => /* @__PURE__ */ jsx("h1", { className: "mt-4 mb-2 text-lg font-semibold first:mt-0", children }),
|
|
2274
2397
|
h2: ({ children }) => /* @__PURE__ */ jsx("h2", { className: "mt-3 mb-2 text-base font-semibold first:mt-0", children }),
|
|
@@ -2337,7 +2460,7 @@ function AgentMessage({
|
|
|
2337
2460
|
}
|
|
2338
2461
|
wasStreamingRef.current = isStreaming;
|
|
2339
2462
|
}, [isStreaming, hasSteps]);
|
|
2340
|
-
const totalElapsedMs = hasSteps ? message.steps.reduce((sum,
|
|
2463
|
+
const totalElapsedMs = hasSteps ? message.steps.reduce((sum, step2) => sum + (step2.elapsedMs || 0), 0) : 0;
|
|
2341
2464
|
const currentMessage = message.currentMessage;
|
|
2342
2465
|
const rawContent = message.streamingContent || message.content || "";
|
|
2343
2466
|
const content = rawContent.replace(/\\n/g, "\n");
|
|
@@ -2365,25 +2488,25 @@ function AgentMessage({
|
|
|
2365
2488
|
}
|
|
2366
2489
|
return `${count} ${stepWord} completed`;
|
|
2367
2490
|
};
|
|
2368
|
-
const renderStepIcon = (
|
|
2491
|
+
const renderStepIcon = (step2, isCurrentlyExecuting) => {
|
|
2369
2492
|
const wrapper = "h-4 w-4 flex items-center justify-center shrink-0";
|
|
2370
2493
|
if (isCurrentlyExecuting)
|
|
2371
2494
|
return /* @__PURE__ */ jsx("div", { className: wrapper, children: /* @__PURE__ */ jsx(Loader2, { className: "h-3.5 w-3.5 payman-agent-step-icon--active animate-spin" }) });
|
|
2372
|
-
if (
|
|
2495
|
+
if (step2.status === "pending" && isCancelled)
|
|
2373
2496
|
return /* @__PURE__ */ jsx("div", { className: wrapper, children: /* @__PURE__ */ jsx("div", { className: "h-1.5 w-1.5 rounded-full payman-agent-step-icon--pending" }) });
|
|
2374
|
-
if (
|
|
2497
|
+
if (step2.status === "pending" || step2.status === "in_progress")
|
|
2375
2498
|
return /* @__PURE__ */ jsx("div", { className: wrapper, children: /* @__PURE__ */ jsx(Loader2, { className: "h-3.5 w-3.5 payman-agent-step-icon--in-progress-dim animate-spin" }) });
|
|
2376
|
-
if (
|
|
2499
|
+
if (step2.status === "completed")
|
|
2377
2500
|
return /* @__PURE__ */ jsx("div", { className: wrapper, children: /* @__PURE__ */ jsx(
|
|
2378
2501
|
Check,
|
|
2379
2502
|
{
|
|
2380
2503
|
className: cn(
|
|
2381
2504
|
"h-3.5 w-3.5",
|
|
2382
|
-
|
|
2505
|
+
step2.eventType === "USER_ACTION_SUCCESS" ? "payman-agent-step-icon--success" : "payman-agent-step-icon--success-dim"
|
|
2383
2506
|
)
|
|
2384
2507
|
}
|
|
2385
2508
|
) });
|
|
2386
|
-
if (
|
|
2509
|
+
if (step2.status === "error")
|
|
2387
2510
|
return /* @__PURE__ */ jsx("div", { className: wrapper, children: /* @__PURE__ */ jsx(X, { className: "h-3.5 w-3.5 payman-agent-step-icon--error" }) });
|
|
2388
2511
|
return /* @__PURE__ */ jsx("div", { className: wrapper, children: /* @__PURE__ */ jsx("div", { className: "h-1.5 w-1.5 rounded-full payman-agent-step-icon--pending-dim" }) });
|
|
2389
2512
|
};
|
|
@@ -2395,33 +2518,33 @@ function AgentMessage({
|
|
|
2395
2518
|
exit: { height: 0, opacity: 0 },
|
|
2396
2519
|
transition: { duration: 0.2, ease: "easeInOut" },
|
|
2397
2520
|
className: "overflow-hidden",
|
|
2398
|
-
children: /* @__PURE__ */ jsx("div", { className: "pt-1.5", children: message.steps.map((
|
|
2399
|
-
const isCurrentlyExecuting =
|
|
2400
|
-
const hasTime =
|
|
2521
|
+
children: /* @__PURE__ */ jsx("div", { className: "pt-1.5", children: message.steps.map((step2) => {
|
|
2522
|
+
const isCurrentlyExecuting = step2.id === currentExecutingStepId && step2.status === "in_progress" && isStreaming && !isCancelled;
|
|
2523
|
+
const hasTime = step2.elapsedMs != null && step2.elapsedMs > 0;
|
|
2401
2524
|
return /* @__PURE__ */ jsxs("div", { className: "mb-1.5", children: [
|
|
2402
2525
|
/* @__PURE__ */ jsxs("div", { className: "flex gap-1.5 items-start", children: [
|
|
2403
|
-
/* @__PURE__ */ jsx("div", { className: "mt-px", children: renderStepIcon(
|
|
2526
|
+
/* @__PURE__ */ jsx("div", { className: "mt-px", children: renderStepIcon(step2, isCurrentlyExecuting) }),
|
|
2404
2527
|
/* @__PURE__ */ jsx(
|
|
2405
2528
|
"span",
|
|
2406
2529
|
{
|
|
2407
2530
|
className: cn(
|
|
2408
2531
|
"text-xs leading-relaxed min-w-0 break-words",
|
|
2409
2532
|
isCurrentlyExecuting && "shimmer-text font-medium",
|
|
2410
|
-
!isCurrentlyExecuting &&
|
|
2411
|
-
!isCurrentlyExecuting &&
|
|
2412
|
-
!isCurrentlyExecuting &&
|
|
2413
|
-
!isCurrentlyExecuting &&
|
|
2414
|
-
!isCurrentlyExecuting &&
|
|
2533
|
+
!isCurrentlyExecuting && step2.status === "error" && "payman-agent-step-text--error",
|
|
2534
|
+
!isCurrentlyExecuting && step2.eventType === "USER_ACTION_SUCCESS" && "payman-agent-step-text--success",
|
|
2535
|
+
!isCurrentlyExecuting && step2.status === "completed" && "payman-agent-step-text--completed",
|
|
2536
|
+
!isCurrentlyExecuting && step2.status === "pending" && "payman-agent-step-text--pending",
|
|
2537
|
+
!isCurrentlyExecuting && step2.status === "in_progress" && "payman-agent-step-text--in-progress"
|
|
2415
2538
|
),
|
|
2416
|
-
children:
|
|
2539
|
+
children: step2.message
|
|
2417
2540
|
}
|
|
2418
2541
|
)
|
|
2419
2542
|
] }),
|
|
2420
2543
|
hasTime && /* @__PURE__ */ jsx("div", { className: "pl-[22px] mt-1", children: /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 px-1.5 py-0.5 rounded-md payman-agent-step-time leading-none", children: [
|
|
2421
2544
|
/* @__PURE__ */ jsx(Clock, { className: "h-2.5 w-2.5 shrink-0 payman-agent-step-time-icon" }),
|
|
2422
|
-
/* @__PURE__ */ jsx("span", { className: "text-[10px] font-mono payman-agent-step-time-text", children: formatElapsedTime(
|
|
2545
|
+
/* @__PURE__ */ jsx("span", { className: "text-[10px] font-mono payman-agent-step-time-text", children: formatElapsedTime(step2.elapsedMs) })
|
|
2423
2546
|
] }) })
|
|
2424
|
-
] },
|
|
2547
|
+
] }, step2.id);
|
|
2425
2548
|
}) })
|
|
2426
2549
|
}
|
|
2427
2550
|
) });
|
|
@@ -3384,7 +3507,7 @@ function buildComponents(onImageClick, isResolvingRef) {
|
|
|
3384
3507
|
code: ({ children }) => /* @__PURE__ */ jsx("code", { children }),
|
|
3385
3508
|
pre: ({ children }) => /* @__PURE__ */ jsx("div", { className: "payman-v2-markdown-pre", children: /* @__PURE__ */ jsx("pre", { children }) }),
|
|
3386
3509
|
ul: ({ children }) => /* @__PURE__ */ jsx("ul", { children }),
|
|
3387
|
-
ol: ({ children }) => /* @__PURE__ */ jsx("ol", { children }),
|
|
3510
|
+
ol: ({ children, start }) => /* @__PURE__ */ jsx("ol", { start, children }),
|
|
3388
3511
|
li: ({ children }) => /* @__PURE__ */ jsx("li", { children }),
|
|
3389
3512
|
h1: ({ children }) => /* @__PURE__ */ jsx("h1", { children }),
|
|
3390
3513
|
h2: ({ children }) => /* @__PURE__ */ jsx("h2", { children }),
|
|
@@ -3685,6 +3808,87 @@ function FeedbackReasonModal({
|
|
|
3685
3808
|
}
|
|
3686
3809
|
) : null });
|
|
3687
3810
|
}
|
|
3811
|
+
|
|
3812
|
+
// src/utils/markdownImageToken.ts
|
|
3813
|
+
function step(text, i) {
|
|
3814
|
+
if (text[i] === "\\" && i + 1 < text.length) return i + 2;
|
|
3815
|
+
return i + 1;
|
|
3816
|
+
}
|
|
3817
|
+
function scanAltText(text, start) {
|
|
3818
|
+
let i = start;
|
|
3819
|
+
while (i < text.length) {
|
|
3820
|
+
if (text[i] === "]") return i;
|
|
3821
|
+
i = step(text, i);
|
|
3822
|
+
}
|
|
3823
|
+
return -1;
|
|
3824
|
+
}
|
|
3825
|
+
function scanOptionalTitle(text, start) {
|
|
3826
|
+
let i = start;
|
|
3827
|
+
while (i < text.length && /[\t\n ]/.test(text[i])) i++;
|
|
3828
|
+
if (i >= text.length) return i;
|
|
3829
|
+
const quote = text[i];
|
|
3830
|
+
if (quote !== '"' && quote !== "'") return i;
|
|
3831
|
+
i++;
|
|
3832
|
+
while (i < text.length) {
|
|
3833
|
+
if (text[i] === quote) return i + 1;
|
|
3834
|
+
i = step(text, i);
|
|
3835
|
+
}
|
|
3836
|
+
return -1;
|
|
3837
|
+
}
|
|
3838
|
+
function scanAngleBracketDestination(text, start) {
|
|
3839
|
+
let i = start + 1;
|
|
3840
|
+
while (i < text.length) {
|
|
3841
|
+
if (text[i] === ">") return i + 1;
|
|
3842
|
+
i = step(text, i);
|
|
3843
|
+
}
|
|
3844
|
+
return -1;
|
|
3845
|
+
}
|
|
3846
|
+
function scanRawDestination(text, start) {
|
|
3847
|
+
let i = start;
|
|
3848
|
+
let depth = 1;
|
|
3849
|
+
while (i < text.length) {
|
|
3850
|
+
const char = text[i];
|
|
3851
|
+
if (char === "\\") {
|
|
3852
|
+
if (i + 1 >= text.length) return -1;
|
|
3853
|
+
i += 2;
|
|
3854
|
+
continue;
|
|
3855
|
+
}
|
|
3856
|
+
if (char === "(") depth++;
|
|
3857
|
+
else if (char === ")") {
|
|
3858
|
+
depth--;
|
|
3859
|
+
if (depth === 0) return i + 1;
|
|
3860
|
+
}
|
|
3861
|
+
i++;
|
|
3862
|
+
}
|
|
3863
|
+
return -1;
|
|
3864
|
+
}
|
|
3865
|
+
function completeMarkdownImageTokenLength(text) {
|
|
3866
|
+
if (!text.startsWith("![")) return 0;
|
|
3867
|
+
const altEnd = scanAltText(text, 2);
|
|
3868
|
+
if (altEnd === -1 || altEnd + 1 >= text.length || text[altEnd + 1] !== "(") {
|
|
3869
|
+
return 0;
|
|
3870
|
+
}
|
|
3871
|
+
let i = altEnd + 2;
|
|
3872
|
+
if (i >= text.length) return 0;
|
|
3873
|
+
if (text[i] === "<") {
|
|
3874
|
+
i = scanAngleBracketDestination(text, i);
|
|
3875
|
+
if (i === -1) return 0;
|
|
3876
|
+
i = scanOptionalTitle(text, i);
|
|
3877
|
+
if (i === -1 || i >= text.length || text[i] !== ")") return 0;
|
|
3878
|
+
return i + 1;
|
|
3879
|
+
}
|
|
3880
|
+
i = scanRawDestination(text, i);
|
|
3881
|
+
return i === -1 ? 0 : i;
|
|
3882
|
+
}
|
|
3883
|
+
function stripIncompleteImageToken(text) {
|
|
3884
|
+
const lastBang = text.lastIndexOf("![");
|
|
3885
|
+
if (lastBang === -1) return text;
|
|
3886
|
+
const suffix = text.slice(lastBang);
|
|
3887
|
+
if (completeMarkdownImageTokenLength(suffix) > 0) return text;
|
|
3888
|
+
return text.slice(0, lastBang);
|
|
3889
|
+
}
|
|
3890
|
+
|
|
3891
|
+
// src/components/v2/useTypingEffect.ts
|
|
3688
3892
|
var RESPONSE_SPEED = {
|
|
3689
3893
|
normal: [2, 4],
|
|
3690
3894
|
fast: 1,
|
|
@@ -3692,7 +3896,6 @@ var RESPONSE_SPEED = {
|
|
|
3692
3896
|
newline: [4, 6],
|
|
3693
3897
|
idle: 15
|
|
3694
3898
|
};
|
|
3695
|
-
var MARKDOWN_IMAGE_REGEX = /^!\[[^\]]*\]\([^)]*\)/;
|
|
3696
3899
|
function charDelay(char, speed, multiplier) {
|
|
3697
3900
|
const raw = (() => {
|
|
3698
3901
|
if (char === "*") return speed.fast;
|
|
@@ -3751,9 +3954,9 @@ function useTypingEffect(targetText, enabled, speed = RESPONSE_SPEED, initialDis
|
|
|
3751
3954
|
}
|
|
3752
3955
|
if (displayedRef.current.length < targetRef.current.length) {
|
|
3753
3956
|
const remaining = targetRef.current.slice(displayedRef.current.length);
|
|
3754
|
-
const
|
|
3755
|
-
if (
|
|
3756
|
-
displayedRef.current +=
|
|
3957
|
+
const imageTokenLength = completeMarkdownImageTokenLength(remaining);
|
|
3958
|
+
if (imageTokenLength > 0) {
|
|
3959
|
+
displayedRef.current += remaining.slice(0, imageTokenLength);
|
|
3757
3960
|
setDisplayedText(displayedRef.current);
|
|
3758
3961
|
timerRef.current = setTimeout(tick, 0);
|
|
3759
3962
|
return;
|
|
@@ -3782,13 +3985,6 @@ function useTypingEffect(targetText, enabled, speed = RESPONSE_SPEED, initialDis
|
|
|
3782
3985
|
isTyping
|
|
3783
3986
|
};
|
|
3784
3987
|
}
|
|
3785
|
-
function stripIncompleteImageToken(text) {
|
|
3786
|
-
const lastBang = text.lastIndexOf("![");
|
|
3787
|
-
if (lastBang === -1) return text;
|
|
3788
|
-
const after = text.slice(lastBang);
|
|
3789
|
-
if (/^!\[[^\]]*\]\([^)]*\)/.test(after)) return text;
|
|
3790
|
-
return text.slice(0, lastBang);
|
|
3791
|
-
}
|
|
3792
3988
|
function getFeedbackState(message) {
|
|
3793
3989
|
const feedback = message.feedback;
|
|
3794
3990
|
if (feedback === "up" || feedback === "down") return feedback;
|
|
@@ -5672,9 +5868,9 @@ var PRE_PIPELINE_STEPS = /* @__PURE__ */ new Set([
|
|
|
5672
5868
|
"build_pipeline",
|
|
5673
5869
|
"load_skill_index"
|
|
5674
5870
|
]);
|
|
5675
|
-
function stepColor(
|
|
5676
|
-
if (
|
|
5677
|
-
if (PRE_PIPELINE_STEPS.has(
|
|
5871
|
+
function stepColor(step2) {
|
|
5872
|
+
if (step2.status === "failed") return "#ef4444";
|
|
5873
|
+
if (PRE_PIPELINE_STEPS.has(step2.step)) return "#f59e0b";
|
|
5678
5874
|
return "#3b82f6";
|
|
5679
5875
|
}
|
|
5680
5876
|
function formatMs(ms) {
|
|
@@ -5851,10 +6047,10 @@ function TimelineBars({
|
|
|
5851
6047
|
totalMs,
|
|
5852
6048
|
unaccountedMs
|
|
5853
6049
|
}) {
|
|
5854
|
-
const bars = trace.pipelineSteps.map((
|
|
5855
|
-
const duration =
|
|
6050
|
+
const bars = trace.pipelineSteps.map((step2) => {
|
|
6051
|
+
const duration = step2.durationMs ?? 0;
|
|
5856
6052
|
const widthPct = totalMs > 0 ? duration / totalMs * 100 : 0;
|
|
5857
|
-
const llmMs =
|
|
6053
|
+
const llmMs = step2.llmCall?.durationMs ?? null;
|
|
5858
6054
|
return /* @__PURE__ */ jsxs("div", { style: { marginBottom: 8 }, children: [
|
|
5859
6055
|
/* @__PURE__ */ jsxs(
|
|
5860
6056
|
"div",
|
|
@@ -5868,8 +6064,8 @@ function TimelineBars({
|
|
|
5868
6064
|
},
|
|
5869
6065
|
children: [
|
|
5870
6066
|
/* @__PURE__ */ jsxs("span", { children: [
|
|
5871
|
-
|
|
5872
|
-
|
|
6067
|
+
step2.step,
|
|
6068
|
+
step2.status === "failed" && /* @__PURE__ */ jsx("span", { style: { color: "#fca5a5", marginLeft: 6 }, children: "(failed)" })
|
|
5873
6069
|
] }),
|
|
5874
6070
|
/* @__PURE__ */ jsxs("span", { style: { opacity: 0.75 }, children: [
|
|
5875
6071
|
formatMs(duration),
|
|
@@ -5897,14 +6093,14 @@ function TimelineBars({
|
|
|
5897
6093
|
style: {
|
|
5898
6094
|
height: "100%",
|
|
5899
6095
|
width: `${Math.max(widthPct, 0.3)}%`,
|
|
5900
|
-
background: stepColor(
|
|
6096
|
+
background: stepColor(step2),
|
|
5901
6097
|
transition: "width 0.2s ease"
|
|
5902
6098
|
}
|
|
5903
6099
|
}
|
|
5904
6100
|
)
|
|
5905
6101
|
}
|
|
5906
6102
|
)
|
|
5907
|
-
] }, `${
|
|
6103
|
+
] }, `${step2.step}-${step2.startTime}`);
|
|
5908
6104
|
});
|
|
5909
6105
|
return /* @__PURE__ */ jsxs("div", { children: [
|
|
5910
6106
|
bars,
|
|
@@ -6123,7 +6319,7 @@ var PaymanChatInner = forwardRef(function PaymanChatInner2({
|
|
|
6123
6319
|
const submitUserAction2 = chat.submitUserAction ?? NOOP_ASYNC;
|
|
6124
6320
|
const cancelUserAction2 = chat.cancelUserAction ?? NOOP_ASYNC;
|
|
6125
6321
|
const resendUserAction2 = chat.resendUserAction ?? NOOP_ASYNC;
|
|
6126
|
-
const
|
|
6322
|
+
const expireUserAction = chat.expireUserAction ?? NOOP_ASYNC;
|
|
6127
6323
|
const dismissNotification = chat.dismissNotification ?? NOOP;
|
|
6128
6324
|
const isUserActionSupported = typeof chat.submitUserAction === "function" && typeof chat.cancelUserAction === "function" && typeof chat.resendUserAction === "function";
|
|
6129
6325
|
const {
|
|
@@ -6524,7 +6720,7 @@ var PaymanChatInner = forwardRef(function PaymanChatInner2({
|
|
|
6524
6720
|
onSubmitUserAction: isUserActionSupported ? submitUserAction2 : void 0,
|
|
6525
6721
|
onCancelUserAction: isUserActionSupported ? cancelUserAction2 : void 0,
|
|
6526
6722
|
onResendUserAction: isUserActionSupported ? resendUserAction2 : void 0,
|
|
6527
|
-
onExpireUserAction: isUserActionSupported ?
|
|
6723
|
+
onExpireUserAction: isUserActionSupported ? expireUserAction : void 0,
|
|
6528
6724
|
onDismissNotification: dismissNotification,
|
|
6529
6725
|
onSubmitFeedback: handleSubmitFeedback
|
|
6530
6726
|
}
|