feat(guardian): Mistral provider + auto-select by API key#87
Conversation
2.0-flash drops connections under load; 2.5-flash is stable. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- MistralProvider uses mistralai SDK (already in guardian dep-group) - guardian_review.py picks Mistral if MISTRAL_API_KEY is set, falls back to Gemini - GUARDIAN_MODEL override works for both providers - Add MISTRAL_API_KEY to guardian.yml workflow env - Add mistralai.* mypy override to silence import-untyped Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Warning You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again! |
Keep _build_provider logic from feat/mistral-provider; main's _DEFAULT_MODEL = "gemini-2.5-flash" is superseded by the provider auto-selection constants. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
/guardian review |
🛡️ CGIS Guardian Review ReportStatus: 📝 SummaryThe Pull Request introduces support for the Mistral AI provider within the Guardian review engine. It successfully adheres to the strict type discipline required by CGIS, avoids the use of 🔍 Detailed Findings1. Determinism & Configuration AmbiguityLocation: Issue: The current implementation of Reason: This violates our principle of Determinism. The engine's behavior should be explicitly driven by configuration, not by the accidental presence of environment variables. Suggested Fix: def _build_provider() -> tuple[BaseProvider, str]:
"""Return (provider, model_name) based on explicit provider selection."""
provider_choice = os.environ.get("GUARDIAN_PROVIDER", "gemini").lower()
model_override = os.environ.get("GUARDIAN_MODEL")
if provider_choice == "mistral":
mistral_key = os.environ.get("MISTRAL_API_KEY")
if not mistral_key:
raise RuntimeError("MISTRAL_API_KEY must be set when GUARDIAN_PROVIDER is 'mistral'")
model = model_override or _DEFAULT_MISTRAL_MODEL
return MistralProvider(api_key=mistral_key, model_name=model), model
# Default to Gemini
gemini_key = os.environ.get("GEMINI_API_KEY")
if not gemini_key:
raise RuntimeError("GEMINI_API_KEY must be set for the default provider")
model = model_override or _DEFAULT_GEMINI_MODEL
return GeminiProvider(api_key=gemini_key, model_name=model), model2. Semantic Exception MappingLocation: Issue: The function raises Reason: While not technically "incorrect," Suggested Fix: 3. Type Safety & Robustness (Positive Note)Location: Observation: The implementation of
✅ Checklist Compliance
🚀 Final RecommendationApprove after addressing the Determinism issue in The code quality is high, and the architectural pattern for new providers is well-defined. Once the provider selection is made explicit, this PR will be ready for merge. |
…eError - Add GUARDIAN_PROVIDER env var for explicit provider selection (Mistral wins if set, otherwise key-based auto-detection as before) - OSError → RuntimeError for configuration failures (semantic correctness) - Expose GUARDIAN_PROVIDER as GitHub Actions variable Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|



Summary
MistralProviderusing themistralaiSDK (already declared in[dependency-groups] guardian)guardian_review.pyauto-selects: ifMISTRAL_API_KEYis set → Mistral; otherwise Gemini. Raises clearly if neither is present.GUARDIAN_MODELenv override works for both providersMISTRAL_API_KEYsecret so you can add it in GitHub and switch with no code changesTest plan
MISTRAL_API_KEYsecret in GitHub repo settings/guardian reviewon a PR — it should pick Mistral automaticallyGUARDIAN_MODEL=mistral-large-latestas a GitHub variable to override the modelMISTRAL_API_KEYand verify Gemini fallback still works🤖 Generated with Claude Code