
    sju                   x   d Z ddlmZ ddlZddlZddlZddlmZ ddlm	Z	m
Z
mZmZ ddlmZmZ  ej        e          ZdEdZdFdZdGdZdHdZddddIdZ eh d          ZdZdJd"ZdKd#ZdLd$ZdMd&ZdNd(Zdd)dOd1Z  eh d2          Z!dPdQd6Z"dPdRd7Z#dSd8Z$ddddddd9dTd=Z%dUd?Z&dVdWdBZ'dPdWdCZ(g dDZ)dS )Xu  Codex API runtime — App Server and Responses-API streaming paths.

Extracted from :class:`AIAgent` to keep the agent loop file focused.
Each function takes the parent ``AIAgent`` as its first argument
(``agent``).  AIAgent keeps thin forwarder methods for backward
compatibility.

* ``run_codex_app_server_turn`` — drives one turn through the
  ``codex_app_server`` subprocess client (used when a Codex CLI install
  is the active provider).
* ``run_codex_stream`` — streams a Codex Responses API call (the
  ``codex_responses`` api_mode).
* ``run_codex_create_stream_fallback`` — recovery path when the
  Responses ``stream=True`` initial create fails.
    )annotationsN)SimpleNamespace)AnyCallableDictList)claim_stream_writerstream_writer_is_currenterrorBaseExceptionreturntuple[int | None, str]c                   d}g }| }t                      }|\t          |          |vrJt          |          dk     r6|                    t          |                     |                    t          |          j                   |	 t          |dd          }n# t          $ r d}Y nw xY w|	 |j	        }n# t          $ r d}Y nw xY wt          |t                    r#t          |                    d                    }n1t          |t          t          t          f          rt          |          }|j        }||j        s|j        }|}|%t          |          |vrt          |          dk     6|d                    |          fS )a  Return the serialized request size and exception class chain.

    OpenAI connection exceptions retain the final ``httpx.Request``. Reading
    its already-buffered content gives us the exact byte count handed to the
    transport without logging any request content. The class-only chain keeps
    the underlying transport failure visible without exposing URLs or payloads
    from exception messages.
    N   requestzutf-8z <- )setidlenaddappendtype__name__getattr	Exceptioncontent
isinstancestrencodebytes	bytearray
memoryview	__cause____suppress_context____context__join)r   request_body_bytesexception_classescurrentseenr   r   causes           7/home/agent/.hermes/hermes-agent/agent/codex_runtime.py_codex_request_failure_detailsr,      s    &*#%$)GUUD

"W++T"9"9c$ii!mmG  g!7888%!'9d;;   "#%oGG  # # #"GGG#gs++ 6),W^^G-D-D)E)E&&%J)GHH 6),W&!=!=='E- 
"W++T"9"9c$ii!mm0 v{{+<====s$   
B B+*B+1B9 9CCagentr   stream_openedboolNonec                   t          |          \  }}t                              d||ndt          |                                          |t          | dd                     d S )NzmCodex Responses request failed: serialized_request_body_bytes=%s stream_opened=%s exception_chain=%s model=%sunknownmodel)r,   loggerwarningr   lowerr   )r-   r   r.   r&   exception_chains        r+   _log_codex_request_failurer8   G   sv     +I*O*O'
NN	& 1<)M  ""w	**        valueintc                j   t          | t                    rdS t          | t                    rt          | d          S t          | t                    rt          t          |           d          S t          | t
                    r/	 t          t          |           d          S # t          $ r Y dS w xY wdS )Nr   )r   r/   r;   maxfloatr   
ValueError)r:   s    r+   _coerce_usage_intr@   Y   s    % q% 5!}}% "3u::q!!!% 	s5zz1%%% 	 	 	11	1s   B" "
B0/B0dict[str, Any]c                j	   | xj         dz  c_         t          |dd          }t          |t                    r|st          | dd          }|&t          |dd          r|                    i            | j        r| j        r	 | j        s|                                  | j        	                    | j        | j
        | j        | j        dd           n8# t          $ r+}t                              d	| j        |           Y d}~nd}~ww xY wi S d
dlm}m} t'          |                    d                    }t'          |                    d                    }t'          |                    d                    }	t'          |                    d                    }
t'          |                    d                    } |||	|d
|
|          }|j        }|j        }|p|j        }||||j        |j        |j        |j        |j        d}t          | dd          }|v	 |                    |           t          |dd          }t          |t8                    r|d
k    r||_        n,# t          $ r t                              dd           Y nw xY w| xj        |z  c_        | xj        |z  c_        | xj         |z  c_         | xj!        |j        z  c_!        | xj"        |j        z  c_"        | xj#        |j        z  c_#        | xj$        |j        z  c_$        | xj%        |j        z  c_%         || j
        || j        | j        t          | dd                    }|j&        "| xj'        tQ          |j&                  z  c_'        |j)        | _*        |j+        | _,        | j        r| j        r	 | j        s|                                  | j        	                    | j        |j        |j        |j        |j        |j        |j&        tQ          |j&                  nd|j)        |j+        | j        | j        |j)        dk    rdnd| j
        d           n9# t          $ r,}t                              d| j        ||           Y d}~nd}~ww xY wi |||j&        tQ          |j&                  nd|j)        |j+        dS )a5  Translate Codex app-server token usage into Hermes accounting.

    Codex app-server reports usage via thread/tokenUsage/updated as:
    inputTokens, cachedInputTokens, outputTokens, reasoningOutputTokens,
    totalTokens.

    Hermes' canonical prompt bucket includes uncached input + cached input.
    The Codex app-server protocol does not currently expose cache-write tokens,
    so that bucket remains zero on this runtime.

    Even when Codex omits usage for a turn, Hermes should still count that turn
    as one API call for session/status accounting.
       token_usage_lastNcontext_compressor%awaiting_real_usage_after_compressionFsubscription_included)r3   billing_providerbilling_base_urlbilling_modeapi_call_countz=Codex app-server api-call persistence failed (session=%s): %sr   )CanonicalUsageestimate_usage_costinputTokenscachedInputTokensoutputTokensreasoningOutputTokenstotalTokens)input_tokensoutput_tokenscache_read_tokenscache_write_tokensreasoning_tokens	raw_usage)prompt_tokenscompletion_tokenstotal_tokensrS   rT   rU   rV   rW   model_context_windowz$codex app-server usage update failedTexc_infoapi_key )providerbase_urlr_   included)rS   rT   rU   rV   rW   estimated_cost_usdcost_statuscost_sourcerH   rI   rJ   r3   rK   zECodex app-server token persistence failed (session=%s, tokens=%d): %s)last_prompt_tokensrd   re   rf   )-session_api_callsr   r   dictupdate_from_response_session_db
session_id_session_db_created_ensure_db_sessionqueue_token_countsr3   ra   rb   r   r4   debugagent.usage_pricingrL   rM   r@   getrY   rT   r[   rS   rU   rV   rW   r;   context_lengthsession_prompt_tokenssession_completion_tokenssession_total_tokenssession_input_tokenssession_output_tokenssession_cache_read_tokenssession_cache_write_tokenssession_reasoning_tokens
amount_usdsession_estimated_cost_usdr>   statussession_cost_statussourcesession_cost_source)r-   turnusage
compressorexcrL   rM   rS   rU   rT   rW   reported_totalcanonical_usagerY   rZ   r[   
usage_dictcontext_windowcost_results                      r+   _record_codex_app_server_usager   h   s    
q D,d33EeT"" % U$8$??
"
$KUSS # ++B/// 	!1 	0 /,,... !44$+%*^%*^!8#$ 5        S$c       
 	GGGGGGGG$UYY}%=%=>>L)%))4G*H*HII%eii&?&?@@M(3J)K)KLL&uyy'?'?@@N$n!#+)  O $1M'5!A_%AL&.$'4(6,>-@+<	 	J  4d;;J	P++J777$T+A4HHN.#.. ;>A3E3E,:
) 	P 	P 	PLL?$LOOOOO	P 
=0	##'88##	,.	/">>	?#@@	##'HH##	$$(JJ$$	""o&FF""%%y"--  K )((E+2H,I,II(( + 2E + 2E U- 	, +((***00 ,9-;"1"C#2#E!0!A)5 $))?#@#@#@;?'.'.!&!&%33 549=k ! 1    $  	 	 	LLW ,       	
+!- $K$:;;;37")")   sE   AC 
D!DDAI& &&JJ)B"Q 
R"Q==RF)approx_tokensforcer   
int | Noner   c                  |st          |dd          sdS t          |dd          pd}t          |dd          pd}t                              dt          | dd          pd	|||           |s-	 d
dlm} |                     |           n# t          $ r Y nw xY wt          | dd          }|t          |dd
          dz   |_        |pd
|_        t          t          |          dd          }t          |          r ||d           nt          |d          rd|_        t          |dd          sd|_        d
|_        d|_        d| _        	 t          | dd          rT|                     dt          | dd          pdt          | dd          pddd|t          |dd
          nd
d||d           n,# t          $ r t                              dd           Y nw xY wdS )a+  Record a Codex-native context compaction boundary in Hermes state.

    The app-server owns the compacted thread context, so Hermes should not
    rewrite local transcript rows here; state.db records the boundary via the
    session event/usage counters while preserving the visible transcript.
    	compactedF	thread_idNr`   turn_idzKcodex app-server compaction observed: session=%s thread=%s turn=%s force=%srl   noner   )COMPACTION_STATUSrE   compression_countrC   record_completed_compaction)used_fallback$_verify_compaction_cleared_thresholdTrD   event_callbackzsession:compressplatformcodex_app_server)r   rl   old_session_idin_placer   runtimer   r   z.event_callback error on codex session:compressr]   )r   r4   infoagent.conversation_compressionr   _emit_statusr   r   last_compression_rough_tokensr   callablehasattrr   rg   last_completion_tokensrF   _last_compaction_in_placer   rp   )	r-   r   r   r   r   r   r   r   record_boundarys	            r+   #_record_codex_app_server_compactionr      s     {E:: uk4006BIdIt,,2G
KKU|T**4f    	HHHHHH01111 	 	 	D	  4d;;J'.+Q(
 (
(
$ 4A3EA
0 ";T
 
 O$$ 	C OJe<<<<<Z!GHH 	C>BJ;t/66 	D,.J)01J-?CJ<&+E#V5*D11 	  " 'z4 @ @ FB")%t"D"D"J&( % "- *1"$7* * * 1!*&   "  V V VEPTUUUUUV 4s%   .B
 

BBA%F5 5&GG>   	webSearch
fileChangemcpToolCalldynamicToolCallcommandExecutionzhermes-toolsitemri   r   c                4   |                      d          pd}|dk    rdS |dk    rdS |dk    rC|                      d          pd	}|                      d
          pd}|t          k    r|S d| d| S |dk    r|                      d
          pdS |dk    rdS |pdS )zSynthetic Hermes tool name for a codex item. Mirrors
    CodexEventProjector so the progress bubble and the projected
    tool_calls entry use the same identifier.r   r`   r   exec_commandr   apply_patchr   servermcptoolr2   zmcp..r   dynamicr   
web_search)rr   _INTERNAL_MCP_SERVER)r   	item_typer   r   s       r+   _codex_item_to_tool_namer   t  s       &BI&&&~L  }M!!(##,uxx,9)))K%f%%t%%%%%%xx,9,K|!	!r9   c                   |                      d          pd}|dk    r/|                      d          pd|                      d          pddS |dk    r#dd	 |                      d          pg D             iS |d
v r2|                      d          pi }t          |t                    r|nd|iS |dk    rd|                      d          pdiS i S )zArgs dict surfaced to tool_progress_callback("tool.started", ...).
    Mirrors the projector's _project_command / _project_file_change /
    _project_mcp_tool_call / _project_dynamic_tool_call shapes.r   r`   r   commandcwd)r   r   r   changesc                    g | ][}t          |t                    |                    d           pi                     d          pd|                    d          pdd\S )kindr   updatepathr`   )r   r   r   ri   rr   .0cs     r+   
<listcomp>z'_codex_item_to_args.<locals>.<listcomp>  sw     
 
 
 Jq$4G4G
eeFmm)r..v66B(UU6]](b* *
 
 
r9      r   r   	argumentsr   query)rr   r   ri   )r   r   argss      r+   _codex_item_to_argsr     s      &BI&&&88I..4"xx,". . 	.L   
 
 hhy))/R
 
 
  	
 666xx$$*!$--FttK3FFK'**0b11Ir9   c                   |                      d          pd}|dk    r%|                      d          pd}|r
|dd         ndS |dk    rpd |                      d	          pg D             }|sdS d
                    |dd                   }t          |          dk    r|dt          |          dz
   dz  }|S |dv rg|                      d          pi }t          |t                    r|sdS 	 t          j        |d          dd         S # t          t          f$ r Y dS w xY w|dk    r%|                      d          pd}|r
|dd         ndS dS )zShort human-readable preview for the tool.started bubble. Returns
    None when no useful preview is available (Hermes' UI tolerates None).r   r`   r   r   Nx   r   c                    g | ]A}t          |t                    |                    d           ,|                    d           BS )r   r   r   s     r+   r   z*_codex_item_to_preview.<locals>.<listcomp>  sR     ; ; ;1q$'';,-EE&MM;v ; ; ;r9   r   ,    z, +z morer   r   Fensure_asciir   r   )	rr   r%   r   r   ri   jsondumps	TypeErrorr?   )r   r   cmdpathspreviewr   r   s          r+   _codex_item_to_previewr     s      &BI&&&hhy!!'R)s4C4yyT)L  ; ;))<)<)B ; ; ; 	4))E"1"I&&u::>>2SZZ!^2222G666xx$$*$%% 	T 	4	:d777==:& 	 	 	44	K!!'R#-uTcT{{-4s   .D D! D!tuple[str, bool]c                   |                      d          pd}|dk    rQ|                      d          pd}|                      d          }t          |duo|dk              }|rd| d	| }||fS |d
k    rH|                      d          pd}t          |                      d          pg           }d| d| d|dvfS |dk    rs|                      d          }|r#dt          j        |d          dd          dfS |                      d          }|t          j        |d          dd         nddfS |dk    r|                      d          pg }	t          |	t                    rD|	rBt          j        |	d          dd         t          |                      dd                     fS |                      dd          }
d|
 t          |
           fS dS ) zReturn (result_text, is_error) for a completed codex tool item.
    Mirrors the projector's tool-result content so the bubble shows the
    same outcome string that ends up in the messages list.r   r`   r   aggregatedOutputexitCodeNr   z[exit z]
r   r~   r2   r   zapply_patch status=r   z
 change(s)>   appliedsuccess	completedr   r   z[error] Fr   i  Tresulti  r   contentItemsr   zsuccess=)r`   F)rr   r/   r   r   r   r   list)r   r   out	exit_codeis_errorr~   nr   r   content_itemsr   s              r+   _codex_item_completion_payloadr     sM      &BI&&&hh)**0bHHZ((		-@)q.AA 	/.9....CH}L  (##0y##)r**9&99A999==
 	
 M!!!! 	I4:e%@@@$GII  (## ! JvE2225D599')
 	

 %%%006BmT** 	} 	
=u===eteD)T22333  ((9d++#'##g%6669r9   Callable[[dict], None]c                z     i ddd fdd fd	d fdd fdd fddfd}|S )u  Build an ``on_event`` callback that wires codex app-server JSON-RPC
    notifications into Hermes' gateway UI callbacks.

    Returns a single-argument callable suitable for
    ``CodexAppServerSession(on_event=...)``.

    Translation map:
      * ``item/started`` for tool-shaped items → ``tool_progress_callback(
        "tool.started", name, preview, args)``
      * ``item/completed`` for tool-shaped items → ``tool_progress_callback(
        "tool.completed", name, None, None, duration=..., is_error=...,
        result=...)``
      * ``item/agentMessage/delta`` → ``_fire_stream_delta(text)`` so chat
        adapters can render the assistant's reply as it streams.
      * ``item/reasoning/delta`` → ``_fire_reasoning_delta(text)``
      * ``item/completed`` for ``agentMessage`` →
        ``_emit_interim_assistant_message({"role": "assistant",
        "content": text})``. The gateway's ``already_streamed`` check
        dedupes against any text the stream-delta callback already
        rendered for the same message.

    All callback invocations are guarded — a buggy display callback must
    not tear down the codex turn loop. Errors are logged at DEBUG so the
    notification stream keeps flowing regardless.
    r   ri   namer   r   c                   ddl m} |                     d          pd}|                     d          pd}|dk    r |d|          S |dk    r |d	|          S |d
k    r@|                     d          pd}|                     d          pd} |d| d| |          S |dk    r&|                     d          pd} |d| |          S  |||          S )zDeterministic tool_call id mirroring CodexEventProjector, so a
        live TUI tool card correlates with the same tool call after the
        session is resumed and history is projected.r   )_deterministic_call_idr   r`   r   r   execr   r   r   r   r   r   r2   mcp____r   dyn_)&agent.transports.codex_event_projectorr   rr   )r   r   r   item_idr   r   r   s          r+   _stable_call_idz;make_codex_app_server_event_bridge.<locals>._stable_call_id	  s'    	RQQQQQ((4..&BHHV$$*	***))&':::$$))-AAA%%XXh''05F88F##0yD))*B&*B*BD*B*BGLLL)))88F##0yD))---AAA%%dG444r9   r0   c                   |                      d          pd}t          |           }t          |           }|r||t          j                    f|<   t          dd           }|J	  |d|t          |           |           n-# t          $ r  t          	                    d|d           Y nw xY wt          dd           }|H	  | | |          ||           d S # t          $ r! t          	                    d	|d           Y d S w xY wd S )
Nr   r`   tool_progress_callbackztool.startedz4tool_progress_callback raised on tool.started for %sTr]   tool_start_callbackz!tool_start_callback raised for %s)
rr   r   r   time	monotonicr   r   r   r4   rp   )	r   r   r   r   cbstart_cbr   r-   starteds	         r+   _fire_tool_startedz>make_codex_app_server_event_bridge.<locals>._fire_tool_started  sq   ((4..&B'--"4(( 	> $dDN,<,<=GGU4d;;>>4)?)E)EtLLLL   J4       5"7>>t44dDAAAAA   7         s$   &B 'B,+B,C 'DDc           	        |                      d          pd}t          |           }                    |d           }d }|                      d          }t          |t          t
          f          r|dk    r|dz  }n|t          j                    |d         z
  }t          |           \  }}t          dd           }|A	  |d|d d |||	           n-# t          $ r  t                              d
|d           Y nw xY wt          dd           }	|	b||d         nt          |           }
	  |	 | |          ||
|           d S # t          $ r! t                              d|d           Y d S w xY wd S )Nr   r`   
durationMsr   g     @@   r   ztool.completed)durationr   r   z6tool_progress_callback raised on tool.completed for %sTr]   tool_complete_callbackrC   z$tool_complete_callback raised for %s)rr   r   popr   r;   r>   r   r   r   r   r   r4   rp   r   )r   r   r   priorr  codex_msr   r   r   complete_cbr   r   r-   r   s              r+   _fire_tool_completedz@make_codex_app_server_event_bridge.<locals>._fire_tool_completed:  s   ((4..&B'--GT**
 88L))he-- 	3(a--&(HH~''%(2H9$??U4d;;>#T4$xH H H H H   L4      
 e%=tDD"$05886I$6O6ODOOD$77tVLLLLL   :D4       	 #"s$   C 'C>=C>.E 'E32E3paramsc                .   |                      d          p|                      d          pd}t          |t                    r|sd S t          dd           }|d S 	  ||           d S # t          $ r  t
                              dd           Y d S w xY w)Ndeltatextr`   _fire_stream_deltaz_fire_stream_delta raisedTr]   rr   r   r   r   r   r4   rp   r  r  fnr-   s      r+   _fire_text_deltaz<make_codex_app_server_event_bridge.<locals>._fire_text_delta]  s    zz'"">fjj&8&8>B$$$ 	D 	FU0$77:F	EBtHHHHH 	E 	E 	ELL4tLDDDDDD	E   A* *&BBc                .   |                      d          p|                      d          pd}t          |t                    r|sd S t          dd           }|d S 	  ||           d S # t          $ r  t
                              dd           Y d S w xY w)Nr  r  r`   _fire_reasoning_deltaz_fire_reasoning_delta raisedTr]   r  r  s      r+   r  zAmake_codex_app_server_event_bridge.<locals>._fire_reasoning_deltai  s    zz'"">fjj&8&8>B$$$ 	D 	FU3T:::F	HBtHHHHH 	H 	H 	HLL7$LGGGGGG	Hr  c                T   |                      d          pd}t          |t                    r|                                sd S t	          dd          sd S t	          dd           }|d S 	  |d|d           d S # t
          $ r  t                              dd	           Y d S w xY w)
