Fetch models from Docker Model Runner API. Returns a list of model options with label and value. Docker Model Runner uses an OpenAI-compatible API at /engines/v1/models
(api_url)
| 981 | |
| 982 | |
| 983 | def _fetch_docker_models(api_url): |
| 984 | """ |
| 985 | Fetch models from Docker Model Runner API. |
| 986 | Returns a list of model options with label and value. |
| 987 | |
| 988 | Docker Model Runner uses an OpenAI-compatible API at /engines/v1/models |
| 989 | """ |
| 990 | import urllib.request |
| 991 | import urllib.error |
| 992 | from pgadmin.llm.utils import validate_api_url |
| 993 | |
| 994 | # Normalize URL |
| 995 | api_url = api_url.rstrip('/') |
| 996 | |
| 997 | if not validate_api_url(api_url): |
| 998 | raise LLMApiError( |
| 999 | 'API URL is not in the allowed list. ' |
| 1000 | 'Check the ALLOWED_LLM_API_URLS configuration.' |
| 1001 | ) |
| 1002 | |
| 1003 | url = f'{api_url}/engines/v1/models' |
| 1004 | |
| 1005 | req = urllib.request.Request(url) |
| 1006 | |
| 1007 | try: |
| 1008 | with urllib.request.urlopen( |
| 1009 | req, timeout=30, context=SSL_CONTEXT |
| 1010 | ) as response: |
| 1011 | data = json.loads(response.read().decode('utf-8')) |
| 1012 | except urllib.error.URLError as e: |
| 1013 | raise LLMApiError( |
| 1014 | f'Cannot connect to Docker Model Runner: ' |
| 1015 | f'{e.reason}. Is Docker Desktop running ' |
| 1016 | f'with model runner enabled?' |
| 1017 | ) |
| 1018 | except OSError: |
| 1019 | raise LLMApiError( |
| 1020 | 'Cannot connect to Docker Model Runner' |
| 1021 | ) |
| 1022 | |
| 1023 | models = [] |
| 1024 | seen = set() |
| 1025 | |
| 1026 | for model in data.get('data', []): |
| 1027 | model_id = model.get('id', '') |
| 1028 | |
| 1029 | # Skip if already seen or empty |
| 1030 | if not model_id or model_id in seen: |
| 1031 | continue |
| 1032 | seen.add(model_id) |
| 1033 | |
| 1034 | models.append({ |
| 1035 | 'label': model_id, |
| 1036 | 'value': model_id |
| 1037 | }) |
| 1038 | |
| 1039 | # Sort alphabetically |
| 1040 | models.sort(key=lambda x: x['value']) |
no test coverage detected