@paymanai/payman-ask-sdk 4.0.23 → 4.0.25

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);
@@ -61,6 +60,7 @@ var chatStore = {
61
60
  memoryStore.delete(key);
62
61
  }
63
62
  };
63
+ var EMPTY_USER_ACTION_STATE = { prompts: [], notifications: [] };
64
64
  var streams = /* @__PURE__ */ new Map();
65
65
  var activeStreamStore = {
66
66
  has(key) {
@@ -69,7 +69,11 @@ var activeStreamStore = {
69
69
  get(key) {
70
70
  const entry = streams.get(key);
71
71
  if (!entry) return null;
72
- return { messages: entry.messages, isWaiting: entry.isWaiting };
72
+ return {
73
+ messages: entry.messages,
74
+ isWaiting: entry.isWaiting,
75
+ userActionState: entry.userActionState
76
+ };
73
77
  },
74
78
  // Called before startStream — registers the controller and initial messages
75
79
  start(key, abortController, initialMessages) {
@@ -77,6 +81,7 @@ var activeStreamStore = {
77
81
  streams.set(key, {
78
82
  messages: initialMessages,
79
83
  isWaiting: true,
84
+ userActionState: EMPTY_USER_ACTION_STATE,
80
85
  abortController,
81
86
  listeners: existing?.listeners ?? /* @__PURE__ */ new Set()
82
87
  });
@@ -87,20 +92,27 @@ var activeStreamStore = {
87
92
  if (!entry) return;
88
93
  const next = typeof updater === "function" ? updater(entry.messages) : updater;
89
94
  entry.messages = next;
90
- entry.listeners.forEach((l) => l(next, entry.isWaiting));
95
+ entry.listeners.forEach((l) => l(next, entry.isWaiting, entry.userActionState));
91
96
  },
92
97
  setWaiting(key, waiting) {
93
98
  const entry = streams.get(key);
94
99
  if (!entry) return;
95
100
  entry.isWaiting = waiting;
96
- entry.listeners.forEach((l) => l(entry.messages, waiting));
101
+ entry.listeners.forEach((l) => l(entry.messages, waiting, entry.userActionState));
102
+ },
103
+ applyUserActionState(key, updater) {
104
+ const entry = streams.get(key);
105
+ if (!entry) return;
106
+ const next = typeof updater === "function" ? updater(entry.userActionState) : updater;
107
+ entry.userActionState = next;
108
+ entry.listeners.forEach((l) => l(entry.messages, entry.isWaiting, next));
97
109
  },
98
110
  // Called when stream completes — persists to chatStore and cleans up
99
111
  complete(key) {
100
112
  const entry = streams.get(key);
101
113
  if (!entry) return;
102
114
  entry.isWaiting = false;
103
- entry.listeners.forEach((l) => l(entry.messages, false));
115
+ entry.listeners.forEach((l) => l(entry.messages, false, entry.userActionState));
104
116
  const toSave = entry.messages.filter((m) => !m.isStreaming);
105
117
  if (toSave.length > 0) chatStore.set(key, toSave);
106
118
  streams.delete(key);
@@ -523,9 +535,9 @@ function processStreamEventV2(rawEvent, state) {
523
535
  state.hasError = true;
524
536
  state.errorMessage = "WORKFLOW_FAILED";
525
537
  }
526
- state.steps.forEach((step) => {
527
- if (step.status === "in_progress") {
528
- step.status = "completed";
538
+ state.steps.forEach((step2) => {
539
+ if (step2.status === "in_progress") {
540
+ step2.status = "completed";
529
541
  }
530
542
  });
531
543
  state.lastEventType = eventType;
@@ -841,12 +853,12 @@ async function resolveRagImageUrls(config, content, signal) {
841
853
  }
842
854
  var FRIENDLY_ERROR_MESSAGE = "Oops, something went wrong. Please try again.";
843
855
  function useStreamManagerV2(config, callbacks, setMessages, setIsWaitingForResponse) {
844
- const abortControllerRef = React.useRef(null);
845
- const configRef = React.useRef(config);
856
+ const abortControllerRef = react.useRef(null);
857
+ const configRef = react.useRef(config);
846
858
  configRef.current = config;
847
- const callbacksRef = React.useRef(callbacks);
859
+ const callbacksRef = react.useRef(callbacks);
848
860
  callbacksRef.current = callbacks;
849
- const startStream = React.useCallback(
861
+ const startStream = react.useCallback(
850
862
  async (userMessage, streamingId, sessionId, externalAbortController, options) => {
851
863
  abortControllerRef.current?.abort();
852
864
  const abortController = externalAbortController ?? new AbortController();
@@ -940,11 +952,11 @@ function useStreamManagerV2(config, callbacks, setMessages, setIsWaitingForRespo
940
952
  errorDetails: isAborted ? void 0 : error.message,
941
953
  content: isAborted ? state.finalResponse || "" : state.finalResponse || FRIENDLY_ERROR_MESSAGE,
942
954
  currentMessage: isAborted ? "Thinking..." : void 0,
943
- steps: [...state.steps].map((step) => {
944
- if (step.status === "in_progress" && isAborted) {
945
- return { ...step, status: "pending" };
955
+ steps: [...state.steps].map((step2) => {
956
+ if (step2.status === "in_progress" && isAborted) {
957
+ return { ...step2, status: "pending" };
946
958
  }
947
- return step;
959
+ return step2;
948
960
  }),
949
961
  currentExecutingStepId: void 0
950
962
  } : msg
@@ -1030,11 +1042,11 @@ function useStreamManagerV2(config, callbacks, setMessages, setIsWaitingForRespo
1030
1042
  isCancelled: isAborted,
1031
1043
  errorDetails: isAborted ? void 0 : error.message,
1032
1044
  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" };
1045
+ steps: [...state.steps].map((step2) => {
1046
+ if (step2.status === "in_progress" && isAborted) {
1047
+ return { ...step2, status: "pending" };
1036
1048
  }
1037
- return step;
1049
+ return step2;
1038
1050
  }),
1039
1051
  currentExecutingStepId: void 0
1040
1052
  } : msg
@@ -1045,7 +1057,7 @@ function useStreamManagerV2(config, callbacks, setMessages, setIsWaitingForRespo
1045
1057
  },
1046
1058
  [setMessages, setIsWaitingForResponse]
1047
1059
  );
1048
- const cancelStream = React.useCallback(() => {
1060
+ const cancelStream = react.useCallback(() => {
1049
1061
  abortControllerRef.current?.abort();
1050
1062
  }, []);
1051
1063
  return {
@@ -1055,11 +1067,11 @@ function useStreamManagerV2(config, callbacks, setMessages, setIsWaitingForRespo
1055
1067
  };
1056
1068
  }
1057
1069
  function createCancelledMessageUpdate(steps, currentMessage) {
1058
- const updatedSteps = steps.map((step) => {
1059
- if (step.status === "in_progress") {
1060
- return { ...step, status: "pending" };
1070
+ const updatedSteps = steps.map((step2) => {
1071
+ if (step2.status === "in_progress") {
1072
+ return { ...step2, status: "pending" };
1061
1073
  }
1062
- return step;
1074
+ return step2;
1063
1075
  });
1064
1076
  return {
1065
1077
  isStreaming: false,
@@ -1108,12 +1120,31 @@ async function resendUserAction(config, userActionId) {
1108
1120
  async function expireUserAction(config, userActionId) {
1109
1121
  return sendUserActionRequest(config, userActionId, "expired");
1110
1122
  }
1111
- var EMPTY_USER_ACTION_STATE = { prompts: [], notifications: [] };
1123
+ function resolveUserActionExpiresAt(req, existing) {
1124
+ if (typeof req.expirySeconds !== "number" || req.expirySeconds <= 0) {
1125
+ return void 0;
1126
+ }
1127
+ if (existing?.expiresAt && existing.userActionId === req.userActionId) {
1128
+ return existing.expiresAt;
1129
+ }
1130
+ return Date.now() + Math.floor(req.expirySeconds) * 1e3;
1131
+ }
1132
+ function getUserActionSecondsLeft(prompt) {
1133
+ if (typeof prompt.expiresAt === "number" && prompt.expiresAt > 0) {
1134
+ return Math.max(0, Math.ceil((prompt.expiresAt - Date.now()) / 1e3));
1135
+ }
1136
+ if (typeof prompt.expirySeconds === "number" && prompt.expirySeconds > 0) {
1137
+ return Math.floor(prompt.expirySeconds);
1138
+ }
1139
+ return void 0;
1140
+ }
1141
+ var EMPTY_USER_ACTION_STATE2 = { prompts: [], notifications: [] };
1112
1142
  function upsertPrompt(prompts, req) {
1113
- const active = { ...req, status: "pending" };
1114
1143
  const idx = prompts.findIndex(
1115
1144
  (p) => req.toolCallId ? p.toolCallId === req.toolCallId : p.userActionId === req.userActionId
1116
1145
  );
1146
+ const expiresAt = resolveUserActionExpiresAt(req, idx >= 0 ? prompts[idx] : void 0);
1147
+ const active = { ...req, status: "pending", expiresAt };
1117
1148
  if (idx >= 0) {
1118
1149
  const next = prompts.slice();
1119
1150
  next[idx] = active;
@@ -1137,24 +1168,24 @@ function getSessionIdFromMessages(messages) {
1137
1168
  return messages.find((message) => message.sessionId)?.sessionId;
1138
1169
  }
1139
1170
  function useChatV2(config, callbacks = {}) {
1140
- const [messages, setMessages] = React.useState(() => getStoredOrInitialMessages(config));
1141
- const [isWaitingForResponse, setIsWaitingForResponse] = React.useState(() => {
1171
+ const [messages, setMessages] = react.useState(() => getStoredOrInitialMessages(config));
1172
+ const [isWaitingForResponse, setIsWaitingForResponse] = react.useState(() => {
1142
1173
  if (!config.userId) return false;
1143
1174
  return activeStreamStore.get(config.userId)?.isWaiting ?? false;
1144
1175
  });
1145
- const sessionIdRef = React.useRef(
1176
+ const sessionIdRef = react.useRef(
1146
1177
  getSessionIdFromMessages(getStoredOrInitialMessages(config)) ?? config.initialSessionId ?? void 0
1147
1178
  );
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);
1179
+ const prevUserIdRef = react.useRef(config.userId);
1180
+ const streamUserIdRef = react.useRef(void 0);
1181
+ const subscriptionPrevUserIdRef = react.useRef(config.userId);
1182
+ const callbacksRef = react.useRef(callbacks);
1152
1183
  callbacksRef.current = callbacks;
1153
- const configRef = React.useRef(config);
1184
+ const configRef = react.useRef(config);
1154
1185
  configRef.current = config;
1155
- const messagesRef = React.useRef(messages);
1186
+ const messagesRef = react.useRef(messages);
1156
1187
  messagesRef.current = messages;
1157
- const storeAwareSetMessages = React.useCallback(
1188
+ const storeAwareSetMessages = react.useCallback(
1158
1189
  (updater) => {
1159
1190
  const streamUserId = streamUserIdRef.current;
1160
1191
  const currentUserId = configRef.current.userId;
@@ -1169,7 +1200,7 @@ function useChatV2(config, callbacks = {}) {
1169
1200
  // eslint-disable-next-line react-hooks/exhaustive-deps
1170
1201
  []
1171
1202
  );
1172
- const storeAwareSetIsWaiting = React.useCallback(
1203
+ const storeAwareSetIsWaiting = react.useCallback(
1173
1204
  (waiting) => {
1174
1205
  const streamUserId = streamUserIdRef.current;
1175
1206
  const currentUserId = configRef.current.userId;
@@ -1184,8 +1215,29 @@ function useChatV2(config, callbacks = {}) {
1184
1215
  // eslint-disable-next-line react-hooks/exhaustive-deps
1185
1216
  []
1186
1217
  );
1187
- const [userActionState, setUserActionState] = React.useState(EMPTY_USER_ACTION_STATE);
1188
- const wrappedCallbacks = React.useMemo(() => ({
1218
+ const [userActionState, setUserActionState] = react.useState(() => {
1219
+ if (!config.userId) return EMPTY_USER_ACTION_STATE2;
1220
+ return activeStreamStore.get(config.userId)?.userActionState ?? EMPTY_USER_ACTION_STATE2;
1221
+ });
1222
+ const storeAwareSetUserActionState = react.useCallback(
1223
+ (updater) => {
1224
+ const streamUserId = streamUserIdRef.current;
1225
+ const currentUserId = configRef.current.userId;
1226
+ const storeKey = streamUserId ?? currentUserId;
1227
+ if (storeKey && activeStreamStore.has(storeKey)) {
1228
+ activeStreamStore.applyUserActionState(
1229
+ storeKey,
1230
+ updater
1231
+ );
1232
+ }
1233
+ if (!streamUserId || streamUserId === currentUserId) {
1234
+ setUserActionState(updater);
1235
+ }
1236
+ },
1237
+ // eslint-disable-next-line react-hooks/exhaustive-deps
1238
+ []
1239
+ );
1240
+ const wrappedCallbacks = react.useMemo(() => ({
1189
1241
  ...callbacksRef.current,
1190
1242
  onMessageSent: (message) => callbacksRef.current.onMessageSent?.(message),
1191
1243
  onStreamStart: () => callbacksRef.current.onStreamStart?.(),
@@ -1194,14 +1246,14 @@ function useChatV2(config, callbacks = {}) {
1194
1246
  onExecutionTraceClick: (data) => callbacksRef.current.onExecutionTraceClick?.(data),
1195
1247
  onSessionIdChange: (sessionId) => callbacksRef.current.onSessionIdChange?.(sessionId),
1196
1248
  onUserActionRequired: (request) => {
1197
- setUserActionState((prev) => ({
1249
+ storeAwareSetUserActionState((prev) => ({
1198
1250
  ...prev,
1199
1251
  prompts: upsertPrompt(prev.prompts, request)
1200
1252
  }));
1201
1253
  callbacksRef.current.onUserActionRequired?.(request);
1202
1254
  },
1203
1255
  onUserNotification: (notification) => {
1204
- setUserActionState(
1256
+ storeAwareSetUserActionState(
1205
1257
  (prev) => prev.notifications.some((n) => n.id === notification.id) ? prev : { ...prev, notifications: [...prev.notifications, notification] }
1206
1258
  );
1207
1259
  callbacksRef.current.onUserNotification?.(notification);
@@ -1214,7 +1266,7 @@ function useChatV2(config, callbacks = {}) {
1214
1266
  storeAwareSetMessages,
1215
1267
  storeAwareSetIsWaiting
1216
1268
  );
1217
- const sendMessage = React.useCallback(
1269
+ const sendMessage = react.useCallback(
1218
1270
  async (userMessage, options) => {
1219
1271
  if (!userMessage.trim()) return;
1220
1272
  if (!sessionIdRef.current && configRef.current.autoGenerateSessionId !== false) {
@@ -1274,16 +1326,16 @@ function useChatV2(config, callbacks = {}) {
1274
1326
  },
1275
1327
  [startStream]
1276
1328
  );
1277
- const clearMessages = React.useCallback(() => {
1329
+ const clearMessages = react.useCallback(() => {
1278
1330
  if (configRef.current.userId) {
1279
1331
  chatStore.delete(configRef.current.userId);
1280
1332
  }
1281
1333
  setMessages([]);
1282
1334
  }, []);
1283
- const prependMessages = React.useCallback((msgs) => {
1335
+ const prependMessages = react.useCallback((msgs) => {
1284
1336
  setMessages((prev) => [...msgs, ...prev]);
1285
1337
  }, []);
1286
- const cancelStream = React.useCallback(() => {
1338
+ const cancelStream = react.useCallback(() => {
1287
1339
  const streamUserId = streamUserIdRef.current ?? configRef.current.userId;
1288
1340
  if (streamUserId) {
1289
1341
  activeStreamStore.abort(streamUserId);
@@ -1291,7 +1343,7 @@ function useChatV2(config, callbacks = {}) {
1291
1343
  streamUserIdRef.current = void 0;
1292
1344
  cancelStreamManager();
1293
1345
  setIsWaitingForResponse(false);
1294
- setUserActionState((prev) => ({ ...prev, prompts: [] }));
1346
+ storeAwareSetUserActionState((prev) => ({ ...prev, prompts: [] }));
1295
1347
  setMessages(
1296
1348
  (prev) => prev.map((msg) => {
1297
1349
  if (msg.isStreaming) {
@@ -1306,8 +1358,8 @@ function useChatV2(config, callbacks = {}) {
1306
1358
  return msg;
1307
1359
  })
1308
1360
  );
1309
- }, [cancelStreamManager]);
1310
- const resetSession = React.useCallback(() => {
1361
+ }, [cancelStreamManager, storeAwareSetUserActionState]);
1362
+ const resetSession = react.useCallback(() => {
1311
1363
  const streamUserId = streamUserIdRef.current ?? configRef.current.userId;
1312
1364
  if (streamUserId) {
1313
1365
  activeStreamStore.abort(streamUserId);
@@ -1320,32 +1372,32 @@ function useChatV2(config, callbacks = {}) {
1320
1372
  sessionIdRef.current = void 0;
1321
1373
  abortControllerRef.current?.abort();
1322
1374
  setIsWaitingForResponse(false);
1323
- setUserActionState(EMPTY_USER_ACTION_STATE);
1375
+ storeAwareSetUserActionState(EMPTY_USER_ACTION_STATE2);
1324
1376
  }, []);
1325
- const getSessionId = React.useCallback(() => {
1377
+ const getSessionId = react.useCallback(() => {
1326
1378
  return sessionIdRef.current;
1327
1379
  }, []);
1328
- const getMessages = React.useCallback(() => {
1380
+ const getMessages = react.useCallback(() => {
1329
1381
  return messages;
1330
1382
  }, [messages]);
1331
- const setPromptStatus = React.useCallback(
1383
+ const setPromptStatus = react.useCallback(
1332
1384
  (userActionId, status) => {
1333
- setUserActionState((prev) => ({
1385
+ storeAwareSetUserActionState((prev) => ({
1334
1386
  ...prev,
1335
1387
  prompts: prev.prompts.map(
1336
1388
  (p) => p.userActionId === userActionId ? { ...p, status } : p
1337
1389
  )
1338
1390
  }));
1339
1391
  },
1340
- []
1392
+ [storeAwareSetUserActionState]
1341
1393
  );
1342
- const removePrompt = React.useCallback((userActionId) => {
1343
- setUserActionState((prev) => ({
1394
+ const removePrompt = react.useCallback((userActionId) => {
1395
+ storeAwareSetUserActionState((prev) => ({
1344
1396
  ...prev,
1345
1397
  prompts: prev.prompts.filter((p) => p.userActionId !== userActionId)
1346
1398
  }));
1347
- }, []);
1348
- const submitUserAction2 = React.useCallback(
1399
+ }, [storeAwareSetUserActionState]);
1400
+ const submitUserAction2 = react.useCallback(
1349
1401
  async (userActionId, content) => {
1350
1402
  setPromptStatus(userActionId, "submitting");
1351
1403
  try {
@@ -1363,7 +1415,7 @@ function useChatV2(config, callbacks = {}) {
1363
1415
  },
1364
1416
  [removePrompt, setPromptStatus]
1365
1417
  );
1366
- const cancelUserAction2 = React.useCallback(
1418
+ const cancelUserAction2 = react.useCallback(
1367
1419
  async (userActionId) => {
1368
1420
  setPromptStatus(userActionId, "submitting");
1369
1421
  try {
@@ -1381,7 +1433,7 @@ function useChatV2(config, callbacks = {}) {
1381
1433
  },
1382
1434
  [removePrompt, setPromptStatus]
1383
1435
  );
1384
- const resendUserAction2 = React.useCallback(
1436
+ const resendUserAction2 = react.useCallback(
1385
1437
  async (userActionId) => {
1386
1438
  setPromptStatus(userActionId, "submitting");
1387
1439
  try {
@@ -1399,7 +1451,7 @@ function useChatV2(config, callbacks = {}) {
1399
1451
  },
1400
1452
  [setPromptStatus]
1401
1453
  );
1402
- const expireUserAction2 = React.useCallback(
1454
+ const expireUserAction2 = react.useCallback(
1403
1455
  async (userActionId) => {
1404
1456
  setPromptStatus(userActionId, "expired");
1405
1457
  try {
@@ -1412,13 +1464,13 @@ function useChatV2(config, callbacks = {}) {
1412
1464
  },
1413
1465
  [setPromptStatus]
1414
1466
  );
1415
- const dismissNotification = React.useCallback((id) => {
1416
- setUserActionState((prev) => ({
1467
+ const dismissNotification = react.useCallback((id) => {
1468
+ storeAwareSetUserActionState((prev) => ({
1417
1469
  ...prev,
1418
1470
  notifications: prev.notifications.filter((n) => n.id !== id)
1419
1471
  }));
1420
- }, []);
1421
- React.useEffect(() => {
1472
+ }, [storeAwareSetUserActionState]);
1473
+ react.useEffect(() => {
1422
1474
  const prevSubscriptionUserId = subscriptionPrevUserIdRef.current;
1423
1475
  subscriptionPrevUserIdRef.current = config.userId;
1424
1476
  const { userId } = config;
@@ -1426,18 +1478,21 @@ function useChatV2(config, callbacks = {}) {
1426
1478
  if (prevSubscriptionUserId && prevSubscriptionUserId !== userId && streamUserIdRef.current === prevSubscriptionUserId && !activeStreamStore.has(prevSubscriptionUserId) && activeStreamStore.has(userId)) {
1427
1479
  streamUserIdRef.current = userId;
1428
1480
  }
1429
- const unsubscribe = activeStreamStore.subscribe(userId, (msgs, isWaiting) => {
1481
+ const unsubscribe = activeStreamStore.subscribe(userId, (msgs, isWaiting, actions) => {
1430
1482
  setMessages(msgs);
1431
1483
  setIsWaitingForResponse(isWaiting);
1484
+ setUserActionState(actions);
1432
1485
  });
1433
1486
  const active = activeStreamStore.get(userId);
1434
1487
  if (active) {
1488
+ streamUserIdRef.current = userId;
1435
1489
  setMessages(active.messages);
1436
1490
  setIsWaitingForResponse(active.isWaiting);
1491
+ setUserActionState(active.userActionState);
1437
1492
  }
1438
1493
  return unsubscribe;
1439
1494
  }, [config.userId]);
1440
- React.useEffect(() => {
1495
+ react.useEffect(() => {
1441
1496
  if (!config.userId) return;
1442
1497
  if (prevUserIdRef.current !== config.userId) return;
1443
1498
  const toSave = messages.filter((m) => !m.isStreaming);
@@ -1445,14 +1500,14 @@ function useChatV2(config, callbacks = {}) {
1445
1500
  chatStore.set(config.userId, toSave);
1446
1501
  }
1447
1502
  }, [messages, config.userId]);
1448
- React.useEffect(() => {
1503
+ react.useEffect(() => {
1449
1504
  if (!config.userId || activeStreamStore.has(config.userId)) return;
1450
1505
  if (!config.initialMessages?.length || messagesRef.current.length > 0) return;
1451
1506
  chatStore.set(config.userId, config.initialMessages);
1452
1507
  setMessages(config.initialMessages);
1453
1508
  sessionIdRef.current = getSessionIdFromMessages(config.initialMessages) ?? config.initialSessionId;
1454
1509
  }, [config.initialMessages, config.initialSessionId, config.userId]);
1455
- React.useEffect(() => {
1510
+ react.useEffect(() => {
1456
1511
  const prevUserId = prevUserIdRef.current;
1457
1512
  prevUserIdRef.current = config.userId;
1458
1513
  if (prevUserId === config.userId) return;
@@ -1461,12 +1516,14 @@ function useChatV2(config, callbacks = {}) {
1461
1516
  setMessages([]);
1462
1517
  sessionIdRef.current = void 0;
1463
1518
  setIsWaitingForResponse(false);
1464
- setUserActionState(EMPTY_USER_ACTION_STATE);
1519
+ setUserActionState(EMPTY_USER_ACTION_STATE2);
1465
1520
  } else if (config.userId) {
1466
1521
  const active = activeStreamStore.get(config.userId);
1467
1522
  if (active) {
1523
+ streamUserIdRef.current = config.userId;
1468
1524
  setMessages(active.messages);
1469
1525
  setIsWaitingForResponse(active.isWaiting);
1526
+ setUserActionState(active.userActionState);
1470
1527
  sessionIdRef.current = getSessionIdFromMessages(active.messages) ?? config.initialSessionId;
1471
1528
  return;
1472
1529
  }
@@ -1500,12 +1557,12 @@ function getSpeechRecognition() {
1500
1557
  return window.SpeechRecognition || window.webkitSpeechRecognition || null;
1501
1558
  }
1502
1559
  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);
1560
+ const [voiceState, setVoiceState] = react.useState("idle");
1561
+ const [transcribedText, setTranscribedText] = react.useState("");
1562
+ const [isAvailable, setIsAvailable] = react.useState(false);
1563
+ const [isRecording, setIsRecording] = react.useState(false);
1564
+ const recognitionRef = react.useRef(null);
1565
+ const autoStopTimerRef = react.useRef(null);
1509
1566
  const {
1510
1567
  lang = "en-US",
1511
1568
  interimResults = true,
@@ -1514,14 +1571,14 @@ function useVoice(config = {}, callbacks = {}) {
1514
1571
  autoStopAfterSilence
1515
1572
  } = config;
1516
1573
  const { onStart, onEnd, onResult, onError, onStateChange } = callbacks;
1517
- React.useEffect(() => {
1574
+ react.useEffect(() => {
1518
1575
  const SpeechRecognitionAPI = getSpeechRecognition();
1519
1576
  setIsAvailable(SpeechRecognitionAPI !== null);
1520
1577
  }, []);
1521
- React.useEffect(() => {
1578
+ react.useEffect(() => {
1522
1579
  onStateChange?.(voiceState);
1523
1580
  }, [voiceState, onStateChange]);
1524
- const requestPermissions = React.useCallback(async () => {
1581
+ const requestPermissions = react.useCallback(async () => {
1525
1582
  try {
1526
1583
  const result = await navigator.mediaDevices.getUserMedia({
1527
1584
  audio: true
@@ -1538,7 +1595,7 @@ function useVoice(config = {}, callbacks = {}) {
1538
1595
  };
1539
1596
  }
1540
1597
  }, []);
1541
- const getPermissions = React.useCallback(async () => {
1598
+ const getPermissions = react.useCallback(async () => {
1542
1599
  if (typeof navigator === "undefined" || !navigator.permissions) {
1543
1600
  return {
1544
1601
  granted: false,
@@ -1560,13 +1617,13 @@ function useVoice(config = {}, callbacks = {}) {
1560
1617
  };
1561
1618
  }
1562
1619
  }, []);
1563
- const clearAutoStopTimer = React.useCallback(() => {
1620
+ const clearAutoStopTimer = react.useCallback(() => {
1564
1621
  if (autoStopTimerRef.current) {
1565
1622
  clearTimeout(autoStopTimerRef.current);
1566
1623
  autoStopTimerRef.current = null;
1567
1624
  }
1568
1625
  }, []);
1569
- const resetAutoStopTimer = React.useCallback(() => {
1626
+ const resetAutoStopTimer = react.useCallback(() => {
1570
1627
  clearAutoStopTimer();
1571
1628
  if (autoStopAfterSilence && autoStopAfterSilence > 0) {
1572
1629
  autoStopTimerRef.current = setTimeout(() => {
@@ -1576,7 +1633,7 @@ function useVoice(config = {}, callbacks = {}) {
1576
1633
  }, autoStopAfterSilence);
1577
1634
  }
1578
1635
  }, [autoStopAfterSilence, clearAutoStopTimer, isRecording]);
1579
- const stopRecording = React.useCallback(() => {
1636
+ const stopRecording = react.useCallback(() => {
1580
1637
  if (recognitionRef.current) {
1581
1638
  try {
1582
1639
  recognitionRef.current.stop();
@@ -1588,7 +1645,7 @@ function useVoice(config = {}, callbacks = {}) {
1588
1645
  setIsRecording(false);
1589
1646
  setVoiceState("idle");
1590
1647
  }, [clearAutoStopTimer]);
1591
- const startRecording = React.useCallback(async () => {
1648
+ const startRecording = react.useCallback(async () => {
1592
1649
  const SpeechRecognitionAPI = getSpeechRecognition();
1593
1650
  if (!SpeechRecognitionAPI) {
1594
1651
  onError?.("Speech recognition not supported in this browser");
@@ -1678,15 +1735,15 @@ function useVoice(config = {}, callbacks = {}) {
1678
1735
  resetAutoStopTimer,
1679
1736
  clearAutoStopTimer
1680
1737
  ]);
1681
- const clearTranscript = React.useCallback(() => {
1738
+ const clearTranscript = react.useCallback(() => {
1682
1739
  setTranscribedText("");
1683
1740
  }, []);
1684
- const reset = React.useCallback(() => {
1741
+ const reset = react.useCallback(() => {
1685
1742
  stopRecording();
1686
1743
  setTranscribedText("");
1687
1744
  setVoiceState("idle");
1688
1745
  }, [stopRecording]);
1689
- React.useEffect(() => {
1746
+ react.useEffect(() => {
1690
1747
  return () => {
1691
1748
  if (recognitionRef.current) {
1692
1749
  try {
@@ -1826,9 +1883,9 @@ function buildContent(schema, values) {
1826
1883
  }
1827
1884
  return content;
1828
1885
  }
1829
- var PaymanChatContext = React.createContext(void 0);
1886
+ var PaymanChatContext = react.createContext(void 0);
1830
1887
  function usePaymanChat() {
1831
- const context = React.useContext(PaymanChatContext);
1888
+ const context = react.useContext(PaymanChatContext);
1832
1889
  if (!context) {
1833
1890
  throw new Error("usePaymanChat must be used within a PaymanChat component");
1834
1891
  }
@@ -2086,8 +2143,8 @@ function ImageLightbox({
2086
2143
  alt = "",
2087
2144
  onClose
2088
2145
  }) {
2089
- const [isMounted, setIsMounted] = React.useState(false);
2090
- const [isImageLoaded, setIsImageLoaded] = React.useState(false);
2146
+ const [isMounted, setIsMounted] = react.useState(false);
2147
+ const [isImageLoaded, setIsImageLoaded] = react.useState(false);
2091
2148
  const overlayStyle = {
2092
2149
  position: "fixed",
2093
2150
  inset: 0,
@@ -2108,14 +2165,14 @@ function ImageLightbox({
2108
2165
  justifyContent: "center",
2109
2166
  overflow: "hidden"
2110
2167
  };
2111
- React.useEffect(() => {
2168
+ react.useEffect(() => {
2112
2169
  setIsMounted(true);
2113
2170
  return () => setIsMounted(false);
2114
2171
  }, []);
2115
- React.useEffect(() => {
2172
+ react.useEffect(() => {
2116
2173
  setIsImageLoaded(false);
2117
2174
  }, [src]);
2118
- React.useEffect(() => {
2175
+ react.useEffect(() => {
2119
2176
  if (typeof document === "undefined") return;
2120
2177
  const previousOverflow = document.body.style.overflow;
2121
2178
  document.body.style.overflow = "hidden";
@@ -2123,7 +2180,7 @@ function ImageLightbox({
2123
2180
  document.body.style.overflow = previousOverflow;
2124
2181
  };
2125
2182
  }, []);
2126
- React.useEffect(() => {
2183
+ react.useEffect(() => {
2127
2184
  if (typeof document === "undefined") return;
2128
2185
  const handleKeyDown = (event) => {
2129
2186
  if (event.key === "Escape") {
@@ -2219,15 +2276,15 @@ function MarkdownImage({
2219
2276
  maxHeight: "18rem",
2220
2277
  objectFit: "contain"
2221
2278
  };
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(
2279
+ const [isLoaded, setIsLoaded] = react.useState(false);
2280
+ const [hasError, setHasError] = react.useState(false);
2281
+ const [isLightboxOpen, setIsLightboxOpen] = react.useState(false);
2282
+ const isUnresolvedRagImage = react.useMemo(
2226
2283
  () => src ? isUnresolvedRagImageSource(src) : false,
2227
2284
  [src]
2228
2285
  );
2229
2286
  const isResolvingRagImage = isResolving && isUnresolvedRagImage;
2230
- React.useEffect(() => {
2287
+ react.useEffect(() => {
2231
2288
  setIsLoaded(false);
2232
2289
  setHasError(false);
2233
2290
  setIsLightboxOpen(false);
@@ -2296,7 +2353,7 @@ function createMarkdownComponents(options = {}) {
2296
2353
  },
2297
2354
  pre: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "my-2 max-w-full overflow-x-auto rounded-lg", children }),
2298
2355
  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 }),
2356
+ ol: ({ children, start }) => /* @__PURE__ */ jsxRuntime.jsx("ol", { className: "mb-3 ml-4 list-decimal space-y-1 text-sm", start, children }),
2300
2357
  li: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("li", { className: "text-sm leading-relaxed", children }),
2301
2358
  h1: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "mt-4 mb-2 text-lg font-semibold first:mt-0", children }),
2302
2359
  h2: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "mt-3 mb-2 text-base font-semibold first:mt-0", children }),
@@ -2354,9 +2411,9 @@ function AgentMessage({
2354
2411
  const hasTraceData = !!(message.tracingData || message.executionId) && !isStreaming;
2355
2412
  const isCancelled = message.isCancelled ?? false;
2356
2413
  const currentExecutingStepId = message.currentExecutingStepId;
2357
- const [isStepsExpanded, setIsStepsExpanded] = React.useState(false);
2358
- const wasStreamingRef = React.useRef(isStreaming);
2359
- React.useEffect(() => {
2414
+ const [isStepsExpanded, setIsStepsExpanded] = react.useState(false);
2415
+ const wasStreamingRef = react.useRef(isStreaming);
2416
+ react.useEffect(() => {
2360
2417
  if (isStreaming && hasSteps) {
2361
2418
  setIsStepsExpanded(true);
2362
2419
  }
@@ -2365,7 +2422,7 @@ function AgentMessage({
2365
2422
  }
2366
2423
  wasStreamingRef.current = isStreaming;
2367
2424
  }, [isStreaming, hasSteps]);
2368
- const totalElapsedMs = hasSteps ? message.steps.reduce((sum, step) => sum + (step.elapsedMs || 0), 0) : 0;
2425
+ const totalElapsedMs = hasSteps ? message.steps.reduce((sum, step2) => sum + (step2.elapsedMs || 0), 0) : 0;
2369
2426
  const currentMessage = message.currentMessage;
2370
2427
  const rawContent = message.streamingContent || message.content || "";
2371
2428
  const content = rawContent.replace(/\\n/g, "\n");
@@ -2373,13 +2430,13 @@ function AgentMessage({
2373
2430
  const completedWithNoContent = !isStreaming && !isCancelled && content.length === 0 && (message.streamProgress === "completed" || message.streamProgress === "error");
2374
2431
  const conflictErrorMessage = getConflictErrorMessage(message.errorDetails);
2375
2432
  const isError = !!conflictErrorMessage || (isFriendlyWorkflowError(message.errorDetails) || looksLikeRawError(content)) && !hasMeaningfulContent || completedWithNoContent;
2376
- const currentStep = React.useMemo(
2433
+ const currentStep = react.useMemo(
2377
2434
  () => message.steps?.find(
2378
2435
  (s) => s.id === currentExecutingStepId && s.status === "in_progress"
2379
2436
  ),
2380
2437
  [message.steps, currentExecutingStepId]
2381
2438
  );
2382
- const markdownRenderers = React.useMemo(
2439
+ const markdownRenderers = react.useMemo(
2383
2440
  () => createMarkdownComponents({
2384
2441
  isResolvingImages: message.isResolvingImages
2385
2442
  }),
@@ -2393,25 +2450,25 @@ function AgentMessage({
2393
2450
  }
2394
2451
  return `${count} ${stepWord} completed`;
2395
2452
  };
2396
- const renderStepIcon = (step, isCurrentlyExecuting) => {
2453
+ const renderStepIcon = (step2, isCurrentlyExecuting) => {
2397
2454
  const wrapper = "h-4 w-4 flex items-center justify-center shrink-0";
2398
2455
  if (isCurrentlyExecuting)
2399
2456
  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)
2457
+ if (step2.status === "pending" && isCancelled)
2401
2458
  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")
2459
+ if (step2.status === "pending" || step2.status === "in_progress")
2403
2460
  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")
2461
+ if (step2.status === "completed")
2405
2462
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: wrapper, children: /* @__PURE__ */ jsxRuntime.jsx(
2406
2463
  lucideReact.Check,
2407
2464
  {
2408
2465
  className: cn(
2409
2466
  "h-3.5 w-3.5",
2410
- step.eventType === "USER_ACTION_SUCCESS" ? "payman-agent-step-icon--success" : "payman-agent-step-icon--success-dim"
2467
+ step2.eventType === "USER_ACTION_SUCCESS" ? "payman-agent-step-icon--success" : "payman-agent-step-icon--success-dim"
2411
2468
  )
2412
2469
  }
2413
2470
  ) });
2414
- if (step.status === "error")
2471
+ if (step2.status === "error")
2415
2472
  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
2473
  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
2474
  };
@@ -2423,38 +2480,38 @@ function AgentMessage({
2423
2480
  exit: { height: 0, opacity: 0 },
2424
2481
  transition: { duration: 0.2, ease: "easeInOut" },
2425
2482
  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;
2483
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pt-1.5", children: message.steps.map((step2) => {
2484
+ const isCurrentlyExecuting = step2.id === currentExecutingStepId && step2.status === "in_progress" && isStreaming && !isCancelled;
2485
+ const hasTime = step2.elapsedMs != null && step2.elapsedMs > 0;
2429
2486
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-1.5", children: [
2430
2487
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-1.5 items-start", children: [
2431
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-px", children: renderStepIcon(step, isCurrentlyExecuting) }),
2488
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-px", children: renderStepIcon(step2, isCurrentlyExecuting) }),
2432
2489
  /* @__PURE__ */ jsxRuntime.jsx(
2433
2490
  "span",
2434
2491
  {
2435
2492
  className: cn(
2436
2493
  "text-xs leading-relaxed min-w-0 break-words",
2437
2494
  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"
2495
+ !isCurrentlyExecuting && step2.status === "error" && "payman-agent-step-text--error",
2496
+ !isCurrentlyExecuting && step2.eventType === "USER_ACTION_SUCCESS" && "payman-agent-step-text--success",
2497
+ !isCurrentlyExecuting && step2.status === "completed" && "payman-agent-step-text--completed",
2498
+ !isCurrentlyExecuting && step2.status === "pending" && "payman-agent-step-text--pending",
2499
+ !isCurrentlyExecuting && step2.status === "in_progress" && "payman-agent-step-text--in-progress"
2443
2500
  ),
2444
- children: step.message
2501
+ children: step2.message
2445
2502
  }
2446
2503
  )
2447
2504
  ] }),
2448
2505
  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
2506
  /* @__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) })
2507
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-mono payman-agent-step-time-text", children: formatElapsedTime(step2.elapsedMs) })
2451
2508
  ] }) })
2452
- ] }, step.id);
2509
+ ] }, step2.id);
2453
2510
  }) })
2454
2511
  }
2455
2512
  ) });
2456
- const stepsToggleRef = React.useRef(null);
2457
- const handleStepsToggle = React.useCallback(() => {
2513
+ const stepsToggleRef = react.useRef(null);
2514
+ const handleStepsToggle = react.useCallback(() => {
2458
2515
  setIsStepsExpanded((prev) => {
2459
2516
  const next = !prev;
2460
2517
  if (next) {
@@ -2782,23 +2839,23 @@ function MessageList({
2782
2839
  isLoadingMoreMessages = false,
2783
2840
  hasMoreMessages = false
2784
2841
  }) {
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(() => {
2842
+ const scrollRef = react.useRef(null);
2843
+ const isNearBottomRef = react.useRef(true);
2844
+ const [showScrollBtn, setShowScrollBtn] = react.useState(false);
2845
+ const prevMessageCountRef = react.useRef(messages.length);
2846
+ const scrollHeightBeforePrependRef = react.useRef(null);
2847
+ const firstMessageIdRef = react.useRef(messages[0]?.id);
2848
+ const getDistanceFromBottom = react.useCallback(() => {
2792
2849
  const el = scrollRef.current;
2793
2850
  if (!el) return 0;
2794
2851
  return el.scrollHeight - el.scrollTop - el.clientHeight;
2795
2852
  }, []);
2796
- const scrollToBottom = React.useCallback((behavior = "smooth") => {
2853
+ const scrollToBottom = react.useCallback((behavior = "smooth") => {
2797
2854
  const el = scrollRef.current;
2798
2855
  if (!el) return;
2799
2856
  el.scrollTo({ top: el.scrollHeight, behavior });
2800
2857
  }, []);
2801
- const handleScroll = React.useCallback(() => {
2858
+ const handleScroll = react.useCallback(() => {
2802
2859
  const el = scrollRef.current;
2803
2860
  if (!el) return;
2804
2861
  const distance = getDistanceFromBottom();
@@ -2810,7 +2867,7 @@ function MessageList({
2810
2867
  onLoadMoreMessages();
2811
2868
  }
2812
2869
  }, [getDistanceFromBottom, hasMoreMessages, isLoadingMoreMessages, onLoadMoreMessages]);
2813
- React.useLayoutEffect(() => {
2870
+ react.useLayoutEffect(() => {
2814
2871
  const el = scrollRef.current;
2815
2872
  const prevHeight = scrollHeightBeforePrependRef.current;
2816
2873
  const newFirstId = messages[0]?.id;
@@ -2820,25 +2877,25 @@ function MessageList({
2820
2877
  }
2821
2878
  firstMessageIdRef.current = newFirstId;
2822
2879
  }, [messages]);
2823
- React.useEffect(() => {
2880
+ react.useEffect(() => {
2824
2881
  const prevCount = prevMessageCountRef.current;
2825
2882
  prevMessageCountRef.current = messages.length;
2826
2883
  if (messages.length > prevCount && isNearBottomRef.current) {
2827
2884
  requestAnimationFrame(() => scrollToBottom());
2828
2885
  }
2829
2886
  }, [messages.length, scrollToBottom]);
2830
- React.useEffect(() => {
2887
+ react.useEffect(() => {
2831
2888
  const lastMsg = messages[messages.length - 1];
2832
2889
  if (!lastMsg?.isStreaming) return;
2833
2890
  if (!isNearBottomRef.current) return;
2834
2891
  requestAnimationFrame(() => scrollToBottom());
2835
2892
  });
2836
- React.useEffect(() => {
2893
+ react.useEffect(() => {
2837
2894
  if (messages.length > 0) {
2838
2895
  setTimeout(() => scrollToBottom("instant"), 50);
2839
2896
  }
2840
2897
  }, []);
2841
- React.useEffect(() => {
2898
+ react.useEffect(() => {
2842
2899
  const handleStepsToggle = () => {
2843
2900
  requestAnimationFrame(() => {
2844
2901
  requestAnimationFrame(() => {
@@ -2855,7 +2912,7 @@ function MessageList({
2855
2912
  return () => el.removeEventListener("payman-steps-toggle", handleStepsToggle);
2856
2913
  }
2857
2914
  }, [getDistanceFromBottom, scrollToBottom]);
2858
- const handleScrollToBottom = React.useCallback(() => {
2915
+ const handleScrollToBottom = react.useCallback(() => {
2859
2916
  scrollToBottom();
2860
2917
  }, [scrollToBottom]);
2861
2918
  if (isLoading) {
@@ -2988,7 +3045,7 @@ function ResetSessionConfirmModal({
2988
3045
  onClose,
2989
3046
  onConfirm
2990
3047
  }) {
2991
- const handleKeyDown = React.useCallback(
3048
+ const handleKeyDown = react.useCallback(
2992
3049
  (event) => {
2993
3050
  if (event.key === "Escape") {
2994
3051
  onClose();
@@ -2996,7 +3053,7 @@ function ResetSessionConfirmModal({
2996
3053
  },
2997
3054
  [onClose]
2998
3055
  );
2999
- React.useEffect(() => {
3056
+ react.useEffect(() => {
3000
3057
  if (!isOpen || typeof document === "undefined") return;
3001
3058
  document.addEventListener("keydown", handleKeyDown);
3002
3059
  const previousOverflow = document.body.style.overflow;
@@ -3102,14 +3159,14 @@ function UserMessageV2({
3102
3159
  retryDisabled = false,
3103
3160
  actions
3104
3161
  }) {
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);
3162
+ const [copied, setCopied] = react.useState(false);
3163
+ const [toast, setToast] = react.useState(null);
3164
+ const copyResetTimerRef = react.useRef(null);
3165
+ const toastTimerRef = react.useRef(null);
3109
3166
  const showCopyAction = actions?.copy ?? true;
3110
3167
  const showEditAction = actions?.edit ?? false;
3111
3168
  const showRetryAction = actions?.retry ?? false;
3112
- React.useEffect(() => {
3169
+ react.useEffect(() => {
3113
3170
  return () => {
3114
3171
  if (copyResetTimerRef.current) clearTimeout(copyResetTimerRef.current);
3115
3172
  if (toastTimerRef.current) clearTimeout(toastTimerRef.current);
@@ -3265,18 +3322,18 @@ function MarkdownImageV2({
3265
3322
  onImageClick
3266
3323
  }) {
3267
3324
  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(
3325
+ const [isVisible, setIsVisible] = react.useState(cachedAlready);
3326
+ const [isLoaded, setIsLoaded] = react.useState(cachedAlready);
3327
+ const [hasError, setHasError] = react.useState(false);
3328
+ const [retryCount, setRetryCount] = react.useState(0);
3329
+ const sentinelRef = react.useRef(null);
3330
+ const prevLoadedRef = react.useRef(cachedAlready);
3331
+ const isUnresolvedRag = react.useMemo(
3275
3332
  () => src ? isUnresolvedRagImageSource2(src) : false,
3276
3333
  [src]
3277
3334
  );
3278
3335
  const isResolvingRag = Boolean(isResolving && isUnresolvedRag);
3279
- React.useEffect(() => {
3336
+ react.useEffect(() => {
3280
3337
  if (src && loadedImageCache.has(src)) {
3281
3338
  setIsLoaded(true);
3282
3339
  setIsVisible(true);
@@ -3285,7 +3342,7 @@ function MarkdownImageV2({
3285
3342
  setHasError(false);
3286
3343
  setRetryCount(0);
3287
3344
  }, [src]);
3288
- React.useEffect(() => {
3345
+ react.useEffect(() => {
3289
3346
  const el = sentinelRef.current;
3290
3347
  if (!el || !src) return;
3291
3348
  const rect = el.getBoundingClientRect();
@@ -3406,92 +3463,13 @@ function MarkdownImageV2({
3406
3463
  }
3407
3464
  ) });
3408
3465
  }
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) {
3466
+ function buildComponents(onImageClick, isResolvingRef) {
3483
3467
  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
- },
3468
+ p: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("p", { children }),
3491
3469
  code: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("code", { children }),
3492
3470
  pre: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "payman-v2-markdown-pre", children: /* @__PURE__ */ jsxRuntime.jsx("pre", { children }) }),
3493
3471
  ul: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("ul", { children }),
3494
- ol: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("ol", { children }),
3472
+ ol: ({ children, start }) => /* @__PURE__ */ jsxRuntime.jsx("ol", { start, children }),
3495
3473
  li: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("li", { children }),
3496
3474
  h1: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("h1", { children }),
3497
3475
  h2: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("h2", { children }),
@@ -3523,15 +3501,10 @@ function MarkdownRendererV2({
3523
3501
  isResolvingImages,
3524
3502
  onImageClick
3525
3503
  }) {
3526
- const isResolvingRef = React.useRef(isResolvingImages);
3504
+ const isResolvingRef = react.useRef(isResolvingImages);
3527
3505
  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),
3506
+ const components = react.useMemo(
3507
+ () => buildComponents(onImageClick, isResolvingRef),
3535
3508
  [onImageClick]
3536
3509
  );
3537
3510
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -3588,14 +3561,14 @@ function FeedbackReasonModal({
3588
3561
  onClose,
3589
3562
  onSubmit
3590
3563
  }) {
3591
- const [reason, setReason] = React.useState(
3564
+ const [reason, setReason] = react.useState(
3592
3565
  NEGATIVE_FEEDBACK_REASONS[0].value
3593
3566
  );
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(() => {
3567
+ const [details, setDetails] = react.useState("");
3568
+ const [submitting, setSubmitting] = react.useState(false);
3569
+ const [error, setError] = react.useState(null);
3570
+ const [reasonOpen, setReasonOpen] = react.useState(false);
3571
+ react.useEffect(() => {
3599
3572
  if (open) {
3600
3573
  setReason(NEGATIVE_FEEDBACK_REASONS[0].value);
3601
3574
  setDetails("");
@@ -3604,7 +3577,7 @@ function FeedbackReasonModal({
3604
3577
  setReasonOpen(false);
3605
3578
  }
3606
3579
  }, [open]);
3607
- const handleKeyDown = React.useCallback(
3580
+ const handleKeyDown = react.useCallback(
3608
3581
  (event) => {
3609
3582
  if (event.key !== "Escape") return;
3610
3583
  if (reasonOpen) {
@@ -3615,7 +3588,7 @@ function FeedbackReasonModal({
3615
3588
  },
3616
3589
  [onClose, reasonOpen]
3617
3590
  );
3618
- React.useEffect(() => {
3591
+ react.useEffect(() => {
3619
3592
  if (!open || typeof document === "undefined") return;
3620
3593
  document.addEventListener("keydown", handleKeyDown);
3621
3594
  const previousOverflow = document.body.style.overflow;
@@ -3797,6 +3770,87 @@ function FeedbackReasonModal({
3797
3770
  }
3798
3771
  ) : null });
3799
3772
  }
3773
+
3774
+ // src/utils/markdownImageToken.ts
3775
+ function step(text, i) {
3776
+ if (text[i] === "\\" && i + 1 < text.length) return i + 2;
3777
+ return i + 1;
3778
+ }
3779
+ function scanAltText(text, start) {
3780
+ let i = start;
3781
+ while (i < text.length) {
3782
+ if (text[i] === "]") return i;
3783
+ i = step(text, i);
3784
+ }
3785
+ return -1;
3786
+ }
3787
+ function scanOptionalTitle(text, start) {
3788
+ let i = start;
3789
+ while (i < text.length && /[\t\n ]/.test(text[i])) i++;
3790
+ if (i >= text.length) return i;
3791
+ const quote = text[i];
3792
+ if (quote !== '"' && quote !== "'") return i;
3793
+ i++;
3794
+ while (i < text.length) {
3795
+ if (text[i] === quote) return i + 1;
3796
+ i = step(text, i);
3797
+ }
3798
+ return -1;
3799
+ }
3800
+ function scanAngleBracketDestination(text, start) {
3801
+ let i = start + 1;
3802
+ while (i < text.length) {
3803
+ if (text[i] === ">") return i + 1;
3804
+ i = step(text, i);
3805
+ }
3806
+ return -1;
3807
+ }
3808
+ function scanRawDestination(text, start) {
3809
+ let i = start;
3810
+ let depth = 1;
3811
+ while (i < text.length) {
3812
+ const char = text[i];
3813
+ if (char === "\\") {
3814
+ if (i + 1 >= text.length) return -1;
3815
+ i += 2;
3816
+ continue;
3817
+ }
3818
+ if (char === "(") depth++;
3819
+ else if (char === ")") {
3820
+ depth--;
3821
+ if (depth === 0) return i + 1;
3822
+ }
3823
+ i++;
3824
+ }
3825
+ return -1;
3826
+ }
3827
+ function completeMarkdownImageTokenLength(text) {
3828
+ if (!text.startsWith("![")) return 0;
3829
+ const altEnd = scanAltText(text, 2);
3830
+ if (altEnd === -1 || altEnd + 1 >= text.length || text[altEnd + 1] !== "(") {
3831
+ return 0;
3832
+ }
3833
+ let i = altEnd + 2;
3834
+ if (i >= text.length) return 0;
3835
+ if (text[i] === "<") {
3836
+ i = scanAngleBracketDestination(text, i);
3837
+ if (i === -1) return 0;
3838
+ i = scanOptionalTitle(text, i);
3839
+ if (i === -1 || i >= text.length || text[i] !== ")") return 0;
3840
+ return i + 1;
3841
+ }
3842
+ i = scanRawDestination(text, i);
3843
+ return i === -1 ? 0 : i;
3844
+ }
3845
+ function stripIncompleteImageToken(text) {
3846
+ const lastBang = text.lastIndexOf("![");
3847
+ if (lastBang === -1) return text;
3848
+ const suffix = text.slice(lastBang);
3849
+ if (completeMarkdownImageTokenLength(suffix) > 0) return text;
3850
+ return text.slice(0, lastBang);
3851
+ }
3852
+
3853
+ // src/components/v2/useTypingEffect.ts
3800
3854
  var RESPONSE_SPEED = {
3801
3855
  normal: [2, 4],
3802
3856
  fast: 1,
@@ -3804,7 +3858,6 @@ var RESPONSE_SPEED = {
3804
3858
  newline: [4, 6],
3805
3859
  idle: 15
3806
3860
  };
3807
- var MARKDOWN_IMAGE_REGEX = /^!\[[^\]]*\]\([^)]*\)/;
3808
3861
  function charDelay(char, speed, multiplier) {
3809
3862
  const raw = (() => {
3810
3863
  if (char === "*") return speed.fast;
@@ -3819,17 +3872,17 @@ function charDelay(char, speed, multiplier) {
3819
3872
  function useTypingEffect(targetText, enabled, speed = RESPONSE_SPEED, initialDisplayedText, speedMultiplier = 1) {
3820
3873
  const instant = speedMultiplier === 0;
3821
3874
  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);
3875
+ const [displayedText, setDisplayedText] = react.useState("");
3876
+ const displayedRef = react.useRef("");
3877
+ const targetRef = react.useRef(targetText);
3878
+ const enabledRef = react.useRef(enabled);
3879
+ const initialDisplayedRef = react.useRef(initialDisplayedText);
3880
+ const timerRef = react.useRef(null);
3881
+ const runningRef = react.useRef(false);
3829
3882
  targetRef.current = targetText;
3830
3883
  enabledRef.current = enabled;
3831
3884
  initialDisplayedRef.current = initialDisplayedText;
3832
- React.useEffect(() => {
3885
+ react.useEffect(() => {
3833
3886
  if (!enabled || instant) {
3834
3887
  if (timerRef.current) {
3835
3888
  clearTimeout(timerRef.current);
@@ -3863,9 +3916,9 @@ function useTypingEffect(targetText, enabled, speed = RESPONSE_SPEED, initialDis
3863
3916
  }
3864
3917
  if (displayedRef.current.length < targetRef.current.length) {
3865
3918
  const remaining = targetRef.current.slice(displayedRef.current.length);
3866
- const imgMatch = MARKDOWN_IMAGE_REGEX.exec(remaining);
3867
- if (imgMatch) {
3868
- displayedRef.current += imgMatch[0];
3919
+ const imageTokenLength = completeMarkdownImageTokenLength(remaining);
3920
+ if (imageTokenLength > 0) {
3921
+ displayedRef.current += remaining.slice(0, imageTokenLength);
3869
3922
  setDisplayedText(displayedRef.current);
3870
3923
  timerRef.current = setTimeout(tick, 0);
3871
3924
  return;
@@ -3894,13 +3947,6 @@ function useTypingEffect(targetText, enabled, speed = RESPONSE_SPEED, initialDis
3894
3947
  isTyping
3895
3948
  };
3896
3949
  }
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
3950
  function getFeedbackState(message) {
3905
3951
  const feedback = message.feedback;
3906
3952
  if (feedback === "up" || feedback === "down") return feedback;
@@ -3919,26 +3965,26 @@ function AssistantMessageV2({
3919
3965
  actions,
3920
3966
  typingSpeed = 4
3921
3967
  }) {
3922
- const [copied, setCopied] = React.useState(false);
3923
- const [activeFeedback, setActiveFeedback] = React.useState(
3968
+ const [copied, setCopied] = react.useState(false);
3969
+ const [activeFeedback, setActiveFeedback] = react.useState(
3924
3970
  () => getFeedbackState(message)
3925
3971
  );
3926
- const [reasonModalOpen, setReasonModalOpen] = React.useState(false);
3972
+ const [reasonModalOpen, setReasonModalOpen] = react.useState(false);
3927
3973
  const canSubmitFeedback = !!onSubmitFeedback && !!message.executionId;
3928
- const [toast, setToast] = React.useState(null);
3929
- const copyResetTimerRef = React.useRef(null);
3930
- const toastTimerRef = React.useRef(null);
3974
+ const [toast, setToast] = react.useState(null);
3975
+ const copyResetTimerRef = react.useRef(null);
3976
+ const toastTimerRef = react.useRef(null);
3931
3977
  const showCopyAction = actions?.copy ?? true;
3932
3978
  const showTraceAction = (actions?.trace ?? true) && !!onExecutionTraceClick;
3933
3979
  const showThumbsUp = actions?.thumbsUp ?? true;
3934
3980
  const showThumbsDown = actions?.thumbsDown ?? true;
3935
3981
  const hydratedFeedback = message.feedback;
3936
- const hasEverStreamed = React.useRef(!!message.isStreaming);
3982
+ const hasEverStreamed = react.useRef(!!message.isStreaming);
3937
3983
  if (message.isStreaming) hasEverStreamed.current = true;
3938
- React.useEffect(() => {
3984
+ react.useEffect(() => {
3939
3985
  setActiveFeedback(getFeedbackState(message));
3940
3986
  }, [hydratedFeedback, message.id]);
3941
- React.useEffect(() => {
3987
+ react.useEffect(() => {
3942
3988
  return () => {
3943
3989
  if (copyResetTimerRef.current) clearTimeout(copyResetTimerRef.current);
3944
3990
  if (toastTimerRef.current) clearTimeout(toastTimerRef.current);
@@ -4232,10 +4278,10 @@ function OtpInputV2({
4232
4278
  disabled = false,
4233
4279
  error = false
4234
4280
  }) {
4235
- const inputRefs = React.useRef([]);
4281
+ const inputRefs = react.useRef([]);
4236
4282
  const safeMaxLength = Number.isInteger(maxLength) && maxLength > 0 ? Math.min(maxLength, MAX_SUPPORTED_LENGTH) : DEFAULT_MAX_LENGTH;
4237
4283
  const digits = value.split("").concat(Array(safeMaxLength).fill("")).slice(0, safeMaxLength);
4238
- React.useEffect(() => {
4284
+ react.useEffect(() => {
4239
4285
  if (disabled) return;
4240
4286
  const timer = window.setTimeout(() => {
4241
4287
  inputRefs.current[0]?.focus();
@@ -4334,31 +4380,31 @@ function VerificationInline({
4334
4380
  onResend
4335
4381
  }) {
4336
4382
  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);
4383
+ const codeLen = react.useMemo(() => codeLengthFromSchema(prompt), [prompt]);
4384
+ const [code, setCode] = react.useState("");
4385
+ const [errored, setErrored] = react.useState(false);
4386
+ const [resendSec, setResendSec] = react.useState(0);
4387
+ const [hiddenAfterResend, setHiddenAfterResend] = react.useState(false);
4388
+ const lastSubmittedRef = react.useRef(null);
4389
+ const resendTimerRef = react.useRef(void 0);
4344
4390
  const status = prompt.status;
4345
4391
  const busy = status === "submitting";
4346
4392
  const stale = status === "stale";
4347
4393
  const locked = busy || stale || expired;
4348
- React.useEffect(() => {
4394
+ react.useEffect(() => {
4349
4395
  if (prompt.subAction === "SubmissionInvalid") {
4350
4396
  setErrored(true);
4351
4397
  setCode("");
4352
4398
  lastSubmittedRef.current = null;
4353
4399
  }
4354
4400
  }, [prompt.subAction, prompt.userActionId]);
4355
- React.useEffect(() => {
4401
+ react.useEffect(() => {
4356
4402
  setHiddenAfterResend(false);
4357
4403
  }, [prompt.expirySeconds, prompt.message, prompt.subAction, prompt.userActionId]);
4358
- React.useEffect(() => {
4404
+ react.useEffect(() => {
4359
4405
  if (code.length < codeLen) lastSubmittedRef.current = null;
4360
4406
  }, [code, codeLen]);
4361
- const doSubmit = React.useCallback(
4407
+ const doSubmit = react.useCallback(
4362
4408
  (value) => {
4363
4409
  if (locked || !value) return;
4364
4410
  if (lastSubmittedRef.current === value) return;
@@ -4370,20 +4416,20 @@ function VerificationInline({
4370
4416
  },
4371
4417
  [locked, onSubmit, prompt.userActionId]
4372
4418
  );
4373
- React.useEffect(() => {
4419
+ react.useEffect(() => {
4374
4420
  if (!isNumeric || locked) return;
4375
4421
  if (code.length === codeLen && /^\d+$/.test(code)) {
4376
4422
  doSubmit(code);
4377
4423
  }
4378
4424
  }, [code, codeLen, doSubmit, isNumeric, locked]);
4379
- React.useEffect(() => {
4425
+ react.useEffect(() => {
4380
4426
  return () => {
4381
4427
  if (typeof resendTimerRef.current === "number") {
4382
4428
  window.clearInterval(resendTimerRef.current);
4383
4429
  }
4384
4430
  };
4385
4431
  }, []);
4386
- const startResendCooldown = React.useCallback(() => {
4432
+ const startResendCooldown = react.useCallback(() => {
4387
4433
  setResendSec(RESEND_COOLDOWN_S);
4388
4434
  if (typeof resendTimerRef.current === "number") {
4389
4435
  window.clearInterval(resendTimerRef.current);
@@ -4401,7 +4447,7 @@ function VerificationInline({
4401
4447
  });
4402
4448
  }, 1e3);
4403
4449
  }, []);
4404
- const handleResend = React.useCallback(async () => {
4450
+ const handleResend = react.useCallback(async () => {
4405
4451
  if (locked || resendSec > 0) return;
4406
4452
  setErrored(false);
4407
4453
  setCode("");
@@ -4414,7 +4460,7 @@ function VerificationInline({
4414
4460
  setHiddenAfterResend(false);
4415
4461
  }
4416
4462
  }, [locked, onResend, prompt.userActionId, resendSec, startResendCooldown]);
4417
- const handleCancel = React.useCallback(() => {
4463
+ const handleCancel = react.useCallback(() => {
4418
4464
  if (busy) return;
4419
4465
  void onCancel(prompt.userActionId);
4420
4466
  }, [busy, onCancel, prompt.userActionId]);
@@ -4504,13 +4550,13 @@ function SchemaFormInline({
4504
4550
  onCancel
4505
4551
  }) {
4506
4552
  const schema = prompt.requestedSchema;
4507
- const fields = React.useMemo(() => renderableFields(schema), [schema]);
4508
- const [values, setValues] = React.useState(() => {
4553
+ const fields = react.useMemo(() => renderableFields(schema), [schema]);
4554
+ const [values, setValues] = react.useState(() => {
4509
4555
  const init2 = {};
4510
4556
  for (const [key, field] of fields) init2[key] = defaultValueFor(field);
4511
4557
  return init2;
4512
4558
  });
4513
- const [errors, setErrors] = React.useState({});
4559
+ const [errors, setErrors] = react.useState({});
4514
4560
  const status = prompt.status;
4515
4561
  const busy = status === "submitting";
4516
4562
  const stale = status === "stale";
@@ -4650,14 +4696,15 @@ function NotificationInline({ notification, onDismiss }) {
4650
4696
  ] });
4651
4697
  }
4652
4698
  function useExpiryCountdown(prompt) {
4653
- 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(() => {
4656
- if (initial === void 0) {
4699
+ const deadlineMs = typeof prompt.expiresAt === "number" && prompt.expiresAt > 0 ? prompt.expiresAt : typeof prompt.expirySeconds === "number" && prompt.expirySeconds > 0 ? Date.now() + Math.floor(prompt.expirySeconds) * 1e3 : void 0;
4700
+ const [secondsLeft, setSecondsLeft] = react.useState(
4701
+ () => deadlineMs !== void 0 ? Math.max(0, Math.ceil((deadlineMs - Date.now()) / 1e3)) : void 0
4702
+ );
4703
+ react.useEffect(() => {
4704
+ if (deadlineMs === void 0) {
4657
4705
  setSecondsLeft(void 0);
4658
4706
  return;
4659
4707
  }
4660
- const deadlineMs = Date.now() + initial * 1e3;
4661
4708
  let intervalId;
4662
4709
  const remaining = () => Math.max(0, Math.ceil((deadlineMs - Date.now()) / 1e3));
4663
4710
  const sync = () => {
@@ -4679,8 +4726,8 @@ function useExpiryCountdown(prompt) {
4679
4726
  window.removeEventListener("focus", sync);
4680
4727
  window.removeEventListener("pageshow", sync);
4681
4728
  };
4682
- }, [prompt.userActionId, prompt.subAction, initial]);
4683
- const expired = initial !== void 0 && secondsLeft === 0;
4729
+ }, [prompt.userActionId, prompt.subAction, deadlineMs]);
4730
+ const expired = deadlineMs !== void 0 && (getUserActionSecondsLeft(prompt) ?? secondsLeft ?? 0) <= 0;
4684
4731
  return [secondsLeft, expired];
4685
4732
  }
4686
4733
  function UserActionInline({
@@ -4691,7 +4738,7 @@ function UserActionInline({
4691
4738
  onExpired
4692
4739
  }) {
4693
4740
  const [secondsLeft, expired] = useExpiryCountdown(prompt);
4694
- React.useEffect(() => {
4741
+ react.useEffect(() => {
4695
4742
  if (expired && prompt.kind !== "notification") onExpired?.();
4696
4743
  }, [expired, onExpired, prompt.kind]);
4697
4744
  let body;
@@ -4754,7 +4801,7 @@ function getPromptViewKey(prompt) {
4754
4801
  prompt.message ?? ""
4755
4802
  ].join(PROMPT_KEY_SEPARATOR);
4756
4803
  }
4757
- var MessageListV2 = React.forwardRef(
4804
+ var MessageListV2 = react.forwardRef(
4758
4805
  function MessageListV22({
4759
4806
  messages,
4760
4807
  isStreaming = false,
@@ -4774,25 +4821,25 @@ var MessageListV2 = React.forwardRef(
4774
4821
  onSubmitFeedback,
4775
4822
  typingSpeed = 4
4776
4823
  }, ref) {
4777
- const noop = React.useCallback(async () => {
4824
+ const noop = react.useCallback(async () => {
4778
4825
  }, []);
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(() => {
4826
+ const scrollRef = react.useRef(null);
4827
+ const scrollInnerRef = react.useRef(null);
4828
+ const isNearBottomRef = react.useRef(true);
4829
+ const [showScrollBtn, setShowScrollBtn] = react.useState(false);
4830
+ const [expiredPromptViewState, setExpiredPromptViewState] = react.useState({});
4831
+ const expiredUserActionIdsRef = react.useRef(/* @__PURE__ */ new Set());
4832
+ const prevCountRef = react.useRef(messages.length);
4833
+ const pauseStickUntilUserMessageRef = react.useRef(false);
4834
+ const followingBottomRef = react.useRef(true);
4835
+ const lastPinAtRef = react.useRef(0);
4836
+ const prevScrollTopRef = react.useRef(0);
4837
+ const getDistanceFromBottom = react.useCallback(() => {
4791
4838
  const el = scrollRef.current;
4792
4839
  if (!el) return 0;
4793
4840
  return el.scrollHeight - el.scrollTop - el.clientHeight;
4794
4841
  }, []);
4795
- const messageActivityFingerprint = React.useMemo(() => {
4842
+ const messageActivityFingerprint = react.useMemo(() => {
4796
4843
  const last = messages[messages.length - 1];
4797
4844
  const promptFingerprint = (userActionPrompts ?? []).map((prompt) => `${getPromptViewKey(prompt)}:${prompt.status}`).join(PROMPT_KEY_SEPARATOR);
4798
4845
  const notificationFingerprint = (notifications ?? []).map((notification) => notification.id).join(PROMPT_KEY_SEPARATOR);
@@ -4818,7 +4865,7 @@ var MessageListV2 = React.forwardRef(
4818
4865
  notificationFingerprint
4819
4866
  ].join(PROMPT_KEY_SEPARATOR);
4820
4867
  }, [isStreaming, messages, notifications, userActionPrompts]);
4821
- const handleUserActionExpired = React.useCallback(
4868
+ const handleUserActionExpired = react.useCallback(
4822
4869
  (promptKey, userActionId) => {
4823
4870
  setExpiredPromptViewState((prev) => {
4824
4871
  if (prev[promptKey]) return prev;
@@ -4835,7 +4882,7 @@ var MessageListV2 = React.forwardRef(
4835
4882
  },
4836
4883
  [messageActivityFingerprint, onExpireUserAction]
4837
4884
  );
4838
- React.useEffect(() => {
4885
+ react.useEffect(() => {
4839
4886
  setExpiredPromptViewState((prev) => {
4840
4887
  let changed = false;
4841
4888
  const next = {};
@@ -4850,7 +4897,7 @@ var MessageListV2 = React.forwardRef(
4850
4897
  return changed ? next : prev;
4851
4898
  });
4852
4899
  }, [messageActivityFingerprint]);
4853
- React.useEffect(() => {
4900
+ react.useEffect(() => {
4854
4901
  const livePromptKeys = new Set((userActionPrompts ?? []).map(getPromptViewKey));
4855
4902
  const liveUserActionIds = new Set((userActionPrompts ?? []).map((p) => p.userActionId));
4856
4903
  for (const userActionId of expiredUserActionIdsRef.current) {
@@ -4871,21 +4918,21 @@ var MessageListV2 = React.forwardRef(
4871
4918
  return changed ? next : prev;
4872
4919
  });
4873
4920
  }, [userActionPrompts]);
4874
- const visibleUserActionPrompts = React.useMemo(
4921
+ const visibleUserActionPrompts = react.useMemo(
4875
4922
  () => userActionPrompts?.filter((prompt) => {
4876
4923
  const promptKey = getPromptViewKey(prompt);
4877
4924
  return !expiredPromptViewState[promptKey]?.hidden;
4878
4925
  }),
4879
4926
  [expiredPromptViewState, userActionPrompts]
4880
4927
  );
4881
- const pinToBottom = React.useCallback((behavior = "instant") => {
4928
+ const pinToBottom = react.useCallback((behavior = "instant") => {
4882
4929
  const el = scrollRef.current;
4883
4930
  if (!el) return;
4884
4931
  lastPinAtRef.current = performance.now();
4885
4932
  el.scrollTo({ top: el.scrollHeight, behavior });
4886
4933
  prevScrollTopRef.current = el.scrollHeight;
4887
4934
  }, []);
4888
- const scrollToBottom = React.useCallback(
4935
+ const scrollToBottom = react.useCallback(
4889
4936
  (behavior = "smooth") => {
4890
4937
  const el = scrollRef.current;
4891
4938
  if (!el) return;
@@ -4895,7 +4942,7 @@ var MessageListV2 = React.forwardRef(
4895
4942
  },
4896
4943
  [pinToBottom]
4897
4944
  );
4898
- React.useImperativeHandle(
4945
+ react.useImperativeHandle(
4899
4946
  ref,
4900
4947
  () => ({
4901
4948
  scrollToBottom: (behavior = "smooth") => {
@@ -4908,7 +4955,7 @@ var MessageListV2 = React.forwardRef(
4908
4955
  }),
4909
4956
  [scrollToBottom]
4910
4957
  );
4911
- const handleScroll = React.useCallback(() => {
4958
+ const handleScroll = react.useCallback(() => {
4912
4959
  const el = scrollRef.current;
4913
4960
  if (!el) return;
4914
4961
  const currentScrollTop = el.scrollTop;
@@ -4929,7 +4976,7 @@ var MessageListV2 = React.forwardRef(
4929
4976
  pauseStickUntilUserMessageRef.current = false;
4930
4977
  }
4931
4978
  }, [getDistanceFromBottom]);
4932
- React.useEffect(() => {
4979
+ react.useEffect(() => {
4933
4980
  const prevCount = prevCountRef.current;
4934
4981
  prevCountRef.current = messages.length;
4935
4982
  if (messages.length > prevCount) {
@@ -4943,7 +4990,7 @@ var MessageListV2 = React.forwardRef(
4943
4990
  }
4944
4991
  }
4945
4992
  }, [messages.length, scrollToBottom]);
4946
- React.useEffect(() => {
4993
+ react.useEffect(() => {
4947
4994
  const inner = scrollInnerRef.current;
4948
4995
  if (!inner) return;
4949
4996
  const pinIfFollowing = () => {
@@ -4968,7 +5015,7 @@ var MessageListV2 = React.forwardRef(
4968
5015
  mo.disconnect();
4969
5016
  };
4970
5017
  }, [pinToBottom]);
4971
- React.useEffect(() => {
5018
+ react.useEffect(() => {
4972
5019
  if (messages.length > 0) {
4973
5020
  setTimeout(() => scrollToBottom("instant"), 50);
4974
5021
  }
@@ -5057,7 +5104,7 @@ var MessageListV2 = React.forwardRef(
5057
5104
  ] });
5058
5105
  }
5059
5106
  );
5060
- var ChatInputV2 = React.forwardRef(
5107
+ var ChatInputV2 = react.forwardRef(
5061
5108
  function ChatInputV22({
5062
5109
  onSend,
5063
5110
  disabled = false,
@@ -5081,20 +5128,20 @@ var ChatInputV2 = React.forwardRef(
5081
5128
  onAnalysisModeChange,
5082
5129
  slashCommands = []
5083
5130
  }, 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(
5131
+ const [value, setValue] = react.useState("");
5132
+ const [isFocused, setIsFocused] = react.useState(false);
5133
+ const [showActions, setShowActions] = react.useState(false);
5134
+ const [showVoiceTooltip, setShowVoiceTooltip] = react.useState(false);
5135
+ const [selectedCommandIndex, setSelectedCommandIndex] = react.useState(0);
5136
+ const [inlineHint, setInlineHint] = react.useState(null);
5137
+ const [commandMenuDismissed, setCommandMenuDismissed] = react.useState(false);
5138
+ const textareaRef = react.useRef(null);
5139
+ const actionsRef = react.useRef(null);
5140
+ const preRecordTextRef = react.useRef("");
5141
+ const voiceTooltipTimerRef = react.useRef(
5095
5142
  null
5096
5143
  );
5097
- const voiceDraftSyncActiveRef = React.useRef(false);
5144
+ const voiceDraftSyncActiveRef = react.useRef(false);
5098
5145
  const isInputLocked = disabled || isRecording;
5099
5146
  const hasAttachmentOptions = showUploadImageButton || showAttachFileButton;
5100
5147
  const showAttachmentMenuButton = showAttachmentButton && hasAttachmentOptions;
@@ -5105,14 +5152,14 @@ var ChatInputV2 = React.forwardRef(
5105
5152
  (command) => command.name.toLowerCase().startsWith(commandQuery)
5106
5153
  );
5107
5154
  const showCommandSuggestions = !commandMenuDismissed && !isRecording && !disabled && commandSuggestions.length > 0;
5108
- React.useEffect(() => {
5155
+ react.useEffect(() => {
5109
5156
  if (textareaRef.current) {
5110
5157
  textareaRef.current.style.height = "auto";
5111
5158
  const scrollHeight = textareaRef.current.scrollHeight;
5112
5159
  textareaRef.current.style.height = `${Math.min(scrollHeight, 200)}px`;
5113
5160
  }
5114
5161
  }, [value]);
5115
- React.useEffect(() => {
5162
+ react.useEffect(() => {
5116
5163
  if (disabled) {
5117
5164
  setIsFocused(false);
5118
5165
  setShowActions(false);
@@ -5122,7 +5169,7 @@ var ChatInputV2 = React.forwardRef(
5122
5169
  const frameId = requestAnimationFrame(() => textareaRef.current?.focus());
5123
5170
  return () => cancelAnimationFrame(frameId);
5124
5171
  }, [disabled]);
5125
- React.useImperativeHandle(
5172
+ react.useImperativeHandle(
5126
5173
  ref,
5127
5174
  () => ({
5128
5175
  setDraft: (message) => {
@@ -5139,7 +5186,7 @@ var ChatInputV2 = React.forwardRef(
5139
5186
  }),
5140
5187
  [disabled]
5141
5188
  );
5142
- React.useEffect(() => {
5189
+ react.useEffect(() => {
5143
5190
  if (!showActions) return;
5144
5191
  const handleClickOutside = (e) => {
5145
5192
  if (actionsRef.current && !actionsRef.current.contains(e.target)) {
@@ -5149,29 +5196,29 @@ var ChatInputV2 = React.forwardRef(
5149
5196
  document.addEventListener("mousedown", handleClickOutside);
5150
5197
  return () => document.removeEventListener("mousedown", handleClickOutside);
5151
5198
  }, [showActions]);
5152
- React.useEffect(() => {
5199
+ react.useEffect(() => {
5153
5200
  if (!showAttachmentMenuButton) {
5154
5201
  setShowActions(false);
5155
5202
  }
5156
5203
  }, [showAttachmentMenuButton]);
5157
- React.useEffect(() => {
5204
+ react.useEffect(() => {
5158
5205
  setSelectedCommandIndex(0);
5159
5206
  setCommandMenuDismissed(false);
5160
5207
  }, [commandQuery]);
5161
- React.useEffect(() => {
5208
+ react.useEffect(() => {
5162
5209
  return () => {
5163
5210
  if (voiceTooltipTimerRef.current) {
5164
5211
  clearTimeout(voiceTooltipTimerRef.current);
5165
5212
  }
5166
5213
  };
5167
5214
  }, []);
5168
- React.useEffect(() => {
5215
+ react.useEffect(() => {
5169
5216
  if (!voiceDraftSyncActiveRef.current) return;
5170
5217
  const base = preRecordTextRef.current;
5171
5218
  const separator = base && !base.endsWith(" ") && transcribedText ? " " : "";
5172
5219
  setValue(`${base}${separator}${transcribedText}`);
5173
5220
  }, [isRecording, transcribedText]);
5174
- const handleSend = React.useCallback(() => {
5221
+ const handleSend = react.useCallback(() => {
5175
5222
  if (!value.trim() || disabled) return;
5176
5223
  const commandHint = getSlashCommandValidationHint(value);
5177
5224
  if (commandHint) {
@@ -5191,7 +5238,7 @@ var ChatInputV2 = React.forwardRef(
5191
5238
  }
5192
5239
  });
5193
5240
  }, [value, disabled, onClearEditing, onSend]);
5194
- const selectCommand = React.useCallback(
5241
+ const selectCommand = react.useCallback(
5195
5242
  (command) => {
5196
5243
  const insertText = command.insertText ?? `${command.name} `;
5197
5244
  setValue(insertText);
@@ -5247,14 +5294,14 @@ var ChatInputV2 = React.forwardRef(
5247
5294
  onAttachFileClick?.();
5248
5295
  setShowActions(false);
5249
5296
  };
5250
- const hideVoiceTooltip = React.useCallback(() => {
5297
+ const hideVoiceTooltip = react.useCallback(() => {
5251
5298
  if (voiceTooltipTimerRef.current) {
5252
5299
  clearTimeout(voiceTooltipTimerRef.current);
5253
5300
  voiceTooltipTimerRef.current = null;
5254
5301
  }
5255
5302
  setShowVoiceTooltip(false);
5256
5303
  }, []);
5257
- const startVoiceTooltipTimer = React.useCallback(() => {
5304
+ const startVoiceTooltipTimer = react.useCallback(() => {
5258
5305
  if (isVoiceButtonDisabled || isRecording) return;
5259
5306
  if (voiceTooltipTimerRef.current) {
5260
5307
  clearTimeout(voiceTooltipTimerRef.current);
@@ -5576,9 +5623,9 @@ var ChatInputV2 = React.forwardRef(
5576
5623
  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
5624
  var DEFAULT_SIZE = 36;
5578
5625
  function useElapsedSeconds(isStreaming) {
5579
- const [elapsed, setElapsed] = React.useState(0);
5580
- const startRef = React.useRef(null);
5581
- React.useEffect(() => {
5626
+ const [elapsed, setElapsed] = react.useState(0);
5627
+ const startRef = react.useRef(null);
5628
+ react.useEffect(() => {
5582
5629
  if (!isStreaming) {
5583
5630
  startRef.current = null;
5584
5631
  setElapsed(0);
@@ -5637,22 +5684,22 @@ function StreamingIndicatorV2({
5637
5684
  ) });
5638
5685
  }
5639
5686
  function ImageLightboxV2({ src, alt, onClose }) {
5640
- const [isMounted, setIsMounted] = React.useState(false);
5641
- const [isImageLoaded, setIsImageLoaded] = React.useState(false);
5642
- React.useEffect(() => {
5687
+ const [isMounted, setIsMounted] = react.useState(false);
5688
+ const [isImageLoaded, setIsImageLoaded] = react.useState(false);
5689
+ react.useEffect(() => {
5643
5690
  setIsMounted(true);
5644
5691
  return () => setIsMounted(false);
5645
5692
  }, []);
5646
- React.useEffect(() => {
5693
+ react.useEffect(() => {
5647
5694
  setIsImageLoaded(false);
5648
5695
  }, [src]);
5649
- const handleKeyDown = React.useCallback(
5696
+ const handleKeyDown = react.useCallback(
5650
5697
  (e) => {
5651
5698
  if (e.key === "Escape") onClose();
5652
5699
  },
5653
5700
  [onClose]
5654
5701
  );
5655
- React.useEffect(() => {
5702
+ react.useEffect(() => {
5656
5703
  if (!src || typeof document === "undefined") return;
5657
5704
  document.addEventListener("keydown", handleKeyDown);
5658
5705
  const previousOverflow = document.body.style.overflow;
@@ -5784,9 +5831,9 @@ var PRE_PIPELINE_STEPS = /* @__PURE__ */ new Set([
5784
5831
  "build_pipeline",
5785
5832
  "load_skill_index"
5786
5833
  ]);
5787
- function stepColor(step) {
5788
- if (step.status === "failed") return "#ef4444";
5789
- if (PRE_PIPELINE_STEPS.has(step.step)) return "#f59e0b";
5834
+ function stepColor(step2) {
5835
+ if (step2.status === "failed") return "#ef4444";
5836
+ if (PRE_PIPELINE_STEPS.has(step2.step)) return "#f59e0b";
5790
5837
  return "#3b82f6";
5791
5838
  }
5792
5839
  function formatMs(ms) {
@@ -5801,10 +5848,10 @@ function TraceTimelineModal({
5801
5848
  apiBaseUrl,
5802
5849
  apiHeaders
5803
5850
  }) {
5804
- const [trace, setTrace] = React.useState(null);
5805
- const [loading, setLoading] = React.useState(false);
5806
- const [error, setError] = React.useState(null);
5807
- React.useEffect(() => {
5851
+ const [trace, setTrace] = react.useState(null);
5852
+ const [loading, setLoading] = react.useState(false);
5853
+ const [error, setError] = react.useState(null);
5854
+ react.useEffect(() => {
5808
5855
  if (!open || !executionId) return;
5809
5856
  const ctrl = new AbortController();
5810
5857
  setLoading(true);
@@ -5826,7 +5873,7 @@ function TraceTimelineModal({
5826
5873
  }).finally(() => setLoading(false));
5827
5874
  return () => ctrl.abort();
5828
5875
  }, [open, executionId, apiBaseUrl, apiHeaders]);
5829
- const totalMs = React.useMemo(() => {
5876
+ const totalMs = react.useMemo(() => {
5830
5877
  if (!trace) return 0;
5831
5878
  const meta = trace.runMetadata?.totalTimeMs;
5832
5879
  if (typeof meta === "number" && meta > 0) return meta;
@@ -5835,7 +5882,7 @@ function TraceTimelineModal({
5835
5882
  if (starts.length === 0 || ends.length === 0) return 0;
5836
5883
  return Math.max(...ends) - Math.min(...starts);
5837
5884
  }, [trace]);
5838
- const accountedMs = React.useMemo(
5885
+ const accountedMs = react.useMemo(
5839
5886
  () => (trace?.pipelineSteps ?? []).reduce(
5840
5887
  (sum, s) => sum + (s.durationMs ?? 0),
5841
5888
  0
@@ -5963,10 +6010,10 @@ function TimelineBars({
5963
6010
  totalMs,
5964
6011
  unaccountedMs
5965
6012
  }) {
5966
- const bars = trace.pipelineSteps.map((step) => {
5967
- const duration = step.durationMs ?? 0;
6013
+ const bars = trace.pipelineSteps.map((step2) => {
6014
+ const duration = step2.durationMs ?? 0;
5968
6015
  const widthPct = totalMs > 0 ? duration / totalMs * 100 : 0;
5969
- const llmMs = step.llmCall?.durationMs ?? null;
6016
+ const llmMs = step2.llmCall?.durationMs ?? null;
5970
6017
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginBottom: 8 }, children: [
5971
6018
  /* @__PURE__ */ jsxRuntime.jsxs(
5972
6019
  "div",
@@ -5980,8 +6027,8 @@ function TimelineBars({
5980
6027
  },
5981
6028
  children: [
5982
6029
  /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
5983
- step.step,
5984
- step.status === "failed" && /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "#fca5a5", marginLeft: 6 }, children: "(failed)" })
6030
+ step2.step,
6031
+ step2.status === "failed" && /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "#fca5a5", marginLeft: 6 }, children: "(failed)" })
5985
6032
  ] }),
5986
6033
  /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { opacity: 0.75 }, children: [
5987
6034
  formatMs(duration),
@@ -6009,14 +6056,14 @@ function TimelineBars({
6009
6056
  style: {
6010
6057
  height: "100%",
6011
6058
  width: `${Math.max(widthPct, 0.3)}%`,
6012
- background: stepColor(step),
6059
+ background: stepColor(step2),
6013
6060
  transition: "width 0.2s ease"
6014
6061
  }
6015
6062
  }
6016
6063
  )
6017
6064
  }
6018
6065
  )
6019
- ] }, `${step.step}-${step.startTime}`);
6066
+ ] }, `${step2.step}-${step2.startTime}`);
6020
6067
  });
6021
6068
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
6022
6069
  bars,
@@ -6096,12 +6143,12 @@ var NOOP_ASYNC = async () => {
6096
6143
  var NOOP = () => {
6097
6144
  };
6098
6145
  function useSentryChatCallbacks(callbacks, config) {
6099
- const sentryCtxRef = React.useRef({});
6100
- const callbacksRef = React.useRef(callbacks);
6146
+ const sentryCtxRef = react.useRef({});
6147
+ const callbacksRef = react.useRef(callbacks);
6101
6148
  callbacksRef.current = callbacks;
6102
6149
  const initialSessionId = config.initialSessionId;
6103
6150
  const apiHeaders = config.api.headers;
6104
- React.useEffect(() => {
6151
+ react.useEffect(() => {
6105
6152
  sentryCtxRef.current.agentId = config.agentId;
6106
6153
  sentryCtxRef.current.sessionOwnerId = config.sessionParams?.id;
6107
6154
  if (initialSessionId) {
@@ -6117,13 +6164,13 @@ function useSentryChatCallbacks(callbacks, config) {
6117
6164
  initialSessionId,
6118
6165
  apiHeaders
6119
6166
  ]);
6120
- React.useEffect(() => {
6167
+ react.useEffect(() => {
6121
6168
  const endpoint = config.api.streamEndpoint || "/api/playground/ask/stream";
6122
6169
  return subscribeToCfRay(endpoint, (cfRay) => {
6123
6170
  sentryCtxRef.current.cfRay = cfRay;
6124
6171
  });
6125
6172
  }, [config.api.streamEndpoint]);
6126
- return React.useMemo(
6173
+ return react.useMemo(
6127
6174
  () => ({
6128
6175
  onMessageSent: (msg) => callbacksRef.current?.onMessageSent?.(msg),
6129
6176
  onStreamStart: () => callbacksRef.current?.onStreamStart?.(),
@@ -6172,7 +6219,7 @@ function useSentryChatCallbacks(callbacks, config) {
6172
6219
  []
6173
6220
  );
6174
6221
  }
6175
- var PaymanChatInner = React.forwardRef(function PaymanChatInner2({
6222
+ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
6176
6223
  config,
6177
6224
  callbacks = {},
6178
6225
  className,
@@ -6183,18 +6230,18 @@ var PaymanChatInner = React.forwardRef(function PaymanChatInner2({
6183
6230
  hasMoreMessages = false,
6184
6231
  chat
6185
6232
  }, 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(() => {
6233
+ const [inputValue, setInputValue] = react.useState("");
6234
+ const prevInputValueRef = react.useRef(inputValue);
6235
+ const [hasEverSentMessage, setHasEverSentMessage] = react.useState(false);
6236
+ const [lightboxSrc, setLightboxSrc] = react.useState(null);
6237
+ const [lightboxAlt, setLightboxAlt] = react.useState("");
6238
+ const [editingMessageId, setEditingMessageId] = react.useState(null);
6239
+ const [isResetSessionConfirmOpen, setIsResetSessionConfirmOpen] = react.useState(false);
6240
+ const [analysisMode, setAnalysisMode] = react.useState("fast");
6241
+ const chatInputV2Ref = react.useRef(null);
6242
+ const messageListV2Ref = react.useRef(null);
6243
+ const resetToEmptyStateRef = react.useRef(false);
6244
+ react.useEffect(() => {
6198
6245
  if (config.sentryDsn) {
6199
6246
  initSentryIfNeeded(config.sentryDsn);
6200
6247
  }
@@ -6210,7 +6257,7 @@ var PaymanChatInner = React.forwardRef(function PaymanChatInner2({
6210
6257
  getSessionId,
6211
6258
  getMessages
6212
6259
  } = chat;
6213
- React.useEffect(() => {
6260
+ react.useEffect(() => {
6214
6261
  if (resetToEmptyStateRef.current) {
6215
6262
  if (messages.length === 0) {
6216
6263
  setHasEverSentMessage(false);
@@ -6222,7 +6269,7 @@ var PaymanChatInner = React.forwardRef(function PaymanChatInner2({
6222
6269
  setHasEverSentMessage(true);
6223
6270
  }
6224
6271
  }, [messages.length, hasEverSentMessage]);
6225
- React.useEffect(() => {
6272
+ react.useEffect(() => {
6226
6273
  if (!editingMessageId) return;
6227
6274
  const editingMessageStillExists = messages.some(
6228
6275
  (message) => message.id === editingMessageId && message.role === "user"
@@ -6261,7 +6308,7 @@ var PaymanChatInner = React.forwardRef(function PaymanChatInner2({
6261
6308
  }
6262
6309
  }
6263
6310
  );
6264
- const contextValue = React.useMemo(
6311
+ const contextValue = react.useMemo(
6265
6312
  () => ({
6266
6313
  resetSession,
6267
6314
  clearMessages,
@@ -6288,8 +6335,8 @@ var PaymanChatInner = React.forwardRef(function PaymanChatInner2({
6288
6335
  onAttachFileClick,
6289
6336
  onMessageFeedback
6290
6337
  } = callbacks;
6291
- const [debugTraceExecutionId, setDebugTraceExecutionId] = React.useState(null);
6292
- const handleSubmitFeedback = React.useCallback(
6338
+ const [debugTraceExecutionId, setDebugTraceExecutionId] = react.useState(null);
6339
+ const handleSubmitFeedback = react.useCallback(
6293
6340
  async ({ messageId, executionId, feedback, details }) => {
6294
6341
  if (!executionId) {
6295
6342
  throw new Error("Cannot submit feedback before the response completes");
@@ -6320,14 +6367,14 @@ var PaymanChatInner = React.forwardRef(function PaymanChatInner2({
6320
6367
  onMessageFeedback
6321
6368
  ]
6322
6369
  );
6323
- const onExecutionTraceClick = React.useMemo(() => {
6370
+ const onExecutionTraceClick = react.useMemo(() => {
6324
6371
  if (!config.debug) return rawOnExecutionTraceClick;
6325
6372
  return (data) => {
6326
6373
  rawOnExecutionTraceClick?.(data);
6327
6374
  if (data.executionId) setDebugTraceExecutionId(data.executionId);
6328
6375
  };
6329
6376
  }, [config.debug, rawOnExecutionTraceClick]);
6330
- const performResetSession = React.useCallback(() => {
6377
+ const performResetSession = react.useCallback(() => {
6331
6378
  resetToEmptyStateRef.current = true;
6332
6379
  setEditingMessageId(null);
6333
6380
  setIsResetSessionConfirmOpen(false);
@@ -6348,13 +6395,13 @@ var PaymanChatInner = React.forwardRef(function PaymanChatInner2({
6348
6395
  resetSession,
6349
6396
  stopRecording
6350
6397
  ]);
6351
- const requestResetSession = React.useCallback(() => {
6398
+ const requestResetSession = react.useCallback(() => {
6352
6399
  setIsResetSessionConfirmOpen(true);
6353
6400
  }, []);
6354
- const closeResetSessionConfirm = React.useCallback(() => {
6401
+ const closeResetSessionConfirm = react.useCallback(() => {
6355
6402
  setIsResetSessionConfirmOpen(false);
6356
6403
  }, []);
6357
- React.useImperativeHandle(ref, () => ({
6404
+ react.useImperativeHandle(ref, () => ({
6358
6405
  resetSession: performResetSession,
6359
6406
  clearMessages,
6360
6407
  cancelStream,
@@ -6393,7 +6440,7 @@ var PaymanChatInner = React.forwardRef(function PaymanChatInner2({
6393
6440
  slashCommands: slashCommandsConfig,
6394
6441
  commandPermissions
6395
6442
  } = config;
6396
- const messageActions = React.useMemo(
6443
+ const messageActions = react.useMemo(
6397
6444
  () => ({
6398
6445
  userMessageActions: {
6399
6446
  copy: messageActionsConfig?.userMessageActions?.copy ?? true,
@@ -6409,18 +6456,18 @@ var PaymanChatInner = React.forwardRef(function PaymanChatInner2({
6409
6456
  }),
6410
6457
  [messageActionsConfig]
6411
6458
  );
6412
- const slashCommands = React.useMemo(
6459
+ const slashCommands = react.useMemo(
6413
6460
  () => enableSlashCommands ? filterSlashCommands(
6414
6461
  slashCommandsConfig ?? DEFAULT_SLASH_COMMANDS,
6415
6462
  commandPermissions
6416
6463
  ) : [],
6417
6464
  [commandPermissions, enableSlashCommands, slashCommandsConfig]
6418
6465
  );
6419
- const isSessionParamsConfigured = React.useMemo(() => {
6466
+ const isSessionParamsConfigured = react.useMemo(() => {
6420
6467
  if (!sessionParams) return false;
6421
6468
  return !!(sessionParams.id?.trim() && sessionParams.name?.trim());
6422
6469
  }, [sessionParams?.id, sessionParams?.name]);
6423
- React.useEffect(() => {
6470
+ react.useEffect(() => {
6424
6471
  const wasEmpty = prevInputValueRef.current.trim() === "";
6425
6472
  const isEmpty2 = inputValue.trim() === "";
6426
6473
  prevInputValueRef.current = inputValue;
@@ -6487,7 +6534,7 @@ var PaymanChatInner = React.forwardRef(function PaymanChatInner2({
6487
6534
  void sendMessage(text.trim(), { analysisMode: effectiveAnalysisMode });
6488
6535
  }
6489
6536
  };
6490
- const handleVoicePress = React.useCallback(async () => {
6537
+ const handleVoicePress = react.useCallback(async () => {
6491
6538
  if (!voiceAvailable) return;
6492
6539
  if (isRecording) {
6493
6540
  stopRecording();
@@ -6496,7 +6543,7 @@ var PaymanChatInner = React.forwardRef(function PaymanChatInner2({
6496
6543
  clearTranscript();
6497
6544
  await startRecording();
6498
6545
  }, [clearTranscript, isRecording, startRecording, stopRecording, voiceAvailable]);
6499
- const handleEditMessageDraft = React.useCallback((messageId) => {
6546
+ const handleEditMessageDraft = react.useCallback((messageId) => {
6500
6547
  const targetMessage = messages.find((message) => message.id === messageId);
6501
6548
  if (!targetMessage?.content.trim()) return;
6502
6549
  setEditingMessageId(messageId);
@@ -6505,7 +6552,7 @@ var PaymanChatInner = React.forwardRef(function PaymanChatInner2({
6505
6552
  messageListV2Ref.current?.scrollToBottom("smooth");
6506
6553
  });
6507
6554
  }, [messages]);
6508
- const handleRetryUserMessage = React.useCallback((messageId) => {
6555
+ const handleRetryUserMessage = react.useCallback((messageId) => {
6509
6556
  if (isWaitingForResponse) return;
6510
6557
  const targetMessage = messages.find(
6511
6558
  (message) => message.id === messageId && message.role === "user"
@@ -6522,7 +6569,7 @@ var PaymanChatInner = React.forwardRef(function PaymanChatInner2({
6522
6569
  });
6523
6570
  });
6524
6571
  }, [isWaitingForResponse, messages, sendMessage, effectiveAnalysisMode]);
6525
- const handleClearEditing = React.useCallback(() => {
6572
+ const handleClearEditing = react.useCallback(() => {
6526
6573
  setEditingMessageId(null);
6527
6574
  }, []);
6528
6575
  return /* @__PURE__ */ jsxRuntime.jsx(PaymanChatContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsxs(
@@ -6712,7 +6759,7 @@ var PaymanChatInner = React.forwardRef(function PaymanChatInner2({
6712
6759
  }
6713
6760
  ) });
6714
6761
  });
6715
- var PaymanChat = React.forwardRef(
6762
+ var PaymanChat = react.forwardRef(
6716
6763
  function PaymanChat2(props, ref) {
6717
6764
  const mergedCallbacks = useSentryChatCallbacks(props.callbacks, props.config);
6718
6765
  const chat = useChatV2(props.config, mergedCallbacks);