@@ -290,8 +290,18 @@ async def pick_affiliation_file_with_ai(
290290 total_cost += result .cost
291291
292292 if result .output .file_name is not None :
293- self .logger .info (f"Affiliation file: { result .output .file_name } (AI)" )
294- return result .output .file_name , total_cost
293+ picked_path = result .output .file_name
294+ if picked_path not in batch :
295+ self .logger .debug (
296+ f"AI picked path not in candidate batch, skipping: { picked_path !r} "
297+ )
298+ continue
299+ full_path = os .path .join (repo_path , picked_path )
300+ if not await aiofiles .os .path .isfile (full_path ):
301+ self .logger .debug (f"AI picked path not on disk, skipping: { picked_path !r} " )
302+ continue
303+ self .logger .info (f"Affiliation file: { picked_path } (AI)" )
304+ return picked_path , total_cost
295305
296306 return None , total_cost
297307
@@ -471,13 +481,16 @@ async def parse_affiliations(
471481 affiliations = parse_result .output .affiliations
472482 if affiliations is not None :
473483 if not affiliations :
474- raise AffiliationAnalysisError ()
484+ return [], parse_result . cost
475485
476486 raw_count = len (affiliations )
477487 normalized = self .normalize_parsed_affiliations (affiliations )
478488
479489 if not normalized :
480- raise AffiliationAnalysisError ()
490+ raise AffiliationAnalysisError (
491+ retain_file_hash = True ,
492+ error_message = "Affiliation file had rows but none were usable" ,
493+ )
481494
482495 if len (normalized ) < raw_count :
483496 self .logger .debug (
@@ -487,7 +500,7 @@ async def parse_affiliations(
487500 return normalized , parse_result .cost
488501
489502 if parse_result .output .error == "not_found" :
490- raise AffiliationAnalysisError ()
503+ return [], parse_result . cost
491504
492505 raise AffiliationAnalysisError (
493506 error_message = "Unexpected response while parsing the affiliation file" ,
@@ -533,7 +546,10 @@ async def process_chunk(chunk_index: int, chunk: str):
533546 normalized = self .normalize_parsed_affiliations (affiliations )
534547
535548 if not normalized :
536- raise AffiliationAnalysisError ()
549+ raise AffiliationAnalysisError (
550+ retain_file_hash = True ,
551+ error_message = "Affiliation file had rows but none were usable" ,
552+ )
537553
538554 if len (normalized ) < raw_count :
539555 self .logger .debug (
@@ -542,7 +558,7 @@ async def process_chunk(chunk_index: int, chunk: str):
542558
543559 return normalized , total_cost
544560
545- raise AffiliationAnalysisError ()
561+ return [], total_cost
546562
547563 async def resolve_snapshot (
548564 self ,
@@ -557,11 +573,13 @@ async def resolve_snapshot(
557573 """
558574 stored_hash = registry .get ("file_hash" ) if registry else None
559575 existing_snapshot = registry .get ("snapshot" ) if registry else None
560- needs_parse = (
561- file_hash != stored_hash or existing_snapshot is None or not existing_snapshot
562- )
576+ needs_parse = file_hash != stored_hash or existing_snapshot is None
563577
564578 if not needs_parse :
579+ if not existing_snapshot :
580+ self .logger .debug ("Using cached empty snapshot, file unchanged" )
581+ return [], 0.0
582+
565583 applyable = self .normalize_parsed_affiliations (existing_snapshot )
566584
567585 if applyable :
@@ -762,6 +780,7 @@ async def process_affiliations(
762780 error_message = None
763781 ai_cost = 0.0
764782 latest_file_path : str | None = None
783+ latest_file_hash : str | None = None
765784 registry = await get_repo_affiliation_registry (repository .id )
766785
767786 try :
@@ -792,6 +811,7 @@ async def process_affiliations(
792811 file_path_on_disk = os .path .join (batch_info .repo_path , latest_file_path )
793812 content = await self .read_text_file (file_path_on_disk )
794813 file_hash = self .compute_file_hash (content )
814+ latest_file_hash = file_hash
795815
796816 affiliations , parse_cost = await self .resolve_snapshot (
797817 registry ,
@@ -833,9 +853,11 @@ async def process_affiliations(
833853 await upsert_repo_affiliation_registry (
834854 repository .id ,
835855 file_path = latest_file_path ,
836- file_hash = None ,
856+ file_hash = latest_file_hash if e . retain_file_hash else None ,
837857 status = AffiliationRegistryStatus .ERROR .value ,
838- snapshot = registry .get ("snapshot" ) if registry else None ,
858+ snapshot = []
859+ if e .retain_file_hash
860+ else (registry .get ("snapshot" ) if registry else None ),
839861 )
840862 self .logger .warning (error_message )
841863
0 commit comments