File size: 9,793 Bytes
824cdbc
 
 
 
 
 
413e679
824cdbc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
413e679
824cdbc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
413e679
824cdbc
 
 
 
 
 
 
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
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
"""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
    )