Bias coach action plans by guidance preference

This commit is contained in:
axiomlogicnexus 2026-04-27 17:15:21 +02:00
parent 5b4c27bcfc
commit 7ef5916223
5 changed files with 92 additions and 4 deletions

View file

@ -1276,6 +1276,7 @@ FHyperTwistTrainingCoachActionPlan UHyperTwistContractLibrary::MakeSampleTrainin
{
return UHyperTwistTrainingRepositoryLibrary::BuildCoachActionPlan(
MakeSampleTrainingCoachBrief(),
MakeSampleTrainingCoachMemorySnapshot(),
TEXT("coach_plan_training_session_01"),
TEXT("2026-04-28T12:05:00Z")
);
@ -1313,6 +1314,7 @@ FHyperTwistTrainingCoachActionSequenceSummary UHyperTwistContractLibrary::MakeSa
const FHyperTwistTrainingCoachActionPlan FollowUpPlan =
UHyperTwistTrainingRepositoryLibrary::BuildCoachActionPlan(
FollowUpBrief,
MakeSampleTrainingCoachMemorySnapshot(),
TEXT("coach_follow_up_training_session_02"),
TEXT("2026-04-28T12:20:00Z")
);
@ -1344,6 +1346,7 @@ FHyperTwistTrainingCoachActionClosureSummary UHyperTwistContractLibrary::MakeSam
const FHyperTwistTrainingCoachActionPlan FollowUpPlan =
UHyperTwistTrainingRepositoryLibrary::BuildCoachActionPlan(
FollowUpBrief,
MakeSampleTrainingCoachMemorySnapshot(),
TEXT("coach_follow_up_training_session_02"),
TEXT("2026-04-28T12:20:00Z")
);
@ -1395,6 +1398,7 @@ FHyperTwistTrainingCoachRecommendationHistorySummary UHyperTwistContractLibrary:
const FHyperTwistTrainingCoachActionPlan FollowUpPlan =
UHyperTwistTrainingRepositoryLibrary::BuildCoachActionPlan(
FollowUpBrief,
MakeSampleTrainingCoachMemorySnapshot(),
TEXT("coach_follow_up_training_session_02"),
TEXT("2026-04-28T12:20:00Z")
);
@ -1426,6 +1430,7 @@ FHyperTwistTrainingCoachCarryForwardPolicySummary UHyperTwistContractLibrary::Ma
const FHyperTwistTrainingCoachActionPlan FollowUpPlan =
UHyperTwistTrainingRepositoryLibrary::BuildCoachActionPlan(
FollowUpBrief,
MakeSampleTrainingCoachMemorySnapshot(),
TEXT("coach_follow_up_training_session_02"),
TEXT("2026-04-28T12:20:00Z")
);
@ -1457,6 +1462,7 @@ FHyperTwistTrainingCoachArchivePolicySummary UHyperTwistContractLibrary::MakeSam
const FHyperTwistTrainingCoachActionPlan FollowUpPlan =
UHyperTwistTrainingRepositoryLibrary::BuildCoachActionPlan(
FollowUpBrief,
MakeSampleTrainingCoachMemorySnapshot(),
TEXT("coach_follow_up_training_session_02"),
TEXT("2026-04-28T12:20:00Z")
);

View file

@ -176,6 +176,67 @@ namespace HyperTwistTrainingRepositoryLibraryInternal
return ReviewPlan.CreatedAtUtc;
}
void ResolveCoachActionPlanPreferenceDefaults(
const FHyperTwistCoachBrief& CoachBrief,
const FHyperTwistTrainingCoachMemorySnapshot& CoachMemorySnapshot,
EHyperTwistTrainingDeliveryMode& InOutMode,
EHyperTwistTrainingSelectionPolicy& InOutSelectionPolicy)
{
if (CoachMemorySnapshot.PreferredGuidanceLane == EHyperTwistTrainingCoachGuidanceLane::FollowUp)
{
const bool bShouldBiasFollowUpDefaults =
CoachBrief.FollowUpDepth > 0
|| CoachBrief.bNeedsCoachReview
|| CoachMemorySnapshot.FollowUpReadyCoachSequenceCount > 0
|| CoachMemorySnapshot.ScheduleBlockedFollowUpEventCount > 0;
if (!bShouldBiasFollowUpDefaults)
{
return;
}
if (CoachBrief.bPreferRecognitionReplayReview
&& CoachMemorySnapshot.DominantCoachSuggestedMode == EHyperTwistTrainingDeliveryMode::RecognitionAssisted)
{
InOutMode = EHyperTwistTrainingDeliveryMode::RecognitionAssisted;
}
else if (InOutMode == EHyperTwistTrainingDeliveryMode::Timer
|| InOutMode == EHyperTwistTrainingDeliveryMode::VirtualCube)
{
InOutMode = EHyperTwistTrainingDeliveryMode::CoachReviewed;
}
if (InOutSelectionPolicy == EHyperTwistTrainingSelectionPolicy::Weighted)
{
InOutSelectionPolicy = EHyperTwistTrainingSelectionPolicy::Scripted;
}
return;
}
if (CoachMemorySnapshot.PreferredGuidanceLane != EHyperTwistTrainingCoachGuidanceLane::Recommended
|| CoachBrief.bNeedsCoachReview
|| CoachBrief.FollowUpDepth > 0)
{
return;
}
if (CoachBrief.bPreferRecognitionReplayReview
&& CoachMemorySnapshot.DominantCoachSuggestedMode == EHyperTwistTrainingDeliveryMode::RecognitionAssisted)
{
InOutMode = EHyperTwistTrainingDeliveryMode::RecognitionAssisted;
}
else if (InOutMode == EHyperTwistTrainingDeliveryMode::CoachReviewed
&& CoachMemorySnapshot.DominantCoachSuggestedMode != EHyperTwistTrainingDeliveryMode::CoachReviewed)
{
InOutMode = CoachMemorySnapshot.DominantCoachSuggestedMode;
}
if (InOutSelectionPolicy == EHyperTwistTrainingSelectionPolicy::Scripted
&& CoachMemorySnapshot.DominantCoachSelectionPolicy != EHyperTwistTrainingSelectionPolicy::Scripted)
{
InOutSelectionPolicy = CoachMemorySnapshot.DominantCoachSelectionPolicy;
}
}
int32 ComputePlanDurationMs(
const FHyperTwistTrainingReviewPlanState& ReviewPlan,
const FString& ReferenceUtc
@ -5862,6 +5923,7 @@ TArray<FHyperTwistTrainingSessionTemplate> UHyperTwistTrainingRepositoryLibrary:
FHyperTwistTrainingCoachActionPlan UHyperTwistTrainingRepositoryLibrary::BuildCoachActionPlan(
const FHyperTwistCoachBrief& CoachBrief,
const FHyperTwistTrainingCoachMemorySnapshot& CoachMemorySnapshot,
const FString& PlanId,
const FString& ReferenceUtc
)
@ -5896,6 +5958,14 @@ FHyperTwistTrainingCoachActionPlan UHyperTwistTrainingRepositoryLibrary::BuildCo
ActionPlan.PrimaryActionLabel = CoachBrief.PrimaryActionLabel;
ActionPlan.SuggestedMode = CoachBrief.SuggestedMode;
ActionPlan.SuggestedSelectionPolicy = CoachBrief.SuggestedSelectionPolicy;
HyperTwistTrainingRepositoryLibraryInternal::ResolveCoachActionPlanPreferenceDefaults(
CoachBrief,
CoachMemorySnapshot,
ActionPlan.SuggestedMode,
ActionPlan.SuggestedSelectionPolicy
);
ActionPlan.PreferredGuidanceLane = CoachMemorySnapshot.PreferredGuidanceLane;
ActionPlan.PreferredGuidanceSourceLabel = CoachMemorySnapshot.PreferredGuidanceSourceLabel;
ActionPlan.FocusCaseIds = CoachBrief.FocusCaseIds;
ActionPlan.PlanState = EHyperTwistTrainingCoachActionPlanState::Draft;
ActionPlan.FollowUpDepth = FMath::Max(0, CoachBrief.FollowUpDepth);
@ -5915,8 +5985,8 @@ FHyperTwistTrainingCoachActionPlan UHyperTwistTrainingRepositoryLibrary::BuildCo
Entry.ActionLabel = CoachBrief.PrimaryActionLabel;
Entry.Headline = CoachBrief.Headline;
Entry.PriorityScore = CoachBrief.PriorityScore;
Entry.SuggestedMode = CoachBrief.SuggestedMode;
Entry.SuggestedSelectionPolicy = CoachBrief.SuggestedSelectionPolicy;
Entry.SuggestedMode = ActionPlan.SuggestedMode;
Entry.SuggestedSelectionPolicy = ActionPlan.SuggestedSelectionPolicy;
Entry.bPreferRecognitionReplayReview = CoachBrief.bPreferRecognitionReplayReview;
if (Entry.IsStructurallyValid())
{
@ -5936,8 +6006,8 @@ FHyperTwistTrainingCoachActionPlan UHyperTwistTrainingRepositoryLibrary::BuildCo
: CoachBrief.PrimaryActionLabel;
Entry.Headline = CoachBrief.Headline;
Entry.PriorityScore = CoachBrief.PriorityScore;
Entry.SuggestedMode = CoachBrief.SuggestedMode;
Entry.SuggestedSelectionPolicy = CoachBrief.SuggestedSelectionPolicy;
Entry.SuggestedMode = ActionPlan.SuggestedMode;
Entry.SuggestedSelectionPolicy = ActionPlan.SuggestedSelectionPolicy;
Entry.bPreferRecognitionReplayReview = CoachBrief.bPreferRecognitionReplayReview;
ActionPlan.Entries.Add(Entry);
}

View file

@ -1304,6 +1304,7 @@ FHyperTwistTrainingRunState UHyperTwistTrainingSubsystem::StartCoachRecommendedR
const FHyperTwistTrainingCoachActionPlan DraftActionPlan =
UHyperTwistTrainingRepositoryLibrary::BuildCoachActionPlan(
ActiveCoachBrief,
ActiveCoachMemorySnapshot,
FString::Printf(TEXT("coach_plan_%s"), *SessionId),
FString()
);
@ -1365,6 +1366,7 @@ FHyperTwistTrainingRunState UHyperTwistTrainingSubsystem::StartCoachFollowUpRun(
const FHyperTwistTrainingCoachActionPlan DraftActionPlan =
UHyperTwistTrainingRepositoryLibrary::BuildCoachActionPlan(
FollowUpBrief,
ActiveCoachMemorySnapshot,
FString::Printf(TEXT("coach_follow_up_%s"), *SessionId),
FString()
);
@ -1453,6 +1455,7 @@ FHyperTwistTrainingRunState UHyperTwistTrainingSubsystem::StartNextQueuedCoachRu
const FHyperTwistTrainingCoachActionPlan DraftActionPlan =
UHyperTwistTrainingRepositoryLibrary::BuildCoachActionPlan(
QueueBrief,
ActiveCoachMemorySnapshot,
FString::Printf(TEXT("coach_queue_%s_%s"), *NextRunnableEntry->EntryId, *SessionId),
FString()
);
@ -1569,6 +1572,7 @@ FHyperTwistTrainingRunState UHyperTwistTrainingSubsystem::StartCoachQueueEntry(
(!QueueBrief.UserId.IsEmpty() && !QueueBrief.Headline.IsEmpty())
? UHyperTwistTrainingRepositoryLibrary::BuildCoachActionPlan(
QueueBrief,
ActiveCoachMemorySnapshot,
FString::Printf(TEXT("coach_queue_%s_%s"), *SelectedEntry->EntryId, *SessionId),
FString()
)

View file

@ -310,6 +310,7 @@ public:
UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Repository|Coach")
static FHyperTwistTrainingCoachActionPlan BuildCoachActionPlan(
const FHyperTwistCoachBrief& CoachBrief,
const FHyperTwistTrainingCoachMemorySnapshot& CoachMemorySnapshot,
const FString& PlanId,
const FString& ReferenceUtc
);

View file

@ -2908,6 +2908,13 @@ struct FHyperTwistTrainingCoachActionPlan
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
EHyperTwistTrainingSelectionPolicy SuggestedSelectionPolicy = EHyperTwistTrainingSelectionPolicy::Weighted;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
EHyperTwistTrainingCoachGuidanceLane PreferredGuidanceLane =
EHyperTwistTrainingCoachGuidanceLane::None;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
FString PreferredGuidanceSourceLabel;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
TArray<FString> FocusCaseIds;