@@ -55,6 +55,17 @@ def _initial_reviewer_anchor(review_data: dict) -> str | None:
5555 return None
5656
5757
58+ def _record_for_current_reviewer (record : dict | None | object , current_reviewer : str ) -> dict | None :
59+ if not isinstance (record , dict ):
60+ return None
61+ actor = record .get ("actor" )
62+ if not isinstance (actor , str ) or not actor .strip ():
63+ return record
64+ if actor .lower () != current_reviewer .lower ():
65+ return None
66+ return record
67+
68+
5869def _contributor_revision_handoff_record (review_data : dict , current_head : str | None , reviewer_review : dict | None ) -> dict | None :
5970 contributor_revision = review_data .get ("contributor_revision" , {}).get ("accepted" )
6071 if not isinstance (contributor_revision , dict ):
@@ -93,33 +104,69 @@ def derive_reviewer_response_state(
93104 contributor_comment = review_data .get ("contributor_comment" , {}).get ("accepted" )
94105
95106 if not issue_is_pull_request :
96- if not reviewer_comment and not reviewer_review :
107+ reviewer_comment = _record_for_current_reviewer (reviewer_comment , current_reviewer )
108+ reviewer_review = _record_for_current_reviewer (reviewer_review , current_reviewer )
109+ latest_reviewer_response = reviewer_comment
110+ if reviewer_review_helpers .compare_records (
111+ reviewer_review ,
112+ latest_reviewer_response ,
113+ parse_timestamp = live_review_support .parse_github_timestamp ,
114+ ) > 0 :
115+ latest_reviewer_response = reviewer_review
116+ completion = review_data .get ("current_cycle_completion" )
117+ if isinstance (completion , dict ) and completion .get ("completed" ):
118+ return {
119+ "state" : "done" ,
120+ "reason" : None ,
121+ "anchor_timestamp" : latest_reviewer_response .get ("timestamp" ) if isinstance (latest_reviewer_response , dict ) else None ,
122+ "reviewer_comment" : reviewer_comment ,
123+ "reviewer_review" : reviewer_review ,
124+ "contributor_comment" : contributor_comment ,
125+ "contributor_handoff" : contributor_comment ,
126+ }
127+ if review_data .get ("review_completed_at" ):
128+ return {
129+ "state" : "done" ,
130+ "reason" : None ,
131+ "anchor_timestamp" : latest_reviewer_response .get ("timestamp" ) if isinstance (latest_reviewer_response , dict ) else None ,
132+ "reviewer_comment" : reviewer_comment ,
133+ "reviewer_review" : reviewer_review ,
134+ "contributor_comment" : contributor_comment ,
135+ "contributor_handoff" : contributor_comment ,
136+ }
137+ if not latest_reviewer_response :
97138 return {
98139 "state" : "awaiting_reviewer_response" ,
99140 "reason" : "no_reviewer_activity" ,
100141 "anchor_timestamp" : _initial_reviewer_anchor (review_data ),
101142 "reviewer_comment" : reviewer_comment ,
102143 "reviewer_review" : reviewer_review ,
103144 "contributor_comment" : contributor_comment ,
104- "contributor_handoff" : None ,
145+ "contributor_handoff" : contributor_comment ,
105146 }
106- latest_reviewer_response = reviewer_comment
107- if reviewer_review_helpers .compare_records (
108- reviewer_review ,
147+ if _compare_cross_channel_conversation (
148+ contributor_comment ,
109149 latest_reviewer_response ,
110150 parse_timestamp = live_review_support .parse_github_timestamp ,
111151 ) > 0 :
112- latest_reviewer_response = reviewer_review
113- completion = review_data .get ("current_cycle_completion" )
114- if not isinstance (completion , dict ) or not completion .get ("completed" ):
115- if review_data .get ("review_completed_at" ):
116- return {"state" : "done" , "reason" : None }
117152 return {
118- "state" : "awaiting_contributor_response" ,
119- "reason" : "completion_missing" ,
120- "anchor_timestamp" : latest_reviewer_response .get ("timestamp" ) if isinstance (latest_reviewer_response , dict ) else None ,
153+ "state" : "awaiting_reviewer_response" ,
154+ "reason" : "contributor_comment_newer" ,
155+ "anchor_timestamp" : contributor_comment .get ("timestamp" ) if isinstance (contributor_comment , dict ) else None ,
156+ "reviewer_comment" : reviewer_comment ,
157+ "reviewer_review" : reviewer_review ,
158+ "contributor_comment" : contributor_comment ,
159+ "contributor_handoff" : contributor_comment ,
121160 }
122- return {"state" : "done" , "reason" : None }
161+ return {
162+ "state" : "awaiting_contributor_response" ,
163+ "reason" : "completion_missing" ,
164+ "anchor_timestamp" : latest_reviewer_response .get ("timestamp" ) if isinstance (latest_reviewer_response , dict ) else None ,
165+ "reviewer_comment" : reviewer_comment ,
166+ "reviewer_review" : reviewer_review ,
167+ "contributor_comment" : contributor_comment ,
168+ "contributor_handoff" : contributor_comment ,
169+ }
123170
124171 if not isinstance (current_head , str ) or not current_head .strip ():
125172 return {"state" : "projection_failed" , "reason" : "pull_request_head_unavailable" }
0 commit comments