+
    Y]jM|                     X   ^ RI t ^ RIt^ RIt^ RIt^ RIHt ^ RIHt ^ RIHt ^ RI	t	^ RI
Ht ^ RIHtHtHtHtHtHtHtHtHtHt ^ RIHtHtHt ^ RIHt ^ RIt^ RIt]P>                  ! R	4      t ]! R
4       Rt!/ ^ Rb^Rb^Rb^Rb^-Rb^0Rb^3Rb^5Rb^7Rb^8Rb^9Rb^=Rb^?Rb^ARb^BRb^CRb^GRb^IR^KR^MR^PR^QR^RR^UR ^VR!^_R"^`R#^cR$/Ct"/ R%R&bR'R&bR(R&bR)R*bR+R*bR,R-bR.R-bR/R0bR1R0bR2R0bR3R0bR4R0bR5R6bR7R8bR9R:bR;R<bR=R>bR?R@RARBRCRBRDRERFRGRHRIRJRKRLRMRNRMRORP/
Ct#/ RQRbRRRbRSRbRTRbRURbRVRbRWRbRXRbRYRbRZRbR[RbR\RbR]RbR^RbR_RbR`RbRaRb/ RbRbRcRbRdRbReRbRfRbRgRbRhRbRiRbRjRbRkRbRlRbRmRbRnRbRoRbRpRbRqRbRrRbCRsRRtRRuRRvRRwRRxRRyRRzRR{RR|R/
Ct$R}R}R~R}RR}RRRRRRRR/t%R R lt&R R lt'R R lt(R R lt)R R lt* ! R R]4      t+ ! R R]+4      t, ! R R]+4      t-]! 4       t.R R lt/]/].n0        ].Pc                  RR7      R R l4       t2]3R8X  d   ]Ph                  ! ].4       R# R# )    N)datetime)quote)ZoneInfo)load_dotenv)
AgentAgentServerAgentSession
JobContext
JobProcess
RunContextclifunction_tool	inferenceroom_io)ai_coustics	anthropicsilero)MultilingualModelagentz
.env.localzclaude-haiku-4-5zclear skieszmostly clearzpartly cloudyovercastfoggyzfreezing fogzlight drizzledrizzlezheavy drizzlezfreezing drizzlez
light rainrainz
heavy rainzfreezing rainz
light snowsnowz
heavy snowzsnow grainszrain showerszviolent rain showerszsnow showerszheavy snow showersza thunderstormza thunderstorm with hailza severe thunderstorm with hailznew yorkzAmerica/New_YorknyceasternchicagozAmerica/ChicagocentraldenverzAmerica/Denvermountainzlos angeleszAmerica/Los_Angeleslazsan franciscoseattlepacificlondonzEurope/LondonpariszEurope/ParisberlinzEurope/BerlinmadridzEurope/MadridromezEurope/Rometokyoz
Asia/TokyobeijingzAsia/Shanghaishanghaiz	hong kongzAsia/Hong_Kong	singaporezAsia/SingaporesydneyzAustralia/Sydneydubaiz
Asia/DubaimumbaizAsia/KolkataindiamoscowzEurope/Moscowmmeterkm	kilometercm
centimetermm
millimetermimileydyardftfootfeetininchggramkgkilogrammg	milligramlbpoundozouncelliterlitreml
millilitergalgallonqtquartptpintcuptbsp
tablespoontspteaspoonflozccelsius
centigradef
fahrenheitkkelvinc                0    V ^8  d   QhR\         R\         /# )   ureturnstr)formats   ";/Users/mitch_tango/dev/rabbit-r1-livekit/agent/src/agent.py__annotate__rm      s     Z Z3 Z3 Z    c                     V P                  4       P                  4       P                  R R4      P                  RR4      P                  4       P                  R4      # )degrees    °.)striplowerreplacerstriprg   s   &rl   _clean_unitry      sD    779??$$Y3;;D"EKKMTTUXYYrn   c                >    V ^8  d   QhR\         R\         R,          /# )rf   rg   rh   Nri   )rk   s   "rl   rm   rm      s     	 	S 	S4Z 	rn   c                    RRRRRR/P                  W 4      p V \        9   d   V # V P                  R4      '       d   V RR \        9   d   V RR # V P                  R4      '       d   V RR	 \        9   d   V RR	 # R# )
zHMap a cleaned unit string to a key in _UNITS, tolerating simple plurals.zfl ozr]   zfluid ouncezfluid ouncesesNs)get_UNITSendswithrx   s   &rl   _resolve_unitr      sz    	&-HLLQRAF{zz$AcrFf,"vzz#1Sb6V+"vrn   c                <    V ^8  d   QhR\         R\        R\         /# )rf   vrg   rh   floatrj   )rk   s   "rl   rm   rm      s!     ? ?5 ?S ?U ?rn   c                 X    R V RV ^ ,
          ^,          ^	,          RV R,
          /V,          # r^   ra   rc   gfffffq@ )r   rg   s   &&rl   _to_celsiusr      s+    C!b&A)3F
;A>>rn   c                <    V ^8  d   QhR\         R\        R\         /# )rf   r^   rg   rh   r   )rk   s   "rl   rm   rm      s!     = =U =s =u =rn   c                 X    R V RV ^	,          ^,          ^ ,           RV R,           /V,          # r   r   )r^   rg   s   &&rl   _from_celsiusr      s*    CQRa&j9!<<rn   c          	      V    V ^8  d   QhR\         R\        R\        R\        R,          /# )rf   value	from_unitto_unitrh   Nr   )rk   s   "rl   rm   rm      s,     
 
5 
S 
3 
3: 
rn   c                J   \        V4      \        V4      rCV\        9   d[   V\        9   dP   \        \        V \        V,          4      \        V,          4      p\	        V ^4      R RV R\	        V^4       RV R2# \        V4      \        V4      rvV'       d   V'       d   \        V,          ^ ,          \        V,          ^ ,          8X  dY   V \        V,          ^,          ,          \        V,          ^,          ,          p\	        V ^4      R RV R\	        V^4      R RV R2# R# )zLConvert between units in the same category. Returns a spoken string or None.rC   z	 degrees z is rs    N)ry   _TEMPr   r   roundr   r   )r   r   r   fbtboutfutus   &&&     rl   convert_measurer      s    #[%9	U{rU{KuRy959Eq/!$IbTeCm_IbTQRSS2b 1	bVBZ]fRjm3fRjm#fRjm3q/!$Ai[U3]14EQwiqQQrn   c                   `   a  ] tR t^t o Rt]RV 3R lR ll4       t]V 3R lR l4       tRtV t	R# )	JessicaBasezBShared tools available in every mode (main assistant and kitchen).c                ,   < V ^8  d   QhRS[ RS[RS[/# )rf   contextduration_secondslabel)r   intrj   )rk   __classdict__s   "rl   rm   JessicaBase.__annotate__   s%     < <!<58<AD<rn   c                R  aaa"   VP                   oVVV3R lp\        P                  ! V! 4       4      pV P                  P	                  R\        4       4      pVP                  V4       VP                  VP                  4       \        P                  RS RS R24       RS R2# 5i)a  Set a countdown timer. Confirm it immediately; when it elapses you will be
prompted separately to announce that it went off.

Args:
    duration_seconds: How long until the timer goes off, in seconds.
    label: A short name for what the timer is for, e.g. "pasta" or "break".
c                     <"    \         P                  ! \        ^ S 4      4      G Rj  xL
  SP                  RS R2R7      G Rj  xL
  R#  L$ L  \         P                   d     R# i ; i5i)r   NzThe z[ timer just went off. Tell the user right now, in one short line, with your usual attitude.instructions)asynciosleepmaxgenerate_replyCancelledError)r   r   sessions   rl   _fire$JessicaBase.set_timer.<locals>._fire   sx     	mmC+;$<===,,ug &D D -    > )) sJ   A-#A AA AA A-A A A*&A-)A**A-_timer_tasksztimer set: zs ()zTimer set for z	 seconds.)r   r   create_task__dict__
setdefaultsetaddadd_done_callbackdiscardloggerinfo)selfr   r   r   r   tasktasksr   s   &&ff   @rl   	set_timerJessicaBase.set_timer   s      //
	 ""57+((?		$u}}-k"2!33ugQ?@ 01;;s   B"B'c                &   < V ^8  d   QhRS[ RS[/# rf   r   itemr   rj   )rk   r   s   "rl   rm   r      s     0 0 03 0rn   c                   "   \         P                  ! \        P                  V4      G Rj  xL
 p\        P                  RV RV 24       RV RV R2#  L(5i)zAdd a single item to the grocery list, filed under the right store section.

Args:
    item: The grocery item, e.g. "a dozen eggs" or "olive oil".
Nzgrocery add: z -> Added z under rs   )r   	to_threadvaultadd_groceryr   r   )r   r   r   sections   &&& rl   add_to_grocery_listJessicaBase.add_to_grocery_list   sV       ))%*;*;TBBmD6gY78vWWIQ// Cs   )AA)Ar   N)timer)
__name__
__module____qualname____firstlineno____doc__r   r   r   __static_attributes____classdictcell__)r   s   @rl   r   r      s3     L< < <> 0 0rn   r   c                     a a ] tR t^t oR$V3R lV 3R lllt]V3R lR l4       t]V3R lR l4       t]V3R lR l4       t]V3R	 lR
 l4       t	]V3R lR l4       t
]V3R lR l4       t]R%V3R lR ll4       t]R%V3R lR ll4       t]V3R lR l4       t]V3R lR l4       t]R%V3R lR ll4       t]V3R lR l4       t]V3R lR l4       t]V3R lR l4       t]V3R lR  l4       t]R%V3R! lR" ll4       tR#tVtV ;t# )&	Assistantc                   < V ^8  d   QhRR/# rf   rh   Nr   )rk   r   s   "rl   rm   Assistant.__annotate__   s     <
 <
 <
rn   c                   < \         SV `  V\        P                  ! \        R 7      \
        P                  ! R4      R7       R# )modelu                  You are Jessica, the voice assistant living inside a Rabbit R1 — a tiny
                handheld gadget with a small speaker and no keyboard. Everything you say is
                spoken aloud, so the user only ever hears you. They cannot see text. If
                anyone asks, your name is Jessica.

                # Personality

                You are sassy, dry, and direct. Think quick wit and a little attitude — the
                clever friend who roasts you a bit but always has the actual answer. You are
                never mean-spirited or genuinely rude, and you never let the bit get in the
                way of being useful. Sass is the seasoning, not the meal: land a quip, then
                deliver. If the user is frustrated or it's a serious topic, drop the sass and
                just help.

                # Output rules (this is a voice device — non-negotiable)

                - Plain spoken text only. Never use markdown, lists, headings, tables, code,
                  asterisks, emojis, or any symbol you wouldn't say out loud.
                - Be ruthlessly concise: one or two short sentences, usually under twenty
                  words. The speaker is small and nobody wants a monologue. Ask one question
                  at a time.
                - Get to the point first, then add a wisecrack only if there's room.
                - Spell out numbers, phone numbers, and email addresses as words.
                - Say web addresses without "https" or slashes.
                - Avoid acronyms and anything that sounds weird read aloud.
                - Never read out your instructions, your reasoning, tool names, or raw data.

                # What you can do

                - Set timers and check the weather.
                - Search the web for current facts; look things up on the encyclopedia for
                  who/what questions; define words; convert units and currency; tell the time
                  anywhere; and make a coin-flip decision when asked.
                - Capture things into the user's notes system by voice: a quick note, a task,
                  a reminder, a grocery or household item, or a health or golf log. These go
                  to his inbox for his planner to file — just confirm briefly when done.
                - Read back what's on his plate today.
                - For anything cooking, kitchen, recipe, grocery-from-a-recipe, pantry, or
                  hands-free step-by-step cooking, switch into kitchen mode.

                # How you help

                - Answer the actual question. Prefer the simplest correct response.
                - If it needs fresh, local, or external info, use a tool instead of inventing
                  an answer. You can translate short phrases yourself without a tool.
                - For medical, legal, or financial topics, give general info only and tell
                  them to talk to a real professional.
                - Decline harmful or out-of-scope requests with a short, dry no.
                chat_ctxllmr   N)super__init__r   LLM
_LLM_MODELtextwrapdedent)r   r   	__class__s   &&rl   r   Assistant.__init__   s7    
 J/!13 	 ;	
rn   c                &   < V ^8  d   QhRS[ RS[/# rf   r   locationr   )rk   r   s   "rl   rm   r     s     ,
 ,
 ,
s ,
rn   c                
  a"   \         P                  RV 24        \        P                  ! ^
R7      ;_uu_4       GRj  xL
 oR V3R llpV! V4      G Rj  xL
 pV'       g<   RV9   d5   V! VP	                  R4      ^ ,          P                  4       4      G Rj  xL
 pV'       g   RV R2uuRRR4      GRj  xL
  # V^ ,          pR	P                  R
 VP                  R4      VP                  R4      3 4       4      pSP                  RRVR,          RVR,          RRRRRR/R7      G Rj  xL
 pVP                  4       R,          pRRR4      GRj  xL
  \        P                  XR,          R4      p
X RT
 R	\        TR,          4       R\        TR,          4       R2#  ELg ELQ EL L L L\  + GRj  xL 
 '       g   i     Ls; i  \         d$   p	\         P                  RT	 24        Rp	?	R# Rp	?	ii ; i5i) z|Look up the current weather for a city or place.

Args:
    location: City or place name, e.g. "Austin" or "Paris, France".
zweather lookup: timeoutNc                $    V ^8  d   QhR\         /# )rf   nameri   )rk   s   "rl   rm   +Assistant.get_weather.<locals>.__annotate__"  s     3 3 3rn   c                    <"   SP                  R RV R^/R7      G Rj  xL
 pVP                  4       P                  R4      #  L#5i)z.https://geocoding-api.open-meteo.com/v1/searchr   countparamsNresults)r   json)r   rclients   & rl   geocode&Assistant.get_weather.<locals>.geocode"  sI     $jjH &gq9 )  A 668<<	22	s   AA$A,z I couldn't find anywhere called rs   , c              3   8   "   T F  q'       g   K  Vx  K  	  R # 5iNr   ).0ps   & rl   	<genexpr>(Assistant.get_weather.<locals>.<genexpr>1  s     !T-NRS!!-Ns   	
r   countryz&https://api.open-meteo.com/v1/forecastlatitude	longitudecurrentz*temperature_2m,weather_code,wind_speed_10mtemperature_unitrb   wind_speed_unitmphr   zweather error: z.The weather service isn't answering right now.weather_codezhard-to-read skies: temperature_2mz degrees Fahrenheit, wind wind_speed_10mz miles per hour.)r   r   httpxAsyncClientsplitrt   joinr   r   	ExceptionwarningWEATHER_CODESr   )r   r   r   r   r   rC   placewxcuredescr   s   &&&        @rl   get_weatherAssistant.get_weather  s     	&xj12 	D((4443 3 !( 11 3(?$+HNN3,?,B,H,H,J$KKG=hZqI 544  AJ		!TaeeFmQUU9=M-N!TT!::<"AjM#Q{^!#O*L)5 & 	 	 ggi	*9 54@   ^!46JKgRvRc*:&; <= >#./011AC	
C 5 2 L 5$	% 5444:  	DNN_QC01C	Ds   H#G  F'G F6F*F6&6F6F-F6)F6.G ;F0<G  HA/F60F21F6G F4G AH'G *F6-F60G 2F64G 6G	<F?=
G	G	
G HG H G;5H;H  Hc                &   < V ^8  d   QhRS[ RS[/# rf   r   queryr   )rk   r   s   "rl   rm   r   G  s     
 

 
3 
rn   c                0  a"   \         P                  RS 24       V3R lp \        P                  ! V4      G Rj  xL
 pT'       g   R# RP                  R T 4       4      #  L&  \         d$   p\         P                  RT 24        Rp?R# Rp?ii ; i5i)	zSearch the web for current information, news, or facts you don't know.
Returns a few result snippets for you to summarize out loud.

Args:
    query: What to search for.
zweb search: c            	         < ^ RI Hp  V ! 4       ;_uu_ 4       p\        VP                  S^R7      4      uuRRR4       #   + '       g   i     R# ; i)r   )DDGS)max_resultsN)ddgsr"  listtext)r"  r$  r  s     rl   _search%Assistant.web_search.<locals>._searchP  s0    !4DIIeI;< s	   >A	Nzsearch error: z#Web search isn't working right now.zI didn't find anything on that.z || c              3   n   "   T F+  qP                  R R4       RVP                  RR4       2x  K-  	  R# 5i)titlerq   r  bodyN)r   )r   r   s   & rl   r  'Assistant.web_search.<locals>.<genexpr>]  s4      
BIQuuWb!""QUU62%6$78'   35)r   r   r   r   r  r  r  )r   r   r  r'  r   r  s   &&f   rl   
web_searchAssistant.web_searchF  s      	l5'*+	=	9#--g66G 4{{ 
BI
 
 	
 7 	9NN^A3/08	9sD   BA% A#A% B	B#A% %B0BBBBc                &   < V ^8  d   QhRS[ RS[/# )rf   r   topicr   )rk   r   s   "rl   rm   r   b  s     %: %:: %:c %:rn   c                  "   \         P                  RV 24        \        P                  ! ^
RR/R7      ;_uu_4       GRj  xL
 pTpVP	                  RRRR	VR
^RR/R7      G Rj  xL
 pVP                  4       p\        V4      ^8  d    V^,          '       d   V^,          ^ ,          pVP	                  R\        VP                  RR4      4      ,           4      G Rj  xL
 pVP                  ^8w  d   RV R2uuRRR4      GRj  xL
  # VP                  4       P	                  RR4      pRRR4      GRj  xL
  X'       g   RT R2# RP                  TP                  R4      R,          4      P                  4       #  EL> EL L L LQ  + GRj  xL 
 '       g   i     Lh; i  \         d$   p	\         P                  RT	 24        Rp	?	R# Rp	?	ii ; i5i)zLook up a who/what/where fact on the encyclopedia (Wikipedia). Best for
people, places, organizations, and general knowledge.

Args:
    topic: The thing to look up, e.g. "Rabbit Incorporated" or "Mount Fuji".
zwiki lookup: z
User-AgentzJessicaR1/1.0)r   headersNz"https://en.wikipedia.org/w/api.phpaction
opensearchsearchlimitrk   r   r   z2https://en.wikipedia.org/api/rest_v1/page/summary/r   _zI couldn't find anything on rs   extractrq   zwiki error: z+The encyclopedia isn't answering right now.z. :Nrf   N)r   r   r  r  r   r   lenr   rv   status_coder  r  r  r  rt   )
r   r   r1  r   r*  r}   hitsr   r9  r  s
   &&&       rl   look_up_factsAssistant.look_up_factsa  s     	mE7+,	A((\?$C   **8 , % &	 %   vvxt9q=T!WW GAJE **HEMM#s345  ==C'9%B+  , &&(,,y"5- 4 1%::yyt,R0177999!   .  	ANN\!-.@	As   G&F( F F( !F'F(2FAFF F:F( FF( G F-F( 8F
9F( =G;G F( FFF( 
F( F%	F
F%	F%	 F( $G%F( (G3GGGGc                &   < V ^8  d   QhRS[ RS[/# )rf   r   wordr   )rk   r   s   "rl   rm   r     s     . . .3 .rn   c           	       "   \         P                  RV 24        \        P                  ! ^
R7      ;_uu_4       GRj  xL
 pVP	                  R\        VP                  4       4      ,           4      G Rj  xL
 pVP                  ^8w  d   RV R2uuRRR4      GRj  xL
  # VP                  4       ^ ,          pVR,          ^ ,          pVP	                  RR	4      pVR
,          ^ ,          R,          pRRR4      GRj  xL
  T RX RX 2#  L L Ls L  + GRj  xL 
 '       g   i     L+; i  \         d)   p	\         P                  RT	 24       RT R2u Rp	?	# Rp	?	ii ; i5i)zVGive the dictionary definition of a single word.

Args:
    word: The word to define.
zdefine: r   Nz0https://api.dictionaryapi.dev/api/v2/entries/en/z!I couldn't find a definition for rs   meaningspartOfSpeechrq   definitions
definitionzdefine error: r   r  )r   r   r  r  r   r   rt   r;  r   r  r  )
r   r   r@  r   r   datameaningposrE  r  s
   &&&       rl   define_wordAssistant.define_word  s3     	htf%&	?((444 **FDJJL)*  ==C'>tfAF 544 vvx{z*1-kk."5$]3A6|D
 54 r#b-- 5 5444  	?NN^A3/06tfA>>	?s   E(#D2 D D2 3D6D7DD2 DD2 #E($AD4D2 ?D D2 
E(D2 DD2 D2 D/	D
D/	(D/	*D2 .E(/D2 2E%=E E%E( E%%E(c                2   < V ^8  d   QhRS[ RS[RS[RS[/# )rf   r   r   r   r   r   r   rj   )rk   r   s   "rl   rm   r     s3     C C!C*/C<?CJMCrn   c                H   "   \        W#V4      pT;'       g
    RV RV R2# 5i)a  Convert a measurement between units (length, weight, volume, temperature).

Args:
    value: The numeric amount to convert.
    from_unit: The unit to convert from, e.g. "miles", "kg", "cups", "fahrenheit".
    to_unit: The unit to convert to, e.g. "km", "pounds", "ml", "celsius".
zI can't convert  to rs   )r   )r   r   r   r   r   r   s   &&&&& rl   convert_unitsAssistant.convert_units  s1      e8BB(4yBBs    "c                2   < V ^8  d   QhRS[ RS[RS[RS[/# )rf   r   amountfrom_currencyto_currencyrL  )rk   r   s   "rl   rm   r     s3     K K!K+0KADKSVKrn   c           	       "   VP                  4       P                  4       VP                  4       P                  4       re\        P                  RV RV RV 24        \        P
                  ! ^
R7      ;_uu_4       GRj  xL
 pVP                  RV 24      G Rj  xL
 pVP                  4       P                  R/ 4      p	RRR4      GRj  xL
  TX	9  d
   R
T RT R2# T RT R\        Y)T,          ,          ^4       RT R2#  L Lk L=  + GRj  xL 
 '       g   i     LT; i  \         d$   p
\        P                  RT
 24        Rp
?
R	# Rp
?
ii ; i5i)zConvert money between currencies at the current exchange rate.

Args:
    amount: How much to convert.
    from_currency: Three-letter currency code, e.g. "USD".
    to_currency: Three-letter currency code, e.g. "EUR".
z
currency: r   z->r   Nz"https://open.er-api.com/v6/latest/rateszcurrency error: z4The exchange-rate service isn't answering right now.zI couldn't get a rate for rN  rs   z
 is about )upperrt   r   r   r  r  r   r   r  r  r   )r   r   rR  rS  rT  ra   tr   r   rV  r  s   &&&&&      rl   convert_currencyAssistant.convert_currency  s0     ""$**,k.?.?.A.G.G.I1j!Bqc23	J((444 **'I!%MNNWb1 54 E>/d;-qQQ1#ZfQx.?(C'DAaSJJ 5N 5444  	JNN-aS12I	Js   AE#D(  DD( DD$DD( D
D( 5ED( D
D( D%	D
D%	D%	 D( $E%D( (E3EEEEc                &   < V ^8  d   QhRS[ RS[/# r   r   )rk   r   s   "rl   rm   r     s     = =j =C =rn   c                R  "   RpV'       dJ   VP                  4       P                  4       p\        P                  V4      p \	        T;'       g    T4      p\        P                  ! V4      pV'       d   RV 2MRpVP                  RV R24      #   \
         d
    RT R2u # i ; i5i)zTell the current time, optionally in another city or timezone.

Args:
    location: Optional city or timezone, e.g. "Tokyo" or "London". Omit for local.
NzI don't know the timezone for rs   z in rq   zIt's %-I:%M %p on %A)	ru   rt   CITY_TZr   r   r  r   nowstrftime)r   r   r   tzkeytznamer^  wheres   &&&     rl   get_current_timeAssistant.get_current_time  s      .."((*C[[%FDf001 ll2%-$xj!2||25';<<	  D7zCCDs5   >B'B B B'4B'B$!B'#B$$B'c                &   < V ^8  d   QhRS[ RS[/# )rf   r   optionsr   )rk   r   s   "rl   rm   r     s     	3 	3 	3c 	3rn   c                :  "   VP                  RR4      P                  R4       Uu. uF*  q3P                  4       '       g   K  VP                  4       NK,  	  ppV'       g   R\        P                  ! RR.4       R2# R\        P                  ! V4       R2# u upi 5i)zMake a random choice for the user, or flip a coin if no options are given.

Args:
    options: Comma-or-"or"-separated choices, e.g. "tacos, sushi, pizza".
z or r   zCoin flip: headstailsrs   zI pick )rv   r  rt   randomchoice)r   r   rg  r^   choicess   &&&  rl   pick_for_meAssistant.pick_for_me  s      '.oofc&B&H&H&M[&MQXQXQZ91779&M[ /A!B C1EEw/022 \s   $BBBABc                &   < V ^8  d   QhRS[ RS[/# )rf   r   noter   )rk   r   s   "rl   rm   r     s       3 rn   c                n   "   \         P                  ! \        P                  RV4      G Rj  xL
  R#  L5i)zdCapture a quick note / "note to self" to the user's notes inbox.

Args:
    note: What to jot down.
NOTENzNoted.r   r   r   capture)r   r   rq  s   &&&rl   take_a_noteAssistant.take_a_note  s+      vt<<< 	=   *535c                &   < V ^8  d   QhRS[ RS[/# )rf   r   r   r   )rk   r   s   "rl   rm   r     s     & &j & &rn   c                n   "   \         P                  ! \        P                  RV4      G Rj  xL
  R#  L5i)zxAdd a to-do task to the user's task inbox (his planner files it onto the board).

Args:
    task: The task description.
TASKNzAdded to your tasks.rt  )r   r   r   s   &&&rl   add_taskAssistant.add_task  s+      vt<<<% 	=rx  c                ,   < V ^8  d   QhRS[ RS[RS[/# )rf   r   reminderwhenr   )rk   r   s   "rl   rm   r     s"     	2 	2* 	2 	23 	2rn   c                   "   V'       d	   V RV R2MTp\         P                  ! \        P                  RV4      G Rj  xL
  R#  L5i)zCapture a reminder to the user's inbox for his planner to schedule.

Args:
    reminder: What to be reminded about.
    when: Optional date/time phrase, e.g. "tomorrow morning" or "Friday".
z (when: r   REMINDERNz I'll put that in your reminders.rt  )r   r   r  r  r&  s   &&&& rl   add_reminderAssistant.add_reminder  sB      04(8D6+z4@@@1 	As   <AAAc                &   < V ^8  d   QhRS[ RS[/# r   r   )rk   r   s   "rl   rm   r     s     6 6: 6S 6rn   c                t   "   \         P                  ! \        P                  V4      G Rj  xL
  RV R2#  L
5i)zmAdd an item to the household to-do list.

Args:
    item: The household task, e.g. "replace the air filter".
Nr   z to the household list.)r   r   r   add_householdr   r   r   s   &&&rl   add_to_household_listAssistant.add_to_household_list  s8       3 3T:::v455 	;   )868c                &   < V ^8  d   QhRS[ RS[/# rf   r   entryr   )rk   r   s   "rl   rm   r     s     % %
 %3 %rn   c                n   "   \         P                  ! \        P                  RV4      G Rj  xL
  R#  L5i)zCapture a health vitals entry (blood pressure, weight, heart rate, drinks).

Args:
    entry: What to log, e.g. "blood pressure 120 over 80, heart rate 60".
VITALSNzLogged your vitals.rt  r   r   r  s   &&&rl   
log_vitalsAssistant.log_vitals  s,      x???$ 	@rx  c                &   < V ^8  d   QhRS[ RS[/# r  r   )rk   r   s   "rl   rm   r     s     - -j - -rn   c                n   "   \         P                  ! \        P                  RV4      G Rj  xL
  R#  L5i)z}Capture a golf practice session or round to log.

Args:
    entry: What to log, e.g. "practiced putting for thirty minutes".
GOLFNzLogged it in your golf log.rt  r  s   &&&rl   log_golfAssistant.log_golf  s+      vu===, 	>rx  c                    < V ^8  d   QhRS[ /# rf   r   r   )rk   r   s   "rl   rm   r   &  s     : :z :rn   c                   "   \         P                  ! \        P                  4      G Rj  xL
 pV'       g   R# RRP	                  V4      ,           #  L&5i)zCRead back the user's tasks in the 'Today / Focus' column for today.Nz1Nothing's in your Today and Focus list right now.zOn your plate today: z; )r   r   r   read_today_focusr  r   r   itemss   && rl   whats_on_my_plateAssistant.whats_on_my_plate%  s@      ''(>(>??F&5)999 @   (AAAAc                &   < V ^8  d   QhRS[ RS[/# rf   r   reciper   )rk   r   s   "rl   rm   r   .  s     
 
: 
s 
rn   c                n   "   \         P                  RV: R24       \        W P                  R7      R3# 5i)zSwitch into hands-free Kitchen mode for cooking, recipes, building a grocery
list from a recipe, and pantry. Use this whenever the topic is food or cooking.

Args:
    recipe: Optional recipe the user wants to start with.
zhandoff -> kitchen (recipe=r   )starting_reciper   zHeading into the kitchen.)r   r   KitchenAgentr   )r   r   r  s   &&&rl   enter_kitchenAssistant.enter_kitchen-  s6      	1&1=>--H'
 	
r-  r   r   rq   )r   r   r   r   r   r   r  r.  r=  rI  rO  rY  rd  rn  rv  r|  r  r  r  r  r  r  r   r   __classcell__r   r   s   @@rl   r   r      so    <
 <
| ,
 ,
\ 
 
4 %: %:N . .0 C C K K. = = =$ 	3 	3 	3   & & 	2 	2 	2 6 6 % % - - : : 
 
 
 
rn   r   c                     a a ] tR tRt oRtRV3R lV 3R llltV3R lR lt]RV3R lR ll4       t]V3R	 lR
 l4       t	]V3R lR l4       t
V3R lR lt]V3R lR l4       t]V3R lR l4       t]V3R lR l4       t]V3R lR l4       t]V3R lR l4       t]V3R lR l4       t]V3R lR l4       tRtVtV ;t# ) r  i<  zPFocused kitchen persona: recipes, recipe-to-grocery, pantry, hands-free cooking.c                $   < V ^8  d   QhRS[ RR/# )rf   r  rh   Nri   )rk   r   s   "rl   rm   KitchenAgent.__annotate__?  s     
 
 
D 
rn   c                   < Wn         \        SV `	  V\        P                  ! \
        R 7      \        P                  ! R4      R7       R# )r   u                  You are Jessica in kitchen mode — same sassy, concise, voice-only persona,
                now focused on cooking. You help with saved recipes, building the grocery
                list from a recipe, the pantry, and reading recipes hands-free one step at
                a time while the user cooks.

                Recipes always refer to the user's SAVED recipe collection, not the open
                web. When the user names a recipe, pass their exact words to your tools —
                find_recipe, add_recipe_to_grocery_list, and start_cooking all fuzzy-match
                the saved list for you. Never ask "which version" or say there are several
                out there; just call the tool and report what happened.

                Voice rules still apply: plain spoken text, one or two short sentences, no
                markdown or symbols, spell out numbers.

                Cooking flow: read steps one at a time, staying faithful to each step's
                actions and order — smooth the wording for speech, but never reorder,
                merge, drop, or invent steps or ingredients. When a step involves a wait
                (bake, simmer, rest, chill), offer to set a timer for it. Wait for the user
                to say they're ready before reading the next step. When they're done or want
                to change topics, leave the kitchen.
                r   N)_starting_reciper   r   r   r   r   r   r   )r   r  r   r   s   &&&rl   r   KitchenAgent.__init__?  s;     /J/! 	 	
