diff --git a/app/controllers/discourse_ai/admin/ai_tools_controller.rb b/app/controllers/discourse_ai/admin/ai_tools_controller.rb
index f5aa081b..92f5905c 100644
--- a/app/controllers/discourse_ai/admin/ai_tools_controller.rb
+++ b/app/controllers/discourse_ai/admin/ai_tools_controller.rb
@@ -5,7 +5,7 @@ module DiscourseAi
class AiToolsController < ::Admin::AdminController
requires_plugin ::DiscourseAi::PLUGIN_NAME
- before_action :find_ai_tool, only: %i[show update destroy]
+ before_action :find_ai_tool, only: %i[test show update destroy]
def index
ai_tools = AiTool.all
@@ -17,7 +17,7 @@ module DiscourseAi
end
def create
- ai_tool = AiTool.new(ai_tool_params.except(:rag_uploads))
+ ai_tool = AiTool.new(ai_tool_params)
ai_tool.created_by_id = current_user.id
if ai_tool.save
@@ -29,7 +29,7 @@ module DiscourseAi
end
def update
- if @ai_tool.update(ai_tool_params.except(:rag_uploads))
+ if @ai_tool.update(ai_tool_params)
RagDocumentFragment.update_target_uploads(@ai_tool, attached_upload_ids)
render_serialized(@ai_tool, AiCustomToolSerializer)
else
@@ -46,18 +46,13 @@ module DiscourseAi
end
def test
- if params[:id].present?
- ai_tool = AiTool.find(params[:id])
- else
- ai_tool = AiTool.new(ai_tool_params.except(:rag_uploads))
- end
-
+ @ai_tool.assign_attributes(ai_tool_params) if params[:ai_tool]
parameters = params[:parameters].to_unsafe_h
# we need an llm so we have a tokenizer
# but will do without if none is available
llm = LlmModel.first&.to_llm
- runner = ai_tool.runner(parameters, llm: llm, bot_user: current_user, context: {})
+ runner = @ai_tool.runner(parameters, llm: llm, bot_user: current_user, context: {})
result = runner.invoke
if result.is_a?(Hash) && result[:error]
@@ -74,24 +69,27 @@ module DiscourseAi
private
def attached_upload_ids
- ai_tool_params[:rag_uploads].to_a.map { |h| h[:id] }
+ params[:ai_tool][:rag_uploads].to_a.map { |h| h[:id] }
end
def find_ai_tool
- @ai_tool = AiTool.find(params[:id])
+ @ai_tool = AiTool.find(params[:id].to_i)
end
def ai_tool_params
- params.require(:ai_tool).permit(
- :name,
- :description,
- :script,
- :summary,
- :rag_chunk_tokens,
- :rag_chunk_overlap_tokens,
- rag_uploads: [:id],
- parameters: [:name, :type, :description, :required, enum: []],
- )
+ params
+ .require(:ai_tool)
+ .permit(
+ :name,
+ :description,
+ :script,
+ :summary,
+ :rag_chunk_tokens,
+ :rag_chunk_overlap_tokens,
+ rag_uploads: [:id],
+ parameters: [:name, :type, :description, :required, enum: []],
+ )
+ .except(:rag_uploads)
end
end
end
diff --git a/assets/javascripts/discourse/components/ai-tool-editor.gjs b/assets/javascripts/discourse/components/ai-tool-editor.gjs
index 566b704a..24536e62 100644
--- a/assets/javascripts/discourse/components/ai-tool-editor.gjs
+++ b/assets/javascripts/discourse/components/ai-tool-editor.gjs
@@ -232,11 +232,13 @@ export default class AiToolEditor extends Component {
{{/if}}
-
+ {{#unless @model.isNew}}
+
+ {{/unless}}
(query, options) do
+ ->(*params) do
begin
+ query, options = params
self.running_attached_function = true
options ||= {}
options = options.symbolize_keys
diff --git a/lib/embeddings/vector_representations/base.rb b/lib/embeddings/vector_representations/base.rb
index d8236181..d5c23d21 100644
--- a/lib/embeddings/vector_representations/base.rb
+++ b/lib/embeddings/vector_representations/base.rb
@@ -205,7 +205,10 @@ module DiscourseAi
FROM
#{rag_fragments_table_name}
INNER JOIN
- rag_document_fragments ON rag_document_fragments.id = rag_document_fragment_id
+ rag_document_fragments ON
+ rag_document_fragments.id = rag_document_fragment_id AND
+ rag_document_fragments.target_id = :target_id AND
+ rag_document_fragments.target_type = :target_type
WHERE
model_id = #{id} AND strategy_id = #{@strategy.id}
ORDER BY
diff --git a/spec/requests/admin/ai_tools_controller_spec.rb b/spec/requests/admin/ai_tools_controller_spec.rb
index e05b7344..3ba96ac4 100644
--- a/spec/requests/admin/ai_tools_controller_spec.rb
+++ b/spec/requests/admin/ai_tools_controller_spec.rb
@@ -137,9 +137,8 @@ RSpec.describe DiscourseAi::Admin::AiToolsController do
describe "#test" do
it "runs an existing tool and returns the result" do
- post "/admin/plugins/discourse-ai/ai-tools/test.json",
+ post "/admin/plugins/discourse-ai/ai-tools/#{ai_tool.id}/test.json",
params: {
- id: ai_tool.id,
parameters: {
input: "Hello, World!",
},
@@ -149,43 +148,36 @@ RSpec.describe DiscourseAi::Admin::AiToolsController do
expect(response.parsed_body["output"]).to eq("input" => "Hello, World!")
end
- it "runs a new unsaved tool and returns the result" do
- post "/admin/plugins/discourse-ai/ai-tools/test.json",
+ it "accept changes to the ai_tool parameters that redefine stuff" do
+ post "/admin/plugins/discourse-ai/ai-tools/#{ai_tool.id}/test.json",
params: {
ai_tool: {
- name: "New Tool",
- description: "A new test tool",
- script: "function invoke(params) { return 'New test result: ' + params.input; }",
- parameters: [
- { name: "input", type: "string", description: "Input for the new test tool" },
- ],
+ script: "function invoke(params) { return 'hi there'; }",
},
- parameters: {
- input: "Test input",
- },
- }
-
- expect(response.status).to eq(200)
- expect(response.parsed_body["output"]).to eq("New test result: Test input")
- end
-
- it "returns an error for invalid tool_id" do
- post "/admin/plugins/discourse-ai/ai-tools/test.json",
- params: {
- id: -1,
parameters: {
input: "Hello, World!",
},
}
- expect(response.status).to eq(400)
- expect(response.parsed_body["errors"]).to include("Couldn't find AiTool with 'id'=-1")
+ expect(response.status).to eq(200)
+ expect(response.parsed_body["output"]).to eq("hi there")
+ end
+
+ it "returns an error for invalid tool_id" do
+ post "/admin/plugins/discourse-ai/ai-tools/-1/test.json",
+ params: {
+ parameters: {
+ input: "Hello, World!",
+ },
+ }
+
+ expect(response.status).to eq(404)
end
it "handles exceptions during tool execution" do
ai_tool.update!(script: "function invoke(params) { throw new Error('Test error'); }")
- post "/admin/plugins/discourse-ai/ai-tools/test.json",
+ post "/admin/plugins/discourse-ai/ai-tools/#{ai_tool.id}/test.json",
params: {
id: ai_tool.id,
parameters: {
diff --git a/spec/system/ai_bot/tool_spec.rb b/spec/system/ai_bot/tool_spec.rb
index 2d250345..ec52ca16 100644
--- a/spec/system/ai_bot/tool_spec.rb
+++ b/spec/system/ai_bot/tool_spec.rb
@@ -49,7 +49,8 @@ describe "AI Tool Management", type: :system do
expect(page.first(".parameter-row__required-toggle").checked?).to eq(true)
expect(page.first(".parameter-row__enum-toggle").checked?).to eq(false)
- ensure_can_run_test
+ # not allowed to test yet
+ expect(page).not_to have_button(".ai-tool-editor__test-button")
expect(page).not_to have_button(".ai-tool-editor__delete")
find(".ai-tool-editor__save").click