@paymanai/payman-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.
@@ -1153,6 +1153,9 @@ function isUserActionExpired(prompt) {
1153
1153
  return left !== void 0 && left <= 0;
1154
1154
  }
1155
1155
  var EMPTY_USER_ACTION_STATE2 = { prompts: [], notifications: [] };
1156
+ function promptSlotKey(p) {
1157
+ return p.toolCallId || p.userActionId;
1158
+ }
1156
1159
  function upsertPrompt(prompts, req) {
1157
1160
  const idx = prompts.findIndex(
1158
1161
  (p) => req.toolCallId ? p.toolCallId === req.toolCallId : p.userActionId === req.userActionId
@@ -1199,6 +1202,7 @@ function useChatV2(config, callbacks = {}) {
1199
1202
  configRef.current = config;
1200
1203
  const messagesRef = react.useRef(messages);
1201
1204
  messagesRef.current = messages;
1205
+ const pendingSubmissionsRef = react.useRef(/* @__PURE__ */ new Map());
1202
1206
  const storeAwareSetMessages = react.useCallback(
1203
1207
  (updater) => {
1204
1208
  const streamUserId = streamUserIdRef.current;
@@ -1233,6 +1237,8 @@ function useChatV2(config, callbacks = {}) {
1233
1237
  if (!config.userId) return EMPTY_USER_ACTION_STATE2;
1234
1238
  return activeStreamStore.get(config.userId)?.userActionState ?? EMPTY_USER_ACTION_STATE2;
1235
1239
  });
1240
+ const userActionStateRef = react.useRef(userActionState);
1241
+ userActionStateRef.current = userActionState;
1236
1242
  const storeAwareSetUserActionState = react.useCallback(
1237
1243
  (updater) => {
1238
1244
  const streamUserId = streamUserIdRef.current;
@@ -1260,6 +1266,12 @@ function useChatV2(config, callbacks = {}) {
1260
1266
  onExecutionTraceClick: (data) => callbacksRef.current.onExecutionTraceClick?.(data),
1261
1267
  onSessionIdChange: (sessionId) => callbacksRef.current.onSessionIdChange?.(sessionId),
1262
1268
  onUserActionRequired: (request) => {
1269
+ const requestSlotKey = promptSlotKey(request);
1270
+ for (const [pendingId, slotKey] of pendingSubmissionsRef.current) {
1271
+ if (slotKey === requestSlotKey) {
1272
+ pendingSubmissionsRef.current.delete(pendingId);
1273
+ }
1274
+ }
1263
1275
  storeAwareSetUserActionState((prev) => ({
1264
1276
  ...prev,
1265
1277
  prompts: upsertPrompt(prev.prompts, request)
@@ -1271,6 +1283,28 @@ function useChatV2(config, callbacks = {}) {
1271
1283
  (prev) => prev.notifications.some((n) => n.id === notification.id) ? prev : { ...prev, notifications: [...prev.notifications, notification] }
1272
1284
  );
1273
1285
  callbacksRef.current.onUserNotification?.(notification);
1286
+ },
1287
+ // A submitted-but-unconfirmed prompt (see `submitUserAction`) is only
1288
+ // safe to drop once the stream has demonstrably moved on. `onEvent`
1289
+ // in useStreamManagerV2 calls `onStepsUpdate` for *every* processed
1290
+ // stream event, unconditionally — so the first time this fires
1291
+ // after a submission, the event in hand is either the rejection
1292
+ // retry (a fresh `USER_ACTION_REQUIRED`, which the handler above
1293
+ // already deleted this pending entry for, earlier in the very same
1294
+ // event) or genuine forward progress (RUN_IN_PROGRESS, a tool call,
1295
+ // content deltas, RUN_COMPLETED, ...). Anything still pending by
1296
+ // the time we get here therefore means the run resumed normally —
1297
+ // clear it.
1298
+ onStepsUpdate: (steps) => {
1299
+ if (pendingSubmissionsRef.current.size > 0) {
1300
+ const resolved = [...pendingSubmissionsRef.current.keys()];
1301
+ pendingSubmissionsRef.current.clear();
1302
+ storeAwareSetUserActionState((prev) => ({
1303
+ ...prev,
1304
+ prompts: prev.prompts.filter((p) => !resolved.includes(p.userActionId))
1305
+ }));
1306
+ }
1307
+ callbacksRef.current.onStepsUpdate?.(steps);
1274
1308
  }
1275
1309
  // eslint-disable-next-line react-hooks/exhaustive-deps
1276
1310
  }), []);
@@ -1406,6 +1440,7 @@ function useChatV2(config, callbacks = {}) {
1406
1440
  [storeAwareSetUserActionState]
1407
1441
  );
1408
1442
  const removePrompt = react.useCallback((userActionId) => {
1443
+ pendingSubmissionsRef.current.delete(userActionId);
1409
1444
  storeAwareSetUserActionState((prev) => ({
1410
1445
  ...prev,
1411
1446
  prompts: prev.prompts.filter((p) => p.userActionId !== userActionId)
@@ -1416,7 +1451,10 @@ function useChatV2(config, callbacks = {}) {
1416
1451
  setPromptStatus(userActionId, "submitting");
1417
1452
  try {
1418
1453
  await submitUserAction(configRef.current, userActionId, content);
1419
- removePrompt(userActionId);
1454
+ const prompt = userActionStateRef.current.prompts.find(
1455
+ (p) => p.userActionId === userActionId
1456
+ );
1457
+ pendingSubmissionsRef.current.set(userActionId, prompt ? promptSlotKey(prompt) : userActionId);
1420
1458
  } catch (error) {
1421
1459
  if (error instanceof UserActionStaleError) {
1422
1460
  setPromptStatus(userActionId, "stale");
@@ -1427,7 +1465,7 @@ function useChatV2(config, callbacks = {}) {
1427
1465
  throw error;
1428
1466
  }
1429
1467
  },
1430
- [removePrompt, setPromptStatus]
1468
+ [setPromptStatus]
1431
1469
  );
1432
1470
  const cancelUserAction2 = react.useCallback(
1433
1471
  async (userActionId) => {