Nr  r`   show_commentaryT_emit_interim_assistant_message	assistant)roler   z&_emit_interim_assistant_message raisedr]   )rr   r   r   stripr   r   r4   rp   )r   r  emitr-   s      r+   _fire_agent_message_completedzImake_codex_app_server_event_bridge.<locals>._fire_agent_message_completedu  s    xx%2$$$ 	DJJLL 	F u/66 	Fu?FF<F	D+$7788888 	 	 	LL84       	s   -A= =&B'&B'notec                (   t          | t                    sd S |                     d          pd}|                     d          pi }t          |t                    si }|dk    r |           d S |dv r |           d S |                    d          }t          |t                    sd S |                    d          pd}|dk    r|t          v r 	|           d S |d	k    r)|t          v r |           d S |d
k    r |           d S d S d S )Nmethodr`   r  zitem/agentMessage/delta>   item/reasoning/deltaitem/reasoning/summaryDeltar   r   zitem/startedzitem/completedagentMessage)r   ri   rr   _CODEX_TOOL_ITEM_TYPES)
r  r!  r  r   r   r  r  r  r
  r   s
        r+   on_eventz4make_codex_app_server_event_bridge.<locals>.on_event  sl   $%% 	F(##)r(##)r&$'' 	F...V$$$FLLL!!&)))Fzz&!!$%% 	FHHV$$*	^##	5K(K(Kt$$$F%%%222$$T*****n,,--d33333	 &% -,r9   )r   ri   r   r   r   r   )r   ri   r   r0   )r  ri   r   r0   )r  ri   r   r0    )	r-   r&  r  r  r  r
  r   r   r   s	   ` @@@@@@@r+   "make_codex_app_server_event_bridger(    s   : 35G5 5 5 5*       8! ! ! ! ! ! ! !F
E 
E 
E 
E 
E 
E
H 
H 
H 
H 
H 
H     &4 4 4 4 4 4 4 4 4 44 Or9   )should_review_memoryuser_messageoriginal_user_messagemessagesList[Dict[str, Any]]effective_task_idr)  Dict[str, Any]c               @	   ddl m}m} t          | d          r| j        ddlm} t          | dd          pt           |                      }		 ddl	m
}
  |
            }n# t          $ r d}Y nw xY wd}	 dd	lm}  |            }n,# t          $ r t                              d
d           Y nw xY w ||	| |||          t!          |                     | _        	 | j                            |          }n# t          $ r}t                              d           	 | j                                         n# t          $ r Y nw xY wd| _        t)          t          | dd                    }|rt          | dd          nd}|r|                                  d| d|ddd|d|rd|ini dt          |          icY d}~S d}~ww xY wt)          |j        ot          | dd                    }|rt          | dd          nd}|r|                                  t          |dd          rRt                              d|j                   	 | j                                         n# t          $ r Y nw xY wd| _        |j        rddlm} |j        D ]} |||           t          | dd          s	 |                     |          }n.# t          $ r! d}t                              dd           Y nw xY w|du r*t                              dt          | dd                     t          | dd          |j        z   | _        t?          | |           tA          | |          }d }d}| j!        dk    r"| j        | j!        k    rd!| j"        v r	d}d| _        |j        sS|j        L	 | #                    ||j$        d|"           n,# t          $ r t                              d#d           Y nw xY w|j$        r^|j        sW|s|rS	 | %                    tM          |          ||$           n,# t          $ r t                              d%d           Y nw xY w|j$        |||j         o|j        du |j        p|j        du|d|rd|ini |j        d|j'        |j(        d&|S )'aN  Codex app-server runtime path. Hands the entire turn to a `codex
    app-server` subprocess and projects its events back into Hermes'
    messages list so memory/skill review keep working.

    Called from run_conversation() when agent.api_mode == "codex_app_server".
    Returns the same dict shape as the chat_completions path.
    r   )CodexAppServerSession_ServerRequestRouting_codex_sessionN)resolve_agent_cwdsession_cwd)_get_approval_callbackF)is_approval_bypass_activezLcodex app-server: approval-bypass lookup failed; keeping fail-closed defaultTr]   )auto_approve_execauto_approve_apply_patch)r   approval_callbackrequest_routingr&  )
user_inputzcodex app-server turn failed_interrupt_requested_interrupt_messagezCodex app-server turn failed: z:. Fall back to default runtime with `/codex-runtime auto`.)final_responser,  	api_callsr   partialinterruptedinterrupt_messager   should_retirez1codex app-server session retired (turn error: %s))append_messagerk   z/codex app-server projected-message flush failedu   codex app-server turn was delivered but could NOT be persisted to the session DB (session=%s) — this turn will be missing after restart/resumerl   _iters_since_skillrC   skill_manage)r+  r?  rB  r,  zexternal memory sync raised)messages_snapshotreview_memoryreview_skillszbackground review spawn raised)r   agent_persistedcodex_thread_idcodex_turn_id)))agent.transports.codex_app_server_sessionr1  r2  r   r3  agent.runtime_cwdr4  r   r   tools.terminal_toolr6  r   tools.approvalr7  r4   rp   r(  run_turn	exceptioncloser/   clear_interruptrB  r5   r   projected_messagesagent.message_metadatarE  _flush_messages_to_session_dbtool_iterationsrF  r   r   _skill_nudge_intervalvalid_tool_names_sync_external_memory_for_turn
final_text_spawn_background_reviewr   r   r   )r-   r*  r+  r,  r.  r)  r1  r2  r4  r   r6  r:  auto_approve_requestsr7  r   r   _user_interruptedr>  rE  projected_message_codex_flush_okusage_resultr@  should_review_skillss                           r+   run_codex_app_server_turnre    s>            5*++ 1
u/C/K777777e]D11MS9J9J9L9L5M5M	%BBBBBB 6 6 8 8 	% 	% 	% $	% !&		@@@@@@$=$=$?$?!! 	 	 	LL.      	  54/11"7)>   8>> 
  
  
%
#,,,EE #
 #
 #
7888	 &&(((( 	 	 	D	# E1599
 

 !GE/666 	
  	$!!###L L L L !,
 
 &$&899
 SXX
 
 	
 	
 	
 	
 	
 	
'#
P JWU,BEJJ  7HQ+T222T     t_e,, 	$?J	
 	
 	
	 &&(((( 	 	 	D	#
  (999999!%!8 	8 	8N8%67777 5-..:"'"E"Eh"O"O   "'E!       %'' ; E<66	    	+Q//$2FF 
 (t4441%>>LI !#a''$(CCCe444##$   	G
 2	G00&;#!!	 1      	G 	G 	GLL6LFFFFF	G 	J J "J &:J
	J**"&x..22 +    
  	J 	J 	JLL9DLIIIII	J /))@djD.@#=tz'=(  " "455   >5  6 7 s   A   A/.A/5B &B/.B/C; ;
G
G D:9G:
EGEA8G?G
G
I) )
I65I65K (K65K6%O &O-,O-%P) )&QQ>   response.failedresponse.completedresponse.incompleteeventr   defaultc                    t          | |d          }|+t          | t                    r|                     ||          }||n|S )zSField access that handles both attr-style (SDK objects) and dict (raw JSON) events.Nr   r   ri   rr   )ri  r   rj  r:   s       r+   _event_fieldrm    sH    E4&&E}E400}		$((%5572r9   c                    t          | |d          }|+t          | t                    r|                     ||          }||n|S )zGField access for nested Response items (attr-style SDK object or dict).Nrl  )r   r   rj  r:   s       r+   _item_fieldro    sH    D$%%E}D$//}w''%5572r9   c                    ddl m} t           d          d fd} |d	          }|$t          |t                    st	          |          }|pd                                pd} || |d           |d                    )a;  Raise a ``_StreamErrorEvent`` from a ``type=error`` SSE frame.

    The Responses spec puts the failure details at the top level of the
    frame (``{"type": "error", "code": ..., "message": ..., "param": ...}``),
    but the official OpenAI SDK and several OpenAI-compatible proxies wrap
    them in an HTTP-style nested envelope instead
    (``{"type": "error", "error": {"code": ..., "message": ..., "param": ...}}``).
    Read the top-level fields first, then fall back to the nested envelope so
    the error classifier sees the provider's real code/message (rate-limit vs
    context-overflow vs entitlement) rather than the generic placeholder.
    Port of anomalyco/opencode#36130.

    Imported lazily so this module stays importable from places that don't
    pull in ``run_agent`` (e.g. plugin code, doc tools).
    r   )_StreamErrorEventr   r   r   r   r   c                P    t          |           }|t          |           }|S N)rm  ro  )r   r:   ri  nesteds     r+   _error_fieldz)_raise_stream_error.<locals>._error_field  s0    UD))=V/--Er9   messageNzstream emitted error eventcodeparam)rw  rx  )r   r   r   r   )	run_agentrq  rm  r   r   r  )ri  rq  ru  raw_messagerv  rt  s   `    @r+   _raise_stream_errorr{    s      ,+++++%))F       ,y))Kz+s'C'C+&&::AACCcGcG

\&!!l7##   r9   )on_text_deltaon_reasoning_deltaon_commentary_messageon_first_deltar&  interrupt_check
event_iterr3   r   c          
     (   g }g }	d}
d}d}g }d}d}d}d}d}d}d}| D ]}|J	  ||           n=# t           t          f$ r  t          $ r t                              dd           Y nw xY w| |            r nt          |dd          }t          |t                    sd}|d	k    rt          |           |d
k    rt          |d          }t          |dd          }|dk    rWt          |dd          }t          |t                    r&|
                                                                nd}|dk    rg }nd}dt          |          v rd}
6d|v s|dk    rEt          |dd          }|rZ|dk    rT|                    |           |<|:	  ||           n# t          $ r t                              dd           Y nw xY wn|rB|dk    r<|9	  ||           n# t          $ r t                              dd           Y nw xY wn|r|	                    |           |
sy|s<d}|8	  |             n,# t          $ r t                              dd           Y nw xY w|9	  ||           n,# t          $ r t                              dd           Y nw xY wd|v rd}
d|v rwd|v rst          |dd          }|r^|\t          |d          }||||k    rd| }||}	  ||           n,# t          $ r t                              dd           Y nw xY w|dk    r=t          |d          }|(|                    |           t          |dd          }t          |t                    r&|
                                                                nd}|dk    r|d                    |          
                                }|sWt          |dg           } t          | t                    r1d                    d | D                       
                                }|r9	  ||           n,# t          $ r t                              dd           Y nw xY wg }K|t          v rd}t          |d          }!|!Vt!          |!dd          }|*t          |!t"                    r|!                    d          }t!          |!d d          }"|"*t          |!t"                    r|!                    d           }"|"}t!          |!d!d          }#|#*t          |!t"                    r|!                    d!          }#t          |#t                    r|#}|d"k    r=t!          |!d#d          }|*t          |!t"                    r|!                    d#          }|d$k    r=t!          |!d	d          }|*t          |!t"                    r|!                    d	          }|d%k    r|pd}n|d"k    r|pd&}n
