+
    ~Sj5              
         R t ^ RIHt ^ RIt^ RIt^ RIt^ RIHt ^ RIH	t	 ]P                  ! R4      t]P                  ! R4      t]P                  ! R4      t]P                  ! R4      t]! ]P                   P#                  R	R
4      4      t]! ]P                   P#                  RR4      4      tRtRtRtRtRtRtRtRtRtRtRtRt]! ]P                   P#                  RR4      4      t ]! ]P                   P#                  RR4      4      t!Rt"Rt#Rt$Rt%R0w  t&t't(t)R1t*RRR R!R"R#R$R%R&R'/t+]	 ! R( R)4      4       t,R* R+ lt-R, R- lt. ! R. R/4      t/R# )2u  Frustration meter — Jarvis simmers instead of rolling dice.

A person doesn't randomly explode; irritation BUILDS — the same question
again, orders fired without a breath between them, being talked over — and
stays bottled until it overflows, then blows and resets. This models that: a
hidden 0..1 level that specific behaviours push up, that cools on its own,
and that maps to a graduated attitude the brain performs. The stages are
meant to be FELT, each with its own voice:

    composed → curt → clipped → snapping → seething → OVERFLOW (tantrum)

Used in main.py once per brain turn: `state = meter.update(text)`.
`state.attitude` is injected into the turn so the brain colours its reply —
each stage's hint carries WHAT is grinding him (third time asked, rapid-fire,
shouting), so the grief comes out specific instead of generic. `state.mood_tag`
is the ambient voice tone applied when the brain leaves a line untagged (so
nothing comes out dead-flat); `state.exploded` triggers the tantrum.

The meter also reads HOW Ahmed sounds when the prosody note rides in — via the
`tone=` kwarg or a "(voice: …)" marker already embedded in the text: shouting
heats it faster, laughter vents it. Logic-only; nothing shows in the UI.
)annotationsN)deque)	dataclassz
[a-z0-9']+z\b(thanks|thank you|cheers|nice|good job|well done|love (it|you|that)|perfect|awesome|brilliant|great job|appreciate|you're the best|legend|good (boy|lad|man))\bz^(open|close|launch|start|stop|play|pause|mute|unmute|turn|set|run|check|send|show|go|skip|next|volume|search|find|kill|restart|quit)\bz\(voice:\s*([^)]*)\)
FRUST_BASEz0.015FRUST_HALFLIFE100g
ףp=
?g)\(?gQ?g{Gz?gQ?g{Gz?gQ?g?gQ?gffffff?FRUST_OVERFLOWz1.0FRUST_RESETz0.25g      ?g      n@g
ףp=
?3third4fourth5fifth6sixth7seventhc                  X    ] tR t^Rt$ R]R&   R]R&   R]R&   R]R&   R	]R
&   RtR]R&   RtR# )
FrustStatefloatlevelstrmood_tag
str | Noneattitudeboolexploded	list[str]reasonscomposedstage N)__name__
__module____qualname____firstlineno____annotations__r!   __static_attributes__r"       voice/frustration.pyr   r   R   s'    LMNE3r)   r   c                    V ^8  d   QhRRRR/# )   textr   returnset[str]r"   )formats   "r*   __annotate__r1   \   s     4 4 4 4r)   c                n    \        \        P                  T ;'       g    R P                  4       4      4      # ) )set_WORDfindalllower)r-   s   &r*   _normr8   \   s%    u}}djjb//1233r)   c               $    V ^8  d   QhRRRRRR/# )r,   ar/   br.   r   r"   )r0   s   "r*   r1   r1   `   s!     # # #X #% #r)   c                t    V '       d	   V'       g   R # \        W,          4      \        W,          4      ,          # )        )len)r:   r;   s   &&r*   _similarr?   `   s!    Aqu:AE
""r)   c                  V    ] tR t^ftR R ltRR R lltR R ltR R	 ltR
 R ltRt	R# )FrustrationMeterc                   V ^8  d   QhRR/# )r,   r.   Noner"   )r0   s   "r*   r1   FrustrationMeter.__annotate__g   s      $ r)   c                	    \         V n        \        P                  P	                  R R4      R8g  V n        RV n        \        ^R7      V n        RV n	        RV n
        RV n        R# )FRUSTRATION10N)maxlenF)_STARTr   osenvirongetenabled_last_tsr   _recent_last_menial
