fix(followup): fix follow-up suggestions not working on OpenAI-compatible providers (#3151)
Some checks are pending
Qwen Code CI / Lint (push) Waiting to run
Qwen Code CI / Test (push) Blocked by required conditions
Qwen Code CI / Test-1 (push) Blocked by required conditions
Qwen Code CI / Test-2 (push) Blocked by required conditions
Qwen Code CI / Test-3 (push) Blocked by required conditions
Qwen Code CI / Test-4 (push) Blocked by required conditions
Qwen Code CI / Test-5 (push) Blocked by required conditions
Qwen Code CI / Test-6 (push) Blocked by required conditions
Qwen Code CI / Test-7 (push) Blocked by required conditions
Qwen Code CI / Test-8 (push) Blocked by required conditions
Qwen Code CI / Post Coverage Comment (push) Blocked by required conditions
Qwen Code CI / CodeQL (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:docker (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:none (push) Waiting to run
E2E Tests / E2E Test - macOS (push) Waiting to run

* fix(followup): fix follow-up suggestions not working on OpenAI-compatible providers

- Respect request.model in pipeline so fastModel setting takes effect
- Skip empty tools array to avoid 400 errors from providers
- Override enable_thinking/reasoning from extra_body when thinking is
  explicitly disabled for suggestion generation
- Filter thought parts from response text in both forkedQuery and
  baseLlm paths to prevent thinking content leaking into suggestions
- Add debug logging (tag: FOLLOWUP) for suggestion generation diagnostics

* fix(followup): validate fastModel belongs to current authType

When the configured fastModel is from a different auth type/provider
than the main model, the API call silently fails because the current
content generator rejects unknown model IDs. Fall back to the main
model in that case so suggestion generation stays functional.

Reported by @yiliang114 in #3151.
This commit is contained in:
Shaojin Wen 2026-04-12 16:07:00 +08:00 committed by GitHub
parent fea61e1788
commit 7614c8c58e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 286 additions and 16 deletions

View file

@ -1113,6 +1113,24 @@ export const AppContainer = (props: AppContainerProps) => {
const followupSuggestionsEnabled =
settings.merged.ui?.enableFollowupSuggestions === true;
// Resolve fastModel, validating it belongs to the current authType.
// If the configured fastModel is from a different provider, the API call
// would fail silently (DashScope/Qwen client rejects unknown model IDs),
// so fall back to the main model instead.
const resolveFastModel = useCallback((): string | undefined => {
const fastModel = settings.merged.fastModel;
if (!fastModel) return undefined;
const currentAuthType = config.getContentGeneratorConfig()?.authType;
if (!currentAuthType) return undefined;
const availableModels = config
.getModelsConfig()
.getAvailableModelsForAuthType(currentAuthType);
const belongsToCurrentAuth = availableModels.some(
(m) => m.id === fastModel,
);
return belongsToCurrentAuth ? fastModel : undefined;
}, [settings.merged.fastModel, config]);
useEffect(() => {
// Clear suggestion when feature is disabled at runtime
if (!followupSuggestionsEnabled) {
@ -1164,9 +1182,10 @@ export const AppContainer = (props: AppContainerProps) => {
const fullHistory = geminiClient.getChat().getHistory(true);
const conversationHistory =
fullHistory.length > 40 ? fullHistory.slice(-40) : fullHistory;
const fastModel = resolveFastModel();
generatePromptSuggestion(config, conversationHistory, ac.signal, {
enableCacheSharing: settings.merged.ui?.enableCacheSharing === true,
model: settings.merged.fastModel || undefined,
model: fastModel,
})
.then((result) => {
if (ac.signal.aborted) return;
@ -1175,7 +1194,7 @@ export const AppContainer = (props: AppContainerProps) => {
// Start speculation if enabled (runs in background)
if (settings.merged.ui?.enableSpeculation) {
startSpeculation(config, result.suggestion, ac.signal, {
model: settings.merged.fastModel || undefined,
model: fastModel,
})
.then((state) => {
speculationRef.current = state;