@unctad-ai/voice-agent-ui 5.2.3 → 5.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -8,7 +8,7 @@ import {
8
8
  VoiceSettingsProvider,
9
9
  VoiceSettingsView,
10
10
  useVoiceSettings
11
- } from "./chunk-LDKQCDOW.js";
11
+ } from "./chunk-RZHUDZVZ.js";
12
12
 
13
13
  // src/VoiceAgentProvider.tsx
14
14
  import { SiteConfigProvider } from "@unctad-ai/voice-agent-core";
@@ -33,7 +33,7 @@ import {
33
33
  } from "react";
34
34
  import { createPortal } from "react-dom";
35
35
  import { motion as motion5, AnimatePresence as AnimatePresence5, useReducedMotion as useReducedMotion2 } from "motion/react";
36
- import { ChevronDown as ChevronDown2, X, Mic as Mic3, ArrowUp, Keyboard as Keyboard2, RotateCw, Settings, VolumeX as VolumeX2, Flag as Flag2 } from "lucide-react";
36
+ import { ChevronDown as ChevronDown2, X, Mic as Mic3, MicOff as MicOff2, ArrowUp, Keyboard as Keyboard2, RotateCw, Settings, VolumeX as VolumeX2, Flag as Flag2 } from "lucide-react";
37
37
  import {
38
38
  useVoiceAgent,
39
39
  voiceStateToOrbState,
@@ -1764,15 +1764,15 @@ function PipelineMetricsBar({
1764
1764
 
1765
1765
  // src/components/GlassCopilotPanel.tsx
1766
1766
  import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
1767
- var VoiceSettingsView2 = lazy(() => import("./VoiceSettingsView-6SD47AUN.js"));
1767
+ var VoiceSettingsView2 = lazy(() => import("./VoiceSettingsView-6QTJRFZ6.js"));
1768
1768
  var RETRY_INITIAL_MS = 3e3;
1769
1769
  var RETRY_MAX_MS = 3e4;
1770
1770
  var STATE_LABELS = {
1771
1771
  IDLE: "Tap mic to speak",
1772
- LISTENING: "Listening...",
1773
- USER_SPEAKING: "Listening...",
1774
- PROCESSING: "Processing...",
1775
- AI_SPEAKING: "Speaking..."
1772
+ LISTENING: "I'm listening...",
1773
+ USER_SPEAKING: "I'm listening...",
1774
+ PROCESSING: "Thinking...",
1775
+ AI_SPEAKING: "Responding..."
1776
1776
  };
1777
1777
  var ARIA_LIVE_LABELS = {
1778
1778
  idle: "",
@@ -2123,35 +2123,33 @@ function CollapsedBar({
2123
2123
  }
2124
2124
  )
2125
2125
  ] }),
2126
- !isOffline && onMicToggle && /* @__PURE__ */ jsxs8(
2127
- "button",
2128
- {
2129
- onClick: (e) => {
2130
- e.stopPropagation();
2131
- onMicToggle();
2132
- },
2133
- className: "shrink-0 rounded-full flex items-center justify-center transition-all cursor-pointer relative",
2134
- style: {
2135
- width: 44,
2136
- height: 44,
2137
- backgroundColor: voiceState === "LISTENING" || voiceState === "USER_SPEAKING" ? colors.primary : "rgba(0,0,0,0.06)",
2138
- color: voiceState === "LISTENING" || voiceState === "USER_SPEAKING" ? "white" : "rgba(0,0,0,0.45)"
2139
- },
2140
- "aria-label": voiceState === "LISTENING" || voiceState === "USER_SPEAKING" ? "Stop listening" : "Start listening",
2141
- children: [
2142
- (voiceState === "LISTENING" || voiceState === "USER_SPEAKING") && /* @__PURE__ */ jsx9(
2143
- motion5.span,
2144
- {
2145
- className: "absolute inset-0 rounded-full",
2146
- animate: { scale: [1, 1.3, 1], opacity: [0.3, 0, 0.3] },
2147
- transition: { duration: 1.8, repeat: Infinity, ease: "easeInOut" },
2148
- style: { backgroundColor: `${colors.primary}40` }
2149
- }
2150
- ),
2151
- /* @__PURE__ */ jsx9(Mic3, { style: { width: 16, height: 16, position: "relative", zIndex: 1 } })
2152
- ]
2153
- }
2154
- ),
2126
+ !isOffline && onMicToggle && (() => {
2127
+ const barListening = voiceState === "LISTENING" || voiceState === "USER_SPEAKING";
2128
+ return /* @__PURE__ */ jsx9(
2129
+ motion5.button,
2130
+ {
2131
+ onClick: (e) => {
2132
+ e.stopPropagation();
2133
+ onMicToggle();
2134
+ },
2135
+ whileHover: { scale: 1.08 },
2136
+ whileTap: { scale: 0.93 },
2137
+ animate: barListening ? { backgroundColor: [colors.primary, `${colors.primary}BB`, colors.primary] } : { backgroundColor: "rgba(0,0,0,0.06)" },
2138
+ transition: barListening ? { backgroundColor: { duration: 1.8, repeat: Infinity, ease: "easeInOut" } } : { duration: 0.3 },
2139
+ className: "shrink-0 rounded-full flex items-center justify-center cursor-pointer relative",
2140
+ style: {
2141
+ width: 44,
2142
+ height: 44,
2143
+ color: barListening ? "white" : "rgba(0,0,0,0.45)",
2144
+ border: "none",
2145
+ padding: 0,
2146
+ boxShadow: barListening ? `0 2px 8px ${colors.primary}40, 0 1px 3px rgba(0,0,0,0.12)` : "0 1px 4px rgba(0,0,0,0.10)"
2147
+ },
2148
+ "aria-label": barListening ? "Stop listening" : "Start listening",
2149
+ children: barListening ? /* @__PURE__ */ jsx9(Mic3, { style: { width: 16, height: 16, position: "relative", zIndex: 1 } }) : /* @__PURE__ */ jsx9(MicOff2, { style: { width: 16, height: 16, position: "relative", zIndex: 1 } })
2150
+ }
2151
+ );
2152
+ })(),
2155
2153
  isOffline && /* @__PURE__ */ jsx9(
2156
2154
  "span",
2157
2155
  {
@@ -2172,8 +2170,8 @@ function CollapsedBar({
2172
2170
  },
2173
2171
  className: "shrink-0 rounded-full flex items-center justify-center transition-colors cursor-pointer",
2174
2172
  style: {
2175
- width: 44,
2176
- height: 44,
2173
+ width: 32,
2174
+ height: 32,
2177
2175
  color: "rgba(0,0,0,0.4)"
2178
2176
  },
2179
2177
  onMouseEnter: (e) => {
@@ -2183,7 +2181,7 @@ function CollapsedBar({
2183
2181
  e.currentTarget.style.color = "rgba(0,0,0,0.4)";
2184
2182
  },
2185
2183
  "aria-label": "Close voice assistant",
2186
- children: /* @__PURE__ */ jsx9(X, { style: { width: 18, height: 18 } })
2184
+ children: /* @__PURE__ */ jsx9(X, { style: { width: 14, height: 14 } })
2187
2185
  }
2188
2186
  )
2189
2187
  ]
@@ -2288,7 +2286,7 @@ function ComposerBar({
2288
2286
  },
2289
2287
  "aria-label": isListening ? "Stop listening" : "Start listening",
2290
2288
  "data-testid": "voice-agent-mic",
2291
- children: /* @__PURE__ */ jsx9(Mic3, { style: { width: 18, height: 18, position: "relative", zIndex: 1 } })
2289
+ children: isListening ? /* @__PURE__ */ jsx9(Mic3, { style: { width: 18, height: 18, position: "relative", zIndex: 1 } }) : /* @__PURE__ */ jsx9(MicOff2, { style: { width: 18, height: 18, position: "relative", zIndex: 1 } })
2292
2290
  }
2293
2291
  ),
2294
2292
  /* @__PURE__ */ jsx9("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsx9(AnimatePresence5, { mode: "wait", children: /* @__PURE__ */ jsx9(
@@ -2304,29 +2302,36 @@ function ComposerBar({
2304
2302
  fontWeight: 400,
2305
2303
  color: micPaused ? "rgba(0,0,0,0.35)" : voiceState === "LISTENING" || voiceState === "USER_SPEAKING" ? colors.primary : "rgba(0,0,0,0.45)"
2306
2304
  },
2307
- children: micPaused ? "Paused" : STATE_LABELS[voiceState]
2305
+ children: micPaused ? "Tap mic to resume" : STATE_LABELS[voiceState]
2308
2306
  },
2309
2307
  micPaused ? "paused" : voiceState
2310
2308
  ) }) }),
