@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.js CHANGED
@@ -1,10 +1,10 @@
1
1
  'use strict';
2
2
 
3
3
  var paymanTypescriptAskSdk = require('@paymanai/payman-typescript-ask-sdk');
4
+ var framerMotion = require('framer-motion');
4
5
  var react = require('react');
5
6
  var clsx = require('clsx');
6
7
  var tailwindMerge = require('tailwind-merge');
7
- var framerMotion = require('framer-motion');
8
8
  var lucideReact = require('lucide-react');
9
9
  var jsxRuntime = require('react/jsx-runtime');
10
10
  var ReactMarkdown = require('react-markdown');
@@ -74,20 +74,25 @@ function ChatInput({
74
74
  enableVoice = false,
75
75
  onVoicePress,
76
76
  voiceAvailable = false,
77
- isRecording = false
77
+ isRecording = false,
78
+ transcribedText = "",
79
+ onCancelRecording,
80
+ onConfirmRecording,
81
+ showResetSession = false,
82
+ onResetSession
78
83
  }) {
79
84
  const textareaRef = react.useRef(null);
80
85
  const containerRef = react.useRef(null);
81
86
  const prevWaitingRef = react.useRef(isWaitingForResponse);
87
+ const [recordingSeconds, setRecordingSeconds] = react.useState(0);
88
+ const recordingTimerRef = react.useRef(null);
89
+ const [isFocused, setIsFocused] = react.useState(false);
82
90
  react.useEffect(() => {
83
91
  if (textareaRef.current) {
84
92
  textareaRef.current.style.height = "auto";
85
93
  const scrollHeight = textareaRef.current.scrollHeight;
86
94
  const maxHeight = 160;
87
- textareaRef.current.style.height = `${Math.min(
88
- scrollHeight,
89
- maxHeight
90
- )}px`;
95
+ textareaRef.current.style.height = `${Math.min(scrollHeight, maxHeight)}px`;
91
96
  }
92
97
  }, [value]);
93
98
  react.useEffect(() => {
@@ -105,6 +110,25 @@ function ChatInput({
105
110
  });
106
111
  }
107
112
  }, [isWaitingForResponse]);
