ruby_llm 0.1.0.pre4 → 0.1.0.pre6
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/.github/workflows/test.yml +5 -2
- data/.overcommit.yml +1 -1
- data/README.md +56 -181
- data/bin/console +6 -0
- data/lib/ruby_llm/chat.rb +95 -0
- data/lib/ruby_llm/chunk.rb +6 -0
- data/lib/ruby_llm/configuration.rb +2 -4
- data/lib/ruby_llm/message.rb +26 -18
- data/lib/ruby_llm/model_capabilities/anthropic.rb +43 -48
- data/lib/ruby_llm/model_capabilities/openai.rb +82 -89
- data/lib/ruby_llm/model_info.rb +26 -17
- data/lib/ruby_llm/models.json +686 -0
- data/lib/ruby_llm/models.rb +52 -0
- data/lib/ruby_llm/provider.rb +99 -0
- data/lib/ruby_llm/providers/anthropic.rb +92 -243
- data/lib/ruby_llm/providers/openai.rb +130 -174
- data/lib/ruby_llm/tool.rb +71 -50
- data/lib/ruby_llm/version.rb +1 -1
- data/lib/ruby_llm.rb +35 -37
- data/lib/tasks/models.rake +25 -0
- data/ruby_llm.gemspec +8 -6
- metadata +39 -15
- data/lib/ruby_llm/active_record/acts_as.rb +0 -115
- data/lib/ruby_llm/client.rb +0 -70
- data/lib/ruby_llm/conversation.rb +0 -19
- data/lib/ruby_llm/model_capabilities/base.rb +0 -35
- data/lib/ruby_llm/providers/base.rb +0 -67
| @@ -2,95 +2,47 @@ | |
| 2 2 |  | 
| 3 3 | 
             
            module RubyLLM
         | 
| 4 4 | 
             
              module ModelCapabilities
         | 
| 5 | 
            -
                 | 
| 6 | 
            -
                   | 
| 7 | 
            -
                    case model_id
         | 
| 8 | 
            -
                    when /gpt-4o/, /o1/, /gpt-4-turbo/
         | 
| 9 | 
            -
                      128_000
         | 
| 10 | 
            -
                    when /gpt-4-0[0-9]{3}/
         | 
| 11 | 
            -
                      8_192
         | 
| 12 | 
            -
                    when /gpt-3.5-turbo-instruct/
         | 
| 13 | 
            -
                      4_096
         | 
| 14 | 
            -
                    when /gpt-3.5/
         | 
| 15 | 
            -
                      16_385
         | 
| 16 | 
            -
                    else
         | 
| 17 | 
            -
                      4_096
         | 
| 18 | 
            -
                    end
         | 
| 19 | 
            -
                  end
         | 
| 5 | 
            +
                module OpenAI
         | 
| 6 | 
            +
                  extend self
         | 
| 20 7 |  | 
| 21 | 
            -
                  def  | 
| 8 | 
            +
                  def context_window_for(model_id)
         | 
| 22 9 | 
             
                    case model_id
         | 
| 23 | 
            -
                    when /o1- | 
| 24 | 
            -
             | 
| 25 | 
            -
                    when / | 
| 26 | 
            -
             | 
| 27 | 
            -
                     | 
| 28 | 
            -
                      32_768
         | 
| 29 | 
            -
                    when /gpt-4o/, /gpt-4-turbo/
         | 
| 30 | 
            -
                      16_384
         | 
| 31 | 
            -
                    when /gpt-4-0[0-9]{3}/
         | 
| 32 | 
            -
                      8_192
         | 
| 33 | 
            -
                    when /gpt-3.5-turbo/
         | 
| 34 | 
            -
                      4_096
         | 
| 35 | 
            -
                    else
         | 
| 36 | 
            -
                      4_096
         | 
| 10 | 
            +
                    when /gpt-4o/, /o1/, /gpt-4-turbo/ then 128_000
         | 
| 11 | 
            +
                    when /gpt-4-0[0-9]{3}/            then 8_192
         | 
| 12 | 
            +
                    when /gpt-3.5-turbo-instruct/     then 4_096
         | 
| 13 | 
            +
                    when /gpt-3.5/                    then 16_385
         | 
| 14 | 
            +
                    else                                   4_096
         | 
| 37 15 | 
             
                    end
         | 
| 38 16 | 
             
                  end
         | 
| 39 17 |  | 
| 40 | 
            -
                  def  | 
| 18 | 
            +
                  def max_tokens_for(model_id)
         | 
| 41 19 | 
             
                    case model_id
         | 
| 42 | 
            -
                    when /o1-2024/
         | 