2311
- /* @__PURE__ */ jsx9(
2309
+ /* @__PURE__ */ jsxs8(
2312
2310
  motion5.button,
2313
2311
  {
2314
- whileHover: { scale: 1.08 },
2315
- whileTap: { scale: 0.92 },
2312
+ whileHover: { scale: 1.04 },
2313
+ whileTap: { scale: 0.96 },
2316
2314
  onClick: () => {
2317
2315
  if (isListening) onMicToggle();
2318
2316
  setMode("text");
2319
2317
  },
2320
- className: "shrink-0 rounded-full flex items-center justify-center cursor-pointer",
2318
+ className: "shrink-0 flex items-center gap-1.5 cursor-pointer",
2321
2319
  style: {
2322
- width: 44,
2323
- height: 44,
2320
+ height: 36,
2321
+ padding: "0 12px",
2322
+ borderRadius: 18,
2324
2323
  backgroundColor: "rgba(0,0,0,0.05)",
2325
- color: "rgba(0,0,0,0.4)"
2324
+ color: "rgba(0,0,0,0.4)",
2325
+ border: "none",
2326
+ fontSize: 12,
2327
+ fontWeight: 500
2326
2328
  },
2327
2329
  "aria-label": "Type a message",
2328
2330
  "data-testid": "voice-agent-keyboard",
2329
- children: /* @__PURE__ */ jsx9(Keyboard2, { style: { width: 18, height: 18 } })
2331
+ children: [
2332
+ /* @__PURE__ */ jsx9(Keyboard2, { style: { width: 14, height: 14 } }),
2333
+ /* @__PURE__ */ jsx9("span", { children: "Type" })
2334
+ ]
2330
2335
  }
2331
2336
  )
2332
2337
  ]
