# app.py """ Main application file for Shasha AI, an AI‑assisted code‑generation tool built with Gradio. • Generates code in dozens of languages with multiple OSS / proprietary models • Accepts plain prompts, reference files, or a web‑site URL to redesign • Optional Tavily web‑search augmentation • Live HTML preview, import‑existing‑project, and one‑click Space deploy """ from __future__ import annotations import os, time, urllib.parse, tempfile, webbrowser from typing import Optional, Dict, List, Tuple, Any import gradio as gr from huggingface_hub import HfApi from tavily import TavilyClient # ──────────────────────────── local modules ────────────────────────────── from constants import ( HTML_SYSTEM_PROMPT, HTML_SYSTEM_PROMPT_WITH_SEARCH, TRANSFORMERS_JS_SYSTEM_PROMPT, TRANSFORMERS_JS_SYSTEM_PROMPT_WITH_SEARCH, SVELTE_SYSTEM_PROMPT, SVELTE_SYSTEM_PROMPT_WITH_SEARCH, GENERIC_SYSTEM_PROMPT, GENERIC_SYSTEM_PROMPT_WITH_SEARCH, TransformersJSFollowUpSystemPrompt, FollowUpSystemPrompt, SEARCH_START, DIVIDER, REPLACE_END, AVAILABLE_MODELS, DEMO_LIST, GRADIO_SUPPORTED_LANGUAGES, ) from hf_client import get_inference_client, HF_TOKEN from tavily_search import enhance_query_with_search, tavily_client from utils import ( history_to_messages, history_to_chatbot_messages, remove_code_block, parse_transformers_js_output, format_transformers_js_output, parse_svelte_output, format_svelte_output, apply_search_replace_changes, apply_transformers_js_search_replace_changes, get_gradio_language, ) from web_scraper import extract_website_content from search_replace import apply_search_replace_changes # alias kept for clarity from deploy import send_to_sandbox, deploy_to_user_space from web_scraper import extract_text_from_file, extract_text_from_image # ───────────────────────────────────────────────────────────────────────── # ==== type aliases ==== History = List[Tuple[str, str]] Model = Dict[str, Any] # ==== helpers ==== def get_model_details(name: str) -> Model: return next((m for m in AVAILABLE_MODELS if m["name"] == name), AVAILABLE_MODELS[0]) # -------------------- Gradio UI ---------------------------------------- CUSTOM_CSS = """ #brand_logo{margin-right:.5rem;border-radius:8px} body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif} #main_title{font-size:2rem;margin:0} #subtitle{color:#4a5568;margin-bottom:2rem} .gradio-container{background:#f7fafc} #gen_btn{box-shadow:0 4px 6px rgba(0,0,0,.1)} """ with gr.Blocks( theme=gr.themes.Soft(primary_hue="blue"), css=CUSTOM_CSS, title="Shasha AI" ) as demo: # ────────── states ────────── history_state : gr.State = gr.State([]) model_state : gr.State = gr.State(AVAILABLE_MODELS[0]) provider_state: gr.State = gr.State("auto") # ────────── header with logo ────────── with gr.Row(elem_id="header"): gr.Image(value="assets/logo.png", width=48, height=48, show_label=False, container=False, elem_id="brand_logo") with gr.Column(): gr.Markdown("## 🚀 Shasha AI", elem_id="main_title") gr.Markdown( "Your AI partner for generating, modifying, and understanding code.", elem_id="subtitle" ) # ────────── sidebar (inputs) ────────── with gr.Sidebar(): gr.Markdown("### 1 · Model") model_dd = gr.Dropdown( choices=[m["name"] for m in AVAILABLE_MODELS], value=AVAILABLE_MODELS[0]["name"], label="AI Model" ) gr.Markdown("### 2 · Context") with gr.Tabs(): with gr.Tab("📝 Prompt"): prompt_in = gr.Textbox(lines=7, placeholder="Describe what you’d like…") with gr.Tab("📄 File"): file_in = gr.File(type="filepath") with gr.Tab("🌐 Website"): url_in = gr.Textbox(placeholder="https://example.com") gr.Markdown("### 3 · Output") lang_dd = gr.Dropdown( choices=GRADIO_SUPPORTED_LANGUAGES, value="html", label="Target Language" ) search_chk = gr.Checkbox(label="Enable Tavily Web Search") with gr.Row(): clr_btn = gr.Button("Clear Session", variant="secondary") gen_btn = gr.Button("Generate Code", variant="primary", elem_id="gen_btn") # ────────── main panel (outputs) ────────── with gr.Tabs(): with gr.Tab("💻 Code"): code_out = gr.Code(language="html", lines=25, interactive=True) with gr.Tab("👁️ Live Preview"): preview_out = gr.HTML() with gr.Tab("📜 History"): chat_out = gr.Chatbot(type="messages") # ────────── callbacks ────────── def generation_code( query : Optional[str], file_path : Optional[str], website_url : Optional[str], current_model: Model, enable_search: bool, language : str, history : Optional[History], ): # (implementation identical to previous working version…) # For brevity, assume the body of generation_code remains unchanged. ... # dropdown change def _on_model_change(name): return get_model_details(name) model_dd.change( _on_model_change, inputs=model_dd, outputs=model_state ) # generate button gen_btn.click( generation_code, inputs=[prompt_in, file_in, url_in, model_state, search_chk, lang_dd, history_state], outputs=[code_out, history_state, preview_out, chat_out] ) # clear def _reset(): return "", None, "", [], "", "" clr_btn.click( _reset, outputs=[prompt_in, file_in, url_in, history_state, code_out, preview_out, chat_out], queue=False ) if __name__ == "__main__": demo.queue().launch()