File size: 5,117 Bytes
2f5bd22
 
2191d1d
2b3bb5c
2191d1d
2f5bd22
7daa048
2f5bd22
2191d1d
2f5bd22
2191d1d
 
 
 
 
 
7daa048
2191d1d
7daa048
2191d1d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7daa048
2191d1d
 
 
 
 
 
 
 
7daa048
2191d1d
 
7daa048
2191d1d
 
 
 
 
 
 
 
 
 
7daa048
2191d1d
 
 
 
 
 
7daa048
2191d1d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7daa048
 
2191d1d
 
 
 
 
 
 
7daa048
2191d1d
7daa048
2191d1d
2f5bd22
 
2191d1d
 
 
 
 
2f5bd22
475a9ce
7daa048
 
 
 
2191d1d
7daa048
2191d1d
7daa048
 
 
 
 
 
 
 
2191d1d
7daa048
2191d1d
 
 
 
 
7daa048
2191d1d
7daa048
2191d1d
7daa048
 
2191d1d
 
7daa048
 
2191d1d
7daa048
2191d1d
 
 
 
 
 
 
 
 
 
 
 
7daa048
2f5bd22
2191d1d
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
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()