# ai-workflow-creator > Generate CasareRPA workflows automatically from natural language prompts with automatic validation and self-healing. Creates workflow JSON using WorkflowBuilder, validates with test_workflow.py, and auto-fixes common errors. Use when: user asks to create workflow, automate task, build RPA flow, generate workflow from description. - Author: CasareRPA Developer - Repository: omerlefaruk/CasareRPA - Version: 20260122083346 - Stars: 0 - Forks: 0 - Last Updated: 2026-02-06 - Source: https://github.com/omerlefaruk/CasareRPA - Web: https://mule.run/skillshub/@@omerlefaruk/CasareRPA~ai-workflow-creator:20260122083346 --- --- name: ai-workflow-creator description: Generate CasareRPA workflows automatically from natural language prompts with automatic validation and self-healing. Creates workflow JSON using WorkflowBuilder, validates with test_workflow.py, and auto-fixes common errors. Use when: user asks to create workflow, automate task, build RPA flow, generate workflow from description. allowed-tools: Bash, Read, Write --- # AI Workflow Creator Generate complete CasareRPA workflow JSON files from natural language descriptions. ## Quick Start When user asks to create a workflow: 1. **Parse requirements** - Extract automation steps from user's prompt 2. **Select nodes** - Choose appropriate nodes from [NODES.md](references/NODES.md) 3. **Build workflow** - Use WorkflowBuilder to create valid JSON 4. **Save file** - Output to `workflows/.json` 5. **Execute first** - **CRITICAL: Run the actual workflow BEFORE validation to verify data flow** 6. **Verify output** - Check that the workflow produces the expected result (CSV, data, screenshots) 7. **Validate** - Run `test_workflow.py` and auto-fix if needed 8. **Self-heal** - Fix any issues and re-validate **IMPORTANT:** Always execute the workflow to verify it produces the expected output. Validation only checks structure - execution checks behavior. See [examples/](examples/) for complete workflow patterns. ## Critical Gotchas (READ BEFORE BUILDING) ### BrowserRunScriptNode Does NOT Store to Context Variables **Problem:** `BrowserRunScriptNode` returns via output port `result`, but does NOT support `output_var` parameter. **Solution:** Always use `SetVariableNode` to bridge the result to a context variable: ```python # WRONG - output_var is ignored! script_node = wb.add_node("BrowserRunScriptNode", config={ "script": "result = [1, 2, 3]", "output_var": "my_data" # DOES NOTHING! }) # CORRECT - Use SetVariableNode to store script_node = wb.add_node("BrowserRunScriptNode", config={ "script": "result = [1, 2, 3]" }) store_node = wb.add_node("SetVariableNode", config={ "variable_name": "my_data" }) wb.connect(script_node, "result", store_node, "value") ``` ### LogNode Requires `data` Port **Problem:** `LogNode` has a required `data` input port that causes validation errors if not connected. **Solution:** Either provide data or skip LogNode entirely in generated workflows. ### Google Consent Dialog **Problem:** Google shows a consent wall that blocks search results. **Solution:** Handle consent in script or use DuckDuckGo as alternative. ## Browser Automation: Playwright Discovery (MANDATORY) **For any browser automation workflow, FIRST use Playwright to discover actual selectors.** ### Step 1: Launch Discovery Session ```python import asyncio from playwright.async_api import async_playwright async def discover_selectors(url: str): async with async_playwright() as p: browser = await p.chromium.launch(headless=False) page = await browser.new_page() await page.goto(url) # Pause for manual inspection print("Press Enter in terminal when ready to capture selectors...") input() # Capture available elements buttons = await page.query_selector_all("button") inputs = await page.query_selector_all("input") links = await page.query_selector_all("a") print(f"Found {len(buttons)} buttons, {len(inputs)} inputs, {len(links)} links") # Get specific element info for i, btn in enumerate(buttons[:5]): text = await btn.inner_text() print(f"Button {i}: '{text[:30]}...' - selector: button:nth-of-type({i+1})") await browser.close() asyncio.run(discover_selectors("https://example.com")) ``` ### Step 2: Test Selectors Work ```python # Test before adding to workflow element = await page.query_selector("#my-button") if element: print("Selector works!") else: print("Selector NOT found - try alternatives") ``` ### Step 3: Update Workflow with Validated Selectors Only use selectors that passed testing in the final workflow. ## Core Workflow Pattern Every workflow needs: ```python from casare_rpa.tools.workflow_builder import WorkflowBuilder wb = WorkflowBuilder() wb.workflow_data["metadata"] = { "name": "Workflow Name", "description": "Human-readable description", "version": "1.0.0", "author": "AI Workflow Creator", "tags": ["automation", "browser"], } # Position variables for clean layout x, y = 0, 0 x_step = 250 # Horizontal spacing y_step = 150 # Vertical spacing (if wrapping) # Always start with StartNode start_id = wb.add_node("StartNode", position=(x, y)) # Add automation nodes with proper spacing x += x_step node_id = wb.add_node("NodeType", config={"key": "value"}, position=(x, y)) # Connect: exec_out -> exec_in for flow wb.connect(start_id, "exec_out", node_id, "exec_in") # Save wb.save("workflows/output.json") ``` ## Visual Layout Guidelines | Rule | Value | Reason | |------|-------|--------| | Horizontal step (x) | 250px | Prevents node overlap | | Vertical step (y) | 150px | For multi-row layouts | | Start position | (0, 0) | Top-left origin | | Single row | All y=0 | Linear workflows | | Multi-row | Increment y by y_step | Complex workflows | ## Common Node Patterns | Task | Node | Config Example | |------|------|----------------| | Launch browser | `LaunchBrowserNode` | `{"headless": false, "browser": "chromium"}` | | Navigate | `GoToURLNode` | `{"url": "https://example.com", "timeout": 30000}` | | Click | `ClickElementNode` | `{"selector": "#button", "timeout": 5000}` | | Type text | `TypeTextNode` | `{"selector": "#input", "text": "value"}` | | Extract text | `ExtractTextNode` | `{"selector": ".content", "output_var": "result"}` | | Wait | `WaitNode` | `{"duration_ms": 1000}` | | Screenshot | `ScreenshotNode` | `{"file_path": "screenshots/capture.png"}` | ## Port Naming Rules - **Flow ports**: `exec_in` / `exec_out` (always connect these for sequence) - **Data ports**: node-specific (e.g., `selector`, `timeout`, `url`) ## Control Flow Patterns ### Loops ```python # For loop over list for_start = wb.add_node("ForLoopStartNode", config={"list_name": "items"}) for_end = wb.add_node("ForLoopEndNode") wb.connect(for_start, "exec_out", "next_node", "exec_in") wb.connect("next_node", "exec_out", for_end, "exec_in") ``` ### Conditionals ```python if_node = wb.add_node("IfNode", config={"condition": "${variable} > 0"}) merge_node = wb.add_node("MergeNode") # Connect if branches to merge ``` ### Error Handling ```python try_node = wb.add_node("TryNode") catch_node = wb.add_node("CatchNode", config={"error_var": "error"}) ``` ## Selector Strategies | Situation | Selector | |-----------|----------| | ID | `#element-id` | | Class | `.class-name` | | Attribute | `[data-testid="submit"]` | | Text contains | `text="Submit"` | | Combined | `button.primary[type="submit"]` | ## Variable Usage ```python # Set variable set_var = wb.add_node("SetVariableNode", config={ "variable_name": "my_var", "value": "static value" }) # Get/use variable get_var = wb.add_node("GetVariableNode", config={ "variable_name": "my_var", "output_var": "result" }) # In conditions, use ${variable_name} syntax if_node = wb.add_node("IfNode", config={ "condition": "${my_var} == 'expected'" }) ``` ## Validation Checklist Before saving, verify: - [ ] Every workflow has `StartNode` (or starts execution) - [ ] All exec connections form a valid path - [ ] No circular dependencies (use loop nodes instead) - [ ] All node_types exist in NODE_REGISTRY - [ ] Selector strings are properly escaped - [ ] Positions form a logical left-to-right flow ## Script Generation For `BrowserRunScriptNode` or custom Python: ```python wb.inject_script(node_id, """ # Multi-line script with automatic JSON escaping result = await page.evaluate("document.title") """) ``` ## Testing & Self-Healing (MANDATORY) **Every generated workflow MUST be tested and validated.** ### Step 1: Run Validation (Always) After saving, immediately validate: ```bash python .claude/skills/ai-workflow-creator/scripts/test_workflow.py workflows/output.json ``` ### Step 2: Auto-Fix if Issues Found If validation fails, run with auto-fix: ```bash python .claude/skills/ai-workflow-creator/scripts/test_workflow.py workflows/output.json --fix ``` This automatically fixes: - Duplicate node IDs - Orphaned connections - Self-connections - Missing metadata ### Step 3: Background Execution Test For browser workflows, run a background execution test: ```bash # Run in background with timeout python scripts/validate_test_workflows.py ``` ### Step 4: Self-Healing Loop If errors persist after auto-fix: 1. **Read the error report** - Note specific error codes 2. **Apply targeted fix** based on error code: - `ORPHANED_CONNECTION` → Remove connection or add missing node - `CIRCULAR_DEPENDENCY` → Use loop nodes instead of circular connections - `UNKNOWN_NODE_TYPE` → Check NODES.md for valid node name - `INVALID_PORT_NAME` → Use snake_case (exec_in, exec_out, etc.) 3. **Re-validate** until all tests pass ### Error Code Reference | Code | Fix | |------|-----| | `ORPHANED_CONNECTION` | Remove connection or add missing node | | `SELF_CONNECTION` | Remove self-connection | | `DUPLICATE_NODE_ID` | Regenerate unique node IDs | | `CIRCULAR_DEPENDENCY` | Use loop nodes (ForLoop/WhileLoop) | | `UNKNOWN_NODE_TYPE` | Use valid type from NODES.md | | `INVALID_PORT_NAME` | Use snake_case for ports | | `UNREACHABLE_NODES` | Connect to main flow or remove | | `EMPTY_WORKFLOW` | Add StartNode + action node | ## References - [Complete node catalog](references/NODES.md) - All available nodes with configs - [Workflow examples](examples/WORKFLOW_EXAMPLES.md) - Common patterns - [Schema reference](references/SCHEMA.md) - WorkflowAISchema structure ## Output Format Always save to `workflows/.json` with: - Descriptive filename (kebab-case) - Proper metadata - Logical node positioning (left-to-right flow) - Helpful comments in config where complex