nano-bots 0.0.10 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +58 -38
- data/components/provider.rb +3 -3
- data/components/providers/base.rb +4 -0
- data/components/providers/openai.rb +33 -15
- data/components/storage.rb +27 -17
- data/controllers/security.rb +4 -0
- data/docker-compose.example.yml +6 -6
- data/static/cartridges/baseline.yml +9 -6
- data/static/cartridges/default.yml +0 -1
- data/static/gem.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4632306b0fe1fc9af4ee96c7624f163d80c70eb259c80f3efad158e95e76414a
|
4
|
+
data.tar.gz: a2156c47648e3b8b118a4698d23031ca4bd4bf139db6f5f19fa5561f1591cf7b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d8271268413e87793b147385c999edddbb59dc70203dfca243adb7836ee680dc430a57dc625d038394b6b86e3bb0a9a4e45f12291f9e1ef9574da8ee69ed93e5
|
7
|
+
data.tar.gz: 1d6d1118162ed3dbc3438205aa7b4e858499d154e7cc6bdba963a53ddeeff7c071398e9eebc1f3d273c7aa128c39fbcb452a8f6f9bfff8d41b2dac81fb04d9ce
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -28,13 +28,13 @@ https://user-images.githubusercontent.com/113217272/238141567-c58a240c-7b67-4b3b
|
|
28
28
|
For a system usage:
|
29
29
|
|
30
30
|
```sh
|
31
|
-
gem install nano-bots -v 0.0
|
31
|
+
gem install nano-bots -v 0.1.0
|
32
32
|
```
|
33
33
|
|
34
34
|
To use it in a project, add it to your `Gemfile`:
|
35
35
|
|
36
36
|
```ruby
|
37
|
-
gem 'nano-bots', '~> 0.0
|
37
|
+
gem 'nano-bots', '~> 0.1.0'
|
38
38
|
```
|
39
39
|
|
40
40
|
```sh
|
@@ -44,10 +44,11 @@ bundle install
|
|
44
44
|
For credentials and configurations, relevant environment variables can be set in your `.bashrc`, `.zshrc`, or equivalent files, as well as in your Docker Container or System Environment. Example:
|
45
45
|
|
46
46
|
```sh
|
47
|
-
export NANO_BOTS_ENCRYPTION_PASSWORD="UNSAFE"
|
48
47
|
export OPENAI_API_ADDRESS=https://api.openai.com
|
49
|
-
export
|
50
|
-
|
48
|
+
export OPENAI_API_KEY=your-access-token
|
49
|
+
|
50
|
+
export NANO_BOTS_ENCRYPTION_PASSWORD=UNSAFE
|
51
|
+
export NANO_BOTS_END_USER=your-user
|
51
52
|
|
52
53
|
# export NANO_BOTS_STATE_DIRECTORY=/home/user/.local/state/nano-bots
|
53
54
|
# export NANO_BOTS_CARTRIDGES_DIRECTORY=/home/user/.local/share/nano-bots/cartridges
|
@@ -56,10 +57,11 @@ export OPENAI_API_USER_IDENTIFIER=your-user
|
|
56
57
|
Alternatively, if your current directory has a `.env` file with the environment variables, they will be automatically loaded:
|
57
58
|
|
58
59
|
```sh
|
59
|
-
NANO_BOTS_ENCRYPTION_PASSWORD="UNSAFE"
|
60
60
|
OPENAI_API_ADDRESS=https://api.openai.com
|
61
|
-
|
62
|
-
|
61
|
+
OPENAI_API_KEY=your-access-token
|
62
|
+
|
63
|
+
NANO_BOTS_ENCRYPTION_PASSWORD=UNSAFE
|
64
|
+
NANO_BOTS_END_USER=your-user
|
63
65
|
|
64
66
|
# NANO_BOTS_STATE_DIRECTORY=/home/user/.local/state/nano-bots
|
65
67
|
# NANO_BOTS_CARTRIDGES_DIRECTORY=/home/user/.local/share/nano-bots/cartridges
|
@@ -83,15 +85,15 @@ version: '3.7'
|
|
83
85
|
services:
|
84
86
|
nano-bots:
|
85
87
|
image: ruby:3.2.2-slim-bullseye
|
86
|
-
command: sh -c "gem install nano-bots -v 0.0
|
88
|
+
command: sh -c "gem install nano-bots -v 0.1.0 && bash"
|
87
89
|
environment:
|
88
|
-
NANO_BOTS_ENCRYPTION_PASSWORD: UNSAFE
|
89
90
|
OPENAI_API_ADDRESS: https://api.openai.com
|
90
|
-
|
91
|
-
|
91
|
+
OPENAI_API_KEY: your-access-token
|
92
|
+
NANO_BOTS_ENCRYPTION_PASSWORD: UNSAFE
|
93
|
+
NANO_BOTS_END_USER: your-user
|
92
94
|
volumes:
|
93
|
-
- ./your-cartridges
|
94
|
-
|
95
|
+
- ./your-cartridges:/.local/share/nano-bots/cartridges
|
96
|
+
- ./your-state:/.local/state/nano-bots
|
95
97
|
```
|
96
98
|
|
97
99
|
Enter the container:
|
@@ -104,8 +106,8 @@ Start playing:
|
|
104
106
|
nb - - eval "hello"
|
105
107
|
nb - - repl
|
106
108
|
|
107
|
-
nb
|
108
|
-
nb
|
109
|
+
nb assistant.yml - eval "hello"
|
110
|
+
nb assistant.yml - repl
|
109
111
|
```
|
110
112
|
|
111
113
|
## Usage
|
@@ -256,13 +258,13 @@ behaviors:
|
|
256
258
|
directive: You are a helpful assistant.
|
257
259
|
|
258
260
|
provider:
|
259
|
-
|
261
|
+
id: openai
|
262
|
+
credentials:
|
263
|
+
address: ENV/OPENAI_API_ADDRESS
|
264
|
+
access-token: ENV/OPENAI_API_KEY
|
260
265
|
settings:
|
266
|
+
user: ENV/NANO_BOTS_END_USER
|
261
267
|
model: gpt-3.5-turbo
|
262
|
-
credentials:
|
263
|
-
address: ENV/OPENAI_API_ADDRESS
|
264
|
-
access-token: ENV/OPENAI_API_ACCESS_TOKEN
|
265
|
-
user-identifier: ENV/OPENAI_API_USER_IDENTIFIER
|
266
268
|
```
|
267
269
|
|
268
270
|
Check the Nano Bots specification to learn more about [how to build cartridges](https://spec.nbots.io/#/README?id=cartridges).
|
@@ -314,33 +316,48 @@ A common strategy for deploying Nano Bots to multiple users through APIs or auto
|
|
314
316
|
You can define custom end-user identifiers in the following way:
|
315
317
|
|
316
318
|
```ruby
|
317
|
-
NanoBot.new(environment: {
|
318
|
-
NanoBot.new(environment: {
|
319
|
+
NanoBot.new(environment: { NANO_BOTS_END_USER: 'custom-user-a' })
|
320
|
+
NanoBot.new(environment: { NANO_BOTS_END_USER: 'custom-user-b' })
|
319
321
|
```
|
320
322
|
|
321
|
-
Consider that you have
|
323
|
+
Consider that you have the following end-user identifier in your environment:
|
322
324
|
```sh
|
323
|
-
|
325
|
+
NANO_BOTS_END_USER=your-name
|
326
|
+
```
|
327
|
+
|
328
|
+
Or a configuration in your Cartridge:
|
329
|
+
```yml
|
330
|
+
---
|
331
|
+
provider:
|
332
|
+
id: openai
|
333
|
+
settings:
|
334
|
+
user: your-name
|
324
335
|
```
|
325
336
|
|
326
337
|
The requests will be performed as follows:
|
327
338
|
|
328
339
|
```ruby
|
329
|
-
NanoBot.new(
|
330
|
-
# { user: 'your-name
|
340
|
+
NanoBot.new(cartridge: '-')
|
341
|
+
# { user: 'your-name' }
|
331
342
|
|
332
|
-
NanoBot.new(environment: {
|
333
|
-
# { user: '
|
343
|
+
NanoBot.new(cartridge: '-', environment: { NANO_BOTS_END_USER: 'custom-user-a' })
|
344
|
+
# { user: 'custom-user-a' }
|
345
|
+
|
346
|
+
NanoBot.new(cartridge: '-', environment: { NANO_BOTS_END_USER: 'custom-user-b' })
|
347
|
+
# { user: 'custom-user-b' }
|
334
348
|
```
|
335
349
|
|
336
350
|
Actually, to enhance privacy, neither your user nor your users' identifiers will be shared in this way. Instead, they will be encrypted before being shared with the provider:
|
337
351
|
|
338
352
|
```ruby
|
339
|
-
'your-name
|
340
|
-
#
|
353
|
+
'your-name'
|
354
|
+
# _O7OjYUESagb46YSeUeSfSMzoO1Yg0BZqpsAkPg4j62SeNYlgwq3kn51Ob2wmIehoA==
|
355
|
+
|
356
|
+
'custom-user-a'
|
357
|
+
# _O7OjYUESagb46YSeUeSfSMzoO1Yg0BZJgIXHCBHyADW-rn4IQr-s2RvP7vym8u5tnzYMIs=
|
341
358
|
|
342
|
-
'
|
343
|
-
#
|
359
|
+
'custom-user-b'
|
360
|
+
# _O7OjYUESagb46YSeUeSfSMzoO1Yg0BZkjUwCcsh9sVppKvYMhd2qGRvP7vym8u5tnzYMIg=
|
344
361
|
```
|
345
362
|
|
346
363
|
In this manner, you possess identifiers if required, however, their actual content can only be decrypted by you via your secure password (`NANO_BOTS_ENCRYPTION_PASSWORD`).
|
@@ -352,11 +369,14 @@ To decrypt your encrypted data, once you have properly configured your password,
|
|
352
369
|
```ruby
|
353
370
|
require 'nano-bots'
|
354
371
|
|
355
|
-
NanoBot.security.decrypt('
|
356
|
-
# your-name
|
372
|
+
NanoBot.security.decrypt('_O7OjYUESagb46YSeUeSfSMzoO1Yg0BZqpsAkPg4j62SeNYlgwq3kn51Ob2wmIehoA==')
|
373
|
+
# your-name
|
374
|
+
|
375
|
+
NanoBot.security.decrypt('_O7OjYUESagb46YSeUeSfSMzoO1Yg0BZJgIXHCBHyADW-rn4IQr-s2RvP7vym8u5tnzYMIs=')
|
376
|
+
# custom-user-a
|
357
377
|
|
358
|
-
NanoBot.security.decrypt('
|
359
|
-
#
|
378
|
+
NanoBot.security.decrypt('_O7OjYUESagb46YSeUeSfSMzoO1Yg0BZkjUwCcsh9sVppKvYMhd2qGRvP7vym8u5tnzYMIg=')
|
379
|
+
# custom-user-b
|
360
380
|
```
|
361
381
|
|
362
382
|
If you lose your password, you lose your data. It is not possible to recover it at all. For real.
|
@@ -388,5 +408,5 @@ gem build nano-bots.gemspec
|
|
388
408
|
|
389
409
|
gem signin
|
390
410
|
|
391
|
-
gem push nano-bots-0.0.
|
411
|
+
gem push nano-bots-0.1.0.gem
|
392
412
|
```
|
data/components/provider.rb
CHANGED
@@ -8,11 +8,11 @@ module NanoBot
|
|
8
8
|
module Components
|
9
9
|
class Provider
|
10
10
|
def self.new(provider, environment: {})
|
11
|
-
case provider[:
|
11
|
+
case provider[:id]
|
12
12
|
when 'openai'
|
13
|
-
Providers::OpenAI.new(provider[:settings], environment:)
|
13
|
+
Providers::OpenAI.new(provider[:settings], provider[:credentials], environment:)
|
14
14
|
else
|
15
|
-
raise "Unsupported provider #{provider[:
|
15
|
+
raise "Unsupported provider \"#{provider[:id]}\""
|
16
16
|
end
|
17
17
|
end
|
18
18
|
end
|
@@ -6,6 +6,10 @@ module NanoBot
|
|
6
6
|
module Components
|
7
7
|
module Providers
|
8
8
|
class Base
|
9
|
+
def initialize(_settings, _credentials, _environment: {})
|
10
|
+
raise NoMethodError, "The 'initialize' method is not implemented for the current provider."
|
11
|
+
end
|
12
|
+
|
9
13
|
def evaluate(_payload)
|
10
14
|
raise NoMethodError, "The 'evaluate' method is not implemented for the current provider."
|
11
15
|
end
|
@@ -9,6 +9,8 @@ module NanoBot
|
|
9
9
|
module Components
|
10
10
|
module Providers
|
11
11
|
class OpenAI < Base
|
12
|
+
DEFAULT_ADDRESS = 'https://api.openai.com'
|
13
|
+
|
12
14
|
CHAT_SETTINGS = %i[
|
13
15
|
model stream temperature top_p n stop max_tokens
|
14
16
|
presence_penalty frequency_penalty logit_bias
|
@@ -16,14 +18,18 @@ module NanoBot
|
|
16
18
|
|
17
19
|
attr_reader :settings
|
18
20
|
|
19
|
-
def initialize(settings, environment: {})
|
21
|
+
def initialize(settings, credentials, environment: {})
|
20
22
|
@settings = settings
|
23
|
+
@credentials = credentials
|
21
24
|
@environment = environment
|
22
25
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
26
|
+
uri_base = if @credentials[:address].nil? || @credentials[:address].to_s.strip.empty?
|
27
|
+
"#{DEFAULT_ADDRESS}/"
|
28
|
+
else
|
29
|
+
"#{@credentials[:address].to_s.sub(%r{/$}, '')}/"
|
30
|
+
end
|
31
|
+
|
32
|
+
@client = ::OpenAI::Client.new(uri_base:, access_token: @credentials[:'access-token'])
|
27
33
|
end
|
28
34
|
|
29
35
|
def stream(input)
|
@@ -48,16 +54,7 @@ module NanoBot
|
|
48
54
|
)
|
49
55
|
end
|
50
56
|
|
51
|
-
|
52
|
-
|
53
|
-
user_suffix = @environment && (
|
54
|
-
@environment['NANO_BOTS_USER_IDENTIFIER'] ||
|
55
|
-
@environment[:NANO_BOTS_USER_IDENTIFIER]
|
56
|
-
)
|
57
|
-
|
58
|
-
user = "#{user}/#{user_suffix}" if user_suffix && user_suffix != ''
|
59
|
-
|
60
|
-
payload = { model: @settings[:model], user: Crypto.encrypt(user, soft: true), messages: }
|
57
|
+
payload = { user: OpenAI.end_user(@settings, @environment), messages: }
|
61
58
|
|
62
59
|
CHAT_SETTINGS.each do |key|
|
63
60
|
payload[key] = @settings[key] if @settings.key?(key)
|
@@ -87,6 +84,27 @@ module NanoBot
|
|
87
84
|
block.call({ who: 'AI', message: result.dig('choices', 0, 'message', 'content') }, true)
|
88
85
|
end
|
89
86
|
end
|
87
|
+
|
88
|
+
def self.end_user(settings, environment)
|
89
|
+
user = ENV.fetch('NANO_BOTS_END_USER', nil)
|
90
|
+
|
91
|
+
user = settings[:user] if !settings[:user].nil? && !settings[:user].to_s.strip.empty?
|
92
|
+
|
93
|
+
candidate = environment && (
|
94
|
+
environment['NANO_BOTS_END_USER'] ||
|
95
|
+
environment[:NANO_BOTS_END_USER]
|
96
|
+
)
|
97
|
+
|
98
|
+
user = candidate if !candidate.nil? && !candidate.to_s.strip.empty?
|
99
|
+
|
100
|
+
user = if user.nil? || user.to_s.strip.empty?
|
101
|
+
'unknown'
|
102
|
+
else
|
103
|
+
user.to_s.strip
|
104
|
+
end
|
105
|
+
|
106
|
+
Crypto.encrypt(user, soft: true)
|
107
|
+
end
|
90
108
|
end
|
91
109
|
end
|
92
110
|
end
|
data/components/storage.rb
CHANGED
@@ -8,6 +8,31 @@ require_relative './crypto'
|
|
8
8
|
module NanoBot
|
9
9
|
module Components
|
10
10
|
class Storage
|
11
|
+
def self.end_user(cartridge, environment)
|
12
|
+
user = ENV.fetch('NANO_BOTS_END_USER', nil)
|
13
|
+
|
14
|
+
if cartridge[:provider][:id] == 'openai' &&
|
15
|
+
!cartridge[:provider][:settings][:user].nil? &&
|
16
|
+
!cartridge[:provider][:settings][:user].to_s.strip.empty?
|
17
|
+
user = cartridge[:provider][:settings][:user]
|
18
|
+
end
|
19
|
+
|
20
|
+
candidate = environment && (
|
21
|
+
environment['NANO_BOTS_END_USER'] ||
|
22
|
+
environment[:NANO_BOTS_END_USER]
|
23
|
+
)
|
24
|
+
|
25
|
+
user = candidate if !candidate.nil? && !candidate.to_s.strip.empty?
|
26
|
+
|
27
|
+
user = if user.nil? || user.to_s.strip.empty?
|
28
|
+
'unknown'
|
29
|
+
else
|
30
|
+
user.to_s.strip
|
31
|
+
end
|
32
|
+
|
33
|
+
Crypto.encrypt(user, soft: true)
|
34
|
+
end
|
35
|
+
|
11
36
|
def self.build_path_and_ensure_state_file!(key, cartridge, environment: {})
|
12
37
|
path = [
|
13
38
|
Logic::Helpers::Hash.fetch(cartridge, %i[state directory]),
|
@@ -18,27 +43,12 @@ module NanoBot
|
|
18
43
|
|
19
44
|
path = "#{user_home!.sub(%r{/$}, '')}/.local/state/nano-bots" if path.nil?
|
20
45
|
|
21
|
-
|
22
|
-
environment['NANO_BOTS_USER_IDENTIFIER'] ||
|
23
|
-
environment[:NANO_BOTS_USER_IDENTIFIER]
|
24
|
-
)
|
25
|
-
|
26
|
-
path = "#{path.sub(%r{/$}, '')}/ruby-nano-bots/vault"
|
27
|
-
|
28
|
-
if prefix
|
29
|
-
normalized = prefix.split('/').map do |part|
|
30
|
-
Crypto.encrypt(
|
31
|
-
part.to_s.gsub('.', '-').force_encoding('UTF-8').to_slug.normalize,
|
32
|
-
soft: true
|
33
|
-
)
|
34
|
-
end.join('/')
|
35
|
-
|
36
|
-
path = "#{path}/#{normalized}"
|
37
|
-
end
|
46
|
+
path = "#{path.sub(%r{/$}, '')}/ruby-nano-bots"
|
38
47
|
|
39
48
|
path = "#{path}/#{cartridge[:meta][:author].to_slug.normalize}"
|
40
49
|
path = "#{path}/#{cartridge[:meta][:name].to_slug.normalize}"
|
41
50
|
path = "#{path}/#{cartridge[:meta][:version].to_s.gsub('.', '-').to_slug.normalize}"
|
51
|
+
path = "#{path}/#{end_user(cartridge, environment)}"
|
42
52
|
path = "#{path}/#{Crypto.encrypt(key, soft: true)}"
|
43
53
|
path = "#{path}/state.json"
|
44
54
|
|
data/controllers/security.rb
CHANGED
@@ -9,6 +9,10 @@ module NanoBot
|
|
9
9
|
Components::Crypto.decrypt(content)
|
10
10
|
end
|
11
11
|
|
12
|
+
def self.encrypt(content, soft: false)
|
13
|
+
Components::Crypto.encrypt(content, soft:)
|
14
|
+
end
|
15
|
+
|
12
16
|
def self.check
|
13
17
|
password = ENV.fetch('NANO_BOTS_ENCRYPTION_PASSWORD', nil)
|
14
18
|
password = 'UNSAFE' unless password && password != ''
|
data/docker-compose.example.yml
CHANGED
@@ -3,12 +3,12 @@ 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.0
|
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.0 && bash"
|
7
7
|
environment:
|
8
|
-
NANO_BOTS_ENCRYPTION_PASSWORD: UNSAFE
|
9
8
|
OPENAI_API_ADDRESS: https://api.openai.com
|
10
|
-
|
11
|
-
|
9
|
+
OPENAI_API_KEY: your-access-token
|
10
|
+
NANO_BOTS_ENCRYPTION_PASSWORD: UNSAFE
|
11
|
+
NANO_BOTS_END_USER: your-user
|
12
12
|
volumes:
|
13
|
-
- ./your-cartridges
|
14
|
-
|
13
|
+
- ./your-cartridges:/.local/share/nano-bots/cartridges
|
14
|
+
- ./your-state:/.local/state/nano-bots
|
@@ -1,14 +1,17 @@
|
|
1
1
|
---
|
2
2
|
meta:
|
3
|
+
symbol: 🤖
|
3
4
|
name: Unknown
|
4
|
-
author:
|
5
|
+
author: None
|
5
6
|
version: 0.0.0
|
7
|
+
license: CC0-1.0
|
8
|
+
description: Unknown
|
6
9
|
|
7
10
|
provider:
|
8
|
-
|
11
|
+
id: openai
|
12
|
+
credentials:
|
13
|
+
address: ENV/OPENAI_API_ADDRESS
|
14
|
+
access-token: ENV/OPENAI_API_KEY
|
9
15
|
settings:
|
16
|
+
user: ENV/NANO_BOTS_END_USER
|
10
17
|
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.1.0',
|
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.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- icebaker
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-06-
|
11
|
+
date: 2023-06-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: babosa
|