File size: 6,916 Bytes
fced645
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60702f2
 
 
 
 
 
 
 
 
fced645
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c53597d
fced645
 
 
 
 
 
c53597d
fced645
 
 
 
 
c53597d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
fced645
 
 
c53597d
fced645
 
c53597d
 
fced645
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
#!/usr/bin/env python3
"""
Gradio Interface for AI Agent Chat
Deployment-ready version for Hugging Face Spaces

To deploy on Hugging Face Spaces:
1. Create a new Space (select Gradio as SDK)
2. Upload app.py and requirements.txt
3. Add GOOGLE_API_KEY as a secret in Space settings
4. Your Space will automatically deploy!
"""

import os
import asyncio
import gradio as gr
from google.adk.agents import Agent
from google.adk.runners import InMemoryRunner
from google.adk.tools import google_search

# Get API key from environment (required for Hugging Face Spaces)
GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY")

if not GOOGLE_API_KEY:
    raise ValueError(
        "GOOGLE_API_KEY environment variable is required.\n"
        "For Hugging Face Spaces: Add it as a secret in Space settings.\n"
        "For local development: Set it with 'export GOOGLE_API_KEY=your-key'"
    )

# Set up environment
os.environ["GOOGLE_API_KEY"] = GOOGLE_API_KEY
os.environ["GOOGLE_GENAI_USE_VERTEXAI"] = "FALSE"

# Create the AI agent
root_agent = Agent(
    name="helpful_assistant",
    model="gemini-2.5-flash-lite",
    description="A helpful AI assistant that can answer questions and search the web.",
    instruction="""You are a helpful and friendly AI assistant.
    Use Google Search for current information, news, weather, or any time-sensitive queries.
    Provide clear, concise, and accurate responses.
    Be conversational and engaging.
    Format your responses nicely with markdown when appropriate.""",
    tools=[google_search],
)

# Create the runner
runner = InMemoryRunner(agent=root_agent)

print("=" * 80)
print("πŸš€ AI Agent Chat - Gradio Interface")
print("=" * 80)
print("βœ… Agent initialized with Google Search tool")
print("βœ… Model: gemini-2.5-flash-lite")
print("=" * 80)


def chat_with_agent(message, history):
    """
    Process user message and return agent response

    Args:
        message: User's current message
        history: Chat history in Gradio format [[user_msg, bot_msg], ...]

    Returns:
        str: Agent's response
    """
    if not message or not message.strip():
        return ""

    try:
        # Run the agent query
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
        response = loop.run_until_complete(runner.run_debug(message))
        loop.close()

        # Extract the text response
        if response and len(response) > 0:
            response_text = response[0].content.parts[0].text
            return response_text
        else:
            return "❌ Sorry, I couldn't generate a response. Please try again."

    except Exception as e:
        print(f"❌ Error: {str(e)}")
        return f"❌ Error: {str(e)}"


# Custom CSS for a beautiful interface with orange-mauve gradient
custom_css = """
.gradio-container {
    max-width: 900px !important;
}

#component-0 {
    background: linear-gradient(135deg, #ff6b35 0%, #c44569 50%, #8b5a9e 100%);
    color: white;
    padding: 20px;
    border-radius: 10px;
    text-align: center;
    margin-bottom: 20px;
    box-shadow: 0 4px 15px rgba(255, 107, 53, 0.3);
}

/* Orange-mauve gradient for buttons */
.primary-button {
    background: linear-gradient(135deg, #ff6b35 0%, #c44569 100%) !important;
}

/* Accent colors */
button.primary {
    background: linear-gradient(135deg, #ff6b35 0%, #c44569 100%) !important;
    border: none !important;
}

.chatbot .message.bot {
    background: linear-gradient(135deg, rgba(255, 107, 53, 0.1) 0%, rgba(196, 69, 105, 0.1) 100%) !important;
    border-left: 3px solid #ff6b35 !important;
}
"""

# Create Gradio interface with orange-mauve theme
with gr.Blocks(
    theme=gr.themes.Soft(
        primary_hue="orange",
        secondary_hue="pink",
    ),
    css=custom_css,
    title="AI Agent Chat",
) as demo:

    # Header
    gr.Markdown(
        """
        # πŸ€– AI Agent Chat
        ### Powered by Google ADK & Gemini

        Ask me anything! I can search the web for current information, answer questions, and help with various tasks.
        """
    )

    # Chat interface
    chatbot = gr.Chatbot(
        height=500,
        show_label=False,
        avatar_images=(
            None,  # User avatar (default)
            "https://em-content.zobj.net/source/apple/391/robot_1f916.png"  # Agent avatar
        ),
        bubble_full_width=False,
    )

    # Input area
    with gr.Row():
        msg = gr.Textbox(
            placeholder="Type your message here...",
            show_label=False,
            scale=9,
            autofocus=True,
        )
        submit = gr.Button("Send πŸ“€", variant="primary", scale=1)

    # Examples
    gr.Examples(
        examples=[
            "What's the weather in Tokyo?",
            "Explain how AI agents work in simple terms",
            "Write a Python function to calculate factorial",
            "What are the latest tech news?",
            "Compare cats vs dogs in a table",
        ],
        inputs=msg,
        label="πŸ’‘ Try these examples:",
    )

    # Clear button
    clear = gr.Button("πŸ—‘οΈ Clear Chat", variant="secondary")

    # Info section
    with gr.Accordion("ℹ️ About this AI Agent", open=False):
        gr.Markdown(
            """
            ### Features:
            - πŸ” **Google Search**: Can search the web for current information
            - 🧠 **Smart Tool Usage**: Decides when to use search based on your query
            - ⚑ **Fast Responses**: Using Gemini 2.5 Flash Lite
            - πŸ“Š **Rich Formatting**: Supports markdown for beautiful responses

            ### How it works:
            1. You ask a question
            2. The agent analyzes if it needs current information
            3. If needed, it searches Google
            4. It synthesizes the information into a clear answer

            ### Technical Details:
            - **Framework**: Google Agent Development Kit (ADK)
            - **Model**: Gemini 2.5 Flash Lite
            - **Tools**: Google Search
            - **Interface**: Gradio

            ### Source Code:
            Built as part of the Kaggle 5-Day AI Agents Course
            """
        )

    # Event handlers
    def respond(message, chat_history):
        bot_message = chat_with_agent(message, chat_history)
        chat_history.append((message, bot_message))
        return "", chat_history

    msg.submit(respond, [msg, chatbot], [msg, chatbot])
    submit.click(respond, [msg, chatbot], [msg, chatbot])
    clear.click(lambda: None, None, chatbot, queue=False)


if __name__ == "__main__":
    print("\n🌐 Starting Gradio interface...")
    print("πŸ“± The interface will open in your browser automatically")
    print("\nPress CTRL+C to stop the server\n")

    # Launch the app
    demo.launch(
        server_name="0.0.0.0",
        server_port=7860,
        share=False,  # Set to True to create a public link
        show_error=True,
    )