@iblai/iblai-js 1.4.0 → 1.4.2

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.
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import React__default, { useRef, useEffect, useState, useCallback, useLayoutEffect, forwardRef, createElement as createElement$1, useMemo, createContext, useReducer, useImperativeHandle, useContext, useDebugValue, isValidElement, Children, PureComponent, cloneElement, Component } from 'react';
3
3
  import { LOCAL_STORAGE_KEYS, TimeTracker, getInitials, useTenantMetadata, isAlphaNumeric32, checkRbacPermission, getTimeAgo, formatRelativeTime as formatRelativeTime$2, ANONYMOUS_USERNAME, combineCSVData, redirectToAuthSpaJoinTenant, redirectToAuthSpa, getAuthSpaJoinUrl } from '@iblai/web-utils';
4
- import { useTimeTrackingMutation, useGetUserMetadataQuery, useGetUserMetadataEdxQuery, useUpdateUserMetadataMutation, useUpdateUserMetadataEdxMutation, useUploadProfileImageMutation, useResetPasswordMutation, useSelfRetireMutation, useCreateUserInstitutionMutation, useGetUserInstitutionsQuery, useCreateUserEducationMutation, useUpdateUserEducationMutation, useDeleteUserEducationMutation, useGetUserEducationQuery, useCreateUserCompanyMutation, useGetUserCompaniesQuery, useCreateUserExperienceMutation, useUpdateUserExperienceMutation, useDeleteUserExperienceMutation, useGetUserExperienceQuery, useGetUserResumeQuery, useCreateUserResumeMutation, useGetMySubscriptionsQuery, useGetItemSubscriptionQuery, useCancelSubscriptionMutation, useCreateGlobalMemoryMutation, useGetMemsearchConfigQuery, useGetUserMemorySettingsQuery, useUpdateUserMemorySettingsMutation, useGetGlobalMemoriesQuery, useDeleteGlobalMemoryMutation, useInviteUserMutation, usePlatformInvitationsQuery, useCreateCatalogInvitationCourseBulkMutation, useGetCatalogInvitationsCourseQuery, useLazyPlatformUsersQuery, useLazyPlatformUserGroupsQuery, useGetPersonnalizedSearchQuery, useCreateCatalogInvitationProgramBulkMutation, useGetCatalogInvitationsProgramQuery, useGetNotificationsCountQuery, useLazyGetNotificationsQuery, useMarkAllAsReadMutation, useCreateNotificationPreviewMutation, useSendNotificationMutation, useGetMentorsQuery, useGetRbacPoliciesQuery, usePlatformUsersQuery, usePlatformUserGroupsQuery, useUpdateTemplateMutation, useGetTemplateDetailsQuery, useGetTemplatesQuery, useLazyGetTemplateDetailsQuery, useToggleTemplateMutation, useGetTopicsStatsQuery, useGetUsersStatsQuery, useGetSessionStatsQuery, useGetTopicsDetailsStatsQuery, useGetAccessTimeHeatmapQuery, useGetUserDetailsStatsQuery, useGetTranscriptsConversationHeadlineQuery, useGetAverageRatingQuery, useGetFinancialStatsQuery, useGetDetailedFinancialStatsQuery, useGetTranscriptsMessagesDetailsQuery, useGetTranscriptsMessagesQuery, useGetReportDetailQuery, useLazyGetDownloadReportFromURLQuery, useGetReportsQuery, useCreateReportMutation, useGetMentorPublicSettingsQuery, useGetContentAnalyticsQuery, useGetContentAnalyticsDetailsQuery, useGetRevenueQuery, useListPaywallsQuery, useListSubscribersQuery, useLazyGetCourseMetaDataQuery, useLazyGetCourseCompletionOutlinesQuery, useLazyGetCourseEligibilityQuery, useLazyGetUserEnrolledCoursesQuery, useLazyGetUserAssignedCoursesQuery, useLazyGetUserCredentialsQuery, useLazyGetOverTimeActivityQuery, useLazyGetCatalogSearchQuery, useGetUserEarnedSkillsQuery, useGetUserReportedSkillsQuery, useGetUserDesiredSkillsQuery, useCreateOrUpdateUserReportedSkillMutation, useCreateOrUpdateUserDesiredSkillMutation, useLazyGetPathwayListQuery, useLazyGetUserAssignedPathwaysQuery, useLazyGetUserEnrolledPathwaysQuery, useLazyGetPathwayCompletionQuery, useLazyGetProgramListQuery, useLazyGetProgramCompletionQuery, useLazyGetUserEnrolledProgramsQuery, useLazyGetAssignedProgramsQuery, useLazyGetUserSkillsPointsQuery, useLazyGetUserReportedSkillsQuery, useLazyGetUserDesiredSkillsQuery, useLazyGetUserCatalogPathwaysQuery, useLazyGetPerLearnerInfoQuery, useLazyGetEdxSSOTokenQuery, useCreateCourseEnrollmentMutation, useCreateStripeCheckoutSessionMutation, useLazyGetCourseProgressQuery, useLazyGetCourseCompletionQuery, useUpdateExamAttemptMutation, useStartExamMutation, useLazyGetExamInfoQuery, useCreateCheckoutMutation } from '@iblai/data-layer';
4
+ import { useTimeTrackingMutation, useGetUserMetadataQuery, useGetUserMetadataEdxQuery, useUpdateUserMetadataMutation, useUpdateUserMetadataEdxMutation, useUploadProfileImageMutation, useResetPasswordMutation, useSelfRetireMutation, useCreateUserInstitutionMutation, useGetUserInstitutionsQuery, useCreateUserEducationMutation, useUpdateUserEducationMutation, useDeleteUserEducationMutation, useGetUserEducationQuery, useCreateUserCompanyMutation, useGetUserCompaniesQuery, useCreateUserExperienceMutation, useUpdateUserExperienceMutation, useDeleteUserExperienceMutation, useGetUserExperienceQuery, useGetUserResumeQuery, useCreateUserResumeMutation, useGetMySubscriptionsQuery, useGetItemSubscriptionQuery, useCancelSubscriptionMutation, useCreateGlobalMemoryMutation, useGetMemsearchStatusQuery, useGetUserMemorySettingsQuery, useUpdateUserMemorySettingsMutation, useGetGlobalMemoriesQuery, useDeleteGlobalMemoryMutation, useInviteUserMutation, usePlatformInvitationsQuery, useCreateCatalogInvitationCourseBulkMutation, useGetCatalogInvitationsCourseQuery, useLazyPlatformUsersQuery, useLazyPlatformUserGroupsQuery, useGetPersonnalizedSearchQuery, useCreateCatalogInvitationProgramBulkMutation, useGetCatalogInvitationsProgramQuery, useGetNotificationsCountQuery, useLazyGetNotificationsQuery, useMarkAllAsReadMutation, useCreateNotificationPreviewMutation, useSendNotificationMutation, useGetMentorsQuery, useGetRbacPoliciesQuery, usePlatformUsersQuery, usePlatformUserGroupsQuery, useUpdateTemplateMutation, useGetTemplateDetailsQuery, useGetTemplatesQuery, useLazyGetTemplateDetailsQuery, useToggleTemplateMutation, useGetTopicsStatsQuery, useGetUsersStatsQuery, useGetSessionStatsQuery, useGetTopicsDetailsStatsQuery, useGetAccessTimeHeatmapQuery, useGetUserDetailsStatsQuery, useGetTranscriptsConversationHeadlineQuery, useGetAverageRatingQuery, useGetFinancialStatsQuery, useGetDetailedFinancialStatsQuery, useGetTranscriptsMessagesDetailsQuery, useGetTranscriptsMessagesQuery, useGetReportDetailQuery, useLazyGetDownloadReportFromURLQuery, useGetReportsQuery, useCreateReportMutation, useGetMentorPublicSettingsQuery, useGetContentAnalyticsQuery, useGetContentAnalyticsDetailsQuery, useGetRevenueQuery, useListPaywallsQuery, useListSubscribersQuery, useLazyGetCourseMetaDataQuery, useLazyGetCourseCompletionOutlinesQuery, useLazyGetCourseEligibilityQuery, useLazyGetUserEnrolledCoursesQuery, useLazyGetUserAssignedCoursesQuery, useLazyGetUserCredentialsQuery, useLazyGetOverTimeActivityQuery, useLazyGetCatalogSearchQuery, useGetUserEarnedSkillsQuery, useGetUserReportedSkillsQuery, useGetUserDesiredSkillsQuery, useCreateOrUpdateUserReportedSkillMutation, useCreateOrUpdateUserDesiredSkillMutation, useLazyGetPathwayListQuery, useLazyGetUserAssignedPathwaysQuery, useLazyGetUserEnrolledPathwaysQuery, useLazyGetPathwayCompletionQuery, useLazyGetProgramListQuery, useLazyGetProgramCompletionQuery, useLazyGetUserEnrolledProgramsQuery, useLazyGetAssignedProgramsQuery, useLazyGetUserSkillsPointsQuery, useLazyGetUserReportedSkillsQuery, useLazyGetUserDesiredSkillsQuery, useLazyGetUserCatalogPathwaysQuery, useLazyGetPerLearnerInfoQuery, useLazyGetEdxSSOTokenQuery, useCreateCourseEnrollmentMutation, useCreateStripeCheckoutSessionMutation, useLazyGetCourseProgressQuery, useLazyGetCourseCompletionQuery, useUpdateExamAttemptMutation, useStartExamMutation, useLazyGetExamInfoQuery, useCreateCheckoutMutation } from '@iblai/data-layer';
5
5
  import { toast, Toaster as Toaster$1 } from 'sonner';
