Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| import json | |
| from huggingface_hub import InferenceClient | |
| import time | |
| # Initialize the client (no API key needed for public models) | |
| def get_client(): | |
| return InferenceClient() | |
| client = get_client() | |
| st.set_page_config(page_title="n8n Workflow Generator", page_icon="π€", layout="wide") | |
| st.title("π€ n8n Workflow Generator") | |
| st.markdown("Generate n8n workflows from your ideas using AI - completely free!") | |
| # Sidebar for settings | |
| with st.sidebar: | |
| st.header("βοΈ Settings") | |
| model_choice = st.selectbox( | |
| "Select Model", | |
| ["Qwen/Qwen2.5-Coder-32B-Instruct", "meta-llama/Llama-3.2-3B-Instruct", "mistralai/Mistral-7B-Instruct-v0.3"], | |
| index=0 | |
| ) | |
| temperature = st.slider("Creativity", 0.1, 1.0, 0.7) | |
| st.markdown("---") | |
| st.markdown("### π How to Use") | |
| st.markdown("1. Describe your workflow idea\n2. Get enhanced suggestions\n3. Generate n8n JSON\n4. Import to n8n") | |
| # Main content | |
| col1, col2 = st.columns([1, 1]) | |
| with col1: | |
| st.header("π‘ Your Workflow Idea") | |
| user_idea = st.text_area( | |
| "Describe your workflow", | |
| placeholder="Example: Create a workflow that monitors GitHub issues, sends them to Slack, and logs them in Google Sheets", | |
| height=150 | |
| ) | |
| if st.button("π Enhance My Idea", type="primary", use_container_width=True): | |
| if user_idea: | |
| with st.spinner("Brainstorming enhancements..."): | |
| try: | |
| prompt = f"""You are an n8n workflow expert. A user wants to create this workflow: | |
| {user_idea} | |
| Provide 3-5 enhanced versions of this idea with: | |
| 1. Additional useful features | |
| 2. Error handling suggestions | |
| 3. Optimization tips | |
| 4. Integration possibilities | |
| Keep each suggestion concise but actionable. Format as a numbered list.""" | |
| response = client.text_generation( | |
| prompt, | |
| model=model_choice, | |
| max_new_tokens=800, | |
| temperature=temperature, | |
| return_full_text=False | |
| ) | |
| st.session_state['enhanced_ideas'] = response | |
| st.session_state['original_idea'] = user_idea | |
| except Exception as e: | |
| st.error(f"Error: {str(e)}") | |
| else: | |
| st.warning("Please enter a workflow idea first!") | |
| with col2: | |
| st.header("β¨ Enhanced Suggestions") | |
| if 'enhanced_ideas' in st.session_state: | |
| st.markdown(st.session_state['enhanced_ideas']) | |
| else: | |
| st.info("Click 'Enhance My Idea' to get AI-powered suggestions") | |
| st.markdown("---") | |
| # Generation section | |
| st.header("π Generate n8n Workflow") | |
| final_idea = st.text_area( | |
| "Final workflow description (edit if needed)", | |
| value=st.session_state.get('original_idea', ''), | |
| height=100, | |
| key="final_idea" | |
| ) | |
| col_gen1, col_gen2, col_gen3 = st.columns([1, 1, 1]) | |
| with col_gen1: | |
| include_error_handling = st.checkbox("Include error handling", value=True) | |
| with col_gen2: | |
| include_schedule = st.checkbox("Add schedule trigger", value=False) | |
| with col_gen3: | |
| workflow_complexity = st.select_slider("Complexity", ["Simple", "Medium", "Advanced"], value="Medium") | |
| if st.button("β‘ Generate n8n JSON", type="primary", use_container_width=True): | |
| if final_idea: | |
| with st.spinner("Generating your workflow..."): | |
| try: | |
| prompt = f"""You are an expert n8n workflow developer. Create a complete, working n8n workflow JSON based on this description: | |
| {final_idea} | |
| Requirements: | |
| - Complexity level: {workflow_complexity} | |
| - Error handling: {"Yes" if include_error_handling else "No"} | |
| - Schedule trigger: {"Yes" if include_schedule else "No"} | |
| Generate ONLY valid n8n workflow JSON. The JSON must include: | |
| 1. "nodes" array with proper node types | |
| 2. "connections" object linking nodes | |
| 3. Realistic node configurations | |
| 4. Valid n8n node types (HTTP Request, Set, IF, Schedule Trigger, etc.) | |
| Return ONLY the JSON, no explanations. Make it production-ready.""" | |
| response = client.text_generation( | |
| prompt, | |
| model=model_choice, | |
| max_new_tokens=2000, | |
| temperature=0.3, # Lower temperature for more precise JSON | |
| return_full_text=False | |
| ) | |
| # Try to extract JSON from response | |
| json_str = response.strip() | |
| # Remove markdown code blocks if present | |
| if json_str.startswith("```"): | |
| json_str = json_str.split("```")[1] | |
| if json_str.startswith("json"): | |
| json_str = json_str[4:] | |
| json_str = json_str.strip() | |
| # Validate JSON | |
| try: | |
| workflow_json = json.loads(json_str) | |
| # Add metadata if missing | |
| if "name" not in workflow_json: | |
| workflow_json["name"] = "AI Generated Workflow" | |
| if "nodes" not in workflow_json: | |
| workflow_json["nodes"] = [] | |
| if "connections" not in workflow_json: | |
| workflow_json["connections"] = {} | |
| st.session_state['generated_workflow'] = workflow_json | |
| st.success("β Workflow generated successfully!") | |
| except json.JSONDecodeError as je: | |
| st.error("Generated response wasn't valid JSON. Trying to fix...") | |
| # Create a basic fallback workflow | |
| workflow_json = { | |
| "name": "AI Generated Workflow", | |
| "nodes": [ | |
| { | |
| "parameters": {}, | |
| "name": "Start", | |
| "type": "n8n-nodes-base.start", | |
| "typeVersion": 1, | |
| "position": [250, 300] | |
| }, | |
| { | |
| "parameters": { | |
| "url": "https://api.example.com", | |
| "options": {} | |
| }, | |
| "name": "HTTP Request", | |
| "type": "n8n-nodes-base.httpRequest", | |
| "typeVersion": 1, | |
| "position": [450, 300] | |
| } | |
| ], | |
| "connections": { | |
| "Start": { | |
| "main": [[{"node": "HTTP Request", "type": "main", "index": 0}]] | |
| } | |
| } | |
| } | |
| st.session_state['generated_workflow'] = workflow_json | |
| st.info("Created a basic template. Please customize it in n8n.") | |
| except Exception as e: | |
| st.error(f"Generation error: {str(e)}") | |
| else: | |
| st.warning("Please enter a workflow description!") | |
| # Display and download section | |
| if 'generated_workflow' in st.session_state: | |
| st.markdown("---") | |
| st.header("π Your n8n Workflow") | |
| workflow = st.session_state['generated_workflow'] | |
| # Display stats | |
| col_stat1, col_stat2, col_stat3 = st.columns(3) | |
| with col_stat1: | |
| st.metric("Nodes", len(workflow.get('nodes', []))) | |
| with col_stat2: | |
| st.metric("Connections", len(workflow.get('connections', {}))) | |
| with col_stat3: | |
| st.metric("Ready to Import", "β") | |
| # JSON display | |
| st.json(workflow) | |
| # Download button | |
| json_str = json.dumps(workflow, indent=2) | |
| st.download_button( | |
| label="π₯ Download Workflow JSON", | |
| data=json_str, | |
| file_name="n8n_workflow.json", | |
| mime="application/json", | |
| use_container_width=True | |
| ) | |
| st.info("π‘ **How to import:** Open n8n β Workflows β Import from File β Select the downloaded JSON") | |
| # Footer | |
| st.markdown("---") | |
| st.markdown("Made by Muhammad Shaheer") |