nano-bots 0.1.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -6,9 +6,9 @@ require_relative '../logic/helpers/hash'
6
6
  require_relative '../components/provider'
7
7
  require_relative '../components/storage'
8
8
  require_relative '../components/stream'
9
- require_relative './interfaces/repl'
10
- require_relative './interfaces/eval'
11
- require_relative './session'
9
+ require_relative 'interfaces/repl'
10
+ require_relative 'interfaces/eval'
11
+ require_relative 'session'
12
12
 
13
13
  module NanoBot
14
14
  module Controllers
@@ -83,7 +83,7 @@ module NanoBot
83
83
  raise StandardError, "Cartridge file not found: \"#{path}\""
84
84
  end
85
85
 
86
- @cartridge = YAML.safe_load(File.read(elected_path), permitted_classes: [Symbol])
86
+ @cartridge = YAML.safe_load_file(elected_path, permitted_classes: [Symbol])
87
87
  end
88
88
 
89
89
  @safe_cartridge = Marshal.load(Marshal.dump(@cartridge))
@@ -81,7 +81,7 @@ module NanoBot
81
81
  when 'cartridge'
82
82
  puts YAML.dump(bot.cartridge)
83
83
  else
84
- raise "TODO: [#{params[:command]}]"
84
+ raise "Command not found: [#{params[:command]}]"
85
85
  end
86
86
  end
87
87
  end
@@ -0,0 +1,104 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rainbow'
4
+
5
+ require_relative '../../logic/cartridge/tools'
6
+ require_relative '../../logic/cartridge/safety'
7
+ require_relative '../../components/embedding'
8
+
9
+ module NanoBot
10
+ module Controllers
11
+ module Interfaces
12
+ module Tool
13
+ def self.confirming(session, cartridge, mode, feedback)
14
+ yeses = Logic::Cartridge::Safety.yeses(cartridge)
15
+ default_answer = Logic::Cartridge::Safety.default_answer(cartridge)
16
+ dispatch_feedback(session, cartridge, mode, feedback)
17
+ session.flush
18
+ answer = $stdin.gets.chomp.to_s.downcase.strip
19
+ answer = default_answer if answer == ''
20
+ session.print("\n")
21
+ yeses.include?(answer)
22
+ end
23
+
24
+ def self.adapt(feedback, adapter, cartridge)
25
+ call = {
26
+ parameters: %w[id name parameters parameters-as-json output],
27
+ values: [
28
+ feedback[:id], feedback[:name], feedback[:parameters],
29
+ feedback[:parameters].to_json,
30
+ feedback[:output]
31
+ ],
32
+ safety: { sandboxed: Logic::Cartridge::Safety.sandboxed?(cartridge) }
33
+ }
34
+
35
+ raise StandardError, 'conflicting adapters' if %i[fennel lua clojure].count { |key| !adapter[key].nil? } > 1
36
+
37
+ if adapter[:fennel]
38
+ call[:source] = adapter[:fennel]
39
+ Components::Embedding.fennel(**call)
40
+ elsif adapter[:clojure]
41
+ call[:source] = adapter[:clojure]
42
+ Components::Embedding.clojure(**call)
43
+ elsif adapter[:lua]
44
+ call[:parameters] = %w[id name parameters parameters_as_json output]
45
+ call[:source] = adapter[:lua]
46
+ Components::Embedding.lua(**call)
47
+ else
48
+ raise 'missing handler for adapter'
49
+ end
50
+ end
51
+
52
+ def self.dispatch_feedback(session, cartridge, mode, feedback)
53
+ enabled = Logic::Cartridge::Tools.feedback?(cartridge, mode.to_sym, feedback[:action].to_sym)
54
+
55
+ enabled = true if feedback[:action].to_sym == :confirming
56
+
57
+ return unless enabled
58
+
59
+ color = Logic::Cartridge::Tools.fetch_from_interface(
60
+ cartridge, mode.to_sym, feedback[:action].to_sym, [:color]
61
+ )
62
+
63
+ adapter = Tool.adapter(cartridge, mode, feedback)
64
+
65
+ if %i[fennel lua clojure].any? { |key| !adapter[key].nil? }
66
+ message = adapt(feedback, adapter, cartridge)
67
+ else
68
+ message = "#{feedback[:name]} #{feedback[:parameters].to_json}"
69
+
70
+ message += "\n#{feedback[:output]}" if feedback[:action].to_sym == :responding
71
+ end
72
+
73
+ message = "#{adapter[:prefix]}#{message}#{adapter[:suffix]}"
74
+
75
+ session.print(color.nil? ? message : Rainbow(message).send(color))
76
+ end
77
+
78
+ def self.adapter(cartridge, mode, feedback)
79
+ prefix = Logic::Cartridge::Tools.fetch_from_interface(
80
+ cartridge, mode.to_sym, feedback[:action].to_sym, [:prefix]
81
+ )
82
+
83
+ suffix = Logic::Cartridge::Tools.fetch_from_interface(
84
+ cartridge, mode.to_sym, feedback[:action].to_sym, [:suffix]
85
+ )
86
+
87
+ fennel = Logic::Cartridge::Tools.fetch_from_interface(
88
+ cartridge, mode.to_sym, feedback[:action].to_sym, %i[adapter fennel]
89
+ )
90
+
91
+ lua = Logic::Cartridge::Tools.fetch_from_interface(
92
+ cartridge, mode.to_sym, feedback[:action].to_sym, %i[adapter lua]
93
+ )
94
+
95
+ clojure = Logic::Cartridge::Tools.fetch_from_interface(
96
+ cartridge, mode.to_sym, feedback[:action].to_sym, %i[adapter clojure]
97
+ )
98
+
99
+ { prefix:, suffix:, fennel:, lua:, clojure: }
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
@@ -3,10 +3,14 @@
3
3
  require 'babosa'
4
4
 
5
5
  require 'fileutils'
6
+ require 'rainbow'
6
7
 
7
8
  require_relative '../logic/helpers/hash'
9
+ require_relative '../logic/cartridge/safety'
8
10
  require_relative '../logic/cartridge/streaming'
9
11
  require_relative '../logic/cartridge/interaction'
12
+ require_relative '../logic/cartridge/fetch'
13
+ require_relative 'interfaces/tools'
10
14
  require_relative '../components/storage'
11
15
  require_relative '../components/adapter'
12
16
  require_relative '../components/crypto'
@@ -14,6 +18,7 @@ require_relative '../components/crypto'
14
18
  module NanoBot
15
19
  module Controllers
16
20
  STREAM_TIMEOUT_IN_SECONDS = 5
21
+ INFINITE_LOOP_PREVENTION = 10
17
22
 
18
23
  class Session
19
24
  attr_accessor :stream
@@ -41,9 +46,9 @@ module NanoBot
41
46
  end
42
47
 
43
48
  def load_state
44
- @state = Logic::Helpers::Hash.symbolize_keys(JSON.parse(
45
- Components::Crypto.decrypt(File.read(@state_path))
46
- ))
49
+ @state = Logic::Helpers::Hash.symbolize_keys(
50
+ JSON.parse(Components::Crypto.decrypt(File.read(@state_path)))
51
+ )
47
52
  end
48
53
 
49
54
  def store_state!
@@ -68,7 +73,7 @@ module NanoBot
68
73
  mode: mode.to_s,
69
74
  input: message,
70
75
  message: Components::Adapter.apply(
71
- :input, Logic::Cartridge::Interaction.input(@cartridge, mode.to_sym, message)
76
+ Logic::Cartridge::Interaction.input(@cartridge, mode.to_sym, message), @cartridge
72
77
  )
73
78
  }
74
79
 
@@ -78,41 +83,88 @@ module NanoBot
78
83
  end
79
84
 
80
85
  def process(input, mode:)
86
+ interface = Logic::Helpers::Hash.fetch(@cartridge, [:interfaces, mode.to_sym]) || {}
87
+
88
+ input[:interface] = interface
89
+ input[:tools] = @cartridge[:tools]
90
+
91
+ needs_another_round = true
92
+
93
+ rounds = 0
94
+
95
+ while needs_another_round
96
+ needs_another_round = process_interaction(input, mode:)
97
+ rounds += 1
98
+ raise StandardError, 'infinite loop prevention' if rounds > INFINITE_LOOP_PREVENTION
99
+ end
100
+ end
101
+
102
+ def process_interaction(input, mode:)
81
103
  prefix = Logic::Cartridge::Affixes.get(@cartridge, mode.to_sym, :output, :prefix)
82
104
  suffix = Logic::Cartridge::Affixes.get(@cartridge, mode.to_sym, :output, :suffix)
83
105
 
84
- interface = Logic::Helpers::Hash.fetch(@cartridge, [:interfaces, mode.to_sym]) || {}
106
+ color = Logic::Cartridge::Fetch.cascate(
107
+ @cartridge, [[:interfaces, mode.to_sym, :output, :color], %i[interfaces output color]]
108
+ )
85
109
 
86
- streaming = Logic::Cartridge::Streaming.enabled?(@cartridge, mode.to_sym)
110
+ color = color.to_sym if color
87
111
 
88
- input[:interface] = interface
112
+ streaming = Logic::Cartridge::Streaming.enabled?(@cartridge, mode.to_sym)
89
113
 
90
114
  updated_at = Time.now
91
115
 
92
116
  ready = false
93
- @provider.evaluate(input) do |output, finished|
94
- updated_at = Time.now
95
-
96
- if finished
97
- event = Marshal.load(Marshal.dump(output))
98
117
 
99
- output = Logic::Cartridge::Interaction.output(
100
- @cartridge, mode.to_sym, output, streaming, finished
101
- )
118
+ needs_another_round = false
102
119
 
103
- output[:message] = Components::Adapter.apply(:output, output[:message])
120
+ @provider.evaluate(input, streaming, @cartridge) do |feedback|
121
+ needs_another_round = true if feedback[:needs_another_round]
104
122
 
105
- event[:mode] = mode.to_s
106
- event[:output] = "#{prefix}#{output[:message]}#{suffix}"
107
-
108
- @state[:history] << event
109
-
110
- self.print(output[:message]) unless streaming
123
+ updated_at = Time.now
111
124
 
112
- ready = true
113
- flush
114
- elsif streaming
115
- self.print(output[:message])
125
+ if feedback[:interaction] &&
126
+ feedback.dig(:interaction, :meta, :tool, :action) &&
127
+ feedback[:interaction][:meta][:tool][:action] == 'confirming'
128
+ Interfaces::Tool.confirming(self, @cartridge, mode, feedback[:interaction][:meta][:tool])
129
+ else
130
+
131
+ if feedback[:interaction] && feedback.dig(:interaction, :meta, :tool, :action)
132
+ Interfaces::Tool.dispatch_feedback(
133
+ self, @cartridge, mode, feedback[:interaction][:meta][:tool]
134
+ )
135
+ end
136
+
137
+ if feedback[:interaction]
138
+ event = Marshal.load(Marshal.dump(feedback[:interaction]))
139
+ event[:mode] = mode.to_s
140
+ event[:output] = nil
141
+
142
+ if feedback[:interaction][:who] == 'AI' && feedback[:interaction][:message]
143
+ event[:output] = feedback[:interaction][:message]
144
+ unless streaming
145
+ output = Logic::Cartridge::Interaction.output(
146
+ @cartridge, mode.to_sym, feedback[:interaction], streaming, feedback[:finished]
147
+ )
148
+ output[:message] = Components::Adapter.apply(output[:message], @cartridge)
149
+ event[:output] = (output[:message]).to_s
150
+ end
151
+ end
152
+
153
+ @state[:history] << event if feedback[:should_be_stored]
154
+
155
+ if event[:output] && ((!feedback[:finished] && streaming) || (!streaming && feedback[:finished]))
156
+ self.print(color ? Rainbow(event[:output]).send(color) : event[:output])
157
+ end
158
+
159
+ # The `print` function already outputs a prefix and a suffix, so
160
+ # we should add them afterwards to avoid printing them twice.
161
+ event[:output] = "#{prefix}#{event[:output]}#{suffix}"
162
+ end
163
+
164
+ if feedback[:finished]
165
+ flush
166
+ ready = true
167
+ end
116
168
  end
117
169
  end
118
170
 
@@ -122,6 +174,8 @@ module NanoBot
122
174
  end
123
175
 
124
176
  store_state! unless @stateless
177
+
178
+ needs_another_round
125
179
  end
126
180
 
127
181
  def flush
@@ -3,7 +3,7 @@ version: '3.7'
3
3
  services:
4
4
  nano-bots:
5
5
  image: ruby:3.2.2-slim-bullseye
6
- command: sh -c "apt-get update && apt-get install -y --no-install-recommends build-essential libffi-dev libsodium-dev lua5.4-dev && gem install nano-bots -v 0.1.1 && bash"
6
+ command: sh -c "apt-get update && apt-get install -y --no-install-recommends build-essential libffi-dev libsodium-dev lua5.4-dev && gem install nano-bots -v 1.0.0 && bash"
7
7
  environment:
8
8
  OPENAI_API_ADDRESS: https://api.openai.com
9
9
  OPENAI_API_KEY: your-access-token
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative '../helpers/hash'
4
- require_relative './default'
4
+ require_relative 'default'
5
5
 
6
6
  module NanoBot
7
7
  module Logic
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative '../helpers/hash'
4
- require_relative './default'
4
+ require_relative 'default'
5
5
 
6
6
  module NanoBot
7
7
  module Logic
@@ -15,7 +15,7 @@ module NanoBot
15
15
  return @values if @values
16
16
 
17
17
  path = File.expand_path('../../static/cartridges/default.yml', __dir__)
18
- cartridge = YAML.safe_load(File.read(path), permitted_classes: [Symbol])
18
+ cartridge = YAML.safe_load_file(path, permitted_classes: [Symbol])
19
19
  @values = Logic::Helpers::Hash.symbolize_keys(cartridge)
20
20
  @values
21
21
  end
@@ -24,7 +24,7 @@ module NanoBot
24
24
  return @baseline if @baseline
25
25
 
26
26
  path = File.expand_path('../../static/cartridges/baseline.yml', __dir__)
27
- cartridge = YAML.safe_load(File.read(path), permitted_classes: [Symbol])
27
+ cartridge = YAML.safe_load_file(path, permitted_classes: [Symbol])
28
28
  @baseline = Logic::Helpers::Hash.symbolize_keys(cartridge)
29
29
  @baseline
30
30
  end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'default'
4
+ require_relative '../helpers/hash'
5
+
6
+ module NanoBot
7
+ module Logic
8
+ module Cartridge
9
+ module Fetch
10
+ def self.cascate(cartridge, paths)
11
+ results = paths.map { |path| Helpers::Hash.fetch(cartridge, path) }
12
+ result = results.find { |candidate| !candidate.nil? }
13
+ return result unless result.nil?
14
+
15
+ results = paths.map { |path| Helpers::Hash.fetch(Default.instance.values, path) }
16
+ result = results.find { |candidate| !candidate.nil? }
17
+ return result unless result.nil?
18
+
19
+ nil
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -1,9 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'sweet-moon'
4
-
5
- require_relative './affixes'
6
- require_relative './adapters'
3
+ require_relative 'affixes'
4
+ require_relative 'adapters'
7
5
 
8
6
  module NanoBot
9
7
  module Logic
@@ -12,23 +10,25 @@ module NanoBot
12
10
  def self.input(cartridge, interface, content)
13
11
  lua = Adapter.expression(cartridge, interface, :input, :lua)
14
12
  fennel = Adapter.expression(cartridge, interface, :input, :fennel)
13
+ clojure = Adapter.expression(cartridge, interface, :input, :clojure)
15
14
 
16
15
  prefix = Affixes.get(cartridge, interface, :input, :prefix)
17
16
  suffix = Affixes.get(cartridge, interface, :input, :suffix)
18
17
 
19
- { content:, prefix:, suffix:, lua:, fennel: }
18
+ { content:, prefix:, suffix:, lua:, fennel:, clojure: }
20
19
  end
21
20
 
22
21
  def self.output(cartridge, interface, result, streaming, _finished)
23
22
  if streaming
24
- result[:message] = { content: result[:message], lua: nil, fennel: nil }
23
+ result[:message] = { content: result[:message], lua: nil, fennel: nil, clojure: nil }
25
24
  return result
26
25
  end
27
26
 
28
27
  lua = Adapter.expression(cartridge, interface, :output, :lua)
29
28
  fennel = Adapter.expression(cartridge, interface, :output, :fennel)
29
+ clojure = Adapter.expression(cartridge, interface, :output, :clojure)
30
30
 
31
- result[:message] = { content: result[:message], lua:, fennel: }
31
+ result[:message] = { content: result[:message], lua:, fennel:, clojure: }
32
32
 
33
33
  result
34
34
  end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'fetch'
4
+
5
+ module NanoBot
6
+ module Logic
7
+ module Cartridge
8
+ module Safety
9
+ def self.default_answer(cartridge)
10
+ default = Fetch.cascate(cartridge, [%i[interfaces tools confirming default]])
11
+ return [] if default.nil?
12
+
13
+ default
14
+ end
15
+
16
+ def self.yeses(cartridge)
17
+ yeses_values = Fetch.cascate(cartridge, [%i[interfaces tools confirming yeses]])
18
+ return [] if yeses_values.nil?
19
+
20
+ yeses_values
21
+ end
22
+
23
+ def self.confirmable?(cartridge)
24
+ confirmable = Fetch.cascate(cartridge, [%i[safety tools confirmable]])
25
+ return true if confirmable.nil?
26
+
27
+ confirmable
28
+ end
29
+
30
+ def self.sandboxed?(cartridge)
31
+ sandboxed = Fetch.cascate(cartridge, [%i[safety functions sandboxed]])
32
+ return true if sandboxed.nil?
33
+
34
+ sandboxed
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'fetch'
4
+ require_relative 'affixes'
5
+ require_relative 'adapters'
6
+
7
+ module NanoBot
8
+ module Logic
9
+ module Cartridge
10
+ module Tools
11
+ def self.fetch_from_interface(cartridge, interface, action, path)
12
+ Fetch.cascate(cartridge, [
13
+ [:interfaces, interface, :tools, action].concat(path),
14
+ [:interfaces, :tools, action].concat(path),
15
+ %i[interfaces tools].concat(path)
16
+ ])
17
+ end
18
+
19
+ def self.feedback?(cartridge, interface, action)
20
+ Fetch.cascate(cartridge, [
21
+ [:interfaces, interface, :tools, action, :feedback],
22
+ [:interfaces, :tools, action, :feedback],
23
+ %i[interfaces tools feedback]
24
+ ])
25
+ end
26
+
27
+ def self.input(cartridge, interface, content)
28
+ lua = Adapter.expression(cartridge, interface, :input, :lua)
29
+ fennel = Adapter.expression(cartridge, interface, :input, :fennel)
30
+
31
+ prefix = Affixes.get(cartridge, interface, :input, :prefix)
32
+ suffix = Affixes.get(cartridge, interface, :input, :suffix)
33
+
34
+ { content:, prefix:, suffix:, lua:, fennel: }
35
+ end
36
+
37
+ def self.output(cartridge, interface, result, streaming, _finished)
38
+ if streaming
39
+ result[:message] = { content: result[:message], lua: nil, fennel: nil }
40
+ return result
41
+ end
42
+
43
+ lua = Adapter.expression(cartridge, interface, :output, :lua)
44
+ fennel = Adapter.expression(cartridge, interface, :output, :fennel)
45
+
46
+ result[:message] = { content: result[:message], lua:, fennel: }
47
+
48
+ result
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+
5
+ require_relative '../../helpers/hash'
6
+
7
+ module NanoBot
8
+ module Logic
9
+ module OpenAI
10
+ module Tools
11
+ def self.prepare(cartridge, tools)
12
+ applies = []
13
+
14
+ tools = Marshal.load(Marshal.dump(tools))
15
+
16
+ tools.each do |tool|
17
+ tool = Helpers::Hash.symbolize_keys(tool)
18
+
19
+ cartridge.each do |candidate|
20
+ next unless tool[:function][:name] == candidate[:name]
21
+
22
+ source = {}
23
+
24
+ source[:clojure] = candidate[:clojure] if candidate[:clojure]
25
+ source[:fennel] = candidate[:fennel] if candidate[:fennel]
26
+ source[:lua] = candidate[:lua] if candidate[:lua]
27
+
28
+ applies << {
29
+ id: tool[:id],
30
+ name: tool[:function][:name],
31
+ type: 'function',
32
+ parameters: JSON.parse(tool[:function][:arguments]),
33
+ source:
34
+ }
35
+ end
36
+ end
37
+
38
+ raise 'missing tool' if applies.size != tools.size
39
+
40
+ applies
41
+ end
42
+
43
+ def self.adapt(cartridge)
44
+ output = {
45
+ type: 'function',
46
+ function: {
47
+ name: cartridge[:name], description: cartridge[:description]
48
+ }
49
+ }
50
+
51
+ output[:function][:parameters] = (cartridge[:parameters] || { type: 'object', properties: {} })
52
+
53
+ output
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+
5
+ module NanoBot
6
+ module Logic
7
+ module OpenAI
8
+ def self.prepare_tools(cartridge, tools)
9
+ applies = []
10
+ tools.each do |tool|
11
+ cartridge.each do |candidate|
12
+ next unless candidate[:type] == 'function' &&
13
+ tool[:type] == candidate[:type] &&
14
+ tool[:function][:name] == candidate[:name]
15
+
16
+ source = {}
17
+
18
+ source[:fennel] = candidate[:fennel] if candidate[:fennel]
19
+ source[:lua] = candidate[:lua] if candidate[:lua]
20
+
21
+ applies << {
22
+ name: tool[:function][:name],
23
+ type: candidate[:type],
24
+ parameters: JSON.parse(tool[:function][:arguments]),
25
+ source:
26
+ }
27
+ end
28
+ end
29
+
30
+ applies
31
+ end
32
+
33
+ def self.adapt_tool(cartridge)
34
+ raise 'unsupported tool' if cartridge[:type] != 'function'
35
+
36
+ adapted = {
37
+ type: 'function',
38
+ function: {
39
+ name: cartridge[:name], description: cartridge[:description],
40
+ parameters: { type: 'object', properties: {} }
41
+ }
42
+ }
43
+
44
+ properties = adapted[:function][:parameters][:properties]
45
+
46
+ cartridge[:parameters].each do |parameter|
47
+ key = parameter[:name].to_sym
48
+ properties[key] = {}
49
+ properties[key][:type] = parameter[:type] || 'string'
50
+ properties[key][:description] = parameter[:description] if parameter[:description]
51
+ end
52
+
53
+ adapted
54
+ end
55
+ end
56
+ end
57
+ end
data/nano-bots.gemspec CHANGED
@@ -32,12 +32,13 @@ Gem::Specification.new do |spec|
32
32
  spec.executables = ['nb']
