nano-bots 0.0.1 → 0.0.2

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: eb32dfa429c178b7af6c3f9a4c8046846ab9ae894c94bbf2038644ceef9c2368
4
- data.tar.gz: 21e37c25c085c27f0f0357f8bb878cba2a366641f9d4649dc25536bcd51afc28
3
+ metadata.gz: 158748eddde7df19233111d423ade5a4ce8d5eccc0e846fefa3c83aa02bdb1f0
4
+ data.tar.gz: 57451266dd04a90fd0df74f49886ad940d58543dc3d0225ceeb548c08bdc93e8
5
5
  SHA512:
6
- metadata.gz: 0a4a1f1a7f33eb6da088b8418cd0d4da61d8e6890ee8b6a0276330217164966b7266c032eabf3e3454e7879bd5e525b47cc99eff40259b7a1a9f9cf86a72db4f
7
- data.tar.gz: 2098e8e5da98da2499ea4267e70be61ba9a06feb5c3fb6375d8ff05dbd01ae72134d34e5205884af80f3c4029c32dc09fec3c91b744ee6f61b05db8a5309b8ec
6
+ metadata.gz: 3e73d11ccd1d49abfb54779069a4a6a802ad21041ce09832221840353a799f358141db46f54e5eccd0416ea3f5ccda7c65c657022a3e6dd0e41ba1fcab91a429
7
+ data.tar.gz: ec1bf4b5d26f57a95f931f23e98db0288af2883cb27d7bc1447ac4c65ab1052d7a4e9779b947c522e3f4c6a91ae1ca9f2f9a7c6c5ec8c0001c6019d2efa848ad
data/.gitignore CHANGED
@@ -1,2 +1,3 @@
1
1
  .env
2
2
  *.gem
3
+ docker-compose.yml
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- nano-bots (0.0.1)
4
+ nano-bots (0.0.2)
5
5
  babosa (~> 2.0)
6
6
  dotenv (~> 2.8, >= 2.8.1)
7
7
  faraday (~> 2.7, >= 2.7.4)
data/README.md CHANGED
@@ -8,6 +8,7 @@ _Image artificially created by Midjourney through a prompt generated by a Nano B
8
8
  https://user-images.githubusercontent.com/113217272/237840989-1e29a5cc-6644-48d0-87b4-62798dc6ebd3.mp4
9
9
 