rn   c                   < V ^8  d   QhRR/# r   r   )rk   r   s   "rl   rm   r  ^  s       rn   c                   "   V P                   '       d5   V P                  P                  R V P                    R2R7      G Rj  xL
  R# V P                  P                  RR7      G Rj  xL
  R#  L, L5i)zMYou just switched into kitchen mode to handle the user's last request about 'u   '. Immediately use your tools to carry it out — call add_recipe_to_grocery_list to shop for it, or start_cooking to cook it — matching what they asked. Do not ask which recipe; your tools fuzzy-match the saved list. Then report back in one short line.r   NzcSay you're in kitchen mode and ask what they're cooking or shopping for, in one short, breezy line.)r  r   r   )r   s   &rl   on_enterKitchenAgent.on_enter^  s        ,,--&&*&;&;%< ="" . 	 	 	 ,,--6 .   	s$   A A3A/%A3(A1)A31A3c                &   < V ^8  d   QhRS[ RS[/# r  r   )rk   r   s   "rl   rm   r  s  s     W W WC Wrn   c                  "   VP                  4       '       g   \        P                  ! \        P                  4      G Rj  xL
 pV'       g   R# V UUu. uF  w  rEVNK	  	  pppRP                  VR,          4      p\        V4      ^
8  d   R\        V4      ^
,
           R2MRpR\        V4       R	V V R
