55from convergent .database import Database
66from pydantic import BaseModel
77import numpy as np
8+ from convergent_engine .math import get_comment_consensus
9+ from convergent .core .routines import get_vote_matrix
810
911
1012router = APIRouter (prefix = "/analysis" )
@@ -35,8 +37,6 @@ class Conversation(BaseModel):
3537 participation_rate : float = None
3638 voting_rate : float = None
3739
38- consensus_comments : list [CommentStatistics ] = None
39-
4040
4141def get_conversation_groups (conversation : models .Conversation , db : Database ):
4242 user_clusters = conversation .clusters
@@ -107,32 +107,6 @@ async def read_conversation_groups(
107107 return get_conversation_groups (conversation , db )
108108
109109
110- def get_consensus_comments (comments : list [models .Comment ], groups : list [Group ], k = 3 ):
111- consensus = {
112- comment .id : {
113- "id" : comment .id ,
114- "content" : comment .content ,
115- "consensus" : 0.0 ,
116- }
117- for comment in comments
118- }
119-
120- for group in groups :
121- for comment_id , vote_count in group ["comment_vote_counts" ].items ():
122- consensus [comment_id ]["consensus" ] += vote_count / len (group ["user_ids" ])
123-
124- consensus = sorted (
125- consensus .values (), key = lambda item : item ["consensus" ], reverse = True
126- )
127-
128- for comment in consensus :
129- comment ["consensus" ] /= len (groups )
130-
131- if len (consensus ) > k :
132- consensus = consensus [:k ]
133- return consensus
134-
135-
136110@router .get (
137111 "/conversation/{conversation_id}" ,
138112 response_model = Conversation ,
@@ -144,7 +118,6 @@ async def read_conversation(
144118 current_user : CurrentUser ,
145119 include_groups : bool = False ,
146120 include_stats : bool = False ,
147- include_consensus_comments : bool = False ,
148121):
149122 conversation = db .query (models .Conversation ).get (conversation_id )
150123 if conversation is None :
@@ -178,12 +151,39 @@ async def read_conversation(
178151 response ["participation_rate" ] = len (participant_ids ) / len (user_ids )
179152 response ["voting_rate" ] = num_votes / (len (user_ids ) * len (comment_ids ))
180153
181- if include_consensus_comments :
182- if "groups" not in response :
183- response ["groups" ] = get_conversation_groups (conversation , db )
154+ return response
155+
184156
185- response ["consensus_comments" ] = get_consensus_comments (
186- conversation .comments , response ["groups" ]
157+ @router .get (
158+ "/conversation/{conversation_id}/comments" ,
159+ response_model = list [CommentStatistics ],
160+ )
161+ async def read_comments_with_consensus (
162+ conversation_id : UUID , db : Database , current_user : CurrentUser
163+ ):
164+ conversation = db .query (models .Conversation ).get (conversation_id )
165+ if conversation is None :
166+ raise HTTPException (status_code = 404 , detail = "Conversation not found" )
167+
168+ votes_matrix , user_index , comment_index = get_vote_matrix (conversation )
169+
170+ user_clusters = np .full (len (user_index ), - 1 , dtype = int ) # Default to -1 for unclustered users
171+ for cluster in conversation .clusters :
172+ if cluster .user in user_index :
173+ user_clusters [user_index [cluster .user ]] = cluster .cluster
174+ else :
175+ raise ValueError (f"Cluster user { cluster .user } not found in user_index" )
176+
177+ consensus_comments = []
178+ for comment in conversation .comments :
179+ comment_idx = comment_index .get (comment .id )
180+ consensus = get_comment_consensus (votes_matrix , comment_idx , user_clusters )
181+ consensus_comments .append (
182+ {
183+ "id" : comment .id ,
184+ "content" : comment .content ,
185+ "consensus" : consensus ,
186+ }
187187 )
188188
189- return response
189+ return sorted ( consensus_comments , key = lambda x : x [ "consensus" ], reverse = True )
0 commit comments