func_bot 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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