SulmanK commited on
Commit
7cf76bc
Β·
1 Parent(s): 6b12a24

Enhance follow-up detection logic in RecommendationService - Added checks to differentiate between follow-up queries and new primary artist queries based on current and previous artist mentions. Updated context handling rules in ContextAwareIntentAnalyzer to clarify follow-up criteria and improve intent management. This update aims to refine user experience by ensuring accurate query handling and maintaining session context effectively.

Browse files
src/services/components/context_handler.py CHANGED
@@ -132,45 +132,33 @@ class ContextAwareIntentAnalyzer:
132
 
133
  Previous query: "{recent_query}"
134
  Previous artists mentioned: {previous_artists}
135
- Original session intent: {original_intent}
136
- Artist-focused session: {was_artist_focused}
137
  Current query: "{query}"
 
 
138
 
139
- 🎯 CRITICAL RULES FOR NEW PRIMARY QUERIES:
140
- 1. If the current query mentions a DIFFERENT artist than previous artists, it is NEVER a follow-up
141
- 2. Queries like "Music by X", "Songs by X", "Tracks by X" are PRIMARY queries, not follow-ups
142
- 3. Only treat as follow-up if query explicitly references previous context ("more", "like this", "similar")
 
143
 
144
- 🎯 FOLLOW-UP DETECTION RULES:
145
- 1. Generic "more" requests in artist-focused sessions β†’ artist_deep_dive (preserve artist context)
146
- 2. "More like this" or "similar" β†’ style_continuation
147
- 3. "More [same artist] tracks" β†’ artist_deep_dive
 
 
 
148
 
149
- Examples:
150
- βœ… FOLLOW-UP: "More tracks" (after "Music by Kendrick Lamar") β†’ artist_deep_dive
151
- βœ… FOLLOW-UP: "More like this" β†’ style_continuation
152
- βœ… FOLLOW-UP: "More Kendrick tracks" (same artist) β†’ artist_deep_dive
153
- ❌ NOT FOLLOW-UP: "Music by Kendrick Lamar" (new primary query, even if different from previous)
154
- ❌ NOT FOLLOW-UP: "Songs by The Beatles" (new primary query)
155
- ❌ NOT FOLLOW-UP: "Tracks by Drake" (new primary query)
156
-
157
- 🚨 IMPORTANT: If current query is a complete standalone request about a different artist,
158
- it should ALWAYS be is_followup=false, regardless of conversation history!
159
-
160
- Return JSON:
161
  {{
162
- "is_followup": true/false,
163
- "followup_type": "artist_deep_dive" | "style_continuation" | "artist_style_refinement" | "none",
164
- "target_entity": "artist name from previous context (only if is_followup=true)",
165
- "style_modifier": "style/genre/mood constraint" or null,
166
- "confidence": 0.0-1.0,
167
- "reasoning": "brief explanation"
168
  }}
169
-
170
- Follow-up types:
171
- - "artist_deep_dive": More tracks from SAME artist OR generic "more" in artist-focused session
172
- - "style_continuation": More of same style without artist reference in non-artist sessions
173
- - "artist_style_refinement": More tracks from SAME artist with style constraint
174
  """
175
 
176
  response = await self.llm_utils.call_llm_with_json_response(
@@ -280,6 +268,15 @@ class ContextAwareIntentAnalyzer:
280
  'genres': [],
281
  'moods': []
282
  }
 
 
 
 
 
 
 
 
 
283
  elif followup_type == 'artist_similarity_continuation':
284
  # For artist similarity continuation, extract entities from history
285
  entities = self._extract_complete_entities_from_history(history)
 
132
 
133
  Previous query: "{recent_query}"
134
  Previous artists mentioned: {previous_artists}
 
 
135
  Current query: "{query}"
136
+ Original intent: {original_intent}
137
+ Was artist-focused: {was_artist_focused}
138
 
139
+ CRITICAL RULES:
140
+ 1. If query mentions "like [Artist Name]" or "similar to [Artist]", this is NEVER a follow-up - it's a new primary query for that specific artist's style.
141
+ 2. Follow-ups modify existing context (e.g., "more upbeat", "different genre", "more tracks") without introducing NEW primary entities.
142
+ 3. When you detect a similarity query like "Songs like Mk.gee", set target_entity to the mentioned artist ("Mk.gee"), NOT None.
143
+ 4. Only set is_followup=true if the query modifies the CURRENT/RECENT context without naming a different primary artist.
144
 
145
+ EXAMPLES:
146
+ βœ… FOLLOW-UP: "Make them more upbeat" (after any query) β†’ is_followup: true, intent should remain same
147
+ βœ… FOLLOW-UP: "More tracks like this" (after any query) β†’ is_followup: true, target_entity: null
148
+ βœ… FOLLOW-UP: "Different genre please" (after any query) β†’ is_followup: true, target_entity: null
149
+ ❌ NOT FOLLOW-UP: "Songs like Mk.gee" (after discussing The Beatles) β†’ is_followup: false, target_entity: "Mk.gee", intent should be artist_similarity
150
+ ❌ NOT FOLLOW-UP: "Music by Radiohead" (after any query) β†’ is_followup: false, target_entity: "Radiohead", intent should be by_artist
151
+ ❌ NOT FOLLOW-UP: "Jazz music" (after any query) β†’ is_followup: false, target_entity: null, intent should be genre_mood
152
 
153
+ Return JSON with:
 
 
 
 
 
 
 
 
 
 
 
154
  {{
155
+ "is_followup": boolean,
156
+ "followup_type": "style_continuation" | "artist_deep_dive" | "genre_shift" | "mood_shift" | "preference_refinement" | "none",
157
+ "target_entity": string or null (IMPORTANT: For "Songs like X" queries, set this to X, not null),
158
+ "style_modifier": string or null,
159
+ "confidence": float,
160
+ "reasoning": string
161
  }}
 
 
 
 
 
162
  """
163
 
164
  response = await self.llm_utils.call_llm_with_json_response(
 
268
  'genres': [],
269
  'moods': []
270
  }
271
+ elif target_entity and followup_type in ['style_continuation', 'artist_similarity']:
272
+ # πŸ”§ CRITICAL FIX: For similarity queries with explicit target entity (like "Songs like Mk.gee")
273
+ # Use the target entity as the primary artist, don't fall back to history
274
+ entities = {
275
+ 'artists': [target_entity],
276
+ 'tracks': [],
277
+ 'genres': [],
278
+ 'moods': []
279
+ }
280
  elif followup_type == 'artist_similarity_continuation':
281
  # For artist similarity continuation, extract entities from history
282
  entities = self._extract_complete_entities_from_history(history)
src/services/recommendation_service.py CHANGED
@@ -10,6 +10,7 @@ Target: 72KB β†’ ~30KB (60% reduction)
10
  import asyncio
11
  from typing import Dict, List, Any, Optional
12
  from dataclasses import dataclass
 
13
 
14
  import structlog
15
  import uuid
@@ -483,6 +484,33 @@ class RecommendationService:
483
  query_lower = request.query.lower().strip()
484
  is_likely_followup = any(indicator in query_lower for indicator in followup_indicators)
485
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
486
  if is_likely_followup:
487
  self.logger.info(
488
  "πŸ”„ Follow-up query detected - preserving session",
@@ -630,8 +658,6 @@ class RecommendationService:
630
  Returns:
631
  Tuple of (artists_set, genres_set)
632
  """
633
- import re
634
-
635
  query_lower = query.lower()
636
  artists = set()
637
  genres = set()
 
10
  import asyncio
11
  from typing import Dict, List, Any, Optional
12
  from dataclasses import dataclass
13
+ import re # Add this import for regex pattern matching
14
 
15
  import structlog
16
  import uuid
 
484
  query_lower = request.query.lower().strip()
485
  is_likely_followup = any(indicator in query_lower for indicator in followup_indicators)
486
 
487
+ # Additional check: avoid detecting new artist queries as follow-ups
488
+ # If query explicitly mentions a different artist than previous, it's NOT a follow-up
489
+ if not is_likely_followup:
490
+ # Extract entities from current query to detect new artist mentions
491
+ current_artists, _ = self._extract_entities_from_query(request.query)
492
+ last_entities = last_interaction.get('entities', {})
493
+ last_artists = set()
494
+
495
+ # Get previous artists from last interaction
496
+ if 'target_artists' in last_entities:
497
+ last_artists.update([a.lower().strip() for a in last_entities['target_artists']])
498
+ if 'target_artist' in last_entities:
499
+ last_artists.add(last_entities['target_artist'].lower().strip())
500
+
501
+ # If current query mentions different artists, it's definitely NOT a follow-up
502
+ if current_artists and last_artists:
503
+ artist_overlap = last_artists.intersection(current_artists)
504
+ if not artist_overlap:
505
+ self.logger.info(
506
+ "🎯 Different artist detected - treating as new primary query",
507
+ last_artists=list(last_artists),
508
+ current_artists=list(current_artists),
509
+ query=request.query
510
+ )
511
+ # Force new session for different artist queries
512
+ return True
513
+
514
  if is_likely_followup:
515
  self.logger.info(
516
  "πŸ”„ Follow-up query detected - preserving session",
 
658
  Returns:
659
  Tuple of (artists_set, genres_set)
660
  """
 
 
661
  query_lower = query.lower()
662
  artists = set()
663
  genres = set()