Sjwjne commited on
Commit
9f0a84b
Β·
verified Β·
1 Parent(s): 192c871

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +82 -88
app.py CHANGED
@@ -1,32 +1,17 @@
1
  import os
 
 
2
  import asyncio
3
  import spaces
4
  import torch
5
  import gradio as gr
6
  from transformers import AutoModelForCausalLM, AutoTokenizer, TextIteratorStreamer
7
  from threading import Thread
8
- from playwright.async_api import async_playwright
9
- from playwright_stealth import stealth
10
 
11
- # --- Playwright Installation Check ---
12
- try:
13
- import playwright
14
- except ImportError:
15
- os.system("pip install playwright playwright-stealth")
16
-
17
- # Space startup par browser install karein
18
- os.system("playwright install chromium")
19
-
20
- # --- AI Model Setup ---
21
- # Qwen 2.5 1.5B - Best balance for ZeroGPU RAM
22
  MODEL_ID = "Qwen/Qwen2.5-1.5B-Instruct"
23
-
24
  tokenizer = AutoTokenizer.from_pretrained(MODEL_ID)
25
- model = AutoModelForCausalLM.from_pretrained(
26
- MODEL_ID,
27
- torch_dtype=torch.bfloat16, # torch_dtype fix
28
- device_map=None # Manual control
29
- ).to("cpu")
30
 
31
  @spaces.GPU
32
  def chat_fn(message, history):
@@ -36,19 +21,11 @@ def chat_fn(message, history):
36
  messages.append({"role": "assistant", "content": h[1]})
37
  messages.append({"role": "user", "content": message})
38
 
39
- model.to("cuda") # Move to GPU only when needed
40
-
41
- input_ids = tokenizer.apply_chat_template(
42
- messages,
43
- tokenize=True,
44
- add_generation_prompt=True,
45
- return_tensors="pt"
46
- ).to("cuda")
47
-
48
  streamer = TextIteratorStreamer(tokenizer, skip_prompt=True, skip_special_tokens=True)
49
- gen_kwargs = dict(input_ids=input_ids, streamer=streamer, max_new_tokens=1024, temperature=0.7)
50
 
51
- thread = Thread(target=model.generate, kwargs=gen_kwargs)
52
  thread.start()
53
 
54
  response = ""
@@ -56,72 +33,89 @@ def chat_fn(message, history):
56
  response += new_text
57
  yield response
58
 
59
- # --- Improved Browser Logic ---
60
- async def browser_task(url, selector=None, text=None, action="nav"):
61
- async with async_playwright() as p:
62
- # Browser launch with args to prevent sandbox crashes
63
- browser = await p.chromium.launch(headless=True, args=["--no-sandbox", "--disable-setuid-sandbox"])
64
- context = await browser.new_context(
65
- viewport={'width': 1280, 'height': 720},
66
- user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36"
67
- )
68
- page = await context.new_page()
69
- await stealth(page)
70
-
71
- try:
72
- # Timeout barha diya hai
73
- await page.goto(url, wait_until="load", timeout=60000)
74
-
75
- if action == "click" and selector:
76
- await page.wait_for_selector(selector, timeout=5000)
77
- await page.click(selector)
78
- await asyncio.sleep(2)
79
- elif action == "type" and selector and text:
80
- await page.wait_for_selector(selector, timeout=5000)
81
- await page.fill(selector, text)
82
- await page.keyboard.press("Enter")
83
- await asyncio.sleep(3)
84
-
85
- screenshot = await page.screenshot()
86
- await browser.close()
87
- return screenshot
88
- except Exception as e:
89
- print(f"Browser Error: {e}")
90
- await browser.close()
91
- return None
92
 
93
- def web_run(url, sel, txt, action):
 
 
 
 
 
 
 
 
94
  try:
95
- return asyncio.run(browser_task(url, sel, txt, action))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96
  except Exception as e:
97
- return None
98
 
99
- # --- Custom UI with Gradio ---
100
- with gr.Blocks(theme=gr.themes.Default()) as demo:
101
- gr.HTML("<h1 style='text-align:center;'>πŸš€ AI Agent + Web Stealth Browser</h1>")
102
 
103
- with gr.Row():
104
- with gr.Column(scale=1):
105
- # Standard Chatbot logic
106
- chat_ui = gr.ChatInterface(fn=chat_fn, type="messages")
107
-
108
- with gr.Column(scale=1):
109
- url_input = gr.Textbox(label="🌐 Website URL", value="https://google.com")
 
110
  with gr.Row():
111
- sel_input = gr.Textbox(label="πŸ” Selector (ID/Class)", placeholder="e.g. input[name='q']")
112
- txt_input = gr.Textbox(label="⌨️ Text to Type", placeholder="Search query...")
113
 
114
- with gr.Row():
115
- btn_visit = gr.Button("Visit", variant="primary")
116
- btn_click = gr.Button("Click")
117
- btn_type = gr.Button("Type & Enter")
118
 
119
- browser_img = gr.Image(label="Live View", type="numpy")
 
 
 
 
 
 
 
 
 
 
 
 
 
120
 
121
- # Handlers
122
- btn_visit.click(lambda u: web_run(u, None, None, "nav"), [url_input], browser_img)
123
- btn_click.click(lambda u, s: web_run(u, s, None, "click"), [url_input, sel_input], browser_img)
124
- btn_type.click(lambda u, s, t: web_run(u, s, t, "type"), [url_input, sel_input, txt_input], browser_img)
 
 
 
125
 
126
  if __name__ == "__main__":
127
- demo.launch()
 
1
  import os
2
+ import shutil
3
+ import subprocess
4
  import asyncio
5
  import spaces
6
  import torch
7
  import gradio as gr
8
  from transformers import AutoModelForCausalLM, AutoTokenizer, TextIteratorStreamer
9
  from threading import Thread
 
 
10
 
11
+ # --- AI Setup ---
 
 
 
 
 
 
 
 
 
 
12
  MODEL_ID = "Qwen/Qwen2.5-1.5B-Instruct"
 
13
  tokenizer = AutoTokenizer.from_pretrained(MODEL_ID)
14
+ model = AutoModelForCausalLM.from_pretrained(MODEL_ID, torch_dtype=torch.bfloat16, device_map=None).to("cpu")
 
 
 
 
15
 
16
  @spaces.GPU
17
  def chat_fn(message, history):
 
21
  messages.append({"role": "assistant", "content": h[1]})
22
  messages.append({"role": "user", "content": message})
23
 
24
+ model.to("cuda")
25
+ input_ids = tokenizer.apply_chat_template(messages, tokenize=True, add_generation_prompt=True, return_tensors="pt").to("cuda")
 
 
 
 
 
 
 
26
  streamer = TextIteratorStreamer(tokenizer, skip_prompt=True, skip_special_tokens=True)
 
27
 
28
+ thread = Thread(target=model.generate, kwargs=dict(input_ids=input_ids, streamer=streamer, max_new_tokens=512))
29
  thread.start()
30
 
31
  response = ""
 
33
  response += new_text
34
  yield response
35
 
36
+ # --- React Preview Logic ---
37
+ BUILD_DIR = "web_app"
38
+ OUTPUT_DIR = "web_app/dist"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
 
40
+ def handle_zip_upload(zip_file):
41
+ if zip_file is None:
42
+ return "Please upload a zip file."
43
+
44
+ # 1. Cleanup old files
45
+ if os.path.exists(BUILD_DIR):
46
+ shutil.rmtree(BUILD_DIR)
47
+ os.makedirs(BUILD_DIR)
48
+
49
  try:
50
+ # 2. Extract Zip
51
+ shutil.unpack_archive(zip_file.name, BUILD_DIR)
52
+
53
+ # 3. Find where package.json is (sometimes it's inside a subfolder)
54
+ root_path = BUILD_DIR
55
+ for root, dirs, files in os.walk(BUILD_DIR):
56
+ if "package.json" in files:
57
+ root_path = root
58
+ break
59
+
60
+ # 4. Install & Build
61
+ yield "Installing libraries (npm install)..."
62
+ subprocess.run(["npm", "install"], cwd=root_path, check=True)
63
+
64
+ yield "Building project (npm run build)..."
65
+ subprocess.run(["npm", "run", "build"], cwd=root_path, check=True)
66
+
67
+ # 5. Serve the 'dist' folder
68
+ dist_path = os.path.join(root_path, "dist")
69
+ if os.path.exists(dist_path):
70
+ # Gradio static access setup
71
+ static_url = f"/file={dist_path}/index.html"
72
+ yield f"### βœ… Build Successful!\nClick to preview below."
73
+ else:
74
+ yield "❌ Error: 'dist' folder not found after build."
75
+
76
  except Exception as e:
77
+ yield f"❌ Error: {str(e)}"
78
 
79
+ # --- Gradio UI Layout ---
80
+ with gr.Blocks(theme=gr.themes.Soft()) as demo:
81
+ gr.HTML("<h1 style='text-align:center;'>Master AI: Chat + Browser + React Preview</h1>")
82
 
83
+ with gr.Tabs():
84
+ # TAB 1: AI Chat
85
+ with gr.TabItem("πŸ’¬ AI Chatbot"):
86
+ gr.ChatInterface(fn=chat_fn, type="messages")
87
+
88
+ # TAB 2: React Live Preview
89
+ with gr.TabItem("βš›οΈ React/Vite Preview"):
90
+ gr.Markdown("### Upload your Vite Project ZIP")
91
  with gr.Row():
92
+ zip_input = gr.File(label="Upload Project ZIP", file_types=[".zip"])
93
+ build_logs = gr.Markdown("Status: Waiting for upload...")
94
 
95
+ build_btn = gr.Button("Build & Preview", variant="primary")
 
 
 
96
 
97
+ # Preview Iframe
98
+ # Note: In Hugging Face, serving local HTML is restricted,
99
+ # we use a workaround to show the build result status.
100
+ preview_area = gr.HTML(label="Preview Screen")
101
+
102
+ def start_preview(file):
103
+ for status in handle_zip_upload(file):
104
+ if "βœ…" in status:
105
+ # Hum file path return karenge jo browser me render ho sake
106
+ # Hugging Face par direct iframe preview ke liye 'dist' folder ko serve karna hota hai
107
+ return status, "Build complete! Check your logs."
108
+ return status, ""
109
+
110
+ build_btn.click(start_preview, inputs=zip_input, outputs=[build_logs, preview_area])
111
 
112
+ # TAB 3: Stealth Browser
113
+ with gr.TabItem("🌐 Stealth Browser"):
114
+ # (Pichla wala browser code yahan aayega)
115
+ gr.Markdown("Browser is active in background...")
116
+
117
+ # Playwright installation
118
+ os.system("playwright install chromium")
119
 
120
  if __name__ == "__main__":
121
+ demo.queue().launch(allowed_paths=["."]) # allowed_paths zaroori hai files serve karne ke liye