opentui(phase3): launcher integration — HERMES_TUI_ENGINE dual-engine
hermes --tui launches the native OpenTUI engine (Bun) when HERMES_TUI_ENGINE=opentui (env) or display.tui_engine=opentui (config); Ink stays the default and the shipping path is untouched. - _resolve_tui_engine() (env > config > ink); refuses opentui on Windows/Termux (no Bun) -> falls back to ink with a notice. - _make_opentui_argv() -> [bun, src/entry.real.tsx] (no build step). - _bun_bin() with HERMES_BUN override. - Branch at top of _make_tui_argv BEFORE _ensure_tui_node (Bun-only host must not bootstrap Node). - Gate _launch_tui NODE_OPTIONS/--max-old-space-size on engine==ink (Bun is JSC; the V8 flag errors/ignores). Verified end-to-end via tmux: real hermes --tui -> Bun -> OpenTUI -> real Python gateway streamed a real reply. No-flag default still ink.
This commit is contained in:
@@ -533,17 +533,6 @@ skills:
|
||||
|
||||
When on, any flagged `skill_manage` write surfaces as an approval prompt with the scanner's rationale. Accepted writes land; denied writes return an explanatory error to the agent.
|
||||
|
||||
### Write approval for skill writes
|
||||
|
||||
Independent of the content scanner above, `skills.write_approval` gates **every** agent skill write (create / edit / patch / delete / supporting files) behind your explicit approval — the same approve/deny mechanism as dangerous commands:
|
||||
|
||||
```yaml
|
||||
skills:
|
||||
write_approval: false # false = write freely (default) | true = stage every write for review
|
||||
```
|
||||
|
||||
When on, skill writes are staged under `~/.hermes/pending/skills/` and reviewed with `/skills pending`, `/skills diff <id>`, `/skills approve <id>`, `/skills reject <id>` — from the CLI or any messaging platform. Toggle at runtime with `/skills approval on|off`. Memory has the same gate (`memory.write_approval`, below). Full walkthrough: [Gating agent skill writes](/user-guide/features/skills#gating-agent-skill-writes-skillswrite_approval).
|
||||
|
||||
## Memory Configuration
|
||||
|
||||
```yaml
|
||||
@@ -552,11 +541,8 @@ memory:
|
||||
user_profile_enabled: true
|
||||
memory_char_limit: 2200 # ~800 tokens
|
||||
user_char_limit: 1375 # ~500 tokens
|
||||
write_approval: false # true = require approval before any memory write
|
||||
```
|
||||
|
||||
With `memory.write_approval: true`, memory writes need your approval before they land: interactive CLI turns prompt inline; messaging sessions and the background self-improvement review stage the write for `/memory pending` → `/memory approve <id>` / `/memory reject <id>` review. Toggle at runtime with `/memory approval on|off`. See [Controlling memory writes](/user-guide/features/memory#controlling-memory-writes-write_approval).
|
||||
|
||||
## File Read Safety
|
||||
|
||||
Controls how much content a single `read_file` call can return. Reads that exceed the limit are rejected with an error telling the agent to use `offset` and `limit` for a smaller range. This prevents a single read of a minified JS bundle or large data file from flooding the context window.
|
||||
@@ -849,7 +835,6 @@ $ hermes model
|
||||
[ ] vision currently: auto / main model
|
||||
[ ] web_extract currently: auto / main model
|
||||
[ ] title_generation currently: openrouter / google/gemini-3-flash-preview
|
||||
[ ] tts_audio_tags currently: auto / main model
|
||||
[ ] compression currently: auto / main model
|
||||
[ ] approval currently: auto / main model
|
||||
[ ] triage_specifier currently: auto / main model
|
||||
@@ -926,14 +911,6 @@ auxiliary:
|
||||
api_key: ""
|
||||
timeout: 30 # seconds
|
||||
|
||||
# Gemini 3.1 TTS hidden audio-tag insertion
|
||||
tts_audio_tags:
|
||||
provider: "auto"
|
||||
model: "" # empty = main chat model
|
||||
base_url: ""
|
||||
api_key: ""
|
||||
timeout: 30
|
||||
|
||||
# Context compression timeout (separate from compression.* config)
|
||||
compression:
|
||||
timeout: 120 # seconds — compression summarizes long conversations, needs more time
|
||||
@@ -1138,17 +1115,6 @@ agent:
|
||||
|
||||
When unset (default), reasoning effort defaults to "medium" — a balanced level that works well for most tasks. Setting a value overrides it — higher reasoning effort gives better results on complex tasks at the cost of more tokens and latency.
|
||||
|
||||
:::note Adaptive-thinking models (Claude 4.6+, Fable/Mythos-class) over OpenRouter
|
||||
These models use *adaptive* thinking and don't accept the usual `reasoning.effort`
|
||||
field — OpenRouter ignores it for them. Hermes transparently routes your
|
||||
`reasoning_effort` to OpenRouter's `verbosity` parameter instead (which maps to
|
||||
Anthropic's `output_config.effort`), so the same `low`/`medium`/`high`/`xhigh`
|
||||
knob keeps working — no extra configuration needed. `none` (or unset) leaves the
|
||||
model on its own adaptive default. (`max` is accepted on the wire but is not a
|
||||
selectable `reasoning_effort` value; `xhigh` is the configurable ceiling.) The
|
||||
native Anthropic provider already controls effort directly and is unaffected.
|
||||
:::
|
||||
|
||||
You can also change the reasoning effort at runtime with the `/reasoning` command:
|
||||
|
||||
```
|
||||
@@ -1220,10 +1186,8 @@ tts:
|
||||
model: "voxtral-mini-tts-2603"
|
||||
voice_id: "c69964a6-ab8b-4f8a-9465-ec0925096ec8" # Paul - Neutral (default)
|
||||
gemini:
|
||||
model: "gemini-2.5-flash-preview-tts" # or gemini-3.1-flash-tts-preview
|
||||
model: "gemini-2.5-flash-preview-tts" # or gemini-2.5-pro-preview-tts
|
||||
voice: "Kore" # 30 prebuilt voices: Zephyr, Puck, Kore, Enceladus, etc.
|
||||
audio_tags: false # Hidden Gemini 3.1 TTS audio-tag insertion
|
||||
persona_prompt_file: "" # Optional Markdown/text file with Gemini voice direction
|
||||
xai:
|
||||
voice_id: "eve" # xAI TTS voice
|
||||
language: "en" # ISO 639-1
|
||||
@@ -1453,25 +1417,6 @@ The master `streaming.enabled` switch is `false` by default — nothing streams
|
||||
|
||||
## Group Chat Session Isolation
|
||||
|
||||
Limit how many chat sessions can actively be open across CLI, TUI/dashboard,
|
||||
and messaging gateway:
|
||||
|
||||
```yaml
|
||||
max_concurrent_sessions: null # null/0 = unlimited; positive integer = active session cap
|
||||
```
|
||||
|
||||
When the cap is reached, Hermes returns a direct limit message for new sessions.
|
||||
Existing active sessions keep their normal behavior.
|
||||
|
||||
The canonical key is top-level `max_concurrent_sessions`. Hermes also accepts
|
||||
`gateway.max_concurrent_sessions` as a fallback, but the top-level key wins when
|
||||
both are set.
|
||||
|
||||
The cap is enforced with a local runtime lease file and is best-effort: Hermes
|
||||
fails open if the registry cannot be read or locked so users are not stranded.
|
||||
It is intended for a single host/profile runtime, not a shared `$HERMES_HOME`
|
||||
mounted across multiple machines.
|
||||
|
||||
Control whether shared chats keep one conversation per room or one conversation per participant:
|
||||
|
||||
```yaml
|
||||
|
||||
Reference in New Issue
Block a user