diff --git a/relay/helper/reasoning_suffix_test.go b/relay/helper/reasoning_suffix_test.go index 592d26ada..b1ef965d4 100644 --- a/relay/helper/reasoning_suffix_test.go +++ b/relay/helper/reasoning_suffix_test.go @@ -161,6 +161,27 @@ func TestApplyReasoningModelSuffixGeminiNoThinkingWhenAdapterEnabled(t *testing. assert.Equal(t, "none", info.ReasoningConversion.Effort) } +func TestApplyReasoningModelSuffixClaudeEffortTailKeptWhenAdapterDisabled(t *testing.T) { + settings := model_setting.GetClaudeSettings() + original := settings.ThinkingAdapterEnabled + t.Cleanup(func() { settings.ThinkingAdapterEnabled = original }) + settings.ThinkingAdapterEnabled = false + + req := &dto.ClaudeRequest{Model: "claude-opus-5-5-high"} + info := &relaycommon.RelayInfo{ + OriginModelName: "claude-opus-5-5-high", + Request: req, + ChannelMeta: &relaycommon.ChannelMeta{ + UpstreamModelName: "claude-opus-5-5-high", + }, + } + + mustApplyReasoningModelSuffix(t, info, req) + assert.Equal(t, "claude-opus-5-5-high", info.UpstreamModelName) + assert.Equal(t, "claude-opus-5-5-high", req.Model) + assert.Nil(t, info.ReasoningConversion) +} + func TestApplyReasoningModelSuffixPreservesEffortTailModelID(t *testing.T) { info := &relaycommon.RelayInfo{ OriginModelName: "qwen-max", diff --git a/relaykit/relayconvert/convmeta/options.go b/relaykit/relayconvert/convmeta/options.go index efafb2ed4..0623ebca5 100644 --- a/relaykit/relayconvert/convmeta/options.go +++ b/relaykit/relayconvert/convmeta/options.go @@ -34,9 +34,13 @@ type Options struct { } type ClaudeOptions struct { - // ThinkingAdapterEnabled controls whether suffix-derived reasoning intent - // is rendered onto Claude thinking / output_config. Suffix parsing itself - // is the host entry layer's job (standalone users call Parse* themselves). + // ThinkingAdapterEnabled is the host thinking-suffix adapter toggle. The + // host passes it to reasoning.ParseClaudeModelSuffix, so -thinking, + // -nothinking, -thinking-, and effort tails such as -high on + // claude-* names become reasoning intent only while it is on; when off the + // model name is sent verbatim. Explicit @ modifiers are unaffected. Suffix + // parsing itself is the host entry layer's job (standalone users call + // Parse* themselves). ThinkingAdapterEnabled bool // ThinkingAdapterBudgetTokensPercentage sizes thinking budget_tokens as a // fraction of max_tokens when the adapter fires. @@ -57,9 +61,12 @@ type ClaudeOptions struct { } type GeminiOptions struct { - // ThinkingAdapterEnabled controls whether suffix-derived reasoning intent - // is rendered onto Gemini thinkingConfig. Suffix parsing itself is the - // host entry layer's job (standalone users call Parse* themselves). + // ThinkingAdapterEnabled is the host thinking-suffix adapter toggle. The + // host and gemini_chat request conversion pass it to + // reasoning.ParseGeminiModelSuffix, so -thinking, -nothinking, + // -thinking-, and effort tails such as -high on gemini-* names + // become reasoning intent only while it is on; when off the model name is + // sent verbatim. Explicit @ modifiers are unaffected. ThinkingAdapterEnabled bool // ThinkingAdapterBudgetTokensPercentage sizes thinkingBudget as a fraction // of maxOutputTokens when the adapter fires. diff --git a/relaykit/relayconvert/reasoning/suffix.go b/relaykit/relayconvert/reasoning/suffix.go index 1cb9a0cc0..04af75fc9 100644 --- a/relaykit/relayconvert/reasoning/suffix.go +++ b/relaykit/relayconvert/reasoning/suffix.go @@ -136,12 +136,16 @@ func ParseOpenAIReasoningEffortFromModelSuffix(modelName string, preserveEffortT return effort, baseModel } -func ParseClaudeModelSuffix(modelName string, allowThinkingAlias bool) (string, Intent, bool, error) { +// ParseClaudeModelSuffix folds the naked claude-* aliases (-thinking, +// -nothinking, -thinking-, and effort tails such as -high) into an +// Intent. allowSuffixAlias is the host thinking-adapter toggle; when false the +// name is returned verbatim and no intent is produced. +func ParseClaudeModelSuffix(modelName string, allowSuffixAlias bool) (string, Intent, bool, error) { prefix, bare := splitModelNamespace(modelName) if !strings.HasPrefix(bare, "claude-") { return modelName, Intent{}, false, nil } - base, intent, found, err := parseProviderModelSuffix(bare, "claude-", allowThinkingAlias, true) + base, intent, found, err := parseProviderModelSuffix(bare, "claude-", allowSuffixAlias, true) if err != nil || !found || !legacyClaudeModelPattern.MatchString(base) { return modelName, Intent{}, false, err } @@ -171,12 +175,14 @@ func isKnownClaudeModel(modelName string) bool { return false } -func ParseGeminiModelSuffix(modelName string, allowThinkingAlias bool) (string, Intent, bool, error) { +// ParseGeminiModelSuffix is the gemini-* counterpart of ParseClaudeModelSuffix +// and honours allowSuffixAlias the same way. +func ParseGeminiModelSuffix(modelName string, allowSuffixAlias bool) (string, Intent, bool, error) { prefix, bare := splitModelNamespace(modelName) if !strings.HasPrefix(bare, "gemini-") { return modelName, Intent{}, false, nil } - base, intent, found, err := parseProviderModelSuffix(bare, "gemini-", allowThinkingAlias, true) + base, intent, found, err := parseProviderModelSuffix(bare, "gemini-", allowSuffixAlias, true) if err != nil || !found || !legacyGeminiModelPattern.MatchString(base) { return modelName, Intent{}, false, err } @@ -186,13 +192,13 @@ func ParseGeminiModelSuffix(modelName string, allowThinkingAlias bool) (string, // ParseKnownProviderModelSuffix extracts a canonical intent only when the // origin identifies a provider family whose suffix vocabulary is defined by // relaykit. Unknown OpenAI-compatible model names are deliberately untouched. -func ParseKnownProviderModelSuffix(modelName string, allowThinkingAlias bool) (string, Intent, bool, error) { +func ParseKnownProviderModelSuffix(modelName string, allowSuffixAlias bool) (string, Intent, bool, error) { bare := lastModelPathSegment(modelName) if strings.HasPrefix(bare, "claude-") { - return ParseClaudeModelSuffix(modelName, allowThinkingAlias) + return ParseClaudeModelSuffix(modelName, allowSuffixAlias) } if strings.HasPrefix(bare, "gemini-") { - return ParseGeminiModelSuffix(modelName, allowThinkingAlias) + return ParseGeminiModelSuffix(modelName, allowSuffixAlias) } return modelName, Intent{}, false, nil } @@ -214,37 +220,39 @@ func TrimGeminiThinkingSuffix(modelName string) (string, bool) { return baseModel, ok && err == nil } -func parseProviderModelSuffix(modelName string, requiredPrefix string, allowThinkingAlias bool, includeThoughts bool) (string, Intent, bool, error) { - if allowThinkingAlias { - if marker := strings.LastIndex(modelName, "-thinking-"); marker >= 0 { - baseModel := modelName[:marker] - if !strings.HasPrefix(baseModel, requiredPrefix) { - return modelName, Intent{}, false, nil - } - budget, err := strconv.Atoi(modelName[marker+len("-thinking-"):]) - if err != nil { - return modelName, Intent{}, false, fmt.Errorf("invalid thinking budget suffix on model %q: %w", modelName, err) - } - intent := Intent{BudgetTokens: &budget, Source: SourceSuffix, BudgetSource: SourceSuffix} - if includeThoughts { - value := true - intent.IncludeThoughts = &value - } - return baseModel, intent, true, nil +// parseProviderModelSuffix recognises a provider family's naked model-name +// aliases. allowSuffixAlias gates all of them, including effort tails, so a +// disabled thinking adapter leaves the model name untouched. +func parseProviderModelSuffix(modelName string, requiredPrefix string, allowSuffixAlias bool, includeThoughts bool) (string, Intent, bool, error) { + if !allowSuffixAlias { + return modelName, Intent{}, false, nil + } + if marker := strings.LastIndex(modelName, "-thinking-"); marker >= 0 { + baseModel := modelName[:marker] + if !strings.HasPrefix(baseModel, requiredPrefix) { + return modelName, Intent{}, false, nil } - if before, ok := strings.CutSuffix(modelName, "-nothinking"); ok { - baseModel := before - return baseModel, Intent{Mode: ModeDisabled, Effort: EffortNone, Source: SourceSuffix}, true, nil + budget, err := strconv.Atoi(modelName[marker+len("-thinking-"):]) + if err != nil { + return modelName, Intent{}, false, fmt.Errorf("invalid thinking budget suffix on model %q: %w", modelName, err) } - if before, ok := strings.CutSuffix(modelName, "-thinking"); ok { - baseModel := before - intent := Intent{Mode: ModeEnabled, Source: SourceSuffix} - if includeThoughts { - value := true - intent.IncludeThoughts = &value - } - return baseModel, intent, true, nil + intent := Intent{BudgetTokens: &budget, Source: SourceSuffix, BudgetSource: SourceSuffix} + if includeThoughts { + value := true + intent.IncludeThoughts = &value } + return baseModel, intent, true, nil + } + if baseModel, ok := strings.CutSuffix(modelName, "-nothinking"); ok { + return baseModel, Intent{Mode: ModeDisabled, Effort: EffortNone, Source: SourceSuffix}, true, nil + } + if baseModel, ok := strings.CutSuffix(modelName, "-thinking"); ok { + intent := Intent{Mode: ModeEnabled, Source: SourceSuffix} + if includeThoughts { + value := true + intent.IncludeThoughts = &value + } + return baseModel, intent, true, nil } suffixes := []string{"-max", "-xhigh", "-high", "-medium", "-low", "-minimal", "-none"} diff --git a/relaykit/relayconvert/reasoning/suffix_test.go b/relaykit/relayconvert/reasoning/suffix_test.go index ff0f6eba2..ec8655766 100644 --- a/relaykit/relayconvert/reasoning/suffix_test.go +++ b/relaykit/relayconvert/reasoning/suffix_test.go @@ -69,6 +69,18 @@ func TestParseKnownProviderModelSuffix(t *testing.T) { wantMode: ModeEnabled, wantEffort: EffortHigh, }, + { + name: "claude effort tail kept when adapter is off", + model: "claude-opus-5-5-high", + wantBase: "claude-opus-5-5-high", + wantFound: false, + }, + { + name: "gemini effort tail kept when adapter is off", + model: "gemini-2.5-flash-high", + wantBase: "gemini-2.5-flash-high", + wantFound: false, + }, { name: "gemini thinking alias", model: "gemini-2.5-flash-thinking", diff --git a/web/src/features/system-settings/models/claude-settings-card.tsx b/web/src/features/system-settings/models/claude-settings-card.tsx index beb662a5c..aaadb4dfa 100644 --- a/web/src/features/system-settings/models/claude-settings-card.tsx +++ b/web/src/features/system-settings/models/claude-settings-card.tsx @@ -254,7 +254,7 @@ export function ClaudeSettingsCard({ defaultValues }: ClaudeSettingsCardProps) { {t('Thinking Suffix Adapter')} {t( - 'Adapt `-thinking` suffix requests to Anthropic native thinking behavior while keeping billing predictable.' + 'Adapt `-thinking`, `-nothinking`, and effort suffixes such as `-high` to Anthropic native thinking behavior while keeping billing predictable. When off, model names are sent upstream unchanged.' )} diff --git a/web/src/features/system-settings/models/gemini-settings-card.tsx b/web/src/features/system-settings/models/gemini-settings-card.tsx index ca4ca4d7d..38ed31247 100644 --- a/web/src/features/system-settings/models/gemini-settings-card.tsx +++ b/web/src/features/system-settings/models/gemini-settings-card.tsx @@ -339,7 +339,7 @@ export function GeminiSettingsCard({ defaultValues }: GeminiSettingsCardProps) { {t('Supports `-thinking`, `-thinking-')} {'{{budget}}'} {t( - '`, and `-nothinking` suffixes while routing to the correct Gemini variant.' + '`, `-nothinking`, and effort suffixes such as `-high` while routing to the correct Gemini variant. When off, model names are sent upstream unchanged.' )} diff --git a/web/src/i18n/locales/en.json b/web/src/i18n/locales/en.json index dc0062249..162341a6e 100644 --- a/web/src/i18n/locales/en.json +++ b/web/src/i18n/locales/en.json @@ -116,7 +116,7 @@ "#1 by usage": "#1 by usage", "#1 Model": "#1 Model", "% off": "% off", - "`, and `-nothinking` suffixes while routing to the correct Gemini variant.": "`, and `-nothinking` suffixes while routing to the correct Gemini variant.", + "`, `-nothinking`, and effort suffixes such as `-high` while routing to the correct Gemini variant. When off, model names are sent upstream unchanged.": "`, `-nothinking`, and effort suffixes such as `-high` while routing to the correct Gemini variant. When off, model names are sent upstream unchanged.", "© 2025 Your Company. All rights reserved.": "© 2025 Your Company. All rights reserved.", "+{{count}} more": "+{{count}} more", "| Based on": "| Based on", @@ -243,7 +243,7 @@ "Actual Amount": "Actual Amount", "Actual Model": "Actual Model", "Actual Model:": "Actual Model:", - "Adapt `-thinking` suffix requests to Anthropic native thinking behavior while keeping billing predictable.": "Adapt `-thinking` suffix requests to Anthropic native thinking behavior while keeping billing predictable.", + "Adapt `-thinking`, `-nothinking`, and effort suffixes such as `-high` to Anthropic native thinking behavior while keeping billing predictable. When off, model names are sent upstream unchanged.": "Adapt `-thinking`, `-nothinking`, and effort suffixes such as `-high` to Anthropic native thinking behavior while keeping billing predictable. When off, model names are sent upstream unchanged.", "Add": "Add", "Add \"{{value}}\"": "Add \"{{value}}\"", "Add {{added}} models and remove {{removed}} models": "Add {{added}} models and remove {{removed}} models", diff --git a/web/src/i18n/locales/fr.json b/web/src/i18n/locales/fr.json index 311925aea..a9fd019a8 100644 --- a/web/src/i18n/locales/fr.json +++ b/web/src/i18n/locales/fr.json @@ -116,7 +116,7 @@ "#1 by usage": "N° 1 d'utilisation", "#1 Model": "#1 Modèle", "% off": "% de réduction", - "`, and `-nothinking` suffixes while routing to the correct Gemini variant.": "`, et les suffixes `-nothinking` lors du routage vers la variante Gemini correcte.", + "`, `-nothinking`, and effort suffixes such as `-high` while routing to the correct Gemini variant. When off, model names are sent upstream unchanged.": "`, `-nothinking` et les suffixes d’effort tels que `-high` lors du routage vers la variante Gemini correcte. Désactivé, les noms de modèle sont envoyés en amont tels quels.", "© 2025 Your Company. All rights reserved.": "© 2025 Votre entreprise. Tous droits réservés.", "+{{count}} more": "+{{count}} de plus", "| Based on": "| Basé sur", @@ -243,7 +243,7 @@ "Actual Amount": "Montant réel", "Actual Model": "Modèle réel", "Actual Model:": "Modèle réel :", - "Adapt `-thinking` suffix requests to Anthropic native thinking behavior while keeping billing predictable.": "Adapter les requêtes avec le suffixe `-thinking` au comportement de pensée natif d’Anthropic tout en gardant une facturation prévisible.", + "Adapt `-thinking`, `-nothinking`, and effort suffixes such as `-high` to Anthropic native thinking behavior while keeping billing predictable. When off, model names are sent upstream unchanged.": "Adapter les requêtes avec les suffixes `-thinking`, `-nothinking` et les suffixes d’effort tels que `-high` au comportement de pensée natif d’Anthropic tout en gardant une facturation prévisible. Désactivé, les noms de modèle sont envoyés en amont tels quels.", "Add": "Ajouter", "Add \"{{value}}\"": "Ajouter \"{{value}}\"", "Add {{added}} models and remove {{removed}} models": "Ajouter {{added}} modèles et en retirer {{removed}}", diff --git a/web/src/i18n/locales/ja.json b/web/src/i18n/locales/ja.json index b1b73295d..ede485254 100644 --- a/web/src/i18n/locales/ja.json +++ b/web/src/i18n/locales/ja.json @@ -116,7 +116,7 @@ "#1 by usage": "利用量1位", "#1 Model": "#1 モデル", "% off": "% OFF", - "`, and `-nothinking` suffixes while routing to the correct Gemini variant.": "`, および `-nothinking` サフィックスを、正しい Gemini バリアントにルーティングする際に使用します。", + "`, `-nothinking`, and effort suffixes such as `-high` while routing to the correct Gemini variant. When off, model names are sent upstream unchanged.": "`、`-nothinking`、および `-high` などの推論強度サフィックスを、正しい Gemini バリアントにルーティングする際に使用します。オフの場合、モデル名はそのまま上流に送信されます。", "© 2025 Your Company. All rights reserved.": "© 2025 Your Company. 全著作権所有。", "+{{count}} more": "他 {{count}} 件", "| Based on": "| に基づく", @@ -243,7 +243,7 @@ "Actual Amount": "実際の金額", "Actual Model": "実際のモデル", "Actual Model:": "実際のモデル:", - "Adapt `-thinking` suffix requests to Anthropic native thinking behavior while keeping billing predictable.": "`-thinking` サフィックス付きリクエストを Anthropic ネイティブの思考動作に適配し、課金を予測可能に保ちます。", + "Adapt `-thinking`, `-nothinking`, and effort suffixes such as `-high` to Anthropic native thinking behavior while keeping billing predictable. When off, model names are sent upstream unchanged.": "`-thinking`、`-nothinking`、および `-high` などの推論強度サフィックス付きリクエストを Anthropic ネイティブの思考動作に適配し、課金を予測可能に保ちます。オフの場合、モデル名はそのまま上流に送信されます。", "Add": "追加", "Add \"{{value}}\"": "\"{{value}}\" を追加", "Add {{added}} models and remove {{removed}} models": "{{added}} 個のモデルを追加、{{removed}} 個を削除", diff --git a/web/src/i18n/locales/ru.json b/web/src/i18n/locales/ru.json index ca0e34e95..9ab4b312d 100644 --- a/web/src/i18n/locales/ru.json +++ b/web/src/i18n/locales/ru.json @@ -116,7 +116,7 @@ "#1 by usage": "№1 по использованию", "#1 Model": "#1 Модель", "% off": "скидка", - "`, and `-nothinking` suffixes while routing to the correct Gemini variant.": "суффиксы `, и `-nothinking` при маршрутизации к правильному варианту Gemini.", + "`, `-nothinking`, and effort suffixes such as `-high` while routing to the correct Gemini variant. When off, model names are sent upstream unchanged.": "суффиксы `, `-nothinking` и суффиксы усилия, такие как `-high`, при маршрутизации к правильному варианту Gemini. При отключении имена моделей отправляются вверх по потоку без изменений.", "© 2025 Your Company. All rights reserved.": "© 2025 Ваша Компания. Все права защищены.", "+{{count}} more": "ещё {{count}}", "| Based on": "| На основе", @@ -243,7 +243,7 @@ "Actual Amount": "Фактическая сумма", "Actual Model": "Фактическая модель", "Actual Model:": "Фактическая модель:", - "Adapt `-thinking` suffix requests to Anthropic native thinking behavior while keeping billing predictable.": "Адаптировать запросы с суффиксом `-thinking` к собственному режиму размышления Anthropic, сохраняя предсказуемость биллинга.", + "Adapt `-thinking`, `-nothinking`, and effort suffixes such as `-high` to Anthropic native thinking behavior while keeping billing predictable. When off, model names are sent upstream unchanged.": "Адаптировать запросы с суффиксами `-thinking`, `-nothinking` и суффиксами усилия, такими как `-high`, к собственному режиму размышления Anthropic, сохраняя предсказуемость биллинга. При отключении имена моделей отправляются вверх по потоку без изменений.", "Add": "Добавить", "Add \"{{value}}\"": "Добавить \"{{value}}\"", "Add {{added}} models and remove {{removed}} models": "Добавить моделей: {{added}}, удалить: {{removed}}", diff --git a/web/src/i18n/locales/vi.json b/web/src/i18n/locales/vi.json index b8c51b935..ffacfc982 100644 --- a/web/src/i18n/locales/vi.json +++ b/web/src/i18n/locales/vi.json @@ -116,7 +116,7 @@ "#1 by usage": "Hạng 1 theo mức sử dụng", "#1 Model": "#1 Mô hình", "% off": "% giảm giá", - "`, and `-nothinking` suffixes while routing to the correct Gemini variant.": ", và", + "`, `-nothinking`, and effort suffixes such as `-high` while routing to the correct Gemini variant. When off, model names are sent upstream unchanged.": "`, `-nothinking` và các hậu tố mức suy luận như `-high` khi định tuyến đến biến thể Gemini đúng. Khi tắt, tên mô hình được gửi nguyên vẹn lên upstream.", "© 2025 Your Company. All rights reserved.": "© 2025 Công ty của bạn. Mọi quyền được bảo lưu.", "+{{count}} more": "thêm {{count}} mục", "| Based on": "| Dựa trên", @@ -243,7 +243,7 @@ "Actual Amount": "Số tiền thực tế", "Actual Model": "Mô hình thực tế", "Actual Model:": "Mô hình thực tế:", - "Adapt `-thinking` suffix requests to Anthropic native thinking behavior while keeping billing predictable.": "Điều chỉnh các yêu cầu có hậu tố `-thinking` sang hành vi suy luận gốc của Anthropic trong khi vẫn giữ tính phí dễ dự đoán.", + "Adapt `-thinking`, `-nothinking`, and effort suffixes such as `-high` to Anthropic native thinking behavior while keeping billing predictable. When off, model names are sent upstream unchanged.": "Điều chỉnh các yêu cầu có hậu tố `-thinking`, `-nothinking` và các hậu tố mức suy luận như `-high` sang hành vi suy luận gốc của Anthropic trong khi vẫn giữ tính phí dễ dự đoán. Khi tắt, tên mô hình được gửi nguyên vẹn lên upstream.", "Add": "Add", "Add \"{{value}}\"": "Thêm \"{{value}}\"", "Add {{added}} models and remove {{removed}} models": "Thêm {{added}} mô hình và xóa {{removed}} mô hình", diff --git a/web/src/i18n/locales/zh-TW.json b/web/src/i18n/locales/zh-TW.json index cc1ff2915..5b2bab0e7 100644 --- a/web/src/i18n/locales/zh-TW.json +++ b/web/src/i18n/locales/zh-TW.json @@ -116,7 +116,7 @@ "#1 by usage": "使用量第一", "#1 Model": "#1 模型", "% off": "折", - "`, and `-nothinking` suffixes while routing to the correct Gemini variant.": "`, 及 `-nothinking` 後綴,同時路由到正確的 Gemini 變體。", + "`, `-nothinking`, and effort suffixes such as `-high` while routing to the correct Gemini variant. When off, model names are sent upstream unchanged.": "`、`-nothinking` 以及 `-high` 等推理強度後綴,同時路由到正確的 Gemini 變體。關閉後模型名原樣傳送給上游。", "© 2025 Your Company. All rights reserved.": "© 2025 您的公司。保留所有權利。", "+{{count}} more": "還有 {{count}} 項", "| Based on": "| 基於", @@ -243,7 +243,7 @@ "Actual Amount": "實付金額", "Actual Model": "實際模型", "Actual Model:": "實際模型:", - "Adapt `-thinking` suffix requests to Anthropic native thinking behavior while keeping billing predictable.": "將帶 `-thinking` 後綴的請求適配為 Anthropic 原生思考請求,並保持收費可預測。", + "Adapt `-thinking`, `-nothinking`, and effort suffixes such as `-high` to Anthropic native thinking behavior while keeping billing predictable. When off, model names are sent upstream unchanged.": "將帶 `-thinking`、`-nothinking` 以及 `-high` 等推理強度後綴的請求適配為 Anthropic 原生思考請求,並保持收費可預測。關閉後模型名原樣傳送給上游。", "Add": "新增", "Add \"{{value}}\"": "新增 \"{{value}}\"", "Add {{added}} models and remove {{removed}} models": "新增 {{added}} 個模型,移除 {{removed}} 個模型", diff --git a/web/src/i18n/locales/zh.json b/web/src/i18n/locales/zh.json index 9f1f683cc..58839b2e6 100644 --- a/web/src/i18n/locales/zh.json +++ b/web/src/i18n/locales/zh.json @@ -116,7 +116,7 @@ "#1 by usage": "使用量第一", "#1 Model": "#1 模型", "% off": "折", - "`, and `-nothinking` suffixes while routing to the correct Gemini variant.": "`, 和 `-nothinking` 后缀,同时路由到正确的 Gemini 变体。", + "`, `-nothinking`, and effort suffixes such as `-high` while routing to the correct Gemini variant. When off, model names are sent upstream unchanged.": "`、`-nothinking` 以及 `-high` 等推理强度后缀,同时路由到正确的 Gemini 变体。关闭后模型名原样发送给上游。", "© 2025 Your Company. All rights reserved.": "© 2025 您的公司。保留所有权利。", "+{{count}} more": "还有 {{count}} 项", "| Based on": "| 基于", @@ -243,7 +243,7 @@ "Actual Amount": "实付金额", "Actual Model": "实际模型", "Actual Model:": "实际模型:", - "Adapt `-thinking` suffix requests to Anthropic native thinking behavior while keeping billing predictable.": "将带 `-thinking` 后缀的请求适配为 Anthropic 原生思考请求,并保持计费可预测。", + "Adapt `-thinking`, `-nothinking`, and effort suffixes such as `-high` to Anthropic native thinking behavior while keeping billing predictable. When off, model names are sent upstream unchanged.": "将带 `-thinking`、`-nothinking` 以及 `-high` 等推理强度后缀的请求适配为 Anthropic 原生思考请求,并保持计费可预测。关闭后模型名原样发送给上游。", "Add": "添加", "Add \"{{value}}\"": "添加 \"{{value}}\"", "Add {{added}} models and remove {{removed}} models": "新增 {{added}} 个模型,移除 {{removed}} 个模型",