113
+ react.useEffect(() => {
114
+ if (isRecording) {
115
+ setRecordingSeconds(0);
116
+ recordingTimerRef.current = setInterval(() => {
117
+ setRecordingSeconds((s) => s + 1);
118
+ }, 1e3);
119
+ } else {
120
+ if (recordingTimerRef.current) {
121
+ clearInterval(recordingTimerRef.current);
122
+ recordingTimerRef.current = null;
123
+ }
124
+ setRecordingSeconds(0);
125
+ }
126
+ return () => {
127
+ if (recordingTimerRef.current) {
128
+ clearInterval(recordingTimerRef.current);
129
+ }
130
+ };
131
+ }, [isRecording]);
108
132
  const handleKeyDown = (e) => {
109
133
  if (e.key === "Enter" && !e.shiftKey) {
110
134
  e.preventDefault();
@@ -120,101 +144,178 @@ function ChatInput({
120
144
  if (!isSessionParamsConfigured) return "Configure session params to begin";
121
145
  return placeholder;
122
146
  };
147
+ const formatTime = react.useCallback((seconds) => {
148
+ const mins = Math.floor(seconds / 60);
149
+ const secs = seconds % 60;
150
+ return `${String(mins).padStart(2, "0")}:${String(secs).padStart(2, "0")}`;
151
+ }, []);
152
+ const handleCancel = () => {
153
+ if (onCancelRecording) {
154
+ onCancelRecording();
155
+ } else if (onVoicePress) {
156
+ onVoicePress();
157
+ }
158
+ };
159
+ const handleConfirm = () => {
160
+ if (onConfirmRecording) {
161
+ onConfirmRecording();
162
+ } else if (onVoicePress) {
163
+ onVoicePress();
164
+ }
165
+ };
123
166
  return /* @__PURE__ */ jsxRuntime.jsx(
124
167
  "div",
125
168
  {
126
169
  ref: containerRef,
127
- className: cn("flex-shrink-0 w-full", className),
128
- style: { flexShrink: 0 },
129
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 pb-3 pt-1.5 w-full", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative w-full max-w-2xl mx-auto", children: [
130
- /* @__PURE__ */ jsxRuntime.jsxs(
131
- framerMotion.motion.div,
132
- {
133
- initial: false,
134
- className: cn(
135
- "flex items-end overflow-hidden",
136
- "payman-chat-input"
137
- ),
138
- children: [
139
- /* @__PURE__ */ jsxRuntime.jsx(
140
- "textarea",
141
- {
142
- ref: textareaRef,
143
- value,
144
- onChange: (e) => onChange(e.target.value),
145
- onKeyDown: handleKeyDown,
146
- onClick,
147
- disabled: isInputDisabled,
148
- placeholder: getPlaceholder(),
149
- className: cn(
150
- "payman-chat-input-field",
151
- "focus:outline-none resize-none overflow-y-auto",
152
- "flex-1 min-w-0 py-3"
153
- ),
154
- style: {
155
- minHeight: "44px",
156
- maxHeight: "160px",
157
- paddingLeft: "18px",
158
- paddingRight: "8px"
159
- },
160
- rows: 1
161
- }
162
- ),
163
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1 shrink-0 p-2", children: [
164
- showVoiceButton && /* @__PURE__ */ jsxRuntime.jsxs(
165
- "button",
170
+ className: cn("payman-chat-input-wrapper", className),
171
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "payman-chat-input-container", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "payman-chat-input-inner", children: [
172
+ /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { mode: "wait", children: isRecording ? (
173
+ /* ======== Recording State ======== */
174
+ /* @__PURE__ */ jsxRuntime.jsxs(
175
+ framerMotion.motion.div,
176
+ {
177
+ initial: { opacity: 0, y: 6 },
178
+ animate: { opacity: 1, y: 0 },
179
+ exit: { opacity: 0, y: 6 },
180
+ transition: { duration: 0.25, ease: [0.25, 0.46, 0.45, 0.94] },
181
+ className: "payman-chat-input payman-chat-input--recording",
182
+ children: [
183
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "payman-recording-transcript-area", children: /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { mode: "wait", children: transcribedText ? /* @__PURE__ */ jsxRuntime.jsxs(
184
+ framerMotion.motion.p,
166
185
  {
167
- type: "button",
168
- onClick: onVoicePress,
169
- disabled: isVoiceButtonDisabled,
170
- className: cn(
171
- "relative flex items-center justify-center",
172
- "w-8 h-8 rounded-full transition-all duration-200",
173
- "payman-chat-input-btn-voice",
174
- isRecording && "recording"
175
- ),
176
- "aria-label": isRecording ? "Stop recording" : "Voice input",
186
+ initial: { opacity: 0 },
187
+ animate: { opacity: 1 },
188
+ exit: { opacity: 0 },
189
+ transition: { duration: 0.15 },
190
+ className: "payman-recording-transcript-text",
177
191
  children: [
178
- isRecording && /* @__PURE__ */ jsxRuntime.jsx(
179
- "span",
180
- {
181
- className: "absolute inset-0 rounded-full border-2 animate-ping opacity-40",
182
- style: {
183
- borderColor: "var(--payman-input-btn-voice-recording-ring)"
184
- }
185
- }
186
- ),
187
- isRecording ? /* @__PURE__ */ jsxRuntime.jsx(
188
- lucideReact.Square,
192
+ transcribedText,
193
+ /* @__PURE__ */ jsxRuntime.jsx(
194
+ framerMotion.motion.span,
189
195
  {
190
- className: "w-3 h-3 relative z-10",
191
- fill: "currentColor"
196
+ className: "payman-recording-cursor",
197
+ animate: { opacity: [1, 0] },
198
+ transition: { duration: 0.8, repeat: Infinity, repeatType: "reverse" }
192
199
  }
193
- ) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Mic, { className: "w-4 h-4" })
200
+ )
194
201
  ]
195
- }
196
- ),
202
+ },
203
+ "text"
204
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
205
+ framerMotion.motion.p,
206
+ {
207
+ initial: { opacity: 0 },
208
+ animate: { opacity: 0.5 },
209
+ className: "payman-recording-transcript-placeholder",
210
+ children: "Listening..."
211
+ },
212
+ "placeholder"
213
+ ) }) }),
214
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "payman-recording-bar", children: [
215
+ /* @__PURE__ */ jsxRuntime.jsx(
216
+ "button",
217
+ {
218
+ type: "button",
219
+ onClick: handleCancel,
220
+ className: "payman-recording-btn-cancel",
221
+ "aria-label": "Cancel recording",
222
+ children: "Cancel"
223
+ }
224
+ ),
225
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "payman-recording-indicator", children: [
226
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "payman-recording-dot" }),
227
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "payman-recording-timer", children: formatTime(recordingSeconds) })
228
+ ] }),
229
+ /* @__PURE__ */ jsxRuntime.jsx(
230
+ "button",
231
+ {
232
+ type: "button",
233
+ onClick: handleConfirm,
234
+ className: "payman-recording-btn-confirm",
235
+ "aria-label": "Confirm recording",
236
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "w-4 h-4", strokeWidth: 2.5 })
237
+ }
238
+ )
239
+ ] })
240
+ ]
241
+ },
242
+ "recording"
243
+ )
244
+ ) : (
245
+ /* ======== Normal Input State ======== */
246
+ /* @__PURE__ */ jsxRuntime.jsxs(
247
+ framerMotion.motion.div,
248
+ {
249
+ initial: false,
250
+ animate: { opacity: 1, y: 0 },
251
+ exit: { opacity: 0, y: 6 },
252
+ transition: { duration: 0.2 },
253
+ className: cn(
254
+ "payman-chat-input",
255
+ isFocused && "payman-chat-input--focused"
256
+ ),
257
+ children: [
197
258
  /* @__PURE__ */ jsxRuntime.jsx(
198
- "button",
259
+ "textarea",
199
260
  {
200
- type: "button",
201
- onClick: onSend,
202
- disabled: !canSend,
203
- className: cn(
204
- "flex items-center justify-center",
205
- "w-8 h-8 rounded-full",
206
- "payman-chat-input-btn-send",
207
- "hover:opacity-90 active:scale-95",
208
- "transition-all duration-150"
209
- ),
210
- "aria-label": "Send message",
211
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowUp, { className: "w-4 h-4", strokeWidth: 2.5 })
261
+ ref: textareaRef,
262
+ value,
263
+ onChange: (e) => onChange(e.target.value),
264
+ onKeyDown: handleKeyDown,
265
+ onFocus: () => setIsFocused(true),
266
+ onBlur: () => setIsFocused(false),
267
+ onClick,
268
+ disabled: isInputDisabled,
269
+ placeholder: getPlaceholder(),
270
+ className: "payman-chat-input-field",
271
+ rows: 1
212
272
  }
213
- )
214
- ] })
215
- ]
216
- }
217
- ),
273
+ ),
274
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "payman-chat-input-bottom", children: [
275
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "payman-chat-input-actions-left", children: showResetSession && onResetSession && /* @__PURE__ */ jsxRuntime.jsxs(
276
+ "button",
277
+ {
278
+ type: "button",
279
+ onClick: onResetSession,
280
+ disabled: isWaitingForResponse,
281
+ className: "payman-chat-input-btn-reset",
282
+ "aria-label": "New Session",
283
+ children: [
284
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RotateCcw, { className: "w-3.5 h-3.5", strokeWidth: 2.5 }),
285
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "payman-chat-input-btn-reset-tooltip", children: "New Session" })
286
+ ]
287
+ }
288
+ ) }),
289
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "payman-chat-input-actions", children: [
290
+ showVoiceButton && /* @__PURE__ */ jsxRuntime.jsx(
291
+ "button",
292
+ {
293
+ type: "button",
294
+ onClick: onVoicePress,
295
+ disabled: isVoiceButtonDisabled,
296
+ className: "payman-chat-input-btn-voice",
297
+ "aria-label": "Voice input",
298
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Mic, { className: "w-[18px] h-[18px]" })
299
+ }
300
+ ),
301
+ /* @__PURE__ */ jsxRuntime.jsx(
302
+ "button",
303
+ {
304
+ type: "button",
305
+ onClick: onSend,
306
+ disabled: !canSend,
307
+ className: "payman-chat-input-btn-send",
308
+ "aria-label": "Send message",
309
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowUp, { className: "w-4 h-4", strokeWidth: 2.5 })
310
+ }
311
+ )
312
+ ] })
313
+ ] })
314
+ ]
315
+ },
316
+ "input"
317
+ )
318
+ ) }),
218
319
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "payman-chat-input-disclaimer", children: AI_DISCLAIMER_TEXT })
219
320
  ] }) })
