Module: Mistri::Content
- Defined in:
- lib/mistri/content.rb
Overview
Typed content blocks: what a message is made of. Text and thinking on assistant turns, text and images on user and tool-result turns, tool calls alongside them. Blocks are immutable values that compare by content, pattern-match, and round-trip through #to_h / Content.from_h, so sessions replay without the loop knowing block shapes.
Defined Under Namespace
Classes: Image, Text, Thinking
Class Method Summary collapse
-
.freeze_string(value) ⇒ Object
String#to_s returns self, so a caller's mutable buffer would alias into an immutable block; blocks own a frozen copy instead.
-
.from_h(hash) ⇒ Object
The inverse of #to_h, used when a session is read back.
-
.wrap(content) ⇒ Object
Coerce a value into a list of blocks: nil becomes none, a String becomes one Text block, blocks pass through, arrays may mix all of these.
Class Method Details
.freeze_string(value) ⇒ Object
String#to_s returns self, so a caller's mutable buffer would alias into an immutable block; blocks own a frozen copy instead.
12 13 14 15 |
# File 'lib/mistri/content.rb', line 12 def self.freeze_string(value) s = value.to_s s.frozen? ? s : s.dup.freeze end |
.from_h(hash) ⇒ Object
The inverse of #to_h, used when a session is read back. Keys may be symbols or, after a JSON round-trip, strings.
83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/mistri/content.rb', line 83 def self.from_h(hash) h = hash.transform_keys(&:to_s) case h["type"].to_s when "text" then Text.new(text: h["text"], signature: h["signature"]) when "thinking" Thinking.new(thinking: h["thinking"], signature: h["signature"], redacted: h.fetch("redacted", false)) when "image" then Image.new(data: h["data"], mime_type: h["mime_type"]) when "tool_call" ToolCall.new(id: h["id"], name: h["name"], arguments: h["arguments"] || {}, signature: h["signature"]) else raise ArgumentError, "unknown content block type #{h["type"].inspect}" end end |
.wrap(content) ⇒ Object
Coerce a value into a list of blocks: nil becomes none, a String becomes one Text block, blocks pass through, arrays may mix all of these.
75 76 77 78 79 |
# File 'lib/mistri/content.rb', line 75 def self.wrap(content) Array(content).map do |block| block.respond_to?(:type) ? block : Text.new(text: block.to_s) end end |