@embedreach/components 0.3.35 → 0.3.36

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.
@@ -35090,10 +35090,15 @@ const useUpdateCommunicationGroup = () => {
35090
35090
  groupId,
35091
35091
  params
35092
35092
  }) => updateCommunicationGroup(groupId, params),
35093
- onSuccess: () => {
35093
+ onSuccess: (_data, variables) => {
35094
35094
  queryClient.invalidateQueries({
35095
35095
  queryKey: communicationGroupQueryKeys.all
35096
35096
  });
35097
+ if (variables?.groupId) {
35098
+ queryClient.invalidateQueries({
35099
+ queryKey: ["communication-group", variables.groupId]
35100
+ });
35101
+ }
35097
35102
  queryClient.invalidateQueries({
35098
35103
  queryKey: ["reputation", "communication-groups"]
35099
35104
  });
@@ -35104,6 +35109,7 @@ const useUpdateCommunicationGroup = () => {
35104
35109
  });
35105
35110
  return {
35106
35111
  updateCommunicationGroup: updateCommunicationGroupMutation.mutate,
35112
+ updateCommunicationGroupAsync: updateCommunicationGroupMutation.mutateAsync,
35107
35113
  isUpdating: updateCommunicationGroupMutation.isPending,
35108
35114
  updateError: updateCommunicationGroupMutation.error,
35109
35115
  isUpdateSuccess: updateCommunicationGroupMutation.isSuccess
@@ -83728,7 +83734,8 @@ const MissingDataForPreview = ({
83728
83734
  };
83729
83735
  const EmailPreviewHtmlRenderer = ({
83730
83736
  html,
83731
- onHeightChange
83737
+ onHeightChange,
83738
+ expanded = false
83732
83739
  }) => {
83733
83740
  const iframeRef = useRef(null);
83734
83741
  const [state, setState] = useState({
@@ -83852,40 +83859,40 @@ const EmailPreviewHtmlRenderer = ({
83852
83859
  return /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center h-full", children: /* @__PURE__ */ jsx(MissingDataForPreview, { type: "email" }) });
83853
83860
  }
83854
83861
  const currentHeight = state.type === "ready" ? state.height : "auto";
83855
- return /* @__PURE__ */ jsx(
83856
- "div",
83862
+ const wrapperStyle = expanded ? {
83863
+ width: "100%",
83864
+ // In expanded mode, let the wrapper size to fit the iframe
83865
+ height: "auto"
83866
+ } : {
83867
+ transition: "height 0.3s ease-in-out",
83868
+ height: currentHeight
83869
+ };
83870
+ const iframeHeight = expanded && state.type === "ready" && state.height ? `${state.height}px` : "100%";
83871
+ return /* @__PURE__ */ jsx("div", { className: "w-full bg-white rounded-lg border-0", style: wrapperStyle, children: state.type === "loading" ? /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center py-8", children: /* @__PURE__ */ jsx(BasicLoader, { text: "Loading email preview..." }) }) : /* @__PURE__ */ jsx(
83872
+ "iframe",
83857
83873
  {
83858
- className: "w-full h-full bg-white rounded-lg border-0 overflow-hidden",
83874
+ ref: iframeRef,
83875
+ title: "Email Preview",
83876
+ srcDoc: prettyHtml,
83877
+ className: "w-full block",
83859
83878
  style: {
83860
- transition: "height 0.3s ease-in-out",
83861
- height: currentHeight
83879
+ border: "none",
83880
+ backgroundColor: "white",
83881
+ width: "100%",
83882
+ height: iframeHeight,
83883
+ overflow: "hidden",
83884
+ scrollbarWidth: "none",
83885
+ msOverflowStyle: "none",
83886
+ display: "block"
83862
83887
  },
83863
- children: state.type === "loading" ? /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center py-8", children: /* @__PURE__ */ jsx(BasicLoader, { text: "Loading email preview..." }) }) : /* @__PURE__ */ jsx(
83864
- "iframe",
83865
- {
83866
- ref: iframeRef,
83867
- title: "Email Preview",
83868
- srcDoc: prettyHtml,
83869
- className: "w-full block",
83870
- style: {
83871
- border: "none",
83872
- backgroundColor: "white",
83873
- width: "100%",
83874
- height: "100%",
83875
- overflow: "hidden",
83876
- scrollbarWidth: "none",
83877
- msOverflowStyle: "none"
83878
- },
83879
- scrolling: "no",
83880
- onLoad: handleIframeLoad,
83881
- onError: () => {
83882
- const estimatedHeight = estimateHeightFromContent(prettyHtml);
83883
- handleHeightUpdate(estimatedHeight);
83884
- }
83885
- }
83886
- )
83888
+ scrolling: "no",
83889
+ onLoad: handleIframeLoad,
83890
+ onError: () => {
83891
+ const estimatedHeight = estimateHeightFromContent(prettyHtml);
83892
+ handleHeightUpdate(estimatedHeight);
83893
+ }
83887
83894
  }
83888
- );
83895
+ ) });
83889
83896
  };
83890
83897
  function OrderedMap(content2) {
83891
83898
  this.content = content2;
@@ -105719,12 +105726,10 @@ const SMSSenderAndCompanyEditor = React__default.memo(
105719
105726
  const [internalCompanyName, setInternalCompanyName] = useState(null);
105720
105727
  const [popoverOpen, setPopoverOpen] = useState(false);
105721
105728
  const [hasInitialized, setHasInitialized] = useState(false);
105722
- const lastSavedCompanyName = useRef(null);
105723
- const debouncedCompanyName = useDebounce(internalCompanyName, 250);
105724
105729
  const { channelSenders } = useChannelSender();
105725
105730
  const { channelAccounts } = useChannelAccount();
105726
105731
  const { data: smsApplication } = useGetLatestSmsRegistrationApplication();
105727
- const { updateCommunicationGroup: updateCommunicationGroup2, isUpdating } = useUpdateCommunicationGroup();
105732
+ const { updateCommunicationGroupAsync, isUpdating } = useUpdateCommunicationGroup();
105728
105733
  const smsChannelSenders = useMemo(() => {
105729
105734
  return getSmsChannelSenders({
105730
105735
  channelSenders: channelSenders?.results ?? [],
@@ -105741,7 +105746,6 @@ const SMSSenderAndCompanyEditor = React__default.memo(
105741
105746
  };
105742
105747
  setFromSender(initialSenderId);
105743
105748
  setInternalCompanyName(companyName);
105744
- lastSavedCompanyName.current = companyName;
105745
105749
  setHasInitialized(true);
105746
105750
  }
105747
105751
  }, [communicationGroupId, companyName, hasInitialized, initialSenderId]);
@@ -105758,16 +105762,9 @@ const SMSSenderAndCompanyEditor = React__default.memo(
105758
105762
  };
105759
105763
  }
105760
105764
  }, [hasInitialized, initialSenderId, companyName, communicationGroupId]);
105761
- const handleSenderChange = useCallback(
105762
- (value) => {
105763
- setFromSender(value);
105764
- updateCommunicationGroup2({
105765
- groupId: propsRef.current.communicationGroupId,
105766
- params: { smsChannelSenderId: value }
105767
- });
105768
- },
105769
- [updateCommunicationGroup2]
105770
- );
105765
+ const handleSenderChange = useCallback((value) => {
105766
+ setFromSender(value);
105767
+ }, []);
105771
105768
  const handleCompanyNameChange = useCallback(
105772
105769
  (e4) => {
105773
105770
  const newValue = e4.target.value;
@@ -105775,17 +105772,38 @@ const SMSSenderAndCompanyEditor = React__default.memo(
105775
105772
  },
105776
105773
  []
105777
105774
  );
105778
- useEffect(() => {
105779
- if (hasInitialized && debouncedCompanyName !== void 0) {
105780
- if (debouncedCompanyName !== lastSavedCompanyName.current) {
105781
- updateCommunicationGroup2({
105775
+ const handleSave = useCallback(async () => {
105776
+ if (!hasInitialized) return;
105777
+ try {
105778
+ const params = {};
105779
+ if (fromSender !== propsRef.current.initialSenderId) {
105780
+ params.smsChannelSenderId = fromSender || void 0;
105781
+ }
105782
+ if (internalCompanyName !== propsRef.current.companyName) {
105783
+ params.textMessageCompanyName = internalCompanyName || null;
105784
+ }
105785
+ if (Object.keys(params).length > 0) {
105786
+ await updateCommunicationGroupAsync({
105782
105787
  groupId: propsRef.current.communicationGroupId,
105783
- params: { textMessageCompanyName: debouncedCompanyName || null }
105788
+ params
105784
105789
  });
105785
- lastSavedCompanyName.current = debouncedCompanyName;
105786
105790
  }
105791
+ setPopoverOpen(false);
105792
+ } catch (error2) {
105793
+ console.error("Failed to save sender and company name:", error2);
105787
105794
  }
105788
- }, [debouncedCompanyName, hasInitialized, updateCommunicationGroup2]);
105795
+ }, [
105796
+ hasInitialized,
105797
+ fromSender,
105798
+ internalCompanyName,
105799
+ updateCommunicationGroupAsync
105800
+ ]);
105801
+ useEffect(() => {
105802
+ if (!popoverOpen && hasInitialized) {
105803
+ setFromSender(propsRef.current.initialSenderId);
105804
+ setInternalCompanyName(propsRef.current.companyName);
105805
+ }
105806
+ }, [popoverOpen, hasInitialized]);
105789
105807
  const handlePopoverOpenChange = useCallback((open) => {
105790
105808
  setPopoverOpen(open);
105791
105809
  }, []);
@@ -105846,8 +105864,30 @@ const SMSSenderAndCompanyEditor = React__default.memo(
105846
105864
  placeholder: "Enter company name",
105847
105865
  className: "w-full"
105848
105866
  }
105867
+ )
105868
+ ] }),
105869
+ /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2 pt-2", children: [
105870
+ /* @__PURE__ */ jsx(
105871
+ Button$1,
105872
+ {
105873
+ variant: "outline",
105874
+ onClick: () => setPopoverOpen(false),
105875
+ disabled: isUpdating,
105876
+ children: "Cancel"
105877
+ }
105849
105878
  ),
105850
- /* @__PURE__ */ jsx("div", { className: "h-6", children: /* @__PURE__ */ jsx(SavingIndicator, { isSaving: isUpdating }) })
105879
+ /* @__PURE__ */ jsx(
105880
+ Button$1,
105881
+ {
105882
+ onClick: handleSave,
105883
+ disabled: isUpdating,
105884
+ className: "min-w-[100px]",
105885
+ children: isUpdating ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
105886
+ /* @__PURE__ */ jsx(LoaderCircle, { className: "h-4 w-4 mr-2 animate-spin" }),
105887
+ /* @__PURE__ */ jsx("span", { children: "Saving..." })
105888
+ ] }) : "Save"
105889
+ }
105890
+ )
105851
105891
  ] })
