func_bot 0.1.2 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e2642f560765801d53e14efe88c613738759eb83c5ea65bac70696987eb38783
4
- data.tar.gz: fc5683415acbaed9f68013aad668dbb180d1059b1496c514bcbcd05d5be6044c
3
+ metadata.gz: b6f1906f61868b8d3ceaad0d239f927d3b962d36ffc811c474f49171e53b2925
4
+ data.tar.gz: 06e384d423073541824b800a279554058b825d62d39fbaa41f26db905991569f
5
5
  SHA512:
6
- metadata.gz: a17a9594c4a6ec3cdfbf31db3531afb2074e314fd092851c76d73fa41f221a3e03c35a183ef2a7a86618e15bbd20cd9ff7d642e5efb5dbb9c55e48495eef1165
7
- data.tar.gz: 615b2b10f8c235b67dd7489ea3624a83c3b53a9b0eb57843d816d66dc1672a4c6692cfd615dd7c2238e3c62c5521093dfd32b8186c358fb595b7eedaca201499
6
+ metadata.gz: ea4c9ab74ea6cdbaff2b76e51ae2bd700136b7a1197a1538c3fd4822c63447c40a72d18366a7ace0e33845be2c085bc883c12ec083f0c46ab7265b5f7bc890c6
7
+ data.tar.gz: 823923bfc4fca76b567f29de390d6580ada38ac2171f4600fb04bededfde893978ba9331d3e3761e100a99cc52836f70cfff271ba10b4d3e8db4ba8991e9a11c
data/README.md CHANGED
@@ -2,57 +2,6 @@
2
2
 
3
3
  FuncBot is a Rails gem built on top of the [ruby-openai](https://github.com/alexrudall/ruby-openai) gem. It allows you to easily create chatbots that can answer questions by calling on functions you define. It's goal is to provide a simple interface to consume [OpenAI's Function Calling API](https://openai.com/blog/function-calling-and-other-api-updates?ref=upstract.com).
4
4
 
5
- ## Usage
6
-
7
- - Generate a new function
8
-
9
- ```bash
10
- rails g func_bot:function <function_name>
11
- ```
12
-
13
- - Update the function in `app/lib/func_bot/functions/<function_name>.rb`
14
-
15
- - A function can be as simple or as complex as you need it to be. Your bot will process the results and express them to the user.
16
- - All functions must have an `execute` method.
17
- - Here's a sample function that returns the current weather for the given location.
18
-
19
- ```ruby
20
- module FuncBot
21
- module Functions
22
- class WeatherFunction < BaseFunction
23
- def execute
24
- weather_info = {
25
- location: parsed_response["location"],
26
- temperature: 98,
27
- forecast: ["sunny", "windy"]
28
- }
29
-
30
- JSON.dump(weather_info)
31
- end
32
- end
33
- end
34
- end
35
- ```
36
-
37
- - The `parsed_response` and `response` methods are available to all functions.
38
- - `parsed_response` is a hash that contains the response relevant to your function from OpenAI.
39
- - `response` is the raw response from OpenAI.
40
-
41
- - Update your new function in the list of functions in `app/lib/func_bot/functions/list.yml`.
42
- - This list of functions will be available to the bot with every request.
43
- - Adding good descriptions to the functions will help the bot infer when to use which function.
44
- - If the user asks a question that is not related to a function in your list, the bot will just ask ChatGPT.
45
-
46
- `bin/rails c`
47
-
48
- ```ruby
49
- irb(main):001:0> bot = FuncBot::Bot.new
50
- => #<FuncBot::Bot:0x0000000105ecd8e8 @history=#<FuncBot::Bots::History:0x0000000105ecd848 @history=[]>>
51
- irb(main):002:0> bot.ask "What's the weather like in Miami, FL?"
52
- => "The current weather in Miami, FL is sunny and windy with a temperature of 98 degrees."
53
- irb(main):003:0>
54
- ```
55
-
56
5
  ## Installation
57
6
 
58
7
  Add this line to your application's Gemfile:
@@ -87,6 +36,62 @@ openai:
87
36
  api_key: your-private-key
88
37
  ```
89
38
 
39
+ ## Usage
40
+
41
+ - Generate a new function
42
+
43
+ ```bash
44
+ rails g func_bot:function <function_name>
45
+ ```
46
+
47
+ - Update your new function in the list of functions in `app/lib/func_bot/functions/list.yml`.
48
+ - This list of functions will be available to the bot with every request.
49
+ - Adding good descriptions to the functions will help the bot infer when to use which function.
50
+ - If the user asks a question that is not related to a function in your list, the bot will just ask ChatGPT.
51
+ - A function can be as simple or as complex as you need it to be. Your bot will process the results and express them to the user.
52
+ - All functions must have an `execute` method.
53
+ - Here's a sample function that returns the current weather for the given location.
54
+
55
+ ```ruby
56
+ module FuncBot
57
+ module Functions
58
+ class WeatherFunction < BaseFunction
59
+ def execute
60
+ weather_info = {
61
+ location: parsed_response["location"],
62
+ temperature: 98,
63
+ forecast: ["sunny", "windy"]
64
+ }
65
+
66
+ JSON.dump(weather_info)
67
+ end
68
+ end
69
+ end
70
+ end
71
+ ```
72
+
73
+ - The `parsed_response` and `response` methods are available to all functions.
74
+ - `parsed_response` is a hash that contains the response relevant to your function from OpenAI.
75
+ - `response` is the raw response from OpenAI.
76
+ - Functions also have access to the `bot` attribute which returns the instance of the bot that called the function.
77
+
78
+ - This is useful if you need to access the bot's history or other methods.
79
+ - There might be times when you need to ask gpt a question from within a function, but you don't want to trigger the functions again. You can set the `bot.include_functions` attribute to false before asking the question and then set it back to true after.
80
+
81
+ `bin/rails c`
82
+
83
+ ```ruby
84
+ irb(main):001:0> bot = FuncBot::Bot.new
85
+ => #<FuncBot::Bot:0x0000000105ecd8e8 @history=#<FuncBot::Bots::History:0x0000000105ecd848 @history=[]>>
86
+ irb(main):002:0> bot.ask "What's the weather like in Miami, FL?"
87
+ => "The current weather in Miami, FL is sunny and windy with a temperature of 98 degrees."
88
+ irb(main):003:0>
89
+ irb(main):006:0> bot.include_functions = false
90
+ => false
91
+ irb(main):007:0> bot.ask "What's the weather like in Miami, FL today?"
92
+ => "I'm sorry, I cannot provide real-time information as my responses are generated based on pre-existing data. Please check a reliable weather source for the most up-to-date information on the weather in Miami, FL."
93
+ ```
94
+
90
95
  ## Testing
91
96
 
92
97
  ```bash
@@ -11,17 +11,26 @@ module FuncBot
11
11
 
12
12
  def call
13
13
  open_ai.chat(
14
- parameters: {
15
- model: "gpt-3.5-turbo-0613",
16
- messages: bot.history.payload,
17
- temperature: 0.7,
18
- functions: FuncBot::Functions::List.call(bot)
19
- }
14
+ parameters: chat_params
20
15
  )
21
16
  end
22
17
 
23
18
  private
24
19
 
20
+ def chat_params
21
+ params = {
22
+ model: "gpt-3.5-turbo-0613",
23
+ messages: bot.history.payload,
24
+ temperature: 0.7
25
+ }
26
+ params.merge!(function_params) if bot.include_functions
27
+ params
28
+ end
29
+
30
+ def function_params
31
+ {functions: FuncBot::Functions::List.call}
32
+ end
33
+
25
34
  def open_ai
26
35
  @client ||= OpenAI::Client.new
27
36
  end
@@ -3,15 +3,11 @@
3
3
  module FuncBot
4
4
  module Functions
5
5
  class List
6
- def self.call(bot)
7
- if bot.include_functions
8
- if File.exist?(Rails.root.join("app", "lib", "func_bot", "functions", "list.yml"))
9
- YAML.load_file(Rails.root.join("app", "lib", "func_bot", "functions", "list.yml"))["functions"]
10
- else
11
- raise "app/lib/func_bot/functions/list.yml file not found. Please create it by running rails func_bot:install."
12
- end
6
+ def self.call
7
+ if File.exist?(Rails.root.join("app", "lib", "func_bot", "functions", "list.yml"))
8
+ YAML.load_file(Rails.root.join("app", "lib", "func_bot", "functions", "list.yml"))["functions"]
13
9
  else
14
- []
10
+ raise "app/lib/func_bot/functions/list.yml file not found. Please create it by running rails func_bot:install."
15
11
  end
16
12
  end
17
13
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FuncBot
4
- VERSION = "0.1.2"
4
+ VERSION = "0.1.4"
5
5
  end
@@ -4,6 +4,7 @@ module FuncBot
4
4
 
5
5
  def generate_function
6
6
  template "function.rb", "app/lib/func_bot/functions/#{file_name}_function.rb"
7
+ template "function_spec.rb", "spec/models/func_bot/functions/#{file_name}_function_spec.rb" if defined?(RSpec)
7
8
  end
8
9
 
9
10
  def append_to_functions_list
@@ -2,9 +2,8 @@ module FuncBot
2
2
  module Functions
3
3
  class <%= class_name %>Function < BaseFunction
4
4
  def execute
5
- # Add your function logic here.
6
- # eg. data = {some: "data"}
7
- # JSON.dump(data)
5
+ data = {key: "value"}
6
+ JSON.dump(data)
8
7
  end
9
8
  end
10
9
  end
@@ -0,0 +1,31 @@
1
+ require "rails_helper"
2
+
3
+ RSpec.describe FuncBot::Functions::<%= class_name %>Function do
4
+ let(:bot) { FuncBot::Bot.new }
5
+ let(:function_response) { described_class.new(bot).execute }
6
+ let(:function_arguments) do
7
+ {
8
+ "choices" => [
9
+ {
10
+ "message" => {
11
+ "function_call" => {
12
+ "arguments" => JSON.dump({key: "value"})
13
+ }
14
+ }
15
+ }
16
+ ]
17
+ }
18
+ end
19
+
20
+ before do
21
+ bot.response = function_arguments
22
+ end
23
+
24
+ describe "#execute" do
25
+ describe "FuncBot::Functions::<%= class_name %>Function" do
26
+ it "returns the expected data" do
27
+ expect(JSON.parse(function_response)["key"]).to eq("value")
28
+ end
29
+ end
30
+ end
31
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: func_bot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - lbp
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-06-20 00:00:00.000000000 Z
11
+ date: 2023-06-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -227,6 +227,7 @@ files:
227
227
  - lib/generators/func_bot/function_generator.rb
228
228
  - lib/generators/func_bot/install_generator.rb
229
229
  - lib/generators/func_bot/templates/function.rb.tt
230
+ - lib/generators/func_bot/templates/function_spec.rb.tt
230
231
  - lib/generators/func_bot/templates/list.yml
231
232
  - lib/generators/func_bot/templates/openai.rb
232
233
  - lib/generators/func_bot/templates/weather_function.rb