llm.rb 11.1.0 → 11.3.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.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +141 -12
  3. data/README.md +104 -69
  4. data/lib/llm/a2a/transport/http.rb +9 -8
  5. data/lib/llm/a2a.rb +14 -7
  6. data/lib/llm/agent.rb +31 -7
  7. data/lib/llm/context.rb +20 -6
  8. data/lib/llm/error.rb +4 -0
  9. data/lib/llm/function/array.rb +6 -0
  10. data/lib/llm/function.rb +26 -0
  11. data/lib/llm/json_adapter.rb +8 -2
  12. data/lib/llm/mcp/transport/http.rb +7 -5
  13. data/lib/llm/mcp.rb +6 -7
  14. data/lib/llm/provider.rb +1 -18
  15. data/lib/llm/providers/anthropic/error_handler.rb +2 -0
  16. data/lib/llm/providers/anthropic/files.rb +6 -6
  17. data/lib/llm/providers/anthropic/models.rb +1 -1
  18. data/lib/llm/providers/anthropic.rb +1 -1
  19. data/lib/llm/providers/bedrock/error_handler.rb +1 -1
  20. data/lib/llm/providers/bedrock/models.rb +4 -4
  21. data/lib/llm/providers/bedrock/signature.rb +3 -3
  22. data/lib/llm/providers/bedrock.rb +1 -1
  23. data/lib/llm/providers/google/error_handler.rb +2 -0
  24. data/lib/llm/providers/google/files.rb +5 -5
  25. data/lib/llm/providers/google/images.rb +1 -1
  26. data/lib/llm/providers/google/models.rb +1 -1
  27. data/lib/llm/providers/google.rb +2 -2
  28. data/lib/llm/providers/ollama/error_handler.rb +2 -0
  29. data/lib/llm/providers/ollama/models.rb +1 -1
  30. data/lib/llm/providers/ollama.rb +2 -2
  31. data/lib/llm/providers/openai/audio.rb +3 -3
  32. data/lib/llm/providers/openai/error_handler.rb +2 -0
  33. data/lib/llm/providers/openai/files.rb +5 -5
  34. data/lib/llm/providers/openai/images.rb +3 -3
  35. data/lib/llm/providers/openai/models.rb +1 -1
  36. data/lib/llm/providers/openai/moderations.rb +1 -1
  37. data/lib/llm/providers/openai/responses.rb +3 -3
  38. data/lib/llm/providers/openai/vector_stores.rb +11 -11
  39. data/lib/llm/providers/openai.rb +2 -2
  40. data/lib/llm/skill.rb +1 -1
  41. data/lib/llm/tool.rb +21 -0
  42. data/lib/llm/transport/curb.rb +246 -0
  43. data/lib/llm/transport/execution.rb +1 -1
  44. data/lib/llm/transport/http.rb +9 -4
  45. data/lib/llm/transport/net_http_adapter.rb +61 -0
  46. data/lib/llm/transport/persistent_http.rb +10 -5
  47. data/lib/llm/transport/request.rb +121 -0
  48. data/lib/llm/transport/response/curb.rb +112 -0
  49. data/lib/llm/transport/response.rb +1 -0
  50. data/lib/llm/transport/utils.rb +42 -17
  51. data/lib/llm/transport.rb +17 -45
  52. data/lib/llm/version.rb +1 -1
  53. data/llm.gemspec +6 -5
  54. metadata +25 -8
@@ -11,8 +11,10 @@ class LLM::Transport
11
11
  #
12
12
  # @api private
13
13
  class HTTP < self
14
+ include NetHTTPAdapter
15
+
14
16
  INTERRUPT_ERRORS = [::IOError, ::EOFError, Errno::EBADF].freeze
15
- Request = Struct.new(:client, keyword_init: true)
17
+ ActiveRequest = Struct.new(:client, keyword_init: true)
16
18
 
17
19
  ##
18
20
  # @param [String] host
@@ -67,15 +69,18 @@ class LLM::Transport
67
69
 
68
70
  ##
69
71
  # Performs a request on the current HTTP transport.
70
- # @param [Net::HTTPRequest] request
72
+ # Accepts both {Net::HTTPRequest} and {LLM::Transport::Request}.
73
+ #
74
+ # @param [Net::HTTPRequest, LLM::Transport::Request] request
71
75
  # @param [Fiber] owner
72
76
  # @param [LLM::Object, nil] stream
73
77
  # @yieldparam [LLM::Transport::Response] response
74
78
  # @return [Object]
75
79
  def request(request, owner:, stream: nil, &b)
80
+ http_req = resolve_request(request)
76
81
  client = client()
77
- set_request(Request.new(client:), owner)
78
- perform_request(client, request, stream, &b)
82
+ set_request(ActiveRequest.new(client:), owner)
83
+ perform_request(client, http_req, stream, &b)
79
84
  ensure
80
85
  clear_request(owner)
81
86
  end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ class LLM::Transport
4
+ ##
5
+ # @api private
6
+ module NetHTTPAdapter
7
+ private
8
+
9
+ def resolve_request(request)
10
+ return request if ::Net::HTTPRequest === request
11
+ build_net_http_request(request)
12
+ end
13
+
14
+ def build_net_http_request(req)
15
+ method = req.method.downcase.to_sym
16
+ path = req.path
17
+ headers = req.headers
18
+ http_req = case method
19
+ when :get then ::Net::HTTP::Get.new(path, headers)
20
+ when :post then ::Net::HTTP::Post.new(path, headers)
21
+ when :put then ::Net::HTTP::Put.new(path, headers)
22
+ when :patch then ::Net::HTTP::Patch.new(path, headers)
23
+ when :delete then ::Net::HTTP::Delete.new(path, headers)
24
+ else ::Net::HTTP::GenericRequest.new(method, path, nil, headers)
25
+ end
26
+ if req.body
27
+ http_req.body = req.body
28
+ elsif req.body_stream
29
+ http_req.body_stream = req.body_stream
30
+ end
31
+ http_req
32
+ end
33
+
34
+ def perform_request(client, request, stream, &b)
35
+ if stream
36
+ client.request(request) do |raw|
37
+ res = LLM::Transport::Response.from(raw)
38
+ if res.success?
39
+ parser = stream.decoder.new(stream.parser.new(stream.streamer))
40
+ res.read_body(parser)
41
+ body = parser.body
42
+ res.body = (Hash === body || Array === body) ? LLM::Object.from(body) : body
43
+ else
44
+ body = +""
45
+ res.read_body { body << _1 }
46
+ res.body = body
47
+ end
48
+ ensure
49
+ parser&.free
50
+ end
51
+ elsif b
52
+ client.request(request) do |raw|
53
+ res = LLM::Transport::Response.from(raw)
54
+ res.success? ? b.call(res) : res
55
+ end
56
+ else
57
+ LLM::Transport::Response.from(client.request(request))
58
+ end
59
+ end
60
+ end
61
+ end
@@ -10,8 +10,10 @@ class LLM::Transport
10
10
  #
11
11
  # @api private
12
12
  class PersistentHTTP < self
13
+ include NetHTTPAdapter
14
+
13
15
  INTERRUPT_ERRORS = [::IOError, ::EOFError, Errno::EBADF].freeze
14
- Request = Struct.new(:client, :connection, keyword_init: true)
16
+ ActiveRequest = Struct.new(:client, :connection, keyword_init: true)
15
17
  @registry = {}
16
18
  @monitor = Monitor.new
17
19
 
@@ -79,15 +81,18 @@ class LLM::Transport
79
81
 
80
82
  ##
81
83
  # Performs a request on the current HTTP transport.
82
- # @param [Net::HTTPRequest] request
84
+ # Accepts both {Net::HTTPRequest} and {LLM::Transport::Request}.
85
+ #
86
+ # @param [Net::HTTPRequest, LLM::Transport::Request] request
83
87
  # @param [Fiber] owner
84
88
  # @param [LLM::Object, nil] stream
85
89
  # @yieldparam [LLM::Transport::Response] response
86
90
  # @return [Object]
87
91
  def request(request, owner:, stream: nil, &b)
88
- client.connection_for(URI.join(base_uri, request.path)) do |connection|
89
- set_request(Request.new(client:, connection:), owner)
90
- perform_request(connection.http, request, stream, &b)
92
+ http_req = resolve_request(request)
93
+ client.connection_for(URI.join(base_uri, http_req.path)) do |connection|
94
+ set_request(ActiveRequest.new(client:, connection:), owner)
95
+ perform_request(connection.http, http_req, stream, &b)
91
96
  end
92
97
  ensure
93
98
  clear_request(owner)
@@ -0,0 +1,121 @@
1
+ # frozen_string_literal: true
2
+
3
+ class LLM::Transport
4
+ ##
5
+ # {LLM::Transport::Request LLM::Transport::Request} defines the
6
+ # normalized request interface expected by transports.
7
+ #
8
+ # Providers build request objects through this class, then hand them
9
+ # to a transport for execution without depending on any specific HTTP
10
+ # client library.
11
+ class Request
12
+ ##
13
+ # @return [Object, nil]
14
+ attr_accessor :body
15
+
16
+ ##
17
+ # @return [IO, nil]
18
+ attr_accessor :body_stream
19
+
20
+ ##
21
+ # @return [String]
22
+ attr_reader :method
23
+
24
+ ##
25
+ # @return [String]
26
+ attr_reader :path
27
+
28
+ ##
29
+ # @return [Hash]
30
+ attr_reader :headers
31
+
32
+ ##
33
+ # @param [String] path
34
+ # @param [Hash, nil] headers
35
+ # @return [LLM::Transport::Request]
36
+ def self.get(path, headers = nil)
37
+ new("GET", path, headers)
38
+ end
39
+
40
+ ##
41
+ # @param [String] path
42
+ # @param [Hash, nil] headers
43
+ # @return [LLM::Transport::Request]
44
+ def self.post(path, headers = nil)
45
+ new("POST", path, headers)
46
+ end
47
+
48
+ ##
49
+ # @param [String] path
50
+ # @param [Hash, nil] headers
51
+ # @return [LLM::Transport::Request]
52
+ def self.put(path, headers = nil)
53
+ new("PUT", path, headers)
54
+ end
55
+
56
+ ##
57
+ # @param [String] path
58
+ # @param [Hash, nil] headers
59
+ # @return [LLM::Transport::Request]
60
+ def self.patch(path, headers = nil)
61
+ new("PATCH", path, headers)
62
+ end
63
+
64
+ ##
65
+ # @param [String] path
66
+ # @param [Hash, nil] headers
67
+ # @return [LLM::Transport::Request]
68
+ def self.delete(path, headers = nil)
69
+ new("DELETE", path, headers)
70
+ end
71
+
72
+ ##
73
+ # @param [String] method
74
+ # @param [String] path
75
+ # @param [Hash, nil] headers
76
+ # @return [LLM::Transport::Request]
77
+ def initialize(method, path, headers = nil)
78
+ @method = method.to_s.upcase
79
+ @path = path.to_s
80
+ @headers = {}
81
+ (headers || {}).each { self[_1] = _2 }
82
+ end
83
+
84
+ ##
85
+ # @param [String] key
86
+ # @return [String, nil]
87
+ def [](key)
88
+ @headers[normalize_header(key)]
89
+ end
90
+
91
+ ##
92
+ # @param [String] key
93
+ # @param [Object] value
94
+ # @return [String]
95
+ def []=(key, value)
96
+ @headers[normalize_header(key)] = value.to_s
97
+ end
98
+
99
+ ##
100
+ # @yieldparam [String] key
101
+ # @yieldparam [String] value
102
+ # @return [Hash]
103
+ def each_header(&block)
104
+ @headers.each(&block)
105
+ end
106
+
107
+ ##
108
+ # @return [String]
109
+ def inspect
110
+ "#<#{self.class.name}:0x#{object_id.to_s(16)}" \
111
+ " @method=#{@method} @path=#{@path}" \
112
+ " @headers=#{@headers.inspect}>"
113
+ end
114
+
115
+ private
116
+
117
+ def normalize_header(key)
118
+ key.to_s.downcase
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,112 @@
1
+ # frozen_string_literal: true
2
+
3
+ class LLM::Transport::Response
4
+ ##
5
+ # {LLM::Transport::Response::Curb LLM::Transport::Response::Curb}
6
+ # adapts a raw status code, header hash, and body string to the
7
+ # {LLM::Transport::Response LLM::Transport::Response} interface.
8
+ #
9
+ # This is the response wrapper used by the
10
+ # {LLM::Transport::Curb LLM::Transport::Curb} transport.
11
+ class Curb < self
12
+ ##
13
+ # @return [Integer]
14
+ attr_reader :code
15
+
16
+ ##
17
+ # @return [Hash]
18
+ attr_reader :headers
19
+
20
+ ##
21
+ # @return [String]
22
+ attr_accessor :body
23
+
24
+ ##
25
+ # @param [#to_i] code
26
+ # @param [Hash] headers
27
+ # @param [String] body
28
+ # @return [LLM::Transport::Response::Curb]
29
+ def initialize(code, headers = {}, body = +"")
30
+ @code = code.to_i
31
+ @headers = {}
32
+ (headers || {}).each { @headers[_1.to_s.downcase] = _2.to_s }
33
+ @body = body
34
+ end
35
+
36
+ ##
37
+ # @param [String] key
38
+ # @return [String, nil]
39
+ def [](key)
40
+ @headers[key.to_s.downcase]
41
+ end
42
+
43
+ ##
44
+ # @param [Object, nil] dest
45
+ # @yieldparam [String] chunk
46
+ # @return [void]
47
+ def read_body(dest = nil, &block)
48
+ return @body unless block_given? || dest
49
+ if dest
50
+ dest << @body.to_s
51
+ else
52
+ yield @body.to_s
53
+ end
54
+ @body
55
+ end
56
+
57
+ ##
58
+ # @return [Boolean]
59
+ def success?
60
+ code.between?(200, 299)
61
+ end
62
+
63
+ ##
64
+ # @return [Boolean]
65
+ def ok?
66
+ code == 200
67
+ end
68
+
69
+ ##
70
+ # @return [Boolean]
71
+ def bad_request?
72
+ code == 400
73
+ end
74
+
75
+ ##
76
+ # @return [Boolean]
77
+ def unauthorized?
78
+ code == 401
79
+ end
80
+
81
+ ##
82
+ # @return [Boolean]
83
+ def forbidden?
84
+ code == 403
85
+ end
86
+
87
+ ##
88
+ # @return [Boolean]
89
+ def not_found?
90
+ code == 404
91
+ end
92
+
93
+ ##
94
+ # @return [Boolean]
95
+ def rate_limited?
96
+ code == 429
97
+ end
98
+
99
+ ##
100
+ # @return [Boolean]
101
+ def server_error?
102
+ code.between?(500, 599)
103
+ end
104
+
105
+ ##
106
+ # @return [String]
107
+ def inspect
108
+ "#<#{self.class.name}:0x#{object_id.to_s(16)}" \
109
+ " @code=#{@code} @headers=#{@headers.inspect}>"
110
+ end
111
+ end
112
+ end
@@ -17,6 +17,7 @@ class LLM::Transport
17
17
  # how the request was actually performed.
