Goal
Make pip install mailplus-intelligence succeed without an LLM provider, and make every LLM-touching code path degrade gracefully when anthropic is absent or no API key is configured. Today the package imports anthropic from llm_extractor.py but does not declare it as a dependency, so a fresh install silently breaks LLM features.
This is R2 of six release milestones (R1–R6) leading to v0.1.0. Parent: see roadmap label release-v0.1.
Evidence
pyproject.toml:15 — dependencies = []
src/mailplus_intelligence/llm_extractor.py:119 — model literal claude-opus-4-7
src/mailplus_intelligence/llm_extractor.py constructs anthropic.Anthropic() at runtime; no guard for missing module or missing API key, no fallback to deterministic-only.
Acceptance criteria
Packaging
Runtime guards
Configurability
Tests
Definition of done
- All boxes above checked.
bash scripts/ci/run-fast-checks.sh green.
mpi doctor on a fresh pip install mailplus-intelligence (no extras) reports a clean "deterministic only" mode with a clear hint at how to enable LLM features.
Goal
Make
pip install mailplus-intelligencesucceed without an LLM provider, and make every LLM-touching code path degrade gracefully whenanthropicis absent or no API key is configured. Today the package importsanthropicfromllm_extractor.pybut does not declare it as a dependency, so a fresh install silently breaks LLM features.This is R2 of six release milestones (R1–R6) leading to v0.1.0. Parent: see roadmap label
release-v0.1.Evidence
pyproject.toml:15—dependencies = []src/mailplus_intelligence/llm_extractor.py:119— model literalclaude-opus-4-7src/mailplus_intelligence/llm_extractor.pyconstructsanthropic.Anthropic()at runtime; no guard for missing module or missing API key, no fallback to deterministic-only.Acceptance criteria
Packaging
pyproject.tomldeclaresanthropic(pinned to a known-working major) under an optional extra, e.g.[project.optional-dependencies] llm = ["anthropic>=0.40,<1.0"].pip install mailplus-intelligence(no extras) installs successfully and the deterministic CLI flow (mpi search,mpi queue,mpi export,mpi doctor) works end-to-end withoutanthropicon the path.pip install 'mailplus-intelligence[llm]'installsanthropicand unlocks LLM extraction.Runtime guards
llm_extractor.pylazy-importsanthropicinside the call site, not at module top.anthropicis missing, raise a singleLLMNotAvailable(or similar) with a message naming the install command (pip install 'mailplus-intelligence[llm]').ANTHROPIC_API_KEYis unset and no cassette is provided, raise the same / a sibling error with a clear next step. No silent crash from the SDK constructor.LLMNotAvailableand either:--llm {auto,off,required}flag (defaultauto= fall back).Configurability
--modelCLI flag →MAILPLUS_LLM_MODELenv var → default constant inllm_extractor.py.claude-opus-4-7for v0.1 but lives in one named constant, not inline.mpi doctorreports detected LLM availability, configured model, and whether an API key is present (without printing the key).Tests
tests/test_llm_extractor_no_anthropic.py(or equivalent) usingsys.modulespatching to prove the deterministic flow and the actionable error are correct when the SDK is absent.--llm offskips LLM calls even with everything installed.Definition of done
bash scripts/ci/run-fast-checks.shgreen.mpi doctoron a freshpip install mailplus-intelligence(no extras) reports a clean "deterministic only" mode with a clear hint at how to enable LLM features.