diff --git a/src/sentry/seer/endpoints/seer_rpc.py b/src/sentry/seer/endpoints/seer_rpc.py index e476c9abf5da5a..7d47716b96e6ef 100644 --- a/src/sentry/seer/endpoints/seer_rpc.py +++ b/src/sentry/seer/endpoints/seer_rpc.py @@ -1048,6 +1048,14 @@ def record_pr_attribution( return PrAttributionResponse(attribution_id=attribution.id) +class ValidateLlmProxyKeyResponse(BaseModel): + valid: bool + + +def validate_llm_proxy_key(api_key: str) -> ValidateLlmProxyKeyResponse: + return ValidateLlmProxyKeyResponse(valid=True) + + # Every value below MUST be a function returning a `pydantic.BaseModel` (or # a union of `BaseModel` subclasses, optionally with `None`). Two complementary # guards enforce this: @@ -1137,6 +1145,9 @@ def record_pr_attribution( # # Monitoring provider tokens (MCP) "refresh_monitoring_provider_token": seer_rpc(refresh_monitoring_provider_token), + # + # LLM Proxy + "validate_llm_proxy_key": seer_rpc(validate_llm_proxy_key), } diff --git a/tests/sentry/seer/endpoints/test_seer_rpc.py b/tests/sentry/seer/endpoints/test_seer_rpc.py index 067a70138790ec..5a0faed8c69ad3 100644 --- a/tests/sentry/seer/endpoints/test_seer_rpc.py +++ b/tests/sentry/seer/endpoints/test_seer_rpc.py @@ -91,6 +91,15 @@ def test_get_organization_features_registered_on_internal_rpc(self) -> None: assert "features" in response.data assert isinstance(response.data["features"], list) + def test_validate_llm_proxy_key(self) -> None: + path = self._get_path("validate_llm_proxy_key") + data: dict[str, Any] = {"args": {"api_key": "test-key"}} + response = self.client.post( + path, data=data, HTTP_AUTHORIZATION=self.auth_header(path, data) + ) + assert response.status_code == 200 + assert response.data["valid"] is True + def test_snuba_rate_limit_returns_429(self) -> None: """Test that SnubaRPCRateLimitExceeded returns 429 to Seer for retry.""" path = self._get_path("get_trace_waterfall")