Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 18 additions & 4 deletions routes/model_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,22 @@ def _truthy(value: str | None) -> bool:
return (value or "").strip().lower() in ("true", "1", "yes", "on")


def _parse_optional_bool(value: Any) -> bool | None:
if value is None:
return None
if isinstance(value, bool):
return value
if isinstance(value, int):
return bool(value)
if isinstance(value, str):
s = value.strip().lower()
if s in ("true", "1", "yes", "on"):
return True
if s in ("false", "0", "no", "off"):
return False
return None


_ENDPOINT_KINDS = {"auto", "local", "api", "proxy"}
_REFRESH_MODES = {"auto", "manual", "disabled"}

Expand Down Expand Up @@ -1852,8 +1868,7 @@ def create_model_endpoint(
ep_id = str(uuid.uuid4())[:8]
db = SessionLocal()
try:
_st_raw = (supports_tools or "").strip().lower()
_st = True if _st_raw in ("true", "1", "yes") else (False if _st_raw in ("false", "0", "no") else None)
_st = _parse_optional_bool(supports_tools)
_pinned = _normalize_model_ids(pinned_models)
# Stamp owner so the picker only shows this endpoint to the admin
# who added it. Pass `shared=true` to mark it null-owner (visible
Expand Down Expand Up @@ -2208,8 +2223,7 @@ async def toggle_model_endpoint(ep_id: str, request: Request):
raise HTTPException(404, "Endpoint not found")
if body:
if "supports_tools" in body:
v = body["supports_tools"]
ep.supports_tools = {True: True, False: False, 'true': True, 'false': False, 1: True, 0: False}.get(v)
ep.supports_tools = _parse_optional_bool(body.get("supports_tools"))
if "is_enabled" in body:
v_ie = body['is_enabled']
ep.is_enabled = v_ie.lower() in ('true', '1', 'yes') if isinstance(v_ie, str) else bool(v_ie)
Expand Down
13 changes: 13 additions & 0 deletions tests/test_model_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
_parse_model_list,
_normalize_refresh_mode,
_truthy,
_parse_optional_bool,
_speech_settings_using_endpoint,
_clear_speech_settings_for_endpoint,
_endpoint_settings_using_endpoint,
Expand Down Expand Up @@ -538,6 +539,18 @@ def test_truthy_true_values(self, value):
def test_truthy_false_values(self, value):
assert _truthy(value) is False

@pytest.mark.parametrize("value", [True, 1, "true", "1", "yes", "on", " TRUE "])
def test_parse_optional_bool_true(self, value):
assert _parse_optional_bool(value) is True

@pytest.mark.parametrize("value", [False, 0, "false", "0", "no", "off", " FALSE "])
def test_parse_optional_bool_false(self, value):
assert _parse_optional_bool(value) is False

@pytest.mark.parametrize("value", [None, "", "unknown", "invalid", [], {}])
def test_parse_optional_bool_none(self, value):
assert _parse_optional_bool(value) is None

def test_keyed_probe_does_not_fallback_to_curated_on_auth_failure(self, monkeypatch):
monkeypatch.setattr(endpoint_resolver, "resolve_url", lambda url: url, raising=False)
monkeypatch.setattr(model_routes, "_normalize_base", lambda url: url.rstrip("/"))
Expand Down
Loading