@paymanai/payman-ask-sdk 1.2.17 → 1.2.18
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 +12 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +349 -151
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +351 -153
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +383 -36
- package/dist/styles.css.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
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 {
|
|
3
|
+
import { AnimatePresence, motion } from 'framer-motion';
|
|
4
|
+
import { createContext, forwardRef, useState, useRef, useEffect, useMemo, useImperativeHandle, useCallback, useLayoutEffect, useContext } from 'react';
|
|
4
5
|
import { clsx } from 'clsx';
|
|
5
6
|
import { twMerge } from 'tailwind-merge';
|
|
6
|
-
import {
|
|
7
|
-
import { MessageCircle, ArrowDown, Square, Mic, ArrowUp, ShieldCheck, Loader2, X, Check, RefreshCw, User, Clock, Sparkles, Binoculars, ChevronDown, ChevronRight } from 'lucide-react';
|
|
7
|
+
import { Check, RotateCcw, Mic, ArrowUp, ArrowDown, ShieldCheck, Loader2, X, RefreshCw, User, Clock, Sparkles, Binoculars, ChevronDown, ChevronRight } 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';
|
|
@@ -68,20 +68,25 @@ function ChatInput({
|
|
|
68
68
|
enableVoice = false,
|
|
69
69
|
onVoicePress,
|
|
70
70
|
voiceAvailable = false,
|
|
71
|
-
isRecording = false
|
|
71
|
+
isRecording = false,
|
|
72
|
+
transcribedText = "",
|
|
73
|
+
onCancelRecording,
|
|
74
|
+
onConfirmRecording,
|
|
75
|
+
showResetSession = false,
|
|
76
|
+
onResetSession
|
|
72
77
|
}) {
|
|
73
78
|
const textareaRef = useRef(null);
|
|
74
79
|
const containerRef = useRef(null);
|
|
75
80
|
const prevWaitingRef = useRef(isWaitingForResponse);
|
|
81
|
+
const [recordingSeconds, setRecordingSeconds] = useState(0);
|
|
82
|
+
const recordingTimerRef = useRef(null);
|
|
83
|
+
const [isFocused, setIsFocused] = useState(false);
|
|
76
84
|
useEffect(() => {
|
|
77
85
|
if (textareaRef.current) {
|
|
78
86
|
textareaRef.current.style.height = "auto";
|
|
79
87
|
const scrollHeight = textareaRef.current.scrollHeight;
|
|
80
88
|
const maxHeight = 160;
|
|
81
|
-
textareaRef.current.style.height = `${Math.min(
|
|
82
|
-
scrollHeight,
|
|
83
|
-
maxHeight
|
|
84
|
-
)}px`;
|
|
89
|
+
textareaRef.current.style.height = `${Math.min(scrollHeight, maxHeight)}px`;
|
|
85
90
|
}
|
|
86
91
|
}, [value]);
|
|
87
92
|
useEffect(() => {
|
|
@@ -99,6 +104,25 @@ function ChatInput({
|
|
|
99
104
|
});
|
|
100
105
|
}
|
|
101
106
|
}, [isWaitingForResponse]);
|
|
107
|
+
useEffect(() => {
|
|
108
|
+
if (isRecording) {
|
|
109
|
+
setRecordingSeconds(0);
|
|
110
|
+
recordingTimerRef.current = setInterval(() => {
|
|
111
|
+
setRecordingSeconds((s) => s + 1);
|
|
112
|
+
}, 1e3);
|
|
113
|
+
} else {
|
|
114
|
+
if (recordingTimerRef.current) {
|
|
115
|
+
clearInterval(recordingTimerRef.current);
|
|
116
|
+
recordingTimerRef.current = null;
|
|
117
|
+
}
|
|
118
|
+
setRecordingSeconds(0);
|
|
119
|
+
}
|
|
120
|
+
return () => {
|
|
121
|
+
if (recordingTimerRef.current) {
|
|
122
|
+
clearInterval(recordingTimerRef.current);
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
}, [isRecording]);
|
|
102
126
|
const handleKeyDown = (e) => {
|
|
103
127
|
if (e.key === "Enter" && !e.shiftKey) {
|
|
104
128
|
e.preventDefault();
|
|
@@ -114,101 +138,178 @@ function ChatInput({
|
|
|
114
138
|
if (!isSessionParamsConfigured) return "Configure session params to begin";
|
|
115
139
|
return placeholder;
|
|
116
140
|
};
|
|
141
|
+
const formatTime = useCallback((seconds) => {
|
|
142
|
+
const mins = Math.floor(seconds / 60);
|
|
143
|
+
const secs = seconds % 60;
|
|
144
|
+
return `${String(mins).padStart(2, "0")}:${String(secs).padStart(2, "0")}`;
|
|
145
|
+
}, []);
|
|
146
|
+
const handleCancel = () => {
|
|
147
|
+
if (onCancelRecording) {
|
|
148
|
+
onCancelRecording();
|
|
149
|
+
} else if (onVoicePress) {
|
|
150
|
+
onVoicePress();
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
const handleConfirm = () => {
|
|
154
|
+
if (onConfirmRecording) {
|
|
155
|
+
onConfirmRecording();
|
|
156
|
+
} else if (onVoicePress) {
|
|
157
|
+
onVoicePress();
|
|
158
|
+
}
|
|
159
|
+
};
|
|
117
160
|
return /* @__PURE__ */ jsx(
|
|
118
161
|
"div",
|
|
119
162
|
{
|
|
120
163
|
ref: containerRef,
|
|
121
|
-
className: cn("
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
"
|
|
135
|
-
|
|
136
|
-
ref: textareaRef,
|
|
137
|
-
value,
|
|
138
|
-
onChange: (e) => onChange(e.target.value),
|
|
139
|
-
onKeyDown: handleKeyDown,
|
|
140
|
-
onClick,
|
|
141
|
-
disabled: isInputDisabled,
|
|
142
|
-
placeholder: getPlaceholder(),
|
|
143
|
-
className: cn(
|
|
144
|
-
"payman-chat-input-field",
|
|
145
|
-
"focus:outline-none resize-none overflow-y-auto",
|
|
146
|
-
"flex-1 min-w-0 py-3"
|
|
147
|
-
),
|
|
148
|
-
style: {
|
|
149
|
-
minHeight: "44px",
|
|
150
|
-
maxHeight: "160px",
|
|
151
|
-
paddingLeft: "18px",
|
|
152
|
-
paddingRight: "8px"
|
|
153
|
-
},
|
|
154
|
-
rows: 1
|
|
155
|
-
}
|
|
156
|
-
),
|
|
157
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 shrink-0 p-2", children: [
|
|
158
|
-
showVoiceButton && /* @__PURE__ */ jsxs(
|
|
159
|
-
"button",
|
|
164
|
+
className: cn("payman-chat-input-wrapper", className),
|
|
165
|
+
children: /* @__PURE__ */ jsx("div", { className: "payman-chat-input-container", children: /* @__PURE__ */ jsxs("div", { className: "payman-chat-input-inner", children: [
|
|
166
|
+
/* @__PURE__ */ jsx(AnimatePresence, { mode: "wait", children: isRecording ? (
|
|
167
|
+
/* ======== Recording State ======== */
|
|
168
|
+
/* @__PURE__ */ jsxs(
|
|
169
|
+
motion.div,
|
|
170
|
+
{
|
|
171
|
+
initial: { opacity: 0, y: 6 },
|
|
172
|
+
animate: { opacity: 1, y: 0 },
|
|
173
|
+
exit: { opacity: 0, y: 6 },
|
|
174
|
+
transition: { duration: 0.25, ease: [0.25, 0.46, 0.45, 0.94] },
|
|
175
|
+
className: "payman-chat-input payman-chat-input--recording",
|
|
176
|
+
children: [
|
|
177
|
+
/* @__PURE__ */ jsx("div", { className: "payman-recording-transcript-area", children: /* @__PURE__ */ jsx(AnimatePresence, { mode: "wait", children: transcribedText ? /* @__PURE__ */ jsxs(
|
|
178
|
+
motion.p,
|
|
160
179
|
{
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
"w-8 h-8 rounded-full transition-all duration-200",
|
|
167
|
-
"payman-chat-input-btn-voice",
|
|
168
|
-
isRecording && "recording"
|
|
169
|
-
),
|
|
170
|
-
"aria-label": isRecording ? "Stop recording" : "Voice input",
|
|
180
|
+
initial: { opacity: 0 },
|
|
181
|
+
animate: { opacity: 1 },
|
|
182
|
+
exit: { opacity: 0 },
|
|
183
|
+
transition: { duration: 0.15 },
|
|
184
|
+
className: "payman-recording-transcript-text",
|
|
171
185
|
children: [
|
|
172
|
-
|
|
173
|
-
|
|
186
|
+
transcribedText,
|
|
187
|
+
/* @__PURE__ */ jsx(
|
|
188
|
+
motion.span,
|
|
174
189
|
{
|
|
175
|
-
className: "
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
),
|
|
181
|
-
isRecording ? /* @__PURE__ */ jsx(
|
|
182
|
-
Square,
|
|
183
|
-
{
|
|
184
|
-
className: "w-3 h-3 relative z-10",
|
|
185
|
-
fill: "currentColor"
|
|
190
|
+
className: "payman-recording-cursor",
|
|
191
|
+
animate: { opacity: [1, 0] },
|
|
192
|
+
transition: { duration: 0.8, repeat: Infinity, repeatType: "reverse" }
|
|
186
193
|
}
|
|
187
|
-
)
|
|
194
|
+
)
|
|
188
195
|
]
|
|
189
|
-
}
|
|
190
|
-
|
|
196
|
+
},
|
|
197
|
+
"text"
|
|
198
|
+
) : /* @__PURE__ */ jsx(
|
|
199
|
+
motion.p,
|
|
200
|
+
{
|
|
201
|
+
initial: { opacity: 0 },
|
|
202
|
+
animate: { opacity: 0.5 },
|
|
203
|
+
className: "payman-recording-transcript-placeholder",
|
|
204
|
+
children: "Listening..."
|
|
205
|
+
},
|
|
206
|
+
"placeholder"
|
|
207
|
+
) }) }),
|
|
208
|
+
/* @__PURE__ */ jsxs("div", { className: "payman-recording-bar", children: [
|
|
209
|
+
/* @__PURE__ */ jsx(
|
|
210
|
+
"button",
|
|
211
|
+
{
|
|
212
|
+
type: "button",
|
|
213
|
+
onClick: handleCancel,
|
|
214
|
+
className: "payman-recording-btn-cancel",
|
|
215
|
+
"aria-label": "Cancel recording",
|
|
216
|
+
children: "Cancel"
|
|
217
|
+
}
|
|
218
|
+
),
|
|
219
|
+
/* @__PURE__ */ jsxs("div", { className: "payman-recording-indicator", children: [
|
|
220
|
+
/* @__PURE__ */ jsx("span", { className: "payman-recording-dot" }),
|
|
221
|
+
/* @__PURE__ */ jsx("span", { className: "payman-recording-timer", children: formatTime(recordingSeconds) })
|
|
222
|
+
] }),
|
|
223
|
+
/* @__PURE__ */ jsx(
|
|
224
|
+
"button",
|
|
225
|
+
{
|
|
226
|
+
type: "button",
|
|
227
|
+
onClick: handleConfirm,
|
|
228
|
+
className: "payman-recording-btn-confirm",
|
|
229
|
+
"aria-label": "Confirm recording",
|
|
230
|
+
children: /* @__PURE__ */ jsx(Check, { className: "w-4 h-4", strokeWidth: 2.5 })
|
|
231
|
+
}
|
|
232
|
+
)
|
|
233
|
+
] })
|
|
234
|
+
]
|
|
235
|
+
},
|
|
236
|
+
"recording"
|
|
237
|
+
)
|
|
238
|
+
) : (
|
|
239
|
+
/* ======== Normal Input State ======== */
|
|
240
|
+
/* @__PURE__ */ jsxs(
|
|
241
|
+
motion.div,
|
|
242
|
+
{
|
|
243
|
+
initial: false,
|
|
244
|
+
animate: { opacity: 1, y: 0 },
|
|
245
|
+
exit: { opacity: 0, y: 6 },
|
|
246
|
+
transition: { duration: 0.2 },
|
|
247
|
+
className: cn(
|
|
248
|
+
"payman-chat-input",
|
|
249
|
+
isFocused && "payman-chat-input--focused"
|
|
250
|
+
),
|
|
251
|
+
children: [
|
|
191
252
|
/* @__PURE__ */ jsx(
|
|
192
|
-
"
|
|
253
|
+
"textarea",
|
|
193
254
|
{
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
children: /* @__PURE__ */ jsx(ArrowUp, { className: "w-4 h-4", strokeWidth: 2.5 })
|
|
255
|
+
ref: textareaRef,
|
|
256
|
+
value,
|
|
257
|
+
onChange: (e) => onChange(e.target.value),
|
|
258
|
+
onKeyDown: handleKeyDown,
|
|
259
|
+
onFocus: () => setIsFocused(true),
|
|
260
|
+
onBlur: () => setIsFocused(false),
|
|
261
|
+
onClick,
|
|
262
|
+
disabled: isInputDisabled,
|
|
263
|
+
placeholder: getPlaceholder(),
|
|
264
|
+
className: "payman-chat-input-field",
|
|
265
|
+
rows: 1
|
|
206
266
|
}
|
|
207
|
-
)
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
267
|
+
),
|
|
268
|
+
/* @__PURE__ */ jsxs("div", { className: "payman-chat-input-bottom", children: [
|
|
269
|
+
/* @__PURE__ */ jsx("div", { className: "payman-chat-input-actions-left", children: showResetSession && onResetSession && /* @__PURE__ */ jsxs(
|
|
270
|
+
"button",
|
|
271
|
+
{
|
|
272
|
+
type: "button",
|
|
273
|
+
onClick: onResetSession,
|
|
274
|
+
disabled: isWaitingForResponse,
|
|
275
|
+
className: "payman-chat-input-btn-reset",
|
|
276
|
+
"aria-label": "New Session",
|
|
277
|
+
children: [
|
|
278
|
+
/* @__PURE__ */ jsx(RotateCcw, { className: "w-3.5 h-3.5", strokeWidth: 2.5 }),
|
|
279
|
+
/* @__PURE__ */ jsx("span", { className: "payman-chat-input-btn-reset-tooltip", children: "New Session" })
|
|
280
|
+
]
|
|
281
|
+
}
|
|
282
|
+
) }),
|
|
283
|
+
/* @__PURE__ */ jsxs("div", { className: "payman-chat-input-actions", children: [
|
|
284
|
+
showVoiceButton && /* @__PURE__ */ jsx(
|
|
285
|
+
"button",
|
|
286
|
+
{
|
|
287
|
+
type: "button",
|
|
288
|
+
onClick: onVoicePress,
|
|
289
|
+
disabled: isVoiceButtonDisabled,
|
|
290
|
+
className: "payman-chat-input-btn-voice",
|
|
291
|
+
"aria-label": "Voice input",
|
|
292
|
+
children: /* @__PURE__ */ jsx(Mic, { className: "w-[18px] h-[18px]" })
|
|
293
|
+
}
|
|
294
|
+
),
|
|
295
|
+
/* @__PURE__ */ jsx(
|
|
296
|
+
"button",
|
|
297
|
+
{
|
|
298
|
+
type: "button",
|
|
299
|
+
onClick: onSend,
|
|
300
|
+
disabled: !canSend,
|
|
301
|
+
className: "payman-chat-input-btn-send",
|
|
302
|
+
"aria-label": "Send message",
|
|
303
|
+
children: /* @__PURE__ */ jsx(ArrowUp, { className: "w-4 h-4", strokeWidth: 2.5 })
|
|
304
|
+
}
|
|
305
|
+
)
|
|
306
|
+
] })
|
|
307
|
+
] })
|
|
308
|
+
]
|
|
309
|
+
},
|
|
310
|
+
"input"
|
|
311
|
+
)
|
|
312
|
+
) }),
|
|
212
313
|
/* @__PURE__ */ jsx("p", { className: "payman-chat-input-disclaimer", children: AI_DISCLAIMER_TEXT })
|
|
213
314
|
] }) })
|
|
214
315
|
}
|
|
@@ -777,6 +878,7 @@ function MessageList({
|
|
|
777
878
|
isLoading = false,
|
|
778
879
|
emptyStateText = "What can I help with?",
|
|
779
880
|
showEmptyStateIcon = true,
|
|
881
|
+
emptyStateComponent,
|
|
780
882
|
layout = "full-width",
|
|
781
883
|
showTimestamps = false,
|
|
782
884
|
stage = "DEV",
|
|
@@ -901,7 +1003,7 @@ function MessageList({
|
|
|
901
1003
|
}
|
|
902
1004
|
if (messages.length === 0) {
|
|
903
1005
|
const lines = emptyStateText.split("\n").map((l) => l.trim()).filter(Boolean);
|
|
904
|
-
return /* @__PURE__ */ jsx("div", { className: cn("payman-empty-root
|
|
1006
|
+
return /* @__PURE__ */ jsx("div", { className: cn("payman-empty-root", className), children: /* @__PURE__ */ jsxs(
|
|
905
1007
|
motion.div,
|
|
906
1008
|
{
|
|
907
1009
|
initial: { opacity: 0, y: 20 },
|
|
@@ -909,17 +1011,17 @@ function MessageList({
|
|
|
909
1011
|
transition: { duration: 0.5, ease: [0.25, 0.46, 0.45, 0.94] },
|
|
910
1012
|
className: "payman-empty-content",
|
|
911
1013
|
children: [
|
|
912
|
-
|
|
1014
|
+
emptyStateComponent && /* @__PURE__ */ jsx(
|
|
913
1015
|
motion.div,
|
|
914
1016
|
{
|
|
915
|
-
initial: { scale: 0.
|
|
1017
|
+
initial: { scale: 0.9, opacity: 0 },
|
|
916
1018
|
animate: { scale: 1, opacity: 1 },
|
|
917
|
-
transition: { delay: 0.
|
|
918
|
-
className: "payman-empty-
|
|
919
|
-
children:
|
|
1019
|
+
transition: { delay: 0.05, duration: 0.45, ease: [0.25, 0.46, 0.45, 0.94] },
|
|
1020
|
+
className: "payman-empty-custom-component",
|
|
1021
|
+
children: emptyStateComponent
|
|
920
1022
|
}
|
|
921
1023
|
),
|
|
922
|
-
/* @__PURE__ */ jsx("div", { className: "
|
|
1024
|
+
/* @__PURE__ */ jsx("div", { className: "payman-empty-text-group", children: lines.map((line, i) => /* @__PURE__ */ jsx(
|
|
923
1025
|
motion.p,
|
|
924
1026
|
{
|
|
925
1027
|
initial: { opacity: 0, y: 6 },
|
|
@@ -1461,6 +1563,7 @@ var PaymanChat = forwardRef(function PaymanChat2({
|
|
|
1461
1563
|
}, ref) {
|
|
1462
1564
|
const [inputValue, setInputValue] = useState("");
|
|
1463
1565
|
const prevInputValueRef = useRef(inputValue);
|
|
1566
|
+
const [hasEverSentMessage, setHasEverSentMessage] = useState(false);
|
|
1464
1567
|
const chat = useChat(config, callbacks);
|
|
1465
1568
|
const {
|
|
1466
1569
|
messages,
|
|
@@ -1473,6 +1576,11 @@ var PaymanChat = forwardRef(function PaymanChat2({
|
|
|
1473
1576
|
getSessionId,
|
|
1474
1577
|
getMessages
|
|
1475
1578
|
} = chat;
|
|
1579
|
+
useEffect(() => {
|
|
1580
|
+
if (messages.length > 0 && !hasEverSentMessage) {
|
|
1581
|
+
setHasEverSentMessage(true);
|
|
1582
|
+
}
|
|
1583
|
+
}, [messages.length, hasEverSentMessage]);
|
|
1476
1584
|
const userActionState = chat.userActionState ?? DEFAULT_USER_ACTION_STATE;
|
|
1477
1585
|
const approveUserAction = chat.approveUserAction ?? NOOP_ASYNC;
|
|
1478
1586
|
const rejectUserAction = chat.rejectUserAction ?? NOOP_ASYNC;
|
|
@@ -1521,14 +1629,17 @@ var PaymanChat = forwardRef(function PaymanChat2({
|
|
|
1521
1629
|
isWaitingForResponse
|
|
1522
1630
|
]
|
|
1523
1631
|
);
|
|
1632
|
+
const { onExecutionTraceClick, onResetSession } = callbacks;
|
|
1524
1633
|
useImperativeHandle(ref, () => ({
|
|
1525
|
-
resetSession
|
|
1634
|
+
resetSession: () => {
|
|
1635
|
+
resetSession();
|
|
1636
|
+
onResetSession?.();
|
|
1637
|
+
},
|
|
1526
1638
|
clearMessages,
|
|
1527
1639
|
cancelStream,
|
|
1528
1640
|
getSessionId,
|
|
1529
1641
|
getMessages
|
|
1530
|
-
}), [resetSession, clearMessages, cancelStream, getSessionId, getMessages]);
|
|
1531
|
-
const { onExecutionTraceClick } = callbacks;
|
|
1642
|
+
}), [resetSession, clearMessages, cancelStream, getSessionId, getMessages, onResetSession]);
|
|
1532
1643
|
const {
|
|
1533
1644
|
placeholder = "Type your message...",
|
|
1534
1645
|
emptyStateText = "What can I help with?",
|
|
@@ -1550,7 +1661,9 @@ var PaymanChat = forwardRef(function PaymanChat2({
|
|
|
1550
1661
|
animated = true,
|
|
1551
1662
|
isChatDisabled = false,
|
|
1552
1663
|
disabledComponent,
|
|
1553
|
-
showEmptyStateIcon = true
|
|
1664
|
+
showEmptyStateIcon = true,
|
|
1665
|
+
emptyStateComponent,
|
|
1666
|
+
showResetSession = false
|
|
1554
1667
|
} = config;
|
|
1555
1668
|
const isSessionParamsConfigured = useMemo(() => {
|
|
1556
1669
|
if (!sessionParams) return false;
|
|
@@ -1558,9 +1671,9 @@ var PaymanChat = forwardRef(function PaymanChat2({
|
|
|
1558
1671
|
}, [sessionParams?.id, sessionParams?.name]);
|
|
1559
1672
|
useEffect(() => {
|
|
1560
1673
|
const wasEmpty = prevInputValueRef.current.trim() === "";
|
|
1561
|
-
const
|
|
1674
|
+
const isEmpty2 = inputValue.trim() === "";
|
|
1562
1675
|
prevInputValueRef.current = inputValue;
|
|
1563
|
-
if (!wasEmpty &&
|
|
1676
|
+
if (!wasEmpty && isEmpty2) {
|
|
1564
1677
|
clearTranscript();
|
|
1565
1678
|
if (isRecording) {
|
|
1566
1679
|
stopRecording();
|
|
@@ -1576,14 +1689,23 @@ var PaymanChat = forwardRef(function PaymanChat2({
|
|
|
1576
1689
|
setInputValue("");
|
|
1577
1690
|
}
|
|
1578
1691
|
};
|
|
1692
|
+
const handleCancelRecording = () => {
|
|
1693
|
+
stopRecording();
|
|
1694
|
+
clearTranscript();
|
|
1695
|
+
setInputValue("");
|
|
1696
|
+
};
|
|
1697
|
+
const handleConfirmRecording = () => {
|
|
1698
|
+
stopRecording();
|
|
1699
|
+
};
|
|
1579
1700
|
const isInputDisabled = isWaitingForResponse || !isSessionParamsConfigured || disableInput;
|
|
1701
|
+
const isEmpty = messages.length === 0;
|
|
1580
1702
|
if (isChatDisabled) {
|
|
1581
1703
|
if (disabledComponent) {
|
|
1582
1704
|
return /* @__PURE__ */ jsx(PaymanChatContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxs(
|
|
1583
1705
|
"div",
|
|
1584
1706
|
{
|
|
1585
1707
|
className: cn(
|
|
1586
|
-
"bg-
|
|
1708
|
+
"bg-background overflow-hidden flex flex-col flex-[4]",
|
|
1587
1709
|
className
|
|
1588
1710
|
),
|
|
1589
1711
|
style,
|
|
@@ -1598,7 +1720,7 @@ var PaymanChat = forwardRef(function PaymanChat2({
|
|
|
1598
1720
|
"div",
|
|
1599
1721
|
{
|
|
1600
1722
|
className: cn(
|
|
1601
|
-
"bg-
|
|
1723
|
+
"bg-background overflow-hidden flex flex-col flex-[4]",
|
|
1602
1724
|
className
|
|
1603
1725
|
),
|
|
1604
1726
|
style,
|
|
@@ -1609,62 +1731,138 @@ var PaymanChat = forwardRef(function PaymanChat2({
|
|
|
1609
1731
|
}
|
|
1610
1732
|
) });
|
|
1611
1733
|
}
|
|
1734
|
+
const inputElement = hasAskPermission && /* @__PURE__ */ jsx(
|
|
1735
|
+
ChatInput,
|
|
1736
|
+
{
|
|
1737
|
+
value: inputValue,
|
|
1738
|
+
onChange: setInputValue,
|
|
1739
|
+
onSend: handleSend,
|
|
1740
|
+
onPause: cancelStream,
|
|
1741
|
+
disabled: isInputDisabled,
|
|
1742
|
+
placeholder: isRecording ? "Listening..." : placeholder,
|
|
1743
|
+
isWaitingForResponse,
|
|
1744
|
+
hasSelectedSession: true,
|
|
1745
|
+
isSessionParamsConfigured,
|
|
1746
|
+
enableVoice: config.enableVoice === true,
|
|
1747
|
+
onVoicePress: isRecording ? stopRecording : startRecording,
|
|
1748
|
+
voiceAvailable: config.enableVoice === true && voiceAvailable,
|
|
1749
|
+
isRecording,
|
|
1750
|
+
transcribedText: inputValue,
|
|
1751
|
+
onCancelRecording: handleCancelRecording,
|
|
1752
|
+
onConfirmRecording: handleConfirmRecording,
|
|
1753
|
+
inputStyle,
|
|
1754
|
+
layout,
|
|
1755
|
+
showResetSession,
|
|
1756
|
+
onResetSession: () => {
|
|
1757
|
+
resetSession();
|
|
1758
|
+
onResetSession?.();
|
|
1759
|
+
}
|
|
1760
|
+
}
|
|
1761
|
+
);
|
|
1612
1762
|
return /* @__PURE__ */ jsx(PaymanChatContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxs(
|
|
1613
1763
|
"div",
|
|
1614
1764
|
{
|
|
1615
1765
|
className: cn(
|
|
1616
|
-
"bg-
|
|
1766
|
+
"bg-background overflow-hidden flex flex-col flex-[4]",
|
|
1617
1767
|
className
|
|
1618
1768
|
),
|
|
1619
1769
|
style,
|
|
1620
1770
|
children: [
|
|
1621
1771
|
children,
|
|
1622
|
-
/* @__PURE__ */ jsx(
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1772
|
+
/* @__PURE__ */ jsx(AnimatePresence, { mode: "wait", children: isEmpty && !hasEverSentMessage ? (
|
|
1773
|
+
/* ---- Centered empty state with input ---- */
|
|
1774
|
+
/* @__PURE__ */ jsx(
|
|
1775
|
+
motion.div,
|
|
1776
|
+
{
|
|
1777
|
+
initial: { opacity: 1 },
|
|
1778
|
+
exit: { opacity: 0 },
|
|
1779
|
+
transition: { duration: 0.3 },
|
|
1780
|
+
className: "payman-empty-centered-layout",
|
|
1781
|
+
children: /* @__PURE__ */ jsxs("div", { className: "payman-empty-centered-inner", children: [
|
|
1782
|
+
/* @__PURE__ */ jsx(
|
|
1783
|
+
MessageList,
|
|
1784
|
+
{
|
|
1785
|
+
messages,
|
|
1786
|
+
isLoading: false,
|
|
1787
|
+
emptyStateText,
|
|
1788
|
+
showEmptyStateIcon,
|
|
1789
|
+
emptyStateComponent,
|
|
1790
|
+
layout,
|
|
1791
|
+
showTimestamps,
|
|
1792
|
+
stage: config.stage || "DEV",
|
|
1793
|
+
animated,
|
|
1794
|
+
showAgentName,
|
|
1795
|
+
agentName,
|
|
1796
|
+
showAvatars,
|
|
1797
|
+
showUserAvatar,
|
|
1798
|
+
showAssistantAvatar,
|
|
1799
|
+
showExecutionSteps,
|
|
1800
|
+
showStreamingDot,
|
|
1801
|
+
streamingStepsText,
|
|
1802
|
+
completedStepsText,
|
|
1803
|
+
onExecutionTraceClick,
|
|
1804
|
+
onLoadMoreMessages,
|
|
1805
|
+
isLoadingMoreMessages,
|
|
1806
|
+
hasMoreMessages
|
|
1807
|
+
}
|
|
1808
|
+
),
|
|
1809
|
+
/* @__PURE__ */ jsx(
|
|
1810
|
+
motion.div,
|
|
1811
|
+
{
|
|
1812
|
+
initial: { opacity: 0, y: 12 },
|
|
1813
|
+
animate: { opacity: 1, y: 0 },
|
|
1814
|
+
transition: { delay: 0.2, duration: 0.4, ease: [0.25, 0.46, 0.45, 0.94] },
|
|
1815
|
+
className: "payman-empty-centered-input",
|
|
1816
|
+
children: inputElement
|
|
1817
|
+
}
|
|
1818
|
+
)
|
|
1819
|
+
] })
|
|
1820
|
+
},
|
|
1821
|
+
"empty-centered"
|
|
1822
|
+
)
|
|
1823
|
+
) : (
|
|
1824
|
+
/* ---- Normal chat layout ---- */
|
|
1825
|
+
/* @__PURE__ */ jsxs(
|
|
1826
|
+
motion.div,
|
|
1827
|
+
{
|
|
1828
|
+
initial: hasEverSentMessage ? { opacity: 0 } : false,
|
|
1829
|
+
animate: { opacity: 1 },
|
|
1830
|
+
transition: { duration: 0.3 },
|
|
1831
|
+
className: "flex flex-col flex-1 min-h-0",
|
|
1832
|
+
children: [
|
|
1833
|
+
/* @__PURE__ */ jsx(
|
|
1834
|
+
MessageList,
|
|
1835
|
+
{
|
|
1836
|
+
messages,
|
|
1837
|
+
isLoading: false,
|
|
1838
|
+
emptyStateText,
|
|
1839
|
+
showEmptyStateIcon,
|
|
1840
|
+
emptyStateComponent,
|
|
1841
|
+
layout,
|
|
1842
|
+
showTimestamps,
|
|
1843
|
+
stage: config.stage || "DEV",
|
|
1844
|
+
animated,
|
|
1845
|
+
showAgentName,
|
|
1846
|
+
agentName,
|
|
1847
|
+
showAvatars,
|
|
1848
|
+
showUserAvatar,
|
|
1849
|
+
showAssistantAvatar,
|
|
1850
|
+
showExecutionSteps,
|
|
1851
|
+
showStreamingDot,
|
|
1852
|
+
streamingStepsText,
|
|
1853
|
+
completedStepsText,
|
|
1854
|
+
onExecutionTraceClick,
|
|
1855
|
+
onLoadMoreMessages,
|
|
1856
|
+
isLoadingMoreMessages,
|
|
1857
|
+
hasMoreMessages
|
|
1858
|
+
}
|
|
1859
|
+
),
|
|
1860
|
+
inputElement
|
|
1861
|
+
]
|
|
1862
|
+
},
|
|
1863
|
+
"chat-layout"
|
|
1864
|
+
)
|
|
1865
|
+
) }),
|
|
1668
1866
|
/* @__PURE__ */ jsx(
|
|
1669
1867
|
UserActionModal,
|
|
1670
1868
|
{
|