Spaces:
Sleeping
Sleeping
import os | |
import streamlit as st | |
from crewai import Agent, Task, Crew | |
from langchain_openai import ChatOpenAI # Importing OpenAI-compatible LLM | |
# Streamlit App Configuration | |
st.set_page_config( | |
page_title="CrewAI + Together AI Content Generator", | |
page_icon="π€", | |
layout="wide", | |
initial_sidebar_state="expanded" | |
) | |
# Custom CSS for Styling | |
st.markdown(""" | |
<style> | |
/* General Styling */ | |
body { | |
font-family: 'Helvetica', sans-serif; | |
} | |
.stButton > button { | |
background-color: #4CAF50; | |
color: white; | |
border-radius: 8px; | |
padding: 10px 20px; | |
font-size: 16px; | |
} | |
.stButton > button:hover { | |
background-color: #45a049; | |
} | |
.header { | |
font-size: 36px; | |
font-weight: bold; | |
color: #333; | |
text-align: center; | |
margin-bottom: 20px; | |
} | |
.subheader { | |
font-size: 24px; | |
font-weight: bold; | |
color: #555; | |
margin-bottom: 15px; | |
} | |
.output-box { | |
background-color: #f9f9f9; | |
border: 1px solid #ddd; | |
border-radius: 8px; | |
padding: 20px; | |
margin-top: 20px; | |
font-size: 16px; | |
line-height: 1.6; | |
} | |
</style> | |
""", unsafe_allow_html=True) | |
# Header | |
st.markdown('<div class="header">π€ CrewAI + Together AI Content Generator</div>', unsafe_allow_html=True) | |
st.markdown("Generate high-quality content using CrewAI and Together AI's Llama 3.3 model.") | |
# Sidebar for API Key Input | |
st.sidebar.markdown("### π οΈ Settings") | |
TOGETHER_API_KEY = st.sidebar.text_input("Enter Together AI API Key", type="password") | |
if not TOGETHER_API_KEY: | |
st.sidebar.warning("Please provide your Together AI API Key to proceed.") | |
else: | |
os.environ["TOGETHER_API_KEY"] = TOGETHER_API_KEY | |
# Main Content | |
st.markdown('<div class="subheader">π Enter a Topic</div>', unsafe_allow_html=True) | |
topic = st.text_input("Topic:", value="Artificial Intelligence", placeholder="e.g., Artificial Intelligence, Blockchain, etc.") | |
if st.button("Generate Content"): | |
if not TOGETHER_API_KEY: | |
st.error("Together AI API Key is missing. Please enter it in the sidebar.") | |
elif not topic.strip(): | |
st.error("Please enter a valid topic.") | |
else: | |
# Configure the LLM to use Together AI's Llama 3.3 | |
llm = ChatOpenAI( | |
openai_api_base="https://api.together.xyz/v1", | |
openai_api_key=os.getenv("TOGETHER_API_KEY"), | |
model_name="meta-llama/Llama-3.3-70B-Instruct-Turbo-Free" | |
) | |
# Define Agents | |
planner = Agent( | |
role="Content Planner", | |
goal="Plan engaging and factually accurate content on {topic}", | |
backstory="You're working on planning a blog article...", | |
allow_delegation=False, | |
verbose=True, | |
llm=llm # Use Together AI for this agent | |
) | |
writer = Agent( | |
role="Content Writer", | |
goal="Write insightful and factually accurate opinion piece about the topic: {topic}", | |
backstory="You're working on writing a new opinion piece...", | |
allow_delegation=False, | |
verbose=True, | |
llm=llm # Use Together AI for this agent | |
) | |
editor = Agent( | |
role="Editor", | |
goal="Edit a given blog post to align with the writing style of the organization.", | |
backstory="You are an editor who receives a blog post...", | |
allow_delegation=False, | |
verbose=True, | |
llm=llm # Use Together AI for this agent | |
) | |
# Define Tasks | |
plan = Task( | |
description=( | |
"1. Prioritize the latest trends, key players, " | |
"and noteworthy news on {topic}.\n" | |
"2. Identify the target audience, considering " | |
"their interests and pain points.\n" | |
"3. Develop a detailed content outline including " | |
"an introduction, key points, and a call to action.\n" | |
"4. Include SEO keywords and relevant data or sources." | |
), | |
expected_output="A comprehensive content plan document " | |
"with an outline, audience analysis, " | |
"SEO keywords, and resources.", | |
agent=planner, | |
) | |
write = Task( | |
description=( | |
"1. Use the content plan to craft a compelling " | |
"blog post on {topic}.\n" | |
"2. Incorporate SEO keywords naturally.\n" | |
"3. Sections/Subtitles are properly named " | |
"in an engaging manner.\n" | |
"4. Ensure the post is structured with an " | |
"engaging introduction, insightful body, " | |
"and a summarizing conclusion.\n" | |
"5. Proofread for grammatical errors and " | |
"alignment with the brand's voice.\n" | |
), | |
expected_output="A well-written blog post " | |
"in markdown format, ready for publication, " | |
"each section should have 2 or 3 paragraphs.", | |
agent=writer, | |
) | |
edit = Task( | |
description=("Proofread the given blog post for " | |
"grammatical errors and " | |
"alignment with the brand's voice."), | |
expected_output="A well-written blog post in markdown format, " | |
"ready for publication, " | |
"each section should have 2 or 3 paragraphs.", | |
agent=editor | |
) | |
# Create Crew | |
crew = Crew( | |
agents=[planner, writer, editor], | |
tasks=[plan, write, edit], | |
verbose=True | |
) | |
# Generate Content with Progress Indicator | |
with st.spinner("Generating content... This may take a few moments."): | |
result = crew.kickoff(inputs={"topic": topic}) | |
# Display Output | |
st.markdown('<div class="output-box">', unsafe_allow_html=True) | |
st.markdown("### β¨ Generated Content") | |
st.markdown(result, unsafe_allow_html=False) | |
st.markdown('</div>', unsafe_allow_html=True) |