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

@@ -19,6 +19,7 @@ const (
var (
ErrInvalidSession = errors.New("invalid ai session")
ErrExpertNotFound = errors.New("ai expert not found")
)
type sessionGateway interface {
@@ -43,7 +44,7 @@ func (s *SessionService) List(userID uint, projectIdentity string) ([]models.Sen
return nil, err
}
var sessions []models.SenlinAgentAISession
if err := models.DBService.Where("project_id = ?", project.ID).Order("updated_at desc, id desc").Find(&sessions).Error; err != nil {
if err := models.DBService.Preload("Expert").Where("project_id = ?", project.ID).Order("updated_at desc, id desc").Find(&sessions).Error; err != nil {
return nil, err
}
if sessions == nil {
@@ -54,6 +55,11 @@ func (s *SessionService) List(userID uint, projectIdentity string) ([]models.Sen
// Create 先校验项目,再限流,最后才选择 provider/key会话创建不会生成任何正式业务对象。
func (s *SessionService) Create(userID uint, projectIdentity, title, context string) (*models.SenlinAgentAISession, error) {
return s.CreateWithExpert(userID, projectIdentity, title, context, "")
}
// CreateWithExpert 创建带本地专家角色的项目会话。
func (s *SessionService) CreateWithExpert(userID uint, projectIdentity, title, context, expertIdentity string) (*models.SenlinAgentAISession, error) {
title = strings.TrimSpace(title)
context = strings.TrimSpace(context)
if title == "" {
@@ -66,6 +72,10 @@ func (s *SessionService) Create(userID uint, projectIdentity, title, context str
if s.gateway == nil {
return nil, errors.New("ai gateway is required")
}
expert, err := findExpertByIdentity(models.DBService, expertIdentity)
if err != nil {
return nil, err
}
if err := s.gateway.ReserveRateLimit(userID, aiSessionCreateAction, aiSessionCreateLimit, time.Hour); err != nil {
if errors.Is(err, ErrAIRateLimited) {
@@ -100,6 +110,10 @@ func (s *SessionService) Create(userID uint, projectIdentity, title, context str
Context: context,
Status: defaultSessionStatus,
}
if expert != nil {
session.ExpertID = &expert.ID
session.ExpertIdentity = &expert.Identity
}
failureCode := "session_create_failed"
err = models.DBService.Transaction(func(tx *gorm.DB) error {
if err := tx.Create(&session).Error; err != nil {
@@ -119,6 +133,7 @@ func (s *SessionService) Create(userID uint, projectIdentity, title, context str
}
return nil, err
}
session.Expert = expert
return &session, nil
}