|
import gradio as gr |
|
import modal |
|
import json |
|
|
|
|
|
MODAL_APP_NAME = "sitegeist-ai-app" |
|
|
|
def analyze_web_content(urls_json: str, deep_analysis: bool = False, analysis_prompt: str = "Summarize the content and identify key themes."): |
|
""" |
|
MCP Tool: Analyzes web content from one or more URLs. |
|
Performs deep analysis with marketing metrics if a single URL is provided and deep_analysis is True. |
|
Otherwise, performs a swarm analysis for multiple URLs or a single URL without deep_analysis. |
|
|
|
Args: |
|
urls_json (str): A JSON string representing a list of URLs. e.g., '["http://example.com", "http://another.com"]' |
|
deep_analysis (bool): If True and only one URL is provided, performs an in-depth analysis. |
|
analysis_prompt (str): The specific analysis to perform on the content. |
|
""" |
|
print(f"Received request: deep_analysis={deep_analysis}, prompt='{analysis_prompt}', urls_json='{urls_json}'") |
|
try: |
|
urls = json.loads(urls_json) |
|
if not isinstance(urls, list) or not all(isinstance(url, str) for url in urls): |
|
raise ValueError("Input must be a JSON string of a list of URLs.") |
|
if not urls: |
|
return json.dumps({"status": "error", "message": "URL list cannot be empty."}) |
|
except json.JSONDecodeError: |
|
return json.dumps({"status": "error", "message": "Invalid JSON format for URLs."}) |
|
except ValueError as ve: |
|
return json.dumps({"status": "error", "message": str(ve)}) |
|
|
|
result = None |
|
try: |
|
if len(urls) == 1 and deep_analysis: |
|
print(f"Calling Modal: deep_analyze_url for {urls[0]}") |
|
|
|
modal_deep_analyze = modal.Function.lookup(MODAL_APP_NAME, "deep_analyze_url") |
|
if modal_deep_analyze is None: |
|
return json.dumps({"status": "error", "message": f"Could not find Modal function 'deep_analyze_url' in app '{MODAL_APP_NAME}'."}) |
|
|
|
result = modal_deep_analyze.remote(url=urls[0]) |
|
else: |
|
print(f"Calling Modal: swarm_analyze_urls for {len(urls)} URLs") |
|
|
|
modal_swarm_analyze = modal.Function.lookup(MODAL_APP_NAME, "swarm_analyze_urls") |
|
if modal_swarm_analyze is None: |
|
return json.dumps({"status": "error", "message": f"Could not find Modal function 'swarm_analyze_urls' in app '{MODAL_APP_NAME}'."}) |
|
|
|
result = modal_swarm_analyze.remote(urls=urls, analysis_prompt=analysis_prompt) |
|
|
|
return json.dumps(result, indent=2) |
|
|
|
except modal.exception.NotFoundError as e: |
|
print(f"Modal function not found: {e}") |
|
return json.dumps({"status": "error", "message": f"Modal function lookup failed. Ensure '{MODAL_APP_NAME}' is deployed and functions are correctly named. Details: {e}"}) |
|
except Exception as e: |
|
print(f"An unexpected error occurred: {e}") |
|
return json.dumps({"status": "error", "message": f"An unexpected error occurred: {str(e)}"}) |
|
|
|
|
|
|
|
|
|
with gr.Blocks() as demo: |
|
gr.Markdown("# Sitegeist AI: Marketing & Content Intelligence Engine") |
|
gr.Markdown( |
|
"Enter URLs as a JSON list (e.g., `[\"http://url1.com\", \"http://url2.com\"]`). " |
|
"The Modal backend calls are mocked and will return predefined data." |
|
) |
|
with gr.Row(): |
|
urls_input = gr.Textbox(label="URLs (JSON list)", placeholder='["https://example.com"]') |
|
deep_analysis_checkbox = gr.Checkbox(label="Perform Deep Analysis (for single URL)", value=False) |
|
analysis_prompt_input = gr.Textbox(label="Analysis Prompt", value="Summarize the content.") |
|
submit_button = gr.Button("Analyze Content") |
|
output_json = gr.JSON(label="Analysis Result") |
|
|
|
submit_button.click( |
|
analyze_web_content, |
|
inputs=[urls_input, deep_analysis_checkbox, analysis_prompt_input], |
|
outputs=output_json |
|
) |
|
|
|
if __name__ == "__main__": |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
print("Attempting to launch Gradio demo...") |
|
print("REMINDER: For Gradio to connect to Modal functions,") |
|
print(f"1. Deploy 'modal_app.py' using 'modal deploy modal_app.py'.") |
|
print(f"2. Ensure your Modal token is set up.") |
|
print(f"3. The MODAL_APP_NAME ('{MODAL_APP_NAME}') in app.py must match the app name in modal_app.py.") |
|
|
|
demo.launch(mcp_server=True) |