How ProviderSettingsManager Handles Multiple API Configuration Profiles in Roo Code
The ProviderSettingsManager class serves as the central component for storing, retrieving, and manipulating unlimited named API configuration profiles, enabling Roo Code to switch between distinct providers, models, and credentials while supporting mode-specific bindings and cloud synchronization.
Roo Code (RooCodeInc/Roo-Code) is a VS Code extension that enables AI-assisted coding with multiple providers simultaneously. The ProviderSettingsManager, defined in src/core/config/ProviderSettingsManager.ts, provides the infrastructure to manage an arbitrary number of API configuration profiles, each with isolated settings and secure credential storage.
Core Storage Architecture
Secret-Based Persistence with Schema Validation
All API configuration profiles persist in VS Code's encrypted secrets storage under the namespace key roo_cline_config_api_config (defined at ProviderSettingsManager.secretsKey). The manager validates all stored data against the providerProfilesSchema, which defines the structure at lines 40-42.
Profiles are stored within an apiConfigs object of type Record<string, ProviderSettingsWithId>, where each key represents a human-readable profile name and the value contains the complete configuration including provider type, model ID, and API credentials.
Default Profile Generation
On first run, the manager automatically generates a default profile using the generateId() utility to create a unique identifier. This default configuration is injected into defaultProviderProfiles and ensures the extension always maintains at least one valid configuration. The default profile uses the key "default" in the apiConfigs record.
Active Configuration State
The currently active profile name is tracked in the currentApiConfigName field. When you switch between profiles, the activateProfile method updates this state and immediately persists the change to secret storage. This global state determines which API configuration the extension uses for subsequent requests.
Profile Lifecycle Management
Initialization and Migration
The initialize method orchestrates the startup sequence through several phases:
- Loading: Retrieves existing profiles from VS Code secrets
- Default Creation: Writes
defaultProviderProfilesif no configurations exist - Migration: Executes
applyModelMigrationsto update legacy model identifiers, generates missing IDs viagenerateId(), and adds required structures likemodeApiConfigs
The initialization also runs sanitizeProviderConfig to validate provider names and remove unknown configurations, ensuring data integrity across extension updates.
Creating and Updating Configurations
The saveConfig method handles both creation and modification of profiles. When creating a new profile, it automatically generates a unique ID if the id field is undefined:
// Create a new profile with auto-generated ID
const profileId = await manager.saveConfig('production-openai', {
id: undefined, // Will be generated by generateId()
apiProvider: 'openai',
apiModelId: 'gpt-4o-2024-08-06',
apiKey: process.env.OPENAI_API_KEY
});
For existing profiles, the method preserves the existing identifier while validating the payload against Zod schemas—strict validation for active providers and passthrough for retired ones.
Retrieval and Activation
Use listConfig to retrieve all stored profiles as an array of metadata objects containing name, id, apiProvider, and modelId. Activate a specific profile using:
await manager.activateProfile({ name: 'production-openai' });
The getProfile method supports dual lookup strategies—by name for direct access or by ID for mode-specific resolution.
Mode-Specific Configuration Binding
Roo Code defines distinct modes such as chat and edit in src/shared/modes.ts. The defaultModeApiConfigs mapping allows each mode to reference a specific profile ID via modeApiConfigs.
Use setModeConfig(mode, configId) to bind a mode to a profile, and getModeConfigId(mode) to retrieve the active configuration for that specific mode. This enables using different providers for different tasks—for example, Anthropic for code editing and OpenAI for general chat.
Cloud Synchronization
The syncCloudProfiles method merges profiles received from cloud services with local configurations. It handles name conflicts by preserving local data, maintains secret keys during the merge, deletes stale cloud-managed profiles, and updates the cloudProfileIds registry to track which profiles originate from remote sources.
Practical Implementation Example
The following workflow demonstrates the complete lifecycle of managing multiple API configuration profiles:
import { ProviderSettingsManager } from './src/core/config/ProviderSettingsManager';
// Initialize with VS Code extension context
const manager = new ProviderSettingsManager(context);
// 1. List existing profiles
const profiles = await manager.listConfig();
// Output: [{ name: 'default', id: 'abc123', apiProvider: 'anthropic', modelId: 'claude-3-opus-20240229' }, ...]
// 2. Create a new OpenAI profile
const openAiId = await manager.saveConfig('my-openai', {
id: undefined, // Auto-generated via generateId()
apiProvider: 'openai',
apiModelId: 'gpt-4-turbo',
apiKey: 'sk-...'
});
// 3. Activate the new profile globally
await manager.activateProfile({ name: 'my-openai' });
// 4. Configure chat mode to use a specific profile
await manager.setModeConfig('chat', openAiId);
// 5. Retrieve the configuration for the current mode
const chatConfigId = await manager.getModeConfigId('chat');
const chatProfile = await manager.getProfile({ id: chatConfigId });
// Returns: ProviderSettingsWithId object for the chat mode configuration
Summary
- ProviderSettingsManager in
src/core/config/ProviderSettingsManager.tsprovides centralized management of unlimited API configuration profiles using VS Code's secret storage underroo_cline_config_api_config. - The system auto-generates unique profile IDs via
generateId(), validates configurations againstproviderProfilesSchema, and maintains backward compatibility throughapplyModelMigrations. - Mode-specific bindings via
modeApiConfigsallow different tasks (defined insrc/shared/modes.ts) to use distinct API providers throughsetModeConfigandgetModeConfigId. - Cloud synchronization through
syncCloudProfilesmerges remote and local profiles while preserving sensitive credentials and handling name conflicts intelligently. - The
deleteConfigmethod enforces data integrity by preventing deletion of the final remaining configuration.
Frequently Asked Questions
How does ProviderSettingsManager secure API credentials when handling multiple profiles?
The manager stores all profile data, including sensitive API keys, in VS Code's encrypted secret storage under the key roo_cline_config_api_config. When synchronizing cloud profiles via syncCloudProfiles, the implementation specifically preserves local secret keys rather than overwriting them with remote values, ensuring credentials remain secure and local to your machine.
What happens to my existing profiles when I upgrade Roo Code?
During initialization, the initialize method automatically runs migration routines including applyModelMigrations and ID correction logic. These updates fix missing identifiers using generateId(), migrate deprecated model fields to current formats, and add new required structures like modeApiConfigs without user intervention, ensuring your profiles remain functional across extension updates.
Can I use different API providers for different modes in Roo Code?
Yes. The modeApiConfigs mapping allows binding specific modes (such as chat or edit defined in src/shared/modes.ts) to different profile IDs. Using setModeConfig(mode, profileId), you can configure the editor to use OpenAI for chat interactions while using Anthropic for code edits, with the manager automatically resolving the correct profile via getModeConfigId when you switch between modes.
How does the extension prevent accidental deletion of all API configurations?
The deleteConfig method includes a safeguard that guarantees at least one configuration remains stored at all times. If you attempt to delete the final profile, the method throws an error to prevent configuration lockout, ensuring the extension always maintains a valid API connection and preventing service interruption.
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 →