feat(search): 面板上终于能改「结果条数上限」(原来改了会被静默丢弃)
真缺陷(上一片登记):`maxResults` 在面板上**根本改不了** —— ① 字段表里没有这个
字段(UI 不显示输入框);② `saveProvider` 只并 provider/apiKey/baseUrl/enabled;
③ `mergeSelectionPatch` 只处理 primary/fallback ⇒ **手工塞进 values 也会被静默丢弃**
(文件不变、也不报错)。「我改了它却没变」正是要消灭的那种假话。
- `panel.go`:表单加 `{Key: FieldMaxResults, Type: sdk.FieldNumber, Min: 1}`(**SDK 本就有
数字类型**,未自造;前端本就渲染 number ⇒ **不需要改前端**)。刻意不设 `Default`
(设了会让一次「只改 key」的保存把默认值固化进文件、还可能盖掉 `.env`)。
- `websearch_selection.go`:`mergeSelectionPatch` 里按**三态**落 `maxResults` ——
缺位/null ⇒ **不改动**;正整数(含整数字符串)⇒ 采用;0/负数/小数/空串/非数/
布尔/数组 ⇒ **400 `invalid_payload`** 且**盘上一字节不动**(绝不静默忽略)。
- `reauth` 回填该值(否则一保存就把上限清掉)。
- `.env.example`:该键的示例值与「默认 5」注释同步为 **10**(代码默认已改;⚠️ `.env` 未动)。
验收(主会话复跑 + 亲自变异):**整树 `go build ./...` 通过**;三包 vet/测试绿;
端到端「面板存 20 ⇒ 模型要 50 也只给 20、要 3 给 3」(走真 action hub → 落盘 →
热重载 → WithSearchMaxResults → 真 dispatcher,未重启后端);
我用 -overlay 把 `f.MaxResults = maxResults` 摘掉 ⇒ 两条用例变红
(「面板给的值必须真的落盘」/「回填的 maxResults = 5, want 20」)。
⚠️ 已知取舍(如实登记):**清空输入框 = 400**(后端按「非数 ⇒ 报错」拒),因此面板上
没有「去掉上限」的手势 —— 要回到 `.env` 兜底得改文件;要支持「清空 = 去掉覆盖」
需另定哨兵语义,未自行发挥。
⚠️ 契约面已变更(面板声明多一个 number 字段 + saveProvider 的 values 多一个可写键 +
响应多一个回显键)⇒ 主会话登记。
This commit is contained in:
1 parent
8325d1bb8c
commit
c68387a69a
8 files changed
+387
-31
No files matched your search
@@ -52,9 +52,11 @@ func (e webSearchActionEnv) listProviderOptions(_ context.Context, _ pluginmgr.A
|
||||
// - apiKey **空串** ⇒ 显式清空(前端只有勾了「清除」才会送出空串);
|
||||
// - baseUrl / enabled 缺位或空串 ⇒ 保留;给出(含 false / 空地址)⇒ 采用。
|
||||
//
|
||||
// 同一次提交里还可能带两个**文件级**字段(`primary` / `fallback`,切片 W3):它们不是这一条
|
||||
// provider 的属性,而是「谁先用 / 失败后按什么顺序降级」,因此合并到文件级而不是条目上
|
||||
// (解析与校验在 websearch_selection.go)。缺位 = 不改动,与其余字段同一套哨兵语义。
|
||||
// 同一次提交里还可能带三个**文件级**字段(`primary` / `fallback` / `maxResults`):它们不是
|
||||
// 这一条 provider 的属性,而是「谁先用 / 失败后按什么顺序降级 / 单次最多几条」,因此合并到
|
||||
// 文件级而不是条目上(解析与校验在 websearch_selection.go)。缺位 = 不改动;但给出了**不合法**
|
||||
// 的值(如 `maxResults` ≤0 / 非整数)⇒ 整笔 400,**绝不静默丢弃** —— 静默丢弃会让用户以为
|
||||
// 上限已经改了,而跑的还是旧的那个(那正是这一片要消灭的那条「我改了它却没变」)。
|
||||
//
|
||||
// 落盘之后由组合根的热重载事务接管(`websearch_reload.go`:重建工具 + 换注册表条目,
|
||||
// 失败则连同本次落盘一起回滚)—— 本函数只负责「把改动存进去」这一件事。
|
||||
@@ -108,10 +110,12 @@ func (e webSearchActionEnv) saveProvider(_ context.Context, req pluginmgr.Action
|
||||
"provider": name,
|
||||
"created": !existed,
|
||||
"enabled": entry.IsEnabled(),
|
||||
// 文件级选择的**落盘后**取值(没给 primary/fallback 时也如实回显当前值):
|
||||
// 面板按它回显「谁先用」,也让「这次保存有没有动到选择」有可机读的答案。
|
||||
// 文件级取值的**落盘后**样子(没给这几个键时也如实回显当前值):面板按它回显
|
||||
// 「谁先用」,也让「这次保存有没有动到选择 / 上限」有可机读的答案。
|
||||
"primary": strings.ToLower(strings.TrimSpace(final.Provider)),
|
||||
"fallback": selectionNames(final.Fallback),
|
||||
// maxResults 的 0 = 文件里未声明(由 `.env` / 代码默认兜底),原样回显,不编一个假值。
|
||||
"maxResults": final.MaxResults,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -167,6 +171,10 @@ func (e webSearchActionEnv) testProvider(ctx context.Context, req pluginmgr.Acti
|
||||
// 只把它算作「盘上已有值」⇒ 留空 = 不改动、要清空必须显式勾选;
|
||||
// - 其余字段回**盘上那条的原样**,不做默认值回填:回填代码默认地址会让一次
|
||||
// 「只改 key」的保存把默认地址固化进文件(面板显示的是「该条」,不是「生效值」)。
|
||||
//
|
||||
// 文件级字段(`maxResults` 在内)也按同一条口径回填:**盘上有值才回**。上限不回填的话表单
|
||||
// 里那个框是空的,用户既看不见当前上限、也无从改起;而盘上没写(0 = 未声明)时**不回** 0 ——
|
||||
// 0 会被前端当成一个值送回来,写侧又拒 ≤0,那会让「只改 key」的保存整笔进不去。
|
||||
func (e webSearchActionEnv) reauthProvider(_ context.Context, req pluginmgr.ActionRequest) (any, error) {
|
||||
name, err := providerNameOf(req.Payload)
|
||||
if err != nil {
|
||||
@@ -185,8 +193,9 @@ func (e webSearchActionEnv) reauthProvider(_ context.Context, req pluginmgr.Acti
|
||||
"baseUrl": entry.BaseURL,
|
||||
"enabled": !exists || entry.IsEnabled(),
|
||||
}
|
||||
// 两个文件级字段一并回填:不然用户「清空降级链」在前端的三态写回里会落成缺位
|
||||
// (= 不改动),「我清掉了它」就成了一句假话。
|
||||
// 三个文件级字段一并回填(主 provider / 降级链 / 条数上限):不然用户「清空降级链」在前端
|
||||
// 的三态写回里会落成缺位(= 不改动),「我清掉了它」就成了一句假话;上限同理 ——
|
||||
// 不回填就看不见盘上的值,改上限也就无从下手。
|
||||
addSelectionValues(values, f)
|
||||
if masked, ok := maskedProviderEntry(f, name); ok && strings.TrimSpace(masked.APIKey) != "" {
|
||||
values["apiKey"] = masked.APIKey
|
||||
|
||||
Reference in new issue
Block a user