package store import ( "fmt" "path/filepath" "strings" "github.com/yaoapp/gou/application" "github.com/yaoapp/gou/store" "github.com/yaoapp/kun/log" "github.com/yaoapp/yao/config" "github.com/yaoapp/yao/data" "github.com/yaoapp/yao/share" ) var systemStores = map[string]string{ "__yao.store": "yao/stores/store.badger.yao", // for common data store "__yao.cache": "yao/stores/cache.lru.yao", // for common cache store "__yao.oauth.store": "yao/stores/oauth/store.badger.yao", // for OAuth data store "__yao.oauth.cache": "yao/stores/oauth/cache.lru.yao", // for OAuth cache store "__yao.oauth.client": "yao/stores/oauth/client.badger.yao", // for OAuth client store "__yao.agent.memory": "yao/stores/agent/memory.badger.yao", // for agent memory store (for agent memory) "__yao.agent.cache": "yao/stores/agent/cache.lru.yao", // for agent cache store (for agent cache) "__yao.kb.store": "yao/stores/kb/store.badger.yao", // for knowledge base store "__yao.kb.cache": "yao/stores/kb/cache.lru.yao", // for knowledge base cache store } // replaceVars replaces template variables in the JSON string // Supports {{ VAR_NAME }} syntax func replaceVars(jsonStr string, vars map[string]string) string { result := jsonStr for key, value := range vars { // Replace both {{ KEY }} and {{KEY}} patterns patterns := []string{ "{{ " + key + " }}", "{{" + key + "}}", } for _, pattern := range patterns { result = strings.ReplaceAll(result, pattern, value) } } return result } // Load load store func Load(cfg config.Config) error { // Load system stores err := loadSystemStores(cfg) if err != nil { return err } // Ignore if the stores directory does not exist exists, err := application.App.Exists("stores") if err != nil { return err } if !exists { return nil } messages := []string{} exts := []string{"*.yao", "*.json", "*.jsonc"} err = application.App.Walk("stores", func(root, file string, isdir bool) error { if isdir { return nil } _, err := store.Load(file, share.ID(root, file)) if err != nil { messages = append(messages, err.Error()) } return err }, exts...) if len(messages) > 0 { return fmt.Errorf("%s", strings.Join(messages, ";\n")) } return err } // loadSystemStores load system stores func loadSystemStores(cfg config.Config) error { for id, path := range systemStores { raw, err := data.Read(path) if err != nil { return err } // Replace template variables in the JSON string source := string(raw) if strings.Contains(source, "YAO_APP_ROOT") || strings.Contains(source, "YAO_DATA_ROOT") { vars := map[string]string{ "YAO_APP_ROOT": cfg.Root, "YAO_DATA_ROOT": cfg.DataRoot, } source = replaceVars(source, vars) } // Load store with the processed source _, err = store.LoadSource([]byte(source), id, filepath.Join("__system", path)) if err != nil { log.Error("load system store %s error: %s", id, err.Error()) return err } } return nil }