discourse-ai/lib/ai_bot/tools/random_picker.rb
Sam 3a8d95f6b2
FEATURE: mentionable personas and random picker tool, context limits (#466)
1. Personas are now optionally mentionable, meaning that you can mention them either from public topics or PMs
       - Mentioning from PMs helps "switch" persona mid conversation, meaning if you want to look up sites setting you can invoke the site setting bot, or if you want to generate an image you can invoke dall e
        - Mentioning outside of PMs allows you to inject a bot reply in a topic trivially
     - We also add the support for max_context_posts this allow you to limit the amount of context you feed in, which can help control costs

2. Add support for a "random picker" tool that can be used to pick random numbers 

3. Clean up routing ai_personas -> ai-personas

4. Add Max Context Posts so users can control how much history a persona can consume (this is important for mentionable personas) 

Co-authored-by: Martin Brennan <martin@discourse.org>
2024-02-15 16:37:59 +11:00

74 lines
1.9 KiB
Ruby

# frozen_string_literal: true
module DiscourseAi
module AiBot
module Tools
class RandomPicker < Tool
def self.signature
{
name: name,
description:
"Handles a variety of random decisions based on the format of each input element",
parameters: [
{
name: "options",
description:
"An array where each element is either a range (e.g., '1-6') or a comma-separated list of options (e.g., 'sam,jane,joe')",
type: "array",
item_type: "string",
required: true,
},
],
}
end
def self.name
"random_picker"
end
def options
parameters[:options]
end
def invoke(_bot_user, _llm)
result = nil
# can be a naive list of strings
if options.none? { |option| option.match?(/\A\d+-\d+\z/) || option.include?(",") }
result = options.sample
else
result =
options.map do |option|
case option
when /\A\d+-\d+\z/ # Range format, e.g., "1-6"
random_range(option)
when /,/ # Comma-separated values, e.g., "sam,jane,joe"
pick_list(option)
else
"Invalid format: #{option}"
end
end
end
@last_result = result
{ options: options, result: result }
end
private
def random_range(range_str)
low, high = range_str.split("-").map(&:to_i)
rand(low..high)
end
def pick_list(list_str)
list_str.split(",").map(&:strip).sample
end
def description_args
{ options: options, result: @last_result }
end
end
end
end
end