Skip to content

Aider Genius Lite - AI Coding Assistant#

Overview#

Aider Genius Lite is a simple Jac-based Streamlit application for AI-powered code generation with task planning and validation. It provides a clean, intuitive interface for generating code from natural language requests with real-time feedback and validation.

Features#

  • Simple, clean interface for code generation requests
  • Pre-built example requests for quick testing
  • Real-time task progress and results display
  • Easy code viewing with syntax highlighting
  • AI feedback and validation results
  • Separate Jac Streamlit frontend and backend

Files#

  • genius_lite.jac - Backend with AI logic, task processing, and API endpoints
  • frontend.jac - Streamlit frontend interface

Complete Code Preview#

Here's what you'll build - a simple AI coding assistant in just two files:

Aider Genius Lite Frontend

import from byllm.lib { Model }
import from pathlib { Path }

glob llm = Model(model_name="gpt-4o-mini");

# Simple task object with semantic annotations
obj Task {
    has name: str;
    has type: str;
    has details: str;
    has priority: int = 1;
}
sem Task = "A specific development task with clear implementation requirements";
sem Task.name = "Clear, descriptive name for the task";
sem Task.type = "Task category: code, fix, docs, or test";
sem Task.details = "Specific implementation instructions";
sem Task.priority = "Task priority: 1=high, 2=medium, 3=low";

obj CodeResult {
    has task_name: str = "";
    has code: str = "";
    has status: str = "";
    has feedback: str = "";
}
sem CodeResult = "Result of code generation task";
sem CodeResult.task_name = "Name of the completed task";
sem CodeResult.code = "Generated code solution";
sem CodeResult.status = "Task completion status: success or failed";
sem CodeResult.feedback = "Validation feedback and suggestions";

# Core AI functions
def create_plan(request: str) -> list[Task] by llm(method="Reason");
def generate_solution(task: Task) -> str by llm(method="Reason");
def validate_code(code: str, task: Task) -> str by llm(method="Reason");

# Nodes for walker traversal
node TaskNode {
    has task: Task = Task(name="", type="", details="", priority=1);
    has code: str = "";
    has feedback: str = "";
    has status: str = "pending";
    has result: CodeResult = CodeResult();

    def process_task() {
        print(f"Working on: {self.task.name}");
        self.code = generate_solution(self.task);
        self.feedback = validate_code(self.code, self.task);
        self.status = "success" if self.feedback else "failed";
        print(f"Completed: {self.task.name}");

        # Create result
        self.result.task_name = self.task.name;
        self.result.code = self.code;
        self.result.status = self.status;
        self.result.feedback = self.feedback;
    }
}

node SummaryNode {
    has results: list[CodeResult] = [];

    def show_summary() {
        output = f"Summary ({len(self.results)} tasks):\n\n";
        for result in self.results {
            status_icon = "SUCCESS" if result.status == "success" else "FAILED";
            output += f"{status_icon} {result.task_name}\n";
            if result.code and len(result.code) > 0 {
                code_preview = result.code[:300];
                if len(result.code) > 300 {
                    code_preview += "...";
                }
                output += f"   Code: {code_preview}\n";
            }
            if result.feedback {
                output += f"   Feedback: {result.feedback[:100]}...\n";
            }
            output += "\n";
        }
        print(output);
    }
}

# GeniusAgent as a walker
walker GeniusAgent {
    has request: str;
    has tasks: list[Task] = [];
    has results: list[CodeResult] = [];
    has current_task_index: int = 0;

    can start with `root entry {
        print("Genius Lite - AI Coding Assistant");
        print("Simple, structured code generation with validation");
        print("=" * 50);
        self.tasks = create_plan(self.request);
        print(f"Created {len(self.tasks)} tasks");

        if len(self.tasks) > 0 {
            # Create task nodes and connect them
            task_nodes = [];
            for task in self.tasks {
                task_node = TaskNode();
                task_node.task = task;
                task_nodes.append(task_node);
            }

            # Connect nodes in sequence
            for i in range(len(task_nodes) - 1) {
                task_nodes[i] ++> task_nodes[i + 1];
            }

            # Connect last task node to summary
            summary_node = SummaryNode();
            summary_node.results = self.results;
            task_nodes[-1] ++> summary_node;

            # Start traversal from first task
            visit task_nodes[0];
        } else {
            print("No tasks created, ending execution");
        }
    }

    can process_task with TaskNode entry {
        # Let the node handle its own processing
        here.process_task();

        # Collect result from node and add to walker's results
        self.results.append(here.result);

        # Continue to next node
        visit [-->];
    }

    can show_summary with SummaryNode entry {
        # Pass results to the summary node
        here.results = self.results;
        # Let the node handle its own summary display
        here.show_summary();
    }
}

# API walker for frontend interaction
walker generate_code {
    has request: str;

    can execute with `root entry {
        print(f"Processing request: {self.request}");
        agent = GeniusAgent(request=self.request) spawn root;

        # Return the results
        report {
            "status": "success",
            "tasks": [
                {
                    "name": result.task_name,
                    "code": result.code,
                    "status": result.status,
                    "feedback": result.feedback
                } for result in agent.results
            ],
            "total_tasks": len(agent.results)
        };
    }
}
import streamlit as st;
import requests;

def bootstrap_frontend(token: str) {
    st.set_page_config(
        page_title="Genius Lite - AI Coding Assistant",
        page_icon="💻",
        layout="wide"
    );

    st.title("🚀 Genius Lite - AI Coding Assistant");
    st.markdown("✨ Simple, structured code generation with validation");

    # Initialize session state
    if "results" not in st.session_state {
        st.session_state.results = None;
    }
    if "loading" not in st.session_state {
        st.session_state.loading = False;
    }

    # Main interface
    st.markdown("### 💡 What would you like me to code for you?");

    # Examples
    with st.expander("💫 Example Requests") {
        if st.button("🧮 Create a Python calculator") {
            st.session_state.user_request = "Create a Python calculator with basic math operations";
        }
        if st.button("🎮 Make a simple game") {
            st.session_state.user_request = "Create a simple number guessing game in Python";
        }
    }

    # Text input
    user_request = st.text_area(
        "📝 Describe your coding request:",
        value=st.session_state.get("user_request", ""),
        height=100,
        placeholder="e.g., Create a Python script that sorts a list of numbers 📊"
    );

    # Generate button
    if st.button("🚀 Generate Code") {
        if user_request.strip() {
            st.session_state.loading = True;
            st.session_state.results = None;
            st.rerun();
        } else {
            st.warning("⚠️ Please enter a coding request!");
        }
    }

    # Show loading state
    if st.session_state.loading {
        with st.spinner("🧠 AI is thinking and generating code...") {
            try {
                response = requests.post(
                    "http://localhost:8000/walker/generate_code",
                    json={"request": user_request},
                    headers={"Authorization": f"Bearer {token}"}
                );

                if response.status_code == 200 {
                    result = response.json();
                    st.session_state.results = result.get("reports", [{}])[0];
                    st.session_state.loading = False;
                    st.success("✅ Code generation completed!");
                    st.rerun();
                } else {
                    st.error(f"❌ Generation failed: {response.text}");
                    st.session_state.loading = False;
                }
            } except requests.exceptions.Timeout {
                st.error("⏰ Request timed out. Please try again with a simpler request.");
                st.session_state.loading = False;
            } except Exception as e {
                st.error(f"❌ Error: {str(e)}");
                st.session_state.loading = False;
            }
        }
    }

    # Display results
    if st.session_state.results {
        results = st.session_state.results;

        st.markdown("---");
        st.markdown("## 🎯 Generated Code Results");

        if "total_tasks" in results {
            st.info(f"📋 Completed {results['total_tasks']} tasks");
        }

        if "tasks" in results and results["tasks"] {
            i = 1;
            for task in results["tasks"] {
                task_name = task.get('name', 'Unnamed Task');
                with st.expander(f"📝 Task {i}: {task_name}") {

                    # Task status
                    status = task.get("status", "unknown");
                    if status == "success" {
                        st.success("✅ Completed successfully");
                    } else {
                        st.error("❌ Failed");
                    }

                    # Generated code
                    if task.get("code") {
                        st.markdown("**🔧 Generated Code:**");
                        st.code(task["code"]);

                        # Copy button
                        if st.button(f"📋 Copy Code {i}") {
                            st.write("📋 Code copied to clipboard! (Use Ctrl+C to copy manually)");
                        }
                    }

                    # Feedback
                    if task.get("feedback") {
                        st.markdown("**💬 AI Feedback:**");
                        st.info(task["feedback"]);
                    }
                }
                i += 1;
            }
        }

        # Clear results button
        if st.button("🗑️ Clear Results") {
            st.session_state.results = None;
            st.session_state.user_request = "";
            st.rerun();
        }
    }

    # Footer
    st.markdown("---");
    st.markdown("**🤖 Powered by Genius Lite AI Assistant**");
    st.markdown("✨ Features: 📋 Task planning • 🔧 Code generation • ✅ Validation");
}


