feat: gpt-5.6 support

This commit is contained in:
leokun
2026-07-10 11:38:45 +08:00
parent 6ab537ad4e
commit e0aa270328
15 changed files with 70 additions and 37 deletions
+1 -1
View File
@@ -8,7 +8,7 @@ info:
description: "Cursor助手"
copyright: "© 2026, Cursor助手"
comments: "Cursor助手"
version: "0.0.39"
version: "0.0.40"
dev_mode:
root_path: .
@@ -23,6 +23,7 @@ const reasoningEffortOptions = [
{ label: "中", value: "medium", icon: "icon-[mdi--head-lightbulb-outline]" },
{ label: "高", value: "high", icon: "icon-[mdi--brain]" },
{ label: "极高", value: "xhigh", icon: "icon-[mdi--head-cog-outline]" },
{ label: "最高", value: "max", icon: "icon-[mdi--brain]" },
];
const anthropicThinkingEffortOptions = [
+29 -12
View File
@@ -274,18 +274,6 @@
}
]
},
"1b7d24b212e52c54": {
"source": "{0} 的推理强度仅支持 low、medium、high、xhigh",
"kind": "template",
"placeholders": 1,
"refs": [
{
"file": "src/state/appState.js",
"line": 315,
"column": 14
}
]
},
"1bc77f5ab979f4c1": {
"source": "新增模型配置",
"kind": "text",
@@ -1175,6 +1163,23 @@
}
]
},
"8672864e90417138": {
"source": "最高",
"kind": "text",
"placeholders": 0,
"refs": [
{
"file": "src/components/ModelAdapterModal.vue",
"line": 26,
"column": 12
},
{
"file": "src/views/ModelEditor.vue",
"line": 41,
"column": 12
}
]
},
"86df7ec743047234": {
"source": "服务运行中",
"kind": "text",
@@ -2110,6 +2115,18 @@
}
]
},
"dbb4b5be9b5723dc": {
"source": "{0} 的推理强度仅支持 low、medium、high、xhigh、max",
"kind": "template",
"placeholders": 1,
"refs": [
{
"file": "src/state/appState.js",
"line": 435,
"column": 14
}
]
},
"dbee6e7139243362": {
"source": "{0} 的接口地址不能为空",
"kind": "template",
+2 -1
View File
@@ -21,7 +21,6 @@
"15d124b200ddabed": "Maximum number of context tokens the model can accept in a single request. Leave blank to use the default.",
"18b7312022cd1840": "Start Service",
"1af38868896cf53d": "Routing mode only supports local or upstream",
"1b7d24b212e52c54": "{0} reasoning effort only supports low, medium, high, and xhigh",
"1bc77f5ab979f4c1": "Add Model Settings",
"1e238093b79b3165": "Uses 65536 by default when left blank",
"24343a2096988d42": "Failed to open",
@@ -84,6 +83,7 @@
"7e9e334aeb0bdc07": "Service operation failed",
"7f68ebad19ba6bcd": "Check for Updates",
"81123c56d5d880d0": "API Key",
"8672864e90417138": "Max",
"86df7ec743047234": "Service running",
"87ed126f7bd1121e": "Routing Mode",
"899add6275682210": "Uses 200000 by default when left blank",
@@ -154,6 +154,7 @@
"d7da2aabd35772ec": "e.g. 200000 (leave blank to use the default)",
"da590a8fe3ce4de0": "Please select",
"daede9881787abe7": "Notes",
"dbb4b5be9b5723dc": "{0} reasoning effort only supports low, medium, high, xhigh, and max",
"dbee6e7139243362": "{0} base URL cannot be empty",
"dc82c5e8fb2ab777": "Version: v{0}",
"de8184da1ef88d03": "Configured",
+2 -1
View File
@@ -21,7 +21,6 @@
"15d124b200ddabed": "モデルが1回のリクエストで受け取れる最大コンテキスト Token 数。空欄の場合はデフォルト値を使用します。",
"18b7312022cd1840": "サービスを開始",
"1af38868896cf53d": "ルーティングモードは local または upstream のみサポートします",
"1b7d24b212e52c54": "{0} の推論強度は low、medium、high、xhigh のみサポートします",
"1bc77f5ab979f4c1": "モデル設定を追加",
"1e238093b79b3165": "空欄で 65536",
"24343a2096988d42": "開けませんでした",
@@ -84,6 +83,7 @@
"7e9e334aeb0bdc07": "サービス操作に失敗しました",
"7f68ebad19ba6bcd": "アップデートを確認",
"81123c56d5d880d0": "API キー",
"8672864e90417138": "最大",
"86df7ec743047234": "サービス稼働中",
"87ed126f7bd1121e": "ルーティングモード",
"899add6275682210": "空欄で 200000",
@@ -154,6 +154,7 @@
"d7da2aabd35772ec": "例: 200000(空欄でデフォルト値)",
"da590a8fe3ce4de0": "選択してください",
"daede9881787abe7": "メモ",
"dbb4b5be9b5723dc": "{0} の推論強度は low、medium、high、xhigh、max のみサポートします",
"dbee6e7139243362": "{0} のベース URL は必須です",
"dc82c5e8fb2ab777": "バージョン: v{0}",
"de8184da1ef88d03": "設定済み",
+2 -1
View File
@@ -21,7 +21,6 @@
"15d124b200ddabed": "模型单次可接受的最大上下文 Token 数。留空时使用默认值。",
"18b7312022cd1840": "启动服务",
"1af38868896cf53d": "运行模式仅支持 local 或 upstream",
"1b7d24b212e52c54": "{0} 的推理强度仅支持 low、medium、high、xhigh",
"1bc77f5ab979f4c1": "新增模型配置",
"1e238093b79b3165": "留空时默认 65536",
"24343a2096988d42": "打开失败",
@@ -84,6 +83,7 @@
"7e9e334aeb0bdc07": "服务操作失败",
"7f68ebad19ba6bcd": "检查更新",
"81123c56d5d880d0": "访问密钥",
"8672864e90417138": "最高",
"86df7ec743047234": "服务运行中",
"87ed126f7bd1121e": "运行模式",
"899add6275682210": "留空时默认 200000",
@@ -154,6 +154,7 @@
"d7da2aabd35772ec": "例如:200000(留空用默认值)",
"da590a8fe3ce4de0": "请选择",
"daede9881787abe7": "备注",
"dbb4b5be9b5723dc": "{0} 的推理强度仅支持 low、medium、high、xhigh、max",
"dbee6e7139243362": "{0} 的接口地址不能为空",
"dc82c5e8fb2ab777": "版本:v{0}",
"de8184da1ef88d03": "已配置",
+2 -2
View File
@@ -22,7 +22,7 @@ import {
const APP_STATE_STORAGE_KEY = "cursor-client:runtime-state:v2";
const GENERIC_SERVICE_ERROR = "服务错误";
const SUPPORTED_MODEL_ADAPTER_TYPES = new Set(["openai", "anthropic"]);
const SUPPORTED_REASONING_EFFORTS = new Set(["low", "medium", "high", "xhigh"]);
const SUPPORTED_REASONING_EFFORTS = new Set(["low", "medium", "high", "xhigh", "max"]);
const SUPPORTED_ANTHROPIC_THINKING_EFFORTS = new Set(["low", "medium", "high", "xhigh", "max"]);
export const ANTHROPIC_THINKING_EFFORT_DEFAULT = "xhigh";
export const OPENAI_ENDPOINT_RESPONSES = "/v1/responses";
@@ -432,7 +432,7 @@ export function validateModelAdapters(source) {
return `${prefix} 的模型标识不能为空`;
}
if (adapter.type === "openai" && !SUPPORTED_REASONING_EFFORTS.has(adapter.reasoningEffort)) {
return `${prefix} 的推理强度仅支持 low、medium、high、xhigh`;
return `${prefix} 的推理强度仅支持 low、medium、high、xhigh、max`;
}
if (adapter.type === "openai" && !isValidOpenAIEndpoint(adapter.openAIEndpoint)) {
return `${prefix} 的 OpenAI 端点仅支持 /v1/responses、/v1/chat/completions 或以 / 开头的自定义路径`;
+1
View File
@@ -38,6 +38,7 @@ const reasoningEffortOptions = [
{ label: "中", value: "medium", icon: "icon-[mdi--head-lightbulb-outline]" },
{ label: "高", value: "high", icon: "icon-[mdi--brain]" },
{ label: "极高", value: "xhigh", icon: "icon-[mdi--head-cog-outline]" },
{ label: "最高", value: "max", icon: "icon-[mdi--brain]" },
];
const anthropicThinkingEffortOptions = [
+17 -9
View File
@@ -29,7 +29,7 @@ type openAIRequestBody struct {
Tools []json.RawMessage `json:"tools,omitempty"`
Messages []map[string]any `json:"messages"`
Stream bool `json:"stream"`
MaxTokens int `json:"max_tokens"`
MaxTokens int `json:"max_tokens,omitempty"`
StreamOptions map[string]any `json:"stream_options"`
ReasoningEffort string `json:"reasoning_effort,omitempty"`
PromptCacheKey string `json:"prompt_cache_key,omitempty"`
@@ -41,7 +41,7 @@ type openAIResponsesRequestBody struct {
Input []map[string]any `json:"input"`
Tools []map[string]any `json:"tools,omitempty"`
Stream bool `json:"stream"`
MaxOutputTokens int `json:"max_output_tokens"`
MaxOutputTokens int `json:"max_output_tokens,omitempty"`
Reasoning *openAIResponsesReasoning `json:"reasoning,omitempty"`
Include []string `json:"include,omitempty"`
PromptCacheKey string `json:"prompt_cache_key,omitempty"`
@@ -455,9 +455,11 @@ func (adapter *OpenAIAdapter) streamChatCompletions(ctx context.Context, req Str
Model: modelID,
Messages: normalizedMessages,
Stream: true,
MaxTokens: req.MaxTokens,
StreamOptions: map[string]any{"include_usage": true},
}
if shouldSendOpenAIMaxOutputTokens(modelID) {
requestBody.MaxTokens = req.MaxTokens
}
if key := openAIPromptCacheKey(req, modelID); key != "" {
requestBody.PromptCacheKey = key
}
@@ -914,12 +916,14 @@ func (adapter *OpenAIAdapter) streamResponses(ctx context.Context, req StreamReq
return err
}
requestBody := openAIResponsesRequestBody{
Model: modelID,
Instructions: instructions,
Input: input,
Stream: true,
MaxOutputTokens: req.MaxTokens,
Store: false,
Model: modelID,
Instructions: instructions,
Input: input,
Stream: true,
Store: false,
}
if shouldSendOpenAIMaxOutputTokens(modelID) {
requestBody.MaxOutputTokens = req.MaxTokens
}
if key := openAIPromptCacheKey(req, modelID); key != "" {
requestBody.PromptCacheKey = key
@@ -1844,6 +1848,10 @@ func normalizeOpenAIProviderMessages(messages []Message, thinkingEnabled bool) (
return items, nil
}
func shouldSendOpenAIMaxOutputTokens(modelID string) bool {
return !strings.Contains(strings.ToLower(strings.TrimSpace(modelID)), "gpt")
}
func shouldIncludeOpenAIReasoningContent(message Message, thinkingEnabled bool) bool {
if strings.TrimSpace(message.ReasoningContent) != "" {
return true
+2 -2
View File
@@ -152,7 +152,7 @@ func NormalizeModelAdapterConfigs(input []ModelAdapterConfig) ([]ModelAdapterCon
case next.ModelID == "":
return nil, errors.New("模型适配器 modelID 不能为空")
case next.Type == "openai" && next.ReasoningEffort == "":
return nil, errors.New("模型适配器 reasoningEffort 仅支持 low、medium、high、xhigh")
return nil, errors.New("模型适配器 reasoningEffort 仅支持 low、medium、high、xhigh、max")
case next.Type == "openai" && next.OpenAIEndpoint == "":
return nil, errors.New("模型适配器 openAIEndpoint 仅支持 /v1/responses、/v1/chat/completions 或 /custom(自定义路径)")
case next.Type == "openai" && next.OpenAIExtraParamsEnabled:
@@ -216,7 +216,7 @@ func normalizeReasoningEffort(value string) string {
switch strings.ToLower(strings.TrimSpace(value)) {
case "", "medium":
return "medium"
case "low", "high", "xhigh":
case "low", "high", "xhigh", "max":
return strings.ToLower(strings.TrimSpace(value))
default:
return ""
+2 -2
View File
@@ -746,7 +746,7 @@ func buildThinkingEffortVariantDisplayName(modelDisplayName string, effortValue
func thinkingEffortValuesForAdapter(adapterType string) []string {
values := []string{"disabled", "low", "medium", "high", "xhigh"}
if strings.EqualFold(strings.TrimSpace(adapterType), "anthropic") {
if adapterType := strings.ToLower(strings.TrimSpace(adapterType)); adapterType == "openai" || adapterType == "anthropic" {
values = append(values, "max")
}
return values
@@ -773,7 +773,7 @@ func defaultThinkingEffortForAdapter(adapter legacyruntime.ModelAdapterConfig) s
if strings.EqualFold(strings.TrimSpace(adapter.Type), "anthropic") {
return normalizeAvailableModelThinkingEffort(adapter.AnthropicThinkingEffort, true, "xhigh")
}
return normalizeAvailableModelThinkingEffort(adapter.ReasoningEffort, false, "medium")
return normalizeAvailableModelThinkingEffort(adapter.ReasoningEffort, true, "medium")
}
func normalizeAvailableModelThinkingEffort(raw string, allowMax bool, fallback string) string {
+1 -1
View File
@@ -668,7 +668,7 @@ func normalizeModelAdapterTestType(value string) string {
func normalizeModelAdapterTestReasoning(value string) string {
switch strings.ToLower(strings.TrimSpace(value)) {
case "low", "medium", "high", "xhigh":
case "low", "medium", "high", "xhigh", "max":
return strings.ToLower(strings.TrimSpace(value))
default:
return "medium"
+2 -2
View File
@@ -138,7 +138,7 @@ func NormalizeModelAdapterConfigs(input []ModelAdapterConfig) ([]ModelAdapterCon
case next.ModelID == "":
return nil, errors.New("模型适配器 modelID 不能为空")
case next.Type == "openai" && next.ReasoningEffort == "":
return nil, errors.New("模型适配器 reasoningEffort 仅支持 low、medium、high、xhigh")
return nil, errors.New("模型适配器 reasoningEffort 仅支持 low、medium、high、xhigh、max")
case next.Type == "openai" && next.OpenAIEndpoint == "":
return nil, errors.New("模型适配器 openAIEndpoint 仅支持 /v1/responses 或 /v1/chat/completions")
case next.Type == "openai" && next.OpenAIExtraParamsEnabled:
@@ -202,7 +202,7 @@ func normalizeReasoningEffort(value string) string {
switch strings.ToLower(strings.TrimSpace(value)) {
case "", "medium":
return "medium"
case "low", "high", "xhigh":
case "low", "high", "xhigh", "max":
return strings.ToLower(strings.TrimSpace(value))
default:
return ""
+3 -1
View File
@@ -1,8 +1,10 @@
你是一个极度务实且高效的软件工程师。你认真对待工程质量,并以直接、客观的陈述方式体现协作。你沟通高效,在不加入无关细节的前提下,清楚告知用户你正在进行的操作。
!IMPORTANT 如非用户明确要求,禁止使用Subagent
你具有极强的架构经验和模块化经验,当用户提出泛泛的需求时,**你会不断评估架构、模块、数据流向、状态机的合理性**,你会自信的引导用户重构代码。
不会从代码、函数等层面交流,只输出你认为用户能看懂的数据结构、演变过程、模块关系、作用域、伪代码等,**并附带注释**。
你只输出你认为普通用户能看懂的回复,再不炫技的情况下回复内容可能是数据结构、演变过程、模块关系、作用域、伪代码、mermaid等,**并附带注释**。
除非你已经确定项目是面向对象的,其他情况下你都偏好 Functional Programming. DSL化编码风格是是你喜欢的,也是用户喜欢的,也是可读的、优秀的。
+3 -2
View File
@@ -1,5 +1,6 @@
QQ10群:1049354347
----
- 更新支持最新版Cursor 3.9.16
- 支持多工作区模式
- 支持 GPT 5.6
- 修复一些bug