|d$k    r|pd'} n|rt          |          }$n@|	r<|
s:d                    |	          }%t'          dd(dt'          d)|%*          g+          g}$ng }$|s|$st)          d,          d                    |	          }&t'          |$|&||||||-          }'|'S ).u  Consume a Codex Responses SSE event stream and return a final response.

    The returned object is a ``SimpleNamespace`` shaped like the SDK's typed
    ``Response`` for the fields downstream code actually reads:

    * ``output``: list of output items, assembled from ``response.output_item.done``.
      For tool-call turns this contains the function_call items; for plain-text
      turns it contains a synthesized ``message`` item built from streamed deltas
      if no message item was emitted directly.
    * ``output_text``: assembled text from ``response.output_text.delta`` deltas.
    * ``usage``: copied from the terminal event's ``response.usage`` (when present).
    * ``status``: ``completed`` / ``incomplete`` / ``failed`` (or ``completed`` if
      the stream ended without a terminal frame but produced content).
    * ``id``: ``response.id`` when present.
    * ``incomplete_details``: passed through for ``response.incomplete`` frames.
    * ``error``: passed through for ``response.failed`` frames.
    * ``model``: from kwargs (the wire model name is not authoritative).

    Critically, we never read ``response.output`` from the terminal event for
    content reconstruction — only ``usage``, ``status``, ``id``.  That field
    being ``null`` / ``[]`` / missing is fine.

    Callbacks:

    * ``on_text_delta(str)`` — fires per ``response.output_text.delta``, suppressed
      once a function_call event is seen (so tool-call turns don't bleed text
      into the chat).
    * ``on_reasoning_delta(str)`` — fires per ``response.reasoning.*.delta`` and
      ``phase=analysis`` message deltas. When no dedicated commentary callback
      is supplied, commentary also uses this legacy fallback.
    * ``on_commentary_message(str)`` — fires once per completed
      ``phase=commentary`` message, before any following tool item executes.
    * ``on_first_delta()`` — one-shot, fires on the first text delta only.
    * ``on_event(event)`` — fires for every event before any other processing.
      Used for watchdog activity, debug logging, anything wire-shape-agnostic.
    * ``interrupt_check()`` — returns True to break the loop early.
    FNr   z!Codex stream on_event hook raisedTr]   r   r`   r   zresponse.output_item.addedr   rv  phase
commentaryfunction_callzoutput_text.deltazresponse.output_text.deltar  z&Codex stream on_reasoning_delta raisedanalysisz"Codex stream on_first_delta raisedz!Codex stream on_text_delta raised	reasoningsummary_indexz

zresponse.output_item.doner   c              3     K   | ]9}t          |d d          dk    t          t          |dd          pd          V  :dS )r   r`   output_textr  N)ro  r   )r   parts     r+   	<genexpr>z._consume_codex_event_stream.<locals>.<genexpr>  s^       6 6$(#.tVR#@#@M#Q#Q !$Kfb$A$A$GR H H#Q#Q#Q#Q6 6r9   z)Codex stream on_commentary_message raisedresponser   r   r~   rh  incomplete_detailsrf  rg  
incompletefailedr  r  )r   r  )r   r  r~   r   z7Codex Responses stream did not emit a terminal response)outputr  r   r~   r   r3   r  r   )TimeoutErrorInterruptedErrorr   r4   rp   rm  r   r   r{  ro  r  r6   r   r%   r   _TERMINAL_EVENT_TYPESr   ri   rr   r   RuntimeError)(r  r3   r|  r}  r~  r  r&  r  collected_output_itemscollected_text_deltashas_tool_callsfirst_delta_firedactive_message_phasecommentary_text_deltasactive_summary_indexterminal_statusterminal_usageterminal_response_idterminal_incomplete_detailsterminal_errorsaw_terminalri  
event_typer   r   r  
delta_textreasoning_textr  	done_item
done_phasecommentary_textcontent_partsresp_objridrstatusr  	assembledassembled_textfinals(                                           r+   _consume_codex_event_streamr    s	   ` )+')N'+(* !%&ON $'+NL a a	Q "23     Q Q Q @4PPPPPQ &??+<+<&E!%44
*c** 	J   &&& 555v..D#D&"55II%%#D'488@J5RU@V@V'`u{{}}':':'<'<'<\`$'<77-/*'+$#i..00!%*,,
>Z0Z0Z%eWb99J ]2lBB&--j999 )05G5S^**:6666$ ^ ^ ^%MX\]]]]]^ ] 4
 B B%1^**:6666$ ^ ^ ^%MX\]]]]]^ 2
  ]%,,Z888% ], b,0))5b . 0 0 0 0#, b b b &-Q\` a a a a ab$0])M*5555( ] ] ]"LL)LW[L\\\\\]j((!N *$$J)>)>)%"==N Z"4"@ !-UO D D!-,8%)===%<N%<%<N ,+8(Z&&~6666  Z Z ZLL!ITXLYYYYYZ444$UF33I$&--i888(GTBB
;EjRU;V;V`Z--//55777\`
--2G2S&(gg.D&E&E&K&K&M&MO* &(3Iy"(M(M%mT:: &.0gg 6 6,96 6 6 / / $egg	 ,
 ' 11/BBBB(   "LL K)- )     
 .0*...L#E:66H#!(7D!A!A!)j4.H.H)%-\\'%:%:Nhd33;:h#=#=;",,t,,C'*$!(Hd;;?z(D'A'A?&ll844Ggs++ .&-O!66629(DXZ^2_2_/2:z(TX?Y?Y:6>llCW6X6X3!222%,Xw%E%EN%-*Xt2L2L-)1g)>)>111"1"@[444"1"A\000"1"=XE? /H  ,--	 	~ 	GG122	!$-iHHHI	
 
 
    
 
E
 
 	
 WW233N"6	 	 	E Ls{   /7A)(A)F&GGG""&H
H/
H::&I#"I#)I55&JJ*K66&LL,P88&Q! Q!r   c                   t          |          }t          | dd          }t          |          rt           |                      nd}|s|S g }d|v r*|                    d           |                    d           |                    d          }t          |t                     rZd|v rVt          |          }|                    d           |r||d<   n|                    d           |                    d           |rRt          	                    d|                    dt          | dd	                    d

                    |                     |S )u  Drop fields the ChatGPT OAuth Codex endpoint does not accept.

    This guard intentionally lives at the final wire boundary, after Relay or
    other request middleware has had a chance to transform the request. The
    normal transport builder already omits ``prompt_cache_retention`` for this
    endpoint, but a late mutation must not be allowed to turn a valid tool
    follow-up into a non-retryable HTTP 400.

    Explicit ``request_overrides`` are subject to the same endpoint contract:
    unsupported retention is dropped with a warning instead of being sent and
    rejected by the provider. The check covers both the top-level kwarg and a
    nested ``extra_body`` entry — the OpenAI SDK merges ``extra_body`` into
    the outgoing JSON body, so either shape reaches the endpoint.
    _is_codex_backendNFprompt_cache_retentionz	top-level
extra_bodyz^Dropped unsupported prompt_cache_retention at consumer Codex wire boundary (model=%s, via %s).r3   r2   r   )ri   r   r   r/   r  r   rr   r   r4   r5   r%   )r-   r   	sanitizedbackend_predicateis_consumer_codexdropped_fromr  s          r+    _sanitize_consumer_codex_requestr    sz   $ WI
  ':DAA%-.?%@%@K  !!!e    L9,,.///K(((
 |,,J*d## *(@J(N(N*%%
/000 	(&0Il##MM,'''L))) 
0MM'75'9#E#EFFIIl##		
 	
 	
 r9   
api_kwargsclientc                    ddl }ddlm} ddlm} |p                     d          d}g  _        d< fd}d< fd}	d< fd}
d= fd}t          |dz             D ]l} j        rt          d          g ddid> fd}d? fd}d@ fd}dAfd}	 |
                    t                    |t          t           dd          pd          t          t           dd          pd           t                              d!          pd          ||j        d" |d# d$t           d%d          t           d&d'          rd(n't!          t           d)d          pd          dk    rd*nd+|d,d-.          }n# |j        |j        |j        t(          f$ rb}||k     r<t*                              d/|dz   |dz                                    |           Y d}~~t1           |d         du0            d}~w|$ r }t1           |d         du0            d}~ww xY wdB fd1}	 	 t3          |                    d!          ||	t           d2d          t           d3d-          r|
nd|||4          }nu# |j        |j        |j        t(          f$ r}||k     rt*                              d5|dz   |dz                                    |           Y d}~t          |d6d          }t5          |          r7	  |             # t6          $ r |                     d7           Y w xY wt1           |d         du0            d}~wt:          $ rq |j        h|j        cY t          |d6d          }t5          |          r=	  |             c S # t6          $ r" |                     d7           Y c S Y c S w xY wc S  |$ r }t1           |d         du0            d}~ww xY w j        s	 |D ]}n# |j        |j        |j        t(          f$ r8}t*                              d8                                 |           Y d}~n]d}~w|$ rR}t1           |d         du0           t*                              d8                                 |           Y d}~nd}~ww xY w|j         d9v r\t*                              d:|j         |j!        |j"        tG          d;  j        D                                                                   |t          |d6d          }t5          |          r=	  |             c S # t6          $ r" |                     d7           Y c S Y c S w xY wc S # t          |d6d          }t5          |          r7	  |             w # t6          $ r |                     d7           Y w Y w w xY ww xY wdS )Cu  Execute one streaming Responses API request and return the final response.

    Uses ``responses.create(stream=True)`` (low-level raw event iteration)
    rather than the high-level ``responses.stream(...)`` helper.  This makes
    us structurally immune to backend drift in the ``response.completed``
    payload shape — we never let the SDK reconstruct a typed object from
    the terminal event's ``output`` field.
    r   N)APIConnectionError)	relay_llmcodex_stream_direct)reasonrC   r  r   r   r0   c                f    j                             |                                |            d S rs  )_codex_streamed_text_partsr   r  r  r-   s    r+   _on_text_deltaz(run_codex_stream.<locals>._on_text_deltag  s4    (//555  &&&&&r9   c                2                         |            d S rs  )r  r  s    r+   _on_reasoning_deltaz-run_codex_stream.<locals>._on_reasoning_deltak  s    ##D)))))r9   c                2                         |            d S rs  )_fire_streamed_codex_commentaryr  s    r+   _on_commentary_messagez0run_codex_stream.<locals>._on_commentary_messagen  s    --d33333r9   ri  r   c                b    t          j                     _                            d           d S )Nzreceiving stream response)r   _codex_stream_last_event_ts_touch_activity)ri  r-   s    r+   	_on_eventz#run_codex_stream.<locals>._on_eventq  s,    ,0IKK)9:::::r9   z+Agent interrupted before Codex stream retryr:   next_api_kwargsrA   c                R    t          |           }d|d<    j        j        di |S )NTstreamr'  )r  	responsescreate)r  stream_kwargsactive_clientr-   s     r+   _open_codex_streamz,run_codex_stream.<locals>._open_codex_stream}  s@    < M '+M(#1=*1BBMBBBr9   _raw_streamc                ,    t                    d<   d S )Nr:   )r	   )r  r-   writer_tokens    r+   _codex_stream_createdz/run_codex_stream.<locals>._codex_stream_created  s     %8$>$>L!!!r9   _chunkr/   c                    d         }|t          |          rdS t                              d                    dd                     dS )Nr:   Tz~Codex streaming attempt superseded by a newer stream; stopping consumption to preserve the single-writer invariant (model=%s).r3   r2   F)r
   r4   r5   rr   )r  tokenr-   r  r  s     r+   _accept_codex_chunkz-run_codex_stream.<locals>._accept_codex_chunk  s[     )E} 8 F F}tNN( w	22	   5r9   c                 f    t          t                                         d                    S )Nr3   )r3   )r  r   rr   )r  intercepted_eventss   r+   _finalize_codex_streamz0run_codex_stream.<locals>._finalize_codex_stream  s5    .'(( nnW--   r9   rl   r`   ra   codexr3   c                    | S rs  r'  )chunks    r+   <lambda>z"run_codex_stream.<locals>.<lambda>  s    E r9   c                ^    t          t          | d          ot          | d                     S )Nr  __iter__)r/   r   )r  s    r+   r  z"run_codex_stream.<locals>.<lambda>  s/    dHh//U*8U8U4U? ? r9   codex_responses_current_api_request_idis_subagentF	delegated_fallback_indexfallbackprimary)api_modeapi_request_id	call_roleretry_countT)rl   r   
model_name	finalizeron_stream_createdon_chunkchunk_adapteraccept_chunkcompleted_response_predicatemetadatadefer_logical_completionzLCodex Responses stream connect failed (attempt %s/%s); retrying. %s error=%s)r.   c                 ,    t           j                  S rs  )r/   r=  )r-   s   r+   _interrupt_or_supersededz2run_codex_stream.<locals>._interrupt_or_superseded  s    2333r9   interim_assistant_callbackr  )r3   r|  r}  r~  r  r&  r  z\Codex Responses stream transport failed mid-iteration (attempt %s/%s); retrying. %s error=%srT  codex_stream_close_failedzCodex Responses stream transport finalization failed after a terminal response was already received; returning the completed response instead of retrying. %s error=%s>   r  r  zbCodex Responses stream terminal status=%s (incomplete_details=%s, error=%s, streamed_chars=%d). %sc              3  4   K   | ]}t          |          V  d S rs  )r   )r   ps     r+   r  z#run_codex_stream.<locals>.<genexpr>2  s(      II1AIIIIIIr9   )r  r   r   r0   ri  r   r   r0   )r  rA   )r  r   r   r0   )r  r   r   r/   )r   r   )r   r/   )$httpxopenair  r-   r  _ensure_primary_openai_clientr  ranger=  r  r  ri   r   r   rr   r   r;   RemoteProtocolErrorReadTimeoutConnectErrorConnectionErrorr4   rp   _client_log_contextr8   r  r   r   _abort_request_openai_clientr  r?  r5   r~   r  r   sum)r-   r  r  r  _httpx_APIConnectionErrorr  max_stream_retriesr  r  r  r  attemptr  r  r  r  event_streamr   r  r  close_fn_ignoredr  r  r  s   ``                     @@@r+   run_codex_streamr  T  s	    @@@@@@_eAAI^A__M-/E$' ' ' ' ' '* * * * * *4 4 4 4 4 4; ; ; ; ; ;
 +a/00 T T% 	R"#PQQQ	C 	C 	C 	C 	C 	C 	C	? 	? 	? 	? 	? 	? 	?

	 
	 
	 
	 
	 
	 
	 
		 	 	 	 	 	 	9	$++Z  "wulB??E2FF
B77B7CCz~~g66<"==0"7+2110. . !2&-e5NPT&U&U #5-??' wu.?CCHqIIAMM (Z&#*  *.5 ,  LL: &	
 	 	 	 +++,aK&*--//   &*734?   
 " 	 	 	&*734?   
 		4 	4 	4 	4 	4 	4p	+3 $..11"0': $E+GNNZ '/@$ G G [ /.
 "#1&$<  " .0BFDWYhi   ///LLA!%7!%;1133S	   HHHF |Wd;;H!! HJJJJ     )::)2M ;   G +".w"7t"C   
    .:'666t |Wd;;H!! HJJJJJJ     )::)2M ;        *)))  u &   *".w"7t"C   
  - $0   .&'#	    NN0 1133S        +   .&27&;4&G   
 NN0 1133S        |777OL%":EKII(HIIIII--//   |Wd;;H!! HJJJJJJ     )::)2M ;        *)))   |Wd;;H!! HJJJJ     )::)2M ;      *)GT Ts  C!F  H"<G:G::H"HH"-AI=;U3=O/<MU3;
L#L.-L.3MO/)U3
N#OO
O/O**O//
U3:P ?U3 R*.QU3R*AR% U3%R**A)U34
U#U-,U-3!W
V W #W	WW	Wc                &    t          | ||          S )a  Backward-compatible alias for the unified event-driven path.

    Historically this was the fallback when the SDK's high-level
    ``responses.stream(...)`` helper raised on shape drift.  The primary
    path now does exactly what the fallback did, so this just forwards.
    Kept as a public symbol because tests and a small number of call sites
    still reference it by name.
    )r  )r  )r-   r  r  s      r+    run_codex_create_stream_fallbackr  M  s     E:f====r9   )re  r  r  r  r(  )r   r   r   r   )r-   r   r   r   r.   r/   r   r0   )r:   r   r   r;   )r   rA   )r   r   r   r/   r   r/   )r   ri   r   r   )r   ri   r   ri   )r   ri   r   r   )r   ri   r   r   )r   r   )r*  r   r+  r   r,  r-  r.  r   r)  r/   r   r/  rs  )ri  r   r   r   rj  r   r   r   )r   r   r   r   rj  r   r   r   r  )r  r   r3   r   r   r   )r-   r   r   rA   r   rA   )NN)r  ri   r  r   )*__doc__
__future__r   r   loggingr   typesr   typingr   r   r   r   agent.stream_single_writerr	   r
   	getLoggerr   r4   r,   r8   r@   r   r   	frozensetr%  r   r   r   r   r   r(  re  r  rm  ro  r{  r  r  r  r  __all__r'  r9   r+   <module>r      s     # " " " " "    ! ! ! ! ! ! , , , , , , , , , , , , T T T T T T T T		8	$	$&> &> &> &>R   $   R R R Rr !%O O O O O ON #UUU   & " " " ",   ,   <) ) ) )Xx x x xD "'S S S S S SZ	 "	 # # #   3 3 3 3 33 3 3 3 3" " " "R K K K K K K\5 5 5 5pv v v v vr	> 	> 	> 	> 	>  r9   