refactor(MetaAction): migrate to Kotlin data class, merge MetaActionType/ResultStatus into nested enums, and update runner/action usages

This commit is contained in:
2026-02-08 17:15:58 +08:00
parent 6ba5784a7f
commit 7dd2104689
12 changed files with 112 additions and 112 deletions

View File

@@ -8,7 +8,10 @@ import work.slhaf.partner.api.agent.factory.capability.annotation.CapabilityCore
import work.slhaf.partner.api.agent.factory.capability.annotation.CapabilityMethod; import work.slhaf.partner.api.agent.factory.capability.annotation.CapabilityMethod;
import work.slhaf.partner.common.vector.VectorClient; import work.slhaf.partner.common.vector.VectorClient;
import work.slhaf.partner.core.PartnerCore; import work.slhaf.partner.core.PartnerCore;
import work.slhaf.partner.core.action.entity.*; import work.slhaf.partner.core.action.entity.ActionData;
import work.slhaf.partner.core.action.entity.MetaAction;
import work.slhaf.partner.core.action.entity.MetaActionInfo;
import work.slhaf.partner.core.action.entity.PhaserRecord;
import work.slhaf.partner.core.action.entity.cache.ActionCacheData; import work.slhaf.partner.core.action.entity.cache.ActionCacheData;
import work.slhaf.partner.core.action.entity.cache.CacheAdjustData; import work.slhaf.partner.core.action.entity.cache.CacheAdjustData;
import work.slhaf.partner.core.action.entity.cache.CacheAdjustMetaData; import work.slhaf.partner.core.action.entity.cache.CacheAdjustMetaData;
@@ -214,17 +217,17 @@ public class ActionCore extends PartnerCore<ActionCore> {
if (metaActionInfo == null) { if (metaActionInfo == null) {
throw new MetaActionNotFoundException("未找到对应的行动程序信息" + actionKey); throw new MetaActionNotFoundException("未找到对应的行动程序信息" + actionKey);
} }
MetaAction metaAction = new MetaAction();
metaAction.setParams(metaActionInfo.getParams());
metaAction.setType(MetaActionType.MCP);
metaAction.setIo(metaActionInfo.isIo());
String[] split = actionKey.split("::"); String[] split = actionKey.split("::");
if (split.length < 2) { if (split.length < 2) {
throw new MetaActionNotFoundException("未找到对应的行动程序,原因: 传入的 actionKey(" + actionKey + ") 存在异常"); throw new MetaActionNotFoundException("未找到对应的行动程序,原因: 传入的 actionKey(" + actionKey + ") 存在异常");
} }
metaAction.setLocation(split[0]); return new MetaAction(
metaAction.setName(split[1]); split[1],
return metaAction; metaActionInfo.isIo(),
MetaAction.Type.MCP,
split[0]
);
} }
@CapabilityMethod @CapabilityMethod

View File

@@ -1,61 +1,73 @@
package work.slhaf.partner.core.action.entity; package work.slhaf.partner.core.action.entity
import lombok.Data;
import java.util.Map;
/** /**
* 行动链中的单一元素,封装了调用外部行动程序的必要信息与结果容器,可被{@link work.slhaf.partner.core.action.ActionCapability}执行 * 行动链中的单一元素,封装了调用外部行动程序的必要信息与结果容器,可被[work.slhaf.partner.core.action.ActionCapability]执行
*/ */
@Data data class MetaAction(
public class MetaAction {
/** /**
* 行动name用于标识行动程序 * 行动name用于标识行动程序
*/ */
private String name; val name: String,
/**
* 行动程序可接受的参数,由调用处设置
*/
private Map<String, Object> params;
/**
* 行动结果,包括执行状态和相应内容(执行结果或者错误信息)
*/
private Result result = new Result();
/** /**
* 是否IO密集用于决定使用何种线程池 * 是否IO密集用于决定使用何种线程池
*/ */
private boolean io; val io: Boolean = false,
/** /**
* 行动程序类型,可分为 MCP、ORIGIN 两种,前者对应读取到的 MCP Tool、后者对应生成的临时行动程序 * 行动程序类型,可分为 MCP、ORIGIN 两种,前者对应读取到的 MCP Tool、后者对应生成的临时行动程序
*/ */
private MetaActionType type; val type: Type,
/** /**
* 当类型为 MCP 时,该字段对应相应 MCP Client 注册时生成的 id; * 当类型为 MCP 时,该字段对应相应 MCP Client 注册时生成的 id;
* 当类型为 ORIGIN 时,该字段对应相应的磁盘路径字符串 * 当类型为 ORIGIN 时,该字段对应相应的磁盘路径字符串
*/ */
private String location; val location: String,
) {
/** /**
* actionKey 将由 location+name 共同定位 * 行动程序可接受的参数,由调用处设置
*
* @return actionKey
*/ */
public String getKey() { val params: MutableMap<String, Any> = mutableMapOf()
return location + "::" + name;
/**
* 行动结果,包括执行状态和相应内容(执行结果或者错误信息)
*/
var result = Result()
val key: String
/**
* actionKey 将由 location+name 共同定位
*
* @return actionKey
*/
get() = "$location::$name"
class Result {
var status = Status.WAITING
var data: String? = null
fun reset() {
status = Status.WAITING
data = null
}
enum class Status {
SUCCESS,
FAILED,
WAITING
}
} }
@Data enum class Type {
public static class Result { /**
private ResultStatus status = ResultStatus.WAITING; * 将调用的 MCP 工具,可包括远程、本地任意服务
private String data = null; */
} MCP,
public enum ResultStatus { /**
SUCCESS, * 适用于‘临时生成’的行动程序,在生成后根据序列化选项及执行情况,进行持久化
FAILED, */
WAITING ORIGIN
} }
} }

View File

@@ -1,12 +0,0 @@
package work.slhaf.partner.core.action.entity;
public enum MetaActionType {
/**
* 将调用的 MCP 工具,可包括远程、本地任意服务
*/
MCP,
/**
* 适用于‘临时生成’的行动程序,在生成后根据序列化选项及执行情况,进行持久化
*/
ORIGIN
}

View File

@@ -29,7 +29,6 @@ import work.slhaf.partner.common.mcp.InProcessMcpTransport;
import work.slhaf.partner.core.action.entity.ActionFileMetaData; import work.slhaf.partner.core.action.entity.ActionFileMetaData;
import work.slhaf.partner.core.action.entity.MetaAction; import work.slhaf.partner.core.action.entity.MetaAction;
import work.slhaf.partner.core.action.entity.MetaActionInfo; import work.slhaf.partner.core.action.entity.MetaActionInfo;
import work.slhaf.partner.core.action.entity.MetaActionType;
import work.slhaf.partner.core.action.exception.ActionInitFailedException; import work.slhaf.partner.core.action.exception.ActionInitFailedException;
import work.slhaf.partner.core.action.exception.ActionSerializeFailedException; import work.slhaf.partner.core.action.exception.ActionSerializeFailedException;
@@ -200,8 +199,8 @@ public class LocalRunnerClient extends RunnerClient {
RunnerResponse response; RunnerResponse response;
try { try {
response = switch (metaAction.getType()) { response = switch (metaAction.getType()) {
case MetaActionType.MCP -> doRunWithMcp(metaAction); case MetaAction.Type.MCP -> doRunWithMcp(metaAction);
case MetaActionType.ORIGIN -> doRunWithOrigin(metaAction); case MetaAction.Type.ORIGIN -> doRunWithOrigin(metaAction);
}; };
} catch (Exception e) { } catch (Exception e) {
response = new RunnerResponse(); response = new RunnerResponse();
@@ -251,8 +250,8 @@ public class LocalRunnerClient extends RunnerClient {
} }
@Override @Override
public String buildTmpPath(MetaAction tempAction, String codeType) { public String buildTmpPath(String actionKey, String codeType) {
return Path.of(TMP_ACTION_PATH, System.currentTimeMillis() + "-" + tempAction.getKey() + codeType).toString(); return Path.of(TMP_ACTION_PATH, System.currentTimeMillis() + "-" + actionKey + codeType).toString();
} }
@Override @Override

View File

@@ -9,7 +9,6 @@ import org.jetbrains.annotations.Nullable;
import work.slhaf.partner.core.action.entity.ActionFileMetaData; import work.slhaf.partner.core.action.entity.ActionFileMetaData;
import work.slhaf.partner.core.action.entity.MetaAction; import work.slhaf.partner.core.action.entity.MetaAction;
import work.slhaf.partner.core.action.entity.MetaAction.Result; import work.slhaf.partner.core.action.entity.MetaAction.Result;
import work.slhaf.partner.core.action.entity.MetaAction.ResultStatus;
import work.slhaf.partner.core.action.entity.MetaActionInfo; import work.slhaf.partner.core.action.entity.MetaActionInfo;
import work.slhaf.partner.core.action.exception.ActionInitFailedException; import work.slhaf.partner.core.action.exception.ActionInitFailedException;
@@ -67,17 +66,17 @@ public abstract class RunnerClient {
public void submit(MetaAction metaAction) { public void submit(MetaAction metaAction) {
// 获取已存在行动列表 // 获取已存在行动列表
Result result = metaAction.getResult(); Result result = metaAction.getResult();
if (!result.getStatus().equals(ResultStatus.WAITING)) { if (!result.getStatus().equals(Result.Status.WAITING)) {
return; return;
} }
RunnerResponse response = doRun(metaAction); RunnerResponse response = doRun(metaAction);
result.setData(response.getData()); result.setData(response.getData());
result.setStatus(response.isOk() ? ResultStatus.SUCCESS : ResultStatus.FAILED); result.setStatus(response.isOk() ? Result.Status.SUCCESS : Result.Status.FAILED);
} }
protected abstract RunnerResponse doRun(MetaAction metaAction); protected abstract RunnerResponse doRun(MetaAction metaAction);
public abstract String buildTmpPath(MetaAction tempAction, String codeType); public abstract String buildTmpPath(String actionKey, String codeType);
public abstract void tmpSerialize(MetaAction tempAction, String code, String codeType) throws IOException; public abstract void tmpSerialize(MetaAction tempAction, String code, String codeType) throws IOException;

View File

@@ -40,7 +40,7 @@ public class SandboxRunnerClient extends RunnerClient {
} }
@Override @Override
public String buildTmpPath(MetaAction tempAction, String codeType) { public String buildTmpPath(String actionKey, String codeType) {
throw new UnsupportedOperationException("Unimplemented method 'buildTmpPath'"); throw new UnsupportedOperationException("Unimplemented method 'buildTmpPath'");
} }

View File

@@ -203,7 +203,7 @@ public class ActionExecutor extends AgentRunningSubModule<ActionExecutorInput, V
continue; continue;
} }
ExecutorService executor = next.isIo() ? virtualExecutor : platformExecutor; ExecutorService executor = next.getIo() ? virtualExecutor : platformExecutor;
executor.execute(buildMataActionTask(next, phaserRecord, source)); executor.execute(buildMataActionTask(next, phaserRecord, source));
if (first) { if (first) {
@@ -238,7 +238,7 @@ public class ActionExecutor extends AgentRunningSubModule<ActionExecutorInput, V
val extractorResult = paramsExtractor.execute(extractorInput); val extractorResult = paramsExtractor.execute(extractorInput);
if (extractorResult.isOk()) { if (extractorResult.isOk()) {
metaAction.setParams(extractorResult.getParams()); metaAction.getParams().putAll(extractorResult.getParams());
runnerClient.submit(metaAction); runnerClient.submit(metaAction);
val historyAction = new HistoryAction(actionKey, actionCapability.loadMetaActionInfo(actionKey).getDescription(), metaAction.getResult().getData()); val historyAction = new HistoryAction(actionKey, actionCapability.loadMetaActionInfo(actionKey).getDescription(), metaAction.getResult().getData());
actionData.getHistory() actionData.getHistory()
@@ -251,21 +251,21 @@ public class ActionExecutor extends AgentRunningSubModule<ActionExecutorInput, V
// 如果本次修复被认为成功,则将补充的信息添加至 additionalContext // 如果本次修复被认为成功,则将补充的信息添加至 additionalContext
case RepairerResult.RepairerStatus.OK -> { case RepairerResult.RepairerStatus.OK -> {
additionalContext.addAll(repairerResult.getFixedData()); additionalContext.addAll(repairerResult.getFixedData());
result.setStatus(MetaAction.ResultStatus.WAITING); result.setStatus(MetaAction.Result.Status.WAITING);
} }
// 此处的修复失败来自系统内部的执行失败:其余方式均不可行时将回退至当前分支 // 此处的修复失败来自系统内部的执行失败:其余方式均不可行时将回退至当前分支
case RepairerResult.RepairerStatus.FAILED -> { case RepairerResult.RepairerStatus.FAILED -> {
result.setStatus(MetaAction.ResultStatus.FAILED); result.setStatus(MetaAction.Result.Status.FAILED);
result.setData("行动执行失败"); result.setData("行动执行失败");
} }
// 此处对应已在 repairer 内发起外部请求,故在此处进行阻塞 // 此处对应已在 repairer 内发起外部请求,故在此处进行阻塞
case RepairerResult.RepairerStatus.ACQUIRE -> { case RepairerResult.RepairerStatus.ACQUIRE -> {
phaserRecord.interrupt(); phaserRecord.interrupt();
result.setStatus(MetaAction.ResultStatus.WAITING); result.setStatus(MetaAction.Result.Status.WAITING);
} }
} }
} }
} while (result.getStatus().equals(MetaAction.ResultStatus.WAITING)); } while (result.getStatus().equals(MetaAction.Result.Status.WAITING));
} catch (Exception e) { } catch (Exception e) {
log.error("Action executing failed: {}", actionKey, e); log.error("Action executing failed: {}", actionKey, e);
} finally { } finally {

View File

@@ -16,7 +16,6 @@ import work.slhaf.partner.core.action.ActionCapability;
import work.slhaf.partner.core.action.ActionCore.ExecutorType; import work.slhaf.partner.core.action.ActionCore.ExecutorType;
import work.slhaf.partner.core.action.entity.MetaAction; import work.slhaf.partner.core.action.entity.MetaAction;
import work.slhaf.partner.core.action.entity.MetaAction.Result; import work.slhaf.partner.core.action.entity.MetaAction.Result;
import work.slhaf.partner.core.action.entity.MetaAction.ResultStatus;
import work.slhaf.partner.core.action.runner.RunnerClient; import work.slhaf.partner.core.action.runner.RunnerClient;
import work.slhaf.partner.core.cognation.CognationCapability; import work.slhaf.partner.core.cognation.CognationCapability;
import work.slhaf.partner.module.modules.action.dispatcher.executor.entity.GeneratorInput; import work.slhaf.partner.module.modules.action.dispatcher.executor.entity.GeneratorInput;
@@ -112,7 +111,7 @@ public class ActionRepairer extends AgentRunningSubModule<RepairerInput, Repaire
runnerClient.submit(tempAction); runnerClient.submit(tempAction);
// 根据 tempAction 的执行状态设置修复结果 // 根据 tempAction 的执行状态设置修复结果
Result actionResult = tempAction.getResult(); Result actionResult = tempAction.getResult();
if (actionResult.getStatus() != ResultStatus.SUCCESS) { if (actionResult.getStatus() != MetaAction.Result.Status.SUCCESS) {
result.setStatus(RepairerStatus.FAILED); result.setStatus(RepairerStatus.FAILED);
return result; return result;
} }
@@ -137,7 +136,7 @@ public class ActionRepairer extends AgentRunningSubModule<RepairerInput, Repaire
AtomicInteger failedCount = new AtomicInteger(0); AtomicInteger failedCount = new AtomicInteger(0);
for (String key : actionKeys) { for (String key : actionKeys) {
MetaAction action = actionCapability.loadMetaAction(key); MetaAction action = actionCapability.loadMetaAction(key);
executor = action.isIo() ? virtual : platform; executor = action.getIo() ? virtual : platform;
executor.execute(() -> { executor.execute(() -> {
try { try {
runnerClient.submit(action); runnerClient.submit(action);

View File

@@ -1,6 +1,7 @@
package work.slhaf.partner.module.modules.action.dispatcher.executor; package work.slhaf.partner.module.modules.action.dispatcher.executor;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import lombok.val;
import work.slhaf.partner.api.agent.factory.capability.annotation.InjectCapability; import work.slhaf.partner.api.agent.factory.capability.annotation.InjectCapability;
import work.slhaf.partner.api.agent.factory.module.annotation.AgentSubModule; import work.slhaf.partner.api.agent.factory.module.annotation.AgentSubModule;
import work.slhaf.partner.api.agent.factory.module.annotation.Init; import work.slhaf.partner.api.agent.factory.module.annotation.Init;
@@ -11,7 +12,6 @@ import work.slhaf.partner.common.util.ExtractUtil;
import work.slhaf.partner.core.action.ActionCapability; import work.slhaf.partner.core.action.ActionCapability;
import work.slhaf.partner.core.action.entity.GeneratedData; import work.slhaf.partner.core.action.entity.GeneratedData;
import work.slhaf.partner.core.action.entity.MetaAction; import work.slhaf.partner.core.action.entity.MetaAction;
import work.slhaf.partner.core.action.entity.MetaActionType;
import work.slhaf.partner.core.action.runner.RunnerClient; import work.slhaf.partner.core.action.runner.RunnerClient;
import work.slhaf.partner.module.modules.action.dispatcher.executor.entity.GeneratorInput; import work.slhaf.partner.module.modules.action.dispatcher.executor.entity.GeneratorInput;
import work.slhaf.partner.module.modules.action.dispatcher.executor.entity.GeneratorResult; import work.slhaf.partner.module.modules.action.dispatcher.executor.entity.GeneratorResult;
@@ -40,15 +40,22 @@ public class DynamicActionGenerator extends AgentRunningSubModule<GeneratorInput
// 由于 SCRIPT 类型程序都是在 SandboxRunner 内部的磁盘上加载然后执行的, // 由于 SCRIPT 类型程序都是在 SandboxRunner 内部的磁盘上加载然后执行的,
// 所以此处的输入内容也只需要指定输入参数、临时key、是否持久化即可路径将按照指定规则统一构建不可交给LLM生成 // 所以此处的输入内容也只需要指定输入参数、临时key、是否持久化即可路径将按照指定规则统一构建不可交给LLM生成
String prompt = buildPrompt(input); String prompt = buildPrompt(input);
// 响应结果需要包含几个特殊数据: 依赖项、代码内容、是否序列化、响应数据释义 // 响应结果需要包含几个特殊数据: 依赖项、代码内容、是否序列化、响应数据释义
ChatResponse response = this.singleChat(prompt); ChatResponse response = this.singleChat(prompt);
GeneratedData generatorData = JSONObject GeneratedData generatorData = JSONObject
.parseObject(ExtractUtil.extractJson(response.getMessage()), GeneratedData.class); .parseObject(ExtractUtil.extractJson(response.getMessage()), GeneratedData.class);
MetaAction tempAction = buildAction(input);
val location = runnerClient.buildTmpPath(input.getActionName(), generatorData.getCodeType());
MetaAction tempAction = new MetaAction(
input.getActionName(),
true,
MetaAction.Type.ORIGIN,
location
);
// 将临时行动单元序列化至临时文件夹,并设置程序路径、放置在队列中,等待执行状态变化,并根据序列化选项选择是否补充 MetaActionInfo 并持久序列化 // 将临时行动单元序列化至临时文件夹,并设置程序路径、放置在队列中,等待执行状态变化,并根据序列化选项选择是否补充 MetaActionInfo 并持久序列化
// 通过 ActionCapability 暴露的接口序列化至临时文件夹同时返回Path对象并设置。队列建议交给 SandboxRunner // 通过 ActionCapability 暴露的接口序列化至临时文件夹同时返回Path对象并设置。队列建议交给 SandboxRunner
// 持有,包括监听与序列化线程 // 持有,包括监听与序列化线程
tempAction.setLocation(runnerClient.buildTmpPath(tempAction, generatorData.getCodeType()));
runnerClient.tmpSerialize(tempAction, generatorData.getCode(), generatorData.getCodeType()); runnerClient.tmpSerialize(tempAction, generatorData.getCode(), generatorData.getCodeType());
if (generatorData.isSerialize()) { if (generatorData.isSerialize()) {
waitingSerialize(); waitingSerialize();
@@ -64,15 +71,6 @@ public class DynamicActionGenerator extends AgentRunningSubModule<GeneratorInput
throw new UnsupportedOperationException("Unimplemented method 'waitingSerialize'"); throw new UnsupportedOperationException("Unimplemented method 'waitingSerialize'");
} }
private MetaAction buildAction(GeneratorInput input) {
MetaAction tempAction = new MetaAction();
tempAction.setName(input.getActionName());
tempAction.setParams(input.getParams());
tempAction.setIo(true);
tempAction.setType(MetaActionType.ORIGIN);
return tempAction;
}
private String buildPrompt(GeneratorInput data) { private String buildPrompt(GeneratorInput data) {
JSONObject prompt = new JSONObject(); JSONObject prompt = new JSONObject();
prompt.put("[行动描述]", data.getDescription()); prompt.put("[行动描述]", data.getDescription());

View File

@@ -7,7 +7,6 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir; import org.junit.jupiter.api.io.TempDir;
import work.slhaf.partner.core.action.entity.MetaAction; import work.slhaf.partner.core.action.entity.MetaAction;
import work.slhaf.partner.core.action.entity.MetaActionInfo; import work.slhaf.partner.core.action.entity.MetaActionInfo;
import work.slhaf.partner.core.action.entity.MetaActionType;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
@@ -177,12 +176,14 @@ public class LocalRunnerClientTest {
+ " }"; + " }";
} }
static MetaAction buildMetaAction(MetaActionType type, String location, String name, Map<String, Object> params) { static MetaAction buildMetaAction(MetaAction.Type type, String location, String name, Map<String, Object> params) {
MetaAction metaAction = new MetaAction(); MetaAction metaAction = new MetaAction(
metaAction.setType(type); name,
metaAction.setLocation(location); false,
metaAction.setName(name); type,
metaAction.setParams(params); location
);
metaAction.getParams().putAll(params);
return metaAction; return metaAction;
} }
} }
@@ -782,7 +783,7 @@ public class LocalRunnerClientTest {
try { try {
Path script = tempDir.resolve("run"); Path script = tempDir.resolve("run");
Files.writeString(script, "echo ok\n"); Files.writeString(script, "echo ok\n");
MetaAction metaAction = buildMetaAction(MetaActionType.ORIGIN, script.toString(), "run", Map.of()); MetaAction metaAction = buildMetaAction(MetaAction.Type.ORIGIN, script.toString(), "run", Map.of());
RunnerClient.RunnerResponse response = client.doRun(metaAction); RunnerClient.RunnerResponse response = client.doRun(metaAction);
Assertions.assertNotNull(response); Assertions.assertNotNull(response);
Assertions.assertFalse(response.isOk()); Assertions.assertFalse(response.isOk());
@@ -801,7 +802,7 @@ public class LocalRunnerClientTest {
try { try {
Path script = tempDir.resolve("run.sh"); Path script = tempDir.resolve("run.sh");
Files.writeString(script, "echo ok\n"); Files.writeString(script, "echo ok\n");
MetaAction metaAction = buildMetaAction(MetaActionType.ORIGIN, script.toString(), "run", Map.of()); MetaAction metaAction = buildMetaAction(MetaAction.Type.ORIGIN, script.toString(), "run", Map.of());
RunnerClient.RunnerResponse response = client.doRun(metaAction); RunnerClient.RunnerResponse response = client.doRun(metaAction);
Assertions.assertNotNull(response); Assertions.assertNotNull(response);
Assertions.assertTrue(response.isOk()); Assertions.assertTrue(response.isOk());
@@ -818,7 +819,7 @@ public class LocalRunnerClientTest {
LocalRunnerClient client = new LocalRunnerClient(existedMetaActions, executor, tempDir.toString()); LocalRunnerClient client = new LocalRunnerClient(existedMetaActions, executor, tempDir.toString());
try { try {
MetaAction metaAction = buildMetaAction(MetaActionType.MCP, "missing-client", "missing-tool", Map.of()); MetaAction metaAction = buildMetaAction(MetaAction.Type.MCP, "missing-client", "missing-tool", Map.of());
RunnerClient.RunnerResponse response = client.doRun(metaAction); RunnerClient.RunnerResponse response = client.doRun(metaAction);
Assertions.assertNotNull(response); Assertions.assertNotNull(response);
Assertions.assertFalse(response.isOk()); Assertions.assertFalse(response.isOk());
@@ -834,7 +835,7 @@ public class LocalRunnerClientTest {
RunnerClient client = new LocalRunnerClient(existedMetaActions, executor, tempDir.toString()); RunnerClient client = new LocalRunnerClient(existedMetaActions, executor, tempDir.toString());
try { try {
MetaAction metaAction = buildMetaAction(MetaActionType.MCP, "missing-client", "missing-tool", Map.of()); MetaAction metaAction = buildMetaAction(MetaAction.Type.MCP, "missing-client", "missing-tool", Map.of());
client.submit(metaAction); client.submit(metaAction);
Assertions.assertNotNull(metaAction.getResult().getData()); Assertions.assertNotNull(metaAction.getResult().getData());
} finally { } finally {
@@ -861,9 +862,9 @@ public class LocalRunnerClientTest {
waitForCondition(() -> hasActionKey(existedMetaActions, key -> key.startsWith("playwright::")), 20000); waitForCondition(() -> hasActionKey(existedMetaActions, key -> key.startsWith("playwright::")), 20000);
Assertions.assertTrue(hasActionKey(existedMetaActions, key -> key.startsWith("playwright::"))); Assertions.assertTrue(hasActionKey(existedMetaActions, key -> key.startsWith("playwright::")));
MetaAction metaAction = buildMetaAction(MetaActionType.MCP, "playwright", "browser_navigate", Map.of("url", "https://deepwiki.com/microsoft/vscode")); MetaAction metaAction = buildMetaAction(MetaAction.Type.MCP, "playwright", "browser_navigate", Map.of("url", "https://deepwiki.com/microsoft/vscode"));
client.submit(metaAction); client.submit(metaAction);
Assertions.assertNotEquals(MetaAction.ResultStatus.WAITING, metaAction.getResult().getStatus()); Assertions.assertNotEquals(MetaAction.Result.Status.WAITING, metaAction.getResult().getStatus());
} finally { } finally {
executor.shutdownNow(); executor.shutdownNow();
} }

View File

@@ -23,7 +23,7 @@ public class RunnerClientTest {
} }
@Override @Override
public String buildTmpPath(MetaAction tempAction, String codeType) { public String buildTmpPath(String actionKey, String codeType) {
return null; return null;
} }

View File

@@ -100,7 +100,7 @@ class ActionExecutorTest {
when(paramsExtractor.execute(any())).thenReturn(extractorResult); when(paramsExtractor.execute(any())).thenReturn(extractorResult);
doAnswer(inv -> { doAnswer(inv -> {
MetaAction metaAction = inv.getArgument(0); MetaAction metaAction = inv.getArgument(0);
metaAction.getResult().setStatus(MetaAction.ResultStatus.SUCCESS); metaAction.getResult().setStatus(MetaAction.Result.Status.SUCCESS);
return null; return null;
}).when(runnerClient).submit(any(MetaAction.class)); }).when(runnerClient).submit(any(MetaAction.class));
@@ -148,7 +148,7 @@ class ActionExecutorTest {
when(paramsExtractor.execute(any())).thenReturn(extractorResult); when(paramsExtractor.execute(any())).thenReturn(extractorResult);
doAnswer(inv -> { doAnswer(inv -> {
MetaAction metaAction = inv.getArgument(0); MetaAction metaAction = inv.getArgument(0);
metaAction.getResult().setStatus(MetaAction.ResultStatus.SUCCESS); metaAction.getResult().setStatus(MetaAction.Result.Status.SUCCESS);
log.info("metaAction result:{}", metaAction.getResult().getStatus()); log.info("metaAction result:{}", metaAction.getResult().getStatus());
return null; return null;
}).when(runnerClient).submit(any(MetaAction.class)); }).when(runnerClient).submit(any(MetaAction.class));
@@ -177,7 +177,7 @@ class ActionExecutorTest {
lenient().when(paramsExtractor.execute(any())).thenReturn(extractorResult); lenient().when(paramsExtractor.execute(any())).thenReturn(extractorResult);
lenient().doAnswer(inv -> { lenient().doAnswer(inv -> {
MetaAction metaAction = inv.getArgument(0); MetaAction metaAction = inv.getArgument(0);
metaAction.getResult().setStatus(MetaAction.ResultStatus.SUCCESS); metaAction.getResult().setStatus(MetaAction.Result.Status.SUCCESS);
return null; return null;
}).when(runnerClient).submit(any(MetaAction.class)); }).when(runnerClient).submit(any(MetaAction.class));
@@ -211,7 +211,7 @@ class ActionExecutorTest {
doAnswer(inv -> { doAnswer(inv -> {
MetaAction metaAction = inv.getArgument(0); MetaAction metaAction = inv.getArgument(0);
metaAction.getResult().setStatus(MetaAction.ResultStatus.SUCCESS); metaAction.getResult().setStatus(MetaAction.Result.Status.SUCCESS);
return null; return null;
}).when(runnerClient).submit(any(MetaAction.class)); }).when(runnerClient).submit(any(MetaAction.class));
@@ -252,7 +252,7 @@ class ActionExecutorTest {
} catch (InterruptedException ignored) { } catch (InterruptedException ignored) {
} }
MetaAction metaAction = actionData.getActionChain().get(0).get(0); MetaAction metaAction = actionData.getActionChain().get(0).get(0);
assertEquals(MetaAction.ResultStatus.FAILED, metaAction.getResult().getStatus()); assertEquals(MetaAction.Result.Status.FAILED, metaAction.getResult().getStatus());
verify(runnerClient, never()).submit(any(MetaAction.class)); verify(runnerClient, never()).submit(any(MetaAction.class));
} }
@@ -279,7 +279,7 @@ class ActionExecutorTest {
doAnswer(inv -> { doAnswer(inv -> {
MetaAction metaAction = inv.getArgument(0); MetaAction metaAction = inv.getArgument(0);
metaAction.getResult().setStatus(MetaAction.ResultStatus.SUCCESS); metaAction.getResult().setStatus(MetaAction.Result.Status.SUCCESS);
return null; return null;
}).when(runnerClient).submit(any(MetaAction.class)); }).when(runnerClient).submit(any(MetaAction.class));
@@ -326,7 +326,7 @@ class ActionExecutorTest {
lenient().when(paramsExtractor.execute(any())).thenReturn(ok); lenient().when(paramsExtractor.execute(any())).thenReturn(ok);
lenient().doAnswer(inv -> { lenient().doAnswer(inv -> {
MetaAction metaAction = inv.getArgument(0); MetaAction metaAction = inv.getArgument(0);
metaAction.getResult().setStatus(MetaAction.ResultStatus.SUCCESS); metaAction.getResult().setStatus(MetaAction.Result.Status.SUCCESS);
return null; return null;
}).when(runnerClient).submit(any(MetaAction.class)); }).when(runnerClient).submit(any(MetaAction.class));
@@ -392,11 +392,12 @@ class ActionExecutorTest {
} }
private MetaAction buildMetaAction(String name, boolean io) { private MetaAction buildMetaAction(String name, boolean io) {
MetaAction metaAction = new MetaAction(); return new MetaAction(
metaAction.setName(name); name,
metaAction.setLocation("loc"); io,
metaAction.setIo(io); MetaAction.Type.ORIGIN,
return metaAction; "location"
);
} }
private Map<Integer, List<String>> initAdditionalContext(Map<Integer, List<MetaAction>> actionChain) { private Map<Integer, List<String>> initAdditionalContext(Map<Integer, List<MetaAction>> actionChain) {