Extensions
Provider extensions. Importing an extension module auto-registers its input adapter with the adapter registry. See the providers guide and the AG-UI guide for usage.
Gemini
hother.streamblocks.extensions.gemini
Gemini extension for StreamBlocks.
This extension provides input adapters for Google GenAI streams.
Importing this module registers the GeminiInputAdapter for auto-detection.
Example
Import to enable auto-detection
import hother.streamblocks.extensions.gemini
Auto-detect from Gemini stream
processor = ProtocolStreamProcessor(registry) async for event in processor.process_stream(gemini_stream): ... print(event)
Or use convenience factory
from hother.streamblocks.extensions.gemini import create_gemini_processor processor = create_gemini_processor(registry)
GeminiInputAdapter
Input adapter for Google GenAI streams.
Handles chunks from google.genai.models.generate_content_stream() and google.ai.generativelanguage clients.
Extracts: - Text from chunk.text attribute - Usage metadata (token counts) - Model version information
Example
from google import genai adapter = GeminiInputAdapter()
async for chunk in client.aio.models.generate_content_stream(...): ... text = adapter.extract_text(chunk) ... metadata = adapter.get_metadata(chunk) ... if metadata: ... print(f"Tokens: {metadata['usage']}")
Source code in src/hother/streamblocks/extensions/gemini/__init__.py
categorize
categorize(event: GenerateContentResponse) -> EventCategory
Categorize event - all Gemini chunks are text content.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
GenerateContentResponse
|
Gemini GenerateContentResponse chunk |
required |
Returns:
| Type | Description |
|---|---|
EventCategory
|
TEXT_CONTENT for all chunks |
Source code in src/hother/streamblocks/extensions/gemini/__init__.py
extract_text
extract_text(event: GenerateContentResponse) -> str | None
Extract text from chunk.text attribute.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
GenerateContentResponse
|
Gemini GenerateContentResponse chunk |
required |
Returns:
| Type | Description |
|---|---|
str | None
|
Text content, or None if not present |
Source code in src/hother/streamblocks/extensions/gemini/__init__.py
get_metadata
Extract usage metadata and model information.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
GenerateContentResponse
|
Gemini GenerateContentResponse chunk |
required |
Returns:
| Type | Description |
|---|---|
dict[str, Any] | None
|
Dictionary with usage and/or model if present |
Source code in src/hother/streamblocks/extensions/gemini/__init__.py
is_complete
is_complete(event: GenerateContentResponse) -> bool
Gemini doesn't have explicit finish markers in each chunk.
Completion is typically detected by the stream ending.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
GenerateContentResponse
|
Gemini GenerateContentResponse chunk |
required |
Returns:
| Type | Description |
|---|---|
bool
|
Always False - Gemini streams end naturally |
Source code in src/hother/streamblocks/extensions/gemini/__init__.py
create_gemini_processor
create_gemini_processor(
registry: Registry,
) -> ProtocolStreamProcessor[Any, BaseEvent]
Create processor pre-configured for Gemini streams.
This is a convenience factory that creates a ProtocolStreamProcessor with GeminiInputAdapter and StreamBlocksOutputAdapter.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
registry
|
Registry
|
Registry with syntax and block definitions |
required |
Returns:
| Type | Description |
|---|---|
ProtocolStreamProcessor[Any, BaseEvent]
|
Pre-configured processor for Gemini streams |
Example
from hother.streamblocks.extensions.gemini import create_gemini_processor processor = create_gemini_processor(registry) async for event in processor.process_stream(gemini_stream): ... if isinstance(event, BlockExtractedEvent): ... print(f"Block: {event.block.metadata.id}")
Source code in src/hother/streamblocks/extensions/gemini/__init__.py
OpenAI
hother.streamblocks.extensions.openai
OpenAI extension for StreamBlocks.
This extension provides input adapters for OpenAI ChatCompletionChunk streams.
Importing this module registers the OpenAIInputAdapter for auto-detection.
Example
Import to enable auto-detection
import hother.streamblocks.extensions.openai
Auto-detect from OpenAI stream
processor = ProtocolStreamProcessor(registry) async for event in processor.process_stream(openai_stream): ... print(event)
Or use convenience factory
from hother.streamblocks.extensions.openai import create_openai_processor processor = create_openai_processor(registry)
OpenAIInputAdapter
Input adapter for OpenAI ChatCompletionChunk streams.
Handles streams from openai.AsyncStream[ChatCompletionChunk].
Extracts: - Delta content from choices[0].delta.content - Finish reasons - Model information
Example
from openai import AsyncOpenAI adapter = OpenAIInputAdapter()
client = AsyncOpenAI() stream = await client.chat.completions.create( ... model="gpt-4", ... messages=[...], ... stream=True ... )
async for chunk in stream: ... text = adapter.extract_text(chunk) ... if adapter.is_complete(chunk): ... print("Stream complete!")
Source code in src/hother/streamblocks/extensions/openai/__init__.py
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | |
categorize
categorize(event: ChatCompletionChunk) -> EventCategory
Categorize event - all OpenAI chunks are text content.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
ChatCompletionChunk
|
OpenAI ChatCompletionChunk |
required |
Returns:
| Type | Description |
|---|---|
EventCategory
|
TEXT_CONTENT for all chunks |
Source code in src/hother/streamblocks/extensions/openai/__init__.py
extract_text
extract_text(event: ChatCompletionChunk) -> str | None
Extract text from choices[0].delta.content.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
ChatCompletionChunk
|
OpenAI ChatCompletionChunk |
required |
Returns:
| Type | Description |
|---|---|
str | None
|
Delta content text, or None if not present |
Source code in src/hother/streamblocks/extensions/openai/__init__.py
get_metadata
Extract model and finish reason.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
ChatCompletionChunk
|
OpenAI ChatCompletionChunk |
required |
Returns:
| Type | Description |
|---|---|
dict[str, Any] | None
|
Dictionary with model and/or finish_reason if present |
Source code in src/hother/streamblocks/extensions/openai/__init__.py
is_complete
is_complete(event: ChatCompletionChunk) -> bool
Check if finish_reason is set.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
ChatCompletionChunk
|
OpenAI ChatCompletionChunk |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if this is the final chunk |
Source code in src/hother/streamblocks/extensions/openai/__init__.py
create_openai_processor
create_openai_processor(
registry: Registry,
) -> ProtocolStreamProcessor[Any, BaseEvent]
Create processor pre-configured for OpenAI streams.
This is a convenience factory that creates a ProtocolStreamProcessor with OpenAIInputAdapter and StreamBlocksOutputAdapter.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
registry
|
Registry
|
Registry with syntax and block definitions |
required |
Returns:
| Type | Description |
|---|---|
ProtocolStreamProcessor[Any, BaseEvent]
|
Pre-configured processor for OpenAI streams |
Example
from hother.streamblocks.extensions.openai import create_openai_processor processor = create_openai_processor(registry) async for event in processor.process_stream(openai_stream): ... if isinstance(event, BlockExtractedEvent): ... print(f"Block: {event.block.metadata.id}")
Source code in src/hother/streamblocks/extensions/openai/__init__.py
Anthropic
hother.streamblocks.extensions.anthropic
Anthropic extension for StreamBlocks.
This extension provides input adapters for Anthropic message streams.
Importing this module registers the AnthropicInputAdapter for auto-detection.
Example
Import to enable auto-detection
import hother.streamblocks.extensions.anthropic
Auto-detect from Anthropic stream
processor = ProtocolStreamProcessor(registry) async for event in processor.process_stream(anthropic_stream): ... print(event)
Or use convenience factory
from hother.streamblocks.extensions.anthropic import create_anthropic_processor processor = create_anthropic_processor(registry)
AnthropicEvent
module-attribute
AnthropicInputAdapter
Input adapter for Anthropic message streams.
Handles event-based streaming from anthropic.MessageStream.
Anthropic uses different event types: - content_block_delta: Contains text deltas (TEXT_CONTENT) - message_delta: Contains usage information (PASSTHROUGH) - message_stop: Signals stream completion (PASSTHROUGH) - Other events: PASSTHROUGH
Example
from anthropic import AsyncAnthropic adapter = AnthropicInputAdapter()
client = AsyncAnthropic() async with client.messages.stream(...) as stream: ... async for event in stream: ... text = adapter.extract_text(event) ... if text: ... print(text, end='', flush=True) ... if adapter.is_complete(event): ... print("\nDone!")
Source code in src/hother/streamblocks/extensions/anthropic/__init__.py
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | |
categorize
categorize(event: AnthropicEvent) -> EventCategory
Categorize event based on type.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
AnthropicEvent
|
Anthropic event |
required |
Returns:
| Type | Description |
|---|---|
EventCategory
|
TEXT_CONTENT for content_block_delta events, PASSTHROUGH for others |
Source code in src/hother/streamblocks/extensions/anthropic/__init__.py
extract_text
extract_text(event: AnthropicEvent) -> str | None
Extract text from content_block_delta events.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
AnthropicEvent
|
Anthropic event |
required |
Returns:
| Type | Description |
|---|---|
str | None
|
Delta text if present, None otherwise |
Source code in src/hother/streamblocks/extensions/anthropic/__init__.py
get_metadata
get_metadata(
event: AnthropicEvent,
) -> dict[str, Any] | None
Extract stop reason and usage information.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
AnthropicEvent
|
Anthropic event |
required |
Returns:
| Type | Description |
|---|---|
dict[str, Any] | None
|
Dictionary with stop_reason or usage if present |
Source code in src/hother/streamblocks/extensions/anthropic/__init__.py
is_complete
is_complete(event: AnthropicEvent) -> bool
Check for message_stop event.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
AnthropicEvent
|
Anthropic event |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if this is the message_stop event |
Source code in src/hother/streamblocks/extensions/anthropic/__init__.py
create_anthropic_processor
create_anthropic_processor(
registry: Registry,
) -> ProtocolStreamProcessor[Any, BaseEvent]
Create processor pre-configured for Anthropic streams.
This is a convenience factory that creates a ProtocolStreamProcessor with AnthropicInputAdapter and StreamBlocksOutputAdapter.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
registry
|
Registry
|
Registry with syntax and block definitions |
required |
Returns:
| Type | Description |
|---|---|
ProtocolStreamProcessor[Any, BaseEvent]
|
Pre-configured processor for Anthropic streams |
Example
from hother.streamblocks.extensions.anthropic import create_anthropic_processor processor = create_anthropic_processor(registry) async for event in processor.process_stream(anthropic_stream): ... if isinstance(event, BlockExtractedEvent): ... print(f"Block: {event.block.metadata.id}")
Source code in src/hother/streamblocks/extensions/anthropic/__init__.py
AG-UI
hother.streamblocks.extensions.agui
AG-UI extension for StreamBlocks.
This extension provides bidirectional adapters for the AG-UI protocol.
AG-UI is an event-based protocol for agent-to-frontend communication with event types for lifecycle, text messages, tool calls, and state management.
Importing this module registers the AGUIInputAdapter for auto-detection.
Example
Import to enable auto-detection
import hother.streamblocks.extensions.agui
Auto-detect from AG-UI stream
processor = ProtocolStreamProcessor(registry) async for event in processor.process_stream(agui_stream): ... print(event)
Bidirectional: AG-UI in, AG-UI out
from hother.streamblocks.extensions.agui import ( ... create_agui_bidirectional_processor, ... AGUIEventFilter, ... ) processor = create_agui_bidirectional_processor( ... registry, ... event_filter=AGUIEventFilter.BLOCKS_WITH_PROGRESS, ... ) async for event in processor.process_stream(agui_stream): ... # event is an AG-UI event (dict format) ... if event["type"] == "CUSTOM": ... handle_streamblocks_event(event) ... else: ... forward_to_frontend(event)
AGUIEventFilter
Bases: Flag
Configurable event filtering for AG-UI output adapter.
Use these flags to control which StreamBlocks events are emitted when using AGUIOutputAdapter.
Example
Only emit block-related events
filter = AGUIEventFilter.BLOCKS_ONLY
Emit blocks with progress updates
filter = AGUIEventFilter.BLOCKS_WITH_PROGRESS
Custom combination
filter = AGUIEventFilter.TEXT_DELTA | AGUIEventFilter.BLOCK_EXTRACTED
Source code in src/hother/streamblocks/extensions/agui/filters.py
ALL
class-attribute
instance-attribute
ALL = (
RAW_TEXT
| TEXT_DELTA
| BLOCK_OPENED
| BLOCK_DELTA
| BLOCK_EXTRACTED
| BLOCK_REJECTED
)
Emit all StreamBlocks events.
BLOCKS_ONLY
class-attribute
instance-attribute
BLOCKS_ONLY = (
BLOCK_OPENED | BLOCK_EXTRACTED | BLOCK_REJECTED
)
Emit only block lifecycle events (opened, extracted, rejected).
BLOCKS_WITH_PROGRESS
class-attribute
instance-attribute
BLOCKS_WITH_PROGRESS = (
BLOCK_OPENED
| BLOCK_DELTA
| BLOCK_EXTRACTED
| BLOCK_REJECTED
)
Emit block lifecycle events plus progress updates.
BLOCK_DELTA
class-attribute
instance-attribute
BLOCK_DELTA = auto()
Emit section delta events (BlockHeaderDeltaEvent, BlockMetadataDeltaEvent, BlockContentDeltaEvent) as CustomEvent.
BLOCK_EXTRACTED
class-attribute
instance-attribute
BLOCK_EXTRACTED = auto()
Emit BlockExtractedEvent as CustomEvent.
BLOCK_OPENED
class-attribute
instance-attribute
BLOCK_OPENED = auto()
Emit BlockOpenedEvent as CustomEvent.
BLOCK_REJECTED
class-attribute
instance-attribute
BLOCK_REJECTED = auto()
Emit BlockRejectedEvent as CustomEvent.
RAW_TEXT
class-attribute
instance-attribute
RAW_TEXT = auto()
Emit RawTextEvent as TextMessageContentEvent.
TEXT_AND_FINAL
class-attribute
instance-attribute
TEXT_AND_FINAL = (
TEXT_DELTA | BLOCK_EXTRACTED | BLOCK_REJECTED
)
Emit text streaming plus final block results.
TEXT_DELTA
class-attribute
instance-attribute
TEXT_DELTA = auto()
Emit TextDeltaEvent as TextMessageContentEvent.
AGUIInputAdapter
Input adapter for AG-UI protocol events.
Handles event-based streaming from AG-UI protocol.
AG-UI Event Categories: - TEXT_MESSAGE_CONTENT, TEXT_MESSAGE_CHUNK: TEXT_CONTENT (has text) - All other events: PASSTHROUGH (lifecycle, tool calls, state)
Example
adapter = AGUIInputAdapter()
async for event in agui_stream: ... category = adapter.categorize(event) ... if category == EventCategory.TEXT_CONTENT: ... text = adapter.extract_text(event) ... print(text, end='', flush=True)
Source code in src/hother/streamblocks/extensions/agui/input_adapter.py
categorize
categorize(event: BaseEvent) -> EventCategory
Categorize event based on type.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
BaseEvent
|
AG-UI BaseEvent |
required |
Returns:
| Type | Description |
|---|---|
EventCategory
|
TEXT_CONTENT for text message events, PASSTHROUGH for others |
Source code in src/hother/streamblocks/extensions/agui/input_adapter.py
extract_text
extract_text(event: BaseEvent) -> str | None
Extract text from TEXT_CONTENT events.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
BaseEvent
|
AG-UI BaseEvent |
required |
Returns:
| Type | Description |
|---|---|
str | None
|
Delta text if TEXT_MESSAGE_CONTENT or TEXT_MESSAGE_CHUNK |
Source code in src/hother/streamblocks/extensions/agui/input_adapter.py
get_metadata
Extract protocol metadata.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
BaseEvent
|
AG-UI BaseEvent |
required |
Returns:
| Type | Description |
|---|---|
dict[str, Any] | None
|
Dictionary with event_type and timestamp if available |
Source code in src/hother/streamblocks/extensions/agui/input_adapter.py
is_complete
is_complete(event: BaseEvent) -> bool
Check for RUN_FINISHED event.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
BaseEvent
|
AG-UI BaseEvent |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if this is the RUN_FINISHED event |
Source code in src/hother/streamblocks/extensions/agui/input_adapter.py
AGUIOutputAdapter
Output adapter for AG-UI protocol events.
Transforms StreamBlocks events into AG-UI CustomEvent format.
StreamBlocks events are mapped to AG-UI as follows: - TextDeltaEvent, TextContentEvent → TextMessageContentEvent - BlockStartEvent → CustomEvent(name="streamblocks.block_start") - BlockHeaderDeltaEvent → CustomEvent(name="streamblocks.block_delta") - BlockMetadataDeltaEvent → CustomEvent(name="streamblocks.block_delta") - BlockContentDeltaEvent → CustomEvent(name="streamblocks.block_delta") - BlockEndEvent → CustomEvent(name="streamblocks.block_end") - BlockErrorEvent → CustomEvent(name="streamblocks.block_error")
Passthrough events (AG-UI events from input) are passed through unchanged.
Example
adapter = AGUIOutputAdapter(event_filter=AGUIEventFilter.BLOCKS_WITH_PROGRESS)
Convert StreamBlocks event to AG-UI event
agui_event = adapter.to_protocol_event(block_extracted_event)
Pass through AG-UI events
original = adapter.passthrough(run_started_event)
Source code in src/hother/streamblocks/extensions/agui/output_adapter.py
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 | |
passthrough
Handle passthrough events.
For AG-UI events, passes them through unchanged.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
original_event
|
Any
|
Original input event |
required |
Returns:
| Type | Description |
|---|---|
Any
|
The original event unchanged |
Source code in src/hother/streamblocks/extensions/agui/output_adapter.py
reset_message_id
to_protocol_event
Convert StreamBlocks event to AG-UI event format.
Returns a dictionary representation of the AG-UI event that can be serialized or converted to the actual AG-UI event type.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
BaseEvent
|
StreamBlocks event |
required |
Returns:
| Type | Description |
|---|---|
dict[str, Any] | None
|
Dictionary representing AG-UI event, or None if filtered out |
Note
Returns dict rather than actual AG-UI types to avoid requiring ag-ui-protocol as a runtime dependency.
Source code in src/hother/streamblocks/extensions/agui/output_adapter.py
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | |
create_agui_bidirectional_processor
create_agui_bidirectional_processor(
registry: Registry, event_filter: AGUIEventFilter = ALL
) -> ProtocolStreamProcessor[Any, dict[str, Any]]
Create processor for AG-UI → AG-UI (bidirectional).
This processor takes AG-UI events as input and emits AG-UI events as output. StreamBlocks events are converted to AG-UI CustomEvent format.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
registry
|
Registry
|
Registry with syntax and block definitions |
required |
event_filter
|
AGUIEventFilter
|
Filter to control which StreamBlocks events are emitted |
ALL
|
Returns:
| Type | Description |
|---|---|
ProtocolStreamProcessor[Any, dict[str, Any]]
|
Pre-configured processor for AG-UI input and output |
Example
from hother.streamblocks.extensions.agui import ( ... create_agui_bidirectional_processor, ... AGUIEventFilter, ... ) processor = create_agui_bidirectional_processor( ... registry, ... event_filter=AGUIEventFilter.BLOCKS_WITH_PROGRESS, ... ) async for event in processor.process_stream(agui_stream): ... if event["type"] == "CUSTOM": ... if event["name"] == "streamblocks.block_extracted": ... handle_block(event["value"]) ... else: ... # Passthrough: lifecycle, tool calls, state ... forward_to_frontend(event)
Source code in src/hother/streamblocks/extensions/agui/__init__.py
create_agui_processor
create_agui_processor(
registry: Registry,
) -> ProtocolStreamProcessor[Any, BaseEvent]
Create processor for AG-UI → StreamBlocks (unidirectional).
This processor takes AG-UI events as input and emits native StreamBlocks events.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
registry
|
Registry
|
Registry with syntax and block definitions |
required |
Returns:
| Type | Description |
|---|---|
ProtocolStreamProcessor[Any, BaseEvent]
|
Pre-configured processor for AG-UI input, StreamBlocks output |
Example
from hother.streamblocks.extensions.agui import create_agui_processor processor = create_agui_processor(registry) async for event in processor.process_stream(agui_stream): ... if isinstance(event, BlockExtractedEvent): ... print(f"Block: {event.block.metadata.id}")
Source code in src/hother/streamblocks/extensions/agui/__init__.py
hother.streamblocks.extensions.agui.filters
Event filter for AG-UI output adapter.
AGUIEventFilter
Bases: Flag
Configurable event filtering for AG-UI output adapter.
Use these flags to control which StreamBlocks events are emitted when using AGUIOutputAdapter.
Example
Only emit block-related events
filter = AGUIEventFilter.BLOCKS_ONLY
Emit blocks with progress updates
filter = AGUIEventFilter.BLOCKS_WITH_PROGRESS
Custom combination
filter = AGUIEventFilter.TEXT_DELTA | AGUIEventFilter.BLOCK_EXTRACTED
Source code in src/hother/streamblocks/extensions/agui/filters.py
ALL
class-attribute
instance-attribute
ALL = (
RAW_TEXT
| TEXT_DELTA
| BLOCK_OPENED
| BLOCK_DELTA
| BLOCK_EXTRACTED
| BLOCK_REJECTED
)
Emit all StreamBlocks events.
BLOCKS_ONLY
class-attribute
instance-attribute
BLOCKS_ONLY = (
BLOCK_OPENED | BLOCK_EXTRACTED | BLOCK_REJECTED
)
Emit only block lifecycle events (opened, extracted, rejected).
BLOCKS_WITH_PROGRESS
class-attribute
instance-attribute
BLOCKS_WITH_PROGRESS = (
BLOCK_OPENED
| BLOCK_DELTA
| BLOCK_EXTRACTED
| BLOCK_REJECTED
)
Emit block lifecycle events plus progress updates.
BLOCK_DELTA
class-attribute
instance-attribute
BLOCK_DELTA = auto()
Emit section delta events (BlockHeaderDeltaEvent, BlockMetadataDeltaEvent, BlockContentDeltaEvent) as CustomEvent.
BLOCK_EXTRACTED
class-attribute
instance-attribute
BLOCK_EXTRACTED = auto()
Emit BlockExtractedEvent as CustomEvent.
BLOCK_OPENED
class-attribute
instance-attribute
BLOCK_OPENED = auto()
Emit BlockOpenedEvent as CustomEvent.
BLOCK_REJECTED
class-attribute
instance-attribute
BLOCK_REJECTED = auto()
Emit BlockRejectedEvent as CustomEvent.
RAW_TEXT
class-attribute
instance-attribute
RAW_TEXT = auto()
Emit RawTextEvent as TextMessageContentEvent.
TEXT_AND_FINAL
class-attribute
instance-attribute
TEXT_AND_FINAL = (
TEXT_DELTA | BLOCK_EXTRACTED | BLOCK_REJECTED
)
Emit text streaming plus final block results.
TEXT_DELTA
class-attribute
instance-attribute
TEXT_DELTA = auto()
Emit TextDeltaEvent as TextMessageContentEvent.
hother.streamblocks.extensions.agui.input_adapter
AG-UI input adapter for StreamBlocks.
AGUIInputAdapter
Input adapter for AG-UI protocol events.
Handles event-based streaming from AG-UI protocol.
AG-UI Event Categories: - TEXT_MESSAGE_CONTENT, TEXT_MESSAGE_CHUNK: TEXT_CONTENT (has text) - All other events: PASSTHROUGH (lifecycle, tool calls, state)
Example
adapter = AGUIInputAdapter()
async for event in agui_stream: ... category = adapter.categorize(event) ... if category == EventCategory.TEXT_CONTENT: ... text = adapter.extract_text(event) ... print(text, end='', flush=True)
Source code in src/hother/streamblocks/extensions/agui/input_adapter.py
categorize
categorize(event: BaseEvent) -> EventCategory
Categorize event based on type.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
BaseEvent
|
AG-UI BaseEvent |
required |
Returns:
| Type | Description |
|---|---|
EventCategory
|
TEXT_CONTENT for text message events, PASSTHROUGH for others |
Source code in src/hother/streamblocks/extensions/agui/input_adapter.py
extract_text
extract_text(event: BaseEvent) -> str | None
Extract text from TEXT_CONTENT events.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
BaseEvent
|
AG-UI BaseEvent |
required |
Returns:
| Type | Description |
|---|---|
str | None
|
Delta text if TEXT_MESSAGE_CONTENT or TEXT_MESSAGE_CHUNK |
Source code in src/hother/streamblocks/extensions/agui/input_adapter.py
get_metadata
Extract protocol metadata.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
BaseEvent
|
AG-UI BaseEvent |
required |
Returns:
| Type | Description |
|---|---|
dict[str, Any] | None
|
Dictionary with event_type and timestamp if available |
Source code in src/hother/streamblocks/extensions/agui/input_adapter.py
is_complete
is_complete(event: BaseEvent) -> bool
Check for RUN_FINISHED event.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
BaseEvent
|
AG-UI BaseEvent |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if this is the RUN_FINISHED event |
Source code in src/hother/streamblocks/extensions/agui/input_adapter.py
hother.streamblocks.extensions.agui.output_adapter
AG-UI output adapter for StreamBlocks.
AGUIOutputAdapter
Output adapter for AG-UI protocol events.
Transforms StreamBlocks events into AG-UI CustomEvent format.
StreamBlocks events are mapped to AG-UI as follows: - TextDeltaEvent, TextContentEvent → TextMessageContentEvent - BlockStartEvent → CustomEvent(name="streamblocks.block_start") - BlockHeaderDeltaEvent → CustomEvent(name="streamblocks.block_delta") - BlockMetadataDeltaEvent → CustomEvent(name="streamblocks.block_delta") - BlockContentDeltaEvent → CustomEvent(name="streamblocks.block_delta") - BlockEndEvent → CustomEvent(name="streamblocks.block_end") - BlockErrorEvent → CustomEvent(name="streamblocks.block_error")
Passthrough events (AG-UI events from input) are passed through unchanged.
Example
adapter = AGUIOutputAdapter(event_filter=AGUIEventFilter.BLOCKS_WITH_PROGRESS)
Convert StreamBlocks event to AG-UI event
agui_event = adapter.to_protocol_event(block_extracted_event)
Pass through AG-UI events
original = adapter.passthrough(run_started_event)
Source code in src/hother/streamblocks/extensions/agui/output_adapter.py
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 | |
passthrough
Handle passthrough events.
For AG-UI events, passes them through unchanged.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
original_event
|
Any
|
Original input event |
required |
Returns:
| Type | Description |
|---|---|
Any
|
The original event unchanged |
Source code in src/hother/streamblocks/extensions/agui/output_adapter.py
reset_message_id
to_protocol_event
Convert StreamBlocks event to AG-UI event format.
Returns a dictionary representation of the AG-UI event that can be serialized or converted to the actual AG-UI event type.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
BaseEvent
|
StreamBlocks event |
required |
Returns:
| Type | Description |
|---|---|
dict[str, Any] | None
|
Dictionary representing AG-UI event, or None if filtered out |
Note
Returns dict rather than actual AG-UI types to avoid requiring ag-ui-protocol as a runtime dependency.
Source code in src/hother/streamblocks/extensions/agui/output_adapter.py
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | |