first commit

This commit is contained in:
Beyhan Oğur
2026-04-26 21:52:23 +03:00
commit 880f412e2c
2662 changed files with 866266 additions and 0 deletions

View File

@@ -0,0 +1,170 @@
import FullPageLoader from "@/components/fullPageLoader";
import { NoPermissionView } from "@/components/noPermissionView";
import { ProviderNames } from "@/lib/constants/logs";
import { useGetModelsQuery, useGetProvidersQuery, useLazyGetLogsModelHistogramQuery, useLazyGetLogsStatsQuery } from "@/lib/store";
import { KnownProvider } from "@/lib/types/config";
import { LogStats } from "@/lib/types/logs";
import { RbacOperation, RbacResource, useRbac } from "@enterprise/lib";
import { useEffect, useMemo, useState } from "react";
import { ModelCatalogEmptyState } from "./modelCatalogEmptyState";
import ModelCatalogTable, { ModelCatalogRow } from "./modelCatalogTable";
export default function ModelCatalogView() {
const hasAccess = useRbac(RbacResource.ModelProvider, RbacOperation.View);
const [providerFilter, setProviderFilter] = useState("");
const [statsMap, setStatsMap] = useState<Map<string, LogStats>>(new Map());
const [modelsUsedMap, setModelsUsedMap] = useState<Map<string, string[]>>(new Map());
const [isLoadingModels, setIsLoadingModels] = useState(true);
const {
data: providers,
isLoading: isLoadingProviders,
error: providersError,
refetch: refetchProviders,
} = useGetProvidersQuery(undefined, { skip: !hasAccess });
const { data: modelsData } = useGetModelsQuery({ unfiltered: true }, { skip: !hasAccess });
// Global 24h stats for summary cards (lazy so we get fresh timestamps)
const [triggerGlobalStats, { data: globalStats }] = useLazyGetLogsStatsQuery();
// Per-provider traffic stats (lazy, fired when providers load)
const [triggerStats] = useLazyGetLogsStatsQuery();
const [triggerModelHistogram] = useLazyGetLogsModelHistogramQuery();
useEffect(() => {
if (!hasAccess) return;
const now = new Date().toISOString();
const dayAgo = new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString();
triggerGlobalStats({ filters: { start_time: dayAgo, end_time: now } });
}, [hasAccess, triggerGlobalStats]);
useEffect(() => {
if (!providers || providers.length === 0) return;
let cancelled = false;
const now = new Date().toISOString();
const dayAgo = new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString();
Promise.all(
providers.map((p) =>
triggerStats({ filters: { providers: [p.name], start_time: dayAgo, end_time: now } })
.unwrap()
.then((stats) => [p.name, stats] as const)
.catch(
() =>
[
p.name,
{
total_requests: 0,
success_rate: 0,
user_facing_success_rate: 0,
average_latency: 0,
user_facing_total_requests:0,
total_tokens: 0,
total_cost: 0
},
] as const,
),
),
).then((results) => {
if (!cancelled) setStatsMap(new Map(results));
});
return () => {
cancelled = true;
};
}, [providers, triggerStats]);
// Per-provider models used in last 30 days
useEffect(() => {
if (!providers || providers.length === 0) return;
let cancelled = false;
setIsLoadingModels(true);
const now = new Date().toISOString();
const monthAgo = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString();
Promise.all(
providers.map((p) =>
triggerModelHistogram({ filters: { providers: [p.name], start_time: monthAgo, end_time: now } })
.unwrap()
.then((data): [string, string[]] => [p.name, data.models ?? []])
.catch((): [string, string[]] => [p.name, []]),
),
).then((results) => {
if (!cancelled) {
setModelsUsedMap(new Map(results));
setIsLoadingModels(false);
}
});
return () => {
cancelled = true;
};
}, [providers, triggerModelHistogram]);
// Build table rows
const rows: ModelCatalogRow[] = useMemo(() => {
if (!providers) return [];
return providers.map((p) => {
const isCustom = !ProviderNames.includes(p.name as KnownProvider);
const modelsUsed = modelsUsedMap.get(p.name) ?? [];
const providerStats = statsMap.get(p.name);
const totalTraffic24h = providerStats?.total_requests ?? 0;
const totalCost24h = providerStats?.total_cost ?? 0;
return {
providerName: p.name,
isCustom,
baseProviderType: p.custom_provider_config?.base_provider_type,
modelsUsed,
totalTraffic24h,
totalCost24h,
};
});
}, [providers, statsMap, modelsUsedMap]);
// Filter rows by provider
const filteredRows = useMemo(() => {
if (!providerFilter) return rows;
return rows.filter((r) => r.providerName === providerFilter);
}, [rows, providerFilter]);
if (isLoadingProviders) {
return <FullPageLoader />;
}
if (!hasAccess) {
return <NoPermissionView entity="model catalog" />;
}
if (providersError) {
return (
<div className="flex h-full flex-col items-center justify-center gap-4 text-center">
<p className="text-muted-foreground text-sm">Failed to load providers</p>
<button type="button" data-testid="model-catalog-retry-btn" onClick={refetchProviders} className="text-sm underline">
Retry
</button>
</div>
);
}
if (!providers || providers.length === 0) {
return <ModelCatalogEmptyState />;
}
return (
<div className="mx-auto w-full max-w-7xl">
<ModelCatalogTable
rows={filteredRows}
providers={(providers ?? []).map((p) => p.name)}
providerFilter={providerFilter}
onProviderFilterChange={setProviderFilter}
totalProviders={(providers ?? []).length}
totalModels={modelsData?.total ?? 0}
totalRequests24h={globalStats?.total_requests ?? 0}
totalCost24h={globalStats?.total_cost ?? 0}
isLoadingModels={isLoadingModels}
/>
</div>
);
}