nano-bots 0.0.1 → 0.0.3
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 +4 -4
- data/.gitignore +1 -0
- data/Gemfile.lock +2 -2
- data/README.md +118 -33
- data/components/providers/openai.rb +8 -1
- data/components/storage.rb +3 -2
- data/controllers/instance.rb +41 -11
- data/controllers/interfaces/cli.rb +31 -11
- data/controllers/interfaces/eval.rb +39 -0
- data/controllers/interfaces/repl.rb +38 -27
- data/controllers/session.rb +16 -13
- data/docker-compose.example.yml +13 -0
- data/nano-bots.gemspec +1 -1
- data/ports/dsl/nano-bots.rb +4 -4
- data/static/cartridges/default.yml +14 -0
- data/static/gem.rb +1 -1
- metadata +7 -4
- /data/bin/{rnb → nb} +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ed836839edfabe16e119f3f7e52ad82fbef851885d5adbb5b3097620d0491bfb
|
|
4
|
+
data.tar.gz: a4f909df92cb62b9d5882ad3c9419e0c4560a15f251fa37aae92814b0e586143
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2c8f39d6d1b0362fb936b0ee0d3df73a6efb77ee3cb86c17c754f1a129d38c01034c2deff7f37f16143a17c28446fc4ebd868e047aaf616ab298b61d0310fa4e
|
|
7
|
+
data.tar.gz: 61ec7033e15173f2c74aeb830b48dcfaac676f7be282f3ebede3c198e710c7b92caad92649ddc84b7e3e665de2a74b4417c260aebb63caa0e0d0a3b7cdfb6fa6
|
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
nano-bots (0.0.
|
|
4
|
+
nano-bots (0.0.3)
|
|
5
5
|
babosa (~> 2.0)
|
|
6
6
|
dotenv (~> 2.8, >= 2.8.1)
|
|
7
7
|
faraday (~> 2.7, >= 2.7.4)
|
|
@@ -48,7 +48,7 @@ GEM
|
|
|
48
48
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
49
49
|
rspec-support (~> 3.12.0)
|
|
50
50
|
rspec-support (3.12.0)
|
|
51
|
-
rubocop (1.
|
|
51
|
+
rubocop (1.51.0)
|
|
52
52
|
json (~> 2.3)
|
|
53
53
|
parallel (~> 1.10)
|
|
54
54
|
parser (>= 3.2.0.0)
|
data/README.md
CHANGED
|
@@ -8,10 +8,13 @@ _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)
|
|
14
15
|
- [Cartridges](#cartridges)
|
|
16
|
+
- [Providers](#providers)
|
|
17
|
+
- [Debugging](#debugging)
|
|
15
18
|
- [Development](#development)
|
|
16
19
|
- [Publish to RubyGems](#publish-to-rubygems)
|
|
17
20
|
|
|
@@ -20,13 +23,13 @@ https://user-images.githubusercontent.com/113217272/237840989-1e29a5cc-6644-48d0
|
|
|
20
23
|
For a system usage:
|
|
21
24
|
|
|
22
25
|
```sh
|
|
23
|
-
gem install nano-bots -v 0.0.
|
|
26
|
+
gem install nano-bots -v 0.0.3
|
|
24
27
|
```
|
|
25
28
|
|
|
26
29
|
To use it in a project, add it to your `Gemfile`:
|
|
27
30
|
|
|
28
31
|
```ruby
|
|
29
|
-
gem 'nano-bots', '~> 0.0.
|
|
32
|
+
gem 'nano-bots', '~> 0.0.3'
|
|
30
33
|
```
|
|
31
34
|
|
|
32
35
|
```sh
|
|
@@ -40,35 +43,89 @@ export OPENAI_API_ADDRESS=https://api.openai.com
|
|
|
40
43
|
export OPENAI_API_ACCESS_TOKEN=your-token
|
|
41
44
|
export OPENAI_API_USER_IDENTIFIER=your-user
|
|
42
45
|
|
|
43
|
-
export NANO_BOTS_STATE_DIRECTORY=/home/user/.local/state/nano-bots
|
|
44
|
-
export NANO_BOTS_CARTRIDGES_DIRECTORY=/home/user/.local/share/nano-bots/cartridges
|
|
46
|
+
# export NANO_BOTS_STATE_DIRECTORY=/home/user/.local/state/nano-bots
|
|
47
|
+
# export NANO_BOTS_CARTRIDGES_DIRECTORY=/home/user/.local/share/nano-bots/cartridges
|
|
45
48
|
```
|
|
46
49
|
|
|
47
|
-
Alternatively, if your current directory has a `.env` file with the environment variables, they will be automatically loaded
|
|
50
|
+
Alternatively, if your current directory has a `.env` file with the environment variables, they will be automatically loaded:
|
|
51
|
+
|
|
52
|
+
```sh
|
|
53
|
+
OPENAI_API_ADDRESS=https://api.openai.com
|
|
54
|
+
OPENAI_API_ACCESS_TOKEN=your-token
|
|
55
|
+
OPENAI_API_USER_IDENTIFIER=your-user
|
|
56
|
+
|
|
57
|
+
# NANO_BOTS_STATE_DIRECTORY=/home/user/.local/state/nano-bots
|
|
58
|
+
# NANO_BOTS_CARTRIDGES_DIRECTORY=/home/user/.local/share/nano-bots/cartridges
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Docker
|
|
62
|
+
|
|
63
|
+
Clone the repository and copy the Docker Compose template:
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
git clone git@github.com:icebaker/ruby-nano-bots.git
|
|
67
|
+
cd ruby-nano-bots
|
|
68
|
+
cp docker-compose.example.yml docker-compose.yml
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Set your provider credentials and choose your desired directory for the cartridges files:
|
|
72
|
+
|
|
73
|
+
```yaml
|
|
74
|
+
version: '3.7'
|
|
75
|
+
|
|
76
|
+
services:
|
|
77
|
+
nano-bots:
|
|
78
|
+
image: ruby:3.2.2-slim-bullseye
|
|
79
|
+
command: sh -c "gem install nano-bots -v 0.0.3 && bash"
|
|
80
|
+
environment:
|
|
81
|
+
OPENAI_API_ADDRESS: https://api.openai.com
|
|
82
|
+
OPENAI_API_ACCESS_TOKEN: your-token
|
|
83
|
+
OPENAI_API_USER_IDENTIFIER: your-user
|
|
84
|
+
volumes:
|
|
85
|
+
- ./your-cartridges:/cartridges
|
|
86
|
+
# - ./your-data:/data
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Enter the container:
|
|
90
|
+
```sh
|
|
91
|
+
docker compose run nano-bots
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Start playing:
|
|
95
|
+
```sh
|
|
96
|
+
nb - - eval "hello"
|
|
97
|
+
nb - - repl
|
|
98
|
+
|
|
99
|
+
nb cartridges/assistant.yml - eval "hello"
|
|
100
|
+
nb cartridges/assistant.yml - repl
|
|
101
|
+
```
|
|
48
102
|
|
|
49
103
|
## Usage
|
|
50
104
|
|
|
51
105
|
### Command Line
|
|
52
106
|
|
|
53
|
-
After installing the gem, the `
|
|
107
|
+
After installing the gem, the `nb` binary command will be available for your project or system.
|
|
54
108
|
|
|
55
109
|
Examples of usage:
|
|
56
110
|
|
|
57
111
|
```bash
|
|
58
|
-
|
|
112
|
+
nb - - eval "hello"
|
|
113
|
+
# => Hello! How may I assist you today?
|
|
114
|
+
|
|
115
|
+
nb to-en-us-translator.yml - eval "Salut, comment ça va?"
|
|
59
116
|
# => Hello, how are you doing?
|
|
60
117
|
|
|
61
|
-
|
|
62
|
-
# =>
|
|
63
|
-
# and
|
|
64
|
-
#
|
|
118
|
+
nb midjourney.yml - eval "happy cyberpunk robot"
|
|
119
|
+
# => A cheerful and fun-loving robot is dancing wildly amidst a
|
|
120
|
+
# futuristic and lively cityscape. Holographic advertisements
|
|
121
|
+
# and vibrant neon colors can be seen in the background.
|
|
65
122
|
|
|
66
|
-
|
|
123
|
+
nb lisp.yml - eval "(+ 1 2)"
|
|
67
124
|
# => 3
|
|
68
125
|
|
|
69
126
|
cat article.txt |
|
|
70
|
-
|
|
71
|
-
|
|
127
|
+
nb to-en-us-translator.yml - eval |
|
|
128
|
+
nb summarizer.yml - eval
|
|
72
129
|
# -> LLM stands for Large Language Model, which refers to an
|
|
73
130
|
# artificial intelligence algorithm capable of processing
|
|
74
131
|
# and understanding vast amounts of natural language data,
|
|
@@ -77,10 +134,31 @@ cat article.txt |
|
|
|
77
134
|
```
|
|
78
135
|
|
|
79
136
|
```bash
|
|
80
|
-
|
|
137
|
+
nb - - repl
|
|
138
|
+
|
|
139
|
+
nb assistant.yml - repl
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
```text
|
|
143
|
+
🤖> Hi, how are you doing?
|
|
144
|
+
|
|
145
|
+
As an AI language model, I do not experience emotions but I am functioning
|
|
146
|
+
well. How can I assist you?
|
|
147
|
+
|
|
148
|
+
🤖> |
|
|
81
149
|
```
|
|
82
150
|
|
|
83
|
-
All of the commands above are stateless. If you want to preserve the history of your interactions, replace the `-` with a state key
|
|
151
|
+
All of the commands above are stateless. If you want to preserve the history of your interactions, replace the `-` with a state key:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
nb assistant.yml your-user eval "Salut, comment ça va?"
|
|
155
|
+
nb assistant.yml your-user repl
|
|
156
|
+
|
|
157
|
+
nb assistant.yml 6ea6c43c42a1c076b1e3c36fa349ac2c eval "Salut, comment ça va?"
|
|
158
|
+
nb assistant.yml 6ea6c43c42a1c076b1e3c36fa349ac2c repl
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
You can use a simple key, such as your username, or a randomly generated one:
|
|
84
162
|
|
|
85
163
|
```ruby
|
|
86
164
|
require 'securerandom'
|
|
@@ -88,12 +166,14 @@ require 'securerandom'
|
|
|
88
166
|
SecureRandom.hex # => 6ea6c43c42a1c076b1e3c36fa349ac2c
|
|
89
167
|
```
|
|
90
168
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
169
|
+
### Debugging
|
|
170
|
+
|
|
171
|
+
```sh
|
|
172
|
+
nb - - cartridge
|
|
173
|
+
nb cartridge.yml - cartridge
|
|
94
174
|
|
|
95
|
-
|
|
96
|
-
|
|
175
|
+
nb - STATE-KEY state
|
|
176
|
+
nb cartridge.yml STATE-KEY state
|
|
97
177
|
```
|
|
98
178
|
|
|
99
179
|
### Library
|
|
@@ -101,13 +181,13 @@ rnb assistant.yml 6ea6c43c42a1c076b1e3c36fa349ac2c repl
|
|
|
101
181
|
To use it as a library:
|
|
102
182
|
|
|
103
183
|
```ruby
|
|
104
|
-
require 'nano-bots/cli' # Equivalent to the `
|
|
184
|
+
require 'nano-bots/cli' # Equivalent to the `nb` command.
|
|
105
185
|
```
|
|
106
186
|
|
|
107
187
|
```ruby
|
|
108
188
|
require 'nano-bots'
|
|
109
189
|
|
|
110
|
-
NanoBot.cli # Equivalent to the `
|
|
190
|
+
NanoBot.cli # Equivalent to the `nb` command.
|
|
111
191
|
|
|
112
192
|
NanoBot.repl(cartridge: 'cartridge.yml') # Starts a new REPL.
|
|
113
193
|
|
|
@@ -128,20 +208,15 @@ Here's what a Nano Bot Cartridge looks like:
|
|
|
128
208
|
|
|
129
209
|
```yaml
|
|
130
210
|
---
|
|
131
|
-
|
|
132
|
-
|
|
211
|
+
meta:
|
|
212
|
+
name: Nano Bot Name
|
|
213
|
+
author: Your Name
|
|
214
|
+
version: 0.0.1
|
|
133
215
|
|
|
134
216
|
behaviors:
|
|
135
217
|
interaction:
|
|
136
218
|
directive: You are a helpful assistant.
|
|
137
219
|
|
|
138
|
-
interfaces:
|
|
139
|
-
repl:
|
|
140
|
-
prompt:
|
|
141
|
-
- text: '🤖'
|
|
142
|
-
- text: '> '
|
|
143
|
-
color: blue
|
|
144
|
-
|
|
145
220
|
provider:
|
|
146
221
|
name: openai
|
|
147
222
|
settings:
|
|
@@ -154,6 +229,16 @@ provider:
|
|
|
154
229
|
|
|
155
230
|
Check the Nano Bots specification to learn more about [how to build cartridges](https://icebaker.github.io/nano-bots/#/README?id=cartridges).
|
|
156
231
|
|
|
232
|
+
## Providers
|
|
233
|
+
|
|
234
|
+
Currently supported providers:
|
|
235
|
+
|
|
236
|
+
- [ ] [Vicuna](https://github.com/lm-sys/FastChat)
|
|
237
|
+
- [x] [Open AI](https://platform.openai.com/docs/api-reference)
|
|
238
|
+
- [ ] [Google PaLM](https://developers.generativeai.google/)
|
|
239
|
+
- [ ] [Alpaca](https://github.com/tatsu-lab/stanford_alpaca)
|
|
240
|
+
- [ ] [LLaMA](https://github.com/facebookresearch/llama)
|
|
241
|
+
|
|
157
242
|
## Development
|
|
158
243
|
|
|
159
244
|
```bash
|
|
@@ -169,5 +254,5 @@ gem build nano-bots.gemspec
|
|
|
169
254
|
|
|
170
255
|
gem signin
|
|
171
256
|
|
|
172
|
-
gem push nano-bots-0.0.
|
|
257
|
+
gem push nano-bots-0.0.3.gem
|
|
173
258
|
```
|
|
@@ -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
|
|
61
|
+
if stream(input)
|
|
55
62
|
content = ''
|
|
56
63
|
|
|
57
64
|
payload[:stream] = proc do |chunk, _bytesize|
|
data/components/storage.rb
CHANGED
|
@@ -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
|
|
21
|
-
path = "#{path}/#{cartridge[:
|
|
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}"
|
|
22
23
|
path = "#{path}/state.json"
|
|
23
24
|
|
|
24
25
|
FileUtils.mkdir_p(File.dirname(path))
|
data/controllers/instance.rb
CHANGED
|
@@ -6,40 +6,70 @@ 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
|
|
12
13
|
module Controllers
|
|
13
14
|
class Instance
|
|
14
|
-
def initialize(cartridge_path:, state: nil)
|
|
15
|
+
def initialize(cartridge_path:, stream:, state: nil)
|
|
16
|
+
@stream = stream
|
|
17
|
+
|
|
15
18
|
load_cartridge!(cartridge_path)
|
|
16
19
|
|
|
17
20
|
provider = Components::Provider.new(@cartridge[:provider])
|
|
18
21
|
|
|
19
|
-
@session = Session.new(provider:, cartridge: @cartridge, state:)
|
|
22
|
+
@session = Session.new(provider:, cartridge: @cartridge, state:, stream: @stream)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def cartridge
|
|
26
|
+
puts YAML.dump(@safe_cartridge)
|
|
20
27
|
end
|
|
21
28
|
|
|
22
|
-
def
|
|
23
|
-
@session.
|
|
29
|
+
def state
|
|
30
|
+
@session.state
|
|
24
31
|
end
|
|
25
32
|
|
|
26
33
|
def eval(input)
|
|
27
|
-
|
|
34
|
+
Interfaces::Eval.evaluate(input, @cartridge, @session)
|
|
35
|
+
|
|
36
|
+
return unless @stream.is_a?(StringIO)
|
|
37
|
+
|
|
38
|
+
@stream.flush
|
|
39
|
+
result = @stream.string.clone
|
|
40
|
+
@stream.truncate(0)
|
|
41
|
+
@stream.rewind
|
|
42
|
+
result
|
|
28
43
|
end
|
|
29
44
|
|
|
30
45
|
def repl
|
|
46
|
+
if @stream.is_a?(StringIO)
|
|
47
|
+
@stream.flush
|
|
48
|
+
@stream = $stdout
|
|
49
|
+
@session.stream = @stream
|
|
50
|
+
end
|
|
31
51
|
Interfaces::REPL.start(@cartridge, @session)
|
|
32
52
|
end
|
|
33
53
|
|
|
34
54
|
private
|
|
35
55
|
|
|
36
56
|
def load_cartridge!(path)
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
57
|
+
elected_path = if path.strip == '-'
|
|
58
|
+
File.expand_path('../static/cartridges/default.yml', __dir__)
|
|
59
|
+
else
|
|
60
|
+
Components::Storage.cartridge_path(path)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
if elected_path.nil?
|
|
64
|
+
@stream.write("Cartridge file not found: \"#{path}\"\n")
|
|
65
|
+
raise StandardError, "Cartridge file not found: \"#{path}\""
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
@cartridge = YAML.safe_load(File.read(elected_path), permitted_classes: [Symbol])
|
|
69
|
+
|
|
70
|
+
@safe_cartridge = Marshal.load(Marshal.dump(@cartridge))
|
|
71
|
+
|
|
72
|
+
@cartridge = Logic::Helpers::Hash.symbolize_keys(@cartridge)
|
|
43
73
|
|
|
44
74
|
inject_environment_variables!(@cartridge)
|
|
45
75
|
end
|
|
@@ -13,20 +13,38 @@ module NanoBot
|
|
|
13
13
|
puts NanoBot::GEM[:version]
|
|
14
14
|
exit
|
|
15
15
|
when 'help', '', nil
|
|
16
|
-
puts
|
|
17
|
-
puts
|
|
18
|
-
puts '
|
|
19
|
-
puts '
|
|
20
|
-
puts '
|
|
21
|
-
puts '
|
|
22
|
-
puts '
|
|
23
|
-
puts '
|
|
16
|
+
puts ''
|
|
17
|
+
puts "Nano Bots #{NanoBot::GEM[:version]}"
|
|
18
|
+
puts ''
|
|
19
|
+
puts ' nb - - eval "hello"'
|
|
20
|
+
puts ' nb - - repl'
|
|
21
|
+
puts ''
|
|
22
|
+
puts ' nb cartridge.yml - eval "hello"'
|
|
23
|
+
puts ' nb cartridge.yml - repl'
|
|
24
|
+
puts ''
|
|
25
|
+
puts ' nb - STATE-KEY eval "hello"'
|
|
26
|
+
puts ' nb - STATE-KEY repl'
|
|
27
|
+
puts ''
|
|
28
|
+
puts ' nb cartridge.yml STATE-KEY eval "hello"'
|
|
29
|
+
puts ' nb cartridge.yml STATE-KEY repl'
|
|
30
|
+
puts ''
|
|
31
|
+
puts ' nb - - cartridge'
|
|
32
|
+
puts ' nb cartridge.yml - cartridge'
|
|
33
|
+
puts ''
|
|
34
|
+
puts ' nb - STATE-KEY state'
|
|
35
|
+
puts ' nb cartridge.yml STATE-KEY state'
|
|
36
|
+
puts ''
|
|
37
|
+
puts ' nb version'
|
|
38
|
+
puts ' nb help'
|
|
39
|
+
puts ''
|
|
24
40
|
exit
|
|
25
41
|
end
|
|
26
42
|
|
|
27
43
|
params = { cartridge_path: ARGV[0], state: ARGV[1], command: ARGV[2] }
|
|
28
44
|
|
|
29
|
-
bot = Instance.new(
|
|
45
|
+
bot = Instance.new(
|
|
46
|
+
cartridge_path: params[:cartridge_path], state: params[:state], stream: $stdout
|
|
47
|
+
)
|
|
30
48
|
|
|
31
49
|
case params[:command]
|
|
32
50
|
when 'eval'
|
|
@@ -35,8 +53,10 @@ module NanoBot
|
|
|
35
53
|
bot.eval(params[:input])
|
|
36
54
|
when 'repl'
|
|
37
55
|
bot.repl
|
|
38
|
-
when '
|
|
39
|
-
bot.
|
|
56
|
+
when 'state'
|
|
57
|
+
bot.state
|
|
58
|
+
when 'cartridge'
|
|
59
|
+
bot.cartridge
|
|
40
60
|
else
|
|
41
61
|
raise "TODO: [#{params[:command]}]"
|
|
42
62
|
end
|
|
@@ -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
|
-
|
|
14
|
-
|
|
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
|
-
|
|
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[
|
|
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
|
-
|
|
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(
|
|
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.
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
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
|
data/controllers/session.rb
CHANGED
|
@@ -12,12 +12,13 @@ module NanoBot
|
|
|
12
12
|
STREAM_TIMEOUT_IN_SECONDS = 5
|
|
13
13
|
|
|
14
14
|
class Session
|
|
15
|
-
|
|
15
|
+
attr_accessor :stream
|
|
16
|
+
|
|
17
|
+
def initialize(provider:, cartridge:, state: nil, stream: $stdout)
|
|
18
|
+
@stream = stream
|
|
16
19
|
@provider = provider
|
|
17
20
|
@cartridge = cartridge
|
|
18
21
|
|
|
19
|
-
@output = $stdout
|
|
20
|
-
|
|
21
22
|
@stateless = state.nil? || state.strip == '-' || state.strip.empty?
|
|
22
23
|
|
|
23
24
|
if @stateless
|
|
@@ -30,7 +31,7 @@ module NanoBot
|
|
|
30
31
|
end
|
|
31
32
|
end
|
|
32
33
|
|
|
33
|
-
def
|
|
34
|
+
def state
|
|
34
35
|
pp({
|
|
35
36
|
state: {
|
|
36
37
|
path: @state_path,
|
|
@@ -67,13 +68,18 @@ module NanoBot
|
|
|
67
68
|
process(input, mode:)
|
|
68
69
|
end
|
|
69
70
|
|
|
70
|
-
def
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
)
|
|
71
|
+
def streaming(interface)
|
|
72
|
+
provider = @provider.settings.key?(:stream) ? @provider.settings[:stream] : true
|
|
73
|
+
interface = interface.key?(:stream) ? interface[:stream] : true
|
|
74
74
|
|
|
75
|
+
provider && interface
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def process(input, mode:)
|
|
75
79
|
interface = Logic::Helpers::Hash.fetch(@cartridge, [:interfaces, mode.to_sym]) || {}
|
|
76
80
|
|
|
81
|
+
streaming = streaming(interface)
|
|
82
|
+
|
|
77
83
|
input[:interface] = interface
|
|
78
84
|
|
|
79
85
|
updated_at = Time.now
|
|
@@ -84,9 +90,6 @@ module NanoBot
|
|
|
84
90
|
if finished
|
|
85
91
|
@state[:history] << output
|
|
86
92
|
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
93
|
ready = true
|
|
91
94
|
flush
|
|
92
95
|
elsif streaming
|
|
@@ -103,11 +106,11 @@ module NanoBot
|
|
|
103
106
|
end
|
|
104
107
|
|
|
105
108
|
def flush
|
|
106
|
-
@
|
|
109
|
+
@stream.flush
|
|
107
110
|
end
|
|
108
111
|
|
|
109
112
|
def print(content)
|
|
110
|
-
@
|
|
113
|
+
@stream.write(content)
|
|
111
114
|
end
|
|
112
115
|
end
|
|
113
116
|
end
|
|
@@ -0,0 +1,13 @@
|
|
|
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.3 && 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
|
|
13
|
+
# - ./your-data:/data
|
data/nano-bots.gemspec
CHANGED
data/ports/dsl/nano-bots.rb
CHANGED
|
@@ -7,16 +7,16 @@ require_relative '../../controllers/instance'
|
|
|
7
7
|
require_relative '../../controllers/interfaces/cli'
|
|
8
8
|
|
|
9
9
|
module NanoBot
|
|
10
|
-
def self.new(cartridge
|
|
11
|
-
Controllers::Instance.new(cartridge_path: cartridge, state:)
|
|
10
|
+
def self.new(cartridge: '-', state: '-')
|
|
11
|
+
Controllers::Instance.new(cartridge_path: cartridge, state:, stream: StringIO.new)
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def self.cli
|
|
15
15
|
Controllers::Interfaces::CLI.handle!
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
-
def self.repl(cartridge
|
|
19
|
-
Controllers::Instance.new(cartridge_path: cartridge, state:).repl
|
|
18
|
+
def self.repl(cartridge: '-', state: '-')
|
|
19
|
+
Controllers::Instance.new(cartridge_path: cartridge, state:, stream: $stdout).repl
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
def self.version
|
|
@@ -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
|
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.
|
|
6
|
+
version: '0.0.3',
|
|
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,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: nano-bots
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- icebaker
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2023-05-
|
|
11
|
+
date: 2023-05-13 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: babosa
|
|
@@ -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
|
-
-
|
|
120
|
+
- nb
|
|
121
121
|
extensions: []
|
|
122
122
|
extra_rdoc_files: []
|
|
123
123
|
files:
|
|
@@ -128,19 +128,22 @@ files:
|
|
|
128
128
|
- Gemfile.lock
|
|
129
129
|
- LICENSE
|
|
130
130
|
- README.md
|
|
131
|
-
- bin/
|
|
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
|
|
143
145
|
- ports/dsl/nano-bots/cli.rb
|
|
146
|
+
- static/cartridges/default.yml
|
|
144
147
|
- static/gem.rb
|
|
145
148
|
homepage: https://github.com/icebaker/ruby-nano-bots
|
|
146
149
|
licenses:
|
/data/bin/{rnb → nb}
RENAMED
|
File without changes
|