diff --git a/.gitignore b/.gitignore
index 74a3cefd..ff212253 100644
--- a/.gitignore
+++ b/.gitignore
@@ -52,6 +52,8 @@ web_research_report*
*.venv_*_*_*
*.venv_*_*_*_*
+website_analyzer.log
+
*venv
venv_new*
venv_*
diff --git a/lib/ai_seo_tools/meta_desc_generator.py b/lib/ai_seo_tools/meta_desc_generator.py
index c0ef0f37..69ad45ac 100644
--- a/lib/ai_seo_tools/meta_desc_generator.py
+++ b/lib/ai_seo_tools/meta_desc_generator.py
@@ -2,7 +2,9 @@ import os
import json
import streamlit as st
from tenacity import retry, stop_after_attempt, wait_random_exponential
-import google.generativeai as genai
+from loguru import logger
+import sys
+
from ..gpt_providers.text_generation.main_text_generation import llm_text_gen
@@ -103,5 +105,6 @@ def generate_blog_metadesc(keywords, tone, search_type, language):
try:
return llm_text_gen(prompt)
except Exception as err:
+ logger.error(f"Error generating meta description: {err}")
st.error(f"💥 Error: Failed to generate response from LLM: {err}")
return None
diff --git a/lib/ai_writers/ai_essay_writer.py b/lib/ai_writers/ai_essay_writer.py
index 06ecd08e..b13ef9ef 100644
--- a/lib/ai_writers/ai_essay_writer.py
+++ b/lib/ai_writers/ai_essay_writer.py
@@ -7,27 +7,29 @@
import os
from pathlib import Path
from dotenv import load_dotenv
-from google.api_core import retry
-import google.generativeai as genai
from pprint import pprint
+from loguru import logger
+import sys
+
+from ..gpt_providers.text_generation.main_text_generation import llm_text_gen
-def generate_with_retry(model, prompt):
+def generate_with_retry(prompt, system_prompt=None):
"""
- Generates content from the model with retry handling for errors.
+ Generates content using the llm_text_gen function with retry handling for errors.
Parameters:
- model (GenerativeModel): The generative model to use for content generation.
prompt (str): The prompt to generate content from.
+ system_prompt (str, optional): Custom system prompt to use instead of the default one.
Returns:
str: The generated content.
"""
try:
- # FIXME: Need a progress bar here.
- return model.generate_content(prompt, request_options={'retry':retry.Retry()})
+ # Use llm_text_gen instead of directly calling the model
+ return llm_text_gen(prompt, system_prompt)
except Exception as e:
- print(f"Error generating content: {e}")
+ logger.error(f"Error generating content: {e}")
return ""
@@ -36,11 +38,12 @@ def ai_essay_generator(essay_title, selected_essay_type, selected_education_leve
Write an Essay using prompt chaining and iterative generation.
Parameters:
- persona (str): The persona statement for the author.
- story_genre (str): The genre of the story.
- characters (str): The characters in the story.
+ essay_title (str): The title or topic of the essay.
+ selected_essay_type (str): The type of essay to write.
+ selected_education_level (str): The education level of the target audience.
+ selected_num_pages (int): The number of pages or words for the essay.
"""
- print(f"Starting to write Essay on {essay_title}..")
+ logger.info(f"Starting to write Essay on {essay_title}..")
try:
# Define persona and writing guidelines
guidelines = f'''\
@@ -127,59 +130,55 @@ def ai_essay_generator(essay_title, selected_essay_type, selected_education_leve
{guidelines}
'''
- # Configure generative AI
- load_dotenv(Path('../.env'))
- genai.configure(api_key=os.getenv('GEMINI_API_KEY'))
- # Initialize the generative model
- model = genai.GenerativeModel('gemini-pro')
-
# Generate prompts
try:
- premise = generate_with_retry(model, premise_prompt).text
- print(f"The title of the Essay is: {premise}")
+ premise = generate_with_retry(premise_prompt)
+ logger.info(f"The title of the Essay is: {premise}")
except Exception as err:
- print(f"Essay title Generation Error: {err}")
+ logger.error(f"Essay title Generation Error: {err}")
return
- outline = generate_with_retry(model, outline_prompt.format(premise=premise)).text
- print(f"The Outline of the essay is: {outline}\n\n")
+ outline = generate_with_retry(outline_prompt.format(premise=premise))
+ logger.info(f"The Outline of the essay is: {outline}\n\n")
if not outline:
- print("Failed to generate Essay outline. Exiting...")
+ logger.error("Failed to generate Essay outline. Exiting...")
return
try:
- starting_draft = generate_with_retry(model,
- starting_prompt.format(premise=premise, outline=outline)).text
+ starting_draft = generate_with_retry(
+ starting_prompt.format(premise=premise, outline=outline))
pprint(starting_draft)
except Exception as err:
- print(f"Failed to Generate Essay draft: {err}")
+ logger.error(f"Failed to Generate Essay draft: {err}")
return
try:
draft = starting_draft
- continuation = generate_with_retry(model,
- continuation_prompt.format(premise=premise, outline=outline, story_text=draft)).text
+ continuation = generate_with_retry(
+ continuation_prompt.format(premise=premise, outline=outline, story_text=draft))
pprint(continuation)
except Exception as err:
- print(f"Failed to write the initial draft: {err}")
+ logger.error(f"Failed to write the initial draft: {err}")
# Add the continuation to the initial draft, keep building the story until we see 'IAMDONE'
try:
draft += '\n\n' + continuation
except Exception as err:
- print(f"Failed as: {err} and {continuation}")
+ logger.error(f"Failed as: {err} and {continuation}")
while 'IAMDONE' not in continuation:
try:
- continuation = generate_with_retry(model,
- continuation_prompt.format(premise=premise, outline=outline, story_text=draft)).text
+ continuation = generate_with_retry(
+ continuation_prompt.format(premise=premise, outline=outline, story_text=draft))
draft += '\n\n' + continuation
except Exception as err:
- print(f"Failed to continually write the Essay: {err}")
+ logger.error(f"Failed to continually write the Essay: {err}")
return
# Remove 'IAMDONE' and print the final story
final = draft.replace('IAMDONE', '').strip()
pprint(final)
+ return final
except Exception as e:
- print(f"Main Essay writing: An error occurred: {e}")
+ logger.error(f"Main Essay writing: An error occurred: {e}")
+ return ""
diff --git a/lib/ai_writers/ai_facebook_writer/facebook_ai_writer.py b/lib/ai_writers/ai_facebook_writer/facebook_ai_writer.py
index 683599b0..30ac1cf4 100644
--- a/lib/ai_writers/ai_facebook_writer/facebook_ai_writer.py
+++ b/lib/ai_writers/ai_facebook_writer/facebook_ai_writer.py
@@ -15,14 +15,14 @@ from pathlib import Path
from ...gpt_providers.text_generation.main_text_generation import llm_text_gen
from .modules.post_generator import write_fb_post
from .modules.story_generator import write_fb_story
-from .modules.reel_generator import write_fb_reel
-from .modules.carousel_generator import write_fb_carousel
-from .modules.event_generator import write_fb_event
-from .modules.group_post_generator import write_fb_group_post
-from .modules.page_about_generator import write_fb_page_about
-from .modules.ad_copy_generator import write_fb_ad_copy
-from .modules.hashtag_generator import write_fb_hashtags
-from .modules.engagement_analyzer import analyze_fb_engagement
+#from .modules.reel_generator import write_fb_reel
+#from .modules.carousel_generator import write_fb_carousel
+#from .modules.event_generator import write_fb_event
+#from .modules.group_post_generator import write_fb_group_post
+#from .modules.page_about_generator import write_fb_page_about
+#from .modules.ad_copy_generator import write_fb_ad_copy
+#from .modules.hashtag_generator import write_fb_hashtags
+#from .modules.engagement_analyzer import analyze_fb_engagement
#from streamlit_quill import st_quill
diff --git a/lib/ai_writers/ai_facebook_writer/modules/post_generator.py b/lib/ai_writers/ai_facebook_writer/modules/post_generator.py
index 3358e188..a16e383a 100644
--- a/lib/ai_writers/ai_facebook_writer/modules/post_generator.py
+++ b/lib/ai_writers/ai_facebook_writer/modules/post_generator.py
@@ -6,8 +6,8 @@ and optimization options.
"""
import streamlit as st
-from ...gpt_providers.text_generation.main_text_generation import llm_text_gen
-from ...gpt_providers.image_generation.main_image_generation import generate_image
+from ....gpt_providers.text_generation.main_text_generation import llm_text_gen
+from ....gpt_providers.text_to_image_generation.main_generate_image_from_prompt import generate_image
def write_fb_post():
diff --git a/lib/ai_writers/ai_facebook_writer/modules/story_generator.py b/lib/ai_writers/ai_facebook_writer/modules/story_generator.py
index 492888ea..9ee8b56e 100644
--- a/lib/ai_writers/ai_facebook_writer/modules/story_generator.py
+++ b/lib/ai_writers/ai_facebook_writer/modules/story_generator.py
@@ -6,8 +6,8 @@ and customization options.
"""
import streamlit as st
-from ...gpt_providers.text_generation.main_text_generation import llm_text_gen
-from ...gpt_providers.image_generation.main_image_generation import generate_image
+from ....gpt_providers.text_generation.main_text_generation import llm_text_gen
+from ....gpt_providers.text_to_image_generation.main_generate_image_from_prompt import generate_image
def write_fb_story():
diff --git a/lib/ai_writers/ai_story_writer/ai_story_generator.py b/lib/ai_writers/ai_story_writer/ai_story_generator.py
index 34368b48..826c6c0d 100644
--- a/lib/ai_writers/ai_story_writer/ai_story_generator.py
+++ b/lib/ai_writers/ai_story_writer/ai_story_generator.py
@@ -6,27 +6,29 @@
import os
from pathlib import Path
-from google.api_core import retry
-import google.generativeai as genai
import streamlit as st
+from loguru import logger
+import sys
+
+from ...gpt_providers.text_generation.main_text_generation import llm_text_gen
-def generate_with_retry(model, prompt):
+def generate_with_retry(prompt, system_prompt=None):
"""
- Generates content from the model with retry handling for errors.
+ Generates content using the llm_text_gen function with retry handling for errors.
Parameters:
- model (GenerativeModel): The generative model to use for content generation.
prompt (str): The prompt to generate content from.
+ system_prompt (str, optional): Custom system prompt to use instead of the default one.
Returns:
str: The generated content.
"""
try:
- # FIXME: Need a progress bar here.
- return model.generate_content(prompt, request_options={'retry':retry.Retry()})
+ # Use llm_text_gen instead of directly calling the model
+ return llm_text_gen(prompt, system_prompt)
except Exception as e:
- print(f"Error generating content: {e}")
+ logger.error(f"Error generating content: {e}")
return ""
@@ -38,8 +40,15 @@ def ai_story(persona, story_setting, character_input,
Parameters:
persona (str): The persona statement for the author.
- story_genre (str): The genre of the story.
- characters (str): The characters in the story.
+ story_setting (str): The setting of the story.
+ character_input (str): The characters in the story.
+ plot_elements (str): The plot elements of the story.
+ writing_style (str): The writing style of the story.
+ story_tone (str): The tone of the story.
+ narrative_pov (str): The narrative point of view.
+ audience_age_group (str): The target audience age group.
+ content_rating (str): The content rating of the story.
+ ending_preference (str): The preferred ending of the story.
"""
st.info(f"""
You have chosen to create a story set in **{story_setting}**.
@@ -170,20 +179,16 @@ def ai_story(persona, story_setting, character_input,
{guidelines}
'''
-
- genai.configure(api_key=os.getenv('GEMINI_API_KEY'))
- # Initialize the generative model
- model = genai.GenerativeModel('gemini-1.5-flash')
# Generate prompts
try:
- premise = generate_with_retry(model, premise_prompt).text
+ premise = generate_with_retry(premise_prompt)
st.info(f"The premise of the story is: {premise}")
except Exception as err:
st.error(f"Premise Generation Error: {err}")
return
- outline = generate_with_retry(model, outline_prompt.format(premise=premise)).text
+ outline = generate_with_retry(outline_prompt.format(premise=premise))
with st.expander("Click to Checkout the outline, writing still in progress.."):
st.markdown(f"The Outline of the story is: {outline}\n\n")
@@ -193,16 +198,16 @@ def ai_story(persona, story_setting, character_input,
# Generate starting draft
try:
- starting_draft = generate_with_retry(model,
- starting_prompt.format(premise=premise, outline=outline)).text
+ starting_draft = generate_with_retry(
+ starting_prompt.format(premise=premise, outline=outline))
except Exception as err:
st.error(f"Failed to Generate Story draft: {err}")
return
try:
draft = starting_draft
- continuation = generate_with_retry(model,
- continuation_prompt.format(premise=premise, outline=outline, story_text=draft)).text
+ continuation = generate_with_retry(
+ continuation_prompt.format(premise=premise, outline=outline, story_text=draft))
except Exception as err:
st.error(f"Failed to write the initial draft: {err}")
@@ -217,8 +222,8 @@ def ai_story(persona, story_setting, character_input,
while 'IAMDONE' not in continuation:
try:
status.update(label=f"Writing in progress... Current draft length: {len(draft)} characters")
- continuation = generate_with_retry(model,
- continuation_prompt.format(premise=premise, outline=outline, story_text=draft)).text
+ continuation = generate_with_retry(
+ continuation_prompt.format(premise=premise, outline=outline, story_text=draft))
draft += '\n\n' + continuation
except Exception as err:
st.error(f"Failed to continually write the story: {err}")
@@ -230,3 +235,4 @@ def ai_story(persona, story_setting, character_input,
except Exception as e:
st.error(f"Main Story writing: An error occurred: {e}")
+ return ""
diff --git a/lib/ai_writers/image_ai_writer.py b/lib/ai_writers/image_ai_writer.py
index 5ec53509..64a4ae6f 100644
--- a/lib/ai_writers/image_ai_writer.py
+++ b/lib/ai_writers/image_ai_writer.py
@@ -2,7 +2,6 @@ import sys
import os
from textwrap import dedent
-from PIL import Image
import json
import asyncio
from pathlib import Path
@@ -23,8 +22,7 @@ from ..blog_metadata.get_blog_metadata import blog_metadata
from ..blog_postprocessing.save_blog_to_file import save_blog_to_file
from ..gpt_providers.text_to_image_generation.main_generate_image_from_prompt import generate_image
from ..gpt_providers.text_generation.main_text_generation import llm_text_gen
-
-import google.generativeai as genai
+from ..gpt_providers.image_to_text_gen.gemini_image_describe import describe_image, analyze_image_with_prompt
def blog_from_image(prompt, uploaded_img):
@@ -97,17 +95,15 @@ def write_blog_from_image(prompt, uploaded_img):
2). Tone and Brand Alignment: Adjust your tone, voice, personality for {blog_characteristics['Blog Tone']} audience.
3). Make sure your response content length is of {blog_characteristics['Blog Length']} words.
"""
- logger.info("Generating blog and FAQs from Google web search results.")
+ logger.info("Generating blog and FAQs from image analysis.")
try:
- #response = llm_text_gen(prompt)
- genai.configure(api_key=os.getenv('GEMINI_API_KEY'))
- version = 'models/gemini-1.5-flash'
- model = genai.GenerativeModel(version)
- model_info = genai.get_model(version)
- print(f'{version} - input limit: {model_info.input_token_limit}, output limit: {model_info.output_token_limit}')
- response = model.generate_content([prompt, Image.open(uploaded_img)])
- return response.text
+ # Use the gemini_image_describe function to analyze the image with the custom prompt
+ response = analyze_image_with_prompt(uploaded_img, prompt)
+ if not response:
+ logger.error("Failed to get response from image analysis")
+ return "Failed to generate content from image."
+ return response
except Exception as err:
- logger.error(f"Exit: Failed to get response from LLM: {err}")
+ logger.error(f"Exit: Failed to get response from image analysis: {err}")
exit(1)
diff --git a/lib/ai_writers/long_form_ai_writer.py b/lib/ai_writers/long_form_ai_writer.py
index 2f8c919e..d3401236 100644
--- a/lib/ai_writers/long_form_ai_writer.py
+++ b/lib/ai_writers/long_form_ai_writer.py
@@ -15,8 +15,6 @@ from dotenv import load_dotenv
from configparser import ConfigParser
import streamlit as st
-from google.api_core import retry
-import google.generativeai as genai
from pprint import pprint
from textwrap import dedent
@@ -32,22 +30,23 @@ from ..ai_web_researcher.gpt_online_researcher import do_metaphor_ai_research
from ..ai_web_researcher.gpt_online_researcher import do_google_serp_search, do_tavily_ai_search
from ..blog_metadata.get_blog_metadata import get_blog_metadata_longform
from ..blog_postprocessing.save_blog_to_file import save_blog_to_file
+from ..gpt_providers.text_generation.main_text_generation import llm_text_gen
-def generate_with_retry(model, prompt):
+def generate_with_retry(prompt, system_prompt=None):
"""
Generates content from the model with retry handling for errors.
Parameters:
- model (GenerativeModel): The generative model to use for content generation.
prompt (str): The prompt to generate content from.
+ system_prompt (str, optional): Custom system prompt to use instead of the default one.
Returns:
str: The generated content.
"""
try:
# FIXME: Need a progress bar here.
- return model.generate_content(prompt, request_options={'retry':retry.Retry()})
+ return llm_text_gen(prompt, system_prompt)
except Exception as e:
logger.error(f"Error generating content: {e}")
st.error(f"Error generating content: {e}")
@@ -57,7 +56,12 @@ def generate_with_retry(model, prompt):
def long_form_generator(content_keywords):
"""
Write long form content using prompt chaining and iterative generation.
+
Parameters:
+ content_keywords (str): The main keywords or topic for the long-form content.
+
+ Returns:
+ str: The generated long-form content.
"""
with st.status("Start Writing Long Form Article, Hold my Beer..", expanded=True) as status:
# Read the main_config to define tone, character, personality of the content to be generated.
@@ -122,39 +126,27 @@ def long_form_generator(content_keywords):
writing_guidelines=writing_guidelines
)
- # Configure generative AI
- load_dotenv(Path('../.env'))
- generation_config = {
- "temperature": 0.7,
- "top_p": 1,
- "max_output_tokens": 8096,
- }
-
- genai.configure(api_key=os.getenv('GEMINI_API_KEY'))
- # Initialize the generative model
- model_flash = genai.GenerativeModel('gemini-1.5-flash', generation_config=generation_config)
- model_pro = genai.GenerativeModel('gemini-pro', generation_config=generation_config)
-
# Do SERP web research for given keywords to generate title and outline.
web_research_result, g_titles = do_google_serp_search(content_keywords)
# Generate prompts
try:
- content_title = generate_with_retry(model_pro, content_title.format(web_research_result=web_research_result)).text
+ content_title = generate_with_retry(content_title.format(web_research_result=web_research_result))
logger.info(f"The title of the content is: {content_title}")
status.update(label=f"The title of the content is: {content_title}")
except Exception as err:
logger.error(f"Content title Generation Error: {err}")
- return
+ return False
try:
- content_outline = generate_with_retry(model_flash, content_outline.format(
+ content_outline = generate_with_retry(content_outline.format(
content_title=content_title,
- web_research_result=web_research_result)).text
+ web_research_result=web_research_result))
logger.info(f"The content Outline is: {content_outline}\n\n")
status.update(label=f"Completed with Content Outline.")
except Exception as err:
logger.error(f"Failed to generate content outline: {err}")
+ return False
try:
status.update(label=f"Do web research with Tavily to provide context for content creation.")
@@ -170,36 +162,38 @@ def long_form_generator(content_keywords):
except Exception as err:
logger.error(f"Failed to do Tavily AI search: {err}")
st.error(f"Failed to do Tavily AI search: {err}")
- return
+ return False
try:
- starting_draft = generate_with_retry(model_pro, starting_prompt.format(
+ starting_draft = generate_with_retry(starting_prompt.format(
content_title=content_title,
content_outline=content_outline,
web_research_result=web_research_result,
- writing_guidelines=writing_guidelines)).text
+ writing_guidelines=writing_guidelines))
except Exception as err:
st.error(f"Failed to Generate Starting draft: {err}")
logger.error(f"Failed to Generate Starting draft: {err}")
- return
+ return False
try:
logger.info(f"Starting to write on the outline introduction.")
draft = starting_draft
- continuation = generate_with_retry(model_pro, continuation_prompt.format(
+ continuation = generate_with_retry(continuation_prompt.format(
content_title=content_title,
content_outline=content_outline,
content_text=draft,
web_research_result=web_research_result,
- writing_guidelines=writing_guidelines)).text
+ writing_guidelines=writing_guidelines))
except Exception as err:
logger.error(f"Failed to write the initial draft: {err}")
+ return False
# Add the continuation to the initial draft, keep building the story until we see 'IAMDONE'
try:
draft += '\n\n' + continuation
except Exception as err:
logger.error(f"Failed as: {err} and {continuation}")
+ return False
logger.info(f"Writing in progress... Current draft length: {len(draft)} characters")
status.update(label=f"Writing in progress... Current draft length: {len(draft)} characters")
@@ -211,7 +205,7 @@ def long_form_generator(content_keywords):
Content Outline:\n
'{content_outline}'
"""
- search_words = generate_with_retry(model_flash, search_terms).text
+ search_words = generate_with_retry(search_terms)
status.update(label=f"Search terms from written draft: {search_words}")
while 'IAMDONE' not in continuation:
@@ -230,12 +224,12 @@ def long_form_generator(content_keywords):
# web_research_result = table_data
try:
- continuation = generate_with_retry(model_pro, continuation_prompt.format(
+ continuation = generate_with_retry(continuation_prompt.format(
content_title=content_title,
content_outline=content_outline,
content_text=draft,
web_research_result=web_research_result,
- writing_guidelines=writing_guidelines)).text
+ writing_guidelines=writing_guidelines))
draft += '\n\n' + continuation
logger.info(f"Writing in progress... Current draft length: {len(draft)} characters")
@@ -245,7 +239,7 @@ def long_form_generator(content_keywords):
except Exception as err:
st.error(f"Failed to continually write long-form content: {err}")
logger.error(f"Failed to continually write the Essay: {err}")
- return
+ return False
# Remove 'IAMDONE' and print the final story
final = draft.replace('IAMDONE', '').strip()
@@ -267,3 +261,26 @@ def long_form_generator(content_keywords):
logger.info(f"\n\n ################ Finished writing Blog for : {content_keywords} #################### \n")
with st.expander("**Click to View the final content draft:**"):
st.markdown(f"\n{final}\n\n")
+
+ return final
+
+
+def generate_long_form_content(content_keywords):
+ """
+ Main function to generate long-form content based on the provided keywords.
+
+ Parameters:
+ content_keywords (str): The main keywords or topic for the long-form content.
+
+ Returns:
+ str: The generated long-form content.
+ """
+ return long_form_generator(content_keywords)
+
+
+# Example usage
+if __name__ == "__main__":
+ # Example usage of the function
+ content_keywords = "artificial intelligence in healthcare"
+ generated_content = generate_long_form_content(content_keywords)
+ print(f"Generated content: {generated_content[:100]}...")
diff --git a/lib/blog_metadata/get_blog_metadata.py b/lib/blog_metadata/get_blog_metadata.py
index dd34585b..1fe59044 100644
--- a/lib/blog_metadata/get_blog_metadata.py
+++ b/lib/blog_metadata/get_blog_metadata.py
@@ -12,8 +12,6 @@ logger.add(sys.stdout,
colorize=True,
format="