fix(model_metadata): rewrite localhost->IPv4 for the remaining local probe sites
fetch_endpoint_model_metadata's generic (non-LM-Studio) /models fetch and its llama.cpp /v1/props context-length follow-up built request URLs straight from the unrewritten candidate, unlike every other local-probe site. Both retained the multi-second dual-stack IPv6 connect penalty that _localhost_to_ipv4() exists to skip (measured on macOS: localhost 32.9ms vs 127.0.0.1 0.1ms on a dead port; ~2s on Windows). normalized stays the cache key so caching behavior is unchanged; only the outbound request target is rewritten. Re-derived from PR #61528 onto current main (original no longer applied cleanly).
This commit is contained in:
parent
d5584a32d8
commit
fc32a38c3a
|
|
@ -1184,7 +1184,11 @@ def fetch_endpoint_model_metadata(
|
|||
last_error = exc
|
||||
|
||||
for candidate in candidates:
|
||||
url = candidate.rstrip("/") + "/models"
|
||||
# normalized/candidates stay unrewritten (cache key stability); only
|
||||
# the outbound request target is IPv4-resolved to skip the multi-second
|
||||
# dual-stack IPv6 connect timeout (see _localhost_to_ipv4).
|
||||
request_candidate = _localhost_to_ipv4(candidate)
|
||||
url = request_candidate.rstrip("/") + "/models"
|
||||
response = None
|
||||
try:
|
||||
response = requests.get(
|
||||
|
|
@ -1230,7 +1234,7 @@ def fetch_endpoint_model_metadata(
|
|||
if is_llamacpp:
|
||||
try:
|
||||
# Try /v1/props first (current llama.cpp); fall back to /props for older builds
|
||||
base = candidate.rstrip("/").replace("/v1", "")
|
||||
base = request_candidate.rstrip("/").replace("/v1", "")
|
||||
_verify = _resolve_requests_verify()
|
||||
props_resp = requests.get(base + "/v1/props", headers=headers, timeout=5, verify=_verify)
|
||||
if not props_resp.ok:
|
||||
|
|
|
|||
|
|
@ -186,6 +186,61 @@ class TestLocalhostIPv4SiblingSites:
|
|||
|
||||
assert client.post.call_args[0][0].startswith("http://127.0.0.1:11434")
|
||||
|
||||
def test_fetch_endpoint_model_metadata_generic_probe_uses_ipv4(self):
|
||||
"""The generic (non-LM-Studio) /models fetch loop must also rewrite
|
||||
localhost->127.0.0.1 before probing, like the LM Studio branch above."""
|
||||
from agent import model_metadata
|
||||
from agent.model_metadata import fetch_endpoint_model_metadata
|
||||
|
||||
model_metadata._endpoint_model_metadata_cache.clear()
|
||||
model_metadata._endpoint_model_metadata_cache_time.clear()
|
||||
|
||||
resp = MagicMock()
|
||||
resp.status_code = 200
|
||||
resp.raise_for_status = MagicMock()
|
||||
resp.json.return_value = {"data": []}
|
||||
|
||||
with patch("agent.model_metadata.detect_local_server_type", return_value=None), \
|
||||
patch("agent.model_metadata.requests.get", return_value=resp) as mock_get:
|
||||
fetch_endpoint_model_metadata("http://localhost:8000/v1")
|
||||
|
||||
assert mock_get.call_args[0][0].startswith("http://127.0.0.1:8000")
|
||||
|
||||
def test_fetch_endpoint_model_metadata_llamacpp_props_followup_uses_ipv4(self):
|
||||
"""The llama.cpp /props context-length follow-up must also rewrite
|
||||
localhost->127.0.0.1 before probing, not just the initial /models call."""
|
||||
from agent import model_metadata
|
||||
from agent.model_metadata import fetch_endpoint_model_metadata
|
||||
|
||||
model_metadata._endpoint_model_metadata_cache.clear()
|
||||
model_metadata._endpoint_model_metadata_cache_time.clear()
|
||||
|
||||
models_resp = MagicMock()
|
||||
models_resp.status_code = 200
|
||||
models_resp.raise_for_status = MagicMock()
|
||||
models_resp.json.return_value = {
|
||||
"data": [{"id": "llama-3-8b", "owned_by": "llamacpp"}],
|
||||
}
|
||||
|
||||
props_resp = MagicMock()
|
||||
props_resp.ok = True
|
||||
props_resp.json.return_value = {
|
||||
"default_generation_settings": {"n_ctx": 32768},
|
||||
"model_alias": "llama-3-8b",
|
||||
}
|
||||
|
||||
with patch("agent.model_metadata.detect_local_server_type", return_value=None), \
|
||||
patch(
|
||||
"agent.model_metadata.requests.get",
|
||||
side_effect=[models_resp, props_resp],
|
||||
) as mock_get:
|
||||
result = fetch_endpoint_model_metadata("http://localhost:8000/v1")
|
||||
|
||||
assert mock_get.call_count == 2
|
||||
props_call_url = mock_get.call_args_list[1][0][0]
|
||||
assert props_call_url.startswith("http://127.0.0.1:8000")
|
||||
assert result["llama-3-8b"]["context_length"] == 32768
|
||||
|
||||
|
||||
|
||||
class TestContextCacheKeyNormalization:
|
||||
|
|
|
|||
Loading…
Reference in New Issue