| from __future__ import annotations |
|
|
| import os |
| from dataclasses import dataclass |
|
|
| LOCAL_DEPLOYMENT = "local" |
| SPACE_DEPLOYMENT = "space" |
| VALID_DEPLOYMENTS = {LOCAL_DEPLOYMENT, SPACE_DEPLOYMENT} |
| PLACEHOLDER_BACKEND = "placeholder" |
|
|
|
|
| @dataclass(frozen=True) |
| class DeploymentPolicy: |
| mode: str = LOCAL_DEPLOYMENT |
|
|
| @property |
| def is_space(self) -> bool: |
| return self.mode == SPACE_DEPLOYMENT |
|
|
| @property |
| def allow_placeholder_backend(self) -> bool: |
| return not self.is_space |
|
|
| @property |
| def allow_demo_mode(self) -> bool: |
| return not self.is_space |
|
|
|
|
| def deployment_mode(env_value: str | None = None) -> str: |
| raw_value = env_value if env_value is not None else os.getenv("WORKBENCH_DEPLOYMENT", "") |
| value = raw_value.strip().lower() or LOCAL_DEPLOYMENT |
| if value not in VALID_DEPLOYMENTS: |
| raise ValueError( |
| "WORKBENCH_DEPLOYMENT must be 'local' or 'space'; " |
| f"got {raw_value!r}." |
| ) |
| return value |
|
|
|
|
| def current_policy() -> DeploymentPolicy: |
| return DeploymentPolicy(deployment_mode()) |
|
|
|
|
| def filter_backends_for_policy(backends: list[str], policy: DeploymentPolicy) -> list[str]: |
| if policy.allow_placeholder_backend: |
| return backends |
| return [backend for backend in backends if backend != PLACEHOLDER_BACKEND] |
|
|
|
|
| def default_backend_for_policy( |
| backends: list[str], |
| preferred: str, |
| policy: DeploymentPolicy, |
| ) -> str: |
| allowed = filter_backends_for_policy(backends, policy) |
| if preferred in allowed: |
| return preferred |
| if allowed: |
| return allowed[0] |
| raise ValueError("No real backend is available for this deployment policy.") |
|
|
|
|
| def ensure_backend_allowed(backend: str, policy: DeploymentPolicy) -> None: |
| if backend == PLACEHOLDER_BACKEND and not policy.allow_placeholder_backend: |
| raise ValueError( |
| "Placeholder inference is disabled in WORKBENCH_DEPLOYMENT=space. " |
| "Select a real backend such as transformers, Ollama, llama.cpp, " |
| "SGLang, or an OpenAI-compatible local server." |
| ) |
|
|
|
|
| def ensure_demo_mode_allowed(policy: DeploymentPolicy) -> None: |
| if not policy.allow_demo_mode: |
| raise ValueError( |
| "Demo/no-model mode is disabled in WORKBENCH_DEPLOYMENT=space. " |
| "Use a real OpenBMB model configuration for the deployed app." |
| ) |
|
|