
    4Rj                      U d dl mZ d dlZd dlZd dlZd dlmZmZm	Z	m
Z
mZmZmZmZmZmZmZ d dlmZmZ d dlmZmZ d dlZddlmZ ddlmZ dd	lmZ dd
lm Z m!Z! ddl"m#Z#m$Z$m%Z% ddl&m'Z' ddl(m)Z)m*Z*m+Z+ ddl,m-Z- ddl.m/Z/ ddl0m1Z1 ddl2m3Z3 ddl4m5Z5 ddl6m7Z7 ddgZ8 ejr                  d      Z:de;d<   dZ<dZ=de;d<   	  G d d      Z> edd       Z?d!e;d"<    ed#d$       Z@d%e;d&<    G d' de*      ZA G d( d)e      ZB G d* d+e      ZC G d, d-e      ZD G d. d/e      ZE G d0 d1      ZFdTd2ZGdUd3ZH G d4 d5      ZIdVd6ZJdWd7ZK G d8 d9      ZLdXd:ZMdYd;ZNdZd<ZOd[d=ZPd\d>ZQd\d?ZRd]d@ZSd^dAZTd_dBZUd`dCZVdadDZWdbdEZXdcdFZYdddGZZdedHZ[dedIZ\dfdJZ]dgdKZ^dhdLZ_	 	 	 	 	 	 	 	 didMZ`djdNZa	 	 	 	 	 	 dkdOZb G dP dQej                        Zd G dR dSej                        Zfy)l    )annotationsN)AnyDictListCallableIterableIteratorOptional	GeneratorAsyncIteratorAsyncGeneratorcast)Token
ContextVar)Literaloverride   )is_dict)	BaseModel)
APIRequest)APIResponseAsyncAPIResponse)StreamAsyncStreamServerSentEvent)AnthropicError)CallNext
MiddlewareAsyncCallNext)merge_headers)Message   )helper_header)BetaMessage)AnthropicBetaParam)BetaFallbackParamBetaFallbackStateBetaRefusalFallbackMiddlewarezanthropic.lib.middlewarezlogging.Loggerlogz/v1/messages)zfallback-credit-2026-06-01tuple[AnthropicBetaParam, ...]DEFAULT_BETASc                  6    e Zd ZU dZded<   	 ddZd	dZd
dZy)r'   u{  Tracks which fallback a sequence of requests is pinned to.

    Create one and enter it (`with state:` — the same context manager works for
    both clients) around every request that should share the pin — the turns of
    one conversation, or any wider scope the stickiness should apply to;
    `BetaRefusalFallbackMiddleware` mutates it in place when a model refuses.
    z
int | Noneindexc                    d | _         y N)r-   selfs    k/var/www/html/meridian/meridian-ai/venv/lib/python3.12/site-packages/anthropic/lib/middleware/_fallbacks.py__init__zBetaFallbackState.__init__D   s	    
    c                    t         j                  |       }t        j                  g t        j                         |       | S r/   )_fallback_stateset_fallback_state_tokensget)r1   tokens     r2   	__enter__zBetaFallbackState.__enter__G   s:    ##D)""#I%;%?%?%A#I5#IJr4   c                    t         j                         }t         j                  |d d        t        j	                  |d          y )N)r8   r9   r7   r6   reset)r1   exc_infotokenss      r2   __exit__zBetaFallbackState.__exit__L   s6    '++-""6#2;/fRj)r4   NreturnNone)rC   r'   )r?   objectrC   rD   )__name__
__module____qualname____doc____annotations__r3   r;   rA    r4   r2   r'   r'   4   s#     
*r4   anthropic_beta_fallback_state)defaultz$ContextVar[BetaFallbackState | None]r6   $anthropic_beta_fallback_state_tokensrK   z7ContextVar[tuple[Token[BetaFallbackState | None], ...]]r8   c                      e Zd ZdZdd	 	 	 	 	 ddZedd       Zedd       ZddZddZ	dd	Z
	 	 	 	 	 	 	 	 	 	 	 	 	 	 dd
Z	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZ	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZ	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZy)r(   u  Middleware that retries refused beta `/v1/messages` requests down a
    fallback chain, reproducing the server-side `fallbacks` wire shape
    client-side.

    Only `client.beta.messages` requests are handled — refusals minted by the
    first-party `client.messages` surface carry no `fallback_credit_token`, so
    those requests pass through untouched.

    Non-streaming: when a response comes back with `stop_reason: "refusal"`, the
    request is retried with each entry of `fallbacks` merged over the original
    params — passing along the refusal's `fallback_credit_token` when it minted
    one — until a model accepts or the chain is exhausted. A `fallback` seam
    block per model boundary is prepended to the served message's content —
    the same block shape the streaming splice emits. The served hop's `usage`
    is left verbatim (streaming rewrites it to per-hop `usage.iterations`).

    Streaming: when the stream ends in `stop_reason: "refusal"`, a second
    request is issued to the fallback model. It carries the refusal's
    `fallback_credit_token`, plus the refused model's partial output as a
    trailing assistant prefill when the refusal grants one
    (`fallback_has_prefill_claim`). The fallback's events are then spliced onto
    the still-open stream, so the client sees one continuous message in the
    server-side `fallbacks` wire shape: a `fallback` content block at each
    model boundary, monotonic block indices, and per-hop `usage.iterations` on
    the final `message_delta`. A refusal before any output streamed retries
    even without a credit token, and the serving hop's `message_start` opens
    the wire carrying the primary's message id.

    The fallback-credit beta the credit tokens require is sent by default on
    every request the middleware handles; the `betas` option controls this.

    In both modes a fallback that itself refuses with a fresh credit token
    continues down the chain. A streaming fallback whose appended prefill the
    server rejects (HTTP 400 body mismatch) is retried once without it; a
    fallback whose request fails outright is skipped — its token was never
    redeemed, so it carries to the next entry. When every remaining entry fails
    over HTTP, the suppressed refusal is replayed to the client with
    `recommended_model` stamped from the final failure (the failed model for
    capacity errors, `null` otherwise). A refusal surfaced to the client rather
    than retried is reported through the `anthropic.lib.middleware` logger.

    To keep later requests on the model that accepted, run them inside a shared
    `BetaFallbackState` context; requests sharing that state start directly at
    the pinned fallback. Reuse one state across whatever scope the pin should
    apply to — typically a conversation. The state is the only pin: `fallback`
    seam blocks replayed in the request history are stripped from the outgoing
    request (an assistant turn left empty by the strip is dropped whole), never
    read back as a pin.

    ```py
    client = Anthropic(middleware=[BetaRefusalFallbackMiddleware([{"model": "claude-opus-4-8"}])])

    state = BetaFallbackState()
    with state:
        message = client.beta.messages.create(**params)
    ```
    N)betasc               b    t        |      | _        |t        n
t        |      | _        d| _        y)u  
        Args:
            fallbacks: The fallback chain, tried in order. An empty chain disables
                the middleware.

            betas: Betas added to the `anthropic-beta` header of every `/v1/messages`
                request this middleware handles — the original request included, since
                refusals only carry a `fallback_credit_token` when the beta is enabled.
                Defaults to `("fallback-credit-2026-06-01",)`; pass `()` to send none.
        NF)tuple
