概述
openai-compatible(中转站/代理)连接无法调节模型思考深度:聊天输入框左下角不显示"思考级别"选择器,请求体也不会带上 reasoning_effort。
DeepSeek 官方 API 已支持 reasoning_effort: low/high/max + thinking: {type: enabled/disabled}(OpenAI 兼容格式),且该参数是 OpenAI 兼容协议的标准顶层参数,透传型中转站原样转发即可生效。堵住的不是中转站,而是 Maka 这一层没有暴露声明入口。
期望:用户能在 openai-compatible 连接的模型上手动声明思考能力,声明后即可使用思考级别选择器,Maka 在请求中发送对应的 reasoning_effort。
复现
- Maka 0.1.5(macOS Apple Silicon)。
- 设置中添加 openai-compatible 连接(例如 DeepSeek 中转站,baseURL
https://tokenrhythm.studio/v1),模型列表通过 /v1/models 拉取。
- 新建聊天,选中该连接的 reasoning 模型(如
deepseek-v4-flash-0731)。
- 观察输入框左下角:模型选择器旁没有"思考级别"选择器。
根因
代码定位(当前 0.1.5):
packages/core/src/model-thinking.ts → thinkingVariantsForModel(providerType, modelId):
- 只按
providerType + modelId 查询内置目录 model-metadata.ts;
openai-compatible 无任何目录条目,直接返回 [];源码注释明确这是保守策略:"backing model is user-configured and unknown"。
- UI 层(
packages/ui/src/chat-model-switcher.tsx → ThinkingLevelSelector):levels 为空时直接 return null,控件不渲染。
- 服务端校验(
apps/desktop/src/main/sessions-ipc-main.ts → normalizeSupportedSessionThinkingLevel):同一函数校验,空列表时抛"当前模型不支持思考级别"。
- 连接模型条目 schema(
packages/core/src/llm-connections.ts):只有 id / displayName / apiProtocol / contextWindow / maxOutputTokens / capabilities / modalities,没有 thinkingOptions 字段,用户无从声明。
wire 层已就绪(无需改动)
- ai-sdk
@ai-sdk/openai-compatible:providerOptions 支持 reasoningEffort,映射为请求体顶层 reasoning_effort(dist/index.js:reasoning_effort: compatibleOptions.reasoningEffort ?? ...)。
packages/runtime/src/model-factory.ts → buildFamilyWire 已有 openai-compatible 分支:{ [openAiCompatibleProviderOptionsName(...)]: { reasoningEffort } },命名空间为 connection.slug。
即:只要 thinkingLevel 能进入 buildProviderOptions,请求就会自动带上 reasoning_effort。缺的只是"声明 → 查询 → 校验 → UI"这一条链。
建议方案(per-model 声明)
- 数据模型(
packages/core/src/llm-connections.ts):连接模型条目新增可选字段,复用现有 ThinkingOptions 类型:
thinkingOptions?: ThinkingOptions; // { efforts?: ['low','high','max'], toggle?: true }
向后兼容,未声明时行为与现在一致。
- 查询(
packages/core/src/model-thinking.ts):新增带 connection 的变体,目录 miss 时回退到连接声明:
export function thinkingVariantsForConnection(connection, modelId) {
if (connection.providerType === 'openai-compatible') {
const m = connection.models?.find((x) => x.id === modelId);
if (m?.thinkingOptions) return deriveThinkingChoices(m.thinkingOptions);
}
return thinkingVariantsForModel(connection.providerType, modelId);
}
- 校验(
apps/desktop/src/main/sessions-ipc-main.ts):normalizeSupportedSessionThinkingLevel 改用新函数(该处已有 connection 对象)。
- UI:
apps/desktop/src/renderer/use-shell-chat-model.ts(L123 / L139):thinkingVariantsForModel(providerType, model) → 换成带 connection 的版本;
- 连接设置页模型管理:新增"思考级别"编辑(启用开关 + 档位多选);subagent 设置页同步换函数。
- 测试:
model-thinking.test.ts 与 sessions-ipc 测试各补一个 openai-compatible 声明 case。
实现时需注意的坑
- off 档不能给 openai-compatible:ai-sdk openai-compatible 只映射
reasoning_effort,无 thinking: {type: 'disabled'} 通道;DeepSeek 的关闭思考依赖 thinking: {type: 'disabled'},而 reasoning_effort: 'none' 不在其取值表(low/high/max)。所以该场景档位只声明 low/high/max。
- xhigh 会被服务端映射:DeepSeek 官方映射表
xhigh → high,声明档位时建议直接给 low/high/max,避免暴露无效档位。
- 透传需用户自测:部分中转站会吞掉未知参数或报错,UI 或文档中应提示用户先用 curl 验证
reasoning_effort 是否透传。
- 不建议启发式模型名匹配:保持保守策略,只在用户显式声明后启用,不要自动猜。
概述
openai-compatible(中转站/代理)连接无法调节模型思考深度:聊天输入框左下角不显示"思考级别"选择器,请求体也不会带上
reasoning_effort。DeepSeek 官方 API 已支持
reasoning_effort: low/high/max+thinking: {type: enabled/disabled}(OpenAI 兼容格式),且该参数是 OpenAI 兼容协议的标准顶层参数,透传型中转站原样转发即可生效。堵住的不是中转站,而是 Maka 这一层没有暴露声明入口。期望:用户能在 openai-compatible 连接的模型上手动声明思考能力,声明后即可使用思考级别选择器,Maka 在请求中发送对应的
reasoning_effort。复现
https://tokenrhythm.studio/v1),模型列表通过/v1/models拉取。deepseek-v4-flash-0731)。根因
代码定位(当前 0.1.5):
packages/core/src/model-thinking.ts→thinkingVariantsForModel(providerType, modelId):providerType + modelId查询内置目录model-metadata.ts;openai-compatible无任何目录条目,直接返回[];源码注释明确这是保守策略:"backing model is user-configured and unknown"。packages/ui/src/chat-model-switcher.tsx→ThinkingLevelSelector):levels 为空时直接return null,控件不渲染。apps/desktop/src/main/sessions-ipc-main.ts→normalizeSupportedSessionThinkingLevel):同一函数校验,空列表时抛"当前模型不支持思考级别"。packages/core/src/llm-connections.ts):只有id / displayName / apiProtocol / contextWindow / maxOutputTokens / capabilities / modalities,没有thinkingOptions字段,用户无从声明。wire 层已就绪(无需改动)
@ai-sdk/openai-compatible:providerOptions 支持reasoningEffort,映射为请求体顶层reasoning_effort(dist/index.js:reasoning_effort: compatibleOptions.reasoningEffort ?? ...)。packages/runtime/src/model-factory.ts→buildFamilyWire已有openai-compatible分支:{ [openAiCompatibleProviderOptionsName(...)]: { reasoningEffort } },命名空间为connection.slug。即:只要 thinkingLevel 能进入
buildProviderOptions,请求就会自动带上reasoning_effort。缺的只是"声明 → 查询 → 校验 → UI"这一条链。建议方案(per-model 声明)
packages/core/src/llm-connections.ts):连接模型条目新增可选字段,复用现有ThinkingOptions类型:packages/core/src/model-thinking.ts):新增带 connection 的变体,目录 miss 时回退到连接声明:apps/desktop/src/main/sessions-ipc-main.ts):normalizeSupportedSessionThinkingLevel改用新函数(该处已有 connection 对象)。apps/desktop/src/renderer/use-shell-chat-model.ts(L123 / L139):thinkingVariantsForModel(providerType, model)→ 换成带 connection 的版本;model-thinking.test.ts与 sessions-ipc 测试各补一个 openai-compatible 声明 case。实现时需注意的坑
reasoning_effort,无thinking: {type: 'disabled'}通道;DeepSeek 的关闭思考依赖thinking: {type: 'disabled'},而reasoning_effort: 'none'不在其取值表(low/high/max)。所以该场景档位只声明low/high/max。xhigh → high,声明档位时建议直接给 low/high/max,避免暴露无效档位。reasoning_effort是否透传。