77import  xml .etree .ElementTree  as  ET 
88from  pathlib  import  Path 
99from  datetime  import  datetime , timezone 
10+ import  os 
1011
1112# ============================================================================= 
1213# Utility Functions 
@@ -21,24 +22,6 @@ def parse_repository(repository):
2122        print (f"❌ Invalid repository format: { repository }  . Expected: 'owner/name'" )
2223        return  None , None 
2324
24- def  make_github_request (url , headers , method = 'GET' , data = None ):
25-     """Make a GitHub API request with consistent error handling""" 
26-     try :
27-         if  method .upper () ==  'GET' :
28-             response  =  requests .get (url , headers = headers )
29-         elif  method .upper () ==  'POST' :
30-             response  =  requests .post (url , headers = headers , json = data )
31-         elif  method .upper () ==  'PATCH' :
32-             response  =  requests .patch (url , headers = headers , json = data )
33-         else :
34-             print (f"❌ Unsupported HTTP method: { method }  " )
35-             return  None 
36-         
37-         return  response 
38-     except  requests .RequestException  as  e :
39-         print (f"❌ Request failed: { e }  " )
40-         return  None 
41- 
4225# ============================================================================= 
4326# GitHub API Functions 
4427# ============================================================================= 
@@ -171,9 +154,9 @@ def find_line_number_of_change(original_content, old_value):
171154# GitHub PR Comment Functions 
172155# ============================================================================= 
173156
174- def  create_pr_suggestion (repo_owner , repo_name , pr_number , calibration_file , xml_file , line_number , suggested_line , head_sha , github_token ):
175-     """Create a PR review  with code suggestion or update existing one """ 
176-     print (f"Creating/updating  PR review  with suggestion  for #{ pr_number }  ..." )
157+ def  create_pr_suggestion (repo_owner , repo_name , pr_number , calibration_file , xml_file , line_number , suggested_line , head_sha , github_token ,  artifacts_url = '' ):
158+     """Create a PR comment  with proposed changes """ 
159+     print (f"Creating PR comment  with calibration update  for #{ pr_number }  ..." )
177160
178161    headers  =  {
179162        'Accept' : 'application/vnd.github+json' ,
@@ -182,90 +165,83 @@ def create_pr_suggestion(repo_owner, repo_name, pr_number, calibration_file, xml
182165
183166    bot_comment_base  =  f"🤖 **Automated Calibration `{ calibration_file }  ` Update**" 
184167
185-     # Check for existing review  comments from bot 
186-     existing_comment_id  =  find_existing_bot_comment (repo_owner , repo_name , pr_number , bot_comment_base ,  xml_file ,  line_number , github_token )
168+     # Check for existing comments from bot 
169+     existing_comment_id  =  find_existing_bot_comment_general (repo_owner , repo_name , pr_number , bot_comment_base , github_token )
187170
188171    # Generate timestamp for the comment 
189172    timestamp  =  datetime .now (timezone .utc ).strftime ("%Y-%m-%d %H:%M:%S UTC" )
190173
191-     suggestion_body  =  f"""{ bot_comment_base } { ' (Updated)'  if  existing_comment_id  else  '' }  
174+     # Get current line content for context 
175+     content  =  get_file_content (repo_owner , repo_name , xml_file , head_sha , github_token )
176+     lines  =  content .split ('\n ' ) if  content  else  []
177+     current_line  =  lines [line_number  -  1 ].strip () if  line_number  <=  len (lines ) else  "Line not found" 
178+ 
179+     comment_body  =  f"""{ bot_comment_base } { ' (Updated)'  if  existing_comment_id  else  '' }  
192180
193181A new calibration has been generated and is ready for use. 
194182
183+ **File:** `{ xml_file }  ` 
184+ **Line:** { line_number }  
195185**Last updated:** { timestamp }  
196186
197- ```suggestion 
198- { suggested_line } 
199- ```""" 
187+ **Current line:** 
188+ ```xml 
189+ { current_line } 
190+ ``` 
191+ 
192+ **Proposed change:** 
193+ ```xml 
194+ { suggested_line .strip ()} 
195+ ``` 
196+ 
197+ Please update the calibration URL in `{ xml_file }  ` at line { line_number }  .""" 
198+ 
199+     # Add artifacts link if provided 
200+     if  artifacts_url :
201+         comment_body  +=  f"\n \n ---\n \n ### 📊 Review Results\n \n Please review the artifacts here: { artifacts_url }  " 
200202
203+     # Create or update comment via GitHub REST API (no gh CLI) 
201204    if  existing_comment_id :
202-         # Update existing comment 
203205        print (f"Updating existing comment { existing_comment_id }  ..." )
204-         update_url  =  f"https://api.github.com/repos/{ repo_owner }  /{ repo_name }  /pulls /comments/{ existing_comment_id }  " 
205-         update_data  =  {'body' : suggestion_body }
206+         update_url  =  f"https://api.github.com/repos/{ repo_owner }  /{ repo_name }  /issues /comments/{ existing_comment_id }  " 
207+         update_data  =  {'body' : comment_body }
206208        response  =  requests .patch (update_url , headers = headers , json = update_data )
207-         
208209        if  response .status_code  ==  200 :
209210            print ("✅ Existing PR comment updated successfully" )
210211            return  response .json ()
211212        else :
212-             print (f"❌ Failed to update existing comment: { response .status_code }  " )
213-             print (f"   Response: { response .text }  " )
213+             print (f"❌ Failed to update existing comment: { response .status_code } \n { response .text }  " )
214214            return  None 
215215    else :
216-         # Create new review comment 
217-         print ("Creating new review comment..." )
218-         review_url  =  f"https://api.github.com/repos/{ repo_owner }  /{ repo_name }  /pulls/{ pr_number }  /reviews" 
219-         
220-         review_data  =  {
221-             'body' : f'🤖 Automated review with updated calibration URLs `{ calibration_file }  ` for PR #{ pr_number }  ' ,
222-             'event' : 'COMMENT' ,
223-             'commit_id' : head_sha ,
224-             'comments' : [
225-                 {
226-                     'path' : xml_file ,
227-                     'line' : line_number ,
228-                     'body' : suggestion_body 
229-                 }
230-             ]
231-         }
232-         
233-         response  =  requests .post (review_url , headers = headers , json = review_data )
234-         
235-         if  response .status_code  ==  200 :
236-             print ("✅ New PR review with suggestion created successfully" )
216+         print ("Creating new PR comment..." )
217+         comment_url  =  f"https://api.github.com/repos/{ repo_owner }  /{ repo_name }  /issues/{ pr_number }  /comments" 
218+         comment_data  =  {'body' : comment_body }
219+         response  =  requests .post (comment_url , headers = headers , json = comment_data )
220+         if  response .status_code  ==  201 :
221+             print ("✅ New PR comment created successfully" )
237222            return  response .json ()
238223        else :
239-             print (f"❌ Failed to create PR review: { response .status_code }  " )
240-             print (f"   Response: { response .text }  " )
224+             print (f"❌ Failed to create PR comment: { response .status_code } \n { response .text }  " )
241225            return  None 
242226
243- def  find_existing_bot_comment (repo_owner , repo_name , pr_number , bot_comment_base , xml_file , line_number , github_token ):
244-     """Find existing bot comment on the specific line""" 
245-     print (f"Checking for existing bot comments on line { line_number }  ..." )
246-     
227+ def  find_existing_bot_comment_general (repo_owner , repo_name , pr_number , bot_comment_base , github_token ):
228+     """Find existing bot comment (general PR comment, not line-specific)""" 
247229    headers  =  {
248230        'Accept' : 'application/vnd.github+json' ,
249231        'Authorization' : f'token { github_token }  ' 
250232    }
251233
252-     # Get all review  comments for the PR 
253-     comments_url  =  f"https://api.github.com/repos/{ repo_owner }  /{ repo_name }  /pulls /{ pr_number }  /comments" 
234+     # Get all general  comments for the PR 
235+     comments_url  =  f"https://api.github.com/repos/{ repo_owner }  /{ repo_name }  /issues /{ pr_number }  /comments" 
254236    response  =  requests .get (comments_url , headers = headers )
255237
256238    if  response .status_code  !=  200 :
257239        print (f"❌ Failed to get PR comments: { response .status_code }  " )
258240        return  None 
259241
260-     comments  =  response .json ()
261-     
262-     # Look for existing bot comment on the same line and file 
263-     for  comment  in  comments :
264-         # Check if it's from the bot (contains the bot identifier) 
265-         # and on the same file and line 
266-         if  (comment .get ('path' ) ==  xml_file  and  
267-             comment .get ('line' ) ==  line_number  and 
268-             bot_comment_base  in  comment .get ('body' , '' )):
242+     # Look for existing bot comment 
243+     for  comment  in  response .json ():
244+         if  bot_comment_base  in  comment .get ('body' , '' ):
269245            print (f"✅ Found existing bot comment: { comment ['id' ]}  " )
270246            return  comment ['id' ]
271247
0 commit comments