Skip to content
Open
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
1 change: 1 addition & 0 deletions agents/.python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.10
Empty file added agents/README.md
Empty file.
6 changes: 6 additions & 0 deletions agents/crew_zaai/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
def main():
print("Hello from crew-zaai!")


if __name__ == "__main__":
main()
7 changes: 7 additions & 0 deletions agents/crew_zaai/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[project]
name = "crew-zaai"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.10"
dependencies = []
13 changes: 7 additions & 6 deletions agents/crew_zaai/src/crew_zaai/config/agents.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,13 @@ summarizer:
You're known for your ability to summarize and retrive facts, references, quotes
and recommend the most useful surprising information about the {topic}.

blog_writer:
linkedin_post_writer:
role: >
{topic} Blog Writer
{topic} LinkedIn Engagement Specialist
goal: >
Create detailed blog posts based on {topic} research findings
Craft high-impact LinkedIn posts about {topic} to maximize engagement and professional reach.Note: Please shorten your post and try again. Max 3000 characters
backstory: >
You're a meticulous writer with a keen eye for detail.
You're known for your ability to turn complex topics into clear and concise blog posts,
making it easy for others to understand and act on the information you provide.
You are a seasoned social media strategist with a specialty in LinkedIn.
You understand the nuances of the LinkedIn algorithm and what content resonates with professionals.
Your expertise lies in creating concise, engaging posts that spark conversations, build thought leadership, and expand professional networks around key topics.
Note: Please shorten your post and try again. Max 3000 characters
27 changes: 17 additions & 10 deletions agents/crew_zaai/src/crew_zaai/config/tasks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ research_task:
description: >
Conduct a thorough research about {topic}
Make sure you find any interesting and relevant youtube links given
the current year is 2024.
the current year is 2025.
expected_output: >
A list with youtube URLs that cover {topic} and the respective description
with the most relevant information about {topic}. Ignore any links that don't
with the most relevant information about {topic}. and do have subtitles enabled.Ignore any links that don't
start with "https://www.youtube.com".
agent: researcher

Expand All @@ -22,12 +22,19 @@ summarize_task:

write_task:
description: >
Review the context you got and expand each topic into a full section for a blog post.
Make sure the blog post is detailed and contains any and all relevant information.
The blog post must contain an introduction, a body, a code example and a conclusion section.
Review the context you got and craft engaging LinkedIn posts for each key topic.
Each post should be concise, insightful, and tailored for a professional audience on LinkedIn.
The LinkedIn post series must include an introductory post, several posts covering each main topic, a post with a code example (if relevant and simplified for LinkedIn), and a concluding post.
expected_output: >
A fully-fledged blog post with the main topics, each presented as a complete section of information.
Format it as HTML without using '```'. Make it look like a professional tech blog website,
including a navbar, menu, and styling. Incorporate YouTube links as clickable references within
the text and at the end.
agent: blog_writer
A series of structured LinkedIn post drafts, one for each topic.
Format each post as text, optimized for LinkedIn's platform.
Note: Please shorten your post and try again. Max 3000 characters.
Focus on:
- Engaging opening lines to grab attention.
- Concise bullet points or short paragraphs for key information.
- Relevant hashtags for discoverability.
- A professional yet approachable tone.
- A clear call to action or question to encourage engagement (optional).
Avoid using '```' and aim for a professional, LinkedIn-style presentation.
agent: linkedin_post_writer # Agent designed to write LinkedIn posts

13 changes: 8 additions & 5 deletions agents/crew_zaai/src/crew_zaai/crew.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import os
from crewai import Agent, Crew, Process, Task
from crewai.project import CrewBase, agent, crew, task
from crew_zaai.src.crew_zaai.tools.searx import SearxSearchTool
from crew_zaai.src.crew_zaai.tools.youtube import YouTubeTranscriptTool
import sys
import os
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) # Add current directory of crew.py to path
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), '..')) # Add parent directory (src) to path, assuming 'tools' is in 'src'
from tools.searx import SearxSearchTool
from tools.youtube import YouTubeTranscriptTool


@CrewBase
Expand Down Expand Up @@ -31,8 +34,8 @@ def summarizer(self) -> Agent:
)

@agent
def blog_writer(self) -> Agent:
return Agent(config=self.agents_config["blog_writer"], verbose=True)
def linkedin_post_writer(self) -> Agent:
return Agent(config=self.agents_config["linkedin_post_writer"], verbose=True)

@task
def research_task(self) -> Task:
Expand Down
19 changes: 0 additions & 19 deletions agents/crew_zaai/src/crew_zaai/main.py

This file was deleted.

56 changes: 56 additions & 0 deletions agents/crew_zaai/src/crew_zaai/streamlit_app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import streamlit as st
import warnings
from dotenv import load_dotenv
from src.crew_zaai.crew import CrewZaai
import sys
import os

# Assuming your crew.py and CrewZaai class are correctly set up in crew_zaai package
# Get the directory where your streamlit_app.py is located
current_dir = os.path.dirname(os.path.abspath(__file__))
src_dir = os.path.join(current_dir, "src") # Assuming 'src' is in the same directory as streamlit_app.py
if os.path.exists(src_dir):
sys.path.insert(0, src_dir) # Add 'src' directory to Python path
else:
src_dir_parent = os.path.dirname(current_dir) # Check if 'src' is in the parent directory
src_dir_parent_check = os.path.join(src_dir_parent, "src")
if os.path.exists(src_dir_parent_check):
sys.path.insert(0, src_dir_parent_check) # Add parent 'src' if found
else:
print(f"Warning: 'src' directory not found in '{current_dir}' or parent directory. Import errors may occur.")


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

def run_crew_zaai(topic):
"""Runs the CrewZaai crew with the given topic and returns the output."""
try:
crew_instance = CrewZaai() # Instantiate CrewZaai class
crew = crew_instance.crew() # Get the crew object
result = crew.kickoff(inputs={"topic": topic}) # Run kickoff and capture the result
return result
except Exception as e:
return {"error": f"An error occurred while running the crew: {e}"}

def main():
st.title("CrewZaai AI Agent Runner")

topic = st.text_input("Enter a Topic for the AI Agents to Explore:", "AI Agents 2024")

if st.button("Run Crew"):
if not topic:
st.warning("Please enter a topic.")
else:
with st.spinner(text="Running CrewZaai..."):
output = run_crew_zaai(topic)

st.subheader("CrewZaai Output:")
if "error" in output:
st.error(output["error"])
else:
# Assuming the output is a dictionary or string that can be displayed
st.write(output) # You might need to format this output better depending on its structure

if __name__ == "__main__":
main()
2 changes: 1 addition & 1 deletion agents/crew_zaai/src/crew_zaai/tools/youtube.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def _run(
Runs the YouTubeTranscriptTool with the given parameters.

Args:
video_url (list[str]): The list of YouTube video URLs to fetch the transcript for.
video_url (list[str]): The list of YouTube video URLs to fetch the transcript for and do have subtitles enabled.
language (Optional[str]): The language code for the transcript (e.g., 'en' for English).

Returns:
Expand Down
76 changes: 76 additions & 0 deletions agents/crew_zaai/src/streamlit_app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import streamlit as st
import warnings
from dotenv import load_dotenv
from crew_zaai.crew import CrewZaai
import sys
import os
import json

# Assuming your crew.py and CrewZaai class are correctly set up in crew_zaai package
# Get the directory where your streamlit_app.py is located
current_dir = os.path.dirname(os.path.abspath(__file__))
src_dir = os.path.join(current_dir, "src") # Assuming 'src' is in the same directory as streamlit_app.py
if os.path.exists(src_dir):
sys.path.insert(0, src_dir) # Add 'src' directory to Python path
else:
src_dir_parent = os.path.dirname(current_dir) # Check if 'src' is in the parent directory
src_dir_parent_check = os.path.join(src_dir_parent, "src")
if os.path.exists(src_dir_parent_check):
sys.path.insert(0, src_dir_parent_check) # Add parent 'src' if found
else:
print(f"Warning: 'src' directory not found in '{current_dir}' or parent directory. Import errors may occur.")


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

def run_crew_zaai(topic):
"""Runs the CrewZaai crew with the given topic and returns the output."""
try:
crew_instance = CrewZaai() # Instantiate CrewZaai class
crew = crew_instance.crew() # Get the crew object
result = crew.kickoff(inputs={"topic": topic}) # Run kickoff and capture the result
return result
except Exception as e:
return {"error": f"An error occurred while running the crew: {e}"}

def main():
st.title("Multi Agents AI for research/Summarizer and Linkindin post") # Updated title

topic = st.text_input("Enter a Topic for the AI Agents to Explore:", "Agentic AI 2025")

if st.button("Button"):
if not topic:
st.warning("Please enter a topic.")
else:
with st.spinner(text="Running ..."):
output = run_crew_zaai(topic)

st.subheader("Task Outputs:") # Updated subheader

if "error" in output:
st.error(output["error"])
else:
if isinstance(output, dict) and "tasks_output" in output:
tasks_output_list = output["tasks_output"] # Get the list of TaskOutput objects

for i, task_output in enumerate(tasks_output_list):
st.subheader(f"Task {i+1}: {task_output.summary}") # Display task summary as subheader

try:
# Try to parse task_output.raw as JSON (dictionary)
raw_dict = json.loads(task_output.raw)
st.json(raw_dict) # Display as JSON if parsing is successful
except json.JSONDecodeError:
# If JSON parsing fails, display as plain text
st.text_area(f"Task {i+1} Output (Plain Text)", value=task_output.raw, height=1500)
except TypeError: # Handle cases where task_output.raw might not be a string
st.text_area(f"Task {i+1} Output (Plain Text, Non-String Raw)", value=str(task_output.raw), height=1500)


else:
st.write(output) # Fallback to raw output if format is unexpected


if __name__ == "__main__":
main()
6 changes: 6 additions & 0 deletions agents/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
def main():
print("Hello from agents!")


if __name__ == "__main__":
main()
10 changes: 10 additions & 0 deletions agents/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[project]
name = "agents"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.10"
dependencies = []

[tool.uv.workspace]
members = ["crew_zaai"]
19 changes: 19 additions & 0 deletions agents/uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.