mirror of
https://github.com/slhaf/Partner.git
synced 2026-05-12 16:53:04 +08:00
refactor(action): support built-in actions
This commit is contained in:
@@ -53,6 +53,8 @@ public interface ActionCapability {
|
||||
|
||||
MetaActionInfo loadMetaActionInfo(@NonNull String actionKey);
|
||||
|
||||
void registerMetaActions(@NonNull Map<String, MetaActionInfo> metaActions);
|
||||
|
||||
Map<String, MetaActionInfo> listAvailableMetaActions();
|
||||
|
||||
boolean checkExists(String... actionKeys);
|
||||
|
||||
@@ -30,6 +30,7 @@ import java.util.stream.Collectors;
|
||||
@CapabilityCore(value = "action")
|
||||
@Slf4j
|
||||
public class ActionCore extends PartnerCore<ActionCore> {
|
||||
public static final String BUILTIN_LOCATION = "builtin";
|
||||
|
||||
private final Lock cacheLock = new ReentrantLock();
|
||||
// 由于当前的执行器逻辑实现,平台线程池大小不得小于 2,这里规定为最小为 4
|
||||
@@ -273,7 +274,12 @@ public class ActionCore extends PartnerCore<ActionCore> {
|
||||
}
|
||||
|
||||
@CapabilityMethod
|
||||
public Map<String, MetaActionInfo> listAvailableActions() {
|
||||
public void registerMetaActions(@NonNull Map<String, MetaActionInfo> metaActions) {
|
||||
existedMetaActions.putAll(metaActions);
|
||||
}
|
||||
|
||||
@CapabilityMethod
|
||||
public Map<String, MetaActionInfo> listAvailableMetaActions() {
|
||||
return existedMetaActions;
|
||||
}
|
||||
|
||||
@@ -320,10 +326,11 @@ public class ActionCore extends PartnerCore<ActionCore> {
|
||||
if (split.length < 2) {
|
||||
throw new MetaActionNotFoundException("未找到对应的行动程序,原因: 传入的 actionKey(" + actionKey + ") 存在异常");
|
||||
}
|
||||
MetaAction.Type type = BUILTIN_LOCATION.equals(split[0]) ? MetaAction.Type.BUILTIN : MetaAction.Type.MCP;
|
||||
return new MetaAction(
|
||||
split[1],
|
||||
metaActionInfo.isIo(),
|
||||
MetaAction.Type.MCP,
|
||||
type,
|
||||
split[0]
|
||||
);
|
||||
}
|
||||
|
||||
@@ -14,12 +14,14 @@ data class MetaAction(
|
||||
*/
|
||||
val io: Boolean = false,
|
||||
/**
|
||||
* 行动程序类型,可分为 MCP、ORIGIN 两种,前者对应读取到的 MCP Tool、后者对应生成的临时行动程序
|
||||
* 行动程序类型,可分为 MCP、ORIGIN、BUILTIN 三种,
|
||||
* 分别对应读取到的 MCP Tool、生成的临时行动程序、本地内置行动
|
||||
*/
|
||||
val type: Type,
|
||||
/**
|
||||
* 当类型为 MCP 时,该字段对应相应 MCP Client 注册时生成的 id;
|
||||
* 当类型为 ORIGIN 时,该字段对应相应的磁盘路径字符串
|
||||
* 当类型为 ORIGIN 时,该字段对应相应的磁盘路径字符串;
|
||||
* 当类型为 BUILTIN 时,该字段固定为 builtin
|
||||
*/
|
||||
val location: String,
|
||||
) {
|
||||
@@ -67,7 +69,12 @@ data class MetaAction(
|
||||
/**
|
||||
* 适用于‘临时生成’的行动程序,在生成后根据序列化选项及执行情况,进行持久化
|
||||
*/
|
||||
ORIGIN
|
||||
ORIGIN,
|
||||
|
||||
/**
|
||||
* 由本地内置注册表直接执行的行动
|
||||
*/
|
||||
BUILTIN
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -224,6 +224,7 @@ public class LocalRunnerClient extends RunnerClient {
|
||||
response = switch (metaAction.getType()) {
|
||||
case MetaAction.Type.MCP -> doRunWithMcp(metaAction);
|
||||
case MetaAction.Type.ORIGIN -> doRunWithOrigin(metaAction);
|
||||
case MetaAction.Type.BUILTIN -> doRunWithBuiltin(metaAction);
|
||||
};
|
||||
} catch (Exception e) {
|
||||
response = new RunnerResponse();
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package work.slhaf.partner.core.action.runner;
|
||||
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import io.modelcontextprotocol.server.McpStatelessAsyncServer;
|
||||
import lombok.Data;
|
||||
import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import lombok.val;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -11,6 +11,7 @@ import work.slhaf.partner.core.action.entity.MetaAction;
|
||||
import work.slhaf.partner.core.action.entity.MetaAction.Result;
|
||||
import work.slhaf.partner.core.action.entity.MetaActionInfo;
|
||||
import work.slhaf.partner.core.action.exception.ActionInitFailedException;
|
||||
import work.slhaf.partner.module.modules.action.builtin.BuiltinActionRegistry;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
@@ -45,8 +46,8 @@ public abstract class RunnerClient {
|
||||
|
||||
protected final ConcurrentHashMap<String, MetaActionInfo> existedMetaActions;
|
||||
protected final ExecutorService executor;
|
||||
//TODO 仍可提供内部 MCP,但调用方式需要结合 AgentContext来获取,否则生命周期不合
|
||||
protected McpStatelessAsyncServer innerMcpServer;
|
||||
@Setter
|
||||
protected BuiltinActionRegistry builtinActionRegistry;
|
||||
|
||||
/**
|
||||
* ActionCore 将注入虚拟线程池
|
||||
@@ -82,6 +83,23 @@ public abstract class RunnerClient {
|
||||
|
||||
public abstract void persistSerialize(MetaActionInfo metaActionInfo, ActionFileMetaData fileMetaData);
|
||||
|
||||
protected RunnerResponse doRunWithBuiltin(MetaAction metaAction) {
|
||||
RunnerResponse response = new RunnerResponse();
|
||||
if (builtinActionRegistry == null) {
|
||||
response.setOk(false);
|
||||
response.setData("BuiltinActionRegistry 未初始化");
|
||||
return response;
|
||||
}
|
||||
try {
|
||||
response.setData(builtinActionRegistry.call(metaAction.getKey(), metaAction.getParams()));
|
||||
response.setOk(true);
|
||||
} catch (Exception e) {
|
||||
response.setOk(false);
|
||||
response.setData(e.getLocalizedMessage());
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
protected void createPath(String pathStr) {
|
||||
val path = Path.of(pathStr);
|
||||
try {
|
||||
|
||||
@@ -30,8 +30,13 @@ public class SandboxRunnerClient extends RunnerClient {
|
||||
}
|
||||
|
||||
protected RunnerResponse doRun(MetaAction metaAction) {
|
||||
// 调用沙盒执行器
|
||||
return null;
|
||||
return switch (metaAction.getType()) {
|
||||
case BUILTIN -> doRunWithBuiltin(metaAction);
|
||||
case MCP, ORIGIN -> {
|
||||
// 调用沙盒执行器
|
||||
yield null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
package work.slhaf.partner.module.modules.action.builtin;
|
||||
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import work.slhaf.partner.api.agent.factory.capability.annotation.InjectCapability;
|
||||
import work.slhaf.partner.api.agent.factory.component.abstracts.AbstractAgentModule;
|
||||
import work.slhaf.partner.api.agent.factory.component.annotation.Init;
|
||||
import work.slhaf.partner.core.action.ActionCapability;
|
||||
import work.slhaf.partner.core.action.entity.MetaActionInfo;
|
||||
import work.slhaf.partner.core.action.exception.MetaActionNotFoundException;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static work.slhaf.partner.core.action.ActionCore.BUILTIN_LOCATION;
|
||||
|
||||
public class BuiltinActionRegistry extends AbstractAgentModule.Standalone {
|
||||
|
||||
@Getter
|
||||
private final Map<String, BuiltinActionDefinition> definitions = new LinkedHashMap<>();
|
||||
@InjectCapability
|
||||
private ActionCapability actionCapability;
|
||||
|
||||
public static BuiltinActionDefinition definition(String name, MetaActionInfo metaActionInfo,
|
||||
Function<Map<String, Object>, Object> invoker) {
|
||||
return new BuiltinActionDefinition(BUILTIN_LOCATION + "::" + name, metaActionInfo, invoker);
|
||||
}
|
||||
|
||||
@Init
|
||||
public void init() {
|
||||
definitions.clear();
|
||||
for (BuiltinActionDefinition definition : buildDefinitions()) {
|
||||
definitions.put(definition.actionKey(), definition);
|
||||
}
|
||||
actionCapability.registerMetaActions(exportMetaActionInfos());
|
||||
actionCapability.runnerClient().setBuiltinActionRegistry(this);
|
||||
}
|
||||
|
||||
protected List<BuiltinActionDefinition> buildDefinitions() {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
public String call(@NonNull String actionKey, @NonNull Map<String, Object> params) {
|
||||
BuiltinActionDefinition definition = definitions.get(actionKey);
|
||||
if (definition == null) {
|
||||
throw new MetaActionNotFoundException("未找到对应的内置行动程序: " + actionKey);
|
||||
}
|
||||
Object result = definition.invoker().apply(params);
|
||||
if (result == null) {
|
||||
return "null";
|
||||
}
|
||||
if (result instanceof String string) {
|
||||
return string;
|
||||
}
|
||||
if (result instanceof Number || result instanceof Boolean || result instanceof Map || result instanceof Iterable) {
|
||||
return JSONObject.toJSONString(result);
|
||||
}
|
||||
return String.valueOf(result);
|
||||
}
|
||||
|
||||
private Map<String, MetaActionInfo> exportMetaActionInfos() {
|
||||
Map<String, MetaActionInfo> metaActions = new LinkedHashMap<>();
|
||||
definitions.forEach((key, value) -> metaActions.put(key, value.metaActionInfo()));
|
||||
return metaActions;
|
||||
}
|
||||
|
||||
public record BuiltinActionDefinition(
|
||||
String actionKey,
|
||||
MetaActionInfo metaActionInfo,
|
||||
Function<Map<String, Object>, Object> invoker
|
||||
) {
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user