Compare commits

...

1 Commits

Author SHA1 Message Date
Metatron
7aeb84e3fc fix: disable terminal toolset for cloud providers in cron jobs (closes #379)
Some checks failed
Forge CI / smoke-and-build (pull_request) Failing after 1m24s
When the cron scheduler resolves a cloud provider (Nous, OpenRouter,
Anthropic), the agent still had the terminal toolset available. This
caused nightwatch-health-monitor and similar jobs to attempt SSH into
remote VPSes (Ezra, Allegro, Bezalel) without local SSH keys.

Fix: use is_local_endpoint() from agent/model_metadata.py to check the
runtime base_url. When it's a cloud endpoint (not localhost/private IP),
append 'terminal' to disabled_toolsets. Local endpoints (Ollama, llama.cpp)
retain terminal access as before.

Also logs when terminal is disabled for observability.
2026-04-13 18:27:02 -04:00

View File

@@ -37,6 +37,7 @@ sys.path.insert(0, str(Path(__file__).parent.parent))
from hermes_constants import get_hermes_home
from hermes_cli.config import load_config
from hermes_time import now as _hermes_now
from agent.model_metadata import is_local_endpoint
logger = logging.getLogger(__name__)
@@ -777,6 +778,20 @@ def run_job(job: dict) -> tuple[bool, str, str, Optional[str]]:
},
)
# Build disabled toolsets — always exclude cronjob/messaging/clarify
# for cron sessions. When the runtime endpoint is cloud (not local),
# also disable terminal so the agent does not attempt SSH or shell
# commands that require local infrastructure (keys, filesystem). #379
_cron_disabled = ["cronjob", "messaging", "clarify"]
_runtime_base_url = turn_route["runtime"].get("base_url", "")
if not is_local_endpoint(_runtime_base_url):
_cron_disabled.append("terminal")
logger.info(
"Job '%s': cloud provider detected (%s), disabling terminal toolset",
job_name,
turn_route["runtime"].get("provider", "unknown"),
)
_agent_kwargs = _safe_agent_kwargs({
"model": turn_route["model"],
"api_key": turn_route["runtime"].get("api_key"),
@@ -792,7 +807,7 @@ def run_job(job: dict) -> tuple[bool, str, str, Optional[str]]:
"providers_ignored": pr.get("ignore"),
"providers_order": pr.get("order"),
"provider_sort": pr.get("sort"),
"disabled_toolsets": ["cronjob", "messaging", "clarify"],
"disabled_toolsets": _cron_disabled,
"tool_choice": "required",
"quiet_mode": True,
"skip_memory": True, # Cron system prompts would corrupt user representations