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:

  1. Loading: Retrieves existing profiles from VS Code secrets
  2. Default Creation: Writes defaultProviderProfiles if no configurations exist
  3. Migration: Executes applyModelMigrations to update legacy model identifiers, generates missing IDs via generateId(), and adds required structures like modeApiConfigs

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.ts provides centralized management of unlimited API configuration profiles using VS Code's secret storage under roo_cline_config_api_config.
  • The system auto-generates unique profile IDs via generateId(), validates configurations against providerProfilesSchema, and maintains backward compatibility through applyModelMigrations.
  • Mode-specific bindings via modeApiConfigs allow different tasks (defined in src/shared/modes.ts) to use distinct API providers through setModeConfig and getModeConfigId.
  • Cloud synchronization through syncCloudProfiles merges remote and local profiles while preserving sensitive credentials and handling name conflicts intelligently.
  • The deleteConfig method 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:

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 →