35 lines
1.3 KiB
C#
35 lines
1.3 KiB
C#
using GymLogAI.Application.DTOs;
|
|
using GymLogAI.Application.Interfaces;
|
|
using GymLogAI.Core.Entities;
|
|
|
|
namespace GymLogAI.AI;
|
|
|
|
public sealed class WorkoutRecommendationAIService(OpenRouterChatClient chatClient) : IWorkoutRecommendationGenerator
|
|
{
|
|
public async Task<WorkoutRecommendationDto> GenerateAsync(
|
|
WorkoutRecommendationContext context,
|
|
IReadOnlyCollection<Workout> workoutHistory,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
await chatClient.CompleteAsync(
|
|
$"Recommend workout for goal {context.GoalType} with {workoutHistory.Count} historical workouts.",
|
|
cancellationToken);
|
|
|
|
var lastWorkout = workoutHistory.FirstOrDefault();
|
|
var fallbackExercises = lastWorkout?.WorkoutExercises
|
|
.OrderBy(x => x.Order)
|
|
.Select(x => x.Exercise?.Name ?? "Bodyweight movement")
|
|
.Distinct()
|
|
.Take(4)
|
|
.ToArray();
|
|
|
|
return new WorkoutRecommendationDto(
|
|
"Today's training recommendation",
|
|
$"Goal: {context.GoalType}. History count: {workoutHistory.Count}.",
|
|
fallbackExercises is { Length: > 0 }
|
|
? fallbackExercises
|
|
: ["Squat", "Bench Press", "Row", "Plank"],
|
|
"Keep the session moderate and leave 1-2 reps in reserve.");
|
|
}
|
|
}
|