Every setting, its tab, its default and who may change it

All 46 AI Support keys mapped to the five tabs on the settings screen, with shipped defaults, accepted ranges, the twelve Super-Admin keys and the four with no control on that screen.

9 min readUpdated 7 August 2026settings, defaults, super-admin, reference, keys

The addon owns 46 settings keys. Settings explains the ones you will actually want to change and why; this page is the whole list, in the order the screen puts them, so that "set aiSupportRetrievalFloor" turns into a tab and a control rather than a search.

The screen is /admin/ai/support/settings and needs access.ai.support.settings.

Reads every key with its default, the list of protected keys, and whether you personally hold the Super Admin role.
Writes them. Refuses any key outside the addon allowlist, and any protected key from a caller who is not a Super Admin.

The five tabs

The tab id is what appears in a field definition and in a URL fragment; the label is what is printed on the rail. Two of them differ, which is the usual reason an instruction naming a tab sends somebody to the wrong one.

Id Label on screen What it holds
guardrails Guardrails Switch it on, and cap what it may spend
channels Channels Where it answers, and when it hands over
knowledge Retrieval What it reads before it answers
model Model Which model runs, and how much it may write
privacy Data What is kept, and what leaves this install

Tab order is the order you do it in, not alphabetical. Guardrails is first because nothing else on the screen has any observable effect until the assistant is switched on and has a budget.

Guardrails

Every control on this tab is a Super-Admin key, and the tab is hand-built rather than generated — the shared settings form has no protected-key concept, so a protected key rendered as an ordinary field would be a live control that rejects the save.

Key Section Default Notes
aiSupportEnabled Assistant false The on/off button at the top of the tab, which refuses to enable an install with no provider
aiSupportAutonomy Assistant COPILOT COPILOT · AUTO_TICKET · AUTO_ALL, chosen under When it answers in the same panel
aiSupportProvider Super-Admin controls null Locked here; changed on Provider (/admin/ai/support/provider)
aiSupportDailyBudgetUsd Super-Admin controls 5 Editable here by a Super Admin, and nowhere else
aiSupportMonthlyBudgetUsd Super-Admin controls 100 Editable here by a Super Admin, and nowhere else
aiSupportAccountToolsEnabled Super-Admin controls true Editable here by a Super Admin, and nowhere else
aiSupportOperationsEnabled Super-Admin controls false Locked here; changed on Actions (/admin/ai/support/workflows)
aiSupportWorkflowsEnabled Super-Admin controls false Locked here; changed on Actions
aiSupportWorkflowKeys Super-Admin controls [] Locked here; written as JSON by Actions when you tick a process
aiSupportAdminAssistantEnabled Super-Admin controls false Your own assistant, not the customers'. Switched on from Handbook; see below for switching it off
aiSupportAdminActionsEnabled Super-Admin controls false Lets it offer a platform action you approve. A two-way switch on the Handbook screen
aiSupportAdminActionKeys Super-Admin controls [] (means none) Which admin actions. Written as JSON when you tick one on the Handbook screen

Those twelve are the complete Super-Admin list. Everything below this section is writable by any role holding access.ai.support.settings.

The last three are a different product from the nine above them. Those decide what an automated system says to your customers; these decide whether the admin surface is described to a model at all, and then whether it may offer a platform-wide write. Every catalogue behind them is filtered by the asking administrator's own permissions, so the assistant can never reach something the console would refuse — but that is a floor, not a reason to leave them off this list.

The "Turn it on" button is inside the panel that renders when the assistant is off, and it writes true. Once it is on, that panel is gone and there is no control anywhere that writes false — the Guardrails row for the key is a locked readout, and it is not one of the three protected keys a Super Admin may edit from that grid.

Switching it back off is a Super Admin calling the PUT at the top of this page with {"settings":{"aiSupportAdminAssistantEnabled":"false"}} — from an authenticated admin session, because the route checks the role rather than the permission.

The same grid renders those three keys with no friendly label and no link to the screen that owns them, so they print as raw camelCase. That is cosmetic; the missing off control is not.

The PUT collects every refused key and throws a single 403 for the entire payload. It does not drop the offender and save the rest. That is why the protected controls are shown locked rather than live: a clickable protected switch would silently throw away every other edit made on the same visit, with nothing on screen naming the control that did it.

The two 403s are deliberately different. "These settings cannot be changed here" means the key belongs somewhere else; "Only a Super Admin can change these" means you need the role. The second one also states, in the message, that nothing was half-applied.

Channels

Key Section Default
aiSupportTicketsEnabled Where it answers true
aiSupportLiveChatEnabled Where it answers false
aiSupportDebounceMs Where it answers 4000
aiSupportGreetingEnabled Opening line true
aiSupportGreeting Opening line "Hi {name} — ask me anything about your account…"
aiSupportQuickReplies Opening line empty
aiSupportOfficeHoursEnabled Office hours false
aiSupportOfficeHours Office hours Mon–Fri 09:00-17:00, Sat and Sun closed
aiSupportOfficeHoursTimezone Office hours UTC
aiSupportOfflineNotice Office hours "The support team is offline right now…"
aiSupportMaxTurnsBeforeEscalation Handover 3
aiSupportDraftOnBargeIn Handover true
aiSupportProactiveEnabled Outbound false

