You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Problem: Xagent's configuration is scattered across 20+ files with inconsistent environment variable naming (LANCEDB_DIR vs XAGENT_UPLOADS_DIR), hardcoded paths, and no type safety. PR #247 improves this but doesn't go far enough.
Solution: A centralized configuration system with:
✅ Single entry point - from xagent.config import PathConfig, DatabaseConfig, SandboxConfig
✅ Type-safe - IDE autocomplete, validation at startup
✅ Unified naming - All env vars use XAGENT_* prefix with __ for nesting
✅ Config file + Environment variables - TOML for complex deployments, env vars for containers/secrets
✅ Internally modular - Independent modules per domain, still centrally managed
Breaking Changes: All env var names will change to follow XAGENT_* prefix convention. A transition period with deprecation warnings will be provided.
Key Decision Points Requiring Community Discussion:
🤔 Internal organization: Single monolithic class vs. modular xagent/config/ package?
🤔 Config file location: ./config.toml (project) vs /etc/xagent/config.toml (system)?
🤔 Config file format: TOML (recommended) vs YAML vs JSON5?
Recommended:Approach B (Pydantic-First) - Score 9.4/10. Best balance of type safety, unified naming, and modular organization support.
Migration Effort: Medium-High (more than incremental fixes, but solid foundation for future growth)
Executive Summary
Xagent currently suffers from a fragmented configuration architecture that causes path inconsistencies, environment variable handling problems, and deployment complexity. This proposal analyzes the current state, identifies pain points, and defines a centralized configuration system.
Proposal Objectives
Single source of truth for all configuration
Eliminate scattered os.getenv() calls across the codebase
Resolve circular dependency issues (core vs web modules)
Make configuration changes maintainable
IDE support and type safety
Enable autocomplete for configuration options
Catch configuration errors at type-check time, not runtime
Provide clear type information for each configuration value
Configuration file + Environment variables
Support TOML configuration files for complex deployments
Environment variables for container/secrets (with precedence)
Configuration organized by domain (paths, database, sandbox, etc.)
Independent development - no merge conflicts on single config file
Clear separation of concerns with namespace access (e.g., config.paths.storage_root)
Part 1: Problem Analysis
1.1 Current State Assessment
The Xagent codebase manages configuration through multiple disconnected mechanisms:
Mechanism 1: Scattered Environment Variables
Configuration scattered across 20+ files using os.getenv() calls
No central documentation of available configuration options
No validation of configuration values
# Example from src/xagent/core/workspace.py:50base_dir: str="uploads"# Hardcoded, ignores XAGENT_UPLOADS_DIR# Example from src/xagent/web/api/files.pyUPLOADS_DIR=Path(os.getenv("XAGENT_UPLOADS_DIR", "uploads"))
Mechanism 2: Database-Backed Settings
system_settings table exists but is underutilized
Primarily used for internal flags rather than user-facing configuration
Mechanism 3: Module-Level Constants
Individual modules define their own configuration constants
Leads to duplication and inconsistency
# src/xagent/providers/vector_store/lancedb.py:66defget_default_lancedb_dir():
# Hardcoded path computation duplicated from configreturnPath(os.getenv("LANCEDB_DIR", "~/.xagent/data/lancedb")).expanduser()
Problem 1: Breaking Changes Required for Unified Naming
Unified XAGENT_* env var naming (FR-6) is fundamentally incompatible with existing env var names:
LANCEDB_DIR → XAGENT_PATHS__LANCEDB_PATH
UPLOADS_DIR → XAGENT_PATHS__UPLOADS_DIR
SANDBOX_IMAGE → XAGENT_SANDBOX__IMAGE
Any solution that properly implements FR-6 will break existing deployments. The question is not whether to break compatibility, but how to manage the transition.
Problem 2: Hardcoded Variable Names and Configuration Reading Function Combination
Each configuration item requires a new function, repeating the same pattern
Adding new config = adding new function = high maintenance cost
Environment variable names, default values, and validation logic are scattered
Cannot see all configuration items and their defaults at a glance
Problem 2: Hardcoded Default Values and Validation Rules
# Default values hardcoded in function body, inconsistent rulesdefget_uploads_dir() ->Path:
returnweb_dir/"uploads"# Relative to web directorydefget_lancedb_path() ->Path:
returnPath("data/lancedb") # Relative to CWD!# Comment admits: "Default to ./data/lancedb, which is **relative** to cwd"defget_database_url() ->str:
db_path=get_default_sqlite_db_path() # Relative to homereturnf"sqlite:///{db_path}"
Problems:
Default values are scattered, cannot be viewed centrally
Path rules are inconsistent (source-relative vs cwd-relative vs home-relative)
Validation logic if env_var: return env_var is repeated 15+ times
Cannot express dependencies between configuration items
os.getenv() returns Optional[str] with no validation
Type errors only discovered at runtime
Poor Developer Experience
No autocomplete for configuration options
No inline documentation when accessing config values
2.2 Deployment Pain Points
Environment Variable Overload
15+ environment variables to manage
No configuration file support for complex deployments
Container Deployment Complexity
Data scattered across multiple directories requires multiple bind-mounts
Path resolution depends on working directory
Configuration Validation
Invalid configuration only discovered at runtime
No startup validation to catch misconfiguration early
2.3 Operational Pain Points
Configuration Documentation
example.env is comprehensive but separated from code
No programmatic way to list all available configuration
Migration Path
No clear path for evolving configuration over time
Risk of breaking existing deployments
Part 3: Requirements
3.1 Functional Requirements (Aligned with Project Goals)
FR-1: Centralized Configuration
Goal: Single source of truth
Req: Single module provides all configuration access
Why: Eliminates configuration scatter and resolves circular dependencies
Acceptance:
All configuration access goes through xagent.config module
No direct os.getenv() calls in business logic
Single import point: from xagent.config import get_uploads_dir, get_storage_root, ...
Configuration module has no internal xagent dependencies (NFR-1)
Related Issues: #243 (path inconsistency), #252 (naming confusion)
FR-2: Type Hints & Type Checking
Goal: IDE support and type safety
Req: Configuration values have type hints and are validated
Why: Current os.getenv() returns Optional[str] with no validation
Acceptance:
All configuration functions have proper type hints
Type errors caught at type-check time (mypy) and config load time
IDE autocomplete shows available configuration options
Return types are specific (e.g., Path, not str)
Generic type support for complex configuration
Example:
# Before (no type hints, no autocomplete)uploads_dir=os.getenv("XAGENT_UPLOADS_DIR", "uploads") # type: str | None# After (type hints, autocomplete)defget_uploads_dir() ->Path:
"""Get the uploads directory path."""
...
# IDE shows: get_uploads_dir() -> Path
FR-3: Configuration File + Environment Variables
Goal: Multi-source configuration loading
Req: Support both configuration files and environment variables with precedence
Why:
Configuration files for complex deployments and documentation
Environment variables for containers/secrets/overrides
xagent/config/
__init__.py # Aggregates all config modules
paths.py # PathConfig for storage, uploads, etc.
database.py # DatabaseConfig for DB connections
sandbox.py # SandboxConfig for container config
llm.py # LLMConfig for model providers
# With env_prefix="XAGENT_" and env_nested_delimiter="__"export XAGENT_STORAGE_ROOT=/data
export XAGENT_PATHS__STORAGE_ROOT=/data # If using nested modelsexport XAGENT_LOG_LEVEL=DEBUG
Testing Effort: High (test all changed code paths)
Relative Effort: ⭐⭐⭐ Highest - Most comprehensive refactoring
Approach C (Hybrid): Migration Effort
New Code: ~800 lines (internal config, function wrappers)
Modified Files: ~20 files (initial migration)
Testing Effort: Medium-High (test both APIs)
Relative Effort: ⭐⭐ Medium - Balance between A and B
5.8 Decision Framework
Updated Requirements Context:
FR-6: Unified XAGENT_* naming with __ for nested config (breaking change required)
FR-8: Modular organization required for independent development
FR-7: Migration path with deprecation warnings (not backward compatibility)
Based on the analysis, the recommended approach should maximize:
Unified Naming & Nested Env Var Support (P0 requirements)
Modular Organization (FR-8, P0 requirement)
Future Extensibility
Reasonable Implementation Risk
Updated Decision Matrix:
Criterion
Weight
A: Function
B: Pydantic
C: Hybrid
Unified Naming (__ separator)
25%
2
10
10
Modular Organization
25%
3
10
10
Type Safety & Validation
25%
4
10
8
Future Extensibility
15%
3
10
7
Implementation Risk
10%
10
4
7
Weighted Score
100%
4.1
9.1
8.8
Winner: Approach B (Pydantic-First) with 9.1/10
Rationale:
With FR-6 requiring unified XAGENT_* naming with __ separator AND FR-8 requiring modular organization:
Approach A (Function-based): Cannot easily support __ separator or true modular organization
Approach B (Pydantic): Native support for env_nested_delimiter="__" AND independent BaseSettings classes per module
Approach C (Hybrid): Supports all requirements but adds unnecessary complexity since breaking changes are acceptable
Key Differentiator: Modular Organization
Only pydantic-settings and Hydra truly support independent config modules. Given xagent's requirements, pydantic-settings is the clear winner.
Part 7: Decision Framework
This section provides a framework for choosing between the three approaches, without prescribing which is "best" for xagent.
7.1 Decision Criteria
Criterion
Approach A
Approach B
Approach C
If type safety is the highest priority
⚠️
✅
✅
If minimal dependencies is required
✅
❌
❌
If fast delivery is important
✅
❌
⚠️
If long-term maintainability matters
⚠️
✅
✅
If team knows pydantic
⚠️
✅
✅
If risk tolerance is low
⚠️
✅
✅
Note: All approaches require breaking changes to implement FR-6 (unified XAGENT_* naming). Backward compatibility is not a differentiator.
7.2 Questions to Guide Decision
Is xagent willing to add pydantic as a dependency?
Yes → Consider Approach B or C
No → Approach A only
What is the team's familiarity with pydantic?
High → Approach B or C
Low → Approach A (or C with training)
What is the team's capacity and urgency?
Need quick wins with minimal changes → Approach A
Have capacity for proper refactoring → Approach B or C
What is the long-term vision for xagent?
Stay simple, minimal dependencies → Approach A
Modern Python best practices → Approach B or C
7.3 Hybrid Approach (C) Consideration
Approach C is often chosen when:
Backward compatibility is non-negotiable
Team wants to adopt pydantic incrementally
Risk tolerance is medium
Long-term vision includes full pydantic migration
Trade-off: Higher initial complexity (two APIs) for smoother migration path.
7.4 Example Decision Outcomes
Scenario
Recommended Approach
Startup phase, moving fast, minimal deps
A
Established product, breaking changes acceptable
B
Large team, gradual migration required
C
New project, no legacy code
B
For xagent: Approach B is recommended because:
Breaking changes are required for unified XAGENT_* naming (FR-6)
Modular organization is required (FR-8)
pydantic-settings provides native support for __ nested delimiter and independent config modules
Part 8: Implementation Considerations
8.1 Configuration File Format
See detailed analysis in Part 5, Section 5.2 for configuration file format options including TOML (recommended), YAML (secondary), and JSON5/JSONC (optional).
8.2 Configuration File Locations
For a multi-user web service like xagent, configuration file locations differ from desktop applications:
/etc/xagent/config.toml — System-wide configuration (for production deployments)
8.3 Environment Variable Naming Migration
Current State (Inconsistent):
Old Name
Notes
LANCEDB_DIR
No prefix
XAGENT_UPLOADS_DIR
Has prefix, inconsistent with LANCEDB_*
UPLOADS_DIR
No prefix, conflicts with above
SANDBOX_IMAGE
No prefix
OPENAI_API_KEY
Third-party, no prefix
Target State (Unified):
New Name
Old Name(s)
Deprecation
XAGENT_PATHS__STORAGE_ROOT
N/A (new)
-
XAGENT_PATHS__UPLOADS_DIR
XAGENT_UPLOADS_DIR, UPLOADS_DIR
⚠️ Warning
XAGENT_PATHS__LANCEDB_PATH
LANCEDB_DIR, LANCEDB_PATH
⚠️ Warning
XAGENT_PATHS__DATABASE_URL
DATABASE_URL
⚠️ Warning
XAGENT_SANDBOX__IMAGE
SANDBOX_IMAGE
⚠️ Warning
XAGENT_SANDBOX__CPUS
SANDBOX_CPUS
⚠️ Warning
OPENAI_API_KEY
OPENAI_API_KEY
✅ Keep (external)
Implementation Notes:
The __ delimiter is an industry standard used by both pydantic-settings and dynaconf
Old env var names should be supported with deprecation warnings for at least 2 minor releases
Implementation Strategy:
Define new XAGENT_* env vars with pydantic-settings
Support old env var names with deprecation warnings (using aliases or custom validators)
Document migration path clearly
Provide migration tooling (optional)
8.4 Module Organization
Proposed Structure:
src/xagent/config/
__init__.py # Aggregates all config modules, exports `paths`, `database`, etc.
paths.py # PathConfig class
database.py # DatabaseConfig class
sandbox.py # SandboxConfig class
llm.py # LLMConfig class
...
Key Finding: Both pydantic-settings and dynaconf use __ as the nested delimiter, making it a de facto standard for Python configuration management with environment variables.
8.6 Implementation Phases
Phase 1: Foundation
Goal: Create core configuration infrastructure with backward compatibility
Estimated Effort: ~30% of total effort
Deliverables:
Create xagent/config module with:
Internal pydantic config classes
Function-based wrapper API for backward compatibility
Proposal: Centralized Configuration System for Xagent
Status: Draft
Author: @tanbro
Created: 2026-04-03
Related Issues: #243, #246, #252
Related PRs: #235, #247
TL;DR
Problem: Xagent's configuration is scattered across 20+ files with inconsistent environment variable naming (
LANCEDB_DIRvsXAGENT_UPLOADS_DIR), hardcoded paths, and no type safety. PR #247 improves this but doesn't go far enough.Solution: A centralized configuration system with:
from xagent.config import PathConfig, DatabaseConfig, SandboxConfigXAGENT_*prefix with__for nestingBreaking Changes: All env var names will change to follow
XAGENT_*prefix convention. A transition period with deprecation warnings will be provided.Key Decision Points Requiring Community Discussion:
xagent/config/package?./config.toml(project) vs/etc/xagent/config.toml(system)?Recommended: Approach B (Pydantic-First) - Score 9.4/10. Best balance of type safety, unified naming, and modular organization support.
Migration Effort: Medium-High (more than incremental fixes, but solid foundation for future growth)
Executive Summary
Xagent currently suffers from a fragmented configuration architecture that causes path inconsistencies, environment variable handling problems, and deployment complexity. This proposal analyzes the current state, identifies pain points, and defines a centralized configuration system.
Proposal Objectives
Single source of truth for all configuration
os.getenv()calls across the codebaseIDE support and type safety
Configuration file + Environment variables
Unified environment variable naming
XAGENT_*prefix convention__separator (e.g.,XAGENT_PATHS__STORAGE_ROOT)Modular organization (proposed for discussion)
config.paths.storage_root)Part 1: Problem Analysis
1.1 Current State Assessment
The Xagent codebase manages configuration through multiple disconnected mechanisms:
Mechanism 1: Scattered Environment Variables
os.getenv()callsMechanism 2: Database-Backed Settings
system_settingstable exists but is underutilizedMechanism 3: Module-Level Constants
1.2 Symptom Analysis
"uploads"XAGENT_UPLOADS_DIRignored in core modulesLANCEDB_DIRvsLANCEDB_PATH./data,~/.xagent,src/xagent/web/XAGENT_UPLOADS_DIR1.3 Dependency Issues
Circular Dependency Problem:
This forces core modules to hardcode paths, creating the inconsistency problem.
1.4 Why PR #247 is Not Enough
Status: PR #247 (
feat/unified-configuration-module) is in thefeat/unified-configuration-modulebranch, not yet merged to main.What PR #247 Does:
src/xagent/core/config.pywith 15+ configuration functionsWhat PR #247 Does NOT Solve:
Problem 1: Breaking Changes Required for Unified Naming
Unified
XAGENT_*env var naming (FR-6) is fundamentally incompatible with existing env var names:LANCEDB_DIR→XAGENT_PATHS__LANCEDB_PATHUPLOADS_DIR→XAGENT_PATHS__UPLOADS_DIRSANDBOX_IMAGE→XAGENT_SANDBOX__IMAGEAny solution that properly implements FR-6 will break existing deployments. The question is not whether to break compatibility, but how to manage the transition.
Problem 2: Hardcoded Variable Names and Configuration Reading Function Combination
Problems:
Problem 2: Hardcoded Default Values and Validation Rules
Problems:
if env_var: return env_varis repeated 15+ timesProblem 3: No Support for Nested Configuration
Cannot Express:
Missing Capabilities:
sandbox.*)Problem 4: Weak Type Checking
Problems:
Noneeven though there's a meaningful defaultProblem 5: No Configuration File Support
Missing:
1.5 Root Cause Analysis
Conclusion: PR #247 is an "improvement" but doesn't fundamentally solve the configuration management problem.
What's really needed: Transition from "function-based API" to "declarative configuration definition".
Part 2: Pain Points
2.1 Development Pain Points
No Single Source of Truth
No Type Safety
os.getenv()returnsOptional[str]with no validationPoor Developer Experience
2.2 Deployment Pain Points
Environment Variable Overload
Container Deployment Complexity
Configuration Validation
2.3 Operational Pain Points
Configuration Documentation
example.envis comprehensive but separated from codeMigration Path
Part 3: Requirements
3.1 Functional Requirements (Aligned with Project Goals)
FR-1: Centralized Configuration
Goal: Single source of truth
xagent.configmoduleos.getenv()calls in business logicfrom xagent.config import get_uploads_dir, get_storage_root, ...Related Issues: #243 (path inconsistency), #252 (naming confusion)
FR-2: Type Hints & Type Checking
Goal: IDE support and type safety
os.getenv()returnsOptional[str]with no validationPath, notstr)Example:
FR-3: Configuration File + Environment Variables
Goal: Multi-source configuration loading
Configuration File Locations (loaded in order, later overrides earlier):
/etc/xagent/config.toml(system-wide, lowest precedence)~/.config/xagent/config.toml(user-specific, medium precedence)./config.toml(project-specific, highest precedence)Example Config File:
Environment Variable Override:
FR-4: Path Configuration Centralization
Goal: Resolve path inconsistency issues
XAGENT_STORAGE_ROOTas default parent for all data pathsFR-5: Sensitive Configuration Handling
Goal: Secure handling of keys and passwords
FR-6: Unified Environment Variable Naming
Goal: Consistent, predictable environment variable naming
XAGENT_*prefix convention with nested support via__XAGENT_*prefix__separator (e.g.,XAGENT_PATHS__STORAGE_ROOT)Industry Convention Verification:
__(default)export MY_APP__DATABASE__HOST=localhost__export DYNACONF_NESTED__LEVEL__KEY=1Key Implementation Notes:
env_nested_delimiter(defaults to__)osmodule limitation)Example Migration:
FR-7: Migration Path
Goal: Smooth transition for existing deployments
LANCEDB_DIR→XAGENT_PATHS__LANCEDB_PATH)FR-8: Modular Organization (Proposed - Needs Discussion)
Goal: Independent development and maintenance of configuration domains
xagent.configpackagePathConfig,DatabaseConfig)from xagent.config import PathConfig, DatabaseConfigpaths = PathConfig(); print(paths.storage_root)Example Structure:
Usage:
Not All Approaches Support This:
BaseSettings3.2 Requirements Summary (Goal Alignment)
Priority Legend:
3.3 Non-Functional Requirements
NFR-1: No Circular Dependencies (P0)
NFR-2: Performance (P1)
NFR-3: Testability (P1)
NFR-4: Error Handling (P1)
NFR-5: Maintainability (P2)
3.2 Non-Functional Requirements
NFR-1: No Circular Dependencies
xagent.confighas no internal xagent dependenciesNFR-2: Performance
NFR-3: Testability
NFR-4: Error Handling (P1)
NFR-5: Maintainability (P2)
Part 4: Configuration Scope
Based on the analysis and goals, the centralized configuration system should cover:
4.1 Path Configuration (P0 - Critical)
XAGENT_STORAGE_ROOT- Root for all data (~/.xagent)XAGENT_UPLOADS_DIR- User upload filesXAGENT_WEB_STATIC_DIR- Static web assetsXAGENT_LANCEDB_PATH- Vector database pathXAGENT_DATABASE_URL- Primary database connectionXAGENT_EXTERNAL_UPLOAD_DIRS- Additional upload directoriesXAGENT_EXTERNAL_SKILLS_LIBRARY_DIRS- Additional skills directories4.2 Service Configuration (P0 - Critical)
XAGENT_LOG_LEVEL- Logging verbosity (DEBUG/INFO/WARNING/ERROR/CRITICAL)4.3 Sandbox Configuration (P1 - High)
SANDBOX_IMAGE- Container imageSANDBOX_CPUS,SANDBOX_MEMORY- Resource limitsSANDBOX_ENV,SANDBOX_VOLUMES- Mounts and environment4.4 External Service Configuration (P1 - High)
Note: These are typically stored as environment variables (secrets), not in config files
Part 5: Configuration System Options (Neutral Analysis)
This section provides a neutral comparison of common Python configuration management approaches, without assuming which is best for xagent.
5.1 Overview of Configuration Approaches
5.2 Detailed Analysis
Option 1: pydantic-settings
Description: Type-safe configuration using Pydantic models with validation.
Example:
Environment Variable Mapping:
Characteristics:
__delimiterTrade-offs:
__nested delimiter supportReferences: Pydantic Settings Documentation
Option 2: Flask Style Config
Description: Class-based configuration with inheritance for environment separation.
Example:
Characteristics:
Trade-offs:
References: Flask Configuration
Option 3: Django Style Settings
Description: Single module with Python-based configuration, optionally split across files.
Example:
Characteristics:
Trade-offs:
References: django-split-settings
Option 4: dynaconf
Description: Multi-format configuration loader with remote config support.
Example:
Characteristics:
Trade-offs:
Option 5: Hydra
Description: Configuration composition framework for complex applications.
Example:
Characteristics:
Trade-offs:
Option 6: Current PR #247 (Function-Based)
Description: Function-based API with hardcoded defaults and environment variable reading.
Example:
Characteristics:
Optional[int]forces callers to handleNoneeven when there's a meaningful defaultTrade-offs:
5.3 Comparison Matrix (Detailed)
Legend: ✅✅✅ Excellent | ✅ Good |⚠️ Partial | ❌ No Support
Notes:
XAGENT_PATHS__STORAGE_ROOTto nested configconfig.paths.storage_root__(double underscore) is the de facto standard (pydantic-settings, dynaconf).via CLI, not env vars5.4 Recommendation Framework
When choosing an approach, consider:
No approach is universally "best" — the choice depends on xagent's specific constraints and priorities.
Part 6: Proposed Solution Approaches
Based on the analysis above, three implementation approaches are considered for xagent:
6.1 Approach A: Enhanced PR #247 (Function-Based)
Technical Design
Pros
Cons
Risk Assessment
Overall Risk Level: LOW
6.2 Approach B: Pydantic-Based Settings (Transformative)
Based on: Option 1 (pydantic-settings) from the analysis above
Technical Design
Pros
Cons
Risk Assessment
Overall Risk Level: HIGH
6.3 Approach C: Hybrid (Balanced)
Technical Design
Pros
Cons
Risk Assessment
Overall Risk Level: MEDIUM
6.4 Configuration File Format Selection
✅ Better than INI for nesting
✅ Growing Python support
✅ Type preservation
❌ Limited expression support
✅ Powerful expressions
✅ Wide tool support
❌ Security concerns (unsafe load)
❌ Significant whitespace
✅ Familiar to JS developers
✅ Wide tool support
❌ No built-in support
✅ Built-in Python support
❌ No type preservation
✅ Easy to parse
❌ Verbose syntax
Recommendation: TOML (primary), with YAML as secondary, JSON5 as optional
Rationale:
tomllib)yaml.unsafe_load()tomllib)JSON5/JSONC Note:
json5,jsoncomment) in Python6.5 Migration Path Analysis
Approach A (Enhanced PR #247): Migration Effort
Approach B (Pydantic-First): Migration Effort
Approach C (Hybrid): Migration Effort
5.8 Decision Framework
Updated Requirements Context:
XAGENT_*naming with__for nested config (breaking change required)Based on the analysis, the recommended approach should maximize:
Updated Decision Matrix:
__separator)Winner: Approach B (Pydantic-First) with 9.1/10
Rationale:
With FR-6 requiring unified
XAGENT_*naming with__separator AND FR-8 requiring modular organization:__separator or true modular organizationenv_nested_delimiter="__"AND independentBaseSettingsclasses per moduleKey Differentiator: Modular Organization
Only pydantic-settings and Hydra truly support independent config modules. Given xagent's requirements, pydantic-settings is the clear winner.
Part 7: Decision Framework
This section provides a framework for choosing between the three approaches, without prescribing which is "best" for xagent.
7.1 Decision Criteria
Note: All approaches require breaking changes to implement FR-6 (unified
XAGENT_*naming). Backward compatibility is not a differentiator.7.2 Questions to Guide Decision
Is xagent willing to add pydantic as a dependency?
What is the team's familiarity with pydantic?
What is the team's capacity and urgency?
What is the long-term vision for xagent?
7.3 Hybrid Approach (C) Consideration
Approach C is often chosen when:
Trade-off: Higher initial complexity (two APIs) for smoother migration path.
7.4 Example Decision Outcomes
For xagent: Approach B is recommended because:
XAGENT_*naming (FR-6)__nested delimiter and independent config modulesPart 8: Implementation Considerations
8.1 Configuration File Format
See detailed analysis in Part 5, Section 5.2 for configuration file format options including TOML (recommended), YAML (secondary), and JSON5/JSONC (optional).
8.2 Configuration File Locations
For a multi-user web service like xagent, configuration file locations differ from desktop applications:
Options:
./config.toml— Project-specific configuration (for development)/etc/xagent/config.toml— System-wide configuration (for production deployments)8.3 Environment Variable Naming Migration
Current State (Inconsistent):
LANCEDB_DIRXAGENT_UPLOADS_DIRUPLOADS_DIRSANDBOX_IMAGEOPENAI_API_KEYTarget State (Unified):
XAGENT_PATHS__STORAGE_ROOTXAGENT_PATHS__UPLOADS_DIRXAGENT_UPLOADS_DIR,UPLOADS_DIRXAGENT_PATHS__LANCEDB_PATHLANCEDB_DIR,LANCEDB_PATHXAGENT_PATHS__DATABASE_URLDATABASE_URLXAGENT_SANDBOX__IMAGESANDBOX_IMAGEXAGENT_SANDBOX__CPUSSANDBOX_CPUSOPENAI_API_KEYOPENAI_API_KEYImplementation Notes:
__delimiter is an industry standard used by both pydantic-settings and dynaconfImplementation Strategy:
XAGENT_*env vars with pydantic-settings8.4 Module Organization
Proposed Structure:
Import Style:
Migration Path:
src/xagent/config/package (replacingsrc/xagent/core/config.py)core/config.pyafter migration complete8.5 Nested Delimiter Convention Research
Research Summary:
The
__(double underscore) convention for nested environment variables is verified as an industry standard:__env_nested_delimiter(default:__)__export DYNACONF_NESTED__LEVEL__KEY=1Sources:
Key Finding: Both pydantic-settings and dynaconf use
__as the nested delimiter, making it a de facto standard for Python configuration management with environment variables.8.6 Implementation Phases
Phase 1: Foundation
Goal: Create core configuration infrastructure with backward compatibility
Estimated Effort: ~30% of total effort
Deliverables:
xagent/configmodule with:pydantic-settingsto dependenciesexample.envwith new configuration optionsAcceptance Criteria:
Phase 3: Path Migration
Goal: Migrate all path configuration to use new system
Estimated Effort: ~40% of total effort
Deliverables:
src/xagent/core/workspace.pysrc/xagent/core/agent/service.pysrc/xagent/core/storage/manager.pysrc/xagent/web/api/files.pysrc/xagent/web/api/websocket.pysrc/xagent/web/sandbox_manager.pyAcceptance Criteria:
Phase 4: Documentation & Tooling
Goal: Improve developer experience and documentation
Deliverables:
xagent config --list(to view all configuration)Acceptance Criteria:
Phase 5: Cleanup & Deprecation (Ongoing)
Goal: Complete migration and remove legacy code
Deliverables:
Acceptance Criteria:
8.7 Critical Success Factors
Part 9: Open Questions
This section lists open questions that need discussion/decision:
Configuration File Location (DECISION NEEDED):
Note: xagent is a multi-user web service (similar to Django/Rails), not a desktop application.
Proposed options:
./config.toml— Project-specific configuration (for development)/etc/xagent/config.toml— System-wide configuration (for production deployments)User data remains at
~/.xagent/(per-user storage, already isolated by user_id in uploads/).Secret Management: Should the configuration system handle secrets separately?
Configuration Profiles: Should we support named configuration profiles?
xagent --profile developmentTOML vs YAML vs JSON5: Which configuration file format to prioritize?
Breaking Changes Communication: How to communicate breaking changes to existing users?
Modular Organization (FR-8): Should configuration be organized as independent modules?
xagent/config/with separate files per domain (paths, database, sandbox, etc.)Part 10: Success Criteria
Regardless of which approach is chosen, success means:
XAGENT_*prefix convention with__for nestingAppendix: References
A.1 Configuration Management Resources
A.2 Existing xagent Configuration
src/xagent/config.py- Path configuration (PR feat: unified configuration module for all path-related settings #247, infeat/unified-configuration-modulebranch)src/xagent/web/config.py- Web-specific configurationsrc/xagent/web/auth_config.py- Authentication configurationsrc/xagent/core/observability/langfuse_config.py- Langfuse config (Pydantic example)A.3 Related Issues
feat/unified-configuration-modulebranch)