Python: Fixed middleware and multimodal input samples (#4022)

* Fix streaming branch in weather override middleware sample

The streaming branch of weather_override_middleware only prefixed the
original weather data via a transform hook instead of replacing the
content with the 'perfect weather' override like the non-streaming
branch does. Replace with a new ResponseStream that yields the override
content as ChatResponseUpdate chunks.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Fixed exception handling middleware sample

* Fixed runtime context delegation middleware example

* Fixed multimodal input examples

* Small update

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Dmytro Struk
2026-02-17 19:49:33 -05:00
committed by GitHub
Unverified
parent df58775d64
commit 2dd731f90f
8 changed files with 204 additions and 33 deletions
@@ -47,8 +47,8 @@ async def exception_handling_middleware(
print(f"[ExceptionHandlingMiddleware] Caught TimeoutError: {e}")
# Override function result to provide custom message in response.
context.result = (
"Request Timeout: The data service is taking longer than expected to respond.",
"Respond with message - 'Sorry for the inconvenience, please try again later.'",
"Request Timeout: The data service is taking longer than expected to respond."
"Respond with message - 'Sorry for the inconvenience, please try again later.'"
)
@@ -2,7 +2,7 @@
import asyncio
import re
from collections.abc import Awaitable, Callable
from collections.abc import AsyncIterable, Awaitable, Callable
from random import randint
from typing import Annotated
@@ -13,9 +13,9 @@ from agent_framework import (
ChatContext,
ChatResponse,
ChatResponseUpdate,
Content,
Message,
ResponseStream,
Role,
tool,
)
from agent_framework.openai import OpenAIResponsesClient
@@ -66,22 +66,20 @@ async def weather_override_middleware(context: ChatContext, call_next: Callable[
]
if context.stream and isinstance(context.result, ResponseStream):
index = {"value": 0}
def _update_hook(update: ChatResponseUpdate) -> ChatResponseUpdate:
for content in update.contents or []:
if not content.text:
continue
content.text = f"Weather Advisory: [{index['value']}] {content.text}"
index["value"] += 1
return update
async def _override_stream() -> AsyncIterable[ChatResponseUpdate]:
for i, chunk_text in enumerate(chunks):
yield ChatResponseUpdate(
contents=[Content.from_text(text=f"Weather Advisory: [{i}] {chunk_text}")],
role="assistant",
)
context.result.with_transform_hook(_update_hook)
context.result = ResponseStream(_override_stream())
else:
# For non-streaming: just replace with a new message
current_text = context.result.text if isinstance(context.result, ChatResponse) else ""
custom_message = f"Weather Advisory: [0] {''.join(chunks)} Original message was: {current_text}"
context.result = ChatResponse(messages=[Message(role=Role.ASSISTANT, text=custom_message)])
context.result = ChatResponse(messages=[Message(role="assistant", text=custom_message)])
async def validate_weather_middleware(context: ChatContext, call_next: Callable[[], Awaitable[None]]) -> None:
@@ -96,12 +94,12 @@ async def validate_weather_middleware(context: ChatContext, call_next: Callable[
if context.stream and isinstance(context.result, ResponseStream):
def _append_validation_note(response: ChatResponse) -> ChatResponse:
response.messages.append(Message(role=Role.ASSISTANT, text=validation_note))
response.messages.append(Message(role="assistant", text=validation_note))
return response
context.result.with_finalizer(_append_validation_note)
elif isinstance(context.result, ChatResponse):
context.result.messages.append(Message(role=Role.ASSISTANT, text=validation_note))
context.result.messages.append(Message(role="assistant", text=validation_note))
async def agent_cleanup_middleware(context: AgentContext, call_next: Callable[[], Awaitable[None]]) -> None:
@@ -154,7 +152,7 @@ async def agent_cleanup_middleware(context: AgentContext, call_next: Callable[[]
if not found_validation:
raise RuntimeError("Expected validation note not found in agent response.")
cleaned_messages.append(Message(role=Role.ASSISTANT, text=" Agent: OK"))
cleaned_messages.append(Message(role="assistant", text=" Agent: OK"))
response.messages = cleaned_messages
return response