| 43 | 
            -
             | 
| 44 | 
            -
                    when /o1- | 
| 45 | 
            -
             | 
| 46 | 
            -
                    when /gpt- | 
| 47 | 
            -
             | 
| 48 | 
            -
                     | 
| 49 | 
            -
                      0.60    # $0.60 per million tokens
         | 
| 50 | 
            -
                    when /gpt-4o-mini/
         | 
| 51 | 
            -
                      0.15    # $0.15 per million tokens
         | 
| 52 | 
            -
                    when /gpt-4o/
         | 
| 53 | 
            -
                      2.50    # $2.50 per million tokens
         | 
| 54 | 
            -
                    when /gpt-4-turbo/
         | 
| 55 | 
            -
                      10.0    # $10.00 per million tokens
         | 
| 56 | 
            -
                    when /gpt-3.5/
         | 
| 57 | 
            -
                      0.50    # $0.50 per million tokens
         | 
| 58 | 
            -
                    else
         | 
| 59 | 
            -
                      0.50    # Default to GPT-3.5 pricing
         | 
| 20 | 
            +
                    when /o1-2024-12-17/              then 100_000
         | 
| 21 | 
            +
                    when /o1-mini-2024-09-12/         then 65_536
         | 
| 22 | 
            +
                    when /o1-preview-2024-09-12/      then 32_768
         | 
| 23 | 
            +
                    when /gpt-4o/, /gpt-4-turbo/      then 16_384
         | 
| 24 | 
            +
                    when /gpt-4-0[0-9]{3}/           then 8_192
         | 
| 25 | 
            +
                    when /gpt-3.5-turbo/             then 4_096
         | 
| 26 | 
            +
                    else                                  4_096
         | 
| 60 27 | 
             
                    end
         | 
| 61 28 | 
             
                  end
         | 
| 62 29 |  | 
| 63 | 
            -
                  def  | 
| 64 | 
            -
                     | 
| 65 | 
            -
                    when /o1-2024/
         | 
| 66 | 
            -
                      60.0    # $60.00 per million tokens
         | 
| 67 | 
            -
                    when /o1-mini/
         | 
| 68 | 
            -
                      12.0    # $12.00 per million tokens
         | 
| 69 | 
            -
                    when /gpt-4o-realtime-preview/
         | 
| 70 | 
            -
                      20.0    # $20.00 per million tokens
         | 
| 71 | 
            -
                    when /gpt-4o-mini-realtime-preview/
         | 
| 72 | 
            -
                      2.40    # $2.40 per million tokens
         | 
| 73 | 
            -
                    when /gpt-4o-mini/
         | 
| 74 | 
            -
                      0.60    # $0.60 per million tokens
         | 
| 75 | 
            -
                    when /gpt-4o/
         | 
| 76 | 
            -
                      10.0    # $10.00 per million tokens
         | 
| 77 | 
            -
                    when /gpt-4-turbo/
         | 
| 78 | 
            -
                      30.0    # $30.00 per million tokens
         | 
| 79 | 
            -
                    when /gpt-3.5/
         | 
| 80 | 
            -
                      1.50    # $1.50 per million tokens
         | 
| 81 | 
            -
                    else
         | 
| 82 | 
            -
                      1.50    # Default to GPT-3.5 pricing
         | 
| 83 | 
            -
                    end
         | 
| 30 | 
            +
                  def input_price_for(model_id)
         | 
| 31 | 
            +
                    PRICES.dig(model_family(model_id), :input) || default_input_price
         | 
| 84 32 | 
             
                  end
         | 
| 85 33 |  | 
| 86 | 
            -
                  def  | 
| 87 | 
            -
                     | 
| 34 | 
            +
                  def output_price_for(model_id)
         | 
| 35 | 
            +
                    PRICES.dig(model_family(model_id), :output) || default_output_price
         | 
| 88 36 | 
             
                  end
         | 
| 89 37 |  | 
| 90 38 | 
             
                  def supports_vision?(model_id)
         | 
| 91 39 | 
             
                    model_id.include?('vision') || model_id.match?(/gpt-4-(?!0314|0613)/)
         | 
| 92 40 | 
             
                  end
         | 
| 93 41 |  | 
| 42 | 
            +
                  def supports_functions?(model_id)
         | 
| 43 | 
            +
                    !model_id.include?('instruct')
         | 
| 44 | 
            +
                  end
         | 
| 45 | 
            +
             | 
| 94 46 | 
             
                  def supports_json_mode?(model_id)
         | 
| 95 47 | 
             
                    model_id.match?(/gpt-4-\d{4}-preview/) ||
         | 
| 96 48 | 
             
                      model_id.include?('turbo') ||
         | 
| @@ -98,23 +50,64 @@ module RubyLLM | |
| 98 50 | 
             
                  end
         | 
| 99 51 |  | 
| 100 52 | 
             
                  def format_display_name(model_id)
         | 
| 101 | 
            -
                     | 
| 102 | 
            -
             | 
| 103 | 
            -
             | 
| 104 | 
            -
             | 
| 105 | 
            -
             | 
| 106 | 
            -
             | 
| 107 | 
            -
             | 
| 108 | 
            -
                     | 
| 109 | 
            -
             | 
| 110 | 
            -
             | 
| 111 | 
            -
             | 
| 112 | 
            -
             | 
| 113 | 
            -
             | 
| 114 | 
            -
             | 
| 115 | 
            -
             | 
| 116 | 
            -
             | 
| 117 | 
            -
             | 
| 53 | 
            +
                    model_id.then { |id| humanize(id) }
         | 
| 54 | 
            +
                            .then { |name| apply_special_formatting(name) }
         | 
| 55 | 
            +
                  end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                  private
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                  def model_family(model_id)
         | 
| 60 | 
            +
                    case model_id
         | 
| 61 | 
            +
                    when /o1-2024/                   then :o1
         | 
| 62 | 
            +
                    when /o1-mini/                   then :o1_mini
         | 
| 63 | 
            +
                    when /gpt-4o-realtime-preview/   then :gpt4o_realtime
         | 
| 64 | 
            +
                    when /gpt-4o-mini-realtime/      then :gpt4o_mini_realtime
         | 
| 65 | 
            +
                    when /gpt-4o-mini/               then :gpt4o_mini
         | 
| 66 | 
            +
                    when /gpt-4o/                    then :gpt4o
         | 
| 67 | 
            +
                    when /gpt-4-turbo/               then :gpt4_turbo
         | 
| 68 | 
            +
                    when /gpt-3.5/                   then :gpt35
         | 
| 69 | 
            +
                    else :gpt35
         | 
| 70 | 
            +
                    end
         | 
| 71 | 
            +
                  end
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                  PRICES = {
         | 
| 74 | 
            +
                    o1: { input: 15.0, output: 60.0 },
         | 
| 75 | 
            +
                    o1_mini: { input: 3.0, output: 12.0 },
         | 
| 76 | 
            +
                    gpt4o_realtime: { input: 5.0, output: 20.0 },
         | 
| 77 | 
            +
                    gpt4o_mini_realtime: { input: 0.60, output: 2.40 },
         | 
| 78 | 
            +
                    gpt4o_mini: { input: 0.15, output: 0.60 },
         | 
| 79 | 
            +
                    gpt4o: { input: 2.50, output: 10.0 },
         | 
| 80 | 
            +
                    gpt4_turbo: { input: 10.0, output: 30.0 },
         | 
| 81 | 
            +
                    gpt35: { input: 0.50, output: 1.50 }
         | 
| 82 | 
            +
                  }.freeze
         | 
| 83 | 
            +
             | 
| 84 | 
            +
                  def default_input_price
         | 
| 85 | 
            +
                    0.50
         | 
| 86 | 
            +
                  end
         | 
| 87 | 
            +
             | 
| 88 | 
            +
                  def default_output_price
         | 
| 89 | 
            +
                    1.50
         | 
| 90 | 
            +
                  end
         | 
| 91 | 
            +
             | 
| 92 | 
            +
                  def humanize(id)
         | 
| 93 | 
            +
                    id.tr('-', ' ')
         | 
| 94 | 
            +
                      .split(' ')
         | 
| 95 | 
            +
                      .map(&:capitalize)
         | 
| 96 | 
            +
                      .join(' ')
         | 
| 97 | 
            +
                  end
         | 
| 98 | 
            +
             | 
| 99 | 
            +
                  def apply_special_formatting(name)
         | 
| 100 | 
            +
                    name
         | 
| 101 | 
            +
                      .gsub(/(\d{4}) (\d{2}) (\d{2})/, '\1\2\3')
         | 
| 102 | 
            +
                      .gsub(/^Gpt /, 'GPT-')
         | 
| 103 | 
            +
                      .gsub(/^O1 /, 'O1-')
         | 
| 104 | 
            +
                      .gsub(/^Chatgpt /, 'ChatGPT-')
         | 
| 105 | 
            +
                      .gsub(/^Tts /, 'TTS-')
         | 
| 106 | 
            +
                      .gsub(/^Dall E /, 'DALL-E-')
         | 
