Skip to content

Commit 6113b00

Browse files
Merge pull request #116 from sylwia-budzynska/sylwia-api-errors
Improve API endpoint error handling
2 parents f6b6dc6 + 3cf05ee commit 6113b00

File tree

4 files changed

+48
-9
lines changed

4 files changed

+48
-9
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ AI_API_TOKEN=<your_github_token>
4848
# MCP configs
4949
GH_TOKEN=<your_github_token>
5050
CODEQL_DBS_BASE_PATH="/app/my_data/codeql_databases"
51+
AI_API_ENDPOINT="https://models.github.ai/inference"
5152
```
5253

5354
## Deploying from Source

src/seclab_taskflow_agent/agent.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@
2727
case AI_API_ENDPOINT_ENUM.AI_API_MODELS_GITHUB:
2828
default_model = 'openai/gpt-4o'
2929
case _:
30-
raise ValueError(f"Unsupported Model Endpoint: {api_endpoint}")
30+
raise ValueError(
31+
f"Unsupported Model Endpoint: {api_endpoint}\n"
32+
f"Supported endpoints: {[e.to_url() for e in AI_API_ENDPOINT_ENUM]}"
33+
)
3134

3235
DEFAULT_MODEL = os.getenv('COPILOT_DEFAULT_MODEL', default=default_model)
3336

src/seclab_taskflow_agent/capi.py

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,20 @@
1111

1212
# Enumeration of currently supported API endpoints.
1313
class AI_API_ENDPOINT_ENUM(StrEnum):
14-
AI_API_MODELS_GITHUB = 'models.github.ai'
15-
AI_API_GITHUBCOPILOT = 'api.githubcopilot.com'
14+
AI_API_MODELS_GITHUB = 'models.github.ai'
15+
AI_API_GITHUBCOPILOT = 'api.githubcopilot.com'
16+
17+
def to_url(self):
18+
"""
19+
Convert the endpoint to its full URL.
20+
"""
21+
match self:
22+
case AI_API_ENDPOINT_ENUM.AI_API_GITHUBCOPILOT:
23+
return f"https://{self}"
24+
case AI_API_ENDPOINT_ENUM.AI_API_MODELS_GITHUB:
25+
return f"https://{self}/inference"
26+
case _:
27+
raise ValueError(f"Unsupported endpoint: {self}")
1628

1729
COPILOT_INTEGRATION_ID = 'vscode-chat'
1830

@@ -21,7 +33,7 @@ class AI_API_ENDPOINT_ENUM(StrEnum):
2133
# since different APIs use their own id schema, use -l with your desired
2234
# endpoint to retrieve the correct id names to use for your taskflow
2335
def get_AI_endpoint():
24-
return os.getenv('AI_API_ENDPOINT', default='https://models.github.ai/inference')
36+
return os.getenv('AI_API_ENDPOINT', default='https://models.github.ai/inference')
2537

2638
def get_AI_token():
2739
"""
@@ -50,7 +62,8 @@ def list_capi_models(token: str) -> dict[str, dict]:
5062
case AI_API_ENDPOINT_ENUM.AI_API_MODELS_GITHUB:
5163
models_catalog = 'catalog/models'
5264
case _:
53-
raise ValueError(f"Unsupported Model Endpoint: {api_endpoint}")
65+
raise ValueError(f"Unsupported Model Endpoint: {api_endpoint}\n"
66+
f"Supported endpoints: {[e.to_url() for e in AI_API_ENDPOINT_ENUM]}")
5467
r = httpx.get(httpx.URL(api_endpoint).join(models_catalog),
5568
headers={
5669
'Accept': 'application/json',
@@ -64,8 +77,6 @@ def list_capi_models(token: str) -> dict[str, dict]:
6477
models_list = r.json().get('data', [])
6578
case AI_API_ENDPOINT_ENUM.AI_API_MODELS_GITHUB:
6679
models_list = r.json()
67-
case _:
68-
raise ValueError(f"Unsupported Model Endpoint: {api_endpoint}")
6980
for model in models_list:
7081
models[model.get('id')] = dict(model)
7182
except httpx.RequestError as e:
@@ -88,7 +99,10 @@ def supports_tool_calls(model: str, models: dict) -> bool:
8899
return 'tool-calling' in models.get(model, {}).\
89100
get('capabilities', [])
90101
case _:
91-
raise ValueError(f"Unsupported Model Endpoint: {api_endpoint}")
102+
raise ValueError(
103+
f"Unsupported Model Endpoint: {api_endpoint}\n"
104+
f"Supported endpoints: {[e.to_url() for e in AI_API_ENDPOINT_ENUM]}"
105+
)
92106

93107
def list_tool_call_models(token: str) -> dict[str, dict]:
94108
models = list_capi_models(token)

tests/test_api_endpoint_config.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import pytest
99
import os
1010
from urllib.parse import urlparse
11-
from seclab_taskflow_agent.capi import get_AI_endpoint, AI_API_ENDPOINT_ENUM
11+
from seclab_taskflow_agent.capi import get_AI_endpoint, AI_API_ENDPOINT_ENUM, list_capi_models
1212

1313
class TestAPIEndpoint:
1414
"""Test API endpoint configuration."""
@@ -43,5 +43,26 @@ def test_api_endpoint_env_override(self):
4343
if original_env:
4444
os.environ['AI_API_ENDPOINT'] = original_env
4545

46+
def test_to_url_models_github(self):
47+
"""Test to_url method for models.github.ai endpoint."""
48+
endpoint = AI_API_ENDPOINT_ENUM.AI_API_MODELS_GITHUB
49+
assert endpoint.to_url() == 'https://models.github.ai/inference'
50+
51+
def test_to_url_githubcopilot(self):
52+
"""Test to_url method for GitHub Copilot endpoint."""
53+
endpoint = AI_API_ENDPOINT_ENUM.AI_API_GITHUBCOPILOT
54+
assert endpoint.to_url() == 'https://api.githubcopilot.com'
55+
56+
def test_unsupported_endpoint(self, monkeypatch):
57+
"""Test that unsupported API endpoint raises ValueError."""
58+
api_endpoint = 'https://unsupported.example.com'
59+
monkeypatch.setenv('AI_API_ENDPOINT', api_endpoint)
60+
with pytest.raises(ValueError) as excinfo:
61+
list_capi_models("abc")
62+
msg = str(excinfo.value)
63+
assert 'Unsupported Model Endpoint' in msg
64+
assert 'https://models.github.ai/inference' in msg
65+
assert 'https://api.githubcopilot.com' in msg
66+
4667
if __name__ == '__main__':
4768
pytest.main([__file__, '-v'])

0 commit comments

Comments
 (0)