Spaces:
Sleeping
Sleeping
Commit
·
4a8958c
1
Parent(s):
1df19b1
first commit
Browse files- .github/workflows/cicd.yml +20 -0
- .gitignore +2 -0
- node.py +116 -0
- pdf_agent.py +102 -0
- requirements.txt +15 -3
- src/streamlit_app.py +90 -33
- weather_agent.py +62 -0
.github/workflows/cicd.yml
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
name: Sync to Hugging Face hub
|
2 |
+
on:
|
3 |
+
push:
|
4 |
+
branches: [main]
|
5 |
+
|
6 |
+
# to run this workflow manually from the Actions tab
|
7 |
+
workflow_dispatch:
|
8 |
+
|
9 |
+
jobs:
|
10 |
+
sync-to-hub:
|
11 |
+
runs-on: ubuntu-latest
|
12 |
+
steps:
|
13 |
+
- uses: actions/checkout@v3
|
14 |
+
with:
|
15 |
+
fetch-depth: 0
|
16 |
+
lfs: true
|
17 |
+
- name: Push to hub
|
18 |
+
env:
|
19 |
+
HF_TOKEN: ${{ secrets.HF_TOKEN }}
|
20 |
+
run: git push --force https://Sharath1036:$HF_TOKEN@huggingface.co/spaces/Sharath1036/langchain-multi-agents main
|
.gitignore
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
1 |
+
venv/*
|
2 |
+
.env
|
node.py
ADDED
@@ -0,0 +1,116 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from typing import List, Literal
|
2 |
+
from langchain_core.messages import BaseMessage, HumanMessage
|
3 |
+
from langgraph.prebuilt import create_react_agent
|
4 |
+
from langgraph.graph import MessagesState, END
|
5 |
+
from langgraph.types import Command
|
6 |
+
from weather_agent import WeatherAgent
|
7 |
+
from pdf_agent import PDFAgent
|
8 |
+
from langgraph.graph import StateGraph, START
|
9 |
+
from IPython.display import Image, display
|
10 |
+
import re
|
11 |
+
|
12 |
+
def split_questions(user_message: str) -> List[str]:
|
13 |
+
# Naive split on ' and ', ' then ', case insensitive
|
14 |
+
parts = re.split(r'\band then\b|\band\b|\bthen\b', user_message, flags=re.IGNORECASE)
|
15 |
+
return [part.strip() for part in parts if part.strip()]
|
16 |
+
|
17 |
+
def classify_question(question: str) -> Literal["pdf_agent", "weather_agent"]:
|
18 |
+
# Simple keyword-based classification
|
19 |
+
if re.search(r'\bweather\b', question, re.IGNORECASE):
|
20 |
+
return "weather_agent"
|
21 |
+
else:
|
22 |
+
return "pdf_agent"
|
23 |
+
|
24 |
+
def pdf_agent_node(state: MessagesState) -> Command[Literal["weather_agent", END]]:
|
25 |
+
pdf_agent = PDFAgent(pdf_path="Sharath_OnePage.pdf")
|
26 |
+
user_message = None
|
27 |
+
for message in reversed(state["messages"]):
|
28 |
+
if isinstance(message, HumanMessage):
|
29 |
+
user_message = message.content
|
30 |
+
break
|
31 |
+
if user_message is None:
|
32 |
+
raise ValueError("No user message found in state.")
|
33 |
+
|
34 |
+
result = pdf_agent.agent.invoke({"input": user_message})
|
35 |
+
# Extract string from result
|
36 |
+
if isinstance(result, dict):
|
37 |
+
# Try common keys
|
38 |
+
text_result = result.get("output") or result.get("text") or str(result)
|
39 |
+
else:
|
40 |
+
text_result = str(result)
|
41 |
+
|
42 |
+
final_msg = HumanMessage(content=text_result, name="pdf_agent")
|
43 |
+
goto = get_next_node(final_msg, "weather_agent")
|
44 |
+
return Command(
|
45 |
+
update={"messages": state["messages"] + [final_msg]},
|
46 |
+
goto=goto,
|
47 |
+
)
|
48 |
+
|
49 |
+
def weather_agent_node(state: MessagesState) -> Command[Literal["pdf_agent", END]]:
|
50 |
+
weather_agent = WeatherAgent()
|
51 |
+
user_message = None
|
52 |
+
for message in reversed(state["messages"]):
|
53 |
+
if isinstance(message, HumanMessage):
|
54 |
+
user_message = message.content
|
55 |
+
break
|
56 |
+
if user_message is None:
|
57 |
+
raise ValueError("No user message found in state.")
|
58 |
+
|
59 |
+
match = re.search(r"weather in ([\w\s,]+)", user_message, re.IGNORECASE)
|
60 |
+
location = match.group(1).strip() if match else user_message
|
61 |
+
result = weather_agent.ask(location)
|
62 |
+
final_msg = HumanMessage(content=result, name="weather_agent")
|
63 |
+
goto = get_next_node(final_msg, "pdf_agent")
|
64 |
+
return Command(
|
65 |
+
update={"messages": state["messages"] + [final_msg]},
|
66 |
+
goto=goto,
|
67 |
+
)
|
68 |
+
|
69 |
+
def get_next_node(last_message: BaseMessage, goto: str):
|
70 |
+
if "FINAL ANSWER" in last_message.content:
|
71 |
+
return END
|
72 |
+
return goto
|
73 |
+
|
74 |
+
def build_graph():
|
75 |
+
workflow = StateGraph(MessagesState)
|
76 |
+
workflow.add_node("pdf_agent", pdf_agent_node)
|
77 |
+
workflow.add_node("weather_agent", weather_agent_node)
|
78 |
+
|
79 |
+
workflow.add_edge(START, "pdf_agent")
|
80 |
+
workflow.add_edge("pdf_agent", "weather_agent")
|
81 |
+
workflow.add_edge("weather_agent", END)
|
82 |
+
|
83 |
+
graph = workflow.compile()
|
84 |
+
return graph
|
85 |
+
|
86 |
+
if __name__ == "__main__":
|
87 |
+
graph = build_graph()
|
88 |
+
display(Image(graph.get_graph().draw_mermaid_png()))
|
89 |
+
|
90 |
+
# Full user input with multiple questions
|
91 |
+
user_input = "What organizations has Sharath worked for and tell me the weather in Mumbai"
|
92 |
+
|
93 |
+
# Split into sub-questions
|
94 |
+
questions = split_questions(user_input)
|
95 |
+
|
96 |
+
# Prepare empty message list to accumulate conversation
|
97 |
+
messages = []
|
98 |
+
|
99 |
+
# Process each question routed to the correct agent node
|
100 |
+
for question in questions:
|
101 |
+
agent_name = classify_question(question)
|
102 |
+
# Run the corresponding node manually with current messages + new question
|
103 |
+
state = {"messages": messages + [HumanMessage(content=question)]}
|
104 |
+
if agent_name == "pdf_agent":
|
105 |
+
cmd = pdf_agent_node(state)
|
106 |
+
else:
|
107 |
+
cmd = weather_agent_node(state)
|
108 |
+
|
109 |
+
# Update messages with agent response
|
110 |
+
messages = cmd.update["messages"]
|
111 |
+
|
112 |
+
# Print all agent responses
|
113 |
+
for msg in messages:
|
114 |
+
if not isinstance(msg, HumanMessage):
|
115 |
+
continue
|
116 |
+
print(f"{msg.name or 'user'}: {msg.content}")
|
pdf_agent.py
ADDED
@@ -0,0 +1,102 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
from dotenv import load_dotenv
|
3 |
+
from langchain.agents import AgentType, Tool, initialize_agent
|
4 |
+
from langchain_community.agent_toolkits.load_tools import load_tools
|
5 |
+
from langchain.chains import RetrievalQA
|
6 |
+
from langchain_google_genai import GoogleGenerativeAIEmbeddings
|
7 |
+
from langchain_google_genai import ChatGoogleGenerativeAI
|
8 |
+
from langchain.text_splitter import CharacterTextSplitter
|
9 |
+
from langchain_qdrant import QdrantVectorStore
|
10 |
+
from qdrant_client import QdrantClient
|
11 |
+
from langchain_community.document_loaders import PyPDFLoader
|
12 |
+
|
13 |
+
|
14 |
+
class PDFAgent:
|
15 |
+
def __init__(self, pdf_path: str, collection_name: str = "test"):
|
16 |
+
self.pdf_path = pdf_path
|
17 |
+
self.collection_name = collection_name
|
18 |
+
self._load_environment()
|
19 |
+
self.llm = self._initialize_llm()
|
20 |
+
self.embeddings = self._initialize_embeddings()
|
21 |
+
self.vector_store = self._initialize_vector_store()
|
22 |
+
self.qa_chain = self._initialize_qa_chain()
|
23 |
+
self.tools = self._initialize_tools()
|
24 |
+
self.agent = self._initialize_agent()
|
25 |
+
|
26 |
+
def _load_environment(self):
|
27 |
+
load_dotenv(override=True)
|
28 |
+
os.environ["GOOGLE_API_KEY"] = os.getenv("GOOGLE_API_KEY")
|
29 |
+
os.environ["QDRANT_API_KEY"] = os.getenv("QDRANT_API_KEY")
|
30 |
+
os.environ["QDRANT_URL"] = os.getenv("QDRANT_URL")
|
31 |
+
os.environ["LANGSMITH_TRACING"]= "true"
|
32 |
+
os.environ["LANGSMITH_API_KEY"] = os.getenv("LANGSMITH_API_KEY")
|
33 |
+
|
34 |
+
def _initialize_llm(self):
|
35 |
+
return ChatGoogleGenerativeAI(
|
36 |
+
model="gemini-2.5-flash",
|
37 |
+
api_key=os.getenv("GOOGLE_API_KEY"),
|
38 |
+
temperature=0.0,
|
39 |
+
)
|
40 |
+
|
41 |
+
def _initialize_embeddings(self):
|
42 |
+
return GoogleGenerativeAIEmbeddings(model="gemini-embedding-001")
|
43 |
+
|
44 |
+
def _initialize_vector_store(self):
|
45 |
+
loader = PyPDFLoader(self.pdf_path)
|
46 |
+
documents = loader.load()
|
47 |
+
|
48 |
+
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
|
49 |
+
split_texts = text_splitter.split_documents(documents)
|
50 |
+
|
51 |
+
return QdrantVectorStore.from_documents(
|
52 |
+
documents=split_texts,
|
53 |
+
embedding=self.embeddings,
|
54 |
+
collection_name=self.collection_name,
|
55 |
+
api_key=os.getenv("QDRANT_API_KEY"),
|
56 |
+
url=os.getenv("QDRANT_URL"),
|
57 |
+
force_recreate=True
|
58 |
+
)
|
59 |
+
|
60 |
+
def _initialize_qa_chain(self):
|
61 |
+
return RetrievalQA.from_chain_type(
|
62 |
+
llm=self.llm,
|
63 |
+
chain_type="stuff",
|
64 |
+
retriever=self.vector_store.as_retriever()
|
65 |
+
)
|
66 |
+
|
67 |
+
def _initialize_tools(self):
|
68 |
+
tools = load_tools([], llm=self.llm)
|
69 |
+
tools.append(
|
70 |
+
Tool(
|
71 |
+
name="State of Union QA System",
|
72 |
+
func=self.qa_chain.run,
|
73 |
+
description=(
|
74 |
+
"Useful for answering questions from the uploaded PDF. "
|
75 |
+
"Input should be a fully formed question."
|
76 |
+
),
|
77 |
+
)
|
78 |
+
)
|
79 |
+
return tools
|
80 |
+
|
81 |
+
def _initialize_agent(self):
|
82 |
+
return initialize_agent(
|
83 |
+
self.tools,
|
84 |
+
self.llm,
|
85 |
+
agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
|
86 |
+
verbose=True,
|
87 |
+
)
|
88 |
+
|
89 |
+
def ask(self, question: str):
|
90 |
+
print("Asking:", question)
|
91 |
+
result = self.agent.run(question)
|
92 |
+
print("Result:", result)
|
93 |
+
return result
|
94 |
+
|
95 |
+
|
96 |
+
|
97 |
+
if __name__ == "__main__":
|
98 |
+
print("Starting PDF Agent...")
|
99 |
+
pdf_agent = PDFAgent(pdf_path="Sharath_OnePage.pdf")
|
100 |
+
print("Agent initialized.")
|
101 |
+
response = pdf_agent.ask("What all organizations has Sharath worked with?")
|
102 |
+
print("Response:", response)
|
requirements.txt
CHANGED
@@ -1,3 +1,15 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
langchain
|
2 |
+
langchain-community
|
3 |
+
langchain-openai
|
4 |
+
langgraph
|
5 |
+
pyowm
|
6 |
+
python-dotenv
|
7 |
+
pypdf
|
8 |
+
langchain-qdrant
|
9 |
+
qdrant-client
|
10 |
+
requests
|
11 |
+
ipython
|
12 |
+
langsmith
|
13 |
+
openai
|
14 |
+
streamlit
|
15 |
+
langchain_google_genai
|
src/streamlit_app.py
CHANGED
@@ -1,40 +1,97 @@
|
|
1 |
-
import
|
2 |
-
import numpy as np
|
3 |
-
import pandas as pd
|
4 |
import streamlit as st
|
|
|
|
|
|
|
5 |
|
6 |
-
|
7 |
-
|
|
|
|
|
|
|
8 |
|
9 |
-
|
10 |
-
|
11 |
-
forums](https://discuss.streamlit.io).
|
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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import asyncio
|
|
|
|
|
2 |
import streamlit as st
|
3 |
+
import tempfile
|
4 |
+
from pdf_agent import PDFAgent
|
5 |
+
from weather_agent import WeatherAgent
|
6 |
|
7 |
+
# Ensure an event loop exists for async libraries (fix for Google Generative AI Embeddings)
|
8 |
+
try:
|
9 |
+
asyncio.get_event_loop()
|
10 |
+
except RuntimeError:
|
11 |
+
asyncio.set_event_loop(asyncio.new_event_loop())
|
12 |
|
13 |
+
st.set_page_config(page_title="LangGraph Agents Demo", layout="wide")
|
14 |
+
st.title("LangGraph Agents Demo")
|
|
|
15 |
|
16 |
+
tab1, tab2, tab3 = st.tabs(["PDF Agent", "Weather Agent", "Multi-Agent QA"])
|
|
|
17 |
|
18 |
+
with tab1:
|
19 |
+
st.header("PDF Agent")
|
20 |
+
uploaded_pdf = st.file_uploader("Upload a PDF", type=["pdf"])
|
21 |
+
question = st.text_input("Ask a question about the PDF:")
|
22 |
+
if uploaded_pdf and question:
|
23 |
+
with tempfile.NamedTemporaryFile(delete=False, suffix=".pdf") as tmp_file:
|
24 |
+
tmp_file.write(uploaded_pdf.read())
|
25 |
+
tmp_path = tmp_file.name
|
26 |
+
pdf_agent = PDFAgent(pdf_path=tmp_path)
|
27 |
+
with st.spinner("Processing..."):
|
28 |
+
answer = pdf_agent.ask(question)
|
29 |
+
st.success("Answer:")
|
30 |
+
st.write(answer)
|
31 |
|
32 |
+
with tab2:
|
33 |
+
st.header("Weather Agent")
|
34 |
+
location = st.text_input("Enter a location for weather info: e.g. Mumbai")
|
35 |
+
if location:
|
36 |
+
weather_agent = WeatherAgent()
|
37 |
+
with st.spinner("Fetching weather..."):
|
38 |
+
try:
|
39 |
+
result = weather_agent.ask(location)
|
40 |
+
st.success("Weather Info:")
|
41 |
+
st.write(result) # This might be None or a dict
|
42 |
+
# Try to extract the answer if it's a dict or object
|
43 |
+
# if isinstance(result, dict):
|
44 |
+
# # Try common keys
|
45 |
+
# if "output" in result:
|
46 |
+
# st.write(result["output"])
|
47 |
+
# elif "result" in result:
|
48 |
+
# st.write(result["result"])
|
49 |
+
# else:
|
50 |
+
# st.write(str(result))
|
51 |
+
# elif hasattr(result, "content"):
|
52 |
+
# st.write(result.content)
|
53 |
+
# elif result is not None:
|
54 |
+
# st.write(str(result))
|
55 |
+
except Exception as e:
|
56 |
+
st.error(f"Error: {e}")
|
57 |
|
58 |
+
with tab3:
|
59 |
+
st.header("Multi-Agent QA (PDF + Weather)")
|
60 |
+
user_input = st.text_area("Ask multiple questions (e.g. 'What organizations has Sharath worked for and tell me the weather in Mumbai'):")
|
61 |
+
uploaded_pdf = st.file_uploader("Upload a PDF for PDF Agent (optional)", type=["pdf"], key="multi_pdf")
|
62 |
+
if st.button("Ask Multi-Agent"):
|
63 |
+
from node import split_questions, classify_question
|
64 |
+
from langchain_core.messages import HumanMessage
|
65 |
+
import tempfile
|
66 |
+
messages = []
|
67 |
+
# If PDF uploaded, save and use it
|
68 |
+
pdf_path = None
|
69 |
+
if uploaded_pdf:
|
70 |
+
with tempfile.NamedTemporaryFile(delete=False, suffix=".pdf") as tmp_file:
|
71 |
+
tmp_file.write(uploaded_pdf.read())
|
72 |
+
pdf_path = tmp_file.name
|
73 |
+
# Split and process each question
|
74 |
+
questions = split_questions(user_input)
|
75 |
+
for question in questions:
|
76 |
+
agent_name = classify_question(question)
|
77 |
+
if agent_name == "pdf_agent":
|
78 |
+
if pdf_path:
|
79 |
+
pdf_agent = PDFAgent(pdf_path=pdf_path)
|
80 |
+
else:
|
81 |
+
pdf_agent = PDFAgent(pdf_path="Sharath_OnePage.pdf")
|
82 |
+
result = pdf_agent.agent.invoke({"input": question})
|
83 |
+
if isinstance(result, dict):
|
84 |
+
text_result = result.get("output") or result.get("text") or str(result)
|
85 |
+
else:
|
86 |
+
text_result = str(result)
|
87 |
+
messages.append(("PDF Agent", text_result))
|
88 |
+
else:
|
89 |
+
weather_agent = WeatherAgent()
|
90 |
+
import re
|
91 |
+
match = re.search(r"weather in ([\w\s,]+)", question, re.IGNORECASE)
|
92 |
+
location = match.group(1).strip() if match else question
|
93 |
+
result = weather_agent.ask(location)
|
94 |
+
messages.append(("Weather Agent", str(result)))
|
95 |
+
st.subheader("Results:")
|
96 |
+
for agent, answer in messages:
|
97 |
+
st.markdown(f"**{agent}:** {answer}")
|
weather_agent.py
ADDED
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
from langchain_community.utilities import OpenWeatherMapAPIWrapper
|
3 |
+
from dotenv import load_dotenv
|
4 |
+
from langchain_google_genai import ChatGoogleGenerativeAI
|
5 |
+
from langchain.agents import AgentType, Tool, initialize_agent
|
6 |
+
|
7 |
+
class WeatherAgent:
|
8 |
+
def __init__(self):
|
9 |
+
self._load_environment()
|
10 |
+
self.weather_tool = self._initialize_weather_tool()
|
11 |
+
self.llm = self._initialize_llm()
|
12 |
+
self.tools = self._initialize_tools()
|
13 |
+
self.agent = self._initialize_agent()
|
14 |
+
|
15 |
+
def _load_environment(self):
|
16 |
+
load_dotenv(override=True)
|
17 |
+
os.environ["GOOGLE_API_KEY"] = os.getenv("GOOGLE_API_KEY")
|
18 |
+
os.environ["OPENWEATHERMAP_API_KEY"] = os.getenv("OPENWEATHERMAP_API_KEY")
|
19 |
+
os.environ["LANGSMITH_TRACING"]= "true"
|
20 |
+
os.environ["LANGSMITH_API_KEY"] = os.getenv("LANGSMITH_API_KEY")
|
21 |
+
|
22 |
+
def _initialize_weather_tool(self):
|
23 |
+
return OpenWeatherMapAPIWrapper()
|
24 |
+
|
25 |
+
def _initialize_llm(self):
|
26 |
+
return ChatGoogleGenerativeAI(
|
27 |
+
model="gemini-2.5-flash",
|
28 |
+
api_key=os.getenv("GOOGLE_API_KEY"),
|
29 |
+
temperature=0.0,
|
30 |
+
)
|
31 |
+
|
32 |
+
def _initialize_tools(self):
|
33 |
+
return [
|
34 |
+
Tool(
|
35 |
+
name="weather",
|
36 |
+
func=self.weather_tool.run,
|
37 |
+
description="Use this tool to get the current weather in a specified location."
|
38 |
+
)
|
39 |
+
]
|
40 |
+
|
41 |
+
def _initialize_agent(self):
|
42 |
+
return initialize_agent(
|
43 |
+
self.tools,
|
44 |
+
self.llm,
|
45 |
+
agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
|
46 |
+
verbose=True,
|
47 |
+
)
|
48 |
+
|
49 |
+
def ask(self, location: str):
|
50 |
+
prompt = f"What's the weather like in {location}?"
|
51 |
+
print("Asking:", prompt)
|
52 |
+
result = self.agent.run(prompt)
|
53 |
+
print("Result:", result)
|
54 |
+
return result
|
55 |
+
|
56 |
+
if __name__ == "__main__":
|
57 |
+
print("Starting Weather Agent...")
|
58 |
+
weather_agent = WeatherAgent()
|
59 |
+
print("Agent initialized.")
|
60 |
+
location = "Avignon" # Example location
|
61 |
+
response = weather_agent.ask(location)
|
62 |
+
print("Response:", response)
|