WIP - Streamlit UI, Porting CLI
This commit is contained in:
@@ -1,5 +1,10 @@
|
|||||||
# How to Use AI Content Generation Toolkit - Alwrity
|
# How to Alwrity - Getting Started
|
||||||
|
|
||||||
|
Alwrity assists content creators and digital marketers in generating, formatting, and uploading blog content with unprecedented efficiency.
|
||||||
|
|
||||||
|
Our toolkit integrates advanced AI models for text generation, image creation, and data analysis, streamlining your content creation pipeline and ensuring high-quality output with minimal effort.
|
||||||
|
|
||||||
|
---
|
||||||
1). [Visit alwrity.com](https://www.alwrity.com/ai-writing-tools), You will find AI content writing tools, which are Free & No-Signup.
|
1). [Visit alwrity.com](https://www.alwrity.com/ai-writing-tools), You will find AI content writing tools, which are Free & No-Signup.
|
||||||
**Note:** Although, this is limited, as is our wallet & Resources.
|
**Note:** Although, this is limited, as is our wallet & Resources.
|
||||||
|
|
||||||
|
|||||||
@@ -6,11 +6,13 @@ import streamlit as st
|
|||||||
# Load .env file
|
# Load .env file
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
|
|
||||||
|
from lib.chatbot_custom.chatbot_local_docqa import alwrity_chat_docqa
|
||||||
from lib.utils.alwrity_streamlit_utils import (
|
from lib.utils.alwrity_streamlit_utils import (
|
||||||
blog_from_keyword, ai_agents_team,
|
blog_from_keyword, ai_agents_team,
|
||||||
blog_from_audio, write_story,
|
blog_from_audio, write_story,
|
||||||
essay_writer, ai_news_writer,
|
essay_writer, ai_news_writer,
|
||||||
ai_finance_ta_writer, ai_social_writer
|
ai_finance_ta_writer, ai_social_writer,
|
||||||
|
do_web_research, competitor_analysis,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Custom CSS for styling
|
# Custom CSS for styling
|
||||||
@@ -291,8 +293,10 @@ def main():
|
|||||||
alwrity_brain()
|
alwrity_brain()
|
||||||
|
|
||||||
with tab5:
|
with tab5:
|
||||||
st.title("🙎 Ask Alwrity 🤦")
|
st.info("Chatbot")
|
||||||
st.write("Oh, you decided to talk to a chatbot? I guess even Netflix can't... Shall we get this over with?")
|
st.markdown("Create a collection by uploading files (PDF, MD, CSV, etc), or crawl a data source (Websites, more sources coming soon.")
|
||||||
|
st.markdown("One can ask/chat, summarize and do semantic search over the uploaded data")
|
||||||
|
#alwrity_chat_docqa()
|
||||||
|
|
||||||
# Sidebar for prompt modification
|
# Sidebar for prompt modification
|
||||||
st.sidebar.title("📝 Modify Prompts")
|
st.sidebar.title("📝 Modify Prompts")
|
||||||
@@ -350,19 +354,17 @@ def content_planning_tools():
|
|||||||
Provide few keywords to get Google, Neural, pytrends analysis. Know keywords, blog titles to target.
|
Provide few keywords to get Google, Neural, pytrends analysis. Know keywords, blog titles to target.
|
||||||
Generate months long content calender around given keywords.""")
|
Generate months long content calender around given keywords.""")
|
||||||
options = [
|
options = [
|
||||||
"Keywords web research🤓",
|
"Keywords Researcher",
|
||||||
"Competitor Analysis🧐",
|
"Competitor Analysis"
|
||||||
"Give me content calendar 🥹🥹"
|
|
||||||
]
|
]
|
||||||
choice = st.selectbox("Select a content planning tool:", options, index=0, format_func=lambda x: f"🔍 {x}")
|
choice = st.selectbox("Select a content planning tool:", options, index=0, format_func=lambda x: f"🔍 {x}")
|
||||||
|
|
||||||
if st.button("Plan Content"):
|
if choice == "Keywords Researcher":
|
||||||
if choice == "Keywords web research🤓":
|
do_web_research()
|
||||||
do_web_research()
|
elif choice == "Competitor Analysis":
|
||||||
elif choice == "Competitor Analysis🧐":
|
competitor_analysis()
|
||||||
competitor_analysis()
|
#elif choice == "Get Content Calender":
|
||||||
elif choice == "Give me content calendar 🥹🥹":
|
# planning_agents()
|
||||||
content_planning_agents()
|
|
||||||
|
|
||||||
|
|
||||||
def alwrity_brain():
|
def alwrity_brain():
|
||||||
|
|||||||
@@ -187,7 +187,8 @@ def get_related_topics_and_save_csv(search_keywords):
|
|||||||
data = pytrends.related_topics()
|
data = pytrends.related_topics()
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
logger.error(f"Failed to get pytrends realted topics: {err}")
|
logger.error(f"Failed to get pytrends realted topics: {err}")
|
||||||
return
|
return None
|
||||||
|
|
||||||
# Extract data from the result
|
# Extract data from the result
|
||||||
top_topics = list(data.values())[0]['top']
|
top_topics = list(data.values())[0]['top']
|
||||||
rising_topics = list(data.values())[0]['rising']
|
rising_topics = list(data.values())[0]['rising']
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ from pathlib import Path
|
|||||||
from metaphor_python import Metaphor
|
from metaphor_python import Metaphor
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
|
import streamlit as st
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
from tqdm import tqdm
|
from tqdm import tqdm
|
||||||
from tabulate import tabulate
|
from tabulate import tabulate
|
||||||
@@ -71,28 +72,45 @@ def metaphor_find_similar(similar_url):
|
|||||||
raise
|
raise
|
||||||
|
|
||||||
competitors = search_response.results
|
competitors = search_response.results
|
||||||
urls = {}
|
# Initialize lists to store titles and URLs
|
||||||
|
titles = []
|
||||||
|
urls = []
|
||||||
|
|
||||||
|
# Initialize lists to store titles, URLs, and contents
|
||||||
|
titles = []
|
||||||
|
urls = []
|
||||||
|
contents = []
|
||||||
|
|
||||||
|
# Extract titles, URLs, and contents from the competitors
|
||||||
for c in competitors:
|
for c in competitors:
|
||||||
print(c.title + ':' + c.url)
|
titles.append(c.title)
|
||||||
for acompetitor in tqdm(competitors, desc="Processing URL content", unit="competitor"):
|
urls.append(c.url)
|
||||||
|
# Simulate web content fetching and summarization (replace with actual logic)
|
||||||
all_contents = ""
|
all_contents = ""
|
||||||
try:
|
try:
|
||||||
search_response = metaphor.search_and_contents(
|
search_response = metaphor.search_and_contents(
|
||||||
acompetitor.url,
|
c.url,
|
||||||
type="keyword",
|
type="keyword",
|
||||||
num_results=3
|
num_results=1
|
||||||
)
|
)
|
||||||
|
research_response = search_response.results
|
||||||
|
for r in research_response:
|
||||||
|
all_contents += r.text
|
||||||
|
c.text = summarize_competitor_content(all_contents) # Replace with actual summarization function
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
logger.error(f"Failed to do metaphor keyword/url research: {err}")
|
c.text = f"Failed to summarize content: {err}"
|
||||||
|
contents.append(c.text)
|
||||||
|
|
||||||
research_response = search_response.results
|
# Create a DataFrame from the titles, URLs, and contents
|
||||||
# Add a progress bar for the inner loop
|
df = pd.DataFrame({
|
||||||
for r in tqdm(research_response, desc=f"{acompetitor.url}", unit="research"):
|
"Title": titles,
|
||||||
all_contents += r.text
|
"URL": urls,
|
||||||
try:
|
"Content Summary": contents
|
||||||
acompetitor.text = summarize_competitor_content(all_contents)
|
})
|
||||||
except Exception as err:
|
# Display the DataFrame as a table
|
||||||
logger.error(f"Failed to summarize_web_content: {err}")
|
if not df.empty:
|
||||||
|
st.write("### Competitor Analysis Results")
|
||||||
|
st.table(df)
|
||||||
|
|
||||||
print_search_result(competitors)
|
print_search_result(competitors)
|
||||||
return search_response
|
return search_response
|
||||||
@@ -179,6 +197,12 @@ def print_search_result(contents_response):
|
|||||||
tablefmt="fancy_grid",
|
tablefmt="fancy_grid",
|
||||||
colalign=["left", "left", "left"],
|
colalign=["left", "left", "left"],
|
||||||
maxcolwidths=[20, 20, 70])
|
maxcolwidths=[20, 20, 70])
|
||||||
|
|
||||||
|
# Convert table_data to DataFrame
|
||||||
|
import pandas as pd
|
||||||
|
df = pd.DataFrame(table_data, columns=["URL", "Title", "Summary"])
|
||||||
|
import streamlit as st
|
||||||
|
st.table(df)
|
||||||
print(table)
|
print(table)
|
||||||
# Save the combined table to a file
|
# Save the combined table to a file
|
||||||
try:
|
try:
|
||||||
|
|||||||
104
lib/chatbot_custom/chat_history_chatbot.py
Normal file
104
lib/chatbot_custom/chat_history_chatbot.py
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
import time
|
||||||
|
import os
|
||||||
|
import joblib
|
||||||
|
import streamlit as st
|
||||||
|
import google.generativeai as genai
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
|
||||||
|
# Load environment variables
|
||||||
|
load_dotenv()
|
||||||
|
GOOGLE_API_KEY = os.environ.get('GOOGLE_API_KEY')
|
||||||
|
genai.configure(api_key=os.environ.get('GEMINI_API_KEY'))
|
||||||
|
|
||||||
|
# Constants
|
||||||
|
MODEL_ROLE = 'ai'
|
||||||
|
AI_AVATAR_ICON = '👄'
|
||||||
|
DATA_DIR = 'data/'
|
||||||
|
|
||||||
|
|
||||||
|
def history_chatbot():
|
||||||
|
# Ensure the data/ directory exists
|
||||||
|
os.makedirs(DATA_DIR, exist_ok=True)
|
||||||
|
|
||||||
|
# Generate a new chat ID
|
||||||
|
new_chat_id = f'{time.time()}'
|
||||||
|
|
||||||
|
# Load past chats if available
|
||||||
|
try:
|
||||||
|
past_chats = joblib.load(os.path.join(DATA_DIR, 'past_chats_list'))
|
||||||
|
except FileNotFoundError:
|
||||||
|
past_chats = {}
|
||||||
|
|
||||||
|
# Sidebar for past chats
|
||||||
|
with st.sidebar:
|
||||||
|
st.write('# Past Chats')
|
||||||
|
if 'chat_id' not in st.session_state:
|
||||||
|
st.session_state.chat_id = st.selectbox(
|
||||||
|
label='Pick a past chat',
|
||||||
|
options=[new_chat_id] + list(past_chats.keys()),
|
||||||
|
format_func=lambda x: past_chats.get(x, 'New Chat'),
|
||||||
|
placeholder='_'
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
st.session_state.chat_id = st.selectbox(
|
||||||
|
label='Pick a past chat',
|
||||||
|
options=[new_chat_id, st.session_state.chat_id] + list(past_chats.keys()),
|
||||||
|
index=1,
|
||||||
|
format_func=lambda x: past_chats.get(x, 'New Chat' if x != st.session_state.chat_id else st.session_state.chat_title),
|
||||||
|
placeholder='_'
|
||||||
|
)
|
||||||
|
st.session_state.chat_title = f'ChatSession-{st.session_state.chat_id}'
|
||||||
|
|
||||||
|
# Load chat history if available
|
||||||
|
try:
|
||||||
|
st.session_state.messages = joblib.load(os.path.join(DATA_DIR, f'{st.session_state.chat_id}-st_messages'))
|
||||||
|
st.session_state.gemini_history = joblib.load(os.path.join(DATA_DIR, f'{st.session_state.chat_id}-gemini_messages'))
|
||||||
|
print('Loaded existing chat history')
|
||||||
|
except FileNotFoundError:
|
||||||
|
st.session_state.messages = []
|
||||||
|
st.session_state.gemini_history = []
|
||||||
|
print('Initialized new chat history')
|
||||||
|
|
||||||
|
# Configure the AI model
|
||||||
|
st.session_state.model = genai.GenerativeModel('gemini-pro')
|
||||||
|
st.session_state.chat = st.session_state.model.start_chat(history=st.session_state.gemini_history)
|
||||||
|
|
||||||
|
# Display past messages
|
||||||
|
for message in st.session_state.messages:
|
||||||
|
with st.chat_message(name=message['role'], avatar=message.get('avatar')):
|
||||||
|
st.markdown(message['content'])
|
||||||
|
|
||||||
|
# Handle user input
|
||||||
|
if prompt := st.chat_input('Ask Alwrity...'):
|
||||||
|
if st.session_state.chat_id not in past_chats:
|
||||||
|
past_chats[st.session_state.chat_id] = st.session_state.chat_title
|
||||||
|
joblib.dump(past_chats, os.path.join(DATA_DIR, 'past_chats_list'))
|
||||||
|
|
||||||
|
# Display and save user message
|
||||||
|
with st.chat_message('user'):
|
||||||
|
st.markdown(prompt)
|
||||||
|
st.session_state.messages.append({'role': 'user', 'content': prompt})
|
||||||
|
|
||||||
|
# Send message to AI and stream the response
|
||||||
|
response = st.session_state.chat.send_message(prompt, stream=True)
|
||||||
|
full_response = ''
|
||||||
|
with st.chat_message(name=MODEL_ROLE, avatar=AI_AVATAR_ICON):
|
||||||
|
message_placeholder = st.empty()
|
||||||
|
for chunk in response:
|
||||||
|
for ch in chunk.text.split(' '):
|
||||||
|
full_response += ch + ' '
|
||||||
|
time.sleep(0.05)
|
||||||
|
message_placeholder.write(full_response + '▌')
|
||||||
|
message_placeholder.write(full_response)
|
||||||
|
|
||||||
|
# Save the AI response
|
||||||
|
st.session_state.messages.append({
|
||||||
|
'role': MODEL_ROLE,
|
||||||
|
'content': full_response,
|
||||||
|
'avatar': AI_AVATAR_ICON
|
||||||
|
})
|
||||||
|
st.session_state.gemini_history = st.session_state.chat.history
|
||||||
|
|
||||||
|
# Persist chat history to disk
|
||||||
|
joblib.dump(st.session_state.messages, os.path.join(DATA_DIR, f'{st.session_state.chat_id}-st_messages'))
|
||||||
|
joblib.dump(st.session_state.gemini_history, os.path.join(DATA_DIR, f'{st.session_state.chat_id}-gemini_messages'))
|
||||||
101
lib/chatbot_custom/chatbot_local_docqa.py
Normal file
101
lib/chatbot_custom/chatbot_local_docqa.py
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
import os
|
||||||
|
import streamlit as st
|
||||||
|
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader, ServiceContext, Document
|
||||||
|
from llama_index.llms.openai import OpenAI
|
||||||
|
import openai
|
||||||
|
from pathlib import Path
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
|
||||||
|
# Load environment variables
|
||||||
|
load_dotenv(Path("../../.env"))
|
||||||
|
openai.api_key = os.getenv("OPENAI_API_KEY")
|
||||||
|
|
||||||
|
|
||||||
|
def initialize_session_state():
|
||||||
|
"""Initialize the chat message history in session state."""
|
||||||
|
if "messages" not in st.session_state:
|
||||||
|
st.session_state.messages = [
|
||||||
|
{"role": "assistant", "content": f"Ask me a question about documents from {LOCAL_BRAIN_DATA} or from the Web."}
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@st.cache_resource(show_spinner=False)
|
||||||
|
def load_data(input_dir):
|
||||||
|
"""Load and index documents from the specified directory."""
|
||||||
|
with st.spinner("Loading and indexing your docs – hang tight! This should take 1-2 minutes."):
|
||||||
|
reader = SimpleDirectoryReader(input_dir=input_dir, recursive=True)
|
||||||
|
docs = reader.load_data()
|
||||||
|
service_context = ServiceContext.from_defaults(
|
||||||
|
llm=OpenAI(
|
||||||
|
model="gpt-3.5-turbo",
|
||||||
|
temperature=0.5,
|
||||||
|
system_prompt=(
|
||||||
|
"You are an expert on content & digital marketing and your job is to answer technical questions."
|
||||||
|
"Assume that all questions are related to provided documents, as context."
|
||||||
|
"Keep your answers technical and based on facts – do not hallucinate features."
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
index = VectorStoreIndex.from_documents(docs, service_context=service_context)
|
||||||
|
return index
|
||||||
|
|
||||||
|
|
||||||
|
def display_chat_history():
|
||||||
|
"""Display the chat message history."""
|
||||||
|
for message in st.session_state.messages:
|
||||||
|
with st.chat_message(message["role"]):
|
||||||
|
st.write(message["content"])
|
||||||
|
|
||||||
|
|
||||||
|
def generate_response(prompt, chat_engine):
|
||||||
|
"""Generate a response from the chat engine and update the chat history."""
|
||||||
|
if prompt:
|
||||||
|
st.session_state.messages.append({"role": "user", "content": prompt})
|
||||||
|
|
||||||
|
with st.chat_message("assistant"):
|
||||||
|
with st.spinner("Thinking..."):
|
||||||
|
response = chat_engine.chat(prompt)
|
||||||
|
st.write(response.response)
|
||||||
|
st.session_state.messages.append({"role": "assistant", "content": response.response})
|
||||||
|
|
||||||
|
|
||||||
|
def alwrity_chat_docqa():
|
||||||
|
"""Main function to run the Streamlit app."""
|
||||||
|
st.header("Ask Alwrity 💬 📚")
|
||||||
|
initialize_session_state()
|
||||||
|
option = st.radio(
|
||||||
|
"Choose Data Source To Ask From:",
|
||||||
|
("Ask Your Local Docs", "Ask Your PDFs", "Ask Your Videos", "Ask Your Audio Files")
|
||||||
|
)
|
||||||
|
|
||||||
|
if option == "Ask Your Local Docs":
|
||||||
|
input_dir = st.text_input("Enter the path to the folder:")
|
||||||
|
if input_dir:
|
||||||
|
st.session_state.input_dir = input_dir
|
||||||
|
|
||||||
|
elif option == "Ask Your PDFs":
|
||||||
|
pdf_file = st.file_uploader("Upload a PDF file or enter a URL:", type=["pdf"])
|
||||||
|
if pdf_file:
|
||||||
|
st.session_state.input_file = pdf_file
|
||||||
|
|
||||||
|
elif option == "Ask Your Videos":
|
||||||
|
video_dir = st.text_input("Enter the path to the video folder:")
|
||||||
|
if video_dir:
|
||||||
|
st.session_state.input_dir = video_dir
|
||||||
|
|
||||||
|
elif option == "Ask Your Audio Files":
|
||||||
|
audio_dir = st.text_input("Enter the path to the audio folder:")
|
||||||
|
if audio_dir:
|
||||||
|
st.session_state.input_dir = audio_dir
|
||||||
|
|
||||||
|
if 'input_dir' in st.session_state:
|
||||||
|
index = load_data(st.session_state.input_dir)
|
||||||
|
chat_engine = index.as_chat_engine(chat_mode="condense_question", verbose=True)
|
||||||
|
display_chat_history()
|
||||||
|
prompt = st.chat_input("Your question")
|
||||||
|
if st.session_state.messages[-1]["role"] != "assistant":
|
||||||
|
generate_response(prompt, chat_engine)
|
||||||
|
|
||||||
|
elif 'input_file' in st.session_state:
|
||||||
|
# Handle PDF file or URL input here
|
||||||
|
st.write("Handling PDF file or URL input is not implemented yet.")
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
import os
|
import os
|
||||||
|
import streamlit as st
|
||||||
|
|
||||||
from crewai import Agent, Task, Crew
|
from crewai import Agent, Task, Crew
|
||||||
from crewai_tools import SerperDevTool
|
from crewai_tools import SerperDevTool
|
||||||
from langchain_google_genai import ChatGoogleGenerativeAI
|
from langchain_google_genai import ChatGoogleGenerativeAI
|
||||||
@@ -162,7 +164,7 @@ def create_agents(search_keywords, already_written_on):
|
|||||||
def create_tasks(agents, search_keywords, already_written_on):
|
def create_tasks(agents, search_keywords, already_written_on):
|
||||||
research_task = Task(
|
research_task = Task(
|
||||||
description=f"""Conduct web analysis on "{search_keywords}",for content calender.
|
description=f"""Conduct web analysis on "{search_keywords}",for content calender.
|
||||||
Set the input parameter as : search_query""",
|
Set the input parameter 'search_query' to query""",
|
||||||
expected_output=f"""Provide comprehensive content calender ideas to Senior Content Strategist & planner - Ted XingPi""",
|
expected_output=f"""Provide comprehensive content calender ideas to Senior Content Strategist & planner - Ted XingPi""",
|
||||||
agent=agents[0] # Assign to the researcher agent
|
agent=agents[0] # Assign to the researcher agent
|
||||||
)
|
)
|
||||||
@@ -170,7 +172,7 @@ def create_tasks(agents, search_keywords, already_written_on):
|
|||||||
google_trends_task = Task(
|
google_trends_task = Task(
|
||||||
description=f"""Conduct Google Trends analysis, on keywords: {search_keywords}, from the file({os.getenv('SEARCH_SAVE_FILE')}).
|
description=f"""Conduct Google Trends analysis, on keywords: {search_keywords}, from the file({os.getenv('SEARCH_SAVE_FILE')}).
|
||||||
Suggest blog titles for content calender. Recommend high-volume, low-competition keywords with strong user intent.
|
Suggest blog titles for content calender. Recommend high-volume, low-competition keywords with strong user intent.
|
||||||
Set the input parameter as : file_path""",
|
Set the input parameter 'file_path' to {os.getenv('SEARCH_SAVE_FILE')}""",
|
||||||
expected_output=f"Provide comprehensive content calender ideas to Senior Content Strategist & planner - Ted XingPi",
|
expected_output=f"Provide comprehensive content calender ideas to Senior Content Strategist & planner - Ted XingPi",
|
||||||
agent=agents[1] # Assign to the researcher agent
|
agent=agents[1] # Assign to the researcher agent
|
||||||
)
|
)
|
||||||
@@ -189,7 +191,7 @@ def create_tasks(agents, search_keywords, already_written_on):
|
|||||||
description=f"""Make sure the content calender is optimised for keywords: '{search_keywords}'.
|
description=f"""Make sure the content calender is optimised for keywords: '{search_keywords}'.
|
||||||
Make sure the titles are unique, semantically unique and mitigate keyword cannabilization.
|
Make sure the titles are unique, semantically unique and mitigate keyword cannabilization.
|
||||||
Use context & insights from Aisha Sharma, Ted XingPi & Sarah Qureshi.
|
Use context & insights from Aisha Sharma, Ted XingPi & Sarah Qureshi.
|
||||||
Set the input parameter file_path to {already_written_on}
|
Set the input parameter 'file_path' to {already_written_on}
|
||||||
""",
|
""",
|
||||||
expected_output=f"""Final content calender for the next 2 months. Targeting 5 articles per week.
|
expected_output=f"""Final content calender for the next 2 months. Targeting 5 articles per week.
|
||||||
Make sure to present the content calender in tabular format. Include details of how to use the content calender.
|
Make sure to present the content calender in tabular format. Include details of how to use the content calender.
|
||||||
@@ -201,6 +203,8 @@ def create_tasks(agents, search_keywords, already_written_on):
|
|||||||
|
|
||||||
|
|
||||||
def execute_tasks(agents, tasks):
|
def execute_tasks(agents, tasks):
|
||||||
|
""" WIP """
|
||||||
|
result = None
|
||||||
crew = Crew(
|
crew = Crew(
|
||||||
agents=agents,
|
agents=agents,
|
||||||
tasks=tasks,
|
tasks=tasks,
|
||||||
@@ -209,17 +213,23 @@ def execute_tasks(agents, tasks):
|
|||||||
#memory=True,
|
#memory=True,
|
||||||
language="en"
|
language="en"
|
||||||
)
|
)
|
||||||
result = crew.kickoff()
|
try:
|
||||||
return result
|
result = crew.kickoff()
|
||||||
|
return result
|
||||||
|
except Exception as err:
|
||||||
|
print(err)
|
||||||
|
|
||||||
|
|
||||||
def ai_agents_planner(search_keywords):
|
def ai_agents_planner(search_keywords):
|
||||||
already_written_on = os.path.join(os.getcwd(), "lib", "content_planning_calender", "content_already_planned.txt")
|
already_written_on = os.path.join(os.getcwd(), "lib", "content_planning_calender", "content_already_planned.txt")
|
||||||
do_google_trends_analysis(search_keywords)
|
do_google_trends_analysis(search_keywords)
|
||||||
|
result = None
|
||||||
#setup_environment()
|
#setup_environment()
|
||||||
agents = create_agents(search_keywords, already_written_on)
|
try:
|
||||||
tasks = create_tasks(agents, search_keywords, already_written_on)
|
agents = create_agents(search_keywords, already_written_on)
|
||||||
result = execute_tasks(agents, tasks)
|
tasks = create_tasks(agents, search_keywords, already_written_on)
|
||||||
print("########## Final Output Result ############")
|
result = execute_tasks(agents, tasks)
|
||||||
print(result)
|
except Exception as err:
|
||||||
|
print(err)
|
||||||
|
st.markdown("### Final Content Calender:")
|
||||||
|
st.markdown(result)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import streamlit as st
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import configparser
|
import configparser
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
import uuid
|
||||||
|
|
||||||
from rich import print
|
from rich import print
|
||||||
from lib.ai_web_researcher.gpt_online_researcher import gpt_web_researcher
|
from lib.ai_web_researcher.gpt_online_researcher import gpt_web_researcher
|
||||||
@@ -29,43 +30,42 @@ def blog_from_keyword():
|
|||||||
""" Input blog keywords, research and write a factual blog."""
|
""" Input blog keywords, research and write a factual blog."""
|
||||||
st.markdown("<div class='sub-header'>Blog from Keywords</div>", unsafe_allow_html=True)
|
st.markdown("<div class='sub-header'>Blog from Keywords</div>", unsafe_allow_html=True)
|
||||||
|
|
||||||
content_keywords = st.text_input('Enter Keywords/Blog Title',
|
blog_keywords = st.text_input('Enter Keywords/Blog Title',
|
||||||
help='Check your keywords against Google search, if you get good search results, you will get good content with Alwrity.',
|
help='Check your keywords against Google search, if you get good search results, you will get good content with Alwrity.',
|
||||||
placeholder='Shit in, Shit Out; Better keywords, better research, hence better content.\n👋 :')
|
placeholder='Shit in, Shit Out; Better keywords, better research, hence better content.\n👋 :')
|
||||||
|
|
||||||
if content_keywords and len(content_keywords.split()) < 2:
|
if blog_keywords and len(blog_keywords.split()) < 2:
|
||||||
st.error('🚫 Blog keywords should be at least two words long. Please try again.')
|
st.error('🚫 Blog keywords should be at least two words long. Please try again.')
|
||||||
|
|
||||||
content_type = st.selectbox("Select content type:", ["Normal-length content", "Long-form content", "Experimental - AI Agents team"])
|
content_type = st.selectbox("Select content type:", ["Normal-length content", "Long-form content", "Experimental - AI Agents team"])
|
||||||
if st.button("Write Blog"):
|
if st.button("Write Blog"):
|
||||||
# Clear the previous results from the screen
|
# Clear the previous results from the screen
|
||||||
st.empty()
|
st.empty()
|
||||||
if content_keywords and len(content_keywords.split()) >= 2:
|
if blog_keywords and len(blog_keywords.split()) >= 2:
|
||||||
if content_type == "Normal-length content":
|
if content_type == "Normal-length content":
|
||||||
try:
|
try:
|
||||||
short_blog = write_blog_from_keywords(content_keywords)
|
short_blog = write_blog_from_keywords(blog_keywords)
|
||||||
st.markdown(short_blog)
|
st.markdown(short_blog)
|
||||||
st.success(f"Successfully wrote blog on: {content_keywords}")
|
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
st.error(f"🚫 Failed to write blog on {content_keywords}, Error: {err}")
|
st.error(f"🚫 Failed to write blog on {blog_keywords}, Error: {err}")
|
||||||
elif content_type == "Long-form content":
|
elif content_type == "Long-form content":
|
||||||
try:
|
try:
|
||||||
st.empty()
|
st.empty()
|
||||||
long_form_generator(content_keywords)
|
long_form_generator(blog_keywords)
|
||||||
st.success(f"Successfully wrote long-form blog on: {content_keywords}")
|
st.success(f"Successfully wrote long-form blog on: {blog_keywords}")
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
st.error(f"🚫 Failed to write blog on {content_keywords}, Error: {err}")
|
st.error(f"🚫 Failed to write blog on {blog_keywords}, Error: {err}")
|
||||||
elif content_type == "Experimental - AI Agents team":
|
elif content_type == "Experimental - AI Agents team":
|
||||||
try:
|
try:
|
||||||
ai_agents_writers(content_keywords)
|
ai_agents_writers(blog_keywords)
|
||||||
st.success(f"Successfully wrote content with AI agents on: {content_keywords}")
|
st.success(f"Successfully wrote content with AI agents on: {blog_keywords}")
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
st.error(f"🚫 Failed to Write content with AI agents: {err}")
|
st.error(f"🚫 Failed to Write content with AI agents: {err}")
|
||||||
|
|
||||||
|
|
||||||
def ai_agents_team():
|
def ai_agents_team():
|
||||||
# Define options for AI Content Teams
|
# Define options for AI Content Teams
|
||||||
st.title("🧚🐲 AI Agents Content Teams")
|
st.title("🧚🐲 Your AI Agents Teams")
|
||||||
st.markdown("""Alwrity offers AI agents team for content creators to easily modify them for their needs.
|
st.markdown("""Alwrity offers AI agents team for content creators to easily modify them for their needs.
|
||||||
Abstracting tech & plumbing, easily define role, goal, task. Use different AI agents framework.""")
|
Abstracting tech & plumbing, easily define role, goal, task. Use different AI agents framework.""")
|
||||||
options = [
|
options = [
|
||||||
@@ -77,16 +77,33 @@ def ai_agents_team():
|
|||||||
selected_team = st.selectbox("**Choose AI Agents Team:**", options)
|
selected_team = st.selectbox("**Choose AI Agents Team:**", options)
|
||||||
|
|
||||||
if selected_team == "AI Content Ideation & Planning Team":
|
if selected_team == "AI Content Ideation & Planning Team":
|
||||||
content_planning_agents()
|
st.title("AI Agents for Content Ideation")
|
||||||
|
plan_keywords = st.text_input(
|
||||||
|
"Enter Keywords to get 2 months content calender:",
|
||||||
|
placeholder="Enter keywords to generate AI content calendar:",
|
||||||
|
help="Enter at least two words for better results."
|
||||||
|
)
|
||||||
|
if st.button("Get calender"):
|
||||||
|
if plan_keywords and len(plan_keywords.split()) >= 2:
|
||||||
|
with st.spinner("Get Content Plan..."):
|
||||||
|
try:
|
||||||
|
plan_content = ai_agents_planner(plan_keywords)
|
||||||
|
st.success(f"Successfully generated content plan for: {plan_keywords}")
|
||||||
|
st.markdown(plan_content)
|
||||||
|
except Exception as err:
|
||||||
|
st.error(f"Failed to generate content plan: {err}")
|
||||||
|
else:
|
||||||
|
st.error("🚫 Single keywords are just too vague. Try again.")
|
||||||
|
|
||||||
elif selected_team == "AI Content Creation Team":
|
elif selected_team == "AI Content Creation Team":
|
||||||
content_creation_agents()
|
content_agents()
|
||||||
|
|
||||||
|
|
||||||
def content_creation_agents():
|
def content_agents():
|
||||||
st.markdown("<div class='sub-header'>AI Agents Team for Content Creation</div>", unsafe_allow_html=True)
|
st.markdown("AI Agents Team for Content Writing")
|
||||||
content_keywords = st.text_input(
|
content_keywords = st.text_input(
|
||||||
"Enter Main Domain Keywords of your business:",
|
"Enter Main Domain Keywords of your business:",
|
||||||
placeholder="Better keywords, Better content calendar:",
|
placeholder="Better keywords, Better content. Get keywords from Google search",
|
||||||
help="These keywords define your main business sector, blogging niche, Industry, domain etc"
|
help="These keywords define your main business sector, blogging niche, Industry, domain etc"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -103,27 +120,6 @@ def content_creation_agents():
|
|||||||
st.error("🚫 Single keywords are just too vague. Try again.")
|
st.error("🚫 Single keywords are just too vague. Try again.")
|
||||||
|
|
||||||
|
|
||||||
def content_planning_agents():
|
|
||||||
st.markdown("<div class='sub-header'>AI Agents Team for Content Ideation</div>", unsafe_allow_html=True)
|
|
||||||
content_keywords = st.text_input(
|
|
||||||
"Enter Main Domain Keywords of your business:",
|
|
||||||
placeholder="Better keywords will generate better content calendar:",
|
|
||||||
help="Enter at least two words for better results."
|
|
||||||
)
|
|
||||||
|
|
||||||
if st.button("Generate Content Plan"):
|
|
||||||
if content_keywords and len(content_keywords.split()) >= 2:
|
|
||||||
with st.spinner("Generating Content Plan..."):
|
|
||||||
try:
|
|
||||||
plan_content = ai_agents_planner(content_keywords)
|
|
||||||
st.success(f"Successfully generated content plan for: {content_keywords}")
|
|
||||||
st.markdown(plan_content)
|
|
||||||
except Exception as err:
|
|
||||||
st.error(f"Failed to generate content plan: {err}")
|
|
||||||
else:
|
|
||||||
st.error("🚫 Single keywords are just too vague. Try again.")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def blog_from_audio():
|
def blog_from_audio():
|
||||||
"""
|
"""
|
||||||
@@ -372,6 +368,52 @@ def ai_news_writer():
|
|||||||
st.error(f"Failed to generate news report: {err}")
|
st.error(f"Failed to generate news report: {err}")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def competitor_analysis():
|
||||||
|
st.title("Competitor Analysis")
|
||||||
|
st.markdown("""**Use Cases:**
|
||||||
|
- Know similar companies and alternatives for the given URL.
|
||||||
|
- Write listicles, similar companies, Top tools, alternative-to, similar products, similar websites, etc.
|
||||||
|
[Read More Here](https://docs.exa.ai/reference/company-analyst)
|
||||||
|
""")
|
||||||
|
|
||||||
|
similar_url = st.text_input("👋 Enter a single valid URL for web analysis:",
|
||||||
|
placeholder="Provide a competitor's URL and get details of similar/alternative companies.")
|
||||||
|
|
||||||
|
if st.button("Analyze"):
|
||||||
|
if similar_url:
|
||||||
|
try:
|
||||||
|
st.info(f"Starting analysis for the URL: {similar_url}")
|
||||||
|
with st.spinner("Performing competitor analysis..."):
|
||||||
|
result = metaphor_find_similar(similar_url)
|
||||||
|
st.success("Analysis completed successfully!")
|
||||||
|
st.write(result)
|
||||||
|
except Exception as err:
|
||||||
|
st.error(f"✖ 🚫 Failed to do similar search.\nError: {err}")
|
||||||
|
else:
|
||||||
|
st.error("Please enter a valid URL.")
|
||||||
|
|
||||||
|
|
||||||
|
def do_web_research():
|
||||||
|
""" Input keywords and do web research and present a report."""
|
||||||
|
st.title("Web Research Assistant")
|
||||||
|
st.write("Enter keywords for web research. The keywords should be at least three words long.")
|
||||||
|
|
||||||
|
search_keywords = st.text_input("Search Keywords", placeholder="Enter keywords for web research...")
|
||||||
|
if st.button("Start Web Research"):
|
||||||
|
if search_keywords and len(search_keywords.split()) >= 3:
|
||||||
|
try:
|
||||||
|
st.info(f"Starting web research on given keywords: {search_keywords}")
|
||||||
|
with st.spinner("Performing web research..."):
|
||||||
|
web_research_result = gpt_web_researcher(search_keywords)
|
||||||
|
st.success("Web research completed successfully!")
|
||||||
|
st.write(web_research_result)
|
||||||
|
except Exception as err:
|
||||||
|
st.error(f"ERROR: Failed to do web research: {err}")
|
||||||
|
else:
|
||||||
|
st.warning("Search keywords should be at least three words long. Please try again.")
|
||||||
|
|
||||||
|
|
||||||
def ai_finance_ta_writer():
|
def ai_finance_ta_writer():
|
||||||
st.markdown("<div class='sub-header'>AI Financial Technical Analysis Writer</div>", unsafe_allow_html=True)
|
st.markdown("<div class='sub-header'>AI Financial Technical Analysis Writer</div>", unsafe_allow_html=True)
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user