fix: tolerate spotify version suffixes and surface rerank failures
This commit is contained in:
parent
ce652d3114
commit
0ccc9a5d4e
6 changed files with 92 additions and 29 deletions
|
|
@ -177,27 +177,44 @@ class RecommendationPipeline:
|
|||
history: tuple[ConversationTurn, ...],
|
||||
selection: _TrackSelection,
|
||||
) -> AsyncGenerator[PipelineTrackEvent | PipelineWarningEvent]:
|
||||
"""Stream one rerank, retry once on invalid output, then fall back."""
|
||||
correction: str | None = None
|
||||
for _ in range(2):
|
||||
if selection.is_full:
|
||||
return
|
||||
try:
|
||||
async for event in self._rerank_once(
|
||||
intent, taste_summary, history, selection, correction
|
||||
):
|
||||
yield event
|
||||
return
|
||||
except RecommenderOutputError as error:
|
||||
correction = (
|
||||
f"Validation failed: {error}."
|
||||
f" Already emitted track ids: {selection.describe_selected_ids()}."
|
||||
)
|
||||
"""Stream the rerank with one corrected retry, then fall back."""
|
||||
try:
|
||||
async for event in self._rerank_with_one_retry(
|
||||
intent, taste_summary, history, selection
|
||||
):
|
||||
yield event
|
||||
return
|
||||
except RecommenderOutputError as error:
|
||||
_log_rerank_failure(attempt=2, error=error)
|
||||
|
||||
yield PipelineWarningEvent(code=RERANK_FALLBACK_CODE, message=RERANK_FALLBACK_MESSAGE)
|
||||
for event in selection.fill_from_pool(RERANK_FALLBACK_JUSTIFICATION):
|
||||
yield event
|
||||
|
||||
async def _rerank_with_one_retry(
|
||||
self,
|
||||
intent: Intent,
|
||||
taste_summary: str,
|
||||
history: tuple[ConversationTurn, ...],
|
||||
selection: _TrackSelection,
|
||||
) -> AsyncGenerator[PipelineTrackEvent]:
|
||||
"""Rerank once; on invalid output, retry once with a correction."""
|
||||
try:
|
||||
async for event in self._rerank_once(intent, taste_summary, history, selection, None):
|
||||
yield event
|
||||
return
|
||||
except RecommenderOutputError as error:
|
||||
_log_rerank_failure(attempt=1, error=error)
|
||||
if selection.is_full:
|
||||
return
|
||||
correction = (
|
||||
f"Validation failed: {error}."
|
||||
f" Already emitted track ids: {selection.describe_selected_ids()}."
|
||||
)
|
||||
|
||||
async for event in self._rerank_once(intent, taste_summary, history, selection, correction):
|
||||
yield event
|
||||
|
||||
async def _rerank_once(
|
||||
self,
|
||||
intent: Intent,
|
||||
|
|
@ -219,6 +236,11 @@ class RecommendationPipeline:
|
|||
yield selection.select(item.track_id, item.justification)
|
||||
|
||||
|
||||
def _log_rerank_failure(attempt: int, error: RecommenderOutputError) -> None:
|
||||
"""Log one invalid rerank attempt with its validation reason."""
|
||||
structlog.get_logger().warning("rerank_attempt_failed", attempt=attempt, error=str(error))
|
||||
|
||||
|
||||
def _log_completion(selection: _TrackSelection, taste: CompressedTasteProfile) -> None:
|
||||
"""Log how many recommendations were served and how many are new."""
|
||||
new_track_count = sum(track.id not in taste.known_track_ids for track in selection.selected)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue