llm.rb 4.1.0 → 4.2.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 (49) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +2 -2
  3. data/README.md +186 -172
  4. data/lib/llm/agent.rb +49 -37
  5. data/lib/llm/bot.rb +57 -28
  6. data/lib/llm/function/tracing.rb +19 -0
  7. data/lib/llm/function.rb +16 -3
  8. data/lib/llm/json_adapter.rb +1 -1
  9. data/lib/llm/message.rb +7 -0
  10. data/lib/llm/prompt.rb +85 -0
  11. data/lib/llm/provider.rb +56 -10
  12. data/lib/llm/providers/anthropic/error_handler.rb +27 -5
  13. data/lib/llm/providers/anthropic/files.rb +22 -16
  14. data/lib/llm/providers/anthropic/models.rb +4 -3
  15. data/lib/llm/providers/anthropic.rb +6 -5
  16. data/lib/llm/providers/deepseek.rb +3 -3
  17. data/lib/llm/providers/gemini/error_handler.rb +34 -12
  18. data/lib/llm/providers/gemini/files.rb +18 -13
  19. data/lib/llm/providers/gemini/images.rb +4 -3
  20. data/lib/llm/providers/gemini/models.rb +4 -3
  21. data/lib/llm/providers/gemini.rb +9 -7
  22. data/lib/llm/providers/llamacpp.rb +3 -3
  23. data/lib/llm/providers/ollama/error_handler.rb +28 -6
  24. data/lib/llm/providers/ollama/models.rb +4 -3
  25. data/lib/llm/providers/ollama.rb +9 -7
  26. data/lib/llm/providers/openai/audio.rb +10 -7
  27. data/lib/llm/providers/openai/error_handler.rb +41 -14
  28. data/lib/llm/providers/openai/files.rb +19 -14
  29. data/lib/llm/providers/openai/images.rb +10 -7
  30. data/lib/llm/providers/openai/models.rb +4 -3
  31. data/lib/llm/providers/openai/moderations.rb +4 -3
  32. data/lib/llm/providers/openai/responses.rb +10 -7
  33. data/lib/llm/providers/openai/vector_stores.rb +34 -23
  34. data/lib/llm/providers/openai.rb +9 -7
  35. data/lib/llm/providers/xai.rb +3 -3
  36. data/lib/llm/providers/zai.rb +2 -2
  37. data/lib/llm/schema/object.rb +2 -2
  38. data/lib/llm/schema.rb +16 -2
  39. data/lib/llm/server_tool.rb +3 -3
  40. data/lib/llm/session.rb +3 -0
  41. data/lib/llm/tracer/logger.rb +192 -0
  42. data/lib/llm/tracer/null.rb +49 -0
  43. data/lib/llm/tracer/telemetry.rb +255 -0
  44. data/lib/llm/tracer.rb +134 -0
  45. data/lib/llm/version.rb +1 -1
  46. data/lib/llm.rb +4 -3
  47. data/llm.gemspec +4 -1
  48. metadata +38 -3
  49. data/lib/llm/builder.rb +0 -79
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LLM
4
+ ##
5
+ # A no-op tracer that ignores all tracing callbacks.
6
+ class Tracer::Null < Tracer
7
+ ##
8
+ # @param (see LLM::Tracer#on_request_start)
9
+ # @return [nil]
10
+ def on_request_start(**)
11
+ nil
12
+ end
13
+
14
+ ##
15
+ # @param (see LLM::Tracer#on_request_finish)
16
+ # @return [nil]
17
+ def on_request_finish(**)
18
+ nil
19
+ end
20
+
21
+ ##
22
+ # @param (see LLM::Tracer#on_request_error)
23
+ # @return [nil]
24
+ def on_request_error(**)
25
+ nil
26
+ end
27
+
28
+ ##
29
+ # @param (see LLM::Tracer#on_tool_start)
30
+ # @return [nil]
31
+ def on_tool_start(**)
32
+ nil
33
+ end
34
+
35
+ ##
36
+ # @param (see LLM::Tracer#on_tool_finish)
37
+ # @return [nil]
38
+ def on_tool_finish(**)
39
+ nil
40
+ end
41
+
42
+ ##
43
+ # @param (see LLM::Tracer#on_tool_error)
44
+ # @return [nil]
45
+ def on_tool_error(**)
46
+ nil
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,255 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LLM
4
+ ##
5
+ # The {LLM::Tracer::Telemetry LLM::Tracer::Telemetry} tracer provides
6
+ # telemetry support through the [opentelemetry-ruby](https://github.com/open-telemetry/opentelemetry-ruby)
7
+ # RubyGem. The gem should be installed separately since this feature is opt-in
8
+ # and disabled by default. This feature exists to support integration with tools
9
+ # like [LangSmith](https://www.langsmith.com).
10
+ #
11
+ # @see https://github.com/open-telemetry/semantic-conventions/blob/main/docs/gen-ai Telemetry specs (index)
12
+ # @see https://github.com/open-telemetry/semantic-conventions/blob/main/docs/gen-ai/openai.md Telemetry specs (OpenAI)
13
+ #
14
+ # @example InMemory export
15
+ # #!/usr/bin/env ruby
16
+ # require "llm"
17
+ # require "pp"
18
+ #
19
+ # llm = LLM.openai(key: ENV["KEY"])
20
+ # llm.tracer = LLM::Tracer::Telemetry.new(llm)
21
+ #
22
+ # ses = LLM::Session.new(llm)
23
+ # ses.talk "hello"
24
+ # ses.talk "how are you?"
25
+ # ses.tracer.spans.each { |span| pp span }
26
+ #
27
+ # @example OTLP export
28
+ # #!/usr/bin/env ruby
29
+ # require "llm"
30
+ # require "opentelemetry-exporter-otlp"
31
+ #
32
+ # endpoint = "https://api.smith.langchain.com/otel/v1/traces"
33
+ # exporter = OpenTelemetry::Exporter::OTLP::Exporter.new(endpoint:)
34
+ #
35
+ # llm = LLM.openai(key: ENV["KEY"])
36
+ # llm.tracer = LLM::Tracer::Telemetry.new(llm, exporter:)
37
+ #
38
+ # ses = LLM::Session.new(llm)
39
+ # ses.talk "hello"
40
+ # ses.talk "how are you?"
41
+ class Tracer::Telemetry < Tracer
42
+ ##
43
+ # param [LLM::Provider] provider
44
+ # An LLM provider
45
+ # @return [LLM::Tracer::Telemetry]
46
+ def initialize(provider, options = {})
47
+ super
48
+ @exporter = options.delete(:exporter)
49
+ setup!
50
+ end
51
+
52
+ ##
53
+ # @param (see LLM::Tracer#on_request_start)
54
+ def on_request_start(operation:, model: nil)
55
+ case operation
56
+ when "chat" then start_chat(operation:, model:)
57
+ when "retrieval" then start_retrieval(operation:)
58
+ else nil
59
+ end
60
+ end
61
+
62
+ ##
63
+ # @param (see LLM::Tracer#on_request_finish)
64
+ def on_request_finish(operation:, res:, model: nil, span: nil)
65
+ return nil unless span
66
+ case operation
67
+ when "chat" then finish_chat(operation:, model:, res:, span:)
68
+ when "retrieval" then finish_retrieval(operation:, res:, span:)
69
+ else nil
70
+ end
71
+ end
72
+
73
+ ##
74
+ # @param (see LLM::Tracer#on_request_error)
75
+ def on_request_error(ex:, span:)
76
+ return nil unless span
77
+ attributes = {"error.type" => ex.class.to_s}.compact
78
+ attributes.each { span.set_attribute(_1, _2) }
79
+ span.add_event("gen_ai.request.finish")
80
+ span.status = ::OpenTelemetry::Trace::Status.error(ex.message)
81
+ span.tap(&:finish)
82
+ end
83
+
84
+ ##
85
+ # @param (see LLM::Tracer#on_tool_start)
86
+ # @return (see LLM::Tracer#on_tool_start)
87
+ def on_tool_start(id:, name:, arguments:, model:)
88
+ attributes = {
89
+ "gen_ai.operation.name" => "execute_tool",
90
+ "gen_ai.request.model" => model,
91
+ "gen_ai.tool.call.id" => id,
92
+ "gen_ai.tool.name" => name,
93
+ "gen_ai.tool.call.arguments" => LLM.json.dump(arguments),
94
+ "gen_ai.provider.name" => provider_name,
95
+ "server.address" => provider_host,
96
+ "server.port" => provider_port
97
+ }.compact
98
+ span_name = ["execute_tool", name].compact.join(" ")
99
+ span = @tracer.start_span(span_name.empty? ? "gen_ai.tool" : span_name, kind: :client, attributes:)
100
+ span.add_event("gen_ai.tool.start")
101
+ span
102
+ end
103
+
104
+ ##
105
+ # @param (see LLM::Tracer#on_tool_finish)
106
+ # @return (see LLM::Tracer#on_tool_finish)
107
+ def on_tool_finish(result:, span:)
108
+ return nil unless span
109
+ attributes = {
110
+ "gen_ai.tool.call.id" => result.id,
111
+ "gen_ai.tool.name" => result.name,
112
+ "gen_ai.tool.call.result" => LLM.json.dump(result.value)
113
+ }.compact
114
+ attributes.each { span.set_attribute(_1, _2) }
115
+ span.add_event("gen_ai.tool.finish")
116
+ span.tap(&:finish)
117
+ end
118
+
119
+ ##
120
+ # @param (see LLM::Tracer#on_tool_error)
121
+ # @return (see LLM::Tracer#on_tool_error)
122
+ def on_tool_error(ex:, span:)
123
+ return nil unless span
124
+ attributes = {"error.type" => ex.class.to_s}.compact
125
+ attributes.each { span.set_attribute(_1, _2) }
126
+ span.add_event("gen_ai.tool.finish")
127
+ span.status = ::OpenTelemetry::Trace::Status.error(ex.message)
128
+ span.tap(&:finish)
129
+ end
130
+
131
+ ##
132
+ # @note
133
+ # This method returns an empty array for exporters that
134
+ # do not implement 'finished_spans' such as the OTLP
135
+ # exporter
136
+ # @return [Array<OpenTelemetry::SDK::Trace::SpanData>]
137
+ def spans
138
+ return [] unless @exporter.respond_to?(:finished_spans)
139
+ flush!
140
+ @exporter.finished_spans
141
+ end
142
+
143
+ ##
144
+ # Flushes queued telemetry to the configured exporter.
145
+ # @note
146
+ # Exports are batched in the background by default.
147
+ # Long-lived processes usually do not need to call this method.
148
+ # Short-lived scripts should call {#flush!} before exit to reduce
149
+ # the risk of losing spans that are still buffered.
150
+ # @return (see LLM::Tracer#flush!)
151
+ def flush!
152
+ @tracer_provider.force_flush
153
+ nil
154
+ end
155
+
156
+ private
157
+
158
+ ##
159
+ # @api private
160
+ def setup!
161
+ require "opentelemetry/sdk" unless defined?(OpenTelemetry)
162
+ @exporter ||= OpenTelemetry::SDK::Trace::Export::InMemorySpanExporter.new
163
+ processor = OpenTelemetry::SDK::Trace::Export::BatchSpanProcessor.new(@exporter)
164
+ @tracer_provider = OpenTelemetry::SDK::Trace::TracerProvider.new
165
+ @tracer_provider.add_span_processor(processor)
166
+ @tracer = @tracer_provider.tracer("llm.rb", LLM::VERSION)
167
+ end
168
+
169
+ ##
170
+ # @param [String] operation
171
+ # @param [LLM::Response] res
172
+ # @api private
173
+ def finish_attributes(operation, res)
174
+ case @provider.class.to_s
175
+ when "LLM::OpenAI" then openai_attributes(operation, res)
176
+ else {}
177
+ end
178
+ end
179
+
180
+ ##
181
+ # @param [String] operation
182
+ # @param [LLM::Response] res
183
+ # @api private
184
+ def openai_attributes(operation, res)
185
+ case operation
186
+ when "chat"
187
+ {
188
+ "openai.response.service_tier" => res.service_tier,
189
+ "openai.response.system_fingerprint" => res.system_fingerprint
190
+ }
191
+ when "retrieval"
192
+ {
193
+ "openai.vector_store.search.result_count" => res.size,
194
+ "openai.vector_store.search.has_more" => res.has_more
195
+ }
196
+ else {}
197
+ end
198
+ end
199
+
200
+ ##
201
+ # start_*
202
+
203
+ def start_chat(operation:, model:)
204
+ attributes = {
205
+ "gen_ai.operation.name" => operation,
206
+ "gen_ai.request.model" => model,
207
+ "gen_ai.provider.name" => provider_name,
208
+ "server.address" => provider_host,
209
+ "server.port" => provider_port
210
+ }.compact
211
+ span_name = [operation, model].compact.join(" ")
212
+ span = @tracer.start_span(span_name.empty? ? "gen_ai.request" : span_name, kind: :client, attributes:)
213
+ span.add_event("gen_ai.request.start")
214
+ span
215
+ end
216
+
217
+ def start_retrieval(operation:)
218
+ attributes = {
219
+ "gen_ai.operation.name" => operation,
220
+ "gen_ai.provider.name" => provider_name,
221
+ "server.address" => provider_host,
222
+ "server.port" => provider_port
223
+ }.compact
224
+ span = @tracer.start_span(operation, kind: :client, attributes:)
225
+ span.add_event("gen_ai.request.start")
226
+ span
227
+ end
228
+
229
+ ##
230
+ # finish_*
231
+
232
+ def finish_chat(operation:, model:, res:, span:)
233
+ attributes = {
234
+ "gen_ai.operation.name" => operation,
235
+ "gen_ai.request.model" => model,
236
+ "gen_ai.response.id" => res.id,
237
+ "gen_ai.response.model" => model,
238
+ "gen_ai.usage.input_tokens" => res.usage.input_tokens,
239
+ "gen_ai.usage.output_tokens" => res.usage.output_tokens
240
+ }.merge!(finish_attributes(operation, res)).compact
241
+ attributes.each { span.set_attribute(_1, _2) }
242
+ span.add_event("gen_ai.request.finish")
243
+ span.tap(&:finish)
244
+ end
245
+
246
+ def finish_retrieval(operation:, res:, span:)
247
+ attributes = {
248
+ "gen_ai.operation.name" => operation
249
+ }.merge!(finish_attributes(operation, res)).compact
250
+ attributes.each { span.set_attribute(_1, _2) }
251
+ span.add_event("gen_ai.request.finish")
252
+ span.tap(&:finish)
253
+ end
254
+ end
255
+ end
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module LLM
4
- VERSION = "4.1.0"
4
+ VERSION = "4.2.0"
5
5
  end
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/builder"
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/bot"
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 +dump+ and +load+
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
@@ -21,7 +21,8 @@ Gem::Specification.new do |spec|
21
21
  spec.required_ruby_version = ">= 3.2.0"
22
22
 
23
23
  spec.metadata["homepage_uri"] = spec.homepage
24
- spec.metadata["source_code_uri"] = "https://github.com/llmrb/llm"
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.1.0
4
+ version: 4.2.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,8 +312,13 @@ 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
286
316
  - lib/llm/tool.rb
287
317
  - lib/llm/tool/param.rb
318
+ - lib/llm/tracer.rb
319
+ - lib/llm/tracer/logger.rb
320
+ - lib/llm/tracer/null.rb
321
+ - lib/llm/tracer/telemetry.rb
288
322
  - lib/llm/usage.rb
289
323
  - lib/llm/utils.rb
290
324
  - lib/llm/version.rb
@@ -294,7 +328,8 @@ licenses:
294
328
  - 0BSD
295
329
  metadata:
296
330
  homepage_uri: https://github.com/llmrb/llm
297
- source_code_uri: https://github.com/llmrb/llm
331
+ source_code_uri: https://github.com/llmrb/llm.rb
332
+ documentation_uri: https://0x1eef.github.io/x/llm.rb
298
333
  rdoc_options: []
299
334
  require_paths:
300
335
  - 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