@@ -2369,8 +2374,8 @@ function ComposerBar({
2369
2374
  onFocus: (e) => {
2370
2375
  const pill = e.currentTarget.parentElement;
2371
2376
  if (pill) {
2372
- pill.style.borderColor = `${colors.primary}4D`;
2373
- pill.style.boxShadow = `0 0 0 2px ${colors.primary}14`;
2377
+ pill.style.borderColor = "rgba(0,0,0,0.15)";
2378
+ pill.style.boxShadow = "0 0 0 2px rgba(0,0,0,0.04)";
2374
2379
  }
2375
2380
  },
2376
2381
  onBlur: (e) => {
@@ -2380,7 +2385,7 @@ function ComposerBar({
2380
2385
  pill.style.boxShadow = "none";
2381
2386
  }
2382
2387
  },
2383
- placeholder: disabled ? "Reconnecting..." : "Ask about services...",
2388
+ placeholder: disabled ? "Reconnecting..." : "Message...",
2384
2389
  "aria-label": "Type your question",
2385
2390
  "data-testid": "voice-agent-input",
2386
2391
  className: "w-full",
@@ -2577,7 +2582,7 @@ function ExpandedContent({
2577
2582
  "div",
2578
2583
  {
2579
2584
  className: "flex items-center gap-3 shrink-0",
2580
- style: { height: 64, padding: "12px 16px", borderBottom: "1px solid rgba(0,0,0,0.06)" },
2585
+ style: { height: 64, padding: "12px 16px", borderBottom: "1px solid rgba(0,0,0,0.06)", backgroundColor: `${colors.primary}08` },
2581
2586
  children: [
2582
2587
  /* @__PURE__ */ jsxs8(
2583
2588
  motion5.div,
@@ -2614,7 +2619,7 @@ function ExpandedContent({
2614
2619
  e.stopPropagation();
2615
2620
  onRetry();
2616
2621
  }, className: "inline-flex items-center justify-center rounded-full transition-colors cursor-pointer", style: { width: 18, height: 18, color: "rgba(220,38,38,0.5)" }, "aria-label": "Retry connection", children: /* @__PURE__ */ jsx9(motion5.span, { animate: isRetrying ? { rotate: 360 } : { rotate: 0 }, transition: isRetrying ? { duration: 0.8, repeat: Infinity, ease: "linear" } : { duration: 0.3 }, style: { display: "flex", alignItems: "center", justifyContent: "center" }, children: /* @__PURE__ */ jsx9(RotateCw, { style: { width: 12, height: 12 } }) }) })
2617
- ] }) : micPaused ? "Paused" : STATE_LABELS[voiceState] })
2622
+ ] }) : micPaused ? "Tap mic to resume" : STATE_LABELS[voiceState] })
2618
2623
  ] }),
2619
2624
  /* @__PURE__ */ jsx9(
2620
2625
  "button",
@@ -2623,20 +2628,20 @@ function ExpandedContent({
2623
2628
  className: "shrink-0 rounded-full transition-colors cursor-pointer",
2624
2629
  style: {
2625
2630
  color: showSettings ? colors.primary : "rgba(0,0,0,0.4)",
2626
- width: 44,
2627
- height: 44,
2631
+ width: 32,
2632
+ height: 32,
2628
2633
  display: "flex",
2629
2634
  alignItems: "center",
2630
2635
  justifyContent: "center",
2631
- backgroundColor: showSettings ? `${colors.primary}14` : "rgba(0,0,0,0.05)"
2636
+ backgroundColor: showSettings ? `${colors.primary}14` : "transparent"
2632
2637
  },
2633
2638
  "aria-label": showSettings ? "Close settings" : "Open settings",
2634
2639
  "data-testid": "voice-agent-settings",
2635
- children: /* @__PURE__ */ jsx9(Settings, { style: { width: 16, height: 16 } })
2640
+ children: /* @__PURE__ */ jsx9(Settings, { style: { width: 14, height: 14 } })
2636
2641
  }
2637
2642
  ),
2638
- /* @__PURE__ */ jsx9("button", { onClick: onCollapse, className: "shrink-0 rounded-full transition-colors cursor-pointer", style: { color: "rgba(0,0,0,0.4)", width: 44, height: 44, display: "flex", alignItems: "center", justifyContent: "center", backgroundColor: "rgba(0,0,0,0.05)" }, "aria-label": "Minimize panel", "data-testid": "voice-agent-minimize", children: /* @__PURE__ */ jsx9(ChevronDown2, { style: { width: 16, height: 16 } }) }),
2639
- /* @__PURE__ */ jsx9("button", { onClick: onClose, className: "shrink-0 rounded-full transition-colors cursor-pointer", style: { color: "rgba(0,0,0,0.4)", width: 44, height: 44, display: "flex", alignItems: "center", justifyContent: "center", backgroundColor: "rgba(0,0,0,0.05)" }, "aria-label": "Close voice assistant", "data-testid": "voice-agent-close", children: /* @__PURE__ */ jsx9(X, { style: { width: 16, height: 16 } }) })
2643
+ /* @__PURE__ */ jsx9("button", { onClick: onCollapse, className: "shrink-0 rounded-full transition-colors cursor-pointer", style: { color: "rgba(0,0,0,0.4)", width: 32, height: 32, display: "flex", alignItems: "center", justifyContent: "center", backgroundColor: "transparent" }, "aria-label": "Minimize panel", "data-testid": "voice-agent-minimize", children: /* @__PURE__ */ jsx9(ChevronDown2, { style: { width: 14, height: 14 } }) }),
2644
+ /* @__PURE__ */ jsx9("button", { onClick: onClose, className: "shrink-0 rounded-full transition-colors cursor-pointer", style: { color: "rgba(0,0,0,0.4)", width: 32, height: 32, display: "flex", alignItems: "center", justifyContent: "center", backgroundColor: "transparent" }, "aria-label": "Close voice assistant", "data-testid": "voice-agent-close", children: /* @__PURE__ */ jsx9(X, { style: { width: 14, height: 14 } }) })
2640
2645
  ]
