Feed queue recovery into coach memory

This commit is contained in:
axiomlogicnexus 2026-04-27 17:58:09 +02:00
parent 5cddb7389d
commit 094d1c1975

View file

@ -237,6 +237,47 @@ namespace HyperTwistTrainingRepositoryLibraryInternal
}
}
EHyperTwistTrainingCoachGuidanceLane GuidanceLaneFromQueueSourceLabel(const FString& SourceLabel)
{
if (SourceLabel == TEXT("follow-up-brief"))
{
return EHyperTwistTrainingCoachGuidanceLane::FollowUp;
}
if (SourceLabel == TEXT("primary-brief"))
{
return EHyperTwistTrainingCoachGuidanceLane::Recommended;
}
return EHyperTwistTrainingCoachGuidanceLane::None;
}
EHyperTwistTrainingCoachGuidanceLane GuidanceLaneFromQueueEntry(
const FHyperTwistTrainingCoachSessionQueueStateEntry* Entry)
{
if (Entry == nullptr)
{
return EHyperTwistTrainingCoachGuidanceLane::None;
}
if (Entry->bRequiresFollowUp)
{
return EHyperTwistTrainingCoachGuidanceLane::FollowUp;
}
return GuidanceLaneFromQueueSourceLabel(Entry->SourceLabel);
}
const FHyperTwistTrainingCoachSessionQueueStateEntry* FindQueueEntryById(
const FHyperTwistTrainingCoachSessionQueueState& QueueState,
const FString& EntryId)
{
return QueueState.Entries.FindByPredicate(
[&EntryId](const FHyperTwistTrainingCoachSessionQueueStateEntry& Candidate)
{
return Candidate.EntryId == EntryId;
}
);
}
int32 ComputePlanDurationMs(
const FHyperTwistTrainingReviewPlanState& ReviewPlan,
const FString& ReferenceUtc
@ -5138,6 +5179,61 @@ FHyperTwistTrainingCoachMemorySnapshot UHyperTwistTrainingRepositoryLibrary::Der
|| QueueExecutionSummary.bHasBlockedFollowUpFriction
|| QueueExecutionSummary.bHasRepeatManualRescheduleFriction;
const FHyperTwistTrainingCoachSessionQueueStateEntry* MostDeferredQueueEntry =
HyperTwistTrainingRepositoryLibraryInternal::FindQueueEntryById(
ActiveQueueState,
QueueExecutionSummary.MostDeferredEntryId
);
const FHyperTwistTrainingCoachSessionQueueStateEntry* MostCompletedQueueEntry =
HyperTwistTrainingRepositoryLibraryInternal::FindQueueEntryById(
ActiveQueueState,
QueueExecutionSummary.MostCompletedEntryId
);
const EHyperTwistTrainingCoachGuidanceLane DominantDeferredLane =
HyperTwistTrainingRepositoryLibraryInternal::GuidanceLaneFromQueueEntry(
MostDeferredQueueEntry
);
const EHyperTwistTrainingCoachGuidanceLane DominantCompletedLane =
HyperTwistTrainingRepositoryLibraryInternal::GuidanceLaneFromQueueEntry(
MostCompletedQueueEntry
);
const int32 DeferredRecoverySignal = FMath::Clamp(
(QueueExecutionSummary.DeferredEventCount / 2)
+ (QueueExecutionSummary.ManualRescheduleEventCount > 0 ? 1 : 0),
0,
3
);
const int32 PromotionRecoverySignal = FMath::Clamp(
QueueExecutionSummary.PromotedEventCount
+ (QueueExecutionSummary.CompletedEventCount > 0 ? 1 : 0),
0,
3
);
const bool bQueueHistoryPrefersFollowUp =
DominantDeferredLane == EHyperTwistTrainingCoachGuidanceLane::FollowUp
|| (DominantCompletedLane == EHyperTwistTrainingCoachGuidanceLane::FollowUp
&& QueueExecutionSummary.PromotedEventCount > 0);
const bool bQueueHistoryPrefersRecommended =
DominantDeferredLane == EHyperTwistTrainingCoachGuidanceLane::Recommended
|| (DominantCompletedLane == EHyperTwistTrainingCoachGuidanceLane::Recommended
&& QueueExecutionSummary.PromotedEventCount > 0);
if (bQueueHistoryPrefersFollowUp)
{
Snapshot.FollowUpGuidanceContinueBias += FMath::Max(
1,
DeferredRecoverySignal + PromotionRecoverySignal
);
}
if (bQueueHistoryPrefersRecommended)
{
Snapshot.RecommendedGuidanceContinueBias += FMath::Max(
1,
DeferredRecoverySignal + PromotionRecoverySignal
- (QueueExecutionSummary.bHasBlockedFollowUpFriction ? 1 : 0)
);
}
if (!QueueExecutionSummary.FocusDeckId.IsEmpty()
&& (Snapshot.FocusDeckId.IsEmpty() || Snapshot.bNeedsScheduleFrictionRecovery))
{
@ -5221,6 +5317,23 @@ FHyperTwistTrainingCoachMemorySnapshot UHyperTwistTrainingRepositoryLibrary::Der
|| QueueExecutionSummary.bHasOutstandingDeferredWork
|| QueueExecutionSummary.bHasCompletionGap
|| QueueExecutionSummary.bHasRepeatManualRescheduleFriction;
if (bQueueHistoryPrefersFollowUp
&& (QueueExecutionSummary.PromotedEventCount > 0
|| QueueExecutionSummary.bHasBlockedFollowUpFriction
|| QueueExecutionSummary.BlockedFollowUpEventCount > 0))
{
Snapshot.PreferredGuidanceLane = EHyperTwistTrainingCoachGuidanceLane::FollowUp;
Snapshot.PreferredGuidanceSourceLabel = TEXT("coach-memory-queue-follow-up");
}
else if (bQueueHistoryPrefersRecommended
&& Snapshot.PreferredGuidanceLane != EHyperTwistTrainingCoachGuidanceLane::FollowUp
&& (QueueExecutionSummary.PromotedEventCount > 0
|| QueueExecutionSummary.CompletedEventCount > 0))
{
Snapshot.PreferredGuidanceLane = EHyperTwistTrainingCoachGuidanceLane::Recommended;
Snapshot.PreferredGuidanceSourceLabel = TEXT("coach-memory-queue-recommended");
}
}
}