asiffarhankhan commited on
Commit
7c40474
1 Parent(s): f9b19a9

Add Initial Chatbot

Browse files
.gitignore ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ .venv
2
+ __pycache__
3
+ .chroma
4
+ initialize.sh
5
+ conversations.log
app.py ADDED
@@ -0,0 +1,189 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ import os
3
+ import boto3
4
+ import openai
5
+ import whisper
6
+ import logging
7
+ import base64
8
+ import gradio as gr
9
+ from io import BytesIO
10
+
11
+ from langchain import OpenAI
12
+ from langchain.chains import RetrievalQA
13
+ from langchain.vectorstores import Chroma
14
+ from langchain.document_loaders import DirectoryLoader
15
+ from langchain.embeddings.openai import OpenAIEmbeddings
16
+ from langchain.text_splitter import CharacterTextSplitter
17
+ from assets.char_poses_base64 import idle_html_base_64, thinking_html_base_64, talking_html_base64
18
+
19
+ logging.basicConfig(level="INFO",
20
+ filename='conversations.log',
21
+ filemode='a',
22
+ format='%(asctime)s %(message)s',
23
+ datefmt='%H:%M:%S')
24
+
25
+ logger = logging.getLogger('voice_agent')
26
+
27
+
28
+ global FUNC_CALL
29
+ FUNC_CALL = 0
30
+
31
+ OPENAI_API_KEY = os.getenv('OPENAI_API_KEY')
32
+ AWS_ACCESS_KEY_ID = os.getenv('AWS_ACCESS_KEY_ID')
33
+ AWS_SECRET_ACCESS_KEY = os.getenv('AWS_SECRET_ACCESS_KEY')
34
+ AWS_REGION_NAME = 'ap-south-1'
35
+
36
+ GENERAL_RSPONSE_TRIGGERS = ["I don't understand the question.", "I don't know", "Hello, my name is", "mentioned in the context provided"]
37
+ MESSAGES = [{"role": "system", "content": "You are a helpful assistant.."}]
38
+
39
+ CHAR_IDLE = f'<img src="{idle_html_base_64}"></img>'
40
+ CHAR_TALKING = f'<img src="{talking_html_base64}"></img>'
41
+ CHAR_THINKING = f'<img src="{thinking_html_base_64}"></img>'
42
+ AUDIO_HTML = ''
43
+
44
+ # Uncomment If this is your first Run:
45
+ import nltk
46
+ nltk.download('averaged_perceptron_tagger')
47
+
48
+
49
+ def initialize_knowledge_base():
50
+
51
+ loader = DirectoryLoader('profiles', glob='**/*.txt')
52
+ docs = loader.load()
53
+
54
+ char_text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
55
+ doc_texts = char_text_splitter.split_documents(docs)
56
+
57
+ openAI_embeddings = OpenAIEmbeddings()
58
+ vStore = Chroma.from_documents(doc_texts, openAI_embeddings)
59
+
60
+ conv_model = RetrievalQA.from_chain_type(
61
+ llm=OpenAI(),
62
+ chain_type="stuff",
63
+ retriever=vStore.as_retriever(
64
+ search_kwargs={"k": 1}
65
+ )
66
+ )
67
+ voice_model = whisper.load_model("tiny")
68
+
69
+ return conv_model, voice_model
70
+
71
+
72
+ def text_to_speech_gen(answer):
73
+
74
+ polly = boto3.client('polly',
75
+ aws_access_key_id=AWS_ACCESS_KEY_ID,
76
+ aws_secret_access_key=AWS_SECRET_ACCESS_KEY,
77
+ region_name=AWS_REGION_NAME)
78
+
79
+ response = polly.synthesize_speech(
80
+ Text=answer,
81
+ VoiceId='Matthew',
82
+ OutputFormat='mp3',
83
+ Engine = "neural")
84
+
85
+ audio_stream = response['AudioStream'].read()
86
+ audio_html = audio_to_html(audio_stream)
87
+
88
+ return audio_html
89
+
90
+
91
+ def audio_to_html(audio_bytes):
92
+ audio_io = BytesIO(audio_bytes)
93
+ audio_io.seek(0)
94
+ audio_base64 = base64.b64encode(audio_io.read()).decode("utf-8")
95
+ audio_html = f'<audio src="data:audio/mpeg;base64,{audio_base64}" controls autoplay></audio>'
96
+
97
+ return audio_html
98
+
99
+
100
+ def update_img():
101
+ global FUNC_CALL
102
+ FUNC_CALL += 1
103
+
104
+ if FUNC_CALL % 2== 0:
105
+ CHARACTER_STATE = CHAR_TALKING
106
+ else:
107
+ CHARACTER_STATE = CHAR_THINKING
108
+
109
+ return CHARACTER_STATE
110
+
111
+
112
+ def user(user_message, history):
113
+ return "", history + [[user_message, None]]
114
+
115
+ conv_model, voice_model = initialize_knowledge_base()
116
+
117
+
118
+ def get_response(history, audio_input):
119
+
120
+ query_type = 'text'
121
+ question =history[-1][0]
122
+
123
+ if not question:
124
+ if audio_input:
125
+ query_type = 'audio'
126
+ os.rename(audio_input, audio_input + '.wav')
127
+ audio_file = open(audio_input + '.wav', "rb")
128
+ transcript = openai.Audio.transcribe("whisper-1", audio_file)
129
+ question = transcript['text']
130
+ else:
131
+ return None, None
132
+
133
+ logger.info("\nquery_type: %s", query_type)
134
+ logger.info("query_text: %s", question)
135
+ print('\nquery_type:', query_type)
136
+ print('\nquery_text:', question)
137
+
138
+ if question.lower().strip() == 'hi':
139
+ question = 'hello'
140
+
141
+ answer = conv_model.run(question)
142
+ logger.info("\ndocument_response: %s", answer)
143
+ print('\ndocument_response:', answer)
144
+
145
+ for trigger in GENERAL_RSPONSE_TRIGGERS:
146
+ if trigger in answer:
147
+ MESSAGES.append({"role": "user", "content": question})
148
+ chat = openai.ChatCompletion.create(
149
+ model="gpt-3.5-turbo",
150
+ messages=MESSAGES,
151
+ temperature=0.7,
152
+ n=128,
153
+ stop="\n"
154
+ )
155
+ answer = chat.choices[0].message.content
156
+ MESSAGES.append({"role": "assistant", "content": answer})
157
+ logger.info("general_response: %s", answer)
158
+ print('\ngeneral_response:', answer)
159
+
160
+ AUDIO_HTML = text_to_speech_gen(answer)
161
+ history[-1][1] = answer
162
+
163
+ return history, AUDIO_HTML
164
+
165
+
166
+ with gr.Blocks(title="Your Assistance Pal!") as demo:
167
+ with gr.Row():
168
+ output_html = gr.HTML(label="Felix's Voice", value=AUDIO_HTML)
169
+ output_html.visible = False
170
+ assistant_character = gr.HTML(label=None, value=CHAR_IDLE, show_label=False)
171
+ with gr.Column(scale=0.1):
172
+ chatbot = gr.Chatbot(label='Send a text or a voice input').style(height=285)
173
+ with gr.Row():
174
+ msg = gr.Textbox(placeholder='Write a chat & press Enter.', show_label=False).style(container=False)
175
+ with gr.Column(scale=0.5):
176
+ audio_input = gr.Audio(source="microphone", type='filepath', show_label=False).style(container=False)
177
+ button = gr.Button(value="Send")
178
+
179
+ msg.submit(user, [msg, chatbot], [msg, chatbot]
180
+ ).then(update_img, outputs=[assistant_character]
181
+ ).then(get_response, [chatbot, audio_input], [chatbot, output_html]
182
+ ).then(update_img, outputs=[assistant_character])
183
+
184
+ button.click(user, [msg, chatbot], [msg, chatbot]
185
+ ).then(update_img, outputs=[assistant_character]
186
+ ).then(get_response, [chatbot, audio_input], [chatbot, output_html]
187
+ ).then(update_img, outputs=[assistant_character])
188
+
189
+ demo.launch(debug=False, favicon_path='assets/favicon.png', show_api=False, share=False)
assets/char_idle.gif ADDED
assets/char_poses_base64.py ADDED
The diff for this file is too large to render. See raw diff
 
assets/char_speaking.gif ADDED
assets/char_thinking.gif ADDED
assets/favicon.png ADDED
profiles/john.txt ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Full name is Alfred Brandon
2
+ you were born in 12th March 1958
3
+ John is at the shop
4
+ Brian is on holiday
5
+ Sarah is coming home soon
6
+ Sarah is net door and has left
7
+ You have granddaughters, jennny and michelle, they are 7 and 10
8
+ Your cousin Arthur is in Australia, he’s back next July
9
+ Your neighbuor Steven passed away a few days ago
10
+ Your wife hospital, broke arm
11
+ John will be back by 8