ruby_llm 0.1.0.pre3 → 0.1.0.pre5

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.
metadata CHANGED
@@ -1,14 +1,35 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_llm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.pre3
4
+ version: 0.1.0.pre5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Carmine Paolino
8
+ autorequire:
8
9
  bindir: exe
9
10
  cert_chain: []
10
- date: 2025-01-30 00:00:00.000000000 Z
11
+ date: 2025-02-01 00:00:00.000000000 Z
11
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: event_stream_parser
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 0.3.0
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: 2.0.0
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: 0.3.0
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: 2.0.0
12
33
  - !ruby/object:Gem::Dependency
13
34
  name: faraday
14
35
  requirement: !ruby/object:Gem::Requirement
@@ -322,21 +343,22 @@ files:
322
343
  - bin/console
323
344
  - bin/setup
324
345
  - lib/ruby_llm.rb
325
- - lib/ruby_llm/active_record/acts_as.rb
326
- - lib/ruby_llm/client.rb
346
+ - lib/ruby_llm/chat.rb
347
+ - lib/ruby_llm/chunk.rb
327
348
  - lib/ruby_llm/configuration.rb
328
- - lib/ruby_llm/conversation.rb
329
349
  - lib/ruby_llm/message.rb
330
350
  - lib/ruby_llm/model_capabilities/anthropic.rb
331
- - lib/ruby_llm/model_capabilities/base.rb
332
351
  - lib/ruby_llm/model_capabilities/openai.rb
333
352
  - lib/ruby_llm/model_info.rb
353
+ - lib/ruby_llm/models.json
354
+ - lib/ruby_llm/models.rb
355
+ - lib/ruby_llm/provider.rb
334
356
  - lib/ruby_llm/providers/anthropic.rb
335
- - lib/ruby_llm/providers/base.rb
336
357
  - lib/ruby_llm/providers/openai.rb
337
358
  - lib/ruby_llm/railtie.rb
338
359
  - lib/ruby_llm/tool.rb
339
360
  - lib/ruby_llm/version.rb
361
+ - lib/tasks/models.rake
340
362
  - ruby_llm.gemspec
341
363
  homepage: https://github.com/crmne/ruby_llm
342
364
  licenses:
@@ -347,6 +369,7 @@ metadata:
347
369
  changelog_uri: https://github.com/crmne/ruby_llm/blob/main/CHANGELOG.md
348
370
  documentation_uri: https://rubydoc.info/gems/ruby_llm
349
371
  bug_tracker_uri: https://github.com/crmne/ruby_llm/issues
372
+ post_install_message:
350
373
  rdoc_options: []
351
374
  require_paths:
352
375
  - lib
@@ -361,7 +384,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
361
384
  - !ruby/object:Gem::Version
362
385
  version: '0'
363
386
  requirements: []
364
- rubygems_version: 3.6.2
387
+ rubygems_version: 3.5.22
388
+ signing_key:
365
389
  specification_version: 4
366
390
  summary: The Ruby LLM client library - unified interface for OpenAI, Anthropic, and
367
391
  other LLM providers
