WIP - Streamlit UI, Porting CLI

This commit is contained in:
ajaysi
2024-06-03 12:14:50 +05:30
parent 970a111f97
commit cfb6718716
3 changed files with 126 additions and 243 deletions

View File

@@ -16,143 +16,13 @@ from lib.utils.alwrity_streamlit_utils import (
do_web_research, competitor_analysis,
)
# Custom CSS for styling
st.markdown(
"""
<style>
div.row-widget.stRadio > div {
flex-direction: row;
align-items: stretch;
}
# Read the CSS file content
css_file_path = os.path.join('lib', 'workspace', 'alwrity_ui_styling.css')
with open(css_file_path) as f:
custom_css = f.read()
div.row-widget.stRadio > div[role="radiogroup"] > label[data-baseweb="radio"] {
background-color: #9AC5F4;
padding-right: 10px;
padding-left: 4px;
padding-bottom: 3px;
margin: 4px;
}
/* Style for the scrollbar track */
::-webkit-scrollbar-track {
background: #f1f1f1;
}
/* Style for the scrollbar handle */
::-webkit-scrollbar-thumb {
background-color: #888;
border-radius: 10px;
border: 3px solid #f1f1f1;
}
/* Style for the scrollbar handle on hover */
::-webkit-scrollbar-thumb:hover {
background: #555;
}
/* Set the width of the scrollbar */
::-webkit-scrollbar {
width: 16px;
}
body {
background: #f9f9f9;
background-image: linear-gradient(to bottom right, #f0f8ff, #e3f2fd);
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
.main-header {
font-size: 2.5em;
font-weight: bold;
color: #2196F3;
margin-bottom: 10px;
text-align: center;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.2);
}
.stApp {
margin-top: -80px;
}
.sub-header {
font-size: 1.75em;
font-weight: bold;
color: #ff6347;
margin-top: 40px;
margin-bottom: 10px;
text-align: center;
}
.option-box {
border: 2px solid #f0f0f0;
padding: 20px;
border-radius: 10px;
margin-bottom: 20px;
box-shadow: 2px 2px 12px #aaaaaa;
background-color: #f5f5f5;
}
.button {
background: #ff6347; /* Orange */
color: white;
border: none;
padding: 10px 20px;
border-radius: 5px; /* Rounded corners */
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 10px 2px;
cursor: pointer;
transition: background-color 0.3s ease; /* Smooth transition for hover effect */
box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.2); /* Add a subtle shadow */
font-weight: bold; /* Make the text bold */
}
.button:hover {
background-color: #ff4d4d; /* Darker orange */
box-shadow: 2px 2px 8px rgba(0, 0, 0, 0.3); /* Slightly larger shadow on hover */
}
.stTabs [role="tab"] {
font-size: 1.2em;
font-weight: bold;
color: white;
background: #673AB7;
padding: 10px;
margin: 5px;
border-radius: 5px;
border: 2px solid #ddd;
transition: background 0.3s ease;
}
.stTabs [role="tab"]:hover {
background: #9575CD;
}
.stTabs [role="tab"][aria-selected="true"] {
background: #D1C4E9;
color: #333;
border: 2px solid #673AB7;
}
.sidebar-header {
font-size: 1.5em;
font-weight: bold;
color: #333;
margin-bottom: 20px;
}
.sidebar-option {
margin-bottom: 10px;
font-size: 1.2em;
color: #2196F3;
}
.content-section {
padding: 20px;
margin-bottom: 30px;
border-radius: 10px;
box-shadow: 2px 2px 10px #ddd;
background-color: #f8f8f8;
}
.content-title {
font-size: 1.5em;
font-weight: bold;
margin-bottom: 10px;
color: #333;
}
</style>
""",
unsafe_allow_html=True
)
# Inject custom CSS into the Streamlit app
st.markdown(f'<style>{custom_css}</style>', unsafe_allow_html=True)
# Function to check if API keys are present and prompt user to input if not

View File

@@ -1,133 +1,109 @@
import os
import configparser
import streamlit as st
from crewai import Agent, Task, Crew
from crewai_tools import SerperDevTool
from langchain_google_genai import ChatGoogleGenerativeAI
def setup_environment():
os.environ["OPENAI_MODEL_NAME"] = 'gpt-3.5-turbo' # Adjust based on available model
# Initialize session state variables if not already done
if 'progress' not in st.session_state:
st.session_state.progress = 0
def create_agents(search_keywords):
"""Create agents for content creation."""
search_tool = SerperDevTool()
# Load the google gemini api key
google_api_key = os.getenv("GEMINI_API_KEY")
# Set gemini pro as llm
llm = ChatGoogleGenerativeAI(
model="gemini-1.5-flash-latest", verbose=True, temperature=0.6, google_api_key=google_api_key
)
role, goal, backstory = read_config("content_researcher")
content_researcher = Agent(
role = role,
goal = goal,
backstory = backstory,
tools = [search_tool],
memory = True, # Enable memory
verbose = True,
max_rpm = None, # No limit on requests per minute
max_iter = 10, # Default value for maximum iterations
allow_delegation = False,
llm = llm
)
try:
role, goal, backstory = read_config("content_researcher")
content_researcher = Agent(
role=role, goal=goal, backstory=backstory, tools=[search_tool], memory=True,
verbose=True, max_rpm=None, max_iter=10, allow_delegation=False, llm=llm
)
role, goal, backstory = read_config("content_outliner")
content_outliner = Agent(
role = role,
goal = goal,
backstory = backstory,
memory = True, # Enable memory
verbose = True,
tools = [search_tool],
max_rpm = 10, # No limit on requests per minute
max_iter = 10, # Default value for maximum iterations
allow_delegation = False,
llm = llm
)
role, goal, backstory = read_config("content_outliner")
content_outliner = Agent(
role=role, goal=goal, backstory=backstory, memory=True,
verbose=True, tools=[search_tool], max_rpm=10, max_iter=10, allow_delegation=False, llm=llm
)
role, goal, backsotry = read_config("content_writer")
content_writer = Agent(
role = role,
goal = goal,
backstory = backstory,
memory = True, # Enable memory
verbose = True,
max_rpm = 10, # No limit on requests per minute
max_iter = 15, # Default value for maximum iterations
allow_delegation = False,
llm = llm
)
role, goal, backstory = read_config("content_writer")
content_writer = Agent(
role=role, goal=goal, backstory=backstory, memory=True,
verbose=True, max_rpm=10, max_iter=15, allow_delegation=False, llm=llm
)
reviewer_config = read_config("content_reviewer")
content_reviewer = Agent(
role=role,
goal=goal,
backstory=backstory,
memory=True, # Enable memory
verbose=True,
max_rpm=10, # No limit on requests per minute
max_iter=10, # Default value for maximum iterations
allow_delegation=False,
llm=llm
)
role, goal, backstory = read_config("content_reviewer")
content_reviewer = Agent(
role=role, goal=goal, backstory=backstory, memory=True,
verbose=True, max_rpm=10, max_iter=10, allow_delegation=False, llm=llm
)
except Exception as err:
st.error(f"Error creating agents: {err}")
st.stop()
return [content_researcher, content_outliner, content_writer, content_reviewer]
def create_tasks(agents, search_keywords):
task_description, expected_output = read_config("research_task")
print(task_description, expected_output)
research_task = Task(
description=f"""The main focus keywords are: "{search_keywords}".\n{task_description}.
Set the input parameter as : search_query""",
expected_output = expected_output,
agent=agents[0] # Assign to the researcher agent
)
"""Create tasks for the agents."""
try:
task_description, expected_output = read_config("research_task")
research_task = Task(
description=f"The main focus keywords are: '{search_keywords}'.\n{task_description}.",
expected_output=expected_output,
agent=agents[0]
)
task_description, expected_output = read_config("outline_task")
outline_task = Task(
description=f"{task_description}.\n The main focus keywords are {search_keywords}",
expected_output=f"{expected_output}",
#human_input=True,
agent=agents[1] # Assign to the outliner agent
)
task_description, expected_output = read_config("outline_task")
outline_task = Task(
description=f"{task_description}.\nThe main focus keywords are {search_keywords}",
expected_output=expected_output,
agent=agents[1]
)
task_description, expected_output = read_config("writer_task")
writer_task = Task(
description=f"{task_description}\nThe main focus keywords are {search_keywords}\n.",
expected_output=expected_output,
agent=agents[2] # Assign to the writer agent
)
task_description, expected_output = read_config("writer_task")
writer_task = Task(
description=f"{task_description}\nThe main focus keywords are {search_keywords}.",
expected_output=expected_output,
agent=agents[2]
)
task_description, expected_output = read_config("review_task")
proofread_task = Task(
description=f"{task_description}.\nThe main focus keywords are: {search_keywords}.",
expected_output=expected_output,
agent=agents[3] # Assign to the reviewer agent
)
task_description, expected_output = read_config("review_task")
proofread_task = Task(
description=f"{task_description}.\nThe main focus keywords are: {search_keywords}.",
expected_output=expected_output,
agent=agents[3]
)
except Exception as err:
st.error(f"Error creating tasks: {err}")
st.stop()
return [research_task, outline_task, writer_task, proofread_task]
def execute_tasks(agents, tasks, lang):
"""Execute tasks with the agents."""
crew = Crew(
agents=agents,
tasks=tasks,
verbose=2, # You can set it to 1 or 2 for different logging levels
#process=Process.sequential,
#memory=True,
verbose=2,
language=lang
)
result = crew.kickoff()
try:
result = crew.kickoff()
except Exception as err:
st.error(f"Error executing tasks: {err}")
st.stop()
return result
def read_config(which_member):
"""
Reads the role, goal, and backstory from the config file.
"""
# Assign the specific config file for each agent.
# Base path to workspace/my_content_team
"""Reads configuration for the specified agent or task."""
team_dir = os.path.join(os.getcwd(), "lib", "workspace", "my_content_team")
config_file = None
@@ -139,8 +115,7 @@ def read_config(which_member):
config_file = os.path.join(team_dir, "content_reviewer.txt")
elif 'content_outliner' in which_member or 'outline_task' in which_member:
config_file = os.path.join(team_dir, "content_outliner.txt")
config = {}
try:
config = configparser.ConfigParser()
config.read(config_file)
@@ -148,20 +123,59 @@ def read_config(which_member):
goal = config.get('main', 'goal')
backstory = config.get('backstory', 'text')
except Exception as err:
print(f"Error reading agent config: {err}")
st.error(f"Error reading config: {err}")
st.stop()
if not 'task' in which_member:
if 'task' not in which_member:
return role, goal, backstory
else:
task_description = config.get('task', 'task_description')
expected_output = config.get('task', 'task_expected_output')
try:
task_description = config.get('task', 'task_description')
expected_output = config.get('task', 'task_expected_output')
except Exception as err:
st.error(f"Error reading task config: {err}")
st.stop()
return task_description, expected_output
def ai_agents_writers(search_keywords, lang="en"):
setup_environment()
agents = create_agents(search_keywords)
tasks = create_tasks(agents, search_keywords)
result = execute_tasks(agents, tasks, lang)
print("######################")
print(result)
"""Main function to kickoff AI Agents content team."""
progress_bar = st.progress(0)
status_text = st.empty()
st.session_state.progress = 0
status_text.text("Setting up environment...")
status_text.text("Creating Agents team...")
try:
agents = create_agents(search_keywords)
st.session_state.progress += 10
progress_bar.progress(st.session_state.progress)
except Exception as err:
st.error(f"Failed in creating Agents team: {err}")
st.stop()
status_text.text("Creating tasks for Agents team...")
try:
tasks = create_tasks(agents, search_keywords)
st.session_state.progress += 25
progress_bar.progress(st.session_state.progress)
except Exception as err:
st.error(f"Failed in creating tasks for Agents team: {err}")
st.stop()
status_text.text("AI Agents busy writing your content...")
try:
result = execute_tasks(agents, tasks, lang)
st.session_state.progress += 60
progress_bar.progress(st.session_state.progress)
status_text.text("Tasks executed successfully.")
st.success("Successfully executed tasks.")
# Display result with an option to copy the content
st.markdown("### Result")
st.code(result, language='markdown')
st.download_button('Download Content', data=result, file_name='alwrity_result.md')
except Exception as err:
st.error(f"Failed to execute tasks: {err}")

View File

@@ -28,4 +28,3 @@ html2image
lxml_html_clean
yfinance
pandas_ta
llama_index