@paymanai/payman-typescript-ask-sdk 4.0.26 → 4.0.27

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.
@@ -1169,6 +1169,9 @@ function isUserActionExpired(prompt) {
1169
1169
 
1170
1170
  // src/hooks/useChatV2.ts
1171
1171
  var EMPTY_USER_ACTION_STATE2 = { prompts: [], notifications: [] };
1172
+ function promptSlotKey(p) {
1173
+ return p.toolCallId || p.userActionId;
1174
+ }
1172
1175
  function upsertPrompt(prompts, req) {
1173
1176
  const idx = prompts.findIndex(
1174
1177
  (p) => req.toolCallId ? p.toolCallId === req.toolCallId : p.userActionId === req.userActionId
@@ -1215,6 +1218,7 @@ function useChatV2(config, callbacks = {}) {
1215
1218
  configRef.current = config;
1216
1219
  const messagesRef = react.useRef(messages);
1217
1220
  messagesRef.current = messages;
1221
+ const pendingSubmissionsRef = react.useRef(/* @__PURE__ */ new Map());
1218
1222
  const storeAwareSetMessages = react.useCallback(
1219
1223
  (updater) => {
1220
1224
  const streamUserId = streamUserIdRef.current;
@@ -1249,6 +1253,8 @@ function useChatV2(config, callbacks = {}) {
1249
1253
  if (!config.userId) return EMPTY_USER_ACTION_STATE2;
1250
1254
  return activeStreamStore.get(config.userId)?.userActionState ?? EMPTY_USER_ACTION_STATE2;
1251
1255
  });
1256
+ const userActionStateRef = react.useRef(userActionState);
1257
+ userActionStateRef.current = userActionState;
1252
1258
  const storeAwareSetUserActionState = react.useCallback(
1253
1259
  (updater) => {
1254
1260
  const streamUserId = streamUserIdRef.current;
@@ -1276,6 +1282,12 @@ function useChatV2(config, callbacks = {}) {
1276
1282
  onExecutionTraceClick: (data) => callbacksRef.current.onExecutionTraceClick?.(data),
1277
1283
  onSessionIdChange: (sessionId) => callbacksRef.current.onSessionIdChange?.(sessionId),
1278
1284
  onUserActionRequired: (request) => {
1285
+ const requestSlotKey = promptSlotKey(request);
1286
+ for (const [pendingId, slotKey] of pendingSubmissionsRef.current) {
1287
+ if (slotKey === requestSlotKey) {
1288
+ pendingSubmissionsRef.current.delete(pendingId);
1289
+ }
1290
+ }
1279
1291
  storeAwareSetUserActionState((prev) => ({
1280
1292
  ...prev,
1281
1293
  prompts: upsertPrompt(prev.prompts, request)
@@ -1287,6 +1299,28 @@ function useChatV2(config, callbacks = {}) {
1287
1299
  (prev) => prev.notifications.some((n) => n.id === notification.id) ? prev : { ...prev, notifications: [...prev.notifications, notification] }
1288
1300
  );
1289
1301
  callbacksRef.current.onUserNotification?.(notification);
1302
+ },
1303
+ // A submitted-but-unconfirmed prompt (see `submitUserAction`) is only
1304
+ // safe to drop once the stream has demonstrably moved on. `onEvent`
1305
+ // in useStreamManagerV2 calls `onStepsUpdate` for *every* processed
1306
+ // stream event, unconditionally — so the first time this fires
1307
+ // after a submission, the event in hand is either the rejection
1308
+ // retry (a fresh `USER_ACTION_REQUIRED`, which the handler above
1309
+ // already deleted this pending entry for, earlier in the very same
1310
+ // event) or genuine forward progress (RUN_IN_PROGRESS, a tool call,
1311
+ // content deltas, RUN_COMPLETED, ...). Anything still pending by
1312
+ // the time we get here therefore means the run resumed normally —
1313
+ // clear it.
1314
+ onStepsUpdate: (steps) => {
1315
+ if (pendingSubmissionsRef.current.size > 0) {
1316
+ const resolved = [...pendingSubmissionsRef.current.keys()];
1317
+ pendingSubmissionsRef.current.clear();
1318
+ storeAwareSetUserActionState((prev) => ({
1319
+ ...prev,
1320
+ prompts: prev.prompts.filter((p) => !resolved.includes(p.userActionId))
1321
+ }));
1322
+ }
1323
+ callbacksRef.current.onStepsUpdate?.(steps);
1290
1324
  }
1291
1325
  // eslint-disable-next-line react-hooks/exhaustive-deps
1292
1326
  }), []);
@@ -1422,6 +1456,7 @@ function useChatV2(config, callbacks = {}) {
1422
1456
  [storeAwareSetUserActionState]
1423
1457
  );
1424
1458
  const removePrompt = react.useCallback((userActionId) => {
1459
+ pendingSubmissionsRef.current.delete(userActionId);
1425
1460
  storeAwareSetUserActionState((prev) => ({
1426
1461
  ...prev,
1427
1462
  prompts: prev.prompts.filter((p) => p.userActionId !== userActionId)
@@ -1432,7 +1467,10 @@ function useChatV2(config, callbacks = {}) {
1432
1467
  setPromptStatus(userActionId, "submitting");
1433
1468
  try {
1434
1469
  await submitUserAction(configRef.current, userActionId, content);
1435
- removePrompt(userActionId);
1470
+ const prompt = userActionStateRef.current.prompts.find(
1471
+ (p) => p.userActionId === userActionId
1472
+ );
1473
+ pendingSubmissionsRef.current.set(userActionId, prompt ? promptSlotKey(prompt) : userActionId);
1436
1474
  } catch (error) {
1437
1475
  if (error instanceof UserActionStaleError) {
1438
1476
  setPromptStatus(userActionId, "stale");
@@ -1443,7 +1481,7 @@ function useChatV2(config, callbacks = {}) {
1443
1481
  throw error;
1444
1482
  }
1445
1483
  },
1446
- [removePrompt, setPromptStatus]
1484
+ [setPromptStatus]
1447
1485
  );
1448
1486
  const cancelUserAction2 = react.useCallback(
1449
1487
  async (userActionId) => {