Skip to content

Commit 023aa8a

Browse files
committed
feat: add comedian agent and datetime tool, update README
1 parent b6c87b4 commit 023aa8a

6 files changed

Lines changed: 99 additions & 3 deletions

File tree

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,18 @@ requirements.txt # Python dependencies
5050
```
5151
4. Use a tunneling tool like `ngrok` to expose `http://localhost:8080/slack/events` to Slack during development.
5252

53+
### Optional: Use the ADK Web Development UI
54+
55+
The Agent Development Kit includes a built-in web-based Development UI that you can run locally. It's a powerful tool for testing, debugging, and interacting with your agent during development. It provides a chat interface to send messages to your agent and inspect the results.
56+
57+
1. **Start the ADK web server:**
58+
```bash
59+
adk web
60+
```
61+
62+
2. **Interact with your agent:**
63+
Open the local URL (usually `http://127.0.0.1:8000`) in your browser to use the Development UI.
64+
5365
## Slack App Configuration
5466
1. Create a new Slack app at <https://api.slack.com/apps>.
5567
2. Under **OAuth & Permissions**, add the following Bot Token scopes:

app/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from .main import root_agent
2+
3+
__all__ = ["root_agent"]

app/agents/comedian.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import os
2+
from google.adk import Agent
3+
from google.adk.planners import BuiltInPlanner
4+
from google.genai import types
5+
from dotenv import load_dotenv
6+
7+
load_dotenv()
8+
MODEL_NAME = os.environ.get("MODEL_NAME", "gemini-2.5-flash")
9+
10+
comedian_agent = Agent(
11+
model=MODEL_NAME,
12+
name="comedian_agent",
13+
planner=BuiltInPlanner(
14+
thinking_config=types.ThinkingConfig(
15+
thinking_budget=512,
16+
)
17+
),
18+
description=(
19+
"Use this agent to generate witty, humorous, and lighthearted responses."
20+
"It transforms any input into a comedic remark, pun, or short bit while staying safe and engaging."
21+
),
22+
instruction="""
23+
**Role & Persona**
24+
You are a professional comedian agent. Your job is to entertain through clever, witty, and humorous remarks. You blend stand-up style comedy, observational humor, and playful exaggeration, while keeping your tone light, engaging, and audience-friendly.
25+
26+
**Guidelines**
27+
28+
* Always aim for humor: jokes, witty comments, playful exaggerations, or puns.
29+
* Use everyday situations, pop culture, or absurd twists to make responses fun.
30+
* Keep the humor lighthearted and safe; avoid offensive, harmful, or discriminatory jokes.
31+
* If asked about serious topics, still bring a humorous spin while respecting the sensitivity of the subject.
32+
* Feel free to break the “fourth wall” (self-aware humor about being an AI comedian).
33+
34+
**Style**
35+
36+
* Short punchlines and snappy one-liners work best.
37+
* Occasionally build up a mini “bit” (setup → punchline).
38+
* Use conversational humor as if you were on stage talking to a live audience.
39+
40+
**Examples**
41+
42+
* User: *Tell me about AI.*
43+
Comedian Agent: “AI is like a teenager—knows everything, but still asks you for Wi-Fi.”
44+
* User: *What’s the weather like?*
45+
Comedian Agent: “It’s so hot outside, my ice cream applied for life insurance.”
46+
* User: *Give me motivation.*
47+
Comedian Agent: “Remember: even a broken clock is right twice a day… and that clock still gets more rest than you.”
48+
""",
49+
)

app/main.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@
1414
from google.adk.agents import Agent
1515
from google.adk.events.event import Event
1616
from google.adk.runners import InMemoryRunner
17-
from google.adk.tools import google_search
17+
# from google.adk.tools import google_search
18+
19+
from .agents.comedian import comedian_agent
20+
from .tools.get_current_datetime import get_current_datetime
1821

1922
# Environment variables
2023
load_dotenv()
@@ -98,7 +101,8 @@ async def _populate_session_from_thread(
98101
root_agent = Agent(
99102
name="slack_bot_agent",
100103
model=MODEL_NAME,
101-
instruction="""You are acting as a Slack Bot. All your responses must be formatted using Slack-compatible Markdown.
104+
instruction="""
105+
You are acting as a Slack Bot. All your responses must be formatted using Slack-compatible Markdown.
102106
103107
### Formatting Rules
104108
- **Headings / emphasis**: Use `*bold*` for section titles or important words.
@@ -109,12 +113,18 @@ async def _populate_session_from_thread(
109113
- Blockquotes: Use `>` at the beginning of a line.
110114
111115
Always structure your response clearly, using these rules so it renders correctly in Slack.""",
112-
tools=[google_search],
116+
tools=[
117+
get_current_datetime,
118+
],
119+
sub_agents=[
120+
comedian_agent,
121+
],
113122
)
114123

115124
runner = InMemoryRunner(agent=root_agent, app_name=APP_NAME)
116125
session_service = runner.session_service
117126

127+
118128
@bolt_app.event("app_mention")
119129
async def handle_mention(body, say, client, logger, ack):
120130
# Ack as soon as possible to avoid Slack retries that can cause duplicated responses
@@ -164,6 +174,7 @@ async def handle_mention(body, say, client, logger, ack):
164174
thread_ts=thread_ts,
165175
)
166176

177+
167178
@fastapi_app.post("/slack/events")
168179
async def slack_events(req: Request):
169180
retry_num = req.headers.get("x-slack-retry-num")
@@ -181,6 +192,7 @@ async def slack_events(req: Request):
181192
return JSONResponse(status_code=403, content={"error": f"{team_id}:workspace_not_allowed"})
182193
return await handler.handle(req)
183194

195+
184196
@fastapi_app.get("/")
185197
async def root():
186198
return {"status": "ok"}

app/tools/get_current_datetime.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import datetime
2+
import pytz
3+
from google.adk.tools import ToolContext
4+
5+
6+
async def get_current_datetime(timezone: str, tool_context: ToolContext):
7+
"""Gets the current date and time for a given timezone.
8+
9+
Args:
10+
timezone: The timezone to get the current time from. Defaults to "America/Los_Angeles".
11+
"""
12+
if not timezone:
13+
timezone = "America/Los_Angeles"
14+
try:
15+
tz = pytz.timezone(timezone)
16+
now = datetime.datetime.now(tz).strftime("%Y-%m-%d %H:%M:%S")
17+
return {"current_datetime": now}
18+
except pytz.UnknownTimeZoneError:
19+
return {"error": f"Unknown timezone: {timezone}"}

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ google-adk>=1.12.0
66
httpx>=0.27.0
77
python-dotenv>=1.0.0
88
aiohttp>=3.9
9+
pytz

0 commit comments

Comments
 (0)