fix: use max_completion_tokens for GitHub Copilot

This commit is contained in:
stormhierta 2026-05-03 14:56:50 +00:00 committed by Teknium
parent d12be46df8
commit f648c2e3aa
4 changed files with 38 additions and 3 deletions

View file

@ -2862,10 +2862,11 @@ def auxiliary_max_tokens_param(value: int) -> dict:
"""
custom_base = _current_custom_base_url()
or_key = os.getenv("OPENROUTER_API_KEY")
# Only use max_completion_tokens for direct OpenAI custom endpoints
# Use max_completion_tokens for direct OpenAI-compatible providers that reject
# max_tokens on newer GPT-4o/o-series/GPT-5-style models.
if (not or_key
and _read_nous_auth() is None
and base_url_hostname(custom_base) == "api.openai.com"):
and base_url_hostname(custom_base) in {"api.openai.com", "api.githubcopilot.com"}):
return {"max_completion_tokens": value}
return {"max_tokens": value}

View file

@ -2852,6 +2852,16 @@ class AIAgent:
url = getattr(self, "_base_url_lower", "") or ""
return "openai.azure.com" in url
def _is_github_copilot_url(self, base_url: str = None) -> bool:
"""Return True when a base URL targets GitHub Copilot's OpenAI-compatible API."""
if base_url is not None:
hostname = base_url_hostname(base_url)
else:
hostname = getattr(self, "_base_url_hostname", "") or base_url_hostname(
getattr(self, "_base_url_lower", "")
)
return hostname == "api.githubcopilot.com"
def _resolved_api_call_timeout(self) -> float:
"""Resolve the effective per-call request timeout in seconds.
@ -3047,7 +3057,7 @@ class AIAgent:
OpenAI-compatible endpoint. OpenRouter, local models, and older
OpenAI models use 'max_tokens'.
"""
if self._is_direct_openai_url() or self._is_azure_openai_url():
if self._is_direct_openai_url() or self._is_azure_openai_url() or self._is_github_copilot_url():
return {"max_completion_tokens": value}
return {"max_tokens": value}

View file

@ -57,6 +57,18 @@ def codex_auth_dir(tmp_path, monkeypatch):
return codex_dir
class TestAuxiliaryMaxTokensParam:
def test_uses_max_completion_tokens_for_github_copilot_custom_base(self):
with patch("agent.auxiliary_client._resolve_custom_runtime", return_value=("https://api.githubcopilot.com", "key", None)), \
patch("agent.auxiliary_client._read_nous_auth", return_value=None):
assert auxiliary_max_tokens_param(2048) == {"max_completion_tokens": 2048}
def test_uses_max_completion_tokens_for_github_copilot_custom_base_path(self):
with patch("agent.auxiliary_client._resolve_custom_runtime", return_value=("https://api.githubcopilot.com/chat/completions", "key", None)), \
patch("agent.auxiliary_client._read_nous_auth", return_value=None):
assert auxiliary_max_tokens_param(2048) == {"max_completion_tokens": 2048}
class TestNormalizeAuxProvider:
def test_maps_github_copilot_aliases(self):
assert _normalize_aux_provider("github") == "copilot"

View file

@ -3666,6 +3666,18 @@ class TestMaxTokensParam:
result = agent._max_tokens_param(4096)
assert result == {"max_completion_tokens": 4096}
def test_returns_max_completion_tokens_for_github_copilot(self, agent):
"""GitHub Copilot's OpenAI-compatible API rejects max_tokens for newer models."""
agent.base_url = "https://api.githubcopilot.com"
result = agent._max_tokens_param(4096)
assert result == {"max_completion_tokens": 4096}
def test_returns_max_completion_tokens_for_github_copilot_path(self, agent):
"""Detect Copilot by hostname even when the configured URL includes a path."""
agent.base_url = "https://api.githubcopilot.com/chat/completions"
result = agent._max_tokens_param(4096)
assert result == {"max_completion_tokens": 4096}
class TestAzureOpenAIRouting:
"""Verify Azure OpenAI endpoints stay on chat_completions for gpt-5.x."""