Class: Kernai::Media
- Inherits:
-
Object
- Object
- Kernai::Media
- Defined in:
- lib/kernai/media.rb
Overview
Immutable value object representing a piece of media (image, audio, video, document) flowing through the agent loop. A Media can reach the conversation in three shapes:
- :url → `data` is a remote URL the provider may reference directly
- :path → `data` is a filesystem path; the provider reads it lazily
- :bytes → `data` is the raw binary payload already in memory
The ‘id` is derived deterministically from the payload so identical media deduplicate across messages and can be referenced by stable id.
Constant Summary collapse
- KINDS =
%i[image audio video document].freeze
- SOURCES =
%i[url path bytes].freeze
Instance Attribute Summary collapse
-
#data ⇒ Object
readonly
Returns the value of attribute data.
-
#id ⇒ Object
readonly
Returns the value of attribute id.
-
#kind ⇒ Object
readonly
Returns the value of attribute kind.
-
#metadata ⇒ Object
readonly
Returns the value of attribute metadata.
-
#mime_type ⇒ Object
readonly
Returns the value of attribute mime_type.
-
#source ⇒ Object
readonly
Returns the value of attribute source.
Class Method Summary collapse
- .from_bytes(bytes, mime_type:, kind: nil) ⇒ Object
- .from_file(path, kind: nil, mime_type: nil) ⇒ Object
- .from_url(url, kind: nil, mime_type: nil) ⇒ Object
Instance Method Summary collapse
- #bytes? ⇒ Boolean
-
#initialize(kind:, mime_type:, source:, data:, metadata: {}) ⇒ Media
constructor
A new instance of Media.
- #path? ⇒ Boolean
-
#read_bytes ⇒ Object
Materialise the payload as raw bytes, regardless of how the media was originally constructed.
- #to_base64 ⇒ Object
- #to_h ⇒ Object
- #url? ⇒ Boolean
Constructor Details
#initialize(kind:, mime_type:, source:, data:, metadata: {}) ⇒ Media
Returns a new instance of Media.
23 24 25 26 27 28 29 30 31 32 33 34 |
# File 'lib/kernai/media.rb', line 23 def initialize(kind:, mime_type:, source:, data:, metadata: {}) raise ArgumentError, "invalid kind: #{kind}" unless KINDS.include?(kind.to_sym) raise ArgumentError, "invalid source: #{source}" unless SOURCES.include?(source.to_sym) @kind = kind.to_sym @mime_type = mime_type.to_s @source = source.to_sym @data = data @metadata = .dup.freeze @id = "media_#{Digest::SHA1.hexdigest(@data.to_s)[0, 12]}" freeze end |
Instance Attribute Details
#data ⇒ Object (readonly)
Returns the value of attribute data.
21 22 23 |
# File 'lib/kernai/media.rb', line 21 def data @data end |
#id ⇒ Object (readonly)
Returns the value of attribute id.
21 22 23 |
# File 'lib/kernai/media.rb', line 21 def id @id end |
#kind ⇒ Object (readonly)
Returns the value of attribute kind.
21 22 23 |
# File 'lib/kernai/media.rb', line 21 def kind @kind end |
#metadata ⇒ Object (readonly)
Returns the value of attribute metadata.
21 22 23 |
# File 'lib/kernai/media.rb', line 21 def @metadata end |
#mime_type ⇒ Object (readonly)
Returns the value of attribute mime_type.
21 22 23 |
# File 'lib/kernai/media.rb', line 21 def mime_type @mime_type end |
#source ⇒ Object (readonly)
Returns the value of attribute source.
21 22 23 |
# File 'lib/kernai/media.rb', line 21 def source @source end |
Class Method Details
.from_bytes(bytes, mime_type:, kind: nil) ⇒ Object
89 90 91 92 93 94 95 96 |
# File 'lib/kernai/media.rb', line 89 def from_bytes(bytes, mime_type:, kind: nil) new( kind: kind || kind_for(mime_type), mime_type: mime_type, source: :bytes, data: bytes ) end |
.from_file(path, kind: nil, mime_type: nil) ⇒ Object
69 70 71 72 73 74 75 76 77 |
# File 'lib/kernai/media.rb', line 69 def from_file(path, kind: nil, mime_type: nil) mime = mime_type || guess_mime(path) new( kind: kind || kind_for(mime), mime_type: mime, source: :path, data: path ) end |
.from_url(url, kind: nil, mime_type: nil) ⇒ Object
79 80 81 82 83 84 85 86 87 |
# File 'lib/kernai/media.rb', line 79 def from_url(url, kind: nil, mime_type: nil) mime = mime_type || guess_mime(url) new( kind: kind || kind_for(mime), mime_type: mime, source: :url, data: url ) end |
Instance Method Details
#bytes? ⇒ Boolean
44 45 46 |
# File 'lib/kernai/media.rb', line 44 def bytes? @source == :bytes end |
#path? ⇒ Boolean
40 41 42 |
# File 'lib/kernai/media.rb', line 40 def path? @source == :path end |
#read_bytes ⇒ Object
Materialise the payload as raw bytes, regardless of how the media was originally constructed. Providers that must upload binary content to their vendor endpoint call this once they know they can actually use the payload — we never load a file we won’t send.
52 53 54 55 56 57 58 |
# File 'lib/kernai/media.rb', line 52 def read_bytes case @source when :bytes then @data when :path then File.binread(@data) when :url then raise Error, "cannot read bytes of a URL-backed media (#{@data})" end end |
#to_base64 ⇒ Object
60 61 62 |
# File 'lib/kernai/media.rb', line 60 def to_base64 Base64.strict_encode64(read_bytes) end |
#to_h ⇒ Object
64 65 66 |
# File 'lib/kernai/media.rb', line 64 def to_h { id: id, kind: @kind, mime_type: @mime_type, source: @source, metadata: @metadata } end |
#url? ⇒ Boolean
36 37 38 |
# File 'lib/kernai/media.rb', line 36 def url? @source == :url end |