220
321
  }
@@ -783,6 +884,7 @@ function MessageList({
783
884
  isLoading = false,
784
885
  emptyStateText = "What can I help with?",
785
886
  showEmptyStateIcon = true,
887
+ emptyStateComponent,
786
888
  layout = "full-width",
787
889
  showTimestamps = false,
788
890
  stage = "DEV",
@@ -907,7 +1009,7 @@ function MessageList({
907
1009
  }
908
1010
  if (messages.length === 0) {
909
1011
  const lines = emptyStateText.split("\n").map((l) => l.trim()).filter(Boolean);
910
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("payman-empty-root p-8", className), children: /* @__PURE__ */ jsxRuntime.jsxs(
1012
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("payman-empty-root", className), children: /* @__PURE__ */ jsxRuntime.jsxs(
911
1013
  framerMotion.motion.div,
912
1014
  {
913
1015
  initial: { opacity: 0, y: 20 },
@@ -915,17 +1017,17 @@ function MessageList({
915
1017
  transition: { duration: 0.5, ease: [0.25, 0.46, 0.45, 0.94] },
916
1018
  className: "payman-empty-content",
917
1019
  children: [
918
- showEmptyStateIcon && /* @__PURE__ */ jsxRuntime.jsx(
1020
+ emptyStateComponent && /* @__PURE__ */ jsxRuntime.jsx(
919
1021
  framerMotion.motion.div,
920
1022
  {
921
- initial: { scale: 0.85, opacity: 0 },
1023
+ initial: { scale: 0.9, opacity: 0 },
922
1024
  animate: { scale: 1, opacity: 1 },
923
- transition: { delay: 0.08, duration: 0.45, ease: [0.25, 0.46, 0.45, 0.94] },
924
- className: "payman-empty-icon-wrap",
925
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageCircle, { className: "h-7 w-7 payman-empty-icon", strokeWidth: 1.5 })
1025
+ transition: { delay: 0.05, duration: 0.45, ease: [0.25, 0.46, 0.45, 0.94] },
1026
+ className: "payman-empty-custom-component",
1027
+ children: emptyStateComponent
926
1028
  }
927
1029
  ),
928
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-1.5", children: lines.map((line, i) => /* @__PURE__ */ jsxRuntime.jsx(
1030
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "payman-empty-text-group", children: lines.map((line, i) => /* @__PURE__ */ jsxRuntime.jsx(
929
1031
  framerMotion.motion.p,
930
1032
  {
931
1033
  initial: { opacity: 0, y: 6 },
@@ -1467,6 +1569,7 @@ var PaymanChat = react.forwardRef(function PaymanChat2({
1467
1569
  }, ref) {
1468
1570
  const [inputValue, setInputValue] = react.useState("");
1469
1571
  const prevInputValueRef = react.useRef(inputValue);
1572
+ const [hasEverSentMessage, setHasEverSentMessage] = react.useState(false);
1470
1573
  const chat = paymanTypescriptAskSdk.useChat(config, callbacks);
1471
1574
  const {
1472
1575
  messages,
@@ -1479,6 +1582,11 @@ var PaymanChat = react.forwardRef(function PaymanChat2({
1479
1582
  getSessionId,
1480
1583
  getMessages
1481
1584
  } = chat;
1585
+ react.useEffect(() => {
1586
+ if (messages.length > 0 && !hasEverSentMessage) {
1587
+ setHasEverSentMessage(true);
1588
+ }
1589
+ }, [messages.length, hasEverSentMessage]);
1482
1590
  const userActionState = chat.userActionState ?? DEFAULT_USER_ACTION_STATE;
1483
1591
  const approveUserAction = chat.approveUserAction ?? NOOP_ASYNC;
1484
1592
  const rejectUserAction = chat.rejectUserAction ?? NOOP_ASYNC;
@@ -1527,14 +1635,17 @@ var PaymanChat = react.forwardRef(function PaymanChat2({
1527
1635
  isWaitingForResponse
1528
1636
  ]
1529
1637
  );
1638
+ const { onExecutionTraceClick, onResetSession } = callbacks;
1530
1639
  react.useImperativeHandle(ref, () => ({
1531
- resetSession,
1640
+ resetSession: () => {
1641
+ resetSession();
1642
+ onResetSession?.();
1643
+ },
1532
1644
  clearMessages,
1533
1645
  cancelStream,
1534
1646
  getSessionId,
1535
1647
  getMessages
1536
- }), [resetSession, clearMessages, cancelStream, getSessionId, getMessages]);
1537
- const { onExecutionTraceClick } = callbacks;
1648
+ }), [resetSession, clearMessages, cancelStream, getSessionId, getMessages, onResetSession]);
1538
1649
  const {
1539
1650
  placeholder = "Type your message...",
1540
1651
  emptyStateText = "What can I help with?",
@@ -1556,7 +1667,9 @@ var PaymanChat = react.forwardRef(function PaymanChat2({
1556
1667
  animated = true,
1557
1668
  isChatDisabled = false,
1558
1669
  disabledComponent,
1559
- showEmptyStateIcon = true
1670
+ showEmptyStateIcon = true,
1671
+ emptyStateComponent,
1672
+ showResetSession = false
1560
1673
  } = config;
1561
1674
  const isSessionParamsConfigured = react.useMemo(() => {
1562
1675
  if (!sessionParams) return false;
@@ -1564,9 +1677,9 @@ var PaymanChat = react.forwardRef(function PaymanChat2({
1564
1677
  }, [sessionParams?.id, sessionParams?.name]);
1565
1678
  react.useEffect(() => {
1566
1679
  const wasEmpty = prevInputValueRef.current.trim() === "";
1567
- const isEmpty = inputValue.trim() === "";
1680
+ const isEmpty2 = inputValue.trim() === "";
1568
1681
  prevInputValueRef.current = inputValue;
1569
- if (!wasEmpty && isEmpty) {
1682
+ if (!wasEmpty && isEmpty2) {
1570
1683
  clearTranscript();
1571
1684
  if (isRecording) {
1572
1685
  stopRecording();
@@ -1582,14 +1695,23 @@ var PaymanChat = react.forwardRef(function PaymanChat2({
1582
1695
  setInputValue("");
1583
1696
  }
1584
1697
  };
1698
+ const handleCancelRecording = () => {
1699
+ stopRecording();
1700
+ clearTranscript();
1701
+ setInputValue("");
1702
+ };
1703
+ const handleConfirmRecording = () => {
1704
+ stopRecording();
1705
+ };
1585
1706
  const isInputDisabled = isWaitingForResponse || !isSessionParamsConfigured || disableInput;
1707
+ const isEmpty = messages.length === 0;
1586
1708
  if (isChatDisabled) {
1587
1709
  if (disabledComponent) {
1588
1710
  return /* @__PURE__ */ jsxRuntime.jsx(PaymanChatContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsxs(
1589
1711
  "div",
1590
1712
  {
1591
1713
  className: cn(
1592
- "bg-card overflow-hidden flex flex-col flex-[4]",
1714
+ "bg-background overflow-hidden flex flex-col flex-[4]",
1593
1715
  className
1594
1716
  ),
1595
1717
  style,
@@ -1604,7 +1726,7 @@ var PaymanChat = react.forwardRef(function PaymanChat2({
1604
1726
  "div",
1605
1727
  {
1606
1728
  className: cn(
1607
- "bg-card overflow-hidden flex flex-col flex-[4]",
1729
+ "bg-background overflow-hidden flex flex-col flex-[4]",
1608
1730
  className
1609
1731
  ),
1610
1732
  style,
@@ -1615,62 +1737,138 @@ var PaymanChat = react.forwardRef(function PaymanChat2({
1615
1737
  }
1616
1738
  ) });
1617
1739
  }
1740
+ const inputElement = hasAskPermission && /* @__PURE__ */ jsxRuntime.jsx(
1741
+ ChatInput,
1742
+ {
1743
+ value: inputValue,
1744
+ onChange: setInputValue,
1745
+ onSend: handleSend,
1746
+ onPause: cancelStream,
1747
+ disabled: isInputDisabled,
1748
+ placeholder: isRecording ? "Listening..." : placeholder,
1749
+ isWaitingForResponse,
1750
+ hasSelectedSession: true,
1751
+ isSessionParamsConfigured,
1752
+ enableVoice: config.enableVoice === true,
1753
+ onVoicePress: isRecording ? stopRecording : startRecording,
1754
+ voiceAvailable: config.enableVoice === true && voiceAvailable,
1755
+ isRecording,
1756
+ transcribedText: inputValue,
1757
+ onCancelRecording: handleCancelRecording,
1758
+ onConfirmRecording: handleConfirmRecording,
1759
+ inputStyle,
1760
+ layout,
1761
+ showResetSession,
1762
+ onResetSession: () => {
1763
+ resetSession();
1764
+ onResetSession?.();
1765
+ }
1766
+ }
1767
+ );
1618
1768
  return /* @__PURE__ */ jsxRuntime.jsx(PaymanChatContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsxs(
1619
1769
  "div",
1620
1770
  {
1621
1771
  className: cn(
1622
- "bg-card overflow-hidden flex flex-col flex-[4]",
1772
+ "bg-background overflow-hidden flex flex-col flex-[4]",
1623
1773
  className
1624
1774
  ),
1625
1775
  style,
1626
1776
  children: [
1627
1777
  children,
1628
- /* @__PURE__ */ jsxRuntime.jsx(
1629
- MessageList,
1630
- {
1631
- messages,
1632
- isLoading: false,
1633
- emptyStateText,
1634
- showEmptyStateIcon,
1635
- layout,
1636
- showTimestamps,
1637
- stage: config.stage || "DEV",
1638
- animated,
1639
- showAgentName,
1640
- agentName,
1641
- showAvatars,
1642
- showUserAvatar,
1643
- showAssistantAvatar,
1644
- showExecutionSteps,
1645
- showStreamingDot,
1646
- streamingStepsText,
1647
- completedStepsText,
1648
- onExecutionTraceClick,
1649
- onLoadMoreMessages,
1650
- isLoadingMoreMessages,
1651
- hasMoreMessages
1652
- }
1653
- ),
1654
- hasAskPermission && /* @__PURE__ */ jsxRuntime.jsx(
1655
- ChatInput,
1656
- {
1657
- value: inputValue,
1658
- onChange: setInputValue,
1659
- onSend: handleSend,
1660
- onPause: cancelStream,
1661
- disabled: isInputDisabled,
1662
- placeholder: isRecording ? "Listening..." : placeholder,
1663
- isWaitingForResponse,
1664
- hasSelectedSession: true,
1665
- isSessionParamsConfigured,
1666
- enableVoice: config.enableVoice === true,
1667
- onVoicePress: isRecording ? stopRecording : startRecording,
1668
- voiceAvailable: config.enableVoice === true && voiceAvailable,
1669
- isRecording,
1670
- inputStyle,
1671
- layout
1672
- }
1673
- ),
1778
+ /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { mode: "wait", children: isEmpty && !hasEverSentMessage ? (
1779
+ /* ---- Centered empty state with input ---- */
1780
+ /* @__PURE__ */ jsxRuntime.jsx(
1781
+ framerMotion.motion.div,
1782
+ {
1783
+ initial: { opacity: 1 },
1784
+ exit: { opacity: 0 },
1785
+ transition: { duration: 0.3 },
1786
+ className: "payman-empty-centered-layout",
1787
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "payman-empty-centered-inner", children: [
1788
+ /* @__PURE__ */ jsxRuntime.jsx(
1789
+ MessageList,
1790
+ {
1791
+ messages,
1792
+ isLoading: false,
1793
+ emptyStateText,
1794
+ showEmptyStateIcon,
1795
+ emptyStateComponent,
1796
+ layout,
1797
+ showTimestamps,
1798
+ stage: config.stage || "DEV",
1799
+ animated,
1800
+ showAgentName,
1801
+ agentName,
1802
+ showAvatars,
1803
+ showUserAvatar,
1804
+ showAssistantAvatar,
1805
+ showExecutionSteps,
1806
+ showStreamingDot,
1807
+ streamingStepsText,
1808
+ completedStepsText,
1809
+ onExecutionTraceClick,
1810
+ onLoadMoreMessages,
1811
+ isLoadingMoreMessages,
1812
+ hasMoreMessages
1813
+ }
1814
+ ),
1815
+ /* @__PURE__ */ jsxRuntime.jsx(
1816
+ framerMotion.motion.div,
1817
+ {
1818
+ initial: { opacity: 0, y: 12 },
1819
+ animate: { opacity: 1, y: 0 },
1820
+ transition: { delay: 0.2, duration: 0.4, ease: [0.25, 0.46, 0.45, 0.94] },
1821
+ className: "payman-empty-centered-input",
1822
+ children: inputElement
1823
+ }
1824
+ )
1825
+ ] })
1826
+ },
1827
+ "empty-centered"
1828
+ )
1829
+ ) : (
1830
+ /* ---- Normal chat layout ---- */
1831
+ /* @__PURE__ */ jsxRuntime.jsxs(
1832
+ framerMotion.motion.div,
1833
+ {
1834
+ initial: hasEverSentMessage ? { opacity: 0 } : false,
1835
+ animate: { opacity: 1 },
1836
+ transition: { duration: 0.3 },
1837
+ className: "flex flex-col flex-1 min-h-0",
1838
+ children: [
1839
+ /* @__PURE__ */ jsxRuntime.jsx(
1840
+ MessageList,
1841
+ {
1842
+ messages,
1843
+ isLoading: false,
1844
+ emptyStateText,
1845
+ showEmptyStateIcon,
1846
+ emptyStateComponent,
1847
+ layout,
1848
+ showTimestamps,
1849
+ stage: config.stage || "DEV",
1850
+ animated,
1851
+ showAgentName,
1852
+ agentName,
1853
+ showAvatars,
1854
+ showUserAvatar,
1855
+ showAssistantAvatar,
1856
+ showExecutionSteps,
1857
+ showStreamingDot,
1858
+ streamingStepsText,
1859
+ completedStepsText,
1860
+ onExecutionTraceClick,
1861
+ onLoadMoreMessages,
1862
+ isLoadingMoreMessages,
1863
+ hasMoreMessages
1864
+ }
1865
+ ),
1866
+ inputElement
1867
+ ]
1868
+ },
1869
+ "chat-layout"
1870
+ )
1871
+ ) }),
1674
1872
  /* @__PURE__ */ jsxRuntime.jsx(
1675
1873
  UserActionModal,
1676
1874
  {