discourse-ai/lib/completions/dialects/nova_tools.rb

84 lines
2.0 KiB
Ruby

# frozen_string_literal: true
module DiscourseAi
module Completions
module Dialects
class NovaTools
def initialize(tools)
@raw_tools = tools
end
def translated_tools
return if !@raw_tools.present?
# note: forced tools are not supported yet toolChoice is always auto
{
tools:
@raw_tools.map do |tool|
{
toolSpec: {
name: tool[:name],
description: tool[:description],
inputSchema: {
json: convert_tool_to_input_schema(tool),
},
},
}
end,
}
end
# nativ tools require no system instructions
def instructions
""
end
def from_raw_tool_call(raw_message)
{
toolUse: {
toolUseId: raw_message[:id],
name: raw_message[:name],
input: JSON.parse(raw_message[:content])["arguments"],
},
}
end
def from_raw_tool(raw_message)
{
toolResult: {
toolUseId: raw_message[:id],
content: [{ json: JSON.parse(raw_message[:content]) }],
},
}
end
private
def convert_tool_to_input_schema(tool)
tool = tool.transform_keys(&:to_sym)
properties = {}
tool[:parameters].each do |param|
schema = {}
type = param[:type]
type = "string" if !%w[string number boolean integer array].include?(type)
schema[:type] = type
if enum = param[:enum]
schema[:enum] = enum
end
schema[:items] = { type: param[:item_type] } if type == "array"
schema[:required] = true if param[:required]
properties[param[:name]] = schema
end
{ type: "object", properties: properties }
end
end
end
end
end