docs: Enforce GPT 5.1 full-opencode.json as only supported configuration

This PR standardizes all documentation and configuration on GPT 5.1 model identifiers, removes deprecated GPT 5.0 models, and enforces full-opencode.json as the only officially supported configuration. The changes address GPT 5 model temperamental behavior and ensure users have the proper setup for reliable operation with OpenCode.

Co-authored-by: Hanzo Dev <[email protected]>
This commit is contained in:
Numman Ali
2025-11-16 21:52:44 +00:00
co-authored by Hanzo Dev
parent d791c8998f
commit 0a9834c6fc
16 changed files with 561 additions and 368 deletions
+5 -2
View File
@@ -4,7 +4,7 @@ This file provides coding guidance for AI agents (including Claude Code, Codex,
## Overview
This is an **opencode plugin** that enables OAuth authentication with OpenAI's ChatGPT Plus/Pro Codex backend. It allows users to access `gpt-5-codex`, `gpt-5-codex-mini`, and `gpt-5` models through their ChatGPT subscription instead of using OpenAI Platform API credits.
This is an **opencode plugin** that enables OAuth authentication with OpenAI's ChatGPT Plus/Pro Codex backend. It allows users to access `gpt-5.1-codex`, `gpt-5.1-codex-mini`, `gpt-5-codex`, `gpt-5-codex-mini`, `gpt-5.1`, and `gpt-5` models through their ChatGPT subscription instead of using OpenAI Platform API credits.
**Key architecture principle**: 7-step fetch flow that intercepts opencode's OpenAI SDK requests, transforms them for the ChatGPT backend API, and handles OAuth token management.
@@ -41,7 +41,7 @@ The main entry point orchestrates a **7-step fetch flow**:
1. **Token Management**: Check token expiration, refresh if needed
2. **URL Rewriting**: Transform OpenAI Platform API URLs → ChatGPT backend API (`https://chatgpt.com/backend-api/codex/responses`)
3. **Request Transformation**:
- Normalize model names (all variants → `gpt-5`, `gpt-5-codex`, or `codex-mini-latest`)
- Normalize model names (all variants → `gpt-5.1`, `gpt-5.1-codex`, `gpt-5.1-codex-mini`, `gpt-5`, `gpt-5-codex`, or `codex-mini-latest`)
- Inject Codex system instructions from latest GitHub release
- Apply reasoning configuration (effort, summary, verbosity)
- Add CODEX_MODE bridge prompt (default) or tool remap message (legacy)
@@ -98,8 +98,11 @@ The main entry point orchestrates a **7-step fetch flow**:
- Plugin defaults: `reasoningEffort: "medium"`, `reasoningSummary: "auto"`, `textVerbosity: "medium"`
**4. Model Normalization**:
- All `gpt-5.1-codex*` variants → `gpt-5.1-codex`
- All `gpt-5.1-codex-mini*` variants → `gpt-5.1-codex-mini`
- All `gpt-5-codex` variants → `gpt-5-codex`
- All `gpt-5-codex-mini*` or `codex-mini-latest` variants → `codex-mini-latest`
- All `gpt-5.1` variants → `gpt-5.1`
- All `gpt-5` variants → `gpt-5`
- `minimal` effort auto-normalized to `low` for gpt-5-codex (API limitation) and clamped to `medium` (or `high` when requested) for Codex Mini
+9
View File
@@ -2,6 +2,15 @@
All notable changes to this project are documented here. Dates use the ISO format (YYYY-MM-DD).
## [3.2.0] - 2025-11-14
### Added
- GPT 5.1 model family support: normalization for `gpt-5.1`, `gpt-5.1-codex`, and `gpt-5.1-codex-mini` plus new GPT 5.1-only presets in the canonical `config/full-opencode.json`.
- Documentation updates (README, docs, AGENTS) describing the 5.1 families, their reasoning defaults, and how they map to ChatGPT slugs and token limits.
### Changed
- Model normalization docs and tests now explicitly cover both 5.0 and 5.1 Codex/general families and the two Codex Mini tiers.
- The legacy GPT 5.0 full configuration is now published as `config/full-opencode-gpt5.json`; new installs should prefer the 5.1 presets.
## [3.1.0] - 2025-11-11
### Added
- Codex Mini support end-to-end: normalization to the `codex-mini-latest` slug, proper reasoning defaults, and two new presets (`gpt-5-codex-mini-medium` / `gpt-5-codex-mini-high`).
+75 -110
View File
@@ -33,7 +33,8 @@ Follow me on [X @nummanthinks](https://x.com/nummanthinks) for future updates an
## Features
- ✅ **ChatGPT Plus/Pro OAuth authentication** - Use your existing subscription
- ✅ **11 pre-configured model variants** - Includes Codex Mini (medium/high) alongside all gpt-5 and gpt-5-codex presets
- ✅ **8 pre-configured GPT 5.1 variants** - GPT 5.1, GPT 5.1 Codex, and GPT 5.1 Codex Mini presets for common reasoning levels
- ⚠️ **GPT 5.1 only** - Older GPT 5.0 models are deprecated and may not work reliably
- ✅ **Zero external dependencies** - Lightweight with only @openauthjs/openauth
- ✅ **Auto-refreshing tokens** - Handles token expiration automatically
- ✅ **Prompt caching** - Reuses responses across turns via stable `prompt_cache_key`
@@ -52,9 +53,15 @@ Follow me on [X @nummanthinks](https://x.com/nummanthinks) for future updates an
**No npm install needed!** opencode automatically installs plugins when you add them to your config.
#### Recommended: Full Configuration (Codex CLI Experience)
#### ⚠️ REQUIRED: Full Configuration (Only Supported Setup)
For the complete experience with all reasoning variants matching the official Codex CLI:
**IMPORTANT**: You MUST use the full configuration from [`config/full-opencode.json`](./config/full-opencode.json). Other configurations are not officially supported and may not work reliably.
**Why the full config is required:**
- GPT 5 models can be temperamental - some work, some don't, some may error
- The full config has been tested and verified to work
- Minimal configs lack proper model metadata for OpenCode features
- Older GPT 5.0 models are deprecated and being phased out by OpenAI
1. **Copy the full configuration** from [`config/full-opencode.json`](./config/full-opencode.json) to your opencode config file:
```json
@@ -75,8 +82,8 @@ For the complete experience with all reasoning variants matching the official Co
"store": false
},
"models": {
"gpt-5-codex-low": {
"name": "GPT 5 Codex Low (OAuth)",
"gpt-5.1-codex-low": {
"name": "GPT 5.1 Codex Low (OAuth)",
"limit": {
"context": 272000,
"output": 128000
@@ -91,8 +98,8 @@ For the complete experience with all reasoning variants matching the official Co
"store": false
}
},
"gpt-5-codex-medium": {
"name": "GPT 5 Codex Medium (OAuth)",
"gpt-5.1-codex-medium": {
"name": "GPT 5.1 Codex Medium (OAuth)",
"limit": {
"context": 272000,
"output": 128000
@@ -107,8 +114,8 @@ For the complete experience with all reasoning variants matching the official Co
"store": false
}
},
"gpt-5-codex-high": {
"name": "GPT 5 Codex High (OAuth)",
"gpt-5.1-codex-high": {
"name": "GPT 5.1 Codex High (OAuth)",
"limit": {
"context": 272000,
"output": 128000
@@ -123,11 +130,11 @@ For the complete experience with all reasoning variants matching the official Co
"store": false
}
},
"gpt-5-codex-mini-medium": {
"name": "GPT 5 Codex Mini Medium (OAuth)",
"gpt-5.1-codex-mini-medium": {
"name": "GPT 5.1 Codex Mini Medium (OAuth)",
"limit": {
"context": 200000,
"output": 100000
"context": 272000,
"output": 128000
},
"options": {
"reasoningEffort": "medium",
@@ -139,11 +146,11 @@ For the complete experience with all reasoning variants matching the official Co
"store": false
}
},
"gpt-5-codex-mini-high": {
"name": "GPT 5 Codex Mini High (OAuth)",
"gpt-5.1-codex-mini-high": {
"name": "GPT 5.1 Codex Mini High (OAuth)",
"limit": {
"context": 200000,
"output": 100000
"context": 272000,
"output": 128000
},
"options": {
"reasoningEffort": "high",
@@ -155,24 +162,8 @@ For the complete experience with all reasoning variants matching the official Co
"store": false
}
},
"gpt-5-minimal": {
"name": "GPT 5 Minimal (OAuth)",
"limit": {
"context": 272000,
"output": 128000
},
"options": {
"reasoningEffort": "minimal",
"reasoningSummary": "auto",
"textVerbosity": "low",
"include": [
"reasoning.encrypted_content"
],
"store": false
}
},
"gpt-5-low": {
"name": "GPT 5 Low (OAuth)",
"gpt-5.1-low": {
"name": "GPT 5.1 Low (OAuth)",
"limit": {
"context": 272000,
"output": 128000
@@ -187,8 +178,8 @@ For the complete experience with all reasoning variants matching the official Co
"store": false
}
},
"gpt-5-medium": {
"name": "GPT 5 Medium (OAuth)",
"gpt-5.1-medium": {
"name": "GPT 5.1 Medium (OAuth)",
"limit": {
"context": 272000,
"output": 128000
@@ -203,8 +194,8 @@ For the complete experience with all reasoning variants matching the official Co
"store": false
}
},
"gpt-5-high": {
"name": "GPT 5 High (OAuth)",
"gpt-5.1-high": {
"name": "GPT 5.1 High (OAuth)",
"limit": {
"context": 272000,
"output": 128000
@@ -218,38 +209,6 @@ For the complete experience with all reasoning variants matching the official Co
],
"store": false
}
},
"gpt-5-mini": {
"name": "GPT 5 Mini (OAuth)",
"limit": {
"context": 272000,
"output": 128000
},
"options": {
"reasoningEffort": "low",
"reasoningSummary": "auto",
"textVerbosity": "low",
"include": [
"reasoning.encrypted_content"
],
"store": false
}
},
"gpt-5-nano": {
"name": "GPT 5 Nano (OAuth)",
"limit": {
"context": 272000,
"output": 128000
},
"options": {
"reasoningEffort": "minimal",
"reasoningSummary": "auto",
"textVerbosity": "low",
"include": [
"reasoning.encrypted_content"
],
"store": false
}
}
}
}
@@ -260,25 +219,25 @@ For the complete experience with all reasoning variants matching the official Co
**Global config**: `~/.config/opencode/opencode.json`
**Project config**: `<project>/.opencode.json`
This gives you 11 model variants with different reasoning levels:
- **gpt-5-codex** (low/medium/high) - Code-optimized reasoning
- **gpt-5-codex-mini** (medium/high) - Cheaper Codex tier with 200k/100k tokens
- **gpt-5** (minimal/low/medium/high) - General-purpose reasoning
- **gpt-5-mini** and **gpt-5-nano** - Lightweight variants
This gives you 8 GPT 5.1 variants with different reasoning levels:
- **gpt-5.1-codex** (low/medium/high) - Latest Codex model presets
- **gpt-5.1-codex-mini** (medium/high) - Latest Codex mini tier presets
- **gpt-5.1** (low/medium/high) - Latest general-purpose reasoning presets
All appear in the opencode model selector as "GPT 5 Codex Low (OAuth)", "GPT 5 High (OAuth)", etc.
All appear in the opencode model selector as "GPT 5.1 Codex Low (OAuth)", "GPT 5.1 High (OAuth)", etc.
### Prompt caching & usage limits
Codex backend caching is enabled automatically. When OpenCode supplies a `prompt_cache_key` (its session identifier), the plugin forwards it unchanged so Codex can reuse work between turns. The plugin no longer synthesizes its own cache IDs—if the host omits `prompt_cache_key`, Codex will treat the turn as uncached. The bundled CODEX_MODE bridge prompt is synchronized with the latest Codex CLI release, so opencode and Codex stay in lock-step on tool availability. When your ChatGPT subscription nears a limit, opencode surfaces the plugin's friendly error message with the 5-hour and weekly windows, mirroring the Codex CLI summary.
> **Auto-compaction note:** OpenCode's context auto-compaction and usage sidebar only populate when the full configuration above is used (the minimal config lacks the per-model metadata OpenCode needs). Stick with `config/full-opencode.json` if you want live token counts and automatic history compaction inside the UI.
> **⚠️ IMPORTANT:** You MUST use the full configuration above. OpenCode's context auto-compaction and usage sidebar only work with the full config. Additionally, GPT 5 models require proper configuration - minimal configs are NOT supported and may fail unpredictably.
#### Alternative: Minimal Configuration
#### ❌ Minimal Configuration (NOT RECOMMENDED - DO NOT USE)
For a simpler setup (uses plugin defaults: medium reasoning, auto summaries):
**DO NOT use minimal configurations** - they are not supported for GPT 5.1 and will not work reliably:
```json
// ❌ DO NOT USE THIS - WILL NOT WORK RELIABLY
{
"$schema": "https://opencode.ai/config.json",
"plugin": [
@@ -288,7 +247,11 @@ For a simpler setup (uses plugin defaults: medium reasoning, auto summaries):
}
```
**Note**: This gives you basic functionality but you won't see the different reasoning variants in the model selector.
**Why this doesn't work:**
- GPT 5 models are temperamental and need proper configuration
- Missing model metadata breaks OpenCode features
- No support for usage limits or context compaction
- Cannot guarantee stable operation
2. **That's it!** opencode will auto-install the plugin on first run.
@@ -327,17 +290,17 @@ Check [releases](https://github.com/numman-ali/opencode-openai-codex-auth/releas
If using the full configuration, select from the model picker in opencode, or specify via command line:
```bash
# Use different reasoning levels for gpt-5-codex
opencode run "simple task" --model=openai/gpt-5-codex-low
opencode run "complex task" --model=openai/gpt-5-codex-high
# Use different reasoning levels for gpt-5.1-codex
opencode run "simple task" --model=openai/gpt-5.1-codex-low
opencode run "complex task" --model=openai/gpt-5.1-codex-high
# Use different reasoning levels for gpt-5
opencode run "quick question" --model=openai/gpt-5-minimal
opencode run "deep analysis" --model=openai/gpt-5-high
# Use different reasoning levels for gpt-5.1
opencode run "quick question" --model=openai/gpt-5.1-low
opencode run "deep analysis" --model=openai/gpt-5.1-high
# Or with minimal config (uses defaults)
opencode run "create a hello world file" --model=openai/gpt-5-codex
opencode run "solve this complex problem" --model=openai/gpt-5
# Use Codex Mini variants
opencode run "balanced task" --model=openai/gpt-5.1-codex-mini-medium
opencode run "complex code" --model=openai/gpt-5.1-codex-mini-high
```
### Available Model Variants (Full Config)
@@ -346,22 +309,21 @@ When using [`config/full-opencode.json`](./config/full-opencode.json), you get t
| CLI Model ID | TUI Display Name | Reasoning Effort | Best For |
|--------------|------------------|-----------------|----------|
| `gpt-5-codex-low` | GPT 5 Codex Low (OAuth) | Low | Fast code generation |
| `gpt-5-codex-medium` | GPT 5 Codex Medium (OAuth) | Medium | Balanced code tasks |
| `gpt-5-codex-high` | GPT 5 Codex High (OAuth) | High | Complex code & tools |
| `gpt-5-codex-mini-medium` | GPT 5 Codex Mini Medium (OAuth) | Medium | Cheaper Codex tier (200k/100k) |
| `gpt-5-codex-mini-high` | GPT 5 Codex Mini High (OAuth) | High | Codex Mini with maximum reasoning |
| `gpt-5-minimal` | GPT 5 Minimal (OAuth) | Minimal | Quick answers, simple tasks |
| `gpt-5-low` | GPT 5 Low (OAuth) | Low | Faster responses with light reasoning |
| `gpt-5-medium` | GPT 5 Medium (OAuth) | Medium | Balanced general-purpose tasks |
| `gpt-5-high` | GPT 5 High (OAuth) | High | Deep reasoning, complex problems |
| `gpt-5-mini` | GPT 5 Mini (OAuth) | Low | Lightweight tasks |
| `gpt-5-nano` | GPT 5 Nano (OAuth) | Minimal | Maximum speed |
| `gpt-5.1-codex-low` | GPT 5.1 Codex Low (OAuth) | Low | Fast code generation |
| `gpt-5.1-codex-medium` | GPT 5.1 Codex Medium (OAuth) | Medium | Balanced code tasks |
| `gpt-5.1-codex-high` | GPT 5.1 Codex High (OAuth) | High | Complex code & tools |
| `gpt-5.1-codex-mini-medium` | GPT 5.1 Codex Mini Medium (OAuth) | Medium | Latest Codex mini tier |
| `gpt-5.1-codex-mini-high` | GPT 5.1 Codex Mini High (OAuth) | High | Codex Mini with maximum reasoning |
| `gpt-5.1-low` | GPT 5.1 Low (OAuth) | Low | Faster responses with light reasoning |
| `gpt-5.1-medium` | GPT 5.1 Medium (OAuth) | Medium | Balanced general-purpose tasks |
| `gpt-5.1-high` | GPT 5.1 High (OAuth) | High | Deep reasoning, complex problems |
**Usage**: `--model=openai/<CLI Model ID>` (e.g., `--model=openai/gpt-5-codex-low`)
**Display**: TUI shows the friendly name (e.g., "GPT 5 Codex Low (OAuth)")
**Usage**: `--model=openai/<CLI Model ID>` (e.g., `--model=openai/gpt-5.1-codex-low`)
**Display**: TUI shows the friendly name (e.g., "GPT 5.1 Codex Low (OAuth)")
> **Note**: All `gpt-5-codex-mini*` presets normalize to the ChatGPT slug `codex-mini-latest` (200k input / 100k output tokens).
> **Note**: All `gpt-5.1-codex-mini*` presets map directly to the `gpt-5.1-codex-mini` slug with standard Codex limits (272k context / 128k output).
> **⚠️ Important**: GPT 5 models can be temperamental - some variants may work better than others, some may give errors, and behavior may vary. Stick to the presets above configured in `full-opencode.json` for best results.
All accessed via your ChatGPT Plus/Pro subscription.
@@ -371,10 +333,10 @@ All accessed via your ChatGPT Plus/Pro subscription.
```yaml
# ✅ Correct
model: openai/gpt-5-codex-low
model: openai/gpt-5.1-codex-low
# ❌ Wrong - will fail
model: gpt-5-codex-low
model: gpt-5.1-codex-low
```
See [Configuration Guide](https://numman-ali.github.io/opencode-openai-codex-auth/configuration) for advanced usage.
@@ -399,12 +361,15 @@ These defaults match the official Codex CLI behavior and can be customized (see
## Configuration
### Recommended: Use Pre-Configured File
### ⚠️ REQUIRED: Use Pre-Configured File
The easiest way to get started is to use [`config/full-opencode.json`](./config/full-opencode.json), which provides:
- 11 pre-configured model variants matching Codex CLI presets
- Optimal settings for each reasoning level
**YOU MUST use [`config/full-opencode.json`](./config/full-opencode.json)** - this is the only officially supported configuration:
- 8 pre-configured GPT 5.1 model variants with verified settings
- Optimal configuration for each reasoning level
- All variants visible in the opencode model selector
- Required metadata for OpenCode features to work properly
**Do NOT use other configurations** - they are not supported and may fail unpredictably with GPT 5 models.
See [Installation](#installation) for setup instructions.
+41 -26
View File
@@ -1,44 +1,59 @@
# Configuration Examples
# Configuration
This directory contains example opencode configuration files for the OpenAI Codex OAuth plugin.
This directory contains the official opencode configuration for the OpenAI Codex OAuth plugin.
## Files
## ⚠️ REQUIRED Configuration File
### minimal-opencode.json
The simplest possible configuration using plugin defaults.
### full-opencode.json (REQUIRED - USE THIS ONLY)
```bash
cp config/minimal-opencode.json ~/.config/opencode/opencode.json
```
This uses default settings:
- `reasoningEffort`: "medium"
- `reasoningSummary`: "auto"
- `textVerbosity`: "medium"
- `include`: ["reasoning.encrypted_content"]
- `store`: false (required for AI SDK 2.0.50+ compatibility)
### full-opencode.json
Complete configuration example showing all model variants with custom settings.
**YOU MUST use this configuration file** - it is the ONLY officially supported setup:
```bash
cp config/full-opencode.json ~/.config/opencode/opencode.json
```
This demonstrates:
- Global options for all models
- Per-model configuration overrides
- All supported model variants (gpt-5-codex, gpt-5-codex-mini, gpt-5, gpt-5-mini, gpt-5-nano)
**Why this is required:**
- GPT 5 models can be temperamental and need proper configuration
- Contains 8 verified GPT 5.1 model variants (Codex, Codex Mini, and general GPT 5.1)
- Includes all required metadata for OpenCode features
- Guaranteed to work reliably
- Global options for all models + per-model configuration overrides
**What's included:**
- All supported GPT 5.1 variants: gpt-5.1, gpt-5.1-codex, gpt-5.1-codex-mini
- Proper reasoning effort settings for each variant
- Context limits (272k context / 128k output)
- Required options: `store: false`, `include: ["reasoning.encrypted_content"]`
### ❌ Other Configurations (NOT SUPPORTED)
**DO NOT use:**
- `minimal-opencode.json` - NOT supported, will fail unpredictably
- `full-opencode-gpt5.json` - DEPRECATED, GPT 5.0 models are being phased out by OpenAI
- Custom configurations - NOT recommended, may not work reliably
**Why other configs don't work:**
- GPT 5 models need specific configurations
- Missing metadata breaks OpenCode features
- No support for usage limits or context compaction
- Cannot guarantee stable operation
## Usage
1. Choose a configuration file based on your needs
2. Copy it to your opencode config directory:
**ONLY ONE OPTION** - use the full configuration:
1. Copy `full-opencode.json` to your opencode config directory:
- Global: `~/.config/opencode/opencode.json`
- Project: `<project>/.opencode.json`
3. Modify settings as needed
4. Run opencode: `opencode run "your prompt"`
2. **DO NOT modify** the configuration unless you know exactly what you're doing. The provided settings have been tested and verified to work.
3. Run opencode: `opencode run "your prompt" --model=openai/gpt-5.1-codex-medium`
> **⚠️ Critical**: GPT 5 models require this exact configuration. Do not use minimal configs or create custom variants - they are not supported and will fail unpredictably.
## Configuration Options
See the main [README.md](../README.md#configuration) for detailed documentation of all configuration options.
**Remember**: Use `full-opencode.json` as-is for guaranteed compatibility. Custom configurations are not officially supported.
+21 -69
View File
@@ -15,8 +15,8 @@
"store": false
},
"models": {
"gpt-5-codex-low": {
"name": "GPT 5 Codex Low (OAuth)",
"gpt-5.1-codex-low": {
"name": "GPT 5.1 Codex Low (OAuth)",
"limit": {
"context": 272000,
"output": 128000
@@ -31,8 +31,8 @@
"store": false
}
},
"gpt-5-codex-medium": {
"name": "GPT 5 Codex Medium (OAuth)",
"gpt-5.1-codex-medium": {
"name": "GPT 5.1 Codex Medium (OAuth)",
"limit": {
"context": 272000,
"output": 128000
@@ -47,8 +47,8 @@
"store": false
}
},
"gpt-5-codex-high": {
"name": "GPT 5 Codex High (OAuth)",
"gpt-5.1-codex-high": {
"name": "GPT 5.1 Codex High (OAuth)",
"limit": {
"context": 272000,
"output": 128000
@@ -63,11 +63,11 @@
"store": false
}
},
"gpt-5-codex-mini-medium": {
"name": "GPT 5 Codex Mini Medium (OAuth)",
"gpt-5.1-codex-mini-medium": {
"name": "GPT 5.1 Codex Mini Medium (OAuth)",
"limit": {
"context": 200000,
"output": 100000
"context": 272000,
"output": 128000
},
"options": {
"reasoningEffort": "medium",
@@ -79,11 +79,11 @@
"store": false
}
},
"gpt-5-codex-mini-high": {
"name": "GPT 5 Codex Mini High (OAuth)",
"gpt-5.1-codex-mini-high": {
"name": "GPT 5.1 Codex Mini High (OAuth)",
"limit": {
"context": 200000,
"output": 100000
"context": 272000,
"output": 128000
},
"options": {
"reasoningEffort": "high",
@@ -95,24 +95,8 @@
"store": false
}
},
"gpt-5-minimal": {
"name": "GPT 5 Minimal (OAuth)",
"limit": {
"context": 272000,
"output": 128000
},
"options": {
"reasoningEffort": "minimal",
"reasoningSummary": "auto",
"textVerbosity": "low",
"include": [
"reasoning.encrypted_content"
],
"store": false
}
},
"gpt-5-low": {
"name": "GPT 5 Low (OAuth)",
"gpt-5.1-low": {
"name": "GPT 5.1 Low (OAuth)",
"limit": {
"context": 272000,
"output": 128000
@@ -127,8 +111,8 @@
"store": false
}
},
"gpt-5-medium": {
"name": "GPT 5 Medium (OAuth)",
"gpt-5.1-medium": {
"name": "GPT 5.1 Medium (OAuth)",
"limit": {
"context": 272000,
"output": 128000
@@ -143,8 +127,8 @@
"store": false
}
},
"gpt-5-high": {
"name": "GPT 5 High (OAuth)",
"gpt-5.1-high": {
"name": "GPT 5.1 High (OAuth)",
"limit": {
"context": 272000,
"output": 128000
@@ -158,40 +142,8 @@
],
"store": false
}
},
"gpt-5-mini": {
"name": "GPT 5 Mini (OAuth)",
"limit": {
"context": 272000,
"output": 128000
},
"options": {
"reasoningEffort": "low",
"reasoningSummary": "auto",
"textVerbosity": "low",
"include": [
"reasoning.encrypted_content"
],
"store": false
}
},
"gpt-5-nano": {
"name": "GPT 5 Nano (OAuth)",
"limit": {
"context": 272000,
"output": 128000
},
"options": {
"reasoningEffort": "minimal",
"reasoningSummary": "auto",
"textVerbosity": "low",
"include": [
"reasoning.encrypted_content"
],
"store": false
}
}
}
}
}
}
}
+33 -18
View File
@@ -18,8 +18,8 @@ Complete reference for configuring the OpenCode OpenAI Codex Auth Plugin.
"store": false
},
"models": {
"gpt-5-codex-low": {
"name": "GPT 5 Codex Low (OAuth)",
"gpt-5.1-codex-low": {
"name": "GPT 5.1 Codex Low (OAuth)",
"limit": {
"context": 272000,
"output": 128000
@@ -59,7 +59,7 @@ Controls computational effort for reasoning.
**Notes**:
- `minimal` auto-converts to `low` for gpt-5-codex (API limitation)
- `gpt-5-codex-mini*` only supports `medium` or `high`; lower settings are clamped to `medium`
- `gpt-5-codex-mini*` and `gpt-5.1-codex-mini*` only support `medium` or `high`; lower settings are clamped to `medium`
**Example:**
```json
@@ -240,6 +240,8 @@ opencode run "task" --model=openai/my-custom-id
# TUI shows: "My Display Name"
```
> **⚠️ Recommendation:** Stick to the official presets in `full-opencode.json` rather than creating custom model variants. GPT 5 models need specific configurations to work reliably.
See [development/CONFIG_FIELDS.md](development/CONFIG_FIELDS.md) for complete explanation.
---
@@ -287,11 +289,11 @@ Different agents use different models:
{
"agent": {
"commit": {
"model": "openai/codex-quick",
"model": "openai/gpt-5.1-codex-low",
"prompt": "Generate concise commit messages"
},
"review": {
"model": "openai/codex-quality",
"model": "openai/gpt-5.1-codex-high",
"prompt": "Thorough code review"
}
}
@@ -381,10 +383,9 @@ CODEX_MODE=1 opencode run "task" # Temporarily enable
## Configuration Files
**Provided Examples:**
- [config/full-opencode.json](../config/full-opencode.json) - Complete with 11 variants (adds Codex Mini presets)
- [config/minimal-opencode.json](../config/minimal-opencode.json) - Minimal setup
- [config/full-opencode.json](../config/full-opencode.json) - Complete with 8 GPT 5.1 variants
> **Why choose the full config?** OpenCode's auto-compaction and usage widgets rely on the per-model `limit` metadata present only in `full-opencode.json`. Use the minimal config only if you don't need those UI features.
> **⚠️ REQUIRED:** You MUST use `full-opencode.json` - this is the ONLY officially supported configuration. Minimal configs are NOT supported for GPT 5 models and will fail unpredictably. OpenCode's auto-compaction and usage widgets also require the full config's per-model `limit` metadata.
**Your Configs:**
- `~/.config/opencode/opencode.json` - Global config
@@ -436,26 +437,38 @@ cat ~/.opencode/logs/codex-plugin/request-*-after-transform.json | jq '.reasonin
Old verbose names still work:
**⚠️ IMPORTANT:** Old configs with GPT 5.0 models are deprecated. You MUST migrate to the new `full-opencode.json` with GPT 5.1 models.
**Old config (deprecated):**
```json
{
"models": {
"GPT 5 Codex Low (ChatGPT Subscription)": {
"id": "gpt-5-codex",
"gpt-5-codex-low": {
"name": "GPT 5 Codex Low (OAuth)",
"options": { "reasoningEffort": "low" }
}
}
}
```
**Recommended update** (cleaner CLI usage):
**New config (required):**
Use the official [`config/full-opencode.json`](../config/full-opencode.json) file which includes:
```json
{
"models": {
"gpt-5-codex-low": {
"name": "GPT 5 Codex Low (OAuth)",
"gpt-5.1-codex-low": {
"name": "GPT 5.1 Codex Low (OAuth)",
"limit": {
"context": 272000,
"output": 128000
},
"options": {
"reasoningEffort": "low",
"reasoningSummary": "auto",
"textVerbosity": "medium",
"include": ["reasoning.encrypted_content"],
"store": false
}
}
@@ -464,9 +477,9 @@ Old verbose names still work:
```
**Benefits:**
- Cleaner: `--model=openai/gpt-5-codex-low`
- Matches Codex CLI preset names
- No redundant `id` field
- GPT 5.1 support (5.0 is deprecated)
- Proper limit metadata for OpenCode features
- Verified configuration that works reliably
---
@@ -563,14 +576,16 @@ Look for `hasModelSpecificConfig: true` in debug output.
**Example Problem:**
```json
{ "models": { "gpt-5-codex": { "options": { ... } } } }
{ "models": { "gpt-5.1-codex": { "options": { ... } } } }
```
```bash
--model=openai/gpt-5-codex-low # Normalizes to "gpt-5-codex" before lookup
--model=openai/gpt-5.1-codex-low # Normalizes to "gpt-5.1-codex" before lookup
```
**Fix**: Use exact name you specify in CLI as config key.
> **⚠️ Best Practice:** Use the official `full-opencode.json` configuration instead of creating custom configs. This ensures proper model normalization and compatibility with GPT 5 models.
---
**Next**: [Troubleshooting](troubleshooting.md) | [Back to Documentation Home](index.md)
+18 -1
View File
@@ -579,6 +579,9 @@ normalizeModel("gpt-5-codex-low") // → "gpt-5-codex" ✅
normalizeModel("GPT-5-CODEX-HIGH") // → "gpt-5-codex" ✅
normalizeModel("gpt-5-codex-mini-high")// → "codex-mini-latest" ✅
normalizeModel("codex-mini-latest") // → "codex-mini-latest" ✅
normalizeModel("gpt-5.1-codex-mini") // → "gpt-5.1-codex-mini" ✅
normalizeModel("gpt-5.1-codex") // → "gpt-5.1-codex" ✅
normalizeModel("gpt-5.1") // → "gpt-5.1" ✅
normalizeModel("my-codex-model") // → "gpt-5-codex" ✅
normalizeModel("gpt-5") // → "gpt-5" ✅
normalizeModel("gpt-5-mini") // → "gpt-5" ✅
@@ -593,9 +596,23 @@ normalizeModel("random-model") // → "gpt-5" ✅ (fallback)
export function normalizeModel(model: string | undefined): string {
if (!model) return "gpt-5";
const normalized = model.toLowerCase();
if (normalized.includes("codex-mini") || normalized.includes("codex-mini-latest")) {
if (normalized.includes("gpt-5.1-codex-mini") || normalized.includes("gpt 5.1 codex mini")) {
return "gpt-5.1-codex-mini";
}
if (
normalized.includes("codex-mini-latest") ||
normalized.includes("gpt-5-codex-mini") ||
normalized.includes("gpt 5 codex mini")
) {
return "codex-mini-latest";
}
if (normalized.includes("gpt-5.1-codex") || normalized.includes("gpt 5.1 codex")) {
return "gpt-5.1-codex";
}
if (normalized.includes("gpt-5.1") || normalized.includes("gpt 5.1")) {
return "gpt-5.1";
}
if (normalized.includes("codex")) {
return "gpt-5-codex";
}
+47 -81
View File
@@ -26,9 +26,15 @@ OpenCode automatically installs plugins - no `npm install` needed!
**Choose your configuration style:**
#### Option A: Full Configuration (Recommended)
#### ⚠️ REQUIRED: Full Configuration (Only Supported Setup)
Get 11 pre-configured model variants with optimal settings (including Codex Mini).
**IMPORTANT**: You MUST use the full configuration. This is the ONLY officially supported setup for GPT 5.1 models.
**Why the full config is required:**
- GPT 5 models can be temperamental and need proper configuration
- Minimal configs are NOT supported and will fail unpredictably
- OpenCode features require proper model metadata
- This configuration has been tested and verified to work
Add this to `~/.config/opencode/opencode.json`:
@@ -46,8 +52,8 @@ Add this to `~/.config/opencode/opencode.json`:
"store": false
},
"models": {
"gpt-5-codex-low": {
"name": "GPT 5 Codex Low (OAuth)",
"gpt-5.1-codex-low": {
"name": "GPT 5.1 Codex Low (OAuth)",
"limit": {
"context": 272000,
"output": 128000
@@ -60,8 +66,8 @@ Add this to `~/.config/opencode/opencode.json`:
"store": false
}
},
"gpt-5-codex-medium": {
"name": "GPT 5 Codex Medium (OAuth)",
"gpt-5.1-codex-medium": {
"name": "GPT 5.1 Codex Medium (OAuth)",
"limit": {
"context": 272000,
"output": 128000
@@ -74,8 +80,8 @@ Add this to `~/.config/opencode/opencode.json`:
"store": false
}
},
"gpt-5-codex-high": {
"name": "GPT 5 Codex High (OAuth)",
"gpt-5.1-codex-high": {
"name": "GPT 5.1 Codex High (OAuth)",
"limit": {
"context": 272000,
"output": 128000
@@ -88,11 +94,11 @@ Add this to `~/.config/opencode/opencode.json`:
"store": false
}
},
"gpt-5-codex-mini-medium": {
"name": "GPT 5 Codex Mini Medium (OAuth)",
"gpt-5.1-codex-mini-medium": {
"name": "GPT 5.1 Codex Mini Medium (OAuth)",
"limit": {
"context": 200000,
"output": 100000
"context": 272000,
"output": 128000
},
"options": {
"reasoningEffort": "medium",
@@ -102,11 +108,11 @@ Add this to `~/.config/opencode/opencode.json`:
"store": false
}
},
"gpt-5-codex-mini-high": {
"name": "GPT 5 Codex Mini High (OAuth)",
"gpt-5.1-codex-mini-high": {
"name": "GPT 5.1 Codex Mini High (OAuth)",
"limit": {
"context": 200000,
"output": 100000
"context": 272000,
"output": 128000
},
"options": {
"reasoningEffort": "high",
@@ -116,22 +122,8 @@ Add this to `~/.config/opencode/opencode.json`:
"store": false
}
},
"gpt-5-minimal": {
"name": "GPT 5 Minimal (OAuth)",
"limit": {
"context": 272000,
"output": 128000
},
"options": {
"reasoningEffort": "minimal",
"reasoningSummary": "auto",
"textVerbosity": "low",
"include": ["reasoning.encrypted_content"],
"store": false
}
},
"gpt-5-low": {
"name": "GPT 5 Low (OAuth)",
"gpt-5.1-low": {
"name": "GPT 5.1 Low (OAuth)",
"limit": {
"context": 272000,
"output": 128000
@@ -144,8 +136,8 @@ Add this to `~/.config/opencode/opencode.json`:
"store": false
}
},
"gpt-5-medium": {
"name": "GPT 5 Medium (OAuth)",
"gpt-5.1-medium": {
"name": "GPT 5.1 Medium (OAuth)",
"limit": {
"context": 272000,
"output": 128000
@@ -158,8 +150,8 @@ Add this to `~/.config/opencode/opencode.json`:
"store": false
}
},
"gpt-5-high": {
"name": "GPT 5 High (OAuth)",
"gpt-5.1-high": {
"name": "GPT 5.1 High (OAuth)",
"limit": {
"context": 272000,
"output": 128000
@@ -171,34 +163,6 @@ Add this to `~/.config/opencode/opencode.json`:
"include": ["reasoning.encrypted_content"],
"store": false
}
},
"gpt-5-mini": {
"name": "GPT 5 Mini (OAuth)",
"limit": {
"context": 272000,
"output": 128000
},
"options": {
"reasoningEffort": "low",
"reasoningSummary": "auto",
"textVerbosity": "low",
"include": ["reasoning.encrypted_content"],
"store": false
}
},
"gpt-5-nano": {
"name": "GPT 5 Nano (OAuth)",
"limit": {
"context": 272000,
"output": 128000
},
"options": {
"reasoningEffort": "minimal",
"reasoningSummary": "auto",
"textVerbosity": "low",
"include": ["reasoning.encrypted_content"],
"store": false
}
}
}
}
@@ -206,25 +170,26 @@ Add this to `~/.config/opencode/opencode.json`:
}
```
**What you get:**
- ✅ GPT-5 Codex (Low/Medium/High reasoning)
- ✅ GPT-5 (Minimal/Low/Medium/High reasoning)
- ✅ gpt-5-codex-mini (medium/high) plus gpt-5-mini & gpt-5-nano (lightweight variants)
**What you get:**
- ✅ GPT 5.1 Codex (Low/Medium/High reasoning)
- ✅ GPT 5.1 Codex Mini (Medium/High reasoning)
- ✅ GPT 5.1 (Low/Medium/High reasoning)
- ✅ 272k context + 128k output window for every preset
- ✅ All visible in OpenCode model selector
- ✅ Optimal settings for each reasoning level
> Codex Mini presets normalize to the ChatGPT slug `codex-mini-latest` (200k input / 100k output tokens).
- ✅ 272k context + 128k output window for every preset
- ✅ All visible in OpenCode model selector
- ✅ Optimal settings for each reasoning level
> **Note**: All `gpt-5.1-codex-mini*` presets use 272k context / 128k output limits.
Prompt caching is enabled out of the box: when OpenCode sends its session identifier as `prompt_cache_key`, the plugin forwards it untouched so multi-turn runs reuse prior work. The plugin no longer synthesizes cache IDs; if the host omits that field, Codex treats the run as uncached. The CODEX_MODE bridge prompt bundled with the plugin is kept in sync with the latest Codex CLI release, so the OpenCode UI and Codex share the same tool contract. If you hit your ChatGPT subscription limits, the plugin returns a friendly Codex-style message with the 5-hour and weekly usage windows so you know when capacity resets.
Prompt caching is enabled out of the box: when OpenCode sends its session identifier as `prompt_cache_key`, the plugin forwards it untouched so multi-turn runs reuse prior work. The CODEX_MODE bridge prompt bundled with the plugin is kept in sync with the latest Codex CLI release, so the OpenCode UI and Codex share the same tool contract. If you hit your ChatGPT subscription limits, the plugin returns a friendly Codex-style message with the 5-hour and weekly usage windows so you know when capacity resets.
> **Heads up:** OpenCode's context auto-compaction and usage sidebar only work when this full configuration is installed. The minimal configuration skips the per-model limits, so OpenCode cannot display token usage or compact history automatically.
> **⚠️ CRITICAL:** This full configuration is REQUIRED. OpenCode's context auto-compaction and usage sidebar only work with this full configuration. GPT 5 models are temperamental and need proper setup - minimal configurations are NOT supported.
#### Option B: Minimal Configuration
#### ❌ Minimal Configuration (NOT SUPPORTED - DO NOT USE)
Just want to get started quickly?
**DO NOT use minimal configurations** - they will NOT work reliably with GPT 5:
```json
// ❌ DO NOT USE THIS
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["opencode-openai-codex-auth"],
@@ -232,9 +197,10 @@ Just want to get started quickly?
}
```
Save to `~/.config/opencode/opencode.json`
**Trade-off**: Uses default settings (medium reasoning), no model variants in selector.
**Why this doesn't work:**
- GPT 5 models need proper configuration to work reliably
- Missing model metadata breaks OpenCode features
- Cannot guarantee stable operation
### Step 2: Authenticate
@@ -254,13 +220,13 @@ opencode auth login
```bash
# Quick test
opencode run "write hello world to test.txt" --model=openai/gpt-5-codex
opencode run "write hello world to test.txt" --model=openai/gpt-5.1-codex-medium
# Or start interactive session
opencode
```
If using full config, you'll see all 11 variants (including Codex Mini) in the model selector!
You'll see all 8 GPT 5.1 variants (5.1, 5.1 Codex, and 5.1 Codex Mini presets) in the model selector!
---
+4 -2
View File
@@ -82,12 +82,14 @@ opencode run "write hello world to test.txt" --model=openai/gpt-5-codex
## Features
✅ **OAuth Authentication** - Secure ChatGPT Plus/Pro login
✅ **Multiple Models** - gpt-5, gpt-5-codex, gpt-5-codex-mini, gpt-5-mini, gpt-5-nano
✅ **GPT 5.1 Models** - gpt-5.1, gpt-5.1-codex, gpt-5.1-codex-mini (8 pre-configured variants)
✅ **Per-Model Configuration** - Different reasoning effort, verbosity for each variant
✅ **Multi-Turn Conversations** - Full conversation history with stateless backend
✅ **Backwards Compatible** - Works with old and new config formats
✅ **Verified Configuration** - Use `config/full-opencode.json` for guaranteed compatibility
✅ **Comprehensive Testing** - 160+ unit tests + 14 integration tests
> **⚠️ Important**: GPT 5 models can be temperamental. Use the official `config/full-opencode.json` configuration - it's the ONLY supported setup. Older GPT 5.0 models are deprecated.
---
## Why This Plugin?
+92
View File
@@ -0,0 +1,92 @@
/**
* Model Configuration Map
*
* Maps model config IDs to their normalized API model names.
* Only includes exact config IDs that OpenCode will pass to the plugin.
*/
/**
* Map of config model IDs to normalized API model names
*
* Key: The model ID as specified in opencode.json config
* Value: The normalized model name to send to the API
*/
export const MODEL_MAP: Record<string, string> = {
// ============================================================================
// GPT-5.1 Codex Models
// ============================================================================
"gpt-5.1-codex": "gpt-5.1-codex",
"gpt-5.1-codex-low": "gpt-5.1-codex",
"gpt-5.1-codex-medium": "gpt-5.1-codex",
"gpt-5.1-codex-high": "gpt-5.1-codex",
// ============================================================================
// GPT-5.1 Codex Mini Models
// ============================================================================
"gpt-5.1-codex-mini": "gpt-5.1-codex-mini",
"gpt-5.1-codex-mini-medium": "gpt-5.1-codex-mini",
"gpt-5.1-codex-mini-high": "gpt-5.1-codex-mini",
// ============================================================================
// GPT-5.1 General Purpose Models
// ============================================================================
"gpt-5.1": "gpt-5.1",
"gpt-5.1-low": "gpt-5.1",
"gpt-5.1-medium": "gpt-5.1",
"gpt-5.1-high": "gpt-5.1",
// ============================================================================
// GPT-5 Codex Models (LEGACY - for backwards compatibility)
// ============================================================================
"gpt-5-codex": "gpt-5-codex",
// ============================================================================
// GPT-5 Codex Mini Models (LEGACY - for backwards compatibility)
// ============================================================================
"codex-mini-latest": "codex-mini-latest",
"gpt-5-codex-mini": "codex-mini-latest",
"gpt-5-codex-mini-medium": "codex-mini-latest",
"gpt-5-codex-mini-high": "codex-mini-latest",
// ============================================================================
// GPT-5 General Purpose Models (LEGACY - for backwards compatibility)
// ============================================================================
"gpt-5": "gpt-5",
"gpt-5-mini": "gpt-5",
"gpt-5-nano": "gpt-5",
};
/**
* Get normalized model name from config ID
*
* @param modelId - Model ID from config (e.g., "gpt-5.1-codex-low")
* @returns Normalized model name (e.g., "gpt-5.1-codex") or undefined if not found
*/
export function getNormalizedModel(modelId: string): string | undefined {
try {
// Try direct lookup first
if (MODEL_MAP[modelId]) {
return MODEL_MAP[modelId];
}
// Try case-insensitive lookup
const lowerModelId = modelId.toLowerCase();
const match = Object.keys(MODEL_MAP).find(
(key) => key.toLowerCase() === lowerModelId,
);
return match ? MODEL_MAP[match] : undefined;
} catch {
return undefined;
}
}
/**
* Check if a model ID is in the model map
*
* @param modelId - Model ID to check
* @returns True if model is in the map
*/
export function isKnownModel(modelId: string): boolean {
return getNormalizedModel(modelId) !== undefined;
}
+53 -7
View File
@@ -2,6 +2,7 @@ import { logDebug, logWarn } from "../logger.js";
import { TOOL_REMAP_MESSAGE } from "../prompts/codex.js";
import { CODEX_OPENCODE_BRIDGE } from "../prompts/codex-opencode-bridge.js";
import { getOpenCodeCodexPrompt } from "../prompts/opencode-codex.js";
import { getNormalizedModel } from "./helpers/model-map.js";
import type {
ConfigOptions,
InputItem,
@@ -12,28 +13,73 @@ import type {
/**
* Normalize model name to Codex-supported variants
* @param model - Original model name
* @returns Normalized model name
*
* Uses explicit model map for known models, with fallback pattern matching
* for unknown/custom model names.
*
* @param model - Original model name (e.g., "gpt-5.1-codex-low", "openai/gpt-5-codex")
* @returns Normalized model name (e.g., "gpt-5.1-codex", "gpt-5-codex")
*/
export function normalizeModel(model: string | undefined): string {
if (!model) return "gpt-5";
const normalized = model.toLowerCase();
// Strip provider prefix if present (e.g., "openai/gpt-5-codex" → "gpt-5-codex")
const modelId = model.includes("/") ? model.split("/").pop()! : model;
if (normalized.includes("codex-mini")) {
// Try explicit model map first (handles all known model variants)
const mappedModel = getNormalizedModel(modelId);
if (mappedModel) {
return mappedModel;
}
// Fallback: Pattern-based matching for unknown/custom model names
// This preserves backwards compatibility with old verbose names
// like "GPT 5 Codex Low (ChatGPT Subscription)"
const normalized = modelId.toLowerCase();
// Priority order for pattern matching (most specific first):
// 1. GPT-5.1 Codex Mini
if (
normalized.includes("gpt-5.1-codex-mini") ||
normalized.includes("gpt 5.1 codex mini")
) {
return "gpt-5.1-codex-mini";
}
// 2. Legacy Codex Mini
if (
normalized.includes("codex-mini-latest") ||
normalized.includes("gpt-5-codex-mini") ||
normalized.includes("gpt 5 codex mini")
) {
return "codex-mini-latest";
}
// Case-insensitive check for "codex" anywhere in the model name
// 3. GPT-5.1 Codex
if (
normalized.includes("gpt-5.1-codex") ||
normalized.includes("gpt 5.1 codex")
) {
return "gpt-5.1-codex";
}
// 4. GPT-5.1 (general-purpose)
if (normalized.includes("gpt-5.1") || normalized.includes("gpt 5.1")) {
return "gpt-5.1";
}
// 5. GPT-5 Codex family (any variant with "codex")
if (normalized.includes("codex")) {
return "gpt-5-codex";
}
// Case-insensitive check for "gpt-5" or "gpt 5" (with space)
// 6. GPT-5 family (any variant)
if (normalized.includes("gpt-5") || normalized.includes("gpt 5")) {
return "gpt-5";
}
return "gpt-5"; // Default fallback
// Default fallback
return "gpt-5";
}
/**
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "opencode-openai-codex-auth",
"version": "3.1.0",
"version": "3.2.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "opencode-openai-codex-auth",
"version": "3.1.0",
"version": "3.2.0",
"license": "MIT",
"dependencies": {
"@openauthjs/openauth": "^0.4.3",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "opencode-openai-codex-auth",
"version": "3.1.0",
"version": "3.2.0",
"description": "OpenAI ChatGPT (Codex backend) OAuth auth plugin for opencode - use your ChatGPT Plus/Pro subscription instead of API credits",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
+49 -46
View File
@@ -28,6 +28,13 @@ echo -e "${BLUE} Model Configuration Verification Test Suite${NC}"
echo -e "${BLUE}════════════════════════════════════════════════════════════════${NC}"
echo ""
# Kill any running OpenCode server processes to force fresh plugin load
echo "Killing OpenCode server processes..."
pkill -f "opencode" 2>/dev/null || true
sleep 2
echo "✓ OpenCode servers stopped"
echo ""
# Initialize results file
cat > "${RESULTS_FILE}" << 'EOF'
# Model Configuration Verification Results
@@ -67,8 +74,8 @@ test_model() {
return 1
fi
# Find the after-transform log file
local log_file=$(find "${LOG_DIR}" -name "*-after-transform.json" | head -n 1)
# Find the after-transform log file (most recent)
local log_file=$(find "${LOG_DIR}" -name "*-after-transform.json" -type f -print0 | xargs -0 ls -t | head -n 1)
if [ ! -f "${log_file}" ]; then
echo -e "${RED} ✗ Log file not found${NC}"
@@ -122,36 +129,14 @@ update_config() {
case "${config_type}" in
"full")
cat "${REPO_DIR}/config/full-opencode.json" > "${OPENCODE_JSON}"
echo "✓ Updated opencode.json with full config"
echo "✓ Updated opencode.json with full config (GPT 5.1)"
;;
"minimal")
cat "${REPO_DIR}/config/minimal-opencode.json" > "${OPENCODE_JSON}"
echo "✓ Updated opencode.json with minimal config"
;;
"backwards-compat")
cat > "${OPENCODE_JSON}" << 'EOCONFIG'
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["file:///Users/numman/Repos/opencode-codex-plugin-fresh/dist"],
"provider": {
"openai": {
"options": {
"reasoningEffort": "medium"
},
"models": {
"GPT 5 Codex Low (ChatGPT Subscription)": {
"id": "gpt-5-codex",
"options": {
"reasoningEffort": "low",
"reasoningSummary": "auto",
"textVerbosity": "medium"
}
}
}
}
}
}
EOCONFIG
cat "${REPO_DIR}/config/full-opencode-gpt5.json" > "${OPENCODE_JSON}"
echo "✓ Updated opencode.json with backwards compatibility config"
;;
esac
@@ -160,36 +145,54 @@ EOCONFIG
}
# ============================================================================
# Scenario 1: Full Config - All 9 Custom Models
# Scenario 1: Full Config - GPT 5.1 Model Family
# ============================================================================
update_config "full"
test_model "gpt-5-codex-low" "gpt-5-codex" "low" "auto" "medium"
test_model "gpt-5-codex-medium" "gpt-5-codex" "medium" "auto" "medium"
test_model "gpt-5-codex-high" "gpt-5-codex" "high" "detailed" "medium"
test_model "gpt-5-minimal" "gpt-5" "minimal" "auto" "low"
test_model "gpt-5-low" "gpt-5" "low" "auto" "low"
test_model "gpt-5-medium" "gpt-5" "medium" "auto" "medium"
test_model "gpt-5-high" "gpt-5" "high" "detailed" "high"
test_model "gpt-5-mini" "gpt-5" "low" "auto" "low"
test_model "gpt-5-nano" "gpt-5" "minimal" "auto" "low"
# GPT 5.1 Codex presets
test_model "gpt-5.1-codex-low" "gpt-5.1-codex" "low" "auto" "medium"
test_model "gpt-5.1-codex-medium" "gpt-5.1-codex" "medium" "auto" "medium"
test_model "gpt-5.1-codex-high" "gpt-5.1-codex" "high" "detailed" "medium"
# ============================================================================
# Scenario 2: Minimal Config - Default Models (No Custom Config)
# ============================================================================
update_config "minimal"
# GPT 5.1 Codex Mini presets (medium/high only)
test_model "gpt-5.1-codex-mini-medium" "gpt-5.1-codex-mini" "medium" "auto" "medium"
test_model "gpt-5.1-codex-mini-high" "gpt-5.1-codex-mini" "high" "detailed" "medium"
test_model "gpt-5" "gpt-5" "medium" "auto" "medium"
test_model "gpt-5-codex" "gpt-5-codex" "medium" "auto" "medium"
test_model "gpt-5-mini" "gpt-5" "minimal" "auto" "medium"
test_model "gpt-5-nano" "gpt-5" "minimal" "auto" "medium"
# GPT 5.1 general-purpose presets
test_model "gpt-5.1-low" "gpt-5.1" "low" "auto" "low"
test_model "gpt-5.1-medium" "gpt-5.1" "medium" "auto" "medium"
test_model "gpt-5.1-high" "gpt-5.1" "high" "detailed" "high"
# # ============================================================================
# # Scenario 2: Minimal Config - Default Models (No Custom Config)
# # ============================================================================
# update_config "minimal"
# test_model "gpt-5" "gpt-5" "medium" "auto" "medium"
# test_model "gpt-5-codex" "gpt-5-codex" "medium" "auto" "medium"
# test_model "gpt-5-mini" "gpt-5" "minimal" "auto" "medium"
# test_model "gpt-5-nano" "gpt-5" "minimal" "auto" "medium"
# ============================================================================
# Scenario 3: Backwards Compatibility
# ============================================================================
update_config "backwards-compat"
# update_config "backwards-compat"
test_model "GPT 5 Codex Low (ChatGPT Subscription)" "gpt-5-codex" "low" "auto" "medium"
# # GPT 5 Codex presets
# test_model "gpt-5-codex-low" "gpt-5-codex" "low" "auto" "medium"
# test_model "gpt-5-codex-medium" "gpt-5-codex" "medium" "auto" "medium"
# test_model "gpt-5-codex-high" "gpt-5-codex" "high" "detailed" "medium"
# GPT 5 Codex Mini presets
# test_model "gpt-5-codex-mini" "codex-mini-latest" "medium" "auto" "medium"
# test_model "gpt-5-codex-mini-medium" "codex-mini-latest" "medium" "auto" "medium"
# test_model "gpt-5-codex-mini-high" "codex-mini-latest" "high" "detailed" "medium"
# GPT 5 general-purpose presets
# test_model "gpt-5" "gpt-5" "medium" "auto" "medium"
# test_model "gpt-5-medium" "gpt-5" "medium" "auto" "medium"
# test_model "gpt-5-high" "gpt-5" "high" "detailed" "high"
# test_model "gpt-5-mini" "gpt-5" "minimal" "auto" "medium"
# ============================================================================
# Summary
+97
View File
@@ -0,0 +1,97 @@
#!/bin/bash
# Simple Model Map Validation Script
# Tests that OpenCode correctly uses models from config
set -e
# Colors
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
LOG_DIR="${HOME}/.opencode/logs/codex-plugin"
echo -e "${BLUE}════════════════════════════════════════════${NC}"
echo -e "${BLUE} Model Map Validation${NC}"
echo -e "${BLUE}════════════════════════════════════════════${NC}"
echo ""
# Test 1: Model that IS in the config (should work)
echo -e "${YELLOW}Test 1: Model IN config (gpt-5.1-codex-low)${NC}"
rm -rf "${LOG_DIR}"/*
cd "${REPO_DIR}"
if ENABLE_PLUGIN_REQUEST_LOGGING=1 opencode run "say hello" --model="openai/gpt-5.1-codex-low" > /dev/null 2>&1; then
# Check the log - find the one for gpt-5.1-codex-low specifically
log_file=$(find "${LOG_DIR}" -name "*-after-transform.json" -exec grep -l "gpt-5.1-codex-low" {} \; | head -n 1)
if [ -f "${log_file}" ]; then
original=$(jq -r '.originalModel // "N/A"' "${log_file}")
normalized=$(jq -r '.normalizedModel // "N/A"' "${log_file}")
echo -e " Original: ${original}"
echo -e " Normalized: ${normalized}"
if [ "${normalized}" == "gpt-5.1-codex" ]; then
echo -e " ${GREEN}✓ PASS - Correctly normalized to gpt-5.1-codex${NC}"
else
echo -e " ${RED}✗ FAIL - Expected gpt-5.1-codex, got ${normalized}${NC}"
exit 1
fi
else
echo -e " ${RED}✗ FAIL - No log file found${NC}"
exit 1
fi
else
echo -e " ${RED}✗ FAIL - Command failed${NC}"
exit 1
fi
echo ""
# Test 2: Model that is NOT in the config (should error or use fallback)
echo -e "${YELLOW}Test 2: Model NOT in config (fake-model-xyz)${NC}"
rm -rf "${LOG_DIR}"/*
if ENABLE_PLUGIN_REQUEST_LOGGING=1 opencode run "write test" --model="openai/fake-model-xyz" > /dev/null 2>&1; then
log_file=$(find "${LOG_DIR}" -name "*-after-transform.json" | head -n 1)
if [ -f "${log_file}" ]; then
original=$(jq -r '.originalModel // "N/A"' "${log_file}")
normalized=$(jq -r '.normalizedModel // "N/A"' "${log_file}")
echo -e " Original: ${original}"
echo -e " Normalized: ${normalized}"
echo -e " ${GREEN}✓ Command succeeded (using fallback: ${normalized})${NC}"
else
echo -e " ${YELLOW}⚠ No log file (expected - model not in config)${NC}"
fi
else
echo -e " ${YELLOW}⚠ Command failed (expected - model not in config)${NC}"
fi
echo ""
# Test 3: Verify config location
echo -e "${YELLOW}Test 3: Verify config file location${NC}"
if [ -f "${REPO_DIR}/opencode.json" ]; then
plugin_path=$(jq -r '.plugin[0]' "${REPO_DIR}/opencode.json")
model_count=$(jq '.provider.openai.models | length' "${REPO_DIR}/opencode.json")
echo -e " Config file: ${REPO_DIR}/opencode.json"
echo -e " Plugin path: ${plugin_path}"
echo -e " Models defined: ${model_count}"
echo -e " ${GREEN}✓ Config file found and valid${NC}"
else
echo -e " ${RED}✗ No opencode.json in repo directory${NC}"
exit 1
fi
echo ""
echo -e "${GREEN}════════════════════════════════════════════${NC}"
echo -e "${GREEN} All validation tests passed!${NC}"
echo -e "${GREEN}════════════════════════════════════════════${NC}"
+14 -3
View File
@@ -69,12 +69,23 @@ describe('Request Transformer Module', () => {
expect(normalizeModel('gpt-5-codex-mini-medium')).toBe('codex-mini-latest');
expect(normalizeModel('gpt-5-codex-mini-high')).toBe('codex-mini-latest');
expect(normalizeModel('openai/gpt-5-codex-mini-high')).toBe('codex-mini-latest');
});
it('should normalize raw codex-mini-latest slug to codex-mini-latest', async () => {
expect(normalizeModel('codex-mini-latest')).toBe('codex-mini-latest');
expect(normalizeModel('openai/codex-mini-latest')).toBe('codex-mini-latest');
});
it('should normalize gpt-5.1 codex and mini slugs', async () => {
expect(normalizeModel('gpt-5.1-codex')).toBe('gpt-5.1-codex');
expect(normalizeModel('openai/gpt-5.1-codex')).toBe('gpt-5.1-codex');
expect(normalizeModel('gpt-5.1-codex-mini')).toBe('gpt-5.1-codex-mini');
expect(normalizeModel('gpt-5.1-codex-mini-high')).toBe('gpt-5.1-codex-mini');
expect(normalizeModel('openai/gpt-5.1-codex-mini-medium')).toBe('gpt-5.1-codex-mini');
});
it('should normalize gpt-5.1 general-purpose slugs', async () => {
expect(normalizeModel('gpt-5.1')).toBe('gpt-5.1');
expect(normalizeModel('openai/gpt-5.1')).toBe('gpt-5.1');
expect(normalizeModel('GPT 5.1 High')).toBe('gpt-5.1');
});
});
// NEW: Edge case tests