ai-agents 0.9.0 → 0.9.1
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/CHANGELOG.md +9 -0
- data/lib/agents/instrumentation/tracing_callbacks.rb +23 -2
- data/lib/agents/runner.rb +19 -1
- data/lib/agents/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1e4285e8a584df94b230a5e9e65e4d7991bab421c48b02726e7a69882068ca9d
|
|
4
|
+
data.tar.gz: 5ebaacb25ed21e880c6393b70ff1a661216b2f7f4f2e946db8d298bb1fe8acc2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0c96c699fa544c44ca8200d70d8663adc2f82a39b9f58001d87b0a79f0c64ace068bbb5622d9708aaec7f5e48be0128c9e04dcbe918c899cc03c00ffaa710bd9
|
|
7
|
+
data.tar.gz: b103cd93cda31c7adfa874405587a6fdd5fc2c54049179e55651dd21585b4ea047d856596eceaf4108a631e30fc787f943d43247d3765c51950130f6e5126176
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.9.1] - 2026-02-24
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
- **Multimodal Conversation History**: Restored multimodal image content from conversation history, ensuring image URLs and base64 data are preserved across agent turns (#46)
|
|
14
|
+
- **Tracing Instrumentation**: Improved serialization of multimodal content in tracing callbacks, returning JSON for non-text content types
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
- **Test Infrastructure**: OpenTelemetry stubs in tests are now conditionally applied only when the `opentelemetry-api` gem is not installed (#45)
|
|
18
|
+
|
|
10
19
|
## [0.9.0] - 2026-02-09
|
|
11
20
|
|
|
12
21
|
### Added
|
|
@@ -48,7 +48,7 @@ module Agents
|
|
|
48
48
|
tracing = tracing_state(context_wrapper)
|
|
49
49
|
return unless tracing
|
|
50
50
|
|
|
51
|
-
tracing[:pending_llm_input] = input
|
|
51
|
+
tracing[:pending_llm_input] = serialize_output(input)
|
|
52
52
|
|
|
53
53
|
return if tracing[:current_agent_name] == agent_name
|
|
54
54
|
|
|
@@ -206,7 +206,7 @@ module Agents
|
|
|
206
206
|
content = response.content
|
|
207
207
|
return format_tool_calls(response) if content.nil?
|
|
208
208
|
|
|
209
|
-
text =
|
|
209
|
+
text = serialize_content(content)
|
|
210
210
|
return format_tool_calls(response) if text.empty?
|
|
211
211
|
|
|
212
212
|
text
|
|
@@ -229,6 +229,8 @@ module Agents
|
|
|
229
229
|
end
|
|
230
230
|
|
|
231
231
|
def serialize_content(content)
|
|
232
|
+
return serialize_multimodal_content(content) if multimodal_content?(content)
|
|
233
|
+
|
|
232
234
|
content.is_a?(Hash) || content.is_a?(Array) ? content.to_json : content.to_s
|
|
233
235
|
end
|
|
234
236
|
|
|
@@ -240,6 +242,8 @@ module Agents
|
|
|
240
242
|
end
|
|
241
243
|
|
|
242
244
|
def serialize_output(value)
|
|
245
|
+
return serialize_multimodal_content(value) if multimodal_content?(value)
|
|
246
|
+
|
|
243
247
|
value.is_a?(Hash) || value.is_a?(Array) ? value.to_json : value.to_s
|
|
244
248
|
end
|
|
245
249
|
|
|
@@ -334,6 +338,23 @@ module Agents
|
|
|
334
338
|
def cleanup_tracing_state(context_wrapper)
|
|
335
339
|
context_wrapper.context.delete(:__otel_tracing)
|
|
336
340
|
end
|
|
341
|
+
|
|
342
|
+
def multimodal_content?(value)
|
|
343
|
+
value.respond_to?(:text) && value.respond_to?(:attachments)
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
def serialize_multimodal_content(content)
|
|
347
|
+
parts = []
|
|
348
|
+
text = content.text
|
|
349
|
+
parts << text if text && !text.empty?
|
|
350
|
+
|
|
351
|
+
if content.attachments&.any?
|
|
352
|
+
urls = content.attachments.map { |a| a.respond_to?(:source) ? a.source.to_s : a.to_s }
|
|
353
|
+
parts << "Attachments: #{urls.join(", ")}"
|
|
354
|
+
end
|
|
355
|
+
|
|
356
|
+
parts.join("\n")
|
|
357
|
+
end
|
|
337
358
|
end
|
|
338
359
|
end
|
|
339
360
|
end
|
data/lib/agents/runner.rb
CHANGED
|
@@ -334,7 +334,7 @@ module Agents
|
|
|
334
334
|
|
|
335
335
|
params = {
|
|
336
336
|
role: role,
|
|
337
|
-
content:
|
|
337
|
+
content: build_content(content_value)
|
|
338
338
|
}
|
|
339
339
|
|
|
340
340
|
# Handle tool-specific parameters (Tool Results)
|
|
@@ -366,6 +366,24 @@ module Agents
|
|
|
366
366
|
params
|
|
367
367
|
end
|
|
368
368
|
|
|
369
|
+
# Build RubyLLM::Content from stored content, handling multimodal arrays with image attachments.
|
|
370
|
+
# Multimodal arrays follow the OpenAI content format: [{type: 'text', text: '...'}, {type: 'image_url', ...}]
|
|
371
|
+
def build_content(content_value)
|
|
372
|
+
return RubyLLM::Content.new(content_value) unless content_value.is_a?(Array)
|
|
373
|
+
|
|
374
|
+
text_parts = content_value.filter_map { |p| p[:text] || p["text"] if (p[:type] || p["type"]) == "text" }
|
|
375
|
+
image_urls = content_value.filter_map do |p|
|
|
376
|
+
next unless (p[:type] || p["type"]) == "image_url"
|
|
377
|
+
|
|
378
|
+
p.dig(:image_url, :url) || p.dig("image_url", "url")
|
|
379
|
+
end
|
|
380
|
+
|
|
381
|
+
return RubyLLM::Content.new(content_value.to_json) if text_parts.empty? && image_urls.empty?
|
|
382
|
+
|
|
383
|
+
text = text_parts.join(" ")
|
|
384
|
+
image_urls.any? ? RubyLLM::Content.new(text, image_urls) : RubyLLM::Content.new(text)
|
|
385
|
+
end
|
|
386
|
+
|
|
369
387
|
# Validate tool message has required tool_call_id
|
|
370
388
|
def valid_tool_message?(msg)
|
|
371
389
|
if msg[:tool_call_id]
|
data/lib/agents/version.rb
CHANGED