18
18
  class Response
19
19
  require_relative "response/http"
20
+ require_relative "response/curb"
20
21
 
21
22
  ##
22
23
  # @param [Object] res
@@ -4,32 +4,57 @@ class LLM::Transport
4
4
  ##
5
5
  # Shared utility methods for HTTP-backed transports.
6
6
  #
7
+ # These methods resolve the transport options accepted by providers,
8
+ # MCP HTTP clients, and A2A HTTP clients into concrete
9
+ # {LLM::Transport} instances.
10
+ #
7
11
  # @api private
8
12
  module Utils
9
13
  extend self
10
- private
11
14
 
12
- def resolve_transport(uri, transport, timeout)
13
- return default_transport(uri, timeout) if transport.nil?
14
- if Class === transport && transport <= LLM::Transport
15
- transport.new(
16
- host: uri.host,
17
- port: uri.port,
18
- timeout:,
19
- ssl: uri.scheme == "https"
20
- )
15
+ ##
16
+ # Resolves a transport configuration into a transport instance.
17
+ #
18
+ # Nil values use the default Net::HTTP transport, or the persistent
19
+ # Net::HTTP transport when `persistent` is true. Transport subclasses
20
+ # are instantiated with the endpoint settings, symbols are resolved
21
+ # through {LLM::Transport} shortcut methods, and transport instances
22
+ # are returned as-is.
23
+ #
24
+ # @param [String] host
25
+ # @param [Integer] port
26
+ # @param [Integer, nil] timeout
27
+ # @param [Boolean] ssl
28
+ # @param [Boolean] persistent
29
+ # @param [LLM::Transport, Class, Symbol, nil] transport
30
+ # @return [LLM::Transport]
31
+ def resolve_transport(host:, port:, timeout:, ssl:, persistent:, transport:)
32
+ if transport.nil?
33
+ default_transport(host:, port:, timeout:, ssl:, persistent:)
34
+ elsif Class === transport && transport <= LLM::Transport
35
+ transport.new(host:, port:, timeout:, ssl:)
36
+ elsif Symbol === transport
37
+ transport = LLM::Transport.public_send(transport)
38
+ transport.new(host:, port:, timeout:, ssl:)
21
39
  else
