okoliechykwuka commited on
Commit
c6aa3ff
·
1 Parent(s): d7ee606

Add application file

Browse files
Files changed (4) hide show
  1. Dockerfile +16 -0
  2. README copy.md +10 -0
  3. RFPAgent.py +188 -0
  4. requirements.txt +9 -0
Dockerfile ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.9
2
+
3
+ WORKDIR /code
4
+
5
+ COPY ./requirements.txt /code/requirements.txt
6
+ RUN python3 -m pip install --no-cache-dir --upgrade pip
7
+ RUN python3 -m pip install --no-cache-dir --upgrade -r /code/requirements.txt
8
+
9
+ COPY . .
10
+
11
+ CMD ["panel", "serve", "/code/RFPAgent.py", "--address", "0.0.0.0", "--port", "7860", "--allow-websocket-origin", "chukypedro-panel-doc-agent-qa.hf.space", "--allow-websocket-origin", "0.0.0.0:7860"]
12
+
13
+ RUN mkdir /.cache
14
+ RUN chmod 777 /.cache
15
+ RUN mkdir .chroma
16
+ RUN chmod 777 .chroma
README copy.md ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Panel Agent Document QA
3
+ emoji: 📈
4
+ colorFrom: pink
5
+ colorTo: red
6
+ sdk: docker
7
+ pinned: false
8
+ ---
9
+
10
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
RFPAgent.py ADDED
@@ -0,0 +1,188 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from langchain.embeddings import OpenAIEmbeddings, HuggingFaceEmbeddings
2
+ from langchain.vectorstores import Chroma
3
+ from langchain.text_splitter import CharacterTextSplitter, RecursiveCharacterTextSplitter
4
+ from langchain.llms import OpenAI
5
+ from langchain.chains import RetrievalQA
6
+ from langchain.document_loaders import PyPDFLoader, Docx2txtLoader, BSHTMLLoader, UnstructuredImageLoader
7
+ # Import things that are needed generically
8
+ from langchain.memory import ConversationBufferMemory
9
+ from langchain.agents import initialize_agent, Tool
10
+ from langchain.agents import AgentType
11
+ from langchain import LLMMathChain
12
+ #setting a memory for conversations
13
+ import panel as pn
14
+ import os
15
+ from dotenv import load_dotenv
16
+ load_dotenv()
17
+ memory = ConversationBufferMemory(memory_key="chat_history")
18
+
19
+
20
+ def qa_agent(file, query, chain_type, k):
21
+ """_summary_
22
+
23
+ Args:
24
+ file (_type_): _description_
25
+ query (_type_): _description_
26
+ chain_type (_type_): _description_
27
+ k (_type_): _description_
28
+
29
+ Returns:
30
+ _type_: _description_
31
+ """
32
+ llm = OpenAI(temperature=0)
33
+ llm_math_chain = LLMMathChain(llm=OpenAI(temperature=0))
34
+
35
+ # load document
36
+ if file.endswith('pdf'):
37
+ loader = PyPDFLoader(file)
38
+ elif file.endswith('docx'):
39
+ loader = Docx2txtLoader(file)
40
+ elif file.endswith('jpg') or file.endswith('jpg'):
41
+ loader = UnstructuredImageLoader(file, mode="elements")
42
+ else:
43
+ raise ValueError
44
+
45
+ documents = loader.load()
46
+ # split the documents into chunks
47
+ text_splitter = CharacterTextSplitter(chunk_size=3228, chunk_overlap=0)
48
+ texts = text_splitter.split_documents(documents)
49
+ # select which embeddings we want to use
50
+ embeddings = OpenAIEmbeddings()
51
+
52
+ # create the vectorestore to use as the index
53
+ db = Chroma.from_documents(texts, embeddings)
54
+ # expose this index in a retriever interface
55
+ retriever = db.as_retriever(search_type="similarity", search_kwargs={"k": k})
56
+ # create a chain to answer questions
57
+ qa = RetrievalQA.from_chain_type(
58
+ llm=llm, chain_type=chain_type, retriever=retriever)
59
+
60
+ '--------------------------------- CREATE AGENT ---------------------------------'
61
+ tools = [
62
+ Tool(
63
+ name = "Demo",
64
+ func=qa.run,
65
+ description="use this as the primary source of context information when you are asked the question. \
66
+ Always search for the answers using only the provided tool, don't make up answers yourself"
67
+
68
+ ),
69
+
70
+ Tool(
71
+ name="Calculator",
72
+ func=llm_math_chain.run,
73
+ description="Useful for answering math-related questions within the given document. Avoid speculating beyond the document's content. If you don't know the answer to a question, simply state 'I don't know'.",
74
+ return_direct=True #return tool directly to the user
75
+ )
76
+
77
+ ]
78
+ # Construct the agent. We will use the default agent type here.
79
+ # See documentation for a full list of options.
80
+
81
+ agent = initialize_agent(
82
+ tools,
83
+ agent= AgentType.ZERO_SHOT_REACT_DESCRIPTION,
84
+ llm=llm,
85
+ memory=memory,
86
+ verbose=True,
87
+ )
88
+
89
+ result = agent.run(input = query)
90
+
91
+ return result
92
+
93
+ #'Explain what the proposed Approach in this Paper is all about'
94
+
95
+ '------------------------------ Panel App ---------------------------------'
96
+
97
+ pn.extension('texteditor', template="bootstrap", sizing_mode='stretch_width',theme='dark' )
98
+ pn.state.template.param.update(
99
+ main_max_width="690px",
100
+ header_background="blue",
101
+ title='DocumentAgent Application'
102
+ )
103
+
104
+ #######Widget###########
105
+ file_input = pn.widgets.FileInput(width=300)
106
+ openaikey = pn.widgets.PasswordInput(
107
+ value="", placeholder="Enter your OpenAI API Key here...", width=300
108
+ )
109
+ prompt = pn.widgets.TextEditor(
110
+ value="", placeholder="Enter your questions here...", height=160, toolbar=False
111
+ )
112
+ run_button = pn.widgets.Button(name="Run!", margin=(25, 50), background='#f0f0f0', button_type='primary')
113
+
114
+ select_k = pn.widgets.IntSlider(
115
+ name="Number of relevant chunks", start=1, end=5, step=1, value=2
116
+ )
117
+ select_chain_type = pn.widgets.RadioButtonGroup(
118
+ name='Chain type',
119
+ options=['stuff', 'map_reduce', "refine", "map_rerank"],button_type='success'
120
+ )
121
+
122
+
123
+ widgets = pn.Row(
124
+ pn.Column(prompt, run_button, margin=5),
125
+ pn.Card(
126
+ "Chain type:",
127
+ pn.Column(select_chain_type, select_k),
128
+ title="Advanced settings", margin=10
129
+ ), width=600
130
+ )
131
+
132
+ convos = [] # store all panel objects in a list
133
+
134
+ def agent_app(_):
135
+ os.environ["OPENAI_API_KEY"] = openaikey.value
136
+
137
+ # save pdf file to a temp file
138
+ if file_input.value is not None:
139
+ file_input.save(f"/.cache/{file_input.filename}")
140
+
141
+ prompt_text = prompt.value
142
+ if prompt_text:
143
+ result = qa_agent(file=f"/.cache/{file_input.filename}", query=prompt_text, chain_type=select_chain_type.value, k=select_k.value)
144
+ convos.extend([
145
+ pn.Row(
146
+ pn.panel("\U0001F60A", width=10),
147
+ prompt_text,
148
+ width=600
149
+ ),
150
+ pn.Row(
151
+ pn.panel("\U0001F916", width=10),
152
+ pn.Column(
153
+ "Relevant source text:",
154
+ pn.pane.Markdown(result)
155
+ )
156
+ )
157
+ ])
158
+ #return convos
159
+ return pn.Column(*convos, margin=15, width=575, min_height=400)
160
+
161
+
162
+ qa_interactive = pn.panel(
163
+ pn.bind(agent_app, run_button),
164
+ loading_indicator=True,
165
+ )
166
+
167
+ output = pn.WidgetBox('*Output will show up here:*', qa_interactive, width=630, scroll=True)
168
+ # Apply CSS styles to the WidgetBox
169
+ output.background = 'blue'
170
+ # layout
171
+ pn.Column(
172
+ pn.pane.Markdown("""
173
+ ## \U0001F60A! Question Answering Agent with your Document file
174
+
175
+ 1) Upload a Document in [pdf, docx, .jpg, html] format. 2) Enter OpenAI API key. This costs $. Set up billing at [OpenAI](https://platform.openai.com/account). 3) Type a question and click "Run".
176
+
177
+ """),
178
+
179
+ pn.Row(file_input,openaikey),
180
+ output,
181
+ widgets,
182
+ css_classes=['body']).servable()
183
+
184
+
185
+
186
+
187
+
188
+
requirements.txt ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ langchain
2
+ panel
3
+ python-dotenv
4
+ openai
5
+ chromadb
6
+ pypdf
7
+ tiktoken
8
+ panel
9
+ unstructured