@@ -4,11 +4,12 @@ import (
44 "os"
55 "path/filepath"
66
7+ "dario.cat/mergo"
78 "github.com/mudler/LocalAI/core/config"
89 . "github.com/mudler/LocalAI/core/gallery"
910 . "github.com/onsi/ginkgo/v2"
1011 . "github.com/onsi/gomega"
11- "gopkg.in/yaml.v2 "
12+ "gopkg.in/yaml.v3 "
1213)
1314
1415var _ = Describe ("Gallery" , func () {
@@ -462,4 +463,60 @@ var _ = Describe("Gallery", func() {
462463 Expect (result ).To (BeNil ())
463464 })
464465 })
466+
467+ Describe ("YAML merge with nested maps" , func () {
468+ It ("should handle YAML anchors and merges with nested overrides (regression test for nanbeige4.1)" , func () {
469+ // This tests the fix for the panic that occurred with yaml.v2:
470+ // yaml.v2 produces map[interface{}]interface{} for nested maps
471+ // which caused mergo.Merge to panic with "value of type interface {} is not assignable to type string"
472+ // The exact YAML structure from gallery/index.yaml nanbeige4.1 entries
473+ yamlContent := `---
474+ - &nanbeige4
475+ name: "nanbeige4.1-3b-q8"
476+ overrides:
477+ parameters:
478+ model: nanbeige4.1-3b-q8_0.gguf
479+ - !!merge <<: *nanbeige4
480+ name: "nanbeige4.1-3b-q4"
481+ overrides:
482+ parameters:
483+ model: nanbeige4.1-3b-q4_k_m.gguf
484+ `
485+ var models []GalleryModel
486+ err := yaml .Unmarshal ([]byte (yamlContent ), & models )
487+ Expect (err ).NotTo (HaveOccurred ())
488+ Expect (models ).To (HaveLen (2 ))
489+
490+ // Verify first model
491+ Expect (models [0 ].Name ).To (Equal ("nanbeige4.1-3b-q8" ))
492+ Expect (models [0 ].Overrides ).NotTo (BeNil ())
493+ Expect (models [0 ].Overrides ["parameters" ]).To (BeAssignableToTypeOf (map [string ]interface {}{}))
494+ params := models [0 ].Overrides ["parameters" ].(map [string ]interface {})
495+ Expect (params ["model" ]).To (Equal ("nanbeige4.1-3b-q8_0.gguf" ))
496+
497+ // Verify second model (merged)
498+ Expect (models [1 ].Name ).To (Equal ("nanbeige4.1-3b-q4" ))
499+ Expect (models [1 ].Overrides ).NotTo (BeNil ())
500+ Expect (models [1 ].Overrides ["parameters" ]).To (BeAssignableToTypeOf (map [string ]interface {}{}))
501+ params = models [1 ].Overrides ["parameters" ].(map [string ]interface {})
502+ Expect (params ["model" ]).To (Equal ("nanbeige4.1-3b-q4_k_m.gguf" ))
503+
504+ // Simulate the mergo.Merge call that was failing in models.go:251
505+ // This should not panic with yaml.v3
506+ configMap := make (map [string ]interface {})
507+ configMap ["name" ] = "test"
508+ configMap ["backend" ] = "llama-cpp"
509+ configMap ["parameters" ] = map [string ]interface {}{
510+ "model" : "original.gguf" ,
511+ }
512+
513+ err = mergo .Merge (& configMap , models [1 ].Overrides , mergo .WithOverride )
514+ Expect (err ).NotTo (HaveOccurred ())
515+ Expect (configMap ["parameters" ]).NotTo (BeNil ())
516+
517+ // Verify the merge worked correctly
518+ mergedParams := configMap ["parameters" ].(map [string ]interface {})
519+ Expect (mergedParams ["model" ]).To (Equal ("nanbeige4.1-3b-q4_k_m.gguf" ))
520+ })
521+ })
465522})
0 commit comments