nano-bots 0.0.4 → 0.0.5

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: 19a8bc3b2ea8dcd2703a22efb3ac334485536b602e385c3d5cd69cdb6e1bfa1b
4
- data.tar.gz: 76375f04692caacd92d832f843acaf3fb82cf68e0e467674749730a04e30794a
3
+ metadata.gz: 1ef7d964a5303c4cf07054210b720b5e57eede718ce549cb697331911577e884
4
+ data.tar.gz: bcfad5aec3b82903fc144d58d37640458bb97e957bddd5deabf46bc890d3a1e7
5
5
  SHA512:
6
- metadata.gz: 9ddbdc1421ce91117a2d16d94794f6111d2ea72503c24ed0f3597c7522a851e7fd7eef08703c5ba8f68826e51e9b34621591232e2d9a5220efda5d026027d413
7
- data.tar.gz: b2a729b278245a971a815c2333cd7676d795a64cdd86aef0d737ad9510c9a78bc8420eaaef9067f305201afbbccaf63e40508832d4cfad7cbf19b91fefc3aa07
6
+ metadata.gz: 816c65f1d09e912d76dfd5e651e9ae17fa9e0bb4fcbfd0932ef6498922c2c4d20422c329dfd239af90ccdd00dc8d1eb03a15ac723f0907e19fbecc79b4fcb2ad
7
+ data.tar.gz: b3254fb89ddfc4d69139130388150e986b2f750a3f56e6a068d211bff6db7413ed47b536dcbc84b04fde1c1679ea5968c7cf63e4ba62d72f07c436d64d21b611
data/Gemfile.lock CHANGED
@@ -1,13 +1,14 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- nano-bots (0.0.4)
4
+ nano-bots (0.0.5)
5
5
  babosa (~> 2.0)
6
6
  dotenv (~> 2.8, >= 2.8.1)
7
7
  faraday (~> 2.7, >= 2.7.4)
8
8
  pry (~> 0.14.2)
9
9
  rainbow (~> 3.1, >= 3.1.1)
10
10
  ruby-openai (~> 4.0)
11
+ sweet-moon (~> 0.0.7)
11
12
 
12
13
  GEM
13
14
  remote: https://rubygems.org/
@@ -23,6 +24,7 @@ GEM
23
24
  faraday-multipart (1.0.4)
24
25
  multipart-post (~> 2)
25
26
  faraday-net_http (3.0.2)
27
+ ffi (1.15.5)
26
28
  json (2.6.3)
27
29
  method_source (1.0.0)
28
30
  multipart-post (2.3.0)
@@ -73,6 +75,8 @@ GEM
73
75
  faraday-multipart (>= 1)
74
76
  ruby-progressbar (1.13.0)
75
77
  ruby2_keywords (0.0.5)
78
+ sweet-moon (0.0.7)
79
+ ffi (~> 1.15, >= 1.15.5)
76
80
  unicode-display_width (2.4.2)
77
81
 
78
82
  PLATFORMS
data/README.md CHANGED
@@ -23,13 +23,13 @@ https://user-images.githubusercontent.com/113217272/238141567-c58a240c-7b67-4b3b
23
23
  For a system usage:
24
24
 
25
25
  ```sh
26
- gem install nano-bots -v 0.0.4
26
+ gem install nano-bots -v 0.0.5
27
27
  ```
28
28
 
29
29
  To use it in a project, add it to your `Gemfile`:
30
30
 
31
31
  ```ruby
32
- gem 'nano-bots', '~> 0.0.4'
32
+ gem 'nano-bots', '~> 0.0.5'
33
33
  ```
34
34
 