105852
105892
  ] });
105853
105893
  }, [
@@ -105857,7 +105897,8 @@ const SMSSenderAndCompanyEditor = React__default.memo(
105857
105897
  isUpdating,
105858
105898
  smsChannelSenders,
105859
105899
  handleSenderChange,
105860
- handleCompanyNameChange
105900
+ handleCompanyNameChange,
105901
+ handleSave
105861
105902
  ]);
105862
105903
  if (modalType === "popover") {
105863
105904
  return /* @__PURE__ */ jsxs(Popover, { open: popoverOpen, onOpenChange: handlePopoverOpenChange, children: [
@@ -105942,6 +105983,9 @@ const MemoizedSMSSenderAndCompanyEditor$1 = React__default.memo(
105942
105983
  modalType: "dialog"
105943
105984
  }
105944
105985
  );
105986
+ },
105987
+ (prevProps, nextProps) => {
105988
+ return prevProps.communicationGroupId === nextProps.communicationGroupId && prevProps.initialSenderId === nextProps.initialSenderId && prevProps.companyName === nextProps.companyName;
105945
105989
  }
105946
105990
  );
105947
105991
  const SMSEditorContent = React__default.memo(
@@ -105966,15 +106010,9 @@ const SMSEditorContent = React__default.memo(
105966
106010
  communicationGroupId,
105967
106011
  automation2?.id ?? void 0
105968
106012
  );
105969
- const lastKnownCompanyNameRef = useRef(
105970
- companyName || null
105971
- );
105972
- if (companyName !== null && companyName !== void 0) {
105973
- lastKnownCompanyNameRef.current = companyName;
105974
- }
105975
106013
  const stableCompanyName = useMemo(() => {
105976
- return lastKnownCompanyNameRef.current;
105977
- }, []);
106014
+ return companyName ?? null;
106015
+ }, [companyName]);
105978
106016
  const hasMergeFieldsInUrl = useCallback((url) => {
105979
106017
  return /\{\{[^}]+\}\}/.test(url);
105980
106018
  }, []);
