@paymanai/payman-typescript-ask-sdk 4.0.24 → 4.0.26
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.d.mts +27 -1
- package/dist/index.d.ts +27 -1
- package/dist/index.js +104 -22
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +102 -23
- package/dist/index.mjs.map +1 -1
- package/dist/index.native.js +104 -22
- package/dist/index.native.js.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -28,6 +28,7 @@ var chatStore = {
|
|
|
28
28
|
};
|
|
29
29
|
|
|
30
30
|
// src/utils/activeStreamStore.ts
|
|
31
|
+
var EMPTY_USER_ACTION_STATE = { prompts: [], notifications: [] };
|
|
31
32
|
var streams = /* @__PURE__ */ new Map();
|
|
32
33
|
var activeStreamStore = {
|
|
33
34
|
has(key) {
|
|
@@ -36,7 +37,11 @@ var activeStreamStore = {
|
|
|
36
37
|
get(key) {
|
|
37
38
|
const entry = streams.get(key);
|
|
38
39
|
if (!entry) return null;
|
|
39
|
-
return {
|
|
40
|
+
return {
|
|
41
|
+
messages: entry.messages,
|
|
42
|
+
isWaiting: entry.isWaiting,
|
|
43
|
+
userActionState: entry.userActionState
|
|
44
|
+
};
|
|
40
45
|
},
|
|
41
46
|
// Called before startStream — registers the controller and initial messages
|
|
42
47
|
start(key, abortController, initialMessages) {
|
|
@@ -44,6 +49,7 @@ var activeStreamStore = {
|
|
|
44
49
|
streams.set(key, {
|
|
45
50
|
messages: initialMessages,
|
|
46
51
|
isWaiting: true,
|
|
52
|
+
userActionState: EMPTY_USER_ACTION_STATE,
|
|
47
53
|
abortController,
|
|
48
54
|
listeners: existing?.listeners ?? /* @__PURE__ */ new Set()
|
|
49
55
|
});
|
|
@@ -54,20 +60,27 @@ var activeStreamStore = {
|
|
|
54
60
|
if (!entry) return;
|
|
55
61
|
const next = typeof updater === "function" ? updater(entry.messages) : updater;
|
|
56
62
|
entry.messages = next;
|
|
57
|
-
entry.listeners.forEach((l) => l(next, entry.isWaiting));
|
|
63
|
+
entry.listeners.forEach((l) => l(next, entry.isWaiting, entry.userActionState));
|
|
58
64
|
},
|
|
59
65
|
setWaiting(key, waiting) {
|
|
60
66
|
const entry = streams.get(key);
|
|
61
67
|
if (!entry) return;
|
|
62
68
|
entry.isWaiting = waiting;
|
|
63
|
-
entry.listeners.forEach((l) => l(entry.messages, waiting));
|
|
69
|
+
entry.listeners.forEach((l) => l(entry.messages, waiting, entry.userActionState));
|
|
70
|
+
},
|
|
71
|
+
applyUserActionState(key, updater) {
|
|
72
|
+
const entry = streams.get(key);
|
|
73
|
+
if (!entry) return;
|
|
74
|
+
const next = typeof updater === "function" ? updater(entry.userActionState) : updater;
|
|
75
|
+
entry.userActionState = next;
|
|
76
|
+
entry.listeners.forEach((l) => l(entry.messages, entry.isWaiting, next));
|
|
64
77
|
},
|
|
65
78
|
// Called when stream completes — persists to chatStore and cleans up
|
|
66
79
|
complete(key) {
|
|
67
80
|
const entry = streams.get(key);
|
|
68
81
|
if (!entry) return;
|
|
69
82
|
entry.isWaiting = false;
|
|
70
|
-
entry.listeners.forEach((l) => l(entry.messages, false));
|
|
83
|
+
entry.listeners.forEach((l) => l(entry.messages, false, entry.userActionState));
|
|
71
84
|
const toSave = entry.messages.filter((m) => !m.isStreaming);
|
|
72
85
|
if (toSave.length > 0) chatStore.set(key, toSave);
|
|
73
86
|
streams.delete(key);
|
|
@@ -261,6 +274,8 @@ function getEventMessage(event) {
|
|
|
261
274
|
}
|
|
262
275
|
case "RUN_IN_PROGRESS":
|
|
263
276
|
return event.partialText || "Thinking...";
|
|
277
|
+
case "LLM_CALL_STARTED":
|
|
278
|
+
return event.description || "";
|
|
264
279
|
case "RUN_COMPLETED":
|
|
265
280
|
return "Agent run completed";
|
|
266
281
|
case "RUN_FAILED":
|
|
@@ -398,7 +413,8 @@ function createInitialV2State() {
|
|
|
398
413
|
finalData: void 0,
|
|
399
414
|
steps: [],
|
|
400
415
|
stepCounter: 0,
|
|
401
|
-
currentExecutingStepId: void 0
|
|
416
|
+
currentExecutingStepId: void 0,
|
|
417
|
+
trailingActivity: false
|
|
402
418
|
};
|
|
403
419
|
}
|
|
404
420
|
function upsertUserAction(state, req) {
|
|
@@ -420,6 +436,7 @@ function processStreamEventV2(rawEvent, state) {
|
|
|
420
436
|
if (typeof eventType === "string" && eventType.toUpperCase() === "KEEP_ALIVE") {
|
|
421
437
|
if (event.executionId) state.executionId = event.executionId;
|
|
422
438
|
if (event.sessionId) state.sessionId = event.sessionId;
|
|
439
|
+
if (state.finalResponse) state.trailingActivity = true;
|
|
423
440
|
const description = typeof event.description === "string" ? event.description : "";
|
|
424
441
|
if (description) {
|
|
425
442
|
for (let i = state.steps.length - 1; i >= 0; i--) {
|
|
@@ -454,7 +471,12 @@ function processStreamEventV2(rawEvent, state) {
|
|
|
454
471
|
state.lastEventType = eventType;
|
|
455
472
|
break;
|
|
456
473
|
}
|
|
474
|
+
case "LLM_CALL_STARTED":
|
|
475
|
+
if (state.finalResponse) state.trailingActivity = true;
|
|
476
|
+
state.lastEventType = eventType;
|
|
477
|
+
break;
|
|
457
478
|
case "INTENT_STARTED": {
|
|
479
|
+
if (state.finalResponse) state.trailingActivity = true;
|
|
458
480
|
const stepId = `step-${state.stepCounter++}`;
|
|
459
481
|
state.steps.push({
|
|
460
482
|
id: stepId,
|
|
@@ -470,6 +492,7 @@ function processStreamEventV2(rawEvent, state) {
|
|
|
470
492
|
break;
|
|
471
493
|
}
|
|
472
494
|
case "INTENT_COMPLETED": {
|
|
495
|
+
if (state.finalResponse) state.trailingActivity = true;
|
|
473
496
|
const intentStep = state.steps.find((s) => s.eventType === "INTENT_STARTED" && s.status === "in_progress");
|
|
474
497
|
if (intentStep) {
|
|
475
498
|
intentStep.status = "completed";
|
|
@@ -501,6 +524,7 @@ function processStreamEventV2(rawEvent, state) {
|
|
|
501
524
|
step.status = "completed";
|
|
502
525
|
}
|
|
503
526
|
});
|
|
527
|
+
state.trailingActivity = false;
|
|
504
528
|
state.lastEventType = eventType;
|
|
505
529
|
break;
|
|
506
530
|
}
|
|
@@ -572,6 +596,7 @@ function processStreamEventV2(rawEvent, state) {
|
|
|
572
596
|
case "WORKFLOW_ERROR":
|
|
573
597
|
state.hasError = true;
|
|
574
598
|
state.errorMessage = event.errorMessage || event.message || "Workflow error";
|
|
599
|
+
state.trailingActivity = false;
|
|
575
600
|
state.lastEventType = eventType;
|
|
576
601
|
break;
|
|
577
602
|
// ---- K2 pipeline stage lifecycle events ----
|
|
@@ -866,7 +891,9 @@ function useStreamManagerV2(config, callbacks, setMessages, setIsWaitingForRespo
|
|
|
866
891
|
const latestUsefulStep = [...state.steps].reverse().find(
|
|
867
892
|
(s) => s.message && !isBlandStatus(s.message)
|
|
868
893
|
);
|
|
869
|
-
const
|
|
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,
|
|
870
897
|
// nothing useful seen yet). Render the bland label so the
|
|
871
898
|
// bubble isn't blank.
|
|
872
899
|
activeStep?.message ?? lastInProgressStep?.message ?? getEventMessage(event);
|
|
@@ -891,6 +918,7 @@ function useStreamManagerV2(config, callbacks, setMessages, setIsWaitingForRespo
|
|
|
891
918
|
streamingContent: state.finalResponse,
|
|
892
919
|
content: "",
|
|
893
920
|
currentMessage,
|
|
921
|
+
hasTrailingActivity: state.trailingActivity,
|
|
894
922
|
streamProgress: "processing",
|
|
895
923
|
isError: false,
|
|
896
924
|
steps: [...state.steps],
|
|
@@ -1092,13 +1120,38 @@ async function expireUserAction(config, userActionId) {
|
|
|
1092
1120
|
return sendUserActionRequest(config, userActionId, "expired");
|
|
1093
1121
|
}
|
|
1094
1122
|
|
|
1123
|
+
// src/utils/userActionExpiry.ts
|
|
1124
|
+
function resolveUserActionExpiresAt(req, existing) {
|
|
1125
|
+
if (typeof req.expirySeconds !== "number" || req.expirySeconds <= 0) {
|
|
1126
|
+
return void 0;
|
|
1127
|
+
}
|
|
1128
|
+
if (existing?.expiresAt && existing.userActionId === req.userActionId) {
|
|
1129
|
+
return existing.expiresAt;
|
|
1130
|
+
}
|
|
1131
|
+
return Date.now() + Math.floor(req.expirySeconds) * 1e3;
|
|
1132
|
+
}
|
|
1133
|
+
function getUserActionSecondsLeft(prompt) {
|
|
1134
|
+
if (typeof prompt.expiresAt === "number" && prompt.expiresAt > 0) {
|
|
1135
|
+
return Math.max(0, Math.ceil((prompt.expiresAt - Date.now()) / 1e3));
|
|
1136
|
+
}
|
|
1137
|
+
if (typeof prompt.expirySeconds === "number" && prompt.expirySeconds > 0) {
|
|
1138
|
+
return Math.floor(prompt.expirySeconds);
|
|
1139
|
+
}
|
|
1140
|
+
return void 0;
|
|
1141
|
+
}
|
|
1142
|
+
function isUserActionExpired(prompt) {
|
|
1143
|
+
const left = getUserActionSecondsLeft(prompt);
|
|
1144
|
+
return left !== void 0 && left <= 0;
|
|
1145
|
+
}
|
|
1146
|
+
|
|
1095
1147
|
// src/hooks/useChatV2.ts
|
|
1096
|
-
var
|
|
1148
|
+
var EMPTY_USER_ACTION_STATE2 = { prompts: [], notifications: [] };
|
|
1097
1149
|
function upsertPrompt(prompts, req) {
|
|
1098
|
-
const active = { ...req, status: "pending" };
|
|
1099
1150
|
const idx = prompts.findIndex(
|
|
1100
1151
|
(p) => req.toolCallId ? p.toolCallId === req.toolCallId : p.userActionId === req.userActionId
|
|
1101
1152
|
);
|
|
1153
|
+
const expiresAt = resolveUserActionExpiresAt(req, idx >= 0 ? prompts[idx] : void 0);
|
|
1154
|
+
const active = { ...req, status: "pending", expiresAt };
|
|
1102
1155
|
if (idx >= 0) {
|
|
1103
1156
|
const next = prompts.slice();
|
|
1104
1157
|
next[idx] = active;
|
|
@@ -1169,7 +1222,28 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1169
1222
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1170
1223
|
[]
|
|
1171
1224
|
);
|
|
1172
|
-
const [userActionState, setUserActionState] = useState(
|
|
1225
|
+
const [userActionState, setUserActionState] = useState(() => {
|
|
1226
|
+
if (!config.userId) return EMPTY_USER_ACTION_STATE2;
|
|
1227
|
+
return activeStreamStore.get(config.userId)?.userActionState ?? EMPTY_USER_ACTION_STATE2;
|
|
1228
|
+
});
|
|
1229
|
+
const storeAwareSetUserActionState = useCallback(
|
|
1230
|
+
(updater) => {
|
|
1231
|
+
const streamUserId = streamUserIdRef.current;
|
|
1232
|
+
const currentUserId = configRef.current.userId;
|
|
1233
|
+
const storeKey = streamUserId ?? currentUserId;
|
|
1234
|
+
if (storeKey && activeStreamStore.has(storeKey)) {
|
|
1235
|
+
activeStreamStore.applyUserActionState(
|
|
1236
|
+
storeKey,
|
|
1237
|
+
updater
|
|
1238
|
+
);
|
|
1239
|
+
}
|
|
1240
|
+
if (!streamUserId || streamUserId === currentUserId) {
|
|
1241
|
+
setUserActionState(updater);
|
|
1242
|
+
}
|
|
1243
|
+
},
|
|
1244
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1245
|
+
[]
|
|
1246
|
+
);
|
|
1173
1247
|
const wrappedCallbacks = useMemo(() => ({
|
|
1174
1248
|
...callbacksRef.current,
|
|
1175
1249
|
onMessageSent: (message) => callbacksRef.current.onMessageSent?.(message),
|
|
@@ -1179,14 +1253,14 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1179
1253
|
onExecutionTraceClick: (data) => callbacksRef.current.onExecutionTraceClick?.(data),
|
|
1180
1254
|
onSessionIdChange: (sessionId) => callbacksRef.current.onSessionIdChange?.(sessionId),
|
|
1181
1255
|
onUserActionRequired: (request) => {
|
|
1182
|
-
|
|
1256
|
+
storeAwareSetUserActionState((prev) => ({
|
|
1183
1257
|
...prev,
|
|
1184
1258
|
prompts: upsertPrompt(prev.prompts, request)
|
|
1185
1259
|
}));
|
|
1186
1260
|
callbacksRef.current.onUserActionRequired?.(request);
|
|
1187
1261
|
},
|
|
1188
1262
|
onUserNotification: (notification) => {
|
|
1189
|
-
|
|
1263
|
+
storeAwareSetUserActionState(
|
|
1190
1264
|
(prev) => prev.notifications.some((n) => n.id === notification.id) ? prev : { ...prev, notifications: [...prev.notifications, notification] }
|
|
1191
1265
|
);
|
|
1192
1266
|
callbacksRef.current.onUserNotification?.(notification);
|
|
@@ -1276,7 +1350,7 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1276
1350
|
streamUserIdRef.current = void 0;
|
|
1277
1351
|
cancelStreamManager();
|
|
1278
1352
|
setIsWaitingForResponse(false);
|
|
1279
|
-
|
|
1353
|
+
storeAwareSetUserActionState((prev) => ({ ...prev, prompts: [] }));
|
|
1280
1354
|
setMessages(
|
|
1281
1355
|
(prev) => prev.map((msg) => {
|
|
1282
1356
|
if (msg.isStreaming) {
|
|
@@ -1291,7 +1365,7 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1291
1365
|
return msg;
|
|
1292
1366
|
})
|
|
1293
1367
|
);
|
|
1294
|
-
}, [cancelStreamManager]);
|
|
1368
|
+
}, [cancelStreamManager, storeAwareSetUserActionState]);
|
|
1295
1369
|
const resetSession = useCallback(() => {
|
|
1296
1370
|
const streamUserId = streamUserIdRef.current ?? configRef.current.userId;
|
|
1297
1371
|
if (streamUserId) {
|
|
@@ -1305,7 +1379,7 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1305
1379
|
sessionIdRef.current = void 0;
|
|
1306
1380
|
abortControllerRef.current?.abort();
|
|
1307
1381
|
setIsWaitingForResponse(false);
|
|
1308
|
-
|
|
1382
|
+
storeAwareSetUserActionState(EMPTY_USER_ACTION_STATE2);
|
|
1309
1383
|
}, []);
|
|
1310
1384
|
const getSessionId = useCallback(() => {
|
|
1311
1385
|
return sessionIdRef.current;
|
|
@@ -1315,21 +1389,21 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1315
1389
|
}, [messages]);
|
|
1316
1390
|
const setPromptStatus = useCallback(
|
|
1317
1391
|
(userActionId, status) => {
|
|
1318
|
-
|
|
1392
|
+
storeAwareSetUserActionState((prev) => ({
|
|
1319
1393
|
...prev,
|
|
1320
1394
|
prompts: prev.prompts.map(
|
|
1321
1395
|
(p) => p.userActionId === userActionId ? { ...p, status } : p
|
|
1322
1396
|
)
|
|
1323
1397
|
}));
|
|
1324
1398
|
},
|
|
1325
|
-
[]
|
|
1399
|
+
[storeAwareSetUserActionState]
|
|
1326
1400
|
);
|
|
1327
1401
|
const removePrompt = useCallback((userActionId) => {
|
|
1328
|
-
|
|
1402
|
+
storeAwareSetUserActionState((prev) => ({
|
|
1329
1403
|
...prev,
|
|
1330
1404
|
prompts: prev.prompts.filter((p) => p.userActionId !== userActionId)
|
|
1331
1405
|
}));
|
|
1332
|
-
}, []);
|
|
1406
|
+
}, [storeAwareSetUserActionState]);
|
|
1333
1407
|
const submitUserAction2 = useCallback(
|
|
1334
1408
|
async (userActionId, content) => {
|
|
1335
1409
|
setPromptStatus(userActionId, "submitting");
|
|
@@ -1398,11 +1472,11 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1398
1472
|
[setPromptStatus]
|
|
1399
1473
|
);
|
|
1400
1474
|
const dismissNotification = useCallback((id) => {
|
|
1401
|
-
|
|
1475
|
+
storeAwareSetUserActionState((prev) => ({
|
|
1402
1476
|
...prev,
|
|
1403
1477
|
notifications: prev.notifications.filter((n) => n.id !== id)
|
|
1404
1478
|
}));
|
|
1405
|
-
}, []);
|
|
1479
|
+
}, [storeAwareSetUserActionState]);
|
|
1406
1480
|
useEffect(() => {
|
|
1407
1481
|
const prevSubscriptionUserId = subscriptionPrevUserIdRef.current;
|
|
1408
1482
|
subscriptionPrevUserIdRef.current = config.userId;
|
|
@@ -1411,14 +1485,17 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1411
1485
|
if (prevSubscriptionUserId && prevSubscriptionUserId !== userId && streamUserIdRef.current === prevSubscriptionUserId && !activeStreamStore.has(prevSubscriptionUserId) && activeStreamStore.has(userId)) {
|
|
1412
1486
|
streamUserIdRef.current = userId;
|
|
1413
1487
|
}
|
|
1414
|
-
const unsubscribe = activeStreamStore.subscribe(userId, (msgs, isWaiting) => {
|
|
1488
|
+
const unsubscribe = activeStreamStore.subscribe(userId, (msgs, isWaiting, actions) => {
|
|
1415
1489
|
setMessages(msgs);
|
|
1416
1490
|
setIsWaitingForResponse(isWaiting);
|
|
1491
|
+
setUserActionState(actions);
|
|
1417
1492
|
});
|
|
1418
1493
|
const active = activeStreamStore.get(userId);
|
|
1419
1494
|
if (active) {
|
|
1495
|
+
streamUserIdRef.current = userId;
|
|
1420
1496
|
setMessages(active.messages);
|
|
1421
1497
|
setIsWaitingForResponse(active.isWaiting);
|
|
1498
|
+
setUserActionState(active.userActionState);
|
|
1422
1499
|
}
|
|
1423
1500
|
return unsubscribe;
|
|
1424
1501
|
}, [config.userId]);
|
|
@@ -1446,12 +1523,14 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1446
1523
|
setMessages([]);
|
|
1447
1524
|
sessionIdRef.current = void 0;
|
|
1448
1525
|
setIsWaitingForResponse(false);
|
|
1449
|
-
setUserActionState(
|
|
1526
|
+
setUserActionState(EMPTY_USER_ACTION_STATE2);
|
|
1450
1527
|
} else if (config.userId) {
|
|
1451
1528
|
const active = activeStreamStore.get(config.userId);
|
|
1452
1529
|
if (active) {
|
|
1530
|
+
streamUserIdRef.current = config.userId;
|
|
1453
1531
|
setMessages(active.messages);
|
|
1454
1532
|
setIsWaitingForResponse(active.isWaiting);
|
|
1533
|
+
setUserActionState(active.userActionState);
|
|
1455
1534
|
sessionIdRef.current = getSessionIdFromMessages(active.messages) ?? config.initialSessionId;
|
|
1456
1535
|
return;
|
|
1457
1536
|
}
|
|
@@ -1819,6 +1898,6 @@ function migrateActiveStream(oldUserId, newUserId) {
|
|
|
1819
1898
|
activeStreamStore.rename(oldUserId, newUserId);
|
|
1820
1899
|
}
|
|
1821
1900
|
|
|
1822
|
-
export { UserActionStaleError, buildContent, cancelUserAction, classifyField, classifyUserActionKind, coerceValue, createInitialV2State, defaultValueFor, expireUserAction, generateId, getOptions, isNestedOrUnsupported, isRequired, migrateActiveStream, processStreamEventV2, renderableFields, resendUserAction, streamWorkflowEvents, submitUserAction, useChatV2, useVoice, validateField, validateForm };
|
|
1901
|
+
export { UserActionStaleError, buildContent, cancelUserAction, classifyField, classifyUserActionKind, coerceValue, createInitialV2State, defaultValueFor, expireUserAction, generateId, getOptions, getUserActionSecondsLeft, isNestedOrUnsupported, isRequired, isUserActionExpired, migrateActiveStream, processStreamEventV2, renderableFields, resendUserAction, resolveUserActionExpiresAt, streamWorkflowEvents, submitUserAction, useChatV2, useVoice, validateField, validateForm };
|
|
1823
1902
|
//# sourceMappingURL=index.mjs.map
|
|
1824
1903
|
//# sourceMappingURL=index.mjs.map
|