docs: stabilize website diagrams

This commit is contained in:
teknium1
2026-03-14 22:49:57 -07:00
parent d5b64ebdb3
commit 259208bfe4
18 changed files with 1504 additions and 112 deletions

39
.github/workflows/docs-site-checks.yml vendored Normal file
View File

@@ -0,0 +1,39 @@
name: Docs Site Checks
on:
pull_request:
paths:
- 'website/**'
- '.github/workflows/docs-site-checks.yml'
workflow_dispatch:
jobs:
docs-site-checks:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
cache-dependency-path: website/package-lock.json
- name: Install website dependencies
run: npm ci
working-directory: website
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install ascii-guard
run: python -m pip install ascii-guard
- name: Lint docs diagrams
run: npm run lint:diagrams
working-directory: website
- name: Build Docusaurus
run: npm run build
working-directory: website

View File

@@ -26,7 +26,7 @@ Make it a **Tool** when:
Bundled skills live in `skills/` organized by category. Official optional skills use the same structure in `optional-skills/`: Bundled skills live in `skills/` organized by category. Official optional skills use the same structure in `optional-skills/`:
``` ```text
skills/ skills/
├── research/ ├── research/
│ └── arxiv/ │ └── arxiv/

View File

@@ -28,34 +28,48 @@ The Python environment framework documented here lives under the repo's `environ
The environment system is built on a three-layer inheritance chain: The environment system is built on a three-layer inheritance chain:
``` ```mermaid
Atropos Framework classDiagram
┌───────────────────────┐ class BaseEnv {
│ BaseEnv │ (atroposlib) Server management
│ - Server management │ Worker scheduling
│ - Worker scheduling │ Wandb logging
│ - Wandb logging │ CLI: serve / process / evaluate
│ - CLI (serve/process/ │ }
│ evaluate) │
└───────────┬───────────┘ class HermesAgentBaseEnv {
│ inherits Terminal backend configuration
┌───────────┴───────────┐ Tool resolution
│ HermesAgentBaseEnv │ environments/hermes_base_env.py Agent loop engine
│ - Terminal backend │ ToolContext access
│ - Tool resolution │ }
│ - Agent loop engine │
│ - ToolContext │ class TerminalTestEnv {
└───────────┬───────────┘ Stack testing
│ inherits }
┌─────────────────────┼─────────────────────┐
│ │ │ class HermesSweEnv {
TerminalTestEnv HermesSweEnv TerminalBench2EvalEnv SWE training
(stack testing) (SWE training) (benchmark eval) }
┌────────┼────────┐ class TerminalBench2EvalEnv {
│ │ Benchmark evaluation
TBLiteEvalEnv YCBenchEvalEnv }
(fast benchmark) (long-horizon)
class TBLiteEvalEnv {
Fast benchmark
}
class YCBenchEvalEnv {
Long-horizon benchmark
}
BaseEnv <|-- HermesAgentBaseEnv
HermesAgentBaseEnv <|-- TerminalTestEnv
HermesAgentBaseEnv <|-- HermesSweEnv
HermesAgentBaseEnv <|-- TerminalBench2EvalEnv
TerminalBench2EvalEnv <|-- TBLiteEvalEnv
TerminalBench2EvalEnv <|-- YCBenchEvalEnv
``` ```
### BaseEnv (Atropos) ### BaseEnv (Atropos)

View File

@@ -45,27 +45,8 @@ hermes -w -q "Fix issue #123" # Single query in worktree
## Interface Layout ## Interface Layout
```text <img className="docs-terminal-figure" src="/img/docs/cli-layout.svg" alt="Stylized preview of the Hermes CLI layout showing the banner, conversation area, and fixed input prompt." />
┌─────────────────────────────────────────────────┐ <p className="docs-figure-caption">The Hermes CLI banner, conversation stream, and fixed input prompt rendered as a stable docs figure instead of fragile text art.</p>
│ HERMES-AGENT ASCII Logo │
│ ┌─────────────┐ ┌────────────────────────────┐ │
│ │ Caduceus │ │ Model: claude-sonnet-4 │ │
│ │ ASCII Art │ │ Terminal: local │ │
│ │ │ │ Working Dir: /home/user │ │
│ │ │ │ Available Tools: 19 │ │
│ │ │ │ Available Skills: 12 │ │
│ └─────────────┘ └────────────────────────────┘ │
├─────────────────────────────────────────────────┤
│ Conversation output scrolls here... │
│ │
│ (◕‿◕✿) 🧠 pondering... (2.3s) │
│ ✧٩(ˊᗜˋ*)و✧ got it! (2.3s) │
│ │
│ Assistant: Hello! How can I help you today? │
├─────────────────────────────────────────────────┤
[Fixed input area at bottom] │
└─────────────────────────────────────────────────┘
```
The welcome banner shows your model, terminal backend, working directory, available tools, and installed skills at a glance. The welcome banner shows your model, terminal backend, working directory, available tools, and installed skills at a glance.

