Skip to content

Commit 3c42d67

Browse files
committed
Merge branch 'main' into anticomputer/capi-cleanup
2 parents 13aef99 + 78aeae9 commit 3c42d67

File tree

4 files changed

+17
-11
lines changed

4 files changed

+17
-11
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
# SPDX-FileCopyrightText: GitHub, Inc.
22
# SPDX-License-Identifier: MIT
3-
__version__ = "0.2.0"
3+
__version__ = "0.3.0"

src/seclab_taskflow_agent/capi.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import json
1515
import logging
1616
import os
17+
from collections.abc import Mapping
1718
from dataclasses import dataclass, field
1819
from types import MappingProxyType
1920
from typing import Any
@@ -45,13 +46,17 @@ class APIProvider:
4546

4647
name: str
4748
base_url: str
48-
models_catalog: str = "models"
49+
models_catalog: str = "/models"
4950
default_model: str = "gpt-4.1"
50-
extra_headers: dict[str, str] = field(default_factory=dict)
51+
extra_headers: Mapping[str, str] = field(default_factory=dict)
5152

5253
def __post_init__(self) -> None:
54+
# Ensure base_url ends with / so httpx URL.join() preserves the path
55+
if self.base_url and not self.base_url.endswith("/"):
56+
object.__setattr__(self, "base_url", self.base_url + "/")
5357
# Freeze mutable headers so singleton providers can't be mutated
54-
object.__setattr__(self, "extra_headers", MappingProxyType(self.extra_headers))
58+
if isinstance(self.extra_headers, dict):
59+
object.__setattr__(self, "extra_headers", MappingProxyType(self.extra_headers))
5560

5661
# -- response parsing -----------------------------------------------------
5762

@@ -123,12 +128,13 @@ def check_tool_calls(self, _model: str, model_info: dict) -> bool:
123128
"models.github.ai": _GitHubModelsProvider(
124129
name="github-models",
125130
base_url="https://models.github.ai/inference",
126-
models_catalog="catalog/models",
131+
models_catalog="/catalog/models",
127132
default_model="openai/gpt-4.1",
128133
),
129134
"api.openai.com": _OpenAIProvider(
130135
name="openai",
131136
base_url="https://api.openai.com/v1",
137+
models_catalog="/v1/models",
132138
default_model="gpt-4.1",
133139
),
134140
}

tests/test_api_endpoint_config.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@ def test_api_endpoint_env_override(self):
4141

4242
def test_provider_base_urls(self):
4343
"""Test that providers resolve to expected base URLs."""
44-
assert get_provider("https://models.github.ai/inference").base_url == "https://models.github.ai/inference"
45-
assert get_provider("https://api.githubcopilot.com").base_url == "https://api.githubcopilot.com"
46-
assert get_provider("https://api.openai.com/v1").base_url == "https://api.openai.com/v1"
44+
assert get_provider("https://models.github.ai/inference").base_url == "https://models.github.ai/inference/"
45+
assert get_provider("https://api.githubcopilot.com").base_url == "https://api.githubcopilot.com/"
46+
assert get_provider("https://api.openai.com/v1").base_url == "https://api.openai.com/v1/"
4747

4848
def test_unsupported_endpoint(self, monkeypatch):
4949
"""Test that unsupported API endpoint falls back gracefully."""

tests/test_capi_extended.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,13 +104,13 @@ class TestGetProvider:
104104
def test_copilot_provider(self):
105105
p = get_provider("https://api.githubcopilot.com")
106106
assert p.name == "copilot"
107-
assert p.base_url == "https://api.githubcopilot.com"
107+
assert p.base_url == "https://api.githubcopilot.com/"
108108
assert "Copilot-Integration-Id" in p.extra_headers
109109

110110
def test_github_models_provider(self):
111111
p = get_provider("https://models.github.ai/inference")
112112
assert p.name == "github-models"
113-
assert p.models_catalog == "catalog/models"
113+
assert p.models_catalog == "/catalog/models"
114114
assert p.default_model == "openai/gpt-4.1"
115115

116116
def test_openai_provider(self):
@@ -121,5 +121,5 @@ def test_openai_provider(self):
121121
def test_custom_endpoint(self):
122122
p = get_provider("https://my-custom-llm.example.com/v1")
123123
assert p.name == "custom"
124-
assert p.base_url == "https://my-custom-llm.example.com/v1"
124+
assert p.base_url == "https://my-custom-llm.example.com/v1/"
125125
assert not p.extra_headers

0 commit comments

Comments
 (0)