35
35
  ```sh
@@ -76,7 +76,7 @@ version: '3.7'
76
76
  services:
77
77
  nano-bots:
78
78
  image: ruby:3.2.2-slim-bullseye
79
- command: sh -c "gem install nano-bots -v 0.0.4 && bash"
79
+ command: sh -c "gem install nano-bots -v 0.0.5 && bash"
80
80
  environment:
81
81
  OPENAI_API_ADDRESS: https://api.openai.com
82
82
  OPENAI_API_ACCESS_TOKEN: your-token
@@ -254,5 +254,5 @@ gem build nano-bots.gemspec
254
254
 
255
255
  gem signin
256
256
 
257
- gem push nano-bots-0.0.4.gem
257
+ gem push nano-bots-0.0.5.gem
258
258
  ```
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'sweet-moon'
4
+
5
+ module NanoBot
6
+ module Components
7
+ class Adapter
8
+ def self.apply(_direction, params)
9
+ content = params[:content]
10
+
11
+ if params[:fennel] && params[:lua]
12
+ raise StandardError, 'Adapter conflict: You can only use either Lua or Fennel, not both.'
13
+ end
14
+
15
+ if params[:fennel]
16
+ content = fennel(content, params[:fennel])
17
+ elsif params[:lua]
18
+ content = lua(content, params[:lua])
19
+ end
20
+
21
+ "#{params[:prefix]}#{content}#{params[:suffix]}"
22
+ end
23
+
24
+ def self.fennel(content, expression)
25
+ path = "#{File.expand_path('../static/fennel', __dir__)}/?.lua"
26
+ state = SweetMoon::State.new(package_path: path).fennel
27
+ state.fennel.eval("(set _G.adapter (fn [content] #{expression}))")
28
+ adapter = state.get(:adapter)
29
+ adapter.call([content])
30
+ end
31
+
32
+ def self.lua(content, expression)
33
+ state = SweetMoon::State.new
34
+ state.eval("adapter = function(content) return #{expression}; end")
35
+ adapter = state.get(:adapter)
36
+ adapter.call([content])
37
+ end
38
+ end
39
+ end
40
+ end
@@ -43,7 +43,7 @@ module NanoBot
43
43
 
44
44
  partial = File.join(File.dirname(partial), File.basename(partial, File.extname(partial)))
45
45
 
46
- partial = path.sub(%r{^\.?/}, '')
46
+ partial = partial.sub(%r{^\.?/}, '')
47
47
 
48
48
  candidates << "#{directory}/#{partial}"
49
49
  candidates << "#{directory}/#{partial}.yml"
@@ -54,7 +54,7 @@ module NanoBot
54
54
 
55
55
  partial = File.join(File.dirname(partial), File.basename(partial, File.extname(partial)))
56
56
 
57
- partial = path.sub(%r{^\.?/}, '')
57
+ partial = partial.sub(%r{^\.?/}, '')
58
58
 
59
59
  candidates << "#{directory}/#{partial}"
60
60
  candidates << "#{directory}/#{partial}.yml"
@@ -55,7 +55,7 @@ module NanoBot
55
55
 
56
56
  def load_cartridge!(path)
57
57
  elected_path = if path.strip == '-'
58
- File.expand_path('../static/cartridges/default.yml', __dir__)
58
+ File.expand_path('../static/cartridges/baseline.yml', __dir__)
59
59
  else
60
60
  Components::Storage.cartridge_path(path)
61
61
  end
@@ -4,34 +4,21 @@ require 'pry'
4
4
  require 'rainbow'
5
5
 
6
6
  require_relative '../../logic/helpers/hash'
7
+ require_relative '../../logic/cartridge/affixes'
7
8
 
8
9
  module NanoBot
9
10
  module Controllers
10
11
  module Interfaces
11
12
  module Eval
12
13
  def self.evaluate(input, cartridge, session)
13
- prefix = build_prefix(cartridge)
14
- postfix = build_postfix(cartridge)
14
+ prefix = Logic::Cartridge::Affixes.get(cartridge, :eval, :output, :prefix)
15
+ suffix = Logic::Cartridge::Affixes.get(cartridge, :eval, :output, :suffix)
15
16
 
16
17
  session.print(prefix) unless prefix.nil?
17
18
 
18
19
  session.evaluate_and_print(input, mode: 'eval')
19
20
 
20
- session.print(postfix) unless postfix.nil?
21
- end
22
-
23
- def self.build_prefix(cartridge)
24
- eval_interface = Logic::Helpers::Hash.fetch(cartridge, %i[interfaces eval])
25
- return nil if eval_interface.nil?
26
-
27
- eval_interface[:prefix]
28
- end
29
-
30
- def self.build_postfix(cartridge)
31
- eval_interface = Logic::Helpers::Hash.fetch(cartridge, %i[interfaces eval])
32
- return "\n" if eval_interface.nil? || !eval_interface.key?(:postfix) # default
33
-
34
- eval_interface[:postfix]
21
+ session.print(suffix) unless suffix.nil?
35
22
  end
36
23
  end
37
24
  end
@@ -4,19 +4,20 @@ require 'pry'
4
4
  require 'rainbow'
5
5
 
6
6
  require_relative '../../logic/helpers/hash'
7
+ require_relative '../../logic/cartridge/affixes'
7
8
 
8
9
  module NanoBot
9
10
  module Controllers
10
11
  module Interfaces
11
12
  module REPL
12
13
  def self.start(cartridge, session)
13
- prefix = build_prefix(cartridge)
14
- postfix = build_postfix(cartridge)
14
+ prefix = Logic::Cartridge::Affixes.get(cartridge, :repl, :output, :prefix)
15
+ suffix = Logic::Cartridge::Affixes.get(cartridge, :repl, :output, :suffix)
15
16
 
16
17
  if Logic::Helpers::Hash.fetch(cartridge, %i[behaviors boot instruction])
17
18
  session.print(prefix) unless prefix.nil?
18
19
  session.boot(mode: 'repl')
19
- session.print(postfix) unless postfix.nil?
20
+ session.print(suffix) unless suffix.nil?
20
21
  session.print("\n")
21
22
  end
22
23
 
@@ -29,9 +30,9 @@ module NanoBot
29
30
  )
30
31
 
31
32
  Pry.commands.block_command(/(.*)/, 'handler') do |line|
32
- session.print(postfix) unless postfix.nil?
33
+ session.print(prefix) unless prefix.nil?
33
34
  session.evaluate_and_print(line, mode: 'repl')
34
- session.print(postfix) unless postfix.nil?
35
+ session.print(suffix) unless suffix.nil?
35
36
  session.print("\n")
36
37
  session.flush
37
38
  end
@@ -39,20 +40,6 @@ module NanoBot
39
40
  Pry.start
40
41
  end
41
42
 
42
- def self.build_prefix(cartridge)
43
- repl = Logic::Helpers::Hash.fetch(cartridge, %i[interfaces repl])
44
- return "\n" if repl.nil? || !repl.key?(:prefix) # default
45
-
46
- repl[:prefix]
47
- end
48
-
49
- def self.build_postfix(cartridge)
50
- repl = Logic::Helpers::Hash.fetch(cartridge, %i[interfaces repl])
51
- return "\n" if repl.nil? || !repl.key?(:postfix) # default
52
-
53
- repl[:postfix]
54
- end
55
-
56
43
  def self.build_prompt(prompt)
57
44
  result = ''
58
45
 
@@ -5,7 +5,10 @@ require 'babosa'
5
5
  require 'fileutils'
6
6
 
7
7
  require_relative '../logic/helpers/hash'
8
+ require_relative '../logic/cartridge/streaming'
9
+ require_relative '../logic/cartridge/interaction'
8
10
  require_relative '../components/storage'
11
+ require_relative '../components/adapter'
9
12
 
10
13
  module NanoBot
11
14
  module Controllers
@@ -56,24 +59,22 @@ module NanoBot
56
59
  def evaluate_and_print(message, mode:)
57
60
  behavior = Logic::Helpers::Hash.fetch(@cartridge, %i[behaviors interaction]) || {}
58
61
 
59
- @state[:history] << ({ who: 'user', message: })
62
+ @state[:history] << {
63
+ who: 'user',
64
+ message: Components::Adapter.apply(
65
+ :input, Logic::Cartridge::Interaction.input(@cartridge, mode.to_sym, message)
66
+ )
67
+ }
60
68
 
61
69
  input = { behavior:, history: @state[:history] }
62
70
 
63
71
  process(input, mode:)
64
72
  end
65
73
 
66
- def streaming(interface)
67
- provider = @provider.settings.key?(:stream) ? @provider.settings[:stream] : true
68
- interface = interface.key?(:stream) ? interface[:stream] : true
69
-
70
- provider && interface
71
- end
72
-
73
74
  def process(input, mode:)
74
75
  interface = Logic::Helpers::Hash.fetch(@cartridge, [:interfaces, mode.to_sym]) || {}
75
76
 
76
- streaming = streaming(interface)
77
+ streaming = Logic::Cartridge::Streaming.enabled?(@cartridge, mode.to_sym)
77
78
 
78
79
  input[:interface] = interface
79
80
 
@@ -82,9 +83,18 @@ module NanoBot
82
83
  ready = false
83
84
  @provider.evaluate(input) do |output, finished|
84
85
  updated_at = Time.now
86
+
85
87
  if finished
86
- @state[:history] << output
88
+ @state[:history] << Marshal.load(Marshal.dump(output))
89
+
90
+ output = Logic::Cartridge::Interaction.output(
91
+ @cartridge, mode.to_sym, output, streaming, finished
92
+ )
93
+
94
+ output[:message] = Components::Adapter.apply(:output, output[:message])
95
+
87
96
  self.print(output[:message]) unless streaming
97
+
88
98
  ready = true
89
99
  flush
90
100
  elsif streaming
@@ -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 "gem install nano-bots -v 0.0.4 && bash"
6
+ command: sh -c "apt-get update && apt-get install -y --no-install-recommends build-essential libffi-dev lua5.4-dev && gem install nano-bots -v 0.0.5 && bash"
7
7
  environment:
8
8
  OPENAI_API_ADDRESS: https://api.openai.com
9
9
  OPENAI_API_ACCESS_TOKEN: your-token
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../helpers/hash'
4
+ require_relative './default'
5
+
6
+ module NanoBot
7
+ module Logic
8
+ module Cartridge
9
+ module Adapter
10
+ def self.expression(cartridge, interface, direction, language)
11
+ adapter = [
12
+ {
13
+ exists: (Helpers::Hash.fetch(cartridge, [:interfaces, direction, :adapter]) || {}).key?(language),
14
+ value: Helpers::Hash.fetch(cartridge, [:interfaces, direction, :adapter, language])
15
+ },
16
+ {
17
+ exists: (Helpers::Hash.fetch(cartridge,
18
+ [:interfaces, interface, direction, :adapter]) || {}).key?(language),
19
+ value: Helpers::Hash.fetch(cartridge, [:interfaces, interface, direction, :adapter, language])
20
+ }
21
+ ].filter { |candidate| candidate[:exists] }.last
22
+
23
+ return nil if adapter.nil?
24
+
25
+ adapter[:value]
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../helpers/hash'
4
+ require_relative './default'
5
+
6
+ module NanoBot
7
+ module Logic
8
+ module Cartridge
9
+ module Affixes
10
+ def self.get(cartridge, interface, direction, kind)
11
+ affix = [
12
+ {
13
+ exists: (Helpers::Hash.fetch(cartridge, [:interfaces, direction]) || {}).key?(kind),
14
+ value: Helpers::Hash.fetch(cartridge, [:interfaces, direction, kind])
15
+ },
16
+ {
17
+ exists: (Helpers::Hash.fetch(cartridge, [:interfaces, interface, direction]) || {}).key?(kind),
18
+ value: Helpers::Hash.fetch(cartridge, [:interfaces, interface, direction, kind])
19
+ }
20
+ ].filter { |candidate| candidate[:exists] }.last
21
+
22
+ if affix.nil?
23
+ return Helpers::Hash.fetch(
24
+ Default.instance.values, [:interfaces, interface, direction, kind]
25
+ )
26
+ end
27
+
28
+ affix[:value]
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yaml'
4
+ require 'singleton'
5
+
6
+ require_relative '../helpers/hash'
7
+
8
+ module NanoBot
9
+ module Logic
10
+ module Cartridge
11
+ class Default
12
+ include Singleton
13
+
14
+ def values
15
+ return @values if @values
16
+
17
+ path = File.expand_path('../../static/cartridges/default.yml', __dir__)
18
+ cartridge = YAML.safe_load(File.read(path), permitted_classes: [Symbol])
19
+ @values = Logic::Helpers::Hash.symbolize_keys(cartridge)
20
+ @values
21
+ end
22
+
23
+ def baseline
24
+ return @baseline if @baseline
25
+
26
+ path = File.expand_path('../../static/cartridges/baseline.yml', __dir__)
27
+ cartridge = YAML.safe_load(File.read(path), permitted_classes: [Symbol])
28
+ @baseline = Logic::Helpers::Hash.symbolize_keys(cartridge)
29
+ @baseline
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'sweet-moon'
4
+
5
+ require_relative './affixes'
6
+ require_relative './adapters'
7
+
8
+ module NanoBot
9
+ module Logic
10
+ module Cartridge
11
+ module Interaction
12
+ def self.input(cartridge, interface, content)
13
+ lua = Adapter.expression(cartridge, interface, :input, :lua)
14
+ fennel = Adapter.expression(cartridge, interface, :input, :fennel)
15
+
16
+ prefix = Affixes.get(cartridge, interface, :input, :prefix)
17
+ suffix = Affixes.get(cartridge, interface, :input, :suffix)
18
+
19
+ { content:, prefix:, suffix:, lua:, fennel: }
20
+ end
21
+
22
+ def self.output(cartridge, interface, result, streaming, _finished)
23
+ if streaming
24
+ result[:message] = { content: result[:message], lua: nil, fennel: nil }
25
+ return result
26
+ end
27
+
28
+ lua = Adapter.expression(cartridge, interface, :output, :lua)
29
+ fennel = Adapter.expression(cartridge, interface, :output, :fennel)
30
+
31
+ result[:message] = { content: result[:message], lua:, fennel: }
32
+
33
+ result
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../helpers/hash'
4
+
5
+ module NanoBot
6
+ module Logic
7
+ module Cartridge
8
+ module Streaming
9
+ def self.enabled?(cartridge, interface)
10
+ return false if Helpers::Hash.fetch(cartridge, %i[provider settings stream]) == false
11
+
12
+ specific_interface = Helpers::Hash.fetch(cartridge, [:interfaces, interface, :output, :stream])
13
+
14
+ return specific_interface unless specific_interface.nil?
15
+
16
+ interface = Helpers::Hash.fetch(cartridge, %i[interfaces output stream])
17
+
18
+ return interface unless interface.nil?
19
+
20
+ true
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -23,6 +23,10 @@ module NanoBot
23
23
  return nil unless node
24
24
 
25
25
  path.each do |key|
26
+ unless node.is_a?(::Hash)
27
+ node = nil
28
+ break
29
+ end
26
30
  node = node[key]
27
31
  break if node.nil?
28
32
  end
data/nano-bots.gemspec CHANGED
@@ -37,6 +37,7 @@ Gem::Specification.new do |spec|
37
37
  spec.add_dependency 'pry', '~> 0.14.2'
38
38
  spec.add_dependency 'rainbow', '~> 3.1', '>= 3.1.1'
39
39
  spec.add_dependency 'ruby-openai', '~> 4.0'
40
+ spec.add_dependency 'sweet-moon', '~> 0.0.7'
40
41
 
41
42
  spec.metadata['rubygems_mfa_required'] = 'true'
42
43
  end
@@ -0,0 +1,14 @@
1
+ ---
2
+ meta:
3
+ name: Unknown
4
+ author: Nobody
5
+ version: 0.0.0
6
+
7
+ provider:
8
+ name: openai
9
+ settings:
10
+ model: gpt-3.5-turbo
11
+ credentials:
12
+ address: ENV/OPENAI_API_ADDRESS
13
+ access-token: ENV/OPENAI_API_ACCESS_TOKEN
14
+ user-identifier: ENV/OPENAI_API_USER_IDENTIFIER
@@ -1,14 +1,19 @@
1
1
  ---
2
- meta:
3
- name: Unknown
4
- author: Nobody
5
- version: 0.0.0
2
+ interfaces:
3
+ repl:
4
+ output:
5
+ stream: true
6
+ suffix: "\n"
7
+ prefix: "\n"
8
+ prompt:
9
+ - text: '🤖'
10
+ - text: '> '
11
+ color: blue
12
+ eval:
13
+ output:
14
+ stream: true
15
+ suffix: "\n"
6
16
 
7
17
  provider:
8
- name: openai
9
18
  settings:
10
- model: gpt-3.5-turbo
11
- credentials:
12
- address: ENV/OPENAI_API_ADDRESS
13
- access-token: ENV/OPENAI_API_ACCESS_TOKEN
14
- user-identifier: ENV/OPENAI_API_USER_IDENTIFIER
19
+ stream: true