Fix env var fallback when base key is given, expert and base provider are different, and expert key is missing.

This commit is contained in:
AI Christianson 2024-12-19 09:18:10 -05:00
parent dd450da832
commit 53c2afdde3
4 changed files with 77 additions and 6 deletions

View File

@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added monorepo_detected, existing_project_detected, and ui_detected tools so the agent can take specific actions. - Added monorepo_detected, existing_project_detected, and ui_detected tools so the agent can take specific actions.
- Prompt improvements for real-world projects. - Prompt improvements for real-world projects.
- Fix env var fallback when base key is given, expert and base provider are different, and expert key is missing.
## [0.6.3] - 2024-12-18 ## [0.6.3] - 2024-12-18

View File

@ -56,12 +56,13 @@ def validate_environment(args) -> Tuple[bool, List[str]]:
expert_key = f'EXPERT_{config.key_name}' expert_key = f'EXPERT_{config.key_name}'
expert_key_missing = not os.environ.get(expert_key) expert_key_missing = not os.environ.get(expert_key)
# Try fallback to base key if providers match # Try fallback to base key for expert provider
fallback_available = expert_provider == provider and os.environ.get(config.key_name) fallback_available = os.environ.get(config.key_name)
if expert_key_missing and fallback_available: if expert_key_missing and fallback_available:
os.environ[expert_key] = os.environ[config.key_name] os.environ[expert_key] = os.environ[config.key_name]
expert_key_missing = False expert_key_missing = False
# Only add to missing list if still missing after fallback attempt
if expert_key_missing: if expert_key_missing:
expert_missing.append(f'{expert_key} environment variable is not set') expert_missing.append(f'{expert_key} environment variable is not set')
@ -69,7 +70,7 @@ def validate_environment(args) -> Tuple[bool, List[str]]:
if expert_provider == "openai-compatible": if expert_provider == "openai-compatible":
expert_base = 'EXPERT_OPENAI_API_BASE' expert_base = 'EXPERT_OPENAI_API_BASE'
base_missing = not os.environ.get(expert_base) base_missing = not os.environ.get(expert_base)
base_fallback = expert_provider == provider and os.environ.get('OPENAI_API_BASE') base_fallback = os.environ.get('OPENAI_API_BASE')
if base_missing and base_fallback: if base_missing and base_fallback:
os.environ[expert_base] = os.environ['OPENAI_API_BASE'] os.environ[expert_base] = os.environ['OPENAI_API_BASE']

View File

@ -119,7 +119,8 @@ def ask_expert(question: str) -> str:
The expert can be extremely useful at logic questions, debugging, and reviewing complex source code, but you must provide all context including source manually. The expert can be extremely useful at logic questions, debugging, and reviewing complex source code, but you must provide all context including source manually.
The query will automatically include any key facts and code snippets from memory, along with any additional context you've provided. The can see any key facts and code snippets previously noted, along with any additional context you've provided.
But the expert cannot see or reason about anything you have not explicitly provided in this way.
Try to phrase your question in a way that it does not expand the scope of our top-level task. Try to phrase your question in a way that it does not expand the scope of our top-level task.

View File

@ -88,3 +88,71 @@ def test_expert_fallback(clean_env, monkeypatch):
assert expert_enabled assert expert_enabled
assert not missing assert not missing
assert os.environ.get('EXPERT_OPENAI_API_KEY') == 'expert-key' assert os.environ.get('EXPERT_OPENAI_API_KEY') == 'expert-key'
def test_cross_provider_fallback(clean_env, monkeypatch):
"""Test that fallback works even when providers differ"""
args = MockArgs(provider="openai", expert_provider="anthropic")
# Set base API key for main provider and expert provider
monkeypatch.setenv('OPENAI_API_KEY', 'openai-key')
monkeypatch.setenv('ANTHROPIC_API_KEY', 'anthropic-key')
# Should enable expert mode with fallback to ANTHROPIC base key
expert_enabled, missing = validate_environment(args)
assert expert_enabled
assert not missing
assert os.environ.get('EXPERT_ANTHROPIC_API_KEY') == 'anthropic-key'
# Try with openai-compatible expert provider
args = MockArgs(provider="anthropic", expert_provider="openai-compatible")
monkeypatch.setenv('OPENAI_API_KEY', 'openai-key')
monkeypatch.setenv('OPENAI_API_BASE', 'http://test')
expert_enabled, missing = validate_environment(args)
assert expert_enabled
assert not missing
assert os.environ.get('EXPERT_OPENAI_API_KEY') == 'openai-key'
assert os.environ.get('EXPERT_OPENAI_API_BASE') == 'http://test'
def test_no_warning_on_fallback(clean_env, monkeypatch):
"""Test that no warning is issued when fallback succeeds"""
args = MockArgs(provider="openai", expert_provider="openai")
# Set only base API key
monkeypatch.setenv('OPENAI_API_KEY', 'test-key')
# Should enable expert mode with fallback and no warnings
expert_enabled, expert_missing = validate_environment(args)
assert expert_enabled
assert not expert_missing # List should be empty
assert os.environ.get('EXPERT_OPENAI_API_KEY') == 'test-key'
def test_different_providers_no_expert_key(clean_env, monkeypatch):
"""Test behavior when providers differ and only base keys are available"""
args = MockArgs(provider="anthropic", expert_provider="openai")
# Set only base keys
monkeypatch.setenv('ANTHROPIC_API_KEY', 'anthropic-key')
monkeypatch.setenv('OPENAI_API_KEY', 'openai-key')
# Should enable expert mode and use base OPENAI key
expert_enabled, missing = validate_environment(args)
assert expert_enabled
assert not missing
assert os.environ.get('EXPERT_OPENAI_API_KEY') == 'openai-key'
def test_mixed_provider_openai_compatible(clean_env, monkeypatch):
"""Test behavior with openai-compatible expert and different main provider"""
args = MockArgs(provider="anthropic", expert_provider="openai-compatible")
# Set all required keys and URLs
monkeypatch.setenv('ANTHROPIC_API_KEY', 'anthropic-key')
monkeypatch.setenv('OPENAI_API_KEY', 'openai-key')
monkeypatch.setenv('OPENAI_API_BASE', 'http://test')
# Should enable expert mode and use base openai key and URL
expert_enabled, missing = validate_environment(args)
assert expert_enabled
assert not missing
assert os.environ.get('EXPERT_OPENAI_API_KEY') == 'openai-key'
assert os.environ.get('EXPERT_OPENAI_API_BASE') == 'http://test'