User in the loop for Teams

Hi All,

I have stumbled upon the problem of not being able to provide an input to my agent from a Team level. When I use isolated agent I can do the trick with the:

“if run_response.is_paused”

But when I try this:

from typing import List
from dotenv import load_dotenv
import os
from agno.run.response import RunEvent

from agno.agent import Agent
from agno.team.team import Team
from agno.models.azure import AzureOpenAI
from agno.tools import tool
from agno.utils import pprint
from agno.tools.function import UserInputField
from agno.tools.user_control_flow import UserControlFlowTools

# Load environment variables from .env file
load_dotenv()

# Azure OpenAI Configuration
AZURE_OPENAI_ENDPOINT = os.getenv("AZURE_OPENAI_ENDPOINT")
AZURE_OPENAI_API_KEY = os.getenv("AZURE_OPENAI_API_KEY")
OPENAI_API_VERSION = os.getenv("OPENAI_API_VERSION")
OPENAI_DEPLOYMENT = os.getenv("OPENAI_DEPLOYMENT")

# Application Configuration
DEBUG = os.getenv("DEBUG", "False").lower() == "true"
LOG_LEVEL = os.getenv("LOG_LEVEL", "INFO")

# Add other configuration variables as needed 
LLM_MODEL_AZURE_OPENAI=AzureOpenAI(id=OPENAI_DEPLOYMENT,
                           api_key=AZURE_OPENAI_API_KEY,
                           api_version=OPENAI_API_VERSION,
                           azure_endpoint=AZURE_OPENAI_ENDPOINT, temperature=0.0)

poet = Agent(
    name="Agent writing poem about the subject given by user",
    model=LLM_MODEL_AZURE_OPENAI,
    tools=[UserControlFlowTools()],
    show_tool_calls=True,
    description="You are a agent that writes poem about the subject given by user",
    instructions="You are a agent that writes poem about the subject given by user",
    expected_output="The poem about the subject",
    reasoning=False
)

DESCRIPTION = """
You are a team of poets who write poems about the subject given by user.
"""

INSTRUCTIONS = """
Identify the subject of the poem if given. 
If the user does not provide a subject let the agent ask for a subject.
"""

AGREEMENT_GENERATION_TEAM = Team(
    name="Team for answering user questions",
    mode="coordinate",
    model=LLM_MODEL_AZURE_OPENAI,
    members=[poet],
    share_member_interactions=True,
    markdown=False,
    description=DESCRIPTION,
    instructions=INSTRUCTIONS,
    show_members_responses=True,
    reasoning=False,
    enable_agentic_context=True,
    get_member_information_tool=True,   
    add_member_tools_to_system_message=True,
)

KNOWN_SUBJECTS = False

if __name__ == "__main__":
    # Ask "How are you?" in all supported languages
    if KNOWN_SUBJECTS:
        AGREEMENT_GENERATION_TEAM.print_response("Write poem about love.", stream=True)
    else:
        AGREEMENT_GENERATION_TEAM.print_response("Write poem.", stream=True)

It does not even ask me for the poem subject. It only complains about the order of tool_calling:

agno.exceptions.ModelProviderError: An assistant message with ‘tool_calls’ must be followed by tool messages responding to each ‘tool_call_id’. The following tool_call_ids did not have response messages: call_kyAO0ObsxB6vZTYyeE0Qjt0U

I have also tried with more “manual mode”. I was able to feed the agent with the subject and resume it’s execution. Unfortunately I don’t know how to properly resume the execution of the team.

# Test the agent in a team, or test the agent as a single agent
TEST_TEAM = True

if __name__ == "__main__":

    if TEST_TEAM:
        
        team_run_response = AGREEMENT_GENERATION_TEAM.run("Write poem about the subject given by user")
        team_session_id = team_run_response.session_id
        print(team_session_id)
        paused_agent_id = find_paused_agent_with_user_input(team_run_response)                                      # Find paused agent and tools requiring user input

        while paused_agent_id:
            paused_agent = get_agent_by_id(AGREEMENT_GENERATION_TEAM, paused_agent_id)
            paused_agent_run_response = paused_agent.run_response
            
            for tool in paused_agent_run_response.tools_requiring_user_input:                                       # For each tool requiring user input, get the input
                input_schema: List[UserInputField] = tool.user_input_schema
                for field in input_schema:
                    # Display field information to the user
                    print(f"\nField: {field.name} ({field.field_type.__name__}) -> {field.description}")

                    # Get user input
                    if field.value is None:
                        user_value = input(f"Please enter a value for {field.name}: ")
                        field.value = user_value
                    else:
                        print(f"Value provided to the agent: {field.value}")

            paused_agent_run_response = paused_agent.continue_run(run_response=paused_agent_run_response)           # Try to advance the agent
            #if not paused_agent_run_response.is_paused:
            #   pprint.pprint_run_response(paused_agent_run_response)
            #   break

            team_run_response = AGREEMENT_GENERATION_TEAM.run("", session_id=team_session_id)                       # Try to advance the team          
            team_session_id = team_run_response.session_id
            print(team_session_id)
            paused_agent_id = find_paused_agent_with_user_input(team_run_response)
            if not paused_agent_id:
                AGREEMENT_GENERATION_TEAM.print_response(team_run_response, stream=True, stream_intermediate_steps=True)
                print("---------------- END BREAK ----------------")
                break

