Feed drill-driven handoffs into coach memory

This commit is contained in:
axiomlogicnexus 2026-04-29 03:30:04 +02:00
parent 1502171e79
commit 982e512902
5 changed files with 178 additions and 16 deletions

View file

@ -130,6 +130,18 @@ namespace HyperTwistCoachDashboardWidgetInternal
{
return TEXT("accepted deferred-first recommended handoff history");
}
if (SourceLabel == TEXT("coach-memory-dashboard-method-drill-queued"))
{
return TEXT("accepted drill-driven queued handoff history");
}
if (SourceLabel == TEXT("coach-memory-dashboard-method-drill-follow-up"))
{
return TEXT("accepted drill-driven follow-up handoff history");
}
if (SourceLabel == TEXT("coach-memory-dashboard-method-drill-recommended"))
{
return TEXT("accepted drill-driven recommended handoff history");
}
if (SourceLabel == TEXT("coach-memory-dashboard-queued"))
{
return TEXT("accepted queued handoff history");
@ -174,6 +186,18 @@ namespace HyperTwistCoachDashboardWidgetInternal
{
return TEXT("accepted deferred-first recommended dashboard handoff");
}
if (SourceLabel == TEXT("dashboard-handoff-method-drill-queued"))
{
return TEXT("accepted drill-driven queued dashboard handoff");
}
if (SourceLabel == TEXT("dashboard-handoff-method-drill-follow-up"))
{
return TEXT("accepted drill-driven follow-up dashboard handoff");
}
if (SourceLabel == TEXT("dashboard-handoff-method-drill-recommended"))
{
return TEXT("accepted drill-driven recommended dashboard handoff");
}
if (SourceLabel == TEXT("dashboard-guidance-outcome-deferred-overflow-queued"))
{
return TEXT("accepted deferred-overflow queued outcome handoff");
@ -242,8 +266,24 @@ namespace HyperTwistCoachDashboardWidgetInternal
FString DashboardHandoffSourceLabel(
const EHyperTwistTrainingCoachHandoffKind HandoffKind,
const bool bDeferredFirstSuppressionDriven)
const bool bDeferredFirstSuppressionDriven,
const bool bMethodDrillDriven = false)
{
if (bMethodDrillDriven)
{
switch (HandoffKind)
{
case EHyperTwistTrainingCoachHandoffKind::Queue:
return TEXT("dashboard-handoff-method-drill-queued");
case EHyperTwistTrainingCoachHandoffKind::FollowUp:
return TEXT("dashboard-handoff-method-drill-follow-up");
case EHyperTwistTrainingCoachHandoffKind::Recommended:
return TEXT("dashboard-handoff-method-drill-recommended");
default:
return FString();
}
}
switch (HandoffKind)
{
case EHyperTwistTrainingCoachHandoffKind::Queue:
@ -3989,9 +4029,13 @@ FString UHyperTwistCoachDashboardWidget::ResolveDashboardHandoffStartActionSourc
const bool bUseDeferredFirstSuppressionLabel =
bDisplayedCoachHandoffRecommendationUsedDeferredFirstSuppressionSignal
&& DisplayedCoachHandoffRecommendationKind == HandoffKind;
const bool bUseMethodDrillLabel =
bDisplayedCoachHandoffRecommendationUsedMethodDrillWeighting
&& DisplayedCoachHandoffRecommendationKind == HandoffKind;
return HyperTwistCoachDashboardWidgetInternal::DashboardHandoffSourceLabel(
HandoffKind,
bUseDeferredFirstSuppressionLabel
bUseDeferredFirstSuppressionLabel,
bUseMethodDrillLabel
);
}
@ -5826,6 +5870,7 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
HyperTwistCoachDashboardWidgetInternal::EHandoffRecommendationKind::None;
DisplayedCoachHandoffRecommendationKind = EHyperTwistTrainingCoachHandoffKind::None;
bDisplayedCoachHandoffRecommendationUsedDeferredFirstSuppressionSignal = false;
bDisplayedCoachHandoffRecommendationUsedMethodDrillWeighting = false;
FString CoachHandoffRecommendationStatusLine;
FString CoachHandoffRecommendationDetailLine;
const bool bQueueReadyForHandoff = CachedCoachPanelState.bCanStartQueuedRun;
@ -6161,6 +6206,8 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
}
bDisplayedCoachHandoffRecommendationUsedDeferredFirstSuppressionSignal =
bHandoffRecommendationUsedDeferredFirstSuppressionSignal;
bDisplayedCoachHandoffRecommendationUsedMethodDrillWeighting =
bHandoffRecommendationUsedMethodDrillWeighting;
CoachHandoffRecommendationDetailLine = FString::Printf(
TEXT("Closure continuation bias %d | Closure suppression bias %d | Queue ready: %s | Follow-up ready: %s | Recommended ready: %s | Preferred lane: %s | Memory source: %s%s%s%s%s%s | Launch bias: %s from %s | broadened/tightened history %d/%d | deferred tightened launches %d | deferred launch cases %d%s | Handoff history preferred: %s | accepted q/f/r %d/%d/%d | deferred-overflow accepted q/f/r %d/%d/%d | deferred-first recommendation q/f/r %d/%d/%d | recommended q/f/r %d/%d/%d"),

View file

@ -95,6 +95,18 @@ namespace HyperTwistTrainingCoachLibraryInternal
{
return TEXT("accepted queued handoff history");
}
if (SourceLabel == TEXT("coach-memory-dashboard-method-drill-queued"))
{
return TEXT("accepted drill-driven queued handoff history");
}
if (SourceLabel == TEXT("coach-memory-dashboard-method-drill-follow-up"))
{
return TEXT("accepted drill-driven follow-up handoff history");
}
if (SourceLabel == TEXT("coach-memory-dashboard-method-drill-recommended"))
{
return TEXT("accepted drill-driven recommended handoff history");
}
if (SourceLabel == TEXT("coach-memory-queue-follow-up"))
{
return TEXT("queue follow-up recovery memory");
@ -127,6 +139,18 @@ namespace HyperTwistTrainingCoachLibraryInternal
{
return TEXT("accepted deferred-first recommended dashboard handoff");
}
if (SourceLabel == TEXT("dashboard-handoff-method-drill-queued"))
{
return TEXT("accepted drill-driven queued dashboard handoff");
}
if (SourceLabel == TEXT("dashboard-handoff-method-drill-follow-up"))
{
return TEXT("accepted drill-driven follow-up dashboard handoff");
}
if (SourceLabel == TEXT("dashboard-handoff-method-drill-recommended"))
{
return TEXT("accepted drill-driven recommended dashboard handoff");
}
if (SourceLabel == TEXT("dashboard-guidance-outcome-deferred-overflow-queued"))
{
return TEXT("accepted deferred-overflow queued outcome handoff");

View file

@ -71,23 +71,34 @@ namespace HyperTwistTrainingRepositoryLibraryInternal
|| SourceLabel.StartsWith(TEXT("coach-memory-dashboard-deferred-first-"));
}
bool IsMethodDrillDashboardHandoffSource(const FString& SourceLabel)
{
return SourceLabel == TEXT("dashboard-handoff-method-drill-queued")
|| SourceLabel == TEXT("dashboard-handoff-method-drill-follow-up")
|| SourceLabel == TEXT("dashboard-handoff-method-drill-recommended")
|| SourceLabel.StartsWith(TEXT("coach-memory-dashboard-method-drill-"));
}
EHyperTwistTrainingCoachHandoffKind DashboardHandoffKindFromSourceLabel(const FString& SourceLabel)
{
if (SourceLabel == TEXT("dashboard-handoff-queued")
|| SourceLabel == TEXT("dashboard-guidance-outcome-deferred-overflow-queued")
|| SourceLabel == TEXT("dashboard-handoff-deferred-first-queued"))
|| SourceLabel == TEXT("dashboard-handoff-deferred-first-queued")
|| SourceLabel == TEXT("dashboard-handoff-method-drill-queued"))
{
return EHyperTwistTrainingCoachHandoffKind::Queue;
}
if (SourceLabel == TEXT("dashboard-handoff-follow-up")
|| SourceLabel == TEXT("dashboard-guidance-outcome-deferred-overflow-follow-up")
|| SourceLabel == TEXT("dashboard-handoff-deferred-first-follow-up"))
|| SourceLabel == TEXT("dashboard-handoff-deferred-first-follow-up")
|| SourceLabel == TEXT("dashboard-handoff-method-drill-follow-up"))
{
return EHyperTwistTrainingCoachHandoffKind::FollowUp;
}
if (SourceLabel == TEXT("dashboard-handoff-recommended")
|| SourceLabel == TEXT("dashboard-guidance-outcome-deferred-overflow-recommended")
|| SourceLabel == TEXT("dashboard-handoff-deferred-first-recommended"))
|| SourceLabel == TEXT("dashboard-handoff-deferred-first-recommended")
|| SourceLabel == TEXT("dashboard-handoff-method-drill-recommended"))
{
return EHyperTwistTrainingCoachHandoffKind::Recommended;
}
@ -98,12 +109,17 @@ namespace HyperTwistTrainingRepositoryLibraryInternal
FString CoachMemoryDashboardSourceLabel(
const EHyperTwistTrainingCoachHandoffKind HandoffKind,
const bool bDeferredOverflowDriven,
const bool bDeferredFirstDriven = false
const bool bDeferredFirstDriven = false,
const bool bMethodDrillDriven = false
)
{
switch (HandoffKind)
{
case EHyperTwistTrainingCoachHandoffKind::Queue:
if (bMethodDrillDriven)
{
return TEXT("coach-memory-dashboard-method-drill-queued");
}
if (bDeferredFirstDriven)
{
return TEXT("coach-memory-dashboard-deferred-first-queued");
@ -112,6 +128,10 @@ namespace HyperTwistTrainingRepositoryLibraryInternal
? TEXT("coach-memory-dashboard-deferred-overflow-queued")
: TEXT("coach-memory-dashboard-queued");
case EHyperTwistTrainingCoachHandoffKind::FollowUp:
if (bMethodDrillDriven)
{
return TEXT("coach-memory-dashboard-method-drill-follow-up");
}
if (bDeferredFirstDriven)
{
return TEXT("coach-memory-dashboard-deferred-first-follow-up");
@ -120,6 +140,10 @@ namespace HyperTwistTrainingRepositoryLibraryInternal
? TEXT("coach-memory-dashboard-deferred-overflow-follow-up")
: TEXT("coach-memory-dashboard-follow-up");
case EHyperTwistTrainingCoachHandoffKind::Recommended:
if (bMethodDrillDriven)
{
return TEXT("coach-memory-dashboard-method-drill-recommended");
}
if (bDeferredFirstDriven)
{
return TEXT("coach-memory-dashboard-deferred-first-recommended");
@ -469,6 +493,21 @@ namespace HyperTwistTrainingRepositoryLibraryInternal
0,
4
);
const int32 ExplicitMethodDrillQueuedHandoffSignal = FMath::Clamp(
QueueExecutionSummary.StartedMethodDrillQueuedHandoffEventCount * 2,
0,
4
);
const int32 ExplicitMethodDrillFollowUpHandoffSignal = FMath::Clamp(
QueueExecutionSummary.StartedMethodDrillFollowUpHandoffEventCount * 2,
0,
4
);
const int32 ExplicitMethodDrillRecommendedHandoffSignal = FMath::Clamp(
QueueExecutionSummary.StartedMethodDrillRecommendedHandoffEventCount * 2,
0,
4
);
if (ExplicitQueuedHandoffSignal > 0
|| ExplicitFollowUpHandoffSignal > 0
|| ExplicitRecommendedHandoffSignal > 0)
@ -481,7 +520,8 @@ namespace HyperTwistTrainingRepositoryLibraryInternal
HyperTwistTrainingRepositoryLibraryInternal::CoachMemoryDashboardSourceLabel(
EHyperTwistTrainingCoachHandoffKind::Queue,
ExplicitDeferredOverflowQueuedHandoffSignal > 0,
ExplicitDeferredFirstQueuedHandoffSignal > 0
ExplicitDeferredFirstQueuedHandoffSignal > 0,
ExplicitMethodDrillQueuedHandoffSignal > 0
);
}
else if (ExplicitFollowUpHandoffSignal >= ExplicitRecommendedHandoffSignal)
@ -491,7 +531,8 @@ namespace HyperTwistTrainingRepositoryLibraryInternal
HyperTwistTrainingRepositoryLibraryInternal::CoachMemoryDashboardSourceLabel(
EHyperTwistTrainingCoachHandoffKind::FollowUp,
ExplicitDeferredOverflowFollowUpHandoffSignal > 0,
ExplicitDeferredFirstFollowUpHandoffSignal > 0
ExplicitDeferredFirstFollowUpHandoffSignal > 0,
ExplicitMethodDrillFollowUpHandoffSignal > 0
);
}
else
@ -501,7 +542,8 @@ namespace HyperTwistTrainingRepositoryLibraryInternal
HyperTwistTrainingRepositoryLibraryInternal::CoachMemoryDashboardSourceLabel(
EHyperTwistTrainingCoachHandoffKind::Recommended,
ExplicitDeferredOverflowRecommendedHandoffSignal > 0,
ExplicitDeferredFirstRecommendedHandoffSignal > 0
ExplicitDeferredFirstRecommendedHandoffSignal > 0,
ExplicitMethodDrillRecommendedHandoffSignal > 0
);
}
}
@ -510,12 +552,15 @@ namespace HyperTwistTrainingRepositoryLibraryInternal
+ ExplicitFollowUpHandoffSignal
+ ExplicitDeferredOverflowFollowUpHandoffSignal
+ ExplicitDeferredFirstQueuedHandoffSignal
+ ExplicitDeferredFirstFollowUpHandoffSignal;
+ ExplicitDeferredFirstFollowUpHandoffSignal
+ ExplicitMethodDrillQueuedHandoffSignal
+ ExplicitMethodDrillFollowUpHandoffSignal;
const int32 WeightedRecommendedRecoverySignal =
ExplicitRecommendedRecoverySignal
+ ExplicitRecommendedHandoffSignal
+ ExplicitDeferredOverflowRecommendedHandoffSignal
+ ExplicitDeferredFirstRecommendedHandoffSignal;
+ ExplicitDeferredFirstRecommendedHandoffSignal
+ ExplicitMethodDrillRecommendedHandoffSignal;
const bool bQueueHistoryPrefersFollowUp =
DominantDeferredLane == EHyperTwistTrainingCoachGuidanceLane::FollowUp
|| (DominantCompletedLane == EHyperTwistTrainingCoachGuidanceLane::FollowUp
@ -6406,6 +6451,21 @@ FHyperTwistTrainingCoachMemorySnapshot UHyperTwistTrainingRepositoryLibrary::Der
0,
4
);
const int32 ExplicitMethodDrillQueuedHandoffSignal = FMath::Clamp(
QueueExecutionSummary.StartedMethodDrillQueuedHandoffEventCount * 2,
0,
4
);
const int32 ExplicitMethodDrillFollowUpHandoffSignal = FMath::Clamp(
QueueExecutionSummary.StartedMethodDrillFollowUpHandoffEventCount * 2,
0,
4
);
const int32 ExplicitMethodDrillRecommendedHandoffSignal = FMath::Clamp(
QueueExecutionSummary.StartedMethodDrillRecommendedHandoffEventCount * 2,
0,
4
);
if (ExplicitQueuedHandoffSignal > 0
|| ExplicitFollowUpHandoffSignal > 0
|| ExplicitRecommendedHandoffSignal > 0)
@ -6418,7 +6478,8 @@ FHyperTwistTrainingCoachMemorySnapshot UHyperTwistTrainingRepositoryLibrary::Der
HyperTwistTrainingRepositoryLibraryInternal::CoachMemoryDashboardSourceLabel(
EHyperTwistTrainingCoachHandoffKind::Queue,
ExplicitDeferredOverflowQueuedHandoffSignal > 0,
ExplicitDeferredFirstQueuedHandoffSignal > 0
ExplicitDeferredFirstQueuedHandoffSignal > 0,
ExplicitMethodDrillQueuedHandoffSignal > 0
);
}
else if (ExplicitFollowUpHandoffSignal >= ExplicitRecommendedHandoffSignal)
@ -6428,7 +6489,8 @@ FHyperTwistTrainingCoachMemorySnapshot UHyperTwistTrainingRepositoryLibrary::Der
HyperTwistTrainingRepositoryLibraryInternal::CoachMemoryDashboardSourceLabel(
EHyperTwistTrainingCoachHandoffKind::FollowUp,
ExplicitDeferredOverflowFollowUpHandoffSignal > 0,
ExplicitDeferredFirstFollowUpHandoffSignal > 0
ExplicitDeferredFirstFollowUpHandoffSignal > 0,
ExplicitMethodDrillFollowUpHandoffSignal > 0
);
}
else
@ -6438,7 +6500,8 @@ FHyperTwistTrainingCoachMemorySnapshot UHyperTwistTrainingRepositoryLibrary::Der
HyperTwistTrainingRepositoryLibraryInternal::CoachMemoryDashboardSourceLabel(
EHyperTwistTrainingCoachHandoffKind::Recommended,
ExplicitDeferredOverflowRecommendedHandoffSignal > 0,
ExplicitDeferredFirstRecommendedHandoffSignal > 0
ExplicitDeferredFirstRecommendedHandoffSignal > 0,
ExplicitMethodDrillRecommendedHandoffSignal > 0
);
}
}
@ -6447,12 +6510,15 @@ FHyperTwistTrainingCoachMemorySnapshot UHyperTwistTrainingRepositoryLibrary::Der
+ ExplicitFollowUpHandoffSignal
+ ExplicitDeferredOverflowFollowUpHandoffSignal
+ ExplicitDeferredFirstQueuedHandoffSignal
+ ExplicitDeferredFirstFollowUpHandoffSignal;
+ ExplicitDeferredFirstFollowUpHandoffSignal
+ ExplicitMethodDrillQueuedHandoffSignal
+ ExplicitMethodDrillFollowUpHandoffSignal;
const int32 WeightedRecommendedRecoverySignal =
ExplicitRecommendedRecoverySignal
+ ExplicitRecommendedHandoffSignal
+ ExplicitDeferredOverflowRecommendedHandoffSignal
+ ExplicitDeferredFirstRecommendedHandoffSignal;
+ ExplicitDeferredFirstRecommendedHandoffSignal
+ ExplicitMethodDrillRecommendedHandoffSignal;
const bool bQueueHistoryPrefersFollowUp =
DominantDeferredLane == EHyperTwistTrainingCoachGuidanceLane::FollowUp
|| (DominantCompletedLane == EHyperTwistTrainingCoachGuidanceLane::FollowUp
@ -8316,6 +8382,9 @@ FHyperTwistTrainingCoachSessionQueueExecutionSummary UHyperTwistTrainingReposito
const bool bDeferredFirstDashboardHandoff =
HyperTwistTrainingRepositoryLibraryInternal::IsDeferredFirstDashboardHandoffSource(
HistoryEntry.StartActionSourceLabel);
const bool bMethodDrillDashboardHandoff =
HyperTwistTrainingRepositoryLibraryInternal::IsMethodDrillDashboardHandoffSource(
HistoryEntry.StartActionSourceLabel);
if (DashboardHandoffKind == EHyperTwistTrainingCoachHandoffKind::Queue)
{
Summary.StartedQueuedHandoffEventCount += 1;
@ -8327,6 +8396,10 @@ FHyperTwistTrainingCoachSessionQueueExecutionSummary UHyperTwistTrainingReposito
{
Summary.StartedDeferredFirstQueuedHandoffEventCount += 1;
}
if (bMethodDrillDashboardHandoff)
{
Summary.StartedMethodDrillQueuedHandoffEventCount += 1;
}
}
else if (DashboardHandoffKind == EHyperTwistTrainingCoachHandoffKind::FollowUp)
{
@ -8339,6 +8412,10 @@ FHyperTwistTrainingCoachSessionQueueExecutionSummary UHyperTwistTrainingReposito
{
Summary.StartedDeferredFirstFollowUpHandoffEventCount += 1;
}
if (bMethodDrillDashboardHandoff)
{
Summary.StartedMethodDrillFollowUpHandoffEventCount += 1;
}
}
else if (DashboardHandoffKind == EHyperTwistTrainingCoachHandoffKind::Recommended)
{
@ -8351,6 +8428,10 @@ FHyperTwistTrainingCoachSessionQueueExecutionSummary UHyperTwistTrainingReposito
{
Summary.StartedDeferredFirstRecommendedHandoffEventCount += 1;
}
if (bMethodDrillDashboardHandoff)
{
Summary.StartedMethodDrillRecommendedHandoffEventCount += 1;
}
}
if (Summary.LastStartedAtUtc.IsEmpty()
|| HyperTwistTrainingRepositoryLibraryInternal::CompareUtcStrings(

View file

@ -1316,6 +1316,7 @@ private:
EHyperTwistTrainingCoachHandoffKind DisplayedCoachHandoffRecommendationKind =
EHyperTwistTrainingCoachHandoffKind::None;
bool bDisplayedCoachHandoffRecommendationUsedDeferredFirstSuppressionSignal = false;
bool bDisplayedCoachHandoffRecommendationUsedMethodDrillWeighting = false;
EHyperTwistCoachDashboardGuidancePreviewLane ActiveGuidancePreviewLane =
EHyperTwistCoachDashboardGuidancePreviewLane::None;
int32 SelectedGuidancePreviewCaseIndex = INDEX_NONE;

View file

@ -3648,6 +3648,15 @@ struct FHyperTwistTrainingCoachSessionQueueExecutionSummary
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
int32 StartedDeferredFirstRecommendedHandoffEventCount = 0;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
int32 StartedMethodDrillQueuedHandoffEventCount = 0;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
int32 StartedMethodDrillFollowUpHandoffEventCount = 0;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
int32 StartedMethodDrillRecommendedHandoffEventCount = 0;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
int32 PromotedFollowUpEventCount = 0;