haive.agents.multi.agent ======================== .. py:module:: haive.agents.multi.agent .. autoapi-nested-parse:: Enhanced MultiAgent V4 - Advanced multi-agent orchestration with enhanced base agent pattern. This module provides the MultiAgent class, which represents the next generation of multi-agent coordination in the Haive framework. It leverages the enhanced base agent pattern to provide sophisticated agent orchestration with clean, intuitive APIs. The MultiAgent extends the base Agent class and implements the required build_graph() abstract method, enabling it to participate fully in the Haive ecosystem while providing advanced multi-agent capabilities. Key Features: - **Enhanced Base Agent Pattern**: Properly extends Agent and implements build_graph() - **Direct List Initialization**: Simple API with agents=[agent1, agent2, ...] - **Multiple Execution Modes**: Sequential, parallel, conditional, and manual orchestration - **AgentNodeV3 Integration**: Advanced state projection for clean agent isolation - **MultiAgentState Management**: Type-safe state handling across agents - **Dynamic Graph Building**: Auto, manual, and lazy build modes - **Conditional Routing**: Rich conditional edge support via BaseGraph2 - **Hot Agent Addition**: Add agents dynamically with automatic recompilation Architecture: The MultiAgent follows a hierarchical architecture: 1. **Agent Layer**: Individual agents with their own state and logic 2. **Orchestration Layer**: Coordination logic and routing decisions 3. **State Layer**: MultiAgentState for shared and private state management 4. **Execution Layer**: AgentNodeV3 for proper state projection .. rubric:: Example Basic sequential workflow:: >>> from haive.agents.multi.agent import MultiAgent >>> from haive.agents.simple import SimpleAgent >>> from haive.agents.react import ReactAgent >>> >>> # Create individual agents >>> analyzer = ReactAgent(name="analyzer", tools=[...]) >>> formatter = SimpleAgent(name="formatter") >>> >>> # Create multi-agent workflow >>> workflow = MultiAgent( ... name="analysis_pipeline", ... agents=[analyzer, formatter], ... execution_mode="sequential" ... ) >>> >>> # Execute workflow >>> result = await workflow.arun({"task": "Analyze this data"}) .. seealso:: - :class:`haive.agents.base.agent.Agent`: Base agent class - :class:`haive.core.schema.prebuilt.multi_agent_state.MultiAgentState`: State management - :mod:`haive.core.graph.node.agent_node_v3`: AgentNodeV3 for state projection - :class:`haive.core.graph.state_graph.base_graph2.BaseGraph`: Graph building Classes ------- .. autoapisummary:: haive.agents.multi.agent.MultiAgent Module Contents --------------- .. py:class:: MultiAgent Bases: :py:obj:`haive.agents.base.agent.Agent` Enhanced MultiAgent V4 using enhanced base agent pattern. This class properly extends the enhanced base Agent class and implements the build_graph() abstract method. It provides clean initialization with direct list support and flexible execution modes. .. rubric:: Example >>> # Simple sequential >>> workflow = MultiAgent( ... name="my_workflow", ... agents=[planner, executor, reviewer], ... execution_mode="sequential" ... ) >>> >>> # With conditional branching >>> workflow = MultiAgent( ... name="smart_workflow", ... agents=[classifier, simple_processor, complex_processor], ... execution_mode="conditional", ... build_mode="manual" ... ) >>> >>> # Add conditional edges >>> workflow.add_conditional_edge( ... from_agent="classifier", ... condition=lambda state: state.get("complexity") > 0.7, ... true_agent="complex_processor", ... false_agent="simple_processor" ... ) >>> >>> # Build and execute >>> workflow.build() >>> result = await workflow.arun({"task": "Process this data"}) .. py:method:: add_agent(agent, name = None) Add an agent dynamically and rebuild the graph. :param agent: Agent instance to add :param name: Override name (defaults to agent.name) .. py:method:: add_conditional_edge(from_agent, condition, true_agent, false_agent = END) Add a conditional edge that routes based on a boolean condition. This method creates a branching point in the workflow where execution can take different paths based on the result of a condition function. :param from_agent: Name of the agent where the condition is evaluated. :param condition: Callable that takes the state and returns True or False. :param true_agent: Agent to route to when condition returns True. :param false_agent: Agent to route to when condition returns False (default: END). :raises ValueError: If from_agent doesn't exist. .. rubric:: Example >>> def check_complexity(state): ... return state.get("complexity", 0) > 0.7 ... >>> workflow.add_conditional_edge( ... from_agent="analyzer", ... condition=check_complexity, ... true_agent="complex_processor", ... false_agent="simple_processor" ... ) .. note:: The condition function receives the full MultiAgentState and should return a boolean value. For more complex routing, use add_multi_conditional_edge. .. py:method:: add_edge(from_agent, to_agent) Add a direct edge between two agents in the graph. This method creates a simple connection from one agent to another, useful for building custom execution flows in manual mode. :param from_agent: Name of the source agent. :param to_agent: Name of the destination agent (or END for termination). :raises ValueError: If from_agent doesn't exist or to_agent is invalid. .. rubric:: Example >>> workflow = MultiAgent( ... agents=[agent1, agent2, agent3], ... execution_mode="manual" ... ) >>> workflow.add_edge("agent1", "agent2") >>> workflow.add_edge("agent2", "agent3") >>> workflow.add_edge("agent3", END) .. note:: If the graph is already built, the edge is added immediately. Otherwise, it will be added when the graph is built. .. py:method:: add_multi_conditional_edge(from_agent, condition, routes, default = END) Add multi-way conditional edge with multiple destinations. This method creates a branching point where the condition function returns a string key that maps to different destination agents. :param from_agent: Name of the agent where routing decision is made. :param condition: Callable that returns a route key string. :param routes: Dictionary mapping route keys to agent names. :param default: Default agent when condition returns unmatched key. :raises ValueError: If from_agent doesn't exist. .. rubric:: Example >>> def categorize(state): ... return state.get("category", "other") ... >>> workflow.add_multi_conditional_edge( ... from_agent="categorizer", ... condition=categorize, ... routes={ ... "technical": "tech_agent", ... "sales": "sales_agent", ... "support": "support_agent" ... }, ... default="general_agent" ... ) .. py:method:: build_graph() Build the computational graph for multi-agent orchestration. This method implements the abstract build_graph() from the base Agent class, fulfilling the enhanced base agent pattern. It constructs a BaseGraph that defines how agents are connected and how data flows between them. The graph structure depends on the execution_mode: - **sequential**: Agents execute one after another in order - **parallel**: All agents execute simultaneously - **conditional**: Agents execute based on conditional routing - **manual**: User must add edges manually after creation :returns: The constructed graph ready for compilation and execution. :rtype: BaseGraph :raises ValueError: If no agents are available to build the graph. .. note:: This method is called automatically based on build_mode: - auto: Called during initialization - manual: Must be called explicitly via build() - lazy: Called on first execution .. rubric:: Example >>> # Manual build mode >>> workflow = MultiAgent( ... name="custom", ... agents=[agent1, agent2], ... build_mode="manual" ... ) >>> graph = workflow.build_graph() # Build explicitly >>> workflow.add_edge("agent1", "agent2") # Add custom edges .. py:method:: create_agent(name, system_message, description = None, tools = None, temperature = 0.7) Create a new agent on the fly and add it. :param name: Agent name :param system_message: System prompt :param description: Optional description :param tools: Optional tools (creates ReactAgent if provided) :param temperature: LLM temperature :returns: The created agent .. py:method:: display_info() Display detailed information about the workflow configuration. This method prints a formatted summary of the workflow including: - Execution and build modes - Registered agents and their types - Number of conditional edges - Graph build status .. rubric:: Example >>> workflow.display_info() === Enhanced MultiAgent V4: analysis_pipeline === Execution Mode: sequential Build Mode: auto Entry Point: analyzer Agents (3): 1. analyzer (ReactAgent) 2. processor (SimpleAgent) 3. formatter (SimpleAgent) Conditional Edges: 0 Graph Built: Yes .. py:method:: get_agent(name) Retrieve an agent instance by name. :param name: The name of the agent to retrieve. :returns: The agent instance if found, None otherwise. :rtype: Optional[Agent] .. rubric:: Example >>> agent = workflow.get_agent("analyzer") >>> if agent: ... print(f"Found agent: {agent.name}") .. py:method:: get_agent_names() Get list of all agent names in the workflow. :returns: Names of all registered agents. :rtype: List[str] .. rubric:: Example >>> names = workflow.get_agent_names() >>> print(names) # ['analyzer', 'processor', 'formatter'] .. py:method:: remove_agent(name) Remove an agent and rebuild the graph. .. py:method:: setup_agent() Set up multi-agent configuration before graph building. This method is called BEFORE schema generation and graph building, allowing us to convert agents list to dict properly.