From 2935daeffa07573187bfe2c2ab7bafbeac67b42f Mon Sep 17 00:00:00 2001 From: slhafzjw Date: Wed, 8 Apr 2026 16:52:21 +0800 Subject: [PATCH] refactor(action): support recover schedulable executable actions together, and ActionExecutor will emit a context block to explain recovering result --- .../action/executor/ActionExecutor.java | 11 +++- .../executor/ExecutingActionBlockManager.java | 59 ++++++++++++++++++- 2 files changed, 67 insertions(+), 3 deletions(-) diff --git a/Partner-Core/src/main/java/work/slhaf/partner/module/action/executor/ActionExecutor.java b/Partner-Core/src/main/java/work/slhaf/partner/module/action/executor/ActionExecutor.java index ec5bf34a..75af42b0 100644 --- a/Partner-Core/src/main/java/work/slhaf/partner/module/action/executor/ActionExecutor.java +++ b/Partner-Core/src/main/java/work/slhaf/partner/module/action/executor/ActionExecutor.java @@ -17,6 +17,7 @@ import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; public class ActionExecutor extends AbstractAgentModule.Standalone { @@ -49,8 +50,14 @@ public class ActionExecutor extends AbstractAgentModule.Standalone { runnerClient = actionCapability.runnerClient(); blockManager = new ExecutingActionBlockManager(cognitionCapability.contextWorkspace()); - actionCapability.listActions(Action.Status.EXECUTING, null) - .forEach(this::execute); + Set recoveredActions = new HashSet<>(); + recoveredActions.addAll(actionCapability.listActions(Action.Status.EXECUTING, null)); + recoveredActions.addAll(actionCapability.listActions(Action.Status.INTERRUPTED, null).stream().map(executableAction -> { + executableAction.setStatus(Action.Status.EXECUTING); + return executableAction; + }).collect(Collectors.toSet())); + recoveredActions.forEach(this::execute); + blockManager.emitActionRecoveredBlock(recoveredActions); } public void execute(Action action) { diff --git a/Partner-Core/src/main/java/work/slhaf/partner/module/action/executor/ExecutingActionBlockManager.java b/Partner-Core/src/main/java/work/slhaf/partner/module/action/executor/ExecutingActionBlockManager.java index 54f98d50..486424fe 100644 --- a/Partner-Core/src/main/java/work/slhaf/partner/module/action/executor/ExecutingActionBlockManager.java +++ b/Partner-Core/src/main/java/work/slhaf/partner/module/action/executor/ExecutingActionBlockManager.java @@ -28,6 +28,64 @@ class ExecutingActionBlockManager { this.contextWorkspace = contextWorkspace; } + void emitActionRecoveredBlock(Set recoveredActions) { + Set snapshots = recoveredActions.stream().map(ExecutableAction::snapshot).collect(Collectors.toSet()); + + String blockName = "actions_recovered"; + String emittedAt = emittedAt(); + String event = "actions_recovered"; + + contextWorkspace.register(new ContextBlock( + buildExecutingActionRecoveredFullBlock(snapshots, blockName, emittedAt, event), + buildExecutingActionRecoveredCompactBlock(snapshots, blockName, emittedAt, event), + buildExecutingActionRecoveredAbstractBlock(snapshots, blockName, event), + Set.of(ContextBlock.VisibleDomain.ACTION), + 100, + 12, + 1 + )); + } + + private @NotNull BlockContent buildExecutingActionRecoveredAbstractBlock(Set recoveredExecutingActions, String blockName, String event) { + return new ActionBlockContent(blockName, SOURCE) { + @Override + protected void fillXml(@NotNull Document document, @NotNull Element root) { + appendEventElement(document, root, event); + appendTextElement(document, root, "abstract", recoveredExecutingActions.size() + " executing actions recovered."); + } + }; + } + + private @NotNull BlockContent buildExecutingActionRecoveredCompactBlock(Set recoveredExecutingActions, String blockName, String emittedAt, String event) { + return new ActionBlockContent(blockName, SOURCE) { + @Override + protected void fillXml(@NotNull Document document, @NotNull Element root) { + appendEventElement(document, root, event); + appendTextElement(document, root, "emitted_at", emittedAt); + appendListElement(document, root, "recovered_actions", "action", recoveredExecutingActions, (actionElement, action) -> { + appendTextElement(document, actionElement, "description", action.getDescription()); + return Unit.INSTANCE; + }); + } + }; + } + + private @NotNull BlockContent buildExecutingActionRecoveredFullBlock(Set recoveredExecutingActions, String blockName, String emittedAt, String event) { + return new ActionBlockContent(blockName, SOURCE) { + @Override + protected void fillXml(@NotNull Document document, @NotNull Element root) { + appendEventElement(document, root, event); + appendTextElement(document, root, "emitted_at", emittedAt); + appendListElement(document, root, "recovered_actions", "action", recoveredExecutingActions, (actionElement, action) -> { + appendTextElement(document, actionElement, "description", action.getDescription()); + appendTextElement(document, actionElement, "source", action.getSource()); + appendTextElement(document, actionElement, "executing_stage", action.getExecutingStage()); + return Unit.INSTANCE; + }); + } + }; + } + void emitStateActionTriggeredBlock(StateAction stateAction) { StateActionSnapshot snapshot = stateAction.snapshot(); @@ -351,7 +409,6 @@ class ExecutingActionBlockManager { return "executing_action-" + actionId; } - private static abstract class ActionBlockContent extends BlockContent { private ActionBlockContent(@NotNull String blockName, @NotNull String source, @NotNull Urgency urgency) {