Skip to content

Commit

Permalink
release: 0.5.0 Alpha 1
Browse files Browse the repository at this point in the history
  • Loading branch information
Estrada Irribarra, Rodrigo Andres committed Oct 19, 2024
1 parent ee06d24 commit b9279e9
Show file tree
Hide file tree
Showing 10 changed files with 161 additions and 104 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@

Welcome to [**StoryCraftr**](https://storycraftr.app), the open-source project designed to revolutionize how books are written. With the power of AI and a streamlined command-line interface (CLI), StoryCraftr helps you craft your story, manage worldbuilding, structure your book, and generate chapters — all while keeping you in full control.

## Release Notes v0.4.0
## Release Notes v0.5.0-alpha1

You can find the release notes for version `v0.4.0` [here](https://github.com/raestrada/storycraftr/releases/tag/v0.4.0).
You can find the release notes for version `v0.5.0-alpha1` [here](https://github.com/raestrada/storycraftr/releases/tag/v0.5.0-alpha1).

## Installation

You can install the current version of **StoryCraftr** via `pipx` using the following command:

```bash
pipx install git+https://github.com/raestrada/storycraftr.git@v0.4.0
pipx install git+https://github.com/raestrada/storycraftr.git@v0.5.0-alpha1
```

### Important: Before using StoryCraftr, make sure to set your OpenAI API key:
Expand Down
2 changes: 1 addition & 1 deletion docs/getting_started.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ First, install **StoryCraftr** using [pipx](https://pypa.github.io/pipx/), a too
To install **StoryCraftr**, run the following command:

```bash
pipx install git+https://github.com/raestrada/storycraftr.git@v0.4.0
pipx install git+https://github.com/raestrada/storycraftr.git@v0.5.0-alpha1
```

### Important: Before running the `storycraftr` command
Expand Down
8 changes: 4 additions & 4 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@
<meta name="twitter:card" content="summary_large_image">

<div class="release-link">
<a href="https://github.com/raestrada/storycraftr/releases/tag/v0.4.0">Release Notes v0.4.0</a>
<a href="https://github.com/raestrada/storycraftr/releases/tag/v0.5.0-alpha1">Release Notes v0.5.0-alpha1</a>
</div>

<nav>
Expand Down Expand Up @@ -213,9 +213,9 @@ <h1>Welcome to StoryCraftr 📚✨</h1>

<section>
<div class="coming-soon">
🚧 Coming Soon - StoryCraftr is in development. Stay tuned for the Alpha release! 🚀
<br>Install the current version:
<code>pipx install git+https://github.com/raestrada/storycraftr.git@v0.4.0</code>
🚧 Coming Soon - Beta Release! 🚀
<br>Meanwhile, you can download the Alpha version, which is fully usable but may still have bugs:
<code>pipx install git+https://github.com/raestrada/storycraftr.git@v0.5.0-alpha1</code>
</div>
</section>

Expand Down
10 changes: 5 additions & 5 deletions docs/iterate.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@ storycraftr iterate check-names "Check character names for consistency."
To update or fix a character name across the entire book:

```bash
storycraftr iterate fix-name Santi Santiago
storycraftr iterate fix-name Zevid Rhaedin
```

### 2. Refine Character Motivation

Characters need strong motivations, and sometimes these evolve as you write. This command will **refine character motivations** throughout the book, ensuring consistency and depth.

```bash
storycraftr iterate refine-motivation "Refine the motivations of 'Elena' in a story about rebellion against gods."
storycraftr iterate refine-motivation "Rahedin ""Refine its motivations in a story about rebellion against gods."
```

### 3. Strengthen Story Argument
Expand All @@ -45,23 +45,23 @@ storycraftr iterate strengthen-argument "Ensure the argument of rebellion agains
Sometimes, you may need to insert a chapter between two existing ones. This command will **insert a new chapter** and automatically **adjust the numbering** of all subsequent chapters.

```bash
storycraftr iterate insert-chapter 5 "just extend the idea in 3 chapters instead of 2"
storycraftr iterate insert-chapter 2 "Insert a new chapter that explores a critical event from the protagonist’s past, shedding light on their true intentions and setting the stage for the conflict in chapter 1."
```

### 5. Split a Chapter

If a chapter becomes too long or covers too many topics, you can **split it into two separate chapters**. This command will split the specified chapter and adjust the numbering of all subsequent chapters.

```bash
storycraftr iterate split-chapter "Split chapter 5 into two chapters." 5
storycraftr 5 iterate split-chapter "Split chapter 5 into two chapters."
```

### 6. Add Flashbacks

Flashbacks are a great way to add depth to a character’s backstory. This command lets you **add a flashback scene** between two chapters, ensuring it integrates seamlessly with the surrounding narrative.

```bash
storycraftr iterate add-flashback "Add a flashback between chapters 6 and 7." 6
storycraftr iterate add-flashback 3 "Insert a flashback revealing a hidden alliance the protagonist formed years ago, explaining a key turning point in the current events."
```

### 7. Update Plot Points
Expand Down
120 changes: 46 additions & 74 deletions storycraftr/agent/iterate.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
REWRITE_SURROUNDING_CHAPTERS_PROMPT,
INSERT_FLASHBACK_CHAPTER_PROMPT,
REWRITE_SURROUNDING_CHAPTERS_FOR_FLASHBACK_PROMPT,
CHECK_CHAPTER_CONSISTENCY_PROMPT,
)
from storycraftr.agent.agents import (
update_agent_files,
Expand All @@ -22,7 +23,9 @@
console = Console()


def check_character_names_consistency(book_path, chapter_path, progress, task_id):
def check_character_names_consistency(
book_path, chapter_path, progress, task_id, assistant
):
"""
Checks for character name consistency in a chapter file.
Uses an OpenAI assistant to perform the review.
Expand All @@ -32,7 +35,6 @@ def check_character_names_consistency(book_path, chapter_path, progress, task_id
prompt = CHECK_NAMES_PROMPT

# Get or create the assistant and the thread
assistant = create_or_get_assistant(book_path, progress, task_id)
thread = get_thread()

# Create the message with the thread_id and assistant
Expand Down Expand Up @@ -84,6 +86,7 @@ def iterate_check_names(book_path):
return corrections

# Create a rich progress bar
assistant = create_or_get_assistant(book_path)
with Progress() as progress:
# Task to process chapters
task_chapters = progress.add_task(
Expand All @@ -100,7 +103,7 @@ def iterate_check_names(book_path):

# Call the function to check name consistency in the chapter
corrections[chapter_file] = check_character_names_consistency(
book_path, chapter_path, progress, task_openai
book_path, chapter_path, progress, task_openai, assistant=assistant
)

# Save to markdown
Expand Down Expand Up @@ -188,9 +191,11 @@ def fix_name_in_chapters(book_path, original_name, new_name):
return


def refine_character_motivation(book_path, character_name, story_context):
def process_chapters(
book_path, prompt_template, task_description, file_suffix, **prompt_kwargs
):
"""
Function to refine character motivations across all chapters in a book.
Generic function to process chapters in a book with a given prompt template.
"""
chapters_dir = os.path.join(book_path, "chapters")

Expand All @@ -209,25 +214,20 @@ def refine_character_motivation(book_path, character_name, story_context):
# Create progress bar
with Progress() as progress:
task_chapters = progress.add_task(
"[cyan]Refining character motivations...", total=len(files_to_process)
f"[cyan]{task_description}", total=len(files_to_process)
)
# Task for calling OpenAI for each chapter
task_openai = progress.add_task("[green]Calling OpenAI...", total=1)

# Iterate over each chapter file
for chapter_file in files_to_process:
chapter_path = os.path.join(chapters_dir, chapter_file)

# Create the prompt using the defined format
prompt = REFINE_MOTIVATION_PROMPT.format(
character_name=character_name, story_context=story_context
)
# Create the prompt using the provided template and kwargs
prompt = prompt_template.format(**prompt_kwargs)

# Get the assistant and thread
assistant = create_or_get_assistant(book_path)
thread = get_thread()

# Send the message to refine the character's motivations
progress.reset(task_openai)
refined_text = create_message(
book_path,
Expand All @@ -243,84 +243,56 @@ def refine_character_motivation(book_path, character_name, story_context):
save_to_markdown(
book_path,
os.path.join("chapters", chapter_file),
"Character Motivation Refinement",
file_suffix,
refined_text,
progress=progress,
task=task_chapters,
)

# Advance the progress bar
progress.update(task_chapters, advance=1)

update_agent_files(book_path, assistant)
return


def strengthen_core_argument(book_path, argument):
def refine_character_motivation(book_path, character_name, story_context):
"""
Function to strengthen the core argument across all chapters in a book.
Function to refine character motivations across all chapters in a book.
"""
chapters_dir = os.path.join(book_path, "chapters")

if not os.path.exists(chapters_dir):
raise FileNotFoundError(
f"The chapter directory '{chapters_dir}' does not exist."
)

files_to_process = [f for f in os.listdir(chapters_dir) if f.endswith(".md")]

if not files_to_process:
raise FileNotFoundError(
"No Markdown (.md) files were found in the chapter directory."
)

# Create progress bar
with Progress() as progress:
task_chapters = progress.add_task(
"[cyan]Strengthening core argument across chapters...",
total=len(files_to_process),
)
# Task for calling OpenAI for each chapter
task_openai = progress.add_task("[green]Calling OpenAI...", total=1)

# Iterate over each chapter file
for chapter_file in files_to_process:
chapter_path = os.path.join(chapters_dir, chapter_file)

# Create the prompt using the defined format
prompt = STRENGTHEN_ARGUMENT_PROMPT.format(argument=argument)

# Get the assistant and thread
assistant = create_or_get_assistant(book_path)
thread = get_thread()
process_chapters(
book_path,
prompt_template=REFINE_MOTIVATION_PROMPT,
task_description="Refining character motivations...",
file_suffix="Character Motivation Refinement",
character_name=character_name,
story_context=story_context,
)

progress.reset(task_openai)
# Send the message to refine the argument in the chapter
refined_text = create_message(
book_path,
thread_id=thread.id,
content=prompt,
assistant=assistant,
progress=progress,
task_id=task_openai,
file_path=chapter_path,
)

# Save the refined chapter
save_to_markdown(
book_path,
os.path.join("chapters", chapter_file),
"Core Argument Strengthening",
refined_text,
progress=progress,
task=task_chapters,
)
def strengthen_core_argument(book_path, argument):
"""
Function to strengthen the core argument across all chapters in a book.
"""
process_chapters(
book_path,
prompt_template=STRENGTHEN_ARGUMENT_PROMPT,
task_description="Strengthening core argument across chapters...",
file_suffix="Core Argument Strengthening",
argument=argument,
)

# Advance the progress bar
progress.update(task_chapters, advance=1)

update_agent_files(book_path, assistant)
return
def check_consistency_across(book_path, consistency_type):
"""
Function to check the consistency of chapters in a book.
"""
process_chapters(
book_path,
prompt_template=CHECK_CHAPTER_CONSISTENCY_PROMPT,
task_description=f"Checking {consistency_type} consistency across chapters...",
file_suffix=f"{consistency_type} Consistency Check",
consistency_type=consistency_type,
)


def insert_new_chapter(book_path, position, prompt, flashback=False):
Expand Down
22 changes: 11 additions & 11 deletions storycraftr/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,6 @@
import os
import json
from rich.console import Console
import storycraftr.templates.folder
from storycraftr.state import debug_state
from storycraftr.cmd.worldbuilding import worldbuilding
from storycraftr.cmd.outline import outline
from storycraftr.cmd.chapters import chapters
from storycraftr.cmd.iterate import iterate
from storycraftr.cmd.publish import publish
from storycraftr.cmd.chat import chat
from storycraftr.templates.tex import TEMPLATE_TEX


console = Console()

Expand All @@ -33,9 +23,18 @@ def load_openai_api_key():
console.print(f"[red]The file {api_key_file} does not exist.[/red]")


# Run the function
load_openai_api_key()

import storycraftr.templates.folder
from storycraftr.state import debug_state
from storycraftr.cmd.worldbuilding import worldbuilding
from storycraftr.cmd.outline import outline
from storycraftr.cmd.chapters import chapters
from storycraftr.cmd.iterate import iterate
from storycraftr.cmd.publish import publish
from storycraftr.cmd.chat import chat
from storycraftr.templates.tex import TEMPLATE_TEX


def verify_book_path(book_path=None):
"""Verify if the book path is valid and contains storycraftr.json."""
Expand Down Expand Up @@ -254,4 +253,5 @@ def init(
cli.add_command(chat)

if __name__ == "__main__":
# Run the function
cli()
23 changes: 17 additions & 6 deletions storycraftr/cmd/iterate.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
refine_character_motivation,
strengthen_core_argument,
insert_new_chapter,
check_consistency_across,
)

console = Console()
Expand Down Expand Up @@ -228,22 +229,32 @@ def update_plot_points(prompt, book_path):


@iterate.command()
@click.option("--book-path", type=click.Path(), help="Path to the book directory")
@click.option(
"--book-path", type=click.Path(), help="Path to the book directory", required=False
)
@click.argument("prompt")
def check_consistency(prompt, book_path):
"""Check for consistency across all chapters and elements of the book."""
"""
Command to check the overall consistency of chapters in the book.
Takes an optional custom prompt as an argument.
"""
if not book_path:
book_path = os.getcwd()

if not load_book_config(book_path):
return None

# Placeholder for future retrieval-based consistency check
console.print(
f"[yellow]The command 'check-consistency' is not yet implemented.[/yellow]"
f"[bold blue]Starting to check overall consistency in the book: {book_path}[/bold blue]"
)

# Call the function to check the consistency across chapters
check_consistency_across(book_path, prompt)

# Success log
console.print(
f"[green bold]Overall consistency check completed across all chapters![/green bold]"
)
console.print(f"Prompt: {prompt}")
# Future implementation would involve checking character arcs, plot points, worldbuilding, etc., using retrieval.


if __name__ == "__main__":
Expand Down
Loading

0 comments on commit b9279e9

Please sign in to comment.