AgentX docs

Settings Reference

Every setting the app exposes, generated from the same declarations the settings screen reads. If a setting is described here, that description is the one you’ll see beside the control; if it isn’t listed here, the app doesn’t offer it.

How this page is laid out. One heading per settings screen, in nav order, so this reads the way the app does. Settings written up in full appear under their screen; the rest are tabulated beneath them and are being written up screen by screen.

Where things are stored. config settings live in data/config.json and are written through POST /api/config/update. memory settings live in data/memory_settings.json and are written through the two /api/memory/* settings endpoints. A setting with no write route is read-only over the API — set it in .env or the settings file directly, and restart.

Defaults. Every value below ships with the default shown. Changing nothing leaves you on a working configuration; the settings screen marks anything you’ve moved and offers to put it back.

Infrastructure → Model Providers

Where AgentX gets its intelligence.

Connections to the model backends: the five built-ins (Anthropic, OpenAI, OpenRouter, Vercel, LM Studio) plus any OpenAI-compatible endpoint you register yourself, which then addresses its models as yourid:model.

The first thing to configure on a new install — nothing else works without at least one reachable provider. Come back when a backend stops responding, when you’re adding a local or self-hosted endpoint, or to read the supply line: which provider a turn actually resolves to, and what it costs.

providers.anthropic.api_key

Your Anthropic key.

Default: (empty) · Set via: /api/config/update

What it is. Credentials for Anthropic’s API — the Claude model family.

How it works. Stored server-side and returned redacted, with an ANTHROPIC_API_KEY environment fallback so a container can supply it without it ever reaching data/config.json.

When to change it. Set it to address Claude models directly rather than through a gateway. Direct access is usually cheaper per token than the same model via an aggregator, and it is the only route to features a gateway has not exposed.

Managing it. Keys save on their own button, never by autosave. The card reports whether the backend is reachable — a saved key that cannot reach the API shows as unreachable rather than silently failing at turn time.

providers.anthropic.base_url

Point Anthropic requests somewhere other than the default endpoint.

Default: — · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. An override for the API host, for proxies and compatible gateways.

How it works. Unset uses Anthropic’s own endpoint, which is the normal state. When set, every Anthropic-routed request goes here instead.

When to change it. Set it for a corporate proxy, a regional endpoint, or a local recording proxy while debugging. Wrong values fail at request time rather than on save, so change it deliberately.

Managing it. A caller-supplied URL is guarded before use, but it is still an outbound destination for your prompts. Treat it with the same care as the key.

providers.custom

Any OpenAI-compatible endpoint, registered as its own provider.

Default: (empty) · Set via: /api/config/update

What it is. User-registered backends — Groq, DeepSeek, Ollama, a colleague’s server — each with an id, so their models are addressed as yourid:model.

How it works. Written as one object rather than key by key. Caller-supplied URLs are guarded before any request is made to them.

When to change it. The escape hatch that keeps the provider list from being a fixed set of five. Anything speaking the OpenAI API can be a first-class backend without pretending to be OpenAI, which is what setting openai.base_url would do.

Managing it. Add and edit these through the Model Providers screen rather than by hand — the id becomes a namespace, and a stored model id that references a provider you later delete resolves to nothing.

providers.lmstudio.base_url

Where your local LM Studio server is listening.

Default: — · Set via: /api/config/update

What it is. The address of a local (or LAN) LM Studio instance serving models from your own hardware.

How it works. Unlike the hosted providers, this needs no key — reachability is the credential. Models served there become addressable like any other.

When to change it. Set it to run models locally: no per-token cost, no data leaving your network, at the cost of your own hardware and slower generation. Particularly worth it for the high-volume background work memory does.

Managing it. Include the scheme and port. Because this is often a LAN address, a laptop that moves networks will find it unreachable — which shows as a provider failure rather than a settings error.

providers.lmstudio.timeout

How long to wait on the local server before giving up.

Default: 300 · Range: 10 to 1800, seconds · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. A request timeout for LM Studio calls.

How it works. Generous by default, because local generation on modest hardware is far slower than a hosted API — a timeout tuned for the cloud would abandon perfectly healthy local runs.

When to change it. Raise it if large local models are being cut off mid-generation. Lower it if you would rather fail over quickly when the machine is asleep or busy.

Managing it. Default 300 seconds. This is the one provider setting where the right value depends mostly on your hardware rather than on the service.

providers.openai.api_key

Your OpenAI key.

Default: (empty) · Set via: /api/config/update

What it is. Credentials for OpenAI’s API.

How it works. Stored server-side, returned redacted, with an OPENAI_API_KEY environment fallback. Also used by the embedding path when the embedding provider is set to OpenAI rather than local.

When to change it. Set it to use OpenAI models directly. Worth noting the second role: memory embeddings can run through this key, so it may matter even on an install whose chat models come from elsewhere.

Managing it. As with all keys here, an explicit Save — nothing is transmitted unless you type a new value over the mask.

providers.openai.base_url

Point OpenAI requests somewhere other than the default endpoint.

Default: — · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. An override for the API host.

How it works. Unset uses OpenAI’s own endpoint. Set, everything OpenAI-routed goes here.

When to change it. Useful for Azure-style deployments or a proxy. For a genuinely different OpenAI-compatible service, prefer registering a custom endpoint below — that keeps its models addressable as yourid:model instead of masquerading as OpenAI.

Managing it. Overriding this changes where all OpenAI traffic goes, including embeddings if they are routed through this provider.

providers.openrouter.api_key

Your OpenRouter key — one key, many model families.

Default: (empty) · Set via: /api/config/update

What it is. Credentials for OpenRouter, an aggregator that fronts models from many vendors behind a single API.

How it works. Stored server-side and redacted. The account can also be linked by signing in, which avoids pasting a key at all; either way the card can then show balance and spend.

When to change it. The fastest way to reach a wide range of models without an account per vendor. The trade is a margin on top of direct pricing and a dependency on one intermediary.

Managing it. OpenRouter renames models; ids can go stale. The provider surface offers a repair for stored ids that were renamed — worth running if models suddenly report far smaller context windows than they should.

providers.openrouter.app_name

The application name OpenRouter attributes your traffic to.

Default: — · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. The companion attribution header to the site URL.

How it works. Informational only, exactly as above.

When to change it. Set it alongside the site URL if you care about attribution. Otherwise leave it empty.

Managing it. Also sent on every request; also not a secret.

providers.openrouter.site_url

The site OpenRouter attributes your traffic to.

Default: — · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. An optional attribution header sent with each request, used in OpenRouter’s own reporting and rankings.

How it works. Purely informational: it does not affect routing, pricing, or which models you can reach.

When to change it. Set it if you want your usage attributed to a site you run. Leave it empty otherwise; nothing degrades without it.

Managing it. Sent on every request, so treat it as public — it is not a secret and should not carry anything you would not publish.

providers.vercel.api_key

Your Vercel AI Gateway key.

Default: (empty) · Set via: /api/config/update

What it is. Credentials for Vercel’s AI Gateway, another multi-vendor front door.

How it works. Stored server-side and redacted, like the others.

When to change it. Set it if you already route through Vercel. It occupies the same niche as OpenRouter — one key, several vendors — so most installs want one or the other rather than both.

Managing it. Having two aggregators configured is not a problem, but it makes the question “where did this turn actually go” harder to answer. The supply line on the provider surface is what answers it.

providers.vercel.base_url

Point Vercel Gateway requests somewhere other than the default.

Default: — · Set via: /api/config/update

What it is. An override for the gateway host.

How it works. Unset uses Vercel’s own endpoint.

When to change it. Set it only for a proxy or a self-hosted gateway deployment.

Managing it. As with the other base URLs, a wrong value fails at request time rather than on save.

Infrastructure → Model Limits

How much context each model really has, and the sampling defaults.

Two things a provider often gets wrong on your behalf: the token window a model actually offers, and the sampling parameters — temperature, max tokens, top-p, penalties — used when a profile doesn’t set its own.

Override a window when a model’s declared one is wrong. An understated window makes conversations compact far earlier than they need to, which you experience as the agent forgetting things it should still be able to see.

context_limits.lmstudio.context_window

How much context your local models can actually hold.

Default: 32768 · Range: 2048 to 2000000, tokens · Set via: /api/config/update

What it is. The window size assumed for LM Studio models, which do not report their own the way hosted APIs do.

How it works. Used to size every turn: how much transcript stays verbatim, when compaction begins, how much room is left for a reply.

When to change it. Set it to what you actually loaded the model with. Too low and conversations compact far earlier than they need to — the usual cause of an agent that seems to forget. Too high and turns are built that the model then refuses or truncates.

Managing it. Default 32768, conservative on purpose because it applies to whatever you happen to load. It is a provider-level default; a specific model that differs belongs in the per-model overrides below.

context_limits.lmstudio.max_output_tokens

How much your local models may generate in one reply.

Default: 8192 · Range: 256 to 200000, tokens · Set via: /api/config/update

What it is. The output ceiling assumed for LM Studio models.

How it works. Bounds every reply and, with the window above, decides how much room assembly reserves for the answer.

When to change it. Raise it if local replies are being cut short; lower it if long generations are tying the machine up. Local generation is slow, so this is a latency dial as much as a length one.

Managing it. Default 8192. As above, per-model differences belong in the overrides.

context_limits.models

Per-model corrections for any provider that reports its limits wrongly.

Default: (empty) · Set via: /api/config/update

What it is. A table of model id → window and output cap, overriding whatever the catalog believes.

How it works. Written as one object. A model listed here uses your figures; everything else uses the catalog’s.

When to change it. The escape hatch for the single most damaging catalog error: a model whose real context is large but is read as small. Turns then compact almost immediately and the agent appears to forget within a few messages. An aggregator alias that resolves to no catalog entry is the classic case.

Managing it. Use it when the supply line or a compaction that fires far too early tells you a limit is wrong. Mapping a model to null removes its override. Setting a window larger than the model truly has moves the failure from early compaction to provider errors, which is worse.

Infrastructure → Model Roles

One model per workload, so features don’t each need their own.

Three roles — fast utility, deep reasoning, and summarizer — that features point at instead of naming a model. A feature left on its default follows its role; a model chosen explicitly on the feature always wins.

Set these once and most of the platform is configured. Change a role to move every background task onto a cheaper or faster model without visiting a dozen sections to do it.

models.roles.deep_reasoning

The model for work where quality matters more than volume.

Default: (empty) · Set via: /api/config/update

What it is. The role for the hardest background jobs — combined extraction is the notable member, because doing relevance and extraction in one pass is harder than either separately.

How it works. Same resolution as the other roles: members on inherit follow it, an explicit choice overrides it.

When to change it. Point it at a genuinely capable model. Its members run rarely enough that the cost is modest, and their output is what the rest of the system builds on — a badly extracted fact is retrieved wrongly forever.

Managing it. Empty falls through to the global default. If memory quality is disappointing and you change one thing, change this.

models.roles.fast_utility

The model for small, frequent, mechanical calls.

Default: (empty) · Set via: /api/config/update

What it is. One of three workload roles. This one covers the high-volume background work: classification, relevance gating, entity resolution, short digests.

How it works. Features left on inherit follow their role rather than naming a model. An explicit per-feature model always wins over the role.

When to change it. This is where model choice pays back most, because these calls are the most numerous. A cheap, fast model here is usually right — the jobs are judgements a small model makes correctly.

Managing it. Empty means the role is unset and its members fall through to the global default. Setting one role does not require setting the others.

models.roles.summarizer

The model for compressing text.

Default: (empty) · Set via: /api/config/update

What it is. The role for summarisation: conversation compaction, tool-output compression, trajectory compression.

How it works. Members on inherit follow it. These jobs run inside a live turn, so latency here is felt directly rather than absorbed by a background queue.

When to change it. Favour a fast model. Summarisation is forgiving of model strength and unforgiving of latency — a slow summarizer stalls the turn it is trying to make room for.

Managing it. Empty falls through to the global default. Its members are spread across Conversation Context rather than gathered on one screen, which is exactly why the role exists.

preferences.default_model

The model everything falls back to.

Default: — · Set via: /api/config/update

What it is. The global default: what runs when an agent profile pins nothing and no role applies.

How it works. The bottom of every resolution chain. Roles sit above it, explicit per-feature models above those, and a profile’s own model above that.

When to change it. Set it to the model you want ordinary conversation on. It is the one model choice that affects an install with no other configuration at all.

Managing it. Because it is the floor, a model unavailable here makes everything fail rather than one feature. Prefer a reliably reachable model, and use roles for the specialised choices.

Also in this area — values that are read-only over the API. Set them in .env or the settings file directly and restart; they have no control and no per-setting write-up:

SettingTypeDefaultStoreSet via
models.defaults.chatNoneType—configread-only
models.defaults.extractionNoneType—configread-only
models.defaults.reasoningNoneType—configread-only
models.fallback_enabledbooltrueconfigread-only
models.overridesdict(empty)configread-only

How the agent searches the web — and what that’s allowed to cost.

The search backend and its defaults, plus two budgets: how many searches an ordinary turn may run and how many a research turn may, each with an optional dollar ceiling. A source policy of preferred and blocked domains applies to every result.

Come here to change backends, to cap spend, or to stop the agent reading a domain you don’t trust. The budgets are the part worth understanding: they are per turn, not per day, and research turns draw on their own much larger allowance.

search.backend

Which search provider is tried first.

Default: tavily · Range: tavily / brave · Set via: /api/config/update

What it is. The provider every web search goes to before anything else. Tavily and Brave answer the same question differently: Tavily returns ranked results plus the research suite (extract, crawl, map, deep research); Brave can return pre-extracted page content and supports Goggles for re-ranking.

How it works. Every web_search call goes to this backend. If it errors or comes back empty and fallback is on, the other one is tried before the tool reports failure. The choice also decides which of the two API keys actually gets used.

When to change it. Stay on Tavily unless you specifically want Brave’s grounded content or its Goggles: the extra web tools (web_extract, web_map, web_crawl, web_research) are Tavily-backed, so switching narrows what agents can do with a page once they have found it.

Managing it. Whichever you pick needs its key set below. Use Test connection after changing this — it reports each backend separately, so you can see the new primary answering before you rely on it.

search.brave_answers_enabled

Allow Brave’s deep research — needs their separate Answers plan.

Default: false · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. A second backend for web_research, so deep research still works when Brave is the active search backend rather than Tavily.

How it works. Routes deep research through Brave’s research endpoint. Answers is a separate subscription from Brave Search, and a key does not advertise which plans it holds — an unsubscribed key answers OPTION_NOT_IN_PLAN.

When to change it. Turn it on once the Answers plan is actually active on your key. This is the rare feature that ships off: enabling it by default would advertise a tool that always fails for everyone who has not bought the plan, which is worse than not offering it.

Managing it. Answers bills a request line of roughly $0.004 plus queries and tokens on top, and reports its own exact total per call — so the ledger shows real figures rather than an estimate. If deep research fails immediately with a plan error, this is the setting to turn back off.

search.brave_api_key

Your Brave key — the Search plan; deep research needs their separate Answers plan.

Default: (empty) · Set via: /api/config/update

What it is. Credentials for api.search.brave.com. The Search subscription covers ordinary search and grounding; Brave’s deep research is a different product on the same key.

How it works. Stored server-side and redacted on read, with a BRAVE_API_KEY environment fallback. A key without the Answers plan answers OPTION_NOT_IN_PLAN when deep research is attempted, and the key does not advertise which plans it holds — which is why Brave deep research ships off.

When to change it. Needed to select Brave as a backend or to use it as the fallback. Worth having as a second provider even on Tavily: fallback only helps if the other side is actually configured.

Managing it. Brave Search bills about $5 per 1,000 requests — roughly $0.005 a search, comparable to Tavily’s basic tier. Answers bills a request line of about $0.004 plus queries and tokens, and reports its own exact total.

search.brave_context_max_tokens

The ceiling on content one grounded search may return.

Default: 4096 · Range: 1024 to 32768, tokens · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. A total token budget for everything a single grounded Brave search brings back, across all of its results.

How it works. Enforced per search. Passages are included in relevance order until the budget is spent, so what falls off the end is what mattered least.

When to change it. Raise it when grounded searches are clearly truncating material the agent then has to fetch separately. Lower it when searches are crowding the context window — this is content that enters the turn and is paid for on every subsequent message in it.

Managing it. Default 4096, well under Brave’s own ceiling of 32768. That gap is deliberate: a default returning 8k tokens per search would undo the saving grounding exists to create. Read it together with the per-URL cap below.

search.brave_context_max_tokens_per_url

The ceiling on how much any single page may contribute.

Default: 1024 · Range: 128 to 8192, tokens · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. A per-result share of the grounded search’s total budget, so one long page cannot consume the whole thing.

How it works. Applied to each result before the total budget is filled. A page whose relevant passages exceed this is truncated; the freed budget goes to other results.

When to change it. Raise it when the answer is usually deep inside one long document and you are getting the top of it. Lower it to force breadth — several sources sampled rather than one quoted at length.

Managing it. Default 1024, a quarter of the total budget, so at least four sources can contribute. Setting it equal to the total lets a single page take everything, which is rarely what you want from a search.

search.brave_context_threshold

How picky Brave is about which passages count as relevant.

Default: balanced · Range: strict / balanced / lenient · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. The relevance bar a passage must clear to be included in grounded content.

How it works. Applied when selecting passages, before the token budgets are filled. A stricter bar means fewer passages qualify, so the budget goes further per source and may not be spent at all.

When to change it. Move to strict when grounded results feel padded with material that only loosely relates. Move to lenient when the agent keeps missing content you can see on the page — a strict bar drops passages that were relevant but worded unlike the query.

Managing it. balanced is the default and is right for most work. This interacts with the token budgets: strict plus a large budget usually returns less than lenient plus a small one.

search.brave_grounding_default

Have Brave return page content, not just a list of links.

Default: true · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. Brave can return pre-extracted, relevance-ranked passages from the results — search and extract fused into one call.

How it works. When on, Brave searches route through the grounding endpoint and come back with content already attached, bounded by the token budgets below. The model can still ask for a plain link list per call when it only wants URLs.

When to change it. Leave it on. Whenever the agent would have read those pages anyway, one grounded search replaces a search and an extract — a clear saving. It does cost more than a bare link list for a quick “what is the URL for X”, which is why the model can opt out per call.

Managing it. Brave only; Tavily has no equivalent and ignores this. If grounded searches feel bloated, tighten the token budgets or the relevance threshold before turning the feature off.

search.cache_ttl_seconds

How long an identical search is served free from memory.

Default: 300 · Range: 0 to 3600, seconds · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. A short in-process cache of search results, keyed by the query. A repeat within the window returns the stored result without billing.

How it works. Held in the server’s memory, so it is lost on restart and not shared between instances. Only exactly-repeated queries hit it.

When to change it. The default of 5 minutes is aimed at the common loop where an agent searches, reads, and searches the same thing again a moment later. Raise it if your agents revisit the same questions inside one session; lower it — or set 0 — when freshness genuinely matters, such as news or prices.

Managing it. 0 disables caching entirely, and every repeat becomes a billable search. Deep research has its own, much longer cache on the Research Mode screen, because a repeated deep call is far more expensive to redo.

search.country

Bias results toward one country.

Default: (empty) · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. A two-letter country code that tilts ranking toward locally relevant results.

How it works. Passed with each search when set. Empty means no preference, which is the shipped state. It is a bias, not a filter — results from elsewhere still appear.

When to change it. Set it when answers are regional and wrong by default: law, tax, pricing, availability, public services. Leave it empty for technical or academic work, where a country bias only narrows a global corpus for no gain.

Managing it. Use the ISO code (GB, DE, JP). This does not change the language of results — that is the next setting, and the two are often both needed.

search.default_chunks_per_source

How much of each result page to bring back.

Default: 0 · Range: 0 to 5 · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. The number of content chunks Tavily returns per result, rather than a bare title and snippet.

How it works. Applied when the model doesn’t specify. 0 means no opinion — the provider decides, which is the shipped state. Higher values mean more of each page arrives inline with the search result.

When to change it. Raise it when the agent habitually follows every search with web_extract on the same pages: it is cheaper to bring the content back once than to fetch it twice. Leave it at 0 when searches are mostly navigational — you don’t need three chunks of a page you only wanted the URL of.

Managing it. Range 1–5. Multiply by max results to see what you are actually asking for: 5 results × 3 chunks is fifteen passages of text entering the turn.

search.default_search_depth

How hard Tavily digs before answering — and what that costs per search.

Default: (empty) · Range: ultra-fast / fast / basic / advanced · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. Tavily’s effort tier for a search. Deeper tiers read more of the web before ranking, so they surface material a fast pass misses.

How it works. Applied when the model doesn’t name a depth itself. Empty means no opinion — the provider’s own default stands, which is the shipped state. Billing follows the tier: advanced costs 2 credits, the rest 1.

When to change it. Set advanced when the agent works on questions where the answer is not on the first page — technical detail, primary sources, anything niche. Set fast or ultra-fast when latency matters more than reach and the questions are ordinary. Doubling the credit cost of every search is the trade.

Managing it. Brave ignores this. If you set advanced here, halve your expectation of how far the per-turn call budget stretches in dollars — the count doesn’t change, the bill does.

search.fallback_enabled

Try the other backend when the primary fails or finds nothing.

Default: true · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. A second attempt on the backend you did not choose, rather than returning an error to the agent.

How it works. Fires on two conditions: the primary raised an error, or it returned zero results. The fallback call is a real, billable search on the other provider.

When to change it. Leave it on if both keys are set — a transient provider outage otherwise surfaces as “I couldn’t find anything”, which the agent will often accept as an answer rather than a failure. Turn it off if only one provider is configured, or if you are deliberately keeping spend on one account.

Managing it. Fallback searches count against the same per-turn budget as the original, so a flapping primary consumes the turn’s allowance twice as fast.

search.max_results

How many results one search returns.

Default: 5 · Range: 1 to 20, results per search · Set via: /api/config/update

What it is. The result count requested from the provider when the agent does not ask for a specific number.

How it works. Passed with every search. Results arrive ranked, so raising this appends lower-relevance entries rather than improving the top of the list.

When to change it. Raise it when the agent keeps searching again with slightly different wording — that usually means the answer was just outside the window. Lower it to keep turns tight: every result is text the model reads and pays for, and on Brave with grounding on, each one can carry page content too.

Managing it. Default 5, capped at 20. Past about 10 the tail is rarely read; if the agent needs breadth it is usually better served by another query than by a longer list of the same one.

search.per_turn_cost_usd

A dollar ceiling on one turn’s searching, alongside the call count.

Default: 0.0 · Range: 0 to 100, USD per turn · Set via: /api/config/update

What it is. The most a single turn’s web searching may cost before the tool stops reaching providers. It binds together with the call limit — whichever runs out first ends that turn’s spending.

How it works. Every search’s estimated cost is charged against the open budget window as it happens, using the provider’s own reported figure where there is one and a per-credit estimate otherwise. When the running total reaches this ceiling, further searches return a budget error rather than billing.

When to change it. This is the ceiling that actually corresponds to money. A call count treats a basic search and a pro deep-research call as equal when one costs twenty times the other. Set this if you have a metered key and a number you would be unhappy to see on one question.

Managing it. 0 — the shipped default — means no cost ceiling, so nothing changes until you set one. For scale: an ordinary search runs under a cent, so even $0.25 a turn is generous for normal chat and still catches a loop.

search.per_turn_limit

How many searches one turn may run before the tool starts refusing.

Default: 8 · Range: 0 to 100, searches per turn · Set via: /api/config/update

What it is. A ceiling on web_search and web_research calls within a single user turn. It exists to bound a tool loop that has started searching in circles.

How it works. A budget window opens when your turn starts and closes when it ends. Each search draws one unit; a deep-research call draws more (see the Research Mode screen). Once the budget is gone the tool returns a budget error to the model instead of reaching the provider, so the turn continues — it just stops spending. Only interactive turns are metered: work running under delegation or the planner is not inside a window and is not capped here.

When to change it. The default of 8 is set to never bite ordinary use and only clip a runaway. Lower it if you have seen turns search a dozen times over one question; raise it if genuinely broad questions are being cut off mid-investigation. Research Mode does not use this number at all — it has its own, much larger one.

Managing it. 0 means unlimited, which is worth avoiding on a metered key. A call count is a rough proxy for spend once a single deep call can cost 20× a basic search, which is what the dollar ceiling below is for; set both and whichever runs out first stops the turn.

search.research_per_turn_cost_usd

The same dollar ceiling, for turns running in Research Mode.

Default: 0.0 · Range: 0 to 100, USD per turn · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. A separate spend ceiling that applies only while a conversation is in Research Mode, where the call budget is deliberately much larger.

How it works. Swapped in for the ordinary ceiling whenever the turn carries the elevated research budget. Charged the same way, against the same window.

When to change it. Research Mode raises the call budget roughly fivefold, which is exactly the situation where a runaway costs real money — deep research calls are the expensive ones. Setting this is how you say “research may be thorough, but not unbounded”.

Managing it. 0 means no ceiling. The Research Mode screen shows a projected worst case for your current budget and depth; a ceiling somewhere near that figure will almost never fire on a normal engagement but will stop a pathological one.

search.safesearch

Brave’s content filter for results.

Default: (empty) · Range: off / moderate / strict · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. How aggressively Brave filters adult and explicit results.

How it works. Passed to Brave with each search. Empty means no opinion — Brave’s own default applies, which is the shipped state. Tavily ignores it.

When to change it. Set strict for shared or workplace installs. Set off when the filter is getting in the way of legitimate research — medical and security topics are the usual casualties.

Managing it. Brave only. Switching the backend to Tavily silently drops this; if filtering matters to you, that alone is a reason to stay on Brave.

search.search_lang

Preferred language for results.

Default: (empty) · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. A language code that tilts results toward pages written in that language.

How it works. Passed with each search when set. Empty means no preference, the shipped state. Like the country bias it ranks rather than filters.

When to change it. Set it when the agent works in one language and keeps surfacing English sources it then has to translate. Leave it empty when the best source may be in any language — the model reads them all, and narrowing costs you reach.

Managing it. Use the short code (en, de, ja). Pair with the country bias when you want local and in-language; setting only one often isn’t enough.

search.source_policy

Which corners of the web may ground an answer — preferred, blocked, and Brave Goggles.

Default: (structured) · Set via: /api/config/update

What it is. An operator-owned answer to “where may this agent get its facts”. Three parts: preferred domains to favour, blocked domains never to return, and a Brave Goggle for finer re-ranking than a list allows.

How it works. Applied to every search and mapped per backend — Tavily receives include and exclude domain lists, Brave receives an inline Goggle. The asymmetry that matters: blocked is a hard floor, always merged in and impossible for the model to widen past. Preferred is a soft preference — it seeds the include list, but a model that passes its own domain scope for a specific call wins, because silently over-narrowing is how a research turn comes back empty.

When to change it. Use blocked for sources you consider actively unreliable — the agent then cannot cite them however it phrases the query. Use preferred to steer toward a corpus you trust without cutting the agent off from everything else. Goggles are for shaping rather than gating: boost and downrank rather than allow and deny.

Managing it. Comma-separated domains; wildcards like *.edu work. Preferred is the one that bites unexpectedly — a narrow list on a broad question returns nothing, and the agent reads that as “no such information exists”. Start with blocked, which has no such failure mode. The Goggle field is Brave-only and takes either a hosted Goggle URL or inline rules; it is merged after the two lists.

search.tavily_api_key

Your Tavily key — also what unlocks the extract, crawl, map and deep-research tools.

Default: (empty) · Set via: /api/config/update

What it is. Credentials for tavily.com. Beyond plain search, this key is what makes web_extract, web_map, web_crawl and web_research available at all.

How it works. Stored server-side and never returned to the client — reading the config gives you a redacted mask. It falls back to the TAVILY_API_KEY environment variable when unset, so a container can supply it without ever writing it to data/config.json.

When to change it. Set this even if you run Brave as the primary backend: the research tools have no Brave equivalent except deep research, and only when the separate Answers plan is active.

Managing it. Tavily bills per credit — a basic search is 1, an advanced search 2, and a deep-research call 5–20. At the shipped estimate of $0.008 per credit that is well under a cent for an ordinary search. Keys save on their own button, not by autosave; nothing is sent unless you type a new value over the mask.

search.timeout

How long one search may hang before it is abandoned.

Default: 15 · Range: 5 to 120, seconds · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. A hard wall-clock cap on a single provider call.

How it works. Searches run synchronously inside the tool loop, so a call that never returns blocks the whole turn — including your Stop button, which can only take effect between rounds. This cap is what guarantees the turn comes back.

When to change it. Raise it only if legitimate searches are timing out, which usually means a slow deep tier rather than a slow network. Lowering it makes a wedged provider fail faster, at the cost of abandoning searches that would have answered.

Managing it. Default 15 seconds. Tavily’s own client default is around 60, which is why this exists — an unbounded call is indistinguishable from a hung app.

Also in this area — values that are read-only over the API. Set them in .env or the settings file directly and restart; they have no control and no per-setting write-up:

SettingTypeDefaultStoreSet via
search.brave_answers_cost_per_request_usdfloat0.004configread-only
search.brave_context_max_snippetsint50configread-only
search.brave_cost_per_request_usdfloat0.005configread-only
search.brave_research_tiers.auto.iterationsint3configread-only
search.brave_research_tiers.auto.queriesint20configread-only
search.brave_research_tiers.auto.secondsint180configread-only
search.brave_research_tiers.mini.iterationsint2configread-only
search.brave_research_tiers.mini.queriesint8configread-only
search.brave_research_tiers.mini.secondsint90configread-only
search.brave_research_tiers.pro.iterationsint5configread-only
search.brave_research_tiers.pro.queriesint40configread-only
search.brave_research_tiers.pro.secondsint300configread-only
search.cost_per_credit_usdfloat0.008configread-only

Infrastructure → Images & Audio

Generating pictures and speech, and re-reading the ones you send.

Image generation for conversations and profile avatars, speech synthesis and transcription, and vision — whether images you attach are shown to the model again on later turns.

Change the models when output quality or cost matters. The vision re-feed is the subtle one: showing an image on more turns keeps the agent able to refer back to it, and spends tokens every time it does.

audio.input_enabled

Whether you can attach or record audio for an agent.

Default: true · Set via: /api/config/update

What it is. Audio input: a clip you attach or record, heard natively by a capable model or transcribed first.

How it works. Off refuses audio attachments outright rather than silently ignoring them.

When to change it. Leave it on unless audio input is unwanted. As with vision, the reason to turn it off is usually policy — keeping recordings from reaching a provider — rather than cost.

Managing it. This switch did nothing before v0.21.270: the screen wrote to a config section nobody had declared, so the value never persisted and reverted on reload. If you tried to turn audio input off before and it came back, that is why.

audio.speech_enabled

Whether agents may speak into a conversation.

Default: true · Set via: /api/config/update

What it is. Speech output: the tool that lets an agent produce spoken audio as part of a reply.

How it works. Off makes the tool unavailable, so agents answer in text. Distinct from the Ambassador’s voice mode, which has its own settings.

When to change it. Leave it on if you use spoken replies at all — it costs nothing unless an agent actually speaks. Turn it off to keep conversations text-only.

Managing it. Which speech model and voice get used is resolved through the Ambassador’s voice settings, so this switch controls whether, not how. Like the input switch above, it did not persist before v0.21.270.

images.avatar_model

Which model draws profile avatars.

Default: openrouter:microsoft/mai-image-2.5 · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. A separate image model for agent avatars, so portraits and conversational images can use different models.

How it works. Used only for avatar generation, paired with the style template below.

When to change it. Avatars are generated rarely and looked at constantly, which justifies a better model here than for throwaway conversational images. That is why it is a separate setting rather than sharing the default.

Managing it. Changing it does not regenerate existing avatars; it applies to the next one created.

images.avatar_style_prompt

The house style every avatar is drawn in.

Default: `Create one square avatar portrait.

COMPOSITI…· **Set via:**/api/config/update` · Advanced — most installs never need to change this.

What it is. A template describing composition, background, lighting and rules, into which each agent’s own subject description is inserted.

How it works. The app-level style prompt; the per-profile subject prompt is appended at generation time. Empty falls back to the shipped template.

When to change it. Edit it to change the look of every avatar at once — a different palette, a different framing, a house style of your own. Leave it alone to keep the shipped look, which is built to survive circular cropping.

Managing it. The shipped template carries real constraints, notably a circular safe zone because avatars are cropped to a circle. A rewrite that drops that produces avatars with their subjects clipped.

images.default_model

Which model draws images in conversations.

Default: openrouter:black-forest-labs/flux.2-klein-4b · Set via: /api/config/update

What it is. The image model used for ordinary in-conversation generation.

How it works. Named as provider:model like every other model here. Image models vary enormously in speed and price for similar-looking results.

When to change it. Change it when output quality or cost matters. This is the one used for anything an agent draws in the course of a conversation, so its price is the one you will notice.

Managing it. Must be a model that can actually output images — the picker filters to those, but a hand-set id is not checked until generation fails.

images.enabled

Whether agents may generate images in a conversation.

Default: true · Set via: /api/config/update

What it is. Image generation as a tool the agent can reach for, distinct from reading images you send.

How it works. Off removes the capability; agents describe rather than draw. Routed through OpenRouter today.

When to change it. Leave it on unless image generation is unwanted or unbudgeted — it costs nothing until an agent actually generates something.

Managing it. Separate from vision below: this is pictures out, that is pictures in. Turning one off does not affect the other.

vision.enabled

Whether agents can see images you attach.

Default: true · Set via: /api/config/update

What it is. Image input: you attach a picture and a vision-capable model looks at it.

How it works. On by default. A model without vision degrades to text-only rather than failing, so leaving this on costs nothing when the model cannot use it.

When to change it. Leave it on. Turn it off to guarantee no image ever reaches a provider — the reason to do that is policy, not cost.

Managing it. Independent of image generation above. Also see the re-feed setting below, which decides whether an attached image stays visible on later turns.

vision.refeed_recent_turns

How many past turns’ images stay visible to the model.

Default: 2 · Range: 0 to 10, turns · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. Whether images you attached earlier are shown again as a conversation continues, or seen once and then only remembered as text.

How it works. When a session reloads from history, this many recent image-bearing turns are re-fed. Re-sending encoded image data on every turn is expensive, which is why it is bounded rather than unlimited.

When to change it. Raise it when the agent keeps losing track of an image you are working through together. Lower it — or set 0 — when images are incidental and the token cost of carrying them is not worth it.

Managing it. 0 disables multi-turn re-feed; single-turn vision still works, so an image is seen when sent and not afterwards. Each re-fed image is paid for on every turn that carries it.

Intelligence → Task Planner

Whether the agent plans before it acts, and how far ahead.

Task decomposition — breaking a request into subtasks before execution rather than working straight through it. A complexity threshold decides which requests are worth planning at all.

Raise the threshold if simple requests are being over-planned; lower it if the agent charges into multi-step work with no structure and loses the thread halfway.

planner.complexity_threshold

How complex a request must be before it gets a plan.

Default: complex · Range: simple / moderate / complex · Set via: /api/config/update

What it is. The bar a request must clear before the planner is invoked at all.

How it works. Three levels. simple plans nearly everything, complex — the shipped default — plans only genuinely multi-step requests, and moderate sits between.

When to change it. Raise to complex if simple requests are being over-planned into ceremony. Lower toward simple if the agent charges into multi-step work with no structure and loses the thread halfway through.

Managing it. This is the dial to reach for before turning planning off entirely. The failure mode of over-planning is wasted latency; the failure mode of under-planning is work abandoned half-done, which is worse.

planner.enabled

Whether the agent breaks big requests into a plan first.

Default: true · Set via: /api/config/update

What it is. Task decomposition — turning one complex request into an ordered set of subtasks before doing any of them.

How it works. Off means every request is worked straight through. On, a request that clears the complexity threshold gets a planning call first, and the plan then drives execution.

When to change it. Keep it on for multi-step work. Turn it off if your requests are mostly single-shot and the planning step reads as ceremony — it costs a call and some latency before anything visible happens.

Managing it. The threshold below decides which requests get planned, so it is usually the better dial than this switch: raising the threshold keeps planning for the work that needs it and skips the rest.

planner.max_subtasks

A hard cap on how many pieces a request may be split into.

Default: 6 · Range: 1 to 20, subtasks · Set via: /api/config/update

What it is. The ceiling on subtasks in a single plan, regardless of how the model would like to decompose the work.

How it works. Applied to the plan the model produces. A request that genuinely needs more pieces gets a coarser plan rather than a longer one.

When to change it. Raise it for genuinely large engagements where a coarse plan loses important structure. Lower it to force the agent to think in bigger steps — long plans tend to fragment work into pieces too small to carry context.

Managing it. Default 6. Each subtask is execution overhead as well as planning overhead, so the cost of a high cap is paid on every step, not once.

planner.max_tokens

How much room the plan itself may take.

Default: 1000 · Range: 100 to 4000, tokens · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. The output budget for the planning call.

How it works. A plan that does not fit is truncated, which produces a partial plan rather than an error — the agent then executes an incomplete decomposition.

When to change it. Raise it if plans arrive visibly cut short, particularly with a high subtask cap. Lower it only to control cost on a planner pointed at an expensive model.

Managing it. Default 1000, comfortable for the shipped subtask cap. If you raise max_subtasks substantially, raise this with it — the two bind together and truncation is silent.

planner.model

Which model writes the plan.

Default: — · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. An explicit model for the planning call, overriding the agent’s own.

How it works. Unset means the agent’s default model plans its own work. Clearing this back to unset is a real write, not a no-op.

When to change it. Set it when planning quality matters more than planning cost — decomposition rewards a stronger model more than most background tasks do, because a bad plan is expensive to follow. Set it cheaper when plans are routine.

Managing it. Planning happens once per request while execution happens many times, so a stronger planner is usually better value than a stronger executor.

planner.temperature

How much variety the planner allows itself.

Default: 0.3 · Range: 0 to 1 · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. Sampling temperature for the planning call only.

How it works. Lower values make decomposition more deterministic and conventional; higher values let the planner consider less obvious orderings and groupings.

When to change it. Keep it low. Planning is a structural task, not a creative one, and a high-temperature plan is mostly a differently-shaped plan rather than a better one. Raise it only if plans feel formulaic on work that has genuinely unusual structure.

Managing it. Default 0.3, deliberately below the conversational default. If plans are erratic between identical requests, this is the first thing to lower.

Intelligence → Thinking Patterns

How agents reason in chat — scaffolds, critique, and consensus.

The reasoning patterns compiled into a live streamed turn: step-by-step chains, principles-first step-back, self-critiquing reflection, and consensus sampling. A classifier picks one per turn unless you pin it.

Turn individual patterns off when they cost more time than they earn on your kind of work. These are the global fallbacks — per-agent defaults live on the profile, and the composer chip overrides for one conversation.

reasoning.auto_classifier_enabled

Let a small model break the tie when the heuristics are unsure.

Default: true · Set via: /api/config/update

What it is. An optional second opinion inside Auto mode. Auto always runs instant keyword heuristics first; this decides what happens when those are not confident.

How it works. The heuristics are free and run on every message, so the common path costs nothing extra. Only when they are unconfident — and only on a message long enough to be worth it — does one tiny classification call fire, bounded at about 150 output tokens and a five-second timeout.

When to change it. Leave it on. It is the cheapest quality improvement here: a bounded call on a minority of messages, choosing between patterns you are already paying for. Turn it off only if you want Auto to be strictly deterministic, or on an install where any extra provider call is unwelcome.

Managing it. With this off, unconfident cases fall back to the heuristics’ best guess rather than to no pattern. The message-length floor below is what keeps it from firing on trivial turns.

reasoning.chat_patterns_enabled

The master switch for reasoning scaffolds in chat.

Default: true · Set via: /api/config/update

What it is. Whether the agent may be given a thinking pattern at all — a structure it follows before answering, compiled into the live streamed turn rather than run as a separate step you wait for.

How it works. Off restores plain turns: no pattern is selected, no pre-calls are made, and the per-pattern switches below stop mattering. Models that think natively still stream their own reasoning — that is the provider’s behaviour, not this feature’s.

When to change it. Leave it on. The patterns are what turn a fast answer into a considered one, and Auto only reaches for the expensive ones when the message warrants it. Turn it off to isolate whether a behaviour you dislike comes from the scaffolding or from the model itself — that is what a kill-switch is for.

Managing it. This is the global fallback. Each agent profile carries its own default, and the composer chip overrides for a single conversation, so turning this off is the only way to be certain no pattern runs anywhere.

reasoning.classifier_min_chars

How long a message must be before the tiebreak is worth paying for.

Default: 240 · Range: 0 to 5000, characters · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. A length floor. Below it, the classification call never fires and Auto settles the choice with heuristics alone.

How it works. Measured against the message you sent. Short messages are overwhelmingly simple ones, and paying a provider call to decide how to think about “thanks” is pure overhead.

When to change it. Lower it if you write tersely and still want careful pattern selection — a dense two-line question can deserve more thought than a rambling paragraph. Raise it to cut classifier calls further on a chatty install.

Managing it. Default 240 characters, roughly a short paragraph. 0 means every message is eligible, which is the setting most likely to make the classifier’s cost visible.

reasoning.classifier_model

Which model breaks the tie.

Default: (empty) · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. The model used for the bounded classification call — a small, fast judgement, not a reasoning task.

How it works. Empty follows the Fast Utility role, so it moves with that role rather than needing to be set here. The call is capped at about 150 output tokens with a five-second timeout regardless of the model chosen.

When to change it. Set it only to pin a specific model for this one job — usually because the Fast Utility role points somewhere you would rather not send message text, or because you want the cheapest possible model for a decision this small.

Managing it. Do not point this at a large reasoning model. The call is a classification with a hard timeout; a slow model will simply time out and the heuristics will decide anyway, having cost you five seconds.

reasoning.cot_enabled

Allow the step-by-step pattern.

Default: true · Set via: /api/config/update

What it is. Chain of thought — the agent works through a problem in explicit steps before committing to an answer.

How it works. Costs nothing extra: the structure rides in the same call as the answer, so the only price is the output tokens the reasoning itself occupies.

When to change it. Keep it on. It is the cheapest pattern here and the one that helps most broadly. The one case it does not help is a model that already reasons natively — Auto knows this and will not stack a redundant scaffold on top.

Managing it. If turns feel padded with visible working you did not want, the thing to change is usually the agent’s profile default rather than this switch, which removes the pattern from every agent at once.

reasoning.min_output_tokens

A floor on output budget when the agent is thinking.

Default: 0 · Range: 0 to 65536, tokens · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. Thinking spends output tokens before the visible answer begins, so a budget sized for the answer alone can leave nothing for the answer.

How it works. 0 means automatic: the budget floors itself whenever a pattern is active or the model reasons natively. A non-zero value pins the floor regardless.

When to change it. Set it when answers are being cut off mid-sentence on thinking turns and the automatic floor is not enough — long reflection passes are the usual cause. Leave it at 0 otherwise; the automatic behaviour already covers the case this exists for.

Managing it. The model’s own output cap still binds above this, so a large value here does nothing if the model cannot deliver it. If raising this does not help, the model’s declared limit under Model Limits is the real constraint.

reasoning.reflection_enabled

Allow the draft-then-critique pattern.

Default: true · Set via: /api/config/update

What it is. Reflection — the agent drafts an answer, criticises its own draft, and revises before you see anything.

How it works. The most expensive pattern in ordinary use: it spends output tokens on a draft you never read. It also gates the multi-pass “reflect deeply” variant, so turning it off removes both.

When to change it. Keep it on for work where being wrong is costly and being slow is not. Turn it off when turns are short and conversational — the critique pass has little to find and you pay for it every time.

Managing it. Watch the thinking output floor below if reflection answers arrive truncated: draft, critique and answer all come out of the same output budget.

reasoning.sc_k

How many independent attempts consensus votes over.

Default: 3 · Range: 2 to 5, samples · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. The number of samples drawn before the agreed answer is chosen.

How it works. Each sample is a full completion, so this is a direct multiplier on the turn’s cost. An odd number avoids ties.

When to change it. Raise it when a question is genuinely marginal and three attempts still disagree; lower it to 2 only if you want the pattern nearly free, accepting that two samples cannot form a majority.

Managing it. Default 3, capped at 5. Returns fall off quickly — the gap between 3 and 5 is much smaller than the gap between 1 and 3, while the cost difference is the same size.

reasoning.sc_model

Which model produces the consensus samples.

Default: (empty) · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. The model used for the k independent attempts that consensus votes over.

How it works. Empty uses the conversation’s own model. The samples are the cost of this pattern, so this setting multiplies: whatever the model charges, it charges k times.

When to change it. The best lever on this screen for making consensus affordable. Voting draws its value from attempts being independent, not from each being excellent, so a cheaper sampling model usually keeps most of the benefit at a fraction of the price.

Managing it. Read it with the sample count below: cheaper model plus a higher k is often a better trade than an expensive model sampled twice.

reasoning.self_consistency_enabled

Allow the consensus pattern — several samples, one judged answer.

Default: true · Set via: /api/config/update

What it is. Self-consistency — the same question is answered several times independently and the agreed answer wins.

How it works. The k samples are the cost: at the default this is roughly three times an ordinary turn. Auto only selects it for short calculation or logic questions with no tools, where independent attempts genuinely disagree and the majority is usually right.

When to change it. Keep it on if arithmetic and logic matter in your work; that is exactly where a single sample is unreliable and voting fixes it. Turn it off if cost matters more — it is the clearest multiplier on this screen.

Managing it. The sample count and the model used for sampling are below. Pointing the samples at a cheaper model is usually better than reducing k, since the value comes from independent attempts rather than from each being excellent.

reasoning.step_back_enabled

Allow the principles-first pattern.

Default: true · Set via: /api/config/update

What it is. Step-back — before answering, the agent distils the governing principles of the question, then answers with those in hand.

How it works. Costs one small hidden pre-call before the turn. The principles are not shown; they enter the prompt that produces the answer.

When to change it. Worth keeping on for conceptual and design questions, where naming the right principle changes the answer rather than decorating it. Turn it off if the extra call’s latency is noticeable on work that is mostly factual — a pre-call adds real wall-clock time before anything starts streaming.

Managing it. The model and timeout for that pre-call are below. If step-back turns feel slow, check the timeout before disabling the pattern outright.

reasoning.step_back_model

Which model distils the principles before a step-back turn.

Default: (empty) · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. The model used for step-back’s hidden pre-call.

How it works. Empty uses the conversation’s own model — not a role. That differs from the classifier above, which follows Fast Utility, and it is deliberate: the principles feed directly into the answering prompt, so a mismatch in capability shows up in the answer.

When to change it. Point it at a cheaper model when step-back is common and the principles are straightforward; point it at a stronger one when the conceptual framing is the hard part and the answer is easy once framed.

Managing it. Keep in mind this is a pre-call: its latency is added before anything streams. A slow model here makes every step-back turn feel unresponsive even if the answer is fast.

reasoning.step_back_timeout_seconds

How long to wait for those principles before giving up on them.

Default: 20 · Range: 5 to 120, seconds · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. A wall-clock cap on the step-back pre-call.

How it works. On timeout the turn proceeds without the principles rather than failing — you get an ordinary answer, slightly later than you would have.

When to change it. Raise it if you have pointed step-back at a slower model and are losing the pre-call to timeouts. Lower it to keep the worst-case delay before streaming tight — this cap is exactly that delay.

Managing it. Default 20 seconds. Since the failure mode is silent — the pattern degrades to no pattern — a too-low value looks like step-back “not doing anything” rather than like an error.

Intelligence → Agent Teams

Letting agents hand work to each other.

Delegation: an agent dispatching a subtask to another agent, either ad-hoc from the roster or through a team you’ve defined. Depth, parallelism, and timeout bound how far a chain of that can run.

Lower the depth or parallelism when delegation is running away with cost. Turn ad-hoc delegation off entirely if you want agents to work alone unless a team explicitly says otherwise.

alloy.allow_adhoc_delegation

Let agents hand work to each other outside a defined team.

Default: true · Set via: /api/config/update

What it is. Whether an agent in a normal conversation is offered a roster of other agents it may dispatch a subtask to.

How it works. On, agents get a delegation tool and a roster block naming who is available. The roster is opt-in per profile — an agent appears only if it has been marked available for delegation — so nothing delegates on a fresh install regardless of this switch.

When to change it. Leave it on. The opt-in roster is the real gate, and this being on is what lets you enable delegation by ticking a profile rather than by finding this setting. Turn it off to guarantee that only defined teams delegate.

Managing it. A conversation can also disable delegation for itself, so this is the outermost of three gates: this switch, the per-profile opt-in, and the per-conversation override.

alloy.chain_of_command

Restrict delegation to the org chart where one exists.

Default: true · Set via: /api/config/update

What it is. Strict adjacency for agents that belong to an organisation: a manager may dispatch to the leads of teams it owns, a lead to its own members, a member upward to its own lead — and no further.

How it works. Enforced in two places at once: the delegation tool only offers legal targets, and the executor rejects an illegal one anyway. Only agents whose teams name a manager are considered part of an org, so installs with no org structure are completely unaffected.

When to change it. Leave it on if you have built an org. It is what stops a specialist at the bottom of the chart dispatching across the whole roster, which is how a delegation chain becomes unbounded.

Managing it. Turning it off does not remove the org — it removes the restriction, so every org agent falls back to the flat opt-in roster.

alloy.delegation_timeout_seconds

How long a delegated subtask may run before it is abandoned.

Default: 300 · Range: 30 to 3600, seconds · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. A wall-clock cap on one dispatched subtask.

How it works. On timeout the dispatching agent gets a failure for that subtask and carries on with the rest, rather than the whole turn hanging.

When to change it. Raise it when specialists do genuinely long work — deep research or a large document pass will exceed a short cap routinely. Lower it to fail fast when delegation is meant to be quick and a hung specialist is worse than a missing answer.

Managing it. Default 300 seconds. Set it against the effort tier a dispatch uses: tiers set the specialist’s tool-round budget, and a marathon tier against a short timeout will be cut off every time.

alloy.max_delegation_depth

How far a chain of delegation may run.

Default: 3 · Range: 1 to 5, levels deep · Set via: /api/config/update

What it is. The limit on delegation depth: an agent dispatching to an agent that dispatches again, and so on.

How it works. Counted from the agent handling your turn. At the limit, further delegation is refused and the agent must do the work itself.

When to change it. This is the main runaway guard. Each level multiplies both cost and latency, and a deep chain is usually a sign that the work was not scoped rather than that it was genuinely deep. Lower it if delegation is running away; raise it only for deliberately layered org structures.

Managing it. Default 3, capped at 5. Read together with the parallel limit: depth times parallelism is roughly the worst-case fan-out of a single turn.

alloy.max_parallel_delegations

How many subtasks may run at once.

Default: 3 · Range: 1 to 8, at once · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. The ceiling on concurrent dispatches from a single agent.

How it works. Excess dispatches queue rather than failing. Parallelism cuts wall-clock time without changing total cost — the same work is done either way.

When to change it. Raise it when a team’s specialists are independent and you want the turn to finish sooner. Lower it if concurrent work is hitting provider rate limits, which surfaces as sporadic delegation failures rather than as slowness.

Managing it. Default 3, capped at 8. This bounds one agent’s fan-out, not the whole turn’s — combined with depth, a modest number here can still produce a large tree.

alloy.non_blocking_delegations

Let a dispatch return immediately and fold its report in later.

Default: true · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. An additional dispatch style: instead of waiting for the specialist, the agent gets a receipt at once and the result arrives later in the same turn.

How it works. The dispatching agent keeps working while the subtask runs, and the report is folded in when it lands. Nothing outlives the turn — an unfinished work order is cancelled when the turn ends, however it ends.

When to change it. Leave it on. It is the difference between an agent that stalls on every dispatch and one that keeps making progress, and it costs nothing extra — the same work runs either way.

Managing it. Turn it off if you want strictly sequential, easier-to-follow turns; the transcript of a non-blocking turn interleaves the agent’s own work with reports arriving out of order.

Also in this area — values that are read-only over the API. Set them in .env or the settings file directly and restart; they have no control and no per-setting write-up:

SettingTypeDefaultStoreSet via
alloy.effort_tiers.deepint60configread-only
alloy.effort_tiers.marathonint100configread-only
alloy.effort_tiers.quickint8configread-only
alloy.effort_tiers.standardint30configread-only

Intelligence → Ambassador

A parallel agent that briefs you without entering the conversation.

A dedicated operator running alongside a conversation: it reads the transcript, answers questions about it, and can propose actions — but its tool belt never executes a write. Reads run automatically; anything that would change state comes back as a proposal for you to confirm.

Change the model or context depth when briefings are too shallow or too expensive. The aide settings tune the parallel read fan-out behind it and rarely need touching.

ambassador.aide.cache_ttl_seconds

How long an aide’s digest is reused before being made again.

Default: 1800 · Range: 0 to 86400, seconds · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. A cache of per-conversation digests, so surveying the same conversations repeatedly does not re-read them each time.

How it works. Refreshes automatically when a conversation grows, so a cached digest never describes a stale version of an active conversation.

When to change it. Keep it generous. Because growth invalidates entries anyway, a long TTL mostly saves work on conversations that have not changed — which is exactly where re-reading is wasted.

Managing it. Default 30 minutes. 0 disables caching and makes every survey pay full price for conversations it has already digested.

ambassador.aide.enabled

Let the Ambassador survey many conversations without reading them all.

Default: true · Set via: /api/config/update

What it is. The aide swarm: instead of pulling whole transcripts into the Ambassador’s own context, cheap parallel “aide” calls each condense one conversation and return a short digest.

How it works. Map-reduce — the aides map, the Ambassador reduces. Read-only throughout, and never allowed to raise: an aide that fails is simply absent from the survey rather than failing the briefing.

When to change it. Leave it on. It is what keeps a cross-conversation question affordable and the Ambassador’s context lean; off, the same question means reading every transcript in full into one prompt.

Managing it. The settings below tune the fan-out and rarely need touching. They are documented because they are writable, not because they need attention.

ambassador.aide.max_input_chars

How much of a conversation an aide is allowed to read.

Default: 6000 · Range: 500 to 50000, characters · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. A cap on the transcript fed to a single aide.

How it works. A longer conversation is truncated to this, so a digest of a very long conversation covers only part of it.

When to change it. Raise it when digests of long conversations miss their later half — the commonest cause of a survey that feels out of date. Lower it to cut input cost across a wide survey.

Managing it. Default 6000 characters. This is the first thing to check when aide digests seem to be summarising the wrong part of a conversation.

ambassador.aide.max_parallel

How many aides run at once.

Default: 4 · Range: 1 to 16, at once · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. Concurrency for the fan-out.

How it works. More at once finishes a survey sooner without changing its total cost — the same aides run either way.

When to change it. Raise it to make wide surveys faster. Lower it if concurrent calls are hitting provider rate limits, which shows up as aides going missing rather than as an error.

Managing it. Default 4; three to five is the practical sweet spot. Beyond that the reduce step usually becomes the bottleneck rather than the fan-out.

ambassador.aide.max_per_survey

How many conversations one survey may cover.

Default: 8 · Range: 1 to 32, aides · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. A cap on the aides spawned by a single question.

How it works. Bounds the worst-case cost of asking something broad. Conversations beyond the cap are not surveyed.

When to change it. Raise it when you routinely ask questions spanning more conversations than this and the answers feel partial. Lower it to bound what one broad question can cost.

Managing it. Default 8. Multiply by the aide output budget for a rough ceiling on what the reduce step has to read.

ambassador.aide.max_tokens

How long one aide’s digest may be.

Default: 220 · Range: 50 to 4000, tokens · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. The output budget per aide — a tight digest, not a transcript.

How it works. Several digests are combined into one briefing, so this multiplies by the number of aides in the reduce step.

When to change it. Raise it if digests are too thin to be useful. Lower it if surveys are producing more material than the Ambassador can usefully reduce.

Managing it. Default 220 tokens — deliberately small. The whole design assumes digests are cheap enough to make several of.

ambassador.aide.model

Which model the aides use to condense one conversation.

Default: (empty) · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. The model behind each aide’s digest — a summarisation job, run many times in parallel.

How it works. Empty follows the Ambassador’s cheap floor through the fallback chain. Because aides run several at a time, this multiplies more than most model settings on this screen.

When to change it. Use the cheapest model that produces a usable digest. A survey spawns several aides at once, so quality here buys much less than it costs.

Managing it. If digests are missing the point of a conversation, raise the input cap below before the model — an aide reading a truncated transcript looks exactly like an aide that is not clever enough.

ambassador.aide.temperature

How literally an aide summarises.

Default: 0.2 · Range: 0 to 1 · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. Sampling temperature for an aide’s digest.

How it works. Low values keep digests close to what the conversation actually contained.

When to change it. Keep it low. A digest is evidence the Ambassador then reasons over, so invention here propagates into the briefing as though it were fact.

Managing it. Default 0.2.

ambassador.aide.timeout_seconds

How long one aide may take before it is abandoned.

Default: 20 · Range: 5 to 120, seconds · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. A wall-clock cap per aide.

How it works. An aide that times out is simply left out of the survey — the briefing still arrives, with one fewer digest behind it.

When to change it. Raise it if you have pointed aides at a slower model and surveys are coming back thin. Lower it to keep a briefing prompt when one provider is struggling.

Managing it. Default 20 seconds. Because a timeout degrades silently rather than failing, a too-low value looks like “the survey missed that conversation”.

ambassador.dispatch.enabled

Let the Ambassador hand a task to another agent, with your confirmation.

Default: true · Set via: /api/config/update

What it is. Dispatch: minting a new conversation and running a chosen worker on a task headlessly, from the briefing side channel.

How it works. Proposal-only. The Ambassador can propose a dispatch; it cannot perform one. The task starts as your action after you pick a worker and confirm. Off hides the affordance and the endpoint refuses.

When to change it. Leave it on — it is the one write-shaped thing the side channel offers, and it is gated by your confirmation. Turn it off if you want the Ambassador strictly read-only with no write-shaped affordance at all.

Managing it. This does not weaken the belt’s invariant: the tool still executes no write. Dispatch lands as a user turn, which is what keeps the audit trail honest about who started the work.

ambassador.enabled

Whether the parallel briefing agent is available at all.

Default: true · Set via: /api/config/update

What it is. The master switch for the Ambassador: an agent that runs alongside a conversation, reads it, and briefs you — without entering the transcript.

How it works. Off removes the affordance everywhere. On, it is available but idle: the Ambassador costs nothing until you actually ask it something.

When to change it. Leave it on. The whole point is that it is there when a turn needs explaining and invisible when it does not. Turn it off on an install where you want exactly one agent per conversation and no side channel.

Managing it. The invariant worth knowing: its tool belt never executes a write. Reads run automatically; anything that would change state comes back as a proposal for you to confirm. That is what makes a read-broad agent safe.

ambassador.max_context_turns

How much of the conversation the Ambassador reads.

Default: 8 · Range: 1 to 40, turns · Set via: /api/config/update

What it is. The number of recent turns pulled in, read-only, to ground a briefing.

How it works. Read fresh for each briefing rather than accumulated, so this bounds every briefing’s input rather than growing over a session.

When to change it. Raise it when briefings miss context that was established earlier and you are asking about the shape of a conversation rather than its last move. Lower it to make briefings cheaper and more focused on what just happened.

Managing it. Default 8 turns. This is input cost on every briefing, so it multiplies with how often you use the feature rather than being a one-off.

ambassador.max_tokens

How long a briefing may be.

Default: 600 · Range: 100 to 8000, tokens · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. The output budget for one briefing.

How it works. A briefing that does not fit is truncated. The budget is deliberately tight — a briefing is meant to be read at a glance, not studied.

When to change it. Raise it if briefings are being cut off mid-sentence, or if you want fuller analysis rather than a summary. Lower it to force brevity.

Managing it. Default 600 tokens, a few paragraphs. If you find yourself raising this a lot, the thing you want is probably a conversation with the agent rather than a briefing about one.

ambassador.model

The model the Ambassador thinks with, overriding its profile.

Default: — · Set via: /api/config/update

What it is. An explicit model for briefing work, authoritative when set.

How it works. Unset uses the chosen profile’s model, and failing that a built-in floor. Setting it here overrides the profile without editing the profile.

When to change it. Briefing is summarisation over a transcript — a job that rewards a fast, cheap model more than a strong one. Set it when the profile you like the voice of carries a model you would rather not pay for on every briefing.

Managing it. Clearing it back to unset is a real write, not a no-op: it returns control to the profile.

ambassador.profile_id

Which agent profile the Ambassador speaks as.

Default: — · Set via: /api/config/update

What it is. The profile supplying the Ambassador’s identity, persona and voice. Any profile carrying an ambassador section can serve.

How it works. Unset falls back to the default agent profile. The profile decides who the Ambassador is; the settings on this screen are feature-level knobs around that.

When to change it. Set it when you want briefings in a distinct voice from the agent doing the work — which is most of the time, since the point of a briefing is a second perspective rather than the same one restated.

Managing it. An explicit model below overrides whatever model the profile carries, so the two settings interact: profile for persona, model for capability.

ambassador.speech_model

Fallback text-to-speech model for spoken briefings.

Default: — · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. The model used to speak a briefing aloud, when nothing more specific has been chosen.

How it works. A fallback near the end of a chain: an explicit request wins, then the chosen profile’s own voice settings, then this, then a shipped default. That is why this screen has no control for it — the profile editor owns the one you actually set.

When to change it. Set it to establish a house default for installs where profiles do not specify a voice model. Most people never touch it.

Managing it. Writable over the API and documented here, but edited on the ambassador profile in practice. Null means “fall through the chain”, which is the shipped state.

ambassador.transcription_model

Fallback speech-to-text model for talking to the Ambassador.

Default: — · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. The model that turns your recorded speech into text, when nothing more specific has been chosen.

How it works. Same fallback chain as the other two voice settings, and used by both voice mode and the ordinary transcription seam so there is one resolution rather than two.

When to change it. Set it if the default transcription is mishearing domain vocabulary — names, jargon, identifiers — which a better model usually fixes.

Managing it. Null means fall through the chain. As with the others, the profile editor is where this is normally set.

ambassador.voice

Fallback voice for spoken briefings.

Default: — · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. Which voice the speech model uses, when nothing more specific has been chosen.

How it works. Sits in the same fallback chain as the speech model: explicit request → profile → this → shipped default.

When to change it. Set it for a consistent house voice across profiles that do not pick one. Otherwise leave it; a voice is part of an agent’s identity and belongs on the profile.

Managing it. Valid values depend on the speech model — a voice name from one provider will not be recognised by another, and the failure surfaces at speech time rather than when you save.

Intelligence → Research Mode

Deep, cited research with a much larger budget than a normal turn.

A per-conversation mode that raises the tool-round and search budgets, runs sub-questions in batches, and produces a report that reviews its own citations before it returns.

Raise the round limit for genuinely broad questions; lower it to stop research becoming an expensive default. The minimum output budget matters more than it looks — a report starved of tokens returns early and half-formed rather than failing outright.

research.default_depth

The deep-research effort tier research starts from — the main cost dial.

Default: auto · Range: mini / auto / pro · Set via: /api/config/update

What it is. Which tier of deep research the prompt steers toward when it reaches for web_research. The agent may still escalate for the hardest questions.

How it works. Three tiers of increasing thoroughness. At the shipped credit estimate they run roughly $0.04, $0.08 and $0.16 per deep call for mini, auto and pro.

When to change it. Move to mini when research is frequent and the questions are not deep — it quarters the per-call cost against pro. Move to pro when reports come back thin on questions you know have rich source material.

Managing it. auto is the default and lets the provider judge. Read this together with the research search budget: depth sets the price per deep call, the budget sets how many of them a turn may make, and their product is the worst case.

research.enabled

Whether Research Mode can be turned on for a conversation at all.

Default: true · Set via: /api/config/update

What it is. The master switch for the whole feature: an elevated search budget plus a rigorous, self-reviewing research prompt that lands a cited report in the attached Project.

How it works. Off hides the Research chip in the composer everywhere, so no conversation can enter the mode. It does not affect ordinary web search, which keeps its own budget.

When to change it. Leave it on — it costs nothing until a conversation actually uses it. Turn it off on a shared or cost-sensitive install where you would rather no one could start a multi-dollar research turn by clicking a chip.

Managing it. This is a global gate, not a default: turning it on does not put any conversation into research mode. Each conversation opts in.

research.max_tool_rounds

How many tool-use rounds a research turn may take.

Default: 40 · Range: 10 to 80, tool rounds · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. The ceiling on back-and-forth tool rounds within a single research turn, replacing the ordinary chat limit.

How it works. When rounds run out the loop forces an answer with whatever it has. It is deliberately generous so that the search budget is what binds first.

When to change it. Mostly leave it alone. If reports end abruptly or mid-investigation, check whether the search budget ran out first — that is the usual cause, and raising rounds will not help. Raise this only when you have watched a turn hit the round cap with search budget still unspent.

Managing it. Default 40, against a much smaller chat default. If rounds bind before the search budget, the turn force-answers mid-research, which reads as a confident report built on half the evidence — the failure mode worth avoiding.

research.min_max_tokens

A floor on the output budget for a research turn’s replies.

Default: 16384 · Range: 1024 to 200000, tokens · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. The minimum number of output tokens a research completion may be given, overriding the ordinary adaptive budget.

How it works. A research turn must fit its thinking and a full report into one call. The chat-sized budget, which adapts down as context fills, starves exactly that. This floor is still bounded by the model’s real output cap.

When to change it. Raise it if reports are being cut off mid-section. Lower it only to control cost on a model that charges heavily for output — the saving is real but the failure mode is a truncated report, which is worth less than no report.

Managing it. Default 16384. If reports still truncate, the model’s declared output cap is the likelier constraint: a model missing from the catalog falls back to a conservative figure, and setting its real limit under Model Limits unlocks this floor.

search.research_per_turn_limit

The elevated search budget a Research Mode turn may spend.

Default: 40 · Range: 0 to 200, searches per turn · Set via: /api/config/update

What it is. The per-turn search ceiling that replaces the ordinary one whenever a conversation is in Research Mode. This — not the tool-round cap — is what actually governs how deep research goes.

How it works. Swapped in for search.per_turn_limit when the turn carries the research flag. Each ordinary search draws one unit; a deep-research call draws several (see the deep-research weight below), so the budget is spent in uneven bites.

When to change it. Raise it for genuinely broad engagements — a survey of a field, a comparison across many sources. Lower it to keep research from becoming an expensive default. If reports read as thorough but shallow, this is the first number to move, not the tool-round cap.

Managing it. Default 40 — about five times the ordinary budget, and enough for a dozen deep calls or forty cheap ones. 0 means unlimited, which on a metered key is exactly where an unattended research turn can cost real money; prefer a large number to none. The screen projects a worst-case dollar figure as you change this.

web_research.budget_weight

How many budget units one deep-research call costs.

Default: 3 · Range: 1 to 20, budget units per call · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. The number of units a web_research call charges against a turn’s search budget, reflecting that it is one call but an expensive one.

How it works. Charged against whichever budget the turn is running under. At the default, three deep calls cost the same budget as nine ordinary searches.

When to change it. Raise it if deep research is consuming turns that should have done more cheap, broad searching first. Lower it if the weight is stopping research short while actual spend is comfortably within your ceiling.

Managing it. Default 3, against a real cost ratio nearer 5–20× an ordinary search — so the weight understates the money deliberately, to avoid making deep research unusable inside a small budget. If you want the count to track spend honestly, use the dollar ceiling instead; that one measures the real thing.

web_research.cache_ttl_seconds

How long an identical deep-research result is reused.

Default: 1800 · Range: 0 to 86400, seconds · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. A cache of completed deep-research results, keyed by query and depth.

How it works. A repeat of the same query at the same depth inside the window returns the stored report without re-running the investigation or billing for it.

When to change it. Keep it generous. A deep call costs 5–20 credits, so serving a repeat from cache is the single largest saving available here — much more than caching ordinary searches. Shorten it only when the subject genuinely moves within the window.

Managing it. Default 30 minutes, six times the ordinary search cache, because deep research is both expensive and stable. Held in server memory, so a restart clears it.

web_research.enabled

Whether the deep-research tool may be used at all.

Default: true · Set via: /api/config/update

What it is. The agentic deep-research tool — an autonomous multi-query investigation that returns a synthesised, sourced answer rather than a list of links.

How it works. Off makes the tool report itself as disabled rather than blocking the turn, so research falls back to ordinary search plus extraction.

When to change it. Leave it on for real research work; it is the difference between a report built on a dozen sources and one built on three. Turn it off when cost matters more than depth — a single deep call can cost twenty ordinary searches.

Managing it. Independent of Research Mode: the tool is available in ordinary turns too, where it draws on the ordinary search budget and can consume most of it in one call. That interaction is the reason for the deep-research weight below.

web_research.poll_interval_seconds

How often to check whether the report is ready.

Default: 5 · Range: 1 to 60, seconds · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. The gap between polls while waiting for a deep-research task.

How it works. Each poll is a cheap status check, not a re-run. Shorter gaps notice completion sooner; longer gaps make fewer requests.

When to change it. There is rarely a reason to change this. Shorten it only if you want a completed report picked up promptly on short mini calls; lengthen it if polling volume is a concern on a rate-limited key.

Managing it. Default 5 seconds against a timeout measured in minutes, which is a sensible ratio. Setting it near the timeout means the deadline can pass between two polls and a finished report is reported as a timeout.

web_research.poll_timeout_seconds

How long to wait for a deep-research report before giving up.

Default: 240 · Range: 30 to 900, seconds · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. The total wall-clock ceiling on waiting for a deep-research task to finish.

How it works. Deep research is asynchronous: the call starts a task and the result is collected by polling. When this deadline passes the tool returns an error advising a narrower query or a shallower tier, rather than waiting forever.

When to change it. Raise it if pro-tier research routinely times out on questions you need answered — the tiers differ enormously in wall-clock time. Lower it to fail fast on an install where a four-minute pause inside a turn is unacceptable.

Managing it. Default 240 seconds. For scale: mini usually completes in 30–60 seconds, auto in one to two minutes, and pro can genuinely take several. Setting this below your chosen depth’s typical time turns every deep call into a timeout.

Prompts → Prompt Enhancement

Rewriting your prompt into a fuller one before it runs.

An optional pass that expands what you typed into a more complete instruction, using its own model and temperature so it doesn’t draw on the conversation’s budget.

Useful when you type quickly and want intent inferred. Turn it off when you need your exact wording to survive — it rewrites, and a rewrite can drop a constraint you meant literally.

prompt_enhancement.enabled

Whether your prompt is rewritten before it runs.

Default: true · Set via: /api/config/update

What it is. An optional pass that expands what you typed into a fuller instruction before the agent sees it.

How it works. Runs on its own model and budget, so it does not draw on the conversation’s own. The agent receives the rewritten prompt.

When to change it. Useful when you type quickly and want intent inferred. Turn it off when you need your exact wording to survive — it rewrites, and a rewrite can drop a constraint you meant literally.

Managing it. The failure mode is quiet: a request that behaves oddly may have been reworded rather than misunderstood. That is the first thing to rule out.

prompt_enhancement.max_tokens

How long the rewritten prompt may be.

Default: 1000 · Range: 100 to 8000, tokens · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. The output budget for the enhancement pass.

How it works. A rewrite that exceeds the budget is truncated — which produces a prompt cut off mid-sentence, sent to the agent as though complete.

When to change it. Raise it if enhanced prompts arrive incomplete. Lower it to keep enhancement from turning a sentence into an essay.

Managing it. Default 1000. Truncation here is silent and easy to misread as the agent misunderstanding you.

prompt_enhancement.model

Which model rewrites your prompt.

Default: (empty) · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. The model used for the enhancement pass.

How it works. Empty follows the summarizer role. The job is rewriting rather than reasoning, which is why it shares a role with the compression work.

When to change it. Use a fast model — this sits between you pressing send and anything happening, so its latency is the most visible on this screen.

Managing it. A slow model here makes the whole app feel slow in a way that is hard to attribute, because the delay lands before any streaming starts.

prompt_enhancement.temperature

How freely your prompt is rewritten.

Default: 0.7 · Range: 0 to 2 · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. Sampling temperature for the enhancement pass.

How it works. Higher values produce more liberal rewrites; lower ones stay closer to what you actually typed.

When to change it. Lower it if enhanced prompts are drifting from what you meant. There is little upside to raising it — a creatively rewritten instruction is a different instruction.

Managing it. Default 0.7, which is high for a rewriting task. If you use enhancement routinely and find it changes your meaning, this is the setting to lower.

Prompts → Feature Prompts

Override the built-in prompts that features use internally.

The prompts behind extraction, relevance filtering, planning, and prompt enhancement. Each ships with a default; an override replaces it, and a diff shows exactly what you changed.

Worth touching only when a feature misbehaves in a way you can trace to its wording. Left on their defaults, these improve when the defaults do — an override opts that key out of future improvements.

extraction_system_prompt

Replace the built-in instruction the extractor works from.

Default: (empty) · Set via: /api/memory/settings · Advanced — most installs never need to change this.

What it is. The prompt that tells extraction what counts as a fact worth keeping, how to phrase it, and how to attribute it. Empty uses the shipped prompt, which is the normal state.

How it works. An override replaces the built-in prompt entirely rather than adding to it, so anything the shipped prompt established — the output structure, the confidence calibration, the attribution rules — has to be restated or it is simply gone.

When to change it. The last thing to reach for, not the first. If extraction is storing the wrong things, the model and the temperature are far more often the cause. A domain with genuinely unusual notions of what is worth remembering is the case that justifies an override.

Managing it. Edited on Prompts → Feature Prompts, which shows a diff against the shipped prompt. Leaving it empty means extraction improves when the default does; an override opts out of that permanently.

planner.prompt_override

Replace the built-in planning prompt with your own.

Default: (empty) · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. The instruction the planner works from. Empty uses the shipped prompt, which is the normal state.

How it works. An override replaces the built-in prompt entirely rather than appending to it, so anything the shipped prompt established has to be restated.

When to change it. Worth touching only when you can trace a planning failure to the wording — for instance a domain where the default decomposition style is wrong. For per-agent behaviour, the agent’s profile is a better place than a global override.

Managing it. Leaving this empty means the prompt improves when the shipped one does; an override opts out of that permanently. Clear it to return to the default.

prompt_enhancement.system_prompt

Replace the built-in instruction that governs how prompts are rewritten.

Default: (empty) · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. The prompt behind the enhancement pass. Empty uses the shipped one, which is the normal state.

How it works. An override replaces the built-in entirely rather than extending it. Edited on Prompts → Feature Prompts, which diffs it against the default.

When to change it. Worth touching only if you want enhancement to follow house conventions — always ask for sources, always prefer a particular format. Otherwise the shipped prompt improves over time and an override opts out of that.

Managing it. Test any override on a request whose exact wording you care about; the point of failure is a rewrite that quietly drops constraints.

relevance_filter_prompt

Replace the built-in instruction the relevance gate works from.

Default: (empty) · Set via: /api/memory/settings · Advanced — most installs never need to change this.

What it is. The prompt behind the yes/no judgement on whether a turn is worth extracting. Empty uses the shipped prompt.

How it works. As with extraction, an override replaces rather than extends — including the part that makes the answer parseable, so a rewrite that changes the output format silently breaks the gate.

When to change it. Worth touching when your conversations carry value the default definition of “worth remembering” misses — a domain where short confirmations are meaningful, say. Otherwise leave it: this prompt runs on every turn, so a subtly worse one is a cost paid continuously.

Managing it. Edited on Prompts → Feature Prompts with a diff against the default. Test any override by watching whether turns you expect to be stored still are — a broken gate fails quietly, by dropping things.

Memory → Conversation Context

How much of the conversation the model sees, word for word.

Per-turn context assembly — how much of the window recent turns may fill verbatim, when older turns fold into a running digest, and how tool output and long tool loops are compressed on the way in.

The section to visit when a conversation starts losing detail, or when a long tool run is eating the window. With a correctly declared model window, most conversations never compact at all.

compression.enabled

Summarise a single tool result that comes back too large.

Default: true · Set via: /api/config/update

What it is. Compression of one oversized tool output, before it enters the turn.

How it works. A result past the size threshold is summarised task-aware — with the question in view — so what survives is the part that answers it.

When to change it. Leave it on. A single large page or query result can otherwise consume the whole turn. Off, oversized results are truncated instead, which cuts arbitrarily.

Managing it. Distinct from trajectory compression, which compresses across rounds. This one shrinks a single result.

compression.max_summary_chars

How much of an oversized tool result survives compression.

Default: 2000 · Range: 500 to 10000, characters · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. The size budget for the summary that replaces a too-large result.

How it works. The compressor writes within this budget, keeping what answers the query.

When to change it. Raise it when compressed results lose specifics the agent needed — figures, names, exact wording. Lower it when tool output still crowds the turn.

Managing it. Default 2000 characters. If you find yourself raising this a lot, the more effective fix is usually a narrower tool query.

compression.model

Which model summarises oversized tool results.

Default: (empty) · Set via: /api/config/update

What it is. The model used for task-aware compression of a single result.

How it works. Empty follows the Summarizer role; an explicit value overrides it here only.

When to change it. Override when tool-heavy turns feel slow and this is where the time is going.

Managing it. Readers floor to a small fast model.

context.conversation_state_compaction_enabled

Fold aged-out turns into the structured digest instead of free prose.

Default: true · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. Which of the two summary mechanisms receives compacted history.

How it works. On, aged-out turns roll into the conversation state’s digest field, re-summarised in place. Off, they fall back to the legacy free-prose rolling summary.

When to change it. The structured digest is the better default — it sits beside the goals and decisions it relates to, and it’s editable. The prose fallback exists for comparison and for conversations where the structure gets in the way.

Managing it. Inert when context.conversation_state_enabled is off.

context.conversation_state_enabled

Keep a structured working memory for the conversation.

Default: true · Set via: /api/config/update

What it is. A per-conversation record of goals, decisions, open threads and artifacts — plus the rolling digest of aged-out turns.

How it works. Rendered into the prompt as a ledger block. The agent maintains it deliberately through the update_conversation_state tool, and you can edit it yourself from the composer badge.

When to change it. Leave it on for anything long-running: it’s what lets an agent still know the goal after the turn that stated it has aged out. Turning it off hides the block and removes the agent’s tool for it.

Managing it. Structured state is also the default compaction target — see context.conversation_state_compaction_enabled.

context.max_input_tokens

Optional hard ceiling on what one turn may spend on input.

Default: 0 · Range: 0 to 1000000, tokens · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. A per-turn spend guard for the tool loop, in tokens. 0 turns it off.

How it works. With a value set, a turn stops growing its input past this ceiling even if the model’s window would allow more — a brake on runaway multi-round tool loops.

When to change it. Set it when you want a predictable per-turn cost ceiling on an expensive model. Leave it at 0 to let the model’s real window govern, which is the right default now that windows are read accurately.

Managing it. This replaced a flat 32k cap that quietly strangled large-window models. Setting it too low reintroduces exactly that problem — prefer the model’s own window unless you have a billing reason not to.

context.preassembly_summary_enabled

Refresh the digest mid-turn rather than let anything drop uncovered.

Default: true · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. The backstop that guarantees nothing leaves the model’s view without being summarised first.

How it works. Before assembling an over-budget turn, the digest is refreshed so the turns about to age out are already covered. If the summarizer is unavailable, a deterministic fallback digest stands in — coverage does not depend on a model call succeeding.

When to change it. Leave it on. Off, a turn that outgrows its budget can drop history that the digest hasn’t caught up with yet, and the agent silently forgets something you said. The cost is one extra summarisation on the turns that need it.

Managing it. Pre-warm (context.summary_trigger_ratio) is what keeps this from firing often — this is the safety net, not the mechanism.

context.recent_floor

How many recent turns are never summarised, whatever the pressure.

Default: 4 · Range: 1 to 50, turns · Set via: /api/config/update

What it is. The number of most-recent turns that always stay word-for-word.

How it works. Compaction works from the oldest turn forward and stops here. Even a conversation well over budget keeps this many exchanges intact.

When to change it. Raise it if the agent loses the thread of what was just said — the immediate back-and-forth is where that lives. Lower it only if you are severely context-constrained and would rather keep older material in view.

Managing it. Four turns is enough for the model to see what it just said and what you replied. High values interact with the verbatim budget: the floor wins, so setting both aggressively can push assembly against its hard cap.

context.rehydrate_max_turns

How far back to read when reopening a cold conversation.

Default: 400 · Range: 20 to 2000, turns · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. The cap on turns pulled from durable history when a session is resumed.

How it works. Reopening a conversation the server no longer holds in memory replays up to this many turns from storage to rebuild context.

When to change it. Raise it for long-lived conversations you return to across days. Lower it if reopening a large conversation is slow — the cost is read volume at open time, not per turn.

Managing it. This bounds what is read, not what is sent: the verbatim budget still decides how much of it reaches the model.

context.summary_trigger_ratio

When to prepare the digest, ahead of actually needing it.

Default: 0.85 · Range: 0.5 to 0.98, of the history budget · Set via: /api/config/update

What it is. The point at which compaction runs after a turn, so the digest is already fresh the next time older turns need to leave the verbatim window.

How it works. Measured against the turn’s real history budget (input budget minus granted preamble blocks). Crossing it schedules a post-turn pre-warm that folds the oldest turns into the digest.

When to change it. Keep it slightly below the verbatim budget — that gap is the whole point. Pre-warm does the summarising between turns, where you don’t feel it; if this sits at or above the verbatim ceiling, the work lands in the middle of a turn instead and you wait for it.

Managing it. Default 0.85 against a 0.9 verbatim budget. Move the two together and keep the gap; closing it doesn’t save anything, it only changes when you notice the cost.

context.verbatim_budget_ratio

How much of the model’s context window the word-for-word transcript may fill.

Default: 0.9 · Range: 0.5 to 0.98, of the context window · Set via: /api/config/update

What it is. The ceiling on the verbatim window — the stretch of recent conversation the model sees exactly as it happened, rather than as a summary.

How it works. Each turn is sized against the model’s real context window, not a fixed number. Turns are kept verbatim until they would exceed this fraction of it; older ones fold into the conversation-state digest. Assembly still hard-caps at window − reserved output, so this can never squeeze out the reply.

When to change it. Lower it to leave room for a long answer, or if you are paying per token and would rather summarise sooner. Raise it to keep more exact wording in view — worth it when detail matters more than cost. It was 0.7 and is now 0.9 deliberately: compressing at 70% of a large window discarded detail long before anything was actually short of room.

Managing it. With a correct window configured (Model Limits), most conversations never compact at all. If yours compact constantly, check the model’s declared window before touching this — an understated window is the usual cause.

memory.episodic_leads_enabled

Offer pointers to earlier conversations that look related.

Default: true · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. Short leads drawn from episodic memory — “we discussed this on…” — rather than full recalled content.

How it works. Derived per turn and injected as a low-priority block, so they yield to the transcript and the state ledger when room is tight.

When to change it. Leave it on for continuity across conversations. Turn it off if leads to unrelated past chats are distracting the agent, or if you want per-turn context strictly scoped to the conversation at hand.

Managing it. Leads are pointers, not recall; the Recall layer is what fetches actual content. They ride at low priority and are the first thing dropped under pressure.

session.rolling_summary.enabled

Whether conversations compact automatically at all.

Default: true · Set via: /api/config/update

What it is. The master switch for automatic compaction, whichever target it writes to.

How it works. Off, no automatic summarisation runs: turns stay verbatim until they hit the budget and then simply leave view.

When to change it. Leave it on. Off is for diagnosing whether a context problem comes from compaction — useful briefly, lossy as a standing setting.

Managing it. Gates both the structured digest and the legacy prose summary. Named for the original prose mechanism, which the digest has since superseded as the default.

session.rolling_summary.max_tokens

How long one compaction pass may make the digest.

Default: 800 · Range: 200 to 4000, tokens · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. The output budget for a single summarisation pass.

How it works. The digest is re-summarised in place on each pass, so this effectively bounds its steady-state size rather than letting it grow with the conversation.

When to change it. Raise it when long conversations lose detail you needed. Lower it when the digest itself is eating the context you wanted for live turns.

Managing it. Default 800 tokens. Because each pass rewrites the whole digest, raising this raises both the summarisation cost and the standing per-turn cost of carrying it.

session.rolling_summary.model

Which model writes the compaction summaries.

Default: (empty) · Set via: /api/config/update

What it is. The model used to fold aged-out turns into the digest.

How it works. Empty follows the Summarizer role, which is the recommended setting — set the role once and every summarising job follows it. An explicit value overrides the role for this job only.

When to change it. Override it when compaction specifically is too slow or too lossy, and you want a different trade-off here than for other summarising work.

Managing it. Readers floor this to a small fast model regardless; compaction runs often and rarely benefits from a large one.

trajectory_compression.enabled

Compress earlier tool rounds during a long turn.

Default: true · Set via: /api/config/update

What it is. In-turn compression of the trajectory — the accumulated tool calls and results within a single turn.

How it works. When a turn’s context crosses the trigger threshold, earlier rounds are replaced by a compact knowledge block, keeping the most recent rounds intact.

When to change it. Leave it on for agents that use tools heavily; a research or multi-step turn can otherwise fill the window with intermediate results before it reaches an answer. Off, long tool loops hit the ceiling sooner.

Managing it. Distinct from tool-output compression, which shrinks one oversized result.

trajectory_compression.max_knowledge_chars

How large the compressed knowledge block may be.

Default: 3000 · Range: 500 to 10000, characters · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. The size cap on the block that replaces compressed tool rounds.

How it works. The compressor writes within this budget; the block persists for the rest of the turn.

When to change it. Raise it when compression is dropping details the agent then has to re-fetch — re-running a tool costs more than carrying a few hundred extra characters. Lower it when the block itself is crowding the turn.

Managing it. Default 3000 characters. Weigh against the cost of the tool call it saves.

trajectory_compression.model

Which model compresses tool rounds mid-turn.

Default: (empty) · Set via: /api/config/update

What it is. The model that writes the knowledge block replacing earlier rounds.

How it works. Empty follows the Summarizer role; an explicit value overrides it here only.

When to change it. Override when in-turn compression is adding noticeable latency — this one runs inside the turn, so its speed is felt directly.

Managing it. Readers floor to a small fast model; latency matters more than nuance here.

trajectory_compression.preserve_recent_rounds

How many recent tool rounds survive compression untouched.

Default: 2 · Range: 1 to 5, rounds · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. The number of most-recent tool-call rounds always kept in full.

How it works. Compression works forward from the oldest round and stops here.

When to change it. Raise it if the agent loses track of what a tool just returned. Lower it to reclaim more room when rounds are large.

Managing it. Two rounds is usually enough to keep the immediate call-and-result pair intact. This is a floor, like context.recent_floor but within a turn.

trajectory_compression.threshold_ratio

How full a turn gets before earlier tool rounds are compressed.

Default: 0.75 · Range: 0.5 to 0.95, of the turn budget · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. The fraction of the turn’s budget that triggers in-turn compression.

How it works. Crossing it compresses all but the most recent rounds into a knowledge block.

When to change it. Lower it for agents that routinely run long tool loops — compressing earlier keeps more headroom for the rounds that matter. Raise it to keep raw tool output visible longer, at the cost of hitting the ceiling sooner.

Managing it. Default 0.75. Below about 0.5 you compress work that had room to breathe.

Also in this area — values that are read-only over the API. Set them in .env or the settings file directly and restart; they have no control and no per-setting write-up:

SettingTypeDefaultStoreSet via
compression.max_tokensint1000configread-only
compression.temperaturefloat0.2configread-only
trajectory_compression.max_tokensint1500configread-only
trajectory_compression.temperaturefloat0.2configread-only

Memory → Recall

How the agent searches its own memory for a turn.

Five retrieval techniques over stored memory — hybrid keyword-and-meaning search, entity-centric expansion, query expansion, HyDE, and self-query — followed by a cross-encoder that re-ranks whatever they found.

Turn techniques on for recall quality and off for latency and cost: each is another pass over the same memory. Every knob here belongs to exactly one technique, so a technique you’ve turned off costs nothing anywhere else.

cross_encoder_enabled

Re-score the shortlist with a slower, more accurate model before answering.

Default: true · Set via: /api/memory/recall-settings

What it is. The second stage of retrieval. The fast searches propose a pool of candidates; a cross-encoder then reads each candidate together with the query and re-orders them. Worth about +20pp MRR on the golden recall set.

How it works. Stage 1 deliberately over-fetches recall_candidate_pool candidates. Stage 2 scores each one against the query with cross_encoder_model — which, unlike an embedding search, sees query and candidate at the same time and can judge whether one actually answers the other — then cuts back to top-k. The model lazy-loads on first use, and a failure is non-fatal: recall falls back to stage-1 order.

When to change it. Leave it on. It is the single largest accuracy win in the recall path. Turn it off only where the model cannot be loaded, or where per-turn latency is tighter than answer quality.

Managing it. Governs recall_candidate_pool and recall_ce_max_demotion — with this off, both are inert. First use pays a one-time model load.

cross_encoder_model

The Hugging Face cross-encoder that re-scores candidates.

Default: cross-encoder/ms-marco-MiniLM-L-6-v2 · Set via: /api/memory/recall-settings

What it is. A local sentence-transformers cross-encoder identifier, loaded on first recall.

How it works. Downloaded and cached on first use, then held in memory. It runs locally on CPU or GPU — no API calls, no per-query cost, so it never appears in usage or spend.

When to change it. Change only to trade size against accuracy. The default (ms-marco-MiniLM-L-6-v2) is small and fast and is what the +20pp figure was measured with; a larger ms-marco variant scores better and costs more latency and memory per turn.

Managing it. Must be a cross-encoder, not a bi-encoder or embedding model — an embedding model here will load and produce meaningless scores rather than fail loudly. Changing it triggers a fresh download on the next recall.

recall_candidate_pool

How many candidates the reranker gets to look at.

Default: 50 · Range: 10 to 200, candidates · Set via: /api/memory/recall-settings

What it is. The size of the shortlist stage 1 hands to stage 2. Deliberately much larger than the number of facts that end up in the prompt.

How it works. The fused searches keep this many candidates; the cross-encoder scores all of them and the top-k survive. Reranking cost scales roughly linearly with this number.

When to change it. Raise it when the right fact exists but never reaches the prompt — a bigger pool gives the reranker a chance to find something the fast search ranked poorly. Lower it when recall is accurate but slow. Below about 20 the reranker has nothing to work with and the whole second stage stops earning its cost.

Managing it. Pointless without cross_encoder_enabled. The default of 50 against a typical top-k of 5–10 is roughly a 5–10× over-fetch, which is the intended shape.

recall_ce_max_demotion

How far the reranker may push a candidate down — a hedge against its blind spots.

Default: 2 · Range: 0 to 20, places · Set via: /api/memory/recall-settings

What it is. A cap on the reranker’s pessimism. It may promote a candidate as far as it likes, but it may only demote one this many positions below where fusion placed it.

How it works. After scoring, each candidate’s new rank is clamped so it cannot fall more than this many places relative to its fused rank. Promotion is unclamped.

When to change it. Cross-encoders are strong on average and occasionally confidently wrong — a fact the keyword and vector searches both ranked first should not vanish because one model disliked it. Raise it if you trust the encoder more than fusion; set it to 0 to freeze fusion’s order against any demotion at all.

Managing it. Asymmetric by design; don’t read it as a general “trust” dial. Values above ~5 effectively remove the hedge, since few candidates move that far.

recall_enable_entity_centric

Find facts by walking the entity graph instead of matching text.

Default: true · Set via: /api/memory/recall-settings

What it is. A retrieval path that goes through things rather than words. When a query names an entity the agent already knows, its facts are pulled directly from the graph.

How it works. Entities are matched from the query above recall_entity_similarity_threshold, up to recall_entity_max_entities of them. Facts attached to those entities are collected, following relationships out to recall_entity_graph_depth hops.

When to change it. Keep it on when the agent accumulates knowledge about recurring people, projects, or systems. It answers questions text search cannot — “what do we know about Redis” returns facts that never contain the word “Redis” but hang off that entity. The cost is a graph query per turn.

Managing it. If it returns loosely-related material, raise recall_entity_similarity_threshold before reaching for graph depth. Depth is the expensive dial, not the threshold.

recall_enable_hybrid

Search memory by keyword and by meaning at once, then fuse the two rankings.

Default: true · Set via: /api/memory/recall-settings

What it is. The default way memory is searched. Two searches run over the same facts: BM25 keyword matching (does this text contain these words?) and vector similarity (does this text mean something close?). Their rankings are then merged.

How it works. Both searches run against the channel list for the turn, each producing a ranked list. The lists are fused with Reciprocal Rank Fusion — a fact scores on where it placed in each list rather than on raw scores, so two incomparable scoring systems can be combined without normalising them. A fact ranked well by both rises highest.

When to change it. Leave it on. Keyword-only search misses paraphrase (“what does she drive” vs “her car is a Volvo”); vector-only search misses exact tokens (identifiers, error codes, names it has never seen). Fusing covers both failure modes at the cost of one extra query. Turn it off only to isolate a retrieval problem while debugging.

Managing it. The balance between the two is recall_hybrid_bm25_weight and recall_hybrid_vector_weight; the fusion constant is recall_hybrid_rrf_k. With this off, those three do nothing.

recall_enable_hyde

Imagine the answer first, then search for facts that look like it.

Default: false · Set via: /api/memory/recall-settings

What it is. Hypothetical Document Embedding. Instead of searching with the question, the agent drafts a plausible answer and searches with that — because a made-up answer sits much closer in vector space to the real one than the question does.

How it works. A small model (recall_hyde_model) writes a short hypothetical answer at recall_hyde_temperature, capped at recall_hyde_max_tokens. That text is embedded and used as the vector query. The invented answer is never shown to anyone and never stored — it exists only to shape the search.

When to change it. Enable for abstract or explanatory questions, where question and answer share few words. It costs a real LLM call on every recall, so it is the most expensive technique here — the first thing to disable if recall latency matters more than recall depth.

Managing it. Needs a working model; leave recall_hyde_model empty to follow the Fast Utility role rather than pinning one. Keep recall_hyde_max_tokens small (~150) — you need the shape of an answer, not a good one.

recall_enable_query_expansion

Rewrite the question a few ways before searching, so phrasing matters less.

Default: true · Set via: /api/memory/recall-settings

What it is. A pre-search step that generates alternative phrasings of the query and searches with all of them, so a stored fact worded differently from the question still surfaces.

How it works. The query is transformed into up to recall_expansion_max_variants variants — “When is my birthday?” also becomes “birthday is”, “born on” — each is searched, and the results are merged and deduplicated.

When to change it. Worth keeping on. Stored facts are declarative (“her birthday is in March”) while questions are interrogative; the mismatch is the single most common reason a fact that exists fails to come back. Costs one extra search per variant.

Managing it. Raise recall_expansion_max_variants only if recall is visibly missing rephrased facts — each variant is another search, and the return falls off quickly past 3.

recall_enable_self_query

Pull filters out of the question — dates, names — and search within them.

Default: false · Set via: /api/memory/recall-settings

What it is. A step that reads structured constraints out of natural language, so “what did we decide last week” becomes a search restricted to last week rather than a text search containing the words “last week”.

How it works. A small model (recall_self_query_model) extracts filters — time ranges, entity names, keywords — at recall_self_query_temperature, capped at recall_self_query_max_tokens. Extracted filters narrow the candidate set before ranking.

When to change it. Enable when questions carry real constraints — time-bounded, person-scoped, project-scoped. Without it, “last week” is just two more tokens to match and the agent happily returns something from March. Like HyDE it costs an LLM call.

Managing it. Keep temperature low (0.2) — this is extraction, not writing; creativity here means invented filters that silently exclude the right answer.

recall_entity_graph_depth

How many relationship hops out from a matched entity to gather facts.

Default: 1 · Range: 1 to 5, hops · Set via: /api/memory/recall-settings · Advanced — most installs never need to change this.

What it is. The traversal radius in the entity graph. Depth 1 means the entity’s own facts; depth 2 also means facts about everything it is directly related to.

How it works. Facts are collected breadth-first from each matched entity out to this many hops. Because real graphs are densely connected, each additional hop multiplies rather than adds to the set.

When to change it. Keep it at 1 unless you have a specific reason. Depth 2 answers genuinely relational questions (“who else works on what she works on”) and is the point where recall starts pulling in loosely-connected noise. Depth 3+ is rarely useful and reliably slow.

Managing it. The most expensive dial in this section. If recall gets vague after raising it, that is the cause — lower it before adjusting anything else.

recall_entity_max_entities

How many entities one query may pull facts from.

Default: 5 · Range: 1 to 20, entities · Set via: /api/memory/recall-settings

What it is. A ceiling on entity fan-out per recall.

How it works. Matched entities are ranked by similarity and the top N are used. Everything below the cut is ignored regardless of score.

When to change it. Raise it for questions that legitimately span many things (“how do our services talk to each other”). Lower it to keep recall tight and the prompt focused — each extra entity brings its whole fact set.

Managing it. Interacts multiplicatively with recall_entity_graph_depth: 5 entities at depth 2 is a much wider sweep than the numbers suggest. Prefer raising this over raising depth.

recall_entity_similarity_threshold

How confident the match must be before a query is linked to a known entity.

Default: 0.65 · Range: 0.3 to 0.95 · Set via: /api/memory/recall-settings

What it is. The minimum similarity for text in the query to be treated as naming an entity.

How it works. Query terms are compared against known entity names; anything at or above this score is treated as a reference to that entity and its facts are pulled in.

When to change it. Raise it (towards 0.9) when the agent drags in facts about the wrong “Alex” or the wrong project — that is a threshold set too low. Lower it (towards 0.5) when entities are referred to loosely, by nickname or abbreviation, and are being missed.

Managing it. The first dial to reach for on entity-recall problems, ahead of recall_entity_max_entities or graph depth. Below ~0.5 nearly everything matches something and the technique stops discriminating.

recall_expansion_max_variants

How many alternative phrasings of the question to search with.

Default: 3 · Range: 1 to 10, variants · Set via: /api/memory/recall-settings

What it is. The cap on generated query variants per recall.

How it works. Each variant is searched separately and the results are merged and deduplicated.

When to change it. Raise it when facts are stored in wording consistently unlike how they’re asked about. Lower it to cut per-turn search cost. Returns diminish quickly — the third variant rarely finds what the first two missed.

Managing it. Every variant is another full search, so this multiplies retrieval cost directly. Inert unless recall_enable_query_expansion is on.

recall_first_person_guard

Penalise facts whose subject is ambiguous between the user and the agent.

Default: false · Set via: /api/memory/recall-settings · Experimental — unproven; may change or be withdrawn.

What it is. An experimental attribution guard. It down-weights facts where “I” or “my” makes it unclear whether the statement is about the user or about the agent itself.

How it works. Candidates with ambiguous first-person attribution have their score reduced by recall_first_person_penalty before ranking.

When to change it. Off by default, and it should stay off unless you are specifically investigating attribution errors. It failed its abstention gate in evaluation — it suppressed correctly-attributed facts alongside ambiguous ones. See Memory-Roadmap §2.11.

Managing it. Experimental. Turning it on will change recall in ways the golden set does not model, so re-run eval_recall before and after and compare rather than trusting the feel.

recall_first_person_penalty

How hard the attribution guard penalises an ambiguous fact.

Default: 0.5 · Range: 0 to 1 · Set via: /api/memory/recall-settings · Experimental — unproven; may change or be withdrawn.

What it is. The score reduction applied to first-person-ambiguous candidates.

How it works. Subtracted from the candidate’s score before ranking; 1.0 is effectively exclusion.

When to change it. Only meaningful with recall_first_person_guard on. Lower values de-prioritise ambiguous facts while keeping them reachable; higher values remove them from consideration entirely.

Managing it. Inert while the guard is off. Given the guard’s evaluation history, prefer a gentle value (~0.3) over exclusion if you enable it at all.

recall_hybrid_bm25_weight

How much keyword matching counts when fusing the two searches.

Default: 0.3 · Range: 0 to 1 · Set via: /api/memory/recall-settings

What it is. The weight given to the BM25 (exact-token) ranking during fusion.

How it works. Scales BM25’s contribution to each candidate’s fused score before ranking.

When to change it. Raise it when the memory is full of identifiers, error strings, code, or proper nouns — text where the exact token is the signal. Lower it for conversational memory, where the same idea is worded differently every time.

Managing it. Read together with recall_hybrid_vector_weight; the two are usually kept summing to 1.0 (default 0.3 / 0.7, favouring meaning over tokens). Nothing enforces that sum — it is a convention that keeps the numbers interpretable.

recall_hybrid_rrf_k

How sharply top ranks are favoured when merging the two result lists.

Default: 60 · Range: 1 to 200 · Set via: /api/memory/recall-settings · Advanced — most installs never need to change this.

What it is. The Reciprocal Rank Fusion constant. Each list contributes 1/(k + rank), so k sets how steeply the reward falls off with position.

How it works. Low k makes first place worth far more than third — fusion becomes winner-take-all. High k flattens the curve, so agreement across both lists matters more than being first in either.

When to change it. Rarely worth touching; 60 is the value the RRF literature settled on and what the defaults were tuned against. Lower it only if you want one strong signal to dominate; raise it to reward consensus.

Managing it. Applies only when recall_enable_hybrid is on. Change it one step at a time and re-run eval_recall — the effect is real but not intuitive from the number alone.

recall_hybrid_vector_weight

How much semantic similarity counts when fusing the two searches.

Default: 0.7 · Range: 0 to 1 · Set via: /api/memory/recall-settings

What it is. The weight given to the vector (meaning) ranking during fusion.

How it works. Scales the vector ranking’s contribution to each candidate’s fused score.

When to change it. The default 0.7 favours meaning, which suits conversational memory where paraphrase is the norm. Lower it if the agent returns thematically-related but factually wrong material — that is vector search over-reaching.

Managing it. Counterpart to recall_hybrid_bm25_weight; conventionally the two sum to 1.0.

recall_hyde_max_tokens

Length cap on the hypothetical answer.

Default: 150 · Range: 50 to 2000, tokens · Set via: /api/memory/recall-settings

What it is. The token ceiling for the drafted answer before it is embedded.

How it works. Generation stops here. Because the text is embedded as a whole, a longer draft dilutes the query’s focus as much as it enriches it.

When to change it. 150 is the sweet spot: enough for a couple of sentences with the right shape and vocabulary. Raise it only for genuinely multi-part questions. Larger drafts cost more latency on every single recall and typically retrieve worse.

Managing it. If you find yourself raising this a lot, the real problem is usually a query that should have been split, not a draft that should be longer.

recall_hyde_model

The model that drafts the hypothetical answer. Empty follows the Fast Utility role.

Default: inherit · Set via: /api/memory/recall-settings

What it is. The small, fast model used to invent a plausible answer for HyDE to search with. Never writes anything the user sees.

How it works. Called once per recall when HyDE is enabled. Left empty, it follows the Fast Utility model role, so changing that role updates this and every other utility call at once.

When to change it. Pin a model only when you need this specific step to differ from every other utility call. Quality matters far less than usual here — the draft is thrown away after embedding, so pick the cheapest, fastest thing that writes a coherent sentence.

Managing it. Prefer leaving it empty and setting the Fast Utility role instead. A slow model here is felt on every recall, not just hard ones.

recall_hyde_temperature

How varied the hypothetical answer is allowed to be.

Default: 0.7 · Range: 0 to 1 · Set via: /api/memory/recall-settings

What it is. Sampling temperature for the HyDE draft.

How it works. Higher values produce more varied drafts, which move the embedded query further afield.

When to change it. The default 0.7 is deliberately loose — some variation helps the draft land near differently-worded real answers. Lower it towards 0.2 if HyDE is dragging in off-topic material; raise it if it keeps producing the same narrow phrasing and missing paraphrased facts.

Managing it. Only affects retrieval. It can never affect what the agent actually says.

recall_min_confidence

The score a fact must reach before it may enter the prompt at all.

Default: 0.5 · Range: 0 to 1 · Set via: /api/memory/recall-settings · Advanced — most installs never need to change this.

What it is. A floor applied after all techniques and reranking have run. Anything below it is dropped rather than ranked.

How it works. Final scores are compared against this value; failures are discarded before top-k.

When to change it. Raise it when the agent cites weakly-related memories — a hard floor is more predictable than tuning individual techniques. Lower it when you know a fact is stored and it still never appears. Set too high, recall goes silent and the agent looks amnesiac.

Managing it. Applies across every technique, so it is the bluntest instrument here. Move it in 0.05 steps and re-run eval_recall; large jumps make retrieval hard to reason about.

recall_self_query_max_tokens

Length cap on the extracted filter set.

Default: 200 · Range: 50 to 2000, tokens · Set via: /api/memory/recall-settings

What it is. The token ceiling for the structured filter output.

How it works. Generation stops here; a truncated filter set is discarded rather than half-applied.

When to change it. 200 comfortably fits a normal filter set. Raise it only if you see extraction being cut off on complex multi-constraint questions.

Managing it. Rarely the cause of a recall problem. Check the model and temperature first.

recall_self_query_model

The model that extracts filters from the question. Empty follows the Fast Utility role.

Default: inherit · Set via: /api/memory/recall-settings

What it is. The small model that reads dates, names, and keywords out of natural language.

How it works. Called once per recall when self-query is enabled, and asked for structured output. Left empty, it follows the Fast Utility model role.

When to change it. Pin one only if the role’s model is unreliable at structured extraction. This is a parsing job, not a reasoning job — a capable small model is the right choice.

Managing it. Prefer leaving it empty and setting the Fast Utility role. A model that returns malformed filters degrades quietly: recall simply proceeds unfiltered.

recall_self_query_temperature

How deterministic filter extraction is. Keep it low.

Default: 0.2 · Range: 0 to 1 · Set via: /api/memory/recall-settings

What it is. Sampling temperature for the extraction call.

How it works. Low values make the same question yield the same filters every time.

When to change it. 0.2 is right, and there is little reason to raise it. Creativity in extraction means invented constraints — a date range nobody asked for — which silently excludes the correct answer and looks like a memory failure.

Managing it. If self-query produces odd filters, lower this before changing the model.

Memory → Consolidation

Turning finished conversations into facts, entities, and procedures.

The background pipeline that reads completed turns and keeps what’s worth keeping: facts and their confidence, entities and the links between them, contradictions and corrections against what is already stored, and distilled “how we work” procedures.

Raise the confidence thresholds when memory accumulates things that aren’t true; lower them when it drops things you said plainly. The job intervals decide how quickly a conversation becomes memory at all.

combined_extraction_max_tokens

How much the combined pass may return.

Default: 2000 · Range: 200 to 8000, tokens · Set via: /api/memory/settings · Advanced — most installs never need to change this.

What it is. The output budget for the merged call.

How it works. It carries both the relevance verdict and the extracted facts, so it needs at least what extraction alone would.

When to change it. Raise it if dense windows lose their later facts. Lower it only to control cost, accepting truncation.

Managing it. Default 2000, matching plain extraction.

combined_extraction_model

Which model runs relevance and extraction as one call.

Default: inherit · Set via: /api/memory/settings

What it is. A merged path that answers “is this worth storing” and “what is in it” in a single call rather than two.

How it works. inherit follows the bulk default, then the Deep Reasoning role — the only memory stage that does, because doing both jobs at once is harder than either alone and quality here pays for itself.

When to change it. Combining cuts memory’s LLM calls by roughly three quarters, which is the single largest saving in the system. That is worth a better model than the individual stages would need.

Managing it. This is the reason memory’s cost does not scale the way the stage list suggests. If you point it at a weak model to save money you may lose more to bad extraction than you save on the call.

combined_extraction_temperature

How literally the combined pass reads.

Default: 0.3 · Range: 0 to 1 · Set via: /api/memory/settings · Advanced — most installs never need to change this.

What it is. Sampling temperature for the merged relevance-plus-extraction call.

How it works. Slightly above the plain extraction default, because the combined call is doing a judgement as well as a reading.

When to change it. Keep it low. The same rule applies as for extraction: creativity here means facts nobody stated.

Managing it. Default 0.3, against extraction’s 0.2 — a deliberate difference, not drift.

contradiction_detection_enabled

Notice when a new fact conflicts with one already stored.

Default: true · Set via: /api/memory/settings

What it is. A check that runs as facts are written: does this contradict something memory already believes?

How it works. Three layers, cheapest first. A fast gate discards near-identical duplicates; a semantic search pulls a handful of possibly-conflicting facts; only then does an LLM judge whether there is a real contradiction. Most new facts never reach the third layer.

When to change it. Leave it on. Without it, memory accumulates both “she drives a Volvo” and “she drives a Škoda” and retrieval will happily return either, with no indication that one superseded the other. That failure is invisible until it produces a confidently wrong answer.

Managing it. Costs an LLM call only for facts that survive the first two layers, so the typical per-fact cost is far below what a per-fact LLM check would imply.

contradiction_max_candidates

How many possible conflicts are judged per new fact.

Default: 10 · Range: 1 to 50, candidates · Set via: /api/memory/settings · Advanced — most installs never need to change this.

What it is. A cap on the candidates from the semantic search that reach the LLM.

How it works. Candidates are taken in similarity order, so the cap drops the least similar. It bounds the worst-case cost of storing one fact.

When to change it. Raise it when memory is large and contradictions are being missed because the real conflict ranked eleventh. Lower it to bound cost on a busy install.

Managing it. Default 10. This multiplies against the contradiction model’s price on every fact that reaches layer three, so it is the main cost lever here.

contradiction_max_tokens

How much room the contradiction judgement has.

Default: 500 · Range: 100 to 4000, tokens · Set via: /api/memory/settings · Advanced — most installs never need to change this.

What it is. The output budget for the contradiction call.

How it works. As with the relevance gate, the verdict is short but a reasoning model needs room to reach it.

When to change it. Raise it if contradictions are going undetected on a reasoning model. Otherwise leave it alone.

Managing it. Default 500. Unused budget costs nothing.

contradiction_model

Which model judges whether two facts really conflict.

Default: inherit · Set via: /api/memory/settings · Advanced — most installs never need to change this.

What it is. The model used for the third and final layer of contradiction detection.

How it works. inherit follows the bulk default, then the Fast Utility role. It only sees candidates the cheaper layers could not resolve.

When to change it. Worth a capable model precisely because it runs rarely. Deciding that “lives in Berlin” and “moved to Munich” conflict, while “likes coffee” and “drinks tea” do not, is a genuine judgement.

Managing it. If memory is flagging contradictions between facts that are merely different, this model — not the thresholds — is usually the cause.

contradiction_similarity_threshold

How related a stored fact must be to be checked for conflict.

Default: 0.5 · Range: 0.1 to 1.0, cosine similarity · Set via: /api/memory/settings · Advanced — most installs never need to change this.

What it is. The second layer: how wide a net to cast when searching for facts that might contradict a new one.

How it works. Stored facts above this similarity become candidates for the LLM judgement. A lower bar means more candidates, which means more of the expensive third layer runs.

When to change it. Raise it to cut contradiction-checking cost, accepting that conflicts between loosely-worded facts get missed. Lower it if you know contradictions are slipping through — the pair that conflicts may simply not be similar enough in wording to have been compared.

Managing it. Default 0.5, much lower than the duplicate bar, because contradicting facts often share little vocabulary — “she moved to Munich” and “lives in Berlin” conflict without sounding alike.

contradiction_temperature

How consistent the contradiction judgement is.

Default: 0.2 · Range: 0 to 1 · Set via: /api/memory/settings · Advanced — most installs never need to change this.

What it is. Sampling temperature for the contradiction call.

How it works. Low values make the same pair of facts get the same verdict each time.

When to change it. Keep it low. An inconsistent verdict here means the same conflict is sometimes resolved and sometimes left in memory, which is worse than either behaviour applied consistently.

Managing it. Default 0.2, matching the other judgement stages.

correction_detection_enabled

Catch “actually, I meant…” and fix what was stored.

Default: true · Set via: /api/memory/settings

What it is. Detection of implicit corrections: you restating something you said earlier, differently.

How it works. Runs at extraction time, so a correction in the same conversation is caught as the conversation is consolidated rather than surfacing later as a contradiction between two stored facts.

When to change it. Leave it on. Without it, “no, her birthday is in March” becomes a second fact rather than a replacement, and both are retrievable. Contradiction detection would eventually notice, but only after both are already stored.

Managing it. This and contradiction detection cover the same failure from two sides: this one catches corrections as they happen, that one catches conflicts that got through. Both on is the intended state.

correction_max_tokens

How much room correction detection has to answer.

Default: 500 · Range: 100 to 4000, tokens · Set via: /api/memory/settings · Advanced — most installs never need to change this.

What it is. The output budget for the correction call.

How it works. Short answer, but reasoning models need room to reach it.

When to change it. Raise it only if corrections are being missed on a reasoning model.

Managing it. Default 500.

correction_model

Which model spots a correction.

Default: inherit · Set via: /api/memory/settings · Advanced — most installs never need to change this.

What it is. The model used to decide whether a statement corrects an earlier one.

How it works. inherit follows the bulk default, then the Fast Utility role.

When to change it. A cheap model is usually fine — corrections are linguistically marked (“actually”, “no”, “I meant”) and easy to spot. Raise it only if implicit corrections without those markers are being missed.

Managing it. Shares its shape with the other judgement stages; if you are setting one of them explicitly, set them together or use the bulk default.

correction_temperature

How consistent correction detection is.

Default: 0.2 · Range: 0 to 1 · Set via: /api/memory/settings · Advanced — most installs never need to change this.

What it is. Sampling temperature for the correction call.

How it works. Low values keep the same phrasing getting the same verdict.

When to change it. Keep it low, for the same reason as the other judgement stages: an inconsistent verdict means the same correction is sometimes applied and sometimes not.

Managing it. Default 0.2.

entity_linking_enabled

Reconnect facts to the entities they are about, after the fact.

Default: true · Set via: /api/memory/settings

What it is. A background pass that finds facts whose subject was never linked to a real entity and attaches them where they belong.

How it works. Runs after consolidation, over history rather than just new material — which is how a person first mentioned in passing months ago gets their earlier facts attached once the system properly knows who they are.

When to change it. Leave it on. Entity-centric recall — the technique that answers “what do we know about X” — can only return facts that are actually attached to X. An orphaned fact is invisible to it however true it is.

Managing it. This is the repair pass, not the write path: facts are linked at write time too. It exists because write-time linking cannot know about an entity that does not exist yet.

entity_linking_max_facts

How many orphaned facts one backfill run may examine.

Default: 5000 · Range: 100 to 100000, facts per run · Set via: /api/memory/settings · Advanced — most installs never need to change this.

What it is. A cap on the facts scanned per run, bounding both time and memory use.

How it works. The run stops at the cap; the remainder is picked up next time, so a large backlog drains across several runs.

When to change it. Raise it to clear a big history faster — most relevant just after enabling linking on an install with a lot of accumulated memory. Lower it if the backfill job is competing for resources with live work.

Managing it. Default 5000. Read together with the run interval below: the two decide how long a backlog takes to clear.

entity_linking_max_ngram

The longest entity name, in words, the matcher will look for.

Default: 4 · Range: 1 to 8, words · Set via: /api/memory/settings · Advanced — most installs never need to change this.

What it is. How many consecutive words are considered as a possible entity name when scanning a fact’s text.

How it works. The matcher tries spans up to this length. Longer spans mean more combinations to check on every fact.

When to change it. Raise it if you work with long proper names — organisations, product lines, paper titles — that are being missed because they exceed the span. Lower it to speed up scanning where names are short.

Managing it. Default 4 words, which covers most personal and product names. The cost grows with the setting on every fact scanned, so raise it deliberately.

entity_linking_model

Which model resolves ambiguous entity matches.

Default: inherit · Set via: /api/memory/settings · Advanced — most installs never need to change this.

What it is. The model used when LLM disambiguation is on.

How it works. inherit follows the bulk default, then the Fast Utility role. It does nothing unless disambiguation is enabled above.

When to change it. Set it only if you have turned disambiguation on and it is choosing wrongly. Distinguishing two people with the same name from context is a real judgement and rewards a better model.

Managing it. Leaving disambiguation off makes this setting inert — worth checking before concluding that a model change here did nothing.

entity_linking_similarity_threshold

How confident a match must be before it is even considered.

Default: 0.75 · Range: 0.3 to 1.0, cosine similarity · Set via: /api/memory/settings · Advanced — most installs never need to change this.

What it is. The lower bound of the band in which a possible entity match is recorded but never acted on automatically.

How it works. Matches at or above this bar, but below the separate auto-merge bar, are logged only — a grey zone kept as evidence for later adjudication, deliberately not merged. Below this bar, nothing is recorded at all.

When to change it. Lower it to widen the grey zone and gather more borderline cases; raise it to keep the log clean. Neither direction causes a merge on its own, which is what makes this safe to move.

Managing it. Default 0.75. The important property: this setting cannot cause two entities to be wrongly merged, because everything in its band is observation rather than action.

entity_linking_use_llm_disambiguation

Ask a model when the name is genuinely ambiguous.

Default: false · Set via: /api/memory/settings · Advanced — most installs never need to change this.

What it is. Whether ambiguous matches — two plausible entities with the same name — get an LLM judgement rather than being left alone.

How it works. Off by default. On, ambiguous cases cost a model call each during the backfill run.

When to change it. Turn it on if you accumulate people or projects with similar names and facts keep landing on the wrong one. It ships off because the failure it prevents is rarer than the cost it adds on a large history.

Managing it. Cost scales with how ambiguous your entity graph is, not with its size — an install with distinctive names will barely notice it.

extraction_condense_facts

Store atomic facts rather than whole sentences.

Default: true · Set via: /api/memory/settings · Advanced — most installs never need to change this.

What it is. A post-step that reduces verbose statements to single, self-contained facts.

How it works. “I think I mentioned that my sister Anna lives in Berlin now” becomes the fact rather than the sentence. Atomic facts retrieve better because each one matches on its own terms instead of being buried in context.

When to change it. Leave it on. Retrieval works on units of meaning; a paragraph stored whole matches poorly and returns a lot of irrelevant text when it does match. Turn it off only if you specifically want the original phrasing preserved.

Managing it. Condensing loses hedging and tone. If you rely on memory recording how something was said rather than what, this is the setting that removes it.

extraction_enabled

Whether finished conversations become memory at all.

Default: true · Set via: /api/memory/settings

What it is. The stage that reads completed turns and pulls out facts, entities and the relationships between them.

How it works. Runs in the background on a schedule, not during your turn — nothing here slows a conversation down. By default it works over windows of several turns at once, so a person mentioned across three messages resolves to one entity rather than three.

When to change it. Leave it on; with it off, memory only ever contains what you stored by hand and recall has nothing to find. Turn it off to stop accumulating new memory without deleting what is already there — useful while diagnosing whether bad recall is a storage problem or a retrieval one.

Managing it. This is the head of the pipeline: with it off, contradiction detection, correction handling and entity linking have no new material to work on.

extraction_max_tokens

How much extracted material one pass may return.

Default: 2000 · Range: 200 to 8000, tokens · Set via: /api/memory/settings · Advanced — most installs never need to change this.

What it is. The output budget for a single extraction call.

How it works. Extraction returns structured output; a budget too small truncates it, which loses whatever came last rather than failing outright.

When to change it. Raise it if dense conversations seem to lose their tail — the later facts in a long window are the ones that go missing. Lower it only to control cost on an expensive extraction model.

Managing it. Default 2000, sized for the shipped window. Reasoning models need noticeably more, since their thinking comes out of the same budget.

extraction_model

Which model reads conversations and pulls out the facts.

Default: inherit · Set via: /api/memory/settings

What it is. The model used for the extraction pass — a structured reading task, not a creative one.

How it works. inherit follows the chain: the bulk default above, then the Fast Utility role, then the default chat model. Fresh installs leave it on inherit so the role drives memory rather than a model chosen years ago.

When to change it. Extraction quality is what everything downstream inherits: a fact recorded wrongly is retrieved wrongly forever. Point it at a stronger model if you find memory storing things you did not say; point it cheaper if volume is the concern and quality is already fine.

Managing it. An existing install keeps whatever model it saved. Adopt roles for all stages clears concrete overrides back to inherit in one action, which is usually what you want after setting up model roles.

extraction_temperature

How literally the extractor reads.

Default: 0.2 · Range: 0 to 1 · Set via: /api/memory/settings · Advanced — most installs never need to change this.

What it is. Sampling temperature for the extraction call.

How it works. Low values keep extraction close to what was actually said; higher values let the model paraphrase and infer more freely.

When to change it. Keep it low. This is a reading task, and creativity here means invented facts — the most expensive kind of error memory can make, because nothing downstream can tell an invented fact from a real one.

Managing it. Default 0.2. If memory contains plausible-sounding things nobody said, this is the first place to look, before the prompt or the model.

fact_confidence_threshold

How sure the extractor must be before a fact is kept.

Default: 0.7 · Range: 0 to 1 · Set via: /api/memory/settings

What it is. The confidence floor a newly extracted fact must clear to be stored at all.

How it works. Extraction assigns each fact a calibrated confidence by how it was expressed: roughly 0.95 for something you stated outright, 0.85 for something strongly implied, 0.70 for a reasonable inference, and 0.50 for anything hedged or ambiguous.

When to change it. Those numbers make the setting concrete. At the default of 0.7 memory keeps inferences but drops guesses. Raise it toward 0.85 to store only what was implied or said — a much stricter memory that forgets more. Lower it toward 0.5 to keep the guesses too, and accept that some of them are wrong.

Managing it. The single most consequential number on this screen: it decides what memory contains, and everything downstream can only work with what got past it.

feature_default_model

One model for every memory stage, unless a stage says otherwise.

Default: (empty) · Set via: /api/memory/settings

What it is. A bulk default sitting between the individual stage models and the global default. Every stage below left on inherit resolves through here.

How it works. The chain is: the stage’s own setting → this → the default chat model. Set this and all of memory moves at once; override individual stages only where you want something different.

When to change it. The single most useful setting on this screen. Memory work is high-volume and mostly mechanical, so pointing it all at one cheap, fast model is usually right — and doing it here is one edit instead of nine.

Managing it. Empty means each stage falls through to its role or the default chat model. Note that not every stage inherits the same way: most follow Fast Utility, combined extraction follows Deep Reasoning because quality there is worth more, and procedural distillation follows this setting.

job_consolidate_interval

How often finished conversations are turned into memory.

Default: 15 · Range: 1 to 1440, minutes · Set via: /api/memory/settings

What it is. The gap between consolidation sweeps, in minutes.

How it works. Each sweep picks up turns not yet consolidated and marks them as it goes, so runs never redo work and a sweep that finds nothing new costs nothing. Recent conversations are consolidated incrementally, which is why a sweep may process only a turn or two.

When to change it. Shorten it if you want something said now to be recallable in the next conversation a few minutes later. Lengthen it to batch more turns per run, which is slightly cheaper because extraction windows fill better.

Managing it. Default 15 minutes. If memory seems not to be updating, check this interval before suspecting extraction — the most common answer is that the sweep has simply not run yet.

job_distill_procedures_interval

How often repeated behaviour is distilled into procedures.

Default: 30 · Range: 1 to 1440, minutes · Set via: /api/memory/settings · Advanced — most installs never need to change this.

What it is. The gap between procedural distillation runs, in minutes.

How it works. Each run takes up to the batch limit of pending candidates and turns them into procedures.

When to change it. Shorten it to make the agent pick up working habits faster — useful early on, when there is a backlog and nothing has been distilled yet. Lengthen it once procedures are stable; distillation is the least urgent of the jobs.

Managing it. Default 30 minutes. Procedures need repeated evidence before they are distilled at all, so running this more often does not by itself produce more of them.

job_entity_linking_interval

How often orphaned facts are reconnected to entities.

Default: 30 · Range: 1 to 1440, minutes · Set via: /api/memory/settings · Advanced — most installs never need to change this.

What it is. The gap between entity-linking backfill runs, in minutes.

How it works. Scheduled to follow consolidation, so newly extracted facts get their linking pass shortly after being written.

When to change it. Shorten it while clearing a backlog after enabling linking. Lengthen it once memory is steady — on an install with little new material, most runs find nothing to do.

Managing it. Default 30 minutes, twice the consolidation interval. Read with the per-run fact cap: interval times cap is how fast a backlog drains.

job_promote_interval

How often facts are considered for promotion between channels.

Default: 60 · Range: 1 to 1440, minutes · Set via: /api/memory/settings · Advanced — most installs never need to change this.

What it is. The gap between promotion passes, in minutes.

How it works. Each pass looks for facts that now meet the promotion conditions and lifts them so other conversations can see them.

When to change it. Shorten it if knowledge should spread between projects quickly. Lengthen it on an install where channels are meant to stay largely separate — a slower pass is a softer boundary than turning promotion off entirely.

Managing it. Default 60 minutes. Promotion depends on repeated access, so a fact usually needs several passes to qualify regardless of how often they run.

Create a placeholder rather than orphan a fact about an unknown thing.

Default: true · Set via: /api/memory/settings · Advanced — most installs never need to change this.

What it is. What happens when a fact mentions something memory has never heard of: a minimal placeholder entity is created so the fact has somewhere to attach.

How it works. Off, the fact is dropped unless an existing entity can be recovered — it is still counted in the metrics, but it is not stored.

When to change it. Leave it on. A fact about a person the system has not met yet is exactly the kind of thing worth remembering, and the placeholder fills in the first time that name appears properly.

Managing it. Turning it off keeps the entity graph tidier at the cost of losing early facts about anything new — usually the wrong trade for a memory system.

procedural_dedupe_threshold

How similar a new procedure must be to reinforce an old one instead.

Default: 0.85 · Range: 0.5 to 1.0, cosine similarity · Set via: /api/memory/settings · Advanced — most installs never need to change this.

What it is. The bar above which a distilled procedure is treated as the same rule you already have, and strengthens it rather than joining it.

How it works. Cosine similarity between the new procedure and existing ones. Above the bar, the existing procedure is reinforced; below, a new one is created.

When to change it. Lower it if you accumulate several procedures that say the same thing in different words — each one costs prompt space on every turn. Raise it if genuinely distinct rules are being merged into one vague rule.

Managing it. Default 0.85, lower than the fact duplicate bar, because two procedures can mean the same thing while sharing little wording.

procedural_distill_batch_limit

How many pending candidates one distillation run may chew through.

Default: 100 · Range: 10 to 1000, candidates per run · Set via: /api/memory/settings · Advanced — most installs never need to change this.

What it is. A cap on candidates processed per run, bounding how long a single run takes and how much it costs.

How it works. Excess candidates stay pending and are picked up by the next run, so a backlog drains over several runs rather than in one expensive pass.

When to change it. Raise it to clear a large backlog faster — useful after enabling distillation on an install with a lot of history. Lower it to keep any single run small and predictable.

Managing it. Default 100. Read together with the run interval below: the two decide how quickly a backlog clears.

procedural_distill_max_tokens

How long the distilled procedures may be.

Default: 1000 · Range: 200 to 8000, tokens · Set via: /api/memory/settings · Advanced — most installs never need to change this.

What it is. The output budget for one distillation run.

How it works. A run produces several procedures at once, so the budget is shared across them.

When to change it. Raise it if procedures arrive truncated. Lower it to force terser rules — which is not a bad outcome, since procedures are injected into prompts and short ones cost less on every turn thereafter.

Managing it. Default 1000. Remember that what is written here is paid for again on every turn that carries it.

procedural_distill_model

Which model turns repeated behaviour into a stated rule.

Default: inherit · Set via: /api/memory/settings · Advanced — most installs never need to change this.

What it is. The model that reads accumulated candidates — things that keep happening — and distils them into procedures: durable “how we work” rules.

How it works. inherit follows the bulk default, then the global default. Runs as a background job, never inside a turn.

When to change it. This is the stage that turns memory from a record into a habit. A stronger model writes rules that generalise; a weaker one writes rules that restate one incident.

Managing it. Distillation is infrequent and batched, so a better model here costs little in aggregate — a rare case on this screen where quality is nearly free.

procedural_distill_temperature

How much latitude the rule-writer has.

Default: 0.2 · Range: 0 to 1 · Set via: /api/memory/settings · Advanced — most installs never need to change this.

What it is. Sampling temperature for the distillation call.

How it works. Low values keep procedures close to the observed behaviour; higher values let the model generalise further from it.

When to change it. Keep it low. An over-generalised procedure is worse than none — it rides in every prompt, so a wrong rule is wrong continuously rather than once.

Managing it. Default 0.2.

procedural_distill_timeout_s

How long a distillation run may hang before it is abandoned.

Default: 90 · Range: 10 to 600, seconds · Set via: /api/memory/settings · Advanced — most installs never need to change this.

What it is. A wall-clock cap on the distillation LLM call.

How it works. Bounds the background job so an unresponsive provider cannot stall it indefinitely. On timeout the run ends and its candidates stay pending for the next one — nothing is lost.

When to change it. Raise it if you have pointed distillation at a slow model and runs are timing out. There is little reason to lower it: this is a background job, so its latency costs you nothing directly.

Managing it. Default 90 seconds. Since candidates survive a timeout, the failure mode is “procedures appear later”, not “procedures are lost”.

promotion_min_confidence

How sure a fact must be before it can travel between channels.

Default: 0.85 · Range: 0 to 1 · Set via: /api/memory/settings · Advanced — most installs never need to change this.

What it is. The bar for promoting a fact out of the channel it was learned in, so other conversations can see it.

How it works. Higher than the storage bar, because a fact crossing channels is asserted in contexts nobody checked it against.

When to change it. Raise it if things learned in one project are turning up wrongly in another. Lower it if useful knowledge stays trapped in the conversation that produced it.

Managing it. Default 0.85 against storage’s 0.7 — a deliberate gap. Confidence is only one of the promotion conditions; access count and how many conversations a fact appears in also apply.

reflex_core_enabled

Put the most important procedures in every prompt.

Default: true · Set via: /api/memory/settings

What it is. A small set of distilled procedures injected into the system prompt on every turn, rather than retrieved when they happen to match.

How it works. Maintained, not searched: the core is chosen in the background and simply is there, so a rule about how you like work done applies even when nothing in your message would have retrieved it.

When to change it. Leave it on. Rules about working style are precisely the ones that never match a query — you do not ask about them, you expect them to be followed. Retrieval cannot deliver that; only always-on can.

Managing it. Everything in the core costs prompt tokens on every turn. That is the trade: reliability for a small permanent overhead.

reflex_core_limit

How many procedures ride in every prompt.

Default: 5 · Range: 0 to 20, procedures · Set via: /api/memory/settings · Advanced — most installs never need to change this.

What it is. The size of the always-on procedure set.

How it works. The highest-ranked procedures fill the slots; the rest remain retrievable but not automatic.

When to change it. Raise it if the agent follows your stated preferences inconsistently — the relevant rule may simply be outside the core. Lower it to reclaim prompt space; 0 disables the core without disabling distillation.

Managing it. Default 5. This is a per-turn cost on every conversation, so a large number here is one of the few settings that quietly raises the price of everything.

relevance_filter_enabled

Skip turns that contain nothing worth remembering.

Default: true · Set via: /api/memory/settings

What it is. A cheap gate in front of extraction that answers one question: is there anything in this turn worth storing?

How it works. A short yes/no call per turn. “Thanks”, “ok”, “try again” are filtered out before the much more expensive extraction pass ever runs.

When to change it. Leave it on. Most turns in a real conversation carry nothing memorable, and this is what stops you paying extraction prices to discover that. Turning it off does not improve memory — it just extracts from turns that have nothing in them.

Managing it. If it is filtering out turns you wanted stored, raise the extraction model’s quality before disabling the gate: a filter that is wrong is usually a filter running on too weak a model.

relevance_filter_max_tokens

How much room the gate has to answer.

Default: 500 · Range: 100 to 4000, tokens · Set via: /api/memory/settings · Advanced — most installs never need to change this.

What it is. The output budget for the relevance call.

How it works. The answer itself is a word, but a reasoning model spends tokens thinking before it gets there — and a reply truncated mid-thought is a lost verdict, not a fast one.

When to change it. Raise it if you have pointed the filter at a reasoning model and turns are being dropped erratically. Otherwise leave it: the extra budget costs nothing when it goes unused.

Managing it. Default 500, which looks generous for a yes/no and is not — that headroom exists precisely for reasoning models.

relevance_filter_model

Which model decides whether a turn is worth extracting.

Default: inherit · Set via: /api/memory/settings · Advanced — most installs never need to change this.

What it is. The model used for the relevance gate — a binary judgement.

How it works. inherit follows the bulk default, then the Fast Utility role. This is the highest-volume call in the whole memory system: it runs on every turn, where extraction runs only on the ones that pass.

When to change it. Use the cheapest model that answers correctly. Because it runs on everything, a model choice here costs more in aggregate than anywhere else on this screen.

Managing it. A model too weak to make the call reliably is worse than no filter, since it silently drops turns you wanted. If memory is missing obvious things, test by disabling the filter briefly rather than by guessing.

relevance_filter_temperature

How consistent the yes/no judgement is.

Default: 0.1 · Range: 0 to 1 · Set via: /api/memory/settings · Advanced — most installs never need to change this.

What it is. Sampling temperature for the relevance gate.

How it works. Near zero makes the same turn get the same verdict every time; higher values make the gate inconsistent between otherwise identical turns.

When to change it. Keep it at or near the default. There is no upside to a creative yes/no — the only effect of raising it is that the same kind of message is sometimes stored and sometimes not.

Managing it. Default 0.1, the lowest on this screen, deliberately.

salient_core_enabled

Put the most important facts in every prompt.

Default: true · Set via: /api/memory/settings

What it is. The fact-and-entity counterpart to the reflex core: a small set of high-salience items always present rather than retrieved.

How it works. Also maintained rather than searched. These are the things it would be absurd for the agent to have to look up — who you are, what you are working on — rather than things it might need.

When to change it. Leave it on. It is what stops the agent needing a successful retrieval before it can behave as though it knows you.

Managing it. As with the reflex core, everything here is paid for on every turn.

salient_core_limit

How many facts ride in every prompt.

Default: 8 · Range: 0 to 10, facts · Set via: /api/memory/settings · Advanced — most installs never need to change this.

What it is. The size of the always-on fact set.

How it works. Filled by salience, highest first.

When to change it. Raise it if the agent keeps failing to recall things that ought to be obvious about you. Lower it, or set 0, to reclaim per-turn prompt space.

Managing it. Default 8, capped at 10 to match the renderer’s own limit — values above that would be silently ignored, so the cap is honest rather than arbitrary.

salient_core_min_salience

How important a fact must be to earn a permanent slot.

Default: 0.6 · Range: 0 to 1 · Set via: /api/memory/settings · Advanced — most installs never need to change this.

What it is. A floor on salience for inclusion in the always-on set.

How it works. Facts below the bar are excluded even when slots are free, so a thin memory does not pad the core with trivia.

When to change it. Raise it if the core is filling with things that are true but unimportant. Lower it on a young install where nothing has accumulated enough salience to qualify and the core sits empty.

Managing it. Default 0.6. Salience grows with reinforcement, so an empty core on a new install is expected and usually resolves itself rather than needing this lowered.

semantic_duplicate_threshold

How similar two facts must be to count as the same fact.

Default: 0.92 · Range: 0.5 to 1.0, cosine similarity · Set via: /api/memory/settings · Advanced — most installs never need to change this.

What it is. The first and cheapest layer of contradiction detection: a similarity bar above which a new fact is treated as a duplicate of an existing one rather than as something new.

How it works. Compared as cosine similarity between the two facts’ embeddings, with no LLM involved. Above the bar, the new fact reinforces the old one instead of being stored again.

When to change it. Lower it if memory fills with near-identical restatements of the same thing. Raise it if genuinely different facts are being collapsed together — which shows up as memory “forgetting” the more specific of two similar statements.

Managing it. Default 0.92, deliberately high: at this bar only near-verbatim repeats merge. Below about 0.85 you begin merging facts that differ in ways that matter.

Not shown in Settings

Read-only plumbing, plus a few values set elsewhere in the app rather than on a settings screen.

llm_settings.default_max_tokens

How long a reply may be when nothing else specifies.

Default: 4096 · Range: 256 to 200000, tokens · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. The global fallback output budget.

How it works. A reply that reaches the budget is cut off mid-sentence rather than summarised, so this is a hard stop rather than a target.

When to change it. Raise it if long answers are being truncated. Lower it to keep replies short and costs predictable on an expensive model.

Managing it. Default 4096. Bounded by what the model actually allows — a value above the model’s own cap does nothing, and Model Context Limits is where a model’s real cap is corrected if the catalog has it wrong. No settings screen shows this; the profile’s own output budget is the UI equivalent.

llm_settings.default_temperature

The sampling temperature a turn uses when nothing else specifies one.

Default: 0.7 · Range: 0 to 2 · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. The global fallback temperature, used when neither the agent profile nor the feature sets its own.

How it works. Lower values make responses more deterministic and repeatable; higher ones more varied. Applies only where nothing more specific has been chosen — most background features set their own and ignore this.

When to change it. Lower it for factual and technical work where you want the same question to get the same answer. Raise it for writing and ideation. Per-agent temperature on the profile is usually the better lever, since different agents want different values.

Managing it. Default 0.7, a conversational middle. Above ~1.2 most models become noticeably erratic rather than creative. No settings screen shows this — it is set via the API or data/config.json; the per-agent temperature on a profile is the equivalent you can reach from the UI.

llm_settings.frequency_penalty

Discourage repeating the same words.

Default: 0.0 · Range: -2 to 2 · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. A penalty applied to tokens in proportion to how often they have already appeared.

How it works. Positive values push away from repetition; negative values encourage it. 0 disables it, which is the shipped state.

When to change it. Raise it slightly if a model loops or repeats phrasing. Leave it at 0 otherwise — modern models rarely need it, and a heavy penalty distorts technical writing where repeating the right term is correct.

Managing it. Range −2 to 2; useful values are small, around 0.1 to 0.5. Not every provider supports it, and those that do not simply ignore it. No settings screen shows this — set it via the API or the config file.

llm_settings.presence_penalty

Encourage bringing up new topics.

Default: 0.0 · Range: -2 to 2 · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. A penalty applied to any token that has appeared at all, regardless of how often.

How it works. Positive values push toward new subject matter; 0 disables it, the shipped state.

When to change it. Raise it if answers circle one aspect of a question instead of covering it. As with the frequency penalty, leave it alone unless you have a specific problem it addresses.

Managing it. Range −2 to 2, small values only. It changes what is discussed rather than how it is worded — that is the difference from the frequency penalty. No settings screen shows this — set it via the API or the config file.

llm_settings.top_p

Nucleus sampling — how much of the probability mass to consider.

Default: 1.0 · Range: 0 to 1 · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. An alternative to temperature for controlling variety: the model samples only from the most likely tokens whose probabilities sum to this.

How it works. 1.0 considers everything and is effectively off, which is the shipped state. Lower values progressively exclude the unlikely tail.

When to change it. Change temperature or this, rarely both — they control the same thing by different means and interact confusingly. If you are unsure which to reach for, use temperature.

Managing it. Default 1.0. Providers differ in how they combine the two, so a configuration that works on one may behave differently on another. No settings screen shows this — set it via the API or the config file.

memory.project_channels

Whether Projects get their own memory channel.

Default: true · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. Scoping that gives each Project a _project_<id> channel, so what is learned inside a Project stays associated with it.

How it works. Off, Project conversations write to the ordinary channel and lose that separation.

When to change it. Leave it on if you use Projects. Channel separation is what stops facts about one client turning up while you work on another; cross-channel promotion is the deliberate route between them.

Managing it. No settings screen shows this — set it via the API or the config file. Changing it does not move memory that has already been written under the previous scheme.

preferences.default_reasoning_strategy

The reasoning pattern used when nothing else picks one.

Default: auto · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. A global fallback in the pattern-resolution chain, below the per-agent default and the per-conversation composer chip.

How it works. auto — the shipped value — lets the classifier choose per message. A named pattern pins it globally instead.

When to change it. Pin one only if you want a single pattern everywhere regardless of the question, which is rarely what you want: the classifier exists because different questions reward different scaffolds.

Managing it. No settings screen shows this — set it via /api/config/update or in data/config.json. The per-agent default on the profile is the equivalent you can reach from the UI.

preferences.enable_memory_by_default

Whether new conversations start with memory on.

Default: true · Set via: /api/config/update · Advanced — most installs never need to change this.

What it is. A default for the per-conversation memory switch.

How it works. Applies at conversation creation. An existing conversation keeps whatever it was created with.

When to change it. Turn it off on an install where memory should be opt-in per conversation — shared machines, or work you would rather not accumulate.

Managing it. No settings screen shows this — set it via the API or the config file. It does not disable memory; it changes the starting position of a switch each conversation still owns.

Also in this area — values that are read-only over the API. Set them in .env or the settings file directly and restart; they have no control and no per-setting write-up:

SettingTypeDefaultStoreSet via
always_include_recent_turnsint3memoryread-only
audit_log_levelstrwritesmemoryread-only
audit_partition_ahead_daysint7memoryread-only
audit_retention_daysint30memoryread-only
audit_sample_ratefloat1.0memoryread-only
channel_active_boostfloat1.2memoryread-only
confidence_explicitfloat0.95memoryread-only
confidence_impliedfloat0.85memoryread-only
confidence_inferredfloat0.7memoryread-only
confidence_uncertainfloat0.5memoryread-only
connection_timeoutint5memoryread-only
default_top_kint10memoryread-only
embedding_api_keystr(secret)memoryread-only
embedding_base_urlstr(empty)memoryread-only
embedding_batch_max_sizeint32memoryread-only
embedding_batch_window_msint5memoryread-only
embedding_cache_enabledbooltruememoryread-only
embedding_cache_max_sizeint2048memoryread-only
embedding_cache_ttl_secondsfloat900.0memoryread-only
embedding_dimensionsint1024memoryread-only
embedding_max_retriesint3memoryread-only
embedding_modelstrtext-embedding-3-smallmemoryread-only
embedding_providerstrlocalmemoryread-only
embedding_queue_enabledbooltruememoryread-only
embedding_queue_max_sizeint1024memoryread-only
embedding_remote_max_inputsint2048memoryread-only
embedding_request_timeoutfloat30.0memoryread-only
entity_embedding_backfill_batchint200memoryread-only
entity_linking_auto_thresholdfloat0.9memoryread-only
entity_typeslist(structured)memoryread-only
episodic_retention_daysint90memoryread-only
extraction_registry_max_entitiesint15memoryread-only
extraction_registry_max_factsint20memoryread-only
extraction_timeoutfloat30.0memoryread-only
extraction_window_max_output_tokensint3000memoryread-only
extraction_window_max_tokensint1200memoryread-only
extraction_window_max_turnsint6memoryread-only
extraction_windowing_enabledbooltruememoryread-only
job_audit_partitions_intervalint1440memoryread-only
job_cleanup_intervalint1440memoryread-only
job_decay_intervalint1440memoryread-only
job_patterns_intervalint60memoryread-only
local_embedding_modelstrBAAI/bge-m3memoryread-only
max_query_lengthint10000memoryread-only
max_results_per_conversationint3memoryread-only
max_working_memory_itemsint50memoryread-only
neo4j_max_connection_lifetimeint300memoryread-only
neo4j_passwordstr(secret)memoryread-only
neo4j_uristr(secret)memoryread-only
neo4j_userstrneo4jmemoryread-only
openai_api_keystr(secret)memoryread-only
postgres_pool_max_overflowint20memoryread-only
postgres_pool_sizeint10memoryread-only
postgres_uristr(secret)memoryread-only
pricing.audiodict(empty)configread-only
pricing.imagesdict(empty)configread-only
promotion_min_access_countint5memoryread-only
promotion_min_conversationsint2memoryread-only
redis_uristr(secret)memoryread-only
relationship_typeslist(structured)memoryread-only
reranking_enabledbooltruememoryread-only
retrieval_cache_enabledbooltruememoryread-only
retrieval_cache_key_prefixstr(secret)memoryread-only
retrieval_cache_ttl_secondsint60memoryread-only
retrieval_weight_episodicfloat0.3memoryread-only
retrieval_weight_proceduralfloat0.15memoryread-only
retrieval_weight_recencyfloat0.1memoryread-only
retrieval_weight_semantic_entitiesfloat0.2memoryread-only
retrieval_weight_semantic_factsfloat0.25memoryread-only
salience_decay_ratefloat0.95memoryread-only
semantic_entity_linking_enabledbooltruememoryread-only
shell.allow_networkboolfalseconfigread-only
shell.allow_unsandboxedboolfalseconfigread-only
shell.deny_patternslist(empty)configread-only
shell.docker.cpusstr2configread-only
shell.docker.enabledboolfalseconfigread-only
shell.docker.idle_ttl_daysint7configread-only
shell.docker.imagestrpython:3.14-slimconfigread-only
shell.docker.memorystr2gconfigread-only
shell.docker.networkstragentx-shell-netconfigread-only
shell.docker.pids_limitint512configread-only
shell.max_materialize_bytesint134217728configread-only
shell.max_output_charsint20000configread-only
shell.require_confirmationboolfalseconfigread-only
shell.timeout_secondsint20configread-only
shell.workdir_cleanup_daysint7configread-only
user_recap_enabledbooltruememoryread-only
worker_heartbeat_intervalint30memoryread-only
worker_heartbeat_ttlint90memoryread-only
workspace_agent_writable_extensionslist(structured)memoryread-only
workspace_agent_write_toolsbooltruememoryread-only
workspace_allowed_extensionslist(structured)memoryread-only
workspace_chunk_overlapint150memoryread-only
workspace_chunk_sizeint1000memoryread-only
workspace_max_file_bytesint52428800memoryread-only
workspace_quota_bytesint536870912memoryread-only
workspace_summary_modelstr(empty)memoryread-only
  • Configuration — environment variables, connector files, and the layout of the config files themselves.