hermes - ✅(Solved) Fix Bug: auxiliary tasks fail with HTTP 404 when using anthropic_messages custom endpoint — URL rewrite strips /anthropic/ path [5 pull requests, 2 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
NousResearch/hermes-agent#17086Fetched 2026-04-29 06:37:18
View on GitHub
Comments
2
Participants
2
Timeline
15
Reactions
0
Author
Timeline (top)
cross-referenced ×6labeled ×6commented ×2referenced ×1

When a custom auxiliary endpoint is configured with api_mode: anthropic_messages, all auxiliary tasks (title_generation, compression, session_search, vision, web_extract, etc.) silently fail with HTTP 404.


Root Cause

In resolve_provider_client(), the custom branch unconditionally passes explicit_base_url through _to_openai_base_url(), which rewrites URLs ending in /anthropic or /anthropic/ to /v1:

# Line ~1834
custom_base = _to_openai_base_url(explicit_base_url).strip()

So a proxy base URL like http://localhost:6655/anthropic/ becomes http://localhost:6655/v1, and all requests land on POST /v1/chat/completions — a route that doesn't exist on an Anthropic-native proxy.

This is inconsistent with the identical api_mode == "anthropic_messages" guard that already exists in:

  • _try_custom_endpoint() (line ~1180)
  • Named provider branches

Fix Action

Fix

Add the same api_mode == "anthropic_messages" guard to the custom + explicit_base_url branch in resolve_provider_client():

if api_mode == "anthropic_messages":
    from agent.anthropic_adapter import build_anthropic_client
    real_client = build_anthropic_client(custom_key, explicit_base_stripped)
    return AnthropicAuxiliaryClient(
        real_client, final_model, custom_key, explicit_base_stripped, is_oauth=False
    ), final_model
# else: fall through to OpenAI path with URL rewrite as before
custom_base = _to_openai_base_url(explicit_base_stripped)

PR fix notes

PR #1: fix: resolve 7 identified issues [automated]

Description (problem / solution / changelog)

Resumo

Este PR corrige 7 issues identificados no repositório NousResearch/hermes-agent.


Issues Corrigidos

1. #17086 - custom endpoint com api_mode=anthropic_messages falhava com 404

Arquivo: agent/auxiliary_client.py Problema: Quando provider=custom com api_mode=anthropic_messages e base_url terminando em /anthropic, a funcao _resolve_provider_client() convertia a URL para o formato /v1/messages, causando 404 em provedores Anthropic-compatíveis de terceiros. Correcao: Mantem o path /anthropic quando api_mode=anthropic_messages e o base_url ja termina em /anthropic.


2. #17076 - kimi-coding vision quebrado (404 em analise de imagem)

Arquivo: agent/auxiliary_client.py Problema: kimi-coding nao estava listado em _PROVIDER_VISION_MODELS, entao auxiliary.vision.provider: auto nao conseguia detectar o modelo de visao disponivel para Kimi. Correcao: Adicionado kimi-coding e kimi-coding-cn ao mapa de modelos de visao.


3. #17080 - hermes profile create --clone copiava credenciais exclusivas de plataforma

Arquivo: hermes_cli/profiles.py Problema: O clone de perfil copiava TELEGRAM_BOT_TOKEN, DISCORD_BOT_TOKEN, WEIXIN_TOKEN verbatim. Quando dois perfis iniciam simultaneamente com o mesmo token, o adaptador de plataforma falha durante a aquisicao de lock. Correcao: Define _EXCLUSIVE_PLATFORM_KEYS e _EXCLUSIVE_PLATFORM_CONFIG_PATHS. Credenciais exclusivas sao comentadas em .env e entradas de plataforma sao enabled: false em config.yaml apos clone.


4. #17054 - Slack manifest rejeitava nomes com underscore

Arquivo: hermes_cli/commands.py Problema: _sanitize_slack_name() convertia nomes de comandos como _reload_mcp para Slack mas nao removia o prefixo underscore, causando rejeicao do manifest. Correcao: Adicionada verificacao para pular nomes que começam com underscore antes de adicionar a lista de slash commands.


5. #17057 - custom Kimi-compatible endpoint falhava apos tool call com thinking habilitado

Arquivo: run_agent.py Problema: _needs_kimi_tool_reasoning() só verificava hostnames oficiais (api.kimi.com, moonshot.ai, moonshot.cn). Endpoints Kimi-compatíveis customizados nao eram detectados. Correcao: Ampliada a verificacao para detectar endpoints customizados pela familia do modelo (nome contem "kimi" ou "k2") alem do hostname.


6. #17049 - UnicodeDecodeError no scan de processos Windows (wmic)

Arquivo: hermes_cli/gateway.py Problema: wmic emitia saida em encoding local do Windows (cp1252/utf-16), causando UnicodeDecodeError e AttributeError durante parsing. Correcao: O parsing agora usa errors=ignore no decode, tratando bytes invalidos como despreziveis.


7. #17052 - stale reasoning reutilizado quando turn atual nao tem reasoning_content

Arquivo: run_agent.py Problema: Mensagens de assistant com tool_calls e reasoning_content eram reutilizadas indevidamente em turns que nao tinham reasoning_content, causando confabulacoes em provedores como Qwen3.6:27b via Ollama. Correcao: O loop de replay agora detecta quando a mensagem atual e um assistant com tool_calls mas sem reasoning_content, e limpa msg[reasoning_content] e msg[reasoning] para evitar propagacao de estado de reasoning de turns anteriores.


Arquivos Modificados

  • agent/auxiliary_client.py - #17086, #17076
  • hermes_cli/profiles.py - #17080
  • hermes_cli/commands.py - #17054
  • run_agent.py - #17057, #17052
  • hermes_cli/gateway.py - #17049

Notas

  • Este PR contem 8 commits (7 issues + 1 fix de seguranca do upstream relacionado a redaction de secrets)
  • Todos os commits foram feitos na branch fix-7-issues-clean
  • Nenhum push intermediario foi feito - push unico ao final
  • Commits do upstream incluidos para manter o historico completo: #16843, #17041, #17039

Changed files

  • .gitignore (modified, +1/-0)
  • Dockerfile (modified, +6/-2)
  • acp_adapter/entry.py (modified, +11/-0)
  • acp_adapter/server.py (modified, +28/-1)
  • agent/anthropic_adapter.py (modified, +134/-74)
  • agent/auxiliary_client.py (modified, +325/-53)
  • agent/bedrock_adapter.py (modified, +41/-3)
  • agent/context_compressor.py (modified, +113/-5)
  • agent/credential_pool.py (modified, +82/-4)
  • agent/credential_sources.py (modified, +0/-1)
  • agent/error_classifier.py (modified, +32/-0)
  • agent/gemini_cloudcode_adapter.py (modified, +0/-2)
  • agent/gemini_schema.py (modified, +1/-1)
  • agent/google_code_assist.py (modified, +0/-1)
  • agent/google_oauth.py (modified, +3/-3)
  • agent/image_routing.py (added, +236/-0)
  • agent/memory_manager.py (modified, +113/-5)
  • agent/model_metadata.py (modified, +56/-21)
  • agent/nous_rate_guard.py (modified, +144/-1)
  • agent/onboarding.py (added, +191/-0)
  • agent/prompt_builder.py (modified, +38/-0)
  • agent/redact.py (modified, +13/-6)
  • agent/shell_hooks.py (modified, +7/-2)
  • agent/skill_commands.py (modified, +2/-2)
  • agent/title_generator.py (modified, +39/-5)
  • agent/transports/anthropic.py (modified, +1/-7)
  • agent/transports/chat_completions.py (modified, +74/-0)
  • agent/transports/codex.py (modified, +1/-3)
  • cli-config.yaml.example (modified, +28/-8)
  • cli.py (modified, +522/-195)
  • cron/jobs.py (modified, +34/-5)
  • cron/scheduler.py (modified, +39/-5)
  • docker/entrypoint.sh (modified, +9/-7)
  • flake.nix (modified, +1/-0)
  • gateway/channel_directory.py (modified, +67/-14)
  • gateway/config.py (modified, +84/-3)
  • gateway/display_config.py (modified, +3/-1)
  • gateway/mirror.py (modified, +57/-11)
  • gateway/pairing.py (modified, +2/-1)
  • gateway/platforms/__init__.py (modified, +2/-0)
  • gateway/platforms/base.py (modified, +233/-16)
  • gateway/platforms/discord.py (modified, +18/-24)
  • gateway/platforms/email.py (modified, +3/-0)
  • gateway/platforms/feishu_comment.py (modified, +0/-1)
  • gateway/platforms/helpers.py (modified, +11/-2)
  • gateway/platforms/matrix.py (modified, +493/-47)
  • gateway/platforms/mattermost.py (modified, +0/-1)
  • gateway/platforms/qqbot/adapter.py (modified, +2/-7)
  • gateway/platforms/slack.py (modified, +753/-70)
  • gateway/platforms/telegram.py (modified, +138/-14)
  • gateway/platforms/weixin.py (modified, +26/-3)
  • gateway/platforms/yuanbao.py (added, +4754/-0)
  • gateway/platforms/yuanbao_media.py (added, +645/-0)
  • gateway/platforms/yuanbao_proto.py (added, +1209/-0)
  • gateway/platforms/yuanbao_sticker.py (added, +558/-0)
  • gateway/run.py (modified, +1143/-283)
  • gateway/runtime_footer.py (added, +150/-0)
  • gateway/session.py (modified, +16/-21)
  • gateway/stream_consumer.py (modified, +110/-0)
  • gateway/whatsapp_identity.py (modified, +21/-1)
  • hermes_cli/auth.py (modified, +40/-4)
  • hermes_cli/azure_detect.py (modified, +1/-1)
  • hermes_cli/backup.py (modified, +272/-1)
  • hermes_cli/banner.py (modified, +0/-1)
  • hermes_cli/claw.py (modified, +67/-6)
  • hermes_cli/commands.py (modified, +119/-5)
  • hermes_cli/config.py (modified, +322/-29)
  • hermes_cli/debug.py (modified, +13/-7)
  • hermes_cli/dingtalk_auth.py (modified, +0/-1)
  • hermes_cli/doctor.py (modified, +11/-1)
  • hermes_cli/env_loader.py (modified, +2/-1)
  • hermes_cli/fallback_cmd.py (added, +361/-0)
  • hermes_cli/gateway.py (modified, +47/-12)
  • hermes_cli/hooks.py (modified, +1/-2)
  • hermes_cli/main.py (modified, +691/-58)
  • hermes_cli/model_catalog.py (added, +329/-0)
  • hermes_cli/model_switch.py (modified, +55/-6)
  • hermes_cli/models.py (modified, +251/-43)
  • hermes_cli/nous_subscription.py (modified, +16/-8)
  • hermes_cli/oneshot.py (modified, +28/-11)
  • hermes_cli/platforms.py (modified, +1/-0)
  • hermes_cli/plugins.py (modified, +14/-0)
  • hermes_cli/plugins_cmd.py (modified, +0/-1)
  • hermes_cli/profiles.py (modified, +199/-4)
  • hermes_cli/providers.py (modified, +26/-0)
  • hermes_cli/runtime_provider.py (modified, +100/-14)
  • hermes_cli/setup.py (modified, +69/-16)
  • hermes_cli/skills_hub.py (modified, +230/-20)
  • hermes_cli/slack_cli.py (added, +152/-0)
  • hermes_cli/status.py (modified, +3/-2)
  • hermes_cli/timeouts.py (modified, +4/-4)
  • hermes_cli/tips.py (modified, +2/-3)
  • hermes_cli/tools_config.py (modified, +173/-4)
  • hermes_cli/web_server.py (modified, +11/-14)
  • hermes_cli/webhook.py (modified, +2/-2)
  • hermes_logging.py (modified, +3/-4)
  • hermes_state.py (modified, +578/-164)
  • model_tools.py (modified, +45/-10)
  • nix/checks.nix (modified, +30/-3)
  • nix/hermes-agent.nix (added, +186/-0)

PR #17090: fix: resolve 7 identified issues [automated]

Description (problem / solution / changelog)

Resumo

Este PR corrige 7 issues identificados no repositório NousResearch/hermes-agent.


Issues Corrigidos

1. #17086 - custom endpoint com api_mode=anthropic_messages falhava com 404

Arquivo: agent/auxiliary_client.py Problema: Quando provider=custom com api_mode=anthropic_messages e base_url terminando em /anthropic, a funcao _resolve_provider_client() convertia a URL para o formato /v1/messages, causando 404 em provedores Anthropic-compatíveis de terceiros. Correcao: Mantem o path /anthropic quando api_mode=anthropic_messages e o base_url ja termina em /anthropic.


2. #17076 - kimi-coding vision quebrado (404 em analise de imagem)

Arquivo: agent/auxiliary_client.py Problema: kimi-coding nao estava listado em _PROVIDER_VISION_MODELS, entao auxiliary.vision.provider: auto nao conseguia detectar o modelo de visao disponivel para Kimi. Correcao: Adicionado kimi-coding e kimi-coding-cn ao mapa de modelos de visao.


3. #17080 - hermes profile create --clone copiava credenciais exclusivas de plataforma

Arquivo: hermes_cli/profiles.py Problema: O clone de perfil copiava TELEGRAM_BOT_TOKEN, DISCORD_BOT_TOKEN, WEIXIN_TOKEN verbatim. Quando dois perfis iniciam simultaneamente com o mesmo token, o adaptador de plataforma falha durante a aquisicao de lock. Correcao: Define _EXCLUSIVE_PLATFORM_KEYS e _EXCLUSIVE_PLATFORM_CONFIG_PATHS. Credenciais exclusivas sao comentadas em .env e entradas de plataforma sao enabled: false em config.yaml apos clone.


4. #17054 - Slack manifest rejeitava nomes com underscore

Arquivo: hermes_cli/commands.py Problema: _sanitize_slack_name() convertia nomes de comandos como _reload_mcp para Slack mas nao removia o prefixo underscore, causando rejeicao do manifest. Correcao: Adicionada verificacao para pular nomes que começam com underscore antes de adicionar a lista de slash commands.


5. #17057 - custom Kimi-compatible endpoint falhava apos tool call com thinking habilitado

Arquivo: run_agent.py Problema: _needs_kimi_tool_reasoning() só verificava hostnames oficiais (api.kimi.com, moonshot.ai, moonshot.cn). Endpoints Kimi-compatíveis customizados nao eram detectados. Correcao: Ampliada a verificacao para detectar endpoints customizados pela familia do modelo (nome contem "kimi" ou "k2") alem do hostname.


6. #17049 - UnicodeDecodeError no scan de processos Windows (wmic)

Arquivo: hermes_cli/gateway.py Problema: wmic emitia saida em encoding local do Windows (cp1252/utf-16), causando UnicodeDecodeError e AttributeError durante parsing. Correcao: O parsing agora usa errors=ignore no decode, tratando bytes invalidos como despreziveis.


7. #17052 - stale reasoning reutilizado quando turn atual nao tem reasoning_content

Arquivo: run_agent.py Problema: Mensagens de assistant com tool_calls e reasoning_content eram reutilizadas indevidamente em turns que nao tinham reasoning_content, causando confabulacoes em provedores como Qwen3.6:27b via Ollama. Correcao: O loop de replay agora detecta quando a mensagem atual e um assistant com tool_calls mas sem reasoning_content, e limpa msg[reasoning_content] e msg[reasoning] para evitar propagacao de estado de reasoning de turns anteriores.


Arquivos Modificados

  • agent/auxiliary_client.py - #17086, #17076
  • hermes_cli/profiles.py - #17080
  • hermes_cli/commands.py - #17054
  • run_agent.py - #17057, #17052
  • hermes_cli/gateway.py - #17049

Notas

  • Este PR contem 8 commits (7 issues + 1 fix de seguranca do upstream relacionado a redaction de secrets)
  • Todos os commits foram feitos na branch fix-7-issues-clean
  • Nenhum push intermediario foi feito - push unico ao final
  • Commits do upstream incluidos para manter o historico completo: #16843, #17041, #17039

Changed files

  • agent/auxiliary_client.py (modified, +36/-0)
  • agent/redact.py (modified, +6/-3)
  • gateway/run.py (modified, +10/-4)
  • hermes_cli/commands.py (modified, +3/-0)
  • hermes_cli/gateway.py (modified, +22/-8)
  • hermes_cli/main.py (modified, +18/-7)
  • hermes_cli/profiles.py (modified, +141/-2)
  • run_agent.py (modified, +33/-9)
  • tools/terminal_tool.py (modified, +10/-2)

PR #17152: fix(aux): honor explicit base_url for named providers; preserve /anthropic

Description (problem / solution / changelog)

Summary

Three related config-inheritance bugs in agent/auxiliary_client.py that surface when the auxiliary client (compression, title generation, vision, session search, etc.) tries to reuse the user's main provider config:

  1. _resolve_auto only forwarded base_url for custom / custom:* providers (#16719). With provider: zai + base_url: <override>, the override was silently dropped and auxiliary traffic went to z.ai's default endpoint. Now forwarded as explicit_base_url / explicit_api_key for any named provider.

  2. PROVIDER_REGISTRY branch ignored explicit_base_url / explicit_api_key. Even after fix (1), the named-provider branch unconditionally pulled base_url from creds["base_url"] or pconfig.inference_base_url. Now prefers the forwarded explicit values.

  3. custom branch unconditionally rewrote /anthropic/v1 (#17086). _to_openai_base_url() is the right normalization for OpenAI-wire gateways, but for api_mode: anthropic_messages (or any URL the _endpoint_speaks_anthropic_messages() heuristic recognizes) the rewrite breaks the AnthropicAuxiliaryClient — requests land on /v1/chat/completions instead of /anthropic/v1/messages → 404 on every aux task. The same guard already existed in _try_custom_endpoint() and the named-custom-provider branch; this PR extends it to the explicit_base_url custom branch and the PROVIDER_REGISTRY branch.

Out of scope (mentioned in the original issues but separately resolved):

  • github-copilot slug normalization (#15017) was already addressed in commit 2e2de12.
  • title_generator.py / context_compressor.py already pass main_runtime to call_llm(); the original issue's claim about missing main_runtime is stale.

Test plan

  • tests/agent/test_auxiliary_named_custom_providers.py — 31 passed (3 new test classes, 5 new tests)
  • tests/agent/test_auxiliary_client.py — 194 sync tests pass; 5 pre-existing async failures unrelated (require pytest-asyncio)
  • tests/agent/test_auxiliary_client_anthropic_custom.py — passes (existing _try_custom_endpoint anthropic_messages coverage)
  • tests/agent/test_auxiliary_main_first.py, test_auxiliary_transport_autodetect.py, test_minimax_auxiliary_url.py, test_auxiliary_config_bridge.py — all pass
  • tests/agent/test_context_compressor.py — 65 passed (no compression regressions)
  • Manual: configure provider: zai + base_url: https://custom-zai.example.com/v1 and verify compression hits the custom URL (logs show Auxiliary auto-detect: using main provider zai and the request goes to the override).
  • Manual: configure custom Anthropic-compat proxy with api_mode: anthropic_messages + base_url: http://localhost:6655/anthropic/ and verify auxiliary tasks no longer 404.

Closes: #16719, #17086

Changed files

  • agent/auxiliary_client.py (modified, +45/-4)
  • tests/agent/test_auxiliary_named_custom_providers.py (modified, +132/-0)

PR #3: fix: resolve 7 identified issues [automated]

Description (problem / solution / changelog)

Summary

This PR resolves 7 issues identified in the NousResearch/hermes-agent upstream repository.

Issues Fixed

#17139 - Cron Telegram deliver=['telegram'] fails

File: cron/scheduler.py Problem: When deliver is specified as a list (e.g., ['telegram']), the scheduler used str(deliver).split(",") which converted it to "['telegram']" instead of parsing the list items. Fix: Added check isinstance(deliver, list) to properly handle list-format delivery targets.

#17086 - Custom endpoint URL rewrite strips /anthropic path

File: agent/auxiliary_client.py Problem: Custom endpoints with api_mode: anthropic_messages had URLs rewritten from /anthropic to /v1, causing 404 errors. Fix: Added api_mode != "anthropic_messages" guard to skip URL rewriting when using Anthropic-native message format.

#17054 - Slack manifest broken metadata

File: hermes_cli/slack_cli.py Problem: Slack manifest used "major_version": 1, "minor_version": 1 which is invalid for v1 manifests. Fix: Changed to use "version": "2.0.0" format.

#17049 - Windows wmic UnicodeDecodeError

File: hermes_cli/gateway.py Problem: wmic command output on Windows uses system code page, not UTF-8, causing UnicodeDecodeError and cascading AttributeError on result.stdout. Fix: Added encoding="utf-8", errors="replace" to subprocess call and OSError exception handling.

#17043 - TelegramFallbackTransport DoH drops IPs

File: gateway/platforms/telegram_network.py Problem: discover_fallback_ips() filtered out DoH-resolved IPs that matched system DNS, causing fallback to hardcoded seed IPs on networks where seed IPs aren't routable. Fix: Removed ip not in system_ips exclusion - DoH-confirmed IPs are now preserved.

#17140 - TTS tools use os.getenv() instead of get_env_value()

File: tools/tts_tool.py Problem: TTS providers (elevenlabs, minimax, mistral, xai, gemini) used os.getenv() which doesn't read values from ~/.hermes/.env loaded via the hermes config bridge. Fix: Replaced with get_env_value() calls for all TTS API keys.

hermes_cli/config.py - _sanitize_env_lines KEY= detection

File: hermes_cli/config.py Problem: _sanitize_env_lines matched KEY= patterns that appeared as substrings within other keys (e.g., LM_API_KEY matched inside GLM_API_KEY). Fix: Only treat KEY= as a separator when it appears at position 0 or after a non-identifier character.

Files Modified

  • agent/auxiliary_client.py (+289 lines)
  • cron/scheduler.py (+21 lines)
  • gateway/platforms/telegram_network.py (+9 lines)
  • hermes_cli/config.py (+259 lines)
  • hermes_cli/gateway.py (+21 lines)
  • hermes_cli/slack_cli.py (+3 lines)
  • tools/tts_tool.py (+43 lines)

Testing

All fixes are focused on bug corrections with minimal behavioral changes. The existing test suite should pass.


Automated PR created by Hermes Agent cron job

Changed files

  • .gitignore (modified, +1/-0)
  • Dockerfile (modified, +8/-3)
  • agent/auxiliary_client.py (modified, +344/-55)
  • agent/context_compressor.py (modified, +509/-54)
  • agent/credential_pool.py (modified, +6/-3)
  • agent/error_classifier.py (modified, +31/-0)
  • agent/image_routing.py (added, +236/-0)
  • agent/memory_manager.py (modified, +114/-5)
  • agent/model_metadata.py (modified, +51/-21)
  • agent/nous_rate_guard.py (modified, +142/-0)
  • agent/onboarding.py (added, +191/-0)
  • agent/prompt_builder.py (modified, +34/-0)
  • agent/shell_hooks.py (modified, +5/-1)
  • agent/skill_commands.py (modified, +2/-2)
  • agent/title_generator.py (modified, +33/-4)
  • agent/transports/chat_completions.py (modified, +11/-0)
  • cli-config.yaml.example (modified, +28/-8)
  • cli.py (modified, +466/-196)
  • cron/jobs.py (modified, +31/-3)
  • cron/scheduler.py (modified, +44/-6)
  • docker/entrypoint.sh (modified, +9/-7)
  • flake.nix (modified, +1/-0)
  • gateway/channel_directory.py (modified, +67/-14)
  • gateway/config.py (modified, +68/-2)
  • gateway/display_config.py (modified, +3/-1)
  • gateway/mirror.py (modified, +57/-11)
  • gateway/platforms/__init__.py (modified, +2/-0)
  • gateway/platforms/base.py (modified, +152/-5)
  • gateway/platforms/discord.py (modified, +24/-28)
  • gateway/platforms/email.py (modified, +3/-0)
  • gateway/platforms/feishu.py (modified, +26/-7)
  • gateway/platforms/helpers.py (modified, +9/-0)
  • gateway/platforms/matrix.py (modified, +73/-3)
  • gateway/platforms/slack.py (modified, +753/-70)
  • gateway/platforms/telegram.py (modified, +45/-0)
  • gateway/platforms/telegram_network.py (modified, +7/-2)
  • gateway/platforms/yuanbao.py (added, +4754/-0)
  • gateway/platforms/yuanbao_media.py (added, +647/-0)
  • gateway/platforms/yuanbao_proto.py (added, +1210/-0)
  • gateway/platforms/yuanbao_sticker.py (added, +558/-0)
  • gateway/run.py (modified, +745/-259)
  • gateway/session.py (modified, +11/-2)
  • gateway/status.py (modified, +8/-1)
  • gateway/stream_consumer.py (modified, +110/-0)
  • gateway/whatsapp_identity.py (modified, +21/-1)
  • hermes_cli/auth.py (modified, +28/-3)
  • hermes_cli/backup.py (modified, +177/-1)
  • hermes_cli/commands.py (modified, +113/-5)
  • hermes_cli/config.py (modified, +349/-34)
  • hermes_cli/copilot_auth.py (modified, +1/-1)
  • hermes_cli/debug.py (modified, +11/-5)
  • hermes_cli/doctor.py (modified, +2/-0)
  • hermes_cli/fallback_cmd.py (added, +361/-0)
  • hermes_cli/gateway.py (modified, +35/-10)
  • hermes_cli/main.py (modified, +577/-30)
  • hermes_cli/model_catalog.py (added, +329/-0)
  • hermes_cli/models.py (modified, +98/-6)
  • hermes_cli/nous_subscription.py (modified, +16/-8)
  • hermes_cli/platforms.py (modified, +1/-0)
  • hermes_cli/providers.py (modified, +11/-0)
  • hermes_cli/runtime_provider.py (modified, +31/-0)
  • hermes_cli/setup.py (modified, +69/-14)
  • hermes_cli/skills_hub.py (modified, +230/-20)
  • hermes_cli/slack_cli.py (added, +151/-0)
  • hermes_cli/status.py (modified, +2/-1)
  • hermes_cli/timeouts.py (modified, +4/-4)
  • hermes_cli/tips.py (modified, +2/-3)
  • hermes_cli/tools_config.py (modified, +14/-3)
  • hermes_cli/web_server.py (modified, +8/-10)
  • hermes_logging.py (modified, +3/-4)
  • hermes_state.py (modified, +319/-63)
  • model_tools.py (modified, +44/-13)
  • nix/checks.nix (modified, +30/-3)
  • nix/hermes-agent.nix (added, +186/-0)
  • nix/nixosModules.nix (modified, +81/-6)
  • nix/overlays.nix (added, +10/-0)
  • nix/packages.nix (modified, +6/-107)
  • nix/python.nix (modified, +2/-1)
  • nix/tui.nix (modified, +2/-1)
  • optional-skills/creative/touchdesigner-mcp/SKILL.md (modified, +7/-1)
  • optional-skills/creative/touchdesigner-mcp/references/audio-reactive.md (added, +175/-0)
  • optional-skills/creative/touchdesigner-mcp/references/geometry-comp.md (added, +121/-0)
  • optional-skills/creative/touchdesigner-mcp/references/glsl.md (added, +151/-0)
  • optional-skills/creative/touchdesigner-mcp/references/layout-compositor.md (added, +131/-0)
  • optional-skills/creative/touchdesigner-mcp/references/operator-tips.md (added, +106/-0)
  • optional-skills/creative/touchdesigner-mcp/references/pitfalls.md (modified, +221/-25)
  • optional-skills/creative/touchdesigner-mcp/references/postfx.md (added, +183/-0)
  • optional-skills/migration/openclaw-migration/scripts/openclaw_to_hermes.py (modified, +27/-2)
  • plugins/google_meet/README.md (added, +131/-0)
  • plugins/google_meet/SKILL.md (added, +148/-0)
  • plugins/google_meet/__init__.py (added, +103/-0)
  • plugins/google_meet/audio_bridge.py (added, +244/-0)
  • plugins/google_meet/cli.py (added, +478/-0)
  • plugins/google_meet/meet_bot.py (added, +852/-0)
  • plugins/google_meet/node/__init__.py (added, +54/-0)
  • plugins/google_meet/node/cli.py (added, +125/-0)
  • plugins/google_meet/node/client.py (added, +107/-0)
  • plugins/google_meet/node/protocol.py (added, +124/-0)
  • plugins/google_meet/node/registry.py (added, +112/-0)
  • plugins/google_meet/node/server.py (added, +193/-0)

PR #16165: fix: resolve 7 identified issues [automated]

Description (problem / solution / changelog)

Summary

This PR resolves 7 issues identified in the NousResearch/hermes-agent upstream repository.

Issues Fixed

#17139 - Cron Telegram deliver=['telegram'] fails

File: cron/scheduler.py Problem: When deliver is specified as a list (e.g., ['telegram']), the scheduler used str(deliver).split(",") which converted it to "['telegram']" instead of parsing the list items. Fix: Added check isinstance(deliver, list) to properly handle list-format delivery targets.

#17086 - Custom endpoint URL rewrite strips /anthropic path

File: agent/auxiliary_client.py Problem: Custom endpoints with api_mode: anthropic_messages had URLs rewritten from /anthropic to /v1, causing 404 errors. Fix: Added api_mode != "anthropic_messages" guard to skip URL rewriting when using Anthropic-native message format.

#17054 - Slack manifest broken metadata

File: hermes_cli/slack_cli.py Problem: Slack manifest used "major_version": 1, "minor_version": 1 which is invalid for v1 manifests. Fix: Changed to use "version": "2.0.0" format.

#17049 - Windows wmic UnicodeDecodeError

File: hermes_cli/gateway.py Problem: wmic command output on Windows uses system code page, not UTF-8, causing UnicodeDecodeError and cascading AttributeError on result.stdout. Fix: Added encoding="utf-8", errors="replace" to subprocess call and OSError exception handling.

#17043 - TelegramFallbackTransport DoH drops IPs

File: gateway/platforms/telegram_network.py Problem: discover_fallback_ips() filtered out DoH-resolved IPs that matched system DNS, causing fallback to hardcoded seed IPs on networks where seed IPs aren't routable. Fix: Removed ip not in system_ips exclusion - DoH-confirmed IPs are now preserved.

#17140 - TTS tools use os.getenv() instead of get_env_value()

File: tools/tts_tool.py Problem: TTS providers (elevenlabs, minimax, mistral, xai, gemini) used os.getenv() which doesn't read values from ~/.hermes/.env loaded via the hermes config bridge. Fix: Replaced with get_env_value() calls for all TTS API keys.

hermes_cli/config.py - _sanitize_env_lines KEY= detection

File: hermes_cli/config.py Problem: _sanitize_env_lines matched KEY= patterns that appeared as substrings within other keys (e.g., LM_API_KEY matched inside GLM_API_KEY). Fix: Only treat KEY= as a separator when it appears at position 0 or after a non-identifier character.

Files Modified

  • agent/auxiliary_client.py
  • cron/scheduler.py
  • gateway/platforms/telegram_network.py
  • hermes_cli/config.py
  • hermes_cli/gateway.py
  • hermes_cli/slack_cli.py
  • tools/tts_tool.py

Automated PR updated by Hermes Agent cron job

Changed files

  • .gitignore (modified, +1/-0)
  • Dockerfile (modified, +8/-3)
  • agent/auxiliary_client.py (modified, +344/-55)
  • agent/context_compressor.py (modified, +509/-54)
  • agent/error_classifier.py (modified, +31/-0)
  • agent/image_routing.py (added, +236/-0)
  • agent/memory_manager.py (modified, +114/-5)
  • agent/model_metadata.py (modified, +35/-16)
  • agent/onboarding.py (modified, +52/-5)
  • agent/prompt_builder.py (modified, +34/-0)
  • agent/shell_hooks.py (modified, +5/-1)
  • agent/title_generator.py (modified, +33/-4)
  • agent/transports/chat_completions.py (modified, +11/-0)
  • cli-config.yaml.example (modified, +6/-1)
  • cli.py (modified, +390/-58)
  • cron/jobs.py (modified, +31/-3)
  • cron/scheduler.py (modified, +41/-3)
  • flake.nix (modified, +1/-0)
  • gateway/channel_directory.py (modified, +67/-14)
  • gateway/config.py (modified, +68/-2)
  • gateway/display_config.py (modified, +3/-1)
  • gateway/mirror.py (modified, +57/-11)
  • gateway/platforms/__init__.py (modified, +2/-0)
  • gateway/platforms/base.py (modified, +117/-0)
  • gateway/platforms/discord.py (modified, +24/-23)
  • gateway/platforms/email.py (modified, +3/-0)
  • gateway/platforms/feishu.py (modified, +26/-7)
  • gateway/platforms/helpers.py (modified, +9/-0)
  • gateway/platforms/matrix.py (modified, +73/-3)
  • gateway/platforms/slack.py (modified, +753/-70)
  • gateway/platforms/telegram.py (modified, +45/-0)
  • gateway/platforms/telegram_network.py (modified, +7/-2)
  • gateway/platforms/yuanbao.py (added, +4754/-0)
  • gateway/platforms/yuanbao_media.py (added, +647/-0)
  • gateway/platforms/yuanbao_proto.py (added, +1210/-0)
  • gateway/platforms/yuanbao_sticker.py (added, +558/-0)
  • gateway/run.py (modified, +570/-60)
  • gateway/session.py (modified, +11/-2)
  • gateway/status.py (modified, +8/-1)
  • gateway/stream_consumer.py (modified, +110/-0)
  • gateway/whatsapp_identity.py (modified, +21/-1)
  • hermes_cli/auth.py (modified, +9/-0)
  • hermes_cli/backup.py (modified, +177/-1)
  • hermes_cli/commands.py (modified, +112/-2)
  • hermes_cli/config.py (modified, +358/-34)
  • hermes_cli/copilot_auth.py (modified, +1/-1)
  • hermes_cli/debug.py (modified, +11/-5)
  • hermes_cli/doctor.py (modified, +2/-0)
  • hermes_cli/gateway.py (modified, +35/-10)
  • hermes_cli/main.py (modified, +530/-28)
  • hermes_cli/models.py (modified, +70/-5)
  • hermes_cli/nous_subscription.py (modified, +16/-8)
  • hermes_cli/platforms.py (modified, +1/-0)
  • hermes_cli/providers.py (modified, +11/-0)
  • hermes_cli/runtime_provider.py (modified, +31/-0)
  • hermes_cli/setup.py (modified, +69/-14)
  • hermes_cli/skills_hub.py (modified, +170/-6)
  • hermes_cli/slack_cli.py (added, +151/-0)
  • hermes_cli/status.py (modified, +2/-1)
  • hermes_cli/timeouts.py (modified, +4/-4)
  • hermes_cli/tips.py (modified, +1/-1)
  • hermes_cli/tools_config.py (modified, +14/-3)
  • hermes_cli/web_server.py (modified, +8/-10)
  • hermes_logging.py (modified, +3/-4)
  • hermes_state.py (modified, +307/-62)
  • model_tools.py (modified, +44/-13)
  • nix/checks.nix (modified, +30/-3)
  • nix/hermes-agent.nix (added, +186/-0)
  • nix/nixosModules.nix (modified, +81/-6)
  • nix/overlays.nix (added, +10/-0)
  • nix/packages.nix (modified, +6/-107)
  • nix/python.nix (modified, +2/-1)
  • nix/tui.nix (modified, +2/-1)
  • optional-skills/creative/touchdesigner-mcp/SKILL.md (modified, +7/-1)
  • optional-skills/creative/touchdesigner-mcp/references/audio-reactive.md (added, +175/-0)
  • optional-skills/creative/touchdesigner-mcp/references/geometry-comp.md (added, +121/-0)
  • optional-skills/creative/touchdesigner-mcp/references/glsl.md (added, +151/-0)
  • optional-skills/creative/touchdesigner-mcp/references/layout-compositor.md (added, +131/-0)
  • optional-skills/creative/touchdesigner-mcp/references/operator-tips.md (added, +106/-0)
  • optional-skills/creative/touchdesigner-mcp/references/pitfalls.md (modified, +221/-25)
  • optional-skills/creative/touchdesigner-mcp/references/postfx.md (added, +183/-0)
  • optional-skills/migration/openclaw-migration/scripts/openclaw_to_hermes.py (modified, +27/-2)
  • plugins/google_meet/README.md (added, +131/-0)
  • plugins/google_meet/SKILL.md (added, +148/-0)
  • plugins/google_meet/__init__.py (added, +103/-0)
  • plugins/google_meet/audio_bridge.py (added, +244/-0)
  • plugins/google_meet/cli.py (added, +478/-0)
  • plugins/google_meet/meet_bot.py (added, +852/-0)
  • plugins/google_meet/node/__init__.py (added, +54/-0)
  • plugins/google_meet/node/cli.py (added, +125/-0)
  • plugins/google_meet/node/client.py (added, +107/-0)
  • plugins/google_meet/node/protocol.py (added, +124/-0)
  • plugins/google_meet/node/registry.py (added, +112/-0)
  • plugins/google_meet/node/server.py (added, +193/-0)
  • plugins/google_meet/plugin.yaml (added, +16/-0)
  • plugins/google_meet/process_manager.py (added, +326/-0)
  • plugins/google_meet/realtime/__init__.py (added, +10/-0)
  • plugins/google_meet/realtime/openai_client.py (added, +332/-0)
  • plugins/google_meet/tools.py (added, +348/-0)
  • plugins/memory/hindsight/__init__.py (modified, +154/-43)

Code Example

# Line ~1834
custom_base = _to_openai_base_url(explicit_base_url).strip()

---

auxiliary:
  title_generation:
    provider: custom
    base_url: http://localhost:6655/anthropic/
    api_mode: anthropic_messages
    model: claude-haiku

---

WARNING agent.title_generator: Title generation failed: <!DOCTYPE html>
<html><body><pre>Cannot POST /v1/chat/completions</pre></body></html>

---

if api_mode == "anthropic_messages":
    from agent.anthropic_adapter import build_anthropic_client
    real_client = build_anthropic_client(custom_key, explicit_base_stripped)
    return AnthropicAuxiliaryClient(
        real_client, final_model, custom_key, explicit_base_stripped, is_oauth=False
    ), final_model
# else: fall through to OpenAI path with URL rewrite as before
custom_base = _to_openai_base_url(explicit_base_stripped)
RAW_BUFFERClick to expand / collapse

Bug Report

Affected file: agent/auxiliary_client.py
Function: resolve_provider_client()custom provider branch


Summary

When a custom auxiliary endpoint is configured with api_mode: anthropic_messages, all auxiliary tasks (title_generation, compression, session_search, vision, web_extract, etc.) silently fail with HTTP 404.


Root Cause

In resolve_provider_client(), the custom branch unconditionally passes explicit_base_url through _to_openai_base_url(), which rewrites URLs ending in /anthropic or /anthropic/ to /v1:

# Line ~1834
custom_base = _to_openai_base_url(explicit_base_url).strip()

So a proxy base URL like http://localhost:6655/anthropic/ becomes http://localhost:6655/v1, and all requests land on POST /v1/chat/completions — a route that doesn't exist on an Anthropic-native proxy.

This is inconsistent with the identical api_mode == "anthropic_messages" guard that already exists in:

  • _try_custom_endpoint() (line ~1180)
  • Named provider branches

Reproduction

~/.hermes/config.yaml:

auxiliary:
  title_generation:
    provider: custom
    base_url: http://localhost:6655/anthropic/
    api_mode: anthropic_messages
    model: claude-haiku

Symptom in ~/.hermes/logs/errors.log:

WARNING agent.title_generator: Title generation failed: <!DOCTYPE html>
<html><body><pre>Cannot POST /v1/chat/completions</pre></body></html>

Expected Behaviour

When api_mode: anthropic_messages is set, the URL should be passed unchanged to build_anthropic_client() / AnthropicAuxiliaryClient, exactly as _try_custom_endpoint() already does.


Fix

Add the same api_mode == "anthropic_messages" guard to the custom + explicit_base_url branch in resolve_provider_client():

if api_mode == "anthropic_messages":
    from agent.anthropic_adapter import build_anthropic_client
    real_client = build_anthropic_client(custom_key, explicit_base_stripped)
    return AnthropicAuxiliaryClient(
        real_client, final_model, custom_key, explicit_base_stripped, is_oauth=False
    ), final_model
# else: fall through to OpenAI path with URL rewrite as before
custom_base = _to_openai_base_url(explicit_base_stripped)

Related

  • #13762 — custom_providers routing failures in auxiliary tasks
  • #16387 — auxiliary client cache routes wrong model

extent analysis

TL;DR

The most likely fix is to add an api_mode == "anthropic_messages" guard to the custom branch in resolve_provider_client() to prevent URL rewriting for Anthropic-native proxies.

Guidance

  • Verify that the api_mode is correctly set to "anthropic_messages" in the config.yaml file.
  • Check the resolve_provider_client() function to ensure the custom branch is correctly handling the explicit_base_url when api_mode is "anthropic_messages".
  • Apply the proposed fix by adding the api_mode == "anthropic_messages" guard to the custom branch in resolve_provider_client().
  • Test the auxiliary tasks (e.g., title_generation, compression, session_search, vision, web_extract) to ensure they no longer fail with HTTP 404.

Example

if api_mode == "anthropic_messages":
    from agent.anthropic_adapter import build_anthropic_client
    real_client = build_anthropic_client(custom_key, explicit_base_stripped)
    return AnthropicAuxiliaryClient(
        real_client, final_model, custom_key, explicit_base_stripped, is_oauth=False
    ), final_model

Notes

This fix assumes that the build_anthropic_client() function and AnthropicAuxiliaryClient class are correctly implemented and handle the Anthropic-native proxy case.

Recommendation

Apply the workaround by adding the api_mode == "anthropic_messages" guard to the custom branch in resolve_provider_client(), as this will prevent URL rewriting for Anthropic-native proxies and allow auxiliary tasks to complete successfully.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

hermes - ✅(Solved) Fix Bug: auxiliary tasks fail with HTTP 404 when using anthropic_messages custom endpoint — URL rewrite strips /anthropic/ path [5 pull requests, 2 comments, 2 participants]