Skip to content

fix(hermes): wire config.yaml through to AIAgent + fix client is_closed false positive#809

Merged
saulmc merged 5 commits intodevfrom
fix/hermes-config-passthrough
Apr 1, 2026
Merged

fix(hermes): wire config.yaml through to AIAgent + fix client is_closed false positive#809
saulmc merged 5 commits intodevfrom
fix/hermes-config-passthrough

Conversation

@saulmc
Copy link
Copy Markdown
Member

@saulmc saulmc commented Apr 1, 2026

Summary

  • Config passthrough: AgentRunner was creating AIAgent without passing provider_routing, fallback_model, or reasoning_config from config.yaml. The upstream gateway and CLI both read these sections and pass them through — we were silently ignoring them. This meant provider_routing.only was dead config and OpenRouter could route to any provider.
  • Client is_closed fix: Monkey-patches _is_openai_client_closed to fix an upstream bug (reported at [Bug]: _is_openai_client_closed false positive — openai SDK is_closed is a method, not a property NousResearch/hermes-agent#4377) where the openai SDK's is_closed method is checked via bool(getattr(client, "is_closed", False)). Since is_closed is a method (not a property), the bound method object is always truthy — every API call falsely detects the shared client as closed and recreates it, adding ~2 unnecessary TCP+TLS round trips per call.

Why

Investigating slow API call latency. Two root causes found:

  1. Provider routing config was never reaching OpenRouter, so it could route to any (potentially slow) provider
  2. Every API call was churning through 2 extra OpenAI client creations + TCP+TLS handshakes due to a false-positive closed-client detection

🤖 Generated with Claude Code

Note

Wire config.yaml into AIAgent and fix is_closed false positive in AgentRunner

  • AgentRunner._create_agent now loads HERMES_HOME/config.yaml and passes provider routing options (only/ignore/order/sort/require_parameters/data_collection), fallback model, and reasoning config into the AIAgent constructor.
  • Fixes a false positive in the OpenAI client closed-status check by overriding _is_openai_client_closed to handle cases where is_closed is a bound method (not a bool), inspect the underlying http_client._client.is_closed, and correctly handle unittest.mock.Mock instances.
  • Changes the hermes-agent install extras from [all] to [cron,mcp,pty,homeassistant] in both the Dockerfile and install-deps.sh, removing unintended optional dependencies from the image.
  • honcho_session_key is no longer passed to AIAgent.

Macroscope summarized 73d6c8a.

@macroscopeapp
Copy link
Copy Markdown
Contributor

macroscopeapp bot commented Apr 1, 2026

Approvability

Verdict: Needs human review

This PR wires provider_routing, fallback_model, and reasoning_config from config.yaml through to AIAgent, enabling configuration-driven provider selection that wasn't previously active. Additionally, it changes Docker dependency installation from [all] to explicit extras. These changes affect runtime behavior and warrant human review.

You can customize Macroscope's approvability policy. Learn more.

saulmc and others added 2 commits March 31, 2026 17:36
…ed false positive

AgentRunner bypassed several config.yaml sections that the upstream
Hermes gateway/cli properly pass to AIAgent:

- provider_routing (only, ignore, order, sort, require_parameters, data_collection)
- fallback_providers / fallback_model
- agent.reasoning_effort

This meant our provider_routing.only restriction was dead config —
OpenRouter could route to any provider.

Also monkey-patches _is_openai_client_closed to fix an upstream bug
where openai SDK's is_closed (a method) is checked via
bool(getattr(client, "is_closed", False)) — the bound method is always
truthy, so every API call falsely detects the shared client as closed
and recreates it, adding ~2 unnecessary TCP+TLS round trips per call.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ith upstream PR

- Use (cfg.get("agent") or {}) to handle null values so the
  HERMES_REASONING_EFFORT env var fallback still works
- Align monkey-patch with the version submitted upstream
  (NousResearch/hermes-agent#4378)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@saulmc saulmc force-pushed the fix/hermes-config-passthrough branch 2 times, most recently from e979c19 to 760c713 Compare April 1, 2026 00:43
.[all] installs every optional dependency (Matrix, Telegram, Discord,
Slack, SMS, DingTalk, voice, Modal, etc.) — most of which we don't
use. The matrix extra in particular requires python-olm which needs
cmake and C++ compilation, breaking local dev on macOS.

Install only the extras we actually use: cron, honcho, mcp, pty.
Applied to both Dockerfile and install-deps.sh.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
We don't use honcho and just removed the dependency.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
staticmethod descriptor assigned to an instance attribute isn't
callable — would raise TypeError at runtime.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@saulmc saulmc merged commit 1fc2e57 into dev Apr 1, 2026
19 checks passed
@saulmc saulmc deleted the fix/hermes-config-passthrough branch April 1, 2026 01:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

runtime/hermes Hermes runtime runtime Runtime changes

1 participant