mirror of
https://github.com/FJurmanovic/sugarr.git
synced 2026-11-11 15:51:09 +00:00
trigger endpoint and retry suggestions
This commit is contained in:
@@ -79,42 +79,58 @@ func (r *Recommender) RunWithCount(count int) ([]model.Recommendation, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Get raw suggestions
|
||||
var suggestions []model.MovieSuggestion
|
||||
if r.cfg.LLMEnabled && r.llm != nil {
|
||||
prompt := client.BuildPrompt(favorites, watchedMovies, library, count)
|
||||
suggestions, err = r.llm.Recommend(prompt)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("llm recommendation failed: %w", err)
|
||||
}
|
||||
log.Info().Msgf("LLM returned %d suggestions", len(suggestions))
|
||||
} else {
|
||||
suggestions = r.tmdbFallback(signalMovies, exclude, count)
|
||||
log.Info().Msgf("TMDb fallback returned %d suggestions", len(suggestions))
|
||||
}
|
||||
|
||||
// 4. Resolve suggestions via TMDb and apply exclusions
|
||||
// 3. Retry loop: each attempt requests only the remaining needed count.
|
||||
// `seen` accumulates every TMDb-resolved movie across attempts so the
|
||||
// LLM prompt excludes them by name, not just by ID.
|
||||
var recommendations []model.Recommendation
|
||||
for _, s := range suggestions {
|
||||
if len(recommendations) >= count {
|
||||
var seen []model.Movie
|
||||
for attempt := 0; attempt <= r.cfg.RecommendMaxRetry && len(recommendations) < count; attempt++ {
|
||||
remaining := count - len(recommendations)
|
||||
if attempt > 0 {
|
||||
log.Info().Msgf("Retry %d/%d: need %d more recommendations", attempt, r.cfg.RecommendMaxRetry, remaining)
|
||||
}
|
||||
|
||||
var suggestions []model.MovieSuggestion
|
||||
if r.cfg.LLMEnabled && r.llm != nil {
|
||||
prompt := client.BuildPrompt(favorites, watchedMovies, library, seen, remaining)
|
||||
suggestions, err = r.llm.Recommend(prompt)
|
||||
if err != nil {
|
||||
return recommendations, fmt.Errorf("llm recommendation failed: %w", err)
|
||||
}
|
||||
log.Info().Msgf("LLM returned %d suggestions (attempt %d)", len(suggestions), attempt+1)
|
||||
} else {
|
||||
suggestions = r.tmdbFallback(signalMovies, exclude, remaining)
|
||||
log.Info().Msgf("TMDb fallback returned %d suggestions (attempt %d)", len(suggestions), attempt+1)
|
||||
}
|
||||
|
||||
before := len(recommendations)
|
||||
for _, s := range suggestions {
|
||||
if len(recommendations) >= count {
|
||||
break
|
||||
}
|
||||
tm, err := r.tmdb.SearchMovie(s.Title, s.Year)
|
||||
if err != nil || tm == nil {
|
||||
log.Debug().Msgf("Could not resolve: %s (%d)", s.Title, s.Year)
|
||||
continue
|
||||
}
|
||||
seen = append(seen, model.Movie{Name: tm.Title, Year: tm.Year, TMDbID: strconv.Itoa(tm.ID)})
|
||||
if exclude[tm.ID] {
|
||||
log.Debug().Msgf("Skipping (already in library): %s", tm.Title)
|
||||
continue
|
||||
}
|
||||
exclude[tm.ID] = true
|
||||
recommendations = append(recommendations, model.Recommendation{
|
||||
Title: tm.Title,
|
||||
Year: tm.Year,
|
||||
TMDbID: tm.ID,
|
||||
Reason: s.Reason,
|
||||
})
|
||||
}
|
||||
|
||||
if len(recommendations) == before {
|
||||
log.Warn().Msgf("No new recommendations found on attempt %d, stopping retries", attempt+1)
|
||||
break
|
||||
}
|
||||
tm, err := r.tmdb.SearchMovie(s.Title, s.Year)
|
||||
if err != nil || tm == nil {
|
||||
log.Debug().Msgf("Could not resolve: %s (%d)", s.Title, s.Year)
|
||||
continue
|
||||
}
|
||||
if exclude[tm.ID] {
|
||||
log.Debug().Msgf("Skipping (already in library): %s", tm.Title)
|
||||
continue
|
||||
}
|
||||
exclude[tm.ID] = true
|
||||
recommendations = append(recommendations, model.Recommendation{
|
||||
Title: tm.Title,
|
||||
Year: tm.Year,
|
||||
TMDbID: tm.ID,
|
||||
Reason: s.Reason,
|
||||
})
|
||||
}
|
||||
|
||||
return recommendations, nil
|
||||
|
||||
Reference in New Issue
Block a user