# frozen_string_literal: true module DiscourseAi module Completions module Dialects class XmlTools def initialize(tools) @raw_tools = tools end def translated_tools raw_tools.reduce(+"") do |tools, function| parameters = +"" if function[:parameters].present? function[:parameters].each do |parameter| parameters << <<~PARAMETER #{parameter[:name]} #{parameter[:type]} #{parameter[:description]} #{parameter[:required]} PARAMETER if parameter[:enum] parameters << "#{parameter[:enum].join(",")}\n" end parameters << "\n" end end tools << <<~TOOLS #{function[:name]} #{function[:description]} #{parameters} TOOLS end end def instructions return "" if raw_tools.blank? @instructions ||= begin has_arrays = raw_tools.any? { |tool| tool[:parameters]&.any? { |p| p[:type] == "array" } } (<<~TEXT).strip #{tool_preamble(include_array_tip: has_arrays)} #{translated_tools} TEXT end end def from_raw_tool(raw_message) (<<~TEXT).strip #{raw_message[:name] || raw_message[:id]} #{raw_message[:content]} TEXT end def from_raw_tool_call(raw_message) parsed = JSON.parse(raw_message[:content], symbolize_names: true) parameters = +"" if parsed[:arguments] parameters << "\n" parsed[:arguments].each { |k, v| parameters << "<#{k}>#{v}\n" } parameters << "\n" end (<<~TEXT).strip #{raw_message[:name] || parsed[:name]} #{parameters} TEXT end private attr_reader :raw_tools def tool_preamble(include_array_tip: true) array_tip = if include_array_tip <<~TEXT If a parameter type is an array, return an array of values. For example: <$PARAMETER_NAME>["one","two","three"] TEXT else "" end <<~TEXT In this environment you have access to a set of tools you can use to answer the user's question. You may call them like this. $TOOL_NAME <$PARAMETER_NAME>$PARAMETER_VALUE ... #{array_tip} If you wish to call multiple function in one reply, wrap multiple block in a single block. Always prefer to lead with tool calls, if you need to execute any. Avoid all niceties prior to tool calls, Eg: "Let me look this up for you.." etc. Here are the complete list of tools available: TEXT end end end end end