@iblai/data-layer 1.18.0 → 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.d.ts +812 -11
- package/dist/index.esm.js +397 -3
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +419 -0
- package/dist/index.js.map +1 -1
- package/dist/package.json +1 -1
- package/dist/src/features/analytics/types.d.ts +67 -8
- package/dist/src/features/user-chat-history/types.d.ts +5 -0
- package/dist/src/features/user-llm-usage/__tests__/api-slice.test.d.ts +1 -0
- package/dist/src/features/user-llm-usage/__tests__/hooks.test.d.ts +1 -0
- package/dist/src/features/user-llm-usage/__tests__/utils.test.d.ts +1 -0
- package/dist/src/features/user-llm-usage/api-slice.d.ts +488 -0
- package/dist/src/features/user-llm-usage/constants.d.ts +25 -0
- package/dist/src/features/user-llm-usage/hooks.d.ts +43 -0
- package/dist/src/features/user-llm-usage/types.d.ts +150 -0
- package/dist/src/features/user-llm-usage/utils.d.ts +35 -0
- package/dist/src/index.d.ts +5 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { LlmUsageMetricsRow, LlmUsageTrace } from '../analytics/types';
|
|
2
|
+
import type { UserLlmCostByModelRow, UserLlmCostByServiceRow, UserLlmSpendPoint, UserLlmUsageMetricsParams, UserLlmUsageObservation, UserLlmUsageObservationsParams, UserLlmUsageQueryState, UserLlmUsageScope, UserLlmUsageSummary, UserLlmUsageTracesParams } from './types';
|
|
3
|
+
export interface UserLlmUsageHookOptions {
|
|
4
|
+
/** Extra switch on top of the built-in platform-key guard. */
|
|
5
|
+
skip?: boolean;
|
|
6
|
+
}
|
|
7
|
+
/** Any metrics query. Idle until `platform_key` and `username` are set. */
|
|
8
|
+
export declare function useUserLlmUsageMetrics(params: UserLlmUsageMetricsParams | null | undefined, options?: UserLlmUsageHookOptions): UserLlmUsageQueryState<LlmUsageMetricsRow>;
|
|
9
|
+
/** Any traces query. Idle until `platform_key` and `username` are set. */
|
|
10
|
+
export declare function useUserLlmUsageTraces(params: UserLlmUsageTracesParams | null | undefined, options?: UserLlmUsageHookOptions): UserLlmUsageQueryState<LlmUsageTrace>;
|
|
11
|
+
/** Any observations query. Idle until `platform_key` and `username` are set. */
|
|
12
|
+
export declare function useUserLlmUsageObservations(params: UserLlmUsageObservationsParams | null | undefined, options?: UserLlmUsageHookOptions): UserLlmUsageQueryState<UserLlmUsageObservation>;
|
|
13
|
+
/** Headline totals for the user: `measures=total_cost,total_tokens,count`, summed. */
|
|
14
|
+
export declare function useUserLlmUsageSummary(scope: UserLlmUsageScope, options?: UserLlmUsageHookOptions): UserLlmUsageQueryState<LlmUsageMetricsRow> & {
|
|
15
|
+
summary: UserLlmUsageSummary | null;
|
|
16
|
+
};
|
|
17
|
+
/** The user's spend per time bucket (`granularity=day` unless told otherwise). */
|
|
18
|
+
export declare function useUserLlmSpendOverTime(scope: UserLlmUsageScope & {
|
|
19
|
+
granularity?: UserLlmUsageMetricsParams['granularity'];
|
|
20
|
+
}, options?: UserLlmUsageHookOptions): UserLlmUsageQueryState<LlmUsageMetricsRow> & {
|
|
21
|
+
points: UserLlmSpendPoint[];
|
|
22
|
+
};
|
|
23
|
+
/** The user's spend and call count per model, most expensive first. */
|
|
24
|
+
export declare function useUserLlmCostByModel(scope: UserLlmUsageScope & {
|
|
25
|
+
limit?: number;
|
|
26
|
+
}, options?: UserLlmUsageHookOptions): UserLlmUsageQueryState<LlmUsageMetricsRow> & {
|
|
27
|
+
models: UserLlmCostByModelRow[];
|
|
28
|
+
};
|
|
29
|
+
/** The user's spend and call count per service (the trace name: chat, memory, …). */
|
|
30
|
+
export declare function useUserLlmCostByService(scope: UserLlmUsageScope, options?: UserLlmUsageHookOptions): UserLlmUsageQueryState<LlmUsageMetricsRow> & {
|
|
31
|
+
services: UserLlmCostByServiceRow[];
|
|
32
|
+
};
|
|
33
|
+
export declare const USER_LLM_RECENT_ACTIVITY_PAGE_SIZE = 10;
|
|
34
|
+
/** The user's traces, newest first, one page at a time. */
|
|
35
|
+
export declare function useUserLlmRecentActivity(scope: UserLlmUsageScope & {
|
|
36
|
+
page?: number;
|
|
37
|
+
limit?: number;
|
|
38
|
+
}, options?: UserLlmUsageHookOptions): UserLlmUsageQueryState<LlmUsageTrace>;
|
|
39
|
+
/** The steps (observations) inside one trace. Idle until a trace is picked. */
|
|
40
|
+
export declare function useUserLlmTraceObservations(scope: UserLlmUsageScope & {
|
|
41
|
+
traceId: string | null | undefined;
|
|
42
|
+
limit?: number;
|
|
43
|
+
}, options?: UserLlmUsageHookOptions): UserLlmUsageQueryState<UserLlmUsageObservation>;
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import type { DateFilter, LlmUsageAggregation, LlmUsageGranularity, LlmUsageGroupBy, LlmUsageMeasure, LlmUsageMetricsRow, LlmUsageObservation, LlmUsagePaginationMeta, LlmUsageTrace } from '../analytics/types';
|
|
2
|
+
export type UserLlmUsageResource = 'metrics' | 'traces' | 'observations';
|
|
3
|
+
/**
|
|
4
|
+
* Services the platform emits traces for. Deployments emit others too
|
|
5
|
+
* (`rag`, `memory_context`, `guided_prompt_generation`, …), so any string is
|
|
6
|
+
* accepted while the known names still autocomplete.
|
|
7
|
+
*/
|
|
8
|
+
export type UserLlmUsageTraceName = 'chat' | 'call' | 'memory' | 'grading' | 'moderation' | 'embeddings' | (string & {});
|
|
9
|
+
export type UserLlmUsageDirection = 'asc' | 'desc';
|
|
10
|
+
/** Every range the endpoint knows except `custom`, which needs its own dates. */
|
|
11
|
+
export type UserLlmUsagePresetDateFilter = Exclude<DateFilter, 'custom'>;
|
|
12
|
+
/**
|
|
13
|
+
* Omitting `date_filter` means **today** upstream. `start_date`/`end_date`
|
|
14
|
+
* only exist alongside `date_filter: 'custom'`, and then both are required.
|
|
15
|
+
*/
|
|
16
|
+
export type UserLlmUsageDateRange = {
|
|
17
|
+
date_filter?: UserLlmUsagePresetDateFilter;
|
|
18
|
+
start_date?: never;
|
|
19
|
+
end_date?: never;
|
|
20
|
+
} | {
|
|
21
|
+
date_filter: 'custom';
|
|
22
|
+
start_date: string;
|
|
23
|
+
end_date: string;
|
|
24
|
+
};
|
|
25
|
+
interface UserLlmUsageCommonParams {
|
|
26
|
+
/** Always sent; the backend validates it against the caller's tenancy. */
|
|
27
|
+
platform_key: string;
|
|
28
|
+
/**
|
|
29
|
+
* The user whose usage this is — the profile being viewed, not necessarily
|
|
30
|
+
* the caller. Required, so a request can never silently widen to the
|
|
31
|
+
* caller's own scope (which for an admin is the whole platform).
|
|
32
|
+
*/
|
|
33
|
+
username: string;
|
|
34
|
+
trace_name?: UserLlmUsageTraceName;
|
|
35
|
+
llm_model?: string;
|
|
36
|
+
/** Upstream maximum is {@link USER_LLM_USAGE_MAX_LIMIT}. */
|
|
37
|
+
limit?: number;
|
|
38
|
+
}
|
|
39
|
+
export type UserLlmUsageMetricsParams = UserLlmUsageCommonParams & UserLlmUsageDateRange & {
|
|
40
|
+
resource: 'metrics';
|
|
41
|
+
/** Serialized as a comma-separated list. Upstream default: `total_cost`. */
|
|
42
|
+
measures?: LlmUsageMeasure[];
|
|
43
|
+
aggregation?: LlmUsageAggregation;
|
|
44
|
+
group_by?: LlmUsageGroupBy;
|
|
45
|
+
/** Turns the result into a time series bucketed by this unit. */
|
|
46
|
+
granularity?: LlmUsageGranularity;
|
|
47
|
+
session_id?: string;
|
|
48
|
+
mentor_unique_id?: string;
|
|
49
|
+
order_by?: LlmUsageMeasure;
|
|
50
|
+
direction?: UserLlmUsageDirection;
|
|
51
|
+
};
|
|
52
|
+
export type UserLlmUsageTracesParams = UserLlmUsageCommonParams & UserLlmUsageDateRange & {
|
|
53
|
+
resource: 'traces';
|
|
54
|
+
session_id?: string;
|
|
55
|
+
mentor_unique_id?: string;
|
|
56
|
+
order_by?: 'timestamp' | 'name' | 'session_id';
|
|
57
|
+
direction?: UserLlmUsageDirection;
|
|
58
|
+
page?: number;
|
|
59
|
+
/** Single-trace lookup; an id the caller cannot see answers 404. */
|
|
60
|
+
trace_id?: string;
|
|
61
|
+
};
|
|
62
|
+
export type UserLlmUsageObservationsParams = UserLlmUsageCommonParams & UserLlmUsageDateRange & {
|
|
63
|
+
resource: 'observations';
|
|
64
|
+
trace_id?: string;
|
|
65
|
+
observation_id?: string;
|
|
66
|
+
page?: number;
|
|
67
|
+
/** Not accepted on observations upstream (400) — scope with `trace_id`. */
|
|
68
|
+
session_id?: never;
|
|
69
|
+
/** Not accepted on observations upstream (403/400) — scope with `trace_id`. */
|
|
70
|
+
mentor_unique_id?: never;
|
|
71
|
+
};
|
|
72
|
+
/** Self-view request params, discriminated by `resource`. No `username`. */
|
|
73
|
+
export type UserLlmUsageParams = UserLlmUsageMetricsParams | UserLlmUsageTracesParams | UserLlmUsageObservationsParams;
|
|
74
|
+
/** Observation rows also carry flattened token counts next to `usage`. */
|
|
75
|
+
export type UserLlmUsageObservation = LlmUsageObservation & {
|
|
76
|
+
promptTokens?: number;
|
|
77
|
+
completionTokens?: number;
|
|
78
|
+
totalTokens?: number;
|
|
79
|
+
costDetails?: {
|
|
80
|
+
total?: number;
|
|
81
|
+
[key: string]: number | undefined;
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
/**
|
|
85
|
+
* The response envelope, with `data` always a list — single-item lookups
|
|
86
|
+
* (`trace_id` on traces, `observation_id` on observations) are wrapped. `meta`
|
|
87
|
+
* is only sent for paginated list pages of traces and observations.
|
|
88
|
+
*/
|
|
89
|
+
export interface UserLlmUsageEnvelope<R extends UserLlmUsageResource, Row> {
|
|
90
|
+
resource: R;
|
|
91
|
+
data: Row[];
|
|
92
|
+
meta?: R extends 'metrics' ? never : LlmUsagePaginationMeta;
|
|
93
|
+
}
|
|
94
|
+
export type UserLlmUsageMetricsResponse = UserLlmUsageEnvelope<'metrics', LlmUsageMetricsRow>;
|
|
95
|
+
export type UserLlmUsageTracesResponse = UserLlmUsageEnvelope<'traces', LlmUsageTrace>;
|
|
96
|
+
export type UserLlmUsageObservationsResponse = UserLlmUsageEnvelope<'observations', UserLlmUsageObservation>;
|
|
97
|
+
/**
|
|
98
|
+
* What the UI branches on. `forbidden` and `not_found` deliberately carry the
|
|
99
|
+
* same kind of neutral message whatever the backend said, so the view never
|
|
100
|
+
* reveals whether another user or tenant exists.
|
|
101
|
+
*/
|
|
102
|
+
export type UserLlmUsageErrorKind = 'forbidden' | 'not_found' | 'unauthorized' | 'unavailable' | 'invalid_params' | 'unknown';
|
|
103
|
+
export interface UserLlmUsageError {
|
|
104
|
+
kind: UserLlmUsageErrorKind;
|
|
105
|
+
/** HTTP status (or RTK's string status) when there was a response. */
|
|
106
|
+
status?: number | string;
|
|
107
|
+
/** A user-safe English fallback; UIs should prefer their own copy per `kind`. */
|
|
108
|
+
message: string;
|
|
109
|
+
}
|
|
110
|
+
/** Derived state every usage hook returns. */
|
|
111
|
+
export interface UserLlmUsageQueryState<Row> {
|
|
112
|
+
rows: Row[];
|
|
113
|
+
meta?: LlmUsagePaginationMeta;
|
|
114
|
+
/** True once loaded with nothing to show (`meta.totalItems === 0` or no rows). */
|
|
115
|
+
isEmpty: boolean;
|
|
116
|
+
/** True while the platform key or username is missing, so nothing was requested. */
|
|
117
|
+
isIdle: boolean;
|
|
118
|
+
isLoading: boolean;
|
|
119
|
+
isFetching: boolean;
|
|
120
|
+
error: UserLlmUsageError | null;
|
|
121
|
+
refetch: () => void;
|
|
122
|
+
}
|
|
123
|
+
/** Shared by the thin wrapper hooks: whose usage, on which tenant and window. */
|
|
124
|
+
export type UserLlmUsageScope = {
|
|
125
|
+
/** The current platform; hooks stay idle while it is empty. */
|
|
126
|
+
platformKey: string | null | undefined;
|
|
127
|
+
/** The profile being viewed; hooks stay idle while it is empty. */
|
|
128
|
+
username: string | null | undefined;
|
|
129
|
+
} & UserLlmUsageDateRange;
|
|
130
|
+
export interface UserLlmUsageSummary {
|
|
131
|
+
totalCost: number;
|
|
132
|
+
totalTokens: number;
|
|
133
|
+
count: number;
|
|
134
|
+
}
|
|
135
|
+
export interface UserLlmSpendPoint {
|
|
136
|
+
/** Bucket start as `YYYY-MM-DD`. */
|
|
137
|
+
date: string;
|
|
138
|
+
totalCost: number;
|
|
139
|
+
}
|
|
140
|
+
export interface UserLlmCostByModelRow {
|
|
141
|
+
model: string;
|
|
142
|
+
totalCost: number;
|
|
143
|
+
count: number;
|
|
144
|
+
}
|
|
145
|
+
export interface UserLlmCostByServiceRow {
|
|
146
|
+
service: string;
|
|
147
|
+
totalCost: number;
|
|
148
|
+
count: number;
|
|
149
|
+
}
|
|
150
|
+
export {};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { UserLlmUsageEnvelope, UserLlmUsageError, UserLlmUsageParams, UserLlmUsageResource } from './types';
|
|
2
|
+
export type UserLlmUsageValidation = {
|
|
3
|
+
ok: true;
|
|
4
|
+
params: UserLlmUsageParams;
|
|
5
|
+
} | {
|
|
6
|
+
ok: false;
|
|
7
|
+
reason: string;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Runtime twin of the param types, for params assembled dynamically where the
|
|
11
|
+
* compiler cannot see them. Runs before every request, so an invalid
|
|
12
|
+
* combination never leaves the browser.
|
|
13
|
+
*/
|
|
14
|
+
export declare function validateUserLlmUsageParams(params: unknown): UserLlmUsageValidation;
|
|
15
|
+
/**
|
|
16
|
+
* Maps whatever a usage query failed with onto a typed, user-safe error.
|
|
17
|
+
* The backend's own `detail`/`error` text is never carried over.
|
|
18
|
+
*
|
|
19
|
+
* A 401 is reported as `unauthorized` for completeness, but it has already
|
|
20
|
+
* gone through the app's registered auth handler (token refresh, then the
|
|
21
|
+
* host's 401 handler) inside the base query before it gets here.
|
|
22
|
+
*/
|
|
23
|
+
export declare function normalizeUserLlmUsageError(error: unknown): UserLlmUsageError | null;
|
|
24
|
+
/**
|
|
25
|
+
* Wraps the raw response so `data` is always a list. Single-item lookups
|
|
26
|
+
* (`trace_id`, `observation_id`) come back as one object without `meta`.
|
|
27
|
+
*/
|
|
28
|
+
export declare function toUserLlmUsageEnvelope<R extends UserLlmUsageResource, Row>(raw: unknown, resource: R): UserLlmUsageEnvelope<R, Row>;
|
|
29
|
+
/**
|
|
30
|
+
* Empty-state rule shared by every usage hook: paginated resources trust
|
|
31
|
+
* `meta.totalItems`; metrics (and unpaginated lookups) fall back to the rows.
|
|
32
|
+
*/
|
|
33
|
+
export declare function isUserLlmUsageEmpty(envelope: Pick<UserLlmUsageEnvelope<UserLlmUsageResource, unknown>, 'data' | 'meta'> | undefined): boolean;
|
|
34
|
+
/** Reads a numeric measure (`sum_totalCost`, `avg_latency`, …) off a metrics row. */
|
|
35
|
+
export declare function readMeasure(row: Record<string, unknown> | undefined, key: string): number;
|
package/dist/src/index.d.ts
CHANGED
|
@@ -139,6 +139,11 @@ export * from './features/watched-groups/types';
|
|
|
139
139
|
export * from './features/user-chat-history/api-slice';
|
|
140
140
|
export * from './features/user-chat-history/constants';
|
|
141
141
|
export * from './features/user-chat-history/types';
|
|
142
|
+
export * from './features/user-llm-usage/api-slice';
|
|
143
|
+
export * from './features/user-llm-usage/constants';
|
|
144
|
+
export * from './features/user-llm-usage/types';
|
|
145
|
+
export * from './features/user-llm-usage/utils';
|
|
146
|
+
export * from './features/user-llm-usage/hooks';
|
|
142
147
|
export * from './reducers';
|
|
143
148
|
export * from './utils';
|
|
144
149
|
export type { CustomQueryArgs } from './features/utils';
|