22
40
  transport
23
41
  end
24
42
  end
25
43
 
26
- def default_transport(uri, timeout)
27
- LLM::Transport::HTTP.new(
28
- host: uri.host,
29
- port: uri.port,
30
- timeout:,
31
- ssl: uri.scheme == "https"
32
- )
44
+ private
45
+
46
+ ##
47
+ # Builds the default Net::HTTP transport for an endpoint.
48
+ #
49
+ # @param [String] host
50
+ # @param [Integer] port
51
+ # @param [Integer, nil] timeout
52
+ # @param [Boolean] ssl
53
+ # @param [Boolean] persistent
54
+ # @return [LLM::Transport]
55
+ def default_transport(host:, port:, timeout:, ssl:, persistent:)
56
+ target = persistent ? LLM::Transport::PersistentHTTP : LLM::Transport::HTTP
57
+ target.new(host:, port:, timeout:, ssl:)
33
58
  end
34
59
  end
35
60
  end
data/lib/llm/transport.rb CHANGED
@@ -9,10 +9,10 @@ module LLM
9
9
  # execute provider requests without changing request adapters or
10
10
  # response adapters.
11
11
  #
12
- # Providers currently construct {Net::HTTPRequest Net::HTTPRequest}
13
- # objects before delegating to a transport. Custom transports are
14
- # therefore expected to execute those requests directly, or transform
15
- # them into backend-specific request objects before execution.
12
+ # Providers should construct {LLM::Transport::Request} objects before
13
+ # delegating to a transport. Custom transports can execute those
14
+ # requests directly, or transform them into backend-specific request
15
+ # objects before execution.
16
16
  #
17
17
  # Only {#request} is required. The remaining methods are optional hooks
18
18
  # for features such as interruption, request ownership, or persistence,
@@ -26,11 +26,14 @@ module LLM
26
26
  # can rely on one normalized response contract instead of
27
27
  # transport-specific classes.
28
28
  class Transport
29
+ require_relative "transport/request"
29
30
  require_relative "transport/response"
30
31
  require_relative "transport/utils"
31
32
  require_relative "transport/stream_decoder"
33
+ require_relative "transport/net_http_adapter"
32
34
  require_relative "transport/http"
33
35
  require_relative "transport/persistent_http"
36
+ require_relative "transport/curb"
34
37
  require_relative "transport/execution"
35
38
 
36
39
  ##
@@ -47,9 +50,17 @@ module LLM
47
50
  PersistentHTTP
48
51
  end
49
52
 
53
+ ##
54
+ # Returns the optional libcurl (curb) transport class.
55
+ # Requires the `curb` gem.
56
+ # @return [Class]
57
+ def self.curb
58
+ Curb
59
+ end
60
+
50
61
  ##
51
62
  # Performs a request through the transport.
52
- # @param [Net::HTTPRequest] request
63
+ # @param [LLM::Transport::Request] request
53
64
  # @param [Object] owner
54
65
  # @param [LLM::Object, nil] stream
55
66
  # @yieldparam [LLM::Transport::Response] response
@@ -90,51 +101,12 @@ module LLM
90
101
  end
91
102
 
92
103
  ##
93
- # @note
94
- # Custom transports may be able to reuse this helper when they
95
- # operate on Net::HTTPRequest objects, or implement their own
96
- # request body preparation path instead.
97
- # @param [Net::HTTPRequest] request
104
+ # @param [LLM::Transport::Request] request
98
105
  # @param [IO] io
99
106
  # @return [void]
100
107
  def set_body_stream(request, io)
101
108
  request.body_stream = io
102
109
  request["transfer-encoding"] = "chunked" unless request["content-length"]
103
110
  end
104
-
105
- private
106
-
107
- ##
108
- # @api private
109
- # @note
110
- # Custom transports may be able to reuse this helper when they
111
- # execute requests through a Net::HTTP-compatible client, or
112
- # implement their own request execution path instead.
113
- def perform_request(client, request, stream, &b)
114
- if stream
115
- client.request(request) do |raw|
116
- res = LLM::Transport::Response.from(raw)
117
- if res.success?
118
- parser = stream.decoder.new(stream.parser.new(stream.streamer))
119
- res.read_body(parser)
120
- body = parser.body
121
- res.body = (Hash === body || Array === body) ? LLM::Object.from(body) : body
122
- else
123
- body = +""
124
- res.read_body { body << _1 }
125
- res.body = body
126
- end
127
- ensure
128
- parser&.free
129
- end
130
- elsif b
131
- client.request(request) do |raw|
132
- res = LLM::Transport::Response.from(raw)
133
- res.success? ? b.call(res) : res
134
- end
135
- else
136
- LLM::Transport::Response.from(client.request(request))
137
- end
138
- end
139
111
  end
140
112
  end
data/lib/llm/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module LLM
4
- VERSION = "11.1.0"
4
+ VERSION = "11.3.0"
5
5
  end
data/llm.gemspec CHANGED
@@ -5,8 +5,8 @@ require_relative "lib/llm/version"
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = "llm.rb"
7
7
  spec.version = LLM::VERSION
8
- spec.authors = ["Antar Azri", "0x1eef", "Christos Maris", "Rodrigo Serrano"]
9
- spec.email = ["azantar@proton.me", "0x1eef@hardenedbsd.org"]
8
+ spec.authors = ["0x1eef (Robert)", "Antar Azri", "Rodrigo Serrano", "Christos Maris"]
9
+ spec.email = ["robert@4.4bsd.dev"]
10
10
 
11
11
  spec.summary = "Ruby's most capable AI runtime"
12
12
  spec.description = <<~DESC
@@ -28,10 +28,10 @@ Gem::Specification.new do |spec|
28
28
  spec.license = "0BSD"
29
29
  spec.required_ruby_version = ">= 3.3.0"
30
30
 
31
- spec.homepage = "https://github.com/llmrb/llm.rb"
32
- spec.metadata["homepage_uri"] = "https://github.com/llmrb/llm.rb"
31
+ spec.homepage = "https://llmrb.github.io"
32
+ spec.metadata["homepage_uri"] = spec.homepage
33
33
  spec.metadata["source_code_uri"] = "https://github.com/llmrb/llm.rb"
34
- spec.metadata["documentation_uri"] = "https://0x1eef.github.io/x/llm.rb"
34
+ spec.metadata["documentation_uri"] = "https://llmrb.github.io/llm.rb"
35
35
  spec.metadata["changelog_uri"] = "https://0x1eef.github.io/x/llm.rb/file.CHANGELOG.html"
36
36
 
37
37
  spec.files = Dir[
@@ -60,4 +60,5 @@ Gem::Specification.new do |spec|
60
60
  spec.add_development_dependency "sqlite3", "~> 2.0"
61
61
  spec.add_development_dependency "xchan.rb", "~> 0.20"
62
62
  spec.add_development_dependency "pg", "~> 1.5"
63
+ spec.add_development_dependency "irb", "~> 1.18"
63
64
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: llm.rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 11.1.0
4
+ version: 11.3.0
5
5
  platform: ruby
6
6
  authors:
7
+ - 0x1eef (Robert)
7
8
  - Antar Azri
8
- - '0x1eef'
9
- - Christos Maris
10
9
  - Rodrigo Serrano
10
+ - Christos Maris
11
11
  bindir: bin
12
12
  cert_chain: []
13
13
  date: 1980-01-02 00:00:00.000000000 Z
@@ -264,6 +264,20 @@ dependencies:
264
264
  - - "~>"
265
265
  - !ruby/object:Gem::Version
266
266
  version: '1.5'
267
+ - !ruby/object:Gem::Dependency
268
+ name: irb
269
+ requirement: !ruby/object:Gem::Requirement
270
+ requirements:
271
+ - - "~>"
272
+ - !ruby/object:Gem::Version
273
+ version: '1.18'
274
+ type: :development
275
+ prerelease: false
276
+ version_requirements: !ruby/object:Gem::Requirement
277
+ requirements:
278
+ - - "~>"
279
+ - !ruby/object:Gem::Version
280
+ version: '1.18'
267
281
  description: |
268
282
  llm.rb is Ruby's most capable AI runtime.
269
283
 
@@ -279,8 +293,7 @@ description: |
279
293
  tool execution through threads, tasks (via async gem), fibers, ractors,
280
294
  and fork (via xchan.rb gem).
281
295
  email:
282
- - azantar@proton.me
283
- - 0x1eef@hardenedbsd.org
296
+ - robert@4.4bsd.dev
284
297
  executables: []
285
298
  extensions: []
286
299
  extra_rdoc_files: []
@@ -482,10 +495,14 @@ files:
482
495
  - lib/llm/tracer/null.rb
483
496
  - lib/llm/tracer/telemetry.rb
484
497
  - lib/llm/transport.rb
498
+ - lib/llm/transport/curb.rb
485
499
  - lib/llm/transport/execution.rb
486
500
  - lib/llm/transport/http.rb
501
+ - lib/llm/transport/net_http_adapter.rb
487
502
  - lib/llm/transport/persistent_http.rb
503
+ - lib/llm/transport/request.rb
488
504
  - lib/llm/transport/response.rb
505
+ - lib/llm/transport/response/curb.rb
489
506
  - lib/llm/transport/response/http.rb
490
507
  - lib/llm/transport/stream_decoder.rb
491
508
  - lib/llm/transport/utils.rb
@@ -495,13 +512,13 @@ files:
495
512
  - lib/sequel/plugins/agent.rb
496
513
  - lib/sequel/plugins/llm.rb
497
514
  - llm.gemspec
498
- homepage: https://github.com/llmrb/llm.rb
515
+ homepage: https://llmrb.github.io
499
516
  licenses:
500
517
  - 0BSD
501
518
  metadata:
502
- homepage_uri: https://github.com/llmrb/llm.rb
519
+ homepage_uri: https://llmrb.github.io
503
520
  source_code_uri: https://github.com/llmrb/llm.rb
504
- documentation_uri: https://0x1eef.github.io/x/llm.rb
521
+ documentation_uri: https://llmrb.github.io/llm.rb
505
522
  changelog_uri: https://0x1eef.github.io/x/llm.rb/file.CHANGELOG.html
506
523
  rdoc_options: []
507
524
  require_paths: