Bias coach queue by guidance preference

This commit is contained in:
axiomlogicnexus 2026-04-27 16:54:55 +02:00
parent 49f7c11840
commit 36f64798aa
4 changed files with 76 additions and 1 deletions

View file

@ -1489,6 +1489,7 @@ FHyperTwistCoachSessionQueueSummary UHyperTwistContractLibrary::MakeSampleTraini
return UHyperTwistTrainingCoachLibrary::DeriveCoachSessionQueueSummary(
MakeSampleTrainingCoachBrief(),
MakeSampleTrainingCoachFollowUpBrief(),
MakeSampleTrainingCoachMemorySnapshot(),
MakeSampleTrainingCoachArchivePolicySummary(),
MakeSampleTrainingReviewProgramSummary()
);

View file

@ -2,6 +2,65 @@
namespace HyperTwistTrainingCoachLibraryInternal
{
EHyperTwistTrainingCoachGuidanceLane GuidanceLaneFromSourceLabel(const FString& SourceLabel)
{
if (SourceLabel == TEXT("primary-brief"))
{
return EHyperTwistTrainingCoachGuidanceLane::Recommended;
}
if (SourceLabel == TEXT("follow-up-brief"))
{
return EHyperTwistTrainingCoachGuidanceLane::FollowUp;
}
return EHyperTwistTrainingCoachGuidanceLane::None;
}
float ResolvePreferredGuidanceQueueBias(
const FString& SourceLabel,
const FHyperTwistTrainingCoachMemorySnapshot& CoachMemorySnapshot,
const bool bHasCompetingGuidanceEntry)
{
if (CoachMemorySnapshot.PreferredGuidanceLane == EHyperTwistTrainingCoachGuidanceLane::None)
{
return 0.0f;
}
const EHyperTwistTrainingCoachGuidanceLane EntryLane = GuidanceLaneFromSourceLabel(SourceLabel);
if (EntryLane == EHyperTwistTrainingCoachGuidanceLane::None)
{
return 0.0f;
}
float LanePressure = 0.0f;
if (CoachMemorySnapshot.PreferredGuidanceLane == EHyperTwistTrainingCoachGuidanceLane::FollowUp)
{
LanePressure =
4.0f
+ static_cast<float>(CoachMemorySnapshot.FollowUpGuidanceContinueBias)
+ (static_cast<float>(CoachMemorySnapshot.FollowUpReadyCoachSequenceCount) * 1.5f)
+ (static_cast<float>(CoachMemorySnapshot.ScheduleBlockedFollowUpEventCount) * 2.0f);
}
else
{
LanePressure =
4.0f
+ static_cast<float>(CoachMemorySnapshot.RecommendedGuidanceContinueBias)
+ (static_cast<float>(CoachMemorySnapshot.RepeatRecommendationSequenceCount) * 1.5f)
+ (CoachMemorySnapshot.bHasRepeatRecommendationPressure ? 4.0f : 0.0f);
}
const float ClampedBoost = FMath::Clamp(LanePressure, 0.0f, 12.0f);
if (EntryLane == CoachMemorySnapshot.PreferredGuidanceLane)
{
return ClampedBoost;
}
return bHasCompetingGuidanceEntry
? -FMath::Clamp(ClampedBoost * 0.5f, 0.0f, 4.0f)
: 0.0f;
}
EHyperTwistCoachPriority PriorityFromScore(const float Score)
{
if (Score >= 85.0f)
@ -630,6 +689,7 @@ FHyperTwistCoachBrief UHyperTwistTrainingCoachLibrary::DeriveCoachFollowUpBrief(
FHyperTwistCoachSessionQueueSummary UHyperTwistTrainingCoachLibrary::DeriveCoachSessionQueueSummary(
const FHyperTwistCoachBrief& CurrentBrief,
const FHyperTwistCoachBrief& FollowUpBrief,
const FHyperTwistTrainingCoachMemorySnapshot& CoachMemorySnapshot,
const FHyperTwistTrainingCoachArchivePolicySummary& ArchivePolicySummary,
const FHyperTwistTrainingReviewProgramSummary& ReviewProgramSummary)
{
@ -653,8 +713,10 @@ FHyperTwistCoachSessionQueueSummary UHyperTwistTrainingCoachLibrary::DeriveCoach
: (!CurrentBrief.FocusMethodSegmentId.IsEmpty()
? CurrentBrief.FocusMethodSegmentId
: ArchivePolicySummary.FocusMethodSegmentId);
const bool bHasCompetingGuidanceEntry =
FollowUpBrief.UserId == Summary.UserId && FollowUpBrief.FocusCaseIds.Num() > 0;
auto AddBriefEntry = [&Summary](
auto AddBriefEntry = [&Summary, &CoachMemorySnapshot, bHasCompetingGuidanceEntry](
const FString& EntryId,
const FString& SourceLabel,
const FHyperTwistCoachBrief& Brief,
@ -679,6 +741,16 @@ FHyperTwistCoachSessionQueueSummary UHyperTwistTrainingCoachLibrary::DeriveCoach
Entry.FocusCaseIds = Brief.FocusCaseIds;
Entry.bRequiresFollowUp = bRequiresFollowUp;
Entry.bRequiresArchiveRetentionTuning = bRequiresArchiveRetentionTuning;
Entry.PriorityScore = FMath::Clamp(
Entry.PriorityScore + HyperTwistTrainingCoachLibraryInternal::ResolvePreferredGuidanceQueueBias(
SourceLabel,
CoachMemorySnapshot,
bHasCompetingGuidanceEntry
),
0.0f,
100.0f
);
Entry.Priority = HyperTwistTrainingCoachLibraryInternal::PriorityFromScore(Entry.PriorityScore);
Summary.Entries.Add(Entry);
};

View file

@ -2135,6 +2135,7 @@ void UHyperTwistTrainingSubsystem::RefreshRepositoryViews()
ActiveCoachSessionQueueSummary = UHyperTwistTrainingCoachLibrary::DeriveCoachSessionQueueSummary(
ActiveCoachBrief,
ActiveCoachFollowUpBrief,
ActiveCoachMemorySnapshot,
ActiveCoachArchivePolicySummary,
ActiveReviewProgramSummary
);

View file

@ -432,6 +432,7 @@ public:
static FHyperTwistCoachSessionQueueSummary DeriveCoachSessionQueueSummary(
const FHyperTwistCoachBrief& CurrentBrief,
const FHyperTwistCoachBrief& FollowUpBrief,
const FHyperTwistTrainingCoachMemorySnapshot& CoachMemorySnapshot,
const FHyperTwistTrainingCoachArchivePolicySummary& ArchivePolicySummary,
const FHyperTwistTrainingReviewProgramSummary& ReviewProgramSummary
);