Skip to content

Commit ac57a31

Browse files
authored
Merge pull request #63 from zhujian0805/main
Add CLAUDE_CODE_OAUTH_TOKEN support and related test
2 parents a84cedd + 5adc597 commit ac57a31

File tree

3 files changed

+45
-0
lines changed

3 files changed

+45
-0
lines changed

code_assistant_manager/strategies.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,11 @@ def setup_environment(self, context: ExecutionContext) -> Dict[str, str]:
7171
endpoint_config = context.endpoint_config
7272
env["ANTHROPIC_BASE_URL"] = str(endpoint_config.url)
7373
env["ANTHROPIC_AUTH_TOKEN"] = endpoint_config.get_api_key_value() or ""
74+
env["CLAUDE_CODE_OAUTH_TOKEN"] = (
75+
os.environ.get("CLAUDE_CODE_OAUTH_TOKEN")
76+
or endpoint_config.get_api_key_value()
77+
or ""
78+
)
7479
env["ANTHROPIC_MODEL"] = str(primary_model)
7580
env["ANTHROPIC_SMALL_FAST_MODEL"] = str(secondary_model)
7681
env["CLAUDE_MODEL_2"] = str(secondary_model)

code_assistant_manager/tools/claude.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import logging
2+
import os
23
from typing import List
34

45
from .base import CLITool
@@ -47,6 +48,11 @@ def run(self, args: List[str] = None) -> int:
4748
ToolEnvironmentBuilder(endpoint_config, model_vars)
4849
.set_base_url("ANTHROPIC_BASE_URL")
4950
.set_api_key("ANTHROPIC_AUTH_TOKEN")
51+
.set_custom_var(
52+
"CLAUDE_CODE_OAUTH_TOKEN",
53+
os.environ.get("CLAUDE_CODE_OAUTH_TOKEN")
54+
or endpoint_config.get("actual_api_key", ""),
55+
)
5056
.set_model("ANTHROPIC_MODEL", "primary_model")
5157
.set_model("ANTHROPIC_SMALL_FAST_MODEL", "secondary_model")
5258
.set_model("CLAUDE_MODEL_2", "secondary_model")
@@ -71,6 +77,7 @@ def run(self, args: List[str] = None) -> int:
7177
print(
7278
f"ANTHROPIC_BASE_URL={env['ANTHROPIC_BASE_URL']} "
7379
f"ANTHROPIC_AUTH_TOKEN=dummy "
80+
f"CLAUDE_CODE_OAUTH_TOKEN=*** "
7481
f"ANTHROPIC_MODEL={primary_model} "
7582
f"ANTHROPIC_DEFAULT_SONNET_MODEL={primary_model} "
7683
f"ANTHROPIC_SMALL_FAST_MODEL={secondary_model} "

tests/test_tools.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,9 +446,42 @@ def test_claude_environment_variables(
446446
env_used = mock_run.call_args[1]["env"]
447447
assert env_used["ANTHROPIC_BASE_URL"] == "https://api.example.com"
448448
assert env_used["ANTHROPIC_AUTH_TOKEN"] == "key123"
449+
assert env_used["CLAUDE_CODE_OAUTH_TOKEN"] == "key123"
449450
assert env_used["ANTHROPIC_MODEL"] == "claude-3"
450451
assert env_used["NODE_TLS_REJECT_UNAUTHORIZED"] == "0"
451452

453+
@patch("code_assistant_manager.tools.subprocess.run")
454+
@patch("code_assistant_manager.tools.select_two_models")
455+
@patch.object(ClaudeTool, "_ensure_tool_installed", return_value=True)
456+
@patch("code_assistant_manager.tools.EndpointManager")
457+
@patch.dict(
458+
os.environ,
459+
{
460+
"CODE_ASSISTANT_MANAGER_NONINTERACTIVE": "1",
461+
"CLAUDE_CODE_OAUTH_TOKEN": "oauth-token-from-env",
462+
},
463+
)
464+
def test_claude_environment_prefers_existing_oauth_token(
465+
self, mock_em_class, mock_install, mock_select, mock_run, config_manager
466+
):
467+
"""Test Claude uses an existing OAuth token from the environment."""
468+
mock_em = MagicMock()
469+
mock_em_class.return_value = mock_em
470+
471+
mock_em.select_endpoint.return_value = (True, "endpoint1")
472+
mock_em.get_endpoint_config.return_value = (
473+
True,
474+
{"endpoint": "https://api.example.com", "actual_api_key": "key123"},
475+
)
476+
mock_em.fetch_models.return_value = (True, ["claude-3"])
477+
mock_select.return_value = (True, ("claude-3", "claude-2"))
478+
479+
tool = ClaudeTool(config_manager)
480+
tool.run([])
481+
482+
env_used = mock_run.call_args[1]["env"]
483+
assert env_used["CLAUDE_CODE_OAUTH_TOKEN"] == "oauth-token-from-env"
484+
452485

453486
class TestToolErrorHandling:
454487
"""Test error handling in tools."""

0 commit comments

Comments
 (0)