The issue is that stream_usage=True sends usage metadata in a separate chunk that doesn’t have a content attribute, so your hasattr(chunk, "content") filter is skipping it. Usage data appears in chunks with usage_metadata instead.
Modify your code to capture usage:
for chunk in response_stream:
if hasattr(chunk, "content"):
yield chunk.content
elif hasattr(chunk, "usage_metadata"):
print(f"Usage: {chunk.usage_metadata}")
# Store usage data as needed
The UsageMetadataCallbackHandler should also capture this data, so check callback.total_tokens after streaming completes. The usage chunk typically comes at the end of the stream.