Skip to content

Fix chat readiness for picker model override#839

Open
lucyonegit wants to merge 1 commit into
fathah:mainfrom
lucyonegit:fix/chat-picker-readiness
Open

Fix chat readiness for picker model override#839
lucyonegit wants to merge 1 commit into
fathah:mainfrom
lucyonegit:fix/chat-picker-readiness

Conversation

@lucyonegit

Copy link
Copy Markdown

问题描述

在 Chat 页面底部的模型选择器中,用户已经选择了模型,例如 qwen3.7-plus,但聊天输入框上方仍然可能显示:

No model selected. Pick one in Models or the Chat picker.

原因是发送前的 readiness 校验只读取持久化的全局模型配置,也就是 config.yaml 里的默认模型;而 Chat 底部 picker 选择的是当前会话的临时模型覆盖值。

当全局默认模型为空,但当前 Chat picker 已经选中模型时,实际发送消息会使用 picker 里的模型,但 readiness 校验仍然误判为“没有选择模型”,导致界面出现错误提示。

解决方案

让发送前 readiness 校验使用当前 Chat picker 的实际选择。

具体调整:

  • Chat 页面调用 validateChatReadiness 时传入当前 picker 的 provider / model / baseUrl
  • 主进程 validateChatReadiness 支持接收模型配置 override
  • 校验时优先使用当前会话 picker 的 override,再回退到持久化全局配置
  • 更新 preload / IPC 类型,让 renderer 可以把 override 传到 main process
  • 添加回归测试,验证全局默认模型为空但 Chat picker 已选模型时,不再返回 NO_ACTIVE_MODEL
  • 更新模型选择相关文档

影响范围

  • 不改变全局默认模型配置
  • 不改变 Chat picker 的选择逻辑
  • 不改变消息发送逻辑
  • 仅修复发送前提示/校验与实际 Chat picker 选择不一致的问题

@greptile-apps

greptile-apps Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR makes Chat readiness validation use the active picker selection. The main changes are:

  • Pass the current picker provider, model, and base URL from Chat.
  • Forward the override through preload and IPC.
  • Prefer the override in main-process readiness validation.
  • Add a regression test and update model-selection docs.

Confidence Score: 5/5

This looks safe to merge after a small readiness fallback cleanup.

  • The main picker override flow is wired through Chat, preload, IPC, and validation.
  • The readiness effect reruns when the picker values change.
  • An empty override model can still mask the persisted default and show the wrong readiness error.

src/main/validation.ts

Important Files Changed

Filename Overview
src/main/validation.ts Adds an optional chat-local model override to readiness validation; empty override model values can still mask the persisted default.
src/main/ipc/register.ts Forwards the optional readiness override through the main-process IPC handler.
src/preload/index.ts Extends the preload bridge so the renderer can pass a readiness override.
src/preload/index.d.ts Updates the renderer-facing API type for the optional readiness override.
src/renderer/src/screens/Chat/Chat.tsx Passes picker-derived provider, model, and base URL into the readiness check.
tests/validation.test.ts Adds coverage for a valid picker-selected model when the persisted model is empty.
lat.md/model-selection.md Documents that pre-send readiness uses the active Chat picker override.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
  participant Chat as Chat.tsx
  participant Preload as preload hermesAPI
  participant IPC as ipcMain handler
  participant Validation as validateChatReadiness
  participant Config as persisted config

  Chat->>Preload: validateChatReadiness(profile, pickerOverride)
  Preload->>IPC: invoke("validate-chat-readiness", profile, override)
  IPC->>Validation: validateChatReadiness(profile, override)
  Validation->>Config: getModelConfig(profile)
  Validation-->>Validation: prefer override, fallback to config
  Validation-->>Chat: readiness result
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
  participant Chat as Chat.tsx
  participant Preload as preload hermesAPI
  participant IPC as ipcMain handler
  participant Validation as validateChatReadiness
  participant Config as persisted config

  Chat->>Preload: validateChatReadiness(profile, pickerOverride)
  Preload->>IPC: invoke("validate-chat-readiness", profile, override)
  IPC->>Validation: validateChatReadiness(profile, override)
  Validation->>Config: getModelConfig(profile)
  Validation-->>Validation: prefer override, fallback to config
  Validation-->>Chat: readiness result
Loading

Reviews (1): Last reviewed commit: "Fix chat readiness for picker model over..." | Re-trigger Greptile

Comment thread src/main/validation.ts
const provider = (override?.provider ?? mc.provider ?? "")
.trim()
.toLowerCase();
const model = (override?.model ?? mc.model ?? "").trim();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Empty Override Masks Default

When the readiness override object contains model: "", this line keeps the empty value instead of falling back to the persisted model. The send path falls back for an empty override model, so this can show NO_ACTIVE_MODEL and block a send that would otherwise use the configured default model.

Suggested change
const model = (override?.model ?? mc.model ?? "").trim();
const model = (override?.model || mc.model || "").trim();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant