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
2 changed files with 16 additions and 104 deletions

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

View File

@@ -1,103 +0,0 @@
# Honcho Memory Integration Evaluation (#322)
## Source
plastic-labs/hermes-honcho — full Honcho AI-native memory integration
## Status: ALREADY IMPLEMENTED
The Honcho integration has been fully ported to the main hermes-agent repository.
## Components Found
### 1. Client Configuration (`plugins/memory/honcho/client.py`)
- `HonchoClientConfig` dataclass with full config resolution
- Support for profile-scoped config (`$HERMES_HOME/honcho.json`)
- Global config fallback (`~/.honcho/config.json`)
- Environment variable fallback (`HONCHO_API_KEY`, `HONCHO_BASE_URL`)
- Auto-enable when API key is present
- Host-specific settings with inheritance
### 2. Session Management (`plugins/memory/honcho/session.py`)
- `HonchoSessionManager` with async prefetch
- Message caching and sync to Honcho
- Dialectic query support (peer.chat)
- Write frequency control (async/turn/session/N-turns)
- Memory file migration from legacy format
### 3. MemoryProvider Interface (`plugins/memory/honcho/__init__.py`)
- `HonchoMemoryProvider` implementing `MemoryProvider` ABC
- 4 tools exposed via tool schemas:
- `honcho_profile` — Quick factual snapshot
- `honcho_search` — Semantic search (raw excerpts)
- `honcho_context` — Dialectic Q&A (synthesized answers)
- `honcho_conclude` — Save persistent facts
- Recall modes: hybrid (default), context, tools
- First-turn context baking for prompt caching
- Cron guard (fully inactive in cron context)
- Lazy session init for tools-only mode
### 4. CLI Integration (`plugins/memory/honcho/cli.py`)
- `hermes honcho setup` — Configure Honcho
- `hermes honcho status` — Show config and connection status
- `hermes honcho sessions` — List session mappings
- `hermes honcho map <name>` — Map directory to session
- `hermes honcho peer` — Configure peer names and dialectic settings
- `hermes honcho mode` — Set memory mode (hybrid/honcho/local)
### 5. Tests
- `tests/test_honcho_client_config.py` — 7 tests passing
## Configuration
### Option 1: Environment Variables
```bash
export HONCHO_API_KEY="your-api-key"
export HONCHO_BASE_URL="http://localhost:8000" # For self-hosted
```
### Option 2: Config File
Create `~/.hermes/honcho.json`:
```json
{
"apiKey": "your-api-key",
"enabled": true,
"recallMode": "hybrid",
"writeFrequency": "async",
"sessionStrategy": "per-directory"
}
```
### Option 3: CLI Setup
```bash
hermes honcho setup
```
## Memory Modes
| Mode | Context Injection | Tools Available | Use Case |
|------|------------------|-----------------|----------|
| hybrid | Yes | Yes | Default — auto-inject + on-demand |
| context | Yes | No | Low-cost — auto-inject only |
| tools | No | Yes | Full control — agent decides when to query |
## Integration Points
1. **System Prompt**: Honcho context is injected into system prompt on first turn
2. **Tool Registry**: 4 tools available when recall_mode != "context"
3. **Session End**: Messages flushed to Honcho on session end
4. **Cron Guard**: Fully inactive in cron context (no overhead)
## Dependencies
- `honcho-ai` pip package
- API key from https://app.honcho.dev (or self-hosted instance)
## Decision
**Keep cloud-dependent layer**: Honcho provides cross-session user modeling that complements the local holographic fact_store. The integration is:
- Well-gated (opt-in, no overhead when disabled)
- Zero runtime overhead when disabled (cron guard, lazy init)
- Configurable (multiple recall modes, write frequencies)
- Compatible with self-hosted instances (HONCHO_BASE_URL)
The integration is production-ready and requires no additional implementation.