Repository navigation
Add Eden AI provider - #1187
Add Eden AI provider#1187
Conversation
Add Eden AI (an EU-based, OpenAI-compatible gateway) as a provider by subclassing BaseOpenAIProvider with a fixed base URL. Include a models list converter (Eden AI's /v3/models omits fields the OpenAI Model schema requires), the enum entry, the pyproject extra, conftest model maps and a unit test. Verified live against the real API: completion, streaming, embeddings, list_models, response_format and moderation.
WalkthroughChangesEden AI provider
Possibly related issues
Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Note that Eden AI exposes /v3/responses but any-llm's OpenResponses shape is unverified against it, so Responses stays unsupported for now. Correct the models-list docstring: created is the field reliably absent, object/owned_by may be present. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
njbrake
left a comment
There was a problem hiding this comment.
Note: this review was drafted by Claude via back-and-forth with @njbrake. The reasoning and decisions are his; the prose is Claude's.
Approving. Eden AI is a genuine EU-based, OpenAI-compatible gateway; I verified the base URL (https://api.edenai.run/v3), the provider/model id format, and the /v3/chat/completions, /v3/models, /v3/embeddings and /v3/moderations endpoints against Eden AI's official docs rather than the PR description. The implementation follows the OpenRouter pattern closely, mypy and ruff are clean locally, and the unit tests pass. CodeRabbit found nothing actionable.
Two small clarifications were pushed on top:
- SUPPORTS_RESPONSES stays False, now with a comment: Eden AI does expose /v3/responses, but any-llm's OpenResponses shape has not been verified against it, so it is left unsupported for now rather than claimed to work.
- The models-conversion docstring was corrected: created is the field reliably absent; object/owned_by may be present. The converter already handled all cases defensively.
Thanks for the clean, well-tested contribution.
Codecov Report❌ Patch coverage is
... and 38 files with indirect coverage changes 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/any_llm/providers/edenai/utils.py (1)
23-26: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueUse
getattrfor fallback and handle standard dictionaries.Using
getattr(response, "data", response)is a more idiomatic Python approach than using a conditionalhasattrcheck. As per coding guidelines,getattris the preferred approach for truly dynamic attributes (sinceresponseis typed asAny).Additionally, if the supplied
modelhappens to be a dictionary, callingvars(model)will raise aTypeError. It would be safer to explicitly handle dictionaries before falling back tovars().♻️ Proposed refactor
- raw_models = response.data if hasattr(response, "data") else response + raw_models = getattr(response, "data", response) result: list[Model] = [] for model in raw_models: - data: dict[str, Any] = model.model_dump() if hasattr(model, "model_dump") else dict(vars(model)) + data: dict[str, Any] = ( + model.model_dump() if hasattr(model, "model_dump") + else dict(model) if isinstance(model, dict) + else dict(vars(model)) + )🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/any_llm/providers/edenai/utils.py` around lines 23 - 26, Update the response extraction in the surrounding model-conversion function to use getattr(response, "data", response) instead of a hasattr conditional. In the model loop, handle dictionary instances directly as the data mapping before falling back to model_dump() or vars(model), preserving the existing Model conversion behavior.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@src/any_llm/providers/edenai/utils.py`:
- Around line 23-26: Update the response extraction in the surrounding
model-conversion function to use getattr(response, "data", response) instead of
a hasattr conditional. In the model loop, handle dictionary instances directly
as the data mapping before falling back to model_dump() or vars(model),
preserving the existing Model conversion behavior.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 0363beab-d3b5-4316-b8a4-77bba0f206fa
📒 Files selected for processing (2)
src/any_llm/providers/edenai/edenai.pysrc/any_llm/providers/edenai/utils.py
Description
This adds Eden AI as a provider.
Eden AI is an EU-based, OpenAI-compatible gateway. One API key reaches models from many providers (OpenAI, Anthropic, Google, Mistral, Cohere and more), with model ids like "openai/gpt-4o-mini", and it offers EU data residency, zero data retention, a DPA and SOC 2 / ISO 27001.
Implementation follows the OpenRouter provider pattern:
src/any_llm/providers/edenai/withEdenaiProvider(BaseOpenAIProvider), a fixedAPI_BASE(https://api.edenai.run/v3), and a small models-list converter (Eden AI's /v3/models omits object/owned_by/created that the OpenAI Model schema requires; extras like model_name and context_length are preserved).LLMProvider.EDENAIenum entry, theedenaiextra in pyproject (empty, no new dependency), and conftest model maps.tests/unit/providers/test_edenai_provider.py.Reasoning and the Responses API are marked unsupported: Eden AI's OpenAI-compatible endpoint inlines reasoning in the message content rather than in a separate field, and does not expose the Responses API.
Verified live against the real Eden AI API: completion, streaming, embeddings, list_models, response_format and moderation all pass. ruff, ruff-format and mypy are clean and the new unit tests pass. (I ran the edenai-relevant unit and integration tests locally; the full suite runs in CI with all extras.)
PR Type
Relevant issues
Fixes #1186
Checklist
AI Usage Information
AI Model used: Claude Opus 4.8
AI Developer Tool used: Claude Code
Any other info you'd like to share: Implemented and verified live against the real Eden AI API by an Eden AI team member using Claude Code. We will maintain the provider.
I am an AI Agent filling out this form (check box if true)
Summary by CodeRabbit