Isolate cloud model access before enabling product RAG workflows
Some checks failed
verify / verify (push) Has been cancelled

The API and ingestion tools now use a fixed internal model gateway while
governed profiles, embedding cache assignments, traceable citations, and
stable API errors establish the boundaries required by later workflows.

Constraint: The current Alibaba Cloud workspace rejects all three live model calls with authentication failures
Rejected: Give the API or seed tools the Bailian key and direct egress | combines database access, cloud credentials, and public network access
Rejected: Mix offline and Bailian vectors in one demo namespace | makes profile activation and retrieval ambiguous
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: Keep Bailian credentials and egress exclusive to model-gateway and create a new immutable profile hash for any embedding identity change
Tested: make verify; 121 backend tests; 14 frontend tests; fresh and populated Alembic upgrade-downgrade-upgrade; two idempotent offline seeds; Docker health and HTTP retrieval; isolated provider smoke
Not-tested: Successful live Bailian responses because the supplied workspace credential currently fails authentication
This commit is contained in:
2026-07-13 04:09:06 +08:00
parent 99b7df64ea
commit 75592af33a
28 changed files with 3932 additions and 254 deletions

View File

@@ -35,6 +35,11 @@ class Settings(BaseSettings):
upload_root: Path = Path("/data/uploads")
max_upload_mb: int = Field(default=100, ge=1, le=2048)
model_gateway_base_url: str = "http://model-gateway:8000"
model_gateway_token_file: Path = Path("/run/secrets/model_gateway_api_token")
model_gateway_caller: Literal["api", "worker"] = "api"
model_gateway_timeout_seconds: float = Field(default=120, gt=0, le=600)
bailian_openai_base_url: str = (
"https://<workspace-id>.cn-beijing.maas.aliyuncs.com/compatible-mode/v1"
)
@@ -71,6 +76,24 @@ class Settings(BaseSettings):
def normalize_base_url(cls, value: str) -> str:
return value.rstrip("/")
@field_validator("model_gateway_base_url")
@classmethod
def validate_model_gateway_base_url(cls, value: str) -> str:
normalized = value.rstrip("/")
parsed = urlsplit(normalized)
if (
parsed.scheme != "http"
or parsed.hostname != "model-gateway"
or parsed.port != 8000
or parsed.path not in ("", "/")
or parsed.username is not None
or parsed.password is not None
or parsed.query
or parsed.fragment
):
raise ValueError("MODEL_GATEWAY_BASE_URL must be the fixed internal service URL")
return normalized
@field_validator("embedding_dimension", mode="before")
@classmethod
def parse_embedding_dimension(cls, value: object) -> int: