
    i2                         d Z ddlZddlZddlmZ ddlmZmZ ddlmZ ddl	m
Z
 ddlmZmZ dd	lmZ d
Z e ej"                  dd            Ze G d d             Z G d d      Zy)u   
CorrectionLoop — MVFL Re-injection Engine.
Re-injects failed output back to LLM with CORRECTION: prefix.
Max 3 attempts before escalation to Opus.
    N)	dataclass)datetimetimezone)Path)Optional   )MVFLTriggerMVFLTriggerResult)VoyagerDefense   EVENTS_LOG_PATHz5/mnt/e/genesis-system/data/observability/events.jsonlc                   6    e Zd ZU eed<   eed<   eed<   eed<   y)CorrectionResultsuccessoutputattempts	escalatedN)__name__
__module____qualname__bool__annotations__dictint     2/mnt/e/genesis-system/core/mvfl/correction_loop.pyr   r      s    MLMOr   r   c                   ^    e Zd ZdZ	 	 	 	 ddee   dee   fdZdedede	d	e
fd
Zded	dfdZy)CorrectionLoopa  
    MVFL Re-injection Engine.

    On a failed swarm output, re-dispatches the task with a CORRECTION: prefix
    up to MAX_CORRECTION_ATTEMPTS times. If all attempts fail, calls the
    escalation function (e.g., Opus fallback). Logs every attempt and escalation
    to the observability events log.

    Dispatch and escalation callables are injected as dependencies, enabling
    deterministic unit testing without any external I/O.
    Ntriggervoyagerc                 l    |xs
 t               | _        |xs
 t               | _        || _        || _        y )N)r	   r    r   r!   	_dispatch	_escalate)selfr    r!   dispatch_fnescalation_fns        r   __init__zCorrectionLoop.__init__)   s/     /+-2."2$&r   task_payloadfailed_outputtrigger_resultreturnc                 R  K   |j                  dd      }t        dt        dz         D ]=  }d|j                   d| }i ||||j                  d}| j
                  r| j                  |       d{   }n|j                  dd	      d
dd}| j                  j                  ||      }	| j                  j                  |      }
| j                  d|j                  dd	      ||j                  |	j                  |
j                  t        j                  t        j                         j#                         d       |	j                  s|
j                  st%        d||d      c S |	}@ | j&                  r| j'                  ||       d{   }n|j                  dd	      ddt        d}| j                  d|j                  dd	      t        |j                  t        j                  t        j                         j#                         d       t%        d|t        d      S 7 7 w)u  
        Run correction loop up to MAX_CORRECTION_ATTEMPTS times.

        Args:
            task_payload:   The original task dict (must contain at least 'task_id' and 'prompt').
            failed_output:  The output that triggered the MVFL condition.
            trigger_result: The MVFLTriggerResult that caused this correction cycle.

        Returns:
            CorrectionResult — success/failure, final output, attempt count, escalation flag.
        prompt r   zCORRECTION: z

)r.   attemptcorrection_sourceNtask_idunknown	completedstub)r2   statusr   mvfl_correction_attempt)eventr2   r0   trigger_typenew_triggeredvoyager_blocked	timestampTF)r   r   r   r   errorMVFL_ESCALATION_REQUIRED)r2   r6   r=   attempts_exhaustedmvfl_escalation)r8   r2   r   r9   r<   )getrangeMAX_CORRECTION_ATTEMPTSdetailsr9   r#   r    evaluater!   score
_log_event	triggeredshould_blockr   nowr   utc	isoformatr   r$   )r%   r)   r*   r+   original_promptr0   correction_promptcorrected_payloadr   new_triggervoyager_scoreescalated_outputs               r   runzCorrectionLoop.run5   s#    " '**8R8Q 7! ;< -	)G".~/E/E.Fd?J[ \!!+"%3%@%@	! ~~#~~.?@@  ,//	9E)$ ,,//8IJK LL..v6M OO2'++IyA" . ; ;!,!6!6#0#=#=%\\(,,7AAC  ((1K1K' !$#	  )N[-	)` >>%)^^L-%PP (++IyA!3&=	  	&#''	9=/*77!hll3==?
 	  #,	
 	
m AJ  Qs&   A0H'2H"3DH'
H%BH'%H'r8   c                     	 t         j                  j                  dd       t        t         d      5 }|j	                  t        j                  |      dz          ddd       y# 1 sw Y   yxY w# t        $ r Y yw xY w)z@Append a JSON event line to the observability log. Never raises.T)parentsexist_oka
N)r   parentmkdiropenwritejsondumps	Exception)r%   r8   fs      r   rG   zCorrectionLoop._log_event   sl    	""(((Eos+ 2q

5)D012 2 2 		s.   1A0 (A$A0 $A-)A0 -A0 0	A<;A<)NNNN)r   r   r   __doc__r   r	   r   r(   r   r
   r   rS   rG   r   r   r   r   r      sz    
 *.,0
'+&
' .)
'Z
Z
 Z
 *	Z

 
Z
x  r   r   )ra   r]   osdataclassesr   r   r   pathlibr   typingr   mvfl_triggerr	   r
   voyager_defenser   rC   getenvr   r   r   r   r   r   <module>ri      sh   
  	 ! '   8 + yryy!24klm   | |r   