Spaces:
Sleeping
Sleeping
File size: 9,438 Bytes
777550f de23a1a 777550f de23a1a 777550f de23a1a 777550f 27b23e1 777550f de23a1a 777550f 7739a39 777550f de23a1a 777550f de23a1a 777550f de23a1a | 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 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 | import gradio as gr
import os
from dotenv import load_dotenv
import uuid
load_dotenv(override=True)
from research_assistant import graph as compiled_graph
def start_research(topic:str, max_analysts:int=3, key:str=""):
if key != os.getenv("RESEARCH_KEY"):
return (
"β Invalid key. Please provide a valid key to use this service.",
gr.update(visible=True, interactive=True),
gr.update(visible=True),
gr.update(visible=True),
gr.update(visible=False),
gr.update(visible=True),
gr.update(value="", interactive=True) # clear key
)
global thread_id
thread_id = str(uuid.uuid4())
clean_state = {
"topic": topic,
"max_analysts": max_analysts,
"human_analyst_feedback": "",
"analysts": [],
"sections": [],
"introduction": "",
"content": "",
"conclusion": "",
"final_report": ""
}
try:
thread = {"configurable": {"thread_id": thread_id}}
result=compiled_graph.invoke(clean_state, thread)
return display_analysts_and_request_feedback(result)
except Exception as e:
return reset_to_start(result, f"β Error starting research: {str(e)}")
def display_analysts_and_request_feedback(result):
analysts= result.get('analysts',[])
if analysts:
analysts_display="\n".join([
f"**{i+1}. {analyst.name}**\n"
f" - Role: {analyst.role}\n"
f" - Affiliation: {analyst.affiliation}\n"
f" - Description: {analyst.description}\n"
for i, analyst in enumerate(analysts)
])
feedback_prompt = (
f"## Analysts Generated for: '{result['topic']}'\n\n"
f"{analysts_display}\n\n"
f"**Please provide your feedback:**\n"
f"- Type 'approve' to continue with these analysts\n"
f"- Or provide specific feedback to regenerate analysts\n"
f"- Example: 'Add a cybersecurity expert, remove the marketing analyst'"
)
return (
feedback_prompt,
gr.update(visible=True, value="", interactive=True),
gr.update(visible=True),
gr.update(visible=True),
gr.update(visible=False),
gr.update(visible=True), # reset_btn
gr.update(value="", interactive=True) # clear key
)
else:
return reset_to_start(result, "β No Analysts generated. Please try again with a different topic.")
def continue_with_feedback(feedback, button_clicked):
if button_clicked == "research":
feedback= "approve"
try:
thread = {"configurable": {"thread_id": thread_id}}
compiled_graph.update_state(
thread,
{"human_analyst_feedback": feedback},
as_node="human_feedback"
)
result=compiled_graph.invoke(None, thread)
state= compiled_graph.get_state(thread)
if state.next and state.next[0] == "human_feedback":
return display_analysts_and_request_feedback(result)
else:
print("Going to display final report")
return display_final_report(result)
except Exception as e:
return reset_to_start(result, f"β Error processing feedback: {str(e)}")
def display_final_report(result):
"""Muestra el reporte final y resetea la interfaz"""
print("Displaying final report...")
try:
final_report = result.get("final_report", "")
print(f"Final report content: {final_report}")
if final_report:
return (
f"## π Final Research Report\n\n{final_report}",
gr.update(visible=False), # feedback_input
gr.update(visible=False), # continue_btn
gr.update(visible=False),
gr.update(visible=False),
gr.update(visible=True), # reset_btn
gr.update(value="", interactive=True) # clear key_input
)
else:
return reset_to_start(result, "β Error: No final report was generated.")
except Exception as e:
return reset_to_start(result, f"β Error displaying final report: {str(e)}")
def reset_to_start(result, message=""):
"""Resetea la interfaz al estado inicial"""
return (
message,
gr.update(visible=False, value="", interactive=True), # feedback_input
gr.update(visible=False), # continue_btn
gr.update(visible=False),
gr.update(visible=False),
gr.update(value="", interactive=True), # clear key_input
gr.update(visible=False)
# start_btn
)
def reset_interface():
return (
"", # output1
gr.update(visible=False, value="", interactive=True), # feedback_input
gr.update(visible=False), # continue_btn
gr.update(visible=False), # continue_research_btn
gr.update(visible=True), # start_btn
gr.update(visible=True, value=""), # topic
gr.update(visible=True) # max_analysts
)
############################################## Gradio UI #########################################################################
with gr.Blocks(title="Research Assistant", theme=gr.themes.Soft()) as app:
gr.Markdown("<h1 style='font-size:2.8em; margin-bottom: 0.2em;'>π€ Research Assistant</h1>")
gr.Markdown("Assistant for researching complex topics. Process:\n"
"1. Provide a research topic and the maximum number of analysts, who will research different subtopics related to your topic.\n"
"2. The assistant will generate a summary of the analysts and their roles and subtopics in the research.\n"
"3. Provide feedback on the subtopics and the generated analysts.\n"
"4. If you agree with the analysts, click on the 'Create Research with Analysts' button \n"
"5. The assistant will generate a final research report.\n\n")
with gr.Row():
with gr.Column(scale=3):
topic_textbox = gr.Textbox(label="Topic to research", placeholder="Enter the topic you want to research", value="")
with gr.Column(scale=1):
max_analysts_slider = gr.Slider(minimum=1, maximum=5, step=1, value=3, label="Max Analysts", info="Maximum number of analysts to select for the research")
with gr.Row():
key_input = gr.Textbox(label="Key to use this service: ", placeholder="Enter your key here", value="", type="password")
with gr.Row():
with gr.Column(scale=3):
gr.Markdown("#Provide Feedback on the Analysts who will perform the research. If you agree with the analysts, click on the 'Create Research with Analysts' button")
feedback_input = gr.Textbox(label="Feedback", placeholder="Provide your feedback or click on the 'Create Research with Analysts' button", visible=False, value="")
with gr.Column(scale=1):
reset_btn = gr.Button("π Reset", variant="secondary", visible=False)
with gr.Row():
with gr.Column(scale=1):
start_button = gr.Button("π Start Research", variant="primary", visible=True)
continue_feedback_btn = gr.Button("β
Re-generate Analysts with Feedback", variant="primary", visible=False)
with gr.Column(scale=1):
continue_research_btn = gr.Button("β‘οΈ Create Research with Analysts", variant="primary", visible=False)
output1=gr.Markdown(label="Analysts Summary", value="")
#########################################################################################
start_button.click(
fn=start_research,
inputs=[topic_textbox, max_analysts_slider, key_input],
outputs=[output1, feedback_input, continue_feedback_btn, continue_research_btn, start_button, reset_btn, key_input]
)
continue_feedback_btn.click(
fn=lambda feedback: continue_with_feedback(feedback, "feedback"),
inputs=[feedback_input],
outputs=[output1, feedback_input, continue_feedback_btn, continue_research_btn, start_button, reset_btn, key_input]
)
continue_research_btn.click(
fn=lambda feedback: continue_with_feedback(feedback, "research"),
inputs=[feedback_input],
outputs=[output1, feedback_input, continue_feedback_btn, continue_research_btn, start_button, reset_btn, key_input]
)
reset_btn.click(
reset_interface,
outputs=[output1, feedback_input, continue_feedback_btn, continue_research_btn, start_button, topic_textbox, max_analysts_slider, key_input]
)
#################################################################################################################################
if __name__ == "__main__":
# Get port from environment variable (Railway sets this)
port = int(os.getenv("PORT", 7860)) # Changed default to match Dockerfile
# Launch the app
print(f"Starting application on port {port}")
app.launch(
server_name="0.0.0.0",
server_port=7860,
share=False,
show_error=True,
inbrowser=True
)
|