fix: resolve 7 identified issues [automated] - #17090
Conversation
…ompatible endpoints (NousResearch#17057) Custom Kimi-compatible endpoints (provider=custom, api_mode=anthropic_messages) also require reasoning_content on assistant tool-call messages when thinking is enabled, but the previous check only matched official Kimi/Moonshot hostnames. Detect Kimi-compatible custom endpoints by model family (model name contains 'kimi' or 'k2') in addition to the hostname check, so self-hosted proxies and third-party Kimi-compatible inference providers are also handled correctly.
…ousResearch#17080) hermes profile create --clone was copying the source profile's .env and config.yaml verbatim, including exclusive platform credentials (TELEGRAM_BOT_TOKEN, WEIXIN_TOKEN, DISCORD_BOT_TOKEN, etc.). These are one-to-one identity bindings — a token belongs to exactly one bot instance and cannot be shared across profiles. When two profiles hold the same token and start simultaneously, the platform adapter fails during scoped lock acquisition, causing a gateway health check timeout and a confusing 'profile loading error' in hermes-web-ui. Fix: define _EXCLUSIVE_PLATFORM_KEYS and _EXCLUSIVE_PLATFORM_CONFIG_PATHS, and apply _strip_env_exclusive_credentials() and _strip_config_exclusive_credentials() to cloned .env and config.yaml files. Exclusive credential keys are commented out in .env, and the corresponding platform entries are force-disabled (enabled: false) in config.yaml. A warning is printed so the user knows to configure them for the new profile.
…sResearch#17054) Slack's app manifest rejects slash command names that start with an underscore. _sanitize_slack_name() converts plugin command names (e.g. _reload_mcp) to valid Slack names by lowercasing and stripping invalid chars, but the underscore prefix was preserved. Commands like /_reload_mcp were included in the manifest and caused Slack to reject the entire app with 'invalid name'. Fix: skip any sanitized name that starts with an underscore before adding it to the slash command list.
…h api_mode=anthropic_messages (NousResearch#17086) When a custom auxiliary endpoint was configured with api_mode=anthropic_messages, resolve_provider_client() unconditionally passed the base URL through _to_openai_base_url(), which rewrites /anthropic → /v1. This caused all auxiliary tasks (title_generation, compression, vision, web_extract, etc.) to land on POST /v1/chat/completions — a 404 on Anthropic-native proxies. Fix: add the same api_mode==anthropic_messages guard that already exists in _try_custom_endpoint() and named-provider branches. When api_mode is anthropic_messages, pass the URL unchanged to build_anthropic_client() and route through AnthropicAuxiliaryClient directly.
…sResearch#17049) Fix two locations where wmic subprocess output was decoded with text=True (UTF-8) on Windows. Non-UTF-8 characters in process paths cause UnicodeDecodeError, and Python ≤3.11 can return None for stdout after decode failures causing AttributeError. Fix: capture raw bytes, decode with utf-8 then fall back to latin-1, and guard against None stdout.
…asoning_content (NousResearch#17052) Changed last_reasoning extraction to only use the most recent assistant message (current turn) rather than walking the full message history. Previously, when the model returned null reasoning for a simple prompt, the loop would skip the current message and match an older assistant message's reasoning, displaying it as if it belonged to the current response.
…tforms after 20 attempts (NousResearch#17063) Instead of removing a platform from _failed_platforms after 20 failed reconnect attempts, keep it in the retry queue with a fixed 10-minute backoff. This prevents transient network/proxy outages that last hours from permanently disabling a platform (e.g. Telegram) until the gateway is manually restarted.
…ands (NousResearch#16843) Make redact_sensitive_text JSON field pattern use exact key match instead of substring match to avoid false positives like 'htpasswd_password' being treated as a credential field. Also restrict terminal_tool redaction to structured output (JSON, logs) only — arbitrary command output passes through unchanged so that functional commands like htpasswd that output passwords as results continue to work correctly.
teknium1
left a comment
There was a problem hiding this comment.
Thanks for collecting several real reports. Most portions have since landed on current main through narrower fixes, but this branch contains regressions that prevent direct salvage.
Problems
agent/auxiliary_client.py:187mapskimi-codinginto automatic vision selection. Current main deliberately skips Kimi Coding because its/codingendpoint has no image-input capability (agent/auxiliary_client.py:492-505,:5330-5338;ff687c019e20794efd4c6c2587b4317ef37eef6e).tools/terminal_tool.py:1963only redacts output with selected prefixes. A normalprintenvresult begins with an environment key and would pass through raw. Current main uses command-awareredact_terminal_output()(tools/terminal_tool.py:2724-2734;agent/redact.py:721-742).- The new profile config scrubber accepts only three-segment paths, while the report itself identifies nested platform credentials such as
platforms.weixin.extra.account_id; those remain in the clone.
Suggested changes
- Keep the profile-clone concern as a focused, schema-complete change with direct and nested-config regression coverage.
- Preserve the current main implementations for the independently fixed auxiliary, reasoning, Slack, Windows, reconnect, and redaction cases.
Automated hermes-sweeper review.
| # chat completions surface, but the platform does serve a multimodal | ||
| # endpoint. Map to the known vision-capable variant so auto vision detect | ||
| # lands on the right model instead of the 404 text-only endpoint (#17076). | ||
| "kimi-coding": "kimi-k2.6", |
There was a problem hiding this comment.
kimi-coding is not a vision-capable automatic backend: the Coding Plan /coding endpoint rejects image input. Please do not add it to auto vision selection; current main skips this provider and falls back to the aggregator chain.
| # Apply redaction only if output looks like structured data | ||
| if stripped.startswith(("{", "[", "202", "error", "warn", "info", "debug", "level", '{"')): | ||
| output = redact_sensitive_text(stripped) if stripped else "" | ||
| # else: pass through unchanged for functional commands |
There was a problem hiding this comment.
This prefix test leaves plain printenv/env output unredacted because it normally starts with an environment-variable name. Keep command-aware redaction so environment dumps mask opaque KEY=value secrets without corrupting source/config output.
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.pyProblema: 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.pyProblema: 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.pyProblema: 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.pyProblema: _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.pyProblema: _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.pyProblema: 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.pyProblema: 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- Bug: auxiliary tasks fail with HTTP 404 when using anthropic_messages custom endpoint — URL rewrite strips /anthropic/ path #17086, [Bug]: Native vision support for kimi-coding provider broken — error 404 on image analysis #17076hermes_cli/profiles.py-hermes profile create --clonecopies exclusive platform credentials causing multi-profile gateway conflicts #17080hermes_cli/commands.py- [Setup]: Slack manifest is broken #17054run_agent.py- Custom Kimi-compatible endpoint with api_mode=anthropic_messages fails after tool call when thinking is enabled #17057, Bug: stale reasoning reused when current turn has no reasoning_content #17052hermes_cli/gateway.py- [Bug]: UnicodeDecodeError and AttributeError in Windows gateway process scanning #17049Notas