@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.native.js
CHANGED
|
@@ -36,6 +36,7 @@ var chatStore = {
|
|
|
36
36
|
};
|
|
37
37
|
|
|
38
38
|
// src/utils/activeStreamStore.ts
|
|
39
|
+
var EMPTY_USER_ACTION_STATE = { prompts: [], notifications: [] };
|
|
39
40
|
var streams = /* @__PURE__ */ new Map();
|
|
40
41
|
var activeStreamStore = {
|
|
41
42
|
has(key) {
|
|
@@ -44,7 +45,11 @@ var activeStreamStore = {
|
|
|
44
45
|
get(key) {
|
|
45
46
|
const entry = streams.get(key);
|
|
46
47
|
if (!entry) return null;
|
|
47
|
-
return {
|
|
48
|
+
return {
|
|
49
|
+
messages: entry.messages,
|
|
50
|
+
isWaiting: entry.isWaiting,
|
|
51
|
+
userActionState: entry.userActionState
|
|
52
|
+
};
|
|
48
53
|
},
|
|
49
54
|
// Called before startStream — registers the controller and initial messages
|
|
50
55
|
start(key, abortController, initialMessages) {
|
|
@@ -52,6 +57,7 @@ var activeStreamStore = {
|
|
|
52
57
|
streams.set(key, {
|
|
53
58
|
messages: initialMessages,
|
|
54
59
|
isWaiting: true,
|
|
60
|
+
userActionState: EMPTY_USER_ACTION_STATE,
|
|
55
61
|
abortController,
|
|
56
62
|
listeners: existing?.listeners ?? /* @__PURE__ */ new Set()
|
|
57
63
|
});
|
|
@@ -62,20 +68,27 @@ var activeStreamStore = {
|
|
|
62
68
|
if (!entry) return;
|
|
63
69
|
const next = typeof updater === "function" ? updater(entry.messages) : updater;
|
|
64
70
|
entry.messages = next;
|
|
65
|
-
entry.listeners.forEach((l) => l(next, entry.isWaiting));
|
|
71
|
+
entry.listeners.forEach((l) => l(next, entry.isWaiting, entry.userActionState));
|
|
66
72
|
},
|
|
67
73
|
setWaiting(key, waiting) {
|
|
68
74
|
const entry = streams.get(key);
|
|
69
75
|
if (!entry) return;
|
|
70
76
|
entry.isWaiting = waiting;
|
|
71
|
-
entry.listeners.forEach((l) => l(entry.messages, waiting));
|
|
77
|
+
entry.listeners.forEach((l) => l(entry.messages, waiting, entry.userActionState));
|
|
78
|
+
},
|
|
79
|
+
applyUserActionState(key, updater) {
|
|
80
|
+
const entry = streams.get(key);
|
|
81
|
+
if (!entry) return;
|
|
82
|
+
const next = typeof updater === "function" ? updater(entry.userActionState) : updater;
|
|
83
|
+
entry.userActionState = next;
|
|
84
|
+
entry.listeners.forEach((l) => l(entry.messages, entry.isWaiting, next));
|
|
72
85
|
},
|
|
73
86
|
// Called when stream completes — persists to chatStore and cleans up
|
|
74
87
|
complete(key) {
|
|
75
88
|
const entry = streams.get(key);
|
|
76
89
|
if (!entry) return;
|
|
77
90
|
entry.isWaiting = false;
|
|
78
|
-
entry.listeners.forEach((l) => l(entry.messages, false));
|
|
91
|
+
entry.listeners.forEach((l) => l(entry.messages, false, entry.userActionState));
|
|
79
92
|
const toSave = entry.messages.filter((m) => !m.isStreaming);
|
|
80
93
|
if (toSave.length > 0) chatStore.set(key, toSave);
|
|
81
94
|
streams.delete(key);
|
|
@@ -284,6 +297,8 @@ function getEventMessage(event) {
|
|
|
284
297
|
}
|
|
285
298
|
case "RUN_IN_PROGRESS":
|
|
286
299
|
return event.partialText || "Thinking...";
|
|
300
|
+
case "LLM_CALL_STARTED":
|
|
301
|
+
return event.description || "";
|
|
287
302
|
case "RUN_COMPLETED":
|
|
288
303
|
return "Agent run completed";
|
|
289
304
|
case "RUN_FAILED":
|
|
@@ -421,7 +436,8 @@ function createInitialV2State() {
|
|
|
421
436
|
finalData: void 0,
|
|
422
437
|
steps: [],
|
|
423
438
|
stepCounter: 0,
|
|
424
|
-
currentExecutingStepId: void 0
|
|
439
|
+
currentExecutingStepId: void 0,
|
|
440
|
+
trailingActivity: false
|
|
425
441
|
};
|
|
426
442
|
}
|
|
427
443
|
function upsertUserAction(state, req) {
|
|
@@ -443,6 +459,7 @@ function processStreamEventV2(rawEvent, state) {
|
|
|
443
459
|
if (typeof eventType === "string" && eventType.toUpperCase() === "KEEP_ALIVE") {
|
|
444
460
|
if (event.executionId) state.executionId = event.executionId;
|
|
445
461
|
if (event.sessionId) state.sessionId = event.sessionId;
|
|
462
|
+
if (state.finalResponse) state.trailingActivity = true;
|
|
446
463
|
const description = typeof event.description === "string" ? event.description : "";
|
|
447
464
|
if (description) {
|
|
448
465
|
for (let i = state.steps.length - 1; i >= 0; i--) {
|
|
@@ -477,7 +494,12 @@ function processStreamEventV2(rawEvent, state) {
|
|
|
477
494
|
state.lastEventType = eventType;
|
|
478
495
|
break;
|
|
479
496
|
}
|
|
497
|
+
case "LLM_CALL_STARTED":
|
|
498
|
+
if (state.finalResponse) state.trailingActivity = true;
|
|
499
|
+
state.lastEventType = eventType;
|
|
500
|
+
break;
|
|
480
501
|
case "INTENT_STARTED": {
|
|
502
|
+
if (state.finalResponse) state.trailingActivity = true;
|
|
481
503
|
const stepId = `step-${state.stepCounter++}`;
|
|
482
504
|
state.steps.push({
|
|
483
505
|
id: stepId,
|
|
@@ -493,6 +515,7 @@ function processStreamEventV2(rawEvent, state) {
|
|
|
493
515
|
break;
|
|
494
516
|
}
|
|
495
517
|
case "INTENT_COMPLETED": {
|
|
518
|
+
if (state.finalResponse) state.trailingActivity = true;
|
|
496
519
|
const intentStep = state.steps.find((s) => s.eventType === "INTENT_STARTED" && s.status === "in_progress");
|
|
497
520
|
if (intentStep) {
|
|
498
521
|
intentStep.status = "completed";
|
|
@@ -524,6 +547,7 @@ function processStreamEventV2(rawEvent, state) {
|
|
|
524
547
|
step.status = "completed";
|
|
525
548
|
}
|
|
526
549
|
});
|
|
550
|
+
state.trailingActivity = false;
|
|
527
551
|
state.lastEventType = eventType;
|
|
528
552
|
break;
|
|
529
553
|
}
|
|
@@ -595,6 +619,7 @@ function processStreamEventV2(rawEvent, state) {
|
|
|
595
619
|
case "WORKFLOW_ERROR":
|
|
596
620
|
state.hasError = true;
|
|
597
621
|
state.errorMessage = event.errorMessage || event.message || "Workflow error";
|
|
622
|
+
state.trailingActivity = false;
|
|
598
623
|
state.lastEventType = eventType;
|
|
599
624
|
break;
|
|
600
625
|
// ---- K2 pipeline stage lifecycle events ----
|
|
@@ -889,7 +914,9 @@ function useStreamManagerV2(config, callbacks, setMessages, setIsWaitingForRespo
|
|
|
889
914
|
const latestUsefulStep = [...state.steps].reverse().find(
|
|
890
915
|
(s) => s.message && !isBlandStatus(s.message)
|
|
891
916
|
);
|
|
892
|
-
const
|
|
917
|
+
const eventTypeUpper = typeof event.eventType === "string" ? event.eventType.toUpperCase() : "";
|
|
918
|
+
const liveEventLabel = eventTypeUpper === "KEEP_ALIVE" || eventTypeUpper === "LLM_CALL_STARTED" ? useful(getEventMessage(event)) : void 0;
|
|
919
|
+
const currentMessage = useful(activeStep?.message) ?? useful(lastInProgressStep?.message) ?? liveEventLabel ?? latestUsefulStep?.message ?? useful(getEventMessage(event)) ?? // Last-resort: every candidate is bland (very first event,
|
|
893
920
|
// nothing useful seen yet). Render the bland label so the
|
|
894
921
|
// bubble isn't blank.
|
|
895
922
|
activeStep?.message ?? lastInProgressStep?.message ?? getEventMessage(event);
|
|
@@ -914,6 +941,7 @@ function useStreamManagerV2(config, callbacks, setMessages, setIsWaitingForRespo
|
|
|
914
941
|
streamingContent: state.finalResponse,
|
|
915
942
|
content: "",
|
|
916
943
|
currentMessage,
|
|
944
|
+
hasTrailingActivity: state.trailingActivity,
|
|
917
945
|
streamProgress: "processing",
|
|
918
946
|
isError: false,
|
|
919
947
|
steps: [...state.steps],
|
|
@@ -1115,13 +1143,38 @@ async function expireUserAction(config, userActionId) {
|
|
|
1115
1143
|
return sendUserActionRequest(config, userActionId, "expired");
|
|
1116
1144
|
}
|
|
1117
1145
|
|
|
1146
|
+
// src/utils/userActionExpiry.ts
|
|
1147
|
+
function resolveUserActionExpiresAt(req, existing) {
|
|
1148
|
+
if (typeof req.expirySeconds !== "number" || req.expirySeconds <= 0) {
|
|
1149
|
+
return void 0;
|
|
1150
|
+
}
|
|
1151
|
+
if (existing?.expiresAt && existing.userActionId === req.userActionId) {
|
|
1152
|
+
return existing.expiresAt;
|
|
1153
|
+
}
|
|
1154
|
+
return Date.now() + Math.floor(req.expirySeconds) * 1e3;
|
|
1155
|
+
}
|
|
1156
|
+
function getUserActionSecondsLeft(prompt) {
|
|
1157
|
+
if (typeof prompt.expiresAt === "number" && prompt.expiresAt > 0) {
|
|
1158
|
+
return Math.max(0, Math.ceil((prompt.expiresAt - Date.now()) / 1e3));
|
|
1159
|
+
}
|
|
1160
|
+
if (typeof prompt.expirySeconds === "number" && prompt.expirySeconds > 0) {
|
|
1161
|
+
return Math.floor(prompt.expirySeconds);
|
|
1162
|
+
}
|
|
1163
|
+
return void 0;
|
|
1164
|
+
}
|
|
1165
|
+
function isUserActionExpired(prompt) {
|
|
1166
|
+
const left = getUserActionSecondsLeft(prompt);
|
|
1167
|
+
return left !== void 0 && left <= 0;
|
|
1168
|
+
}
|
|
1169
|
+
|
|
1118
1170
|
// src/hooks/useChatV2.ts
|
|
1119
|
-
var
|
|
1171
|
+
var EMPTY_USER_ACTION_STATE2 = { prompts: [], notifications: [] };
|
|
1120
1172
|
function upsertPrompt(prompts, req) {
|
|
1121
|
-
const active = { ...req, status: "pending" };
|
|
1122
1173
|
const idx = prompts.findIndex(
|
|
1123
1174
|
(p) => req.toolCallId ? p.toolCallId === req.toolCallId : p.userActionId === req.userActionId
|
|
1124
1175
|
);
|
|
1176
|
+
const expiresAt = resolveUserActionExpiresAt(req, idx >= 0 ? prompts[idx] : void 0);
|
|
1177
|
+
const active = { ...req, status: "pending", expiresAt };
|
|
1125
1178
|
if (idx >= 0) {
|
|
1126
1179
|
const next = prompts.slice();
|
|
1127
1180
|
next[idx] = active;
|
|
@@ -1192,7 +1245,28 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1192
1245
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1193
1246
|
[]
|
|
1194
1247
|
);
|
|
1195
|
-
const [userActionState, setUserActionState] = react.useState(
|
|
1248
|
+
const [userActionState, setUserActionState] = react.useState(() => {
|
|
1249
|
+
if (!config.userId) return EMPTY_USER_ACTION_STATE2;
|
|
1250
|
+
return activeStreamStore.get(config.userId)?.userActionState ?? EMPTY_USER_ACTION_STATE2;
|
|
1251
|
+
});
|
|
1252
|
+
const storeAwareSetUserActionState = react.useCallback(
|
|
1253
|
+
(updater) => {
|
|
1254
|
+
const streamUserId = streamUserIdRef.current;
|
|
1255
|
+
const currentUserId = configRef.current.userId;
|
|
1256
|
+
const storeKey = streamUserId ?? currentUserId;
|
|
1257
|
+
if (storeKey && activeStreamStore.has(storeKey)) {
|
|
1258
|
+
activeStreamStore.applyUserActionState(
|
|
1259
|
+
storeKey,
|
|
1260
|
+
updater
|
|
1261
|
+
);
|
|
1262
|
+
}
|
|
1263
|
+
if (!streamUserId || streamUserId === currentUserId) {
|
|
1264
|
+
setUserActionState(updater);
|
|
1265
|
+
}
|
|
1266
|
+
},
|
|
1267
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1268
|
+
[]
|
|
1269
|
+
);
|
|
1196
1270
|
const wrappedCallbacks = react.useMemo(() => ({
|
|
1197
1271
|
...callbacksRef.current,
|
|
1198
1272
|
onMessageSent: (message) => callbacksRef.current.onMessageSent?.(message),
|
|
@@ -1202,14 +1276,14 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1202
1276
|
onExecutionTraceClick: (data) => callbacksRef.current.onExecutionTraceClick?.(data),
|
|
1203
1277
|
onSessionIdChange: (sessionId) => callbacksRef.current.onSessionIdChange?.(sessionId),
|
|
1204
1278
|
onUserActionRequired: (request) => {
|
|
1205
|
-
|
|
1279
|
+
storeAwareSetUserActionState((prev) => ({
|
|
1206
1280
|
...prev,
|
|
1207
1281
|
prompts: upsertPrompt(prev.prompts, request)
|
|
1208
1282
|
}));
|
|
1209
1283
|
callbacksRef.current.onUserActionRequired?.(request);
|
|
1210
1284
|
},
|
|
1211
1285
|
onUserNotification: (notification) => {
|
|
1212
|
-
|
|
1286
|
+
storeAwareSetUserActionState(
|
|
1213
1287
|
(prev) => prev.notifications.some((n) => n.id === notification.id) ? prev : { ...prev, notifications: [...prev.notifications, notification] }
|
|
1214
1288
|
);
|
|
1215
1289
|
callbacksRef.current.onUserNotification?.(notification);
|
|
@@ -1299,7 +1373,7 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1299
1373
|
streamUserIdRef.current = void 0;
|
|
1300
1374
|
cancelStreamManager();
|
|
1301
1375
|
setIsWaitingForResponse(false);
|
|
1302
|
-
|
|
1376
|
+
storeAwareSetUserActionState((prev) => ({ ...prev, prompts: [] }));
|
|
1303
1377
|
setMessages(
|
|
1304
1378
|
(prev) => prev.map((msg) => {
|
|
1305
1379
|
if (msg.isStreaming) {
|
|
@@ -1314,7 +1388,7 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1314
1388
|
return msg;
|
|
1315
1389
|
})
|
|
1316
1390
|
);
|
|
1317
|
-
}, [cancelStreamManager]);
|
|
1391
|
+
}, [cancelStreamManager, storeAwareSetUserActionState]);
|
|
1318
1392
|
const resetSession = react.useCallback(() => {
|
|
1319
1393
|
const streamUserId = streamUserIdRef.current ?? configRef.current.userId;
|
|
1320
1394
|
if (streamUserId) {
|
|
@@ -1328,7 +1402,7 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1328
1402
|
sessionIdRef.current = void 0;
|
|
1329
1403
|
abortControllerRef.current?.abort();
|
|
1330
1404
|
setIsWaitingForResponse(false);
|
|
1331
|
-
|
|
1405
|
+
storeAwareSetUserActionState(EMPTY_USER_ACTION_STATE2);
|
|
1332
1406
|
}, []);
|
|
1333
1407
|
const getSessionId = react.useCallback(() => {
|
|
1334
1408
|
return sessionIdRef.current;
|
|
@@ -1338,21 +1412,21 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1338
1412
|
}, [messages]);
|
|
1339
1413
|
const setPromptStatus = react.useCallback(
|
|
1340
1414
|
(userActionId, status) => {
|
|
1341
|
-
|
|
1415
|
+
storeAwareSetUserActionState((prev) => ({
|
|
1342
1416
|
...prev,
|
|
1343
1417
|
prompts: prev.prompts.map(
|
|
1344
1418
|
(p) => p.userActionId === userActionId ? { ...p, status } : p
|
|
1345
1419
|
)
|
|
1346
1420
|
}));
|
|
1347
1421
|
},
|
|
1348
|
-
[]
|
|
1422
|
+
[storeAwareSetUserActionState]
|
|
1349
1423
|
);
|
|
1350
1424
|
const removePrompt = react.useCallback((userActionId) => {
|
|
1351
|
-
|
|
1425
|
+
storeAwareSetUserActionState((prev) => ({
|
|
1352
1426
|
...prev,
|
|
1353
1427
|
prompts: prev.prompts.filter((p) => p.userActionId !== userActionId)
|
|
1354
1428
|
}));
|
|
1355
|
-
}, []);
|
|
1429
|
+
}, [storeAwareSetUserActionState]);
|
|
1356
1430
|
const submitUserAction2 = react.useCallback(
|
|
1357
1431
|
async (userActionId, content) => {
|
|
1358
1432
|
setPromptStatus(userActionId, "submitting");
|
|
@@ -1421,11 +1495,11 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1421
1495
|
[setPromptStatus]
|
|
1422
1496
|
);
|
|
1423
1497
|
const dismissNotification = react.useCallback((id) => {
|
|
1424
|
-
|
|
1498
|
+
storeAwareSetUserActionState((prev) => ({
|
|
1425
1499
|
...prev,
|
|
1426
1500
|
notifications: prev.notifications.filter((n) => n.id !== id)
|
|
1427
1501
|
}));
|
|
1428
|
-
}, []);
|
|
1502
|
+
}, [storeAwareSetUserActionState]);
|
|
1429
1503
|
react.useEffect(() => {
|
|
1430
1504
|
const prevSubscriptionUserId = subscriptionPrevUserIdRef.current;
|
|
1431
1505
|
subscriptionPrevUserIdRef.current = config.userId;
|
|
@@ -1434,14 +1508,17 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1434
1508
|
if (prevSubscriptionUserId && prevSubscriptionUserId !== userId && streamUserIdRef.current === prevSubscriptionUserId && !activeStreamStore.has(prevSubscriptionUserId) && activeStreamStore.has(userId)) {
|
|
1435
1509
|
streamUserIdRef.current = userId;
|
|
1436
1510
|
}
|
|
1437
|
-
const unsubscribe = activeStreamStore.subscribe(userId, (msgs, isWaiting) => {
|
|
1511
|
+
const unsubscribe = activeStreamStore.subscribe(userId, (msgs, isWaiting, actions) => {
|
|
1438
1512
|
setMessages(msgs);
|
|
1439
1513
|
setIsWaitingForResponse(isWaiting);
|
|
1514
|
+
setUserActionState(actions);
|
|
1440
1515
|
});
|
|
1441
1516
|
const active = activeStreamStore.get(userId);
|
|
1442
1517
|
if (active) {
|
|
1518
|
+
streamUserIdRef.current = userId;
|
|
1443
1519
|
setMessages(active.messages);
|
|
1444
1520
|
setIsWaitingForResponse(active.isWaiting);
|
|
1521
|
+
setUserActionState(active.userActionState);
|
|
1445
1522
|
}
|
|
1446
1523
|
return unsubscribe;
|
|
1447
1524
|
}, [config.userId]);
|
|
@@ -1469,12 +1546,14 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1469
1546
|
setMessages([]);
|
|
1470
1547
|
sessionIdRef.current = void 0;
|
|
1471
1548
|
setIsWaitingForResponse(false);
|
|
1472
|
-
setUserActionState(
|
|
1549
|
+
setUserActionState(EMPTY_USER_ACTION_STATE2);
|
|
1473
1550
|
} else if (config.userId) {
|
|
1474
1551
|
const active = activeStreamStore.get(config.userId);
|
|
1475
1552
|
if (active) {
|
|
1553
|
+
streamUserIdRef.current = config.userId;
|
|
1476
1554
|
setMessages(active.messages);
|
|
1477
1555
|
setIsWaitingForResponse(active.isWaiting);
|
|
1556
|
+
setUserActionState(active.userActionState);
|
|
1478
1557
|
sessionIdRef.current = getSessionIdFromMessages(active.messages) ?? config.initialSessionId;
|
|
1479
1558
|
return;
|
|
1480
1559
|
}
|
|
@@ -1753,12 +1832,15 @@ exports.defaultValueFor = defaultValueFor;
|
|
|
1753
1832
|
exports.expireUserAction = expireUserAction;
|
|
1754
1833
|
exports.generateId = generateId;
|
|
1755
1834
|
exports.getOptions = getOptions;
|
|
1835
|
+
exports.getUserActionSecondsLeft = getUserActionSecondsLeft;
|
|
1756
1836
|
exports.isNestedOrUnsupported = isNestedOrUnsupported;
|
|
1757
1837
|
exports.isRequired = isRequired;
|
|
1838
|
+
exports.isUserActionExpired = isUserActionExpired;
|
|
1758
1839
|
exports.migrateActiveStream = migrateActiveStream;
|
|
1759
1840
|
exports.processStreamEventV2 = processStreamEventV2;
|
|
1760
1841
|
exports.renderableFields = renderableFields;
|
|
1761
1842
|
exports.resendUserAction = resendUserAction;
|
|
1843
|
+
exports.resolveUserActionExpiresAt = resolveUserActionExpiresAt;
|
|
1762
1844
|
exports.streamWorkflowEvents = streamWorkflowEvents;
|
|
1763
1845
|
exports.submitUserAction = submitUserAction;
|
|
1764
1846
|
exports.useChatV2 = useChatV2;
|