Conversation
|
Update: I've identified a different root cause in my case. All 6 profiles (default, coding, knowledge, manager, siper, search) share the same HERMES_HOME (~/.hermes) because none of them have When the default profile's gateway starts with --replace, it reads the shared PID file and finds the PID of another profile's gateway (e.g., coding). It attempts to kill that process. The other profile's gateway doesn't respond expectedly (because it's managed by the profile system, not by --replace), so the new default gateway gives up and returns False → exit 1. systemd sees exit 1 and restarts → loop. The exit-code fix in this PR would help, but the deeper issue is that --replace should not attempt to replace processes from different profiles. A simple fix is to check the profile name stored in the PID file and only replace if it matches. Workaround that resolved it: stop and disable the default systemd service ( |
|
Thanks @gavin-jack - I think this comment was meant for #21555 (the gateway --replace / launchd exit-code PR). Worth re-posting there so the deeper fix idea (profile-aware PID file check) doesn't get lost. The PRs are right next to each other so easy to mix up. |
|
Thanks for the focused configuration-based approach. The underlying need remains real for first-class providers, but the current implementation needs rework against the newer provider-resolution path. Problems
Suggested changes
This is an automated hermes-sweeper review. |
Addresses @teknium1 hermes-sweeper review on NousResearch#21554. - Resolve first-class / built-in provider extra_body overrides once during agent setup into request_overrides (transport already merges those). - Canonicalize aliases: providers.dashscope.extra_body applies when the session provider is alibaba (and vice versa). Exact session key wins over canonical/alias siblings. - Explicit schema: URL-bearing providers.* entries stay named custom endpoints; partial entries (extra_body only, no api/base_url/url) are the built-in override contract. - Preserve existing custom-provider merge + caller precedence. - Docs + alias/precedence/custom-path tests.
5d1bd7f to
16e7f22
Compare
# Conflicts: # website/docs/integrations/providers.md
|
Closing this PR per author request. Thanks! |
What does this PR do?
Closes #8160.
OpenAI-compatible endpoints regularly take non-standard request fields (
enable_thinking,top_k,repetition_penalty, vendor-specific options). Hardcoding them per-provider inchat_completions.pydoesn't scale; users want a way to pin these once inconfig.yaml.Concrete use case from the issue: DashScope-hosted Qwen3 models default to reasoning mode (~3.5s overhead vs ~0.9s on plain calls). DashScope accepts
enable_thinking: falseas an OpenAI-compatextra_bodyfield to disable it cleanly. Today there's no way to pin that without editing Hermes source.This PR adds:
The block is read at request build time and merged into the request's
extra_bodyafter profile defaults + caller-levelextra_body_additionsbut before per-callrequest_overrides, so:request_overrides.extra_bodystill wins (treated as the user's explicit per-call instruction, more specific than standing config).Related Issue
Closes #8160.
Type of Change
Changes Made
agent/transports/chat_completions.py—_load_provider_extra_body_override(provider_name)reads~/.hermes/config.yaml→providers.<name>.extra_body. Returns{}on any failure (missing config, missing key, non-dict value,load_configexception) so callers can always merge safely.extra_bodyassembly paths insidebuild_kwargs: the legacy path (no profile) and the profile-based path. Each path buildsextra_bodyfrom different sources, so the helper is invoked in each at the right precedence point.tests/agent/transports/test_chat_completions_provider_extra_body.py(new) — 12 tests:_load_provider_extra_body_overridecovering the failure modes (blank name, noproviderssection, missing entry, missingextra_body, non-dict shape,load_configexception, and the happy-path "returns a copy, not the original" guarantee).build_kwargs— the DashScope use case, config-vs-additions precedence, no-emission when nothing is configured, merging with existing profile-drivenextra_body(Nous tags), and graceful behavior when the configured provider name doesn't match the call.website/docs/user-guide/configuration.md— new "Provider extra_body" subsection documenting the schema, precedence, and the limitation noted below.How to Test
End-to-end (the DashScope case):
~/.hermes/config.yaml:hermes chat --provider alibaba-coding-planagainst a thinking-mode Qwen3 model.extra_bodyshould containenable_thinking: false.Checklist
Code
feat(transport):)extra_bodyconfig overrideDocumentation & Housekeeping
website/docs/user-guide/configuration.mdcli-config.yaml.examplechanges (the new key is documented inconfiguration.mdand is purely additive)Notes for reviewers
get_auxiliary_extra_body()inagent/auxiliary_client.py) is intentionally not changed. It's a separate code path with its own provider-detection mechanics (no current global tracking of the auxiliary provider name) and warrants a follow-up. The primary win for the DashScope use case — long agent turns wasting ~3s per call on thinking mode — lives on the mainchat_completionspath this PR covers. Mentioned in the docs as a known limitation.anthropic_messages,codex_responses) are not affected — they don't useextra_bodyin the same shape, so a future PR would need a parallel mechanism for them.profile < additions < config < request_overrides— treats the YAML config as the user's standing intent that beats code-defaultextra_body_additions, while still letting an explicit per-call CLI / APIrequest_overrideswin because that's even more specific. Tests pin the precedence so a future refactor can't accidentally flip it.