refactor(providers): address PR #772 review round 2 — guard, naming, docs, tests
- _retry.py: replace `assert last_error is not None` with explicit `if last_error is None: raise RuntimeError(...)` so the original rate-limit error is preserved under `python -O`. - openai.py: drop the `_retry_factory` alias chain; rename the bound decorator to `_retry_429` to match the pattern in mistral.py. - mistral.py: comment the imports so future reviewers understand why `from mistralai.client import …` is the canonical path on 2.x (no top-level `__init__.py`; no `mistralai.models` subpackage either). - docs/configuration.md: add `OPENAI_GENERATION_MODEL` and `OLLAMA_GENERATION_MODEL` rows to the env-var reference table. - test_mistral.py: add direct unit test for the `_is_rate_limit` predicate (429 → True, 500 → False, missing-attr → False). - test_registry.py: stub `mistralai.client.Mistral` in the registry picker test, mirroring the Ollama sibling, so the test doesn't depend on the SDK accepting arbitrary keys. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
e360a7782b
commit
20f1770794
@@ -3,11 +3,13 @@
|
||||
from unittest.mock import AsyncMock, MagicMock
|
||||
|
||||
import pytest
|
||||
from mistralai.client.errors import SDKError
|
||||
|
||||
from nextcloud_mcp_server.providers.mistral import (
|
||||
BATCH_SIZE,
|
||||
MISTRAL_EMBEDDING_DIMENSIONS,
|
||||
MistralProvider,
|
||||
_is_rate_limit,
|
||||
)
|
||||
|
||||
|
||||
@@ -196,3 +198,17 @@ async def test_mistral_base_url_passed_to_sdk(mocker):
|
||||
api_key="test-key",
|
||||
server_url="https://example.com/mistral",
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_mistral_is_rate_limit_predicate():
|
||||
"""_is_rate_limit returns True only for SDKErrors with status_code == 429."""
|
||||
err_429 = MagicMock(spec=SDKError)
|
||||
err_429.status_code = 429
|
||||
err_500 = MagicMock(spec=SDKError)
|
||||
err_500.status_code = 500
|
||||
|
||||
assert _is_rate_limit(err_429) is True
|
||||
assert _is_rate_limit(err_500) is False
|
||||
# ValueError has no status_code attr → getattr returns None → False.
|
||||
assert _is_rate_limit(ValueError()) is False
|
||||
|
||||
@@ -69,8 +69,11 @@ def test_registry_picks_simple_with_custom_dimension(clean_provider_env):
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_registry_picks_mistral_when_api_key_set(clean_provider_env):
|
||||
def test_registry_picks_mistral_when_api_key_set(clean_provider_env, mocker):
|
||||
"""MISTRAL_API_KEY alone is enough to select MistralProvider."""
|
||||
# MistralProvider eagerly constructs the SDK client in __init__; stub it
|
||||
# so the test doesn't depend on the SDK accepting arbitrary keys.
|
||||
mocker.patch("nextcloud_mcp_server.providers.mistral.Mistral")
|
||||
clean_provider_env.setenv("MISTRAL_API_KEY", "test-key")
|
||||
_reload_config()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user