10
10
  - [Setup](#setup)
11
+ - [Docker](#docker)
11
12
  - [Usage](#usage)
12
13
  - [Command Line](#command-line)
13
14
  - [Library](#library)
@@ -20,13 +21,13 @@ https://user-images.githubusercontent.com/113217272/237840989-1e29a5cc-6644-48d0
20
21
  For a system usage:
21
22
 
22
23
  ```sh
23
- gem install nano-bots -v 0.0.1
24
+ gem install nano-bots -v 0.0.2
24
25
  ```
25
26
 
26
27
  To use it in a project, add it to your `Gemfile`:
27
28
 
28
29
  ```ruby
29
- gem 'nano-bots', '~> 0.0.1'
30
+ gem 'nano-bots', '~> 0.0.2'
30
31
  ```
31
32
 
32
33
  ```sh
@@ -46,29 +47,66 @@ export NANO_BOTS_CARTRIDGES_DIRECTORY=/home/user/.local/share/nano-bots/cartridg
46
47
 
47
48
  Alternatively, if your current directory has a `.env` file with the environment variables, they will be automatically loaded.
48
49
 
50
+ ## Docker
51
+
52
+ Clone the repository and copy the Docker Compose template:
53
+
54
+ ```
55
+ git clone git@github.com:icebaker/ruby-nano-bots.git
56
+ cd ruby-nano-bots
57
+ cp docker-compose.example.yml docker-compose.yml
58
+ ```
59
+
60
+ Set your provider credentials and choose your desired directory for the cartridges files:
61
+
62
+ ```yaml
63
+ version: '3.7'
64
+
65
+ services:
66
+ nano-bots:
67
+ image: ruby:3.2.2-slim-bullseye
68
+ command: sh -c "gem install nano-bots -v 0.0.2 && bash"
69
+ environment:
70
+ OPENAI_API_ADDRESS: https://api.openai.com
71
+ OPENAI_API_ACCESS_TOKEN: your-token
72
+ OPENAI_API_USER_IDENTIFIER: your-user
73
+ volumes:
74
+ - ./your-cartridges:/cartridges
75
+ ```
76
+
77
+ Enter the container:
78
+ ```sh
79
+ docker compose run nano-bots
80
+ ```
81
+
82
+ Start playing:
83
+ ```sh
84
+ nb cartridges/assistant.yml - repl
85
+ ```
86
+
49
87
  ## Usage
50
88
 
51
89
  ### Command Line
52
90
 
53
- After installing the gem, the `rnb` binary command will be available for your project or system.
91
+ After installing the gem, the `nb` binary command will be available for your project or system.
54
92
 
55
93
  Examples of usage:
56
94
 
57
95
  ```bash
58
- rnb to-en-us-translator.yml - eval "Salut, comment ça va?"
96
+ nb to-en-us-translator.yml - eval "Salut, comment ça va?"
59
97
  # => Hello, how are you doing?
60
98
 
61
- rnb midjourney.yml - eval "happy and friendly cyberpunk robot"
62
- # => The robot exploring a bustling city, surrounded by neon lights
63
- # and high-rise buildings. The prompt should include colorful
64
- # lighting and a sense of excitement in the facial expression.
99
+ nb midjourney.yml - eval "happy cyberpunk robot"
100
+ # => A cheerful and fun-loving robot is dancing wildly amidst a
101
+ # futuristic and lively cityscape. Holographic advertisements
102
+ # and vibrant neon colors can be seen in the background.
65
103
 
66
- rnb lisp.yml - eval "(+ 1 2)"
104
+ nb lisp.yml - eval "(+ 1 2)"
67
105
  # => 3
68
106
 
69
107
  cat article.txt |
70
- rnb to-en-us-translator.yml - eval |
71
- rnb summarizer.yml - eval
108
+ nb to-en-us-translator.yml - eval |
109
+ nb summarizer.yml - eval
72
110
  # -> LLM stands for Large Language Model, which refers to an
73
111
  # artificial intelligence algorithm capable of processing
74
112
  # and understanding vast amounts of natural language data,
@@ -77,23 +115,34 @@ cat article.txt |
77
115
  ```
78
116
 
79
117
  ```bash
80
- rnb assistant.yml - repl
118
+ nb assistant.yml - repl
81
119
  ```
82
120
 
83
- All of the commands above are stateless. If you want to preserve the history of your interactions, replace the `-` with a state key. You can use a simple key, such as your username, or a randomly generated one:
121
+ ```text
122
+ 🤖> Hi, how are you doing?
84
123
 
85
- ```ruby
86
- require 'securerandom'
124
+ As an AI language model, I do not experience emotions but I am functioning
125
+ well. How can I assist you?
87
126
 
88
- SecureRandom.hex # => 6ea6c43c42a1c076b1e3c36fa349ac2c
127
+ 🤖> |
89
128
  ```
90
129
 
130
+ All of the commands above are stateless. If you want to preserve the history of your interactions, replace the `-` with a state key:
131
+
91
132
  ```bash
92
- rnb assistant.yml your-user eval "Salut, comment ça va?"
93
- rnb assistant.yml your-user repl
133
+ nb assistant.yml your-user eval "Salut, comment ça va?"
134
+ nb assistant.yml your-user repl
94
135
 
95
- rnb assistant.yml 6ea6c43c42a1c076b1e3c36fa349ac2c eval "Salut, comment ça va?"
96
- rnb assistant.yml 6ea6c43c42a1c076b1e3c36fa349ac2c repl
136
+ nb assistant.yml 6ea6c43c42a1c076b1e3c36fa349ac2c eval "Salut, comment ça va?"
137
+ nb assistant.yml 6ea6c43c42a1c076b1e3c36fa349ac2c repl
138
+ ```
139
+
140
+ You can use a simple key, such as your username, or a randomly generated one:
141
+
142
+ ```ruby
143
+ require 'securerandom'
144
+
145
+ SecureRandom.hex # => 6ea6c43c42a1c076b1e3c36fa349ac2c
97
146
  ```
98
147
 
99
148
  ### Library
@@ -101,13 +150,13 @@ rnb assistant.yml 6ea6c43c42a1c076b1e3c36fa349ac2c repl
101
150
  To use it as a library:
102
151
 
103
152
  ```ruby
104
- require 'nano-bots/cli' # Equivalent to the `rnb` command.
153
+ require 'nano-bots/cli' # Equivalent to the `nb` command.
105
154
  ```
106
155
 
107
156
  ```ruby
108
157
  require 'nano-bots'
109
158
 
110
- NanoBot.cli # Equivalent to the `rnb` command.
159
+ NanoBot.cli # Equivalent to the `nb` command.
111
160
 
112
161
  NanoBot.repl(cartridge: 'cartridge.yml') # Starts a new REPL.
113
162
 
@@ -128,20 +177,15 @@ Here's what a Nano Bot Cartridge looks like:
128
177
 
129
178
  ```yaml
130
179
  ---
131
- name: Assistant
132
- version: 0.0.1
180
+ meta:
181
+ name: Nano Bot Name
182
+ author: Your Name
183
+ version: 0.0.1
133
184
 
134
185
  behaviors:
135
186
  interaction:
136
187
  directive: You are a helpful assistant.
137
188
 
138
- interfaces:
139
- repl:
140
- prompt:
141
- - text: '🤖'
142
- - text: '> '
143
- color: blue
144
-
145
189
  provider:
146
190
  name: openai
147
191
  settings:
@@ -169,5 +213,5 @@ gem build nano-bots.gemspec
169
213
 
170
214
  gem signin
171
215
 
172
- gem push nano-bots-0.0.1.gem
216
+ gem push nano-bots-0.0.2.gem
173
217
  ```
@@ -24,6 +24,13 @@ module NanoBot
24
24
  )
25
25
  end
26
26
 
27
+ def stream(input)
28
+ provider = @settings.key?(:stream) ? @settings[:stream] : true
29
+ interface = input[:interface].key?(:stream) ? input[:interface][:stream] : true
30
+
31
+ provider && interface
32
+ end
33
+
27
34
  def evaluate(input, &block)
28
35
  messages = input[:history].map do |event|
29
36
  { role: event[:who] == 'user' ? 'user' : 'assistant',
@@ -51,7 +58,7 @@ module NanoBot
51
58
 
52
59
  payload.delete(:logit_bias) if payload.key?(:logit_bias) && payload[:logit_bias].nil?
53
60
 
54
- if @settings[:stream] && input[:interface][:stream]
61
+ if stream(input)
55
62
  content = ''
56
63
 
57
64
  payload[:stream] = proc do |chunk, _bytesize|
@@ -17,8 +17,9 @@ module NanoBot
17
17
 
18
18
  path = "#{user_home!.sub(%r{/$}, '')}/.local/state/nano-bots" if path.nil?
19
19
 
20
- path = "#{path.sub(%r{/$}, '')}/nano-bots-rb/#{cartridge[:name].to_slug.normalize}"
21
- path = "#{path}/#{cartridge[:version].to_slug.normalize}/#{key.to_slug.normalize}"
20
+ path = "#{path.sub(%r{/$}, '')}/ruby-nano-bots/#{cartridge[:meta][:author].to_slug.normalize}"
21
+ path = "#{path}/#{cartridge[:meta][:name].to_slug.normalize}"
22
+ path = "#{path}/#{cartridge[:meta][:version].to_s.gsub('.', '-').to_slug.normalize}/#{key.to_slug.normalize}"
22
23
  path = "#{path}/state.json"
23
24
 
24
25
  FileUtils.mkdir_p(File.dirname(path))
@@ -6,6 +6,7 @@ require_relative '../logic/helpers/hash'
6
6
  require_relative '../components/provider'
7
7
  require_relative '../components/storage'
8
8
  require_relative './interfaces/repl'
9
+ require_relative './interfaces/eval'
9
10
  require_relative './session'
10
11
 
11
12
  module NanoBot
@@ -24,7 +25,7 @@ module NanoBot
24
25
  end
25
26
 
26
27
  def eval(input)
27
- @session.evaluate_and_print(input, mode: 'eval')
28
+ Interfaces::Eval.evaluate(input, @cartridge, @session)
28
29
  end
29
30
 
30
31
  def repl
@@ -13,14 +13,14 @@ module NanoBot
13
13
  puts NanoBot::GEM[:version]
14
14
  exit
15
15
  when 'help', '', nil
16
- puts "Ruby Nano Bots #{NanoBot::GEM[:version]}"
17
- puts ' rnb cartridge.yml - eval "Hello"'
18
- puts ' rnb cartridge.yml - repl'
19
- puts ' rnb cartridge.yml - debug'
20
- puts ' rnb cartridge.yml STATE-KEY eval "Hello"'
21
- puts ' rnb cartridge.yml STATE-KEY repl'
22
- puts ' rnb cartridge.yml STATE-KEY debug'
23
- puts ' rnb version'
16
+ puts "Nano Bots #{NanoBot::GEM[:version]}"
17
+ puts ' nb cartridge.yml - eval "Hello"'
18
+ puts ' nb cartridge.yml - repl'
19
+ puts ' nb cartridge.yml - debug'
20
+ puts ' nb cartridge.yml STATE-KEY eval "Hello"'
21
+ puts ' nb cartridge.yml STATE-KEY repl'
22
+ puts ' nb cartridge.yml STATE-KEY debug'
23
+ puts ' nb version'
24
24
  exit
25
25
  end
26
26
 
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pry'
4
+ require 'rainbow'
5
+
6
+ require_relative '../../logic/helpers/hash'
7
+
8
+ module NanoBot
9
+ module Controllers
10
+ module Interfaces
11
+ module Eval
12
+ def self.evaluate(input, cartridge, session)
13
+ prefix = build_prefix(cartridge)
14
+ postfix = build_postfix(cartridge)
15
+
16
+ session.print(prefix) unless prefix.nil?
17
+
18
+ session.evaluate_and_print(input, mode: 'eval')
19
+
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]
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -10,20 +10,17 @@ module NanoBot
10
10
  module Interfaces
11
11
  module REPL
12
12
  def self.start(cartridge, session)
13
- if Logic::Helpers::Hash.fetch(
14
- cartridge, %i[interfaces repl prefix]
15
- )
16
- session.print(Logic::Helpers::Hash.fetch(cartridge,
17
- %i[interfaces repl prefix]))
18
- end
19
-
20
- session.boot(mode: 'repl')
21
-
22
- session.print(Logic::Helpers::Hash.fetch(cartridge, %i[interfaces repl postfix]) || "\n")
13
+ prefix = build_prefix(cartridge)
14
+ postfix = build_postfix(cartridge)
23
15
 
24
- session.flush
16
+ if Logic::Helpers::Hash.fetch(cartridge, %i[behaviors boot instruction])
17
+ session.print(prefix) unless prefix.nil?
18
+ session.boot(mode: 'repl')
19
+ session.print(postfix) unless postfix.nil?
20
+ session.print("\n")
21
+ end
25
22
 
26
- prompt = build_prompt(cartridge[:interfaces][:repl][:prompt])
23
+ prompt = build_prompt(Logic::Helpers::Hash.fetch(cartridge, %i[interfaces repl prompt]))
27
24
 
28
25
  Pry.config.prompt = Pry::Prompt.new(
29
26
  'REPL',
@@ -32,31 +29,45 @@ module NanoBot
32
29
  )
33
30
 
34
31
  Pry.commands.block_command(/(.*)/, 'handler') do |line|
35
- if Logic::Helpers::Hash.fetch(
36
- cartridge, %i[interfaces repl prefix]
37
- )
38
- session.print(Logic::Helpers::Hash.fetch(
39
- cartridge, %i[interfaces repl prefix]
40
- ))
41
- end
42
-
32
+ session.print(postfix) unless postfix.nil?
43
33
  session.evaluate_and_print(line, mode: 'repl')
44
- session.print(Logic::Helpers::Hash.fetch(cartridge, %i[interfaces repl postfix]) || "\n")
34
+ session.print(postfix) unless postfix.nil?
35
+ session.print("\n")
45
36
  session.flush
46
37
  end
47
38
 
48
39
  Pry.start
49
40
  end
50
41
 
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
+
51
56
  def self.build_prompt(prompt)
52
57
  result = ''
53
58
 
54
- prompt.each do |partial|
55
- result += if partial[:color]
56
- Rainbow(partial[:text]).send(partial[:color])
57
- else
58
- partial[:text]
59
- end
59
+ if prompt.is_a?(Array)
60
+ prompt.each do |partial|
61
+ result += if partial[:color]
62
+ Rainbow(partial[:text]).send(partial[:color])
63
+ else
64
+ partial[:text]
65
+ end
66
+ end
67
+ elsif prompt.is_a?(String)
68
+ result = prompt
69
+ else
70
+ result = "🤖#{Rainbow('> ').blue}"
60
71
  end
61
72
 
62
73
  result
@@ -67,13 +67,18 @@ module NanoBot
67
67
  process(input, mode:)
68
68
  end
69
69
 
70
- def process(input, mode:)
71
- streaming = @provider.settings[:stream] && Logic::Helpers::Hash.fetch(
72
- @cartridge, [:interfaces, mode.to_sym, :stream]
73
- )
70
+ def stream(interface)
71
+ provider = @provider.settings.key?(:stream) ? @provider.settings[:stream] : true
72
+ interface = interface.key?(:stream) ? interface[:stream] : true
73
+
74
+ provider && interface
75
+ end
74
76
 
77
+ def process(input, mode:)
75
78
  interface = Logic::Helpers::Hash.fetch(@cartridge, [:interfaces, mode.to_sym]) || {}
76
79
 
80
+ streaming = stream(interface)
81
+
77
82
  input[:interface] = interface
78
83
 
79
84
  updated_at = Time.now
@@ -84,9 +89,6 @@ module NanoBot
84
89
  if finished
85
90
  @state[:history] << output
86
91
  self.print(output[:message]) unless streaming
87
- unless Logic::Helpers::Hash.fetch(@cartridge, [:interfaces, mode.to_sym, :postfix]).nil?
88
- self.print(Logic::Helpers::Hash.fetch(@cartridge, [:interfaces, mode.to_sym, :postfix]))
89
- end
90
92
  ready = true
91
93
  flush
92
94
  elsif streaming
@@ -0,0 +1,12 @@
1
+ version: '3.7'
2
+
3
+ services:
4
+ nano-bots:
5
+ image: ruby:3.2.2-slim-bullseye
6
+ command: sh -c "gem install nano-bots -v 0.0.2 && bash"
7
+ environment:
8
+ OPENAI_API_ADDRESS: https://api.openai.com
9
+ OPENAI_API_ACCESS_TOKEN: your-token
10
+ OPENAI_API_USER_IDENTIFIER: your-user
11
+ volumes:
12
+ - ./your-cartridges:/cartridges
data/nano-bots.gemspec CHANGED
@@ -29,7 +29,7 @@ Gem::Specification.new do |spec|
29
29
 
30
30
  spec.require_paths = ['ports/dsl']
31
31
 
32
- spec.executables = ['rnb']
32
+ spec.executables = ['nb']
33
33
 
34
34
  spec.add_dependency 'babosa', '~> 2.0'
35
35
  spec.add_dependency 'dotenv', '~> 2.8', '>= 2.8.1'
data/static/gem.rb CHANGED
@@ -3,7 +3,7 @@
3
3
  module NanoBot
4
4
  GEM = {
5
5
  name: 'nano-bots',
6
- version: '0.0.1',
6
+ version: '0.0.2',
7
7
  author: 'icebaker',
8
8
  summary: 'Ruby Implementation of Nano Bots: small, AI-powered bots',
9
9
  description: 'Ruby Implementation of Nano Bots: small, AI-powered bots easily shared as a single file, designed to support multiple providers such as Vicuna, OpenAI ChatGPT, Google PaLM, Alpaca, and LLaMA.',
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nano-bots
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - icebaker
@@ -117,7 +117,7 @@ description: 'Ruby Implementation of Nano Bots: small, AI-powered bots easily sh
117
117
  ChatGPT, Google PaLM, Alpaca, and LLaMA.'
118
118
  email:
119
119
  executables:
120
- - rnb
120
+ - nb
121
121
  extensions: []
122
122
  extra_rdoc_files: []
123
123
  files:
@@ -128,15 +128,17 @@ files:
128
128
  - Gemfile.lock
129
129
  - LICENSE
130
130
  - README.md
131
- - bin/rnb
131
+ - bin/nb
132
132
  - components/provider.rb
133
133
  - components/providers/base.rb
134
134
  - components/providers/openai.rb
135
135
  - components/storage.rb
136
136
  - controllers/instance.rb
137
137
  - controllers/interfaces/cli.rb
138
+ - controllers/interfaces/eval.rb
138
139
  - controllers/interfaces/repl.rb
139
140
  - controllers/session.rb
141
+ - docker-compose.example.yml
140
142
  - logic/helpers/hash.rb
141
143
  - nano-bots.gemspec
142
144
  - ports/dsl/nano-bots.rb
/data/bin/{rnb → nb} RENAMED
File without changes