UserNode#

UserNode is a node that receives user input from the terminal and provides interactive functionality for the graph.

Overview#

UserNode inherits from AsyncNode, providing a simple user interaction interface. When the graph execution reaches UserNode, it displays a prompt in the terminal and waits for user input, then passes the input to the subsequent flow.

Characteristics#

  • Asynchronous Processing: Avoid blocking the event loop, support high-concurrency scenarios

  • Configurable Prompt: Supports custom user prompts

  • Flexible Storage: Can specify the storage key name for input in the state

  • Exception Safety: Gracefully handle various exceptions

  • Simple and Easy to Use: Simple configuration, Ready to use out of the box

Basic Usage#

from evofabric.core.agent._user_node import UserNode

# Create a UserNode with default configuration
user_node = UserNode()

# Custom prompt message
custom_node = UserNode(prompt_message="Please enter your command: ")

# Custom storage key name
keyed_node = UserNode(input_key="custom_input")

Use in the figure#

# Define a graph containing UserNode
from evofabric.core.graph import GraphBuilder

graph = GraphBuilder()

# Add nodes and edges
graph.add_node("user_input", User  Node(prompt_message="Please enter task description: "))
graph.add_node("process", YourProcessingNode())
graph.add_edge("user_input", "process")

# Execute the graph
final_state = await graph.run({"messages": []})

# Assume user input "Complete data analysis"
# Result: final_state["messages"] contains the user input message

Best Practices#

1. Input Validation

If user input validation is required, processing logic can be added in subsequent nodes:

async def validate_input(state: State) -> StateDelta:
    user_input = state.get("user_input", "")
    if not user_input.strip():
        return {"error": "Input cannot be empty"}
    # Other validation ...

2. Error Handling

UserNode already has built-in comprehensive exception handling, but it is recommended to add business logic error handling in the subsequent nodes of the graph:

async def handle_error(state: State) -> StateDelta:
    if "error" in state:
        print(f"Error: {state['error']}")
        return {"messages": [UserMessage(content="Please re-enter")]}
    return {}

3. Multi-turn Dialogue

Can implement a simple multi-turn dialogue mode:

class ConversationNode(AsyncNode):
    async def __call__(self, state: State) -> StateDelta:
        messages = state.get("  "messages", [])
        if not messages:
            # First round: ask for requirements
            return {"messages": [UserMessage(content="What help do you need?")]}
        else:
            # Subsequent rounds: process user replies
            last_message = messages[-1].content
            if last_message.lower() in ["exit", "quit"]:
                return {"messages": [UserMessage(content="Goodbye!")]}
            # Process other replies...
            return {"messages": [UserMessage(content="Your reply has been received")]}

Parameter Description#

evofabric.core.agent.prompt_message#

Displayed user input prompt

Type:

str

Default:

“Please enter your input: “

evofabric.core.agent.input_key#

The key name for user input stored in the state.

Type:

str

Default:

“user_input”

Exception Handling#

UserNode automatically handles the following exceptions:

  • EOFError: User input stream ends (e.g., end-of-file marker)

  • KeyboardInterrupt: User interrupted input (Ctrl+C)

  • Other Exceptions: Catch all unexpected errors

An empty state delta is returned in all exceptional cases to ensure that graph execution is not interrupted.