Spaces:
Running
Running
| import os | |
| import gradio as gr | |
| from ultralytics import YOLO | |
| from PIL import Image, ImageDraw | |
| from openai import AzureOpenAI | |
| # Load YOLOv8 model | |
| model = YOLO("yolov8m.pt") | |
| # Azure OpenAI configuration | |
| endpoint = "https://kendrickfilbert-9824-resource.cognitiveservices.azure.com/" | |
| deployment = "gpt-5.3-chat-ken" | |
| api_version = "2024-12-01-preview" | |
| subscription_key = os.environ.get("AZURE_OPENAI_API_KEY") | |
| if not subscription_key: | |
| raise ValueError( | |
| "AZURE_OPENAI_API_KEY is not set! " | |
| "Add it as a secret in your Hugging Face Space settings." | |
| ) | |
| client = AzureOpenAI( | |
| api_version=api_version, | |
| azure_endpoint=endpoint, | |
| api_key=subscription_key, | |
| ) | |
| SYSTEM_PROMPT = ( | |
| "You are Ken Chatbot, a helpful and friendly AI assistant. " | |
| "You can answer questions on any topic. When the user uploads an image, " | |
| "you may also receive object detection results to discuss." | |
| ) | |
| def build_api_messages(chat_history): | |
| """Convert Gradio chat history to OpenAI API message format.""" | |
| messages = [{"role": "system", "content": SYSTEM_PROMPT}] | |
| for msg in chat_history: | |
| messages.append({"role": msg["role"], "content": msg["content"]}) | |
| return messages | |
| def chat_with_bot(message, chat_history): | |
| """Send a text message to GPT-5.3 and return updated chat history.""" | |
| if not message.strip(): | |
| return chat_history, "" | |
| # Add user message to Gradio history | |
| chat_history.append({"role": "user", "content": message}) | |
| # Call Azure OpenAI with full conversation context | |
| api_messages = build_api_messages(chat_history) | |
| response = client.chat.completions.create( | |
| model=deployment, | |
| messages=api_messages, | |
| max_completion_tokens=4096, | |
| ) | |
| bot_reply = response.choices[0].message.content | |
| # Add assistant reply to Gradio history | |
| chat_history.append({"role": "assistant", "content": bot_reply}) | |
| return chat_history, "" | |
| def analyze_image(image_path, chat_history): | |
| """Run YOLOv8 detection, then ask GPT-5.3 to comment on the results.""" | |
| if image_path is None: | |
| return None, chat_history | |
| try: | |
| image = Image.open(image_path).convert("RGB") | |
| results = model(image) | |
| detected_objects = [] | |
| image_draw = image.copy() | |
| draw = ImageDraw.Draw(image_draw) | |
| for result in results: | |
| for box in result.boxes.data: | |
| x1, y1, x2, y2, score, class_id = box.tolist() | |
| if score > 0.5: | |
| class_name = model.names[int(class_id)] | |
| detected_objects.append(f"{class_name} ({score:.0%})") | |
| draw.rectangle([x1, y1, x2, y2], outline="red", width=3) | |
| draw.text((x1, y1 - 12), class_name, fill="red") | |
| # Build a summary and feed it to GPT-5.3 | |
| if detected_objects: | |
| detection_summary = ", ".join(detected_objects) | |
| user_msg = ( | |
| f"[Image uploaded] Objects detected by YOLO: {detection_summary}. " | |
| "Please describe what you see and any interesting observations." | |
| ) | |
| else: | |
| user_msg = ( | |
| "[Image uploaded] No objects were detected. " | |
| "Let the user know and suggest they try a clearer image." | |
| ) | |
| chat_history.append({"role": "user", "content": user_msg}) | |
| api_messages = build_api_messages(chat_history) | |
| response = client.chat.completions.create( | |
| model=deployment, | |
| messages=api_messages, | |
| max_completion_tokens=2048, | |
| ) | |
| bot_reply = response.choices[0].message.content | |
| chat_history.append({"role": "assistant", "content": bot_reply}) | |
| return image_draw, chat_history | |
| except Exception as e: | |
| error_msg = f"Error processing the image: {str(e)}" | |
| chat_history.append({"role": "user", "content": "Uploaded an image for analysis"}) | |
| chat_history.append({"role": "assistant", "content": error_msg}) | |
| return None, chat_history | |
| def clear_all(): | |
| """Reset conversation.""" | |
| return None, [], "" | |
| #Gradio UI | |
| with gr.Blocks(title="Ken Chatbot") as demo: | |
| gr.Markdown("# Ken Chatbot") | |
| gr.Markdown("Ask me anything or upload an image for analysis! Powered by **GPT-5.3** + **YOLOv8**.") | |
| chatbot = gr.Chatbot(elem_id="chatbot", height=480) | |
| with gr.Row(): | |
| msg = gr.Textbox( | |
| placeholder="Type your message here...", | |
| show_label=False, | |
| scale=4, | |
| ) | |
| send_btn = gr.Button("Send", variant="primary", scale=1) | |
| with gr.Row(): | |
| img_upload = gr.Image(type="filepath", label="Upload an image for analysis") | |
| img_output = gr.Image(label="Detected Objects") | |
| clear_btn = gr.Button("Clear conversation") | |
| # Event bindings — pass chat_history as state via chatbot component | |
| msg.submit(chat_with_bot, [msg, chatbot], [chatbot, msg]) | |
| send_btn.click(chat_with_bot, [msg, chatbot], [chatbot, msg]) | |
| img_upload.change(analyze_image, [img_upload, chatbot], [img_output, chatbot]) | |
| clear_btn.click(clear_all, None, [img_output, chatbot, msg]) | |
| demo.launch() |