feat: Enhance Kol Generation Service with web search and knowledge group support
- Added `EnableWebSearch` and `KnowledgeGroupIDs` fields to `KolGenerationSubmitRequest`. - Updated `Submit` method in `KolGenerationService` to handle new request fields. - Integrated web search and knowledge group validation based on card configuration. - Introduced caching mechanisms in `KolPackageService`, `KolPromptService`, and `KolSubscriptionAdminService` to improve performance. - Implemented knowledge context resolution in `KolGenerationWorker` to enrich prompts with relevant knowledge snippets. - Added utility functions for handling card configuration in both backend and frontend. - Created tests for knowledge extraction and rendering to ensure accuracy and reliability.
This commit is contained in:
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
|
||||
"github.com/geo-platform/tenant-api/internal/shared/auth"
|
||||
sharedcache "github.com/geo-platform/tenant-api/internal/shared/cache"
|
||||
"github.com/geo-platform/tenant-api/internal/shared/response"
|
||||
"github.com/geo-platform/tenant-api/internal/tenant/repository"
|
||||
)
|
||||
@@ -66,6 +67,7 @@ type KolPromptService struct {
|
||||
promptRepo repository.KolPromptRepository
|
||||
subRepo repository.KolSubscriptionRepository
|
||||
asset *KolPromptAsset
|
||||
cache sharedcache.Cache
|
||||
}
|
||||
|
||||
func NewKolPromptService(
|
||||
@@ -86,6 +88,11 @@ func NewKolPromptService(
|
||||
}
|
||||
}
|
||||
|
||||
func (s *KolPromptService) WithCache(c sharedcache.Cache) *KolPromptService {
|
||||
s.cache = c
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *KolPromptService) CreatePrompt(ctx context.Context, actor auth.Actor, input CreatePromptInput) (*KolPromptDetailResponse, error) {
|
||||
if strings.TrimSpace(input.Name) == "" {
|
||||
return nil, response.ErrBadRequest(40063, "kol_prompt_name_required", "prompt name is required")
|
||||
@@ -107,6 +114,7 @@ func (s *KolPromptService) CreatePrompt(ctx context.Context, actor auth.Actor, i
|
||||
return nil, response.ErrInternal(50070, "kol_prompt_create_failed", err.Error())
|
||||
}
|
||||
|
||||
InvalidateKolPromptCaches(ctx, s.cache)
|
||||
return s.buildPromptDetail(ctx, prompt, false)
|
||||
}
|
||||
|
||||
@@ -176,6 +184,7 @@ func (s *KolPromptService) UpdateMetadata(ctx context.Context, actor auth.Actor,
|
||||
return nil, ErrPromptNotFound
|
||||
}
|
||||
|
||||
InvalidateKolPromptCaches(ctx, s.cache)
|
||||
return s.buildPromptDetail(ctx, updated, false)
|
||||
}
|
||||
|
||||
@@ -248,6 +257,7 @@ func (s *KolPromptService) Save(ctx context.Context, actor auth.Actor, promptID
|
||||
return nil, ErrPromptNotFound
|
||||
}
|
||||
|
||||
InvalidateKolPromptCaches(ctx, s.cache)
|
||||
return s.buildPromptDetail(ctx, updated, true)
|
||||
}
|
||||
|
||||
@@ -330,6 +340,7 @@ func (s *KolPromptService) Publish(ctx context.Context, actor auth.Actor, prompt
|
||||
return nil, ErrPromptNotFound
|
||||
}
|
||||
|
||||
InvalidateKolPromptCaches(ctx, s.cache)
|
||||
return s.buildPromptDetail(ctx, updated, true)
|
||||
}
|
||||
|
||||
@@ -373,6 +384,7 @@ func (s *KolPromptService) Activate(ctx context.Context, actor auth.Actor, promp
|
||||
return nil, ErrPromptNotFound
|
||||
}
|
||||
|
||||
InvalidateKolPromptCaches(ctx, s.cache)
|
||||
return s.buildPromptDetail(ctx, updated, false)
|
||||
}
|
||||
|
||||
@@ -393,6 +405,7 @@ func (s *KolPromptService) Archive(ctx context.Context, actor auth.Actor, prompt
|
||||
return nil, ErrPromptNotFound
|
||||
}
|
||||
|
||||
InvalidateKolPromptCaches(ctx, s.cache)
|
||||
return s.buildPromptDetail(ctx, updated, false)
|
||||
}
|
||||
|
||||
@@ -405,6 +418,7 @@ func (s *KolPromptService) Delete(ctx context.Context, actor auth.Actor, promptI
|
||||
return response.ErrInternal(50082, "kol_prompt_delete_failed", err.Error())
|
||||
}
|
||||
|
||||
InvalidateKolPromptCaches(ctx, s.cache)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -520,10 +534,36 @@ func (s *KolPromptService) grantPromptToActiveSubscribers(
|
||||
}
|
||||
|
||||
func normalizeKolCardConfig(cardConfig map[string]interface{}) map[string]interface{} {
|
||||
if cardConfig == nil {
|
||||
return map[string]interface{}{}
|
||||
normalized := map[string]interface{}{
|
||||
"allow_web_search": false,
|
||||
"allow_user_knowledge": true,
|
||||
}
|
||||
return cardConfig
|
||||
for key, value := range cardConfig {
|
||||
normalized[key] = value
|
||||
}
|
||||
normalized["allow_web_search"] = kolCardConfigBoolValue(cardConfig["allow_web_search"], false)
|
||||
normalized["allow_user_knowledge"] = kolCardConfigBoolValue(cardConfig["allow_user_knowledge"], true)
|
||||
return normalized
|
||||
}
|
||||
|
||||
func kolCardConfigBoolValue(value interface{}, defaultValue bool) bool {
|
||||
switch typed := value.(type) {
|
||||
case bool:
|
||||
return typed
|
||||
case *bool:
|
||||
if typed != nil {
|
||||
return *typed
|
||||
}
|
||||
}
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
func kolCardConfigAllowsWebSearch(cardConfig map[string]interface{}) bool {
|
||||
return kolCardConfigBoolValue(cardConfig["allow_web_search"], false)
|
||||
}
|
||||
|
||||
func kolCardConfigAllowsUserKnowledge(cardConfig map[string]interface{}) bool {
|
||||
return kolCardConfigBoolValue(cardConfig["allow_user_knowledge"], true)
|
||||
}
|
||||
|
||||
func decodeKolSchema(raw []byte) (*KolSchemaJSON, error) {
|
||||
@@ -542,7 +582,7 @@ func decodeKolSchema(raw []byte) (*KolSchemaJSON, error) {
|
||||
func decodeKolCardConfig(raw []byte) (map[string]interface{}, error) {
|
||||
trimmed := bytes.TrimSpace(raw)
|
||||
if len(trimmed) == 0 || bytes.Equal(trimmed, []byte("null")) {
|
||||
return map[string]interface{}{}, nil
|
||||
return normalizeKolCardConfig(nil), nil
|
||||
}
|
||||
|
||||
var cardConfig map[string]interface{}
|
||||
|
||||
Reference in New Issue
Block a user