Ensure live provider checks reach the provider
Some checks failed
verify / verify (push) Has been cancelled
Some checks failed
verify / verify (push) Has been cancelled
Accept Docker Compose's exact string representation of the fixed 1024-dimensional embedding contract while rejecting every widened or ambiguous value. Entry-level smoke tests now exercise the same environment shape used by the container. Constraint: The current local Bailian credential still returns 401 for all three capabilities and is not stored in Git. Rejected: Change the field to an unconstrained integer | would allow a runtime dimension that disagrees with vector(1024). Confidence: high Scope-risk: narrow Directive: Keep the database vector dimension and provider dimension locked together through an ADR-backed migration. Tested: make verify; 75 backend tests; 14 frontend tests; rebuilt provider-smoke image; normal Compose smoke reached all three provider endpoints. Not-tested: Successful live provider response remains blocked by external authentication.
This commit is contained in:
@@ -71,6 +71,16 @@ class Settings(BaseSettings):
|
|||||||
def normalize_base_url(cls, value: str) -> str:
|
def normalize_base_url(cls, value: str) -> str:
|
||||||
return value.rstrip("/")
|
return value.rstrip("/")
|
||||||
|
|
||||||
|
@field_validator("embedding_dimension", mode="before")
|
||||||
|
@classmethod
|
||||||
|
def parse_embedding_dimension(cls, value: object) -> int:
|
||||||
|
"""Accept Compose's string representation without widening the contract."""
|
||||||
|
if value == "1024" or (
|
||||||
|
isinstance(value, int) and not isinstance(value, bool) and value == 1024
|
||||||
|
):
|
||||||
|
return 1024
|
||||||
|
raise ValueError("EMBEDDING_DIMENSION must be exactly 1024")
|
||||||
|
|
||||||
@model_validator(mode="after")
|
@model_validator(mode="after")
|
||||||
def validate_rag_limits(self) -> Self:
|
def validate_rag_limits(self) -> Self:
|
||||||
if self.chunk_overlap_tokens >= self.chunk_target_tokens:
|
if self.chunk_overlap_tokens >= self.chunk_target_tokens:
|
||||||
|
|||||||
@@ -46,6 +46,32 @@ def test_base_urls_drop_trailing_slashes() -> None:
|
|||||||
assert settings.bailian_rerank_base_url.endswith("/v1")
|
assert settings.bailian_rerank_base_url.endswith("/v1")
|
||||||
|
|
||||||
|
|
||||||
|
def test_embedding_dimension_accepts_compose_string(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||||
|
monkeypatch.setenv("EMBEDDING_DIMENSION", "1024")
|
||||||
|
|
||||||
|
settings = Settings(_env_file=None)
|
||||||
|
|
||||||
|
assert settings.embedding_dimension == 1024
|
||||||
|
assert isinstance(settings.embedding_dimension, int)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("configured", ["1536", "1024.0", "01024", " 1024 "])
|
||||||
|
def test_embedding_dimension_rejects_any_other_environment_value(
|
||||||
|
monkeypatch: pytest.MonkeyPatch,
|
||||||
|
configured: str,
|
||||||
|
) -> None:
|
||||||
|
monkeypatch.setenv("EMBEDDING_DIMENSION", configured)
|
||||||
|
|
||||||
|
with pytest.raises(ValueError, match="EMBEDDING_DIMENSION must be exactly 1024"):
|
||||||
|
Settings(_env_file=None)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("configured", [1024.0, True, None])
|
||||||
|
def test_embedding_dimension_rejects_non_integer_programmatic_values(configured: object) -> None:
|
||||||
|
with pytest.raises(ValueError, match="EMBEDDING_DIMENSION must be exactly 1024"):
|
||||||
|
Settings.model_validate({"embedding_dimension": configured})
|
||||||
|
|
||||||
|
|
||||||
def test_live_endpoints_must_share_one_beijing_workspace(tmp_path: Path) -> None:
|
def test_live_endpoints_must_share_one_beijing_workspace(tmp_path: Path) -> None:
|
||||||
key_path = tmp_path / "key"
|
key_path = tmp_path / "key"
|
||||||
key_path.write_text("test-key-value", encoding="utf-8")
|
key_path.write_text("test-key-value", encoding="utf-8")
|
||||||
|
|||||||
@@ -1,5 +1,54 @@
|
|||||||
|
import pytest
|
||||||
|
|
||||||
|
from app.core.config import Settings
|
||||||
from app.ports.model_providers import ModelProviderError, ProviderErrorKind
|
from app.ports.model_providers import ModelProviderError, ProviderErrorKind
|
||||||
from app.tools.provider_smoke import failed_probe
|
from app.tools import provider_smoke
|
||||||
|
from app.tools.provider_smoke import ProbeResult, failed_probe
|
||||||
|
|
||||||
|
|
||||||
|
def test_provider_smoke_settings_accept_compose_embedding_dimension(
|
||||||
|
monkeypatch: pytest.MonkeyPatch,
|
||||||
|
) -> None:
|
||||||
|
monkeypatch.setenv("EMBEDDING_DIMENSION", "1024")
|
||||||
|
|
||||||
|
settings = Settings(_env_file=None)
|
||||||
|
|
||||||
|
assert settings.embedding_dimension == 1024
|
||||||
|
|
||||||
|
|
||||||
|
async def test_provider_smoke_entrypoint_accepts_compose_embedding_dimension(
|
||||||
|
monkeypatch: pytest.MonkeyPatch,
|
||||||
|
) -> None:
|
||||||
|
workspace_host = "workspace-test.cn-beijing.maas.aliyuncs.com"
|
||||||
|
monkeypatch.setenv("EMBEDDING_DIMENSION", "1024")
|
||||||
|
monkeypatch.setenv(
|
||||||
|
"BAILIAN_OPENAI_BASE_URL",
|
||||||
|
f"https://{workspace_host}/compatible-mode/v1",
|
||||||
|
)
|
||||||
|
monkeypatch.setenv(
|
||||||
|
"BAILIAN_RERANK_BASE_URL",
|
||||||
|
f"https://{workspace_host}/compatible-api/v1",
|
||||||
|
)
|
||||||
|
observed_dimensions: list[int] = []
|
||||||
|
|
||||||
|
def fake_api_key(settings: Settings) -> str:
|
||||||
|
observed_dimensions.append(settings.embedding_dimension)
|
||||||
|
return "test-only-api-key"
|
||||||
|
|
||||||
|
async def successful_probe(settings: Settings, api_key: str) -> ProbeResult:
|
||||||
|
observed_dimensions.append(settings.embedding_dimension)
|
||||||
|
assert api_key == "test-only-api-key"
|
||||||
|
return ProbeResult(capability="test", status="ok")
|
||||||
|
|
||||||
|
monkeypatch.setattr(Settings, "bailian_api_key", fake_api_key)
|
||||||
|
monkeypatch.setattr(provider_smoke, "probe_embedding", successful_probe)
|
||||||
|
monkeypatch.setattr(provider_smoke, "probe_rerank", successful_probe)
|
||||||
|
monkeypatch.setattr(provider_smoke, "probe_chat", successful_probe)
|
||||||
|
|
||||||
|
exit_code = await provider_smoke.async_main()
|
||||||
|
|
||||||
|
assert exit_code == 0
|
||||||
|
assert observed_dimensions == [1024, 1024, 1024, 1024]
|
||||||
|
|
||||||
|
|
||||||
def test_failed_probe_only_exposes_sanitized_provider_fields() -> None:
|
def test_failed_probe_only_exposes_sanitized_provider_fields() -> None:
|
||||||
|
|||||||
Reference in New Issue
Block a user