Commit Graph
18 Commits
Author SHA1 Message Date
Claude fef0388534 Quote parent's message in email replies
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
2026-02-21 20:05:12 +00:00
Claude 98a5f5b5b1 Resolve PR review comments
- 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
2026-02-21 13:35:35 +00:00
gurix 60f056ece4 Merge branch 'main' into claude/email-agent-multi-model-c3ShZ 2026-02-21 14:24:33 +01:00
Markus GrafandGitHub cfa90174e3 Merge pull request #3 from gurix/claude/update-readme-purpose-MxY60
Update README with project purpose and capabilities
2026-02-21 14:22:10 +01:00
Claude 7f55cdd204 Add pytest test suite (92 tests, all passing)
Covers every module in src/ with unit tests:

- tests/conftest.py        shared fixtures (complete_registration, fresh_state, …)
- tests/test_models.py     RegistrationData.is_complete(), to_dict/from_dict round-trips
- tests/test_storage.py    normalize_email, _diff_registrations, ConversationStore CRUD,
                           registration versioning
- tests/test_llm.py        litellm wrapper — message construction, model passthrough,
                           error propagation
- tests/test_agent.py      EmailAgent — new/existing conversations, registration
                           completion, admin notification, fallback on LLM error,
                           JSON parsing, _apply_updates
- tests/test_notifier.py   AdminNotifier routing, fee calculation, SMTP dispatch
- tests/test_knowledge_base.py  KnowledgeBase loading and reload

All external I/O (litellm, SMTP, filesystem) is mocked. Tests run fast (~6s)
with no network access required.

https://claude.ai/code/session_01HaUFs7SaLD5SoiuGCY27Tw
2026-02-21 08:07:31 +00:00
Claude 431847a8b7 Replace custom provider abstraction with litellm
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
2026-02-21 07:35:37 +00:00
Claude 1ba42f9497 docs: document flock + cron approach for email agent scheduling
https://claude.ai/code/session_01HaUFs7SaLD5SoiuGCY27Tw
2026-02-21 06:41:57 +00:00
Claude 05d4b51e7a Upgrade to Python 3.13
- .python-version: 3.11 → 3.13
- pyproject.toml: requires-python = ">=3.13"
- uv.lock: regenerated against Python 3.13.12

https://claude.ai/code/session_01HaUFs7SaLD5SoiuGCY27Tw
2026-02-20 22:30:43 +00:00
Claude a174023ee5 Switch to uv as dependency manager
- Add pyproject.toml with project metadata and pinned dependency ranges
- Add uv.lock (generated by `uv lock`) for reproducible installs
- Add .python-version pinning Python 3.11
- Remove requirements.txt (superseded by pyproject.toml)

Install: `uv sync`
Run: `uv run python main.py`

https://claude.ai/code/session_01HaUFs7SaLD5SoiuGCY27Tw
2026-02-20 22:29:37 +00:00
Claude 0c3b5a9033 Implement email-address-based conversation matching
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
2026-02-20 22:15:49 +00:00
Claude 968475804c Update README with project purpose and capabilities
Replaces the placeholder heading with a concise description of what
Meister-Eder does, its channels, and current status.

https://claude.ai/code/session_01XinJbQWij74daNnyZ9grSw
2026-02-20 22:14:45 +00:00
gurix c37862b75e Merge branch 'main' into claude/email-agent-multi-model-c3ShZ 2026-02-20 22:30:15 +01:00
gurixandClaude Opus 4.5 b10ff7a4fe Add change spec: email-based conversation matching
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>
2026-02-20 22:00:21 +01:00
Claude b82ff27efd Implement Python email agent with multi-model AI support
Adds a complete email-based registration agent for Spielgruppe Pumuckl
based on the OpenSpec define-project-scope specifications.

Architecture
- Channel-agnostic EmailAgent core — no email-specific code in business logic
- Pluggable AI provider layer: Anthropic (Claude) and OpenAI (GPT) supported
  via a shared LLMProvider interface; switch with AI_PROVIDER env var
- IMAP polling for inbound emails with thread-tracking via email headers
  (Message-ID / In-Reply-To / References)
- SMTP for outbound replies and admin notifications
- File-based JSON storage for conversation state and completed registrations
- Admin-editable knowledge-base loaded from markdown files at startup

Key files
  src/config.py                  — env-var configuration
  src/providers/base.py          — abstract LLMProvider
  src/providers/anthropic_provider.py — Claude backend
  src/providers/openai_provider.py    — OpenAI backend
  src/agent/core.py              — EmailAgent orchestrator
  src/agent/prompts.py           — system prompt builder (KB + registration state)
  src/models/registration.py     — RegistrationData matching the JSON schema
  src/models/conversation.py     — ConversationState persisted per thread
  src/channels/email_channel.py  — IMAP/SMTP I/O + quoted-text stripping
  src/storage/json_store.py      — conversation & registration persistence
  src/notifications/notifier.py  — admin notification routing by playgroup type
  main.py                        — polling entry point
  requirements.txt               — anthropic, openai, python-dotenv, jsonschema
  .env.example                   — configuration template

https://claude.ai/code/session_01HaUFs7SaLD5SoiuGCY27Tw
2026-02-20 20:17:00 +00:00
Markus GrafandGitHub 4d44d4ee58 Merge pull request #1 from gurix/claude/claude-md-mlv4qouppkw29jdy-GvDt5
Add CLAUDE.md with comprehensive codebase documentation
2026-02-20 18:00:08 +01:00
Claude f24525e691 Add CLAUDE.md with comprehensive codebase documentation
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
2026-02-20 16:58:08 +00:00
gurixandClaude Opus 4.5 145947c520 Add project scope documentation for AI playgroup registration system
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>
2026-02-20 17:52:13 +01:00
Markus GrafandGitHub 685bfbd03f Initial commit 2026-02-20 14:12:45 +01:00