Spaces:
Sleeping
Sleeping
File size: 5,443 Bytes
80654a3 7b7d3f1 80654a3 047bb2e 80654a3 169fb9d 80654a3 169fb9d 50cc36f 169fb9d 50cc36f 169fb9d 50cc36f b966ce1 169fb9d 80654a3 50cc36f |
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 |
import os, datetime, math, numexpr, logging, requests, uuid
import gradio as gr
from langchain_google_genai import ChatGoogleGenerativeAI
from langchain_google_genai import GoogleGenerativeAIEmbeddings
from langchain_core.documents import Document
from langchain.agents import AgentExecutor, create_tool_calling_agent
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain.chains import create_retrieval_chain
from langchain_core.tools import StructuredTool
from langchain_core.messages import SystemMessage, HumanMessage
from langchain.prompts import PromptTemplate, HumanMessagePromptTemplate, ChatPromptTemplate, SystemMessagePromptTemplate
from langchain_community.vectorstores import FAISS
# === SETUP ===
GOOGLE_API_KEY = os.environ.get("GOOGLE_API_KEY")
# === LLM ===
llm = ChatGoogleGenerativeAI(model="gemini-2.0-flash")
# === TOOLS ===
def dani_drinks() -> str:
"""Dani's favorite drinks info on beers, wine and water."""
return (
"Dani's favourite drinks:\n"
"Beers: Peroni (better if 33cl), Moretti, Ichnusa (unfiltered)\n"
"Wine: Red fruity, White cold only, No Rosè\n"
"Water: Normal or sparkling, only cold\n"
)
def calculator(expression: str) -> str:
"""Math calculations."""
local_dict = {"pi": math.pi, "e": math.e}
result = str(numexpr.evaluate(expression.strip(), local_dict=local_dict))
return result
# Nuovo Weather Tool
def weather_tool(location: str) -> str:
"""Return current weather for the given city name using Open‑Meteo APIs."""
# 1. Geocoding: city → lat, lon
geocode = requests.get(
"https://geocoding-api.open-meteo.com/v1/search",
params={"name": location, "count": 1}
)
geo_json = geocode.json()
if not geo_json.get("results"):
return f"Non ho trovato la città '{location}'. Riprova."
first = geo_json["results"][0]
lat = first["latitude"]
lon = first["longitude"]
name = first.get("name")
country = first.get("country", "")
# 2. Current weather
weather_resp = requests.get(
"https://api.open-meteo.com/v1/forecast",
params={
"latitude": lat,
"longitude": lon,
"current_weather": True,
"timezone": "auto"
}
)
w = weather_resp.json().get("current_weather")
if not w:
return f"Meteo non disponibile per {location}."
temp = w.get("temperature")
wind = w.get("windspeed")
return (f"Meteo attuale a {name}, {country}: {temp}°C, vento {wind} km/h")
# === RETRIEVAL TOOL VIA FAISS ===
# create mock docs and embed
docs = [
Document(page_content="Milan was founded in 1900."),
Document(page_content="Inter was founded in 1950."),
Document(page_content="Juve was founded in 1920."),
Document(page_content="Torino was founded in 1910."),
]
embeddings = GoogleGenerativeAIEmbeddings(model="models/text-embedding-004")
vector_db = FAISS.from_documents(docs, embeddings)
retriever = vector_db.as_retriever()
rag_prompt = PromptTemplate.from_template(
"Answer the questions using ONLY the documents.\nQuestion: {input}\n\nDocuments:\n{context}"
)
doc_chain = create_stuff_documents_chain(llm, rag_prompt)
rag_chain = create_retrieval_chain(retriever, doc_chain)
def retrieval_tool(query: str) -> str:
"""Answer questions about italian soccer teams"""
result = rag_chain.invoke(
{"input": query},
)
return result["answer"]
tools = [
StructuredTool.from_function(dani_drinks),
StructuredTool.from_function(calculator),
StructuredTool.from_function(weather_tool),
StructuredTool.from_function(retrieval_tool)
]
# === AGENT ===
system_prompt = SystemMessagePromptTemplate.from_template(
"You are DaniBot, an agent that can answer math questions, tell info about Dani's favorite drinks and tell the weather in a city."
"You can also answer questions about italian soccer teams "
"Dani is your boss. Use the tools if needed. Answer with an Italian accent! "
"You can also answer general base knowledge questions if you know the answer"
"If the user seems wanting to quit, thank him/her and say 'SUCA!'"
)
human_prompt = HumanMessagePromptTemplate.from_template("{input}\n{agent_scratchpad}")
chat_prompt = ChatPromptTemplate.from_messages([system_prompt, human_prompt])
# === AGENT ===
raw_agent = create_tool_calling_agent(llm, tools, chat_prompt)
agent_executor = AgentExecutor(
agent=raw_agent,
tools=tools,
verbose=False
)
# === GRADIO INTERFACCIA + window ===
def chat_fn(message, history):
session_id = str(uuid.uuid4())
result = agent_executor.invoke(
{"input": message},
config={"configurable": {"session_id": session_id}}
)
return result["output"]
with gr.Blocks() as demo:
gr.Markdown(
"""
# DaniBot 🤖
Questo chatbot può rispondere sui drinks di Dani, ma anche a domande di matematica, informazioni sulle squadre di calcio italiane,
il meteo, e altro ancora. Usa dei tools integrati per darti risposte più accurate.
Scrivi un messaggio per iniziare la chat!
Scrivi 'q' o 'quit' per terminare la chat!
"""
)
chatbot = gr.ChatInterface(
fn=chat_fn,
examples=["Quando è stata fondata la Juventus?"],
title="DaniBot - ask me something!",
type="messages"
)
if __name__ == "__main__":
demo.launch() |