Initial SQL-only 1C adapter baseline
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
from urllib.parse import urlparse
|
||||
|
||||
from common import ROOT, read_json
|
||||
|
||||
|
||||
GPU_PROFILES = ROOT / "config" / "gpu_profiles.json"
|
||||
KNOWN_SERVICES = {
|
||||
"vllm-text",
|
||||
"llama-gguf",
|
||||
"translation-api",
|
||||
"audio-api",
|
||||
"video-api",
|
||||
"image-api",
|
||||
"model-chat-ui",
|
||||
}
|
||||
REQUIRED_PROFILES = {"default", "text", "audio", "video", "image", "gguf-1c"}
|
||||
REQUIRED_FIELDS = {"id", "label", "command", "starts", "stops", "wait", "notes"}
|
||||
|
||||
|
||||
def require(condition: bool, message: str, errors: list[str]) -> None:
|
||||
if not condition:
|
||||
errors.append(message)
|
||||
|
||||
|
||||
def validate_service_list(profile_id: str, field: str, value: object, errors: list[str]) -> list[str]:
|
||||
require(isinstance(value, list), f"{profile_id}.{field} must be a list", errors)
|
||||
if not isinstance(value, list):
|
||||
return []
|
||||
|
||||
services = []
|
||||
for index, service in enumerate(value):
|
||||
if not isinstance(service, str) or not service:
|
||||
errors.append(f"{profile_id}.{field}[{index}] must be a non-empty string")
|
||||
continue
|
||||
services.append(service)
|
||||
if service not in KNOWN_SERVICES:
|
||||
errors.append(f"{profile_id}.{field}[{index}] has unknown service `{service}`")
|
||||
if len(services) != len(set(services)):
|
||||
errors.append(f"{profile_id}.{field} contains duplicate service ids")
|
||||
return services
|
||||
|
||||
|
||||
def validate_wait(profile_id: str, value: object, errors: list[str]) -> None:
|
||||
require(isinstance(value, list), f"{profile_id}.wait must be a list", errors)
|
||||
if not isinstance(value, list):
|
||||
return
|
||||
|
||||
for index, item in enumerate(value):
|
||||
if not isinstance(item, dict):
|
||||
errors.append(f"{profile_id}.wait[{index}] must be an object")
|
||||
continue
|
||||
name = item.get("name")
|
||||
url = item.get("url")
|
||||
if not isinstance(name, str) or not name:
|
||||
errors.append(f"{profile_id}.wait[{index}].name must be a non-empty string")
|
||||
if not isinstance(url, str) or not url:
|
||||
errors.append(f"{profile_id}.wait[{index}].url must be a non-empty string")
|
||||
continue
|
||||
parsed = urlparse(url)
|
||||
if parsed.scheme not in {"http", "https"} or not parsed.netloc:
|
||||
errors.append(f"{profile_id}.wait[{index}].url is not an HTTP URL: {url}")
|
||||
|
||||
|
||||
def validate_profile(profile_id: str, profile: object, errors: list[str]) -> None:
|
||||
if not isinstance(profile, dict):
|
||||
errors.append(f"{profile_id} must be an object")
|
||||
return
|
||||
|
||||
missing = sorted(REQUIRED_FIELDS - set(profile))
|
||||
if missing:
|
||||
errors.append(f"{profile_id} missing field(s): {', '.join(missing)}")
|
||||
|
||||
require(profile.get("id") == profile_id, f"{profile_id}.id must equal `{profile_id}`", errors)
|
||||
for field in ("label", "command", "notes"):
|
||||
require(isinstance(profile.get(field), str) and bool(profile.get(field)), f"{profile_id}.{field} must be a non-empty string", errors)
|
||||
|
||||
command = str(profile.get("command") or "")
|
||||
require(f"-Profile {profile_id}" in command, f"{profile_id}.command must include `-Profile {profile_id}`", errors)
|
||||
|
||||
starts = validate_service_list(profile_id, "starts", profile.get("starts"), errors)
|
||||
stops = validate_service_list(profile_id, "stops", profile.get("stops"), errors)
|
||||
overlap = sorted(set(starts) & set(stops))
|
||||
if overlap:
|
||||
errors.append(f"{profile_id} has service(s) in both starts and stops: {', '.join(overlap)}")
|
||||
validate_wait(profile_id, profile.get("wait"), errors)
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description="Validate GPU profile config.")
|
||||
parser.add_argument("--print", action="store_true", help="Print valid profile ids.")
|
||||
args = parser.parse_args()
|
||||
|
||||
try:
|
||||
profiles = read_json(GPU_PROFILES)
|
||||
except (OSError, ValueError) as exc:
|
||||
print(f"GPU profile config error: {exc}", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
errors: list[str] = []
|
||||
missing_profiles = sorted(REQUIRED_PROFILES - set(profiles))
|
||||
if missing_profiles:
|
||||
errors.append(f"missing required profile(s): {', '.join(missing_profiles)}")
|
||||
|
||||
for profile_id, profile in sorted(profiles.items()):
|
||||
validate_profile(str(profile_id), profile, errors)
|
||||
|
||||
if errors:
|
||||
print("GPU profile validation failed:", file=sys.stderr)
|
||||
for error in errors:
|
||||
print(f"- {error}", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
print(f"Validated {len(profiles)} GPU profile(s).")
|
||||
if args.print:
|
||||
for profile_id in sorted(profiles):
|
||||
print(f"- {profile_id}")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in New Issue
Block a user