AI story writer, UI & prompts improvements
This commit is contained in:
103
lib/ai_writers/ai_story_writer/README.md
Normal file
103
lib/ai_writers/ai_story_writer/README.md
Normal file
@@ -0,0 +1,103 @@
|
||||
# AI Story Generator App
|
||||
|
||||
In the age of AI, creativity and technology are intertwining in ways that are transforming how we tell stories. Imagine having the power to craft a captivating narrative tailored to your exact specifications with just a few clicks. Whether you're an aspiring writer, a seasoned novelist, or just someone who loves a good story, our new AI-powered story writing app is here to make storytelling easier and more engaging than ever before.
|
||||
|
||||
## Why an AI Story Writing App?
|
||||
|
||||
Storytelling has always been a cherished art form, but not everyone finds it easy to start from scratch. With the AI Story Generator App, you can create detailed and personalized stories by simply providing some key inputs. Our app uses advanced AI to turn your ideas into compelling narratives, helping you overcome writer's block and unleashing your creative potential.
|
||||
|
||||
## Features of the AI Story Generator App
|
||||
|
||||
### Genre
|
||||
Choose from a variety of genres such as Fantasy, Sci-Fi, Mystery, Romance, and Horror to set the tone for your story.
|
||||
|
||||
### Story Setting
|
||||
Provide a detailed setting for your story, including location and time period.
|
||||
|
||||
For example:
|
||||
A bustling futuristic city with towering skyscrapers and flying cars, set in the year 2150. The city is known for its technological advancements but has a dark underbelly of crime and corruption.
|
||||
|
||||
|
||||
### Main Characters
|
||||
Input the names, descriptions, and roles of your main characters.
|
||||
|
||||
For example:
|
||||
Character Names: John, Xishan, Amol
|
||||
Character Descriptions: John is a tall, muscular man with a kind heart. Xishan is a clever and resourceful woman. Amol is a mischievous and energetic young boy.
|
||||
Character Roles: John - Hero, Xishan - Sidekick, Amol - Supporting Character
|
||||
|
||||
|
||||
### Plot Elements
|
||||
Outline the key plot elements including the story theme, key events, and main conflict.
|
||||
|
||||
For example:
|
||||
Story Theme: Love conquers all, The hero's journey, Good vs. evil
|
||||
|
||||
Key Events or Plot Points:
|
||||
|
||||
The hero meets the villain
|
||||
The hero faces a challenge
|
||||
The hero overcomes the conflict
|
||||
Main Conflict or Problem:
|
||||
The hero must save the world from a powerful enemy, The hero must overcome a personal obstacle to achieve their goal.
|
||||
|
||||
|
||||
### Tone and Style
|
||||
Choose the writing style, tone, and narrative point of view for your story.
|
||||
|
||||
For example:
|
||||
Writing Style: Formal, Casual, Poetic, Humorous
|
||||
Story Tone: Dark
|
||||
|
||||
### Perspective
|
||||
Choose the narrative point of view from which the story is told (e.g., first person, third person limited, third person omniscient).
|
||||
|
||||
### Target Audience
|
||||
Specify the intended audience age group (Children, Young Adults, Adults) and set a content rating (G, PG, PG-13, R) for appropriateness.
|
||||
|
||||
### Ending Preference
|
||||
Select the type of ending you prefer for the story (e.g., happy, tragic, cliffhanger, twist).
|
||||
|
||||
## How to Use
|
||||
|
||||
Choose Genre: Select the genre that best fits your story idea.
|
||||
Set Story Setting: Describe the setting and time period where your story unfolds.
|
||||
Define Characters: Provide names, descriptions, and roles for your main characters.
|
||||
Outline Plot Elements: Detail the story's theme, key events, and main conflict.
|
||||
Select Tone and Style: Choose the writing style and tone that align with your story's mood.
|
||||
Specify Perspective: Decide on the narrative point of view.
|
||||
Target Audience: Specify the age group and content rating.
|
||||
Choose Ending: Select the preferred type of story conclusion.
|
||||
Generate Story: Click the "Generate Story" button to receive a customized story prompt based on your inputs.
|
||||
|
||||
|
||||
### Example Prompt
|
||||
|
||||
**Genre:** Fantasy
|
||||
**Setting:** A mystical forest in a medieval realm, where magic thrives and mythical creatures roam freely.
|
||||
**Characters:**
|
||||
- Name: Elara
|
||||
Description: Elara is a young elf with a mischievous glint in her emerald eyes, known for her ability to wield powerful spells.
|
||||
Role: Protagonist
|
||||
- Name: Thorne
|
||||
Description: Thorne is a gruff dwarf with a heart of gold, skilled in forging enchanted weapons.
|
||||
Role: Sidekick
|
||||
- Name: Malachai
|
||||
Description: Malachai is a cunning dragon with shimmering scales of azure, whose allegiance is uncertain.
|
||||
Role: Antagonist
|
||||
|
||||
**Plot Elements:**
|
||||
- Theme: The power of friendship and bravery in the face of adversity.
|
||||
- Key Events: Elara discovers an ancient prophecy that foretells a looming darkness threatening the realm. Thorne crafts a legendary sword to aid in their quest. Malachai challenges Elara's resolve, forcing her to make a difficult choice.
|
||||
- Conflict: Elara must gather allies and confront the dark sorcerer who seeks to plunge the realm into eternal shadow.
|
||||
|
||||
**Writing Style:** Poetic
|
||||
**Tone:** Whimsical
|
||||
**Point of View:** Third Person Limited
|
||||
|
||||
**Audience:** Young Adults, **Content Rating:** PG
|
||||
**Ending:** Happy
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -6,10 +6,9 @@
|
||||
|
||||
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
|
||||
import streamlit as st
|
||||
|
||||
|
||||
def generate_with_retry(model, prompt):
|
||||
@@ -30,7 +29,10 @@ def generate_with_retry(model, prompt):
|
||||
print(f"Error generating content: {e}")
|
||||
return ""
|
||||
|
||||
def ai_story_generator(persona, story_genre, characters):
|
||||
|
||||
def ai_story(persona, story_setting, character_input,
|
||||
plot_elements, writing_style, story_tone, narrative_pov,
|
||||
audience_age_group, content_rating, ending_preference):
|
||||
"""
|
||||
Write a story using prompt chaining and iterative generation.
|
||||
|
||||
@@ -39,15 +41,53 @@ def ai_story_generator(persona, story_genre, characters):
|
||||
story_genre (str): The genre of the story.
|
||||
characters (str): The characters in the story.
|
||||
"""
|
||||
print(f"Starting to write {story_genre} story based on characters: {characters}..")
|
||||
st.info(f"""
|
||||
You have chosen to create a story set in **{story_setting}**.
|
||||
The main characters are: **{character_input}**.
|
||||
The plot will revolve around the theme of **{plot_elements}**.
|
||||
The story will be written in a **{writing_style}** style with a **{story_tone}** tone, from a **{narrative_pov}** perspective.
|
||||
It is intended for a **{audience_age_group}** audience with a **{content_rating}** rating.
|
||||
You prefer the story to have a **{ending_preference}** ending.
|
||||
""")
|
||||
try:
|
||||
persona = f"""{persona}
|
||||
Write a story with the following details:
|
||||
|
||||
**The stroy Setting is:**
|
||||
{story_setting}
|
||||
|
||||
**The Characters of the story are:**
|
||||
{character_input}
|
||||
|
||||
**Plot Elements of the story:**
|
||||
{plot_elements}
|
||||
|
||||
**Story Writing Style:**
|
||||
{writing_style}
|
||||
|
||||
**The story Tone is:**
|
||||
{story_tone}
|
||||
|
||||
**Write story from the Point of View of:**
|
||||
{narrative_pov}
|
||||
|
||||
**Target Audience of the story:**
|
||||
{audience_age_group}, **Content Rating:** {content_rating}
|
||||
|
||||
**Story Ending:**
|
||||
{ending_preference}
|
||||
|
||||
Make sure the story is engaging and tailored to the specified audience and content rating.
|
||||
Ensure the ending aligns with the preference indicated.
|
||||
|
||||
"""
|
||||
# Define persona and writing guidelines
|
||||
guidelines = f'''\
|
||||
Writing Guidelines
|
||||
Writing Guidelines:
|
||||
|
||||
Delve deeper. Lose yourself in the world you're building. Unleash vivid
|
||||
descriptions to paint the scenes in your reader's mind.
|
||||
Develop your characters—let their motivations, fears, and complexities unfold naturally.
|
||||
Develop your characters — let their motivations, fears, and complexities unfold naturally.
|
||||
Weave in the threads of your outline, but don't feel constrained by it.
|
||||
Allow your story to surprise you as you write. Use rich imagery, sensory details, and
|
||||
evocative language to bring the setting, characters, and events to life.
|
||||
@@ -65,7 +105,7 @@ def ai_story_generator(persona, story_genre, characters):
|
||||
premise_prompt = f'''\
|
||||
{persona}
|
||||
|
||||
Write a single sentence premise for a {story_genre} story featuring {characters}.
|
||||
Write a single sentence premise for a {story_setting} story featuring {character_input}.
|
||||
'''
|
||||
|
||||
outline_prompt = f'''\
|
||||
@@ -95,7 +135,7 @@ def ai_story_generator(persona, story_genre, characters):
|
||||
Start to write the very beginning of the story. You are not expected to finish
|
||||
the whole story now. Your writing should be detailed enough that you are only
|
||||
scratching the surface of the first bullet of your outline. Try to write AT
|
||||
MINIMUM 5000 WORDS.
|
||||
MINIMUM 4000 WORDS.
|
||||
|
||||
{guidelines}
|
||||
'''
|
||||
@@ -130,25 +170,25 @@ def ai_story_generator(persona, story_genre, characters):
|
||||
|
||||
{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-1.0-pro')
|
||||
model = genai.GenerativeModel('gemini-1.5-flash')
|
||||
|
||||
# Generate prompts
|
||||
try:
|
||||
premise = generate_with_retry(model, premise_prompt).text
|
||||
print(f"The premise of the story is: {premise}")
|
||||
st.info(f"The premise of the story is: {premise}")
|
||||
except Exception as err:
|
||||
print(f"Premise Generation Error: {err}")
|
||||
st.error(f"Premise Generation Error: {err}")
|
||||
return
|
||||
|
||||
outline = generate_with_retry(model, outline_prompt.format(premise=premise)).text
|
||||
print(f"The Outline of the story is: {outline}\n\n")
|
||||
with st.expander("Click to Checkout the outline, writing still in progress.."):
|
||||
st.markdown(f"The Outline of the story is: {outline}\n\n")
|
||||
|
||||
if not outline:
|
||||
print("Failed to generate outline. Exiting...")
|
||||
st.error("Failed to generate outline. Exiting...")
|
||||
return
|
||||
|
||||
# Generate starting draft
|
||||
@@ -156,7 +196,7 @@ def ai_story_generator(persona, story_genre, characters):
|
||||
starting_draft = generate_with_retry(model,
|
||||
starting_prompt.format(premise=premise, outline=outline)).text
|
||||
except Exception as err:
|
||||
print(f"Failed to Generate Story draft: {err}")
|
||||
st.error(f"Failed to Generate Story draft: {err}")
|
||||
return
|
||||
|
||||
try:
|
||||
@@ -164,25 +204,29 @@ def ai_story_generator(persona, story_genre, characters):
|
||||
continuation = generate_with_retry(model,
|
||||
continuation_prompt.format(premise=premise, outline=outline, story_text=draft)).text
|
||||
except Exception as err:
|
||||
print(f"Failed to write the initial draft: {err}")
|
||||
st.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}")
|
||||
while 'IAMDONE' not in continuation:
|
||||
try:
|
||||
continuation = generate_with_retry(model,
|
||||
st.error(f"Failed as: {err} and {continuation}")
|
||||
|
||||
with st.status("Story Writing in Progress..", expanded=True) as status:
|
||||
status.update(label=f"Writing in progress... Current draft length: {len(draft)} characters")
|
||||
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
|
||||
draft += '\n\n' + continuation
|
||||
except Exception as err:
|
||||
print(f"Failed to continually write the story: {err}")
|
||||
return
|
||||
draft += '\n\n' + continuation
|
||||
except Exception as err:
|
||||
st.error(f"Failed to continually write the story: {err}")
|
||||
return
|
||||
|
||||
# Remove 'IAMDONE' and print the final story
|
||||
final = draft.replace('IAMDONE', '').strip()
|
||||
print(final)
|
||||
return(final)
|
||||
|
||||
except Exception as e:
|
||||
print(f"Main Story writing: An error occurred: {e}")
|
||||
st.error(f"Main Story writing: An error occurred: {e}")
|
||||
134
lib/ai_writers/ai_story_writer/story_writer.py
Normal file
134
lib/ai_writers/ai_story_writer/story_writer.py
Normal file
@@ -0,0 +1,134 @@
|
||||
import time
|
||||
import os
|
||||
import json
|
||||
import streamlit as st
|
||||
|
||||
from .ai_story_generator import ai_story
|
||||
|
||||
|
||||
def story_input_section():
|
||||
st.title("🧕 Alwrity - AI Story Writer")
|
||||
personas = [
|
||||
("Award-Winning Science Fiction Author", "👽 Award-Winning Science Fiction Author"),
|
||||
("Historical Fiction Author", "🏺 Historical Fiction Author"),
|
||||
("Fantasy World Builder", "🧙 Fantasy World Builder"),
|
||||
("Mystery Novelist", "🕵️ Mystery Novelist"),
|
||||
("Romantic Poet", "💌 Romantic Poet"),
|
||||
("Thriller Writer", "🔪 Thriller Writer"),
|
||||
("Children's Book Author", "📚 Children's Book Author"),
|
||||
("Satirical Humorist", "😂 Satirical Humorist"),
|
||||
("Biographical Writer", "📜 Biographical Writer"),
|
||||
("Dystopian Visionary", "🌆 Dystopian Visionary"),
|
||||
("Magical Realism Author", "🪄 Magical Realism Author")
|
||||
]
|
||||
|
||||
selected_persona_name = st.selectbox(
|
||||
"Select Your Story Writing Persona Or Book Genre",
|
||||
options=[persona[0] for persona in personas]
|
||||
)
|
||||
|
||||
persona_descriptions = {
|
||||
"Award-Winning Science Fiction Author": "You are an award-winning science fiction author with a penchant for expansive, intricately woven stories. Your ultimate goal is to write the next award-winning sci-fi novel.",
|
||||
"Historical Fiction Author": "You are a seasoned historical fiction author, meticulously researching past eras to weave captivating narratives. Your goal is to transport readers to different times and places through your vivid storytelling.",
|
||||
"Fantasy World Builder": "You are a world-building enthusiast, crafting intricate realms filled with magic, mythical creatures, and epic quests. Your ambition is to create the next immersive fantasy saga that captivates readers' imaginations.",
|
||||
"Mystery Novelist": "You are a master of suspense and intrigue, intricately plotting out mysteries with unexpected twists and turns. Your aim is to keep readers on the edge of their seats, eagerly turning pages to unravel the truth.",
|
||||
"Romantic Poet": "You are a romantic at heart, composing verses that capture the essence of love, longing, and human connections. Your dream is to write the next timeless love story that leaves readers swooning.",
|
||||
"Thriller Writer": "You are a thrill-seeker, crafting adrenaline-pumping tales of danger, suspense, and high-stakes action. Your mission is to keep readers hooked from start to finish with heart-pounding thrills and unexpected twists.",
|
||||
"Children's Book Author": "You are a storyteller for the young and young at heart, creating whimsical worlds and lovable characters that inspire imagination and wonder. Your goal is to spark joy and curiosity in young readers with enchanting tales.",
|
||||
"Satirical Humorist": "You are a keen observer of society, using humor and wit to satirize the absurdities of everyday life. Your aim is to entertain and provoke thought, delivering biting social commentary through clever and humorous storytelling.",
|
||||
"Biographical Writer": "You are a chronicler of lives, delving into the stories of real people and events to illuminate the human experience. Your passion is to bring history to life through richly detailed biographies that resonate with readers.",
|
||||
"Dystopian Visionary": "You are a visionary writer, exploring dark and dystopian futures that reflect contemporary fears and anxieties. Your vision is to challenge societal norms and provoke reflection on the path humanity is heading.",
|
||||
"Magical Realism Author": "You are a purveyor of magical realism, blending the ordinary with the extraordinary to create enchanting and thought-provoking tales. Your goal is to blur the lines between reality and fantasy, leaving readers enchanted and introspective."
|
||||
}
|
||||
|
||||
# Story Setting
|
||||
st.subheader("🌍 Story Setting")
|
||||
story_setting = st.text_area(
|
||||
label="**Story Setting** (e.g., medieval kingdom in the past, futuristic city in the future, haunted house in the present):",
|
||||
placeholder="""Enter settings for your story, like Location (e.g., medieval kingdom, futuristic city, haunted house),
|
||||
Time period in which your story is set (e.g: Past, Present, Future)
|
||||
Example: 'A bustling futuristic city with towering skyscrapers and flying cars, set in the year 2150.
|
||||
The city is known for its technological advancements but has a dark underbelly of crime and corruption.'""",
|
||||
help="Describe the main location and time period where the story will unfold in a detailed manner."
|
||||
)
|
||||
|
||||
# Main Characters
|
||||
st.subheader("👥 Main Characters")
|
||||
character_input = st.text_area(
|
||||
label="**Character Information** (Names, Descriptions, Roles)",
|
||||
placeholder="""Example:
|
||||
Character Names: John, Xishan, Amol
|
||||
Character Descriptions: John is a tall, muscular man with a kind heart. Xishan is a clever and resourceful woman. Amol is a mischievous and energetic young boy.
|
||||
Character Roles: John - Hero, Xishan - Sidekick, Amol - Supporting Character""",
|
||||
help="Enter character information as specified in the placeholder."
|
||||
)
|
||||
|
||||
# Plot Elements
|
||||
st.subheader("🗺️ Plot Elements")
|
||||
plot_elements = st.text_area(
|
||||
"**Plot Elements** - (Theme, Key Events & Main Conflict)",
|
||||
placeholder="""Example:
|
||||
Story Theme: Love conquers all, The hero's journey, Good vs. evil.
|
||||
Key Events: The hero meets the villain, The hero faces a challenge, The hero overcomes the conflict.
|
||||
Main Conflict: The hero must save the world from a powerful enemy, The hero must overcome a personal obstacle to achieve their goal.""",
|
||||
help="Enter plot elements as specified in the placeholder."
|
||||
)
|
||||
|
||||
# Tone and Style
|
||||
st.subheader("🎨 Tone and Style")
|
||||
col1, col2, col3 = st.columns(3)
|
||||
with col1:
|
||||
writing_style = st.selectbox(
|
||||
"**Writing Style:**",
|
||||
["🧐 Formal", "😎 Casual", "🎼 Poetic", "😂 Humorous"],
|
||||
help="Choose the writing style that fits your story."
|
||||
)
|
||||
with col2:
|
||||
story_tone = st.selectbox(
|
||||
"**Story Tone:**",
|
||||
["🌑 Dark", "☀️ Uplifting", "⏳ Suspenseful", "🎈 Whimsical"],
|
||||
help="Select the overall tone or mood of the story."
|
||||
)
|
||||
with col3:
|
||||
narrative_pov = st.selectbox(
|
||||
"**Narrative Point of View:**",
|
||||
["👤 First Person", "👥 Third Person Limited", "👁️ Third Person Omniscient"],
|
||||
help="Choose the point of view from which the story is told."
|
||||
)
|
||||
|
||||
# Target Audience
|
||||
st.subheader("👨👩👧👦 Target Audience")
|
||||
col1, col2, col3 = st.columns(3)
|
||||
with col1:
|
||||
audience_age_group = st.selectbox(
|
||||
"**Audience Age Group:**",
|
||||
["🧒 Children", "👨🎓 Young Adults", "🧑🦳 Adults"],
|
||||
help="Choose the intended audience age group."
|
||||
)
|
||||
with col2:
|
||||
content_rating = st.selectbox(
|
||||
"**Content Rating:**",
|
||||
["🟢 G", "🟡 PG", "🔵 PG-13", "🔴 R"],
|
||||
help="Select a content rating for appropriateness."
|
||||
)
|
||||
with col3:
|
||||
ending_preference = st.selectbox(
|
||||
"Story Conclusion:",
|
||||
["😊 Happy", "😢 Tragic", "❓ Cliffhanger", "🔀 Twist"],
|
||||
help="Choose the type of ending you prefer for the story."
|
||||
)
|
||||
|
||||
if st.button('AI, Write a Story..'):
|
||||
if character_input.strip():
|
||||
with st.spinner("Generating Story...💥💥"):
|
||||
story_content = ai_story(persona_descriptions[selected_persona_name],
|
||||
story_setting, character_input, plot_elements, writing_style,
|
||||
story_tone, narrative_pov, audience_age_group, content_rating,
|
||||
ending_preference)
|
||||
if story_content:
|
||||
st.subheader('**🧕 Your Awesome Story:**')
|
||||
st.markdown(story_content)
|
||||
else:
|
||||
st.error("💥 **Failed to generate Story. Please try again!**")
|
||||
else:
|
||||
st.error("Describe the story you have in your mind.. !")
|
||||
@@ -50,7 +50,8 @@ def generate_with_retry(model, prompt):
|
||||
return model.generate_content(prompt, request_options={'retry':retry.Retry()})
|
||||
except Exception as e:
|
||||
logger.error(f"Error generating content: {e}")
|
||||
return ""
|
||||
st.error(f"Error generating content: {e}")
|
||||
return False
|
||||
|
||||
|
||||
def long_form_generator(content_keywords):
|
||||
|
||||
Reference in New Issue
Block a user