opentelemetry-instrumentation-ruby_llm 0.6.0 → 0.7.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.
@@ -1,11 +1,14 @@
1
1
  require "test_helper"
2
2
 
3
3
  class InstrumentationTest < Minitest::Test
4
+ include ChatCompletionStubs
5
+
4
6
  def setup
5
7
  EXPORTER.reset
6
8
 
7
9
  RubyLLM.configure do |c|
8
10
  c.openai_api_key = "fake-key-for-testing"
11
+ c.anthropic_api_key = "fake-key-for-testing"
9
12
  end
10
13
  end
11
14
 
@@ -30,29 +33,12 @@ class InstrumentationTest < Minitest::Test
30
33
  assert_equal "1.8.0", OpenTelemetry::Instrumentation::RubyLLM::Instrumentation::MINIMUM_RUBY_LLM_VERSION
31
34
  end
32
35
 
36
+ def test_agent_minimum_ruby_llm_version_is_pinned_at_1_12_1
37
+ assert_equal "1.12.1", OpenTelemetry::Instrumentation::RubyLLM::Instrumentation::AGENT_MINIMUM_RUBY_LLM_VERSION
38
+ end
39
+
33
40
  def test_creates_span_with_attributes
34
- stub_request(:post, "https://api.openai.com/v1/chat/completions")
35
- .to_return(
36
- status: 200,
37
- headers: { "Content-Type" => "application/json" },
38
- body: {
39
- id: "chatcmpl-123",
40
- object: "chat.completion",
41
- model: "gpt-4o-mini",
42
- choices: [
43
- {
44
- index: 0,
45
- message: { role: "assistant", content: "Hello, world!" },
46
- finish_reason: "stop"
47
- }
48
- ],
49
- usage: {
50
- prompt_tokens: 10,
51
- completion_tokens: 5,
52
- total_tokens: 15
53
- }
54
- }.to_json
55
- )
41
+ stub_chat_completion
56
42
 
57
43
  chat = RubyLLM.chat(model: "gpt-4o-mini")
58
44
  chat.ask("Hi")
@@ -73,17 +59,9 @@ class InstrumentationTest < Minitest::Test
73
59
  end
74
60
 
75
61
  def test_marks_streaming_chat_requests
76
- stub_request(:post, "https://api.openai.com/v1/chat/completions")
77
- .to_return(
78
- status: 200,
79
- headers: { "Content-Type" => "application/json" },
80
- body: {
81
- id: "chatcmpl-123",
82
- model: "gpt-4o-mini",
83
- choices: [{ index: 0, message: { role: "assistant", content: "Hi" }, finish_reason: "stop" }],
84
- usage: { prompt_tokens: 1, completion_tokens: 1, total_tokens: 2 }
85
- }.to_json
86
- )
62
+ stub_chat_completion(
63
+ chat_completion_body(content: "Hi", usage: { prompt_tokens: 1, completion_tokens: 1, total_tokens: 2 })
64
+ )
87
65
 
88
66
  chat = RubyLLM.chat(model: "gpt-4o-mini")
89
67
  chat.ask("Hi") { |_chunk| }
@@ -92,28 +70,58 @@ class InstrumentationTest < Minitest::Test
92
70
  assert_equal true, span.attributes["gen_ai.request.stream"]
93
71
  end
94
72
 
