# ProviderEnvironmentResolver in CodexBar: Environment Variable Resolution for LLM Providers

> Discover the ProviderEnvironmentResolver in CodexBar. This Swift utility efficiently merges system environment, provider settings, and account tokens for LLM provider requests.

- Repository: [Peter Steinberger/CodexBar](https://github.com/steipete/CodexBar)
- Tags: internals
- Published: 2026-07-07

---

**The ProviderEnvironmentResolver is a Swift utility in CodexBar that merges the system environment, provider-specific settings, and active account tokens into a sanitized environment variable map for LLM provider requests.**

CodexBar is an open-source macOS menu bar application for managing LLM provider tokens and configurations. At its core, the **ProviderEnvironmentResolver** orchestrates how environment variables are constructed before launching provider requests, ensuring that sensitive tokens and provider-specific settings are correctly injected while stale values are removed.

## Architecture of ProviderEnvironmentResolver

The **ProviderEnvironmentResolver** is a central component in the `CodexBarCore` module that constructs the final environment variable set used when CodexBar launches LLM provider processes. Located in [`Sources/CodexBarCore/Providers/ProviderEnvironmentResolver.swift`](https://github.com/steipete/CodexBar/blob/main/Sources/CodexBarCore/Providers/ProviderEnvironmentResolver.swift), this resolver harmonizes three distinct configuration sources into a coherent dictionary that downstream code can use without ambiguity.

### The Three Configuration Sources

The resolver combines these inputs in a specific priority order:

1. **Base environment** – The current process environment (e.g., variables exported in the shell).
2. **Provider-specific configuration** – Settings saved in the CodexBar UI, handled by `ProviderConfigEnvironment.applyProviderConfigOverrides` in [`Sources/CodexBarCore/Config/ProviderConfigEnvironment.swift`](https://github.com/steipete/CodexBar/blob/main/Sources/CodexBarCore/Config/ProviderConfigEnvironment.swift).
3. **Selected account token** – The active token from the "Accounts" UI that triggers scrubbing and override logic.

## How ProviderEnvironmentResolver Works

The resolution process follows a deterministic merge strategy implemented in `ProviderEnvironmentResolver.resolve(base:provider:config:selectedAccount:)`. The algorithm processes each layer sequentially to ensure the final environment contains exactly the variables the selected provider expects.

### Step-by-Step Resolution

The resolver executes this logic chain:

1. Apply `ProviderConfigEnvironment.applyProviderConfigOverrides` to merge saved provider settings with the base environment.
2. If a selected account exists, call `TokenAccountSupportCatalog.scrubEnvironmentForSelectedAccount` to remove variables belonging to other accounts.
3. Merge token-specific overrides using `TokenAccountSupportCatalog.envOverride`, keeping the token-specific value when conflicts occur.
4. Apply provider-specific account overrides via `applyProviderSpecificAccountOverrides` for special cases like Z-AI team scopes.

### Token Scrubbing and Override Logic

When a user selects a specific account, the resolver removes conflicting variables (such as old `OPENAI_API_KEY` values) to prevent cross-contamination between different provider accounts. After scrubbing, token-specific custom variables are merged, with the resolver ensuring that the selected token's values take precedence over inherited system variables.

## Provider-Specific Handling: The Z-AI Example

Certain providers require specialized treatment beyond the standard merge logic. The **Z-AI** provider (`.zai`) implements unique logic in `applyProviderSpecificAccountOverrides` within [`Sources/CodexBarCore/Providers/ProviderEnvironmentResolver.swift`](https://github.com/steipete/CodexBar/blob/main/Sources/CodexBarCore/Providers/ProviderEnvironmentResolver.swift) (lines 38-63):

- **Personal accounts** must not inherit stray `BIG_MODEL_ORG` or `BIG_MODEL_PROJECT` values.
- **Team accounts** have these keys injected automatically based on the token's `organizationID` and `workspaceID`.

This ensures Z-AI team scopes receive the correct organizational context while preventing personal accounts from accidentally using organizational resources.

## Integration Points in CodexBar

The resolver is invoked wherever CodexBar needs a ready-to-use environment map for provider communication.

### CLI Command Execution

The `TokenAccountCLI` class in [`Sources/CodexBarCLI/TokenAccountCLI.swift`](https://github.com/steipete/CodexBar/blob/main/Sources/CodexBarCLI/TokenAccountCLI.swift) (line 310) invokes the resolver to prepare the environment before launching provider subprocesses. This ensures CLI commands run with the exact variables the selected provider expects.

### Provider Registry Integration

[`ProviderRegistry.swift`](https://github.com/steipete/CodexBar/blob/main/ProviderRegistry.swift) in the main app target ([`Sources/CodexBar/ProviderRegistry.swift`](https://github.com/steipete/CodexBar/blob/main/Sources/CodexBar/ProviderRegistry.swift), line 141) calls the resolver when building requests for the selected provider, bridging the UI selection with the underlying execution environment.

## Code Examples

### Basic Resolution with Selected Account

```swift
import CodexBarCore

let baseEnv = ProcessInfo.processInfo.environment
let provider: UsageProvider = .zai
let config: ProviderConfig? = loadProviderConfig()
let selectedAccount: ProviderTokenAccount? = getSelectedAccount()

let env = ProviderEnvironmentResolver.resolve(
    base: baseEnv,
    provider: provider,
    config: config,
    selectedAccount: selectedAccount
)

// env now contains sanitized variables for the Z-AI provider

```

### CLI Integration Pattern

```swift
// Inside TokenAccountCLI.run()
var environment = ProviderEnvironmentResolver.resolve(
    base: ProcessInfo.processInfo.environment,
    provider: chosenProvider,
    config: providerConfig,
    selectedAccount: chosenAccount
)

// Launch provider process with resolved environment
runProviderProcess(environment: environment)

```

### Unit Testing Z-AI Team Scopes

```swift
func testZaiTeamScopeInjectsOrgAndProject() {
    let base = ["FOO": "bar"]
    let token = ProviderTokenAccount(
        token: "zai-token",
        sanitizedOrganizationID: "org-123",
        sanitizedWorkspaceID: "proj-456",
        sanitizedUsageScope: "team"
    )
    
    let env = ProviderEnvironmentResolver.resolve(
        base: base,
        provider: .zai,
        config: nil,
        selectedAccount: token
    )
    
    XCTAssertEqual(env[ZaiSettingsReader.bigModelOrganizationKey], "org-123")
    XCTAssertEqual(env[ZaiSettingsReader.bigModelProjectKey], "proj-456")
}

```

## Summary

- The **ProviderEnvironmentResolver** in [`Sources/CodexBarCore/Providers/ProviderEnvironmentResolver.swift`](https://github.com/steipete/CodexBar/blob/main/Sources/CodexBarCore/Providers/ProviderEnvironmentResolver.swift) merges system, configuration, and token environments into a single map.
- It uses **three-tier resolution**: base environment, `ProviderConfigEnvironment.applyProviderConfigOverrides`, and selected account token processing.
- **Token scrubbing** via `TokenAccountSupportCatalog` removes stale values before applying new overrides.
- **Provider-specific logic** handles edge cases like Z-AI team scopes requiring `BIG_MODEL_ORG` and `BIG_MODEL_PROJECT` injection.
- The resolver is invoked by both the **CLI** ([`TokenAccountCLI.swift`](https://github.com/steipete/CodexBar/blob/main/TokenAccountCLI.swift)) and the **app registry** ([`ProviderRegistry.swift`](https://github.com/steipete/CodexBar/blob/main/ProviderRegistry.swift)) to ensure consistent environment preparation.

## Frequently Asked Questions

### What does ProviderEnvironmentResolver do in CodexBar?

The ProviderEnvironmentResolver constructs the complete set of environment variables used when launching LLM provider requests. It combines the system environment with saved provider configurations and active account tokens, ensuring sensitive credentials are correctly injected while removing conflicting values from previous sessions.

### How does ProviderEnvironmentResolver handle multiple accounts?

When a specific account is selected, the resolver calls `TokenAccountSupportCatalog.scrubEnvironmentForSelectedAccount` to remove environment variables belonging to other accounts. It then applies token-specific overrides from the catalog, ensuring only the active token's credentials and settings are present in the final environment.

### Where is ProviderEnvironmentResolver called in the CodexBar codebase?

The resolver is invoked in two primary locations: [`Sources/CodexBarCLI/TokenAccountCLI.swift`](https://github.com/steipete/CodexBar/blob/main/Sources/CodexBarCLI/TokenAccountCLI.swift) (line 310) for command-line provider execution, and [`Sources/CodexBar/ProviderRegistry.swift`](https://github.com/steipete/CodexBar/blob/main/Sources/CodexBar/ProviderRegistry.swift) (line 141) for the main application when building provider requests. Both locations ensure the environment is properly configured before any LLM API calls occur.

### Why does the Z-AI provider require special handling in ProviderEnvironmentResolver?

The Z-AI provider requires special handling because team accounts need automatic injection of `BIG_MODEL_ORG` and `BIG_MODEL_PROJECT` variables based on the token's `organizationID` and `workspaceID`, while personal accounts must explicitly not inherit these values. This logic is implemented in `applyProviderSpecificAccountOverrides` within [`ProviderEnvironmentResolver.swift`](https://github.com/steipete/CodexBar/blob/main/ProviderEnvironmentResolver.swift).