# How ProviderSettingsManager Handles Multiple API Configuration Profiles in Roo Code

> Learn how the ProviderSettingsManager in Roo Code manages unlimited named API configuration profiles, enabling seamless switching between providers, models, and credentials with mode-specific bindings and cloud sync.

- Repository: [Roo Code/Roo-Code](https://github.com/RooCodeInc/Roo-Code)
- Tags: internals
- Published: 2026-04-26

---

**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`](https://github.com/RooCodeInc/Roo-Code/blob/main/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`](https://github.com/RooCodeInc/Roo-Code/blob/main/src/core/config/ProviderSettingsManager.ts#L77-L78)). 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`](https://github.com/RooCodeInc/Roo-Code/blob/main/src/core/config/ProviderSettingsManager.ts#L65-L76) 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`](https://github.com/RooCodeInc/Roo-Code/blob/main/src/core/config/ProviderSettingsManager.ts#L22-L34) 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:

```typescript
// 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:

```typescript
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`](https://github.com/RooCodeInc/Roo-Code/blob/main/src/shared/modes.ts). The [`defaultModeApiConfigs`](https://github.com/RooCodeInc/Roo-Code/blob/main/src/core/config/ProviderSettingsManager.ts#L61-L64) 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:

```typescript
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`](https://github.com/RooCodeInc/Roo-Code/blob/main/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`](https://github.com/RooCodeInc/Roo-Code/blob/main/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`](https://github.com/RooCodeInc/Roo-Code/blob/main/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.