Skip to main content

Entertainment Planner Agent — Google ADK

The Entertainment Planner is a Google ADK agent that finds entertainment options for events. It's one of seven specialist agents in the Event Planning Team — a multi-agent system where each agent is built with a different framework and coordinates through Dapr pub/sub.


Event Planning Team

AgentFrameworkPortPub/Sub Topics
Venue ScoutCrewAI8001venue.requestsvenue.results
Catering CoordinatorOpenAI Agents8002catering.requestscatering.results
Entertainment PlannerGoogle ADK8003entertainment.requestsentertainment.results
Budget AnalystStrands8004budget.requestsbudget.results
Schedule PlannerLangGraph8005schedule.requestsschedule.results
Invitations ManagerDapr Agents8006events.invitations.requests
Event CoordinatorDapr Agents8007Orchestrator
Decoration PlannerPydantic AI8008decorations.requestsdecorations.results

Prerequisites


Agent Code

The Entertainment Planner uses Google ADK's LlmAgent and FunctionTool, wrapped in a DaprWorkflowAgentRunner for durable execution and pub/sub messaging.

agents/adk/main.py
import logging
import os

logging.basicConfig(level=logging.DEBUG)

from google.adk.agents import LlmAgent
from google.adk.tools import FunctionTool
from diagrid.agent.adk import DaprWorkflowAgentRunner
from diagrid.agent.core.state import DaprStateStore


def find_entertainment(event_type: str) -> str:
"""Find entertainment options for an event type."""
return (
f"Entertainment options for {event_type}:\n"
f"1. Live Jazz Band 'Blue Notes' - $2,500 for 3 hours\n"
f"2. DJ & Sound System - $1,200 for 4 hours\n"
f"3. Stand-up Comedian - $1,800 for 1 hour set"
)


agent = LlmAgent(
name="entertainment_planner",
instruction="You are an entertainment planner. When asked to find entertainment, use the find_entertainment tool with the event type. Return the available entertainment options with pricing and duration. Always call the tool before responding.",
tools=[FunctionTool(find_entertainment)],
)

# State: persist agent memory across invocations
runner = DaprWorkflowAgentRunner(
agent=agent,
state_store=DaprStateStore(store_name="agent-memory"),
)

# PubSub: subscribe for incoming tasks, publish results
runner.serve(
port=int(os.environ.get("APP_PORT", "8003")),
pubsub_name="agent-pubsub",
subscribe_topic="entertainment.requests",
publish_topic="entertainment.results",
)

What's happening

  1. find_entertainment — A plain Python function wrapped in FunctionTool to make it callable by the ADK agent
  2. LlmAgent(...) — Google ADK agent with a name and instruction that guide LLM behavior
  3. DaprWorkflowAgentRunner — Wraps the ADK agent in a durable workflow that survives crashes and restarts
  4. DaprStateStore — Persists agent memory to Dapr state management (backed by Redis locally, or any Dapr state store in production)
  5. runner.serve() — Starts an HTTP server that subscribes to entertainment.requests and publishes results to entertainment.results via Dapr pub/sub

Dapr Components

The agent uses shared Dapr components for pub/sub messaging, state persistence, and LLM access.

Pub/Sub (agent-pubsub)

resources/agent-pubsub.yaml
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: agent-pubsub
spec:
type: pubsub.redis
version: v1
metadata:
- name: redisHost
value: localhost:6379
- name: redisPassword
value: ""

Routes messages between agents. Locally uses Redis; in production, swap for Kafka, RabbitMQ, or any Dapr pub/sub broker.

State Store (agent-memory)

resources/agent-memory.yaml
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: agent-memory
spec:
type: state.redis
version: v1
metadata:
- name: redisHost
value: localhost:6379
- name: redisPassword
value: ""
- name: actorStateStore
value: "false"

Persists agent memory and conversation state across invocations.

LLM Provider

resources/llm-provider.yaml
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: llm-provider
spec:
type: conversation.openai
version: v1
metadata:
- name: key
value: "{{OPENAI_API_KEY}}"
- name: model
value: gpt-4.1-2025-04-14

Provides LLM access through Dapr's conversation API. The API key is injected from the environment.


Run the Agent

1

Clone the quickstart

git clone https://github.com/diagridio/catalyst-quickstarts.git
cd catalyst-quickstarts/agents/adk
2

Set your API key

export OPENAI_API_KEY="your-key-here"
3

Install dependencies

pip install -r requirements.txt
4

Start the agent

diagrid dev run -f dev-python-adk.yaml
5

Test the agent

Send an entertainment search request:

curl -X POST http://localhost:8888/agent/run \
-H "Content-Type: application/json" \
-d '{"task": "Find entertainment for a corporate gala"}'

Run with the Full Team

To run all seven specialist agents together with the orchestrator, see the Event Planning Team overview.


Key Concepts

ConceptDescription
Durable WorkflowsDaprWorkflowAgentRunner checkpoints every step — agent survives crashes and restarts
Pub/Sub DecouplingAgents communicate through topics, not direct calls. Add or remove agents without code changes.
State PersistenceDaprStateStore saves agent memory to a pluggable backend (Redis, PostgreSQL, etc.)
Portable InfrastructureSwap message brokers and state stores by changing YAML — agent code stays the same

Next Steps