mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-08-09 00:47:59 +08:00
fix: reject duplicate chat parameter keys (#17977)
This commit is contained in:
@@ -256,9 +256,13 @@ func (s *ChatService) Create(ctx context.Context, userID string, req map[string]
|
||||
}
|
||||
|
||||
if promptConfigValue, ok := req["prompt_config"]; ok {
|
||||
if _, ok := mapFromValue(promptConfigValue); !ok {
|
||||
promptConfig, ok := mapFromValue(promptConfigValue)
|
||||
if !ok {
|
||||
return nil, common.CodeDataError, errors.New("`prompt_config` should be an object")
|
||||
}
|
||||
if err := validatePromptConfigParameters(promptConfig); err != nil {
|
||||
return nil, common.CodeDataError, err
|
||||
}
|
||||
}
|
||||
|
||||
if metaDataFilterValue, ok := req["meta_data_filter"]; ok && metaDataFilterValue != nil {
|
||||
@@ -915,6 +919,9 @@ func (s *ChatService) updateChatREST(ctx context.Context, userID, chatID string,
|
||||
if !ok {
|
||||
return nil, errors.New("`prompt_config` should be an object")
|
||||
}
|
||||
if err := validatePromptConfigParameters(promptConfig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if patch {
|
||||
req["prompt_config"] = mergeJSONMap(currentChat.PromptConfig, promptConfig)
|
||||
} else {
|
||||
@@ -980,6 +987,30 @@ func (s *ChatService) updateChatREST(ctx context.Context, userID, chatID string,
|
||||
return s.buildRESTChatResponse(ctx, updatedChat), nil
|
||||
}
|
||||
|
||||
func validatePromptConfigParameters(promptConfig map[string]interface{}) error {
|
||||
parameters, ok := promptConfig["parameters"].([]interface{})
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
seen := make(map[string]struct{}, len(parameters))
|
||||
for _, value := range parameters {
|
||||
parameter, ok := mapFromValue(value)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
key, ok := parameter["key"].(string)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if _, exists := seen[key]; exists {
|
||||
return fmt.Errorf("`parameters` contains duplicate key: %s", key)
|
||||
}
|
||||
seen[key] = struct{}{}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateRESTChatName(value interface{}, required bool) (string, bool, error) {
|
||||
if value == nil {
|
||||
if required {
|
||||
|
||||
@@ -489,6 +489,24 @@ func TestChatServiceCreateRejectsInvalidPromptConfig(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestChatServiceUpdateRejectsDuplicatePromptParameterKeys(t *testing.T) {
|
||||
db := setupChatRESTUpdateServiceTestDB(t)
|
||||
createChatRESTUpdateServiceTestChat(t, db, "chat-1", "user-1")
|
||||
|
||||
svc := NewChatService()
|
||||
_, err := svc.UpdateChat(t.Context(), "user-1", "chat-1", map[string]interface{}{
|
||||
"prompt_config": map[string]interface{}{
|
||||
"parameters": []interface{}{
|
||||
map[string]interface{}{"key": "knowledge"},
|
||||
map[string]interface{}{"key": "knowledge"},
|
||||
},
|
||||
},
|
||||
})
|
||||
if err == nil || err.Error() != "`parameters` contains duplicate key: knowledge" {
|
||||
t.Fatalf("expected duplicate parameter key error, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestChatServiceCreatePromptDefaultsContract(t *testing.T) {
|
||||
setupChatRESTUpdateServiceTestDB(t)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user