33
33
 
34
34
  spec.add_dependency 'babosa', '~> 2.0'
35
+ spec.add_dependency 'concurrent-ruby', '~> 1.2', '>= 1.2.2'
35
36
  spec.add_dependency 'dotenv', '~> 2.8', '>= 2.8.1'
36
- spec.add_dependency 'faraday', '~> 2.7', '>= 2.7.5'
37
+ spec.add_dependency 'faraday', '~> 2.7', '>= 2.7.12'
37
38
  spec.add_dependency 'pry', '~> 0.14.2'
38
39
  spec.add_dependency 'rainbow', '~> 3.1', '>= 3.1.1'
39
40
  spec.add_dependency 'rbnacl', '~> 7.1', '>= 7.1.1'
40
- spec.add_dependency 'ruby-openai', '~> 4.0'
41
+ spec.add_dependency 'ruby-openai', '~> 6.3'
41
42
  spec.add_dependency 'sweet-moon', '~> 0.0.7'
42
43
 
43
44
  spec.metadata['rubygems_mfa_required'] = 'true'
@@ -14,4 +14,4 @@ provider:
14
14
  access-token: ENV/OPENAI_API_KEY
15
15
  settings:
16
16
  user: ENV/NANO_BOTS_END_USER
17
- model: gpt-3.5-turbo
17
+ model: gpt-3.5-turbo-1106
@@ -1,4 +1,10 @@
1
1
  ---
2
+ safety:
3
+ functions:
4
+ sandboxed: true
5
+ tools:
6
+ confirmable: true
7
+
2
8
  interfaces:
3
9
  repl:
4
10
  output:
@@ -12,6 +18,16 @@ interfaces:
12
18
  output:
13
19
  stream: true
14
20
  suffix: "\n"
21
+ tools:
22
+ confirming:
23
+ suffix: ' [yN] '
24
+ default: 'n'
25
+ yeses: ['y', 'yes']
26
+ executing:
27
+ feedback: false
28
+ responding:
29
+ suffix: "\n\n"
30
+ feedback: true
15
31
 
16
32
  provider:
17
33
  settings: