Hi everyone,
I’ve been building a multi-agent system using Agno + AG-UI, and I’ve run into a major issue that’s quite confusing to me:
I noticed that Agno’s AgentOS has a fully functional implementation of human-in-the-loop (HITL).
However, when Agno converts the output into AG-UI format, things seem to break. From the code, it appears that the AG-UI conversion layer is not fully implemented, and at this point I’m not sure how Agno expects HITL to work when using AG-UI.
To be more specific, I checked the related event-conversion code inside Agno, but it seems that it only outputs tool-call events, without reflecting the essential HITL sequence of:
pause → wait for user → resume execution
\# emit frontend tool calls, i.e. external_execution=True if isinstance(chunk, RunPausedEvent) and chunk.tools is not None: \# First, emit an assistant message for external tool calls assistant_message_id = str(uuid.uuid4()) assistant_start_event = TextMessageStartEvent( type=EventType.TEXT_MESSAGE_START, message_id=assistant_message_id, role="assistant", ) events_to_emit.append(assistant_start_event) \# Add any text content if present for the assistant message if chunk.content: content_event = TextMessageContentEvent( type=EventType.TEXT_MESSAGE_CONTENT, message_id=assistant_message_id, delta=str(chunk.content), ) events_to_emit.append(content_event) \# End the assistant message assistant_end_event = TextMessageEndEvent( type=EventType.TEXT_MESSAGE_END, message_id=assistant_message_id, ) events_to_emit.append(assistant_end_event) \# Now emit the tool call events with the assistant message as parent for tool in chunk.tools: if tool.tool_call_id is None or tool.tool_name is None: continue start_event = ToolCallStartEvent( type=EventType.TOOL_CALL_START, tool_call_id=tool.tool_call_id, tool_call_name=tool.tool_name, parent_message_id=assistant_message_id, # Use the assistant message as parent ) events_to_emit.append(start_event) args_event = ToolCallArgsEvent( type=EventType.TOOL_CALL_ARGS, tool_call_id=tool.tool_call_id, delta=json.dumps(tool.tool_args), ) events_to_emit.append(args_event) end_event = ToolCallEndEvent( type=EventType.TOOL_CALL_END, tool_call_id=tool.tool_call_id, ) events_to_emit.append(end_event)