@paymanai/payman-ask-sdk 4.0.26 → 4.0.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +8 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +984 -63
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +985 -64
- package/dist/index.mjs.map +1 -1
- package/dist/index.native.js +40 -2
- package/dist/index.native.js.map +1 -1
- package/dist/styles.css +101 -0
- package/dist/styles.css.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1155,6 +1155,9 @@ function getUserActionSecondsLeft(prompt) {
|
|
|
1155
1155
|
return void 0;
|
|
1156
1156
|
}
|
|
1157
1157
|
var EMPTY_USER_ACTION_STATE2 = { prompts: [], notifications: [] };
|
|
1158
|
+
function promptSlotKey(p) {
|
|
1159
|
+
return p.toolCallId || p.userActionId;
|
|
1160
|
+
}
|
|
1158
1161
|
function upsertPrompt(prompts, req) {
|
|
1159
1162
|
const idx = prompts.findIndex(
|
|
1160
1163
|
(p) => req.toolCallId ? p.toolCallId === req.toolCallId : p.userActionId === req.userActionId
|
|
@@ -1201,6 +1204,7 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1201
1204
|
configRef.current = config;
|
|
1202
1205
|
const messagesRef = React.useRef(messages);
|
|
1203
1206
|
messagesRef.current = messages;
|
|
1207
|
+
const pendingSubmissionsRef = React.useRef(/* @__PURE__ */ new Map());
|
|
1204
1208
|
const storeAwareSetMessages = React.useCallback(
|
|
1205
1209
|
(updater) => {
|
|
1206
1210
|
const streamUserId = streamUserIdRef.current;
|
|
@@ -1235,6 +1239,8 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1235
1239
|
if (!config.userId) return EMPTY_USER_ACTION_STATE2;
|
|
1236
1240
|
return activeStreamStore.get(config.userId)?.userActionState ?? EMPTY_USER_ACTION_STATE2;
|
|
1237
1241
|
});
|
|
1242
|
+
const userActionStateRef = React.useRef(userActionState);
|
|
1243
|
+
userActionStateRef.current = userActionState;
|
|
1238
1244
|
const storeAwareSetUserActionState = React.useCallback(
|
|
1239
1245
|
(updater) => {
|
|
1240
1246
|
const streamUserId = streamUserIdRef.current;
|
|
@@ -1262,6 +1268,12 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1262
1268
|
onExecutionTraceClick: (data) => callbacksRef.current.onExecutionTraceClick?.(data),
|
|
1263
1269
|
onSessionIdChange: (sessionId) => callbacksRef.current.onSessionIdChange?.(sessionId),
|
|
1264
1270
|
onUserActionRequired: (request) => {
|
|
1271
|
+
const requestSlotKey = promptSlotKey(request);
|
|
1272
|
+
for (const [pendingId, slotKey] of pendingSubmissionsRef.current) {
|
|
1273
|
+
if (slotKey === requestSlotKey) {
|
|
1274
|
+
pendingSubmissionsRef.current.delete(pendingId);
|
|
1275
|
+
}
|
|
1276
|
+
}
|
|
1265
1277
|
storeAwareSetUserActionState((prev) => ({
|
|
1266
1278
|
...prev,
|
|
1267
1279
|
prompts: upsertPrompt(prev.prompts, request)
|
|
@@ -1273,6 +1285,28 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1273
1285
|
(prev) => prev.notifications.some((n) => n.id === notification.id) ? prev : { ...prev, notifications: [...prev.notifications, notification] }
|
|
1274
1286
|
);
|
|
1275
1287
|
callbacksRef.current.onUserNotification?.(notification);
|
|
1288
|
+
},
|
|
1289
|
+
// A submitted-but-unconfirmed prompt (see `submitUserAction`) is only
|
|
1290
|
+
// safe to drop once the stream has demonstrably moved on. `onEvent`
|
|
1291
|
+
// in useStreamManagerV2 calls `onStepsUpdate` for *every* processed
|
|
1292
|
+
// stream event, unconditionally — so the first time this fires
|
|
1293
|
+
// after a submission, the event in hand is either the rejection
|
|
1294
|
+
// retry (a fresh `USER_ACTION_REQUIRED`, which the handler above
|
|
1295
|
+
// already deleted this pending entry for, earlier in the very same
|
|
1296
|
+
// event) or genuine forward progress (RUN_IN_PROGRESS, a tool call,
|
|
1297
|
+
// content deltas, RUN_COMPLETED, ...). Anything still pending by
|
|
1298
|
+
// the time we get here therefore means the run resumed normally —
|
|
1299
|
+
// clear it.
|
|
1300
|
+
onStepsUpdate: (steps) => {
|
|
1301
|
+
if (pendingSubmissionsRef.current.size > 0) {
|
|
1302
|
+
const resolved = [...pendingSubmissionsRef.current.keys()];
|
|
1303
|
+
pendingSubmissionsRef.current.clear();
|
|
1304
|
+
storeAwareSetUserActionState((prev) => ({
|
|
1305
|
+
...prev,
|
|
1306
|
+
prompts: prev.prompts.filter((p) => !resolved.includes(p.userActionId))
|
|
1307
|
+
}));
|
|
1308
|
+
}
|
|
1309
|
+
callbacksRef.current.onStepsUpdate?.(steps);
|
|
1276
1310
|
}
|
|
1277
1311
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1278
1312
|
}), []);
|
|
@@ -1408,6 +1442,7 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1408
1442
|
[storeAwareSetUserActionState]
|
|
1409
1443
|
);
|
|
1410
1444
|
const removePrompt = React.useCallback((userActionId) => {
|
|
1445
|
+
pendingSubmissionsRef.current.delete(userActionId);
|
|
1411
1446
|
storeAwareSetUserActionState((prev) => ({
|
|
1412
1447
|
...prev,
|
|
1413
1448
|
prompts: prev.prompts.filter((p) => p.userActionId !== userActionId)
|
|
@@ -1418,7 +1453,10 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1418
1453
|
setPromptStatus(userActionId, "submitting");
|
|
1419
1454
|
try {
|
|
1420
1455
|
await submitUserAction(configRef.current, userActionId, content);
|
|
1421
|
-
|
|
1456
|
+
const prompt = userActionStateRef.current.prompts.find(
|
|
1457
|
+
(p) => p.userActionId === userActionId
|
|
1458
|
+
);
|
|
1459
|
+
pendingSubmissionsRef.current.set(userActionId, prompt ? promptSlotKey(prompt) : userActionId);
|
|
1422
1460
|
} catch (error) {
|
|
1423
1461
|
if (error instanceof UserActionStaleError) {
|
|
1424
1462
|
setPromptStatus(userActionId, "stale");
|
|
@@ -1429,7 +1467,7 @@ function useChatV2(config, callbacks = {}) {
|
|
|
1429
1467
|
throw error;
|
|
1430
1468
|
}
|
|
1431
1469
|
},
|
|
1432
|
-
[
|
|
1470
|
+
[setPromptStatus]
|
|
1433
1471
|
);
|
|
1434
1472
|
const cancelUserAction2 = React.useCallback(
|
|
1435
1473
|
async (userActionId) => {
|
|
@@ -4109,6 +4147,8 @@ function AssistantMessageV2({
|
|
|
4109
4147
|
void 0,
|
|
4110
4148
|
typingSpeed
|
|
4111
4149
|
);
|
|
4150
|
+
const displayContentPending = Boolean(rawResponseContent) && !displayContent;
|
|
4151
|
+
const showThinkingBlock = isThinkingStreaming || displayContentPending;
|
|
4112
4152
|
const stickyLabel = (() => {
|
|
4113
4153
|
const steps = message.steps;
|
|
4114
4154
|
if (!steps || steps.length === 0) return void 0;
|
|
@@ -4243,7 +4283,7 @@ function AssistantMessageV2({
|
|
|
4243
4283
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4244
4284
|
toastPortal,
|
|
4245
4285
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "payman-v2-assistant-msg payman-v2-fade-in", children: [
|
|
4246
|
-
/* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children:
|
|
4286
|
+
/* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: showThinkingBlock && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4247
4287
|
framerMotion.motion.div,
|
|
4248
4288
|
{
|
|
4249
4289
|
initial: { opacity: 0, height: 0 },
|
|
@@ -4273,6 +4313,10 @@ function AssistantMessageV2({
|
|
|
4273
4313
|
isResolvingImages: message.isResolvingImages,
|
|
4274
4314
|
onImageClick
|
|
4275
4315
|
}
|
|
4316
|
+
) : displayContentPending ? (
|
|
4317
|
+
// The intent/status line above is still bridging this
|
|
4318
|
+
// gap (see `showThinkingBlock`) — nothing to add here.
|
|
4319
|
+
null
|
|
4276
4320
|
) : !isThinkingStreaming ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "payman-v2-assistant-msg-placeholder", children: "..." }) : null }),
|
|
4277
4321
|
/* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: showTrailingProgress && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4278
4322
|
framerMotion.motion.div,
|
|
@@ -4393,6 +4437,112 @@ function AssistantMessageV2({
|
|
|
4393
4437
|
)
|
|
4394
4438
|
] });
|
|
4395
4439
|
}
|
|
4440
|
+
var CHAR_VARIANTS = {
|
|
4441
|
+
fade: {
|
|
4442
|
+
initial: { opacity: 0, scale: 0.7 },
|
|
4443
|
+
animate: { opacity: 1, scale: 1 },
|
|
4444
|
+
exit: { opacity: 0, scale: 0.7 },
|
|
4445
|
+
transition: { duration: 0.14, ease: "easeOut" },
|
|
4446
|
+
overflow: "hidden"
|
|
4447
|
+
},
|
|
4448
|
+
blur: {
|
|
4449
|
+
initial: { opacity: 0, filter: "blur(8px)", y: -8 },
|
|
4450
|
+
animate: { opacity: 1, filter: "blur(0px)", y: 0 },
|
|
4451
|
+
exit: { opacity: 0, filter: "blur(8px)", y: 8 },
|
|
4452
|
+
transition: { duration: 0.18, ease: "easeOut" },
|
|
4453
|
+
overflow: "visible"
|
|
4454
|
+
}
|
|
4455
|
+
};
|
|
4456
|
+
function CharSlot({
|
|
4457
|
+
char,
|
|
4458
|
+
charKey,
|
|
4459
|
+
effect
|
|
4460
|
+
}) {
|
|
4461
|
+
if (!/\d/.test(char)) return /* @__PURE__ */ jsxRuntime.jsx("span", { style: { display: "inline-block" }, children: char });
|
|
4462
|
+
const v = CHAR_VARIANTS[effect];
|
|
4463
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { style: { position: "relative", display: "inline-block", overflow: v.overflow }, children: /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { mode: "popLayout", initial: false, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4464
|
+
framerMotion.motion.span,
|
|
4465
|
+
{
|
|
4466
|
+
initial: v.initial,
|
|
4467
|
+
animate: v.animate,
|
|
4468
|
+
exit: v.exit,
|
|
4469
|
+
transition: v.transition,
|
|
4470
|
+
style: { display: "inline-block" },
|
|
4471
|
+
children: char
|
|
4472
|
+
},
|
|
4473
|
+
charKey
|
|
4474
|
+
) }) });
|
|
4475
|
+
}
|
|
4476
|
+
function CountUp({
|
|
4477
|
+
to,
|
|
4478
|
+
from = 0,
|
|
4479
|
+
duration = 2,
|
|
4480
|
+
delay = 0,
|
|
4481
|
+
digitEffect = "none",
|
|
4482
|
+
className,
|
|
4483
|
+
startWhen = true,
|
|
4484
|
+
separator = ""
|
|
4485
|
+
}) {
|
|
4486
|
+
const ref = React.useRef(null);
|
|
4487
|
+
const motionValue = framerMotion.useMotionValue(from);
|
|
4488
|
+
const damping = 20 + 40 * (1 / duration);
|
|
4489
|
+
const stiffness = 100 * (1 / duration);
|
|
4490
|
+
const springValue = framerMotion.useSpring(motionValue, { damping, stiffness });
|
|
4491
|
+
const isInView = framerMotion.useInView(ref, { once: true, margin: "0px" });
|
|
4492
|
+
const decimals = React.useMemo(() => {
|
|
4493
|
+
const d = (n) => {
|
|
4494
|
+
const s = n.toString();
|
|
4495
|
+
return s.includes(".") ? s.split(".")[1].length : 0;
|
|
4496
|
+
};
|
|
4497
|
+
return Math.max(d(from), d(to));
|
|
4498
|
+
}, [from, to]);
|
|
4499
|
+
const formatValue = React.useCallback(
|
|
4500
|
+
(latest) => {
|
|
4501
|
+
const formatted = Intl.NumberFormat("en-US", {
|
|
4502
|
+
useGrouping: !!separator,
|
|
4503
|
+
minimumFractionDigits: decimals,
|
|
4504
|
+
maximumFractionDigits: decimals
|
|
4505
|
+
}).format(latest);
|
|
4506
|
+
return separator ? formatted.replace(/,/g, separator) : formatted;
|
|
4507
|
+
},
|
|
4508
|
+
[decimals, separator]
|
|
4509
|
+
);
|
|
4510
|
+
const [chars, setChars] = React.useState(formatValue(from).split(""));
|
|
4511
|
+
React.useEffect(() => {
|
|
4512
|
+
if (isInView && startWhen) {
|
|
4513
|
+
const t = setTimeout(() => motionValue.set(to), delay * 1e3);
|
|
4514
|
+
return () => clearTimeout(t);
|
|
4515
|
+
}
|
|
4516
|
+
}, [isInView, startWhen, motionValue, to, delay]);
|
|
4517
|
+
React.useEffect(() => {
|
|
4518
|
+
const unsub = springValue.on("change", (latest) => {
|
|
4519
|
+
if (digitEffect === "none") {
|
|
4520
|
+
if (ref.current) ref.current.textContent = formatValue(latest);
|
|
4521
|
+
} else {
|
|
4522
|
+
setChars(formatValue(latest).split(""));
|
|
4523
|
+
}
|
|
4524
|
+
});
|
|
4525
|
+
return () => unsub();
|
|
4526
|
+
}, [springValue, formatValue, digitEffect]);
|
|
4527
|
+
if (digitEffect === "none") {
|
|
4528
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { ref, className: cn(className), children: formatValue(from) });
|
|
4529
|
+
}
|
|
4530
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { ref, className: cn("inline-flex items-center", className), children: chars.map((char, i) => /* @__PURE__ */ jsxRuntime.jsx(CharSlot, { char, charKey: `${i}-${char}`, effect: digitEffect }, i)) });
|
|
4531
|
+
}
|
|
4532
|
+
function AnimatedDuration({ seconds, className }) {
|
|
4533
|
+
const total = Math.max(0, seconds);
|
|
4534
|
+
const m = Math.floor(total / 60);
|
|
4535
|
+
const s = total % 60;
|
|
4536
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: cn("tabular-nums", className), children: [
|
|
4537
|
+
m > 0 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4538
|
+
/* @__PURE__ */ jsxRuntime.jsx(CountUp, { to: m, duration: 0.9, digitEffect: "blur", className: "tabular-nums" }),
|
|
4539
|
+
"m",
|
|
4540
|
+
" "
|
|
4541
|
+
] }),
|
|
4542
|
+
/* @__PURE__ */ jsxRuntime.jsx(CountUp, { to: s, duration: 0.9, digitEffect: "blur", className: "tabular-nums" }),
|
|
4543
|
+
"s"
|
|
4544
|
+
] });
|
|
4545
|
+
}
|
|
4396
4546
|
var DEFAULT_MAX_LENGTH = 6;
|
|
4397
4547
|
var MAX_SUPPORTED_LENGTH = 12;
|
|
4398
4548
|
var AUTO_FOCUS_DELAY_MS = 250;
|
|
@@ -4519,7 +4669,6 @@ function VerificationInline({
|
|
|
4519
4669
|
React.useEffect(() => {
|
|
4520
4670
|
if (prompt.subAction === "SubmissionInvalid") {
|
|
4521
4671
|
setErrored(true);
|
|
4522
|
-
setCode("");
|
|
4523
4672
|
lastSubmittedRef.current = null;
|
|
4524
4673
|
}
|
|
4525
4674
|
}, [prompt.subAction, prompt.userActionId]);
|
|
@@ -4598,7 +4747,7 @@ function VerificationInline({
|
|
|
4598
4747
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "payman-v2-ua-head", children: [
|
|
4599
4748
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ShieldCheck, { className: "payman-v2-ua-icon", size: 15, strokeWidth: 1.75, "aria-hidden": true }),
|
|
4600
4749
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "payman-v2-ua-title", children: "Verification required" }),
|
|
4601
|
-
typeof secondsLeft === "number" && !stale && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "payman-v2-ua-timer", children: expired ? "Expired" :
|
|
4750
|
+
typeof secondsLeft === "number" && !stale && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "payman-v2-ua-timer", children: expired ? "Expired" : /* @__PURE__ */ jsxRuntime.jsx(AnimatedDuration, { seconds: secondsLeft }) })
|
|
4602
4751
|
] }),
|
|
4603
4752
|
renderMarkdown ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "payman-v2-ua-markdown", children: /* @__PURE__ */ jsxRuntime.jsx(MarkdownRendererV2, { content: description }) }) : /* @__PURE__ */ jsxRuntime.jsx("p", { className: "payman-v2-ua-desc", children: description }),
|
|
4604
4753
|
stale ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "payman-v2-ua-stale", children: "This request is no longer available." }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
@@ -4670,6 +4819,228 @@ function VerificationInline({
|
|
|
4670
4819
|
] })
|
|
4671
4820
|
] });
|
|
4672
4821
|
}
|
|
4822
|
+
function AmountFieldV2({
|
|
4823
|
+
id,
|
|
4824
|
+
value,
|
|
4825
|
+
onChange,
|
|
4826
|
+
disabled,
|
|
4827
|
+
className,
|
|
4828
|
+
onEnter
|
|
4829
|
+
}) {
|
|
4830
|
+
const inputRef = React.useRef(null);
|
|
4831
|
+
const digits = digitsFromValue(value);
|
|
4832
|
+
const display = formatDigits(digits);
|
|
4833
|
+
React.useLayoutEffect(() => {
|
|
4834
|
+
const el = inputRef.current;
|
|
4835
|
+
if (el && document.activeElement === el) {
|
|
4836
|
+
el.setSelectionRange(el.value.length, el.value.length);
|
|
4837
|
+
}
|
|
4838
|
+
}, [display]);
|
|
4839
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4840
|
+
"input",
|
|
4841
|
+
{
|
|
4842
|
+
ref: inputRef,
|
|
4843
|
+
id,
|
|
4844
|
+
type: "text",
|
|
4845
|
+
inputMode: "decimal",
|
|
4846
|
+
autoComplete: "off",
|
|
4847
|
+
className,
|
|
4848
|
+
value: display,
|
|
4849
|
+
placeholder: "0.00",
|
|
4850
|
+
disabled,
|
|
4851
|
+
onChange: (e) => {
|
|
4852
|
+
onChange(valueFromDigits(digitsFromDisplay(e.target.value)));
|
|
4853
|
+
},
|
|
4854
|
+
onKeyDown: (e) => {
|
|
4855
|
+
if (e.key === "Enter") {
|
|
4856
|
+
e.preventDefault();
|
|
4857
|
+
onEnter?.();
|
|
4858
|
+
}
|
|
4859
|
+
},
|
|
4860
|
+
onFocus: (e) => {
|
|
4861
|
+
const el = e.currentTarget;
|
|
4862
|
+
requestAnimationFrame(() => el.setSelectionRange(el.value.length, el.value.length));
|
|
4863
|
+
}
|
|
4864
|
+
}
|
|
4865
|
+
);
|
|
4866
|
+
}
|
|
4867
|
+
function digitsFromDisplay(raw) {
|
|
4868
|
+
return raw.replace(/[^0-9]/g, "").replace(/^0+(?=\d)/, "").slice(-9);
|
|
4869
|
+
}
|
|
4870
|
+
function digitsFromValue(value) {
|
|
4871
|
+
const num = Number(value);
|
|
4872
|
+
if (!value || !Number.isFinite(num) || num <= 0) return "";
|
|
4873
|
+
return String(Math.round(num * 100));
|
|
4874
|
+
}
|
|
4875
|
+
function formatDigits(digits) {
|
|
4876
|
+
if (!digits) return "";
|
|
4877
|
+
const padded = digits.padStart(3, "0");
|
|
4878
|
+
const cents = padded.slice(-2);
|
|
4879
|
+
const whole = padded.slice(0, -2).replace(/^0+(?=\d)/, "") || "0";
|
|
4880
|
+
const grouped = whole.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
4881
|
+
return `${grouped}.${cents}`;
|
|
4882
|
+
}
|
|
4883
|
+
function valueFromDigits(digits) {
|
|
4884
|
+
if (!digits) return "";
|
|
4885
|
+
return (Number(digits) / 100).toString();
|
|
4886
|
+
}
|
|
4887
|
+
function findRootClassName(el) {
|
|
4888
|
+
const root = el?.closest(".payman-v2-root");
|
|
4889
|
+
return root instanceof HTMLElement ? root.className : "";
|
|
4890
|
+
}
|
|
4891
|
+
var MENU_MAX_HEIGHT = 240;
|
|
4892
|
+
var OPTION_HEIGHT = 34;
|
|
4893
|
+
var VIEWPORT_MARGIN = 8;
|
|
4894
|
+
function SelectFieldV2({
|
|
4895
|
+
id,
|
|
4896
|
+
value,
|
|
4897
|
+
options,
|
|
4898
|
+
onChange,
|
|
4899
|
+
disabled,
|
|
4900
|
+
error,
|
|
4901
|
+
placeholder = "Select\u2026"
|
|
4902
|
+
}) {
|
|
4903
|
+
const triggerRef = React.useRef(null);
|
|
4904
|
+
const listRef = React.useRef(null);
|
|
4905
|
+
const [open, setOpen] = React.useState(false);
|
|
4906
|
+
const [rect, setRect] = React.useState(null);
|
|
4907
|
+
const [activeIndex, setActiveIndex] = React.useState(-1);
|
|
4908
|
+
const [rootClassName, setRootClassName] = React.useState("");
|
|
4909
|
+
const selected = options.find((o) => o.const === value);
|
|
4910
|
+
React.useLayoutEffect(() => {
|
|
4911
|
+
if (!open) return;
|
|
4912
|
+
const place = () => {
|
|
4913
|
+
const el = triggerRef.current;
|
|
4914
|
+
if (!el) return;
|
|
4915
|
+
const r = el.getBoundingClientRect();
|
|
4916
|
+
const viewportH = window.innerHeight;
|
|
4917
|
+
const estimatedMenuH = Math.min(
|
|
4918
|
+
options.length * OPTION_HEIGHT + VIEWPORT_MARGIN,
|
|
4919
|
+
MENU_MAX_HEIGHT
|
|
4920
|
+
);
|
|
4921
|
+
const spaceBelow = viewportH - r.bottom;
|
|
4922
|
+
const spaceAbove = r.top;
|
|
4923
|
+
const openUp = spaceBelow < estimatedMenuH && spaceAbove > spaceBelow;
|
|
4924
|
+
setRect({ top: r.bottom, bottom: viewportH - r.top, left: r.left, width: r.width, openUp });
|
|
4925
|
+
setRootClassName(findRootClassName(el));
|
|
4926
|
+
};
|
|
4927
|
+
place();
|
|
4928
|
+
window.addEventListener("resize", place);
|
|
4929
|
+
window.addEventListener("scroll", place, true);
|
|
4930
|
+
return () => {
|
|
4931
|
+
window.removeEventListener("resize", place);
|
|
4932
|
+
window.removeEventListener("scroll", place, true);
|
|
4933
|
+
};
|
|
4934
|
+
}, [open, options.length]);
|
|
4935
|
+
React.useEffect(() => {
|
|
4936
|
+
if (!open) return;
|
|
4937
|
+
setActiveIndex(Math.max(0, options.findIndex((o) => o.const === value)));
|
|
4938
|
+
listRef.current?.focus();
|
|
4939
|
+
}, [open]);
|
|
4940
|
+
React.useEffect(() => {
|
|
4941
|
+
if (!open) return;
|
|
4942
|
+
const onDocDown = (e) => {
|
|
4943
|
+
const target = e.target;
|
|
4944
|
+
if (triggerRef.current?.contains(target) || listRef.current?.contains(target)) return;
|
|
4945
|
+
setOpen(false);
|
|
4946
|
+
};
|
|
4947
|
+
document.addEventListener("mousedown", onDocDown);
|
|
4948
|
+
return () => document.removeEventListener("mousedown", onDocDown);
|
|
4949
|
+
}, [open]);
|
|
4950
|
+
const commit = (opt) => {
|
|
4951
|
+
onChange(opt.const);
|
|
4952
|
+
setOpen(false);
|
|
4953
|
+
triggerRef.current?.focus();
|
|
4954
|
+
};
|
|
4955
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4956
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
4957
|
+
"button",
|
|
4958
|
+
{
|
|
4959
|
+
ref: triggerRef,
|
|
4960
|
+
id,
|
|
4961
|
+
type: "button",
|
|
4962
|
+
disabled,
|
|
4963
|
+
className: cn("payman-v2-ua-select-trigger", error && "payman-v2-ua-input-error"),
|
|
4964
|
+
"aria-haspopup": "listbox",
|
|
4965
|
+
"aria-expanded": open,
|
|
4966
|
+
onClick: () => setOpen((v) => !v),
|
|
4967
|
+
onKeyDown: (e) => {
|
|
4968
|
+
if (e.key === "ArrowDown" || e.key === "Enter" || e.key === " ") {
|
|
4969
|
+
e.preventDefault();
|
|
4970
|
+
setOpen(true);
|
|
4971
|
+
}
|
|
4972
|
+
},
|
|
4973
|
+
children: [
|
|
4974
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4975
|
+
"span",
|
|
4976
|
+
{
|
|
4977
|
+
className: cn(
|
|
4978
|
+
"payman-v2-ua-select-value",
|
|
4979
|
+
!selected && "payman-v2-ua-select-placeholder"
|
|
4980
|
+
),
|
|
4981
|
+
children: selected ? selected.title || selected.const : placeholder
|
|
4982
|
+
}
|
|
4983
|
+
),
|
|
4984
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { size: 14, className: "payman-v2-ua-select-chevron", "aria-hidden": true })
|
|
4985
|
+
]
|
|
4986
|
+
}
|
|
4987
|
+
),
|
|
4988
|
+
open && rect && typeof document !== "undefined" && reactDom.createPortal(
|
|
4989
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4990
|
+
"div",
|
|
4991
|
+
{
|
|
4992
|
+
ref: listRef,
|
|
4993
|
+
role: "listbox",
|
|
4994
|
+
className: cn(rootClassName, "payman-v2-ua-select-menu"),
|
|
4995
|
+
tabIndex: -1,
|
|
4996
|
+
style: {
|
|
4997
|
+
position: "fixed",
|
|
4998
|
+
left: rect.left,
|
|
4999
|
+
width: rect.width,
|
|
5000
|
+
height: "fit-content",
|
|
5001
|
+
maxHeight: MENU_MAX_HEIGHT,
|
|
5002
|
+
...rect.openUp ? { bottom: rect.bottom } : { top: rect.top }
|
|
5003
|
+
},
|
|
5004
|
+
onKeyDown: (e) => {
|
|
5005
|
+
if (e.key === "ArrowDown") {
|
|
5006
|
+
e.preventDefault();
|
|
5007
|
+
setActiveIndex((i) => Math.min(options.length - 1, i + 1));
|
|
5008
|
+
} else if (e.key === "ArrowUp") {
|
|
5009
|
+
e.preventDefault();
|
|
5010
|
+
setActiveIndex((i) => Math.max(0, i - 1));
|
|
5011
|
+
} else if (e.key === "Enter" || e.key === " ") {
|
|
5012
|
+
e.preventDefault();
|
|
5013
|
+
if (activeIndex >= 0) commit(options[activeIndex]);
|
|
5014
|
+
} else if (e.key === "Escape" || e.key === "Tab") {
|
|
5015
|
+
setOpen(false);
|
|
5016
|
+
triggerRef.current?.focus();
|
|
5017
|
+
}
|
|
5018
|
+
},
|
|
5019
|
+
children: options.map((opt, i) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5020
|
+
"div",
|
|
5021
|
+
{
|
|
5022
|
+
role: "option",
|
|
5023
|
+
"aria-selected": opt.const === value,
|
|
5024
|
+
className: cn(
|
|
5025
|
+
"payman-v2-ua-select-option",
|
|
5026
|
+
i === activeIndex && "payman-v2-ua-select-option-active",
|
|
5027
|
+
opt.const === value && "payman-v2-ua-select-option-selected"
|
|
5028
|
+
),
|
|
5029
|
+
onMouseEnter: () => setActiveIndex(i),
|
|
5030
|
+
onClick: () => commit(opt),
|
|
5031
|
+
children: [
|
|
5032
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: opt.title || opt.const }),
|
|
5033
|
+
opt.const === value && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { size: 13, "aria-hidden": true })
|
|
5034
|
+
]
|
|
5035
|
+
},
|
|
5036
|
+
opt.const
|
|
5037
|
+
))
|
|
5038
|
+
}
|
|
5039
|
+
),
|
|
5040
|
+
document.body
|
|
5041
|
+
)
|
|
5042
|
+
] });
|
|
5043
|
+
}
|
|
4673
5044
|
function SchemaFormInline({
|
|
4674
5045
|
prompt,
|
|
4675
5046
|
secondsLeft,
|
|
@@ -4715,7 +5086,7 @@ function SchemaFormInline({
|
|
|
4715
5086
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "payman-v2-ua-head", children: [
|
|
4716
5087
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Pencil, { className: "payman-v2-ua-icon", size: 14, strokeWidth: 1.75, "aria-hidden": true }),
|
|
4717
5088
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "payman-v2-ua-title", children: "Action required" }),
|
|
4718
|
-
typeof secondsLeft === "number" && !stale && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "payman-v2-ua-timer", children: expired ? "Expired" :
|
|
5089
|
+
typeof secondsLeft === "number" && !stale && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "payman-v2-ua-timer", children: expired ? "Expired" : /* @__PURE__ */ jsxRuntime.jsx(AnimatedDuration, { seconds: secondsLeft }) })
|
|
4719
5090
|
] }),
|
|
4720
5091
|
prompt.message?.trim() && (renderMarkdown ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "payman-v2-ua-markdown", children: /* @__PURE__ */ jsxRuntime.jsx(MarkdownRendererV2, { content: prompt.message }) }) : /* @__PURE__ */ jsxRuntime.jsx("p", { className: "payman-v2-ua-desc", children: prompt.message })),
|
|
4721
5092
|
stale ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "payman-v2-ua-stale", children: "This request is no longer available." }) : fields.length === 0 ? null : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "payman-v2-ua-form", children: fields.map(([key, field]) => {
|
|
@@ -4747,26 +5118,33 @@ function SchemaFormInline({
|
|
|
4747
5118
|
required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "payman-v2-ua-req", children: "*" })
|
|
4748
5119
|
] }),
|
|
4749
5120
|
field.description && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "payman-v2-ua-hint", children: field.description }),
|
|
4750
|
-
widget === "select" ? /* @__PURE__ */ jsxRuntime.
|
|
4751
|
-
|
|
5121
|
+
widget === "select" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
5122
|
+
SelectFieldV2,
|
|
4752
5123
|
{
|
|
4753
5124
|
id: fieldId,
|
|
4754
|
-
className: cn("payman-v2-ua-input", err && "payman-v2-ua-input-error"),
|
|
4755
5125
|
value: String(values[key] ?? ""),
|
|
5126
|
+
options: getOptions(field),
|
|
4756
5127
|
disabled: locked,
|
|
4757
|
-
|
|
4758
|
-
|
|
4759
|
-
|
|
4760
|
-
|
|
4761
|
-
|
|
5128
|
+
error: Boolean(err),
|
|
5129
|
+
onChange: (v) => setValue(key, v)
|
|
5130
|
+
}
|
|
5131
|
+
) : widget === "decimal" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
5132
|
+
AmountFieldV2,
|
|
5133
|
+
{
|
|
5134
|
+
id: fieldId,
|
|
5135
|
+
value: String(values[key] ?? ""),
|
|
5136
|
+
disabled: locked,
|
|
5137
|
+
className: cn("payman-v2-ua-input", err && "payman-v2-ua-input-error"),
|
|
5138
|
+
onChange: (v) => setValue(key, v),
|
|
5139
|
+
onEnter: handleSubmit
|
|
4762
5140
|
}
|
|
4763
5141
|
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
4764
5142
|
"input",
|
|
4765
5143
|
{
|
|
4766
5144
|
id: fieldId,
|
|
4767
|
-
type: widget === "integer"
|
|
4768
|
-
inputMode: widget === "integer" ? "numeric" :
|
|
4769
|
-
step: widget === "
|
|
5145
|
+
type: widget === "integer" ? "number" : "text",
|
|
5146
|
+
inputMode: widget === "integer" ? "numeric" : void 0,
|
|
5147
|
+
step: widget === "integer" ? "1" : void 0,
|
|
4770
5148
|
className: cn("payman-v2-ua-input", err && "payman-v2-ua-input-error"),
|
|
4771
5149
|
value: String(values[key] ?? ""),
|
|
4772
5150
|
disabled: locked,
|
|
@@ -4863,12 +5241,16 @@ function UserActionInline({
|
|
|
4863
5241
|
onSubmit,
|
|
4864
5242
|
onCancel,
|
|
4865
5243
|
onResend,
|
|
4866
|
-
onExpired
|
|
5244
|
+
onExpired,
|
|
5245
|
+
suppressExpiredNote
|
|
4867
5246
|
}) {
|
|
4868
5247
|
const [secondsLeft, expired] = useExpiryCountdown(prompt);
|
|
4869
5248
|
React.useEffect(() => {
|
|
4870
5249
|
if (expired && prompt.kind !== "notification") onExpired?.();
|
|
4871
5250
|
}, [expired, onExpired, prompt.kind]);
|
|
5251
|
+
if (expired && prompt.kind !== "notification" && suppressExpiredNote) {
|
|
5252
|
+
return null;
|
|
5253
|
+
}
|
|
4872
5254
|
let body;
|
|
4873
5255
|
if (expired && prompt.kind !== "notification") {
|
|
4874
5256
|
const note = {
|
|
@@ -4929,6 +5311,9 @@ function getPromptViewKey(prompt) {
|
|
|
4929
5311
|
prompt.message ?? ""
|
|
4930
5312
|
].join(PROMPT_KEY_SEPARATOR);
|
|
4931
5313
|
}
|
|
5314
|
+
function getPromptMountKey(prompt) {
|
|
5315
|
+
return [getPromptSlotKey(prompt), prompt.userActionId].join(PROMPT_KEY_SEPARATOR);
|
|
5316
|
+
}
|
|
4932
5317
|
var MessageListV2 = React.forwardRef(
|
|
4933
5318
|
function MessageListV22({
|
|
4934
5319
|
messages,
|
|
@@ -4940,6 +5325,7 @@ var MessageListV2 = React.forwardRef(
|
|
|
4940
5325
|
messageActions,
|
|
4941
5326
|
retryDisabled = false,
|
|
4942
5327
|
userActionPrompts,
|
|
5328
|
+
dockedUserActionId,
|
|
4943
5329
|
notifications,
|
|
4944
5330
|
onSubmitUserAction,
|
|
4945
5331
|
onCancelUserAction,
|
|
@@ -5048,10 +5434,11 @@ var MessageListV2 = React.forwardRef(
|
|
|
5048
5434
|
}, [userActionPrompts]);
|
|
5049
5435
|
const visibleUserActionPrompts = React.useMemo(
|
|
5050
5436
|
() => userActionPrompts?.filter((prompt) => {
|
|
5437
|
+
if (prompt.userActionId === dockedUserActionId) return false;
|
|
5051
5438
|
const promptKey = getPromptViewKey(prompt);
|
|
5052
5439
|
return !expiredPromptViewState[promptKey]?.hidden;
|
|
5053
5440
|
}),
|
|
5054
|
-
[expiredPromptViewState, userActionPrompts]
|
|
5441
|
+
[dockedUserActionId, expiredPromptViewState, userActionPrompts]
|
|
5055
5442
|
);
|
|
5056
5443
|
const pinToBottom = React.useCallback((behavior = "instant") => {
|
|
5057
5444
|
const el = scrollRef.current;
|
|
@@ -5200,7 +5587,7 @@ var MessageListV2 = React.forwardRef(
|
|
|
5200
5587
|
onResend: onResendUserAction ?? noop,
|
|
5201
5588
|
onExpired: () => handleUserActionExpired(promptKey, prompt.userActionId)
|
|
5202
5589
|
},
|
|
5203
|
-
|
|
5590
|
+
getPromptMountKey(prompt)
|
|
5204
5591
|
);
|
|
5205
5592
|
})
|
|
5206
5593
|
]
|
|
@@ -5746,10 +6133,455 @@ var ChatInputV2 = React.forwardRef(
|
|
|
5746
6133
|
] });
|
|
5747
6134
|
}
|
|
5748
6135
|
);
|
|
5749
|
-
|
|
5750
|
-
|
|
5751
|
-
|
|
5752
|
-
|
|
6136
|
+
function dockKey(prompt) {
|
|
6137
|
+
return `${prompt.toolCallId || prompt.userActionId}:${prompt.userActionId}`;
|
|
6138
|
+
}
|
|
6139
|
+
function UserActionDock({
|
|
6140
|
+
prompt,
|
|
6141
|
+
onSubmit,
|
|
6142
|
+
onCancel,
|
|
6143
|
+
onResend,
|
|
6144
|
+
onExpired,
|
|
6145
|
+
children
|
|
6146
|
+
}) {
|
|
6147
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "payman-v2-ua-dock", children: /* @__PURE__ */ jsxRuntime.jsx(framerMotion.motion.div, { layout: "size", transition: { duration: 0.3, ease: [0.2, 0, 0, 1] }, children: /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { mode: "wait", initial: false, children: prompt ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
6148
|
+
framerMotion.motion.div,
|
|
6149
|
+
{
|
|
6150
|
+
initial: { opacity: 0 },
|
|
6151
|
+
animate: { opacity: 1 },
|
|
6152
|
+
exit: { opacity: 0 },
|
|
6153
|
+
transition: { duration: 0.15 },
|
|
6154
|
+
className: "payman-v2-ua-dock-panel",
|
|
6155
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6156
|
+
UserActionInline,
|
|
6157
|
+
{
|
|
6158
|
+
prompt,
|
|
6159
|
+
onSubmit,
|
|
6160
|
+
onCancel,
|
|
6161
|
+
onResend,
|
|
6162
|
+
onExpired: () => onExpired?.(prompt.userActionId),
|
|
6163
|
+
suppressExpiredNote: true
|
|
6164
|
+
}
|
|
6165
|
+
)
|
|
6166
|
+
},
|
|
6167
|
+
dockKey(prompt)
|
|
6168
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
6169
|
+
framerMotion.motion.div,
|
|
6170
|
+
{
|
|
6171
|
+
initial: { opacity: 0 },
|
|
6172
|
+
animate: { opacity: 1 },
|
|
6173
|
+
exit: { opacity: 0 },
|
|
6174
|
+
transition: { duration: 0.15 },
|
|
6175
|
+
children
|
|
6176
|
+
},
|
|
6177
|
+
"composer"
|
|
6178
|
+
) }) }) });
|
|
6179
|
+
}
|
|
6180
|
+
function clamp(value) {
|
|
6181
|
+
return Math.max(0, Math.min(1, value));
|
|
6182
|
+
}
|
|
6183
|
+
function ensureFrameSize(frame, rows, cols) {
|
|
6184
|
+
const result = [];
|
|
6185
|
+
for (let r = 0; r < rows; r++) {
|
|
6186
|
+
const row = frame[r] || [];
|
|
6187
|
+
result.push([]);
|
|
6188
|
+
for (let c = 0; c < cols; c++) {
|
|
6189
|
+
result[r][c] = row[c] ?? 0;
|
|
6190
|
+
}
|
|
6191
|
+
}
|
|
6192
|
+
return result;
|
|
6193
|
+
}
|
|
6194
|
+
function useAnimation(frames, options) {
|
|
6195
|
+
const [frameIndex, setFrameIndex] = React.useState(0);
|
|
6196
|
+
const [isPlaying, setIsPlaying] = React.useState(options.autoplay);
|
|
6197
|
+
const frameIdRef = React.useRef(void 0);
|
|
6198
|
+
const lastTimeRef = React.useRef(0);
|
|
6199
|
+
const accumulatorRef = React.useRef(0);
|
|
6200
|
+
React.useEffect(() => {
|
|
6201
|
+
if (!frames || frames.length === 0 || !isPlaying) {
|
|
6202
|
+
return;
|
|
6203
|
+
}
|
|
6204
|
+
const frameInterval = 1e3 / options.fps;
|
|
6205
|
+
const animate = (currentTime) => {
|
|
6206
|
+
if (lastTimeRef.current === 0) {
|
|
6207
|
+
lastTimeRef.current = currentTime;
|
|
6208
|
+
}
|
|
6209
|
+
const deltaTime = currentTime - lastTimeRef.current;
|
|
6210
|
+
lastTimeRef.current = currentTime;
|
|
6211
|
+
accumulatorRef.current += deltaTime;
|
|
6212
|
+
if (accumulatorRef.current >= frameInterval) {
|
|
6213
|
+
accumulatorRef.current -= frameInterval;
|
|
6214
|
+
setFrameIndex((prev) => {
|
|
6215
|
+
const next = prev + 1;
|
|
6216
|
+
if (next >= frames.length) {
|
|
6217
|
+
if (options.loop) {
|
|
6218
|
+
options.onFrame?.(0);
|
|
6219
|
+
return 0;
|
|
6220
|
+
} else {
|
|
6221
|
+
setIsPlaying(false);
|
|
6222
|
+
return prev;
|
|
6223
|
+
}
|
|
6224
|
+
}
|
|
6225
|
+
options.onFrame?.(next);
|
|
6226
|
+
return next;
|
|
6227
|
+
});
|
|
6228
|
+
}
|
|
6229
|
+
frameIdRef.current = requestAnimationFrame(animate);
|
|
6230
|
+
};
|
|
6231
|
+
frameIdRef.current = requestAnimationFrame(animate);
|
|
6232
|
+
return () => {
|
|
6233
|
+
if (frameIdRef.current) {
|
|
6234
|
+
cancelAnimationFrame(frameIdRef.current);
|
|
6235
|
+
}
|
|
6236
|
+
};
|
|
6237
|
+
}, [frames, isPlaying, options.fps, options.loop, options.onFrame]);
|
|
6238
|
+
React.useEffect(() => {
|
|
6239
|
+
setFrameIndex(0);
|
|
6240
|
+
setIsPlaying(options.autoplay);
|
|
6241
|
+
lastTimeRef.current = 0;
|
|
6242
|
+
accumulatorRef.current = 0;
|
|
6243
|
+
}, [frames, options.autoplay]);
|
|
6244
|
+
return { frameIndex, isPlaying };
|
|
6245
|
+
}
|
|
6246
|
+
function emptyFrame(rows, cols) {
|
|
6247
|
+
return Array.from({ length: rows }, () => Array(cols).fill(0));
|
|
6248
|
+
}
|
|
6249
|
+
function setPixel(frame, row, col, value) {
|
|
6250
|
+
if (row >= 0 && row < frame.length && col >= 0 && col < frame[0].length) {
|
|
6251
|
+
frame[row][col] = value;
|
|
6252
|
+
}
|
|
6253
|
+
}
|
|
6254
|
+
var loader = (() => {
|
|
6255
|
+
const frames = [];
|
|
6256
|
+
const size = 7;
|
|
6257
|
+
const center = 3;
|
|
6258
|
+
const radius = 2.5;
|
|
6259
|
+
for (let frame = 0; frame < 12; frame++) {
|
|
6260
|
+
const f = emptyFrame(size, size);
|
|
6261
|
+
for (let i = 0; i < 8; i++) {
|
|
6262
|
+
const angle = frame / 12 * Math.PI * 2 + i / 8 * Math.PI * 2;
|
|
6263
|
+
const x = Math.round(center + Math.cos(angle) * radius);
|
|
6264
|
+
const y = Math.round(center + Math.sin(angle) * radius);
|
|
6265
|
+
const brightness = 1 - i / 10;
|
|
6266
|
+
setPixel(f, y, x, Math.max(0.2, brightness));
|
|
6267
|
+
}
|
|
6268
|
+
frames.push(f);
|
|
6269
|
+
}
|
|
6270
|
+
return frames;
|
|
6271
|
+
})();
|
|
6272
|
+
var pulse = (() => {
|
|
6273
|
+
const frames = [];
|
|
6274
|
+
const size = 7;
|
|
6275
|
+
const center = 3;
|
|
6276
|
+
for (let frame = 0; frame < 16; frame++) {
|
|
6277
|
+
const f = emptyFrame(size, size);
|
|
6278
|
+
const phase = frame / 16 * Math.PI * 2;
|
|
6279
|
+
const intensity = (Math.sin(phase) + 1) / 2;
|
|
6280
|
+
setPixel(f, center, center, 1);
|
|
6281
|
+
const radius = Math.floor((1 - intensity) * 3) + 1;
|
|
6282
|
+
for (let dy = -radius; dy <= radius; dy++) {
|
|
6283
|
+
for (let dx = -radius; dx <= radius; dx++) {
|
|
6284
|
+
const dist = Math.sqrt(dx * dx + dy * dy);
|
|
6285
|
+
if (Math.abs(dist - radius) < 0.7) {
|
|
6286
|
+
setPixel(f, center + dy, center + dx, intensity * 0.6);
|
|
6287
|
+
}
|
|
6288
|
+
}
|
|
6289
|
+
}
|
|
6290
|
+
frames.push(f);
|
|
6291
|
+
}
|
|
6292
|
+
return frames;
|
|
6293
|
+
})();
|
|
6294
|
+
function vu(columns, levels) {
|
|
6295
|
+
const rows = 7;
|
|
6296
|
+
const frame = emptyFrame(rows, columns);
|
|
6297
|
+
for (let col = 0; col < Math.min(columns, levels.length); col++) {
|
|
6298
|
+
const level = Math.max(0, Math.min(1, levels[col]));
|
|
6299
|
+
const height = Math.floor(level * rows);
|
|
6300
|
+
for (let row = 0; row < rows; row++) {
|
|
6301
|
+
const rowFromBottom = rows - 1 - row;
|
|
6302
|
+
if (rowFromBottom < height) {
|
|
6303
|
+
let brightness = 1;
|
|
6304
|
+
if (row < rows * 0.3) {
|
|
6305
|
+
brightness = 1;
|
|
6306
|
+
} else if (row < rows * 0.6) {
|
|
6307
|
+
brightness = 0.8;
|
|
6308
|
+
} else {
|
|
6309
|
+
brightness = 0.6;
|
|
6310
|
+
}
|
|
6311
|
+
frame[row][col] = brightness;
|
|
6312
|
+
}
|
|
6313
|
+
}
|
|
6314
|
+
}
|
|
6315
|
+
return frame;
|
|
6316
|
+
}
|
|
6317
|
+
var wave = (() => {
|
|
6318
|
+
const frames = [];
|
|
6319
|
+
const rows = 7;
|
|
6320
|
+
const cols = 7;
|
|
6321
|
+
for (let frame = 0; frame < 24; frame++) {
|
|
6322
|
+
const f = emptyFrame(rows, cols);
|
|
6323
|
+
const phase = frame / 24 * Math.PI * 2;
|
|
6324
|
+
for (let col = 0; col < cols; col++) {
|
|
6325
|
+
const colPhase = col / cols * Math.PI * 2;
|
|
6326
|
+
const height = Math.sin(phase + colPhase) * 2.5 + 3.5;
|
|
6327
|
+
const row = Math.floor(height);
|
|
6328
|
+
if (row >= 0 && row < rows) {
|
|
6329
|
+
setPixel(f, row, col, 1);
|
|
6330
|
+
const frac = height - row;
|
|
6331
|
+
if (row > 0) setPixel(f, row - 1, col, 1 - frac);
|
|
6332
|
+
if (row < rows - 1) setPixel(f, row + 1, col, frac);
|
|
6333
|
+
}
|
|
6334
|
+
}
|
|
6335
|
+
frames.push(f);
|
|
6336
|
+
}
|
|
6337
|
+
return frames;
|
|
6338
|
+
})();
|
|
6339
|
+
var snake = (() => {
|
|
6340
|
+
const frames = [];
|
|
6341
|
+
const rows = 7;
|
|
6342
|
+
const cols = 7;
|
|
6343
|
+
const path = [];
|
|
6344
|
+
let x = 0;
|
|
6345
|
+
let y = 0;
|
|
6346
|
+
let dx = 1;
|
|
6347
|
+
let dy = 0;
|
|
6348
|
+
const visited = /* @__PURE__ */ new Set();
|
|
6349
|
+
while (path.length < rows * cols) {
|
|
6350
|
+
path.push([y, x]);
|
|
6351
|
+
visited.add(`${y},${x}`);
|
|
6352
|
+
const nextX = x + dx;
|
|
6353
|
+
const nextY = y + dy;
|
|
6354
|
+
if (nextX >= 0 && nextX < cols && nextY >= 0 && nextY < rows && !visited.has(`${nextY},${nextX}`)) {
|
|
6355
|
+
x = nextX;
|
|
6356
|
+
y = nextY;
|
|
6357
|
+
} else {
|
|
6358
|
+
const newDx = -dy;
|
|
6359
|
+
const newDy = dx;
|
|
6360
|
+
dx = newDx;
|
|
6361
|
+
dy = newDy;
|
|
6362
|
+
const nextX2 = x + dx;
|
|
6363
|
+
const nextY2 = y + dy;
|
|
6364
|
+
if (nextX2 >= 0 && nextX2 < cols && nextY2 >= 0 && nextY2 < rows && !visited.has(`${nextY2},${nextX2}`)) {
|
|
6365
|
+
x = nextX2;
|
|
6366
|
+
y = nextY2;
|
|
6367
|
+
} else {
|
|
6368
|
+
break;
|
|
6369
|
+
}
|
|
6370
|
+
}
|
|
6371
|
+
}
|
|
6372
|
+
const snakeLength = 5;
|
|
6373
|
+
for (let frame = 0; frame < path.length; frame++) {
|
|
6374
|
+
const f = emptyFrame(rows, cols);
|
|
6375
|
+
for (let i = 0; i < snakeLength; i++) {
|
|
6376
|
+
const idx = frame - i;
|
|
6377
|
+
if (idx >= 0 && idx < path.length) {
|
|
6378
|
+
const [y2, x2] = path[idx];
|
|
6379
|
+
const brightness = 1 - i / snakeLength;
|
|
6380
|
+
setPixel(f, y2, x2, brightness);
|
|
6381
|
+
}
|
|
6382
|
+
}
|
|
6383
|
+
frames.push(f);
|
|
6384
|
+
}
|
|
6385
|
+
return frames;
|
|
6386
|
+
})();
|
|
6387
|
+
var Matrix = React__namespace.forwardRef(
|
|
6388
|
+
({
|
|
6389
|
+
rows,
|
|
6390
|
+
cols,
|
|
6391
|
+
pattern,
|
|
6392
|
+
frames,
|
|
6393
|
+
fps = 12,
|
|
6394
|
+
autoplay = true,
|
|
6395
|
+
loop = true,
|
|
6396
|
+
size = 10,
|
|
6397
|
+
gap = 2,
|
|
6398
|
+
palette = {
|
|
6399
|
+
on: "currentColor",
|
|
6400
|
+
off: "var(--muted-foreground)"
|
|
6401
|
+
},
|
|
6402
|
+
brightness = 1,
|
|
6403
|
+
ariaLabel,
|
|
6404
|
+
onFrame,
|
|
6405
|
+
mode = "default",
|
|
6406
|
+
levels,
|
|
6407
|
+
className,
|
|
6408
|
+
...props
|
|
6409
|
+
}, ref) => {
|
|
6410
|
+
const { frameIndex } = useAnimation(frames, {
|
|
6411
|
+
fps,
|
|
6412
|
+
autoplay: autoplay && !pattern,
|
|
6413
|
+
loop,
|
|
6414
|
+
onFrame
|
|
6415
|
+
});
|
|
6416
|
+
const currentFrame = React.useMemo(() => {
|
|
6417
|
+
if (mode === "vu" && levels && levels.length > 0) {
|
|
6418
|
+
return ensureFrameSize(vu(cols, levels), rows, cols);
|
|
6419
|
+
}
|
|
6420
|
+
if (pattern) {
|
|
6421
|
+
return ensureFrameSize(pattern, rows, cols);
|
|
6422
|
+
}
|
|
6423
|
+
if (frames && frames.length > 0) {
|
|
6424
|
+
return ensureFrameSize(frames[frameIndex] || frames[0], rows, cols);
|
|
6425
|
+
}
|
|
6426
|
+
return ensureFrameSize([], rows, cols);
|
|
6427
|
+
}, [pattern, frames, frameIndex, rows, cols, mode, levels]);
|
|
6428
|
+
const cellPositions = React.useMemo(() => {
|
|
6429
|
+
const positions = [];
|
|
6430
|
+
for (let row = 0; row < rows; row++) {
|
|
6431
|
+
positions[row] = [];
|
|
6432
|
+
for (let col = 0; col < cols; col++) {
|
|
6433
|
+
positions[row][col] = {
|
|
6434
|
+
x: col * (size + gap),
|
|
6435
|
+
y: row * (size + gap)
|
|
6436
|
+
};
|
|
6437
|
+
}
|
|
6438
|
+
}
|
|
6439
|
+
return positions;
|
|
6440
|
+
}, [rows, cols, size, gap]);
|
|
6441
|
+
const svgDimensions = React.useMemo(() => {
|
|
6442
|
+
return {
|
|
6443
|
+
width: cols * (size + gap) - gap,
|
|
6444
|
+
height: rows * (size + gap) - gap
|
|
6445
|
+
};
|
|
6446
|
+
}, [rows, cols, size, gap]);
|
|
6447
|
+
const isAnimating = !pattern && frames && frames.length > 0;
|
|
6448
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
6449
|
+
"div",
|
|
6450
|
+
{
|
|
6451
|
+
ref,
|
|
6452
|
+
role: "img",
|
|
6453
|
+
"aria-label": ariaLabel ?? "matrix display",
|
|
6454
|
+
"aria-live": isAnimating ? "polite" : void 0,
|
|
6455
|
+
className: cn("relative inline-block", className),
|
|
6456
|
+
style: {
|
|
6457
|
+
"--matrix-on": palette.on,
|
|
6458
|
+
"--matrix-off": palette.off,
|
|
6459
|
+
"--matrix-gap": `${gap}px`,
|
|
6460
|
+
"--matrix-size": `${size}px`
|
|
6461
|
+
},
|
|
6462
|
+
...props,
|
|
6463
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6464
|
+
"svg",
|
|
6465
|
+
{
|
|
6466
|
+
width: svgDimensions.width,
|
|
6467
|
+
height: svgDimensions.height,
|
|
6468
|
+
viewBox: `0 0 ${svgDimensions.width} ${svgDimensions.height}`,
|
|
6469
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
6470
|
+
className: "block",
|
|
6471
|
+
style: { overflow: "visible" },
|
|
6472
|
+
children: [
|
|
6473
|
+
/* @__PURE__ */ jsxRuntime.jsxs("defs", { children: [
|
|
6474
|
+
/* @__PURE__ */ jsxRuntime.jsxs("radialGradient", { id: "matrix-pixel-on", cx: "50%", cy: "50%", r: "50%", children: [
|
|
6475
|
+
/* @__PURE__ */ jsxRuntime.jsx("stop", { offset: "0%", stopColor: "var(--matrix-on)", stopOpacity: "1" }),
|
|
6476
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6477
|
+
"stop",
|
|
6478
|
+
{
|
|
6479
|
+
offset: "70%",
|
|
6480
|
+
stopColor: "var(--matrix-on)",
|
|
6481
|
+
stopOpacity: "0.85"
|
|
6482
|
+
}
|
|
6483
|
+
),
|
|
6484
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6485
|
+
"stop",
|
|
6486
|
+
{
|
|
6487
|
+
offset: "100%",
|
|
6488
|
+
stopColor: "var(--matrix-on)",
|
|
6489
|
+
stopOpacity: "0.6"
|
|
6490
|
+
}
|
|
6491
|
+
)
|
|
6492
|
+
] }),
|
|
6493
|
+
/* @__PURE__ */ jsxRuntime.jsxs("radialGradient", { id: "matrix-pixel-off", cx: "50%", cy: "50%", r: "50%", children: [
|
|
6494
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6495
|
+
"stop",
|
|
6496
|
+
{
|
|
6497
|
+
offset: "0%",
|
|
6498
|
+
stopColor: "var(--muted-foreground)",
|
|
6499
|
+
stopOpacity: "1"
|
|
6500
|
+
}
|
|
6501
|
+
),
|
|
6502
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6503
|
+
"stop",
|
|
6504
|
+
{
|
|
6505
|
+
offset: "100%",
|
|
6506
|
+
stopColor: "var(--muted-foreground)",
|
|
6507
|
+
stopOpacity: "0.7"
|
|
6508
|
+
}
|
|
6509
|
+
)
|
|
6510
|
+
] }),
|
|
6511
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
6512
|
+
"filter",
|
|
6513
|
+
{
|
|
6514
|
+
id: "matrix-glow",
|
|
6515
|
+
x: "-50%",
|
|
6516
|
+
y: "-50%",
|
|
6517
|
+
width: "200%",
|
|
6518
|
+
height: "200%",
|
|
6519
|
+
children: [
|
|
6520
|
+
/* @__PURE__ */ jsxRuntime.jsx("feGaussianBlur", { stdDeviation: "2", result: "blur" }),
|
|
6521
|
+
/* @__PURE__ */ jsxRuntime.jsx("feComposite", { in: "SourceGraphic", in2: "blur", operator: "over" })
|
|
6522
|
+
]
|
|
6523
|
+
}
|
|
6524
|
+
)
|
|
6525
|
+
] }),
|
|
6526
|
+
/* @__PURE__ */ jsxRuntime.jsx("style", { children: `
|
|
6527
|
+
.matrix-pixel {
|
|
6528
|
+
transition: opacity 300ms ease-out, transform 150ms ease-out;
|
|
6529
|
+
transform-origin: center;
|
|
6530
|
+
transform-box: fill-box;
|
|
6531
|
+
}
|
|
6532
|
+
.matrix-pixel-active {
|
|
6533
|
+
filter: url(#matrix-glow);
|
|
6534
|
+
}
|
|
6535
|
+
` }),
|
|
6536
|
+
currentFrame.map(
|
|
6537
|
+
(row, rowIndex) => row.map((value, colIndex) => {
|
|
6538
|
+
const pos = cellPositions[rowIndex]?.[colIndex];
|
|
6539
|
+
if (!pos) return null;
|
|
6540
|
+
const opacity = clamp(brightness * value);
|
|
6541
|
+
const isActive = opacity > 0.5;
|
|
6542
|
+
const isOn = opacity > 0.05;
|
|
6543
|
+
const fill = isOn ? "url(#matrix-pixel-on)" : "url(#matrix-pixel-off)";
|
|
6544
|
+
const scale = isActive ? 1.1 : 1;
|
|
6545
|
+
const radius = size / 2 * 0.9;
|
|
6546
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
6547
|
+
"circle",
|
|
6548
|
+
{
|
|
6549
|
+
className: cn(
|
|
6550
|
+
"matrix-pixel",
|
|
6551
|
+
isActive && "matrix-pixel-active",
|
|
6552
|
+
!isOn && "opacity-20 dark:opacity-[0.1]"
|
|
6553
|
+
),
|
|
6554
|
+
cx: pos.x + size / 2,
|
|
6555
|
+
cy: pos.y + size / 2,
|
|
6556
|
+
r: radius,
|
|
6557
|
+
fill,
|
|
6558
|
+
opacity: isOn ? opacity : 0.1,
|
|
6559
|
+
style: {
|
|
6560
|
+
transform: `scale(${scale})`
|
|
6561
|
+
}
|
|
6562
|
+
},
|
|
6563
|
+
`${rowIndex}-${colIndex}`
|
|
6564
|
+
);
|
|
6565
|
+
})
|
|
6566
|
+
)
|
|
6567
|
+
]
|
|
6568
|
+
}
|
|
6569
|
+
)
|
|
6570
|
+
}
|
|
6571
|
+
);
|
|
6572
|
+
}
|
|
6573
|
+
);
|
|
6574
|
+
Matrix.displayName = "Matrix";
|
|
6575
|
+
var DEFAULT_SIZE = 22;
|
|
6576
|
+
var MATRIX_GRID = 7;
|
|
6577
|
+
var MATRIX_ON = "var(--payman-v2-matrix-color)";
|
|
6578
|
+
var MATRIX_PRESETS = [
|
|
6579
|
+
{ frames: loader, fps: 8 },
|
|
6580
|
+
{ frames: wave, fps: 14 },
|
|
6581
|
+
{ frames: snake, fps: 16 },
|
|
6582
|
+
{ frames: pulse, fps: 12 }
|
|
6583
|
+
];
|
|
6584
|
+
var PRESET_ROTATE_MS = 1e4;
|
|
5753
6585
|
function useElapsedSeconds(isStreaming) {
|
|
5754
6586
|
const [elapsed, setElapsed] = React.useState(0);
|
|
5755
6587
|
const startRef = React.useRef(null);
|
|
@@ -5770,12 +6602,37 @@ function useElapsedSeconds(isStreaming) {
|
|
|
5770
6602
|
}, [isStreaming]);
|
|
5771
6603
|
return elapsed;
|
|
5772
6604
|
}
|
|
6605
|
+
function useMatrixPresetIndex(isStreaming) {
|
|
6606
|
+
const [index, setIndex] = React.useState(0);
|
|
6607
|
+
React.useEffect(() => {
|
|
6608
|
+
if (!isStreaming) return;
|
|
6609
|
+
setIndex(0);
|
|
6610
|
+
const id = setInterval(() => {
|
|
6611
|
+
setIndex((prev) => (prev + 1) % MATRIX_PRESETS.length);
|
|
6612
|
+
}, PRESET_ROTATE_MS);
|
|
6613
|
+
return () => clearInterval(id);
|
|
6614
|
+
}, [isStreaming]);
|
|
6615
|
+
return index;
|
|
6616
|
+
}
|
|
6617
|
+
function formatElapsed(totalSeconds) {
|
|
6618
|
+
if (totalSeconds < 60) return `${totalSeconds}s`;
|
|
6619
|
+
const minutes = Math.floor(totalSeconds / 60);
|
|
6620
|
+
const seconds = totalSeconds % 60;
|
|
6621
|
+
return `${minutes}m ${seconds}s`;
|
|
6622
|
+
}
|
|
5773
6623
|
function StreamingIndicatorV2({
|
|
5774
6624
|
isStreaming,
|
|
5775
6625
|
loadingAnimation
|
|
5776
6626
|
}) {
|
|
5777
6627
|
const size = loadingAnimation?.size ?? DEFAULT_SIZE;
|
|
5778
6628
|
const elapsed = useElapsedSeconds(isStreaming);
|
|
6629
|
+
const presetIndex = useMatrixPresetIndex(isStreaming);
|
|
6630
|
+
const preset = MATRIX_PRESETS[presetIndex];
|
|
6631
|
+
const gap = 1;
|
|
6632
|
+
const cell = React.useMemo(
|
|
6633
|
+
() => Math.max(2, Math.round((size - (MATRIX_GRID - 1) * gap) / MATRIX_GRID)),
|
|
6634
|
+
[size]
|
|
6635
|
+
);
|
|
5779
6636
|
return /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: isStreaming && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5780
6637
|
framerMotion.motion.div,
|
|
5781
6638
|
{
|
|
@@ -5791,21 +6648,62 @@ function StreamingIndicatorV2({
|
|
|
5791
6648
|
{
|
|
5792
6649
|
className: "payman-v2-streaming-indicator-glyph",
|
|
5793
6650
|
style: { width: size, height: size },
|
|
5794
|
-
children:
|
|
5795
|
-
|
|
5796
|
-
|
|
5797
|
-
|
|
5798
|
-
|
|
5799
|
-
|
|
5800
|
-
|
|
5801
|
-
|
|
6651
|
+
children: loadingAnimation?.src ? (
|
|
6652
|
+
// Consumer override: render their Lottie animation.
|
|
6653
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6654
|
+
dotlottieReact.DotLottieReact,
|
|
6655
|
+
{
|
|
6656
|
+
src: loadingAnimation.src,
|
|
6657
|
+
loop: true,
|
|
6658
|
+
autoplay: true,
|
|
6659
|
+
style: { width: "100%", height: "100%" }
|
|
6660
|
+
}
|
|
6661
|
+
)
|
|
6662
|
+
) : (
|
|
6663
|
+
// Default: dot-matrix glyph, cycling presets +
|
|
6664
|
+
// Payman brand tint. Each preset lives in its own
|
|
6665
|
+
// keyed motion layer so swapping presets crossfades
|
|
6666
|
+
// (old scales/fades out while the new scales/fades
|
|
6667
|
+
// in) instead of hard-cutting. Keying the layer on
|
|
6668
|
+
// `presetIndex` also remounts the Matrix, restarting
|
|
6669
|
+
// its frame counter cleanly at frame 0.
|
|
6670
|
+
/* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { initial: false, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6671
|
+
framerMotion.motion.div,
|
|
6672
|
+
{
|
|
6673
|
+
className: "payman-v2-streaming-indicator-matrix",
|
|
6674
|
+
initial: { opacity: 0, scale: 0.8 },
|
|
6675
|
+
animate: { opacity: 1, scale: 1 },
|
|
6676
|
+
exit: { opacity: 0, scale: 0.8 },
|
|
6677
|
+
transition: { duration: 0.45, ease: [0.2, 0, 0, 1] },
|
|
6678
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6679
|
+
Matrix,
|
|
6680
|
+
{
|
|
6681
|
+
rows: MATRIX_GRID,
|
|
6682
|
+
cols: MATRIX_GRID,
|
|
6683
|
+
frames: preset.frames,
|
|
6684
|
+
fps: preset.fps,
|
|
6685
|
+
size: cell,
|
|
6686
|
+
gap,
|
|
6687
|
+
palette: {
|
|
6688
|
+
on: MATRIX_ON,
|
|
6689
|
+
// Unlit dots use the v2 theme's own muted-text
|
|
6690
|
+
// token (light/dark-aware), not the bare
|
|
6691
|
+
// `--muted-foreground` the vendored Matrix
|
|
6692
|
+
// component falls back to internally — that
|
|
6693
|
+
// variable isn't defined under `.payman-v2-root`
|
|
6694
|
+
// and would otherwise resolve to black.
|
|
6695
|
+
off: "var(--payman-v2-matrix-dot-off)"
|
|
6696
|
+
},
|
|
6697
|
+
ariaLabel: "Working\u2026"
|
|
6698
|
+
}
|
|
6699
|
+
)
|
|
6700
|
+
},
|
|
6701
|
+
presetIndex
|
|
6702
|
+
) })
|
|
5802
6703
|
)
|
|
5803
6704
|
}
|
|
5804
6705
|
),
|
|
5805
|
-
elapsed > 0 && /* @__PURE__ */ jsxRuntime.
|
|
5806
|
-
elapsed,
|
|
5807
|
-
"s"
|
|
5808
|
-
] })
|
|
6706
|
+
elapsed > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "payman-v2-streaming-indicator-elapsed", children: formatElapsed(elapsed) })
|
|
5809
6707
|
]
|
|
5810
6708
|
},
|
|
5811
6709
|
"streaming-indicator"
|
|
@@ -6413,6 +7311,15 @@ var PaymanChatInner = React.forwardRef(function PaymanChatInner2({
|
|
|
6413
7311
|
const expireUserAction2 = chat.expireUserAction ?? NOOP_ASYNC;
|
|
6414
7312
|
const dismissNotification = chat.dismissNotification ?? NOOP;
|
|
6415
7313
|
const isUserActionSupported = typeof chat.submitUserAction === "function" && typeof chat.cancelUserAction === "function" && typeof chat.resendUserAction === "function";
|
|
7314
|
+
const expiredUserActionIdsRef = React.useRef(/* @__PURE__ */ new Set());
|
|
7315
|
+
const expireUserActionOnce = React.useCallback(
|
|
7316
|
+
(userActionId) => {
|
|
7317
|
+
if (expiredUserActionIdsRef.current.has(userActionId)) return;
|
|
7318
|
+
expiredUserActionIdsRef.current.add(userActionId);
|
|
7319
|
+
void expireUserAction2(userActionId);
|
|
7320
|
+
},
|
|
7321
|
+
[expireUserAction2]
|
|
7322
|
+
);
|
|
6416
7323
|
const {
|
|
6417
7324
|
transcribedText,
|
|
6418
7325
|
isAvailable: voiceAvailable,
|
|
@@ -6655,6 +7562,9 @@ var PaymanChatInner = React.forwardRef(function PaymanChatInner2({
|
|
|
6655
7562
|
};
|
|
6656
7563
|
const userActionPrompts = isUserActionSupported ? userActionState.prompts : void 0;
|
|
6657
7564
|
const notifications = userActionState.notifications;
|
|
7565
|
+
const dockedPrompt = userActionPrompts?.find(
|
|
7566
|
+
(prompt) => prompt.kind !== "notification" && (prompt.status === "pending" || prompt.status === "submitting" || prompt.status === "stale")
|
|
7567
|
+
);
|
|
6658
7568
|
const handleV2Send = (text) => {
|
|
6659
7569
|
if (isRecording) stopRecording();
|
|
6660
7570
|
if (text.trim() && !disableInput && isSessionParamsConfigured) {
|
|
@@ -6807,11 +7717,12 @@ var PaymanChatInner = React.forwardRef(function PaymanChatInner2({
|
|
|
6807
7717
|
retryDisabled: isWaitingForResponse,
|
|
6808
7718
|
typingSpeed: config.typingSpeed ?? 4,
|
|
6809
7719
|
userActionPrompts,
|
|
7720
|
+
dockedUserActionId: dockedPrompt?.userActionId,
|
|
6810
7721
|
notifications,
|
|
6811
7722
|
onSubmitUserAction: isUserActionSupported ? submitUserAction2 : void 0,
|
|
6812
7723
|
onCancelUserAction: isUserActionSupported ? cancelUserAction2 : void 0,
|
|
6813
7724
|
onResendUserAction: isUserActionSupported ? resendUserAction2 : void 0,
|
|
6814
|
-
onExpireUserAction: isUserActionSupported ?
|
|
7725
|
+
onExpireUserAction: isUserActionSupported ? async (id) => expireUserActionOnce(id) : void 0,
|
|
6815
7726
|
onDismissNotification: dismissNotification,
|
|
6816
7727
|
onSubmitFeedback: handleSubmitFeedback
|
|
6817
7728
|
}
|
|
@@ -6824,33 +7735,43 @@ var PaymanChatInner = React.forwardRef(function PaymanChatInner2({
|
|
|
6824
7735
|
}
|
|
6825
7736
|
),
|
|
6826
7737
|
hasAskPermission && /* @__PURE__ */ jsxRuntime.jsx(
|
|
6827
|
-
|
|
7738
|
+
UserActionDock,
|
|
6828
7739
|
{
|
|
6829
|
-
|
|
6830
|
-
|
|
6831
|
-
onCancel:
|
|
6832
|
-
|
|
6833
|
-
|
|
6834
|
-
|
|
6835
|
-
|
|
6836
|
-
|
|
6837
|
-
|
|
6838
|
-
|
|
6839
|
-
|
|
6840
|
-
|
|
6841
|
-
|
|
6842
|
-
|
|
6843
|
-
|
|
6844
|
-
|
|
6845
|
-
|
|
6846
|
-
|
|
6847
|
-
|
|
6848
|
-
|
|
6849
|
-
|
|
6850
|
-
|
|
6851
|
-
|
|
6852
|
-
|
|
6853
|
-
|
|
7740
|
+
prompt: isUserActionSupported ? dockedPrompt : void 0,
|
|
7741
|
+
onSubmit: submitUserAction2,
|
|
7742
|
+
onCancel: cancelUserAction2,
|
|
7743
|
+
onResend: resendUserAction2,
|
|
7744
|
+
onExpired: expireUserActionOnce,
|
|
7745
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
7746
|
+
ChatInputV2,
|
|
7747
|
+
{
|
|
7748
|
+
ref: chatInputV2Ref,
|
|
7749
|
+
onSend: handleV2Send,
|
|
7750
|
+
onCancel: cancelStream,
|
|
7751
|
+
disabled: isV2InputDisabled,
|
|
7752
|
+
isStreaming: isWaitingForResponse,
|
|
7753
|
+
placeholder: isRecording ? "Listening..." : placeholder,
|
|
7754
|
+
enableVoice: config.enableVoice === true,
|
|
7755
|
+
transcribedText: config.enableVoice === true ? transcribedText : "",
|
|
7756
|
+
voiceAvailable: config.enableVoice === true && voiceAvailable,
|
|
7757
|
+
isRecording,
|
|
7758
|
+
onVoicePress: config.enableVoice === true ? handleVoicePress : void 0,
|
|
7759
|
+
onCancelRecording: handleCancelRecording,
|
|
7760
|
+
onConfirmRecording: handleConfirmRecording,
|
|
7761
|
+
showResetSession,
|
|
7762
|
+
onResetSession: requestResetSession,
|
|
7763
|
+
showAttachmentButton,
|
|
7764
|
+
showUploadImageButton,
|
|
7765
|
+
showAttachFileButton,
|
|
7766
|
+
onUploadImageClick,
|
|
7767
|
+
onAttachFileClick,
|
|
7768
|
+
editingMessageId,
|
|
7769
|
+
onClearEditing: handleClearEditing,
|
|
7770
|
+
analysisMode: enableDeepModeToggle ? analysisMode : void 0,
|
|
7771
|
+
onAnalysisModeChange: enableDeepModeToggle ? setAnalysisMode : void 0,
|
|
7772
|
+
slashCommands
|
|
7773
|
+
}
|
|
7774
|
+
)
|
|
6854
7775
|
}
|
|
6855
7776
|
)
|
|
6856
7777
|
]
|