Skip to content

Config Fields and Settings

The configuration is described by AgentConfig and stored on disk at $XUN_HOME/config.json. Every agent receives a clone of the global configuration, so runtime changes affect only that agent and are never written back to the file.

Location and loading

flowchart LR
    T["Built-in template<br/>with ${XUN_*} placeholders"] --> M["Deep merge<br/>config.json"]
    F["$XUN_HOME/config.json"] --> M
    M --> S["Environment variable substitution"]
    S --> C["AgentConfig"]
    C --> A1["agent.config clone"]
    C --> A2["Sub-agent clone"]
  • When XUN_HOME is unset it defaults to ./.xun, so the config file is ./.xun/config.json.
  • It is loaded once per process (lru_cache); after changing XUN_HOME you need load_config(force_reload=True).
  • load_dotenv() is called before the file is read; by default it does not overwrite existing environment variables.
  • The file only needs the fields you want to change. Dictionaries merge recursively, lists and scalars are replaced wholesale — if you write only {"model": {"name": "x"}}, model.capabilities keeps the template value; to clear it you must write "capabilities": [].
  • Every model uses extra="forbid": a misspelled field name fails at startup instead of being silently ignored.
  • When the file does not exist the template is used directly, and XUN_OPENAI_BASE_URL and XUN_OPENAI_API_KEY must then be present in the environment.

Environment variable placeholders

Strings in the template are string.Template patterns, so both ${XUN_OPENAI_API_KEY} and $XUN_OPENAI_API_KEY work ($$ escapes). Rules:

  • A placeholder identifier must start with XUN_, otherwise startup fails with an error.
  • When a variable is missing, a built-in fallback table is consulted first; if there is no fallback, it is an error:
Variable Fallback when missing
XUN_OPENAI_MODEL "" (triggers model auto-detection)
XUN_AUTO_CONFIRM "false"
XUN_ENABLE_EXTENSIONS "true"
XUN_OPENAI_BASE_URL / XUN_OPENAI_API_KEY No fallback; missing means an error
  • Substitution happens before json.loads, so a placeholder may appear at any position inside a string (including inside extension_settings). Conversely, a value must not contain quotes, backslashes, or newlines, or it will break the JSON.

The built-in mappings:

Environment variable Affected field
XUN_OPENAI_BASE_URL provider.openai_base_url
XUN_OPENAI_API_KEY provider.openai_api_key
XUN_OPENAI_MODEL model.name
XUN_AUTO_CONFIRM auto_confirm
XUN_ENABLE_EXTENSIONS enable_extensions
XUN_HOME Root location of config, extensions, and data directories (not a config field)

Extensions use the same mechanism

Placeholder substitution applies to the merged JSON as a whole, so ${XUN_*} also works inside an extension's config bucket — secrets stay in the environment instead of in the config file.

Field reference

Field Type Default Description
auto_confirm bool ${XUN_AUTO_CONFIRM} → false Every confirmation picks the default option without asking the user. /yolo toggles it at runtime
auto_compact.enabled bool true Master switch for automatic compaction
auto_compact.token_threshold int 192000 Token threshold that triggers compaction; the value compared is the total reported by the most recent model call
provider.openai_base_url str ${XUN_OPENAI_BASE_URL} OpenAI-compatible endpoint
provider.openai_api_key str ${XUN_OPENAI_API_KEY} API key
model.name str ${XUN_OPENAI_MODEL} → "" Model name; when the resolved value is an empty string, initialize() takes the first entry of models.list()
model.capabilities set ["vision"] Capability gating; currently only "vision". Decides whether tools carrying required_capabilities are exposed
model.temperature float | None None When None, it does not appear in the request
model.reasoning_field str | None None Field name for reasoning text; None means auto-detect on first appearance (reasoning / reasoning_content)
model.reasoning_effort str | None None none / minimal / low / medium / high / xhigh / max; some models accept only part of this set
enable_extensions bool ${XUN_ENABLE_EXTENSIONS} → true Whether extensions run at each agent initialization; automatically disabled for internal helper agents
load_project_instructions bool true Whether to load AGENTS.md from the working directory as a separate section of the system prompt
extension_settings dict[str, dict] {} Configuration bucketed per extension name; extensions read it through ctx.settings

Internal agents modify their own config

The conversation-summary agent turns off auto_compact and enable_extensions; the command risk-assessment agent likewise disables extensions. These changes happen only on their cloned configs.

Reading and writing at runtime

print(agent.config.to_json_str())        # JSON indented with 4 spaces
agent.config.model.name = "my-model"     # validate_assignment=True; a wrong type errors immediately

In a session, /config is the counterpart: with no arguments it prints the current configuration, and with key.sub=value it changes a single value (without writing to disk). load_config() returns the resolved global template — to diagnose what one agent actually uses, read agent.config.

How the compaction threshold behaves

auto_compact.token_threshold only decides "when compaction starts"; the strategy itself lives on AutoCompactor: old tool results are reclaimed first (no API call spent), and only if that is not enough does the summary agent write a summary that is placed into the system prompt. The tunables (toolcall_keep_max=12, summary_keep_max=16, escalation_rounds=2, max_retries=2) are fields of AutoCompactor, not entries in the config file; replace agent.compactor when you need to change them.

What is not in the config

The following are often mistaken for config fields:

  • Maximum iterations: a parameter of execute(max_iterations=…), default 512.
  • Retries and timeouts: hard-coded in the loop (at most 3 retries, exponential backoff, 900-second streaming timeout).
  • Display layer and web service parameters: constructor parameters of Display / WebDisplay / WebDisplayService, plus CLI arguments.
  • Command and path allow lists: runtime state of the current agent, managed with /policy.
  • Containers and multi-user: command-line arguments of xunc / xunx.