Skip to content

Commit

Permalink
remove sk
Browse files Browse the repository at this point in the history
  • Loading branch information
obie committed Nov 11, 2024
1 parent 74ec2ff commit f401db0
Show file tree
Hide file tree
Showing 4 changed files with 202 additions and 40 deletions.
34 changes: 23 additions & 11 deletions lib/raix/chat_completion.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,22 @@ module Raix
# with the OpenRouter Chat Completion API via its client. The module includes a few
# methods that allow you to build a transcript of messages and then send them to
# the API for completion. The API will return a response that you can use however
# you see fit. If the response includes a function call, the module will dispatch
# the function call and return the result. Which implies that function calls need
# to be defined on the class that includes this module. (Note: You should probably
# use the `FunctionDispatch` module to define functions instead of doing it manually.)
# you see fit.
#
# If the response includes a function call, the module will dispatch the function
# call and return the result. Which implies that function calls need to be defined
# on the class that includes this module. The `FunctionDispatch` module provides a
# Rails-like DSL for declaring and implementing tool functions at the top of your
# class instead of having to manually implement them as instance methods. The
# primary benefit of using the `FunctionDispatch` module is that it handles
# adding the function call results to the ongoing conversation transcript for you.
# It also triggers a new chat completion automatically if you've set the `loop`
# option to `true`, which is useful for implementing conversational chatbots that
# include tool calls.
#
# Note that some AI models can make more than a single tool function call in a
# single response. When that happens, the module will dispatch all of the function
# calls sequentially and return an array of results.
module ChatCompletion
extend ActiveSupport::Concern

Expand Down Expand Up @@ -92,13 +104,13 @@ def chat_completion(params: {}, loop: false, json: false, raw: false, openai: fa
# TODO: add a standardized callback hook for usage events
# broadcast(:usage_event, usage_subject, self.class.name.to_s, response, premium?)

# TODO: handle parallel tool calls
if (function = response.dig("choices", 0, "message", "tool_calls", 0, "function"))
@current_function = function["name"]
# dispatch the called function
arguments = JSON.parse(function["arguments"].presence || "{}")
arguments[:bot_message] = bot_message if respond_to?(:bot_message)
return send(function["name"], arguments.with_indifferent_access)
tool_calls = response.dig("choices", 0, "message", "tool_calls") || []
if tool_calls.any?
return tool_calls.map do |tool_call|
# dispatch the called function
arguments = JSON.parse(tool_call["function"]["arguments"].presence || "{}")
send(tool_call["function"]["name"], arguments.with_indifferent_access)
end
end

response.tap do |res|
Expand Down
28 changes: 24 additions & 4 deletions spec/raix/function_dispatch_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,31 @@ def initialize
end
end

RSpec.describe WhatIsTheWeather, :vcr do
subject { described_class.new }
class MultipleToolCalls
include Raix::ChatCompletion
include Raix::FunctionDispatch

function :call_this_function_twice do |arguments|
@callback.call(arguments)
end

def initialize(callback)
@callback = callback
end
end

RSpec.describe Raix::FunctionDispatch, :vcr do
let(:callback) { double("callback") }

it "can call a function and loop to provide text response" do
response = subject.chat_completion(openai: "gpt-4o", loop: true)
expect(response).to include("hot and sunny")
response = WhatIsTheWeather.new.chat_completion(openai: "gpt-4o", loop: true)
expect(response.first).to include("hot and sunny")
end

it "supports multiple tool calls in a single response" do
subject = MultipleToolCalls.new(callback)
subject.transcript << { user: "For testing purposes, call the provided tool function twice in a single response." }
expect(callback).to receive(:call).twice
subject.chat_completion(openai: "gpt-4o")
end
end

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit f401db0

Please sign in to comment.