Configuration Precedence Rules for Models and Environment Variables in the Summarize CLI

The Summarize CLI resolves model selection and environment settings through a strict four-tier hierarchy where command-line flags override environment variables, which in turn override config file values, with automatic fallback to "auto" mode when nothing is specified.

The steipete/summarize repository implements a deterministic configuration system that governs how the CLI selects AI models and resolves API credentials. Understanding these configuration precedence rules ensures predictable behavior when deploying the tool across different environments, from local development to CI/CD pipelines.

Model Selection Precedence Hierarchy

The core resolution logic lives in src/run/run-models.ts within the resolveModelSelection function (lines 45‑73). This implementation enforces a strict evaluation order:

1. Command-Line Flag (--model)

The highest priority belongs to the --model <model> argument parsed from the command line in src/run/runner.ts via the parseModel() function. When present, this value overrides every other configuration source.

summarize https://example.com --model openai/gpt-5-mini

In this case, resolveModelSelection uses the explicitModelArg parameter and immediately returns the specified model, ignoring both environment variables and config file entries.

2. SUMMARIZE_MODEL Environment Variable

When no CLI flag is present, the system checks the SUMMARIZE_MODEL environment variable (lines 45‑50 in src/run/run-models.ts). This serves as the secondary override mechanism for containerized environments and deployment scripts.

export SUMMARIZE_MODEL=openai/gpt-5-mini
summarize https://example.com

The resolveModelSelection function detects the presence of this variable and uses its value before falling back to file-based configuration.

3. Config File Model Entry

If neither the flag nor the environment variable is set, the CLI examines the configuration file located at ~/.summarize/config.json (or the path specified by --config). The loadSummarizeConfig function loads this file, and resolveModelSelection evaluates the model entry (lines 52‑66).

The config file supports three specification formats:

  • ID format: {"model": {"id": "openai/gpt-5.2"}}
  • Name format: {"model": {"name": "my-preset"}}
  • Auto mode: {"model": {"mode": "auto"}}
{
  "model": { "id": "openai/gpt-5-mini" }
}

4. Default Auto Mode

When no configuration source provides a model value, the system defaults to "auto" (line 66 in src/run/run-models.ts). This triggers the automatic selection logic that chooses the cheapest available provider capable of handling the request.

Environment Variable Precedence for API Keys and Settings

Beyond model selection, the CLI manages API credentials and provider-specific settings through src/run/run-env.ts and the resolveEnvState function (lines 46‑62). This system follows a two-tier hierarchy:

  1. Explicit environment variables (envForRun.<NAME>) always take precedence
  2. Config file values (configForCli?.<provider>?.<key>) serve as fallback

The implementation checks each variable individually using helper functions like resolveConfiguredBaseUrl:

const openaiBaseUrl = resolveConfiguredBaseUrl({
  envValue: envForRun.OPENAI_BASE_URL,
  configValue: configForCli?.openai?.baseUrl,
});

This pattern applies to all sensitive credentials including OPENAI_API_KEY, ANTHROPIC_API_KEY, and GOOGLE_API_KEY. Because envForRun merges with the bootstrap configuration in src/run/runner.ts via mergeConfigEnv, environment variables maintain the final authority even when duplicate entries exist in the user configuration file.

Practical Configuration Examples

Overriding with CLI Flags


# Ignores SUMMARIZE_MODEL and config file settings

summarize https://example.com --model anthropic/claude-3-opus

Using Environment Variables

export SUMMARIZE_MODEL=openai/gpt-5-mini
export OPENAI_API_KEY=sk-env-key

# Uses environment values despite config file contents

summarize https://example.com

Configuring via File

~/.summarize/config.json:

{
  "model": {
    "name": "fast-gpt"
  },
  "models": {
    "fast-gpt": {
      "mode": "auto",
      "rules": [
        { "candidates": ["openai/gpt-5-mini"] }
      ]
    }
  },
  "openai": {
    "apiKey": "config-key-123"
  }
}

# Resolves "fast-gpt" preset and uses config API key

summarize https://example.com

Environment Override of Config Credentials

Even with the config file above:

export OPENAI_API_KEY=env-override-456
summarize https://example.com

The resolveEnvState function selects env-override-456 over config-key-123.

Summary

  • Command-line flags (--model) hold the highest precedence for model selection, overriding all other sources.
  • Environment variables (SUMMARIZE_MODEL, OPENAI_API_KEY, etc.) serve as the secondary tier, overriding config file values but yielding to CLI arguments.
  • Configuration files (~/.summarize/config.json) provide the third tier for both model presets and provider credentials.
  • Default "auto" mode activates when no explicit model is configured anywhere in the hierarchy.
  • The resolution logic is implemented in src/run/run-models.ts (model selection) and src/run/run-env.ts (environment/credential resolution).

Frequently Asked Questions

What is the exact order of precedence for model selection in the Summarize CLI?

The CLI evaluates model selection in this strict order: first the --model command-line flag, then the SUMMARIZE_MODEL environment variable, then the model entry in the configuration file, and finally the default "auto" mode if nothing else is specified. This hierarchy is enforced by the resolveModelSelection function in src/run/run-models.ts.

Can environment variables override settings in the config file?

Yes, environment variables always override their corresponding config file entries. The resolveEnvState function in src/run/run-env.ts explicitly checks environment variables first (via envForRun) before falling back to config values. For example, setting OPENAI_API_KEY in your shell will override any openai.apiKey value in ~/.summarize/config.json.

How do named model presets work within the configuration hierarchy?

Named presets allow you to define reusable model configurations under the models key in your config file. When you specify "model": "fast-gpt" (either via CLI, env var, or config), the system looks up this name in a case-insensitive map that combines built-in presets (BUILTIN_MODELS) and your custom definitions. The preset resolution happens in src/run/run-models.ts before the final model selection is returned.

What happens if I don't specify a model anywhere in the configuration?

If no model is provided via the --model flag, SUMMARIZE_MODEL environment variable, or config file entry, the CLI defaults to "auto" mode. This triggers automatic provider selection logic that chooses the cheapest available model capable of handling your request. This fallback is hardcoded in resolveModelSelection at line 66 of src/run/run-models.ts.

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 →