2023-11-23 12:58:54 -03:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
module DiscourseAi
|
|
|
|
module Completions
|
|
|
|
module Dialects
|
2023-12-18 18:06:01 -03:00
|
|
|
class Claude < Dialect
|
|
|
|
class << self
|
|
|
|
def can_translate?(model_name)
|
|
|
|
%w[claude-instant-1 claude-2].include?(model_name)
|
|
|
|
end
|
|
|
|
|
|
|
|
def tokenizer
|
|
|
|
DiscourseAi::Tokenizer::AnthropicTokenizer
|
|
|
|
end
|
2023-11-23 12:58:54 -03:00
|
|
|
end
|
|
|
|
|
2023-12-18 18:06:01 -03:00
|
|
|
def translate
|
2024-01-09 00:28:03 +11:00
|
|
|
claude_prompt = uses_system_message? ? +"" : +"Human: "
|
|
|
|
claude_prompt << prompt[:insts] << "\n"
|
2023-11-23 12:58:54 -03:00
|
|
|
|
2023-12-18 18:06:01 -03:00
|
|
|
claude_prompt << build_tools_prompt if prompt[:tools]
|
2023-11-23 12:58:54 -03:00
|
|
|
|
2023-12-18 18:06:01 -03:00
|
|
|
claude_prompt << build_examples(prompt[:examples]) if prompt[:examples]
|
2023-11-23 12:58:54 -03:00
|
|
|
|
2023-12-18 18:06:01 -03:00
|
|
|
claude_prompt << conversation_context if prompt[:conversation_context]
|
|
|
|
|
2024-01-09 14:10:20 -03:00
|
|
|
if uses_system_message? && (prompt[:input] || prompt[:post_insts])
|
|
|
|
claude_prompt << "Human: "
|
|
|
|
end
|
|
|
|
claude_prompt << "#{prompt[:input]}\n" if prompt[:input]
|
2023-12-18 18:06:01 -03:00
|
|
|
|
|
|
|
claude_prompt << "#{prompt[:post_insts]}\n" if prompt[:post_insts]
|
2023-11-23 12:58:54 -03:00
|
|
|
|
2024-01-09 00:28:03 +11:00
|
|
|
claude_prompt << "\n\n"
|
2023-12-19 12:04:15 +11:00
|
|
|
claude_prompt << "Assistant:"
|
|
|
|
claude_prompt << " #{prompt[:final_insts]}:" if prompt[:final_insts]
|
|
|
|
claude_prompt << "\n"
|
2023-11-23 12:58:54 -03:00
|
|
|
end
|
|
|
|
|
2023-12-18 18:06:01 -03:00
|
|
|
def max_prompt_tokens
|
2024-01-09 14:10:20 -03:00
|
|
|
100_000 # Claude-2.1 has a 200k context window.
|
2023-12-18 18:06:01 -03:00
|
|
|
end
|
|
|
|
|
|
|
|
def conversation_context
|
|
|
|
return "" if prompt[:conversation_context].blank?
|
|
|
|
|
2024-01-04 10:44:07 -03:00
|
|
|
clean_context = prompt[:conversation_context].select { |cc| cc[:type] != "tool_call" }
|
2024-01-04 18:15:34 -03:00
|
|
|
flattened_context = flatten_context(clean_context)
|
|
|
|
trimmed_context = trim_context(flattened_context)
|
2023-12-18 18:06:01 -03:00
|
|
|
|
|
|
|
trimmed_context
|
|
|
|
.reverse
|
|
|
|
.reduce(+"") do |memo, context|
|
|
|
|
memo << (context[:type] == "user" ? "Human:" : "Assistant:")
|
|
|
|
|
|
|
|
if context[:type] == "tool"
|
|
|
|
memo << <<~TEXT
|
|
|
|
|
|
|
|
<function_results>
|
|
|
|
<result>
|
|
|
|
<tool_name>#{context[:name]}</tool_name>
|
|
|
|
<json>
|
|
|
|
#{context[:content]}
|
|
|
|
</json>
|
|
|
|
</result>
|
|
|
|
</function_results>
|
|
|
|
TEXT
|
|
|
|
else
|
|
|
|
memo << " " << context[:content] << "\n"
|
|
|
|
end
|
|
|
|
|
|
|
|
memo
|
|
|
|
end
|
2023-11-23 12:58:54 -03:00
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
2024-01-09 00:28:03 +11:00
|
|
|
def uses_system_message?
|
|
|
|
model_name == "claude-2"
|
|
|
|
end
|
|
|
|
|
2023-11-23 12:58:54 -03:00
|
|
|
def build_examples(examples_arr)
|
|
|
|
examples_arr.reduce("") do |memo, example|
|
|
|
|
memo += "<example>\nH: #{example[0]}\nA: #{example[1]}\n</example>\n"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|