fix: Enhance Kol Variable Rendering and Management
- Updated the regex for placeholder matching to support more flexible key formats. - Refactored variable storage to allow both ID and key lookups in rendering. - Improved schema validation to check for duplicate keys and enforce non-empty keys. - Added new utility functions for variable value lookup and display name generation. - Enhanced tests to cover new key-based variable scenarios. - Refactored KolPrompt repository to simplify prompt storage and management, including the removal of obsolete revision handling. - Introduced new API endpoints for saving, activating, and archiving prompts. - Added new utility functions for handling Kol placeholders and platform options in the admin web. - Implemented database migrations to simplify prompt storage structure and ensure data integrity.
This commit is contained in:
@@ -99,16 +99,16 @@ func (s *KolGenerationService) WithCache(c sharedcache.Cache) *KolGenerationServ
|
||||
}
|
||||
|
||||
func (s *KolGenerationService) GetSchema(ctx context.Context, actor auth.Actor, subPromptID int64) (*KolSubscriptionPromptSchemaResponse, error) {
|
||||
row, revision, err := s.loadAuthorizedRevision(ctx, actor, subPromptID)
|
||||
row, prompt, err := s.loadAuthorizedPrompt(ctx, actor, subPromptID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
schema, err := decodeKolSchema(revision.SchemaJSON)
|
||||
schema, err := decodeKolSchema(prompt.SchemaJSON)
|
||||
if err != nil {
|
||||
return nil, response.ErrInternal(50096, "kol_generation_schema_decode_failed", err.Error())
|
||||
}
|
||||
cardConfig, err := decodeKolCardConfig(revision.CardConfigJSON)
|
||||
cardConfig, err := decodeKolCardConfig(prompt.CardConfigJSON)
|
||||
if err != nil {
|
||||
return nil, response.ErrInternal(50097, "kol_generation_card_config_decode_failed", err.Error())
|
||||
}
|
||||
@@ -126,7 +126,7 @@ func (s *KolGenerationService) GetSchema(ctx context.Context, actor auth.Actor,
|
||||
}
|
||||
|
||||
func (s *KolGenerationService) Submit(ctx context.Context, actor auth.Actor, subPromptID int64, variables map[string]any) (*KolGenerationSubmitResponse, error) {
|
||||
row, revision, err := s.loadAuthorizedRevision(ctx, actor, subPromptID)
|
||||
row, prompt, err := s.loadAuthorizedPrompt(ctx, actor, subPromptID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -135,12 +135,16 @@ func (s *KolGenerationService) Submit(ctx context.Context, actor auth.Actor, sub
|
||||
variables = map[string]any{}
|
||||
}
|
||||
|
||||
schema, err := decodeKolSchema(revision.SchemaJSON)
|
||||
schema, err := decodeKolSchema(prompt.SchemaJSON)
|
||||
if err != nil {
|
||||
return nil, response.ErrInternal(50096, "kol_generation_schema_decode_failed", err.Error())
|
||||
}
|
||||
|
||||
content, err := s.asset.Get(ctx, revision.PromptAssetKey)
|
||||
if prompt.PromptAssetKey == nil || *prompt.PromptAssetKey == "" {
|
||||
return nil, response.ErrInternal(50098, "kol_generation_prompt_asset_missing", "published prompt content not found")
|
||||
}
|
||||
|
||||
content, err := s.asset.Get(ctx, *prompt.PromptAssetKey)
|
||||
if err != nil {
|
||||
return nil, response.ErrInternal(50098, "kol_generation_prompt_asset_load_failed", err.Error())
|
||||
}
|
||||
@@ -150,6 +154,10 @@ func (s *KolGenerationService) Submit(ctx context.Context, actor auth.Actor, sub
|
||||
return nil, response.ErrBadRequest(40071, "kol_generation_variables_invalid", err.Error())
|
||||
}
|
||||
renderedPromptHash := HashPrompt(renderedPrompt)
|
||||
promptRevisionNo := 1
|
||||
if row.PublishedRevisionNo != nil && *row.PublishedRevisionNo > 0 {
|
||||
promptRevisionNo = *row.PublishedRevisionNo
|
||||
}
|
||||
|
||||
balance, err := s.quotaRepo.GetCurrentBalance(ctx, actor.TenantID, "article_generation")
|
||||
if err != nil || balance < 1 {
|
||||
@@ -161,10 +169,10 @@ func (s *KolGenerationService) Submit(ctx context.Context, actor auth.Actor, sub
|
||||
SubscriptionID: row.SubscriptionID,
|
||||
PackageID: row.PackageID,
|
||||
PromptID: row.PromptID,
|
||||
PromptRevisionNo: *row.PublishedRevisionNo,
|
||||
PromptRevisionNo: promptRevisionNo,
|
||||
Variables: variables,
|
||||
SchemaSnapshot: json.RawMessage(revision.SchemaJSON),
|
||||
CardConfigSnapshot: json.RawMessage(revision.CardConfigJSON),
|
||||
SchemaSnapshot: json.RawMessage(prompt.SchemaJSON),
|
||||
CardConfigSnapshot: json.RawMessage(prompt.CardConfigJSON),
|
||||
RenderedPromptHash: renderedPromptHash,
|
||||
RenderedPrompt: renderedPrompt,
|
||||
})
|
||||
@@ -259,10 +267,10 @@ func (s *KolGenerationService) Submit(ctx context.Context, actor auth.Actor, sub
|
||||
SubscriptionPromptID: &row.ID,
|
||||
PackageID: row.PackageID,
|
||||
PromptID: row.PromptID,
|
||||
PromptRevisionNo: *row.PublishedRevisionNo,
|
||||
PromptRevisionNo: promptRevisionNo,
|
||||
GenerationTaskID: &taskID,
|
||||
VariablesSnapshot: variablesJSON,
|
||||
SchemaSnapshot: revision.SchemaJSON,
|
||||
SchemaSnapshot: prompt.SchemaJSON,
|
||||
RenderedPromptHash: &renderedPromptHash,
|
||||
})
|
||||
if err != nil {
|
||||
@@ -300,7 +308,7 @@ func (s *KolGenerationService) Submit(ctx context.Context, actor auth.Actor, sub
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *KolGenerationService) loadAuthorizedRevision(ctx context.Context, actor auth.Actor, subPromptID int64) (*repository.KolSubscriptionPrompt, *repository.KolPromptRevision, error) {
|
||||
func (s *KolGenerationService) loadAuthorizedPrompt(ctx context.Context, actor auth.Actor, subPromptID int64) (*repository.KolSubscriptionPrompt, *repository.KolPrompt, error) {
|
||||
row, err := s.subRepo.GetSubscriptionPromptByID(ctx, actor.TenantID, subPromptID)
|
||||
if err != nil {
|
||||
return nil, nil, response.ErrInternal(50109, "kol_subscription_prompt_query_failed", err.Error())
|
||||
@@ -319,19 +327,19 @@ func (s *KolGenerationService) loadAuthorizedRevision(ctx context.Context, actor
|
||||
return nil, nil, ErrKolGenerationForbidden
|
||||
case row.PackageStatus != "published":
|
||||
return nil, nil, ErrKolGenerationForbidden
|
||||
case row.PromptStatus != "active" || row.PublishedRevisionNo == nil:
|
||||
case row.PromptStatus != "active":
|
||||
return nil, nil, ErrKolGenerationForbidden
|
||||
}
|
||||
|
||||
revision, err := s.promptRepo.GetRevision(ctx, row.CreatorTenantID, row.PromptID, *row.PublishedRevisionNo)
|
||||
prompt, err := s.promptRepo.GetByID(ctx, row.CreatorTenantID, row.PromptID)
|
||||
if err != nil {
|
||||
return nil, nil, response.ErrInternal(50110, "kol_prompt_revision_query_failed", err.Error())
|
||||
return nil, nil, response.ErrInternal(50110, "kol_prompt_query_failed", err.Error())
|
||||
}
|
||||
if revision == nil {
|
||||
return nil, nil, response.ErrInternal(50111, "kol_prompt_revision_missing", "published prompt revision not found")
|
||||
if prompt == nil || prompt.PromptAssetKey == nil || *prompt.PromptAssetKey == "" {
|
||||
return nil, nil, response.ErrInternal(50111, "kol_prompt_content_missing", "published prompt content not found")
|
||||
}
|
||||
|
||||
return row, revision, nil
|
||||
return row, prompt, nil
|
||||
}
|
||||
|
||||
func HandleKolGenerationTaskFailure(
|
||||
|
||||
Reference in New Issue
Block a user