@paymanai/payman-ask-sdk 4.0.28 → 4.0.29

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.mjs CHANGED
@@ -4,7 +4,7 @@ import { AnimatePresence, motion, useMotionValue, useSpring, useInView } from 'f
4
4
  import { clsx } from 'clsx';
5
5
  import { twMerge } from 'tailwind-merge';
6
6
  import * as Sentry from '@sentry/react';
7
- import { ArrowDown, Pencil, X, RotateCcw, Telescope, Zap, ImagePlus, Paperclip, ArrowUp, Check, AlertCircle, Copy, WifiOff, ThumbsUp, ThumbsDown, Binoculars, Info, PanelLeft, Download, Loader2, ChevronDown, MoreHorizontal, User, Clock, Sparkles, ImageOff, Eye, ChevronRight, ShieldCheck } from 'lucide-react';
7
+ import { ArrowDown, Pencil, X, RotateCcw, Telescope, Zap, Plus, ImagePlus, Paperclip, Mic, ArrowUp, Check, AlertCircle, Copy, WifiOff, ThumbsUp, ThumbsDown, Binoculars, Info, Download, Loader2, ChevronDown, User, Clock, Sparkles, ImageOff, Eye, ChevronRight, ShieldCheck } from 'lucide-react';
8
8
  import ReactMarkdown from 'react-markdown';
9
9
  import remarkGfm from 'remark-gfm';
10
10
  import { createPortal } from 'react-dom';
@@ -1794,284 +1794,6 @@ function useVoice(config = {}, callbacks = {}) {
1794
1794
  reset
1795
1795
  };
1796
1796
  }
