@paymanai/payman-typescript-ask-sdk 4.0.25 → 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.
package/dist/index.mjs CHANGED
@@ -274,6 +274,8 @@ function getEventMessage(event) {
274
274
  }
275
275
  case "RUN_IN_PROGRESS":
276
276
  return event.partialText || "Thinking...";
277
+ case "LLM_CALL_STARTED":
278
+ return event.description || "";
277
279
  case "RUN_COMPLETED":
278
280
  return "Agent run completed";
279
281
  case "RUN_FAILED":
@@ -411,7 +413,8 @@ function createInitialV2State() {
411
413
  finalData: void 0,
412
414
  steps: [],
413
415
  stepCounter: 0,
414
- currentExecutingStepId: void 0
416
+ currentExecutingStepId: void 0,
417
+ trailingActivity: false
415
418
  };
416
419
  }
417
420
  function upsertUserAction(state, req) {
@@ -433,6 +436,7 @@ function processStreamEventV2(rawEvent, state) {
433
436
  if (typeof eventType === "string" && eventType.toUpperCase() === "KEEP_ALIVE") {
434
437
  if (event.executionId) state.executionId = event.executionId;
435
438
  if (event.sessionId) state.sessionId = event.sessionId;
439
+ if (state.finalResponse) state.trailingActivity = true;
436
440
  const description = typeof event.description === "string" ? event.description : "";
437
441
  if (description) {
438
442
  for (let i = state.steps.length - 1; i >= 0; i--) {
@@ -467,7 +471,12 @@ function processStreamEventV2(rawEvent, state) {
467
471
  state.lastEventType = eventType;
468
472
  break;
469
473
  }
474
+ case "LLM_CALL_STARTED":
475
+ if (state.finalResponse) state.trailingActivity = true;
476
+ state.lastEventType = eventType;
477
+ break;
470
478
  case "INTENT_STARTED": {
479
+ if (state.finalResponse) state.trailingActivity = true;
471
480
  const stepId = `step-${state.stepCounter++}`;
472
481
  state.steps.push({
473
482
  id: stepId,
@@ -483,6 +492,7 @@ function processStreamEventV2(rawEvent, state) {
483
492
  break;
484
493
  }
485
494
  case "INTENT_COMPLETED": {
495
+ if (state.finalResponse) state.trailingActivity = true;
486
496
  const intentStep = state.steps.find((s) => s.eventType === "INTENT_STARTED" && s.status === "in_progress");
487
497
  if (intentStep) {
488
498
  intentStep.status = "completed";
@@ -514,6 +524,7 @@ function processStreamEventV2(rawEvent, state) {
514
524
  step.status = "completed";
515
525
  }
516
526
  });
527
+ state.trailingActivity = false;
517
528
  state.lastEventType = eventType;
518
529
  break;
519
530
  }
@@ -585,6 +596,7 @@ function processStreamEventV2(rawEvent, state) {
585
596
  case "WORKFLOW_ERROR":
586
597
  state.hasError = true;
587
598
  state.errorMessage = event.errorMessage || event.message || "Workflow error";
599
+ state.trailingActivity = false;
588
600
  state.lastEventType = eventType;
589
601
  break;
590
602
  // ---- K2 pipeline stage lifecycle events ----
@@ -879,7 +891,9 @@ function useStreamManagerV2(config, callbacks, setMessages, setIsWaitingForRespo
879
891
  const latestUsefulStep = [...state.steps].reverse().find(
880
892
  (s) => s.message && !isBlandStatus(s.message)
881
893
  );
882
- const currentMessage = useful(activeStep?.message) ?? useful(lastInProgressStep?.message) ?? latestUsefulStep?.message ?? useful(getEventMessage(event)) ?? // Last-resort: every candidate is bland (very first event,
894
+ const eventTypeUpper = typeof event.eventType === "string" ? event.eventType.toUpperCase() : "";
895
+ const liveEventLabel = eventTypeUpper === "KEEP_ALIVE" || eventTypeUpper === "LLM_CALL_STARTED" ? useful(getEventMessage(event)) : void 0;
896
+ const currentMessage = useful(activeStep?.message) ?? useful(lastInProgressStep?.message) ?? liveEventLabel ?? latestUsefulStep?.message ?? useful(getEventMessage(event)) ?? // Last-resort: every candidate is bland (very first event,
883
897
  // nothing useful seen yet). Render the bland label so the
884
898
  // bubble isn't blank.
885
899
  activeStep?.message ?? lastInProgressStep?.message ?? getEventMessage(event);
@@ -904,6 +918,7 @@ function useStreamManagerV2(config, callbacks, setMessages, setIsWaitingForRespo
904
918
  streamingContent: state.finalResponse,
905
919
  content: "",
906
920
  currentMessage,
921
+ hasTrailingActivity: state.trailingActivity,
907
922
  streamProgress: "processing",
908
923
  isError: false,
909
924
  steps: [...state.steps],
@@ -1131,6 +1146,9 @@ function isUserActionExpired(prompt) {
1131
1146
 
1132
1147
  // src/hooks/useChatV2.ts
1133
1148
  var EMPTY_USER_ACTION_STATE2 = { prompts: [], notifications: [] };
1149
+ function promptSlotKey(p) {
1150
+ return p.toolCallId || p.userActionId;
1151
+ }
1134
1152
  function upsertPrompt(prompts, req) {
1135
1153
  const idx = prompts.findIndex(
1136
1154
  (p) => req.toolCallId ? p.toolCallId === req.toolCallId : p.userActionId === req.userActionId
@@ -1177,6 +1195,7 @@ function useChatV2(config, callbacks = {}) {
1177
1195
  configRef.current = config;
1178
1196
  const messagesRef = useRef(messages);
1179
1197
  messagesRef.current = messages;
1198
+ const pendingSubmissionsRef = useRef(/* @__PURE__ */ new Map());
1180
1199
  const storeAwareSetMessages = useCallback(
1181
1200
  (updater) => {
1182
1201
  const streamUserId = streamUserIdRef.current;
@@ -1211,6 +1230,8 @@ function useChatV2(config, callbacks = {}) {
1211
1230
  if (!config.userId) return EMPTY_USER_ACTION_STATE2;
1212
1231
  return activeStreamStore.get(config.userId)?.userActionState ?? EMPTY_USER_ACTION_STATE2;
1213
1232
  });
1233
+ const userActionStateRef = useRef(userActionState);
1234
+ userActionStateRef.current = userActionState;
1214
1235
  const storeAwareSetUserActionState = useCallback(
1215
1236
  (updater) => {
1216
1237
  const streamUserId = streamUserIdRef.current;
@@ -1238,6 +1259,12 @@ function useChatV2(config, callbacks = {}) {
1238
1259
  onExecutionTraceClick: (data) => callbacksRef.current.onExecutionTraceClick?.(data),
1239
1260
  onSessionIdChange: (sessionId) => callbacksRef.current.onSessionIdChange?.(sessionId),
1240
1261
  onUserActionRequired: (request) => {
1262
+ const requestSlotKey = promptSlotKey(request);
1263
+ for (const [pendingId, slotKey] of pendingSubmissionsRef.current) {
1264
+ if (slotKey === requestSlotKey) {
1265
+ pendingSubmissionsRef.current.delete(pendingId);
1266
+ }
1267
+ }
1241
1268
  storeAwareSetUserActionState((prev) => ({
1242
1269
  ...prev,
1243
1270
  prompts: upsertPrompt(prev.prompts, request)
@@ -1249,6 +1276,28 @@ function useChatV2(config, callbacks = {}) {
1249
1276
  (prev) => prev.notifications.some((n) => n.id === notification.id) ? prev : { ...prev, notifications: [...prev.notifications, notification] }
1250
1277
  );
1251
1278
  callbacksRef.current.onUserNotification?.(notification);
1279
+ },
1280
+ // A submitted-but-unconfirmed prompt (see `submitUserAction`) is only
1281
+ // safe to drop once the stream has demonstrably moved on. `onEvent`
1282
+ // in useStreamManagerV2 calls `onStepsUpdate` for *every* processed
1283
+ // stream event, unconditionally — so the first time this fires
1284
+ // after a submission, the event in hand is either the rejection
1285
+ // retry (a fresh `USER_ACTION_REQUIRED`, which the handler above
1286
+ // already deleted this pending entry for, earlier in the very same
1287
+ // event) or genuine forward progress (RUN_IN_PROGRESS, a tool call,
1288
+ // content deltas, RUN_COMPLETED, ...). Anything still pending by
1289
+ // the time we get here therefore means the run resumed normally —
1290
+ // clear it.
1291
+ onStepsUpdate: (steps) => {
1292
+ if (pendingSubmissionsRef.current.size > 0) {
1293
+ const resolved = [...pendingSubmissionsRef.current.keys()];
1294
+ pendingSubmissionsRef.current.clear();
1295
+ storeAwareSetUserActionState((prev) => ({
1296
+ ...prev,
1297
+ prompts: prev.prompts.filter((p) => !resolved.includes(p.userActionId))
1298
+ }));
1299
+ }
1300
+ callbacksRef.current.onStepsUpdate?.(steps);
1252
1301
  }
1253
1302
  // eslint-disable-next-line react-hooks/exhaustive-deps
1254
1303
  }), []);
@@ -1384,6 +1433,7 @@ function useChatV2(config, callbacks = {}) {
1384
1433
  [storeAwareSetUserActionState]
1385
1434
  );
1386
1435
  const removePrompt = useCallback((userActionId) => {
1436
+ pendingSubmissionsRef.current.delete(userActionId);
1387
1437
  storeAwareSetUserActionState((prev) => ({
1388
1438
  ...prev,
1389
1439
  prompts: prev.prompts.filter((p) => p.userActionId !== userActionId)
@@ -1394,7 +1444,10 @@ function useChatV2(config, callbacks = {}) {
1394
1444
  setPromptStatus(userActionId, "submitting");
1395
1445
  try {
1396
1446
  await submitUserAction(configRef.current, userActionId, content);
1397
- removePrompt(userActionId);
1447
+ const prompt = userActionStateRef.current.prompts.find(
1448
+ (p) => p.userActionId === userActionId
1449
+ );
1450
+ pendingSubmissionsRef.current.set(userActionId, prompt ? promptSlotKey(prompt) : userActionId);
1398
1451
  } catch (error) {
1399
1452
  if (error instanceof UserActionStaleError) {
1400
1453
  setPromptStatus(userActionId, "stale");
@@ -1405,7 +1458,7 @@ function useChatV2(config, callbacks = {}) {
1405
1458
  throw error;
1406
1459
  }
1407
1460
  },
1408
- [removePrompt, setPromptStatus]
1461
+ [setPromptStatus]
1409
1462
  );
1410
1463
  const cancelUserAction2 = useCallback(
1411
1464
  async (userActionId) => {