主人 2026-10-03 拍板「注释一律中文」;gateway 至此整包注释中文化完成(本会话共 3 批: 已推库 16 个文件 + 本批剩余文件)。 校验:机械校验(非注释改动行)= 空;剥注释后代码文本逐行比对全等(不一致文件数 0); 全树 go test ./... 58 包 ok / 0 FAIL;交叉编译绿。
103 lines
3.9 KiB
Go
103 lines
3.9 KiB
Go
package gateway
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
|
|
"gopkg.in/yaml.v3"
|
|
|
|
"git.yeij.top/AskaEth/Cyrene_v2/internal/persona/loader"
|
|
)
|
|
|
|
// TestPersonaUpsertRequest_ThinkingRoundTripsThroughYAML 钉住管理侧人格
|
|
// 写路径对可选 `thinking` 块的处理:手写 DTO 映射进
|
|
// loader 结构体,yaml.Marshal 输出文档化的键,重载
|
|
// 该 YAML 得到相同的值 —— 即该字段真的往返成功,
|
|
// 而不是被未列入白名单的 DTO 丢弃。
|
|
func TestPersonaUpsertRequest_ThinkingRoundTripsThroughYAML(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
show := false
|
|
req := personaUpsertRequest{
|
|
ID: "xilian", Name: "昔涟", Role: "r", SystemPrompt: "s",
|
|
Thinking: &personaThinkingRequest{BudgetTokens: 4096, Effort: " medium ", ShowToUser: &show, Mode: " on "},
|
|
}
|
|
p := personaFromRequest(req)
|
|
if err := p.ValidateThinking(); err != nil {
|
|
t.Fatalf("ValidateThinking() error: %v", err)
|
|
}
|
|
data, err := yaml.Marshal(p)
|
|
if err != nil {
|
|
t.Fatalf("Marshal: %v", err)
|
|
}
|
|
back := &loader.Persona{}
|
|
if err := yaml.Unmarshal(data, back); err != nil {
|
|
t.Fatalf("Unmarshal: %v", err)
|
|
}
|
|
if back.Thinking.BudgetTokens != 4096 || back.Thinking.Mode != loader.ThinkingModeOn || back.Thinking.Effort != "medium" {
|
|
t.Fatalf("thinking = %+v, want 4096/on/medium", back.Thinking)
|
|
}
|
|
if back.Thinking.ShowToUser == nil || *back.Thinking.ShowToUser {
|
|
t.Fatalf("showToUser = %v, want an explicit false", back.Thinking.ShowToUser)
|
|
}
|
|
}
|
|
|
|
// TestPersonaUpsertRequest_ThinkingInvalidRejected 断言非法的 thinking
|
|
// 块会经由 loader 所用的同一套校验被拒绝,因此管理 API
|
|
// 无法持久化运行时拒绝加载的模式。
|
|
func TestPersonaUpsertRequest_ThinkingInvalidRejected(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
p := personaFromRequest(personaUpsertRequest{
|
|
ID: "x", Name: "x", Role: "r", Thinking: &personaThinkingRequest{Mode: "always"},
|
|
})
|
|
err := p.ValidateThinking()
|
|
if err == nil {
|
|
t.Fatal("ValidateThinking() = nil, want an error")
|
|
}
|
|
if !strings.Contains(err.Error(), "always") {
|
|
t.Fatalf("error %q does not name the offending mode", err)
|
|
}
|
|
}
|
|
|
|
// TestPersonaUpsertRequest_NoThinkingBlockOmitsTheKey 断言不带 thinking
|
|
// 块的请求在 YAML 中不产出它,因此既有人格文件不会多出
|
|
// 一段噪声。
|
|
func TestPersonaUpsertRequest_NoThinkingBlockOmitsTheKey(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
data, err := yaml.Marshal(personaFromRequest(personaUpsertRequest{ID: "x", Name: "x", Role: "r", SystemPrompt: "s"}))
|
|
if err != nil {
|
|
t.Fatalf("Marshal: %v", err)
|
|
}
|
|
if strings.Contains(string(data), "thinking") {
|
|
t.Fatalf("marshaled persona carries a thinking block:\n%s", data)
|
|
}
|
|
}
|
|
|
|
// TestApplyThinkingEdit_PreservesOnOmission 是非破坏性更新规则:
|
|
// 省略 `thinking` 的客户端保留已存块,显式给出块则替换
|
|
// 它,全默认值的块清除它。
|
|
func TestApplyThinkingEdit_PreservesOnOmission(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
show := false
|
|
stored := &loader.Persona{Thinking: loader.ThinkingParams{BudgetTokens: 8192, Mode: loader.ThinkingModeOn, ShowToUser: &show}}
|
|
|
|
kept := applyThinkingEdit(nil, stored)
|
|
if kept.BudgetTokens != 8192 || kept.Mode != loader.ThinkingModeOn || kept.ShowToUser == nil {
|
|
t.Fatalf("applyThinkingEdit(nil, stored) = %+v, want the stored block", kept)
|
|
}
|
|
replaced := applyThinkingEdit(&personaThinkingRequest{BudgetTokens: 1024, Mode: "off"}, stored)
|
|
if replaced.BudgetTokens != 1024 || replaced.Mode != loader.ThinkingModeOff || replaced.ShowToUser != nil {
|
|
t.Fatalf("applyThinkingEdit(explicit, stored) = %+v, want the request block", replaced)
|
|
}
|
|
cleared := applyThinkingEdit(&personaThinkingRequest{}, stored)
|
|
if cleared.BudgetTokens != 0 || cleared.Mode != "" || cleared.ShowToUser != nil {
|
|
t.Fatalf("applyThinkingEdit(empty object, stored) = %+v, want the zero block", cleared)
|
|
}
|
|
if created := applyThinkingEdit(nil, nil); created.BudgetTokens != 0 || created.ShowToUser != nil {
|
|
t.Fatalf("applyThinkingEdit(nil, nil) = %+v, want the zero block (create path)", created)
|
|
}
|
|
}
|