diff --git a/backend/flags/api.py b/backend/flags/api.py index b115dec9..b890d1c4 100644 --- a/backend/flags/api.py +++ b/backend/flags/api.py @@ -1,18 +1,11 @@ -from fastapi import APIRouter, Depends, HTTPException +from fastapi import APIRouter from utils.logger import logger from flags.flags import list_flags, is_enabled, get_flag_details -from utils.auth_utils import get_current_user_id_from_jwt - - router = APIRouter() - - @router.get("/feature-flags") -async def get_feature_flags(user_id: str = Depends(get_current_user_id_from_jwt)): - if not user_id: - raise HTTPException(status_code=401, detail="Unauthorized") +async def get_feature_flags(): try: flags = await list_flags() return {"flags": flags} @@ -20,12 +13,8 @@ async def get_feature_flags(user_id: str = Depends(get_current_user_id_from_jwt) logger.error(f"Error fetching feature flags: {str(e)}") return {"flags": {}} - - @router.get("/feature-flags/{flag_name}") -async def get_feature_flag(flag_name: str, user_id: str = Depends(get_current_user_id_from_jwt)): - if not user_id: - raise HTTPException(status_code=401, detail="Unauthorized") +async def get_feature_flag(flag_name: str): try: enabled = await is_enabled(flag_name) details = await get_flag_details(flag_name) diff --git a/frontend/src/app/(dashboard)/agents/page.tsx b/frontend/src/app/(dashboard)/agents/page.tsx index db49b818..7d96c6d4 100644 --- a/frontend/src/app/(dashboard)/agents/page.tsx +++ b/frontend/src/app/(dashboard)/agents/page.tsx @@ -16,6 +16,7 @@ import { Pagination } from './_components/pagination'; import { useRouter } from 'next/navigation'; import { DEFAULT_AGENTPRESS_TOOLS } from './_data/tools'; import { AgentsParams } from '@/hooks/react-query/agents/utils'; +import { useFeatureFlags } from '@/lib/feature-flags'; type ViewMode = 'grid' | 'list'; type SortOption = 'name' | 'created_at' | 'updated_at' | 'tools_count'; @@ -34,6 +35,7 @@ export default function AgentsPage() { const [editingAgentId, setEditingAgentId] = useState(null); const [viewMode, setViewMode] = useState('grid'); + // Server-side parameters const [page, setPage] = useState(1); const [searchQuery, setSearchQuery] = useState(''); diff --git a/frontend/src/app/(dashboard)/dashboard/_components/dashboard-content.tsx b/frontend/src/app/(dashboard)/dashboard/_components/dashboard-content.tsx index e5b65014..6021f0a2 100644 --- a/frontend/src/app/(dashboard)/dashboard/_components/dashboard-content.tsx +++ b/frontend/src/app/(dashboard)/dashboard/_components/dashboard-content.tsx @@ -33,7 +33,7 @@ import { useThreadQuery } from '@/hooks/react-query/threads/use-threads'; const PENDING_PROMPT_KEY = 'pendingAgentPrompt'; -export function DashboardContent({ customAgentsEnabled }: { customAgentsEnabled: boolean }) { +export function DashboardContent() { const [inputValue, setInputValue] = useState(''); const [isSubmitting, setIsSubmitting] = useState(false); const [autoSubmit, setAutoSubmit] = useState(false); @@ -198,7 +198,6 @@ export function DashboardContent({ customAgentsEnabled }: { customAgentsEnabled: selectedAgentId={selectedAgentId} onAgentSelect={setSelectedAgentId} variant="heading" - customAgentsEnabled={customAgentsEnabled} />

diff --git a/frontend/src/app/(dashboard)/dashboard/page.tsx b/frontend/src/app/(dashboard)/dashboard/page.tsx index 560dae13..ef80c942 100644 --- a/frontend/src/app/(dashboard)/dashboard/page.tsx +++ b/frontend/src/app/(dashboard)/dashboard/page.tsx @@ -5,7 +5,6 @@ import { Skeleton } from "@/components/ui/skeleton"; import { isFlagEnabled } from "@/lib/feature-flags"; export default async function DashboardPage() { - const customAgentsEnabled = await isFlagEnabled('custom_agents'); return ( } > - + ); } \ No newline at end of file diff --git a/frontend/src/components/dashboard/agent-selector.tsx b/frontend/src/components/dashboard/agent-selector.tsx index df12dd09..1c2cd869 100644 --- a/frontend/src/components/dashboard/agent-selector.tsx +++ b/frontend/src/components/dashboard/agent-selector.tsx @@ -15,13 +15,13 @@ import { useAgents } from '@/hooks/react-query/agents/use-agents'; import { useRouter } from 'next/navigation'; import { cn } from '@/lib/utils'; import { CreateAgentDialog } from '@/app/(dashboard)/agents/_components/create-agent-dialog'; +import { useFeatureFlags } from '@/lib/feature-flags'; interface AgentSelectorProps { onAgentSelect?: (agentId: string | undefined) => void; selectedAgentId?: string; className?: string; variant?: 'default' | 'heading'; - customAgentsEnabled?: boolean; } export function AgentSelector({ @@ -29,13 +29,16 @@ export function AgentSelector({ selectedAgentId, className, variant = 'default', - customAgentsEnabled = true }: AgentSelectorProps) { const { data: agentsResponse, isLoading, refetch: loadAgents } = useAgents({ limit: 100, sort_by: 'name', sort_order: 'asc' }); + + + const { flags, loading: flagsLoading } = useFeatureFlags(['custom_agents']); + const customAgentsEnabled = flags.custom_agents; const router = useRouter(); const [isOpen, setIsOpen] = useState(false); @@ -81,25 +84,6 @@ export function AgentSelector({ ); } - - return ( -

-
- -
-
- Suna - - Default - -
- - Your personal AI employee - -
-
-
- ); } if (isLoading) { diff --git a/frontend/src/lib/feature-flags.ts b/frontend/src/lib/feature-flags.ts index d98e5e65..c798d73a 100644 --- a/frontend/src/lib/feature-flags.ts +++ b/frontend/src/lib/feature-flags.ts @@ -1,5 +1,4 @@ import React from 'react'; -import { createClient } from './supabase/client'; const API_URL = process.env.NEXT_PUBLIC_BACKEND_URL || ''; @@ -39,13 +38,10 @@ export class FeatureFlagManager { if (cached && Date.now() - cached.timestamp < CACHE_DURATION) { return cached.value; } - const supabase = createClient(); - const { data: { session }} = await supabase.auth.getSession(); const response = await fetch(`${API_URL}/feature-flags/${flagName}`, { method: 'GET', headers: { 'Content-Type': 'application/json', - 'Authorization': `Bearer ${session?.access_token}`, }, }); if (!response.ok) { @@ -68,15 +64,11 @@ export class FeatureFlagManager { } async getFlagDetails(flagName: string): Promise { - const supabase = createClient(); - const { data: { session }} = await supabase.auth.getSession(); - try { const response = await fetch(`${API_URL}/feature-flags/${flagName}`, { method: 'GET', headers: { 'Content-Type': 'application/json', - 'Authorization': `Bearer ${session?.access_token}`, }, }); @@ -94,9 +86,6 @@ export class FeatureFlagManager { } async getAllFlags(): Promise> { - const supabase = createClient(); - const { data: { session }} = await supabase.auth.getSession(); - try { if (globalFlagsCache && Date.now() - globalFlagsCache.timestamp < CACHE_DURATION) { return globalFlagsCache.flags; @@ -106,7 +95,6 @@ export class FeatureFlagManager { method: 'GET', headers: { 'Content-Type': 'application/json', - Authorization: `Bearer ${session.access_token}`, }, });