aiSupportOfficeHours and aiSupportOfficeHoursTimezone are the only two keys on the whole screen that are validated at write time. A schedule nothing can parse is rejected with an example rather than saved, and a schedule that is closed on every day is rejected too; a timezone the server's Intl does not recognise is rejected rather than silently becoming UTC and shifting every hour you told your customers. The read path deliberately fails silently, so this save is the only moment there is a person present to be told.

The Preview control under aiSupportProactiveEnabled is not a setting — see below, and Proactive support for what it shows.

Retrieval

Key Section Default
aiSupportRemoteDocsEnabled What it may read true
aiSupportScopeToInstalledProducts What it may read true
aiSupportTopK How it searches 6
aiSupportRetrievalFloor How it searches 0.28
aiSupportRerankEnabled How it searches true
aiSupportMultilingualEnabled How it searches false
aiSupportGroundednessFloor Before it sends 0.4
aiSupportDeflectEnabled Before a ticket is filed true

Read top to bottom, this tab is the pipeline in order: which corpus is in scope, how a question is searched against it, what has to be true before an answer goes out, and the one thing that runs before any of it. aiSupportDeflectEnabled is last because it happens first and costs nothing — it is a search, not a model call.

Model

Key Section Default Shown when
aiSupportGatewayUrl Connection empty Provider is mashdiv
aiSupportModel Which model mashdiv-core Always; the options are fetched from the active provider
aiSupportEffort Which model low Always
aiSupportMaxTokens Which model 4000 Always
aiSupportRerankModel Internal models mashdiv-lite Provider is not mashdiv
aiSupportClassifierModel Internal models mashdiv-lite Provider is not mashdiv

What ships is a tier, not a model id. These three used to default to named vendor models, which meant every install rendered a supplier's model id on the screen an operator opens most — the disclosure the tier vocabulary exists to prevent. A tier is also the more honest value: which model serves mashdiv-core is a routing decision made on the gateway, so an install asserting a specific model is claiming knowledge it does not have and pinning a choice that stops being current the moment routing changes. Nothing is lost on the self-managed path — an operator who brings their own key and names a specific model still gets exactly that model, and the mapping only catches the tier names.

On a gateway install the three values are additionally masked at the API boundary, not merely hidden by the form: the GET rewrites them to the tier name before the response leaves the server, because showIf is render-only and a raw value was otherwise readable from the network tab.

One discrepancy worth knowing about: on an install that has never saved this tab, the form seeds the three fields from its own copy of the defaults, and that copy is still the old bring-your-own-key one. It is a placeholder in an unsaved form, not a stored row — the engine reads the tiers above until you save something — but if the field disagrees with this table on a fresh install, that is why.

aiSupportEffort is shown on every install including the gateway — the gateway reads it per call. It is the cheapest lever on the screen, because thinking tokens are billed and are counted against aiSupportMaxTokens.

Data

Key Section Default
aiSupportRetentionDays Conversation lifecycle 90
aiSupportAutoCloseDays Conversation lifecycle 0 (off)
aiSupportShareQuestionsEnabled What leaves this install false

aiSupportShareQuestionsEnabled is the only control on the whole screen that sends anything outside the install, which is why it has its own heading on the tab an operator opens when somebody asks what this feature transmits.

Four keys that are not on this screen

Key Default Where it lives
aiSupportGuidesEnabled true The Actions console, /admin/ai/support/workflows
aiSupportGuideKeys [] (means all) The Actions console — ticking walkthroughs writes it
aiSupportDirectAnswerEnabled false No control in this build. The PUT accepts it; nothing renders it
aiSupportAnswerCacheEnabled false No control in this build. The PUT accepts it; nothing renders it

The two walkthrough keys are deliberately on the Actions console rather than here — they belong beside the catalogue they narrow, and unlike the three capability switches they are not Super-Admin gated, because a walkthrough cannot write.

The last two are a genuine gap rather than a design decision. Both are real and both are read on every turn, but no control in the product renders either one — they appear in no field definition, in no hand-built tab, and nowhere else in the admin app. The only ways to change them are the PUT at the top of this page, with a body such as {"settings":{"aiSupportDirectAnswerEnabled":"true"}}, or a row written straight into the settings table. Any instruction to "switch direct answers on" from the Settings screen is describing a control that does not exist.

aiSupportDirectAnswerEnabled is the largest cost lever the addon has when your article coverage is good, which is what makes the missing control worth naming rather than filing under polish.

aiSupportProactivePreview looks like a key on the Channels tab and is not one. It is a custom component with a field slot, so it can sit inline under the switch it demonstrates; nothing is ever written under that name.

Values are TEXT, and that is not a detail

The settings table stores value as LONGTEXT. Everything the admin form writes is String()-coerced on the way in, so a boolean arrives as the four characters false — and Boolean("false") is true.

Every boolean in this addon therefore goes through one coercion helper, which accepts exactly:

true   1   yes   on

