@paymanai/payman-ask-sdk 1.2.11 → 1.2.13
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/README.md +3 -0
- package/dist/index.d.mts +23 -3
- package/dist/index.d.ts +23 -3
- package/dist/index.js +124 -35
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +125 -36
- package/dist/index.mjs.map +1 -1
- package/dist/index.native.js +59 -9
- package/dist/index.native.js.map +1 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useChat, useVoice } from '@paymanai/payman-typescript-ask-sdk';
|
|
2
2
|
export { cancelUserAction, generateId, resendUserAction, streamWorkflowEvents, submitUserAction, useChat, useVoice } from '@paymanai/payman-typescript-ask-sdk';
|
|
3
|
-
import { createContext, useContext, useState, useRef, useMemo, useEffect, useCallback } from 'react';
|
|
3
|
+
import { createContext, useContext, useState, useRef, useMemo, useEffect, useCallback, useLayoutEffect } from 'react';
|
|
4
4
|
import { clsx } from 'clsx';
|
|
5
5
|
import { twMerge } from 'tailwind-merge';
|
|
6
6
|
import { motion, AnimatePresence } from 'framer-motion';
|
|
@@ -56,6 +56,7 @@ function ChatInput({
|
|
|
56
56
|
value,
|
|
57
57
|
onChange,
|
|
58
58
|
onSend,
|
|
59
|
+
onPause,
|
|
59
60
|
disabled = false,
|
|
60
61
|
placeholder = "Type your message...",
|
|
61
62
|
isWaitingForResponse = false,
|
|
@@ -87,6 +88,7 @@ function ChatInput({
|
|
|
87
88
|
}
|
|
88
89
|
};
|
|
89
90
|
const isInputDisabled = disabled || isWaitingForResponse;
|
|
91
|
+
const showPauseButton = isWaitingForResponse && onPause;
|
|
90
92
|
const showVoiceButton = enableVoice && onVoicePress != null;
|
|
91
93
|
const isVoiceButtonDisabled = isWaitingForResponse || !voiceAvailable || !isSessionParamsConfigured;
|
|
92
94
|
const canSend = !isInputDisabled && !!value.trim();
|
|
@@ -167,7 +169,22 @@ function ChatInput({
|
|
|
167
169
|
]
|
|
168
170
|
}
|
|
169
171
|
),
|
|
170
|
-
/* @__PURE__ */ jsx(
|
|
172
|
+
showPauseButton ? /* @__PURE__ */ jsx(
|
|
173
|
+
"button",
|
|
174
|
+
{
|
|
175
|
+
type: "button",
|
|
176
|
+
onClick: onPause,
|
|
177
|
+
className: cn(
|
|
178
|
+
"flex items-center justify-center",
|
|
179
|
+
"w-8 h-8 rounded-full",
|
|
180
|
+
"payman-chat-input-btn-pause",
|
|
181
|
+
"hover:opacity-90 active:scale-95",
|
|
182
|
+
"transition-all duration-150"
|
|
183
|
+
),
|
|
184
|
+
"aria-label": "Stop response",
|
|
185
|
+
children: /* @__PURE__ */ jsx(Square, { className: "w-3.5 h-3.5", fill: "currentColor" })
|
|
186
|
+
}
|
|
187
|
+
) : /* @__PURE__ */ jsx(
|
|
171
188
|
"button",
|
|
172
189
|
{
|
|
173
190
|
type: "button",
|
|
@@ -191,6 +208,48 @@ function ChatInput({
|
|
|
191
208
|
}
|
|
192
209
|
);
|
|
193
210
|
}
|
|
211
|
+
|
|
212
|
+
// src/utils/errorMessages.ts
|
|
213
|
+
var WORKFLOW_FAILED = "WORKFLOW_FAILED";
|
|
214
|
+
var STREAM_NOT_STARTED = "STREAM_NOT_STARTED";
|
|
215
|
+
var HTTP_ERROR_PREFIX = /^HTTP\s+(\d+)\s*:\s*([\s\S]+)$/;
|
|
216
|
+
function isFriendlyWorkflowError(errorDetails) {
|
|
217
|
+
if (!errorDetails) return false;
|
|
218
|
+
return errorDetails === WORKFLOW_FAILED || errorDetails === STREAM_NOT_STARTED || errorDetails.includes(WORKFLOW_FAILED);
|
|
219
|
+
}
|
|
220
|
+
function parseErrorPayload(payload) {
|
|
221
|
+
try {
|
|
222
|
+
const parsed = JSON.parse(payload);
|
|
223
|
+
if (typeof parsed === "string") {
|
|
224
|
+
return { message: parsed.trim() || void 0 };
|
|
225
|
+
}
|
|
226
|
+
if (typeof parsed === "object" && parsed !== null) {
|
|
227
|
+
const record = parsed;
|
|
228
|
+
return {
|
|
229
|
+
status: typeof record.status === "number" ? record.status : void 0,
|
|
230
|
+
message: typeof record.message === "string" && record.message.trim() ? record.message.trim() : void 0
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
} catch {
|
|
234
|
+
}
|
|
235
|
+
return {};
|
|
236
|
+
}
|
|
237
|
+
function getConflictErrorMessage(errorDetails) {
|
|
238
|
+
if (!errorDetails) return void 0;
|
|
239
|
+
const trimmedError = errorDetails.trim();
|
|
240
|
+
const httpMatch = trimmedError.match(HTTP_ERROR_PREFIX);
|
|
241
|
+
const httpStatus = httpMatch ? Number(httpMatch[1]) : void 0;
|
|
242
|
+
const rawPayload = (httpMatch ? httpMatch[2] : trimmedError).trim();
|
|
243
|
+
const payload = parseErrorPayload(rawPayload);
|
|
244
|
+
const status = payload.status ?? httpStatus;
|
|
245
|
+
if (status !== 409) {
|
|
246
|
+
return void 0;
|
|
247
|
+
}
|
|
248
|
+
if (payload.message) {
|
|
249
|
+
return payload.message;
|
|
250
|
+
}
|
|
251
|
+
return rawPayload || void 0;
|
|
252
|
+
}
|
|
194
253
|
function ThinkingBlock({ text }) {
|
|
195
254
|
const [isOpen, setIsOpen] = useState(false);
|
|
196
255
|
const hasContent = typeof text === "string" && text.trim().length > 0;
|
|
@@ -232,12 +291,6 @@ function ThinkingBlock({ text }) {
|
|
|
232
291
|
] });
|
|
233
292
|
}
|
|
234
293
|
var FRIENDLY_ERROR_MESSAGE = "Oops, something went wrong. Please try again.";
|
|
235
|
-
var WORKFLOW_FAILED = "WORKFLOW_FAILED";
|
|
236
|
-
var STREAM_NOT_STARTED = "STREAM_NOT_STARTED";
|
|
237
|
-
function isFriendlyError(errorDetails) {
|
|
238
|
-
if (!errorDetails) return false;
|
|
239
|
-
return errorDetails === WORKFLOW_FAILED || errorDetails === STREAM_NOT_STARTED || errorDetails.includes(WORKFLOW_FAILED);
|
|
240
|
-
}
|
|
241
294
|
function looksLikeRawError(text) {
|
|
242
295
|
if (!text || text.length < 10) return false;
|
|
243
296
|
return text.includes("errorType=") || /failed:\s*\{/.test(text);
|
|
@@ -277,7 +330,8 @@ function AgentMessage({
|
|
|
277
330
|
const content = rawContent.replace(/\\n/g, "\n");
|
|
278
331
|
const hasMeaningfulContent = content.length > 0 && !looksLikeRawError(content);
|
|
279
332
|
const completedWithNoContent = !isStreaming && !isCancelled && content.length === 0 && (message.streamProgress === "completed" || message.streamProgress === "error");
|
|
280
|
-
const
|
|
333
|
+
const conflictErrorMessage = getConflictErrorMessage(message.errorDetails);
|
|
334
|
+
const isError = !!conflictErrorMessage || (isFriendlyWorkflowError(message.errorDetails) || looksLikeRawError(content)) && !hasMeaningfulContent || completedWithNoContent;
|
|
281
335
|
const activeThinkingText = message.activeThinkingText;
|
|
282
336
|
const allThinkingText = message.allThinkingText;
|
|
283
337
|
const currentStep = useMemo(
|
|
@@ -474,7 +528,7 @@ function AgentMessage({
|
|
|
474
528
|
{
|
|
475
529
|
remarkPlugins: [remarkGfm],
|
|
476
530
|
components: markdownComponents(),
|
|
477
|
-
children: isError ? FRIENDLY_ERROR_MESSAGE : content || (isStreaming ? "Thinking..." : isCancelled ? "Request was stopped." : "")
|
|
531
|
+
children: isError ? conflictErrorMessage ?? FRIENDLY_ERROR_MESSAGE : content || (isStreaming ? "Thinking..." : isCancelled ? "Request was stopped." : "")
|
|
478
532
|
}
|
|
479
533
|
)
|
|
480
534
|
}
|
|
@@ -711,6 +765,7 @@ function MessageRowSkeleton({
|
|
|
711
765
|
);
|
|
712
766
|
}
|
|
713
767
|
var SCROLL_THRESHOLD = 150;
|
|
768
|
+
var LOAD_MORE_THRESHOLD = 80;
|
|
714
769
|
function MessageList({
|
|
715
770
|
messages,
|
|
716
771
|
isLoading = false,
|
|
@@ -730,12 +785,17 @@ function MessageList({
|
|
|
730
785
|
streamingStepsText,
|
|
731
786
|
completedStepsText,
|
|
732
787
|
onExecutionTraceClick,
|
|
733
|
-
className
|
|
788
|
+
className,
|
|
789
|
+
onLoadMoreMessages,
|
|
790
|
+
isLoadingMoreMessages = false,
|
|
791
|
+
hasMoreMessages = false
|
|
734
792
|
}) {
|
|
735
793
|
const scrollRef = useRef(null);
|
|
736
794
|
const isNearBottomRef = useRef(true);
|
|
737
795
|
const [showScrollBtn, setShowScrollBtn] = useState(false);
|
|
738
796
|
const prevMessageCountRef = useRef(messages.length);
|
|
797
|
+
const scrollHeightBeforePrependRef = useRef(null);
|
|
798
|
+
const firstMessageIdRef = useRef(messages[0]?.id);
|
|
739
799
|
const getDistanceFromBottom = useCallback(() => {
|
|
740
800
|
const el = scrollRef.current;
|
|
741
801
|
if (!el) return 0;
|
|
@@ -747,11 +807,27 @@ function MessageList({
|
|
|
747
807
|
el.scrollTo({ top: el.scrollHeight, behavior });
|
|
748
808
|
}, []);
|
|
749
809
|
const handleScroll = useCallback(() => {
|
|
810
|
+
const el = scrollRef.current;
|
|
811
|
+
if (!el) return;
|
|
750
812
|
const distance = getDistanceFromBottom();
|
|
751
813
|
const nearBottom = distance <= SCROLL_THRESHOLD;
|
|
752
814
|
isNearBottomRef.current = nearBottom;
|
|
753
815
|
setShowScrollBtn(!nearBottom);
|
|
754
|
-
|
|
816
|
+
if (el.scrollTop <= LOAD_MORE_THRESHOLD && hasMoreMessages && !isLoadingMoreMessages && onLoadMoreMessages) {
|
|
817
|
+
scrollHeightBeforePrependRef.current = el.scrollHeight;
|
|
818
|
+
onLoadMoreMessages();
|
|
819
|
+
}
|
|
820
|
+
}, [getDistanceFromBottom, hasMoreMessages, isLoadingMoreMessages, onLoadMoreMessages]);
|
|
821
|
+
useLayoutEffect(() => {
|
|
822
|
+
const el = scrollRef.current;
|
|
823
|
+
const prevHeight = scrollHeightBeforePrependRef.current;
|
|
824
|
+
const newFirstId = messages[0]?.id;
|
|
825
|
+
if (el && prevHeight !== null && newFirstId !== firstMessageIdRef.current) {
|
|
826
|
+
el.scrollTop = el.scrollHeight - prevHeight;
|
|
827
|
+
scrollHeightBeforePrependRef.current = null;
|
|
828
|
+
}
|
|
829
|
+
firstMessageIdRef.current = newFirstId;
|
|
830
|
+
}, [messages]);
|
|
755
831
|
useEffect(() => {
|
|
756
832
|
const prevCount = prevMessageCountRef.current;
|
|
757
833
|
prevMessageCountRef.current = messages.length;
|
|
@@ -862,34 +938,37 @@ function MessageList({
|
|
|
862
938
|
className
|
|
863
939
|
),
|
|
864
940
|
children: [
|
|
865
|
-
/* @__PURE__ */
|
|
941
|
+
/* @__PURE__ */ jsxs(
|
|
866
942
|
"div",
|
|
867
943
|
{
|
|
868
944
|
className: cn(
|
|
869
945
|
"space-y-4",
|
|
870
946
|
layout === "centered" ? "max-w-2xl mx-auto px-4 py-6" : "p-4"
|
|
871
947
|
),
|
|
872
|
-
children:
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
948
|
+
children: [
|
|
949
|
+
isLoadingMoreMessages && /* @__PURE__ */ jsx("div", { className: "flex justify-center py-2", children: /* @__PURE__ */ jsx("div", { className: "w-5 h-5 rounded-full border-2 border-muted-foreground/30 border-t-muted-foreground animate-spin" }) }),
|
|
950
|
+
messages.map((message) => /* @__PURE__ */ jsx(
|
|
951
|
+
MessageRow,
|
|
952
|
+
{
|
|
953
|
+
message,
|
|
954
|
+
stage,
|
|
955
|
+
animated,
|
|
956
|
+
showAgentName,
|
|
957
|
+
agentName,
|
|
958
|
+
showAvatars,
|
|
959
|
+
showUserAvatar,
|
|
960
|
+
showAssistantAvatar,
|
|
961
|
+
layout,
|
|
962
|
+
showTimestamps,
|
|
963
|
+
showExecutionSteps,
|
|
964
|
+
showStreamingDot,
|
|
965
|
+
streamingStepsText,
|
|
966
|
+
completedStepsText,
|
|
967
|
+
onExecutionTraceClick
|
|
968
|
+
},
|
|
969
|
+
message.id
|
|
970
|
+
))
|
|
971
|
+
]
|
|
893
972
|
}
|
|
894
973
|
),
|
|
895
974
|
showScrollBtn && /* @__PURE__ */ jsx("div", { className: "sticky bottom-0 z-20 flex justify-center pb-3 -mt-11", children: /* @__PURE__ */ jsx(
|
|
@@ -1369,7 +1448,10 @@ function PaymanChat({
|
|
|
1369
1448
|
callbacks = {},
|
|
1370
1449
|
className,
|
|
1371
1450
|
style,
|
|
1372
|
-
children
|
|
1451
|
+
children,
|
|
1452
|
+
onLoadMoreMessages,
|
|
1453
|
+
isLoadingMoreMessages = false,
|
|
1454
|
+
hasMoreMessages = false
|
|
1373
1455
|
}) {
|
|
1374
1456
|
const [inputValue, setInputValue] = useState("");
|
|
1375
1457
|
const prevInputValueRef = useRef(inputValue);
|
|
@@ -1380,6 +1462,7 @@ function PaymanChat({
|
|
|
1380
1462
|
isWaitingForResponse,
|
|
1381
1463
|
resetSession,
|
|
1382
1464
|
clearMessages,
|
|
1465
|
+
prependMessages,
|
|
1383
1466
|
cancelStream,
|
|
1384
1467
|
getSessionId,
|
|
1385
1468
|
getMessages
|
|
@@ -1416,6 +1499,7 @@ function PaymanChat({
|
|
|
1416
1499
|
() => ({
|
|
1417
1500
|
resetSession,
|
|
1418
1501
|
clearMessages,
|
|
1502
|
+
prependMessages,
|
|
1419
1503
|
cancelStream,
|
|
1420
1504
|
getSessionId,
|
|
1421
1505
|
getMessages,
|
|
@@ -1424,6 +1508,7 @@ function PaymanChat({
|
|
|
1424
1508
|
[
|
|
1425
1509
|
resetSession,
|
|
1426
1510
|
clearMessages,
|
|
1511
|
+
prependMessages,
|
|
1427
1512
|
cancelStream,
|
|
1428
1513
|
getSessionId,
|
|
1429
1514
|
getMessages,
|
|
@@ -1541,7 +1626,10 @@ function PaymanChat({
|
|
|
1541
1626
|
showStreamingDot,
|
|
1542
1627
|
streamingStepsText,
|
|
1543
1628
|
completedStepsText,
|
|
1544
|
-
onExecutionTraceClick
|
|
1629
|
+
onExecutionTraceClick,
|
|
1630
|
+
onLoadMoreMessages,
|
|
1631
|
+
isLoadingMoreMessages,
|
|
1632
|
+
hasMoreMessages
|
|
1545
1633
|
}
|
|
1546
1634
|
),
|
|
1547
1635
|
hasAskPermission && /* @__PURE__ */ jsx(
|
|
@@ -1550,6 +1638,7 @@ function PaymanChat({
|
|
|
1550
1638
|
value: inputValue,
|
|
1551
1639
|
onChange: setInputValue,
|
|
1552
1640
|
onSend: handleSend,
|
|
1641
|
+
onPause: cancelStream,
|
|
1553
1642
|
disabled: isInputDisabled,
|
|
1554
1643
|
placeholder: isRecording ? "Listening..." : placeholder,
|
|
1555
1644
|
isWaitingForResponse,
|