import type { ColumnDef } from "@tanstack/react-table"; import { getCountryFromIP } from "./ip_lookup"; import moment from "moment"; import React from "react"; import { CountryCell } from "./country_cell"; import { getProviderLogoAndName } from "../provider_info_helpers"; import { Tooltip } from "antd"; import { TimeCell } from "./time_cell"; import { Button } from "@tremor/react"; // Helper to get the appropriate logo URL const getLogoUrl = ( row: LogEntry, provider: string ) => { // Check if mcp_tool_call_metadata exists and contains mcp_server_logo_url if (row.metadata?.mcp_tool_call_metadata?.mcp_server_logo_url) { return row.metadata.mcp_tool_call_metadata.mcp_server_logo_url; } // Fall back to default provider logo return provider ? getProviderLogoAndName(provider).logo : ''; }; export type LogEntry = { request_id: string; api_key: string; team_id: string; model: string; model_id: string; api_base?: string; call_type: string; spend: number; total_tokens: number; prompt_tokens: number; completion_tokens: number; startTime: string; endTime: string; user?: string; end_user?: string; custom_llm_provider?: string; metadata?: Record; cache_hit: string; cache_key?: string; request_tags?: Record; requester_ip_address?: string; messages: string | any[] | Record; response: string | any[] | Record; proxy_server_request?: string | any[] | Record; session_id?: string; onKeyHashClick?: (keyHash: string) => void; onSessionClick?: (sessionId: string) => void; }; export const columns: ColumnDef[] = [ { id: "expander", header: () => null, cell: ({ row }) => { // Convert the cell function to a React component to properly use hooks const ExpanderCell = () => { const [localExpanded, setLocalExpanded] = React.useState(row.getIsExpanded()); // Memoize the toggle handler to prevent unnecessary re-renders const toggleHandler = React.useCallback(() => { setLocalExpanded((prev) => !prev); row.getToggleExpandedHandler()(); }, [row]); return row.getCanExpand() ? ( ) : ( ); }; // Return the component return ; }, }, { header: "Time", accessorKey: "startTime", cell: (info: any) => , }, { header: "Status", accessorKey: "metadata.status", cell: (info: any) => { const status = info.getValue() || "Success"; const isSuccess = status.toLowerCase() !== "failure"; return ( {isSuccess ? "Success" : "Failure"} ); }, }, { header: "Session ID", accessorKey: "session_id", cell: (info: any) => { const value = String(info.getValue() || ""); const onSessionClick = info.row.original.onSessionClick; return ( ); }, }, { header: "Request ID", accessorKey: "request_id", cell: (info: any) => ( {String(info.getValue() || "")} ), }, { header: "Cost", accessorKey: "spend", cell: (info: any) => ( ${Number(info.getValue() || 0).toFixed(6)} ), }, { header: "Country", accessorKey: "requester_ip_address", cell: (info: any) => , }, { header: "Team Name", accessorKey: "metadata.user_api_key_team_alias", cell: (info: any) => ( {String(info.getValue() || "-")} ), }, { header: "Key Hash", accessorKey: "metadata.user_api_key", cell: (info: any) => { const value = String(info.getValue() || "-"); const onKeyHashClick = info.row.original.onKeyHashClick; return ( onKeyHashClick?.(value)} > {value} ); }, }, { header: "Key Name", accessorKey: "metadata.user_api_key_alias", cell: (info: any) => ( {String(info.getValue() || "-")} ), }, { header: "Model", accessorKey: "model", cell: (info: any) => { const row = info.row.original; const provider = row.custom_llm_provider; const modelName = String(info.getValue() || ""); return (
{provider && ( { const target = e.target as HTMLImageElement; target.style.display = 'none'; }} /> )} {modelName}
); }, }, { header: "Tokens", accessorKey: "total_tokens", cell: (info: any) => { const row = info.row.original; return ( {String(row.total_tokens || "0")} ({String(row.prompt_tokens || "0")}+ {String(row.completion_tokens || "0")}) ); }, }, { header: "Internal User", accessorKey: "user", cell: (info: any) => ( {String(info.getValue() || "-")} ), }, { header: "End User", accessorKey: "end_user", cell: (info: any) => ( {String(info.getValue() || "-")} ), }, { header: "Tags", accessorKey: "request_tags", cell: (info: any) => { const tags = info.getValue(); if (!tags || Object.keys(tags).length === 0) return "-"; const tagEntries = Object.entries(tags); const firstTag = tagEntries[0]; const remainingTags = tagEntries.slice(1); return (
{tagEntries.map(([key, value]) => ( {key}: {String(value)} ))}
} > {firstTag[0]}: {String(firstTag[1])} {remainingTags.length > 0 && ` +${remainingTags.length}`} ); }, }, ]; const formatMessage = (message: any): string => { if (!message) return "N/A"; if (typeof message === "string") return message; if (typeof message === "object") { // Handle the {text, type} object specifically if (message.text) return message.text; if (message.content) return message.content; return JSON.stringify(message); } return String(message); }; // Add this new component for displaying request/response with copy buttons export const RequestResponsePanel = ({ request, response }: { request: any; response: any }) => { const requestStr = typeof request === 'object' ? JSON.stringify(request, null, 2) : String(request || '{}'); const responseStr = typeof response === 'object' ? JSON.stringify(response, null, 2) : String(response || '{}'); const copyToClipboard = (text: string) => { navigator.clipboard.writeText(text); }; return (

Request

{requestStr}

Response

{responseStr}
); };