_fallbacksr+   _betas_warned_missing_state)r1   	fallbacksrP   s      r2   r3   z&BetaRefusalFallbackMiddleware.__init__   s)       	*',}m%,%*"r4   c           	     |   | j                  |      }| ||      S t        j                         }| j                  |      }| j	                  |      }t        || j                        }t        |      }|dk(  r|ni || j                  |   }|j                  |      } ||      }	|	j                  j                  s|	S |j                  r6|dz   }
|
t        | j                        k\  r|	S | j                  |||	||
|      S |}|	}t        |j                  d      xs d      }g }|t        | j                        dz
  k  r"|j                  j                  r|j!                         }t#        |t$        t&        f      r|j(                  dk7  rn|dz  } ||       t+        |      }t-        |      } ||j                  t/        || j                  |   |                  }|j                  j                  r9t        | j                  |   d         }|j1                  t3        |||             |}|t        | j                        dz
  k  r|j                  j                  r|rW|j                  j                  rA|j!                         }t#        |t$        t&        f      r|j(                  dk7  rt5        ||      S |S Nr=   body   requestrZ   response	call_next	first_hoppinmodel refusal)_applicable_bodyr6   r9   _start_index	_make_pin_with_middleware_headersrT   _strip_seam_blocksrS   copyhttp_response
is_successstreamlen_splice_fallback_streamstrparse
isinstancer!   r$   stop_reason_credit_token_refusal_category_merged_bodyappend_seam_block_prepend_seam_blocksr1   r]   r_   rZ   statestart_indexra   initial_bodyinitial_requestr^   r`   r-   res
from_modelseamsmessager:   categoryto_modelserveds                       r2   handlez$BetaRefusalFallbackMiddleware.handle   s   $$W-<W%%##%''.nnU# +7DKK@
 "$'*b0t6^6^Q\A]6^!,,L,9_-%%00O>>#aI C00//'!!## 0   ))'28b9
&(c$//*Q..33D3D3O3OiikGg'=>'BUBUYbBbQJEJ!'*E(1HGLLl4QVAWY^._L`aC  ++tu5g>?[XxHI%
 c$//*Q..33D3D3O3O S&&11YY[F&7K"89f>P>PT]>] ,C77
r4   c           	       K   | j                  |      }| ||       d {   S t        j                         }| j                  |      }| j	                  |      }t        || j                        }t        |      }|dk(  r|ni || j                  |   }|j                  |      } ||       d {   }	|	j                  j                  s|	S |j                  r6|dz   }
|
t        | j                        k\  r|	S | j                  |||	||
|      S |}|	}t        |j                  d      xs d      }g }|t        | j                        dz
  k  r2|j                  j                  r|j!                          d {   }t#        |t$        t&        f      r|j(                  dk7  rn|dz  } ||       t+        |      }t-        |      } ||j                  t/        || j                  |   |                   d {   }|j                  j                  r9t        | j                  |   d         }|j1                  t3        |||             |}|t        | j                        dz
  k  r|j                  j                  r|r_|j                  j                  rI|j!                          d {   }t#        |t$        t&        f      r|j(                  dk7  rt5        ||      S |S 7 7 77 q7 7 BwrX   )re   r6   r9   rf   rg   rh   rT   ri   rS   rj   rk   rl   rm   rn   _splice_fallback_stream_asyncrp   rq   rr   r!   r$   rs   rt   ru   rv   rw   rx   _prepend_seam_blocks_asyncrz   s                       r2   handle_asyncz*BetaRefusalFallbackMiddleware.handle_async   s    $$W-<"7+++##%''.nnU# +7DKK@
 "$'*b0t6^6^Q\A]6^!,,L,9"?33%%00O>>#aI C0055'!!## 6   ))'28b9
&(c$//*Q..33D3D3O3OIIK'Gg'=>'BUBUYbBbQJEJ!'*E(1H!',,LtW\G]_d4e,"fggC  ++tu5g>?[XxHI%
 c$//*Q..33D3D3O3O S&&1199;&F&7K"89f>P>PT]>] 2#u==
} ," 40 ( h 'sa   K5K(BK54K+5CK5=K.>B K5>K1?BK5+K50K318K5+K5.K51K53K5c                `   t        |j                        }t        j                  |j                        }| j
                  rP|j                  j                         dk7  s3|j                  t        k7  s |j                  j                  d      dk7  s|y|j                  d      t        d      |S )zMThe request's JSON body when this middleware applies to it, `None` otherwise.postbetatrueNrV   az  Sending the `fallbacks:` request param is not supported when using the `BetaRefusalFallbackMiddleware`. You should either remove the middleware and send `fallbacks:` with the `server-side-fallback-2026-06-01` beta header to let the API handle refusal fallbacks, or omit the `fallbacks:` param if you'd like `BetaRefusalFallbackMiddleware` to handle fallbacks on the client side.)_as_dictjsonhttpxURLurlrS   methodlowerpath_MESSAGES_PATHparamsr9   r   )r1   r]   rZ   r   s       r2   re   z.BetaRefusalFallbackMiddleware._applicable_body5  s    %ii$  ~~##%/xx>)zz~~f%/|88K , 0  r4   c                    ||j                   y|j                   }d|cxk  rt        | j                        k  s'n t        d| dt        | j                         d      |S )zThe chain entry this request starts at (-1 = the original params).

        Only an explicit `BetaFallbackState` pin moves the start; without one
        the request starts at the original params.
        r=   zBetaFallbackState.index z! is out of bounds for a chain of z? fallback(s); was the state shared with a different middleware?)r-   rn   rS   r   )r1   r{   r|   s      r2   rf   z*BetaRefusalFallbackMiddleware._start_indexO  sk     =EKK/kk[73t#77 *;-7Xt'((gi  r4   c                     d fd}|S )zUPin requests sharing the state to the entry being tried (or warn that there is none).c                l    | _         y j                  sd_        t        j                  d       y y )NTzanthropic-sdk: BetaRefusalFallbackMiddleware fell back without an active BetaFallbackState; follow-up requests will retry models that already refused. Run them inside a shared `with BetaFallbackState():` block to pin them to the accepted model.)r-   rU   r)   warning)r-   r1   r{   s    r2   ra   z4BetaRefusalFallbackMiddleware._make_pin.<locals>.pinb  s7     #//-1*& 0r4   )r-   intrC   rD   rK   )r1   r{   ra   s   `` r2   rg   z'BetaRefusalFallbackMiddleware._make_pin_  s    
	 
r4   c          	         | j                  ||||||      }t        t        |j                  t	        |            |j
                  |j                  d|j                  |j                  |j                        S )aH  Wrap the refusable stream in a response whose body passes events through
        until a retryable refusal, then splices the fallback chain's events on.

        Closing the returned response (or the `Stream` parsed from it) tears down
        whichever stream is being read and abandons any in-flight fallback request.
        r\   Trawcast_toclientrm   
