docs: sync developer-guide agent-core docs with the facade/siblings layout (#102117)

This commit is contained in:
Teknium
2026-09-04 00:07:14 -07:00
parent 27a4023791
commit 4fb332b427
8 changed files with 28 additions and 24 deletions

View File

@@ -6,7 +6,7 @@ description: "Detailed walkthrough of AIAgent execution, API modes, tools, callb
# Agent Loop Internals
The core orchestration engine is `run_agent.py`'s `AIAgent` class — a large file that handles everything from prompt assembly to tool dispatch to provider failover.
The core orchestration engine is the `AIAgent` class. `run_agent.py` is now a thin facade: the loop itself lives in `agent/conversation_loop.py`, each turn phase in `agent/turn_*.py` (iteration prep, API call, API error, overflow, truncation, recovery), constructor wiring in `agent/agent_init.py`, and everything from prompt assembly to tool dispatch to provider failover in focused `agent/*.py` modules mixed into `AIAgent`.
## Core Responsibilities
@@ -149,7 +149,7 @@ for each tool_call in response.tool_calls:
### Agent-Level Tools
Some tools are intercepted by `run_agent.py` *before* reaching `handle_function_call()`:
Some tools are intercepted by `agent/tool_executor.py` (called from `agent/conversation_loop.py`) *before* reaching `handle_function_call()`:
| Tool | Why intercepted |
|------|--------------------|
@@ -222,7 +222,10 @@ After each turn:
| File | Purpose |
|------|---------|
| `run_agent.py` | AIAgent class — the complete agent loop |
| `run_agent.py` | `AIAgent` facade — public entry points; loop and turn phases live in `agent/` |
| `agent/conversation_loop.py` | The agent loop (`run_conversation()` body) |
| `agent/turn_*.py` | Turn phases: iteration_prep, api_call, api_error, overflow, truncation, recovery |
| `agent/tool_executor.py` | Tool-call execution and agent-level tool interception |
| `agent/prompt_builder.py` | System prompt assembly from memory, skills, context files, personality |
| `agent/context_engine.py` | ContextEngine ABC — pluggable context management |
| `agent/context_compressor.py` | Default engine — lossy summarization algorithm |

View File

@@ -52,11 +52,11 @@ This page is the top-level map of Hermes Agent internals. Use it to orient yours
```text
hermes-agent/
├── run_agent.py # AIAgent — core conversation loop (large file)
├── cli.py # HermesCLI — interactive terminal UI (large file)
├── run_agent.py # AIAgent facade — loop lives in agent/conversation_loop.py + agent/turn_*.py
├── cli.py # HermesCLI facade — mixins in hermes_cli/cli_*_mixin.py
├── model_tools.py # Tool discovery, schema collection, dispatch
├── toolsets.py # Tool groupings and platform presets
├── hermes_state.py # SQLite session/state database with FTS5
├── hermes_state.py # SQLite session/state database facade (+ hermes_state_*.py siblings)
├── hermes_constants.py # HERMES_HOME, profile-aware paths
├── batch_runner.py # Batch trajectory generation
│
@@ -76,14 +76,14 @@ hermes-agent/
│ └── trajectory.py # Trajectory saving helpers
│
├── hermes_cli/ # CLI subcommands and setup
│ ├── main.py # Entry point — all `hermes` subcommands (large file)
│ ├── main.py # Entry point — `hermes` subcommands (parsers in subcommands/, main_*.py)
│ ├── config.py # DEFAULT_CONFIG, OPTIONAL_ENV_VARS, migration
│ ├── commands.py # COMMAND_REGISTRY — central slash command definitions
│ ├── auth.py # PROVIDER_REGISTRY, credential resolution
│ ├── auth.py # PROVIDER_REGISTRY, credential resolution (+ auth_*.py siblings)
│ ├── runtime_provider.py # Provider → api_mode + credentials
│ ├── models.py # Model catalog, provider model lists
│ ├── model_switch.py # /model command logic (CLI + gateway shared)
│ ├── setup.py # Interactive setup wizard (large file)
│ ├── setup.py # Interactive setup wizard (+ setup_*.py siblings)
│ ├── skin_engine.py # CLI theming engine
│ ├── skills_config.py # hermes skills — enable/disable per platform
│ ├── skills_hub.py # /skills slash command
@@ -99,17 +99,17 @@ hermes-agent/
│ ├── process_registry.py # Background process management
│ ├── file_tools.py # read_file, write_file, patch, search_files
│ ├── web_tools.py # web_search, web_extract
│ ├── browser_tool.py # 10 browser automation tools
│ ├── browser_tool.py # Browser automation tools facade (+ browser_tool_*.py siblings)
│ ├── code_execution_tool.py # execute_code sandbox
│ ├── delegate_tool.py # Subagent delegation
│ ├── mcp_tool.py # MCP client (large file)
│ ├── mcp_tool.py # MCP client facade (+ mcp_tool_*.py siblings)
│ ├── credential_files.py # File-based credential passthrough
│ ├── env_passthrough.py # Env var passthrough for sandboxes
│ ├── ansi_strip.py # ANSI escape stripping
│ └── environments/ # Terminal backends (local, docker, ssh, modal, daytona, singularity)
│
├── gateway/ # Messaging platform gateway
│ ├── run.py # GatewayRunner — message dispatch (large file)
│ ├── run.py # GatewayRunner facade — message dispatch (+ run_*.py siblings)
│ ├── session.py # SessionStore — conversation persistence
│ ├── delivery.py # Outbound message delivery
│ ├── pairing.py # DM pairing authorization
@@ -191,7 +191,7 @@ If you are new to the codebase:
### Agent Loop
The synchronous orchestration engine (`AIAgent` in `run_agent.py`). Handles provider selection, prompt construction, tool execution, retries, fallback, callbacks, compression, and persistence. Supports three API modes for different provider backends.
The synchronous orchestration engine (`AIAgent`, exposed by the `run_agent.py` facade; the loop lives in `agent/conversation_loop.py` and `agent/turn_*.py`). Handles provider selection, prompt construction, tool execution, retries, fallback, callbacks, compression, and persistence. Supports three API modes for different provider backends.
→ [Agent Loop Internals](./agent-loop.md)

View File

@@ -18,7 +18,7 @@ Hermes is a large repository, and most contributions touch exactly one subsystem
| Plugins system | `plugins/` | [Build a Hermes Plugin](plugins/index.md) |
| Skills (bundled & optional) | `skills/`, `optional-skills/` | [Creating Skills](creating-skills.md) |
| Cron / scheduled jobs | `cron/` | [Cron Internals](cron-internals.md) |
| Session storage | `hermes_state.py` | [Session Storage](session-storage.md) |
| Session storage | `hermes_state.py`, `hermes_state_*.py` | [Session Storage](session-storage.md) |
| Browser stack | `tools/browser_tool.py`, `tools/browser_supervisor.py`, `tools/browser_cdp_tool.py` | [Browser Supervisor](browser-supervisor.md) |
| Egress firewall | `agent/proxy_sources/iron_proxy.py` | [Egress Internals](egress-internals.md) |
| ACP (IDE integration) | `acp_adapter/` | [ACP Internals](acp-internals.md) |

View File

@@ -4,7 +4,7 @@ Hermes Agent uses a dual compression system and Anthropic prompt caching to
manage context window usage efficiently across long conversations.
Source files: `agent/context_engine.py` (ABC), `agent/context_compressor.py` (default engine),
`agent/prompt_caching.py`, `gateway/run.py` (session hygiene), `run_agent.py` (search for `_compress_context`)
`agent/prompt_caching.py`, `gateway/run_turn.py` (session hygiene), `agent/compression_facade.py` (search for `_compress_context`)
## Pluggable Context Engine
@@ -53,7 +53,7 @@ Hermes has two separate compression layers that operate independently:
### 1. Gateway Session Hygiene (85% threshold)
Located in `gateway/run.py` (search for `Session hygiene: auto-compress`). This is a **safety net** that
Located in `gateway/run_turn.py` (search for `Session hygiene`). This is a **safety net** that
runs before the agent processes a message. It prevents API failures when sessions
grow too large between turns (e.g., overnight accumulation in Telegram/Discord).
@@ -551,4 +551,4 @@ The CLI shows caching status at startup:
## Context Pressure Warnings
Intermediate context-pressure warnings have been removed (see the iteration-budget block in `run_agent.py`, which notes: "No intermediate pressure warnings — they caused models to 'give up' prematurely on complex tasks"). Compression fires when prompt tokens reach the configured `compression.threshold` (default 50%) with no prior warning step; gateway session hygiene fires as the secondary safety net at 85% of the model's context window.
Intermediate context-pressure warnings have been removed (see the iteration-budget block in `agent/turn_iteration_prep.py`, which notes: "No intermediate pressure warnings — they caused models to 'give up' prematurely on complex tasks"). Compression fires when prompt tokens reach the configured `compression.threshold` (default 50%) with no prior warning step; gateway session hygiene fires as the secondary safety net at 85% of the model's context window.

View File

@@ -22,7 +22,8 @@ hermes_cli/proxy_cli.py Wizard + slash command handlers.
status,disable,config}`. Wires the
core module into argparse.
hermes_cli/main.py:_dispatch_egress Top-level subparser dispatcher.
hermes_cli/subcommands/egress.py:_dispatch_egress
Top-level subparser dispatcher.
dest='egress_command' (intentionally
disjoint from the inbound OAuth
`hermes proxy` subparser, which uses

View File

@@ -170,7 +170,7 @@ Hermes supports a configured fallback provider chain — a list of `(provider, m
1. **Storage**: `AIAgent.__init__` stores the `fallback_model` dict and sets `_fallback_activated = False`.
2. **Trigger points**: `_try_activate_fallback()` is called from three places in the main retry loop in `run_agent.py`:
2. **Trigger points**: `_try_activate_fallback()` (forwarded to `try_activate_fallback()` in `agent/chat_completion_helpers.py`) is called from three places in the turn phases (`agent/turn_api_error.py`, `agent/turn_response_check.py`, `agent/turn_recovery.py`):
- After max retries on invalid API responses (None choices, missing content)
- On non-retryable client errors (HTTP 401, 403, 404)
- After max retries on transient errors (HTTP 429, 500, 502, 503)
@@ -187,7 +187,7 @@ Hermes supports a configured fallback provider chain — a list of `(provider, m
4. **Config flow**:
- CLI: reads the fallback chain via `hermes_cli/fallback_config.get_fallback_chain()` → passes to `AIAgent(fallback_model=...)`
- Gateway: `gateway/run.py._load_fallback_model()` reads `config.yaml` → passes to `AIAgent`
- Gateway: `gateway/run_config_loaders.py._load_fallback_model()` reads `config.yaml` → passes to `AIAgent`
- Validation: both `provider` and `model` keys must be non-empty, or fallback is disabled
### What does NOT support fallback

View File

@@ -4,7 +4,7 @@ Hermes Agent uses a SQLite database (`~/.hermes/state.db`) to persist session
metadata, full message history, and model configuration across CLI and gateway
sessions. This replaces the earlier per-session JSONL file approach.
Source file: `hermes_state.py`
Source files: `hermes_state.py` (facade) plus the `hermes_state_*.py` siblings (schema, fts, search, compression, portability, gateway, ...)
## Architecture Overview
@@ -42,7 +42,7 @@ Key design decisions:
### Sessions Table
Abridged — see `SCHEMA_SQL` in `hermes_state.py` for the full current column list
Abridged — see `SCHEMA_SQL` in `hermes_state_common.py` (applied by `hermes_state_schema.py`) for the full current column list
(which also includes gateway routing metadata such as `session_key`, `chat_id`,
`chat_type`, `thread_id`, `display_name`, `origin_json`, `expiry_finalized`,
workspace fields `cwd` / `git_branch` / `git_repo_root`, handoff and
@@ -142,7 +142,7 @@ The FTS5 table is kept in sync via three triggers that fire on INSERT, UPDATE,
and DELETE of the `messages` table. The current triggers are gated on the
`fts_rebuild_high_water` / `fts_rebuild_progress` markers in `state_meta` (so a
background FTS rebuild can proceed without double-indexing) and cover all three
indexed columns — see `SCHEMA_SQL` in `hermes_state.py` for the exact SQL.
indexed columns — see `SCHEMA_SQL` in `hermes_state_common.py` for the exact SQL.
## Schema Version and Migrations

View File

@@ -3,7 +3,7 @@
Hermes Agent saves conversation trajectories in ShareGPT-compatible JSONL format
for use as training data, debugging artifacts, and reinforcement learning datasets.
Source files: `agent/trajectory.py`, `run_agent.py` (search for `_save_trajectory`), `batch_runner.py`
Source files: `agent/trajectory.py`, `agent/session_persistence.py` (search for `_save_trajectory`), `batch_runner.py`
## File Naming Convention