Summary
chunk.message in streaming callbacks returns a raw Hash, while response.message after generation returns a typed Common::Messages::* object. This inconsistency means .content works on one but not the other.
Example
class MyAgent < ActiveAgent::Base
on_stream :handle_chunk
def handle_chunk(chunk)
chunk.message[:content] # ✅ Works — message is a Hash
chunk.message.content # ❌ NoMethodError — Hash doesn't have .content
end
end
# But after generation:
response = MyAgent.ask(message: "Hi").generate_now
response.message.content # ✅ Works — message is a Common::Messages::Assistant
response.message[:content] # ❌ Doesn't work
Root Cause
PromptResponse#messages are cast through Types::MessagesType, which converts them into Common::Messages::* objects with method accessors (.content, .role).
StreamChunk#message wraps the raw Hash from the provider's message_stack, which is built by merging deltas during streaming in ChatProvider#process_stream_chunk. No type casting is applied.
Suggestion
Consider casting StreamChunk#message through the same type system so the API is consistent, or document the difference clearly. A uniform interface where both chunk.message.content and response.message.content work would be less surprising.
Summary
chunk.messagein streaming callbacks returns a raw Hash, whileresponse.messageafter generation returns a typedCommon::Messages::*object. This inconsistency means.contentworks on one but not the other.Example
Root Cause
PromptResponse#messagesare cast throughTypes::MessagesType, which converts them intoCommon::Messages::*objects with method accessors (.content,.role).StreamChunk#messagewraps the raw Hash from the provider'smessage_stack, which is built by merging deltas during streaming inChatProvider#process_stream_chunk. No type casting is applied.Suggestion
Consider casting
StreamChunk#messagethrough the same type system so the API is consistent, or document the difference clearly. A uniform interface where bothchunk.message.contentandresponse.message.contentwork would be less surprising.