diff --git a/CHANGELOG.md b/CHANGELOG.md index 38d0b81d..2e054d0c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. This format follows [Keep a Changelog](https://keepachangelog.com/) and adheres to [Semantic Versioning](https://semver.org/). +## [Unreleased] + +### Fixed +- **`agentops explain` and every `explain` manual command no longer crash on a + clean install.** The CLI imports `click` directly for its pager and manual + output paths, but `click` was not a declared dependency. Newer Typer releases + (0.26+) no longer pull `click` transitively, so `pip install + agentops-accelerator` produced a `ModuleNotFoundError: No module named 'click'` + for `agentops explain`, `agentops init explain`, and `agentops doctor explain`. + `click>=8.1,<9` is now an explicit runtime dependency. + ## [0.3.11] - 2026-06-08 ### Fixed diff --git a/pyproject.toml b/pyproject.toml index 6974c5a3..3f616cb4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,6 +10,7 @@ readme = "README.md" requires-python = ">=3.11" dependencies = [ "typer>=0.12,<1.0", + "click>=8.1,<9", "pydantic>=2,<3", "ruamel.yaml>=0.18,<1.0", "azure-ai-projects>=2.0.1,<3.0", diff --git a/src/agentops/services/azd_eval_init.py b/src/agentops/services/azd_eval_init.py index aae84d12..6caa267f 100644 --- a/src/agentops/services/azd_eval_init.py +++ b/src/agentops/services/azd_eval_init.py @@ -119,9 +119,7 @@ def run_azd_eval_init( effective_dataset, workspace=root, ) - command.extend( - ["--dataset", _command_path(effective_dataset, workspace=root)] - ) + command.extend(["--dataset", _command_path(effective_dataset, workspace=root)]) for evaluator in _azd_evaluators_from_config(resolved_config): command.extend(["--evaluator", evaluator]) @@ -147,7 +145,11 @@ def run_azd_eval_init( ) from exc if completed.returncode != 0: - detail = completed.stderr.strip() or completed.stdout.strip() or f"exit code {completed.returncode}" + detail = ( + completed.stderr.strip() + or completed.stdout.strip() + or f"exit code {completed.returncode}" + ) raise AzdBackendError(f"azd ai agent eval init failed: {detail}") recipe = find_eval_yaml(root) @@ -337,6 +339,8 @@ def _ensure_azd_project_env_metadata( if not location.found or location.env_path is None: location = ensure_azd_env(workspace, "sandbox") env_path = location.env_path + if env_path is None: + return updates = { "AZURE_AI_FOUNDRY_PROJECT_ENDPOINT": endpoint, "FOUNDRY_PROJECT_ENDPOINT": endpoint, @@ -475,7 +479,11 @@ def _azd_evaluators_from_config(config_path: Path) -> tuple[str, ...]: if not isinstance(raw_name, str) or not raw_name.strip(): continue name = raw_name.strip() - mapped = name if name.startswith("builtin.") else _EVALUATOR_NAME_TO_AZD.get(name) + mapped = ( + name + if name.startswith("builtin.") + else _EVALUATOR_NAME_TO_AZD.get(name) + ) if mapped and mapped not in names: names.append(mapped) return tuple(names) if names else _DEFAULT_AZD_EVALUATORS @@ -518,7 +526,9 @@ def _persist_recipe( data["eval_recipe"] = recipe_value if previous_execution in (None, "", "local", "auto"): data["execution"] = "azd" - config_updated = previous_recipe != recipe_value or data.get("execution") != previous_execution + config_updated = ( + previous_recipe != recipe_value or data.get("execution") != previous_execution + ) if config_updated: save_yaml(config_path, data) return AzdEvalInitResult(