Explain coach handoff memory in UI
This commit is contained in:
parent
a6288a882a
commit
d0a55eca5a
2 changed files with 184 additions and 37 deletions
|
|
@ -39,6 +39,55 @@ namespace HyperTwistCoachDashboardWidgetInternal
|
|||
return TEXT("Unknown");
|
||||
}
|
||||
|
||||
bool IsDashboardHandoffGuidanceSource(const FString& SourceLabel)
|
||||
{
|
||||
return SourceLabel.StartsWith(TEXT("coach-memory-dashboard-"));
|
||||
}
|
||||
|
||||
bool IsQueueRecoveryMemorySource(const FString& SourceLabel)
|
||||
{
|
||||
return SourceLabel.StartsWith(TEXT("coach-memory-queue-"))
|
||||
|| IsDashboardHandoffGuidanceSource(SourceLabel);
|
||||
}
|
||||
|
||||
FString DescribeCoachMemorySourceLabel(const FString& SourceLabel)
|
||||
{
|
||||
if (SourceLabel == TEXT("coach-memory-dashboard-follow-up"))
|
||||
{
|
||||
return TEXT("accepted follow-up handoff history");
|
||||
}
|
||||
if (SourceLabel == TEXT("coach-memory-dashboard-recommended"))
|
||||
{
|
||||
return TEXT("accepted recommended handoff history");
|
||||
}
|
||||
if (SourceLabel == TEXT("coach-memory-queue-follow-up"))
|
||||
{
|
||||
return TEXT("queue follow-up recovery memory");
|
||||
}
|
||||
if (SourceLabel == TEXT("coach-memory-queue-recommended"))
|
||||
{
|
||||
return TEXT("queue recommended recovery memory");
|
||||
}
|
||||
if (SourceLabel == TEXT("dashboard-handoff-queued"))
|
||||
{
|
||||
return TEXT("accepted queued dashboard handoff");
|
||||
}
|
||||
if (SourceLabel == TEXT("queue-history-promote-pressure"))
|
||||
{
|
||||
return TEXT("queue promote-pressure history");
|
||||
}
|
||||
if (SourceLabel == TEXT("queue-history-launch-pressure"))
|
||||
{
|
||||
return TEXT("queue launch-pressure history");
|
||||
}
|
||||
if (SourceLabel == TEXT("queue-history-balanced-pressure"))
|
||||
{
|
||||
return TEXT("balanced queue-recovery history");
|
||||
}
|
||||
|
||||
return SourceLabel.IsEmpty() ? TEXT("n/a") : SourceLabel;
|
||||
}
|
||||
|
||||
UTextBlock* AddTextRow(
|
||||
UWidgetTree* WidgetTree,
|
||||
UVerticalBox* Parent,
|
||||
|
|
@ -333,7 +382,8 @@ bool UHyperTwistCoachDashboardWidget::ApplyQueueRecoveryPosture()
|
|||
|
||||
const FString DeferredEntryId = FindFirstDeferredQueueEntryId();
|
||||
const bool bQueueRecoveryMemorySource =
|
||||
CachedCoachPanelState.PreferredGuidanceSourceLabel.StartsWith(TEXT("coach-memory-queue-"));
|
||||
HyperTwistCoachDashboardWidgetInternal::IsQueueRecoveryMemorySource(
|
||||
CachedCoachPanelState.PreferredGuidanceSourceLabel);
|
||||
const bool bPrefersFollowUp =
|
||||
CachedCoachPanelState.PreferredGuidanceLane == EHyperTwistTrainingCoachGuidanceLane::FollowUp;
|
||||
const bool bPrefersRecommended =
|
||||
|
|
@ -4301,6 +4351,12 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
|
|||
HyperTwistCoachDashboardWidgetInternal::DeriveClosureRecoveryDashboardBias(
|
||||
ClosureRecoveryHistoryEntries
|
||||
);
|
||||
const FString HandoffMemorySourceLabel =
|
||||
HyperTwistCoachDashboardWidgetInternal::DescribeCoachMemorySourceLabel(
|
||||
CachedCoachPanelState.PreferredGuidanceSourceLabel);
|
||||
const bool bDashboardHandoffMemorySource =
|
||||
HyperTwistCoachDashboardWidgetInternal::IsDashboardHandoffGuidanceSource(
|
||||
CachedCoachPanelState.PreferredGuidanceSourceLabel);
|
||||
const bool bQueueLooksFollowUpOrRecovery =
|
||||
CachedCoachPanelState.NextQueueSourceLabel.Contains(TEXT("follow-up"))
|
||||
|| CachedCoachPanelState.NextQueueSourceLabel.Contains(TEXT("queue-recovery"))
|
||||
|
|
@ -4402,7 +4458,7 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
|
|||
}
|
||||
|
||||
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"),
|
||||
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"),
|
||||
HandoffClosureBias.ContinuationBias,
|
||||
HandoffClosureBias.SuppressionBias,
|
||||
CachedCoachPanelState.bCanStartQueuedRun ? TEXT("yes") : TEXT("no"),
|
||||
|
|
@ -4415,7 +4471,11 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
|
|||
: (CachedCoachPanelState.PreferredGuidanceLane
|
||||
== EHyperTwistTrainingCoachGuidanceLane::Recommended
|
||||
? TEXT("recommended")
|
||||
: TEXT("none"))
|
||||
: TEXT("none")),
|
||||
*HandoffMemorySourceLabel,
|
||||
bDashboardHandoffMemorySource
|
||||
? TEXT(" | Accepted dashboard handoffs are actively reinforcing this recommendation.")
|
||||
: TEXT("")
|
||||
);
|
||||
}
|
||||
FString QueuedRunLabel = CachedCoachPanelState.NextQueueSourceLabel.IsEmpty()
|
||||
|
|
@ -4524,7 +4584,8 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
|
|||
? TEXT("closure-history + memory")
|
||||
: (CachedCoachPanelState.PreferredGuidanceSourceLabel.IsEmpty()
|
||||
? TEXT("availability fallback")
|
||||
: CachedCoachPanelState.PreferredGuidanceSourceLabel));
|
||||
: HyperTwistCoachDashboardWidgetInternal::DescribeCoachMemorySourceLabel(
|
||||
CachedCoachPanelState.PreferredGuidanceSourceLabel)));
|
||||
const FString GuidancePreferenceStatusLine =
|
||||
GuidanceLanePreference.IsStructurallyValid()
|
||||
? FString::Printf(
|
||||
|
|
@ -4549,7 +4610,8 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
|
|||
)
|
||||
: TEXT("Preference detail: build recommended or follow-up guidance to let the dashboard choose a next surfaced lane.");
|
||||
const bool bQueueRecoveryMemorySource =
|
||||
CachedCoachPanelState.PreferredGuidanceSourceLabel.StartsWith(TEXT("coach-memory-queue-"));
|
||||
HyperTwistCoachDashboardWidgetInternal::IsQueueRecoveryMemorySource(
|
||||
CachedCoachPanelState.PreferredGuidanceSourceLabel);
|
||||
const bool bQueueRecoveryFollowUp =
|
||||
CachedCoachPanelState.PreferredGuidanceLane == EHyperTwistTrainingCoachGuidanceLane::FollowUp;
|
||||
const bool bQueueRecoveryRecommended =
|
||||
|
|
@ -4560,13 +4622,14 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
|
|||
: (bQueueRecoveryRecommended
|
||||
? TEXT("recommended")
|
||||
: TEXT("none"));
|
||||
const FString QueueRecoverySourceLabel = CachedCoachPanelState.PreferredGuidanceSourceLabel.IsEmpty()
|
||||
? TEXT("n/a")
|
||||
: CachedCoachPanelState.PreferredGuidanceSourceLabel;
|
||||
const FString QueueRecoverySourceLabel =
|
||||
HyperTwistCoachDashboardWidgetInternal::DescribeCoachMemorySourceLabel(
|
||||
CachedCoachPanelState.PreferredGuidanceSourceLabel);
|
||||
const FString QueueRecoveryActionSourceLabel =
|
||||
CachedCoachPanelState.PreferredQueueRecoveryActionSourceLabel.IsEmpty()
|
||||
? TEXT("n/a")
|
||||
: CachedCoachPanelState.PreferredQueueRecoveryActionSourceLabel;
|
||||
: HyperTwistCoachDashboardWidgetInternal::DescribeCoachMemorySourceLabel(
|
||||
CachedCoachPanelState.PreferredQueueRecoveryActionSourceLabel);
|
||||
const FHyperTwistCoachDashboardQueueRecoveryWeighting QueueRecoveryWeighting = BuildQueueRecoveryWeighting();
|
||||
const bool bCanLaunchQueueRecovery =
|
||||
CachedCoachPanelState.bCanStartQueuedRun
|
||||
|
|
@ -4875,7 +4938,7 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
|
|||
const FString GuidanceRationaleDetailLine =
|
||||
ActivePreviewBrief != nullptr
|
||||
? FString::Printf(
|
||||
TEXT("Brief: %s | Action: %s | Deck: %s | Method: %s | Focus cases: %d | Review: %s | Cadence: %s | Variety: %s | Selected focus: %s | Matching signals: %d | Case signal: %s | Top signals: %s"),
|
||||
TEXT("Brief: %s | Action: %s | Deck: %s | Method: %s | Focus cases: %d | Review: %s | Cadence: %s | Variety: %s | Guidance source: %s | Selected focus: %s | Matching signals: %d | Case signal: %s | Top signals: %s"),
|
||||
ActivePreviewBrief->Headline.IsEmpty() ? TEXT("n/a") : *ActivePreviewBrief->Headline,
|
||||
ActivePreviewBrief->PrimaryActionLabel.IsEmpty() ? TEXT("n/a") : *ActivePreviewBrief->PrimaryActionLabel,
|
||||
ActivePreviewBrief->FocusDeckId.IsEmpty() ? TEXT("n/a") : *ActivePreviewBrief->FocusDeckId,
|
||||
|
|
@ -4884,6 +4947,8 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
|
|||
ActivePreviewBrief->bNeedsCoachReview ? TEXT("yes") : TEXT("no"),
|
||||
ActivePreviewBrief->bNeedsCadenceRecovery ? TEXT("yes") : TEXT("no"),
|
||||
ActivePreviewBrief->bNeedsVarietyRotation ? TEXT("yes") : TEXT("no"),
|
||||
*HyperTwistCoachDashboardWidgetInternal::DescribeCoachMemorySourceLabel(
|
||||
CachedCoachPanelState.PreferredGuidanceSourceLabel),
|
||||
bSelectedPreviewCaseIsExplicitFocus ? TEXT("yes") : TEXT("no"),
|
||||
SelectedPreviewCaseSignalCount,
|
||||
*SelectedPreviewCaseSignalLine,
|
||||
|
|
@ -5901,9 +5966,8 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
|
|||
? TEXT("yes")
|
||||
: TEXT("no"),
|
||||
*ClosureGuidanceLaneLabel,
|
||||
CachedCoachPanelState.PreferredGuidanceSourceLabel.IsEmpty()
|
||||
? TEXT("n/a")
|
||||
: *CachedCoachPanelState.PreferredGuidanceSourceLabel,
|
||||
*HyperTwistCoachDashboardWidgetInternal::DescribeCoachMemorySourceLabel(
|
||||
CachedCoachPanelState.PreferredGuidanceSourceLabel),
|
||||
ClosureRecoverySignal != nullptr ? TEXT(" || Signal detail: ") : TEXT(""),
|
||||
ClosureRecoverySignal != nullptr
|
||||
? *ClosureRecoverySignal->Detail
|
||||
|
|
@ -5950,9 +6014,8 @@ void UHyperTwistCoachDashboardWidget::UpdateDashboardPresentation()
|
|||
SelectedClosureRecoveryEntry->bBorderlineFollowUpSuppressedByRecoveryHistory
|
||||
? TEXT("yes")
|
||||
: TEXT("no"),
|
||||
SelectedClosureRecoveryEntry->PreferredGuidanceSourceLabel.IsEmpty()
|
||||
? TEXT("n/a")
|
||||
: *SelectedClosureRecoveryEntry->PreferredGuidanceSourceLabel,
|
||||
*HyperTwistCoachDashboardWidgetInternal::DescribeCoachMemorySourceLabel(
|
||||
SelectedClosureRecoveryEntry->PreferredGuidanceSourceLabel),
|
||||
SelectedClosureRecoveryEntry->bActiveSignalPromoted ? TEXT("yes") : TEXT("no"),
|
||||
SelectedClosureRecoveryEntry->ActiveSignalHeadline.IsEmpty()
|
||||
? TEXT("n/a")
|
||||
|
|
|
|||
|
|
@ -18,6 +18,55 @@ namespace HyperTwistTrainingCoachLibraryInternal
|
|||
return EHyperTwistTrainingCoachGuidanceLane::None;
|
||||
}
|
||||
|
||||
bool IsDashboardHandoffGuidanceSource(const FString& SourceLabel)
|
||||
{
|
||||
return SourceLabel.StartsWith(TEXT("coach-memory-dashboard-"));
|
||||
}
|
||||
|
||||
bool IsQueueRecoveryMemorySource(const FString& SourceLabel)
|
||||
{
|
||||
return SourceLabel.StartsWith(TEXT("coach-memory-queue-"))
|
||||
|| IsDashboardHandoffGuidanceSource(SourceLabel);
|
||||
}
|
||||
|
||||
FString DescribeCoachMemorySourceLabel(const FString& SourceLabel)
|
||||
{
|
||||
if (SourceLabel == TEXT("coach-memory-dashboard-follow-up"))
|
||||
{
|
||||
return TEXT("accepted follow-up handoff history");
|
||||
}
|
||||
if (SourceLabel == TEXT("coach-memory-dashboard-recommended"))
|
||||
{
|
||||
return TEXT("accepted recommended handoff history");
|
||||
}
|
||||
if (SourceLabel == TEXT("coach-memory-queue-follow-up"))
|
||||
{
|
||||
return TEXT("queue follow-up recovery memory");
|
||||
}
|
||||
if (SourceLabel == TEXT("coach-memory-queue-recommended"))
|
||||
{
|
||||
return TEXT("queue recommended recovery memory");
|
||||
}
|
||||
if (SourceLabel == TEXT("dashboard-handoff-queued"))
|
||||
{
|
||||
return TEXT("accepted queued dashboard handoff");
|
||||
}
|
||||
if (SourceLabel == TEXT("queue-history-promote-pressure"))
|
||||
{
|
||||
return TEXT("queue promote-pressure history");
|
||||
}
|
||||
if (SourceLabel == TEXT("queue-history-launch-pressure"))
|
||||
{
|
||||
return TEXT("queue launch-pressure history");
|
||||
}
|
||||
if (SourceLabel == TEXT("queue-history-balanced-pressure"))
|
||||
{
|
||||
return TEXT("balanced queue-recovery history");
|
||||
}
|
||||
|
||||
return SourceLabel.IsEmpty() ? TEXT("none") : SourceLabel;
|
||||
}
|
||||
|
||||
float ResolvePreferredGuidanceLanePressure(
|
||||
const FHyperTwistTrainingCoachMemorySnapshot& CoachMemorySnapshot)
|
||||
{
|
||||
|
|
@ -531,13 +580,18 @@ TArray<FHyperTwistCoachSignal> UHyperTwistTrainingCoachLibrary::DeriveCoachSigna
|
|||
const bool bBlockedFollowUp = CoachMemorySnapshot.bHasBlockedFollowUpScheduleFriction;
|
||||
const bool bRepeatManualReschedule = CoachMemorySnapshot.bHasRepeatManualScheduleFriction;
|
||||
const bool bQueueRecoverySource =
|
||||
CoachMemorySnapshot.PreferredGuidanceSourceLabel.StartsWith(TEXT("coach-memory-queue-"));
|
||||
HyperTwistTrainingCoachLibraryInternal::IsQueueRecoveryMemorySource(
|
||||
CoachMemorySnapshot.PreferredGuidanceSourceLabel);
|
||||
const bool bQueueRecoveryFollowUp =
|
||||
bQueueRecoverySource
|
||||
&& CoachMemorySnapshot.PreferredGuidanceLane == EHyperTwistTrainingCoachGuidanceLane::FollowUp;
|
||||
const bool bQueueRecoveryRecommended =
|
||||
bQueueRecoverySource
|
||||
&& CoachMemorySnapshot.PreferredGuidanceLane == EHyperTwistTrainingCoachGuidanceLane::Recommended;
|
||||
const bool bDashboardFollowUpRecovery =
|
||||
CoachMemorySnapshot.PreferredGuidanceSourceLabel == TEXT("coach-memory-dashboard-follow-up");
|
||||
const bool bDashboardRecommendedRecovery =
|
||||
CoachMemorySnapshot.PreferredGuidanceSourceLabel == TEXT("coach-memory-dashboard-recommended");
|
||||
const bool bPromoteQueueRecovery =
|
||||
CoachMemorySnapshot.PreferredQueueRecoveryAction
|
||||
== EHyperTwistTrainingQueueRecoveryAction::PromoteDeferred;
|
||||
|
|
@ -550,33 +604,61 @@ TArray<FHyperTwistCoachSignal> UHyperTwistTrainingCoachLibrary::DeriveCoachSigna
|
|||
+ (bBlockedFollowUp ? 6.0f : 0.0f)
|
||||
+ (bRepeatManualReschedule ? 5.0f : 0.0f)
|
||||
+ (CoachMemorySnapshot.bHasQueueExecutionCompletionGap ? 4.0f : 0.0f)
|
||||
+ (bQueueRecoverySource ? 2.0f : 0.0f);
|
||||
+ (bQueueRecoverySource ? 2.0f : 0.0f)
|
||||
+ ((bDashboardFollowUpRecovery || bDashboardRecommendedRecovery) ? 2.0f : 0.0f);
|
||||
|
||||
const EHyperTwistCoachFocusLane FocusLane = bArchiveAware
|
||||
? EHyperTwistCoachFocusLane::Stability
|
||||
: EHyperTwistCoachFocusLane::Cadence;
|
||||
const FString Headline = bQueueRecoveryFollowUp
|
||||
? (bPromoteQueueRecovery
|
||||
FString Headline;
|
||||
if (bDashboardFollowUpRecovery)
|
||||
{
|
||||
Headline = bPromoteQueueRecovery
|
||||
? TEXT("Accepted follow-up handoffs keep the deferred follow-up lane active")
|
||||
: TEXT("Accepted follow-up handoffs favor recovering the follow-up lane next");
|
||||
}
|
||||
else if (bDashboardRecommendedRecovery)
|
||||
{
|
||||
Headline = bPromoteQueueRecovery
|
||||
? TEXT("Accepted recommended handoffs keep the deferred recommended lane active")
|
||||
: TEXT("Accepted recommended handoffs favor restoring the recommended lane next");
|
||||
}
|
||||
else if (bQueueRecoveryFollowUp)
|
||||
{
|
||||
Headline = bPromoteQueueRecovery
|
||||
? TEXT("Promote the deferred follow-up lane back into active queue flow")
|
||||
: TEXT("Recover the deferred follow-up lane before the queue drifts further"))
|
||||
: (bQueueRecoveryRecommended
|
||||
? (bPromoteQueueRecovery
|
||||
? TEXT("Promote the deferred recommended lane back into the active queue")
|
||||
: TEXT("Recover the deferred recommended lane and restore queue cadence"))
|
||||
: (bBlockedFollowUp
|
||||
? (bPromoteQueueRecovery
|
||||
? TEXT("Promote deferred work to relieve follow-up scheduling friction")
|
||||
: TEXT("Follow-up scheduling friction is stalling the queue"))
|
||||
: (bArchiveAware
|
||||
? TEXT("Archive-aware scheduling friction needs cleanup")
|
||||
: (bLaunchQueueRecovery
|
||||
? TEXT("Launch recovery work to restore coaching queue cadence")
|
||||
: TEXT("Coaching queue scheduling needs intervention")))));
|
||||
: TEXT("Recover the deferred follow-up lane before the queue drifts further");
|
||||
}
|
||||
else if (bQueueRecoveryRecommended)
|
||||
{
|
||||
Headline = bPromoteQueueRecovery
|
||||
? TEXT("Promote the deferred recommended lane back into the active queue")
|
||||
: TEXT("Recover the deferred recommended lane and restore queue cadence");
|
||||
}
|
||||
else if (bBlockedFollowUp)
|
||||
{
|
||||
Headline = bPromoteQueueRecovery
|
||||
? TEXT("Promote deferred work to relieve follow-up scheduling friction")
|
||||
: TEXT("Follow-up scheduling friction is stalling the queue");
|
||||
}
|
||||
else if (bArchiveAware)
|
||||
{
|
||||
Headline = TEXT("Archive-aware scheduling friction needs cleanup");
|
||||
}
|
||||
else if (bLaunchQueueRecovery)
|
||||
{
|
||||
Headline = TEXT("Launch recovery work to restore coaching queue cadence");
|
||||
}
|
||||
else
|
||||
{
|
||||
Headline = TEXT("Coaching queue scheduling needs intervention");
|
||||
}
|
||||
const FString DeferralReasonLabel = !CoachMemorySnapshot.DominantScheduleDeferralReasonLabel.IsEmpty()
|
||||
? CoachMemorySnapshot.DominantScheduleDeferralReasonLabel
|
||||
: TEXT("none");
|
||||
const FString RecoverySourceLabel = bQueueRecoverySource
|
||||
? CoachMemorySnapshot.PreferredGuidanceSourceLabel
|
||||
? HyperTwistTrainingCoachLibraryInternal::DescribeCoachMemorySourceLabel(
|
||||
CoachMemorySnapshot.PreferredGuidanceSourceLabel)
|
||||
: TEXT("none");
|
||||
const FString RecoveryActionLabel =
|
||||
CoachMemorySnapshot.PreferredQueueRecoveryAction == EHyperTwistTrainingQueueRecoveryAction::PromoteDeferred
|
||||
|
|
@ -588,7 +670,8 @@ TArray<FHyperTwistCoachSignal> UHyperTwistTrainingCoachLibrary::DeriveCoachSigna
|
|||
const FString RecoveryActionSourceLabel =
|
||||
CoachMemorySnapshot.PreferredQueueRecoveryActionSourceLabel.IsEmpty()
|
||||
? TEXT("none")
|
||||
: CoachMemorySnapshot.PreferredQueueRecoveryActionSourceLabel;
|
||||
: HyperTwistTrainingCoachLibraryInternal::DescribeCoachMemorySourceLabel(
|
||||
CoachMemorySnapshot.PreferredQueueRecoveryActionSourceLabel);
|
||||
const FString SignalId = bQueueRecoveryFollowUp
|
||||
? (bPromoteQueueRecovery
|
||||
? TEXT("schedule_friction_follow_up_promote_recovery")
|
||||
|
|
@ -1556,7 +1639,8 @@ FHyperTwistCoachSignal UHyperTwistTrainingCoachLibrary::DeriveClosureRecoveryHis
|
|||
CoachMemorySnapshot.FollowUpReadyCoachSequenceCount,
|
||||
CoachMemorySnapshot.PreferredGuidanceSourceLabel.IsEmpty()
|
||||
? TEXT("n/a")
|
||||
: *CoachMemorySnapshot.PreferredGuidanceSourceLabel
|
||||
: *HyperTwistTrainingCoachLibraryInternal::DescribeCoachMemorySourceLabel(
|
||||
CoachMemorySnapshot.PreferredGuidanceSourceLabel)
|
||||
);
|
||||
const EHyperTwistTrainingDeliveryMode SuggestedMode = bHistoryPrefersFollowUp
|
||||
? EHyperTwistTrainingDeliveryMode::CoachReviewed
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue