Venue Scout Agent — CrewAI
The Venue Scout is a CrewAI agent that finds event venues by city and guest capacity. 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
| Agent | Framework | Port | Pub/Sub Topics |
|---|---|---|---|
| Venue Scout | CrewAI | 8001 | venue.requests → venue.results |
| Catering Coordinator | OpenAI Agents | 8002 | catering.requests → catering.results |
| Entertainment Planner | Google ADK | 8003 | entertainment.requests → entertainment.results |
| Budget Analyst | Strands | 8004 | budget.requests → budget.results |
| Schedule Planner | LangGraph | 8005 | schedule.requests → schedule.results |
| Invitations Manager | Dapr Agents | 8006 | events.invitations.requests |
| Event Coordinator | Dapr Agents | 8007 | Orchestrator |
| Decoration Planner | Pydantic AI | 8008 | decorations.requests → decorations.results |
Prerequisites
- Python 3.11+
- Diagrid CLI installed and initialized (
diagrid dev init) - An OpenAI API key
Agent Code
The Venue Scout agent uses CrewAI's Agent and @tool decorator, wrapped in a DaprWorkflowAgentRunner for durable execution and pub/sub messaging.
import logging
import os
logging.basicConfig(level=logging.DEBUG)
from crewai import Agent
from crewai.tools import tool
from diagrid.agent.crewai import DaprWorkflowAgentRunner
from diagrid.agent.core.state import DaprStateStore
@tool("Search venues")
def search_venues(city: str, capacity: int) -> str:
"""Search for event venues in a city with given capacity."""
return (
f"Found 3 venues in {city} for {capacity} guests:\n"
f"1. Grand Ballroom - $5,000/day, capacity {capacity+20}\n"
f"2. Riverside Conference Center - $3,500/day, capacity {capacity+10}\n"
f"3. Downtown Loft Space - $2,000/day, capacity {capacity}"
)
agent = Agent(
role="Venue Scout",
goal="Search for event venues by city and guest capacity using the search_venues tool. Return venue names, pricing, and capacity.",
backstory="You are an expert venue finder with knowledge of event spaces across major cities. When asked to find a venue, always use the search_venues tool with the city name and expected number of guests.",
tools=[search_venues],
)
# 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", "8001")),
pubsub_name="agent-pubsub",
subscribe_topic="venue.requests",
publish_topic="venue.results",
)
What's happening
@tool("Search venues")— CrewAI tool decorator that the agent can call during executionAgent(...)— CrewAI agent with a role, goal, and backstory that guide LLM behaviorDaprWorkflowAgentRunner— Wraps the CrewAI agent in a durable workflow that survives crashes and restartsDaprStateStore— Persists agent memory to Dapr state management (backed by Redis locally, or any Dapr state store in production)runner.serve()— Starts an HTTP server that subscribes tovenue.requestsand publishes results tovenue.resultsvia Dapr pub/sub
Dapr Components
The agent uses shared Dapr components for pub/sub messaging, state persistence, and LLM access.
Pub/Sub (agent-pubsub)
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)
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
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
Clone the quickstart
git clone https://github.com/diagridio/catalyst-quickstarts.git
cd catalyst-quickstarts/agents/crewai
Set your API key
export OPENAI_API_KEY="your-key-here"
Install dependencies
pip install -r requirements.txt
Start the agent
diagrid dev run -f dev-python-crewai.yaml
Test the agent
Send a venue search request:
curl -X POST http://localhost:8888/agent/run \
-H "Content-Type: application/json" \
-d '{"task": "Find venues in San Francisco for 200 guests"}'
Run with the Full Team
To run all seven specialist agents together with the orchestrator, see the Event Planning Team overview.
Key Concepts
| Concept | Description |
|---|---|
| Durable Workflows | DaprWorkflowAgentRunner checkpoints every step — agent survives crashes and restarts |
| Pub/Sub Decoupling | Agents communicate through topics, not direct calls. Add or remove agents without code changes. |
| State Persistence | DaprStateStore saves agent memory to a pluggable backend (Redis, PostgreSQL, etc.) |
| Portable Infrastructure | Swap message brokers and state stores by changing YAML — agent code stays the same |
Next Steps
- CLI Quickstart — Deploy a durable agent to Catalyst in minutes
- Session Management — Add persistent memory to your CrewAI agents
- Event Planning Team — See all agents working together