Sandbox run (the config-dialog Test drawer): the graph runs for real against a synthetic ticket, but every externally-visible side effect — tag publish, ticket status, replies, bookings, wiki writes — is recorded into state.test_actions instead of executed. Set per-thread at invoke time, never on saved rows.
Master on/off switch for this assistant. When False the agent never engages on EXTERNAL triggers (no replies, no escalations of its own); workflow rules that act on their own — junk, close, assign, tag, template reply, forward, hand off — still run, and a run is started only for those.
LEGACY — tagging is mandatory. The field remains for stored-row compatibility but heals to True on load (tagging_is_mandatory validator); the consumer no longer gates on it. Use active to switch the agent off (workflow rules keep running) and get_involved to keep it tagging-only.
Allow the agent to engage (answer / act for) guests on EXTERNAL triggers after tagging. Requires tag_enabled=True. False = tagging only; the run ends after tagging and the workflow rules (which run in both modes). When True the run is still gated by required_tags and the workflow rules.
Orchestration model (main reasoning/response-generation LLM). Default is controlled by the HARNESS_ORCHESTRATOR_MODEL env var; falls back to Claude Haiku 4.5 when unset.
EXTERNAL only. When True, every orchestrator turn must end in a tool call — text-only responses get bounced back from reflect once with a nudge message, and the system prompt carries an explicit rule telling the model to act, not narrate. Turn off for tenants where the orchestrator is doing free-form chat.
Model for the tag_intent ReAct loop (chooses relevant tags).
Model used by the tag_intent extractor (structured field extraction).
DEPRECATED — unused. The compose_reply_email sub-agent was removed; guest replies are written by the orchestrator (model).
Fast model used by the prompt_shield to classify subtle injection attempts.
Fast model that answers llm workflow-rule conditions — the free-text yes/no questions an operator writes on a rule (‘Is the guest complaining about the food?’). Runs once per inbound message per distinct question, and not at all when no rule uses the source.
Fast model that classifies WHY a case was escalated, against the tenant’s escalation-category registry (the ‘questions the agent couldn’t answer’ taxonomy). Runs once per first hand-off.
If True, the support ticket is set to CLOSED whenever the agent’s reply is delivered to the guest — email (reply_guest) and live chat (send_chat_reply) alike. Default False — the team closes tickets manually.
If True, reply_guest with CONFIRM_BOOKING intent also closes the support ticket. Default False — let the reviewer close.
Escalation behaviour: the closing message shown to a chat guest on hand-off.
LEGACY — superseded by working_ticket_status + an interrupt_steps set_status step. A stored True migrates on load (see migrate_lifecycle_status_updates); the harness no longer reads this flag.
Enable the jonna-knowledge wiki MCP server for this assistant. When False, the wiki_* tools are stripped from the agent’s tool set even if listed in selected_tools. Mirrors the ‘wiki’ entry in mcp_connections — disabling either disables both.
Language the agent replies in when the guest’s detected language is not in allowed_reply_languages (or detection fails).
Languages the agent may reply in. When the guest’s detected language is in this list the reply mirrors it; otherwise the reply falls back to fallback_language.
Location-specific instructions appended to the base prompt. Use this to define tone, personality, and voice for this location.
DEPRECATED — unused. The compose_reply_email sub-agent was removed; customise the reply style via system_prompt and brand_voice.
DEPRECATED — unused. The compose_reply_email sub-agent was removed; customise the reply style via system_prompt and brand_voice.
Combined input+output token budget per run. When exceeded the run is paused at the next safe boundary (resumable). None disables.
Auto-close open tickets (NEW / IN_PROGRESS / PENDING) after this many minutes without activity. Executed by the platform time.ping sweeper for this assistant’s medium and locations; closed chat tickets then run the post-close analysis (tagging + CX scoring). None = disabled.
Base system prompt for the harness. Applies to all locations. Rendered as a Jinja template with {{locations}} (the venue list) and {{tool_discovery_enabled}} available; today’s date and the live plan are injected separately as a per-turn message, not via this field. A customised prompt that is not valid Jinja is used as literal text.
When True, the orchestrator runs the discovery-first model: it starts with only the harness primitives plus search_tools (browse/search the catalog and activate by name) and pulls domain tools in on demand, and the system prompt carries the discovery instructions.
When False, discovery is turned OFF for speed: search_tools is never bound, EVERY tool in selected_tools is bound from the first turn, and the system prompt lists the agent’s capabilities statically (one reference per bound tool). A tool that is not in selected_tools is then truly unreachable — there is no way for the agent to discover it. Chat defaults this to False (latency-tuned, fixed tool set).
Skip the intent-tag pass for live chat. Lives on the base (not just the chat subclass) so it is part of the generated GraphQL output/input types and round-trips through the assistant editor and save. The chat config overrides the default to True; the chat graph also omits the tag_intent node structurally, so this flag is the operator-facing intent, not a runtime branch on the chat path.
Executed when the agent pauses and waits for human approval — e.g. set the ticket to IN_PROGRESS and assign a reviewer. Same step model as workflow rules, but only ticket-side types run here (set_status / send_reply / assign / add_tag / mark_junk / close_ticket); agent-flow types (human_handoff, skip_agent, end_run_silent, limit_tools) are logged and skipped. Steps run once per interrupt, at the moment the judge raises it — never again when the run resumes. Empty list = no ticket-side effects beyond the built-in PENDING bookkeeping.
Master switch for the judge LLM. When False (current default — temporarily disabled 2026-08-27, too strict in production) no judge LLM call is made anywhere in the judge node: an InterruptPolicy.JUDGE call passes straight through like NEVER, and the ALWAYS path raises its human interrupt without the correctness pre-check. Deterministic gates (workflow tool bans, guardrail denies, validators, the args-schema check) and human approvals are unaffected. judge_llm_verdict=False still promotes JUDGE to ALWAYS regardless of this switch — an agent whose posture is ‘a human decides’ keeps that posture. judge_semantic_precheck only matters while this is True.
On the ALWAYS (human-approval) path, run the LLM correctness pre-check before raising the interrupt, whenever the tool has semantic_checks or the matched rule has a judge_prompt. Worth it when nobody is watching: a caught mistake never reaches the reviewer. Set False where the approver is already the person in the conversation and the verdict has no second audience — the InterruptPolicy.JUDGE path is unaffected either way.
Close the ticket when the agent considers the request completed — on BOTH mediums. Email reads the delivered reply’s send intent (answered the question, confirmed/modified/cancelled a booking, gave the requested information) and also closes on a judged finish_no_reply, the guest’s sign-off. Chat has no reply tool to carry an intent, so it asks a classifier whether the conversation is finished, after the reply is delivered. Replies that ask the guest for something, promise a follow-up, or leave a complaint unsettled keep the ticket open, and an unavailable classifier leaves it open too. Default on — turn off to have the team close every ticket manually.
The channel this assistant is bound to (EMAIL, CHAT, FORM, REVIEW, API, …). On EXTERNAL requests the dispatcher filters candidates by this field — an EMAIL request only routes to assistants with trigger_medium=EMAIL. At invoke time the runtime overrides this with the actual event’s medium so downstream tools see the real channel. Independent of trigger_audience.
THE event that starts a run — exactly one. NEW_MESSAGE (default) = every new inbound guest message on this assistant’s channel; ASSIGNMENT = only when a support ticket is explicitly assigned to this assistant in the inbox (the publisher stamps trigger_reason=‘assignment’; the inbox does not publish these yet). Enforced at the AMQP consumer before any thread or run exists. EXTERNAL runs only.
Sender patterns that must never start a run ('' wildcards: ‘@agoda.com’, ‘badr@-ops.com’, exact addresses). Seeded with the machine-sender patterns (noreply@, mailer-daemon@, …), which are ordinary removable entries. Enforced before intent tagging on EXTERNAL runs — an excepted sender is never tagged, engaged, or replied to, and no automation rule can touch it.
Safety default for tool gaps. When the tagger resolves an intent the assistant demonstrably cannot act on (e.g. a booking request while no booking tool is in selected_tools), the run is handed to a human instead of engaging the agent — a guest must never be answered by an agent that cannot actually do what they asked. A workflow rule conditioned on that tag overrides this (the operator has expressed their own policy). Applies to EXTERNAL runs only.
Require the agent to have read venue knowledge (wiki_recall or get_booking_settings) earlier in the run before it may CREATE a booking. Guarantees house rules — children’s hours, party-size limits, area restrictions — are in front of the agent before it commits, instead of being discovered after the confirmation went out. Ignored when the wiki bundle is disabled.
What to do when a guest’s message assumes they already have a reservation but none can be found. ‘enforce’ (default) blocks the new booking and makes the agent ask the guest or escalate; ‘enforce_strong’ blocks only on strong evidence — an explicit reference (‘our booking’, a confirmation number), or arrival phrasing that the parallel LLM classifier independently confirms — and leaves a single weak signal advisory; ‘observe’ warns the agent but blocks nothing; ‘off’ disables the check AND the classifier call entirely.
Tag-label allowlist that gates EXTERNAL runs after tag_intent. Empty list = off (all extracted tags pass). When non-empty, the run only proceeds to the orchestrator if at least one extracted super-tag label is in this list. Tags outside the allowlist route directly to END — the guest is not responded to and no human reviewer is paged. The special entry ‘none’ opts in the untagged case (no tags extracted, including skip-tagging-for-chat runs); without it, untagged runs end. Example: [‘booking’] to only engage on booking-tagged requests; [‘booking’, ‘none’] to also engage when nothing was tagged.
MCP server connections in this assistant’s tool chain. Tools are exposed to the agent as ‘{name}__{tool}’ (e.g. ‘booking__create_booking’) and are Tier-2 discoverable by default (bound up front when tool discovery is off). Per-connection tool_allowlist narrows which served tools load; per-tool allow/deny/approval lives in guardrails.
Per-tool guardrail rules, evaluated first-match top-to-bottom against every pending tool call. tool_name is an exact (namespaced) name, a wildcard suffix (‘booking__’), or ''. allow = run autonomously, judge = LLM judge evaluates, require_approval = human must approve, suggest = offered to a human as a draft they send themselves (reply_guest), deny = block (filtered from binding when static; rejected per-call when conditions reference tool args). New assistants start with the deployment defaults; an explicitly empty list means no deployment overrides — every tool falls back to its own default policy.
Ordered workflow rules. Each has a trigger (pre_run / post_tag / post_close), AND’d guardrail-style conditions (sender / medium / location / super_tag), and ordered steps (set_status, send_reply, assign, add_tag, forward_email, set_classification, mark_junk, close_ticket, human_handoff, skip_agent, end_run_silent, limit_tools, pass_to_agent). The first matching rule carrying a terminal step wins. Empty list = no workflow automation.
Ordered reply-language rules. Each maps detected ISO 639-1 codes to ONE reply language; the first rule whose detected list contains the guest’s detected code wins ('' matches any detected language). Example: [{detected: [‘no’,‘nb’,‘nn’], reply_language: ‘no’}, {detected: [''], reply_language: ‘en’}] keeps Norwegian in Norwegian and answers everything else in English. Empty list = no explicit policy: the venue’s country decides instead (its own language for a guest who wrote in it, English for everyone else).
ISO 639-1 code the agent replies in when no language rule matches. Empty string = no explicit policy: the venue’s country (geoLocation.region) decides — a guest writing the venue’s own language is answered in it, everyone else in English. Venues with no country on file fall back to mirroring the guest (subject to allowed_reply_languages / fallback_language).
Enable Anthropic extended thinking for the orchestrator with this token budget (Anthropic minimum 1024; e.g. 2048). Reasoning before each tool call measurably improves first-shot tool-argument fidelity on small models (Haiku pattern-matches arg names from description prose without it). None (default) disables thinking. Anthropic orchestrator models only; ignored for other providers.
Restaurant brand voice / writing style for guest replies. Free text. Injected into the orchestrator prompt on both channels — the orchestrator writes every guest reply and reviewer draft itself — to steer HOW it writes: tone, warmth, signature phrasings, words to prefer or avoid. This shapes style only; WHAT to say still comes from the run’s lookups and rules. None = the default hospitable voice.
Status the ticket is set to while the agent is working on it (NEW / IN_PROGRESS / PENDING / CLOSED — typically IN_PROGRESS). Empty (the default) = the agent never touches the status while working. The waiting-for-approval status is NOT set here — it comes from the operator’s interrupt_steps (a set_status step in “Waiting for your approval — do:”). Feature-driven dispositions (escalation PENDING, junk/close rules) are separate and unaffected.