diff --git a/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/MetaAction.java b/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/MetaAction.java index 78c95c2c..c1935052 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/MetaAction.java +++ b/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/MetaAction.java @@ -1,12 +1,14 @@ package work.slhaf.partner.core.action.entity; -import lombok.Data; -import org.jetbrains.annotations.NotNull; +import static work.slhaf.partner.common.Constant.Path.ACTION_PROGRAM; import java.io.File; import java.nio.file.Path; +import java.util.Map; -import static work.slhaf.partner.common.Constant.Path.ACTION_PROGRAM; +import org.jetbrains.annotations.NotNull; + +import lombok.Data; /** * 行动链中的单一元素,封装了调用外部行动程序的必要信息与结果容器,可被{@link work.slhaf.partner.core.action.ActionCapability}执行 @@ -21,7 +23,7 @@ public class MetaAction implements Comparable { /** * 行动程序可接受的参数,由调用处设置 */ - private String[] params; + private Map params; /** * 行动结果,包括执行状态和相应内容(执行结果或者错误信息) */ @@ -36,18 +38,21 @@ public class MetaAction implements Comparable { private boolean io; /** * 行动程序类型,可分为PLUGIN(jar文件)、SCRIPT(Python程序)、MCP(MCP服务) + * . */ private MetaActionType type; + private Path path; + public Path checkAndGetPath() { - Path path = switch (type) { + path = switch (type) { case PLUGIN -> Path.of(ACTION_PROGRAM, key, "action.jar"); case SCRIPT -> Path.of(ACTION_PROGRAM, key, "action.py"); case MCP -> Path.of(ACTION_PROGRAM, key, "action.json"); }; File action = path.toFile(); if (!action.exists()) { - result.setSuccess(false); + result.setStatus(ResultStatus.FAILED); result.setData("Action file not found: " + action.getAbsolutePath()); } return path; @@ -60,8 +65,14 @@ public class MetaAction implements Comparable { @Data public static class Result { - private boolean success = true; + private ResultStatus status = ResultStatus.WAITING; private String data = null; } + public enum ResultStatus { + SUCCESS, + FAILED, + WAITING + } + } diff --git a/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/PhaserRecord.java b/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/PhaserRecord.java index cc3d1805..c0c85289 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/PhaserRecord.java +++ b/Partner-Main/src/main/java/work/slhaf/partner/core/action/entity/PhaserRecord.java @@ -10,11 +10,24 @@ public record PhaserRecord(Phaser phaser, ActionData actionData) { actionData.setStatus(ActionStatus.FAILED); } + /** + * 负责将 ActionData 的状态设置为 INTERRUPTED + * 同时循环检查进行阻塞 + */ public void interrupt() { - + actionData.setStatus(ActionStatus.INTERRUPTED); + while (actionData().getStatus() == ActionStatus.INTERRUPTED) { + try { + Thread.sleep(500); + } catch (InterruptedException ignored) { + } + } } + /** + * 将状态重新设置为 EXECUTING ,恢复 interrupt 阻塞状态 + */ public void complete() { - + actionData().setStatus(ActionStatus.EXECUTING); } } diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/ActionExecutor.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/ActionExecutor.java index 54de088a..5d3138bd 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/ActionExecutor.java +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/ActionExecutor.java @@ -10,6 +10,7 @@ import work.slhaf.partner.core.action.ActionCapability; import work.slhaf.partner.core.action.ActionCore; import work.slhaf.partner.core.action.entity.*; import work.slhaf.partner.core.action.entity.ActionData.ActionStatus; +import work.slhaf.partner.core.action.entity.MetaAction.ResultStatus; import work.slhaf.partner.core.cognation.CognationCapability; import work.slhaf.partner.core.memory.MemoryCapability; import work.slhaf.partner.module.modules.action.dispatcher.executor.entity.*; @@ -110,8 +111,8 @@ public class ActionExecutor extends AgentRunningSubModule actions, String userId, ActionData actionData, - ExecutorService executor, - PhaserRecord phaserRecord) { + ExecutorService executor, + PhaserRecord phaserRecord) { Phaser phaser = phaserRecord.phaser(); phaser.bulkRegister(actions.size()); // 不可替换为增强for,因为单组的行动单元集合数量是可以被外部干预的 @@ -130,7 +131,7 @@ public class ActionExecutor extends AgentRunningSubModule additionalContext) { + List additionalContext) { ExtractorInput input = new ExtractorInput(); input.setEvaluatedSlices(memoryCapability.getActivatedSlices(userId)); input.setRecentMessages(cognationCapability.getChatMessages()); diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/ActionRepairer.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/ActionRepairer.java index 3c5ea80a..086b10eb 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/ActionRepairer.java +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/ActionRepairer.java @@ -63,7 +63,7 @@ public class ActionRepairer extends AgentRunningSubModule - handleActionGeneration(JSONObject.parseObject(repairerData.getData(), GeneratorInput.class)); + handleActionGeneration(JSONObject.parseObject(repairerData.getData(), GeneratorInput.class)); case ACTION_INVOCATION -> handleActionInvocation( JSONObject.parseObject(repairerData.getData(), new TypeReference>() { })); @@ -127,6 +127,11 @@ public class ActionRepairer extends AgentRunningSubModule 0) { result.setStatus(RepairerStatus.OK); } else { @@ -144,7 +149,7 @@ public class ActionRepairer extends AgentRunningSubModule implements ActivateModel { +public class DynamicActionGenerator extends AgentRunningSubModule + implements ActivateModel { @Override - public GeneratorResult execute(GeneratorInput data) { + public GeneratorResult execute(GeneratorInput input) { + GeneratorResult result = new GeneratorResult(); + // 由于 SCRIPT 类型程序都是在 SandboxRunner 内部的磁盘上加载然后执行的, + // 所以此处的输入内容也只需要指定输入参数、临时key、是否持久化即可,路径将按照指定规则统一构建,不可交给LLM生成 + String prompt = buildPrompt(input); + // 响应结果需要包含几个特殊数据: 依赖项、代码内容、是否序列化、响应数据释义 + ChatResponse response = this.singleChat(prompt); + GeneratorResponseData generatorData = JSONObject + .parseObject(ExtractUtil.extractJson(response.getMessage()), GeneratorResponseData.class); + MetaAction tempAction = buildAction(input); + waitingSerialize(tempAction, generatorData); + result.setTempAction(tempAction); return null; } + /** + * 将临时行动单元序列化至临时文件夹,并设置程序路径、放置在队列中,等待执行状态变化,并根据序列化选项选择是否补充 MetaActionInfo 并持久序列化 + */ + private void waitingSerialize(MetaAction tempAction, GeneratorResponseData generatorData) { + + } + + private MetaAction buildAction(GeneratorInput input) { + MetaAction tempAction = new MetaAction(); + tempAction.setKey(input.getKey()); + tempAction.setParams(input.getParams()); + tempAction.setIo(true); + tempAction.setOrder(-1); + tempAction.setType(MetaActionType.SCRIPT); + return tempAction; + } + + private String buildPrompt(GeneratorInput data) { + JSONObject prompt = new JSONObject(); + prompt.put("[行动描述]", data.getDescription()); + // prompt.putObject("[行动参数]").putAll(data.getParams()); + prompt.putObject("[行动参数描述]").putAll(data.getParamsDescription()); + return prompt.toString(); + } + @Override public String modelKey() { - return ""; + return "dynamic_generator"; } @Override public boolean withBasicPrompt() { return false; } + + @Data + private class GeneratorResponseData { + private List dependencies; + private String code; + private boolean serialize; + private JSONObject responseSchema; + } } diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/ParamsExtractor.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/ParamsExtractor.java index 44dfa680..ff527d21 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/ParamsExtractor.java +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/ParamsExtractor.java @@ -1,7 +1,11 @@ package work.slhaf.partner.module.modules.action.dispatcher.executor; +import java.util.HashMap; +import java.util.List; + import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; + import lombok.extern.slf4j.Slf4j; import work.slhaf.partner.api.agent.factory.module.annotation.AgentSubModule; import work.slhaf.partner.api.agent.runtime.interaction.flow.abstracts.ActivateModel; @@ -12,8 +16,6 @@ import work.slhaf.partner.module.modules.action.dispatcher.executor.entity.Extra import work.slhaf.partner.module.modules.action.dispatcher.executor.entity.ExtractorResult; import work.slhaf.partner.module.modules.action.dispatcher.executor.entity.HistoryAction; -import java.util.List; - /** * 负责依据输入内容进行行动单元的参数信息提取 */ @@ -32,7 +34,7 @@ public class ParamsExtractor extends AgentRunningSubModule()); } return result; } diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/entity/ExtractorResult.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/entity/ExtractorResult.java index de05dfd5..9ddf9060 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/entity/ExtractorResult.java +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/entity/ExtractorResult.java @@ -1,9 +1,11 @@ package work.slhaf.partner.module.modules.action.dispatcher.executor.entity; +import java.util.Map; + import lombok.Data; @Data public class ExtractorResult { private boolean ok; - private String[] params; + private Map params; } diff --git a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/entity/GeneratorInput.java b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/entity/GeneratorInput.java index 89d52ba8..0d84f40f 100644 --- a/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/entity/GeneratorInput.java +++ b/Partner-Main/src/main/java/work/slhaf/partner/module/modules/action/dispatcher/executor/entity/GeneratorInput.java @@ -1,7 +1,13 @@ package work.slhaf.partner.module.modules.action.dispatcher.executor.entity; +import java.util.Map; + import lombok.Data; @Data public class GeneratorInput { + private String key; + private Map params; + private String description; + private Map paramsDescription; }