diff --git a/src/opensquilla/cli/agent_cmd.py b/src/opensquilla/cli/agent_cmd.py index b3544d266f..7658725df2 100644 --- a/src/opensquilla/cli/agent_cmd.py +++ b/src/opensquilla/cli/agent_cmd.py @@ -897,6 +897,9 @@ def _write_json(path: str, payload: dict[str, Any]) -> None: def _print_no_provider_error() -> None: """Print a three-section diagnostic panel when no LLM provider is configured.""" + from opensquilla.onboarding.config_store import resolve_config_path + + config_path, _ = resolve_config_path(os.environ.get("OPENSQUILLA_GATEWAY_CONFIG_PATH")) body = Text.assemble( ("Symptom\n", "bold red"), "No LLM provider configured.\n\n", @@ -905,7 +908,7 @@ def _print_no_provider_error() -> None: "No API key was found. The following environment variables were all empty:\n" " OPENROUTER_API_KEY, OPENAI_API_KEY, ANTHROPIC_API_KEY,\n" " DEEPSEEK_API_KEY, GEMINI_API_KEY, DASHSCOPE_API_KEY, and others.\n" - "The config file ~/.opensquilla/config.toml also has no [llm].api_key set.\n\n" + f"The config file {config_path} also has no [llm].api_key set.\n\n" ), ("Next steps\n", "bold green"), ( @@ -915,7 +918,7 @@ def _print_no_provider_error() -> None: " export OPENROUTER_API_KEY=sk-or-... # POSIX / macOS / Linux\n" ' setx OPENROUTER_API_KEY "sk-or-..." ' "# Windows cmd: set OPENROUTER_API_KEY=...\n\n" - "Option 3 — edit ~/.opensquilla/config.toml and add:\n" + f"Option 3 — edit {config_path} and add:\n" " [llm]\n" ' api_key = "your-key-here"\n' ), diff --git a/tests/test_agent_cmd_no_key.py b/tests/test_agent_cmd_no_key.py index 7a4d5e4d5d..7b51a45d7e 100644 --- a/tests/test_agent_cmd_no_key.py +++ b/tests/test_agent_cmd_no_key.py @@ -140,3 +140,51 @@ def test_exit_code_nonzero_when_no_key( result = runner.invoke(app, ["-m", "hi"]) assert result.exit_code != 0 + + +def _flattened_output(output: str) -> str: + """Drop panel borders and whitespace so a long path that Rich wrapped still matches.""" + return re.sub(r"[│\s]", "", output) + + +def test_panel_names_the_state_dir_config_file( + monkeypatch: pytest.MonkeyPatch, + tmp_path: Path, +) -> None: + """With OPENSQUILLA_STATE_DIR set, the panel points at the config file the CLI reads.""" + for key in _PROVIDER_ENV_VARS: + monkeypatch.delenv(key, raising=False) + monkeypatch.delenv("OPENSQUILLA_GATEWAY_CONFIG_PATH", raising=False) + monkeypatch.setenv("HOME", str(tmp_path / "home")) + monkeypatch.setenv("USERPROFILE", str(tmp_path / "home")) + monkeypatch.chdir(tmp_path) + state_dir = tmp_path / "state" + monkeypatch.setenv("OPENSQUILLA_STATE_DIR", str(state_dir)) + + with _mock_patch(): + result = CliRunner().invoke(_make_app(), ["-m", "hi"]) + + combined = _flattened_output(result.output or "") + assert str(state_dir / "config.toml").replace(" ", "") in combined + assert "~/.opensquilla/config.toml" not in combined + + +def test_panel_names_the_explicit_config_file( + monkeypatch: pytest.MonkeyPatch, + tmp_path: Path, +) -> None: + """With OPENSQUILLA_GATEWAY_CONFIG_PATH set, the panel points at that file.""" + for key in _PROVIDER_ENV_VARS: + monkeypatch.delenv(key, raising=False) + monkeypatch.setenv("HOME", str(tmp_path / "home")) + monkeypatch.setenv("USERPROFILE", str(tmp_path / "home")) + monkeypatch.chdir(tmp_path) + config_file = tmp_path / "custom" / "my-config.toml" + monkeypatch.setenv("OPENSQUILLA_GATEWAY_CONFIG_PATH", str(config_file)) + + with _mock_patch(): + result = CliRunner().invoke(_make_app(), ["-m", "hi"]) + + combined = _flattened_output(result.output or "") + assert str(config_file).replace(" ", "") in combined + assert "~/.opensquilla/config.toml" not in combined