stream_clsoptionsretries_taken)
_spliced_framesr   _spliced_http_responserk   _FrameByteStream_cast_to_client_stream_cls_optionsr   r1   r]   rZ   r^   r_   r`   ra   framess           r2   ro   z5BetaRefusalFallbackMiddleware._splice_fallback_streamp  s      %% & 
 &x'='=?OPV?WX%%##++%%"00
 	
r4   c          	         | j                  ||||||      }t        t        |j                  t	        |            |j
                  |j                  d|j                  |j                  |j                        S )Nr\   Tr   )
_spliced_frames_asyncr   r   rk   _AsyncFrameByteStreamr   r   r   r   r   r   s           r2   r   z;BetaRefusalFallbackMiddleware._splice_fallback_stream_async  s     ++ , 
  &x'='=?TU[?\]%%##++%%"00
 	
r4   c          
   #  ,  K   | j                   }|j                  }	 |j                  }	t        ddd dd g       }
t        |	|
      E d {   }|j                  	 ||j                          y y |	j                          d }t        j                  ||      }t        |t        |            D ]w  }||   }t        |d         }|dz   t        |      k  } ||       |j                         }d }d }t        d      D ]  }|j                  |j                  ||            }	  ||      }|j                  j$                  r|j                  } nt'        |j                        }|j                  j                          |dk(  r?|j(                  dk(  r0|r.t        j+                  dt-        |             |j.                  }d }t        j!                  d||j(                  t-        |             t#        ||j(                  
      } n |3|r`|j1                  |      D ]  }|   ||j                          y y |J |j                  }|j3                  |       t        |j4                  |t7        |j8                  |      |j:                  |j<                  |j?                               }
t        ||
      E d {   }|j@                  r|jC                          |j                   ||j                          y y |j                          d }|jE                  |||       z 	 ||j                          y y 7 # t        $ r0}t        j!                  d	||       t#        |d 
      }Y d }~ md }~ww xY w7 # ||j                          w w xY wwNr   TF)
index_basehas_nextsplice	wire_open
primary_idseam_framesrb   r[   r"   rY   zOanthropic-sdk: BetaRefusalFallbackMiddleware: fallback request to %s failed: %s)rb   statusi  zanthropic-sdk: BetaRefusalFallbackMiddleware: fallback request with the partial output appended was rejected (HTTP 400: %s); retrying without itzXanthropic-sdk: BetaRefusalFallbackMiddleware: fallback request to %s failed: HTTP %s: %s)
iterationsrb   )#rS   rk   
_HopReader
_drive_hoprefusedclose_ChainStatebeginrangern   rp   continuationrj   hop_body	Exceptionr)   error_HopFailurerl   
_read_jsonstatus_coder   _json_dumpsbaseterminal_failure_frames
queue_seam
next_index_SpliceInfor   r   r   pending_seam_framesopenedmark_openedabsorb_refusal)r1   r]   rZ   r^   r_   r`   ra   rV   currentstream_areaderoutcomechainhopentryrb   r   r   res_bfailureattempthop_requesterrerr_bodyframehop_responses                             r2   r   z-BetaRefusalFallbackMiddleware._spliced_frames  s     OO	)1)?)?k	 --HF ",Hf!==G&x " #w NNG  %%dG4EYI7 SC!#E'N+7S^3C  %11315.2$Qx !G"),,ENN5,4W,"XK	 )+ 6 **55"'"5"5)%*=*=>H''--/!|(9(9S(@\g'1
 (-zz $ IIr))#H-	 *e>O>OPGC!F &  "'!>!>w!G $#$6 " #1 ((($22  '#$//%&%2B2B%P#oo$// % 9 9 ; &0f%EE>>%%'??* " # ""$
 $$We\BgSCj " #} >8 % 		m!
 #.E$"Gj F " #s   N,M< L;	M< N.B2M< !L>)C=M< &N:BM< <M:=-M< *N>(M< 'N;M< >	M7$M2+M< 2M77M< <NNc          
    @  K   | j                   }|j                  }	 |j                  }	t        ddd dd g       }
t        |	|
      2 3 d {   }| 7 
6 |
j	                         }|j
                  	 ||j                          d {  7   y y |	j                          d {  7   d }t        j                  ||      }t        |t        |            D ]  }||   }t        |d         }|dz   t        |      k  } ||       |j                         }d }d }t        d      D ]_  }|j                  |j                  ||            }	  ||       d {  7  }n;# t        $ r/}t         j#                  d	||       t%        |d 
      }Y d }~ nd }~ww xY w|j                  j&                  r|j                  } nt)        |j                         d {  7  }|j                  j                          d {  7   |dk(  r@|j*                  dk(  r1|r/t         j-                  dt/        |             |j0                  }d }t         j#                  d||j*                  t/        |             t%        ||j*                  
      } n |=|r|j3                  |      D ]  }| 	  ||j                          d {  7   y y |J |j                  }|j5                  |       t        |j6                  |t9        |j:                  |      |j<                  |j>                  |jA                               }
t        ||
      2 3 d {  7  }| 6 |
j	                         }|jB                  r|jE                          |j
                   ||j                          d {  7   y y |j                          d {  7   d }|jG                  |||        	 ||j                          d {  7   y y # ||j                          d {  7   w w xY wwr   )$rS   rk   r   _drive_hop_asyncfinishr   acloser   r   r   rn   rp   r   rj   r   r   r)   r   r   rl   _read_json_asyncr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   )r1   r]   rZ   r^   r_   r`   ra   rV   r   r   r   r   r   r   r   r   rb   r   r   r   r   r   r   r   r   r   s                             r2   r   z3BetaRefusalFallbackMiddleware._spliced_frames_asyncE  s      OO	)1)?)?b	'--HF  0&A  eAmmoG&b "nn&&& #a //###G%%dG4EYI7 IC!#E'N+7S^3C$1136:.2$Qx !G"),,ENN5,4W,"XK	&/&< < <$ 		m!
 #.E$"G **55"'"5"5%5e6I6I%JJJH--44666!|(9(9S(@\g'1
 (-zz $ IIr))#H-	 *e>O>OPGC!F & !&!>!>w!G $#$2 "nn&&& #/ ((($22  '#$//%&%2B2B%P#oo$// % 9 9 ; $4L&#I    %K $J --/>>%%'??* "nn&&& # #))+++$$We\BSICV "nn&&& #w"nn&&& #s"  P)O= A	A
