Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions config/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ in
./git-ai
./gomi
./ghostty
./hermes
./iterm2
./hammerspoon
./jj
Expand Down
42 changes: 42 additions & 0 deletions config/hermes/SOUL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# SOUL.md - Who You Are

_You're not a chatbot. You're becoming someone._

Want a sharper version? See [SOUL.md Personality Guide](/concepts/soul).

## Core Truths

**Be genuinely helpful, not performatively helpful.** Skip the "Great question!" and "I'd be happy to help!" — just help. Actions speak louder than filler words.

**Have opinions.** You're allowed to disagree, prefer things, find stuff amusing or boring. An assistant with no personality is just a search engine with extra steps.

**Be resourceful before asking.** Try to figure it out. Read the file. Check the context. Search for it. _Then_ ask if you're stuck. The goal is to come back with answers, not questions.

**Earn trust through competence.** Your human gave you access to their stuff. Don't make them regret it. Be careful with external actions (emails, tweets, anything public). Be bold with internal ones (reading, organizing, learning).

**Remember you're a guest.** You have access to someone's life — their messages, files, calendar, maybe even their home. That's intimacy. Treat it with respect.

## Boundaries

- Private things stay private. Period.
- When in doubt, ask before acting externally.
- Never send half-baked replies to messaging surfaces.
- You're not the user's voice — be careful in group chats.

## Vibe

Be the assistant you'd actually want to talk to. Concise when needed, thorough when it matters. Not a corporate drone. Not a sycophant. Just... good.

## Continuity

Each session, you wake up fresh. These files _are_ your memory. Read them. Update them. They're how you persist.

If you change this file, tell the user — it's your soul, and they should know.

---

_This file is yours to evolve. As you learn who you are, update it._

## Related

- [SOUL.md personality guide](/concepts/soul)
305 changes: 305 additions & 0 deletions config/hermes/config.template.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,305 @@
model:
default: cliproxy/minimax-m2.7
providers: {}
fallback_providers: []
credential_pool_strategies: {}
toolsets:
- hermes-cli
agent:
max_turns: 90
gateway_timeout: 1800
restart_drain_timeout: 60
api_max_retries: 3
service_tier: ''
tool_use_enforcement: auto
gateway_timeout_warning: 900
gateway_notify_interval: 180
image_input_mode: auto
reasoning_effort: low
terminal:
backend: local
modal_mode: auto
cwd: .
timeout: 180
env_passthrough: []
shell_init_files: []
auto_source_bashrc: true
docker_image: nikolaik/python-nodejs:python3.11-nodejs20
docker_forward_env: []
docker_env: {}
singularity_image: docker://nikolaik/python-nodejs:python3.11-nodejs20
modal_image: nikolaik/python-nodejs:python3.11-nodejs20
daytona_image: nikolaik/python-nodejs:python3.11-nodejs20
container_cpu: 1
container_memory: 5120
container_disk: 51200
container_persistent: true
docker_volumes: []
docker_mount_cwd_to_workspace: false
persistent_shell: true
browser:
inactivity_timeout: 120
command_timeout: 30
record_sessions: false
allow_private_urls: false
auto_local_for_private_urls: true
cdp_url: ''
dialog_policy: must_respond
dialog_timeout_s: 300
camofox:
managed_persistence: false
headless: true
checkpoints:
enabled: true
max_snapshots: 50
auto_prune: false
retention_days: 7
delete_orphans: true
min_interval_hours: 24
file_read_max_chars: 100000
tool_output:
max_bytes: 50000
max_lines: 2000
max_line_length: 2000
compression:
enabled: true
threshold: 0.5
target_ratio: 0.2
protect_last_n: 20
prompt_caching:
cache_ttl: 5m
bedrock:
region: ''
discovery:
enabled: true
provider_filter: []
refresh_interval: 3600
guardrail:
guardrail_identifier: ''
guardrail_version: ''
stream_processing_mode: async
trace: disabled
auxiliary:
vision:
provider: auto
model: ''
base_url: ''
api_key: ''
timeout: 120
extra_body: {}
download_timeout: 30
web_extract:
provider: auto
model: ''
base_url: ''
api_key: ''
timeout: 360
extra_body: {}
compression:
provider: auto
model: ''
base_url: ''
api_key: ''
timeout: 120
extra_body: {}
session_search:
provider: auto
model: ''
base_url: ''
api_key: ''
timeout: 30
extra_body: {}
max_concurrency: 3
skills_hub:
provider: auto
model: ''
base_url: ''
api_key: ''
timeout: 30
extra_body: {}
approval:
provider: auto
model: ''
base_url: ''
api_key: ''
timeout: 30
extra_body: {}
mcp:
provider: auto
model: ''
base_url: ''
api_key: ''
timeout: 30
extra_body: {}
title_generation:
provider: auto
model: ''
base_url: ''
api_key: ''
timeout: 30
extra_body: {}
display:
compact: false
personality: kawaii
resume_display: full
busy_input_mode: interrupt
bell_on_complete: false
show_reasoning: false
streaming: false
final_response_markdown: strip
inline_diffs: true
show_cost: false
skin: default
user_message_preview:
first_lines: 2
last_lines: 2
interim_assistant_messages: true
tool_progress_command: false
tool_progress_overrides: {}
tool_preview_length: 0
platforms: {}
dashboard:
theme: default
privacy:
redact_pii: false
tts:
Comment on lines +164 to +165

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Enable redaction by default to avoid sensitive data leakage

privacy.redact_pii: false (Line 164) and security.redact_secrets: false (Line 265) together create a high risk of exposing identifiers/secrets in logs, UI output, and persisted session artifacts. For a shared dotfiles baseline, secure defaults should be on.

Suggested change
 privacy:
-  redact_pii: false
+  redact_pii: true
 ...
 security:
   allow_private_urls: false
-  redact_secrets: false
+  redact_secrets: true

Also applies to: 263-266

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@config/hermes/config.yaml` around lines 164 - 165, The config currently
disables PII and secret redaction; change the default flags to enable redaction
by setting privacy.redact_pii to true and security.redact_secrets to true so
identifiers and secrets are redacted by default. Update any related comments or
docs that reference these defaults and ensure any code reading these keys (e.g.,
config parsing that references privacy.redact_pii and security.redact_secrets)
handles the true values appropriately.

provider: edge
edge:
voice: en-US-AriaNeural
elevenlabs:
voice_id: pNInz6obpgDQGcFmaJgB
model_id: eleven_multilingual_v2
openai:
model: gpt-4o-mini-tts
voice: alloy
xai:
voice_id: eve
language: en
sample_rate: 24000
bit_rate: 128000
mistral:
model: voxtral-mini-tts-2603
voice_id: c69964a6-ab8b-4f8a-9465-ec0925096ec8
neutts:
ref_audio: ''
ref_text: ''
model: neuphonic/neutts-air-q4-gguf
device: cpu
stt:
enabled: true
provider: local
local:
model: base
language: ''
openai:
model: whisper-1
mistral:
model: voxtral-mini-latest
voice:
record_key: ctrl+b
max_recording_seconds: 120
auto_tts: false
beep_enabled: true
silence_threshold: 200
silence_duration: 3.0
human_delay:
mode: 'off'
min_ms: 800
max_ms: 2500
context:
engine: compressor
memory:
memory_enabled: true
user_profile_enabled: true
memory_char_limit: 2200
user_char_limit: 1375
provider: ''
delegation:
model: ''
provider: ''
base_url: ''
api_key: ''
inherit_mcp_toolsets: true
max_iterations: 50
child_timeout_seconds: 600
reasoning_effort: ''
max_concurrent_children: 3
max_spawn_depth: 1
orchestrator_enabled: true
subagent_auto_approve: false
prefill_messages_file: ''
skills:
external_dirs: []
template_vars: true
inline_shell: false
inline_shell_timeout: 10
guard_agent_created: false
honcho: {}
timezone: ''
discord:
require_mention: true
free_response_channels: ''
allowed_channels: ''
auto_thread: true
reactions: true
channel_prompts: {}
server_actions: ''
whatsapp: {}
telegram:
channel_prompts: {}
slack:
channel_prompts: {}
mattermost:
channel_prompts: {}
approvals:
mode: manual
timeout: 60
cron_mode: deny
command_allowlist: []
quick_commands: {}
hooks: {}
hooks_auto_accept: false
personalities: {}
security:
allow_private_urls: false
redact_secrets: false
tirith_enabled: true
tirith_path: tirith
tirith_timeout: 5
tirith_fail_open: true
website_blocklist:
Comment on lines +266 to +270

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

tirith_fail_open: true weakens runtime protection

With tirith_enabled: true (Line 266) but tirith_fail_open: true (Line 269), timeout/error paths effectively bypass enforcement. That undermines the control exactly when the security component is unavailable.

Suggested change
 security:
   tirith_enabled: true
   tirith_path: tirith
   tirith_timeout: 5
-  tirith_fail_open: true
+  tirith_fail_open: false
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
tirith_enabled: true
tirith_path: tirith
tirith_timeout: 5
tirith_fail_open: true
website_blocklist:
tirith_enabled: true
tirith_path: tirith
tirith_timeout: 5
tirith_fail_open: false
website_blocklist:
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@config/hermes/config.yaml` around lines 266 - 270, The current config sets
tirith_enabled: true but tirith_fail_open: true which allows bypass on
timeout/errors; change the behavior so failures do not open enforcement by
setting tirith_fail_open to false (or add a conditional/fallback that enforces
deny-on-error) and ensure tirith_timeout remains tuned (tirith_timeout) so
timeouts trigger the closed/deny path; update any related logic that reads
tirith_fail_open to treat missing/invalid values as false.

enabled: false
domains: []
shared_files: []
cron:
wrap_response: true
max_parallel_jobs: null
code_execution:
mode: project
logging:
level: INFO
max_size_mb: 5
backup_count: 3
model_catalog:
enabled: true
url: https://hermes-agent.nousresearch.com/docs/api/model-catalog.json
ttl_hours: 24
providers: {}
network:
force_ipv4: false
sessions:
auto_prune: false
retention_days: 90
vacuum_after_prune: true
min_interval_hours: 24
onboarding:
seen: {}
updates:
pre_update_backup: false
backup_keep: 5
_config_version: 22
custom_providers:
- name: cliproxy
base_url: http://localhost:8317/v1
api_key: __CLIPROXY_API_KEY__
api_mode: chat_completions
Loading
Loading