diff --git a/apps/rowboat/app/projects/[projectId]/workflow/workflow_editor.tsx b/apps/rowboat/app/projects/[projectId]/workflow/workflow_editor.tsx index 1e1c6268..a1ab84fd 100644 --- a/apps/rowboat/app/projects/[projectId]/workflow/workflow_editor.tsx +++ b/apps/rowboat/app/projects/[projectId]/workflow/workflow_editor.tsx @@ -91,6 +91,7 @@ export type Action = { } | { type: "add_pipeline"; pipeline: Partial>; + defaultModel?: string; } | { type: "select_agent"; name: string; @@ -437,50 +438,84 @@ function reducer(state: State, action: Action): State { draft.chatKey++; break; } + // TODO: parameterize this instead of writing if else based on pipeline length (pipelineAgents.length) case "add_pipeline": { if (isLive) { break; } - let newPipelineName = "New pipeline"; - if (draft.workflow?.pipelines?.some((pipeline) => pipeline.name === newPipelineName)) { - newPipelineName = `New pipeline ${(draft.workflow?.pipelines?.filter((pipeline) => - pipeline.name.startsWith("New pipeline")).length || 0) + 1}`; - } + if (!draft.workflow.pipelines) { draft.workflow.pipelines = []; } - // Create the first agent for this pipeline - const firstAgentName = `${action.pipeline.name || newPipelineName} Step 1`; - draft.workflow.agents.push({ - name: firstAgentName, - type: "pipeline", - description: "", - disabled: false, - instructions: "", - model: "gpt-4o", - locked: false, - toggleAble: true, - ragReturnType: "chunks", - ragK: 3, - controlType: "relinquish_to_parent", - outputVisibility: "internal", - maxCallsPerParentAgent: 3, - }); + // 1. ✅ Create the pipeline definition FIRST with the action data + const pipelineName = action.pipeline.name || "New pipeline"; + const pipelineDescription = action.pipeline.description || ""; + let pipelineAgents = action.pipeline.agents || []; - // Create the pipeline with the first agent + // 2. ✅ Handle manual creation (no agents provided) vs copilot creation (agents provided) + if (pipelineAgents.length === 0) { + // Manual creation: create a default first agent to prevent 0-step pipelines + const defaultAgentName = `${pipelineName} Step 1`; + pipelineAgents = [defaultAgentName]; + + // Create the default agent + draft.workflow.agents.push({ + name: defaultAgentName, + type: "pipeline", + description: `Default agent for ${pipelineName} pipeline`, + disabled: false, + instructions: `You are the first step in the ${pipelineName} pipeline. Focus on your specific role.`, + model: action.defaultModel || "gpt-4.1", + locked: false, + toggleAble: true, + ragReturnType: "chunks", + ragK: 3, + controlType: "relinquish_to_parent", + outputVisibility: "internal", + maxCallsPerParentAgent: 3, + }); + } else { + // Copilot creation: ensure all referenced agents exist + for (const agentName of pipelineAgents) { + const existingAgent = draft.workflow.agents.find(a => a.name === agentName); + if (!existingAgent) { + // Create the agent with proper pipeline type + draft.workflow.agents.push({ + name: agentName, + type: "pipeline", + description: `Agent for ${pipelineName} pipeline`, + disabled: false, + instructions: `You are part of the ${pipelineName} pipeline. Focus on your specific role.`, + model: action.defaultModel || "gpt-4.1", + locked: false, + toggleAble: true, + ragReturnType: "chunks", + ragK: 3, + controlType: "relinquish_to_parent", + outputVisibility: "internal", + maxCallsPerParentAgent: 3, + }); + } + } + } + + // 3. ✅ Create the pipeline with the agents draft.workflow.pipelines.push({ - name: newPipelineName, - description: "", - agents: [firstAgentName], + name: pipelineName, + description: pipelineDescription, + agents: pipelineAgents, ...action.pipeline }); - // Select the newly created agent to open it in agent_config - draft.selection = { - type: "agent", - name: firstAgentName - }; + // 4. ✅ Select the first agent for configuration + if (pipelineAgents.length > 0) { + draft.selection = { + type: "agent", + name: pipelineAgents[0] + }; + } + draft.pendingChanges = true; draft.chatKey++; break; @@ -1056,7 +1091,7 @@ export function WorkflowEditor({ function handleAddAgent(agent: Partial> = {}) { const agentWithModel = { ...agent, - model: agent.model || defaultModel || "gpt-4o" + model: agent.model || defaultModel || "gpt-4.1" }; dispatch({ type: "add_agent", agent: agentWithModel }); } @@ -1074,7 +1109,7 @@ export function WorkflowEditor({ } function handleAddPipeline(pipeline: Partial> = {}) { - dispatch({ type: "add_pipeline", pipeline }); + dispatch({ type: "add_pipeline", pipeline, defaultModel }); } function handleDeletePipeline(name: string) { @@ -1091,7 +1126,7 @@ export function WorkflowEditor({ name: newAgentName, type: 'pipeline' as const, outputVisibility: 'internal' as const, - model: defaultModel || "gpt-4o" + model: defaultModel || "gpt-4.1" }; // First add the agent