View File

@@ -100,7 +100,7 @@ In the current implementation, distributions assign a probability to **each indi
All output goes to `data/<run_name>/`: All output goes to `data/<run_name>/`:
``` ```text
data/my_run/ data/my_run/
├── trajectories.jsonl # Combined final output (all batches merged) ├── trajectories.jsonl # Combined final output (all batches merged)
├── batch_0.jsonl # Individual batch results ├── batch_0.jsonl # Individual batch results

View File

@@ -103,7 +103,7 @@ Context files are loaded by `build_context_files_prompt()` in `agent/prompt_buil
The final prompt section looks roughly like: The final prompt section looks roughly like:
``` ```text
# Project Context # Project Context
The following project context files have been loaded and should be followed: The following project context files have been loaded and should be followed:

View File

@@ -207,16 +207,17 @@ honcho: {}
Honcho context is fetched asynchronously to avoid blocking the response path: Honcho context is fetched asynchronously to avoid blocking the response path:
``` ```mermaid
Turn N: flowchart TD
user message user["User message"] --> cache["Consume cached Honcho context<br/>from the previous turn"]
→ consume cached context (from previous turn's background fetch) cache --> prompt["Inject user, AI, and dialectic context<br/>into the system prompt"]
→ inject into system prompt (user representation, AI representation, dialectic) prompt --> llm["LLM call"]
→ LLM call llm --> response["Assistant response"]
response response --> fetch["Start background fetch for Turn N+1"]
→ fire background fetch for next turn fetch --> ctx["Fetch context"]
→ fetch context ─┐ fetch --> dia["Fetch dialectic"]
→ fetch dialectic ─┴→ cache for Turn N+1 ctx --> next["Cache for the next turn"]
dia --> next
``` ```
Turn 1 is a cold start (no cache). All subsequent turns consume cached results with zero HTTP latency on the response path. The system prompt on turn 1 uses only static context to preserve prefix cache hits at the LLM provider. Turn 1 is a cold start (no cache). All subsequent turns consume cached results with zero HTTP latency on the response path. The system prompt on turn 1 uses only static context to preserve prefix cache hits at the LLM provider.

View File

@@ -12,7 +12,7 @@ The hooks system lets you run custom code at key points in the agent lifecycle
Each hook is a directory under `~/.hermes/hooks/` containing two files: Each hook is a directory under `~/.hermes/hooks/` containing two files:
``` ```text
~/.hermes/hooks/ ~/.hermes/hooks/
└── my-hook/ └── my-hook/
├── HOOK.yaml # Declares which events to listen for ├── HOOK.yaml # Declares which events to listen for

View File

@@ -174,21 +174,17 @@ The training loop:
## Architecture Diagram ## Architecture Diagram
``` ```mermaid
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐ flowchart LR
Atropos API │◄────│ Environment │────►│ OpenAI/sglang │ api["Atropos API<br/>run-api<br/>port 8000"]
(run-api) │ │ (BaseEnv impl) │ │ Inference API │ env["Environment<br/>BaseEnv implementation"]
│ Port 8000 │ │ │ │ Port 8001 infer["OpenAI / sglang<br/>inference API<br/>port 8001"]
└────────┬────────┘ └──────────────────┘ └────────┬────────┘ trainer["Tinker Trainer<br/>LoRA training + FastAPI"]
│ │
│ Batches (tokens + scores + logprobs) │ env <--> api
│ │ env --> infer
▼ │ api -->|"batches: tokens, scores, logprobs"| trainer
┌─────────────────┐ │ trainer -->|"serves inference"| infer
│ Tinker Trainer │◄──────────────────────────────────────┘
│ (LoRA training) │ Serves inference via FastAPI
│ + FastAPI │ Trains via Tinker ServiceClient
└─────────────────┘
``` ```
## Creating Custom Environments ## Creating Custom Environments

View File

@@ -140,7 +140,7 @@ When a missing value is encountered, Hermes asks for it securely only when the s
## Skill Directory Structure ## Skill Directory Structure
``` ```text
~/.hermes/skills/ # Single source of truth ~/.hermes/skills/ # Single source of truth
├── mlops/ # Category directory ├── mlops/ # Category directory
│ ├── axolotl/ │ ├── axolotl/

View File

@@ -12,29 +12,33 @@ For the full voice feature set — including CLI microphone mode, spoken replies
## Architecture ## Architecture
```text ```mermaid
┌───────────────────────────────────────────────────────────────────────────────────────┐ flowchart TB
Hermes Gateway │ subgraph Gateway["Hermes Gateway"]
├───────────────────────────────────────────────────────────────────────────────────────┤ subgraph Adapters["Platform adapters"]
tg[Telegram]
┌──────────┐ ┌─────────┐ ┌──────────┐ ┌───────┐ ┌───────┐ ┌───────┐ ┌────┐ │ dc[Discord]
│ Telegram │ │ Discord │ │ WhatsApp │ │ Slack │ │Signal │ │ Email │ │ HA │ │ wa[WhatsApp]
│ Adapter │ │ Adapter │ │ Adapter │ │Adapter│ │Adapter│ │Adapter│ │Adpt│ │ sl[Slack]
└────┬─────┘ └────┬────┘ └────┬─────┘ └──┬────┘ └──┬────┘ └──┬────┘ └─┬──┘ │ sig[Signal]
│ │ │ │ │ │ │ │ em[Email]
└─────────────┴───────────┴───────────┴─────────┴─────────┴────────┘ │ ha[Home Assistant]
│ │ │ end
│ ┌────────▼────────┐ │
Session Store │ │ store["Session store<br/>per chat"]
│ (per-chat) │ │ agent["AIAgent<br/>run_agent.py"]
└────────┬────────┘ │ cron["Cron scheduler<br/>ticks every 60s"]
│ │ │ end
│ ┌────────▼────────┐ │
│ │ AIAgent │ │ tg --> store
│ │ (run_agent) │ │ dc --> store
│ └─────────────────┘ │ wa --> store
│ │ sl --> store
└───────────────────────────────────────────────────────────────────────────────────────┘ sig --> store
em --> store
ha --> store
store --> agent
cron --> store
``` ```
Each platform adapter receives messages, routes them through a per-chat session store, and dispatches them to the AIAgent for processing. The gateway also runs the cron scheduler, ticking every 60 seconds to execute any due jobs. Each platform adapter receives messages, routes them through a per-chat session store, and dispatches them to the AIAgent for processing. The gateway also runs the cron scheduler, ticking every 60 seconds to execute any due jobs.

View File

@@ -88,15 +88,8 @@ Session IDs are shown when you exit a CLI session, and can be found with `hermes
When you resume a session, Hermes displays a compact recap of the previous conversation in a styled panel before the input prompt: When you resume a session, Hermes displays a compact recap of the previous conversation in a styled panel before the input prompt:
```text <img className="docs-terminal-figure" src="/img/docs/session-recap.svg" alt="Stylized preview of the Previous Conversation recap panel shown when resuming a Hermes session." />
╭─────────────────────────── Previous Conversation ────────────────────────────╮ <p className="docs-figure-caption">Resume mode shows a compact recap panel with recent user and assistant turns before returning you to the live prompt.</p>
│ ● You: What is Python? │
│ ◆ Hermes: Python is a high-level programming language. │
│ ● You: How do I install it? │
│ ◆ Hermes: [3 tool calls: web_search, web_extract, terminal] │
│ ◆ Hermes: You can download Python from python.org... │
╰──────────────────────────────────────────────────────────────────────────────╯
```
The recap: The recap:
- Shows **user messages** (gold `●`) and **assistant responses** (green `◆`) - Shows **user messages** (gold `●`) and **assistant responses** (green `◆`)

