@paymanai/payman-ask-sdk 1.1.1 → 1.2.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 +17 -1
- package/dist/index.d.ts +17 -1
- package/dist/index.js +98 -49
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +97 -52
- package/dist/index.mjs.map +1 -1
- package/dist/index.native.js +526 -125
- package/dist/index.native.js.map +1 -1
- package/package.json +112 -104
package/dist/index.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { useChat, useVoice } from '@paymanai/payman-typescript-ask-sdk';
|
|
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';
|
|
4
4
|
import { clsx } from 'clsx';
|
|
5
5
|
import { twMerge } from 'tailwind-merge';
|
|
6
6
|
import { motion, AnimatePresence } from 'framer-motion';
|
|
7
|
-
import { Bot, Pause, Send, ShieldCheck, Loader2, User, CheckCircle2, XCircle, X, ChevronUp, ChevronDown, Check, Binoculars } from 'lucide-react';
|
|
7
|
+
import { Bot, Mic, Pause, Send, ShieldCheck, Loader2, User, CheckCircle2, XCircle, X, ChevronUp, ChevronDown, Check, Binoculars } from 'lucide-react';
|
|
8
8
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
9
9
|
import ReactMarkdown from 'react-markdown';
|
|
10
10
|
import remarkGfm from 'remark-gfm';
|
|
@@ -58,7 +58,11 @@ function ChatInput({
|
|
|
58
58
|
hasSelectedSession = true,
|
|
59
59
|
isSessionParamsConfigured = true,
|
|
60
60
|
onClick,
|
|
61
|
-
className
|
|
61
|
+
className,
|
|
62
|
+
enableVoice = false,
|
|
63
|
+
onVoicePress,
|
|
64
|
+
voiceAvailable = false,
|
|
65
|
+
isRecording = false
|
|
62
66
|
}) {
|
|
63
67
|
const textareaRef = useRef(null);
|
|
64
68
|
useEffect(() => {
|
|
@@ -77,6 +81,8 @@ function ChatInput({
|
|
|
77
81
|
};
|
|
78
82
|
const isInputDisabled = disabled || isWaitingForResponse;
|
|
79
83
|
const showPauseButton = isWaitingForResponse && onPause;
|
|
84
|
+
const showVoiceButton = enableVoice && onVoicePress != null;
|
|
85
|
+
const isVoiceButtonDisabled = isWaitingForResponse || !voiceAvailable || !isSessionParamsConfigured;
|
|
80
86
|
const getPlaceholder = () => {
|
|
81
87
|
if (!hasSelectedSession) {
|
|
82
88
|
return "Select a version to start chatting";
|
|
@@ -90,7 +96,7 @@ function ChatInput({
|
|
|
90
96
|
motion.div,
|
|
91
97
|
{
|
|
92
98
|
initial: false,
|
|
93
|
-
className: "
|
|
99
|
+
className: "flex items-end overflow-hidden transition-colors bg-input border border-border shadow-sm",
|
|
94
100
|
style: { borderRadius: "24px" },
|
|
95
101
|
children: [
|
|
96
102
|
/* @__PURE__ */ jsx(
|
|
@@ -103,51 +109,48 @@ function ChatInput({
|
|
|
103
109
|
onClick,
|
|
104
110
|
disabled: isInputDisabled,
|
|
105
111
|
placeholder: getPlaceholder(),
|
|
106
|
-
className: "bg-transparent text-foreground focus:outline-none resize-none overflow-y-auto disabled:opacity-50 disabled:cursor-not-allowed w-
|
|
112
|
+
className: "bg-transparent text-foreground focus:outline-none resize-none overflow-y-auto disabled:opacity-50 disabled:cursor-not-allowed flex-1 min-w-0 text-sm placeholder:text-muted-foreground",
|
|
107
113
|
style: {
|
|
108
114
|
minHeight: "48px",
|
|
109
115
|
maxHeight: "200px",
|
|
110
|
-
padding: "12px
|
|
116
|
+
padding: "12px 12px 12px 16px"
|
|
111
117
|
},
|
|
112
118
|
rows: 1
|
|
113
119
|
}
|
|
114
120
|
),
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
children: /* @__PURE__ */ jsx(Send, { className: "w-4 h-4" })
|
|
149
|
-
}
|
|
150
|
-
)
|
|
121
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-row items-center gap-1 shrink-0 mb-2 mr-2", children: [
|
|
122
|
+
showVoiceButton && /* @__PURE__ */ jsx(
|
|
123
|
+
"button",
|
|
124
|
+
{
|
|
125
|
+
type: "button",
|
|
126
|
+
onClick: onVoicePress,
|
|
127
|
+
disabled: isVoiceButtonDisabled,
|
|
128
|
+
className: `flex items-center justify-center flex-shrink-0 transition-all rounded-full w-8 h-8 min-w-[32px] ${isRecording ? "animate-pulse" : "hover:opacity-80"} disabled:opacity-50 disabled:cursor-not-allowed`,
|
|
129
|
+
"aria-label": isRecording ? "Stop recording" : "Voice input",
|
|
130
|
+
children: /* @__PURE__ */ jsx(Mic, { className: `w-5 h-5 shrink-0 ${isRecording ? "text-red-500" : "text-foreground"}` })
|
|
131
|
+
}
|
|
132
|
+
),
|
|
133
|
+
showPauseButton ? /* @__PURE__ */ jsx(
|
|
134
|
+
"button",
|
|
135
|
+
{
|
|
136
|
+
type: "button",
|
|
137
|
+
onClick: onPause,
|
|
138
|
+
className: "flex items-center justify-center flex-shrink-0 transition-all rounded-full w-8 h-8 bg-primary text-primary-foreground hover:bg-primary/90",
|
|
139
|
+
"aria-label": "Pause request",
|
|
140
|
+
children: /* @__PURE__ */ jsx(Pause, { className: "w-4 h-4" })
|
|
141
|
+
}
|
|
142
|
+
) : /* @__PURE__ */ jsx(
|
|
143
|
+
"button",
|
|
144
|
+
{
|
|
145
|
+
type: "button",
|
|
146
|
+
onClick: onSend,
|
|
147
|
+
disabled: isInputDisabled || !value.trim(),
|
|
148
|
+
className: "flex items-center justify-center flex-shrink-0 transition-all rounded-full w-8 h-8 bg-primary text-primary-foreground hover:bg-primary/90 disabled:opacity-50 disabled:cursor-not-allowed",
|
|
149
|
+
"aria-label": "Send message",
|
|
150
|
+
children: /* @__PURE__ */ jsx(Send, { className: "w-4 h-4" })
|
|
151
|
+
}
|
|
152
|
+
)
|
|
153
|
+
] })
|
|
151
154
|
]
|
|
152
155
|
}
|
|
153
156
|
) }) }) });
|
|
@@ -748,11 +751,11 @@ function OtpInput({ value, onChange, maxLength, disabled = false }) {
|
|
|
748
751
|
textAlign: "center",
|
|
749
752
|
fontSize: "20px",
|
|
750
753
|
fontWeight: 600,
|
|
751
|
-
border: "1px solid var(--border,
|
|
754
|
+
border: "1px solid hsl(var(--border, 214.3 31.8% 91.4%))",
|
|
752
755
|
borderRadius: "8px",
|
|
753
756
|
outline: "none",
|
|
754
|
-
backgroundColor: disabled ? "var(--muted,
|
|
755
|
-
color: "var(--foreground,
|
|
757
|
+
backgroundColor: disabled ? "hsl(var(--muted, 210 40% 96.1%))" : "transparent",
|
|
758
|
+
color: "hsl(var(--foreground, 222.2 84% 4.9%))",
|
|
756
759
|
opacity: disabled ? 0.5 : 1
|
|
757
760
|
}
|
|
758
761
|
},
|
|
@@ -944,7 +947,7 @@ function UserActionModal({
|
|
|
944
947
|
role: "dialog",
|
|
945
948
|
"aria-modal": "true",
|
|
946
949
|
style: {
|
|
947
|
-
backgroundColor: "var(--card,
|
|
950
|
+
backgroundColor: "hsl(var(--card, 0 0% 100%))",
|
|
948
951
|
borderRadius: "12px",
|
|
949
952
|
padding: "24px",
|
|
950
953
|
width: "100%",
|
|
@@ -965,7 +968,7 @@ function UserActionModal({
|
|
|
965
968
|
width: "48px",
|
|
966
969
|
height: "48px",
|
|
967
970
|
borderRadius: "50%",
|
|
968
|
-
backgroundColor: "var(--muted,
|
|
971
|
+
backgroundColor: "hsl(var(--muted, 210 40% 96.1%))",
|
|
969
972
|
marginBottom: "12px"
|
|
970
973
|
},
|
|
971
974
|
children: /* @__PURE__ */ jsx(
|
|
@@ -983,7 +986,7 @@ function UserActionModal({
|
|
|
983
986
|
style: {
|
|
984
987
|
fontSize: "18px",
|
|
985
988
|
fontWeight: 600,
|
|
986
|
-
color: "var(--foreground,
|
|
989
|
+
color: "hsl(var(--foreground, 222.2 84% 4.9%))",
|
|
987
990
|
margin: 0
|
|
988
991
|
},
|
|
989
992
|
children: MODAL_CONTENT.TITLE
|
|
@@ -995,7 +998,7 @@ function UserActionModal({
|
|
|
995
998
|
{
|
|
996
999
|
style: {
|
|
997
1000
|
fontSize: "14px",
|
|
998
|
-
color: "var(--muted-foreground,
|
|
1001
|
+
color: "hsl(var(--muted-foreground, 215.4 16.3% 46.9%))",
|
|
999
1002
|
textAlign: "center",
|
|
1000
1003
|
margin: "0 0 24px 0",
|
|
1001
1004
|
lineHeight: 1.5
|
|
@@ -1128,6 +1131,7 @@ function PaymanChat({
|
|
|
1128
1131
|
children
|
|
1129
1132
|
}) {
|
|
1130
1133
|
const [inputValue, setInputValue] = useState("");
|
|
1134
|
+
const prevInputValueRef = useRef(inputValue);
|
|
1131
1135
|
const chat = useChat(config, callbacks);
|
|
1132
1136
|
const {
|
|
1133
1137
|
messages,
|
|
@@ -1144,6 +1148,29 @@ function PaymanChat({
|
|
|
1144
1148
|
const rejectUserAction = chat.rejectUserAction ?? NOOP_ASYNC;
|
|
1145
1149
|
const resendOtp = chat.resendOtp ?? NOOP_ASYNC;
|
|
1146
1150
|
const isUserActionSupported = typeof chat.approveUserAction === "function" && typeof chat.rejectUserAction === "function" && typeof chat.resendOtp === "function";
|
|
1151
|
+
const {
|
|
1152
|
+
isAvailable: voiceAvailable,
|
|
1153
|
+
isRecording,
|
|
1154
|
+
startRecording,
|
|
1155
|
+
stopRecording,
|
|
1156
|
+
clearTranscript
|
|
1157
|
+
} = useVoice(
|
|
1158
|
+
{
|
|
1159
|
+
lang: config.voiceLang || "en-US",
|
|
1160
|
+
interimResults: config.voiceInterimResults !== false,
|
|
1161
|
+
continuous: config.voiceContinuous !== false
|
|
1162
|
+
},
|
|
1163
|
+
{
|
|
1164
|
+
onResult: (text) => {
|
|
1165
|
+
setInputValue(text);
|
|
1166
|
+
},
|
|
1167
|
+
onEnd: () => {
|
|
1168
|
+
},
|
|
1169
|
+
onError: (error) => {
|
|
1170
|
+
console.error("Voice error:", error);
|
|
1171
|
+
}
|
|
1172
|
+
}
|
|
1173
|
+
);
|
|
1147
1174
|
const contextValue = useMemo(
|
|
1148
1175
|
() => ({
|
|
1149
1176
|
resetSession,
|
|
@@ -1190,7 +1217,21 @@ function PaymanChat({
|
|
|
1190
1217
|
if (!sessionParams) return false;
|
|
1191
1218
|
return !!(sessionParams.id?.trim() && sessionParams.name?.trim());
|
|
1192
1219
|
}, [sessionParams?.id, sessionParams?.name]);
|
|
1220
|
+
useEffect(() => {
|
|
1221
|
+
const wasEmpty = prevInputValueRef.current.trim() === "";
|
|
1222
|
+
const isEmpty = inputValue.trim() === "";
|
|
1223
|
+
prevInputValueRef.current = inputValue;
|
|
1224
|
+
if (!wasEmpty && isEmpty) {
|
|
1225
|
+
clearTranscript();
|
|
1226
|
+
if (isRecording) {
|
|
1227
|
+
stopRecording();
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
}, [inputValue, clearTranscript, isRecording, stopRecording]);
|
|
1193
1231
|
const handleSend = () => {
|
|
1232
|
+
if (isRecording) {
|
|
1233
|
+
stopRecording();
|
|
1234
|
+
}
|
|
1194
1235
|
if (inputValue.trim() && !disableInput && isSessionParamsConfigured) {
|
|
1195
1236
|
sendMessage(inputValue.trim());
|
|
1196
1237
|
setInputValue("");
|
|
@@ -1270,10 +1311,14 @@ function PaymanChat({
|
|
|
1270
1311
|
onSend: handleSend,
|
|
1271
1312
|
onPause: cancelStream,
|
|
1272
1313
|
disabled: isInputDisabled,
|
|
1273
|
-
placeholder,
|
|
1314
|
+
placeholder: isRecording ? "Listening..." : placeholder,
|
|
1274
1315
|
isWaitingForResponse,
|
|
1275
1316
|
hasSelectedSession: true,
|
|
1276
1317
|
isSessionParamsConfigured,
|
|
1318
|
+
enableVoice: config.enableVoice === true,
|
|
1319
|
+
onVoicePress: isRecording ? stopRecording : startRecording,
|
|
1320
|
+
voiceAvailable: config.enableVoice === true && voiceAvailable,
|
|
1321
|
+
isRecording,
|
|
1277
1322
|
inputStyle,
|
|
1278
1323
|
layout
|
|
1279
1324
|
}
|