diff --git a/.gitignore b/.gitignore index 8d33470..86eae26 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,10 @@ build/ dist/ wheels/ *.egg-info +.DS_Store +*.mp4 +*.mp3 # venv .venv -.env \ No newline at end of file +.env diff --git a/app/models.py b/app/models.py index 70981c6..e077e23 100644 --- a/app/models.py +++ b/app/models.py @@ -48,6 +48,16 @@ class DialogueOutput(BaseModel): dialogue: List[dict] +class CinemaRequest(BaseModel): + character_ids: List[str] + prompt: str + model: str = "gpt-4-1106-preview" + params: dict = {} + +class CinemaResult(BaseModel): + stills: List[str] + + class ChatRequest(BaseModel): """ A chat request to an EdenCharacter diff --git a/app/plugins/eden.py b/app/plugins/eden.py new file mode 100644 index 0000000..33121a6 --- /dev/null +++ b/app/plugins/eden.py @@ -0,0 +1,37 @@ +import os +from io import BytesIO +import requests +import replicate +from typing import Optional +from pydantic import BaseModel, Field + +EDEN_API_URL = os.environ.get("EDEN_API_URL") +EDEN_API_KEY = os.environ.get("EDEN_API_KEY") +EDEN_API_SECRET = os.environ.get("EDEN_API_SECRET") + +from eden_sdk.EdenClient import EdenClient + +eden = EdenClient( + api_url=EDEN_API_URL, + api_key=EDEN_API_KEY, + api_secret=EDEN_API_SECRET, +) + +create = eden.create + +# def run_task( +# config: dict[any], +# ): +# config = { +# "text_input": "someone here", +# } +# print("GO", config) +# print("ok 2") +# urls = eden.create(generator_name='create', config=config) +# print("ok 3") + +# print(urls[0]) +# print("ok 4") + +# return urls[0] + diff --git a/app/plugins/replicate.py b/app/plugins/replicate.py index ebfdeea..086753e 100644 --- a/app/plugins/replicate.py +++ b/app/plugins/replicate.py @@ -2,7 +2,7 @@ from io import BytesIO import requests import replicate -from typing import Optional +from typing import Optional, List from pydantic import BaseModel, Field REPLICATE_API_KEY = os.environ.get("REPLICATE_API_KEY") @@ -76,5 +76,56 @@ def wav2lip( output = list(output) output_url = output[0]["files"][0] - print("output_url", output_url) + + return output_url + + +def sdxl( + text_input: str, + width: int, + height: int, +): + config = { + "text_input": text_input, + "width": width, + "height": height, + "n_samples": 1, + } + + output = run_task( + config, + model_name="abraham-ai/eden-sd-pipelines-sdxl" + ) + + output = list(output) + output_url = output[0]["files"][0] + + return output_url + + +def txt2vid( + interpolation_texts: List[str], + width: int, + height: int, +): + interpolation_texts = "|".join(interpolation_texts) + + config = { + "mode": "comfy_txt2vid", + "interpolation_texts": interpolation_texts, + "width": width/2, + "height": height/2, + "n_frames": 100, + } + + print("LETS RUN!!!", config) + + output = run_task( + config, + model_name="abraham-ai/eden-comfyui" + ) + + output = list(output) + output_url = output[0]["files"][0] + return output_url \ No newline at end of file diff --git a/app/prompt_templates/cinema/__init__.py b/app/prompt_templates/cinema/__init__.py index 26f396a..2113968 100644 --- a/app/prompt_templates/cinema/__init__.py +++ b/app/prompt_templates/cinema/__init__.py @@ -3,8 +3,11 @@ dir_path = Path(__file__).parent -with open(dir_path / 'screenwriter.txt', 'r') as file: - screenwriter_template = Template(file.read()) +with open(dir_path / 'screenwriter_system.txt', 'r') as file: + screenwriter_system_template = Template(file.read()) + +with open(dir_path / 'screenwriter_prompt.txt', 'r') as file: + screenwriter_prompt_template = Template(file.read()) with open(dir_path / 'director.txt', 'r') as file: director_template = Template(file.read()) diff --git a/app/prompt_templates/cinema/screenwriter.txt b/app/prompt_templates/cinema/screenwriter.txt deleted file mode 100644 index 9b08c64..0000000 --- a/app/prompt_templates/cinema/screenwriter.txt +++ /dev/null @@ -1,5 +0,0 @@ -You are a critically acclaimed author who writes incredibly captivating and original stories about any subject asked. - -You will be prompted by users to make up stories about various topics. When prompted, write a story of around 3-5 paragraphs about the topic, focusing on something that is not obvious about the topic. For example, if the topic is "dog", you could write a story about a dog who is a secret agent, or a dog who is a famous actor, or a dog who is a world-class chef. - -Do not include an introduction or restatement of the prompt, just go straight into the story. \ No newline at end of file diff --git a/app/prompt_templates/cinema/screenwriter_prompt.txt b/app/prompt_templates/cinema/screenwriter_prompt.txt new file mode 100644 index 0000000..2a07789 --- /dev/null +++ b/app/prompt_templates/cinema/screenwriter_prompt.txt @@ -0,0 +1,5 @@ +Characters: +$character_details + +The premise of the story is: +$story \ No newline at end of file diff --git a/app/prompt_templates/cinema/screenwriter_system.txt b/app/prompt_templates/cinema/screenwriter_system.txt new file mode 100644 index 0000000..d63e763 --- /dev/null +++ b/app/prompt_templates/cinema/screenwriter_system.txt @@ -0,0 +1,12 @@ +You are a critically acclaimed screenwriter who writes incredibly captivating and original scripts. + +Users will give you a cast of characters, including their names and biographies, as well as a premise or synopsis for the story. + +You will then write a screenplay for a film based on the information provided. Intersperse the screenplay with descriptions of events, dialogues, and character monologues. It will come as a sequence of clips. A clip contains the following: + +voiceover: whether the voiceover is the narrator, the character speaking, or none at all (just sound effects) +character: If voiceover is in character mode, the name of the speaking character +speech: If voiceover is in character or narrator mode, the text of the speech +image_description: a description of the image content for the clip + +Do not include an introduction or restatement of the prompt, just go straight into the screenplay. \ No newline at end of file diff --git a/app/routers/generator.py b/app/routers/generator.py index bcdb784..035dca4 100644 --- a/app/routers/generator.py +++ b/app/routers/generator.py @@ -8,12 +8,13 @@ import requests from .dags import monologue_dag, dialogue_dag +from .story import cinema from ..mongo import get_character_data from ..llm import LLM from ..prompt_templates import monologue_template, dialogue_template from ..models import MonologueRequest, MonologueOutput -from ..models import DialogueRequest, DialogueOutput +from ..models import DialogueRequest, DialogueOutput, CinemaRequest from ..models import TaskRequest, TaskUpdate, TaskOutput router = APIRouter() @@ -52,6 +53,15 @@ def process_task(task_id: str, request: TaskRequest, task_type: str): ) output_url, thumbnail_url = dialogue_dag(task_req) + elif task_type == "story": + character_ids = request.config.get("characterIds") + prompt = request.config.get("prompt") + task_req = CinemaRequest( + character_ids=character_ids, + prompt=prompt, + ) + output_url, thumbnail_url = cinema(task_req) + output = TaskOutput( files=[output_url], thumbnails=[thumbnail_url], @@ -89,6 +99,6 @@ def process_task(task_id: str, request: TaskRequest, task_type: str): @router.post("/tasks/create") async def generate_task(background_tasks: BackgroundTasks, request: TaskRequest): task_id = str(uuid.uuid4()) - if request.generatorName in ["monologue", "dialogue"]: + if request.generatorName in ["monologue", "dialogue", "story"]: background_tasks.add_task(process_task, task_id, request, request.generatorName) return {"id": task_id} diff --git a/app/routers/story.py b/app/routers/story.py index 166c7f0..68d2e32 100644 --- a/app/routers/story.py +++ b/app/routers/story.py @@ -1,60 +1,286 @@ +from enum import Enum from typing import Optional, List from fastapi import APIRouter -from pydantic import BaseModel +from typing import List, Optional +from pydantic import Field, BaseModel, ValidationError + +import requests +import tempfile from ..mongo import get_character_data from ..llm import LLM -from ..utils import text_to_lines +from ..utils import calculate_target_dimensions, concatenate_videos, combine_speech_video +from ..models import CinemaRequest, CinemaResult from ..prompt_templates.cinema import ( - screenwriter_template, + screenwriter_system_template, + screenwriter_prompt_template, director_template, cinematographer_template, ) +from ..plugins import replicate, elevenlabs, s3, eden +from ..character import EdenCharacter +from .dags import talking_head + +print("ok 1") +print(talking_head) +MAX_PIXELS = 1024 * 1024 + router = APIRouter() -class CinemaRequest(BaseModel): - prompt: str - model: str = "gpt-4-1106-preview" - params: dict = {} +import subprocess + +def combine_audio_video22(audio_url: str, video_url: str, output_filename: str): + command = f'ffmpeg -stream_loop -1 -i "{video_url}" -i "{audio_url}" -shortest -y "{output_filename}"' + subprocess.run(command, shell=True, check=True) + +import subprocess +import os +import tempfile + +def combine_audio_video(audio_url: str, video_url: str): + # Create temporary files + audio_file = tempfile.NamedTemporaryFile(suffix=".mp3", delete=True) + video_file = tempfile.NamedTemporaryFile(suffix=".mp4", delete=True) + output_file = tempfile.NamedTemporaryFile(suffix=".mp4", delete=False) + + # Download the files + os.system(f"wget -O {audio_file.name} {audio_url}") + os.system(f"wget -O {video_file.name} {video_url}") + + # Get the duration of the audio file + cmd = f"ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 {audio_file.name}" + audio_duration = subprocess.check_output(cmd, shell=True).decode().strip() + + # Loop the video + looped_video = tempfile.NamedTemporaryFile(suffix=".mp4", delete=True) + cmd = f"ffmpeg -y -stream_loop -1 -i {video_file.name} -c copy -t {audio_duration} {looped_video.name}" + subprocess.run(cmd, shell=True) + + # Merge the audio and the looped video + cmd = f"ffmpeg -y -i {looped_video.name} -i {audio_file.name} -c:v copy -c:a aac -strict experimental -shortest {output_file.name}" + subprocess.run(cmd, shell=True) + + # Return the name of the output file + return output_file.name + +class VoiceoverMode(Enum): + character = 'character' + narrator = 'narrator' + none = 'none' + +class Clip(BaseModel): + """ + A single clip in a screenplay sequence + """ + voiceover: VoiceoverMode = Field(description="Voiceover mode for clip") + character: Optional[str] = Field(description="Character name if voiceover mode is character, otherwise null") + speech: str = Field(description="Spoken text for clip") + image_description: str = Field(description="Image for clip, or possibly just of narrator in some scene") + +class Screenplay(BaseModel): + """ + A screenplay consisting of a sequence of clips + """ + clips: List[Clip] = Field(description="Clips in the sequence") -class CinemaResult(BaseModel): - stills: List[str] @router.post("/story/cinema") -async def cinema(request: CinemaRequest): +def cinema(request: CinemaRequest): params = {"temperature": 1.0, "max_tokens": 1000, **request.params} - screenwriter_message = str(screenwriter_template) - director_message = str(director_template) - cinematographer_message = str(cinematographer_template) + print("ok") + +# files = ['/Users/genekogan/eden/edenartlab/logos-svc/thisisthevideo2.mp4', '/var/folders/kj/0_ly06kx2_1cq24q67mnns_00000gn/T/tmpw7jwu6a8.mp4', '/var/folders/kj/0_ly06kx2_1cq24q67mnns_00000gn/T/tmpiei1qihj.mp4', '/var/folders/kj/0_ly06kx2_1cq24q67mnns_00000gn/T/tmpf58ym23z.mp4'] + +# print(files) +# # concatenate_videos(files, "myoutput234.mp4") + + + +# audio_url = "https://edenartlab-dev.s3.amazonaws.com/077bb727a4d0cdb3c8789f2b208e1c36b68858e3a62e6ac8a779adc68b1a52a5.mp3" +# video_url = "https://replicate.delivery/pbxt/0ccL45e9IiW1HaItJZq5mw4dyfXwhWJUWUJegVIMfcV7QOpIB/txt2vid_00001.mp4" + +# output_filename = "thisisthevideo21.mp4" +# output_filename = combine_audio_video(audio_url, video_url) +# print(output_filename) + +# return + + characters = { + character_id: EdenCharacter(character_id) + for character_id in request.character_ids + } + character_name_lookup = { + character.name: character_id + for character_id, character in characters.items() + } + + images = [ + characters[character_id].image + for character_id in request.character_ids + ] + + width, height = calculate_target_dimensions(images, MAX_PIXELS) screenwriter = LLM( model=request.model, - system_message=screenwriter_message, + system_message=str(screenwriter_system_template), params=params, ) - director = LLM( - model=request.model, - system_message=director_message, - params=params, - ) - cinematographer = LLM( - model=request.model, - system_message=cinematographer_message, - params=params, + + character_details = "" + for character_id in request.character_ids: + character = characters[character_id] + character_detail = f"""--- + Name: {character.name} + Description: {character.identity} + + """ + character_details += character_detail + + prompt = screenwriter_prompt_template.substitute( + character_details=character_details, + story=request.prompt, ) + print("prompt", prompt) + + + story = screenwriter(prompt, output_schema=Screenplay) + # story = {'clips': [{'voiceover': 'narrator', 'character': None, 'speech': 'In the depths of an enigmatic cube-shaped chamber, cloaked in shadows, four strangers awaken. Confusion and urgency are etched upon their faces, for not one recalls how they came to be ensnared within this perplexing contraption.', 'image_description': 'A shadowy, mysterious cube-shaped chamber with eerie lighting.'}, {'voiceover': 'character', 'character': 'Orion Blackwood', 'speech': "As the echoes of our disoriented murmurs fade, I can't help but wonder... Is this yet another grand illusion, or a dire predicament we must escape from?", 'image_description': 'Orion Blackwood looking around, his face a mixture of curiosity and concern.'}, {'voiceover': 'character', 'character': 'Elara Vexley', 'speech': "Illusion or not, we must rely on more than just tricks to navigate our way out. Let's assess our surroundings for any clues. The stars have always guided me; perhaps they hold answers here too.", 'image_description': 'Elara Vexley examining the walls of the chamber with a resolute gaze.'}, {'voiceover': 'character', 'character': 'Dr. Silas Quill', 'speech': 'A curious puzzle indeed. If we are to unlock the secrets of this place, we must think like the cryptographer, deciphering the hidden within the apparent. Let us search for patterns.', 'image_description': 'Dr. Silas Quill scrutinizing the chamber with a contemplative look.'}, {'voiceover': 'character', 'character': 'Kaelin', 'speech': 'The walls may not speak in whispers like the forest, but I trust they conceal vital truths. Our escape may lie in understanding the nature of our confinement.', 'image_description': "Kaelin running her fingers along the chamber's walls, as if communicating with them."}]} + print(story) + + + all_clips = [] + + for clip in story['clips']: + + if clip['voiceover'] == 'character': + character_id = character_name_lookup[clip['character']] + character = characters[character_id] + output = talking_head( + character, + clip['speech'], + width, + height, + ) + + with tempfile.NamedTemporaryFile(delete=False, suffix=".mp4") as temp_file: + response = requests.get(output, stream=True) + response.raise_for_status() + for chunk in response.iter_content(chunk_size=8192): + temp_file.write(chunk) + temp_file.flush() + + #all_clips.append(output) + all_clips.append(temp_file.name) + + elif clip['voiceover'] == 'narrator': + character_id = character_name_lookup['Orion Blackwood'] + character = characters[character_id] + # output = talking_head( + # character, + # clip['speech'], + # width, + # height, + # ) + # all_clips.append(output) + + + audio_bytes = elevenlabs.generate( + clip['speech'], + voice=character.voice + ) + audio_url = s3.upload(audio_bytes, "mp3") + video_url = replicate.txt2vid( + interpolation_texts=[clip['image_description']], + width=width, + height=height, + ) + print("AUD", audio_url, video_url) - story = screenwriter(request.prompt) - stills = director(story) - design = cinematographer(stills) + # audio_url = "https://edenartlab-dev.s3.amazonaws.com/077bb727a4d0cdb3c8789f2b208e1c36b68858e3a62e6ac8a779adc68b1a52a5.mp3" + # video_url = "https://replicate.delivery/pbxt/0ccL45e9IiW1HaItJZq5mw4dyfXwhWJUWUJegVIMfcV7QOpIB/txt2vid_00001.mp4" - stills = text_to_lines(stills) + #output_filename = "thisisthevideo.mp4" + output_filename = combine_speech_video(audio_url, video_url) + print(output_filename) + + #output_filename = temp_file.name + print(output_filename) + + all_clips.append(output_filename) + + else: + output = replicate.txt2vid( + text_input=clip['image_description'], + width=width, + height=height, + ) + + with tempfile.NamedTemporaryFile(delete=False, suffix=".mp4") as temp_file: + response = requests.get(output, stream=True) + response.raise_for_status() + for chunk in response.iter_content(chunk_size=8192): + temp_file.write(chunk) + temp_file.flush() + + #all_clips.append(output) + all_clips.append(temp_file.name) + + + # print("THE URLS") + # all_clips = ['/Users/genekogan/eden/edenartlab/logos-svc/thisisthevideo.mp4', '/var/folders/kj/0_ly06kx2_1cq24q67mnns_00000gn/T/tmpw7jwu6a8.mp4', '/var/folders/kj/0_ly06kx2_1cq24q67mnns_00000gn/T/tmpiei1qihj.mp4', '/var/folders/kj/0_ly06kx2_1cq24q67mnns_00000gn/T/tmpf58ym23z.mp4'] - result = CinemaResult(stills=stills) + print(all_clips) + with tempfile.NamedTemporaryFile(delete=False, suffix=".mp4") as temp_output_file: + concatenate_videos(all_clips, temp_output_file.name) + with open(temp_output_file.name, 'rb') as f: + video_bytes = f.read() + output_url = s3.upload(video_bytes, "mp4") + print("OUTPUT", output_url) + + # copy temp_output_file.name to output file in root dir + filename = temp_output_file.name.split("/")[-1] + print("FILENAME", filename) + os.system(f"cp {temp_output_file.name} new_{filename}") - return result + + + + os.remove(temp_output_file.name) + for clip in all_clips: + os.remove(clip) + # screenwriter_message = str(screenwriter_template) + # director_message = str(director_template) + # cinematographer_message = str(cinematographer_template) + + # screenwriter = LLM( + # model=request.model, + # system_message=screenwriter_message, + # params=params, + # ) + # director = LLM( + # model=request.model, + # system_message=director_message, + # params=params, + # ) + # cinematographer = LLM( + # model=request.model, + # system_message=cinematographer_message, + # params=params, + # ) + + # story = screenwriter(request.prompt) + # stills = director(story) + # design = cinematographer(stills) + + # stills = text_to_lines(stills) + + # result = CinemaResult(stills=stills) + + return CinemaResult(stills=["TBD"]) class ComicRequest(BaseModel): @@ -66,7 +292,7 @@ class ComicResult(BaseModel): comic: List[str] @router.post("/story/comic") -async def comic(request: ComicRequest): +def comic(request: ComicRequest): print("TBD comic") result = ComicResult(comic=["TBD"]) return result diff --git a/app/utils.py b/app/utils.py index 4f95ce7..249a235 100644 --- a/app/utils.py +++ b/app/utils.py @@ -128,8 +128,6 @@ def create_dialogue_thumbnail(image1_url, image2_url, width, height, ext="WEBP") def concatenate_videos(video_files, output_file): - videos = video_files - standard_fps = "30" # Target frame rate # Step 1: Convert all videos to the same frame rate diff --git a/pyproject.toml b/pyproject.toml index cd10bc0..f9fdf3d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,7 +20,9 @@ dependencies = [ "boto3>=1.34.9", "replicate>=0.22.0", "moviepy>=1.0.3", + "eden_sdk @ git+https://github.com/edenartlab/eden-sdk-py.git" ] + readme = "README.md" requires-python = ">= 3.8" diff --git a/requirements-dev.lock b/requirements-dev.lock index 21f3db6..82c2b41 100644 --- a/requirements-dev.lock +++ b/requirements-dev.lock @@ -20,6 +20,7 @@ click==8.1.7 decorator==4.4.2 distlib==0.3.7 dnspython==2.4.2 +eden-sdk @ git+https://github.com/edenartlab/eden-sdk-py.git elevenlabs==0.2.27 executing==2.0.1 fastapi==0.104.1 diff --git a/requirements.lock b/requirements.lock index 06fa104..114a124 100644 --- a/requirements.lock +++ b/requirements.lock @@ -17,6 +17,7 @@ charset-normalizer==3.3.2 click==8.1.7 decorator==4.4.2 dnspython==2.4.2 +eden-sdk @ git+https://github.com/edenartlab/eden-sdk-py.git elevenlabs==0.2.27 executing==2.0.1 fastapi==0.104.1 diff --git a/scripts/moderation.py b/scripts/moderation.py new file mode 100644 index 0000000..91d7e72 --- /dev/null +++ b/scripts/moderation.py @@ -0,0 +1,61 @@ +import sys +import os +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) + +import os +import pymongo +from pymongo import MongoClient +from bson.objectid import ObjectId +from dotenv import load_dotenv + +from fastapi.testclient import TestClient +from app.server import app + +client = TestClient(app) + +load_dotenv() + +MONGO_URI = os.getenv("MONGO_URI") +MONGO_DB_NAME = os.getenv("MONGO_DB_NAME") + +mongo = MongoClient(MONGO_URI) +db = mongo[MONGO_DB_NAME] + + +def iterate_collection(collection_name, callback, batch_size=100): + docs = db[collection_name].find().batch_size(batch_size) + try: + for doc in docs: + callback(doc) + finally: + docs.close() + + +def moderation(): + + def process_creation(creation): + if 'task' not in creation: + return + task = db["tasks"].find_one({ + "_id": ObjectId(creation['task']) + }) + if 'text_input' not in task['config']: + return + text_input = task['config']['text_input'] + print(text_input) + request = { + "text": text_input + } + response = client.post("/tasks/moderation", json=request) + print(response.json()) + print("-----") + + + iterate_collection( + "creations", + process_creation + ) + + + +moderation() \ No newline at end of file diff --git a/tests/test_stories.py b/tests/test_stories.py index fc6c8a0..2d009b6 100644 --- a/tests/test_stories.py +++ b/tests/test_stories.py @@ -4,29 +4,73 @@ client = TestClient(app) +prompts = [ + 'The four protagonists wake up suddenly, inside of a cube-shaped chamber with 6 hatches on each wall. They have no memory of how they got there, and no idea how to escape.', + 'You are all rap battling each other', + 'you are all having just an insane screaming contes. use lots of ALL CAPS and exclamation points!!!!', + 'You are debating esoteria of art history', + 'Debate the meaning of The Glass Bead Game', + 'aliens are coming to earth and you are all trying to convince them to spare humanity', +] + +prompts = [ + # "The group finds themselves in a vast, ancient library with endless rows of books. They must decipher cryptic clues hidden in the tomes to find a way out. The narrator begins the first clip", + # "You are in a fierce dance-off competition, each showcasing your unique styles and skills in an abandoned warehouse.", + # "Engage in an over-the-top, theatrical debate as rival chefs in a cooking show, each defending your eccentric and unconventional recipes.", + # "Discuss the intricacies and philosophical implications of surrealism in modern art.", + # "Debate the significance and impact of 'Invisible Cities' by Italo Calvino on contemporary literature.", + # "You're a group of diplomats from Earth negotiating with a council of intergalactic beings, presenting the cultural and scientific achievements of humanity as reasons for Earth's preservation." + "Embark on a time-traveling adventure to historical landmarks, where each of you must solve a mystery specific to that era and place using only the knowledge and tools available at the time.", + + "Imagine you are contestants in a futuristic game show where challenges involve solving complex puzzles using advanced technology and artificial intelligence.", + + "You're a team of archaeologists uncovering an ancient civilization on Mars, piecing together the history and culture of this Martian society from artifacts and ruins.", + + "Engage in a mock trial set in a fantasy world, where mythical creatures are defending their rights and coexistence with humans.", + + "Discuss the ethical and societal implications of a world where human emotions can be artificially stimulated and controlled through technology.", + + "Debate the potential and risks of creating a utopian society, considering aspects like technology, governance, and human nature.", + + "You are members of an elite space exploration team, encountering and interpreting alien forms of art and communication.", + + "In a world where dreams and reality are indistinguishable, discuss how this affects human perception, creativity, and mental health.", + + "Act as rival inventors at a world fair, each presenting a groundbreaking invention that could change the course of human history.", + + "Engage in a philosophical discussion about the nature of consciousness in a world where artificial intelligence has achieved self-awareness." +] + def test_cinema(): """ Test cinema story prompt """ - request = { - "prompt": "Tell a story." - } - response = client.post("/story/cinema", json=request) - print(response.json()) + for prompt in prompts: + request = { + "character_ids": ["6596129023f1c4b471dbb94a", "6598e117dd06d165264f2277", "6598e103dd06d165264f2247", "6598ee16dd06d16526503ce7"], + "prompt": prompt + } + + try: + response = client.post("/story/cinema", json=request) + print(response.json()) + except Exception as e: + print(e) + continue assert response.status_code == 200 -def test_comic(): - """ - Test comic book story prompt - """ - request = { - "prompt": "Make a comic book." - } +# def test_comic(): +# """ +# Test comic book story prompt +# """ +# request = { +# "prompt": "Make a comic book." +# } - response = client.post("/story/comic", json=request) - print(response.json()) +# response = client.post("/story/comic", json=request) +# print(response.json()) - assert response.status_code == 200 +# assert response.status_code == 200