opencode-openai-codex-auth

repository·main·Indexed 24 days ago

https://github.com/numman-ali/opencode-openai-codex-auth

An OAuth authentication plugin for opencode that enables access to OpenAI Codex and GPT-5.x models using ChatGPT Plus/Pro subscriptions instead of API credits. It supports various reasoning variants (low, medium, high, xhigh) across model families like gpt-5.2 and gpt-5.1-codex. The plugin provides different configuration paths for OpenCode v1.0.210+ (modern variants system) and v1.0.209 and older (legacy standalone model entries).

Tokens
24.9K
Snippets
48
Records
114
Agent score
77%

What's inside opencode-openai-codex-auth

  1. Locate project documentation and configuration examples

    main

    The documentation for opencode-openai-codex-auth is organized into several key areas depending on your needs:

    For Users (Quick Start & Usage)

    • README.md (Root): The primary entry point. Use this for installation steps, basic configuration, quick examples, and troubleshooting.
    • config/ directory: Contains practical configuration examples:
      • opencode-legacy.json: Full configuration example for versions v1.0.209 and below.
      • opencode-modern.json: Variant configuration example for versions v1.0.210 and above.
      • minimal-opencode.json: A minimal configuration example.
    • CHANGELOG.md: Review this for version history and feature updates.

    For Developers (Technical Deep Dives)

    • docs/development/: Contains technical documentation including:
      • ARCHITECTURE.md: Technical design decisions, request transformation pipelines, and AI SDK compatibility layers.
      • CONFIG_FLOW.md: Internals of the configuration system.
      • CONFIG_FIELDS.md: Reference for configuration fields.
      • TESTING.md: Test procedures and methodology.
  2. Understand the OpenCode configuration loading order

    main

    OpenCode merges configuration from multiple sources. When multiple sources define the same setting, the last source in the list wins. The loading order is:

    1. Global Config: Located at ~/.config/opencode/opencode.jsonc or ~/.config/opencode/opencode.json.
    2. Project Configs: Traversed upward from the current working directory (cwd) to the worktree root. Looks for .opencode/opencode.jsonc or .opencode/opencode.json in the current or parent directories.
    3. Custom Config (via flags): Provided via environment variables during execution:
      • OPENCODE_CONFIG=/path/to/config.json opencode
      • OPENCODE_CONFIG_CONTENT='{"model":"openai/gpt-5"}' opencode
    4. Auth Configs: Fetched from .well-known/opencode endpoints for OAuth providers (e.g., https://auth.example.com/.well-known/opencode).
    OPENCODE_CONFIG=/path/to/config.json opencode
    # or
    OPENCODE_CONFIG_CONTENT='{"model":"openai/gpt-5"}' opencode
  3. Apply Global vs Per-Model Configuration Patterns

    main

    You can apply settings at different levels of granularity:

    Pattern 1: Global Options

    Apply settings to all models by placing them in the provider.openai.options block. Use this for consistent behavior across your environment.

    Pattern 2: Per-Model Options

    Define specific settings within the provider.openai.models.<model-id>.options block.

    Precedence: Model-specific options always override global options.

    {
      "plugin": ["opencode-openai-codex-auth"],
      "provider": {
        "openai": {
          "options": {
            "reasoningEffort": "medium",
            "store": false
          },
          "models": {
            "gpt-5-codex-fast": {
              "name": "Fast Codex",
              "options": {
                "reasoningEffort": "low",
                "store": false
              }
            }
          }
        }
      }
    }
  4. Understand local data storage locations

    main

    The plugin stores the following data locally on your machine:

    Data TypeLocationContents
    OAuth Tokens~/.opencode/auth/openai.jsonAccess tokens, refresh tokens, expiration timestamps
    Cache Files~/.opencode/cache/codex-instructions.txt (system instructions) and codex-instructions-meta.json (metadata)
    Debug Logs~/.opencode/logs/codex-plugin/Request/response logs (only if ENABLE_PLUGIN_REQUEST_LOGGING=1 is set)
  5. Configure model variants using unique Config Keys

    main

    To create multiple variants of the same base model (e.g., different reasoning efforts for the same GPT model), you must use unique Config Keys for each variant. The Config Key is the actual identifier used by the CLI, TUI, and the plugin for lookups. The id field is merely metadata and should not be used as the unique identifier.

    Key distinction:

    • Config Key: The property name in the JSON object. Used for selection, persistence, and plugin configuration lookups.
    • id field: Metadata used for documentation and model sorting. It is NOT used for plugin lookups or sent to the AI SDK.
    • name field: UI sugar used to display a friendly name in the TUI.
    {
      "gpt-5-codex-low": {
        "id": "gpt-5-codex",
        "name": "GPT 5 Codex Low (OAuth)",
        "options": { "reasoningEffort": "low" }
      },
      "gpt-5-codex-high": {
        "id": "gpt-5-codex",
        "name": "GPT 5 Codex High (OAuth)",
        "options": { "reasoningEffort": "high" }
      }
    }
  6. Use global options for default models

    main

    If you do not define a specific model in your configuration, or if the selected model does not have a custom entry in the models object, the plugin falls back to the global options defined under the provider.

    For example, if you select openai/gpt-5-codex and it is not explicitly defined in your models config, it will use the settings provided in provider.openai.options.

    {
      "plugin": ["opencode-openai-codex-auth"],
      "provider": {
        "openai": {
          "options": {
            "reasoningEffort": "medium"
          }
        }
      }
    }
  7. How the Codex-OpenCode Bridge works

    main

    The codex-opencode-bridge (located in lib/prompts/codex-opencode-bridge.ts) is a specialized prompt transformation layer. It replaces standard OpenCode system prompts with Codex-specific instructions.

    Benefits include:

    • Tool Mapping: Explains differences in tool names (e.g., mapping apply_patch to edit).
    • Efficiency: Achieves approximately a 90% reduction in prompt tokens compared to full OpenCode prompts, leading to faster inference and lower costs.
    • Behavioral Alignment: Maintains the OpenCode working style while preserving Codex best practices.
  8. How the OpenCode OpenAI Codex Auth Plugin works

    main

    The OpenCode OpenAI Codex Auth Plugin is designed to bridge AI SDK constructs with the Codex API. It employs several key architectural strategies to ensure compatibility and performance:

    • AI SDK Compatibility: The plugin filters item_reference (an AI SDK construct) to ensure compatibility with the Codex API.
    • Stateless Operation: For ChatGPT backends, the plugin operates in a stateless mode by setting store: false.
    • Full Context Preservation: To maintain LLM context, the plugin sends the complete message history, though it strips IDs before transmission.
    • Rate Limit Protection: It implements a 15-minute caching mechanism to prevent exhausting GitHub API rate limits.
    • Per-Model Configuration: The system supports per-model configuration, allowing users to switch between different quality presets easily.
  9. Understand the Provider Options merging flow

    main

    Before options reach a plugin, they are merged through several stages. The User Config has the highest priority and overrides all previous stages.

    1. Stage 1: Database Defaults: Baseline capabilities provided by Models.dev.
    2. Stage 2: Environment Variables: e.g., export OPENAI_API_KEY="sk-...".
    3. Stage 3: Custom Loaders: Options injected via a plugin's loader() function.
    4. Stage 4: User Config (HIGHEST PRIORITY): Settings defined in your OpenCode configuration file under the provider key.
  10. Maintain context using reasoning.encrypted_content

    main

    Since the plugin uses store:false, it cannot rely on the server to remember the model's internal reasoning process. To solve this, the plugin uses reasoning.encrypted_content to pass reasoning context back and forth between the client and server.

    The Flow:

    1. Turn 1: The client sends a request. The server returns a response containing encrypted_content (the model's reasoning).
    2. Client Side: The client stores this encrypted content locally.
    3. Turn 2: The client sends the next request, including the previously received encrypted_content in the include array.
    4. Server Side: The server decrypts the content to restore the model's reasoning context before generating the next response.
    body.include = modelConfig.include || ["reasoning.encrypted_content"];