From 33ef9c0d36a529cd12d004de958d43d5bda09cdb Mon Sep 17 00:00:00 2001 From: Oleg Samarin Date: Thu, 7 May 2026 17:28:08 +0300 Subject: [PATCH] Fixed model list showing garbled names with 1M-context menu format MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ModelMenuParser is now always the primary extractor in discoverModels(). The hand-rolled descPat approach (applied to ChoiceMenuModel options) is kept as a fallback only. This fixes garbled names like "Mtoket 4.6 with 1M context" caused by the new /model menu format that includes 1M-context variants and cost annotations (e.g. · $3/$15 per Mtok). Added fixture test case format1-with-1m-context to ModelMenuParserTest covering the full 5-option menu with wrapped lines and footer text. Co-Authored-By: Claude Sonnet 4.6 --- CHANGELOG.md | 2 ++ pom.xml | 2 +- .../controller/ClaudeSessionController.java | 14 +++++++++---- .../format1-with-1m-context.expected.json | 1 + .../format1-with-1m-context.src.txt | 20 +++++++++++++++++++ 5 files changed, 34 insertions(+), 5 deletions(-) create mode 100644 src/test/resources/io/github/nbclaudecodegui/process/model-menu-parser/format1-with-1m-context.expected.json create mode 100644 src/test/resources/io/github/nbclaudecodegui/process/model-menu-parser/format1-with-1m-context.src.txt diff --git a/CHANGELOG.md b/CHANGELOG.md index 121b28db..9e6c5fe8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,5 @@ +- Fixed model list showing garbled names (e.g. "Mtoket 4.6 with 1M context") when the /model menu includes 1M-context variants and cost annotations + # 0.22.30 (2026-05-05) - Fixed digits going into the "Type something." text field instead of selecting the intended numbered option in planning and permission-prompt choice menus diff --git a/pom.xml b/pom.xml index 3822d397..2356e96b 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.github.nbclaudecodegui netbeans-claude-code-gui - 0.22.46-SNAPSHOT + 0.22.47-SNAPSHOT nbm Netbeans Plugin Claude Code GUI NetBeans plugin that provides a GUI for Claude Code CLI — run claude code sessions directly inside the IDE. diff --git a/src/main/java/io/github/nbclaudecodegui/controller/ClaudeSessionController.java b/src/main/java/io/github/nbclaudecodegui/controller/ClaudeSessionController.java index 22dfc5e6..c83ac1fe 100644 --- a/src/main/java/io/github/nbclaudecodegui/controller/ClaudeSessionController.java +++ b/src/main/java/io/github/nbclaudecodegui/controller/ClaudeSessionController.java @@ -887,7 +887,14 @@ void discoverModels() { List models; int selIdx; - if (menuOpt.isPresent() && !menuOpt.get().options().isEmpty()) { + // Always prefer ModelMenuParser — it is fixture-tested and handles all known + // formats including 1M-context variants. The ChoiceMenuModel path is kept as + // a fallback for formats that ModelMenuParser does not recognise. + ModelMenuParser.ModelDiscovery discovery = new ModelMenuParser().parse(lines); + if (!discovery.models().isEmpty()) { + models = discovery.models(); + selIdx = discovery.currentIndex(); + } else if (menuOpt.isPresent() && !menuOpt.get().options().isEmpty()) { List opts = menuOpt.get().options(); Pattern descPat = Pattern.compile("(?:\u2714\\s+|\\s{2,})(.+?)(?:\\s*[·\u00b7].*)?$"); Pattern currentlyPat = Pattern.compile("\\(currently\\s+([^)]+?)\\s*\\)"); @@ -909,9 +916,8 @@ void discoverModels() { if (display.contains("\u2714")) selIdx = i; } } else { - ModelMenuParser.ModelDiscovery discovery = new ModelMenuParser().parse(lines); - models = discovery.models(); - selIdx = discovery.currentIndex(); + models = List.of(); + selIdx = -1; } connector.write(new byte[]{0x1b}); // Esc — dismiss model menu diff --git a/src/test/resources/io/github/nbclaudecodegui/process/model-menu-parser/format1-with-1m-context.expected.json b/src/test/resources/io/github/nbclaudecodegui/process/model-menu-parser/format1-with-1m-context.expected.json new file mode 100644 index 00000000..df7a2427 --- /dev/null +++ b/src/test/resources/io/github/nbclaudecodegui/process/model-menu-parser/format1-with-1m-context.expected.json @@ -0,0 +1 @@ +{"models": ["Sonnet 4.6", "Sonnet 4.6 with 1M context", "Opus 4.7", "Opus 4.7 with 1M context", "Haiku 4.5"], "currentIndex": 0} diff --git a/src/test/resources/io/github/nbclaudecodegui/process/model-menu-parser/format1-with-1m-context.src.txt b/src/test/resources/io/github/nbclaudecodegui/process/model-menu-parser/format1-with-1m-context.src.txt new file mode 100644 index 00000000..ce94f075 --- /dev/null +++ b/src/test/resources/io/github/nbclaudecodegui/process/model-menu-parser/format1-with-1m-context.src.txt @@ -0,0 +1,20 @@ + +─────────────────────────────────────────────────────────────────────────────────────────────────────────────── + Select model + Switch between Claude models. Applies to this session and future Claude Code sessions. For other/previous + model names, specify with --model. + + ❯ 1. Default (recommended) ✔ Sonnet 4.6 · Best for everyday tasks + 2. Sonnet (1M context) Sonnet 4.6 with 1M context · Billed as extra usage · $3/$15 per Mtok + 3. Opus Opus 4.7 · Most capable for complex work · ~2× usage vs Sonnet + 4. Opus 4.7 (1M context) Opus 4.7 with 1M context · ~2× usage vs Sonnet · Billed as extra usage · + $5/$25 per Mtok + 5. Haiku Haiku 4.5 · Fastest for quick answers + + ○ Low effort ← → to adjust + + Use /fast to turn on Fast mode (Opus 4.6 only). + + Enter to confirm · Esc to exit + +