@ensembleapp/client-sdk 0.0.38 → 0.0.39

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
@@ -33,6 +33,40 @@ styleInject(':root[data-chat-widget],\n[data-chat-widget] {\n --chat-primary: #
33
33
  import { Send, StopCircle } from "lucide-react";
34
34
  import { forwardRef, useCallback as useCallback6, useEffect as useEffect6, useImperativeHandle, useMemo as useMemo5, useRef as useRef5, useState as useState7 } from "react";
35
35
 
36
+ // lib/api/invokeTool.ts
37
+ function createInvokeTool(api, onAuthError) {
38
+ return async (toolId, request = {}) => {
39
+ const { baseUrl, headers: customHeaders = {} } = api;
40
+ const doFetch = (token) => fetch(`${baseUrl}/api/tools/${toolId}/invoke`, {
41
+ method: "POST",
42
+ headers: {
43
+ "Content-Type": "application/json",
44
+ Authorization: `Bearer ${token}`,
45
+ ...customHeaders
46
+ },
47
+ body: JSON.stringify(request)
48
+ });
49
+ let response = await doFetch(api.token);
50
+ if (response.status === 401 && onAuthError) {
51
+ const newToken = await onAuthError();
52
+ if (newToken) {
53
+ response = await doFetch(newToken);
54
+ }
55
+ }
56
+ if (!response.ok) {
57
+ return {
58
+ success: false,
59
+ error: {
60
+ message: `HTTP ${response.status}`,
61
+ details: [await response.text().catch(() => response.statusText)],
62
+ code: "HTTP_ERROR"
63
+ }
64
+ };
65
+ }
66
+ return response.json();
67
+ };
68
+ }
69
+
36
70
  // ../../node_modules/.pnpm/@ai-sdk+provider@3.0.8/node_modules/@ai-sdk/provider/dist/index.mjs
37
71
  var marker = "vercel.ai.error";
38
72
  var symbol = Symbol.for(marker);
@@ -25982,7 +26016,7 @@ function renderError(container, message) {
25982
26016
  errorDiv.textContent = message;
25983
26017
  container.appendChild(errorDiv);
25984
26018
  }
25985
- function WidgetRenderer({ widget, payload, enriched, messageContext }) {
26019
+ function WidgetRenderer({ widget, payload, enriched, messageContext, invokeTool }) {
25986
26020
  const containerRef = useRef4(null);
25987
26021
  const rootRef = useRef4(null);
25988
26022
  const customerReactDOMRef = useRef4(void 0);
@@ -26019,7 +26053,7 @@ function WidgetRenderer({ widget, payload, enriched, messageContext }) {
26019
26053
  }
26020
26054
  let element;
26021
26055
  try {
26022
- element = widget.render(payload, enriched, { messageContext });
26056
+ element = widget.render(payload, enriched, { messageContext, invokeTool });
26023
26057
  } catch (error48) {
26024
26058
  console.error(`Widget "${widget.widgetType}" render function threw:`, error48);
26025
26059
  renderError(containerRef.current, `Widget render error: ${widget.widgetType}`);
@@ -26080,10 +26114,10 @@ To fix, add your ReactDOM to the widget config:
26080
26114
  renderError(containerRef.current, `Widget system error: ${widget.widgetType}`);
26081
26115
  }
26082
26116
  }
26083
- }, [isSdk, widget, payload, enriched, payloadHash, enrichedHash, messageContext]);
26117
+ }, [isSdk, widget, payload, enriched, payloadHash, enrichedHash, messageContext, invokeTool]);
26084
26118
  if (isSdk) {
26085
26119
  try {
26086
- const element = widget.render(payload, enriched, { messageContext });
26120
+ const element = widget.render(payload, enriched, { messageContext, invokeTool });
26087
26121
  return /* @__PURE__ */ jsx7(Fragment3, { children: element });
26088
26122
  } catch (error48) {
26089
26123
  console.error(`SDK widget "${widget.widgetType}" render threw:`, error48);
@@ -26111,7 +26145,8 @@ function MessageRenderer({
26111
26145
  displayMode = "brief",
26112
26146
  tagExpansion,
26113
26147
  className,
26114
- feedback
26148
+ feedback,
26149
+ invokeTool
26115
26150
  }) {
26116
26151
  const messageContext = useMemo4(() => {
26117
26152
  if (!feedback) return void 0;
@@ -26169,7 +26204,8 @@ function MessageRenderer({
26169
26204
  widget: widgetDef,
26170
26205
  payload: widget.payload,
26171
26206
  enriched: widget.enriched ?? {},
26172
- messageContext: messageContext ?? void 0
26207
+ messageContext: messageContext ?? void 0,
26208
+ invokeTool
26173
26209
  }
26174
26210
  )
26175
26211
  },
@@ -26372,6 +26408,10 @@ var ChatWidget = forwardRef(function ChatWidget2({
26372
26408
  agentId,
26373
26409
  agentVersion
26374
26410
  });
26411
+ const invokeTool = useMemo5(
26412
+ () => createInvokeTool(api, onAuthError),
26413
+ [api, onAuthError]
26414
+ );
26375
26415
  const [tagExpansionState, setTagExpansionState] = useState7(/* @__PURE__ */ new Map());
26376
26416
  const handleTagToggle = useCallback6((messageId, tagId, currentlyExpanded) => {
26377
26417
  suppressScrollRef.current = true;
@@ -26553,7 +26593,8 @@ var ChatWidget = forwardRef(function ChatWidget2({
26553
26593
  requireCommentForNegative: feedback?.requireCommentForNegative,
26554
26594
  getFeedback: () => getFeedback(message.id),
26555
26595
  submitFeedback: (params) => submitFeedback(message.id, params)
26556
- } : void 0
26596
+ } : void 0,
26597
+ invokeTool
26557
26598
  }
26558
26599
  )
26559
26600
  }
@@ -26727,60 +26768,41 @@ function PopupChatWidget({ anchor, ...props }) {
26727
26768
  ] });
26728
26769
  }
26729
26770
 
26730
- // lib/chat/widgets/VendorCards.tsx
26771
+ // lib/chat/widgets/HybridVendorCards.tsx
26731
26772
  import { MessageSquare as MessageSquare3, MessageSquareText as MessageSquareText2, ThumbsDown as ThumbsDown2, ThumbsUp as ThumbsUp2 } from "lucide-react";
26732
- import React8 from "react";
26773
+ import { useEffect as useEffect8, useMemo as useMemo7, useRef as useRef6, useState as useState9 } from "react";
26733
26774
  import { Fragment as Fragment5, jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
26734
- var vendorCardsSchema = jsonSchema({
26735
- type: "object",
26736
- description: "displaying a list of vendor cards. Use this widget to represent data from CareNetwork vendor search tool.",
26737
- properties: {
26738
- // fromLocation: {
26739
- // type: 'string',
26740
- // description: 'The location the user is searching for',
26741
- // },
26742
- // fromCoordinates: {
26743
- // type: 'object',
26744
- // description: "The location's lat/lng coordinates. This must come from the previous geocoding tool as-is - do NOT guess",
26745
- // properties: {
26746
- // latitude: { type: 'number' },
26747
- // longitude: { type: 'number' },
26748
- // },
26749
- // required: ['latitude', 'longitude'],
26750
- // },
26751
- vendors: {
26752
- type: "array",
26753
- items: {
26754
- type: "object",
26755
- properties: {
26756
- vendor_id: { type: "string" }
26757
- // notes: {
26758
- // type: 'string',
26759
- // description: 'Give 7-10 words on why this vendor was recommended. Only include the notes for the top 3 vendors',
26760
- // },
26761
- // vendorCoordinates: {
26762
- // type: 'object',
26763
- // description: "The lat/lng coordinates of this vendor. This must come from the vendor's location.coordinates from the previous vendor search tool - do NOT guess",
26764
- // properties: {
26765
- // latitude: { type: 'number' },
26766
- // longitude: { type: 'number' },
26767
- // },
26768
- // required: ['latitude', 'longitude'],
26769
- // },
26770
- },
26771
- required: ["vendor_id"]
26772
- // required: ['vendor_id', 'vendorCoordinates'],
26773
- }
26774
- // description: '5-7 vendors to display. With notes for the top 3 only',
26775
- }
26776
- },
26777
- required: ["vendors"]
26778
- // required: ['fromLocation', 'fromCoordinates', 'vendors'],
26779
- });
26780
- function VendorCards({ payload, enriched, onAddToList, onFeedback, existingFeedback }) {
26781
- const [feedbackState, setFeedbackState] = React8.useState({});
26782
- const initializedRef = React8.useRef(false);
26783
- React8.useEffect(() => {
26775
+ var vendorCardsHybridSchema = zod_default.object({
26776
+ fromLocation: zod_default.string().describe("The location the user is searching from"),
26777
+ fromCoordinates: zod_default.object({
26778
+ latitude: zod_default.number(),
26779
+ longitude: zod_default.number()
26780
+ }).describe("The user's lat/lng coordinates from geocoding"),
26781
+ vendors: zod_default.array(zod_default.object({
26782
+ vendor_id: zod_default.string(),
26783
+ notes: zod_default.string().optional().describe("7-10 words on why this vendor was recommended. Be brief and concise - do not include unecessary details such as vendor names.")
26784
+ }))
26785
+ }).describe("Display vendor cards. Only vendor IDs needed - details enriched server-side, distances fetched client-side.");
26786
+ function HybridVendorCards({
26787
+ payload,
26788
+ serverEnriched,
26789
+ distanceMatrixToolId,
26790
+ invokeTool,
26791
+ messageContext
26792
+ }) {
26793
+ const [distanceMatrix, setDistanceMatrix] = useState9();
26794
+ const [loadingDistance, setLoadingDistance] = useState9(true);
26795
+ const [feedbackState, setFeedbackState] = useState9({});
26796
+ const hasFetchedRef = useRef6(false);
26797
+ const initializedRef = useRef6(false);
26798
+ const vendorIds = useMemo7(
26799
+ () => payload.vendors.map((v) => v.vendor_id).join(","),
26800
+ [payload.vendors]
26801
+ );
26802
+ const originKey = `${payload.fromCoordinates.latitude},${payload.fromCoordinates.longitude}`;
26803
+ const hasVendorDetails = serverEnriched.vendorDetails?.success ?? false;
26804
+ const existingFeedback = messageContext?.getFeedback?.()?.notes;
26805
+ useEffect8(() => {
26784
26806
  if (!initializedRef.current && existingFeedback && existingFeedback.length > 0) {
26785
26807
  initializedRef.current = true;
26786
26808
  const initialState = {};
@@ -26796,6 +26818,44 @@ function VendorCards({ payload, enriched, onAddToList, onFeedback, existingFeedb
26796
26818
  setFeedbackState(initialState);
26797
26819
  }
26798
26820
  }, [existingFeedback]);
26821
+ useEffect8(() => {
26822
+ if (hasFetchedRef.current) {
26823
+ return;
26824
+ }
26825
+ if (!invokeTool || !hasVendorDetails) {
26826
+ setLoadingDistance(false);
26827
+ return;
26828
+ }
26829
+ const fetchDistance = async () => {
26830
+ hasFetchedRef.current = true;
26831
+ try {
26832
+ const vendorDetails = serverEnriched.vendorDetails?.data;
26833
+ const destinations = payload.vendors.map((v) => {
26834
+ const detail = vendorDetails?.[v.vendor_id];
26835
+ return detail?.location?.coordinates ?? null;
26836
+ }).filter(Boolean);
26837
+ if (destinations.length === 0) {
26838
+ setLoadingDistance(false);
26839
+ return;
26840
+ }
26841
+ const distanceResult = await invokeTool(distanceMatrixToolId, {
26842
+ args: {
26843
+ origin: payload.fromCoordinates,
26844
+ destinations
26845
+ }
26846
+ });
26847
+ setDistanceMatrix(
26848
+ distanceResult.success ? { success: true, data: distanceResult.data } : { success: false }
26849
+ );
26850
+ } catch (error48) {
26851
+ console.warn("[HybridVendorCards] Distance fetch failed:", error48);
26852
+ setDistanceMatrix({ success: false });
26853
+ } finally {
26854
+ setLoadingDistance(false);
26855
+ }
26856
+ };
26857
+ fetchDistance();
26858
+ }, [invokeTool, vendorIds, originKey, hasVendorDetails, distanceMatrixToolId, payload, serverEnriched]);
26799
26859
  const getFeedbackState = (vendorId) => {
26800
26860
  return feedbackState[vendorId] || { rating: null, commentText: null, showComment: false };
26801
26861
  };
@@ -26807,51 +26867,62 @@ function VendorCards({ payload, enriched, onAddToList, onFeedback, existingFeedb
26807
26867
  };
26808
26868
  const removeFeedbackState = (vendorId) => {
26809
26869
  setFeedbackState((prev) => {
26810
- const { [vendorId]: _, ...rest } = prev;
26870
+ const { [vendorId]: _removed, ...rest } = prev;
26871
+ void _removed;
26811
26872
  return rest;
26812
26873
  });
26813
26874
  };
26814
- const { vendorDetails, distanceMatrix } = enriched || {};
26815
- const vendorData = vendorDetails?.data ?? {};
26816
- const distances = distanceMatrix?.data ?? [];
26875
+ const handleFeedback = (noteId, feedbackPayload) => {
26876
+ messageContext?.submitFeedback?.({
26877
+ notes: [{
26878
+ noteId,
26879
+ ...feedbackPayload
26880
+ }]
26881
+ });
26882
+ };
26817
26883
  const formatDistance = (meters) => {
26818
26884
  const miles = meters / 1609.34;
26819
26885
  return miles < 0.1 ? "< 0.1 mi" : `${miles.toFixed(1)} mi`;
26820
26886
  };
26821
- return /* @__PURE__ */ jsx11("div", { style: { display: "flex", flexDirection: "column", gap: "0.75rem" }, children: payload.vendors.map((v, index) => {
26822
- const data = vendorData[v.vendor_id];
26823
- const name21 = data?.names?.[0]?.value ?? "Unknown";
26824
- const address = data?.location?.address;
26825
- const distanceEntry = distances.find((d) => d.destinationIndex === index);
26826
- const distance = distanceEntry && distanceEntry.distanceMeters ? formatDistance(distanceEntry.distanceMeters) : void 0;
26827
- const hourlyRate = data?.financials?.fees?.find((f) => f.fee_type?.includes("Hourly"))?.amount;
26828
- const avgRating = data?.avg_rating;
26829
- const reviewCount = data?.review_count;
26830
- const booleans = data?.booleans;
26831
- const verification = data?.verification;
26832
- const cnScore = data?.quality_scores?.completeness_score;
26833
- const subtypes = data?.subtype ?? [];
26834
- const careLocationType = subtypes.includes("In-Home") ? "In-Home" : subtypes.includes("In-Center") ? "In-Center" : null;
26835
- const backgroundCheckStatus = data?.references_and_background_check?.background_check_status?.toLowerCase();
26836
- const hasBackgroundCheck = backgroundCheckStatus === "clear" || backgroundCheckStatus === "completed";
26837
- return /* @__PURE__ */ jsxs10(
26838
- "div",
26839
- {
26840
- style: {
26841
- display: "flex",
26842
- flexDirection: "column",
26843
- gap: "0.2rem",
26844
- padding: "1rem",
26845
- background: "#ffffff",
26846
- border: "1px solid #e5e7eb",
26847
- borderRadius: "0.5rem",
26848
- boxShadow: "0 1px 3px 0 rgba(0, 0, 0, 0.1)",
26849
- fontSize: "0.875rem",
26850
- position: "relative"
26851
- },
26852
- children: [
26853
- /* @__PURE__ */ jsxs10("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "flex-start" }, children: [
26854
- /* @__PURE__ */ jsxs10("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
26887
+ if (!serverEnriched || !serverEnriched.vendorDetails) {
26888
+ return /* @__PURE__ */ jsx11("div", { children: "Loading vendor details..." });
26889
+ }
26890
+ const vendorData = serverEnriched.vendorDetails?.data ?? {};
26891
+ const distances = distanceMatrix?.data ?? [];
26892
+ return /* @__PURE__ */ jsxs10("div", { style: { display: "flex", flexDirection: "column", gap: "0.75rem" }, children: [
26893
+ loadingDistance && /* @__PURE__ */ jsx11("style", { children: `@keyframes hybrid-vendor-cards-shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }` }),
26894
+ payload.vendors.map((v, index) => {
26895
+ const data = vendorData[v.vendor_id];
26896
+ const name21 = data?.names?.[0]?.value ?? "Unknown";
26897
+ const address = data?.location?.address;
26898
+ const distanceEntry = distances.find((d) => d.destinationIndex === index);
26899
+ const distance = distanceEntry && distanceEntry.distanceMeters ? formatDistance(distanceEntry.distanceMeters) : void 0;
26900
+ const hourlyRate = data?.financials?.fees?.find((f) => f.fee_type?.includes("Hourly"))?.amount;
26901
+ const avgRating = data?.avg_rating;
26902
+ const reviewCount = data?.review_count;
26903
+ const verification = data?.verification;
26904
+ const cnScore = data?.quality_scores?.completeness_score;
26905
+ const subtypes = data?.subtype ?? [];
26906
+ const careLocationType = subtypes.includes("In-Home") ? "In-Home" : subtypes.includes("In-Center") ? "In-Center" : null;
26907
+ const backgroundCheckStatus = data?.references_and_background_check?.background_check_status?.toLowerCase();
26908
+ const hasBackgroundCheck = backgroundCheckStatus === "clear" || backgroundCheckStatus === "completed";
26909
+ return /* @__PURE__ */ jsxs10(
26910
+ "div",
26911
+ {
26912
+ style: {
26913
+ display: "flex",
26914
+ flexDirection: "column",
26915
+ gap: "0.2rem",
26916
+ padding: "1rem",
26917
+ background: "#ffffff",
26918
+ border: "1px solid #e5e7eb",
26919
+ borderRadius: "0.5rem",
26920
+ boxShadow: "0 1px 3px 0 rgba(0, 0, 0, 0.1)",
26921
+ fontSize: "0.875rem",
26922
+ position: "relative"
26923
+ },
26924
+ children: [
26925
+ /* @__PURE__ */ jsx11("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "flex-start" }, children: /* @__PURE__ */ jsxs10("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
26855
26926
  /* @__PURE__ */ jsx11("div", { style: {
26856
26927
  width: "2rem",
26857
26928
  height: "2rem",
@@ -26865,162 +26936,110 @@ function VendorCards({ payload, enriched, onAddToList, onFeedback, existingFeedb
26865
26936
  color: "#374151"
26866
26937
  }, children: name21.charAt(0).toUpperCase() }),
26867
26938
  /* @__PURE__ */ jsx11("span", { style: { fontWeight: 600, fontSize: "1rem", color: "#111827" }, children: name21 })
26939
+ ] }) }),
26940
+ (reviewCount != null || cnScore != null) && /* @__PURE__ */ jsxs10("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem", color: "#6b7280" }, children: [
26941
+ avgRating != null && /* @__PURE__ */ jsxs10(Fragment5, { children: [
26942
+ /* @__PURE__ */ jsx11("span", { style: { color: "#facc15" }, children: "\u2605" }),
26943
+ /* @__PURE__ */ jsx11("span", { children: avgRating.toFixed(1) }),
26944
+ reviewCount != null && /* @__PURE__ */ jsxs10("span", { style: { color: "#9ca3af" }, children: [
26945
+ "(",
26946
+ reviewCount,
26947
+ " reviews)"
26948
+ ] })
26949
+ ] }),
26950
+ avgRating != null && cnScore != null ? /* @__PURE__ */ jsx11("span", { style: { color: "#9ca3af" }, children: "\u2022" }) : null,
26951
+ cnScore != null ? /* @__PURE__ */ jsxs10("span", { children: [
26952
+ "CN Score: ",
26953
+ cnScore
26954
+ ] }) : null
26868
26955
  ] }),
26869
- onAddToList && /* @__PURE__ */ jsx11(
26870
- "button",
26871
- {
26872
- onClick: () => onAddToList(v.vendor_id),
26873
- style: {
26874
- background: "none",
26875
- border: "none",
26876
- color: "#3b82f6",
26877
- fontSize: "0.875rem",
26878
- cursor: "pointer",
26879
- padding: 0
26880
- },
26881
- children: "Add to list"
26882
- }
26883
- )
26884
- ] }),
26885
- (reviewCount != null || cnScore != null) && /* @__PURE__ */ jsxs10("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem", color: "#6b7280" }, children: [
26886
- avgRating != null && /* @__PURE__ */ jsxs10(Fragment5, { children: [
26887
- /* @__PURE__ */ jsx11("span", { style: { color: "#facc15" }, children: "\u2605" }),
26888
- /* @__PURE__ */ jsx11("span", { children: avgRating.toFixed(1) }),
26889
- reviewCount != null && /* @__PURE__ */ jsxs10("span", { style: { color: "#9ca3af" }, children: [
26890
- "(",
26891
- reviewCount,
26892
- " reviews)"
26956
+ careLocationType && /* @__PURE__ */ jsx11("div", { style: { color: "#6b7280" }, children: careLocationType }),
26957
+ address && /* @__PURE__ */ jsx11("div", { style: { color: "#6b7280" }, children: address }),
26958
+ /* @__PURE__ */ jsx11("div", { style: { display: "flex", alignItems: "center", gap: "0.25rem", color: "#6b7280", minHeight: "1.25rem" }, children: loadingDistance ? /* @__PURE__ */ jsxs10(Fragment5, { children: [
26959
+ /* @__PURE__ */ jsx11("span", { children: "\u{1F4CD}" }),
26960
+ /* @__PURE__ */ jsx11("span", { style: {
26961
+ width: "100px",
26962
+ height: "0.875rem",
26963
+ background: "linear-gradient(90deg, #f3f4f6 25%, #e5e7eb 50%, #f3f4f6 75%)",
26964
+ backgroundSize: "200% 100%",
26965
+ animation: "hybrid-vendor-cards-shimmer 1.5s infinite",
26966
+ borderRadius: "0.25rem"
26967
+ } })
26968
+ ] }) : distance ? /* @__PURE__ */ jsxs10(Fragment5, { children: [
26969
+ /* @__PURE__ */ jsx11("span", { children: "\u{1F4CD}" }),
26970
+ /* @__PURE__ */ jsxs10("span", { children: [
26971
+ distance,
26972
+ " from ",
26973
+ payload.fromLocation
26974
+ ] })
26975
+ ] }) : null }),
26976
+ hourlyRate && /* @__PURE__ */ jsxs10("div", { style: { display: "flex", alignItems: "center", gap: "0.25rem", color: "#6b7280" }, children: [
26977
+ /* @__PURE__ */ jsx11("span", { children: "\u{1F4B0}" }),
26978
+ /* @__PURE__ */ jsxs10("span", { children: [
26979
+ "Rate: $",
26980
+ hourlyRate,
26981
+ "/hr"
26893
26982
  ] })
26894
26983
  ] }),
26895
- avgRating != null && cnScore != null ? /* @__PURE__ */ jsx11("span", { style: { color: "#9ca3af" }, children: "\u2022" }) : null,
26896
- cnScore != null ? /* @__PURE__ */ jsxs10("span", { children: [
26897
- "CN Score: ",
26898
- cnScore
26899
- ] }) : null
26900
- ] }),
26901
- careLocationType && /* @__PURE__ */ jsx11("div", { style: { color: "#6b7280" }, children: careLocationType }),
26902
- address && /* @__PURE__ */ jsx11("div", { style: { color: "#6b7280" }, children: address }),
26903
- distance && /* @__PURE__ */ jsxs10("div", { style: { display: "flex", alignItems: "center", gap: "0.25rem", color: "#6b7280" }, children: [
26904
- /* @__PURE__ */ jsx11("span", { children: "\u{1F4CD}" }),
26905
- /* @__PURE__ */ jsxs10("span", { children: [
26906
- distance,
26907
- " from ",
26908
- payload.fromLocation
26909
- ] })
26910
- ] }),
26911
- hourlyRate && /* @__PURE__ */ jsxs10("div", { style: { display: "flex", alignItems: "center", gap: "0.25rem", color: "#6b7280" }, children: [
26912
- /* @__PURE__ */ jsx11("span", { children: "\u{1F4B0}" }),
26913
- /* @__PURE__ */ jsxs10("span", { children: [
26914
- "Rate: $",
26915
- hourlyRate,
26916
- "/hr"
26917
- ] })
26918
- ] }),
26919
- v.notes && /* @__PURE__ */ jsxs10("div", { style: { color: "#374151", marginTop: "0.4rem" }, children: [
26920
- /* @__PURE__ */ jsx11("span", { style: { marginRight: "0.25rem" }, children: "\u2728" }),
26921
- /* @__PURE__ */ jsx11("strong", { children: "Recommendation notes" }),
26922
- /* @__PURE__ */ jsx11("div", { style: { marginLeft: "1.25rem", marginTop: "0.25rem", color: "#6b7280" }, children: v.notes })
26923
- ] }),
26924
- (() => {
26925
- const state = getFeedbackState(v.vendor_id);
26926
- const isPositiveSelected = state.rating === "positive";
26927
- const isNegativeSelected = state.rating === "negative";
26928
- const handleRatingClick = (rating) => {
26929
- const currentState = getFeedbackState(v.vendor_id);
26930
- if (currentState.rating === rating) {
26931
- removeFeedbackState(v.vendor_id);
26932
- onFeedback?.(v.vendor_id, {});
26933
- } else {
26934
- updateFeedbackState(v.vendor_id, { rating });
26935
- onFeedback?.(v.vendor_id, { rating, vendorId: v.vendor_id, vendorName: name21 });
26936
- }
26937
- };
26938
- const handleCommentToggle = () => {
26939
- const currentState = getFeedbackState(v.vendor_id);
26940
- updateFeedbackState(v.vendor_id, { showComment: !currentState.showComment });
26941
- };
26942
- const handleCommentSubmit = () => {
26943
- const currentState = getFeedbackState(v.vendor_id);
26944
- const trimmedComment = currentState.commentText?.trim();
26945
- if (trimmedComment) {
26946
- updateFeedbackState(v.vendor_id, { showComment: false, commentText: trimmedComment });
26947
- onFeedback?.(v.vendor_id, { comment: trimmedComment, vendorId: v.vendor_id, vendorName: name21 });
26948
- }
26949
- };
26950
- return /* @__PURE__ */ jsxs10(Fragment5, { children: [
26951
- /* @__PURE__ */ jsxs10("div", { style: {
26952
- display: "flex",
26953
- flexWrap: "wrap",
26954
- gap: "0.5rem",
26955
- // marginTop: '0.25rem',
26956
- alignItems: "center",
26957
- minHeight: "1.75rem"
26958
- }, children: [
26959
- verification?.verified && /* @__PURE__ */ jsxs10("span", { style: { display: "flex", alignItems: "center", gap: "0.25rem", color: "#22c55e", fontSize: "0.75rem" }, children: [
26960
- /* @__PURE__ */ jsx11("span", { style: { fontSize: "0.875rem" }, children: "\u2713" }),
26961
- " Wellthy Verified"
26962
- ] }),
26963
- hasBackgroundCheck && /* @__PURE__ */ jsxs10("span", { style: { display: "flex", alignItems: "center", gap: "0.25rem", color: "#22c55e", fontSize: "0.75rem" }, children: [
26964
- /* @__PURE__ */ jsx11("span", { style: { fontSize: "0.875rem" }, children: "\u2713" }),
26965
- " Background check"
26966
- ] }),
26967
- onFeedback && /* @__PURE__ */ jsxs10("div", { style: {
26968
- marginLeft: "auto",
26984
+ v.notes && /* @__PURE__ */ jsxs10("div", { style: { color: "#374151", marginTop: "0.4rem" }, children: [
26985
+ /* @__PURE__ */ jsx11("span", { style: { marginRight: "0.25rem" }, children: "\u2728" }),
26986
+ /* @__PURE__ */ jsx11("strong", { children: "Recommendation notes" }),
26987
+ /* @__PURE__ */ jsx11("div", { style: { marginLeft: "1.25rem", marginTop: "0.25rem", color: "#6b7280" }, children: v.notes })
26988
+ ] }),
26989
+ (() => {
26990
+ const state = getFeedbackState(v.vendor_id);
26991
+ const isPositiveSelected = state.rating === "positive";
26992
+ const isNegativeSelected = state.rating === "negative";
26993
+ const handleRatingClick = (rating) => {
26994
+ const currentState = getFeedbackState(v.vendor_id);
26995
+ if (currentState.rating === rating) {
26996
+ removeFeedbackState(v.vendor_id);
26997
+ handleFeedback(v.vendor_id, {});
26998
+ } else {
26999
+ updateFeedbackState(v.vendor_id, { rating });
27000
+ handleFeedback(v.vendor_id, { rating, vendorId: v.vendor_id, vendorName: name21 });
27001
+ }
27002
+ };
27003
+ const handleCommentToggle = () => {
27004
+ const currentState = getFeedbackState(v.vendor_id);
27005
+ updateFeedbackState(v.vendor_id, { showComment: !currentState.showComment });
27006
+ };
27007
+ const handleCommentSubmit = () => {
27008
+ const currentState = getFeedbackState(v.vendor_id);
27009
+ const trimmedComment = currentState.commentText?.trim();
27010
+ if (trimmedComment) {
27011
+ updateFeedbackState(v.vendor_id, { showComment: false, commentText: trimmedComment });
27012
+ handleFeedback(v.vendor_id, { comment: trimmedComment, vendorId: v.vendor_id, vendorName: name21 });
27013
+ }
27014
+ };
27015
+ return /* @__PURE__ */ jsxs10(Fragment5, { children: [
27016
+ /* @__PURE__ */ jsxs10("div", { style: {
26969
27017
  display: "flex",
26970
- gap: "0.25rem",
26971
- alignItems: "center"
27018
+ flexWrap: "wrap",
27019
+ gap: "0.5rem",
27020
+ alignItems: "center",
27021
+ minHeight: "1.75rem"
26972
27022
  }, children: [
26973
- /* @__PURE__ */ jsx11(
26974
- "button",
26975
- {
26976
- onClick: () => handleRatingClick("positive"),
26977
- style: {
26978
- background: isPositiveSelected ? "rgba(34, 197, 94, 0.1)" : "transparent",
26979
- border: "none",
26980
- borderRadius: "0.35rem",
26981
- padding: "0.25rem",
26982
- cursor: "pointer",
26983
- display: "flex",
26984
- alignItems: "center",
26985
- justifyContent: "center",
26986
- color: isPositiveSelected ? "#22c55e" : "#9ca3af",
26987
- width: "1.75rem",
26988
- height: "1.75rem"
26989
- },
26990
- title: "This vendor was helpful",
26991
- children: /* @__PURE__ */ jsx11(ThumbsUp2, { style: { width: "1rem", height: "1rem" } })
26992
- }
26993
- ),
26994
- /* @__PURE__ */ jsx11(
26995
- "button",
26996
- {
26997
- onClick: () => handleRatingClick("negative"),
26998
- style: {
26999
- background: isNegativeSelected ? "rgba(239, 68, 68, 0.1)" : "transparent",
27000
- border: "none",
27001
- borderRadius: "0.35rem",
27002
- padding: "0.25rem",
27003
- cursor: "pointer",
27004
- display: "flex",
27005
- alignItems: "center",
27006
- justifyContent: "center",
27007
- color: isNegativeSelected ? "#ef4444" : "#9ca3af",
27008
- width: "1.75rem",
27009
- height: "1.75rem"
27010
- },
27011
- title: "This vendor was not helpful",
27012
- children: /* @__PURE__ */ jsx11(ThumbsDown2, { style: { width: "1rem", height: "1rem" } })
27013
- }
27014
- ),
27015
- (() => {
27016
- const hasComment = !!state.commentText?.trim();
27017
- const CommentIcon = hasComment ? MessageSquareText2 : MessageSquare3;
27018
- return /* @__PURE__ */ jsx11(
27023
+ verification?.verified && /* @__PURE__ */ jsxs10("span", { style: { display: "flex", alignItems: "center", gap: "0.25rem", color: "#22c55e", fontSize: "0.75rem" }, children: [
27024
+ /* @__PURE__ */ jsx11("span", { style: { fontSize: "0.875rem" }, children: "\u2713" }),
27025
+ " Wellthy Verified"
27026
+ ] }),
27027
+ hasBackgroundCheck && /* @__PURE__ */ jsxs10("span", { style: { display: "flex", alignItems: "center", gap: "0.25rem", color: "#22c55e", fontSize: "0.75rem" }, children: [
27028
+ /* @__PURE__ */ jsx11("span", { style: { fontSize: "0.875rem" }, children: "\u2713" }),
27029
+ " Background check"
27030
+ ] }),
27031
+ messageContext && /* @__PURE__ */ jsxs10("div", { style: {
27032
+ marginLeft: "auto",
27033
+ display: "flex",
27034
+ gap: "0.25rem",
27035
+ alignItems: "center"
27036
+ }, children: [
27037
+ /* @__PURE__ */ jsx11(
27019
27038
  "button",
27020
27039
  {
27021
- onClick: handleCommentToggle,
27040
+ onClick: () => handleRatingClick("positive"),
27022
27041
  style: {
27023
- background: state.showComment ? "rgba(0, 0, 0, 0.05)" : "transparent",
27042
+ background: isPositiveSelected ? "rgba(34, 197, 94, 0.1)" : "transparent",
27024
27043
  border: "none",
27025
27044
  borderRadius: "0.35rem",
27026
27045
  padding: "0.25rem",
@@ -27028,96 +27047,190 @@ function VendorCards({ payload, enriched, onAddToList, onFeedback, existingFeedb
27028
27047
  display: "flex",
27029
27048
  alignItems: "center",
27030
27049
  justifyContent: "center",
27031
- color: hasComment ? "#3b82f6" : state.showComment ? "#6b7280" : "#9ca3af",
27050
+ color: isPositiveSelected ? "#22c55e" : "#9ca3af",
27032
27051
  width: "1.75rem",
27033
27052
  height: "1.75rem"
27034
27053
  },
27035
- title: hasComment ? "Edit comment" : "Add comment",
27036
- children: /* @__PURE__ */ jsx11(CommentIcon, { style: { width: "1rem", height: "1rem" } })
27054
+ title: "This vendor was helpful",
27055
+ children: /* @__PURE__ */ jsx11(ThumbsUp2, { style: { width: "1rem", height: "1rem" } })
27037
27056
  }
27038
- );
27039
- })()
27040
- ] })
27041
- ] }),
27042
- state.showComment && /* @__PURE__ */ jsx11("div", { style: {
27043
- position: "absolute",
27044
- bottom: 0,
27045
- left: 0,
27046
- right: 0,
27047
- background: "#ffffff",
27048
- borderTop: "1px solid #e5e7eb",
27049
- borderRadius: "0 0 0.5rem 0.5rem",
27050
- padding: "0.75rem 1rem",
27051
- boxShadow: "0 -2px 8px rgba(0, 0, 0, 0.1)"
27052
- }, children: /* @__PURE__ */ jsxs10("div", { style: { display: "flex", gap: "0.5rem", alignItems: "flex-start" }, children: [
27053
- /* @__PURE__ */ jsx11(
27054
- "textarea",
27055
- {
27056
- placeholder: "Share your thoughts about this vendor...",
27057
- value: state.commentText ?? "",
27058
- onChange: (e) => updateFeedbackState(v.vendor_id, { commentText: e.target.value }),
27059
- rows: 2,
27060
- style: {
27061
- flex: 1,
27062
- padding: "0.5rem",
27063
- border: "1px solid #e5e7eb",
27064
- borderRadius: "0.35rem",
27065
- fontSize: "0.875rem",
27066
- fontFamily: "inherit",
27067
- resize: "none",
27068
- minHeight: "50px"
27069
- }
27070
- }
27071
- ),
27072
- /* @__PURE__ */ jsxs10("div", { style: { display: "flex", flexDirection: "column", gap: "0.375rem" }, children: [
27057
+ ),
27058
+ /* @__PURE__ */ jsx11(
27059
+ "button",
27060
+ {
27061
+ onClick: () => handleRatingClick("negative"),
27062
+ style: {
27063
+ background: isNegativeSelected ? "rgba(239, 68, 68, 0.1)" : "transparent",
27064
+ border: "none",
27065
+ borderRadius: "0.35rem",
27066
+ padding: "0.25rem",
27067
+ cursor: "pointer",
27068
+ display: "flex",
27069
+ alignItems: "center",
27070
+ justifyContent: "center",
27071
+ color: isNegativeSelected ? "#ef4444" : "#9ca3af",
27072
+ width: "1.75rem",
27073
+ height: "1.75rem"
27074
+ },
27075
+ title: "This vendor was not helpful",
27076
+ children: /* @__PURE__ */ jsx11(ThumbsDown2, { style: { width: "1rem", height: "1rem" } })
27077
+ }
27078
+ ),
27079
+ (() => {
27080
+ const hasComment = !!state.commentText?.trim();
27081
+ const CommentIcon = hasComment ? MessageSquareText2 : MessageSquare3;
27082
+ return /* @__PURE__ */ jsx11(
27083
+ "button",
27084
+ {
27085
+ onClick: handleCommentToggle,
27086
+ style: {
27087
+ background: state.showComment ? "rgba(0, 0, 0, 0.05)" : "transparent",
27088
+ border: "none",
27089
+ borderRadius: "0.35rem",
27090
+ padding: "0.25rem",
27091
+ cursor: "pointer",
27092
+ display: "flex",
27093
+ alignItems: "center",
27094
+ justifyContent: "center",
27095
+ color: hasComment ? "#3b82f6" : state.showComment ? "#6b7280" : "#9ca3af",
27096
+ width: "1.75rem",
27097
+ height: "1.75rem"
27098
+ },
27099
+ title: hasComment ? "Edit comment" : "Add comment",
27100
+ children: /* @__PURE__ */ jsx11(CommentIcon, { style: { width: "1rem", height: "1rem" } })
27101
+ }
27102
+ );
27103
+ })()
27104
+ ] })
27105
+ ] }),
27106
+ state.showComment && /* @__PURE__ */ jsx11("div", { style: {
27107
+ position: "absolute",
27108
+ bottom: 0,
27109
+ left: 0,
27110
+ right: 0,
27111
+ background: "#ffffff",
27112
+ borderTop: "1px solid #e5e7eb",
27113
+ borderRadius: "0 0 0.5rem 0.5rem",
27114
+ padding: "0.75rem 1rem",
27115
+ boxShadow: "0 -2px 8px rgba(0, 0, 0, 0.1)"
27116
+ }, children: /* @__PURE__ */ jsxs10("div", { style: { display: "flex", gap: "0.5rem", alignItems: "flex-start" }, children: [
27073
27117
  /* @__PURE__ */ jsx11(
27074
- "button",
27118
+ "textarea",
27075
27119
  {
27076
- onClick: handleCommentSubmit,
27077
- disabled: !state.commentText?.trim(),
27120
+ placeholder: "Share your thoughts about this vendor...",
27121
+ value: state.commentText ?? "",
27122
+ onChange: (e) => updateFeedbackState(v.vendor_id, { commentText: e.target.value }),
27123
+ rows: 2,
27078
27124
  style: {
27079
- padding: "0.35rem 0.75rem",
27080
- fontSize: "0.75rem",
27081
- fontWeight: 500,
27082
- borderRadius: "0.3rem",
27083
- cursor: state.commentText?.trim() ? "pointer" : "not-allowed",
27084
- background: "#3b82f6",
27085
- border: "none",
27086
- color: "#ffffff",
27087
- opacity: state.commentText?.trim() ? 1 : 0.5
27088
- },
27089
- children: "Save"
27125
+ flex: 1,
27126
+ padding: "0.5rem",
27127
+ border: "1px solid #e5e7eb",
27128
+ borderRadius: "0.35rem",
27129
+ fontSize: "0.875rem",
27130
+ fontFamily: "inherit",
27131
+ resize: "none",
27132
+ minHeight: "50px"
27133
+ }
27090
27134
  }
27091
27135
  ),
27092
- /* @__PURE__ */ jsx11(
27093
- "button",
27094
- {
27095
- onClick: handleCommentToggle,
27096
- style: {
27097
- padding: "0.25rem 0.5rem",
27098
- fontSize: "0.75rem",
27099
- fontWeight: 500,
27100
- background: "transparent",
27101
- border: "none",
27102
- color: "#9ca3af",
27103
- cursor: "pointer"
27104
- },
27105
- children: "Cancel"
27106
- }
27107
- )
27108
- ] })
27109
- ] }) })
27110
- ] });
27111
- })()
27112
- ]
27113
- },
27114
- v.vendor_id
27115
- );
27116
- }) });
27136
+ /* @__PURE__ */ jsxs10("div", { style: { display: "flex", flexDirection: "column", gap: "0.375rem" }, children: [
27137
+ /* @__PURE__ */ jsx11(
27138
+ "button",
27139
+ {
27140
+ onClick: handleCommentSubmit,
27141
+ disabled: !state.commentText?.trim(),
27142
+ style: {
27143
+ padding: "0.35rem 0.75rem",
27144
+ fontSize: "0.75rem",
27145
+ fontWeight: 500,
27146
+ borderRadius: "0.3rem",
27147
+ cursor: state.commentText?.trim() ? "pointer" : "not-allowed",
27148
+ background: "#3b82f6",
27149
+ border: "none",
27150
+ color: "#ffffff",
27151
+ opacity: state.commentText?.trim() ? 1 : 0.5
27152
+ },
27153
+ children: "Save"
27154
+ }
27155
+ ),
27156
+ /* @__PURE__ */ jsx11(
27157
+ "button",
27158
+ {
27159
+ onClick: handleCommentToggle,
27160
+ style: {
27161
+ padding: "0.25rem 0.5rem",
27162
+ fontSize: "0.75rem",
27163
+ fontWeight: 500,
27164
+ background: "transparent",
27165
+ border: "none",
27166
+ color: "#9ca3af",
27167
+ cursor: "pointer"
27168
+ },
27169
+ children: "Cancel"
27170
+ }
27171
+ )
27172
+ ] })
27173
+ ] }) })
27174
+ ] });
27175
+ })()
27176
+ ]
27177
+ },
27178
+ v.vendor_id
27179
+ );
27180
+ })
27181
+ ] });
27117
27182
  }
27118
27183
 
27184
+ // lib/chat/widgets/VendorCards.tsx
27185
+ import { MessageSquare as MessageSquare4, MessageSquareText as MessageSquareText3, ThumbsDown as ThumbsDown3, ThumbsUp as ThumbsUp3 } from "lucide-react";
27186
+ import React9 from "react";
27187
+ import { Fragment as Fragment6, jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
27188
+ var vendorCardsSchema = jsonSchema({
27189
+ type: "object",
27190
+ description: "displaying a list of vendor cards. Use this widget to represent data from CareNetwork vendor search tool.",
27191
+ properties: {
27192
+ fromLocation: {
27193
+ type: "string",
27194
+ description: "The location the user is searching for"
27195
+ },
27196
+ fromCoordinates: {
27197
+ type: "object",
27198
+ description: "The location's lat/lng coordinates. This must come from the previous geocoding tool as-is - do NOT guess",
27199
+ properties: {
27200
+ latitude: { type: "number" },
27201
+ longitude: { type: "number" }
27202
+ },
27203
+ required: ["latitude", "longitude"]
27204
+ },
27205
+ vendors: {
27206
+ type: "array",
27207
+ items: {
27208
+ type: "object",
27209
+ properties: {
27210
+ vendor_id: { type: "string" },
27211
+ notes: {
27212
+ type: "string",
27213
+ description: "Give 7-10 words on why this vendor was recommended"
27214
+ },
27215
+ vendorCoordinates: {
27216
+ type: "object",
27217
+ description: "The lat/lng coordinates of this vendor. This must come from the vendor's location.coordinates from the previous vendor search tool - do NOT guess",
27218
+ properties: {
27219
+ latitude: { type: "number" },
27220
+ longitude: { type: "number" }
27221
+ },
27222
+ required: ["latitude", "longitude"]
27223
+ }
27224
+ },
27225
+ required: ["vendor_id", "vendorCoordinates"]
27226
+ }
27227
+ }
27228
+ },
27229
+ required: ["fromLocation", "fromCoordinates", "vendors"]
27230
+ });
27231
+
27119
27232
  // lib/chat/widgets/default-widgets.tsx
27120
- import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
27233
+ import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
27121
27234
  var defaultChatWidgets = [
27122
27235
  createSDKWidget({
27123
27236
  widgetType: "person-card",
@@ -27126,7 +27239,7 @@ var defaultChatWidgets = [
27126
27239
  photoUri: zod_default.string().optional().describe("URL to a photo of the person"),
27127
27240
  details: zod_default.record(zod_default.string(), zod_default.any()).optional()
27128
27241
  }).describe("showing a person card with name, photo and additional details"),
27129
- render: (payload) => /* @__PURE__ */ jsx12(
27242
+ render: (payload) => /* @__PURE__ */ jsx13(
27130
27243
  "div",
27131
27244
  {
27132
27245
  style: {
@@ -27139,8 +27252,8 @@ var defaultChatWidgets = [
27139
27252
  borderRadius: "0.5rem",
27140
27253
  boxShadow: "0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)"
27141
27254
  },
27142
- children: /* @__PURE__ */ jsxs11("div", { style: { display: "flex", alignItems: "flex-start", gap: "0.75rem" }, children: [
27143
- payload.photoUri && /* @__PURE__ */ jsx12(
27255
+ children: /* @__PURE__ */ jsxs12("div", { style: { display: "flex", alignItems: "flex-start", gap: "0.75rem" }, children: [
27256
+ payload.photoUri && /* @__PURE__ */ jsx13(
27144
27257
  "img",
27145
27258
  {
27146
27259
  src: payload.photoUri,
@@ -27155,14 +27268,14 @@ var defaultChatWidgets = [
27155
27268
  loading: "lazy"
27156
27269
  }
27157
27270
  ),
27158
- /* @__PURE__ */ jsxs11("div", { style: { flex: 1, minWidth: 0 }, children: [
27159
- /* @__PURE__ */ jsx12("div", { style: { fontWeight: 600, fontSize: "1rem", color: "#111827", marginBottom: "0.25rem" }, children: payload.name }),
27160
- payload.details ? /* @__PURE__ */ jsx12("div", { style: { display: "flex", flexDirection: "column", gap: "0.25rem" }, children: Object.entries(payload.details).map(([key, value]) => /* @__PURE__ */ jsxs11("div", { style: { display: "flex", gap: "0.5rem", fontSize: "0.875rem" }, children: [
27161
- /* @__PURE__ */ jsxs11("span", { style: { color: "#6b7280", fontWeight: 500, minWidth: "fit-content" }, children: [
27271
+ /* @__PURE__ */ jsxs12("div", { style: { flex: 1, minWidth: 0 }, children: [
27272
+ /* @__PURE__ */ jsx13("div", { style: { fontWeight: 600, fontSize: "1rem", color: "#111827", marginBottom: "0.25rem" }, children: payload.name }),
27273
+ payload.details ? /* @__PURE__ */ jsx13("div", { style: { display: "flex", flexDirection: "column", gap: "0.25rem" }, children: Object.entries(payload.details).map(([key, value]) => /* @__PURE__ */ jsxs12("div", { style: { display: "flex", gap: "0.5rem", fontSize: "0.875rem" }, children: [
27274
+ /* @__PURE__ */ jsxs12("span", { style: { color: "#6b7280", fontWeight: 500, minWidth: "fit-content" }, children: [
27162
27275
  key,
27163
27276
  ":"
27164
27277
  ] }),
27165
- /* @__PURE__ */ jsx12("span", { style: { color: "#374151" }, children: String(value) })
27278
+ /* @__PURE__ */ jsx13("span", { style: { color: "#374151" }, children: String(value) })
27166
27279
  ] }, key)) }) : null
27167
27280
  ] })
27168
27281
  ] })
@@ -27175,7 +27288,7 @@ var defaultChatWidgets = [
27175
27288
  uri: zod_default.string().url(),
27176
27289
  text: zod_default.string().optional()
27177
27290
  }).describe("rendering a clickable link"),
27178
- render: (payload) => /* @__PURE__ */ jsx12(
27291
+ render: (payload) => /* @__PURE__ */ jsx13(
27179
27292
  "a",
27180
27293
  {
27181
27294
  href: payload.uri,
@@ -27215,43 +27328,25 @@ var getVendorCardsWidget = (isProd) => {
27215
27328
  return [
27216
27329
  createSDKWidget({
27217
27330
  widgetType: "vendor-cards",
27218
- schema: vendorCardsSchema,
27331
+ schema: vendorCardsHybridSchema,
27332
+ // Server-side enrichment for vendor details (runs parallel to LLM)
27219
27333
  enrich: {
27220
- /** fetch vendor details from the list of IDs */
27221
27334
  vendorDetails: {
27222
27335
  toolId: vendorDetailsToolId,
27223
27336
  inputs: {
27224
27337
  vendorIds: "${vendors|map('vendor_id')|join(',')}"
27225
27338
  }
27226
27339
  }
27227
- /* calculate distance from user to each vendor */
27228
- // distanceMatrix: {
27229
- // toolId: distanceMatrixToolId,
27230
- // inputs: {
27231
- // origin: "${fromCoordinates}",
27232
- // destinations: "${vendors|map('vendorCoordinates')}",
27233
- // },
27234
- // }
27235
27340
  },
27236
- render: (payload, enriched, { messageContext }) => /* @__PURE__ */ jsx12(
27237
- VendorCards,
27341
+ // Client-side: fetch distance matrix progressively
27342
+ render: (payload, enriched, { messageContext, invokeTool }) => /* @__PURE__ */ jsx13(
27343
+ HybridVendorCards,
27238
27344
  {
27239
27345
  payload,
27240
- enriched,
27241
- existingFeedback: messageContext?.getFeedback?.()?.notes,
27242
- onAddToList: (vendorId) => {
27243
- window.dispatchEvent(new CustomEvent("vendor-selected", {
27244
- detail: { vendorId }
27245
- }));
27246
- },
27247
- onFeedback: (noteId, payload2) => {
27248
- messageContext?.submitFeedback?.({
27249
- notes: [{
27250
- noteId,
27251
- ...payload2
27252
- }]
27253
- });
27254
- }
27346
+ serverEnriched: enriched,
27347
+ distanceMatrixToolId,
27348
+ invokeTool,
27349
+ messageContext
27255
27350
  }
27256
27351
  )
27257
27352
  })