MusaR commited on
Commit
d0a08f1
·
verified ·
1 Parent(s): cd70b8e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +54 -45
app.py CHANGED
@@ -7,17 +7,17 @@ from sentence_transformers import SentenceTransformer, CrossEncoder
7
  from research_agent.config import AgentConfig
8
  from research_agent.agent import get_clarifying_questions, research_and_plan, write_report_stream
9
 
10
- # --- Improved CSS for a professional chatbot look ---
11
  CSS = """
12
- body, .gradio-container { font-family: 'Inter', sans-serif; background-color: #F1F5F9; }
13
- .gradio-container { max-width: 800px !important; margin: auto !important; }
14
  h1 { text-align: center; font-weight: 700; font-size: 2.5em; color: #1E293B; }
15
  .sub-header { text-align: center; color: #475569; margin-bottom: 20px; font-size: 1.1em; }
16
  .accordion { border: none !important; box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px -1px rgba(0, 0, 0, 0.1) !important; }
17
- .chat-window { min-height: 450px; }
18
- .message { box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px -1px rgba(0, 0, 0, 0.1) !important; }
19
- .message.user { background: #2563EB !important; color: white; border-bottom-right-radius: 2px !important; }
20
- .message.bot { background: #FFFFFF !important; color: #334155; border: 1px solid #E2E8F0; border-bottom-left-radius: 2px !important; }
21
  footer { display: none !important; }
22
  """
23
 
@@ -45,7 +45,7 @@ with gr.Blocks(css=CSS, theme=gr.themes.Soft(primary_hue="blue", secondary_hue="
45
  gr.Markdown("<h1>Mini DeepSearch Agent</h1>")
46
  gr.Markdown("<p class='sub-header'>Your AI partner for in-depth research and analysis.</p>")
47
 
48
- with gr.Accordion("API & Settings", open=True, elem_classes="accordion") as settings:
49
  with gr.Row():
50
  google_api_key_input = gr.Textbox(label="Google API Key", type="password", placeholder="Enter Google AI API Key", scale=2)
51
  tavily_api_key_input = gr.Textbox(label="Tavily API Key", type="password", placeholder="Enter Tavily Search API Key", scale=2)
@@ -59,79 +59,88 @@ with gr.Blocks(css=CSS, theme=gr.themes.Soft(primary_hue="blue", secondary_hue="
59
  label="Research Agent",
60
  bubble_full_width=False,
61
  height=500,
62
- avatar_images=(None, "https://www.gradio.app/images/logo.png"),
63
- visible=False
64
  )
65
- chat_input = gr.Textbox(placeholder="What topic would you like to research?", interactive=False, visible=False)
 
66
 
67
- # State Management
 
 
68
  agent_state = gr.State("INITIAL")
69
  initial_topic_state = gr.State("")
70
 
71
  def handle_initialization(google_key, tavily_key):
72
  init_status = initialize_models(google_key, tavily_key)
 
73
  return {
74
  initialization_status: gr.update(value=f"**Status:** {init_status}", visible=True),
75
- chatbot: gr.update(visible=True, value=[(None, "Agent initialized. Please enter your research topic to begin.")]),
 
76
  chat_input: gr.update(interactive=True, visible=True),
77
- settings: gr.update(open=False)
78
  }
79
 
80
- def chat_step(user_input, history):
81
- current_state = agent_state.value
82
- original_topic = initial_topic_state.value
83
-
84
- if current_state == "INITIAL":
85
  # 1. User provides the initial topic
86
- agent_state.update("CLARIFYING")
87
- initial_topic_state.update(user_input)
88
- history.append([user_input, None])
89
- yield history, gr.update(interactive=False, placeholder="Thinking...")
90
 
91
  questions = get_clarifying_questions(planner_model, user_input)
92
- history[-1][1] = "I can do that. To give you the best report, could you answer these questions for me?\n\n" + questions
93
- yield history, gr.update(interactive=True, placeholder="Provide your answers to the questions above...")
94
 
95
- elif current_state == "CLARIFYING":
96
  # 2. User provides answers to clarifying questions
97
- agent_state.update("GENERATING")
98
- history.append([user_input, None])
99
- yield history, gr.update(interactive=False, placeholder="Generating full report...")
 
100
 
101
  try:
102
- plan = research_and_plan(config, planner_model, tavily_client, original_topic, user_input)
103
  report_generator = write_report_stream(config, writer_model, tavily_client, embedding_model, reranker, plan)
104
 
105
  status_updates = ""
106
  final_report_md = ""
107
  for update in report_generator:
108
- if isinstance(update, str) and "Report Generation Complete" not in update:
109
- final_report_md = update # Keep track of the full report text
110
  status_updates += update
111
- history[-1][1] = status_updates # Stream thought process
112
- yield history, gr.update(interactive=False)
113
 
114
- history.append([None, final_report_md]) # Post the final report
115
- agent_state.update("INITIAL") # Reset for next query
116
- initial_topic_state.update("")
117
- yield history, gr.update(interactive=True, placeholder="Research complete. What's the next topic?")
118
 
119
  except Exception as e:
120
- history.append([None, f"An error occurred: {str(e)}"])
121
- agent_state.update("INITIAL")
122
- initial_topic_state.update("")
123
- yield history, gr.update(interactive=True, placeholder="Let's try again. What's the topic?")
 
 
 
 
 
124
 
125
  init_button.click(
126
  fn=handle_initialization,
127
  inputs=[google_api_key_input, tavily_api_key_input],
128
- outputs=[initialization_status, chatbot, chat_input, settings]
129
  )
130
 
131
  chat_input.submit(
132
  fn=chat_step,
133
- inputs=[chat_input, chatbot],
134
- outputs=[chatbot, chat_input]
135
  ).then(
136
  lambda: "", None, chat_input, queue=False
137
  )
 
7
  from research_agent.config import AgentConfig
8
  from research_agent.agent import get_clarifying_questions, research_and_plan, write_report_stream
9
 
10
+ # --- CSS for a professional chatbot look ---
11
  CSS = """
12
+ body, .gradio-container { font-family: 'Inter', sans-serif; }
13
+ .gradio-container { max-width: 800px !important; margin: auto !important; padding-top: 20px !important;}
14
  h1 { text-align: center; font-weight: 700; font-size: 2.5em; color: #1E293B; }
15
  .sub-header { text-align: center; color: #475569; margin-bottom: 20px; font-size: 1.1em; }
16
  .accordion { border: none !important; box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px -1px rgba(0, 0, 0, 0.1) !important; }
17
+ #chatbot { box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px -1px rgba(0, 0, 0, 0.1) !important; }
18
+ .message-bubble-container > .message-bubble { box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.05) !important; }
19
+ .message-bubble.user { background: #2563EB !important; color: white; }
20
+ .message-bubble.bot { background: #FFFFFF !important; color: #334155; border: 1px solid #E2E8F0; }
21
  footer { display: none !important; }
22
  """
23
 
 
45
  gr.Markdown("<h1>Mini DeepSearch Agent</h1>")
46
  gr.Markdown("<p class='sub-header'>Your AI partner for in-depth research and analysis.</p>")
47
 
48
+ with gr.Accordion("API & Settings", open=True, elem_classes="accordion") as settings_accordion:
49
  with gr.Row():
50
  google_api_key_input = gr.Textbox(label="Google API Key", type="password", placeholder="Enter Google AI API Key", scale=2)
51
  tavily_api_key_input = gr.Textbox(label="Tavily API Key", type="password", placeholder="Enter Tavily Search API Key", scale=2)
 
59
  label="Research Agent",
60
  bubble_full_width=False,
61
  height=500,
62
+ visible=False,
63
+ render=False # We will render it manually later
64
  )
65
+ # Use the modern 'messages' type for the chatbot state
66
+ chat_history_state = gr.State([])
67
 
68
+ chat_input = gr.Textbox(placeholder="Enter your research topic...", interactive=False, visible=False, render=False)
69
+
70
+ # Agent state can be: "INITIAL", "CLARIFYING", "GENERATING"
71
  agent_state = gr.State("INITIAL")
72
  initial_topic_state = gr.State("")
73
 
74
  def handle_initialization(google_key, tavily_key):
75
  init_status = initialize_models(google_key, tavily_key)
76
+ initial_message = {"role": "assistant", "content": "Agent initialized. Please enter your research topic to begin."}
77
  return {
78
  initialization_status: gr.update(value=f"**Status:** {init_status}", visible=True),
79
+ chatbot: gr.update(visible=True, value=[initial_message]),
80
+ chat_history_state: [initial_message],
81
  chat_input: gr.update(interactive=True, visible=True),
82
+ settings_accordion: gr.update(open=False)
83
  }
84
 
85
+ def chat_step(user_input, history, current_agent_state, topic_state):
86
+ history.append({"role": "user", "content": user_input})
87
+
88
+ if current_agent_state == "INITIAL":
 
89
  # 1. User provides the initial topic
90
+ new_agent_state = "CLARIFYING"
91
+ new_topic_state = user_input
92
+ history.append({"role": "assistant", "content": "Thinking..."})
93
+ yield history, history, new_agent_state, new_topic_state, gr.update(interactive=False)
94
 
95
  questions = get_clarifying_questions(planner_model, user_input)
96
+ history[-1] = {"role": "assistant", "content": "I can do that. To give you the best report, could you answer these questions for me?\n\n" + questions}
97
+ yield history, history, new_agent_state, new_topic_state, gr.update(interactive=True)
98
 
99
+ elif current_agent_state == "CLARIFYING":
100
  # 2. User provides answers to clarifying questions
101
+ new_agent_state = "GENERATING"
102
+ new_topic_state = topic_state
103
+ history.append({"role": "assistant", "content": "Generating full report..."})
104
+ yield history, history, new_agent_state, new_topic_state, gr.update(interactive=False)
105
 
106
  try:
107
+ plan = research_and_plan(config, planner_model, tavily_client, new_topic_state, user_input)
108
  report_generator = write_report_stream(config, writer_model, tavily_client, embedding_model, reranker, plan)
109
 
110
  status_updates = ""
111
  final_report_md = ""
112
  for update in report_generator:
113
+ final_report_md = update if "Report Generation Complete" not in update else final_report_md
 
114
  status_updates += update
115
+ history[-1] = {"role": "assistant", "content": status_updates}
116
+ yield history, history, new_agent_state, new_topic_state, gr.update(interactive=False)
117
 
118
+ history.append({"role": "assistant", "content": final_report_md})
119
+ new_agent_state = "INITIAL"
120
+ new_topic_state = ""
121
+ yield history, history, new_agent_state, new_topic_state, gr.update(interactive=True)
122
 
123
  except Exception as e:
124
+ error_message = f"An error occurred: {str(e)}"
125
+ history.append({"role": "assistant", "content": error_message})
126
+ new_agent_state = "INITIAL"
127
+ new_topic_state = ""
128
+ yield history, history, new_agent_state, new_topic_state, gr.update(interactive=True)
129
+
130
+ # Manually render components to control order
131
+ chatbot.render()
132
+ chat_input.render()
133
 
134
  init_button.click(
135
  fn=handle_initialization,
136
  inputs=[google_api_key_input, tavily_api_key_input],
137
+ outputs=[initialization_status, chatbot, chat_history_state, chat_input, settings_accordion]
138
  )
139
 
140
  chat_input.submit(
141
  fn=chat_step,
142
+ inputs=[chat_input, chat_history_state, agent_state, initial_topic_state],
143
+ outputs=[chatbot, chat_history_state, agent_state, initial_topic_state, chat_input]
144
  ).then(
145
  lambda: "", None, chat_input, queue=False
146
  )