mgbam commited on
Commit
2b7139c
Β·
verified Β·
1 Parent(s): 93f08f4

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +152 -145
app.py CHANGED
@@ -1,52 +1,40 @@
1
  # app.py
2
- # ---------------------------------------------------------------------
3
- # AnyCoder / ShashaΒ AI – Gradio front‑end (no external static files)
4
- # ---------------------------------------------------------------------
5
  """
6
- Interactive UI for generating / modifying / previewing code with multiple
7
- LLM back‑ends. Relies on:
8
-
9
- β€’ models.py – AVAILABLE_MODELS registry + find_model()
10
- β€’ inference.py – chat_completion() (provider routing handled there)
11
- β€’ utils.py – file / website extractors, history helpers, etc.
12
- β€’ tavily_search.py (optional) – enhance_query_with_search()
13
- β€’ deploy.py – send_to_sandbox() for live HTML preview
14
  """
15
 
16
  from __future__ import annotations
17
-
18
- from pathlib import Path
19
  from typing import List, Tuple, Dict, Any, Optional
20
 
21
  import gradio as gr
22
 
23
- # ---------- local helpers --------------------------------------------------
24
- from models import AVAILABLE_MODELS, find_model, ModelInfo
25
- from inference import chat_completion
26
- from tavily_search import enhance_query_with_search
27
- from utils import (
 
 
 
 
 
 
28
  extract_text_from_file,
29
  extract_website_content,
 
30
  history_to_messages,
31
  history_to_chatbot_messages,
32
- apply_search_replace_changes,
33
  remove_code_block,
34
  parse_transformers_js_output,
35
  format_transformers_js_output,
36
  )
37
- from deploy import send_to_sandbox
38
-
39
- # ---------- constants ------------------------------------------------------
40
- SYSTEM_PROMPTS = {
41
- "html": (
42
- "ONLY USE HTML, CSS AND JAVASCRIPT. Produce ONE complete html file "
43
- "wrapped in ```html … ```."
44
- ),
45
- "transformers.js": (
46
- "Generate THREE fenced blocks: index.html, index.js, style.css "
47
- "for a transformers.js demo."
48
- ),
49
- }
50
  SUPPORTED_LANGUAGES = [
51
  "python", "c", "cpp", "markdown", "latex", "json", "html", "css",
52
  "javascript", "jinja2", "typescript", "yaml", "dockerfile", "shell",
@@ -54,149 +42,168 @@ SUPPORTED_LANGUAGES = [
54
  "sql-cassandra", "sql-plSQL", "sql-hive", "sql-pgSQL", "sql-gql",
55
  "sql-gpSQL", "sql-sparkSQL", "sql-esper",
56
  ]
57
- History = List[Tuple[str, str]] # [(prompt, code/result)]
58
-
59
 
60
- # ---------- core generation callback --------------------------------------
61
- def generate(
62
- prompt: str,
63
- file_path: str | None,
64
- website_url: str | None,
65
- model_name: str,
 
 
 
66
  language: str,
67
- use_search: bool,
68
- hist: History | None,
69
  ) -> Tuple[str, History, str, List[Dict[str, str]]]:
70
- """Main callback wired to the β€œGenerateΒ Code” button."""
71
- hist = hist or []
72
- user_prompt = (prompt or "").strip()
73
-
74
- # 1Β Β· system + previous messages
75
- sys = SYSTEM_PROMPTS.get(language, f"You are an expert {language} developer.")
76
- messages = history_to_messages(hist, sys)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
 
78
- # 2Β Β· gather extra context
79
- ctx_parts: list[str] = [user_prompt]
 
80
 
81
  if file_path:
82
- ctx_parts.append("[Reference file]")
83
- ctx_parts.append(extract_text_from_file(file_path)[:5000])
84
 
85
  if website_url:
86
  html = extract_website_content(website_url)
87
- if not html.lower().startswith("error"):
88
- ctx_parts.append("[Website content]")
89
- ctx_parts.append(html[:8000])
90
 
91
- user_query = "\n\n".join(filter(None, ctx_parts))
92
- user_query = enhance_query_with_search(user_query, use_search)
93
- messages.append({"role": "user", "content": user_query})
94
 
95
- # 3Β Β· call the model
96
- model: ModelInfo = find_model(model_name) or AVAILABLE_MODELS[0]
97
  try:
98
- assistant = chat_completion(model.id, messages)
 
 
 
 
 
 
 
99
  except Exception as exc:
100
- err = f"❌ **Error**\n```{exc}```"
101
- hist.append((user_prompt, err))
102
- return "", hist, "", history_to_chatbot_messages(hist)
103
 
104
- # 4Β Β· post‑process
105
  if language == "transformers.js":
106
- files = parse_transformers_js_output(assistant)
107
- code = format_transformers_js_output(files)
108
  preview = send_to_sandbox(files.get("index.html", ""))
109
  else:
110
- cleaned = remove_code_block(assistant)
111
- if hist and not hist[-1][1].startswith("❌"):
112
- cleaned = apply_search_replace_changes(hist[-1][1], cleaned)
113
- code = cleaned
114
  preview = send_to_sandbox(code) if language == "html" else ""
115
 
116
- # 5Β Β· update history & chat
117
- hist.append((user_prompt, code))
118
- chat_messages = history_to_chatbot_messages(hist)
119
- return code, hist, preview, chat_messages
120
-
121
-
122
- # ---------- UI (GradioΒ 5) --------------------------------------------------
123
- THEME = gr.themes.Soft(primary_hue="indigo")
124
- CSS = """
125
- .gradio-container {max-width: 1450px !important;}
126
- @media (min-width: 960px){
127
- .layout {display:flex; gap:32px}
128
- .inputs {flex:1 0 360px}
129
- .outputs {flex:2 0 0}
130
- }
131
  """
132
 
133
- with gr.Blocks(title="AnyCoderΒ AI", theme=THEME, css=CSS) as demo:
134
- state_hist: gr.State = gr.State([])
 
 
 
 
135
 
136
- # ---- header ----------------------------------------------------------
137
- gr.Markdown(
138
- "## πŸš€Β **AnyCoderΒ AI** \n"
139
- "Your AI partner for generating, modifying & understanding code."
 
 
 
 
 
140
  )
141
 
142
- with gr.Row(elem_classes="layout"):
143
- # -------- left column (inputs) ------------------------------------
144
- with gr.Column(elem_classes="inputs"):
145
- gr.Markdown("### 1β€―Β·β€―Model")
146
- model_dd = gr.Dropdown(
147
- choices=[m.name for m in AVAILABLE_MODELS],
148
- value=AVAILABLE_MODELS[0].name,
149
- label="AIΒ Model",
150
- )
151
-
152
- gr.Markdown("### 2β€―Β·β€―Context")
153
- with gr.Tabs():
154
- with gr.Tab("Prompt"):
155
- prompt_box = gr.Textbox(lines=6, placeholder="Describe what you need…")
156
- with gr.Tab("File"):
157
- file_box = gr.File(type="filepath")
158
- with gr.Tab("Website"):
159
- url_box = gr.Textbox(placeholder="https://example.com")
160
-
161
- gr.Markdown("### 3β€―Β·β€―Output")
162
- lang_dd = gr.Dropdown(SUPPORTED_LANGUAGES, value="html", label="TargetΒ Language")
163
- search_chk = gr.Checkbox(label="Enable TavilyΒ WebΒ Search")
164
-
165
- with gr.Row():
166
- clear_btn = gr.Button("ClearΒ Session", variant="secondary")
167
- gen_btn = gr.Button("GenerateΒ Code", variant="primary")
168
-
169
- # -------- right column (outputs) ----------------------------------
170
- with gr.Column(elem_classes="outputs"):
171
- with gr.Tabs():
172
- with gr.Tab("Code"):
173
- code_out = gr.Code(height=500, language="html")
174
- with gr.Tab("LiveΒ Preview"):
175
- preview_out = gr.HTML()
176
- with gr.Tab("History"):
177
- chat_out = gr.Chatbot(type="messages")
178
-
179
- # ---- callbacks -------------------------------------------------------
180
  gen_btn.click(
181
- generate,
182
- inputs=[
183
- prompt_box, file_box, url_box,
184
- model_dd, lang_dd, search_chk, state_hist
185
- ],
186
- outputs=[code_out, state_hist, preview_out, chat_out],
187
  )
188
 
189
  clear_btn.click(
190
- lambda: ("", None, "", "html", False, [], [], "", []),
191
- outputs=[
192
- prompt_box, file_box, url_box,
193
- lang_dd, search_chk, state_hist,
194
- code_out, preview_out, chat_out,
195
- ],
196
  queue=False,
197
  )
198
 
199
-
200
- # ---------- launch ---------------------------------------------------------
201
  if __name__ == "__main__":
202
  demo.queue().launch()
 
1
  # app.py
 
 
 
2
  """
3
+ Shasha /β€―AnyCoderΒ AI – Gradio front‑end + back‑end
4
+
5
+ Generate or refactor code with multiple foundation models.
6
+ Uploads, website scrape, optional Tavily search enrichment, live HTML preview.
 
 
 
 
7
  """
8
 
9
  from __future__ import annotations
 
 
10
  from typing import List, Tuple, Dict, Any, Optional
11
 
12
  import gradio as gr
13
 
14
+ # ──────────────────────────────────────────────────────────────────────────────
15
+ # Local helpers (unchanged)
16
+ # ──────────────────────────────────────────────────────────────────────────────
17
+ from constants import (
18
+ HTML_SYSTEM_PROMPT,
19
+ TRANSFORMERS_JS_SYSTEM_PROMPT,
20
+ AVAILABLE_MODELS,
21
+ )
22
+ from hf_client import get_inference_client
23
+ from tavily_search import enhance_query_with_search
24
+ from utils import (
25
  extract_text_from_file,
26
  extract_website_content,
27
+ apply_search_replace_changes,
28
  history_to_messages,
29
  history_to_chatbot_messages,
 
30
  remove_code_block,
31
  parse_transformers_js_output,
32
  format_transformers_js_output,
33
  )
34
+ from deploy import send_to_sandbox
35
+
36
+ History = List[Tuple[str, str]]
37
+
 
 
 
 
 
 
 
 
 
38
  SUPPORTED_LANGUAGES = [
39
  "python", "c", "cpp", "markdown", "latex", "json", "html", "css",
40
  "javascript", "jinja2", "typescript", "yaml", "dockerfile", "shell",
 
42
  "sql-cassandra", "sql-plSQL", "sql-hive", "sql-pgSQL", "sql-gql",
43
  "sql-gpSQL", "sql-sparkSQL", "sql-esper",
44
  ]
 
 
45
 
46
+ # ──────────────────────────────────────────────────────────────────────────────
47
+ # Generation callback
48
+ # ──────────────────────────────────────────────────────────────────────────────
49
+ def generation_code(
50
+ query: Optional[str],
51
+ file_path: Optional[str],
52
+ website_url: Optional[str],
53
+ current_model: Dict[str, Any],
54
+ enable_search: bool,
55
  language: str,
56
+ history: History | None,
 
57
  ) -> Tuple[str, History, str, List[Dict[str, str]]]:
58
+ """Core back‑end that the β€œGenerateΒ Code” button calls."""
59
+ query = (query or "").strip()
60
+ history = history or []
61
+
62
+ # Pick proper system prompt
63
+ if language == "html":
64
+ system_prompt = HTML_SYSTEM_PROMPT
65
+ elif language == "transformers.js":
66
+ system_prompt = TRANSFORMERS_JS_SYSTEM_PROMPT
67
+ else:
68
+ system_prompt = (
69
+ f"You are an expert {language} developer. "
70
+ f"Write clean, idiomatic {language} based on the user request."
71
+ )
72
+
73
+ # Route to provider
74
+ model_id = current_model["id"]
75
+ if model_id.startswith(("openai/", "gpt-")):
76
+ provider = "openai"
77
+ elif model_id.startswith(("gemini/", "google/")):
78
+ provider = "gemini"
79
+ elif model_id.startswith("fireworks-ai/"):
80
+ provider = "fireworks-ai"
81
+ else:
82
+ provider = "auto"
83
 
84
+ # Build message list
85
+ messages = history_to_messages(history, system_prompt)
86
+ context_parts: List[str] = [query]
87
 
88
  if file_path:
89
+ context_parts.append("[Attachedβ€―file]")
90
+ context_parts.append(extract_text_from_file(file_path)[:5_000])
91
 
92
  if website_url:
93
  html = extract_website_content(website_url)
94
+ if not html.startswith("Error"):
95
+ context_parts.append("[Websiteβ€―content]")
96
+ context_parts.append(html[:8_000])
97
 
98
+ user_msg = "\n\n".join(context_parts)
99
+ user_msg = enhance_query_with_search(user_msg, enable_search)
100
+ messages.append({"role": "user", "content": user_msg})
101
 
102
+ # Call model
 
103
  try:
104
+ client = get_inference_client(model_id, provider)
105
+ resp = client.chat.completions.create(
106
+ model = model_id,
107
+ messages = messages,
108
+ max_tokens = 16_000,
109
+ temperature= 0.1,
110
+ )
111
+ answer = resp.choices[0].message.content
112
  except Exception as exc:
113
+ err = f"❌ **Error**\n```\n{exc}\n```"
114
+ history.append((query, err))
115
+ return "", history, "", history_to_chatbot_messages(history)
116
 
117
+ # Post‑process
118
  if language == "transformers.js":
119
+ files = parse_transformers_js_output(answer)
120
+ code = format_transformers_js_output(files)
121
  preview = send_to_sandbox(files.get("index.html", ""))
122
  else:
123
+ cleaned = remove_code_block(answer)
124
+ if history and not history[-1][1].startswith("❌"):
125
+ cleaned = apply_search_replace_changes(history[-1][1], cleaned)
126
+ code = cleaned
127
  preview = send_to_sandbox(code) if language == "html" else ""
128
 
129
+ history.append((query, code))
130
+ chat_history = history_to_chatbot_messages(history)
131
+ return code, history, preview, chat_history
132
+
133
+ # ──────────────────────────────────────────────────────────────────────────────
134
+ # Gradio UI
135
+ # ──────────────────────────────────────────────────────────────────────────────
136
+ CUSTOM_CSS = """
137
+ body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;}
138
+ .gradio-container{background:#f9fafb;}
139
+ #gen-btn{box-shadow:0 2px 4px rgba(0,0,0,.08);}
 
 
 
 
140
  """
141
 
142
+ with gr.Blocks(theme=gr.themes.Soft(primary_hue="indigo"),
143
+ title="AnyCoderΒ AI",
144
+ css=CUSTOM_CSS) as demo:
145
+
146
+ state_history: gr.State = gr.State([])
147
+ state_model : gr.State = gr.State(AVAILABLE_MODELS[0])
148
 
149
+ gr.Markdown("## 🏒 **AnyCoderΒ AI**\nYour AI partner for generating, modifying  and  understanding code.",
150
+ elem_id="header")
151
+
152
+ # 1Β Β·Β MODEL
153
+ gr.Markdown("### 1Β Β·Β Model")
154
+ model_dd = gr.Dropdown(
155
+ choices=[m["name"] for m in AVAILABLE_MODELS],
156
+ value=AVAILABLE_MODELS[0]["name"],
157
+ label="AIΒ Model",
158
  )
159
 
160
+ # 2Β Β·Β CONTEXT
161
+ gr.Markdown("### 2Β Β·Β Context")
162
+ with gr.Tabs():
163
+ with gr.Tab("Prompt"):
164
+ prompt_tb = gr.Textbox(lines=6, placeholder="Describe what you need…")
165
+ with gr.Tab("File"):
166
+ file_upl = gr.File(label="ReferenceΒ file")
167
+ import_btn= gr.Button("Importβ€―Project", variant="secondary")
168
+ import_btn.click(lambda: print("import clicked"), outputs=[])
169
+ with gr.Tab("Website"):
170
+ url_tb = gr.Textbox(placeholder="https://example.com")
171
+
172
+ # 3Β Β·Β OUTPUT
173
+ gr.Markdown("### 3Β Β·Β Output")
174
+ lang_dd = gr.Dropdown(SUPPORTED_LANGUAGES, value="html", label="TargetΒ Language")
175
+ search_ck = gr.Checkbox(label="Enable Tavily WebΒ Search")
176
+
177
+ with gr.Row():
178
+ clear_btn = gr.Button("Clear Session", variant="secondary")
179
+ gen_btn = gr.Button("GenerateΒ Code", elem_id="gen-btn")
180
+
181
+ # OUTPUT PANELS
182
+ with gr.Tabs():
183
+ with gr.Tab("Code"):
184
+ code_out = gr.Code(language="html", interactive=True, lines=25)
185
+ with gr.Tab("LiveΒ Preview"):
186
+ preview = gr.HTML()
187
+ with gr.Tab("History"):
188
+ chatbox = gr.Chatbot(type="messages")
189
+
190
+ # ── CALLBACKS ──────────────────────────────────────────────
191
+ model_dd.change(lambda n: next(m for m in AVAILABLE_MODELS if m["name"] == n),
192
+ inputs=model_dd, outputs=state_model)
193
+
 
 
 
 
194
  gen_btn.click(
195
+ fn=generation_code,
196
+ inputs=[prompt_tb, file_upl, url_tb,
197
+ state_model, search_ck, lang_dd, state_history],
198
+ outputs=[code_out, state_history, preview, chatbox],
 
 
199
  )
200
 
201
  clear_btn.click(
202
+ lambda: ("", None, "", [], "", "", []),
203
+ outputs=[prompt_tb, file_upl, url_tb, state_history,
204
+ code_out, preview, chatbox],
 
 
 
205
  queue=False,
206
  )
207
 
 
 
208
  if __name__ == "__main__":
209
  demo.queue().launch()