cafierom commited on
Commit
795bf6b
·
verified ·
1 Parent(s): cc2e122

Upload MoDrAg_Chat_HFS.py

Browse files
Files changed (1) hide show
  1. MoDrAg_Chat_HFS.py +246 -0
MoDrAg_Chat_HFS.py ADDED
@@ -0,0 +1,246 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import openai
2
+ import os
3
+ from openai import OpenAI
4
+ import gradio as gr
5
+ from elevenlabs.client import ElevenLabs
6
+ from elevenlabs import stream
7
+ import base64
8
+
9
+ api_key = os.getenv("OPENAI_API_KEY")
10
+ eleven_key = os.getenv("eleven_key")
11
+
12
+ elevenlabs = ElevenLabs(api_key=eleven_key)
13
+ client = OpenAI(api_key=api_key)
14
+
15
+ cafchem_tools = [
16
+ {
17
+ "type" : "mcp",
18
+ "server_label":"cafiero-proteinagent",
19
+ "server_url":"https://cafierom-proteinagent.hf.space/gradio_api/mcp/",
20
+ "require_approval": "never",
21
+ "allowed_tools": ["ProteinAgent_ProteinAgent"],
22
+ },
23
+ {
24
+ "type" : "mcp",
25
+ "server_label":"cafiero-propagent",
26
+ "server_url":"https://cafierom-propagent.hf.space/gradio_api/mcp/",
27
+ "require_approval": "never",
28
+ "allowed_tools": ["PropAgent_PropAgent"],
29
+ },
30
+ {
31
+ "type" : "mcp",
32
+ "server_label":"cafiero-moleculeagent",
33
+ "server_url":"https://cafierom-moleculeagent.hf.space/gradio_api/mcp/",
34
+ "require_approval": "never",
35
+ "allowed_tools": ["MoleculeAgent_MoleculeAgent"],
36
+ },
37
+ {
38
+ "type" : "mcp",
39
+ "server_label":"cafiero-dockagent",
40
+ "server_url":"https://cafierom-dockagent.hf.space/gradio_api/mcp/",
41
+ "require_approval": "never",
42
+ "allowed_tools": ["DockAgent_DockAgent"],
43
+ },
44
+ ]
45
+
46
+ chat_history = []
47
+ global last_id
48
+ last_id = None
49
+
50
+ def chat(prompt, tools, voice_choice):
51
+ chat_history.append(
52
+ {"role": "user", "content": prompt}
53
+ )
54
+ global last_id
55
+
56
+ if tools == "Yes":
57
+ if (last_id != None):
58
+ response = client.responses.create(
59
+ model = "o4-mini",
60
+ tools = cafchem_tools,
61
+ input=prompt,
62
+ previous_response_id = last_id
63
+ )
64
+ else:
65
+ response = client.responses.create(
66
+ model = "o4-mini",
67
+ tools = cafchem_tools,
68
+ input=prompt
69
+ )
70
+ else:
71
+ if (last_id != None):
72
+ response = client.responses.create(
73
+ model = "o4-mini",
74
+ input=prompt,
75
+ previous_response_id = last_id
76
+ )
77
+ else:
78
+ response = client.responses.create(
79
+ model = "o4-mini",
80
+ input=prompt
81
+ )
82
+
83
+ chat_history.append(
84
+ {"role": "assistant", "content": response.output_text}
85
+ )
86
+ last_id = response.id
87
+
88
+ if voice_choice == "On":
89
+ elita_text = response.output_text
90
+
91
+ voice_settings = {
92
+ "stability": 0.37,
93
+ "similarity_boost": 0.90,
94
+ "style": 0.0,
95
+ "speed": 1.05
96
+ }
97
+
98
+ audio_stream = elevenlabs.text_to_speech.convert(
99
+ text = elita_text,
100
+ voice_id = 'vxO9F6g9yqYJ4RsWvMbc',
101
+ model_id = 'eleven_multilingual_v2',
102
+ output_format='mp3_44100_128',
103
+ voice_settings=voice_settings
104
+ )
105
+
106
+ audio_converted = b"".join(audio_stream)
107
+ audio = base64.b64encode(audio_converted).decode("utf-8")
108
+ audio_player = f'<audio src="data:audio/mpeg;base64,{audio}" controls autoplay></audio>'
109
+ else:
110
+ audio_player = ''
111
+
112
+ return "", chat_history, audio_player
113
+
114
+ def clear_history():
115
+ global chat_history
116
+ chat_history = []
117
+ global last_id
118
+ last_id = None
119
+
120
+ def voice_from_file(file_name):
121
+ audio_file = file_name
122
+ with open(audio_file, 'rb') as audio_bytes:
123
+ audio = base64.b64encode(audio_bytes.read()).decode("utf-8")
124
+ audio_player = f'<audio src="data:audio/mpeg;base64,{audio}" controls autoplay></audio>'
125
+ return audio_player
126
+
127
+ def prot_workflow():
128
+ elita_text = "Starting with a protein, try searching for Uniprot IDs, followed by Chembl IDs. \
129
+ Then you can look for bioactive molecules for each Chembl ID. You can also search for crystal structures \
130
+ in the PDB and get titles of those structures, sequences, numbers of chains, and small molecules in the structure. \
131
+ Generate novel bioactive molecules based on a protein Chembl ID using a GPT, or predict an IC50 for a molecule \
132
+ based on a protein Chembl ID using a gradient-boosting model."
133
+ messages = [{'role': 'assistant', 'content': elita_text}]
134
+ audio_player = voice_from_file('protein_chat.mp3')
135
+ return audio_player, messages
136
+
137
+ def mol_workflow():
138
+ elita_text = "Starting with a molecule, try finding it's Lipinski properties, or its pharmacophore similarity to a known active. \
139
+ Find similar molecules or, if it has substituted rings, find analogues."
140
+ messages = [{'role': 'assistant', 'content': elita_text}]
141
+ audio_player = voice_from_file('mol_wf.mp3')
142
+ return audio_player, messages
143
+
144
+ def combo_workflow():
145
+ elita_text ="Starting with a protein and a molecule, try docking the molecule in the protein. If you have a Chembl ID, predict the IC50 \
146
+ value of the molecule in the protein."
147
+ messages = [{'role': 'assistant', 'content': elita_text}]
148
+ audio_player = voice_from_file('combo_wf.mp3')
149
+ return audio_player, messages
150
+
151
+ def prot_accordions():
152
+ elita_text = 'Try queries like: find UNIPROT IDs for the protein MAOB; find PDB IDs for MAOB; how many chains \
153
+ are in the PDB structure 4A7G; find PDB IDs matching the protein MAOB; list the bioactive molecules for the CHEMBL \
154
+ ID CHEMBL2039; dock the molecule CCCC(F) in the protein DRD2; predict the IC50 value for CCCC(F) based on the CHEMBL \
155
+ ID CHEMBL2039; or generate novel molecules based on the CHEMBL ID CHEMBL2039.'
156
+ messages = [{'role': 'assistant', 'content': elita_text}]
157
+ audio_player = voice_from_file('protein.mp3')
158
+ return audio_player, messages
159
+
160
+ def mol_accordions():
161
+ elita_text = 'Try queries like: Find the name of CCCF, find the smiles for paracetamol, or find molecules similar to paracetamol.'
162
+ messages = [{'role': 'assistant', 'content': elita_text}]
163
+ audio_player = voice_from_file('mol.mp3')
164
+ return audio_player, messages
165
+
166
+ def prop_accordions():
167
+ elita_text = 'Try queries like: Find Lipinski properties for CCCF, find pharmacophore-similarity between \
168
+ CCCF and CCCBr, or generate analogues of c1ccc(O)cc1.'
169
+ messages = [{'role': 'assistant', 'content': elita_text}]
170
+ audio_player = voice_from_file('Props.mp3')
171
+ return audio_player, messages
172
+
173
+ def dock_accordions():
174
+ elita_text = 'Try queries like: dock CCC(F) in the protein MAOB'
175
+ messages = [{'role': 'assistant', 'content': elita_text}]
176
+ audio_player = voice_from_file('Dock.mp3')
177
+ return audio_player, messages
178
+
179
+ with gr.Blocks() as forest:
180
+ gr.Markdown(
181
+ """
182
+ # Chat with MoDrAg! OpenAI 04-mini can tap into Modrag through an MCP and use all of your favourite drug design tools.
183
+ - Currently using the tools below:
184
+ """)
185
+ with gr.Row():
186
+ with gr.Accordion("Protein Agent - Click to open/close.", open=False)as prot:
187
+ gr.Markdown('''
188
+ - Find Uniprot IDs for a protein/gene name.
189
+ - report the number of bioactive molecules for a protein, organized by Chembl ID.
190
+ - report the SMILES and IC50 values of bioactive molecules for a particular Chembl ID.
191
+ - find protein sequences, report number fo chains.
192
+ - find small molecules present in a PDB structure.
193
+ - find PDB IDs that match a protein.
194
+ - predict the IC50 value of a small molecule based on a Chembl ID.
195
+ - generate novel molecules based on a Chembl ID.
196
+ ''')
197
+ with gr.Accordion("Molecule Agent - Click to open/close.", open=False) as mol:
198
+ gr.Markdown('''
199
+ - find the name of a molecule from the SMILES string.
200
+ - find the SMILES string of a molecule from the name
201
+ - find similar or related molecules with some basic properties from a name or SMILES.
202
+ ''')
203
+ with gr.Accordion("Property Agent - Click to open/close.", open=False) as prop:
204
+ gr.Markdown('''
205
+ - calculate Lipinski properties from a SMILES string.
206
+ - find the pharmacophore-similarity between two molecules (a molecule and a reference).
207
+ - generate analogues of ring molecules and report their QED values.
208
+ ''')
209
+ with gr.Accordion("Docking Agent - Click to open/close.", open=False) as dock:
210
+ gr.Markdown('''
211
+ - Find the docking score and pose coordinates for a molecules defined by a SMILES string in on of the proteins below:
212
+ - IGF1R,JAK2,KIT,LCK,MAPK14,MAPKAPK2,MET,PTK2,PTPN1,SRC,ABL1,AKT1,AKT2,CDK2,CSF1R,EGFR,KDR,MAPK1,FGFR1,ROCK1,MAP2K1,
213
+ PLK1,HSD11B1,PARP1,PDE5A,PTGS2,ACHE,MAOB,CA2,GBA,HMGCR,NOS1,REN,DHFR,ESR1,ESR2,NR3C1,PGR,PPARA,PPARD,PPARG,AR,THRB,
214
+ ADAM17,F10,F2,BACE1,CASP3,MMP13,DPP4,ADRB1,ADRB2,DRD2,DRD3,ADORA2A,CYP2C9,CYP3A4,HSP90AA1
215
+ ''')
216
+ with gr.Row():
217
+ molecule_workflow = gr.Button(value = "Sample Molecule Workflow")
218
+ protein_workflow = gr.Button(value = "Sample Protein Workflow")
219
+ combined_workflow = gr.Button(value = "Sample Combined Workflow")
220
+
221
+ with gr.Row():
222
+ tools = gr.Radio(choices = ["Yes", "No"],label="Use CafChem tools?",interactive=True, value = "Yes", scale = 2)
223
+ voice_choice = gr.Radio(choices = ['On', 'Off'],label="Audio Voice Response?", interactive=True, value='Off', scale = 2)
224
+
225
+ chatbot = gr.Chatbot()
226
+
227
+ with gr.Row():
228
+ msg = gr.Textbox(label="Type your messages here and hit enter.", scale = 2)
229
+ chat_btn = gr.Button(value = "Send", scale = 0)
230
+ elitas_voice = gr.HTML()
231
+
232
+ clear = gr.ClearButton([msg, chatbot])
233
+
234
+ chat_btn.click(chat, [msg, tools, voice_choice], [msg, chatbot, elitas_voice])
235
+ msg.submit(chat, [msg, tools, voice_choice], [msg, chatbot, elitas_voice])
236
+ mol.expand(mol_accordions, outputs = [talk_ele, chatbot])
237
+ prop.expand(prop_accordions, outputs = [talk_ele, chatbot])
238
+ prot.expand(prot_accordions, outputs = [talk_ele, chatbot])
239
+ dock.expand(dock_accordions, outputs = [talk_ele, chatbot])
240
+ molecule_workflow.click(mol_workflow, outputs = [talk_ele, chatbot])
241
+ protein_workflow.click(prot_workflow, outputs = [talk_ele, chatbot])
242
+ combined_workflow.click(combo_workflow, outputs = [talk_ele, chatbot])
243
+ clear.click(clear_history)
244
+
245
+ if __name__ == "__main__":
246
+ forest.launch(debug=False, share=True)