95
- def test_records_prompt_cache_tokens
96
- # RubyLLM's OpenAI provider maps `cached_tokens` `cache_read_tokens(usage)`
97
- # and `cache_creation_tokens` ← `cache_write_tokens(usage)`, both surfaced
98
- # on `Message#cached_tokens` / `Message#cache_creation_tokens`.
99
- stub_request(:post, "https://api.openai.com/v1/chat/completions")
73
+ def test_records_openai_prompt_cache_read_tokens
74
+ # OpenAI exposes only `cached_tokens` via `prompt_tokens_details.cached_tokens`.
75
+ # Its provider in ruby_llm does not surface a `cache_creation_tokens` value
76
+ # until 1.15.0 (we only assert the cache-read attribute here).
77
+ # The accessor itself was added in ruby_llm 1.9.0.
78
+ skip "cached_tokens accessor not available before ruby_llm 1.9.0" unless RubyLLM::Message.instance_methods.include?(:cached_tokens)
79
+ stub_chat_completion(
80
+ chat_completion_body(
81
+ content: "Hello!",
82
+ usage: {
83
+ prompt_tokens: 100,
84
+ completion_tokens: 5,
85
+ total_tokens: 105,
86
+ prompt_tokens_details: { cached_tokens: 75 }
87
+ }
88
+ )
89
+ )
90
+
91
+ chat = RubyLLM.chat(model: "gpt-4o-mini")
92
+ chat.ask("Hi")
93
+
94
+ span = EXPORTER.finished_spans.first
95
+ assert_equal 75, span.attributes["gen_ai.usage.cache_read.input_tokens"]
96
+ assert_equal 0, span.attributes["gen_ai.usage.cache_creation.input_tokens"]
97
+ end
98
+
99
+ def test_records_anthropic_prompt_cache_tokens
100
+ # Anthropic's provider surfaces both `cached_tokens` (via
101
+ # `cache_read_input_tokens`) and `cache_creation_tokens` (via
102
+ # `cache_creation_input_tokens`). Accessors were added in ruby_llm 1.9.0.
103
+ skip "cache token accessors not available before ruby_llm 1.9.0" unless RubyLLM::Message.instance_methods.include?(:cache_creation_tokens)
104
+ stub_request(:post, "https://api.anthropic.com/v1/messages")
100
105
  .to_return(
101
106
  status: 200,
102
107
  headers: { "Content-Type" => "application/json" },
103
108
  body: {
104
- id: "chatcmpl-cache",
105
- model: "gpt-4o-mini",
106
- choices: [{ index: 0, message: { role: "assistant", content: "Hello!" }, finish_reason: "stop" }],
109
+ id: "msg_cache",
110
+ type: "message",
111
+ role: "assistant",
112
+ model: "claude-3-5-sonnet-20241022",
113
+ content: [{ type: "text", text: "Hello!" }],
114
+ stop_reason: "end_turn",
107
115
  usage: {
108
- prompt_tokens: 100,
109
- completion_tokens: 5,
110
- total_tokens: 105,
111
- prompt_tokens_details: { cached_tokens: 75, cache_write_tokens: 20 }
116
+ input_tokens: 100,
117
+ output_tokens: 5,
118
+ cache_read_input_tokens: 75,
119
+ cache_creation_input_tokens: 20
112
120
  }
113
121
  }.to_json
114
122
  )
115
123
 
116
- chat = RubyLLM.chat(model: "gpt-4o-mini")
124
+ chat = RubyLLM.chat(model: "claude-3-5-sonnet-20241022")
117
125
  chat.ask("Hi")
118
126
 
119
127
  span = EXPORTER.finished_spans.first
@@ -140,22 +148,7 @@ class InstrumentationTest < Minitest::Test
140
148
  end
141
149
 
142
150
  def test_instruments_complete_called_directly
143
- stub_request(:post, "https://api.openai.com/v1/chat/completions")
144
- .to_return(
145
- status: 200,
146
- headers: { "Content-Type" => "application/json" },
147
- body: {
148
- id: "chatcmpl-123",
149
- object: "chat.completion",
150
- model: "gpt-4o-mini",
151
- choices: [{
152
- index: 0,
153
- message: { role: "assistant", content: "Hello, world!" },
154
- finish_reason: "stop"
155
- }],
156
- usage: { prompt_tokens: 10, completion_tokens: 5, total_tokens: 15 }
157
- }.to_json
158
- )
151
+ stub_chat_completion
159
152
 
160
153
  chat = RubyLLM.chat(model: "gpt-4o-mini")
161
154
  chat.add_message(role: :user, content: "Hi")
@@ -183,47 +176,20 @@ class InstrumentationTest < Minitest::Test
183
176
  end
184
177
  end
185
178
 
186
- stub_request(:post, "https://api.openai.com/v1/chat/completions")
187
- .to_return(
188
- {
189
- status: 200,
190
- headers: { "Content-Type" => "application/json" },
191
- body: {
192
- id: "chatcmpl-123",
193
- object: "chat.completion",
194
- model: "gpt-4o-mini",
195
- choices: [{
196
- index: 0,
197
- message: {
198
- role: "assistant",
199
- content: nil,
200
- tool_calls: [{
201
- id: "call_abc123",
202
- type: "function",
203
- function: { name: "calculator", arguments: '{"expression":"2+2"}' }
204
- }]
205
- },
206
- finish_reason: "tool_calls"
207
- }],
208
- usage: { prompt_tokens: 10, completion_tokens: 5, total_tokens: 15 }
209
- }.to_json
210
- },
211
- {
212
- status: 200,
213
- headers: { "Content-Type" => "application/json" },
214
- body: {
215
- id: "chatcmpl-456",
216
- object: "chat.completion",
217
- model: "gpt-4o-mini",
218
- choices: [{
219
- index: 0,
220
- message: { role: "assistant", content: "The answer is 4" },
221
- finish_reason: "stop"
222
- }],
223
- usage: { prompt_tokens: 20, completion_tokens: 5, total_tokens: 25 }
224
- }.to_json
225
- }
179
+ stub_chat_completion(
180
+ chat_completion_body(
181
+ content: nil,
182
+ tool_calls: [{
183
+ id: "call_abc123",
184
+ type: "function",
185
+ function: { name: "calculator", arguments: '{"expression":"2+2"}' }
186
+ }]
187
+ ),
188
+ chat_completion_body(
189
+ content: "The answer is 4",
190
+ usage: { prompt_tokens: 20, completion_tokens: 5, total_tokens: 25 }
226
191
  )
192
+ )
227
193
 
228
194
  chat = RubyLLM.chat(model: "gpt-4o-mini")
229
195
  chat.with_tool(calculator)
@@ -249,6 +215,41 @@ class InstrumentationTest < Minitest::Test
249
215
  assert_equal "function", tool_span.attributes["gen_ai.tool.type"]
250
216
  end
251
217
 
218
+ def test_truncates_tool_result_to_configured_max_length
219
+ long_value = "x" * 1000
220
+ echo = Class.new(RubyLLM::Tool) do
221
+ def self.name = "echo"
222
+ description "Echoes a long string"
223
+
224
+ define_method(:execute) { long_value }
225
+ end
226
+
227
+ stub_chat_completion(
228
+ chat_completion_body(
229
+ content: nil,
230
+ tool_calls: [{
231
+ id: "call_echo",
232
+ type: "function",
233
+ function: { name: "echo", arguments: "{}" }
234
+ }]
235
+ ),
236
+ chat_completion_body(
237
+ content: "done",
238
+ usage: { prompt_tokens: 20, completion_tokens: 5, total_tokens: 25 }
239
+ )
240
+ )
241
+
242
+ OpenTelemetry::Instrumentation::RubyLLM::Instrumentation.instance.config[:tool_result_max_length] = 700
243
+
244
+ chat = RubyLLM.chat(model: "gpt-4o-mini").with_tool(echo)
245
+ chat.ask("echo please")
246
+
247
+ tool_span = EXPORTER.finished_spans.find { |s| s.name.start_with?("execute_tool ") }
248
+ assert_equal "x" * 700, tool_span.attributes["gen_ai.tool.call.result"]
249
+ ensure
250
+ OpenTelemetry::Instrumentation::RubyLLM::Instrumentation.instance.config[:tool_result_max_length] = 500
251
+ end
252
+
252
253
  def test_records_error_when_tool_raises
253
254
  boom = Class.new(RubyLLM::Tool) do
254
255
  def self.name = "boom"
@@ -259,29 +260,17 @@ class InstrumentationTest < Minitest::Test
259
260
  end
260
261
  end
261
262
 
262
- stub_request(:post, "https://api.openai.com/v1/chat/completions")
263
- .to_return(
264
- status: 200,
265
- headers: { "Content-Type" => "application/json" },
266
- body: {
267
- id: "chatcmpl-boom",
268
- model: "gpt-4o-mini",
269
- choices: [{
270
- index: 0,
271
- message: {
272
- role: "assistant",
273
- content: nil,
274
- tool_calls: [{
275
- id: "call_x",
276
- type: "function",
277
- function: { name: "boom", arguments: "{}" }
278
- }]
279
- },
280
- finish_reason: "tool_calls"
281
- }],
282
- usage: { prompt_tokens: 1, completion_tokens: 1, total_tokens: 2 }
283
- }.to_json
263
+ stub_chat_completion(
264
+ chat_completion_body(
265
+ content: nil,
266
+ tool_calls: [{
267
+ id: "call_x",
268
+ type: "function",
269
+ function: { name: "boom", arguments: "{}" }
270
+ }],
271
+ usage: { prompt_tokens: 1, completion_tokens: 1, total_tokens: 2 }
284
272
  )
273
+ )
285
274
 
286
275
  chat = RubyLLM.chat(model: "gpt-4o-mini").with_tool(boom)
287
276
  assert_raises(ArgumentError) { chat.ask("trigger") }
@@ -292,22 +281,7 @@ class InstrumentationTest < Minitest::Test
292
281
  end
293
282
 
294
283
  def test_does_not_capture_content_by_default
295
- stub_request(:post, "https://api.openai.com/v1/chat/completions")
296
- .to_return(
297
- status: 200,
298
- headers: { "Content-Type" => "application/json" },
299
- body: {
300
- id: "chatcmpl-123",
301
- object: "chat.completion",
302
- model: "gpt-4o-mini",
303
- choices: [{
304
- index: 0,
305
- message: { role: "assistant", content: "Hello, world!" },
306
- finish_reason: "stop"
307
- }],
308
- usage: { prompt_tokens: 10, completion_tokens: 5, total_tokens: 15 }
309
- }.to_json
310
- )
284
+ stub_chat_completion
311
285
 
312
286
  chat = RubyLLM.chat(model: "gpt-4o-mini")
313
287
  chat.with_instructions("You are helpful")
@@ -322,22 +296,7 @@ class InstrumentationTest < Minitest::Test
322
296
  def test_captures_content_when_enabled
323
297
  OpenTelemetry::Instrumentation::RubyLLM::Instrumentation.instance.config[:capture_content] = true
324
298
 
325
- stub_request(:post, "https://api.openai.com/v1/chat/completions")
326
- .to_return(
327
- status: 200,
328
- headers: { "Content-Type" => "application/json" },
329
- body: {
330
- id: "chatcmpl-123",
331
- object: "chat.completion",
332
- model: "gpt-4o-mini",
333
- choices: [{
334
- index: 0,
335
- message: { role: "assistant", content: "Hello, world!" },
336
- finish_reason: "stop"
337
- }],
338
- usage: { prompt_tokens: 10, completion_tokens: 5, total_tokens: 15 }
339
- }.to_json
340
- )
299
+ stub_chat_completion
341
300
 
342
301
  chat = RubyLLM.chat(model: "gpt-4o-mini")
343
302
  chat.with_instructions("You are helpful")
@@ -409,22 +368,7 @@ class InstrumentationTest < Minitest::Test
409
368
  end
410
369
 
411
370
  def test_with_otel_attributes_sets_span_attributes
412
- stub_request(:post, "https://api.openai.com/v1/chat/completions")
413
- .to_return(
414
- status: 200,
415
- headers: { "Content-Type" => "application/json" },
416
- body: {
417
- id: "chatcmpl-123",
418
- object: "chat.completion",
419
- model: "gpt-4o-mini",
420
- choices: [{
421
- index: 0,
422
- message: { role: "assistant", content: "Hello!" },
423
- finish_reason: "stop"
424
- }],
425
- usage: { prompt_tokens: 10, completion_tokens: 5, total_tokens: 15 }
426
- }.to_json
427
- )
371
+ stub_chat_completion(chat_completion_body(content: "Hello!"))
428
372
 
429
373
  chat = RubyLLM.chat(model: "gpt-4o-mini")
430
374
  chat.with_otel_attributes(
@@ -439,22 +383,7 @@ class InstrumentationTest < Minitest::Test
439
383
  end
440
384
 
441
385
  def test_with_otel_attributes_returns_self_for_chaining
442
- stub_request(:post, "https://api.openai.com/v1/chat/completions")
443
- .to_return(
444
- status: 200,
445
- headers: { "Content-Type" => "application/json" },
446
- body: {
447
- id: "chatcmpl-123",
448
- object: "chat.completion",
449
- model: "gpt-4o-mini",
450
- choices: [{
451
- index: 0,
452
- message: { role: "assistant", content: "Hello!" },
453
- finish_reason: "stop"
454
- }],
455
- usage: { prompt_tokens: 10, completion_tokens: 5, total_tokens: 15 }
456
- }.to_json
457
- )
386
+ stub_chat_completion(chat_completion_body(content: "Hello!"))
458
387
 
459
388
  chat = RubyLLM.chat(model: "gpt-4o-mini")
460
389
  result = chat.with_otel_attributes("custom.category" => "test")
@@ -463,22 +392,7 @@ class InstrumentationTest < Minitest::Test
463
392
  end
464
393
 
465
394
  def test_with_otel_attributes_evaluates_callables
466
- stub_request(:post, "https://api.openai.com/v1/chat/completions")
467
- .to_return(
468
- status: 200,
469
- headers: { "Content-Type" => "application/json" },
470
- body: {
471
- id: "chatcmpl-123",
472
- object: "chat.completion",
473
- model: "gpt-4o-mini",
474
- choices: [{
475
- index: 0,
476
- message: { role: "assistant", content: "Hello!" },
477
- finish_reason: "stop"
478
- }],
479
- usage: { prompt_tokens: 10, completion_tokens: 5, total_tokens: 15 }
480
- }.to_json
481
- )
395
+ stub_chat_completion(chat_completion_body(content: "Hello!"))
482
396
 
483
397
  chat = RubyLLM.chat(model: "gpt-4o-mini")
484
398
  chat.with_otel_attributes(
@@ -493,22 +407,7 @@ class InstrumentationTest < Minitest::Test
493
407
  end
494
408
 
495
409
  def test_works_without_otel_attributes
496
- stub_request(:post, "https://api.openai.com/v1/chat/completions")
497
- .to_return(
498
- status: 200,
499
- headers: { "Content-Type" => "application/json" },
500
- body: {
501
- id: "chatcmpl-123",
502
- object: "chat.completion",
503
- model: "gpt-4o-mini",
504
- choices: [{
505
- index: 0,
506
- message: { role: "assistant", content: "Hello!" },
507
- finish_reason: "stop"
508
- }],
509
- usage: { prompt_tokens: 10, completion_tokens: 5, total_tokens: 15 }
510
- }.to_json
511
- )
410
+ stub_chat_completion(chat_completion_body(content: "Hello!"))
512
411
 
513
412
  chat = RubyLLM.chat(model: "gpt-4o-mini")
514
413
  response = chat.ask("Hi")
@@ -516,25 +415,84 @@ class InstrumentationTest < Minitest::Test
516
415
  assert_equal "Hello!", response.content
517
416
  end
518
417
 
418
+ def test_captures_ruby_llm_content_with_attachments
419
+ OpenTelemetry::Instrumentation::RubyLLM::Instrumentation.instance.config[:capture_content] = true
420
+
421
+ stub_chat_completion(chat_completion_body(content: "A cat."))
422
+
423
+ content = RubyLLM::Content.new("What is this?", "https://example.com/cat.png")
424
+
425
+ chat = RubyLLM.chat(model: "gpt-4o-mini")
426
+ chat.add_message(role: :user, content: content)
427
+ chat.complete
428
+
429
+ span = EXPORTER.finished_spans.first
430
+ input_messages = JSON.parse(span.attributes["gen_ai.input.messages"])
431
+ assert_equal(
432
+ [
433
+ { "type" => "text", "content" => "What is this?" },
434
+ {
435
+ "type" => "uri",
436
+ "modality" => "image",
437
+ "mime_type" => "image/png",
438
+ "uri" => "https://example.com/cat.png"
439
+ }
440
+ ],
441
+ input_messages[0]["parts"]
442
+ )
443
+ ensure
444
+ OpenTelemetry::Instrumentation::RubyLLM::Instrumentation.instance.config[:capture_content] = false
445
+ end
446
+
447
+ def test_captures_ruby_llm_content_raw
448
+ skip "RubyLLM::Content::Raw not available before ruby_llm 1.9.0" unless defined?(RubyLLM::Content::Raw)
449
+ OpenTelemetry::Instrumentation::RubyLLM::Instrumentation.instance.config[:capture_content] = true
450
+
451
+ stub_chat_completion(chat_completion_body(content: "Acknowledged."))
452
+
453
+ raw = RubyLLM::Content::Raw.new([{ type: "text", text: "raw payload" }])
454
+
455
+ chat = RubyLLM.chat(model: "gpt-4o-mini")
456
+ chat.add_message(role: :user, content: raw)
457
+ chat.complete
458
+
459
+ span = EXPORTER.finished_spans.first
460
+ input_messages = JSON.parse(span.attributes["gen_ai.input.messages"])
461
+ assert_equal(
462
+ [{ "type" => "raw", "content" => [{ "type" => "text", "text" => "raw payload" }].to_json }],
463
+ input_messages[0]["parts"]
464
+ )
465
+ ensure
466
+ OpenTelemetry::Instrumentation::RubyLLM::Instrumentation.instance.config[:capture_content] = false
467
+ end
468
+
469
+ def test_captures_ruby_llm_content_raw_system_instructions
470
+ skip "RubyLLM::Content::Raw not available before ruby_llm 1.9.0" unless defined?(RubyLLM::Content::Raw)
471
+ OpenTelemetry::Instrumentation::RubyLLM::Instrumentation.instance.config[:capture_content] = true
472
+
473
+ stub_chat_completion(chat_completion_body(content: "Acknowledged."))
474
+
475
+ raw_block = RubyLLM::Content::Raw.new([{ type: "text", text: "You are helpful" }])
476
+
477
+ chat = RubyLLM.chat(model: "gpt-4o-mini")
478
+ chat.add_message(role: :system, content: raw_block)
479
+ chat.add_message(role: :user, content: "Hi")
480
+ chat.complete
481
+
482
+ span = EXPORTER.finished_spans.first
483
+ system_instructions = JSON.parse(span.attributes["gen_ai.system_instructions"])
484
+ assert_equal(
485
+ [{ "type" => "raw", "content" => [{ "type" => "text", "text" => "You are helpful" }].to_json }],
486
+ system_instructions
487
+ )
488
+ ensure
489
+ OpenTelemetry::Instrumentation::RubyLLM::Instrumentation.instance.config[:capture_content] = false
490
+ end
491
+
519
492
  def test_captures_content_when_enabled_via_env_var
520
493
  ENV["OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT"] = "true"
521
494
 
522
- stub_request(:post, "https://api.openai.com/v1/chat/completions")
523
- .to_return(
524
- status: 200,
525
- headers: { "Content-Type" => "application/json" },
526
- body: {
527
- id: "chatcmpl-123",
528
- object: "chat.completion",
529
- model: "gpt-4o-mini",
530
- choices: [{
531
- index: 0,
532
- message: { role: "assistant", content: "Hello, world!" },
533
- finish_reason: "stop"
534
- }],
535
- usage: { prompt_tokens: 10, completion_tokens: 5, total_tokens: 15 }
536
- }.to_json
537
- )
495
+ stub_chat_completion
538
496
 
539
497
  chat = RubyLLM.chat(model: "gpt-4o-mini")
540
498
  chat.ask("Hi")
data/test/test_helper.rb CHANGED
@@ -6,6 +6,36 @@ require "ruby_llm"
6
6
  require "opentelemetry/sdk"
7
7
  require "opentelemetry-instrumentation-ruby_llm"
8
8
 
9
+ module ChatCompletionStubs
10
+ DEFAULT_USAGE = { prompt_tokens: 10, completion_tokens: 5, total_tokens: 15 }.freeze
11
+
12
+ def chat_completion_body(content: "Hello, world!", model: "gpt-4o-mini", tool_calls: nil, usage: DEFAULT_USAGE)
13
+ message = { role: "assistant", content: content }
14
+ message[:tool_calls] = tool_calls if tool_calls
15
+
16
+ {
17
+ id: "chatcmpl-123",
18
+ object: "chat.completion",
19
+ model: model,
20
+ choices: [{
21
+ index: 0,
22
+ message: message,
23
+ finish_reason: tool_calls ? "tool_calls" : "stop"
24
+ }],
25
+ usage: usage
26
+ }.to_json
27
+ end
28
+
29
+ def stub_chat_completion(*bodies)
30
+ bodies = [chat_completion_body] if bodies.empty?
31
+ responses = bodies.map do |body|
32
+ { status: 200, headers: { "Content-Type" => "application/json" }, body: body }
33
+ end
34
+
35
+ stub_request(:post, "https://api.openai.com/v1/chat/completions").to_return(*responses)
36
+ end
37
+ end
38
+
9
39
  EXPORTER = OpenTelemetry::SDK::Trace::Export::InMemorySpanExporter.new
10
40
  span_processor = OpenTelemetry::SDK::Trace::Export::SimpleSpanProcessor.new(EXPORTER)
11
41
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opentelemetry-instrumentation-ruby_llm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Clarissa Borges
@@ -61,14 +61,20 @@ files:
61
61
  - example/trace_demonstration_with_langfuse_and_tools.rb
62
62
  - example/trace_demonstration_with_langfuse_ingredient_search.rb
63
63
  - example/trace_demonstration_with_tools.rb
64
+ - gemfiles/ruby_llm_1.12.1.gemfile
64
65
  - gemfiles/ruby_llm_1.8.0.gemfile
65
66
  - gemfiles/ruby_llm_1_latest.gemfile
66
67
  - lib/opentelemetry-instrumentation-ruby_llm.rb
67
68
  - lib/opentelemetry/instrumentation/ruby_llm/instrumentation.rb
69
+ - lib/opentelemetry/instrumentation/ruby_llm/message_formatter.rb
70
+ - lib/opentelemetry/instrumentation/ruby_llm/patches/agent.rb
68
71
  - lib/opentelemetry/instrumentation/ruby_llm/patches/chat.rb
72
+ - lib/opentelemetry/instrumentation/ruby_llm/patches/chat_methods.rb
69
73
  - lib/opentelemetry/instrumentation/ruby_llm/patches/embedding.rb
70
74
  - lib/opentelemetry/instrumentation/ruby_llm/version.rb
71
75
  - opentelemetry-instrumentation-ruby_llm.gemspec
76
+ - test/active_record_chat_methods_test.rb
77
+ - test/agent_instrumentation_test.rb
72
78
  - test/instrumentation_test.rb
73
79
  - test/test_helper.rb
74
80
  homepage: https://github.com/thoughtbot/opentelemetry-instrumentation-ruby_llm