Spaces:
Sleeping
Sleeping
File size: 7,992 Bytes
47b7765 dd502d9 8450f7b ea352db 8450f7b ea352db 2ef477b d705d38 6d23bce 6d910d5 3e6d38c 8450f7b d705d38 e61e3e2 14c7c47 d705d38 8450f7b 41c607d d705d38 500156a 41c607d 757f397 e61e3e2 2ef477b e61e3e2 41c607d ea352db efa0b1f 32553dc 860758d 32553dc ea352db 9d5c51f e61e3e2 93f4c21 e61e3e2 93f4c21 32553dc e61e3e2 93f4c21 e61e3e2 860758d 8450f7b 32553dc 55c357e 7ff33ff ea352db e61e3e2 ea352db e61e3e2 ea352db e61e3e2 41c607d 2b2e182 e61e3e2 2b2e182 e61e3e2 41c607d cbee133 41c607d 7ff33ff 41c607d 2ef477b e858d01 2ef477b efa0b1f 2b2e182 b41cccb 2b2e182 d6e3b0b 4052a3c bb65cff 860758d 55c357e fd08cdc 93f4c21 fd08cdc 47b7765 55c357e |
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 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 |
import gradio as gr
from openai import OpenAI
import os
import base64
import time
import copy
import re
from dotenv import load_dotenv
# Load environment variables from .env file
load_dotenv()
from agents import rag_decision
from agents import get_top_k
from agents import get_prescription_text
from prompts import bot_welcome_message, openai_opening_system_message
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
with gr.Blocks() as demo:
################################ AGENTS ###################################
# Agent1 - RAG Decision Agent (whether RAG is needed for the user's query)
def agent1_rag_decision(query):
decision = rag_decision(query)
return decision
# Agent2 - RAG Retrieval Agent (retrieve top k relevant documents)
def agent2_use_rag(query, k=3):
results = get_top_k(query, k=k)
return results
# Agent3 - LLM Agent (get query response from LLM)
def agent3_llm_agent(messages):
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=messages,
temperature=0.7
)
return response.choices[0].message.content.strip()
def agent4_get_prescription_text(messages):
"""
Openai agent to get prescription text.
"""
prescription_text = get_prescription_text(messages)
return prescription_text
###########################################################################
def encode_image(image_path):
with open(image_path, "rb") as f:
return base64.b64encode(f.read()).decode("utf-8")
def load_welcome():
history = []
history.append({"role": "system", "content": openai_opening_system_message})
history.append({"role": "assistant", "content": bot_welcome_message})
return history
def clear_and_load():
# Return the welcome message
history = []
history.append({"role": "system", "content": openai_opening_system_message})
history.append({"role": "assistant", "content": bot_welcome_message})
return history, None
def add_message(history, message):
# Send the image to the agent4_get_prescription_text
messages = []
if message["text"] is not None:
messages.append({
"role": "user",
"content":[{"type": "text", "text": message["text"]}]
})
for x in message["files"]:
encoded_content = encode_image(x)
messages[0]["content"].append({
"type": "image_url",
"image_url": {"url": f"data:image/jpeg;base64,{encoded_content}"}
})
history.append({"role": "user", "content": {"path": x}})
# call agent4_get_prescription_text if there is an image_url in the message
has_image_url = any("image_url" in item for item in messages[0]["content"])
if has_image_url:
prescription_text = agent4_get_prescription_text(messages)
history.append({"role": "system", "content": prescription_text})
if message["text"] is not None:
history.append({"role": "user", "content": message["text"]})
return history, gr.MultimodalTextbox(value=None, interactive=False, file_count="multiple", placeholder="Enter message or upload file...")
def respond(history):
if len(history) == 2:
history.insert(0,{"role": "system", "content": openai_opening_system_message})
messages = copy.deepcopy(history)
for i, msg in enumerate(messages):
if isinstance(msg["content"], str):
# If the content is a string, encode it
messages[i]["content"] = [{
"type": "text",
"text": msg["content"]
}]
if isinstance(msg["content"],tuple):
# If the content is a file path, encode it
# file_path = msg["content"][0]
# encoded_content = encode_image(file_path)
messages[i]["content"] = [{
"type": "text",
"text": "User Image"}]
clean_messages = [] # OpenAI doesnot accept metadata or options in messages
for msg in messages:
clean_msg = {
"role": msg["role"],
"content": msg["content"]
}
clean_messages.append(clean_msg)
########################### AGENTIC WORKFLOW ##########################
# Call Agent1- the RAG Decision Agent
rag_query = ""
if clean_messages[-1]["role"] == "system" and "No prescription found" in clean_messages[-1]["content"]:
# If the last message is a system message with "No prescription found", skip RAG decision
rag_decision = False
elif clean_messages[-2]["role"] == "system" and "No prescription found" in clean_messages[-2]["content"]:
rag_decision = False
else:
# Get the last 10 messages in the format "role: <message>"
last_10 = clean_messages[-10:] if len(clean_messages) > 10 else clean_messages
rag_query = "\n".join(
f"{msg['role']}: {msg['content'][0]['text'] if isinstance(msg['content'], list) and msg['content'] and 'text' in msg['content'][0] else ''}"
for msg in last_10
)
rag_decision = agent1_rag_decision(rag_query)
if rag_decision == True:
#Call Agent2 - the RAG Retrieval Agent
top_k_results = agent2_use_rag(clean_messages[-1]["content"][0]["text"], k=5)
# Append the top k results to the messages
for i, result in enumerate(top_k_results):
clean_messages.append({
"role": "system",
"content": f"RAG Retrieved Result-{i+1}: " + result["content"]
})
# Call Agent3 - the LLM Agent to get query response
response = agent3_llm_agent(clean_messages)
else:
# Call Agent3 - the LLM Agent to get query response
response = agent3_llm_agent(clean_messages)
#######################################################################
# history.append({"role": "assistant", "content": response})
# return history
history.append({"role": "assistant", "content": ""})
# Split by sentence boundaries (naive but works for most cases)
chunks = re.split(r'(?<=[.!?]) +', response)
for chunk in chunks:
history[-1]["content"] += chunk + " "
time.sleep(0.3)
yield history
##########################################################################
gr.Markdown(
"""
<h1 style='text-align: center; font-size: 1.5em; color: #2c3e50; margin-bottom: 0.2em;'>
MedScan Diagnostic Services Chatbot (Agentic AI framework powered by OpenAI)
</h1>
"""
)
chatbot = gr.Chatbot(type="messages",
render_markdown=True,
height=380)
chat_input = gr.MultimodalTextbox(
interactive=True,
file_count="multiple",
placeholder="Enter message or upload file...",
show_label=False
)
clear = gr.Button("New Chat")
clear.click(
clear_and_load,
inputs=None,
outputs=[chatbot, chat_input]
)
demo.load(load_welcome, None, chatbot, api_name="load_welcome")
chat_msg = chat_input.submit(
add_message, [chatbot, chat_input], [chatbot, chat_input]
)
bot_msg = chat_msg.then(respond, chatbot, chatbot, api_name="bot_response")
bot_msg.then(lambda: gr.MultimodalTextbox(interactive=True), None, [chat_input])
if __name__ == "__main__":
demo.launch() |