ibagur commited on
Commit
fb76c41
1 Parent(s): 5763045

complete app.py

Browse files
Files changed (1) hide show
  1. app.py +126 -94
app.py CHANGED
@@ -1,107 +1,139 @@
1
- import os
2
- from typing import Optional, Tuple
 
 
 
 
 
 
 
 
 
3
 
4
  import gradio as gr
5
- from langchain.chains import ConversationChain
6
- from langchain.llms import OpenAI
7
- from threading import Lock
8
-
9
-
10
- def load_chain():
11
- """Logic for loading the chain you want to use should go here."""
12
- llm = OpenAI(temperature=0)
13
- chain = ConversationChain(llm=llm)
14
- return chain
15
-
16
-
17
- def set_openai_api_key(api_key: str):
18
- """Set the api key and return chain.
19
-
20
- If no api_key, then None is returned.
21
- """
22
- if api_key:
23
- os.environ["OPENAI_API_KEY"] = api_key
24
- chain = load_chain()
25
- os.environ["OPENAI_API_KEY"] = ""
26
- return chain
27
-
28
- class ChatWrapper:
29
-
30
- def __init__(self):
31
- self.lock = Lock()
32
- def __call__(
33
- self, api_key: str, inp: str, history: Optional[Tuple[str, str]], chain: Optional[ConversationChain]
34
- ):
35
- """Execute the chat functionality."""
36
- self.lock.acquire()
37
- try:
38
- history = history or []
39
- # If chain is None, that is because no API key was provided.
40
- if chain is None:
41
- history.append((inp, "Please paste your OpenAI key to use"))
42
- return history, history
43
- # Set OpenAI key
44
- import openai
45
- openai.api_key = api_key
46
- # Run chain and append input.
47
- output = chain.run(input=inp)
48
- history.append((inp, output))
49
- except Exception as e:
50
- raise e
51
- finally:
52
- self.lock.release()
53
- return history, history
54
-
55
- chat = ChatWrapper()
56
-
57
- block = gr.Blocks(css=".gradio-container {background-color: lightgray}")
58
-
59
- with block:
60
- with gr.Row():
61
- gr.Markdown("<h3><center>LangChain Demo</center></h3>")
62
-
63
- openai_api_key_textbox = gr.Textbox(
64
- placeholder="Paste your OpenAI API key (sk-...)",
65
- show_label=False,
66
- lines=1,
67
- type="password",
68
- )
69
 
70
- chatbot = gr.Chatbot()
 
71
 
72
- with gr.Row():
73
- message = gr.Textbox(
74
- label="What's your question?",
75
- placeholder="What's the answer to life, the universe, and everything?",
76
- lines=1,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  )
78
- submit = gr.Button(value="Send", variant="secondary").style(full_width=False)
79
-
80
- gr.Examples(
81
- examples=[
82
- "Hi! How's it going?",
83
- "What should I do tonight?",
84
- "Whats 2 + 2?",
85
- ],
86
- inputs=message,
 
 
 
 
 
 
 
87
  )
 
88
 
89
- gr.HTML("Demo application of a LangChain chain.")
 
90
 
91
- gr.HTML(
92
- "<center>Powered by <a href='https://github.com/hwchase17/langchain'>LangChain 🦜️🔗</a></center>"
93
- )
94
 
95
- state = gr.State()
96
- agent_state = gr.State()
 
97
 
98
- submit.click(chat, inputs=[openai_api_key_textbox, message, state, agent_state], outputs=[chatbot, state])
99
- message.submit(chat, inputs=[openai_api_key_textbox, message, state, agent_state], outputs=[chatbot, state])
 
100
 
101
- openai_api_key_textbox.change(
102
- set_openai_api_key,
103
- inputs=[openai_api_key_textbox],
104
- outputs=[agent_state],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
  )
 
106
 
107
- block.launch(debug=True)
 
 
1
+ from langchain.embeddings.openai import OpenAIEmbeddings
2
+ from langchain.vectorstores import Chroma
3
+ from langchain.text_splitter import RecursiveCharacterTextSplitter
4
+ from langchain.agents import AgentExecutor, Tool, load_tools
5
+ from langchain.chains import RetrievalQA, RetrievalQAWithSourcesChain, LLMChain, LLMMathChain
6
+ from langchain.chat_models import ChatOpenAI
7
+ from langchain.document_loaders import DirectoryLoader
8
+ from langchain.memory import ConversationBufferMemory
9
+ from langchain.utilities import WikipediaAPIWrapper
10
+ from langchain.agents import initialize_agent, AgentType
11
+ from langchain.document_loaders import WebBaseLoader
12
 
13
  import gradio as gr
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
 
15
+ # Add presets for Gradio theme
16
+ from app_modules.presets import *
17
 
