refactor(RunnerClient): restructure serialization and temp execution paths

Context:
Following the consolidation of action types into ORIGIN and MCP,
the serialization logic needs to be separated into dedicated methods.
These methods are invoked by DynamicActionGenerator.
This commit is contained in:
2025-12-16 10:47:23 +08:00
parent 628234f6e2
commit bf2d5ac707
6 changed files with 55 additions and 83 deletions

View File

@@ -6,7 +6,7 @@ public final class Constant {
public static final String DATA = "./data"; public static final String DATA = "./data";
public static final String MEMORY_DATA = DATA + "/memory"; public static final String MEMORY_DATA = DATA + "/memory";
public static final String ACTION_PROGRAM = DATA + "/action"; public static final String ACTION_PROGRAM = DATA + "/action";
public static final String TMP_ACTION_DIR_LOCAL = DATA + "/tmp"; public static final String TMP_ACTION_DIR_LOCAL = ACTION_PROGRAM + "/tmp";
} }
} }

View File

@@ -0,0 +1,5 @@
package work.slhaf.partner.core.action.entity;
public class McpData {
}

View File

@@ -5,6 +5,8 @@ import com.alibaba.fastjson2.JSONObject;
import lombok.Data; import lombok.Data;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import work.slhaf.partner.core.action.entity.McpData;
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.entity.MetaActionType;
@@ -52,37 +54,36 @@ public class LocalRunnerClient extends RunnerClient {
return response; return response;
} }
private RunnerResponse doRunWithOrigin(MetaAction metaAction) {
RunnerResponse response = new RunnerResponse();
return response;
}
private RunnerResponse doRunWithMcp(MetaAction metaAction) { private RunnerResponse doRunWithMcp(MetaAction metaAction) {
RunnerResponse response = new RunnerResponse(); RunnerResponse response = new RunnerResponse();
return response; return response;
} }
private RunnerResponse doRunWithPlugin(MetaAction metaAction) {
RunnerResponse response = new RunnerResponse();
return response;
}
private RunnerResponse doRunWithScript(MetaAction metaAction) {
RunnerResponse response = new RunnerResponse();
return response;
}
@Override @Override
protected Path doBuildTempPath(MetaAction tempAction, String codeType) { public Path buildTmpPath(MetaAction tempAction, String codeType) {
return Path.of(TMP_ACTION_DIR_LOCAL, System.currentTimeMillis() + "-" + tempAction.getKey() + codeType); return Path.of(TMP_ACTION_DIR_LOCAL, System.currentTimeMillis() + "-" + tempAction.getKey() + codeType);
} }
@Override @Override
protected void doSerialize(MetaAction tempAction, String code, String codeType) throws IOException { public void tmpSerialize(MetaAction tempAction, String code, String codeType) throws IOException {
Path path = tempAction.getPath(); Path path = tempAction.getPath();
File file = path.toFile(); File file = path.toFile();
file.createNewFile(); file.createNewFile();
Files.writeString(path, code); Files.writeString(path, code);
} }
@Override
public void persistSerialize(MetaActionInfo metaActionInfo, McpData mcpData) {
throw new UnsupportedOperationException("Unimplemented method 'doPersistSerialize'");
}
@Override @Override
public JSONObject listSysDependencies() { public JSONObject listSysDependencies() {
// 先只列出系统/环境的 Python 依赖 // 先只列出系统/环境的 Python 依赖
@@ -252,7 +253,7 @@ public class LocalRunnerClient extends RunnerClient {
} }
private void handleParentDirEvent(WatchEvent.Kind<Path> kind, Path thisDir, Path context, private void handleParentDirEvent(WatchEvent.Kind<Path> kind, Path thisDir, Path context,
WatchService watchService) { WatchService watchService) {
Path path = Path.of(thisDir.toString(), context.toString()); Path path = Path.of(thisDir.toString(), context.toString());
// MODIFY 事件不进行处理 // MODIFY 事件不进行处理
if (kind == StandardWatchEventKinds.ENTRY_CREATE) { if (kind == StandardWatchEventKinds.ENTRY_CREATE) {
@@ -316,4 +317,5 @@ public class LocalRunnerClient extends RunnerClient {
} }
} }
} }

View File

