feat: filter meaningful conversations with local model
This commit is contained in:
@@ -209,15 +209,19 @@ func (s *Service) Test(ctx context.Context, principal identity.Principal, tenant
|
||||
testStatus, errorCode = "failed", normalizedErrorCode(err)
|
||||
}
|
||||
var result Model
|
||||
auditResult := "success"
|
||||
if testStatus != "passed" {
|
||||
auditResult = "failure"
|
||||
}
|
||||
updateErr := database.Transact(ctx, s.registry.pool, func(tx pgx.Tx) error {
|
||||
row := tx.QueryRow(ctx, modelUpdateReturning+` WHERE cm.tenant_id=$1::uuid AND cm.public_id=$2::uuid`, current.tenantID, publicID, testStatus, errorCode, current.userID, current.tenantPublicID)
|
||||
row := tx.QueryRow(ctx, modelUpdateReturning, current.tenantID, publicID, testStatus, errorCode, current.userID, current.tenantPublicID)
|
||||
updated, scanErr := scanModel(row)
|
||||
if scanErr != nil {
|
||||
return scanErr
|
||||
}
|
||||
result = updated.Model
|
||||
resourceID := result.ID
|
||||
return s.audit.Record(ctx, tx, audit.Event{TenantID: ¤t.tenantID, ActorType: "user", ActorPublicID: ¤t.userPublicID, Action: "content_model.test", ResourceType: "content_model", ResourceID: &resourceID, RequestID: requestID, Purpose: "验证总结模型连通性", Result: testStatus, Detail: map[string]any{"error_code": errorCode}})
|
||||
return s.audit.Record(ctx, tx, audit.Event{TenantID: ¤t.tenantID, ActorType: "user", ActorPublicID: ¤t.userPublicID, Action: "content_model.test", ResourceType: "content_model", ResourceID: &resourceID, RequestID: requestID, Purpose: "验证总结模型连通性", Result: auditResult, Detail: map[string]any{"test_status": testStatus, "error_code": errorCode}})
|
||||
})
|
||||
if updateErr != nil {
|
||||
return Model{}, updateErr
|
||||
@@ -359,13 +363,18 @@ func normalizeInput(input *CreateInput) {
|
||||
func validateInput(input CreateInput) error {
|
||||
parsed, err := url.Parse(input.BaseURL)
|
||||
validProvider := input.Provider == "ark" || input.Provider == "openai_compatible"
|
||||
validURL := err == nil && parsed.Host != "" && (parsed.Scheme == "https" || (parsed.Scheme == "http" && (parsed.Hostname() == "localhost" || parsed.Hostname() == "127.0.0.1")))
|
||||
validURL := err == nil && parsed.Host != "" && (parsed.Scheme == "https" || (parsed.Scheme == "http" && isApprovedLocalModelHost(parsed.Hostname())))
|
||||
if !validUUID(input.TenantID) || len([]rune(input.DisplayName)) < 1 || len([]rune(input.DisplayName)) > 120 || !validProvider || !validURL || input.ModelID == "" || len(input.APIKey) < 8 || input.Temperature < 0 || input.Temperature > 2 || input.MaxTokens < 256 || input.MaxTokens > 8192 {
|
||||
return ErrInvalid
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func isApprovedLocalModelHost(host string) bool {
|
||||
host = strings.ToLower(strings.TrimSpace(host))
|
||||
return host == "localhost" || host == "127.0.0.1" || host == "::1" || host == "ollama"
|
||||
}
|
||||
|
||||
func credentialHint(key string) string {
|
||||
runes := []rune(strings.TrimSpace(key))
|
||||
if len(runes) <= 4 {
|
||||
@@ -398,7 +407,7 @@ func validUUID(value string) bool { _, err := uuid.Parse(value); return err == n
|
||||
|
||||
const modelSelect = `SELECT cm.public_id::text,t.public_id::text,cm.display_name,cm.provider,cm.base_url,cm.model_id,cm.credential_hint,cm.temperature::float8,cm.max_tokens,cm.status,cm.test_status,cm.last_tested_at,COALESCE(cm.last_error_code,''),cm.activated_at,cm.version,cm.created_at,cm.updated_at,cm.tenant_id::text,cm.encrypted_api_key,cm.nonce,cm.key_version FROM content_model_config cm JOIN tenant t ON t.id=cm.tenant_id`
|
||||
const modelReturning = `cm.public_id::text,$4::text,cm.display_name,cm.provider,cm.base_url,cm.model_id,cm.credential_hint,cm.temperature::float8,cm.max_tokens,cm.status,cm.test_status,cm.last_tested_at,COALESCE(cm.last_error_code,''),cm.activated_at,cm.version,cm.created_at,cm.updated_at,cm.tenant_id::text,cm.encrypted_api_key,cm.nonce,cm.key_version`
|
||||
const modelUpdateReturning = `UPDATE content_model_config cm SET test_status=$3,last_tested_at=now(),last_error_code=NULLIF($4,''),updated_at=now(),version=version+1,updated_by=$5::uuid RETURNING cm.public_id::text,$6::text,cm.display_name,cm.provider,cm.base_url,cm.model_id,cm.credential_hint,cm.temperature::float8,cm.max_tokens,cm.status,cm.test_status,cm.last_tested_at,COALESCE(cm.last_error_code,''),cm.activated_at,cm.version,cm.created_at,cm.updated_at,cm.tenant_id::text,cm.encrypted_api_key,cm.nonce,cm.key_version`
|
||||
const modelUpdateReturning = `UPDATE content_model_config cm SET test_status=$3,last_tested_at=now(),last_error_code=NULLIF($4,''),updated_at=now(),version=version+1,updated_by=$5::uuid WHERE cm.tenant_id=$1::uuid AND cm.public_id=$2::uuid RETURNING cm.public_id::text,$6::text,cm.display_name,cm.provider,cm.base_url,cm.model_id,cm.credential_hint,cm.temperature::float8,cm.max_tokens,cm.status,cm.test_status,cm.last_tested_at,COALESCE(cm.last_error_code,''),cm.activated_at,cm.version,cm.created_at,cm.updated_at,cm.tenant_id::text,cm.encrypted_api_key,cm.nonce,cm.key_version`
|
||||
|
||||
type rowScanner interface{ Scan(...any) error }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user