agno==1.5.9, macos, GPT-4o

Can someone help please ?

I think I have found the answer.

from typing import List
from dotenv import load_dotenv
import os
from agno.run.response import RunEvent

from agno.agent import Agent
from agno.team.team import Team
from agno.models.azure import AzureOpenAI
from agno.tools import tool
from agno.utils import pprint
from agno.tools.function import UserInputField
from rich.console import Console
from rich.prompt import Prompt
from agno.tools.user_control_flow import UserControlFlowTools

# Load environment variables from .env file
load_dotenv()

# Azure OpenAI Configuration
AZURE_OPENAI_ENDPOINT = os.getenv("AZURE_OPENAI_ENDPOINT")
AZURE_OPENAI_API_KEY = os.getenv("AZURE_OPENAI_API_KEY")
OPENAI_API_VERSION = os.getenv("OPENAI_API_VERSION")
OPENAI_DEPLOYMENT = os.getenv("OPENAI_DEPLOYMENT")

# Application Configuration
DEBUG = os.getenv("DEBUG", "False").lower() == "true"
LOG_LEVEL = os.getenv("LOG_LEVEL", "INFO")

# Add other configuration variables as needed 
LLM_MODEL_AZURE_OPENAI=AzureOpenAI(id=OPENAI_DEPLOYMENT,
                           api_key=AZURE_OPENAI_API_KEY,
                           api_version=OPENAI_API_VERSION,
                           azure_endpoint=AZURE_OPENAI_ENDPOINT, temperature=0.0)

console = Console()

@tool()
def ask_user_about_poem_subject() -> str:
    """Ask the user for the subject of the poem.

    Returns:
        str: string containing poem subject
    """
    live = console._live

    # Stop the live display temporarily so we can ask for user confirmation
    live.stop()

    # Ask for confirmation.
    subject = (Prompt.ask("Enter the subject of the poem:").strip().lower())

    # Restart the live display
    live.start()

    return subject


poet = Agent(
    name="Agent writing poem about the subject given by user",
    model=LLM_MODEL_AZURE_OPENAI,
    tools=[ask_user_about_poem_subject, UserControlFlowTools()],
    show_tool_calls=True,
    description="You are a agent that writes poem about the subject given by user",
    instructions="You are a agent that writes poem about the subject given by user",
    expected_output="The poem about the subject",
    reasoning=False
)


DESCRIPTION = """
You are a team of poets who write poems about the subject given by user.
"""

INSTRUCTIONS = """
Identify the subject of the poem if given. 
If the user does not provide a subject let the agent ask for a subject.
"""


AGREEMENT_GENERATION_TEAM = Team(
    name="Team for answering user questions",
    mode="coordinate",
    model=LLM_MODEL_AZURE_OPENAI,
    members=[poet],
    share_member_interactions=True,
    markdown=False,
    description=DESCRIPTION,
    instructions=INSTRUCTIONS,
    show_members_responses=True,
    reasoning=False,
    enable_agentic_context=True,
    get_member_information_tool=True,   
    add_member_tools_to_system_message=True,
)


RUN_AS_AGENT = False
if __name__ == "__main__":
    # Ask "How are you?" in all supported languages
    if RUN_AS_AGENT:
        poet.print_response("Write poem.", stream=True, console=console)
    else:
        AGREEMENT_GENERATION_TEAM.print_response("Write poem.", stream=True, console=console)

I’d appreciate if someone can give more hints, or some useful doc link for managing user input in Teams, Agents and Workflows.

Thx in advance!

Hey @bkoseda
thanks for reaching out and supporting Agno. I’ve shared this with the team, we’re working through all requests one by one and will get back to you soon.
If it’s urgent, please let us know. We appreciate your patience!