| 107 | 
            +
                      .gsub(/3\.5 /, '3.5-')
         | 
| 108 | 
            +
                      .gsub(/4 /, '4-')
         | 
| 109 | 
            +
                      .gsub(/4o (?=Mini|Preview|Turbo)/, '4o-')
         | 
| 110 | 
            +
                      .gsub(/\bHd\b/, 'HD')
         | 
| 118 111 | 
             
                  end
         | 
| 119 112 | 
             
                end
         | 
| 120 113 | 
             
              end
         | 
    
        data/lib/ruby_llm/model_info.rb
    CHANGED
    
    | @@ -1,42 +1,51 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 | 
            +
            require 'time'
         | 
| 4 | 
            +
             | 
| 3 5 | 
             
            module RubyLLM
         | 
| 4 6 | 
             
              class ModelInfo
         | 
| 5 7 | 
             
                attr_reader :id, :created_at, :display_name, :provider, :metadata,
         | 
| 6 8 | 
             
                            :context_window, :max_tokens, :supports_vision, :supports_functions,
         | 
| 7 9 | 
             
                            :supports_json_mode, :input_price_per_million, :output_price_per_million
         | 
| 8 10 |  | 
| 9 | 
            -
                def initialize( | 
| 10 | 
            -
             | 
| 11 | 
            -
                  @ | 
| 12 | 
            -
                  @ | 
| 13 | 
            -
                  @ | 
| 14 | 
            -
                  @ | 
| 15 | 
            -
                  @ | 
| 16 | 
            -
                  @ | 
| 17 | 
            -
                  @ | 
| 18 | 
            -
                  @ | 
| 19 | 
            -
                  @ | 
| 20 | 
            -
                  @ | 
| 21 | 
            -
                  @ | 
| 22 | 
            -
                  @output_price_per_million = output_price_per_million
         | 
| 11 | 
            +
                def initialize(data)
         | 
| 12 | 
            +
                  @id = data[:id]
         | 
| 13 | 
            +
                  @created_at = data[:created_at].is_a?(String) ? Time.parse(data[:created_at]) : data[:created_at]
         | 
| 14 | 
            +
                  @display_name = data[:display_name]
         | 
| 15 | 
            +
                  @provider = data[:provider]
         | 
| 16 | 
            +
                  @context_window = data[:context_window]
         | 
| 17 | 
            +
                  @max_tokens = data[:max_tokens]
         | 
| 18 | 
            +
                  @supports_vision = data[:supports_vision]
         | 
| 19 | 
            +
                  @supports_functions = data[:supports_functions]
         | 
| 20 | 
            +
                  @supports_json_mode = data[:supports_json_mode]
         | 
| 21 | 
            +
                  @input_price_per_million = data[:input_price_per_million]
         | 
| 22 | 
            +
                  @output_price_per_million = data[:output_price_per_million]
         | 
| 23 | 
            +
                  @metadata = data[:metadata] || {}
         | 
| 23 24 | 
             
                end
         | 
| 24 25 |  | 
| 25 26 | 
             
                def to_h
         | 
| 26 27 | 
             
                  {
         | 
| 27 28 | 
             
                    id: id,
         | 
| 28 | 
            -
                    created_at: created_at,
         | 
| 29 | 
            +
                    created_at: created_at.iso8601,
         | 
| 29 30 | 
             
                    display_name: display_name,
         | 
| 30 31 | 
             
                    provider: provider,
         | 
| 31 | 
            -
                    metadata: metadata,
         | 
| 32 32 | 
             
                    context_window: context_window,
         | 
| 33 33 | 
             
                    max_tokens: max_tokens,
         | 
| 34 34 | 
             
                    supports_vision: supports_vision,
         | 
| 35 35 | 
             
                    supports_functions: supports_functions,
         | 
| 36 36 | 
             
                    supports_json_mode: supports_json_mode,
         | 
| 37 37 | 
             
                    input_price_per_million: input_price_per_million,
         | 
| 38 | 
            -
                    output_price_per_million: output_price_per_million
         | 
| 38 | 
            +
                    output_price_per_million: output_price_per_million,
         | 
| 39 | 
            +
                    metadata: metadata
         | 
| 39 40 | 
             
                  }
         | 
| 40 41 | 
             
                end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                def type
         | 
| 44 | 
            +
                  metadata['type']
         | 
| 45 | 
            +
                end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                def family
         | 
| 48 | 
            +
                  metadata['family']
         | 
| 49 | 
            +
                end
         | 
| 41 50 | 
             
              end
         | 
| 42 51 | 
             
            end
         |