"""Vendor-Neutral Smolagents Fork - Main Application This is the main Gradio UI application that integrates CSV-driven agent tools. Designed to be vendor-neutral and work with various LLM backends. """ import gradio as gr import os import sys from pathlib import Path from dotenv import load_dotenv # Add smolagents to path sys.path.insert(0, str(Path(__file__).parent / 'smolagents')) try: from tools import CSVToolHandler, CSVDataHandler, register_csv_tools except ImportError as e: print(f"Warning: Could not import tools module: {e}") print("Some features may not be available.") CSVToolHandler = None CSVDataHandler = None register_csv_tools = None # Load environment variables load_dotenv() # Configuration CSV_TOOLS_PATH = os.getenv('CSV_TOOLS_PATH', './tools.csv') CSV_DATA_DIR = os.getenv('CSV_DATA_DIR', './data') AGENT_BACKEND = os.getenv('AGENT_BACKEND', 'huggingface') AGENT_MODEL_NAME = os.getenv('AGENT_MODEL_NAME', 'HuggingFaceH4/zephyr-7b-beta') # Initialize CSV tool handler tool_handler = None available_tools = [] if CSVToolHandler: try: tool_handler = CSVToolHandler(CSV_TOOLS_PATH) available_tools = tool_handler.get_tools() print(f"Initialized with {len(available_tools)} CSV tools") except Exception as e: print(f"Error initializing CSV tool handler: {e}") def process_query(query: str, tool_selection: str = None) -> str: """Process user query with optional tool selection. Args: query: User input query tool_selection: Optional tool to use Returns: Response string """ if not query or not query.strip(): return "Please enter a query." response_parts = [] response_parts.append(f"Query: {query}") response_parts.append(f"Backend: {AGENT_BACKEND}") response_parts.append(f"Model: {AGENT_MODEL_NAME}") if tool_selection and tool_selection != "None": response_parts.append(f"Selected Tool: {tool_selection}") if tool_handler: tool = tool_handler.get_tool_by_name(tool_selection) if tool: response_parts.append(f"Tool Description: {tool.get('description', 'N/A')}") # List available tools if available_tools: response_parts.append(f"\nAvailable Tools ({len(available_tools)}):") for tool in available_tools[:5]: # Show first 5 response_parts.append(f" - {tool.get('name', 'N/A')}: {tool.get('description', 'N/A')}") if len(available_tools) > 5: response_parts.append(f" ... and {len(available_tools) - 5} more") else: response_parts.append("\nNote: No CSV tools loaded. Add tools to tools.csv to enable tool support.") response_parts.append("\n---") response_parts.append("This is a vendor-neutral fork of Salesforce-Smolagents-AI.") response_parts.append("CSV tool integration is active. Full agent capabilities coming soon!") return "\n".join(response_parts) def list_tools() -> str: """List all available CSV tools.""" if not available_tools: return "No tools available. Please add tool definitions to tools.csv." tool_list = ["Available CSV Tools:"] tool_list.append("=" * 50) for i, tool in enumerate(available_tools, 1): tool_list.append(f"\n{i}. {tool.get('name', 'Unknown')}") tool_list.append(f" Description: {tool.get('description', 'N/A')}") tool_list.append(f" Function: {tool.get('function', 'N/A')}") tool_list.append(f" Parameters: {tool.get('parameters', 'N/A')}") return "\n".join(tool_list) def upload_csv_tools(file) -> str: """Upload and process a CSV tools file.""" if file is None: return "No file uploaded." try: # Read the uploaded file if CSVDataHandler: data = CSVDataHandler.read_csv(file.name) return f"Successfully uploaded CSV with {len(data)} rows.\n" + str(data[:5]) else: return "CSV tools module not available." except Exception as e: return f"Error processing CSV file: {str(e)}" # Create Gradio interface with gr.Blocks(title="Vendor-Neutral Smolagents Fork", theme=gr.themes.Soft()) as demo: gr.Markdown(""" # 🤖 Vendor-Neutral Smolagents Fork A vendor-neutral implementation of agent tools with CSV-driven configuration. Based on Salesforce-Smolagents-AI, designed for maximum flexibility and portability. ### Features: - 📊 CSV-based tool definitions - 🔧 Vendor-neutral LLM backend support - 🚀 Gradio UI for easy interaction - 🔌 Extensible architecture """) with gr.Tab("Agent Chat"): gr.Markdown("### Interact with the Agent") tool_names = ["None"] + [t.get('name', 'Unknown') for t in available_tools] with gr.Row(): query_input = gr.Textbox( label="Your Query", placeholder="Ask me anything or request a tool action...", lines=3 ) with gr.Row(): tool_dropdown = gr.Dropdown( choices=tool_names, label="Select Tool (Optional)", value="None" ) with gr.Row(): submit_btn = gr.Button("Submit", variant="primary") clear_btn = gr.Button("Clear") output = gr.Textbox( label="Response", lines=10, interactive=False ) submit_btn.click( fn=process_query, inputs=[query_input, tool_dropdown], outputs=output ) clear_btn.click( fn=lambda: ("", "None", ""), inputs=[], outputs=[query_input, tool_dropdown, output] ) with gr.Tab("Tool Management"): gr.Markdown("### CSV Tool Configuration") list_tools_btn = gr.Button("List Available Tools") tools_output = gr.Textbox( label="Tools", lines=15, interactive=False ) list_tools_btn.click( fn=list_tools, inputs=[], outputs=tools_output ) gr.Markdown("### Upload CSV Tools") gr.Markdown("Upload a CSV file with columns: name, description, function, parameters") csv_upload = gr.File( label="Upload CSV File", file_types=[".csv"] ) upload_output = gr.Textbox( label="Upload Status", lines=5, interactive=False ) csv_upload.change( fn=upload_csv_tools, inputs=csv_upload, outputs=upload_output ) with gr.Tab("Configuration"): gr.Markdown("### System Configuration") with gr.Row(): with gr.Column(): gr.Markdown(f"**Backend:** {AGENT_BACKEND}") gr.Markdown(f"**Model:** {AGENT_MODEL_NAME}") gr.Markdown(f"**CSV Tools Path:** {CSV_TOOLS_PATH}") gr.Markdown(f"**CSV Data Dir:** {CSV_DATA_DIR}") gr.Markdown(""" ### Setup Instructions 1. Copy `smolagents/.env.sample` to `smolagents/.env` 2. Configure your preferred LLM backend and API keys 3. Create a `tools.csv` file with your tool definitions 4. Use the Tool Management tab to verify your tools are loaded ### CSV Tools Format Your `tools.csv` should have these columns: - `name`: Unique tool name - `description`: What the tool does - `function`: Function identifier or code - `parameters`: Parameter specification (e.g., "query:str,limit:int") """) with gr.Tab("About"): gr.Markdown(""" ### About This Project This is a **vendor-neutral fork** of Salesforce's Smolagents-AI, designed to provide: - 🌐 **Vendor Neutrality**: Works with any LLM provider (OpenAI, Anthropic, HuggingFace, local models, etc.) - 📊 **CSV-Driven Configuration**: Easy tool management through CSV files - 🔧 **Extensibility**: Simple architecture for adding new capabilities - 🚀 **Production Ready**: Built with best practices and clean code ### Key Components - `smolagents/tools.py`: CSV tool handlers and registration - `smolagents/.env.sample`: Configuration template - `app.py`: Gradio UI (this file) - `requirements.txt`: Minimal dependencies ### Repository Structure ``` ├── smolagents/ │ ├── tools.py # CSV tool support │ └── .env.sample # Configuration template ├── app.py # Main Gradio application ├── requirements.txt # Dependencies ├── tools.csv # Tool definitions (create this) └── README.md # Documentation ``` ### Next Steps 1. Create your `tools.csv` file with tool definitions 2. Configure your `.env` file with API keys 3. Test the agent with your custom tools 4. Extend with additional capabilities as needed --- Built with ❤️ for the AI agent community """) # Launch the app if __name__ == "__main__": demo.launch( server_name=os.getenv('GRADIO_SERVER_HOST', '0.0.0.0'), server_port=int(os.getenv('GRADIO_SERVER_PORT', 7860)), share=False )