stutiagrawal commited on
Commit
7cddf19
·
unverified ·
1 Parent(s): 98feb0f

Add speaker labels

Browse files
Files changed (1) hide show
  1. app/agents/claims.py +39 -1
app/agents/claims.py CHANGED
@@ -126,6 +126,40 @@ def run_claim_extractor(transcript: str) -> Dict[str, Any]:
126
  return {"claims": []}
127
 
128
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
  # =========================
130
  # Public: extract_claims (used by orchestrator)
131
  # =========================
@@ -146,10 +180,14 @@ def extract_claims(segments: List[Dict]) -> List[Claim]:
146
  text = (c.get("text") or "").strip()
147
  if not text:
148
  continue
 
 
 
 
149
  out.append(Claim(
150
  id=f"c{i}",
151
  text=text,
152
- speaker=c.get("speaker"),
153
  segment_idx=0, # TODO: map to true segment via start/end if available
154
  confidence=float(c.get("confidence", 0.6)),
155
  ))
 
126
  return {"claims": []}
127
 
128
 
129
+ # =========================
130
+ # Helper Functions
131
+ # =========================
132
+
133
+ def _find_speaker_for_claim(claim_text: str, segments: List[Dict]) -> str:
134
+ """
135
+ Find which speaker made a claim by matching claim text to transcript segments.
136
+ Uses fuzzy matching to handle slight variations in wording.
137
+ """
138
+ claim_words = set(claim_text.lower().split())
139
+ best_match_speaker = None
140
+ best_match_score = 0
141
+
142
+ for segment in segments:
143
+ segment_text = segment.get("text", "").lower()
144
+ segment_words = set(segment_text.split())
145
+
146
+ # Calculate overlap score (Jaccard similarity)
147
+ if segment_words:
148
+ intersection = claim_words.intersection(segment_words)
149
+ union = claim_words.union(segment_words)
150
+ score = len(intersection) / len(union) if union else 0
151
+
152
+ # Also check if claim is a substring (for exact matches)
153
+ if claim_text.lower() in segment_text or any(word in segment_text for word in claim_words if len(word) > 3):
154
+ score += 0.2 # Boost for substring matches
155
+
156
+ if score > best_match_score:
157
+ best_match_score = score
158
+ best_match_speaker = segment.get("speaker")
159
+
160
+ # Only return speaker if we have a reasonable confidence match
161
+ return best_match_speaker if best_match_score > 0.2 else None
162
+
163
  # =========================
164
  # Public: extract_claims (used by orchestrator)
165
  # =========================
 
180
  text = (c.get("text") or "").strip()
181
  if not text:
182
  continue
183
+
184
+ # Map claim to speaker by finding which segment contains this text
185
+ speaker = _find_speaker_for_claim(text, segments)
186
+
187
  out.append(Claim(
188
  id=f"c{i}",
189
  text=text,
190
+ speaker=speaker or c.get("speaker"),
191
  segment_idx=0, # TODO: map to true segment via start/end if available
192
  confidence=float(c.get("confidence", 0.6)),
193
  ))