From 513d1acc8ecca1113d1482d43a3d40e02e7f502a Mon Sep 17 00:00:00 2001 From: Jonathan Bell Date: Mon, 30 Mar 2026 01:58:57 +0000 Subject: [PATCH] Draft implementaton of lens export --- workbench/_web/src/actions/notebook.ts | 39 +++++++++ .../[chartId]/components/Lens2Display.tsx | 37 ++++++++- .../src/notebook-templates/logit-lens.ipynb | 82 +++++++++++++++++++ 3 files changed, 155 insertions(+), 3 deletions(-) create mode 100644 workbench/_web/src/notebook-templates/logit-lens.ipynb diff --git a/workbench/_web/src/actions/notebook.ts b/workbench/_web/src/actions/notebook.ts index e27cd99d..80ac7824 100644 --- a/workbench/_web/src/actions/notebook.ts +++ b/workbench/_web/src/actions/notebook.ts @@ -189,11 +189,50 @@ const activationPatchingHandler: NotebookToolHandler = { }, }; +// ── Logit Lens handler ────────────────────────────────────────────── + +const logitLensHandler: NotebookToolHandler = { + templateName: "logit-lens", + + buildParameterSource(config) { + const prompt = escapePythonTripleDoubleQuoted( + (config.prompt as string) ?? "" + ); + const topk = (config.topk as number) ?? 5; + const includeEntropy = (config.includeEntropy as boolean) ?? true; + + return [ + `prompt = """${prompt}"""`, + `topk = ${topk}`, + `include_entropy = ${includeEntropy ? "True" : "False"}`, + ].join("\n"); + }, + + buildConfigSource(config) { + const model = (config.model as string) ?? ""; + return [ + `MODEL_NAME = "${model}"`, + `REMOTE = True`, + ].join("\n"); + }, + + buildVisualizationPayload(chartData) { + if (!chartData || !("meta" in chartData)) return null; + + return { + widget: "LogitLensWidget", + data: chartData, + options: {}, + }; + }, +}; + // ── Handler registry ───────────────────────────────────────────────── // Add new tool handlers here as they're implemented. const toolHandlers: Record = { "activation-patching": activationPatchingHandler, + "lens2": logitLensHandler, }; // ── Public API ─────────────────────────────────────────────────────── diff --git a/workbench/_web/src/app/workbench/[workspaceId]/lens2/[chartId]/components/Lens2Display.tsx b/workbench/_web/src/app/workbench/[workspaceId]/lens2/[chartId]/components/Lens2Display.tsx index 59be92ff..7d76703c 100644 --- a/workbench/_web/src/app/workbench/[workspaceId]/lens2/[chartId]/components/Lens2Display.tsx +++ b/workbench/_web/src/app/workbench/[workspaceId]/lens2/[chartId]/components/Lens2Display.tsx @@ -2,22 +2,31 @@ import { useParams } from "next/navigation"; import { useQuery, useIsMutating } from "@tanstack/react-query"; -import { getChartById } from "@/lib/queries/chartQueries"; +import { getChartById, getConfigForChart } from "@/lib/queries/chartQueries"; +import { getWorkspaceById } from "@/lib/queries/workspaceQueries"; import { queryKeys } from "@/lib/queryKeys"; -import { Lens2Data } from "@/types/lens2"; +import { Lens2Data, Lens2ConfigData } from "@/types/lens2"; import { useTheme } from "next-themes"; import { Loader2 } from "lucide-react"; import { LogitLensWidget } from "nnsightful"; import type { LogitLensData } from "nnsightful"; +import { NotebookExporter } from "@/components/NotebookExporter"; interface Lens2Chart { id: string; data: Lens2Data | null; type: string; + name?: string; +} + +interface Lens2Config { + id: string; + data: Lens2ConfigData; + type: string; } export function Lens2Display() { - const { chartId } = useParams<{ chartId: string }>(); + const { chartId, workspaceId } = useParams<{ chartId: string; workspaceId: string }>(); const { resolvedTheme } = useTheme(); const isDarkMode = resolvedTheme === "dark"; @@ -29,7 +38,20 @@ export function Lens2Display() { enabled: !!chartId, }); + const { data: config } = useQuery({ + queryKey: queryKeys.charts.configByChart(chartId), + queryFn: () => getConfigForChart(chartId), + enabled: !!chartId, + }); + + const { data: workspace } = useQuery({ + queryKey: queryKeys.workspaces.workspace(workspaceId), + queryFn: () => getWorkspaceById(workspaceId), + enabled: !!workspaceId, + }); + const lens2Chart = chart as Lens2Chart | undefined; + const lens2Config = config as Lens2Config | undefined; const hasData = lens2Chart?.data && "meta" in lens2Chart.data; // Loading state @@ -65,6 +87,15 @@ export function Lens2Display() { return (
+
+ } + chartData={(lens2Chart?.data ?? null) as Record | null} + chartName={lens2Chart?.name ?? undefined} + workspaceName={(workspace as { name?: string } | undefined)?.name ?? undefined} + /> +