Spaces:
Runtime error
Runtime error
File size: 3,907 Bytes
e489749 cf929e7 e489749 cf929e7 e489749 cf929e7 e489749 cf929e7 e489749 cf929e7 e489749 cf929e7 e489749 cf929e7 e489749 cf929e7 e489749 cf929e7 e489749 cf929e7 e489749 cf929e7 df2f885 cf929e7 e489749 cf929e7 e489749 cf929e7 e489749 cf929e7 e489749 cf929e7 e489749 cf929e7 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
import gradio as gr
from dotenv import load_dotenv
from openai import OpenAI
from duckduckgo_search import DDGS
import os
import requests
import json
import re
# Load environment variables
load_dotenv()
API_KEY = os.getenv("OPENAI_API_KEY")
MODEL_NAME = os.getenv("MODEL_NAME")
BASE_URL = os.getenv("BASE_URL")
IMAGE_SEARCH_ENDPOINT = os.getenv("IMAGE_SEARCH_ENDPOINT")
client = OpenAI(
api_key=API_KEY,
base_url=BASE_URL,
)
# MCP TOOL: Search via DuckDuckGo
def search(query: str) -> list[dict]:
with DDGS() as ddgs:
results = ddgs.text(query, max_results=5)
return results
# MCP TOOL: Analyze Image URL to get caption for further searching
def analyze_image(data: str) -> str:
try:
response = requests.post(IMAGE_SEARCH_ENDPOINT, json={"image_url": data})
if response.status_code == 200:
return response.json().get("caption", "No caption found")
else:
return f"Image analysis failed: {response.status_code}"
except Exception as e:
return f"Error during image analysis: {str(e)}"
# Helper to extract tool_code from model response
def extract_tool_code(text):
match = re.search(r"```tool_code\\n(.*?)```", text, re.DOTALL)
return match.group(1).strip() if match else None
# Helper to format tool output back to model
def format_tool_output(output):
return f"```tool_output\n{json.dumps(output)}\n```"
# CHAT HANDLER
def chat_with_gemma(history, message, image_url):
messages = [
{"role": "system", "content": "You are a helpful assistant who helps users find products online using search and image analysis. Wrap tool use in ```tool_code``` and return results in ```tool_output```."} ]
for user_msg, bot_msg in history:
messages.append({"role": "user", "content": user_msg})
messages.append({"role": "assistant", "content": bot_msg})
if image_url:
image_caption = analyze_image(image_url)
message = f"Image URL: {image_url}\nCaption: {image_caption}\nUser says: {message}"
messages.append({"role": "user", "content": message})
try:
response = client.chat.completions.create(
model=MODEL_NAME,
messages=messages,
temperature=0.7,
max_tokens=512,
)
reply = response.choices[0].message.content.strip()
tool_code = extract_tool_code(reply)
if tool_code:
tool_result = eval(tool_code) # Note: Only safe in dev/testing
tool_output = format_tool_output(tool_result)
messages.append({"role": "user", "content": tool_output})
response2 = client.chat.completions.create(
model=MODEL_NAME,
messages=messages,
temperature=0.7,
max_tokens=512,
)
reply = response2.choices[0].message.content.strip()
except Exception as e:
reply = f"β οΈ Error: {str(e)}"
history.append((message, reply))
return history, "", ""
# GRADIO UI
with gr.Blocks(title="π§ Gemma Shopper - MCP Tool(demo)") as demo:
gr.Markdown("""
<h1 style='text-align: center; color: #4e73df;'>ποΈ Gemma Product Finder</h1>
""")
with gr.Row():
chatbot = gr.Chatbot(height=420, label="π§ Chat with Gemma", bubble_full_width=False)
with gr.Row():
msg = gr.Textbox(label="π¬ Ask something", placeholder="e.g. Red Nike shoes under 4000", scale=3)
image_url = gr.Textbox(label="π Optional image URL", placeholder="Paste image URL here", scale=2)
with gr.Row():
clear = gr.Button("π Clear Chat", variant="secondary")
state = gr.State([])
msg.submit(chat_with_gemma, [state, msg, image_url], [chatbot, msg, image_url])
clear.click(lambda: ([], "", ""), outputs=[chatbot, msg, image_url])
if __name__ == "__main__":
demo.launch(mcp_server=True) |