import { createClient } from "@/lib/supabase/client"; import { isFlagEnabled } from "@/lib/feature-flags"; const API_URL = process.env.NEXT_PUBLIC_BACKEND_URL || ''; export interface WorkflowStep { id: string; name: string; description?: string; type: string; config: Record; conditions?: Record; order: number; created_at: string; updated_at: string; } export interface AgentWorkflow { id: string; agent_id: string; name: string; description?: string; status: 'draft' | 'active' | 'paused' | 'archived'; trigger_phrase?: string; is_default: boolean; steps: WorkflowStep[]; created_at: string; updated_at: string; } export interface WorkflowExecution { id: string; workflow_id: string; agent_id: string; thread_id?: string; status: 'pending' | 'running' | 'completed' | 'failed' | 'cancelled'; started_at: string; completed_at?: string; duration_seconds?: number; triggered_by: string; input_data?: Record; output_data?: Record; error_message?: string; created_at: string; } export interface CreateWorkflowRequest { name: string; description?: string; trigger_phrase?: string; is_default?: boolean; steps: Array<{ name: string; description?: string; type?: string; config?: Record; conditions?: Record; order: number; }>; } export interface UpdateWorkflowRequest { name?: string; description?: string; trigger_phrase?: string; is_default?: boolean; status?: 'draft' | 'active' | 'paused' | 'archived'; steps?: Array<{ name: string; description?: string; type?: string; config?: Record; conditions?: Record; order: number; }>; } export interface ExecuteWorkflowRequest { input_data?: Record; thread_id?: string; } export interface LLMWorkflowStep { step: string; description?: string; tool?: string; condition?: string; then?: LLMWorkflowStep[]; } export interface LLMWorkflowFormat { workflow: string; description?: string; steps: LLMWorkflowStep[]; } export const convertWorkflowToLLMFormat = (workflow: AgentWorkflow): LLMWorkflowFormat => { const convertSteps = (steps: any[]): LLMWorkflowStep[] => { return steps.map(step => { const llmStep: LLMWorkflowStep = { step: step.name, }; if (step.description) { llmStep.description = step.description; } if (step.config?.tool_name) { llmStep.tool = step.config.tool_name; } if (step.type === 'condition' && step.conditions) { if (step.conditions.type === 'if' && step.conditions.expression) { llmStep.condition = step.conditions.expression; } else if (step.conditions.type === 'else') { llmStep.condition = 'else'; } } if (step.steps && step.steps.length > 0) { llmStep.then = convertSteps(step.steps); } return llmStep; }); }; const llmFormat: LLMWorkflowFormat = { workflow: workflow.name, steps: convertSteps(workflow.steps) }; if (workflow.description) { llmFormat.description = workflow.description; } return llmFormat; }; export const generateLLMWorkflowPrompt = (workflow: AgentWorkflow): string => { const llmFormat = convertWorkflowToLLMFormat(workflow); return JSON.stringify(llmFormat, null, 2); }; export const getAgentWorkflows = async (agentId: string): Promise => { try { const agentPlaygroundEnabled = await isFlagEnabled('custom_agents'); if (!agentPlaygroundEnabled) { throw new Error('Custom agents is not enabled'); } const supabase = createClient(); const { data: { session } } = await supabase.auth.getSession(); if (!session) { throw new Error('You must be logged in to get workflows'); } const response = await fetch(`${API_URL}/workflows/agents/${agentId}/workflows`, { method: 'GET', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${session.access_token}`, }, }); if (!response.ok) { const errorData = await response.json().catch(() => ({ detail: 'Unknown error' })); throw new Error(errorData.detail || `HTTP ${response.status}: ${response.statusText}`); } const workflows = await response.json(); console.log('[API] Fetched workflows for agent:', agentId, workflows.length); return workflows; } catch (err) { console.error('Error fetching workflows:', err); throw err; } }; export const createAgentWorkflow = async (agentId: string, workflow: CreateWorkflowRequest): Promise => { try { const agentPlaygroundEnabled = await isFlagEnabled('custom_agents'); if (!agentPlaygroundEnabled) { throw new Error('Custom agents is not enabled'); } const supabase = createClient(); const { data: { session } } = await supabase.auth.getSession(); if (!session) { throw new Error('You must be logged in to create a workflow'); } const response = await fetch(`${API_URL}/workflows/agents/${agentId}/workflows`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${session.access_token}`, }, body: JSON.stringify(workflow), }); if (!response.ok) { const errorData = await response.json().catch(() => ({ detail: 'Unknown error' })); throw new Error(errorData.detail || `HTTP ${response.status}: ${response.statusText}`); } const result = await response.json(); console.log('[API] Created workflow:', result.id); return result; } catch (err) { console.error('Error creating workflow:', err); throw err; } }; export const updateAgentWorkflow = async ( agentId: string, workflowId: string, workflow: UpdateWorkflowRequest ): Promise => { try { console.log('[API] Updating workflow:', workflow); const agentPlaygroundEnabled = await isFlagEnabled('custom_agents'); if (!agentPlaygroundEnabled) { throw new Error('Custom agents is not enabled'); } const supabase = createClient(); const { data: { session } } = await supabase.auth.getSession(); if (!session) { throw new Error('You must be logged in to update a workflow'); } const response = await fetch(`${API_URL}/workflows/agents/${agentId}/workflows/${workflowId}`, { method: 'PUT', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${session.access_token}`, }, body: JSON.stringify(workflow), }); if (!response.ok) { const errorData = await response.json().catch(() => ({ detail: 'Unknown error' })); throw new Error(errorData.detail || `HTTP ${response.status}: ${response.statusText}`); } const result = await response.json(); console.log('[API] Updated workflow:', result.id); return result; } catch (err) { console.error('Error updating workflow:', err); throw err; } }; export const deleteAgentWorkflow = async (agentId: string, workflowId: string): Promise => { try { const agentPlaygroundEnabled = await isFlagEnabled('custom_agents'); if (!agentPlaygroundEnabled) { throw new Error('Custom agents is not enabled'); } const supabase = createClient(); const { data: { session } } = await supabase.auth.getSession(); if (!session) { throw new Error('You must be logged in to delete a workflow'); } const response = await fetch(`${API_URL}/workflows/agents/${agentId}/workflows/${workflowId}`, { method: 'DELETE', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${session.access_token}`, }, }); if (!response.ok) { const errorData = await response.json().catch(() => ({ detail: 'Unknown error' })); throw new Error(errorData.detail || `HTTP ${response.status}: ${response.statusText}`); } console.log('[API] Deleted workflow:', workflowId); } catch (err) { console.error('Error deleting workflow:', err); throw err; } }; export const executeWorkflow = async ( agentId: string, workflowId: string, execution: ExecuteWorkflowRequest ): Promise<{ execution_id: string; thread_id?: string; agent_run_id?: string; status: string; message?: string; }> => { try { const agentPlaygroundEnabled = await isFlagEnabled('custom_agents'); if (!agentPlaygroundEnabled) { throw new Error('Custom agents is not enabled'); } const supabase = createClient(); const { data: { session } } = await supabase.auth.getSession(); if (!session) { throw new Error('You must be logged in to execute a workflow'); } const response = await fetch(`${API_URL}/workflows/agents/${agentId}/workflows/${workflowId}/execute`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${session.access_token}`, }, body: JSON.stringify(execution), }); if (!response.ok) { const errorData = await response.json().catch(() => ({ detail: 'Unknown error' })); throw new Error(errorData.detail || `HTTP ${response.status}: ${response.statusText}`); } const result = await response.json(); console.log('[API] Executed workflow:', workflowId, 'execution:', result.execution_id); return result; } catch (err) { console.error('Error executing workflow:', err); throw err; } }; export const getWorkflowExecutions = async ( agentId: string, workflowId: string, limit: number = 20 ): Promise => { try { const agentPlaygroundEnabled = await isFlagEnabled('custom_agents'); if (!agentPlaygroundEnabled) { throw new Error('Custom agents is not enabled'); } const supabase = createClient(); const { data: { session } } = await supabase.auth.getSession(); if (!session) { throw new Error('You must be logged in to get workflow executions'); } const response = await fetch(`${API_URL}/workflows/agents/${agentId}/workflows/${workflowId}/executions?limit=${limit}`, { method: 'GET', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${session.access_token}`, }, }); if (!response.ok) { const errorData = await response.json().catch(() => ({ detail: 'Unknown error' })); throw new Error(errorData.detail || `HTTP ${response.status}: ${response.statusText}`); } const executions = await response.json(); console.log('[API] Fetched executions for workflow:', workflowId, executions.length); return executions; } catch (err) { console.error('Error fetching workflow executions:', err); throw err; } };