diff --git a/ui/litellm-dashboard/eslint-suppressions.json b/ui/litellm-dashboard/eslint-suppressions.json
index a4dcf0f6c73..47db33f1a79 100644
--- a/ui/litellm-dashboard/eslint-suppressions.json
+++ b/ui/litellm-dashboard/eslint-suppressions.json
@@ -3809,11 +3809,6 @@
"count": 1
}
},
- "src/components/view_logs/LogDetailsDrawer/JsonViewer.tsx": {
- "no-restricted-imports": {
- "count": 1
- }
- },
"src/components/view_logs/LogDetailsDrawer/LogDetailContent.tsx": {
"no-nested-ternary": {
"count": 3
@@ -3863,11 +3858,6 @@
"count": 1
}
},
- "src/components/view_logs/LogDetailsDrawer/TokenFlow.tsx": {
- "no-restricted-imports": {
- "count": 1
- }
- },
"src/components/view_logs/LogDetailsDrawer/TruncatedValue.tsx": {
"no-restricted-imports": {
"count": 1
diff --git a/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/JsonViewer.test.tsx b/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/JsonViewer.test.tsx
new file mode 100644
index 00000000000..055e400167b
--- /dev/null
+++ b/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/JsonViewer.test.tsx
@@ -0,0 +1,28 @@
+import { render, screen } from "@testing-library/react";
+import { describe, expect, it } from "vitest";
+import { JsonViewer } from "./JsonViewer";
+
+describe("JsonViewer", () => {
+ it("should render a placeholder and no tree when the log entry carries no payload", () => {
+ render();
+
+ expect(screen.getByText("No data")).toBeInTheDocument();
+ expect(screen.queryByRole("tree")).not.toBeInTheDocument();
+ });
+
+ it("should render the payload as a tree exposing its keys", () => {
+ render();
+
+ expect(screen.getByRole("tree")).toBeInTheDocument();
+ expect(screen.getByText(/model/)).toBeInTheDocument();
+ expect(screen.getByText(/stream/)).toBeInTheDocument();
+ expect(screen.queryByText("No data")).not.toBeInTheDocument();
+ });
+
+ it("should treat an empty payload as data rather than showing the placeholder", () => {
+ render();
+
+ expect(screen.getByRole("tree")).toBeInTheDocument();
+ expect(screen.queryByText("No data")).not.toBeInTheDocument();
+ });
+});
diff --git a/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/JsonViewer.tsx b/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/JsonViewer.tsx
index 0a873a7e255..af99eee0d16 100644
--- a/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/JsonViewer.tsx
+++ b/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/JsonViewer.tsx
@@ -1,10 +1,7 @@
-import { Typography } from "antd";
import { JsonView, defaultStyles } from "react-json-view-lite";
import "react-json-view-lite/dist/index.css";
import { JSON_MAX_HEIGHT, COLOR_BG_LIGHT, SPACING_LARGE } from "./constants";
-const { Text } = Typography;
-
interface JsonViewerProps {
data: any;
mode: "formatted";
@@ -15,7 +12,7 @@ interface JsonViewerProps {
* Uses an interactive tree component for easy navigation.
*/
export function JsonViewer({ data }: JsonViewerProps) {
- if (!data) return No data;
+ if (!data) return No data;
return (
count.toLocaleString();
+
+describe("TokenFlow", () => {
+ it("should render the total followed by its prompt and completion breakdown", () => {
+ render();
+
+ expect(screen.getByText("12 (9 prompt tokens + 3 completion tokens)")).toBeInTheDocument();
+ });
+
+ it("should group large counts the way the reader's locale does", () => {
+ render();
+
+ expect(
+ screen.getByText(
+ `${localised(1323579)} (${localised(1234567)} prompt tokens + ${localised(89012)} completion tokens)`,
+ ),
+ ).toBeInTheDocument();
+ });
+
+ it("should fall back to zero for counts the log entry does not carry", () => {
+ render();
+
+ expect(screen.getByText("12 (0 prompt tokens + 0 completion tokens)")).toBeInTheDocument();
+ });
+});
diff --git a/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/TokenFlow.tsx b/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/TokenFlow.tsx
index 5eec3c0a5cb..2183ed53f35 100644
--- a/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/TokenFlow.tsx
+++ b/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/TokenFlow.tsx
@@ -1,7 +1,3 @@
-import { Typography } from "antd";
-
-const { Text } = Typography;
-
interface TokenFlowProps {
prompt?: number;
completion?: number;
@@ -14,9 +10,9 @@ interface TokenFlowProps {
*/
export function TokenFlow({ prompt = 0, completion = 0, total = 0 }: TokenFlowProps) {
return (
-
+
{total.toLocaleString()} ({prompt.toLocaleString()} prompt tokens + {completion.toLocaleString()} completion
tokens)
-
+
);
}