Skip to content
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
99 changes: 65 additions & 34 deletions examples/bedtime-story-teller/assets/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,55 +7,83 @@ const socket = io(`http://${window.location.host}`);
let generateStoryButtonOriginalHTML = ''; // To store the original content of the generate story button
let storyBuffer = '';

// Error container elements
const errorContainer = document.getElementById('error-container');

function showError(message) {
errorContainer.textContent = message;
errorContainer.style.display = 'block';
}

function initSocketIO() {
socket.on('prompt', (data) => {
const promptContainer = document.getElementById('prompt-container');
const promptDisplay = document.getElementById('prompt-display');
promptDisplay.innerHTML = data;
promptContainer.style.display = 'block';
});

socket.on('response', (data) => {

document.getElementById('story-container').style.display = 'flex';

storyBuffer += data;

});



socket.on('stream_end', () => {
function hideError() {
errorContainer.style.display = 'none';
errorContainer.textContent = '';
}

const storyResponse = document.getElementById('story-response');

storyResponse.innerHTML = storyBuffer;
function handlePrompt(data) {
const promptContainer = document.getElementById('prompt-container');
const promptDisplay = document.getElementById('prompt-display');
promptDisplay.innerHTML = data;
promptContainer.style.display = 'block';
}


function handleResponse(data) {
document.getElementById('story-container').style.display = 'flex';
storyBuffer += data;
}

document.getElementById('loading-spinner').style.display = 'none';
function handleStreamEnd() {
hideError(); // Hide any errors on successful stream end

const clearStoryButton = document.getElementById('clear-story-button');
const storyResponse = document.getElementById('story-response');
storyResponse.innerHTML = storyBuffer;

clearStoryButton.style.display = 'block';
document.getElementById('loading-spinner').style.display = 'none';
const clearStoryButton = document.getElementById('clear-story-button');
clearStoryButton.style.display = 'block';
clearStoryButton.disabled = false;

clearStoryButton.disabled = false;
const generateStoryButton = document.querySelector('.generate-story-button');
if (generateStoryButton) {
generateStoryButton.disabled = false;
generateStoryButton.innerHTML = generateStoryButtonOriginalHTML; // Restore original content
}
}


function handleStoryError(data) {
// Hide the loading spinner
document.getElementById('loading-spinner').style.display = 'none';

const generateStoryButton = document.querySelector('.generate-story-button');
// Restore the generate story button
const generateStoryButton = document.querySelector('.generate-story-button');
if (generateStoryButton) {
generateStoryButton.disabled = false;
generateStoryButton.innerHTML = generateStoryButtonOriginalHTML;
}

if (generateStoryButton) {
// Display the error message in the dedicated error container
showError(`An error occurred while generating the story: ${data.error}`);

generateStoryButton.disabled = false;
// Also show the "New story" button to allow the user to restart
const clearStoryButton = document.getElementById('clear-story-button');
clearStoryButton.style.display = 'block';
clearStoryButton.disabled = false;
}

generateStoryButton.innerHTML = generateStoryButtonOriginalHTML; // Restore original content
function initSocketIO() {
socket.on('prompt', handlePrompt);
socket.on('response', handleResponse);
socket.on('stream_end', handleStreamEnd);
socket.on('story_error', handleStoryError);

}
socket.on('connect', () => {
hideError(); // Clear any previous errors on successful connection
});

});
socket.on('disconnect', () => {
showError("Connection to backend lost. Please refresh the page or check the backend server.");
});
}

function unlockAndOpenNext(currentContainer) {
Expand Down Expand Up @@ -229,6 +257,7 @@ function gatherDataAndGenerateStory() {
}

function generateStory(data) {
hideError(); // Hide any errors when starting a new generation
document.querySelector('.story-output-placeholder').style.display = 'none';
const responseArea = document.getElementById('story-response-area');
responseArea.style.display = 'flex';
Expand All @@ -251,6 +280,7 @@ function generateStory(data) {
}

function resetStoryView() {
hideError(); // Hide any errors when resetting view
document.querySelector('.story-output-placeholder').style.display = 'flex';
const responseArea = document.getElementById('story-response-area');
responseArea.style.display = 'none';
Expand Down Expand Up @@ -469,6 +499,7 @@ document.addEventListener('DOMContentLoaded', () => {
});

document.getElementById('generate-randomly-button').addEventListener('click', () => {
hideError(); // Hide any errors when starting a new generation
// Age
const ageChips = document.querySelectorAll('.parameter-container:nth-child(1) .chip');
const randomAgeChip = getRandomElement(ageChips);
Expand Down Expand Up @@ -519,4 +550,4 @@ document.addEventListener('DOMContentLoaded', () => {

generateStory(storyData);
});
});
});
1 change: 1 addition & 0 deletions examples/bedtime-story-teller/assets/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ <h3 class="response-title">Story</h3>
</div>

</div>
<div id="error-container" class="error-message" style="display: none;"></div>
</div>
</div>

Expand Down
15 changes: 14 additions & 1 deletion examples/bedtime-story-teller/assets/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -687,6 +687,14 @@ body {
100% { transform: rotate(360deg); }
}

.error-message {
background-color: #f8d7da;
color: #721c24;
padding: 10px;
margin-top: 20px;
border-radius: 5px;
text-align: center;
}


/*
Expand Down Expand Up @@ -791,5 +799,10 @@ body {
}

#story-response::-webkit-scrollbar-track {
background-color: transparent;
background-color: #ECF1F1;
}

#story-response::-webkit-scrollbar-thumb {
background-color: #C9D2D2;
border-radius: 4px;
}
79 changes: 41 additions & 38 deletions examples/bedtime-story-teller/python/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,44 +18,47 @@


def generate_story(_, data):
age = data.get('age', 'any')
theme = data.get('theme', 'any')
tone = data.get('tone', 'any')
ending_type = data.get('endingType', 'any')
narrative_structure = data.get('narrativeStructure', 'any')
duration = data.get('duration', 'any')
characters = data.get('characters', [])
other = data.get('other', '')

# Create a prompt with HTML for display
prompt_for_display = f"As a parent who loves to read bedtime stories to my <strong>{age}</strong> year old child, I need a delightful and age-appropriate story."

if characters:
prompt_for_display += " Characters of the story: "
char_prompts = []
for i, char in enumerate(characters):
ch = f"Character {i+1} (<strong>{char.get('name')}</strong>, <strong>{char.get('role')}</strong>"
ch += f", <strong>{char.get('description')}</strong>)" if char.get('description') else ")"
char_prompts.append(ch)
prompt_for_display += ", ".join(char_prompts)
prompt_for_display += "."

prompt_for_display += f" The story type is <strong>{theme}</strong>. The tone should be <strong>{tone}</strong>. The format should be a narrative-style story with a clear beginning, middle, and end, allowing for a smooth and engaging reading experience. The objective is to entertain and soothe the child before bedtime. Provide a brief introduction to set the scene and introduce the main character. The scope should revolve around the topic: managing emotions and conflicts. The length should be approximately <strong>{duration}</strong>. Please ensure the story has a <strong>{narrative_structure}</strong> narrative structure, leaving the child with a sense of <strong>{ending_type}</strong>. The language should be easy to understand and suitable for my child's age comprehension."
if other:
prompt_for_display += f"\n\nOther on optional stuff for the story: <strong>{other}</strong>"

# Create a plain text prompt for the LLM by stripping HTML tags
prompt_for_llm = re.sub('<[^>]*>', '', prompt_for_display)

# Send the display prompt to the UI
ui.send_message("prompt", prompt_for_display)

# Use the plain text prompt for the LLM and stream the response
for resp in llm.chat_stream(prompt_for_llm):
ui.send_message("response", resp)

# Signal the end of the stream
ui.send_message("stream_end", {})
try:
age = data.get('age', 'any')
theme = data.get('theme', 'any')
tone = data.get('tone', 'any')
ending_type = data.get('endingType', 'any')
narrative_structure = data.get('narrativeStructure', 'any')
duration = data.get('duration', 'any')
characters = data.get('characters', [])
other = data.get('other', '')

# Create a prompt with HTML for display
prompt_for_display = f"As a parent who loves to read bedtime stories to my <strong>{age}</strong> year old child, I need a delightful and age-appropriate story."

if characters:
prompt_for_display += " Characters of the story: "
char_prompts = []
for i, char in enumerate(characters):
ch = f"Character {i+1} (<strong>{char.get('name')}</strong>, <strong>{char.get('role')}</strong>"
ch += f", <strong>{char.get('description')}</strong>)" if char.get('description') else ")"
char_prompts.append(ch)
prompt_for_display += ", ".join(char_prompts)
prompt_for_display += "."

prompt_for_display += f" The story type is <strong>{theme}</strong>. The tone should be <strong>{tone}</strong>. The format should be a narrative-style story with a clear beginning, middle, and end, allowing for a smooth and engaging reading experience. The objective is to entertain and soothe the child before bedtime. Provide a brief introduction to set the scene and introduce the main character. The scope should revolve around the topic: managing emotions and conflicts. The length should be approximately <strong>{duration}</strong>. Please ensure the story has a <strong>{narrative_structure}</strong> narrative structure, leaving the child with a sense of <strong>{ending_type}</strong>. The language should be easy to understand and suitable for my child's age comprehension."
if other:
prompt_for_display += f"\n\nOther on optional stuff for the story: <strong>{other}</strong>"

# Create a plain text prompt for the LLM by stripping HTML tags
prompt_for_llm = re.sub('<[^>]*>', '', prompt_for_display)

# Send the display prompt to the UI
ui.send_message("prompt", prompt_for_display)

# Use the plain text prompt for the LLM and stream the response
for resp in llm.chat_stream(prompt_for_llm):
ui.send_message("response", resp)

# Signal the end of the stream
ui.send_message("stream_end", {})
except Exception as e:
ui.send_message("story_error", {"error": str(e)})

ui.on_message("generate_story", generate_story)

Expand Down