@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.js
CHANGED
|
@@ -522,9 +522,9 @@ function processStreamEventV2(rawEvent, state) {
|
|
|
522
522
|
state.hasError = true;
|
|
523
523
|
state.errorMessage = "WORKFLOW_FAILED";
|
|
524
524
|
}
|
|
525
|
-
state.steps.forEach((
|
|
526
|
-
if (
|
|
527
|
-
|
|
525
|
+
state.steps.forEach((step2) => {
|
|
526
|
+
if (step2.status === "in_progress") {
|
|
527
|
+
step2.status = "completed";
|
|
528
528
|
}
|
|
529
529
|
});
|
|
530
530
|
state.lastEventType = eventType;
|
|
@@ -736,7 +736,8 @@ function buildRequestBody(config, userMessage, sessionId, options) {
|
|
|
736
736
|
sessionAttributes,
|
|
737
737
|
analysisMode: options?.analysisMode,
|
|
738
738
|
locale: resolveLocale(config.locale),
|
|
739
|
-
timezone: resolveTimezone(config.timezone)
|
|
739
|
+
timezone: resolveTimezone(config.timezone),
|
|
740
|
+
...options?.attachments?.length ? { attachments: options.attachments } : {}
|
|
740
741
|
};
|
|
741
742
|
}
|
|
742
743
|
function resolveLocale(configured) {
|
|
@@ -781,6 +782,7 @@ function buildResolveImagesUrl(config) {
|
|
|
781
782
|
const basePath = normalizedEndpointPath.endsWith("/stream") ? normalizedEndpointPath.slice(0, -"/stream".length) : normalizedEndpointPath;
|
|
782
783
|
return `${config.api.baseUrl}${basePath}/resolve-image-urls`;
|
|
783
784
|
}
|
|
785
|
+
var NGROK_SKIP_BROWSER_WARNING = "ngrok-skip-browser-warning";
|
|
784
786
|
function buildRequestHeaders(config) {
|
|
785
787
|
const headers = {
|
|
786
788
|
...config.api.headers
|
|
@@ -788,6 +790,9 @@ function buildRequestHeaders(config) {
|
|
|
788
790
|
if (config.api.authToken) {
|
|
789
791
|
headers.Authorization = `Bearer ${config.api.authToken}`;
|
|
790
792
|
}
|
|
793
|
+
if (!headers[NGROK_SKIP_BROWSER_WARNING]) {
|
|
794
|
+
headers[NGROK_SKIP_BROWSER_WARNING] = "true";
|
|
795
|
+
}
|
|
791
796
|
return headers;
|
|
792
797
|
}
|
|
793
798
|
var RAG_IMAGE_REGEX = /\/api\/rag\/chunks\/[^"'\s]+\/image/;
|
|
@@ -939,11 +944,11 @@ function useStreamManagerV2(config, callbacks, setMessages, setIsWaitingForRespo
|
|
|
939
944
|
errorDetails: isAborted ? void 0 : error.message,
|
|
940
945
|
content: isAborted ? state.finalResponse || "" : state.finalResponse || FRIENDLY_ERROR_MESSAGE,
|
|
941
946
|
currentMessage: isAborted ? "Thinking..." : void 0,
|
|
942
|
-
steps: [...state.steps].map((
|
|
943
|
-
if (
|
|
944
|
-
return { ...
|
|
947
|
+
steps: [...state.steps].map((step2) => {
|
|
948
|
+
if (step2.status === "in_progress" && isAborted) {
|
|
949
|
+
return { ...step2, status: "pending" };
|
|
945
950
|
}
|
|
946
|
-
return
|
|
951
|
+
return step2;
|
|
947
952
|
}),
|
|
948
953
|
currentExecutingStepId: void 0
|
|
949
954
|
} : msg
|
|
@@ -1029,11 +1034,11 @@ function useStreamManagerV2(config, callbacks, setMessages, setIsWaitingForRespo
|
|
|
1029
1034
|
isCancelled: isAborted,
|
|
1030
1035
|
errorDetails: isAborted ? void 0 : error.message,
|
|
1031
1036
|
content: isAborted ? state.finalResponse || "" : state.finalResponse || FRIENDLY_ERROR_MESSAGE,
|
|
1032
|
-
steps: [...state.steps].map((
|
|
1033
|
-
if (
|
|
1034
|
-
return { ...
|
|
1037
|
+
steps: [...state.steps].map((step2) => {
|
|
1038
|
+
if (step2.status === "in_progress" && isAborted) {
|
|
1039
|
+
return { ...step2, status: "pending" };
|
|
1035
1040
|
}
|
|
1036
|
-
return
|
|
1041
|
+
return step2;
|
|
1037
1042
|
}),
|
|
1038
1043
|
currentExecutingStepId: void 0
|
|
1039
1044
|
} : msg
|
|
@@ -1054,11 +1059,11 @@ function useStreamManagerV2(config, callbacks, setMessages, setIsWaitingForRespo
|
|
|
1054
1059
|
};
|
|
1055
1060
|
}
|
|
1056
1061
|
function createCancelledMessageUpdate(steps, currentMessage) {
|
|
1057
|
-
const updatedSteps = steps.map((
|
|
1058
|
-
if (
|
|
1059
|
-
return { ...
|
|
1062
|
+
const updatedSteps = steps.map((step2) => {
|
|
1063
|
+
if (step2.status === "in_progress") {
|
|
1064
|
+
return { ...step2, status: "pending" };
|
|
1060
1065
|
}
|
|
1061
|
-
return
|
|
1066
|
+
return step2;
|
|
1062
1067
|
});
|
|
1063
1068
|
return {
|
|
1064
1069
|
isStreaming: false,
|
|
@@ -1068,6 +1073,81 @@ function createCancelledMessageUpdate(steps, currentMessage) {
|
|
|
1068
1073
|
currentMessage: currentMessage || "Thinking..."
|
|
1069
1074
|
};
|
|
1070
1075
|
}
|
|
1076
|
+
var DEFAULT_SIGNED_URL_ENDPOINT = "/api/files/signed-url";
|
|
1077
|
+
function fileExtension(filename) {
|
|
1078
|
+
const ext = filename.split(".").pop()?.toLowerCase().replace(/^\./, "");
|
|
1079
|
+
return ext && ext.length > 0 ? ext : "bin";
|
|
1080
|
+
}
|
|
1081
|
+
function resolveMimeType(file) {
|
|
1082
|
+
if (file.type && file.type.trim().length > 0) return file.type;
|
|
1083
|
+
const ext = fileExtension(file.name);
|
|
1084
|
+
const byExt = {
|
|
1085
|
+
pdf: "application/pdf",
|
|
1086
|
+
png: "image/png",
|
|
1087
|
+
jpg: "image/jpeg",
|
|
1088
|
+
jpeg: "image/jpeg",
|
|
1089
|
+
gif: "image/gif",
|
|
1090
|
+
webp: "image/webp"
|
|
1091
|
+
};
|
|
1092
|
+
return byExt[ext] ?? "application/octet-stream";
|
|
1093
|
+
}
|
|
1094
|
+
function buildSignedUrlEndpoint(config, ext) {
|
|
1095
|
+
const endpoint = config.api.signedUrlEndpoint || DEFAULT_SIGNED_URL_ENDPOINT;
|
|
1096
|
+
const queryParams = new URLSearchParams({ extn: ext.replace(/^\./, "") });
|
|
1097
|
+
return `${config.api.baseUrl}${endpoint}?${queryParams.toString()}`;
|
|
1098
|
+
}
|
|
1099
|
+
async function requestSignedUrl(config, ext, signal) {
|
|
1100
|
+
const url = buildSignedUrlEndpoint(config, ext);
|
|
1101
|
+
const headers = buildRequestHeaders(config);
|
|
1102
|
+
const response = await fetch(url, {
|
|
1103
|
+
method: "GET",
|
|
1104
|
+
headers,
|
|
1105
|
+
signal
|
|
1106
|
+
});
|
|
1107
|
+
if (!response.ok) {
|
|
1108
|
+
const errorText = await response.text().catch(() => "");
|
|
1109
|
+
throw new Error(
|
|
1110
|
+
errorText ? `Failed to get upload URL (${response.status}): ${errorText}` : `Failed to get upload URL (${response.status})`
|
|
1111
|
+
);
|
|
1112
|
+
}
|
|
1113
|
+
const data = await response.json();
|
|
1114
|
+
if (!data.key || !data.url) {
|
|
1115
|
+
throw new Error("Signed URL response missing key or url");
|
|
1116
|
+
}
|
|
1117
|
+
return { key: data.key, url: data.url };
|
|
1118
|
+
}
|
|
1119
|
+
async function uploadToSignedUrl(signedUrl, file, mimeType, signal) {
|
|
1120
|
+
const response = await fetch(signedUrl, {
|
|
1121
|
+
method: "PUT",
|
|
1122
|
+
headers: {
|
|
1123
|
+
"Content-Type": mimeType,
|
|
1124
|
+
"x-ms-blob-type": "BlockBlob"
|
|
1125
|
+
},
|
|
1126
|
+
body: file,
|
|
1127
|
+
signal
|
|
1128
|
+
});
|
|
1129
|
+
if (!response.ok) {
|
|
1130
|
+
const errorText = await response.text().catch(() => "");
|
|
1131
|
+
throw new Error(
|
|
1132
|
+
errorText ? `Failed to upload file (${response.status}): ${errorText}` : `Failed to upload file (${response.status})`
|
|
1133
|
+
);
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
async function uploadAttachment(config, file, signal) {
|
|
1137
|
+
const ext = fileExtension(file.name);
|
|
1138
|
+
const mimeType = resolveMimeType(file);
|
|
1139
|
+
const { key, url } = await requestSignedUrl(config, ext, signal);
|
|
1140
|
+
await uploadToSignedUrl(url, file, mimeType, signal);
|
|
1141
|
+
return {
|
|
1142
|
+
tempKey: key,
|
|
1143
|
+
filename: file.name,
|
|
1144
|
+
mimeType
|
|
1145
|
+
};
|
|
1146
|
+
}
|
|
1147
|
+
async function uploadAttachments(config, files, signal) {
|
|
1148
|
+
const uploads = files.map((file) => uploadAttachment(config, file, signal));
|
|
1149
|
+
return Promise.all(uploads);
|
|
1150
|
+
}
|
|
1071
1151
|
var UserActionStaleError = class extends Error {
|
|
1072
1152
|
constructor(userActionId, message = "User action is no longer actionable") {
|
|
1073
1153
|
super(message);
|
|
@@ -1104,9 +1184,6 @@ async function cancelUserAction(config, userActionId) {
|
|
|
1104
1184
|
async function resendUserAction(config, userActionId) {
|
|
1105
1185
|
return sendUserActionRequest(config, userActionId, "resend");
|
|
1106
1186
|
}
|
|
1107
|
-
async function expireUserAction(config, userActionId) {
|
|
1108
|
-
return sendUserActionRequest(config, userActionId, "expired");
|
|
1109
|
-
}
|
|
1110
1187
|
var EMPTY_USER_ACTION_STATE = { prompts: [], notifications: [] };
|
|
1111
1188
|
function upsertPrompt(prompts, req) {
|
|
1112
1189
|
const active = { ...req, status: "pending" };
|
|
@@ -1135,12 +1212,32 @@ function getStoredOrInitialMessages(config) {
|
|
|
1135
1212
|
function getSessionIdFromMessages(messages) {
|
|
1136
1213
|
return messages.find((message) => message.sessionId)?.sessionId;
|
|
1137
1214
|
}
|
|
1215
|
+
var IMAGE_EXTENSIONS = /* @__PURE__ */ new Set(["jpg", "jpeg", "png", "gif", "webp", "avif"]);
|
|
1216
|
+
function attachmentKindFromFile(file) {
|
|
1217
|
+
const ext = file.name.split(".").pop()?.toLowerCase() ?? "";
|
|
1218
|
+
if (IMAGE_EXTENSIONS.has(ext) || file.type.startsWith("image/")) return "image";
|
|
1219
|
+
return "file";
|
|
1220
|
+
}
|
|
1221
|
+
function buildMessageAttachments(files) {
|
|
1222
|
+
return files.map((file, index) => {
|
|
1223
|
+
const kind = attachmentKindFromFile(file);
|
|
1224
|
+
return {
|
|
1225
|
+
id: `att-${Date.now()}-${index}`,
|
|
1226
|
+
filename: file.name,
|
|
1227
|
+
mimeType: file.type || "application/octet-stream",
|
|
1228
|
+
// Blob URL for all local files so PDFs/docs stay previewable after send.
|
|
1229
|
+
previewUrl: URL.createObjectURL(file),
|
|
1230
|
+
kind
|
|
1231
|
+
};
|
|
1232
|
+
});
|
|
1233
|
+
}
|
|
1138
1234
|
function useChatV2(config, callbacks = {}) {
|
|
1139
1235
|
const [messages, setMessages] = react.useState(() => getStoredOrInitialMessages(config));
|
|
1140
1236
|
const [isWaitingForResponse, setIsWaitingForResponse] = react.useState(() => {
|
|
1141
1237
|
if (!config.userId) return false;
|
|
1142
1238
|
return activeStreamStore.get(config.userId)?.isWaiting ?? false;
|
|
1143
1239
|
});
|
|
1240
|
+
const [isUploadingAttachments, setIsUploadingAttachments] = react.useState(false);
|
|
1144
1241
|
const sessionIdRef = react.useRef(
|
|
1145
1242
|
getSessionIdFromMessages(getStoredOrInitialMessages(config)) ?? config.initialSessionId ?? void 0
|
|
1146
1243
|
);
|
|
@@ -1215,21 +1312,45 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1215
1312
|
);
|
|
1216
1313
|
const sendMessage = react.useCallback(
|
|
1217
1314
|
async (userMessage, options) => {
|
|
1218
|
-
|
|
1315
|
+
const trimmedMessage = userMessage.trim();
|
|
1316
|
+
const files = options?.files ?? [];
|
|
1317
|
+
const hasPreuploadedAttachments = (options?.attachments?.length ?? 0) > 0;
|
|
1318
|
+
if (!trimmedMessage && files.length === 0 && !hasPreuploadedAttachments) return;
|
|
1319
|
+
let streamAttachments = options?.attachments;
|
|
1320
|
+
if (!streamAttachments && files.length > 0) {
|
|
1321
|
+
setIsUploadingAttachments(true);
|
|
1322
|
+
try {
|
|
1323
|
+
streamAttachments = await uploadAttachments(configRef.current, files);
|
|
1324
|
+
} catch (error) {
|
|
1325
|
+
if (error.name !== "AbortError") {
|
|
1326
|
+
callbacksRef.current.onError?.(error);
|
|
1327
|
+
}
|
|
1328
|
+
throw error;
|
|
1329
|
+
} finally {
|
|
1330
|
+
setIsUploadingAttachments(false);
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1219
1333
|
if (!sessionIdRef.current && configRef.current.autoGenerateSessionId !== false) {
|
|
1220
1334
|
sessionIdRef.current = generateId();
|
|
1221
1335
|
callbacksRef.current.onSessionIdChange?.(sessionIdRef.current);
|
|
1222
1336
|
}
|
|
1337
|
+
const messageAttachments = files.length > 0 ? buildMessageAttachments(files) : streamAttachments?.length ? streamAttachments.map((attachment, index) => ({
|
|
1338
|
+
id: `att-${Date.now()}-${index}`,
|
|
1339
|
+
filename: attachment.filename,
|
|
1340
|
+
mimeType: attachment.mimeType,
|
|
1341
|
+
kind: attachment.mimeType.startsWith("image/") ? "image" : "file"
|
|
1342
|
+
})) : void 0;
|
|
1223
1343
|
const userMessageId = `user-${Date.now()}`;
|
|
1224
1344
|
const userMsg = {
|
|
1225
1345
|
id: userMessageId,
|
|
1226
1346
|
sessionId: sessionIdRef.current,
|
|
1227
1347
|
role: "user",
|
|
1228
|
-
content:
|
|
1229
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1348
|
+
content: trimmedMessage,
|
|
1349
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1350
|
+
attachments: messageAttachments
|
|
1230
1351
|
};
|
|
1231
1352
|
setMessages((prev) => [...prev, userMsg]);
|
|
1232
|
-
callbacksRef.current.onMessageSent?.(
|
|
1353
|
+
callbacksRef.current.onMessageSent?.(trimmedMessage);
|
|
1233
1354
|
setIsWaitingForResponse(true);
|
|
1234
1355
|
callbacksRef.current.onStreamStart?.();
|
|
1235
1356
|
const streamingId = `assistant-${Date.now()}`;
|
|
@@ -1256,11 +1377,14 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1256
1377
|
activeStreamStore.start(userId, abortController, initialMessages);
|
|
1257
1378
|
}
|
|
1258
1379
|
const newSessionId = await startStream(
|
|
1259
|
-
|
|
1380
|
+
trimmedMessage,
|
|
1260
1381
|
streamingId,
|
|
1261
1382
|
sessionIdRef.current,
|
|
1262
1383
|
abortController,
|
|
1263
|
-
|
|
1384
|
+
{
|
|
1385
|
+
analysisMode: options?.analysisMode,
|
|
1386
|
+
attachments: streamAttachments
|
|
1387
|
+
}
|
|
1264
1388
|
);
|
|
1265
1389
|
const finalStreamUserId = streamUserIdRef.current ?? userId;
|
|
1266
1390
|
if (finalStreamUserId) {
|
|
@@ -1398,19 +1522,6 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1398
1522
|
},
|
|
1399
1523
|
[setPromptStatus]
|
|
1400
1524
|
);
|
|
1401
|
-
const expireUserAction2 = react.useCallback(
|
|
1402
|
-
async (userActionId) => {
|
|
1403
|
-
setPromptStatus(userActionId, "expired");
|
|
1404
|
-
try {
|
|
1405
|
-
await expireUserAction(configRef.current, userActionId);
|
|
1406
|
-
} catch (error) {
|
|
1407
|
-
if (error instanceof UserActionStaleError) return;
|
|
1408
|
-
callbacksRef.current.onError?.(error);
|
|
1409
|
-
throw error;
|
|
1410
|
-
}
|
|
1411
|
-
},
|
|
1412
|
-
[setPromptStatus]
|
|
1413
|
-
);
|
|
1414
1525
|
const dismissNotification = react.useCallback((id) => {
|
|
1415
1526
|
setUserActionState((prev) => ({
|
|
1416
1527
|
...prev,
|
|
@@ -1451,6 +1562,18 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1451
1562
|
setMessages(config.initialMessages);
|
|
1452
1563
|
sessionIdRef.current = getSessionIdFromMessages(config.initialMessages) ?? config.initialSessionId;
|
|
1453
1564
|
}, [config.initialMessages, config.initialSessionId, config.userId]);
|
|
1565
|
+
const hydratedSessionIdRef = react.useRef(void 0);
|
|
1566
|
+
react.useEffect(() => {
|
|
1567
|
+
if (config.userId) return;
|
|
1568
|
+
if (!config.initialMessages?.length) return;
|
|
1569
|
+
const sessionId = config.initialSessionId;
|
|
1570
|
+
if (hydratedSessionIdRef.current === sessionId && messagesRef.current.length > 0) {
|
|
1571
|
+
return;
|
|
1572
|
+
}
|
|
1573
|
+
hydratedSessionIdRef.current = sessionId;
|
|
1574
|
+
setMessages(config.initialMessages);
|
|
1575
|
+
sessionIdRef.current = getSessionIdFromMessages(config.initialMessages) ?? sessionId;
|
|
1576
|
+
}, [config.initialMessages, config.initialSessionId, config.userId]);
|
|
1454
1577
|
react.useEffect(() => {
|
|
1455
1578
|
const prevUserId = prevUserIdRef.current;
|
|
1456
1579
|
prevUserIdRef.current = config.userId;
|
|
@@ -1485,12 +1608,12 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1485
1608
|
getSessionId,
|
|
1486
1609
|
getMessages,
|
|
1487
1610
|
isWaitingForResponse,
|
|
1611
|
+
isUploadingAttachments,
|
|
1488
1612
|
sessionId: sessionIdRef.current,
|
|
1489
1613
|
userActionState,
|
|
1490
1614
|
submitUserAction: submitUserAction2,
|
|
1491
1615
|
cancelUserAction: cancelUserAction2,
|
|
1492
1616
|
resendUserAction: resendUserAction2,
|
|
1493
|
-
expireUserAction: expireUserAction2,
|
|
1494
1617
|
dismissNotification
|
|
1495
1618
|
};
|
|
1496
1619
|
}
|
|
@@ -2295,7 +2418,7 @@ function createMarkdownComponents(options = {}) {
|
|
|
2295
2418
|
},
|
|
2296
2419
|
pre: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "my-2 max-w-full overflow-x-auto rounded-lg", children }),
|
|
2297
2420
|
ul: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "mb-3 ml-4 list-disc space-y-1 text-sm", children }),
|
|
2298
|
-
ol: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("ol", { className: "mb-3 ml-4 list-decimal space-y-1 text-sm", children }),
|
|
2421
|
+
ol: ({ children, start }) => /* @__PURE__ */ jsxRuntime.jsx("ol", { className: "mb-3 ml-4 list-decimal space-y-1 text-sm", start, children }),
|
|
2299
2422
|
li: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("li", { className: "text-sm leading-relaxed", children }),
|
|
2300
2423
|
h1: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "mt-4 mb-2 text-lg font-semibold first:mt-0", children }),
|
|
2301
2424
|
h2: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "mt-3 mb-2 text-base font-semibold first:mt-0", children }),
|
|
@@ -2364,7 +2487,7 @@ function AgentMessage({
|
|
|
2364
2487
|
}
|
|
2365
2488
|
wasStreamingRef.current = isStreaming;
|
|
2366
2489
|
}, [isStreaming, hasSteps]);
|
|
2367
|
-
const totalElapsedMs = hasSteps ? message.steps.reduce((sum,
|
|
2490
|
+
const totalElapsedMs = hasSteps ? message.steps.reduce((sum, step2) => sum + (step2.elapsedMs || 0), 0) : 0;
|
|
2368
2491
|
const currentMessage = message.currentMessage;
|
|
2369
2492
|
const rawContent = message.streamingContent || message.content || "";
|
|
2370
2493
|
const content = rawContent.replace(/\\n/g, "\n");
|
|
@@ -2392,25 +2515,25 @@ function AgentMessage({
|
|
|
2392
2515
|
}
|
|
2393
2516
|
return `${count} ${stepWord} completed`;
|
|
2394
2517
|
};
|
|
2395
|
-
const renderStepIcon = (
|
|
2518
|
+
const renderStepIcon = (step2, isCurrentlyExecuting) => {
|
|
2396
2519
|
const wrapper = "h-4 w-4 flex items-center justify-center shrink-0";
|
|
2397
2520
|
if (isCurrentlyExecuting)
|
|
2398
2521
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: wrapper, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "h-3.5 w-3.5 payman-agent-step-icon--active animate-spin" }) });
|
|
2399
|
-
if (
|
|
2522
|
+
if (step2.status === "pending" && isCancelled)
|
|
2400
2523
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: wrapper, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-1.5 w-1.5 rounded-full payman-agent-step-icon--pending" }) });
|
|
2401
|
-
if (
|
|
2524
|
+
if (step2.status === "pending" || step2.status === "in_progress")
|
|
2402
2525
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: wrapper, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "h-3.5 w-3.5 payman-agent-step-icon--in-progress-dim animate-spin" }) });
|
|
2403
|
-
if (
|
|
2526
|
+
if (step2.status === "completed")
|
|
2404
2527
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: wrapper, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2405
2528
|
lucideReact.Check,
|
|
2406
2529
|
{
|
|
2407
2530
|
className: cn(
|
|
2408
2531
|
"h-3.5 w-3.5",
|
|
2409
|
-
|
|
2532
|
+
step2.eventType === "USER_ACTION_SUCCESS" ? "payman-agent-step-icon--success" : "payman-agent-step-icon--success-dim"
|
|
2410
2533
|
)
|
|
2411
2534
|
}
|
|
2412
2535
|
) });
|
|
2413
|
-
if (
|
|
2536
|
+
if (step2.status === "error")
|
|
2414
2537
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: wrapper, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-3.5 w-3.5 payman-agent-step-icon--error" }) });
|
|
2415
2538
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: wrapper, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-1.5 w-1.5 rounded-full payman-agent-step-icon--pending-dim" }) });
|
|
2416
2539
|
};
|
|
@@ -2422,33 +2545,33 @@ function AgentMessage({
|
|
|
2422
2545
|
exit: { height: 0, opacity: 0 },
|
|
2423
2546
|
transition: { duration: 0.2, ease: "easeInOut" },
|
|
2424
2547
|
className: "overflow-hidden",
|
|
2425
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pt-1.5", children: message.steps.map((
|
|
2426
|
-
const isCurrentlyExecuting =
|
|
2427
|
-
const hasTime =
|
|
2548
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pt-1.5", children: message.steps.map((step2) => {
|
|
2549
|
+
const isCurrentlyExecuting = step2.id === currentExecutingStepId && step2.status === "in_progress" && isStreaming && !isCancelled;
|
|
2550
|
+
const hasTime = step2.elapsedMs != null && step2.elapsedMs > 0;
|
|
2428
2551
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-1.5", children: [
|
|
2429
2552
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-1.5 items-start", children: [
|
|
2430
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-px", children: renderStepIcon(
|
|
2553
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-px", children: renderStepIcon(step2, isCurrentlyExecuting) }),
|
|
2431
2554
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2432
2555
|
"span",
|
|
2433
2556
|
{
|
|
2434
2557
|
className: cn(
|
|
2435
2558
|
"text-xs leading-relaxed min-w-0 break-words",
|
|
2436
2559
|
isCurrentlyExecuting && "shimmer-text font-medium",
|
|
2437
|
-
!isCurrentlyExecuting &&
|
|
2438
|
-
!isCurrentlyExecuting &&
|
|
2439
|
-
!isCurrentlyExecuting &&
|
|
2440
|
-
!isCurrentlyExecuting &&
|
|
2441
|
-
!isCurrentlyExecuting &&
|
|
2560
|
+
!isCurrentlyExecuting && step2.status === "error" && "payman-agent-step-text--error",
|
|
2561
|
+
!isCurrentlyExecuting && step2.eventType === "USER_ACTION_SUCCESS" && "payman-agent-step-text--success",
|
|
2562
|
+
!isCurrentlyExecuting && step2.status === "completed" && "payman-agent-step-text--completed",
|
|
2563
|
+
!isCurrentlyExecuting && step2.status === "pending" && "payman-agent-step-text--pending",
|
|
2564
|
+
!isCurrentlyExecuting && step2.status === "in_progress" && "payman-agent-step-text--in-progress"
|
|
2442
2565
|
),
|
|
2443
|
-
children:
|
|
2566
|
+
children: step2.message
|
|
2444
2567
|
}
|
|
2445
2568
|
)
|
|
2446
2569
|
] }),
|
|
2447
2570
|
hasTime && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pl-[22px] mt-1", children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1 px-1.5 py-0.5 rounded-md payman-agent-step-time leading-none", children: [
|
|
2448
2571
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Clock, { className: "h-2.5 w-2.5 shrink-0 payman-agent-step-time-icon" }),
|
|
2449
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-mono payman-agent-step-time-text", children: formatElapsedTime(
|
|
2572
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-mono payman-agent-step-time-text", children: formatElapsedTime(step2.elapsedMs) })
|
|
2450
2573
|
] }) })
|
|
2451
|
-
] },
|
|
2574
|
+
] }, step2.id);
|
|
2452
2575
|
}) })
|
|
2453
2576
|
}
|
|
2454
2577
|
) });
|
|
@@ -3411,7 +3534,7 @@ function buildComponents(onImageClick, isResolvingRef) {
|
|
|
3411
3534
|
code: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("code", { children }),
|
|
3412
3535
|
pre: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "payman-v2-markdown-pre", children: /* @__PURE__ */ jsxRuntime.jsx("pre", { children }) }),
|
|
3413
3536
|
ul: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("ul", { children }),
|
|
3414
|
-
ol: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("ol", { children }),
|
|
3537
|
+
ol: ({ children, start }) => /* @__PURE__ */ jsxRuntime.jsx("ol", { start, children }),
|
|
3415
3538
|
li: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("li", { children }),
|
|
3416
3539
|
h1: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("h1", { children }),
|
|
3417
3540
|
h2: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("h2", { children }),
|
|
@@ -3712,6 +3835,87 @@ function FeedbackReasonModal({
|
|
|
3712
3835
|
}
|
|
3713
3836
|
) : null });
|
|
3714
3837
|
}
|
|
3838
|
+
|
|
3839
|
+
// src/utils/markdownImageToken.ts
|
|
3840
|
+
function step(text, i) {
|
|
3841
|
+
if (text[i] === "\\" && i + 1 < text.length) return i + 2;
|
|
3842
|
+
return i + 1;
|
|
3843
|
+
}
|
|
3844
|
+
function scanAltText(text, start) {
|
|
3845
|
+
let i = start;
|
|
3846
|
+
while (i < text.length) {
|
|
3847
|
+
if (text[i] === "]") return i;
|
|
3848
|
+
i = step(text, i);
|
|
3849
|
+
}
|
|
3850
|
+
return -1;
|
|
3851
|
+
}
|
|
3852
|
+
function scanOptionalTitle(text, start) {
|
|
3853
|
+
let i = start;
|
|
3854
|
+
while (i < text.length && /[\t\n ]/.test(text[i])) i++;
|
|
3855
|
+
if (i >= text.length) return i;
|
|
3856
|
+
const quote = text[i];
|
|
3857
|
+
if (quote !== '"' && quote !== "'") return i;
|
|
3858
|
+
i++;
|
|
3859
|
+
while (i < text.length) {
|
|
3860
|
+
if (text[i] === quote) return i + 1;
|
|
3861
|
+
i = step(text, i);
|
|
3862
|
+
}
|
|
3863
|
+
return -1;
|
|
3864
|
+
}
|
|
3865
|
+
function scanAngleBracketDestination(text, start) {
|
|
3866
|
+
let i = start + 1;
|
|
3867
|
+
while (i < text.length) {
|
|
3868
|
+
if (text[i] === ">") return i + 1;
|
|
3869
|
+
i = step(text, i);
|
|
3870
|
+
}
|
|
3871
|
+
return -1;
|
|
3872
|
+
}
|
|
3873
|
+
function scanRawDestination(text, start) {
|
|
3874
|
+
let i = start;
|
|
3875
|
+
let depth = 1;
|
|
3876
|
+
while (i < text.length) {
|
|
3877
|
+
const char = text[i];
|
|
3878
|
+
if (char === "\\") {
|
|
3879
|
+
if (i + 1 >= text.length) return -1;
|
|
3880
|
+
i += 2;
|
|
3881
|
+
continue;
|
|
3882
|
+
}
|
|
3883
|
+
if (char === "(") depth++;
|
|
3884
|
+
else if (char === ")") {
|
|
3885
|
+
depth--;
|
|
3886
|
+
if (depth === 0) return i + 1;
|
|
3887
|
+
}
|
|
3888
|
+
i++;
|
|
3889
|
+
}
|
|
3890
|
+
return -1;
|
|
3891
|
+
}
|
|
3892
|
+
function completeMarkdownImageTokenLength(text) {
|
|
3893
|
+
if (!text.startsWith("![")) return 0;
|
|
3894
|
+
const altEnd = scanAltText(text, 2);
|
|
3895
|
+
if (altEnd === -1 || altEnd + 1 >= text.length || text[altEnd + 1] !== "(") {
|
|
3896
|
+
return 0;
|
|
3897
|
+
}
|
|
3898
|
+
let i = altEnd + 2;
|
|
3899
|
+
if (i >= text.length) return 0;
|
|
3900
|
+
if (text[i] === "<") {
|
|
3901
|
+
i = scanAngleBracketDestination(text, i);
|
|
3902
|
+
if (i === -1) return 0;
|
|
3903
|
+
i = scanOptionalTitle(text, i);
|
|
3904
|
+
if (i === -1 || i >= text.length || text[i] !== ")") return 0;
|
|
3905
|
+
return i + 1;
|
|
3906
|
+
}
|
|
3907
|
+
i = scanRawDestination(text, i);
|
|
3908
|
+
return i === -1 ? 0 : i;
|
|
3909
|
+
}
|
|
3910
|
+
function stripIncompleteImageToken(text) {
|
|
3911
|
+
const lastBang = text.lastIndexOf("![");
|
|
3912
|
+
if (lastBang === -1) return text;
|
|
3913
|
+
const suffix = text.slice(lastBang);
|
|
3914
|
+
if (completeMarkdownImageTokenLength(suffix) > 0) return text;
|
|
3915
|
+
return text.slice(0, lastBang);
|
|
3916
|
+
}
|
|
3917
|
+
|
|
3918
|
+
// src/components/v2/useTypingEffect.ts
|
|
3715
3919
|
var RESPONSE_SPEED = {
|
|
3716
3920
|
normal: [2, 4],
|
|
3717
3921
|
fast: 1,
|
|
@@ -3719,7 +3923,6 @@ var RESPONSE_SPEED = {
|
|
|
3719
3923
|
newline: [4, 6],
|
|
3720
3924
|
idle: 15
|
|
3721
3925
|
};
|
|
3722
|
-
var MARKDOWN_IMAGE_REGEX = /^!\[[^\]]*\]\([^)]*\)/;
|
|
3723
3926
|
function charDelay(char, speed, multiplier) {
|
|
3724
3927
|
const raw = (() => {
|
|
3725
3928
|
if (char === "*") return speed.fast;
|
|
@@ -3778,9 +3981,9 @@ function useTypingEffect(targetText, enabled, speed = RESPONSE_SPEED, initialDis
|
|
|
3778
3981
|
}
|
|
3779
3982
|
if (displayedRef.current.length < targetRef.current.length) {
|
|
3780
3983
|
const remaining = targetRef.current.slice(displayedRef.current.length);
|
|
3781
|
-
const
|
|
3782
|
-
if (
|
|
3783
|
-
displayedRef.current +=
|
|
3984
|
+
const imageTokenLength = completeMarkdownImageTokenLength(remaining);
|
|
3985
|
+
if (imageTokenLength > 0) {
|
|
3986
|
+
displayedRef.current += remaining.slice(0, imageTokenLength);
|
|
3784
3987
|
setDisplayedText(displayedRef.current);
|
|
3785
3988
|
timerRef.current = setTimeout(tick, 0);
|
|
3786
3989
|
return;
|
|
@@ -3809,13 +4012,6 @@ function useTypingEffect(targetText, enabled, speed = RESPONSE_SPEED, initialDis
|
|
|
3809
4012
|
isTyping
|
|
3810
4013
|
};
|
|
3811
4014
|
}
|
|
3812
|
-
function stripIncompleteImageToken(text) {
|
|
3813
|
-
const lastBang = text.lastIndexOf("![");
|
|
3814
|
-
if (lastBang === -1) return text;
|
|
3815
|
-
const after = text.slice(lastBang);
|
|
3816
|
-
if (/^!\[[^\]]*\]\([^)]*\)/.test(after)) return text;
|
|
3817
|
-
return text.slice(0, lastBang);
|
|
3818
|
-
}
|
|
3819
4015
|
function getFeedbackState(message) {
|
|
3820
4016
|
const feedback = message.feedback;
|
|
3821
4017
|
if (feedback === "up" || feedback === "down") return feedback;
|
|
@@ -5699,9 +5895,9 @@ var PRE_PIPELINE_STEPS = /* @__PURE__ */ new Set([
|
|
|
5699
5895
|
"build_pipeline",
|
|
5700
5896
|
"load_skill_index"
|
|
5701
5897
|
]);
|
|
5702
|
-
function stepColor(
|
|
5703
|
-
if (
|
|
5704
|
-
if (PRE_PIPELINE_STEPS.has(
|
|
5898
|
+
function stepColor(step2) {
|
|
5899
|
+
if (step2.status === "failed") return "#ef4444";
|
|
5900
|
+
if (PRE_PIPELINE_STEPS.has(step2.step)) return "#f59e0b";
|
|
5705
5901
|
return "#3b82f6";
|
|
5706
5902
|
}
|
|
5707
5903
|
function formatMs(ms) {
|
|
@@ -5878,10 +6074,10 @@ function TimelineBars({
|
|
|
5878
6074
|
totalMs,
|
|
5879
6075
|
unaccountedMs
|
|
5880
6076
|
}) {
|
|
5881
|
-
const bars = trace.pipelineSteps.map((
|
|
5882
|
-
const duration =
|
|
6077
|
+
const bars = trace.pipelineSteps.map((step2) => {
|
|
6078
|
+
const duration = step2.durationMs ?? 0;
|
|
5883
6079
|
const widthPct = totalMs > 0 ? duration / totalMs * 100 : 0;
|
|
5884
|
-
const llmMs =
|
|
6080
|
+
const llmMs = step2.llmCall?.durationMs ?? null;
|
|
5885
6081
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginBottom: 8 }, children: [
|
|
5886
6082
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5887
6083
|
"div",
|
|
@@ -5895,8 +6091,8 @@ function TimelineBars({
|
|
|
5895
6091
|
},
|
|
5896
6092
|
children: [
|
|
5897
6093
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
5898
|
-
|
|
5899
|
-
|
|
6094
|
+
step2.step,
|
|
6095
|
+
step2.status === "failed" && /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "#fca5a5", marginLeft: 6 }, children: "(failed)" })
|
|
5900
6096
|
] }),
|
|
5901
6097
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { style: { opacity: 0.75 }, children: [
|
|
5902
6098
|
formatMs(duration),
|
|
@@ -5924,14 +6120,14 @@ function TimelineBars({
|
|
|
5924
6120
|
style: {
|
|
5925
6121
|
height: "100%",
|
|
5926
6122
|
width: `${Math.max(widthPct, 0.3)}%`,
|
|
5927
|
-
background: stepColor(
|
|
6123
|
+
background: stepColor(step2),
|
|
5928
6124
|
transition: "width 0.2s ease"
|
|
5929
6125
|
}
|
|
5930
6126
|
}
|
|
5931
6127
|
)
|
|
5932
6128
|
}
|
|
5933
6129
|
)
|
|
5934
|
-
] }, `${
|
|
6130
|
+
] }, `${step2.step}-${step2.startTime}`);
|
|
5935
6131
|
});
|
|
5936
6132
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
5937
6133
|
bars,
|
|
@@ -6150,7 +6346,7 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
|
|
|
6150
6346
|
const submitUserAction2 = chat.submitUserAction ?? NOOP_ASYNC;
|
|
6151
6347
|
const cancelUserAction2 = chat.cancelUserAction ?? NOOP_ASYNC;
|
|
6152
6348
|
const resendUserAction2 = chat.resendUserAction ?? NOOP_ASYNC;
|
|
6153
|
-
const
|
|
6349
|
+
const expireUserAction = chat.expireUserAction ?? NOOP_ASYNC;
|
|
6154
6350
|
const dismissNotification = chat.dismissNotification ?? NOOP;
|
|
6155
6351
|
const isUserActionSupported = typeof chat.submitUserAction === "function" && typeof chat.cancelUserAction === "function" && typeof chat.resendUserAction === "function";
|
|
6156
6352
|
const {
|
|
@@ -6551,7 +6747,7 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
|
|
|
6551
6747
|
onSubmitUserAction: isUserActionSupported ? submitUserAction2 : void 0,
|
|
6552
6748
|
onCancelUserAction: isUserActionSupported ? cancelUserAction2 : void 0,
|
|
6553
6749
|
onResendUserAction: isUserActionSupported ? resendUserAction2 : void 0,
|
|
6554
|
-
onExpireUserAction: isUserActionSupported ?
|
|
6750
|
+
onExpireUserAction: isUserActionSupported ? expireUserAction : void 0,
|
|
6555
6751
|
onDismissNotification: dismissNotification,
|
|
6556
6752
|
onSubmitFeedback: handleSubmitFeedback
|
|
6557
6753
|
}
|