mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-07 08:26:10 +00:00
fix(usage): label key activity tables with email when alias is missing
Key Activity charts already fell back to user_email. The top-keys tables and usage export still printed '-' or a truncated hash. They now use the same alias-then-email label. Co-authored-by: Mateo Wang <mateo-berri@users.noreply.github.com>
This commit is contained in:
parent
e76a18ca32
commit
6f4ea2d296
6 changed files with 34 additions and 5 deletions
|
|
@ -1,3 +1,4 @@
|
|||
import { keyActivityLabel } from "@/components/UsagePage/keyActivityLabel";
|
||||
import { BreakdownMetrics, DailyData, KeyMetricWithMetadata, TagUsage } from "@/components/UsagePage/types";
|
||||
|
||||
export type ExtendedDailyData = DailyData & {
|
||||
|
|
@ -118,6 +119,7 @@ export const getTopAPIKeys = (results: ExtendedDailyData[], topKeysLimit: number
|
|||
metadata: {
|
||||
key_alias: metrics.metadata.key_alias,
|
||||
team_id: metrics.metadata.team_id || null,
|
||||
user_email: metrics.metadata.user_email,
|
||||
tags: tagDictionary[key] || [],
|
||||
},
|
||||
};
|
||||
|
|
@ -137,7 +139,7 @@ export const getTopAPIKeys = (results: ExtendedDailyData[], topKeysLimit: number
|
|||
return Object.entries(keySpend)
|
||||
.map(([api_key, metrics]) => ({
|
||||
api_key,
|
||||
key_alias: metrics.metadata.key_alias || "-", // Using truncated key as alias
|
||||
key_alias: keyActivityLabel(metrics.metadata),
|
||||
tags: metrics.metadata.tags || "-",
|
||||
spend: metrics.metrics.spend,
|
||||
}))
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ import { Tag } from "@/components/tag_management/types";
|
|||
import UserAgentActivity from "@/components/user_agent_activity";
|
||||
import ViewUserSpend from "@/components/view_user_spend";
|
||||
import { usePaginatedDailyActivity } from "../hooks/usePaginatedDailyActivity";
|
||||
import { keyActivityLabel } from "@/components/UsagePage/keyActivityLabel";
|
||||
import { DailyData, KeyMetricWithMetadata, MetricWithMetadata } from "@/components/UsagePage/types";
|
||||
import { valueFormatterSpend } from "@/components/UsagePage/utils/value_formatters";
|
||||
import {
|
||||
|
|
@ -426,6 +427,7 @@ const UsagePage: React.FC<UsagePageProps> = ({ teams, organizations }) => {
|
|||
metadata: {
|
||||
key_alias: metrics.metadata.key_alias,
|
||||
team_id: null,
|
||||
user_email: metrics.metadata.user_email,
|
||||
tags: metrics.metadata.tags || [],
|
||||
},
|
||||
};
|
||||
|
|
@ -445,7 +447,7 @@ const UsagePage: React.FC<UsagePageProps> = ({ teams, organizations }) => {
|
|||
return Object.entries(keySpend)
|
||||
.map(([api_key, metrics]) => ({
|
||||
api_key,
|
||||
key_alias: metrics.metadata.key_alias || "-",
|
||||
key_alias: keyActivityLabel(metrics.metadata),
|
||||
tags: metrics.metadata.tags || [],
|
||||
spend: metrics.metrics.spend,
|
||||
}))
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { formatNumberWithCommas } from "@/utils/dataUtils";
|
||||
import type { DateRangePickerValue } from "@/components/shared/date_picker_types";
|
||||
import Papa from "papaparse";
|
||||
import { keyActivityLabel } from "@/components/UsagePage/keyActivityLabel";
|
||||
import type { EntityBreakdown, EntitySpendData, EntityType, ExportMetadata, ExportScope } from "./types";
|
||||
|
||||
const resolveEntityDisplay = (
|
||||
|
|
@ -186,7 +187,7 @@ export const generateDailyWithKeysData = (
|
|||
|
||||
// Iterate through each API key in the breakdown
|
||||
Object.entries(apiKeyBreakdown).forEach(([keyId, keyData]: [string, any]) => {
|
||||
const keyAlias = keyData?.metadata?.key_alias || null;
|
||||
const keyAlias = keyActivityLabel(keyData?.metadata, "") || null;
|
||||
|
||||
// Create unique key for aggregation: Date_EntityID_KeyID
|
||||
const uniqueKey = `${day.date}_${entityId}_${keyId}`;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
import { keyActivityLabel } from "./keyActivityLabel";
|
||||
|
||||
describe("keyActivityLabel", () => {
|
||||
it("prefers key_alias", () => {
|
||||
expect(keyActivityLabel({ key_alias: "batch-worker", user_email: "alice@example.com" })).toBe("batch-worker");
|
||||
});
|
||||
|
||||
it("falls back to user_email when alias is missing", () => {
|
||||
expect(keyActivityLabel({ key_alias: null, user_email: "alice@example.com" })).toBe("alice@example.com");
|
||||
});
|
||||
|
||||
it("uses the fallback when both alias and email are missing", () => {
|
||||
expect(keyActivityLabel({ key_alias: null, user_email: null }, "key-hash-abc")).toBe("key-hash-abc");
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
import type { KeyMetadata } from "./types";
|
||||
|
||||
export function keyActivityLabel(
|
||||
metadata: Pick<KeyMetadata, "key_alias" | "user_email"> | null | undefined,
|
||||
fallback = "-",
|
||||
): string {
|
||||
return metadata?.key_alias || metadata?.user_email || fallback;
|
||||
}
|
||||
|
|
@ -7,6 +7,7 @@ import { ChevronDown } from "lucide-react";
|
|||
import React, { useState } from "react";
|
||||
import { Team } from "./key_team_helpers/key_list";
|
||||
import KeyModelUsageView from "./UsagePage/components/KeyModelUsageView";
|
||||
import { keyActivityLabel } from "./UsagePage/keyActivityLabel";
|
||||
import { DailyData, KeyMetricWithMetadata, ModelActivityData, TopApiKeyData, TopModelData } from "./UsagePage/types";
|
||||
import { valueFormatter } from "./UsagePage/utils/value_formatters";
|
||||
|
||||
|
|
@ -433,7 +434,7 @@ export const ActivityMetrics: React.FC<ActivityMetricsProps> = ({ modelMetrics,
|
|||
|
||||
// Helper function to format key label
|
||||
export const formatKeyLabel = (modelData: KeyMetricWithMetadata, model: string, teams: Team[]): string => {
|
||||
const keyAlias = modelData.metadata.key_alias || modelData.metadata.user_email || `key-hash-${model}`;
|
||||
const keyAlias = keyActivityLabel(modelData.metadata, `key-hash-${model}`);
|
||||
const teamId = modelData.metadata.team_id;
|
||||
if (teamId) {
|
||||
const teamAlias = resolveTeamAliasFromTeamID(teamId, teams);
|
||||
|
|
@ -516,7 +517,7 @@ export const processActivityData = (
|
|||
if (!apiKeyBreakdown[apiKey]) {
|
||||
apiKeyBreakdown[apiKey] = {
|
||||
api_key: apiKey,
|
||||
key_alias: keyData.metadata.key_alias,
|
||||
key_alias: keyActivityLabel(keyData.metadata, "") || null,
|
||||
team_id: keyData.metadata.team_id,
|
||||
spend: 0,
|
||||
requests: 0,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue