Spaces:
Sleeping
Sleeping
| from __future__ import annotations | |
| import math | |
| from typing import Dict, List, Optional | |
| from .models import ClarifyingQuestion, IntentMeta | |
| def _entropy(probs: List[float]) -> float: | |
| return -sum(p * math.log(p + 1e-12) for p in probs if p > 0) | |
| def _find_question(questions: List[ClarifyingQuestion], topic_groups: List[str]) -> Optional[ClarifyingQuestion]: | |
| topic_set = set(topic_groups) | |
| for q in questions: | |
| if not q.applies_to_topic_groups: | |
| return q | |
| if topic_set.intersection(set(q.applies_to_topic_groups)): | |
| return q | |
| return questions[0] if questions else None | |
| def select_clarifying( | |
| patient_state: Dict[str, object], | |
| intent_scores: Dict[str, float], | |
| intents: Dict[str, IntentMeta], | |
| highlevel_questions: List[ClarifyingQuestion], | |
| detail_questions: List[ClarifyingQuestion], | |
| ) -> Optional[ClarifyingQuestion]: | |
| state = patient_state or {} | |
| # Check if topic is already determined from patient state | |
| current_topic = state.get("topic_group") | |
| topic_already_set = current_topic and current_topic not in ("other", "unknown", "") | |
| if not intent_scores: | |
| # No intent candidates - only ask highlevel if topic not yet set | |
| if not topic_already_set: | |
| return highlevel_questions[0] if highlevel_questions else None | |
| # Topic is set but no intents matched - proceed to answer | |
| return None | |
| sorted_pairs = sorted(intent_scores.items(), key=lambda x: x[1], reverse=True) | |
| top_id, top_score = sorted_pairs[0] | |
| top2 = sorted_pairs[1][1] if len(sorted_pairs) > 1 else 0.0 | |
| probs = [s for _, s in sorted_pairs] | |
| ent = _entropy(probs) | |
| inferred_topics = list({intents[intent_id].topic_group for intent_id, _ in sorted_pairs if intent_id in intents}) | |
| # Only ask highlevel question for TRULY AMBIGUOUS cases: | |
| # - Topic not already set by user | |
| # - Top intent score is very low (< 0.30) | |
| # - High entropy (uncertainty across multiple topics) | |
| # - Multiple topics with no clear winner | |
| truly_ambiguous = ( | |
| top_score < 0.30 and | |
| ent > 1.2 and | |
| len(inferred_topics) > 1 | |
| ) | |
| if not topic_already_set and truly_ambiguous: | |
| return _find_question(highlevel_questions, inferred_topics) | |
| # Determine the topic to use: prefer user-set topic, fallback to inferred | |
| best_topic = current_topic if topic_already_set else (intents[top_id].topic_group if top_id in intents else None) | |
| def _detail_for(topic: str) -> Optional[ClarifyingQuestion]: | |
| return _find_question(detail_questions, [topic]) | |
| # Ask detail questions only if the specific state info is missing | |
| # These questions help provide targeted, situation-specific advice | |
| if best_topic == "sick_day" and state.get("food_intake_level") in ("unknown", "", None): | |
| return _detail_for("sick_day") | |
| if best_topic == "travel" and state.get("travel_overseas") is None: | |
| return _detail_for("travel") | |
| if best_topic == "diet" and state.get("insulin_experience") in ("unknown", "", None): | |
| return _detail_for("diet") | |
| if best_topic in ("complication", "hypoglycemia") and state.get("hypoglycemia_concern") in ("unknown", "", None): | |
| return _detail_for("complication") | |
| if best_topic == "neuropathy" and state.get("acute_neurologic_red_flags") in (None, ""): | |
| return _detail_for("neuropathy") | |
| if best_topic == "footcare" and state.get("foot_infection_risk") in (None, ""): | |
| return _detail_for("footcare") | |
| # No clarifying needed - proceed to answer generation | |
| return None | |