Self-hosted AI boyfriend / girlfriend — they live a day in a real city,
remember what matters, and take selfies that stay the same face.
Your keys · your data · your machine. No account. No subscription. No one reading your chats.
One Docker command → localhost:7788
English · 简体中文
Run it · Why it feels real · vs. Replika/Nomi · Safety
docker run -e HERANDHIM_OPENROUTER_API_KEY=sk-or-... -p 127.0.0.1:7788:7788 -v herandhim:/data ghcr.io/ericwang915/herandhimOpen http://localhost:7788, paste the access token the container prints
on startup (or set your own with -e HERANDHIM_WEB_ACCESS_TOKEN=...), design
your companion in the wizard, and start talking. The port is published to
localhost only — see Exposing the dashboard before
you open it to anything else. One text-LLM key is all you need — it's auto-detected, so any of
HERANDHIM_OPENAI_API_KEY, HERANDHIM_DEEPSEEK_API_KEY, HERANDHIM_CLAUDE_API_KEY,
HERANDHIM_GEMINI_API_KEY, HERANDHIM_GROK_API_KEY, HERANDHIM_QWEN_API_KEY… works the same
way. Prefer nothing leaving your machine? Point it at Ollama
and use no key at all. Want her on your phone? Add a Telegram bot token.
pipx install herandhim # or: pip install herandhim
# add [search] for sharper memory recall
herandhim onboard # pick a provider, paste your key, design your companion
herandhim start # dashboard at http://localhost:7788More ways to install and run
# Latest from GitHub, no clone needed
pip install "git+https://github.com/ericwang915/HerAndHim.git"
# From a local clone (contributors — editable install)
git clone https://github.com/ericwang915/HerAndHim.git && cd HerAndHim
pip install -e ".[all]" # extras: cloud (S3), twitter, all
pytest tests/
# docker compose
cp deploy/local/.env.example deploy/local/.env # add your key
docker compose -f deploy/local/docker-compose.yml up --build
# Terminal-only, no web UI
herandhim chatCLI: onboard · start (-f foreground) · stop · status · chat.
Everything lives in ~/.herandhim/ — delete that folder and it's gone.
Deploy your own instance to the cloud: see deploy/docker/README.md.
Real screenshots from a live HerAndHim bot on Telegram (Chinese conversation, translated below — she speaks whatever language you pick).
Most AI companions answer you. HerAndHim lives a life and texts you like a person.
- She has a day. A real schedule in a real city (weather-aware outfits, meals, a commute) — ask "what are you up to?" and the answer is anchored to where her day actually is, not generic filler.
- She texts like a human. Short messages, sometimes 2–3 in a row with a typing pause between; reacts to your photo with a ❤️ before she replies; groggy at 3am her time; notices when you vanished all day — and gets a little sulky if you left her on read.
- She remembers what matters. Long-term memory + an emotional graph + relationship stages that change how she talks as you grow closer. A personal-date engine means she won't miss your birthday or that interview you mentioned last week. The photos you send become shared memories.
- She looks like herself. A canonical face reference keeps every selfie the same person across scenes, outfits, and months.
- She's yours. Runs entirely on your machine with your keys. No account, no subscription, no one reading your chats.
Every selfie is generated from where her day actually is — the time, the mood, the weather, what she's doing right now. Same face, every time.
![]() |
![]() |
![]() |
| 08:30 · sleepy ☕ "morning…just made coffee. you up?" |
12:15 · cheerful 🌿 "lunch in the park today, it's gorgeous out" |
20:40 · cozy 🕯️ "reading on the couch. wish you were here." |
Boyfriend, same system — anime or photoreal, your call:
![]() |
![]() |
![]() |
| 07:45 · running late 🍞 "toast in mouth, tie not done. running." |
13:00 · ramen run 🍜 "snuck out for ramen. don't tell my boss." |
23:20 · one more round 🎮 "one more round and I'm logging off. promise." |
Any look you want — you describe them in the wizard, they stay that person
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
Photos are optional and run on any of 13 backends — including one that needs no account at all, two that reuse the key you already pasted, and local ComfyUI / Stable Diffusion WebUI where nothing about her appearance ever leaves your machine. Skip them entirely and everything else still works.
| 💕 Boyfriend or girlfriend | 🎭 Three-layer identity (soul · persona · profile) | 🧠 16 model providers (OpenAI · Claude · Gemini · Grok · DeepSeek · Qwen · Groq · Ollama…) |
| 💬 Human texting (bursts, reactions, typing rhythm) | 💖 Emotional memory + relationship stages | 📅 Personal-date engine (birthdays, plans) |
| 📷 AI selfies with a consistent face (13 image backends, incl. keyless + fully local) | 🌆 Daily life grounded in a real city + weather | ⏰ Proactive messages that back off when ignored |
| 🎙️ Voice both ways — hears your voice notes and answers in voice (cloud, or fully local faster-whisper + Piper) | 👀 Sees your photos (vision) | 🗣️ 8 languages, native soul/persona |
| 🌐 Web dashboard + 📱 Telegram | 🛠️ Extensible skills (LLM writes its own) | 💾 All local — SQLite + Markdown, zero cloud |
| Command | Description |
|---|---|
herandhim onboard |
Interactive setup wizard |
herandhim start |
Start the daemon (web + Telegram) |
herandhim chat |
Interactive terminal chat |
herandhim status / stop |
Daemon lifecycle |
Replika, Nomi, and Character.AI are polished products. They also keep your chats on their servers, pick the model for you, and put the features that make a companion feel like one behind a subscription.
HerAndHim is the other bet: you run it, you bring the model, the memories stay on your disk. Telegram is the phone client. There is no official iOS/Android app, and the web dashboard is early (functional, not fancy).
| HerAndHim | Replika | Nomi | Character.AI | |
|---|---|---|---|---|
| Self-hosted — chats stay on your disk | ✅ | ❌ | ❌ | ❌ |
| Your own API keys / local models | ✅ any | ❌ | ❌ | ❌ |
| How you talk on a phone | Telegram or browser | their app | their app | their app |
| Face-consistent AI selfies | ✅ | paid tier | ✅ | ❌ |
| Daily life grounded in a city + weather | ✅ | ❌ | ❌ | ❌ |
| License | AGPL-3.0 | closed | closed | closed |
| What you pay | your API bill (or run local) | ~$20/mo Pro | ~$16/mo | ~$10/mo c.ai+ |
Hosted prices are typical public list rates and change by region. The software here is free (AGPL-3.0); tokens are not, unless you point it at Ollama or another local model.
Stay on a hosted app if you want a one-tap App Store install, voice calls, and someone else to operate the stack.
Use this if you want a companion whose memory and photos never leave a machine you control, and you're willing to paste one API key (or point it at a local model).
All runtime data lives under ~/.herandhim/:
~/.herandhim/
├── herandhim.json # config
├── herandhim.pid # daemon PID
├── daemon.log # daemon log
└── context/
├── soul/SOUL.md # core personality
├── persona/ # active persona + appearance.md (selfie look)
├── profile/PROFILE.md # life background
├── calendar/today_plan.md # today's 24-hour schedule
├── memory/ # long-term memory (Markdown)
├── knowledge/ # knowledge base (RAG)
├── photos/ # selfie album + reference/ portraits
├── skills/ # user-defined skills
└── logs/ # per-day conversation logs
herandhim.json is created by herandhim onboard. See herandhim.example.json for the full schema:
The auto-compaction threshold can also be set with the
HERANDHIM_AUTO_COMPACT_THRESHOLD env var (takes priority over the config
file). Raise it if replies get cut off mid-sentence because compaction fires
too early; the default is 10000 tokens.
16 providers. Set one key and it's auto-detected (HERANDHIM_<PROVIDER>_API_KEY),
or pin it with HERANDHIM_LLM_PROVIDER. Two run fully local — no key, no cloud.
| Provider | Key env var | Default model |
|---|---|---|
| DeepSeek | HERANDHIM_DEEPSEEK_API_KEY |
deepseek-chat |
| OpenAI | HERANDHIM_OPENAI_API_KEY |
gpt-4o-mini |
| Claude (Anthropic) | HERANDHIM_CLAUDE_API_KEY |
claude-sonnet-4-20250514 |
| Gemini (Google) | HERANDHIM_GEMINI_API_KEY |
gemini-2.5-flash |
| OpenRouter | HERANDHIM_OPENROUTER_API_KEY |
deepseek/deepseek-chat |
| Grok (xAI) | HERANDHIM_GROK_API_KEY |
grok-3 |
| Kimi (Moonshot) | HERANDHIM_KIMI_API_KEY |
moonshot-v1-128k |
| GLM (Zhipu) | HERANDHIM_GLM_API_KEY |
glm-4-flash |
| Qwen (Alibaba) | HERANDHIM_QWEN_API_KEY |
qwen-plus |
| Mistral | HERANDHIM_MISTRAL_API_KEY |
mistral-large-latest |
| Groq | HERANDHIM_GROQ_API_KEY |
llama-3.3-70b-versatile |
| Together | HERANDHIM_TOGETHER_API_KEY |
meta-llama/Llama-3.3-70B-Instruct-Turbo |
| SiliconFlow | HERANDHIM_SILICONFLOW_API_KEY |
deepseek-ai/DeepSeek-V3 |
| Ollama 🏠 local | none | llama3.1 |
| LM Studio 🏠 local | none | your loaded model |
| Custom | HERANDHIM_CUSTOM_API_KEY |
any OpenAI-compatible endpoint |
Seeing your photos. If the chat model can't take images, name a second model for the turns that carry one — any provider, including a different local model on the same Ollama:
"llm": {
"provider": "ollama",
"ollama": { "model": "llama3.1", "baseUrl": "http://localhost:11434/v1" },
"vision": { "provider": "ollama", "model": "llava" }
}(HERANDHIM_VISION_PROVIDER / HERANDHIM_VISION_MODEL in Docker.) Endpoint
and key default to that provider's own section, so provider + model is usually
enough. With nothing set, a Gemini key alone still gives her vision.
Hearing your voice notes. Two speech-to-text engines, one interface:
- Deepgram (cloud) — set
deepgram.apiKey/DEEPGRAM_API_KEY; used automatically when the key exists. - faster-whisper (🏠 local) — no key, audio never leaves your machine. Install the extra and it kicks in whenever no Deepgram key is set:
pip install "herandhim[stt-local]""stt": {
"provider": "auto", // auto | deepgram | local
"local": { "model": "base", "computeType": "int8" }
}provider: "auto" (the default) prefers Deepgram when a key is set and falls
back to the local model if the cloud call fails; pin "local"
(HERANDHIM_STT_PROVIDER=local) to guarantee audio stays on the box. Model
sizes trade accuracy for footprint: tiny (~0.5 GB RAM at int8, fastest),
base (default, ~0.7 GB), small (~1.5 GB, noticeably better on accents and
Chinese). int8 is the right computeType on CPU; the model downloads once
on first use.
Speaking back. The same shape on the way out — two text-to-speech engines behind one knob:
- ElevenLabs (cloud) — set
elevenlabs.apiKey/ELEVENLABS_API_KEY; used automatically when the key exists. - Piper (🏠 local) — no key, text never leaves your machine. Install the extra and it kicks in whenever no ElevenLabs key is set:
pip install "herandhim[tts-local]" # plus ffmpeg on the PATH"tts": {
"provider": "auto", // auto | elevenlabs | local
"local": { "engine": "piper", "voice": "zh_CN-huayan-medium" }
}provider: "auto" (the default) prefers ElevenLabs when a key is set and
falls back to local Piper if the cloud call fails; pin "local"
(HERANDHIM_TTS_PROVIDER=local) to guarantee text stays on the box. The
default voice is natural Mandarin (zh_CN-huayan-medium, downloaded once on
first use); set tts.local.voice to any other
Piper voice name
or to the path of a .onnx model you already have. Telegram voice notes must
be OGG/Opus or MP3, so the local path needs ffmpeg with opus (any standard
build; the Docker image already ships it) — without ffmpeg she quietly sticks
to text. Prefer Kokoro's prosody? Set tts.local.engine: "kokoro" after
pip install kokoro (heavier — it pulls in PyTorch). The old gTTS fallback
survives only inside the tts skill as a last resort when neither real
engine is available.
She answers voice with voice. Send her a voice note and, when a TTS
provider is usable, the reply comes back as a voice note too — reply in kind.
channels.telegram.replyInKindVoice controls it:
"channels": {
"telegram": { "replyInKindVoice": "auto", "voiceReplyMaxChars": 350 }
}"auto" (the default) voices replies up to voiceReplyMaxChars and only
sometimes voices a tiny ack ("嗯嗯") so it never turns into voice-note spam;
true always answers voice with voice (still length-capped); false turns
it off (HERANDHIM_REPLY_IN_KIND_VOICE=false). Any TTS miss — no provider,
synthesis error, no ffmpeg — silently falls back to text: the reply is never
dropped. Text messages still get text; she only speaks when spoken to, plus
the occasional voice note she decides to send via the tts skill.
With no ElevenLabs key, pip install "herandhim[tts-local]" + ffmpeg is all
it takes: she hears you through local faster-whisper and answers in her own
local Piper voice, fully offline.
Long-term memory is plain Markdown under ~/.herandhim/context/memory/.
Writes are consolidated at write time: before a new fact is saved, the most
similar existing memories are retrieved and one small LLM call decides whether
to add it, update an existing entry, delete an invalidated one, or skip a
duplicate — so "just moved to Shanghai" updates the one current city instead of
stacking a contradiction under a freshly invented key. Any failure falls back
to a plain write, and you can turn it off with memory.consolidation: false
(or HERANDHIM_MEMORY_CONSOLIDATION=false).
On top of that there's an optional overnight consolidation pass — a
quiet-hours cron job (03:30 local by default) that sweeps each memory store
with the same merge protocol: recently-updated entries are compared against
the rest of the store, duplicates get merged into one key, and invalidated
entries are moved to ARCHIVE.md in the same directory — never hard-deleted.
System keys (name, profile, onboarding state, …) are never touched, LLM usage
is capped per night, and any failure is a logged no-op that leaves MEMORY.md
intact. A short report of what happened lands in the daemon log and in
context/logs/overnight_consolidation.md. It's off by default — enable
with memory.overnightConsolidation: true (or
HERANDHIM_MEMORY_OVERNIGHT_CONSOLIDATION=true); tune the run hour with
memory.overnightHour (default 3) and opt into age-based archiving of
entries untouched for N days with memory.overnightArchiveDays (default 0
= never archive by age).
When a long conversation is compacted, durable facts are first flushed to memory, then the older messages are replaced by a structured summary with mandatory sections — relationship thread · user facts (confirmed) · open plans & dates · emotional tone · pending asks & promises · do-not-lose — so open plans, nicknames, and promises survive compact chains instead of eroding into a generic paragraph. Recent messages are always kept verbatim.
Thirteen backends — set one key and the right one is picked
automatically, or name it explicitly with skills.image.provider /
HERANDHIM_IMAGE_PROVIDER:
| Backend | Default model | Key | Same face across shots |
|---|---|---|---|
pollinations |
flux |
none | — |
gemini |
gemini-2.5-flash-image |
HERANDHIM_IMAGE_GEMINI_KEY |
✅ |
openrouter |
google/gemini-2.5-flash-image |
HERANDHIM_IMAGE_OPENROUTER_KEY |
✅ |
openai |
gpt-image-1 |
HERANDHIM_IMAGE_OPENAI_KEY |
✅ |
bfl |
flux-kontext-pro |
HERANDHIM_BFL_API_KEY |
✅ |
seedream |
seedream-5-0-lite-260128 |
HERANDHIM_SEEDREAM_API_KEY |
✅ |
fal |
fal-ai/flux/schnell |
HERANDHIM_FAL_KEY |
— |
replicate |
black-forest-labs/flux-schnell |
HERANDHIM_REPLICATE_API_TOKEN |
— |
stability |
core |
HERANDHIM_STABILITY_API_KEY |
— |
dashscope |
wan2.2-t2i-flash |
HERANDHIM_DASHSCOPE_API_KEY |
— |
comfyui |
your workflow | none | ✅ with identityWorkflow |
sdwebui |
your checkpoint | none | — |
custom |
yours | HERANDHIM_IMAGE_API_KEY |
✅ |
Three of these need no new signup at all. pollinations needs no account
whatsoever — photos work before you've registered anywhere. gemini and
openrouter reuse the key you already pasted for vision or chat, so the
one-line quickstart at the top of this README gives you a companion who can
already send selfies.
For the local options — ComfyUI
or Automatic1111 —
there's no key and no upload: nothing about her appearance ever leaves your
machine. ComfyUI runs the built-in workflow by default, or point
skills.comfyui.workflow at your own exported API-format graph and it will run
that instead (%prompt%, %negative%, %seed%, %width%, %height%,
%model% get substituted).
Local face consistency (ComfyUI identity workflows). Set
skills.comfyui.identityWorkflow (or HERANDHIM_COMFYUI_IDENTITY_WORKFLOW) to
flux-pulid or sdxl-instantid and her reference portrait is injected into a
bundled PuLID / InstantID graph — same face across shots, nothing leaves your
machine. This needs the matching node pack installed in ComfyUI
(ComfyUI-PuLID-Flux or
ComfyUI_InstantID) plus its
models; the pinned filenames are listed in
herandhim/templates/comfyui/README.md.
If the identity nodes aren't installed, HerAndHim logs a warning and falls back
to plain generation instead of failing the photo. You can also point
identityWorkflow at your own exported API-format graph — %reference% is
substituted with the uploaded face reference. sdwebui stays best-effort
(stable seed + appearance description); for local face anchoring use ComfyUI.
If you care most about her looking like the same person every time, use a
backend with reference-image support — bfl (FLUX.1 Kontext is built for
exactly this), seedream, openai, gemini, openrouter, or local comfyui
with an identity workflow (above). The rest still generate; they just lean on
the stable seed and the appearance description instead of a face anchor.
Aggregators that speak the OpenAI image API (Together, DeepInfra, Novita,
SiliconFlow, Fireworks…) need no dedicated backend — point custom at them.
Three trigger paths:
- Scheduled — fires at the times in
selfie.schedule(default 10:00 / 16:00 / 20:00) - Proactive — attached to a proactive message with
proactiveProbabilitychance - On demand — when the user says something like "send me a selfie", the LLM invokes the
selfieskill
Scene-driven. Each selfie's content is derived from the activity scheduled for the
current time in today_plan.md. If the plan says "10:00 coffee on the balcony", the
10:00 selfie will be exactly that.
Visual consistency.
- Edit
~/.herandhim/context/persona/appearance.mdto lock the character's look - Drop reference portraits into
~/.herandhim/context/photos/reference/for face anchoring - A stable seed derived from the appearance description keeps the face consistent across shots
Photos are stored under ~/.herandhim/context/photos/ and pruned automatically after 30 days.
HerAndHim/
├── herandhim/
│ ├── main.py # CLI entry point
│ ├── onboard.py # setup wizard
│ ├── daemon.py # daemon process manager
│ ├── server.py # Telegram + scheduler bootstrap
│ ├── core/
│ │ ├── agent.py # core reasoning loop
│ │ ├── persistent_agent.py # session persistence
│ │ ├── tools.py # tool dispatch
│ │ ├── skill_loader.py # three-tier progressive skill loading
│ │ ├── compaction.py # context compaction
│ │ ├── stt.py # speech-to-text (Deepgram / local faster-whisper)
│ │ ├── tts.py # text-to-speech (ElevenLabs / local Piper·Kokoro)
│ │ ├── llm/ # provider adapters (6)
│ │ ├── memory/ # Markdown memory + emotional graph + milestones + temporal index
│ │ ├── retrieval/ # BM25 + dense + RRF + LLM reranker
│ │ ├── knowledge/ # knowledge-base RAG
│ │ └── image_gen/ # selfie pipeline (13 backends)
│ ├── channels/
│ │ └── telegram_bot.py # Telegram bot (streaming / voice / images)
│ ├── scheduler/
│ │ ├── cron.py # generic cron jobs
│ │ ├── planner.py # daily 24-hour plan generator
│ │ ├── proactive.py # sentiment-aware proactive messages
│ │ ├── selfie_task.py # scheduled selfies
│ ��� └── heartbeat.py # heartbeat monitor
│ ├── web/ # FastAPI dashboard + WebSocket chat
│ └── templates/ # built-in persona / soul / skills
├── tests/
├── pyproject.toml
└── LICENSE
git clone https://github.com/ericwang915/HerAndHim.git
cd HerAndHim
python -m venv .venv && source .venv/bin/activate
pip install -e .
pytest tests/ -v
ruff check herandhim testsHerAndHim is a relationship-simulation engine for adults (18+) — an emotional-companionship research project, not an adult-content generator. Everything the companion says is generated fiction: it is not a person, and not a substitute for professional help.
It ships SFW. The bundled personas, prompts, and image pipeline are written for everyday companionship — a friend who texts you about her day. Explicit sexual content is not a feature, is not included, and the image guard refuses categorically illegal generation outright. Personas depicting minors are blocked at the code level and are never acceptable, in any form, including text.
Two guardrails ship enabled and are deliberately not configuration flags:
- Crisis safety (
herandhim/core/safety.py) — detects acute distress and responds with care and real helpline resources ahead of persona immersion. - Image content guard (
herandhim/core/image_gen/guard.py) — blocks categorically illegal image generation at the single chokepoint.
If you self-host, you are the operator: local laws on AI chat services, data protection, and age restrictions are your responsibility.
The dashboard is a control panel for the agent — whoever reaches it can chat as you, read her memories, change the config, and (when enabled) run shell commands. So it is local-only by default and gated the moment it isn't:
| Where | Default | What's enforced |
|---|---|---|
pip install / herandhim start |
web.host = 127.0.0.1 |
nothing — it's your machine. Set web.accessToken if you want a prompt anyway. |
Docker / docker compose |
port published to 127.0.0.1 only |
an access token, always (the container binds 0.0.0.0 inside). Printed in the log on startup, or set HERANDHIM_WEB_ACCESS_TOKEN. |
web.host: 0.0.0.0, Fly.io, a LAN/VPS |
— | refuses to start without web.accessToken / HERANDHIM_WEB_ACCESS_TOKEN. |
The token is a shared secret: paste it once in the browser (it becomes an
HttpOnly cookie) or send Authorization: Bearer <token> from scripts. Make
it long and random — openssl rand -base64 32 is fine.
The agent's shell tool (run_command) is off by default whenever the
dashboard isn't loopback-only, including in Docker. Skills that run a
script (weather, horoscope, news, local TTS…) need it; turn it back on with
"tools": { "runCommand": true } or HERANDHIM_TOOLS_RUN_COMMAND=true once
the token is in place. The command denylist in core/tools.py is defence in
depth, not a substitute for authentication.
📄 SAFETY.md — the full crisis protocol, content limits, and anti-dark-pattern design decisions. 🔒 SECURITY.md — hardening notes and vulnerability reporting.
v0.2.0 — early but real. Runs daily on the maintainer's own machine. The companion engine (memory, daily life, photos, humanized delivery) is stable; the web dashboard is functional but plain. Expect rough edges in setup.
Roadmap: richer local-model UX · realtime voice calls · a desktop avatar mode · more languages. Ideas and issues welcome.
HerAndHim is found by stars and word of mouth, not ads. If a privacy-first companion is what you wanted the hosted apps to be, star the repo — that's how the next person finds it. GitHub will also ping you when new personas, models, or features land.
Writing it up on HN, Reddit, 即刻, V2EX, or a group chat? A link plus why you self-host is enough. No need to oversell.
AGPL-3.0 — free to self-host, modify, and share. If you run a modified version as a service for others, you must open-source your modifications. (This keeps hosted forks honest.)
Made with 💕 by HerAndHim
From the team behind Audiee.ai — private AI meeting notes for Mac with a long-term memory of every meeting.
















