Class: Kernai::Media

Inherits:
Object
  • Object
show all
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

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(kind:, mime_type:, source:, data:, metadata: {}) ⇒ Media

Returns a new instance of Media.

Raises:

  • (ArgumentError)


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

#dataObject (readonly)

Returns the value of attribute data.



21
22
23
# File 'lib/kernai/media.rb', line 21

def data
  @data
end

#idObject (readonly)

Returns the value of attribute id.



21
22
23
# File 'lib/kernai/media.rb', line 21

def id
  @id
end

#kindObject (readonly)

Returns the value of attribute kind.



21
22
23
# File 'lib/kernai/media.rb', line 21

def kind
  @kind
end

#metadataObject (readonly)

Returns the value of attribute metadata.



21
22
23
# File 'lib/kernai/media.rb', line 21

def 
  @metadata
end

#mime_typeObject (readonly)

Returns the value of attribute mime_type.



21
22
23
# File 'lib/kernai/media.rb', line 21

def mime_type
  @mime_type
end

#sourceObject (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

Returns:

  • (Boolean)


44
45
46
# File 'lib/kernai/media.rb', line 44

def bytes?
  @source == :bytes
end

#path?Boolean

Returns:

  • (Boolean)


40
41
42
# File 'lib/kernai/media.rb', line 40

def path?
  @source == :path
end

#read_bytesObject

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_base64Object



60
61
62
# File 'lib/kernai/media.rb', line 60

def to_base64
  Base64.strict_encode64(read_bytes)
end

#to_hObject



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

Returns:

  • (Boolean)


36
37
38
# File 'lib/kernai/media.rb', line 36

def url?
  @source == :url
end