diff --git a/interpretability/sparse_autoencoders/pyproject.toml b/interpretability/sparse_autoencoders/pyproject.toml
index 1cdda03695..6bc4900b00 100644
--- a/interpretability/sparse_autoencoders/pyproject.toml
+++ b/interpretability/sparse_autoencoders/pyproject.toml
@@ -32,4 +32,4 @@ where = ["."]
include = []
[tool.uv.workspace]
-members = ["sae", "recipes/esm2"]
+members = ["sae", "recipes/esm2", "recipes/gpt2"]
diff --git a/interpretability/sparse_autoencoders/recipes/evo2/feature_explorer/src/Dashboard.jsx b/interpretability/sparse_autoencoders/recipes/evo2/feature_explorer/src/Dashboard.jsx
index 9eff834811..892b590521 100644
--- a/interpretability/sparse_autoencoders/recipes/evo2/feature_explorer/src/Dashboard.jsx
+++ b/interpretability/sparse_autoencoders/recipes/evo2/feature_explorer/src/Dashboard.jsx
@@ -4,7 +4,7 @@ import GenerativeSteering from './GenerativeSteering'
import SequenceInspector from './SequenceInspector'
import SequenceUMAPView, { EMBEDDINGS_URL } from './SequenceUMAPView'
import { Sun, Moon } from 'lucide-react'
-import { useHealth } from './backend'
+import { useHealth, UI } from './backend'
// Four-tab shell with graceful degradation when there's no live backend:
// offline:true -> always available (reads static files only)
@@ -64,6 +64,12 @@ export default function Dashboard() {
document.documentElement.classList.toggle('dark', dark)
}, [dark])
+ // Keep the tab title in sync with the (possibly server-overridden) brand. `health` re-renders
+ // after useHealth merges the /health `ui` block into UI, so the title picks up UI.brand then.
+ useEffect(() => {
+ document.title = UI.brand
+ }, [health])
+
// Probe for a precomputed Sequence-UMAP bundle so that tab survives without a backend.
useEffect(() => {
fetch(EMBEDDINGS_URL, { method: 'HEAD' })
@@ -84,7 +90,7 @@ export default function Dashboard() {
return (
-
Evo 2 SAE Feature Explorer
+
{UI.brand}
{TABS.map((t) => (