# How OpenClaude Handles Legacy Provider Names: 6 Compatibility Layers Explained

> Discover the 6 compatibility layers in OpenClaude that translate legacy provider names into modern IDs. Learn how OpenClaude ensures seamless integration with older systems.

- Repository: [Gitlawb/openclaude](https://github.com/Gitlawb/openclaude)
- Tags: deep-dive
- Published: 2026-09-02

---

**OpenClaude translates legacy provider identifiers like "openai-proxy" into modern internal provider IDs through a centralized compatibility layer involving name normalization, fallback handling, and credential merging.**

Modernizing an AI client without breaking existing integrations is a significant engineering challenge. The OpenClaude project solves this by implementing multiple **compatibility layers for legacy provider names** that intercept outdated identifiers and map them to current internal representations. According to the Gitlawb/OpenClaude source code, this architecture ensures backward compatibility across configuration loading, model discovery, credential handling, and request dispatch.

## Provider Name Normalization

The first line of defense is `normalizeProviderName()` in **[`src/utils/providerProfiles.ts`](https://github.com/Gitlawb/openclaude/blob/main/src/utils/providerProfiles.ts)**. This function performs a hard-coded lookup against a legacy map.

If the supplied name matches a legacy entry, it returns the canonical modern ID. For example, `"openai-proxy"` resolves to `"openai"`, while `"openai"` remains unchanged.

```typescript
// src/utils/providerProfiles.ts
import { normalizeProviderName } from '@/utils/providerProfiles';

const rawName = 'openai-proxy';  // legacy identifier from user input
const providerId = normalizeProviderName(rawName);

console.log(providerId);  // → "openai"

```

This normalization happens early in the provider-initialization pipeline, ensuring all downstream components work with a single canonical name.

## Fallback Handling for Legacy Configs

When a provider is not explicitly defined in user configuration, `fallbackLegacyProvider()` in **[`src/utils/providerFallback.ts`](https://github.com/Gitlawb/openclaude/blob/main/src/utils/providerFallback.ts)** provides a secondary lookup.

This utility pulls the legacy default profile from the old "single-cache" file and transforms it into the modern profile structure. The fallback mechanism ensures that users who haven't migrated to the new configuration format continue to function without interruption.

## Auto-Detect and Discovery Integration

The auto-detect routine in **[`src/utils/providerAutoDetect.ts`](https://github.com/Gitlawb/openclaude/blob/main/src/utils/providerAutoDetect.ts)** extends the compatibility layer to command-line interfaces. Legacy provider names passed via flags like `--provider=openai-legacy` are recognized and resolved correctly before the provider selection process completes.

This integration demonstrates how the **compatibility layers for legacy provider names** span both programmatic APIs and CLI surfaces.

## Credential Merging for Environment Variables

Environment-variable-based authentication patterns require special handling. The `mergeLegacySecrets()` function in **[`src/utils/providerSecrets.ts`](https://github.com/Gitlawb/openclaude/blob/main/src/utils/providerSecrets.ts)** bridges old and new credential systems.

It merges legacy API keys (e.g., `OPENAI_API_KEY`) with the newer OAuth-style credential store, ensuring that existing scripts and deployment pipelines continue to authenticate successfully.

```typescript
// src/utils/providerSecrets.ts - conceptual usage
import { mergeLegacySecrets } from '@/utils/providerSecrets';

const legacySecrets = { OPENAI_API_KEY: process.env.OPENAI_API_KEY };
const modernCredentials = await mergeLegacySecrets(legacySecrets);

```

## Profile Loading with Dual-File Support

The `loadProfileFile()` function in **[`src/utils/providerProfile.ts`](https://github.com/Gitlawb/openclaude/blob/main/src/utils/providerProfile.ts)** implements a sophisticated synchronization strategy. When reading a profile, it:

- Checks for a legacy profile file in the same directory
- Returns both modern and legacy profiles if found
- Keeps the legacy file in sync only when the modern profile is updated

This approach preserves backward compatibility while encouraging migration to the new format.

## API Shim Compatibility

The OpenAI-shim layer in **[`src/services/api/openaiShim/providerCompatibility.ts`](https://github.com/Gitlawb/openclaude/blob/main/src/services/api/openaiShim/providerCompatibility.ts)** handles translation at the request level. Helper functions like `adaptLegacyRequest()` convert legacy request fields—including model aliases—into the current format expected by the shim.

```typescript
// src/services/api/openaiShim/providerCompatibility.ts
import { adaptLegacyRequest } from '@/services/api/openaiShim/providerCompatibility';

const legacyReq = {
  model: 'gpt-3.5-turbo',
  // additional OpenAI-compatible fields...
};

const modernReq = adaptLegacyRequest(legacyReq);
await openaiShim.dispatch(modernReq);

```

This guarantees that older OpenAI-compatible clients work unchanged without modification.

## Architecture Benefits

The layered design provides three critical properties:

- **Single source of truth** — All legacy handling centralizes in specific utility files, eliminating duplicate checks across the codebase
- **Graceful fallback** — Missing modern configurations trigger automatic retrieval of historic single-cache profiles
- **Future-proofing** — New providers add to the normalization map without modifying legacy code paths

## Summary

- **`normalizeProviderName()`** in [`src/utils/providerProfiles.ts`](https://github.com/Gitlawb/openclaude/blob/main/src/utils/providerProfiles.ts) converts legacy identifiers to modern provider IDs
- **`fallbackLegacyProvider()`** in [`src/utils/providerFallback.ts`](https://github.com/Gitlawb/openclaude/blob/main/src/utils/providerFallback.ts) retrieves historic profiles when modern configs are absent
- **[`src/utils/providerAutoDetect.ts`](https://github.com/Gitlawb/openclaude/blob/main/src/utils/providerAutoDetect.ts)** resolves legacy names from CLI flags and environment variables
- **`mergeLegacySecrets()`** in [`src/utils/providerSecrets.ts`](https://github.com/Gitlawb/openclaude/blob/main/src/utils/providerSecrets.ts) bridges environment-based API keys with modern credential storage
- **`loadProfileFile()`** in [`src/utils/providerProfile.ts`](https://github.com/Gitlawb/openclaude/blob/main/src/utils/providerProfile.ts) maintains dual-file profile synchronization
- **OpenAI-shim compatibility helpers** in [`src/services/api/openaiShim/providerCompatibility.ts`](https://github.com/Gitlawb/openclaude/blob/main/src/services/api/openaiShim/providerCompatibility.ts) translate legacy request fields

## Frequently Asked Questions

### How do I migrate from legacy provider names to modern identifiers in OpenClaude?

You don't need to manually migrate. The `normalizeProviderName()` function automatically translates legacy identifiers at runtime. However, you can proactively update your configuration files to use canonical names like `"openai"` instead of deprecated variants like `"openai-proxy"` to eliminate normalization overhead.

### What happens if both legacy and modern profile files exist?

The `loadProfileFile()` function reads both files and prioritizes the modern profile. The legacy file remains as a fallback and is synchronized only when the modern profile updates, ensuring consistent behavior during gradual migration periods.

### Can I still use environment variables like OPENAI_API_KEY with new OpenClaude versions?

Yes. The `mergeLegacySecrets()` utility in [`src/utils/providerSecrets.ts`](https://github.com/Gitlawb/openclaude/blob/main/src/utils/providerSecrets.ts) explicitly handles legacy environment variables, merging them into the modern OAuth-style credential structure. Existing deployment scripts and CI/CD pipelines continue to function without modification.

### Which providers support the legacy compatibility layer?

The compatibility layer applies to all providers with defined legacy mappings in the `normalizeProviderName()` lookup table. The current implementation includes mappings for major providers including OpenAI, Anthropic, and Cohere, with the architecture designed to accommodate additional providers by extending the normalization map alone.