Configuration Management in SymbolicAI: A Complete Guide to JSON-Based Settings

SymbolicAI manages configuration through a hierarchical JSON file system with three priority levels—debug (current directory), environment-specific, and global user settings—centered around the SymAIConfig class in symai/backend/settings.py.

The extensityai/symbolicai repository implements a robust configuration management system that allows developers to customize LLM models, API keys, and engine options across different deployment contexts. This article explores how the framework handles configuration files, prioritizes settings, and provides runtime access to configuration dictionaries.

The Three-Tier Configuration Hierarchy

SymbolicAI employs a cascading priority system where configuration files are resolved in the following order:

  1. Debug mode (current working directory)./symai.config.json (plus symsh/config.json and symserver/config.json for shell and server components). This allows developers to override settings locally without modifying global files.

  2. Python-environment config<python-prefix>/.symai/. This holds per-environment configurations for virtual environments or Conda environments.

  3. User-home (global) config~/.symai/. This serves as the fallback for defaults shared across all environments for a user.

The SymAIConfig class in symai/backend/settings.py encapsulates this resolution logic, checking for file existence in each location and returning the first match found.

Core Configuration Components

SymAIConfig: The Configuration Facade

The SymAIConfig class serves as the primary interface for all configuration operations in symai/backend/settings.py. During initialization, it records three base directories:

  • self._debug_dir = Path.cwd() for the current working directory
  • self._env_config_dir = Path(sys.prefix) / ".symai" for the Python environment
  • self._home_config_dir = Path.home() / ".symai" for the user home directory

The config_dir property implements priority resolution by checking for symai.config.json in the debug folder first, then falling back to environment or home directories. The get_config_path() method builds absolute paths for requested config files, respecting this priority order and an optional fallback_to_home flag.

For persistence, load_config() reads JSON files, caches paths in _active_paths, and returns empty dictionaries for missing files. The save_config() method writes JSON data, ensures parent directories exist, and updates the cache. Migration utilities like migrate_config() add new fields to existing configurations, while private helpers such as _canonical_key and _remove_legacy_path_keys prevent stale path keys from lingering in the cache.

Package Bootstrap in symai/__init__.py

When the SymbolicAI package imports, the _start_symai() function executes a comprehensive initialization sequence:

  1. Directory creation – Ensures config directories exist using mkdir(parents=True, exist_ok=True)
  2. Default file creation – Generates symsh.config.json and symserver.config.json if missing
  3. Primary config loading – Loads symai.config.json, launching a setup wizard when the file is absent
  4. Post-migration – Handles field migrations, such as moving TEXT_TO_SPEECH_ENGINE_API_KEY to new locations
  5. Engine validation – Verifies neuro-symbolic engine configuration, falling back to home config or aborting with user-friendly messages if the model is not a built-in Llama/HuggingFace engine and lacks an API key

This bootstrap populates three global dictionaries—SYMAI_CONFIG, SYMSH_CONFIG, and SYMSERVER_CONFIG—making configuration data available throughout the codebase via simple imports:

from symai.backend.settings import SYMAI_CONFIG

Runtime Helpers

The configuration system provides diagnostic utilities for runtime inspection. The get_active_path(filename) method returns the exact file path last used to read or write a given config, aiding in debugging configuration source issues. The display_config() function leverages the Rich library to render an interactive tree showing all three configuration locations (debug, environment, home) with active paths highlighted, providing immediate visual feedback about which configuration files are currently in effect.

How Components Access Configuration

Individual engines and high-level components import the shared SYMAI_CONFIG dictionary to retrieve settings. For example, the OpenAI-based neuro-symbolic engine in symai/backend/engines/neurosymbolic/engine_openai_gptX_chat.py accesses its model and API key as follows:

from symai.backend.settings import SYMAI_CONFIG

model = SYMAI_CONFIG.get("NEUROSYMBOLIC_ENGINE_MODEL")
api_key = SYMAI_CONFIG.get("NEUROSYMBOLIC_ENGINE_API_KEY")

Because SYMAI_CONFIG populates once at import time, subsequent imports throughout the application see a fully resolved configuration state without additional file I/O.

Practical Configuration Examples

Reading and Overriding Settings

Developers can inspect and modify configuration values at runtime using the configuration manager and global dictionary:


# 1️⃣ Import the manager and config dict

from symai.backend.settings import config_manager, SYMAI_CONFIG

# 2️⃣ Read the current model

print("Current neuro-symbolic model:", SYMAI_CONFIG.get("NEUROSYMBOLIC_ENGINE_MODEL"))

# 3️⃣ Override a value for the current session (e.g., switch to a local Llama model)

SYMAI_CONFIG["NEUROSYMBOLIC_ENGINE_MODEL"] = "llama_cpp"
SYMAI_CONFIG["NEUROSYMBOLIC_ENGINE_API_KEY"] = ""   # not needed for local inference

# 4️⃣ Persist the change to the *debug* config (CWD) – useful during experimentation

config_manager.save_config("symai.config.json", SYMAI_CONFIG)
print("Saved new config to:", config_manager.get_active_path("symai.config.json"))

Using the Configuration Inspector

For debugging configuration sources, SymbolicAI provides a visual inspection tool:

from symai import display_config

# Opens an interactive Rich tree showing:

# • Debug config (if present)

# • Environment config

# • Home (global) config

# • Active configuration summary

display_config()

Key Configuration Files

The configuration architecture spans several critical files within the repository:

  • symai/backend/settings.py – Contains the core SymAIConfig implementation, including path resolution, JSON load/save operations, and configuration migration logic.

  • symai/__init__.py – Handles package bootstrap, directory creation, default config file generation, setup wizard execution, and population of global configuration dictionaries.

  • symai/backend/engines/neurosymbolic/engine_openai_gptX_chat.py – Demonstrates how neuro-symbolic engines retrieve model and API key settings from SYMAI_CONFIG.

  • symai/extended/vectordb.py – Illustrates how higher-level tools copy the configuration dictionary for internal use.

  • symai/utils.py – Provides helper functions such as UserMessage for emitting user-visible messages during configuration validation.

Summary

  • SymbolicAI uses a three-tier hierarchy for configuration files: debug (current directory), Python environment (<prefix>/.symai/), and user home (~/.symai/), resolved in that priority order.

  • The SymAIConfig class in symai/backend/settings.py encapsulates all path resolution, file I/O, and migration logic for JSON configuration files.

  • Global dictionaries (SYMAI_CONFIG, SYMSH_CONFIG, SYMSERVER_CONFIG) populate at package import time via the bootstrap sequence in symai/__init__.py, making settings immediately available throughout the codebase.

  • Components access settings by importing SYMAI_CONFIG and using standard dictionary methods, as demonstrated in the OpenAI engine implementation.

  • Runtime utilities like config_manager.save_config() and display_config() enable dynamic configuration updates and visual debugging of active settings.

Frequently Asked Questions

Where does SymbolicAI store its configuration files?

SymbolicAI stores configuration files in three possible locations, checked in priority order: first in the current working directory (./symai.config.json for debug mode), then in the Python environment directory (<python-prefix>/.symai/), and finally in the user home directory (~/.symai/). The framework uses the first configuration file it finds in this sequence, allowing local overrides to take precedence over global settings.

How do I override configuration settings for a single project?

To override settings for a specific project, create a symai.config.json file in your project's root directory (current working directory). This debug-mode configuration automatically takes priority over environment and home directory settings. You can also modify settings at runtime by importing SYMAI_CONFIG from symai.backend.settings, updating the dictionary values, and calling config_manager.save_config("symai.config.json", SYMAI_CONFIG) to persist changes to the local file.

What happens if the configuration file is missing?

If SymbolicAI cannot find symai.config.json in any of the three hierarchical locations (debug, environment, or home), the bootstrap process in symai/__init__.py triggers an interactive setup wizard to create a new configuration file. Additionally, the load_config() method in SymAIConfig returns an empty dictionary if a requested file does not exist, allowing the system to handle missing configurations gracefully while prompting the user for necessary setup.

How can I view the currently active configuration?

Use the display_config() function imported from the symai package to visualize the active configuration hierarchy. This function renders an interactive Rich tree showing all three configuration locations (debug, environment, and home), highlighting which specific files are currently active. For programmatic access, call config_manager.get_active_path("symai.config.json") to retrieve the exact file path being used for the main configuration.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →