mirror of
https://github.com/katanemo/plano.git
synced 2026-06-17 15:25:17 +02:00
Break the 507-line monolithic validate_and_render_schema() into focused modules with pure validation functions, proper error handling, and clean I/O separation: - config_providers.py: provider constants, ConfigValidationError, unified URL parsing (replaces 3 different inline implementations) - config_validator.py: 11 pure validation functions (no I/O, no print/exit) - config_generator.py: thin 146-line I/O orchestrator, reads files once (was twice), uses logging instead of print() Also cleans up module responsibilities: - Move stream_access_logs from utils.py to docker_cli.py (Docker operation) - Deduplicate llm_providers->model_providers migration - Fix "Model alias 2 -" debug artifact in error message - Update docker-compose.dev.yaml volume mounts for new files - Rewrite tests: 53 tests calling pure functions directly (no mock_open chains), up from 10 brittle mock-dependent tests Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
87 lines
2 KiB
Python
87 lines
2 KiB
Python
"""Model provider constants, custom exception, and URL parsing utility."""
|
|
|
|
import logging
|
|
from urllib.parse import urlparse
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
|
|
class ConfigValidationError(Exception):
|
|
"""Raised when config validation fails."""
|
|
|
|
pass
|
|
|
|
|
|
# --- Provider Constants ---
|
|
|
|
SUPPORTED_PROVIDERS_WITH_BASE_URL = [
|
|
"azure_openai",
|
|
"ollama",
|
|
"qwen",
|
|
"amazon_bedrock",
|
|
"arch",
|
|
]
|
|
|
|
SUPPORTED_PROVIDERS_WITHOUT_BASE_URL = [
|
|
"deepseek",
|
|
"groq",
|
|
"mistral",
|
|
"openai",
|
|
"gemini",
|
|
"anthropic",
|
|
"together_ai",
|
|
"xai",
|
|
"moonshotai",
|
|
"zhipu",
|
|
]
|
|
|
|
SUPPORTED_PROVIDERS = (
|
|
SUPPORTED_PROVIDERS_WITHOUT_BASE_URL + SUPPORTED_PROVIDERS_WITH_BASE_URL
|
|
)
|
|
|
|
INTERNAL_PROVIDERS = {
|
|
"arch-function": {
|
|
"name": "arch-function",
|
|
"provider_interface": "arch",
|
|
"model": "Arch-Function",
|
|
"internal": True,
|
|
},
|
|
"plano-orchestrator": {
|
|
"name": "plano-orchestrator",
|
|
"provider_interface": "arch",
|
|
"model": "Plano-Orchestrator",
|
|
"internal": True,
|
|
},
|
|
}
|
|
|
|
|
|
def parse_url_endpoint(url):
|
|
"""Parse a URL into endpoint, port, protocol, and optional path_prefix.
|
|
|
|
Replaces the old get_endpoint_and_port() and inline urlparse logic.
|
|
Raises ConfigValidationError for invalid URLs.
|
|
|
|
Returns dict with keys: endpoint, port, protocol, path_prefix (optional)
|
|
"""
|
|
result = urlparse(url)
|
|
if not result.scheme or result.scheme not in ("http", "https"):
|
|
raise ConfigValidationError(
|
|
f"Invalid URL '{url}': scheme must be http or https"
|
|
)
|
|
if not result.hostname:
|
|
raise ConfigValidationError(f"Invalid URL '{url}': hostname is required")
|
|
|
|
port = result.port
|
|
if port is None:
|
|
port = 80 if result.scheme == "http" else 443
|
|
|
|
parsed = {
|
|
"endpoint": result.hostname,
|
|
"port": port,
|
|
"protocol": result.scheme,
|
|
}
|
|
|
|
if result.path and result.path != "/":
|
|
parsed["path_prefix"] = result.path
|
|
|
|
return parsed
|