Spaces:
Running
Running
File size: 4,843 Bytes
1b8d07e de198d3 1b8d07e a0a02f2 1b8d07e de198d3 1b8d07e a0a02f2 1b8d07e a0a02f2 1b8d07e a0a02f2 1b8d07e a0a02f2 1b8d07e a0a02f2 1b8d07e a0a02f2 1b8d07e a0a02f2 1b8d07e a0a02f2 1b8d07e a0a02f2 1b8d07e a0a02f2 1b8d07e a0a02f2 1b8d07e a0a02f2 1b8d07e a0a02f2 1b8d07e a0a02f2 1b8d07e a0a02f2 1b8d07e a0a02f2 1b8d07e a0a02f2 1b8d07e a0a02f2 1b8d07e a0a02f2 1b8d07e a0a02f2 1b8d07e a0a02f2 1b8d07e |
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 |
import os
import sys
import io
import re
import pandas as pd
import gradio as gr
from contextlib import redirect_stdout
from smolagents import InferenceClientModel, CodeAgent, Tool
def remove_ansi_codes(text):
"""Removes ANSI escape codes (colors) from text."""
ansi_escape = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])')
return ansi_escape.sub('', text)
# Note: MCPClient might not be directly exposed by smolagents in all versions.
# If import fails, a different approach or version check might be needed.
# User provided `from smolagents import ..., MCPClient`, so we follow this path.
try:
from smolagents import MCPClient
except ImportError:
# Fallback or mock if MCPClient is not yet in the installed version
# Assuming it's good as requested by user for now
MCPClient = None
class PlaygroundManager:
def __init__(self):
self.agent = None
self.tools = []
self.mcp_client = None
def load_mcp_tools(self, mcp_url: str):
"""Connects the MCP client to the given URL and loads tools."""
try:
# Cleanup old client
if self.mcp_client:
# self.mcp_client.disconnect() # If method exists
pass
# Initialize MCP Client
# User requested to ignore SSE mode and use streamable HTTP
# Clean URL if it still contains /sse by mistake
if mcp_url.endswith("/sse"):
mcp_url = mcp_url[:-4]
# Pass URL without forcing SSE transport, smolagents should handle it
# Note: Pass URL directly if possible, or in a dict depending on API
# structured_output=False to avoid FutureWarning and stay compatible
self.mcp_client = MCPClient({"url": mcp_url}, structured_output=False)
# Retrieve tools
self.tools = self.mcp_client.get_tools()
# Agent Configuration
# Use HF_TOKEN for inference model
token = os.environ.get("HF_TOKEN")
if not token:
return pd.DataFrame({"Error": ["HF_TOKEN env var is missing"]}), "Error: HF_TOKEN missing"
model = InferenceClientModel(token=token)
self.agent = CodeAgent(tools=self.tools, model=model)
# Create DataFrame for display
rows = []
for tool in self.tools:
# Simplified input handling for display
input_desc = str(tool.inputs) if hasattr(tool, 'inputs') else "N/A"
rows.append({
"Tool name": tool.name,
"Description": tool.description,
"Params": input_desc
})
df = pd.DataFrame(rows)
return df, f"Success! {len(self.tools)} tools loaded from {mcp_url}"
except Exception as e:
import traceback
traceback.print_exc()
return pd.DataFrame({"Error": [str(e)]}), f"Connection error: {str(e)}"
def chat(self, message: str, history: list):
"""Executes user message via agent capturing reflection."""
if not self.agent:
return "⚠️ Please load a valid MCP server first."
# Capture stdout (smolagents reflection logs)
f = io.StringIO()
try:
with redirect_stdout(f):
# Run smolagents agent
# Note: Real streaming of reflection would require deeper integration with smolagents
response = self.agent.run(message)
# Clean logs (remove ANSI colors that break Markdown)
raw_logs = f.getvalue()
clean_logs = remove_ansi_codes(raw_logs)
# Format response with cleaned reflection logs
if clean_logs:
formatted_response = f"**💭 Agent Reflection:**\n```text\n{clean_logs}\n```\n\n**✅ Response:**\n{str(response)}"
else:
formatted_response = str(response)
return formatted_response
except Exception as e:
raw_logs = f.getvalue()
clean_logs = remove_ansi_codes(raw_logs)
return f"Error executing agent: {str(e)}\n\nPartial logs:\n{clean_logs}"
# Singleton to manage playground state in Gradio instance
# Warning: In a real multi-user deployment, state should be managed by gr.State
playground = PlaygroundManager()
def get_playground_ui_handlers():
"""Returns wrapper functions for Gradio UI."""
def reload_tools(url):
return playground.load_mcp_tools(url)
def chat_response(message, history):
return playground.chat(message, history)
return reload_tools, chat_response
|