AI

Build an AI-driven application using code workflows in Plan → File → tinydev

In this tutorial, we introduce the TinyDev class implementation, a minimal and powerful AI code generation tool that uses the Gemini API to transform simple application ideas into comprehensive structured applications. Tinydev is designed to run effortlessly on a notebook, following a clean three-phase workflow (plan → file → code) to ensure consistency, functionality and modular design. Whether building a web interface, Python backend or utility scripts, TinyDev allows users to describe their projects in natural language and receive ready-made code files, which are automatically generated and saved in organized directories. This makes it an ideal starting point for rapid prototyping or understanding how AI can assist development tasks.

import google.generativeai as genai
import os
import json
import re
from pathlib import Path
from typing import List, Dict

We first import the required libraries required for the TinyDev code generator. Google.generativeai is used to interact with the Gemini API, while OS, JSON, and RE support standard libraries such as file processing and text processing. Tips for typing paths and inputs ensure clean file operations and better code readability.

class TinyDev:
   """
   TinyDev: A lightweight AI code generator inspired by smol-dev
   Uses Gemini API to generate complete applications from simple prompts
   Follows the proven three-phase workflow: Plan → Files → Code
   """
  
   def __init__(self, api_key: str, model: str = "gemini-1.5-flash"):
       genai.configure(api_key=api_key)
       self.model = genai.GenerativeModel(model)
       self.generation_config = {
           'temperature': 0.1,
           'top_p': 0.8,
           'max_output_tokens': 8192,
       }
  
   def plan(self, prompt: str) -> str:
       """
       Phase 1: Generate project plan and shared dependencies
       Creates the foundation for consistent code generation
       """
       planning_prompt = f"""As an AI developer, you’re building a tool that automatically generates code tailored to the user’s needs.


the program you are writing is based on the following description:
{prompt}


the files we write will be generated by a python script. the goal is for us to all work together to write a program that will write the code for the user.


since we are working together, we need to understand what our shared dependencies are. this includes:
- import statements we all need to use
- variable names that are shared between files
- functions that are called from one file to another
- any other shared state


this is the most critical part of the process, if we don't get this right, the generated code will not work properly.


please output a markdown file called shared_dependencies.md that lists all of the shared dependencies.


the dependencies should be organized as:
1. shared variables (globals, constants)
2. shared functions (function signatures)
3. shared classes (class names and key methods)
4. shared imports (modules to import)
5. shared DOM element ids (if web project)
6. shared file paths/names


be EXHAUSTIVE in your analysis. every file must be able to import or reference these shared items."""


       response = self.model.generate_content(
           planning_prompt,
           generation_config=self.generation_config
       )
       return response.text


   def specify_file_paths(self, prompt: str, shared_deps: str) -> List[str]:
       """
       Phase 2: Determine what files need to be created
       """
       files_prompt = f"""As an AI developer, you’re building a tool that automatically generates code tailored to the user’s needs.


the program:
{prompt}


the shared dependencies:
{shared_deps}


Based on the program description and shared dependencies, return a JSON array of the filenames that should be written.


Only return the JSON array, nothing else. The JSON should be an array of strings representing file paths.


For example, for a simple web app you might return:
["index.html", "styles.css", "script.js"]


For a Python project you might return:
["main.py", "utils.py", "config.py", "requirements.txt"]


JSON array:"""


       response = self.model.generate_content(
           files_prompt,
           generation_config=self.generation_config
       )
      
       try:
           json_match = re.search(r'[.*?]', response.text, re.DOTALL)
           if json_match:
               files = json.loads(json_match.group())
               return [f for f in files if isinstance(f, str)]
           else:
               lines = [line.strip() for line in response.text.split('n') if line.strip()]
               files = []
               for line in lines:
                   if '.' in line and not line.startswith('#'):
                       file = re.sub(r'[^w-_./]', '', line)
                       if file:
                           files.append(file)
               return files[:10] 
       except Exception as e:
           print(f"Error parsing files: {e}")
           return ["main.py", "README.md"]


   def generate_code_sync(self, prompt: str, shared_deps: str, filename: str) -> str:
       """
       Phase 3: Generate code for individual files
       """
       code_prompt = f"""As an AI developer, you’re building a tool that automatically generates code tailored to the user’s needs..


the program:
{prompt}


the shared dependencies:
{shared_deps}


Please write the file {filename}.


Remember that your job is to write the code for {filename} ONLY. Do not write any other files.


the code should be fully functional. meaning:
- all imports should be correct
- all variable references should be correct 
- all function calls should be correct
- the code should be syntactically correct
- the code should be logically correct


Make sure to implement every part of the functionality described in the program description.


DO NOT include ``` code fences in your response. Return only the raw code.


Here is the code for {filename}:"""


       response = self.model.generate_content(
           code_prompt,
           generation_config=self.generation_config
       )
      
       code = response.text
       code = re.sub(r'^```[w]*n', '', code, flags=re.MULTILINE)
       code = re.sub(r'n```$', '', code, flags=re.MULTILINE)
      
       return code.strip()


   def create_app(self, prompt: str, output_dir: str = "/content/generated_app") -> Dict:
       """
       Main workflow: Transform a simple prompt into a complete application
       """
       print(f"🚀 TinyDev workflow starting...")
       print(f"📝 Prompt: {prompt}")
      
       print("n📋 Step 1: Planning shared dependencies...")
       shared_deps = self.plan(prompt)
       print("✅ Dependencies planned")
      
       print("n📁 Step 2: Determining file structure...")
       file_paths = self.specify_file_paths(prompt, shared_deps)
       print(f"📄 Files to generate: {file_paths}")
      
       Path(output_dir).mkdir(parents=True, exist_ok=True)
      
       print(f"n⚡ Step 3: Generating {len(file_paths)} files...")
       results = {
           'prompt': prompt,
           'shared_deps': shared_deps,
           'files': {},
           'output_dir': output_dir
       }
      
       with open(Path(output_dir) / "shared_dependencies.md", 'w') as f:
           f.write(shared_deps)
      
       for filename in file_paths:
           print(f"  🔧 Generating {filename}...")
           try:
               code = self.generate_code_sync(prompt, shared_deps, filename)
              
               file_path = Path(output_dir) / filename
               file_path.parent.mkdir(parents=True, exist_ok=True)
              
               with open(file_path, 'w', encoding='utf-8') as f:
                   f.write(code)
              
               results['files'][filename] = code
               print(f"  ✅ {filename} created ({len(code)} chars)")
              
           except Exception as e:
               print(f"  ❌ Error generating {filename}: {e}")
               results['files'][filename] = f"# Error: {e}"
      
       readme = f"""# Generated by TinyDev (Gemini-Powered)


## Original Prompt
{prompt}


## Generated Files
{chr(10).join(f'- {f}' for f in file_paths)}


## About TinyDev
TinyDev is inspired by smol-ai/developer but uses free Gemini API.
It follows the proven three-phase workflow: Plan → Files → Code


## Usage
Check individual files for specific usage instructions.


Generated on: {os.popen('date').read().strip()}
"""
      
       with open(Path(output_dir) / "README.md", 'w') as f:
           f.write(readme)
      
       print(f"n🎉 Complete! Generated {len(results['files'])} files in {output_dir}")
       return results

