@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.
@@ -55,6 +55,7 @@ var chatStore = {
55
55
  memoryStore.delete(key);
56
56
  }
57
57
  };
58
+ var EMPTY_USER_ACTION_STATE = { prompts: [], notifications: [] };
58
59
  var streams = /* @__PURE__ */ new Map();
59
60
  var activeStreamStore = {
60
61
  has(key) {
@@ -63,7 +64,11 @@ var activeStreamStore = {
63
64
  get(key) {
64
65
  const entry = streams.get(key);
65
66
  if (!entry) return null;
66
- return { messages: entry.messages, isWaiting: entry.isWaiting };
67
+ return {
68
+ messages: entry.messages,
69
+ isWaiting: entry.isWaiting,
70
+ userActionState: entry.userActionState
71
+ };
67
72
  },
68
73
  // Called before startStream — registers the controller and initial messages
69
74
  start(key, abortController, initialMessages) {
@@ -71,6 +76,7 @@ var activeStreamStore = {
71
76
  streams.set(key, {
72
77
  messages: initialMessages,
73
78
  isWaiting: true,
79
+ userActionState: EMPTY_USER_ACTION_STATE,
74
80
  abortController,
75
81
  listeners: existing?.listeners ?? /* @__PURE__ */ new Set()
76
82
  });
@@ -81,20 +87,27 @@ var activeStreamStore = {
81
87
  if (!entry) return;
82
88
  const next = typeof updater === "function" ? updater(entry.messages) : updater;
83
89
  entry.messages = next;
84
- entry.listeners.forEach((l) => l(next, entry.isWaiting));
90
+ entry.listeners.forEach((l) => l(next, entry.isWaiting, entry.userActionState));
85
91
  },
86
92
  setWaiting(key, waiting) {
87
93
  const entry = streams.get(key);
88
94
  if (!entry) return;
89
95
  entry.isWaiting = waiting;
90
- entry.listeners.forEach((l) => l(entry.messages, waiting));
96
+ entry.listeners.forEach((l) => l(entry.messages, waiting, entry.userActionState));
97
+ },
98
+ applyUserActionState(key, updater) {
99
+ const entry = streams.get(key);
100
+ if (!entry) return;
101
+ const next = typeof updater === "function" ? updater(entry.userActionState) : updater;
102
+ entry.userActionState = next;
103
+ entry.listeners.forEach((l) => l(entry.messages, entry.isWaiting, next));
91
104
  },
92
105
  // Called when stream completes — persists to chatStore and cleans up
93
106
  complete(key) {
94
107
  const entry = streams.get(key);
95
108
  if (!entry) return;
96
109
  entry.isWaiting = false;
97
- entry.listeners.forEach((l) => l(entry.messages, false));
110
+ entry.listeners.forEach((l) => l(entry.messages, false, entry.userActionState));
98
111
  const toSave = entry.messages.filter((m) => !m.isStreaming);
99
112
  if (toSave.length > 0) chatStore.set(key, toSave);
100
113
  streams.delete(key);
@@ -517,9 +530,9 @@ function processStreamEventV2(rawEvent, state) {
517
530
  state.hasError = true;
518
531
  state.errorMessage = "WORKFLOW_FAILED";
519
532
  }
520
- state.steps.forEach((step) => {
521
- if (step.status === "in_progress") {
522
- step.status = "completed";
533
+ state.steps.forEach((step2) => {
534
+ if (step2.status === "in_progress") {
535
+ step2.status = "completed";
523
536
  }
524
537
  });
525
538
  state.lastEventType = eventType;
@@ -934,11 +947,11 @@ function useStreamManagerV2(config, callbacks, setMessages, setIsWaitingForRespo
934
947
  errorDetails: isAborted ? void 0 : error.message,
935
948
  content: isAborted ? state.finalResponse || "" : state.finalResponse || FRIENDLY_ERROR_MESSAGE,
936
949
  currentMessage: isAborted ? "Thinking..." : void 0,
937
- steps: [...state.steps].map((step) => {
938
- if (step.status === "in_progress" && isAborted) {
939
- return { ...step, status: "pending" };
950
+ steps: [...state.steps].map((step2) => {
951
+ if (step2.status === "in_progress" && isAborted) {
952
+ return { ...step2, status: "pending" };
940
953
  }
941
- return step;
954
+ return step2;
942
955
  }),
943
956
  currentExecutingStepId: void 0
944
957
  } : msg
@@ -1024,11 +1037,11 @@ function useStreamManagerV2(config, callbacks, setMessages, setIsWaitingForRespo
1024
1037
  isCancelled: isAborted,
1025
1038
  errorDetails: isAborted ? void 0 : error.message,
1026
1039
  content: isAborted ? state.finalResponse || "" : state.finalResponse || FRIENDLY_ERROR_MESSAGE,
1027
- steps: [...state.steps].map((step) => {
1028
- if (step.status === "in_progress" && isAborted) {
1029
- return { ...step, status: "pending" };
1040
+ steps: [...state.steps].map((step2) => {
1041
+ if (step2.status === "in_progress" && isAborted) {
1042
+ return { ...step2, status: "pending" };
1030
1043
  }
1031
- return step;
1044
+ return step2;
1032
1045
  }),
1033
1046
  currentExecutingStepId: void 0
1034
1047
  } : msg
@@ -1049,11 +1062,11 @@ function useStreamManagerV2(config, callbacks, setMessages, setIsWaitingForRespo
1049
1062
  };
1050
1063
  }
1051
1064
  function createCancelledMessageUpdate(steps, currentMessage) {
1052
- const updatedSteps = steps.map((step) => {
1053
- if (step.status === "in_progress") {
1054
- return { ...step, status: "pending" };
1065
+ const updatedSteps = steps.map((step2) => {
1066
+ if (step2.status === "in_progress") {
1067
+ return { ...step2, status: "pending" };
1055
1068
  }
1056
- return step;
1069
+ return step2;
1057
1070
  });
1058
1071
  return {
1059
1072
  isStreaming: false,
@@ -1102,12 +1115,35 @@ async function resendUserAction(config, userActionId) {
1102
1115
  async function expireUserAction(config, userActionId) {
1103
1116
  return sendUserActionRequest(config, userActionId, "expired");
1104
1117
  }
1105
- var EMPTY_USER_ACTION_STATE = { prompts: [], notifications: [] };
1118
+ function resolveUserActionExpiresAt(req, existing) {
1119
+ if (typeof req.expirySeconds !== "number" || req.expirySeconds <= 0) {
1120
+ return void 0;
1121
+ }
1122
+ if (existing?.expiresAt && existing.userActionId === req.userActionId) {
1123
+ return existing.expiresAt;
1124
+ }
1125
+ return Date.now() + Math.floor(req.expirySeconds) * 1e3;
1126
+ }
1127
+ function getUserActionSecondsLeft(prompt) {
1128
+ if (typeof prompt.expiresAt === "number" && prompt.expiresAt > 0) {
1129
+ return Math.max(0, Math.ceil((prompt.expiresAt - Date.now()) / 1e3));
1130
+ }
1131
+ if (typeof prompt.expirySeconds === "number" && prompt.expirySeconds > 0) {
1132
+ return Math.floor(prompt.expirySeconds);
1133
+ }
1134
+ return void 0;
1135
+ }
1136
+ function isUserActionExpired(prompt) {
1137
+ const left = getUserActionSecondsLeft(prompt);
1138
+ return left !== void 0 && left <= 0;
1139
+ }
1140
+ var EMPTY_USER_ACTION_STATE2 = { prompts: [], notifications: [] };
1106
1141
  function upsertPrompt(prompts, req) {
1107
- const active = { ...req, status: "pending" };
1108
1142
  const idx = prompts.findIndex(
1109
1143
  (p) => req.toolCallId ? p.toolCallId === req.toolCallId : p.userActionId === req.userActionId
1110
1144
  );
1145
+ const expiresAt = resolveUserActionExpiresAt(req, idx >= 0 ? prompts[idx] : void 0);
1146
+ const active = { ...req, status: "pending", expiresAt };
1111
1147
  if (idx >= 0) {
1112
1148
  const next = prompts.slice();
1113
1149
  next[idx] = active;
@@ -1178,7 +1214,28 @@ function useChatV2(config, callbacks = {}) {
1178
1214
  // eslint-disable-next-line react-hooks/exhaustive-deps
1179
1215
  []
1180
1216
  );
1181
- const [userActionState, setUserActionState] = react.useState(EMPTY_USER_ACTION_STATE);
1217
+ const [userActionState, setUserActionState] = react.useState(() => {
1218
+ if (!config.userId) return EMPTY_USER_ACTION_STATE2;
1219
+ return activeStreamStore.get(config.userId)?.userActionState ?? EMPTY_USER_ACTION_STATE2;
1220
+ });
1221
+ const storeAwareSetUserActionState = react.useCallback(
1222
+ (updater) => {
1223
+ const streamUserId = streamUserIdRef.current;
1224
+ const currentUserId = configRef.current.userId;
1225
+ const storeKey = streamUserId ?? currentUserId;
1226
+ if (storeKey && activeStreamStore.has(storeKey)) {
1227
+ activeStreamStore.applyUserActionState(
1228
+ storeKey,
1229
+ updater
1230
+ );
1231
+ }
1232
+ if (!streamUserId || streamUserId === currentUserId) {
1233
+ setUserActionState(updater);
1234
+ }
1235
+ },
1236
+ // eslint-disable-next-line react-hooks/exhaustive-deps
1237
+ []
1238
+ );
1182
1239
  const wrappedCallbacks = react.useMemo(() => ({
1183
1240
  ...callbacksRef.current,
1184
1241
  onMessageSent: (message) => callbacksRef.current.onMessageSent?.(message),
@@ -1188,14 +1245,14 @@ function useChatV2(config, callbacks = {}) {
1188
1245
  onExecutionTraceClick: (data) => callbacksRef.current.onExecutionTraceClick?.(data),
1189
1246
  onSessionIdChange: (sessionId) => callbacksRef.current.onSessionIdChange?.(sessionId),
1190
1247
  onUserActionRequired: (request) => {
1191
- setUserActionState((prev) => ({
1248
+ storeAwareSetUserActionState((prev) => ({
1192
1249
  ...prev,
1193
1250
  prompts: upsertPrompt(prev.prompts, request)
1194
1251
  }));
1195
1252
  callbacksRef.current.onUserActionRequired?.(request);
1196
1253
  },
1197
1254
  onUserNotification: (notification) => {
1198
- setUserActionState(
1255
+ storeAwareSetUserActionState(
1199
1256
  (prev) => prev.notifications.some((n) => n.id === notification.id) ? prev : { ...prev, notifications: [...prev.notifications, notification] }
1200
1257
  );
1201
1258
  callbacksRef.current.onUserNotification?.(notification);
@@ -1285,7 +1342,7 @@ function useChatV2(config, callbacks = {}) {
1285
1342
  streamUserIdRef.current = void 0;
1286
1343
  cancelStreamManager();
1287
1344
  setIsWaitingForResponse(false);
1288
- setUserActionState((prev) => ({ ...prev, prompts: [] }));
1345
+ storeAwareSetUserActionState((prev) => ({ ...prev, prompts: [] }));
1289
1346
  setMessages(
1290
1347
  (prev) => prev.map((msg) => {
1291
1348
  if (msg.isStreaming) {
@@ -1300,7 +1357,7 @@ function useChatV2(config, callbacks = {}) {
1300
1357
  return msg;
1301
1358
  })
1302
1359
  );
1303
- }, [cancelStreamManager]);
1360
+ }, [cancelStreamManager, storeAwareSetUserActionState]);
1304
1361
  const resetSession = react.useCallback(() => {
1305
1362
  const streamUserId = streamUserIdRef.current ?? configRef.current.userId;
1306
1363
  if (streamUserId) {
@@ -1314,7 +1371,7 @@ function useChatV2(config, callbacks = {}) {
1314
1371
  sessionIdRef.current = void 0;
1315
1372
  abortControllerRef.current?.abort();
1316
1373
  setIsWaitingForResponse(false);
1317
- setUserActionState(EMPTY_USER_ACTION_STATE);
1374
+ storeAwareSetUserActionState(EMPTY_USER_ACTION_STATE2);
1318
1375
  }, []);
1319
1376
  const getSessionId = react.useCallback(() => {
1320
1377
  return sessionIdRef.current;
@@ -1324,21 +1381,21 @@ function useChatV2(config, callbacks = {}) {
1324
1381
  }, [messages]);
1325
1382
  const setPromptStatus = react.useCallback(
1326
1383
  (userActionId, status) => {
1327
- setUserActionState((prev) => ({
1384
+ storeAwareSetUserActionState((prev) => ({
1328
1385
  ...prev,
1329
1386
  prompts: prev.prompts.map(
1330
1387
  (p) => p.userActionId === userActionId ? { ...p, status } : p
1331
1388
  )
1332
1389
  }));
1333
1390
  },
1334
- []
1391
+ [storeAwareSetUserActionState]
1335
1392
  );
1336
1393
  const removePrompt = react.useCallback((userActionId) => {
1337
- setUserActionState((prev) => ({
1394
+ storeAwareSetUserActionState((prev) => ({
1338
1395
  ...prev,
1339
1396
  prompts: prev.prompts.filter((p) => p.userActionId !== userActionId)
1340
1397
  }));
1341
- }, []);
1398
+ }, [storeAwareSetUserActionState]);
1342
1399
  const submitUserAction2 = react.useCallback(
1343
1400
  async (userActionId, content) => {
1344
1401
  setPromptStatus(userActionId, "submitting");
@@ -1407,11 +1464,11 @@ function useChatV2(config, callbacks = {}) {
1407
1464
  [setPromptStatus]
1408
1465
  );
1409
1466
  const dismissNotification = react.useCallback((id) => {
1410
- setUserActionState((prev) => ({
1467
+ storeAwareSetUserActionState((prev) => ({
1411
1468
  ...prev,
1412
1469
  notifications: prev.notifications.filter((n) => n.id !== id)
1413
1470
  }));
1414
- }, []);
1471
+ }, [storeAwareSetUserActionState]);
1415
1472
  react.useEffect(() => {
1416
1473
  const prevSubscriptionUserId = subscriptionPrevUserIdRef.current;
1417
1474
  subscriptionPrevUserIdRef.current = config.userId;
@@ -1420,14 +1477,17 @@ function useChatV2(config, callbacks = {}) {
1420
1477
  if (prevSubscriptionUserId && prevSubscriptionUserId !== userId && streamUserIdRef.current === prevSubscriptionUserId && !activeStreamStore.has(prevSubscriptionUserId) && activeStreamStore.has(userId)) {
1421
1478
  streamUserIdRef.current = userId;
1422
1479
  }
1423
- const unsubscribe = activeStreamStore.subscribe(userId, (msgs, isWaiting) => {
1480
+ const unsubscribe = activeStreamStore.subscribe(userId, (msgs, isWaiting, actions) => {
1424
1481
  setMessages(msgs);
1425
1482
  setIsWaitingForResponse(isWaiting);
1483
+ setUserActionState(actions);
1426
1484
  });
1427
1485
  const active = activeStreamStore.get(userId);
1428
1486
  if (active) {
1487
+ streamUserIdRef.current = userId;
1429
1488
  setMessages(active.messages);
1430
1489
  setIsWaitingForResponse(active.isWaiting);
1490
+ setUserActionState(active.userActionState);
1431
1491
  }
1432
1492
  return unsubscribe;
1433
1493
  }, [config.userId]);
@@ -1455,12 +1515,14 @@ function useChatV2(config, callbacks = {}) {
1455
1515
  setMessages([]);
1456
1516
  sessionIdRef.current = void 0;
1457
1517
  setIsWaitingForResponse(false);
1458
- setUserActionState(EMPTY_USER_ACTION_STATE);
1518
+ setUserActionState(EMPTY_USER_ACTION_STATE2);
1459
1519
  } else if (config.userId) {
1460
1520
  const active = activeStreamStore.get(config.userId);
1461
1521
  if (active) {
1522
+ streamUserIdRef.current = config.userId;
1462
1523
  setMessages(active.messages);
1463
1524
  setIsWaitingForResponse(active.isWaiting);
1525
+ setUserActionState(active.userActionState);
1464
1526
  sessionIdRef.current = getSessionIdFromMessages(active.messages) ?? config.initialSessionId;
1465
1527
  return;
1466
1528
  }
@@ -1828,6 +1890,85 @@ function usePaymanChat() {
1828
1890
  }
1829
1891
  return context;
1830
1892
  }
1893
+
1894
+ // src/utils/markdownImageToken.ts
1895
+ function step(text, i) {
1896
+ if (text[i] === "\\" && i + 1 < text.length) return i + 2;
1897
+ return i + 1;
1898
+ }
1899
+ function scanAltText(text, start) {
1900
+ let i = start;
1901
+ while (i < text.length) {
1902
+ if (text[i] === "]") return i;
1903
+ i = step(text, i);
1904
+ }
1905
+ return -1;
1906
+ }
1907
+ function scanOptionalTitle(text, start) {
1908
+ let i = start;
1909
+ while (i < text.length && /[\t\n ]/.test(text[i])) i++;
1910
+ if (i >= text.length) return i;
1911
+ const quote = text[i];
1912
+ if (quote !== '"' && quote !== "'") return i;
1913
+ i++;
1914
+ while (i < text.length) {
1915
+ if (text[i] === quote) return i + 1;
1916
+ i = step(text, i);
1917
+ }
1918
+ return -1;
1919
+ }
1920
+ function scanAngleBracketDestination(text, start) {
1921
+ let i = start + 1;
1922
+ while (i < text.length) {
1923
+ if (text[i] === ">") return i + 1;
1924
+ i = step(text, i);
1925
+ }
1926
+ return -1;
1927
+ }
1928
+ function scanRawDestination(text, start) {
1929
+ let i = start;
1930
+ let depth = 1;
1931
+ while (i < text.length) {
1932
+ const char = text[i];
1933
+ if (char === "\\") {
1934
+ if (i + 1 >= text.length) return -1;
1935
+ i += 2;
1936
+ continue;
1937
+ }
1938
+ if (char === "(") depth++;
1939
+ else if (char === ")") {
1940
+ depth--;
1941
+ if (depth === 0) return i + 1;
1942
+ }
1943
+ i++;
1944
+ }
1945
+ return -1;
1946
+ }
1947
+ function completeMarkdownImageTokenLength(text) {
1948
+ if (!text.startsWith("![")) return 0;
1949
+ const altEnd = scanAltText(text, 2);
1950
+ if (altEnd === -1 || altEnd + 1 >= text.length || text[altEnd + 1] !== "(") {
1951
+ return 0;
1952
+ }
1953
+ let i = altEnd + 2;
1954
+ if (i >= text.length) return 0;
1955
+ if (text[i] === "<") {
1956
+ i = scanAngleBracketDestination(text, i);
1957
+ if (i === -1) return 0;
1958
+ i = scanOptionalTitle(text, i);
1959
+ if (i === -1 || i >= text.length || text[i] !== ")") return 0;
1960
+ return i + 1;
1961
+ }
1962
+ i = scanRawDestination(text, i);
1963
+ return i === -1 ? 0 : i;
1964
+ }
1965
+ function stripIncompleteImageToken(text) {
1966
+ const lastBang = text.lastIndexOf("![");
1967
+ if (lastBang === -1) return text;
1968
+ const suffix = text.slice(lastBang);
1969
+ if (completeMarkdownImageTokenLength(suffix) > 0) return text;
1970
+ return text.slice(0, lastBang);
1971
+ }
1831
1972
  if (reactNative.Platform.OS === "android" && reactNative.UIManager.setLayoutAnimationEnabledExperimental) {
1832
1973
  reactNative.UIManager.setLayoutAnimationEnabledExperimental(true);
1833
1974
  }
@@ -2280,13 +2421,6 @@ function UserBubble({ message, accent }) {
2280
2421
  if (!text) return null;
2281
2422
  return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [sd.bubbleRow, sd.rowUser], children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [sd.bubble, sd.bubbleUser, { backgroundColor: accent }], children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [sd.bubbleText, sd.textUser], children: text }) }) });
2282
2423
  }
2283
- function stripIncompleteImageToken(text) {
2284
- const lastBang = text.lastIndexOf("![");
2285
- if (lastBang === -1) return text;
2286
- const after = text.slice(lastBang);
2287
- if (/^!\[[^\]]*\]\([^)]*\)/.test(after)) return text;
2288
- return text.slice(0, lastBang);
2289
- }
2290
2424
  function stripDuplicatePromptText(text, promptText) {
2291
2425
  if (!promptText) return text;
2292
2426
  const pm = promptText.replace(/\\n/g, "\n").trim();
@@ -2376,35 +2510,37 @@ function uaPalette(isDark) {
2376
2510
  grabber: "rgba(15,23,42,0.18)"
2377
2511
  };
2378
2512
  }
2379
- function promptInitialSeconds(prompt) {
2380
- return prompt && typeof prompt.expirySeconds === "number" && prompt.expirySeconds > 0 ? Math.floor(prompt.expirySeconds) : void 0;
2381
- }
2382
2513
  function promptTimerKey(prompt) {
2383
- return prompt ? `${prompt.userActionId}|${prompt.subAction ?? ""}` : "";
2514
+ return prompt ? `${prompt.userActionId}|${prompt.subAction ?? ""}|${prompt.expiresAt ?? ""}` : "";
2384
2515
  }
2385
2516
  function useExpiredFlag(prompt) {
2386
- const initial = promptInitialSeconds(prompt);
2387
2517
  const key = promptTimerKey(prompt);
2388
- const [expired, setExpired] = react.useState(false);
2518
+ const [expired, setExpired] = react.useState(() => prompt ? isUserActionExpired(prompt) : false);
2389
2519
  react.useEffect(() => {
2390
- setExpired(false);
2391
- if (initial === void 0) return;
2392
- const t = setTimeout(() => setExpired(true), initial * 1e3);
2520
+ const secondsLeft = prompt ? getUserActionSecondsLeft(prompt) : void 0;
2521
+ setExpired(secondsLeft !== void 0 && secondsLeft <= 0);
2522
+ if (secondsLeft === void 0 || secondsLeft <= 0) return;
2523
+ const t = setTimeout(() => setExpired(true), secondsLeft * 1e3);
2393
2524
  return () => clearTimeout(t);
2394
- }, [key, initial]);
2525
+ }, [key, prompt]);
2395
2526
  return expired;
2396
2527
  }
2397
- function useSecondsLeft(expirySeconds, restartKey) {
2398
- const initial = typeof expirySeconds === "number" && expirySeconds > 0 ? Math.floor(expirySeconds) : void 0;
2399
- const [left, setLeft] = react.useState(initial);
2528
+ function useSecondsLeft(prompt, restartKey) {
2529
+ const deadlineMs = prompt && typeof prompt.expiresAt === "number" && prompt.expiresAt > 0 ? prompt.expiresAt : prompt && typeof prompt.expirySeconds === "number" && prompt.expirySeconds > 0 ? Date.now() + Math.floor(prompt.expirySeconds) * 1e3 : void 0;
2530
+ const [left, setLeft] = react.useState(
2531
+ () => deadlineMs !== void 0 ? Math.max(0, Math.ceil((deadlineMs - Date.now()) / 1e3)) : void 0
2532
+ );
2400
2533
  react.useEffect(() => {
2401
- setLeft(initial);
2402
- if (initial === void 0) return;
2403
- const id = setInterval(() => {
2404
- setLeft((s2) => s2 === void 0 ? s2 : s2 <= 1 ? 0 : s2 - 1);
2405
- }, 1e3);
2534
+ if (deadlineMs === void 0) {
2535
+ setLeft(void 0);
2536
+ return;
2537
+ }
2538
+ const remaining = () => Math.max(0, Math.ceil((deadlineMs - Date.now()) / 1e3));
2539
+ const sync = () => setLeft(remaining());
2540
+ sync();
2541
+ const id = setInterval(sync, 1e3);
2406
2542
  return () => clearInterval(id);
2407
- }, [restartKey, initial]);
2543
+ }, [restartKey, deadlineMs]);
2408
2544
  return left;
2409
2545
  }
2410
2546
  function SheetTimerPill({
@@ -2412,7 +2548,7 @@ function SheetTimerPill({
2412
2548
  accent,
2413
2549
  isDark
2414
2550
  }) {
2415
- const left = useSecondsLeft(prompt.expirySeconds, promptTimerKey(prompt));
2551
+ const left = useSecondsLeft(prompt, promptTimerKey(prompt));
2416
2552
  if (left === void 0 || prompt.status === "stale") return null;
2417
2553
  const expired = left <= 0;
2418
2554
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -2434,7 +2570,7 @@ function CardTimerPill({
2434
2570
  accent,
2435
2571
  isDark
2436
2572
  }) {
2437
- const left = useSecondsLeft(prompt.expirySeconds, promptTimerKey(prompt));
2573
+ const left = useSecondsLeft(prompt, promptTimerKey(prompt));
2438
2574
  if (left === void 0 || left <= 0) return null;
2439
2575
  return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [rc.timer, { backgroundColor: accent + (isDark ? "26" : "14") }], children: /* @__PURE__ */ jsxRuntime.jsxs(reactNative.Text, { style: { color: accent, fontSize: 12, fontWeight: "700" }, children: [
2440
2576
  left,