feat: integrate AI candidate review and automatic publication

This commit is contained in:
2026-10-09 22:33:38 +08:00
parent 04dbeb2ac6
commit 86f1e7a897
46 changed files with 2460 additions and 2362 deletions
+19 -1
View File
@@ -112,7 +112,7 @@ func (s *ProviderService) Save(ctx context.Context, actor model.User, key, reque
if input.WireAPI != "responses" && input.WireAPI != "chat_completions" {
return c, apperror.ErrInvalidInput
}
if utf8.RuneCountInString(input.Name) > 80 || utf8.RuneCountInString(input.ModelName) > 120 || len(input.BaseURL) > 2048 || len(input.ModelCatalogURL) > 2048 || input.TimeoutSeconds < 1 || input.TimeoutSeconds > 30 {
if utf8.RuneCountInString(input.Name) > 80 || utf8.RuneCountInString(input.ModelName) > 120 || len(input.BaseURL) > 2048 || len(input.ModelCatalogURL) > 2048 || input.TimeoutSeconds < 1 || input.TimeoutSeconds > 120 {
return c, apperror.ErrInvalidInput
}
if input.BaseURL != "" {
@@ -173,3 +173,21 @@ func (s *ProviderService) Save(ctx context.Context, actor model.User, key, reque
}
return s.repo.Save(ctx, c, input.ExpectedVersion, actor.ID, requestID, input.APIKey != nil || input.ClearAPIKey)
}
// CopyPrimaryToReview lets a single endpoint/key configure a separate review call.
// Credentials stay in the server vault and are rebound to the destination config.
func (s *ProviderService) CopyPrimaryToReview(ctx context.Context, actor model.User, requestID string, expected int64) (model.ProviderConfig, error) {
if err := s.authorize(actor); err != nil {
return model.ProviderConfig{}, err
}
primary, err := s.repo.Get(ctx, "model_primary")
if err != nil {
return model.ProviderConfig{}, err
}
key, err := s.vault.Decrypt(primary.EncryptedAPIKey, primary.ConfigKey)
if err != nil {
return model.ProviderConfig{}, err
}
disabled, auth := primary.DisableResponseStorage, primary.RequiresOpenAIAuth
return s.Save(ctx, actor, "model_review", requestID, ProviderInput{Name: primary.Name, BaseURL: primary.BaseURL, ModelName: primary.ModelName, WireAPI: primary.WireAPI, ModelCatalogURL: primary.ModelCatalogURL, DisableResponseStorage: &disabled, RequiresOpenAIAuth: &auth, Enabled: primary.Enabled, TimeoutSeconds: primary.TimeoutSeconds, APIKey: &key, ExpectedVersion: expected})
}