@usecrow/ui 0.1.65 → 0.1.67

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.cjs CHANGED
@@ -1263,6 +1263,16 @@ function useCrowAPI({ onIdentified, onReset } = {}) {
1263
1263
  }
1264
1264
  return client.crowAsk(opts);
1265
1265
  }
1266
+ case "setContextLabel":
1267
+ if (typeof options !== "string") {
1268
+ console.error("[Crow] setContextLabel() requires a string");
1269
+ return;
1270
+ }
1271
+ window.__crow_context_label = options || void 0;
1272
+ window.dispatchEvent(
1273
+ new CustomEvent("crow:setContextLabel", { detail: options })
1274
+ );
1275
+ break;
1266
1276
  case "setSuggestedActions":
1267
1277
  if (!Array.isArray(options)) {
1268
1278
  console.error("[Crow] setSuggestedActions() requires an array of { label, message }");
@@ -1628,6 +1638,12 @@ function useWidgetStyles({
1628
1638
  const [selectedModel, setSelectedModel] = React3.useState(
1629
1639
  styleCache.get(key)?.model ?? void 0
1630
1640
  );
1641
+ const [modelSelectionEnabled, setModelSelectionEnabled] = React3.useState(
1642
+ styleCache.get(key)?.modelSelectionEnabled || false
1643
+ );
1644
+ const [availableModels, setAvailableModels] = React3.useState(
1645
+ styleCache.get(key)?.availableModels || []
1646
+ );
1631
1647
  const hasFetchedRef = React3.useRef(false);
1632
1648
  const fetchStyles = async () => {
1633
1649
  if (skip) return;
@@ -1647,6 +1663,8 @@ function useWidgetStyles({
1647
1663
  setSelectedModel(config.model ?? void 0);
1648
1664
  setInitialSuggestions(config.initialSuggestions || []);
1649
1665
  setToolConsentSettings(config.toolConsentSettings || {});
1666
+ setModelSelectionEnabled(config.modelSelectionEnabled || false);
1667
+ setAvailableModels(config.availableModels || []);
1650
1668
  } catch (err) {
1651
1669
  console.error("[CrowWidget] Failed to fetch styles:", err);
1652
1670
  setError(err instanceof Error ? err : new Error(String(err)));
@@ -1665,6 +1683,8 @@ function useWidgetStyles({
1665
1683
  setPersistAnonymousConversations(cached.persistAnonymousConversations ?? true);
1666
1684
  setWelcomeMessage(cached.welcomeMessage ?? void 0);
1667
1685
  setSelectedModel(cached.model ?? void 0);
1686
+ setModelSelectionEnabled(cached.modelSelectionEnabled || false);
1687
+ setAvailableModels(cached.availableModels || []);
1668
1688
  setIsLoading(false);
1669
1689
  return;
1670
1690
  }
@@ -1686,6 +1706,8 @@ function useWidgetStyles({
1686
1706
  selectedModel,
1687
1707
  initialSuggestions,
1688
1708
  toolConsentSettings,
1709
+ modelSelectionEnabled,
1710
+ availableModels,
1689
1711
  refetch: fetchStyles
1690
1712
  };
1691
1713
  }
@@ -1725,6 +1747,12 @@ function useCopilotStyles({
1725
1747
  const [toolConsentSettings, setToolConsentSettings] = React3.useState(
1726
1748
  styleCache.get(key)?.toolConsentSettings || {}
1727
1749
  );
1750
+ const [modelSelectionEnabled, setModelSelectionEnabled] = React3.useState(
1751
+ styleCache.get(key)?.modelSelectionEnabled || false
1752
+ );
1753
+ const [availableModels, setAvailableModels] = React3.useState(
1754
+ styleCache.get(key)?.availableModels || []
1755
+ );
1728
1756
  const hasFetchedRef = React3.useRef(false);
1729
1757
  const fetchStyles = async () => {
1730
1758
  if (skip) return;
@@ -1742,6 +1770,8 @@ function useCopilotStyles({
1742
1770
  setWelcomeMessage(config.welcomeMessage ?? void 0);
1743
1771
  setSelectedModel(config.model ?? void 0);
1744
1772
  setToolConsentSettings(config.toolConsentSettings || {});
1773
+ setModelSelectionEnabled(config.modelSelectionEnabled || false);
1774
+ setAvailableModels(config.availableModels || []);
1745
1775
  } catch (err) {
1746
1776
  console.error("[CrowCopilot] Failed to fetch styles:", err);
1747
1777
  setError(err instanceof Error ? err : new Error(String(err)));
@@ -1761,6 +1791,8 @@ function useCopilotStyles({
1761
1791
  setPersistAnonymousConversations(cached.persistAnonymousConversations ?? true);
1762
1792
  setWelcomeMessage(cached.welcomeMessage ?? void 0);
1763
1793
  setSelectedModel(cached.model ?? void 0);
1794
+ setModelSelectionEnabled(cached.modelSelectionEnabled || false);
1795
+ setAvailableModels(cached.availableModels || []);
1764
1796
  setIsLoading(false);
1765
1797
  return;
1766
1798
  }
@@ -1780,6 +1812,8 @@ function useCopilotStyles({
1780
1812
  welcomeMessage,
1781
1813
  selectedModel,
1782
1814
  toolConsentSettings,
1815
+ modelSelectionEnabled,
1816
+ availableModels,
1783
1817
  refetch: fetchStyles
1784
1818
  };
1785
1819
  }
@@ -2464,7 +2498,8 @@ function WidgetHeader({
2464
2498
  onDragPointerDown,
2465
2499
  isDragging,
2466
2500
  hasCustomTransform,
2467
- onResetTransform
2501
+ onResetTransform,
2502
+ contextLabel
2468
2503
  }) {
2469
2504
  const { agentName, styles } = useWidgetStyleContext();
2470
2505
  return /* @__PURE__ */ jsxRuntime.jsxs(
@@ -2552,7 +2587,36 @@ function WidgetHeader({
2552
2587
  children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { size: 18, className: "crow-text-gray-700" })
2553
2588
  }
2554
2589
  )
2555
- ] })
2590
+ ] }),
2591
+ contextLabel && /* @__PURE__ */ jsxRuntime.jsxs(
2592
+ "div",
2593
+ {
2594
+ className: "crow-flex crow-items-center crow-gap-1.5 crow-mt-1 crow-text-xs",
2595
+ style: { color: "#6b7280" },
2596
+ children: [
2597
+ /* @__PURE__ */ jsxRuntime.jsxs(
2598
+ "svg",
2599
+ {
2600
+ xmlns: "http://www.w3.org/2000/svg",
2601
+ width: "12",
2602
+ height: "12",
2603
+ viewBox: "0 0 24 24",
2604
+ fill: "none",
2605
+ stroke: "currentColor",
2606
+ strokeWidth: "2",
2607
+ strokeLinecap: "round",
2608
+ strokeLinejoin: "round",
2609
+ className: "crow-shrink-0",
2610
+ children: [
2611
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0Z" }),
2612
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "12", cy: "10", r: "3" })
2613
+ ]
2614
+ }
2615
+ ),
2616
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "crow-truncate", children: contextLabel })
2617
+ ]
2618
+ }
2619
+ )
2556
2620
  ]
2557
2621
  }
2558
2622
  );
@@ -3191,7 +3255,9 @@ var ModelSelector = ({
3191
3255
  const dropdownRef = React3.useRef(null);
3192
3256
  React3.useEffect(() => {
3193
3257
  const handleClickOutside = (event) => {
3194
- if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
3258
+ if (!dropdownRef.current) return;
3259
+ const path = event.composedPath();
3260
+ if (!path.includes(dropdownRef.current)) {
3195
3261
  setIsOpen(false);
3196
3262
  }
3197
3263
  };
@@ -4158,7 +4224,8 @@ function CrowWidget({
4158
4224
  context,
4159
4225
  toolRenderers,
4160
4226
  language,
4161
- customCss
4227
+ customCss,
4228
+ contextLabel: contextLabelProp
4162
4229
  }) {
4163
4230
  const effectiveGetIdentityToken = getIdentityToken || window.__crow_identity_token_fetcher;
4164
4231
  const effectiveOnToolResult = onToolResult || window.__crow_on_tool_result;
@@ -4175,7 +4242,9 @@ function CrowWidget({
4175
4242
  welcomeMessage: welcomeMessageFromAPI,
4176
4243
  selectedModel: selectedModelFromAPI,
4177
4244
  initialSuggestions,
4178
- toolConsentSettings
4245
+ toolConsentSettings,
4246
+ modelSelectionEnabled,
4247
+ availableModels: availableModelsFromAPI
4179
4248
  } = useWidgetStyles({
4180
4249
  productId,
4181
4250
  apiUrl,
@@ -4199,6 +4268,15 @@ function CrowWidget({
4199
4268
  window.addEventListener("crow:setGreeting", handler);
4200
4269
  return () => window.removeEventListener("crow:setGreeting", handler);
4201
4270
  }, []);
4271
+ const [contextLabelFromAPI, setContextLabelFromAPI] = React3.useState(
4272
+ () => window.__crow_context_label
4273
+ );
4274
+ React3.useEffect(() => {
4275
+ const handler = (e) => setContextLabelFromAPI(e.detail || void 0);
4276
+ window.addEventListener("crow:setContextLabel", handler);
4277
+ return () => window.removeEventListener("crow:setContextLabel", handler);
4278
+ }, []);
4279
+ const contextLabel = contextLabelProp ?? contextLabelFromAPI;
4202
4280
  const agentName = agentNameProp ?? agentNameFromAPI;
4203
4281
  const welcomeMessage = greetingOverride ?? welcomeMessageProp ?? welcomeMessageFromAPI;
4204
4282
  const selectedModel = selectedModelFromAPI;
@@ -4689,7 +4767,8 @@ function CrowWidget({
4689
4767
  onDragPointerDown: variant === "floating" ? transform.onDragPointerDown : void 0,
4690
4768
  isDragging: transform.isDragging,
4691
4769
  hasCustomTransform: transform.hasCustomTransform,
4692
- onResetTransform: transform.resetTransform
4770
+ onResetTransform: transform.resetTransform,
4771
+ contextLabel
4693
4772
  }
4694
4773
  ),
4695
4774
  /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: showConversationList && isVerifiedUser && /* @__PURE__ */ jsxRuntime.jsx(
@@ -4762,7 +4841,10 @@ function CrowWidget({
4762
4841
  showStopButton: isBrowserUseActive || !!askUserResolver || !!pendingConfirmation,
4763
4842
  highlighted: !!askUserResolver,
4764
4843
  className: "crow-backdrop-blur-md",
4765
- backendUrl: apiUrl
4844
+ backendUrl: apiUrl,
4845
+ selectedModel: chat.selectedModel || selectedModelFromAPI,
4846
+ onModelChange: chat.setSelectedModel,
4847
+ availableModels: modelSelectionEnabled ? availableModelsFromAPI : []
4766
4848
  }
4767
4849
  )
4768
4850
  ] })
@@ -5081,7 +5163,8 @@ function CrowCopilot({
5081
5163
  toolRenderers,
5082
5164
  getIdentityToken,
5083
5165
  context,
5084
- language
5166
+ language,
5167
+ contextLabel: contextLabelProp
5085
5168
  }) {
5086
5169
  const effectiveGetIdentityToken = getIdentityToken || window.__crow_identity_token_fetcher;
5087
5170
  const effectiveOnToolResult = onToolResult || window.__crow_on_tool_result;
@@ -5096,7 +5179,9 @@ function CrowCopilot({
5096
5179
  persistAnonymousConversations,
5097
5180
  welcomeMessage: welcomeMessageFromAPI,
5098
5181
  selectedModel,
5099
- toolConsentSettings
5182
+ toolConsentSettings,
5183
+ modelSelectionEnabled,
5184
+ availableModels: availableModelsFromAPI
5100
5185
  } = useCopilotStyles({
5101
5186
  productId,
5102
5187
  apiUrl,
@@ -5122,6 +5207,15 @@ function CrowCopilot({
5122
5207
  return () => window.removeEventListener("crow:setGreeting", handler);
5123
5208
  }, []);
5124
5209
  const welcomeMessage = greetingOverride ?? welcomeMessageProp ?? welcomeMessageFromAPI;
5210
+ const [contextLabelFromAPI, setContextLabelFromAPI] = React3.useState(
5211
+ () => window.__crow_context_label
5212
+ );
5213
+ React3.useEffect(() => {
5214
+ const handler = (e) => setContextLabelFromAPI(e.detail || void 0);
5215
+ window.addEventListener("crow:setContextLabel", handler);
5216
+ return () => window.removeEventListener("crow:setContextLabel", handler);
5217
+ }, []);
5218
+ const contextLabel = contextLabelProp ?? contextLabelFromAPI;
5125
5219
  const [autoTools, setAutoTools] = React3.useState({});
5126
5220
  const browserUseLoaded = autoTools.browser_use;
5127
5221
  React3.useEffect(() => {
@@ -5936,6 +6030,38 @@ function CrowCopilot({
5936
6030
  ]
5937
6031
  }
5938
6032
  ),
6033
+ contextLabel && /* @__PURE__ */ jsxRuntime.jsxs(
6034
+ "div",
6035
+ {
6036
+ className: "crow-flex crow-items-center crow-gap-1.5 crow-px-3 crow-py-1.5 crow-border-b crow-text-xs",
6037
+ style: {
6038
+ color: "#6b7280",
6039
+ borderColor: styles.colors.border
6040
+ },
6041
+ children: [
6042
+ /* @__PURE__ */ jsxRuntime.jsxs(
6043
+ "svg",
6044
+ {
6045
+ xmlns: "http://www.w3.org/2000/svg",
6046
+ width: "12",
6047
+ height: "12",
6048
+ viewBox: "0 0 24 24",
6049
+ fill: "none",
6050
+ stroke: "currentColor",
6051
+ strokeWidth: "2",
6052
+ strokeLinecap: "round",
6053
+ strokeLinejoin: "round",
6054
+ className: "crow-shrink-0",
6055
+ children: [
6056
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0Z" }),
6057
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "12", cy: "10", r: "3" })
6058
+ ]
6059
+ }
6060
+ ),
6061
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "crow-truncate", children: contextLabel })
6062
+ ]
6063
+ }
6064
+ ),
5939
6065
  /* @__PURE__ */ jsxRuntime.jsxs(framerMotion.AnimatePresence, { children: [
5940
6066
  showConversationList && isVerifiedUser && /* @__PURE__ */ jsxRuntime.jsx(
5941
6067
  ConversationList,
@@ -6020,7 +6146,10 @@ function CrowCopilot({
6020
6146
  onSend: handleSend,
6021
6147
  onStop: handleStop,
6022
6148
  placeholder: "Ask anything...",
6023
- isLoading: chat.isLoading
6149
+ isLoading: chat.isLoading,
6150
+ selectedModel: chat.selectedModel || selectedModel,
6151
+ onModelChange: chat.setSelectedModel,
6152
+ availableModels: modelSelectionEnabled ? availableModelsFromAPI : []
6024
6153
  }
6025
6154
  )
6026
6155
  ]