MusaR commited on
Commit
386ca1b
·
verified ·
1 Parent(s): 162852d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +53 -43
app.py CHANGED
@@ -7,17 +7,24 @@ 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
- # --- 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; 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; min-height: 450px; }
18
- .message-bubble.user { background: #2563EB !important; color: white; }
19
- .message-bubble.bot { background: #FFFFFF !important; color: #334155; border: 1px solid #E2E8F0; }
 
20
  footer { display: none !important; }
 
 
 
 
 
 
21
  """
22
 
23
  # --- Model Initialization ---
@@ -27,7 +34,7 @@ writer_model, planner_model, embedding_model, reranker, tavily_client = None, No
27
  def initialize_models(google_key, tavily_key):
28
  global writer_model, planner_model, embedding_model, reranker, tavily_client
29
  if not google_key or not tavily_key:
30
- raise gr.Error("API keys are required. Please provide both Google and Tavily API keys.")
31
  try:
32
  genai.configure(api_key=google_key)
33
  tavily_client = TavilyClient(api_key=tavily_key)
@@ -35,93 +42,96 @@ def initialize_models(google_key, tavily_key):
35
  planner_model = genai.GenerativeModel(config.WRITER_MODEL)
36
  embedding_model = SentenceTransformer('all-MiniLM-L6-v2', device='cpu')
37
  reranker = CrossEncoder('cross-encoder/ms-marco-MiniLM-L-6-v2', device='cpu')
38
- return "Models initialized successfully!"
39
  except Exception as e:
40
  raise gr.Error(f"Failed to initialize models. Error: {str(e)}")
41
 
42
  # --- Gradio Application Logic ---
43
- with gr.Blocks(css=CSS, theme=gr.themes.Soft(primary_hue="blue", secondary_hue="slate")) as app:
44
  gr.Markdown("<h1>Mini DeepSearch Agent</h1>")
45
  gr.Markdown("<p class='sub-header'>Your AI partner for in-depth research and analysis.</p>")
46
 
 
 
 
47
  with gr.Accordion("API & Settings", open=True, elem_classes="accordion") as settings_accordion:
48
  with gr.Row():
49
  google_api_key_input = gr.Textbox(label="Google API Key", type="password", placeholder="Enter Google AI API Key", scale=2)
50
  tavily_api_key_input = gr.Textbox(label="Tavily API Key", type="password", placeholder="Enter Tavily Search API Key", scale=2)
51
- init_button = gr.Button("Initialize Agent", scale=1, variant="primary")
52
 
53
- initialization_status = gr.Markdown(visible=False)
54
-
55
  chatbot = gr.Chatbot(
56
  elem_id="chatbot",
57
  bubble_full_width=False,
58
  height=500,
59
- visible=False,
60
- type="messages" # Use the modern 'messages' format
61
  )
62
- chat_input = gr.Textbox(placeholder="Enter your research topic...", interactive=False, visible=False)
63
 
64
- # State variables
65
- agent_state = gr.State("INITIAL")
66
- initial_topic_state = gr.State("")
67
 
68
  def handle_initialization(google_key, tavily_key):
69
- init_status = initialize_models(google_key, tavily_key)
70
- initial_messages = [{"role": "assistant", "content": "Agent initialized. Please enter your research topic to begin."}]
71
  return {
72
- initialization_status: gr.update(value=f"**Status:** {init_status}", visible=True),
73
- chatbot: gr.update(visible=True, value=initial_messages),
74
  chat_input: gr.update(interactive=True, visible=True),
 
75
  settings_accordion: gr.update(open=False)
76
  }
77
 
78
  def chat_step(user_input, history, current_agent_state, topic_state):
79
- history.append({"role": "user", "content": user_input})
 
80
 
81
  if current_agent_state == "INITIAL":
82
- history.append({"role": "assistant", "content": "Thinking..."})
83
- yield history, "CLARIFYING", user_input, gr.update(interactive=False)
84
-
85
  questions = get_clarifying_questions(planner_model, user_input)
86
- 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}
87
- yield history, "CLARIFYING", user_input, gr.update(interactive=True)
88
 
89
  elif current_agent_state == "CLARIFYING":
90
- history.append({"role": "assistant", "content": "Generating full report..."})
91
- yield history, "GENERATING", topic_state, gr.update(interactive=False)
 
92
 
93
  try:
94
  plan = research_and_plan(config, planner_model, tavily_client, topic_state, user_input)
95
  report_generator = write_report_stream(config, writer_model, tavily_client, embedding_model, reranker, plan)
96
 
97
  status_updates = ""
98
- final_report_md = ""
99
  for update in report_generator:
100
- final_report_md = update if "Report Generation Complete" not in update else final_report_md
101
  status_updates += update
102
- history[-1] = {"role": "assistant", "content": status_updates}
103
  yield history, "GENERATING", topic_state, gr.update(interactive=False)
104
 
105
- history.append({"role": "assistant", "content": final_report_md})
106
- yield history, "INITIAL", "", gr.update(interactive=True)
 
107
 
108
  except Exception as e:
109
  error_message = f"An error occurred: {str(e)}"
110
- history.append({"role": "assistant", "content": error_message})
111
- yield history, "INITIAL", "", gr.update(interactive=True)
112
 
113
  init_button.click(
114
  fn=handle_initialization,
115
  inputs=[google_api_key_input, tavily_api_key_input],
116
- outputs=[initialization_status, chatbot, chat_input, settings_accordion]
117
  )
118
 
 
 
 
 
 
119
  chat_input.submit(
120
  fn=chat_step,
121
  inputs=[chat_input, chatbot, agent_state, initial_topic_state],
122
  outputs=[chatbot, agent_state, initial_topic_state, chat_input]
123
- ).then(
124
- lambda: "", None, chat_input, queue=False
125
  )
126
 
 
 
 
 
127
  app.launch(debug=True)
 
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, ChatGPT-inspired look ---
11
  CSS = """
12
+ body, .gradio-container { font-family: 'Inter', sans-serif; background-color: #343541; color: #ECECEC; }
13
+ .gradio-container { max-width: 800px !important; margin: auto !important; padding-top: 2rem !important;}
14
+ h1 { text-align: center; font-weight: 700; font-size: 2.5em; color: white; }
15
+ .sub-header { text-align: center; color: #C5C5D2; margin-bottom: 2rem; font-size: 1.1em; }
16
+ .accordion { background-color: #40414F; border: 1px solid #565869 !important; border-radius: 8px !important; }
17
+ .accordion .gr-button { background-color: #4B4C5A; color: white; }
18
+ #chatbot { box-shadow: none !important; border: none !important; background-color: transparent !important; }
19
+ .message-bubble { background: #40414F !important; border: 1px solid #565869 !important; color: #ECECEC !important;}
20
+ .message-bubble.user { background: #343541 !important; border: none !important; }
21
  footer { display: none !important; }
22
+ .gr-box.gradio-container { padding: 0 !important; }
23
+ .gr-form { background-color: transparent !important; border: none !important; box-shadow: none !important; }
24
+ .gradio-container .gr-form .gr-button { display: none; } /* Hide the default submit button */
25
+ #chat-input-container { position: relative; }
26
+ #chat-input-container textarea { background-color: #40414F; color: white; border: 1px solid #565869 !important; }
27
+ #submit-button { position: absolute; right: 10px; top: 50%; transform: translateY(-50%); background: #2563EB; color: white; border-radius: 4px; padding: 4px 8px; }
28
  """
29
 
30
  # --- Model Initialization ---
 
34
  def initialize_models(google_key, tavily_key):
35
  global writer_model, planner_model, embedding_model, reranker, tavily_client
36
  if not google_key or not tavily_key:
37
+ raise gr.Error("API keys are required.")
38
  try:
39
  genai.configure(api_key=google_key)
40
  tavily_client = TavilyClient(api_key=tavily_key)
 
42
  planner_model = genai.GenerativeModel(config.WRITER_MODEL)
43
  embedding_model = SentenceTransformer('all-MiniLM-L6-v2', device='cpu')
44
  reranker = CrossEncoder('cross-encoder/ms-marco-MiniLM-L-6-v2', device='cpu')
 
45
  except Exception as e:
46
  raise gr.Error(f"Failed to initialize models. Error: {str(e)}")
47
 
48
  # --- Gradio Application Logic ---
49
+ with gr.Blocks(css=CSS, theme=gr.themes.Base()) as app:
50
  gr.Markdown("<h1>Mini DeepSearch Agent</h1>")
51
  gr.Markdown("<p class='sub-header'>Your AI partner for in-depth research and analysis.</p>")
52
 
53
+ agent_state = gr.State("INITIAL")
54
+ initial_topic_state = gr.State("")
55
+
56
  with gr.Accordion("API & Settings", open=True, elem_classes="accordion") as settings_accordion:
57
  with gr.Row():
58
  google_api_key_input = gr.Textbox(label="Google API Key", type="password", placeholder="Enter Google AI API Key", scale=2)
59
  tavily_api_key_input = gr.Textbox(label="Tavily API Key", type="password", placeholder="Enter Tavily Search API Key", scale=2)
60
+ init_button = gr.Button("Initialize Agent", scale=1)
61
 
 
 
62
  chatbot = gr.Chatbot(
63
  elem_id="chatbot",
64
  bubble_full_width=False,
65
  height=500,
66
+ visible=False
 
67
  )
 
68
 
69
+ with gr.Row(elem_id="chat-input-container"):
70
+ chat_input = gr.Textbox(placeholder="What would you like to research?", interactive=False, visible=False, show_label=False, scale=8)
71
+ submit_button = gr.Button("Submit", elem_id="submit-button", visible=False, scale=1)
72
 
73
  def handle_initialization(google_key, tavily_key):
74
+ initialize_models(google_key, tavily_key)
 
75
  return {
76
+ chatbot: gr.update(visible=True, value=[(None, "Agent initialized. Please enter your research topic to begin.")]),
 
77
  chat_input: gr.update(interactive=True, visible=True),
78
+ submit_button: gr.update(visible=True),
79
  settings_accordion: gr.update(open=False)
80
  }
81
 
82
  def chat_step(user_input, history, current_agent_state, topic_state):
83
+ history = history or []
84
+ history.append((user_input, None))
85
 
86
  if current_agent_state == "INITIAL":
87
+ yield history, "CLARIFYING", user_input, gr.update(interactive=False, placeholder="Thinking...")
 
 
88
  questions = get_clarifying_questions(planner_model, user_input)
89
+ history[-1] = (user_input, "To give you the best report, could you answer these questions for me?\n\n" + questions)
90
+ yield history, "CLARIFYING", user_input, gr.update(interactive=True, placeholder="Provide your answers to the questions above...")
91
 
92
  elif current_agent_state == "CLARIFYING":
93
+ thinking_message = "Got it. Generating your full research report. This will take a moment..."
94
+ history[-1] = (user_input, thinking_message)
95
+ yield history, "GENERATING", topic_state, gr.update(interactive=False, placeholder="Generating...")
96
 
97
  try:
98
  plan = research_and_plan(config, planner_model, tavily_client, topic_state, user_input)
99
  report_generator = write_report_stream(config, writer_model, tavily_client, embedding_model, reranker, plan)
100
 
101
  status_updates = ""
 
102
  for update in report_generator:
 
103
  status_updates += update
104
+ history[-1] = (user_input, status_updates)
105
  yield history, "GENERATING", topic_state, gr.update(interactive=False)
106
 
107
+ full_report = status_updates # The final state of the stream is the report
108
+ history.append((None, full_report))
109
+ yield history, "INITIAL", "", gr.update(interactive=True, placeholder="Research complete. What's the next topic?")
110
 
111
  except Exception as e:
112
  error_message = f"An error occurred: {str(e)}"
113
+ history.append((None, error_message))
114
+ yield history, "INITIAL", "", gr.update(interactive=True, placeholder="Let's try again. What's the topic?")
115
 
116
  init_button.click(
117
  fn=handle_initialization,
118
  inputs=[google_api_key_input, tavily_api_key_input],
119
+ outputs=[chatbot, chat_input, submit_button, settings_accordion]
120
  )
121
 
122
+ submit_action = submit_button.click(
123
+ fn=chat_step,
124
+ inputs=[chat_input, chatbot, agent_state, initial_topic_state],
125
+ outputs=[chatbot, agent_state, initial_topic_state, chat_input]
126
+ )
127
  chat_input.submit(
128
  fn=chat_step,
129
  inputs=[chat_input, chatbot, agent_state, initial_topic_state],
130
  outputs=[chatbot, agent_state, initial_topic_state, chat_input]
 
 
131
  )
132
 
133
+ # Clear input after submission
134
+ submit_action.then(lambda: "", None, chat_input)
135
+ chat_input.submit(lambda: "", None, chat_input)
136
+
137
  app.launch(debug=True)