Metadata-Version: 2.4
Name: dailystories-generator
Version: 0.2.1
Summary: Gemini-based story generator for children's books
Author-email: DailyStories <your-email@example.com>
License: MIT
Keywords: ai,books,children,gemini,generator,story
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.11
Requires-Dist: google-generativeai>=0.8.0
Requires-Dist: pydantic>=2.0.0
Provides-Extra: dev
Requires-Dist: mypy>=1.0.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
Requires-Dist: pytest>=7.0.0; extra == 'dev'
Description-Content-Type: text/markdown

# DailyStories Generator

A Python library for generating children's storybooks using Google's Gemini AI.

## Installation

```bash
# From PyPI
pip install dailystories-generator

# Or with uv
uv pip install dailystories-generator
```

## Building and Publishing

### Build

```bash
./build.sh
```

This creates distribution files in `dist/` directory.

### Publish to PyPI

1. Get a PyPI API token from https://pypi.org/manage/account/token/
2. Set the token:
   ```bash
   export PYPI_TOKEN="pypi-your-token-here"
   ```
3. Publish:
   ```bash
   ./publish.sh
   ```

The publish script will automatically build the package before publishing.

## Quick Test

```bash
# Set your API key
export GOOGLE_API_KEY="your-gemini-api-key-here"

# Run a simple test
uv run python test.py

# Or test outline-only (faster)
uv run python test.py --outline-only

# Or test without images (faster)
uv run python test.py --no-images
```

## Usage

```python
from dailystories_generator import StoryGenerator, GenerationRequest, UpdateType

async def on_update(update):
    print(f"Update: {update.type}")
    if update.type == UpdateType.PAGE_COMPLETE:
        print(f"Page {update.data['page_number']} completed")

generator = StoryGenerator(gemini_api_key="your-api-key")

request = GenerationRequest(
    title="The Adventure Begins",
    summary="A tale of courage and friendship",
    num_pages=10,
    child_name="Alex",
    child_age=6,
    language="English",
    illustration_style="watercolor",
    generate_images=True,
)

story = await generator.generate(request, on_update=on_update)
print(f"Story generated with {len(story.pages)} pages")
```

## Features

- Async story generation with Gemini AI
- Optional image generation
- Support for multiple reference images
- Type-safe with full type annotations
- Callback-based progress updates
- **Prompt optimization system** for iterative improvement

## Prompt Optimization

The library includes a powerful prompt optimization system that automatically improves story generation prompts through iterative evaluation and feedback.

### Modes

1. **outline** - Optimizes story structure and outline generation
2. **pages** - Optimizes page text generation
3. **images** - Optimizes image generation prompts for child resemblance and story accuracy

### How It Works

1. **Generate** story content (outline, pages, or images)
2. **Evaluate** quality with LLM scoring (1-5 scale with explanations)
3. **Improve** prompts based on evaluation feedback
4. **Validate** that all template placeholders are preserved
5. **Track** scores in CSV for analysis
6. **Repeat** for N iterations

### Evaluation Categories

**Text modes (outline/pages)** evaluate on:
- **creativity** - Originality and imaginativeness
- **age_appropriateness** - Suitable content and vocabulary for target age
- **coherence** - Logical flow and narrative consistency
- **engagement** - How captivating for young readers
- **language_quality** - Grammar and writing style
- **plot_structure** - Clear beginning/middle/end
- **character_development** - Growth and relatability
- **character_introduction** - How well characters are established
- **emotional_resonance** - Emotional depth and impact
- **pacing** - Story rhythm and transitions
- **tone_consistency** - Maintaining age-appropriate tone

**Images mode** evaluates on:
- **child_resemblance** - How well the character matches the reference photo (hair, face, clothing, accessories)
- **story_capture** (cover) - How well the cover represents the story theme
- **page_content_accuracy** (pages) - How well illustrations depict the page text
- **style_consistency** (pages) - Artistic consistency and character appearance across pages

### Running Optimization

```bash
# Set your API key
export GOOGLE_API_KEY="your-gemini-api-key-here"

# Optimize the outline prompt (50 iterations)
uv run python optimize_prompts.py --mode outline --iterations 50 \
  --child-name Ludwig --child-age 6 \
  --title "The Magical Adventure" \
  --summary "A child discovers magic and goes on an adventure" \
  --language Norwegian

# Optimize the page generation prompt (20 iterations)
uv run python optimize_prompts.py --mode pages --iterations 20 \
  --child-name Emma --child-age 7 \
  --num-pages 5 \
  --language English

# Optimize image generation prompts (10 iterations)
uv run python optimize_prompts.py --mode images --iterations 10 \
  --reference-image photo.png \
  --child-name Ludwig --child-age 6 \
  --num-pages 5
```

### Command Line Options

- `--mode` - Type of prompt to optimize: `outline`, `pages`, or `images` (required)
- `--iterations` - Number of optimization iterations (default: 10)
- `--reference-image` - Path to reference photo of child (required for `images` mode)
- `--child-name` - Child's name for test story (default: Alex)
- `--child-age` - Child's age for test story (default: 6)
- `--title` - Story title (default: The Magical Adventure)
- `--summary` - Story theme/summary
- `--num-pages` - Number of pages (default: 5)
- `--language` - Story language (default: English)
- `--illustration-style` - Illustration style for images mode (default: colorful watercolor illustration)

### Output

The optimization system produces:

1. **Updated prompt templates** in `prompt_templates/`
   - Text modes: `story_outline_prompt.txt`, `story_page_prompt.txt`
   - Images mode: `cover_image_reference_prompt.txt`, `page_image_reference_prompt.txt`

2. **Statistics CSV** with scores over time:
   - Text modes: `statistics.csv`
   - Images mode: `image_statistics.csv`

3. **Detailed logs** with evaluation explanations and improvement suggestions:
   - Text modes: `optimization.log`
   - Images mode: `image_optimization.log`

### Analyzing Results

Use the `statistics.csv` file to plot score trajectories over iterations:

```python
import pandas as pd
import matplotlib.pyplot as plt

df = pd.read_csv('statistics.csv')
df_outline = df[df['mode'] == 'outline']

# Plot trajectory for each category
for category in ['creativity', 'engagement', 'coherence']:
    plt.plot(df_outline['iteration'], df_outline[category], label=category)

plt.xlabel('Iteration')
plt.ylabel('Score (1-5)')
plt.legend()
plt.title('Prompt Optimization Progress')
plt.show()
```

### Automatic Retry on Placeholder Loss

The system automatically validates that all template placeholders (e.g., `{child_name}`, `{story_so_far}`) are preserved during optimization. If the LLM forgets a placeholder, it receives clear feedback and retries up to 5 times before failing.

This ensures the system can run autonomously for hours without manual intervention.