@@ -3,7 +3,7 @@ package work.slhaf.partner.core.action.runner;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import lombok.Data; import lombok.Data;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import work.slhaf.partner.core.action.entity.GeneratedData; import work.slhaf.partner.core.action.entity.McpData;
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.MetaAction.ResultStatus;
@@ -42,58 +42,13 @@ public abstract class RunnerClient {
result.setStatus(response.isOk() ? ResultStatus.SUCCESS : ResultStatus.FAILED); result.setStatus(response.isOk() ? ResultStatus.SUCCESS : ResultStatus.FAILED);
} }
//TODO 将执行划分为 MCP、OriginalScript两种类型SCRIPT、PLUGIN、MCP的分类不再必要
protected abstract RunnerResponse doRun(MetaAction metaAction); protected abstract RunnerResponse doRun(MetaAction metaAction);
/** public abstract Path buildTmpPath(MetaAction tempAction, String codeType);
* 将临时行动程序放入等待队列,根据其是否需要持久序列化,监听其执行状态,执行成功则持久序列化
*
* @throws IOException
*/
public Path getPathAndSerialize(MetaAction tempAction, GeneratedData generatedData) throws IOException {
String code = generatedData.getCode();
String codeType = generatedData.getCodeType();
Path path = doBuildTempPath(tempAction, codeType); public abstract void tmpSerialize(MetaAction tempAction, String code, String codeType) throws IOException;
tempAction.setPath(path);
doSerialize(tempAction, code, codeType);
if (generatedData.isSerialize()) {
waitingSerialize(tempAction, code, codeType, generatedData.getResponseSchema());
}
return path;
}
private void waitingSerialize(MetaAction tempAction, String code, String codeType, JSONObject jsonObject) { public abstract void persistSerialize(MetaActionInfo metaActionInfo, McpData mcpData);
executor.execute(() -> {
Result result = tempAction.getResult();
while (true) {
switch (result.getStatus()) {
case ResultStatus.WAITING -> {
try {
Thread.sleep(300);
} catch (InterruptedException ignored) {
}
}
case ResultStatus.FAILED -> {
break;
}
case ResultStatus.SUCCESS -> {
tempAction.resetPath();
try {
doSerialize(tempAction, code, codeType);
} catch (IOException e) {
log.error("行动程序序列化出错: {}", tempAction.getKey(), e);
}
}
}
}
});
}
protected abstract Path doBuildTempPath(MetaAction tempAction, String codeType);
protected abstract void doSerialize(MetaAction tempAction, String code, String codeType) throws IOException;
/** /**
* 列出执行环境下的系统依赖情况 * 列出执行环境下的系统依赖情况
@@ -105,4 +60,4 @@ public abstract class RunnerClient {
private boolean ok; private boolean ok;
private String data; private String data;
} }
} }

View File

@@ -1,9 +1,12 @@
package work.slhaf.partner.core.action.runner; package work.slhaf.partner.core.action.runner;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import work.slhaf.partner.core.action.entity.McpData;
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 java.io.IOException;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
@@ -24,18 +27,6 @@ import java.util.concurrent.ExecutorService;
*/ */
public class SandboxRunnerClient extends RunnerClient { public class SandboxRunnerClient extends RunnerClient {
@Override
protected Path doBuildTempPath(MetaAction tempAction, String codeType) {
// TODO Auto-generated method stub
return null;
}
@Override
protected void doSerialize(MetaAction tempAction, String code, String codeType) {
// TODO Auto-generated method stub
}
public SandboxRunnerClient(Map<String, MetaActionInfo> existedMetaActions, ExecutorService executor) { // 连接沙盒执行器(websocket) public SandboxRunnerClient(Map<String, MetaActionInfo> existedMetaActions, ExecutorService executor) { // 连接沙盒执行器(websocket)
super(existedMetaActions, executor); super(existedMetaActions, executor);
} }
@@ -47,8 +38,22 @@ public class SandboxRunnerClient extends RunnerClient {
@Override @Override
public JSONObject listSysDependencies() { public JSONObject listSysDependencies() {
// TODO Auto-generated method stub
return null; return null;
} }
@Override
public Path buildTmpPath(MetaAction tempAction, String codeType) {
throw new UnsupportedOperationException("Unimplemented method 'buildTmpPath'");
}
@Override
public void tmpSerialize(MetaAction tempAction, String code, String codeType) throws IOException {
throw new UnsupportedOperationException("Unimplemented method 'tmpSerialize'");
}
@Override
public void persistSerialize(MetaActionInfo metaActionInfo, McpData mcpData) {
throw new UnsupportedOperationException("Unimplemented method 'persistSerialize'");
}
} }

View File

@@ -16,8 +16,6 @@ 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;
import java.nio.file.Path;
/** /**
* 负责依据输入内容生成可执行的动态行动单元,并选择是否持久化至 SandboxRunner 容器内 * 负责依据输入内容生成可执行的动态行动单元,并选择是否持久化至 SandboxRunner 容器内
*/ */
@@ -50,8 +48,11 @@ public class DynamicActionGenerator extends AgentRunningSubModule<GeneratorInput
// 将临时行动单元序列化至临时文件夹,并设置程序路径、放置在队列中,等待执行状态变化,并根据序列化选项选择是否补充 MetaActionInfo 并持久序列化 // 将临时行动单元序列化至临时文件夹,并设置程序路径、放置在队列中,等待执行状态变化,并根据序列化选项选择是否补充 MetaActionInfo 并持久序列化
// 通过 ActionCapability 暴露的接口序列化至临时文件夹同时返回Path对象并设置。队列建议交给 SandboxRunner // 通过 ActionCapability 暴露的接口序列化至临时文件夹同时返回Path对象并设置。队列建议交给 SandboxRunner
// 持有,包括监听与序列化线程 // 持有,包括监听与序列化线程
Path path = runnerClient.getPathAndSerialize(tempAction, generatorData); tempAction.setPath(runnerClient.buildTmpPath(tempAction, generatorData.getCodeType()));
tempAction.setPath(path); runnerClient.tmpSerialize(tempAction, generatorData.getCode(), generatorData.getCodeType());
if (generatorData.isSerialize()) {
waitingSerialize();
}
result.setTempAction(tempAction); result.setTempAction(tempAction);
} catch (Exception e) { } catch (Exception e) {
result.setTempAction(null); result.setTempAction(null);
@@ -59,6 +60,10 @@ public class DynamicActionGenerator extends AgentRunningSubModule<GeneratorInput
return result; return result;
} }
private void waitingSerialize() {
throw new UnsupportedOperationException("Unimplemented method 'waitingSerialize'");
}
private MetaAction buildAction(GeneratorInput input) { private MetaAction buildAction(GeneratorInput input) {
MetaAction tempAction = new MetaAction(); MetaAction tempAction = new MetaAction();
tempAction.setKey(input.getKey()); tempAction.setKey(input.getKey());