@paymanai/payman-ask-sdk 4.0.6 → 4.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +126 -55
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +127 -56
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +138 -15
- package/dist/styles.css.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -258,28 +258,38 @@ var NEGATIVE_FEEDBACK_REASONS = [
|
|
|
258
258
|
{ value: "REPORT_CONTENT", label: "Report content" },
|
|
259
259
|
{ value: "OTHER", label: "Other" }
|
|
260
260
|
];
|
|
261
|
-
|
|
261
|
+
var DEFAULT_STREAM_ENDPOINT = "/api/playground/ask/stream";
|
|
262
|
+
async function submitFeedback({
|
|
262
263
|
baseUrl,
|
|
264
|
+
streamEndpoint,
|
|
263
265
|
headers,
|
|
266
|
+
authToken,
|
|
267
|
+
stage,
|
|
268
|
+
stageQueryParam,
|
|
264
269
|
executionId,
|
|
265
270
|
feedback,
|
|
266
271
|
details,
|
|
267
272
|
signal
|
|
268
273
|
}) {
|
|
269
274
|
const base = baseUrl.replace(/\/+$/, "");
|
|
270
|
-
const
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
275
|
+
const endpointPath = (streamEndpoint || DEFAULT_STREAM_ENDPOINT).split("?")[0].replace(/\/+$/, "");
|
|
276
|
+
const basePath = endpointPath.endsWith("/stream") ? endpointPath.slice(0, -"/stream".length) : endpointPath;
|
|
277
|
+
const query = new URLSearchParams();
|
|
278
|
+
if (stage) query.set(stageQueryParam ?? "stage", stage);
|
|
279
|
+
const qs = query.toString() ? `?${query.toString()}` : "";
|
|
280
|
+
const url = `${base}${basePath}/executions/${encodeURIComponent(executionId)}/feedback${qs}`;
|
|
281
|
+
const requestHeaders = {
|
|
282
|
+
"Content-Type": "application/json",
|
|
283
|
+
Accept: "application/json",
|
|
284
|
+
...headers ?? {}
|
|
285
|
+
};
|
|
286
|
+
if (authToken) requestHeaders.Authorization = `Bearer ${authToken}`;
|
|
287
|
+
const resp = await fetch(url, {
|
|
288
|
+
method: "POST",
|
|
289
|
+
headers: requestHeaders,
|
|
290
|
+
body: JSON.stringify(details ? { feedback, details } : { feedback }),
|
|
291
|
+
signal
|
|
292
|
+
});
|
|
283
293
|
if (!resp.ok) {
|
|
284
294
|
throw new Error(`Feedback failed: ${resp.status} ${resp.statusText}`);
|
|
285
295
|
}
|
|
@@ -1758,19 +1768,26 @@ function FeedbackReasonModal({
|
|
|
1758
1768
|
const [details, setDetails] = react.useState("");
|
|
1759
1769
|
const [submitting, setSubmitting] = react.useState(false);
|
|
1760
1770
|
const [error, setError] = react.useState(null);
|
|
1771
|
+
const [reasonOpen, setReasonOpen] = react.useState(false);
|
|
1761
1772
|
react.useEffect(() => {
|
|
1762
1773
|
if (open) {
|
|
1763
1774
|
setReason(NEGATIVE_FEEDBACK_REASONS[0].value);
|
|
1764
1775
|
setDetails("");
|
|
1765
1776
|
setError(null);
|
|
1766
1777
|
setSubmitting(false);
|
|
1778
|
+
setReasonOpen(false);
|
|
1767
1779
|
}
|
|
1768
1780
|
}, [open]);
|
|
1769
1781
|
const handleKeyDown = react.useCallback(
|
|
1770
1782
|
(event) => {
|
|
1771
|
-
if (event.key
|
|
1783
|
+
if (event.key !== "Escape") return;
|
|
1784
|
+
if (reasonOpen) {
|
|
1785
|
+
setReasonOpen(false);
|
|
1786
|
+
return;
|
|
1787
|
+
}
|
|
1788
|
+
onClose();
|
|
1772
1789
|
},
|
|
1773
|
-
[onClose]
|
|
1790
|
+
[onClose, reasonOpen]
|
|
1774
1791
|
);
|
|
1775
1792
|
react.useEffect(() => {
|
|
1776
1793
|
if (!open || typeof document === "undefined") return;
|
|
@@ -1785,6 +1802,7 @@ function FeedbackReasonModal({
|
|
|
1785
1802
|
const handleSubmit = async () => {
|
|
1786
1803
|
setSubmitting(true);
|
|
1787
1804
|
setError(null);
|
|
1805
|
+
setReasonOpen(false);
|
|
1788
1806
|
try {
|
|
1789
1807
|
await onSubmit(reason, details.trim() ? details.trim() : void 0);
|
|
1790
1808
|
onClose();
|
|
@@ -1793,6 +1811,7 @@ function FeedbackReasonModal({
|
|
|
1793
1811
|
setSubmitting(false);
|
|
1794
1812
|
}
|
|
1795
1813
|
};
|
|
1814
|
+
const selectedReason = NEGATIVE_FEEDBACK_REASONS.find((item) => item.value === reason) ?? NEGATIVE_FEEDBACK_REASONS[0];
|
|
1796
1815
|
return /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: open ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1797
1816
|
framerMotion.motion.div,
|
|
1798
1817
|
{
|
|
@@ -1816,6 +1835,17 @@ function FeedbackReasonModal({
|
|
|
1816
1835
|
"aria-modal": "true",
|
|
1817
1836
|
"aria-labelledby": "payman-v2-feedback-title",
|
|
1818
1837
|
children: [
|
|
1838
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1839
|
+
"button",
|
|
1840
|
+
{
|
|
1841
|
+
type: "button",
|
|
1842
|
+
onClick: onClose,
|
|
1843
|
+
disabled: submitting,
|
|
1844
|
+
className: "payman-v2-feedback-modal-close",
|
|
1845
|
+
"aria-label": "Close feedback modal",
|
|
1846
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { size: 18, strokeWidth: 2 })
|
|
1847
|
+
}
|
|
1848
|
+
),
|
|
1819
1849
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1820
1850
|
"h2",
|
|
1821
1851
|
{
|
|
@@ -1832,15 +1862,73 @@ function FeedbackReasonModal({
|
|
|
1832
1862
|
children: "What was the issue?"
|
|
1833
1863
|
}
|
|
1834
1864
|
),
|
|
1835
|
-
/* @__PURE__ */ jsxRuntime.
|
|
1836
|
-
"
|
|
1865
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1866
|
+
"div",
|
|
1837
1867
|
{
|
|
1838
1868
|
id: "payman-v2-feedback-reason",
|
|
1839
|
-
className: "payman-v2-feedback-modal-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1869
|
+
className: "payman-v2-feedback-modal-reason",
|
|
1870
|
+
onBlur: (event) => {
|
|
1871
|
+
const nextTarget = event.relatedTarget;
|
|
1872
|
+
if (!nextTarget || !event.currentTarget.contains(nextTarget)) {
|
|
1873
|
+
setReasonOpen(false);
|
|
1874
|
+
}
|
|
1875
|
+
},
|
|
1876
|
+
children: [
|
|
1877
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1878
|
+
"button",
|
|
1879
|
+
{
|
|
1880
|
+
type: "button",
|
|
1881
|
+
className: "payman-v2-feedback-modal-reason-trigger",
|
|
1882
|
+
"aria-haspopup": "listbox",
|
|
1883
|
+
"aria-expanded": reasonOpen,
|
|
1884
|
+
"aria-controls": "payman-v2-feedback-reason-options",
|
|
1885
|
+
disabled: submitting,
|
|
1886
|
+
onClick: () => setReasonOpen((current) => !current),
|
|
1887
|
+
children: [
|
|
1888
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: selectedReason.label }),
|
|
1889
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1890
|
+
lucideReact.ChevronDown,
|
|
1891
|
+
{
|
|
1892
|
+
size: 17,
|
|
1893
|
+
strokeWidth: 2,
|
|
1894
|
+
className: reasonOpen ? "payman-v2-feedback-modal-reason-chevron payman-v2-feedback-modal-reason-chevron-open" : "payman-v2-feedback-modal-reason-chevron"
|
|
1895
|
+
}
|
|
1896
|
+
)
|
|
1897
|
+
]
|
|
1898
|
+
}
|
|
1899
|
+
),
|
|
1900
|
+
reasonOpen ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1901
|
+
"div",
|
|
1902
|
+
{
|
|
1903
|
+
id: "payman-v2-feedback-reason-options",
|
|
1904
|
+
className: "payman-v2-feedback-modal-reason-menu",
|
|
1905
|
+
role: "listbox",
|
|
1906
|
+
"aria-label": "Feedback issue",
|
|
1907
|
+
tabIndex: -1,
|
|
1908
|
+
children: NEGATIVE_FEEDBACK_REASONS.map((item) => {
|
|
1909
|
+
const isSelected = item.value === reason;
|
|
1910
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1911
|
+
"button",
|
|
1912
|
+
{
|
|
1913
|
+
type: "button",
|
|
1914
|
+
className: isSelected ? "payman-v2-feedback-modal-reason-option payman-v2-feedback-modal-reason-option-selected" : "payman-v2-feedback-modal-reason-option",
|
|
1915
|
+
role: "option",
|
|
1916
|
+
"aria-selected": isSelected,
|
|
1917
|
+
onClick: () => {
|
|
1918
|
+
setReason(item.value);
|
|
1919
|
+
setReasonOpen(false);
|
|
1920
|
+
},
|
|
1921
|
+
children: [
|
|
1922
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: item.label }),
|
|
1923
|
+
isSelected ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { size: 16, strokeWidth: 2 }) : null
|
|
1924
|
+
]
|
|
1925
|
+
},
|
|
1926
|
+
item.value
|
|
1927
|
+
);
|
|
1928
|
+
})
|
|
1929
|
+
}
|
|
1930
|
+
) : null
|
|
1931
|
+
]
|
|
1844
1932
|
}
|
|
1845
1933
|
),
|
|
1846
1934
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -2014,34 +2102,6 @@ function AssistantMessageV2({
|
|
|
2014
2102
|
void 0,
|
|
2015
2103
|
typingSpeed
|
|
2016
2104
|
);
|
|
2017
|
-
const elapsedMs = (() => {
|
|
2018
|
-
const fromServer = message.totalElapsedMs;
|
|
2019
|
-
if (typeof fromServer === "number" && Number.isFinite(fromServer) && fromServer > 0) {
|
|
2020
|
-
return fromServer;
|
|
2021
|
-
}
|
|
2022
|
-
const steps = message.steps;
|
|
2023
|
-
if (!steps || steps.length === 0) return void 0;
|
|
2024
|
-
let earliest = Number.POSITIVE_INFINITY;
|
|
2025
|
-
let latest = Number.NEGATIVE_INFINITY;
|
|
2026
|
-
for (const s of steps) {
|
|
2027
|
-
if (!s.timestamp) continue;
|
|
2028
|
-
if (s.timestamp < earliest) earliest = s.timestamp;
|
|
2029
|
-
const end = s.timestamp + (s.elapsedMs ?? 0);
|
|
2030
|
-
if (end > latest) latest = end;
|
|
2031
|
-
}
|
|
2032
|
-
if (!Number.isFinite(earliest) || !Number.isFinite(latest)) {
|
|
2033
|
-
const total = steps.reduce((sum, s) => sum + (s.elapsedMs || 0), 0);
|
|
2034
|
-
return total > 0 ? total : void 0;
|
|
2035
|
-
}
|
|
2036
|
-
const diff = latest - earliest;
|
|
2037
|
-
return diff > 0 ? diff : void 0;
|
|
2038
|
-
})();
|
|
2039
|
-
function formatElapsed(ms) {
|
|
2040
|
-
if (ms === void 0) return void 0;
|
|
2041
|
-
if (ms < 1e3) return `${Math.round(ms)}ms`;
|
|
2042
|
-
return `${(ms / 1e3).toFixed(1)}s`;
|
|
2043
|
-
}
|
|
2044
|
-
const totalElapsedLabel = formatElapsed(elapsedMs);
|
|
2045
2105
|
const stickyLabel = (() => {
|
|
2046
2106
|
const steps = message.steps;
|
|
2047
2107
|
if (!steps || steps.length === 0) return void 0;
|
|
@@ -2256,8 +2316,7 @@ function AssistantMessageV2({
|
|
|
2256
2316
|
"aria-label": "Trace response",
|
|
2257
2317
|
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Binoculars, { style: { width: 16, height: 16 } })
|
|
2258
2318
|
}
|
|
2259
|
-
) })
|
|
2260
|
-
totalElapsedLabel && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "payman-v2-assistant-msg-elapsed", children: totalElapsedLabel })
|
|
2319
|
+
) })
|
|
2261
2320
|
] })
|
|
2262
2321
|
] }),
|
|
2263
2322
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -3976,9 +4035,13 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
|
|
|
3976
4035
|
if (!executionId) {
|
|
3977
4036
|
throw new Error("Cannot submit feedback before the response completes");
|
|
3978
4037
|
}
|
|
3979
|
-
await
|
|
4038
|
+
await submitFeedback({
|
|
3980
4039
|
baseUrl: config.api.baseUrl,
|
|
4040
|
+
streamEndpoint: config.api.streamEndpoint,
|
|
3981
4041
|
headers: config.api.headers,
|
|
4042
|
+
authToken: config.api.authToken,
|
|
4043
|
+
stage: config.stage,
|
|
4044
|
+
stageQueryParam: config.stageQueryParam,
|
|
3982
4045
|
executionId,
|
|
3983
4046
|
feedback,
|
|
3984
4047
|
details
|
|
@@ -3988,7 +4051,15 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
|
|
|
3988
4051
|
feedback: feedback === "POSITIVE" ? "up" : "down"
|
|
3989
4052
|
});
|
|
3990
4053
|
},
|
|
3991
|
-
[
|
|
4054
|
+
[
|
|
4055
|
+
config.api.baseUrl,
|
|
4056
|
+
config.api.streamEndpoint,
|
|
4057
|
+
config.api.headers,
|
|
4058
|
+
config.api.authToken,
|
|
4059
|
+
config.stage,
|
|
4060
|
+
config.stageQueryParam,
|
|
4061
|
+
onMessageFeedback
|
|
4062
|
+
]
|
|
3992
4063
|
);
|
|
3993
4064
|
const onExecutionTraceClick = react.useMemo(() => {
|
|
3994
4065
|
if (!config.debug) return rawOnExecutionTraceClick;
|