Gemini AI common code and utils

This commit is contained in:
ajaysi
2025-04-11 17:47:55 +05:30
parent b556edb989
commit e41be5789a
18 changed files with 590 additions and 262 deletions

View File

@@ -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 ""

View File

@@ -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

View File

@@ -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():

View File

@@ -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():

View File

@@ -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 ""

View File

@@ -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)

View File

@@ -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]}...")