@webless/agent 0.5.0 → 0.6.0

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.
@@ -985,7 +985,7 @@ function visitorBookingPrefix(booking) {
985
985
  }
986
986
 
987
987
  // src/react/persisted-conversation.ts
988
- var CONVERSATION_VERSION = 1;
988
+ var CONVERSATION_VERSION = 2;
989
989
  function conversationKey(storageKeyPrefix, visitorSessionId) {
990
990
  return `${storageKeyPrefix}:conversation:${visitorSessionId}`;
991
991
  }
@@ -1011,6 +1011,20 @@ function parseMessage(value) {
1011
1011
  createdAt: record.createdAt
1012
1012
  };
1013
1013
  }
1014
+ function parseToolStep(value) {
1015
+ if (typeof value !== "object" || value === null) return null;
1016
+ const record = value;
1017
+ if (typeof record.id !== "string" || record.kind !== "planning" && record.kind !== "search" && record.kind !== "specialist" || typeof record.label !== "string" || record.state !== "completed" && record.state !== "active" && record.state !== "pending" && record.state !== "error") {
1018
+ return null;
1019
+ }
1020
+ return {
1021
+ id: record.id,
1022
+ kind: record.kind,
1023
+ label: record.label,
1024
+ state: record.state,
1025
+ ...typeof record.detail === "string" && record.detail ? { detail: record.detail } : {}
1026
+ };
1027
+ }
1014
1028
  function visitorTurnText(message) {
1015
1029
  return message.role === "visitor" && message.runtimeText ? message.runtimeText : message.text;
1016
1030
  }
@@ -1022,15 +1036,19 @@ function loadPersistedAgentConversation(storageKeyPrefix, visitorSessionId) {
1022
1036
  const value = JSON.parse(raw);
1023
1037
  if (typeof value !== "object" || value === null) return null;
1024
1038
  const record = value;
1025
- if (record.version !== CONVERSATION_VERSION || !Array.isArray(record.messages) || typeof record.pending !== "boolean" || typeof record.streamingText !== "string") {
1039
+ if (record.version !== 1 && record.version !== CONVERSATION_VERSION || !Array.isArray(record.messages) || typeof record.pending !== "boolean" || typeof record.streamingText !== "string" || record.version === CONVERSATION_VERSION && !Array.isArray(record.toolSteps)) {
1026
1040
  return null;
1027
1041
  }
1028
1042
  const messages = record.messages.map(parseMessage);
1029
1043
  if (messages.some((message) => message === null)) return null;
1044
+ const storedToolSteps = record.version === CONVERSATION_VERSION && Array.isArray(record.toolSteps) ? record.toolSteps : [];
1045
+ const toolSteps = storedToolSteps.map(parseToolStep);
1046
+ if (toolSteps.some((step) => step === null)) return null;
1030
1047
  return {
1031
1048
  messages: messages.filter((message) => message !== null),
1032
1049
  pending: record.pending,
1033
- streamingText: record.streamingText
1050
+ streamingText: record.streamingText,
1051
+ toolSteps: toolSteps.filter((step) => step !== null)
1034
1052
  };
1035
1053
  } catch {
1036
1054
  return null;
@@ -1111,7 +1129,8 @@ function stateFromConversation(conversation, initialState) {
1111
1129
  ...initialState,
1112
1130
  messages: conversation.messages,
1113
1131
  phase: conversation.pending ? conversation.streamingText ? "streaming" : "thinking" : "complete",
1114
- streamingText: conversation.streamingText
1132
+ streamingText: conversation.streamingText,
1133
+ toolSteps: conversation.toolSteps
1115
1134
  };
1116
1135
  }
1117
1136
  function upsertToolStep(steps, item) {
@@ -1245,13 +1264,15 @@ function useAgentChat({
1245
1264
  savePersistedAgentConversation(resolvedStorageKeyPrefix, visitorId, {
1246
1265
  messages: state.messages,
1247
1266
  pending: isAgentBusy(state.phase),
1248
- streamingText: state.streamingText
1267
+ streamingText: state.streamingText,
1268
+ toolSteps: state.toolSteps
1249
1269
  });
1250
1270
  }, [
1251
1271
  resolvedStorageKeyPrefix,
1252
1272
  state.messages,
1253
1273
  state.phase,
1254
1274
  state.streamingText,
1275
+ state.toolSteps,
1255
1276
  visitorId
1256
1277
  ]);
1257
1278
  const reset = useCallback(() => {
@@ -1565,18 +1586,65 @@ var defaultAgentRailTheme = {
1565
1586
  fontBody: '"Mulish", "Avenir Next", "Segoe UI", sans-serif',
1566
1587
  fontDisplay: '"Space Grotesk", sans-serif'
1567
1588
  };
1589
+ var defaultDarkAgentRailTheme = {
1590
+ ...defaultAgentRailTheme,
1591
+ brand: "#a77bff",
1592
+ brandSoft: "#2b2140",
1593
+ brandDeep: "#f5f0ff",
1594
+ surface: "#101218",
1595
+ surfaceMuted: "#1a1e27",
1596
+ text: "#f5f7fb",
1597
+ textMuted: "#b6bfce",
1598
+ textSubtle: "#919cad",
1599
+ border: "rgb(226 232 240 / 0.16)",
1600
+ visitorBubble: "#7c3aed",
1601
+ success: "#55cf91",
1602
+ danger: "#ff8da1"
1603
+ };
1568
1604
 
1569
1605
  // src/react/components/AgentRail/AgentRail.tsx
1570
- import { useEffect as useEffect2, useRef as useRef3 } from "react";
1606
+ import { useEffect as useEffect2, useRef as useRef3, useState as useState6 } from "react";
1607
+
1608
+ // src/react/hooks/useAgentColorScheme.ts
1609
+ import { useSyncExternalStore } from "react";
1610
+ var DARK_MODE_QUERY = "(prefers-color-scheme: dark)";
1611
+ function subscribeToDarkMode(onChange) {
1612
+ if (typeof window === "undefined" || !window.matchMedia) {
1613
+ return () => void 0;
1614
+ }
1615
+ const mediaQuery = window.matchMedia(DARK_MODE_QUERY);
1616
+ if (typeof mediaQuery.addEventListener === "function") {
1617
+ mediaQuery.addEventListener("change", onChange);
1618
+ return () => mediaQuery.removeEventListener("change", onChange);
1619
+ }
1620
+ mediaQuery.addListener(onChange);
1621
+ return () => mediaQuery.removeListener(onChange);
1622
+ }
1623
+ function getPrefersDarkMode() {
1624
+ return typeof window !== "undefined" && Boolean(window.matchMedia?.(DARK_MODE_QUERY).matches);
1625
+ }
1626
+ function useAgentColorScheme(colorScheme = "auto") {
1627
+ const prefersDarkMode = useSyncExternalStore(
1628
+ subscribeToDarkMode,
1629
+ getPrefersDarkMode,
1630
+ () => false
1631
+ );
1632
+ return resolveAgentColorScheme(colorScheme, prefersDarkMode);
1633
+ }
1634
+ function resolveAgentColorScheme(colorScheme = "auto", prefersDarkMode) {
1635
+ return colorScheme === "auto" ? prefersDarkMode ? "dark" : "light" : colorScheme;
1636
+ }
1571
1637
 
1572
1638
  // src/react/components/AgentActivityBubble/AgentActivityBubble.tsx
1639
+ import { useState as useState2 } from "react";
1573
1640
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
1574
1641
  function workSummary(steps, failed, brandLabel) {
1575
1642
  const active = [...steps].reverse().find((step) => step.state === "active");
1576
1643
  if (active?.kind === "specialist")
1577
1644
  return `${active.label} is reviewing your question`;
1578
1645
  if (active?.kind === "search") return "Searching this site";
1579
- if (active) return `${brandLabel} is choosing the best way to help`;
1646
+ if (active)
1647
+ return brandLabel ? `${brandLabel} is choosing the best way to help` : "Choosing the best way to help";
1580
1648
  if (failed) return "Couldn\u2019t complete this request";
1581
1649
  const hasError = steps.some((step) => step.state === "error");
1582
1650
  const specialists = steps.filter(
@@ -1587,22 +1655,24 @@ function workSummary(steps, failed, brandLabel) {
1587
1655
  );
1588
1656
  if (hasError) return "Answered with available information";
1589
1657
  if (specialists.length > 1)
1590
- return `Consulted ${specialists.length} specialists`;
1591
- if (specialists.length === 1) return `Consulted ${specialists[0]?.label}`;
1658
+ return `Brought in ${specialists.length} specialists`;
1659
+ if (specialists.length === 1)
1660
+ return `Brought in ${specialists[0]?.label}`;
1592
1661
  if (searched) return "Searched this site";
1593
1662
  return "Answer ready";
1594
1663
  }
1595
1664
  function stepLabel(step, brandLabel) {
1596
- return step.kind === "planning" ? brandLabel : step.label;
1665
+ return step.kind === "planning" ? brandLabel || "Supervisor" : step.label;
1597
1666
  }
1598
1667
  function stepDetail(step, steps) {
1599
1668
  if (step.kind !== "planning" || step.state !== "completed") {
1600
1669
  return step.detail;
1601
1670
  }
1602
1671
  const specialists = steps.filter((item) => item.kind === "specialist");
1603
- if (specialists.length === 1) return `Delegated to ${specialists[0]?.label}`;
1672
+ if (specialists.length === 1)
1673
+ return `Routed your question to ${specialists[0]?.label}`;
1604
1674
  if (specialists.length > 1)
1605
- return `Delegated to ${specialists.length} specialists`;
1675
+ return `Routed your question to ${specialists.length} specialists`;
1606
1676
  if (steps.some((item) => item.kind === "search"))
1607
1677
  return "Used built-in Search & Discovery";
1608
1678
  return step.detail;
@@ -1633,12 +1703,17 @@ function PlanningIcon() {
1633
1703
  ) });
1634
1704
  }
1635
1705
  function AgentActivityBubble({
1636
- brandLabel = "Webless Guide",
1706
+ brandLabel = "",
1637
1707
  brandLogoUrl,
1638
1708
  failed = false,
1639
1709
  steps
1640
1710
  }) {
1641
1711
  const active = steps.some((step) => step.state === "active");
1712
+ const receiptId = steps.map((step) => step.id).join(":");
1713
+ const [expandedReceiptId, setExpandedReceiptId] = useState2(
1714
+ null
1715
+ );
1716
+ const detailsOpen = active || expandedReceiptId === receiptId;
1642
1717
  return /* @__PURE__ */ jsxs("article", { className: "agent-activity-bubble", children: [
1643
1718
  /* @__PURE__ */ jsxs("p", { className: "agent-activity-bubble__status", "aria-live": "polite", children: [
1644
1719
  /* @__PURE__ */ jsx(
@@ -1650,9 +1725,23 @@ function AgentActivityBubble({
1650
1725
  ),
1651
1726
  workSummary(steps, failed, brandLabel)
1652
1727
  ] }),
1653
- /* @__PURE__ */ jsxs("details", { className: "agent-activity-bubble__details", open: active, children: [
1654
- /* @__PURE__ */ jsx("summary", { children: "Work details" }),
1655
- /* @__PURE__ */ jsx("ol", { className: "agent-activity-bubble__steps", children: steps.map((step) => {
1728
+ /* @__PURE__ */ jsxs("div", { className: "agent-activity-bubble__details", children: [
1729
+ /* @__PURE__ */ jsx(
1730
+ "button",
1731
+ {
1732
+ type: "button",
1733
+ className: "agent-activity-bubble__summary",
1734
+ "aria-expanded": detailsOpen,
1735
+ onClick: () => {
1736
+ if (active) return;
1737
+ setExpandedReceiptId(
1738
+ (current) => current === receiptId ? null : receiptId
1739
+ );
1740
+ },
1741
+ children: "How this answer was made"
1742
+ }
1743
+ ),
1744
+ detailsOpen ? /* @__PURE__ */ jsx("ol", { className: "agent-activity-bubble__steps", children: steps.map((step) => {
1656
1745
  const detail = stepDetail(step, steps);
1657
1746
  return /* @__PURE__ */ jsxs(
1658
1747
  "li",
@@ -1684,7 +1773,7 @@ function AgentActivityBubble({
1684
1773
  /* @__PURE__ */ jsxs("span", { className: "agent-activity-bubble__step-copy", children: [
1685
1774
  /* @__PURE__ */ jsxs("span", { className: "agent-activity-bubble__step-heading", children: [
1686
1775
  /* @__PURE__ */ jsx("strong", { children: stepLabel(step, brandLabel) }),
1687
- /* @__PURE__ */ jsx("small", { children: step.kind === "specialist" ? "Specialist" : step.kind === "search" ? "Built-in capability" : "Supervisor" })
1776
+ step.kind === "planning" && !brandLabel ? null : /* @__PURE__ */ jsx("small", { children: step.kind === "specialist" ? "Specialist" : step.kind === "search" ? "Built-in capability" : "Supervisor" })
1688
1777
  ] }),
1689
1778
  detail ? /* @__PURE__ */ jsx("span", { className: "agent-activity-bubble__step-detail", children: detail }) : null
1690
1779
  ] })
@@ -1692,13 +1781,13 @@ function AgentActivityBubble({
1692
1781
  },
1693
1782
  step.id
1694
1783
  );
1695
- }) })
1784
+ }) }) : null
1696
1785
  ] })
1697
1786
  ] });
1698
1787
  }
1699
1788
 
1700
1789
  // src/react/components/Composer/Composer.tsx
1701
- import { useRef as useRef2, useState as useState2 } from "react";
1790
+ import { useRef as useRef2, useState as useState3 } from "react";
1702
1791
  import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
1703
1792
  function SendIcon() {
1704
1793
  return /* @__PURE__ */ jsx2("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx2("path", { d: "M8 12V4M8 4l-3 3M8 4l3 3", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) });
@@ -1709,7 +1798,7 @@ function Composer({
1709
1798
  variant = "default",
1710
1799
  onSubmit
1711
1800
  }) {
1712
- const [value, setValue] = useState2("");
1801
+ const [value, setValue] = useState3("");
1713
1802
  const inputRef = useRef2(null);
1714
1803
  function submitCurrent() {
1715
1804
  const trimmed = value.trim();
@@ -1795,8 +1884,11 @@ function FollowUpChips({
1795
1884
  ] });
1796
1885
  }
1797
1886
 
1887
+ // src/react/components/MessageBubble/MessageBubble.tsx
1888
+ import { useState as useState5 } from "react";
1889
+
1798
1890
  // src/react/components/BookingCard/BookingCard.tsx
1799
- import { useId, useMemo as useMemo2, useState as useState3 } from "react";
1891
+ import { useId, useMemo as useMemo2, useState as useState4 } from "react";
1800
1892
  import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
1801
1893
  function monthFromKey(key) {
1802
1894
  const [year, month] = key.split("-").map(Number);
@@ -1827,12 +1919,12 @@ function BookingCard({
1827
1919
  }) {
1828
1920
  const fieldId = useId();
1829
1921
  const defaultType = offer.eventTypes[0]?.uri ?? offer.slots[0]?.eventTypeUri ?? "";
1830
- const [step, setStep] = useState3("date");
1831
- const [eventTypeUri, setEventTypeUri] = useState3(defaultType);
1832
- const [selectedDate, setSelectedDate] = useState3("");
1833
- const [startTime, setStartTime] = useState3("");
1834
- const [name, setName] = useState3("");
1835
- const [email, setEmail] = useState3("");
1922
+ const [step, setStep] = useState4("date");
1923
+ const [eventTypeUri, setEventTypeUri] = useState4(defaultType);
1924
+ const [selectedDate, setSelectedDate] = useState4("");
1925
+ const [startTime, setStartTime] = useState4("");
1926
+ const [name, setName] = useState4("");
1927
+ const [email, setEmail] = useState4("");
1836
1928
  const slots = useMemo2(
1837
1929
  () => bookingSlotsForEventType(offer.slots, eventTypeUri),
1838
1930
  [eventTypeUri, offer.slots]
@@ -1845,7 +1937,7 @@ function BookingCard({
1845
1937
  }
1846
1938
  return next;
1847
1939
  }, [slots]);
1848
- const [visibleMonth, setVisibleMonth] = useState3(
1940
+ const [visibleMonth, setVisibleMonth] = useState4(
1849
1941
  () => firstAvailableBookingMonth(slots)
1850
1942
  );
1851
1943
  function selectEventType(nextType) {
@@ -2063,9 +2155,13 @@ import "streamdown/styles.css";
2063
2155
  import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
2064
2156
  function MessageBubble({
2065
2157
  message,
2158
+ brandLogoUrl,
2066
2159
  offer,
2067
2160
  onBook
2068
2161
  }) {
2162
+ const resolvedLogoUrl = brandLogoUrl?.trim();
2163
+ const [failedLogoUrl, setFailedLogoUrl] = useState5(null);
2164
+ const showBrandLogo = Boolean(resolvedLogoUrl) && failedLogoUrl !== resolvedLogoUrl;
2069
2165
  const cards = message.role === "agent" ? extractToolCards(message.text) : [];
2070
2166
  const extractedOffers = cards.filter(
2071
2167
  (card) => card.type === "booking_offer"
@@ -2077,21 +2173,34 @@ function MessageBubble({
2077
2173
  if (message.role === "visitor") {
2078
2174
  return /* @__PURE__ */ jsx5("article", { className: "message-bubble message-bubble--visitor", children: /* @__PURE__ */ jsx5("p", { className: "message-bubble__text", children: message.text }) });
2079
2175
  }
2176
+ const agentText = /* @__PURE__ */ jsx5("div", { className: "message-bubble__text", children: /* @__PURE__ */ jsx5(
2177
+ Streamdown,
2178
+ {
2179
+ animated: true,
2180
+ caret: "circle",
2181
+ className: "message-bubble__markdown",
2182
+ controls: false,
2183
+ isAnimating: isStreaming,
2184
+ linkSafety: { enabled: false },
2185
+ mode: isStreaming ? "streaming" : "static",
2186
+ skipHtml: true,
2187
+ children: displayText
2188
+ }
2189
+ ) });
2080
2190
  return /* @__PURE__ */ jsxs5("article", { className: "message-bubble message-bubble--agent", children: [
2081
- displayText ? /* @__PURE__ */ jsx5("div", { className: "message-bubble__text", children: /* @__PURE__ */ jsx5(
2082
- Streamdown,
2083
- {
2084
- animated: true,
2085
- caret: "circle",
2086
- className: "message-bubble__markdown",
2087
- controls: false,
2088
- isAnimating: isStreaming,
2089
- linkSafety: { enabled: false },
2090
- mode: isStreaming ? "streaming" : "static",
2091
- skipHtml: true,
2092
- children: displayText
2093
- }
2094
- ) }) : null,
2191
+ displayText ? showBrandLogo ? /* @__PURE__ */ jsxs5("div", { className: "message-bubble__agent-row", children: [
2192
+ /* @__PURE__ */ jsx5("span", { className: "message-bubble__agent-avatar", "aria-hidden": "true", children: /* @__PURE__ */ jsx5(
2193
+ "img",
2194
+ {
2195
+ src: resolvedLogoUrl,
2196
+ alt: "",
2197
+ onError: () => {
2198
+ setFailedLogoUrl(resolvedLogoUrl ?? null);
2199
+ }
2200
+ }
2201
+ ) }),
2202
+ agentText
2203
+ ] }) : agentText : null,
2095
2204
  offers.map((nextOffer, index) => /* @__PURE__ */ jsx5(
2096
2205
  BookingCard,
2097
2206
  {
@@ -2166,7 +2275,8 @@ function RestoreIcon() {
2166
2275
  function AgentRail({
2167
2276
  state,
2168
2277
  theme,
2169
- brandLabel = "Webless Assist",
2278
+ colorScheme = "auto",
2279
+ brandLabel = "",
2170
2280
  brandLogoUrl,
2171
2281
  poweredByLabel = "Powered by Webless",
2172
2282
  composerPlaceholder = "Ask anything\u2026",
@@ -2182,7 +2292,27 @@ function AgentRail({
2182
2292
  onBook
2183
2293
  }) {
2184
2294
  const transcriptRef = useRef3(null);
2185
- const resolvedTheme = { ...defaultAgentRailTheme, ...theme };
2295
+ const resolvedBrandLabel = brandLabel.trim();
2296
+ const resolvedBrandLogoUrl = brandLogoUrl?.trim();
2297
+ const [failedLogoUrl, setFailedLogoUrl] = useState6(null);
2298
+ const showBrandLogo = Boolean(resolvedBrandLogoUrl) && failedLogoUrl !== resolvedBrandLogoUrl;
2299
+ const resolvedColorScheme = useAgentColorScheme(colorScheme);
2300
+ const brandedTheme = { ...defaultAgentRailTheme, ...theme };
2301
+ const resolvedTheme = resolvedColorScheme === "dark" ? {
2302
+ ...brandedTheme,
2303
+ brand: theme?.brand ?? defaultDarkAgentRailTheme.brand,
2304
+ brandDeep: defaultDarkAgentRailTheme.brandDeep,
2305
+ brandSoft: `color-mix(in srgb, ${theme?.brand ?? defaultDarkAgentRailTheme.brand} 18%, ${defaultDarkAgentRailTheme.surface})`,
2306
+ border: defaultDarkAgentRailTheme.border,
2307
+ danger: defaultDarkAgentRailTheme.danger,
2308
+ success: defaultDarkAgentRailTheme.success,
2309
+ surface: defaultDarkAgentRailTheme.surface,
2310
+ surfaceMuted: defaultDarkAgentRailTheme.surfaceMuted,
2311
+ text: defaultDarkAgentRailTheme.text,
2312
+ textMuted: defaultDarkAgentRailTheme.textMuted,
2313
+ textSubtle: defaultDarkAgentRailTheme.textSubtle,
2314
+ visitorBubble: theme?.visitorBubble ?? theme?.brand ?? defaultDarkAgentRailTheme.visitorBubble
2315
+ } : brandedTheme;
2186
2316
  const railStyle = {
2187
2317
  "--rail-width": resolvedTheme.railMaxWidth,
2188
2318
  "--as-rail-max-width": resolvedTheme.railMaxWidth,
@@ -2200,7 +2330,8 @@ function AgentRail({
2200
2330
  "--as-success": resolvedTheme.success,
2201
2331
  "--as-danger": resolvedTheme.danger,
2202
2332
  "--as-font-body": resolvedTheme.fontBody,
2203
- "--as-font-display": resolvedTheme.fontDisplay
2333
+ "--as-font-display": resolvedTheme.fontDisplay,
2334
+ colorScheme: resolvedColorScheme
2204
2335
  };
2205
2336
  const isBusy = state.phase === "thinking" || state.phase === "running-tools" || state.phase === "streaming";
2206
2337
  const showActivity = state.toolSteps.length > 0;
@@ -2211,7 +2342,7 @@ function AgentRail({
2211
2342
  const greeting = state.messages.find(
2212
2343
  (message) => message.role === "agent" && message.id === "greeting"
2213
2344
  );
2214
- const visibleMessages = hasVisitorMessages2 ? state.messages.filter((message) => message.id !== "greeting") : [];
2345
+ const visibleMessages = hasVisitorMessages2 ? state.messages : [];
2215
2346
  const lastMessage = visibleMessages.at(-1);
2216
2347
  const completedAnswer = showActivity && state.phase === "complete" && lastMessage?.role === "agent" ? lastMessage : null;
2217
2348
  const transcriptMessages = completedAnswer ? visibleMessages.slice(0, -1) : visibleMessages;
@@ -2243,6 +2374,7 @@ function AgentRail({
2243
2374
  "aside",
2244
2375
  {
2245
2376
  className: `agent-rail${mobileFullscreen ? " agent-rail--mobile-fullscreen" : ""}${expanded ? " agent-rail--expanded" : ""}`,
2377
+ "data-color-scheme": resolvedColorScheme,
2246
2378
  style: railStyle,
2247
2379
  "aria-label": "Agent conversation",
2248
2380
  "aria-modal": mobileFullscreen || expanded ? true : void 0,
@@ -2270,23 +2402,20 @@ function AgentRail({
2270
2402
  children: /* @__PURE__ */ jsx6(CloseIcon, {})
2271
2403
  }
2272
2404
  ) : /* @__PURE__ */ jsx6("span", { className: "agent-rail__brand-spacer", "aria-hidden": "true" }),
2273
- /* @__PURE__ */ jsxs6("span", { className: "agent-rail__identity", children: [
2274
- /* @__PURE__ */ jsxs6("span", { className: "agent-rail__brand-mark", "aria-hidden": "true", children: [
2275
- brandLabel.slice(0, 1).toUpperCase(),
2276
- brandLogoUrl ? /* @__PURE__ */ jsx6(
2277
- "img",
2278
- {
2279
- className: "agent-rail__brand-logo",
2280
- src: brandLogoUrl,
2281
- alt: "",
2282
- onError: (event) => {
2283
- event.currentTarget.hidden = true;
2284
- }
2405
+ resolvedBrandLabel || showBrandLogo ? /* @__PURE__ */ jsxs6("span", { className: "agent-rail__identity", children: [
2406
+ showBrandLogo ? /* @__PURE__ */ jsx6("span", { className: "agent-rail__brand-mark", "aria-hidden": "true", children: /* @__PURE__ */ jsx6(
2407
+ "img",
2408
+ {
2409
+ className: "agent-rail__brand-logo",
2410
+ src: resolvedBrandLogoUrl,
2411
+ alt: "",
2412
+ onError: () => {
2413
+ setFailedLogoUrl(resolvedBrandLogoUrl ?? null);
2285
2414
  }
2286
- ) : null
2287
- ] }),
2288
- /* @__PURE__ */ jsx6("span", { className: "agent-rail__brand-label", children: brandLabel })
2289
- ] }),
2415
+ }
2416
+ ) }) : null,
2417
+ resolvedBrandLabel ? /* @__PURE__ */ jsx6("span", { className: "agent-rail__brand-label", children: resolvedBrandLabel }) : null
2418
+ ] }) : null,
2290
2419
  /* @__PURE__ */ jsxs6("span", { className: "agent-rail__actions", children: [
2291
2420
  onReset ? /* @__PURE__ */ jsx6(
2292
2421
  "button",
@@ -2304,7 +2433,7 @@ function AgentRail({
2304
2433
  {
2305
2434
  type: "button",
2306
2435
  className: "agent-rail__expand",
2307
- "aria-label": expanded ? "Exit focus view" : "Open focus view",
2436
+ "aria-label": expanded ? "Exit full screen" : "Open full screen",
2308
2437
  onClick: onExpandToggle,
2309
2438
  children: expanded ? /* @__PURE__ */ jsx6(RestoreIcon, {}) : /* @__PURE__ */ jsx6(ExpandIcon, {})
2310
2439
  }
@@ -2313,7 +2442,14 @@ function AgentRail({
2313
2442
  ] }) }),
2314
2443
  /* @__PURE__ */ jsx6("div", { ref: transcriptRef, className: "agent-rail__transcript", children: /* @__PURE__ */ jsxs6("div", { className: "agent-rail__thread", children: [
2315
2444
  !hasVisitorMessages2 ? /* @__PURE__ */ jsxs6("section", { className: "agent-rail__welcome", "aria-label": "Welcome", children: [
2316
- greeting?.role === "agent" ? /* @__PURE__ */ jsx6(MessageBubble, { message: greeting, onBook }) : null,
2445
+ greeting?.role === "agent" ? /* @__PURE__ */ jsx6(
2446
+ MessageBubble,
2447
+ {
2448
+ message: greeting,
2449
+ brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
2450
+ onBook
2451
+ }
2452
+ ) : null,
2317
2453
  showIdleFollowUps ? /* @__PURE__ */ jsx6("div", { className: "agent-rail__followups-slot", children: /* @__PURE__ */ jsx6(
2318
2454
  FollowUpChips,
2319
2455
  {
@@ -2324,21 +2460,37 @@ function AgentRail({
2324
2460
  }
2325
2461
  ) }) : null
2326
2462
  ] }) : null,
2327
- transcriptMessages.map((message) => /* @__PURE__ */ jsx6(MessageBubble, { message, onBook }, message.id)),
2328
- completedAnswer ? /* @__PURE__ */ jsx6(MessageBubble, { message: completedAnswer, onBook }) : null,
2463
+ transcriptMessages.map((message) => /* @__PURE__ */ jsx6(
2464
+ MessageBubble,
2465
+ {
2466
+ message,
2467
+ brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
2468
+ onBook
2469
+ },
2470
+ message.id
2471
+ )),
2329
2472
  showActivity ? /* @__PURE__ */ jsx6(
2330
2473
  AgentActivityBubble,
2331
2474
  {
2332
- brandLabel,
2333
- brandLogoUrl,
2475
+ brandLabel: resolvedBrandLabel,
2476
+ brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
2334
2477
  failed: state.phase === "error",
2335
2478
  steps: state.toolSteps
2336
2479
  }
2337
2480
  ) : null,
2481
+ completedAnswer ? /* @__PURE__ */ jsx6(
2482
+ MessageBubble,
2483
+ {
2484
+ message: completedAnswer,
2485
+ brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
2486
+ onBook
2487
+ }
2488
+ ) : null,
2338
2489
  streamingMessage ? /* @__PURE__ */ jsx6(
2339
2490
  MessageBubble,
2340
2491
  {
2341
2492
  message: streamingMessage,
2493
+ brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
2342
2494
  offer: state.pendingOffer,
2343
2495
  onBook
2344
2496
  }
@@ -2450,9 +2602,9 @@ function DragDots() {
2450
2602
  return /* @__PURE__ */ jsx7("span", { className: "assist-edge-tab__dots", "aria-hidden": "true", children: Array.from({ length: 12 }, (_, index) => /* @__PURE__ */ jsx7("i", {}, index)) });
2451
2603
  }
2452
2604
  var VARIANT_COPY = {
2453
- outline: { label: "Assist", aria: "Open Assist" },
2605
+ outline: { label: "Ask anything", aria: "Ask anything" },
2454
2606
  ask: { label: "Ask anything", aria: "Ask anything" },
2455
- fill: { label: "Assist", aria: "Open Assist" }
2607
+ fill: { label: "Ask anything", aria: "Ask anything" }
2456
2608
  };
2457
2609
  function AssistEdgeTab({
2458
2610
  variant,
@@ -2470,26 +2622,34 @@ function AssistEdgeTab({
2470
2622
  mobile = false,
2471
2623
  surfaceColor,
2472
2624
  textColor,
2625
+ colorScheme = "auto",
2473
2626
  onOpen
2474
2627
  }) {
2628
+ const resolvedColorScheme = useAgentColorScheme(colorScheme);
2475
2629
  const copy = VARIANT_COPY[variant];
2476
2630
  const visibleLabel = label?.trim() || copy.label;
2477
2631
  const showLogo = Boolean(logoUrl?.trim()) && !customIconUrl?.trim();
2632
+ const resolvedBrandColor = brandColor ?? (resolvedColorScheme === "dark" ? defaultDarkAgentRailTheme.brand : void 0);
2633
+ const resolvedBorderColor = resolvedColorScheme === "dark" ? defaultDarkAgentRailTheme.border : borderColor;
2634
+ const resolvedSurfaceColor = resolvedColorScheme === "dark" ? defaultDarkAgentRailTheme.surface : surfaceColor;
2635
+ const resolvedTextColor = resolvedColorScheme === "dark" ? defaultDarkAgentRailTheme.text : textColor;
2478
2636
  const style = {
2479
2637
  "--tab-along": `${along}%`,
2480
2638
  "--tab-inset": `${inset}px`,
2481
- ...brandColor ? { "--as-brand": brandColor } : {},
2639
+ ...resolvedBrandColor ? { "--as-brand": resolvedBrandColor } : {},
2482
2640
  ...brandForeground ? { "--as-visitor-text": brandForeground } : {},
2483
- ...borderColor ? { "--as-border": borderColor } : {},
2641
+ ...resolvedBorderColor ? { "--as-border": resolvedBorderColor } : {},
2484
2642
  ...fontFamily ? { "--as-font-display": fontFamily } : {},
2485
- ...surfaceColor ? { "--as-surface": surfaceColor } : {},
2486
- ...textColor ? { "--as-text": textColor } : {}
2643
+ ...resolvedSurfaceColor ? { "--as-surface": resolvedSurfaceColor } : {},
2644
+ ...resolvedTextColor ? { "--as-text": resolvedTextColor } : {},
2645
+ colorScheme: resolvedColorScheme
2487
2646
  };
2488
2647
  return /* @__PURE__ */ jsxs7(
2489
2648
  "button",
2490
2649
  {
2491
2650
  type: "button",
2492
2651
  className: `assist-edge-tab assist-edge-tab--${variant} assist-edge-tab--${side}${mobile ? " assist-edge-tab--mobile" : ""}${visible ? " is-visible" : ""}`,
2652
+ "data-color-scheme": resolvedColorScheme,
2493
2653
  style,
2494
2654
  "aria-label": `Open ${visibleLabel}`,
2495
2655
  "aria-hidden": !visible,
@@ -2503,7 +2663,7 @@ function AssistEdgeTab({
2503
2663
  className: "assist-edge-tab__mark assist-edge-tab__mark--mobile",
2504
2664
  "aria-hidden": "true",
2505
2665
  children: [
2506
- customIconUrl?.trim() ? /* @__PURE__ */ jsx7(TabMarkIcon, { customIconUrl }) : visibleLabel.slice(0, 1).toUpperCase(),
2666
+ /* @__PURE__ */ jsx7(TabMarkIcon, { customIconUrl }),
2507
2667
  showLogo ? /* @__PURE__ */ jsx7(
2508
2668
  "img",
2509
2669
  {
@@ -2518,10 +2678,7 @@ function AssistEdgeTab({
2518
2678
  ]
2519
2679
  }
2520
2680
  ),
2521
- /* @__PURE__ */ jsxs7("span", { className: "assist-edge-tab__label", children: [
2522
- "Ask ",
2523
- visibleLabel
2524
- ] })
2681
+ /* @__PURE__ */ jsx7("span", { className: "assist-edge-tab__label", children: visibleLabel })
2525
2682
  ] }) : variant === "outline" ? /* @__PURE__ */ jsxs7(Fragment2, { children: [
2526
2683
  /* @__PURE__ */ jsxs7("span", { className: "assist-edge-tab__mark", "aria-hidden": "true", children: [
2527
2684
  /* @__PURE__ */ jsx7(TabMarkIcon, { customIconUrl }),
@@ -2569,7 +2726,7 @@ function AssistEdgeTab({
2569
2726
  }
2570
2727
 
2571
2728
  // src/react/components/AgentWidget/AgentWidget.tsx
2572
- import { useEffect as useEffect5, useRef as useRef4, useState as useState5 } from "react";
2729
+ import { useEffect as useEffect5, useRef as useRef4, useState as useState8 } from "react";
2573
2730
 
2574
2731
  // src/react/page-shift.ts
2575
2732
  import { useEffect as useEffect3 } from "react";
@@ -2652,9 +2809,9 @@ function usePageShift(input) {
2652
2809
  }
2653
2810
 
2654
2811
  // src/react/hooks/useIsMobile.ts
2655
- import { useEffect as useEffect4, useState as useState4 } from "react";
2812
+ import { useEffect as useEffect4, useState as useState7 } from "react";
2656
2813
  function useIsMobile(breakpoint = 767) {
2657
- const [isMobile, setIsMobile] = useState4(
2814
+ const [isMobile, setIsMobile] = useState7(
2658
2815
  () => typeof window !== "undefined" && window.matchMedia(`(max-width: ${breakpoint}px)`).matches
2659
2816
  );
2660
2817
  useEffect4(() => {
@@ -2700,8 +2857,8 @@ function AgentWidget({
2700
2857
  const isMobile = useIsMobile();
2701
2858
  const placement = normalizeAgentPlacement(placementInput);
2702
2859
  const railSlotRef = useRef4(null);
2703
- const [railCollapsed, setRailCollapsed] = useState5(defaultCollapsed);
2704
- const [railExpanded, setRailExpanded] = useState5(false);
2860
+ const [railCollapsed, setRailCollapsed] = useState8(defaultCollapsed);
2861
+ const [railExpanded, setRailExpanded] = useState8(false);
2705
2862
  const pageShiftActive = shouldApplyPageShift({
2706
2863
  pageShift,
2707
2864
  isMobile,
@@ -2721,7 +2878,7 @@ function AgentWidget({
2721
2878
  runtimeOrigin,
2722
2879
  greeting: branding?.greeting
2723
2880
  });
2724
- const agentName = branding?.agentName ?? "Webless Guide";
2881
+ const agentName = branding?.agentName ?? "";
2725
2882
  const tabLabel = branding?.tabLabel ?? agentName;
2726
2883
  const theme = {
2727
2884
  ...branding?.fontFamily ? { fontBody: branding.fontFamily, fontDisplay: branding.fontFamily } : {},
@@ -2790,58 +2947,40 @@ function AgentWidget({
2790
2947
  return () => window.removeEventListener("keydown", handleKeyDown);
2791
2948
  }, [isMobile, railCollapsed, railExpanded]);
2792
2949
  return /* @__PURE__ */ jsxs8("div", { className: "webless-agent-root", children: [
2793
- /* @__PURE__ */ jsxs8(
2950
+ /* @__PURE__ */ jsx8(
2794
2951
  "div",
2795
2952
  {
2796
2953
  className: `webless-agent-root__shell${railCollapsed ? " webless-agent-root__shell--collapsed" : ""}${railExpanded ? " webless-agent-root__shell--expanded" : ""}`,
2797
- children: [
2798
- /* @__PURE__ */ jsx8(
2799
- "div",
2800
- {
2801
- ref: railSlotRef,
2802
- className: "webless-agent-root__rail-slot",
2803
- inert: railCollapsed || void 0,
2804
- "aria-hidden": railCollapsed,
2805
- children: /* @__PURE__ */ jsx8(
2806
- AgentRail,
2807
- {
2808
- theme,
2809
- brandLabel: agentName,
2810
- brandLogoUrl: branding?.logoUrl,
2811
- composerPlaceholder: branding?.composerPlaceholder ?? "Ask as a visitor\u2026",
2812
- poweredByLabel: branding?.poweredByLabel ?? "Powered by Webless",
2813
- state,
2814
- mobileFullscreen: isMobile && !railCollapsed,
2815
- expanded: railExpanded,
2816
- onCollapse: !isMobile ? () => setRailCollapsed(true) : void 0,
2817
- onClose: isMobile ? () => setRailCollapsed(true) : void 0,
2818
- onExpandToggle: !isMobile ? () => setRailExpanded((current) => !current) : void 0,
2819
- onSubmit: handleSubmit,
2820
- onReset: reset,
2821
- onRetry: () => void retry(),
2822
- onFollowUpSelect: (label) => void handleSubmit(label),
2823
- onBook: (input) => void submit(input.displayText, { runtimeText: input.runtimeText })
2824
- }
2825
- )
2826
- }
2827
- ),
2828
- !railCollapsed && isMobile || !isMobile && railExpanded && !railCollapsed ? /* @__PURE__ */ jsx8(
2829
- "button",
2830
- {
2831
- type: "button",
2832
- className: `webless-agent-root__backdrop${isMobile ? " webless-agent-root__backdrop--mobile" : ""}`,
2833
- tabIndex: -1,
2834
- "aria-label": isMobile ? "Close agent" : "Exit focus view",
2835
- onClick: () => {
2836
- if (isMobile) {
2837
- setRailCollapsed(true);
2838
- } else {
2839
- setRailExpanded(false);
2840
- }
2954
+ children: /* @__PURE__ */ jsx8(
2955
+ "div",
2956
+ {
2957
+ ref: railSlotRef,
2958
+ className: "webless-agent-root__rail-slot",
2959
+ inert: railCollapsed || void 0,
2960
+ "aria-hidden": railCollapsed,
2961
+ children: /* @__PURE__ */ jsx8(
2962
+ AgentRail,
2963
+ {
2964
+ theme,
2965
+ brandLabel: agentName,
2966
+ brandLogoUrl: branding?.logoUrl,
2967
+ composerPlaceholder: branding?.composerPlaceholder ?? "Ask a question\u2026",
2968
+ poweredByLabel: branding?.poweredByLabel ?? "Powered by Webless",
2969
+ state,
2970
+ mobileFullscreen: isMobile && !railCollapsed,
2971
+ expanded: railExpanded,
2972
+ onCollapse: !isMobile ? () => setRailCollapsed(true) : void 0,
2973
+ onClose: isMobile ? () => setRailCollapsed(true) : void 0,
2974
+ onExpandToggle: !isMobile ? () => setRailExpanded((current) => !current) : void 0,
2975
+ onSubmit: handleSubmit,
2976
+ onReset: reset,
2977
+ onRetry: () => void retry(),
2978
+ onFollowUpSelect: (label) => void handleSubmit(label),
2979
+ onBook: (input) => void submit(input.displayText, { runtimeText: input.runtimeText })
2841
2980
  }
2842
- }
2843
- ) : null
2844
- ]
2981
+ )
2982
+ }
2983
+ )
2845
2984
  }
2846
2985
  ),
2847
2986
  railCollapsed ? /* @__PURE__ */ jsx8(
@@ -2880,8 +3019,9 @@ export {
2880
3019
  openAgentPanel,
2881
3020
  closeAgentPanel,
2882
3021
  defaultAgentRailTheme,
3022
+ defaultDarkAgentRailTheme,
2883
3023
  AgentRail,
2884
3024
  AssistEdgeTab,
2885
3025
  AgentWidget
2886
3026
  };
2887
- //# sourceMappingURL=chunk-E4JSTYPX.js.map
3027
+ //# sourceMappingURL=chunk-Y7Z3ZIAQ.js.map