Two prompt changes:
1. Greeting step: explicitly tell parents they can write in any language
(German, English, French, Italian, Spanish, …) and the agent will reply
in the same language. Also kick off info collection immediately by asking
for child name + DOB in the greeting reply.
2. Personality: replace the "1–2 questions at a time" rule with a strategy
that gathers all relevant questions per step in one message (woven into
natural sentences, not a form), and explicitly re-asks any unanswered
questions before advancing — no open question is silently skipped.
https://claude.ai/code/session_01HaUFs7SaLD5SoiuGCY27Tw
The LLM previously only received the stripped email body, giving it no
way to extract the sender's email address for the parentGuardian.email
field. Prepend Von:/Betreff: headers to every message so the LLM can
read the From address and subject without asking the parent for them.
The quoted_text sent back in the reply still uses only msg["body"] so
the quote block stays clean.
https://claude.ai/code/session_01HaUFs7SaLD5SoiuGCY27Tw
Tell the LLM explicitly that the reply field must be plain text with no
markdown (no bold, italic, headers, bullet points, or backticks). Email
clients display raw text so markdown syntax would appear as literal
characters rather than formatting.
https://claude.ai/code/session_01HaUFs7SaLD5SoiuGCY27Tw
Add standard > -prefixed quote block to outbound replies so parents can
see what they wrote in the previous message, matching natural email client
behaviour. The quote header uses the German "Am <date> schrieb <addr>:"
convention (matching Outlook/Thunderbird).
- email_channel.py: add _build_quoted_block() helper; extend send_reply()
with optional quoted_text/quoted_from params
- main.py: pass msg["body"] and msg["from"] as quoted_text/quoted_from
https://claude.ai/code/session_01HaUFs7SaLD5SoiuGCY27Tw
- prompts.py: correct age restrictions (indoor ≥2 yrs, outdoor ≥2.5 yrs)
Previously had indoor ≥2.5 and outdoor ≥3, which was too restrictive
- README.md: add full setup and configuration guide covering prerequisites,
installation, env var reference, provider switching, cron scheduling,
running tests, and knowledge base editing
https://claude.ai/code/session_01HaUFs7SaLD5SoiuGCY27Tw
Drops the src/providers/ package (base class, AnthropicProvider,
OpenAIProvider, factory) in favour of a single src/llm.py that calls
litellm.completion() directly. litellm handles provider routing,
authentication, and SDK differences for 100+ providers without any
code we need to maintain.
Changes:
- Delete src/providers/ entirely
- Add src/llm.py — one complete() function wrapping litellm
- src/agent/core.py: EmailAgent takes model: str instead of LLMProvider
- src/config.py: ai_provider + api key fields → single ai_model string
in litellm format (e.g. "anthropic/claude-opus-4-6")
- main.py: remove provider factory wiring; pass config.ai_model to agent
- .env.example: simplify AI section, show litellm model string examples
- pyproject.toml: replace anthropic + openai deps with litellm>=1.0.0
- uv.lock: regenerated
https://claude.ai/code/session_01HaUFs7SaLD5SoiuGCY27Tw
Closes the gap where parents sending a new email (instead of replying)
would lose their registration progress. All changes follow the
email-based-conversation-matching OpenSpec change.
Key changes
-----------
storage/json_store.py
- normalize_email() helper (lowercase + trim)
- Conversations now keyed by sender email address, not thread ID
- Versioned registration storage: data/registrations/<email>/v<N>_<ts>.json
- current.json always reflects the latest version
- save_registration() returns (email_key, version) tuple
- save_registration_version() for updates with change_summary
- get_registration_history() returns all versions in order
models/conversation.py
- Added last_inbound_message_id field for reply threading (not matching)
channels/email_channel.py
- fetch_unread_messages() no longer exposes thread_id
- Conversation matching removed from channel layer (now in agent)
- Removed _resolve_thread_id() — threading headers kept for SMTP only
agent/core.py
- process_message() takes parent_email + inbound_message_id (no thread ID)
- Looks up conversation by normalized email address
- Post-completion handler: detects intent (question / update / new_child)
- Registration updates: diffs old vs new, versions storage, notifies admin
agent/prompts.py
- build_system_prompt() dispatches to registration or post-completion prompt
- Post-completion prompt guides LLM to return intent field
- Reminder language updated: no expiration threats
notifications/notifier.py
- notify_admin() accepts version parameter
- notify_registration_update() sends "Registration Updated" emails with diff
- _build_update_body() includes field-level old→new change summary
main.py
- Poll loop passes parent_email + inbound_message_id to agent (no thread_id)
https://claude.ai/code/session_01HaUFs7SaLD5SoiuGCY27Tw
Replace thread-ID-based conversation matching with email-address-based
matching for more reliable conversation continuity. Key changes:
- One conversation per email address (simpler model)
- No data expiration (conversations persist indefinitely)
- Post-completion support (questions and registration updates)
- Versioned storage for registration updates (audit trail)
- Admin notifications for registration changes
This addresses the gap where parents sending new emails (instead of
replying) would lose their registration progress.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Documents project overview, repository structure, OpenSpec workflow,
system architecture decisions, domain knowledge (fees, schedule,
registration schema, conversation flow), and conventions for AI
assistants working in this repo.
https://claude.ai/code/session_01A6JAs2Pbg1hF1aLs7bcKhx
Define complete non-technical scope for replacing Google Forms registration
with an AI-powered conversational agent. Includes:
- Registration data requirements (13 fields with validation rules)
- Knowledge base content (fees, regulations, schedule, FAQ from official PDFs)
- Conversation flow design with bilingual support (German/English)
- Agent personality guidelines (warm & friendly tone)
- Admin notification routing by playgroup type
- Email reminder system for incomplete registrations
- Data export formats (CSV/JSON)
- Channel configuration (email + chat)
- Release priorities (MVP scope defined)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>