Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
|
@@ -53,7 +53,14 @@ from crewai.tools import tool
|
|
| 53 |
from geopy.geocoders import Nominatim
|
| 54 |
from timezonefinder import TimezoneFinder
|
| 55 |
from langchain_experimental.agents import create_pandas_dataframe_agent
|
|
|
|
| 56 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 57 |
|
| 58 |
session_retriever = None
|
| 59 |
session_qa_chain = None
|
|
@@ -293,7 +300,7 @@ def search_web(query):
|
|
| 293 |
api_key = os.environ.get("SERPAPI_API_KEY")
|
| 294 |
if not api_key:
|
| 295 |
return "SERPAPI_API_KEY not set. Please set the environment variable."
|
| 296 |
-
params = {"engine": "google", "q": query, "api_key": api_key, "num":
|
| 297 |
search = GoogleSearch(params)
|
| 298 |
results = search.get_dict()
|
| 299 |
if "organic_results" in results:
|
|
@@ -303,7 +310,25 @@ def search_web(query):
|
|
| 303 |
link = result.get("link", "No Link")
|
| 304 |
snippet = result.get("snippet", "No Snippet")
|
| 305 |
raw_output += f"Title: {title}\nLink: {link}\nSnippet: {snippet}\n\n"
|
| 306 |
-
prompt = "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 307 |
summarized = _general_chat(prompt)
|
| 308 |
return summarized if summarized else raw_output.strip()
|
| 309 |
else:
|
|
@@ -618,16 +643,41 @@ def weather_agent_tool(query: str) -> str:
|
|
| 618 |
hour_str = closest_hour["time"].split(" ")[1]
|
| 619 |
|
| 620 |
summary_prompt = f"""
|
| 621 |
-
|
| 622 |
-
|
| 623 |
-
|
| 624 |
-
|
| 625 |
-
|
| 626 |
-
|
| 627 |
-
|
| 628 |
-
|
| 629 |
-
|
| 630 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 631 |
response = llm_gpt4.invoke(summary_prompt)
|
| 632 |
return response.content.strip() if isinstance(response, AIMessage) else str(response)
|
| 633 |
|
|
@@ -715,16 +765,41 @@ def weather_tool(query: str) -> str:
|
|
| 715 |
hour_str = closest_hour["time"].split(" ")[1]
|
| 716 |
|
| 717 |
summary_prompt = f"""
|
| 718 |
-
|
| 719 |
-
|
| 720 |
-
|
| 721 |
-
|
| 722 |
-
|
| 723 |
-
|
| 724 |
-
|
| 725 |
-
|
| 726 |
-
|
| 727 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 728 |
response = llm_gpt4.invoke(summary_prompt)
|
| 729 |
return response.content.strip() if isinstance(response, AIMessage) else str(response)
|
| 730 |
|
|
@@ -927,7 +1002,7 @@ def multi_agent_chat_advanced(query: str, file=None) -> str:
|
|
| 927 |
date_keywords = ["what date", "today", "what time", "what day", "current time", "date", "現在幾點", "今天幾號", "禮拜幾"]
|
| 928 |
if any(k in lower_query for k in date_keywords):
|
| 929 |
return get_time_tool(query)
|
| 930 |
-
weather_keywords = ["weather", "rain", "snow", "cold", "hot", "cloudy", "sunny", "temperature", "forecast", "天氣", "會不會下雨", "冷嗎", "熱嗎", "氣溫"]
|
| 931 |
if any(k in lower_query for k in weather_keywords):
|
| 932 |
return weather_agent_tool(query)
|
| 933 |
search_keywords = ["latest", "news", "startup", "startups", "company", "companies", "top", "trending", "in 2025", "in 2024", "tell me"]
|
|
@@ -1033,6 +1108,8 @@ If no relevant information is found in the document, the system will say "No rel
|
|
| 1033 |
|
| 1034 |
*Note: The LLaMA module generates responses based solely on the current query without follow-up memory or chat history management.*
|
| 1035 |
|
|
|
|
|
|
|
| 1036 |
Feel free to ask any question related to Biden’s 2023 State of the Union Address.
|
| 1037 |
"""
|
| 1038 |
demo_description2 = """
|
|
@@ -1058,7 +1135,15 @@ demo_description3 = """
|
|
| 1058 |
Upload a PDF, TXT, or DOCX file and ask a question about its content.
|
| 1059 |
This demo uses **GPT-4o-Mini** to answer questions based on the content of your uploaded document.
|
| 1060 |
|
| 1061 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1062 |
"""
|
| 1063 |
demo_description4 = """
|
| 1064 |
**Context**:
|
|
@@ -1083,7 +1168,7 @@ This demo presents a GPT-style Multi-Agent AI Assistant, built with **LangChain,
|
|
| 1083 |
2. What are the key ideas mentioned in this file? *(→ RAG QA Agent)*
|
| 1084 |
3. What is LangChain used for? | What are the latest trends in AI startups in 2025? | Tell me the most recent breakthrough in quantum computing. *(→ Online Rag Agent)*
|
| 1085 |
4. What's the current time in London? | What’s today’s date in New York? | What time is it in Taipei right now? *(→ Time Agent)*
|
| 1086 |
-
5. Will it rain
|
| 1087 |
6. If I earn $15 per hour and work 8 hours a day for 5 days, how much will I earn? | What is 5 * 22.5 / sin(45) | 3^3 + 4^2 | Calculate 25 * log(1000) | What is the square root of 144 *(→ Math Agent)*
|
| 1088 |
7. Who are you? | What can you do? | What is the meaning of life? *(→ General Chat Agent)*
|
| 1089 |
|
|
|
|
| 53 |
from geopy.geocoders import Nominatim
|
| 54 |
from timezonefinder import TimezoneFinder
|
| 55 |
from langchain_experimental.agents import create_pandas_dataframe_agent
|
| 56 |
+
import pinecone
|
| 57 |
|
| 58 |
+
pinecone.init(
|
| 59 |
+
api_key=os.environ["PINECONE_API_KEY"],
|
| 60 |
+
environment=os.environ["PINECONE_ENVIRONMENT"]
|
| 61 |
+
)
|
| 62 |
+
|
| 63 |
+
index = pinecone.Index("rag-docs")
|
| 64 |
|
| 65 |
session_retriever = None
|
| 66 |
session_qa_chain = None
|
|
|
|
| 300 |
api_key = os.environ.get("SERPAPI_API_KEY")
|
| 301 |
if not api_key:
|
| 302 |
return "SERPAPI_API_KEY not set. Please set the environment variable."
|
| 303 |
+
params = {"engine": "google", "q": query, "api_key": api_key, "num": 10}
|
| 304 |
search = GoogleSearch(params)
|
| 305 |
results = search.get_dict()
|
| 306 |
if "organic_results" in results:
|
|
|
|
| 310 |
link = result.get("link", "No Link")
|
| 311 |
snippet = result.get("snippet", "No Snippet")
|
| 312 |
raw_output += f"Title: {title}\nLink: {link}\nSnippet: {snippet}\n\n"
|
| 313 |
+
prompt = f"""
|
| 314 |
+
You are a helpful assistant. Given the following web search results and the user's question:
|
| 315 |
+
|
| 316 |
+
1. First, identify **only** the most relevant entries.
|
| 317 |
+
2. Then, summarise the key insights using fluent, **British English**.
|
| 318 |
+
3. If the user's question asks for trends, categories, or multiple items, you may present key points in a non-markdown bullet-point style (e.g. use "•" instead of "-", avoid using "**" for bold).
|
| 319 |
+
4. Otherwise, reply in a short, natural paragraph.
|
| 320 |
+
5. Do **not** use any markdown formatting such as `**`, `##`, or list syntax.
|
| 321 |
+
6. Keep your answer concise and professional, as if explaining to a colleague.
|
| 322 |
+
7. If no relevant info is found, say: "Sorry, I couldn't find a reliable answer from the current results."
|
| 323 |
+
|
| 324 |
+
--- Web Search Results ---
|
| 325 |
+
{raw_output}
|
| 326 |
+
|
| 327 |
+
--- User's Question ---
|
| 328 |
+
"{query}"
|
| 329 |
+
|
| 330 |
+
Answer:
|
| 331 |
+
"""
|
| 332 |
summarized = _general_chat(prompt)
|
| 333 |
return summarized if summarized else raw_output.strip()
|
| 334 |
else:
|
|
|
|
| 643 |
hour_str = closest_hour["time"].split(" ")[1]
|
| 644 |
|
| 645 |
summary_prompt = f"""
|
| 646 |
+
You are a helpful weather reasoning assistant.
|
| 647 |
+
|
| 648 |
+
The user wants to know about the weather conditions at a specific time: {target_dt.strftime('%Y-%m-%d %H:%M')} in {location}.
|
| 649 |
+
Use the data below to answer their question. This may refer to the past, present, or future — do not assume it is the current weather.
|
| 650 |
+
|
| 651 |
+
Based on the following weather data and the user's question, think step-by-step to extract the most relevant information, and give a natural, friendly, and cautious answer in British English.
|
| 652 |
+
|
| 653 |
+
Avoid being overly confident — never say "Yes, it will..." or "Definitely." Instead, use expressions like:
|
| 654 |
+
- "It is very likely that..."
|
| 655 |
+
- "There is a high chance of..."
|
| 656 |
+
- "Based on the available data, it seems that..."
|
| 657 |
+
- "There may be..."
|
| 658 |
+
|
| 659 |
+
Also, after answering the question, include a short weather summary and a useful suggestion (e.g., bring an umbrella, wear sunscreen, avoid outdoor activities).
|
| 660 |
+
|
| 661 |
+
**Do not use markdown formatting such as `*`, `**`, or list symbols.**
|
| 662 |
+
|
| 663 |
+
--- Weather Data ---
|
| 664 |
+
Location: {location}
|
| 665 |
+
Time: {target_dt.strftime('%Y-%m-%d')} at {hour_str}
|
| 666 |
+
Condition: {condition}
|
| 667 |
+
Temperature: {temp}°C (Feels like {feels}°C)
|
| 668 |
+
Humidity: {humidity}%
|
| 669 |
+
Chance of rain: {chance_rain}%
|
| 670 |
+
Chance of snow: {closest_hour.get("chance_of_snow", "N/A")}%
|
| 671 |
+
Wind speed: {closest_hour.get("wind_kph", "N/A")} kph
|
| 672 |
+
UV index: {closest_hour.get("uv", "N/A")}
|
| 673 |
+
Cloud cover: {closest_hour.get("cloud", "N/A")}%
|
| 674 |
+
Visibility: {closest_hour.get("vis_km", "N/A")} km
|
| 675 |
+
|
| 676 |
+
--- User Question ---
|
| 677 |
+
{query}
|
| 678 |
+
|
| 679 |
+
--- Final Answer ---
|
| 680 |
+
"""
|
| 681 |
response = llm_gpt4.invoke(summary_prompt)
|
| 682 |
return response.content.strip() if isinstance(response, AIMessage) else str(response)
|
| 683 |
|
|
|
|
| 765 |
hour_str = closest_hour["time"].split(" ")[1]
|
| 766 |
|
| 767 |
summary_prompt = f"""
|
| 768 |
+
You are a helpful weather reasoning assistant.
|
| 769 |
+
|
| 770 |
+
The user wants to know about the weather conditions at a specific time: {target_dt.strftime('%Y-%m-%d %H:%M')} in {location}.
|
| 771 |
+
Use the data below to answer their question. This may refer to the past, present, or future — do not assume it is the current weather.
|
| 772 |
+
|
| 773 |
+
Based on the following weather data and the user's question, think step-by-step to extract the most relevant information, and give a natural, friendly, and cautious answer in British English.
|
| 774 |
+
|
| 775 |
+
Avoid being overly confident — never say "Yes, it will..." or "Definitely." Instead, use expressions like:
|
| 776 |
+
- "It is very likely that..."
|
| 777 |
+
- "There is a high chance of..."
|
| 778 |
+
- "Based on the available data, it seems that..."
|
| 779 |
+
- "There may be..."
|
| 780 |
+
|
| 781 |
+
Also, after answering the question, include a short weather summary and a useful suggestion (e.g., bring an umbrella, wear sunscreen, avoid outdoor activities).
|
| 782 |
+
|
| 783 |
+
**Do not use markdown formatting such as `*`, `**`, or list symbols.**
|
| 784 |
+
|
| 785 |
+
--- Weather Data ---
|
| 786 |
+
Location: {location}
|
| 787 |
+
Time: {target_dt.strftime('%Y-%m-%d')} at {hour_str}
|
| 788 |
+
Condition: {condition}
|
| 789 |
+
Temperature: {temp}°C (Feels like {feels}°C)
|
| 790 |
+
Humidity: {humidity}%
|
| 791 |
+
Chance of rain: {chance_rain}%
|
| 792 |
+
Chance of snow: {closest_hour.get("chance_of_snow", "N/A")}%
|
| 793 |
+
Wind speed: {closest_hour.get("wind_kph", "N/A")} kph
|
| 794 |
+
UV index: {closest_hour.get("uv", "N/A")}
|
| 795 |
+
Cloud cover: {closest_hour.get("cloud", "N/A")}%
|
| 796 |
+
Visibility: {closest_hour.get("vis_km", "N/A")} km
|
| 797 |
+
|
| 798 |
+
--- User Question ---
|
| 799 |
+
{query}
|
| 800 |
+
|
| 801 |
+
--- Final Answer ---
|
| 802 |
+
"""
|
| 803 |
response = llm_gpt4.invoke(summary_prompt)
|
| 804 |
return response.content.strip() if isinstance(response, AIMessage) else str(response)
|
| 805 |
|
|
|
|
| 1002 |
date_keywords = ["what date", "today", "what time", "what day", "current time", "date", "現在幾點", "今天幾號", "禮拜幾"]
|
| 1003 |
if any(k in lower_query for k in date_keywords):
|
| 1004 |
return get_time_tool(query)
|
| 1005 |
+
weather_keywords = ["weather", "rain", "snow", "cold", "hot", "sunscreen", "sunglasses", "umbrella", "windy", "cloudy", "sunny", "temperature", "forecast", "天氣", "會不會下雨", "冷嗎", "熱嗎", "氣溫"]
|
| 1006 |
if any(k in lower_query for k in weather_keywords):
|
| 1007 |
return weather_agent_tool(query)
|
| 1008 |
search_keywords = ["latest", "news", "startup", "startups", "company", "companies", "top", "trending", "in 2025", "in 2024", "tell me"]
|
|
|
|
| 1108 |
|
| 1109 |
*Note: The LLaMA module generates responses based solely on the current query without follow-up memory or chat history management.*
|
| 1110 |
|
| 1111 |
+
> This is a CPU-only demo running a **quantised 1B LLaMA model**, built to show that full RAG + multi-agent systems can run even without a GPU. In production, the model can be replaced with larger ones (3B, 7B, etc.) and served using vLLM, 4-bit quantisation, or TensorRT for better speed. The design focuses on portability, deployment, and modularity.
|
| 1112 |
+
|
| 1113 |
Feel free to ask any question related to Biden’s 2023 State of the Union Address.
|
| 1114 |
"""
|
| 1115 |
demo_description2 = """
|
|
|
|
| 1135 |
Upload a PDF, TXT, or DOCX file and ask a question about its content.
|
| 1136 |
This demo uses **GPT-4o-Mini** to answer questions based on the content of your uploaded document.
|
| 1137 |
|
| 1138 |
+
Note: This is a **strict RAG-based QA** system. It will only answer questions if the answer is explicitly found in the uploaded document.
|
| 1139 |
+
For more flexible or general-purpose responses, please try Tab 1 (Multi-Agent Assistant).
|
| 1140 |
+
|
| 1141 |
+
Typical Use Cases:
|
| 1142 |
+
- Legal, technical, or academic documents where factual precision is critical
|
| 1143 |
+
- Internal company reports where hallucination must be avoided
|
| 1144 |
+
- Medical papers where only referenced content should be discussed
|
| 1145 |
+
|
| 1146 |
+
Feel free to ask any question directly related to your document.
|
| 1147 |
"""
|
| 1148 |
demo_description4 = """
|
| 1149 |
**Context**:
|
|
|
|
| 1168 |
2. What are the key ideas mentioned in this file? *(→ RAG QA Agent)*
|
| 1169 |
3. What is LangChain used for? | What are the latest trends in AI startups in 2025? | Tell me the most recent breakthrough in quantum computing. *(→ Online Rag Agent)*
|
| 1170 |
4. What's the current time in London? | What’s today’s date in New York? | What time is it in Taipei right now? *(→ Time Agent)*
|
| 1171 |
+
5. Will it rain or snow in Sapporo tomorrow night? | Is it too windy for cycling in Amsterdam at 6am? | Do I need to bring an umbrella later this evening in Edinburgh? | Should I wear sunscreen in Bangkok around noon tomorrow? | Is it gonna rain later? | What was the weather like in Paris on last Sunday? | Will the weather be suitable for hiking at 3pm in Lake District? *(→ Weather Agent)*
|
| 1172 |
6. If I earn $15 per hour and work 8 hours a day for 5 days, how much will I earn? | What is 5 * 22.5 / sin(45) | 3^3 + 4^2 | Calculate 25 * log(1000) | What is the square root of 144 *(→ Math Agent)*
|
| 1173 |
7. Who are you? | What can you do? | What is the meaning of life? *(→ General Chat Agent)*
|
| 1174 |
|