@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.js
CHANGED
|
@@ -157,11 +157,17 @@ var DEFAULT_SLASH_COMMANDS = [
|
|
|
157
157
|
requiredAnyPermissions: ["vault:author", "vault:publish"]
|
|
158
158
|
}
|
|
159
159
|
];
|
|
160
|
+
function hasCommandPermission(granted, requiredPermission) {
|
|
161
|
+
if (granted.has("*") || granted.has(requiredPermission)) return true;
|
|
162
|
+
if (!requiredPermission.includes(".")) return false;
|
|
163
|
+
const wildcard = requiredPermission.substring(0, requiredPermission.lastIndexOf(".")) + ".*";
|
|
164
|
+
return granted.has(wildcard);
|
|
165
|
+
}
|
|
160
166
|
function filterSlashCommands(commands, permissions) {
|
|
161
167
|
const granted = new Set(permissions ?? []);
|
|
162
168
|
return commands.filter((command) => {
|
|
163
169
|
const required = command.requiredAnyPermissions ?? [];
|
|
164
|
-
return required.length === 0 || required.some((permission) => granted
|
|
170
|
+
return required.length === 0 || required.some((permission) => hasCommandPermission(granted, permission));
|
|
165
171
|
});
|
|
166
172
|
}
|
|
167
173
|
function parseSlashCommand(content) {
|
|
@@ -174,9 +180,19 @@ function parseSlashCommand(content) {
|
|
|
174
180
|
body: match[2] ?? ""
|
|
175
181
|
};
|
|
176
182
|
}
|
|
177
|
-
function
|
|
183
|
+
function getSlashCommandValidationHint(content) {
|
|
178
184
|
const parsed = parseSlashCommand(content);
|
|
179
|
-
|
|
185
|
+
if (parsed?.command !== "/draft-knowledge") return null;
|
|
186
|
+
const lines = parsed.body.split(/\r?\n/);
|
|
187
|
+
const title = lines[0]?.trim() ?? "";
|
|
188
|
+
const markdownContent = lines.slice(1).join("\n").trim();
|
|
189
|
+
if (!title) {
|
|
190
|
+
return "Add a title after /draft-knowledge, then add markdown content on the next line.";
|
|
191
|
+
}
|
|
192
|
+
if (!markdownContent) {
|
|
193
|
+
return "Add markdown content on a new line below the title.";
|
|
194
|
+
}
|
|
195
|
+
return null;
|
|
180
196
|
}
|
|
181
197
|
|
|
182
198
|
// src/utils/errorMessages.ts
|
|
@@ -231,6 +247,43 @@ function initSentryIfNeeded(dsn) {
|
|
|
231
247
|
}
|
|
232
248
|
});
|
|
233
249
|
}
|
|
250
|
+
|
|
251
|
+
// src/utils/feedbackClient.ts
|
|
252
|
+
var NEGATIVE_FEEDBACK_REASONS = [
|
|
253
|
+
{ value: "NOT_FACTUALLY_CORRECT", label: "Not factually correct" },
|
|
254
|
+
{ value: "INCOMPLETE_RESPONSE", label: "Incomplete response" },
|
|
255
|
+
{ value: "DID_NOT_FOLLOW_REQUEST", label: "Did not follow my request" },
|
|
256
|
+
{ value: "OVERACTIVE_REFUSAL", label: "Refused unnecessarily" },
|
|
257
|
+
{ value: "ISSUE_WITH_THOUGHT_PROCESS", label: "Issue with reasoning" },
|
|
258
|
+
{ value: "REPORT_CONTENT", label: "Report content" },
|
|
259
|
+
{ value: "OTHER", label: "Other" }
|
|
260
|
+
];
|
|
261
|
+
async function submitAskFeedback({
|
|
262
|
+
baseUrl,
|
|
263
|
+
headers,
|
|
264
|
+
executionId,
|
|
265
|
+
feedback,
|
|
266
|
+
details,
|
|
267
|
+
signal
|
|
268
|
+
}) {
|
|
269
|
+
const base = baseUrl.replace(/\/+$/, "");
|
|
270
|
+
const resp = await fetch(
|
|
271
|
+
`${base}/api/ask/executions/${encodeURIComponent(executionId)}/feedback`,
|
|
272
|
+
{
|
|
273
|
+
method: "POST",
|
|
274
|
+
headers: {
|
|
275
|
+
"Content-Type": "application/json",
|
|
276
|
+
Accept: "application/json",
|
|
277
|
+
...headers ?? {}
|
|
278
|
+
},
|
|
279
|
+
body: JSON.stringify(details ? { feedback, details } : { feedback }),
|
|
280
|
+
signal
|
|
281
|
+
}
|
|
282
|
+
);
|
|
283
|
+
if (!resp.ok) {
|
|
284
|
+
throw new Error(`Feedback failed: ${resp.status} ${resp.statusText}`);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
234
287
|
function ImageLightbox({
|
|
235
288
|
src,
|
|
236
289
|
alt = "",
|
|
@@ -1693,6 +1746,143 @@ function ThinkingBlockV2({
|
|
|
1693
1746
|
) }) })
|
|
1694
1747
|
] });
|
|
1695
1748
|
}
|
|
1749
|
+
var MAX_DETAILS_CHARS = 2e3;
|
|
1750
|
+
function FeedbackReasonModal({
|
|
1751
|
+
open,
|
|
1752
|
+
onClose,
|
|
1753
|
+
onSubmit
|
|
1754
|
+
}) {
|
|
1755
|
+
const [reason, setReason] = react.useState(
|
|
1756
|
+
NEGATIVE_FEEDBACK_REASONS[0].value
|
|
1757
|
+
);
|
|
1758
|
+
const [details, setDetails] = react.useState("");
|
|
1759
|
+
const [submitting, setSubmitting] = react.useState(false);
|
|
1760
|
+
const [error, setError] = react.useState(null);
|
|
1761
|
+
react.useEffect(() => {
|
|
1762
|
+
if (open) {
|
|
1763
|
+
setReason(NEGATIVE_FEEDBACK_REASONS[0].value);
|
|
1764
|
+
setDetails("");
|
|
1765
|
+
setError(null);
|
|
1766
|
+
setSubmitting(false);
|
|
1767
|
+
}
|
|
1768
|
+
}, [open]);
|
|
1769
|
+
const handleKeyDown = react.useCallback(
|
|
1770
|
+
(event) => {
|
|
1771
|
+
if (event.key === "Escape") onClose();
|
|
1772
|
+
},
|
|
1773
|
+
[onClose]
|
|
1774
|
+
);
|
|
1775
|
+
react.useEffect(() => {
|
|
1776
|
+
if (!open || typeof document === "undefined") return;
|
|
1777
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
1778
|
+
const previousOverflow = document.body.style.overflow;
|
|
1779
|
+
document.body.style.overflow = "hidden";
|
|
1780
|
+
return () => {
|
|
1781
|
+
document.removeEventListener("keydown", handleKeyDown);
|
|
1782
|
+
document.body.style.overflow = previousOverflow;
|
|
1783
|
+
};
|
|
1784
|
+
}, [handleKeyDown, open]);
|
|
1785
|
+
const handleSubmit = async () => {
|
|
1786
|
+
setSubmitting(true);
|
|
1787
|
+
setError(null);
|
|
1788
|
+
try {
|
|
1789
|
+
await onSubmit(reason, details.trim() ? details.trim() : void 0);
|
|
1790
|
+
onClose();
|
|
1791
|
+
} catch (e) {
|
|
1792
|
+
setError(e instanceof Error ? e.message : "Could not send feedback");
|
|
1793
|
+
setSubmitting(false);
|
|
1794
|
+
}
|
|
1795
|
+
};
|
|
1796
|
+
return /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: open ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1797
|
+
framerMotion.motion.div,
|
|
1798
|
+
{
|
|
1799
|
+
className: "payman-v2-feedback-modal-backdrop",
|
|
1800
|
+
initial: { opacity: 0 },
|
|
1801
|
+
animate: { opacity: 1 },
|
|
1802
|
+
exit: { opacity: 0 },
|
|
1803
|
+
transition: { duration: 0.18 },
|
|
1804
|
+
onClick: onClose,
|
|
1805
|
+
role: "presentation",
|
|
1806
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1807
|
+
framerMotion.motion.div,
|
|
1808
|
+
{
|
|
1809
|
+
initial: { opacity: 0, y: 12, scale: 0.98 },
|
|
1810
|
+
animate: { opacity: 1, y: 0, scale: 1 },
|
|
1811
|
+
exit: { opacity: 0, y: 8, scale: 0.98 },
|
|
1812
|
+
transition: { duration: 0.2, ease: [0.16, 1, 0.3, 1] },
|
|
1813
|
+
className: "payman-v2-feedback-modal-dialog",
|
|
1814
|
+
onClick: (event) => event.stopPropagation(),
|
|
1815
|
+
role: "dialog",
|
|
1816
|
+
"aria-modal": "true",
|
|
1817
|
+
"aria-labelledby": "payman-v2-feedback-title",
|
|
1818
|
+
children: [
|
|
1819
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1820
|
+
"h2",
|
|
1821
|
+
{
|
|
1822
|
+
id: "payman-v2-feedback-title",
|
|
1823
|
+
className: "payman-v2-feedback-modal-title",
|
|
1824
|
+
children: "Tell us what went wrong"
|
|
1825
|
+
}
|
|
1826
|
+
),
|
|
1827
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1828
|
+
"label",
|
|
1829
|
+
{
|
|
1830
|
+
className: "payman-v2-feedback-modal-label",
|
|
1831
|
+
htmlFor: "payman-v2-feedback-reason",
|
|
1832
|
+
children: "What was the issue?"
|
|
1833
|
+
}
|
|
1834
|
+
),
|
|
1835
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1836
|
+
"select",
|
|
1837
|
+
{
|
|
1838
|
+
id: "payman-v2-feedback-reason",
|
|
1839
|
+
className: "payman-v2-feedback-modal-select",
|
|
1840
|
+
value: reason,
|
|
1841
|
+
onChange: (e) => setReason(e.target.value),
|
|
1842
|
+
disabled: submitting,
|
|
1843
|
+
children: NEGATIVE_FEEDBACK_REASONS.map((r) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: r.value, children: r.label }, r.value))
|
|
1844
|
+
}
|
|
1845
|
+
),
|
|
1846
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1847
|
+
"textarea",
|
|
1848
|
+
{
|
|
1849
|
+
className: "payman-v2-feedback-modal-textarea",
|
|
1850
|
+
placeholder: "Add details (optional)",
|
|
1851
|
+
value: details,
|
|
1852
|
+
maxLength: MAX_DETAILS_CHARS,
|
|
1853
|
+
onChange: (e) => setDetails(e.target.value),
|
|
1854
|
+
disabled: submitting
|
|
1855
|
+
}
|
|
1856
|
+
),
|
|
1857
|
+
error ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "payman-v2-feedback-modal-error", children: error }) : null,
|
|
1858
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "payman-v2-feedback-modal-actions", children: [
|
|
1859
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1860
|
+
"button",
|
|
1861
|
+
{
|
|
1862
|
+
type: "button",
|
|
1863
|
+
onClick: onClose,
|
|
1864
|
+
disabled: submitting,
|
|
1865
|
+
className: "payman-v2-feedback-modal-btn payman-v2-feedback-modal-btn-secondary",
|
|
1866
|
+
children: "Cancel"
|
|
1867
|
+
}
|
|
1868
|
+
),
|
|
1869
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1870
|
+
"button",
|
|
1871
|
+
{
|
|
1872
|
+
type: "button",
|
|
1873
|
+
onClick: handleSubmit,
|
|
1874
|
+
disabled: submitting,
|
|
1875
|
+
className: "payman-v2-feedback-modal-btn payman-v2-feedback-modal-btn-primary",
|
|
1876
|
+
children: submitting ? "Sending\u2026" : "Submit"
|
|
1877
|
+
}
|
|
1878
|
+
)
|
|
1879
|
+
] })
|
|
1880
|
+
]
|
|
1881
|
+
}
|
|
1882
|
+
)
|
|
1883
|
+
}
|
|
1884
|
+
) : null });
|
|
1885
|
+
}
|
|
1696
1886
|
var RESPONSE_SPEED = {
|
|
1697
1887
|
normal: [2, 4],
|
|
1698
1888
|
fast: 1,
|
|
@@ -1775,12 +1965,26 @@ function AssistantMessageV2({
|
|
|
1775
1965
|
message,
|
|
1776
1966
|
onImageClick,
|
|
1777
1967
|
onExecutionTraceClick,
|
|
1778
|
-
|
|
1968
|
+
onSubmitFeedback,
|
|
1779
1969
|
actions,
|
|
1780
1970
|
typingSpeed = 4
|
|
1781
1971
|
}) {
|
|
1782
1972
|
const [copied, setCopied] = react.useState(false);
|
|
1783
1973
|
const [activeFeedback, setActiveFeedback] = react.useState(null);
|
|
1974
|
+
const [reasonModalOpen, setReasonModalOpen] = react.useState(false);
|
|
1975
|
+
const canSubmitFeedback = !!onSubmitFeedback && !!message.executionId;
|
|
1976
|
+
const handlePositiveFeedback = () => {
|
|
1977
|
+
if (!canSubmitFeedback || activeFeedback === "up") return;
|
|
1978
|
+
const previous = activeFeedback;
|
|
1979
|
+
setActiveFeedback("up");
|
|
1980
|
+
Promise.resolve(
|
|
1981
|
+
onSubmitFeedback?.({
|
|
1982
|
+
messageId: message.id,
|
|
1983
|
+
executionId: message.executionId,
|
|
1984
|
+
feedback: "POSITIVE"
|
|
1985
|
+
})
|
|
1986
|
+
).catch(() => setActiveFeedback(previous));
|
|
1987
|
+
};
|
|
1784
1988
|
const [toast, setToast] = react.useState(null);
|
|
1785
1989
|
const copyResetTimerRef = react.useRef(null);
|
|
1786
1990
|
const toastTimerRef = react.useRef(null);
|
|
@@ -2020,14 +2224,10 @@ function AssistantMessageV2({
|
|
|
2020
2224
|
children: copied ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { style: { width: 16, height: 16 } }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Copy, { style: { width: 16, height: 16 } })
|
|
2021
2225
|
}
|
|
2022
2226
|
) }),
|
|
2023
|
-
showThumbsUp && /* @__PURE__ */ jsxRuntime.jsx(ActionTooltipV2, { label: "Good response", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2227
|
+
showThumbsUp && canSubmitFeedback && /* @__PURE__ */ jsxRuntime.jsx(ActionTooltipV2, { label: "Good response", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2024
2228
|
"button",
|
|
2025
2229
|
{
|
|
2026
|
-
onClick:
|
|
2027
|
-
const next = activeFeedback === "up" ? null : "up";
|
|
2028
|
-
setActiveFeedback(next);
|
|
2029
|
-
if (next) onFeedback?.({ messageId: message.id, feedback: "up" });
|
|
2030
|
-
},
|
|
2230
|
+
onClick: handlePositiveFeedback,
|
|
2031
2231
|
className: cn(
|
|
2032
2232
|
"payman-v2-assistant-msg-action-btn",
|
|
2033
2233
|
activeFeedback === "up" && "payman-v2-assistant-msg-action-btn-active"
|
|
@@ -2036,14 +2236,10 @@ function AssistantMessageV2({
|
|
|
2036
2236
|
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ThumbsUp, { style: { width: 15, height: 15 } })
|
|
2037
2237
|
}
|
|
2038
2238
|
) }),
|
|
2039
|
-
showThumbsDown && /* @__PURE__ */ jsxRuntime.jsx(ActionTooltipV2, { label: "Bad response", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2239
|
+
showThumbsDown && canSubmitFeedback && /* @__PURE__ */ jsxRuntime.jsx(ActionTooltipV2, { label: "Bad response", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2040
2240
|
"button",
|
|
2041
2241
|
{
|
|
2042
|
-
onClick: () =>
|
|
2043
|
-
const next = activeFeedback === "down" ? null : "down";
|
|
2044
|
-
setActiveFeedback(next);
|
|
2045
|
-
if (next) onFeedback?.({ messageId: message.id, feedback: "down" });
|
|
2046
|
-
},
|
|
2242
|
+
onClick: () => setReasonModalOpen(true),
|
|
2047
2243
|
className: cn(
|
|
2048
2244
|
"payman-v2-assistant-msg-action-btn",
|
|
2049
2245
|
activeFeedback === "down" && "payman-v2-assistant-msg-action-btn-active"
|
|
@@ -2063,7 +2259,23 @@ function AssistantMessageV2({
|
|
|
2063
2259
|
) }),
|
|
2064
2260
|
totalElapsedLabel && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "payman-v2-assistant-msg-elapsed", children: totalElapsedLabel })
|
|
2065
2261
|
] })
|
|
2066
|
-
] })
|
|
2262
|
+
] }),
|
|
2263
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2264
|
+
FeedbackReasonModal,
|
|
2265
|
+
{
|
|
2266
|
+
open: reasonModalOpen,
|
|
2267
|
+
onClose: () => setReasonModalOpen(false),
|
|
2268
|
+
onSubmit: async (reason, details) => {
|
|
2269
|
+
await onSubmitFeedback?.({
|
|
2270
|
+
messageId: message.id,
|
|
2271
|
+
executionId: message.executionId,
|
|
2272
|
+
feedback: reason,
|
|
2273
|
+
details
|
|
2274
|
+
});
|
|
2275
|
+
setActiveFeedback("down");
|
|
2276
|
+
}
|
|
2277
|
+
}
|
|
2278
|
+
)
|
|
2067
2279
|
] });
|
|
2068
2280
|
}
|
|
2069
2281
|
var DEFAULT_MAX_LENGTH = 6;
|
|
@@ -2344,7 +2556,7 @@ var MessageListV2 = react.forwardRef(
|
|
|
2344
2556
|
onApproveAction,
|
|
2345
2557
|
onRejectAction,
|
|
2346
2558
|
onResendAction,
|
|
2347
|
-
|
|
2559
|
+
onSubmitFeedback,
|
|
2348
2560
|
typingSpeed = 4
|
|
2349
2561
|
}, ref) {
|
|
2350
2562
|
const scrollRef = react.useRef(null);
|
|
@@ -2484,7 +2696,7 @@ var MessageListV2 = react.forwardRef(
|
|
|
2484
2696
|
message,
|
|
2485
2697
|
onImageClick,
|
|
2486
2698
|
onExecutionTraceClick,
|
|
2487
|
-
|
|
2699
|
+
onSubmitFeedback,
|
|
2488
2700
|
actions: messageActions?.assistantMessageActions,
|
|
2489
2701
|
typingSpeed
|
|
2490
2702
|
}
|
|
@@ -2648,8 +2860,9 @@ var ChatInputV2 = react.forwardRef(
|
|
|
2648
2860
|
}, [isRecording, transcribedText]);
|
|
2649
2861
|
const handleSend = react.useCallback(() => {
|
|
2650
2862
|
if (!value.trim() || disabled) return;
|
|
2651
|
-
|
|
2652
|
-
|
|
2863
|
+
const commandHint = getSlashCommandValidationHint(value);
|
|
2864
|
+
if (commandHint) {
|
|
2865
|
+
setInlineHint(commandHint);
|
|
2653
2866
|
return;
|
|
2654
2867
|
}
|
|
2655
2868
|
voiceDraftSyncActiveRef.current = false;
|
|
@@ -3251,6 +3464,316 @@ function ImageLightboxV2({ src, alt, onClose }) {
|
|
|
3251
3464
|
document.body
|
|
3252
3465
|
);
|
|
3253
3466
|
}
|
|
3467
|
+
var PRE_PIPELINE_STEPS = /* @__PURE__ */ new Set([
|
|
3468
|
+
"record_execution",
|
|
3469
|
+
"resolve_provider",
|
|
3470
|
+
"resolve_mcp_servers",
|
|
3471
|
+
"build_pipeline",
|
|
3472
|
+
"load_skill_index"
|
|
3473
|
+
]);
|
|
3474
|
+
function stepColor(step) {
|
|
3475
|
+
if (step.status === "failed") return "#ef4444";
|
|
3476
|
+
if (PRE_PIPELINE_STEPS.has(step.step)) return "#f59e0b";
|
|
3477
|
+
return "#3b82f6";
|
|
3478
|
+
}
|
|
3479
|
+
function formatMs(ms) {
|
|
3480
|
+
if (ms == null) return "\u2014";
|
|
3481
|
+
if (ms < 1e3) return `${ms} ms`;
|
|
3482
|
+
return `${(ms / 1e3).toFixed(2)} s`;
|
|
3483
|
+
}
|
|
3484
|
+
function TraceTimelineModal({
|
|
3485
|
+
open,
|
|
3486
|
+
onClose,
|
|
3487
|
+
executionId,
|
|
3488
|
+
apiBaseUrl,
|
|
3489
|
+
apiHeaders
|
|
3490
|
+
}) {
|
|
3491
|
+
const [trace, setTrace] = react.useState(null);
|
|
3492
|
+
const [loading, setLoading] = react.useState(false);
|
|
3493
|
+
const [error, setError] = react.useState(null);
|
|
3494
|
+
react.useEffect(() => {
|
|
3495
|
+
if (!open || !executionId) return;
|
|
3496
|
+
const ctrl = new AbortController();
|
|
3497
|
+
setLoading(true);
|
|
3498
|
+
setError(null);
|
|
3499
|
+
setTrace(null);
|
|
3500
|
+
const base = apiBaseUrl.replace(/\/+$/, "");
|
|
3501
|
+
fetch(`${base}/api/ask/executions/${encodeURIComponent(executionId)}/trace`, {
|
|
3502
|
+
method: "GET",
|
|
3503
|
+
headers: { Accept: "application/json", ...apiHeaders },
|
|
3504
|
+
signal: ctrl.signal
|
|
3505
|
+
}).then(async (resp) => {
|
|
3506
|
+
if (!resp.ok) {
|
|
3507
|
+
throw new Error(`Trace fetch failed: ${resp.status} ${resp.statusText}`);
|
|
3508
|
+
}
|
|
3509
|
+
return resp.json();
|
|
3510
|
+
}).then((data) => setTrace(data)).catch((e) => {
|
|
3511
|
+
if (e.name === "AbortError") return;
|
|
3512
|
+
setError(e instanceof Error ? e.message : "Trace fetch failed");
|
|
3513
|
+
}).finally(() => setLoading(false));
|
|
3514
|
+
return () => ctrl.abort();
|
|
3515
|
+
}, [open, executionId, apiBaseUrl, apiHeaders]);
|
|
3516
|
+
const totalMs = react.useMemo(() => {
|
|
3517
|
+
if (!trace) return 0;
|
|
3518
|
+
const meta = trace.runMetadata?.totalTimeMs;
|
|
3519
|
+
if (typeof meta === "number" && meta > 0) return meta;
|
|
3520
|
+
const starts = trace.pipelineSteps.map((s) => s.startTime);
|
|
3521
|
+
const ends = trace.pipelineSteps.map((s) => s.endTime ?? s.startTime).filter((t) => typeof t === "number");
|
|
3522
|
+
if (starts.length === 0 || ends.length === 0) return 0;
|
|
3523
|
+
return Math.max(...ends) - Math.min(...starts);
|
|
3524
|
+
}, [trace]);
|
|
3525
|
+
const accountedMs = react.useMemo(
|
|
3526
|
+
() => (trace?.pipelineSteps ?? []).reduce(
|
|
3527
|
+
(sum, s) => sum + (s.durationMs ?? 0),
|
|
3528
|
+
0
|
|
3529
|
+
),
|
|
3530
|
+
[trace]
|
|
3531
|
+
);
|
|
3532
|
+
const unaccountedMs = Math.max(totalMs - accountedMs, 0);
|
|
3533
|
+
if (typeof document === "undefined") return null;
|
|
3534
|
+
return reactDom.createPortal(
|
|
3535
|
+
/* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: open && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3536
|
+
framerMotion.motion.div,
|
|
3537
|
+
{
|
|
3538
|
+
initial: { opacity: 0 },
|
|
3539
|
+
animate: { opacity: 1 },
|
|
3540
|
+
exit: { opacity: 0 },
|
|
3541
|
+
transition: { duration: 0.15 },
|
|
3542
|
+
onClick: onClose,
|
|
3543
|
+
style: {
|
|
3544
|
+
position: "fixed",
|
|
3545
|
+
inset: 0,
|
|
3546
|
+
background: "rgba(0,0,0,0.45)",
|
|
3547
|
+
zIndex: 9999,
|
|
3548
|
+
display: "flex",
|
|
3549
|
+
alignItems: "center",
|
|
3550
|
+
justifyContent: "center",
|
|
3551
|
+
padding: 24
|
|
3552
|
+
},
|
|
3553
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3554
|
+
framerMotion.motion.div,
|
|
3555
|
+
{
|
|
3556
|
+
initial: { y: 12, opacity: 0 },
|
|
3557
|
+
animate: { y: 0, opacity: 1 },
|
|
3558
|
+
exit: { y: 12, opacity: 0 },
|
|
3559
|
+
transition: { duration: 0.18 },
|
|
3560
|
+
onClick: (e) => e.stopPropagation(),
|
|
3561
|
+
style: {
|
|
3562
|
+
background: "#0b1220",
|
|
3563
|
+
color: "#e5e7eb",
|
|
3564
|
+
borderRadius: 12,
|
|
3565
|
+
width: "100%",
|
|
3566
|
+
maxWidth: 760,
|
|
3567
|
+
maxHeight: "85vh",
|
|
3568
|
+
overflow: "auto",
|
|
3569
|
+
boxShadow: "0 20px 60px rgba(0,0,0,0.45)",
|
|
3570
|
+
fontFamily: "ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, sans-serif"
|
|
3571
|
+
},
|
|
3572
|
+
children: [
|
|
3573
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
3574
|
+
"header",
|
|
3575
|
+
{
|
|
3576
|
+
style: {
|
|
3577
|
+
display: "flex",
|
|
3578
|
+
alignItems: "center",
|
|
3579
|
+
justifyContent: "space-between",
|
|
3580
|
+
padding: "14px 18px",
|
|
3581
|
+
borderBottom: "1px solid rgba(255,255,255,0.08)"
|
|
3582
|
+
},
|
|
3583
|
+
children: [
|
|
3584
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
3585
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 14, fontWeight: 600 }, children: "Execution trace" }),
|
|
3586
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3587
|
+
"div",
|
|
3588
|
+
{
|
|
3589
|
+
style: {
|
|
3590
|
+
fontSize: 11,
|
|
3591
|
+
opacity: 0.6,
|
|
3592
|
+
marginTop: 2,
|
|
3593
|
+
fontFamily: "ui-monospace, SFMono-Regular, monospace"
|
|
3594
|
+
},
|
|
3595
|
+
children: executionId ?? ""
|
|
3596
|
+
}
|
|
3597
|
+
)
|
|
3598
|
+
] }),
|
|
3599
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3600
|
+
"button",
|
|
3601
|
+
{
|
|
3602
|
+
onClick: onClose,
|
|
3603
|
+
"aria-label": "Close",
|
|
3604
|
+
style: {
|
|
3605
|
+
background: "transparent",
|
|
3606
|
+
border: 0,
|
|
3607
|
+
color: "#e5e7eb",
|
|
3608
|
+
cursor: "pointer",
|
|
3609
|
+
padding: 6,
|
|
3610
|
+
borderRadius: 6
|
|
3611
|
+
},
|
|
3612
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { style: { width: 18, height: 18 } })
|
|
3613
|
+
}
|
|
3614
|
+
)
|
|
3615
|
+
]
|
|
3616
|
+
}
|
|
3617
|
+
),
|
|
3618
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { padding: 18 }, children: [
|
|
3619
|
+
loading && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { opacity: 0.7, fontSize: 13 }, children: "Loading trace\u2026" }),
|
|
3620
|
+
error && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3621
|
+
"div",
|
|
3622
|
+
{
|
|
3623
|
+
style: {
|
|
3624
|
+
color: "#fca5a5",
|
|
3625
|
+
fontSize: 13,
|
|
3626
|
+
whiteSpace: "pre-wrap"
|
|
3627
|
+
},
|
|
3628
|
+
children: error
|
|
3629
|
+
}
|
|
3630
|
+
),
|
|
3631
|
+
trace && !loading && !error && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3632
|
+
TimelineBars,
|
|
3633
|
+
{
|
|
3634
|
+
trace,
|
|
3635
|
+
totalMs,
|
|
3636
|
+
unaccountedMs
|
|
3637
|
+
}
|
|
3638
|
+
)
|
|
3639
|
+
] })
|
|
3640
|
+
]
|
|
3641
|
+
}
|
|
3642
|
+
)
|
|
3643
|
+
}
|
|
3644
|
+
) }),
|
|
3645
|
+
document.body
|
|
3646
|
+
);
|
|
3647
|
+
}
|
|
3648
|
+
function TimelineBars({
|
|
3649
|
+
trace,
|
|
3650
|
+
totalMs,
|
|
3651
|
+
unaccountedMs
|
|
3652
|
+
}) {
|
|
3653
|
+
const bars = trace.pipelineSteps.map((step) => {
|
|
3654
|
+
const duration = step.durationMs ?? 0;
|
|
3655
|
+
const widthPct = totalMs > 0 ? duration / totalMs * 100 : 0;
|
|
3656
|
+
const llmMs = step.llmCall?.durationMs ?? null;
|
|
3657
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginBottom: 8 }, children: [
|
|
3658
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
3659
|
+
"div",
|
|
3660
|
+
{
|
|
3661
|
+
style: {
|
|
3662
|
+
display: "flex",
|
|
3663
|
+
justifyContent: "space-between",
|
|
3664
|
+
fontSize: 12,
|
|
3665
|
+
marginBottom: 4,
|
|
3666
|
+
fontFamily: "ui-monospace, SFMono-Regular, monospace"
|
|
3667
|
+
},
|
|
3668
|
+
children: [
|
|
3669
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
3670
|
+
step.step,
|
|
3671
|
+
step.status === "failed" && /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "#fca5a5", marginLeft: 6 }, children: "(failed)" })
|
|
3672
|
+
] }),
|
|
3673
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { style: { opacity: 0.75 }, children: [
|
|
3674
|
+
formatMs(duration),
|
|
3675
|
+
llmMs != null && /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { marginLeft: 8, opacity: 0.6 }, children: [
|
|
3676
|
+
"(LLM ",
|
|
3677
|
+
formatMs(llmMs),
|
|
3678
|
+
")"
|
|
3679
|
+
] })
|
|
3680
|
+
] })
|
|
3681
|
+
]
|
|
3682
|
+
}
|
|
3683
|
+
),
|
|
3684
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3685
|
+
"div",
|
|
3686
|
+
{
|
|
3687
|
+
style: {
|
|
3688
|
+
height: 8,
|
|
3689
|
+
background: "rgba(255,255,255,0.06)",
|
|
3690
|
+
borderRadius: 4,
|
|
3691
|
+
overflow: "hidden"
|
|
3692
|
+
},
|
|
3693
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3694
|
+
"div",
|
|
3695
|
+
{
|
|
3696
|
+
style: {
|
|
3697
|
+
height: "100%",
|
|
3698
|
+
width: `${Math.max(widthPct, 0.3)}%`,
|
|
3699
|
+
background: stepColor(step),
|
|
3700
|
+
transition: "width 0.2s ease"
|
|
3701
|
+
}
|
|
3702
|
+
}
|
|
3703
|
+
)
|
|
3704
|
+
}
|
|
3705
|
+
)
|
|
3706
|
+
] }, `${step.step}-${step.startTime}`);
|
|
3707
|
+
});
|
|
3708
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
3709
|
+
bars,
|
|
3710
|
+
unaccountedMs > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginBottom: 8 }, children: [
|
|
3711
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
3712
|
+
"div",
|
|
3713
|
+
{
|
|
3714
|
+
style: {
|
|
3715
|
+
display: "flex",
|
|
3716
|
+
justifyContent: "space-between",
|
|
3717
|
+
fontSize: 12,
|
|
3718
|
+
marginBottom: 4,
|
|
3719
|
+
fontFamily: "ui-monospace, SFMono-Regular, monospace",
|
|
3720
|
+
opacity: 0.7
|
|
3721
|
+
},
|
|
3722
|
+
children: [
|
|
3723
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "(unaccounted)" }),
|
|
3724
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: formatMs(unaccountedMs) })
|
|
3725
|
+
]
|
|
3726
|
+
}
|
|
3727
|
+
),
|
|
3728
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3729
|
+
"div",
|
|
3730
|
+
{
|
|
3731
|
+
style: {
|
|
3732
|
+
height: 8,
|
|
3733
|
+
background: "rgba(255,255,255,0.06)",
|
|
3734
|
+
borderRadius: 4,
|
|
3735
|
+
overflow: "hidden"
|
|
3736
|
+
},
|
|
3737
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3738
|
+
"div",
|
|
3739
|
+
{
|
|
3740
|
+
style: {
|
|
3741
|
+
height: "100%",
|
|
3742
|
+
width: `${unaccountedMs / Math.max(totalMs, 1) * 100}%`,
|
|
3743
|
+
background: "repeating-linear-gradient(45deg, rgba(255,255,255,0.18) 0 4px, transparent 4px 8px)"
|
|
3744
|
+
}
|
|
3745
|
+
}
|
|
3746
|
+
)
|
|
3747
|
+
}
|
|
3748
|
+
)
|
|
3749
|
+
] }),
|
|
3750
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
3751
|
+
"div",
|
|
3752
|
+
{
|
|
3753
|
+
style: {
|
|
3754
|
+
marginTop: 14,
|
|
3755
|
+
paddingTop: 12,
|
|
3756
|
+
borderTop: "1px solid rgba(255,255,255,0.08)",
|
|
3757
|
+
fontSize: 12,
|
|
3758
|
+
display: "flex",
|
|
3759
|
+
justifyContent: "space-between",
|
|
3760
|
+
opacity: 0.85
|
|
3761
|
+
},
|
|
3762
|
+
children: [
|
|
3763
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
3764
|
+
trace.pipelineSteps.length,
|
|
3765
|
+
" step",
|
|
3766
|
+
trace.pipelineSteps.length === 1 ? "" : "s"
|
|
3767
|
+
] }),
|
|
3768
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { style: { fontFamily: "ui-monospace, SFMono-Regular, monospace" }, children: [
|
|
3769
|
+
"total: ",
|
|
3770
|
+
formatMs(totalMs)
|
|
3771
|
+
] })
|
|
3772
|
+
]
|
|
3773
|
+
}
|
|
3774
|
+
)
|
|
3775
|
+
] });
|
|
3776
|
+
}
|
|
3254
3777
|
var DEFAULT_USER_ACTION_STATE = {
|
|
3255
3778
|
request: null,
|
|
3256
3779
|
result: null};
|
|
@@ -3441,12 +3964,39 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
|
|
|
3441
3964
|
]
|
|
3442
3965
|
);
|
|
3443
3966
|
const {
|
|
3444
|
-
onExecutionTraceClick,
|
|
3967
|
+
onExecutionTraceClick: rawOnExecutionTraceClick,
|
|
3445
3968
|
onResetSession,
|
|
3446
3969
|
onUploadImageClick,
|
|
3447
3970
|
onAttachFileClick,
|
|
3448
3971
|
onMessageFeedback
|
|
3449
3972
|
} = callbacks;
|
|
3973
|
+
const [debugTraceExecutionId, setDebugTraceExecutionId] = react.useState(null);
|
|
3974
|
+
const handleSubmitFeedback = react.useCallback(
|
|
3975
|
+
async ({ messageId, executionId, feedback, details }) => {
|
|
3976
|
+
if (!executionId) {
|
|
3977
|
+
throw new Error("Cannot submit feedback before the response completes");
|
|
3978
|
+
}
|
|
3979
|
+
await submitAskFeedback({
|
|
3980
|
+
baseUrl: config.api.baseUrl,
|
|
3981
|
+
headers: config.api.headers,
|
|
3982
|
+
executionId,
|
|
3983
|
+
feedback,
|
|
3984
|
+
details
|
|
3985
|
+
});
|
|
3986
|
+
onMessageFeedback?.({
|
|
3987
|
+
messageId,
|
|
3988
|
+
feedback: feedback === "POSITIVE" ? "up" : "down"
|
|
3989
|
+
});
|
|
3990
|
+
},
|
|
3991
|
+
[config.api.baseUrl, config.api.headers, onMessageFeedback]
|
|
3992
|
+
);
|
|
3993
|
+
const onExecutionTraceClick = react.useMemo(() => {
|
|
3994
|
+
if (!config.debug) return rawOnExecutionTraceClick;
|
|
3995
|
+
return (data) => {
|
|
3996
|
+
rawOnExecutionTraceClick?.(data);
|
|
3997
|
+
if (data.executionId) setDebugTraceExecutionId(data.executionId);
|
|
3998
|
+
};
|
|
3999
|
+
}, [config.debug, rawOnExecutionTraceClick]);
|
|
3450
4000
|
const performResetSession = react.useCallback(() => {
|
|
3451
4001
|
resetToEmptyStateRef.current = true;
|
|
3452
4002
|
setEditingMessageId(null);
|
|
@@ -3504,6 +4054,7 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
|
|
|
3504
4054
|
showEmptyStateIcon = true,
|
|
3505
4055
|
emptyStateComponent,
|
|
3506
4056
|
showResetSession = false,
|
|
4057
|
+
enableDeepModeToggle = true,
|
|
3507
4058
|
showAttachmentButton = true,
|
|
3508
4059
|
showUploadImageButton = true,
|
|
3509
4060
|
showAttachFileButton = true,
|
|
@@ -3559,6 +4110,7 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
|
|
|
3559
4110
|
stopRecording();
|
|
3560
4111
|
};
|
|
3561
4112
|
const isV2InputDisabled = !isSessionParamsConfigured || disableInput;
|
|
4113
|
+
const effectiveAnalysisMode = enableDeepModeToggle ? analysisMode : "fast";
|
|
3562
4114
|
const isEmpty = messages.length === 0;
|
|
3563
4115
|
if (isChatDisabled) {
|
|
3564
4116
|
if (disabledComponent) {
|
|
@@ -3617,7 +4169,7 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
|
|
|
3617
4169
|
if (isRecording) stopRecording();
|
|
3618
4170
|
if (text.trim() && !disableInput && isSessionParamsConfigured) {
|
|
3619
4171
|
setEditingMessageId(null);
|
|
3620
|
-
void sendMessage(text.trim(), { analysisMode });
|
|
4172
|
+
void sendMessage(text.trim(), { analysisMode: effectiveAnalysisMode });
|
|
3621
4173
|
}
|
|
3622
4174
|
};
|
|
3623
4175
|
const handleVoicePress = react.useCallback(async () => {
|
|
@@ -3644,7 +4196,9 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
|
|
|
3644
4196
|
(message) => message.id === messageId && message.role === "user"
|
|
3645
4197
|
);
|
|
3646
4198
|
if (!targetMessage?.content.trim()) return;
|
|
3647
|
-
void sendMessage(targetMessage.content.trim(), {
|
|
4199
|
+
void sendMessage(targetMessage.content.trim(), {
|
|
4200
|
+
analysisMode: effectiveAnalysisMode
|
|
4201
|
+
});
|
|
3648
4202
|
const bump = () => messageListV2Ref.current?.scrollToBottom("instant");
|
|
3649
4203
|
requestAnimationFrame(() => {
|
|
3650
4204
|
bump();
|
|
@@ -3652,7 +4206,7 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
|
|
|
3652
4206
|
window.setTimeout(bump, 120);
|
|
3653
4207
|
});
|
|
3654
4208
|
});
|
|
3655
|
-
}, [isWaitingForResponse, messages, sendMessage,
|
|
4209
|
+
}, [isWaitingForResponse, messages, sendMessage, effectiveAnalysisMode]);
|
|
3656
4210
|
const handleClearEditing = react.useCallback(() => {
|
|
3657
4211
|
setEditingMessageId(null);
|
|
3658
4212
|
}, []);
|
|
@@ -3731,8 +4285,8 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
|
|
|
3731
4285
|
onAttachFileClick,
|
|
3732
4286
|
editingMessageId,
|
|
3733
4287
|
onClearEditing: handleClearEditing,
|
|
3734
|
-
analysisMode,
|
|
3735
|
-
onAnalysisModeChange: setAnalysisMode,
|
|
4288
|
+
analysisMode: enableDeepModeToggle ? analysisMode : void 0,
|
|
4289
|
+
onAnalysisModeChange: enableDeepModeToggle ? setAnalysisMode : void 0,
|
|
3736
4290
|
slashCommands
|
|
3737
4291
|
}
|
|
3738
4292
|
)
|
|
@@ -3772,7 +4326,7 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
|
|
|
3772
4326
|
onResendAction: isUserActionSupported ? async () => {
|
|
3773
4327
|
await resendOtp();
|
|
3774
4328
|
} : void 0,
|
|
3775
|
-
|
|
4329
|
+
onSubmitFeedback: handleSubmitFeedback
|
|
3776
4330
|
}
|
|
3777
4331
|
),
|
|
3778
4332
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -3807,8 +4361,8 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
|
|
|
3807
4361
|
onAttachFileClick,
|
|
3808
4362
|
editingMessageId,
|
|
3809
4363
|
onClearEditing: handleClearEditing,
|
|
3810
|
-
analysisMode,
|
|
3811
|
-
onAnalysisModeChange: setAnalysisMode,
|
|
4364
|
+
analysisMode: enableDeepModeToggle ? analysisMode : void 0,
|
|
4365
|
+
onAnalysisModeChange: enableDeepModeToggle ? setAnalysisMode : void 0,
|
|
3812
4366
|
slashCommands
|
|
3813
4367
|
}
|
|
3814
4368
|
)
|
|
@@ -3831,6 +4385,16 @@ var PaymanChatInner = react.forwardRef(function PaymanChatInner2({
|
|
|
3831
4385
|
onClose: closeResetSessionConfirm,
|
|
3832
4386
|
onConfirm: performResetSession
|
|
3833
4387
|
}
|
|
4388
|
+
),
|
|
4389
|
+
config.debug && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4390
|
+
TraceTimelineModal,
|
|
4391
|
+
{
|
|
4392
|
+
open: debugTraceExecutionId !== null,
|
|
4393
|
+
onClose: () => setDebugTraceExecutionId(null),
|
|
4394
|
+
executionId: debugTraceExecutionId,
|
|
4395
|
+
apiBaseUrl: config.api.baseUrl,
|
|
4396
|
+
apiHeaders: config.api.headers
|
|
4397
|
+
}
|
|
3834
4398
|
)
|
|
3835
4399
|
]
|
|
3836
4400
|
}
|