-
Notifications
You must be signed in to change notification settings - Fork 74
Description
Overview
The SDK's configuration system is confusing and needs clarification. We have multiple configuration approaches that overlap:
- A
RunAnywhereConfig.example.jsonfile that's barely used ConfigurationDatastruct with complex remote/local/consumer fallbackSDKInitParamspassed during initialization- Hardcoded constants in
RunAnywhereConstants
Impact: High - Developers don't understand how to configure the SDK
Priority: P1
Effort: Medium
Problem Statement
Current Confusing State
1. JSON Config File Exists But Isn't Really Used
- Location: sdk/runanywhere-swift/Configuration/RunAnywhereConfig.example.json
- Only contains API URLs and basic feature flags
- Loaded by RunAnywhereConstants.swift:68
- BUT: Not actually used during SDK initialization!
2. Three Different Configuration Sources
// ConfigurationData has 3 sources:
public enum ConfigurationSource {
case remote // From backend API
case consumer // From developer overrides
case defaults // SDK built-in defaults
}The fallback chain in ConfigurationService.swift:26-63:
Remote API → Database → Consumer Config → SDK Defaults
3. Initialization Uses Different Approach
RunAnywhereAIApp.swift:87-92:
try RunAnywhere.initialize(
apiKey: "dev",
baseURL: "localhost",
environment: .development
)4. ConfigurationData vs SDKInitParams Confusion
SDKInitParams- Used during RunAnywhere.initialize()ConfigurationData- Complex struct with routing, generation, storage, API configs- They serve different purposes but it's unclear which is which!
Key Questions to Answer
🔴 Critical Questions:
-
What is the JSON config file for?
- Should it be used during initialization?
- Or is it only for build-time constants?
- Should we remove it if unused?
-
When do we use ConfigurationData?
- Is it only for runtime settings fetched from backend?
- Can developers provide their own ConfigurationData?
- How does it relate to SDKInitParams?
-
What's the intended configuration flow?
Option A: JSON → SDKInitParams → Initialize → Fetch Remote Config Option B: SDKInitParams → Initialize → No JSON needed Option C: Something else entirely? -
Consumer Configuration - What is it?
- LocalConfigurationDataSource.swift:109-125 has
saveConsumerOverride - When/how do developers use this?
- Is this for runtime overrides?
- LocalConfigurationDataSource.swift:109-125 has
Current Implementation Analysis
What Actually Happens Today:
Development Mode:
// 1. Initialize with params
RunAnywhere.initialize(apiKey: "dev", baseURL: "localhost", environment: .development)
// 2. No remote fetch, uses SDK defaults
ConfigurationData.sdkDefaults(apiKey: "dev")
// 3. JSON file ignored ❌Production Mode:
// 1. Initialize with params
RunAnywhere.initialize(apiKey: key, baseURL: url, environment: .production)
// 2. Tries to fetch from remote API
// 3. Falls back to DB → Consumer → Defaults
// 4. JSON file still ignored ❌Files Involved:
| File | Purpose | Issues |
|---|---|---|
| RunAnywhereConfig.example.json | Build-time config | ❌ Not used during init |
| ConfigurationData.swift | Runtime settings | ❓ Unclear when/how to use |
| SDKInitParams | Init parameters | ✅ Clear usage |
| RunAnywhereConstants.swift | Static constants |
Proposed Solution
Option 1: Simplify - Remove JSON Config (Recommended)
Reasoning: The JSON isn't actually used. SDKInitParams is clearer.
// Developers initialize directly with params - no JSON needed
try RunAnywhere.initialize(
apiKey: apiKey,
baseURL: baseURL,
environment: .production
)Changes:
- Remove
RunAnywhereConfig.example.json - Remove JSON loading from
RunAnywhereConstants - Document that init params are the only config needed
- Keep
ConfigurationDatafor backend-fetched settings
Option 2: Make JSON Actually Work
Reasoning: If we keep the JSON, make it useful.
// Load from JSON + environment-specific overrides
try RunAnywhere.initialize(
configFile: "RunAnywhereConfig", // Loads JSON
environment: .production // Uses production values from JSON
)
// Or allow programmatic override
try RunAnywhere.initialize(
apiKey: apiKey, // Overrides JSON
environment: .production
)Changes:
- Update
initialize()to load from JSON first - Allow programmatic overrides
- Document the precedence: Code > Env Vars > JSON > Defaults
Option 3: Separate Concerns Clearly
Reasoning: Different configs for different purposes.
// 1. Build-time config (JSON) - for constants, endpoints
RunAnywhereConstants.load("RunAnywhereConfig.json")
// 2. SDK initialization - for API key, environment
try RunAnywhere.initialize(
apiKey: apiKey,
baseURL: RunAnywhereConstants.apiURLs.production
)
// 3. Runtime config (ConfigurationData) - fetched from backend
let config = await RunAnywhere.getConfiguration()Document clearly:
- JSON = Build-time constants
- SDKInitParams = SDK initialization
- ConfigurationData = Runtime settings from backend
Implementation Plan
Phase 1: Documentation & Clarity
- Document current behavior in README
- Add inline comments explaining each config type
- Create decision matrix: "When to use X vs Y"
Phase 2: Choose Solution
- Discuss with team which option to pursue
- Get stakeholder approval on approach
Phase 3: Implementation
- Implement chosen solution
- Add example code showing proper usage
- Update sample app to demonstrate best practices
- Add migration guide if breaking changes
Phase 4: Validation
- Add tests for configuration loading
- Verify all paths work correctly
- Update documentation
Success Criteria
- Clear documentation on when to use JSON vs SDKInitParams vs ConfigurationData
- Example code showing all configuration scenarios
- No unused/dead configuration code
- Consistent behavior between dev and production modes
- Developers can configure the SDK without confusion
Related Files
Configuration System:
- RunAnywhere.swift:58-129 - Initialization
- ConfigurationService.swift - Config loading
- ConfigurationData.swift - Config model
- RunAnywhereConstants.swift - JSON loading
Sample App Usage:
- RunAnywhereAIApp.swift:66-139 - How it's actually used
🔵 P1 - Critical for developer experience and SDK adoption