with entry {
    INSTANCE_URL = "http://localhost:8000";
    TEST_USER_EMAIL = "test@mail.com";
    TEST_USER_PASSWORD = "password";

    response = requests.post(
        f"{INSTANCE_URL}/user/login",
        json={"email": TEST_USER_EMAIL, "password": TEST_USER_PASSWORD}
    );

    if response.status_code != 200 {
        # Try registering the user if login fails
        response = requests.post(
            f"{INSTANCE_URL}/user/register",
            json={
                "email": TEST_USER_EMAIL,
                "password": TEST_USER_PASSWORD
            }
        );
        assert response.status_code == 201;

        response = requests.post(
            f"{INSTANCE_URL}/user/login",
            json={"email": TEST_USER_EMAIL, "password": TEST_USER_PASSWORD}
        );
        assert response.status_code == 200;
    }

    token = response.json()["token"];

    bootstrap_frontend(token);
}

Setup#

Installation#

Install dependencies:

pip install jac-streamlit requests jaclang jac-cloud byllm
  1. Open your browser to http://localhost:8501

Usage#

  1. Start the backend server:

    jac serve genius_lite.jac
    
    The backend API will be available at http://localhost:8000
  2. Launch the frontend (in a new terminal):

    jac streamlit frontend.jac
    
    The web interface will be available at http://localhost:8501

Usage Examples#

Basic Code Generation#

Try these example requests:

  • "Create a Python calculator with basic math operations"
  • "Make a simple number guessing game in Python"

Looking for the full version? This is a lite version for learning purposes. Check out the full-scale Aider Genius project for a complete implementation with advanced features.

Code Architecture Deep Dive#

Task Planning System#

The core of Genius Lite's intelligence lies in its task planning system, which: - Analyzes the complexity and scope of user requests - Breaks down large problems into smaller, manageable components - Creates dependency graphs for complex multi-step tasks - Prioritizes execution order for optimal results

Code Generation Pipeline#

  1. Request Analysis: Understanding the user's intent and requirements
  2. Context Gathering: Identifying relevant libraries, frameworks, and patterns
  3. Code Synthesis: Generating code that meets the specified requirements
  4. Quality Assurance: Validating syntax, logic, and best practices

Validation Framework#

The validation system ensures code quality through:

  • Syntax Checking: Validates generated code for syntactic correctness
  • Logic Analysis: Reviews code flow and potential edge cases
  • Best Practice Compliance: Ensures adherence to coding standards
  • Security Assessment: Identifies potential security vulnerabilities

Integration Options#


Aider Genius Lite demonstrates the power of agentic AI for code generation, showcasing how intelligent systems can understand, plan, and execute complex programming tasks autonomously.