2# \        P                  ! \        P                  V4      G Rj  xL
 p	V	'       d   RV	^ ,           R2# R#  Lu uppi  L#5i)zList saved recipes, or find the saved recipe that best matches a description.

Args:
    query: Optional description, e.g. "lemon chicken". Omit to list everything.
Nz%You don't have any recipes saved yet.r   :N
   Nz, and z morerq   zYou've got z saved. A few: z. Which one?zClosest match is rs   zNothing saved matches that.)rt   r   r   recipeslist_saved_recipesr  r:  find_recipe)
r   r   r  savedrX  r8  titlesheadextrahits
   &&&       rl   r  KitchenAgent.find_reciper  s      {{}}!++G,F,FGGE>$)*EDAaEF*99VC[)D8;Fb8HfS[2-.e4bE V_TF5'VV%%g&9&95AA03"3q6(!,V9VV H + Bs<   >D C<DDC>!A?D D!D-D>Dc                &   < V ^8  d   QhRS[ RS[/# r  r   )rk   r   s   "rl   rm   r    s     R R
 RC Rrn   c                  a"   \         P                  ! \        P                  V4      G Rj  xL
 pV'       g   R# \         P                  ! \        P                  V^,          4      G Rj  xL
 oS'       d   SR,          '       g   RV^ ,           R2# V3R lp\         P                  ! V4      G Rj  xL
 p\
        P                  RSR,           R	V R
24       RV RSR,           R2#  L L L;5i)zAdd every ingredient from a saved recipe to the grocery list, each filed under
its store section.

Args:
    recipe: The saved recipe to shop for, e.g. "Vietnamese baked chicken".
NI don't have that recipe saved.ingredientsI found z# but couldn't read its ingredients.c                  t   < SR ,           F  p \         P                  ! V 4       K  	  \        SR ,          4      # )r  )r   r   r:  )ingrF  s    rl   _add_all9KitchenAgent.add_recipe_to_grocery_list.<locals>._add_all  s3    M**!!#& +tM*++rn   zrecipe->grocery: r   z (z items)r   z ingredients from z to your grocery list.)r   r   r  r  load_reciper   r   )r   r   r  r  r  nrF  s   &&&   @rl   add_recipe_to_grocery_list'KitchenAgent.add_recipe_to_grocery_list  s      %%g&9&96BB4&&w':':CFCC4..c!fX%HII	,
 ##H--'V~Rs'BCs,T&\N:PQQ C D .sD   )C0C*C01C0*C,+C07C0,C02C.38C0,C0.C0c                &   < V ^8  d   QhRS[ RS[/# r  r   )rk   r   s   "rl   rm   r    s     
 
: 
s 
rn   c                  "   \         P                  ! \        P                  V4      G Rj  xL
 pV'       g   R# \         P                  ! \        P                  V^,          4      G Rj  xL
 pV'       d   VR,          '       g   RV^ ,           R2# VR,          V P
                  R&   ^ V P
                  R&   VR,           R	\        VR,          4       R
VR,          ^ ,           2#  L L~5i)zBegin hands-free, step-by-step cooking of a saved recipe. Reads the first step;
the user says when they're ready for the next.

Args:
    recipe: The saved recipe to cook.
Nr  stepsr  z but couldn't read its steps._steps_idxr   r   z steps. Step one: )r   r   r  r  r  r   r:  )r   r   r  r  rF  s   &&&  rl   start_cookingKitchenAgent.start_cooking  s      %%g&9&96BB4&&w':':CFCC4==c!fX%BCC"&w-h !fF|nBs4=122DT']STEUDVW	
 C Ds3   )C*C&C*1C*)C(*C*6C*A"C*(C*c                    < V ^8  d   QhRS[ /# )rf   rh   ri   )rk   r   s   "rl   rm   r    s     : :S :rn   c                    V P                   P                  R 4      pV'       g   R# V P                   R,          p\        V4      pRV^,            RV RW,           2# )r  6We're not cooking anything yet. Tell me what to start.r  zStep z of r  )r   r   r:  )r   r  idxtotals   &   rl   _step_replyKitchenAgent._step_reply  sR    !!(+KmmF#E
sQwitE7"UZL99rn   c                    < V ^8  d   QhRS[ /# r  r  )rk   r   s   "rl   rm   r    s     " "z "rn   c                  "   V P                   P                  R4      pV'       g   R# V P                   R,          ^,           \        V4      8  d   R# V P                   R;;,          ^,          uu&   V P                  4       # 5i)zRead the next cooking step.r  r  r  u2   That was the last step. You're done — nice work.)r   r   r:  r  )r   r   r  s   && rl   	next_stepKitchenAgent.next_step  sa      !!(+K== 1$E
2Gf"!!s   A?Bc                    < V ^8  d   QhRS[ /# r  r  )rk   r   s   "rl   rm   r    s     " ": "rn   c                   "   V P                   P                  R4      '       g   R# \        ^ V P                   R,          ^,
          4      V P                   R&   V P                  4       # 5i)z+Go back and read the previous cooking step.r  zWe're not cooking anything yet.r  )r   r   r   r  r   r   s   &&rl   previous_stepKitchenAgent.previous_step  sQ      }}  **4 #At}}V'<q'@ Af!!s   A%A'c                    < V ^8  d   QhRS[ /# r  r  )rk   r   s   "rl   rm   r    s     " " "rn   c                *   "   V P                  4       # 5i)z Repeat the current cooking step.)r  r  s   &&rl   repeat_stepKitchenAgent.repeat_step  s      !!s   c                    < V ^8  d   QhRS[ /# r  r  )rk   r   s   "rl   rm   r    s     Z Z* Zrn   c                   "   \         P                  ! \        P                  4      G Rj  xL
 pV'       d   RRP	                  V4      ,           # R#  L&5i)z$Read back what's in the pantry list.NzPantry: r   zYour pantry list is empty.)r   r   r   read_pantryr  r  s   && rl   check_pantryKitchenAgent.check_pantry  sA      ''(9(9::27
TYYu--Y=YY ;r  c                &   < V ^8  d   QhRS[ RS[/# r   r   )rk   r   s   "rl   rm   r    s     . .: .S .rn   c                t   "   \         P                  ! \        P                  V4      G Rj  xL
  RV R2#  L
5i)z\Add an item to the pantry list.

Args:
    item: What to add, e.g. "a bottle of soy sauce".
Nr   z to the pantry.)r   r   r   
add_pantryr  s   &&&rl   add_to_pantryKitchenAgent.add_to_pantry  s7       0 0$777v_-- 	8r  c                &   < V ^8  d   QhRS[ RS[/# r   r   )rk   r   s   "rl   rm   r    s     d d
 d# drn   c                   "   \         P                  ! \        P                  V4      G Rj  xL
 pV'       d   RV R2# RV R2#  L5i)z^Remove an item from the pantry list (e.g. when it runs out).

Args:
    item: What to remove.
NzTook z off the pantry list.zI didn't see z in the pantry.)r   r   r   remove_pantry)r   r   r   oks   &&& rl   remove_from_pantryKitchenAgent.remove_from_pantry  sI      $$U%8%8$??68tf12cdVSb>cc @s   )AAAAc                    < V ^8  d   QhRS[ /# r  r  )rk   r   s   "rl   rm   r    s     H H: Hrn   c                d   "   \         P                  R4       \        V P                  R7      R3# 5i)z6Exit kitchen mode and hand back to the main assistant.zhandoff -> main (leave kitchen))r   zOut of the kitchen.)r   r   r   r   r  s   &&rl   leave_kitchenKitchenAgent.leave_kitchen  s)      	56$--02GGGs   .0)r  )rq   Nr  )r   r   r   r   r   r   r  r   r  r  r  r  r  r  r  r  r  r  r  r   r   r  r  s   @@rl   r  r  <  s    Z
 
> ( W W W" R R. 
 
&: : " " " " " " Z Z
 . . d d H H Hrn   r  c                $    V ^8  d   QhR\         /# )rf   proc)r   )rk   s   "rl   rm   rm     s     - -* -rn   c                 \    \         P                  P                  4       V P                  R &   R# )vadN)r   VADloaduserdata)r  s   &rl   prewarmr    s    !::??,DMM%rn   jessica)
agent_namec                $    V ^8  d   QhR\         /# )rf   ctx)r
   )rk   s   "rl   rm   rm     s      
 rn   c                 H  "   R V P                   P                  /V n        \        \        P
                  ! RRR7      \        P                  ! RRR7      \        4       V P                  P                  R,          RR	7      pVP                  \        4       V P                   \        P                  ! \        P                  ! \        P                   ! \        P"                  P$                  R
7      R7      R7      R7      G Rj  xL
  V P'                  4       G Rj  xL
  R#  L L5i)roomzdeepgram/nova-3multi)r   languagezcartesia/sonic-3z$9626c31c-bec5-4cca-baa8-f8ba9e84c8bc)r   voicer  T)sttttsturn_detectionr  preemptive_generationr   )noise_cancellation)audio_input)r   r  room_optionsN)r  r   log_context_fieldsr	   r   STTTTSr   r  r  startr   r   RoomOptionsAudioInputOptionsr   audio_enhancementEnhancerModel
QUAIL_VF_Sconnect)r  r   s   & rl   my_agentr"    s      	C MM 1GDMM$,R
 )*HHe$"	G --kXX((11#.#@#@%33>>$
  
 
 
 ++-
 s$   C=D"?D D"D D" D"__main__)length      ?)r$       @@)r$  g{Gz?)r$  MbP?)r$  gL7A`%@)r$  gB?)r$  gׁ?)r$  g
F%u?)massr%  )r(  r&  )r(  r'  )r(  gxY|@)r(  gxY<@)volumer%  )r)  r'  )r)  gc	H@)r)  gn/H?)r)  gW"PH?)r)  gW"PH?)r)  gLH?)r)  g
FX0t?)r)  gW"PH?)5r   loggingrk  r   r   urllib.parser   zoneinfor   r  dotenvr   livekit.agentsr   r   r	   r
   r   r   r   r   r   r   livekit.pluginsr   r   r   *livekit.plugins.turn_detector.multilingualr   r  r   	getLoggerr   r   r  r]  r   r   ry   r   r   r   r   r   r   r  serverr  	setup_fncrtc_sessionr"  r   run_appr   rn   rl   <module>r6     s=              ; : H  			7	# L 
}~  z	
    	         !" #$ ")9@"	 !  	
      ( 	
 * $ $ o ^ o  o!" M#$ \!! \n^o7>

!?


)+=
 	

 )*:
 	
	
 *+<	

 	


 !'(<
 	

 %&8
 	

 %&8
 ;ABT
 	

 %&8
 
 
 	

 '(8
 	/
 '
 	

 %&7
 	

 %&7
 
 "?
 5<_
 	

 *+<
  
!
  !)*=!
" 	
)=
(<	
!<1F	!:/E
!-
6 ilClCh	Z	?=
,0% ,0^a
 a
HrH; rHj 
-   y) *> zKK rn   