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.
This commit is contained in:
@@ -108,8 +108,11 @@ const EnvironmentSchema = z
|
||||
DASHBOARD_AGENT_SECRET_KEY: z.string().optional(),
|
||||
// Global default for the `hasDashboardAgentAccess` flag. "0" (off) ships the
|
||||
// agent dark; flip to "1" to enable it for everyone at GA. Per-org overrides
|
||||
// (org featureFlags) and admins/impersonators win regardless.
|
||||
// (org featureFlags) win regardless.
|
||||
DASHBOARD_AGENT_ENABLED: z.string().default("0"),
|
||||
// "1" gives admins/impersonators an everywhere-preview (default off),
|
||||
// separate from the per-org rollout flag above.
|
||||
DASHBOARD_AGENT_ADMIN_PREVIEW: z.string().default("0"),
|
||||
// Anthropic key for the dashboard agent's Head Start route only (the warm
|
||||
// first-turn step-1 LLM call runs in this process). The agent run itself
|
||||
// uses its own key on the Trigger side. When unset, Head Start is disabled
|
||||
|
||||
@@ -5,10 +5,10 @@ import { makeFlag } from "~/v3/featureFlags.server";
|
||||
|
||||
/**
|
||||
* Whether the in-dashboard AI agent is available to this user in this org.
|
||||
* Mirrors `canAccessAi`: admins/impersonators always pass, then the global /
|
||||
* per-org feature flag with `DASHBOARD_AGENT_ENABLED` as the global default, so
|
||||
* a per-org override (incl. disabling it) wins. Enforced server-side so a
|
||||
* non-flagged user can't start sessions by hitting the resource route directly.
|
||||
* Gated by the global / per-org `hasDashboardAgentAccess` flag, with
|
||||
* `DASHBOARD_AGENT_ENABLED` as the global default (a per-org override wins).
|
||||
* Admins/impersonators bypass it only when `DASHBOARD_AGENT_ADMIN_PREVIEW` is on
|
||||
* (default off). Enforced server-side so a non-flagged user can't start sessions.
|
||||
*/
|
||||
export async function canAccessDashboardAgent(options: {
|
||||
userId: string;
|
||||
@@ -22,7 +22,7 @@ export async function canAccessDashboardAgent(options: {
|
||||
}): Promise<boolean> {
|
||||
const { userId, isAdmin, isImpersonating, organizationSlug, orgFeatureFlags } = options;
|
||||
|
||||
if (isAdmin || isImpersonating) {
|
||||
if ((isAdmin || isImpersonating) && env.DASHBOARD_AGENT_ADMIN_PREVIEW === "1") {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ export const FeatureFlagCatalog = {
|
||||
[FEATURE_FLAG.hasLogsPageAccess]: z.coerce.boolean(),
|
||||
[FEATURE_FLAG.hasAiAccess]: z.coerce.boolean(),
|
||||
// Gates the in-dashboard AI agent panel. Controllable globally and per-org
|
||||
// (org wins); admins/impersonators always see it. Defaults off via DASHBOARD_AGENT_ENABLED.
|
||||
// (org wins). Defaults off via DASHBOARD_AGENT_ENABLED.
|
||||
[FEATURE_FLAG.hasDashboardAgentAccess]: z.coerce.boolean(),
|
||||
[FEATURE_FLAG.hasComputeAccess]: z.coerce.boolean(),
|
||||
[FEATURE_FLAG.hasPrivateConnections]: z.coerce.boolean(),
|
||||
|
||||
Reference in New Issue
Block a user