From 8ab8bc2f035ac4ed8b3b43ed2940ba3dc4589cc9 Mon Sep 17 00:00:00 2001 From: Guillaume Meyer Date: Sat, 16 May 2026 23:04:42 +0000 Subject: [PATCH] =?UTF-8?q?fix(plugins):=20remove=20unreachable=20hermes?= =?UTF-8?q?=20tools=20=E2=86=92=20Langfuse=20path?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The langfuse plugin is hooks-only (no toolsets), so it never appears in `hermes tools` — that menu iterates `_get_effective_configurable_toolsets()` (= `CONFIGURABLE_TOOLSETS` + plugin-registered toolsets), and "langfuse" is in neither. The `TOOL_CATEGORIES["langfuse"]` setup wizard (with its `post_setup: "langfuse"` hook that pip-installs the SDK and writes `plugins.enabled`) was reachable only when a toolset key "langfuse" got enabled, which can't happen — so it's been dead code, and the docs that promised "Setup (interactive): hermes tools → Langfuse Observability" were silently broken. Right home for that wizard is `hermes plugins` (e.g. auto-running a plugin's post-setup hook on enable), which is a generic plugin-setup mechanism worth designing properly rather than shoehorning langfuse back into `hermes tools`. Until that exists, point users at the working manual flow. Code: - Delete `TOOL_CATEGORIES["langfuse"]` (24 lines) — unreachable. - Delete the `post_setup_key == "langfuse"` branch in `_run_post_setup` (29 lines) — only caller was the deleted TOOL_CATEGORIES entry. Docs / comments (point at the manual flow + interactive `hermes plugins`): - `plugins/observability/langfuse/README.md`: collapse the two-option setup section to the single working flow. - `plugins/observability/langfuse/plugin.yaml`: update `description`. - `plugins/observability/langfuse/__init__.py`: update module docstring. - `hermes_cli/config.py`: update inline comment above the LANGFUSE_* env-var allow-list. - `website/docs/user-guide/features/built-in-plugins.md`: collapse "Setup (interactive)" + "Setup (manual)" into one accurate block. - `website/docs/reference/environment-variables.md`: update the cross-reference in the Langfuse env-vars section. Co-Authored-By: Claude Opus 4.7 (1M context) --- hermes_cli/config.py | 3 +- hermes_cli/tools_config.py | 55 ------------------- plugins/observability/langfuse/README.md | 10 +--- plugins/observability/langfuse/__init__.py | 8 +-- plugins/observability/langfuse/plugin.yaml | 2 +- .../docs/reference/environment-variables.md | 2 +- .../user-guide/features/built-in-plugins.md | 12 +--- 7 files changed, 12 insertions(+), 80 deletions(-) diff --git a/hermes_cli/config.py b/hermes_cli/config.py index 81706d1edb4..c1f68e1c88c 100644 --- a/hermes_cli/config.py +++ b/hermes_cli/config.py @@ -134,8 +134,7 @@ _EXTRA_ENV_KEYS = frozenset({ "MATRIX_RECOVERY_KEY", # Langfuse observability plugin — optional tuning keys + standard SDK vars. # Activation is via plugins.enabled (opt-in through `hermes plugins enable - # observability/langfuse` or `hermes tools → Langfuse`); credentials gate - # the plugin at runtime. + # observability/langfuse`); credentials gate the plugin at runtime. "HERMES_LANGFUSE_ENV", "HERMES_LANGFUSE_RELEASE", "HERMES_LANGFUSE_SAMPLE_RATE", diff --git a/hermes_cli/tools_config.py b/hermes_cli/tools_config.py index 3afaa5cc7c9..06ba32bea9e 100644 --- a/hermes_cli/tools_config.py +++ b/hermes_cli/tools_config.py @@ -461,31 +461,6 @@ TOOL_CATEGORIES = { }, ], }, - "langfuse": { - "name": "Langfuse Observability", - "icon": "📊", - "providers": [ - { - "name": "Langfuse Cloud", - "tag": "Hosted Langfuse (cloud.langfuse.com)", - "env_vars": [ - {"key": "HERMES_LANGFUSE_PUBLIC_KEY", "prompt": "Langfuse public key (pk-lf-...)", "url": "https://cloud.langfuse.com"}, - {"key": "HERMES_LANGFUSE_SECRET_KEY", "prompt": "Langfuse secret key (sk-lf-...)", "url": "https://cloud.langfuse.com"}, - ], - "post_setup": "langfuse", - }, - { - "name": "Langfuse Self-Hosted", - "tag": "Self-hosted Langfuse instance", - "env_vars": [ - {"key": "HERMES_LANGFUSE_PUBLIC_KEY", "prompt": "Langfuse public key (pk-lf-...)"}, - {"key": "HERMES_LANGFUSE_SECRET_KEY", "prompt": "Langfuse secret key (sk-lf-...)"}, - {"key": "HERMES_LANGFUSE_BASE_URL", "prompt": "Langfuse server URL (e.g. http://localhost:3000)", "default": "http://localhost:3000"}, - ], - "post_setup": "langfuse", - }, - ], - }, } # Simple env-var requirements for toolsets NOT in TOOL_CATEGORIES. @@ -947,36 +922,6 @@ def _run_post_setup(post_setup_key: str): _print_warning(f" Spotify login failed: {exc}") _print_info(" Run manually: hermes auth spotify") - elif post_setup_key == "langfuse": - # Install the langfuse SDK. - try: - __import__("langfuse") - _print_success(" langfuse SDK already installed") - except ImportError: - _print_info(" Installing langfuse SDK...") - result = _pip_install(["langfuse", "--quiet"], timeout=120) - if result.returncode == 0: - _print_success(" langfuse SDK installed") - else: - _print_warning(" langfuse SDK install failed — run manually: uv pip install langfuse") - # Opt the bundled observability/langfuse plugin into plugins.enabled. - # The plugin ships in the repo but doesn't load until the user enables - # it (standalone plugins are opt-in). - try: - from hermes_cli.plugins_cmd import _get_enabled_set, _save_enabled_set - enabled = _get_enabled_set() - if "observability/langfuse" in enabled or "langfuse" in enabled: - _print_success(" Plugin observability/langfuse already enabled") - else: - enabled.add("observability/langfuse") - _save_enabled_set(enabled) - _print_success(" Plugin observability/langfuse enabled") - except Exception as exc: - _print_warning(f" Could not enable plugin automatically: {exc}") - _print_info(" Run manually: hermes plugins enable observability/langfuse") - _print_info(" Restart Hermes for tracing to take effect.") - _print_info(" Verify: hermes plugins list") - elif post_setup_key == "xai_grok": # Shared credential bootstrap for any picker entry that talks to xAI # (TTS, Video Gen, future Image Gen, etc.). Accepts either a diff --git a/plugins/observability/langfuse/README.md b/plugins/observability/langfuse/README.md index 864735d9688..97f4757e5a8 100644 --- a/plugins/observability/langfuse/README.md +++ b/plugins/observability/langfuse/README.md @@ -5,20 +5,16 @@ you explicitly enable it. ## Enable -Pick one: - ```bash -# Interactive: walks you through credentials + SDK install + enable -hermes tools # → Langfuse Observability - -# Manual pip install langfuse hermes plugins enable observability/langfuse ``` +Or check the box in the interactive `hermes plugins` UI. + ## Required credentials -Set these in `~/.hermes/.env` (or via `hermes tools`): +Set these in `~/.hermes/.env`: ```bash HERMES_LANGFUSE_PUBLIC_KEY=pk-lf-... diff --git a/plugins/observability/langfuse/__init__.py b/plugins/observability/langfuse/__init__.py index 8516030fb01..a99a8eb9279 100644 --- a/plugins/observability/langfuse/__init__.py +++ b/plugins/observability/langfuse/__init__.py @@ -4,11 +4,11 @@ Traces Hermes conversations, LLM calls, and tool usage to Langfuse. Activation is handled by the Hermes plugin system — standalone plugins only load when listed in ``plugins.enabled`` (via ``hermes plugins enable -observability/langfuse`` or ``hermes tools → Langfuse Observability``). At -runtime the plugin also requires the ``langfuse`` SDK and credentials; if -either is missing the hooks are inert. +observability/langfuse``, or by checking the box in the interactive +``hermes plugins`` UI). At runtime the plugin also requires the +``langfuse`` SDK and credentials; if either is missing the hooks are inert. -Required env vars (set via ``hermes tools`` or ~/.hermes/.env): +Required env vars (set in ~/.hermes/.env): HERMES_LANGFUSE_PUBLIC_KEY - Langfuse project public key (pk-lf-...) HERMES_LANGFUSE_SECRET_KEY - Langfuse project secret key (sk-lf-...) HERMES_LANGFUSE_BASE_URL - Langfuse server URL (default: https://cloud.langfuse.com) diff --git a/plugins/observability/langfuse/plugin.yaml b/plugins/observability/langfuse/plugin.yaml index 18f1c6245d3..708264c8a96 100644 --- a/plugins/observability/langfuse/plugin.yaml +++ b/plugins/observability/langfuse/plugin.yaml @@ -1,6 +1,6 @@ name: langfuse version: "1.0.0" -description: "Optional Langfuse observability for Hermes — traces conversations, LLM calls, and tool usage. Opt-in via `hermes plugins enable observability/langfuse` or `hermes tools → Langfuse Observability`." +description: "Optional Langfuse observability for Hermes — traces conversations, LLM calls, and tool usage. Opt-in via `hermes plugins enable observability/langfuse` (or check the box in `hermes plugins`)." author: NousResearch requires_env: - HERMES_LANGFUSE_PUBLIC_KEY diff --git a/website/docs/reference/environment-variables.md b/website/docs/reference/environment-variables.md index 56fe8a13715..4866ac083ac 100644 --- a/website/docs/reference/environment-variables.md +++ b/website/docs/reference/environment-variables.md @@ -156,7 +156,7 @@ For native Anthropic auth, Hermes prefers Claude Code's own credential files whe ### Langfuse Observability -Environment variables for the bundled [`observability/langfuse`](/docs/user-guide/features/built-in-plugins#observabilitylangfuse) plugin. Set these with `hermes tools → Langfuse Observability` or manually in `~/.hermes/.env`. The plugin must also be enabled (`hermes plugins enable observability/langfuse`) before any of these take effect. +Environment variables for the bundled [`observability/langfuse`](/docs/user-guide/features/built-in-plugins#observabilitylangfuse) plugin. Set these in `~/.hermes/.env`. The plugin must also be enabled (`hermes plugins enable observability/langfuse`, or check the box in `hermes plugins`) before any of these take effect. | Variable | Description | |----------|-------------| diff --git a/website/docs/user-guide/features/built-in-plugins.md b/website/docs/user-guide/features/built-in-plugins.md index aa346308913..8ac3322c68b 100644 --- a/website/docs/user-guide/features/built-in-plugins.md +++ b/website/docs/user-guide/features/built-in-plugins.md @@ -121,22 +121,14 @@ Traces Hermes turns, LLM calls, and tool invocations to [Langfuse](https://langf The plugin is fail-open: no SDK installed, no credentials, or a transient Langfuse error — all turn into a silent no-op in the hook. The agent loop is never impacted. -**Setup (interactive — recommended):** - -```bash -hermes tools # → Langfuse Observability → Cloud or Self-Hosted -``` - -The wizard collects your keys, `pip install`s the `langfuse` SDK, and adds `observability/langfuse` to `plugins.enabled` for you. Restart Hermes and the next turn ships a trace. - -**Setup (manual):** +**Setup:** ```bash pip install langfuse hermes plugins enable observability/langfuse ``` -Then put the credentials in `~/.hermes/.env`: +Or check the box in the interactive `hermes plugins` UI. Then put the credentials in `~/.hermes/.env`: ```bash HERMES_LANGFUSE_PUBLIC_KEY=pk-lf-...