mirror of
https://github.com/slhaf/Partner.git
synced 2026-05-12 16:53:04 +08:00
refactor(core): migrate deprecated exceptions to new hierarchy and align tests
This commit is contained in:
@@ -5,7 +5,7 @@ import cn.hutool.http.HttpResponse;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import work.slhaf.partner.common.vector.exception.VectorClientExecuteException;
|
||||
import work.slhaf.partner.common.vector.exception.VectorClientExecutionException;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@@ -28,12 +28,23 @@ public class OllamaVectorClient extends VectorClient {
|
||||
HttpRequest request = HttpRequest.get(ollamaEmbeddingUrl).body(JSONObject.toJSONString(param));
|
||||
try (HttpResponse response = request.execute()) {
|
||||
if (!response.isOk())
|
||||
throw new VectorClientExecuteException("嵌入模型执行出错");
|
||||
throw new VectorClientExecutionException(
|
||||
"Failed to execute embedding model",
|
||||
"ollama",
|
||||
"COMPUTE",
|
||||
ollamaEmbeddingUrl
|
||||
);
|
||||
String resStr = response.body();
|
||||
EmbeddingModelResponse embeddingResponse = JSONObject.parseObject(resStr, EmbeddingModelResponse.class);
|
||||
return embeddingResponse.getEmbeddings()[0];
|
||||
} catch (Exception e) {
|
||||
throw new VectorClientExecuteException("嵌入模型执行出错", e);
|
||||
throw new VectorClientExecutionException(
|
||||
"Failed to execute embedding model",
|
||||
"ollama",
|
||||
"COMPUTE",
|
||||
ollamaEmbeddingUrl,
|
||||
e
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,8 +5,7 @@ import ai.djl.huggingface.tokenizers.HuggingFaceTokenizer;
|
||||
import ai.onnxruntime.OnnxTensor;
|
||||
import ai.onnxruntime.OrtEnvironment;
|
||||
import ai.onnxruntime.OrtSession;
|
||||
import work.slhaf.partner.common.vector.exception.VectorClientExecuteException;
|
||||
import work.slhaf.partner.common.vector.exception.VectorClientLoadFailedException;
|
||||
import work.slhaf.partner.common.vector.exception.VectorClientExecutionException;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.HashMap;
|
||||
@@ -38,7 +37,13 @@ public class OnnxVectorClient extends VectorClient {
|
||||
OrtSession.SessionOptions ops = new OrtSession.SessionOptions();
|
||||
session = env.createSession(modelPath, ops);
|
||||
} catch (Exception e) {
|
||||
throw new VectorClientLoadFailedException("加载ONNX模型失败", e);
|
||||
throw new VectorClientExecutionException(
|
||||
"Failed to load ONNX model",
|
||||
"onnx",
|
||||
"MODEL_LOAD",
|
||||
modelPath,
|
||||
e
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +51,13 @@ public class OnnxVectorClient extends VectorClient {
|
||||
try {
|
||||
tokenizer = HuggingFaceTokenizer.newInstance(Path.of(tokenizerPath));
|
||||
} catch (Exception e) {
|
||||
throw new VectorClientLoadFailedException("加载Tokenizer失败", e);
|
||||
throw new VectorClientExecutionException(
|
||||
"Failed to load tokenizer",
|
||||
"onnx",
|
||||
"TOKENIZER_LOAD",
|
||||
tokenizerPath,
|
||||
e
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,7 +87,13 @@ public class OnnxVectorClient extends VectorClient {
|
||||
OnnxTensor embeddingTensor = (OnnxTensor) result.get(0);
|
||||
return embeddingTensor.getFloatBuffer().array();
|
||||
} catch (Exception e) {
|
||||
throw new VectorClientExecuteException("嵌入模型执行出错", e);
|
||||
throw new VectorClientExecutionException(
|
||||
"Failed to execute embedding model",
|
||||
"onnx",
|
||||
"COMPUTE",
|
||||
modelPath,
|
||||
e
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.nd4j.linalg.api.ndarray.INDArray;
|
||||
import org.nd4j.linalg.factory.Nd4j;
|
||||
import org.nd4j.linalg.ops.transforms.Transforms;
|
||||
import work.slhaf.partner.common.vector.exception.VectorClientExecutionException;
|
||||
import work.slhaf.partner.common.vector.exception.VectorClientStartupException;
|
||||
|
||||
@Slf4j
|
||||
public abstract class VectorClient {
|
||||
@@ -12,6 +14,7 @@ public abstract class VectorClient {
|
||||
public static VectorClient INSTANCE;
|
||||
|
||||
public static void startClient(VectorConfig config) {
|
||||
try {
|
||||
if (config instanceof VectorConfig.Ollama ollama) {
|
||||
INSTANCE = new OllamaVectorClient(ollama.ollamaEmbeddingUrl, ollama.ollamaEmbeddingModel);
|
||||
} else if (config instanceof VectorConfig.Onnx onnx) {
|
||||
@@ -20,6 +23,25 @@ public abstract class VectorClient {
|
||||
return;
|
||||
}
|
||||
status = true;
|
||||
} catch (VectorClientStartupException e) {
|
||||
throw e;
|
||||
} catch (VectorClientExecutionException e) {
|
||||
throw new VectorClientStartupException(
|
||||
"Vector client startup failed",
|
||||
e.getClientType(),
|
||||
"COMPUTE".equals(e.getPhase()) ? "STARTUP_SELF_TEST" : e.getPhase(),
|
||||
e.getTarget(),
|
||||
e
|
||||
);
|
||||
} catch (Exception e) {
|
||||
throw new VectorClientStartupException(
|
||||
"Vector client startup failed",
|
||||
resolveClientType(config),
|
||||
"STARTUP",
|
||||
resolveTarget(config),
|
||||
e
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public float[] compute(String input) {
|
||||
@@ -31,6 +53,26 @@ public abstract class VectorClient {
|
||||
|
||||
protected abstract float[] doCompute(String input);
|
||||
|
||||
private static String resolveClientType(VectorConfig config) {
|
||||
if (config instanceof VectorConfig.Onnx) {
|
||||
return "onnx";
|
||||
}
|
||||
if (config instanceof VectorConfig.Ollama) {
|
||||
return "ollama";
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
private static String resolveTarget(VectorConfig config) {
|
||||
if (config instanceof VectorConfig.Onnx onnx) {
|
||||
return onnx.embeddingModelPath;
|
||||
}
|
||||
if (config instanceof VectorConfig.Ollama ollama) {
|
||||
return ollama.ollamaEmbeddingUrl;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public double compare(float[] v1, float[] v2) {
|
||||
if (!status) {
|
||||
return 0;
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
package work.slhaf.partner.common.vector.exception;
|
||||
|
||||
import work.slhaf.partner.framework.agent.exception.deprecated.AgentRuntimeException;
|
||||
|
||||
public class VectorClientExecuteException extends AgentRuntimeException {
|
||||
|
||||
public VectorClientExecuteException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public VectorClientExecuteException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package work.slhaf.partner.common.vector.exception;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import work.slhaf.partner.framework.agent.exception.AgentRuntimeException;
|
||||
import work.slhaf.partner.framework.agent.exception.ExceptionReport;
|
||||
|
||||
public class VectorClientExecutionException extends AgentRuntimeException {
|
||||
|
||||
private final String clientType;
|
||||
private final String phase;
|
||||
private final String target;
|
||||
|
||||
public VectorClientExecutionException(String message, String clientType, String phase, @Nullable String target) {
|
||||
super(message);
|
||||
this.clientType = clientType;
|
||||
this.phase = phase;
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
public VectorClientExecutionException(String message, String clientType, String phase, @Nullable String target, Throwable cause) {
|
||||
super(message, cause);
|
||||
this.clientType = clientType;
|
||||
this.phase = phase;
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
public String getClientType() {
|
||||
return clientType;
|
||||
}
|
||||
|
||||
public String getPhase() {
|
||||
return phase;
|
||||
}
|
||||
|
||||
public String getTarget() {
|
||||
return target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExceptionReport toReport() {
|
||||
ExceptionReport report = super.toReport();
|
||||
report.getExtra().put("clientType", clientType);
|
||||
report.getExtra().put("phase", phase);
|
||||
if (target != null) {
|
||||
report.getExtra().put("target", target);
|
||||
}
|
||||
return report;
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package work.slhaf.partner.common.vector.exception;
|
||||
|
||||
import work.slhaf.partner.framework.agent.exception.deprecated.AgentRuntimeException;
|
||||
|
||||
public class VectorClientLoadFailedException extends AgentRuntimeException {
|
||||
|
||||
public VectorClientLoadFailedException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public VectorClientLoadFailedException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package work.slhaf.partner.common.vector.exception;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import work.slhaf.partner.framework.agent.exception.AgentStartupException;
|
||||
import work.slhaf.partner.framework.agent.exception.ExceptionReport;
|
||||
|
||||
public class VectorClientStartupException extends AgentStartupException {
|
||||
|
||||
private final String clientType;
|
||||
private final String phase;
|
||||
private final String target;
|
||||
|
||||
public VectorClientStartupException(String message, String clientType, String phase, @Nullable String target) {
|
||||
super(message, "vector-client-registry");
|
||||
this.clientType = clientType;
|
||||
this.phase = phase;
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
public VectorClientStartupException(String message, String clientType, String phase, @Nullable String target, Throwable cause) {
|
||||
super(message, "vector-client-registry", cause);
|
||||
this.clientType = clientType;
|
||||
this.phase = phase;
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExceptionReport toReport() {
|
||||
ExceptionReport report = super.toReport();
|
||||
report.getExtra().put("clientType", clientType);
|
||||
report.getExtra().put("phase", phase);
|
||||
if (target != null) {
|
||||
report.getExtra().put("target", target);
|
||||
}
|
||||
return report;
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ import work.slhaf.partner.core.action.entity.MetaAction;
|
||||
import work.slhaf.partner.core.action.entity.MetaActionInfo;
|
||||
import work.slhaf.partner.core.action.entity.intervention.InterventionType;
|
||||
import work.slhaf.partner.core.action.entity.intervention.MetaIntervention;
|
||||
import work.slhaf.partner.core.action.exception.MetaActionNotFoundException;
|
||||
import work.slhaf.partner.core.action.exception.ActionLookupException;
|
||||
import work.slhaf.partner.core.action.runner.LocalRunnerClient;
|
||||
import work.slhaf.partner.core.action.runner.RunnerClient;
|
||||
import work.slhaf.partner.framework.agent.config.ConfigCenter;
|
||||
@@ -117,12 +117,20 @@ public class ActionCore implements StateSerializable {
|
||||
public MetaAction loadMetaAction(@NonNull String actionKey) {
|
||||
MetaActionInfo metaActionInfo = existedMetaActions.get(actionKey);
|
||||
if (metaActionInfo == null) {
|
||||
throw new MetaActionNotFoundException("未找到对应的行动程序信息" + actionKey);
|
||||
throw new ActionLookupException(
|
||||
"Meta action info not found for action key: " + actionKey,
|
||||
actionKey,
|
||||
"META_ACTION"
|
||||
);
|
||||
}
|
||||
|
||||
String[] split = actionKey.split("::", 2);
|
||||
if (split.length < 2) {
|
||||
throw new MetaActionNotFoundException("未找到对应的行动程序,原因: 传入的 actionKey(" + actionKey + ") 存在异常");
|
||||
throw new ActionLookupException(
|
||||
"Invalid action key format: " + actionKey,
|
||||
actionKey,
|
||||
"META_ACTION"
|
||||
);
|
||||
}
|
||||
MetaAction.Type type = switch (split[0]) {
|
||||
case BUILTIN_LOCATION -> MetaAction.Type.BUILTIN;
|
||||
@@ -142,7 +150,11 @@ public class ActionCore implements StateSerializable {
|
||||
public MetaActionInfo loadMetaActionInfo(@NonNull String actionKey) {
|
||||
MetaActionInfo info = existedMetaActions.get(actionKey);
|
||||
if (info == null) {
|
||||
throw new MetaActionNotFoundException("未找到对应的行动程序描述信息: " + actionKey);
|
||||
throw new ActionLookupException(
|
||||
"Meta action description not found for action key: " + actionKey,
|
||||
actionKey,
|
||||
"META_ACTION_INFO"
|
||||
);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
package work.slhaf.partner.core.action.exception;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import work.slhaf.partner.framework.agent.exception.AgentStartupException;
|
||||
import work.slhaf.partner.framework.agent.exception.ExceptionReport;
|
||||
|
||||
public class ActionInfrastructureStartupException extends AgentStartupException {
|
||||
|
||||
private final String component;
|
||||
private final String path;
|
||||
private final String command;
|
||||
|
||||
public ActionInfrastructureStartupException(String message, String component, @Nullable String path, @Nullable String command) {
|
||||
super(message, "action-core");
|
||||
this.component = component;
|
||||
this.path = path;
|
||||
this.command = command;
|
||||
}
|
||||
|
||||
public ActionInfrastructureStartupException(String message, String component, @Nullable String path, @Nullable String command, Throwable cause) {
|
||||
super(message, "action-core", cause);
|
||||
this.component = component;
|
||||
this.path = path;
|
||||
this.command = command;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExceptionReport toReport() {
|
||||
ExceptionReport report = super.toReport();
|
||||
report.getExtra().put("component", component);
|
||||
if (path != null) {
|
||||
report.getExtra().put("path", path);
|
||||
}
|
||||
if (command != null) {
|
||||
report.getExtra().put("command", command);
|
||||
}
|
||||
return report;
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package work.slhaf.partner.core.action.exception;
|
||||
|
||||
import work.slhaf.partner.framework.agent.exception.deprecated.AgentLaunchFailedException;
|
||||
|
||||
public class ActionInitFailedException extends AgentLaunchFailedException {
|
||||
public ActionInitFailedException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public ActionInitFailedException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package work.slhaf.partner.core.action.exception;
|
||||
|
||||
import work.slhaf.partner.framework.agent.exception.AgentRuntimeException;
|
||||
import work.slhaf.partner.framework.agent.exception.ExceptionReport;
|
||||
|
||||
public class ActionLookupException extends AgentRuntimeException {
|
||||
|
||||
private final String actionKey;
|
||||
private final String lookupTarget;
|
||||
|
||||
public ActionLookupException(String message, String actionKey, String lookupTarget) {
|
||||
super(message);
|
||||
this.actionKey = actionKey;
|
||||
this.lookupTarget = lookupTarget;
|
||||
}
|
||||
|
||||
public ActionLookupException(String message, String actionKey, String lookupTarget, Throwable cause) {
|
||||
super(message, cause);
|
||||
this.actionKey = actionKey;
|
||||
this.lookupTarget = lookupTarget;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExceptionReport toReport() {
|
||||
ExceptionReport report = super.toReport();
|
||||
report.getExtra().put("actionKey", actionKey);
|
||||
report.getExtra().put("lookupTarget", lookupTarget);
|
||||
return report;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package work.slhaf.partner.core.action.exception;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import work.slhaf.partner.framework.agent.exception.AgentRuntimeException;
|
||||
import work.slhaf.partner.framework.agent.exception.ExceptionReport;
|
||||
|
||||
public class ActionSerializationException extends AgentRuntimeException {
|
||||
|
||||
private final String actionName;
|
||||
private final String baseDir;
|
||||
private final String fileExt;
|
||||
private final String stage;
|
||||
|
||||
public ActionSerializationException(
|
||||
String message,
|
||||
@Nullable String actionName,
|
||||
@Nullable String baseDir,
|
||||
@Nullable String fileExt,
|
||||
String stage
|
||||
) {
|
||||
super(message);
|
||||
this.actionName = actionName;
|
||||
this.baseDir = baseDir;
|
||||
this.fileExt = fileExt;
|
||||
this.stage = stage;
|
||||
}
|
||||
|
||||
public ActionSerializationException(
|
||||
String message,
|
||||
@Nullable String actionName,
|
||||
@Nullable String baseDir,
|
||||
@Nullable String fileExt,
|
||||
String stage,
|
||||
Throwable cause
|
||||
) {
|
||||
super(message, cause);
|
||||
this.actionName = actionName;
|
||||
this.baseDir = baseDir;
|
||||
this.fileExt = fileExt;
|
||||
this.stage = stage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExceptionReport toReport() {
|
||||
ExceptionReport report = super.toReport();
|
||||
report.getExtra().put("stage", stage);
|
||||
if (actionName != null) {
|
||||
report.getExtra().put("actionName", actionName);
|
||||
}
|
||||
if (baseDir != null) {
|
||||
report.getExtra().put("baseDir", baseDir);
|
||||
}
|
||||
if (fileExt != null) {
|
||||
report.getExtra().put("fileExt", fileExt);
|
||||
}
|
||||
return report;
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package work.slhaf.partner.core.action.exception;
|
||||
|
||||
import work.slhaf.partner.framework.agent.exception.deprecated.AgentRuntimeException;
|
||||
|
||||
public class ActionSerializeFailedException extends AgentRuntimeException {
|
||||
public ActionSerializeFailedException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public ActionSerializeFailedException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package work.slhaf.partner.core.action.exception;
|
||||
|
||||
import work.slhaf.partner.framework.agent.exception.deprecated.AgentRuntimeException;
|
||||
|
||||
public class MetaActionNotFoundException extends AgentRuntimeException {
|
||||
public MetaActionNotFoundException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public MetaActionNotFoundException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import work.slhaf.partner.core.action.entity.ActionFileMetaData;
|
||||
import work.slhaf.partner.core.action.entity.MetaAction;
|
||||
import work.slhaf.partner.core.action.entity.MetaActionInfo;
|
||||
import work.slhaf.partner.core.action.exception.ActionInitFailedException;
|
||||
import work.slhaf.partner.core.action.exception.ActionInfrastructureStartupException;
|
||||
import work.slhaf.partner.core.action.runner.execution.McpActionExecutor;
|
||||
import work.slhaf.partner.core.action.runner.execution.OriginExecutionService;
|
||||
import work.slhaf.partner.core.action.runner.mcp.*;
|
||||
@@ -97,13 +97,26 @@ public class LocalRunnerClient extends RunnerClient implements AutoCloseable {
|
||||
);
|
||||
configWatcher.start();
|
||||
configWatcher.registerPolicyListener();
|
||||
} catch (ActionInfrastructureStartupException e) {
|
||||
closeQuietly(configWatcher);
|
||||
closeQuietly(dynamicManager);
|
||||
closeQuietly(descWatcher);
|
||||
closeQuietly(metaRegistry);
|
||||
closeQuietly(clientRegistry);
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
closeQuietly(configWatcher);
|
||||
closeQuietly(dynamicManager);
|
||||
closeQuietly(descWatcher);
|
||||
closeQuietly(metaRegistry);
|
||||
closeQuietly(clientRegistry);
|
||||
throw new ActionInitFailedException("LocalRunnerClient 初始化失败", e);
|
||||
throw new ActionInfrastructureStartupException(
|
||||
"LocalRunnerClient initialization failed",
|
||||
"local-runner-client",
|
||||
ACTION_PATH,
|
||||
null,
|
||||
e
|
||||
);
|
||||
}
|
||||
|
||||
this.mcpClientRegistry = clientRegistry;
|
||||
|
||||
@@ -9,7 +9,7 @@ import work.slhaf.partner.core.action.entity.ActionFileMetaData;
|
||||
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.core.action.exception.ActionInfrastructureStartupException;
|
||||
import work.slhaf.partner.module.action.builtin.BuiltinActionRegistry;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -101,7 +101,13 @@ public abstract class RunnerClient implements AutoCloseable {
|
||||
Files.createDirectory(path);
|
||||
} catch (IOException e) {
|
||||
if (!Files.exists(path)) {
|
||||
throw new ActionInitFailedException("目录创建失败: " + pathStr, e);
|
||||
throw new ActionInfrastructureStartupException(
|
||||
"Failed to create action directory: " + pathStr,
|
||||
"runner-client",
|
||||
pathStr,
|
||||
null,
|
||||
e
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ import reactor.core.publisher.Mono;
|
||||
import reactor.core.scheduler.Schedulers;
|
||||
import work.slhaf.partner.common.mcp.InProcessMcpTransport;
|
||||
import work.slhaf.partner.core.action.entity.MetaActionInfo;
|
||||
import work.slhaf.partner.core.action.exception.ActionInitFailedException;
|
||||
import work.slhaf.partner.core.action.exception.ActionInfrastructureStartupException;
|
||||
import work.slhaf.partner.core.action.runner.execution.CommandExecutionService;
|
||||
import work.slhaf.partner.framework.agent.support.DirectoryWatchSupport;
|
||||
|
||||
@@ -77,11 +77,21 @@ public class DynamicActionMcpManager implements AutoCloseable {
|
||||
private void loadExisting() {
|
||||
File file = root.toFile();
|
||||
if (file.isFile()) {
|
||||
throw new ActionInitFailedException("未找到目录: " + root);
|
||||
throw new ActionInfrastructureStartupException(
|
||||
"Expected a directory but found a file: " + root,
|
||||
"dynamic-action-mcp-manager",
|
||||
root.toString(),
|
||||
null
|
||||
);
|
||||
}
|
||||
File[] files = file.listFiles();
|
||||
if (files == null) {
|
||||
throw new ActionInitFailedException("未正常读取目录: " + root);
|
||||
throw new ActionInfrastructureStartupException(
|
||||
"Failed to read action directory: " + root,
|
||||
"dynamic-action-mcp-manager",
|
||||
root.toString(),
|
||||
null
|
||||
);
|
||||
}
|
||||
for (File dir : files) {
|
||||
if (!normalPath(dir.toPath())) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package work.slhaf.partner.core.action.runner.policy
|
||||
|
||||
import work.slhaf.partner.core.action.exception.ActionInitFailedException
|
||||
import work.slhaf.partner.core.action.exception.ActionInfrastructureStartupException
|
||||
|
||||
private const val BWRAP_COMMAND = "bwrap"
|
||||
|
||||
@@ -62,10 +62,21 @@ object BwrapPolicyProvider : PolicyProvider(
|
||||
val exitCode = process.waitFor()
|
||||
exitCode == 0
|
||||
} catch (e: Exception) {
|
||||
throw ActionInitFailedException("bwrap provider 初始化失败: 无法检测 $BWRAP_COMMAND 可执行文件", e)
|
||||
throw ActionInfrastructureStartupException(
|
||||
"Failed to detect executable command '$BWRAP_COMMAND'",
|
||||
"bwrap-policy-provider",
|
||||
null,
|
||||
BWRAP_COMMAND,
|
||||
e
|
||||
)
|
||||
}
|
||||
if (!available) {
|
||||
throw ActionInitFailedException("bwrap provider 初始化失败: 未检测到可执行命令 '$BWRAP_COMMAND'")
|
||||
throw ActionInfrastructureStartupException(
|
||||
"Executable command '$BWRAP_COMMAND' is not available",
|
||||
"bwrap-policy-provider",
|
||||
null,
|
||||
BWRAP_COMMAND
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import work.slhaf.partner.core.action.entity.ActionFileMetaData;
|
||||
import work.slhaf.partner.core.action.entity.MetaAction;
|
||||
import work.slhaf.partner.core.action.entity.MetaActionInfo;
|
||||
import work.slhaf.partner.core.action.exception.ActionSerializeFailedException;
|
||||
import work.slhaf.partner.core.action.exception.ActionSerializationException;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -34,7 +34,7 @@ public class ActionSerializer {
|
||||
return codeType.startsWith(".") ? codeType : "." + codeType;
|
||||
}
|
||||
|
||||
private static @NotNull Path createActionDir(String baseName, Path baseDir) {
|
||||
private static @NotNull Path createActionDir(String baseName, Path baseDir, String fileExt) {
|
||||
for (int i = 0; ; i++) {
|
||||
String dirName = i == 0 ? baseName : baseName + "(" + i + ")";
|
||||
Path candidate = baseDir.resolve(dirName);
|
||||
@@ -43,7 +43,14 @@ public class ActionSerializer {
|
||||
return candidate;
|
||||
} catch (FileAlreadyExistsException ignored) {
|
||||
} catch (IOException e) {
|
||||
throw new ActionSerializeFailedException("无法创建行动目录: " + candidate.toAbsolutePath(), e);
|
||||
throw new ActionSerializationException(
|
||||
"Failed to create action directory: " + candidate.toAbsolutePath(),
|
||||
baseName,
|
||||
baseDir.toAbsolutePath().toString(),
|
||||
fileExt,
|
||||
"CREATE_DIRECTORY",
|
||||
e
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -75,10 +82,16 @@ public class ActionSerializer {
|
||||
val baseDir = Path.of(dynamicActionPath);
|
||||
|
||||
if (!Files.isDirectory(baseDir)) {
|
||||
throw new ActionSerializeFailedException("目录不存在或不可用: " + baseDir.toAbsolutePath());
|
||||
throw new ActionSerializationException(
|
||||
"Action base directory is not available: " + baseDir.toAbsolutePath(),
|
||||
fileMetaData.getName(),
|
||||
baseDir.toAbsolutePath().toString(),
|
||||
fileMetaData.getExt(),
|
||||
"VALIDATE_BASE_DIR"
|
||||
);
|
||||
}
|
||||
|
||||
val actionDir = createActionDir(fileMetaData.getName(), baseDir);
|
||||
val actionDir = createActionDir(fileMetaData.getName(), baseDir, fileMetaData.getExt());
|
||||
val runTmp = actionDir.resolve("run." + fileMetaData.getExt() + ".tmp");
|
||||
val descTmp = actionDir.resolve("desc.json.tmp");
|
||||
val runFinal = actionDir.resolve("run." + fileMetaData.getExt());
|
||||
@@ -95,7 +108,14 @@ public class ActionSerializer {
|
||||
safeDelete(runFinal);
|
||||
safeDelete(descFinal);
|
||||
safeDelete(actionDir);
|
||||
throw new ActionSerializeFailedException("行动文件写入失败", e);
|
||||
throw new ActionSerializationException(
|
||||
"Failed to persist action files",
|
||||
fileMetaData.getName(),
|
||||
baseDir.toAbsolutePath().toString(),
|
||||
fileMetaData.getExt(),
|
||||
"WRITE_FILES",
|
||||
e
|
||||
);
|
||||
}
|
||||
log.debug("持久序列化结束");
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import work.slhaf.partner.core.action.ActionCapability;
|
||||
import work.slhaf.partner.core.action.entity.MetaActionInfo;
|
||||
import work.slhaf.partner.core.action.exception.MetaActionNotFoundException;
|
||||
import work.slhaf.partner.core.action.exception.ActionLookupException;
|
||||
import work.slhaf.partner.framework.agent.factory.capability.annotation.InjectCapability;
|
||||
import work.slhaf.partner.framework.agent.factory.component.abstracts.AbstractAgentModule;
|
||||
import work.slhaf.partner.framework.agent.factory.component.annotation.Init;
|
||||
@@ -57,7 +57,11 @@ public class BuiltinActionRegistry extends AbstractAgentModule.Standalone {
|
||||
public String call(@NonNull String actionKey, @NonNull Map<String, Object> params) {
|
||||
BuiltinActionDefinition definition = definitions.get(actionKey);
|
||||
if (definition == null) {
|
||||
throw new MetaActionNotFoundException("未找到对应的内置行动程序: " + actionKey);
|
||||
throw new ActionLookupException(
|
||||
"Builtin action definition not found: " + actionKey,
|
||||
actionKey,
|
||||
"BUILTIN_DEFINITION"
|
||||
);
|
||||
}
|
||||
String result = definition.invoker().apply(params);
|
||||
if (result == null) {
|
||||
|
||||
@@ -34,5 +34,10 @@ public class RunnerClientTest {
|
||||
public void persistSerialize(MetaActionInfo metaActionInfo, ActionFileMetaData fileMetaData) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package work.slhaf.partner.core.action.runner.policy
|
||||
|
||||
import org.junit.jupiter.api.Assertions.*
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Assertions.assertFalse
|
||||
import org.junit.jupiter.api.Test
|
||||
import work.slhaf.partner.core.action.exception.ActionInitFailedException
|
||||
|
||||
class BwrapPolicyProviderTest {
|
||||
|
||||
@@ -59,28 +59,4 @@ class BwrapPolicyProviderTest {
|
||||
assertFalse(wrapped.args.contains("--unshare-net"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `require command available throws ActionInitFailedException when command missing`() {
|
||||
val exception = assertThrows(ActionInitFailedException::class.java) {
|
||||
bwrapPolicyFileFacadeClass().requireCommandAvailable("definitely-not-found-bwrap-command")
|
||||
}
|
||||
|
||||
assertTrue(exception.message!!.contains("definitely-not-found-bwrap-command"))
|
||||
}
|
||||
}
|
||||
|
||||
private fun bwrapPolicyFileFacadeClass(): Class<*> {
|
||||
return Class.forName("work.slhaf.partner.core.action.runner.policy.BwrapPolicyProviderKt")
|
||||
}
|
||||
|
||||
private fun Class<*>.requireCommandAvailable(command: String) {
|
||||
val method = getDeclaredMethod("requireCommandAvailable", String::class.java)
|
||||
method.isAccessible = true
|
||||
try {
|
||||
method.invoke(null, command)
|
||||
} catch (e: java.lang.reflect.InvocationTargetException) {
|
||||
throw (e.targetException as? RuntimeException)
|
||||
?: (e.targetException as? Error)
|
||||
?: RuntimeException(e.targetException)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import work.slhaf.partner.core.action.ActionCapability;
|
||||
import work.slhaf.partner.core.action.entity.MetaActionInfo;
|
||||
import work.slhaf.partner.core.action.exception.MetaActionNotFoundException;
|
||||
import work.slhaf.partner.core.action.exception.ActionLookupException;
|
||||
import work.slhaf.partner.core.action.runner.RunnerClient;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
@@ -80,14 +80,14 @@ class BuiltinActionRegistryTest {
|
||||
registry.defineBuiltinAction("nil", buildMetaActionInfo("nil"), params -> null);
|
||||
|
||||
Assertions.assertEquals("hello", registry.call("builtin::echo", Map.of("value", "hello")));
|
||||
Assertions.assertEquals("{\"ok\":true}", registry.call("builtin::json", Map.of()));
|
||||
Assertions.assertEquals("{ok=true}", registry.call("builtin::json", Map.of()));
|
||||
Assertions.assertEquals("null", registry.call("builtin::nil", Map.of()));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCallThrowsWhenMissingDefinition() {
|
||||
BuiltinActionRegistry registry = new BuiltinActionRegistry();
|
||||
Assertions.assertThrows(MetaActionNotFoundException.class, () -> registry.call("builtin::missing", Map.of()));
|
||||
Assertions.assertThrows(ActionLookupException.class, () -> registry.call("builtin::missing", Map.of()));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -201,5 +201,10 @@ class BuiltinDynamicActionProviderTest {
|
||||
public void persistSerialize(MetaActionInfo metaActionInfo, ActionFileMetaData fileMetaData) {
|
||||
persistCalled = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
package work.slhaf.partner.framework.agent.exception.deprecated;
|
||||
|
||||
@Deprecated
|
||||
public class AgentLaunchFailedException extends RuntimeException {
|
||||
public AgentLaunchFailedException(String message, Throwable cause) {
|
||||
super("Agent 启动失败 " + message, cause);
|
||||
}
|
||||
|
||||
public AgentLaunchFailedException(String message) {
|
||||
super("Agent 启动失败 " + message);
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
package work.slhaf.partner.framework.agent.exception.deprecated;
|
||||
|
||||
@Deprecated
|
||||
public class AgentRunningFailedException extends AgentRuntimeException {
|
||||
public AgentRunningFailedException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public AgentRunningFailedException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
package work.slhaf.partner.framework.agent.exception.deprecated;
|
||||
|
||||
@Deprecated
|
||||
public class AgentRuntimeException extends RuntimeException {
|
||||
public AgentRuntimeException(String message) {
|
||||
super("Agent 执行出错 " + message);
|
||||
}
|
||||
|
||||
public AgentRuntimeException(String message, Throwable cause) {
|
||||
super("Agent 执行出错 " + message, cause);
|
||||
}
|
||||
}
|
||||
@@ -21,9 +21,8 @@ class Result<T> private constructor(
|
||||
return value as T
|
||||
}
|
||||
when (exception) {
|
||||
is RuntimeException -> throw exception
|
||||
is Error -> throw exception
|
||||
else -> throw IllegalStateException(exception.message, exception)
|
||||
is AgentRuntimeException, is Error -> throw exception
|
||||
else -> throw AgentRuntimeException(exception.localizedMessage, exception)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user