AO= AO= 4P	B
PO= $B'%B'O= EEEO= 	F($FO= F?O= G"O= 9G<:B1O= +P KPA?O= MMMAO= P&N)'P.O= OO=  P5O86P=PPPP)rV   zIterable[BetaFallbackParam]rP   z#Iterable[AnthropicBetaParam] | NonerC   rD   )r]   r   r_   r   rC   APIResponse[Any])r]   r   r_   r   rC   AsyncAPIResponse[Any])r]   r   rC   dict[str, Any] | None)r{   BetaFallbackState | NonerC   r   )r{   r   rC   Callable[[int], None])r]   r   rZ   dict[str, Any]r^   r   r_   r   r`   r   ra   r   rC   r   )r]   r   rZ   r   r^   r   r_   r   r`   r   ra   r   rC   r   )r]   r   rZ   r   r^   r   r_   r   r`   r   ra   r   rC   Generator[bytes, None, None])r]   r   rZ   r   r^   r   r_   r   r`   r   ra   r   rC   AsyncGenerator[bytes, None])rF   rG   rH   rI   r3   r   r   r   re   rf   rg   ro   r   r   r   rK   r4   r2   r(   r(   ^   s   8| 6:	+.+ 3	+
 
+( A AF A AF4 " 
  
 	 

 # 
  
  
 # 
 
 
D
 
 	

 (
 !
 
 #
 

py  y  	y 
 #y  y  y  #y  
&y vp' p' 	p'
 (p' !p' p' #p' 
%p'r4   c                  D    e Zd ZU ded<   	 ded<   	 ded<   ded<   ded<   y	)
_RefusalOptional[str]r:   r   boolhas_prefill_claimDict[str, Any]usageeventN)rF   rG   rH   rJ   rK   r4   r2   r   r     s+    SS(r4   r   c                  &    e Zd ZU dZded<   ded<   y)r   z6Splice context for fallback hops; `None` for stream A.List[Dict[str, Any]]r   rp   rb   NrF   rG   rH   rI   rJ   rK   r4   r2   r   r     s    @$$Jr4   r   c                  &    e Zd ZU dZded<   ded<   y)r   z[A fallback hop whose request failed; stamps `recommended_model` when it
    ends the chain.rp   rb   zOptional[int]r   Nr   rK   r4   r2   r   r     s     JRr4   r   c                  d    e Zd ZU dZded<   	 ded<   	 ded<   	 ded	<   	 d
ed<   	 ded<   	 ded<   y)_HopOutcomez*The outcome of consuming one hop's stream.zOptional[_Refusal]r   r   rb   zOptional[Dict[str, Any]]start_eventr   blocksr   r   r   r   last_fallback_toNr   rK   r4   r2   r   r     sD    4E:))0  \O^LT##3r4   r   c                  t    e Zd ZU dZded<   	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZedd       ZddZddZ	ddZ
dd	Zy
)r   u  Consumes one hop's SSE events, producing the frames to forward to the
    client while accumulating its content blocks.

    Events are held until the hop produces output (a content block or a
    terminal event), so a refusal that arrives before any output — a pre-stream
    decline — leaves no trace on the wire and chains silently. On open, stream
    A's held `message_start` is flushed in its original wire bytes; a spliced
    hop's is suppressed when the wire is already open, or emitted with its `id`
    rewritten to the primary's when this hop's start opens the wire. Queued
    seam frames for every hop reached so far are flushed right after.

    A spliced hop has its block indices shifted by `index_base` and its
    terminal message_delta's usage rewritten to the `usage.iterations` chain
    shape.

    A refusal that can be chained — an entry remains, and either a
    `fallback_credit_token` was minted or nothing has streamed yet — ends the
    hop early: open blocks are closed, the terminal message_delta +
    message_stop are suppressed, and the refusal is set on the outcome so the
    caller can issue the next hop. Any other refusal is logged and passes
    through to the client.
    z_HopOutcome | Noner   c                   t        |      | _        || _        || _        || _        || _        || _        d | _        d | _        d | _	        d | _
        g | _        d| _        d | _        d | _        y )NF)_BlockTracker_tracker	_has_next_splice
_wire_open_primary_id_seam_frames_model_start_usage_start_event_held_start_held_opened_last_fallback_tor   )r1   r   r   r   r   r   r   s          r2   r3   z_HopReader.__init__  sq     &j1!#%'"&373737,.
-1r4   c                    | j                   S r/   )r  r0   s    r2   r   z_HopReader.opened'      ||r4   c           	     p
   t        t        |j                              }||j                  d      nd}| j                  }|dk(  rw|ut        |j                  d            }|I|j                  d      }t        |t              r|nd| _        t        |j                  d            | _        || _	        || _
        g S |dk(  r|| j                         }t        |j                  d            }|Z|j                  d      d	k(  rFt        |j                  d
            }	|	|	j                  d      nd}
t        |
t              r|
| _        | j                  j                  |       |g |t        d|      S g |t!        |      S |dk(  rN|L| j                         }| j                  j#                  |       |g |t        d|      S g |t!        |      S |dk(  rN|L| j                         }| j                  j%                  |       |g |t        d|      S g |t!        |      S |dk(  r|t        |j                  d            xs i }|j                  d      dk(  rt        |j                  d            }||j                  d      dk(  r|nd}||j                  d      nd}t        |t              r|r|nd}| j&                   xr | j                  j)                          }| j*                  r||rt-        t        |j                  d            | j                        }t/        | j                  j1                               }d| _
        | j2                  j5                          t7        t9        |||j                  d      nd|duxr |j                  d      du ||      | j                  | j                  | j                  j)                         | j                  j:                  | j&                  | j                        | _        |S |st>        jA                  d       nt>        jA                  d       | j                         }||j                  d      dk(  r.t        |j                  d            }||jC                  dd       t        |j                  d            xs i }g |jD                  tG        ||jH                        |d<   ||d<   g |t        d|      S g |t!        |      S | j&                  s| j2                  jK                  |       g S t!        |      gS )z:Process one event, returning the frames to forward for it.Ntypemessage_startr   rb   r   content_block_startcontent_blockfallbacktocontent_block_deltacontent_block_stopmessage_deltadeltars   rd   stop_detailsfallback_credit_tokenr   fallback_has_prefill_claimT)r:   r   r   r   r   r   rb   r   r   r   r   r   zvanthropic-sdk: BetaRefusalFallbackMiddleware: refusal stop_details has no fallback_credit_token; surfacing the refusalzkanthropic-sdk: BetaRefusalFallbackMiddleware: refusal but no fallback entries remain; surfacing the refusalrecommended_modelr   )&r   
_safe_jsondatar9   r  rr   rp   r
  r  r  r  _openr  r  start_emit_passthrough_sser  stopr  content_blocksr  	_backfilllistclose_open_blocksr  clearr   r   r   r   r)   r   
setdefaultr   _serving_iteration_entryrb   rw   )r1   sser   
event_typer   r   rb   r   r  r  r   r  r  detailsr:   
pre_streamr   s                    r2   feedz_HopReader.feed+  s   CHH-.*/*;UYYv&
(U->uyy34G"G,'1%'=e4$,W[[-A$B! %D"DI00U5FZZ\F$UYY%?@M(]->->v-F*-Tm//56.0n266'?$h,-5D*MM& % ?&>% 5u=> 6v5/45
 00U5FZZ\FMM& % ?&>% 5u=> 6v5/45
 //E4EZZ\FMMu% % >&=% 4e<= 6v5/45
 ?*u/@UYYw/06BEyy'94'		.(AB*6*B|GWGWX^G_clGl,rv@G@S$;<Y]!+E3!7Et!%-Tdmm6R6R6T2T
 >>u'8J%huyy/A&BDDUDUVE!$--"A"A"CDF (,D$JJ$$&#. ("'@G@SW[[%<Y].5T.A.wgkkRnFoswFw"'"'! #kk$($5$5#}};;=#'==#;#;#||)-)?)?$DL "MIIG
 II@ ZZ\F!99]+y8 $,EIIn,E#FL#/$//0CTJ !7!34:'&&',UFLLA'l# "'g??!>??3V3-c233||JJc"I !%&&r4   c                |   | j                   rg S d| _         g }| j                  1| j                  |j                  t	        | j                               n| j
                  s}| j                  qt        j                  | j                        }t        |j                  d            }|| j                  | j                  |d<   |j                  t        d|             |j                  | j                         |j                  d | j                  D               d| _        | j                  j!                          |S )zOpen the wire for this hop: its message_start (raw for stream A;
        suppressed or id-rewritten for a spliced hop), the queued seam frames,
        then anything else held.TNr   idr  c              3  2   K   | ]  }t        |        y wr/   )r(  ).0helds     r2   	<genexpr>z#_HopReader._open.<locals>.<genexpr>  s     D&t,D   )r  r  r  rw   r(  r  r  _copydeepcopyr   r9   r  r'  extendr	  r  r.  )r1   r   r   r   s       r2   r%  z_HopReader._open  s     <<I <<+.t/?/?@AT%6%6%B..):):;K{y9:G"t'7'7'C $ 0 0MM%=>d''(DDD

r4   c                V    | j                   | j                  rg S | j                         S )zCFrames still owed when the stream ends without a chainable refusal.)r   r  r%  r0   s    r2   finish_framesz_HopReader.finish_frames  s#    <<#t||Izz|r4   c           	         | j                   | j                   S t        d| j                  | j                  | j                  j                         | j                  j                  | j                  | j                        S )zCThe outcome once the hop's stream is fully consumed (or cut early).Nr!  )	r   r   r
  r  r  r*  r   r  r  r0   s    r2   r   z_HopReader.finish  sc    <<#<<++))==//1}}//<<!33
 	
r4   N)r   r   r   r   r   z_SpliceInfo | Noner   r   r   
str | Noner   list[bytes]rC   rD   )rC   r   )r1  r   rC   rD  rC   rD  )rC   r   )rF   rG   rH   rI   rJ   r3   propertyr   r5  r%  rA  r   rK   r4   r2   r   r     s    .  U  	
 #   ! 
2  x't.
r4   r   c              #     K   t        j                  |       D ]*  }|j                  |      D ]  }|  |j                  * n |j	                         D ]  }|  |j                         S w)zKFeed one hop's SSE events through `reader`, yielding the frames to forward.)r   
raw_eventsr5  r   rA  r   r^   r   r1  r   s       r2   r   r     su       * [[% 	EK	>>%	
 %%' ==?s   ?A.,A.c                  K   t        j                  |       2 3 d{   }|j                  |      D ]  }| 	 |j                  1 |j	                         D ]  }| 	 y7 H6 w)u   Feed one hop's SSE events through `reader`, yielding the frames to forward.

    The outcome is read from `reader.finish()` afterwards — async generators
    cannot return a value.
    N)r   rH  r5  r   rA  rI  s       r2   r   r     sr      !++H5  c[[% 	EK	>>%%%' 5s+   A)A'A%A'(A)	A)%A''A)c                      e Zd ZU dZded<   	 ded<   	 ded<   	 ded	<   	 ded
<   ded<   ded<   ded<   ded<   ded<   ded<   	 ddZed d       Zd!dZd"dZ	d#dZ
d$dZd%dZd&dZd'dZy)(r   z9Bookkeeping shared across the hops of one spliced stream.r   r   r   r   rC  r   rp   primary_modelr:   	List[Any]r   partialr   r   last_refusalzDict[str, Any] | Nonelast_start_eventr   r   c                     || _         g | _        y r/   )_body_pending_seams)r1   rZ   s     r2   r3   z_ChainState.__init__  s    
+-r4   c                   |j                   J  | |      }t        |j                  d      xs d      |_        |j                  |_        |j
                  |_        t        |j                  xs i j                  d            }||j                  d      nd}t        |t              r|nd|_
        |j                   j                  |_        g |_        |j                   j                  rt        |j                        ng |_        |j"                  xs |j                  |_        |j                   |_        |j                  |_        t+        |j                   |j                        |_        |S )z3The chain state after stream A's chainable refusal.Nrb   rc   r   r7  )r   rp   r9   rL  r   r   r   r   r   rr   r   r:   r   r   _to_prefill_blocksr   rN  r   r   rO  rP  _declined_iteration_entriesr   )clsrZ   r   r   start_messagestart_ids         r2   r   z_ChainState.begin  s&    ***D	!$((7"3"9r:"--!.. '"5"5";!@!@!KL.;.G=$$T*T'1(C'@8doo++
>Eoo>_>_*7>>:eg #33Ju7J7J$__!(!4!46wH[H[\r4   c                   | j                   }| xj                   dz  c_         | j                  j                  t        dd|t	        | j
                  || j                  j                        d      t        dd|d      g       || _        y)a  Queue the reached hop's `fallback` seam block at the next monotonic index.

        Queued seams are flushed by the hop reader once output reaches the wire,
        so a chain of pre-stream declines lines its seams up after the serving
        hop's message_start.
        r[   r  )r  r-   r  r  r  r-   N)r   rS  r?  r'  rx   r   rO  r   )r1   r   
seam_indexs      r2   r   z_ChainState.queue_seam#  s     __
1"") 5!+)4T__hPTPaPaPjPj)k *5IT^,_`
	
 #r4   c                ,    t        | j                        S r/   )r,  rS  r0   s    r2   r   z_ChainState.pending_seam_frames;  s    D''((r4   c                F    d| _         | j                  j                          y )NT)r   rS  r.  r0   s    r2   r   z_ChainState.mark_opened>  s    !!#r4   c                6    g | j                   | j                  S r/   )r   rN  r0   s    r2   r   z_ChainState.continuationB  s    **T\\**r4   c                   i | j                   |j                         D ci c]  \  }}|dk7  s|| }}}| j                  | j                  |d<   |r/|j                  d      }g t	        |t
              r|ng d|d|d<   |S c c}}w )uz  The hop's request body: the refused request's, with the entry's
        overrides merged over it and extended by the continuation.

        The server-side `fallbacks` param is stripped — it is mutually exclusive
        with a credit-token retry. When the refusal granted no prefill claim the
        appended turn is omitted entirely and the same-body form is sent.
        rV   r  messages	assistant)rolecontent)rR  itemsr:   r9   rr   r,  )r1   r   r   keyvaluerZ   ra  s          r2   r   z_ChainState.hop_bodyE  s     >U

=Te=T=Z=Z=\szsE`cgr`rU
ss::!,0JJD()xx
+H (48(b $> D   ts
   BBc                   |j                   J |j                   j                  | _        || _        |j                   j                  rt	        |j
                        ng | _        | j                  j                  t        |j                   |             |j                   | _
        |j                  |j                  | _        |j                  | _        y)z7Fold a refused hop's outcome in, readying the next hop.N)r   r:   r   r   rU  r   rN  r   r?  rV  rO  r   rP  r   )r1   r   rb   r   s       r2   r   z_ChainState.absorb_refusalX  s    ***__**
 	=D__=^=^)'..9df:7??ERS#OO*$+$7$7D!!,,r4   c                L   g }| j                   s}| j                  qt        j                  | j                        }t	        |j                  d            }|| j                  | j                  |d<   |j                  t        d|             |j                  | j                         t        j                  | j                  j                        }t	        |j                  d            }|;t	        |j                  d            }||j                  dv r|j                  nd|d<   t	        |j                  d	            xs i }t        j                  | j                        |d
<   ||d	<   |j                  t        d|             |j                  t        dddi             |S )uS  Degrade to the suppressed refusal when every remaining entry failed
        over HTTP: replay its message_delta verbatim — `recommended_model`
        stamped from the final failure (the failed model for capacity errors,
        `null` otherwise) and `usage.iterations` carrying the recorded chain —
        then message_stop.
        Nr   r7  r  r  r  )i  i  r"  r   r   r  message_stopr  )r   rP  r=  r>  r   r9   r   rw   r'  r?  rS  rO  r   r   rb   r   )	r1   r   r   r   r   r   r  r3  r   s	            r2   r   z#_ChainState.terminal_failure_framesd  sU    !~~$"7"7"C..)>)>?K{y9:G"t'B $MM%=>d))*t006677+,uyy89G"@GR\@\w}}bf+,7+,2#nnT__=lgeOU34eNV^,DEFr4   N)rZ   r   rC   rD   )rZ   r   r   r   rC   r   )r   rp   rC   rD   rE  rB   )rC   	list[Any])r   r&   r   rk  rC   r   )r   r   rb   rp   r   rk  rC   rD   )r   r   rC   rD  )rF   rG   rH   rI   rJ   r3   classmethodr   r   r   r   r   r   r   r   rK   r4   r2   r   r     s    CO;O=2 ; 
OO++$$I.  ,#0)$+&
-r4   r   c                d   | j                   j                  d      }t        |t              ri|rgd t	        d|      D        }|D cg c]  }|i |ddi }}|r:t        |      dk(  r*t        |d   j                  d      t              s||d   d<   |S t        d|| j                         gS c c}w )	uS  The `usage.iterations` entries a declined hop contributes to the chain.

    The hop's refusal self-reports its iterations: adopt them, retyped to
    `message` (every one of them declined — a server-stitched envelope labels
    its last hop `fallback_message`). A single-entry self-report describes the
    hop itself and gains its model — `model_label`, the caller-spelled primary
    or the chain entry's id — when the wire didn't name one; a multi-entry
    self-report (a server-tool loop) is kept verbatim. Without a self-report,
    one entry is built from the refusal's usage.
    r   c              3  2   K   | ]  }t        |        y wr/   )r   )r9  r   s     r2   r;  z._declined_iteration_entries.<locals>.<genexpr>  s     QEQr<  rM  r  r   r[   r   rb   )r   r9   rr   r,  r   rn   rp   _to_iteration_usage)rd   model_labelreporteddict_entriesr   entriess         r2   rV  rV    s     }}  .H(D!hQT+x5PQS_(u%chct)EE)E69)E(u(u7|q GAJNN74KS)Q&1
7#N	;FGG )vs   B-
B-c                    | j                  d      }t        |t              r8|r6t        t	        d|      d         }|i |d|j                  d      xs |dS t        d||       S )zThe serving hop's `fallback_message` completer entry: its own
    self-reported iteration relabeled, or one built from its delta usage.r   rM  r=   fallback_messagerb   )r  rb   )r9   rr   r,  r   r   ro  )delta_usagerb   rq  lasts       r2   r0  r0    sl     |,H(D!h[(3B78\d\$6'ARA[V[\\15+FFr4   c                  P    e Zd ZU dZded<   	 dddZddZddZddZddZ	dd	Z
y
)r  a/  Block bookkeeping for one stream of the splice: accumulates each content
    block from its deltas (for the continuation prefill), shifts wire indices
    by `index_base` so they stay monotonic across hops, and tracks which blocks
    are still open so a refusal that cuts mid-block can close them.
    r   r   c                <    || _         || _        g | _        g | _        y r/   )_index_baser   _blocksr%  )r1   r   s     r2   r3   z_BlockTracker.__init__  s    %$9; "
r4   c                L    | j                   D cg c]  \  }}|	 c}}S c c}}w )z/The accumulated content blocks, in start order.)r{  )r1   _blocks      r2   r*  z_BlockTracker.content_blocks  s    &*ll3(!U333s    c                j   |j                  d      }t        |t              syt        |j                  d            }| j                  j                  ||t        |      ni f       || j                  z   }||d<   | j                  j                  |       t        | j                  |dz         | _
        y)z7Track a content_block_start, shifting `event["index"]`.r-   Nr  r[   )r9   rr   r   r   r{  rw   dictrz  r%  maxr   )r1   r   r-   r  shifteds        r2   r&  z_BlockTracker.start  s    		'"%% ?!;<U=;TD$7Z\]^$*** g

'"doow{;r4   c                    |j                  d      }t        |t              syt        |j                  d            }|t	        | j
                  ||       || j                  z   |d<   y)zQApply a content_block_delta to its accumulating block, shifting `event["index"]`.r-   Nr  )r9   rr   r   r   _apply_deltar{  rz  )r1   r   r-   r  s       r2   r  z_BlockTracker.delta  sZ    		'"%%7+,ue4!1!11gr4   c                    |j                  d      }t        |t              sy|| j                  z   }||d<   || j                  v r| j                  j                  |       t        | j                  |dz         | _        y)z6Track a content_block_stop, shifting `event["index"]`.r-   Nr[   )r9   rr   r   rz  r%  remover  r   )r1   r   r-   r  s       r2   r)  z_BlockTracker.stop  sj    		'"%%$*** gdjj JJg&doow{;r4   c              #     K   | j                   D ]  }t        dd|d        | j                   j                          yw)z4content_block_stop events for any blocks still open.r  r[  N)r%  r'  r.  )r1   r-   s     r2   r-  z_BlockTracker.close_open_blocks  s@     ZZ 	^E,7KV[.\]]	^

s   >A N)r   )r   r   rC   rD   )rC   list[dict[str, Any]])r   r   rC   rD   rC   zIterator[bytes])rF   rG   rH   rI   rJ   r3   r*  r&  r  r)  r-  rK   r4   r2   r  r    s/     O8#4
<2	<r4   r  c                   t        fd| D        d      }|y|j                  d      }|dk(  rAt        |j                  d      xs d      t        |j                  d      xs d      z   |d<   y|dk(  rAt        |j                  d      xs d      t        |j                  d	      xs d      z   |d<   y|d
k(  rS|j                  d      }t        |t              sg }||d<   t        d|      j                  |j                  d             y|dk(  rAt        |j                  d      xs d      t        |j                  d      xs d      z   |d<   y|dk(  r|j                  d      |d<   yy)zAApply a content_block_delta to the accumulating block at `index`.c              3  4   K   | ]  \  }}|k(  s|  y wr/   rK   )r9  block_indexr~  r-   s      r2   r;  z_apply_delta.<locals>.<genexpr>  s     Q.KK5<P%Qs   Nr  
text_deltatextrc   input_json_delta_partial_jsonpartial_jsoncitations_delta	citationsrM  citationthinking_deltathinkingsignature_delta	signature)nextr9   rp   rr   r,  r   rw   )r   r-   r  r~  
delta_typer  s    `    r2   r  r    sW   Q&QSWXE}6"J\!EIIf-34s599V;L;RPR7SSf	)	)!$UYY%?%E2!FUYYWeMfMljlIm!mo	(	(IIk*	)T*I!*E+[)$++EIIj,AB	'	'		* 5 ;<s599ZCXC^\^?__j	(	("YY{3k 
)r4   c                   g }| D ]  }|j                  d      dk(  r|j                  d      }t        |t              s|j                  |       K|j	                         D ci c]  \  }}|dk7  s|| }}}t        |      }||n|j                  d      |d<   |j                  |        |r?|d   j                  d      dv r)|j                          |r|d   j                  d      dv r)|S c c}}w )u  Convert a hop's accumulated response blocks to the appended assistant turn.

    A `fallback_has_prefill_claim` refusal guarantees the partial output is
    resendable, so the blocks go out near-verbatim. Three rewrites apply:
    `fallback` seam blocks (wire markers, not content) are dropped, tool inputs
    are reassembled from their accumulated `input_json_delta` JSON
    (content_block_start carries `input: {}`), and trailing thinking blocks are
    stripped — the server rejects an assistant turn whose final block is
    `thinking`, so a refusal that cut the stream mid-thought would otherwise
    400 the continuation. A partial that was nothing but thinking strips to
    empty, and the hop falls back to the same-body form.
    r  r  r  inputr=   )r  redacted_thinking)r9   rr   rp   rw   re  r#  pop)response_blocksoutr~  r  rf  rg  parseds          r2   rU  rU    s     C  
99V
*yy1,,JJu.3kkmV
Uso?UeVVL)#)#5599W;Mg

5
 #b'++f%)JJ	 #b'++f%)JJJ Ws   #C21C2c                D   | j                  d      }t        |t              s| S d}g }t        d|      D ]  }t	        |      }||j                  d      nd}|t        |t              s|j                  |       Gt        d|      }|D cg c]$  }t        |      r|j                  d      dk(  r#|& }	}t        |	      t        |      k(  r|j                  |       d}|	s|j                  d	      d
k(  r|j                  i |d|	i        |s| S i | d|iS c c}w )u  A copy of `body` with `{type: "fallback"}` seam blocks filtered out of the
    replayed message history; `body` itself when there are none.

    An assistant turn left with no content by the strip — a seam-only turn — is
    dropped whole; the server rejects empty-content turns.ra  FrM  Nrd  r  r  Trc  rb  )r9   rr   r,  r   r   rw   r   rn   )
rZ   ra  strippedstripped_messagesr   message_dictrd  content_listr~  kepts
             r2   ri   ri     s9    xx
#Hh%H#%X. D(1=1I,""9-tz'4'@$$W-K1#/l%599U[K\`jKjllt9L))$$W-((0K?  !BL!B)T!BCD 2d2J 122 ms   $D0Dc           
        t        j                  | j                  j                         D ci c]  \  }}t	        |t
              s|| c}}      j                  dd      }|j                  d      D ch c]  }|j                          c}t        j                  fd|D              }| j                  j                         D ci c]  \  }}|j                         dk7  s|| }}}|s|r!dj                  t        d|g|            |d<   | j                  t        |t!        d                  S c c}}w c c}w c c}}w )	zA copy of `request` with `betas` appended to its `anthropic-beta` header
    (skipping values already present) and the middleware's helper-telemetry tag
    appended to `x-stainless-helper`. Single `request.copy()` for both.
    zanthropic-betarc   ,c              3  P   K   | ]  }t        |      vst        |        y wr/   )rp   )r9  r   existings     r2   r;  z+_with_middleware_headers.<locals>.<genexpr>C  s      WDSYh=Vc$iWs   &&z, Nzfallback-refusal-middleware)headers)r   Headersr  re  rr   rp   r9   splitstripr  fromkeysr   joinfilterrj   r    r#   )	r]   rP   kvr   rg  	additionsr  r  s	           @r2   rh   rh   :  s    mmgoo.C.C.E\daTUWZI[QT\]aabrtvwG+2==+=>%>HWEWWI ' 5 5 7Y11779HX;Xq!tYGY)$(IIfTG;Pi;P.Q$R !<<g}Eb7c d<ee ]>Ys   D:
D:
7E E(Ec                h    t        | t              r"| j                  | j                  j                  S y)zEThe refusal's minted credit token; only the beta surface carries one.N)rr   r$   r  r  r   s    r2   rt   rt   J  s,    ';'G,@,@,L##999r4   c                h    t        | t              r"| j                  | j                  j                  S y)zOThe policy category that caused the refusal; only the beta surface carries one.N)rr   r$   r  r   r  s    r2   ru   ru   Q  s,    ';'G,@,@,L##,,,r4   c                    dd| id|id|ddS )zBThe synthetic `fallback` content block marking one model boundary.r  rb   rd   )r  r   )r  fromr  triggerrK   )r   r   r   s      r2   rx   rx   X  s)     *%!%8<	 r4   c           
        t        t        | j                  j                  d                  }|t	        |j                  d      t              syt        i |dg |t        d|d         i      j                  d      }| j                  j                         }dD ]
  }||v s||=  t        j                  | j                  ||| j                        S )zA copy of the served hop's response with `seams` prepended to its
    `content`, or `None` when the body isn't the expected message shape.

    The caller has already parsed the response, so its body is buffered.
    utf-8Nrd  rM  zcontent-encodingzcontent-length)r   r  rd  r]   )r   r#  rd  decoderr   r9   r,  r   r   encoder  rj   r   Responser   r]   )originalr   r   rZ   r  headers         r2   _seamed_http_responser  b  s     z("2"2"9"9'"BCDGjY)?F_'_9.^.^['R[J\8].^_`gghopD##%G8  W  >>((  	 r4   c           	         t        | j                  |      }|| S t        || j                  | j                  d| j
                  | j                  | j                        S NFr   )r  rk   r   r   r   r   r   r   r^   r   r   s      r2   ry   ry   x  s^    
 6 6
>C
{!!''!!,, r4   c           	         t        | j                  |      }|| S t        || j                  | j                  d| j
                  | j                  | j                        S r  )r  rk   r   r   r   r   r   r   r  s      r2   r   r     s^    
 6 6
>C
{!!''!!,, r4   c                     i | |}|r||d<   |S )zThe non-streaming retry body: the fallback entry merged whole over the
    original params, plus the refusal's credit token when it minted one.r  rK   )rZ   r  credit_tokenmergeds       r2   rv   rv     s&     211F*6&'Mr4   c                L    	 t        j                  |       S # t        $ r Y y w xY wr/   )r   loadsr   )r  s    r2   r#  r#    s(    zz$ s    	##c                0    t        j                  | d      S )N)r  :)
separators)r   dumpsrg  s    r2   r   r     s    ::e
33r4   c                4    t        |       rt        d|       S d S )Nr   )r   r   r  s    r2   r   r     s    ,3EN4 %(DDr4   c                h    	 t        j                  | j                               S # t        $ r Y y w xY wr/   )r   r  readr   r^   s    r2   r   r     s.    zz(--/** s   "% 	11c                   K   	 t        j                  | j                          d {         S 7 # t        $ r Y y w xY wwr/   )r   r  areadr   r  s    r2   r   r     s8     zz 00110 s,   A "1 /1 A 1 	=A =A c                L    t        | t        |            j                  d      S )Nr   r$  r  )_serialize_sser   r  )r   payloads     r2   r'  r'    s    K,@AHHQQr4   c                    | j                   r-dj                  | j                         dz   j                  d      S t        | j                  | j
                        j                  d      S )zForward a decoded event in its original wire bytes, preserving SSE fields
    beyond `event:`/`data:` (`id:`, `retry:`, comment lines). Falls back to
    re-serializing for events with no raw lines.
    
z

r  r  )r   r  r  r  r   r$  )r1  s    r2   r(  r(    sN    
 ww		#''"V+33G<<		9@@IIr4   c                d    d}| 	|d|  dz  }|j                  d      D ]  }|d| dz  } |dz   S )zSerialize an event back to its SSE wire form (`event: ...\ndata: ...\n\n`).

    Multi-line `data` is emitted as one `data:` line per line, matching the
    spec. The inverse of the decoder behind `Stream.raw_events`.
    rc   zevent: r  zdata: )r  )r   r$  r  lines       r2   r  r    sW     Cr""

4  !vR  !:r4   c           	         |xs i }| ||j                  d      xs d|j                  d      xs d|j                  d      xs d|j                  d      xs d|j                  d      dS )Ninput_tokensr   output_tokenscache_read_input_tokenscache_creation_input_tokenscache_creation)r  rb   r  r  r  r  r  )r9   )r  rb   r   us       r2   ro  ro    sp     	An-2/41#$55)B#C#Hq'(uu-J'K'Pq%% 01 r4   c                    |xs i }i || xs i }|j                         D ]"  \  }}|	|j                  |      ||   ||<   $ |S )z0Fill `None` fields on `primary` from `fallback`.)re  r9   )primaryr  r  rf  rg  s        r2   r+  r+    s^    ~2H9X9'-R9Ciik %
U=X\\#.:}CH% Jr4   c                    | j                   j                         }dD ]
  }||v s||=  t        j                  | j                  ||| j
                        S )zA synthetic response standing in for `original`, with `stream` as its body.

    The spliced frames are emitted post-decode, so the original's
    content-encoding/length headers no longer describe the body.
    r  )r   r  rm   r]   )r  rj   r   r  r   r]   )r  rm   r  r  s       r2   r   r     sa     ##%G8  W  >>((  	 r4   c                  8    e Zd ZddZedd       Zedd       Zy)r   c                    || _         y r/   _framesr1   r   s     r2   r3   z_FrameByteStream.__init__  	    r4   c                    | j                   S r/   r  r0   s    r2   __iter__z_FrameByteStream.__iter__	  r  r4   c                8    | j                   j                          y r/   )r  r   r0   s    r2   r   z_FrameByteStream.close  s    r4   N)r   r   rC   rD   r  rB   )rF   rG   rH   r3   r   r  r   rK   r4   r2   r   r     s/        r4   r   c                  8    e Zd ZddZedd       Zedd       Zy)r   c                    || _         y r/   r  r  s     r2   r3   z_AsyncFrameByteStream.__init__  r  r4   c                    | j                   S r/   r  r0   s    r2   	__aiter__z_AsyncFrameByteStream.__aiter__  r  r4   c                T   K   | j                   j                          d {    y 7 wr/   )r  r   r0   s    r2   r   z_AsyncFrameByteStream.aclose  s     ll!!###s   (&(N)r   r   rC   rD   )rC   AsyncIterator[bytes]rB   )rF   rG   rH   r3   r   r  r   rK   r4   r2   r   r     s/       $ $r4   r   )r^   httpx.Responser   r   rC   z#Generator[bytes, None, _HopOutcome])r^   r  r   r   rC   r  )rd   r   rp  rp   rC   r  )rv  r   rb   rp   rC   r   )r   z list[tuple[int, dict[str, Any]]]r-   r   r  r   rC   rD   )r  r  rC   rk  )rZ   r   rC   r   )r]   r   rP   r*   rC   r   )r   zMessage | BetaMessagerC   rC  )r   rp   r   rp   r   rC  rC   r   )r  r  r   r  rC   zhttpx.Response | None)r^   r   r   r  rC   r   )r^   r   r   r  rC   r   )rZ   r   r  r&   r  rC  rC   r   )r  rp   rC   r   )rg  r   rC   rp   )rg  rE   rC   r   )r^   r  rC   r   )r   rp   r  r   rC   bytes)r1  r   rC   r  )r   rC  r$  rp   rC   rp   )r  z&Literal['message', 'fallback_message']rb   rp   r   r   rC   r   )r  r   r  r   rC   r   )r  r  rm   z,httpx.SyncByteStream | httpx.AsyncByteStreamrC   r  )g
__future__r   rj   r=  r   loggingtypingr   r   r   r   r   r	   r
   r   r   r   r   contextvarsr   r   typing_extensionsr   r   r   _utilsr   _modelsr   _requestr   	_responser   r   
_streamingr   r   r   _exceptionsr   _middlewarer   r   r   _base_clientr    types.messager!   _stainless_helpersr#   types.beta.beta_messager$   types.anthropic_beta_paramr%   types.beta.beta_fallback_paramr&   __all__	getLoggerr)   rJ   r   r+   r'   r6   r8   r(   r   r   r   r   r   r   r   r   rV  r0  r  r  rU  ri   rh   rt   ru   rx   r  ry   r   rv   r#  r   r   r   r   r'  r(  r  ro  r+  r   SyncByteStreamr   AsyncByteStreamr   rK   r4   r2   <module>r     s"   "       * /     " 6 > > ) > > ) $ . 2 < ? # (g''(BC^ C0O- O >* *< 9CCblp8q5 q S]*BS O 
W	'J W	'z(y () S) S3) 34[
 [
|	S SlH,G; ;B4,B3>f ,4ERJ
09<EZ&R(
u++ 

$E11 
$r4   