18
+ import os
19
+ os.environ["OPENAI_API_KEY"] = "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"
20
+
21
+ # Flag to load chroma store
22
+ flag_chroma = True
23
+
24
+ # Define the LLM chat model
25
+ #model = 'gpt-3.5-turbo'
26
+ model = 'gpt-4'
27
+ temperature = 0
28
+ llm = ChatOpenAI(temperature=temperature, model=model)
29
+
30
+ # Check flag to load vectorstore
31
+ if flag_chroma:
32
+ # Load an existing database
33
+ persist_dir = "./chroma"
34
+ embeddings = OpenAIEmbeddings()
35
+ vectorstore = Chroma(persist_directory=persist_dir, embedding_function=embeddings)
36
+ vectorstore.persist()
37
+ else:
38
+ # Document and sources loader
39
+ pdf_loader = DirectoryLoader('./Reports/', glob="**/*.pdf")
40
+ txt_loader = DirectoryLoader('./Reports/', glob="**/*.txt")
41
+ word_loader = DirectoryLoader('./Reports/', glob="**/*.docx")
42
+ web_based_loader = WebBaseLoader(["https://www.unwomen.org/en/what-we-do/ending-violence-against-women/faqs/types-of-violence", "https://2021.gho.unocha.org/global-trends/gender-and-gender-based-violence-humanitarian-action/"])
43
+
44
+ loaders = [pdf_loader, txt_loader, word_loader, web_based_loader]
45
+ docs = []
46
+ for loader in loaders:
47
+ docs.extend(loader.load())
48
+
49
+ # Text splitter
50
+ ## If chunks are bigger than 1000, it recursively splits them until fitting them within size
51
+ text_splitter = RecursiveCharacterTextSplitter(
52
+ separators=["\n\n", "\n", ".", "!", "?", ",", " ", ""],
53
+ chunk_size = 1000,
54
+ chunk_overlap = 50
55
+ )
56
+ documents = text_splitter.split_documents(docs)
57
+
58
+ # Embed documents in Vectorstore
59
+ persist_dir = "chroma"
60
+ embeddings = OpenAIEmbeddings()
61
+ vectorstore = Chroma.from_documents(documents, embeddings, persist_directory=persist_dir)
62
+ vectorstore.persist()
63
+
64
+ # Create Retrieval Chain with sources
65
+ ## It returns a dictionary with at least the 'answer' and the 'sources'
66
+ qa = RetrievalQAWithSourcesChain.from_chain_type(
67
+ llm=llm,
68
+ chain_type="stuff",
69
+ retriever=vectorstore.as_retriever(),
70
+ return_source_documents=True
71
  )
72
+
73
+ # Define tools
74
+ wikipedia = WikipediaAPIWrapper()
75
+
76
+ tools = [
77
+ Tool(
78
+ name="GBV Q&A Bot System",
79
+ #func=qa,
80
+ func=lambda question: qa({"question": question}, return_only_outputs=True),
81
+ description="Useful for when you need to answer questions about the aspects asked. Input may be a partial or fully formed question.",
82
+ #return_direct=True, # use the agent as a router and directly return the result
83
+ ),
84
+ Tool(
85
+ name='Wikipedia',
86
+ func=wikipedia.run,
87
+ description='You must only use this tool if you cannot find answers with the other tools. Useful for when you need to look for answers in the Wikipedia.'
88
  )
89
+ ]
90
 
91
+ # Create Buffer Memory
92
+ memory = ConversationBufferMemory(memory_key="chat_history", input_key='input', output_key="output", return_messages=True)
93
 
94
+ # Initialize Re-Act agent and create Agent Executor Chain
95
+ react = initialize_agent(tools, llm, agent=AgentType.CHAT_CONVERSATIONAL_REACT_DESCRIPTION, verbose=True, max_iterations=3, early_stopping_method='generate', memory=memory)
 
96
 
97
+ agent_chain = AgentExecutor.from_agent_and_tools(
98
+ agent=react.agent, tools=tools, verbose=True, memory=memory, return_intermediate_steps=True, return_source_documents=True, handle_parsing_errors=True
99
+ )
100
 
101
+ # Add custom CSS
102
+ with open("assets/custom.css", "r", encoding="utf-8") as f:
103
+ customCSS = f.read()
104
 
105
+ with gr.Blocks(css=customCSS, theme=small_and_beautiful_theme) as demo:
106
+
107
+ gr.Markdown(
108
+ """
109
+ # 🦜🔗 Ask GBV Q&A Bot!
110
+ Start typing below to see the output.
111
+ """
112
+ )
113
+
114
+ # Start chatbot with welcome from bot
115
+ chatbot = gr.Chatbot([(None,'How can I help you?')]).style(height=650)
116
+ msg = gr.Textbox()
117
+ clear = gr.ClearButton([msg, chatbot])
118
+
119
+ def user(user_message, history):
120
+ return gr.update(value="", interactive=False), history + [[user_message, None]]
121
+
122
+ def bot(history):
123
+ user_message = history[-1][0] # get if from most recent history element
124
+ #bot_message = conversation.run(user_message)
125
+ response = agent_chain(user_message)
126
+ bot_message = response['output']
127
+ history[-1][1] = ""
128
+ for character in bot_message:
129
+ history[-1][1] += character
130
+ #time.sleep(0.05)
131
+ yield history
132
+
133
+ response = msg.submit(user, [msg, chatbot], [msg, chatbot], queue=False).then(
134
+ bot, chatbot, chatbot
135
  )
136
+ response.then(lambda: gr.update(interactive=True), None, [msg], queue=False)
137
 
138
+ demo.queue()
139
+ demo.launch()