llm.rb 4.1.0 → 4.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.
- checksums.yaml +4 -4
- data/LICENSE +2 -2
- data/README.md +241 -166
- data/lib/llm/agent.rb +65 -37
- data/lib/llm/bot.rb +118 -30
- data/lib/llm/buffer.rb +6 -0
- data/lib/llm/function/tracing.rb +19 -0
- data/lib/llm/function.rb +28 -3
- data/lib/llm/json_adapter.rb +12 -12
- data/lib/llm/message.rb +19 -4
- data/lib/llm/prompt.rb +85 -0
- data/lib/llm/provider.rb +62 -10
- data/lib/llm/providers/anthropic/error_handler.rb +27 -5
- data/lib/llm/providers/anthropic/files.rb +22 -16
- data/lib/llm/providers/anthropic/models.rb +4 -3
- data/lib/llm/providers/anthropic.rb +6 -5
- data/lib/llm/providers/deepseek.rb +3 -3
- data/lib/llm/providers/gemini/error_handler.rb +34 -12
- data/lib/llm/providers/gemini/files.rb +19 -14
- data/lib/llm/providers/gemini/images.rb +4 -3
- data/lib/llm/providers/gemini/models.rb +4 -3
- data/lib/llm/providers/gemini.rb +9 -7
- data/lib/llm/providers/llamacpp.rb +3 -3
- data/lib/llm/providers/ollama/error_handler.rb +28 -6
- data/lib/llm/providers/ollama/models.rb +4 -3
- data/lib/llm/providers/ollama.rb +9 -7
- data/lib/llm/providers/openai/audio.rb +10 -7
- data/lib/llm/providers/openai/error_handler.rb +41 -14
- data/lib/llm/providers/openai/files.rb +19 -14
- data/lib/llm/providers/openai/images.rb +10 -7
- data/lib/llm/providers/openai/models.rb +4 -3
- data/lib/llm/providers/openai/moderations.rb +4 -3
- data/lib/llm/providers/openai/responses.rb +10 -7
- data/lib/llm/providers/openai/vector_stores.rb +34 -23
- data/lib/llm/providers/openai.rb +9 -7
- data/lib/llm/providers/xai.rb +3 -3
- data/lib/llm/providers/zai.rb +2 -2
- data/lib/llm/schema/object.rb +4 -4
- data/lib/llm/schema.rb +16 -2
- data/lib/llm/server_tool.rb +3 -3
- data/lib/llm/session/deserializer.rb +36 -0
- data/lib/llm/session.rb +3 -0
- data/lib/llm/tracer/logger.rb +192 -0
- data/lib/llm/tracer/null.rb +49 -0
- data/lib/llm/tracer/telemetry.rb +255 -0
- data/lib/llm/tracer.rb +134 -0
- data/lib/llm/version.rb +1 -1
- data/lib/llm.rb +4 -3
- data/llm.gemspec +6 -3
- metadata +41 -5
- data/lib/llm/builder.rb +0 -79
data/lib/llm/tracer.rb
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module LLM
|
|
4
|
+
##
|
|
5
|
+
# The {LLM::Tracer LLM::Tracer} is the superclass of all
|
|
6
|
+
# LLM tracers. It can be helpful for implementing instrumentation
|
|
7
|
+
# and hooking into the lifecycle of an LLM request. See
|
|
8
|
+
# {LLM::Tracer::Telemetry LLM::Tracer::Telemetry}, and
|
|
9
|
+
# {LLM::Tracer::Logger LLM::Tracer::Logger} for example
|
|
10
|
+
# tracer implementations.
|
|
11
|
+
class Tracer
|
|
12
|
+
require_relative "tracer/logger"
|
|
13
|
+
require_relative "tracer/telemetry"
|
|
14
|
+
require_relative "tracer/null"
|
|
15
|
+
|
|
16
|
+
##
|
|
17
|
+
# @param [LLM::Provider] provider
|
|
18
|
+
# A provider
|
|
19
|
+
# @param [Hash] options
|
|
20
|
+
# A hash of options
|
|
21
|
+
def initialize(provider, options = {})
|
|
22
|
+
@provider = provider
|
|
23
|
+
@options = {}
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
##
|
|
27
|
+
# Called before an LLM provider request is executed.
|
|
28
|
+
# @param [String] operation
|
|
29
|
+
# @param [String] model
|
|
30
|
+
# @return [void]
|
|
31
|
+
def on_request_start(operation:, model: nil)
|
|
32
|
+
raise NotImplementedError, "#{self.class} does not implement '#{__method__}'"
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
##
|
|
36
|
+
# Called after an LLM provider request succeeds.
|
|
37
|
+
# @param [String] operation
|
|
38
|
+
# @param [String] model
|
|
39
|
+
# @param [LLM::Response] res
|
|
40
|
+
# @param [Object, nil] span
|
|
41
|
+
# @return [void]
|
|
42
|
+
def on_request_finish(operation:, res:, model: nil, span: nil)
|
|
43
|
+
raise NotImplementedError, "#{self.class} does not implement '#{__method__}'"
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
##
|
|
47
|
+
# Called when an LLM provider request fails.
|
|
48
|
+
# @param [LLM::Error] ex
|
|
49
|
+
# @param [Object, nil] span
|
|
50
|
+
# @return [void]
|
|
51
|
+
def on_request_error(ex:, span:)
|
|
52
|
+
raise NotImplementedError, "#{self.class} does not implement '#{__method__}'"
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
##
|
|
56
|
+
# Called before a local tool/function executes.
|
|
57
|
+
# @param [String] id
|
|
58
|
+
# The tool call ID assigned by the model/provider
|
|
59
|
+
# @param [String] name
|
|
60
|
+
# The tool (function) name.
|
|
61
|
+
# @param [Hash] arguments
|
|
62
|
+
# The parsed tool arguments.
|
|
63
|
+
# @param [String] model
|
|
64
|
+
# The model name
|
|
65
|
+
# @return [void]
|
|
66
|
+
def on_tool_start(id:, name:, arguments:, model:)
|
|
67
|
+
raise NotImplementedError, "#{self.class} does not implement '#{__method__}'"
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
##
|
|
71
|
+
# Called after a local tool/function succeeds.
|
|
72
|
+
# @param [LLM::Function::Return] result
|
|
73
|
+
# The tool return object.
|
|
74
|
+
# @param [Object, nil] span
|
|
75
|
+
# The span/context object returned by {#on_tool_start}.
|
|
76
|
+
# @return [void]
|
|
77
|
+
def on_tool_finish(result:, span:)
|
|
78
|
+
raise NotImplementedError, "#{self.class} does not implement '#{__method__}'"
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
##
|
|
82
|
+
# Called when a local tool/function raises.
|
|
83
|
+
# @param [Exception] ex
|
|
84
|
+
# The raised error.
|
|
85
|
+
# @param [Object, nil] span
|
|
86
|
+
# The span/context object returned by {#on_tool_start}.
|
|
87
|
+
# @return [void]
|
|
88
|
+
def on_tool_error(ex:, span:)
|
|
89
|
+
raise NotImplementedError, "#{self.class} does not implement '#{__method__}'"
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
##
|
|
93
|
+
# @return [String]
|
|
94
|
+
def inspect
|
|
95
|
+
"#<#{self.class.name}:0x#{object_id.to_s(16)} @provider=#{@provider.class} @tracer=#{@tracer.inspect}>"
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
##
|
|
99
|
+
# @return [Array]
|
|
100
|
+
def spans
|
|
101
|
+
[]
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
##
|
|
105
|
+
# Flush the tracer
|
|
106
|
+
# @note
|
|
107
|
+
# This method is only implemented by the {LLM::Tracer::Telemetry} tracer.
|
|
108
|
+
# It is a noop for other tracers.
|
|
109
|
+
# @return [nil]
|
|
110
|
+
def flush!
|
|
111
|
+
nil
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
private
|
|
115
|
+
|
|
116
|
+
##
|
|
117
|
+
# @return [String]
|
|
118
|
+
def provider_name
|
|
119
|
+
@provider.class.name.split("::").last.downcase
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
##
|
|
123
|
+
# @return [String]
|
|
124
|
+
def provider_host
|
|
125
|
+
@provider.instance_variable_get(:@host)
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
##
|
|
129
|
+
# @return [String]
|
|
130
|
+
def provider_port
|
|
131
|
+
@provider.instance_variable_get(:@port)
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
data/lib/llm/version.rb
CHANGED
data/lib/llm.rb
CHANGED
|
@@ -3,10 +3,11 @@
|
|
|
3
3
|
module LLM
|
|
4
4
|
require "stringio"
|
|
5
5
|
require_relative "llm/json_adapter"
|
|
6
|
+
require_relative "llm/tracer"
|
|
6
7
|
require_relative "llm/error"
|
|
7
8
|
require_relative "llm/contract"
|
|
8
9
|
require_relative "llm/usage"
|
|
9
|
-
require_relative "llm/
|
|
10
|
+
require_relative "llm/prompt"
|
|
10
11
|
require_relative "llm/schema"
|
|
11
12
|
require_relative "llm/object"
|
|
12
13
|
require_relative "llm/version"
|
|
@@ -17,7 +18,7 @@ module LLM
|
|
|
17
18
|
require_relative "llm/multipart"
|
|
18
19
|
require_relative "llm/file"
|
|
19
20
|
require_relative "llm/provider"
|
|
20
|
-
require_relative "llm/
|
|
21
|
+
require_relative "llm/session"
|
|
21
22
|
require_relative "llm/agent"
|
|
22
23
|
require_relative "llm/buffer"
|
|
23
24
|
require_relative "llm/function"
|
|
@@ -35,7 +36,7 @@ module LLM
|
|
|
35
36
|
##
|
|
36
37
|
# Returns the JSON adapter used by the library
|
|
37
38
|
# @return [Class]
|
|
38
|
-
# Returns a class that responds to
|
|
39
|
+
# Returns a class that responds to `dump` and `load`
|
|
39
40
|
def json
|
|
40
41
|
@json ||= JSONAdapter::JSON
|
|
41
42
|
end
|
data/llm.gemspec
CHANGED
|
@@ -16,12 +16,13 @@ Gem::Specification.new do |spec|
|
|
|
16
16
|
SUMMARY
|
|
17
17
|
|
|
18
18
|
spec.description = spec.summary
|
|
19
|
-
spec.homepage = "https://github.com/llmrb/llm"
|
|
20
19
|
spec.license = "0BSD"
|
|
21
20
|
spec.required_ruby_version = ">= 3.2.0"
|
|
22
21
|
|
|
23
|
-
spec.
|
|
24
|
-
spec.metadata["
|
|
22
|
+
spec.homepage = "https://github.com/llmrb/llm.rb"
|
|
23
|
+
spec.metadata["homepage_uri"] = "https://github.com/llmrb/llm.rb"
|
|
24
|
+
spec.metadata["source_code_uri"] = "https://github.com/llmrb/llm.rb"
|
|
25
|
+
spec.metadata["documentation_uri"] = "https://0x1eef.github.io/x/llm.rb"
|
|
25
26
|
|
|
26
27
|
spec.files = Dir[
|
|
27
28
|
"README.md", "LICENSE",
|
|
@@ -41,4 +42,6 @@ Gem::Specification.new do |spec|
|
|
|
41
42
|
spec.add_development_dependency "vcr", "~> 6.0"
|
|
42
43
|
spec.add_development_dependency "dotenv", "~> 2.8"
|
|
43
44
|
spec.add_development_dependency "net-http-persistent", "~> 4.0"
|
|
45
|
+
spec.add_development_dependency "opentelemetry-sdk", "~> 1.10"
|
|
46
|
+
spec.add_development_dependency "logger", "~> 1.7"
|
|
44
47
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: llm.rb
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 4.
|
|
4
|
+
version: 4.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Antar Azri
|
|
@@ -164,6 +164,34 @@ dependencies:
|
|
|
164
164
|
- - "~>"
|
|
165
165
|
- !ruby/object:Gem::Version
|
|
166
166
|
version: '4.0'
|
|
167
|
+
- !ruby/object:Gem::Dependency
|
|
168
|
+
name: opentelemetry-sdk
|
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
|
170
|
+
requirements:
|
|
171
|
+
- - "~>"
|
|
172
|
+
- !ruby/object:Gem::Version
|
|
173
|
+
version: '1.10'
|
|
174
|
+
type: :development
|
|
175
|
+
prerelease: false
|
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
177
|
+
requirements:
|
|
178
|
+
- - "~>"
|
|
179
|
+
- !ruby/object:Gem::Version
|
|
180
|
+
version: '1.10'
|
|
181
|
+
- !ruby/object:Gem::Dependency
|
|
182
|
+
name: logger
|
|
183
|
+
requirement: !ruby/object:Gem::Requirement
|
|
184
|
+
requirements:
|
|
185
|
+
- - "~>"
|
|
186
|
+
- !ruby/object:Gem::Version
|
|
187
|
+
version: '1.7'
|
|
188
|
+
type: :development
|
|
189
|
+
prerelease: false
|
|
190
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
191
|
+
requirements:
|
|
192
|
+
- - "~>"
|
|
193
|
+
- !ruby/object:Gem::Version
|
|
194
|
+
version: '1.7'
|
|
167
195
|
description: llm.rb is a zero-dependency Ruby toolkit for Large Language Models that
|
|
168
196
|
includes OpenAI, Gemini, Anthropic, xAI (grok), zAI, DeepSeek, Ollama, and LlamaCpp.
|
|
169
197
|
The toolkit includes full support for chat, streaming, tool calling, audio, images,
|
|
@@ -181,7 +209,6 @@ files:
|
|
|
181
209
|
- lib/llm/agent.rb
|
|
182
210
|
- lib/llm/bot.rb
|
|
183
211
|
- lib/llm/buffer.rb
|
|
184
|
-
- lib/llm/builder.rb
|
|
185
212
|
- lib/llm/client.rb
|
|
186
213
|
- lib/llm/contract.rb
|
|
187
214
|
- lib/llm/contract/completion.rb
|
|
@@ -192,6 +219,7 @@ files:
|
|
|
192
219
|
- lib/llm/eventstream/parser.rb
|
|
193
220
|
- lib/llm/file.rb
|
|
194
221
|
- lib/llm/function.rb
|
|
222
|
+
- lib/llm/function/tracing.rb
|
|
195
223
|
- lib/llm/json_adapter.rb
|
|
196
224
|
- lib/llm/message.rb
|
|
197
225
|
- lib/llm/mime.rb
|
|
@@ -200,6 +228,7 @@ files:
|
|
|
200
228
|
- lib/llm/object.rb
|
|
201
229
|
- lib/llm/object/builder.rb
|
|
202
230
|
- lib/llm/object/kernel.rb
|
|
231
|
+
- lib/llm/prompt.rb
|
|
203
232
|
- lib/llm/provider.rb
|
|
204
233
|
- lib/llm/providers/anthropic.rb
|
|
205
234
|
- lib/llm/providers/anthropic/error_handler.rb
|
|
@@ -283,18 +312,25 @@ files:
|
|
|
283
312
|
- lib/llm/schema/string.rb
|
|
284
313
|
- lib/llm/schema/version.rb
|
|
285
314
|
- lib/llm/server_tool.rb
|
|
315
|
+
- lib/llm/session.rb
|
|
316
|
+
- lib/llm/session/deserializer.rb
|
|
286
317
|
- lib/llm/tool.rb
|
|
287
318
|
- lib/llm/tool/param.rb
|
|
319
|
+
- lib/llm/tracer.rb
|
|
320
|
+
- lib/llm/tracer/logger.rb
|
|
321
|
+
- lib/llm/tracer/null.rb
|
|
322
|
+
- lib/llm/tracer/telemetry.rb
|
|
288
323
|
- lib/llm/usage.rb
|
|
289
324
|
- lib/llm/utils.rb
|
|
290
325
|
- lib/llm/version.rb
|
|
291
326
|
- llm.gemspec
|
|
292
|
-
homepage: https://github.com/llmrb/llm
|
|
327
|
+
homepage: https://github.com/llmrb/llm.rb
|
|
293
328
|
licenses:
|
|
294
329
|
- 0BSD
|
|
295
330
|
metadata:
|
|
296
|
-
homepage_uri: https://github.com/llmrb/llm
|
|
297
|
-
source_code_uri: https://github.com/llmrb/llm
|
|
331
|
+
homepage_uri: https://github.com/llmrb/llm.rb
|
|
332
|
+
source_code_uri: https://github.com/llmrb/llm.rb
|
|
333
|
+
documentation_uri: https://0x1eef.github.io/x/llm.rb
|
|
298
334
|
rdoc_options: []
|
|
299
335
|
require_paths:
|
|
300
336
|
- lib
|
data/lib/llm/builder.rb
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
##
|
|
4
|
-
# The {LLM::Builder LLM::Builder} class can build a collection
|
|
5
|
-
# of messages that can be sent in a single request.
|
|
6
|
-
#
|
|
7
|
-
# @note
|
|
8
|
-
# This API is not meant to be used directly.
|
|
9
|
-
#
|
|
10
|
-
# @example
|
|
11
|
-
# llm = LLM.openai(key: ENV["KEY"])
|
|
12
|
-
# bot = LLM::Bot.new(llm)
|
|
13
|
-
# prompt = bot.build_prompt do
|
|
14
|
-
# it.system "Your task is to assist the user"
|
|
15
|
-
# it.user "Hello. Can you assist me?"
|
|
16
|
-
# end
|
|
17
|
-
# res = bot.chat(prompt)
|
|
18
|
-
class LLM::Builder
|
|
19
|
-
##
|
|
20
|
-
# @param [Proc] evaluator
|
|
21
|
-
# The evaluator
|
|
22
|
-
def initialize(provider, &evaluator)
|
|
23
|
-
@provider = provider
|
|
24
|
-
@buffer = []
|
|
25
|
-
@evaluator = evaluator
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
##
|
|
29
|
-
# @return [void]
|
|
30
|
-
def call
|
|
31
|
-
@evaluator.call(self)
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
##
|
|
35
|
-
# @param [String] content
|
|
36
|
-
# The message
|
|
37
|
-
# @param [Symbol] role
|
|
38
|
-
# The role (eg user, system)
|
|
39
|
-
# @return [void]
|
|
40
|
-
def chat(content, role: @provider.user_role)
|
|
41
|
-
role = case role.to_sym
|
|
42
|
-
when :system then @provider.system_role
|
|
43
|
-
when :user then @provider.user_role
|
|
44
|
-
when :developer then @provider.developer_role
|
|
45
|
-
else role
|
|
46
|
-
end
|
|
47
|
-
@buffer << LLM::Message.new(role, content)
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
##
|
|
51
|
-
# @param [String] content
|
|
52
|
-
# The message content
|
|
53
|
-
# @return [void]
|
|
54
|
-
def user(content)
|
|
55
|
-
chat(content, role: @provider.user_role)
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
##
|
|
59
|
-
# @param [String] content
|
|
60
|
-
# The message content
|
|
61
|
-
# @return [void]
|
|
62
|
-
def system(content)
|
|
63
|
-
chat(content, role: @provider.system_role)
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
##
|
|
67
|
-
# @param [String] content
|
|
68
|
-
# The message content
|
|
69
|
-
# @return [void]
|
|
70
|
-
def developer(content)
|
|
71
|
-
chat(content, role: @provider.developer_role)
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
##
|
|
75
|
-
# @return [Array]
|
|
76
|
-
def to_a
|
|
77
|
-
@buffer.dup
|
|
78
|
-
end
|
|
79
|
-
end
|