EmpryoEmpryo.beta
reference

Configuration

Every Empryo config field: default model, thinking, Genome graph, task router, agent features, compaction, key storage, instruction files, and env vars.

Config lives in two files. Project wins.

ScopePath
Global~/.empryo/config.json
Project.empryo/config.json

Full example

{
  "defaultModel": "anthropic/claude-sonnet-4-5",
  "thinking": { "mode": "adaptive" },
  "genome": true,
  "semanticSummaries": "ast",
  "diffStyle": "default",
  "chatStyle": "accent",
  "toolTimeout": 2,
  "compaction": {
    "strategy": "v2",
    "triggerThreshold": 0.7,
    "keepRecent": 4
  },
  "taskRouter": {
    "spark":      "anthropic/claude-haiku-4-5",
    "ember":      "anthropic/claude-sonnet-4-5",
    "compact":    "google/gemini-2.5-flash"
  },
  "agentFeatures": {
    "desloppify": true,
    "tierRouting": true,
    "dispatchCache": true,
    "targetFileValidation": true
  },
  "retry": { "maxAttempts": 5, "baseDelayMs": 3000 }
}

Fields

Model

FieldDefaultWhat it does
defaultModel"none"Active model ID. "none" (default) forces picker on launch.
thinking.mode"off""off", "adaptive", "enabled"
thinking.budgetTokens-Tokens when mode: "enabled" (1024, 2048, 5000, 10000, 20000)

Display

FieldDefaultWhat it does
diffStyle"default""default", "sidebyside", "compact"
chatStyle"accent""accent", "bubble"
vimHintstrueShow Vim keybinding hints
nerdFontautoNerd Font icons — auto-detected from installed fonts; set true/false to force (off shows ASCII)

Intelligence

FieldDefaultWhat it does
genometrueBuild the codebase graph on launch
semanticSummaries"synthetic""synthetic" (default), "ast", "llm", "off"
toolTimeout2Tool call timeout in minutes. 0 disables.

Compaction

See compaction for what these do.

"compaction": {
  "strategy": "v2",
  "triggerThreshold": 0.7,
  "resetThreshold": 0.4,
  "keepRecent": 4,
  "maxToolResults": 30,
  "llmExtraction": true
}

Retry

For 429s and transient errors. Delays double each attempt.

"retry": { "maxAttempts": 5, "baseDelayMs": 3000 }

Web access

FieldDefaultWhat it does
webSearchtrueAllow the web_search tool at all. Off means no web search on any path.
nativeSearchtrueLet the provider run the search server-side on lanes where we have measured it working. Requires webSearch.

With nativeSearch on, a supported model searches in one step and returns its own citations instead of Empryo scraping on your machine — and the query goes only to your model provider rather than also to DuckDuckGo, Brave or Jina. Two trade-offs worth knowing:

  • Because the provider executes the search, there is no per-query approval prompt to intercept.

Turn nativeSearch off to keep every search client-side and promptable.

  • The provider's search tool adds a fixed ~2.2K input tokens to each request whether or not the

model searches. It sits in the cached prefix, so the effective cost is much lower than that.

It is on only where we have actually run it: Claude (direct and through the proxy), GPT through the proxy, and OpenRouter's native-search generations. Lanes we have implemented but never exercised against a real key stay off and use the search below instead — being wrong about a provider-executed tool costs the whole request, not just the search, so an unproven lane is not worth the gamble. /web-search names whichever backend is actually in play.

Everything else — gateways, local models, unproven lanes, no provider support — falls back to the search backends you've keyed, with free DuckDuckGo as the floor. Toggle both in Settings › Provider, or with /provider websearch and /provider nativesearch.

VariablePurpose
EMPRYO_NATIVE_SEARCH_UNVERIFIEDSet to 1 to also use provider-side search on the unproven lanes (Gemini, Grok and Groq direct). Untested by us — if it works for you, please say so.

Task router

Assign different models to different jobs. See the task router recipe for tuning tips.

"taskRouter": {
  "spark":      "anthropic/claude-haiku-4-5",
  "ember":      "anthropic/claude-sonnet-4-5",
  "webSearch":  "anthropic/claude-haiku-4-5",
  "desloppify": "anthropic/claude-haiku-4-5",
  "verify":     "anthropic/claude-haiku-4-5",
  "compact":    "google/gemini-2.5-flash",
  "semantic":   "anthropic/claude-haiku-4-5",
  "default":    null
}
SlotRuns when
sparkRead-only research agents
emberCode-writing agents
webSearchWeb search agent
desloppifyCleanup pass after code edits
verifyAdversarial review after code edits
compactContext compaction
semanticGenome one-line summaries
defaultFallback for background tasks

Resolution: taskRouter[slot]taskRouter.default → active model.

Agent features

"agentFeatures": {
  "marionette": false,
  "desloppify": true,
  "tierRouting": true,
  "dispatchCache": true,
  "targetFileValidation": true
}
FeatureWhat it does
marionetteCompile each sent prompt into a repo map (focus files, graph edges, memories) before the agent starts — model via taskRouter.marionette
desloppifyRun cleanup agent after code agents
tierRoutingAuto-route trivial tasks to cheap model
dispatchCacheShare file reads across dispatches
targetFileValidationRequire file paths on dispatch tasks

Toggle with /agent-features (or /marionette for the prompt compiler directly).

Marionette lane

How the prompt compiler surveys the repository before it writes the map.

"marionetteMode": "fast"
LaneHow it surveysTypical
nonerepository index only — no model call~0.2s, 0 tokens
fast *(default)*index survey, then one tool-less call judges and writes~20s
assistindex survey, then a short tooled pass confirms~55s
deepno pre-retrieval — the model drives the whole survey~75s

Measured on 11 real requests against a large TypeScript monorepo (haiku-4.5): fast found the right files as often as none while roughly doubling precision, and beat deep by 30 points of recall at a third of the latency. deep keeps the highest ceiling on requests whose product wording matches nothing in the code, at the cost of high run-to-run variance.

Switch with /marionette none|fast|assist|deep, in Settings → Router → Behaviors, or per run with --marionette-mode <lane>. marionetteBudget (steps / time) only applies to assist and deep — the retrieval lanes have no loop to bound.

Providers

Pick keys and add custom providers on the dedicated pages:

Auth & key storage

Keys go to your OS keychain when available, with a file fallback otherwise.

PlatformBackend
macOSLogin Keychain (security), service empryo
Linuxlibsecret via secret-tool (GNOME Keyring, KWallet)
Linux without secret-tool~/.empryo/secrets.json, mode 0600
WindowsDPAPI (crypt32.dll) - %LOCALAPPDATA%\Empryo\secrets.dat, user-scoped
Windows without DPAPIPlain JSON under same dir, mode-restricted
Windows (WSL)Same as Linux above

empryo --set-key <provider> <key> writes to whichever backend is active. Inspect with empryo --list-providers.

Lookup order

{ "keyPriority": "env" }
ValueOrder
"env" (default)env var → keychain → file
"app"keychain → file → env var

Use "app" when shell-exported keys keep overriding stored ones.

Pass a key per-launch

Env vars work for the TUI too - useful for one-off sessions or CI:

LLM_GATEWAY_API_KEY=sk-... empryo
ANTHROPIC_API_KEY=sk-ant-... empryo

Nothing is persisted. There is no --key flag - the TUI only reads stored keys and env vars.

Remove a key

/keys inside the TUI lists every provider with delete shortcuts. Or delete from the keychain directly (security delete-generic-password -a empryo -s anthropic-api-key on macOS).

Instruction files

Auto-load project rules from AI-tool markdown files:

{ "instructionFiles": ["empryo", "claude", "cursorrules"] }
KeyFileDefault
empryoEMPRYO.mdon
claudeCLAUDE.mdoff
cursorrules.cursorrulesoff
github-copilot.github/copilot-instructions.mdoff
cline.clinerulesoff
windsurf.windsurfrulesoff
aider.aider.conf.ymloff
codexAGENTS.mdoff
ampAMPLIFY.mdoff

Toggle in TUI with /instructions.

Privacy

Block files from the agent:

/privacy add .env
/privacy add secrets/**

Built-ins already cover .env, .pem, credentials, id_rsa, .npmrc, .netrc, shadow, passwd.

Environment variables

VariableDefaultPurpose
EMPRYO_NO_GENOMEunsetSkip the Genome scan at startup.
EMPRYO_MAX_OUTPUT_TOKENS64000Per-step output cap for all agents (forge + subagents + web-search). Raise for reasoning models that hit finish_reason=length.
EMPRYO_PRESETSunsetComma-separated preset specs to load on boot. Set automatically by --plugin <spec> flags. See presets.
EMPRYO_NO_PROMPTunsetSkip first-run addon wizard (set to 1). Useful in CI.
EMPRYO_DEBUG_APIunsetDump per-step API requests to ~/.empryo/api-export/.
EMPRYO_DEV_UIunsetShow dev-only slash commands (/ui-demo, etc).
EMPRYO_ENABLE_GHOSTTYunsetForce-enable the embedded floating terminal on Windows (off by default - see Windows notes).
EMPRYO_HEARTH_SOCKET<configDir>/hearth.sockOverride the Hearth IPC socket path.
EMPRYO_HEARTH_APPROVAL_TIMEOUT_MS300000Approval timeout for remote tool calls.
EMPRYO_HEARTH_DENY_READ_REMOTEunsetBlock read-only tools from remote surfaces (set to 1).
EMPRYO_PROXY_VERSIONlatestPin a CLIProxyAPI version when installing the proxy addon.
EMPRYO_AUTO_INSTALL_ADDONSunsetComma-separated addons to install automatically (proxy,neovim).
EMPRYO_MEMORY_LIMIT_MB1536Ceiling on Empryo's own heap. Past it, memory-hungry analysis (type-aware diagnostics) declines rather than pushing the collector into a spiral.
EMPRYO_TREE_MEMORY_LIMIT_MB4096Ceiling on Empryo plus every process it spawned — language servers, mostly. A separate question from the heap ceiling: a big tsserver is not a reason to stop type-checking, but it is a reason to worry about the machine.
EMPRYO_LSP_IDLE_MS180000How long a language server may sit unused before it is stopped. Restarting one costs 37–700ms depending on the server; holding four idle costs ~750MB. Lower it on a small machine, raise it if you bounce between languages.
EMPRYO_LSP_MAX_CLIENTS6How many language servers may run at once; past this the coldest is stopped. Six keeps the worst case (~550MB each) inside the 4GB tree ceiling.

The four values above are defaults measured on one machine. A malformed, zero or negative value falls back to the default — an empty variable never reads as "no limit".

Hooks

Covered on the hooks page. Short version: Empryo reads hooks.{Event} from all 5 config sources (Claude Code's three + Empryo's two), fires all matches.

Storage

/storage shows per-component disk usage (Genome, sessions, plans, memory, input history, binaries, fonts) with one-click cleanup.

Scope priority

Session → Project → Global. Changes via commands land in whatever scope the command targets. Use /model-scope to move the active model between project and global.