trimmed and lower-cased, so TRUE with a trailing space is on. Anything else is false: enabled, y, -1, and an empty string.

Writing aiSupportEnabled = 'True' in the database works, because it is lower-cased. Writing aiSupportEnabled = 'enabled' does not: the assistant is off, the row exists, the admin screen renders the switch as off, and nothing anywhere reports a problem.

Change these from the screen. If you must write a row directly, write exactly true or false.

Enums degrade to the safe value rather than to whatever was typed, which means a typo can never enable something:

Key Accepted A typo becomes
aiSupportAutonomy COPILOT · AUTO_TICKET · AUTO_ALL COPILOT
aiSupportProvider anthropic · openai_compatible · mashdiv · null null (no provider)
aiSupportEffort low · medium · high · xhigh · max low

Text keys degrade the other way. Seven of them are read with || rather than ??, so an empty value is discarded and the shipped default comes back: aiSupportModel, aiSupportRerankModel, aiSupportClassifierModel, aiSupportGatewayUrl, aiSupportGreeting, aiSupportOfficeHoursTimezone (back to UTC) and aiSupportOfflineNotice. Clearing one of those fields is not "set it to nothing" — an operator who empties the greeting to stop it being sent gets the shipped greeting back on the next read, with the field still showing empty in an unsaved form. The way to silence the greeting is aiSupportGreetingEnabled = false.

aiSupportOfficeHours is the deliberate exception: it is read with ??, because "no schedule" is a real answer there and restoring a nine-to-five underneath an operator would be a promise the product invented.

Numbers are clamped to a range. A value that does not parse as a number at all — enabled, abc, true — falls back to the shipped default. An empty value is not that case: Number("") is 0, which is a perfectly finite number, so an emptied numeric setting is 0 clamped to the key's minimum.

On both budget keys the minimum is 0, and 0 means no cap — the documented escape hatch for an install running its own model at genuinely zero per-token cost. The two are reachable in one gesture: the Guardrails ceiling inputs commit on blur and write whatever is in the box, so a Super Admin who selects the Daily budget, deletes it, and clicks away has saved an empty string, which is read as 0, which is unlimited. Nothing warns. The meter beside it stops reading "of $5.00", says "no ceiling set" instead and drops its bar — that is the only signal you get.

Type a number. If you want no ceiling, type 0, so that the next person reading the row can tell a decision from an accident.

Key Range
aiSupportDailyBudgetUsd, aiSupportMonthlyBudgetUsd 0 and up; 0 means no cap
aiSupportMaxTokens 1024 – 64000
aiSupportTopK 1 – 20
aiSupportRetrievalFloor, aiSupportGroundednessFloor 0 – 1
aiSupportMaxTurnsBeforeEscalation 1 – 20
aiSupportAutoCloseDays 0 – 90; 0 is off
aiSupportRetentionDays 1 – 3650
aiSupportDebounceMs 0 – 60000

The four list keys are bounded too: aiSupportQuickReplies keeps the first six entries at 80 characters each, aiSupportWorkflowKeys and aiSupportAdminActionKeys the first forty at 64, and aiSupportGuideKeys the first sixty-four at 64. Lists are read as JSON when the stored text starts with [, and as newline-separated otherwise, so a hand-written row does not silently vanish.

Empty means different things on three of them, and the difference is deliberate: empty is none for aiSupportWorkflowKeys and aiSupportAdminActionKeys, because both gate something that writes and a catalogue that grows in an upgrade must not grant a capability nobody agreed to; empty is all for aiSupportGuideKeys, because a walkthrough writes nothing and a new one is a new explanation of a page you already ship.

A change is not instant everywhere

Two caches sit in front of these rows, and they behave differently. A change made through the PUT clears both: the addon's snapshot, the install profile and the route catalogue go first, then CacheManager.clearCache() empties the platform Map, reloads it from the database and announces the invalidation to every other process — by broadcast where one can be heard, and by a version stamp written into the settings table where it cannot.

A row changed outside the PUT — a direct database write, a migration, a script — is a different story on each side:

Cache What it serves A hand-edited row reaches it
The addon's snapshot Everything on this page, read by the agent Within 10 seconds. It re-queries the settings table on expiry, so the value does arrive on its own
The platform CacheManager GET /api/settings, every getSetting* reader elsewhere in the platform Never, on its own. The Map reloads only when it is empty or when the __cacheVersion stamp moves, and a hand-written row moves neither. There is no clock

So "expect it within ten seconds" is true of AI Support behaviour and false of everything else. If you have edited a row by hand, re-save it from the screen — that is what bumps the version stamp and converges every process — or restart the backend.

Never put a credential here

It feeds the public site's branding and feature flags, so it requires no login and returns every row in the settings table minus a denylist that currently holds exactly one key.

Anything credential-shaped written to this table is world-readable on the next page load of your public site. Provider tokens, API keys and the gateway signing secret live in .env and are read at call time. aiSupportGatewayUrl is here because a URL is not a secret; the token that goes with it is not.

That is also why no field on the settings screen is a password box. If you find yourself wanting one, the answer is an environment variable — see Install.