Skip to content

Repository files navigation

Email Reflection Assistant

A structured email-writing assistant built with the reflection agentic design pattern:

  1. Writer creates an email from the user's context.
  2. Critic checks the draft for accuracy, tone, clarity, and completeness.
  3. Rewriter applies actionable feedback.
  4. The loop repeats until the email is approved or the iteration limit is reached.

The project uses Pydantic structured outputs and works with OpenAI or an OpenAI-compatible API.

Project layout

.
├── app.py                         # Streamlit UI
├── src/email_assistant/
│   ├── client.py                  # Environment-based API client
│   ├── critic.py                  # Draft evaluation
│   ├── models.py                  # Pydantic request/response models
│   ├── prompts.py                 # Agent instructions
│   ├── reflection.py              # Writer → critic → rewriter loop
│   └── writer.py                  # Initial draft generation
└── tests/
    ├── test_writer.py
    ├── test_critic.py
    └── test_reflection.py

Setup

Python 3.11+ is required. With uv:

uv sync
cp .env.example .env

Set OPENAI_API_KEY and MODEL_NAME in .env. For an OpenAI-compatible provider, set OPENAI_BASE_URL too. The legacy names API_KEY and BASE_URL are also accepted.

With standard pip:

python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
cp .env.example .env

Run the UI

uv run streamlit run app.py
# or: streamlit run app.py

Enter the sender and recipient context, choose a tone, optionally provide an existing draft, and click Write email. The UI displays the final email, provides a local Copy email button for the subject and body, and includes expandable critic/reflection details.

Screenshots

English example

English UI example

Persian example

The interface supports Persian input and mixed Persian/English text using the configured Unicode direction styles.

Persian UI example

Debug logging

The app logs workflow steps to the terminal running Streamlit. For example:

INFO | email_assistant.reflection | Reflection: iteration 1/3
INFO | email_assistant.writer | Writer: draft received in 2.14s
INFO | email_assistant.critic | Critic: completed in 1.08s (approved=False, issues=2)
INFO | email_assistant.reflection | Reflection: draft not approved; moving to rewriter

Logs include stage names, model name, timings, iteration counts, and approval state, but not API keys or full email content. Set level=logging.DEBUG in app.py if more verbose diagnostics are needed.

Run tests

Tests use fake structured responses and do not call an API:

uv run pytest
# or: pytest

About

A reflection-based AI email writing assistant that drafts, critiques, and improves emails using structured outputs and an OpenAI-compatible API.

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages