From 45c22d3ea9a758afaddd46286bfae3e59ea4d6c4 Mon Sep 17 00:00:00 2001 From: Filip Stastny Date: Mon, 7 Sep 2026 22:32:21 +0200 Subject: [PATCH] fix(agents): correctly recognize prefixed GPT-5.6 models in opencode and pi --- .../plugins/opencode/opencode-dynamic-models.ts | 12 ++++++++---- src/agents/plugins/pi/pi.models.ts | 6 +++--- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/agents/plugins/opencode/opencode-dynamic-models.ts b/src/agents/plugins/opencode/opencode-dynamic-models.ts index 528a82346..9ff57b9de 100644 --- a/src/agents/plugins/opencode/opencode-dynamic-models.ts +++ b/src/agents/plugins/opencode/opencode-dynamic-models.ts @@ -44,10 +44,14 @@ const RESPONSES_API_MODEL_PATTERNS: RegExp[] = [ /^gpt-5-4-/, // hyphenated variant of gpt-5.4-* /^gpt-5\.5-/, // gpt-5.5-2026-04-24 — same Azure restriction as gpt-5.4 /^gpt-5-5-/, // hyphenated variant of gpt-5.5-* - /^gpt-5\.6-/, // gpt-5.6-sol-2026-07-09 — same Azure restriction (tools + reasoning_effort) - /^gpt-5-6-/, // hyphenated variant of gpt-5.6-* + /gpt-5[.-]6/, // gpt-5.6-* (e.g. openai.gpt-5.6-luna) — same Azure restriction (tools + reasoning_effort) ]; +function isGpt56Model(id: string): boolean { + // Some deployments include a provider prefix (for example, openai.gpt-5.6-luna). + return /gpt-5[.-]6/.test(id); +} + function isResponsesApiModel(id: string): boolean { return RESPONSES_API_MODEL_PATTERNS.some(p => p.test(id)); } @@ -58,7 +62,7 @@ function detectFamily(id: string): string { if (id.startsWith('claude')) return 'claude-4'; if (id.startsWith('gemini')) return 'gemini-2'; if (id.startsWith('gpt-4')) return 'gpt-4'; - if (id.startsWith('gpt-5')) return 'gpt-5'; + if (id.startsWith('gpt-5') || isGpt56Model(id)) return 'gpt-5'; if (/^o[134]-/.test(id) || id === 'o1') return 'openai-reasoning'; if (id.startsWith('qwen')) return 'qwen3'; if (id.startsWith('deepseek')) return 'deepseek'; @@ -77,7 +81,7 @@ function detectLimits(id: string, family: string): { context: number; output: nu if (id.startsWith('gpt-4.1')) return { context: 1048576, output: 32768 }; if (id.startsWith('gpt-4o')) return { context: 128000, output: 16384 }; if (id.startsWith('gpt-5.5') || id.startsWith('gpt-5-5')) return { context: 1050000, output: 128000 }; // Azure-published window for gpt-5.5 - if (id.startsWith('gpt-5.6') || id.startsWith('gpt-5-6')) return { context: 1050000, output: 128000 }; // Azure-published window for gpt-5.6 + if (isGpt56Model(id)) return { context: 1050000, output: 128000 }; // Azure-published window for gpt-5.6 if (id.startsWith('gpt-5')) return { context: 400000, output: 128000 }; if (/^o[134]-/.test(id) || id === 'o1') return { context: 200000, output: 100000 }; if (id.startsWith('qwen') || id.startsWith('moonshotai') || id.startsWith('kimi')) return { context: 262144, output: 131072 }; diff --git a/src/agents/plugins/pi/pi.models.ts b/src/agents/plugins/pi/pi.models.ts index 6aefac7b0..8348de219 100644 --- a/src/agents/plugins/pi/pi.models.ts +++ b/src/agents/plugins/pi/pi.models.ts @@ -23,8 +23,7 @@ const RESPONSES_API_PATTERNS: RegExp[] = [ /^gpt-5-4-/, /^gpt-5\.5-/, /^gpt-5-5-/, - /^gpt-5\.6-/, - /^gpt-5-6-/, + /gpt-5[.-]6/, ]; export function classifyPiModel(modelId: string): PiModelClassification { @@ -69,7 +68,7 @@ function detectLimits(id: string): { contextWindow: number; maxTokens: number } if (id.startsWith('gemini')) return { contextWindow: 1048576, maxTokens: 65536 }; if (id.startsWith('gpt-4.1')) return { contextWindow: 1048576, maxTokens: 32768 }; if (/^gpt-5\.5-/.test(id) || /^gpt-5-5-/.test(id)) return { contextWindow: 1050000, maxTokens: 128000 }; - if (/^gpt-5\.6-/.test(id) || /^gpt-5-6-/.test(id)) return { contextWindow: 1050000, maxTokens: 128000 }; + if (/gpt-5[.-]6/.test(id)) return { contextWindow: 1050000, maxTokens: 128000 }; if (id.startsWith('gpt-5')) return { contextWindow: 400000, maxTokens: 128000 }; if (/^o[134]-/.test(id) || id === 'o1') return { contextWindow: 200000, maxTokens: 100000 }; if (id.startsWith('qwen') || id.startsWith('moonshotai') || id.startsWith('kimi')) { @@ -96,6 +95,7 @@ function isReasoningModel(id: string): boolean { id.startsWith('claude') || id.startsWith('gemini') || id.startsWith('gpt-5') || + /gpt-5[.-]6/.test(id) || /^o[134]-/.test(id) || id === 'o1' || id.startsWith('deepseek') ||