View File

@@ -16,6 +16,7 @@ const config: Config = {
onBrokenLinks: 'warn', onBrokenLinks: 'warn',
markdown: { markdown: {
mermaid: true,
hooks: { hooks: {
onBrokenMarkdownLinks: 'warn', onBrokenMarkdownLinks: 'warn',
}, },
@@ -27,6 +28,7 @@ const config: Config = {
}, },
themes: [ themes: [
'@docusaurus/theme-mermaid',
[ [
require.resolve('@easyops-cn/docusaurus-search-local'), require.resolve('@easyops-cn/docusaurus-search-local'),
/** @type {import("@easyops-cn/docusaurus-search-local").PluginOptions} */ /** @type {import("@easyops-cn/docusaurus-search-local").PluginOptions} */
@@ -128,6 +130,9 @@ const config: Config = {
darkTheme: prismThemes.dracula, darkTheme: prismThemes.dracula,
additionalLanguages: ['bash', 'yaml', 'json', 'python', 'toml'], additionalLanguages: ['bash', 'yaml', 'json', 'python', 'toml'],
}, },
mermaid: {
theme: {light: 'neutral', dark: 'dark'},
},
} satisfies Preset.ThemeConfig, } satisfies Preset.ThemeConfig,
}; };

1262
website/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -12,11 +12,13 @@
"serve": "docusaurus serve", "serve": "docusaurus serve",
"write-translations": "docusaurus write-translations", "write-translations": "docusaurus write-translations",
"write-heading-ids": "docusaurus write-heading-ids", "write-heading-ids": "docusaurus write-heading-ids",
"typecheck": "tsc" "typecheck": "tsc",
"lint:diagrams": "ascii-guard lint docs"
}, },
"dependencies": { "dependencies": {
"@docusaurus/core": "3.9.2", "@docusaurus/core": "3.9.2",
"@docusaurus/preset-classic": "3.9.2", "@docusaurus/preset-classic": "3.9.2",
"@docusaurus/theme-mermaid": "^3.9.2",
"@easyops-cn/docusaurus-search-local": "^0.55.1", "@easyops-cn/docusaurus-search-local": "^0.55.1",
"@mdx-js/react": "^3.0.0", "@mdx-js/react": "^3.0.0",
"clsx": "^2.0.0", "clsx": "^2.0.0",

View File

@@ -89,6 +89,56 @@
border: 1px solid rgba(255, 215, 0, 0.06); border: 1px solid rgba(255, 215, 0, 0.06);
} }
/* Text diagrams: preserve spacing, disable ligatures, and prefer box-drawing-safe fonts */
pre.prism-code.language-text,
pre.prism-code.language-plaintext,
pre.prism-code.language-txt,
pre.prism-code.language-ascii {
white-space: pre;
overflow-x: auto;
line-height: 1.35;
font-family: 'JetBrains Mono', 'Cascadia Mono', 'Cascadia Code', 'Fira Code', 'SFMono-Regular', 'DejaVu Sans Mono', 'Liberation Mono', monospace;
font-variant-ligatures: none;
font-feature-settings: "liga" 0, "calt" 0;
text-rendering: optimizeSpeed;
}
pre.prism-code.language-text code,
pre.prism-code.language-plaintext code,
pre.prism-code.language-txt code,
pre.prism-code.language-ascii code {
white-space: pre;
font-variant-ligatures: none;
font-feature-settings: "liga" 0, "calt" 0;
}
.theme-mermaid {
margin: 1.5rem 0;
text-align: center;
}
.theme-mermaid svg {
max-width: 100%;
height: auto;
}
.docs-terminal-figure {
display: block;
width: 100%;
max-width: 900px;
margin: 1.25rem auto 0.5rem;
border: 1px solid rgba(255, 215, 0, 0.08);
border-radius: 12px;
background: #0a0a12;
}
.docs-figure-caption {
margin-top: 0.35rem;
text-align: center;
color: var(--ifm-font-color-secondary);
font-size: 0.95rem;
}
/* Admonitions — gold-tinted */ /* Admonitions — gold-tinted */
[data-theme='dark'] .alert--info { [data-theme='dark'] .alert--info {
--ifm-alert-background-color: rgba(255, 215, 0, 0.05); --ifm-alert-background-color: rgba(255, 215, 0, 0.05);

View File

@@ -0,0 +1,32 @@
<svg xmlns="http://www.w3.org/2000/svg" width="960" height="520" viewBox="0 0 960 520" role="img" aria-labelledby="title desc">
<title id="title">Hermes CLI interface layout</title>
<desc id="desc">Stylized terminal window showing the Hermes CLI banner, conversation area, and fixed input prompt.</desc>
<rect width="960" height="520" rx="18" fill="#07070d"/>
<rect x="18" y="18" width="924" height="484" rx="14" fill="#0a0a12" stroke="#2b2410"/>
<rect x="18" y="18" width="924" height="42" rx="14" fill="#11111a" stroke="#2b2410"/>
<circle cx="48" cy="39" r="8" fill="#ff5f56"/>
<circle cx="74" cy="39" r="8" fill="#ffbd2e"/>
<circle cx="100" cy="39" r="8" fill="#27c93f"/>
<text x="480" y="44" text-anchor="middle" fill="#e8e4dc" font-family="Inter, sans-serif" font-size="18" font-weight="600">Hermes CLI</text>
<rect x="48" y="86" width="864" height="136" rx="12" fill="#0f0f18" stroke="#3a3217"/>
<text x="72" y="112" fill="#ffd700" font-family="JetBrains Mono, monospace" font-size="16">HERMES AGENT</text>
<rect x="72" y="126" width="190" height="72" rx="10" fill="#11111a" stroke="#4b3f12"/>
<text x="92" y="150" fill="#ffdd66" font-family="JetBrains Mono, monospace" font-size="14">Caduceus banner</text>
<text x="92" y="172" fill="#9a968e" font-family="JetBrains Mono, monospace" font-size="13">Model, terminal, tools,</text>
<text x="92" y="190" fill="#9a968e" font-family="JetBrains Mono, monospace" font-size="13">skills, working dir</text>
<rect x="292" y="126" width="590" height="72" rx="10" fill="#11111a" stroke="#4b3f12"/>
<text x="316" y="150" fill="#e8e4dc" font-family="JetBrains Mono, monospace" font-size="14">Model: anthropic/claude-sonnet-4</text>
<text x="316" y="172" fill="#e8e4dc" font-family="JetBrains Mono, monospace" font-size="14">Terminal: local Working dir: /home/user/project</text>
<text x="316" y="194" fill="#e8e4dc" font-family="JetBrains Mono, monospace" font-size="14">Tools: 19 Skills: 12 Session: 20260315_123456_abcd1234</text>
<rect x="48" y="246" width="864" height="182" rx="12" fill="#0f0f18" stroke="#2b2410"/>
<text x="72" y="278" fill="#9a968e" font-family="JetBrains Mono, monospace" font-size="14">Conversation output</text>
<text x="72" y="320" fill="#ffdd66" font-family="JetBrains Mono, monospace" font-size="15">┊ terminal: git status</text>
<text x="72" y="350" fill="#7ce38b" font-family="JetBrains Mono, monospace" font-size="15">Hermes: Working tree is clean. Ready for the next task.</text>
<text x="72" y="380" fill="#9a968e" font-family="JetBrains Mono, monospace" font-size="15">Hermes streams tool progress and responses here.</text>
<rect x="48" y="448" width="864" height="30" rx="10" fill="#11111a" stroke="#4b3f12"/>
<text x="72" y="468" fill="#ffd700" font-family="JetBrains Mono, monospace" font-size="15"></text>
<text x="98" y="468" fill="#e8e4dc" font-family="JetBrains Mono, monospace" font-size="15">Fixed input area at the bottom with slash-command autocomplete</text>
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@@ -0,0 +1,13 @@
<svg xmlns="http://www.w3.org/2000/svg" width="960" height="250" viewBox="0 0 960 250" role="img" aria-labelledby="title desc">
<title id="title">Hermes session recap panel</title>
<desc id="desc">Stylized panel showing the previous conversation summary displayed when resuming a session.</desc>
<rect width="960" height="250" rx="18" fill="#07070d"/>
<rect x="24" y="24" width="912" height="202" rx="16" fill="#0a0a12" stroke="#3a3217"/>
<text x="480" y="56" text-anchor="middle" fill="#ffd700" font-family="Inter, sans-serif" font-size="20" font-weight="600">Previous Conversation</text>
<line x1="48" y1="72" x2="912" y2="72" stroke="#2b2410"/>
<text x="64" y="106" fill="#ffdd66" font-family="JetBrains Mono, monospace" font-size="15">● You: What is Python?</text>
<text x="64" y="136" fill="#7ce38b" font-family="JetBrains Mono, monospace" font-size="15">◆ Hermes: Python is a high-level programming language.</text>
<text x="64" y="166" fill="#ffdd66" font-family="JetBrains Mono, monospace" font-size="15">● You: How do I install it?</text>
<text x="64" y="196" fill="#7ce38b" font-family="JetBrains Mono, monospace" font-size="15">◆ Hermes: [3 tool calls: web_search, web_extract, terminal]</text>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB