refactor(action): add ExecutingActionBlockManager to emit execution lifecycle ContextBlocks from action snapshots

This commit is contained in:
2026-03-26 15:38:01 +08:00
parent 750bef0fd8
commit 5219142b5c

View File

@@ -0,0 +1,370 @@
package work.slhaf.partner.module.modules.action.executor;
import kotlin.Unit;
import org.jetbrains.annotations.NotNull;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import work.slhaf.partner.core.action.entity.*;
import work.slhaf.partner.core.action.entity.intervention.MetaIntervention;
import work.slhaf.partner.core.cognition.BlockContent;
import work.slhaf.partner.core.cognition.ContextBlock;
import work.slhaf.partner.core.cognition.ContextWorkspace;
import work.slhaf.partner.module.modules.action.executor.entity.HistoryAction;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.stream.Collectors;
class ExecutingActionBlockManager {
private static final String SOURCE = "action_executor";
private final ContextWorkspace contextWorkspace;
ExecutingActionBlockManager(ContextWorkspace contextWorkspace) {
this.contextWorkspace = contextWorkspace;
}
void emitStateActionTriggeredBlock(StateAction stateAction) {
StateActionSnapshot snapshot = stateAction.snapshot();
String blockName = buildBlockName(stateAction.getUuid());
String emittedAt = emittedAt();
String event = "state_action_triggered";
contextWorkspace.register(new ContextBlock(
buildStateActionFullBlock(snapshot, blockName, emittedAt, event),
buildStateActionCompactBlock(snapshot, blockName, emittedAt, event),
buildStateActionAbstractBlock(snapshot, blockName, event),
Set.of(ContextBlock.VisibleDomain.ACTION),
70,
18,
10
));
}
private @NotNull BlockContent buildStateActionAbstractBlock(StateActionSnapshot snapshot, 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, "description", snapshot.getDescription());
}
};
}
private @NotNull BlockContent buildStateActionCompactBlock(StateActionSnapshot snapshot, 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);
appendTextElement(document, root, "reason", snapshot.getReason());
appendTextElement(document, root, "description", snapshot.getDescription());
}
};
}
private @NotNull BlockContent buildStateActionFullBlock(StateActionSnapshot snapshot, 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);
appendTextElement(document, root, "reason", snapshot.getReason());
appendTextElement(document, root, "description", snapshot.getDescription());
appendTextElement(document, root, "source", snapshot.getSource());
appendTextElement(document, root, "schedule_type", snapshot.getScheduleType().name().toLowerCase(Locale.ROOT));
}
};
}
void emitActionLaunchedBlock(ExecutableAction action) {
ExecutableActionSnapshot snapshot = action.snapshot();
String blockName = buildBlockName(action.getUuid());
String emittedAt = emittedAt();
String event = "executable_action_launched";
contextWorkspace.register(new ContextBlock(
buildActionLaunchedFullBlock(snapshot, blockName, event, emittedAt),
buildActionCompactBlock(snapshot, blockName, event, emittedAt),
buildActionAbstractBlock(snapshot, blockName, event),
Set.of(ContextBlock.VisibleDomain.ACTION),
28,
6,
18
));
}
private @NotNull BlockContent buildActionAbstractBlock(ExecutableActionSnapshot snapshot, 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, "description", snapshot.getDescription());
}
};
}
private @NotNull BlockContent buildActionCompactBlock(ExecutableActionSnapshot snapshot, String blockName, String event, String emittedAt) {
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);
appendTextElement(document, root, "primary_action_chain_size", snapshot.getActionChainSize());
appendTextElement(document, root, "reason", snapshot.getReason());
appendTextElement(document, root, "description", snapshot.getDescription());
Schedulable.ScheduleType scheduleType = snapshot.getScheduleType();
String scheduleContent = snapshot.getScheduleContent();
if (scheduleType != null && scheduleContent != null) {
appendChildElement(document, root, "schedule_info", (element) -> {
appendTextElement(document, element, "schedule_type", scheduleType.name().toLowerCase(Locale.ROOT));
appendTextElement(document, element, "schedule_content", scheduleContent);
return Unit.INSTANCE;
});
}
}
};
}
private @NotNull BlockContent buildActionLaunchedFullBlock(ExecutableActionSnapshot snapshot, String blockName, String event, String emittedAt) {
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);
appendTextElement(document, root, "primary_action_chain_size", snapshot.getActionChainSize());
appendTextElement(document, root, "reason", snapshot.getReason());
appendTextElement(document, root, "description", snapshot.getDescription());
appendTextElement(document, root, "source", snapshot.getSource());
appendTextElement(document, root, "tendency", snapshot.getTendency());
Schedulable.ScheduleType scheduleType = snapshot.getScheduleType();
String scheduleContent = snapshot.getScheduleContent();
if (scheduleType != null && scheduleContent != null) {
appendChildElement(document, root, "schedule_info", (element) -> {
appendTextElement(document, element, "schedule_type", scheduleType.name().toLowerCase(Locale.ROOT));
appendTextElement(document, element, "schedule_content", scheduleContent);
return Unit.INSTANCE;
});
}
}
};
}
void emitActionStageSettledBlock(ExecutableAction action) {
ExecutableActionSnapshot snapshot = action.snapshot();
String blockName = buildBlockName(action.getUuid());
String emittedAt = emittedAt();
String event = "executable_action_stage_settled";
contextWorkspace.register(new ContextBlock(
buildActionStageFullBlock(snapshot, blockName, emittedAt, event),
buildActionStageCompactBlock(snapshot, blockName, emittedAt, event),
buildActionStageAbstractBlock(snapshot, blockName, event),
Set.of(ContextBlock.VisibleDomain.ACTION),
55,
10,
12
));
}
private @NotNull BlockContent buildActionStageAbstractBlock(ExecutableActionSnapshot snapshot, String blockName, String event) {
int settledStage = snapshot.getExecutingStage();
List<HistoryAction> history = snapshot.getHistory().get(settledStage);
return new ActionBlockContent(blockName, SOURCE) {
@Override
protected void fillXml(@NotNull Document document, @NotNull Element root) {
appendEventElement(document, root, event);
appendTextElement(document, root, "abstract", history.size() + " meta actions are resolved in stage " + settledStage);
}
};
}
private @NotNull BlockContent buildActionStageCompactBlock(ExecutableActionSnapshot snapshot, String blockName, String emittedAt, String event) {
int settledStage = snapshot.getExecutingStage();
List<HistoryAction> history = snapshot.getHistory().get(settledStage);
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);
appendTextElement(document, root, "action_chain_size", snapshot.getActionChainSize());
appendTextElement(document, root, "abstract", history.size() + " meta actions are resolved in stage " + settledStage);
}
};
}
private @NotNull BlockContent buildActionStageFullBlock(ExecutableActionSnapshot snapshot, String blockName, String emittedAt, String event) {
int settledStage = snapshot.getExecutingStage();
List<HistoryAction> history = snapshot.getHistory().get(settledStage);
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);
appendTextElement(document, root, "action_chain_size", snapshot.getActionChainSize());
appendTextElement(document, root, "settled_action_chain_stage", settledStage);
appendListElement(document,
root,
"settled_meta_actions",
"meta_action",
history.subList(0, Math.min(3, history.size())),
(item, action) -> {
String primaryResult = action.result();
String result = primaryResult.length() > 160 ? primaryResult.substring(0, 160) : primaryResult;
appendTextElement(document, item, "action_key", action.actionKey());
appendTextElement(document, item, "result", result);
return Unit.INSTANCE;
}
);
}
};
}
void emitActionCorrectionBlock(ExecutableAction action, String reason, List<MetaIntervention> interventions) {
ExecutableActionSnapshot snapshot = action.snapshot();
String blockName = buildBlockName(action.getUuid());
String emittedAt = emittedAt();
String event = "executable_action_correction_triggered";
contextWorkspace.register(new ContextBlock(
buildActionCorrectionFullBlock(snapshot, reason, interventions, blockName, emittedAt, event),
buildActionCorrectionCompactBlock(snapshot, reason, interventions, blockName, emittedAt, event),
buildActionCorrectionAbstractBlock(snapshot, interventions, blockName, event),
Set.of(ContextBlock.VisibleDomain.ACTION),
22,
5,
22
));
}
private @NotNull BlockContent buildActionCorrectionAbstractBlock(ExecutableActionSnapshot snapshot, List<MetaIntervention> interventions, 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", interventions.size() + " interventions occurred after stage " + snapshot.getExecutingStage());
}
};
}
private @NotNull BlockContent buildActionCorrectionCompactBlock(ExecutableActionSnapshot snapshot, String reason, List<MetaIntervention> interventions, String blockName, String emittedAt, String event) {
return new ActionBlockContent(blockName, SOURCE, BlockContent.Urgency.HIGH) {
@Override
protected void fillXml(@NotNull Document document, @NotNull Element root) {
Set<Integer> affectedStage = interventions.stream().map(MetaIntervention::getOrder).collect(Collectors.toSet());
appendEventElement(document, root, event);
appendTextElement(document, root, "emitted_at", emittedAt);
appendTextElement(document, root, "action_chain_size", snapshot.getActionChainSize());
appendTextElement(document, root, "abstract", interventions.size() + " interventions occurred after stage " + snapshot.getExecutingStage() + ", stage: " + affectedStage + " are affected");
appendTextElement(document, root, "correction_reason", reason);
}
};
}
private @NotNull BlockContent buildActionCorrectionFullBlock(ExecutableActionSnapshot snapshot, String reason, List<MetaIntervention> interventions, String blockName, String emittedAt, String event) {
return new ActionBlockContent(blockName, SOURCE, BlockContent.Urgency.HIGH) {
@Override
protected void fillXml(@NotNull Document document, @NotNull Element root) {
appendEventElement(document, root, event);
appendTextElement(document, root, "emitted_at", emittedAt);
appendTextElement(document, root, "action_chain_size", snapshot.getActionChainSize());
appendTextElement(document, root, "correction_reason", reason);
appendListElement(document,
root,
"applied_interventions",
"intervention",
interventions,
(item, intervention) -> {
appendTextElement(document, item, "type", intervention.getType().name().toLowerCase(Locale.ROOT));
appendTextElement(document, item, "affected_stage", intervention.getOrder());
appendTextElement(document, item, "applied_action_key_set", intervention.getActions());
return Unit.INSTANCE;
}
);
}
};
}
void emitActionFinishedBlock(ExecutableAction action) {
ExecutableActionSnapshot snapshot = action.snapshot();
String blockName = buildBlockName(action.getUuid());
String emittedAt = emittedAt();
String event = "executable_action_finished";
contextWorkspace.register(new ContextBlock(
buildActionFinishedFullBlock(snapshot, blockName, emittedAt, event),
buildActionFinishedFullBlock(snapshot, blockName, emittedAt, event),
buildActionFinishedAbstractBlock(snapshot, blockName, event),
Set.of(ContextBlock.VisibleDomain.ACTION),
35,
14,
24
));
}
private @NotNull BlockContent buildActionFinishedAbstractBlock(ExecutableActionSnapshot snapshot, 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, "final_status", snapshot.getStatus().name().toLowerCase(Locale.ROOT));
}
};
}
private @NotNull BlockContent buildActionFinishedFullBlock(ExecutableActionSnapshot snapshot, String blockName, String emittedAt, String event) {
return new ActionBlockContent(blockName, SOURCE, BlockContent.Urgency.HIGH) {
@Override
protected void fillXml(@NotNull Document document, @NotNull Element root) {
appendEventElement(document, root, event);
appendTextElement(document, root, "emitted_at", emittedAt);
appendTextElement(document, root, "final_status", snapshot.getStatus().name().toLowerCase(Locale.ROOT));
appendTextElement(document, root, "result", snapshot.getResult());
}
};
}
private String emittedAt() {
return ZonedDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
}
private String buildBlockName(String actionId) {
return "executing_action-" + actionId;
}
private static abstract class ActionBlockContent extends BlockContent {
private ActionBlockContent(@NotNull String blockName, @NotNull String source, @NotNull Urgency urgency) {
super(blockName, source, urgency);
}
private ActionBlockContent(@NotNull String blockName, @NotNull String source) {
super(blockName, source);
}
protected void appendEventElement(@NotNull Document document, @NotNull Element root, String event) {
appendTextElement(document, root, "event", event);
}
}
}