fix(agent): portable api.env path, declared rich dep, optional SSH HOST field#66
Conversation
There was a problem hiding this comment.
Code Review
This pull request implements dynamic resolution for the API environment file and adds support for explicit SSH hosts in server configurations. It also introduces the rich dependency and updates the test suite to reflect these changes. Review feedback recommends prioritizing local configuration files over global ones in the resolution logic to follow standard CLI conventions, along with a corresponding update to the test assertions.
| candidates = ( | ||
| Path.home() / ".chemsmart" / "api.env", | ||
| Path.cwd() / "api.env", | ||
| ) |
There was a problem hiding this comment.
The current resolution logic prioritizes the global configuration file (~/.chemsmart/api.env) over the local one (./api.env). In standard CLI tool design, local (project-specific) configuration is expected to override global configuration. Swapping the order allows users to define project-specific API keys more easily. Additionally, Path.home() can raise a RuntimeError if the home directory is not resolvable; while rare, placing it second or handling it defensively would improve portability.
| candidates = ( | |
| Path.home() / ".chemsmart" / "api.env", | |
| Path.cwd() / "api.env", | |
| ) | |
| candidates = ( | |
| Path.cwd() / "api.env", | |
| Path.home() / ".chemsmart" / "api.env", | |
| ) |
| def test_get_provider_prefers_home_api_env_over_cwd(monkeypatch, tmp_path): | ||
| dummy_provider = _configure_openai(monkeypatch) | ||
| home_dir = tmp_path / "home" | ||
| cwd_dir = tmp_path / "cwd" | ||
| cwd_dir.mkdir() | ||
| monkeypatch.setenv("HOME", str(home_dir)) | ||
| monkeypatch.chdir(cwd_dir) | ||
|
|
||
| _write_api_env(home_dir / ".chemsmart" / "api.env", "home-key") | ||
| _write_api_env(cwd_dir / "api.env", "cwd-key") | ||
|
|
||
| provider = providers.get_provider() | ||
|
|
||
| assert isinstance(provider, dummy_provider) | ||
| assert provider.api_key == "home-key" |
There was a problem hiding this comment.
This test asserts that the global configuration takes precedence over the local one. If the priority is reversed in chemsmart/agent/providers.py (as suggested), this test should be updated to verify that the local configuration (cwd-key) is preferred over the global one (home-key).
| def test_get_provider_prefers_home_api_env_over_cwd(monkeypatch, tmp_path): | |
| dummy_provider = _configure_openai(monkeypatch) | |
| home_dir = tmp_path / "home" | |
| cwd_dir = tmp_path / "cwd" | |
| cwd_dir.mkdir() | |
| monkeypatch.setenv("HOME", str(home_dir)) | |
| monkeypatch.chdir(cwd_dir) | |
| _write_api_env(home_dir / ".chemsmart" / "api.env", "home-key") | |
| _write_api_env(cwd_dir / "api.env", "cwd-key") | |
| provider = providers.get_provider() | |
| assert isinstance(provider, dummy_provider) | |
| assert provider.api_key == "home-key" | |
| def test_get_provider_prefers_cwd_api_env_over_home(monkeypatch, tmp_path): | |
| dummy_provider = _configure_openai(monkeypatch) | |
| home_dir = tmp_path / "home" | |
| cwd_dir = tmp_path / "cwd" | |
| cwd_dir.mkdir() | |
| monkeypatch.setenv("HOME", str(home_dir)) | |
| monkeypatch.chdir(cwd_dir) | |
| _write_api_env(home_dir / ".chemsmart" / "api.env", "home-key") | |
| _write_api_env(cwd_dir / "api.env", "cwd-key") | |
| provider = providers.get_provider() | |
| assert isinstance(provider, dummy_provider) | |
| assert provider.api_key == "cwd-key" |
Summary
api.envpath with portable resolution logic inchemsmart.agent.providersrich>=13,<15as a direct runtime dependency becausechemsmart.agent.cliimports it at module loadHOSTfield while preserving the existing filename-stem fallbackWhy
PR #65's HPC OS compatibility audit identified three portability defects on
fork/main:richonly arrived transitively viatextualUser / developer impact
--env-path,$CHEMSMART_API_ENV,~/.chemsmart/api.env, or./api.envrichexplicitlySERVER.HOSTin server YAML when the SSH alias differs from the filenameRoot cause
The agent code path baked in maintainer-local filesystem assumptions and relied on an undeclared transitive dependency.
Validation
AI_PROVIDER=openai python -m pytest -v tests/agent/test_providers_api_env_resolution.py tests/agent/test_transport_ssh_host_resolution.pyAI_PROVIDER=openai python -m pytest tests/agent/black -l 79 .isort --gitignore .ruff check . --fixNotes
bin/plan.mdis intentionally not linked here because it does not exist in this branch, per task instructions.