How the Codex Plugin Selects Which Model to Use: A Complete Guide

The Codex plugin determines which LLM model to use by parsing a user-provided --model flag, normalizing known aliases like "spark" to canonical names, and falling back to the Codex service's default (gpt-5.4) when no model is specified.

The OpenAI Codex plugin for the CC ecosystem provides a flexible mechanism for model selection that balances user control with sensible defaults. Rather than hard-coding a specific model, the plugin implements a resolution pipeline that processes command-line arguments, resolves aliases, and propagates the final value to the underlying Codex service. Understanding how the Codex plugin selects which model to use helps developers optimize performance and cost for different coding tasks.

Command-Line Model Selection

The primary entry point for model selection is the --model flag available across all runner commands. In plugins/codex/scripts/codex-companion.mjs, the CLI accepts this flag for commands including task, review, and adversarial-review.

The argument parser parseArgs (imported from plugins/codex/scripts/lib/args.mjs) extracts the raw model string from the command line.

node scripts/codex-companion.mjs task --model spark "Write a function that flattens a nested array"

Alias Normalization and Resolution

Once parsed, the raw model string undergoes normalization in plugins/codex/scripts/codex-companion.mjs (lines 72-112). The normalizeRequestedModel function checks the value against a predefined alias map:

const MODEL_ALIASES = new Map([["spark", "gpt-5.3-codex-spark"]]);

If the supplied string matches an alias, the function returns the canonical model name. If no alias exists, it returns the original string unchanged. When the --model flag is omitted entirely, the function returns null.

This design allows users to use convenient shorthand while maintaining flexibility to specify full model names directly.

Default Model Behavior

When normalizeRequestedModel returns null (indicating no model was specified), the system delegates to Codex's internal defaults. The helper functions runAppServerTurn and runAppServerReview in plugins/codex/scripts/lib/codex.mjs handle this case by allowing the Codex service to apply its default model, currently gpt-5.4.

This behavior is documented in the README and validated by the test suite in tests/commands.test.mjs.

node scripts/codex-companion.mjs task "Generate unit tests for the existing module"

Model Propagation to the Runtime

After resolution, the normalized model value is attached to the request object as request.model. This value is forwarded through the runAppServerTurn or runAppServerReview helpers and ultimately transmitted to the Codex runtime via the model field of the turn or review payload.

Programmatic usage allows direct specification:

import { runAppServerTurn } from "./plugins/codex/scripts/lib/codex.mjs";

const result = await runAppServerTurn(cwd, {
  prompt: "Explain the Visitor pattern",
  model: "gpt-5.3-codex-spark",   // explicit model
  sandbox: "read-only",
});

Validation and Testing

The model selection logic is validated in tests/runtime.test.mjs (lines 766-784). These tests verify that:

  • The "spark" alias correctly resolves to gpt-5.3-codex-spark
  • The model selection is correctly transmitted through the app-server turn
  • Missing model flags result in the expected default behavior

Summary

  • The Codex plugin uses a command-line flag (--model) to accept user model preferences across all commands.
  • Alias normalization in codex-companion.mjs converts shorthand names like "spark" to canonical model identifiers (gpt-5.3-codex-spark).
  • When no model is specified, the system defaults to gpt-5.4 via the Codex service's internal selection.
  • The normalized model value propagates through request.model to the runtime payload.
  • All behavior is validated by the test suite in tests/runtime.test.mjs.

Frequently Asked Questions

What happens if I don't specify a model when running a Codex task?

If you omit the --model flag, the normalizeRequestedModel function returns null, and the runAppServerTurn helper in plugins/codex/scripts/lib/codex.mjs allows the Codex service to apply its default model, which is currently gpt-5.4.

Can I use custom model names or only predefined aliases?

You can specify any valid model name supported by the Codex service. The alias system only provides shortcuts for convenience; if you provide a full model identifier that isn't in the MODEL_ALIASES map, it passes through unchanged to the runtime.

How do I use the "spark" model alias in the Codex plugin?

Pass --model spark to any supported command. The normalizeRequestedModel function in codex-companion.mjs automatically expands this to gpt-5.3-codex-spark before sending the request to the underlying service.

Where is the model selection logic tested?

The test suite in tests/runtime.test.mjs (lines 766-784) validates the entire model selection pipeline, ensuring aliases resolve correctly and that the model parameter reaches the app-server turn as expected.

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 →