From 75752ba70ae821d6ef63c11c781c02203e37342f Mon Sep 17 00:00:00 2001 From: Eric Allam Date: Wed, 1 Apr 2026 22:19:10 +0100 Subject: [PATCH 1/3] feat(dashboard): a few tweaks to the AI models page --- .../route.tsx | 44 ++++-------- .../route.tsx | 72 ++++++------------- 2 files changed, 33 insertions(+), 83 deletions(-) diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.models.$modelId/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.models.$modelId/route.tsx index 2d2a0ac850..610307b94b 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.models.$modelId/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.models.$modelId/route.tsx @@ -112,8 +112,8 @@ type Tab = "overview" | "global" | "usage"; const TAB_CONFIG: { id: Tab; label: string }[] = [ { id: "overview", label: "Overview" }, + { id: "usage", label: "Metrics" }, { id: "global", label: "Global Metrics" }, - { id: "usage", label: "Your Usage" }, ]; export default function ModelDetailPage() { @@ -425,16 +425,7 @@ function GlobalMetricsTab({ return (
{/* Big numbers */} -
-
- -
+
{/* Charts */} -
-
- -
-
- -
+
+
@@ -523,7 +503,7 @@ function YourUsageTab({
)} p50 TTFC - Calls (7d) @@ -397,9 +396,6 @@ function ModelsList({ {popular && popular.ttfcP50 > 0 ? `${popular.ttfcP50.toFixed(0)}ms` : "—"} - - {popular && popular.callCount > 0 ? formatNumberCompact(popular.callCount) : "—"} - ); })} @@ -718,20 +714,20 @@ function ModelDetailPanel({ Overview setTab("global")} - shortcut={{ key: "g" }} + onClick={() => setTab("usage")} + shortcut={{ key: "u" }} > - Global metrics + Metrics setTab("usage")} - shortcut={{ key: "u" }} + onClick={() => setTab("global")} + shortcut={{ key: "g" }} > - Your usage + Global metrics
@@ -876,18 +872,7 @@ function DetailGlobalMetricsTab({ return (
-
- -
-
+
-
+
-
+
-
- -
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
Date: Thu, 2 Apr 2026 13:38:47 +0100 Subject: [PATCH 2/3] Addressing review feedback, fixing slow fairqueue test --- .../route.tsx | 2 +- packages/redis-worker/src/fair-queue/tests/fairQueue.test.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.models.$modelId/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.models.$modelId/route.tsx index 610307b94b..7a25f996d4 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.models.$modelId/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.models.$modelId/route.tsx @@ -113,7 +113,7 @@ type Tab = "overview" | "global" | "usage"; const TAB_CONFIG: { id: Tab; label: string }[] = [ { id: "overview", label: "Overview" }, { id: "usage", label: "Metrics" }, - { id: "global", label: "Global Metrics" }, + { id: "global", label: "Global metrics" }, ]; export default function ModelDetailPage() { diff --git a/packages/redis-worker/src/fair-queue/tests/fairQueue.test.ts b/packages/redis-worker/src/fair-queue/tests/fairQueue.test.ts index d827da1590..f1634ad2fe 100644 --- a/packages/redis-worker/src/fair-queue/tests/fairQueue.test.ts +++ b/packages/redis-worker/src/fair-queue/tests/fairQueue.test.ts @@ -215,7 +215,7 @@ describe("FairQueue", () => { describe("basic enqueue and process", () => { redisTest( "should enqueue and process a single message", - { timeout: 15000 }, + { timeout: 30000 }, async ({ redisOptions }) => { const processed: string[] = []; keys = new DefaultFairQueueKeyProducer({ prefix: "test" }); From 54be5998e8fc0a41edd2bb58a2eb54cd272b6e10 Mon Sep 17 00:00:00 2001 From: Eric Allam Date: Thu, 2 Apr 2026 15:17:35 +0100 Subject: [PATCH 3/3] Cleanup AI feature flags to just a single one --- .../app/components/navigation/SideMenu.tsx | 2 +- apps/webapp/app/env.server.ts | 3 -- .../OrganizationsPresenter.server.ts | 1 + .../webapp/app/v3/canAccessAiModels.server.ts | 47 ------------------- apps/webapp/app/v3/featureFlags.ts | 2 - 5 files changed, 2 insertions(+), 53 deletions(-) delete mode 100644 apps/webapp/app/v3/canAccessAiModels.server.ts diff --git a/apps/webapp/app/components/navigation/SideMenu.tsx b/apps/webapp/app/components/navigation/SideMenu.tsx index 1169343e9d..14b3c56495 100644 --- a/apps/webapp/app/components/navigation/SideMenu.tsx +++ b/apps/webapp/app/components/navigation/SideMenu.tsx @@ -477,7 +477,7 @@ export function SideMenu({ data-action="prompts" isCollapsed={isCollapsed} /> - {(user.admin || user.isImpersonating || featureFlags.hasAiModelsAccess) && ( + {(user.admin || user.isImpersonating || featureFlags.hasAiAccess) && ( { - const { userId, isAdmin, isImpersonating, organizationSlug } = options; - - // 1. If env var is set then globally enabled - if (env.AI_MODELS_ENABLED === "1") { - return true; - } - - // 2. Admins always have access - if (isAdmin || isImpersonating) { - return true; - } - - // 3. Check if org/global feature flag is on - const org = await prisma.organization.findFirst({ - where: { - slug: organizationSlug, - members: { some: { userId } }, - }, - select: { - featureFlags: true, - }, - }); - - const flag = makeFlag(); - const flagResult = await flag({ - key: FEATURE_FLAG.hasAiModelsAccess, - defaultValue: false, - overrides: (org?.featureFlags as Record) ?? {}, - }); - if (flagResult) { - return true; - } - - // 4. Not enabled anywhere - return false; -} diff --git a/apps/webapp/app/v3/featureFlags.ts b/apps/webapp/app/v3/featureFlags.ts index 7571d27f67..24942ce14c 100644 --- a/apps/webapp/app/v3/featureFlags.ts +++ b/apps/webapp/app/v3/featureFlags.ts @@ -7,7 +7,6 @@ export const FEATURE_FLAG = { hasQueryAccess: "hasQueryAccess", hasLogsPageAccess: "hasLogsPageAccess", hasAiAccess: "hasAiAccess", - hasAiModelsAccess: "hasAiModelsAccess", hasComputeAccess: "hasComputeAccess", hasPrivateConnections: "hasPrivateConnections", } as const; @@ -19,7 +18,6 @@ export const FeatureFlagCatalog = { [FEATURE_FLAG.hasQueryAccess]: z.coerce.boolean(), [FEATURE_FLAG.hasLogsPageAccess]: z.coerce.boolean(), [FEATURE_FLAG.hasAiAccess]: z.coerce.boolean(), - [FEATURE_FLAG.hasAiModelsAccess]: z.coerce.boolean(), [FEATURE_FLAG.hasComputeAccess]: z.coerce.boolean(), [FEATURE_FLAG.hasPrivateConnections]: z.coerce.boolean(), };