@paymanai/payman-ask-sdk 4.0.23 → 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 CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var React = require('react');
3
+ var react = require('react');
4
4
  var framerMotion = require('framer-motion');
5
5
  var clsx = require('clsx');
6
6
  var tailwindMerge = require('tailwind-merge');
@@ -33,7 +33,6 @@ function _interopNamespace(e) {
33
33
  return Object.freeze(n);
34
34
  }
35
35
 
36
- var React__namespace = /*#__PURE__*/_interopNamespace(React);
37
36
  var Sentry__namespace = /*#__PURE__*/_interopNamespace(Sentry);
38
37
  var ReactMarkdown__default = /*#__PURE__*/_interopDefault(ReactMarkdown);
39
38
  var remarkGfm__default = /*#__PURE__*/_interopDefault(remarkGfm);
@@ -523,9 +522,9 @@ function processStreamEventV2(rawEvent, state) {
523
522
  state.hasError = true;
524
523
  state.errorMessage = "WORKFLOW_FAILED";
525
524
  }
526
- state.steps.forEach((step) => {
527
- if (step.status === "in_progress") {
528
- step.status = "completed";
525
+ state.steps.forEach((step2) => {
526
+ if (step2.status === "in_progress") {
527
+ step2.status = "completed";
529
528
  }
530
529
  });
531
530
  state.lastEventType = eventType;
@@ -737,7 +736,8 @@ function buildRequestBody(config, userMessage, sessionId, options) {
737
736
  sessionAttributes,
738
737
  analysisMode: options?.analysisMode,
739
738
  locale: resolveLocale(config.locale),
740
- timezone: resolveTimezone(config.timezone)
739
+ timezone: resolveTimezone(config.timezone),
740
+ ...options?.attachments?.length ? { attachments: options.attachments } : {}
741
741
  };
742
742
  }
743
743
  function resolveLocale(configured) {
@@ -782,6 +782,7 @@ function buildResolveImagesUrl(config) {
782
782
  const basePath = normalizedEndpointPath.endsWith("/stream") ? normalizedEndpointPath.slice(0, -"/stream".length) : normalizedEndpointPath;
783
783
  return `${config.api.baseUrl}${basePath}/resolve-image-urls`;
784
784
  }
785
+ var NGROK_SKIP_BROWSER_WARNING = "ngrok-skip-browser-warning";
785
786
  function buildRequestHeaders(config) {
786
787
  const headers = {
787
788
  ...config.api.headers
@@ -789,6 +790,9 @@ function buildRequestHeaders(config) {
789
790
  if (config.api.authToken) {
790
791
  headers.Authorization = `Bearer ${config.api.authToken}`;
791
792
  }
793
+ if (!headers[NGROK_SKIP_BROWSER_WARNING]) {
794
+ headers[NGROK_SKIP_BROWSER_WARNING] = "true";
795
+ }
792
796
  return headers;
793
797
  }
794
798
  var RAG_IMAGE_REGEX = /\/api\/rag\/chunks\/[^"'\s]+\/image/;
@@ -841,12 +845,12 @@ async function resolveRagImageUrls(config, content, signal) {
841
845
  }
842
846
  var FRIENDLY_ERROR_MESSAGE = "Oops, something went wrong. Please try again.";
843
847
  function useStreamManagerV2(config, callbacks, setMessages, setIsWaitingForResponse) {
844
- const abortControllerRef = React.useRef(null);
845
- const configRef = React.useRef(config);
848
+ const abortControllerRef = react.useRef(null);
849
+ const configRef = react.useRef(config);
846
850
  configRef.current = config;
847
- const callbacksRef = React.useRef(callbacks);
851
+ const callbacksRef = react.useRef(callbacks);
848
852
  callbacksRef.current = callbacks;
849
- const startStream = React.useCallback(
853
+ const startStream = react.useCallback(
850
854
  async (userMessage, streamingId, sessionId, externalAbortController, options) => {
851
855
  abortControllerRef.current?.abort();
852
856
  const abortController = externalAbortController ?? new AbortController();
@@ -940,11 +944,11 @@ function useStreamManagerV2(config, callbacks, setMessages, setIsWaitingForRespo
940
944
  errorDetails: isAborted ? void 0 : error.message,
941
945
  content: isAborted ? state.finalResponse || "" : state.finalResponse || FRIENDLY_ERROR_MESSAGE,
942
946
  currentMessage: isAborted ? "Thinking..." : void 0,
943
- steps: [...state.steps].map((step) => {
944
- if (step.status === "in_progress" && isAborted) {
945
- return { ...step, status: "pending" };
947
+ steps: [...state.steps].map((step2) => {
948
+ if (step2.status === "in_progress" && isAborted) {
949
+ return { ...step2, status: "pending" };
946
950
  }
947
- return step;
951
+ return step2;
948
952
  }),
949
953
  currentExecutingStepId: void 0
950
954
  } : msg
@@ -1030,11 +1034,11 @@ function useStreamManagerV2(config, callbacks, setMessages, setIsWaitingForRespo
1030
1034
  isCancelled: isAborted,
1031
1035
  errorDetails: isAborted ? void 0 : error.message,
1032
1036
  content: isAborted ? state.finalResponse || "" : state.finalResponse || FRIENDLY_ERROR_MESSAGE,
1033
- steps: [...state.steps].map((step) => {
1034
- if (step.status === "in_progress" && isAborted) {
1035
- return { ...step, status: "pending" };
1037
+ steps: [...state.steps].map((step2) => {
1038
+ if (step2.status === "in_progress" && isAborted) {
1039
+ return { ...step2, status: "pending" };
1036
1040
  }
1037
- return step;
1041
+ return step2;
1038
1042
  }),
1039
1043
  currentExecutingStepId: void 0
1040
1044
  } : msg
@@ -1045,7 +1049,7 @@ function useStreamManagerV2(config, callbacks, setMessages, setIsWaitingForRespo
1045
1049
  },
1046
1050
  [setMessages, setIsWaitingForResponse]
1047
1051
  );
1048
- const cancelStream = React.useCallback(() => {
1052
+ const cancelStream = react.useCallback(() => {
1049
1053
  abortControllerRef.current?.abort();
1050
1054
  }, []);
1051
1055
  return {
@@ -1055,11 +1059,11 @@ function useStreamManagerV2(config, callbacks, setMessages, setIsWaitingForRespo
1055
1059
  };
1056
1060
  }
1057
1061
  function createCancelledMessageUpdate(steps, currentMessage) {
1058
- const updatedSteps = steps.map((step) => {
1059
- if (step.status === "in_progress") {
1060
- return { ...step, status: "pending" };
1062
+ const updatedSteps = steps.map((step2) => {
1063
+ if (step2.status === "in_progress") {
1064
+ return { ...step2, status: "pending" };
1061
1065
  }
1062
- return step;
1066
+ return step2;
1063
1067
  });
1064
1068
  return {
1065
1069
  isStreaming: false,
@@ -1069,6 +1073,81 @@ function createCancelledMessageUpdate(steps, currentMessage) {
1069
1073
  currentMessage: currentMessage || "Thinking..."
1070
1074
  };
1071
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
+ }
1072
1151
  var UserActionStaleError = class extends Error {
1073
1152
  constructor(userActionId, message = "User action is no longer actionable") {
1074
1153
  super(message);
@@ -1105,9 +1184,6 @@ async function cancelUserAction(config, userActionId) {
1105
1184
  async function resendUserAction(config, userActionId) {
1106
1185
  return sendUserActionRequest(config, userActionId, "resend");
1107
1186
  }
1108
- async function expireUserAction(config, userActionId) {
1109
- return sendUserActionRequest(config, userActionId, "expired");
1110
- }
1111
1187
  var EMPTY_USER_ACTION_STATE = { prompts: [], notifications: [] };
1112
1188
  function upsertPrompt(prompts, req) {
1113
1189
  const active = { ...req, status: "pending" };
@@ -1136,25 +1212,45 @@ function getStoredOrInitialMessages(config) {
1136
1212
  function getSessionIdFromMessages(messages) {
1137
1213
  return messages.find((message) => message.sessionId)?.sessionId;
1138
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
+ }
1139
1234
  function useChatV2(config, callbacks = {}) {
1140
- const [messages, setMessages] = React.useState(() => getStoredOrInitialMessages(config));
1141
- const [isWaitingForResponse, setIsWaitingForResponse] = React.useState(() => {
1235
+ const [messages, setMessages] = react.useState(() => getStoredOrInitialMessages(config));
1236
+ const [isWaitingForResponse, setIsWaitingForResponse] = react.useState(() => {
1142
1237
  if (!config.userId) return false;
1143
1238
  return activeStreamStore.get(config.userId)?.isWaiting ?? false;
1144
1239
  });
1145
- const sessionIdRef = React.useRef(
1240
+ const [isUploadingAttachments, setIsUploadingAttachments] = react.useState(false);
1241
+ const sessionIdRef = react.useRef(
1146
1242
  getSessionIdFromMessages(getStoredOrInitialMessages(config)) ?? config.initialSessionId ?? void 0
1147
1243
  );
1148
- const prevUserIdRef = React.useRef(config.userId);
1149
- const streamUserIdRef = React.useRef(void 0);
1150
- const subscriptionPrevUserIdRef = React.useRef(config.userId);
1151
- const callbacksRef = React.useRef(callbacks);
1244
+ const prevUserIdRef = react.useRef(config.userId);
1245
+ const streamUserIdRef = react.useRef(void 0);
1246
+ const subscriptionPrevUserIdRef = react.useRef(config.userId);
1247
+ const callbacksRef = react.useRef(callbacks);
1152
1248
  callbacksRef.current = callbacks;
1153
- const configRef = React.useRef(config);
1249
+ const configRef = react.useRef(config);
1154
1250
  configRef.current = config;
1155
- const messagesRef = React.useRef(messages);
1251
+ const messagesRef = react.useRef(messages);
1156
1252
  messagesRef.current = messages;
1157
- const storeAwareSetMessages = React.useCallback(
1253
+ const storeAwareSetMessages = react.useCallback(
1158
1254
  (updater) => {
1159
1255
  const streamUserId = streamUserIdRef.current;
1160
1256
  const currentUserId = configRef.current.userId;
@@ -1169,7 +1265,7 @@ function useChatV2(config, callbacks = {}) {
1169
1265
  // eslint-disable-next-line react-hooks/exhaustive-deps
1170
1266
  []
1171
1267
  );
1172
- const storeAwareSetIsWaiting = React.useCallback(
1268
+ const storeAwareSetIsWaiting = react.useCallback(
1173
1269
  (waiting) => {
1174
1270
  const streamUserId = streamUserIdRef.current;
1175
1271
  const currentUserId = configRef.current.userId;
@@ -1184,8 +1280,8 @@ function useChatV2(config, callbacks = {}) {
1184
1280
  // eslint-disable-next-line react-hooks/exhaustive-deps
1185
1281
  []
1186
1282
  );
1187
- const [userActionState, setUserActionState] = React.useState(EMPTY_USER_ACTION_STATE);
1188
- const wrappedCallbacks = React.useMemo(() => ({
1283
+ const [userActionState, setUserActionState] = react.useState(EMPTY_USER_ACTION_STATE);
1284
+ const wrappedCallbacks = react.useMemo(() => ({
1189
1285
  ...callbacksRef.current,
1190
1286
  onMessageSent: (message) => callbacksRef.current.onMessageSent?.(message),
1191
1287
  onStreamStart: () => callbacksRef.current.onStreamStart?.(),
@@ -1214,23 +1310,47 @@ function useChatV2(config, callbacks = {}) {
1214
1310
  storeAwareSetMessages,
1215
1311
  storeAwareSetIsWaiting
1216
1312
  );
1217
- const sendMessage = React.useCallback(
1313
+ const sendMessage = react.useCallback(
1218
1314
  async (userMessage, options) => {
1219
- if (!userMessage.trim()) return;
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
+ }
1220
1333
  if (!sessionIdRef.current && configRef.current.autoGenerateSessionId !== false) {
1221
1334
  sessionIdRef.current = generateId();
1222
1335
  callbacksRef.current.onSessionIdChange?.(sessionIdRef.current);
1223
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;
1224
1343
  const userMessageId = `user-${Date.now()}`;
1225
1344
  const userMsg = {
1226
1345
  id: userMessageId,
1227
1346
  sessionId: sessionIdRef.current,
1228
1347
  role: "user",
1229
- content: userMessage,
1230
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
1348
+ content: trimmedMessage,
1349
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
1350
+ attachments: messageAttachments
1231
1351
  };
1232
1352
  setMessages((prev) => [...prev, userMsg]);
1233
- callbacksRef.current.onMessageSent?.(userMessage);
1353
+ callbacksRef.current.onMessageSent?.(trimmedMessage);
1234
1354
  setIsWaitingForResponse(true);
1235
1355
  callbacksRef.current.onStreamStart?.();
1236
1356
  const streamingId = `assistant-${Date.now()}`;
@@ -1257,11 +1377,14 @@ function useChatV2(config, callbacks = {}) {
1257
1377
  activeStreamStore.start(userId, abortController, initialMessages);
1258
1378
  }
1259
1379
  const newSessionId = await startStream(
1260
- userMessage,
1380
+ trimmedMessage,
1261
1381
  streamingId,
1262
1382
  sessionIdRef.current,
1263
1383
  abortController,
1264
- options
1384
+ {
1385
+ analysisMode: options?.analysisMode,
1386
+ attachments: streamAttachments
1387
+ }
1265
1388
  );
1266
1389
  const finalStreamUserId = streamUserIdRef.current ?? userId;
1267
1390
  if (finalStreamUserId) {
@@ -1274,16 +1397,16 @@ function useChatV2(config, callbacks = {}) {
1274
1397
  },
1275
1398
  [startStream]
1276
1399
  );
1277
- const clearMessages = React.useCallback(() => {
1400
+ const clearMessages = react.useCallback(() => {
1278
1401
  if (configRef.current.userId) {
1279
1402
  chatStore.delete(configRef.current.userId);
1280
1403
  }
1281
1404
  setMessages([]);
1282
1405
  }, []);
1283
- const prependMessages = React.useCallback((msgs) => {
1406
+ const prependMessages = react.useCallback((msgs) => {
1284
1407
  setMessages((prev) => [...msgs, ...prev]);
1285
1408
  }, []);
1286
- const cancelStream = React.useCallback(() => {
1409
+ const cancelStream = react.useCallback(() => {
1287
1410
  const streamUserId = streamUserIdRef.current ?? configRef.current.userId;
1288
1411
  if (streamUserId) {
1289
1412
  activeStreamStore.abort(streamUserId);
@@ -1307,7 +1430,7 @@ function useChatV2(config, callbacks = {}) {
1307
1430
  })
1308
1431
  );
1309
1432
  }, [cancelStreamManager]);
1310
- const resetSession = React.useCallback(() => {
1433
+ const resetSession = react.useCallback(() => {
1311
1434
  const streamUserId = streamUserIdRef.current ?? configRef.current.userId;
1312
1435
  if (streamUserId) {
1313
1436
  activeStreamStore.abort(streamUserId);
@@ -1322,13 +1445,13 @@ function useChatV2(config, callbacks = {}) {
1322
1445
  setIsWaitingForResponse(false);
1323
1446
  setUserActionState(EMPTY_USER_ACTION_STATE);
1324
1447
  }, []);
1325
- const getSessionId = React.useCallback(() => {
1448
+ const getSessionId = react.useCallback(() => {
1326
1449
  return sessionIdRef.current;
1327
1450
  }, []);
1328
- const getMessages = React.useCallback(() => {
1451
+ const getMessages = react.useCallback(() => {
1329
1452
  return messages;
1330
1453
  }, [messages]);
1331
- const setPromptStatus = React.useCallback(
1454
+ const setPromptStatus = react.useCallback(
1332
1455
  (userActionId, status) => {
1333
1456
  setUserActionState((prev) => ({
1334
1457
  ...prev,
@@ -1339,13 +1462,13 @@ function useChatV2(config, callbacks = {}) {
1339
1462
  },
1340
1463
  []
1341
1464
  );
1342
- const removePrompt = React.useCallback((userActionId) => {
1465
+ const removePrompt = react.useCallback((userActionId) => {
1343
1466
  setUserActionState((prev) => ({
1344
1467
  ...prev,
1345
1468
  prompts: prev.prompts.filter((p) => p.userActionId !== userActionId)
1346
1469
  }));
1347
1470
  }, []);
1348
- const submitUserAction2 = React.useCallback(
1471
+ const submitUserAction2 = react.useCallback(
1349
1472
  async (userActionId, content) => {
1350
1473
  setPromptStatus(userActionId, "submitting");
1351
1474
  try {
@@ -1363,7 +1486,7 @@ function useChatV2(config, callbacks = {}) {
1363
1486
  },
1364
1487
  [removePrompt, setPromptStatus]
1365
1488
  );
1366
- const cancelUserAction2 = React.useCallback(
1489
+ const cancelUserAction2 = react.useCallback(
1367
1490
  async (userActionId) => {
1368
1491
  setPromptStatus(userActionId, "submitting");
1369
1492
  try {
@@ -1381,7 +1504,7 @@ function useChatV2(config, callbacks = {}) {
1381
1504
  },
1382
1505
  [removePrompt, setPromptStatus]
1383
1506
  );
1384
- const resendUserAction2 = React.useCallback(
1507
+ const resendUserAction2 = react.useCallback(
1385
1508
  async (userActionId) => {
1386
1509
  setPromptStatus(userActionId, "submitting");
1387
1510
  try {
@@ -1399,26 +1522,13 @@ function useChatV2(config, callbacks = {}) {
1399
1522
  },
1400
1523
  [setPromptStatus]
1401
1524
  );
1402
- const expireUserAction2 = React.useCallback(
1403
- async (userActionId) => {
1404
- setPromptStatus(userActionId, "expired");
1405
- try {
1406
- await expireUserAction(configRef.current, userActionId);
1407
- } catch (error) {
1408
- if (error instanceof UserActionStaleError) return;
1409
- callbacksRef.current.onError?.(error);
1410
- throw error;
1411
- }
1412
- },
1413
- [setPromptStatus]
1414
- );
1415
- const dismissNotification = React.useCallback((id) => {
1525
+ const dismissNotification = react.useCallback((id) => {
1416
1526
  setUserActionState((prev) => ({
1417
1527
  ...prev,
1418
1528
  notifications: prev.notifications.filter((n) => n.id !== id)
1419
1529
  }));
1420
1530
  }, []);
1421
- React.useEffect(() => {
1531
+ react.useEffect(() => {
1422
1532
  const prevSubscriptionUserId = subscriptionPrevUserIdRef.current;
1423
1533
  subscriptionPrevUserIdRef.current = config.userId;
1424
1534
  const { userId } = config;
@@ -1437,7 +1547,7 @@ function useChatV2(config, callbacks = {}) {
1437
1547
  }
1438
1548
  return unsubscribe;
1439
1549
  }, [config.userId]);
1440
- React.useEffect(() => {
1550
+ react.useEffect(() => {
1441
1551
  if (!config.userId) return;
1442
1552
  if (prevUserIdRef.current !== config.userId) return;
1443
1553
  const toSave = messages.filter((m) => !m.isStreaming);
@@ -1445,14 +1555,26 @@ function useChatV2(config, callbacks = {}) {
1445
1555
  chatStore.set(config.userId, toSave);
1446
1556
  }
1447
1557
  }, [messages, config.userId]);
1448
- React.useEffect(() => {
1558
+ react.useEffect(() => {
1449
1559
  if (!config.userId || activeStreamStore.has(config.userId)) return;
1450
1560
  if (!config.initialMessages?.length || messagesRef.current.length > 0) return;
1451
1561
  chatStore.set(config.userId, config.initialMessages);
1452
1562
  setMessages(config.initialMessages);
1453
1563
  sessionIdRef.current = getSessionIdFromMessages(config.initialMessages) ?? config.initialSessionId;
1454
1564
  }, [config.initialMessages, config.initialSessionId, config.userId]);
1455
- React.useEffect(() => {
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]);
1577
+ react.useEffect(() => {
1456
1578
  const prevUserId = prevUserIdRef.current;
1457
1579
  prevUserIdRef.current = config.userId;
1458
1580
  if (prevUserId === config.userId) return;
@@ -1486,12 +1608,12 @@ function useChatV2(config, callbacks = {}) {
1486
1608
  getSessionId,
1487
1609
  getMessages,
1488
1610
  isWaitingForResponse,
1611
+ isUploadingAttachments,
1489
1612
  sessionId: sessionIdRef.current,
1490
1613
  userActionState,
1491
1614
  submitUserAction: submitUserAction2,
1492
1615
  cancelUserAction: cancelUserAction2,
1493
1616
  resendUserAction: resendUserAction2,
1494
- expireUserAction: expireUserAction2,
1495
1617
  dismissNotification
1496
1618
  };
1497
1619
  }
@@ -1500,12 +1622,12 @@ function getSpeechRecognition() {
1500
1622
  return window.SpeechRecognition || window.webkitSpeechRecognition || null;
1501
1623
  }
1502
1624
  function useVoice(config = {}, callbacks = {}) {
1503
- const [voiceState, setVoiceState] = React.useState("idle");
1504
- const [transcribedText, setTranscribedText] = React.useState("");
1505
- const [isAvailable, setIsAvailable] = React.useState(false);
1506
- const [isRecording, setIsRecording] = React.useState(false);
1507
- const recognitionRef = React.useRef(null);
1508
- const autoStopTimerRef = React.useRef(null);
1625
+ const [voiceState, setVoiceState] = react.useState("idle");
1626
+ const [transcribedText, setTranscribedText] = react.useState("");
1627
+ const [isAvailable, setIsAvailable] = react.useState(false);
1628
+ const [isRecording, setIsRecording] = react.useState(false);
1629
+ const recognitionRef = react.useRef(null);
1630
+ const autoStopTimerRef = react.useRef(null);
1509
1631
  const {
1510
1632
  lang = "en-US",
1511
1633
  interimResults = true,
@@ -1514,14 +1636,14 @@ function useVoice(config = {}, callbacks = {}) {
1514
1636
  autoStopAfterSilence
1515
1637
  } = config;
1516
1638
  const { onStart, onEnd, onResult, onError, onStateChange } = callbacks;
1517
- React.useEffect(() => {
1639
+ react.useEffect(() => {
1518
1640
  const SpeechRecognitionAPI = getSpeechRecognition();
1519
1641
  setIsAvailable(SpeechRecognitionAPI !== null);
1520
1642
  }, []);
1521
- React.useEffect(() => {
1643
+ react.useEffect(() => {
1522
1644
  onStateChange?.(voiceState);
1523
1645
  }, [voiceState, onStateChange]);
1524
- const requestPermissions = React.useCallback(async () => {
1646
+ const requestPermissions = react.useCallback(async () => {
1525
1647
  try {
1526
1648
  const result = await navigator.mediaDevices.getUserMedia({
1527
1649
  audio: true
@@ -1538,7 +1660,7 @@ function useVoice(config = {}, callbacks = {}) {
1538
1660
  };
1539
1661
  }
1540
1662
  }, []);
1541
- const getPermissions = React.useCallback(async () => {
1663
+ const getPermissions = react.useCallback(async () => {
1542
1664
  if (typeof navigator === "undefined" || !navigator.permissions) {
1543
1665
  return {
1544
1666
  granted: false,
@@ -1560,13 +1682,13 @@ function useVoice(config = {}, callbacks = {}) {
1560
1682
  };
1561
1683
  }
1562
1684
  }, []);
1563
- const clearAutoStopTimer = React.useCallback(() => {
1685
+ const clearAutoStopTimer = react.useCallback(() => {
1564
1686
  if (autoStopTimerRef.current) {
1565
1687
  clearTimeout(autoStopTimerRef.current);
1566
1688
  autoStopTimerRef.current = null;
1567
1689
  }
1568
1690
  }, []);
1569
- const resetAutoStopTimer = React.useCallback(() => {
1691
+ const resetAutoStopTimer = react.useCallback(() => {
1570
1692
  clearAutoStopTimer();
1571
1693
  if (autoStopAfterSilence && autoStopAfterSilence > 0) {
1572
1694
  autoStopTimerRef.current = setTimeout(() => {
@@ -1576,7 +1698,7 @@ function useVoice(config = {}, callbacks = {}) {
1576
1698
  }, autoStopAfterSilence);
1577
1699
  }
1578
1700
  }, [autoStopAfterSilence, clearAutoStopTimer, isRecording]);
1579
- const stopRecording = React.useCallback(() => {
1701
+ const stopRecording = react.useCallback(() => {
1580
1702
  if (recognitionRef.current) {
1581
1703
  try {
1582
1704
  recognitionRef.current.stop();
@@ -1588,7 +1710,7 @@ function useVoice(config = {}, callbacks = {}) {
1588
1710
  setIsRecording(false);
1589
1711
  setVoiceState("idle");
1590
1712
  }, [clearAutoStopTimer]);
1591
- const startRecording = React.useCallback(async () => {
1713
+ const startRecording = react.useCallback(async () => {
1592
1714
  const SpeechRecognitionAPI = getSpeechRecognition();
1593
1715
  if (!SpeechRecognitionAPI) {
1594
1716
  onError?.("Speech recognition not supported in this browser");
@@ -1678,15 +1800,15 @@ function useVoice(config = {}, callbacks = {}) {
1678
1800
  resetAutoStopTimer,
1679
1801
  clearAutoStopTimer
1680
1802
  ]);
1681
- const clearTranscript = React.useCallback(() => {
1803
+ const clearTranscript = react.useCallback(() => {
1682
1804
  setTranscribedText("");
1683
1805
  }, []);
1684
- const reset = React.useCallback(() => {
1806
+ const reset = react.useCallback(() => {
1685
1807
  stopRecording();
1686
1808
  setTranscribedText("");
1687
1809
  setVoiceState("idle");
1688
1810
  }, [stopRecording]);
1689
- React.useEffect(() => {
1811
+ react.useEffect(() => {
1690
1812
  return () => {
1691
1813
  if (recognitionRef.current) {
1692
1814
  try {
@@ -1826,9 +1948,9 @@ function buildContent(schema, values) {
1826
1948
  }
1827
1949
  return content;
1828
1950
  }
1829
- var PaymanChatContext = React.createContext(void 0);
1951
+ var PaymanChatContext = react.createContext(void 0);
1830
1952
  function usePaymanChat() {
1831
- const context = React.useContext(PaymanChatContext);
1953
+ const context = react.useContext(PaymanChatContext);
1832
1954
  if (!context) {
1833
1955
  throw new Error("usePaymanChat must be used within a PaymanChat component");
1834
1956
  }
@@ -2086,8 +2208,8 @@ function ImageLightbox({
2086
2208
  alt = "",
2087
2209
  onClose
2088
2210
  }) {
2089
- const [isMounted, setIsMounted] = React.useState(false);
2090
- const [isImageLoaded, setIsImageLoaded] = React.useState(false);
2211
+ const [isMounted, setIsMounted] = react.useState(false);
2212
+ const [isImageLoaded, setIsImageLoaded] = react.useState(false);
2091
2213
  const overlayStyle = {
2092
2214
  position: "fixed",
2093
2215
  inset: 0,
@@ -2108,14 +2230,14 @@ function ImageLightbox({
2108
2230
  justifyContent: "center",
2109
2231
  overflow: "hidden"
2110
2232
  };
2111
- React.useEffect(() => {
2233
+ react.useEffect(() => {
2112
2234
  setIsMounted(true);
2113
2235
  return () => setIsMounted(false);
2114
2236
  }, []);
2115
- React.useEffect(() => {
2237
+ react.useEffect(() => {
2116
2238
  setIsImageLoaded(false);
2117
2239
  }, [src]);
2118
- React.useEffect(() => {
2240
+ react.useEffect(() => {
2119
2241
  if (typeof document === "undefined") return;
2120
2242
  const previousOverflow = document.body.style.overflow;
2121
2243
  document.body.style.overflow = "hidden";
@@ -2123,7 +2245,7 @@ function ImageLightbox({
2123
2245
  document.body.style.overflow = previousOverflow;
2124
2246
  };
2125
2247
  }, []);
2126
- React.useEffect(() => {
2248
+ react.useEffect(() => {
2127
2249
  if (typeof document === "undefined") return;
2128
2250
  const handleKeyDown = (event) => {
2129
2251
  if (event.key === "Escape") {
@@ -2219,15 +2341,15 @@ function MarkdownImage({
2219
2341
  maxHeight: "18rem",
2220
2342
  objectFit: "contain"
2221
2343
  };
2222
- const [isLoaded, setIsLoaded] = React.useState(false);
2223
- const [hasError, setHasError] = React.useState(false);
2224
- const [isLightboxOpen, setIsLightboxOpen] = React.useState(false);
2225
- const isUnresolvedRagImage = React.useMemo(
2344
+ const [isLoaded, setIsLoaded] = react.useState(false);
2345
+ const [hasError, setHasError] = react.useState(false);
2346
+ const [isLightboxOpen, setIsLightboxOpen] = react.useState(false);
2347
+ const isUnresolvedRagImage = react.useMemo(
2226
2348
  () => src ? isUnresolvedRagImageSource(src) : false,
2227
2349
  [src]
2228
2350
  );
2229
2351
  const isResolvingRagImage = isResolving && isUnresolvedRagImage;
2230
- React.useEffect(() => {
2352
+ react.useEffect(() => {
2231
2353
  setIsLoaded(false);
2232
2354
  setHasError(false);
2233
2355
  setIsLightboxOpen(false);
@@ -2296,7 +2418,7 @@ function createMarkdownComponents(options = {}) {
2296
2418
  },
2297
2419
  pre: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "my-2 max-w-full overflow-x-auto rounded-lg", children }),
2298
2420
  ul: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "mb-3 ml-4 list-disc space-y-1 text-sm", children }),
2299
- 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 }),
2300
2422
  li: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("li", { className: "text-sm leading-relaxed", children }),
2301
2423
  h1: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "mt-4 mb-2 text-lg font-semibold first:mt-0", children }),
2302
2424
  h2: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "mt-3 mb-2 text-base font-semibold first:mt-0", children }),
@@ -2354,9 +2476,9 @@ function AgentMessage({
2354
2476
  const hasTraceData = !!(message.tracingData || message.executionId) && !isStreaming;
2355
2477
  const isCancelled = message.isCancelled ?? false;
2356
2478
  const currentExecutingStepId = message.currentExecutingStepId;
2357
- const [isStepsExpanded, setIsStepsExpanded] = React.useState(false);
2358
- const wasStreamingRef = React.useRef(isStreaming);
2359
- React.useEffect(() => {
2479
+ const [isStepsExpanded, setIsStepsExpanded] = react.useState(false);
2480
+ const wasStreamingRef = react.useRef(isStreaming);
2481
+ react.useEffect(() => {
2360
2482
  if (isStreaming && hasSteps) {
2361
2483
  setIsStepsExpanded(true);
2362
2484
  }
@@ -2365,7 +2487,7 @@ function AgentMessage({
2365
2487
  }
2366
2488
  wasStreamingRef.current = isStreaming;
2367
2489
  }, [isStreaming, hasSteps]);
2368
- const totalElapsedMs = hasSteps ? message.steps.reduce((sum, step) => sum + (step.elapsedMs || 0), 0) : 0;
2490
+ const totalElapsedMs = hasSteps ? message.steps.reduce((sum, step2) => sum + (step2.elapsedMs || 0), 0) : 0;
2369
2491
  const currentMessage = message.currentMessage;
2370
2492
  const rawContent = message.streamingContent || message.content || "";
2371
2493
  const content = rawContent.replace(/\\n/g, "\n");
@@ -2373,13 +2495,13 @@ function AgentMessage({
2373
2495
  const completedWithNoContent = !isStreaming && !isCancelled && content.length === 0 && (message.streamProgress === "completed" || message.streamProgress === "error");
2374
2496
  const conflictErrorMessage = getConflictErrorMessage(message.errorDetails);
2375
2497
  const isError = !!conflictErrorMessage || (isFriendlyWorkflowError(message.errorDetails) || looksLikeRawError(content)) && !hasMeaningfulContent || completedWithNoContent;
2376
- const currentStep = React.useMemo(
2498
+ const currentStep = react.useMemo(
2377
2499
  () => message.steps?.find(
2378
2500
  (s) => s.id === currentExecutingStepId && s.status === "in_progress"
2379
2501
  ),
2380
2502
  [message.steps, currentExecutingStepId]
2381
2503
  );
2382
- const markdownRenderers = React.useMemo(
2504
+ const markdownRenderers = react.useMemo(
2383
2505
  () => createMarkdownComponents({
2384
2506
  isResolvingImages: message.isResolvingImages
2385
2507
  }),
@@ -2393,25 +2515,25 @@ function AgentMessage({
2393
2515
  }
2394
2516
  return `${count} ${stepWord} completed`;
2395
2517
  };
2396
- const renderStepIcon = (step, isCurrentlyExecuting) => {
2518
+ const renderStepIcon = (step2, isCurrentlyExecuting) => {
2397
2519
  const wrapper = "h-4 w-4 flex items-center justify-center shrink-0";
2398
2520
  if (isCurrentlyExecuting)
2399
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" }) });
2400
- if (step.status === "pending" && isCancelled)
2522
+ if (step2.status === "pending" && isCancelled)
2401
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" }) });
2402
- if (step.status === "pending" || step.status === "in_progress")
2524
+ if (step2.status === "pending" || step2.status === "in_progress")
2403
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" }) });
2404
- if (step.status === "completed")
2526
+ if (step2.status === "completed")
2405
2527
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: wrapper, children: /* @__PURE__ */ jsxRuntime.jsx(
2406
2528
  lucideReact.Check,
2407
2529
  {
2408
2530
  className: cn(
2409
2531
  "h-3.5 w-3.5",
2410
- step.eventType === "USER_ACTION_SUCCESS" ? "payman-agent-step-icon--success" : "payman-agent-step-icon--success-dim"
2532
+ step2.eventType === "USER_ACTION_SUCCESS" ? "payman-agent-step-icon--success" : "payman-agent-step-icon--success-dim"
2411
2533
  )
2412
2534
  }
2413
2535
  ) });
2414
- if (step.status === "error")
2536
+ if (step2.status === "error")
2415
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" }) });
2416
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" }) });
2417
2539
  };
@@ -2423,38 +2545,38 @@ function AgentMessage({
2423
2545
  exit: { height: 0, opacity: 0 },
2424
2546
  transition: { duration: 0.2, ease: "easeInOut" },
2425
2547
  className: "overflow-hidden",
2426
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pt-1.5", children: message.steps.map((step) => {
2427
- const isCurrentlyExecuting = step.id === currentExecutingStepId && step.status === "in_progress" && isStreaming && !isCancelled;
2428
- const hasTime = step.elapsedMs != null && step.elapsedMs > 0;
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;
2429
2551
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-1.5", children: [
2430
2552
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-1.5 items-start", children: [
2431
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-px", children: renderStepIcon(step, isCurrentlyExecuting) }),
2553
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-px", children: renderStepIcon(step2, isCurrentlyExecuting) }),
2432
2554
  /* @__PURE__ */ jsxRuntime.jsx(
2433
2555
  "span",
2434
2556
  {
2435
2557
  className: cn(
2436
2558
  "text-xs leading-relaxed min-w-0 break-words",
2437
2559
  isCurrentlyExecuting && "shimmer-text font-medium",
2438
- !isCurrentlyExecuting && step.status === "error" && "payman-agent-step-text--error",
2439
- !isCurrentlyExecuting && step.eventType === "USER_ACTION_SUCCESS" && "payman-agent-step-text--success",
2440
- !isCurrentlyExecuting && step.status === "completed" && "payman-agent-step-text--completed",
2441
- !isCurrentlyExecuting && step.status === "pending" && "payman-agent-step-text--pending",
2442
- !isCurrentlyExecuting && step.status === "in_progress" && "payman-agent-step-text--in-progress"
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"
2443
2565
  ),
2444
- children: step.message
2566
+ children: step2.message
2445
2567
  }
2446
2568
  )
2447
2569
  ] }),
2448
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: [
2449
2571
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Clock, { className: "h-2.5 w-2.5 shrink-0 payman-agent-step-time-icon" }),
2450
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-mono payman-agent-step-time-text", children: formatElapsedTime(step.elapsedMs) })
2572
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-mono payman-agent-step-time-text", children: formatElapsedTime(step2.elapsedMs) })
2451
2573
  ] }) })
2452
- ] }, step.id);
2574
+ ] }, step2.id);
2453
2575
  }) })
2454
2576
  }
2455
2577
  ) });
2456
- const stepsToggleRef = React.useRef(null);
2457
- const handleStepsToggle = React.useCallback(() => {
2578
+ const stepsToggleRef = react.useRef(null);
2579
+ const handleStepsToggle = react.useCallback(() => {
2458
2580
  setIsStepsExpanded((prev) => {
2459
2581
  const next = !prev;
2460
2582
  if (next) {
@@ -2782,23 +2904,23 @@ function MessageList({
2782
2904
  isLoadingMoreMessages = false,
2783
2905
  hasMoreMessages = false
2784
2906
  }) {
2785
- const scrollRef = React.useRef(null);
2786
- const isNearBottomRef = React.useRef(true);
2787
- const [showScrollBtn, setShowScrollBtn] = React.useState(false);
2788
- const prevMessageCountRef = React.useRef(messages.length);
2789
- const scrollHeightBeforePrependRef = React.useRef(null);
2790
- const firstMessageIdRef = React.useRef(messages[0]?.id);
2791
- const getDistanceFromBottom = React.useCallback(() => {
2907
+ const scrollRef = react.useRef(null);
2908
+ const isNearBottomRef = react.useRef(true);
2909
+ const [showScrollBtn, setShowScrollBtn] = react.useState(false);
2910
+ const prevMessageCountRef = react.useRef(messages.length);
2911
+ const scrollHeightBeforePrependRef = react.useRef(null);
2912
+ const firstMessageIdRef = react.useRef(messages[0]?.id);
2913
+ const getDistanceFromBottom = react.useCallback(() => {
2792
2914
  const el = scrollRef.current;
2793
2915
  if (!el) return 0;
2794
2916
  return el.scrollHeight - el.scrollTop - el.clientHeight;
2795
2917
  }, []);
2796
- const scrollToBottom = React.useCallback((behavior = "smooth") => {
2918
+ const scrollToBottom = react.useCallback((behavior = "smooth") => {
2797
2919
  const el = scrollRef.current;
2798
2920
  if (!el) return;
2799
2921
  el.scrollTo({ top: el.scrollHeight, behavior });
2800
2922
  }, []);
2801
- const handleScroll = React.useCallback(() => {
2923
+ const handleScroll = react.useCallback(() => {
2802
2924
  const el = scrollRef.current;
2803
2925
  if (!el) return;
2804
2926
  const distance = getDistanceFromBottom();
@@ -2810,7 +2932,7 @@ function MessageList({
2810
2932
  onLoadMoreMessages();
2811
2933
  }
2812
2934
  }, [getDistanceFromBottom, hasMoreMessages, isLoadingMoreMessages, onLoadMoreMessages]);
2813
- React.useLayoutEffect(() => {
2935
+ react.useLayoutEffect(() => {
2814
2936
  const el = scrollRef.current;
2815
2937
  const prevHeight = scrollHeightBeforePrependRef.current;
2816
2938
  const newFirstId = messages[0]?.id;
@@ -2820,25 +2942,25 @@ function MessageList({
2820
2942
  }
2821
2943
  firstMessageIdRef.current = newFirstId;
2822
2944
  }, [messages]);
2823
- React.useEffect(() => {
2945
+ react.useEffect(() => {
2824
2946
  const prevCount = prevMessageCountRef.current;
2825
2947
  prevMessageCountRef.current = messages.length;
2826
2948
  if (messages.length > prevCount && isNearBottomRef.current) {
2827
2949
  requestAnimationFrame(() => scrollToBottom());
2828
2950
  }
2829
2951
  }, [messages.length, scrollToBottom]);
2830
- React.useEffect(() => {
2952
+ react.useEffect(() => {
2831
2953
  const lastMsg = messages[messages.length - 1];
2832
2954
  if (!lastMsg?.isStreaming) return;
2833
2955
  if (!isNearBottomRef.current) return;
2834
2956
  requestAnimationFrame(() => scrollToBottom());
2835
2957
  });
2836
- React.useEffect(() => {
2958
+ react.useEffect(() => {
2837
2959
  if (messages.length > 0) {
2838
2960
  setTimeout(() => scrollToBottom("instant"), 50);
2839
2961
  }
2840
2962
  }, []);
2841
- React.useEffect(() => {
2963
+ react.useEffect(() => {
2842
2964
  const handleStepsToggle = () => {
2843
2965
  requestAnimationFrame(() => {
2844
2966
  requestAnimationFrame(() => {
@@ -2855,7 +2977,7 @@ function MessageList({
2855
2977
  return () => el.removeEventListener("payman-steps-toggle", handleStepsToggle);
2856
2978
  }
2857
2979
  }, [getDistanceFromBottom, scrollToBottom]);
2858
- const handleScrollToBottom = React.useCallback(() => {
2980
+ const handleScrollToBottom = react.useCallback(() => {
2859
2981
  scrollToBottom();
2860
2982
  }, [scrollToBottom]);
2861
2983
  if (isLoading) {
@@ -2988,7 +3110,7 @@ function ResetSessionConfirmModal({
2988
3110
  onClose,
2989
3111
  onConfirm
2990
3112
  }) {
2991
- const handleKeyDown = React.useCallback(
3113
+ const handleKeyDown = react.useCallback(
2992
3114
  (event) => {
2993
3115
  if (event.key === "Escape") {
2994
3116
  onClose();
@@ -2996,7 +3118,7 @@ function ResetSessionConfirmModal({
2996
3118
  },
2997
3119
  [onClose]
2998
3120
  );
2999
- React.useEffect(() => {
3121
+ react.useEffect(() => {
3000
3122
  if (!isOpen || typeof document === "undefined") return;
3001
3123
  document.addEventListener("keydown", handleKeyDown);
3002
3124
  const previousOverflow = document.body.style.overflow;
@@ -3102,14 +3224,14 @@ function UserMessageV2({
3102
3224
  retryDisabled = false,
3103
3225
  actions
3104
3226
  }) {
3105
- const [copied, setCopied] = React.useState(false);
3106
- const [toast, setToast] = React.useState(null);
3107
- const copyResetTimerRef = React.useRef(null);
3108
- const toastTimerRef = React.useRef(null);
3227
+ const [copied, setCopied] = react.useState(false);
3228
+ const [toast, setToast] = react.useState(null);
3229
+ const copyResetTimerRef = react.useRef(null);
3230
+ const toastTimerRef = react.useRef(null);
3109
3231
  const showCopyAction = actions?.copy ?? true;
3110
3232
  const showEditAction = actions?.edit ?? false;
3111
3233
  const showRetryAction = actions?.retry ?? false;
3112
- React.useEffect(() => {
3234
+ react.useEffect(() => {
3113
3235
  return () => {
3114
3236
  if (copyResetTimerRef.current) clearTimeout(copyResetTimerRef.current);
3115
3237
  if (toastTimerRef.current) clearTimeout(toastTimerRef.current);
@@ -3265,18 +3387,18 @@ function MarkdownImageV2({
3265
3387
  onImageClick
3266
3388
  }) {
3267
3389
  const cachedAlready = src ? loadedImageCache.has(src) : false;
3268
- const [isVisible, setIsVisible] = React.useState(cachedAlready);
3269
- const [isLoaded, setIsLoaded] = React.useState(cachedAlready);
3270
- const [hasError, setHasError] = React.useState(false);
3271
- const [retryCount, setRetryCount] = React.useState(0);
3272
- const sentinelRef = React.useRef(null);
3273
- const prevLoadedRef = React.useRef(cachedAlready);
3274
- const isUnresolvedRag = React.useMemo(
3390
+ const [isVisible, setIsVisible] = react.useState(cachedAlready);
3391
+ const [isLoaded, setIsLoaded] = react.useState(cachedAlready);
3392
+ const [hasError, setHasError] = react.useState(false);
3393
+ const [retryCount, setRetryCount] = react.useState(0);
3394
+ const sentinelRef = react.useRef(null);
3395
+ const prevLoadedRef = react.useRef(cachedAlready);
3396
+ const isUnresolvedRag = react.useMemo(
3275
3397
  () => src ? isUnresolvedRagImageSource2(src) : false,
3276
3398
  [src]
3277
3399
  );
3278
3400
  const isResolvingRag = Boolean(isResolving && isUnresolvedRag);
3279
- React.useEffect(() => {
3401
+ react.useEffect(() => {
3280
3402
  if (src && loadedImageCache.has(src)) {
3281
3403
  setIsLoaded(true);
3282
3404
  setIsVisible(true);
@@ -3285,7 +3407,7 @@ function MarkdownImageV2({
3285
3407
  setHasError(false);
3286
3408
  setRetryCount(0);
3287
3409
  }, [src]);
3288
- React.useEffect(() => {
3410
+ react.useEffect(() => {
3289
3411
  const el = sentinelRef.current;
3290
3412
  if (!el || !src) return;
3291
3413
  const rect = el.getBoundingClientRect();
@@ -3406,92 +3528,13 @@ function MarkdownImageV2({
3406
3528
  }
3407
3529
  ) });
3408
3530
  }
3409
- var RAG_SOURCE_CLASS = "payman-v2-rag-source";
3410
- var RAG_FOLLOW_UP_CLASS = "payman-v2-rag-follow-up";
3411
- var SOURCE_PATTERN = /^Sources?:\s*\S/i;
3412
- var MAX_FOLLOW_UP_LENGTH = 320;
3413
- var HR_PATTERN = /^-{3,}$|^_{3,}$|^\*{3,}$/;
3414
- function normalizeRagParagraphText(text) {
3415
- return text.replace(/\s+/g, " ").trim();
3416
- }
3417
- function isRagSourceParagraph(text) {
3418
- return SOURCE_PATTERN.test(normalizeRagParagraphText(text));
3419
- }
3420
- function isRagFollowUpCandidate(text) {
3421
- const normalized = normalizeRagParagraphText(text);
3422
- return normalized.length > 0 && normalized.length <= MAX_FOLLOW_UP_LENGTH && normalized.endsWith("?");
3423
- }
3424
- function extractRagParagraphTexts(content) {
3425
- const paragraphs = [];
3426
- const currentParagraph = [];
3427
- const flushParagraph = () => {
3428
- const paragraph = normalizeRagParagraphText(currentParagraph.join(" "));
3429
- currentParagraph.length = 0;
3430
- if (paragraph) paragraphs.push(paragraph);
3431
- };
3432
- content.replace(/\\n/g, "\n").split(/\r?\n/).forEach((line) => {
3433
- const trimmedLine = line.trim();
3434
- if (!trimmedLine) {
3435
- flushParagraph();
3436
- return;
3437
- }
3438
- if (HR_PATTERN.test(trimmedLine)) {
3439
- flushParagraph();
3440
- return;
3441
- }
3442
- currentParagraph.push(trimmedLine);
3443
- });
3444
- flushParagraph();
3445
- return paragraphs;
3446
- }
3447
- function getRagAnswerParagraphRoles(paragraphs) {
3448
- const normalized = paragraphs.map(normalizeRagParagraphText);
3449
- const roles = normalized.map(() => null);
3450
- const sourceIndexes = normalized.map((paragraph, index) => isRagSourceParagraph(paragraph) ? index : -1).filter((index) => index >= 0);
3451
- for (const sourceIndex of sourceIndexes) {
3452
- roles[sourceIndex] = "source";
3453
- for (const candidateIndex of [sourceIndex - 1, sourceIndex + 1]) {
3454
- if (candidateIndex >= 0 && candidateIndex < normalized.length && roles[candidateIndex] == null && isRagFollowUpCandidate(normalized[candidateIndex] ?? "")) {
3455
- roles[candidateIndex] = "follow-up";
3456
- }
3457
- }
3458
- }
3459
- return roles;
3460
- }
3461
- function getRagAnswerParagraphRole(paragraph, paragraphs) {
3462
- const normalizedParagraph = normalizeRagParagraphText(paragraph);
3463
- if (isRagSourceParagraph(normalizedParagraph)) return "source";
3464
- const roles = getRagAnswerParagraphRoles(paragraphs);
3465
- return paragraphs.map(normalizeRagParagraphText).some((candidate, index) => {
3466
- return candidate === normalizedParagraph && roles[index] === "follow-up";
3467
- }) ? "follow-up" : null;
3468
- }
3469
- function ragAnswerRoleClassName(role) {
3470
- if (role === "source") return RAG_SOURCE_CLASS;
3471
- if (role === "follow-up") return RAG_FOLLOW_UP_CLASS;
3472
- return void 0;
3473
- }
3474
- function reactNodeText(node) {
3475
- if (typeof node === "string" || typeof node === "number") return String(node);
3476
- if (Array.isArray(node)) return node.map(reactNodeText).join("");
3477
- if (React__namespace.isValidElement(node)) {
3478
- return reactNodeText(node.props.children);
3479
- }
3480
- return "";
3481
- }
3482
- function buildComponents(onImageClick, isResolvingRef, ragParagraphsRef) {
3531
+ function buildComponents(onImageClick, isResolvingRef) {
3483
3532
  return {
3484
- p: ({ children }) => {
3485
- const role = getRagAnswerParagraphRole(
3486
- reactNodeText(children),
3487
- ragParagraphsRef?.current ?? []
3488
- );
3489
- return /* @__PURE__ */ jsxRuntime.jsx("p", { className: ragAnswerRoleClassName(role), children });
3490
- },
3533
+ p: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("p", { children }),
3491
3534
  code: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("code", { children }),
3492
3535
  pre: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "payman-v2-markdown-pre", children: /* @__PURE__ */ jsxRuntime.jsx("pre", { children }) }),
3493
3536
  ul: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("ul", { children }),
3494
- ol: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("ol", { children }),
3537
+ ol: ({ children, start }) => /* @__PURE__ */ jsxRuntime.jsx("ol", { start, children }),
3495
3538
  li: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("li", { children }),
3496
3539
  h1: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("h1", { children }),
3497
3540
  h2: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("h2", { children }),
@@ -3523,15 +3566,10 @@ function MarkdownRendererV2({
3523
3566
  isResolvingImages,
3524
3567
  onImageClick
3525
3568
  }) {
3526
- const isResolvingRef = React.useRef(isResolvingImages);
3569
+ const isResolvingRef = react.useRef(isResolvingImages);
3527
3570
  isResolvingRef.current = isResolvingImages;
3528
- const ragParagraphsRef = React.useRef([]);
3529
- ragParagraphsRef.current = React.useMemo(
3530
- () => extractRagParagraphTexts(content),
3531
- [content]
3532
- );
3533
- const components = React.useMemo(
3534
- () => buildComponents(onImageClick, isResolvingRef, ragParagraphsRef),
3571
+ const components = react.useMemo(
3572
+ () => buildComponents(onImageClick, isResolvingRef),
3535
3573
  [onImageClick]
3536
3574
  );
3537
3575
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -3588,14 +3626,14 @@ function FeedbackReasonModal({
3588
3626
  onClose,
3589
3627
  onSubmit
3590
3628
  }) {
3591
- const [reason, setReason] = React.useState(
3629
+ const [reason, setReason] = react.useState(
3592
3630
  NEGATIVE_FEEDBACK_REASONS[0].value
3593
3631
  );
3594
- const [details, setDetails] = React.useState("");
3595
- const [submitting, setSubmitting] = React.useState(false);
3596
- const [error, setError] = React.useState(null);
3597
- const [reasonOpen, setReasonOpen] = React.useState(false);
3598
- React.useEffect(() => {
3632
+ const [details, setDetails] = react.useState("");
3633
+ const [submitting, setSubmitting] = react.useState(false);
3634
+ const [error, setError] = react.useState(null);
3635
+ const [reasonOpen, setReasonOpen] = react.useState(false);
3636
+ react.useEffect(() => {
3599
3637
  if (open) {
3600
3638
  setReason(NEGATIVE_FEEDBACK_REASONS[0].value);
3601
3639
  setDetails("");
@@ -3604,7 +3642,7 @@ function FeedbackReasonModal({
3604
3642
  setReasonOpen(false);
3605
3643
  }
3606
3644
  }, [open]);
3607
- const handleKeyDown = React.useCallback(
3645
+ const handleKeyDown = react.useCallback(
3608
3646
  (event) => {
3609
3647
  if (event.key !== "Escape") return;
3610
3648
  if (reasonOpen) {
@@ -3615,7 +3653,7 @@ function FeedbackReasonModal({
3615
3653
  },
3616
3654
  [onClose, reasonOpen]
3617
3655
  );
3618
- React.useEffect(() => {
3656
+ react.useEffect(() => {
3619
3657
  if (!open || typeof document === "undefined") return;
3620
3658
  document.addEventListener("keydown", handleKeyDown);
3621
3659
  const previousOverflow = document.body.style.overflow;
@@ -3797,6 +3835,87 @@ function FeedbackReasonModal({
3797
3835
  }
3798
3836
  ) : null });
3799
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
3800
3919
  var RESPONSE_SPEED = {
3801
3920
  normal: [2, 4],
3802
3921
  fast: 1,
@@ -3804,7 +3923,6 @@ var RESPONSE_SPEED = {
3804
3923
  newline: [4, 6],
3805
3924
  idle: 15
3806
3925
  };
3807
- var MARKDOWN_IMAGE_REGEX = /^!\[[^\]]*\]\([^)]*\)/;
3808
3926
  function charDelay(char, speed, multiplier) {
3809
3927
  const raw = (() => {
3810
3928
  if (char === "*") return speed.fast;
@@ -3819,17 +3937,17 @@ function charDelay(char, speed, multiplier) {
3819
3937
  function useTypingEffect(targetText, enabled, speed = RESPONSE_SPEED, initialDisplayedText, speedMultiplier = 1) {
3820
3938
  const instant = speedMultiplier === 0;
3821
3939
  const multiplier = instant ? 1 : Math.max(speedMultiplier, 0.1);
3822
- const [displayedText, setDisplayedText] = React.useState("");
3823
- const displayedRef = React.useRef("");
3824
- const targetRef = React.useRef(targetText);
3825
- const enabledRef = React.useRef(enabled);
3826
- const initialDisplayedRef = React.useRef(initialDisplayedText);
3827
- const timerRef = React.useRef(null);
3828
- const runningRef = React.useRef(false);
3940
+ const [displayedText, setDisplayedText] = react.useState("");
3941
+ const displayedRef = react.useRef("");
3942
+ const targetRef = react.useRef(targetText);
3943
+ const enabledRef = react.useRef(enabled);
3944
+ const initialDisplayedRef = react.useRef(initialDisplayedText);
3945
+ const timerRef = react.useRef(null);
3946
+ const runningRef = react.useRef(false);
3829
3947
  targetRef.current = targetText;
3830
3948
  enabledRef.current = enabled;
3831
3949
  initialDisplayedRef.current = initialDisplayedText;
3832
- React.useEffect(() => {
3950
+ react.useEffect(() => {
3833
3951
  if (!enabled || instant) {
3834
3952
  if (timerRef.current) {
3835
3953
  clearTimeout(timerRef.current);
@@ -3863,9 +3981,9 @@ function useTypingEffect(targetText, enabled, speed = RESPONSE_SPEED, initialDis
3863
3981
  }
3864
3982
  if (displayedRef.current.length < targetRef.current.length) {
3865
3983
  const remaining = targetRef.current.slice(displayedRef.current.length);
3866
- const imgMatch = MARKDOWN_IMAGE_REGEX.exec(remaining);
3867
- if (imgMatch) {
3868
- displayedRef.current += imgMatch[0];
3984
+ const imageTokenLength = completeMarkdownImageTokenLength(remaining);
3985
+ if (imageTokenLength > 0) {
3986
+ displayedRef.current += remaining.slice(0, imageTokenLength);
3869
3987
  setDisplayedText(displayedRef.current);
3870
3988
  timerRef.current = setTimeout(tick, 0);
3871
3989
  return;
@@ -3894,13 +4012,6 @@ function useTypingEffect(targetText, enabled, speed = RESPONSE_SPEED, initialDis
3894
4012
  isTyping
3895
4013
  };
3896
4014
  }
3897
- function stripIncompleteImageToken(text) {
3898
- const lastBang = text.lastIndexOf("![");
3899
- if (lastBang === -1) return text;
3900
- const after = text.slice(lastBang);
3901
- if (/^!\[[^\]]*\]\([^)]*\)/.test(after)) return text;
3902
- return text.slice(0, lastBang);
3903
- }
3904
4015
  function getFeedbackState(message) {
3905
4016
  const feedback = message.feedback;
3906
4017
  if (feedback === "up" || feedback === "down") return feedback;
@@ -3919,26 +4030,26 @@ function AssistantMessageV2({
3919
4030
  actions,
3920
4031
  typingSpeed = 4
3921
4032
  }) {
3922
- const [copied, setCopied] = React.useState(false);
3923
- const [activeFeedback, setActiveFeedback] = React.useState(
4033
+ const [copied, setCopied] = react.useState(false);
4034
+ const [activeFeedback, setActiveFeedback] = react.useState(
3924
4035
  () => getFeedbackState(message)
3925
4036
  );
3926
- const [reasonModalOpen, setReasonModalOpen] = React.useState(false);
4037
+ const [reasonModalOpen, setReasonModalOpen] = react.useState(false);
3927
4038
  const canSubmitFeedback = !!onSubmitFeedback && !!message.executionId;
3928
- const [toast, setToast] = React.useState(null);
3929
- const copyResetTimerRef = React.useRef(null);
3930
- const toastTimerRef = React.useRef(null);
4039
+ const [toast, setToast] = react.useState(null);
4040
+ const copyResetTimerRef = react.useRef(null);
4041
+ const toastTimerRef = react.useRef(null);
3931
4042
  const showCopyAction = actions?.copy ?? true;
3932
4043
  const showTraceAction = (actions?.trace ?? true) && !!onExecutionTraceClick;
3933
4044
  const showThumbsUp = actions?.thumbsUp ?? true;
3934
4045
  const showThumbsDown = actions?.thumbsDown ?? true;
3935
4046
  const hydratedFeedback = message.feedback;
3936
- const hasEverStreamed = React.useRef(!!message.isStreaming);
4047
+ const hasEverStreamed = react.useRef(!!message.isStreaming);
3937
4048
  if (message.isStreaming) hasEverStreamed.current = true;
3938
- React.useEffect(() => {
4049
+ react.useEffect(() => {
3939
4050
  setActiveFeedback(getFeedbackState(message));
3940
4051
  }, [hydratedFeedback, message.id]);
3941
- React.useEffect(() => {
4052
+ react.useEffect(() => {
3942
4053
  return () => {
3943
4054
  if (copyResetTimerRef.current) clearTimeout(copyResetTimerRef.current);
3944
4055
  if (toastTimerRef.current) clearTimeout(toastTimerRef.current);
@@ -4232,10 +4343,10 @@ function OtpInputV2({
4232
4343
  disabled = false,
4233
4344
  error = false
4234
4345
  }) {
4235
- const inputRefs = React.useRef([]);
4346
+ const inputRefs = react.useRef([]);
4236
4347
  const safeMaxLength = Number.isInteger(maxLength) && maxLength > 0 ? Math.min(maxLength, MAX_SUPPORTED_LENGTH) : DEFAULT_MAX_LENGTH;
4237
4348
  const digits = value.split("").concat(Array(safeMaxLength).fill("")).slice(0, safeMaxLength);
4238
- React.useEffect(() => {
4349
+ react.useEffect(() => {
4239
4350
  if (disabled) return;
4240
4351
  const timer = window.setTimeout(() => {
4241
4352
  inputRefs.current[0]?.focus();
@@ -4334,31 +4445,31 @@ function VerificationInline({
4334
4445
  onResend
4335
4446
  }) {
4336
4447
  const isNumeric = prompt.verificationType !== "ALPHANUMERIC_CODE";
4337
- const codeLen = React.useMemo(() => codeLengthFromSchema(prompt), [prompt]);
4338
- const [code, setCode] = React.useState("");
4339
- const [errored, setErrored] = React.useState(false);
4340
- const [resendSec, setResendSec] = React.useState(0);
4341
- const [hiddenAfterResend, setHiddenAfterResend] = React.useState(false);
4342
- const lastSubmittedRef = React.useRef(null);
4343
- const resendTimerRef = React.useRef(void 0);
4448
+ const codeLen = react.useMemo(() => codeLengthFromSchema(prompt), [prompt]);
4449
+ const [code, setCode] = react.useState("");
4450
+ const [errored, setErrored] = react.useState(false);
4451
+ const [resendSec, setResendSec] = react.useState(0);
4452
+ const [hiddenAfterResend, setHiddenAfterResend] = react.useState(false);
4453
+ const lastSubmittedRef = react.useRef(null);
4454
+ const resendTimerRef = react.useRef(void 0);
4344
4455
  const status = prompt.status;
4345
4456
  const busy = status === "submitting";
4346
4457
  const stale = status === "stale";
4347
4458
  const locked = busy || stale || expired;
4348
- React.useEffect(() => {
4459
+ react.useEffect(() => {
4349
4460
  if (prompt.subAction === "SubmissionInvalid") {
4350
4461
  setErrored(true);
4351
4462
  setCode("");
4352
4463
  lastSubmittedRef.current = null;
4353
4464
  }
4354
4465
  }, [prompt.subAction, prompt.userActionId]);
4355
- React.useEffect(() => {
4466
+ react.useEffect(() => {
4356
4467
  setHiddenAfterResend(false);
4357
4468
  }, [prompt.expirySeconds, prompt.message, prompt.subAction, prompt.userActionId]);
4358
- React.useEffect(() => {
4469
+ react.useEffect(() => {
4359
4470
  if (code.length < codeLen) lastSubmittedRef.current = null;
4360
4471
  }, [code, codeLen]);
4361
- const doSubmit = React.useCallback(
4472
+ const doSubmit = react.useCallback(
4362
4473
  (value) => {
4363
4474
  if (locked || !value) return;
4364
4475
  if (lastSubmittedRef.current === value) return;
@@ -4370,20 +4481,20 @@ function VerificationInline({
4370
4481
  },
4371
4482
  [locked, onSubmit, prompt.userActionId]
4372
4483
  );
4373
- React.useEffect(() => {
4484
+ react.useEffect(() => {
4374
4485
  if (!isNumeric || locked) return;
4375
4486
  if (code.length === codeLen && /^\d+$/.test(code)) {
4376
4487
  doSubmit(code);
4377
4488
  }
4378
4489
  }, [code, codeLen, doSubmit, isNumeric, locked]);
4379
- React.useEffect(() => {
4490
+ react.useEffect(() => {
4380
4491
  return () => {
4381
4492
  if (typeof resendTimerRef.current === "number") {
4382
4493
  window.clearInterval(resendTimerRef.current);
4383
4494
  }
4384
4495
  };
4385
4496
  }, []);
4386
- const startResendCooldown = React.useCallback(() => {
4497
+ const startResendCooldown = react.useCallback(() => {
4387
4498
  setResendSec(RESEND_COOLDOWN_S);
4388
4499
  if (typeof resendTimerRef.current === "number") {
4389
4500
  window.clearInterval(resendTimerRef.current);
@@ -4401,7 +4512,7 @@ function VerificationInline({
4401
4512
  });
4402
4513
  }, 1e3);
4403
4514
  }, []);
4404
- const handleResend = React.useCallback(async () => {
4515
+ const handleResend = react.useCallback(async () => {
4405
4516
  if (locked || resendSec > 0) return;
4406
4517
  setErrored(false);
4407
4518
  setCode("");
@@ -4414,7 +4525,7 @@ function VerificationInline({
4414
4525
  setHiddenAfterResend(false);
4415
4526
  }
4416
4527
  }, [locked, onResend, prompt.userActionId, resendSec, startResendCooldown]);
4417
- const handleCancel = React.useCallback(() => {
4528
+ const handleCancel = react.useCallback(() => {
4418
4529
  if (busy) return;
4419
4530
  void onCancel(prompt.userActionId);
4420
4531
  }, [busy, onCancel, prompt.userActionId]);
@@ -4504,13 +4615,13 @@ function SchemaFormInline({
4504
4615
  onCancel
4505
4616
  }) {
4506
4617
  const schema = prompt.requestedSchema;
4507
- const fields = React.useMemo(() => renderableFields(schema), [schema]);
4508
- const [values, setValues] = React.useState(() => {
4618
+ const fields = react.useMemo(() => renderableFields(schema), [schema]);
4619
+ const [values, setValues] = react.useState(() => {
4509
4620
  const init2 = {};
4510
4621
  for (const [key, field] of fields) init2[key] = defaultValueFor(field);
4511
4622
  return init2;
4512
4623
  });
4513
- const [errors, setErrors] = React.useState({});
4624
+ const [errors, setErrors] = react.useState({});
4514
4625
  const status = prompt.status;
4515
4626
  const busy = status === "submitting";
4516
4627
  const stale = status === "stale";
@@ -4651,8 +4762,8 @@ function NotificationInline({ notification, onDismiss }) {
4651
4762
  }
4652
4763
  function useExpiryCountdown(prompt) {
4653
4764
  const initial = typeof prompt.expirySeconds === "number" && prompt.expirySeconds > 0 ? Math.floor(prompt.expirySeconds) : void 0;
4654
- const [secondsLeft, setSecondsLeft] = React.useState(initial);
4655
- React.useEffect(() => {
4765
+ const [secondsLeft, setSecondsLeft] = react.useState(initial);
4766
+ react.useEffect(() => {
4656
4767
  if (initial === void 0) {
4657
4768
  setSecondsLeft(void 0);
4658
4769
  return;
@@ -4691,7 +4802,7 @@ function UserActionInline({
4691
4802
  onExpired
4692
4803
  }) {
4693
4804
  const [secondsLeft, expired] = useExpiryCountdown(prompt);
4694
- React.useEffect(() => {
4805
+ react.useEffect(() => {
4695
4806
  if (expired && prompt.kind !== "notification") onExpired?.();
4696
4807
  }, [expired, onExpired, prompt.kind]);
4697
4808
  let body;
@@ -4754,7 +4865,7 @@ function getPromptViewKey(prompt) {
4754
4865
  prompt.message ?? ""
4755
4866
  ].join(PROMPT_KEY_SEPARATOR);
4756
4867
  }
4757
- var MessageListV2 = React.forwardRef(
4868
+ var MessageListV2 = react.forwardRef(
4758
4869
  function MessageListV22({
4759
4870
  messages,
4760
4871
  isStreaming = false,
@@ -4774,25 +4885,25 @@ var MessageListV2 = React.forwardRef(
4774
4885
  onSubmitFeedback,
4775
4886
  typingSpeed = 4
4776
4887
  }, ref) {
4777
- const noop = React.useCallback(async () => {
4888
+ const noop = react.useCallback(async () => {
4778
4889
  }, []);
4779
- const scrollRef = React.useRef(null);
4780
- const scrollInnerRef = React.useRef(null);
4781
- const isNearBottomRef = React.useRef(true);
4782
- const [showScrollBtn, setShowScrollBtn] = React.useState(false);
4783
- const [expiredPromptViewState, setExpiredPromptViewState] = React.useState({});
4784
- const expiredUserActionIdsRef = React.useRef(/* @__PURE__ */ new Set());
4785
- const prevCountRef = React.useRef(messages.length);
4786
- const pauseStickUntilUserMessageRef = React.useRef(false);
4787
- const followingBottomRef = React.useRef(true);
4788
- const lastPinAtRef = React.useRef(0);
4789
- const prevScrollTopRef = React.useRef(0);
4790
- const getDistanceFromBottom = React.useCallback(() => {
4890
+ const scrollRef = react.useRef(null);
4891
+ const scrollInnerRef = react.useRef(null);
4892
+ const isNearBottomRef = react.useRef(true);
4893
+ const [showScrollBtn, setShowScrollBtn] = react.useState(false);
4894
+ const [expiredPromptViewState, setExpiredPromptViewState] = react.useState({});
4895
+ const expiredUserActionIdsRef = react.useRef(/* @__PURE__ */ new Set());
4896
+ const prevCountRef = react.useRef(messages.length);
4897
+ const pauseStickUntilUserMessageRef = react.useRef(false);
4898
+ const followingBottomRef = react.useRef(true);
4899
+ const lastPinAtRef = react.useRef(0);
4900
+ const prevScrollTopRef = react.useRef(0);
4901
+ const getDistanceFromBottom = react.useCallback(() => {
4791
4902
  const el = scrollRef.current;
4792
4903
  if (!el) return 0;
4793
4904
  return el.scrollHeight - el.scrollTop - el.clientHeight;
4794
4905
  }, []);
4795
- const messageActivityFingerprint = React.useMemo(() => {
4906
+ const messageActivityFingerprint = react.useMemo(() => {
4796
4907
  const last = messages[messages.length - 1];
4797
4908
  const promptFingerprint = (userActionPrompts ?? []).map((prompt) => `${getPromptViewKey(prompt)}:${prompt.status}`).join(PROMPT_KEY_SEPARATOR);
4798
4909
  const notificationFingerprint = (notifications ?? []).map((notification) => notification.id).join(PROMPT_KEY_SEPARATOR);
@@ -4818,7 +4929,7 @@ var MessageListV2 = React.forwardRef(
4818
4929
  notificationFingerprint
4819
4930
  ].join(PROMPT_KEY_SEPARATOR);
4820
4931
  }, [isStreaming, messages, notifications, userActionPrompts]);
4821
- const handleUserActionExpired = React.useCallback(
4932
+ const handleUserActionExpired = react.useCallback(
4822
4933
  (promptKey, userActionId) => {
4823
4934
  setExpiredPromptViewState((prev) => {
4824
4935
  if (prev[promptKey]) return prev;
@@ -4835,7 +4946,7 @@ var MessageListV2 = React.forwardRef(
4835
4946
  },
4836
4947
  [messageActivityFingerprint, onExpireUserAction]
4837
4948
  );
4838
- React.useEffect(() => {
4949
+ react.useEffect(() => {
4839
4950
  setExpiredPromptViewState((prev) => {
4840
4951
  let changed = false;
4841
4952
  const next = {};
@@ -4850,7 +4961,7 @@ var MessageListV2 = React.forwardRef(
4850
4961
  return changed ? next : prev;
4851
4962
  });
4852
4963
  }, [messageActivityFingerprint]);
4853
- React.useEffect(() => {
4964
+ react.useEffect(() => {
4854
4965
  const livePromptKeys = new Set((userActionPrompts ?? []).map(getPromptViewKey));
4855
4966
  const liveUserActionIds = new Set((userActionPrompts ?? []).map((p) => p.userActionId));
4856
4967
  for (const userActionId of expiredUserActionIdsRef.current) {
@@ -4871,21 +4982,21 @@ var MessageListV2 = React.forwardRef(
4871
4982
  return changed ? next : prev;
4872
4983
  });
4873
4984
  }, [userActionPrompts]);
4874
- const visibleUserActionPrompts = React.useMemo(
4985
+ const visibleUserActionPrompts = react.useMemo(
4875
4986
  () => userActionPrompts?.filter((prompt) => {
4876
4987
  const promptKey = getPromptViewKey(prompt);
4877
4988
  return !expiredPromptViewState[promptKey]?.hidden;
4878
4989
  }),
4879
4990
  [expiredPromptViewState, userActionPrompts]
4880
4991
  );
4881
- const pinToBottom = React.useCallback((behavior = "instant") => {
4992
+ const pinToBottom = react.useCallback((behavior = "instant") => {
4882
4993
  const el = scrollRef.current;
4883
4994
  if (!el) return;
4884
4995
  lastPinAtRef.current = performance.now();
4885
4996
  el.scrollTo({ top: el.scrollHeight, behavior });
4886
4997
  prevScrollTopRef.current = el.scrollHeight;
4887
4998
  }, []);
4888
- const scrollToBottom = React.useCallback(
4999
+ const scrollToBottom = react.useCallback(
4889
5000
  (behavior = "smooth") => {
4890
5001
  const el = scrollRef.current;
4891
5002
  if (!el) return;
@@ -4895,7 +5006,7 @@ var MessageListV2 = React.forwardRef(
4895
5006
  },
4896
5007
  [pinToBottom]
4897
5008
  );
4898
- React.useImperativeHandle(
5009
+ react.useImperativeHandle(
4899
5010
  ref,
4900
5011
  () => ({
4901
5012
  scrollToBottom: (behavior = "smooth") => {
@@ -4908,7 +5019,7 @@ var MessageListV2 = React.forwardRef(
4908
5019
  }),
4909
5020
  [scrollToBottom]
4910
5021
  );
4911
- const handleScroll = React.useCallback(() => {
5022
+ const handleScroll = react.useCallback(() => {
4912
5023
  const el = scrollRef.current;
4913
5024
  if (!el) return;
4914
5025
  const currentScrollTop = el.scrollTop;
@@ -4929,7 +5040,7 @@ var MessageListV2 = React.forwardRef(
4929
5040
  pauseStickUntilUserMessageRef.current = false;
4930
5041
  }
4931
5042
  }, [getDistanceFromBottom]);
4932
- React.useEffect(() => {
5043
+ react.useEffect(() => {
4933
5044
  const prevCount = prevCountRef.current;
4934
5045
  prevCountRef.current = messages.length;
4935
5046
  if (messages.length > prevCount) {
@@ -4943,7 +5054,7 @@ var MessageListV2 = React.forwardRef(
4943
5054
  }
4944
5055
  }
4945
5056
  }, [messages.length, scrollToBottom]);
4946
- React.useEffect(() => {
5057
+ react.useEffect(() => {
4947
5058
  const inner = scrollInnerRef.current;
4948
5059
  if (!inner) return;
4949
5060
  const pinIfFollowing = () => {
@@ -4968,7 +5079,7 @@ var MessageListV2 = React.forwardRef(
4968
5079
  mo.disconnect();
4969
5080
  };
4970
5081
  }, [pinToBottom]);
4971
- React.useEffect(() => {
5082
+ react.useEffect(() => {
4972
5083
  if (messages.length > 0) {
4973
5084
  setTimeout(() => scrollToBottom("instant"), 50);
4974
5085
  }
@@ -5057,7 +5168,7 @@ var MessageListV2 = React.forwardRef(
5057
5168
  ] });
5058
5169
  }
5059
5170
  );
5060
- var ChatInputV2 = React.forwardRef(
5171
+ var ChatInputV2 = react.forwardRef(
5061
5172
  function ChatInputV22({
5062
5173
  onSend,
5063
5174
  disabled = false,
@@ -5081,20 +5192,20 @@ var ChatInputV2 = React.forwardRef(
5081
5192
  onAnalysisModeChange,
5082
5193
  slashCommands = []
5083
5194
  }, ref) {
5084
- const [value, setValue] = React.useState("");
5085
- const [isFocused, setIsFocused] = React.useState(false);
5086
- const [showActions, setShowActions] = React.useState(false);
5087
- const [showVoiceTooltip, setShowVoiceTooltip] = React.useState(false);
5088
- const [selectedCommandIndex, setSelectedCommandIndex] = React.useState(0);
5089
- const [inlineHint, setInlineHint] = React.useState(null);
5090
- const [commandMenuDismissed, setCommandMenuDismissed] = React.useState(false);
5091
- const textareaRef = React.useRef(null);
5092
- const actionsRef = React.useRef(null);
5093
- const preRecordTextRef = React.useRef("");
5094
- const voiceTooltipTimerRef = React.useRef(
5195
+ const [value, setValue] = react.useState("");
5196
+ const [isFocused, setIsFocused] = react.useState(false);
5197
+ const [showActions, setShowActions] = react.useState(false);
5198
+ const [showVoiceTooltip, setShowVoiceTooltip] = react.useState(false);
5199
+ const [selectedCommandIndex, setSelectedCommandIndex] = react.useState(0);
5200
+ const [inlineHint, setInlineHint] = react.useState(null);
5201
+ const [commandMenuDismissed, setCommandMenuDismissed] = react.useState(false);
5202
+ const textareaRef = react.useRef(null);
5203
+ const actionsRef = react.useRef(null);
5204
+ const preRecordTextRef = react.useRef("");
5205
+ const voiceTooltipTimerRef = react.useRef(
5095
5206
  null
5096
5207
  );
5097
- const voiceDraftSyncActiveRef = React.useRef(false);
5208
+ const voiceDraftSyncActiveRef = react.useRef(false);
5098
5209
  const isInputLocked = disabled || isRecording;
5099
5210
  const hasAttachmentOptions = showUploadImageButton || showAttachFileButton;
5100
5211
  const showAttachmentMenuButton = showAttachmentButton && hasAttachmentOptions;
@@ -5105,14 +5216,14 @@ var ChatInputV2 = React.forwardRef(
5105
5216
  (command) => command.name.toLowerCase().startsWith(commandQuery)
5106
5217
  );
5107
5218
  const showCommandSuggestions = !commandMenuDismissed && !isRecording && !disabled && commandSuggestions.length > 0;
5108
- React.useEffect(() => {
5219
+ react.useEffect(() => {
5109
5220
  if (textareaRef.current) {
5110
5221
  textareaRef.current.style.height = "auto";
5111
5222
  const scrollHeight = textareaRef.current.scrollHeight;
5112
5223
  textareaRef.current.style.height = `${Math.min(scrollHeight, 200)}px`;
5113
5224
  }
5114
5225
  }, [value]);
5115
- React.useEffect(() => {
5226
+ react.useEffect(() => {
5116
5227
  if (disabled) {
5117
5228
  setIsFocused(false);
5118
5229
  setShowActions(false);
@@ -5122,7 +5233,7 @@ var ChatInputV2 = React.forwardRef(
5122
5233
  const frameId = requestAnimationFrame(() => textareaRef.current?.focus());
5123
5234
  return () => cancelAnimationFrame(frameId);
5124
5235
  }, [disabled]);
5125
- React.useImperativeHandle(
5236
+ react.useImperativeHandle(
5126
5237
  ref,
5127
5238
  () => ({
5128
5239
  setDraft: (message) => {
@@ -5139,7 +5250,7 @@ var ChatInputV2 = React.forwardRef(
5139
5250
  }),
5140
5251
  [disabled]
5141
5252
  );
5142
- React.useEffect(() => {
5253
+ react.useEffect(() => {
5143
5254
  if (!showActions) return;
5144
5255
  const handleClickOutside = (e) => {
5145
5256
  if (actionsRef.current && !actionsRef.current.contains(e.target)) {
@@ -5149,29 +5260,29 @@ var ChatInputV2 = React.forwardRef(
5149
5260
  document.addEventListener("mousedown", handleClickOutside);
5150
5261
  return () => document.removeEventListener("mousedown", handleClickOutside);
5151
5262
  }, [showActions]);
5152
- React.useEffect(() => {
5263
+ react.useEffect(() => {
5153
5264
  if (!showAttachmentMenuButton) {
5154
5265
  setShowActions(false);
5155
5266
  }
5156
5267
  }, [showAttachmentMenuButton]);
5157
- React.useEffect(() => {
5268
+ react.useEffect(() => {
5158
5269
  setSelectedCommandIndex(0);
5159
5270
  setCommandMenuDismissed(false);
5160
5271
  }, [commandQuery]);
5161
- React.useEffect(() => {
5272
+ react.useEffect(() => {
5162
5273
  return () => {
5163
5274
  if (voiceTooltipTimerRef.current) {
5164
5275
  clearTimeout(voiceTooltipTimerRef.current);
5165
5276
  }
5166
5277
  };
5167
5278
  }, []);
5168
- React.useEffect(() => {
5279
+ react.useEffect(() => {
5169
5280
  if (!voiceDraftSyncActiveRef.current) return;
5170
5281
  const base = preRecordTextRef.current;
5171
5282
  const separator = base && !base.endsWith(" ") && transcribedText ? " " : "";
5172
5283
  setValue(`${base}${separator}${transcribedText}`);
5173
5284
  }, [isRecording, transcribedText]);
5174
- const handleSend = React.useCallback(() => {
5285
+ const handleSend = react.useCallback(() => {
5175
5286
  if (!value.trim() || disabled) return;
5176
5287
  const commandHint = getSlashCommandValidationHint(value);
5177
5288
  if (commandHint) {
@@ -5191,7 +5302,7 @@ var ChatInputV2 = React.forwardRef(
5191
5302
  }
5192
5303
  });
5193
5304
  }, [value, disabled, onClearEditing, onSend]);
5194
- const selectCommand = React.useCallback(
5305
+ const selectCommand = react.useCallback(
5195
5306
  (command) => {
5196
5307
  const insertText = command.insertText ?? `${command.name} `;
5197
5308
  setValue(insertText);
@@ -5247,14 +5358,14 @@ var ChatInputV2 = React.forwardRef(
5247
5358
  onAttachFileClick?.();
5248
5359
  setShowActions(false);
5249
5360
  };
5250
- const hideVoiceTooltip = React.useCallback(() => {
5361
+ const hideVoiceTooltip = react.useCallback(() => {
5251
5362
  if (voiceTooltipTimerRef.current) {
5252
5363
  clearTimeout(voiceTooltipTimerRef.current);
5253
5364
  voiceTooltipTimerRef.current = null;
5254
5365
  }
5255
5366
  setShowVoiceTooltip(false);
5256
5367
  }, []);
5257
- const startVoiceTooltipTimer = React.useCallback(() => {
5368
+ const startVoiceTooltipTimer = react.useCallback(() => {
5258
5369
  if (isVoiceButtonDisabled || isRecording) return;
5259
5370
  if (voiceTooltipTimerRef.current) {
5260
5371
  clearTimeout(voiceTooltipTimerRef.current);
@@ -5576,9 +5687,9 @@ var ChatInputV2 = React.forwardRef(
5576
5687
  var thinking_atom_default = "data:application/zip;base64,UEsDBBQAAAAIAMWrkFzFrMWzUgAAAF4AAAANAAAAbWFuaWZlc3QuanNvbqtWKkstKs7Mz1OyUjJS0lFKT81LLUosyS8C8h1S8kty8ktKMlP14SzdrGIHQz0zPZDaxLzM3MQSoN5iJavoaqXMFKAe38TMPIXgZKApSrWxtQBQSwMEFAAAAAgAxauQXLRghFpXBAAA1RwAABEAAABhL01haW4gU2NlbmUuanNvbu1YWW/jNhD+KwafJVWkqMtPbdEDfdiiQIq+GMZCcei1GvmApLRdGP7v/YYiddqbGNumR4wcomZGHM7B76N0ZLstm7N3Wb6b3a3UTjGHPTw8sLnvsA2bCx/X3811q+qMzY/sAx74stjXda7WeaGqL1alyup9OeNeEnmcnRxWZB9VWbH54sjqj2weOI2bH5+KYibhoirZnONSa0f7AzykGOQYkGP4X2dFpbq13ONx0mTVu6x6bNXZXosf4erI9OLwjwRw7Tv4WWLSP+ALa7I2Rs0RkvkzRhEZQdWz8iHCms48Z54RMEAs2gABkcGRYVFHBqXv8Sh2GBKgRzDNW00SIClag1GzugVNShk5OUd9zxMj4cI/2UhoSdUwVBJpn53EGPMTOd0hh8hAUwuodC1UoVZ1ud+9UjWog+jvb6hIv9D9egxT8aK8kfte5tD5kiTYCfpaqvUPyABb7beH9/57zlUi4zBwE+FnrsyUdDOfC/c+iNVqzVOVKoH06vwLLDsr1Y6q+VZLgX7+dxQDW29SDGmKsVNPr1iLSyB1Bkui0CDGAEdkEmmpeXghQwe/Td0slnRzyDQ5NwdH8L05htXHLGFqIWk0fQ+YPhc9P3+3VpvsoDrSYR9KFNHWpKvWdgfdV998/e3sF2w70Nb35f7pAFNdfn0z49QpNLHDVnqh0FL9IUXU1kG1eZmDO1rYzB06+imrN30/hNG9JmkiPLIVm9flE2ZFuRZoFzf0hIyXzkJfqXcgtLJGCSHyi1SR/URF9pNJYP8b2adeaEwwoqc6AQ2XS+obXTi7bdi6eGmWs8MmXyEN3+UFPaOzQGOdBcQ52BeeDGXqgB3jRNIlirBe7Vs2TYNkXeiGsFtcTS0w3XLPAp8x0MQ86uluEVPse66t9R4ZdbVd88Vw4tNpqTcZIZekEUrFQi/2fAS3hqPIwBMXSIqBp6yqVN1shjHH5NejpvUyOtdZzNyX93lNVfwPn+vGrHjDpiuxSXAvFIHDhSdFRNghvcSPnMQLhKRbo3dbg0bvNgYWsZ4xcz7txuIYrGOfOzz0/JiTUZB4acwdVwiNa43abfVGrbVnMA79fCXG3WGvPdLLlM5nc6czWiBpKFXxq07ptqBOudg7hDI49vRUOAJYuJggZiQDrqFSxA6CMgj2/8PCNqDty6oCjqlViaL8XOb0iC4JjWfU51Xb6CiLunz8CiPop0cnnIb6Ryd7YGpf4bqTUmhPSpSSYXxuSsBtk3ztGkQwPAJS7QevkWdOa2SLNLSn378smfqMTZF0yRzV8Ez4SToNf4i5drmWByfHdk1B5PxGQW+Xgix5jMlhTB5jchlS0CeNOiK74GREQROOGVLQhKFuFHSjoH+CgkSELwM3CrqCgjDJGQoKbhT0pikIH0oE+CAMgOmpF3HAof580grxHaWRdt9opjr9wWUyj6UWHnvSD4yZ1N9pBiIXshuF3Cjktd9izmHo61CIxeSAPpWd/gRQSwECFAAUAAAACADFq5BcxazFs1IAAABeAAAADQAAAAAAAAAAAAAAAAAAAAAAbWFuaWZlc3QuanNvblBLAQIUABQAAAAIAMWrkFy0YIRaVwQAANUcAAARAAAAAAAAAAAAAAAAAH0AAABhL01haW4gU2NlbmUuanNvblBLBQYAAAAAAgACAHoAAAADBQAAAAA=";
5577
5688
  var DEFAULT_SIZE = 36;
5578
5689
  function useElapsedSeconds(isStreaming) {
5579
- const [elapsed, setElapsed] = React.useState(0);
5580
- const startRef = React.useRef(null);
5581
- React.useEffect(() => {
5690
+ const [elapsed, setElapsed] = react.useState(0);
5691
+ const startRef = react.useRef(null);
5692
+ react.useEffect(() => {
5582
5693
  if (!isStreaming) {
5583
5694
  startRef.current = null;
5584
5695
  setElapsed(0);
@@ -5637,22 +5748,22 @@ function StreamingIndicatorV2({
5637
5748
  ) });
5638
5749
  }
5639
5750
  function ImageLightboxV2({ src, alt, onClose }) {
5640
- const [isMounted, setIsMounted] = React.useState(false);
5641
- const [isImageLoaded, setIsImageLoaded] = React.useState(false);
5642
- React.useEffect(() => {
5751
+ const [isMounted, setIsMounted] = react.useState(false);
5752
+ const [isImageLoaded, setIsImageLoaded] = react.useState(false);
5753
+ react.useEffect(() => {
5643
5754
  setIsMounted(true);
5644
5755
  return () => setIsMounted(false);
5645
5756
  }, []);
5646
- React.useEffect(() => {
5757
+ react.useEffect(() => {
5647
5758
  setIsImageLoaded(false);
5648
5759
  }, [src]);
5649
- const handleKeyDown = React.useCallback(
5760
+ const handleKeyDown = react.useCallback(
5650
5761
  (e) => {
5651
5762
  if (e.key === "Escape") onClose();
5652
5763
  },
5653
5764
  [onClose]
5654
5765
  );
5655
- React.useEffect(() => {
5766
+ react.useEffect(() => {
5656
5767
  if (!src || typeof document === "undefined") return;
5657
5768
  document.addEventListener("keydown", handleKeyDown);
5658
5769
  const previousOverflow = document.body.style.overflow;
@@ -5784,9 +5895,9 @@ var PRE_PIPELINE_STEPS = /* @__PURE__ */ new Set([
5784
5895
  "build_pipeline",
5785
5896
  "load_skill_index"
5786
5897
  ]);
5787
- function stepColor(step) {
5788
- if (step.status === "failed") return "#ef4444";
5789
- if (PRE_PIPELINE_STEPS.has(step.step)) return "#f59e0b";
5898
+ function stepColor(step2) {
5899
+ if (step2.status === "failed") return "#ef4444";
5900
+ if (PRE_PIPELINE_STEPS.has(step2.step)) return "#f59e0b";
5790
5901
  return "#3b82f6";
5791
5902
  }
5792
5903
  function formatMs(ms) {
@@ -5801,10 +5912,10 @@ function TraceTimelineModal({
5801
5912
  apiBaseUrl,
5802
5913
  apiHeaders
5803
5914
  }) {
5804
- const [trace, setTrace] = React.useState(null);
5805
- const [loading, setLoading] = React.useState(false);
5806
- const [error, setError] = React.useState(null);
5807
- React.useEffect(() => {
5915
+ const [trace, setTrace] = react.useState(null);
5916
+ const [loading, setLoading] = react.useState(false);
5917
+ const [error, setError] = react.useState(null);
5918
+ react.useEffect(() => {
5808
5919
  if (!open || !executionId) return;
5809
5920
  const ctrl = new AbortController();
5810
5921
  setLoading(true);
@@ -5826,7 +5937,7 @@ function TraceTimelineModal({
5826
5937
  }).finally(() => setLoading(false));
5827
5938
  return () => ctrl.abort();
5828
5939
  }, [open, executionId, apiBaseUrl, apiHeaders]);
5829
- const totalMs = React.useMemo(() => {
5940
+ const totalMs = react.useMemo(() => {
5830
5941
  if (!trace) return 0;
5831
5942
  const meta = trace.runMetadata?.totalTimeMs;
5832
5943
  if (typeof meta === "number" && meta > 0) return meta;
@@ -5835,7 +5946,7 @@ function TraceTimelineModal({
5835
5946
  if (starts.length === 0 || ends.length === 0) return 0;
5836
5947
  return Math.max(...ends) - Math.min(...starts);
5837
5948
  }, [trace]);
5838
- const accountedMs = React.useMemo(
5949
+ const accountedMs = react.useMemo(
5839
5950
  () => (trace?.pipelineSteps ?? []).reduce(
5840
5951
  (sum, s) => sum + (s.durationMs ?? 0),
5841
5952
  0
@@ -5963,10 +6074,10 @@ function TimelineBars({
5963
6074
  totalMs,
5964
6075
  unaccountedMs
5965
6076
  }) {
5966
- const bars = trace.pipelineSteps.map((step) => {
5967
- const duration = step.durationMs ?? 0;
6077
+ const bars = trace.pipelineSteps.map((step2) => {
6078
+ const duration = step2.durationMs ?? 0;
5968
6079
  const widthPct = totalMs > 0 ? duration / totalMs * 100 : 0;
5969
- const llmMs = step.llmCall?.durationMs ?? null;
6080
+ const llmMs = step2.llmCall?.durationMs ?? null;
5970
6081
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginBottom: 8 }, children: [
5971
6082
  /* @__PURE__ */ jsxRuntime.jsxs(
5972
6083
  "div",
@@ -5980,8 +6091,8 @@ function TimelineBars({
5980
6091
  },
5981
6092
  children: [
5982
6093
  /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
5983
- step.step,
5984
- step.status === "failed" && /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "#fca5a5", marginLeft: 6 }, children: "(failed)" })
6094
+ step2.step,
6095
+ step2.status === "failed" && /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "#fca5a5", marginLeft: 6 }, children: "(failed)" })
5985
6096
  ] }),
5986
6097
  /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { opacity: 0.75 }, children: [
5987
6098
  formatMs(duration),
@@ -6009,14 +6120,14 @@ function TimelineBars({
6009
6120
  style: {
6010
6121
  height: "100%",
6011
6122
  width: `${Math.max(widthPct, 0.3)}%`,
6012
- background: stepColor(step),
6123
+ background: stepColor(step2),
6013
6124
  transition: "width 0.2s ease"
6014
6125
  }
6015
6126
  }
6016
6127
  )
6017
6128
  }
6018
6129
  )
6019
- ] }, `${step.step}-${step.startTime}`);
6130
+ ] }, `${step2.step}-${step2.startTime}`);
6020
6131
  });
6021
6132
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
6022
6133
  bars,
@@ -6096,12 +6207,12 @@ var NOOP_ASYNC = async () => {
6096
6207
  var NOOP = () => {
6097
6208
  };
6098
6209
  function useSentryChatCallbacks(callbacks, config) {
6099
- const sentryCtxRef = React.useRef({});
6100
- const callbacksRef = React.useRef(callbacks);
6210
+ const sentryCtxRef = react.useRef({});
6211
+ const callbacksRef = react.useRef(callbacks);
6101
6212
  callbacksRef.current = callbacks;
6102
6213
  const initialSessionId = config.initialSessionId;
6103
6214
  const apiHeaders = config.api.headers;
6104
- React.useEffect(() => {
6215
+ react.useEffect(() => {
6105
6216
  sentryCtxRef.current.agentId = config.agentId;
6106
6217
  sentryCtxRef.current.sessionOwnerId = config.sessionParams?.id;
6107
6218
  if (initialSessionId) {
@@ -6117,13 +6228,13 @@ function useSentryChatCallbacks(callbacks, config) {
6117
6228
  initialSessionId,
6118
6229
  apiHeaders
6119
6230
  ]);
6120
- React.useEffect(() => {
6231
+ react.useEffect(() => {
6121
6232
  const endpoint = config.api.streamEndpoint || "/api/playground/ask/stream";
6122
6233
  return subscribeToCfRay(endpoint, (cfRay) => {
6123
6234
  sentryCtxRef.current.cfRay = cfRay;
6124
6235
  });
6125
6236
  }, [config.api.streamEndpoint]);
6126
- return React.useMemo(
6237
+ return react.useMemo(
6127
6238
  () => ({
6128
6239
  onMessageSent: (msg) => callbacksRef.current?.onMessageSent?.(msg),
6129
6240
  onStreamStart: () => callbacksRef.current?.onStreamStart?.(),
@@ -6172,7 +6283,7 @@ function useSentryChatCallbacks(callbacks, config) {
6172
6283
  []
6173
6284
  );
6174
6285
  }
6175
- var PaymanChatInner = React.forwardRef(function PaymanChatInner2({
6286
+ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
6176
6287
  config,
6177
6288
  callbacks = {},
6178
6289
  className,
@@ -6183,18 +6294,18 @@ var PaymanChatInner = React.forwardRef(function PaymanChatInner2({
6183
6294
  hasMoreMessages = false,
6184
6295
  chat
6185
6296
  }, ref) {
6186
- const [inputValue, setInputValue] = React.useState("");
6187
- const prevInputValueRef = React.useRef(inputValue);
6188
- const [hasEverSentMessage, setHasEverSentMessage] = React.useState(false);
6189
- const [lightboxSrc, setLightboxSrc] = React.useState(null);
6190
- const [lightboxAlt, setLightboxAlt] = React.useState("");
6191
- const [editingMessageId, setEditingMessageId] = React.useState(null);
6192
- const [isResetSessionConfirmOpen, setIsResetSessionConfirmOpen] = React.useState(false);
6193
- const [analysisMode, setAnalysisMode] = React.useState("fast");
6194
- const chatInputV2Ref = React.useRef(null);
6195
- const messageListV2Ref = React.useRef(null);
6196
- const resetToEmptyStateRef = React.useRef(false);
6197
- React.useEffect(() => {
6297
+ const [inputValue, setInputValue] = react.useState("");
6298
+ const prevInputValueRef = react.useRef(inputValue);
6299
+ const [hasEverSentMessage, setHasEverSentMessage] = react.useState(false);
6300
+ const [lightboxSrc, setLightboxSrc] = react.useState(null);
6301
+ const [lightboxAlt, setLightboxAlt] = react.useState("");
6302
+ const [editingMessageId, setEditingMessageId] = react.useState(null);
6303
+ const [isResetSessionConfirmOpen, setIsResetSessionConfirmOpen] = react.useState(false);
6304
+ const [analysisMode, setAnalysisMode] = react.useState("fast");
6305
+ const chatInputV2Ref = react.useRef(null);
6306
+ const messageListV2Ref = react.useRef(null);
6307
+ const resetToEmptyStateRef = react.useRef(false);
6308
+ react.useEffect(() => {
6198
6309
  if (config.sentryDsn) {
6199
6310
  initSentryIfNeeded(config.sentryDsn);
6200
6311
  }
@@ -6210,7 +6321,7 @@ var PaymanChatInner = React.forwardRef(function PaymanChatInner2({
6210
6321
  getSessionId,
6211
6322
  getMessages
6212
6323
  } = chat;
6213
- React.useEffect(() => {
6324
+ react.useEffect(() => {
6214
6325
  if (resetToEmptyStateRef.current) {
6215
6326
  if (messages.length === 0) {
6216
6327
  setHasEverSentMessage(false);
@@ -6222,7 +6333,7 @@ var PaymanChatInner = React.forwardRef(function PaymanChatInner2({
6222
6333
  setHasEverSentMessage(true);
6223
6334
  }
6224
6335
  }, [messages.length, hasEverSentMessage]);
6225
- React.useEffect(() => {
6336
+ react.useEffect(() => {
6226
6337
  if (!editingMessageId) return;
6227
6338
  const editingMessageStillExists = messages.some(
6228
6339
  (message) => message.id === editingMessageId && message.role === "user"
@@ -6235,7 +6346,7 @@ var PaymanChatInner = React.forwardRef(function PaymanChatInner2({
6235
6346
  const submitUserAction2 = chat.submitUserAction ?? NOOP_ASYNC;
6236
6347
  const cancelUserAction2 = chat.cancelUserAction ?? NOOP_ASYNC;
6237
6348
  const resendUserAction2 = chat.resendUserAction ?? NOOP_ASYNC;
6238
- const expireUserAction2 = chat.expireUserAction ?? NOOP_ASYNC;
6349
+ const expireUserAction = chat.expireUserAction ?? NOOP_ASYNC;
6239
6350
  const dismissNotification = chat.dismissNotification ?? NOOP;
6240
6351
  const isUserActionSupported = typeof chat.submitUserAction === "function" && typeof chat.cancelUserAction === "function" && typeof chat.resendUserAction === "function";
6241
6352
  const {
@@ -6261,7 +6372,7 @@ var PaymanChatInner = React.forwardRef(function PaymanChatInner2({
6261
6372
  }
6262
6373
  }
6263
6374
  );
6264
- const contextValue = React.useMemo(
6375
+ const contextValue = react.useMemo(
6265
6376
  () => ({
6266
6377
  resetSession,
6267
6378
  clearMessages,
@@ -6288,8 +6399,8 @@ var PaymanChatInner = React.forwardRef(function PaymanChatInner2({
6288
6399
  onAttachFileClick,
6289
6400
  onMessageFeedback
6290
6401
  } = callbacks;
6291
- const [debugTraceExecutionId, setDebugTraceExecutionId] = React.useState(null);
6292
- const handleSubmitFeedback = React.useCallback(
6402
+ const [debugTraceExecutionId, setDebugTraceExecutionId] = react.useState(null);
6403
+ const handleSubmitFeedback = react.useCallback(
6293
6404
  async ({ messageId, executionId, feedback, details }) => {
6294
6405
  if (!executionId) {
6295
6406
  throw new Error("Cannot submit feedback before the response completes");
@@ -6320,14 +6431,14 @@ var PaymanChatInner = React.forwardRef(function PaymanChatInner2({
6320
6431
  onMessageFeedback
6321
6432
  ]
6322
6433
  );
6323
- const onExecutionTraceClick = React.useMemo(() => {
6434
+ const onExecutionTraceClick = react.useMemo(() => {
6324
6435
  if (!config.debug) return rawOnExecutionTraceClick;
6325
6436
  return (data) => {
6326
6437
  rawOnExecutionTraceClick?.(data);
6327
6438
  if (data.executionId) setDebugTraceExecutionId(data.executionId);
6328
6439
  };
6329
6440
  }, [config.debug, rawOnExecutionTraceClick]);
6330
- const performResetSession = React.useCallback(() => {
6441
+ const performResetSession = react.useCallback(() => {
6331
6442
  resetToEmptyStateRef.current = true;
6332
6443
  setEditingMessageId(null);
6333
6444
  setIsResetSessionConfirmOpen(false);
@@ -6348,13 +6459,13 @@ var PaymanChatInner = React.forwardRef(function PaymanChatInner2({
6348
6459
  resetSession,
6349
6460
  stopRecording
6350
6461
  ]);
6351
- const requestResetSession = React.useCallback(() => {
6462
+ const requestResetSession = react.useCallback(() => {
6352
6463
  setIsResetSessionConfirmOpen(true);
6353
6464
  }, []);
6354
- const closeResetSessionConfirm = React.useCallback(() => {
6465
+ const closeResetSessionConfirm = react.useCallback(() => {
6355
6466
  setIsResetSessionConfirmOpen(false);
6356
6467
  }, []);
6357
- React.useImperativeHandle(ref, () => ({
6468
+ react.useImperativeHandle(ref, () => ({
6358
6469
  resetSession: performResetSession,
6359
6470
  clearMessages,
6360
6471
  cancelStream,
@@ -6393,7 +6504,7 @@ var PaymanChatInner = React.forwardRef(function PaymanChatInner2({
6393
6504
  slashCommands: slashCommandsConfig,
6394
6505
  commandPermissions
6395
6506
  } = config;
6396
- const messageActions = React.useMemo(
6507
+ const messageActions = react.useMemo(
6397
6508
  () => ({
6398
6509
  userMessageActions: {
6399
6510
  copy: messageActionsConfig?.userMessageActions?.copy ?? true,
@@ -6409,18 +6520,18 @@ var PaymanChatInner = React.forwardRef(function PaymanChatInner2({
6409
6520
  }),
6410
6521
  [messageActionsConfig]
6411
6522
  );
6412
- const slashCommands = React.useMemo(
6523
+ const slashCommands = react.useMemo(
6413
6524
  () => enableSlashCommands ? filterSlashCommands(
6414
6525
  slashCommandsConfig ?? DEFAULT_SLASH_COMMANDS,
6415
6526
  commandPermissions
6416
6527
  ) : [],
6417
6528
  [commandPermissions, enableSlashCommands, slashCommandsConfig]
6418
6529
  );
6419
- const isSessionParamsConfigured = React.useMemo(() => {
6530
+ const isSessionParamsConfigured = react.useMemo(() => {
6420
6531
  if (!sessionParams) return false;
6421
6532
  return !!(sessionParams.id?.trim() && sessionParams.name?.trim());
6422
6533
  }, [sessionParams?.id, sessionParams?.name]);
6423
- React.useEffect(() => {
6534
+ react.useEffect(() => {
6424
6535
  const wasEmpty = prevInputValueRef.current.trim() === "";
6425
6536
  const isEmpty2 = inputValue.trim() === "";
6426
6537
  prevInputValueRef.current = inputValue;
@@ -6487,7 +6598,7 @@ var PaymanChatInner = React.forwardRef(function PaymanChatInner2({
6487
6598
  void sendMessage(text.trim(), { analysisMode: effectiveAnalysisMode });
6488
6599
  }
6489
6600
  };
6490
- const handleVoicePress = React.useCallback(async () => {
6601
+ const handleVoicePress = react.useCallback(async () => {
6491
6602
  if (!voiceAvailable) return;
6492
6603
  if (isRecording) {
6493
6604
  stopRecording();
@@ -6496,7 +6607,7 @@ var PaymanChatInner = React.forwardRef(function PaymanChatInner2({
6496
6607
  clearTranscript();
6497
6608
  await startRecording();
6498
6609
  }, [clearTranscript, isRecording, startRecording, stopRecording, voiceAvailable]);
6499
- const handleEditMessageDraft = React.useCallback((messageId) => {
6610
+ const handleEditMessageDraft = react.useCallback((messageId) => {
6500
6611
  const targetMessage = messages.find((message) => message.id === messageId);
6501
6612
  if (!targetMessage?.content.trim()) return;
6502
6613
  setEditingMessageId(messageId);
@@ -6505,7 +6616,7 @@ var PaymanChatInner = React.forwardRef(function PaymanChatInner2({
6505
6616
  messageListV2Ref.current?.scrollToBottom("smooth");
6506
6617
  });
6507
6618
  }, [messages]);
6508
- const handleRetryUserMessage = React.useCallback((messageId) => {
6619
+ const handleRetryUserMessage = react.useCallback((messageId) => {
6509
6620
  if (isWaitingForResponse) return;
6510
6621
  const targetMessage = messages.find(
6511
6622
  (message) => message.id === messageId && message.role === "user"
@@ -6522,7 +6633,7 @@ var PaymanChatInner = React.forwardRef(function PaymanChatInner2({
6522
6633
  });
6523
6634
  });
6524
6635
  }, [isWaitingForResponse, messages, sendMessage, effectiveAnalysisMode]);
6525
- const handleClearEditing = React.useCallback(() => {
6636
+ const handleClearEditing = react.useCallback(() => {
6526
6637
  setEditingMessageId(null);
6527
6638
  }, []);
6528
6639
  return /* @__PURE__ */ jsxRuntime.jsx(PaymanChatContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsxs(
@@ -6636,7 +6747,7 @@ var PaymanChatInner = React.forwardRef(function PaymanChatInner2({
6636
6747
  onSubmitUserAction: isUserActionSupported ? submitUserAction2 : void 0,
6637
6748
  onCancelUserAction: isUserActionSupported ? cancelUserAction2 : void 0,
6638
6749
  onResendUserAction: isUserActionSupported ? resendUserAction2 : void 0,
6639
- onExpireUserAction: isUserActionSupported ? expireUserAction2 : void 0,
6750
+ onExpireUserAction: isUserActionSupported ? expireUserAction : void 0,
6640
6751
  onDismissNotification: dismissNotification,
6641
6752
  onSubmitFeedback: handleSubmitFeedback
6642
6753
  }
@@ -6712,7 +6823,7 @@ var PaymanChatInner = React.forwardRef(function PaymanChatInner2({
6712
6823
  }
6713
6824
  ) });
6714
6825
  });
6715
- var PaymanChat = React.forwardRef(
6826
+ var PaymanChat = react.forwardRef(
6716
6827
  function PaymanChat2(props, ref) {
6717
6828
  const mergedCallbacks = useSentryChatCallbacks(props.callbacks, props.config);
6718
6829
  const chat = useChatV2(props.config, mergedCallbacks);