@@ -309,7 +309,6 @@ def _traverse(
309309 field_name = _convert_field_path_to_string (item_path ),
310310 field_schema = items_schema ,
311311 confidence_threshold = threshold ,
312- parent_assessment_dict = assessment_list , # type: ignore
313312 )
314313 tasks .append (task )
315314 task_counter [0 ] += 1
@@ -332,7 +331,6 @@ def _traverse(
332331 field_name = _convert_field_path_to_string (field_path ),
333332 field_schema = prop_schema ,
334333 confidence_threshold = threshold ,
335- parent_assessment_dict = parent_dict ,
336334 )
337335 tasks .append (task )
338336 task_counter [0 ] += 1
@@ -536,14 +534,40 @@ def _is_throttling_exception(self, exception: Exception) -> bool:
536534 for throttle_term in self .throttling_exceptions
537535 )
538536
537+ def _insert_at_field_path (
538+ self ,
539+ structure : dict [str , Any ],
540+ field_path : tuple [str | int , ...],
541+ value : Any ,
542+ ) -> None :
543+ """
544+ Navigate through structure using field_path and insert value at the end.
545+
546+ Args:
547+ structure: The assessment structure to navigate
548+ field_path: Tuple path like ("Account Holder Address", "City") or ("Transactions", 0, "Amount")
549+ value: The assessment data to insert
550+
551+ Example:
552+ field_path = ("Account Holder Address", "City")
553+ -> structure["Account Holder Address"]["City"] = value
554+
555+ field_path = ("Transactions", 0, "Amount")
556+ -> structure["Transactions"][0]["Amount"] = value
557+ """
558+ parent = structure
559+ for key in field_path [:- 1 ]:
560+ parent = parent [key ]
561+ parent [field_path [- 1 ]] = value
562+
539563 def _aggregate_assessment_results (
540564 self ,
541565 tasks : list [AssessmentTask ],
542566 results : list [AssessmentResult ],
543567 assessment_structure : dict [str , Any ],
544568 ) -> tuple [dict [str , Any ], list [dict [str , Any ]], dict [str , Any ]]:
545569 """
546- Aggregate individual task results into assessment structure using direct parent insertion .
570+ Aggregate individual task results into assessment structure using field_path navigation .
547571
548572 Args:
549573 tasks: list of assessment tasks
@@ -553,13 +577,12 @@ def _aggregate_assessment_results(
553577 Returns:
554578 Tuple of (assessment_structure, confidence_alerts, aggregated_metering)
555579 """
556- all_confidence_alerts = []
557- aggregated_metering = {}
580+ all_confidence_alerts : list [ dict [ str , Any ]] = []
581+ aggregated_metering : dict [ str , Any ] = {}
558582
559583 # Create a mapping from task_id to result
560584 result_map = {result .task_id : result for result in results }
561585
562- # Process each task result - direct O(1) insertion using parent reference
563586 for task in tasks :
564587 result = result_map .get (task .task_id )
565588 if not result or not result .success :
@@ -575,45 +598,31 @@ def _aggregate_assessment_results(
575598 # Add confidence alerts
576599 all_confidence_alerts .extend (result .confidence_alerts )
577600
578- # Get assessment data from result - should be a single assessment object
579- # The Strands agent returns the assessment in result.assessment_data
580- assessment_obj = result .assessment_data
601+ # Get assessment data directly from result
602+ # strands_service returns flat assessment dict: {confidence, value, reasoning, ...}
603+ field_assessment = result .assessment_data
581604
582- if not isinstance (assessment_obj , dict ):
605+ if not isinstance (field_assessment , dict ):
583606 logger .warning (
584- f"Task { task .task_id } : expected dict assessment, got { type (assessment_obj )} "
607+ f"Task { task .task_id } : expected dict assessment, got { type (field_assessment )} "
585608 )
586609 continue
587610
588- # Add confidence_threshold to the assessment object
589- assessment_obj ["confidence_threshold" ] = task .confidence_threshold
590-
591- # Direct insertion using parent reference - O(1) operation!
592- parent = task .parent_assessment_dict
593- field_name = task .field_name
594-
595- if isinstance (parent , dict ):
596- # Regular field - insert into parent dict
597- parent [field_name ] = assessment_obj
598- elif isinstance (parent , list ):
599- # Array item - get index from field_path
600- # field_path is like ("items", 0, "price") - second-to-last is the index
601- if len (task .field_path ) >= 2 and isinstance (task .field_path [- 2 ], int ):
602- idx = task .field_path [- 2 ]
603- # Replace the None placeholder we created during structure building
604- if idx < len (parent ):
605- parent [idx ] = assessment_obj
606- else :
607- logger .warning (
608- f"Task { task .task_id } : index { idx } out of range for list of length { len (parent )} "
609- )
610- else :
611- logger .warning (
612- f"Task { task .task_id } : cannot determine array index from path { task .field_path } "
613- )
614- else :
615- logger .warning (
616- f"Task { task .task_id } : unexpected parent type { type (parent )} "
611+ # Add confidence_threshold if not already present
612+ if "confidence_threshold" not in field_assessment :
613+ field_assessment ["confidence_threshold" ] = task .confidence_threshold
614+
615+ # Insert directly at field_path - no unwrapping needed
616+ try :
617+ self ._insert_at_field_path (
618+ assessment_structure , task .field_path , field_assessment
619+ )
620+ logger .debug (
621+ f"Task { task .task_id } : Inserted assessment at { task .field_path } "
622+ )
623+ except (KeyError , IndexError , TypeError ) as e :
624+ logger .error (
625+ f"Task { task .task_id } : Failed to insert at path { task .field_path } : { e } "
617626 )
618627
619628 return assessment_structure , all_confidence_alerts , aggregated_metering
0 commit comments