@@ -106553,11 +106591,8 @@ const EditSMSContent = () => {
106553
106591
  }
106554
106592
  );
106555
106593
  };
106556
- const AutomationEditorPreviewContainer = ({ children }) => {
106557
- return /* @__PURE__ */ jsx("div", { className: "rounded-lg p-6 bg-background flex-1 min-h-0 flex items-center justify-center overflow-y-auto", children });
106558
- };
106559
106594
  const EmailPreviewExpanded = ({ emailBody }) => {
106560
- return /* @__PURE__ */ jsx(AutomationEditorPreviewContainer, { children: /* @__PURE__ */ jsx(EmailPreviewHtmlRenderer, { html: emailBody }) });
106595
+ return /* @__PURE__ */ jsx("div", { className: "h-full w-full flex flex-col overflow-hidden", children: /* @__PURE__ */ jsx("div", { className: "flex-1 min-h-0 overflow-y-auto bg-background rounded-lg p-6", children: /* @__PURE__ */ jsx("div", { className: "w-full flex justify-center", children: /* @__PURE__ */ jsx("div", { className: "w-full max-w-4xl", children: /* @__PURE__ */ jsx(EmailPreviewHtmlRenderer, { html: emailBody, expanded: true }) }) }) }) });
106561
106596
  };
106562
106597
  const DialogCloseButton = ({ onOpenChange }) => {
106563
106598
  return /* @__PURE__ */ jsx(
@@ -106609,6 +106644,9 @@ const ExpandButton = ({ expandDialogContent }) => {
106609
106644
  )
106610
106645
  ] });
106611
106646
  };
106647
+ const AutomationEditorPreviewContainer = ({ children }) => {
106648
+ return /* @__PURE__ */ jsx("div", { className: "rounded-lg p-6 bg-background flex-1 min-h-0 flex items-center justify-center overflow-y-auto", children });
106649
+ };
106612
106650
  const SMSPreviewExpanded = ({ smsBody, imageUrls }) => {
106613
106651
  return /* @__PURE__ */ jsx(AutomationEditorPreviewContainer, { children: /* @__PURE__ */ jsx(SMSPreview, { body: smsBody, imageUrls }) });
106614
106652
  };
@@ -106653,6 +106691,7 @@ const validatePhoneNumber = (phoneNumber) => {
106653
106691
  return false;
106654
106692
  };
106655
106693
  const prettyPrintPhoneNumber = (phoneNumber) => {
106694
+ if (!phoneNumber) return "";
106656
106695
  const digitsOnly = phoneNumber.replace(/\D/g, "");
106657
106696
  if (digitsOnly.length === 10) {
106658
106697
  return `(${digitsOnly.slice(0, 3)}) ${digitsOnly.slice(3, 6)}-${digitsOnly.slice(6)}`;
@@ -122833,25 +122872,22 @@ const AutomationEditorSMSPreview = ({
122833
122872
  const dynamicUrls = dynamicMergeFieldImages.map((img) => img.placeholderUrl);
122834
122873
  return [...dynamicUrls, ...imageUrls];
122835
122874
  }, [imageUrls, dynamicMergeFieldImages]);
122836
- const lastValidCompanyName = useRef(null);
122837
- const companyName = useMemo(() => {
122838
- if (lastValidCompanyName.current === null && communicationGroup?.textMessageCompanyName) {
122839
- const currentName = communicationGroup.textMessageCompanyName;
122840
- if (currentName && currentName.trim()) {
122841
- lastValidCompanyName.current = currentName;
122842
- return currentName;
122843
- }
122875
+ const [stableCompanyName, setStableCompanyName] = useState(
122876
+ null
122877
+ );
122878
+ useEffect(() => {
122879
+ const latest = communicationGroup?.textMessageCompanyName;
122880
+ if (latest !== void 0) {
122881
+ setStableCompanyName(latest ?? null);
122844
122882
  }
122845
- const stableName = lastValidCompanyName.current;
122846
- return stableName;
122847
- }, []);
122883
+ }, [communicationGroup?.textMessageCompanyName]);
122848
122884
  const finalSMSBody = useMemo(() => {
122849
122885
  const result = buildFinalSMSBody({
122850
- companyName: companyName ?? void 0,
122886
+ companyName: stableCompanyName ?? void 0,
122851
122887
  smsBody
122852
122888
  });
122853
122889
  return result;
122854
- }, [companyName, smsBody]);
122890
+ }, [stableCompanyName, smsBody]);
122855
122891
  const { getMergeFields: getMergeFields2 } = useGetMergeFieldsWithAutomation(
122856
122892
  communicationGroup?.id ?? void 0,
122857
122893
  automation2?.id ?? void 0
@@ -123007,7 +123043,7 @@ const AutomationEditorSMSPreview = ({
123007
123043
  communicationGroupId: communicationGroup?.id || "",
123008
123044
  initialMessage,
123009
123045
  initialImageUrls: imageUrls,
123010
- companyName,
123046
+ companyName: stableCompanyName,
123011
123047
  initialSenderId: communicationGroup?.smsChannelSenderId
123012
123048
  }
123013
123049
  ),
@@ -24435,17 +24435,18 @@ const createPhoneNumberFactory = (agentId, number) => {
24435
24435
  return {
24436
24436
  id: f.string.uuid(),
24437
24437
  agentId,
24438
- number: generatedNumber,
24439
- forwardingEnabled: false,
24438
+ businessId: "mock-business-id",
24439
+ phoneNumber: generatedNumber,
24440
+ forwardingType: "none",
24440
24441
  createdAt: f.date.past().toISOString(),
24441
24442
  updatedAt: f.date.recent().toISOString()
24442
24443
  };
24443
24444
  };
24444
24445
  const createCallFactory = (agentId) => {
24445
24446
  const createdAt = f.date.recent();
24446
- const answeredAt = f.date.between({ from: createdAt, to: /* @__PURE__ */ new Date() });
24447
+ const startedAt = f.date.between({ from: createdAt, to: /* @__PURE__ */ new Date() });
24447
24448
  const duration = f.number.int({ min: 30, max: 1800 });
24448
- const endedAt = new Date(answeredAt.getTime() + duration * 1e3);
24449
+ const endedAt = new Date(startedAt.getTime() + duration * 1e3);
24449
24450
  const summaries = [
24450
24451
  "Customer inquired about business hours and services offered. Provided information about our operating schedule and explained our consultation process.",
24451
24452
  "Client called to schedule an appointment for next week. Confirmed availability and provided pricing information for the requested service.",
@@ -24459,15 +24460,22 @@ const createCallFactory = (agentId) => {
24459
24460
  return {
24460
24461
  id: f.string.uuid(),
24461
24462
  agentId,
24463
+ callType: "phone_call",
24464
+ callStatus: "completed",
24462
24465
  fromNumber: generatePlainPhoneNumber(),
24463
- duration,
24464
- location: `${f.location.city()}, ${f.location.state({ abbreviated: true })}`,
24466
+ toNumber: generatePlainPhoneNumber(),
24467
+ direction: "inbound",
24468
+ startedAt: startedAt.toISOString(),
24469
+ endedAt: endedAt.toISOString(),
24470
+ durationSecs: duration,
24471
+ sentiment: f.datatype.boolean({ probability: 0.7 }) ? "positive" : "negative",
24472
+ successful: f.datatype.boolean({ probability: 0.8 }),
24473
+ blockedReason: null,
24474
+ transcript: null,
24475
+ summary: f.helpers.arrayElement(summaries),
24465
24476
  recordingUrl: f.datatype.boolean({ probability: 0.8 }) ? `https://example.com/recording/${f.string.uuid()}.mp3` : void 0,
24466
- aiSummary: f.helpers.arrayElement(summaries),
24467
- status: "completed",
24468
24477
  createdAt: createdAt.toISOString(),
24469
- answeredAt: answeredAt.toISOString(),
24470
- endedAt: endedAt.toISOString()
24478
+ updatedAt: createdAt.toISOString()
24471
24479
  };
24472
24480
  };
24473
24481
  const knowledgeStore = /* @__PURE__ */ new Map();
@@ -24479,6 +24487,7 @@ const mockStore = {
24479
24487
  phoneNumbers: [],
24480
24488
  testCalls: [],
24481
24489
  forwardingTests: [],
24490
+ agentKnowledge: {},
24482
24491
  calls: []
24483
24492
  };
24484
24493
  const getOrCreateAgent = (businessId) => {
@@ -24514,17 +24523,131 @@ const voiceHandlers = [
24514
24523
  return HttpResponse.json({
24515
24524
  success: true,
24516
24525
  message: "Success (Sandbox)",
24517
- data: [agent]
24526
+ data: {
24527
+ results: [agent],
24528
+ pagination: {
24529
+ hasNextPage: false,
24530
+ cursor: null
24531
+ }
24532
+ }
24518
24533
  });
24519
24534
  }),
24535
+ // Create voice agent
24536
+ http.post(`${HOSTNAME}/api/voice/agents`, async () => {
24537
+ const businessId = "mock-business-id";
24538
+ const existingAgent = mockStore.agents.find(
24539
+ (a2) => a2.businessId === businessId
24540
+ );
24541
+ if (existingAgent) {
24542
+ return HttpResponse.json(
24543
+ {
24544
+ success: false,
24545
+ message: "Agent already exists for this business (Sandbox)"
24546
+ },
24547
+ { status: 409 }
24548
+ );
24549
+ }
24550
+ const agent = createVoiceAgentFactory(businessId);
24551
+ mockStore.agents.push(agent);
24552
+ mockStore.agentKnowledge[agent.id] = [];
24553
+ return HttpResponse.json(
24554
+ {
24555
+ success: true,
24556
+ message: "Agent created (Sandbox)",
24557
+ data: agent
24558
+ },
24559
+ { status: 201 }
24560
+ );
24561
+ }),
24562
+ // Get knowledge items for an agent
24563
+ http.get(
24564
+ `${HOSTNAME}/api/voice/agents/:agentId/knowledge`,
24565
+ async ({ params, request }) => {
24566
+ const agentId = typeof params.agentId === "string" ? params.agentId : Array.isArray(params.agentId) ? params.agentId[0] : "";
24567
+ const agent = mockStore.agents.find((a2) => a2.id === agentId);
24568
+ if (!agent) {
24569
+ return HttpResponse.json(
24570
+ {
24571
+ success: false,
24572
+ message: `Agent with ID ${agentId} not found (Sandbox)`
24573
+ },
24574
+ { status: 404 }
24575
+ );
24576
+ }
24577
+ const url = new URL(request.url);
24578
+ const cursor = url.searchParams.get("cursor") || void 0;
24579
+ const limitParam = url.searchParams.get("limit");
24580
+ const limit = limitParam ? Number.parseInt(limitParam, 10) : void 0;
24581
+ const knowledgeItems = mockStore.agentKnowledge[agentId] || [];
24582
+ const startIndex = cursor ? Number.parseInt(cursor, 10) : 0;
24583
+ const endIndex = limit ? startIndex + limit : knowledgeItems.length;
24584
+ const paginatedItems = knowledgeItems.slice(startIndex, endIndex);
24585
+ const hasNextPage = endIndex < knowledgeItems.length;
24586
+ return HttpResponse.json({
24587
+ success: true,
24588
+ message: "Success (Sandbox)",
24589
+ data: {
24590
+ data: paginatedItems,
24591
+ pagination: {
24592
+ hasNextPage,
24593
+ cursor: hasNextPage ? endIndex.toString() : void 0
24594
+ }
24595
+ }
24596
+ });
24597
+ }
24598
+ ),
24599
+ // Apply knowledge to an agent
24600
+ http.post(
24601
+ `${HOSTNAME}/api/voice/agents/:agentId/knowledge`,
24602
+ async ({ params, request }) => {
24603
+ const agentId = typeof params.agentId === "string" ? params.agentId : Array.isArray(params.agentId) ? params.agentId[0] : "";
24604
+ const agent = mockStore.agents.find((a2) => a2.id === agentId);
24605
+ if (!agent) {
24606
+ return HttpResponse.json(
24607
+ {
24608
+ success: false,
24609
+ message: `Agent with ID ${agentId} not found (Sandbox)`
24610
+ },
24611
+ { status: 404 }
24612
+ );
24613
+ }
24614
+ const body = await request.json();
24615
+ const requests = Array.isArray(body) ? body : [body];
24616
+ const knowledgeItems = requests.map((req) => ({
24617
+ id: crypto.randomUUID(),
24618
+ agentId,
24619
+ title: req.title,
24620
+ content: req.content,
24621
+ websiteScanId: void 0,
24622
+ deactivatedAt: null,
24623
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
24624
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
24625
+ }));
24626
+ if (!mockStore.agentKnowledge[agentId]) {
24627
+ mockStore.agentKnowledge[agentId] = [];
24628
+ }
24629
+ mockStore.agentKnowledge[agentId].push(...knowledgeItems);
24630
+ return HttpResponse.json(
24631
+ {
24632
+ success: true,
24633
+ message: "Knowledge applied (Sandbox)",
24634
+ data: knowledgeItems
24635
+ },
24636
+ { status: 201 }
24637
+ );
24638
+ }
24639
+ ),
24520
24640
  // Get knowledge items from webscan-knowledge (business-scoped)
24521
24641
  http.get(`${HOSTNAME}/api/webscan-knowledge`, async () => {
24522
24642
  return HttpResponse.json({
24523
24643
  success: true,
24524
24644
  message: "Success (Sandbox)",
24525
24645
  data: {
24526
- items: mockStore.knowledgeItems,
24527
- total: mockStore.knowledgeItems.length
24646
+ results: mockStore.knowledgeItems,
24647
+ pagination: {
24648
+ hasNextPage: false,
24649
+ cursor: null
24650
+ }
24528
24651
  }
24529
24652
  });
24530
24653
  }),
@@ -24871,7 +24994,13 @@ const voiceHandlers = [
24871
24994
  return HttpResponse.json({
24872
24995
  success: true,
24873
24996
  message: "Success (Sandbox)",
24874
- data: phoneNumbers
24997
+ data: {
24998
+ results: phoneNumbers,
24999
+ pagination: {
25000
+ hasNextPage: false,
25001
+ cursor: null
25002
+ }
25003
+ }
24875
25004
  });
24876
25005
  }
24877
25006
  ),
@@ -25001,28 +25130,36 @@ const voiceHandlers = [
25001
25130
  }
25002
25131
  ),
25003
25132
  // Get calls for an agent
25004
- http.get(`${HOSTNAME}/api/voice/calls`, ({ request }) => {
25005
- const url = new URL(request.url);
25006
- const agentId = url.searchParams.get("agentId");
25007
- if (!agentId) {
25008
- return HttpResponse.json(
25009
- {
25010
- success: false,
25011
- message: "agentId query parameter is required (Sandbox)"
25012
- },
25013
- { status: 400 }
25133
+ http.get(
25134
+ `${HOSTNAME}/api/voice/agents/:agentId/calls`,
25135
+ ({ params, request }) => {
25136
+ const agentId = params.agentId;
25137
+ const url = new URL(request.url);
25138
+ const cursor = url.searchParams.get("cursor");
25139
+ const limitParam = url.searchParams.get("limit");
25140
+ const limit = limitParam ? parseInt(limitParam, 10) : void 0;
25141
+ const agentCalls = mockStore.calls.filter((c2) => c2.agentId === agentId);
25142
+ agentCalls.sort(
25143
+ (a2, b2) => new Date(b2.createdAt).getTime() - new Date(a2.createdAt).getTime()
25014
25144
  );
25145
+ const startIndex = cursor ? parseInt(cursor, 10) : 0;
25146
+ const endIndex = limit ? Math.min(startIndex + limit, agentCalls.length) : agentCalls.length;
25147
+ const paginatedCalls = agentCalls.slice(startIndex, endIndex);
25148
+ const hasNextPage = endIndex < agentCalls.length;
25149
+ const nextCursor = hasNextPage ? endIndex.toString() : void 0;
25150
+ return HttpResponse.json({
25151
+ success: true,
25152
+ message: "Success (Sandbox)",
25153
+ data: {
25154
+ results: paginatedCalls,
25155
+ pagination: {
25156
+ hasNextPage,
25157
+ cursor: nextCursor
25158
+ }
25159
+ }
25160
+ });
25015
25161
  }
25016
- const agentCalls = mockStore.calls.filter((c2) => c2.agentId === agentId);
25017
- agentCalls.sort(
25018
- (a2, b2) => new Date(b2.createdAt).getTime() - new Date(a2.createdAt).getTime()
25019
- );
25020
- return HttpResponse.json({
25021
- success: true,
25022
- message: "Success (Sandbox)",
25023
- data: agentCalls
25024
- });
25025
- })
25162
+ )
25026
25163
  ];
25027
25164
  const getHandlersByFeatures = (features) => {
25028
25165
  const allHandlers = [];