Skip to content

Instantly share code, notes, and snippets.

@marckohlbrugge
Created January 7, 2025 18:08
Show Gist options
  • Save marckohlbrugge/6d8989ebcfe827236868967c5bfa19f7 to your computer and use it in GitHub Desktop.
Save marckohlbrugge/6d8989ebcfe827236868967c5bfa19f7 to your computer and use it in GitHub Desktop.
Example of implementing user confirmation with function calling in Raix
require "thor"
require "raix"
module AIChat
class Cli < Thor
desc "chat", "Start a chat session with AI"
def chat
client = Client.new(
user_interaction: -> (message, type: :prompt) {
case type
when :prompt
answer = ask(set_color(message, :yellow))
answer.downcase.start_with?('y')
when :info
say(message, :yellow)
puts
end
}
)
system_message = <<~PROMPT
You are a helpful AI assistant. Today's date is #{Time.current.strftime('%B %d, %Y')}.
You should be direct and concise in your responses while remaining helpful and friendly.
If you're not sure about something, please say so.
You have access to several tools - use them when appropriate.
PROMPT
client.transcript << { system: system_message }
say("Welcome to AI Chat!", :green)
say("Type 'exit' to quit", :yellow)
puts
while (input = ask(set_color("You:", :cyan))) != "exit"
begin
client.transcript << { user: input }
results = client.chat_completion(openai: "gpt-4o", loop: true)
results = Array.wrap(results).flatten
puts
say("AI:", :magenta)
results.each do |result|
wrapped_text = result.to_s.gsub(/\[.*?\]/, "")
.gsub(/\n+/, "\n")
.strip
say(wrapped_text)
puts
end
rescue => e
say("Error: Failed to get AI response", :red)
say("(#{e.message})", :red)
end
end
say("Goodbye! Thanks for chatting.", [:green, :bold])
end
end
end
module AIChat
class Client
include Raix::ChatCompletion
include Raix::FunctionDispatch
# Tools
include Tools::Weather
include Tools::Web
attr_reader :user_interaction
def initialize(user_interaction: nil)
@user_interaction = user_interaction
super()
end
end
end
module Tools
module Weather
extend ActiveSupport::Concern
included do
function :check_weather, "Check the weather for a location", location: { type: "string" } do |arguments|
response = if !user_interaction
"I cannot check the weather without your permission to use the weather API."
else
permission = user_interaction.call(
"Would you like to allow access to the weather API to check the weather in #{arguments[:location]}? (y/n)",
type: :prompt
)
if permission
# Here you would make the actual weather API call
"The weather in #{arguments[:location]} is hot and sunny"
else
user_interaction.call("Weather API access denied. Cannot proceed.", type: :info)
"I cannot check the weather without permission to use the weather API."
end
end
{ response: response }
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment