feat(catalog): updated model definitions and provider constraints
- Added `gpt-5.6-luna`, `gpt-5.6-sol`, and `gpt-5.6-terra` variants for the `opencode-zen` provider. - Removed deprecated `*-pro` model aliases from the `openai-codex` provider in `models.json`. - Updated `openai-compat.ts` to restrict pro-reasoning alias generation to the `openai` provider only. - Adjusted various model `contextWindow`, `maxTokens`, and `cost` parameters to reflect latest upstream metadata. - Added `perplexity-academic-researcher` model definition.
This commit is contained in:
@@ -2,6 +2,22 @@
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
|
||||
- Added GPT-5.6 Luna, Sol, and Terra models
|
||||
- Added perplexity-academic-researcher model
|
||||
|
||||
### Changed
|
||||
|
||||
- Updated context windows for multiple GPT-5.6 models
|
||||
- Increased max tokens for several models
|
||||
- Updated cache write costs for GPT-5.6 variants
|
||||
- Reduced pricing for select models
|
||||
|
||||
### Removed
|
||||
|
||||
- Removed pro-reasoning aliases for GPT-5.6 variants
|
||||
|
||||
## [16.4.0] - 2026-07-10
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
+227
-139
@@ -18667,7 +18667,7 @@
|
||||
"cacheRead": 0.2,
|
||||
"cacheWrite": 0
|
||||
},
|
||||
"contextWindow": 200000,
|
||||
"contextWindow": 1000000,
|
||||
"maxTokens": 64000,
|
||||
"headers": {
|
||||
"User-Agent": "opencode/1.3.15",
|
||||
@@ -19190,7 +19190,7 @@
|
||||
"cacheRead": 0.5,
|
||||
"cacheWrite": 0
|
||||
},
|
||||
"contextWindow": 400000,
|
||||
"contextWindow": 1050000,
|
||||
"maxTokens": 128000,
|
||||
"headers": {
|
||||
"User-Agent": "opencode/1.3.15",
|
||||
@@ -19207,6 +19207,108 @@
|
||||
},
|
||||
"contextPromotionTarget": "github-copilot/gpt-5.4"
|
||||
},
|
||||
"gpt-5.6-luna": {
|
||||
"id": "gpt-5.6-luna",
|
||||
"name": "GPT-5.6 Luna",
|
||||
"api": "openai-responses",
|
||||
"provider": "github-copilot",
|
||||
"baseUrl": "https://api.githubcopilot.com",
|
||||
"reasoning": true,
|
||||
"input": [
|
||||
"text",
|
||||
"image"
|
||||
],
|
||||
"cost": {
|
||||
"input": 1,
|
||||
"output": 6,
|
||||
"cacheRead": 0.1,
|
||||
"cacheWrite": 0
|
||||
},
|
||||
"contextWindow": 1050000,
|
||||
"maxTokens": 128000,
|
||||
"headers": {
|
||||
"User-Agent": "opencode/1.3.15",
|
||||
"X-GitHub-Api-Version": "2026-06-01"
|
||||
},
|
||||
"thinking": {
|
||||
"mode": "effort",
|
||||
"efforts": [
|
||||
"low",
|
||||
"medium",
|
||||
"high",
|
||||
"xhigh",
|
||||
"max"
|
||||
]
|
||||
}
|
||||
},
|
||||
"gpt-5.6-sol": {
|
||||
"id": "gpt-5.6-sol",
|
||||
"name": "GPT-5.6 Sol",
|
||||
"api": "openai-responses",
|
||||
"provider": "github-copilot",
|
||||
"baseUrl": "https://api.githubcopilot.com",
|
||||
"reasoning": true,
|
||||
"input": [
|
||||
"text",
|
||||
"image"
|
||||
],
|
||||
"cost": {
|
||||
"input": 5,
|
||||
"output": 30,
|
||||
"cacheRead": 0.5,
|
||||
"cacheWrite": 0
|
||||
},
|
||||
"contextWindow": 1050000,
|
||||
"maxTokens": 128000,
|
||||
"headers": {
|
||||
"User-Agent": "opencode/1.3.15",
|
||||
"X-GitHub-Api-Version": "2026-06-01"
|
||||
},
|
||||
"thinking": {
|
||||
"mode": "effort",
|
||||
"efforts": [
|
||||
"low",
|
||||
"medium",
|
||||
"high",
|
||||
"xhigh",
|
||||
"max"
|
||||
]
|
||||
}
|
||||
},
|
||||
"gpt-5.6-terra": {
|
||||
"id": "gpt-5.6-terra",
|
||||
"name": "GPT-5.6 Terra",
|
||||
"api": "openai-responses",
|
||||
"provider": "github-copilot",
|
||||
"baseUrl": "https://api.githubcopilot.com",
|
||||
"reasoning": true,
|
||||
"input": [
|
||||
"text",
|
||||
"image"
|
||||
],
|
||||
"cost": {
|
||||
"input": 2.5,
|
||||
"output": 15,
|
||||
"cacheRead": 0.25,
|
||||
"cacheWrite": 0
|
||||
},
|
||||
"contextWindow": 1050000,
|
||||
"maxTokens": 128000,
|
||||
"headers": {
|
||||
"User-Agent": "opencode/1.3.15",
|
||||
"X-GitHub-Api-Version": "2026-06-01"
|
||||
},
|
||||
"thinking": {
|
||||
"mode": "effort",
|
||||
"efforts": [
|
||||
"low",
|
||||
"medium",
|
||||
"high",
|
||||
"xhigh",
|
||||
"max"
|
||||
]
|
||||
}
|
||||
},
|
||||
"grok-code-fast-1": {
|
||||
"id": "grok-code-fast-1",
|
||||
"name": "Grok Code Fast 1",
|
||||
@@ -48660,6 +48762,25 @@
|
||||
"contextWindow": null,
|
||||
"maxTokens": null
|
||||
},
|
||||
"perplexity-academic-researcher": {
|
||||
"id": "perplexity-academic-researcher",
|
||||
"name": "perplexity-academic-researcher",
|
||||
"api": "openai-completions",
|
||||
"provider": "nanogpt",
|
||||
"baseUrl": "https://nano-gpt.com/api/v1",
|
||||
"reasoning": false,
|
||||
"input": [
|
||||
"text"
|
||||
],
|
||||
"cost": {
|
||||
"input": 0,
|
||||
"output": 0,
|
||||
"cacheRead": 0,
|
||||
"cacheWrite": 0
|
||||
},
|
||||
"contextWindow": null,
|
||||
"maxTokens": null
|
||||
},
|
||||
"phi-4-mini-instruct": {
|
||||
"id": "phi-4-mini-instruct",
|
||||
"name": "phi-4-mini-instruct",
|
||||
@@ -63390,47 +63511,6 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"gpt-5.6-luna-pro": {
|
||||
"id": "gpt-5.6-luna-pro",
|
||||
"name": "GPT-5.6 Luna Pro",
|
||||
"api": "openai-codex-responses",
|
||||
"provider": "openai-codex",
|
||||
"baseUrl": "https://chatgpt.com/backend-api",
|
||||
"reasoning": true,
|
||||
"input": [
|
||||
"text",
|
||||
"image"
|
||||
],
|
||||
"cost": {
|
||||
"input": 1,
|
||||
"output": 6,
|
||||
"cacheRead": 0.1,
|
||||
"cacheWrite": 1.25
|
||||
},
|
||||
"remoteCompaction": {
|
||||
"enabled": true,
|
||||
"api": "openai-codex-responses",
|
||||
"v2StreamingEnabled": true
|
||||
},
|
||||
"contextWindow": 372000,
|
||||
"maxTokens": 128000,
|
||||
"preferWebsockets": true,
|
||||
"useResponsesLite": true,
|
||||
"priority": 3,
|
||||
"requestModelId": "gpt-5.6-luna",
|
||||
"reasoningMode": "pro",
|
||||
"applyPatchToolType": "freeform",
|
||||
"thinking": {
|
||||
"mode": "effort",
|
||||
"efforts": [
|
||||
"low",
|
||||
"medium",
|
||||
"high",
|
||||
"xhigh",
|
||||
"max"
|
||||
]
|
||||
}
|
||||
},
|
||||
"gpt-5.6-sol": {
|
||||
"id": "gpt-5.6-sol",
|
||||
"name": "GPT-5.6 Sol",
|
||||
@@ -63470,47 +63550,6 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"gpt-5.6-sol-pro": {
|
||||
"id": "gpt-5.6-sol-pro",
|
||||
"name": "GPT-5.6 Sol Pro",
|
||||
"api": "openai-codex-responses",
|
||||
"provider": "openai-codex",
|
||||
"baseUrl": "https://chatgpt.com/backend-api",
|
||||
"reasoning": true,
|
||||
"input": [
|
||||
"text",
|
||||
"image"
|
||||
],
|
||||
"cost": {
|
||||
"input": 5,
|
||||
"output": 30,
|
||||
"cacheRead": 0.5,
|
||||
"cacheWrite": 6.25
|
||||
},
|
||||
"remoteCompaction": {
|
||||
"enabled": true,
|
||||
"api": "openai-codex-responses",
|
||||
"v2StreamingEnabled": true
|
||||
},
|
||||
"contextWindow": 372000,
|
||||
"maxTokens": 128000,
|
||||
"preferWebsockets": true,
|
||||
"useResponsesLite": true,
|
||||
"priority": 1,
|
||||
"requestModelId": "gpt-5.6-sol",
|
||||
"reasoningMode": "pro",
|
||||
"applyPatchToolType": "freeform",
|
||||
"thinking": {
|
||||
"mode": "effort",
|
||||
"efforts": [
|
||||
"low",
|
||||
"medium",
|
||||
"high",
|
||||
"xhigh",
|
||||
"max"
|
||||
]
|
||||
}
|
||||
},
|
||||
"gpt-5.6-terra": {
|
||||
"id": "gpt-5.6-terra",
|
||||
"name": "GPT-5.6 Terra",
|
||||
@@ -63549,47 +63588,6 @@
|
||||
"max"
|
||||
]
|
||||
}
|
||||
},
|
||||
"gpt-5.6-terra-pro": {
|
||||
"id": "gpt-5.6-terra-pro",
|
||||
"name": "GPT-5.6 Terra Pro",
|
||||
"api": "openai-codex-responses",
|
||||
"provider": "openai-codex",
|
||||
"baseUrl": "https://chatgpt.com/backend-api",
|
||||
"reasoning": true,
|
||||
"input": [
|
||||
"text",
|
||||
"image"
|
||||
],
|
||||
"cost": {
|
||||
"input": 2.5,
|
||||
"output": 15,
|
||||
"cacheRead": 0.25,
|
||||
"cacheWrite": 3.125
|
||||
},
|
||||
"remoteCompaction": {
|
||||
"enabled": true,
|
||||
"api": "openai-codex-responses",
|
||||
"v2StreamingEnabled": true
|
||||
},
|
||||
"contextWindow": 372000,
|
||||
"maxTokens": 128000,
|
||||
"preferWebsockets": true,
|
||||
"useResponsesLite": true,
|
||||
"priority": 2,
|
||||
"requestModelId": "gpt-5.6-terra",
|
||||
"reasoningMode": "pro",
|
||||
"applyPatchToolType": "freeform",
|
||||
"thinking": {
|
||||
"mode": "effort",
|
||||
"efforts": [
|
||||
"low",
|
||||
"medium",
|
||||
"high",
|
||||
"xhigh",
|
||||
"max"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"opencode": {
|
||||
@@ -65525,6 +65523,96 @@
|
||||
},
|
||||
"contextPromotionTarget": "opencode-zen/gpt-5.4"
|
||||
},
|
||||
"gpt-5.6-luna": {
|
||||
"id": "gpt-5.6-luna",
|
||||
"name": "GPT-5.6 Luna",
|
||||
"api": "openai-responses",
|
||||
"provider": "opencode-zen",
|
||||
"baseUrl": "https://opencode.ai/zen/v1",
|
||||
"reasoning": true,
|
||||
"input": [
|
||||
"text",
|
||||
"image"
|
||||
],
|
||||
"cost": {
|
||||
"input": 1,
|
||||
"output": 6,
|
||||
"cacheRead": 0.1,
|
||||
"cacheWrite": 1.25
|
||||
},
|
||||
"contextWindow": 1050000,
|
||||
"maxTokens": 128000,
|
||||
"thinking": {
|
||||
"mode": "effort",
|
||||
"efforts": [
|
||||
"low",
|
||||
"medium",
|
||||
"high",
|
||||
"xhigh",
|
||||
"max"
|
||||
]
|
||||
}
|
||||
},
|
||||
"gpt-5.6-sol": {
|
||||
"id": "gpt-5.6-sol",
|
||||
"name": "GPT-5.6 Sol",
|
||||
"api": "openai-responses",
|
||||
"provider": "opencode-zen",
|
||||
"baseUrl": "https://opencode.ai/zen/v1",
|
||||
"reasoning": true,
|
||||
"input": [
|
||||
"text",
|
||||
"image"
|
||||
],
|
||||
"cost": {
|
||||
"input": 5,
|
||||
"output": 30,
|
||||
"cacheRead": 0.5,
|
||||
"cacheWrite": 6.25
|
||||
},
|
||||
"contextWindow": 1050000,
|
||||
"maxTokens": 128000,
|
||||
"thinking": {
|
||||
"mode": "effort",
|
||||
"efforts": [
|
||||
"low",
|
||||
"medium",
|
||||
"high",
|
||||
"xhigh",
|
||||
"max"
|
||||
]
|
||||
}
|
||||
},
|
||||
"gpt-5.6-terra": {
|
||||
"id": "gpt-5.6-terra",
|
||||
"name": "GPT-5.6 Terra",
|
||||
"api": "openai-responses",
|
||||
"provider": "opencode-zen",
|
||||
"baseUrl": "https://opencode.ai/zen/v1",
|
||||
"reasoning": true,
|
||||
"input": [
|
||||
"text",
|
||||
"image"
|
||||
],
|
||||
"cost": {
|
||||
"input": 2.5,
|
||||
"output": 15,
|
||||
"cacheRead": 0.25,
|
||||
"cacheWrite": 3.125
|
||||
},
|
||||
"contextWindow": 1050000,
|
||||
"maxTokens": 128000,
|
||||
"thinking": {
|
||||
"mode": "effort",
|
||||
"efforts": [
|
||||
"low",
|
||||
"medium",
|
||||
"high",
|
||||
"xhigh",
|
||||
"max"
|
||||
]
|
||||
}
|
||||
},
|
||||
"grok-4.5": {
|
||||
"id": "grok-4.5",
|
||||
"name": "Grok 4.5",
|
||||
@@ -65601,7 +65689,7 @@
|
||||
"cacheRead": 0,
|
||||
"cacheWrite": 0
|
||||
},
|
||||
"contextWindow": 256000,
|
||||
"contextWindow": 190000,
|
||||
"maxTokens": 64000,
|
||||
"thinking": {
|
||||
"mode": "effort",
|
||||
@@ -68111,13 +68199,13 @@
|
||||
"text"
|
||||
],
|
||||
"cost": {
|
||||
"input": 0.09,
|
||||
"output": 0.18,
|
||||
"cacheRead": 0.018,
|
||||
"input": 0.08399999999999999,
|
||||
"output": 0.16799999999999998,
|
||||
"cacheRead": 0.016800000000000002,
|
||||
"cacheWrite": 0
|
||||
},
|
||||
"contextWindow": 1048576,
|
||||
"maxTokens": 65536,
|
||||
"maxTokens": 384000,
|
||||
"thinking": {
|
||||
"mode": "effort",
|
||||
"efforts": [
|
||||
@@ -75529,9 +75617,9 @@
|
||||
"text"
|
||||
],
|
||||
"cost": {
|
||||
"input": 0.77,
|
||||
"output": 2.42,
|
||||
"cacheRead": 0.143,
|
||||
"input": 0.42,
|
||||
"output": 1.32,
|
||||
"cacheRead": 0.078,
|
||||
"cacheWrite": 0
|
||||
},
|
||||
"contextWindow": 1048576,
|
||||
@@ -79347,7 +79435,7 @@
|
||||
"input": 1.25,
|
||||
"output": 7.5,
|
||||
"cacheRead": 0.125,
|
||||
"cacheWrite": 0
|
||||
"cacheWrite": 1.5625
|
||||
},
|
||||
"contextWindow": 1000000,
|
||||
"maxTokens": 128000,
|
||||
@@ -79377,7 +79465,7 @@
|
||||
"input": 1.25,
|
||||
"output": 7.5,
|
||||
"cacheRead": 0.125,
|
||||
"cacheWrite": 0
|
||||
"cacheWrite": 1.5625
|
||||
},
|
||||
"contextWindow": 1000000,
|
||||
"maxTokens": 128000,
|
||||
@@ -79407,7 +79495,7 @@
|
||||
"input": 6.25,
|
||||
"output": 37.5,
|
||||
"cacheRead": 0.625,
|
||||
"cacheWrite": 0
|
||||
"cacheWrite": 7.8125
|
||||
},
|
||||
"contextWindow": 1000000,
|
||||
"maxTokens": 128000,
|
||||
@@ -79437,7 +79525,7 @@
|
||||
"input": 6.25,
|
||||
"output": 37.5,
|
||||
"cacheRead": 0.625,
|
||||
"cacheWrite": 0
|
||||
"cacheWrite": 7.8125
|
||||
},
|
||||
"contextWindow": 1000000,
|
||||
"maxTokens": 128000,
|
||||
@@ -79467,7 +79555,7 @@
|
||||
"input": 3.125,
|
||||
"output": 18.75,
|
||||
"cacheRead": 0.3125,
|
||||
"cacheWrite": 0
|
||||
"cacheWrite": 3.90625
|
||||
},
|
||||
"contextWindow": 1000000,
|
||||
"maxTokens": 128000,
|
||||
@@ -79497,7 +79585,7 @@
|
||||
"input": 3.125,
|
||||
"output": 18.75,
|
||||
"cacheRead": 0.3125,
|
||||
"cacheWrite": 0
|
||||
"cacheWrite": 3.90625
|
||||
},
|
||||
"contextWindow": 1000000,
|
||||
"maxTokens": 128000,
|
||||
|
||||
@@ -823,17 +823,23 @@ const OPENAI_PRO_REASONING_BASE_IDS: Record<string, true> = {
|
||||
"gpt-5.6-sol": true,
|
||||
"gpt-5.6-terra": true,
|
||||
};
|
||||
const OPENAI_PRO_REASONING_PROVIDERS: Record<string, true> = { openai: true, "openai-codex": true };
|
||||
/**
|
||||
* Providers whose generated pro aliases this pass owns. `openai-codex` stays in
|
||||
* the sweep so stale aliases from earlier snapshots are dropped on regen, but
|
||||
* projection is `openai`-only — subscription (Codex) auth does not offer pro
|
||||
* reasoning.
|
||||
*/
|
||||
const OPENAI_PRO_REASONING_SWEEP_PROVIDERS: Record<string, true> = { openai: true, "openai-codex": true };
|
||||
|
||||
/**
|
||||
* A row this generator pass owns: one of the derived `gpt-5.6-*-pro` alias ids
|
||||
* on `openai`/`openai-codex` that carries the generated `reasoningMode` marker.
|
||||
* on a swept provider that carries the generated `reasoningMode` marker.
|
||||
* A real upstream model occupying the same id has no `reasoningMode` and is
|
||||
* never touched.
|
||||
*/
|
||||
function isGeneratedOpenAIProReasoningAlias(model: ModelSpec<Api>): boolean {
|
||||
return (
|
||||
OPENAI_PRO_REASONING_PROVIDERS[model.provider] === true &&
|
||||
OPENAI_PRO_REASONING_SWEEP_PROVIDERS[model.provider] === true &&
|
||||
model.reasoningMode !== undefined &&
|
||||
model.id.endsWith("-pro") &&
|
||||
OPENAI_PRO_REASONING_BASE_IDS[model.id.slice(0, -"-pro".length)] === true
|
||||
@@ -842,21 +848,21 @@ function isGeneratedOpenAIProReasoningAlias(model: ModelSpec<Api>): boolean {
|
||||
|
||||
/**
|
||||
* Re-derive the generated pro-reasoning aliases (`gpt-5.6-*-pro`) for the
|
||||
* first-party `openai`/`openai-codex` gpt-5.6 rows. Each alias inherits the
|
||||
* base row's metadata, requests the base wire id via `requestModelId`, and
|
||||
* sets `reasoningMode: "pro"` so Responses-family request builders emit
|
||||
* first-party `openai` gpt-5.6 rows. Each alias inherits the base row's
|
||||
* metadata, requests the base wire id via `requestModelId`, and sets
|
||||
* `reasoningMode: "pro"` so Responses-family request builders emit
|
||||
* `reasoning: { mode: "pro" }`. Called by the models.json generator after all
|
||||
* sources merge: stale copies of the owned aliases (previous snapshot) are
|
||||
* dropped and re-projected from the current base rows so alias metadata always
|
||||
* tracks the base, while a real upstream model that occupies an alias id wins
|
||||
* and suppresses the projection.
|
||||
* sources merge: stale copies of the owned aliases (previous snapshot,
|
||||
* including retired `openai-codex` rows) are dropped and re-projected from the
|
||||
* current base rows so alias metadata always tracks the base, while a real
|
||||
* upstream model that occupies an alias id wins and suppresses the projection.
|
||||
*/
|
||||
export function projectOpenAIProReasoningAliases(models: readonly ModelSpec<Api>[]): ModelSpec<Api>[] {
|
||||
const kept = models.filter(model => !isGeneratedOpenAIProReasoningAlias(model));
|
||||
const ids = new Set(kept.map(model => `${model.provider}/${model.id}`));
|
||||
const out = [...kept];
|
||||
for (const model of kept) {
|
||||
if (!OPENAI_PRO_REASONING_PROVIDERS[model.provider]) continue;
|
||||
if (model.provider !== "openai") continue;
|
||||
if (!OPENAI_PRO_REASONING_BASE_IDS[model.id]) continue;
|
||||
const aliasId = `${model.id}-pro`;
|
||||
const aliasKey = `${model.provider}/${aliasId}`;
|
||||
|
||||
Reference in New Issue
Block a user