Skip to content

fix(custom): 首个模型自动设为默认 LLM,修复加模型后登录反复弹初始化 / auto-promote first model to default LLM - #780

Open
WenhuaXia wants to merge 1 commit into
AgentFlocks:mainfrom
WenhuaXia:fix/auto-promote-first-model-to-default
Open

WenhuaXia wants to merge 1 commit into
AgentFlocks:mainfrom
WenhuaXia:fix/auto-promote-first-model-to-default

Conversation

@WenhuaXia

Copy link
Copy Markdown

问题描述 / Bug Description

从模型管理页添加模型(非 onboarding 向导)后,provider 已配置、凭据已存、模型可用,但 default_models.llm 为空。/api/onboarding/status 要求「默认模型已设置 + 凭据可用」才返回 completed=True,而 WebUI 在 completed=False 时每次登录都强制弹出初始化向导(前端 dismissed flag 被测试用例显式忽略)。

结果:用户明明加了模型并可用,每次登录还是被弹初始化。

After adding a model from the model management page (not the onboarding wizard), the provider is configured and credentials exist, but default_models.llm stays empty. /api/onboarding/status only reports completed=True when a default model is set AND credentials exist, and the WebUI force-opens the setup wizard on every login when completed=False.

根因 / Root Cause

create_model(custom_provider.py)只 upsert 模型条目,从不调 set_default_model。只有 onboarding /apply 路径会设默认模型,而该路径此前被验证 bug 挡住(见 PR #779),用户只能跳过 onboarding 后手动加模型,陷入「有模型、无默认」的中间态。

create_model only upserts the model entry and never calls set_default_model. Only the onboarding /apply path sets a default, and that path was previously blocked by the validation bug in PR #779 — users who skipped onboarding and added a model manually were left in a "model exists but no default" limbo.

修复 / Fix

create_model 新增 _maybe_promote_first_model_to_default,当且仅当三个条件同时满足时自动把新模型设为默认 LLM:

  1. 该 provider 此前没有任何模型(这是第一个模型)
  2. 全局尚无默认 LLM(default_models.llm 为空)
  3. 该 provider 已有可用凭据(secret 或 inline apiKey)

设计取舍:

  • 仅第一个模型才提升 — 加第二/第三个模型时不会覆盖用户已选的默认
  • 有默认就不提升 — 不覆盖 onboarding/其他 provider 设置的默认
  • 有凭据才提升 — 与 /api/onboarding/status 的 completed 判定完全对齐;无凭据时不设,避免出现「设了默认但跑不通、status 仍 False」的矛盾态
  • 提升逻辑 try/except 兜底,绝不阻塞模型创建本身

验证 / Verification

新增 5 个回归测试,覆盖全部条件组合:

场景 预期
首个模型 + secret 凭据 ✅ 自动设默认
首个模型 + inline apiKey(flocks.json) ✅ 自动设默认
首个模型 + 无凭据 ❌ 不设(等补 key)
第二个模型(已有默认) ❌ 不覆盖
其他 provider 已有默认 ❌ 不覆盖

测试运行:

tests/server/routes/test_custom_provider_routes.py  → 8 passed (3 existing + 5 new)
tests/server/routes/test_custom_provider_runtime.py
tests/server/routes/test_provider_optional_api_key.py
tests/server/routes/test_onboarding*.py             → 53 passed, 5 skipped, 0 regression

真实环境验证:用户 openai-compatible provider + Qwen3.8-27B 模型已配置,设默认后 /api/onboarding/status 返回 completed=True,登录不再弹初始化。

测试计划 / Test Plan

  • 5 个新回归测试(条件组合全覆盖)
  • 3 个现有 create_model 测试不受影响(无凭据场景,新逻辑静默跳过)
  • 相邻模块 53 passed / 5 skipped
  • CI

风险评估 / Risk Assessment

Low — 改动仅在 create_model 内,且三重条件门控(首模型 ∧ 无默认 ∧ 有凭据),任何一条不满足都静默跳过。提升失败被 try/except 吞掉并记 warning,不影响 201 返回。不触及 onboarding/credential/默认模型管理端点的既有语义。

关联 / Related

… to default LLM

问题 / Problem:
从模型管理页添加模型(非 onboarding 向导)后,provider 已配置、凭据已存,
但 default_models.llm 为空。/api/onboarding/status 要求'默认模型已设置
+ 凭据可用'才返回 completed=True,WebUI 在 completed=False 时每次登录
强制弹出初始化向导(前端 dismissed flag 已被测试显式忽略)。
结果:用户明明加了模型,每次登录还是被弹初始化。
Adding a model from the model-management page (not the onboarding
wizard) leaves default_models.llm empty. /api/onboarding/status only
returns completed=True when a default model is set AND credentials
exist, and the WebUI force-opens the setup wizard whenever
completed=False (the frontend dismissed flag is explicitly ignored).
So users who already added a model get the onboarding popup on
every login.

根因 / Root cause:
create_model (custom_provider.py) 只写 provider.{id}.models.{model_id},
从不调 set_default_model。只有 onboarding /apply 路径(1023-1057 行)
会设默认,而该路径此前被 AgentFlocks#779 的验证 bug 挡住,用户只能跳过 onboarding
后手动加模型,陷入'有模型无默认'的中间态。
create_model only upserts the model entry and never calls
set_default_model. Only the onboarding /apply path sets the default,
and that path was previously blocked by the validation bug in AgentFlocks#779 —
users skipped onboarding, added the model manually, and were left with
'a model but no default'.

修复 / Fix:
create_model 新增 _maybe_promote_first_model_to_default:当且仅当
(1) 该 provider 此前无模型(这是第一个模型)、(2) 全局尚无默认 LLM、
(3) 该 provider 已有可用凭据(secret 或 inline apiKey)时,自动把新模型
设为默认 LLM。
- 仅第一个模型才提升 → 不会在后续加第二/第三个模型时覆盖用户已选默认
- 无默认才提升 → 不覆盖 onboarding/其它 provider 已设的默认
- 有凭据才提升 → 与 status.completed 判定对齐,避免'设了默认但跑不通'
  的矛盾态(无凭据时不设,用户补 key 后在模型管理页一键设默认)
- 提升失败 try/except 兜底,绝不阻塞模型创建本身
create_model now calls _maybe_promote_first_model_to_default: the new
model is promoted to the default LLM only when (1) the provider had no
models before, (2) no global default LLM exists, and (3) the provider
already has usable credentials. Failures are swallowed — model creation
never blocks on default promotion.

验证 / Verified:
- 新增 5 个回归测试(首个模型+凭据→设默认;inline key→设默认;
  无凭据→不设;第二个模型→不覆盖;其它 provider 已有默认→不覆盖),
  8/8 passed
- 相邻模块 53 passed / 5 skipped,零回归
- 真实环境数据修复:将 Qwen3.8-27B 设为默认后 /api/onboarding/status
  completed=True,登录不再弹
- 8 regression tests: 8/8 passed; neighboring modules: 53 passed / 5 skipped
@WenhuaXia
WenhuaXia force-pushed the fix/auto-promote-first-model-to-default branch from 1b58e24 to 08bb40f Compare October 13, 2026 11:03
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