@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.d.mts
CHANGED
|
@@ -2,7 +2,7 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import React__default from 'react';
|
|
4
4
|
import { UserActionResult, UserActionRequest } from '@paymanai/payman-typescript-ask-sdk';
|
|
5
|
-
export { StreamEvent, StreamOptions, UserActionRequest, UserActionResult, UserActionState, cancelUserAction, generateId, resendUserAction, streamWorkflowEvents, submitUserAction, useChat } from '@paymanai/payman-typescript-ask-sdk';
|
|
5
|
+
export { StreamEvent, StreamOptions, UseVoiceReturn, UserActionRequest, UserActionResult, UserActionState, VoiceCallbacks, VoiceConfig, VoicePermissions, VoiceState, cancelUserAction, generateId, resendUserAction, streamWorkflowEvents, submitUserAction, useChat, useVoice } from '@paymanai/payman-typescript-ask-sdk';
|
|
6
6
|
import { ClassValue } from 'clsx';
|
|
7
7
|
|
|
8
8
|
type MessageRole = "user" | "assistant" | "system";
|
|
@@ -114,6 +114,14 @@ type ChatConfig = {
|
|
|
114
114
|
isChatDisabled?: boolean;
|
|
115
115
|
/** Custom component to render when chat is disabled. If not provided, default disabled UI will be shown */
|
|
116
116
|
disabledComponent?: React__default.ReactNode;
|
|
117
|
+
/** Enable voice input (default: true) */
|
|
118
|
+
enableVoice?: boolean;
|
|
119
|
+
/** Voice language (default: "en-US") */
|
|
120
|
+
voiceLang?: string;
|
|
121
|
+
/** Voice interim results (default: true) */
|
|
122
|
+
voiceInterimResults?: boolean;
|
|
123
|
+
/** Voice continuous mode (default: true) */
|
|
124
|
+
voiceContinuous?: boolean;
|
|
117
125
|
};
|
|
118
126
|
type ChatCallbacks = {
|
|
119
127
|
/** Called when a message is sent (before API call) */
|
|
@@ -176,6 +184,14 @@ type ChatInputProps = {
|
|
|
176
184
|
layout?: "centered" | "full-width";
|
|
177
185
|
/** Custom class name */
|
|
178
186
|
className?: string;
|
|
187
|
+
/** Enable voice input in the chat input. When false, voice button is hidden. */
|
|
188
|
+
enableVoice?: boolean;
|
|
189
|
+
/** Voice button handler */
|
|
190
|
+
onVoicePress?: () => void;
|
|
191
|
+
/** Is voice available (e.g. speech recognition ready) */
|
|
192
|
+
voiceAvailable?: boolean;
|
|
193
|
+
/** Is currently recording voice */
|
|
194
|
+
isRecording?: boolean;
|
|
179
195
|
};
|
|
180
196
|
type MessageListProps = {
|
|
181
197
|
/** Messages to display */
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import React__default from 'react';
|
|
4
4
|
import { UserActionResult, UserActionRequest } from '@paymanai/payman-typescript-ask-sdk';
|
|
5
|
-
export { StreamEvent, StreamOptions, UserActionRequest, UserActionResult, UserActionState, cancelUserAction, generateId, resendUserAction, streamWorkflowEvents, submitUserAction, useChat } from '@paymanai/payman-typescript-ask-sdk';
|
|
5
|
+
export { StreamEvent, StreamOptions, UseVoiceReturn, UserActionRequest, UserActionResult, UserActionState, VoiceCallbacks, VoiceConfig, VoicePermissions, VoiceState, cancelUserAction, generateId, resendUserAction, streamWorkflowEvents, submitUserAction, useChat, useVoice } from '@paymanai/payman-typescript-ask-sdk';
|
|
6
6
|
import { ClassValue } from 'clsx';
|
|
7
7
|
|
|
8
8
|
type MessageRole = "user" | "assistant" | "system";
|
|
@@ -114,6 +114,14 @@ type ChatConfig = {
|
|
|
114
114
|
isChatDisabled?: boolean;
|
|
115
115
|
/** Custom component to render when chat is disabled. If not provided, default disabled UI will be shown */
|
|
116
116
|
disabledComponent?: React__default.ReactNode;
|
|
117
|
+
/** Enable voice input (default: true) */
|
|
118
|
+
enableVoice?: boolean;
|
|
119
|
+
/** Voice language (default: "en-US") */
|
|
120
|
+
voiceLang?: string;
|
|
121
|
+
/** Voice interim results (default: true) */
|
|
122
|
+
voiceInterimResults?: boolean;
|
|
123
|
+
/** Voice continuous mode (default: true) */
|
|
124
|
+
voiceContinuous?: boolean;
|
|
117
125
|
};
|
|
118
126
|
type ChatCallbacks = {
|
|
119
127
|
/** Called when a message is sent (before API call) */
|
|
@@ -176,6 +184,14 @@ type ChatInputProps = {
|
|
|
176
184
|
layout?: "centered" | "full-width";
|
|
177
185
|
/** Custom class name */
|
|
178
186
|
className?: string;
|
|
187
|
+
/** Enable voice input in the chat input. When false, voice button is hidden. */
|
|
188
|
+
enableVoice?: boolean;
|
|
189
|
+
/** Voice button handler */
|
|
190
|
+
onVoicePress?: () => void;
|
|
191
|
+
/** Is voice available (e.g. speech recognition ready) */
|
|
192
|
+
voiceAvailable?: boolean;
|
|
193
|
+
/** Is currently recording voice */
|
|
194
|
+
isRecording?: boolean;
|
|
179
195
|
};
|
|
180
196
|
type MessageListProps = {
|
|
181
197
|
/** Messages to display */
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var react = require('react');
|
|
4
3
|
var paymanTypescriptAskSdk = require('@paymanai/payman-typescript-ask-sdk');
|
|
4
|
+
var react = require('react');
|
|
5
5
|
var clsx = require('clsx');
|
|
6
6
|
var tailwindMerge = require('tailwind-merge');
|
|
7
7
|
var framerMotion = require('framer-motion');
|
|
@@ -64,7 +64,11 @@ function ChatInput({
|
|
|
64
64
|
hasSelectedSession = true,
|
|
65
65
|
isSessionParamsConfigured = true,
|
|
66
66
|
onClick,
|
|
67
|
-
className
|
|
67
|
+
className,
|
|
68
|
+
enableVoice = false,
|
|
69
|
+
onVoicePress,
|
|
70
|
+
voiceAvailable = false,
|
|
71
|
+
isRecording = false
|
|
68
72
|
}) {
|
|
69
73
|
const textareaRef = react.useRef(null);
|
|
70
74
|
react.useEffect(() => {
|
|
@@ -83,6 +87,8 @@ function ChatInput({
|
|
|
83
87
|
};
|
|
84
88
|
const isInputDisabled = disabled || isWaitingForResponse;
|
|
85
89
|
const showPauseButton = isWaitingForResponse && onPause;
|
|
90
|
+
const showVoiceButton = enableVoice && onVoicePress != null;
|
|
91
|
+
const isVoiceButtonDisabled = isWaitingForResponse || !voiceAvailable || !isSessionParamsConfigured;
|
|
86
92
|
const getPlaceholder = () => {
|
|
87
93
|
if (!hasSelectedSession) {
|
|
88
94
|
return "Select a version to start chatting";
|
|
@@ -96,7 +102,7 @@ function ChatInput({
|
|
|
96
102
|
framerMotion.motion.div,
|
|
97
103
|
{
|
|
98
104
|
initial: false,
|
|
99
|
-
className: "
|
|
105
|
+
className: "flex items-end overflow-hidden transition-colors bg-input border border-border shadow-sm",
|
|
100
106
|
style: { borderRadius: "24px" },
|
|
101
107
|
children: [
|
|
102
108
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -109,51 +115,48 @@ function ChatInput({
|
|
|
109
115
|
onClick,
|
|
110
116
|
disabled: isInputDisabled,
|
|
111
117
|
placeholder: getPlaceholder(),
|
|
112
|
-
className: "bg-transparent text-foreground focus:outline-none resize-none overflow-y-auto disabled:opacity-50 disabled:cursor-not-allowed w-
|
|
118
|
+
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",
|
|
113
119
|
style: {
|
|
114
120
|
minHeight: "48px",
|
|
115
121
|
maxHeight: "200px",
|
|
116
|
-
padding: "12px
|
|
122
|
+
padding: "12px 12px 12px 16px"
|
|
117
123
|
},
|
|
118
124
|
rows: 1
|
|
119
125
|
}
|
|
120
126
|
),
|
|
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
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Send, { className: "w-4 h-4" })
|
|
155
|
-
}
|
|
156
|
-
)
|
|
127
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-row items-center gap-1 shrink-0 mb-2 mr-2", children: [
|
|
128
|
+
showVoiceButton && /* @__PURE__ */ jsxRuntime.jsx(
|
|
129
|
+
"button",
|
|
130
|
+
{
|
|
131
|
+
type: "button",
|
|
132
|
+
onClick: onVoicePress,
|
|
133
|
+
disabled: isVoiceButtonDisabled,
|
|
134
|
+
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`,
|
|
135
|
+
"aria-label": isRecording ? "Stop recording" : "Voice input",
|
|
136
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Mic, { className: `w-5 h-5 shrink-0 ${isRecording ? "text-red-500" : "text-foreground"}` })
|
|
137
|
+
}
|
|
138
|
+
),
|
|
139
|
+
showPauseButton ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
140
|
+
"button",
|
|
141
|
+
{
|
|
142
|
+
type: "button",
|
|
143
|
+
onClick: onPause,
|
|
144
|
+
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",
|
|
145
|
+
"aria-label": "Pause request",
|
|
146
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Pause, { className: "w-4 h-4" })
|
|
147
|
+
}
|
|
148
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
149
|
+
"button",
|
|
150
|
+
{
|
|
151
|
+
type: "button",
|
|
152
|
+
onClick: onSend,
|
|
153
|
+
disabled: isInputDisabled || !value.trim(),
|
|
154
|
+
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",
|
|
155
|
+
"aria-label": "Send message",
|
|
156
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Send, { className: "w-4 h-4" })
|
|
157
|
+
}
|
|
158
|
+
)
|
|
159
|
+
] })
|
|
157
160
|
]
|
|
158
161
|
}
|
|
159
162
|
) }) }) });
|
|
@@ -754,11 +757,11 @@ function OtpInput({ value, onChange, maxLength, disabled = false }) {
|
|
|
754
757
|
textAlign: "center",
|
|
755
758
|
fontSize: "20px",
|
|
756
759
|
fontWeight: 600,
|
|
757
|
-
border: "1px solid var(--border,
|
|
760
|
+
border: "1px solid hsl(var(--border, 214.3 31.8% 91.4%))",
|
|
758
761
|
borderRadius: "8px",
|
|
759
762
|
outline: "none",
|
|
760
|
-
backgroundColor: disabled ? "var(--muted,
|
|
761
|
-
color: "var(--foreground,
|
|
763
|
+
backgroundColor: disabled ? "hsl(var(--muted, 210 40% 96.1%))" : "transparent",
|
|
764
|
+
color: "hsl(var(--foreground, 222.2 84% 4.9%))",
|
|
762
765
|
opacity: disabled ? 0.5 : 1
|
|
763
766
|
}
|
|
764
767
|
},
|
|
@@ -950,7 +953,7 @@ function UserActionModal({
|
|
|
950
953
|
role: "dialog",
|
|
951
954
|
"aria-modal": "true",
|
|
952
955
|
style: {
|
|
953
|
-
backgroundColor: "var(--card,
|
|
956
|
+
backgroundColor: "hsl(var(--card, 0 0% 100%))",
|
|
954
957
|
borderRadius: "12px",
|
|
955
958
|
padding: "24px",
|
|
956
959
|
width: "100%",
|
|
@@ -971,7 +974,7 @@ function UserActionModal({
|
|
|
971
974
|
width: "48px",
|
|
972
975
|
height: "48px",
|
|
973
976
|
borderRadius: "50%",
|
|
974
|
-
backgroundColor: "var(--muted,
|
|
977
|
+
backgroundColor: "hsl(var(--muted, 210 40% 96.1%))",
|
|
975
978
|
marginBottom: "12px"
|
|
976
979
|
},
|
|
977
980
|
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -989,7 +992,7 @@ function UserActionModal({
|
|
|
989
992
|
style: {
|
|
990
993
|
fontSize: "18px",
|
|
991
994
|
fontWeight: 600,
|
|
992
|
-
color: "var(--foreground,
|
|
995
|
+
color: "hsl(var(--foreground, 222.2 84% 4.9%))",
|
|
993
996
|
margin: 0
|
|
994
997
|
},
|
|
995
998
|
children: MODAL_CONTENT.TITLE
|
|
@@ -1001,7 +1004,7 @@ function UserActionModal({
|
|
|
1001
1004
|
{
|
|
1002
1005
|
style: {
|
|
1003
1006
|
fontSize: "14px",
|
|
1004
|
-
color: "var(--muted-foreground,
|
|
1007
|
+
color: "hsl(var(--muted-foreground, 215.4 16.3% 46.9%))",
|
|
1005
1008
|
textAlign: "center",
|
|
1006
1009
|
margin: "0 0 24px 0",
|
|
1007
1010
|
lineHeight: 1.5
|
|
@@ -1134,6 +1137,7 @@ function PaymanChat({
|
|
|
1134
1137
|
children
|
|
1135
1138
|
}) {
|
|
1136
1139
|
const [inputValue, setInputValue] = react.useState("");
|
|
1140
|
+
const prevInputValueRef = react.useRef(inputValue);
|
|
1137
1141
|
const chat = paymanTypescriptAskSdk.useChat(config, callbacks);
|
|
1138
1142
|
const {
|
|
1139
1143
|
messages,
|
|
@@ -1150,6 +1154,29 @@ function PaymanChat({
|
|
|
1150
1154
|
const rejectUserAction = chat.rejectUserAction ?? NOOP_ASYNC;
|
|
1151
1155
|
const resendOtp = chat.resendOtp ?? NOOP_ASYNC;
|
|
1152
1156
|
const isUserActionSupported = typeof chat.approveUserAction === "function" && typeof chat.rejectUserAction === "function" && typeof chat.resendOtp === "function";
|
|
1157
|
+
const {
|
|
1158
|
+
isAvailable: voiceAvailable,
|
|
1159
|
+
isRecording,
|
|
1160
|
+
startRecording,
|
|
1161
|
+
stopRecording,
|
|
1162
|
+
clearTranscript
|
|
1163
|
+
} = paymanTypescriptAskSdk.useVoice(
|
|
1164
|
+
{
|
|
1165
|
+
lang: config.voiceLang || "en-US",
|
|
1166
|
+
interimResults: config.voiceInterimResults !== false,
|
|
1167
|
+
continuous: config.voiceContinuous !== false
|
|
1168
|
+
},
|
|
1169
|
+
{
|
|
1170
|
+
onResult: (text) => {
|
|
1171
|
+
setInputValue(text);
|
|
1172
|
+
},
|
|
1173
|
+
onEnd: () => {
|
|
1174
|
+
},
|
|
1175
|
+
onError: (error) => {
|
|
1176
|
+
console.error("Voice error:", error);
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
);
|
|
1153
1180
|
const contextValue = react.useMemo(
|
|
1154
1181
|
() => ({
|
|
1155
1182
|
resetSession,
|
|
@@ -1196,7 +1223,21 @@ function PaymanChat({
|
|
|
1196
1223
|
if (!sessionParams) return false;
|
|
1197
1224
|
return !!(sessionParams.id?.trim() && sessionParams.name?.trim());
|
|
1198
1225
|
}, [sessionParams?.id, sessionParams?.name]);
|
|
1226
|
+
react.useEffect(() => {
|
|
1227
|
+
const wasEmpty = prevInputValueRef.current.trim() === "";
|
|
1228
|
+
const isEmpty = inputValue.trim() === "";
|
|
1229
|
+
prevInputValueRef.current = inputValue;
|
|
1230
|
+
if (!wasEmpty && isEmpty) {
|
|
1231
|
+
clearTranscript();
|
|
1232
|
+
if (isRecording) {
|
|
1233
|
+
stopRecording();
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
1236
|
+
}, [inputValue, clearTranscript, isRecording, stopRecording]);
|
|
1199
1237
|
const handleSend = () => {
|
|
1238
|
+
if (isRecording) {
|
|
1239
|
+
stopRecording();
|
|
1240
|
+
}
|
|
1200
1241
|
if (inputValue.trim() && !disableInput && isSessionParamsConfigured) {
|
|
1201
1242
|
sendMessage(inputValue.trim());
|
|
1202
1243
|
setInputValue("");
|
|
@@ -1276,10 +1317,14 @@ function PaymanChat({
|
|
|
1276
1317
|
onSend: handleSend,
|
|
1277
1318
|
onPause: cancelStream,
|
|
1278
1319
|
disabled: isInputDisabled,
|
|
1279
|
-
placeholder,
|
|
1320
|
+
placeholder: isRecording ? "Listening..." : placeholder,
|
|
1280
1321
|
isWaitingForResponse,
|
|
1281
1322
|
hasSelectedSession: true,
|
|
1282
1323
|
isSessionParamsConfigured,
|
|
1324
|
+
enableVoice: config.enableVoice === true,
|
|
1325
|
+
onVoicePress: isRecording ? stopRecording : startRecording,
|
|
1326
|
+
voiceAvailable: config.enableVoice === true && voiceAvailable,
|
|
1327
|
+
isRecording,
|
|
1283
1328
|
inputStyle,
|
|
1284
1329
|
layout
|
|
1285
1330
|
}
|
|
@@ -1324,6 +1369,10 @@ Object.defineProperty(exports, "useChat", {
|
|
|
1324
1369
|
enumerable: true,
|
|
1325
1370
|
get: function () { return paymanTypescriptAskSdk.useChat; }
|
|
1326
1371
|
});
|
|
1372
|
+
Object.defineProperty(exports, "useVoice", {
|
|
1373
|
+
enumerable: true,
|
|
1374
|
+
get: function () { return paymanTypescriptAskSdk.useVoice; }
|
|
1375
|
+
});
|
|
1327
1376
|
exports.PaymanChat = PaymanChat;
|
|
1328
1377
|
exports.PaymanChatContext = PaymanChatContext;
|
|
1329
1378
|
exports.cn = cn;
|