The TinyDev class uses the Gemini API to encapsulate the complete logic of an AI-driven code generator. It implements a structured three-phase workflow: first, it analyzes user prompts to generate shared dependencies (plans); next, it identifies which files the application needs (specified_file_paths); last, it generates functional code (generate_code_sync) for each file separately. The Create_app method provides a complete, available application scaffolding from a single prompt by curating a complete application pipeline and saving the results (including code files and detailed readings).

def demo_tinydev():
   """Demo the TinyDev code generator"""
  
   api_key = "Use Your API Key here"
  
   if api_key == "YOUR_GEMINI_API_KEY_HERE":
       print("❌ Please set your Gemini API key!")
       print("Get one free at: 
       return None
  
   tiny_dev = TinyDev(api_key)
  
   demo_prompts = [
       "a simple HTML/JS/CSS tic tac toe game",
       "a Python web scraper that gets the latest news from multiple sources",
       "a responsive landing page for a local coffee shop with contact form",
       "a Flask REST API for managing a todo list",
       "a JavaScript calculator with a modern UI"
   ]
  
   print("🤖 TinyDev - AI Code Generator")
   print("=" * 50)
   print("Inspired by smol-ai/developer, powered by Gemini API")
   print(f"Available demo projects:")
  
   for i, prompt in enumerate(demo_prompts, 1):
       print(f"{i}. {prompt}")
  
   demo_prompt = demo_prompts[0] 
   print(f"n🎯 Running demo: {demo_prompt}")
  
   try:
       results = tiny_dev.create_app(demo_prompt)
      
       print(f"n📊 Results Summary:")
       print(f"  📝 Prompt: {results['prompt']}")
       print(f"  📁 Output: {results['output_dir']}")
       print(f"  📄 Files: {len(results['files'])}")
      
       print(f"n📋 Generated Files:")
       for filename in results['files'].keys():
           print(f"  - {filename}")
      
       if results['files']:
           preview_file = list(results['files'].keys())[0]
           preview_code = results['files'][preview_file]
           print(f"n👁️  Preview of {preview_file}:")
           print("-" * 40)
           print(preview_code[:400] + "..." if len(preview_code) > 400 else preview_code)
           print("-" * 40)
      
       print(f"n💡 This uses the same proven workflow as smol-ai/developer!")
       print(f"📂 Check {results['output_dir']} for all generated files")
      
       return results
      
   except Exception as e:
       print(f"❌ Demo failed: {e}")
       return None

The Demo_tinydev() function demonstrates the functionality of TinyDev by using one of several example tips, such as generating a TIC TAC TOE game or Python News Scraper. It initializes the TinyDev class using the Gemini API key, selects the first prompt from the project creative list, and guides the user through a complete code generation pipeline, including planning shared dependencies, defining file structures, and generating code. After execution, it summarizes the output, previews the sample file, and points to the directory where the full application has been saved.

def interactive_tinydev():
   """Interactive version where you can try your own prompts"""
   api_key = input("🔑 Enter your Gemini API key: ").strip()
  
   if not api_key:
       print("❌ API key required!")
       return
  
   tiny_dev = TinyDev(api_key)
  
   print("n🎮 Interactive TinyDev Mode")
   print("Type your app ideas and watch them come to life!")
  
   while True:
       prompt = input("n💭 Describe your app (or 'quit'): ").strip()
      
       if prompt.lower() in ['quit', 'exit', 'q']:
           print("👋 Goodbye!")
           break
      
       if prompt:
           try:
               results = tiny_dev.create_app(prompt, f"/content/app_{hash(prompt) % 10000}")
               print(f"✅ Success! Check {results['output_dir']}")
           except Exception as e:
               print(f"❌ Error: {e}")


print("🎬 TinyDev - AI Code Generator Ready!")
print("Inspired by smol-ai/developer, powered by free Gemini API")
print("nTo run demo: demo_tinydev()")
print("To try interactive mode: interactive_tinydev()")

The Interactive_tinydev() function allows users to generate applications from their custom prompts in real time. After entering a valid Gemini API key, the user can describe the idea of ​​any application, and TinyDev will automatically develop complete projects, code, structure and support files. The process continues to loop until the user typed “Exit”. This interactive mode enables rapid prototypes of hands-on experimentation and natural language description.

Finally, use the sample application prompt to call demo_tinydev() to run the predefined demo of tinydev. It introduces a complete workflow, planning, file structure creation and code generation to show how the tool can automatically build a complete application from a simple idea.

In summary, the TinyDev class demonstrates the potential of using AI to automate application scaffolding with obvious accuracy and efficiency. By breaking down the code generation process into intuitive stages, it ensures that the output is logically reasonable, well-structured, and consistent with the user’s intentions. Whether you are exploring new application ideas or looking to accelerate development, Tinydev offers a lightweight and user-friendly solution provided by the Gemini model. This is a practical tool for developers who want to integrate AI into their workflows without unnecessary complexity or overhead.


Check The notebook is here. All credits for this study are to the researchers on the project. Also, please feel free to follow us twitter And don’t forget to join us 100K+ ml reddit And subscribe Our newsletter.


Sana Hassan, a consulting intern at Marktechpost and a dual-degree student at IIT Madras, is passionate about applying technology and AI to address real-world challenges. He is very interested in solving practical problems, and he brings a new perspective to the intersection of AI and real-life solutions.

Related Articles

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top button