2641
2646
  }
2642
2647
  ),
@@ -2905,7 +2910,7 @@ function WiredPanelInner({
2905
2910
  timings: lastTimings ?? void 0,
2906
2911
  route: window.location.pathname,
2907
2912
  copilotName: config.copilotName,
2908
- kitVersion: "5.2.3"
2913
+ kitVersion: "5.2.5"
2909
2914
  })
2910
2915
  });
2911
2916
  const body = await res.json().catch(() => ({ ticketId: void 0 }));
@@ -2988,7 +2993,6 @@ function GlassCopilotPanel({ isOpen: isOpenProp, onOpen: onOpenProp, onClose: on
2988
2993
  clearInterval(timer);
2989
2994
  };
2990
2995
  }, [config.excludeRoutes]);
2991
- if (routeHidden) return null;
2992
2996
  const [internalOpen, setInternalOpen] = useState5(false);
2993
2997
  const isControlled = isOpenProp !== void 0;
2994
2998
  const isOpen = isControlled ? isOpenProp : internalOpen;
@@ -3010,7 +3014,7 @@ function GlassCopilotPanel({ isOpen: isOpenProp, onOpen: onOpenProp, onClose: on
3010
3014
  }, []);
3011
3015
  const [fabOffline, setFabOffline] = useState5(false);
3012
3016
  useEffect6(() => {
3013
- if (isOpen) return;
3017
+ if (isOpen || routeHidden) return;
3014
3018
  let cancelled = false;
3015
3019
  const check = () => {
3016
3020
  checkBackendHealth().then(({ available }) => {
@@ -3023,7 +3027,7 @@ function GlassCopilotPanel({ isOpen: isOpenProp, onOpen: onOpenProp, onClose: on
3023
3027
  cancelled = true;
3024
3028
  clearInterval(timer);
3025
3029
  };
3026
- }, [isOpen]);
3030
+ }, [isOpen, routeHidden]);
3027
3031
  const isVisible = panelState !== "hidden";
3028
3032
  const isExpanded = panelState === "expanded";
3029
3033
  const targetHeight = isExpanded ? PANEL_EXPANDED_HEIGHT : PANEL_COLLAPSED_HEIGHT;
@@ -3046,6 +3050,7 @@ function GlassCopilotPanel({ isOpen: isOpenProp, onOpen: onOpenProp, onClose: on
3046
3050
  setAriaAnnouncement(ARIA_LIVE_LABELS[orbState]);
3047
3051
  onStateChange?.(orbState);
3048
3052
  }, [onStateChange]);
3053
+ if (routeHidden) return null;
3049
3054
  return createPortal(
3050
3055
  /* @__PURE__ */ jsxs8(VoiceErrorBoundary, { onReset: handleClose, children: [
3051
3056
  /* @__PURE__ */ jsx9("svg", { xmlns: "http://www.w3.org/2000/svg", width: "0", height: "0", style: { position: "absolute", overflow: "hidden" }, "aria-hidden": "true", children: /* @__PURE__ */ jsx9("defs", { children: /* @__PURE__ */ jsxs8("filter", { id: "liquid-glass-panel", x: "0%", y: "0%", width: "100%", height: "100%", children: [