
    Yij                       d dl mZ d dlZd dlZd dlmZ d dlZ ee      j                         j                  d   Z
 ee
      ej                  vr"ej                  j                  d  ee
             d dlmZ d dlmZ d dlmZ d dlmZmZ dd	Zddd
	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZddZedk(  r e ej6                   e                   y)    )annotationsN)Path   )GoogleWorkspacePreviewRequest)+prepare_google_workspace_preview_with_trace)$run_operational_assistant_with_trace)SessionIdentityget_tenant_storec                   t               }|j                         5 }|j                  d| f      j                         }|t	        d|        	 d d d        |j                  d         }|t	        d|        |S # 1 sw Y   /xY w)NaT  
            SELECT
                tenants.id AS tenant_id,
                tenants.slug AS tenant_slug,
                tenants.name AS tenant_name,
                tenants.database_path AS database_path,
                users.id AS user_id,
                users.email AS user_email,
                users.username AS username,
                users.name AS user_name,
                users.role AS role
            FROM tenants
            JOIN users ON users.tenant_id = tenants.id
            WHERE tenants.slug = ?
            ORDER BY users.created_at ASC
            LIMIT 1
            zTenant non trovato: 	tenant_idz1Sessione di servizio non disponibile per tenant: )r
   _connect_registryexecutefetchone
SystemExitbuild_service_session)tenant_slugstore
connectionrowsessions        +apps/backend-hub/scripts/assistant_smoke.py_build_sessionr      s    E		 	 	" Cj  " N%
& (*' 	( ;3K=ABB +C. ))#k*:;GL[MZ[[N5C Cs   2A<<B)thread_statemust_not_containc                8  K   t        | |||       d {   }|j                  }g }	|D ]  }
|
|vs|	j                  d|
 d        |xs g D ]  }
|
|v s|	j                  d|
 d        |	sdnd}t        d| d|        t        d	|j                          t        d
|j
                          t        d|        t        d|        |	rt        ddj                  |	              t                |d|dd|dgz   }|	 ||j                  fS 7 w)N)r   messageconversationr   zmanca ''znon dovrebbe contenere 'PASSFAIL[z] 	  route: 	  model: z
  prompt: z	  reply: z
  errors: z, userrolecontent	assistant)r   replyappendprintroutemodeljoinr   )r   namepromptr   r   must_containr   outcomer)   errorstokenstatusnext_conversations                r   	_run_caser7   1   sT     9!!	 G MMEF .MMGE7!,-. "'R ?E>MM4UG1=>? "VvF	AfXRv
	Igmm_
%&	Igmm_
%&	Jvh
 	IeW

499V,-./	G$F+/(  J*G,@,@@@=s   DDD$DCDc                   K   t        j                  d      } | j                  ddd       | j                         }t	        |j
                        }t	        d      }t	        d      }d	}d	}t        |d
dg ddgdg       d {   \  }}}	|t        |      z  }|t        |       z  }t        |ddg dgdg       d {   \  }}	}	|t        |      z  }|t        |       z  }t        |ddg ddgdg       d {   \  }}	}	|t        |      z  }|t        |       z  }t        |ddg ddgg d       d {   \  }}	}	|t        |      z  }|t        |       z  }t        |ddd dd!d"d#d!gdd$gd%d&g       d {   \  }}	}	|t        |      z  }|t        |       z  }t        |d'd(g g d)d*g       d {   \  }}	}
|t        |      z  }|t        |       z  }t        |d+d,d d-d!d"d.d!g|
g d/d0d*g1       d {   \  }}	}	|t        |      z  }|t        |       z  }t        |d2d3g g d4d5d6g       d {   \  }}	}	|t        |      z  }|t        |       z  }t        |d7d8g d9d:gd;g       d {   \  }}	}	|t        |      z  }|t        |       z  }t        |d<d=g d>d?gd@dAg       d {   \  }}	}	|t        |      z  }|t        |       z  }t        |dBdCg dDdEgd%dAg       d {   \  }}	}	|t        |      z  }|t        |       z  }t        |dFdGg dHdIgdJg       d {   \  }}	}	|t        |      z  }|t        |       z  }t        |dKdLd dGd!d"dMd!gdHdIgdAd%g       d {   \  }}	}	|t        |      z  }|t        |       z  }t        |dNdOg dPdQgdRg       d {   \  }}}|t        |      z  }|t        |       z  }t        |dSdT||dUdVgdRg1       d {   \  }}	}	|t        |      z  }|t        |       z  }t        |dWdXd dYd!d"dZd!gd[d\gd;g       d {   \  }}	}	|t        |      z  }|t        |       z  }t        |d]d^g d_d`gd;g       d {   \  }}	}	|t        |      z  }|t        |       z  }t        |dadbg dcddgd;g       d {   \  }}	}	|t        |      z  }|t        |       z  }t        |dedfd dgd!d"dhd!gg didjdkg       d {   \  }}	}	|t        |      z  }|t        |       z  }t        |dldmd dnd!d"dod!d dpd!d"dqd!gg drdg       d {   \  }}	}	|t        |      z  }|t        |       z  }t        |dsdtg g dudg       d {   \  }}}|t        |      z  }|t        |       z  }t        |dvdw||g dxdydzg1       d {   \  }}}|t        |      z  }|t        |       z  }t        |d{d|||d}d~gdydzg1       d {   \  }}}|t        |      z  }|t        |       z  }t        |dd||d}d~gdydzg1       d {   \  }}	}	|t        |      z  }|t        |       z  }t        |ddg ddgd;g       d {   \  }}}|t        |      z  }|t        |       z  }t        |dd||ddgdd;g1       d {   \  }}}|t        |      z  }|t        |       z  }t        |ddg ddgdd;g       d {   \  }}	}	|t        |      z  }|t        |       z  }t        |ddg ddgdd%g       d {   \  }}}|t        |      z  }|t        |       z  }t        |dd||dgd%dg1       d {   \  }}	}	|t        |      z  }|t        |       z  }t        |ddg dgdg       d {   \  }}}|t        |      z  }|t        |       z  }t        |dd||ddgddg1       d {   \  }}}|t        |      z  }|t        |       z  }t        |dd||dgdg1       d {   \  }}	}	|t        |      z  }|t        |       z  }t        |ddg dg       d {   \  }}}|t        |      z  }|t        |       z  }t        |dd||dgdg1       d {   \  }}	}	|t        |      z  }|t        |       z  }t        |ddg ddgddg       d {   \  }}}|t        |      z  }|t        |       z  }t        |dd||dgddg1       d {   \  }}	}	|t        |      z  }|t        |       z  }t        |ddg ddgg d       d {   \  }}	}	|t        |      z  }|t        |       z  }t        |ddg ddgddg       d {   \  }}	}	|t        |      z  }|t        |       z  }t        |ddg g dg d       d {   \  }}	}	|t        |      z  }|t        |       z  }d dd!d"dd!g}t        |dd|g ddg       d {   \  }}	}	|t        |      z  }|t        |       z  }t        |dd|g dĢdg       d {   \  }}	}	|t        |      z  }|t        |       z  }t        |t        dddǬȫ             d {   }|j                  dk(  xr" t        |j                  j                        d	kD  }t        dV|rdnd˛ d̝       t        d|j                          t        d|j                          t        dt        |j                  j                                t        d|j                  j                           t                |t        |      z  }|t        |       z  }t        |t        dddҬȫ             d {   }|j                  dk(  xr" t        |j                  j                        d	kD  }t        dV|rdnd˛ dӝ       t        d|j                          t        d|j                          t        dt        |j                  j                                t        d|j                  j                           t                |t        |      z  }|t        |       z  }t        |t        dddլȫ             d {   }|j                  dk(  xrI t        |j                  j                        dk\  xr% dt#        |j                  j                   xs dث      v }t        dV|rdnd˛ dٝ       t        d|j                          t        d|j                          t        dt        |j                  j                                t        d|j                  j                           t                |t        |      z  }|t        |       z  }t        d| d| dܝ       |d	k(  rd	S dS 7 g7 .7 7 7 v7 <7 7 7 7 H7 7 
7 
7 
V7 
7 	7 	7 	e7 	"7 7 7 b7 &7 7 7 t7 97 7 7 7 N7 7 7 7 h7 -7 7 7 |7 87 7 7 7 w)Nz4Smoke harness per l'assistente operativo del locale.)descriptionz--tenantritualz(Slug del tenant da usare, default ritual)defaulthelpzbaco-lounge-bartestr   zcompare-monthsu=   ho ordinato più prodotti in agosto 2025 o in settembre 2025?agosto 2025settembre 2025z&catalogo prodotti del locale non trovo)r   r/   r0   r   r1   r   zorders-year-without-queryzho fatto degli ordini nel 2026?20263Non trovo acquisti che corrispondano alla richiestazvodka-familyz$quante vodke abbiamo tra i prodotti?vodkaz
GREY GOOSEz
1 articolizsupplier-product-listz7voglio una lista dei prodotti che acquistiamo da laconizprodotti acquistati da LACONIREDBULL)zFornitori piu presenti:*Nel catalogo prodotti del locale risultanorA   z"supplier-product-list-followup-allzme li puoi mostrare tutti?r$   r%   r(   zQuesti sono i prodotti acquistati da LACONI: 59 prodotti distinti.
- REDBULL: quantita totale 674, lotto ct
- ... e altri 29 prodottiz59 prodotti distintiz(Non riesco ancora a leggere o aggiornarez... e altri 29 prodottiz'purchase-comparison-percentage-quantityu|   quanto ho ordinato in più in percentuale parlando di pezzi di articoli acquistati in agosto 2025 rispetto a settembre 2025?)r>   r?   %z90 prodotti distinti, 0 ordini distinti, quantita totale 0z$purchase-comparison-followup-contextze tra luglio e agosto?u   quanto ho ordinato in più in percentuale (parlando di pezzi di articoli acquistati) in agosto 2025 rispetto ad settembre 2025?zConfronto storico acquisti:
Hai ordinato una quantita totale maggiore in agosto 2025: 3570 contro 162.
In agosto 2025 hai ordinato il 2103,7% in piu rispetto a settembre 2025, parlando di pezzi totali acquistati.)zluglio 2025r>   rE   z*Nel catalogo prodotti del locale non trovo)r   r/   r0   r   r   r1   r   z purchase-frequency-week-of-monthz<quanti ordini ho fatto nella prima settimana di agosto 2025?)z
01/08/2025z
07/08/2025zordini distintiz362 righe trovatez
29/08/2025z#purchase-batches-show-orders-totaliz,mostrami gli ordini di agosto 2025, a totaliz/Questi sono gli ordini rilevati per agosto 2025zOrdine #z2Non trovo ordini che corrispondano alla richiesta.ztips-person-yearz&Quante mance ha preso Cioeta nel 2025?Cioeta2025z
Errore SQLz,Risposta LLM priva di contenuto utilizzabileztips-person-shortzQuante mance Ale Cioeta?z
Ale Cioetamanceztips-total-yearz3Quante mance sala abbiamo fatto in totale nel 2025?zTotale mance sala nel 2025zTotale complessivo da pagarez Giornate mance salvate per 2025:ztips-total-followupzFammi una somma del totaleuL   Giornate mance salvate per 2025:
- 2025-09-14: € 4700,01, sala, 27 personezsales-goals-read-progresszCome siamo messi a obbiettivi?	Obiettivizconfigurati nel localezPer impostare bene l'obiettivozsales-goals-graph-followupz Puoi mostrarmeli con un grafico?zGrafico testuale obiettivir!   z$purchase-batches-followup-next-monthz%mostrami gli ordini di settembre 2025z1mi mostri gli ordini che ho fatto in agosto 2025?zQuesti sono gli ordini rilevati per agosto 2025:
- Ordine #106 del 2025-08-29 22:09:38: 5 righe, quantita totale 18
- Ordine #102 del 2025-08-24 06:08:59: 5 righe, quantita totale 20z2Questi sono gli ordini rilevati per settembre 2025zOrdine #107zpurchase-batch-detail-by-idzXmostrami per esteso l' Ordine #96 del 2025-08-17 15:16:46: 15 righe, quantita totale 118z"Ordine #96 del 2025-08-17 15:16:46zContenuto ordine:zpurchase-batch-detail-by-datez mostrami l'ordine del 2025-08-17z
Ordine #96z
Ordine #95z#sales-goal-supplier-liters-followupu   Moet & Chandon (come fornitore), obbiettivo 1000 litri, i prodotti sono tutti quelli del fornitore MOET, il target è solo a litri, l'anno è il 2026.z*devo fissare un nuovo obbiettivo aziendaleu   Per impostare un nuovo obiettivo di vendita avrei bisogno di alcuni dettagli:
1. Nome dell’obiettivo.
2. Tipo di obiettivo.
3. Criterio di corrispondenza del prodotto o fornitore.
4. Target numerico.
5. Anno di riferimento.)MOETzquante unita contienecartonerD   z,corrispondono a moet chandon come obbiettivoz(sales-goal-product-quantity-confirmationz5Dom Perignon, 500 bottiglie da ordinare entro l'anno,zChe obbiettivi abbiamo?zHObiettivi 2026 configurati nel locale:
- Target MOET 2026: 70.0/1000.0 LzNe aggiungiamo uno?u  Certo! Per aggiungere un nuovo obiettivo di vendita avrei bisogno di qualche dettaglio in più:
1. Nome dell’obiettivo (es. "Bombay estate")
2. Tipo di target: quantità, litri, litri_dual o nota
3. Cosa deve corrispondere il prodotto (query di ricerca)
4. Valore del target (numero))Per essere precisozDom Perignonz500 bottiglieCONFERMOzsales-goal-confirm-seedz1imposta obbiettivo 1000 litri dal fornitore ferro)Target ferro 20261000 LrM   zsales-goal-confirm-applyconfermo)rN   rO   zfornitore ferrorL   zSe e corretto, scrivi CONFERMOzsales-goal-read-after-confirmzmostrami gli obbiettiviz%Obiettivi 2026 configurati nel localerN   z&sales-goal-read-question-after-confirmzche obbiettivi abbiamo?zlatest-order-defaultzUltimo ordinez
Ordine #32z2026-04-21 15:17:00zlatest-order-penultimatezPenultimo ordinez
Ordine #31z2026-04-06 10:16:00zlatest-order-last-twozUltimi 2 ordini fattiz
Ordine #24z#purchase-frequency-last-vodka-orderzDa quanto non ordino vodka?zNon ordini vodkaz06/03/2026 10:15zAMARO NONNINOz,purchase-frequency-last-vodka-order-followupz
Ma quando?zProva a riformularezproduct-price-per-kg-seedzQuanto costa la Nutella al kg?zNUTELLA CARTUCCIA KG1X6PZzDA COMPLETAREzproduct-price-per-kg-updatez/Aggiungi 11.31 come prezzo al kg per la nutellaz3Ho aggiornato il prodotto NUTELLA CARTUCCIA KG1X6PZu   Prezzo al kg: € 11,31/kgzHo aggiunto il prodottoz%product-price-per-kg-delete-guardrailz!No cancella questo nuovo prodottoz<Non risulta nessun nuovo prodotto appena creato da eliminarezHo eliminato il prodottozhistory-month-contextz"che ordini ho fatto agosto scorso?)r   r/   r0   r   r1   zhistory-follow-upzmi mostri i singoli ordini?zcatalog-detail-requestz6mostrami tutti i dati che abbiamo su giffard alla morazQuesti sono i dati che trovo suzGIFFARD ALLA MORA CL100z6Nel catalogo prodotti del locale risultano 19 articolizcatalog-detail-followup-searchzcerca nei prodottiz+corrispondono a dati giffard mora cerca neizpack-size-exact-productz*quante unit per pack ha giffard alla mora?z-GIFFARD ALLA MORA CL100 (FERRO, bt): lotto btz5GIFFARD ALLA MORA CL100 (FERRO, ct): 6 unita per pack)zGIFFARD POMPELMOzSCIROPPO MANGOzLIQUORE GIFFARD LIME CANEzpurchase-amount-overview-bacoz#quanto ho speso di ordini del 2026?zspesa totaleu   €zquantita totale 1ztenant-sql-analytics-rankingzCquali sono i primi 3 fornitori per numero di prodotti nel catalogo?)LACONIrJ   zsupplier_name=ztotal_products=)z$Questi sono i prodotti acquistati daz	Non trovozDOM PERIGNONzche salmone compro?a<  Nel catalogo prodotti del locale risultano 5 articoli che corrispondono a salmone:
- SALMONE NORV. PREAF. KG.1 (CHEF, 1kg)
- SALMONE AFF RITAGLI 500G S/VS (MARR, 500g)
- FIL. SALMONE 1000/1600 G F (MARR, 1000/1600g)
- FIL. SALMONE 1000/1600 g F (MARR, 1000/1600g)
- FIL.SALMONE 1000/1400G G MOWI F (MARR, 1000/1400g)zcatalog-lowest-price-followupzquale costa meno?)z	meno carozSALMONE AFF RITAGLI 500G S/VSu   € 7,65z0Nel catalogo prodotti trovo questi prezzi ivati:zcatalog-price-per-kg-followupzcalcola il prezzo al chilo)zPrezzo al chilo stimatoz/kgSALMONEz4Non trovo articoli che corrispondano a calcola chilosheetuY   lista di tutti i prodotti food che compriamo, ordinata dal più economico al più costoso)kindtitler0   zdocuments-grounded-previewr   r    z] documents-grounded-previewr"   r#   z  rows: z  summary: zordini agostoz:creami un file sheet con tutti gli ordini di agosto scorsoz#] documents-orders-grounded-previewchefzdcreami un file con la lista di tutti i prodotti che compro da Chef comprensiva di prezzi di acquisto2   zcatalogo locale z(] documents-supplier-catalog-with-priceszRisultato: z
 passati, z fallitir   )argparseArgumentParseradd_argument
parse_argsr   tenantr7   intr   r   r,   lenpreviewrowsr+   r-   summarystr) parserargsr   baco_sessiontest_sessionpassedfailedokr   _comparison_thread_stategoals_conversationgoals_thread_stategoal_conversationgoal_thread_statelatest_orders_conversationlatest_orders_thread_statevodka_conversationvodka_thread_statenutella_conversationnutella_thread_statefollowup_conversationfollowup_thread_statecatalog_conversationcatalog_thread_statesalmone_conversationpreview_outcomedocument_okorders_preview_outcomeorders_document_ok supplier_catalog_preview_outcomesupplier_document_oks                                    r   mainr   \   s    $$1ghF

H;efDT[[)G!"34L!&)LFF )N#%56BC! Ba c"gF
cb&kF(0XOP HB1 c"gF
cb&kF5|,& HB1 c"gF
cb&kF$H5yA Z HB1 c"gF
cb&kF1+(ab   .w  x
 67MNDF_`
 
