@paymanai/payman-ask-sdk 4.0.5 → 4.0.6
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 +1 -0
- package/dist/index.d.mts +54 -5
- package/dist/index.d.ts +54 -5
- package/dist/index.js +594 -30
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +594 -30
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +90 -0
- package/dist/styles.css.map +1 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -131,11 +131,17 @@ var DEFAULT_SLASH_COMMANDS = [
|
|
|
131
131
|
requiredAnyPermissions: ["vault:author", "vault:publish"]
|
|
132
132
|
}
|
|
133
133
|
];
|
|
134
|
+
function hasCommandPermission(granted, requiredPermission) {
|
|
135
|
+
if (granted.has("*") || granted.has(requiredPermission)) return true;
|
|
136
|
+
if (!requiredPermission.includes(".")) return false;
|
|
137
|
+
const wildcard = requiredPermission.substring(0, requiredPermission.lastIndexOf(".")) + ".*";
|
|
138
|
+
return granted.has(wildcard);
|
|
139
|
+
}
|
|
134
140
|
function filterSlashCommands(commands, permissions) {
|
|
135
141
|
const granted = new Set(permissions ?? []);
|
|
136
142
|
return commands.filter((command) => {
|
|
137
143
|
const required = command.requiredAnyPermissions ?? [];
|
|
138
|
-
return required.length === 0 || required.some((permission) => granted
|
|
144
|
+
return required.length === 0 || required.some((permission) => hasCommandPermission(granted, permission));
|
|
139
145
|
});
|
|
140
146
|
}
|
|
141
147
|
function parseSlashCommand(content) {
|
|
@@ -148,9 +154,19 @@ function parseSlashCommand(content) {
|
|
|
148
154
|
body: match[2] ?? ""
|
|
149
155
|
};
|
|
150
156
|
}
|
|
151
|
-
function
|
|
157
|
+
function getSlashCommandValidationHint(content) {
|
|
152
158
|
const parsed = parseSlashCommand(content);
|
|
153
|
-
|
|
159
|
+
if (parsed?.command !== "/draft-knowledge") return null;
|
|
160
|
+
const lines = parsed.body.split(/\r?\n/);
|
|
161
|
+
const title = lines[0]?.trim() ?? "";
|
|
162
|
+
const markdownContent = lines.slice(1).join("\n").trim();
|
|
163
|
+
if (!title) {
|
|
164
|
+
return "Add a title after /draft-knowledge, then add markdown content on the next line.";
|
|
165
|
+
}
|
|
166
|
+
if (!markdownContent) {
|
|
167
|
+
return "Add markdown content on a new line below the title.";
|
|
168
|
+
}
|
|
169
|
+
return null;
|
|
154
170
|
}
|
|
155
171
|
|
|
156
172
|
// src/utils/errorMessages.ts
|
|
@@ -205,6 +221,43 @@ function initSentryIfNeeded(dsn) {
|
|
|
205
221
|
}
|
|
206
222
|
});
|
|
207
223
|
}
|
|
224
|
+
|
|
225
|
+
// src/utils/feedbackClient.ts
|
|
226
|
+
var NEGATIVE_FEEDBACK_REASONS = [
|
|
227
|
+
{ value: "NOT_FACTUALLY_CORRECT", label: "Not factually correct" },
|
|
228
|
+
{ value: "INCOMPLETE_RESPONSE", label: "Incomplete response" },
|
|
229
|
+
{ value: "DID_NOT_FOLLOW_REQUEST", label: "Did not follow my request" },
|
|
230
|
+
{ value: "OVERACTIVE_REFUSAL", label: "Refused unnecessarily" },
|
|
231
|
+
{ value: "ISSUE_WITH_THOUGHT_PROCESS", label: "Issue with reasoning" },
|
|
232
|
+
{ value: "REPORT_CONTENT", label: "Report content" },
|
|
233
|
+
{ value: "OTHER", label: "Other" }
|
|
234
|
+
];
|
|
235
|
+
async function submitAskFeedback({
|
|
236
|
+
baseUrl,
|
|
237
|
+
headers,
|
|
238
|
+
executionId,
|
|
239
|
+
feedback,
|
|
240
|
+
details,
|
|
241
|
+
signal
|
|
242
|
+
}) {
|
|
243
|
+
const base = baseUrl.replace(/\/+$/, "");
|
|
244
|
+
const resp = await fetch(
|
|
245
|
+
`${base}/api/ask/executions/${encodeURIComponent(executionId)}/feedback`,
|
|
246
|
+
{
|
|
247
|
+
method: "POST",
|
|
248
|
+
headers: {
|
|
249
|
+
"Content-Type": "application/json",
|
|
250
|
+
Accept: "application/json",
|
|
251
|
+
...headers ?? {}
|
|
252
|
+
},
|
|
253
|
+
body: JSON.stringify(details ? { feedback, details } : { feedback }),
|
|
254
|
+
signal
|
|
255
|
+
}
|
|
256
|
+
);
|
|
257
|
+
if (!resp.ok) {
|
|
258
|
+
throw new Error(`Feedback failed: ${resp.status} ${resp.statusText}`);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
208
261
|
function ImageLightbox({
|
|
209
262
|
src,
|
|
210
263
|
alt = "",
|
|
@@ -1667,6 +1720,143 @@ function ThinkingBlockV2({
|
|
|
1667
1720
|
) }) })
|
|
1668
1721
|
] });
|
|
1669
1722
|
}
|
|
1723
|
+
var MAX_DETAILS_CHARS = 2e3;
|
|
1724
|
+
function FeedbackReasonModal({
|
|
1725
|
+
open,
|
|
1726
|
+
onClose,
|
|
1727
|
+
onSubmit
|
|
1728
|
+
}) {
|
|
1729
|
+
const [reason, setReason] = useState(
|
|
1730
|
+
NEGATIVE_FEEDBACK_REASONS[0].value
|
|
1731
|
+
);
|
|
1732
|
+
const [details, setDetails] = useState("");
|
|
1733
|
+
const [submitting, setSubmitting] = useState(false);
|
|
1734
|
+
const [error, setError] = useState(null);
|
|
1735
|
+
useEffect(() => {
|
|
1736
|
+
if (open) {
|
|
1737
|
+
setReason(NEGATIVE_FEEDBACK_REASONS[0].value);
|
|
1738
|
+
setDetails("");
|
|
1739
|
+
setError(null);
|
|
1740
|
+
setSubmitting(false);
|
|
1741
|
+
}
|
|
1742
|
+
}, [open]);
|
|
1743
|
+
const handleKeyDown = useCallback(
|
|
1744
|
+
(event) => {
|
|
1745
|
+
if (event.key === "Escape") onClose();
|
|
1746
|
+
},
|
|
1747
|
+
[onClose]
|
|
1748
|
+
);
|
|
1749
|
+
useEffect(() => {
|
|
1750
|
+
if (!open || typeof document === "undefined") return;
|
|
1751
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
1752
|
+
const previousOverflow = document.body.style.overflow;
|
|
1753
|
+
document.body.style.overflow = "hidden";
|
|
1754
|
+
return () => {
|
|
1755
|
+
document.removeEventListener("keydown", handleKeyDown);
|
|
1756
|
+
document.body.style.overflow = previousOverflow;
|
|
1757
|
+
};
|
|
1758
|
+
}, [handleKeyDown, open]);
|
|
1759
|
+
const handleSubmit = async () => {
|
|
1760
|
+
setSubmitting(true);
|
|
1761
|
+
setError(null);
|
|
1762
|
+
try {
|
|
1763
|
+
await onSubmit(reason, details.trim() ? details.trim() : void 0);
|
|
1764
|
+
onClose();
|
|
1765
|
+
} catch (e) {
|
|
1766
|
+
setError(e instanceof Error ? e.message : "Could not send feedback");
|
|
1767
|
+
setSubmitting(false);
|
|
1768
|
+
}
|
|
1769
|
+
};
|
|
1770
|
+
return /* @__PURE__ */ jsx(AnimatePresence, { children: open ? /* @__PURE__ */ jsx(
|
|
1771
|
+
motion.div,
|
|
1772
|
+
{
|
|
1773
|
+
className: "payman-v2-feedback-modal-backdrop",
|
|
1774
|
+
initial: { opacity: 0 },
|
|
1775
|
+
animate: { opacity: 1 },
|
|
1776
|
+
exit: { opacity: 0 },
|
|
1777
|
+
transition: { duration: 0.18 },
|
|
1778
|
+
onClick: onClose,
|
|
1779
|
+
role: "presentation",
|
|
1780
|
+
children: /* @__PURE__ */ jsxs(
|
|
1781
|
+
motion.div,
|
|
1782
|
+
{
|
|
1783
|
+
initial: { opacity: 0, y: 12, scale: 0.98 },
|
|
1784
|
+
animate: { opacity: 1, y: 0, scale: 1 },
|
|
1785
|
+
exit: { opacity: 0, y: 8, scale: 0.98 },
|
|
1786
|
+
transition: { duration: 0.2, ease: [0.16, 1, 0.3, 1] },
|
|
1787
|
+
className: "payman-v2-feedback-modal-dialog",
|
|
1788
|
+
onClick: (event) => event.stopPropagation(),
|
|
1789
|
+
role: "dialog",
|
|
1790
|
+
"aria-modal": "true",
|
|
1791
|
+
"aria-labelledby": "payman-v2-feedback-title",
|
|
1792
|
+
children: [
|
|
1793
|
+
/* @__PURE__ */ jsx(
|
|
1794
|
+
"h2",
|
|
1795
|
+
{
|
|
1796
|
+
id: "payman-v2-feedback-title",
|
|
1797
|
+
className: "payman-v2-feedback-modal-title",
|
|
1798
|
+
children: "Tell us what went wrong"
|
|
1799
|
+
}
|
|
1800
|
+
),
|
|
1801
|
+
/* @__PURE__ */ jsx(
|
|
1802
|
+
"label",
|
|
1803
|
+
{
|
|
1804
|
+
className: "payman-v2-feedback-modal-label",
|
|
1805
|
+
htmlFor: "payman-v2-feedback-reason",
|
|
1806
|
+
children: "What was the issue?"
|
|
1807
|
+
}
|
|
1808
|
+
),
|
|
1809
|
+
/* @__PURE__ */ jsx(
|
|
1810
|
+
"select",
|
|
1811
|
+
{
|
|
1812
|
+
id: "payman-v2-feedback-reason",
|
|
1813
|
+
className: "payman-v2-feedback-modal-select",
|
|
1814
|
+
value: reason,
|
|
1815
|
+
onChange: (e) => setReason(e.target.value),
|
|
1816
|
+
disabled: submitting,
|
|
1817
|
+
children: NEGATIVE_FEEDBACK_REASONS.map((r) => /* @__PURE__ */ jsx("option", { value: r.value, children: r.label }, r.value))
|
|
1818
|
+
}
|
|
1819
|
+
),
|
|
1820
|
+
/* @__PURE__ */ jsx(
|
|
1821
|
+
"textarea",
|
|
1822
|
+
{
|
|
1823
|
+
className: "payman-v2-feedback-modal-textarea",
|
|
1824
|
+
placeholder: "Add details (optional)",
|
|
1825
|
+
value: details,
|
|
1826
|
+
maxLength: MAX_DETAILS_CHARS,
|
|
1827
|
+
onChange: (e) => setDetails(e.target.value),
|
|
1828
|
+
disabled: submitting
|
|
1829
|
+
}
|
|
1830
|
+
),
|
|
1831
|
+
error ? /* @__PURE__ */ jsx("p", { className: "payman-v2-feedback-modal-error", children: error }) : null,
|
|
1832
|
+
/* @__PURE__ */ jsxs("div", { className: "payman-v2-feedback-modal-actions", children: [
|
|
1833
|
+
/* @__PURE__ */ jsx(
|
|
1834
|
+
"button",
|
|
1835
|
+
{
|
|
1836
|
+
type: "button",
|
|
1837
|
+
onClick: onClose,
|
|
1838
|
+
disabled: submitting,
|
|
1839
|
+
className: "payman-v2-feedback-modal-btn payman-v2-feedback-modal-btn-secondary",
|
|
1840
|
+
children: "Cancel"
|
|
1841
|
+
}
|
|
1842
|
+
),
|
|
1843
|
+
/* @__PURE__ */ jsx(
|
|
1844
|
+
"button",
|
|
1845
|
+
{
|
|
1846
|
+
type: "button",
|
|
1847
|
+
onClick: handleSubmit,
|
|
1848
|
+
disabled: submitting,
|
|
1849
|
+
className: "payman-v2-feedback-modal-btn payman-v2-feedback-modal-btn-primary",
|
|
1850
|
+
children: submitting ? "Sending\u2026" : "Submit"
|
|
1851
|
+
}
|
|
1852
|
+
)
|
|
1853
|
+
] })
|
|
1854
|
+
]
|
|
1855
|
+
}
|
|
1856
|
+
)
|
|
1857
|
+
}
|
|
1858
|
+
) : null });
|
|
1859
|
+
}
|
|
1670
1860
|
var RESPONSE_SPEED = {
|
|
1671
1861
|
normal: [2, 4],
|
|
1672
1862
|
fast: 1,
|
|
@@ -1749,12 +1939,26 @@ function AssistantMessageV2({
|
|
|
1749
1939
|
message,
|
|
1750
1940
|
onImageClick,
|
|
1751
1941
|
onExecutionTraceClick,
|
|
1752
|
-
|
|
1942
|
+
onSubmitFeedback,
|
|
1753
1943
|
actions,
|
|
1754
1944
|
typingSpeed = 4
|
|
1755
1945
|
}) {
|
|
1756
1946
|
const [copied, setCopied] = useState(false);
|
|
1757
1947
|
const [activeFeedback, setActiveFeedback] = useState(null);
|
|
1948
|
+
const [reasonModalOpen, setReasonModalOpen] = useState(false);
|
|
1949
|
+
const canSubmitFeedback = !!onSubmitFeedback && !!message.executionId;
|
|
1950
|
+
const handlePositiveFeedback = () => {
|
|
1951
|
+
if (!canSubmitFeedback || activeFeedback === "up") return;
|
|
1952
|
+
const previous = activeFeedback;
|
|
1953
|
+
setActiveFeedback("up");
|
|
1954
|
+
Promise.resolve(
|
|
1955
|
+
onSubmitFeedback?.({
|
|
1956
|
+
messageId: message.id,
|
|
1957
|
+
executionId: message.executionId,
|
|
1958
|
+
feedback: "POSITIVE"
|
|
1959
|
+
})
|
|
1960
|
+
).catch(() => setActiveFeedback(previous));
|
|
1961
|
+
};
|
|
1758
1962
|
const [toast, setToast] = useState(null);
|
|
1759
1963
|
const copyResetTimerRef = useRef(null);
|
|
1760
1964
|
const toastTimerRef = useRef(null);
|
|
@@ -1994,14 +2198,10 @@ function AssistantMessageV2({
|
|
|
1994
2198
|
children: copied ? /* @__PURE__ */ jsx(Check, { style: { width: 16, height: 16 } }) : /* @__PURE__ */ jsx(Copy, { style: { width: 16, height: 16 } })
|
|
1995
2199
|
}
|
|
1996
2200
|
) }),
|
|
1997
|
-
showThumbsUp && /* @__PURE__ */ jsx(ActionTooltipV2, { label: "Good response", children: /* @__PURE__ */ jsx(
|
|
2201
|
+
showThumbsUp && canSubmitFeedback && /* @__PURE__ */ jsx(ActionTooltipV2, { label: "Good response", children: /* @__PURE__ */ jsx(
|
|
1998
2202
|
"button",
|
|
1999
2203
|
{
|
|
2000
|
-
onClick:
|
|
2001
|
-
const next = activeFeedback === "up" ? null : "up";
|
|
2002
|
-
setActiveFeedback(next);
|
|
2003
|
-
if (next) onFeedback?.({ messageId: message.id, feedback: "up" });
|
|
2004
|
-
},
|
|
2204
|
+
onClick: handlePositiveFeedback,
|
|
2005
2205
|
className: cn(
|
|
2006
2206
|
"payman-v2-assistant-msg-action-btn",
|
|
2007
2207
|
activeFeedback === "up" && "payman-v2-assistant-msg-action-btn-active"
|
|
@@ -2010,14 +2210,10 @@ function AssistantMessageV2({
|
|
|
2010
2210
|
children: /* @__PURE__ */ jsx(ThumbsUp, { style: { width: 15, height: 15 } })
|
|
2011
2211
|
}
|
|
2012
2212
|
) }),
|
|
2013
|
-
showThumbsDown && /* @__PURE__ */ jsx(ActionTooltipV2, { label: "Bad response", children: /* @__PURE__ */ jsx(
|
|
2213
|
+
showThumbsDown && canSubmitFeedback && /* @__PURE__ */ jsx(ActionTooltipV2, { label: "Bad response", children: /* @__PURE__ */ jsx(
|
|
2014
2214
|
"button",
|
|
2015
2215
|
{
|
|
2016
|
-
onClick: () =>
|
|
2017
|
-
const next = activeFeedback === "down" ? null : "down";
|
|
2018
|
-
setActiveFeedback(next);
|
|
2019
|
-
if (next) onFeedback?.({ messageId: message.id, feedback: "down" });
|
|
2020
|
-
},
|
|
2216
|
+
onClick: () => setReasonModalOpen(true),
|
|
2021
2217
|
className: cn(
|
|
2022
2218
|
"payman-v2-assistant-msg-action-btn",
|
|
2023
2219
|
activeFeedback === "down" && "payman-v2-assistant-msg-action-btn-active"
|
|
@@ -2037,7 +2233,23 @@ function AssistantMessageV2({
|
|
|
2037
2233
|
) }),
|
|
2038
2234
|
totalElapsedLabel && /* @__PURE__ */ jsx("span", { className: "payman-v2-assistant-msg-elapsed", children: totalElapsedLabel })
|
|
2039
2235
|
] })
|
|
2040
|
-
] })
|
|
2236
|
+
] }),
|
|
2237
|
+
/* @__PURE__ */ jsx(
|
|
2238
|
+
FeedbackReasonModal,
|
|
2239
|
+
{
|
|
2240
|
+
open: reasonModalOpen,
|
|
2241
|
+
onClose: () => setReasonModalOpen(false),
|
|
2242
|
+
onSubmit: async (reason, details) => {
|
|
2243
|
+
await onSubmitFeedback?.({
|
|
2244
|
+
messageId: message.id,
|
|
2245
|
+
executionId: message.executionId,
|
|
2246
|
+
feedback: reason,
|
|
2247
|
+
details
|
|
2248
|
+
});
|
|
2249
|
+
setActiveFeedback("down");
|
|
2250
|
+
}
|
|
2251
|
+
}
|
|
2252
|
+
)
|
|
2041
2253
|
] });
|
|
2042
2254
|
}
|
|
2043
2255
|
var DEFAULT_MAX_LENGTH = 6;
|
|
@@ -2318,7 +2530,7 @@ var MessageListV2 = forwardRef(
|
|
|
2318
2530
|
onApproveAction,
|
|
2319
2531
|
onRejectAction,
|
|
2320
2532
|
onResendAction,
|
|
2321
|
-
|
|
2533
|
+
onSubmitFeedback,
|
|
2322
2534
|
typingSpeed = 4
|
|
2323
2535
|
}, ref) {
|
|
2324
2536
|
const scrollRef = useRef(null);
|
|
@@ -2458,7 +2670,7 @@ var MessageListV2 = forwardRef(
|
|
|
2458
2670
|
message,
|
|
2459
2671
|
onImageClick,
|
|
2460
2672
|
onExecutionTraceClick,
|
|
2461
|
-
|
|
2673
|
+
onSubmitFeedback,
|
|
2462
2674
|
actions: messageActions?.assistantMessageActions,
|
|
2463
2675
|
typingSpeed
|
|
2464
2676
|
}
|
|
@@ -2622,8 +2834,9 @@ var ChatInputV2 = forwardRef(
|
|
|
2622
2834
|
}, [isRecording, transcribedText]);
|
|
2623
2835
|
const handleSend = useCallback(() => {
|
|
2624
2836
|
if (!value.trim() || disabled) return;
|
|
2625
|
-
|
|
2626
|
-
|
|
2837
|
+
const commandHint = getSlashCommandValidationHint(value);
|
|
2838
|
+
if (commandHint) {
|
|
2839
|
+
setInlineHint(commandHint);
|
|
2627
2840
|
return;
|
|
2628
2841
|
}
|
|
2629
2842
|
voiceDraftSyncActiveRef.current = false;
|
|
@@ -3225,6 +3438,316 @@ function ImageLightboxV2({ src, alt, onClose }) {
|
|
|
3225
3438
|
document.body
|
|
3226
3439
|
);
|
|
3227
3440
|
}
|
|
3441
|
+
var PRE_PIPELINE_STEPS = /* @__PURE__ */ new Set([
|
|
3442
|
+
"record_execution",
|
|
3443
|
+
"resolve_provider",
|
|
3444
|
+
"resolve_mcp_servers",
|
|
3445
|
+
"build_pipeline",
|
|
3446
|
+
"load_skill_index"
|
|
3447
|
+
]);
|
|
3448
|
+
function stepColor(step) {
|
|
3449
|
+
if (step.status === "failed") return "#ef4444";
|
|
3450
|
+
if (PRE_PIPELINE_STEPS.has(step.step)) return "#f59e0b";
|
|
3451
|
+
return "#3b82f6";
|
|
3452
|
+
}
|
|
3453
|
+
function formatMs(ms) {
|
|
3454
|
+
if (ms == null) return "\u2014";
|
|
3455
|
+
if (ms < 1e3) return `${ms} ms`;
|
|
3456
|
+
return `${(ms / 1e3).toFixed(2)} s`;
|
|
3457
|
+
}
|
|
3458
|
+
function TraceTimelineModal({
|
|
3459
|
+
open,
|
|
3460
|
+
onClose,
|
|
3461
|
+
executionId,
|
|
3462
|
+
apiBaseUrl,
|
|
3463
|
+
apiHeaders
|
|
3464
|
+
}) {
|
|
3465
|
+
const [trace, setTrace] = useState(null);
|
|
3466
|
+
const [loading, setLoading] = useState(false);
|
|
3467
|
+
const [error, setError] = useState(null);
|
|
3468
|
+
useEffect(() => {
|
|
3469
|
+
if (!open || !executionId) return;
|
|
3470
|
+
const ctrl = new AbortController();
|
|
3471
|
+
setLoading(true);
|
|
3472
|
+
setError(null);
|
|
3473
|
+
setTrace(null);
|
|
3474
|
+
const base = apiBaseUrl.replace(/\/+$/, "");
|
|
3475
|
+
fetch(`${base}/api/ask/executions/${encodeURIComponent(executionId)}/trace`, {
|
|
3476
|
+
method: "GET",
|
|
3477
|
+
headers: { Accept: "application/json", ...apiHeaders },
|
|
3478
|
+
signal: ctrl.signal
|
|
3479
|
+
}).then(async (resp) => {
|
|
3480
|
+
if (!resp.ok) {
|
|
3481
|
+
throw new Error(`Trace fetch failed: ${resp.status} ${resp.statusText}`);
|
|
3482
|
+
}
|
|
3483
|
+
return resp.json();
|
|
3484
|
+
}).then((data) => setTrace(data)).catch((e) => {
|
|
3485
|
+
if (e.name === "AbortError") return;
|
|
3486
|
+
setError(e instanceof Error ? e.message : "Trace fetch failed");
|
|
3487
|
+
}).finally(() => setLoading(false));
|
|
3488
|
+
return () => ctrl.abort();
|
|
3489
|
+
}, [open, executionId, apiBaseUrl, apiHeaders]);
|
|
3490
|
+
const totalMs = useMemo(() => {
|
|
3491
|
+
if (!trace) return 0;
|
|
3492
|
+
const meta = trace.runMetadata?.totalTimeMs;
|
|
3493
|
+
if (typeof meta === "number" && meta > 0) return meta;
|
|
3494
|
+
const starts = trace.pipelineSteps.map((s) => s.startTime);
|
|
3495
|
+
const ends = trace.pipelineSteps.map((s) => s.endTime ?? s.startTime).filter((t) => typeof t === "number");
|
|
3496
|
+
if (starts.length === 0 || ends.length === 0) return 0;
|
|
3497
|
+
return Math.max(...ends) - Math.min(...starts);
|
|
3498
|
+
}, [trace]);
|
|
3499
|
+
const accountedMs = useMemo(
|
|
3500
|
+
() => (trace?.pipelineSteps ?? []).reduce(
|
|
3501
|
+
(sum, s) => sum + (s.durationMs ?? 0),
|
|
3502
|
+
0
|
|
3503
|
+
),
|
|
3504
|
+
[trace]
|
|
3505
|
+
);
|
|
3506
|
+
const unaccountedMs = Math.max(totalMs - accountedMs, 0);
|
|
3507
|
+
if (typeof document === "undefined") return null;
|
|
3508
|
+
return createPortal(
|
|
3509
|
+
/* @__PURE__ */ jsx(AnimatePresence, { children: open && /* @__PURE__ */ jsx(
|
|
3510
|
+
motion.div,
|
|
3511
|
+
{
|
|
3512
|
+
initial: { opacity: 0 },
|
|
3513
|
+
animate: { opacity: 1 },
|
|
3514
|
+
exit: { opacity: 0 },
|
|
3515
|
+
transition: { duration: 0.15 },
|
|
3516
|
+
onClick: onClose,
|
|
3517
|
+
style: {
|
|
3518
|
+
position: "fixed",
|
|
3519
|
+
inset: 0,
|
|
3520
|
+
background: "rgba(0,0,0,0.45)",
|
|
3521
|
+
zIndex: 9999,
|
|
3522
|
+
display: "flex",
|
|
3523
|
+
alignItems: "center",
|
|
3524
|
+
justifyContent: "center",
|
|
3525
|
+
padding: 24
|
|
3526
|
+
},
|
|
3527
|
+
children: /* @__PURE__ */ jsxs(
|
|
3528
|
+
motion.div,
|
|
3529
|
+
{
|
|
3530
|
+
initial: { y: 12, opacity: 0 },
|
|
3531
|
+
animate: { y: 0, opacity: 1 },
|
|
3532
|
+
exit: { y: 12, opacity: 0 },
|
|
3533
|
+
transition: { duration: 0.18 },
|
|
3534
|
+
onClick: (e) => e.stopPropagation(),
|
|
3535
|
+
style: {
|
|
3536
|
+
background: "#0b1220",
|
|
3537
|
+
color: "#e5e7eb",
|
|
3538
|
+
borderRadius: 12,
|
|
3539
|
+
width: "100%",
|
|
3540
|
+
maxWidth: 760,
|
|
3541
|
+
maxHeight: "85vh",
|
|
3542
|
+
overflow: "auto",
|
|
3543
|
+
boxShadow: "0 20px 60px rgba(0,0,0,0.45)",
|
|
3544
|
+
fontFamily: "ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, sans-serif"
|
|
3545
|
+
},
|
|
3546
|
+
children: [
|
|
3547
|
+
/* @__PURE__ */ jsxs(
|
|
3548
|
+
"header",
|
|
3549
|
+
{
|
|
3550
|
+
style: {
|
|
3551
|
+
display: "flex",
|
|
3552
|
+
alignItems: "center",
|
|
3553
|
+
justifyContent: "space-between",
|
|
3554
|
+
padding: "14px 18px",
|
|
3555
|
+
borderBottom: "1px solid rgba(255,255,255,0.08)"
|
|
3556
|
+
},
|
|
3557
|
+
children: [
|
|
3558
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
3559
|
+
/* @__PURE__ */ jsx("div", { style: { fontSize: 14, fontWeight: 600 }, children: "Execution trace" }),
|
|
3560
|
+
/* @__PURE__ */ jsx(
|
|
3561
|
+
"div",
|
|
3562
|
+
{
|
|
3563
|
+
style: {
|
|
3564
|
+
fontSize: 11,
|
|
3565
|
+
opacity: 0.6,
|
|
3566
|
+
marginTop: 2,
|
|
3567
|
+
fontFamily: "ui-monospace, SFMono-Regular, monospace"
|
|
3568
|
+
},
|
|
3569
|
+
children: executionId ?? ""
|
|
3570
|
+
}
|
|
3571
|
+
)
|
|
3572
|
+
] }),
|
|
3573
|
+
/* @__PURE__ */ jsx(
|
|
3574
|
+
"button",
|
|
3575
|
+
{
|
|
3576
|
+
onClick: onClose,
|
|
3577
|
+
"aria-label": "Close",
|
|
3578
|
+
style: {
|
|
3579
|
+
background: "transparent",
|
|
3580
|
+
border: 0,
|
|
3581
|
+
color: "#e5e7eb",
|
|
3582
|
+
cursor: "pointer",
|
|
3583
|
+
padding: 6,
|
|
3584
|
+
borderRadius: 6
|
|
3585
|
+
},
|
|
3586
|
+
children: /* @__PURE__ */ jsx(X, { style: { width: 18, height: 18 } })
|
|
3587
|
+
}
|
|
3588
|
+
)
|
|
3589
|
+
]
|
|
3590
|
+
}
|
|
3591
|
+
),
|
|
3592
|
+
/* @__PURE__ */ jsxs("div", { style: { padding: 18 }, children: [
|
|
3593
|
+
loading && /* @__PURE__ */ jsx("div", { style: { opacity: 0.7, fontSize: 13 }, children: "Loading trace\u2026" }),
|
|
3594
|
+
error && /* @__PURE__ */ jsx(
|
|
3595
|
+
"div",
|
|
3596
|
+
{
|
|
3597
|
+
style: {
|
|
3598
|
+
color: "#fca5a5",
|
|
3599
|
+
fontSize: 13,
|
|
3600
|
+
whiteSpace: "pre-wrap"
|
|
3601
|
+
},
|
|
3602
|
+
children: error
|
|
3603
|
+
}
|
|
3604
|
+
),
|
|
3605
|
+
trace && !loading && !error && /* @__PURE__ */ jsx(
|
|
3606
|
+
TimelineBars,
|
|
3607
|
+
{
|
|
3608
|
+
trace,
|
|
3609
|
+
totalMs,
|
|
3610
|
+
unaccountedMs
|
|
3611
|
+
}
|
|
3612
|
+
)
|
|
3613
|
+
] })
|
|
3614
|
+
]
|
|
3615
|
+
}
|
|
3616
|
+
)
|
|
3617
|
+
}
|
|
3618
|
+
) }),
|
|
3619
|
+
document.body
|
|
3620
|
+
);
|
|
3621
|
+
}
|
|
3622
|
+
function TimelineBars({
|
|
3623
|
+
trace,
|
|
3624
|
+
totalMs,
|
|
3625
|
+
unaccountedMs
|
|
3626
|
+
}) {
|
|
3627
|
+
const bars = trace.pipelineSteps.map((step) => {
|
|
3628
|
+
const duration = step.durationMs ?? 0;
|
|
3629
|
+
const widthPct = totalMs > 0 ? duration / totalMs * 100 : 0;
|
|
3630
|
+
const llmMs = step.llmCall?.durationMs ?? null;
|
|
3631
|
+
return /* @__PURE__ */ jsxs("div", { style: { marginBottom: 8 }, children: [
|
|
3632
|
+
/* @__PURE__ */ jsxs(
|
|
3633
|
+
"div",
|
|
3634
|
+
{
|
|
3635
|
+
style: {
|
|
3636
|
+
display: "flex",
|
|
3637
|
+
justifyContent: "space-between",
|
|
3638
|
+
fontSize: 12,
|
|
3639
|
+
marginBottom: 4,
|
|
3640
|
+
fontFamily: "ui-monospace, SFMono-Regular, monospace"
|
|
3641
|
+
},
|
|
3642
|
+
children: [
|
|
3643
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
3644
|
+
step.step,
|
|
3645
|
+
step.status === "failed" && /* @__PURE__ */ jsx("span", { style: { color: "#fca5a5", marginLeft: 6 }, children: "(failed)" })
|
|
3646
|
+
] }),
|
|
3647
|
+
/* @__PURE__ */ jsxs("span", { style: { opacity: 0.75 }, children: [
|
|
3648
|
+
formatMs(duration),
|
|
3649
|
+
llmMs != null && /* @__PURE__ */ jsxs("span", { style: { marginLeft: 8, opacity: 0.6 }, children: [
|
|
3650
|
+
"(LLM ",
|
|
3651
|
+
formatMs(llmMs),
|
|
3652
|
+
")"
|
|
3653
|
+
] })
|
|
3654
|
+
] })
|
|
3655
|
+
]
|
|
3656
|
+
}
|
|
3657
|
+
),
|
|
3658
|
+
/* @__PURE__ */ jsx(
|
|
3659
|
+
"div",
|
|
3660
|
+
{
|
|
3661
|
+
style: {
|
|
3662
|
+
height: 8,
|
|
3663
|
+
background: "rgba(255,255,255,0.06)",
|
|
3664
|
+
borderRadius: 4,
|
|
3665
|
+
overflow: "hidden"
|
|
3666
|
+
},
|
|
3667
|
+
children: /* @__PURE__ */ jsx(
|
|
3668
|
+
"div",
|
|
3669
|
+
{
|
|
3670
|
+
style: {
|
|
3671
|
+
height: "100%",
|
|
3672
|
+
width: `${Math.max(widthPct, 0.3)}%`,
|
|
3673
|
+
background: stepColor(step),
|
|
3674
|
+
transition: "width 0.2s ease"
|
|
3675
|
+
}
|
|
3676
|
+
}
|
|
3677
|
+
)
|
|
3678
|
+
}
|
|
3679
|
+
)
|
|
3680
|
+
] }, `${step.step}-${step.startTime}`);
|
|
3681
|
+
});
|
|
3682
|
+
return /* @__PURE__ */ jsxs("div", { children: [
|
|
3683
|
+
bars,
|
|
3684
|
+
unaccountedMs > 0 && /* @__PURE__ */ jsxs("div", { style: { marginBottom: 8 }, children: [
|
|
3685
|
+
/* @__PURE__ */ jsxs(
|
|
3686
|
+
"div",
|
|
3687
|
+
{
|
|
3688
|
+
style: {
|
|
3689
|
+
display: "flex",
|
|
3690
|
+
justifyContent: "space-between",
|
|
3691
|
+
fontSize: 12,
|
|
3692
|
+
marginBottom: 4,
|
|
3693
|
+
fontFamily: "ui-monospace, SFMono-Regular, monospace",
|
|
3694
|
+
opacity: 0.7
|
|
3695
|
+
},
|
|
3696
|
+
children: [
|
|
3697
|
+
/* @__PURE__ */ jsx("span", { children: "(unaccounted)" }),
|
|
3698
|
+
/* @__PURE__ */ jsx("span", { children: formatMs(unaccountedMs) })
|
|
3699
|
+
]
|
|
3700
|
+
}
|
|
3701
|
+
),
|
|
3702
|
+
/* @__PURE__ */ jsx(
|
|
3703
|
+
"div",
|
|
3704
|
+
{
|
|
3705
|
+
style: {
|
|
3706
|
+
height: 8,
|
|
3707
|
+
background: "rgba(255,255,255,0.06)",
|
|
3708
|
+
borderRadius: 4,
|
|
3709
|
+
overflow: "hidden"
|
|
3710
|
+
},
|
|
3711
|
+
children: /* @__PURE__ */ jsx(
|
|
3712
|
+
"div",
|
|
3713
|
+
{
|
|
3714
|
+
style: {
|
|
3715
|
+
height: "100%",
|
|
3716
|
+
width: `${unaccountedMs / Math.max(totalMs, 1) * 100}%`,
|
|
3717
|
+
background: "repeating-linear-gradient(45deg, rgba(255,255,255,0.18) 0 4px, transparent 4px 8px)"
|
|
3718
|
+
}
|
|
3719
|
+
}
|
|
3720
|
+
)
|
|
3721
|
+
}
|
|
3722
|
+
)
|
|
3723
|
+
] }),
|
|
3724
|
+
/* @__PURE__ */ jsxs(
|
|
3725
|
+
"div",
|
|
3726
|
+
{
|
|
3727
|
+
style: {
|
|
3728
|
+
marginTop: 14,
|
|
3729
|
+
paddingTop: 12,
|
|
3730
|
+
borderTop: "1px solid rgba(255,255,255,0.08)",
|
|
3731
|
+
fontSize: 12,
|
|
3732
|
+
display: "flex",
|
|
3733
|
+
justifyContent: "space-between",
|
|
3734
|
+
opacity: 0.85
|
|
3735
|
+
},
|
|
3736
|
+
children: [
|
|
3737
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
3738
|
+
trace.pipelineSteps.length,
|
|
3739
|
+
" step",
|
|
3740
|
+
trace.pipelineSteps.length === 1 ? "" : "s"
|
|
3741
|
+
] }),
|
|
3742
|
+
/* @__PURE__ */ jsxs("span", { style: { fontFamily: "ui-monospace, SFMono-Regular, monospace" }, children: [
|
|
3743
|
+
"total: ",
|
|
3744
|
+
formatMs(totalMs)
|
|
3745
|
+
] })
|
|
3746
|
+
]
|
|
3747
|
+
}
|
|
3748
|
+
)
|
|
3749
|
+
] });
|
|
3750
|
+
}
|
|
3228
3751
|
var DEFAULT_USER_ACTION_STATE = {
|
|
3229
3752
|
request: null,
|
|
3230
3753
|
result: null};
|
|
@@ -3415,12 +3938,39 @@ var PaymanChatInner = forwardRef(function PaymanChatInner2({
|
|
|
3415
3938
|
]
|
|
3416
3939
|
);
|
|
3417
3940
|
const {
|
|
3418
|
-
onExecutionTraceClick,
|
|
3941
|
+
onExecutionTraceClick: rawOnExecutionTraceClick,
|
|
3419
3942
|
onResetSession,
|
|
3420
3943
|
onUploadImageClick,
|
|
3421
3944
|
onAttachFileClick,
|
|
3422
3945
|
onMessageFeedback
|
|
3423
3946
|
} = callbacks;
|
|
3947
|
+
const [debugTraceExecutionId, setDebugTraceExecutionId] = useState(null);
|
|
3948
|
+
const handleSubmitFeedback = useCallback(
|
|
3949
|
+
async ({ messageId, executionId, feedback, details }) => {
|
|
3950
|
+
if (!executionId) {
|
|
3951
|
+
throw new Error("Cannot submit feedback before the response completes");
|
|
3952
|
+
}
|
|
3953
|
+
await submitAskFeedback({
|
|
3954
|
+
baseUrl: config.api.baseUrl,
|
|
3955
|
+
headers: config.api.headers,
|
|
3956
|
+
executionId,
|
|
3957
|
+
feedback,
|
|
3958
|
+
details
|
|
3959
|
+
});
|
|
3960
|
+
onMessageFeedback?.({
|
|
3961
|
+
messageId,
|
|
3962
|
+
feedback: feedback === "POSITIVE" ? "up" : "down"
|
|
3963
|
+
});
|
|
3964
|
+
},
|
|
3965
|
+
[config.api.baseUrl, config.api.headers, onMessageFeedback]
|
|
3966
|
+
);
|
|
3967
|
+
const onExecutionTraceClick = useMemo(() => {
|
|
3968
|
+
if (!config.debug) return rawOnExecutionTraceClick;
|
|
3969
|
+
return (data) => {
|
|
3970
|
+
rawOnExecutionTraceClick?.(data);
|
|
3971
|
+
if (data.executionId) setDebugTraceExecutionId(data.executionId);
|
|
3972
|
+
};
|
|
3973
|
+
}, [config.debug, rawOnExecutionTraceClick]);
|
|
3424
3974
|
const performResetSession = useCallback(() => {
|
|
3425
3975
|
resetToEmptyStateRef.current = true;
|
|
3426
3976
|
setEditingMessageId(null);
|
|
@@ -3478,6 +4028,7 @@ var PaymanChatInner = forwardRef(function PaymanChatInner2({
|
|
|
3478
4028
|
showEmptyStateIcon = true,
|
|
3479
4029
|
emptyStateComponent,
|
|
3480
4030
|
showResetSession = false,
|
|
4031
|
+
enableDeepModeToggle = true,
|
|
3481
4032
|
showAttachmentButton = true,
|
|
3482
4033
|
showUploadImageButton = true,
|
|
3483
4034
|
showAttachFileButton = true,
|
|
@@ -3533,6 +4084,7 @@ var PaymanChatInner = forwardRef(function PaymanChatInner2({
|
|
|
3533
4084
|
stopRecording();
|
|
3534
4085
|
};
|
|
3535
4086
|
const isV2InputDisabled = !isSessionParamsConfigured || disableInput;
|
|
4087
|
+
const effectiveAnalysisMode = enableDeepModeToggle ? analysisMode : "fast";
|
|
3536
4088
|
const isEmpty = messages.length === 0;
|
|
3537
4089
|
if (isChatDisabled) {
|
|
3538
4090
|
if (disabledComponent) {
|
|
@@ -3591,7 +4143,7 @@ var PaymanChatInner = forwardRef(function PaymanChatInner2({
|
|
|
3591
4143
|
if (isRecording) stopRecording();
|
|
3592
4144
|
if (text.trim() && !disableInput && isSessionParamsConfigured) {
|
|
3593
4145
|
setEditingMessageId(null);
|
|
3594
|
-
void sendMessage(text.trim(), { analysisMode });
|
|
4146
|
+
void sendMessage(text.trim(), { analysisMode: effectiveAnalysisMode });
|
|
3595
4147
|
}
|
|
3596
4148
|
};
|
|
3597
4149
|
const handleVoicePress = useCallback(async () => {
|
|
@@ -3618,7 +4170,9 @@ var PaymanChatInner = forwardRef(function PaymanChatInner2({
|
|
|
3618
4170
|
(message) => message.id === messageId && message.role === "user"
|
|
3619
4171
|
);
|
|
3620
4172
|
if (!targetMessage?.content.trim()) return;
|
|
3621
|
-
void sendMessage(targetMessage.content.trim(), {
|
|
4173
|
+
void sendMessage(targetMessage.content.trim(), {
|
|
4174
|
+
analysisMode: effectiveAnalysisMode
|
|
4175
|
+
});
|
|
3622
4176
|
const bump = () => messageListV2Ref.current?.scrollToBottom("instant");
|
|
3623
4177
|
requestAnimationFrame(() => {
|
|
3624
4178
|
bump();
|
|
@@ -3626,7 +4180,7 @@ var PaymanChatInner = forwardRef(function PaymanChatInner2({
|
|
|
3626
4180
|
window.setTimeout(bump, 120);
|
|
3627
4181
|
});
|
|
3628
4182
|
});
|
|
3629
|
-
}, [isWaitingForResponse, messages, sendMessage,
|
|
4183
|
+
}, [isWaitingForResponse, messages, sendMessage, effectiveAnalysisMode]);
|
|
3630
4184
|
const handleClearEditing = useCallback(() => {
|
|
3631
4185
|
setEditingMessageId(null);
|
|
3632
4186
|
}, []);
|
|
@@ -3705,8 +4259,8 @@ var PaymanChatInner = forwardRef(function PaymanChatInner2({
|
|
|
3705
4259
|
onAttachFileClick,
|
|
3706
4260
|
editingMessageId,
|
|
3707
4261
|
onClearEditing: handleClearEditing,
|
|
3708
|
-
analysisMode,
|
|
3709
|
-
onAnalysisModeChange: setAnalysisMode,
|
|
4262
|
+
analysisMode: enableDeepModeToggle ? analysisMode : void 0,
|
|
4263
|
+
onAnalysisModeChange: enableDeepModeToggle ? setAnalysisMode : void 0,
|
|
3710
4264
|
slashCommands
|
|
3711
4265
|
}
|
|
3712
4266
|
)
|
|
@@ -3746,7 +4300,7 @@ var PaymanChatInner = forwardRef(function PaymanChatInner2({
|
|
|
3746
4300
|
onResendAction: isUserActionSupported ? async () => {
|
|
3747
4301
|
await resendOtp();
|
|
3748
4302
|
} : void 0,
|
|
3749
|
-
|
|
4303
|
+
onSubmitFeedback: handleSubmitFeedback
|
|
3750
4304
|
}
|
|
3751
4305
|
),
|
|
3752
4306
|
/* @__PURE__ */ jsx(
|
|
@@ -3781,8 +4335,8 @@ var PaymanChatInner = forwardRef(function PaymanChatInner2({
|
|
|
3781
4335
|
onAttachFileClick,
|
|
3782
4336
|
editingMessageId,
|
|
3783
4337
|
onClearEditing: handleClearEditing,
|
|
3784
|
-
analysisMode,
|
|
3785
|
-
onAnalysisModeChange: setAnalysisMode,
|
|
4338
|
+
analysisMode: enableDeepModeToggle ? analysisMode : void 0,
|
|
4339
|
+
onAnalysisModeChange: enableDeepModeToggle ? setAnalysisMode : void 0,
|
|
3786
4340
|
slashCommands
|
|
3787
4341
|
}
|
|
3788
4342
|
)
|
|
@@ -3805,6 +4359,16 @@ var PaymanChatInner = forwardRef(function PaymanChatInner2({
|
|
|
3805
4359
|
onClose: closeResetSessionConfirm,
|
|
3806
4360
|
onConfirm: performResetSession
|
|
3807
4361
|
}
|
|
4362
|
+
),
|
|
4363
|
+
config.debug && /* @__PURE__ */ jsx(
|
|
4364
|
+
TraceTimelineModal,
|
|
4365
|
+
{
|
|
4366
|
+
open: debugTraceExecutionId !== null,
|
|
4367
|
+
onClose: () => setDebugTraceExecutionId(null),
|
|
4368
|
+
executionId: debugTraceExecutionId,
|
|
4369
|
+
apiBaseUrl: config.api.baseUrl,
|
|
4370
|
+
apiHeaders: config.api.headers
|
|
4371
|
+
}
|
|
3808
4372
|
)
|
|
3809
4373
|
]
|
|
3810
4374
|
}
|