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