nano-bots 3.2.0 → 3.4.0
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/Gemfile.lock +9 -4
- data/README.md +87 -15
- data/components/embedding.rb +10 -2
- data/components/provider.rb +3 -0
- data/components/providers/anthropic.rb +114 -0
- data/components/providers/cohere.rb +4 -3
- data/components/providers/google.rb +6 -1
- data/components/providers/maritaca.rb +2 -1
- data/components/providers/mistral.rb +2 -1
- data/components/providers/ollama.rb +6 -3
- data/components/storage.rb +2 -12
- data/controllers/session.rb +12 -2
- data/docker-compose.example.yml +4 -1
- data/logic/cartridge/streaming.rb +1 -1
- data/logic/providers/anthropic/tokens.rb +14 -0
- data/nano-bots.gemspec +2 -1
- data/static/fennel/fennel.lua +1587 -1179
- data/static/gem.rb +3 -3
- metadata +22 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 12888eb352fa3d3a744e0d4be79073bde3325bc795e13f0bbe60d6b6d0143105
|
4
|
+
data.tar.gz: 644af12193710d8484e3802d8ff5f976fb37d88c29bdcb25bbfc0f59df153a90
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0cbda4335fcd2508e0735bd1a1034aea1588f0b944d145ffb0a2c63211c227aa0c855790bc45813c4dcabc97f062fbd26c3c211f405a0bc52b7048ad8ce113fb
|
7
|
+
data.tar.gz: e08dabe3aae2bd9501bd9087ebaaf3b243afb3580ca09ce08be2a42b58e9bb3187d2a27df3d4db9e992294ec841e301192af0196fc4daebc8aa5b7dca56eaa3b
|
data/Gemfile.lock
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
nano-bots (3.
|
4
|
+
nano-bots (3.4.0)
|
5
|
+
anthropic (~> 0.3.0)
|
5
6
|
babosa (~> 2.0)
|
6
7
|
cohere-ai (~> 1.1)
|
7
8
|
concurrent-ruby (~> 1.3, >= 1.3.3)
|
8
9
|
dotenv (~> 3.1, >= 3.1.2)
|
9
10
|
faraday (~> 2.9, >= 2.9.2)
|
10
11
|
faraday-typhoeus (~> 1.1)
|
11
|
-
gemini-ai (~> 4.
|
12
|
+
gemini-ai (~> 4.1)
|
12
13
|
maritaca-ai (~> 1.2)
|
13
14
|
mistral-ai (~> 1.2)
|
14
15
|
ollama-ai (~> 1.2, >= 1.2.1)
|
@@ -25,6 +26,10 @@ GEM
|
|
25
26
|
specs:
|
26
27
|
addressable (2.8.7)
|
27
28
|
public_suffix (>= 2.0.2, < 7.0)
|
29
|
+
anthropic (0.3.0)
|
30
|
+
event_stream_parser (>= 0.3.0, < 2.0.0)
|
31
|
+
faraday (>= 1)
|
32
|
+
faraday-multipart (>= 1)
|
28
33
|
ast (2.4.2)
|
29
34
|
babosa (2.0.0)
|
30
35
|
base64 (0.2.0)
|
@@ -49,9 +54,9 @@ GEM
|
|
49
54
|
faraday (~> 2.0)
|
50
55
|
typhoeus (~> 1.4)
|
51
56
|
ffi (1.17.0)
|
52
|
-
gemini-ai (4.
|
57
|
+
gemini-ai (4.1.0)
|
53
58
|
event_stream_parser (~> 1.0)
|
54
|
-
faraday (~> 2.9)
|
59
|
+
faraday (~> 2.9, >= 2.9.2)
|
55
60
|
faraday-typhoeus (~> 1.1)
|
56
61
|
googleauth (~> 1.8)
|
57
62
|
typhoeus (~> 1.4, >= 1.4.1)
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Nano Bots 💎 🤖
|
2
2
|
|
3
|
-
An implementation of the [Nano Bots](https://spec.nbots.io) specification with support for [Cohere Command](https://cohere.com), [Google Gemini](https://deepmind.google/technologies/gemini), [Maritaca AI
|
3
|
+
An implementation of the [Nano Bots](https://spec.nbots.io) specification with support for [Anthropic Claude](https://www.anthropic.com/claude), [Cohere Command](https://cohere.com), [Google Gemini](https://deepmind.google/technologies/gemini), [Maritaca AI Sabiá](https://www.maritaca.ai), [Mistral AI](https://mistral.ai), [Ollama](https://ollama.ai), [OpenAI ChatGPT](https://openai.com/chatgpt), and others, with support for calling tools (functions).
|
4
4
|
|
5
5
|

|
6
6
|
|
@@ -9,7 +9,7 @@ https://user-images.githubusercontent.com/113217272/238141567-c58a240c-7b67-4b3b
|
|
9
9
|
## TL;DR and Quick Start
|
10
10
|
|
11
11
|
```sh
|
12
|
-
gem install nano-bots -v 3.
|
12
|
+
gem install nano-bots -v 3.4.0
|
13
13
|
```
|
14
14
|
|
15
15
|
```bash
|
@@ -59,7 +59,7 @@ nb gpt.yml - eval "hi"
|
|
59
59
|
```
|
60
60
|
|
61
61
|
```ruby
|
62
|
-
gem 'nano-bots', '~> 3.
|
62
|
+
gem 'nano-bots', '~> 3.4.0'
|
63
63
|
```
|
64
64
|
|
65
65
|
```ruby
|
@@ -80,6 +80,7 @@ end
|
|
80
80
|
- [Debugging](#debugging)
|
81
81
|
- [Library](#library)
|
82
82
|
- [Setup](#setup)
|
83
|
+
- [Anthropic Claude](#anthropic-claude)
|
83
84
|
- [Cohere Command](#cohere-command)
|
84
85
|
- [Maritaca AI MariTalk](#maritaca-ai-maritalk)
|
85
86
|
- [Mistral AI](#mistral-ai)
|
@@ -100,6 +101,7 @@ end
|
|
100
101
|
- [Decrypting](#decrypting)
|
101
102
|
- [Supported Providers](#supported-providers)
|
102
103
|
- [Docker](#docker)
|
104
|
+
- [Anthropic Claude Container](#anthropic-claude-container)
|
103
105
|
- [Cohere Command Container](#cohere-command-container)
|
104
106
|
- [Maritaca AI MariTalk Container](#maritaca-ai-maritalk-container)
|
105
107
|
- [Mistral AI Container](#mistral-ai-container)
|
@@ -250,13 +252,13 @@ end
|
|
250
252
|
To install the CLI on your system:
|
251
253
|
|
252
254
|
```sh
|
253
|
-
gem install nano-bots -v 3.
|
255
|
+
gem install nano-bots -v 3.4.0
|
254
256
|
```
|
255
257
|
|
256
258
|
To use it in a Ruby project as a library, add to your `Gemfile`:
|
257
259
|
|
258
260
|
```ruby
|
259
|
-
gem 'nano-bots', '~> 3.
|
261
|
+
gem 'nano-bots', '~> 3.4.0'
|
260
262
|
```
|
261
263
|
|
262
264
|
```sh
|
@@ -283,6 +285,59 @@ NANO_BOTS_END_USER=your-user
|
|
283
285
|
# NANO_BOTS_CARTRIDGES_PATH=/home/user/.local/share/nano-bots/cartridges
|
284
286
|
```
|
285
287
|
|
288
|
+
### Anthropic Claude
|
289
|
+
|
290
|
+
You can obtain your credentials on the [Anthropic Console](https://console.anthropic.com).
|
291
|
+
|
292
|
+
```sh
|
293
|
+
export ANTHROPIC_API_KEY=your-api-key
|
294
|
+
```
|
295
|
+
|
296
|
+
Alternatively, if your current directory has a `.env` file with the environment variables, they will be automatically loaded:
|
297
|
+
|
298
|
+
```sh
|
299
|
+
ANTHROPIC_API_KEY=your-api-key
|
300
|
+
```
|
301
|
+
|
302
|
+
Create a `cartridge.yml` file:
|
303
|
+
|
304
|
+
```yaml
|
305
|
+
---
|
306
|
+
meta:
|
307
|
+
symbol: 🤖
|
308
|
+
name: Nano Bot Name
|
309
|
+
author: Your Name
|
310
|
+
version: 1.0.0
|
311
|
+
license: CC0-1.0
|
312
|
+
description: A helpful assistant.
|
313
|
+
|
314
|
+
behaviors:
|
315
|
+
interaction:
|
316
|
+
directive: You are a helpful assistant.
|
317
|
+
|
318
|
+
provider:
|
319
|
+
id: anthropic
|
320
|
+
credentials:
|
321
|
+
api-key: ENV/ANTHROPIC_API_KEY
|
322
|
+
settings:
|
323
|
+
model: claude-3-5-sonnet-20240620
|
324
|
+
max_tokens: 4096
|
325
|
+
```
|
326
|
+
|
327
|
+
Read the [full specification](https://spec.nbots.io/#/README?id=anthropic-claude) for Anthropic Claude.
|
328
|
+
|
329
|
+
```bash
|
330
|
+
nb cartridge.yml - eval "Hello"
|
331
|
+
|
332
|
+
nb cartridge.yml - repl
|
333
|
+
```
|
334
|
+
|
335
|
+
```ruby
|
336
|
+
bot = NanoBot.new(cartridge: 'cartridge.yml')
|
337
|
+
|
338
|
+
puts bot.eval('Hello')
|
339
|
+
```
|
340
|
+
|
286
341
|
### Cohere Command
|
287
342
|
|
288
343
|
You can obtain your credentials on the [Cohere Platform](https://dashboard.cohere.com).
|
@@ -939,7 +994,7 @@ If you lose your password, you lose your data. It is not possible to recover it
|
|
939
994
|
|
940
995
|
## Supported Providers
|
941
996
|
|
942
|
-
- [
|
997
|
+
- [x] [Anthropic Claude](https://www.anthropic.com)
|
943
998
|
- [x] [Cohere Command](https://cohere.com)
|
944
999
|
- [x] [Google Gemini](https://deepmind.google/technologies/gemini)
|
945
1000
|
- [x] [Maritaca AI MariTalk](https://www.maritaca.ai)
|
@@ -965,6 +1020,23 @@ cp docker-compose.example.yml docker-compose.yml
|
|
965
1020
|
|
966
1021
|
Set your provider credentials and choose your desired path for the cartridges files:
|
967
1022
|
|
1023
|
+
### Anthropic Claude Container
|
1024
|
+
|
1025
|
+
```yaml
|
1026
|
+
---
|
1027
|
+
services:
|
1028
|
+
nano-bots:
|
1029
|
+
image: ruby:3.3.3-slim-bookworm
|
1030
|
+
command: sh -c "apt-get update && apt-get install -y --no-install-recommends build-essential libffi-dev libsodium-dev lua5.4-dev curl && curl -s https://raw.githubusercontent.com/babashka/babashka/master/install | bash && gem install nano-bots -v 3.4.0 && bash"
|
1031
|
+
environment:
|
1032
|
+
ANTHROPIC_API_KEY: your-api-key
|
1033
|
+
NANO_BOTS_ENCRYPTION_PASSWORD: UNSAFE
|
1034
|
+
NANO_BOTS_END_USER: your-user
|
1035
|
+
volumes:
|
1036
|
+
- ./your-cartridges:/root/.local/share/nano-bots/cartridges
|
1037
|
+
- ./your-state-path:/root/.local/state/nano-bots
|
1038
|
+
```
|
1039
|
+
|
968
1040
|
### Cohere Command Container
|
969
1041
|
|
970
1042
|
```yaml
|
@@ -972,7 +1044,7 @@ Set your provider credentials and choose your desired path for the cartridges fi
|
|
972
1044
|
services:
|
973
1045
|
nano-bots:
|
974
1046
|
image: ruby:3.3.3-slim-bookworm
|
975
|
-
command: sh -c "apt-get update && apt-get install -y --no-install-recommends build-essential libffi-dev libsodium-dev lua5.4-dev curl && curl -s https://raw.githubusercontent.com/babashka/babashka/master/install | bash && gem install nano-bots -v 3.
|
1047
|
+
command: sh -c "apt-get update && apt-get install -y --no-install-recommends build-essential libffi-dev libsodium-dev lua5.4-dev curl && curl -s https://raw.githubusercontent.com/babashka/babashka/master/install | bash && gem install nano-bots -v 3.4.0 && bash"
|
976
1048
|
environment:
|
977
1049
|
COHERE_API_KEY: your-api-key
|
978
1050
|
NANO_BOTS_ENCRYPTION_PASSWORD: UNSAFE
|
@@ -989,7 +1061,7 @@ services:
|
|
989
1061
|
services:
|
990
1062
|
nano-bots:
|
991
1063
|
image: ruby:3.3.3-slim-bookworm
|
992
|
-
command: sh -c "apt-get update && apt-get install -y --no-install-recommends build-essential libffi-dev libsodium-dev lua5.4-dev curl && curl -s https://raw.githubusercontent.com/babashka/babashka/master/install | bash && gem install nano-bots -v 3.
|
1064
|
+
command: sh -c "apt-get update && apt-get install -y --no-install-recommends build-essential libffi-dev libsodium-dev lua5.4-dev curl && curl -s https://raw.githubusercontent.com/babashka/babashka/master/install | bash && gem install nano-bots -v 3.4.0 && bash"
|
993
1065
|
environment:
|
994
1066
|
MARITACA_API_KEY: your-api-key
|
995
1067
|
NANO_BOTS_ENCRYPTION_PASSWORD: UNSAFE
|
@@ -1006,7 +1078,7 @@ services:
|
|
1006
1078
|
services:
|
1007
1079
|
nano-bots:
|
1008
1080
|
image: ruby:3.3.3-slim-bookworm
|
1009
|
-
command: sh -c "apt-get update && apt-get install -y --no-install-recommends build-essential libffi-dev libsodium-dev lua5.4-dev curl && curl -s https://raw.githubusercontent.com/babashka/babashka/master/install | bash && gem install nano-bots -v 3.
|
1081
|
+
command: sh -c "apt-get update && apt-get install -y --no-install-recommends build-essential libffi-dev libsodium-dev lua5.4-dev curl && curl -s https://raw.githubusercontent.com/babashka/babashka/master/install | bash && gem install nano-bots -v 3.4.0 && bash"
|
1010
1082
|
environment:
|
1011
1083
|
MISTRAL_API_KEY: your-api-key
|
1012
1084
|
NANO_BOTS_ENCRYPTION_PASSWORD: UNSAFE
|
@@ -1025,7 +1097,7 @@ Remember that your `localhost` is by default inaccessible from inside Docker. Yo
|
|
1025
1097
|
services:
|
1026
1098
|
nano-bots:
|
1027
1099
|
image: ruby:3.3.3-slim-bookworm
|
1028
|
-
command: sh -c "apt-get update && apt-get install -y --no-install-recommends build-essential libffi-dev libsodium-dev lua5.4-dev curl && curl -s https://raw.githubusercontent.com/babashka/babashka/master/install | bash && gem install nano-bots -v 3.
|
1100
|
+
command: sh -c "apt-get update && apt-get install -y --no-install-recommends build-essential libffi-dev libsodium-dev lua5.4-dev curl && curl -s https://raw.githubusercontent.com/babashka/babashka/master/install | bash && gem install nano-bots -v 3.4.0 && bash"
|
1029
1101
|
environment:
|
1030
1102
|
OLLAMA_API_ADDRESS: http://localhost:11434
|
1031
1103
|
NANO_BOTS_ENCRYPTION_PASSWORD: UNSAFE
|
@@ -1044,7 +1116,7 @@ services:
|
|
1044
1116
|
services:
|
1045
1117
|
nano-bots:
|
1046
1118
|
image: ruby:3.3.3-slim-bookworm
|
1047
|
-
command: sh -c "apt-get update && apt-get install -y --no-install-recommends build-essential libffi-dev libsodium-dev lua5.4-dev curl && curl -s https://raw.githubusercontent.com/babashka/babashka/master/install | bash && gem install nano-bots -v 3.
|
1119
|
+
command: sh -c "apt-get update && apt-get install -y --no-install-recommends build-essential libffi-dev libsodium-dev lua5.4-dev curl && curl -s https://raw.githubusercontent.com/babashka/babashka/master/install | bash && gem install nano-bots -v 3.4.0 && bash"
|
1048
1120
|
environment:
|
1049
1121
|
OPENAI_API_KEY: your-access-token
|
1050
1122
|
NANO_BOTS_ENCRYPTION_PASSWORD: UNSAFE
|
@@ -1063,7 +1135,7 @@ services:
|
|
1063
1135
|
services:
|
1064
1136
|
nano-bots:
|
1065
1137
|
image: ruby:3.3.3-slim-bookworm
|
1066
|
-
command: sh -c "apt-get update && apt-get install -y --no-install-recommends build-essential libffi-dev libsodium-dev lua5.4-dev curl && curl -s https://raw.githubusercontent.com/babashka/babashka/master/install | bash && gem install nano-bots -v 3.
|
1138
|
+
command: sh -c "apt-get update && apt-get install -y --no-install-recommends build-essential libffi-dev libsodium-dev lua5.4-dev curl && curl -s https://raw.githubusercontent.com/babashka/babashka/master/install | bash && gem install nano-bots -v 3.4.0 && bash"
|
1067
1139
|
environment:
|
1068
1140
|
GOOGLE_API_KEY: your-api-key
|
1069
1141
|
NANO_BOTS_ENCRYPTION_PASSWORD: UNSAFE
|
@@ -1080,7 +1152,7 @@ services:
|
|
1080
1152
|
services:
|
1081
1153
|
nano-bots:
|
1082
1154
|
image: ruby:3.3.3-slim-bookworm
|
1083
|
-
command: sh -c "apt-get update && apt-get install -y --no-install-recommends build-essential libffi-dev libsodium-dev lua5.4-dev curl && curl -s https://raw.githubusercontent.com/babashka/babashka/master/install | bash && gem install nano-bots -v 3.
|
1155
|
+
command: sh -c "apt-get update && apt-get install -y --no-install-recommends build-essential libffi-dev libsodium-dev lua5.4-dev curl && curl -s https://raw.githubusercontent.com/babashka/babashka/master/install | bash && gem install nano-bots -v 3.4.0 && bash"
|
1084
1156
|
environment:
|
1085
1157
|
GOOGLE_CREDENTIALS_FILE_PATH: /root/.config/google-credentials.json
|
1086
1158
|
GOOGLE_REGION: us-east4
|
@@ -1099,7 +1171,7 @@ services:
|
|
1099
1171
|
services:
|
1100
1172
|
nano-bots:
|
1101
1173
|
image: ruby:3.3.3-slim-bookworm
|
1102
|
-
command: sh -c "apt-get update && apt-get install -y --no-install-recommends build-essential libffi-dev libsodium-dev lua5.4-dev curl && curl -s https://raw.githubusercontent.com/babashka/babashka/master/install | bash && gem install nano-bots -v 3.
|
1174
|
+
command: sh -c "apt-get update && apt-get install -y --no-install-recommends build-essential libffi-dev libsodium-dev lua5.4-dev curl && curl -s https://raw.githubusercontent.com/babashka/babashka/master/install | bash && gem install nano-bots -v 3.4.0 && bash"
|
1103
1175
|
environment:
|
1104
1176
|
GOOGLE_REGION: us-east4
|
1105
1177
|
NANO_BOTS_ENCRYPTION_PASSWORD: UNSAFE
|
@@ -1161,5 +1233,5 @@ gem build nano-bots.gemspec
|
|
1161
1233
|
|
1162
1234
|
gem signin
|
1163
1235
|
|
1164
|
-
gem push nano-bots-3.
|
1236
|
+
gem push nano-bots-3.4.0.gem
|
1165
1237
|
```
|
data/components/embedding.rb
CHANGED
@@ -24,7 +24,11 @@ module NanoBot
|
|
24
24
|
|
25
25
|
state.eval(code)
|
26
26
|
embedded = state.get(:embedded)
|
27
|
-
|
27
|
+
begin
|
28
|
+
embedded.call(values)
|
29
|
+
rescue StandardError => e
|
30
|
+
e.message
|
31
|
+
end
|
28
32
|
end
|
29
33
|
|
30
34
|
def self.fennel(source:, parameters:, values:, safety:)
|
@@ -39,7 +43,11 @@ module NanoBot
|
|
39
43
|
safety[:sandboxed] ? { allowedGlobals: %w[math string table] } : nil
|
40
44
|
)
|
41
45
|
embedded = state.get(:embedded)
|
42
|
-
|
46
|
+
begin
|
47
|
+
embedded.call(values)
|
48
|
+
rescue StandardError => e
|
49
|
+
e.message
|
50
|
+
end
|
43
51
|
end
|
44
52
|
|
45
53
|
def self.clojure(source:, parameters:, values:, safety:)
|
data/components/provider.rb
CHANGED
@@ -4,6 +4,7 @@ require_relative 'providers/openai'
|
|
4
4
|
require_relative 'providers/ollama'
|
5
5
|
require_relative 'providers/mistral'
|
6
6
|
require_relative 'providers/google'
|
7
|
+
require_relative 'providers/anthropic'
|
7
8
|
require_relative 'providers/cohere'
|
8
9
|
require_relative 'providers/maritaca'
|
9
10
|
|
@@ -20,6 +21,8 @@ module NanoBot
|
|
20
21
|
Providers::Mistral.new(provider[:options], provider[:settings], provider[:credentials], environment:)
|
21
22
|
when 'google'
|
22
23
|
Providers::Google.new(provider[:options], provider[:settings], provider[:credentials], environment:)
|
24
|
+
when 'anthropic'
|
25
|
+
Providers::Anthropic.new(nil, provider[:settings], provider[:credentials], environment:)
|
23
26
|
when 'cohere'
|
24
27
|
Providers::Cohere.new(provider[:options], provider[:settings], provider[:credentials], environment:)
|
25
28
|
when 'maritaca'
|
@@ -0,0 +1,114 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'anthropic'
|
4
|
+
|
5
|
+
require_relative 'base'
|
6
|
+
|
7
|
+
require_relative '../../logic/providers/anthropic/tokens'
|
8
|
+
require_relative '../../logic/helpers/hash'
|
9
|
+
require_relative '../../logic/cartridge/default'
|
10
|
+
|
11
|
+
module NanoBot
|
12
|
+
module Components
|
13
|
+
module Providers
|
14
|
+
class Anthropic < Base
|
15
|
+
attr_reader :settings
|
16
|
+
|
17
|
+
CHAT_SETTINGS = %i[
|
18
|
+
model stream max_tokens temperature top_k top_p tool_choice
|
19
|
+
metadata stop_sequences
|
20
|
+
].freeze
|
21
|
+
|
22
|
+
def initialize(_options, settings, credentials, _environment)
|
23
|
+
@settings = settings
|
24
|
+
|
25
|
+
unless @settings.key?(:stream)
|
26
|
+
@settings = Marshal.load(Marshal.dump(@settings))
|
27
|
+
@settings[:stream] = Logic::Helpers::Hash.fetch(
|
28
|
+
Logic::Cartridge::Default.instance.values, %i[provider settings stream]
|
29
|
+
)
|
30
|
+
end
|
31
|
+
|
32
|
+
@client = ::Anthropic::Client.new(
|
33
|
+
access_token: credentials[:'api-key'],
|
34
|
+
anthropic_version: credentials[:'anthropic-version']
|
35
|
+
)
|
36
|
+
end
|
37
|
+
|
38
|
+
def evaluate(input, streaming, cartridge, &feedback)
|
39
|
+
messages = input[:history].map do |event|
|
40
|
+
{ role: event[:who] == 'user' ? 'user' : 'assistant',
|
41
|
+
content: event[:message],
|
42
|
+
_meta: { at: event[:at] } }
|
43
|
+
end
|
44
|
+
|
45
|
+
if input[:behavior][:backdrop]
|
46
|
+
messages.prepend(
|
47
|
+
{ role: 'assistant',
|
48
|
+
content: 'Ok.',
|
49
|
+
_meta: { at: Time.now } }
|
50
|
+
)
|
51
|
+
|
52
|
+
messages.prepend(
|
53
|
+
{ role: 'user',
|
54
|
+
content: input[:behavior][:backdrop],
|
55
|
+
_meta: { at: Time.now } }
|
56
|
+
)
|
57
|
+
end
|
58
|
+
|
59
|
+
payload = { messages: }
|
60
|
+
|
61
|
+
payload[:system] = input[:behavior][:directive] if input[:behavior][:directive]
|
62
|
+
|
63
|
+
CHAT_SETTINGS.each do |key|
|
64
|
+
payload[key] = @settings[key] unless payload.key?(key) || !@settings.key?(key)
|
65
|
+
end
|
66
|
+
|
67
|
+
raise 'Anthropic does not support tools.' if input[:tools]
|
68
|
+
|
69
|
+
if streaming
|
70
|
+
content = ''
|
71
|
+
|
72
|
+
stream_call_back = proc do |event|
|
73
|
+
partial_content = event.dig('delta', 'text')
|
74
|
+
|
75
|
+
if partial_content && event['type'] == 'content_block_delta'
|
76
|
+
content += partial_content
|
77
|
+
feedback.call(
|
78
|
+
{ should_be_stored: false,
|
79
|
+
interaction: { who: 'AI', message: partial_content } }
|
80
|
+
)
|
81
|
+
end
|
82
|
+
|
83
|
+
if event['type'] == 'content_block_stop'
|
84
|
+
feedback.call(
|
85
|
+
{ should_be_stored: !(content.nil? || content == ''),
|
86
|
+
interaction: content.nil? || content == '' ? nil : { who: 'AI', message: content },
|
87
|
+
finished: true }
|
88
|
+
)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
@client.messages(
|
93
|
+
parameters: Logic::Anthropic::Tokens.apply_policies!(
|
94
|
+
cartridge, payload
|
95
|
+
).merge({ stream: stream_call_back })
|
96
|
+
)
|
97
|
+
else
|
98
|
+
result = @client.messages(
|
99
|
+
parameters: Logic::Anthropic::Tokens.apply_policies!(cartridge, payload)
|
100
|
+
)
|
101
|
+
|
102
|
+
content = result['content'].map { |content| content['text'] }.join
|
103
|
+
|
104
|
+
feedback.call(
|
105
|
+
{ should_be_stored: !(content.nil? || content.to_s.strip == ''),
|
106
|
+
interaction: content.nil? || content == '' ? nil : { who: 'AI', message: content },
|
107
|
+
finished: true }
|
108
|
+
)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
@@ -15,9 +15,10 @@ module NanoBot
|
|
15
15
|
attr_reader :settings
|
16
16
|
|
17
17
|
CHAT_SETTINGS = %i[
|
18
|
-
model stream prompt_truncation connectors
|
19
|
-
|
20
|
-
|
18
|
+
model stream prompt_truncation connectors search_queries_only
|
19
|
+
documents citation_quality temperature max_tokens max_input_tokens
|
20
|
+
k p seed stop_sequences frequency_penalty presence_penalty
|
21
|
+
force_single_step
|
21
22
|
].freeze
|
22
23
|
|
23
24
|
def initialize(options, settings, credentials, _environment)
|
@@ -19,7 +19,9 @@ module NanoBot
|
|
19
19
|
|
20
20
|
SETTINGS = {
|
21
21
|
generationConfig: %i[
|
22
|
-
temperature
|
22
|
+
temperature maxOutputTokens candidateCount presencePenalty
|
23
|
+
frequencyPenalty topK topP stopSequences
|
24
|
+
responseMimeType responseSchema
|
23
25
|
].freeze
|
24
26
|
}.freeze
|
25
27
|
|
@@ -154,6 +156,9 @@ module NanoBot
|
|
154
156
|
if event.dig('candidates', 0, 'finishReason') == 'SAFETY'
|
155
157
|
reasons = event.dig('candidates', 0, 'safetyRatings')
|
156
158
|
raise StandardError, "Generation stopped for safety reasons: #{reasons}"
|
159
|
+
elsif event.dig('candidates', 0, 'finishReason') == 'RECITATION'
|
160
|
+
reasons = event.dig('candidates', 0, 'citationMetadata')
|
161
|
+
raise StandardError, "Generation stopped for recitation reasons: #{reasons}"
|
157
162
|
end
|
158
163
|
end
|
159
164
|
|
@@ -15,7 +15,8 @@ module NanoBot
|
|
15
15
|
attr_reader :settings
|
16
16
|
|
17
17
|
CHAT_SETTINGS = %i[
|
18
|
-
|
18
|
+
stream model max_tokens do_sample temperature top_p
|
19
|
+
repetition_penalty num_tokens_per_message stopping_tokens
|
19
20
|
].freeze
|
20
21
|
|
21
22
|
def initialize(options, settings, credentials, _environment)
|
@@ -15,7 +15,8 @@ module NanoBot
|
|
15
15
|
attr_reader :settings
|
16
16
|
|
17
17
|
CHAT_SETTINGS = %i[
|
18
|
-
model temperature top_p max_tokens stream
|
18
|
+
model temperature top_p max_tokens stream safe_prompt random_seed
|
19
|
+
safe_mode
|
19
20
|
].freeze
|
20
21
|
|
21
22
|
def initialize(options, settings, credentials, _environment)
|
@@ -15,12 +15,15 @@ module NanoBot
|
|
15
15
|
attr_reader :settings
|
16
16
|
|
17
17
|
CHAT_SETTINGS = %i[
|
18
|
-
model template stream
|
18
|
+
model template stream format raw
|
19
19
|
].freeze
|
20
20
|
|
21
21
|
CHAT_OPTIONS = %i[
|
22
|
-
|
23
|
-
|
22
|
+
num_keep seed num_predict top_k top_p tfs_z typical_p repeat_last_n
|
23
|
+
temperature repeat_penalty presence_penalty frequency_penalty
|
24
|
+
mirostat mirostat_tau mirostat_eta penalize_newline numa num_ctx
|
25
|
+
num_batch num_gpu main_gpu low_vram f16_kv vocab_only use_mmap
|
26
|
+
use_mlock num_thread stop
|
24
27
|
].freeze
|
25
28
|
|
26
29
|
def initialize(options, settings, credentials, _environment)
|
data/components/storage.rb
CHANGED
@@ -35,7 +35,7 @@ module NanoBot
|
|
35
35
|
Crypto.encrypt(user, soft: true)
|
36
36
|
end
|
37
37
|
|
38
|
-
def self.
|
38
|
+
def self.build_path_for_state_file(key, cartridge, environment: {})
|
39
39
|
path = [
|
40
40
|
Logic::Helpers::Hash.fetch(cartridge, %i[state path]),
|
41
41
|
Logic::Helpers::Hash.fetch(cartridge, %i[state directory]),
|
@@ -54,18 +54,8 @@ module NanoBot
|
|
54
54
|
path = "#{path}/#{cartridge[:meta][:version].to_s.gsub('.', '-').to_slug.normalize}"
|
55
55
|
path = "#{path}/#{end_user(cartridge, environment)}"
|
56
56
|
path = "#{path}/#{Crypto.encrypt(key, soft: true)}"
|
57
|
-
path = "#{path}/state.json"
|
58
57
|
|
59
|
-
|
60
|
-
|
61
|
-
unless File.exist?(path)
|
62
|
-
File.write(
|
63
|
-
path,
|
64
|
-
Crypto.encrypt(JSON.generate({ key:, history: [] }))
|
65
|
-
)
|
66
|
-
end
|
67
|
-
|
68
|
-
path
|
58
|
+
"#{path}/state.json"
|
69
59
|
end
|
70
60
|
|
71
61
|
def self.cartridges_path(components: {})
|
data/controllers/session.rb
CHANGED
@@ -34,7 +34,9 @@ module NanoBot
|
|
34
34
|
if @stateless
|
35
35
|
@state = { history: [] }
|
36
36
|
else
|
37
|
-
@
|
37
|
+
@state_key = state.strip
|
38
|
+
|
39
|
+
@state_path = Components::Storage.build_path_for_state_file(
|
38
40
|
state.strip, @cartridge, environment:
|
39
41
|
)
|
40
42
|
|
@@ -43,16 +45,24 @@ module NanoBot
|
|
43
45
|
end
|
44
46
|
|
45
47
|
def state
|
46
|
-
|
48
|
+
if @state[:history].empty?
|
49
|
+
nil
|
50
|
+
else
|
51
|
+
{ state: { path: @state_path, content: @state } }
|
52
|
+
end
|
47
53
|
end
|
48
54
|
|
49
55
|
def load_state
|
56
|
+
return { key: @state_key, history: [] } unless File.exist?(@state_path)
|
57
|
+
|
50
58
|
@state = Logic::Helpers::Hash.symbolize_keys(
|
51
59
|
JSON.parse(Components::Crypto.decrypt(File.read(@state_path)))
|
52
60
|
)
|
53
61
|
end
|
54
62
|
|
55
63
|
def store_state!
|
64
|
+
FileUtils.mkdir_p(File.dirname(@state_path)) unless File.exist?(@state_path)
|
65
|
+
|
56
66
|
File.write(@state_path, Components::Crypto.encrypt(JSON.generate(@state)))
|
57
67
|
end
|
58
68
|
|
data/docker-compose.example.yml
CHANGED
@@ -2,13 +2,16 @@
|
|
2
2
|
services:
|
3
3
|
nano-bots:
|
4
4
|
image: ruby:3.3.3-slim-bookworm
|
5
|
-
command: sh -c "apt-get update && apt-get install -y --no-install-recommends build-essential libffi-dev libsodium-dev lua5.4-dev curl && curl -s https://raw.githubusercontent.com/babashka/babashka/master/install | bash && gem install nano-bots -v 3.
|
5
|
+
command: sh -c "apt-get update && apt-get install -y --no-install-recommends build-essential libffi-dev libsodium-dev lua5.4-dev curl && curl -s https://raw.githubusercontent.com/babashka/babashka/master/install | bash && gem install nano-bots -v 3.4.0 && bash"
|
6
6
|
environment:
|
7
|
+
ANTHROPIC_API_KEY: your-api-key
|
8
|
+
|
7
9
|
COHERE_API_KEY: your-api-key
|
8
10
|
|
9
11
|
# GOOGLE_API_KEY: your-api-key
|
10
12
|
|
11
13
|
# GOOGLE_CREDENTIALS_FILE_PATH: /root/.config/google-credentials.json
|
14
|
+
# GOOGLE_CREDENTIALS_FILE_CONTENTS: "contents"
|
12
15
|
# GOOGLE_PROJECT_ID: your-project-id
|
13
16
|
GOOGLE_REGION: us-east4
|
14
17
|
|
@@ -8,7 +8,7 @@ module NanoBot
|
|
8
8
|
module Streaming
|
9
9
|
def self.enabled?(cartridge, interface)
|
10
10
|
provider_stream = case Helpers::Hash.fetch(cartridge, %i[provider id])
|
11
|
-
when 'openai', 'mistral', 'cohere', 'ollama'
|
11
|
+
when 'openai', 'mistral', 'anthropic', 'cohere', 'ollama'
|
12
12
|
Helpers::Hash.fetch(cartridge, %i[provider settings stream])
|
13
13
|
when 'google', 'maritaca'
|
14
14
|
Helpers::Hash.fetch(cartridge, %i[provider options stream])
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module NanoBot
|
4
|
+
module Logic
|
5
|
+
module Anthropic
|
6
|
+
module Tokens
|
7
|
+
def self.apply_policies!(_cartridge, payload)
|
8
|
+
payload[:messages] = payload[:messages].map { |message| message.except(:_meta) }
|
9
|
+
payload
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/nano-bots.gemspec
CHANGED
@@ -40,8 +40,9 @@ Gem::Specification.new do |spec|
|
|
40
40
|
spec.add_dependency 'redcarpet', '~> 3.6'
|
41
41
|
spec.add_dependency 'sweet-moon', '~> 1.0'
|
42
42
|
|
43
|
+
spec.add_dependency 'anthropic', '~> 0.3.0'
|
43
44
|
spec.add_dependency 'cohere-ai', '~> 1.1'
|
44
|
-
spec.add_dependency 'gemini-ai', '~> 4.
|
45
|
+
spec.add_dependency 'gemini-ai', '~> 4.1'
|
45
46
|
spec.add_dependency 'maritaca-ai', '~> 1.2'
|
46
47
|
spec.add_dependency 'mistral-ai', '~> 1.2'
|
47
48
|
spec.add_dependency 'ollama-ai', '~> 1.2', '>= 1.2.1'
|