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:
-
Debug mode (current working directory) –
./symai.config.json(plussymsh/config.jsonandsymserver/config.jsonfor shell and server components). This allows developers to override settings locally without modifying global files. -
Python-environment config –
<python-prefix>/.symai/. This holds per-environment configurations for virtual environments or Conda environments. -
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 directoryself._env_config_dir = Path(sys.prefix) / ".symai"for the Python environmentself._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:
- Directory creation – Ensures config directories exist using
mkdir(parents=True, exist_ok=True) - Default file creation – Generates
symsh.config.jsonandsymserver.config.jsonif missing - Primary config loading – Loads
symai.config.json, launching a setup wizard when the file is absent - Post-migration – Handles field migrations, such as moving
TEXT_TO_SPEECH_ENGINE_API_KEYto new locations - 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 coreSymAIConfigimplementation, 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 fromSYMAI_CONFIG. -
symai/extended/vectordb.py– Illustrates how higher-level tools copy the configuration dictionary for internal use. -
symai/utils.py– Provides helper functions such asUserMessagefor 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
SymAIConfigclass insymai/backend/settings.pyencapsulates 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 insymai/__init__.py, making settings immediately available throughout the codebase. -
Components access settings by importing
SYMAI_CONFIGand using standard dictionary methods, as demonstrated in the OpenAI engine implementation. -
Runtime utilities like
config_manager.save_config()anddisplay_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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →