File size: 4,847 Bytes
d3a40e2
 
 
 
 
 
 
 
 
 
 
 
 
 
253ce6d
d3a40e2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5bc193e
d3a40e2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import streamlit as st
from langchain_groq import ChatGroq
from langchain_community.utilities import ArxivAPIWrapper, WikipediaAPIWrapper, DuckDuckGoSearchAPIWrapper
from langchain_community.tools import ArxivQueryRun, WikipediaQueryRun, DuckDuckGoSearchResults
from langchain.tools import Tool
from langchain.agents import initialize_agent, AgentType
from langchain_community.callbacks.streamlit import StreamlitCallbackHandler
from langchain_huggingface import HuggingFaceEmbeddings
from langchain.memory import ConversationBufferWindowMemory
import os
from dotenv import load_dotenv
load_dotenv()

## Embeddings
os.environ["HF_TOKEN"] = os.getenv("HF_TOKEN")
embeddings = HuggingFaceEmbeddings(model_name="all-MiniLM-L6-v2")

## Wikipedia Agent/Tool
api_wrapper_wiki = WikipediaAPIWrapper(top_k_results = 3, doc_content_chars_max=10000)
wiki = WikipediaQueryRun(api_wrapper=api_wrapper_wiki)
wiki_tool= Tool(
    name = "Wikipedia",
    func = wiki.run,
    description = "This tool uses the Wikipedia API to search for a topic."
)

## Arxiv Agent/Tool
api_wrapper_arxiv = ArxivAPIWrapper(top_k_results = 5, doc_content_chars_max=10000)
arxiv = ArxivQueryRun(api_wrapper=api_wrapper_arxiv)
arxiv_tool = Tool(
    name = "arxiv",
    func = arxiv.run,
    description = "Searches arXiv for papers matching the query.",
)


## DuckDuckGo Search Agent/Tool
api_wrapper_ddg = DuckDuckGoSearchAPIWrapper(region="us-en", time="y", max_results=10)
ddg = DuckDuckGoSearchResults(
    api_wrapper=api_wrapper_ddg,
    #source = "news",
    output_format="string",
    handle_tool_error=True,
    handle_validation_error=True)
ddg_tool = Tool(
    name = "DuckDuckGo_Search",
    func = ddg.run,
    description = "Searches for search queries using the DuckDuckGo Search engine."
)

system_prompt = """
You are a helpful and detailed research assistant
that has the ability to search the web, Wikipedia, and arXiv for information on a topic.
Try to understand the query submitted by the user.
Searching the internet is MANDATORY before responding to every query.
Look for any context clues that may be present in the memory.
Provide thorough, step-by-step explanations in your responses 
and include all relevant context and details from available sources.
Make sure that your response is around 100-200 words long.
You are a highly intelligent and reflective assistant.
For every query, first provide a detailed, step-by-step explanation
of your reasoning process, then on a new line after a separator 'Final Answer:', 
give your concise final answer. Do not omit any part of your reasoning.
User query: 
"""

# Streamlit App
## App Title
st.title("Langchain - Chat with search")

api_key = st.sidebar.text_input("Enter your Groq API Key:", type="password")
warning_placeholder = st.sidebar.empty()

# Ask for API key if it's not set in session state.
if "api_key" not in st.session_state or not st.session_state.api_key:
    st.session_state.api_key = api_key
    # Only display the warning if no API key is provided.
    if not st.session_state.api_key:
        warning_placeholder.warning("Please enter your Groq API Key to proceed.")
else:
    # Once the API key is provided, clear the warning.
    warning_placeholder.empty()

if "messages" not in st.session_state:
    st.session_state["messages"] = [    
        {
            "role": "assistant",
            "content": "Hi, I am a chatbot who can search the web. How can I help you today?"
        }
    ]

for msg in st.session_state.messages:
    st.chat_message(msg["role"]).write(msg['content'])

# Initialize conversation memory once and persist it
if "memory" not in st.session_state:
    st.session_state.memory = ConversationBufferWindowMemory(k=5, memory_key="chat_history", return_messages=True)
memory = st.session_state.memory

if prompt:= st.chat_input(placeholder = "Write your query here...."):
    st.session_state.messages.append({
        "role":"user",
        "content": prompt
    })
    st.chat_message("user").write(prompt)

    llm = ChatGroq(groq_api_key = st.session_state.api_key, model_name = "Llama3-8b-8192", streaming = True)
    #llm = ChatOllama(base_url=OLLAMA_WSL_IP, model="llama3.1", streaming=True)

    tools = [wiki_tool, arxiv_tool, ddg_tool]

    search_agent = initialize_agent(
        tools = tools,
        llm = llm,
        agent = AgentType.CHAT_CONVERSATIONAL_REACT_DESCRIPTION,
        max_iterations = 10,
        memory = memory,
        handle_parsing_errors = True)

    with st.chat_message("assistant"):
        st_cb = StreamlitCallbackHandler(st.container(), expand_new_thoughts=True)
        response = search_agent.run(system_prompt + prompt, callbacks = [st_cb])
        #print(memory)
        st.session_state.messages.append({
            "role":"assistant",
            "content": response
        })
        st.write(response)