Spaces:
Sleeping
Sleeping
| """ | |
| Streamlit Interface for M1 - Hugging Face Spaces Deployment | |
| Replicates the functionality of ui_es.html in a Streamlit interface | |
| Supports English and Spanish languages | |
| """ | |
| import streamlit as st | |
| import asyncio | |
| import json | |
| from decision_agent import DecisionAgent | |
| from tools.n8n_builder import N8NWorkflowBuilder | |
| from tools.comfyui_builder import ComfyUIWorkflowBuilder | |
| from tools.github_search import GitHubSearchTool | |
| from tools.web_search import WebSearchTool | |
| from chat_handler import SessionManager | |
| # ======================================== | |
| # LANGUAGE TRANSLATIONS | |
| # ======================================== | |
| TRANSLATIONS = { | |
| "en": { | |
| "title": "AI Workflow Agent", | |
| "subtitle": "AI Decision Making System - Milestone 1", | |
| "sidebar_config": "βοΈ Configuration", | |
| "sidebar_llm": "π§ Intelligent AI Mode (Gemini)", | |
| "sidebar_llm_help": "Enable to use Gemini AI analysis. Disable for fast keyword mode.", | |
| "sidebar_language": "π Language / Idioma", | |
| "sidebar_stats": "π M1 Statistics", | |
| "sidebar_endpoints": "21 API endpoints", | |
| "sidebar_templates": "16 workflow templates", | |
| "sidebar_modes": "2 modes: Fast and AI", | |
| "sidebar_status": "π Status", | |
| "sidebar_current_mode": "Current Mode:", | |
| "sidebar_latency": "Latency:", | |
| "sidebar_info": "π Information", | |
| "sidebar_description": "Workflow analysis and generation system.", | |
| "sidebar_milestone": "Milestone 1 - Completed β ", | |
| "mode_intelligent": "π§ Intelligent AI", | |
| "mode_fast": "β‘ Fast", | |
| # Tabs | |
| "tab_home": "π Home", | |
| "tab_analyze": "π§ AI Analysis", | |
| "tab_build": "βοΈ Build Workflow", | |
| "tab_github": "π GitHub Search", | |
| "tab_web": "π Web Search", | |
| "tab_chat": "π¬ Chat", | |
| # Home tab | |
| "home_welcome": "Welcome to M1 Dashboard", | |
| "home_features": "β¨ Main Features:", | |
| "home_feature_1": "π§ **AI Analysis**: Analyzes your needs and recommends the best tool", | |
| "home_feature_2": "βοΈ **Workflow Generation**: Creates n8n and ComfyUI workflows", | |
| "home_feature_3": "π **Smart Search**: Search GitHub and web", | |
| "home_feature_4": "π¬ **AI Chat**: Conversational assistant for automation", | |
| "home_getting_started": "π Getting Started:", | |
| "home_step_1": "1. Enable **AI Mode** in the sidebar for intelligent analysis", | |
| "home_step_2": "2. Navigate through tabs to explore features", | |
| "home_step_3": "3. Try example queries in each tab", | |
| "home_modes": "π‘ Modes:", | |
| "home_mode_fast": "**β‘ Fast**: <100ms, predefined templates", | |
| "home_mode_intelligent": "**π§ Intelligent**: 2-3s, deep analysis with Gemini", | |
| "home_tip": "π **Tip**: Start with fast mode to test, then enable AI mode for deep analysis.", | |
| # AI Analysis tab | |
| "analyze_title": "Let AI analyze your automation needs", | |
| "analyze_query": "Your Query", | |
| "analyze_placeholder": "Describe what you want to automate...", | |
| "analyze_examples": "π‘ View Example Queries", | |
| "analyze_example_1": "Example 1: Automated Emails", | |
| "analyze_example_2": "Example 2: AI Art Generation", | |
| "analyze_example_3": "Example 3: CRM Sync", | |
| "analyze_btn": "Analyze with AI β¨", | |
| "analyze_result": "π§ AI Analysis Result", | |
| "analyze_project_type": "Project Type", | |
| "analyze_confidence": "Confidence", | |
| "analyze_method": "Method", | |
| "analyze_explanation": "π Explanation:", | |
| "analyze_tools": "π§ Suggested Tools:", | |
| "analyze_steps": "π Next Steps:", | |
| "error_empty_query": "β Please enter a query", | |
| "analyzing": "Analyzing...", | |
| # Build Workflow tab | |
| "build_title": "Generate complete workflows from descriptions", | |
| "build_description": "Workflow Description", | |
| "build_placeholder": "Describe the workflow you want to create...", | |
| "build_tool": "Tool", | |
| "build_tool_help": "n8n for automation, ComfyUI for AI image generation", | |
| "build_examples": "π‘ View Example Workflows", | |
| "build_example_1": "Example 1: Webhook + Email", | |
| "build_example_2": "Example 2: Twitter Monitor", | |
| "build_example_3": "Example 3: AI Photos", | |
| "build_btn": "Generate Workflow π", | |
| "build_result": "β Workflow Generated!", | |
| "build_type": "Type", | |
| "build_nodes": "Nodes", | |
| "build_method": "Method", | |
| "build_ai_analysis": "π AI Analysis:", | |
| "build_explanation": "Explanation:", | |
| "build_confidence": "Confidence:", | |
| "build_json": "π Workflow JSON:", | |
| "generating": "Generating workflow...", | |
| "generated_ai": "π§ Generated with AI", | |
| "generated_template": "β‘ Generated with templates", | |
| # GitHub Search tab | |
| "github_title": "Find relevant open source projects", | |
| "github_keywords": "Search Keywords", | |
| "github_placeholder": "e.g., workflow automation", | |
| "github_max": "Maximum Results", | |
| "github_examples": "π‘ View Search Examples", | |
| "github_btn": "Search GitHub π", | |
| "github_results": "π GitHub Results ({} found)", | |
| "github_description": "Description:", | |
| "github_language": "Language:", | |
| "github_docker": "π³ **Docker:** Yes", | |
| "github_url": "URL:", | |
| "github_no_results": "π No repositories found", | |
| "searching_github": "Searching GitHub...", | |
| # Web Search tab | |
| "web_title": "Search the web using DuckDuckGo", | |
| "web_query": "Search Query", | |
| "web_placeholder": "e.g., n8n automation examples", | |
| "web_max": "Maximum Results", | |
| "web_btn": "Search Web π", | |
| "web_results": "π Search Results ({} found)", | |
| "web_no_title": "No title", | |
| "web_no_description": "No description", | |
| "web_no_results": "π No results found", | |
| "searching_web": "Searching the web...", | |
| # Chat tab | |
| "chat_title": "Chat with AI about your automation needs", | |
| "chat_placeholder": "Ask the AI assistant anything...", | |
| "chat_examples": "π‘ View Conversation Starters", | |
| "chat_example_1": "I want to create a bot that answers questions", | |
| "chat_example_2": "Help me automate my social media posts", | |
| "chat_example_3": "I need to process CSV files", | |
| "chat_thinking": "Thinking...", | |
| "chat_tools": "Suggested tools:", | |
| # Footer | |
| "footer_notes": "π Notes:", | |
| "footer_fast": "**Fast mode (keywords)**: <100ms, uses predefined templates", | |
| "footer_intelligent": "**Intelligent mode (Gemini)**: 2-3s, deep AI analysis", | |
| "footer_requirements": "**Requirements**: Gemini API key for intelligent mode (free at [Google AI Studio](https://aistudio.google.com/app/apikeys))", | |
| "footer_milestone": "π **Milestone 1** - Basic AI decision-making system completed", | |
| # Example texts | |
| "ex_email": "I need to send automated emails to 1000 clients every morning", | |
| "ex_ai_art": "I want to generate AI art from text descriptions and post to Instagram", | |
| "ex_crm": "Process customer data from Shopify and sync with CRM", | |
| "ex_chatbot": "Create a chatbot that answers questions from my documentation", | |
| "ex_webhook": "Create a flow that receives customer data from webhook and sends confirmation email", | |
| "ex_twitter": "Build a flow that monitors Twitter for mentions and sends Slack notifications", | |
| "ex_photos": "Generate professional photos from uploaded photos", | |
| "ex_automation": "workflow automation", | |
| "ex_ml": "machine learning deployment", | |
| "ex_image_gen": "AI image generation", | |
| "ex_bot": "I want to create a bot that answers customer questions from my website", | |
| "ex_social": "Help me automate my social media posts", | |
| "ex_csv": "I need to process CSV files and generate reports" | |
| }, | |
| "es": { | |
| "title": "Agente de Flujo de Trabajo IA", | |
| "subtitle": "Sistema de Toma de Decisiones IA - Milestone 1", | |
| "sidebar_config": "βοΈ ConfiguraciΓ³n", | |
| "sidebar_llm": "π§ Modo IA Inteligente (Gemini)", | |
| "sidebar_llm_help": "Activar para usar anΓ‘lisis con Gemini AI. Desactivar para modo rΓ‘pido con palabras clave.", | |
| "sidebar_language": "π Language / Idioma", | |
| "sidebar_stats": "π EstadΓsticas M1", | |
| "sidebar_endpoints": "21 endpoints API activos", | |
| "sidebar_templates": "16 plantillas de flujos", | |
| "sidebar_modes": "2 modos: RΓ‘pido y IA", | |
| "sidebar_status": "π Estado", | |
| "sidebar_current_mode": "Modo Actual:", | |
| "sidebar_latency": "Latencia:", | |
| "sidebar_info": "π InformaciΓ³n", | |
| "sidebar_description": "Sistema de anΓ‘lisis y generaciΓ³n de flujos de trabajo.", | |
| "sidebar_milestone": "Milestone 1 - Completado β ", | |
| "mode_intelligent": "π§ IA Inteligente", | |
| "mode_fast": "β‘ RΓ‘pido", | |
| # Tabs | |
| "tab_home": "π Inicio", | |
| "tab_analyze": "π§ AnΓ‘lisis IA", | |
| "tab_build": "βοΈ Construir Flujo", | |
| "tab_github": "π BΓΊsqueda GitHub", | |
| "tab_web": "π BΓΊsqueda Web", | |
| "tab_chat": "π¬ Chat", | |
| # Home tab | |
| "home_welcome": "Bienvenido al Panel M1", | |
| "home_features": "β¨ CaracterΓsticas Principales:", | |
| "home_feature_1": "π§ **AnΓ‘lisis IA**: Analiza tus necesidades y recomienda la mejor herramienta", | |
| "home_feature_2": "βοΈ **GeneraciΓ³n de Flujos**: Crea flujos de trabajo de n8n y ComfyUI", | |
| "home_feature_3": "π **BΓΊsqueda Inteligente**: Busca en GitHub y la web", | |
| "home_feature_4": "π¬ **Chat IA**: Asistente conversacional para automatizaciΓ³n", | |
| "home_getting_started": "π Comenzar:", | |
| "home_step_1": "1. Activa el **Modo IA** en la barra lateral para anΓ‘lisis inteligente", | |
| "home_step_2": "2. Navega por las pestaΓ±as para explorar caracterΓsticas", | |
| "home_step_3": "3. Prueba las consultas de ejemplo en cada pestaΓ±a", | |
| "home_modes": "π‘ Modos:", | |
| "home_mode_fast": "**β‘ RΓ‘pido**: <100ms, plantillas predefinidas", | |
| "home_mode_intelligent": "**π§ Inteligente**: 2-3s, anΓ‘lisis profundo con Gemini", | |
| "home_tip": "π **Tip**: Comienza con el modo rΓ‘pido para probar, luego activa el modo IA para anΓ‘lisis profundo.", | |
| # AI Analysis tab | |
| "analyze_title": "Permite que la IA analice tus necesidades de automatizaciΓ³n", | |
| "analyze_query": "Tu Consulta", | |
| "analyze_placeholder": "Describe lo que deseas automatizar...", | |
| "analyze_examples": "π‘ Ver Consultas de Ejemplo", | |
| "analyze_example_1": "Ejemplo 1: Correos Automatizados", | |
| "analyze_example_2": "Ejemplo 2: GeneraciΓ³n de Arte IA", | |
| "analyze_example_3": "Ejemplo 3: SincronizaciΓ³n CRM", | |
| "analyze_btn": "Analizar con IA β¨", | |
| "analyze_result": "π§ Resultado del AnΓ‘lisis IA", | |
| "analyze_project_type": "Tipo de Proyecto", | |
| "analyze_confidence": "Confianza", | |
| "analyze_method": "MΓ©todo", | |
| "analyze_explanation": "π ExplicaciΓ³n:", | |
| "analyze_tools": "π§ Herramientas Sugeridas:", | |
| "analyze_steps": "π PrΓ³ximos Pasos:", | |
| "error_empty_query": "β Por favor ingrese una consulta", | |
| "analyzing": "Analizando...", | |
| # Build Workflow tab | |
| "build_title": "Genera flujos de trabajo completos a partir de descripciones", | |
| "build_description": "DescripciΓ³n del Flujo de Trabajo", | |
| "build_placeholder": "Describe el flujo de trabajo que deseas crear...", | |
| "build_tool": "Herramienta", | |
| "build_tool_help": "n8n para automatizaciΓ³n, ComfyUI para generaciΓ³n de imΓ‘genes IA", | |
| "build_examples": "π‘ Ver Flujos de Ejemplo", | |
| "build_example_1": "Ejemplo 1: Webhook + Email", | |
| "build_example_2": "Ejemplo 2: Monitor Twitter", | |
| "build_example_3": "Ejemplo 3: Fotos IA", | |
| "build_btn": "Generar Flujo de Trabajo π", | |
| "build_result": "β Β‘Flujo de Trabajo Generado!", | |
| "build_type": "Tipo", | |
| "build_nodes": "Nodos", | |
| "build_method": "MΓ©todo", | |
| "build_ai_analysis": "π AnΓ‘lisis IA:", | |
| "build_explanation": "ExplicaciΓ³n:", | |
| "build_confidence": "Confianza:", | |
| "build_json": "π JSON del Flujo de Trabajo:", | |
| "generating": "Generando flujo de trabajo...", | |
| "generated_ai": "π§ Generado con IA", | |
| "generated_template": "β‘ Generado con plantillas", | |
| # GitHub Search tab | |
| "github_title": "Encuentra proyectos de cΓ³digo abierto relevantes", | |
| "github_keywords": "Palabras Clave de BΓΊsqueda", | |
| "github_placeholder": "ej., automatizaciΓ³n de flujos de trabajo", | |
| "github_max": "Resultados MΓ‘ximos", | |
| "github_examples": "π‘ Ver Ejemplos de BΓΊsqueda", | |
| "github_btn": "Buscar en GitHub π", | |
| "github_results": "π Resultados de GitHub ({} encontrados)", | |
| "github_description": "DescripciΓ³n:", | |
| "github_language": "Lenguaje:", | |
| "github_docker": "π³ **Docker:** SΓ", | |
| "github_url": "URL:", | |
| "github_no_results": "π No se encontraron repositorios", | |
| "searching_github": "Buscando en GitHub...", | |
| # Web Search tab | |
| "web_title": "Busca en la web usando DuckDuckGo", | |
| "web_query": "Consulta de BΓΊsqueda", | |
| "web_placeholder": "ej., ejemplos de automatizaciΓ³n n8n", | |
| "web_max": "Resultados MΓ‘ximos", | |
| "web_btn": "Buscar en Web π", | |
| "web_results": "π Resultados de BΓΊsqueda ({} encontrados)", | |
| "web_no_title": "Sin tΓtulo", | |
| "web_no_description": "Sin descripciΓ³n", | |
| "web_no_results": "π No se encontraron resultados", | |
| "searching_web": "Buscando en la web...", | |
| # Chat tab | |
| "chat_title": "Conversa con la IA sobre tus necesidades de automatizaciΓ³n", | |
| "chat_placeholder": "Pregunta al asistente IA cualquier cosa...", | |
| "chat_examples": "π‘ Ver Iniciadores de ConversaciΓ³n", | |
| "chat_example_1": "Quiero crear un bot que responda preguntas", | |
| "chat_example_2": "AyΓΊdame a automatizar mis publicaciones", | |
| "chat_example_3": "Necesito procesar archivos CSV", | |
| "chat_thinking": "Pensando...", | |
| "chat_tools": "Herramientas sugeridas:", | |
| # Footer | |
| "footer_notes": "π Notas:", | |
| "footer_fast": "**Modo RΓ‘pido (palabras clave)**: <100ms, usa plantillas predefinidas", | |
| "footer_intelligent": "**Modo Inteligente (Gemini)**: 2-3s, anΓ‘lisis profundo con IA", | |
| "footer_requirements": "**Requisitos**: Clave API de Gemini para modo inteligente (gratis en [Google AI Studio](https://aistudio.google.com/app/apikeys))", | |
| "footer_milestone": "π **Milestone 1** - Sistema de toma de decisiones IA bΓ‘sico completado", | |
| # Example texts | |
| "ex_email": "Necesito enviar correos electrΓ³nicos automatizados a 1000 clientes cada maΓ±ana", | |
| "ex_ai_art": "Quiero generar arte IA a partir de descripciones de texto y publicar en Instagram", | |
| "ex_crm": "Procesar datos de clientes de Shopify y sincronizar con CRM", | |
| "ex_chatbot": "Crear un chatbot que responda preguntas de mi documentaciΓ³n", | |
| "ex_webhook": "Crear un flujo que reciba datos de clientes desde webhook y envΓe correo de confirmaciΓ³n", | |
| "ex_twitter": "Construir un flujo que monitoree Twitter para menciones y envΓe notificaciones de Slack", | |
| "ex_photos": "Generar fotos profesionales a partir de fotos subidas", | |
| "ex_automation": "automatizaciΓ³n de flujos de trabajo", | |
| "ex_ml": "implementaciΓ³n de aprendizaje automΓ‘tico", | |
| "ex_image_gen": "generaciΓ³n de imΓ‘genes IA", | |
| "ex_bot": "Quiero crear un bot que responda preguntas de clientes desde mi sitio web", | |
| "ex_social": "AyΓΊdame a automatizar mis publicaciones en redes sociales", | |
| "ex_csv": "Necesito procesar archivos CSV y generar reportes" | |
| } | |
| } | |
| def t(key: str, lang: str = "es") -> str: | |
| """Get translation for key in specified language""" | |
| return TRANSLATIONS.get(lang, {}).get(key, TRANSLATIONS["en"].get(key, key)) | |
| # Page config | |
| st.set_page_config( | |
| page_title="M1 - Agente de Flujo de Trabajo IA", | |
| page_icon="π€", | |
| layout="wide", | |
| initial_sidebar_state="expanded" | |
| ) | |
| # Custom CSS | |
| st.markdown(""" | |
| <style> | |
| .main-header { | |
| font-size: 2.5rem; | |
| font-weight: bold; | |
| color: #1f77b4; | |
| margin-bottom: 0.5rem; | |
| } | |
| .sub-header { | |
| font-size: 1.2rem; | |
| color: #666; | |
| margin-bottom: 2rem; | |
| } | |
| .feature-box { | |
| padding: 1rem; | |
| border-radius: 0.5rem; | |
| background-color: #f0f2f6; | |
| margin-bottom: 1rem; | |
| } | |
| .success-message { | |
| padding: 1rem; | |
| border-radius: 0.5rem; | |
| background-color: #d4edda; | |
| border: 1px solid #c3e6cb; | |
| color: #155724; | |
| } | |
| .error-message { | |
| padding: 1rem; | |
| border-radius: 0.5rem; | |
| background-color: #f8d7da; | |
| border: 1px solid #f5c6cb; | |
| color: #721c24; | |
| } | |
| </style> | |
| """, unsafe_allow_html=True) | |
| # Initialize components | |
| def init_components(): | |
| """Initialize all M1 components (cached)""" | |
| return { | |
| 'decision_agent': DecisionAgent(), | |
| 'n8n_builder': N8NWorkflowBuilder(), | |
| 'comfyui_builder': ComfyUIWorkflowBuilder(), | |
| 'github_tool': GitHubSearchTool(), | |
| 'web_tool': WebSearchTool(), | |
| 'session_manager': SessionManager() | |
| } | |
| components = init_components() | |
| # Helper to run async functions | |
| def run_async(coro): | |
| """Run async function in sync context""" | |
| try: | |
| loop = asyncio.get_event_loop() | |
| except RuntimeError: | |
| loop = asyncio.new_event_loop() | |
| asyncio.set_event_loop(loop) | |
| return loop.run_until_complete(coro) | |
| # ======================================== | |
| # SIDEBAR - Global Settings | |
| # ======================================== | |
| with st.sidebar: | |
| # Language selector | |
| lang = st.selectbox( | |
| "π Language / Idioma", | |
| options=["es", "en"], | |
| format_func=lambda x: "πͺπΈ EspaΓ±ol" if x == "es" else "π¬π§ English", | |
| index=0 | |
| ) | |
| st.markdown("---") | |
| st.markdown(f"## {t('sidebar_config', lang)}") | |
| # Initialize use_llm in session state if not present | |
| if 'use_llm' not in st.session_state: | |
| st.session_state.use_llm = True | |
| use_llm = st.checkbox( | |
| t('sidebar_llm', lang), | |
| value=st.session_state.use_llm, | |
| key='use_llm_checkbox' | |
| ) | |
| st.markdown(f""" | |
| ### {t('sidebar_stats', lang)} | |
| - **{t('sidebar_endpoints', lang)}** | |
| - **{t('sidebar_templates', lang)}** | |
| - **{t('sidebar_modes', lang)}** | |
| ### {t('sidebar_status', lang)} | |
| - **{t('sidebar_current_mode', lang)}** {t('mode_intelligent', lang) if use_llm else t('mode_fast', lang)} | |
| - **{t('sidebar_latency', lang)}** {"2-3s" if use_llm else "<100ms"} | |
| """) | |
| st.markdown("---") | |
| st.markdown(f""" | |
| ### {t('sidebar_info', lang)} | |
| {t('sidebar_description', lang)} | |
| **{t('sidebar_milestone', lang)}** | |
| """) | |
| # ======================================== | |
| # MAIN CONTENT | |
| # ======================================== | |
| # Header | |
| st.markdown(f'<div class="main-header">π€ {t("title", lang)}</div>', unsafe_allow_html=True) | |
| st.markdown(f'<div class="sub-header">{t("subtitle", lang)}</div>', unsafe_allow_html=True) | |
| # Tabs | |
| tab_home, tab_analyze, tab_build, tab_github, tab_web, tab_chat = st.tabs([ | |
| t("tab_home", lang), | |
| t("tab_analyze", lang), | |
| t("tab_build", lang), | |
| t("tab_github", lang), | |
| t("tab_web", lang), | |
| t("tab_chat", lang) | |
| ]) | |
| # ======================================== | |
| # TAB 1: HOME | |
| # ======================================== | |
| with tab_home: | |
| st.markdown(f"## {t('home_welcome', lang)}") | |
| col1, col2 = st.columns(2) | |
| with col1: | |
| st.markdown(f""" | |
| ### {t('home_features', lang)} | |
| - {t('home_feature_1', lang)} | |
| - {t('home_feature_2', lang)} | |
| - {t('home_feature_3', lang)} | |
| - {t('home_feature_4', lang)} | |
| """) | |
| with col2: | |
| st.markdown(f""" | |
| ### {t('home_getting_started', lang)} | |
| {t('home_step_1', lang)} | |
| {t('home_step_2', lang)} | |
| {t('home_step_3', lang)} | |
| ### {t('home_modes', lang)} | |
| - {t('home_mode_fast', lang)} | |
| - {t('home_mode_intelligent', lang)} | |
| """) | |
| st.info(f"{t('home_tip', lang)}") | |
| # ======================================== | |
| # TAB 2: AI ANALYSIS | |
| # ======================================== | |
| with tab_analyze: | |
| st.markdown(f"### {t('analyze_title', lang)}") | |
| col1, col2 = st.columns([1, 1]) | |
| with col1: | |
| # Handle example button clicks | |
| if 'analysis_example' not in st.session_state: | |
| st.session_state.analysis_example = "" | |
| with st.expander(t('analyze_examples', lang)): | |
| if st.button(t('analyze_example_1', lang), key="ex1"): | |
| st.session_state.analysis_example = t('ex_email', lang) | |
| if st.button(t('analyze_example_2', lang), key="ex2"): | |
| st.session_state.analysis_example = t('ex_ai_art', lang) | |
| if st.button(t('analyze_example_3', lang), key="ex3"): | |
| st.session_state.analysis_example = t('ex_crm', lang) | |
| analysis_query = st.text_area( | |
| t('analyze_query', lang), | |
| value=st.session_state.analysis_example, | |
| placeholder=t('analyze_placeholder', lang), | |
| height=150, | |
| key="analysis_query" | |
| ) | |
| analyze_btn = st.button(t('analyze_btn', lang), type="primary", use_container_width=True, key="analyze_btn") | |
| with col2: | |
| if analyze_btn: | |
| if not analysis_query: | |
| st.error(t('error_empty_query', lang)) | |
| else: | |
| with st.spinner(t('analyzing', lang)): | |
| try: | |
| result = run_async(components['decision_agent'].analyze( | |
| analysis_query, | |
| context={'use_llm': use_llm} | |
| )) | |
| st.markdown(f"## {t('analyze_result', lang)}") | |
| col_a, col_b, col_c = st.columns(3) | |
| with col_a: | |
| st.metric(t('analyze_project_type', lang), result['project_type'].upper()) | |
| with col_b: | |
| st.metric(t('analyze_confidence', lang), f"{result['confidence']*100:.0f}%") | |
| with col_c: | |
| st.metric(t('analyze_method', lang), result.get('classification_method', 'N/A')) | |
| st.markdown(f"### {t('analyze_explanation', lang)}") | |
| st.write(result['explanation']) | |
| st.markdown(f"### {t('analyze_tools', lang)}") | |
| for tool in result.get('suggested_tools', []): | |
| st.write(f"- {tool}") | |
| st.markdown(f"### {t('analyze_steps', lang)}") | |
| for i, step in enumerate(result.get('next_steps', []), 1): | |
| st.write(f"{i}. {step}") | |
| except Exception as e: | |
| st.error(f"β Error: {str(e)}") | |
| # ======================================== | |
| # TAB 3: BUILD WORKFLOW | |
| # ======================================== | |
| with tab_build: | |
| st.markdown(f"### {t('build_title', lang)}") | |
| col1, col2 = st.columns([1, 1]) | |
| with col1: | |
| # Handle example button clicks | |
| if 'build_example' not in st.session_state: | |
| st.session_state.build_example = "" | |
| with st.expander(t('build_examples', lang)): | |
| if st.button(t('build_example_1', lang), key="build_ex1"): | |
| st.session_state.build_example = t('ex_webhook', lang) | |
| if st.button(t('build_example_2', lang), key="build_ex2"): | |
| st.session_state.build_example = t('ex_twitter', lang) | |
| if st.button(t('build_example_3', lang), key="build_ex3"): | |
| st.session_state.build_example = t('ex_photos', lang) | |
| build_description = st.text_area( | |
| t('build_description', lang), | |
| value=st.session_state.build_example, | |
| placeholder=t('build_placeholder', lang), | |
| height=150, | |
| key="build_description" | |
| ) | |
| build_tool = st.radio( | |
| t('build_tool', lang), | |
| options=["n8n", "comfyui"], | |
| help=t('build_tool_help', lang), | |
| horizontal=True | |
| ) | |
| build_btn = st.button(t('build_btn', lang), type="primary", use_container_width=True, key="build_btn") | |
| with col2: | |
| if build_btn: | |
| if not build_description: | |
| st.error(t('error_empty_query', lang)) | |
| else: | |
| with st.spinner(t('generating', lang)): | |
| try: | |
| if build_tool == "n8n": | |
| workflow = run_async(components['n8n_builder'].generate_workflow( | |
| build_description, | |
| context={'use_llm': use_llm} | |
| )) | |
| else: | |
| workflow = run_async(components['comfyui_builder'].generate_workflow( | |
| build_description, | |
| context={'use_llm': use_llm} | |
| )) | |
| enhanced = workflow.get('meta', {}).get('generated_with_llm', False) | |
| status = t('generated_ai', lang) if enhanced else t('generated_template', lang) | |
| st.markdown(f"## {t('build_result', lang)}") | |
| col_a, col_b, col_c = st.columns(3) | |
| with col_a: | |
| st.metric(t('build_type', lang), build_tool.upper()) | |
| with col_b: | |
| st.metric(t('build_nodes', lang), len(workflow.get('nodes', []))) | |
| with col_c: | |
| st.metric(t('build_method', lang), status) | |
| # Show workflow summary | |
| st.markdown("### π Workflow Summary") | |
| st.markdown(f"**Name:** {workflow.get('name', 'N/A')}") | |
| # Show nodes in readable format | |
| nodes = workflow.get('nodes', []) | |
| if nodes: | |
| st.markdown("**Nodes:**") | |
| for i, node in enumerate(nodes, 1): | |
| node_name = node.get('name', 'Unknown') | |
| node_type = node.get('type', 'unknown').split('.')[-1] | |
| st.write(f"{i}. **{node_name}** (`{node_type}`)") | |
| # Show connections | |
| connections = workflow.get('connections', {}) | |
| if connections: | |
| st.markdown("**Flow:**") | |
| flow_text = " β ".join([node.get('name', f"Node {i+1}") for i, node in enumerate(nodes)]) | |
| st.info(flow_text) | |
| # Show AI analysis if available | |
| if enhanced and 'llm_analysis' in workflow.get('meta', {}): | |
| analysis = workflow['meta']['llm_analysis'] | |
| with st.expander("π§ AI Analysis Details", expanded=False): | |
| st.write(f"**{t('build_explanation', lang)}** {analysis.get('explanation', 'N/A')}") | |
| st.write(f"**{t('build_confidence', lang)}** {analysis.get('confidence', 0)*100:.0f}%") | |
| # Show JSON in collapsible section | |
| with st.expander(f"π {t('build_json', lang)}", expanded=False): | |
| st.code(json.dumps(workflow, indent=2, ensure_ascii=False), language="json") | |
| # Download button | |
| json_str = json.dumps(workflow, indent=2, ensure_ascii=False) | |
| st.download_button( | |
| label="β¬οΈ Download Workflow JSON", | |
| data=json_str, | |
| file_name=f"{workflow.get('name', 'workflow')}.json", | |
| mime="application/json" | |
| ) | |
| except Exception as e: | |
| st.error(f"β Error: {str(e)}") | |
| # ======================================== | |
| # TAB 4: GITHUB SEARCH | |
| # ======================================== | |
| with tab_github: | |
| st.markdown(f"### {t('github_title', lang)}") | |
| col1, col2 = st.columns([1, 2]) | |
| with col1: | |
| github_keywords = st.text_input( | |
| t('github_keywords', lang), | |
| placeholder=t('github_placeholder', lang) | |
| ) | |
| github_max = st.slider( | |
| t('github_max', lang), | |
| min_value=1, | |
| max_value=10, | |
| value=5 | |
| ) | |
| with st.expander(t('github_examples', lang)): | |
| if st.button(t('ex_automation', lang), key="gh_ex1"): | |
| st.session_state.github_keywords_input = t('ex_automation', lang) | |
| st.rerun() | |
| if st.button(t('ex_ml', lang), key="gh_ex2"): | |
| st.session_state.github_keywords_input = t('ex_ml', lang) | |
| st.rerun() | |
| if st.button(t('ex_image_gen', lang), key="gh_ex3"): | |
| st.session_state.github_keywords_input = t('ex_image_gen', lang) | |
| st.rerun() | |
| github_btn = st.button(t('github_btn', lang), type="primary", use_container_width=True) | |
| with col2: | |
| if github_btn: | |
| if not github_keywords: | |
| st.error(t('error_empty_query', lang)) | |
| else: | |
| with st.spinner(t('searching_github', lang)): | |
| try: | |
| results = run_async(components['github_tool'].search( | |
| github_keywords, | |
| max_results=int(github_max) | |
| )) | |
| if not results: | |
| st.info(t('github_no_results', lang)) | |
| else: | |
| st.markdown(f"## {t('github_results', lang).format(len(results))}") | |
| for i, repo in enumerate(results, 1): | |
| with st.expander(f"**{i}. {repo.get('full_name', 'N/A')}** β {repo.get('stars', 0):,}"): | |
| st.write(f"**{t('github_description', lang)}** {repo.get('description', t('web_no_description', lang))}") | |
| st.write(f"**{t('github_language', lang)}** {repo.get('language', 'N/A')}") | |
| if repo.get('has_docker'): | |
| st.write(t('github_docker', lang)) | |
| st.markdown(f"**{t('github_url', lang)}** [{repo.get('url', 'N/A')}]({repo.get('url', '#')})") | |
| except Exception as e: | |
| st.error(f"β Error: {str(e)}") | |
| # ======================================== | |
| # TAB 5: WEB SEARCH | |
| # ======================================== | |
| with tab_web: | |
| st.markdown(f"### {t('web_title', lang)}") | |
| col1, col2 = st.columns([1, 2]) | |
| with col1: | |
| web_query = st.text_input( | |
| t('web_query', lang), | |
| placeholder=t('web_placeholder', lang) | |
| ) | |
| web_max = st.slider( | |
| t('web_max', lang), | |
| min_value=1, | |
| max_value=10, | |
| value=5, | |
| key="web_max_slider" | |
| ) | |
| web_btn = st.button(t('web_btn', lang), type="primary", use_container_width=True, key="web_btn") | |
| with col2: | |
| if web_btn: | |
| if not web_query: | |
| st.error(t('error_empty_query', lang)) | |
| else: | |
| with st.spinner(t('searching_web', lang)): | |
| try: | |
| results = run_async(components['web_tool'].search( | |
| web_query, | |
| max_results=int(web_max) | |
| )) | |
| if not results: | |
| st.info(t('web_no_results', lang)) | |
| else: | |
| st.markdown(f"## {t('web_results', lang).format(len(results))}") | |
| for i, result in enumerate(results, 1): | |
| with st.expander(f"**{i}. {result.get('title', t('web_no_title', lang))}**"): | |
| st.write(result.get('snippet', t('web_no_description', lang))) | |
| st.markdown(f"π [{result.get('url', 'N/A')}]({result.get('url', '#')})") | |
| except Exception as e: | |
| st.error(f"β Error: {str(e)}") | |
| # ======================================== | |
| # TAB 6: CHAT | |
| # ======================================== | |
| with tab_chat: | |
| st.markdown(f"### {t('chat_title', lang)}") | |
| # Initialize chat history | |
| if 'chat_history' not in st.session_state: | |
| st.session_state.chat_history = [] | |
| if 'chat_session' not in st.session_state: | |
| st.session_state.chat_session = components['session_manager'].create_session() | |
| # Display chat history | |
| for message in st.session_state.chat_history: | |
| with st.chat_message(message["role"]): | |
| st.write(message["content"]) | |
| # Chat input | |
| chat_input = st.chat_input(t('chat_placeholder', lang)) | |
| if chat_input: | |
| # Add user message | |
| st.session_state.chat_history.append({"role": "user", "content": chat_input}) | |
| st.session_state.chat_session.add_message("user", chat_input) | |
| with st.chat_message("user"): | |
| st.write(chat_input) | |
| # Get AI response | |
| with st.chat_message("assistant"): | |
| with st.spinner(t('chat_thinking', lang)): | |
| try: | |
| result = run_async(components['decision_agent'].analyze( | |
| chat_input, | |
| context={'use_llm': use_llm} | |
| )) | |
| response = f"{result['explanation']}\n\n**{t('chat_tools', lang)}** {', '.join(result.get('suggested_tools', []))}" | |
| st.write(response) | |
| # Add to history | |
| st.session_state.chat_history.append({"role": "assistant", "content": response}) | |
| st.session_state.chat_session.add_message("assistant", response) | |
| except Exception as e: | |
| error_msg = f"β Error: {str(e)}" | |
| st.error(error_msg) | |
| st.session_state.chat_history.append({"role": "assistant", "content": error_msg}) | |
| # Example starters | |
| with st.expander(t('chat_examples', lang)): | |
| if st.button(t('chat_example_1', lang), key="chat_ex1"): | |
| st.session_state.pending_chat = t('ex_bot', lang) | |
| st.rerun() | |
| if st.button(t('chat_example_2', lang), key="chat_ex2"): | |
| st.session_state.pending_chat = t('ex_social', lang) | |
| st.rerun() | |
| if st.button(t('chat_example_3', lang), key="chat_ex3"): | |
| st.session_state.pending_chat = t('ex_csv', lang) | |
| st.rerun() | |
| # ======================================== | |
| # FOOTER | |
| # ======================================== | |
| st.markdown("---") | |
| st.markdown(f""" | |
| ### {t('footer_notes', lang)} | |
| - {t('footer_fast', lang)} | |
| - {t('footer_intelligent', lang)} | |
| - {t('footer_requirements', lang)} | |
| {t('footer_milestone', lang)} | |
| """) | |