6
6
  import { jsx, Fragment as Fragment$1, jsxs } from 'react/jsx-runtime';
7
7
  import * as ReactDOM from 'react-dom';
@@ -49601,17 +49601,11 @@ const Database = createLucideIcon("database", __iconNode$W);
49601
49601
 
49602
49602
 
49603
49603
  const __iconNode$V = [
49604
- [
49605
- "path",
49606
- {
49607
- d: "M10 5a2 2 0 0 0-1.344.519l-6.328 5.74a1 1 0 0 0 0 1.481l6.328 5.741A2 2 0 0 0 10 19h10a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2z",
49608
- key: "1yo7s0"
49609
- }
49610
- ],
49611
- ["path", { d: "m12 9 6 6", key: "anjzzh" }],
49612
- ["path", { d: "m18 9-6 6", key: "1fp51s" }]
49604
+ ["path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4", key: "ih7n3h" }],
49605
+ ["polyline", { points: "7 10 12 15 17 10", key: "2ggqvy" }],
49606
+ ["line", { x1: "12", x2: "12", y1: "15", y2: "3", key: "1vk2je" }]
49613
49607
  ];
49614
- const Delete$1 = createLucideIcon("delete", __iconNode$V);
49608
+ const Download = createLucideIcon("download", __iconNode$V);
49615
49609
 
49616
49610
  /**
49617
49611
  * @license lucide-react v0.507.0 - ISC
@@ -49622,11 +49616,11 @@ const Delete$1 = createLucideIcon("delete", __iconNode$V);
49622
49616
 
49623
49617
 
49624
49618
  const __iconNode$U = [
49625
- ["path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4", key: "ih7n3h" }],
49626
- ["polyline", { points: "7 10 12 15 17 10", key: "2ggqvy" }],
49627
- ["line", { x1: "12", x2: "12", y1: "15", y2: "3", key: "1vk2je" }]
49619
+ ["circle", { cx: "12", cy: "12", r: "1", key: "41hilf" }],
49620
+ ["circle", { cx: "19", cy: "12", r: "1", key: "1wjl8i" }],
49621
+ ["circle", { cx: "5", cy: "12", r: "1", key: "1pcz8c" }]
49628
49622
  ];
49629
- const Download = createLucideIcon("download", __iconNode$U);
49623
+ const Ellipsis = createLucideIcon("ellipsis", __iconNode$U);
49630
49624
 
49631
49625
  /**
49632
49626
  * @license lucide-react v0.507.0 - ISC
@@ -82032,12 +82026,82 @@ function AddMemoryDialog({ open, onOpenChange, org, username }) {
82032
82026
  }, children: jsx(DialogContent$1, { className: "p-0 overflow-hidden max-w-lg", children: jsxs("form", { onSubmit: handleSubmit, children: [jsx("div", { className: "flex items-center justify-between px-6 py-4 border-b", children: jsx(DialogTitle$1, { className: "text-lg font-semibold text-gray-900", children: "Add Memory" }) }), jsx(DialogDescription$1, { className: "sr-only", children: "Add a new memory for the AI to remember about you" }), jsx("div", { className: "p-6 space-y-4", children: jsxs("div", { className: "space-y-2", children: [jsx(Label$2, { htmlFor: "memory-content", children: "What should the AI remember?" }), jsx(Textarea, { id: "memory-content", placeholder: "e.g., I prefer learning through practical examples rather than theory.", value: content, onChange: (e) => setContent(e.target.value), rows: 4, className: "w-full bg-gray-50 border-gray-200 focus:ring-blue-500 focus:border-blue-500 text-sm resize-none", disabled: isLoading }), content.length > 0 && content.trim().length < 10 && (jsx("p", { className: "text-sm text-red-500", children: "Must be at least 10 characters" }))] }) }), jsxs("div", { className: "flex justify-end gap-3 border-t px-6 py-4", children: [jsx(Button$1, { type: "button", variant: "outline", onClick: () => onOpenChange(false), disabled: isLoading, children: "Cancel" }), jsx(Button$1, { className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] hover:opacity-90 text-white", type: "submit", disabled: isLoading || content.trim().length < 10, children: isLoading ? 'Saving...' : 'Save Memory' })] })] }) }) }));
82033
82027
  }
82034
82028
 
82029
+ const Pagination = ({ className, ...props }) => (jsx("nav", { role: "navigation", "aria-label": "pagination", className: cn("mx-auto flex w-full justify-center", className), ...props }));
82030
+ Pagination.displayName = "Pagination";
82031
+ const PaginationContent = React.forwardRef(({ className, ...props }, ref) => (jsx("ul", { ref: ref, className: cn("flex flex-row items-center gap-1", className), ...props })));
82032
+ PaginationContent.displayName = "PaginationContent";
82033
+ const PaginationItem = React.forwardRef(({ className, ...props }, ref) => (jsx("li", { ref: ref, className: cn("", className), ...props })));
82034
+ PaginationItem.displayName = "PaginationItem";
82035
+ const PaginationLink = ({ className, isActive, size = "icon", ...props }) => (jsx("a", { "aria-current": isActive ? "page" : undefined, className: cn(buttonVariants({
82036
+ variant: isActive ? "outline" : "ghost",
82037
+ size,
82038
+ }), className), ...props }));
82039
+ PaginationLink.displayName = "PaginationLink";
82040
+ const PaginationPrevious = ({ className, ...props }) => (jsxs(PaginationLink, { "aria-label": "Go to previous page", size: "default", className: cn("gap-1 pl-2.5", className), ...props, children: [jsx(ChevronLeft, { className: "h-4 w-4" }), jsx("span", { children: "Previous" })] }));
82041
+ PaginationPrevious.displayName = "PaginationPrevious";
82042
+ const PaginationNext = ({ className, ...props }) => (jsxs(PaginationLink, { "aria-label": "Go to next page", size: "default", className: cn("gap-1 pr-2.5", className), ...props, children: [jsx("span", { children: "Next" }), jsx(ChevronRight, { className: "h-4 w-4" })] }));
82043
+ PaginationNext.displayName = "PaginationNext";
82044
+ const PaginationEllipsis = ({ className, ...props }) => (jsxs("span", { "aria-hidden": true, className: cn("flex h-9 w-9 items-center justify-center", className), ...props, children: [jsx(Ellipsis, { className: "h-4 w-4" }), jsx("span", { className: "sr-only", children: "More pages" })] }));
82045
+ PaginationEllipsis.displayName = "PaginationEllipsis";
82046
+
82047
+ const IblPagination = ({ currentPage, totalPages, onPageChange, disabled = false, disableNumberedButtons = false, }) => {
82048
+ const getPageNumbers = () => {
82049
+ const pages = [];
82050
+ pages.push(1);
82051
+ let startPage = Math.max(2, currentPage - 1);
82052
+ let endPage = Math.min(totalPages - 1, currentPage + 1);
82053
+ if (currentPage <= 2) {
82054
+ endPage = Math.min(totalPages - 1, 4);
82055
+ }
82056
+ else if (currentPage >= totalPages - 1) {
82057
+ startPage = Math.max(2, totalPages - 3);
82058
+ }
82059
+ if (startPage > 2) {
82060
+ pages.push('ellipsis-start');
82061
+ }
82062
+ for (let i = startPage; i <= endPage; i++) {
82063
+ if (i !== 1 && i !== totalPages) {
82064
+ pages.push(i);
82065
+ }
82066
+ }
82067
+ if (endPage < totalPages - 1) {
82068
+ pages.push('ellipsis-end');
82069
+ }
82070
+ if (totalPages > 1) {
82071
+ pages.push(totalPages);
82072
+ }
82073
+ return pages;
82074
+ };
82075
+ if (totalPages <= 1) {
82076
+ return null;
82077
+ }
82078
+ return (jsx(Pagination, { children: jsxs(PaginationContent, { children: [jsx(PaginationItem, { children: jsx(PaginationPrevious, { size: "sm", onClick: (e) => {
82079
+ e.preventDefault();
82080
+ if (!disabled && currentPage > 1) {
82081
+ onPageChange(currentPage - 1);
82082
+ }
82083
+ }, "aria-disabled": currentPage === 1 || disabled, className: cn('cursor-pointer', (currentPage === 1 || disabled) && 'pointer-events-none opacity-50') }) }), !disableNumberedButtons &&
82084
+ getPageNumbers().map((page, index) => (jsx(PaginationItem, { children: page === 'ellipsis-start' || page === 'ellipsis-end' ? (jsx(PaginationEllipsis, {})) : (jsx(PaginationLink, { size: "sm", onClick: (e) => {
82085
+ e.preventDefault();
82086
+ if (!disabled && typeof page === 'number') {
82087
+ onPageChange(page);
82088
+ }
82089
+ }, isActive: page === currentPage, className: cn('cursor-pointer', disabled && 'pointer-events-none opacity-50'), children: page })) }, index))), jsx(PaginationItem, { children: jsx(PaginationNext, { size: "sm", onClick: (e) => {
82090
+ e.preventDefault();
82091
+ if (!disabled && currentPage < totalPages) {
82092
+ onPageChange(currentPage + 1);
82093
+ }
82094
+ }, "aria-disabled": currentPage === totalPages || disabled, className: cn('cursor-pointer', (currentPage === totalPages || disabled) && 'pointer-events-none opacity-50') }) })] }) }));
82095
+ };
82096
+
82097
+ const MEMORIES_PAGE_SIZE = 25;
82035
82098
  function MemoryTab({ org, username }) {
82036
82099
  var _a, _b, _c;
82037
82100
  const [isAddDialogOpen, setIsAddDialogOpen] = useState(false);
82038
82101
  const [deletingId, setDeletingId] = useState(null);
82039
- // Platform memsearch config
82040
- const { data: memsearchConfig, isLoading: isLoadingConfig, isError: isConfigError, } = useGetMemsearchConfigQuery({
82102
+ const [currentPage, setCurrentPage] = useState(1);
82103
+ // Platform memsearch status (available to students and admins)
82104
+ const { data: memsearchStatus, isLoading: isLoadingConfig, isError: isConfigError, } = useGetMemsearchStatusQuery({
82041
82105
  org,
82042
82106
  userId: username,
82043
82107
  });
@@ -82051,8 +82115,9 @@ function MemoryTab({ org, username }) {
82051
82115
  const { data: memoriesData, isLoading: isLoadingMemories } = useGetGlobalMemoriesQuery({
82052
82116
  org,
82053
82117
  userId: username,
82054
- params: { page_size: 25 },
82118
+ params: { page: currentPage, page_size: MEMORIES_PAGE_SIZE },
82055
82119
  });
82120
+ const totalPages = (memoriesData === null || memoriesData === void 0 ? void 0 : memoriesData.count) ? Math.ceil(memoriesData.count / MEMORIES_PAGE_SIZE) : 0;
82056
82121
  const [deleteMemory] = useDeleteGlobalMemoryMutation();
82057
82122
  const handleToggleSetting = async (key, checked) => {
82058
82123
  try {
@@ -82088,10 +82153,10 @@ function MemoryTab({ org, username }) {
82088
82153
  return (jsxs("div", { className: "max-w-2xl space-y-6", children: [jsx(Skeleton, { className: "h-20 w-full rounded-lg" }), jsx(Skeleton, { className: "h-20 w-full rounded-lg" }), jsx(Skeleton, { className: "h-40 w-full rounded-lg" })] }));
82089
82154
  }
82090
82155
  // Hide memory UI when platform has disabled memsearch (skip check if API errored)
82091
- if (!isConfigError && memsearchConfig && !memsearchConfig.enable_memsearch) {
82156
+ if (!isConfigError && memsearchStatus && !memsearchStatus.enable_memsearch) {
82092
82157
  return (jsx("div", { className: "max-w-2xl", children: jsx("div", { className: "rounded-lg border px-6 py-8 text-center", style: { borderColor: 'oklch(.922 0 0)' }, children: jsx("p", { className: "text-sm text-gray-500", children: "The memory feature is not enabled for this platform. Contact your administrator to enable it." }) }) }));
82093
82158
  }
82094
- return (jsxs("div", { className: "max-w-2xl space-y-8", children: [jsxs("div", { className: "space-y-4", children: [jsx("h4", { className: "text-sm font-semibold text-gray-700 dark:text-gray-300 tracking-wide", children: "Memory & Personalization" }), jsxs("div", { className: "flex items-center justify-between rounded-lg border px-6 py-5", style: { borderColor: 'oklch(.922 0 0)' }, children: [jsxs("div", { className: "flex-1 mr-4", children: [jsx("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: "Allow AI to learn from our conversations" }), jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400 mt-1", children: "When enabled, the AI will remember useful information from your chats to provide better assistance." })] }), jsx(Switch, { checked: (_a = settings === null || settings === void 0 ? void 0 : settings.auto_capture_enabled) !== null && _a !== void 0 ? _a : false, onCheckedChange: (checked) => handleToggleSetting('auto_capture_enabled', checked), disabled: isUpdatingSettings, "aria-label": `Auto memory capture ${(settings === null || settings === void 0 ? void 0 : settings.auto_capture_enabled) ? 'enabled' : 'disabled'}`, className: "cursor-pointer data-[state=checked]:bg-blue-500 flex-shrink-0" })] }), jsxs("div", { className: "flex items-center justify-between rounded-lg border px-6 py-5", style: { borderColor: 'oklch(.922 0 0)' }, children: [jsxs("div", { className: "flex-1 mr-4", children: [jsx("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: "Use my saved information in responses" }), jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400 mt-1", children: "When enabled, the AI will use what it knows about you to personalize responses." })] }), jsx(Switch, { checked: (_b = settings === null || settings === void 0 ? void 0 : settings.use_memory_in_responses) !== null && _b !== void 0 ? _b : false, onCheckedChange: (checked) => handleToggleSetting('use_memory_in_responses', checked), disabled: isUpdatingSettings, "aria-label": `Use memory in responses ${(settings === null || settings === void 0 ? void 0 : settings.use_memory_in_responses) ? 'enabled' : 'disabled'}`, className: "cursor-pointer data-[state=checked]:bg-blue-500 flex-shrink-0" })] })] }), jsxs("div", { className: "space-y-4", children: [jsxs("div", { className: "flex items-center justify-between", children: [jsx("h4", { className: "text-sm font-semibold text-gray-700 dark:text-gray-300 tracking-wide", children: "My Memories" }), jsxs(Button$1, { variant: "outline", size: "sm", onClick: () => setIsAddDialogOpen(true), className: "text-xs", children: [jsx(Plus, { className: "h-3 w-3 mr-1" }), "Add Memory"] })] }), isLoadingMemories ? (jsx("div", { className: "space-y-3", children: [1, 2, 3].map((i) => (jsx(Skeleton, { className: "h-16 w-full rounded-lg" }, i))) })) : ((_c = memoriesData === null || memoriesData === void 0 ? void 0 : memoriesData.results) === null || _c === void 0 ? void 0 : _c.length) ? (jsx("div", { className: "space-y-3", children: memoriesData.results.map((memory) => (jsxs("div", { className: "group flex items-start gap-3 rounded-lg border px-4 py-3", style: { borderColor: 'oklch(.922 0 0)' }, children: [jsx("div", { className: "flex-shrink-0 mt-0.5", children: memory.is_auto_generated ? (jsx(Bot, { className: "h-4 w-4 text-blue-500", "aria-label": "Auto-generated memory" })) : (jsx(User, { className: "h-4 w-4 text-gray-400", "aria-label": "Manually added memory" })) }), jsxs("div", { className: "flex-1 min-w-0", children: [jsx("p", { className: "text-sm text-gray-800 dark:text-gray-200", children: memory.content }), jsxs("p", { className: "text-xs text-gray-400 mt-1", children: [new Date(memory.created_at).toLocaleDateString(), memory.is_auto_generated && (jsx("span", { className: "ml-2 inline-flex items-center rounded-full bg-blue-50 px-1.5 py-0.5 text-[10px] font-medium text-blue-600", children: "auto" }))] })] }), jsx("button", { type: "button", onClick: () => handleDeleteMemory(memory.id), disabled: deletingId === memory.id, className: "flex-shrink-0 opacity-0 group-hover:opacity-100 transition-opacity p-1 rounded hover:bg-gray-100 text-gray-400 hover:text-gray-600 focus:opacity-100 focus:outline-none focus:ring-2 focus:ring-gray-300", "aria-label": `Delete memory: ${memory.content.substring(0, 30)}`, children: deletingId === memory.id ? (jsx("div", { className: "w-4 h-4 border-2 border-gray-500 border-t-transparent rounded-full animate-spin" })) : (jsx(Delete$1, { className: "h-4 w-4" })) })] }, memory.id))) })) : (jsx("div", { className: "rounded-lg border px-6 py-8 text-center", style: { borderColor: 'oklch(.922 0 0)' }, children: jsx("p", { className: "text-sm text-gray-500", children: "No memories yet. The AI will start remembering information from your conversations, or you can add memories manually." }) })), memoriesData && memoriesData.count > 25 && (jsxs("p", { className: "text-xs text-gray-400 text-center", children: ["Showing 25 of ", memoriesData.count, " memories"] }))] }), jsx(AddMemoryDialog, { open: isAddDialogOpen, onOpenChange: setIsAddDialogOpen, org: org, username: username })] }));
82159
+ return (jsxs("div", { className: "max-w-2xl space-y-8", children: [jsxs("div", { className: "space-y-4", children: [jsx("h4", { className: "text-sm font-semibold text-gray-700 dark:text-gray-300 tracking-wide", children: "Memory & Personalization" }), jsxs("div", { className: "flex items-center justify-between rounded-lg border px-6 py-5", style: { borderColor: 'oklch(.922 0 0)' }, children: [jsxs("div", { className: "flex-1 mr-4", children: [jsx("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: "Allow AI to learn from our conversations" }), jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400 mt-1", children: "When enabled, the AI will remember useful information from your chats to provide better assistance." })] }), jsx(Switch, { checked: (_a = settings === null || settings === void 0 ? void 0 : settings.auto_capture_enabled) !== null && _a !== void 0 ? _a : false, onCheckedChange: (checked) => handleToggleSetting('auto_capture_enabled', checked), disabled: isUpdatingSettings, "aria-label": `Auto memory capture ${(settings === null || settings === void 0 ? void 0 : settings.auto_capture_enabled) ? 'enabled' : 'disabled'}`, className: "cursor-pointer data-[state=checked]:bg-blue-500 flex-shrink-0" })] }), jsxs("div", { className: "flex items-center justify-between rounded-lg border px-6 py-5", style: { borderColor: 'oklch(.922 0 0)' }, children: [jsxs("div", { className: "flex-1 mr-4", children: [jsx("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: "Use my saved information in responses" }), jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400 mt-1", children: "When enabled, the AI will use what it knows about you to personalize responses." })] }), jsx(Switch, { checked: (_b = settings === null || settings === void 0 ? void 0 : settings.use_memory_in_responses) !== null && _b !== void 0 ? _b : false, onCheckedChange: (checked) => handleToggleSetting('use_memory_in_responses', checked), disabled: isUpdatingSettings, "aria-label": `Use memory in responses ${(settings === null || settings === void 0 ? void 0 : settings.use_memory_in_responses) ? 'enabled' : 'disabled'}`, className: "cursor-pointer data-[state=checked]:bg-blue-500 flex-shrink-0" })] })] }), jsxs("div", { className: "space-y-4", children: [jsxs("div", { className: "flex items-center justify-between", children: [jsx("h4", { className: "text-sm font-semibold text-gray-700 dark:text-gray-300 tracking-wide", children: "My Memories" }), jsxs(Button$1, { variant: "outline", size: "sm", onClick: () => setIsAddDialogOpen(true), className: "text-xs", children: [jsx(Plus, { className: "h-3 w-3 mr-1" }), "Add Memory"] })] }), isLoadingMemories ? (jsx("div", { className: "space-y-3", children: [1, 2, 3].map((i) => (jsx(Skeleton, { className: "h-16 w-full rounded-lg" }, i))) })) : ((_c = memoriesData === null || memoriesData === void 0 ? void 0 : memoriesData.results) === null || _c === void 0 ? void 0 : _c.length) ? (jsx("div", { className: "space-y-3", children: memoriesData.results.map((memory) => (jsxs("div", { className: "group flex items-start gap-3 rounded-lg border px-4 py-3", style: { borderColor: 'oklch(.922 0 0)' }, children: [jsx("div", { className: "flex-shrink-0 mt-0.5", children: memory.is_auto_generated ? (jsx(Bot, { className: "h-4 w-4 text-blue-500", "aria-label": "Auto-generated memory" })) : (jsx(User, { className: "h-4 w-4 text-gray-400", "aria-label": "Manually added memory" })) }), jsxs("div", { className: "flex-1 min-w-0", children: [jsx("p", { className: "text-sm text-gray-800 dark:text-gray-200", children: memory.content }), jsxs("p", { className: "text-xs text-gray-400 mt-1", children: [new Date(memory.created_at).toLocaleDateString(), memory.is_auto_generated && (jsx("span", { className: "ml-2 inline-flex items-center rounded-full bg-blue-50 px-1.5 py-0.5 text-[10px] font-medium text-blue-600", children: "auto" }))] })] }), jsx("button", { type: "button", onClick: () => handleDeleteMemory(memory.id), disabled: deletingId === memory.id, className: "flex-shrink-0 opacity-0 group-hover:opacity-100 transition-opacity p-1 rounded hover:bg-gray-100 text-gray-400 hover:text-gray-600 focus:opacity-100 focus:outline-none focus:ring-2 focus:ring-gray-300", "aria-label": `Delete memory: ${memory.content.substring(0, 30)}`, children: deletingId === memory.id ? (jsx("div", { className: "w-4 h-4 border-2 border-gray-500 border-t-transparent rounded-full animate-spin" })) : (jsx(Trash2, { className: "h-4 w-4" })) })] }, memory.id))) })) : (jsx("div", { className: "rounded-lg border px-6 py-8 text-center", style: { borderColor: 'oklch(.922 0 0)' }, children: jsx("p", { className: "text-sm text-gray-500", children: "No memories yet. The AI will start remembering information from your conversations, or you can add memories manually." }) })), totalPages > 1 && (jsx(IblPagination, { currentPage: currentPage, totalPages: totalPages, onPageChange: setCurrentPage, disabled: isLoadingMemories }))] }), jsx(AddMemoryDialog, { open: isAddDialogOpen, onOpenChange: setIsAddDialogOpen, org: org, username: username })] }));
82095
82160
  }
82096
82161
 
82097
82162
  const renderLucideIcon = (Icon) => function RenderedIcon(props) {
@@ -82105,17 +82170,17 @@ function Profile({ tenant, username, onClose, customization = {}, isAdmin = fals
82105
82170
  isUsingFoundry: localLLMProps === null || localLLMProps === void 0 ? void 0 : localLLMProps.isUsingFoundry,
82106
82171
  hasFoundryStatus: 'foundryStatus' in (localLLMProps || {}),
82107
82172
  });
82108
- const { data: memsearchConfig, isError: isMemsearchConfigError, isLoading: isMemsearchConfigLoading, error: memsearchConfigError, } = useGetMemsearchConfigQuery({ org: tenant, userId: username }, { skip: !enableMemoryTab });
82109
- console.log('[Profile] memsearch config debug:', {
82173
+ const { data: memsearchStatus, isError: isMemsearchStatusError, isLoading: isMemsearchStatusLoading, error: memsearchStatusError, } = useGetMemsearchStatusQuery({ org: tenant, userId: username }, { skip: !enableMemoryTab });
82174
+ console.log('[Profile] memsearch status debug:', {
82110
82175
  enableMemoryTab,
82111
- isMemsearchConfigLoading,
82112
- isMemsearchConfigError,
82113
- memsearchConfigError,
82114
- memsearchConfig,
82115
- enable_memsearch: memsearchConfig === null || memsearchConfig === void 0 ? void 0 : memsearchConfig.enable_memsearch,
82116
- });
82117
- // Show memory tab if enabled for this platform AND memsearch is enabled (or config API is unavailable)
82118
- const isMemoryEnabled = enableMemoryTab && (isMemsearchConfigError || ((_a = memsearchConfig === null || memsearchConfig === void 0 ? void 0 : memsearchConfig.enable_memsearch) !== null && _a !== void 0 ? _a : false));
82176
+ isMemsearchStatusLoading,
82177
+ isMemsearchStatusError,
82178
+ memsearchStatusError,
82179
+ memsearchStatus,
82180
+ enable_memsearch: memsearchStatus === null || memsearchStatus === void 0 ? void 0 : memsearchStatus.enable_memsearch,
82181
+ });
82182
+ // Show memory tab if enabled for this platform AND memsearch is enabled (or status API is unavailable)
82183
+ const isMemoryEnabled = enableMemoryTab && (isMemsearchStatusError || ((_a = memsearchStatus === null || memsearchStatus === void 0 ? void 0 : memsearchStatus.enable_memsearch) !== null && _a !== void 0 ? _a : false));
82119
82184
  const baseTabs = [
82120
82185
  { id: 'basic', label: 'Basic', renderIcon: renderLucideIcon(User) },
82121
82186
  { id: 'social', label: 'Social', renderIcon: renderLucideIcon(Globe) },
@@ -7,7 +7,7 @@ import Link$2 from 'next/link';
7
7
  import * as ReactDOM from 'react-dom';
8
8
  import ReactDOM__default from 'react-dom';
9
9
  import { z as z$1 } from 'zod';
10
- import { useGetUserMetadataQuery, useGetUserMetadataEdxQuery, useUpdateUserMetadataMutation, useUpdateUserMetadataEdxMutation, useUploadProfileImageMutation, useResetPasswordMutation, useSelfRetireMutation, useCreateUserInstitutionMutation, useGetUserInstitutionsQuery, useCreateUserEducationMutation, useUpdateUserEducationMutation, useDeleteUserEducationMutation, useGetUserEducationQuery, useCreateUserCompanyMutation, useGetUserCompaniesQuery, useCreateUserExperienceMutation, useUpdateUserExperienceMutation, useDeleteUserExperienceMutation, useGetUserExperienceQuery, useGetUserResumeQuery, useCreateUserResumeMutation, useGetMySubscriptionsQuery, useGetItemSubscriptionQuery, useCancelSubscriptionMutation, useCreateGlobalMemoryMutation, useGetMemsearchConfigQuery, useGetUserMemorySettingsQuery, useUpdateUserMemorySettingsMutation, useGetGlobalMemoriesQuery, useDeleteGlobalMemoryMutation, useInviteUserMutation, usePlatformInvitationsQuery, useCreateCatalogInvitationCourseBulkMutation, useGetCatalogInvitationsCourseQuery, useLazyPlatformUsersQuery, useLazyPlatformUserGroupsQuery, useGetPersonnalizedSearchQuery, useCreateCatalogInvitationProgramBulkMutation, useGetCatalogInvitationsProgramQuery, useLazyGetCourseMetaDataQuery, useLazyGetCourseCompletionOutlinesQuery, useLazyGetCourseEligibilityQuery, useLazyGetEdxSSOTokenQuery, useCreateCourseEnrollmentMutation, useCreateStripeCheckoutSessionMutation, useLazyGetCourseProgressQuery, useLazyGetCourseCompletionQuery, useUpdateExamAttemptMutation, useStartExamMutation, useLazyGetExamInfoQuery, useUpdateUserRoleMutation, useUpdateUserStatusMutation, useUpdatePlatformUserRoleWithPoliciesMutation, usePlatformUsersQuery, isPoliciesResponse, platformApiSlice, featureTags, useLazyGetRbacTeamsAccessListQuery, useCreateRbacTeamsAccessMutation, useGetRbacGroupsQuery, usePlatformUserGroupsQuery, useCreateRbacGroupMutation, useUpdateRbacGroupMutation, useDeleteRbacGroupMutation, useCreatePlatformUserGroupMutation, useUpdatePlatformUserGroupMutation, useDeletePlatformUserGroupMutation, useGetRbacGroupDetailsQuery, useGetPlatformUserGroupDetailsQuery, useGetRbacPermissionsMutation, useGetRbacRolesQuery, useCreateRbacRoleMutation, useUpdateRbacRoleMutation, useDeleteRbacRoleMutation, useGetRbacRoleDetailsQuery, useGetRbacPoliciesQuery, useCreateRbacPolicyMutation, useUpdateRbacPolicyMutation, useDeleteRbacPolicyMutation, useGetRbacPolicyDetailsQuery, useUploadLightLogoMutation, useUploadDarkLogoMutation, useUpdatePlatformInfoMutation, useUpdateTenantMetadataMutation, LOGO_ENDPOINTS, useDeleteApiKeyMutation, useGetApiKeysQuery, useCreateApiKeyMutation, useCreateLLMCredentialMutation, useGetCredentialsSchemaQuery, useGetMaskedLLMCredentialsQuery, useGetLlmsQuery, useDeleteIntegrationCredentialMutation, useDeleteCredentialMutation, useCreateIntegrationCredentialMutation, useGetIntegrationCredentialsSchemaQuery, useGetMaskedIntegrationCredentialsQuery, useGetAccountBillingInfoQuery, useUpdateAutoRechargeInfoMutation, useTriggerAutoRechargeMutation, useCreateStripeCustomerPortalMutation, useSetPlatformConfigurationsMutation, useGetPlatformConfigurationsQuery, useUpdatePlatformMembershipMutation, useGetPlatformMembershipQuery, useGetCustomDomainsQuery, useCreateCustomDomainMutation, useDeleteCustomDomainMutation, useGetStudentMentorCreationStatusQuery, useSetStudentMentorCreationStatusMutation, coreApiSlice, recommendationPromptTypeEnum, useGetRecommendedPromptsListQuery, useCreateRecommendedPromptMutation, useUpdateRecommendedPromptMutation, useDeleteRecommendedPromptMutation, useLazyGetPublicPlatformImageAssetFileUrlQuery, useCreatePlatformImageAssetMutation, useGetProviderConfigQuery, useCreateProviderConfigMutation, useDeleteProviderConfigMutation, useGetExternalMappingQuery, useGetCredentialsListQuery, useCreateExternalMappingMutation, useDeleteExternalMappingMutation, useUpdateMemsearchConfigMutation, useGetCustomMentorsQuery, useGetStripeConnectStatusQuery, useStartStripeConnectOnboardingMutation, useLazyGetStripeConnectDashboardQuery, useListPricesQuery, useCreatePriceMutation, useUpdatePriceMutation, useDeletePriceMutation, useGetPaywallConfigQuery, useEnablePaywallMutation, useDisablePaywallMutation, useListPaywallsQuery, useGetAiSearchMentorsQuery, useCreateSessionIdMutation } from '@iblai/data-layer';
10
+ import { useGetUserMetadataQuery, useGetUserMetadataEdxQuery, useUpdateUserMetadataMutation, useUpdateUserMetadataEdxMutation, useUploadProfileImageMutation, useResetPasswordMutation, useSelfRetireMutation, useCreateUserInstitutionMutation, useGetUserInstitutionsQuery, useCreateUserEducationMutation, useUpdateUserEducationMutation, useDeleteUserEducationMutation, useGetUserEducationQuery, useCreateUserCompanyMutation, useGetUserCompaniesQuery, useCreateUserExperienceMutation, useUpdateUserExperienceMutation, useDeleteUserExperienceMutation, useGetUserExperienceQuery, useGetUserResumeQuery, useCreateUserResumeMutation, useGetMySubscriptionsQuery, useGetItemSubscriptionQuery, useCancelSubscriptionMutation, useCreateGlobalMemoryMutation, useGetMemsearchStatusQuery, useGetUserMemorySettingsQuery, useUpdateUserMemorySettingsMutation, useGetGlobalMemoriesQuery, useDeleteGlobalMemoryMutation, useInviteUserMutation, usePlatformInvitationsQuery, useCreateCatalogInvitationCourseBulkMutation, useGetCatalogInvitationsCourseQuery, useLazyPlatformUsersQuery, useLazyPlatformUserGroupsQuery, useGetPersonnalizedSearchQuery, useCreateCatalogInvitationProgramBulkMutation, useGetCatalogInvitationsProgramQuery, useLazyGetCourseMetaDataQuery, useLazyGetCourseCompletionOutlinesQuery, useLazyGetCourseEligibilityQuery, useLazyGetEdxSSOTokenQuery, useCreateCourseEnrollmentMutation, useCreateStripeCheckoutSessionMutation, useLazyGetCourseProgressQuery, useLazyGetCourseCompletionQuery, useUpdateExamAttemptMutation, useStartExamMutation, useLazyGetExamInfoQuery, useUpdateUserRoleMutation, useUpdateUserStatusMutation, useUpdatePlatformUserRoleWithPoliciesMutation, usePlatformUsersQuery, isPoliciesResponse, platformApiSlice, featureTags, useLazyGetRbacTeamsAccessListQuery, useCreateRbacTeamsAccessMutation, useGetRbacGroupsQuery, usePlatformUserGroupsQuery, useCreateRbacGroupMutation, useUpdateRbacGroupMutation, useDeleteRbacGroupMutation, useCreatePlatformUserGroupMutation, useUpdatePlatformUserGroupMutation, useDeletePlatformUserGroupMutation, useGetRbacGroupDetailsQuery, useGetPlatformUserGroupDetailsQuery, useGetRbacPermissionsMutation, useGetRbacRolesQuery, useCreateRbacRoleMutation, useUpdateRbacRoleMutation, useDeleteRbacRoleMutation, useGetRbacRoleDetailsQuery, useGetRbacPoliciesQuery, useCreateRbacPolicyMutation, useUpdateRbacPolicyMutation, useDeleteRbacPolicyMutation, useGetRbacPolicyDetailsQuery, useUploadLightLogoMutation, useUploadDarkLogoMutation, useUpdatePlatformInfoMutation, useUpdateTenantMetadataMutation, LOGO_ENDPOINTS, useDeleteApiKeyMutation, useGetApiKeysQuery, useCreateApiKeyMutation, useCreateLLMCredentialMutation, useGetCredentialsSchemaQuery, useGetMaskedLLMCredentialsQuery, useGetLlmsQuery, useDeleteIntegrationCredentialMutation, useDeleteCredentialMutation, useCreateIntegrationCredentialMutation, useGetIntegrationCredentialsSchemaQuery, useGetMaskedIntegrationCredentialsQuery, useGetAccountBillingInfoQuery, useUpdateAutoRechargeInfoMutation, useTriggerAutoRechargeMutation, useCreateStripeCustomerPortalMutation, useSetPlatformConfigurationsMutation, useGetPlatformConfigurationsQuery, useUpdatePlatformMembershipMutation, useGetPlatformMembershipQuery, useGetCustomDomainsQuery, useCreateCustomDomainMutation, useDeleteCustomDomainMutation, useGetStudentMentorCreationStatusQuery, useSetStudentMentorCreationStatusMutation, coreApiSlice, recommendationPromptTypeEnum, useGetRecommendedPromptsListQuery, useCreateRecommendedPromptMutation, useUpdateRecommendedPromptMutation, useDeleteRecommendedPromptMutation, useLazyGetPublicPlatformImageAssetFileUrlQuery, useCreatePlatformImageAssetMutation, useGetProviderConfigQuery, useCreateProviderConfigMutation, useDeleteProviderConfigMutation, useGetExternalMappingQuery, useGetCredentialsListQuery, useCreateExternalMappingMutation, useDeleteExternalMappingMutation, useGetMemsearchConfigQuery, useUpdateMemsearchConfigMutation, useGetCustomMentorsQuery, useGetStripeConnectStatusQuery, useStartStripeConnectOnboardingMutation, useLazyGetStripeConnectDashboardQuery, useListPricesQuery, useCreatePriceMutation, useUpdatePriceMutation, useDeletePriceMutation, useGetPaywallConfigQuery, useEnablePaywallMutation, useDisablePaywallMutation, useListPaywallsQuery, useGetAiSearchMentorsQuery, useCreateSessionIdMutation } from '@iblai/data-layer';
11
11
  import { toast, Toaster as Toaster$1 } from 'sonner';
12
12
  import { getInitials, useTenantMetadata, isAlphaNumeric32, checkRbacPermission, WithPermissions, useTenantContext, CHAT_AREA_SIZE, TimeTracker, advancedTabsProperties, defaultSessionIds, chatActions } from '@iblai/web-utils';
13
13
  import '@iblai/iblai-api';
@@ -81815,12 +81815,82 @@ function AddMemoryDialog({ open, onOpenChange, org, username }) {
81815
81815
  }, children: jsx(DialogContent$1, { className: "p-0 overflow-hidden max-w-lg", children: jsxs("form", { onSubmit: handleSubmit, children: [jsx("div", { className: "flex items-center justify-between px-6 py-4 border-b", children: jsx(DialogTitle$1, { className: "text-lg font-semibold text-gray-900", children: "Add Memory" }) }), jsx(DialogDescription$1, { className: "sr-only", children: "Add a new memory for the AI to remember about you" }), jsx("div", { className: "p-6 space-y-4", children: jsxs("div", { className: "space-y-2", children: [jsx(Label, { htmlFor: "memory-content", children: "What should the AI remember?" }), jsx(Textarea, { id: "memory-content", placeholder: "e.g., I prefer learning through practical examples rather than theory.", value: content, onChange: (e) => setContent(e.target.value), rows: 4, className: "w-full bg-gray-50 border-gray-200 focus:ring-blue-500 focus:border-blue-500 text-sm resize-none", disabled: isLoading }), content.length > 0 && content.trim().length < 10 && (jsx("p", { className: "text-sm text-red-500", children: "Must be at least 10 characters" }))] }) }), jsxs("div", { className: "flex justify-end gap-3 border-t px-6 py-4", children: [jsx(Button$1, { type: "button", variant: "outline", onClick: () => onOpenChange(false), disabled: isLoading, children: "Cancel" }), jsx(Button$1, { className: "bg-gradient-to-r from-[#2563EB] to-[#93C5FD] hover:opacity-90 text-white", type: "submit", disabled: isLoading || content.trim().length < 10, children: isLoading ? 'Saving...' : 'Save Memory' })] })] }) }) }));
81816
81816
  }
81817
81817
 
81818
+ const Pagination = ({ className, ...props }) => (jsx("nav", { role: "navigation", "aria-label": "pagination", className: cn("mx-auto flex w-full justify-center", className), ...props }));
81819
+ Pagination.displayName = "Pagination";
81820
+ const PaginationContent = React.forwardRef(({ className, ...props }, ref) => (jsx("ul", { ref: ref, className: cn("flex flex-row items-center gap-1", className), ...props })));
81821
+ PaginationContent.displayName = "PaginationContent";
81822
+ const PaginationItem = React.forwardRef(({ className, ...props }, ref) => (jsx("li", { ref: ref, className: cn("", className), ...props })));
81823
+ PaginationItem.displayName = "PaginationItem";
81824
+ const PaginationLink = ({ className, isActive, size = "icon", ...props }) => (jsx("a", { "aria-current": isActive ? "page" : undefined, className: cn(buttonVariants({
81825
+ variant: isActive ? "outline" : "ghost",
81826
+ size,
81827
+ }), className), ...props }));
81828
+ PaginationLink.displayName = "PaginationLink";
81829
+ const PaginationPrevious = ({ className, ...props }) => (jsxs(PaginationLink, { "aria-label": "Go to previous page", size: "default", className: cn("gap-1 pl-2.5", className), ...props, children: [jsx(ChevronLeft, { className: "h-4 w-4" }), jsx("span", { children: "Previous" })] }));
81830
+ PaginationPrevious.displayName = "PaginationPrevious";
81831
+ const PaginationNext = ({ className, ...props }) => (jsxs(PaginationLink, { "aria-label": "Go to next page", size: "default", className: cn("gap-1 pr-2.5", className), ...props, children: [jsx("span", { children: "Next" }), jsx(ChevronRight, { className: "h-4 w-4" })] }));
81832
+ PaginationNext.displayName = "PaginationNext";
81833
+ const PaginationEllipsis = ({ className, ...props }) => (jsxs("span", { "aria-hidden": true, className: cn("flex h-9 w-9 items-center justify-center", className), ...props, children: [jsx(Ellipsis, { className: "h-4 w-4" }), jsx("span", { className: "sr-only", children: "More pages" })] }));
81834
+ PaginationEllipsis.displayName = "PaginationEllipsis";
81835
+
81836
+ const IblPagination = ({ currentPage, totalPages, onPageChange, disabled = false, disableNumberedButtons = false, }) => {
81837
+ const getPageNumbers = () => {
81838
+ const pages = [];
81839
+ pages.push(1);
81840
+ let startPage = Math.max(2, currentPage - 1);
81841
+ let endPage = Math.min(totalPages - 1, currentPage + 1);
81842
+ if (currentPage <= 2) {
81843
+ endPage = Math.min(totalPages - 1, 4);
81844
+ }
81845
+ else if (currentPage >= totalPages - 1) {
81846
+ startPage = Math.max(2, totalPages - 3);
81847
+ }
81848
+ if (startPage > 2) {
81849
+ pages.push('ellipsis-start');
81850
+ }
81851
+ for (let i = startPage; i <= endPage; i++) {
81852
+ if (i !== 1 && i !== totalPages) {
81853
+ pages.push(i);
81854
+ }
81855
+ }
81856
+ if (endPage < totalPages - 1) {
81857
+ pages.push('ellipsis-end');
81858
+ }
81859
+ if (totalPages > 1) {
81860
+ pages.push(totalPages);
81861
+ }
81862
+ return pages;
81863
+ };
81864
+ if (totalPages <= 1) {
81865
+ return null;
81866
+ }
81867
+ return (jsx(Pagination, { children: jsxs(PaginationContent, { children: [jsx(PaginationItem, { children: jsx(PaginationPrevious, { size: "sm", onClick: (e) => {
81868
+ e.preventDefault();
81869
+ if (!disabled && currentPage > 1) {
81870
+ onPageChange(currentPage - 1);
81871
+ }
81872
+ }, "aria-disabled": currentPage === 1 || disabled, className: cn('cursor-pointer', (currentPage === 1 || disabled) && 'pointer-events-none opacity-50') }) }), !disableNumberedButtons &&
81873
+ getPageNumbers().map((page, index) => (jsx(PaginationItem, { children: page === 'ellipsis-start' || page === 'ellipsis-end' ? (jsx(PaginationEllipsis, {})) : (jsx(PaginationLink, { size: "sm", onClick: (e) => {
81874
+ e.preventDefault();
81875
+ if (!disabled && typeof page === 'number') {
81876
+ onPageChange(page);
81877
+ }
81878
+ }, isActive: page === currentPage, className: cn('cursor-pointer', disabled && 'pointer-events-none opacity-50'), children: page })) }, index))), jsx(PaginationItem, { children: jsx(PaginationNext, { size: "sm", onClick: (e) => {
81879
+ e.preventDefault();
81880
+ if (!disabled && currentPage < totalPages) {
81881
+ onPageChange(currentPage + 1);
81882
+ }
81883
+ }, "aria-disabled": currentPage === totalPages || disabled, className: cn('cursor-pointer', (currentPage === totalPages || disabled) && 'pointer-events-none opacity-50') }) })] }) }));
81884
+ };
81885
+
81886
+ const MEMORIES_PAGE_SIZE = 25;
81818
81887
  function MemoryTab({ org, username }) {
81819
81888
  var _a, _b, _c;
81820
81889
  const [isAddDialogOpen, setIsAddDialogOpen] = useState(false);
81821
81890
  const [deletingId, setDeletingId] = useState(null);
81822
- // Platform memsearch config
81823
- const { data: memsearchConfig, isLoading: isLoadingConfig, isError: isConfigError, } = useGetMemsearchConfigQuery({
81891
+ const [currentPage, setCurrentPage] = useState(1);
81892
+ // Platform memsearch status (available to students and admins)
81893
+ const { data: memsearchStatus, isLoading: isLoadingConfig, isError: isConfigError, } = useGetMemsearchStatusQuery({
81824
81894
  org,
81825
81895
  userId: username,
81826
81896
  });
@@ -81834,8 +81904,9 @@ function MemoryTab({ org, username }) {
81834
81904
  const { data: memoriesData, isLoading: isLoadingMemories } = useGetGlobalMemoriesQuery({
81835
81905
  org,
81836
81906
  userId: username,
81837
- params: { page_size: 25 },
81907
+ params: { page: currentPage, page_size: MEMORIES_PAGE_SIZE },
81838
81908
  });
81909
+ const totalPages = (memoriesData === null || memoriesData === void 0 ? void 0 : memoriesData.count) ? Math.ceil(memoriesData.count / MEMORIES_PAGE_SIZE) : 0;
81839
81910
  const [deleteMemory] = useDeleteGlobalMemoryMutation();
81840
81911
  const handleToggleSetting = async (key, checked) => {
81841
81912
  try {
@@ -81871,10 +81942,10 @@ function MemoryTab({ org, username }) {
81871
81942
  return (jsxs("div", { className: "max-w-2xl space-y-6", children: [jsx(Skeleton, { className: "h-20 w-full rounded-lg" }), jsx(Skeleton, { className: "h-20 w-full rounded-lg" }), jsx(Skeleton, { className: "h-40 w-full rounded-lg" })] }));
81872
81943
  }
81873
81944
  // Hide memory UI when platform has disabled memsearch (skip check if API errored)
81874
- if (!isConfigError && memsearchConfig && !memsearchConfig.enable_memsearch) {
81945
+ if (!isConfigError && memsearchStatus && !memsearchStatus.enable_memsearch) {
81875
81946
  return (jsx("div", { className: "max-w-2xl", children: jsx("div", { className: "rounded-lg border px-6 py-8 text-center", style: { borderColor: 'oklch(.922 0 0)' }, children: jsx("p", { className: "text-sm text-gray-500", children: "The memory feature is not enabled for this platform. Contact your administrator to enable it." }) }) }));
81876
81947
  }
81877
- return (jsxs("div", { className: "max-w-2xl space-y-8", children: [jsxs("div", { className: "space-y-4", children: [jsx("h4", { className: "text-sm font-semibold text-gray-700 dark:text-gray-300 tracking-wide", children: "Memory & Personalization" }), jsxs("div", { className: "flex items-center justify-between rounded-lg border px-6 py-5", style: { borderColor: 'oklch(.922 0 0)' }, children: [jsxs("div", { className: "flex-1 mr-4", children: [jsx("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: "Allow AI to learn from our conversations" }), jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400 mt-1", children: "When enabled, the AI will remember useful information from your chats to provide better assistance." })] }), jsx(Switch, { checked: (_a = settings === null || settings === void 0 ? void 0 : settings.auto_capture_enabled) !== null && _a !== void 0 ? _a : false, onCheckedChange: (checked) => handleToggleSetting('auto_capture_enabled', checked), disabled: isUpdatingSettings, "aria-label": `Auto memory capture ${(settings === null || settings === void 0 ? void 0 : settings.auto_capture_enabled) ? 'enabled' : 'disabled'}`, className: "cursor-pointer data-[state=checked]:bg-blue-500 flex-shrink-0" })] }), jsxs("div", { className: "flex items-center justify-between rounded-lg border px-6 py-5", style: { borderColor: 'oklch(.922 0 0)' }, children: [jsxs("div", { className: "flex-1 mr-4", children: [jsx("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: "Use my saved information in responses" }), jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400 mt-1", children: "When enabled, the AI will use what it knows about you to personalize responses." })] }), jsx(Switch, { checked: (_b = settings === null || settings === void 0 ? void 0 : settings.use_memory_in_responses) !== null && _b !== void 0 ? _b : false, onCheckedChange: (checked) => handleToggleSetting('use_memory_in_responses', checked), disabled: isUpdatingSettings, "aria-label": `Use memory in responses ${(settings === null || settings === void 0 ? void 0 : settings.use_memory_in_responses) ? 'enabled' : 'disabled'}`, className: "cursor-pointer data-[state=checked]:bg-blue-500 flex-shrink-0" })] })] }), jsxs("div", { className: "space-y-4", children: [jsxs("div", { className: "flex items-center justify-between", children: [jsx("h4", { className: "text-sm font-semibold text-gray-700 dark:text-gray-300 tracking-wide", children: "My Memories" }), jsxs(Button$1, { variant: "outline", size: "sm", onClick: () => setIsAddDialogOpen(true), className: "text-xs", children: [jsx(Plus, { className: "h-3 w-3 mr-1" }), "Add Memory"] })] }), isLoadingMemories ? (jsx("div", { className: "space-y-3", children: [1, 2, 3].map((i) => (jsx(Skeleton, { className: "h-16 w-full rounded-lg" }, i))) })) : ((_c = memoriesData === null || memoriesData === void 0 ? void 0 : memoriesData.results) === null || _c === void 0 ? void 0 : _c.length) ? (jsx("div", { className: "space-y-3", children: memoriesData.results.map((memory) => (jsxs("div", { className: "group flex items-start gap-3 rounded-lg border px-4 py-3", style: { borderColor: 'oklch(.922 0 0)' }, children: [jsx("div", { className: "flex-shrink-0 mt-0.5", children: memory.is_auto_generated ? (jsx(Bot, { className: "h-4 w-4 text-blue-500", "aria-label": "Auto-generated memory" })) : (jsx(User, { className: "h-4 w-4 text-gray-400", "aria-label": "Manually added memory" })) }), jsxs("div", { className: "flex-1 min-w-0", children: [jsx("p", { className: "text-sm text-gray-800 dark:text-gray-200", children: memory.content }), jsxs("p", { className: "text-xs text-gray-400 mt-1", children: [new Date(memory.created_at).toLocaleDateString(), memory.is_auto_generated && (jsx("span", { className: "ml-2 inline-flex items-center rounded-full bg-blue-50 px-1.5 py-0.5 text-[10px] font-medium text-blue-600", children: "auto" }))] })] }), jsx("button", { type: "button", onClick: () => handleDeleteMemory(memory.id), disabled: deletingId === memory.id, className: "flex-shrink-0 opacity-0 group-hover:opacity-100 transition-opacity p-1 rounded hover:bg-gray-100 text-gray-400 hover:text-gray-600 focus:opacity-100 focus:outline-none focus:ring-2 focus:ring-gray-300", "aria-label": `Delete memory: ${memory.content.substring(0, 30)}`, children: deletingId === memory.id ? (jsx("div", { className: "w-4 h-4 border-2 border-gray-500 border-t-transparent rounded-full animate-spin" })) : (jsx(Delete$1, { className: "h-4 w-4" })) })] }, memory.id))) })) : (jsx("div", { className: "rounded-lg border px-6 py-8 text-center", style: { borderColor: 'oklch(.922 0 0)' }, children: jsx("p", { className: "text-sm text-gray-500", children: "No memories yet. The AI will start remembering information from your conversations, or you can add memories manually." }) })), memoriesData && memoriesData.count > 25 && (jsxs("p", { className: "text-xs text-gray-400 text-center", children: ["Showing 25 of ", memoriesData.count, " memories"] }))] }), jsx(AddMemoryDialog, { open: isAddDialogOpen, onOpenChange: setIsAddDialogOpen, org: org, username: username })] }));
81948
+ return (jsxs("div", { className: "max-w-2xl space-y-8", children: [jsxs("div", { className: "space-y-4", children: [jsx("h4", { className: "text-sm font-semibold text-gray-700 dark:text-gray-300 tracking-wide", children: "Memory & Personalization" }), jsxs("div", { className: "flex items-center justify-between rounded-lg border px-6 py-5", style: { borderColor: 'oklch(.922 0 0)' }, children: [jsxs("div", { className: "flex-1 mr-4", children: [jsx("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: "Allow AI to learn from our conversations" }), jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400 mt-1", children: "When enabled, the AI will remember useful information from your chats to provide better assistance." })] }), jsx(Switch, { checked: (_a = settings === null || settings === void 0 ? void 0 : settings.auto_capture_enabled) !== null && _a !== void 0 ? _a : false, onCheckedChange: (checked) => handleToggleSetting('auto_capture_enabled', checked), disabled: isUpdatingSettings, "aria-label": `Auto memory capture ${(settings === null || settings === void 0 ? void 0 : settings.auto_capture_enabled) ? 'enabled' : 'disabled'}`, className: "cursor-pointer data-[state=checked]:bg-blue-500 flex-shrink-0" })] }), jsxs("div", { className: "flex items-center justify-between rounded-lg border px-6 py-5", style: { borderColor: 'oklch(.922 0 0)' }, children: [jsxs("div", { className: "flex-1 mr-4", children: [jsx("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: "Use my saved information in responses" }), jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400 mt-1", children: "When enabled, the AI will use what it knows about you to personalize responses." })] }), jsx(Switch, { checked: (_b = settings === null || settings === void 0 ? void 0 : settings.use_memory_in_responses) !== null && _b !== void 0 ? _b : false, onCheckedChange: (checked) => handleToggleSetting('use_memory_in_responses', checked), disabled: isUpdatingSettings, "aria-label": `Use memory in responses ${(settings === null || settings === void 0 ? void 0 : settings.use_memory_in_responses) ? 'enabled' : 'disabled'}`, className: "cursor-pointer data-[state=checked]:bg-blue-500 flex-shrink-0" })] })] }), jsxs("div", { className: "space-y-4", children: [jsxs("div", { className: "flex items-center justify-between", children: [jsx("h4", { className: "text-sm font-semibold text-gray-700 dark:text-gray-300 tracking-wide", children: "My Memories" }), jsxs(Button$1, { variant: "outline", size: "sm", onClick: () => setIsAddDialogOpen(true), className: "text-xs", children: [jsx(Plus, { className: "h-3 w-3 mr-1" }), "Add Memory"] })] }), isLoadingMemories ? (jsx("div", { className: "space-y-3", children: [1, 2, 3].map((i) => (jsx(Skeleton, { className: "h-16 w-full rounded-lg" }, i))) })) : ((_c = memoriesData === null || memoriesData === void 0 ? void 0 : memoriesData.results) === null || _c === void 0 ? void 0 : _c.length) ? (jsx("div", { className: "space-y-3", children: memoriesData.results.map((memory) => (jsxs("div", { className: "group flex items-start gap-3 rounded-lg border px-4 py-3", style: { borderColor: 'oklch(.922 0 0)' }, children: [jsx("div", { className: "flex-shrink-0 mt-0.5", children: memory.is_auto_generated ? (jsx(Bot, { className: "h-4 w-4 text-blue-500", "aria-label": "Auto-generated memory" })) : (jsx(User, { className: "h-4 w-4 text-gray-400", "aria-label": "Manually added memory" })) }), jsxs("div", { className: "flex-1 min-w-0", children: [jsx("p", { className: "text-sm text-gray-800 dark:text-gray-200", children: memory.content }), jsxs("p", { className: "text-xs text-gray-400 mt-1", children: [new Date(memory.created_at).toLocaleDateString(), memory.is_auto_generated && (jsx("span", { className: "ml-2 inline-flex items-center rounded-full bg-blue-50 px-1.5 py-0.5 text-[10px] font-medium text-blue-600", children: "auto" }))] })] }), jsx("button", { type: "button", onClick: () => handleDeleteMemory(memory.id), disabled: deletingId === memory.id, className: "flex-shrink-0 opacity-0 group-hover:opacity-100 transition-opacity p-1 rounded hover:bg-gray-100 text-gray-400 hover:text-gray-600 focus:opacity-100 focus:outline-none focus:ring-2 focus:ring-gray-300", "aria-label": `Delete memory: ${memory.content.substring(0, 30)}`, children: deletingId === memory.id ? (jsx("div", { className: "w-4 h-4 border-2 border-gray-500 border-t-transparent rounded-full animate-spin" })) : (jsx(Trash2, { className: "h-4 w-4" })) })] }, memory.id))) })) : (jsx("div", { className: "rounded-lg border px-6 py-8 text-center", style: { borderColor: 'oklch(.922 0 0)' }, children: jsx("p", { className: "text-sm text-gray-500", children: "No memories yet. The AI will start remembering information from your conversations, or you can add memories manually." }) })), totalPages > 1 && (jsx(IblPagination, { currentPage: currentPage, totalPages: totalPages, onPageChange: setCurrentPage, disabled: isLoadingMemories }))] }), jsx(AddMemoryDialog, { open: isAddDialogOpen, onOpenChange: setIsAddDialogOpen, org: org, username: username })] }));
81878
81949
  }
81879
81950
 
81880
81951
  const renderLucideIcon = (Icon) => function RenderedIcon(props) {
@@ -81888,17 +81959,17 @@ function Profile({ tenant, username, onClose, customization = {}, isAdmin = fals
81888
81959
  isUsingFoundry: localLLMProps === null || localLLMProps === void 0 ? void 0 : localLLMProps.isUsingFoundry,
81889
81960
  hasFoundryStatus: 'foundryStatus' in (localLLMProps || {}),
81890
81961
  });
81891
- const { data: memsearchConfig, isError: isMemsearchConfigError, isLoading: isMemsearchConfigLoading, error: memsearchConfigError, } = useGetMemsearchConfigQuery({ org: tenant, userId: username }, { skip: !enableMemoryTab });
81892
- console.log('[Profile] memsearch config debug:', {
81962
+ const { data: memsearchStatus, isError: isMemsearchStatusError, isLoading: isMemsearchStatusLoading, error: memsearchStatusError, } = useGetMemsearchStatusQuery({ org: tenant, userId: username }, { skip: !enableMemoryTab });
81963
+ console.log('[Profile] memsearch status debug:', {
81893
81964
  enableMemoryTab,
81894
- isMemsearchConfigLoading,
81895
- isMemsearchConfigError,
81896
- memsearchConfigError,
81897
- memsearchConfig,
81898
- enable_memsearch: memsearchConfig === null || memsearchConfig === void 0 ? void 0 : memsearchConfig.enable_memsearch,
81965
+ isMemsearchStatusLoading,
81966
+ isMemsearchStatusError,
81967
+ memsearchStatusError,
81968
+ memsearchStatus,
81969
+ enable_memsearch: memsearchStatus === null || memsearchStatus === void 0 ? void 0 : memsearchStatus.enable_memsearch,
81899
81970
  });
81900
- // Show memory tab if enabled for this platform AND memsearch is enabled (or config API is unavailable)
81901
- const isMemoryEnabled = enableMemoryTab && (isMemsearchConfigError || ((_a = memsearchConfig === null || memsearchConfig === void 0 ? void 0 : memsearchConfig.enable_memsearch) !== null && _a !== void 0 ? _a : false));
81971
+ // Show memory tab if enabled for this platform AND memsearch is enabled (or status API is unavailable)
81972
+ const isMemoryEnabled = enableMemoryTab && (isMemsearchStatusError || ((_a = memsearchStatus === null || memsearchStatus === void 0 ? void 0 : memsearchStatus.enable_memsearch) !== null && _a !== void 0 ? _a : false));
81902
81973
  const baseTabs = [
81903
81974
  { id: 'basic', label: 'Basic', renderIcon: renderLucideIcon(User) },
81904
81975
  { id: 'social', label: 'Social', renderIcon: renderLucideIcon(Globe) },
@@ -115700,22 +115771,6 @@ AlertDialogAction.displayName = Action.displayName;
115700
115771
  const AlertDialogCancel = React.forwardRef(({ className, ...props }, ref) => (jsx(Cancel, { ref: ref, className: cn(buttonVariants({ variant: 'outline' }), 'mt-2 sm:mt-0', className), ...props })));
115701
115772
  AlertDialogCancel.displayName = Cancel.displayName;
115702
115773
 
115703
- const Pagination = ({ className, ...props }) => (jsx("nav", { role: "navigation", "aria-label": "pagination", className: cn("mx-auto flex w-full justify-center", className), ...props }));
115704
- Pagination.displayName = "Pagination";
115705
- const PaginationContent = React.forwardRef(({ className, ...props }, ref) => (jsx("ul", { ref: ref, className: cn("flex flex-row items-center gap-1", className), ...props })));
115706
- PaginationContent.displayName = "PaginationContent";
115707
- const PaginationItem = React.forwardRef(({ className, ...props }, ref) => (jsx("li", { ref: ref, className: cn("", className), ...props })));
115708
- PaginationItem.displayName = "PaginationItem";
115709
- const PaginationLink = ({ className, isActive, size = "icon", ...props }) => (jsx("a", { "aria-current": isActive ? "page" : undefined, className: cn(buttonVariants({
115710
- variant: isActive ? "outline" : "ghost",
115711
- size,
115712
- }), className), ...props }));
115713
- PaginationLink.displayName = "PaginationLink";
115714
- const PaginationPrevious = ({ className, ...props }) => (jsxs(PaginationLink, { "aria-label": "Go to previous page", size: "default", className: cn("gap-1 pl-2.5", className), ...props, children: [jsx(ChevronLeft, { className: "h-4 w-4" }), jsx("span", { children: "Previous" })] }));
115715
- PaginationPrevious.displayName = "PaginationPrevious";
115716
- const PaginationNext = ({ className, ...props }) => (jsxs(PaginationLink, { "aria-label": "Go to next page", size: "default", className: cn("gap-1 pr-2.5", className), ...props, children: [jsx("span", { children: "Next" }), jsx(ChevronRight, { className: "h-4 w-4" })] }));
115717
- PaginationNext.displayName = "PaginationNext";
115718
-
115719
115774
  const AdvancedPagination = ({ currentPage, totalPages, onPageChange, siblingCount = 1, }) => {
115720
115775
  const generateRange = () => {
115721
115776
  const totalNumbers = siblingCount * 2 + 5;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iblai/iblai-js",
3
- "version": "1.4.0",
3
+ "version": "1.4.2",
4
4
  "description": "Unified JavaScript SDK for IBL.ai — re-exports data-layer, web-containers, and web-utils under a single package",
5
5
  "type": "module",
6
6
  "engines": {
@@ -61,9 +61,9 @@
61
61
  "axios": "1.13.6",
62
62
  "dotenv": "16.6.1",
63
63
  "winston": "3.19.0",
64
- "@iblai/data-layer": "1.3.0",
65
- "@iblai/web-containers": "1.3.0",
64
+ "@iblai/data-layer": "1.3.2",
66
65
  "@iblai/mcp": "1.3.0",
66
+ "@iblai/web-containers": "1.3.2",
67
67
  "@iblai/web-utils": "1.2.8"
68
68
  },
69
69
  "peerDependencies": {