content: ///*
  // * Copyright 2024-2025 the original author or authors.
  // *
  // * Licensed under the Apache License, Version 2.0 (the "License");
  // * you may not use this file except in compliance with the License.
  // * You may obtain a copy of the License at
  // *
  // *      https://www.apache.org/licenses/LICENSE-2.0
  // *
  // * Unless required by applicable law or agreed to in writing, software
  // * distributed under the License is distributed on an "AS IS" BASIS,
  // * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  // * See the License for the specific language governing permissions and
  // * limitations under the License.
  // */
  //
  //package com.alibaba.cloud.ai.graph.agent.flow.strategy;
  //
  //import com.alibaba.cloud.ai.graph.KeyStrategyFactory;
  //import com.alibaba.cloud.ai.graph.KeyStrategyFactoryBuilder;
  //import com.alibaba.cloud.ai.graph.StateGraph;
  //import com.alibaba.cloud.ai.graph.agent.BaseAgent;
  //import com.alibaba.cloud.ai.graph.agent.a2a.A2aRemoteAgent;
  //import com.alibaba.cloud.ai.graph.agent.flow.agent.LoopAgent;
  //import com.alibaba.cloud.ai.graph.agent.flow.builder.FlowGraphBuilder;
  //import com.alibaba.cloud.ai.graph.agent.flow.enums.FlowAgentEnum;
  //import com.alibaba.cloud.ai.graph.agent.flow.node.TransparentNode;
  //import com.alibaba.cloud.ai.graph.exception.GraphStateException;
  //import com.alibaba.cloud.ai.graph.state.strategy.ReplaceStrategy;
  //
  //import java.util.Map;
  //import java.util.stream.Collectors;
  //import java.util.stream.Stream;
  //
  //import static com.alibaba.cloud.ai.graph.StateGraph.END;
  //import static com.alibaba.cloud.ai.graph.StateGraph.START;
  //import static com.alibaba.cloud.ai.graph.action.AsyncEdgeAction.edge_async;
  //import static com.alibaba.cloud.ai.graph.action.AsyncNodeAction.node_async;
  //
  //public class LoopGraphBuildingStrategy implements FlowGraphBuildingStrategy {
  //
  //	private String generateTempInput(BaseAgent agent) {
  //		return agent.name() + "__input";
  //	}
  //
  //	private String generateTempOutput(BaseAgent agent) {
  //		return agent.name() + "__output";
  //	}
  //
  //	private String generateBodyName(String agentName, int idx) {
  //		return agentName + "__loop_body" + idx;
  //	}
  //
  //	@Override
  //	public StateGraph buildGraph(FlowGraphBuilder.FlowGraphConfig config) throws GraphStateException {
  //		String agentName = config.getName();
  //
  //		// Special case: if the loop body has no sub-agents, return an empty StateGraph
  //		// directly
  //		if (config.getSubAgents() == null || config.getSubAgents().isEmpty()) {
  //			return new StateGraph(agentName, config.getKeyStrategyFactory()).addEdge(START, END);
  //		}
  //
  //		// Get LoopConfig
  //		LoopAgent.LoopConfig loopConfig = (LoopAgent.LoopConfig) config.getCustomProperty(LoopAgent.LOOP_CONFIG_KEY);
  //
  //		// Combine the StrategyFactory of Start, loop body, and End into one
  //		KeyStrategyFactory strategyFactory = new KeyStrategyFactoryBuilder()
  //			.addStrategies(config.getKeyStrategyFactory().apply())
  //			.addStrategies(loopConfig.loopMode().getLoopTempKeyStrategyFactory(agentName).apply())
  //			.addStrategies(config.getSubAgents()
  //				.stream()
  //				.flatMap(agent -> Stream.of(generateTempInput(agent), generateTempOutput(agent)))
  //				.collect(Collectors.toMap(k -> k, v -> new ReplaceStrategy(), (v1, v2) -> v2)))
  //			.build();
  //		StateGraph stateGraph = new StateGraph(agentName, strategyFactory);
  //
  //		// Define node names
  //		String bodyStartNodeName = agentName + "__loop_body_start__";
  //		String bodyEndNodeName = agentName + "__loop_body_end__";
  //		String startNodeName = agentName + "__loop_start__";
  //		String endNodeName = agentName + "__loop_end__";
  //
  //		// Add nodes
  //		stateGraph.addNode(startNodeName, node_async(loopConfig.loopMode().getStartAction(loopConfig)));
  //
  //		// Expand sub-agent nodes
  //		String lastOutput = generateTempInput(config.getSubAgents().get(0));
  //		stateGraph.addNode(bodyStartNodeName,
  //				node_async(new TransparentNode(lastOutput, LoopAgent.LoopMode.iteratorItemKey(agentName))));
  //		for (int i = 0; i < config.getSubAgents().size(); i++) {
  //			String thisOutput = generateTempOutput(config.getSubAgents().get(i));
  //			BaseAgent subAgent = config.getSubAgents().get(i);
  //			if (subAgent instanceof A2aRemoteAgent subA2aAgent) {
  //				stateGraph.addNode(generateBodyName(agentName, i),
  //						subA2aAgent.asAsyncNodeActionWithConfig(lastOutput, thisOutput));
  //			} else {
  //				stateGraph.addNode(generateBodyName(agentName, i),
  //						subAgent.asAsyncNodeAction(lastOutput, thisOutput));
  //			}
  //			lastOutput = thisOutput;
  //		}
  //		stateGraph.addNode(bodyEndNodeName,
  //				node_async(new TransparentNode(LoopAgent.LoopMode.iteratorResultKey(agentName), lastOutput)));
  //
  //		stateGraph.addNode(endNodeName, node_async(loopConfig.loopMode().getEndAction(loopConfig)));
  //
  //		// Add conditional edges to control the loop flow
  //		stateGraph.addEdge(START, startNodeName).addConditionalEdges(startNodeName, edge_async((state -> {
  //			Boolean flag = state.value(LoopAgent.LoopMode.loopStartFlagKey(agentName), false);
  //			return flag ? "true" : "false";
  //		})), Map.of("true", bodyStartNodeName, "false", END));
  //
  //		// Expand sub-agent edges
  //		stateGraph.addEdge(bodyStartNodeName, generateBodyName(agentName, 0));
  //		for (int i = 1; i < config.getSubAgents().size(); i++) {
  //			stateGraph.addEdge(generateBodyName(agentName, i - 1), generateBodyName(agentName, i));
  //		}
  //		stateGraph.addEdge(generateBodyName(agentName, config.getSubAgents().size() - 1), bodyEndNodeName);
  //
  //		stateGraph.addEdge(bodyEndNodeName, endNodeName).addEdge(endNodeName, startNodeName);
  //
  //		return stateGraph;
  //	}
  //
  //	@Override
  //	public String getStrategyType() {
  //		return FlowAgentEnum.LOOP.getType();
  //	}
  //
  //	@Override
  //	public void validateConfig(FlowGraphBuilder.FlowGraphConfig config) {
  //		FlowGraphBuildingStrategy.super.validateConfig(config);
  //		Object loopConfigObj = config.getCustomProperty(LoopAgent.LOOP_CONFIG_KEY);
  //		if (!(loopConfigObj instanceof LoopAgent.LoopConfig)) {
  //			throw new IllegalArgumentException("loopConfig is not LoopConfig");
  //		}
  //		((LoopAgent.LoopConfig) loopConfigObj).validate();
  //	}
  //
  //}
  