mirror of
https://github.com/zhukunpenglinyutong/jetbrains-cc-gui.git
synced 2026-09-21 14:06:54 +08:00
Bring emergency main fixes into v0.4.7 work
Main carries the v0.4.6-fix1 hotfix merge. This merge preserves the current feature/v0.4.7 branch while applying those fixes, with the CLI-login API config test resolved by combining the stricter inherited-env guard from the branch with the explicit empty Claude settings fixture from main. Constraint: Current branch needed emergency fixes already landed on origin/main Rejected: Cherry-pick the hotfix commit | merging origin/main preserves upstream history and future conflict context Confidence: high Scope-risk: moderate Directive: Keep CLI-login host-managed regression coverage aligned when changing provider env handling Tested: node --test ai-bridge/config/api-config.test.js Not-tested: Full Gradle and webview suites
This commit is contained in:
@@ -1,3 +1,19 @@
|
||||
##### **2026年7月6日(v0.4.6-fix1)**
|
||||
|
||||
English:
|
||||
|
||||
🐛 Fixes
|
||||
- Fix Claude CLI login being treated as a host-managed provider: when `access` is `cli_login`, the bridge now leaves `CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST` unset, avoiding the host-managed credential path for users already authenticated through the Claude CLI (by @zkpaiminmin)
|
||||
- Fix Claude model metadata after the lineup update: replace the retired `claude-opus-4-7` built-in option with `claude-opus-4-8`, and add `claude-sonnet-5` with 200K / 1M context handling, max reasoning support, usage pricing, model mapping, and localized labels across all supported languages (by @zkpaiminmin)
|
||||
|
||||
中文:
|
||||
|
||||
🐛 修复
|
||||
- 修复 Claude CLI 登录被误判为 host-managed provider:当认证状态为 `cli_login` 时,bridge 不再设置 `CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST`,避免已通过 Claude CLI 登录的用户走错 host-managed 凭证路径(by @zkpaiminmin)
|
||||
- 修复 Claude 模型清单与元数据滞后:内置模型移除已下线的 `claude-opus-4-7`,切换到 `claude-opus-4-8`,并新增 `claude-sonnet-5` 的 200K / 1M 上下文、max reasoning、用量计价、模型映射和全语言本地化标签(by @zkpaiminmin)
|
||||
|
||||
---
|
||||
|
||||
##### **2026年6月28日(v0.4.6)**
|
||||
|
||||
English:
|
||||
|
||||
@@ -231,7 +231,7 @@ export function buildWebviewControlledSettingsOverride(modelId) {
|
||||
* Reads settings via loadClaudeSettings() (same source as setupApiKey) so the
|
||||
* auth-decision and the provider-management-decision always see the same env.
|
||||
*
|
||||
* @returns {boolean} true unless a cloud provider switch is active in settings.
|
||||
* @returns {boolean} true unless CLI login or a cloud provider switch is active.
|
||||
*/
|
||||
function shouldHostManageProvider() {
|
||||
if (getClaudeRuntimeState().access === 'cli_login') {
|
||||
|
||||
@@ -306,6 +306,7 @@ test('buildCliEnv leaves CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST unset for CLI logi
|
||||
// inherited copy from a parent Claude Code host.
|
||||
const tempHome = fs.mkdtempSync(path.join(os.tmpdir(), 'cc-gui-api-config-'));
|
||||
writeCodemossClaudeConfig(tempHome, '__cli_login__');
|
||||
writeClaudeSettingsEnv(tempHome, {});
|
||||
|
||||
const env = runBuildCliEnv(tempHome);
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ test('resolvePromptEnhancerRuntimeConfig throws a strict error when manual provi
|
||||
effectiveProvider: null,
|
||||
resolutionSource: 'unavailable',
|
||||
models: {
|
||||
claude: 'claude-opus-4-7',
|
||||
claude: 'claude-opus-4-8',
|
||||
codex: 'gpt-5.4',
|
||||
},
|
||||
availability: {
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
// --- mapModelIdToSdkName ------------------------------------------------
|
||||
|
||||
test('mapModelIdToSdkName maps Claude families to short SDK names', () => {
|
||||
assert.equal(mapModelIdToSdkName('claude-opus-4-7'), 'opus');
|
||||
assert.equal(mapModelIdToSdkName('claude-opus-4-8'), 'opus');
|
||||
assert.equal(mapModelIdToSdkName('claude-haiku-4-5'), 'haiku');
|
||||
assert.equal(mapModelIdToSdkName('claude-sonnet-4-6'), 'sonnet');
|
||||
// Unknown / third-party IDs fall back to sonnet (because the SDK uses
|
||||
@@ -34,7 +34,7 @@ test('resolveModelFromSettings applies model-specific settings mapping', () => {
|
||||
ANTHROPIC_DEFAULT_SONNET_MODEL: 'glm-4.7',
|
||||
ANTHROPIC_DEFAULT_HAIKU_MODEL: 'glm-4.7-flash',
|
||||
};
|
||||
assert.equal(resolveModelFromSettings('claude-opus-4-7', env), 'glm-4.7-opus');
|
||||
assert.equal(resolveModelFromSettings('claude-opus-4-8', env), 'glm-4.7-opus');
|
||||
assert.equal(resolveModelFromSettings('claude-sonnet-4-6', env), 'glm-4.7');
|
||||
assert.equal(resolveModelFromSettings('claude-haiku-4-5', env), 'glm-4.7-flash');
|
||||
});
|
||||
@@ -45,7 +45,7 @@ test('resolveModelFromSettings honors global ANTHROPIC_MODEL override', () => {
|
||||
ANTHROPIC_DEFAULT_SONNET_MODEL: 'ignored',
|
||||
};
|
||||
assert.equal(resolveModelFromSettings('claude-sonnet-4-6', env), 'override-everywhere');
|
||||
assert.equal(resolveModelFromSettings('claude-opus-4-7', env), 'override-everywhere');
|
||||
assert.equal(resolveModelFromSettings('claude-opus-4-8', env), 'override-everywhere');
|
||||
});
|
||||
|
||||
test('resolveModelFromSettings ignores empty / whitespace mapping values', () => {
|
||||
@@ -54,7 +54,7 @@ test('resolveModelFromSettings ignores empty / whitespace mapping values', () =>
|
||||
ANTHROPIC_DEFAULT_OPUS_MODEL: '',
|
||||
};
|
||||
assert.equal(resolveModelFromSettings('claude-sonnet-4-6', env), 'claude-sonnet-4-6');
|
||||
assert.equal(resolveModelFromSettings('claude-opus-4-7', env), 'claude-opus-4-7');
|
||||
assert.equal(resolveModelFromSettings('claude-opus-4-8', env), 'claude-opus-4-8');
|
||||
});
|
||||
|
||||
test('resolveModelFromSettings does NOT remap non-Anthropic model IDs', () => {
|
||||
@@ -111,7 +111,7 @@ test('resolveModelFromSettings preserves [1m] across ANTHROPIC_MODEL global over
|
||||
|
||||
test('resolveModelFromSettings preserves [1m] for opus mapping', () => {
|
||||
const env = { ANTHROPIC_DEFAULT_OPUS_MODEL: 'mimo-v2.5-pro' };
|
||||
assert.equal(resolveModelFromSettings('claude-opus-4-7[1m]', env), 'mimo-v2.5-pro[1m]');
|
||||
assert.equal(resolveModelFromSettings('claude-opus-4-8[1m]', env), 'mimo-v2.5-pro[1m]');
|
||||
});
|
||||
|
||||
// --- setModelEnvironmentVariables ---------------------------------------
|
||||
@@ -161,7 +161,7 @@ test('setModelEnvironmentVariables routes haiku base to haiku env', () => {
|
||||
|
||||
test('modelSupportsVision only matches the canonical claude- prefix', () => {
|
||||
assert.equal(modelSupportsVision('claude-sonnet-4-6'), true);
|
||||
assert.equal(modelSupportsVision('claude-opus-4-7'), true);
|
||||
assert.equal(modelSupportsVision('claude-opus-4-8'), true);
|
||||
// Third-party proxies that merely contain "claude" must NOT be treated as
|
||||
// native vision-capable models.
|
||||
assert.equal(modelSupportsVision('claude-compatible-proxy'), true); // starts with 'claude-'
|
||||
|
||||
+1
-1
@@ -42,7 +42,7 @@ tasks.named('checkstyleTest') {
|
||||
}
|
||||
|
||||
group = 'com.github.idea-claude-code-gui'
|
||||
version = '0.4.6'
|
||||
version = '0.4.6-fix1'
|
||||
|
||||
java {
|
||||
sourceCompatibility = JavaVersion.VERSION_17
|
||||
|
||||
Vendored
+93
-93
@@ -1,93 +1,93 @@
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@rem Fix Windows console encoding issues - use English locale for all Java processes
|
||||
@rem This prevents garbled characters when running on Windows with non-English locale
|
||||
@set JAVA_TOOL_OPTIONS=-Duser.language=en -Dfile.encoding=UTF-8
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@rem Fix Windows console encoding issues - use English locale for all Java processes
|
||||
@rem This prevents garbled characters when running on Windows with non-English locale
|
||||
@set JAVA_TOOL_OPTIONS=-Duser.language=en -Dfile.encoding=UTF-8
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
|
||||
@@ -26,16 +26,16 @@ public class ModelProviderHandler {
|
||||
static final Map<String, Integer> MODEL_CONTEXT_LIMITS = new HashMap<>();
|
||||
static {
|
||||
// Claude models with 1M context (base IDs)
|
||||
MODEL_CONTEXT_LIMITS.put("claude-sonnet-5", 200_000);
|
||||
MODEL_CONTEXT_LIMITS.put("claude-sonnet-4-6", 200_000);
|
||||
MODEL_CONTEXT_LIMITS.put("claude-fable-5", 200_000);
|
||||
MODEL_CONTEXT_LIMITS.put("claude-opus-4-8", 200_000);
|
||||
MODEL_CONTEXT_LIMITS.put("claude-opus-4-7", 200_000);
|
||||
MODEL_CONTEXT_LIMITS.put("claude-opus-4-6", 200_000);
|
||||
// Claude models with [1m] suffix - 1M context
|
||||
MODEL_CONTEXT_LIMITS.put("claude-sonnet-5[1m]", 1_000_000);
|
||||
MODEL_CONTEXT_LIMITS.put("claude-sonnet-4-6[1m]", 1_000_000);
|
||||
MODEL_CONTEXT_LIMITS.put("claude-fable-5[1m]", 1_000_000);
|
||||
MODEL_CONTEXT_LIMITS.put("claude-opus-4-8[1m]", 1_000_000);
|
||||
MODEL_CONTEXT_LIMITS.put("claude-opus-4-7[1m]", 1_000_000);
|
||||
MODEL_CONTEXT_LIMITS.put("claude-opus-4-6[1m]", 1_000_000);
|
||||
// Haiku - no 1M context available
|
||||
MODEL_CONTEXT_LIMITS.put("claude-haiku-4-5", 200_000);
|
||||
|
||||
@@ -496,7 +496,7 @@ public class ClaudeSDKBridge extends BaseSDKBridge {
|
||||
*
|
||||
* @param sessionId The session ID to query context for
|
||||
* @param cwd Working directory
|
||||
* @param model The model ID to use for the runtime (e.g., "claude-opus-4-7")
|
||||
* @param model The model ID to use for the runtime (e.g., "claude-opus-4-8")
|
||||
* @return CompletableFuture with context usage data as JsonObject
|
||||
*/
|
||||
public CompletableFuture<JsonObject> getContextUsage(String sessionId, String cwd, String model) {
|
||||
|
||||
@@ -55,6 +55,7 @@ class ClaudeUsageAggregator {
|
||||
Map.entry("claude-sonnet-4-20250514", TIERED_SONNET_PRICING),
|
||||
Map.entry("claude-sonnet-4-5", TIERED_SONNET_PRICING),
|
||||
Map.entry("claude-sonnet-4-6", DEFAULT_PRICING),
|
||||
Map.entry("claude-sonnet-5", DEFAULT_PRICING),
|
||||
Map.entry("claude-haiku-4", HAIKU_4_5_PRICING),
|
||||
Map.entry("claude-haiku-4-5", HAIKU_4_5_PRICING)
|
||||
);
|
||||
@@ -68,6 +69,7 @@ class ClaudeUsageAggregator {
|
||||
"claude-opus-4-1",
|
||||
"claude-opus-4",
|
||||
"claude-sonnet-4-20250514",
|
||||
"claude-sonnet-5",
|
||||
"claude-sonnet-4-6",
|
||||
"claude-sonnet-4-5",
|
||||
"claude-sonnet-4",
|
||||
|
||||
@@ -21,14 +21,14 @@ public class ContextHandlerTest {
|
||||
JsonObject body = new JsonObject();
|
||||
body.addProperty("sessionId", "sess-123");
|
||||
body.addProperty("cwd", "/home/user/project");
|
||||
body.addProperty("model", "claude-opus-4-7[1m]");
|
||||
body.addProperty("model", "claude-opus-4-8[1m]");
|
||||
body.addProperty("requestId", "req-abc");
|
||||
|
||||
String[] result = ContextHandler.parseContextUsageRequest(GSON, body.toString());
|
||||
|
||||
assertEquals("sess-123", result[0]);
|
||||
assertEquals("/home/user/project", result[1]);
|
||||
assertEquals("claude-opus-4-7[1m]", result[2]);
|
||||
assertEquals("claude-opus-4-8[1m]", result[2]);
|
||||
assertEquals("req-abc", result[3]);
|
||||
}
|
||||
|
||||
@@ -70,14 +70,14 @@ public class ContextHandlerTest {
|
||||
public void parseNullJsonFieldsReturnNull() {
|
||||
JsonObject body = new JsonObject();
|
||||
body.add("sessionId", null);
|
||||
body.addProperty("model", "claude-opus-4-7");
|
||||
body.addProperty("model", "claude-opus-4-8");
|
||||
body.add("requestId", null);
|
||||
|
||||
String[] result = ContextHandler.parseContextUsageRequest(GSON, body.toString());
|
||||
|
||||
assertNull(result[0]); // sessionId is null
|
||||
assertNull(result[1]); // cwd not present
|
||||
assertEquals("claude-opus-4-7", result[2]);
|
||||
assertEquals("claude-opus-4-8", result[2]);
|
||||
assertNull(result[3]); // requestId is null
|
||||
}
|
||||
|
||||
@@ -94,11 +94,11 @@ public class ContextHandlerTest {
|
||||
@Test
|
||||
public void parseModelWith1MContextSuffix() {
|
||||
JsonObject body = new JsonObject();
|
||||
body.addProperty("model", "claude-opus-4-7[1m]");
|
||||
body.addProperty("model", "claude-opus-4-8[1m]");
|
||||
|
||||
String[] result = ContextHandler.parseContextUsageRequest(GSON, body.toString());
|
||||
|
||||
assertEquals("claude-opus-4-7[1m]", result[2]);
|
||||
assertEquals("claude-opus-4-8[1m]", result[2]);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+6
-2
@@ -74,12 +74,16 @@ public class ModelProviderHandlerTest {
|
||||
@Test
|
||||
public void shouldReturnCorrectContextLimitsForClaudeModels() {
|
||||
// Base IDs without [1m] suffix - 200k context by default
|
||||
assertTrue(ModelProviderHandler.MODEL_CONTEXT_LIMITS.containsKey("claude-sonnet-5"));
|
||||
assertTrue(ModelProviderHandler.MODEL_CONTEXT_LIMITS.containsKey("claude-sonnet-5[1m]"));
|
||||
assertEquals(200_000, ModelProviderHandler.getModelContextLimit("claude-sonnet-5"));
|
||||
assertEquals(200_000, ModelProviderHandler.getModelContextLimit("claude-sonnet-4-6"));
|
||||
assertEquals(200_000, ModelProviderHandler.getModelContextLimit("claude-opus-4-7"));
|
||||
assertEquals(200_000, ModelProviderHandler.getModelContextLimit("claude-opus-4-8"));
|
||||
assertEquals(200_000, ModelProviderHandler.getModelContextLimit("claude-opus-4-6"));
|
||||
// IDs with [1m] suffix - 1M context
|
||||
assertEquals(1_000_000, ModelProviderHandler.getModelContextLimit("claude-sonnet-5[1m]"));
|
||||
assertEquals(1_000_000, ModelProviderHandler.getModelContextLimit("claude-sonnet-4-6[1m]"));
|
||||
assertEquals(1_000_000, ModelProviderHandler.getModelContextLimit("claude-opus-4-7[1m]"));
|
||||
assertEquals(1_000_000, ModelProviderHandler.getModelContextLimit("claude-opus-4-8[1m]"));
|
||||
assertEquals(1_000_000, ModelProviderHandler.getModelContextLimit("claude-opus-4-6[1m]"));
|
||||
// Haiku - no 1M context available
|
||||
assertEquals(200_000, ModelProviderHandler.getModelContextLimit("claude-haiku-4-5"));
|
||||
|
||||
+2
-2
@@ -29,12 +29,12 @@ public class GitCommitMessageServiceCommitAiConfigTest {
|
||||
|
||||
@Test
|
||||
public void shouldRouteToResolvedClaudeModel() {
|
||||
TestableGitCommitMessageService service = new TestableGitCommitMessageService(buildConfig("claude", "claude-opus-4-7", "gpt-5.5"));
|
||||
TestableGitCommitMessageService service = new TestableGitCommitMessageService(buildConfig("claude", "claude-opus-4-8", "gpt-5.5"));
|
||||
ResultCapture callback = new ResultCapture();
|
||||
|
||||
service.generateCommitMessage(Collections.<Change>emptyList(), callback);
|
||||
|
||||
assertEquals("claude-opus-4-7", service.lastClaudeModel);
|
||||
assertEquals("claude-opus-4-8", service.lastClaudeModel);
|
||||
assertNull(service.lastCodexModel);
|
||||
assertEquals("fix: use claude routing", callback.success);
|
||||
}
|
||||
|
||||
+5
-5
@@ -75,13 +75,13 @@ public class CodemossSettingsServiceCommitAiConfigTest {
|
||||
|
||||
CodemossSettingsService service = new CodemossSettingsService();
|
||||
|
||||
invokeSetCommitAiConfig(service, "claude", "claude-opus-4-7", "gpt-5.4");
|
||||
invokeSetCommitAiConfig(service, "claude", "claude-opus-4-8", "gpt-5.4");
|
||||
JsonObject config = invokeGetCommitAiConfig(service);
|
||||
|
||||
assertEquals("claude", config.get("provider").getAsString());
|
||||
assertEquals("claude", config.get("effectiveProvider").getAsString());
|
||||
assertEquals("manual", config.get("resolutionSource").getAsString());
|
||||
assertEquals("claude-opus-4-7", config.getAsJsonObject("models").get("claude").getAsString());
|
||||
assertEquals("claude-opus-4-8", config.getAsJsonObject("models").get("claude").getAsString());
|
||||
assertEquals("gpt-5.4", config.getAsJsonObject("models").get("codex").getAsString());
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ public class CodemossSettingsServiceCommitAiConfigTest {
|
||||
|
||||
CodemossSettingsService service = new CodemossSettingsService();
|
||||
|
||||
invokeSetCommitAiConfig(service, "claude", "claude-opus-4-7", "gpt-5.4");
|
||||
invokeSetCommitAiConfig(service, "claude", "claude-opus-4-8", "gpt-5.4");
|
||||
JsonObject config = invokeGetCommitAiConfig(service);
|
||||
|
||||
assertEquals("claude", config.get("provider").getAsString());
|
||||
@@ -114,7 +114,7 @@ public class CodemossSettingsServiceCommitAiConfigTest {
|
||||
CodemossSettingsService service = new CodemossSettingsService();
|
||||
invokeSetPromptEnhancerConfig(service, "claude", "claude-opus-4-6", "gpt-5.4");
|
||||
|
||||
invokeSetCommitAiConfig(service, "codex", "claude-opus-4-7", "gpt-5.5");
|
||||
invokeSetCommitAiConfig(service, "codex", "claude-opus-4-8", "gpt-5.5");
|
||||
|
||||
JsonObject promptEnhancerConfig = invokeGetPromptEnhancerConfig(service);
|
||||
JsonObject commitAiConfig = invokeGetCommitAiConfig(service);
|
||||
@@ -125,7 +125,7 @@ public class CodemossSettingsServiceCommitAiConfigTest {
|
||||
|
||||
assertEquals("codex", commitAiConfig.get("provider").getAsString());
|
||||
assertEquals("gpt-5.5", commitAiConfig.getAsJsonObject("models").get("codex").getAsString());
|
||||
assertEquals("claude-opus-4-7", commitAiConfig.getAsJsonObject("models").get("claude").getAsString());
|
||||
assertEquals("claude-opus-4-8", commitAiConfig.getAsJsonObject("models").get("claude").getAsString());
|
||||
}
|
||||
|
||||
private JsonObject invokeGetCommitAiConfig(CodemossSettingsService service) throws Exception {
|
||||
|
||||
+3
-3
@@ -75,13 +75,13 @@ public class CodemossSettingsServicePromptEnhancerConfigTest {
|
||||
|
||||
CodemossSettingsService service = new CodemossSettingsService();
|
||||
|
||||
invokeSetPromptEnhancerConfig(service, "claude", "claude-opus-4-7", "gpt-5.4");
|
||||
invokeSetPromptEnhancerConfig(service, "claude", "claude-opus-4-8", "gpt-5.4");
|
||||
JsonObject config = invokeGetPromptEnhancerConfig(service);
|
||||
|
||||
assertEquals("claude", config.get("provider").getAsString());
|
||||
assertEquals("claude", config.get("effectiveProvider").getAsString());
|
||||
assertEquals("manual", config.get("resolutionSource").getAsString());
|
||||
assertEquals("claude-opus-4-7", config.getAsJsonObject("models").get("claude").getAsString());
|
||||
assertEquals("claude-opus-4-8", config.getAsJsonObject("models").get("claude").getAsString());
|
||||
assertEquals("gpt-5.4", config.getAsJsonObject("models").get("codex").getAsString());
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ public class CodemossSettingsServicePromptEnhancerConfigTest {
|
||||
|
||||
CodemossSettingsService service = new CodemossSettingsService();
|
||||
|
||||
invokeSetPromptEnhancerConfig(service, "claude", "claude-opus-4-7", "gpt-5.4");
|
||||
invokeSetPromptEnhancerConfig(service, "claude", "claude-opus-4-8", "gpt-5.4");
|
||||
JsonObject config = invokeGetPromptEnhancerConfig(service);
|
||||
|
||||
assertEquals("claude", config.get("provider").getAsString());
|
||||
|
||||
@@ -132,9 +132,9 @@ export const ButtonArea = ({
|
||||
*/
|
||||
const applyModelMapping = useCallback((model: ModelInfo, mapping: { main?: string; haiku?: string; sonnet?: string; opus?: string }): ModelInfo => {
|
||||
const modelKeyMap: Record<string, keyof typeof mapping> = {
|
||||
'claude-sonnet-5': 'sonnet',
|
||||
'claude-sonnet-4-6': 'sonnet',
|
||||
'claude-opus-4-8': 'opus',
|
||||
'claude-opus-4-7': 'opus',
|
||||
'claude-haiku-4-5': 'haiku',
|
||||
};
|
||||
|
||||
|
||||
@@ -74,8 +74,12 @@ describe('ModelSelect', () => {
|
||||
expect(screen.getByRole('button').textContent).toContain('glm-4.7');
|
||||
});
|
||||
|
||||
it('Claude 内置模型列表应移除已下线的 Opus 4.6,且不使用 [1m] 后缀 ID', () => {
|
||||
it('Claude 内置模型列表应新增 Sonnet 5、保留 Sonnet 4.6,并移除 Opus 4.7', () => {
|
||||
const ids = CLAUDE_MODELS.map((model) => model.id);
|
||||
expect(ids).toContain('claude-sonnet-5');
|
||||
expect(ids).toContain('claude-sonnet-4-6');
|
||||
expect(ids).toContain('claude-opus-4-8');
|
||||
expect(ids).not.toContain('claude-opus-4-7');
|
||||
expect(ids).not.toContain('claude-opus-4-6');
|
||||
expect(ids.some((id) => id.endsWith('[1m]'))).toBe(false);
|
||||
});
|
||||
|
||||
@@ -42,10 +42,10 @@ const DEFAULT_MODEL_MAP: Record<string, ModelInfo> = AVAILABLE_MODELS.reduce(
|
||||
);
|
||||
|
||||
const MODEL_LABEL_KEYS: Record<string, string> = {
|
||||
'claude-sonnet-5': 'models.claude.sonnet5.label',
|
||||
'claude-sonnet-4-6': 'models.claude.sonnet46.label',
|
||||
'claude-fable-5': 'models.claude.fable5.label',
|
||||
'claude-opus-4-8': 'models.claude.opus48.label',
|
||||
'claude-opus-4-7': 'models.claude.opus46.label',
|
||||
'claude-opus-4-6': 'models.claude.opus46_1m.label',
|
||||
'claude-opus-4-6[1m]': 'models.claude.opus46_1m.label',
|
||||
'claude-haiku-4-5': 'models.claude.haiku45.label',
|
||||
@@ -61,10 +61,10 @@ const MODEL_LABEL_KEYS: Record<string, string> = {
|
||||
};
|
||||
|
||||
const MODEL_DESCRIPTION_KEYS: Record<string, string> = {
|
||||
'claude-sonnet-5': 'models.claude.sonnet5.description',
|
||||
'claude-sonnet-4-6': 'models.claude.sonnet46.description',
|
||||
'claude-fable-5': 'models.claude.fable5.description',
|
||||
'claude-opus-4-8': 'models.claude.opus48.description',
|
||||
'claude-opus-4-7': 'models.claude.opus46.description',
|
||||
'claude-opus-4-6': 'models.claude.opus46_1m.description',
|
||||
'claude-opus-4-6[1m]': 'models.claude.opus46_1m.description',
|
||||
'claude-haiku-4-5': 'models.claude.haiku45.description',
|
||||
@@ -85,9 +85,9 @@ const MODEL_DESCRIPTION_KEYS: Record<string, string> = {
|
||||
* Legacy Opus 4.6 IDs share the same opus mapping bucket.
|
||||
*/
|
||||
const MODEL_ID_TO_MAPPING_KEY: Record<string, string> = {
|
||||
'claude-sonnet-5': 'sonnet',
|
||||
'claude-sonnet-4-6': 'sonnet',
|
||||
'claude-opus-4-8': 'opus',
|
||||
'claude-opus-4-7': 'opus',
|
||||
'claude-opus-4-6': 'opus',
|
||||
'claude-opus-4-6[1m]': 'opus',
|
||||
'claude-haiku-4-5': 'haiku',
|
||||
|
||||
@@ -9,13 +9,13 @@ vi.mock('react-i18next', () => ({
|
||||
}));
|
||||
|
||||
describe('ReasoningSelect', () => {
|
||||
it('shows xhigh and max for Claude Opus 4.7', () => {
|
||||
it('shows xhigh and max for Claude Opus 4.8', () => {
|
||||
render(
|
||||
<ReasoningSelect
|
||||
value="high"
|
||||
onChange={vi.fn()}
|
||||
currentProvider="claude"
|
||||
selectedModel="claude-opus-4-7"
|
||||
selectedModel="claude-opus-4-8"
|
||||
/>,
|
||||
);
|
||||
|
||||
@@ -41,6 +41,22 @@ describe('ReasoningSelect', () => {
|
||||
expect(screen.getByText('Max')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('shows max but not xhigh for Claude Sonnet 5', () => {
|
||||
render(
|
||||
<ReasoningSelect
|
||||
value="high"
|
||||
onChange={vi.fn()}
|
||||
currentProvider="claude"
|
||||
selectedModel="claude-sonnet-5"
|
||||
/>,
|
||||
);
|
||||
|
||||
fireEvent.click(screen.getByRole('button'));
|
||||
|
||||
expect(screen.queryByText('XHigh')).toBeNull();
|
||||
expect(screen.getByText('Max')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('resets unavailable effort when selected Claude model changes', () => {
|
||||
const onChange = vi.fn();
|
||||
|
||||
|
||||
@@ -34,8 +34,8 @@ interface ReasoningSelectProps {
|
||||
* Controls the depth of reasoning for AI models.
|
||||
* Visibility and available levels depend on the selected model:
|
||||
* - Codex: low/medium/high/xhigh
|
||||
* - Claude Opus 4.7: low/medium/high/xhigh/max
|
||||
* - Claude Opus 4.6 and Sonnet 4.6: low/medium/high/max
|
||||
* - Claude Opus 4.8: low/medium/high/xhigh/max
|
||||
* - Claude Sonnet 5, Opus 4.6, and Sonnet 4.6: low/medium/high/max
|
||||
* - Claude Haiku 4.5 and legacy models: hidden (no adaptive thinking support)
|
||||
*/
|
||||
export const ReasoningSelect = ({ value, onChange, disabled, selectedModel, currentProvider }: ReasoningSelectProps) => {
|
||||
|
||||
@@ -319,9 +319,9 @@ export const CLAUDE_MODELS: ModelInfo[] = [
|
||||
description: 'Opus 4.8 · Latest and most capable',
|
||||
},
|
||||
{
|
||||
id: 'claude-opus-4-7',
|
||||
label: 'Opus 4.7',
|
||||
description: 'Opus 4.7 · Previous flagship model',
|
||||
id: 'claude-sonnet-5',
|
||||
label: 'Sonnet 5',
|
||||
description: 'Sonnet 5 · Upgraded Sonnet model',
|
||||
},
|
||||
{
|
||||
id: 'claude-fable-5',
|
||||
@@ -423,9 +423,9 @@ export const AVAILABLE_PROVIDERS: ProviderInfo[] = [
|
||||
export const EFFORT_SUPPORTED_CLAUDE_MODELS = new Set([
|
||||
'claude-fable-5',
|
||||
'claude-opus-4-8',
|
||||
'claude-opus-4-7',
|
||||
'claude-opus-4-6',
|
||||
'claude-opus-4-6[1m]',
|
||||
'claude-sonnet-5',
|
||||
'claude-sonnet-4-6',
|
||||
]);
|
||||
|
||||
@@ -435,7 +435,6 @@ export const EFFORT_SUPPORTED_CLAUDE_MODELS = new Set([
|
||||
export const XHIGH_EFFORT_CLAUDE_MODELS = new Set([
|
||||
'claude-fable-5',
|
||||
'claude-opus-4-8',
|
||||
'claude-opus-4-7',
|
||||
]);
|
||||
|
||||
/**
|
||||
@@ -444,9 +443,9 @@ export const XHIGH_EFFORT_CLAUDE_MODELS = new Set([
|
||||
export const MAX_EFFORT_CLAUDE_MODELS = new Set([
|
||||
'claude-fable-5',
|
||||
'claude-opus-4-8',
|
||||
'claude-opus-4-7',
|
||||
'claude-opus-4-6',
|
||||
'claude-opus-4-6[1m]',
|
||||
'claude-sonnet-5',
|
||||
'claude-sonnet-4-6',
|
||||
]);
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ describe('PromptEnhancerSection', () => {
|
||||
effectiveProvider: 'claude',
|
||||
resolutionSource: 'manual',
|
||||
models: {
|
||||
claude: 'claude-opus-4-7',
|
||||
claude: 'claude-opus-4-8',
|
||||
codex: 'gpt-5.4',
|
||||
},
|
||||
availability: {
|
||||
|
||||
@@ -9,7 +9,7 @@ describe('useMessageSender - /context command', () => {
|
||||
t,
|
||||
addToast: vi.fn(),
|
||||
currentProvider: 'claude',
|
||||
selectedModel: 'claude-opus-4-7',
|
||||
selectedModel: 'claude-opus-4-8',
|
||||
permissionMode: 'default',
|
||||
reasoningEffort: 'high',
|
||||
codexFastMode: 'normal',
|
||||
@@ -50,7 +50,7 @@ describe('useMessageSender - /context command', () => {
|
||||
|
||||
it('sends get_context_usage with base model when longContext is disabled', () => {
|
||||
const opts = createOptions({
|
||||
selectedModel: 'claude-opus-4-7',
|
||||
selectedModel: 'claude-opus-4-8',
|
||||
longContextEnabled: false,
|
||||
});
|
||||
|
||||
@@ -65,13 +65,13 @@ describe('useMessageSender - /context command', () => {
|
||||
expect(call).toMatch(/^get_context_usage:/);
|
||||
|
||||
const payload = JSON.parse(call.substring('get_context_usage:'.length));
|
||||
expect(payload.model).toBe('claude-opus-4-7');
|
||||
expect(payload.model).toBe('claude-opus-4-8');
|
||||
expect(payload.requestId).toBeTruthy();
|
||||
});
|
||||
|
||||
it('sends get_context_usage with [1m] suffix when longContext is enabled', () => {
|
||||
const opts = createOptions({
|
||||
selectedModel: 'claude-opus-4-7',
|
||||
selectedModel: 'claude-opus-4-8',
|
||||
longContextEnabled: true,
|
||||
});
|
||||
|
||||
@@ -84,7 +84,7 @@ describe('useMessageSender - /context command', () => {
|
||||
expect(window.sendToJava).toHaveBeenCalledTimes(1);
|
||||
const call = (window.sendToJava as any).mock.calls[0][0] as string;
|
||||
const payload = JSON.parse(call.substring('get_context_usage:'.length));
|
||||
expect(payload.model).toBe('claude-opus-4-7[1m]');
|
||||
expect(payload.model).toBe('claude-opus-4-8[1m]');
|
||||
});
|
||||
|
||||
it('opens dialog with loading state before sending bridge event', () => {
|
||||
@@ -153,7 +153,7 @@ describe('useMessageSender - /context command', () => {
|
||||
it('includes explicit Claude high reasoning effort in plain message payload', () => {
|
||||
const opts = createOptions({
|
||||
currentProvider: 'claude',
|
||||
selectedModel: 'claude-opus-4-7',
|
||||
selectedModel: 'claude-opus-4-8',
|
||||
reasoningEffort: 'high',
|
||||
});
|
||||
|
||||
@@ -170,7 +170,7 @@ describe('useMessageSender - /context command', () => {
|
||||
it('includes explicit Claude high reasoning effort in attachment message payload', () => {
|
||||
const opts = createOptions({
|
||||
currentProvider: 'claude',
|
||||
selectedModel: 'claude-opus-4-7',
|
||||
selectedModel: 'claude-opus-4-8',
|
||||
reasoningEffort: 'high',
|
||||
});
|
||||
|
||||
|
||||
@@ -1646,9 +1646,9 @@
|
||||
"label": "Sonnet 4.6",
|
||||
"description": "Sonnet 4.6 · Use the default model"
|
||||
},
|
||||
"opus46": {
|
||||
"label": "Opus 4.7",
|
||||
"description": "Opus 4.7 · Previous flagship model"
|
||||
"sonnet5": {
|
||||
"label": "Sonnet 5",
|
||||
"description": "Sonnet 5 · Upgraded Sonnet model"
|
||||
},
|
||||
"opus46_1m": {
|
||||
"label": "Opus 4.6",
|
||||
|
||||
@@ -1402,9 +1402,9 @@
|
||||
"label": "Sonnet 4.6",
|
||||
"description": "Sonnet 4.6 · Modelo recomendado por defecto"
|
||||
},
|
||||
"opus46": {
|
||||
"label": "Opus 4.7",
|
||||
"description": "Opus 4.7 · Modelo insignia anterior"
|
||||
"sonnet5": {
|
||||
"label": "Sonnet 5",
|
||||
"description": "Sonnet 5 · Modelo mejorado de Sonnet 4.6"
|
||||
},
|
||||
"opus46_1m": {
|
||||
"label": "Opus 4.6",
|
||||
|
||||
@@ -1402,9 +1402,9 @@
|
||||
"label": "Sonnet 4.6",
|
||||
"description": "Sonnet 4.6 · Modèle recommandé par défaut"
|
||||
},
|
||||
"opus46": {
|
||||
"label": "Opus 4.7",
|
||||
"description": "Opus 4.7 · Modèle phare précédent"
|
||||
"sonnet5": {
|
||||
"label": "Sonnet 5",
|
||||
"description": "Sonnet 5 · Modèle amélioré de Sonnet 4.6"
|
||||
},
|
||||
"opus46_1m": {
|
||||
"label": "Opus 4.6",
|
||||
|
||||
@@ -1401,9 +1401,9 @@
|
||||
"label": "Sonnet 4.6",
|
||||
"description": "Sonnet 4.6 · डिफ़ॉल्ट अनुशंसित मॉडल"
|
||||
},
|
||||
"opus46": {
|
||||
"label": "Opus 4.7",
|
||||
"description": "Opus 4.7 · पिछला फ्लैगशिप मॉडल"
|
||||
"sonnet5": {
|
||||
"label": "Sonnet 5",
|
||||
"description": "Sonnet 5 · Sonnet 4.6 का अपग्रेड मॉडल"
|
||||
},
|
||||
"opus46_1m": {
|
||||
"label": "Opus 4.6",
|
||||
|
||||
@@ -1413,9 +1413,9 @@
|
||||
"label": "Sonnet 4.6",
|
||||
"description": "Sonnet 4.6 · デフォルトモデルを使用"
|
||||
},
|
||||
"opus46": {
|
||||
"label": "Opus 4.7",
|
||||
"description": "Opus 4.7 · 前世代フラッグシップモデル"
|
||||
"sonnet5": {
|
||||
"label": "Sonnet 5",
|
||||
"description": "Sonnet 5 · Sonnet 4.6 のアップグレードモデル"
|
||||
},
|
||||
"opus46_1m": {
|
||||
"label": "Opus 4.6",
|
||||
|
||||
@@ -1519,9 +1519,9 @@
|
||||
"label": "Sonnet 4.6",
|
||||
"description": "Sonnet 4.6 · 기본 모델 사용"
|
||||
},
|
||||
"opus46": {
|
||||
"label": "Opus 4.7",
|
||||
"description": "Opus 4.7 · 이전 세대 플래그십 모델"
|
||||
"sonnet5": {
|
||||
"label": "Sonnet 5",
|
||||
"description": "Sonnet 5 · Sonnet 4.6 업그레이드 모델"
|
||||
},
|
||||
"opus46_1m": {
|
||||
"label": "Opus 4.6",
|
||||
|
||||
@@ -1574,9 +1574,9 @@
|
||||
"label": "Sonnet 4.6",
|
||||
"description": "Sonnet 4.6 · Usar o modelo padrão"
|
||||
},
|
||||
"opus46": {
|
||||
"label": "Opus 4.7",
|
||||
"description": "Opus 4.7 · Modelo principal anterior"
|
||||
"sonnet5": {
|
||||
"label": "Sonnet 5",
|
||||
"description": "Sonnet 5 · Modelo aprimorado do Sonnet 4.6"
|
||||
},
|
||||
"opus46_1m": {
|
||||
"label": "Opus 4.6",
|
||||
|
||||
@@ -1428,9 +1428,9 @@
|
||||
"label": "Sonnet 4.6",
|
||||
"description": "Sonnet 4.6 · Модель по умолчанию"
|
||||
},
|
||||
"opus46": {
|
||||
"label": "Opus 4.7",
|
||||
"description": "Opus 4.7 · Предыдущая флагманская модель"
|
||||
"sonnet5": {
|
||||
"label": "Sonnet 5",
|
||||
"description": "Sonnet 5 · Обновленная модель Sonnet 4.6"
|
||||
},
|
||||
"opus46_1m": {
|
||||
"label": "Opus 4.6",
|
||||
|
||||
@@ -1407,9 +1407,9 @@
|
||||
"label": "Sonnet 4.6",
|
||||
"description": "Sonnet 4.6 · 預設推薦模型"
|
||||
},
|
||||
"opus46": {
|
||||
"label": "Opus 4.7",
|
||||
"description": "Opus 4.7 · 上一代旗艦模型"
|
||||
"sonnet5": {
|
||||
"label": "Sonnet 5",
|
||||
"description": "Sonnet 5 · Sonnet 4.6 升級模型"
|
||||
},
|
||||
"opus46_1m": {
|
||||
"label": "Opus 4.6",
|
||||
|
||||
@@ -1651,9 +1651,9 @@
|
||||
"label": "Sonnet 4.6",
|
||||
"description": "Sonnet 4.6 · 默认推荐模型"
|
||||
},
|
||||
"opus46": {
|
||||
"label": "Opus 4.7",
|
||||
"description": "Opus 4.7 · 上一代旗舰模型"
|
||||
"sonnet5": {
|
||||
"label": "Sonnet 5",
|
||||
"description": "Sonnet 5 · Sonnet 4.6 升级模型"
|
||||
},
|
||||
"opus46_1m": {
|
||||
"label": "Opus 4.6",
|
||||
|
||||
@@ -12,6 +12,18 @@ export interface ChangelogEntry {
|
||||
}
|
||||
|
||||
export const CHANGELOG_DATA: ChangelogEntry[] = [
|
||||
{
|
||||
version: '0.4.6-fix1',
|
||||
date: '2026-07-06',
|
||||
content: {
|
||||
en: `🐛 Fixes
|
||||
- Fix Claude CLI login being treated as a host-managed provider: when \`access\` is \`cli_login\`, the bridge now leaves \`CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST\` unset, avoiding the host-managed credential path for users already authenticated through the Claude CLI (by @zkpaiminmin)
|
||||
- Fix Claude model metadata after the lineup update: replace the retired \`claude-opus-4-7\` built-in option with \`claude-opus-4-8\`, and add \`claude-sonnet-5\` with 200K / 1M context handling, max reasoning support, usage pricing, model mapping, and localized labels across all supported languages (by @zkpaiminmin)`,
|
||||
zh: `🐛 修复
|
||||
- 修复 Claude CLI 登录被误判为 host-managed provider:当认证状态为 \`cli_login\` 时,bridge 不再设置 \`CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST\`,避免已通过 Claude CLI 登录的用户走错 host-managed 凭证路径(by @zkpaiminmin)
|
||||
- 修复 Claude 模型清单与元数据滞后:内置模型移除已下线的 \`claude-opus-4-7\`,切换到 \`claude-opus-4-8\`,并新增 \`claude-sonnet-5\` 的 200K / 1M 上下文、max reasoning、用量计价、模型映射和全语言本地化标签(by @zkpaiminmin)`,
|
||||
},
|
||||
},
|
||||
{
|
||||
version: '0.4.6',
|
||||
date: '2026-06-28',
|
||||
|
||||
Reference in New Issue
Block a user