Class: Kernai::SkillResult
- Inherits:
-
Object
- Object
- Kernai::SkillResult
- Defined in:
- lib/kernai/skill_result.rb
Overview
Rich return shape for a skill’s ‘execute` block. Lets the skill carry three distinct pieces of information back to the kernel:
- `text` → the message the LLM will see (injected in a
<block type="result" name="..."> wrapper)
- `media` → one or more Kernai::Media parts (spliced in as
<block type="media"/> references after the text)
- `metadata` → free-form hash attached to the :skill_result recorder
entry. Never shown to the LLM; useful for scoring,
timings, structured status codes, etc.
Skills are NOT required to return a SkillResult — the legacy return shapes (String, Media, Array<String|Media>, nil, other) remain fully supported. Use SkillResult only when you need the metadata side-channel or when it reads more clearly than a raw string.
Normalisation utilities for ANY return shape live as class methods on this class (‘.wrap`, `.metadata_of`) so callers only have to know about one name.
Instance Attribute Summary collapse
-
#media ⇒ Object
readonly
Returns the value of attribute media.
-
#metadata ⇒ Object
readonly
Returns the value of attribute metadata.
-
#text ⇒ Object
readonly
Returns the value of attribute text.
Class Method Summary collapse
- .coerce(part) ⇒ Object
-
.metadata_of(value) ⇒ Object
Extract observability metadata from a skill return value.
- .normalise(value) ⇒ Object
-
.text_of(value) ⇒ Object
Extract the text payload from a skill return value — what ends up in the LLM-facing <block type=“result”> wrapper.
-
.wrap(value, store) ⇒ Object
Turn whatever a Skill’s execute block returned into a canonical list of parts the kernel can splice back into the conversation.
Instance Method Summary collapse
-
#initialize(text: '', media: nil, metadata: nil) ⇒ SkillResult
constructor
A new instance of SkillResult.
- #to_h ⇒ Object
Constructor Details
#initialize(text: '', media: nil, metadata: nil) ⇒ SkillResult
Returns a new instance of SkillResult.
26 27 28 29 30 |
# File 'lib/kernai/skill_result.rb', line 26 def initialize(text: '', media: nil, metadata: nil) @text = text.to_s @media = Array(media).compact @metadata = || {} end |
Instance Attribute Details
#media ⇒ Object (readonly)
Returns the value of attribute media.
24 25 26 |
# File 'lib/kernai/skill_result.rb', line 24 def media @media end |
#metadata ⇒ Object (readonly)
Returns the value of attribute metadata.
24 25 26 |
# File 'lib/kernai/skill_result.rb', line 24 def @metadata end |
#text ⇒ Object (readonly)
Returns the value of attribute text.
24 25 26 |
# File 'lib/kernai/skill_result.rb', line 24 def text @text end |
Class Method Details
.coerce(part) ⇒ Object
83 84 85 86 87 88 |
# File 'lib/kernai/skill_result.rb', line 83 def self.coerce(part) case part when String, Media then part else part.to_s end end |
.metadata_of(value) ⇒ Object
Extract observability metadata from a skill return value. Only explicit SkillResult instances carry metadata; every other return shape yields an empty hash. Providers / the kernel call this without having to introspect the return type themselves.
53 54 55 |
# File 'lib/kernai/skill_result.rb', line 53 def self.(value) value.is_a?(SkillResult) ? value. : {} end |
.normalise(value) ⇒ Object
72 73 74 75 76 77 78 79 80 81 |
# File 'lib/kernai/skill_result.rb', line 72 def self.normalise(value) case value when nil then [''] when String then [value] when Media then [value] when Array then value.map { |p| coerce(p) } when SkillResult then [value.text, *value.media] else [value.to_s] end end |
.text_of(value) ⇒ Object
Extract the text payload from a skill return value — what ends up in the LLM-facing <block type=“result”> wrapper. Defined as the counterpart to ‘metadata_of` so the kernel can log “what the LLM saw” cleanly.
61 62 63 64 65 66 67 68 69 70 |
# File 'lib/kernai/skill_result.rb', line 61 def self.text_of(value) case value when nil then '' when SkillResult then value.text when String then value when Media then '' when Array then value.grep(String).join else value.to_s end end |
.wrap(value, store) ⇒ Object
Turn whatever a Skill’s execute block returned into a canonical list of parts the kernel can splice back into the conversation. Media parts are side-registered in the context’s MediaStore so other components (skills, workflow consumers, recorders) can look them up by id without having to pass the object around.
43 44 45 46 47 |
# File 'lib/kernai/skill_result.rb', line 43 def self.wrap(value, store) parts = normalise(value) parts.each { |p| store.put(p) if p.is_a?(Media) } parts end |
Instance Method Details
#to_h ⇒ Object
32 33 34 |
# File 'lib/kernai/skill_result.rb', line 32 def to_h { text: @text, media: @media.map(&:to_h), metadata: @metadata } end |