mirror of
https://github.com/discourse/discourse-ai.git
synced 2025-06-25 00:52:14 +00:00
FIX: custom tools incorrectly setting all fields to blank enum (#1385)
Previous to this change, enum was set to [] which broke all non enum tools
This commit is contained in:
parent
77ae426d95
commit
b5d393b4bc
@ -22,6 +22,8 @@ class AiTool < ActiveRecord::Base
|
|||||||
message: I18n.t("discourse_ai.tools.name.characters"),
|
message: I18n.t("discourse_ai.tools.name.characters"),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
validate :validate_parameters_enum
|
||||||
|
|
||||||
def signature
|
def signature
|
||||||
{
|
{
|
||||||
name: function_call_name,
|
name: function_call_name,
|
||||||
@ -57,6 +59,30 @@ class AiTool < ActiveRecord::Base
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def validate_parameters_enum
|
||||||
|
return unless parameters.is_a?(Array)
|
||||||
|
|
||||||
|
parameters.each_with_index do |param, index|
|
||||||
|
next if !param.is_a?(Hash) || !param.key?("enum")
|
||||||
|
enum_values = param["enum"]
|
||||||
|
|
||||||
|
if enum_values.empty?
|
||||||
|
errors.add(
|
||||||
|
:parameters,
|
||||||
|
"Parameter '#{param["name"]}' at index #{index}: enum cannot be empty",
|
||||||
|
)
|
||||||
|
next
|
||||||
|
end
|
||||||
|
|
||||||
|
if enum_values.uniq.length != enum_values.length
|
||||||
|
errors.add(
|
||||||
|
:parameters,
|
||||||
|
"Parameter '#{param["name"]}' at index #{index}: enum values must be unique",
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def self.preamble
|
def self.preamble
|
||||||
<<~JS
|
<<~JS
|
||||||
/**
|
/**
|
||||||
|
@ -30,11 +30,16 @@ export default class AiToolEditorForm extends Component {
|
|||||||
|
|
||||||
get formData() {
|
get formData() {
|
||||||
const parameters = (this.args.editingModel.parameters ?? []).map(
|
const parameters = (this.args.editingModel.parameters ?? []).map(
|
||||||
(parameter) => ({
|
(parameter) => {
|
||||||
...parameter,
|
const mappedParameter = {
|
||||||
isEnum: !!parameter.enum?.length,
|
...parameter,
|
||||||
enum: (parameter.enum ??= []),
|
};
|
||||||
})
|
parameter.isEnum = parameter.enum && parameter.enum.length > 0;
|
||||||
|
if (!parameter.isEnum) {
|
||||||
|
delete mappedParameter.enum;
|
||||||
|
}
|
||||||
|
return mappedParameter;
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -92,6 +92,40 @@ RSpec.describe DiscourseAi::Admin::AiToolsController do
|
|||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "when enum validation fails" do
|
||||||
|
it "fails to create tool with empty enum" do
|
||||||
|
attrs = valid_attributes
|
||||||
|
attrs[:parameters] = [attrs[:parameters].first.merge(enum: [])]
|
||||||
|
|
||||||
|
expect {
|
||||||
|
post "/admin/plugins/discourse-ai/ai-tools.json",
|
||||||
|
params: { ai_tool: attrs }.to_json,
|
||||||
|
headers: {
|
||||||
|
"CONTENT_TYPE" => "application/json",
|
||||||
|
}
|
||||||
|
}.not_to change(AiTool, :count)
|
||||||
|
|
||||||
|
expect(response).to have_http_status(:unprocessable_entity)
|
||||||
|
expect(response.parsed_body["errors"]).to include(match(/enum cannot be empty/))
|
||||||
|
end
|
||||||
|
|
||||||
|
it "fails to create tool with duplicate enum values" do
|
||||||
|
attrs = valid_attributes
|
||||||
|
attrs[:parameters] = [attrs[:parameters].first.merge(enum: %w[c f c])]
|
||||||
|
|
||||||
|
expect {
|
||||||
|
post "/admin/plugins/discourse-ai/ai-tools.json",
|
||||||
|
params: { ai_tool: attrs }.to_json,
|
||||||
|
headers: {
|
||||||
|
"CONTENT_TYPE" => "application/json",
|
||||||
|
}
|
||||||
|
}.not_to change(AiTool, :count)
|
||||||
|
|
||||||
|
expect(response).to have_http_status(:unprocessable_entity)
|
||||||
|
expect(response.parsed_body["errors"]).to include(match(/enum values must be unique/))
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "PUT #update" do
|
describe "PUT #update" do
|
||||||
|
Loading…
x
Reference in New Issue
Block a user