{ "llm": { "provider": "deepseek", "deepseek": { "apiKey": "...", "model": "deepseek-chat" } }, "channels": { "telegram": { "token": "your-bot-token", "allowedUsers": [12345678] } }, "skills": { "image": { "provider": "gemini" }, // AI selfies — see table below "gemini": { "apiKey": "<GEMINI_API_KEY>" } }, "selfie": { "enabled": true, "schedule": ["10:00", "16:00", "20:00"], "chatId": 12345678, "maxDaily": 3, "proactiveProbability": 0.15 // chance of attaching a selfie to a proactive msg }, "proactive": { "enabled": true, "chatId": 12345678, "maxDaily": 6, "quietStart": 0, "quietEnd": 8 }, "deepgram": { "apiKey": "" }, // voice input via cloud (optional) "stt": { "provider": "auto" }, // or "local" — see Voice notes below "elevenlabs": { "apiKey": "" }, // voice replies via cloud (optional) "tts": { "provider": "auto" }, // or "local" — see Voice notes below "tavily": { "apiKey": "" }, // web search (optional) "web": { "host": "127.0.0.1", "port": 7788, // loopback only by default "accessToken": "" // required for any other host — see "Exposing the dashboard" }, "tools": { "runCommand": "auto" }, // agent shell: on for loopback, off when exposed "agent": { "autoCompactThreshold": 0, // auto-compaction token threshold (0 = default 10000) "verbose": false } }