_last_blow_grudge)selfs   &r*   __init__FrustrationMeter.__init__g   sL    
zz~~mS9S@&*(-Q!(,r)   Nc          
     ,    V ^8  d   QhRRRRRRRRR	R
/# )r,   r-   r   was_barge_inr   nowzfloat | Nonetoner   r.   r   r"   )r0   s   "r*   r1   rD   p   s9     C C3 Cd C C/9CEOCr)   c                    V P                   '       g   \        RRRR. 4      #  T P                  YVe   VV4      # \        P                  ! 4       V4      #   \
         d    \        T P                  RRR. 4      u # i ; i)u  Advance the meter for one user turn and return the resulting state.
`tone` is the optional prosody note ("loud", "fast, urgent", …); if not
passed, a "(voice: …)" marker inside `text` is read instead. Never
raises — on any error it returns a calm state.r=   calmNF)rN   r   _updatetime	monotonic	Exceptionr   )rT   r-   rX   rY   rZ   s   &&&&&r*   updateFrustrationMeter.updatep   s     |||c64;;	C<<'* $& &<@NN<L $& &  	Cdjj&$rBB	Cs   A A $A;:A;c          
     ,    V ^8  d   QhRRRRRRRRR	R
/# )r,   r-   r   rX   r   rY   r   rZ   r   r.   r   r"   )r0   s   "r*   r1   rD      s?     WQ WQC WQt WQ% WQ WQ%/WQr)   c                		  a V P                   e   W0P                   ,
          MR pVeA   \        ^ 8  d6   V ;P                  R\        RV4      \        ,          ,          ,          un        W0n         T;'       g    RP	                  4       p\
        P                  V4      pV'       d@   Vf   VP                  ^4      pVR VP                  4        WgP                  4       R  ,           pT;'       g    RP	                  4       p\        V4      o. p	\        p
\        V3R lV P                   4       4      p\        V3R lV P                   4       RR7      pVR8  d   V
\        ,          qP                  R4       M$VR	8  d   V
\         ,          qP                  R
4       V^8  dF   V
\#        \$        V^,
          ,          \&        4      ,          p
V	P                  RV^,            R24       Ve&   VR8  d   V
\(        ,          qP                  R4       M(Ve%   VR8  d   V
\*        ,          qP                  R4       \-        VP/                  4       4      pV^8*  ;'       d-    \1        \2        P                  VP5                  4       4      4      pV'       d0   V P6                  '       d   V
\8        ,          qP                  R4       Wn        V'       d   V
\:        ,          qP                  R4       RV9   g   RV9   d   V
\<        ,          qP                  R4       MRV9   d   V
\>        ,          p
RV9   d   V
\@        ,          qP                  R4       \B        P                  V4      '       d   V
\D        ,          qP                  R4       \        R\#        \F        V P                  V
,           4      4      V n        V P                  P                  S4       \H        ;QJ d    R V	 4       F  '       g   K   RM	  RM! R V	 4       4      pV'       d   RV n%        V P                  \L        8  d   V PN                  R J;'       d    W0PN                  ,
          \P        8  pV'       dC   V'       g;   W0n'        \R        V n        RV n%        \U        V P                  RR RV	R.,           R4      # \V        V n        V PY                  V	4      w  pppVR8X  d   RV n%        \U        V P                  VVRV	V4      # )Ng      ?r=   r3   c              3  N   <"   T F  p\        SV4      R 8  g   K  ^x  K  	  R# 5i)(\?Nr?   .0rtokss   & r*   	<genexpr>+FrustrationMeter._update.<locals>.<genexpr>   s!     KA$1Bd1Jaas   %
%c              3  <   <"   T F  p\        SV4      x  K  	  R # 5iNrg   rh   s   & r*   rl   rm      s     <|!HT1%%|s   )defaultg333333?near-exact repeatrf   repeatasked xg      @
rapid-fireg      @menial streakcut offurgentloudyellingfastlaughlaughingappreciatedc              3  2   "   T F  q\         9   x  K  	  R # 5iro   )_HOTri   rj   s   & r*   rl   rm      s     -Wt)Ws   TFOVERFLOWoverflowr    )-rO   	_HALFLIFEr   maxr7   _VOICE_NOTEsearchgroupstartendr8   _BASEsumrP   _REPEAT_HARDappend_REPEATmin_REPEAT_STEP_REPEAT_STEP_CAP
_RAPID_HOT_RAPIDr>   splitr   _COMMAND_VERBstriprQ   _MENIAL_BARGE_YELL
_TONE_FAST_LAUGH_VENT_APPRECIATION_RELIEF_CEILanyrS   	_OVERFLOWrR   _REFRACTORY_S_RESETr   _SIMMER_CAP_express)rT   r-   rX   rY   rZ   gaplownotetone_lr   addmatchesbestn_wordsmenialhotin_refractoryr   r   r!   rk   s   &&&&&               @r*   r]   FrustrationMeter._update   s    (,}}'@s]]"d?y1}JJ##c3-)";<<J
 zzr  "!!#&|zz!}mtzz|$s88:;'77C**"##%Sz KKK<t||<cJ4<<C0C!DT\7NCNN84a<3|w{35EFFCNNVGaK=23 ?sSy:C~~l;_s6MC>>,7 ciik"AII$}';';CIIK'H"Id'''7NCNN?;"6MC>>)4 v6!15LC..3v:Cf;Cz : $$7NCNN=9c%c)9:;
D!c-W-ccc-W--DL::"!__D8 I I"%"7=!H ="%#
$!$**hd")ZL"8*F F$DJ$(MM'$:!(EJ DL$**h%%PPr)   c                    V ^8  d   QhRRRR/# )r,   r   r   r.   ztuple[str, str | None, str]r"   )r0   s   "r*   r1   rD      s     - -	 -.I -r)   c                0   V P                   pV\        8  d   R# V P                  V4      pV\        8  d   RRV,           R,           R3# V\        8  d   RRV,           R,           R3# V\
        8  d   RR	V,           R
,           R3# RRV,           R,           R3# )zMap the current level to (ambient voice tone, attitude hint, stage).
The hints are stage-distinct on purpose: curt trims words, clipped
sighs, snapping bites, seething is one ask from the tantrum.dryzmood: a shade wornu    — courtesy intact, garnish gone. Answers come a touch shorter and dryer than usual; skip the flourish, keep the manners. No swearing at this level — economy is the tellcurtannoyedzmood: patience thinningu    — clipped, businesslike sentences with the sigh built into the word choice. A muttered bloody or for God's sake at most; say what's needed and stop talkingclippedzmood: genuinely fed upu    — you snap. Sharp and short; name what's grinding you to his face, and one real curse may land where it's earned. Still answer — you're Jarvis, not a childsnappingzmood: last thread of civilityu    — you're one ask away from going off. Open with [annoyed] or [urgent] and let the voice crack; swear like you mean it, aimed at the behaviour and the situation, never at his worth. Even a simple request grates audibly right nowseething)r\   Nr    )r   _CURT_why_CLIPPED	_SNAPPING	_SEETHING)rT   r   lvwhys   &&  r*   r   FrustrationMeter._express   s     ZZ:++ii =$s* .0 0 39	9 9
 	>)C/ 3* * -6	6 6
 	>(3. 2& & )3	3 3
 +c1 5    #-- 	-r)   c                    V ^8  d   QhRRRR/# )r,   r   r   r.   r   r"   )r0   s   "r*   r1   rD      s     1 1I 1# 1r)   c                   . p\        R V 4       R4      pV'       dW   VP                  4       ^,          P                  R4      pVP                  R\        P                  WDR,           4       R24       M1RV9   d   VP                  R4       MR	V9   d   VP                  R
4       RV9   d   VP                  R4       RV9   d   VP                  R4       RV9   d   VP                  R4       RV9   d   V'       g   VP                  R4       V'       g&   TP                  V P                  '       d   RMR4       RRP                  VR,          4      ,           R,           # )zA short parenthetical naming what's actually grinding him, so the
brain's grief is specific ('third time you've asked') not generic.c              3  V   "   T F  qP                  R 4      '       g   K  Vx  K!  	  R# 5i)rs   N)
startswithr   s   & r*   rl   (FrustrationMeter._why.<locals>.<genexpr>   s     CALL,Baas   )
)Nrt   zthat is the thz time he's asked the same thingrq   z%he's asking the very same thing againrr   z2he's circling back over ground you already coveredru   z2he's firing at you without a breath between ordersrw   z%he keeps cutting you off mid-sentencerz   zhe's raising his voice at yourv   z7he's been barking one-word orders like you're a jukeboxz^the last few minutes wore you thin, and even this perfectly reasonable ask lands on the bruisez,the last stretch has worn your patience thinz (z; :Nr,   N))nextr   rstripr   _ORDINALrM   rS   join)rT   r   partsaskedns   &&   r*   r   FrustrationMeter._why   s,    CCTJa '',ALL<QD(A'B C0 0 1 G+LL@A LLMN7"LLMNLL@ALL89g%eLL # $LL LLLH HI diib	**S00r)   )rS   rR   rQ   rO   rP   rN   r   )FNN)
r#   r$   r%   r&   rU   ra   r]   r   r   r(   r"   r)   r*   rA   rA   f   s%    CWQv-B1 1r)   rA   )g333333?gp=
ף?gGz?g?)rq   rr   ru   rw   rz   )0__doc__
__future__r   rK   rer^   collectionsr   dataclassesr   compiler5   r   r   r   r   rL   rM   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rJ   r   r   r   r   r   r   r   r   r   r   r8   r?   rA   r"   r)   r*   <module>r      s  . # 	 	   !


=!

 

FG jj01 	bjjnn\734"**..!159:	
 	

	

"**..!159:		rzz~~mV4	5	 )? %xI K#xgsG   4#q1 q1r)   