mirror of
https://github.com/discourse/discourse-ai.git
synced 2025-03-09 11:48:47 +00:00
This changeset contains 4 fixes: 1. We were allowing running tests on unsaved tools, this is problematic cause uploads are not yet associated or indexed leading to confusing results. We now only show the test button when tool is saved. 2. We were not properly scoping rag document fragements, this meant that personas and ai tools could get results from other unrelated tools, just to be filtered out later 3. index.search showed options as "optional" but implementation required the second option 4. When testing tools searching through document fragments was not working at all cause we did not properly load the tool
97 lines
2.6 KiB
Ruby
97 lines
2.6 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module DiscourseAi
|
|
module Admin
|
|
class AiToolsController < ::Admin::AdminController
|
|
requires_plugin ::DiscourseAi::PLUGIN_NAME
|
|
|
|
before_action :find_ai_tool, only: %i[test show update destroy]
|
|
|
|
def index
|
|
ai_tools = AiTool.all
|
|
render_serialized({ ai_tools: ai_tools }, AiCustomToolListSerializer, root: false)
|
|
end
|
|
|
|
def show
|
|
render_serialized(@ai_tool, AiCustomToolSerializer)
|
|
end
|
|
|
|
def create
|
|
ai_tool = AiTool.new(ai_tool_params)
|
|
ai_tool.created_by_id = current_user.id
|
|
|
|
if ai_tool.save
|
|
RagDocumentFragment.link_target_and_uploads(ai_tool, attached_upload_ids)
|
|
render_serialized(ai_tool, AiCustomToolSerializer, status: :created)
|
|
else
|
|
render_json_error ai_tool
|
|
end
|
|
end
|
|
|
|
def update
|
|
if @ai_tool.update(ai_tool_params)
|
|
RagDocumentFragment.update_target_uploads(@ai_tool, attached_upload_ids)
|
|
render_serialized(@ai_tool, AiCustomToolSerializer)
|
|
else
|
|
render_json_error @ai_tool
|
|
end
|
|
end
|
|
|
|
def destroy
|
|
if @ai_tool.destroy
|
|
head :no_content
|
|
else
|
|
render_json_error @ai_tool
|
|
end
|
|
end
|
|
|
|
def test
|
|
@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: {})
|
|
result = runner.invoke
|
|
|
|
if result.is_a?(Hash) && result[:error]
|
|
render_json_error result[:error]
|
|
else
|
|
render json: { output: result }
|
|
end
|
|
rescue ActiveRecord::RecordNotFound => e
|
|
render_json_error e.message, status: 400
|
|
rescue => e
|
|
render_json_error "Error executing the tool: #{e.message}", status: 400
|
|
end
|
|
|
|
private
|
|
|
|
def attached_upload_ids
|
|
params[:ai_tool][:rag_uploads].to_a.map { |h| h[:id] }
|
|
end
|
|
|
|
def find_ai_tool
|
|
@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: []],
|
|
)
|
|
.except(:rag_uploads)
|
|
end
|
|
end
|
|
end
|
|
end
|