mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-06-09 08:21:50 +00:00
fix: guard int(os.getenv()) casts against malformed env vars (#40598)
A non-numeric value in env vars like HERMES_STREAM_RETRIES, HERMES_KANBAN_SPECIFY_MAX_TOKENS, GOOGLE_CHAT_MAX_BYTES, IRC_PORT, etc. raised ValueError at import/init and crashed startup. Parse them safely, falling back to the default. Unified onto the existing utils.env_int(key, default) helper for core/ hermes_cli/tools modules instead of the original PR's three duplicate local helpers; plugins keep minimal inline guards (no core-utils import). All existing max()/min()/`or extra.get()` wrappers preserved. Co-authored-by: annguyenNous <annguyenNous@users.noreply.github.com>
This commit is contained in:
parent
e2cc24e331
commit
2912d94370
8 changed files with 29 additions and 13 deletions
|
|
@ -34,7 +34,7 @@ from agent.message_sanitization import (
|
|||
_repair_tool_call_arguments,
|
||||
)
|
||||
from tools.terminal_tool import is_persistent_env
|
||||
from utils import base_url_host_matches, base_url_hostname
|
||||
from utils import base_url_host_matches, base_url_hostname, env_int
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
|
@ -2058,7 +2058,7 @@ def interruptible_streaming_api_call(agent, api_kwargs: dict, *, on_first_delta=
|
|||
def _call():
|
||||
import httpx as _httpx
|
||||
|
||||
_max_stream_retries = int(os.getenv("HERMES_STREAM_RETRIES", 2))
|
||||
_max_stream_retries = env_int("HERMES_STREAM_RETRIES", 2)
|
||||
|
||||
try:
|
||||
for _stream_attempt in range(_max_stream_retries + 1):
|
||||
|
|
|
|||
|
|
@ -40,9 +40,11 @@ from typing import Optional
|
|||
|
||||
from hermes_cli import kanban_db as kb
|
||||
|
||||
from utils import env_int
|
||||
|
||||
HERMES_KANBAN_SPECIFY_MAX_TOKENS = max(
|
||||
1500,
|
||||
int(os.getenv("HERMES_KANBAN_SPECIFY_MAX_TOKENS", "6000")),
|
||||
env_int("HERMES_KANBAN_SPECIFY_MAX_TOKENS", 6000),
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ from hermes_cli.auth import (
|
|||
)
|
||||
from hermes_cli.config import get_compatible_custom_providers, load_config
|
||||
from hermes_constants import OPENROUTER_BASE_URL
|
||||
from utils import base_url_host_matches, base_url_hostname
|
||||
from utils import base_url_host_matches, base_url_hostname, env_int
|
||||
|
||||
|
||||
def _normalize_custom_provider_name(value: str) -> str:
|
||||
|
|
@ -1144,7 +1144,7 @@ def _resolve_explicit_runtime(
|
|||
str(state.get("agent_key") or "").strip()
|
||||
if _agent_key_is_usable(
|
||||
state,
|
||||
max(60, int(os.getenv("HERMES_NOUS_MIN_KEY_TTL_SECONDS", "1800"))),
|
||||
max(60, env_int("HERMES_NOUS_MIN_KEY_TTL_SECONDS", 1800)),
|
||||
)
|
||||
else ""
|
||||
)
|
||||
|
|
@ -1343,7 +1343,7 @@ def resolve_runtime_provider(
|
|||
# expired, clear pool_api_key so we fall through to
|
||||
# resolve_nous_runtime_credentials() which handles refresh.
|
||||
if provider == "nous" and entry is not None and pool_api_key:
|
||||
min_ttl = max(60, int(os.getenv("HERMES_NOUS_MIN_KEY_TTL_SECONDS", "1800")))
|
||||
min_ttl = max(60, env_int("HERMES_NOUS_MIN_KEY_TTL_SECONDS", 1800))
|
||||
nous_state = {
|
||||
"agent_key": getattr(entry, "agent_key", None),
|
||||
"agent_key_expires_at": getattr(entry, "agent_key_expires_at", None),
|
||||
|
|
|
|||
|
|
@ -78,7 +78,10 @@ class FirecrawlBrowserProvider(BrowserProvider):
|
|||
}
|
||||
|
||||
def create_session(self, task_id: str) -> Dict[str, object]:
|
||||
ttl = int(os.environ.get("FIRECRAWL_BROWSER_TTL", "300"))
|
||||
try:
|
||||
ttl = int(os.environ.get("FIRECRAWL_BROWSER_TTL", "300"))
|
||||
except (ValueError, TypeError):
|
||||
ttl = 300
|
||||
|
||||
body: Dict[str, object] = {"ttl": ttl}
|
||||
|
||||
|
|
|
|||
|
|
@ -540,8 +540,14 @@ class GoogleChatAdapter(BasePlatformAdapter):
|
|||
# they don't sit in the chat forever as "Hermes is thinking…".
|
||||
self._orphan_typing_messages: Dict[str, List[str]] = {}
|
||||
# FlowControl knobs (env-configurable).
|
||||
self._max_messages = int(os.getenv("GOOGLE_CHAT_MAX_MESSAGES", "1"))
|
||||
self._max_bytes = int(os.getenv("GOOGLE_CHAT_MAX_BYTES", str(16 * 1024 * 1024)))
|
||||
try:
|
||||
self._max_messages = int(os.getenv("GOOGLE_CHAT_MAX_MESSAGES", "1"))
|
||||
except (ValueError, TypeError):
|
||||
self._max_messages = 1
|
||||
try:
|
||||
self._max_bytes = int(os.getenv("GOOGLE_CHAT_MAX_BYTES", str(16 * 1024 * 1024)))
|
||||
except (ValueError, TypeError):
|
||||
self._max_bytes = 16 * 1024 * 1024
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Configuration loading and validation
|
||||
|
|
|
|||
|
|
@ -107,7 +107,10 @@ class IRCAdapter(BasePlatformAdapter):
|
|||
|
||||
# Connection settings (env vars override config.yaml)
|
||||
self.server = os.getenv("IRC_SERVER") or extra.get("server", "")
|
||||
self.port = int(os.getenv("IRC_PORT") or extra.get("port", 6697))
|
||||
try:
|
||||
self.port = int(os.getenv("IRC_PORT") or extra.get("port", 6697))
|
||||
except (ValueError, TypeError):
|
||||
self.port = 6697
|
||||
self.nickname = os.getenv("IRC_NICKNAME") or extra.get("nickname", "hermes-bot")
|
||||
self.channel = os.getenv("IRC_CHANNEL") or extra.get("channel", "")
|
||||
self.use_tls = (
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ from typing import Dict, Any, Optional, List, Tuple, Union
|
|||
from pathlib import Path
|
||||
from agent.auxiliary_client import call_llm
|
||||
from hermes_constants import get_hermes_home
|
||||
from utils import is_truthy_value
|
||||
from utils import env_int, is_truthy_value
|
||||
from hermes_cli.config import cfg_get
|
||||
|
||||
try:
|
||||
|
|
@ -1178,7 +1178,7 @@ _cleanup_done = False
|
|||
# Session inactivity timeout (seconds) - cleanup if no activity for this long
|
||||
# Default: 5 minutes. Needs headroom for LLM reasoning between browser commands,
|
||||
# especially when subagents are doing multi-step browser tasks.
|
||||
BROWSER_SESSION_INACTIVITY_TIMEOUT = int(os.environ.get("BROWSER_INACTIVITY_TIMEOUT", "300"))
|
||||
BROWSER_SESSION_INACTIVITY_TIMEOUT = env_int("BROWSER_INACTIVITY_TIMEOUT", 300)
|
||||
|
||||
# Track last activity time per session
|
||||
_session_last_activity: Dict[str, float] = {}
|
||||
|
|
|
|||
|
|
@ -60,6 +60,8 @@ from pathlib import Path
|
|||
from hermes_constants import get_hermes_home
|
||||
from typing import Dict, List, Optional, Set, Tuple
|
||||
|
||||
from utils import env_int
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
|
|
@ -139,7 +141,7 @@ DEFAULT_EXCLUDES = [
|
|||
]
|
||||
|
||||
# Git subprocess timeout (seconds).
|
||||
_GIT_TIMEOUT: int = max(10, min(60, int(os.getenv("HERMES_CHECKPOINT_TIMEOUT", "30"))))
|
||||
_GIT_TIMEOUT: int = max(10, min(60, env_int("HERMES_CHECKPOINT_TIMEOUT", 30)))
|
||||
|
||||
# Max files to snapshot — skip huge directories to avoid slowdowns.
|
||||
_MAX_FILES = 50_000
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue