fix: improve ccproxy OAuth install hint (#55)
Co-authored-by: Dinos Papakostas <dinospk1999@gmail.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -49,6 +49,40 @@ def is_ccproxy_available() -> bool:
|
|||||||
return _ccproxy_exe() is not None
|
return _ccproxy_exe() is not None
|
||||||
|
|
||||||
|
|
||||||
|
def _is_editable_install() -> bool:
|
||||||
|
"""Return True if EvoScientist was installed in editable/development mode.
|
||||||
|
|
||||||
|
Checks all matching distributions because a stale ``.egg-info`` in the
|
||||||
|
project root can shadow the real ``dist-info`` in site-packages.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
import json
|
||||||
|
import importlib.metadata as _meta
|
||||||
|
|
||||||
|
for dist in _meta.distributions():
|
||||||
|
name = dist.metadata.get("Name", "")
|
||||||
|
if name.lower() != "evoscientist":
|
||||||
|
continue
|
||||||
|
direct_url = dist.read_text("direct_url.json")
|
||||||
|
if direct_url is not None:
|
||||||
|
data = json.loads(direct_url)
|
||||||
|
if data.get("dir_info", {}).get("editable", False) is True:
|
||||||
|
return True
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def _oauth_install_hint() -> str:
|
||||||
|
"""Return the appropriate install command depending on install method."""
|
||||||
|
if _is_editable_install():
|
||||||
|
return (
|
||||||
|
"uv sync --extra oauth "
|
||||||
|
"or pip install -e '.[oauth]'"
|
||||||
|
)
|
||||||
|
return "pip install 'evoscientist[oauth]'"
|
||||||
|
|
||||||
|
|
||||||
def _summarize_auth_output(raw: str) -> str:
|
def _summarize_auth_output(raw: str) -> str:
|
||||||
"""Extract key fields from ccproxy auth status output into a one-line summary.
|
"""Extract key fields from ccproxy auth status output into a one-line summary.
|
||||||
|
|
||||||
@@ -356,7 +390,7 @@ def maybe_start_ccproxy(config: EvoScientistConfig) -> subprocess.Popen | None:
|
|||||||
if not is_ccproxy_available():
|
if not is_ccproxy_available():
|
||||||
raise RuntimeError(
|
raise RuntimeError(
|
||||||
"ccproxy is required for OAuth mode but not found. "
|
"ccproxy is required for OAuth mode but not found. "
|
||||||
"Install it with: pip install 'evoscientist[oauth]'"
|
f"Install it with: {_oauth_install_hint()}"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Check auth for each provider that uses OAuth
|
# Check auth for each provider that uses OAuth
|
||||||
|
|||||||
@@ -334,13 +334,30 @@ class TestMaybeStartCcproxy:
|
|||||||
mock_anthropic_env.assert_called_once()
|
mock_anthropic_env.assert_called_once()
|
||||||
mock_codex_env.assert_called_once()
|
mock_codex_env.assert_called_once()
|
||||||
|
|
||||||
|
@patch("EvoScientist.ccproxy_manager._is_editable_install", return_value=True)
|
||||||
@patch("EvoScientist.ccproxy_manager.is_ccproxy_available", return_value=False)
|
@patch("EvoScientist.ccproxy_manager.is_ccproxy_available", return_value=False)
|
||||||
def test_openai_oauth_raises_no_binary(self, mock_avail):
|
def test_openai_oauth_raises_no_binary_editable(self, mock_avail, mock_edit):
|
||||||
config = MagicMock()
|
config = MagicMock()
|
||||||
config.anthropic_auth_mode = "api_key"
|
config.anthropic_auth_mode = "api_key"
|
||||||
config.openai_auth_mode = "oauth"
|
config.openai_auth_mode = "oauth"
|
||||||
with pytest.raises(RuntimeError, match="not found"):
|
with pytest.raises(RuntimeError) as exc_info:
|
||||||
maybe_start_ccproxy(config)
|
maybe_start_ccproxy(config)
|
||||||
|
msg = str(exc_info.value)
|
||||||
|
assert "ccproxy is required for OAuth mode but not found" in msg
|
||||||
|
assert "uv sync --extra oauth" in msg
|
||||||
|
assert "pip install -e '.[oauth]'" in msg
|
||||||
|
|
||||||
|
@patch("EvoScientist.ccproxy_manager._is_editable_install", return_value=False)
|
||||||
|
@patch("EvoScientist.ccproxy_manager.is_ccproxy_available", return_value=False)
|
||||||
|
def test_openai_oauth_raises_no_binary_pip(self, mock_avail, mock_edit):
|
||||||
|
config = MagicMock()
|
||||||
|
config.anthropic_auth_mode = "api_key"
|
||||||
|
config.openai_auth_mode = "oauth"
|
||||||
|
with pytest.raises(RuntimeError) as exc_info:
|
||||||
|
maybe_start_ccproxy(config)
|
||||||
|
msg = str(exc_info.value)
|
||||||
|
assert "ccproxy is required for OAuth mode but not found" in msg
|
||||||
|
assert "pip install 'evoscientist[oauth]'" in msg
|
||||||
|
|
||||||
@patch(
|
@patch(
|
||||||
"EvoScientist.ccproxy_manager.check_ccproxy_auth",
|
"EvoScientist.ccproxy_manager.check_ccproxy_auth",
|
||||||
|
|||||||
Reference in New Issue
Block a user