From 3263793861433ebc5c9cc877a4707cf10b8b4308 Mon Sep 17 00:00:00 2001 From: cyberprophet Date: Sun, 8 Mar 2026 11:12:25 +0900 Subject: [PATCH 1/2] fix(think-mode): remove gpt-5-nano from HIGH_VARIANT_MAP and tighten Korean keyword matching MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two independent bugs caused 'Model not found: opencode/gpt-5-nano-high': 1. gpt-5-nano was mapped to gpt-5-nano-high in HIGH_VARIANT_MAP, but this variant does not exist on the OpenCode Zen provider. gpt-5-nano is a lightweight nano model with no reasoning/high-effort variant. 2. The Korean word '고민' (to worry/ponder) was listed as a think-mode trigger keyword. It is a common conversational word that fires think mode on everyday sentences like '어떻게 할지 고민하고 있었는데' (I was wondering how to...). Replaced with explicit reasoning-request forms only: '생각해줘', '깊이 생각', '신중하게 검토'. Fixes: https://github.com/code-yeongyu/oh-my-openagent/issues/2382 --- src/hooks/think-mode/detector.ts | 6 ++- src/hooks/think-mode/index.test.ts | 67 +++++++++++++++++++++++++++ src/hooks/think-mode/switcher.test.ts | 7 +++ src/hooks/think-mode/switcher.ts | 4 +- 4 files changed, 82 insertions(+), 2 deletions(-) diff --git a/src/hooks/think-mode/detector.ts b/src/hooks/think-mode/detector.ts index f67cfc703b..a35c0fa9c2 100644 --- a/src/hooks/think-mode/detector.ts +++ b/src/hooks/think-mode/detector.ts @@ -1,7 +1,11 @@ const ENGLISH_PATTERNS = [/\bultrathink\b/i, /\bthink\b/i] const MULTILINGUAL_KEYWORDS = [ - "생각", "고민", "검토", "제대로", + // Korean: intentionally use only explicit reasoning-request forms. + // "고민" (“to worry/ponder”) is excluded — it is a common conversational word + // that fires think mode on everyday sentences like "어떻게 할지 고민하고 있었는데". + // Only "생각해줘" / "깊이 생각" style explicit directives should trigger think mode. + "생각해줘", "깊이 생각", "신중하게 검토", "제대로", "思考", "考虑", "考慮", "思考", "考え", "熟考", "सोच", "विचार", diff --git a/src/hooks/think-mode/index.test.ts b/src/hooks/think-mode/index.test.ts index e135412db4..4aaa98ef74 100644 --- a/src/hooks/think-mode/index.test.ts +++ b/src/hooks/think-mode/index.test.ts @@ -153,3 +153,70 @@ describe("createThinkModeHook", () => { expect(output.message.model).toBeUndefined() }) }) + +describe("think-mode: regression tests for issue #2382", () => { + const sessionID = "regression-2382" + + beforeEach(() => { + clearThinkModeState(sessionID) + }) + + it("does NOT activate think mode for conversational Korean '고민' (to worry/ponder)", async () => { + // given — a real user sentence that triggered the bug: + // "너와 인공지능 엔진에게 이미지와 참조 자료를 어떻게 전달할지 고민하고 있었는데" + const hook = createThinkModeHook() + const input = createHookInput({ + sessionID, + providerID: "opencode", + modelID: "gpt-5-nano", + }) + const output = createHookOutput( + "너와 인공지능 엔진에게 이미지와 참조 자료를 어떻게 전달할지 고민하고 있었는데" + ) + + // when + await hook["chat.message"](input, output) + + // then — model must NOT be upgraded; '고민' is conversational, not a reasoning directive + expect(output.message.variant).toBeUndefined() + expect(output.message.model).toBeUndefined() + }) + + it("does NOT upgrade gpt-5-nano even when think keyword IS present", async () => { + // given — gpt-5-nano has no -high variant on Zen; upgrading it causes Model not found + const hook = createThinkModeHook() + const input = createHookInput({ + sessionID, + providerID: "opencode", + modelID: "gpt-5-nano", + }) + const output = createHookOutput("신중하게 검토해줘") + + // when + await hook["chat.message"](input, output) + + // then — no high variant exists for gpt-5-nano, so model stays unchanged + expect(output.message.model).toBeUndefined() + }) + + it("still activates think mode for explicit Korean reasoning directive '생각해줘'", async () => { + // given — explicit reasoning request should still trigger think mode on capable models + const hook = createThinkModeHook() + const input = createHookInput({ + sessionID, + providerID: "anthropic", + modelID: "claude-opus-4-6", + }) + const output = createHookOutput("이 문제 깊이 생각해줘") + + // when + await hook["chat.message"](input, output) + + // then — explicit directive on a capable model should still upgrade + expect(output.message.variant).toBe("high") + expect(output.message.model).toEqual({ + providerID: "anthropic", + modelID: "claude-opus-4-6-high", + }) + }) +}) diff --git a/src/hooks/think-mode/switcher.test.ts b/src/hooks/think-mode/switcher.test.ts index e56ec5823d..670717e0f3 100644 --- a/src/hooks/think-mode/switcher.test.ts +++ b/src/hooks/think-mode/switcher.test.ts @@ -69,6 +69,13 @@ describe("think-mode switcher", () => { expect(getHighVariant("llama-3-70b")).toBeNull() expect(getHighVariant("mistral-large")).toBeNull() }) + + it("should return null for gpt-5-nano (no reasoning variant on Zen)", () => { + // given gpt-5-nano — a lightweight model with no high variant on OpenCode Zen + // see: https://github.com/code-yeongyu/oh-my-openagent/issues/2382 + expect(getHighVariant("gpt-5-nano")).toBeNull() + expect(getHighVariant("opencode/gpt-5-nano")).toBeNull() + }) }) }) diff --git a/src/hooks/think-mode/switcher.ts b/src/hooks/think-mode/switcher.ts index f458d9b663..fe4ff28645 100644 --- a/src/hooks/think-mode/switcher.ts +++ b/src/hooks/think-mode/switcher.ts @@ -50,9 +50,11 @@ const HIGH_VARIANT_MAP: Record = { "gemini-3-1-pro-low": "gemini-3-1-pro-high", "gemini-3-flash": "gemini-3-flash-high", // GPT-5 + // NOTE: gpt-5-nano is intentionally excluded — it is a lightweight nano model + // that does not have a reasoning/high-effort variant on the OpenCode Zen provider. + // Mapping it to gpt-5-nano-high causes a "Model not found" error. "gpt-5": "gpt-5-high", "gpt-5-mini": "gpt-5-mini-high", - "gpt-5-nano": "gpt-5-nano-high", "gpt-5-pro": "gpt-5-pro-high", "gpt-5-chat-latest": "gpt-5-chat-latest-high", // GPT-5.1 From 877aa486c8e936c256a48b1e3f304087f5aea60b Mon Sep 17 00:00:00 2001 From: cyberprophet Date: Sun, 8 Mar 2026 11:23:41 +0900 Subject: [PATCH 2/2] fix(think-mode): keep Korean triggers and skip gpt-5-nano high upgrade MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Preserve existing multilingual think-mode detection, including Korean trigger words like "고민", while limiting the fix to the actual incompatibility: gpt-5-nano has no supported high variant on the OpenCode Zen provider. This keeps existing Sonnet/Opus high-variant behavior intact on the same trigger text and prevents Model not found: opencode/gpt-5-nano-high. Refs: https://github.com/code-yeongyu/oh-my-openagent/issues/2382 --- src/hooks/think-mode/detector.ts | 6 +----- src/hooks/think-mode/index.test.ts | 34 ++++++------------------------ 2 files changed, 8 insertions(+), 32 deletions(-) diff --git a/src/hooks/think-mode/detector.ts b/src/hooks/think-mode/detector.ts index a35c0fa9c2..f67cfc703b 100644 --- a/src/hooks/think-mode/detector.ts +++ b/src/hooks/think-mode/detector.ts @@ -1,11 +1,7 @@ const ENGLISH_PATTERNS = [/\bultrathink\b/i, /\bthink\b/i] const MULTILINGUAL_KEYWORDS = [ - // Korean: intentionally use only explicit reasoning-request forms. - // "고민" (“to worry/ponder”) is excluded — it is a common conversational word - // that fires think mode on everyday sentences like "어떻게 할지 고민하고 있었는데". - // Only "생각해줘" / "깊이 생각" style explicit directives should trigger think mode. - "생각해줘", "깊이 생각", "신중하게 검토", "제대로", + "생각", "고민", "검토", "제대로", "思考", "考虑", "考慮", "思考", "考え", "熟考", "सोच", "विचार", diff --git a/src/hooks/think-mode/index.test.ts b/src/hooks/think-mode/index.test.ts index 4aaa98ef74..911c4dce61 100644 --- a/src/hooks/think-mode/index.test.ts +++ b/src/hooks/think-mode/index.test.ts @@ -161,9 +161,7 @@ describe("think-mode: regression tests for issue #2382", () => { clearThinkModeState(sessionID) }) - it("does NOT activate think mode for conversational Korean '고민' (to worry/ponder)", async () => { - // given — a real user sentence that triggered the bug: - // "너와 인공지능 엔진에게 이미지와 참조 자료를 어떻게 전달할지 고민하고 있었는데" + it("does NOT upgrade gpt-5-nano on Korean think-mode trigger text", async () => { const hook = createThinkModeHook() const input = createHookInput({ sessionID, @@ -177,46 +175,28 @@ describe("think-mode: regression tests for issue #2382", () => { // when await hook["chat.message"](input, output) - // then — model must NOT be upgraded; '고민' is conversational, not a reasoning directive expect(output.message.variant).toBeUndefined() expect(output.message.model).toBeUndefined() }) - it("does NOT upgrade gpt-5-nano even when think keyword IS present", async () => { - // given — gpt-5-nano has no -high variant on Zen; upgrading it causes Model not found - const hook = createThinkModeHook() - const input = createHookInput({ - sessionID, - providerID: "opencode", - modelID: "gpt-5-nano", - }) - const output = createHookOutput("신중하게 검토해줘") - - // when - await hook["chat.message"](input, output) - - // then — no high variant exists for gpt-5-nano, so model stays unchanged - expect(output.message.model).toBeUndefined() - }) - - it("still activates think mode for explicit Korean reasoning directive '생각해줘'", async () => { - // given — explicit reasoning request should still trigger think mode on capable models + it("still upgrades claude-sonnet-4-6 on the same Korean think-mode trigger text", async () => { const hook = createThinkModeHook() const input = createHookInput({ sessionID, providerID: "anthropic", - modelID: "claude-opus-4-6", + modelID: "claude-sonnet-4-6", }) - const output = createHookOutput("이 문제 깊이 생각해줘") + const output = createHookOutput( + "너와 인공지능 엔진에게 이미지와 참조 자료를 어떻게 전달할지 고민하고 있었는데" + ) // when await hook["chat.message"](input, output) - // then — explicit directive on a capable model should still upgrade expect(output.message.variant).toBe("high") expect(output.message.model).toEqual({ providerID: "anthropic", - modelID: "claude-opus-4-6-high", + modelID: "claude-sonnet-4-6-high", }) }) })