@@ -1,115 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RubyLLM
4
- module ActiveRecord
5
- # Provides ActsAs functionality for LLM-related models
6
- module ActsAs
7
- def acts_as_llm_model(_options = {})
8
- include ModelMethods
9
- end
10
-
11
- def acts_as_llm_conversation(_options = {})
12
- include ConversationMethods
13
- has_many :messages, -> { order(created_at: :asc) }
14
- end
15
-
16
- def acts_as_llm_message(_options = {})
17
- include MessageMethods
18
- belongs_to :conversation
19
- end
20
- end
21
-
22
- # Methods for LLM model functionality
23
- module ModelMethods
24
- extend ActiveSupport::Concern
25
-
26
- included do
27
- validates :name, presence: true
28
- validates :provider, presence: true
29
- end
30
-
31
- class_methods do
32
- def sync_models
33
- # Logic to sync models from providers
34
- end
35
- end
36
- end
37
-
38
- # Methods for LLM conversation handling
39
- module ConversationMethods
40
- extend ActiveSupport::Concern
41
-
42
- included do
43
- before_create :set_default_model
44
- end
45
-
46
- def send_message(content, model: nil)
47
- transaction do
48
- create_user_message(content)
49
- create_assistant_response(model)
50
- end
51
- end
52
-
53
- private
54
-
55
- def create_user_message(content)
56
- messages.create!(
57
- role: :user,
58
- content: content
59
- )
60
- end
61
-
62
- def create_assistant_response(model)
63
- response = RubyLLM.client.chat(
64
- conversation_messages,
65
- model: model || current_model
66
- )
67
-
68
- messages.create!(
69
- role: :assistant,
70
- content: response.content,
71
- token_count: response.token_count
72
- )
73
- end
74
-
75
- def conversation_messages
76
- messages.map(&:to_llm_format)
77
- end
78
-
79
- def set_default_model
80
- self.current_model ||= RubyLLM.configuration.default_model
81
- end
82
- end
83
-
84
- # Methods for LLM message handling
85
- module MessageMethods
86
- extend ActiveSupport::Concern
87
-
88
- included do
89
- validates :role, presence: true, inclusion: { in: RubyLLM::Message::VALID_ROLES.map(&:to_s) }
90
- validates :content, presence: true, unless: :tool_call?
91
-
92
- before_save :calculate_tokens
93
- end
94
-
95
- def to_llm_format
96
- RubyLLM::Message.new(
97
- role: role.to_sym,
98
- content: content,
99
- tool_calls: tool_calls,
100
- tool_results: tool_results
101
- )
102
- end
103
-
104
- private
105
-
106
- def calculate_tokens
107
- # Logic to calculate tokens
108
- end
109
-
110
- def tool_call?
111
- tool_calls.present? || tool_results.present?
112
- end
113
- end
114
- end
115
- end
@@ -1,67 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RubyLLM
4
- # Client class for handling LLM provider interactions
5
- class Client
6
- def initialize
7
- @providers = {}
8
- end
9
-
10
- def chat(messages, model: nil, temperature: 0.7, stream: false, tools: nil, &block)
11
- # Convert any hash messages to Message objects
12
- formatted_messages = messages.map do |msg|
13
- msg.is_a?(Message) ? msg : Message.new(**msg)
14
- end
15
-
16
- provider = provider_for(model)
17
- provider.chat(
18
- formatted_messages,
19
- model: model,
20
- temperature: temperature,
21
- stream: stream,
22
- tools: tools,
23
- &block
24
- )
25
- end
26
-
27
- def list_models(provider = nil)
28
- if provider
29
- provider_for(nil, provider).list_models
30
- else
31
- all_providers.flat_map(&:list_models)
32
- end
33
- end
34
-
35
- private
36
-
37
- def all_providers
38
- [
39
- provider_for(nil, :openai),
40
- provider_for(nil, :anthropic)
41
- ]
42
- end
43
-
44
- def provider_for(model, specific_provider = nil)
45
- provider_name = specific_provider || detect_provider(model)
46
- @providers[provider_name] ||= case provider_name
47
- when :openai then Providers::OpenAI.new
48
- when :anthropic then Providers::Anthropic.new
49
- else
50
- raise Error, "Unsupported provider: #{provider_name}"
51
- end
52
- end
53
-
54
- def detect_provider(model)
55
- return RubyLLM.configuration.default_provider unless model
56
-
57
- case model
58
- when /^gpt-/, /^text-davinci/
59
- :openai
60
- when /^claude/
61
- :anthropic
62
- else
63
- RubyLLM.configuration.default_provider
64
- end
65
- end
66
- end
67
- end
@@ -1,19 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RubyLLM
4
- # Represents a conversation with an LLM
5
- class Conversation
6
- attr_reader :id, :messages, :tools
7
-
8
- def initialize(tools: [])
9
- @id = SecureRandom.uuid
10
- @messages = []
11
- @tools = tools
12
- end
13
-
14
- def add_message(message)
15
- @messages << message
16
- message
17
- end
18
- end
19
- end
@@ -1,35 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RubyLLM
4
- module ModelCapabilities
5
- class Base
6
- def determine_context_window(_model_id)
7
- raise NotImplementedError
8
- end
9
-
10
- def determine_max_tokens(_model_id)
11
- raise NotImplementedError
12
- end
13
-
14
- def get_input_price(_model_id)
15
- raise NotImplementedError
16
- end
17
-
18
- def get_output_price(_model_id)
19
- raise NotImplementedError
20
- end
21
-
22
- def supports_vision?(_model_id)
23
- raise NotImplementedError
24
- end
25
-
26
- def supports_functions?(_model_id)
27
- raise NotImplementedError
28
- end
29
-
30
- def supports_json_mode?(_model_id)
31
- raise NotImplementedError
32
- end
33
- end
34
- end
35
- end
@@ -1,60 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RubyLLM
4
- module Providers
5
- # Base provider class for LLM interactions
6
- class Base
7
- attr_reader :connection
8
-
9
- def initialize
10
- @connection = build_connection
11
- end
12
-
13
- def chat(messages, **options, &block)
14
- raise NotImplementedError
15
- end
16
-
17
- protected
18
-
19
- def build_connection
20
- Faraday.new(url: api_base) do |f|
21
- f.options.timeout = RubyLLM.configuration.request_timeout
22
- f.request :json
23
- f.response :json
24
- f.adapter Faraday.default_adapter
25
- end
26
- end
27
-
28
- def handle_error(error)
29
- case error
30
- when Faraday::TimeoutError
31
- raise RubyLLM::Error, 'Request timed out'
32
- when Faraday::ConnectionFailed
33
- raise RubyLLM::Error, 'Connection failed'
34
- when Faraday::ClientError
35
- handle_api_error(error)
36
- else
37
- raise error
38
- end
39
- end
40
-
41
- def handle_api_error(error)
42
- raise RubyLLM::Error, "API error: #{error.response[:status]}"
43
- end
44
-
45
- def parse_error_message(response)
46
- return "HTTP #{response.status}" unless response.body
47
-
48
- if response.body.is_a?(String)
49
- begin
50
- JSON.parse(response.body).dig('error', 'message')
51
- rescue StandardError
52
- "HTTP #{response.status}"
53
- end
54
- else
55
- response.body.dig('error', 'message') || "HTTP #{response.status}"
56
- end
57
- end
58
- end
59
- end
60
- end