mirror of
https://github.com/slhaf/Partner.git
synced 2026-05-12 16:53:04 +08:00
feat(action): add stage descriptions to action chains
This commit is contained in:
@@ -76,6 +76,10 @@ final class ActionPoolStateCodec {
|
|||||||
.<StateValue>map(entry -> {
|
.<StateValue>map(entry -> {
|
||||||
Map<String, StateValue> stageMap = new LinkedHashMap<>();
|
Map<String, StateValue> stageMap = new LinkedHashMap<>();
|
||||||
stageMap.put("stage", StateValue.num(entry.getKey()));
|
stageMap.put("stage", StateValue.num(entry.getKey()));
|
||||||
|
String stageDescription = action.getStageDescriptions().get(entry.getKey());
|
||||||
|
if (stageDescription != null && !stageDescription.isBlank()) {
|
||||||
|
stageMap.put("description", StateValue.str(stageDescription));
|
||||||
|
}
|
||||||
stageMap.put("actions", StateValue.arr(entry.getValue().stream()
|
stageMap.put("actions", StateValue.arr(entry.getValue().stream()
|
||||||
.map(metaAction -> (StateValue) encodeMetaAction(metaAction))
|
.map(metaAction -> (StateValue) encodeMetaAction(metaAction))
|
||||||
.toList()));
|
.toList()));
|
||||||
@@ -126,7 +130,11 @@ final class ActionPoolStateCodec {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<Integer, List<MetaAction>> restoredChain = decodeActionChain(actionObject.getJSONArray("action_chain"));
|
Map<Integer, String> restoredStageDescriptions = new LinkedHashMap<>();
|
||||||
|
Map<Integer, List<MetaAction>> restoredChain = decodeActionChain(
|
||||||
|
actionObject.getJSONArray("action_chain"),
|
||||||
|
restoredStageDescriptions
|
||||||
|
);
|
||||||
ExecutableAction executableAction;
|
ExecutableAction executableAction;
|
||||||
if ("schedulable".equals(kind)) {
|
if ("schedulable".equals(kind)) {
|
||||||
String scheduleType = actionObject.getString("schedule_type");
|
String scheduleType = actionObject.getString("schedule_type");
|
||||||
@@ -173,11 +181,15 @@ final class ActionPoolStateCodec {
|
|||||||
if (result != null) {
|
if (result != null) {
|
||||||
executableAction.setResult(result);
|
executableAction.setResult(result);
|
||||||
}
|
}
|
||||||
|
executableAction.getStageDescriptions().putAll(restoredStageDescriptions);
|
||||||
executableAction.getHistory().putAll(decodeHistory(actionObject.getJSONArray("history")));
|
executableAction.getHistory().putAll(decodeHistory(actionObject.getJSONArray("history")));
|
||||||
return executableAction;
|
return executableAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Map<Integer, List<MetaAction>> decodeActionChain(@Nullable JSONArray actionChainArray) {
|
private static Map<Integer, List<MetaAction>> decodeActionChain(
|
||||||
|
@Nullable JSONArray actionChainArray,
|
||||||
|
Map<Integer, String> stageDescriptions
|
||||||
|
) {
|
||||||
Map<Integer, List<MetaAction>> restored = new LinkedHashMap<>();
|
Map<Integer, List<MetaAction>> restored = new LinkedHashMap<>();
|
||||||
if (actionChainArray == null) {
|
if (actionChainArray == null) {
|
||||||
return toMutableActionChain(restored);
|
return toMutableActionChain(restored);
|
||||||
@@ -188,10 +200,14 @@ final class ActionPoolStateCodec {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Integer stage = stageObject.getInteger("stage");
|
Integer stage = stageObject.getInteger("stage");
|
||||||
|
String description = stageObject.getString("description");
|
||||||
JSONArray actions = stageObject.getJSONArray("actions");
|
JSONArray actions = stageObject.getJSONArray("actions");
|
||||||
if (stage == null || actions == null) {
|
if (stage == null || actions == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (description != null && !description.isBlank()) {
|
||||||
|
stageDescriptions.put(stage, description);
|
||||||
|
}
|
||||||
List<MetaAction> metaActions = new ArrayList<>();
|
List<MetaAction> metaActions = new ArrayList<>();
|
||||||
for (int j = 0; j < actions.size(); j++) {
|
for (int j = 0; j < actions.size(); j++) {
|
||||||
JSONObject actionObject = actions.getJSONObject(j);
|
JSONObject actionObject = actions.getJSONObject(j);
|
||||||
|
|||||||
@@ -96,6 +96,11 @@ sealed class ExecutableAction(
|
|||||||
*/
|
*/
|
||||||
abstract val actionChain: MutableMap<Int, MutableList<MetaAction>>
|
abstract val actionChain: MutableMap<Int, MutableList<MetaAction>>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 行动阶段描述,用于为每个 stage 提供可落地的执行目标说明
|
||||||
|
*/
|
||||||
|
val stageDescriptions: MutableMap<Int, String> = mutableMapOf()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 行动阶段(当前阶段)
|
* 行动阶段(当前阶段)
|
||||||
*/
|
*/
|
||||||
@@ -143,6 +148,7 @@ sealed class ExecutableAction(
|
|||||||
status = status,
|
status = status,
|
||||||
tendency = tendency,
|
tendency = tendency,
|
||||||
actionChainSize = actionChain.size,
|
actionChainSize = actionChain.size,
|
||||||
|
stageDescriptions = stageDescriptions.toMap(),
|
||||||
executingStage = executingStage,
|
executingStage = executingStage,
|
||||||
result = result,
|
result = result,
|
||||||
history = history.mapValues { (_, value) -> value.toList() },
|
history = history.mapValues { (_, value) -> value.toList() },
|
||||||
@@ -268,6 +274,7 @@ data class ExecutableActionSnapshot(
|
|||||||
|
|
||||||
val tendency: String,
|
val tendency: String,
|
||||||
val actionChainSize: Int,
|
val actionChainSize: Int,
|
||||||
|
val stageDescriptions: Map<Int, String>,
|
||||||
val executingStage: Int,
|
val executingStage: Int,
|
||||||
val result: String?,
|
val result: String?,
|
||||||
val history: Map<Int, List<HistoryAction>>,
|
val history: Map<Int, List<HistoryAction>>,
|
||||||
|
|||||||
@@ -406,7 +406,12 @@ public class ActionExecutor extends AbstractAgentModule.Standalone {
|
|||||||
result.reset();
|
result.reset();
|
||||||
metaAction.getParams().clear();
|
metaAction.getParams().clear();
|
||||||
|
|
||||||
Result<ExtractorInput> extractorInputResult = assemblyHelper.buildExtractorInput(metaAction.getKey(), actionData.getUuid(), actionData.getDescription());
|
Result<ExtractorInput> extractorInputResult = assemblyHelper.buildExtractorInput(
|
||||||
|
metaAction.getKey(),
|
||||||
|
actionData.getUuid(),
|
||||||
|
actionData.getDescription(),
|
||||||
|
resolveCurrentStageDescription(actionData, executingStage)
|
||||||
|
);
|
||||||
AgentRuntimeException exception = extractorInputResult.exceptionOrNull();
|
AgentRuntimeException exception = extractorInputResult.exceptionOrNull();
|
||||||
if (exception != null) {
|
if (exception != null) {
|
||||||
failureReason.set(exception.getMessage());
|
failureReason.set(exception.getMessage());
|
||||||
@@ -512,6 +517,10 @@ public class ActionExecutor extends AbstractAgentModule.Standalone {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String resolveCurrentStageDescription(ExecutableAction executableAction, int executingStage) {
|
||||||
|
return executableAction.getStageDescriptions().get(executingStage);
|
||||||
|
}
|
||||||
|
|
||||||
private String buildAttemptFailureReason(String prefix, String detail) {
|
private String buildAttemptFailureReason(String prefix, String detail) {
|
||||||
if (detail == null || detail.isBlank()) {
|
if (detail == null || detail.isBlank()) {
|
||||||
return prefix;
|
return prefix;
|
||||||
@@ -745,13 +754,14 @@ public class ActionExecutor extends AbstractAgentModule.Standalone {
|
|||||||
private AssemblyHelper() {
|
private AssemblyHelper() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Result<ExtractorInput> buildExtractorInput(String actionKey, @NotNull String uuid, @NotNull String description) {
|
private Result<ExtractorInput> buildExtractorInput(String actionKey, @NotNull String uuid, @NotNull String description, String currentStageDescription) {
|
||||||
return actionCapability.loadMetaActionInfo(actionKey).fold(
|
return actionCapability.loadMetaActionInfo(actionKey).fold(
|
||||||
metaActionInfo -> {
|
metaActionInfo -> {
|
||||||
ExtractorInput input = new ExtractorInput();
|
ExtractorInput input = new ExtractorInput();
|
||||||
input.setMetaActionInfo(metaActionInfo);
|
input.setMetaActionInfo(metaActionInfo);
|
||||||
input.setTargetActionId(uuid);
|
input.setTargetActionId(uuid);
|
||||||
input.setTargetActionDesc(description);
|
input.setTargetActionDesc(description);
|
||||||
|
input.setCurrentStageDesc(currentStageDescription);
|
||||||
return Result.success(input);
|
return Result.success(input);
|
||||||
},
|
},
|
||||||
Result::failure
|
Result::failure
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ public class ParamsExtractor extends AbstractAgentModule.Sub<ExtractorInput, Res
|
|||||||
你会收到:
|
你会收到:
|
||||||
- 一条结构化上下文消息,其中可能包含当前行动相关状态、近期交流轨迹、以及活跃记忆切片;
|
- 一条结构化上下文消息,其中可能包含当前行动相关状态、近期交流轨迹、以及活跃记忆切片;
|
||||||
- 一条任务消息,其中包含:
|
- 一条任务消息,其中包含:
|
||||||
- target_action:本次参数提取所面向的目标行动,用于帮助你判断上下文中哪些内容与当前提取直接相关;
|
- target_action:本次参数提取所面向的目标行动,用于帮助你判断上下文中哪些内容与当前提取直接相关;其中 current_stage_description 表示本次 MetaAction 所属阶段的具体执行目标,应优先用于约束参数提取;
|
||||||
- meta_action_info:该行动对应的说明,以及允许提取的参数列表。每个 <param name="..."> 节点的文本内容表示该参数的含义或期望内容。
|
- meta_action_info:该行动对应的说明,以及允许提取的参数列表。每个 <param name="..."> 节点的文本内容表示该参数的含义或期望内容。
|
||||||
|
|
||||||
你的任务:
|
你的任务:
|
||||||
@@ -78,6 +78,9 @@ public class ParamsExtractor extends AbstractAgentModule.Sub<ExtractorInput, Res
|
|||||||
appendChildElement(document, root, "target_action", block -> {
|
appendChildElement(document, root, "target_action", block -> {
|
||||||
appendTextElement(document, block, "uuid", input.getTargetActionId());
|
appendTextElement(document, block, "uuid", input.getTargetActionId());
|
||||||
appendTextElement(document, block, "description", input.getTargetActionDesc());
|
appendTextElement(document, block, "description", input.getTargetActionDesc());
|
||||||
|
if (input.getCurrentStageDesc() != null && !input.getCurrentStageDesc().isBlank()) {
|
||||||
|
appendTextElement(document, block, "current_stage_description", input.getCurrentStageDesc());
|
||||||
|
}
|
||||||
return Unit.INSTANCE;
|
return Unit.INSTANCE;
|
||||||
});
|
});
|
||||||
appendChildElement(document, root, "meta_action_info", element -> {
|
appendChildElement(document, root, "meta_action_info", element -> {
|
||||||
|
|||||||
@@ -16,6 +16,11 @@ public class ExtractorInput {
|
|||||||
*/
|
*/
|
||||||
private String targetActionDesc;
|
private String targetActionDesc;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当前执行阶段的 description
|
||||||
|
*/
|
||||||
|
private String currentStageDesc;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 目标 MetaActionInfo
|
* 目标 MetaActionInfo
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -150,10 +150,13 @@ public class ActionEvaluator extends AbstractAgentModule.Sub<EvaluatorInput, Lis
|
|||||||
|
|
||||||
primaryActionChain:
|
primaryActionChain:
|
||||||
- 只在 ok=true 时填写。
|
- 只在 ok=true 时填写。
|
||||||
- 每个元素包含 order 和 actionKeys。
|
- 每个元素包含 order、description 和 actionKeys。
|
||||||
- 不要写自然语言步骤。
|
- description 是该 stage 的具体执行目标,用一句短句说明本阶段要获得、检查、修改或触发什么;它不是用户回复文案,也不是完整推理过程。
|
||||||
- 不要写伪代码。
|
- 不要写伪代码。
|
||||||
- 若一个能力即可承接,使用单步链。
|
- 若 tendency 包含多个依赖步骤、需要先获取 A 再根据 A 决定 B、需要多次调用同一能力处理不同对象,或需要为后续汇报获取多类事实,应输出多 order 的 primaryActionChain。
|
||||||
|
- 不要为了减少步骤而把复杂诊断、查找、读取、分析全部压缩成单个 command::execute。
|
||||||
|
- 同一个 available_meta_action 可以在不同 order 中重复使用,只要每次对应的阶段目标、参数或对象不同。
|
||||||
|
- 对需要最终汇报的任务,行动链应负责获取支撑汇报所需的事实;最终自然语言汇报由 Communication 基于 action-finished state 完成,不需要把“汇报”本身作为一个 MetaAction。
|
||||||
|
|
||||||
scheduleData:
|
scheduleData:
|
||||||
- 仅当 tendency 明确要求未来、周期、延迟、提醒、定时或计划安排时填写。
|
- 仅当 tendency 明确要求未来、周期、延迟、提醒、定时或计划安排时填写。
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ public class EvaluatorResult {
|
|||||||
@Data
|
@Data
|
||||||
public static class ChainElement {
|
public static class ChainElement {
|
||||||
private Integer order;
|
private Integer order;
|
||||||
|
private String description;
|
||||||
private List<String> actionKeys;
|
private List<String> actionKeys;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user