Spaces:
Running
Running
File size: 6,181 Bytes
13654ed 7cc86bb 13654ed 7cc86bb 13654ed 7cc86bb 13654ed cc2e122 085c39f 13654ed 085c39f 13654ed 6ee5685 13654ed 7cc86bb 113d09a 6ee5685 13654ed 7cc86bb 13654ed 6ee5685 13654ed 6ee5685 13654ed 6ee5685 13654ed 6ee5685 13654ed 8b3ac93 13654ed e988524 7cc86bb 13654ed 6ee5685 13654ed |
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 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
import openai
import os
from openai import OpenAI
import gradio as gr
from elevenlabs.client import ElevenLabs
from elevenlabs import stream
import base64
api_key = os.getenv("OPENAI_API_KEY")
eleven_key = os.getenv("eleven_key")
elevenlabs = ElevenLabs(api_key=eleven_key)
client = OpenAI(api_key=api_key)
cafchem_tools = [
{
"type" : "mcp",
"server_label":"cafiero-proteinagent",
"server_url":"https://cafierom-proteinagent.hf.space/gradio_api/mcp/",
"require_approval": "never",
"allowed_tools": ["ProteinAgent_ProteinAgent"],
},
]
chat_history = []
global last_id
last_id = None
def chat(prompt, tools, voice_choice):
chat_history.append(
{"role": "user", "content": prompt}
)
global last_id
if tools == "Yes":
if (last_id != None):
response = client.responses.create(
model = "o4-mini",
tools = cafchem_tools,
input=prompt,
previous_response_id = last_id
)
else:
response = client.responses.create(
model = "o4-mini",
tools = cafchem_tools,
input=prompt
)
else:
if (last_id != None):
response = client.responses.create(
model = "o4-mini",
input=prompt,
previous_response_id = last_id
)
else:
response = client.responses.create(
model = "o4-mini",
input=prompt
)
chat_history.append(
{"role": "assistant", "content": response.output_text}
)
last_id = response.id
if voice_choice == "On":
elita_text = response.output_text
voice_settings = {
"stability": 0.37,
"similarity_boost": 0.90,
"style": 0.0,
"speed": 1.05
}
audio_stream = elevenlabs.text_to_speech.convert(
text = elita_text,
voice_id = 'vxO9F6g9yqYJ4RsWvMbc',
model_id = 'eleven_multilingual_v2',
output_format='mp3_44100_128',
voice_settings=voice_settings
)
audio_converted = b"".join(audio_stream)
audio = base64.b64encode(audio_converted).decode("utf-8")
audio_player = f'<audio src="data:audio/mpeg;base64,{audio}" controls autoplay></audio>'
else:
audio_player = ''
return "", chat_history, audio_player
def clear_history():
global chat_history
chat_history = []
global last_id
last_id = None
def voice_from_file(file_name):
audio_file = file_name
with open(audio_file, 'rb') as audio_bytes:
audio = base64.b64encode(audio_bytes.read()).decode("utf-8")
audio_player = f'<audio src="data:audio/mpeg;base64,{audio}" controls autoplay></audio>'
return audio_player
def prot_workflow():
elita_text = "Starting with a protein, try searching for Uniprot IDs, followed by Chembl IDs. \
Then you can look for bioactive molecules for each Chembl ID. You can also search for crystal structures \
in the PDB and get titles of those structures, sequences, numbers of chains, and small molecules in the structure. \
Generate novel bioactive molecules based on a protein Chembl ID using a GPT, or predict an IC50 for a molecule \
based on a protein Chembl ID using a gradient-boosting model."
messages = [{'role': 'assistant', 'content': elita_text}]
audio_player = voice_from_file('protein_chat.mp3')
return audio_player, messages
def prot_accordions():
elita_text = 'Try queries like: find UNIPROT IDs for the protein MAOB; find PDB IDs for MAOB; how many chains \
are in the PDB structure 4A7G; find PDB IDs matching the protein MAOB; list the bioactive molecules for the CHEMBL \
ID CHEMBL2039; dock the molecule CCCC(F) in the protein DRD2; predict the IC50 value for CCCC(F) based on the CHEMBL \
ID CHEMBL2039; or generate novel molecules based on the CHEMBL ID CHEMBL2039.'
messages = [{'role': 'assistant', 'content': elita_text}]
audio_player = voice_from_file('protein.mp3')
return audio_player, messages
with gr.Blocks() as forest:
gr.Markdown(
"""
# Chat with MoDrAg! OpenAI 04-mini can tap into Modrag through an MCP and use all of your favourite drug design tools.
- Currently using the tools below:
""")
with gr.Row():
with gr.Accordion("Protein Agent - Click to open/close.", open=False)as prot:
gr.Markdown('''
- Find Uniprot IDs for a protein/gene name.
- report the number of bioactive molecules for a protein, organized by Chembl ID.
- report the SMILES and IC50 values of bioactive molecules for a particular Chembl ID.
- find protein sequences, report number fo chains.
- find small molecules present in a PDB structure.
- find PDB IDs that match a protein.
- predict the IC50 value of a small molecule based on a Chembl ID.
- generate novel molecules based on a Chembl ID.
''')
workflow = gr.Button(value = "Sample Workflow")
with gr.Row():
tools = gr.Radio(choices = ["Yes", "No"],label="Use CafChem tools?",interactive=True, value = "Yes", scale = 2)
voice_choice = gr.Radio(choices = ['On', 'Off'],label="Audio Voice Response?", interactive=True, value='Off', scale = 2)
chatbot = gr.Chatbot()
with gr.Row():
msg = gr.Textbox(label="Type your messages here and hit enter.", scale = 2)
chat_btn = gr.Button(value = "Send", scale = 0)
elitas_voice = gr.HTML()
clear = gr.ClearButton([msg, chatbot])
chat_btn.click(chat, [msg, tools, voice_choice], [msg, chatbot, elitas_voice])
msg.submit(chat, [msg, tools, voice_choice], [msg, chatbot, elitas_voice])
workflow.click(prot_workflow, outputs=[elitas_voice, chatbot])
prot.expand(prot_accordions, outputs = [elitas_voice, chatbot])
clear.click(clear_history)
if __name__ == "__main__":
forest.launch(debug=False, share=True)
|