@iblai/data-layer 1.18.1 → 1.19.0

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
@@ -48424,6 +48424,396 @@ const USER_CHAT_HISTORY_REPORT_ACTIVE_STATES = [
48424
48424
  'storing',
48425
48425
  ];
48426
48426
 
48427
+ const USER_LLM_USAGE_REDUCER_PATH = 'userLlmUsageApiSlice';
48428
+ const USER_LLM_USAGE_QUERY_KEYS = {
48429
+ GET_USER_LLM_USAGE: () => ['USER_LLM_USAGE'],
48430
+ };
48431
+ /** Upstream cap on `limit`. */
48432
+ const USER_LLM_USAGE_MAX_LIMIT = 1000;
48433
+ /**
48434
+ * The same llm-usage endpoint the admin analytics use, always scoped to one
48435
+ * `username`. The path builder is the admin one, so array params (`measures`)
48436
+ * serialize identically — comma-joined — and empty values are dropped the
48437
+ * same way.
48438
+ */
48439
+ const USER_LLM_USAGE_ENDPOINTS = {
48440
+ GET_USER_LLM_USAGE: {
48441
+ service: exports.SERVICES.DM,
48442
+ path: ({ resource, ...rest }) => NON_AI_ANALYTICS_ENDPOINTS.GET_LLM_USAGE.path(resource, rest),
48443
+ },
48444
+ };
48445
+ /**
48446
+ * User-safe fallbacks per error kind. None of them echo the backend's detail,
48447
+ * so a 403 or 404 never tells the viewer whether another user or tenant exists.
48448
+ */
48449
+ const USER_LLM_USAGE_ERROR_MESSAGES = {
48450
+ forbidden: 'Usage data is not available for this account.',
48451
+ not_found: 'Usage data is not available for this account.',
48452
+ unauthorized: 'Your session has expired. Sign in again to see your usage.',
48453
+ unavailable: 'Usage data is temporarily unavailable. Please try again later.',
48454
+ invalid_params: 'This usage request is not supported.',
48455
+ unknown: 'Something went wrong while loading your usage.',
48456
+ };
48457
+
48458
+ const RESOURCES = ['metrics', 'traces', 'observations'];
48459
+ /** Params the backend refuses on the observations resource. */
48460
+ const NOT_ON_OBSERVATIONS = ['session_id', 'mentor_unique_id'];
48461
+ const isSet = (value) => value !== undefined && value !== null && value !== '';
48462
+ /**
48463
+ * Runtime twin of the param types, for params assembled dynamically where the
48464
+ * compiler cannot see them. Runs before every request, so an invalid
48465
+ * combination never leaves the browser.
48466
+ */
48467
+ function validateUserLlmUsageParams(params) {
48468
+ if (!params || typeof params !== 'object') {
48469
+ return { ok: false, reason: 'params must be an object' };
48470
+ }
48471
+ const p = params;
48472
+ if (!RESOURCES.includes(p.resource)) {
48473
+ return { ok: false, reason: `unknown resource "${String(p.resource)}"` };
48474
+ }
48475
+ if (typeof p.platform_key !== 'string' || p.platform_key.trim() === '') {
48476
+ return { ok: false, reason: 'platform_key is required' };
48477
+ }
48478
+ if (typeof p.username !== 'string' || p.username.trim() === '') {
48479
+ // Without it the backend falls back to the caller's own scope, which for
48480
+ // an admin is every user on the platform.
48481
+ return { ok: false, reason: 'username is required' };
48482
+ }
48483
+ if (p.resource === 'observations') {
48484
+ const offending = NOT_ON_OBSERVATIONS.find((key) => isSet(p[key]));
48485
+ if (offending) {
48486
+ return { ok: false, reason: `${offending} is not allowed on observations` };
48487
+ }
48488
+ }
48489
+ const hasDates = isSet(p.start_date) || isSet(p.end_date);
48490
+ if (p.date_filter === 'custom') {
48491
+ if (!isSet(p.start_date) || !isSet(p.end_date)) {
48492
+ return { ok: false, reason: 'a custom range needs both start_date and end_date' };
48493
+ }
48494
+ }
48495
+ else if (hasDates) {
48496
+ return { ok: false, reason: 'start_date/end_date require date_filter "custom"' };
48497
+ }
48498
+ if (isSet(p.limit)) {
48499
+ const limit = Number(p.limit);
48500
+ if (!Number.isInteger(limit) || limit < 1 || limit > USER_LLM_USAGE_MAX_LIMIT) {
48501
+ return { ok: false, reason: `limit must be between 1 and ${USER_LLM_USAGE_MAX_LIMIT}` };
48502
+ }
48503
+ }
48504
+ return { ok: true, params: params };
48505
+ }
48506
+ const errorFor = (kind, status) => ({
48507
+ kind,
48508
+ ...(status !== undefined && { status }),
48509
+ message: USER_LLM_USAGE_ERROR_MESSAGES[kind],
48510
+ });
48511
+ /**
48512
+ * Maps whatever a usage query failed with onto a typed, user-safe error.
48513
+ * The backend's own `detail`/`error` text is never carried over.
48514
+ *
48515
+ * A 401 is reported as `unauthorized` for completeness, but it has already
48516
+ * gone through the app's registered auth handler (token refresh, then the
48517
+ * host's 401 handler) inside the base query before it gets here.
48518
+ */
48519
+ function normalizeUserLlmUsageError(error) {
48520
+ if (error === undefined || error === null)
48521
+ return null;
48522
+ if (typeof error !== 'object')
48523
+ return errorFor('unknown');
48524
+ const { status, data } = error;
48525
+ if (status === 'CUSTOM_ERROR') {
48526
+ const kind = data === null || data === void 0 ? void 0 : data.kind;
48527
+ return errorFor(kind === 'invalid_params' ? 'invalid_params' : 'unknown', status);
48528
+ }
48529
+ if (status === 'FETCH_ERROR' || status === 'TIMEOUT_ERROR') {
48530
+ return errorFor('unavailable', status);
48531
+ }
48532
+ if (typeof status === 'number') {
48533
+ if (status === 401)
48534
+ return errorFor('unauthorized', status);
48535
+ if (status === 403)
48536
+ return errorFor('forbidden', status);
48537
+ if (status === 404)
48538
+ return errorFor('not_found', status);
48539
+ if (status === 502 || status === 503 || status === 504)
48540
+ return errorFor('unavailable', status);
48541
+ return errorFor('unknown', status);
48542
+ }
48543
+ return errorFor('unknown');
48544
+ }
48545
+ /**
48546
+ * Wraps the raw response so `data` is always a list. Single-item lookups
48547
+ * (`trace_id`, `observation_id`) come back as one object without `meta`.
48548
+ */
48549
+ function toUserLlmUsageEnvelope(raw, resource) {
48550
+ const body = (raw && typeof raw === 'object' ? raw : {});
48551
+ const data = Array.isArray(body.data)
48552
+ ? body.data
48553
+ : body.data && typeof body.data === 'object'
48554
+ ? [body.data]
48555
+ : [];
48556
+ const envelope = { resource, data };
48557
+ if (resource !== 'metrics' && body.meta) {
48558
+ envelope.meta = body.meta;
48559
+ }
48560
+ return envelope;
48561
+ }
48562
+ /**
48563
+ * Empty-state rule shared by every usage hook: paginated resources trust
48564
+ * `meta.totalItems`; metrics (and unpaginated lookups) fall back to the rows.
48565
+ */
48566
+ function isUserLlmUsageEmpty(envelope) {
48567
+ if (!envelope)
48568
+ return false;
48569
+ if (envelope.meta && typeof envelope.meta.totalItems === 'number') {
48570
+ return envelope.meta.totalItems === 0;
48571
+ }
48572
+ return envelope.data.length === 0;
48573
+ }
48574
+ /** Reads a numeric measure (`sum_totalCost`, `avg_latency`, …) off a metrics row. */
48575
+ function readMeasure(row, key) {
48576
+ const value = row === null || row === void 0 ? void 0 : row[key];
48577
+ if (typeof value === 'number' && Number.isFinite(value))
48578
+ return value;
48579
+ if (typeof value === 'string' && value.trim() !== '' && Number.isFinite(Number(value))) {
48580
+ return Number(value);
48581
+ }
48582
+ return 0;
48583
+ }
48584
+
48585
+ /**
48586
+ * One request through the app's standard base query (auth header, token
48587
+ * refresh, registered 401 handler). `iblFetchBaseQuery` throws on HTTP
48588
+ * errors, and a thrown error would reach RTK as a SerializedError with the
48589
+ * status stripped; catching it here keeps `{ status, data }` intact so the
48590
+ * view can tell a 403 from a 404.
48591
+ */
48592
+ async function fetchUserLlmUsage(params, api, extraOptions) {
48593
+ const check = validateUserLlmUsageParams(params);
48594
+ if (!check.ok) {
48595
+ return {
48596
+ error: {
48597
+ status: 'CUSTOM_ERROR',
48598
+ error: check.reason,
48599
+ data: { kind: 'invalid_params', error: check.reason },
48600
+ },
48601
+ };
48602
+ }
48603
+ try {
48604
+ const result = await iblFetchBaseQuery({
48605
+ url: USER_LLM_USAGE_ENDPOINTS.GET_USER_LLM_USAGE.path(check.params),
48606
+ service: USER_LLM_USAGE_ENDPOINTS.GET_USER_LLM_USAGE.service,
48607
+ }, api, extraOptions);
48608
+ if ('error' in result && result.error) {
48609
+ return { error: result.error };
48610
+ }
48611
+ return { data: toUserLlmUsageEnvelope(result.data, params.resource) };
48612
+ }
48613
+ catch (error) {
48614
+ return { error: error };
48615
+ }
48616
+ }
48617
+ /**
48618
+ * Per-user llm-usage queries. Registered in the mentor and skills stores.
48619
+ * Cache entries are keyed on the full param object, so `platform_key`,
48620
+ * `username`, `resource` and every filter take part in the key.
48621
+ */
48622
+ const userLlmUsageApiSlice = react.createApi({
48623
+ reducerPath: USER_LLM_USAGE_REDUCER_PATH,
48624
+ baseQuery: iblFakeBaseQuery,
48625
+ tagTypes: [...USER_LLM_USAGE_QUERY_KEYS.GET_USER_LLM_USAGE()],
48626
+ endpoints: (builder) => ({
48627
+ getUserLlmUsageMetrics: builder.query({
48628
+ queryFn: (params, api, extraOptions) => fetchUserLlmUsage(params, api, extraOptions),
48629
+ providesTags: USER_LLM_USAGE_QUERY_KEYS.GET_USER_LLM_USAGE(),
48630
+ }),
48631
+ getUserLlmUsageTraces: builder.query({
48632
+ queryFn: (params, api, extraOptions) => fetchUserLlmUsage(params, api, extraOptions),
48633
+ providesTags: USER_LLM_USAGE_QUERY_KEYS.GET_USER_LLM_USAGE(),
48634
+ }),
48635
+ getUserLlmUsageObservations: builder.query({
48636
+ queryFn: (params, api, extraOptions) => fetchUserLlmUsage(params, api, extraOptions),
48637
+ providesTags: USER_LLM_USAGE_QUERY_KEYS.GET_USER_LLM_USAGE(),
48638
+ }),
48639
+ }),
48640
+ });
48641
+ const { useGetUserLlmUsageMetricsQuery, useGetUserLlmUsageTracesQuery, useGetUserLlmUsageObservationsQuery, } = userLlmUsageApiSlice;
48642
+
48643
+ /** A query needs a platform key and a user; without either it stays idle. */
48644
+ const shouldSkip = (params, options) => !!(options === null || options === void 0 ? void 0 : options.skip) || !params || !params.platform_key || !params.username;
48645
+ function useDerivedState(query, isIdle) {
48646
+ const { data, error, isLoading, isFetching, refetch } = query;
48647
+ return react$1.useMemo(() => {
48648
+ var _a;
48649
+ const normalized = isIdle ? null : normalizeUserLlmUsageError(error);
48650
+ return {
48651
+ rows: (_a = data === null || data === void 0 ? void 0 : data.data) !== null && _a !== void 0 ? _a : [],
48652
+ meta: data === null || data === void 0 ? void 0 : data.meta,
48653
+ // Only a successful load can be empty: an error or a pending first load
48654
+ // is not "no usage".
48655
+ isEmpty: !isIdle && !normalized && !isLoading && isUserLlmUsageEmpty(data),
48656
+ isIdle,
48657
+ isLoading: !isIdle && isLoading,
48658
+ isFetching: !isIdle && isFetching,
48659
+ error: normalized,
48660
+ refetch: () => {
48661
+ if (!isIdle)
48662
+ refetch();
48663
+ },
48664
+ };
48665
+ }, [data, error, isLoading, isFetching, refetch, isIdle]);
48666
+ }
48667
+ /** Any metrics query. Idle until `platform_key` and `username` are set. */
48668
+ function useUserLlmUsageMetrics(params, options) {
48669
+ const skip = shouldSkip(params, options);
48670
+ const query$1 = useGetUserLlmUsageMetricsQuery(skip || !params ? query.skipToken : params);
48671
+ return useDerivedState(query$1, skip);
48672
+ }
48673
+ /** Any traces query. Idle until `platform_key` and `username` are set. */
48674
+ function useUserLlmUsageTraces(params, options) {
48675
+ const skip = shouldSkip(params, options);
48676
+ const query$1 = useGetUserLlmUsageTracesQuery(skip || !params ? query.skipToken : params);
48677
+ return useDerivedState(query$1, skip);
48678
+ }
48679
+ /** Any observations query. Idle until `platform_key` and `username` are set. */
48680
+ function useUserLlmUsageObservations(params, options) {
48681
+ const skip = shouldSkip(params, options);
48682
+ const query$1 = useGetUserLlmUsageObservationsQuery(skip || !params ? query.skipToken : params);
48683
+ return useDerivedState(query$1, skip);
48684
+ }
48685
+ /**
48686
+ * `{ platformKey, username, ...range }` → the wire params, or null while
48687
+ * either identifier is still missing.
48688
+ */
48689
+ function scopeToParams(scope) {
48690
+ const { platformKey, username, ...range } = scope;
48691
+ if (!platformKey || !username)
48692
+ return null;
48693
+ return {
48694
+ platform_key: platformKey,
48695
+ username,
48696
+ ...range,
48697
+ };
48698
+ }
48699
+ // ---------------------------------------------------------------------------
48700
+ // Thin wrappers — one per view need. Each is the parameterized hook
48701
+ // above with the resource and measures filled in, plus a parsed view of the
48702
+ // rows so components never read `sum_totalCost`-style keys themselves.
48703
+ // ---------------------------------------------------------------------------
48704
+ /** Headline totals for the user: `measures=total_cost,total_tokens,count`, summed. */
48705
+ function useUserLlmUsageSummary(scope, options) {
48706
+ const base = scopeToParams(scope);
48707
+ const state = useUserLlmUsageMetrics(base && {
48708
+ ...base,
48709
+ resource: 'metrics',
48710
+ measures: ['total_cost', 'total_tokens', 'count'],
48711
+ aggregation: 'sum',
48712
+ }, options);
48713
+ return react$1.useMemo(() => {
48714
+ const row = state.rows[0];
48715
+ const summary = row
48716
+ ? {
48717
+ totalCost: readMeasure(row, 'sum_totalCost'),
48718
+ totalTokens: readMeasure(row, 'sum_totalTokens'),
48719
+ count: readMeasure(row, 'sum_count'),
48720
+ }
48721
+ : null;
48722
+ // The totals query always answers with one row; a row of zeros is still
48723
+ // "no usage in this range".
48724
+ const isEmpty = state.isEmpty || (!!summary && summary.count === 0 && summary.totalCost === 0);
48725
+ return { ...state, isEmpty, summary };
48726
+ }, [state]);
48727
+ }
48728
+ /** The user's spend per time bucket (`granularity=day` unless told otherwise). */
48729
+ function useUserLlmSpendOverTime(scope, options) {
48730
+ const { granularity = 'day', ...rest } = scope;
48731
+ const base = scopeToParams(rest);
48732
+ const state = useUserLlmUsageMetrics(base && {
48733
+ ...base,
48734
+ resource: 'metrics',
48735
+ measures: ['total_cost'],
48736
+ aggregation: 'sum',
48737
+ granularity,
48738
+ }, options);
48739
+ return react$1.useMemo(() => {
48740
+ const points = state.rows
48741
+ .filter((row) => typeof row.time_dimension === 'string' && row.time_dimension)
48742
+ .map((row) => ({
48743
+ date: String(row.time_dimension).slice(0, 10),
48744
+ totalCost: readMeasure(row, 'sum_totalCost'),
48745
+ }))
48746
+ .sort((a, b) => a.date.localeCompare(b.date));
48747
+ return { ...state, points };
48748
+ }, [state]);
48749
+ }
48750
+ /** The user's spend and call count per model, most expensive first. */
48751
+ function useUserLlmCostByModel(scope, options) {
48752
+ const { limit, ...rest } = scope;
48753
+ const base = scopeToParams(rest);
48754
+ const state = useUserLlmUsageMetrics(base && {
48755
+ ...base,
48756
+ resource: 'metrics',
48757
+ measures: ['total_cost', 'count'],
48758
+ aggregation: 'sum',
48759
+ group_by: 'model',
48760
+ order_by: 'total_cost',
48761
+ direction: 'desc',
48762
+ ...(limit !== undefined && { limit }),
48763
+ }, options);
48764
+ return react$1.useMemo(() => {
48765
+ const models = state.rows
48766
+ .map((row) => ({
48767
+ model: typeof row.providedModelName === 'string' ? row.providedModelName : '',
48768
+ totalCost: readMeasure(row, 'sum_totalCost'),
48769
+ count: readMeasure(row, 'sum_count'),
48770
+ }))
48771
+ .sort((a, b) => b.totalCost - a.totalCost);
48772
+ return { ...state, models };
48773
+ }, [state]);
48774
+ }
48775
+ /** The user's spend and call count per service (the trace name: chat, memory, …). */
48776
+ function useUserLlmCostByService(scope, options) {
48777
+ const base = scopeToParams(scope);
48778
+ const state = useUserLlmUsageMetrics(base && {
48779
+ ...base,
48780
+ resource: 'metrics',
48781
+ measures: ['total_cost', 'count'],
48782
+ aggregation: 'sum',
48783
+ group_by: 'type',
48784
+ }, options);
48785
+ return react$1.useMemo(() => {
48786
+ const services = state.rows
48787
+ .map((row) => ({
48788
+ service: typeof row.traceName === 'string' ? row.traceName : '',
48789
+ totalCost: readMeasure(row, 'sum_totalCost'),
48790
+ count: readMeasure(row, 'sum_count'),
48791
+ }))
48792
+ .sort((a, b) => b.totalCost - a.totalCost);
48793
+ return { ...state, services };
48794
+ }, [state]);
48795
+ }
48796
+ const USER_LLM_RECENT_ACTIVITY_PAGE_SIZE = 10;
48797
+ /** The user's traces, newest first, one page at a time. */
48798
+ function useUserLlmRecentActivity(scope, options) {
48799
+ const { page = 1, limit = USER_LLM_RECENT_ACTIVITY_PAGE_SIZE, ...rest } = scope;
48800
+ const base = scopeToParams(rest);
48801
+ return useUserLlmUsageTraces(base && {
48802
+ ...base,
48803
+ resource: 'traces',
48804
+ order_by: 'timestamp',
48805
+ direction: 'desc',
48806
+ page,
48807
+ limit,
48808
+ }, options);
48809
+ }
48810
+ /** The steps (observations) inside one trace. Idle until a trace is picked. */
48811
+ function useUserLlmTraceObservations(scope, options) {
48812
+ const { traceId, limit = 50, ...rest } = scope;
48813
+ const base = scopeToParams(rest);
48814
+ return useUserLlmUsageObservations(base && traceId ? { ...base, resource: 'observations', trace_id: traceId, limit } : null, options);
48815
+ }
48816
+
48427
48817
  const mentorReducer = {
48428
48818
  [mentorApiSlice.reducerPath]: mentorApiSlice.reducer,
48429
48819
  [tenantApiSlice.reducerPath]: tenantApiSlice.reducer,
@@ -48486,6 +48876,7 @@ const mentorReducer = {
48486
48876
  [gradingApiSlice.reducerPath]: gradingApiSlice.reducer,
48487
48877
  [spendCapsApiSlice.reducerPath]: spendCapsApiSlice.reducer,
48488
48878
  [userChatHistoryApiSlice.reducerPath]: userChatHistoryApiSlice.reducer,
48879
+ [userLlmUsageApiSlice.reducerPath]: userLlmUsageApiSlice.reducer,
48489
48880
  };
48490
48881
  const mentorMiddleware = [
48491
48882
  mentorApiSlice.middleware,
@@ -48549,6 +48940,7 @@ const mentorMiddleware = [
48549
48940
  gradingApiSlice.middleware,
48550
48941
  spendCapsApiSlice.middleware,
48551
48942
  userChatHistoryApiSlice.middleware,
48943
+ userLlmUsageApiSlice.middleware,
48552
48944
  ];
48553
48945
 
48554
48946
  const skillsReducer = {
@@ -48595,6 +48987,7 @@ const skillsReducer = {
48595
48987
  [chatPrivacyApiSlice.reducerPath]: chatPrivacyApiSlice.reducer,
48596
48988
  [agentSkillsApiSlice.reducerPath]: agentSkillsApiSlice.reducer,
48597
48989
  [userChatHistoryApiSlice.reducerPath]: userChatHistoryApiSlice.reducer,
48990
+ [userLlmUsageApiSlice.reducerPath]: userLlmUsageApiSlice.reducer,
48598
48991
  };
48599
48992
  const skillsMiddleware = [
48600
48993
  perLearnerApiSlice.middleware,
@@ -48640,6 +49033,7 @@ const skillsMiddleware = [
48640
49033
  chatPrivacyApiSlice.middleware,
48641
49034
  agentSkillsApiSlice.middleware,
48642
49035
  userChatHistoryApiSlice.middleware,
49036
+ userLlmUsageApiSlice.middleware,
48643
49037
  ];
48644
49038
 
48645
49039
  const initializeDataLayer = (dmUrl, lmsUrl, legacyLmsUrl, storageService, httpErrorHandler = {}, studioUrl, refreshAuthToken) => {
@@ -48751,6 +49145,12 @@ exports.USER_CHAT_HISTORY_ENDPOINTS = USER_CHAT_HISTORY_ENDPOINTS;
48751
49145
  exports.USER_CHAT_HISTORY_QUERY_KEYS = USER_CHAT_HISTORY_QUERY_KEYS;
48752
49146
  exports.USER_CHAT_HISTORY_REDUCER_PATH = USER_CHAT_HISTORY_REDUCER_PATH;
48753
49147
  exports.USER_CHAT_HISTORY_REPORT_ACTIVE_STATES = USER_CHAT_HISTORY_REPORT_ACTIVE_STATES;
49148
+ exports.USER_LLM_RECENT_ACTIVITY_PAGE_SIZE = USER_LLM_RECENT_ACTIVITY_PAGE_SIZE;
49149
+ exports.USER_LLM_USAGE_ENDPOINTS = USER_LLM_USAGE_ENDPOINTS;
49150
+ exports.USER_LLM_USAGE_ERROR_MESSAGES = USER_LLM_USAGE_ERROR_MESSAGES;
49151
+ exports.USER_LLM_USAGE_MAX_LIMIT = USER_LLM_USAGE_MAX_LIMIT;
49152
+ exports.USER_LLM_USAGE_QUERY_KEYS = USER_LLM_USAGE_QUERY_KEYS;
49153
+ exports.USER_LLM_USAGE_REDUCER_PATH = USER_LLM_USAGE_REDUCER_PATH;
48754
49154
  exports.USER_PROGRESS_DATA_POINTS = USER_PROGRESS_DATA_POINTS;
48755
49155
  exports.USER_PROGRESS_SUMMARY_TYPE = USER_PROGRESS_SUMMARY_TYPE;
48756
49156
  exports.WATCHED_GROUPS_ENDPOINTS = WATCHED_GROUPS_ENDPOINTS;
@@ -48804,6 +49204,7 @@ exports.evalTotalPages = evalTotalPages;
48804
49204
  exports.evaluationsApiSlice = evaluationsApiSlice;
48805
49205
  exports.fakeBaseQueryWithLogging = fakeBaseQueryWithLogging;
48806
49206
  exports.featureTags = featureTags;
49207
+ exports.fetchUserLlmUsage = fetchUserLlmUsage;
48807
49208
  exports.filterCourseUserRoles = filterCourseUserRoles;
48808
49209
  exports.filterGlobalUserRoles = filterGlobalUserRoles;
48809
49210
  exports.filterOrgUserRoles = filterOrgUserRoles;
@@ -48818,6 +49219,7 @@ exports.isBaseAgentMentor = isBaseAgentMentor;
48818
49219
  exports.isPoliciesResponse = isPoliciesResponse;
48819
49220
  exports.isPrivacyBlockedError = isPrivacyBlockedError;
48820
49221
  exports.isSpendCapExceededErrorBody = isSpendCapExceededErrorBody;
49222
+ exports.isUserLlmUsageEmpty = isUserLlmUsageEmpty;
48821
49223
  exports.llmsApiSlice = llmsApiSlice;
48822
49224
  exports.mcpApiSlice = mcpApiSlice;
48823
49225
  exports.memoryApiSlice = memoryApiSlice;
@@ -48830,6 +49232,7 @@ exports.mentorReducer = mentorReducer;
48830
49232
  exports.moderationLogsApiReducer = moderationLogsApiReducer;
48831
49233
  exports.moderationLogsApiSlice = moderationLogsApiSlice;
48832
49234
  exports.monetizationApiSlice = monetizationApiSlice;
49235
+ exports.normalizeUserLlmUsageError = normalizeUserLlmUsageError;
48833
49236
  exports.notificationsApiSlice = notificationsApiSlice;
48834
49237
  exports.notificationsCustomApiSlice = notificationsCustomApiSlice;
48835
49238
  exports.perLearnerApiSlice = perLearnerApiSlice;
@@ -48839,6 +49242,7 @@ exports.platformApiSlice = platformApiSlice;
48839
49242
  exports.platformCustomApiSlice = platformCustomApiSlice;
48840
49243
  exports.projectsApiSlice = projectsApiSlice;
48841
49244
  exports.promptsApiSlice = promptsApiSlice;
49245
+ exports.readMeasure = readMeasure;
48842
49246
  exports.reportsApiSlice = reportsApiSlice;
48843
49247
  exports.resolveEffectiveAgentSkills = resolveEffectiveAgentSkills;
48844
49248
  exports.retirementApiSlice = retirementApiSlice;
@@ -48854,6 +49258,7 @@ exports.supportTicketsApiSlice = supportTicketsApiSlice;
48854
49258
  exports.tenantApiReducer = tenantApiReducer;
48855
49259
  exports.tenantApiSlice = tenantApiSlice;
48856
49260
  exports.tenantLogoApiSlice = tenantLogoApiSlice;
49261
+ exports.toUserLlmUsageEnvelope = toUserLlmUsageEnvelope;
48857
49262
  exports.toolsApiSlice = toolsApiSlice;
48858
49263
  exports.trainingDocumentsApiSlice = trainingDocumentsApiSlice;
48859
49264
  exports.unwrapApiTokenList = unwrapApiTokenList;
@@ -49271,6 +49676,9 @@ exports.useGetUserEnrolledProgramsQuery = useGetUserEnrolledProgramsQuery;
49271
49676
  exports.useGetUserExperienceQuery = useGetUserExperienceQuery;
49272
49677
  exports.useGetUserInstitutionsQuery = useGetUserInstitutionsQuery;
49273
49678
  exports.useGetUserInvitationsQuery = useGetUserInvitationsQuery;
49679
+ exports.useGetUserLlmUsageMetricsQuery = useGetUserLlmUsageMetricsQuery;
49680
+ exports.useGetUserLlmUsageObservationsQuery = useGetUserLlmUsageObservationsQuery;
49681
+ exports.useGetUserLlmUsageTracesQuery = useGetUserLlmUsageTracesQuery;
49274
49682
  exports.useGetUserMemorySettingsQuery = useGetUserMemorySettingsQuery;
49275
49683
  exports.useGetUserMetadataEdxQuery = useGetUserMetadataEdxQuery;
49276
49684
  exports.useGetUserMetadataQuery = useGetUserMetadataQuery;
@@ -49682,12 +50090,23 @@ exports.useUploadStudioScormPackageMutation = useUploadStudioScormPackageMutatio
49682
50090
  exports.useUpsertAgentSpendCapMutation = useUpsertAgentSpendCapMutation;
49683
50091
  exports.useUpsertTenantSpendCapMutation = useUpsertTenantSpendCapMutation;
49684
50092
  exports.useUpsertUserSpendCapMutation = useUpsertUserSpendCapMutation;
50093
+ exports.useUserLlmCostByModel = useUserLlmCostByModel;
50094
+ exports.useUserLlmCostByService = useUserLlmCostByService;
50095
+ exports.useUserLlmRecentActivity = useUserLlmRecentActivity;
50096
+ exports.useUserLlmSpendOverTime = useUserLlmSpendOverTime;
50097
+ exports.useUserLlmTraceObservations = useUserLlmTraceObservations;
50098
+ exports.useUserLlmUsageMetrics = useUserLlmUsageMetrics;
50099
+ exports.useUserLlmUsageObservations = useUserLlmUsageObservations;
50100
+ exports.useUserLlmUsageSummary = useUserLlmUsageSummary;
50101
+ exports.useUserLlmUsageTraces = useUserLlmUsageTraces;
49685
50102
  exports.useUsersGradesPassedQuery = useUsersGradesPassedQuery;
49686
50103
  exports.useValidateWorkflowMutation = useValidateWorkflowMutation;
49687
50104
  exports.useWithdrawApplicationMutation = useWithdrawApplicationMutation;
49688
50105
  exports.userApiSlice = userApiSlice;
49689
50106
  exports.userChatHistoryApiSlice = userChatHistoryApiSlice;
49690
50107
  exports.userInvitationsApiSlice = userInvitationsApiSlice;
50108
+ exports.userLlmUsageApiSlice = userLlmUsageApiSlice;
50109
+ exports.validateUserLlmUsageParams = validateUserLlmUsageParams;
49691
50110
  exports.watchedGroupsApiSlice = watchedGroupsApiSlice;
49692
50111
  exports.workflowsApiSlice = workflowsApiSlice;
49693
50112
  //# sourceMappingURL=index.js.map