Skip to content

Commit 9ef5cf0

Browse files
authored
fix(webapp): stop showing the in-dashboard agent to admins by default (#4050)
## Summary The in-dashboard agent button was rendered for all admins and impersonators regardless of the `hasDashboardAgentAccess` flag, so it appeared even where the agent is disabled (for example, floating over the run inspector controls). It is now gated by the flag for everyone, so it stays hidden until the flag is turned on. ## Rollout Both levers default off, so nothing changes for users until deliberately enabled: - **Per-org:** set `hasDashboardAgentAccess` on an org's feature flags to enable the agent for just that org. - **All admins:** set `DASHBOARD_AGENT_ADMIN_PREVIEW=1` to give admins and impersonators an everywhere-preview, independent of the per-org flag. Previously admins bypassed the flag unconditionally, which is why the button showed up before the agent was ready to ship.
1 parent df78ef9 commit 9ef5cf0

3 files changed

Lines changed: 10 additions & 7 deletions

File tree

apps/webapp/app/env.server.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,11 @@ const EnvironmentSchema = z
108108
DASHBOARD_AGENT_SECRET_KEY: z.string().optional(),
109109
// Global default for the `hasDashboardAgentAccess` flag. "0" (off) ships the
110110
// agent dark; flip to "1" to enable it for everyone at GA. Per-org overrides
111-
// (org featureFlags) and admins/impersonators win regardless.
111+
// (org featureFlags) win regardless.
112112
DASHBOARD_AGENT_ENABLED: z.string().default("0"),
113+
// "1" gives admins/impersonators an everywhere-preview (default off),
114+
// separate from the per-org rollout flag above.
115+
DASHBOARD_AGENT_ADMIN_PREVIEW: z.string().default("0"),
113116
// Anthropic key for the dashboard agent's Head Start route only (the warm
114117
// first-turn step-1 LLM call runs in this process). The agent run itself
115118
// uses its own key on the Trigger side. When unset, Head Start is disabled

apps/webapp/app/v3/canAccessDashboardAgent.server.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ import { makeFlag } from "~/v3/featureFlags.server";
55

66
/**
77
* Whether the in-dashboard AI agent is available to this user in this org.
8-
* Mirrors `canAccessAi`: admins/impersonators always pass, then the global /
9-
* per-org feature flag with `DASHBOARD_AGENT_ENABLED` as the global default, so
10-
* a per-org override (incl. disabling it) wins. Enforced server-side so a
11-
* non-flagged user can't start sessions by hitting the resource route directly.
8+
* Gated by the global / per-org `hasDashboardAgentAccess` flag, with
9+
* `DASHBOARD_AGENT_ENABLED` as the global default (a per-org override wins).
10+
* Admins/impersonators bypass it only when `DASHBOARD_AGENT_ADMIN_PREVIEW` is on
11+
* (default off). Enforced server-side so a non-flagged user can't start sessions.
1212
*/
1313
export async function canAccessDashboardAgent(options: {
1414
userId: string;
@@ -22,7 +22,7 @@ export async function canAccessDashboardAgent(options: {
2222
}): Promise<boolean> {
2323
const { userId, isAdmin, isImpersonating, organizationSlug, orgFeatureFlags } = options;
2424

25-
if (isAdmin || isImpersonating) {
25+
if ((isAdmin || isImpersonating) && env.DASHBOARD_AGENT_ADMIN_PREVIEW === "1") {
2626
return true;
2727
}
2828

apps/webapp/app/v3/featureFlags.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export const FeatureFlagCatalog = {
2727
[FEATURE_FLAG.hasLogsPageAccess]: z.coerce.boolean(),
2828
[FEATURE_FLAG.hasAiAccess]: z.coerce.boolean(),
2929
// Gates the in-dashboard AI agent panel. Controllable globally and per-org
30-
// (org wins); admins/impersonators always see it. Defaults off via DASHBOARD_AGENT_ENABLED.
30+
// (org wins). Defaults off via DASHBOARD_AGENT_ENABLED.
3131
[FEATURE_FLAG.hasDashboardAgentAccess]: z.coerce.boolean(),
3232
[FEATURE_FLAG.hasComputeAccess]: z.coerce.boolean(),
3333
[FEATURE_FLAG.hasPrivateConnections]: z.coerce.boolean(),

0 commit comments

Comments
 (0)