Skip to content

fix(api): honor the Chat task preset for local API / MCP chat - #730

Open
johnsonafool wants to merge 1 commit into
nashsu:mainfrom
johnsonafool:fix/api-chat-preset
Open

fix(api): honor the Chat task preset for local API / MCP chat#730
johnsonafool wants to merge 1 commit into
nashsu:mainfrom
johnsonafool:fix/api-chat-preset

Conversation

@johnsonafool

@johnsonafool johnsonafool commented Sep 6, 2026

Copy link
Copy Markdown

Problem

When the desktop app is configured with different models per task — the very common setup Ingest: Claude Code CLI, Chat: Azure / OpenAI — every chat that goes through the local HTTP API (POST /api/v1/projects/{id}/chat) and therefore through the bundled MCP server ignores the Chat routing. load_agent_runtime_config in api_server.rs only looks at the enabled project override and the global llmConfig, so it resolves to the CLI provider, which the backend HTTP agent cannot drive (is_usable_for_backend_http → false), and the turn degrades to the retrieval-only fallback answer ("I searched the current LLM Wiki project for … and found N relevant page(s)").

The desktop UI does not hit this because the frontend resolves the preset itself (resolveTaskLlmConfig) before calling the runtime.

Fix

Resolve the Chat task preset on the backend with the same precedence the frontend uses:

  1. enabled project override (unchanged behaviour)
  2. taskModelRouting.chatPresetIdproviderConfigs[presetId], mapped onto LlmConfig (built-in preset ids with their default endpoints / API modes, custom-* presets validated against customLlmPresets)
  3. global llmConfig (unchanged behaviour)

Presets the backend cannot use (claude-code, codex-cli, missing key or model) return None, so nothing changes for them.

Verified

  • Windows, desktop 0.6.11, Chat preset = Azure gpt-4o, ingest = Claude Code CLI. Before: API chat returned the search-hit dump with toolEvents only. After: a synthesized answer with citations in ~4 s.
  • Unit test chat_preset_routes_api_chat_to_the_selected_provider covers: built-in preset (Azure), CLI preset → None, known custom preset defaults (DeepSeek), unknown / deleted custom presets → None, and disabled project override yielding to the Chat preset.

Notes for review

  • The built-in preset table (BUILTIN_LLM_PRESETS) duplicates the ids/defaults from src/components/settings/llm-presets.ts. If you would rather have the frontend persist a resolved, non-secret chat profile (the way projectLlmOverrides[].profile already works) and merge credentials at runtime, I'm happy to rework it that way — this version is the smallest change that makes MCP/API chat follow the user's routing.

`load_agent_runtime_config` only looked at the project override and the
global `llmConfig`, ignoring `taskModelRouting.chatPresetId`. With the
common setup "Ingest: Claude Code CLI, Chat: Azure / OpenAI", every chat
through the local HTTP API (and therefore the MCP server) resolved to the
CLI provider, which the backend HTTP agent cannot drive, and degraded to
the retrieval-only fallback answer.

Resolve the Chat preset the same way `resolveTaskLlmConfig` does in
src/lib/llm-task-routing.ts: enabled project override -> Chat preset from
`providerConfigs` (built-in ids and `custom-*` presets) -> global
`llmConfig`. Presets the backend cannot use (claude-code, codex-cli,
missing key/model) yield None so behaviour is unchanged for them.

Verified on Windows (0.6.11 desktop): with Chat = Azure gpt-4o, the API
chat went from dumping search hits to a synthesized answer with citations.
Unit test covers built-in, CLI, custom, unknown/deleted presets and the
project-override precedence.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
johnsonafool added a commit to johnsonafool/llm_wiki that referenced this pull request Sep 6, 2026
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
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