agent_chatbot / app.py
NeoPy's picture
Update app.py
475a9ce verified
import gradio as gr
from gradio import ChatMessage
from typing import Iterator, List
import google.generativeai as genai
import os
genai.configure(api_key=os.environ.get("GEMINI_API_KEY"))
system_instruction = "You are a helpful AI assistant."
model = genai.GenerativeModel(
"gemini-2.0-flash-thinking-exp-1219",
system_instruction=system_instruction
)
def add_user_message(user_msg: str, messages: List[ChatMessage]) -> List[ChatMessage]:
"""
Adds the user's message to the chat history.
"""
messages.append(ChatMessage(role="user", content=user_msg))
return messages
def stream_gemini_response(
user_message: str,
chat_session: genai.ChatSession,
messages: List[ChatMessage]
) -> Iterator[List[ChatMessage]]:
"""
Streams both thoughts and responses from the Gemini model using the chat session.
Handles errors gracefully.
"""
try:
# Generate response using the chat session for history management
response = chat_session.send_message(user_message, stream=True)
# Initialize buffers
thought_buffer = ""
response_buffer = ""
thinking_complete = False
# Add initial thinking message
messages.append(
ChatMessage(
role="assistant",
content="",
metadata={"title": "⏳ Thinking: *The thoughts produced by the Gemini 2.0 Flash model are experimental*"}
)
)
yield messages
for chunk in response:
if not hasattr(chunk, 'candidates') or not chunk.candidates:
continue # Skip invalid chunks
parts = chunk.candidates[0].content.parts
if not parts:
continue
current_chunk = parts[0].text
if len(parts) == 2 and not thinking_complete:
# Complete thought and start response
thought_buffer += current_chunk
messages[-1] = ChatMessage(
role="assistant",
content=thought_buffer,
metadata={"title": "⏳ Thinking: *The thoughts produced by the Gemini 2.0 Flash model are experimental*"}
)
# Add response message
messages.append(
ChatMessage(
role="assistant",
content=parts[1].text
)
)
thinking_complete = True
elif thinking_complete:
# Continue streaming response
response_buffer += current_chunk
messages[-1] = ChatMessage(
role="assistant",
content=response_buffer
)
else:
# Continue streaming thoughts
thought_buffer += current_chunk
messages[-1] = ChatMessage(
role="assistant",
content=thought_buffer,
metadata={"title": "⏳ Thinking: *The thoughts produced by the Gemini 2.0 Flash model are experimental*"}
)
yield messages
except Exception as e:
# Handle errors by appending an error message
error_msg = f"Error: {str(e)}"
messages.append(
ChatMessage(
role="assistant",
content=error_msg
)
)
yield messages
def reset_chat() -> tuple[List[ChatMessage], genai.ChatSession]:
"""
Resets the chat history and starts a new chat session.
"""
return [], model.start_chat()
with gr.Blocks() as demo:
gr.Markdown("# Chat with Gemini 2.0 Flash and See its Thoughts 💭")
chatbot = gr.Chatbot(
type="messages",
label="Gemini 2.0 'Thinking' Chatbot",
render_markdown=True,
height=500
)
input_box = gr.Textbox(
lines=1,
label="Chat Message",
placeholder="Type your message here and press Enter..."
)
clear_btn = gr.Button("Clear Chat")
# State variables
msg_store = gr.State("") # Temporary store for user message
chat_session = gr.State(model.start_chat()) # Chat session for history
# Event handlers
input_box.submit(
fn=lambda msg: msg, # Store the message
inputs=[input_box],
outputs=[msg_store],
queue=False
).then(
fn=lambda: "", # Clear the input box
outputs=[input_box],
queue=False
).then(
fn=add_user_message, # Add user message to chatbot
inputs=[msg_store, chatbot],
outputs=[chatbot],
queue=False
).then(
fn=stream_gemini_response, # Stream the response
inputs=[msg_store, chat_session, chatbot],
outputs=[chatbot]
)
# Clear button handler
clear_btn.click(
fn=reset_chat,
outputs=[chatbot, chat_session]
)
demo.launch()