Spaces:
Sleeping
Sleeping
| import os | |
| import gradio as gr | |
| from fastapi import FastAPI | |
| from google.generativeai.generative_models import GenerativeModel | |
| from google.generativeai import configure | |
| import asyncio | |
| import requests | |
| import json | |
| import re | |
| from gradio.routes import mount_gradio_app | |
| # --- Load API Keys from Secrets --- | |
| BROWSERLESS_API_KEY = os.environ.get("BROWSERLESS_API_KEY") | |
| GEMINI_API_KEY = os.environ.get("GEMINI_API_KEY") | |
| # --- Configure Gemini API --- | |
| configure(api_key=GEMINI_API_KEY) | |
| # Use the specified Gemini model | |
| model = GenerativeModel(model_name="gemini-1.5-flash") | |
| # --- FastAPI Setup --- | |
| app = FastAPI() | |
| def scrape_with_browserless(url, api_key): | |
| """Scrapes a URL using the Browserless API.""" | |
| try: | |
| response = requests.post( | |
| f"https://chrome.browserless.io/scrape?token={api_key}", | |
| json={"url": url} | |
| ) | |
| response.raise_for_status() | |
| return response.json().get('html') | |
| except Exception as e: | |
| return f"Browserless API error: {e}" | |
| def generate_action_plan_with_execution(command, initial_url): | |
| """ | |
| Generates an action plan from Gemini and executes the navigate step | |
| using Browserless. | |
| """ | |
| try: | |
| # Step 1: Generate the plan (AI Reasoning) | |
| prompt = f""" | |
| You are an AI web assistant. Your task is to interpret a user's natural language command and create a detailed, step-by-step action plan to accomplish it. The plan MUST be outputted as a JSON array ONLY. Do not include any extra text, markdown formatting, or explanations. Each object in the array should represent a single action. | |
| Possible actions and their properties: | |
| - action: "navigate" | |
| target: a full URL to go to (e.g., https://www.google.com). | |
| The current URL is: {initial_url} | |
| The user's command is: "{command}" | |
| Generate the JSON action plan. The only keys allowed are "action" and "target". | |
| """ | |
| response = model.generate_content(prompt) | |
| json_plan_text = response.text | |
| # Step 2: Parse the JSON plan and execute it | |
| match = re.search(r'\[.*\]', json_plan_text, re.DOTALL) | |
| if match: | |
| json_plan_text = match.group(0) | |
| plan = json.loads(json_plan_text) | |
| output_messages = [] | |
| for step in plan: | |
| action = step.get("action") | |
| target = step.get("target") | |
| if action == "navigate": | |
| # Validate the URL before making the call | |
| if target is None or not target.startswith('http'): | |
| return "Error: The AI generated an invalid URL. Please try a different command." | |
| # Use the Browserless API to get the page content | |
| page_content = scrape_with_browserless(target, BROWSERLESS_API_KEY) | |
| if "Browserless API error" in page_content: | |
| return page_content | |
| output_messages.append(f"Successfully executed 'navigate' action. Scraped content length: {len(page_content)} characters.") | |
| # Now, use Gemini to summarize the scraped content | |
| summary_prompt = f"Summarize the main points of the following HTML content:\n\n{page_content[:5000]}" # Truncate large content | |
| summary_response = model.generate_content(summary_prompt) | |
| output_messages.append("\n--- Gemini Summary of Scraped Page ---\n") | |
| output_messages.append(summary_response.text) | |
| else: | |
| return f"An error occurred: Unsupported action '{action}'" | |
| return "\n".join(output_messages) | |
| except Exception as e: | |
| return f"An error occurred: {e}" | |
| # --- Gradio Interface --- | |
| iface = gr.Interface( | |
| fn=generate_action_plan_with_execution, | |
| inputs=[ | |
| gr.Textbox(label="Enter your natural language command"), | |
| gr.Textbox(label="Enter the initial URL") | |
| ], | |
| outputs="text", | |
| title="AI Web Assistant (Browserless)", | |
| description="This app uses Gemini to plan and the Browserless API to execute web tasks." | |
| ) | |
| app = mount_gradio_app(app, iface, path="/") | |