Repair object-shaped children maps into arrays in page specs
ci / vet-and-test (pull_request) Successful in 52s
ci / vet-and-test (pull_request) Successful in 52s
Why: Live E2E on the dev instance - the model keyed section children as an object map (children.item.*), the strict decode rejected it, and the page fell back to a file artifact; the guidance fix made the model call present, this closes the remaining shape gap. Evidence: genui suite green incl. the reproduction case; post-deploy E2E rerun recorded in the Dev task. Impact: Repair strategy only; validation unchanged. Refs: Dev task fix/genui-page-visibility (E2E follow-up)
This commit is contained in:
@@ -274,10 +274,53 @@ func normalizeSpecParam(v any) any {
|
||||
}
|
||||
}
|
||||
}
|
||||
repairChildrenShape(m)
|
||||
repairPairs(m)
|
||||
return m
|
||||
}
|
||||
|
||||
// repairChildrenShape 递归修复 children 的常见形状偏差(真实模型实测):
|
||||
// children 为对象(按 key 编号的子节点映射)→ 取其值转数组;单对象 → 包一层数组。
|
||||
func repairChildrenShape(node any) {
|
||||
m, ok := node.(map[string]any)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
if ch, ok := m["children"]; ok && ch != nil {
|
||||
switch v := ch.(type) {
|
||||
case map[string]any:
|
||||
arr := make([]any, 0, len(v))
|
||||
for _, val := range v {
|
||||
arr = append(arr, val)
|
||||
}
|
||||
m["children"] = arr
|
||||
case []any:
|
||||
for _, c := range v {
|
||||
if cm, ok := c.(map[string]any); ok {
|
||||
repairChildrenShape(cm)
|
||||
}
|
||||
}
|
||||
default:
|
||||
// 单对象子节点
|
||||
if cm, ok := ch.(map[string]any); ok {
|
||||
m["children"] = []any{cm}
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, v := range m {
|
||||
if vm, ok := v.(map[string]any); ok {
|
||||
repairChildrenShape(vm)
|
||||
}
|
||||
if va, ok := v.([]any); ok {
|
||||
for _, item := range va {
|
||||
if im, ok := item.(map[string]any); ok {
|
||||
repairChildrenShape(im)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// repairPairs 递归把 "kv"/"cells" 下的对象项改写为二元组。
|
||||
func repairPairs(node any) {
|
||||
m, ok := node.(map[string]any)
|
||||
|
||||
@@ -280,3 +280,19 @@ type ledgerHost struct {
|
||||
|
||||
func (h *ledgerHost) KVPut(key, value string) error { h.kv[key] = value; return nil }
|
||||
func (h *ledgerHost) Audit(action, target, evidence string) error { return nil }
|
||||
|
||||
func TestNormalizeChildrenShape(t *testing.T) {
|
||||
// 真实偏差(2026-10-11 dev 实测):模型把 children 写成按 key 编号的对象映射。
|
||||
in := map[string]any{
|
||||
"type": "section", "id": "n1", "title": "结论",
|
||||
"children": map[string]any{
|
||||
"item": map[string]any{"type": "markdown", "id": "m1", "markdown": "结论先行"},
|
||||
},
|
||||
}
|
||||
out := normalizeSpecParam(map[string]any{"title": "t", "nodes": []any{in}})
|
||||
nodes := out.(map[string]any)["nodes"].([]any)
|
||||
ch := nodes[0].(map[string]any)["children"].([]any)
|
||||
if len(ch) != 1 || ch[0].(map[string]any)["id"] != "m1" {
|
||||
t.Fatalf("children should be repaired to array, got %v", ch)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user