From 48fff86a27aff4a60975a833e8b3cea5d12c96d4 Mon Sep 17 00:00:00 2001 From: moe-berri Date: Sat, 3 Oct 2026 18:27:59 -0700 Subject: [PATCH] fix(lens): compact onboarding and animate gateway flow --- .../lens/LensWorkspace.integration.test.tsx | 13 ++- .../lens/setup/LensGettingStarted.tsx | 4 +- .../lens/setup/LensIntroduction.module.css | 18 +++ .../lens/setup/LensIntroduction.tsx | 106 +++++++++++------- 4 files changed, 89 insertions(+), 52 deletions(-) create mode 100644 ui/litellm-dashboard/src/components/lens/setup/LensIntroduction.module.css diff --git a/ui/litellm-dashboard/src/components/lens/LensWorkspace.integration.test.tsx b/ui/litellm-dashboard/src/components/lens/LensWorkspace.integration.test.tsx index 3b268546344..058ff1e1e03 100644 --- a/ui/litellm-dashboard/src/components/lens/LensWorkspace.integration.test.tsx +++ b/ui/litellm-dashboard/src/components/lens/LensWorkspace.integration.test.tsx @@ -26,7 +26,8 @@ describe("Lens interactive demo", () => { onUrlUpdate, }); expect(await screen.findByRole("heading", { name: "The gateway that helps your agents improve" })).toBeVisible(); - await user.click(screen.getByRole("button", { name: "Preview sample" })); + expect(screen.queryByRole("button", { name: "Preview sample" })).not.toBeInTheDocument(); + await user.click(screen.getByRole("button", { name: "Explore with sample data" })); expect(await screen.findByText("Where is order #1042?")).toBeVisible(); expect(screen.getByText("You’re viewing demo data")).toBeVisible(); expect(screen.queryByRole("button", { name: "Set up tracing" })).not.toBeInTheDocument(); @@ -58,8 +59,7 @@ describe("Lens interactive demo", () => { searchParams: "?tab=investigations", onUrlUpdate, }); - await screen.findByRole("button", { name: "Preview sample" }); - await user.click(screen.getByRole("button", { name: "Preview sample" })); + await user.click(await screen.findByRole("button", { name: "Explore with sample data" })); await user.click(await screen.findByRole("tab", { name: "Findings" })); network.mockClear(); await user.click(await screen.findByRole("row", { name: /Repeated lookups leave customers without an answer/ })); @@ -111,7 +111,7 @@ describe("Lens interactive demo", () => { expect(screen.queryByRole("button", { name: "Preview sample" })).not.toBeInTheDocument(); }); - it("shows the header preview only for the active tab that still needs setup", async () => { + it("offers sample data in the main panel only for the active tab that needs setup", async () => { const user = userEvent.setup(); const saved = createLensDemoData().lenses[0]; network.mockImplementation(async (input) => { @@ -122,13 +122,14 @@ describe("Lens interactive demo", () => { return Response.json({ data: [], traces: false, requests: false }); }); renderWithProviders(); - expect(await screen.findByRole("button", { name: "Preview sample" })).toBeVisible(); + expect(await screen.findByRole("button", { name: "Explore with sample data" })).toBeVisible(); const tabs = within(screen.getByRole("tablist", { name: "Lens" })); await user.click(tabs.getByRole("tab", { name: "Investigations" })); expect(await screen.findByRole("row", { name: new RegExp(saved.settings.name) })).toBeVisible(); expect(screen.queryByRole("button", { name: "Preview sample" })).not.toBeInTheDocument(); + expect(screen.queryByRole("button", { name: "Explore with sample data" })).not.toBeInTheDocument(); await user.click(tabs.getByRole("tab", { name: "Traces" })); - await user.click(await screen.findByRole("button", { name: "Preview sample" })); + await user.click(await screen.findByRole("button", { name: "Explore with sample data" })); expect(await screen.findByRole("table", { name: "Agent runs" })).toBeVisible(); expect(screen.queryByRole("button", { name: "Preview sample" })).not.toBeInTheDocument(); }); diff --git a/ui/litellm-dashboard/src/components/lens/setup/LensGettingStarted.tsx b/ui/litellm-dashboard/src/components/lens/setup/LensGettingStarted.tsx index 01a83797b9f..01b62c864da 100644 --- a/ui/litellm-dashboard/src/components/lens/setup/LensGettingStarted.tsx +++ b/ui/litellm-dashboard/src/components/lens/setup/LensGettingStarted.tsx @@ -9,7 +9,6 @@ import { lensQueries } from "../api/queries"; import { useSaveLens } from "../api/mutations"; import { useLensApi } from "../services"; import { TraceSheet } from "../investigations/TraceSheet"; -import { LensPreviewButton } from "../LensPreviewButton"; import { useAnalysisKeyInfo } from "./worker/AnalysisKeyDetails"; import { WorkerDialog } from "./worker/WorkerDialog"; import { InvestigationSetupDialog } from "./InvestigationSetupDialog"; @@ -65,8 +64,7 @@ export function LensGettingStarted({ }; return ( -
- {onDemo && } +
0.9) return null; return { x: column * 10 + 5, y: row * 10 + 5, - color: column < 61 ? swarmColors[(column + row) % swarmColors.length] : "fill-indigo-600 dark:fill-indigo-400", + color: swarmColors[(phase + row) % swarmColors.length], }; } -const flowDots = Array.from({ length: 600 }, (_, index) => flowDot(index)).filter((dot) => dot !== null); +const flowDots = Array.from({ length: 744 }, (_, index) => flowDot(index)).filter((dot) => dot !== null); function GatewayFlow() { const patternId = useId(); + const beforeGateway = `${patternId}-before`; + const afterGateway = `${patternId}-after`; return ( -
-
+
+

Agent swarms

-

Every run, every recorded step

+

Every run, every recorded step

LiteLLM gateway

-

One place, your infrastructure

+

One place, your infrastructure

Lens

-

Findings to improve your agents

+

Findings to improve your agents

-
@@ -65,14 +86,14 @@ const sampleAnswer = "The column store is 40% faster than the row store for your function TraceExample() { return ( -
+

Tracing

Sample trace · 14.2s

-
    +
      {traceSteps.map((item, index) => (
    1. ))}
    -
    -
    +
    +

    run_benchmark · output

    -

    Error: benchmark runner unavailable (503)

    +

    Error: benchmark runner unavailable (503)

    -
    +

    answer · output

    -

    “{sampleAnswer}”

    +

    “{sampleAnswer}”

@@ -115,38 +136,38 @@ function TraceExample() { function FindingExamples() { return ( -
+

Lens findings

500 sample runs reviewed

-
-
+
+

-
-

- When the benchmark tool fails, the agent still reports a speedup in its answer. -

-
“{sampleAnswer}”
+
+

Reports a speedup even though the benchmark failed.

+
+ “…40% faster than the row store for your workload.” +

- Next step: Tell the agent to report the failed benchmark - instead of estimating. + Next step: Report the failed benchmark instead of + estimating.

38 linked runs · High priority

-
+

-
-

After the order lookup times out, the support agent replies “I will check” and ends the run.

+
+

After an order lookup times out, the agent promises to check and ends the run.

12 linked runs · Medium priority

@@ -159,25 +180,24 @@ export function LensIntroduction({ onStart, onDemo }: { onStart: () => void; onD return (

The gateway that helps your agents improve

-

- Lens turns recorded agent runs into findings tied to the exact steps that caused them, so you can see what needs - to change without reading every trace by hand. +

+ Turn recorded agent runs into findings linked to the exact steps, so you know what happened and what to change.

-
+
{onDemo && ( - )} - void; onD
-
+