Skip to content

docs: add story-book.gpt example #99

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion docs/README-USECASES.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,12 @@ Here is a GPTScript that summarizes the the code stored under the current direct
## Vision, Image, and Audio

### Vision

Here is an example of a web app that leverages GPTScript to recognize ingredients in a photo and suggest a recipe based on them: [recipe-generator](../examples/recipegenerator).

[More details to come]
### Image Generation

Here is a GPTScript that takes a story prompt and generates an illustrated children's book: [story-book.gpt](../examples/story-book)

## Memory Management

Expand Down
34 changes: 34 additions & 0 deletions examples/story-book/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Story Book

Story Book is a GPTScript that can generate a story based on a prompt and the number of pages you want the story to be in. It is generated in HTML format and can then be viewed
by `index.html` which has some JS/CSS to make the story styling consistent and readable.

## Usage Instructions

1. **Install and bootstrap the `image-generation` tool.**

This tool uses the `image-generation` tool, which is in a separate repository. To install and bootstrap the `image-generation` tool, starting at the root of `gptscript` run the following commands:

> Note: We'll soon have package management that handles tools installation for you, but until then, you have to manually clone and boostrap tools.

```shell
cd .. # This assumes you're starting at the root of the gptscript project. We want image-generation to be a sibling of gptscript.
git clone https://github.com/gptscript-ai/image-generation
cd image-generation
make bootstrap
source .venv/bin/activate
cd - # returns you back to your original directory
```

2. **Run the `story-book.gpt` script.**

In the same terminal session where the virtual environment (venv) is now activated, navigate to the `story-book` example directory and run the `story-book.gpt` script:

```shell
cd examples/story-book
gptscript story-book.gpt --prompt "Goldilocks" --pages 3
```

3. **View the story.**

Open `index.html` in your browser to view the generated story.
147 changes: 147 additions & 0 deletions examples/story-book/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
<!DOCTYPE html>
<html>
<head>
<title>Story Book</title>
<style>
body {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 0;
margin: 0 150px;
font-family: Arial, sans-serif;
min-height: 100vh;
background-color: #f5f5f5;
}

h1 {
text-align: center;
color: #333;
margin-bottom: 20px;
}

p {
margin-bottom: 10px;
}

select {
width: 200px;
margin-bottom: 20px;
}

iframe {
width: 100%;
height: calc(100vh - 200px); /* Adjust the height to leave space for other elements */
border: none;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}

.select-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin-bottom: 20px;
}

.select-container select {
margin-bottom: 10px;
}

.next-page-button,
.previous-page-button {
position: fixed;
top: 50%;
padding: 10px;
background-color: transparent;
color: #333;
border: none;
cursor: pointer;
font-size: 150px;
}

.next-page-button {
right: 160px;
transform: translateY(-50%);
}

.previous-page-button {
left: 160px;
transform: translateY(-36%) rotate(180deg);
}

.next-page-button:hover,
.previous-page-button:hover {
color: #666;
}

</style>
</head>
<body>
<h1>Story Book</h1>
<div class="select-container">
<select id="pageSelect">
<!-- Options will be populated by JavaScript, do not edit this -->
</select>
</div>
<iframe id="pageFrame"></iframe>
<button id="previousButton" class="previous-page-button">&#x2192;</button>
<button id="nextButton" class="next-page-button">&#x2192;</button>

<script>
// List of pages to display
var pages = ["pages/page1.html", "pages/page2.html"];

// Populate the select element with options
var select = document.getElementById("pageSelect");
var addedValues = []; // Track added values to avoid duplicates
for (var i = 0; i < pages.length; i++) {
var option = document.createElement("option");
option.value = pages[i];
option.text = "Page " + (i + 1);
if (!addedValues.includes(option.value)) {
select.appendChild(option);
addedValues.push(option.value);
}
}

// Function to change the iframe source
function changePage() {
var iframe = document.getElementById("pageFrame");
iframe.src = select.value;
}

// Function to switch to the next page
function switchPage() {
var currentIndex = select.selectedIndex;
var nextIndex = (currentIndex + 1) % pages.length;
select.selectedIndex = nextIndex;
changePage();
}

// Function to switch to the previous page
function previousPage() {
var currentIndex = select.selectedIndex;
var previousIndex = (currentIndex - 1 + pages.length) % pages.length;
select.selectedIndex = previousIndex;
changePage();
}

// Event listener for select change
select.addEventListener("change", changePage);

// Event listener for next button click
var nextButton = document.getElementById("nextButton");
nextButton.addEventListener("click", switchPage);

// Event listener for previous button click
var previousButton = document.getElementById("previousButton");
previousButton.addEventListener("click", previousPage);

// Load the first page by default
select.selectedIndex = 0;
changePage();
</script>
</body>
</html>
69 changes: 69 additions & 0 deletions examples/story-book/story-book.gpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
tools: story-writer, story-illustrator, mkdir, sys.write, sys.read, sys.download
description: Writes a children's book and generates illustrations for it.
args: story: The story to write and illustrate. Can be a prompt or a complete story.
args: pages: The number of pages to generate

Do the following steps sequentially:

1. Create the `pages` directory if it does not already exist.
2. If ${story} is a prompt and not a complete children's story, call story-writer
to write a story based on the prompt.
3. Take ${story} and break it up into ${pages} logical "pages" of text.
4. For each page:
- Call story-illustrator to illustrate it. Be sure to include any relevant characters to include when
asking it to illustrate the page.
- Download the illustration to a file at pages/<page_number>.png.
5. For each page and its illustration write an html file with the text on top and image below it to pages/page<page number>.html.
Assume the illustration file is a sibling to the html file, Add this style tag to the HTML file:
```html
<style>
body {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
}

img {
max-width: 100%;
height: auto;
margin-bottom: 5%
}

p {
margin: 5%;
font-size: 24px;
}
</style>
```
6. Edit the "pages" variable array in index.html to serve the pages you created. Do not
edit anything else. Do not edit the page select field.

---
name: story-writer
description: Writes a story for children
args: prompt: The prompt to use for the story

Write a story with a tone for children based on ${prompt}.

---
name: story-illustrator
tools: ../../../image-generation/tool.gpt
description: Generates a illustration for a children's story
args: text: The text of the page to illustrate

Think of a good prompt to generate an image to represent $text. Make sure to
include the name of any relevant characters in your prompt. Then use that prompt to
generate an illustration. Append any prompt that you have with ". In an pointilism cartoon
children's book style with no text in it". Only return the URL of the illustration.

---
name: mkdir
tools: sys.write
description: Creates a specified directory
args: dir: Path to the directory to be created

#!bash

mkdir ${dir}