@paymanai/payman-ask-sdk 1.2.3 → 1.2.5
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/README.md +32 -0
- package/dist/index.d.mts +16 -2
- package/dist/index.d.ts +16 -2
- package/dist/index.js +880 -561
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +881 -562
- package/dist/index.mjs.map +1 -1
- package/dist/index.native.js +1132 -1188
- package/dist/index.native.js.map +1 -1
- package/dist/styles.css +705 -54
- package/dist/styles.css.map +1 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import { createContext, useContext, useState, useRef, useMemo, useEffect, useCal
|
|
|
4
4
|
import { clsx } from 'clsx';
|
|
5
5
|
import { twMerge } from 'tailwind-merge';
|
|
6
6
|
import { motion, AnimatePresence } from 'framer-motion';
|
|
7
|
-
import {
|
|
7
|
+
import { MessageCircle, ArrowDown, Square, Mic, ArrowUp, ShieldCheck, Loader2, X, Check, 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';
|
|
@@ -47,6 +47,11 @@ function formatDate(timestamp) {
|
|
|
47
47
|
year: date.getFullYear() !== now.getFullYear() ? "numeric" : void 0
|
|
48
48
|
});
|
|
49
49
|
}
|
|
50
|
+
function formatElapsedTime(ms) {
|
|
51
|
+
if (!ms) return "";
|
|
52
|
+
if (ms < 1e3) return `${ms}ms`;
|
|
53
|
+
return `${(ms / 1e3).toFixed(1)}s`;
|
|
54
|
+
}
|
|
50
55
|
function ChatInput({
|
|
51
56
|
value,
|
|
52
57
|
onChange,
|
|
@@ -69,92 +74,181 @@ function ChatInput({
|
|
|
69
74
|
if (textareaRef.current) {
|
|
70
75
|
textareaRef.current.style.height = "auto";
|
|
71
76
|
const scrollHeight = textareaRef.current.scrollHeight;
|
|
72
|
-
const maxHeight =
|
|
73
|
-
textareaRef.current.style.height = `${Math.min(
|
|
77
|
+
const maxHeight = 160;
|
|
78
|
+
textareaRef.current.style.height = `${Math.min(
|
|
79
|
+
scrollHeight,
|
|
80
|
+
maxHeight
|
|
81
|
+
)}px`;
|
|
74
82
|
}
|
|
75
83
|
}, [value]);
|
|
76
84
|
const handleKeyDown = (e) => {
|
|
77
85
|
if (e.key === "Enter" && !e.shiftKey) {
|
|
78
86
|
e.preventDefault();
|
|
79
|
-
onSend();
|
|
87
|
+
if (value.trim() && !isInputDisabled) onSend();
|
|
80
88
|
}
|
|
81
89
|
};
|
|
82
90
|
const isInputDisabled = disabled || isWaitingForResponse;
|
|
83
91
|
const showPauseButton = isWaitingForResponse && onPause;
|
|
84
92
|
const showVoiceButton = enableVoice && onVoicePress != null;
|
|
85
93
|
const isVoiceButtonDisabled = isWaitingForResponse || !voiceAvailable || !isSessionParamsConfigured;
|
|
94
|
+
const canSend = !isInputDisabled && !!value.trim();
|
|
86
95
|
const getPlaceholder = () => {
|
|
87
|
-
if (!hasSelectedSession)
|
|
88
|
-
|
|
89
|
-
}
|
|
90
|
-
if (!isSessionParamsConfigured) {
|
|
91
|
-
return "Configure User ID and User Label in Session Params";
|
|
92
|
-
}
|
|
96
|
+
if (!hasSelectedSession) return "Select a version to start chatting";
|
|
97
|
+
if (!isSessionParamsConfigured) return "Configure session params to begin";
|
|
93
98
|
return placeholder;
|
|
94
99
|
};
|
|
95
|
-
return /* @__PURE__ */ jsx(
|
|
96
|
-
|
|
100
|
+
return /* @__PURE__ */ jsx(
|
|
101
|
+
"div",
|
|
97
102
|
{
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
onChange: (e) => onChange(e.target.value),
|
|
108
|
-
onKeyDown: handleKeyDown,
|
|
109
|
-
onClick,
|
|
110
|
-
disabled: isInputDisabled,
|
|
111
|
-
placeholder: getPlaceholder(),
|
|
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",
|
|
113
|
-
style: {
|
|
114
|
-
minHeight: "48px",
|
|
115
|
-
maxHeight: "200px",
|
|
116
|
-
padding: "12px 12px 12px 16px"
|
|
117
|
-
},
|
|
118
|
-
rows: 1
|
|
119
|
-
}
|
|
120
|
-
),
|
|
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
|
-
}
|
|
103
|
+
className: cn("flex-shrink-0 w-full", className),
|
|
104
|
+
style: { flexShrink: 0 },
|
|
105
|
+
children: /* @__PURE__ */ jsx("div", { className: "px-3 pb-3 pt-1.5 w-full", children: /* @__PURE__ */ jsx("div", { className: "relative w-full max-w-2xl mx-auto", children: /* @__PURE__ */ jsxs(
|
|
106
|
+
motion.div,
|
|
107
|
+
{
|
|
108
|
+
initial: false,
|
|
109
|
+
className: cn(
|
|
110
|
+
"flex items-end overflow-hidden",
|
|
111
|
+
"payman-chat-input"
|
|
132
112
|
),
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
113
|
+
children: [
|
|
114
|
+
/* @__PURE__ */ jsx(
|
|
115
|
+
"textarea",
|
|
116
|
+
{
|
|
117
|
+
ref: textareaRef,
|
|
118
|
+
value,
|
|
119
|
+
onChange: (e) => onChange(e.target.value),
|
|
120
|
+
onKeyDown: handleKeyDown,
|
|
121
|
+
onClick,
|
|
122
|
+
disabled: isInputDisabled,
|
|
123
|
+
placeholder: getPlaceholder(),
|
|
124
|
+
className: cn(
|
|
125
|
+
"payman-chat-input-field",
|
|
126
|
+
"focus:outline-none resize-none overflow-y-auto",
|
|
127
|
+
"flex-1 min-w-0 py-3"
|
|
128
|
+
),
|
|
129
|
+
style: {
|
|
130
|
+
minHeight: "44px",
|
|
131
|
+
maxHeight: "160px",
|
|
132
|
+
paddingLeft: "18px",
|
|
133
|
+
paddingRight: "8px"
|
|
134
|
+
},
|
|
135
|
+
rows: 1
|
|
136
|
+
}
|
|
137
|
+
),
|
|
138
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 shrink-0 p-2", children: [
|
|
139
|
+
showVoiceButton && /* @__PURE__ */ jsxs(
|
|
140
|
+
"button",
|
|
141
|
+
{
|
|
142
|
+
type: "button",
|
|
143
|
+
onClick: onVoicePress,
|
|
144
|
+
disabled: isVoiceButtonDisabled,
|
|
145
|
+
className: cn(
|
|
146
|
+
"relative flex items-center justify-center",
|
|
147
|
+
"w-8 h-8 rounded-full transition-all duration-200",
|
|
148
|
+
"payman-chat-input-btn-voice",
|
|
149
|
+
isRecording && "recording"
|
|
150
|
+
),
|
|
151
|
+
"aria-label": isRecording ? "Stop recording" : "Voice input",
|
|
152
|
+
children: [
|
|
153
|
+
isRecording && /* @__PURE__ */ jsx(
|
|
154
|
+
"span",
|
|
155
|
+
{
|
|
156
|
+
className: "absolute inset-0 rounded-full border-2 animate-ping opacity-40",
|
|
157
|
+
style: {
|
|
158
|
+
borderColor: "var(--payman-input-btn-voice-recording-ring)"
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
),
|
|
162
|
+
isRecording ? /* @__PURE__ */ jsx(
|
|
163
|
+
Square,
|
|
164
|
+
{
|
|
165
|
+
className: "w-3 h-3 relative z-10",
|
|
166
|
+
fill: "currentColor"
|
|
167
|
+
}
|
|
168
|
+
) : /* @__PURE__ */ jsx(Mic, { className: "w-4 h-4" })
|
|
169
|
+
]
|
|
170
|
+
}
|
|
171
|
+
),
|
|
172
|
+
showPauseButton ? /* @__PURE__ */ jsx(
|
|
173
|
+
"button",
|
|
174
|
+
{
|
|
175
|
+
type: "button",
|
|
176
|
+
onClick: onPause,
|
|
177
|
+
className: cn(
|
|
178
|
+
"flex items-center justify-center",
|
|
179
|
+
"w-8 h-8 rounded-full",
|
|
180
|
+
"payman-chat-input-btn-pause",
|
|
181
|
+
"hover:opacity-90 active:scale-95",
|
|
182
|
+
"transition-all duration-150"
|
|
183
|
+
),
|
|
184
|
+
"aria-label": "Stop response",
|
|
185
|
+
children: /* @__PURE__ */ jsx(Square, { className: "w-3.5 h-3.5", fill: "currentColor" })
|
|
186
|
+
}
|
|
187
|
+
) : /* @__PURE__ */ jsx(
|
|
188
|
+
"button",
|
|
189
|
+
{
|
|
190
|
+
type: "button",
|
|
191
|
+
onClick: onSend,
|
|
192
|
+
disabled: !canSend,
|
|
193
|
+
className: cn(
|
|
194
|
+
"flex items-center justify-center",
|
|
195
|
+
"w-8 h-8 rounded-full",
|
|
196
|
+
"payman-chat-input-btn-send",
|
|
197
|
+
"hover:opacity-90 active:scale-95",
|
|
198
|
+
"transition-all duration-150"
|
|
199
|
+
),
|
|
200
|
+
"aria-label": "Send message",
|
|
201
|
+
children: /* @__PURE__ */ jsx(ArrowUp, { className: "w-4 h-4", strokeWidth: 2.5 })
|
|
202
|
+
}
|
|
203
|
+
)
|
|
204
|
+
] })
|
|
205
|
+
]
|
|
206
|
+
}
|
|
207
|
+
) }) })
|
|
208
|
+
}
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
function ThinkingBlock({ text }) {
|
|
212
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
213
|
+
const hasContent = typeof text === "string" && text.trim().length > 0;
|
|
214
|
+
if (!hasContent) return null;
|
|
215
|
+
return /* @__PURE__ */ jsxs("div", { className: "mt-1.5 mb-1.5", children: [
|
|
216
|
+
/* @__PURE__ */ jsxs(
|
|
217
|
+
"button",
|
|
218
|
+
{
|
|
219
|
+
type: "button",
|
|
220
|
+
onClick: () => setIsOpen((prev) => !prev),
|
|
221
|
+
className: "inline-flex items-center gap-1 text-[10px] text-muted-foreground/50 hover:text-muted-foreground/80 transition-colors",
|
|
222
|
+
"aria-expanded": isOpen,
|
|
223
|
+
"aria-label": isOpen ? "Collapse thought process" : "Expand thought process",
|
|
224
|
+
children: [
|
|
225
|
+
/* @__PURE__ */ jsx(
|
|
226
|
+
motion.div,
|
|
144
227
|
{
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
"aria-label": "Send message",
|
|
150
|
-
children: /* @__PURE__ */ jsx(Send, { className: "w-4 h-4" })
|
|
228
|
+
animate: { rotate: isOpen ? 180 : 0 },
|
|
229
|
+
transition: { duration: 0.15 },
|
|
230
|
+
className: "shrink-0",
|
|
231
|
+
children: /* @__PURE__ */ jsx(ChevronDown, { className: "h-3 w-3" })
|
|
151
232
|
}
|
|
152
|
-
)
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
233
|
+
),
|
|
234
|
+
/* @__PURE__ */ jsx("span", { children: "Thought process" })
|
|
235
|
+
]
|
|
236
|
+
}
|
|
237
|
+
),
|
|
238
|
+
/* @__PURE__ */ jsx(AnimatePresence, { initial: false, children: isOpen && /* @__PURE__ */ jsx(
|
|
239
|
+
motion.div,
|
|
240
|
+
{
|
|
241
|
+
initial: { height: 0, opacity: 0 },
|
|
242
|
+
animate: { height: "auto", opacity: 1 },
|
|
243
|
+
exit: { height: 0, opacity: 0 },
|
|
244
|
+
transition: { duration: 0.2, ease: "easeInOut" },
|
|
245
|
+
className: "overflow-hidden",
|
|
246
|
+
children: /* @__PURE__ */ jsx("div", { className: "mt-1 bg-muted/50 rounded-md p-2 overflow-y-auto overflow-x-hidden", children: /* @__PURE__ */ jsx("p", { className: "m-0 text-xs text-muted-foreground/70 whitespace-pre-wrap leading-relaxed", children: text }) })
|
|
247
|
+
}
|
|
248
|
+
) })
|
|
249
|
+
] });
|
|
157
250
|
}
|
|
251
|
+
var FRIENDLY_ERROR_MESSAGE = "Oops, something went wrong. Please try again.";
|
|
158
252
|
function AgentMessage({
|
|
159
253
|
message,
|
|
160
254
|
animated = false,
|
|
@@ -174,310 +268,364 @@ function AgentMessage({
|
|
|
174
268
|
const isError = message.isError ?? (message.streamProgress === "error" || !!message.errorDetails);
|
|
175
269
|
const isCancelled = message.isCancelled ?? false;
|
|
176
270
|
const currentExecutingStepId = message.currentExecutingStepId;
|
|
177
|
-
const [isStepsExpanded, setIsStepsExpanded] = useState(
|
|
271
|
+
const [isStepsExpanded, setIsStepsExpanded] = useState(false);
|
|
272
|
+
const wasStreamingRef = useRef(isStreaming);
|
|
178
273
|
useEffect(() => {
|
|
179
274
|
if (isStreaming && hasSteps) {
|
|
180
275
|
setIsStepsExpanded(true);
|
|
181
276
|
}
|
|
277
|
+
if (wasStreamingRef.current && !isStreaming) {
|
|
278
|
+
setIsStepsExpanded(false);
|
|
279
|
+
}
|
|
280
|
+
wasStreamingRef.current = isStreaming;
|
|
182
281
|
}, [isStreaming, hasSteps]);
|
|
183
282
|
const totalElapsedMs = hasSteps ? message.steps.reduce((sum, step) => sum + (step.elapsedMs || 0), 0) : 0;
|
|
184
283
|
const currentMessage = message.currentMessage;
|
|
185
284
|
const rawContent = message.streamingContent || message.content || "";
|
|
186
285
|
const content = rawContent.replace(/\\n/g, "\n");
|
|
187
|
-
const
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
286
|
+
const activeThinkingText = message.activeThinkingText;
|
|
287
|
+
const allThinkingText = message.allThinkingText;
|
|
288
|
+
const currentStep = useMemo(
|
|
289
|
+
() => message.steps?.find(
|
|
290
|
+
(s) => s.id === currentExecutingStepId && s.status === "in_progress"
|
|
291
|
+
),
|
|
292
|
+
[message.steps, currentExecutingStepId]
|
|
293
|
+
);
|
|
294
|
+
const getStepsLabel = (streaming) => {
|
|
295
|
+
const count = message.steps.length;
|
|
296
|
+
const stepWord = count === 1 ? "step" : "steps";
|
|
194
297
|
if (completedStepsText) {
|
|
195
|
-
|
|
196
|
-
return result;
|
|
298
|
+
return completedStepsText.replace("{count}", count.toString()).replace("{time}", (totalElapsedMs / 1e3).toFixed(1));
|
|
197
299
|
}
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
300
|
+
return `${count} ${stepWord} completed`;
|
|
301
|
+
};
|
|
302
|
+
const renderStepIcon = (step, isCurrentlyExecuting) => {
|
|
303
|
+
const wrapper = "h-4 w-4 flex items-center justify-center shrink-0";
|
|
304
|
+
if (isCurrentlyExecuting)
|
|
305
|
+
return /* @__PURE__ */ jsx("div", { className: wrapper, children: /* @__PURE__ */ jsx(Loader2, { className: "h-3.5 w-3.5 payman-agent-step-icon--active animate-spin" }) });
|
|
306
|
+
if (step.status === "pending" && isCancelled)
|
|
307
|
+
return /* @__PURE__ */ jsx("div", { className: wrapper, children: /* @__PURE__ */ jsx("div", { className: "h-1.5 w-1.5 rounded-full payman-agent-step-icon--pending" }) });
|
|
308
|
+
if (step.status === "pending" || step.status === "in_progress")
|
|
309
|
+
return /* @__PURE__ */ jsx("div", { className: wrapper, children: /* @__PURE__ */ jsx(Loader2, { className: "h-3.5 w-3.5 payman-agent-step-icon--in-progress-dim animate-spin" }) });
|
|
310
|
+
if (step.status === "completed")
|
|
311
|
+
return /* @__PURE__ */ jsx("div", { className: wrapper, children: /* @__PURE__ */ jsx(
|
|
312
|
+
Check,
|
|
313
|
+
{
|
|
314
|
+
className: cn(
|
|
315
|
+
"h-3.5 w-3.5",
|
|
316
|
+
step.eventType === "USER_ACTION_SUCCESS" ? "payman-agent-step-icon--success" : "payman-agent-step-icon--success-dim"
|
|
317
|
+
)
|
|
318
|
+
}
|
|
319
|
+
) });
|
|
320
|
+
if (step.status === "error")
|
|
321
|
+
return /* @__PURE__ */ jsx("div", { className: wrapper, children: /* @__PURE__ */ jsx(X, { className: "h-3.5 w-3.5 payman-agent-step-icon--error" }) });
|
|
322
|
+
return /* @__PURE__ */ jsx("div", { className: wrapper, children: /* @__PURE__ */ jsx("div", { className: "h-1.5 w-1.5 rounded-full payman-agent-step-icon--pending-dim" }) });
|
|
201
323
|
};
|
|
202
|
-
const
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
324
|
+
const stepsListContent = hasSteps && /* @__PURE__ */ jsx(AnimatePresence, { initial: false, children: isStepsExpanded && /* @__PURE__ */ jsxs(
|
|
325
|
+
motion.div,
|
|
326
|
+
{
|
|
327
|
+
initial: { height: 0, opacity: 0 },
|
|
328
|
+
animate: { height: "auto", opacity: 1 },
|
|
329
|
+
exit: { height: 0, opacity: 0 },
|
|
330
|
+
transition: { duration: 0.2, ease: "easeInOut" },
|
|
331
|
+
className: "overflow-hidden",
|
|
332
|
+
children: [
|
|
333
|
+
!isStreaming && allThinkingText?.trim() && /* @__PURE__ */ jsx(ThinkingBlock, { text: allThinkingText }),
|
|
334
|
+
/* @__PURE__ */ jsx("div", { className: "pt-1.5", children: message.steps.map((step) => {
|
|
335
|
+
const isCurrentlyExecuting = step.id === currentExecutingStepId && step.status === "in_progress" && isStreaming && !isCancelled;
|
|
336
|
+
const hasTime = step.elapsedMs != null && step.elapsedMs > 0;
|
|
337
|
+
return /* @__PURE__ */ jsxs("div", { className: "mb-1.5", children: [
|
|
338
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-1.5 items-start", children: [
|
|
339
|
+
/* @__PURE__ */ jsx("div", { className: "mt-px", children: renderStepIcon(step, isCurrentlyExecuting) }),
|
|
340
|
+
/* @__PURE__ */ jsx(
|
|
341
|
+
"span",
|
|
342
|
+
{
|
|
343
|
+
className: cn(
|
|
344
|
+
"text-xs leading-relaxed min-w-0 break-words",
|
|
345
|
+
isCurrentlyExecuting && "shimmer-text font-medium",
|
|
346
|
+
!isCurrentlyExecuting && step.status === "error" && "text-destructive payman-agent-step-text--error",
|
|
347
|
+
!isCurrentlyExecuting && step.eventType === "USER_ACTION_SUCCESS" && "text-emerald-600 payman-agent-step-text--success",
|
|
348
|
+
!isCurrentlyExecuting && step.status === "completed" && "text-muted-foreground payman-agent-step-text--completed",
|
|
349
|
+
!isCurrentlyExecuting && step.status === "pending" && "text-muted-foreground/40 payman-agent-step-text--pending",
|
|
350
|
+
!isCurrentlyExecuting && step.status === "in_progress" && "text-muted-foreground/60 payman-agent-step-text--in-progress"
|
|
351
|
+
),
|
|
352
|
+
children: step.message
|
|
353
|
+
}
|
|
354
|
+
)
|
|
355
|
+
] }),
|
|
356
|
+
hasTime && /* @__PURE__ */ jsx("div", { className: "pl-[22px] mt-1", children: /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 px-1.5 py-0.5 rounded-md bg-muted border border-border/40 leading-none payman-agent-step-time", children: [
|
|
357
|
+
/* @__PURE__ */ jsx(Clock, { className: "h-2.5 w-2.5 text-muted-foreground/60 shrink-0 payman-agent-step-time-icon" }),
|
|
358
|
+
/* @__PURE__ */ jsx("span", { className: "text-[10px] font-mono text-muted-foreground/60", children: formatElapsedTime(step.elapsedMs) })
|
|
359
|
+
] }) })
|
|
360
|
+
] }, step.id);
|
|
361
|
+
}) })
|
|
362
|
+
]
|
|
363
|
+
}
|
|
364
|
+
) });
|
|
365
|
+
const stepsToggleRef = useRef(null);
|
|
366
|
+
const handleStepsToggle = useCallback(() => {
|
|
367
|
+
setIsStepsExpanded((prev) => {
|
|
368
|
+
const next = !prev;
|
|
369
|
+
if (next) {
|
|
370
|
+
requestAnimationFrame(() => {
|
|
371
|
+
stepsToggleRef.current?.closest(".payman-scrollbar")?.dispatchEvent(new CustomEvent("payman-steps-toggle"));
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
return next;
|
|
375
|
+
});
|
|
376
|
+
}, []);
|
|
377
|
+
const stepsToggle = (streaming) => /* @__PURE__ */ jsxs(
|
|
378
|
+
"button",
|
|
379
|
+
{
|
|
380
|
+
ref: stepsToggleRef,
|
|
381
|
+
onClick: handleStepsToggle,
|
|
382
|
+
className: "inline-flex items-center gap-1.5 text-xs payman-agent-step-toggle transition-colors",
|
|
383
|
+
children: [
|
|
384
|
+
/* @__PURE__ */ jsx(
|
|
385
|
+
motion.div,
|
|
386
|
+
{
|
|
387
|
+
animate: { rotate: isStepsExpanded ? 90 : 0 },
|
|
388
|
+
transition: { duration: 0.15 },
|
|
389
|
+
className: "shrink-0",
|
|
390
|
+
children: /* @__PURE__ */ jsx(ChevronRight, { className: "h-3 w-3" })
|
|
391
|
+
}
|
|
392
|
+
),
|
|
393
|
+
/* @__PURE__ */ jsx("span", { children: getStepsLabel() })
|
|
394
|
+
]
|
|
395
|
+
}
|
|
396
|
+
);
|
|
397
|
+
const showSteps = showExecutionSteps && hasSteps && !isStreaming && !isError;
|
|
398
|
+
const messageContent = /* @__PURE__ */ jsxs("div", { className: "w-full", children: [
|
|
399
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-3 justify-start items-start w-full", children: [
|
|
400
|
+
showAvatar && /* @__PURE__ */ jsx("div", { className: "shrink-0 mt-0.5", children: isStreaming && showStreamingDot ? /* @__PURE__ */ jsx("div", { className: "h-8 w-8 flex items-center justify-center", children: /* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
401
|
+
/* @__PURE__ */ jsx("div", { className: "h-2.5 w-2.5 rounded-full payman-agent-avatar-dot animate-pulse" }),
|
|
402
|
+
/* @__PURE__ */ jsx("div", { className: "absolute inset-0 h-2.5 w-2.5 rounded-full payman-agent-avatar-dot-ping animate-ping" })
|
|
403
|
+
] }) }) : /* @__PURE__ */ jsx("div", { className: "h-8 w-8 rounded-full payman-agent-avatar flex items-center justify-center", children: /* @__PURE__ */ jsx(Sparkles, { className: "h-3.5 w-3.5 payman-agent-avatar-icon" }) }) }),
|
|
224
404
|
/* @__PURE__ */ jsxs(
|
|
225
405
|
"div",
|
|
226
406
|
{
|
|
227
407
|
className: cn(
|
|
228
|
-
"
|
|
229
|
-
layout === "centered" ?
|
|
230
|
-
"bg-white border transition-all duration-200 p-3",
|
|
231
|
-
hasSteps ? "rounded-t-2xl rounded-tl-sm border-b-0" : "rounded-2xl rounded-tl-sm",
|
|
232
|
-
message.isStreaming ? "border-neutral-300 shadow-sm" : "border-neutral-200",
|
|
233
|
-
isError && "border-red-200"
|
|
234
|
-
) : cn(
|
|
235
|
-
"p-3",
|
|
236
|
-
hasSteps && !isStreaming ? "rounded-t-md" : "rounded-md",
|
|
237
|
-
isError ? "bg-destructive/10 border border-destructive/30" : "bg-muted"
|
|
238
|
-
)
|
|
408
|
+
"min-w-0",
|
|
409
|
+
layout === "centered" ? "max-w-[85%]" : showAvatar ? "max-w-[85%]" : "max-w-[80%]"
|
|
239
410
|
),
|
|
240
411
|
children: [
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
// Without avatars (yaak): show spinner
|
|
244
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
245
|
-
/* @__PURE__ */ jsx(Loader2, { className: "w-4 h-4 text-primary animate-spin flex-shrink-0" }),
|
|
246
|
-
/* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground", children: currentMessage || /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center", children: [
|
|
247
|
-
"Thinking",
|
|
248
|
-
/* @__PURE__ */ jsxs("span", { className: "ml-1 inline-flex", children: [
|
|
249
|
-
/* @__PURE__ */ jsx("span", { className: "thinking-dot", children: "." }),
|
|
250
|
-
/* @__PURE__ */ jsx("span", { className: "thinking-dot", children: "." }),
|
|
251
|
-
/* @__PURE__ */ jsx("span", { className: "thinking-dot", children: "." })
|
|
252
|
-
] })
|
|
253
|
-
] }) })
|
|
254
|
-
] })
|
|
255
|
-
) : (
|
|
256
|
-
// With avatars (paygent-central): no spinner in message (dot avatar handles it)
|
|
257
|
-
/* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground", children: currentMessage || /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center", children: [
|
|
258
|
-
"Thinking",
|
|
259
|
-
/* @__PURE__ */ jsxs("span", { className: "ml-1 inline-flex", children: [
|
|
260
|
-
/* @__PURE__ */ jsx("span", { className: "thinking-dot", children: "." }),
|
|
261
|
-
/* @__PURE__ */ jsx("span", { className: "thinking-dot", children: "." }),
|
|
262
|
-
/* @__PURE__ */ jsx("span", { className: "thinking-dot", children: "." })
|
|
263
|
-
] })
|
|
264
|
-
] }) })
|
|
265
|
-
) : isCancelled && !content ? (
|
|
266
|
-
// Show cancelled state only when message is cancelled and has no content
|
|
267
|
-
!showAvatar ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
268
|
-
/* @__PURE__ */ jsx(X, { className: "w-4 h-4 text-muted-foreground flex-shrink-0" }),
|
|
269
|
-
/* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground", children: currentMessage || "The request was stopped." })
|
|
270
|
-
] }) : /* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground", children: currentMessage || "The request was stopped." })
|
|
271
|
-
) : /* @__PURE__ */ jsx("div", { className: cn(
|
|
272
|
-
"prose prose-sm dark:prose-invert max-w-none",
|
|
273
|
-
isError && "text-destructive"
|
|
274
|
-
), children: /* @__PURE__ */ jsx(
|
|
275
|
-
ReactMarkdown,
|
|
412
|
+
message.userActionResult && /* @__PURE__ */ jsx("div", { className: "mb-2", children: message.userActionResult === "approved" ? /* @__PURE__ */ jsxs(
|
|
413
|
+
"span",
|
|
276
414
|
{
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
return isInline ? /* @__PURE__ */ jsx("code", { className: cn("px-1.5 py-0.5 rounded text-xs font-mono break-all", isError ? "bg-destructive/10 text-destructive" : "bg-muted"), children }) : /* @__PURE__ */ jsx("code", { className: cn("block p-3 rounded text-xs font-mono overflow-x-auto my-2 whitespace-pre", isError ? "bg-destructive/10 text-destructive" : "bg-muted"), children });
|
|
283
|
-
},
|
|
284
|
-
pre: ({ children }) => /* @__PURE__ */ jsx("pre", { className: cn("my-2 overflow-x-auto max-w-full", isError && "bg-destructive/10"), children }),
|
|
285
|
-
ul: ({ children }) => /* @__PURE__ */ jsx("ul", { className: cn("list-disc ml-4 mb-3 space-y-1 text-sm", isError && "text-destructive"), children }),
|
|
286
|
-
ol: ({ children }) => /* @__PURE__ */ jsx("ol", { className: cn("list-decimal ml-4 mb-3 space-y-1 text-sm", isError && "text-destructive"), children }),
|
|
287
|
-
li: ({ children }) => /* @__PURE__ */ jsx("li", { className: cn("text-sm leading-relaxed", isError ? "text-destructive" : "text-foreground"), children }),
|
|
288
|
-
h1: ({ children }) => /* @__PURE__ */ jsx("h1", { className: cn("text-lg font-semibold mb-2 mt-4 first:mt-0", isError ? "text-destructive" : "text-foreground"), children }),
|
|
289
|
-
h2: ({ children }) => /* @__PURE__ */ jsx("h2", { className: cn("text-base font-semibold mb-2 mt-3 first:mt-0", isError ? "text-destructive" : "text-foreground"), children }),
|
|
290
|
-
h3: ({ children }) => /* @__PURE__ */ jsx("h3", { className: cn("text-sm font-semibold mb-1 mt-2 first:mt-0", isError ? "text-destructive" : "text-foreground"), children }),
|
|
291
|
-
strong: ({ children }) => /* @__PURE__ */ jsx("strong", { className: cn("font-semibold", isError ? "text-destructive" : "text-foreground"), children }),
|
|
292
|
-
em: ({ children }) => /* @__PURE__ */ jsx("em", { className: cn("italic", isError ? "text-destructive" : "text-foreground"), children }),
|
|
293
|
-
blockquote: ({ children }) => /* @__PURE__ */ jsx("blockquote", { className: "border-l-4 border-border pl-4 my-2 italic text-muted-foreground", children }),
|
|
294
|
-
hr: () => /* @__PURE__ */ jsx("hr", { className: "my-4 border-border" }),
|
|
295
|
-
a: ({ href, children }) => /* @__PURE__ */ jsx(
|
|
296
|
-
"a",
|
|
297
|
-
{
|
|
298
|
-
href,
|
|
299
|
-
target: "_blank",
|
|
300
|
-
rel: "noopener noreferrer",
|
|
301
|
-
className: cn("underline underline-offset-2", isError ? "text-destructive hover:text-destructive/80" : "text-primary hover:text-primary/80"),
|
|
302
|
-
children
|
|
303
|
-
}
|
|
304
|
-
),
|
|
305
|
-
table: ({ children }) => /* @__PURE__ */ jsx("div", { className: "relative w-full overflow-x-auto my-4 -mx-1", children: /* @__PURE__ */ jsx("table", { className: "min-w-full caption-bottom text-sm border border-border rounded-md", children }) }),
|
|
306
|
-
thead: ({ children }) => /* @__PURE__ */ jsx("thead", { className: "[&_tr]:border-b bg-muted/50", children }),
|
|
307
|
-
tbody: ({ children }) => /* @__PURE__ */ jsx("tbody", { className: "[&_tr:last-child]:border-0", children }),
|
|
308
|
-
tr: ({ children }) => /* @__PURE__ */ jsx("tr", { className: "hover:bg-muted/50 border-b transition-colors", children }),
|
|
309
|
-
th: ({ children }) => /* @__PURE__ */ jsx("th", { className: "text-foreground h-10 px-2 text-left align-middle font-medium whitespace-nowrap", children }),
|
|
310
|
-
td: ({ children }) => /* @__PURE__ */ jsx("td", { className: "p-2 align-middle text-foreground", children })
|
|
415
|
+
className: "inline-flex items-center gap-1.5 px-4 py-1.5 text-xs font-semibold rounded-full payman-agent-approved shrink-0",
|
|
416
|
+
style: {
|
|
417
|
+
background: "var(--payman-agent-approved-bg, var(--payman-success-light, #ecfdf5))",
|
|
418
|
+
color: "var(--payman-agent-approved-text, var(--payman-success-dark, #047857))",
|
|
419
|
+
border: "1px solid var(--payman-agent-approved-border, var(--payman-success, #059669))"
|
|
311
420
|
},
|
|
312
|
-
children:
|
|
421
|
+
children: [
|
|
422
|
+
/* @__PURE__ */ jsx(Check, { className: "w-3.5 h-3.5 shrink-0", strokeWidth: 2.5 }),
|
|
423
|
+
"Verified"
|
|
424
|
+
]
|
|
313
425
|
}
|
|
314
|
-
)
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2 text-xs", children: [
|
|
347
|
-
isCurrentlyExecuting && /* @__PURE__ */ jsx(Loader2, { className: "h-3 w-3 text-primary animate-spin shrink-0 mt-0.5" }),
|
|
348
|
-
step.status === "pending" && isCancelled && /* @__PURE__ */ jsx(XCircle, { className: "h-3 w-3 text-muted-foreground shrink-0 mt-0.5" }),
|
|
349
|
-
step.status === "pending" && !isCancelled && /* @__PURE__ */ jsx(Loader2, { className: "h-3 w-3 text-primary animate-spin shrink-0 mt-0.5" }),
|
|
350
|
-
step.status === "in_progress" && !isCurrentlyExecuting && /* @__PURE__ */ jsx(Loader2, { className: "h-3 w-3 text-primary animate-spin shrink-0 mt-0.5" }),
|
|
351
|
-
step.status === "completed" && /* @__PURE__ */ jsx(Check, { className: cn("h-3 w-3 shrink-0 mt-0.5", step.eventType === "USER_ACTION_SUCCESS" ? "text-green-600" : "text-primary") }),
|
|
352
|
-
step.status === "error" && /* @__PURE__ */ jsx(X, { className: "h-3 w-3 text-destructive shrink-0 mt-0.5" }),
|
|
353
|
-
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
354
|
-
/* @__PURE__ */ jsx(
|
|
355
|
-
"span",
|
|
426
|
+
) : /* @__PURE__ */ jsxs(
|
|
427
|
+
"span",
|
|
428
|
+
{
|
|
429
|
+
className: "inline-flex items-center gap-1.5 px-4 py-1.5 text-xs font-semibold rounded-full payman-agent-rejected shrink-0",
|
|
430
|
+
style: {
|
|
431
|
+
background: "var(--payman-agent-rejected-bg, var(--payman-error-light, #fef2f2))",
|
|
432
|
+
color: "var(--payman-agent-rejected-text, var(--payman-error-dark, #b91c1c))",
|
|
433
|
+
border: "1px solid var(--payman-agent-rejected-border, var(--payman-destructive, #dc2626))"
|
|
434
|
+
},
|
|
435
|
+
children: [
|
|
436
|
+
/* @__PURE__ */ jsx(X, { className: "w-3.5 h-3.5 shrink-0", strokeWidth: 2.5 }),
|
|
437
|
+
"Rejected"
|
|
438
|
+
]
|
|
439
|
+
}
|
|
440
|
+
) }),
|
|
441
|
+
/* @__PURE__ */ jsxs(
|
|
442
|
+
"div",
|
|
443
|
+
{
|
|
444
|
+
className: cn(
|
|
445
|
+
"overflow-hidden w-full min-w-0 px-4 py-3 rounded-2xl rounded-tl-md transition-all duration-200",
|
|
446
|
+
layout === "centered" ? cn(
|
|
447
|
+
"payman-agent-bubble payman-agent-bubble--centered border shadow-sm",
|
|
448
|
+
isStreaming && "streaming",
|
|
449
|
+
isError && "error"
|
|
450
|
+
) : cn(
|
|
451
|
+
"payman-agent-bubble",
|
|
452
|
+
isError && "payman-agent-bubble--error"
|
|
453
|
+
)
|
|
454
|
+
),
|
|
455
|
+
children: [
|
|
456
|
+
showAgentName && /* @__PURE__ */ jsx(
|
|
457
|
+
"p",
|
|
356
458
|
{
|
|
357
459
|
className: cn(
|
|
358
|
-
"text-muted-foreground
|
|
359
|
-
|
|
360
|
-
step.eventType === "USER_ACTION_SUCCESS" && "text-green-600"
|
|
460
|
+
"text-sm font-semibold mb-1 leading-none text-muted-foreground/70 payman-agent-name",
|
|
461
|
+
isStreaming && !content && "animate-pulse"
|
|
361
462
|
),
|
|
362
|
-
children:
|
|
463
|
+
children: isStreaming && !content ? "Thought Process" : agentName
|
|
363
464
|
}
|
|
364
465
|
),
|
|
365
|
-
step.elapsedMs && /* @__PURE__ */ jsxs("span", { className: "ml-1.5 text-[10px] opacity-50", children: [
|
|
366
|
-
"(",
|
|
367
|
-
(step.elapsedMs / 1e3).toFixed(1),
|
|
368
|
-
"s)"
|
|
369
|
-
] })
|
|
370
|
-
] })
|
|
371
|
-
] }, step.id);
|
|
372
|
-
})
|
|
373
|
-
}
|
|
374
|
-
) })
|
|
375
|
-
] }),
|
|
376
|
-
hasSteps && isStreaming && /* @__PURE__ */ jsxs("div", { className: cn(
|
|
377
|
-
"overflow-hidden",
|
|
378
|
-
layout === "centered" ? "bg-white border border-t-0 border-neutral-300 rounded-b-2xl" : "bg-muted border-t border-border/30 rounded-b-md"
|
|
379
|
-
), children: [
|
|
380
|
-
/* @__PURE__ */ jsxs(
|
|
381
|
-
"button",
|
|
382
|
-
{
|
|
383
|
-
onClick: () => setIsStepsExpanded(!isStepsExpanded),
|
|
384
|
-
className: cn(
|
|
385
|
-
"w-full px-4 py-2 flex items-center justify-between text-xs transition-colors",
|
|
386
|
-
layout === "centered" ? "text-neutral-500 hover:bg-neutral-50" : "text-muted-foreground hover:bg-muted/70"
|
|
387
|
-
),
|
|
388
|
-
children: [
|
|
389
|
-
/* @__PURE__ */ jsx("span", { children: getStreamingStepsText(!!isStepsExpanded) }),
|
|
390
|
-
isStepsExpanded ? /* @__PURE__ */ jsx(ChevronUp, { className: "h-3 w-3" }) : /* @__PURE__ */ jsx(ChevronDown, { className: "h-3 w-3" })
|
|
391
|
-
]
|
|
392
|
-
}
|
|
393
|
-
),
|
|
394
|
-
isStepsExpanded && /* @__PURE__ */ jsx(AnimatePresence, { children: /* @__PURE__ */ jsx(
|
|
395
|
-
motion.div,
|
|
396
|
-
{
|
|
397
|
-
initial: { height: 0, opacity: 0 },
|
|
398
|
-
animate: { height: "auto", opacity: 1 },
|
|
399
|
-
exit: { height: 0, opacity: 0 },
|
|
400
|
-
transition: { duration: 0.2 },
|
|
401
|
-
className: "px-4 pb-3 pt-2 space-y-2 bg-background/30",
|
|
402
|
-
children: message.steps.map((step) => {
|
|
403
|
-
const isCurrentlyExecuting = step.id === currentExecutingStepId && step.status === "in_progress" && isStreaming && !isCancelled;
|
|
404
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2 text-xs", children: [
|
|
405
|
-
isCurrentlyExecuting && /* @__PURE__ */ jsx(Loader2, { className: "h-3 w-3 text-primary animate-spin shrink-0 mt-0.5" }),
|
|
406
|
-
step.status === "pending" && isCancelled && /* @__PURE__ */ jsx(XCircle, { className: "h-3 w-3 text-muted-foreground shrink-0 mt-0.5" }),
|
|
407
|
-
step.status === "pending" && !isCancelled && /* @__PURE__ */ jsx(Loader2, { className: "h-3 w-3 text-primary animate-spin shrink-0 mt-0.5" }),
|
|
408
|
-
step.status === "in_progress" && !isCurrentlyExecuting && /* @__PURE__ */ jsx(Loader2, { className: "h-3 w-3 text-primary animate-spin shrink-0 mt-0.5" }),
|
|
409
|
-
step.status === "completed" && /* @__PURE__ */ jsx(Check, { className: cn("h-3 w-3 shrink-0 mt-0.5", step.eventType === "USER_ACTION_SUCCESS" ? "text-green-600" : "text-primary") }),
|
|
410
|
-
step.status === "error" && /* @__PURE__ */ jsx(X, { className: "h-3 w-3 text-destructive shrink-0 mt-0.5" }),
|
|
411
|
-
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
412
466
|
/* @__PURE__ */ jsx(
|
|
413
|
-
"
|
|
467
|
+
"div",
|
|
414
468
|
{
|
|
415
469
|
className: cn(
|
|
416
|
-
"text-
|
|
417
|
-
|
|
418
|
-
step.eventType === "USER_ACTION_SUCCESS" && "text-green-600"
|
|
470
|
+
"text-sm leading-relaxed min-w-0 w-full break-words overflow-wrap-anywhere",
|
|
471
|
+
showAgentName && "mt-1"
|
|
419
472
|
),
|
|
420
|
-
children:
|
|
473
|
+
children: isStreaming && !content ? (
|
|
474
|
+
// One active item at a time, by event order: thinking stream OR current step with loading (same bullet UI as dropdown)
|
|
475
|
+
activeThinkingText ? /* @__PURE__ */ jsxs("div", { className: "flex gap-1.5 items-start", children: [
|
|
476
|
+
/* @__PURE__ */ jsx("div", { className: "mt-px", children: /* @__PURE__ */ jsx("div", { className: "h-4 w-4 flex items-center justify-center shrink-0", children: /* @__PURE__ */ jsx(Loader2, { className: "h-3.5 w-3.5 text-primary animate-spin payman-agent-thinking-spinner" }) }) }),
|
|
477
|
+
/* @__PURE__ */ jsxs("span", { className: "text-sm leading-relaxed min-w-0 break-words text-muted-foreground whitespace-pre-wrap flex-1 payman-agent-thinking-text", children: [
|
|
478
|
+
activeThinkingText,
|
|
479
|
+
/* @__PURE__ */ jsx("span", { className: "inline-block w-0.5 h-3.5 bg-muted-foreground/50 animate-pulse ml-0.5 align-text-bottom" })
|
|
480
|
+
] })
|
|
481
|
+
] }) : currentStep ? /* @__PURE__ */ jsxs("div", { className: "flex gap-1.5 items-start", children: [
|
|
482
|
+
/* @__PURE__ */ jsx("div", { className: "mt-px", children: renderStepIcon(currentStep, true) }),
|
|
483
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm leading-relaxed min-w-0 break-words shimmer-text font-medium", children: currentStep.message })
|
|
484
|
+
] }) : /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2.5", children: [
|
|
485
|
+
!showAvatar && /* @__PURE__ */ jsx(Loader2, { className: "w-4 h-4 text-primary/70 animate-spin flex-shrink-0 payman-agent-thinking-spinner" }),
|
|
486
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground whitespace-nowrap payman-agent-thinking-text", children: currentMessage || "Thinking..." })
|
|
487
|
+
] })
|
|
488
|
+
) : isCancelled && !content ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2.5", children: [
|
|
489
|
+
/* @__PURE__ */ jsx(X, { className: "w-4 h-4 payman-agent-cancelled-icon flex-shrink-0" }),
|
|
490
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm payman-agent-cancelled-text italic", children: currentMessage || "Request was stopped." })
|
|
491
|
+
] }) : /* @__PURE__ */ jsx(
|
|
492
|
+
"div",
|
|
493
|
+
{
|
|
494
|
+
className: cn(
|
|
495
|
+
"payman-markdown payman-agent-markdown prose prose-sm dark:prose-invert max-w-none min-w-0 w-full break-words overflow-wrap-anywhere",
|
|
496
|
+
isError && "payman-agent-markdown--error",
|
|
497
|
+
isStreaming && content && "streaming-cursor"
|
|
498
|
+
),
|
|
499
|
+
children: /* @__PURE__ */ jsx(
|
|
500
|
+
ReactMarkdown,
|
|
501
|
+
{
|
|
502
|
+
remarkPlugins: [remarkGfm],
|
|
503
|
+
components: markdownComponents(),
|
|
504
|
+
children: isError ? FRIENDLY_ERROR_MESSAGE : content || (isStreaming ? "Thinking..." : isCancelled ? "Request was stopped." : "")
|
|
505
|
+
}
|
|
506
|
+
)
|
|
507
|
+
}
|
|
508
|
+
)
|
|
421
509
|
}
|
|
422
|
-
)
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
510
|
+
)
|
|
511
|
+
]
|
|
512
|
+
}
|
|
513
|
+
)
|
|
514
|
+
]
|
|
515
|
+
}
|
|
516
|
+
),
|
|
517
|
+
hasTraceData && onExecutionTraceClick && /* @__PURE__ */ jsx(
|
|
518
|
+
"button",
|
|
519
|
+
{
|
|
520
|
+
onClick: () => onExecutionTraceClick({
|
|
521
|
+
message,
|
|
522
|
+
tracingData: message.tracingData,
|
|
523
|
+
executionId: message.executionId
|
|
524
|
+
}),
|
|
525
|
+
className: cn(
|
|
526
|
+
"p-2 rounded-lg shrink-0 payman-agent-trace",
|
|
527
|
+
"active:scale-95 transition-all duration-150",
|
|
528
|
+
message.userActionResult ? "mt-8" : "mt-0.5"
|
|
529
|
+
),
|
|
530
|
+
title: "View execution trace",
|
|
531
|
+
"aria-label": "View execution trace",
|
|
532
|
+
children: /* @__PURE__ */ jsx(Binoculars, { className: "w-4 h-4 payman-agent-trace-icon" })
|
|
533
|
+
}
|
|
534
|
+
)
|
|
434
535
|
] }),
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
message,
|
|
440
|
-
tracingData: message.tracingData,
|
|
441
|
-
executionId: message.executionId
|
|
442
|
-
}),
|
|
443
|
-
className: cn(
|
|
444
|
-
"p-2 bg-white/5 border border-white/20 rounded-lg shadow-sm hover:bg-white/10 hover:border-highlight transition-colors duration-200 flex-shrink-0",
|
|
445
|
-
message.userActionResult ? "mt-8" : "mt-0.5"
|
|
446
|
-
),
|
|
447
|
-
title: "View execution trace",
|
|
448
|
-
"aria-label": "View execution trace",
|
|
449
|
-
children: /* @__PURE__ */ jsx(Binoculars, { className: "w-4 h-4 text-foreground" })
|
|
450
|
-
}
|
|
451
|
-
)
|
|
536
|
+
showSteps && /* @__PURE__ */ jsxs("div", { className: cn("mt-1.5", showAvatar ? "ml-11" : "ml-0"), children: [
|
|
537
|
+
showExecutionSteps && hasSteps && !isStreaming && !isError && stepsToggle(),
|
|
538
|
+
stepsListContent
|
|
539
|
+
] })
|
|
452
540
|
] });
|
|
453
541
|
if (animated) {
|
|
454
542
|
return /* @__PURE__ */ jsx(
|
|
455
543
|
motion.div,
|
|
456
544
|
{
|
|
457
|
-
initial: { opacity: 0, y:
|
|
458
|
-
animate: { opacity: 1, y: 0 },
|
|
459
|
-
transition: { duration: 0.
|
|
545
|
+
initial: { opacity: 0, y: 8, scale: 0.98 },
|
|
546
|
+
animate: { opacity: 1, y: 0, scale: 1 },
|
|
547
|
+
transition: { duration: 0.25, ease: [0.25, 0.46, 0.45, 0.94] },
|
|
460
548
|
children: messageContent
|
|
461
549
|
}
|
|
462
550
|
);
|
|
463
551
|
}
|
|
464
552
|
return messageContent;
|
|
465
553
|
}
|
|
466
|
-
function
|
|
467
|
-
|
|
468
|
-
/* @__PURE__ */
|
|
469
|
-
|
|
470
|
-
|
|
554
|
+
function markdownComponents(_isError) {
|
|
555
|
+
return {
|
|
556
|
+
p: ({ children }) => /* @__PURE__ */ jsx("p", { className: "mb-3 last:mb-0 text-sm leading-relaxed", children }),
|
|
557
|
+
code: ({ className: codeClassName, children }) => {
|
|
558
|
+
const isInline = !codeClassName;
|
|
559
|
+
return isInline ? /* @__PURE__ */ jsx("code", { className: "px-1.5 py-0.5 rounded-md text-xs font-mono break-all", children }) : /* @__PURE__ */ jsx("code", { className: "block p-3 rounded-lg text-xs font-mono overflow-x-auto my-2 whitespace-pre", children });
|
|
560
|
+
},
|
|
561
|
+
pre: ({ children }) => /* @__PURE__ */ jsx("pre", { className: "my-2 overflow-x-auto max-w-full rounded-lg", children }),
|
|
562
|
+
ul: ({ children }) => /* @__PURE__ */ jsx("ul", { className: "list-disc ml-4 mb-3 space-y-1 text-sm", children }),
|
|
563
|
+
ol: ({ children }) => /* @__PURE__ */ jsx("ol", { className: "list-decimal ml-4 mb-3 space-y-1 text-sm", children }),
|
|
564
|
+
li: ({ children }) => /* @__PURE__ */ jsx("li", { className: "text-sm leading-relaxed", children }),
|
|
565
|
+
h1: ({ children }) => /* @__PURE__ */ jsx("h1", { className: "text-lg font-semibold mb-2 mt-4 first:mt-0", children }),
|
|
566
|
+
h2: ({ children }) => /* @__PURE__ */ jsx("h2", { className: "text-base font-semibold mb-2 mt-3 first:mt-0", children }),
|
|
567
|
+
h3: ({ children }) => /* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold mb-1 mt-2 first:mt-0", children }),
|
|
568
|
+
strong: ({ children }) => /* @__PURE__ */ jsx("strong", { className: "font-semibold", children }),
|
|
569
|
+
em: ({ children }) => /* @__PURE__ */ jsx("em", { className: "italic", children }),
|
|
570
|
+
blockquote: ({ children }) => /* @__PURE__ */ jsx("blockquote", { className: "pl-4 my-2 italic", children }),
|
|
571
|
+
hr: () => /* @__PURE__ */ jsx("hr", { className: "my-4" }),
|
|
572
|
+
a: ({ href, children }) => /* @__PURE__ */ jsx(
|
|
573
|
+
"a",
|
|
574
|
+
{
|
|
575
|
+
href,
|
|
576
|
+
target: "_blank",
|
|
577
|
+
rel: "noopener noreferrer",
|
|
578
|
+
className: "underline underline-offset-2 decoration-1",
|
|
579
|
+
children
|
|
580
|
+
}
|
|
581
|
+
),
|
|
582
|
+
table: ({ children }) => /* @__PURE__ */ jsx("div", { className: "relative w-full overflow-x-auto my-4 -mx-1", children: /* @__PURE__ */ jsx("table", { className: "min-w-full caption-bottom text-sm border rounded-lg overflow-hidden", children }) }),
|
|
583
|
+
thead: ({ children }) => /* @__PURE__ */ jsx("thead", { className: "[&_tr]:border-b", children }),
|
|
584
|
+
tbody: ({ children }) => /* @__PURE__ */ jsx("tbody", { className: "[&_tr:last-child]:border-0", children }),
|
|
585
|
+
tr: ({ children }) => /* @__PURE__ */ jsx("tr", { className: "border-b transition-colors", children }),
|
|
586
|
+
th: ({ children }) => /* @__PURE__ */ jsx("th", { className: "h-10 px-3 text-left align-middle font-medium whitespace-nowrap text-xs", children }),
|
|
587
|
+
td: ({ children }) => /* @__PURE__ */ jsx("td", { className: "p-3 align-middle text-sm", children })
|
|
588
|
+
};
|
|
589
|
+
}
|
|
590
|
+
function UserMessage({
|
|
591
|
+
message,
|
|
592
|
+
animated = false,
|
|
593
|
+
showAvatar = false
|
|
594
|
+
}) {
|
|
595
|
+
const content = /* @__PURE__ */ jsxs("div", { className: "flex gap-3 justify-end w-full", children: [
|
|
596
|
+
/* @__PURE__ */ jsxs("div", { className: "max-w-[80%] min-w-0 flex flex-col items-end", children: [
|
|
597
|
+
/* @__PURE__ */ jsx(
|
|
598
|
+
"div",
|
|
599
|
+
{
|
|
600
|
+
className: cn(
|
|
601
|
+
"rounded-2xl rounded-br-md px-4 py-3",
|
|
602
|
+
"bg-primary text-primary-foreground",
|
|
603
|
+
"shadow-sm"
|
|
604
|
+
),
|
|
605
|
+
children: /* @__PURE__ */ jsx("p", { className: "text-sm leading-relaxed whitespace-pre-wrap break-words", children: message.content })
|
|
606
|
+
}
|
|
607
|
+
),
|
|
608
|
+
/* @__PURE__ */ jsx("span", { className: "text-[10px] mt-1.5 mr-1 text-muted-foreground/70 select-none", children: formatDate(message.timestamp) })
|
|
471
609
|
] }),
|
|
472
|
-
showAvatar && /* @__PURE__ */ jsx("div", { className: "
|
|
610
|
+
showAvatar && /* @__PURE__ */ jsx("div", { className: "shrink-0 mt-0.5", children: /* @__PURE__ */ jsx(
|
|
611
|
+
"div",
|
|
612
|
+
{
|
|
613
|
+
className: cn(
|
|
614
|
+
"h-8 w-8 rounded-full",
|
|
615
|
+
"bg-primary/10 border border-primary/20",
|
|
616
|
+
"flex items-center justify-center"
|
|
617
|
+
),
|
|
618
|
+
children: /* @__PURE__ */ jsx(User, { className: "h-3.5 w-3.5 text-primary" })
|
|
619
|
+
}
|
|
620
|
+
) })
|
|
473
621
|
] });
|
|
474
622
|
if (animated) {
|
|
475
623
|
return /* @__PURE__ */ jsx(
|
|
476
624
|
motion.div,
|
|
477
625
|
{
|
|
478
|
-
initial: { opacity: 0, y:
|
|
479
|
-
animate: { opacity: 1, y: 0 },
|
|
480
|
-
transition: { duration: 0.
|
|
626
|
+
initial: { opacity: 0, y: 8, scale: 0.98 },
|
|
627
|
+
animate: { opacity: 1, y: 0, scale: 1 },
|
|
628
|
+
transition: { duration: 0.25, ease: [0.25, 0.46, 0.45, 0.94] },
|
|
481
629
|
children: content
|
|
482
630
|
}
|
|
483
631
|
);
|
|
@@ -489,7 +637,7 @@ function MessageRow({
|
|
|
489
637
|
stage = "DEV",
|
|
490
638
|
animated = false,
|
|
491
639
|
showAgentName = false,
|
|
492
|
-
agentName = "
|
|
640
|
+
agentName = "Assistant",
|
|
493
641
|
showAvatars = false,
|
|
494
642
|
showUserAvatar,
|
|
495
643
|
showAssistantAvatar,
|
|
@@ -504,7 +652,14 @@ function MessageRow({
|
|
|
504
652
|
const actualShowUserAvatar = showUserAvatar !== void 0 ? showUserAvatar : showAvatars;
|
|
505
653
|
const actualShowAssistantAvatar = showAssistantAvatar !== void 0 ? showAssistantAvatar : showAvatars;
|
|
506
654
|
if (message.role === "user") {
|
|
507
|
-
return /* @__PURE__ */ jsx(
|
|
655
|
+
return /* @__PURE__ */ jsx(
|
|
656
|
+
UserMessage,
|
|
657
|
+
{
|
|
658
|
+
message,
|
|
659
|
+
animated,
|
|
660
|
+
showAvatar: actualShowUserAvatar
|
|
661
|
+
}
|
|
662
|
+
);
|
|
508
663
|
}
|
|
509
664
|
return /* @__PURE__ */ jsx(
|
|
510
665
|
AgentMessage,
|
|
@@ -531,30 +686,58 @@ function MessageRowSkeleton({
|
|
|
531
686
|
return /* @__PURE__ */ jsx(
|
|
532
687
|
"div",
|
|
533
688
|
{
|
|
534
|
-
className:
|
|
689
|
+
className: cn(
|
|
690
|
+
"flex w-full",
|
|
691
|
+
isRightAligned ? "justify-end" : "justify-start"
|
|
692
|
+
),
|
|
535
693
|
children: /* @__PURE__ */ jsxs(
|
|
536
694
|
"div",
|
|
537
695
|
{
|
|
538
|
-
className:
|
|
696
|
+
className: cn(
|
|
697
|
+
"flex flex-col gap-2 w-full",
|
|
698
|
+
isRightAligned ? "items-end max-w-[70%]" : "items-start max-w-[80%]"
|
|
699
|
+
),
|
|
539
700
|
children: [
|
|
540
701
|
/* @__PURE__ */ jsx(
|
|
541
702
|
"div",
|
|
542
703
|
{
|
|
543
|
-
className:
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
704
|
+
className: cn(
|
|
705
|
+
"rounded-2xl p-4 w-full",
|
|
706
|
+
isRightAligned ? "bg-primary/8 rounded-br-md" : "bg-muted/70 rounded-bl-md"
|
|
707
|
+
),
|
|
708
|
+
children: /* @__PURE__ */ jsxs("div", { className: "space-y-2.5", children: [
|
|
709
|
+
/* @__PURE__ */ jsx("div", { className: "h-3 skeleton-pulse rounded-full bg-muted-foreground/10 w-[85%]" }),
|
|
710
|
+
/* @__PURE__ */ jsx(
|
|
711
|
+
"div",
|
|
712
|
+
{
|
|
713
|
+
className: "h-3 skeleton-pulse rounded-full bg-muted-foreground/10 w-full",
|
|
714
|
+
style: { animationDelay: "0.1s" }
|
|
715
|
+
}
|
|
716
|
+
),
|
|
717
|
+
!isRightAligned && /* @__PURE__ */ jsx(
|
|
718
|
+
"div",
|
|
719
|
+
{
|
|
720
|
+
className: "h-3 skeleton-pulse rounded-full bg-muted-foreground/10 w-[60%]",
|
|
721
|
+
style: { animationDelay: "0.2s" }
|
|
722
|
+
}
|
|
723
|
+
)
|
|
548
724
|
] })
|
|
549
725
|
}
|
|
550
726
|
),
|
|
551
|
-
/* @__PURE__ */ jsx(
|
|
727
|
+
/* @__PURE__ */ jsx(
|
|
728
|
+
"div",
|
|
729
|
+
{
|
|
730
|
+
className: "h-2 skeleton-pulse rounded-full bg-muted-foreground/8 w-12 mx-1",
|
|
731
|
+
style: { animationDelay: "0.3s" }
|
|
732
|
+
}
|
|
733
|
+
)
|
|
552
734
|
]
|
|
553
735
|
}
|
|
554
736
|
)
|
|
555
737
|
}
|
|
556
738
|
);
|
|
557
739
|
}
|
|
740
|
+
var SCROLL_THRESHOLD = 150;
|
|
558
741
|
function MessageList({
|
|
559
742
|
messages,
|
|
560
743
|
isLoading = false,
|
|
@@ -565,7 +748,7 @@ function MessageList({
|
|
|
565
748
|
stage = "DEV",
|
|
566
749
|
animated = false,
|
|
567
750
|
showAgentName = false,
|
|
568
|
-
agentName = "
|
|
751
|
+
agentName = "Assistant",
|
|
569
752
|
showAvatars = false,
|
|
570
753
|
showUserAvatar,
|
|
571
754
|
showAssistantAvatar,
|
|
@@ -576,106 +759,204 @@ function MessageList({
|
|
|
576
759
|
onExecutionTraceClick,
|
|
577
760
|
className
|
|
578
761
|
}) {
|
|
579
|
-
const
|
|
580
|
-
const
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
762
|
+
const scrollRef = useRef(null);
|
|
763
|
+
const isNearBottomRef = useRef(true);
|
|
764
|
+
const [showScrollBtn, setShowScrollBtn] = useState(false);
|
|
765
|
+
const prevMessageCountRef = useRef(messages.length);
|
|
766
|
+
const getDistanceFromBottom = useCallback(() => {
|
|
767
|
+
const el = scrollRef.current;
|
|
768
|
+
if (!el) return 0;
|
|
769
|
+
return el.scrollHeight - el.scrollTop - el.clientHeight;
|
|
770
|
+
}, []);
|
|
771
|
+
const scrollToBottom = useCallback((behavior = "smooth") => {
|
|
772
|
+
const el = scrollRef.current;
|
|
773
|
+
if (!el) return;
|
|
774
|
+
el.scrollTo({ top: el.scrollHeight, behavior });
|
|
775
|
+
}, []);
|
|
776
|
+
const handleScroll = useCallback(() => {
|
|
777
|
+
const distance = getDistanceFromBottom();
|
|
778
|
+
const nearBottom = distance <= SCROLL_THRESHOLD;
|
|
779
|
+
isNearBottomRef.current = nearBottom;
|
|
780
|
+
setShowScrollBtn(!nearBottom);
|
|
781
|
+
}, [getDistanceFromBottom]);
|
|
782
|
+
useEffect(() => {
|
|
783
|
+
const prevCount = prevMessageCountRef.current;
|
|
784
|
+
prevMessageCountRef.current = messages.length;
|
|
785
|
+
if (messages.length > prevCount && isNearBottomRef.current) {
|
|
786
|
+
requestAnimationFrame(() => scrollToBottom());
|
|
787
|
+
}
|
|
788
|
+
}, [messages.length, scrollToBottom]);
|
|
789
|
+
useEffect(() => {
|
|
790
|
+
const lastMsg = messages[messages.length - 1];
|
|
791
|
+
if (!lastMsg?.isStreaming) return;
|
|
792
|
+
if (!isNearBottomRef.current) return;
|
|
793
|
+
requestAnimationFrame(() => scrollToBottom());
|
|
794
|
+
});
|
|
795
|
+
useEffect(() => {
|
|
796
|
+
if (messages.length > 0) {
|
|
797
|
+
setTimeout(() => scrollToBottom("instant"), 50);
|
|
584
798
|
}
|
|
585
799
|
}, []);
|
|
586
800
|
useEffect(() => {
|
|
587
|
-
|
|
588
|
-
|
|
801
|
+
const handleStepsToggle = () => {
|
|
802
|
+
requestAnimationFrame(() => {
|
|
803
|
+
requestAnimationFrame(() => {
|
|
804
|
+
const distance = getDistanceFromBottom();
|
|
805
|
+
if (distance > 0 && distance < 600) {
|
|
806
|
+
scrollToBottom();
|
|
807
|
+
}
|
|
808
|
+
});
|
|
809
|
+
});
|
|
810
|
+
};
|
|
811
|
+
const el = scrollRef.current;
|
|
812
|
+
if (el) {
|
|
813
|
+
el.addEventListener("payman-steps-toggle", handleStepsToggle);
|
|
814
|
+
return () => el.removeEventListener("payman-steps-toggle", handleStepsToggle);
|
|
815
|
+
}
|
|
816
|
+
}, [getDistanceFromBottom, scrollToBottom]);
|
|
817
|
+
const handleScrollToBottom = useCallback(() => {
|
|
818
|
+
scrollToBottom();
|
|
819
|
+
}, [scrollToBottom]);
|
|
589
820
|
if (isLoading) {
|
|
590
|
-
return /* @__PURE__ */ jsx("div", { className: cn("flex-1 overflow-y-auto min-h-0", className), children: /* @__PURE__ */ jsx("div", { className: "p-4 space-y-4", children: Array.from({ length: 6 }).map((_, index) => /* @__PURE__ */ jsx(
|
|
591
|
-
MessageRowSkeleton,
|
|
592
|
-
{
|
|
593
|
-
isRightAligned: index % 3 === 0
|
|
594
|
-
},
|
|
595
|
-
`skeleton-${index}`
|
|
596
|
-
)) }) });
|
|
597
|
-
}
|
|
598
|
-
if (messages.length === 0) {
|
|
599
821
|
return /* @__PURE__ */ jsx(
|
|
600
822
|
"div",
|
|
601
823
|
{
|
|
602
824
|
className: cn(
|
|
603
|
-
"flex-1 overflow-y-auto min-h-0
|
|
825
|
+
"flex-1 overflow-y-auto min-h-0 payman-scrollbar",
|
|
604
826
|
className
|
|
605
827
|
),
|
|
606
|
-
children: /* @__PURE__ */
|
|
607
|
-
|
|
828
|
+
children: /* @__PURE__ */ jsx(
|
|
829
|
+
"div",
|
|
608
830
|
{
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
{
|
|
621
|
-
className: cn(
|
|
622
|
-
index === 0 ? layout === "centered" ? "text-2xl font-semibold text-primary" : "text-2xl font-semibold text-foreground" : "text-sm text-muted-foreground"
|
|
623
|
-
),
|
|
624
|
-
children: line
|
|
625
|
-
},
|
|
626
|
-
index
|
|
627
|
-
))
|
|
628
|
-
]
|
|
831
|
+
className: cn(
|
|
832
|
+
"space-y-5",
|
|
833
|
+
layout === "centered" ? "max-w-2xl mx-auto px-4 py-6" : "p-4"
|
|
834
|
+
),
|
|
835
|
+
children: Array.from({ length: 5 }).map((_, i) => /* @__PURE__ */ jsx(
|
|
836
|
+
MessageRowSkeleton,
|
|
837
|
+
{
|
|
838
|
+
isRightAligned: i % 3 === 0
|
|
839
|
+
},
|
|
840
|
+
`skel-${i}`
|
|
841
|
+
))
|
|
629
842
|
}
|
|
630
843
|
)
|
|
631
844
|
}
|
|
632
845
|
);
|
|
633
846
|
}
|
|
634
|
-
|
|
847
|
+
if (messages.length === 0) {
|
|
848
|
+
const lines = emptyStateText.split("\n").map((l) => l.trim()).filter(Boolean);
|
|
849
|
+
return /* @__PURE__ */ jsx("div", { className: cn("payman-empty-root p-8", className), children: /* @__PURE__ */ jsxs(
|
|
850
|
+
motion.div,
|
|
851
|
+
{
|
|
852
|
+
initial: { opacity: 0, y: 20 },
|
|
853
|
+
animate: { opacity: 1, y: 0 },
|
|
854
|
+
transition: { duration: 0.5, ease: [0.25, 0.46, 0.45, 0.94] },
|
|
855
|
+
className: "payman-empty-content",
|
|
856
|
+
children: [
|
|
857
|
+
showEmptyStateIcon && /* @__PURE__ */ jsx(
|
|
858
|
+
motion.div,
|
|
859
|
+
{
|
|
860
|
+
initial: { scale: 0.85, opacity: 0 },
|
|
861
|
+
animate: { scale: 1, opacity: 1 },
|
|
862
|
+
transition: { delay: 0.08, duration: 0.45, ease: [0.25, 0.46, 0.45, 0.94] },
|
|
863
|
+
className: "payman-empty-icon-wrap",
|
|
864
|
+
children: /* @__PURE__ */ jsx(MessageCircle, { className: "h-7 w-7 payman-empty-icon", strokeWidth: 1.5 })
|
|
865
|
+
}
|
|
866
|
+
),
|
|
867
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-col gap-1.5", children: lines.map((line, i) => /* @__PURE__ */ jsx(
|
|
868
|
+
motion.p,
|
|
869
|
+
{
|
|
870
|
+
initial: { opacity: 0, y: 6 },
|
|
871
|
+
animate: { opacity: 1, y: 0 },
|
|
872
|
+
transition: { delay: 0.12 + i * 0.06, duration: 0.4 },
|
|
873
|
+
className: i === 0 ? "payman-empty-title" : "payman-empty-subtitle",
|
|
874
|
+
children: line
|
|
875
|
+
},
|
|
876
|
+
i
|
|
877
|
+
)) })
|
|
878
|
+
]
|
|
879
|
+
}
|
|
880
|
+
) });
|
|
881
|
+
}
|
|
882
|
+
return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(
|
|
635
883
|
"div",
|
|
636
884
|
{
|
|
637
|
-
ref:
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
"
|
|
641
|
-
|
|
642
|
-
),
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
885
|
+
ref: scrollRef,
|
|
886
|
+
onScroll: handleScroll,
|
|
887
|
+
className: cn(
|
|
888
|
+
"flex-1 min-h-0 overflow-y-auto payman-scrollbar relative",
|
|
889
|
+
className
|
|
890
|
+
),
|
|
891
|
+
children: [
|
|
892
|
+
/* @__PURE__ */ jsx(
|
|
893
|
+
"div",
|
|
894
|
+
{
|
|
895
|
+
className: cn(
|
|
896
|
+
"space-y-4",
|
|
897
|
+
layout === "centered" ? "max-w-2xl mx-auto px-4 py-6" : "p-4"
|
|
898
|
+
),
|
|
899
|
+
children: messages.map((message) => /* @__PURE__ */ jsx(
|
|
900
|
+
MessageRow,
|
|
901
|
+
{
|
|
902
|
+
message,
|
|
903
|
+
stage,
|
|
904
|
+
animated,
|
|
905
|
+
showAgentName,
|
|
906
|
+
agentName,
|
|
907
|
+
showAvatars,
|
|
908
|
+
showUserAvatar,
|
|
909
|
+
showAssistantAvatar,
|
|
910
|
+
layout,
|
|
911
|
+
showTimestamps,
|
|
912
|
+
showExecutionSteps,
|
|
913
|
+
showStreamingDot,
|
|
914
|
+
streamingStepsText,
|
|
915
|
+
completedStepsText,
|
|
916
|
+
onExecutionTraceClick
|
|
917
|
+
},
|
|
918
|
+
message.id
|
|
919
|
+
))
|
|
920
|
+
}
|
|
921
|
+
),
|
|
922
|
+
showScrollBtn && /* @__PURE__ */ jsx("div", { className: "sticky bottom-0 z-20 flex justify-center pb-3 -mt-11", children: /* @__PURE__ */ jsx(
|
|
923
|
+
"button",
|
|
924
|
+
{
|
|
925
|
+
onClick: handleScrollToBottom,
|
|
926
|
+
className: cn(
|
|
927
|
+
"w-8 h-8 rounded-full",
|
|
928
|
+
"bg-card border border-border shadow-lg",
|
|
929
|
+
"flex items-center justify-center",
|
|
930
|
+
"hover:bg-muted active:scale-95",
|
|
931
|
+
"transition-all duration-150",
|
|
932
|
+
"cursor-pointer"
|
|
933
|
+
),
|
|
934
|
+
"aria-label": "Scroll to bottom",
|
|
935
|
+
children: /* @__PURE__ */ jsx(ArrowDown, { className: "w-4 h-4 text-muted-foreground" })
|
|
936
|
+
}
|
|
937
|
+
) })
|
|
938
|
+
]
|
|
663
939
|
}
|
|
664
|
-
);
|
|
940
|
+
) });
|
|
665
941
|
}
|
|
666
942
|
var DEFAULT_MAX_LENGTH = 6;
|
|
667
943
|
var MAX_SUPPORTED_LENGTH = 12;
|
|
668
944
|
var AUTO_FOCUS_DELAY_MS = 250;
|
|
669
|
-
function OtpInput({
|
|
945
|
+
function OtpInput({
|
|
946
|
+
value,
|
|
947
|
+
onChange,
|
|
948
|
+
maxLength,
|
|
949
|
+
disabled = false
|
|
950
|
+
}) {
|
|
670
951
|
const inputRefs = useRef([]);
|
|
671
952
|
const safeMaxLength = Number.isInteger(maxLength) && maxLength > 0 ? Math.min(maxLength, MAX_SUPPORTED_LENGTH) : DEFAULT_MAX_LENGTH;
|
|
672
953
|
const digits = value.split("").concat(Array(safeMaxLength).fill("")).slice(0, safeMaxLength);
|
|
673
954
|
useEffect(() => {
|
|
674
955
|
if (disabled) return;
|
|
675
|
-
const
|
|
956
|
+
const timer = window.setTimeout(() => {
|
|
676
957
|
inputRefs.current[0]?.focus();
|
|
677
958
|
}, AUTO_FOCUS_DELAY_MS);
|
|
678
|
-
return () => window.clearTimeout(
|
|
959
|
+
return () => window.clearTimeout(timer);
|
|
679
960
|
}, [disabled]);
|
|
680
961
|
const focusInput = (index) => {
|
|
681
962
|
if (index >= 0 && index < safeMaxLength) {
|
|
@@ -690,9 +971,7 @@ function OtpInput({ value, onChange, maxLength, disabled = false }) {
|
|
|
690
971
|
const newDigits = [...digits];
|
|
691
972
|
newDigits[index] = char;
|
|
692
973
|
updateValue(newDigits);
|
|
693
|
-
if (char && index < safeMaxLength - 1)
|
|
694
|
-
focusInput(index + 1);
|
|
695
|
-
}
|
|
974
|
+
if (char && index < safeMaxLength - 1) focusInput(index + 1);
|
|
696
975
|
};
|
|
697
976
|
const handleKeyDown = (index, e) => {
|
|
698
977
|
if (e.key === "Enter") {
|
|
@@ -729,7 +1008,7 @@ function OtpInput({ value, onChange, maxLength, disabled = false }) {
|
|
|
729
1008
|
updateValue(newDigits);
|
|
730
1009
|
focusInput(Math.min(pasted.length, safeMaxLength - 1));
|
|
731
1010
|
};
|
|
732
|
-
return /* @__PURE__ */ jsx("div", {
|
|
1011
|
+
return /* @__PURE__ */ jsx("div", { className: "flex gap-2.5 justify-center", children: digits.map((digit, i) => /* @__PURE__ */ jsx(
|
|
733
1012
|
"input",
|
|
734
1013
|
{
|
|
735
1014
|
ref: (el) => {
|
|
@@ -745,7 +1024,12 @@ function OtpInput({ value, onChange, maxLength, disabled = false }) {
|
|
|
745
1024
|
onPaste: handlePaste,
|
|
746
1025
|
onFocus: (e) => e.target.select(),
|
|
747
1026
|
"aria-label": `Digit ${i + 1}`,
|
|
748
|
-
className:
|
|
1027
|
+
className: cn(
|
|
1028
|
+
"w-12 h-14 text-center text-xl font-semibold rounded-xl",
|
|
1029
|
+
"payman-otp-input otp-input",
|
|
1030
|
+
"transition-all duration-150 cursor-text",
|
|
1031
|
+
disabled && "cursor-not-allowed"
|
|
1032
|
+
)
|
|
749
1033
|
},
|
|
750
1034
|
i
|
|
751
1035
|
)) });
|
|
@@ -814,9 +1098,10 @@ function UserActionModal({
|
|
|
814
1098
|
}, [isOpen, resetActionState]);
|
|
815
1099
|
useEffect(() => {
|
|
816
1100
|
if (resendCooldownRemaining <= 0) return;
|
|
817
|
-
const timer = setTimeout(
|
|
818
|
-
setResendCooldownRemaining((
|
|
819
|
-
|
|
1101
|
+
const timer = setTimeout(
|
|
1102
|
+
() => setResendCooldownRemaining((p) => p - 1),
|
|
1103
|
+
1e3
|
|
1104
|
+
);
|
|
820
1105
|
return () => clearTimeout(timer);
|
|
821
1106
|
}, [resendCooldownRemaining]);
|
|
822
1107
|
useEffect(() => {
|
|
@@ -828,9 +1113,7 @@ function UserActionModal({
|
|
|
828
1113
|
useEffect(() => {
|
|
829
1114
|
if (!isOpen || !isSubmitting) return;
|
|
830
1115
|
if (actionType !== "approve" && actionType !== "reject") return;
|
|
831
|
-
const timeout = setTimeout(
|
|
832
|
-
resetActionState();
|
|
833
|
-
}, ACTION_PENDING_TIMEOUT_MS);
|
|
1116
|
+
const timeout = setTimeout(resetActionState, ACTION_PENDING_TIMEOUT_MS);
|
|
834
1117
|
return () => clearTimeout(timeout);
|
|
835
1118
|
}, [isOpen, isSubmitting, actionType, resetActionState]);
|
|
836
1119
|
useEffect(() => {
|
|
@@ -840,39 +1123,39 @@ function UserActionModal({
|
|
|
840
1123
|
previousFocusedRef.current = document.activeElement;
|
|
841
1124
|
const originalOverflow = document.body.style.overflow;
|
|
842
1125
|
document.body.style.overflow = "hidden";
|
|
843
|
-
const
|
|
1126
|
+
const getFocusable = () => Array.from(
|
|
844
1127
|
dialog.querySelectorAll(
|
|
845
1128
|
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
|
|
846
1129
|
)
|
|
847
1130
|
).filter((el) => !el.hasAttribute("disabled") && el.tabIndex !== -1);
|
|
848
|
-
const focusables =
|
|
1131
|
+
const focusables = getFocusable();
|
|
849
1132
|
(focusables[0] ?? dialog).focus();
|
|
850
|
-
const handleKeyDown = (
|
|
851
|
-
if (
|
|
852
|
-
|
|
1133
|
+
const handleKeyDown = (e) => {
|
|
1134
|
+
if (e.key === "Escape") {
|
|
1135
|
+
e.preventDefault();
|
|
853
1136
|
return;
|
|
854
1137
|
}
|
|
855
|
-
if (
|
|
856
|
-
const
|
|
857
|
-
if (
|
|
858
|
-
|
|
1138
|
+
if (e.key !== "Tab") return;
|
|
1139
|
+
const items = getFocusable();
|
|
1140
|
+
if (!items.length) {
|
|
1141
|
+
e.preventDefault();
|
|
859
1142
|
dialog.focus();
|
|
860
1143
|
return;
|
|
861
1144
|
}
|
|
862
|
-
const first =
|
|
863
|
-
const last =
|
|
864
|
-
const
|
|
865
|
-
const
|
|
866
|
-
if (
|
|
867
|
-
if (!
|
|
868
|
-
|
|
1145
|
+
const first = items[0];
|
|
1146
|
+
const last = items[items.length - 1];
|
|
1147
|
+
const active = document.activeElement;
|
|
1148
|
+
const inDialog = active ? dialog.contains(active) : false;
|
|
1149
|
+
if (e.shiftKey) {
|
|
1150
|
+
if (!inDialog || active === first) {
|
|
1151
|
+
e.preventDefault();
|
|
869
1152
|
last.focus();
|
|
870
1153
|
}
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
1154
|
+
} else {
|
|
1155
|
+
if (!inDialog || active === last) {
|
|
1156
|
+
e.preventDefault();
|
|
1157
|
+
first.focus();
|
|
1158
|
+
}
|
|
876
1159
|
}
|
|
877
1160
|
};
|
|
878
1161
|
document.addEventListener("keydown", handleKeyDown);
|
|
@@ -916,155 +1199,191 @@ function UserActionModal({
|
|
|
916
1199
|
}, [resendCooldownRemaining, onResend]);
|
|
917
1200
|
if (!isOpen || !userActionRequest) return null;
|
|
918
1201
|
const isOtpValid = otp.length === schema.maxLength && /^\d+$/.test(otp);
|
|
919
|
-
return /* @__PURE__ */
|
|
1202
|
+
return /* @__PURE__ */ jsxs(
|
|
920
1203
|
"div",
|
|
921
1204
|
{
|
|
1205
|
+
className: "payman-modal-backdrop",
|
|
922
1206
|
style: {
|
|
923
1207
|
position: "fixed",
|
|
924
1208
|
inset: 0,
|
|
925
|
-
backgroundColor: "rgba(0, 0, 0, 0.5)",
|
|
926
1209
|
zIndex: 1e4,
|
|
927
1210
|
display: "flex",
|
|
928
1211
|
alignItems: "center",
|
|
929
|
-
justifyContent: "center"
|
|
1212
|
+
justifyContent: "center",
|
|
1213
|
+
padding: 16,
|
|
1214
|
+
boxSizing: "border-box"
|
|
930
1215
|
},
|
|
931
|
-
children:
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
disabled: isSubmitting
|
|
953
|
-
}
|
|
954
|
-
) }),
|
|
955
|
-
/* @__PURE__ */ jsxs(
|
|
1216
|
+
children: [
|
|
1217
|
+
/* @__PURE__ */ jsx(
|
|
1218
|
+
"div",
|
|
1219
|
+
{
|
|
1220
|
+
className: "absolute inset-0 backdrop-blur-sm payman-modal-backdrop-overlay payman-modal-animate",
|
|
1221
|
+
"aria-hidden": true,
|
|
1222
|
+
style: {
|
|
1223
|
+
background: "var(--payman-modal-backdrop-bg, rgba(0, 0, 0, 0.4))"
|
|
1224
|
+
}
|
|
1225
|
+
}
|
|
1226
|
+
),
|
|
1227
|
+
/* @__PURE__ */ jsx(
|
|
1228
|
+
"div",
|
|
1229
|
+
{
|
|
1230
|
+
style: {
|
|
1231
|
+
flexShrink: 0,
|
|
1232
|
+
width: "100%",
|
|
1233
|
+
maxWidth: 400,
|
|
1234
|
+
minWidth: 0
|
|
1235
|
+
},
|
|
1236
|
+
children: /* @__PURE__ */ jsxs(
|
|
956
1237
|
"div",
|
|
957
1238
|
{
|
|
1239
|
+
ref: dialogRef,
|
|
1240
|
+
role: "dialog",
|
|
1241
|
+
"aria-modal": "true",
|
|
1242
|
+
"aria-labelledby": "payman-modal-title",
|
|
1243
|
+
className: cn(
|
|
1244
|
+
"relative w-full rounded-2xl p-6 shadow-2xl",
|
|
1245
|
+
"payman-modal-dialog payman-modal-animate"
|
|
1246
|
+
),
|
|
958
1247
|
style: {
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
1248
|
+
width: "100%",
|
|
1249
|
+
maxWidth: 400,
|
|
1250
|
+
boxSizing: "border-box",
|
|
1251
|
+
background: "var(--payman-modal-dialog-bg, var(--payman-card, #ffffff))",
|
|
1252
|
+
border: "1px solid var(--payman-modal-dialog-border, var(--payman-border, #e4e4e7))"
|
|
962
1253
|
},
|
|
1254
|
+
tabIndex: -1,
|
|
963
1255
|
children: [
|
|
964
|
-
/* @__PURE__ */ jsxs(
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
onClick: handleReject,
|
|
976
|
-
disabled: isSubmitting,
|
|
977
|
-
className: cn(
|
|
978
|
-
"rounded-lg font-medium transition-colors cursor-pointer",
|
|
979
|
-
"bg-destructive/10 text-destructive hover:bg-destructive/30 hover:text-destructive",
|
|
980
|
-
"disabled:opacity-50 disabled:cursor-not-allowed"
|
|
981
|
-
),
|
|
982
|
-
style: {
|
|
983
|
-
flex: 1,
|
|
984
|
-
display: "flex",
|
|
985
|
-
alignItems: "center",
|
|
986
|
-
justifyContent: "center",
|
|
987
|
-
gap: "6px",
|
|
988
|
-
whiteSpace: "nowrap",
|
|
989
|
-
minWidth: 0,
|
|
990
|
-
padding: "10px 16px",
|
|
991
|
-
fontSize: "14px",
|
|
992
|
-
lineHeight: "20px",
|
|
993
|
-
border: "none"
|
|
994
|
-
},
|
|
995
|
-
children: [
|
|
996
|
-
actionType === "reject" && /* @__PURE__ */ jsx(Loader2, { className: "w-4 h-4 animate-spin", style: { flexShrink: 0 } }),
|
|
997
|
-
actionType === "reject" ? MODAL_CONTENT.LOADING_REJECT : BUTTON_LABELS.REJECT
|
|
998
|
-
]
|
|
999
|
-
}
|
|
1000
|
-
),
|
|
1001
|
-
/* @__PURE__ */ jsxs(
|
|
1002
|
-
"button",
|
|
1256
|
+
/* @__PURE__ */ jsxs("div", { className: "text-center mb-5", children: [
|
|
1257
|
+
/* @__PURE__ */ jsx(
|
|
1258
|
+
"div",
|
|
1259
|
+
{
|
|
1260
|
+
className: "inline-flex items-center justify-center w-12 h-12 rounded-2xl payman-modal-icon-wrap mb-3",
|
|
1261
|
+
style: {
|
|
1262
|
+
background: "var(--payman-modal-icon-bg, color-mix(in srgb, var(--payman-primary, #18181b) 10%, transparent))",
|
|
1263
|
+
border: "1px solid var(--payman-modal-icon-border, color-mix(in srgb, var(--payman-primary, #18181b) 20%, transparent))"
|
|
1264
|
+
},
|
|
1265
|
+
children: /* @__PURE__ */ jsx(
|
|
1266
|
+
ShieldCheck,
|
|
1003
1267
|
{
|
|
1004
|
-
|
|
1005
|
-
disabled: !isOtpValid || isSubmitting,
|
|
1006
|
-
className: cn(
|
|
1007
|
-
"rounded-lg font-medium transition-colors cursor-pointer",
|
|
1008
|
-
"bg-primary text-primary-foreground hover:bg-primary/90 active:bg-primary/80",
|
|
1009
|
-
"disabled:opacity-50 disabled:cursor-not-allowed"
|
|
1010
|
-
),
|
|
1268
|
+
className: "w-6 h-6 payman-modal-icon",
|
|
1011
1269
|
style: {
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
alignItems: "center",
|
|
1015
|
-
justifyContent: "center",
|
|
1016
|
-
gap: "6px",
|
|
1017
|
-
whiteSpace: "nowrap",
|
|
1018
|
-
minWidth: 0,
|
|
1019
|
-
padding: "10px 16px",
|
|
1020
|
-
fontSize: "14px",
|
|
1021
|
-
lineHeight: "20px",
|
|
1022
|
-
border: "none"
|
|
1023
|
-
},
|
|
1024
|
-
children: [
|
|
1025
|
-
actionType === "approve" && /* @__PURE__ */ jsx(Loader2, { className: "w-4 h-4 animate-spin", style: { flexShrink: 0 } }),
|
|
1026
|
-
actionType === "approve" ? MODAL_CONTENT.LOADING_APPROVE : BUTTON_LABELS.APPROVE
|
|
1027
|
-
]
|
|
1270
|
+
color: "var(--payman-modal-icon-fg, var(--payman-primary, #18181b))"
|
|
1271
|
+
}
|
|
1028
1272
|
}
|
|
1029
1273
|
)
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1274
|
+
}
|
|
1275
|
+
),
|
|
1276
|
+
/* @__PURE__ */ jsx(
|
|
1277
|
+
"h2",
|
|
1278
|
+
{
|
|
1279
|
+
id: "payman-modal-title",
|
|
1280
|
+
className: "text-lg font-semibold payman-modal-title tracking-tight",
|
|
1281
|
+
style: {
|
|
1282
|
+
color: "var(--payman-modal-title-fg, var(--payman-foreground, #18181b))"
|
|
1283
|
+
},
|
|
1284
|
+
children: MODAL_CONTENT.TITLE
|
|
1285
|
+
}
|
|
1286
|
+
)
|
|
1287
|
+
] }),
|
|
1288
|
+
/* @__PURE__ */ jsx(
|
|
1289
|
+
"p",
|
|
1035
1290
|
{
|
|
1036
|
-
|
|
1037
|
-
disabled: isSubmitting || resendCooldownRemaining > 0,
|
|
1038
|
-
className: cn(
|
|
1039
|
-
"rounded-lg font-medium transition-colors cursor-pointer",
|
|
1040
|
-
"border border-border text-muted-foreground hover:text-foreground hover:border-muted-foreground/40 hover:bg-muted/50",
|
|
1041
|
-
"disabled:opacity-50 disabled:cursor-not-allowed"
|
|
1042
|
-
),
|
|
1291
|
+
className: "text-sm payman-modal-desc text-center mb-6 leading-relaxed px-0.5",
|
|
1043
1292
|
style: {
|
|
1044
|
-
|
|
1045
|
-
alignItems: "center",
|
|
1046
|
-
justifyContent: "center",
|
|
1047
|
-
gap: "6px",
|
|
1048
|
-
whiteSpace: "nowrap",
|
|
1049
|
-
width: "100%",
|
|
1050
|
-
padding: "8px 16px",
|
|
1051
|
-
fontSize: "12px",
|
|
1052
|
-
lineHeight: "16px"
|
|
1293
|
+
color: "var(--payman-modal-desc-fg, var(--payman-muted-foreground, #71717a))"
|
|
1053
1294
|
},
|
|
1054
|
-
children:
|
|
1055
|
-
actionType === "resend" && /* @__PURE__ */ jsx(Loader2, { className: "w-3.5 h-3.5 animate-spin", style: { flexShrink: 0 } }),
|
|
1056
|
-
actionType === "resend" ? MODAL_CONTENT.LOADING_RESEND : resendCooldownRemaining > 0 ? `${MODAL_CONTENT.RESEND_AVAILABLE_IN} ${resendCooldownRemaining}s` : BUTTON_LABELS.RESEND
|
|
1057
|
-
]
|
|
1295
|
+
children: userActionRequest.message
|
|
1058
1296
|
}
|
|
1059
|
-
)
|
|
1297
|
+
),
|
|
1298
|
+
/* @__PURE__ */ jsx("div", { className: "mb-6", children: /* @__PURE__ */ jsx(
|
|
1299
|
+
OtpInput,
|
|
1300
|
+
{
|
|
1301
|
+
value: otp,
|
|
1302
|
+
onChange: setOtp,
|
|
1303
|
+
maxLength: schema.maxLength,
|
|
1304
|
+
disabled: isSubmitting
|
|
1305
|
+
}
|
|
1306
|
+
) }),
|
|
1307
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
1308
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-2.5", children: [
|
|
1309
|
+
/* @__PURE__ */ jsxs(
|
|
1310
|
+
"button",
|
|
1311
|
+
{
|
|
1312
|
+
type: "button",
|
|
1313
|
+
onClick: handleReject,
|
|
1314
|
+
disabled: isSubmitting,
|
|
1315
|
+
className: cn(
|
|
1316
|
+
"flex-1 flex items-center justify-center gap-2",
|
|
1317
|
+
"min-h-[48px] py-3 px-4 rounded-xl text-sm font-medium border-0 cursor-pointer",
|
|
1318
|
+
"payman-modal-btn-reject",
|
|
1319
|
+
"active:scale-[0.98] transition-all duration-150",
|
|
1320
|
+
"disabled:cursor-not-allowed"
|
|
1321
|
+
),
|
|
1322
|
+
style: {
|
|
1323
|
+
background: "var(--payman-modal-btn-reject-bg, color-mix(in srgb, var(--payman-destructive, #ef4444) 10%, transparent))",
|
|
1324
|
+
color: "var(--payman-modal-btn-reject-fg, var(--payman-destructive, #ef4444))"
|
|
1325
|
+
},
|
|
1326
|
+
children: [
|
|
1327
|
+
actionType === "reject" ? /* @__PURE__ */ jsx(Loader2, { className: "w-4 h-4 animate-spin shrink-0" }) : /* @__PURE__ */ jsx(X, { className: "w-4 h-4 shrink-0", strokeWidth: 2.5 }),
|
|
1328
|
+
actionType === "reject" ? MODAL_CONTENT.LOADING_REJECT : BUTTON_LABELS.REJECT
|
|
1329
|
+
]
|
|
1330
|
+
}
|
|
1331
|
+
),
|
|
1332
|
+
/* @__PURE__ */ jsxs(
|
|
1333
|
+
"button",
|
|
1334
|
+
{
|
|
1335
|
+
type: "button",
|
|
1336
|
+
onClick: handleApprove,
|
|
1337
|
+
disabled: !isOtpValid || isSubmitting,
|
|
1338
|
+
className: cn(
|
|
1339
|
+
"flex-1 flex items-center justify-center gap-2",
|
|
1340
|
+
"min-h-[48px] py-3 px-4 rounded-xl text-sm font-medium border-0 cursor-pointer",
|
|
1341
|
+
"payman-modal-btn-approve",
|
|
1342
|
+
"active:scale-[0.98] transition-all duration-150",
|
|
1343
|
+
"disabled:cursor-not-allowed"
|
|
1344
|
+
),
|
|
1345
|
+
style: {
|
|
1346
|
+
background: "var(--payman-modal-btn-approve-bg, var(--payman-primary, #18181b))",
|
|
1347
|
+
color: "var(--payman-modal-btn-approve-fg, var(--payman-primary-foreground, #fafafa))"
|
|
1348
|
+
},
|
|
1349
|
+
children: [
|
|
1350
|
+
actionType === "approve" ? /* @__PURE__ */ jsx(Loader2, { className: "w-4 h-4 animate-spin shrink-0" }) : /* @__PURE__ */ jsx(Check, { className: "w-4 h-4 shrink-0", strokeWidth: 2.5 }),
|
|
1351
|
+
actionType === "approve" ? MODAL_CONTENT.LOADING_APPROVE : BUTTON_LABELS.APPROVE
|
|
1352
|
+
]
|
|
1353
|
+
}
|
|
1354
|
+
)
|
|
1355
|
+
] }),
|
|
1356
|
+
/* @__PURE__ */ jsxs(
|
|
1357
|
+
"button",
|
|
1358
|
+
{
|
|
1359
|
+
type: "button",
|
|
1360
|
+
onClick: handleResend,
|
|
1361
|
+
disabled: isSubmitting || resendCooldownRemaining > 0,
|
|
1362
|
+
className: cn(
|
|
1363
|
+
"w-full flex items-center justify-center gap-2",
|
|
1364
|
+
"min-h-[48px] py-3 px-4 rounded-xl text-sm font-medium cursor-pointer",
|
|
1365
|
+
"payman-modal-btn-resend",
|
|
1366
|
+
"transition-all duration-150 disabled:cursor-not-allowed"
|
|
1367
|
+
),
|
|
1368
|
+
style: {
|
|
1369
|
+
border: "1px solid var(--payman-modal-btn-resend-border, var(--payman-border, #e4e4e7))",
|
|
1370
|
+
color: "var(--payman-modal-btn-resend-fg, var(--payman-muted-foreground, #71717a))"
|
|
1371
|
+
},
|
|
1372
|
+
children: [
|
|
1373
|
+
actionType === "resend" ? /* @__PURE__ */ jsx(Loader2, { className: "w-4 h-4 animate-spin shrink-0" }) : /* @__PURE__ */ jsx(RefreshCw, { className: "w-4 h-4 shrink-0", strokeWidth: 2.5 }),
|
|
1374
|
+
actionType === "resend" ? MODAL_CONTENT.LOADING_RESEND : resendCooldownRemaining > 0 ? `${MODAL_CONTENT.RESEND_AVAILABLE_IN} ${resendCooldownRemaining}s` : BUTTON_LABELS.RESEND
|
|
1375
|
+
]
|
|
1376
|
+
}
|
|
1377
|
+
)
|
|
1378
|
+
] })
|
|
1060
1379
|
]
|
|
1061
1380
|
}
|
|
1062
1381
|
)
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1382
|
+
}
|
|
1383
|
+
)
|
|
1384
|
+
]
|
|
1066
1385
|
}
|
|
1067
|
-
)
|
|
1386
|
+
);
|
|
1068
1387
|
}
|
|
1069
1388
|
var DEFAULT_USER_ACTION_STATE = {
|
|
1070
1389
|
request: null,
|
|
@@ -1193,7 +1512,7 @@ function PaymanChat({
|
|
|
1193
1512
|
"div",
|
|
1194
1513
|
{
|
|
1195
1514
|
className: cn(
|
|
1196
|
-
"bg-card
|
|
1515
|
+
"bg-card overflow-hidden flex flex-col flex-[4]",
|
|
1197
1516
|
className
|
|
1198
1517
|
),
|
|
1199
1518
|
style,
|
|
@@ -1208,7 +1527,7 @@ function PaymanChat({
|
|
|
1208
1527
|
"div",
|
|
1209
1528
|
{
|
|
1210
1529
|
className: cn(
|
|
1211
|
-
"bg-card
|
|
1530
|
+
"bg-card overflow-hidden flex flex-col flex-[4]",
|
|
1212
1531
|
className
|
|
1213
1532
|
),
|
|
1214
1533
|
style,
|
|
@@ -1223,7 +1542,7 @@ function PaymanChat({
|
|
|
1223
1542
|
"div",
|
|
1224
1543
|
{
|
|
1225
1544
|
className: cn(
|
|
1226
|
-
"bg-card
|
|
1545
|
+
"bg-card overflow-hidden flex flex-col flex-[4]",
|
|
1227
1546
|
className
|
|
1228
1547
|
),
|
|
1229
1548
|
style,
|