summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoricebaker <113217272+icebaker@users.noreply.github.com>2023-12-16 11:58:47 -0300
committerGitHub <noreply@github.com>2023-12-16 11:58:47 -0300
commite68499587cc2ef6205aa01e13af0b520fdcc8edf (patch)
treebb7ee0e35be9202144240b3edcbcbc024bbc0f8e
parent5ea806de5d021a7f86d18c3d74bf521a3ba05ccd (diff)
parent57f44096dd22c32b2575268a00fd467469400d44 (diff)
Merge pull request #10 from icebaker/ib-gemini-stream
Gemini Stream Issues and System Messages Support
-rw-r--r--Gemfile.lock6
-rw-r--r--README.md110
-rw-r--r--components/providers/google.rb62
-rw-r--r--nano-bots.gemspec2
-rw-r--r--ports/dsl/nano-bots.rb4
-rw-r--r--static/gem.rb1
6 files changed, 137 insertions, 48 deletions
diff --git a/Gemfile.lock b/Gemfile.lock
index 92d16fa..bcbb07b 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -5,7 +5,7 @@ PATH
babosa (~> 2.0)
concurrent-ruby (~> 1.2, >= 1.2.2)
dotenv (~> 2.8, >= 2.8.1)
- gemini-ai (~> 2.0)
+ gemini-ai (~> 2.1)
pry (~> 0.14.2)
rainbow (~> 3.1, >= 3.1.1)
rbnacl (~> 7.1, >= 7.1.1)
@@ -34,7 +34,7 @@ GEM
multipart-post (~> 2)
faraday-net_http (3.0.2)
ffi (1.16.3)
- gemini-ai (2.0.0)
+ gemini-ai (2.1.0)
event_stream_parser (~> 1.0)
faraday (~> 2.7, >= 2.7.12)
googleauth (~> 1.9, >= 1.9.1)
@@ -54,7 +54,7 @@ GEM
multi_json (1.15.0)
multipart-post (2.3.0)
os (1.1.4)
- parallel (1.23.0)
+ parallel (1.24.0)
parser (3.2.2.4)
ast (~> 2.4.1)
racc
diff --git a/README.md b/README.md
index 867e8f7..3ed58bc 100644
--- a/README.md
+++ b/README.md
@@ -105,11 +105,10 @@ NANO_BOTS_END_USER=your-user
# NANO_BOTS_CARTRIDGES_DIRECTORY=/home/user/.local/share/nano-bots/cartridges
```
-#### Option 2: Service Account (Vertex AI API)
+#### Option 2: Service Account Credentials File (Vertex AI API)
```sh
export GOOGLE_CREDENTIALS_FILE_PATH=google-credentials.json
-export GOOGLE_PROJECT_ID=your-project-id
export GOOGLE_REGION=us-east4
export NANO_BOTS_ENCRYPTION_PASSWORD=UNSAFE
@@ -123,7 +122,6 @@ Alternatively, if your current directory has a `.env` file with the environment
```sh
GOOGLE_CREDENTIALS_FILE_PATH=google-credentials.json
-GOOGLE_PROJECT_ID=your-project-id
GOOGLE_REGION=us-east4
NANO_BOTS_ENCRYPTION_PASSWORD=UNSAFE
@@ -133,6 +131,44 @@ NANO_BOTS_END_USER=your-user
# NANO_BOTS_CARTRIDGES_DIRECTORY=/home/user/.local/share/nano-bots/cartridges
```
+#### Option 3: Application Default Credentials (Vertex AI API)
+
+```sh
+export GOOGLE_REGION=us-east4
+
+export NANO_BOTS_ENCRYPTION_PASSWORD=UNSAFE
+export NANO_BOTS_END_USER=your-user
+
+# export NANO_BOTS_STATE_DIRECTORY=/home/user/.local/state/nano-bots
+# export NANO_BOTS_CARTRIDGES_DIRECTORY=/home/user/.local/share/nano-bots/cartridges
+```
+
+Alternatively, if your current directory has a `.env` file with the environment variables, they will be automatically loaded:
+
+```sh
+GOOGLE_REGION=us-east4
+
+NANO_BOTS_ENCRYPTION_PASSWORD=UNSAFE
+NANO_BOTS_END_USER=your-user
+
+# NANO_BOTS_STATE_DIRECTORY=/home/user/.local/state/nano-bots
+# NANO_BOTS_CARTRIDGES_DIRECTORY=/home/user/.local/share/nano-bots/cartridges
+```
+
+#### Custom Project ID
+
+If you need to manually set a Google Project ID:
+
+```sh
+export GOOGLE_PROJECT_ID=your-project-id
+```
+
+Alternatively, if your current directory has a `.env` file with the environment variables, they will be automatically loaded:
+
+```sh
+GOOGLE_PROJECT_ID=your-project-id
+```
+
## Docker
Clone the repository and copy the Docker Compose template:
@@ -182,7 +218,7 @@ services:
- ./your-state-path:/root/.local/state/nano-bots
```
-#### Option 2: Service Account (Vertex AI API)
+#### Option 2: Service Account Credentials File (Vertex AI API)
```yaml
---
@@ -192,7 +228,6 @@ services:
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 2.0.0 && bash"
environment:
GOOGLE_CREDENTIALS_FILE_PATH: /root/.config/google-credentials.json
- GOOGLE_PROJECT_ID: your-project-id
GOOGLE_REGION: us-east4
NANO_BOTS_ENCRYPTION_PASSWORD: UNSAFE
NANO_BOTS_END_USER: your-user
@@ -202,6 +237,31 @@ services:
- ./your-state-path:/root/.local/state/nano-bots
```
+#### Option 3: Application Default Credentials (Vertex AI API)
+
+```yaml
+---
+services:
+ nano-bots:
+ image: ruby:3.2.2-slim-bookworm
+ 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 2.0.0 && bash"
+ environment:
+ GOOGLE_REGION: us-east4
+ NANO_BOTS_ENCRYPTION_PASSWORD: UNSAFE
+ NANO_BOTS_END_USER: your-user
+ volumes:
+ - ./your-cartridges:/root/.local/share/nano-bots/cartridges
+ - ./your-state-path:/root/.local/state/nano-bots
+```
+
+#### Custom Project ID
+If you need to manually set a Google Project ID:
+
+```yaml
+environment:
+ GOOGLE_PROJECT_ID=your-project-id
+```
+
### Container
Enter the container:
@@ -416,7 +476,7 @@ provider:
model: gemini-pro
```
-#### Option 2: Service Account (Vertex AI API)
+#### Option 2: Service Account Credentials File (Vertex AI API)
```yaml
---
@@ -437,12 +497,48 @@ provider:
credentials:
service: vertex-ai-api
file-path: ENV/GOOGLE_CREDENTIALS_FILE_PATH
- project-id: ENV/GOOGLE_PROJECT_ID
region: ENV/GOOGLE_REGION
options:
model: gemini-pro
```
+#### Option 3: Application Default Credentials (Vertex AI API)
+
+```yaml
+---
+meta:
+ symbol: 🤖
+ name: Nano Bot Name
+ author: Your Name
+ version: 1.0.0
+ license: CC0-1.0
+ description: A helpful assistant.
+
+behaviors:
+ interaction:
+ directive: You are a helpful assistant.
+
+provider:
+ id: google
+ credentials:
+ service: vertex-ai-api
+ region: ENV/GOOGLE_REGION
+ options:
+ model: gemini-pro
+```
+
+#### Custom Project ID
+
+If you need to manually set a Google Project ID:
+
+```yaml
+---
+provider:
+ id: google
+ credentials:
+ project-id: ENV/GOOGLE_PROJECT_ID
+```
+
### Tools (Functions)
Nano Bots can also be powered by _Tools_ (Functions):
diff --git a/components/providers/google.rb b/components/providers/google.rb
index b15dd1b..a522d06 100644
--- a/components/providers/google.rb
+++ b/components/providers/google.rb
@@ -26,25 +26,9 @@ module NanoBot
def initialize(options, settings, credentials, _environment)
@settings = settings
- gemini_credentials = if credentials[:'api-key']
- {
- service: credentials[:service],
- api_key: credentials[:'api-key'],
- project_id: credentials[:'project-id'],
- region: credentials[:region]
- }
- else
- {
- service: credentials[:service],
- file_path: credentials[:'file-path'],
- project_id: credentials[:'project-id'],
- region: credentials[:region]
- }
- end
-
@client = Gemini.new(
- credentials: gemini_credentials,
- options: { model: options[:model], stream: options[:stream] }
+ credentials: credentials.transform_keys { |key| key.to_s.gsub('-', '_').to_sym },
+ options: options.transform_keys { |key| key.to_s.gsub('-', '_').to_sym }
)
end
@@ -70,6 +54,7 @@ module NanoBot
end
end
+ # TODO: Does Gemini have system messages?
%i[backdrop directive].each do |key|
next unless input[:behavior][key]
@@ -79,7 +64,6 @@ module NanoBot
_meta: { at: Time.now } }
)
- # TODO: Does Gemini have system messages?
messages.prepend(
{ role: 'user',
parts: { text: input[:behavior][key] },
@@ -140,24 +124,9 @@ module NanoBot
end
if event.dig('candidates', 0, 'finishReason')
- if tools&.size&.positive?
- feedback.call(
- { should_be_stored: true,
- needs_another_round: true,
- interaction: { who: 'AI', message: nil, meta: { tool_calls: tools } } }
- )
- Tools.apply(
- cartridge, input[:tools], tools, feedback, Logic::Google::Tools
- ).each do |interaction|
- feedback.call({ should_be_stored: true, needs_another_round: true, interaction: })
- end
- end
-
- feedback.call(
- { should_be_stored: !(content.nil? || content == ''),
- interaction: content.nil? || content == '' ? nil : { who: 'AI', message: content },
- finished: true }
- )
+ # TODO: This does not have the same behavior as OpenAI, so you should
+ # not use it as a reference for the end of the streaming.
+ # Is this a bug from the Google Gemini REST API or expected behavior?
end
end
@@ -166,6 +135,25 @@ module NanoBot
Logic::Google::Tokens.apply_policies!(cartridge, payload),
stream: true, &stream_call_back
)
+
+ if tools&.size&.positive?
+ feedback.call(
+ { should_be_stored: true,
+ needs_another_round: true,
+ interaction: { who: 'AI', message: nil, meta: { tool_calls: tools } } }
+ )
+ Tools.apply(
+ cartridge, input[:tools], tools, feedback, Logic::Google::Tools
+ ).each do |interaction|
+ feedback.call({ should_be_stored: true, needs_another_round: true, interaction: })
+ end
+ end
+
+ feedback.call(
+ { should_be_stored: !(content.nil? || content == ''),
+ interaction: content.nil? || content == '' ? nil : { who: 'AI', message: content },
+ finished: true }
+ )
rescue StandardError => e
raise e.class, e.response[:body] if e.response && e.response[:body]
diff --git a/nano-bots.gemspec b/nano-bots.gemspec
index ff466aa..074cf50 100644
--- a/nano-bots.gemspec
+++ b/nano-bots.gemspec
@@ -34,7 +34,7 @@ Gem::Specification.new do |spec|
spec.add_dependency 'babosa', '~> 2.0'
spec.add_dependency 'concurrent-ruby', '~> 1.2', '>= 1.2.2'
spec.add_dependency 'dotenv', '~> 2.8', '>= 2.8.1'
- spec.add_dependency 'gemini-ai', '~> 2.0'
+ spec.add_dependency 'gemini-ai', '~> 2.1'
spec.add_dependency 'pry', '~> 0.14.2'
spec.add_dependency 'rainbow', '~> 3.1', '>= 3.1.1'
spec.add_dependency 'rbnacl', '~> 7.1', '>= 7.1.1'
diff --git a/ports/dsl/nano-bots.rb b/ports/dsl/nano-bots.rb
index 29cc828..e01b2c4 100644
--- a/ports/dsl/nano-bots.rb
+++ b/ports/dsl/nano-bots.rb
@@ -40,4 +40,8 @@ module NanoBot
def self.version
NanoBot::GEM[:version]
end
+
+ def self.specification
+ NanoBot::GEM[:specification]
+ end
end
diff --git a/static/gem.rb b/static/gem.rb
index 5541189..6b45650 100644
--- a/static/gem.rb
+++ b/static/gem.rb
@@ -4,6 +4,7 @@ module NanoBot
GEM = {
name: 'nano-bots',
version: '2.0.0',
+ specification: '2.0.1',
author: 'icebaker',
summary: 'Ruby Implementation of Nano Bots: small, AI-powered bots for OpenAI ChatGPT and Google Gemini.',
description: 'Ruby Implementation of Nano Bots: small, AI-powered bots that can be easily shared as a single file, designed to support multiple providers such as OpenAI ChatGPT and Google Gemini, with support for calling Tools (Functions).',