Skip to content

feat: add pantheon doctor command for environment diagnostics#43

Open
hazelian0619 wants to merge 1 commit intoaristoteleo:mainfrom
hazelian0619:feat/doctor-command
Open

feat: add pantheon doctor command for environment diagnostics#43
hazelian0619 wants to merge 1 commit intoaristoteleo:mainfrom
hazelian0619:feat/doctor-command

Conversation

@hazelian0619
Copy link
Copy Markdown

feat: add pantheon doctor command for environment diagnostics

Summary

Pantheon currently auto-checks for LLM provider API keys at startup
(check_and_run_setup), but has no way to surface other common
environment misconfigurations before execution begins.

This PR adds an explicit pantheon doctor command that makes the
project's existing environment contracts visible before a run starts,
following established CLI diagnostics patterns used by
flutter doctor, npm doctor, dbt debug, and brew doctor.

Motivation

Two concrete gaps this addresses:

1. Python versionpyproject.toml declares requires-python = ">=3.10",
but nothing checks this at runtime; mismatches only surface as cryptic
import failures.

2. Core package integrityipykernel, jupyter-client, and nbformat
are declared required dependencies. A broken or incomplete install
silently degrades notebook functionality with no clear diagnosis.

Additionally, the r optional-dependency comment in pyproject.toml
explicitly states "requires R installed on system". When a user installs
the r extra but does not have R on PATH, the failure is currently silent
until rpy2 is actually called.

Changes

File Change
pantheon/doctor.py New file — check functions + run_doctor() runner
pantheon/__main__.py +9 lines — add doctor to auto-setup skip list, add doctor() function, register in fire.Fire()

No other files are modified.

What pantheon doctor checks

Check Level Basis
Python ≥ 3.10 FAIL pyproject.toml requires-python
LLM provider key configured WARN mirrors check_and_run_setup() four-step detection: SKIP_SETUP_WIZARDPROVIDER_API_KEYSCUSTOM_ENDPOINT_ENVSLLM_API_KEY
ipykernel / jupyter-client / nbformat importable FAIL declared required deps
R runtime on PATH WARN r optional extra — pyproject.toml comment: "requires R installed on system"

All checks are output-only. The command never modifies the system.

Design notes

Why doctor skips check_and_run_setup()

The existing guard in main() already skips the setup wizard when
sys.argv[1] == "setup". doctor is added to this skip list for the
same reason: running pantheon doctor should surface the environment
state, not trigger the interactive wizard. The one-character change
(!= "setup"not in ("setup", "doctor")) makes this explicit.

Why _check_api_keys mirrors check_and_run_setup exactly

Rather than defining a new key-detection heuristic, _check_api_keys()
replicates the same four-step check from check_and_run_setup() in the
same order (SKIP_SETUP_WIZARDPROVIDER_API_KEYS
CUSTOM_ENDPOINT_ENVS → legacy LLM_API_KEY), so that doctor and the
startup wizard always agree on whether the environment is configured.

Non-goals

  • Does not change any existing command's behavior
  • Does not auto-trigger on any existing command
  • Does not add new settings keys or configuration surface
  • Does not introduce a component registration API
  • Does not model downstream workflow requirements

Backward compatibility

None — this is a pure addition. All existing commands are unchanged.

Testing

pantheon doctor          # shows structured PASS/WARN/FAIL table
echo $?                  # 0 = pass/warn only, 1 = at least one FAIL

Manual test matrix:

Scenario Expected
Python 3.10 / 3.11 / 3.12 PASS version check
Python 3.9 FAIL version check, exit 1
API key set (any provider) PASS API key check
CUSTOM_ANTHROPIC_API_KEY set PASS API key check
LLM_API_KEY set (legacy) PASS API key check
SKIP_SETUP_WIZARD=1 PASS API key check
No API key WARN, exit 0
rpy2 installed, R absent WARN R runtime
rpy2 not installed R check silently skipped
No API key, run pantheon doctor shows diagnostics, does NOT open setup wizard

Copy link
Copy Markdown

@JiwaniZakir JiwaniZakir left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The _check_api_keys docstring explicitly says it "replicates" the four-step detection from check_and_run_setup(), but the duplication is a maintenance hazard — if the wizard's detection logic or the contents of PROVIDER_API_KEYS/CUSTOM_ENDPOINT_ENVS change, doctor.py will silently diverge and report a different result than the wizard would. The detection logic should be extracted into a shared utility (e.g., pantheon/utils/api_key_check.py) that both check_and_run_setup and _check_api_keys call, making synchronization structural rather than a comment-level promise.

Additionally, _check_r_runtime has a different return type (Optional[CheckResult]) compared to every other check function (CheckResult), forcing special-case handling in _collect_checks. A more uniform approach would be to have all check functions return CheckResult unconditionally and introduce a "SKIP" status (or a skipped: bool field) — this also makes it easier to add future optional checks without changing the collector's logic each time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants