Enable Rich UI embed support for action functions (#21294)

Action functions can now return HTMLResponse objects or (html, headers)
tuples with Content-Disposition: inline to render rich UI iframes in
chat, matching the existing tool behavior.

https://claude.ai/code/session_01KCZKQXj1uqgPjqjMd4U2NF

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Classic298
2026-02-11 16:27:00 -06:00
committed by GitHub
co-authored by Claude
parent f376d4f378
commit ab20745ee5
2 changed files with 25 additions and 1 deletions
+24
View File
@@ -449,6 +449,30 @@ async def chat_action(request: Request, action_id: str, form_data: dict, user: A
else:
data = action(**params)
# Process action result for Rich UI embeds (HTMLResponse, tuple with headers)
# Deferred import to avoid circular dependency (middleware imports chat)
from open_webui.utils.middleware import process_tool_result
processed_result, _, action_embeds = process_tool_result(
request,
action_id,
data,
"action",
)
if action_embeds:
await __event_emitter__(
{
"type": "embeds",
"data": {
"embeds": action_embeds,
},
}
)
# Replace data with the processed status dict so we don't
# try to serialize the raw HTMLResponse / tuple back to the client
data = processed_result
except Exception as e:
raise Exception(f"Error: {e}")
+1 -1
View File
@@ -859,7 +859,7 @@ def process_tool_result(
else:
tool_result = tool_result.body.decode("utf-8", "replace")
elif (tool_type == "external" and isinstance(tool_result, tuple)) or (
elif (tool_type in ("external", "action") and isinstance(tool_result, tuple)) or (
direct_tool and isinstance(tool_result, list) and len(tool_result) == 2
):
tool_result, tool_response_headers = tool_result