fix: util parsing and ajust structure

This commit is contained in:
Vukasin 2025-07-29 23:34:02 +02:00
parent 8ee6d79858
commit 612e5c6d74
6 changed files with 111 additions and 11 deletions

View File

@ -26,7 +26,16 @@ class WorkflowParser:
self.step_counter = 0
self.parsed_steps = []
filtered_steps = [step for step in steps if step.get('name') != 'Start' or step.get('description') != 'Click to add steps or use the Add Node button']
start_node = next(
(step for step in steps if step.get('name') == 'Start' and step.get('description') == 'Click to add steps or use the Add Node button'),
None
)
if start_node and "children" in start_node:
filtered_steps = start_node["children"]
else:
# fallback: use top-level list (for backward compat)
filtered_steps = steps
return self._parse_steps_recursive(filtered_steps)
@ -143,6 +152,22 @@ class WorkflowParser:
total_steps, total_conditions, max_nesting_depth = count_steps_recursive(steps)
# Large debug print to show inputs and parsed output
print("=" * 80)
print("WORKFLOW PARSER DEBUG - get_workflow_summary")
print("=" * 80)
print(f"INPUT STEPS:")
print(f"Type: {type(steps)}")
print(f"Length: {len(steps) if isinstance(steps, list) else 'N/A'}")
print(f"Raw steps: {steps}")
print("-" * 80)
print(f"PARSED OUTPUT:")
print(f"Total steps: {total_steps}")
print(f"Total conditions: {total_conditions}")
print(f"Max nesting depth: {max_nesting_depth}")
print(f"Has conditional logic: {total_conditions > 0}")
print("=" * 80)
return {
"total_steps": total_steps,
"total_conditions": total_conditions,

View File

@ -15,6 +15,7 @@ import { ConditionalStep } from '@/components/agents/workflows/conditional-workf
import { WorkflowBuilder } from '@/components/workflows/workflow-builder';
const convertToNestedJSON = (steps: ConditionalStep[]): any[] => {
// Since we're using the old structure directly, just pass it through
let globalOrder = 1;
const convertStepsWithNesting = (stepList: ConditionalStep[]): any[] => {
return stepList.map((step) => {
@ -40,7 +41,18 @@ const convertToNestedJSON = (steps: ConditionalStep[]): any[] => {
};
const reconstructFromNestedJSON = (nestedSteps: any[]): ConditionalStep[] => {
if (!nestedSteps || nestedSteps.length === 0) return [];
if (!nestedSteps || nestedSteps.length === 0) {
// Return default root structure if no steps
return [{
id: 'start-node',
name: 'Start',
description: 'Click to add steps or use the Add Node button',
type: 'instruction',
config: {},
order: 0,
children: []
}];
}
const convertStepsFromNested = (stepList: any[]): ConditionalStep[] => {
return stepList.map((step) => {
@ -70,7 +82,25 @@ const reconstructFromNestedJSON = (nestedSteps: any[]): ConditionalStep[] => {
});
};
return convertStepsFromNested(nestedSteps);
const reconstructedSteps = convertStepsFromNested(nestedSteps);
// Make sure we have proper root structure
if (reconstructedSteps.length > 0 &&
reconstructedSteps[0].name === 'Start' &&
reconstructedSteps[0].description === 'Click to add steps or use the Add Node button') {
return reconstructedSteps;
}
// If not proper structure, wrap in root node
return [{
id: 'start-node',
name: 'Start',
description: 'Click to add steps or use the Add Node button',
type: 'instruction',
config: {},
order: 0,
children: reconstructedSteps
}];
};
const reconstructFromFlatJSON = (flatSteps: any[]): ConditionalStep[] => {

View File

@ -33,6 +33,17 @@ interface WorkflowBuilderProps {
onDescriptionChange?: (description: string) => void;
}
// Root node structure that parser expects
const createRootNode = (children: ConditionalStep[] = []): ConditionalStep => ({
id: 'start-node',
name: 'Start',
description: 'Click to add steps or use the Add Node button',
type: 'instruction',
config: {},
order: 0,
children: children
});
export function WorkflowBuilder({
steps,
onStepsChange,
@ -48,6 +59,38 @@ export function WorkflowBuilder({
onNameChange,
onDescriptionChange
}: WorkflowBuilderProps) {
// Ensure we always have the proper root structure
const workflowSteps = useMemo(() => {
// If we don't have steps or it's not the right structure, create proper root
if (!steps || steps.length === 0) {
return [createRootNode()];
}
// Check if we already have proper root structure
const firstStep = steps[0];
if (firstStep &&
firstStep.name === 'Start' &&
firstStep.description === 'Click to add steps or use the Add Node button' &&
firstStep.type === 'instruction' &&
Array.isArray(firstStep.children)) {
return steps;
}
// If we have flat structure, wrap it in root node
return [createRootNode(steps)];
}, [steps]);
// Get the actual workflow children (the steps we edit)
const editableSteps = useMemo(() => {
return workflowSteps[0]?.children || [];
}, [workflowSteps]);
// Handle changes to the editable steps
const handleStepsChange = useCallback((newSteps: ConditionalStep[]) => {
const updatedWorkflow = [createRootNode(newSteps)];
onStepsChange(updatedWorkflow);
}, [onStepsChange]);
const [isPanelOpen, setIsPanelOpen] = useState(false);
const [panelMode, setPanelMode] = useState<'add' | 'edit'>('add');
const [selectedStep, setSelectedStep] = useState<ConditionalStep | null>(null);
@ -66,8 +109,8 @@ export function WorkflowBuilder({
getAvailableStepTypes,
STEP_CATEGORIES
} = useWorkflowSteps({
steps,
onStepsChange,
steps: editableSteps, // Work with the children array
onStepsChange: handleStepsChange, // Update the root structure
agentTools,
setIsPanelOpen,
setPanelMode,
@ -105,7 +148,7 @@ export function WorkflowBuilder({
>
<div className="min-h-full bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
<div className="mx-auto max-w-3xl md:px-8 min-w-0 py-8">
{steps.length === 0 ? (
{editableSteps.length === 0 ? (
// Empty state
<div className="flex-1 min-h-[60vh] flex items-center justify-center">
<div className="text-center">
@ -125,17 +168,17 @@ export function WorkflowBuilder({
</div>
</div>
) : (
// Steps list
// Steps list - uses the children array from root node
<div className="space-y-8 min-w-0">
<WorkflowSteps
steps={steps}
steps={editableSteps}
onAddStep={handleAddStep}
onEditStep={handleEditStep}
onUpdateStep={handleUpdateStep}
onDeleteStep={handleDeleteStep}
onAddElseIf={handleAddElseIf}
onAddElse={handleAddElse}
onStepsChange={onStepsChange}
onStepsChange={handleStepsChange}
agentTools={agentTools}
isLoadingTools={isLoadingTools}
/>

View File

@ -180,10 +180,10 @@ export function WorkflowSidePanel({
{/* Tool configuration */}
{selectedStep.config?.tool_name && (
<div className="p-4 bg-zinc-50 dark:bg-zinc-900/50 rounded-lg border border-zinc-200 dark:border-zinc-800">
<div className="p-4 bg-zinc-50 dark:bg-zinc-900/50 rounded-xl border border-zinc-200 dark:border-zinc-800">
<div className="font-medium text-sm mb-2 text-zinc-900 dark:text-zinc-100">Tool Configuration</div>
<div className="text-sm text-zinc-600 dark:text-zinc-400">
Using: <Badge variant="secondary" className="ml-1">{selectedStep.config.tool_name}</Badge>
Using: <Badge variant="default" className="ml-1">{selectedStep.config.tool_name}</Badge>
</div>
</div>
)}

View File

@ -0,0 +1 @@