icebaker / ruby-nano-bots

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 Anthropic Claude, Cohere Command, Google Gemini, Maritaca AI, Mistral AI, Ollama, OpenAI ChatGPT, and others, with support for calling tools (functions).
https://rubygems.org/gems/nano-bots
MIT License
79 stars 10 forks source link

the server responded with status 400 (Faraday::BadRequestError) with Gemini API key #21

Open palladius opened 2 weeks ago

palladius commented 2 weeks ago

Hi, I'm trying to use nanobots with Gemini API key and keep failing repeatedly. after some debugging, I can see that gemini-ai and curl work great with my API key, while nb fails to work.

For convenience the code is all here: https://github.com/palladius/ragazzi

# .env file has this 
export GOOGLE_API_KEY='blah blah blah'
# gemini-api-cartridge.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: generative-language-api
    api-key: ENV/GOOGLE_API_KEY
  options:
    model: gemini-pro
$ nb gemini-api-cartridge.yaml - eval "Hello" 
/usr/local/google/home/ricc/.rbenv/versions/3.2.1/lib/ruby/gems/3.2.0/gems/faraday-2.9.1/lib/faraday/response/raise_error.rb:16:in `on_complete': the server responded with status 400 (Faraday::BadRequestError)
        from /usr/local/google/home/ricc/.rbenv/versions/3.2.1/lib/ruby/gems/3.2.0/gems/faraday-2.9.1/lib/faraday/middleware.rb:18:in `block in call'
        from /usr/local/google/home/ricc/.rbenv/versions/3.2.1/lib/ruby/gems/3.2.0/gems/faraday-2.9.1/lib/faraday/response.rb:42:in `on_complete'
        from /usr/local/google/home/ricc/.rbenv/versions/3.2.1/lib/ruby/gems/3.2.0/gems/faraday-2.9.1/lib/faraday/middleware.rb:17:in `call'
        from /usr/local/google/home/ricc/.rbenv/versions/3.2.1/lib/ruby/gems/3.2.0/gems/faraday-2.9.1/lib/faraday/rack_builder.rb:152:in `build_response'
        from /usr/local/google/home/ricc/.rbenv/versions/3.2.1/lib/ruby/gems/3.2.0/gems/faraday-2.9.1/lib/faraday/connection.rb:444:in `run_request'
        from /usr/local/google/home/ricc/.rbenv/versions/3.2.1/lib/ruby/gems/3.2.0/gems/faraday-2.9.1/lib/faraday/connection.rb:280:in `post'
        from /usr/local/google/home/ricc/.rbenv/versions/3.2.1/lib/ruby/gems/3.2.0/gems/gemini-ai-4.0.0/controllers/client.rb:150:in `request'
        from /usr/local/google/home/ricc/.rbenv/versions/3.2.1/lib/ruby/gems/3.2.0/gems/gemini-ai-4.0.0/controllers/client.rb:101:in `stream_generate_content'
        from /usr/local/google/home/ricc/.rbenv/versions/3.2.1/lib/ruby/gems/3.2.0/gems/nano-bots-3.1.0/components/providers/google.rb:152:in `evaluate'
        from /usr/local/google/home/ricc/.rbenv/versions/3.2.1/lib/ruby/gems/3.2.0/gems/nano-bots-3.1.0/controllers/session.rb:131:in `process_interaction'
        from /usr/local/google/home/ricc/.rbenv/versions/3.2.1/lib/ruby/gems/3.2.0/gems/nano-bots-3.1.0/controllers/session.rb:107:in `process'
        from /usr/local/google/home/ricc/.rbenv/versions/3.2.1/lib/ruby/gems/3.2.0/gems/nano-bots-3.1.0/controllers/session.rb:93:in `evaluate_and_print'
        from /usr/local/google/home/ricc/.rbenv/versions/3.2.1/lib/ruby/gems/3.2.0/gems/nano-bots-3.1.0/controllers/interfaces/eval.rb:15:in `evaluate'
        from /usr/local/google/home/ricc/.rbenv/versions/3.2.1/lib/ruby/gems/3.2.0/gems/nano-bots-3.1.0/controllers/instance.rb:52:in `eval'
        from /usr/local/google/home/ricc/.rbenv/versions/3.2.1/lib/ruby/gems/3.2.0/gems/nano-bots-3.1.0/controllers/interfaces/cli.rb:80:in `handle!'
        from /usr/local/google/home/ricc/.rbenv/versions/3.2.1/lib/ruby/gems/3.2.0/gems/nano-bots-3.1.0/ports/dsl/nano-bots.rb:32:in `cli'
        from /usr/local/google/home/ricc/.rbenv/versions/3.2.1/lib/ruby/gems/3.2.0/gems/nano-bots-3.1.0/ports/dsl/nano-bots/cli.rb:5:in `<top (required)>'
        from <internal:/usr/local/google/home/ricc/.rbenv/versions/3.2.1/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:88:in `require'
        from <internal:/usr/local/google/home/ricc/.rbenv/versions/3.2.1/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:88:in `require'
        from /usr/local/google/home/ricc/.rbenv/versions/3.2.1/lib/ruby/gems/3.2.0/gems/nano-bots-3.1.0/bin/nb:4:in `<top (required)>'
        from /usr/local/google/home/ricc/.rbenv/versions/3.2.1/bin/nb:25:in `load'
        from /usr/local/google/home/ricc/.rbenv/versions/3.2.1/bin/nb:25:in `<main>'

I thought I might have a bad key, but then I tried this with same key and that worked:

require 'gemini-ai'

client = Gemini.new(
  credentials: {
    service: 'generative-language-api',
    api_key: ENV['GOOGLE_API_KEY'],
    version: 'v1beta'
  },
  options: {
    model: 'gemini-pro',
    server_sent_events: true }
)

client.stream_generate_content(
  { contents: {
    role: 'user',
    parts: { text: 'hi!' } } }
) do |event, parsed, raw|
  puts event
end

==>

{"candidates"=>[{"content"=>{"parts"=>[{"text"=>"Hello! How can I assist you today?"}], "role"=>"model"}, "finishReason"=>"STOP", "index"=>0, "safetyRatings"=>[{"category"=>"HARM_CATEGORY_SEXUALLY_EXPLICIT", "probability"=>"NEGLIGIBLE"}, {"category"=>"HARM_CATEGORY_HATE_SPEECH", "probability"=>"NEGLIGIBLE"}, {"category"=>"HARM_CATEGORY_HARASSMENT", "probability"=>"NEGLIGIBLE"}, {"category"=>"HARM_CATEGORY_DANGEROUS_CONTENT", "probability"=>"NEGLIGIBLE"}]}], "usageMetadata"=>{"promptTokenCount"=>3, "candidatesTokenCount"=>9, "totalTokenCount"=>12}}

Please help

$ ruby -v
ruby 3.2.1 (2023-02-08 revision 31819e82c8) [x86_64-linux]

$ cat Gemfile
source "https://rubygems.org"

gem 'nano-bots', '~> 3.1.0'
gem 'gemini-ai', '~> 4.0.0'
palladius commented 2 weeks ago

I'm happy to troubleshoot and file a PR myself, I just need help on how to enable Faraday logging (to see what API call is being made and what JSON is being returned).

palladius commented 2 weeks ago

This is the faraday dump. Seems like NO response body is available, just a "mute" 400. Note I'm based in Switzerland, and recently Gemini API KEYs have been made available in most of Europe. Weird it works from curl and not from this gem.

#<struct Faraday::Env
 method=:post,
 request_body=
  "{\"contents\":[{\"role\":\"user\",\"parts\":{\"text\":\"Write a story about a magic backpack\"}}],\"generationConfig\":{\"candidateCount\":1},\"system_instruction\":{\"role\":\"user\",\"parts\":{\"text\":\"You are a helpful assistant from Google, called RAGazzo.\\nMake sure to always introduce yourself in interactions with humans.\\n\"}}}",
 url=
  #<URI::HTTPS https://generativelanguage.googleapis.com/v1/models/gemini-pro:streamGenerateContent?alt=sse&key=REDACTED>,
 request=
  #<struct Faraday::RequestOptions
   params_encoder=nil,
   proxy=nil,
   bind=nil,
   timeout=nil,
   open_timeout=nil,
   read_timeout=nil,
   write_timeout=nil,
   boundary=nil,
   oauth=nil,
   context=nil,
   on_data=
    #<Proc:0x0000000106e03358 /Users/ricc/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/gemini-ai-4.0.0/controllers/client.rb:164>>,
 request_headers=
  {"User-Agent"=>"Faraday v2.9.1", "Content-Type"=>"application/json"},
 ssl=
  #<struct Faraday::SSLOptions
   verify=true,
   verify_hostname=nil,
   ca_file=nil,
   ca_path=nil,
   verify_mode=nil,
   cert_store=nil,
   client_cert=nil,
   client_key=nil,
   certificate=nil,
   private_key=nil,
   verify_depth=nil,
   version=nil,
   min_version=nil,
   max_version=nil>,
 parallel_manager=nil,
 params=nil,
 response=
  #<Faraday::Response:0x0000000106df2238
   @env=#<struct Faraday::Env:...>,
   @on_complete_callbacks=[]>,
 response_headers=
  {"vary"=>"Origin, X-Origin, Referer",
   "content-type"=>"text/event-stream",
   "date"=>"Tue, 18 Jun 2024 06:19:46 GMT",
   "server"=>"scaffolding on HTTPServer2",
   "content-length"=>"457",
   "x-xss-protection"=>"0",
   "x-frame-options"=>"SAMEORIGIN",
   "x-content-type-options"=>"nosniff",
   "server-timing"=>"gfet4t7; dur=817",
   "alt-svc"=>"h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000"},
 status=400,
 reason_phrase="",
 response_body="">
icebaker commented 1 week ago

Hi @palladius! Thank you very much for reporting the issue. I identified the root cause and I'm working on a fix in this PR:

icebaker commented 1 week ago

@palladius fixed in version 3.2.0:

gem 'nano-bots', '~> 3.2'

Update:

Actually, prefer the newer version 3.4.0:

gem 'nano-bots', '~> 3.4'
palladius commented 1 week ago

You are a STAR! I've updated the dependency and now it works like a charm!

I took a look at https://github.com/icebaker/ruby-nano-bots/pull/22 . Nice job!