feat(ai): add local expert library

This commit is contained in:
2026-07-22 17:09:54 +08:00
parent b28a5d635c
commit 42dd0dce47
22 changed files with 3432 additions and 60 deletions

View File

@@ -1,6 +1,7 @@
package models
import (
_ "embed"
"encoding/json"
"fmt"
"strings"
@@ -31,6 +32,7 @@ func runVersionedMigrations(database *gorm.DB) error {
migrations := []versionedMigration{
{version: 1, name: "normalize_project_identifiers", run: normalizeLegacyProjectIdentifiers},
{version: 2, name: "deduplicate_project_tags", run: deduplicateLegacyProjectTags},
{version: 3, name: "seed_ai_experts", run: seedAIExperts},
}
for _, migration := range migrations {
// Connection callbacks can provide an initialized Gorm session. Start each
@@ -63,6 +65,48 @@ func runVersionedMigrations(database *gorm.DB) error {
return nil
}
//go:embed experts_catalog.json
var expertCatalogJSON []byte
type embeddedExpertCatalog struct {
Source string `json:"source"`
License string `json:"license"`
Experts []embeddedExpertCatalogItem `json:"experts"`
}
type embeddedExpertCatalogItem struct {
Slug string `json:"slug"`
Category string `json:"category"`
CategoryName string `json:"categoryName"`
Name string `json:"name"`
Description string `json:"description"`
Emoji string `json:"emoji"`
Color string `json:"color"`
SystemPrompt string `json:"systemPrompt"`
}
func seedAIExperts(tx *gorm.DB) (map[string]int, error) {
var catalog embeddedExpertCatalog
if err := json.Unmarshal(expertCatalogJSON, &catalog); err != nil {
return nil, fmt.Errorf("decode embedded AI expert catalog: %w", err)
}
records := make([]SenlinAgentAIExpert, 0, len(catalog.Experts))
for _, expert := range catalog.Experts {
records = append(records, SenlinAgentAIExpert{
Slug: expert.Slug, Category: expert.Category, CategoryName: expert.CategoryName,
Name: expert.Name, Description: expert.Description, Emoji: expert.Emoji,
Color: expert.Color, SystemPrompt: expert.SystemPrompt, Source: catalog.Source,
SourceLicense: catalog.License, Enabled: true,
})
}
if len(records) > 0 {
if err := tx.CreateInBatches(&records, 25).Error; err != nil {
return nil, err
}
}
return map[string]int{"inserted": len(records)}, nil
}
func normalizeLegacyProjectIdentifiers(tx *gorm.DB) (map[string]int, error) {
var projects []SenlinAgentProject
if err := tx.Model(&SenlinAgentProject{}).Select("id", "owner_id", "identifier").Order("owner_id asc, id asc").Find(&projects).Error; err != nil {