/*
* Copyright (c) Huawei Technologies Co., Ltd. 2024-2025. All rights reserved.
*/
package magic.agent_executor
import magic.core.agent.AgentExecutor
import magic.agent_executor.naive.NaiveExecutor
import magic.agent_executor.react.ReactExecutor
import magic.agent_executor.plan_react.PlanReactExecutor
import magic.agent_executor.tool_loop.ToolLoopExecutor
import std.collection.ArrayList
import magic.core.agent.AgentExecutionException
import std.convert.Parsable
private struct AgentExecutorBuilder {
AgentExecutorBuilder(
let checkFn: (String) -> Bool,
let buildFn: (String) -> AgentExecutor) { }
}
public struct AgentExecutorManager {
private static let AGENT_EXECUTOR_BUILDS = ArrayList<AgentExecutorBuilder>()
public static func register(checkFn: (String) -> Bool,
buildFn: (String) -> AgentExecutor): Unit {
AGENT_EXECUTOR_BUILDS.append(AgentExecutorBuilder(checkFn, buildFn))
}
public static func register(name: String,
buildFn: () -> AgentExecutor): Unit {
AGENT_EXECUTOR_BUILDS.append(
AgentExecutorBuilder(
{ n: String => n == name },
{ n: String => buildFn() }
)
)
}
public static func create(name: String): AgentExecutor {
if (name == "naive") {
return NaiveExecutor()
} else if (name == "react") {
return ReactExecutor()
} else if (name == "plan-react") {
return PlanReactExecutor()
} else if (name == "tool-loop") {
return ToolLoopExecutor()
}
// react with a loop number, like react:5
if (name.startsWith("react:") || name.startsWith("tool-loop:")) {
let items = name.split(":")
if (items.size == 2) {
if (let Some(num) <- Int64.tryParse(items[1])) {
if (items[0] == "react") {
return ReactExecutor(loop: num)
} else {
return ToolLoopExecutor(loop: num)
}
}
}
}
for (builder in AGENT_EXECUTOR_BUILDS) {
if (builder.checkFn(name)) {
return builder.buildFn(name)
}
}
throw AgentExecutionException("Unknown executor: `${name}`")
}
}