Spaces:
Running
Running
File size: 4,796 Bytes
c92ea65 693bdb2 c92ea65 abfac44 d8c5e10 7936d9a e01ab7c d8c5e10 abfac44 693bdb2 abfac44 693bdb2 abfac44 693bdb2 abfac44 693bdb2 abfac44 693bdb2 7936d9a 693bdb2 f5327ec 693bdb2 33bbb87 7936d9a 33bbb87 7936d9a 693bdb2 f5327ec 693bdb2 e01ab7c 7936d9a e01ab7c 693bdb2 e01ab7c 693bdb2 e01ab7c 693bdb2 e01ab7c 693bdb2 e01ab7c 693bdb2 e01ab7c 693bdb2 e01ab7c 693bdb2 abfac44 693bdb2 c92ea65 693bdb2 e01ab7c 7936d9a 693bdb2 e01ab7c 693bdb2 e01ab7c 693bdb2 e01ab7c 693bdb2 e01ab7c 693bdb2 7936d9a 693bdb2 e01ab7c 693bdb2 abfac44 693bdb2 7936d9a 693bdb2 6eda213 abfac44 7936d9a 693bdb2 6eda213 7aaf290 8b9fcae 7aaf290 ab133b3 |
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 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
"""
Gradio + OpenAI MCP Connector — Clean, Fast, Streaming, With File Upload
"""
import os
import shutil
import gradio as gr
from openai import OpenAI
# ---------------------
# CONFIGURATION
# ---------------------
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
MCP_SERVER_URL = "https://mcp-1st-birthday-auto-deployer.hf.space/gradio_api/mcp/"
MODEL_FAST = "gpt-5-mini" # for tool resolution
MODEL_STREAM = "gpt-5.1" # for final streaming reply
client = OpenAI(api_key=OPENAI_API_KEY)
SYSTEM_PROMPT = """
You are a fast MLOps assistant with access to remote MCP tools.
Use tools only when necessary.
Keep reasoning effort LOW for speed.
After tools run, summarize clearly and concisely.
"""
# ---------------------
# NATIVE MCP CONNECTOR
# ---------------------
TOOLS = [
{
"type": "mcp",
"server_label": "deploy_tools",
"server_url": MCP_SERVER_URL,
# transport auto-detected; HF space supports HTTP
}
]
# ---------------------
# FILE UPLOAD HANDLER
# ---------------------
def handle_upload(file_obj, request: gr.Request):
if file_obj is None:
return None
# Ensure file is in a stable path
local_path = file_obj.name
stable_path = os.path.join("/tmp", os.path.basename(local_path))
try:
shutil.copy(local_path, stable_path)
local_path = stable_path
except Exception:
pass
# Build public Gradio URL
base = str(request.base_url).rstrip("/")
return f"{base}/gradio_api/file={local_path}"
# ---------------------
# MAIN CHAT HANDLER
# ---------------------
def chat_send_stream(user_msg, history, file_url):
# history always starts as list of dicts
if history is None:
history = []
# Append the user's message
history.append({"role": "user", "content": user_msg})
# Build OpenAI message history
messages = [{"role": "system", "content": SYSTEM_PROMPT}]
messages.extend(history)
# Inject file context
final_user_msg = user_msg
if file_url:
final_user_msg = f"[Uploaded CSV file: {file_url}]\n\n{user_msg}"
messages[-1] = {"role": "user", "content": final_user_msg}
# ----------------------------------
# PHASE 1 — TOOL RESOLUTION
# ----------------------------------
tool_phase = client.responses.create(
model=MODEL_FAST,
reasoning={"effort": "low"},
tools=TOOLS,
instructions=SYSTEM_PROMPT,
input=messages,
)
tool_feedback = []
if tool_phase.output:
for item in tool_phase.output:
if item.type == "tool_call":
tool_feedback.append(f"🛠️ Used tool `{item.name}`.")
elif item.type == "tool_result":
tool_feedback.append(str(item.content))
if not tool_feedback:
tool_feedback.append("No MCP tools needed.")
else:
tool_feedback.append("No MCP tools needed.")
# Add assistant message with tool feedback
history.append({"role": "assistant", "content": "\n".join(tool_feedback)})
yield history
# ----------------------------------
# PHASE 2 — STREAMING FINAL ANSWER
# ----------------------------------
final_msg = history[-1]["content"] + "\n\n"
history[-1]["content"] = final_msg
stream = client.responses.create(
model=MODEL_STREAM,
reasoning={"effort": "low"},
instructions=SYSTEM_PROMPT,
input=messages + [history[-1]],
stream=True,
)
for ev in stream:
if ev.type == "response.output_text.delta":
final_msg += ev.delta
history[-1]["content"] = final_msg
yield history
elif ev.type == "response.completed":
break
stream.close()
# ---------------------
# GRADIO UI
# ---------------------
with gr.Blocks(title="MCP + GPT-5 — Fast Streaming MLOps Agent") as demo:
gr.Markdown("""
# 🚀 AI-Driven MLOps Agent (MCP-Powered)
- Upload a CSV file
- Tools resolve instantly
- Final answer streams smoothly
""")
file_state = gr.State()
uploader = gr.File(label="Upload CSV file", type="filepath", file_count="single")
uploader.change(handle_upload, inputs=[uploader], outputs=[file_state])
chatbot = gr.Chatbot(label="Chat")
msg = gr.Textbox(label="Message")
send = gr.Button("Send")
send.click(
chat_send_stream,
inputs=[msg, chatbot, file_state],
outputs=[chatbot],
).then(lambda: "", outputs=[msg])
msg.submit(
chat_send_stream,
inputs=[msg, chatbot, file_state],
outputs=[chatbot],
).then(lambda: "", outputs=[msg])
if __name__ == "__main__":
demo.queue().launch(
allowed_paths=["/tmp"],
show_error=True,
quiet=True,
)
|