1797
- var DEFAULT_PAGE_SIZE = 20;
1798
- var DEFAULT_MESSAGES_PAGE_SIZE = 100;
1799
- function defaultParseSessions(json) {
1800
- const body = json;
1801
- const rows = Array.isArray(body?.data) ? body.data : [];
1802
- const data = rows.map((row) => ({ ...row, title: row.title ?? row.sessionTitle ?? null }));
1803
- return { data, total: body?.total };
1804
- }
1805
- function defaultParseMessages(json) {
1806
- const body = json;
1807
- return { data: Array.isArray(body?.data) ? body.data : [] };
1808
- }
1809
- function withQuery(path, params) {
1810
- const qs = Object.entries(params).map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`).join("&");
1811
- if (!qs) return path;
1812
- return `${path}${path.includes("?") ? "&" : "?"}${qs}`;
1813
- }
1814
- function toFeedbackState(feedback) {
1815
- const value = feedback?.feedback;
1816
- if (!value) return null;
1817
- return value === "POSITIVE" ? "up" : "down";
1818
- }
1819
- function toMessageDisplay(rows, sessionId) {
1820
- return rows.flatMap((row) => {
1821
- const timestamp = row.startTime || row.endTime || (/* @__PURE__ */ new Date()).toISOString();
1822
- const out = [
1823
- {
1824
- id: `${row.id}:user`,
1825
- sessionId,
1826
- role: "user",
1827
- content: row.sessionUserIntent,
1828
- timestamp
1829
- }
1830
- ];
1831
- if (row.agentResponse) {
1832
- out.push({
1833
- id: `${row.id}:assistant`,
1834
- sessionId,
1835
- role: "assistant",
1836
- content: row.agentResponse,
1837
- timestamp: row.endTime || timestamp,
1838
- executionId: row.id,
1839
- isError: row.status === "FAILED",
1840
- feedback: toFeedbackState(row.feedback)
1841
- });
1842
- }
1843
- return out;
1844
- });
1845
- }
1846
- function useChatSessions({
1847
- api,
1848
- sessions,
1849
- initialSessionId
1850
- }) {
1851
- const enabled = sessions?.enabled === true;
1852
- const listEndpoint = sessions?.listEndpoint ?? "/api/conversations/sessions";
1853
- const messagesEndpointTemplate = sessions?.messagesEndpoint ?? "/api/conversations/sessions/{sessionId}/messages";
1854
- const pageSize = sessions?.pageSize ?? DEFAULT_PAGE_SIZE;
1855
- const messagesPageSize = sessions?.messagesPageSize ?? DEFAULT_MESSAGES_PAGE_SIZE;
1856
- const parseSessionsResponse = sessions?.parseSessionsResponse ?? defaultParseSessions;
1857
- const parseMessagesResponse = sessions?.parseMessagesResponse ?? defaultParseMessages;
1858
- const [sessionsList, setSessionsList] = useState([]);
1859
- const [isLoadingList, setIsLoadingList] = useState(enabled);
1860
- const [isLoadingMore, setIsLoadingMore] = useState(false);
1861
- const [listError, setListError] = useState(null);
1862
- const hasLoadedOnceRef = useRef(false);
1863
- const [page, setPage] = useState(0);
1864
- const [total, setTotal] = useState(null);
1865
- const [lastPageFull, setLastPageFull] = useState(false);
1866
- const [selectedSessionId, setSelectedSessionId] = useState(
1867
- initialSessionId ?? null
1868
- );
1869
- const [draftSessionId, setDraftSessionId] = useState(generateId);
1870
- const [selectedMessages, setSelectedMessages] = useState([]);
1871
- const [isLoadingMessages, setIsLoadingMessages] = useState(
1872
- enabled && initialSessionId != null
1873
- );
1874
- const [messagesError, setMessagesError] = useState(null);
1875
- const [refetchTick, setRefetchTick] = useState(0);
1876
- const baseUrl = (api.baseUrl || "").replace(/\/+$/, "");
1877
- const apiHeaders = api.headers;
1878
- const authToken = api.authToken;
1879
- const headersKey = JSON.stringify(apiHeaders ?? {});
1880
- const requestHeaders = useMemo(() => {
1881
- const headers = { Accept: "application/json", ...apiHeaders ?? {} };
1882
- if (authToken && !headers.Authorization) headers.Authorization = `Bearer ${authToken}`;
1883
- return headers;
1884
- }, [headersKey, authToken]);
1885
- const hasMore = total != null ? sessionsList.length < total : lastPageFull;
1886
- useEffect(() => {
1887
- setPage(0);
1888
- hasLoadedOnceRef.current = false;
1889
- }, [enabled, baseUrl, listEndpoint, pageSize, requestHeaders]);
1890
- useEffect(() => {
1891
- setPage(0);
1892
- }, [refetchTick]);
1893
- useEffect(() => {
1894
- if (!enabled) return;
1895
- const ctrl = new AbortController();
1896
- const isFirstPage = page === 0;
1897
- if (isFirstPage && !hasLoadedOnceRef.current) setIsLoadingList(true);
1898
- else if (!isFirstPage) setIsLoadingMore(true);
1899
- setListError(null);
1900
- fetch(withQuery(`${baseUrl}${listEndpoint}`, { page, limit: pageSize }), {
1901
- method: "GET",
1902
- headers: requestHeaders,
1903
- signal: ctrl.signal
1904
- }).then(async (res) => {
1905
- if (!res.ok) throw new Error(`Failed to load chats (${res.status})`);
1906
- return res.json();
1907
- }).then((json) => {
1908
- const parsed = parseSessionsResponse(json);
1909
- setSessionsList((prev) => isFirstPage ? parsed.data : [...prev, ...parsed.data]);
1910
- setTotal(parsed.total ?? null);
1911
- setLastPageFull(parsed.data.length >= pageSize);
1912
- hasLoadedOnceRef.current = true;
1913
- }).catch((e) => {
1914
- if (e.name === "AbortError") return;
1915
- setListError(e instanceof Error ? e.message : "Failed to load chats");
1916
- }).finally(() => {
1917
- setIsLoadingList(false);
1918
- setIsLoadingMore(false);
1919
- });
1920
- return () => ctrl.abort();
1921
- }, [enabled, baseUrl, listEndpoint, pageSize, requestHeaders, refetchTick, page]);
1922
- useEffect(() => {
1923
- if (!enabled || !selectedSessionId) {
1924
- setSelectedMessages([]);
1925
- return;
1926
- }
1927
- const ctrl = new AbortController();
1928
- setIsLoadingMessages(true);
1929
- setMessagesError(null);
1930
- const path = messagesEndpointTemplate.replace(
1931
- "{sessionId}",
1932
- encodeURIComponent(selectedSessionId)
1933
- );
1934
- fetch(withQuery(`${baseUrl}${path}`, { limit: messagesPageSize }), {
1935
- method: "GET",
1936
- headers: requestHeaders,
1937
- signal: ctrl.signal
1938
- }).then(async (res) => {
1939
- if (!res.ok) throw new Error(`Failed to load messages (${res.status})`);
1940
- return res.json();
1941
- }).then(
1942
- (json) => setSelectedMessages(
1943
- toMessageDisplay(parseMessagesResponse(json).data, selectedSessionId)
1944
- )
1945
- ).catch((e) => {
1946
- if (e.name === "AbortError") return;
1947
- setMessagesError(e instanceof Error ? e.message : "Failed to load messages");
1948
- setSelectedMessages([]);
1949
- }).finally(() => setIsLoadingMessages(false));
1950
- return () => ctrl.abort();
1951
- }, [enabled, selectedSessionId, baseUrl, messagesEndpointTemplate, messagesPageSize, requestHeaders]);
1952
- const loadMore = useCallback(() => {
1953
- setPage((prev) => {
1954
- if (isLoadingList || isLoadingMore || !hasMore) return prev;
1955
- return prev + 1;
1956
- });
1957
- }, [isLoadingList, isLoadingMore, hasMore]);
1958
- const selectSession = useCallback((sessionId) => {
1959
- setSelectedSessionId(sessionId);
1960
- setSelectedMessages([]);
1961
- }, []);
1962
- const startNewSession = useCallback(() => {
1963
- setSelectedSessionId(null);
1964
- setDraftSessionId(generateId());
1965
- setSelectedMessages([]);
1966
- }, []);
1967
- const refetch = useCallback(() => setRefetchTick((tick) => tick + 1), []);
1968
- const noteSentMessage = useCallback(
1969
- (text) => {
1970
- const id = selectedSessionId ?? draftSessionId;
1971
- const now = (/* @__PURE__ */ new Date()).toISOString();
1972
- const trimmed = text.trim();
1973
- setSessionsList((prev) => {
1974
- const idx = prev.findIndex((s) => s.sessionId === id);
1975
- if (idx >= 0) {
1976
- const existing = prev[idx];
1977
- const bumped = {
1978
- ...existing,
1979
- lastMessageAt: now,
1980
- messageCount: (existing.messageCount ?? 0) + 1,
1981
- title: existing.title?.trim() ? existing.title : trimmed
1982
- };
1983
- return [bumped, ...prev.slice(0, idx), ...prev.slice(idx + 1)];
1984
- }
1985
- const fresh = {
1986
- sessionId: id,
1987
- title: trimmed,
1988
- messageCount: 1,
1989
- lastMessageAt: now,
1990
- status: "PROCESSING"
1991
- };
1992
- return [fresh, ...prev];
1993
- });
1994
- },
1995
- [selectedSessionId, draftSessionId]
1996
- );
1997
- return {
1998
- enabled,
1999
- sessionsList,
2000
- isLoadingList,
2001
- listError,
2002
- total,
2003
- hasMore,
2004
- isLoadingMore,
2005
- loadMore,
2006
- noteSentMessage,
2007
- selectedSessionId,
2008
- activeSessionId: selectedSessionId ?? draftSessionId,
2009
- selectSession,
2010
- startNewSession,
2011
- selectedMessages,
2012
- isLoadingMessages,
2013
- messagesError,
2014
- refetch
2015
- };
2016
- }
2017
- function deriveStatus(enabled, blocked) {
2018
- if (blocked === true) return "blocked";
2019
- if (enabled === false) return "disabled";
2020
- if (enabled === true) return "available";
2021
- return "unknown";
2022
- }
2023
- function defaultParse(json) {
2024
- const body = json;
2025
- return {
2026
- available: body?.enabled === true && body?.blocked !== true,
2027
- status: deriveStatus(body?.enabled, body?.blocked),
2028
- config: body ?? void 0
2029
- };
2030
- }
2031
- function useAgentConfig({ api, availability }) {
2032
- const enabled = availability?.enabled === true;
2033
- const endpoint = availability?.endpoint ?? "/api/agent/config";
2034
- const parseResponse = availability?.parseResponse ?? defaultParse;
2035
- const [available, setAvailable] = useState(null);
2036
- const [status, setStatus] = useState("unknown");
2037
- const [config, setConfig] = useState(void 0);
2038
- const [isLoading, setIsLoading] = useState(enabled);
2039
- const [error, setError] = useState(null);
2040
- const [refetchTick, setRefetchTick] = useState(0);
2041
- const baseUrl = (api.baseUrl || "").replace(/\/+$/, "");
2042
- const apiHeaders = api.headers;
2043
- const authToken = api.authToken;
2044
- const requestHeaders = useMemo(() => {
2045
- const headers = { Accept: "application/json", ...apiHeaders ?? {} };
2046
- if (authToken && !headers.Authorization) headers.Authorization = `Bearer ${authToken}`;
2047
- return headers;
2048
- }, [apiHeaders, authToken]);
2049
- useEffect(() => {
2050
- if (!enabled) return;
2051
- const ctrl = new AbortController();
2052
- setIsLoading(true);
2053
- setError(null);
2054
- fetch(`${baseUrl}${endpoint}`, {
2055
- method: "GET",
2056
- headers: requestHeaders,
2057
- signal: ctrl.signal
2058
- }).then(async (res) => {
2059
- if (!res.ok) throw new Error(`Failed to check availability (${res.status})`);
2060
- return res.json();
2061
- }).then((json) => {
2062
- const parsed = parseResponse(json);
2063
- setAvailable(parsed.available);
2064
- setStatus(parsed.status ?? deriveStatus(parsed.available, void 0));
2065
- setConfig(parsed.config);
2066
- }).catch((e) => {
2067
- if (e.name === "AbortError") return;
2068
- setError(e instanceof Error ? e.message : "Failed to check availability");
2069
- }).finally(() => setIsLoading(false));
2070
- return () => ctrl.abort();
2071
- }, [enabled, baseUrl, endpoint, requestHeaders, refetchTick]);
2072
- const refetch = useCallback(() => setRefetchTick((tick) => tick + 1), []);
2073
- return { enabled, available, status, config, isLoading, error, refetch };
2074
- }
2075
1797
  function classifyField(field) {
2076
1798
  if (!field) return "text";
2077
1799
  if (Array.isArray(field.oneOf) && field.oneOf.length > 0) return "select";
@@ -3528,10 +3250,11 @@ function UserMessageV2({
3528
3250
  ),
3529
3251
  style: { borderRadius: 9999 },
3530
3252
  children: [
3531
- toast.tone === "success" ? /* @__PURE__ */ jsx(Check, { style: { width: 14, height: 14, color: "#059669" } }) : /* @__PURE__ */ jsx(
3253
+ toast.tone === "success" ? /* @__PURE__ */ jsx(Check, { className: "h-3.5 w-3.5", style: { color: "#059669" } }) : /* @__PURE__ */ jsx(
3532
3254
  AlertCircle,
3533
3255
  {
3534
- style: { width: 14, height: 14, color: "#ef4444" }
3256
+ className: "h-3.5 w-3.5",
3257
+ style: { color: "#ef4444" }
3535
3258
  }
3536
3259
  ),
3537
3260
  /* @__PURE__ */ jsx("span", { children: toast.label })
@@ -3555,13 +3278,8 @@ function UserMessageV2({
3555
3278
  /* @__PURE__ */ jsx(
3556
3279
  AlertCircle,
3557
3280
  {
3558
- style: {
3559
- width: 14,
3560
- height: 14,
3561
- flexShrink: 0,
3562
- color: "rgba(239, 68, 68, 0.7)",
3563
- marginTop: "2px"
3564
- }
3281
+ className: "h-3.5 w-3.5 shrink-0",
3282
+ style: { color: "rgba(239, 68, 68, 0.7)", marginTop: "2px" }
3565
3283
  }
3566
3284
  ),
3567
3285
  /* @__PURE__ */ jsx("p", { className: "payman-v2-user-msg-error-text", children: resolvedError })
@@ -3579,9 +3297,10 @@ function UserMessageV2({
3579
3297
  children: copied ? /* @__PURE__ */ jsx(
3580
3298
  Check,
3581
3299
  {
3582
- style: { width: 14, height: 14, color: "#059669" }
3300
+ className: "h-3.5 w-3.5",
3301
+ style: { color: "#059669" }
3583
3302
  }
3584
- ) : /* @__PURE__ */ jsx(Copy, { style: { width: 14, height: 14 } })
3303
+ ) : /* @__PURE__ */ jsx(Copy, { className: "h-3.5 w-3.5" })
3585
3304
  }
3586
3305
  ) }),
3587
3306
  showEditAction && onEdit && /* @__PURE__ */ jsx(ActionTooltipV2, { label: "Edit", children: /* @__PURE__ */ jsx(
@@ -3591,7 +3310,7 @@ function UserMessageV2({
3591
3310
  onClick: () => onEdit(message.id),
3592
3311
  className: "payman-v2-user-msg-action-btn",
3593
3312
  "aria-label": "Edit message",
3594
- children: /* @__PURE__ */ jsx(Pencil, { style: { width: 14, height: 14 } })
3313
+ children: /* @__PURE__ */ jsx(Pencil, { className: "h-3.5 w-3.5" })
3595
3314
  }
3596
3315
  ) }),
3597
3316
  showRetryAction && onRetry && /* @__PURE__ */ jsx(ActionTooltipV2, { label: "Retry", children: /* @__PURE__ */ jsx(
@@ -3602,7 +3321,7 @@ function UserMessageV2({
3602
3321
  disabled: retryDisabled,
3603
3322
  className: "payman-v2-user-msg-action-btn",
3604
3323
  "aria-label": "Retry message",
3605
- children: /* @__PURE__ */ jsx(RotateCcw, { style: { width: 14, height: 14 } })
3324
+ children: /* @__PURE__ */ jsx(RotateCcw, { className: "h-3.5 w-3.5" })
3606
3325
  }
3607
3326
  ) })
3608
3327
  ] })
@@ -4516,12 +4235,14 @@ function AssistantMessageV2({
4516
4235
  toast.tone === "success" ? /* @__PURE__ */ jsx(
4517
4236
  Check,
4518
4237
  {
4519
- style: { width: 14, height: 14, color: "#059669" }
4238
+ className: "h-3.5 w-3.5",
4239
+ style: { color: "#059669" }
4520
4240
  }
4521
4241
  ) : /* @__PURE__ */ jsx(
4522
4242
  AlertCircle,
4523
4243
  {
4524
- style: { width: 14, height: 14, color: "#ef4444" }
4244
+ className: "h-3.5 w-3.5",
4245
+ style: { color: "#ef4444" }
4525
4246
  }
4526
4247
  ),
4527
4248
  /* @__PURE__ */ jsx("span", { children: toast.label })
@@ -5871,62 +5592,6 @@ var MessageListV2 = forwardRef(
5871
5592
  ] });
5872
5593
  }
5873
5594
  );
5874
- function IconNewChat({ size = 16, className, style }) {
5875
- return /* @__PURE__ */ jsx("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", className, style, "aria-hidden": true, children: /* @__PURE__ */ jsx(
5876
- "path",
5877
- {
5878
- d: "M11.9991 14.25V12M11.9991 12V9.75M11.9991 12H9.74936M11.9991 12H14.2489M20.9983 12C20.9983 13.2938 20.7253 14.5238 20.2338 15.6356L21 20.9991L16.4039 19.85C15.1019 20.5823 13.5993 21 11.9991 21C7.02906 21 3 16.9706 3 12C3 7.02944 7.02906 3 11.9991 3C16.9692 3 20.9983 7.02944 20.9983 12Z",
5879
- stroke: "currentColor",
5880
- strokeWidth: 2,
5881
- strokeLinecap: "round",
5882
- strokeLinejoin: "round"
5883
- }
5884
- ) });
5885
- }
5886
- function IconPlus({ size = 16, className, style }) {
5887
- return /* @__PURE__ */ jsx("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", className, style, "aria-hidden": true, children: /* @__PURE__ */ jsx(
5888
- "path",
5889
- {
5890
- d: "M12.0001 4.7998L12 19.1998M19.2 11.9998L4.80005 11.9998",
5891
- stroke: "currentColor",
5892
- strokeWidth: 2,
5893
- strokeLinecap: "round"
5894
- }
5895
- ) });
5896
- }
5897
- function IconMic({ size = 18, className, style }) {
5898
- return /* @__PURE__ */ jsx("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", className, style, "aria-hidden": true, children: /* @__PURE__ */ jsx(
5899
- "path",
5900
- {
5901
- d: "M2.49292 13.3764C2.82536 15.6606 3.96908 17.7487 5.71484 19.2588C7.4606 20.7688 9.69168 21.5999 11.9999 21.5999C14.3082 21.5999 16.5393 20.7688 18.285 19.2588C20.0308 17.7487 21.1745 15.6606 21.5069 13.3764M12.0013 2.3999C10.9096 2.3999 9.86265 2.83357 9.09072 3.6055C8.31878 4.37744 7.88512 5.4244 7.88512 6.51608V12.0043C7.88512 13.096 8.31878 14.143 9.09072 14.9149C9.86265 15.6868 10.9096 16.1205 12.0013 16.1205C13.093 16.1205 14.1399 15.6868 14.9119 14.9149C15.6838 14.143 16.1175 13.096 16.1175 12.0043V6.51608C16.1175 5.4244 15.6838 4.37744 14.9119 3.6055C14.1399 2.83357 13.093 2.3999 12.0013 2.3999Z",
5902
- stroke: "currentColor",
5903
- strokeWidth: 2,
5904
- strokeLinecap: "round",
5905
- strokeLinejoin: "round"
5906
- }
5907
- ) });
5908
- }
5909
- function IconClock({ size = 12, className, style }) {
5910
- return /* @__PURE__ */ jsx("svg", { width: size, height: size, viewBox: "0 0 25 24", fill: "none", className, style, "aria-hidden": true, children: /* @__PURE__ */ jsx(
5911
- "path",
5912
- {
5913
- d: "M15.5588 15.1987C16.0827 15.3733 16.649 15.0902 16.8237 14.5662C16.9983 14.0423 16.7152 13.476 16.1912 13.3013L15.5588 15.1987ZM12.5 13.125H11.5C11.5 13.5554 11.7754 13.9376 12.1838 14.0737L12.5 13.125ZM13.5 8.42087C13.5 7.86858 13.0523 7.42087 12.5 7.42087C11.9477 7.42087 11.5 7.86858 11.5 8.42087H13.5ZM16.1912 13.3013L12.8162 12.1763L12.1838 14.0737L15.5588 15.1987L16.1912 13.3013ZM13.5 13.125V8.42087H11.5V13.125H13.5ZM20.5 12C20.5 16.4183 16.9183 20 12.5 20V22C18.0228 22 22.5 17.5228 22.5 12H20.5ZM12.5 20C8.08172 20 4.5 16.4183 4.5 12H2.5C2.5 17.5228 6.97715 22 12.5 22V20ZM4.5 12C4.5 7.58172 8.08172 4 12.5 4V2C6.97715 2 2.5 6.47715 2.5 12H4.5ZM12.5 4C16.9183 4 20.5 7.58172 20.5 12H22.5C22.5 6.47715 18.0228 2 12.5 2V4Z",
5914
- fill: "currentColor"
5915
- }
5916
- ) });
5917
- }
5918
- function IconMessage({ size = 12, className, style }) {
5919
- return /* @__PURE__ */ jsx("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", className, style, "aria-hidden": true, children: /* @__PURE__ */ jsx(
5920
- "path",
5921
- {
5922
- d: "M8.39917 8.40002H15.5992M8.39917 13.2H12.5992M21.5992 12C21.5992 13.3801 21.308 14.6921 20.7837 15.878L21.601 21.5991L16.6981 20.3734C15.3091 21.1545 13.7062 21.6 11.9992 21.6C6.69724 21.6 2.39917 17.302 2.39917 12C2.39917 6.69809 6.69724 2.40002 11.9992 2.40002C17.3011 2.40002 21.5992 6.69809 21.5992 12Z",
5923
- stroke: "currentColor",
5924
- strokeWidth: 2,
5925
- strokeLinecap: "round",
5926
- strokeLinejoin: "round"
5927
- }
5928
- ) });
5929
- }
5930
5595
  var ChatInputV2 = forwardRef(
5931
5596
  function ChatInputV22({
5932
5597
  onSend,
@@ -6317,7 +5982,12 @@ var ChatInputV2 = forwardRef(
6317
5982
  showActions && "payman-v2-input-attach-btn-active"
6318
5983
  ),
6319
5984
  "aria-label": "Attach",
6320
- children: /* @__PURE__ */ jsx(IconPlus, { size: 20 })
5985
+ children: /* @__PURE__ */ jsx(
5986
+ Plus,
5987
+ {
5988
+ style: { width: 20, height: 20, strokeWidth: 2 }
5989
+ }
5990
+ )
6321
5991
  }
6322
5992
  ),
6323
5993
  /* @__PURE__ */ jsx(AnimatePresence, { children: showActions && /* @__PURE__ */ jsxs(
@@ -6400,7 +6070,7 @@ var ChatInputV2 = forwardRef(
6400
6070
  ),
6401
6071
  "aria-label": isRecording ? "Stop recording" : "Voice input",
6402
6072
  children: [
6403
- /* @__PURE__ */ jsx(IconMic, { size: 18 }),
6073
+ /* @__PURE__ */ jsx(Mic, { style: { width: 18, height: 18 } }),
6404
6074
  isRecording && /* @__PURE__ */ jsx("span", { className: "payman-v2-input-mic-indicator" })
6405
6075
  ]
6406
6076
  }
@@ -7463,584 +7133,6 @@ function TimelineBars({
7463
7133
  )
7464
7134
  ] });
7465
7135
  }
7466
- var MIN_SIDEBAR_WIDTH = 240;
7467
- var MAX_SIDEBAR_WIDTH = 520;
7468
- var DEFAULT_SIDEBAR_WIDTH = 264;
7469
- var WIDTH_STORAGE_KEY = "payman-v2-sessions-width";
7470
- function readStoredWidth() {
7471
- if (typeof window === "undefined") return DEFAULT_SIDEBAR_WIDTH;
7472
- const raw = Number(window.localStorage?.getItem(WIDTH_STORAGE_KEY));
7473
- if (Number.isFinite(raw) && raw >= MIN_SIDEBAR_WIDTH && raw <= MAX_SIDEBAR_WIDTH) return raw;
7474
- return DEFAULT_SIDEBAR_WIDTH;
7475
- }
7476
- function formatRelativeTime(iso) {
7477
- if (!iso) return "";
7478
- const date = new Date(iso);
7479
- if (Number.isNaN(date.getTime())) return "";
7480
- const diffSec = Math.round((Date.now() - date.getTime()) / 1e3);
7481
- if (diffSec < 60) return "just now";
7482
- const diffMin = Math.round(diffSec / 60);
7483
- if (diffMin < 60) return `${diffMin} minute${diffMin === 1 ? "" : "s"} ago`;
7484
- const diffHr = Math.round(diffMin / 60);
7485
- if (diffHr < 24) return `${diffHr} hour${diffHr === 1 ? "" : "s"} ago`;
7486
- const diffDay = Math.round(diffHr / 24);
7487
- if (diffDay < 7) return `${diffDay} day${diffDay === 1 ? "" : "s"} ago`;
7488
- return date.toLocaleDateString(void 0, { month: "short", day: "numeric" });
7489
- }
7490
- function SessionsSidebarV2({
7491
- open,
7492
- onClose,
7493
- title,
7494
- newChatLabel,
7495
- sessions,
7496
- isLoading,
7497
- error,
7498
- onRetry,
7499
- selectedSessionId,
7500
- onSelectSession,
7501
- onNewSession,
7502
- actions,
7503
- hasMore,
7504
- isLoadingMore,
7505
- onLoadMore
7506
- }) {
7507
- const [width, setWidth] = useState(readStoredWidth);
7508
- const [isResizing, setIsResizing] = useState(false);
7509
- const dragState = useRef(null);
7510
- const onResizeMove = useCallback((event) => {
7511
- if (!dragState.current) return;
7512
- const delta = event.clientX - dragState.current.startX;
7513
- const next = Math.min(
7514
- MAX_SIDEBAR_WIDTH,
7515
- Math.max(MIN_SIDEBAR_WIDTH, dragState.current.startWidth + delta)
7516
- );
7517
- setWidth(next);
7518
- }, []);
7519
- const onResizeEnd = useCallback(() => {
7520
- dragState.current = null;
7521
- setIsResizing(false);
7522
- document.removeEventListener("mousemove", onResizeMove);
7523
- document.removeEventListener("mouseup", onResizeEnd);
7524
- document.body.style.removeProperty("user-select");
7525
- setWidth((w) => {
7526
- if (typeof window !== "undefined") window.localStorage?.setItem(WIDTH_STORAGE_KEY, String(w));
7527
- return w;
7528
- });
7529
- }, [onResizeMove]);
7530
- const onResizeStart = useCallback(
7531
- (event) => {
7532
- event.preventDefault();
7533
- dragState.current = { startX: event.clientX, startWidth: width };
7534
- setIsResizing(true);
7535
- document.body.style.userSelect = "none";
7536
- document.addEventListener("mousemove", onResizeMove);
7537
- document.addEventListener("mouseup", onResizeEnd);
7538
- },
7539
- [width, onResizeMove, onResizeEnd]
7540
- );
7541
- useEffect(
7542
- () => () => {
7543
- document.removeEventListener("mousemove", onResizeMove);
7544
- document.removeEventListener("mouseup", onResizeEnd);
7545
- },
7546
- [onResizeMove, onResizeEnd]
7547
- );
7548
- return /* @__PURE__ */ jsxs(
7549
- "div",
7550
- {
7551
- className: cn(
7552
- "payman-v2-sessions-sidebar",
7553
- !open && "payman-v2-sessions-sidebar-collapsed",
7554
- isResizing && "payman-v2-sessions-sidebar-resizing"
7555
- ),
7556
- role: "complementary",
7557
- "aria-label": title,
7558
- "aria-hidden": !open,
7559
- style: { "--payman-v2-sessions-width": `${width}px` },
7560
- children: [
7561
- /* @__PURE__ */ jsxs("div", { className: "payman-v2-sessions-sidebar-inner", children: [
7562
- /* @__PURE__ */ jsxs("div", { className: "payman-v2-sessions-header", children: [
7563
- /* @__PURE__ */ jsx("span", { className: "payman-v2-sessions-title", children: title }),
7564
- onClose && /* @__PURE__ */ jsx(
7565
- "button",
7566
- {
7567
- type: "button",
7568
- className: "payman-v2-sessions-close",
7569
- onClick: onClose,
7570
- "aria-label": "Close chats panel",
7571
- tabIndex: open ? 0 : -1,
7572
- children: /* @__PURE__ */ jsx(X, { size: 16 })
7573
- }
7574
- )
7575
- ] }),
7576
- /* @__PURE__ */ jsxs(
7577
- "button",
7578
- {
7579
- type: "button",
7580
- className: "payman-v2-sessions-new-btn",
7581
- onClick: onNewSession,
7582
- tabIndex: open ? 0 : -1,
7583
- children: [
7584
- /* @__PURE__ */ jsx(IconNewChat, { size: 16 }),
7585
- newChatLabel
7586
- ]
7587
- }
7588
- ),
7589
- /* @__PURE__ */ jsx("div", { className: "payman-v2-sessions-divider" }),
7590
- /* @__PURE__ */ jsx(
7591
- SessionsListBody,
7592
- {
7593
- sessions,
7594
- isLoading,
7595
- error,
7596
- onRetry,
7597
- selectedSessionId,
7598
- onSelectSession,
7599
- actions,
7600
- hasMore,
7601
- isLoadingMore,
7602
- onLoadMore
7603
- }
7604
- )
7605
- ] }),
7606
- open && /* @__PURE__ */ jsx(
7607
- "div",
7608
- {
7609
- className: "payman-v2-sessions-resizer",
7610
- onMouseDown: onResizeStart,
7611
- role: "separator",
7612
- "aria-orientation": "vertical",
7613
- "aria-label": "Resize chats panel"
7614
- }
7615
- )
7616
- ]
7617
- }
7618
- );
7619
- }
7620
- function SessionsListBody({
7621
- sessions,
7622
- isLoading,
7623
- error,
7624
- onRetry,
7625
- selectedSessionId,
7626
- onSelectSession,
7627
- actions,
7628
- compact = false,
7629
- hasMore,
7630
- isLoadingMore,
7631
- onLoadMore
7632
- }) {
7633
- const [openMenuId, setOpenMenuId] = useState(null);
7634
- const listRef = useRef(null);
7635
- const [shadow, setShadow] = useState({ top: false, bottom: false });
7636
- const updateShadow = useCallback(() => {
7637
- const el = listRef.current;
7638
- if (!el) return;
7639
- const top = el.scrollTop > 1;
7640
- const bottom = Math.ceil(el.scrollTop + el.clientHeight) < el.scrollHeight - 1;
7641
- setShadow((s) => s.top === top && s.bottom === bottom ? s : { top, bottom });
7642
- }, []);
7643
- useEffect(() => {
7644
- updateShadow();
7645
- const el = listRef.current;
7646
- if (!el) return;
7647
- const ro = new ResizeObserver(updateShadow);
7648
- ro.observe(el);
7649
- return () => ro.disconnect();
7650
- }, [sessions, isLoading, updateShadow]);
7651
- return /* @__PURE__ */ jsx(
7652
- "div",
7653
- {
7654
- className: cn(
7655
- "payman-v2-sessions-list-wrap",
7656
- shadow.top && "payman-v2-scroll-shadow-top",
7657
- shadow.bottom && "payman-v2-scroll-shadow-bottom"
7658
- ),
7659
- children: /* @__PURE__ */ jsx(
7660
- "div",
7661
- {
7662
- ref: listRef,
7663
- onScroll: updateShadow,
7664
- className: cn("payman-v2-sessions-list", compact && "payman-v2-sessions-list-compact"),
7665
- children: isLoading ? /* @__PURE__ */ jsx(SessionsListSkeleton, {}) : error ? /* @__PURE__ */ jsxs("div", { className: "payman-v2-sessions-error", children: [
7666
- /* @__PURE__ */ jsx(AlertCircle, { size: 18 }),
7667
- /* @__PURE__ */ jsx("p", { children: error }),
7668
- onRetry && /* @__PURE__ */ jsx("button", { type: "button", className: "payman-v2-sessions-retry-btn", onClick: onRetry, children: "Try again" })
7669
- ] }) : sessions.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "payman-v2-sessions-empty", children: [
7670
- /* @__PURE__ */ jsx(IconMessage, { size: 20 }),
7671
- /* @__PURE__ */ jsx("p", { children: "No chats yet" })
7672
- ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
7673
- sessions.map((session) => /* @__PURE__ */ jsx(
7674
- SessionRow,
7675
- {
7676
- session,
7677
- isSelected: session.sessionId === selectedSessionId,
7678
- isMenuOpen: openMenuId === session.sessionId,
7679
- onSelect: () => onSelectSession(session.sessionId),
7680
- onToggleMenu: () => setOpenMenuId((id) => id === session.sessionId ? null : session.sessionId),
7681
- onCloseMenu: () => setOpenMenuId(null),
7682
- actions
7683
- },
7684
- session.sessionId
7685
- )),
7686
- hasMore && onLoadMore && /* @__PURE__ */ jsx(
7687
- "button",
7688
- {
7689
- type: "button",
7690
- className: "payman-v2-sessions-load-more-btn",
7691
- onClick: onLoadMore,
7692
- disabled: isLoadingMore,
7693
- children: isLoadingMore ? /* @__PURE__ */ jsx("span", { className: "payman-v2-spinner payman-v2-spinner-sm" }) : "Load more"
7694
- }
7695
- )
7696
- ] })
7697
- }
7698
- )
7699
- }
7700
- );
7701
- }
7702
- function SessionsListSkeleton() {
7703
- return /* @__PURE__ */ jsx("div", { "aria-hidden": true, className: "payman-v2-sessions-skeleton", children: [0, 1, 2, 3, 4].map((i) => /* @__PURE__ */ jsxs("div", { className: "payman-v2-sessions-skeleton-row", children: [
7704
- /* @__PURE__ */ jsx(
7705
- "div",
7706
- {
7707
- className: "payman-v2-sessions-skeleton-line payman-v2-sessions-skeleton-line-title",
7708
- style: { animationDelay: `${i * 90}ms`, width: `${60 + i * 13 % 30}%` }
7709
- }
7710
- ),
7711
- /* @__PURE__ */ jsxs("div", { className: "payman-v2-sessions-skeleton-meta", children: [
7712
- /* @__PURE__ */ jsx(
7713
- "div",
7714
- {
7715
- className: "payman-v2-sessions-skeleton-line payman-v2-sessions-skeleton-pill",
7716
- style: { animationDelay: `${i * 90 + 60}ms` }
7717
- }
7718
- ),
7719
- /* @__PURE__ */ jsx(
7720
- "div",
7721
- {
7722
- className: "payman-v2-sessions-skeleton-line payman-v2-sessions-skeleton-pill",
7723
- style: { animationDelay: `${i * 90 + 120}ms` }
7724
- }
7725
- )
7726
- ] })
7727
- ] }, i)) });
7728
- }
7729
- function SessionRow({
7730
- session,
7731
- isSelected,
7732
- isMenuOpen,
7733
- onSelect,
7734
- onToggleMenu,
7735
- onCloseMenu,
7736
- actions
7737
- }) {
7738
- const menuRef = useRef(null);
7739
- const clipRef = useRef(null);
7740
- const textRef = useRef(null);
7741
- const [overflowPx, setOverflowPx] = useState(0);
7742
- const [scrolling, setScrolling] = useState(false);
7743
- useEffect(() => {
7744
- if (!isMenuOpen) return;
7745
- const handlePointerDown = (event) => {
7746
- if (menuRef.current && !menuRef.current.contains(event.target)) {
7747
- onCloseMenu();
7748
- }
7749
- };
7750
- document.addEventListener("mousedown", handlePointerDown);
7751
- return () => document.removeEventListener("mousedown", handlePointerDown);
7752
- }, [isMenuOpen, onCloseMenu]);
7753
- useEffect(() => {
7754
- const clip = clipRef.current;
7755
- const text = textRef.current;
7756
- if (!clip || !text) return;
7757
- const measure = () => setOverflowPx(Math.max(0, text.scrollWidth - clip.clientWidth));
7758
- measure();
7759
- const ro = new ResizeObserver(measure);
7760
- ro.observe(clip);
7761
- return () => ro.disconnect();
7762
- }, [session.title]);
7763
- const truncated = overflowPx > 2;
7764
- const messageCount = session.messageCount ?? 0;
7765
- const title = session.title?.trim() || "New chat";
7766
- const relativeTime = formatRelativeTime(session.lastMessageAt);
7767
- return /* @__PURE__ */ jsxs(
7768
- "div",
7769
- {
7770
- className: cn(
7771
- "payman-v2-session-row",
7772
- isSelected && "payman-v2-session-row-selected"
7773
- ),
7774
- children: [
7775
- /* @__PURE__ */ jsxs(
7776
- "button",
7777
- {
7778
- type: "button",
7779
- className: "payman-v2-session-row-main",
7780
- onClick: onSelect,
7781
- title,
7782
- onMouseEnter: () => truncated && setScrolling(true),
7783
- onMouseLeave: () => setScrolling(false),
7784
- children: [
7785
- /* @__PURE__ */ jsx(
7786
- "span",
7787
- {
7788
- ref: clipRef,
7789
- className: "payman-v2-session-row-title",
7790
- "data-truncated": truncated ? "true" : void 0,
7791
- "data-scrolling": scrolling ? "true" : void 0,
7792
- children: /* @__PURE__ */ jsx(
7793
- "span",
7794
- {
7795
- ref: textRef,
7796
- className: "payman-v2-session-row-title-text",
7797
- style: scrolling ? {
7798
- // +16 so the last chars clear the right-edge fade mask.
7799
- transform: `translateX(-${overflowPx + 16}px)`,
7800
- // Constant reading pace (~38px/s), so it moves at the same
7801
- // speed from start to end rather than easing in/out.
7802
- transitionDuration: `${Math.max(0.9, (overflowPx + 16) / 38)}s`
7803
- } : void 0,
7804
- children: title
7805
- }
7806
- )
7807
- }
7808
- ),
7809
- /* @__PURE__ */ jsxs("span", { className: "payman-v2-session-row-meta", children: [
7810
- /* @__PURE__ */ jsxs("span", { className: "payman-v2-session-row-meta-item", children: [
7811
- /* @__PURE__ */ jsx(IconMessage, { size: 12 }),
7812
- messageCount,
7813
- " ",
7814
- messageCount === 1 ? "message" : "messages"
7815
- ] }),
7816
- relativeTime && /* @__PURE__ */ jsxs("span", { className: "payman-v2-session-row-meta-item", children: [
7817
- /* @__PURE__ */ jsx(IconClock, { size: 12 }),
7818
- relativeTime
7819
- ] })
7820
- ] })
7821
- ]
7822
- }
7823
- ),
7824
- actions && actions.length > 0 && /* @__PURE__ */ jsxs("div", { className: "payman-v2-session-row-menu-wrap", ref: menuRef, children: [
7825
- /* @__PURE__ */ jsx(
7826
- "button",
7827
- {
7828
- type: "button",
7829
- className: cn(
7830
- "payman-v2-session-row-menu-btn",
7831
- isMenuOpen && "payman-v2-session-row-menu-btn-active"
7832
- ),
7833
- onClick: onToggleMenu,
7834
- "aria-label": "Chat options",
7835
- "aria-expanded": isMenuOpen,
7836
- children: /* @__PURE__ */ jsx(MoreHorizontal, { size: 14 })
7837
- }
7838
- ),
7839
- isMenuOpen && /* @__PURE__ */ jsx("div", { className: "payman-v2-session-row-menu", role: "menu", children: actions.map((action) => /* @__PURE__ */ jsx(
7840
- "button",
7841
- {
7842
- type: "button",
7843
- role: "menuitem",
7844
- className: cn(
7845
- "payman-v2-session-row-menu-item",
7846
- action.destructive && "payman-v2-session-row-menu-item-destructive"
7847
- ),
7848
- onClick: () => {
7849
- onCloseMenu();
7850
- void action.onSelect(session);
7851
- },
7852
- children: action.label
7853
- },
7854
- action.key
7855
- )) })
7856
- ] })
7857
- ]
7858
- }
7859
- );
7860
- }
7861
- var CLOSE_DELAY_MS = 150;
7862
- var HOVER_OPEN_DELAY_MS = 500;
7863
- function SessionsPeekPopoverV2({
7864
- title,
7865
- newChatLabel,
7866
- sessions,
7867
- isLoading,
7868
- error,
7869
- onRetry,
7870
- selectedSessionId,
7871
- onSelectSession,
7872
- onNewSession,
7873
- onExpand,
7874
- actions
7875
- }) {
7876
- const [open, setOpen] = useState(false);
7877
- const closeTimerRef = useRef(null);
7878
- const openTimerRef = useRef(null);
7879
- const cancelClose = useCallback(() => {
7880
- if (closeTimerRef.current) {
7881
- clearTimeout(closeTimerRef.current);
7882
- closeTimerRef.current = null;
7883
- }
7884
- }, []);
7885
- const cancelOpen = useCallback(() => {
7886
- if (openTimerRef.current) {
7887
- clearTimeout(openTimerRef.current);
7888
- openTimerRef.current = null;
7889
- }
7890
- }, []);
7891
- const scheduleClose = useCallback(() => {
7892
- cancelOpen();
7893
- cancelClose();
7894
- closeTimerRef.current = setTimeout(() => setOpen(false), CLOSE_DELAY_MS);
7895
- }, [cancelOpen, cancelClose]);
7896
- const handleEnter = useCallback(() => {
7897
- cancelClose();
7898
- cancelOpen();
7899
- openTimerRef.current = setTimeout(() => setOpen(true), HOVER_OPEN_DELAY_MS);
7900
- }, [cancelClose, cancelOpen]);
7901
- useEffect(
7902
- () => () => {
7903
- cancelOpen();
7904
- cancelClose();
7905
- },
7906
- [cancelOpen, cancelClose]
7907
- );
7908
- return /* @__PURE__ */ jsxs(
7909
- "div",
7910
- {
7911
- className: "payman-v2-sessions-peek-anchor",
7912
- onMouseEnter: handleEnter,
7913
- onMouseLeave: scheduleClose,
7914
- children: [
7915
- /* @__PURE__ */ jsx(
7916
- "button",
7917
- {
7918
- type: "button",
7919
- className: "payman-v2-sessions-reopen-btn",
7920
- onClick: onExpand,
7921
- "aria-label": "Show chats",
7922
- title: "Show chats",
7923
- children: /* @__PURE__ */ jsx(PanelLeft, { size: 16 })
7924
- }
7925
- ),
7926
- open && /* @__PURE__ */ jsxs("div", { className: "payman-v2-sessions-peek", role: "dialog", "aria-label": title, children: [
7927
- /* @__PURE__ */ jsx("div", { className: "payman-v2-sessions-peek-header", children: /* @__PURE__ */ jsx("span", { className: "payman-v2-sessions-peek-title", children: title }) }),
7928
- /* @__PURE__ */ jsxs(
7929
- "button",
7930
- {
7931
- type: "button",
7932
- className: "payman-v2-sessions-new-btn payman-v2-sessions-peek-new-btn",
7933
- onClick: () => {
7934
- onNewSession();
7935
- setOpen(false);
7936
- },
7937
- children: [
7938
- /* @__PURE__ */ jsx(IconNewChat, { size: 14 }),
7939
- newChatLabel
7940
- ]
7941
- }
7942
- ),
7943
- /* @__PURE__ */ jsx("div", { className: "payman-v2-sessions-divider" }),
7944
- /* @__PURE__ */ jsx(
7945
- SessionsListBody,
7946
- {
7947
- sessions,
7948
- isLoading,
7949
- error,
7950
- onRetry,
7951
- selectedSessionId,
7952
- onSelectSession: (sessionId) => {
7953
- onSelectSession(sessionId);
7954
- setOpen(false);
7955
- },
7956
- actions,
7957
- compact: true
7958
- }
7959
- )
7960
- ] })
7961
- ]
7962
- }
7963
- );
7964
- }
7965
- function SessionsBottomSheetV2({
7966
- title,
7967
- newChatLabel,
7968
- sessions,
7969
- isLoading,
7970
- error,
7971
- onRetry,
7972
- selectedSessionId,
7973
- onSelectSession,
7974
- onNewSession,
7975
- onClose,
7976
- actions,
7977
- hasMore,
7978
- isLoadingMore,
7979
- onLoadMore
7980
- }) {
7981
- return /* @__PURE__ */ jsxs(Fragment, { children: [
7982
- /* @__PURE__ */ jsx(
7983
- motion.div,
7984
- {
7985
- className: "payman-v2-sessions-sheet-backdrop",
7986
- initial: { opacity: 0 },
7987
- animate: { opacity: 1 },
7988
- exit: { opacity: 0 },
7989
- transition: { duration: 0.2 },
7990
- onClick: onClose
7991
- }
7992
- ),
7993
- /* @__PURE__ */ jsxs(
7994
- motion.div,
7995
- {
7996
- className: "payman-v2-sessions-sheet",
7997
- role: "dialog",
7998
- "aria-modal": "true",
7999
- "aria-label": title,
8000
- initial: { y: "100%" },
8001
- animate: { y: 0 },
8002
- exit: { y: "100%" },
8003
- transition: { type: "spring", damping: 32, stiffness: 320 },
8004
- children: [
8005
- /* @__PURE__ */ jsx("div", { className: "payman-v2-sessions-sheet-grabber", "aria-hidden": true }),
8006
- /* @__PURE__ */ jsxs("div", { className: "payman-v2-sessions-header", children: [
8007
- /* @__PURE__ */ jsx("span", { className: "payman-v2-sessions-title", children: title }),
8008
- /* @__PURE__ */ jsx(
8009
- "button",
8010
- {
8011
- type: "button",
8012
- className: "payman-v2-sessions-close",
8013
- onClick: onClose,
8014
- "aria-label": "Close chats panel",
8015
- children: /* @__PURE__ */ jsx(X, { size: 16 })
8016
- }
8017
- )
8018
- ] }),
8019
- /* @__PURE__ */ jsxs("button", { type: "button", className: "payman-v2-sessions-new-btn", onClick: onNewSession, children: [
8020
- /* @__PURE__ */ jsx(IconNewChat, { size: 16 }),
8021
- newChatLabel
8022
- ] }),
8023
- /* @__PURE__ */ jsx("div", { className: "payman-v2-sessions-divider" }),
8024
- /* @__PURE__ */ jsx(
8025
- SessionsListBody,
8026
- {
8027
- sessions,
8028
- isLoading,
8029
- error,
8030
- onRetry,
8031
- selectedSessionId,
8032
- onSelectSession,
8033
- actions,
8034
- hasMore,
8035
- isLoadingMore,
8036
- onLoadMore
8037
- }
8038
- )
8039
- ]
8040
- }
8041
- )
8042
- ] });
8043
- }
8044
7136
  var DEFAULT_USER_ACTION_STATE = {
8045
7137
  prompts: [],
8046
7138
  notifications: []
@@ -8135,8 +7227,7 @@ var PaymanChatInner = forwardRef(function PaymanChatInner2({
8135
7227
  onLoadMoreMessages,
8136
7228
  isLoadingMoreMessages = false,
8137
7229
  hasMoreMessages = false,
8138
- chat,
8139
- sessionsPanel
7230
+ chat
8140
7231
  }, ref) {
8141
7232
  const [inputValue, setInputValue] = useState("");
8142
7233
  const prevInputValueRef = useRef(inputValue);
@@ -8149,25 +7240,6 @@ var PaymanChatInner = forwardRef(function PaymanChatInner2({
8149
7240
  const chatInputV2Ref = useRef(null);
8150
7241
  const messageListV2Ref = useRef(null);
8151
7242
  const resetToEmptyStateRef = useRef(false);
8152
- const rootRef = useRef(null);
8153
- const [isCompact, setIsCompact] = useState(false);
8154
- useEffect(() => {
8155
- const el = rootRef.current;
8156
- if (!el) return;
8157
- const ro = new ResizeObserver((entries) => {
8158
- const width = entries[0]?.contentRect.width;
8159
- if (width != null) setIsCompact(width < COMPACT_BREAKPOINT_PX);
8160
- });
8161
- ro.observe(el);
8162
- return () => ro.disconnect();
8163
- }, []);
8164
- const wasCompactRef = useRef(isCompact);
8165
- useEffect(() => {
8166
- if (isCompact && !wasCompactRef.current && sessionsPanel?.open) {
8167
- sessionsPanel.onToggle();
8168
- }
8169
- wasCompactRef.current = isCompact;
8170
- }, [isCompact, sessionsPanel]);
8171
7243
  useEffect(() => {
8172
7244
  if (config.sentryDsn) {
8173
7245
  initSentryIfNeeded(config.sentryDsn);
@@ -8322,20 +7394,13 @@ var PaymanChatInner = forwardRef(function PaymanChatInner2({
8322
7394
  if (isRecording) {
8323
7395
  stopRecording();
8324
7396
  }
8325
- if (sessionsPanel?.onNewSession) {
8326
- sessionsPanel.onNewSession();
8327
- if (isCompact && sessionsPanel.open) sessionsPanel.onToggle();
8328
- } else {
8329
- resetSession();
8330
- }
7397
+ resetSession();
8331
7398
  onResetSession?.();
8332
7399
  }, [
8333
7400
  clearTranscript,
8334
7401
  isRecording,
8335
- isCompact,
8336
7402
  onResetSession,
8337
7403
  resetSession,
8338
- sessionsPanel,
8339
7404
  stopRecording
8340
7405
  ]);
8341
7406
  const requestResetSession = useCallback(() => {
@@ -8349,9 +7414,8 @@ var PaymanChatInner = forwardRef(function PaymanChatInner2({
8349
7414
  clearMessages,
8350
7415
  cancelStream,
8351
7416
  getSessionId,
8352
- getMessages,
8353
- refreshSessions: sessionsPanel?.refetch ?? NOOP
8354
- }), [performResetSession, clearMessages, cancelStream, getSessionId, getMessages, sessionsPanel?.refetch]);
7417
+ getMessages
7418
+ }), [performResetSession, clearMessages, cancelStream, getSessionId, getMessages]);
8355
7419
  const {
8356
7420
  placeholder = "Type your message...",
8357
7421
  emptyStateText = "What can I help with?",
@@ -8471,13 +7535,9 @@ var PaymanChatInner = forwardRef(function PaymanChatInner2({
8471
7535
  };
8472
7536
  const userActionPrompts = isUserActionSupported ? userActionState.prompts : void 0;
8473
7537
  const notifications = userActionState.notifications;
8474
- const dockableUserActionPrompts = userActionPrompts?.filter(
7538
+ const dockedPrompt = userActionPrompts?.find(
8475
7539
  (prompt) => prompt.kind !== "notification" && (prompt.status === "pending" || prompt.status === "submitting" || prompt.status === "stale")
8476
7540
  );
8477
- const dockedPendingPrompts = dockableUserActionPrompts?.filter(
8478
- (prompt) => prompt.status === "pending"
8479
- );
8480
- const dockedPrompt = dockedPendingPrompts?.[dockedPendingPrompts.length - 1] ?? dockableUserActionPrompts?.[dockableUserActionPrompts.length - 1];
8481
7541
  const handleV2Send = (text) => {
8482
7542
  if (isRecording) stopRecording();
8483
7543
  if (text.trim() && !disableInput && isSessionParamsConfigured) {
@@ -8526,236 +7586,171 @@ var PaymanChatInner = forwardRef(function PaymanChatInner2({
8526
7586
  return /* @__PURE__ */ jsx(PaymanChatContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxs(
8527
7587
  "div",
8528
7588
  {
8529
- ref: rootRef,
8530
7589
  className: cn("payman-v2-root", className),
8531
7590
  style,
8532
7591
  children: [
8533
7592
  children,
8534
- /* @__PURE__ */ jsxs("div", { className: "payman-v2-body", children: [
8535
- sessionsPanel && !isCompact && /* @__PURE__ */ jsx(
8536
- SessionsSidebarV2,
8537
- {
8538
- open: sessionsPanel.open,
8539
- onClose: sessionsPanel.onToggle,
8540
- title: sessionsPanel.title,
8541
- newChatLabel: sessionsPanel.newChatLabel,
8542
- sessions: sessionsPanel.sessionsList,
8543
- isLoading: sessionsPanel.isLoadingList,
8544
- error: sessionsPanel.listError,
8545
- onRetry: sessionsPanel.refetch,
8546
- selectedSessionId: sessionsPanel.activeSessionId,
8547
- onSelectSession: sessionsPanel.onSelectSession,
8548
- onNewSession: requestResetSession,
8549
- actions: sessionsPanel.actions,
8550
- hasMore: sessionsPanel.hasMore,
8551
- isLoadingMore: sessionsPanel.isLoadingMore,
8552
- onLoadMore: sessionsPanel.onLoadMore
8553
- }
8554
- ),
8555
- /* @__PURE__ */ jsx(AnimatePresence, { children: sessionsPanel && isCompact && sessionsPanel.open && /* @__PURE__ */ jsx(
8556
- SessionsBottomSheetV2,
8557
- {
8558
- title: sessionsPanel.title,
8559
- newChatLabel: sessionsPanel.newChatLabel,
8560
- sessions: sessionsPanel.sessionsList,
8561
- isLoading: sessionsPanel.isLoadingList,
8562
- error: sessionsPanel.listError,
8563
- onRetry: sessionsPanel.refetch,
8564
- selectedSessionId: sessionsPanel.activeSessionId,
8565
- onSelectSession: (sessionId) => {
8566
- sessionsPanel.onSelectSession(sessionId);
8567
- sessionsPanel.onToggle();
8568
- },
8569
- onNewSession: requestResetSession,
8570
- onClose: sessionsPanel.onToggle,
8571
- actions: sessionsPanel.actions,
8572
- hasMore: sessionsPanel.hasMore,
8573
- isLoadingMore: sessionsPanel.isLoadingMore,
8574
- onLoadMore: sessionsPanel.onLoadMore
8575
- },
8576
- "sessions-bottom-sheet"
8577
- ) }),
8578
- /* @__PURE__ */ jsxs("div", { className: "payman-v2-chat-column", children: [
8579
- sessionsPanel?.isLoadingMessages && /* @__PURE__ */ jsx("div", { className: "payman-v2-messages-loading-overlay", children: /* @__PURE__ */ jsx("span", { className: "payman-v2-spinner" }) }),
8580
- sessionsPanel && !sessionsPanel.open && /* @__PURE__ */ jsx(
8581
- SessionsPeekPopoverV2,
8582
- {
8583
- title: sessionsPanel.title,
8584
- newChatLabel: sessionsPanel.newChatLabel,
8585
- sessions: sessionsPanel.sessionsList,
8586
- isLoading: sessionsPanel.isLoadingList,
8587
- error: sessionsPanel.listError,
8588
- onRetry: sessionsPanel.refetch,
8589
- selectedSessionId: sessionsPanel.activeSessionId,
8590
- onSelectSession: sessionsPanel.onSelectSession,
8591
- onNewSession: requestResetSession,
8592
- onExpand: sessionsPanel.onToggle,
8593
- actions: sessionsPanel.actions
8594
- }
8595
- ),
8596
- /* @__PURE__ */ jsx(AnimatePresence, { mode: "wait", children: isEmpty && !hasEverSentMessage ? /* @__PURE__ */ jsx(
8597
- motion.div,
8598
- {
8599
- initial: { opacity: 1 },
8600
- exit: { opacity: 0 },
8601
- transition: { duration: 0.3 },
8602
- className: "payman-v2-chat-layout",
8603
- style: { justifyContent: "center", alignItems: "center" },
8604
- children: /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", flex: 1, width: "100%" }, children: [
8605
- /* @__PURE__ */ jsx(
8606
- MessageList,
8607
- {
8608
- messages,
8609
- isLoading: false,
8610
- emptyStateText,
8611
- showEmptyStateIcon,
8612
- emptyStateComponent,
8613
- layout,
8614
- showTimestamps,
8615
- stage: config.stage || "DEVELOPMENT",
8616
- animated,
8617
- showAgentName,
8618
- agentName,
8619
- showAvatars,
8620
- showUserAvatar,
8621
- showAssistantAvatar,
8622
- showExecutionSteps,
8623
- showStreamingDot,
8624
- streamingStepsText,
8625
- completedStepsText,
8626
- onExecutionTraceClick,
8627
- onLoadMoreMessages,
8628
- isLoadingMoreMessages,
8629
- hasMoreMessages
8630
- }
8631
- ),
8632
- /* @__PURE__ */ jsx(
8633
- motion.div,
8634
- {
8635
- initial: { opacity: 0 },
8636
- animate: { opacity: 1 },
8637
- transition: { duration: 0.18 },
8638
- style: { width: "100%" },
8639
- children: hasAskPermission && /* @__PURE__ */ jsx(
8640
- ChatInputV2,
8641
- {
8642
- ref: chatInputV2Ref,
8643
- onSend: handleV2Send,
8644
- onCancel: cancelStream,
8645
- disabled: isV2InputDisabled,
8646
- isStreaming: isWaitingForResponse,
8647
- placeholder: isRecording ? "Listening..." : placeholder,
8648
- enableVoice: config.enableVoice === true,
8649
- transcribedText: config.enableVoice === true ? transcribedText : "",
8650
- voiceAvailable: config.enableVoice === true && voiceAvailable,
8651
- isRecording,
8652
- onVoicePress: config.enableVoice === true ? handleVoicePress : void 0,
8653
- onCancelRecording: handleCancelRecording,
8654
- onConfirmRecording: handleConfirmRecording,
8655
- showResetSession,
8656
- onResetSession: requestResetSession,
8657
- showAttachmentButton,
8658
- showUploadImageButton,
8659
- showAttachFileButton,
8660
- onUploadImageClick,
8661
- onAttachFileClick,
8662
- editingMessageId,
8663
- onClearEditing: handleClearEditing,
8664
- analysisMode: enableDeepModeToggle ? analysisMode : void 0,
8665
- onAnalysisModeChange: enableDeepModeToggle ? setAnalysisMode : void 0,
8666
- slashCommands
8667
- }
8668
- )
8669
- }
8670
- )
8671
- ] })
8672
- },
8673
- "v2-empty"
8674
- ) : /* @__PURE__ */ jsxs(
8675
- motion.div,
8676
- {
8677
- initial: { opacity: 0 },
8678
- animate: { opacity: 1 },
8679
- transition: { duration: 0.25 },
8680
- className: "payman-v2-chat-layout",
8681
- children: [
8682
- /* @__PURE__ */ jsx(
8683
- MessageListV2,
7593
+ /* @__PURE__ */ jsx(AnimatePresence, { mode: "wait", children: isEmpty && !hasEverSentMessage ? /* @__PURE__ */ jsx(
7594
+ motion.div,
7595
+ {
7596
+ initial: { opacity: 1 },
7597
+ exit: { opacity: 0 },
7598
+ transition: { duration: 0.3 },
7599
+ className: "payman-v2-chat-layout",
7600
+ style: { justifyContent: "center", alignItems: "center" },
7601
+ children: /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", flex: 1, width: "100%" }, children: [
7602
+ /* @__PURE__ */ jsx(
7603
+ MessageList,
7604
+ {
7605
+ messages,
7606
+ isLoading: false,
7607
+ emptyStateText,
7608
+ showEmptyStateIcon,
7609
+ emptyStateComponent,
7610
+ layout,
7611
+ showTimestamps,
7612
+ stage: config.stage || "DEVELOPMENT",
7613
+ animated,
7614
+ showAgentName,
7615
+ agentName,
7616
+ showAvatars,
7617
+ showUserAvatar,
7618
+ showAssistantAvatar,
7619
+ showExecutionSteps,
7620
+ showStreamingDot,
7621
+ streamingStepsText,
7622
+ completedStepsText,
7623
+ onExecutionTraceClick,
7624
+ onLoadMoreMessages,
7625
+ isLoadingMoreMessages,
7626
+ hasMoreMessages
7627
+ }
7628
+ ),
7629
+ /* @__PURE__ */ jsx(
7630
+ motion.div,
7631
+ {
7632
+ initial: { opacity: 0, y: 12 },
7633
+ animate: { opacity: 1, y: 0 },
7634
+ transition: { delay: 0.2, duration: 0.4, ease: [0.25, 0.46, 0.45, 0.94] },
7635
+ style: { width: "100%" },
7636
+ children: hasAskPermission && /* @__PURE__ */ jsx(
7637
+ ChatInputV2,
8684
7638
  {
8685
- ref: messageListV2Ref,
8686
- messages,
7639
+ ref: chatInputV2Ref,
7640
+ onSend: handleV2Send,
7641
+ onCancel: cancelStream,
7642
+ disabled: isV2InputDisabled,
8687
7643
  isStreaming: isWaitingForResponse,
8688
- onEditUserMessage: handleEditMessageDraft,
8689
- onRetryUserMessage: handleRetryUserMessage,
8690
- onImageClick: handleImageClick,
8691
- onExecutionTraceClick,
8692
- messageActions,
8693
- retryDisabled: isWaitingForResponse,
8694
- typingSpeed: config.typingSpeed ?? 4,
8695
- userActionPrompts,
8696
- dockedUserActionId: dockedPrompt?.userActionId,
8697
- notifications,
8698
- onSubmitUserAction: isUserActionSupported ? submitUserAction2 : void 0,
8699
- onCancelUserAction: isUserActionSupported ? cancelUserAction2 : void 0,
8700
- onResendUserAction: isUserActionSupported ? resendUserAction2 : void 0,
8701
- onExpireUserAction: isUserActionSupported ? async (id) => expireUserActionOnce(id) : void 0,
8702
- onDismissNotification: dismissNotification,
8703
- onSubmitFeedback: handleSubmitFeedback
7644
+ placeholder: isRecording ? "Listening..." : placeholder,
7645
+ enableVoice: config.enableVoice === true,
7646
+ transcribedText: config.enableVoice === true ? transcribedText : "",
7647
+ voiceAvailable: config.enableVoice === true && voiceAvailable,
7648
+ isRecording,
7649
+ onVoicePress: config.enableVoice === true ? handleVoicePress : void 0,
7650
+ onCancelRecording: handleCancelRecording,
7651
+ onConfirmRecording: handleConfirmRecording,
7652
+ showResetSession,
7653
+ onResetSession: requestResetSession,
7654
+ showAttachmentButton,
7655
+ showUploadImageButton,
7656
+ showAttachFileButton,
7657
+ onUploadImageClick,
7658
+ onAttachFileClick,
7659
+ editingMessageId,
7660
+ onClearEditing: handleClearEditing,
7661
+ analysisMode: enableDeepModeToggle ? analysisMode : void 0,
7662
+ onAnalysisModeChange: enableDeepModeToggle ? setAnalysisMode : void 0,
7663
+ slashCommands
8704
7664
  }
8705
- ),
8706
- /* @__PURE__ */ jsx(
8707
- StreamingIndicatorV2,
7665
+ )
7666
+ }
7667
+ )
7668
+ ] })
7669
+ },
7670
+ "v2-empty"
7671
+ ) : /* @__PURE__ */ jsxs(
7672
+ motion.div,
7673
+ {
7674
+ initial: hasEverSentMessage ? { opacity: 0 } : false,
7675
+ animate: { opacity: 1 },
7676
+ transition: { duration: 0.3 },
7677
+ className: "payman-v2-chat-layout",
7678
+ children: [
7679
+ /* @__PURE__ */ jsx(
7680
+ MessageListV2,
7681
+ {
7682
+ ref: messageListV2Ref,
7683
+ messages,
7684
+ isStreaming: isWaitingForResponse,
7685
+ onEditUserMessage: handleEditMessageDraft,
7686
+ onRetryUserMessage: handleRetryUserMessage,
7687
+ onImageClick: handleImageClick,
7688
+ onExecutionTraceClick,
7689
+ messageActions,
7690
+ retryDisabled: isWaitingForResponse,
7691
+ typingSpeed: config.typingSpeed ?? 4,
7692
+ userActionPrompts,
7693
+ dockedUserActionId: dockedPrompt?.userActionId,
7694
+ notifications,
7695
+ onSubmitUserAction: isUserActionSupported ? submitUserAction2 : void 0,
7696
+ onCancelUserAction: isUserActionSupported ? cancelUserAction2 : void 0,
7697
+ onResendUserAction: isUserActionSupported ? resendUserAction2 : void 0,
7698
+ onExpireUserAction: isUserActionSupported ? async (id) => expireUserActionOnce(id) : void 0,
7699
+ onDismissNotification: dismissNotification,
7700
+ onSubmitFeedback: handleSubmitFeedback
7701
+ }
7702
+ ),
7703
+ /* @__PURE__ */ jsx(
7704
+ StreamingIndicatorV2,
7705
+ {
7706
+ isStreaming: isWaitingForResponse,
7707
+ loadingAnimation: config.loadingAnimation
7708
+ }
7709
+ ),
7710
+ hasAskPermission && /* @__PURE__ */ jsx(
7711
+ UserActionDock,
7712
+ {
7713
+ prompt: isUserActionSupported ? dockedPrompt : void 0,
7714
+ onSubmit: submitUserAction2,
7715
+ onCancel: cancelUserAction2,
7716
+ onResend: resendUserAction2,
7717
+ onExpired: expireUserActionOnce,
7718
+ children: /* @__PURE__ */ jsx(
7719
+ ChatInputV2,
8708
7720
  {
7721
+ ref: chatInputV2Ref,
7722
+ onSend: handleV2Send,
7723
+ onCancel: cancelStream,
7724
+ disabled: isV2InputDisabled,
8709
7725
  isStreaming: isWaitingForResponse,
8710
- loadingAnimation: config.loadingAnimation
8711
- }
8712
- ),
8713
- hasAskPermission && /* @__PURE__ */ jsx(
8714
- UserActionDock,
8715
- {
8716
- prompt: isUserActionSupported ? dockedPrompt : void 0,
8717
- onSubmit: submitUserAction2,
8718
- onCancel: cancelUserAction2,
8719
- onResend: resendUserAction2,
8720
- onExpired: expireUserActionOnce,
8721
- children: /* @__PURE__ */ jsx(
8722
- ChatInputV2,
8723
- {
8724
- ref: chatInputV2Ref,
8725
- onSend: handleV2Send,
8726
- onCancel: cancelStream,
8727
- disabled: isV2InputDisabled,
8728
- isStreaming: isWaitingForResponse,
8729
- placeholder: isRecording ? "Listening..." : placeholder,
8730
- enableVoice: config.enableVoice === true,
8731
- transcribedText: config.enableVoice === true ? transcribedText : "",
8732
- voiceAvailable: config.enableVoice === true && voiceAvailable,
8733
- isRecording,
8734
- onVoicePress: config.enableVoice === true ? handleVoicePress : void 0,
8735
- onCancelRecording: handleCancelRecording,
8736
- onConfirmRecording: handleConfirmRecording,
8737
- showResetSession,
8738
- onResetSession: requestResetSession,
8739
- showAttachmentButton,
8740
- showUploadImageButton,
8741
- showAttachFileButton,
8742
- onUploadImageClick,
8743
- onAttachFileClick,
8744
- editingMessageId,
8745
- onClearEditing: handleClearEditing,
8746
- analysisMode: enableDeepModeToggle ? analysisMode : void 0,
8747
- onAnalysisModeChange: enableDeepModeToggle ? setAnalysisMode : void 0,
8748
- slashCommands
8749
- }
8750
- )
7726
+ placeholder: isRecording ? "Listening..." : placeholder,
7727
+ enableVoice: config.enableVoice === true,
7728
+ transcribedText: config.enableVoice === true ? transcribedText : "",
7729
+ voiceAvailable: config.enableVoice === true && voiceAvailable,
7730
+ isRecording,
7731
+ onVoicePress: config.enableVoice === true ? handleVoicePress : void 0,
7732
+ onCancelRecording: handleCancelRecording,
7733
+ onConfirmRecording: handleConfirmRecording,
7734
+ showResetSession,
7735
+ onResetSession: requestResetSession,
7736
+ showAttachmentButton,
7737
+ showUploadImageButton,
7738
+ showAttachFileButton,
7739
+ onUploadImageClick,
7740
+ onAttachFileClick,
7741
+ editingMessageId,
7742
+ onClearEditing: handleClearEditing,
7743
+ analysisMode: enableDeepModeToggle ? analysisMode : void 0,
7744
+ onAnalysisModeChange: enableDeepModeToggle ? setAnalysisMode : void 0,
7745
+ slashCommands
8751
7746
  }
8752
7747
  )
8753
- ]
8754
- },
8755
- "v2-chat"
8756
- ) })
8757
- ] })
8758
- ] }),
7748
+ }
7749
+ )
7750
+ ]
7751
+ },
7752
+ "v2-chat"
7753
+ ) }),
8759
7754
  /* @__PURE__ */ jsx(
8760
7755
  ImageLightboxV2,
8761
7756
  {
@@ -8786,163 +7781,14 @@ var PaymanChatInner = forwardRef(function PaymanChatInner2({
8786
7781
  }
8787
7782
  ) });
8788
7783
  });
8789
- var PaymanChatWithChat = forwardRef(
8790
- function PaymanChatWithChat2(props, ref) {
7784
+ var PaymanChat = forwardRef(
7785
+ function PaymanChat2(props, ref) {
8791
7786
  const mergedCallbacks = useSentryChatCallbacks(props.callbacks, props.config);
8792
7787
  const chat = useChatV2(props.config, mergedCallbacks);
8793
7788
  return /* @__PURE__ */ jsx(PaymanChatInner, { ...props, chat, ref });
8794
7789
  }
8795
7790
  );
8796
- function AvailabilityNotice({ message }) {
8797
- return /* @__PURE__ */ jsx("div", { className: "flex-1 flex items-center justify-center p-4", children: /* @__PURE__ */ jsx("div", { className: "text-center", children: /* @__PURE__ */ jsx("div", { className: "text-muted-foreground text-sm", children: message }) }) });
8798
- }
8799
- var DEFAULT_AGENT_DISABLED_MESSAGE = "Chat is currently unavailable. Please try again later.";
8800
- var DEFAULT_USER_BLOCKED_MESSAGE = "Chat isn't available for your account right now.";
8801
- var COMPACT_BREAKPOINT_PX = 640;
8802
- var PaymanChat = forwardRef(
8803
- function PaymanChat2(props, ref) {
8804
- const { config } = props;
8805
- const sessionsConfig = config.sessions;
8806
- const availabilityData = useAgentConfig({
8807
- api: config.api,
8808
- availability: config.availability
8809
- });
8810
- const agentUnavailable = availabilityData.enabled && availabilityData.available === false;
8811
- const availabilityStatus = availabilityData.status;
8812
- const availabilityGateOpen = !availabilityData.enabled || availabilityData.available === true || availabilityData.available === null && !availabilityData.isLoading;
8813
- const gatedSessionsConfig = useMemo(
8814
- () => sessionsConfig ? {
8815
- ...sessionsConfig,
8816
- enabled: sessionsConfig.enabled === true && availabilityGateOpen
8817
- } : sessionsConfig,
8818
- [sessionsConfig, availabilityGateOpen]
8819
- );
8820
- const sessionsData = useChatSessions({
8821
- api: config.api,
8822
- sessions: gatedSessionsConfig,
8823
- initialSessionId: config.initialSessionId
8824
- });
8825
- const [sidebarOpen, setSidebarOpen] = useState(
8826
- sessionsConfig?.defaultOpen !== false
8827
- );
8828
- const toggleSidebar = useCallback(() => setSidebarOpen((open) => !open), []);
8829
- const effectiveConfig = useMemo(() => {
8830
- if (!sessionsData.enabled) return config;
8831
- return {
8832
- ...config,
8833
- initialSessionId: sessionsData.activeSessionId,
8834
- initialMessages: sessionsData.selectedMessages,
8835
- autoGenerateSessionId: false,
8836
- // Scope the message store per active session. The base userId alone
8837
- // is shared across every session, so its chatStore entry would leak
8838
- // the previous chat's messages into a newly-selected or brand-new
8839
- // session (getStoredOrInitialMessages prefers the store over
8840
- // initialMessages). Per-session keys give each chat a clean slate.
8841
- userId: config.userId ? `${config.userId}::${sessionsData.activeSessionId}` : void 0
8842
- };
8843
- }, [
8844
- config,
8845
- sessionsData.enabled,
8846
- sessionsData.activeSessionId,
8847
- sessionsData.selectedMessages
8848
- ]);
8849
- const sessionsPanel = useMemo(() => {
8850
- if (!sessionsData.enabled) return void 0;
8851
- return {
8852
- open: sidebarOpen,
8853
- onToggle: toggleSidebar,
8854
- title: sessionsConfig?.title ?? "Chats",
8855
- newChatLabel: sessionsConfig?.newChatLabel ?? "Start New Chat",
8856
- sessionsList: sessionsData.sessionsList,
8857
- isLoadingList: sessionsData.isLoadingList,
8858
- listError: sessionsData.listError,
8859
- activeSessionId: sessionsData.activeSessionId,
8860
- onSelectSession: sessionsData.selectSession,
8861
- onNewSession: sessionsData.startNewSession,
8862
- actions: sessionsConfig?.actions,
8863
- refetch: sessionsData.refetch,
8864
- hasMore: sessionsData.hasMore,
8865
- isLoadingMore: sessionsData.isLoadingMore,
8866
- onLoadMore: sessionsData.loadMore,
8867
- isLoadingMessages: sessionsData.isLoadingMessages
8868
- };
8869
- }, [
8870
- sessionsData.enabled,
8871
- sessionsData.sessionsList,
8872
- sessionsData.isLoadingList,
8873
- sessionsData.listError,
8874
- sessionsData.activeSessionId,
8875
- sessionsData.selectSession,
8876
- sessionsData.startNewSession,
8877
- sessionsData.refetch,
8878
- sessionsData.hasMore,
8879
- sessionsData.isLoadingMore,
8880
- sessionsData.loadMore,
8881
- sessionsData.isLoadingMessages,
8882
- sidebarOpen,
8883
- toggleSidebar,
8884
- sessionsConfig?.title,
8885
- sessionsConfig?.newChatLabel,
8886
- sessionsConfig?.actions
8887
- ]);
8888
- const callbacksWithSessionsRefresh = useMemo(() => {
8889
- if (!sessionsData.enabled) return props.callbacks;
8890
- return {
8891
- ...props.callbacks,
8892
- // Reflect the message in the sidebar the instant it's sent, before
8893
- // the server round-trip — the refetch below reconciles on complete.
8894
- onMessageSent: (message) => {
8895
- props.callbacks?.onMessageSent?.(message);
8896
- sessionsData.noteSentMessage(message);
8897
- },
8898
- onStreamComplete: (message) => {
8899
- props.callbacks?.onStreamComplete?.(message);
8900
- sessionsData.refetch();
8901
- }
8902
- };
8903
- }, [sessionsData.enabled, props.callbacks, sessionsData.refetch, sessionsData.noteSentMessage]);
8904
- const availabilityPending = availabilityData.enabled && availabilityData.isLoading && availabilityData.available === null;
8905
- if (availabilityPending) {
8906
- return /* @__PURE__ */ jsxs(
8907
- "div",
8908
- {
8909
- className: cn("bg-background overflow-hidden flex flex-col flex-[4]", props.className),
8910
- style: props.style,
8911
- children: [
8912
- props.children,
8913
- /* @__PURE__ */ jsx("div", { className: "payman-v2-chat-loading", children: /* @__PURE__ */ jsx("span", { className: "payman-v2-spinner" }) })
8914
- ]
8915
- }
8916
- );
8917
- }
8918
- if (agentUnavailable) {
8919
- const disabledBody = availabilityStatus === "blocked" ? config.availability?.blockedComponent ?? /* @__PURE__ */ jsx(AvailabilityNotice, { message: DEFAULT_USER_BLOCKED_MESSAGE }) : config.availability?.disabledComponent ?? /* @__PURE__ */ jsx(AvailabilityNotice, { message: DEFAULT_AGENT_DISABLED_MESSAGE });
8920
- return /* @__PURE__ */ jsxs(
8921
- "div",
8922
- {
8923
- className: cn("bg-background overflow-hidden flex flex-col flex-[4]", props.className),
8924
- style: props.style,
8925
- children: [
8926
- props.children,
8927
- disabledBody
8928
- ]
8929
- }
8930
- );
8931
- }
8932
- return /* @__PURE__ */ jsx(
8933
- PaymanChatWithChat,
8934
- {
8935
- ...props,
8936
- config: effectiveConfig,
8937
- callbacks: callbacksWithSessionsRefresh,
8938
- sessionsPanel,
8939
- ref
8940
- },
8941
- sessionsData.enabled ? sessionsData.activeSessionId : void 0
8942
- );
8943
- }
8944
- );
8945
7791
 
8946
- export { PaymanChat, PaymanChatContext, UserActionStaleError, cancelUserAction, captureSentryError, cn, formatDate, resendUserAction, submitUserAction, useAgentConfig, useChatV2, usePaymanChat, useVoice };
7792
+ export { PaymanChat, PaymanChatContext, UserActionStaleError, cancelUserAction, captureSentryError, cn, formatDate, resendUserAction, submitUserAction, useChatV2, usePaymanChat, useVoice };
8947
7793
  //# sourceMappingURL=index.mjs.map
8948
7794
  //# sourceMappingURL=index.mjs.map