HB1 c"gF
cb&kF+46 N;UV, &"B" c"gF
cb&kF3'  ]
 $D
 -8F  ID  E) HB1, c"gF
cb&kF/MD-|< HB1 c"gF
cb&kF2=GTNO HB1 c"gF
cb&kF7'&(VW HB1 c"gF
cb&kF )"G,DFtu HB1 c"gF
cb&kFD24RS<= HB1 c"gF
cb&kF"+(]^ -|}
 34RSHJtu
 
HB1 c"gF
cb&kF7@(/!#;<:;8 2.B. c"gF
cb&kF)1''2C8:; HB1 c"gF
cb&kF36([\#Y

 KMZNO! HB1$ c"gF
cb&kF*i:<OPNO HB1 c"gF
cb&kF,1"L1NO HB1 c"gF
cb&kF2 h(TU#.

 BFHvw' HB1* c"gF
cb&kF7F(AB -xy(=>#4		
 YOP) HB1, c"gF
cb&kF5>&B@OP6 0,B, c"gF
cb&kF5>'&&G.0PQ6 0,B, c"gF
cb&kF5>,(&&=?RS.0PQ6 0,B, c"gF
cb&kF5(&&=?RS.0PQ HB1 c"gF
cb&kFGP#"$9:NOH B>B"$> c"gF
cb&kFGP'!//"$9:&(\]H B>B"$> c"gF
cb&kF$&"L1&(\] HB1 c"gF
cb&kF7@2,(*<=)+UV8 2.B. c"gF
cb&kF;''()DF[\ HB1 c"gF
cb&kF;D(/12)*< 62B2 c"gF
cb&kF;D*@))KMij3_E< 62B2 c"gF
cb&kF42))TU45 HB1 c"gF
cb&kF=F$3#_> 84B4 c"gF
cb&kF ,**#_OP HB1 c"gF
cb&kF;D%G79RSO  RJ  K< 62B2 c"gF
cb&kF-#))/0GI~ HB1 c"gF
cb&kF&;EG~\ HB1 c"gF
cb&kF,4$e,-/de HB1 c"gF
cb&kF+TL^ HB1 c"gF
cb&kF $9:G
	
 ,")OLM HB1 c"gF
cb&kF,+)BPQ HB1 c"gF
cb&kFG%n	
 O "''+GGqCP_PgPgPlPlLmpqLqK	Af00L
MN	Io++,
-.	Io++,
-.	HS005567
89	K//778
9:	G
c+F
ck/""F#N%!O	
$  	$$(DD 	9&..334q8  
A*f77Z
[\	I,223
45	I,223
45	HS/77<<=>
?@	K.66>>?
@A	G
c$%%F
c(())F-X%y	
. ($ 	)..2NN 	]088==>"D	]%E%M%M%U%U%[Y[!\\ 
 
A,f&99a
bc	I6<<=
>?	I6<<=
>?	HS9AAFFGH
IJ	K8@@HHI
JK	G
c&''F
c**++F	Kxz&
:;!1""e
&2
2*02000BB266864$*(s#  By.w*;y.?w- <y.<w0==y.:w3;Ay. w6<y.=w9>Ay.w<=y.w?<y.?x =y.=x>=y.;x<<y.8x9Ay.>x?<y.;x<=y.9x:Ay.>x?<y.;x<<y.8x9Ay.>x ?Ay.x#<y.x&	>y.x)>y.x,>y.x/<y.x2>y.x5=y.?x8 =y.=x;>=y.;x><;y.7y8>y.6y7<y.3y49y.-y
.<y.*y+=y.(y)=y.&y'=y.$y%=y."y#=y. y!Ay.'y(<y.$y"%A y.%y%&D	y./y(0D	y.9y+:D1y.-y.0y.3y.6y.9y.<y.?y.y.y.y.y.y.y.y.y.y.y. y.#y.&y.)y.,y./y.2y.5y.8y.;y.>y.y.y.y.
y.y.y.y.y.y.y.y."y.%y.(y.+y.__main__)r   rc   returnr	   )r   r	   r/   rc   r0   rc   r   zlist[dict[str, str]]r   zdict[str, object] | Noner1   z	list[str]r   zlist[str] | Noner   z;tuple[bool, list[dict[str, str]], dict[str, object] | None])r   r^   )
__future__r   rY   asynciopathlibr   sys__file__resolveparentsPROJECT_ROOTrc   pathinsertapp.models.google_workspacer   *app.services.operational_assistant_servicer   r   app.services.tenant_storer	   r
   r   r7   r   __name__r   run     r   <module>r      s    "    
H~%%'//2|CHH$HHOOAs<() E b [ GJ .2)-(A(A (A 	(A
 '(A +(A (A '(A A(AV]	#@ z
[W[[(
)) r   