@paymanai/payman-typescript-ask-sdk 1.0.2 → 1.1.0
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 +50 -2
- package/dist/index.d.ts +50 -2
- package/dist/index.js +303 -23
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +302 -25
- package/dist/index.mjs.map +1 -1
- package/dist/index.native.js +303 -23
- package/dist/index.native.js.map +1 -1
- package/package.json +1 -1
package/dist/index.native.js
CHANGED
|
@@ -137,10 +137,10 @@ async function streamWorkflowEvents(url, body, headers, options = {}) {
|
|
|
137
137
|
// src/utils/eventProcessor.ts
|
|
138
138
|
function getEventMessage(event) {
|
|
139
139
|
if (event.message?.trim()) {
|
|
140
|
-
return event.message;
|
|
140
|
+
return event.message.trim();
|
|
141
141
|
}
|
|
142
142
|
if (event.errorMessage?.trim()) {
|
|
143
|
-
return event.errorMessage;
|
|
143
|
+
return event.errorMessage.trim();
|
|
144
144
|
}
|
|
145
145
|
const eventType = event.eventType;
|
|
146
146
|
switch (eventType) {
|
|
@@ -168,6 +168,20 @@ function getEventMessage(event) {
|
|
|
168
168
|
case "WORKFLOW_ERROR":
|
|
169
169
|
case "INTENT_ERROR":
|
|
170
170
|
return event.errorMessage || "An error occurred";
|
|
171
|
+
case "USER_ACTION_REQUIRED":
|
|
172
|
+
return "Waiting for verification...";
|
|
173
|
+
case "USER_ACTION_SUCCESS":
|
|
174
|
+
return "Verification successful";
|
|
175
|
+
case "USER_ACTION_EXPIRED":
|
|
176
|
+
return "Verification expired";
|
|
177
|
+
case "USER_ACTION_INVALID":
|
|
178
|
+
return "Invalid input, please try again";
|
|
179
|
+
case "USER_ACTION_REJECTED":
|
|
180
|
+
return "Verification rejected";
|
|
181
|
+
case "USER_ACTION_RESENT":
|
|
182
|
+
return "Verification code resent";
|
|
183
|
+
case "USER_ACTION_FAILED":
|
|
184
|
+
return "Verification failed";
|
|
171
185
|
default:
|
|
172
186
|
return eventType;
|
|
173
187
|
}
|
|
@@ -194,6 +208,14 @@ function extractResponseContent(response) {
|
|
|
194
208
|
}
|
|
195
209
|
return "";
|
|
196
210
|
}
|
|
211
|
+
function completeLastInProgressStep(steps) {
|
|
212
|
+
for (let i = steps.length - 1; i >= 0; i--) {
|
|
213
|
+
if (steps[i].status === "in_progress") {
|
|
214
|
+
steps[i].status = "completed";
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
197
219
|
function processStreamEvent(event, state) {
|
|
198
220
|
const eventType = event.eventType;
|
|
199
221
|
const message = getEventMessage(event);
|
|
@@ -293,6 +315,110 @@ function processStreamEvent(event, state) {
|
|
|
293
315
|
});
|
|
294
316
|
state.currentExecutingStepId = stepId;
|
|
295
317
|
}
|
|
318
|
+
} else if (eventType === "USER_ACTION_REQUIRED") {
|
|
319
|
+
completeLastInProgressStep(state.steps);
|
|
320
|
+
if (event.userActionRequest) {
|
|
321
|
+
state.userActionRequest = {
|
|
322
|
+
userActionId: event.userActionRequest.userActionId,
|
|
323
|
+
message: event.userActionRequest.message,
|
|
324
|
+
requestedSchema: event.userActionRequest.requestedSchema
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
state.userActionPending = true;
|
|
328
|
+
const stepId = `step-${state.stepCounter++}`;
|
|
329
|
+
state.steps.push({
|
|
330
|
+
id: stepId,
|
|
331
|
+
eventType,
|
|
332
|
+
message,
|
|
333
|
+
status: "in_progress",
|
|
334
|
+
timestamp: Date.now(),
|
|
335
|
+
elapsedMs: event.elapsedMs
|
|
336
|
+
});
|
|
337
|
+
state.currentExecutingStepId = stepId;
|
|
338
|
+
} else if (eventType === "USER_ACTION_SUCCESS") {
|
|
339
|
+
completeLastInProgressStep(state.steps);
|
|
340
|
+
state.userActionRequest = void 0;
|
|
341
|
+
state.userActionPending = false;
|
|
342
|
+
state.userActionResult = "approved";
|
|
343
|
+
const stepId = `step-${state.stepCounter++}`;
|
|
344
|
+
state.steps.push({
|
|
345
|
+
id: stepId,
|
|
346
|
+
eventType,
|
|
347
|
+
message,
|
|
348
|
+
status: "completed",
|
|
349
|
+
timestamp: Date.now(),
|
|
350
|
+
elapsedMs: event.elapsedMs
|
|
351
|
+
});
|
|
352
|
+
} else if (eventType === "USER_ACTION_INVALID") {
|
|
353
|
+
completeLastInProgressStep(state.steps);
|
|
354
|
+
const errorStepId = `step-${state.stepCounter++}`;
|
|
355
|
+
state.steps.push({
|
|
356
|
+
id: errorStepId,
|
|
357
|
+
eventType,
|
|
358
|
+
message,
|
|
359
|
+
status: "error",
|
|
360
|
+
timestamp: Date.now(),
|
|
361
|
+
elapsedMs: event.elapsedMs
|
|
362
|
+
});
|
|
363
|
+
const retryStepId = `step-${state.stepCounter++}`;
|
|
364
|
+
state.steps.push({
|
|
365
|
+
id: retryStepId,
|
|
366
|
+
eventType: "USER_ACTION_REQUIRED",
|
|
367
|
+
message: "Waiting for verification...",
|
|
368
|
+
status: "in_progress",
|
|
369
|
+
timestamp: Date.now()
|
|
370
|
+
});
|
|
371
|
+
state.currentExecutingStepId = retryStepId;
|
|
372
|
+
} else if (eventType === "USER_ACTION_EXPIRED") {
|
|
373
|
+
completeLastInProgressStep(state.steps);
|
|
374
|
+
state.userActionRequest = void 0;
|
|
375
|
+
state.userActionPending = false;
|
|
376
|
+
const stepId = `step-${state.stepCounter++}`;
|
|
377
|
+
state.steps.push({
|
|
378
|
+
id: stepId,
|
|
379
|
+
eventType,
|
|
380
|
+
message,
|
|
381
|
+
status: "error",
|
|
382
|
+
timestamp: Date.now(),
|
|
383
|
+
elapsedMs: event.elapsedMs
|
|
384
|
+
});
|
|
385
|
+
} else if (eventType === "USER_ACTION_REJECTED") {
|
|
386
|
+
completeLastInProgressStep(state.steps);
|
|
387
|
+
state.userActionRequest = void 0;
|
|
388
|
+
state.userActionPending = false;
|
|
389
|
+
state.userActionResult = "rejected";
|
|
390
|
+
const stepId = `step-${state.stepCounter++}`;
|
|
391
|
+
state.steps.push({
|
|
392
|
+
id: stepId,
|
|
393
|
+
eventType,
|
|
394
|
+
message,
|
|
395
|
+
status: "completed",
|
|
396
|
+
timestamp: Date.now(),
|
|
397
|
+
elapsedMs: event.elapsedMs
|
|
398
|
+
});
|
|
399
|
+
} else if (eventType === "USER_ACTION_RESENT") {
|
|
400
|
+
const stepId = `step-${state.stepCounter++}`;
|
|
401
|
+
state.steps.push({
|
|
402
|
+
id: stepId,
|
|
403
|
+
eventType,
|
|
404
|
+
message,
|
|
405
|
+
status: "completed",
|
|
406
|
+
timestamp: Date.now(),
|
|
407
|
+
elapsedMs: event.elapsedMs
|
|
408
|
+
});
|
|
409
|
+
} else if (eventType === "USER_ACTION_FAILED") {
|
|
410
|
+
completeLastInProgressStep(state.steps);
|
|
411
|
+
state.userActionRequest = void 0;
|
|
412
|
+
state.userActionPending = false;
|
|
413
|
+
const stepId = `step-${state.stepCounter++}`;
|
|
414
|
+
state.steps.push({
|
|
415
|
+
id: stepId,
|
|
416
|
+
eventType,
|
|
417
|
+
message,
|
|
418
|
+
status: "error",
|
|
419
|
+
timestamp: Date.now(),
|
|
420
|
+
elapsedMs: event.elapsedMs
|
|
421
|
+
});
|
|
296
422
|
}
|
|
297
423
|
return state;
|
|
298
424
|
}
|
|
@@ -314,9 +440,9 @@ ${state.errorMessage}` : "",
|
|
|
314
440
|
executionId: state.executionId,
|
|
315
441
|
sessionId: state.sessionId,
|
|
316
442
|
steps: state.hasError ? [] : [...state.steps],
|
|
317
|
-
// Don't show steps on error
|
|
318
443
|
currentExecutingStepId: state.hasError ? void 0 : state.currentExecutingStepId,
|
|
319
|
-
isCancelled: false
|
|
444
|
+
isCancelled: false,
|
|
445
|
+
userActionResult: state.userActionResult
|
|
320
446
|
};
|
|
321
447
|
}
|
|
322
448
|
function createErrorMessageUpdate(error, state) {
|
|
@@ -357,9 +483,9 @@ ${state.errorMessage}` : state.accumulatedContent || "",
|
|
|
357
483
|
executionId: state.executionId,
|
|
358
484
|
tracingData: state.finalData,
|
|
359
485
|
steps: state.hasError ? [] : [...state.steps],
|
|
360
|
-
// Don't show steps on error
|
|
361
486
|
isCancelled: false,
|
|
362
|
-
currentExecutingStepId: void 0
|
|
487
|
+
currentExecutingStepId: void 0,
|
|
488
|
+
userActionResult: state.userActionResult
|
|
363
489
|
};
|
|
364
490
|
}
|
|
365
491
|
function createCancelledMessageUpdate(steps, currentMessage) {
|
|
@@ -405,6 +531,14 @@ function buildStreamingUrl(config) {
|
|
|
405
531
|
}
|
|
406
532
|
return `${config.api.baseUrl}${endpoint}?${queryParams.toString()}`;
|
|
407
533
|
}
|
|
534
|
+
function buildUserActionUrl(config, userActionId, action) {
|
|
535
|
+
const endpoint = config.api.streamEndpoint || "/api/workflows/ask/stream";
|
|
536
|
+
const [endpointPath] = endpoint.split("?");
|
|
537
|
+
const normalizedEndpointPath = endpointPath.replace(/\/+$/, "");
|
|
538
|
+
const basePath = normalizedEndpointPath.endsWith("/stream") ? normalizedEndpointPath.slice(0, -"/stream".length) : normalizedEndpointPath;
|
|
539
|
+
const encodedUserActionId = encodeURIComponent(userActionId);
|
|
540
|
+
return `${config.api.baseUrl}${basePath}/user-action/${encodedUserActionId}/${action}`;
|
|
541
|
+
}
|
|
408
542
|
function buildRequestHeaders(config) {
|
|
409
543
|
const headers = {
|
|
410
544
|
...config.api.headers
|
|
@@ -414,8 +548,39 @@ function buildRequestHeaders(config) {
|
|
|
414
548
|
}
|
|
415
549
|
return headers;
|
|
416
550
|
}
|
|
551
|
+
|
|
552
|
+
// src/utils/userActionClient.ts
|
|
553
|
+
async function sendUserActionRequest(config, userActionId, action, data) {
|
|
554
|
+
const url = buildUserActionUrl(config, userActionId, action);
|
|
555
|
+
const baseHeaders = buildRequestHeaders(config);
|
|
556
|
+
const hasBody = data !== void 0;
|
|
557
|
+
const headers = hasBody ? { "Content-Type": "application/json", ...baseHeaders } : baseHeaders;
|
|
558
|
+
const response = await fetch(url, {
|
|
559
|
+
method: "POST",
|
|
560
|
+
headers,
|
|
561
|
+
body: hasBody ? JSON.stringify(data) : void 0
|
|
562
|
+
});
|
|
563
|
+
if (!response.ok) {
|
|
564
|
+
const errorText = await response.text();
|
|
565
|
+
throw new Error(`HTTP ${response.status}: ${errorText}`);
|
|
566
|
+
}
|
|
567
|
+
return await response.json();
|
|
568
|
+
}
|
|
569
|
+
async function submitUserAction(config, userActionId, data) {
|
|
570
|
+
return sendUserActionRequest(config, userActionId, "submit", data);
|
|
571
|
+
}
|
|
572
|
+
async function cancelUserAction(config, userActionId) {
|
|
573
|
+
return sendUserActionRequest(config, userActionId, "cancel");
|
|
574
|
+
}
|
|
575
|
+
async function resendUserAction(config, userActionId) {
|
|
576
|
+
return sendUserActionRequest(config, userActionId, "resend");
|
|
577
|
+
}
|
|
417
578
|
function useStreamManager(config, callbacks, setMessages, setIsWaitingForResponse) {
|
|
418
579
|
const abortControllerRef = react.useRef(null);
|
|
580
|
+
const configRef = react.useRef(config);
|
|
581
|
+
configRef.current = config;
|
|
582
|
+
const callbacksRef = react.useRef(callbacks);
|
|
583
|
+
callbacksRef.current = callbacks;
|
|
419
584
|
const startStream = react.useCallback(
|
|
420
585
|
async (userMessage, streamingId, sessionId) => {
|
|
421
586
|
abortControllerRef.current?.abort();
|
|
@@ -430,11 +595,15 @@ function useStreamManager(config, callbacks, setMessages, setIsWaitingForRespons
|
|
|
430
595
|
stepCounter: 0,
|
|
431
596
|
currentExecutingStepId: void 0,
|
|
432
597
|
hasError: false,
|
|
433
|
-
errorMessage: ""
|
|
598
|
+
errorMessage: "",
|
|
599
|
+
userActionRequest: void 0,
|
|
600
|
+
userActionPending: false,
|
|
601
|
+
userActionResult: void 0
|
|
434
602
|
};
|
|
435
|
-
const
|
|
436
|
-
const
|
|
437
|
-
const
|
|
603
|
+
const currentConfig = configRef.current;
|
|
604
|
+
const requestBody = buildRequestBody(currentConfig, userMessage, sessionId);
|
|
605
|
+
const url = buildStreamingUrl(currentConfig);
|
|
606
|
+
const headers = buildRequestHeaders(currentConfig);
|
|
438
607
|
try {
|
|
439
608
|
await streamWorkflowEvents(url, requestBody, headers, {
|
|
440
609
|
signal: abortController.signal,
|
|
@@ -445,7 +614,15 @@ function useStreamManager(config, callbacks, setMessages, setIsWaitingForRespons
|
|
|
445
614
|
if (event.executionId) state.executionId = event.executionId;
|
|
446
615
|
if (event.sessionId) state.currentSessionId = event.sessionId;
|
|
447
616
|
processStreamEvent(event, state);
|
|
448
|
-
const
|
|
617
|
+
const eventType = event.eventType;
|
|
618
|
+
if (eventType === "USER_ACTION_REQUIRED" && state.userActionRequest) {
|
|
619
|
+
callbacksRef.current.onUserActionRequired?.(state.userActionRequest);
|
|
620
|
+
} else if (eventType.startsWith("USER_ACTION_") && eventType !== "USER_ACTION_REQUIRED") {
|
|
621
|
+
const msg = event.message?.trim() || event.errorMessage?.trim() || getEventMessage(event);
|
|
622
|
+
callbacksRef.current.onUserActionEvent?.(eventType, msg);
|
|
623
|
+
}
|
|
624
|
+
const rawMessage = event.message?.trim() || event.errorMessage?.trim();
|
|
625
|
+
const currentMessage = rawMessage || (event.eventType?.startsWith("USER_ACTION_") ? getEventMessage(event) : void 0);
|
|
449
626
|
setMessages(
|
|
450
627
|
(prev) => prev.map(
|
|
451
628
|
(msg) => msg.id === streamingId ? {
|
|
@@ -461,7 +638,7 @@ function useStreamManager(config, callbacks, setMessages, setIsWaitingForRespons
|
|
|
461
638
|
onError: (error) => {
|
|
462
639
|
setIsWaitingForResponse(false);
|
|
463
640
|
if (error.name !== "AbortError") {
|
|
464
|
-
|
|
641
|
+
callbacksRef.current.onError?.(error);
|
|
465
642
|
}
|
|
466
643
|
setMessages(
|
|
467
644
|
(prev) => prev.map(
|
|
@@ -475,7 +652,7 @@ function useStreamManager(config, callbacks, setMessages, setIsWaitingForRespons
|
|
|
475
652
|
onComplete: () => {
|
|
476
653
|
setIsWaitingForResponse(false);
|
|
477
654
|
if (state.currentSessionId && state.currentSessionId !== sessionId) {
|
|
478
|
-
|
|
655
|
+
callbacksRef.current.onSessionIdChange?.(state.currentSessionId);
|
|
479
656
|
}
|
|
480
657
|
const finalMessage = createFinalMessage(streamingId, {
|
|
481
658
|
...state,
|
|
@@ -486,14 +663,14 @@ function useStreamManager(config, callbacks, setMessages, setIsWaitingForRespons
|
|
|
486
663
|
(msg) => msg.id === streamingId ? finalMessage : msg
|
|
487
664
|
)
|
|
488
665
|
);
|
|
489
|
-
|
|
666
|
+
callbacksRef.current.onStreamComplete?.(finalMessage);
|
|
490
667
|
}
|
|
491
668
|
});
|
|
492
669
|
return state.currentSessionId;
|
|
493
670
|
} catch (error) {
|
|
494
671
|
setIsWaitingForResponse(false);
|
|
495
672
|
if (error.name !== "AbortError") {
|
|
496
|
-
|
|
673
|
+
callbacksRef.current.onError?.(error);
|
|
497
674
|
}
|
|
498
675
|
setMessages(
|
|
499
676
|
(prev) => prev.map(
|
|
@@ -506,7 +683,7 @@ function useStreamManager(config, callbacks, setMessages, setIsWaitingForRespons
|
|
|
506
683
|
return state.currentSessionId;
|
|
507
684
|
}
|
|
508
685
|
},
|
|
509
|
-
[
|
|
686
|
+
[setMessages, setIsWaitingForResponse]
|
|
510
687
|
);
|
|
511
688
|
const cancelStream = react.useCallback(() => {
|
|
512
689
|
abortControllerRef.current?.abort();
|
|
@@ -523,18 +700,61 @@ function useChat(config, callbacks = {}) {
|
|
|
523
700
|
const [messages, setMessages] = react.useState([]);
|
|
524
701
|
const [isWaitingForResponse, setIsWaitingForResponse] = react.useState(false);
|
|
525
702
|
const sessionIdRef = react.useRef(void 0);
|
|
703
|
+
const callbacksRef = react.useRef(callbacks);
|
|
704
|
+
callbacksRef.current = callbacks;
|
|
705
|
+
const configRef = react.useRef(config);
|
|
706
|
+
configRef.current = config;
|
|
707
|
+
const [userActionState, setUserActionState] = react.useState({
|
|
708
|
+
request: null,
|
|
709
|
+
result: null,
|
|
710
|
+
clearOtpTrigger: 0
|
|
711
|
+
});
|
|
712
|
+
const userActionStateRef = react.useRef(userActionState);
|
|
713
|
+
userActionStateRef.current = userActionState;
|
|
714
|
+
const wrappedCallbacks = react.useMemo(() => ({
|
|
715
|
+
...callbacksRef.current,
|
|
716
|
+
onMessageSent: (message) => callbacksRef.current.onMessageSent?.(message),
|
|
717
|
+
onStreamStart: () => callbacksRef.current.onStreamStart?.(),
|
|
718
|
+
onStreamComplete: (message) => callbacksRef.current.onStreamComplete?.(message),
|
|
719
|
+
onError: (error) => callbacksRef.current.onError?.(error),
|
|
720
|
+
onExecutionTraceClick: (data) => callbacksRef.current.onExecutionTraceClick?.(data),
|
|
721
|
+
onSessionIdChange: (sessionId) => callbacksRef.current.onSessionIdChange?.(sessionId),
|
|
722
|
+
onUserActionRequired: (request) => {
|
|
723
|
+
setUserActionState((prev) => ({ ...prev, request, result: null }));
|
|
724
|
+
callbacksRef.current.onUserActionRequired?.(request);
|
|
725
|
+
},
|
|
726
|
+
onUserActionEvent: (eventType, message) => {
|
|
727
|
+
switch (eventType) {
|
|
728
|
+
case "USER_ACTION_SUCCESS":
|
|
729
|
+
setUserActionState((prev) => ({ ...prev, request: null, result: "approved" }));
|
|
730
|
+
break;
|
|
731
|
+
case "USER_ACTION_REJECTED":
|
|
732
|
+
setUserActionState((prev) => ({ ...prev, request: null, result: "rejected" }));
|
|
733
|
+
break;
|
|
734
|
+
case "USER_ACTION_EXPIRED":
|
|
735
|
+
case "USER_ACTION_FAILED":
|
|
736
|
+
setUserActionState((prev) => ({ ...prev, request: null }));
|
|
737
|
+
break;
|
|
738
|
+
case "USER_ACTION_INVALID":
|
|
739
|
+
setUserActionState((prev) => ({ ...prev, clearOtpTrigger: prev.clearOtpTrigger + 1 }));
|
|
740
|
+
break;
|
|
741
|
+
}
|
|
742
|
+
callbacksRef.current.onUserActionEvent?.(eventType, message);
|
|
743
|
+
}
|
|
744
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
745
|
+
}), []);
|
|
526
746
|
const { startStream, cancelStream: cancelStreamManager, abortControllerRef } = useStreamManager(
|
|
527
747
|
config,
|
|
528
|
-
|
|
748
|
+
wrappedCallbacks,
|
|
529
749
|
setMessages,
|
|
530
750
|
setIsWaitingForResponse
|
|
531
751
|
);
|
|
532
752
|
const sendMessage = react.useCallback(
|
|
533
753
|
async (userMessage) => {
|
|
534
754
|
if (!userMessage.trim()) return;
|
|
535
|
-
if (!sessionIdRef.current &&
|
|
755
|
+
if (!sessionIdRef.current && configRef.current.autoGenerateSessionId !== false) {
|
|
536
756
|
sessionIdRef.current = generateId();
|
|
537
|
-
|
|
757
|
+
callbacksRef.current.onSessionIdChange?.(sessionIdRef.current);
|
|
538
758
|
}
|
|
539
759
|
const userMessageId = `user-${Date.now()}`;
|
|
540
760
|
const userMsg = {
|
|
@@ -545,9 +765,9 @@ function useChat(config, callbacks = {}) {
|
|
|
545
765
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
546
766
|
};
|
|
547
767
|
setMessages((prev) => [...prev, userMsg]);
|
|
548
|
-
|
|
768
|
+
callbacksRef.current.onMessageSent?.(userMessage);
|
|
549
769
|
setIsWaitingForResponse(true);
|
|
550
|
-
|
|
770
|
+
callbacksRef.current.onStreamStart?.();
|
|
551
771
|
const streamingId = `assistant-${Date.now()}`;
|
|
552
772
|
const streamingMsg = {
|
|
553
773
|
id: streamingId,
|
|
@@ -573,7 +793,7 @@ function useChat(config, callbacks = {}) {
|
|
|
573
793
|
sessionIdRef.current = newSessionId;
|
|
574
794
|
}
|
|
575
795
|
},
|
|
576
|
-
[
|
|
796
|
+
[startStream]
|
|
577
797
|
);
|
|
578
798
|
const clearMessages = react.useCallback(() => {
|
|
579
799
|
setMessages([]);
|
|
@@ -581,6 +801,7 @@ function useChat(config, callbacks = {}) {
|
|
|
581
801
|
const cancelStream = react.useCallback(() => {
|
|
582
802
|
cancelStreamManager();
|
|
583
803
|
setIsWaitingForResponse(false);
|
|
804
|
+
setUserActionState((prev) => ({ ...prev, request: null, result: null }));
|
|
584
805
|
setMessages(
|
|
585
806
|
(prev) => prev.map((msg) => {
|
|
586
807
|
if (msg.isStreaming) {
|
|
@@ -601,6 +822,7 @@ function useChat(config, callbacks = {}) {
|
|
|
601
822
|
sessionIdRef.current = void 0;
|
|
602
823
|
abortControllerRef.current?.abort();
|
|
603
824
|
setIsWaitingForResponse(false);
|
|
825
|
+
setUserActionState({ request: null, result: null, clearOtpTrigger: 0 });
|
|
604
826
|
}, []);
|
|
605
827
|
const getSessionId = react.useCallback(() => {
|
|
606
828
|
return sessionIdRef.current;
|
|
@@ -608,6 +830,56 @@ function useChat(config, callbacks = {}) {
|
|
|
608
830
|
const getMessages = react.useCallback(() => {
|
|
609
831
|
return messages;
|
|
610
832
|
}, [messages]);
|
|
833
|
+
const approveUserAction = react.useCallback(
|
|
834
|
+
async (otp) => {
|
|
835
|
+
const request = userActionStateRef.current.request;
|
|
836
|
+
if (!request) return;
|
|
837
|
+
try {
|
|
838
|
+
await submitUserAction(configRef.current, request.userActionId, { otp });
|
|
839
|
+
} catch (error) {
|
|
840
|
+
setUserActionState((prev) => ({
|
|
841
|
+
...prev,
|
|
842
|
+
clearOtpTrigger: prev.clearOtpTrigger + 1
|
|
843
|
+
}));
|
|
844
|
+
callbacksRef.current.onError?.(error);
|
|
845
|
+
throw error;
|
|
846
|
+
}
|
|
847
|
+
},
|
|
848
|
+
[]
|
|
849
|
+
);
|
|
850
|
+
const rejectUserAction = react.useCallback(async () => {
|
|
851
|
+
const request = userActionStateRef.current.request;
|
|
852
|
+
if (!request) return;
|
|
853
|
+
try {
|
|
854
|
+
setMessages((prev) => {
|
|
855
|
+
let lastStreamingIdx = -1;
|
|
856
|
+
for (let i = prev.length - 1; i >= 0; i--) {
|
|
857
|
+
if (prev[i].role === "assistant" && prev[i].isStreaming) {
|
|
858
|
+
lastStreamingIdx = i;
|
|
859
|
+
break;
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
if (lastStreamingIdx === -1) return prev;
|
|
863
|
+
return prev.map(
|
|
864
|
+
(msg, i) => i === lastStreamingIdx ? { ...msg, currentMessage: "Rejecting..." } : msg
|
|
865
|
+
);
|
|
866
|
+
});
|
|
867
|
+
await cancelUserAction(configRef.current, request.userActionId);
|
|
868
|
+
} catch (error) {
|
|
869
|
+
callbacksRef.current.onError?.(error);
|
|
870
|
+
throw error;
|
|
871
|
+
}
|
|
872
|
+
}, []);
|
|
873
|
+
const resendOtp = react.useCallback(async () => {
|
|
874
|
+
const request = userActionStateRef.current.request;
|
|
875
|
+
if (!request) return;
|
|
876
|
+
try {
|
|
877
|
+
await resendUserAction(configRef.current, request.userActionId);
|
|
878
|
+
} catch (error) {
|
|
879
|
+
callbacksRef.current.onError?.(error);
|
|
880
|
+
throw error;
|
|
881
|
+
}
|
|
882
|
+
}, []);
|
|
611
883
|
return {
|
|
612
884
|
messages,
|
|
613
885
|
sendMessage,
|
|
@@ -617,12 +889,20 @@ function useChat(config, callbacks = {}) {
|
|
|
617
889
|
getSessionId,
|
|
618
890
|
getMessages,
|
|
619
891
|
isWaitingForResponse,
|
|
620
|
-
sessionId: sessionIdRef.current
|
|
892
|
+
sessionId: sessionIdRef.current,
|
|
893
|
+
// User action (OTP) state and methods
|
|
894
|
+
userActionState,
|
|
895
|
+
approveUserAction,
|
|
896
|
+
rejectUserAction,
|
|
897
|
+
resendOtp
|
|
621
898
|
};
|
|
622
899
|
}
|
|
623
900
|
|
|
901
|
+
exports.cancelUserAction = cancelUserAction;
|
|
624
902
|
exports.generateId = generateId;
|
|
903
|
+
exports.resendUserAction = resendUserAction;
|
|
625
904
|
exports.streamWorkflowEvents = streamWorkflowEvents;
|
|
905
|
+
exports.submitUserAction = submitUserAction;
|
|
626
906
|
exports.useChat = useChat;
|
|
627
907
|
//# sourceMappingURL=index.native.js.map
|
|
628
908
|
//# sourceMappingURL=index.native.js.map
|