PRizdZddlZddlZddlZddlmZddlmZmZmZm Z m Z m Z m Z m Z mZmZmZmZmZmZmZmZddlmZddlmZddlmZGdd eZy) z< ProfileEditorDialog - Editor visuale per parametri profilo N)datetime)QDialog QVBoxLayout QHBoxLayoutQLabelQPlainTextEdit QPushButton QMessageBox QTabWidgetQWidgetQDoubleSpinBoxQSpinBox QFormLayout QTableWidgetQTableWidgetItem QFileDialogQProgressDialog)Qt)QFont) ConfigManagerceZdZdZdfd ZdZdefdZdefdZdZ de fdZ d Z d e d edefd Zd ZdefdZdZdZdZde fdZxZS)ProfileEditorDialogz6Dialog modale per modifica/creazione parametri profiloc t||||_||_d|_d|_t jjt jjt jjt jjt jjtdd|_ |j|j|jdk(r|jyy)a1 Inizializza dialog editor profilo Args: kernel: Riferimento al JarvisKernel (per active_profile) o MockKernel mode: 'edit' per modificare profilo esistente, 'create' per nuovo profilo parent: Widget parent (ProfileSelectorDialog o MainWindow) Nconfigz config.yamledit)super__init__kernelmodeconfig_managernew_profile_idospathjoindirnameabspath__file__ config_pathinit_uiapply_stylesheetload_current_config)selfrrparent __class__s M/mnt/ssd/data/python-lab/Jarvis-Cognitive/desktop/ui/profile_editor_dialog.pyrzProfileEditorDialog.__init__s    ""77<< GGOOBGGOOBGGOOBGGOOHjA|jB|j!| t;d} | j=d| j>jA|jD|j!| |jG||jI|y)z Inizializza l'interfaccia utentecreatezCrea Nuovo Profilou➕ Crea Nuovo ProfilouQConfigura un nuovo assistente personalizzato. Verrà aggiunto alla lista profili.ProfilozModifica Profilo - u⚙️ Modifica Profilo: z^Modifica i parametri del profilo. Le modifiche saranno applicate al riavvio dell'applicazione.Ti iz2color: #666; font-size: 11px; margin-bottom: 10px;u📝 Personalitàu🎛️ Parametriu📚 Documenti RAGAnnulla cancel_btnu 💾 Salvasave_btnN)%rsetWindowTitleractive_profile capitalizesetModalsetMinimumWidthsetMinimumHeightr setSpacingsetContentsMarginsrr setPointSizesetBoldsetFont addWidget setStyleSheetr tabs_create_personality_tabpersonality_tabaddTab_create_parameters_tabparameters_tab_create_documents_tab documents_tabr addStretchr setObjectNameclickedconnectreject save_config addLayout setLayout) r, header_text subtitle_text profile_namelayoutheader header_fontsubtitle button_layoutr8r9s r/r)zProfileEditorDialog.init_ui4s 99    4 52KoMFJkkF`F`4;;55@@BfoL   "5l^ D E5l^DK|M d S! c""!!"b"b1 $g   $D!{# -(ST"L  $;;= --/BC#99; ,,.AB"779 ++-AB#$   " +   .""4;;/ +|,z*  !1!12)' vr0returnct}t}|jddddtd}|j d|j |td}|j d|j |t |_|jjd|jjd|j |j|j||S)u-Crea tab Personalità con editor agent_prompt zSystem Prompt (agent_prompt)&font-weight: bold; margin-bottom: 5px;uVDefinisce la personalità, stile comunicativo, regole e comportamento dell'assistente.2color: #666; font-size: 10px; margin-bottom: 10px;uSystem prompt che definisce personalità, stile, regole... Esempio struttura: - Introduzione personalità - STILE COMUNICATIVO - VIETATO - REGOLA ASSOLUTA - STRUMENTIi) r rrArrFrEr prompt_editorsetPlaceholderTextr?rV)r,tabrZlabel help_texts r/rHz+ProfileEditorDialog._create_personality_tabxsi!!"b"b156 DE d   TU#,- --   ++C0++, f r0cddlm}t}t}|j ddddt }|j d|jdk(rt}|j d||_|jjd|j|jtd}|jd |j||jd |t}|j dt|_|jj!d |jj#d |jj%d |jj'd|jj)d|j|jtd}|jd |j||jd|t} | j dt+|_|j,j!d|j,j#d|j,j%d|j,j)d| j|j,td} | jd | j| |jd| |j/||j1dtd} | jd|j| td} | jd|j| t3|_|j4jd|j4j7d|j4j9d|j|j4|j;|j=||S) z#Crea tab Parametri con spinbox varir) QLineEditrar4r2zes: einstein, darwin, curie...z/ID univoco del profilo (minuscolo, senza spazi)zcolor: #666; font-size: 10px;z ID Profilo*:?g?ffffff?z$0.0 = deterministico, 1.0 = creativouTemperatura (creatività):d z1Numero massimo token per risposta (default: 4096)zLunghezza massima risposta:r5z'Descrizione Tool Ricerca Knowledge BaserbzIDescrizione del tool di ricerca semantica nel knowledge base del profilo.rczEs: Cerca nel knowledge base di Warren (portfolio, scans, decisioni, verbali). Usa questo per verificare vincoli, thesis, performance storiche, regole.x)PyQt6.QtWidgetsrjr rrArr@rprofile_id_inputrerErrFaddRowr temperature_spin setMinimum setMaximum setSingleStep setDecimalssetValuermax_tokens_spinrU addSpacingrrag_description_editorr?setMaximumHeightrOrV) r,rjrfrZ form_layout id_containerid_helptemp_container temp_helptokens_container tokens_help rag_labelrag_helps r/rKz*ProfileEditorDialog._create_parameters_tabsS-i!!"b"b1"m r" 99 &=L  # #A &$-KD !  ! ! 4 45U V  " "4#8#8 9NOG  ! !"A B  " "7 +   ~| <%!!!$ . 0 ((- ((- ++D1 ))!, &&s+  !6!67AB  ?@  +7H'=##A&'z '', ''- **3/ %%d+""4#7#78PQ !!"AB"";/8:JK% "DE  HI# W  ST"&4&6# ##66 W  ##44S9 ##44S9445 f r0c  t|j|_|jj|jj d}|s@t j|dd|jj d|jy|jj|jdd|jj|jdd |jj|jd d |jj|jd dy#t $r=}t j"|d dt%||jYd}~yd}~wwxYw)z8Carica parametri attuali da config.yaml e popola widgetsCognitiveServicezErrore Caricamentoz1Impossibile caricare configurazione per profilo ''N agent_prompt temperaturero max_tokensrsrag_tool_descriptionErrore Criticoz#Impossibile caricare config.yaml: )rr(r get_service_configrr;r warningrSrd setPlainTextgetryr~rr Exceptioncriticalstr)r,service_configes r/r+z'ProfileEditorDialog.load_current_configsJ "/0@0@"AD !00CC **"N "##(G HbHbGccde      + +N,>,>~r,R S  ! ! * *>+=+=mS+Q R  ) ).*<*<\4*P Q  ' ' 4 4""#92>     7Ax@  KKMM  sB D;B,D;; F3E<<Fc|jdk(r|jjjj }|syddl}|j d|sy|jst|j|_|jj|d}|rdd |d fS||_ |jjj}|sy |jj}d |cxkrd ks ndd|dfS|j j}d|cxkrdks ndd|dfS|j"jj}|rt%|dkryy)z Valida tutti gli input prima del salvataggio Returns: Tupla (is_valid: bool, error_message: str) r2)Fu L'ID del profilo è obbligatoriorNz ^[a-z0-9_]+$)FzEID profilo deve contenere solo lettere minuscole, numeri e underscorerF Profilo 'u$' esiste già. Scegli un ID diverso.)Fu2Il prompt della personalità non può essere vuotorlrmz0Temperatura deve essere tra 0.0 e 1.0 (attuale: )rprqz0Max tokens deve essere tra 100 e 8192 (attuale: ra)Fz7Descrizione RAG tool troppo breve (minimo 10 caratteri))Tr)rrwtextstriplowerrematchr rr(rr!rd toPlainTextryvaluerrlen)r, profile_idrexisting_configprompttemptokensrag_descs r/validate_inputsz#ProfileEditorDialog.validate_inputsss 99 ..335;;=CCEJ@ 88OZ8e&&&3D4D4D&E#"11DDZQcdO *5YZZZ",D ##//1779N$$**,t"s"LTFRSTT T%%++-v%%LVHTUVV V..::<BBD H *Sr0c |j\}}|stj|d|y|jdk(r|j}d|d}d|d}n"|j j }d|d}d|d }tj|d |tjjtjjz}|tjjk7ry|jj|jj|jj|j jd } |j"st%|j&|_|j"j)}|jdk(r|j+||} n|j"j-|d |} | rJtj.|d |dt0j2j5||j7ytj8|ddy#t:$r-} tj8|ddt=| Yd} ~ yd} ~ wwxYw)zCSalva modifiche su config.yaml (edit) o crea nuovo profilo (create)zValidazione FallitaNr2zCreare il nuovo profilo 'u6'? Verrà creato un backup automatico di config.yaml.rz' creato con successo!z!Salvare le modifiche al profilo 'z' aggiornato con successo!zConferma Salvataggio)rrrrrSuccessoz Backup creato: ErrorezSalvataggio fallitorz(Impossibile salvare la configurazione: )rr rrr!rr;questionStandardButtonYesNordrryrrrr rr( create_backup_create_new_profileupdate_service_config informationr"r#basenameacceptrrr) r,valid error_msgtarget_profile confirm_msg success_msgreplyupdates backup_pathsuccessrs r/rTzProfileEditorDialog.save_configKsE //1y   &;Y G  99 !00N5n5EE}~K%n%55KLK![[77N=n=MNFGK%n%55OPK$$  "   & & * *[-G-G-J-J J   K..22 2 !..::<00668..446$($?$?$K$K$M   &&&3D4D4D&E#--;;=KyyH$22>7K--CC"& ''"m#6rww7G7G 7T6UV  $$T85JK     D&* G, ^*>z:&$""C' : a II#("   ggll GGOOD,, -       BGGLLk:TJ BGGLLk:TJ BGGLLf5E BGGLLg6F/  s GG c&|jdy)z%Applica stylesheet coerente con l'appat QDialog { background-color: #f5f5f5; } QLabel { color: #333; font-size: 12px; } QPlainTextEdit { border: 1px solid #ddd; border-radius: 4px; padding: 8px; font-family: 'Courier New', 'Consolas', monospace; font-size: 11px; background-color: white; } QDoubleSpinBox, QSpinBox { border: 1px solid #ddd; border-radius: 4px; padding: 6px; min-width: 100px; background-color: white; } QPushButton { background-color: #4CAF50; color: white; border: none; border-radius: 4px; padding: 10px 20px; font-weight: bold; font-size: 12px; } QPushButton:hover { background-color: #45a049; } QPushButton#cancel_btn { background-color: #999; } QPushButton#cancel_btn:hover { background-color: #777; } QTabWidget::pane { border: 1px solid #ddd; border-radius: 4px; background-color: white; } QTabBar::tab { background-color: #e0e0e0; padding: 10px 20px; margin-right: 2px; border-top-left-radius: 4px; border-top-right-radius: 4px; } QTabBar::tab:selected { background-color: white; border-bottom: 2px solid #4CAF50; } QTabBar::tab:hover { background-color: #d0d0d0; } N)rF)r,s r/r*z$ProfileEditorDialog.apply_stylesheets < < r0ct}t}td|j}|j d|j |t |_|jjd|jjgd|jjt jj|jjt jj|jj!d|jj#}|j%d|j'dd|j'd d |j'd d |j'd d|j'dd|j |jt)}t+d}|j,j/|j0|j ||j3t+d}|j d|j,j/|j4|j |t+d}|j d|j,j/|j6|j ||j9||j;||j1|S)z&Tab gestione documenti RAG del profiloz&Documenti knowledge base per profilo: z8font-weight: bold; font-size: 13px; margin-bottom: 10px;rk)FilenameAutoreChunks Dimensione IndicizzatoTFrrurnPrprtu🔄 Ricarica Listau➕ Aggiungi PDFa= QPushButton { background-color: #4CAF50; color: white; font-weight: bold; padding: 8px 16px; border-radius: 4px; } QPushButton:hover { background-color: #45a049; } u🗑️ Elimina Selezionatia= QPushButton { background-color: #f44336; color: white; font-weight: bold; padding: 8px 16px; border-radius: 4px; } QPushButton:hover { background-color: #da190b; } )r rr_get_profile_display_namerFrErdocuments_tablesetColumnCountsetHorizontalHeaderLabelssetSelectionBehaviorSelectionBehavior SelectRowssetSelectionMode SelectionModeMultiSelectionsetSortingEnabledhorizontalHeadersetStretchLastSection resizeSectionrr rQrR_load_documents_listrO _add_document_delete_selected_documentsrUrV) r,widgetrZ info_labelr[buttons_layout refresh_btnadd_btn delete_btns r/rMz)ProfileEditorDialog._create_documents_tab2sgDTEcEcEeDfgh   ![\$ ,~ ++A. 668   11,2P2P2[2[\ --l.H.H.W.WX ..t4%%668$$U+Q$Q$Q#Q$Q$--.%!"78 ##D$=$=>  -!!#01    2 23  ) !>?   "  ""4#B#BC  ,(  !!# r0c lddlm}tjj tjj tjj t }|j dk(r|jj}nCt|dsy|jjjj}|sy |||}|j}|j&j)d|j&j+d|D]!}|j&j-} |j&j/| |j&j1| dt3|j4|j&j1| dt3|j6xsd t3t9|j:} | j=t>j@jB|j&j1| d | |jDd z } t3| d d } | j=t>j@jFt>j@jHz|j&j1| d| tKjL|jNjQd} |j&j1| dt3| |j&jS| djUt>jVjX|jZ$|j&j+dy#t$rG}t!d|ddl}|j%|j&j)dYd}~yd}~wwxYw)z,Carica lista documenti da RAGDocumentManagerrRAGDocumentManagerrrwNz"Errore caricamento documenti RAG: Frrrniz.1fz MBrz%d/%m/%YrT).(services.ragservice.rag_document_managerrr"r#r%r'rrr;hasattrrwrrrlist_documentsrprint traceback print_excr setRowCountr rowCount insertRowsetItemrfilenameauthorr chunk_countsetTextAlignmentr AlignmentFlag AlignCenter file_size AlignRight AlignVCenterr fromtimestamp indexed_datestrftimeitemsetData ItemDataRoleUserRole source_path)r,r project_rootrYmanager documentsrr docrow chunks_itemsize_mb size_itemdate_strs r/rz(ProfileEditorDialog._load_documents_listsOwwrwwrwwx7P'QR  99 ;;55L4!3400557==?EEGL  (|DG..0I ((+ ..u5 aC&&//1C  * *3 /  ( (a1A#,,1O P  ( (a1A#**BRPR1S T+3s+?@K  ( ()9)9)E)E F  ( (a =mm{3G(GC=)<=I  & &r'7'7'B'BREUEUEbEb'b c  ( (a ; --c.>.>?HHTH  ( (a1A(1K L  % %c1 - 5 5boo6N6NPSP_P_ `5 a8 ..t4Q  6qc: ;     !  , ,Q /   sM## N3,=N..N3c tj|ddd\}}|sy|jdk(r|jj}n6|j j jj}tjjtjjtjjt}tjj|dd}tdd d d |}|jt j"j$|j'd|j) t+j,t.j0||d |gd d d }|j3|j4d k(rHt7j8|ddtjj;||j=yt7j>|dd|j@y#t*jB$r*|j3t7jD|ddYytF$r=}|j3t7j>|ddtI|Yd}~yd}~wwxYw)zUpload nuovo documento PDFzSeleziona PDF da indicizzarerzPDF Files (*.pdf)Nrscriptszindicizza_documenti.pyzIndicizzazione in corso...r7rz --profileTi,)capture_outputrtimeoutrz%Documento indicizzato con successo! rzIndicizzazione fallita: Timeoutz$Indicizzazione troppo lunga (>5 min)z Errore durante indicizzazione: )%rgetOpenFileNamerrr;rwrrrr"r#r%r'r$rsetWindowModalityrWindowModality WindowModalsetCancelButtonshow subprocessrunsys executableclose returncoder rrrrstderrTimeoutExpiredrrr) r, file_path_rYr7 script_pathprogressresultrs r/rz!ProfileEditorDialog._add_documents"22  *    1  99 ;;55L00557==?EEGLwwrwwrwwx7P'QR ggll<N>Ny>Y=Z[ ))+$$1&--A (( Y NN    i1W X ` NN   x3UVYZ[V\U]1^ _ _ `s%BH &$H :J J 3JJ c |jjj}|stj|ddytj |ddt |dtjjtjjz}|tjjk7ryg}|D]f}|jj|jd}|jtjj}|j!|hddlm}t&j(j+t&j(j+t&j(j+t,}|j.d k(r|j0j2} n6|j4j7j9j;} || |} d} |D]}| j=|s| d z } | t |k(rtj>|d | d n'tj|d d| dt |d|jAy)zElimina documenti selezionatizNessuna Selezionez*Seleziona almeno un documento da eliminareNzConferma Eliminazionez Eliminare zP documento/i selezionato/i? Verranno rimossi: vettori, chunks e file originale.rrrrrz& documento/i eliminato/i con successo!zEliminazione Parzialez Eliminati /z1 documenti. Controlla i log per dettagli errori.)!rselectionModel selectedRowsr rrrrrrr2r;rrr4r5appendrrr"r#r%r'rrr;rwrrrdelete_documentrr) r, selected_rowsr source_paths row_indexr2r6rr7rYr8 deleted_counts r/rz.ProfileEditorDialog._delete_selected_documentss,,;;=JJL    &9;g h $$  #]+,-B B  & & * *[-G-G-J-J J   K..22 2  & -I'',,Y]]_a@D))BOO$<$<=K    , - Pwwrwwrwwx7P'QR 99 ;;55L00557==?EEGL$\<@ ' #K&&{3"  # C - -  # # /!GH    ']O1S->,?@77  !!#r0c&|jdk(rMddd}|j|jj|jjj S|j j jj S)z Ottieni nome display del profilorz Marco Aurelioz Warren Mentor)aureliowarren)rrrr;r<rwrr)r, profile_namess r/rz-ProfileEditorDialog._get_profile_display_name<st 99 *)M!$$T[[%?%?A[A[AfAfAhi i((--/557BBD Dr0)rN)__name__ __module__ __qualname____doc__rr)r rHrKr+tuplerrTrdictboolrr*rMrrrr __classcell__)r.s@r/rrs@'8BH!!FZZx D00dFP]c]]]~> @OwOb?5B9`v;$z E3 Er0r)rir"rMrKrrvrrrrrr r r r r rrrrrr PyQt6.QtCorer PyQt6.QtGuircore.config_managerrrr0r/rrsL -p E'p Er0