Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/publish-to-pypi-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
echo "Error: Tag name is not in the correct format. Expected format: v<MAJOR>.<MINOR>.<PATCH>"
exit 1
fi
echo "VERSION=$VERSION" >> $GITHUB_ENV

check-version-before:
runs-on: ubuntu-latest
needs: extract-version
Expand Down
3 changes: 3 additions & 0 deletions examples/crewai/gmail_summarizer/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.env
__pycache__/
.DS_Store
92 changes: 92 additions & 0 deletions examples/crewai/gmail_summarizer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# GmailSummarizer Crew

Welcome to the GmailSummarizer Crew project, powered by [crewAI](https://crewai.com). This template is designed to help
you set up a multi-agent AI system with ease, leveraging the powerful and flexible framework provided by crewAI. Our
goal is to enable your agents to collaborate effectively on complex tasks, maximizing their collective intelligence and
capabilities.

## Installation

Ensure you have Python >=3.10 <3.13 installed on your system. This project uses [UV](https://docs.astral.sh/uv/) for
dependency management and package handling, offering a seamless setup and execution experience.

First, if you haven't already, install uv:

```bash
pip install uv
```

Next, navigate to your project directory and install the dependencies:

(Optional) Lock the dependencies and install them by using the CLI command:

```bash
crewai install
```

### Customizing

**Add your `OPENAI_API_KEY` into the `.env` file**

- Modify `src/gmail_summarizer/config/agents.yaml` to define your agents
- Modify `src/gmail_summarizer/config/tasks.yaml` to define your tasks
- Modify `src/gmail_summarizer/crew.py` to add your own logic, tools and specific args
- Modify `src/gmail_summarizer/main.py` to add custom inputs for your agents and tasks

**Add your app id of google and slack into the `.secrets.toml`**

```toml
[auth.slack]
client_id = ""
client_secret = ""

[auth.google]
client_id = ""
client_secret = ""
```

**customize input by your way in `main.py`**

```python
def run():
"""
Run the crew.
"""

inputs = {
'num_emails': 20,
'date': datetime.now().strftime("%Y%m%d"),
'slack_channel': 'your-slack-channel'
}
```

## Running the Project

To kickstart your crew of AI agents and begin task execution, run this from the root folder of your project:

```bash
$ crewai run
```

This command initializes the gmail-summarizer Crew, assembling the agents and assigning them tasks as defined in your
configuration.

This example, unmodified, will run the create a `report.md` file with the output of a research on LLMs in the root
folder.

## Understanding Your Crew

The gmail-summarizer Crew is composed of multiple AI agents, each with unique roles, goals, and tools. These agents
collaborate on a series of tasks, defined in `config/tasks.yaml`, leveraging their collective skills to achieve complex
objectives. The `config/agents.yaml` file outlines the capabilities and configurations of each agent in your crew.

## Support

For support, questions, or feedback regarding the GmailSummarizer Crew or crewAI.

- Visit our [documentation](https://docs.crewai.com)
- Reach out to us through our [GitHub repository](https://github.com/joaomdmoura/crewai)
- [Join our Discord](https://discord.com/invite/X4JWnZnxPb)
- [Chat with our docs](https://chatg.pt/DWjSBZn)

Let's create wonders together with the power and simplicity of crewAI.
31 changes: 31 additions & 0 deletions examples/crewai/gmail_summarizer/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
[project]
name = "gmail_summarizer"
version = "0.1.0"
description = "gmail-summarizer using crewAI"
authors = [{ name = "Your Name", email = "you@example.com" }]
requires-python = ">=3.10,<3.13"
dependencies = [
"crewai[tools]>=0.102.0,<1.0.0",
"hyperdock-container",
"hyperpocket",
"hyperpocket-crewai",
]

[project.scripts]
gmail_summarizer = "gmail_summarizer.main:run"
run_crew = "gmail_summarizer.main:run"
train = "gmail_summarizer.main:train"
replay = "gmail_summarizer.main:replay"
test = "gmail_summarizer.main:test"

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.crewai]
type = "crew"

[tool.uv.sources]
hyperpocket-crewai = { path = "../../../libs/extensions/crewai", editable = true }
hyperpocket = { path = "../../../libs/hyperpocket", editable = true }
hyperdock-container = { path = "../../../libs/docks/hyperdock-container", editable = true }
Empty file.
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
gmail_agent:
role: "Mail Retriever and Summarizer"
goal: "Fetch the latest {num_emails} emails from Gmail, filter out irrelevant or spam messages, and provide concise summaries of the valuable ones."
backstory: |
You are an AI assistant specializing in managing and summarizing email communications. Your role is to fetch the latest {num_emails} emails from Gmail, filter out irrelevant or spam messages, and provide concise summaries of the valuable ones.

Follow these steps:
1. Retrieve the {num_emails} most recent emails from the inbox.
2. Ignore irrelevant, spam, or promotional emails.
3. Summarize emails, providing clear and concise details.
4. If any information is missing (sender, subject, main content, actions required), leave it blank.

Format the summary as follows:

**Email :**
- **Sender:** [Email sender]
- **Subject:** [Email subject]
- **Main Content:** [Brief summary of key details]
- **Actions Required:** [List necessary actions, if any]

Example output:

**Email 1:**
- **Sender:** John Doe
- **Subject:** Project Update Meeting
- **Main Content:** The team has completed phase 1. A meeting is scheduled for Monday to discuss next steps.
- **Actions Required:** Confirm attendance for the meeting.

**Email 2:**
- **Sender:**
- **Subject:**
- **Main Content:**
- **Actions Required:**

Continue this format for all relevant emails.


sheets_agent:
role: "Spreadsheet Manager"
goal: "Create a Google Spreadsheet with a clear structure and store email summaries efficiently."
backstory: |
You specialize in efficiently organizing and structuring email data. Your role is to create a well-formatted spreadsheet with the following columns:
- **Date**: The date the email was received
- **Sender**: The name or email address of the sender
- **Subject**: The subject of the email
- **Summary**: A concise summary of the key points in the email
- **Action Required**: Specific actions the user needs to take, if any
- **Category**: A relevant label or classification for easy reference (e.g., Work, Personal, Urgent, Meeting, Follow-up, etc.)

### Guidelines:
1. Retrieve and process the latest {num_emails} emails.
2. Exclude irrelevant, spam, or promotional emails.
3. Summarize each relevant email concisely, focusing on key points.
4. Clearly list any required actions in the appropriate column.
5. Categorize emails logically to improve accessibility.
6. Enter each email summary as a separate row in the spreadsheet.
7. After filling in the data, double-check the spreadsheet to ensure accuracy and completeness.

Your goal is to create a structured and easy-to-read summary that helps the user quickly understand and prioritize their emails.

slack_agent:
role: "Notification Dispatcher"
goal: "Send the spreadsheet link to Slack."
backstory: |
You are responsible for ensuring that important email summaries are efficiently shared with the right people.
Your task is to post the generated spreadsheet link in the {slack_channel} Slack channel.

### Guidelines:
1. Ensure the spreadsheet link is correct and accessible.
2. Format the message clearly to highlight its purpose.
3. Include a brief description of the spreadsheet’s contents and relevance.
4. If necessary, mention any urgent or important emails that require immediate attention.
5. Confirm that the message has been successfully posted in {slack_channel}.

Your goal is to ensure that email summaries are easily accessible and that any required actions are promptly addressed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
fetch_and_summarize_emails:
description: >
Retrieve the most recent {num_emails} emails from Gmail, summarize it, and generate an insightful summary.
expected_output: >
A structured summary of the {num_emails} most recent emails.
agent: gmail_agent

create_spreadsheet:
description: >
Create a new Google Spreadsheet named 'email_summarization_{date}'
and populate it with the email summaries.
expected_output: >
A Google Spreadsheet URL containing the summarized emails.
agent: sheets_agent

send_slack_notification:
description: >
Send the Google Spreadsheet link to Slack.
expected_output: >
A confirmation message that the spreadsheet link has been successfully sent to Slack.
agent: slack_agent
105 changes: 105 additions & 0 deletions examples/crewai/gmail_summarizer/src/gmail_summarizer/crew.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
from crewai import Agent, Crew, Process, Task
from crewai.project import CrewBase, agent, crew, task
from hyperpocket_crewai import PocketCrewAI


@CrewBase
class GmailSummarizer:
"""Gmail Summarization Crew"""

# YAML Configuration Files
agents_config = "config/agents.yaml"
tasks_config = "config/tasks.yaml"

gmail_agent_pocket: PocketCrewAI
sheets_agent_pocket: PocketCrewAI
slack_agent_pocket: PocketCrewAI

def __enter__(self):
return self

def __exit__(self, exc_type, exc_val, exc_tb):
if self.gmail_agent_pocket is not None:
self.gmail_agent_pocket.teardown()
if self.sheets_agent_pocket is not None:
self.sheets_agent_pocket.teardown()
if self.slack_agent_pocket is not None:
self.slack_agent_pocket.teardown()

# Agents
@agent
def gmail_agent(self) -> Agent:
self.gmail_agent_pocket = PocketCrewAI(
tools=[
"https://github.com/vessl-ai/hyperpocket/tree/main/tools/google/list-gmail"
]
)
self.gmail_agent_pocket.init()

return Agent(
config=self.agents_config["gmail_agent"],
tools=self.gmail_agent_pocket.get_tools(),
verbose=True,
)

@agent
def sheets_agent(self) -> Agent:
self.sheets_agent_pocket = PocketCrewAI(
tools=[
"https://github.com/vessl-ai/hyperpocket/tree/main/tools/google/create-spreadsheet",
"https://github.com/vessl-ai/hyperpocket/tree/main/tools/google/update-spreadsheet-cells",
"https://github.com/vessl-ai/hyperpocket/tree/main/tools/google/get-spreadsheet",
]
)
self.sheets_agent_pocket.init()

return Agent(
config=self.agents_config["sheets_agent"],
tools=self.sheets_agent_pocket.get_tools(),
verbose=True,
)

@agent
def slack_agent(self) -> Agent:
self.slack_agent_pocket = PocketCrewAI(
tools=[
"https://github.com/vessl-ai/hyperpocket/tree/main/tools/slack/post-message",
]
)
self.slack_agent_pocket.init()

return Agent(
config=self.agents_config["slack_agent"],
tools=self.slack_agent_pocket.get_tools(),
verbose=True,
)

# Tasks
@task
def fetch_and_summarize_emails(self) -> Task:
return Task(
config=self.tasks_config["fetch_and_summarize_emails"],
)

@task
def create_spreadsheet(self) -> Task:
return Task(
config=self.tasks_config["create_spreadsheet"],
)

@task
def send_slack_notification(self) -> Task:
return Task(
config=self.tasks_config["send_slack_notification"],
)

# Crew Definition
@crew
def crew(self) -> Crew:
"""Creates the GmailSummarizer crew"""
return Crew(
agents=self.agents, # Automatically created by @agent decorator
tasks=self.tasks, # Automatically created by @task decorator
process=Process.sequential, # Run tasks in order
verbose=True,
)
34 changes: 34 additions & 0 deletions examples/crewai/gmail_summarizer/src/gmail_summarizer/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/usr/bin/env python
import warnings
from datetime import datetime

from gmail_summarizer.crew import GmailSummarizer

warnings.filterwarnings("ignore", category=SyntaxWarning, module="pysbd")


# This main file is intended to be a way for you to run your
# crew locally, so refrain from adding unnecessary logic into this file.
# Replace with inputs you want to test with, it will automatically
# interpolate any tasks and agents information

def run():
"""
Run the crew.
"""

inputs = {
'num_emails': 20,
'date': datetime.now().strftime("%Y%m%d"),
'slack_channel': 'engr-test'
}

try:
with GmailSummarizer() as summarizer:
summarizer.crew().kickoff(inputs=inputs)
except Exception as e:
raise Exception(f"An error occurred while running the crew: {e}")


if __name__ == '__main__':
run()
Loading
Loading