import * as React from 'react'; import { ReactNode } from 'react'; import { A as ApiDataInterface, J as JsonApiHydratedDataInterface } from '../../ApiDataInterface-BcZeXy5X.mjs'; import { A as AbstractApiData } from '../../AbstractApiData-XLhBP5Tl.mjs'; import { A as AbstractService } from '../../AbstractService-B0T7h8fX.mjs'; export { b as TokenUsageAdminBreakdownModule, T as TokenUsageAdminSummaryModule, a as TokenUsageAdminTimelineModule, c as configureTokenUsage, g as getTokenUsageCurrency, t as tokenUsageModules } from '../../config-n-ZpPmOL.mjs'; import '../../ApiRequestDataTypeInterface-CYEcRUrh.mjs'; import '../../types-Bq_UA8Lg.mjs'; import 'lucide-react'; interface TokenUsageAdminBreakdownInterface extends ApiDataInterface { get label(): string; get sublabel(): string | undefined; get cost(): number; get credits(): number; get tokensIn(): number; get tokensOut(): number; get cached(): number; get calls(): number; /** Company dimension only. */ get activeUsers(): number | undefined; /** Company dimension only. */ get monthlyCredits(): number | undefined; /** Company dimension only. */ get availableMonthlyCredits(): number | undefined; } interface TokenUsageAdminSummaryInterface extends ApiDataInterface { /** "customer" | "platform" | "total" */ get scope(): string; /** "current" | "previous" */ get window(): string; get cost(): number; get credits(): number; get tokensIn(): number; get tokensOut(): number; get cached(): number; get calls(): number; } interface TokenUsageAdminTimelineInterface extends ApiDataInterface { /** Backend declares this `type: "date"`, so it is a Date in memory. */ get bucket(): Date; get series(): string; get cost(): number; get credits(): number; get tokensIn(): number; get tokensOut(): number; get cached(): number; get calls(): number; } type Granularity = "day" | "week" | "month"; type StackBy = "scope" | "type" | "company"; type Dimension = "company" | "user" | "operation"; type Scope = "customer" | "platform"; type Metric = "cost" | "credits" | "tokens"; type TokenUsageAdminFilters = { /** ISO 8601 instant. */ from: string; /** ISO 8601 instant. */ to: string; companyId?: string; }; type TokenUsageAdminSummaryInput = { id: string; scope: string; window: string; cost: number; credits: number; tokensIn: number; tokensOut: number; cached: number; calls: number; }; type TokenUsageAdminTimelineInput = { id: string; /** Backend field type is "date" — emitted via formatLocalDate, never raw. */ bucket: Date; series: string; cost: number; credits: number; tokensIn: number; tokensOut: number; cached: number; calls: number; }; type TokenUsageAdminBreakdownInput = { id: string; label: string; sublabel?: string; cost: number; credits: number; tokensIn: number; tokensOut: number; cached: number; calls: number; activeUsers?: number; monthlyCredits?: number; availableMonthlyCredits?: number; }; type TokenUsageAdminFilterState = { /** ISO 8601 instant. */ from: string; /** ISO 8601 instant. */ to: string; granularity: Granularity; stackBy: StackBy; companyId?: string; metric: Metric; }; interface TokenUsageAdminContextType { summary: TokenUsageAdminSummaryInterface[]; timeline: TokenUsageAdminTimelineInterface[]; byCompany: TokenUsageAdminBreakdownInterface[]; byUser: TokenUsageAdminBreakdownInterface[]; /** Platform-side spend split by operation. Always empty in single-customer mode. */ /** Platform spend by operation — empty in single-customer mode. */ byOperation: TokenUsageAdminBreakdownInterface[]; /** Customer spend by operation — the customer-side mirror of byOperation. */ byCustomerOperation: TokenUsageAdminBreakdownInterface[]; companies: { id: string; label: string; }[]; filters: TokenUsageAdminFilterState; /** Merges a partial patch into the current filters; every key is optional. */ setFilters: (next: Partial) => void; /** `true` once a company filter is applied — the platform panels are meaningless then. */ singleCustomerMode: boolean; isLoading: boolean; error: string | null; } type TokenUsageAdminProviderProps = { children: ReactNode; /** Pre-select a company, which puts the page in single-customer mode from the first render. */ initialCompanyId?: string; /** ISO 8601 instant. Defaults to the start of the current month. */ initialFrom?: string; /** ISO 8601 instant. Defaults to now. */ initialTo?: string; /** Rows per ranked panel. Defaults to 10. */ topN?: number; /** Route the breadcrumb links back to. */ pageUrl?: string; }; /** * Owns every filter the administrative token-usage page reads, fetches the five * panels behind it, and publishes the filter bar into the page title bar. * * The filter bar is rendered into `title.functions` here — NOT in the container — * because `RoundPageContainer`'s title bar reads `title.functions` from * `SharedContext`, and a descendant cannot inject nodes into an ancestor's * provider value. That is why the filter state lives at this level. */ declare const TokenUsageAdminProvider: ({ children, initialCompanyId, initialFrom, initialTo, topN, pageUrl, }: TokenUsageAdminProviderProps) => React.JSX.Element; declare const useTokenUsageAdmin: () => TokenUsageAdminContextType; /** * Page body for the administrative token-usage dashboard. * * Stateless by design — every value it renders comes from * `useTokenUsageAdmin()`. The filter bar is deliberately NOT here: it belongs to * the page title bar, which `RoundPageContainer` fills from `SharedContext`, so * the provider publishes it (see TokenUsageAdminContext). */ declare function TokenUsageAdminContainer(): React.JSX.Element; type FilterState = { from: string; to: string; granularity: Granularity; companyId?: string; metric: Metric; }; type Props$6 = FilterState & { companies: { id: string; label: string; }[]; /** Receives ONLY the keys that changed. */ onChange: (next: Partial) => void; }; /** * The single control row above the KPI tiles. * * It is deliberately stateless: every control reports the one key it changed and * the owning context re-fetches. Keeping the whole filter state in one place is * what lets the page issue a single coordinated batch of requests instead of one * per control. */ declare function TokenUsageAdminFilterBar({ granularity, companyId, metric, companies, onChange }: Props$6): React.JSX.Element; type Props$5 = { /** The six summary rows: {customer, platform, total} × {current, previous}. */ summary: TokenUsageAdminSummaryInterface[]; metric: Metric; /** True when a company filter is applied — platform spend is then meaningless. */ singleCustomerMode: boolean; }; /** * The KPI header of the administrative token-usage page. * * Two lead tiles carry the cost centres — customer spend and platform spend — * each with its delta against the equal-length preceding window. Three * supporting tiles below carry the totals that give those two numbers context. * * The backend always returns both windows, which is why no tile has to branch on * a missing row: an absent scope is simply zero-filled here. */ declare function TokenUsageAdminTiles({ summary, metric, singleCustomerMode }: Props$5): React.JSX.Element; /** * Locale-free arithmetic for the token-usage surfaces. * * Everything that turns a number into a STRING lives in `./formatters` instead, * because it depends on the request's locale and the app's configured currency. * This file stays pure arithmetic so it needs neither. */ /** * The metric field set every admin token-usage resource carries. Declared * structurally so it accepts the summary, timeline and breakdown interfaces * alike — all three expose exactly these getters. */ type TokenUsageMetrics = { cost: number; credits: number; tokensIn: number; tokensOut: number; cached: number; calls: number; }; /** * Everything this component actually reads from a row. * * Declared STRUCTURALLY rather than as one of the breakdown interfaces on * purpose: the same list ranks administrative rows (which additionally carry * activeUsers / monthlyCredits / availableMonthlyCredits) and self-service * report rows (which do not). Narrowing this to the administrative interface * would force every self-service caller into a cast, and duplicating the * component would fork the ramp and the share arithmetic. */ type TokenUsageRankedRow = TokenUsageMetrics & { /** Row identity; the literal "other" marks the folded tail. */ id: string; label: string; }; type Props$4 = { /** Ranked rows, already ordered descending by the backend, "other" last. */ rows: TokenUsageRankedRow[]; metric: Metric; /** Copy shown when there is nothing to rank, already translated by the caller. */ emptyLabel: string; /** * Whether `row.label` is an operation TYPE (vocabulary the consuming app * translates) rather than an entity NAME (data, rendered verbatim). * * Company and user rows carry names — translating them would be nonsense — so * this defaults to false and only the platform-by-operation panel opts in. */ labelsAreOperationTypes?: boolean; }; /** * A ranked horizontal bar list — "who spent the most". * * This does a MAGNITUDE job, not a categorical one, so colour comes from a * single sequential ramp indexed by RANK POSITION, never from a categorical * palette keyed by entity. That is deliberate: a filter change reorders the * rows, and rank-indexed colour simply re-shades them instead of repainting a * company into another company's identity hue. * * There is exactly one series, so there is no legend: every bar is * direct-labelled with its value and its share of the total. */ declare function TokenUsageRankedBar({ rows, metric, emptyLabel, labelsAreOperationTypes }: Props$4): React.JSX.Element; type Props$3 = { rows: TokenUsageAdminBreakdownInterface[]; metric: Metric; }; /** * The numeric detail behind the ranked bars: every row, every metric column. * * The bars answer "who is biggest"; this answers "why". Sorting is client-side * because the whole ranked set — top-N plus the "other" rollup — is already in * memory, so a round trip would buy nothing. */ declare function TokenUsageBreakdownTable({ rows, metric }: Props$3): React.JSX.Element; type TokenUsageTimelineChartProps = { rows: TokenUsageAdminTimelineInterface[]; metric: Metric; stackBy: StackBy; className?: string; }; /** * Usage over time as a stacked bar chart. * * Colour does an IDENTITY job here — each stacked segment is a series, not a * magnitude — so it draws the fixed categorical order from `../lib/palette` and * never generates or cycles a hue: series past the ceiling are summed into a * single "other" segment painted in the palette's neutral. * * The palette's light-mode validator run carries a sub-3:1 contrast WARN on * three slots, which obliges a relief channel. That is why the legend and the * value-carrying tooltip below are not optional decoration: they are what makes * the low-contrast fills readable. */ declare function TokenUsageTimelineChart({ rows, metric, stackBy, className }: TokenUsageTimelineChartProps): React.JSX.Element; /** * One row of the administrative summary: a cost centre observed over one time * window. Six rows are returned per request — scope crossed with window — so the * KPI tiles can render a value and its delta without a second call. */ declare class TokenUsageAdminSummary extends AbstractApiData implements TokenUsageAdminSummaryInterface { private _scope; private _window; private _cost; private _credits; private _tokensIn; private _tokensOut; private _cached; private _calls; get scope(): string; get window(): string; get cost(): number; get credits(): number; get tokensIn(): number; get tokensOut(): number; get cached(): number; get calls(): number; rehydrate(data: JsonApiHydratedDataInterface): this; createJsonApi(data: TokenUsageAdminSummaryInput): any; } /** * One (bucket, series) cell of the usage-over-time chart. Rows arrive flat; the * chart pivots them into stacked columns. */ declare class TokenUsageAdminTimeline extends AbstractApiData implements TokenUsageAdminTimelineInterface { private _bucket; private _series; private _cost; private _credits; private _tokensIn; private _tokensOut; private _cached; private _calls; get bucket(): Date; get series(): string; get cost(): number; get credits(): number; get tokensIn(): number; get tokensOut(): number; get cached(): number; get calls(): number; rehydrate(data: JsonApiHydratedDataInterface): this; createJsonApi(data: TokenUsageAdminTimelineInput): any; } /** * One ranked row of a breakdown. The same shape serves all three dimensions — * company, user and operation — which is why the three "by-X" views collapse * into a single `breakdown?dimension=` call. * * `activeUsers` / `monthlyCredits` / `availableMonthlyCredits` are populated only * for `dimension=company`; they are absent on user and operation rows. */ declare class TokenUsageAdminBreakdown extends AbstractApiData implements TokenUsageAdminBreakdownInterface { private _label; private _sublabel?; private _cost; private _credits; private _tokensIn; private _tokensOut; private _cached; private _calls; private _activeUsers?; private _monthlyCredits?; private _availableMonthlyCredits?; get label(): string; get sublabel(): string | undefined; get cost(): number; get credits(): number; get tokensIn(): number; get tokensOut(): number; get cached(): number; get calls(): number; get activeUsers(): number | undefined; get monthlyCredits(): number | undefined; get availableMonthlyCredits(): number | undefined; rehydrate(data: JsonApiHydratedDataInterface): this; createJsonApi(data: TokenUsageAdminBreakdownInput): any; } declare class TokenUsageAdminService extends AbstractService { /** Six rows: {customer, platform, total} × {current, previous}. */ static getSummary(filters: TokenUsageAdminFilters): Promise; static getTimeline(params: TokenUsageAdminFilters & { granularity: Granularity; stackBy: StackBy; }): Promise; static getBreakdown(params: TokenUsageAdminFilters & { dimension: Dimension; scope: Scope; limit?: number; }): Promise; } /** Metrics the self-service surface may request. `cost` is deliberately absent. */ type ReportMetric = "credits" | "tokens"; /** Dimensions the self-service breakdown can group by. */ type ReportDimension = "operation" | "target"; type TokenUsageReportFilters = { /** ISO 8601 instant. */ from: string; /** ISO 8601 instant. */ to: string; }; type TokenUsageReportSummaryInput = { id: string; window: string; cost: number; credits: number; tokensIn: number; tokensOut: number; cached: number; calls: number; }; type TokenUsageReportTimelineInput = { id: string; /** Backend field type is "date" — emitted via formatLocalDate, never raw. */ bucket: Date; series: string; cost: number; credits: number; tokensIn: number; tokensOut: number; cached: number; calls: number; }; type TokenUsageReportBreakdownInput = { id: string; label: string; sublabel?: string; cost: number; credits: number; tokensIn: number; tokensOut: number; cached: number; calls: number; }; interface TokenUsageReportSummaryInterface extends ApiDataInterface { /** "current" or "previous" — the equal-length preceding span. */ get window(): string; get cost(): number; get credits(): number; get tokensIn(): number; get tokensOut(): number; get cached(): number; get calls(): number; } /** * One row of the self-service summary: the caller's own company observed over * one time window. Two rows are returned per request — "current" and the * equal-length "previous" span — so the KPI tiles can render a value and its * delta without a second call. * * There is no `scope` here: a company only ever sees itself, so the * customer/platform split that the administrative summary carries is absent. */ declare class TokenUsageReportSummary extends AbstractApiData implements TokenUsageReportSummaryInterface { private _window; private _cost; private _credits; private _tokensIn; private _tokensOut; private _cached; private _calls; get window(): string; get cost(): number; get credits(): number; get tokensIn(): number; get tokensOut(): number; get cached(): number; get calls(): number; rehydrate(data: JsonApiHydratedDataInterface): this; createJsonApi(data: TokenUsageReportSummaryInput): any; } interface TokenUsageReportTimelineInterface extends ApiDataInterface { /** Backend declares this `type: "date"`, so it is a Date in memory. */ get bucket(): Date; get series(): string; get cost(): number; get credits(): number; get tokensIn(): number; get tokensOut(): number; get cached(): number; get calls(): number; } /** * One (bucket, series) cell of the self-service usage-over-time chart. Rows * arrive flat; the chart pivots them into stacked columns. */ declare class TokenUsageReportTimeline extends AbstractApiData implements TokenUsageReportTimelineInterface { private _bucket; private _series; private _cost; private _credits; private _tokensIn; private _tokensOut; private _cached; private _calls; get bucket(): Date; get series(): string; get cost(): number; get credits(): number; get tokensIn(): number; get tokensOut(): number; get cached(): number; get calls(): number; rehydrate(data: JsonApiHydratedDataInterface): this; createJsonApi(data: TokenUsageReportTimelineInput): any; } interface TokenUsageReportBreakdownInterface extends ApiDataInterface { get label(): string; get sublabel(): string | undefined; get cost(): number; get credits(): number; get tokensIn(): number; get tokensOut(): number; get cached(): number; get calls(): number; } /** * One ranked row of a self-service breakdown. The same shape serves both * dimensions — operation and target — which is why the two "by-X" panels * collapse into a single `breakdown?dimension=` call. * * Deliberately narrower than the administrative row: no `activeUsers`, * `monthlyCredits` or `availableMonthlyCredits`, which are company-fleet * figures a single company has no business seeing. */ declare class TokenUsageReportBreakdown extends AbstractApiData implements TokenUsageReportBreakdownInterface { private _label; private _sublabel?; private _cost; private _credits; private _tokensIn; private _tokensOut; private _cached; private _calls; get label(): string; get sublabel(): string | undefined; get cost(): number; get credits(): number; get tokensIn(): number; get tokensOut(): number; get cached(): number; get calls(): number; rehydrate(data: JsonApiHydratedDataInterface): this; createJsonApi(data: TokenUsageReportBreakdownInput): any; } /** * The self-service token-usage endpoints. * * No companyId parameter anywhere: the backend scopes every query to the * caller's own company through the CLS preamble, so there is nothing for the * client to name. No `metric: "cost"` either — the controller rejects it. */ declare class TokenUsageReportService extends AbstractService { /** Two rows: window "current" and "previous". */ static getSummary(filters: TokenUsageReportFilters): Promise; static getTimeline(params: TokenUsageReportFilters & { granularity: "day"; }): Promise; static getBreakdown(params: TokenUsageReportFilters & { dimension: ReportDimension; targetLabel?: string; metric: ReportMetric; limit?: number; }): Promise; } /** * The fixed namespace of i18n keys the administrative token-usage feature reads * via useTranslations/getTranslations. Consuming apps must define each entry in * their messages/.json — this list is the contract between the package * and the app. * * One key is NOT listed because it is resolved from data rather than from a * fixed string: the timeline chart labels each series through * `token_usage.types.` and falls back to the raw series key when the * app has no entry, so that namespace stays the app's own vocabulary. */ declare const TOKEN_USAGE_ADMIN_I18N_KEYS: readonly ["token_usage.admin.title", "token_usage.admin.customer_spend", "token_usage.admin.platform_spend", "token_usage.admin.total_cost", "token_usage.admin.avg_per_call", "token_usage.admin.cache_hit", "token_usage.admin.vs_previous", "token_usage.admin.usage_over_time", "token_usage.admin.by_company", "token_usage.admin.by_user", "token_usage.admin.customer_by_operation", "token_usage.admin.platform_by_operation", "token_usage.admin.detail", "token_usage.admin.other", "token_usage.admin.no_data", "token_usage.admin.all_companies", "token_usage.admin.granularity.label", "token_usage.admin.granularity.day", "token_usage.admin.granularity.week", "token_usage.admin.granularity.month", "token_usage.admin.metric.label", "token_usage.admin.metric.cost", "token_usage.admin.metric.credits", "token_usage.admin.metric.tokens", "token_usage.admin.stack_by", "token_usage.admin.stack.scope", "token_usage.admin.stack.type", "token_usage.admin.stack.company", "token_usage.admin.columns.label", "token_usage.admin.columns.sublabel", "token_usage.admin.columns.calls", "token_usage.admin.columns.tokens_in", "token_usage.admin.columns.tokens_out", "token_usage.admin.columns.cost", "token_usage.admin.columns.credits", "token_usage.admin.columns.share", "token_usage.admin.columns.active_users", "token_usage.series.other", "token_usage.timeline.empty"]; /** * The fixed namespace of i18n keys the self-service token-usage feature reads. * Consuming apps must define each entry in their messages/.json — this * list is the contract between the package and the app. * * The target panel's title is NOT listed: its key is supplied per app through * the provider's `targetPanelTitleKey`, because what usage is attributed to is * application-specific. Operation labels resolve through * `token_usage.types.` with the raw key as fallback, so that * namespace stays the app's own vocabulary. */ declare const TOKEN_USAGE_REPORT_I18N_KEYS: readonly ["token_usage.report.title", "token_usage.report.used_in_period", "token_usage.report.vs_previous", "token_usage.report.monthly_left", "token_usage.report.extra_credits", "token_usage.report.calls", "token_usage.report.usage_over_time", "token_usage.report.by_operation", "token_usage.report.no_data"]; type TokenUsageReportFilterState = { /** ISO 8601 instant. */ from: string; /** ISO 8601 instant. */ to: string; }; interface TokenUsageReportContextType { summary: TokenUsageReportSummaryInterface[]; timeline: TokenUsageReportTimelineInterface[]; byOperation: TokenUsageReportBreakdownInterface[]; /** Empty unless the host app declared a targetLabel. */ byTarget: TokenUsageReportBreakdownInterface[]; /** i18n key for the target panel's title; undefined when the host set no targetLabel. */ targetPanelTitleKey?: string; filters: TokenUsageReportFilterState; /** Merges a partial patch into the current filters; every key is optional. */ setFilters: (next: Partial) => void; isLoading: boolean; error: string | null; } type TokenUsageReportProviderProps = { children: ReactNode; /** * The Neo4j label the "by target" panel groups by, e.g. "Campaign". The set of * things usage can be attributed to is application-specific, so the package * cannot pick one — omit it and the panel is skipped rather than rendered * empty, and no request is issued. */ targetLabel?: string; /** i18n key for the target panel's title. Required when targetLabel is set. */ targetPanelTitleKey?: string; /** ISO 8601 instant. Defaults to the start of the current month. */ initialFrom?: string; /** ISO 8601 instant. Defaults to now. */ initialTo?: string; /** Rows per ranked panel. Defaults to 10. */ topN?: number; /** Route the breadcrumb links back to. */ pageUrl?: string; }; /** * Owns the date range of the self-service token-usage page, fetches the three * panels behind it, and publishes the filter bar into the page title bar. * * The filter bar is rendered into `title.functions` here — NOT in the container — * because `RoundPageContainer`'s title bar reads `title.functions` from * `SharedContext`, and a descendant cannot inject nodes into an ancestor's * provider value. That is why the filter state lives at this level. */ declare const TokenUsageReportProvider: ({ children, targetLabel, targetPanelTitleKey, initialFrom, initialTo, topN, pageUrl, }: TokenUsageReportProviderProps) => React.JSX.Element; declare const useTokenUsageReport: () => TokenUsageReportContextType; /** * The caller's own credit position, as the host app reads it from its * CurrentUserContext. The package has no access to that context, so the numbers * arrive as a prop. */ type TokenUsageBalances = { monthlyCredits: number; availableMonthlyCredits: number; availableExtraCredits: number; }; type Props$2 = { /** Two rows: window "current" and "previous". */ summary: TokenUsageReportSummaryInterface[]; metric: ReportMetric; /** The caller's own balances, read from CurrentUserContext by the container. */ balances: TokenUsageBalances | null; }; /** * The KPI header of the self-service token-usage page. * * One lead tile carries the number the page exists to answer — how much was * spent in the period — with its delta against the equal-length preceding * window. Three supporting tiles give it context: what is left this month, what * extra sits behind that, and how many calls produced the spend. * * Credits are fractional. Customer-facing BALANCES are floored to whole credits * (Math.max(0, Math.floor(v))) so nobody is told they have 715.4 of something * indivisible; the percentage arithmetic behind the colour keeps the raw floats. * Spend is NOT floored — it is a measurement, not a wallet. */ declare function TokenUsageReportTiles({ summary, metric, balances }: Props$2): React.JSX.Element; type Props$1 = { /** * The caller's own credit balances. Supplied by the host app, which reads them * from its CurrentUserContext — the package has no access to that context. */ balances?: TokenUsageBalances | null; }; /** * Page body for the self-service token-usage dashboard. * * Stateless by design — every value comes from useTokenUsageReport(). The filter * bar is deliberately NOT here: it belongs to the page title bar, which * RoundPageContainer fills from SharedContext, so the provider publishes it. * * The timeline and the ranked bars are the PACKAGE'S EXISTING components, used * verbatim. They take the same six metric getters the report interfaces were * given, which is what makes that reuse possible. */ declare function TokenUsageReportContainer({ balances }: Props$1): React.JSX.Element; type Props = { /** Receives ONLY the keys that changed. */ onChange: (next: { from?: string; to?: string; }) => void; }; /** * The single control row above the KPI tiles. * * Deliberately stateless: the control reports the keys it changed and the owning * context re-fetches, which is what lets the page issue a single coordinated * batch of requests instead of one per control. * * There is NO metric selector. A game master is billed in credits, so credits * are the only unit this surface speaks: cost would leak platform margin (the * controller rejects metric=cost outright) and a raw token count is an * implementation detail nobody is charged for. There is no company selector * either — a self-service caller has exactly one company. */ declare function TokenUsageReportFilterBar({ onChange }: Props): React.JSX.Element; type UsageFormatters = { /** Locale-aware fixed-decimal number, e.g. 9.46 → "9,46" in it-IT. */ decimal(value: number, decimals: number): string; /** Currency for cost, 2 decimals for credits, whole numbers for tokens. */ metricValue(value: number, metric: Metric): string; /** Currency with an explicit decimal count — the per-call tile needs 4. */ currency(value: number, decimals: number): string; /** Percentage with one decimal by default, e.g. 60 → "60,0 %" in it-IT. */ percent(value: number, decimals?: number): string; /** Compact notation for axis ticks, e.g. 1500000 → "1,5 Mln" in it-IT. */ compact(value: number): string; /** A "YYYY-MM-DD" bucket key rendered as an axis or tooltip label, in UTC. */ bucketDate(iso: string, granularity: "day" | "week" | "month"): string; /** Locale collation for client-side table sorting. */ compare(a: string, b: string): number; }; /** * Builds every formatter the token-usage surfaces need, for one locale and one * currency. * * A pure factory on purpose: it takes no React context, so the arithmetic and * the formatting are unit-testable without rendering, and a server component or * a test can construct a set for an arbitrary locale. * * The currency symbol is placed with a space rather than through * `style: "currency"`, which is what the previous hard-coded implementation * rendered ("€ 9,46"). Keeping that shape means a consuming app on EUR sees * byte-identical output after this refactor. * * `bucketDate` formats in UTC, always. The wire value is a `type: "date"` — a * calendar day — parsed to UTC midnight; reading it back with local getters * would shift the label a day early west of UTC. */ declare function createUsageFormatters(locale: string, currency: string): UsageFormatters; /** * The formatter set for the current request's locale and the app's configured * currency. Memoised on both, so the Intl objects are built once per locale * rather than on every render. */ declare function useUsageFormatters(): UsageFormatters; export { type Dimension, type Granularity, type Metric, type ReportDimension, type ReportMetric, type Scope, type StackBy, TOKEN_USAGE_ADMIN_I18N_KEYS, TOKEN_USAGE_REPORT_I18N_KEYS, TokenUsageAdminBreakdown, type TokenUsageAdminBreakdownInput, type TokenUsageAdminBreakdownInterface, TokenUsageAdminContainer, type TokenUsageAdminContextType, TokenUsageAdminFilterBar, type TokenUsageAdminFilterState, type TokenUsageAdminFilters, TokenUsageAdminProvider, TokenUsageAdminService, TokenUsageAdminSummary, type TokenUsageAdminSummaryInput, type TokenUsageAdminSummaryInterface, TokenUsageAdminTiles, TokenUsageAdminTimeline, type TokenUsageAdminTimelineInput, type TokenUsageAdminTimelineInterface, type TokenUsageBalances, TokenUsageBreakdownTable, TokenUsageRankedBar, TokenUsageReportBreakdown, type TokenUsageReportBreakdownInput, type TokenUsageReportBreakdownInterface, TokenUsageReportContainer, type TokenUsageReportContextType, TokenUsageReportFilterBar, type TokenUsageReportFilterState, type TokenUsageReportFilters, TokenUsageReportProvider, TokenUsageReportService, TokenUsageReportSummary, type TokenUsageReportSummaryInput, type TokenUsageReportSummaryInterface, TokenUsageReportTiles, TokenUsageReportTimeline, type TokenUsageReportTimelineInput, type TokenUsageReportTimelineInterface, TokenUsageTimelineChart, type UsageFormatters, createUsageFormatters, useTokenUsageAdmin, useTokenUsageReport, useUsageFormatters };