feat(core): allow openai-compatible relays to declare per-model thinking options - #2351
feat(core): allow openai-compatible relays to declare per-model thinking options#2351cat0825 wants to merge 1 commit into
Conversation
|
写完才发现这个 pr,撞车了😭。 |
…ing options openai-compatible (relay/proxy) connections have no built-in catalog entry, so thinkingVariantsForModel always reported no thinking support and the chat composer hid the thinking-level selector, even when the backing model speaks reasoning_effort. The wire layer already mapped the level when it reached buildProviderOptions; the missing piece was a way to declare it. - ModelInfo.thinkingOptions (optional): user-declared ThinkingOptions for a connection model; wins over the catalog when present. - thinkingVariantsForConnection(connection, modelId): declaration-first lookup with catalog fallback, used everywhere a connection object exists (chat model choices, runtime wire, session IPC validation, subagent settings, runtime-host coordinator). - Connection settings: new "思考级别" editor per enabled model, choosing effort levels (none/low/medium/high/xhigh/max) sent verbatim as reasoning_effort (off -> none). - Storage: a fetched model refresh merges declarations back by id, so updating the /v1/models list no longer drops the user's setup. CLI (pi-tui-runner) keeps the old provider+model lookup: it has no connection object to read declarations from; behavior unchanged there. Fixes apache#2219
6480816 to
9e70cff
Compare
Review decisionClosing in favor of #2391 (and the rebased follow-up once landed). Why #2391 supersedes this PR Both PRs address #2219 (openai-compatible relays declaring thinking capabilities). The approaches differ on a first-principles ownership question:
Putting user configuration inside Conflict state against current Thank you for the solid exploration — the wire path ( |
|
Superseded by #2391's relayModelProfiles design (see review comment). |
概述
修复 #2219:openai-compatible(中转站/代理)连接现在可以在模型上手动声明
thinkingOptions,声明后聊天输入框显示思考级别选择器,请求体携带对应的reasoning_effort。wire 层此前已就绪(
buildFamilyWire的 openai-compatible 分支把 level 映射为reasoning_effort,off→none),缺的是「声明 → 查询 → 校验 → UI」这条链。变更
数据模型(
packages/core/src/llm-connections.ts)ModelInfo新增可选thinkingOptions?: ThinkingOptions,复用现有类型,未声明时行为与之前完全一致。查询(
packages/core/src/model-thinking.ts)thinkingVariantsForConnection(connection, modelId):连接模型列表里的显式声明优先,miss 时回退内置目录。任意 providerType 通用(用户声明的模型覆盖目录),不再是 issue 草案里的 openai-compatible 特判——语义更干净:目录条目对未声明模型仍然生效。链路替换(所有能拿到 connection 对象的调用点)
chat-model-choice.ts(模型选择器的 thinkingLevels)model-factory.tsbuildProviderOptions+ responses wire 的forceReasoning判定sessions-ipc-main.tsnormalizeSupportedSessionThinkingLevel(建会话 / 切换思考级别两个入口)subagent-settings-page.tsxruntime-host/session-catalog-coordinator.tsUI(连接设置页 · 模型区)
none/low/medium/high/xhigh/max)→ 保存;清空即撤销声明。reasoning_effort发送,UI 文案提示用户先确认中转站透传(常见取值low/high/max)。use-connection-detail增加saveThinkingOptions。存储(
packages/storage/src/connection-store.ts)/v1/models)会整体替换模型列表;现在按 id 把用户声明 merge 回去,刷新不再丢声明。测试
model-thinking.test.ts:声明优先 / 目录回退 /none出 off 档model-factory-thinking.test.ts:relay 声明 → wire 输出{ [slug]: { reasoningEffort } },未声明模型保持静默connection-store.test.ts:fetched 刷新保留声明验证
npm run typecheck全 workspace 通过(含 desktop 4 个 tsconfig)范围说明
pi-tui-runner.ts)未改:它只有providerType + modelId,没有 connection 对象可读声明,行为不变。none时才暴露(与目录规则一致,无真实 off wire 的模型不暴露 off);声明['low','high','max']时选 off 会被正常拒绝。reasoning_effort: none报错的情况需要用户自行用 curl 验证透传,UI 文案已提示。Fixes #2219