Spaces:
Sleeping
Sleeping
Commit ·
d53a51c
1
Parent(s): 8c90b3a
Added chatbot with agent for legislation
Browse files- app.py +1 -1
- requirements.txt +2 -1
- src/ui/interface.py +4 -1
- src/ui/tabs/__init__.py +2 -1
- src/ui/tabs/legislation_tab.py +99 -0
- src/utils/elevenlabs_agent.py +152 -0
app.py
CHANGED
|
@@ -6,7 +6,7 @@ Detects crop diseases with AI.
|
|
| 6 |
|
| 7 |
from src.ui import create_gradio_interface
|
| 8 |
from dotenv import load_dotenv
|
| 9 |
-
load_dotenv()
|
| 10 |
|
| 11 |
if __name__ == "__main__":
|
| 12 |
demo = create_gradio_interface()
|
|
|
|
| 6 |
|
| 7 |
from src.ui import create_gradio_interface
|
| 8 |
from dotenv import load_dotenv
|
| 9 |
+
load_dotenv()
|
| 10 |
|
| 11 |
if __name__ == "__main__":
|
| 12 |
demo = create_gradio_interface()
|
requirements.txt
CHANGED
|
@@ -3,4 +3,5 @@ transformers
|
|
| 3 |
torch
|
| 4 |
requests
|
| 5 |
openai
|
| 6 |
-
pillow
|
|
|
|
|
|
| 3 |
torch
|
| 4 |
requests
|
| 5 |
openai
|
| 6 |
+
pillow
|
| 7 |
+
elevenlabs
|
src/ui/interface.py
CHANGED
|
@@ -5,7 +5,7 @@ Assembles all tabs into the main application interface.
|
|
| 5 |
"""
|
| 6 |
|
| 7 |
import gradio as gr
|
| 8 |
-
from .tabs import create_leaf_tab, create_farm_tab, create_weather_tab
|
| 9 |
|
| 10 |
|
| 11 |
def create_gradio_interface() -> gr.Blocks:
|
|
@@ -31,6 +31,9 @@ def create_gradio_interface() -> gr.Blocks:
|
|
| 31 |
|
| 32 |
# Tab 3: Weather Alerts
|
| 33 |
create_weather_tab()
|
|
|
|
|
|
|
|
|
|
| 34 |
|
| 35 |
# ========== FOOTER ==========
|
| 36 |
gr.Markdown(
|
|
|
|
| 5 |
"""
|
| 6 |
|
| 7 |
import gradio as gr
|
| 8 |
+
from .tabs import create_leaf_tab, create_farm_tab, create_weather_tab, create_legislation_tab
|
| 9 |
|
| 10 |
|
| 11 |
def create_gradio_interface() -> gr.Blocks:
|
|
|
|
| 31 |
|
| 32 |
# Tab 3: Weather Alerts
|
| 33 |
create_weather_tab()
|
| 34 |
+
|
| 35 |
+
# Tab 4: EU Agricultural Legislation
|
| 36 |
+
create_legislation_tab()
|
| 37 |
|
| 38 |
# ========== FOOTER ==========
|
| 39 |
gr.Markdown(
|
src/ui/tabs/__init__.py
CHANGED
|
@@ -7,5 +7,6 @@ Individual tab components for the Gradio interface.
|
|
| 7 |
from .leaf_tab import create_leaf_tab
|
| 8 |
from .farm_tab import create_farm_tab
|
| 9 |
from .weather_tab import create_weather_tab
|
|
|
|
| 10 |
|
| 11 |
-
__all__ = ["create_leaf_tab", "create_farm_tab", "create_weather_tab"]
|
|
|
|
| 7 |
from .leaf_tab import create_leaf_tab
|
| 8 |
from .farm_tab import create_farm_tab
|
| 9 |
from .weather_tab import create_weather_tab
|
| 10 |
+
from .legislation_tab import create_legislation_tab
|
| 11 |
|
| 12 |
+
__all__ = ["create_leaf_tab", "create_farm_tab", "create_weather_tab", "create_legislation_tab"]
|
src/ui/tabs/legislation_tab.py
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
EU Agricultural Legislation Agent Tab
|
| 3 |
+
======================================
|
| 4 |
+
UI component for consulting with an AI agent specialized in EU agricultural legislation.
|
| 5 |
+
"""
|
| 6 |
+
|
| 7 |
+
import gradio as gr
|
| 8 |
+
from src.utils.elevenlabs_agent import chat_with_agent
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
def create_legislation_tab():
|
| 12 |
+
"""Create the EU legislation consultation tab with chat interface."""
|
| 13 |
+
|
| 14 |
+
with gr.Tab("⚖️ EU Agricultural Legislation"):
|
| 15 |
+
gr.Markdown(
|
| 16 |
+
"""
|
| 17 |
+
### 🇪🇺 Expert Agent in European Agricultural Legislation
|
| 18 |
+
|
| 19 |
+
Ask questions about regulations, policies, subsidies, and compliance requirements
|
| 20 |
+
for agriculture in the European Union.
|
| 21 |
+
|
| 22 |
+
**Examples:**
|
| 23 |
+
- What are the main requirements for organic certification in the EU?
|
| 24 |
+
- How does the Common Agricultural Policy (CAP) affect small farmers?
|
| 25 |
+
- What are the regulations for pesticide use in European agriculture?
|
| 26 |
+
"""
|
| 27 |
+
)
|
| 28 |
+
|
| 29 |
+
# Chat interface
|
| 30 |
+
chatbot = gr.Chatbot(
|
| 31 |
+
label="💬 Conversation with EU Legislation Expert",
|
| 32 |
+
height=500,
|
| 33 |
+
show_label=True,
|
| 34 |
+
avatar_images=(None, "🤖")
|
| 35 |
+
)
|
| 36 |
+
|
| 37 |
+
with gr.Row():
|
| 38 |
+
msg = gr.Textbox(
|
| 39 |
+
label="Your question",
|
| 40 |
+
placeholder="Ask about EU agricultural legislation...",
|
| 41 |
+
scale=4,
|
| 42 |
+
show_label=False
|
| 43 |
+
)
|
| 44 |
+
submit_btn = gr.Button("Send", variant="primary", scale=1)
|
| 45 |
+
|
| 46 |
+
with gr.Row():
|
| 47 |
+
clear_btn = gr.Button("🗑️ Clear conversation", size="sm")
|
| 48 |
+
|
| 49 |
+
# Function to handle user message
|
| 50 |
+
def user_message(message, history):
|
| 51 |
+
"""Add user message to chat history."""
|
| 52 |
+
if not message.strip():
|
| 53 |
+
return "", history
|
| 54 |
+
return "", history + [[message, None]]
|
| 55 |
+
|
| 56 |
+
# Function to get bot response
|
| 57 |
+
def bot_response(history):
|
| 58 |
+
"""Get response from ElevenLabs agent."""
|
| 59 |
+
if not history or history[-1][1] is not None:
|
| 60 |
+
return history
|
| 61 |
+
|
| 62 |
+
user_msg = history[-1][0]
|
| 63 |
+
response = chat_with_agent(user_msg)
|
| 64 |
+
|
| 65 |
+
history[-1][1] = response
|
| 66 |
+
return history
|
| 67 |
+
|
| 68 |
+
# Function to clear chat
|
| 69 |
+
def clear_chat():
|
| 70 |
+
"""Clear the chat history."""
|
| 71 |
+
return []
|
| 72 |
+
|
| 73 |
+
# Connect events
|
| 74 |
+
msg.submit(
|
| 75 |
+
fn=user_message,
|
| 76 |
+
inputs=[msg, chatbot],
|
| 77 |
+
outputs=[msg, chatbot],
|
| 78 |
+
queue=False
|
| 79 |
+
).then(
|
| 80 |
+
fn=bot_response,
|
| 81 |
+
inputs=[chatbot],
|
| 82 |
+
outputs=[chatbot]
|
| 83 |
+
)
|
| 84 |
+
|
| 85 |
+
submit_btn.click(
|
| 86 |
+
fn=user_message,
|
| 87 |
+
inputs=[msg, chatbot],
|
| 88 |
+
outputs=[msg, chatbot],
|
| 89 |
+
queue=False
|
| 90 |
+
).then(
|
| 91 |
+
fn=bot_response,
|
| 92 |
+
inputs=[chatbot],
|
| 93 |
+
outputs=[chatbot]
|
| 94 |
+
)
|
| 95 |
+
|
| 96 |
+
clear_btn.click(
|
| 97 |
+
fn=clear_chat,
|
| 98 |
+
outputs=[chatbot]
|
| 99 |
+
)
|
src/utils/elevenlabs_agent.py
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
ElevenLabs Conversational AI Agent Integration
|
| 3 |
+
================================================
|
| 4 |
+
Module for interacting with ElevenLabs conversational AI agents.
|
| 5 |
+
"""
|
| 6 |
+
|
| 7 |
+
import os
|
| 8 |
+
from dotenv import load_dotenv
|
| 9 |
+
from elevenlabs.client import ElevenLabs
|
| 10 |
+
from elevenlabs.conversational_ai.conversation import Conversation
|
| 11 |
+
|
| 12 |
+
# Load environment variables from .env file
|
| 13 |
+
load_dotenv()
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
# =============================================================================
|
| 17 |
+
# CONFIGURATION - Update these values with your ElevenLabs agent settings
|
| 18 |
+
# =============================================================================
|
| 19 |
+
|
| 20 |
+
# Your ElevenLabs API key (stored in .env file)
|
| 21 |
+
ELEVENLABS_API_KEY = os.getenv("ELEVENLABS_API_KEY")
|
| 22 |
+
|
| 23 |
+
# Agent ID - Replace with your agent's ID from ElevenLabs dashboard
|
| 24 |
+
AGENT_ID = os.getenv("ELEVENLABS_AGENT_ID", "your-agent-id-here")
|
| 25 |
+
|
| 26 |
+
# Optional: Custom configuration for the agent
|
| 27 |
+
AGENT_CONFIG = {
|
| 28 |
+
# Add any custom configuration here if needed
|
| 29 |
+
# Example: language, voice settings, etc.
|
| 30 |
+
}
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
# =============================================================================
|
| 34 |
+
# Agent Interaction
|
| 35 |
+
# =============================================================================
|
| 36 |
+
|
| 37 |
+
class EULegislationAgent:
|
| 38 |
+
"""Wrapper class for ElevenLabs conversational agent."""
|
| 39 |
+
|
| 40 |
+
def __init__(self):
|
| 41 |
+
"""Initialize the ElevenLabs client and conversation."""
|
| 42 |
+
if not ELEVENLABS_API_KEY:
|
| 43 |
+
raise ValueError(
|
| 44 |
+
"ELEVENLABS_API_KEY not found. Please add it to your .env file:\n"
|
| 45 |
+
"ELEVENLABS_API_KEY=your_api_key_here"
|
| 46 |
+
)
|
| 47 |
+
|
| 48 |
+
self.client = ElevenLabs(api_key=ELEVENLABS_API_KEY)
|
| 49 |
+
self.conversation = None
|
| 50 |
+
|
| 51 |
+
def start_conversation(self):
|
| 52 |
+
"""Start or restart a conversation with the agent."""
|
| 53 |
+
try:
|
| 54 |
+
self.conversation = Conversation(
|
| 55 |
+
client=self.client,
|
| 56 |
+
agent_id=AGENT_ID,
|
| 57 |
+
# Add any additional configuration here
|
| 58 |
+
**AGENT_CONFIG
|
| 59 |
+
)
|
| 60 |
+
return True
|
| 61 |
+
except Exception as e:
|
| 62 |
+
print(f"Error starting conversation: {e}")
|
| 63 |
+
return False
|
| 64 |
+
|
| 65 |
+
def send_message(self, message: str) -> str:
|
| 66 |
+
"""
|
| 67 |
+
Send a message to the agent and get a response.
|
| 68 |
+
|
| 69 |
+
Args:
|
| 70 |
+
message: User's question or message
|
| 71 |
+
|
| 72 |
+
Returns:
|
| 73 |
+
str: Agent's response
|
| 74 |
+
"""
|
| 75 |
+
try:
|
| 76 |
+
# Start conversation if not already started
|
| 77 |
+
if self.conversation is None:
|
| 78 |
+
if not self.start_conversation():
|
| 79 |
+
return "❌ Error: Could not connect to the agent. Please check your API key and Agent ID."
|
| 80 |
+
|
| 81 |
+
# Send message and get response
|
| 82 |
+
response = self.conversation.send(message)
|
| 83 |
+
|
| 84 |
+
# Extract text from response
|
| 85 |
+
if hasattr(response, 'text'):
|
| 86 |
+
return response.text
|
| 87 |
+
elif isinstance(response, dict) and 'text' in response:
|
| 88 |
+
return response['text']
|
| 89 |
+
else:
|
| 90 |
+
return str(response)
|
| 91 |
+
|
| 92 |
+
except Exception as e:
|
| 93 |
+
error_msg = str(e)
|
| 94 |
+
|
| 95 |
+
# Provide helpful error messages
|
| 96 |
+
if "agent_id" in error_msg.lower() or "not found" in error_msg.lower():
|
| 97 |
+
return (
|
| 98 |
+
"❌ Error: Agent not found. Please verify your ELEVENLABS_AGENT_ID "
|
| 99 |
+
"in the .env file or in src/utils/elevenlabs_agent.py"
|
| 100 |
+
)
|
| 101 |
+
elif "api key" in error_msg.lower() or "unauthorized" in error_msg.lower():
|
| 102 |
+
return (
|
| 103 |
+
"❌ Error: Invalid API key. Please check your ELEVENLABS_API_KEY "
|
| 104 |
+
"in the .env file."
|
| 105 |
+
)
|
| 106 |
+
else:
|
| 107 |
+
return f"❌ Error communicating with agent: {error_msg}"
|
| 108 |
+
|
| 109 |
+
def end_conversation(self):
|
| 110 |
+
"""End the current conversation."""
|
| 111 |
+
if self.conversation:
|
| 112 |
+
try:
|
| 113 |
+
self.conversation.end()
|
| 114 |
+
except:
|
| 115 |
+
pass
|
| 116 |
+
self.conversation = None
|
| 117 |
+
|
| 118 |
+
|
| 119 |
+
# Global agent instance
|
| 120 |
+
_agent = None
|
| 121 |
+
|
| 122 |
+
|
| 123 |
+
def get_agent():
|
| 124 |
+
"""Get or create the global agent instance."""
|
| 125 |
+
global _agent
|
| 126 |
+
if _agent is None:
|
| 127 |
+
_agent = EULegislationAgent()
|
| 128 |
+
return _agent
|
| 129 |
+
|
| 130 |
+
|
| 131 |
+
def chat_with_agent(message: str) -> str:
|
| 132 |
+
"""
|
| 133 |
+
Send a message to the EU Legislation agent and get a response.
|
| 134 |
+
|
| 135 |
+
This is the main function to be called from the UI.
|
| 136 |
+
|
| 137 |
+
Args:
|
| 138 |
+
message: User's question about EU agricultural legislation
|
| 139 |
+
|
| 140 |
+
Returns:
|
| 141 |
+
str: Agent's response
|
| 142 |
+
"""
|
| 143 |
+
agent = get_agent()
|
| 144 |
+
return agent.send_message(message)
|
| 145 |
+
|
| 146 |
+
|
| 147 |
+
def reset_conversation():
|
| 148 |
+
"""Reset the conversation with the agent."""
|
| 149 |
+
global _agent
|
| 150 |
+
if _agent:
|
| 151 |
+
_agent.end_conversation()
|
| 152 |
+
_agent = None
|