浏览代码

fix(core): tighten ChatGPT codex model eligibility

Replace the codex-substring heuristic with the empirically verified
allow/disallow lists plus the >5.4 version rule; the ChatGPT backend
rejects models like gpt-5.3-codex that the substring rule admitted.
Kit Langton 1 月之前
父节点
当前提交
f019bb3abf
共有 2 个文件被更改,包括 16 次插入7 次删除
  1. 10 3
      packages/core/src/plugin/provider/openai.ts
  2. 6 4
      packages/core/test/plugin/provider-openai.test.ts

+ 10 - 3
packages/core/src/plugin/provider/openai.ts

@@ -181,7 +181,7 @@ export const OpenAIPlugin = define({
           if (!chatgpt) continue
           for (const model of item.models.values()) {
             evt.model.update(item.provider.id, model.id, (draft) => {
-              if (!eligible(draft)) {
+              if (!eligible(draft.api.id)) {
                 draft.enabled = false
                 return
               }
@@ -316,8 +316,15 @@ function isChatGPT(credential: { readonly type: string; readonly methodID?: stri
   )
 }
 
-function eligible(model: { readonly id: string }) {
-  return model.id.includes("codex")
+const chatgptAllowed = new Set(["gpt-5.5", "gpt-5.3-codex-spark", "gpt-5.4", "gpt-5.4-mini"])
+const chatgptDisallowed = new Set(["gpt-5.5-pro"])
+
+/** Which API model ids a ChatGPT subscription may call through the codex backend. */
+function eligible(apiID: string) {
+  if (chatgptAllowed.has(apiID)) return true
+  if (chatgptDisallowed.has(apiID)) return false
+  const match = apiID.match(/^gpt-(\d+\.\d+)/)
+  return match ? Number.parseFloat(match[1]) > 5.4 : false
 }
 
 function claim(token: string) {

+ 6 - 4
packages/core/test/plugin/provider-openai.test.ts

@@ -182,8 +182,8 @@ describe("OpenAIPlugin", () => {
         catalog.provider.update(item.id, (draft) => {
           draft.api = item.api
         })
-        catalog.model.update(item.id, ModelV2.ID.make("gpt-5-codex"), (draft) => {
-          draft.api = { id: ModelV2.ID.make("gpt-5-codex"), type: "aisdk", package: "@ai-sdk/openai" }
+        catalog.model.update(item.id, ModelV2.ID.make("gpt-5.3-codex-spark"), (draft) => {
+          draft.api = { id: ModelV2.ID.make("gpt-5.3-codex-spark"), type: "aisdk", package: "@ai-sdk/openai" }
           draft.cost = [{ input: 1, output: 2, cache: { read: 3, write: 4 } }]
         })
         catalog.model.update(item.id, ModelV2.ID.make("gpt-5"), (draft) => {
@@ -204,11 +204,13 @@ describe("OpenAIPlugin", () => {
 
       yield* addPlugin()
 
-      expect(required(yield* catalog.model.get(ProviderV2.ID.openai, ModelV2.ID.make("gpt-5-codex")))).toMatchObject({
+      expect(
+        required(yield* catalog.model.get(ProviderV2.ID.openai, ModelV2.ID.make("gpt-5.3-codex-spark"))),
+      ).toMatchObject({
         enabled: true,
         api: {
           type: "native",
-          id: "gpt-5-codex",
+          id: "gpt-5.3-codex-spark",
           package: "@opencode-ai/llm/providers/openai/codex",
           settings: { store: false },
         },