Enhance i18n support and refactor API response handling in assistant functions
- Introduced global i18n initialization and connector setup in the Load function for better localization support. - Refactored handleAssistantList, handleAssistantDetail, and handleAssistantTags functions to utilize the new Translate method for improved response translation based on user locale. - Simplified locale handling by removing redundant code and centralizing translation logic.
This commit is contained in:
parent
6467a9c37e
commit
1b921cf7b0
4 changed files with 175 additions and 55 deletions
50
neo/api.go
50
neo/api.go
|
|
@ -889,22 +889,15 @@ func (neo *DSL) handleAssistantList(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
// Translate the response
|
||||
locale := "en-us" // Default locale
|
||||
if loc := c.Query("locale"); loc != "" {
|
||||
locale = strings.ToLower(strings.TrimSpace(loc))
|
||||
}
|
||||
for i, ast := range response.Data {
|
||||
id := ast["assistant_id"].(string)
|
||||
if locales, ok := assistant.Locales[id]; ok {
|
||||
if loc := c.Query("locale"); loc != "" {
|
||||
loc = strings.ToLower(strings.TrimSpace(loc))
|
||||
if _, ok := locales[loc]; ok {
|
||||
locale = loc
|
||||
}
|
||||
}
|
||||
if i18n, ok := locales[locale]; ok {
|
||||
response.Data[i] = i18n.Parse(ast).(map[string]interface{})
|
||||
}
|
||||
}
|
||||
response.Data[i] = assistant.Translate(locale, id, ast).(map[string]interface{})
|
||||
}
|
||||
|
||||
c.JSON(200, response)
|
||||
c.Done()
|
||||
}
|
||||
|
|
@ -995,18 +988,12 @@ func (neo *DSL) handleAssistantDetail(c *gin.Context) {
|
|||
}
|
||||
|
||||
locale := "en-us" // Default locale
|
||||
id := response.Data[0]["assistant_id"].(string)
|
||||
if locales, ok := assistant.Locales[id]; ok {
|
||||
if loc := c.Query("locale"); loc != "" {
|
||||
loc = strings.ToLower(strings.TrimSpace(loc))
|
||||
if _, ok := locales[loc]; ok {
|
||||
locale = loc
|
||||
}
|
||||
}
|
||||
if i18n, ok := locales[locale]; ok {
|
||||
response.Data[0] = i18n.Parse(response.Data[0]).(map[string]interface{})
|
||||
}
|
||||
// Translate the response
|
||||
if loc := c.Query("locale"); loc != "" {
|
||||
locale = strings.ToLower(strings.TrimSpace(loc))
|
||||
}
|
||||
id := response.Data[0]["assistant_id"].(string)
|
||||
response.Data[0] = assistant.Translate(locale, id, response.Data[0]).(map[string]interface{})
|
||||
|
||||
c.JSON(200, map[string]interface{}{"data": response.Data[0]})
|
||||
c.Done()
|
||||
|
|
@ -1118,6 +1105,21 @@ func (neo *DSL) handleAssistantTags(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
c.JSON(200, gin.H{"data": tags})
|
||||
// Translate the tags
|
||||
locale := "en-us" // Default locale
|
||||
if loc := c.Query("locale"); loc != "" {
|
||||
locale = strings.ToLower(strings.TrimSpace(loc))
|
||||
}
|
||||
|
||||
// Translate the tags
|
||||
items := []map[string]interface{}{}
|
||||
for _, value := range tags {
|
||||
items = append(items, map[string]interface{}{
|
||||
"label": assistant.Translate(locale, "", value).(string),
|
||||
"key": value,
|
||||
})
|
||||
}
|
||||
|
||||
c.JSON(200, gin.H{"data": items})
|
||||
c.Done()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,12 @@
|
|||
package assistant
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/yaoapp/gou/application"
|
||||
"github.com/yaoapp/gou/fs"
|
||||
"github.com/yaoapp/kun/maps"
|
||||
)
|
||||
|
||||
// Locales the locales
|
||||
|
|
@ -49,3 +54,98 @@ func (i18n I18n) Parse(input any) any {
|
|||
|
||||
return input
|
||||
}
|
||||
|
||||
// GetI18n load the i18n from path
|
||||
func GetI18n(path string) (map[string]I18n, error) {
|
||||
app, err := fs.Get("app")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Get the global i18n
|
||||
globalI18ns, hasGlobal := Locales["__global__"]
|
||||
// i18ns
|
||||
localesdir := filepath.Join(path, "locales")
|
||||
var i18ns map[string]I18n = map[string]I18n{}
|
||||
if has, _ := app.Exists(localesdir); has {
|
||||
locales, err := app.ReadDir(localesdir, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// load locales
|
||||
for _, locale := range locales {
|
||||
localeData, err := app.ReadFile(locale)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var messages maps.Map = map[string]any{}
|
||||
err = application.Parse(locale, localeData, &messages)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
name := strings.ToLower(strings.TrimSuffix(filepath.Base(locale), ".yml"))
|
||||
// Merge the global i18n
|
||||
if hasGlobal {
|
||||
global, has := globalI18ns[name]
|
||||
if has {
|
||||
for key, value := range global.Messages {
|
||||
if _, ok := messages[key]; !ok {
|
||||
messages[key] = value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
i18ns[name] = I18n{Locale: name, Messages: messages.Dot()}
|
||||
namer := strings.Split(name, "-")
|
||||
if len(namer) > 1 {
|
||||
// Merge the global i18n
|
||||
if hasGlobal {
|
||||
global, has := globalI18ns[namer[0]]
|
||||
if has {
|
||||
for key, value := range global.Messages {
|
||||
if _, ok := messages[key]; !ok {
|
||||
messages[key] = value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
i18ns[namer[0]] = I18n{Locale: name, Messages: messages.Dot()}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return i18ns, nil
|
||||
}
|
||||
|
||||
// Translate translate the input
|
||||
func Translate(locale string, id string, input any) any {
|
||||
|
||||
locale = strings.ToLower(strings.TrimSpace(locale))
|
||||
i18ns, has := Locales[id]
|
||||
if !has {
|
||||
i18ns = map[string]I18n{}
|
||||
}
|
||||
|
||||
i18n, has := i18ns[locale]
|
||||
if !has {
|
||||
namer := strings.Split(locale, "-")
|
||||
lang := namer[0]
|
||||
i18n, has = i18ns[lang]
|
||||
}
|
||||
if !has {
|
||||
var hasGlobal bool = false
|
||||
i18ns, hasGlobal = Locales["__global__"]
|
||||
if hasGlobal {
|
||||
i18n, has = i18ns[locale]
|
||||
}
|
||||
}
|
||||
|
||||
if has {
|
||||
return i18n.Parse(input)
|
||||
}
|
||||
|
||||
return input
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ import (
|
|||
"github.com/yaoapp/gou/fs"
|
||||
"github.com/yaoapp/gou/rag/driver"
|
||||
v8 "github.com/yaoapp/gou/runtime/v8"
|
||||
"github.com/yaoapp/kun/maps"
|
||||
"github.com/yaoapp/yao/neo/store"
|
||||
neovision "github.com/yaoapp/yao/neo/vision"
|
||||
"github.com/yaoapp/yao/openai"
|
||||
|
|
@ -315,37 +314,11 @@ func LoadPath(path string) (*Assistant, error) {
|
|||
}
|
||||
|
||||
// i18ns
|
||||
localesdir := filepath.Join(path, "locales")
|
||||
var i18ns map[string]I18n = map[string]I18n{}
|
||||
if has, _ := app.Exists(localesdir); has {
|
||||
locales, err := app.ReadDir(localesdir, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// load locales
|
||||
for _, locale := range locales {
|
||||
localeData, err := app.ReadFile(locale)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var messages maps.Map
|
||||
err = application.Parse(locale, localeData, &messages)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if messages != nil {
|
||||
name := strings.ToLower(strings.TrimSuffix(filepath.Base(locale), ".yml"))
|
||||
i18ns[name] = I18n{Locale: name, Messages: messages.Dot()}
|
||||
namer := strings.Split(name, "-")
|
||||
if len(namer) > 1 {
|
||||
i18ns[namer[0]] = I18n{Locale: name, Messages: messages.Dot()}
|
||||
}
|
||||
}
|
||||
}
|
||||
data["locales"] = i18ns
|
||||
locales, err := GetI18n(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data["locales"] = locales
|
||||
return loadMap(data)
|
||||
}
|
||||
|
||||
|
|
|
|||
45
neo/load.go
45
neo/load.go
|
|
@ -63,6 +63,18 @@ func Load(cfg config.Config) error {
|
|||
return err
|
||||
}
|
||||
|
||||
// Initialize Connectors
|
||||
err = initConnectors()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Initialize Global I18n
|
||||
err = initGlobalI18n()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Initialize Assistant
|
||||
err = initAssistant()
|
||||
if err != nil {
|
||||
|
|
@ -72,6 +84,39 @@ func Load(cfg config.Config) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// initGlobalI18n initialize the global i18n
|
||||
func initGlobalI18n() error {
|
||||
locales, err := assistant.GetI18n("neo")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
assistant.Locales["__global__"] = locales
|
||||
return nil
|
||||
}
|
||||
|
||||
// initConnectors initialize the connectors
|
||||
func initConnectors() error {
|
||||
path := filepath.Join("neo", "connectors.yml")
|
||||
if exists, _ := application.App.Exists(path); !exists {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Open the connectors
|
||||
bytes, err := application.App.Read(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var connectors map[string]assistant.ConnectorSetting = map[string]assistant.ConnectorSetting{}
|
||||
err = application.Parse("connectors.yml", bytes, &connectors)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Neo.Connectors = connectors
|
||||
return nil
|
||||
}
|
||||
|
||||
// initStore initialize the store
|
||||
func initStore() error {
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue