Skip to content

doctor: ACP installation probe (silent on success, fail+issue on missing)#53

Merged
PowerCreek merged 1 commit into
mainfrom
doctor-acp-installation-probe
May 23, 2026
Merged

doctor: ACP installation probe (silent on success, fail+issue on missing)#53
PowerCreek merged 1 commit into
mainfrom
doctor-acp-installation-probe

Conversation

@PowerCreek

Copy link
Copy Markdown

Summary

ACP (Agent-Client Protocol) is the IDE integration surface — hermes acp is invoked by Zed / Cursor / JetBrains via the ACP Registry, gated on the optional agent-client-protocol dependency. Operators who don't use ACP don't need a doctor row. Operators who DO use ACP only learn the package is missing when their IDE breaks; hermes doctor is the natural place to surface the fix.

What's surfaced

State Doctor row
Both acp + acp_adapter.server importable (silent)
ImportError check_fail("agent-client-protocol not importable", ...) + _fail_and_issue adds pip install agent-client-protocol to the issues list
Non-ImportError exception (e.g. downstream SyntaxError, ValueError during module init) check_warn (no issue — fix is less clear-cut)

Mirrors the cron-when-jobs.json-absent pattern: silent when irrelevant, loud and actionable when broken.

Test plan

  • 4 new tests in tests/hermes_cli/test_doctor_acp_probe.py:
    • Silent path with both modules stubbed importable
    • ImportError → _fail_and_issue with pip-install hint
    • acp_adapter.server import failure also fails (either is fatal)
    • Non-ImportError (ValueError during attribute access) → check_warn, no issue
  • pytest tests/hermes_cli/test_doctor_acp_probe.py tests/hermes_cli/test_doctor.py → 74 passed.

Filed by hermes-maintainer (PowerCreek).

…ing)

ACP (Agent-Client Protocol) is the IDE integration surface — `hermes
acp` is invoked by Zed / Cursor / JetBrains via the ACP Registry,
gated on the `agent-client-protocol` optional dependency.
Operators who don't use ACP don't need a doctor row. Operators
who DO use ACP only learn the package is missing when their IDE
breaks; `hermes doctor` is the natural place to surface the fix.

New `_check_acp_installation()`:

  - Silent when `import acp` + `from acp_adapter.server import
    HermesACPAgent` both succeed.
  - check_fail + issue (with `pip install agent-client-protocol`
    hint) on ImportError — the runtime would break either way,
    so this is actionable.
  - check_warn (no issue) on non-ImportError module-init exceptions
    (downstream SyntaxError / runtime ValueError in module load);
    the fix is less clear-cut, so we surface but don't add to the
    auto-fixable issues list.

Tests:
  - silent path with both modules stubbed importable
  - ImportError emits fail + issue with the pip-install hint
  - acp_adapter.server import failure also fails (either is fatal)
  - Non-ImportError (e.g. ValueError during module attribute access)
    surfaces as warn, not fail, not issue

The probe mirrors the cron-when-jobs.json-absent pattern: silent
when irrelevant, loud and actionable when broken. Operators who
don't use ACP see zero noise.
@PowerCreek PowerCreek merged commit 30fd6c6 into main May 23, 2026
@PowerCreek PowerCreek deleted the doctor-acp-installation-probe branch May 23, 2026 03:22
PowerCreek added a commit that referenced this pull request May 25, 2026
…env vars (#95)

Surfaces typos in either env var at ``hermes doctor`` time instead
of letting the worker silently fall through to ``auto`` mid-session.
Closes a follow-up gap from #70 — the env var I shipped in PR #91
had no boot-time validation, so a typo like ``devagentic-locol``
would silently fail downstream in resolve_requested_provider's
auto-detect fallthrough.

## Behavior

- **Silent** when neither env var is set — most operators don't pin
  the provider via env, no row each run (silent-when-irrelevant
  pattern from the #88/#53 doctor probes).
- **check_ok** when the env var matches a known provider name —
  surfaces deployment pins so operators can confirm they're live.
- **check_warn** with a sample of valid names when the env var
  doesn't match. Diagnosed-not-blocked: a custom provider name set
  outside the registry's view is still legal, just noisy.

Known-provider set is the union of:
- ``providers.list_providers()`` (plugin-registered, e.g.
  devagentic-local)
- ``hermes_cli.auth.PROVIDER_REGISTRY`` (built-in)
- standard aliases (``openrouter`` / ``custom`` / ``auto`` /
  ``anthropic`` / ``openai``)

Both env vars are checked independently — a partial mismatch (one
valid, one typo) surfaces precisely.

## Tests

- 8 new tests in tests/hermes_cli/test_doctor_provider_env_probe.py:
  silent-when-unset / silent-when-empty / known-name-ok / typo-warn-
  with-sample / both-env-vars-checked-independently / case-insens
  / plugin-registered-name-known / providers-import-failure-doesnt-
  crash.
- 96 total green across affected suites (probe + doctor + acp probe
  + resolver). No regression.

## Composition

- Pairs with PR #91 (HERMES_DEFAULT_PROVIDER env var) — closes the
  validation gap I left in that ship.
- Follows the silent-when-irrelevant probe pattern from PR #53
  (_check_acp_installation) and the diagnostic-loudness wave that
  established it.
PowerCreek added a commit that referenced this pull request May 25, 2026
#96)

Operators who narrow the tool surface via HERMES_TOOLS_SUBSET can
now confirm at ``hermes doctor`` time exactly which tools the
filter parsed to. Catches two failure modes that previously
required a separate ``hermes mcp list`` diff:

1. Operator typoed a tool name → still in the parsed list (no
   cross-check), but the diff against ``hermes mcp list`` is now
   trivial.
2. Operator forgot the ``mcp_<server>_<tool>`` prefix for MCP
   tools → no entry uses ``mcp_`` prefix but entries look
   structured → info reminder fires.

Silent when env var is unset/empty (silent-when-irrelevant pattern
from the #88/#53/#54 doctor probes). When set, surfaces:

  * check_ok with the count + a sample of names (first 6, then
    ``+N more`` suffix to keep the row readable);
  * check_info reminder when zero entries use the mcp_ prefix but
    some look structured (the most common parse-correctly-but-
    filter-nothing failure mode).

Cross-check against the live MCP registry was considered + rejected
for this PR — it would require spinning up ``create_mcp_server()``
at probe time. Operators can ``hermes mcp list`` separately if they
want the full diff. Filing as opportunistic follow-up if demand
shows up.

## Tests

- 8 new tests in tests/hermes_cli/test_doctor_tools_subset_probe.py:
  silent-when-unset / silent-when-empty / silent-when-whitespace /
  count-and-sample-shown / long-list-truncated / mcp-prefix-reminder
  / no-reminder-when-mcp-present / no-reminder-when-only-simple-bare-
  names.
- 30 total green across affected suites (probe + provider-env-probe
  + mcp_subset_filter). No regression.
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.

1 participant