@paymanai/payman-ask-sdk 1.1.2 → 1.2.1
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 +99 -113
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +98 -116
- 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
|
) }) }) });
|
|
@@ -748,19 +751,7 @@ function OtpInput({ value, onChange, maxLength, disabled = false }) {
|
|
|
748
751
|
onPaste: handlePaste,
|
|
749
752
|
onFocus: (e) => e.target.select(),
|
|
750
753
|
"aria-label": `Digit ${i + 1}`,
|
|
751
|
-
|
|
752
|
-
width: "40px",
|
|
753
|
-
height: "48px",
|
|
754
|
-
textAlign: "center",
|
|
755
|
-
fontSize: "20px",
|
|
756
|
-
fontWeight: 600,
|
|
757
|
-
border: "1px solid hsl(var(--border, 214.3 31.8% 91.4%))",
|
|
758
|
-
borderRadius: "8px",
|
|
759
|
-
outline: "none",
|
|
760
|
-
backgroundColor: disabled ? "hsl(var(--muted, 210 40% 96.1%))" : "transparent",
|
|
761
|
-
color: "hsl(var(--foreground, 222.2 84% 4.9%))",
|
|
762
|
-
opacity: disabled ? 0.5 : 1
|
|
763
|
-
}
|
|
754
|
+
className: `w-10 h-12 text-center text-xl font-semibold border border-border rounded-lg outline-none text-foreground ${disabled ? "bg-muted opacity-50" : "bg-transparent"}`
|
|
764
755
|
},
|
|
765
756
|
i
|
|
766
757
|
)) });
|
|
@@ -949,67 +940,16 @@ function UserActionModal({
|
|
|
949
940
|
ref: dialogRef,
|
|
950
941
|
role: "dialog",
|
|
951
942
|
"aria-modal": "true",
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
borderRadius: "12px",
|
|
955
|
-
padding: "24px",
|
|
956
|
-
width: "100%",
|
|
957
|
-
maxWidth: "420px",
|
|
958
|
-
margin: "0 16px",
|
|
959
|
-
boxShadow: "0 25px 50px -12px rgba(0, 0, 0, 0.25)"
|
|
960
|
-
},
|
|
943
|
+
className: "bg-card rounded-xl p-6 shadow-2xl",
|
|
944
|
+
style: { width: "100%", maxWidth: "420px", margin: "0 16px" },
|
|
961
945
|
tabIndex: -1,
|
|
962
946
|
children: [
|
|
963
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", {
|
|
964
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
965
|
-
|
|
966
|
-
{
|
|
967
|
-
style: {
|
|
968
|
-
display: "inline-flex",
|
|
969
|
-
alignItems: "center",
|
|
970
|
-
justifyContent: "center",
|
|
971
|
-
width: "48px",
|
|
972
|
-
height: "48px",
|
|
973
|
-
borderRadius: "50%",
|
|
974
|
-
backgroundColor: "hsl(var(--muted, 210 40% 96.1%))",
|
|
975
|
-
marginBottom: "12px"
|
|
976
|
-
},
|
|
977
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
978
|
-
lucideReact.ShieldCheck,
|
|
979
|
-
{
|
|
980
|
-
className: "text-primary",
|
|
981
|
-
style: { width: "24px", height: "24px" }
|
|
982
|
-
}
|
|
983
|
-
)
|
|
984
|
-
}
|
|
985
|
-
),
|
|
986
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
987
|
-
"h2",
|
|
988
|
-
{
|
|
989
|
-
style: {
|
|
990
|
-
fontSize: "18px",
|
|
991
|
-
fontWeight: 600,
|
|
992
|
-
color: "hsl(var(--foreground, 222.2 84% 4.9%))",
|
|
993
|
-
margin: 0
|
|
994
|
-
},
|
|
995
|
-
children: MODAL_CONTENT.TITLE
|
|
996
|
-
}
|
|
997
|
-
)
|
|
947
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center mb-4", children: [
|
|
948
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "inline-flex items-center justify-center w-12 h-12 rounded-full bg-muted mb-3", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ShieldCheck, { className: "w-6 h-6 text-primary" }) }),
|
|
949
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-lg font-semibold text-foreground m-0", children: MODAL_CONTENT.TITLE })
|
|
998
950
|
] }),
|
|
999
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1000
|
-
|
|
1001
|
-
{
|
|
1002
|
-
style: {
|
|
1003
|
-
fontSize: "14px",
|
|
1004
|
-
color: "hsl(var(--muted-foreground, 215.4 16.3% 46.9%))",
|
|
1005
|
-
textAlign: "center",
|
|
1006
|
-
margin: "0 0 24px 0",
|
|
1007
|
-
lineHeight: 1.5
|
|
1008
|
-
},
|
|
1009
|
-
children: userActionRequest.message
|
|
1010
|
-
}
|
|
1011
|
-
),
|
|
1012
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { marginBottom: "24px" }, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
951
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground text-center mb-6 leading-relaxed", children: userActionRequest.message }),
|
|
952
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-6", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1013
953
|
OtpInput,
|
|
1014
954
|
{
|
|
1015
955
|
value: otp,
|
|
@@ -1134,6 +1074,7 @@ function PaymanChat({
|
|
|
1134
1074
|
children
|
|
1135
1075
|
}) {
|
|
1136
1076
|
const [inputValue, setInputValue] = react.useState("");
|
|
1077
|
+
const prevInputValueRef = react.useRef(inputValue);
|
|
1137
1078
|
const chat = paymanTypescriptAskSdk.useChat(config, callbacks);
|
|
1138
1079
|
const {
|
|
1139
1080
|
messages,
|
|
@@ -1150,6 +1091,29 @@ function PaymanChat({
|
|
|
1150
1091
|
const rejectUserAction = chat.rejectUserAction ?? NOOP_ASYNC;
|
|
1151
1092
|
const resendOtp = chat.resendOtp ?? NOOP_ASYNC;
|
|
1152
1093
|
const isUserActionSupported = typeof chat.approveUserAction === "function" && typeof chat.rejectUserAction === "function" && typeof chat.resendOtp === "function";
|
|
1094
|
+
const {
|
|
1095
|
+
isAvailable: voiceAvailable,
|
|
1096
|
+
isRecording,
|
|
1097
|
+
startRecording,
|
|
1098
|
+
stopRecording,
|
|
1099
|
+
clearTranscript
|
|
1100
|
+
} = paymanTypescriptAskSdk.useVoice(
|
|
1101
|
+
{
|
|
1102
|
+
lang: config.voiceLang || "en-US",
|
|
1103
|
+
interimResults: config.voiceInterimResults !== false,
|
|
1104
|
+
continuous: config.voiceContinuous !== false
|
|
1105
|
+
},
|
|
1106
|
+
{
|
|
1107
|
+
onResult: (text) => {
|
|
1108
|
+
setInputValue(text);
|
|
1109
|
+
},
|
|
1110
|
+
onEnd: () => {
|
|
1111
|
+
},
|
|
1112
|
+
onError: (error) => {
|
|
1113
|
+
console.error("Voice error:", error);
|
|
1114
|
+
}
|
|
1115
|
+
}
|
|
1116
|
+
);
|
|
1153
1117
|
const contextValue = react.useMemo(
|
|
1154
1118
|
() => ({
|
|
1155
1119
|
resetSession,
|
|
@@ -1196,7 +1160,21 @@ function PaymanChat({
|
|
|
1196
1160
|
if (!sessionParams) return false;
|
|
1197
1161
|
return !!(sessionParams.id?.trim() && sessionParams.name?.trim());
|
|
1198
1162
|
}, [sessionParams?.id, sessionParams?.name]);
|
|
1163
|
+
react.useEffect(() => {
|
|
1164
|
+
const wasEmpty = prevInputValueRef.current.trim() === "";
|
|
1165
|
+
const isEmpty = inputValue.trim() === "";
|
|
1166
|
+
prevInputValueRef.current = inputValue;
|
|
1167
|
+
if (!wasEmpty && isEmpty) {
|
|
1168
|
+
clearTranscript();
|
|
1169
|
+
if (isRecording) {
|
|
1170
|
+
stopRecording();
|
|
1171
|
+
}
|
|
1172
|
+
}
|
|
1173
|
+
}, [inputValue, clearTranscript, isRecording, stopRecording]);
|
|
1199
1174
|
const handleSend = () => {
|
|
1175
|
+
if (isRecording) {
|
|
1176
|
+
stopRecording();
|
|
1177
|
+
}
|
|
1200
1178
|
if (inputValue.trim() && !disableInput && isSessionParamsConfigured) {
|
|
1201
1179
|
sendMessage(inputValue.trim());
|
|
1202
1180
|
setInputValue("");
|
|
@@ -1276,10 +1254,14 @@ function PaymanChat({
|
|
|
1276
1254
|
onSend: handleSend,
|
|
1277
1255
|
onPause: cancelStream,
|
|
1278
1256
|
disabled: isInputDisabled,
|
|
1279
|
-
placeholder,
|
|
1257
|
+
placeholder: isRecording ? "Listening..." : placeholder,
|
|
1280
1258
|
isWaitingForResponse,
|
|
1281
1259
|
hasSelectedSession: true,
|
|
1282
1260
|
isSessionParamsConfigured,
|
|
1261
|
+
enableVoice: config.enableVoice === true,
|
|
1262
|
+
onVoicePress: isRecording ? stopRecording : startRecording,
|
|
1263
|
+
voiceAvailable: config.enableVoice === true && voiceAvailable,
|
|
1264
|
+
isRecording,
|
|
1283
1265
|
inputStyle,
|
|
1284
1266
|
layout
|
|
1285
1267
|
}
|
|
@@ -1324,6 +1306,10 @@ Object.defineProperty(exports, "useChat", {
|
|
|
1324
1306
|
enumerable: true,
|
|
1325
1307
|
get: function () { return paymanTypescriptAskSdk.useChat; }
|
|
1326
1308
|
});
|
|
1309
|
+
Object.defineProperty(exports, "useVoice", {
|
|
1310
|
+
enumerable: true,
|
|
1311
|
+
get: function () { return paymanTypescriptAskSdk.useVoice; }
|
|
1312
|
+
});
|
|
1327
1313
|
exports.PaymanChat = PaymanChat;
|
|
1328
1314
|
exports.PaymanChatContext = PaymanChatContext;
|
|
1329
1315
|
exports.cn = cn;
|