2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/ * *  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  LLM  Chat  Panel  Widget 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  BasicWidget  from  "../basic_widget.js" ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  toastService  from  "../../services/toast.js" ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  appContext  from  "../../components/app_context.js" ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  server  from  "../../services/server.js" ;  
						 
					
						
							
								
									
										
										
										
											2025-06-01 03:03:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								import  noteAutocompleteService  from  "../../services/note_autocomplete.js" ;  
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 20:12:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								import  {  TPL ,  addMessageToChat ,  showSources ,  hideSources ,  showLoadingIndicator ,  hideLoadingIndicator  }  from  "./ui.js" ;  
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								import  {  formatMarkdown  }  from  "./utils.js" ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  {  createChatSession ,  checkSessionExists ,  setupStreamingResponse ,  getDirectResponse  }  from  "./communication.js" ;  
						 
					
						
							
								
									
										
										
										
											2025-04-13 20:12:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								import  {  extractInChatToolSteps  }  from  "./message_processor.js" ;  
						 
					
						
							
								
									
										
										
										
											2025-06-07 18:20:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								import  {  validateProviders  }  from  "./validation.js" ;  
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								import  type  {  MessageData ,  ToolExecutionStep ,  ChatData  }  from  "./types.js" ;  
						 
					
						
							
								
									
										
										
										
											2025-05-26 15:17:10 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								import  {  formatCodeBlocks  }  from  "../../services/syntax_highlight.js" ;  
						 
					
						
							
								
									
										
										
										
											2025-06-01 03:03:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								import  {  ClassicEditor ,  type  CKTextEditor ,  type  MentionFeed  }  from  "@triliumnext/ckeditor5" ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  type  {  Suggestion  }  from  "../../services/note_autocomplete.js" ;  
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-22 23:02:36 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								import  "../../stylesheets/llm_chat.css" ;  
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								export  default  class  LlmChatPanel  extends  BasicWidget  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    private  noteContextChatMessages ! :  HTMLElement ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    private  noteContextChatForm ! :  HTMLFormElement ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-06-01 03:03:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    private  noteContextChatInput ! :  HTMLElement ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    private  noteContextChatInputEditor ! :  CKTextEditor ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    private  noteContextChatSendButton ! :  HTMLButtonElement ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    private  chatContainer ! :  HTMLElement ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    private  loadingIndicator ! :  HTMLElement ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    private  sourcesList ! :  HTMLElement ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    private  sourcesContainer ! :  HTMLElement ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    private  sourcesCount ! :  HTMLElement ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    private  useAdvancedContextCheckbox ! :  HTMLInputElement ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    private  showThinkingCheckbox ! :  HTMLInputElement ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    private  validationWarning ! :  HTMLElement ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-06-01 03:21:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    private  thinkingContainer ! :  HTMLElement ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    private  thinkingBubble ! :  HTMLElement ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    private  thinkingText ! :  HTMLElement ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    private  thinkingToggle ! :  HTMLElement ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-06-02 00:56:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Simplified to just use noteId - this represents the AI Chat note we're working with
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    private  noteId : string  |  null  =  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    private  currentNoteId : string  |  null  =  null ;  // The note providing context (for regular notes)
 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    private  _messageHandlerId : number  |  null  =  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    private  _messageHandler : any  =  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Callbacks for data persistence
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    private  onSaveData :  ( ( data : any )  = >  Promise < void > )  |  null  =  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    private  onGetData :  ( ( )  = >  Promise < any > )  |  null  =  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    private  messages : MessageData [ ]  =  [ ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:16:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    private  sources : Array < { noteId : string ;  title : string ;  similarity? : number ;  content? : string } >  =  [ ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    private  metadata :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        model? : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        provider? : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        temperature? : number ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        maxTokens? : number ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        toolExecutions? : Array < { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            id : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            name : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            arguments : any ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            result : any ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            error? : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            timestamp : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } > ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        lastUpdated? : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        usage ? :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            promptTokens? : number ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            completionTokens? : number ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            totalTokens? : number ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        temperature : 0.7 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        toolExecutions :  [ ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Public getters and setters for private properties
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    public  getCurrentNoteId ( ) :  string  |  null  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  this . currentNoteId ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    public  setCurrentNoteId ( noteId : string  |  null ) :  void  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        this . currentNoteId  =  noteId ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    public  getMessages ( ) :  MessageData [ ]  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  this . messages ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    public  setMessages ( messages : MessageData [ ] ) :  void  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        this . messages  =  messages ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-06-02 00:56:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    public  getNoteId ( ) :  string  |  null  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  this . noteId ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    public  setNoteId ( noteId : string  |  null ) :  void  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        this . noteId  =  noteId ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Deprecated - keeping for backward compatibility but mapping to noteId
 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-16 21:43:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    public  getChatNoteId ( ) :  string  |  null  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-06-02 00:56:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  this . noteId ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-06-02 00:56:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    public  setChatNoteId ( noteId : string  |  null ) :  void  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        this . noteId  =  noteId ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    public  getNoteContextChatMessages ( ) :  HTMLElement  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  this . noteContextChatMessages ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    public  clearNoteContextChatMessages ( ) :  void  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        this . noteContextChatMessages . innerHTML  =  '' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    doRender() { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        this . $widget  =  $ ( TPL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        const  element  =  this . $widget [ 0 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        this . noteContextChatMessages  =  element . querySelector ( '.note-context-chat-messages' )  as  HTMLElement ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        this . noteContextChatForm  =  element . querySelector ( '.note-context-chat-form' )  as  HTMLFormElement ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-06-01 03:03:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        this . noteContextChatInput  =  element . querySelector ( '.note-context-chat-input' )  as  HTMLElement ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        this . noteContextChatSendButton  =  element . querySelector ( '.note-context-chat-send-button' )  as  HTMLButtonElement ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        this . chatContainer  =  element . querySelector ( '.note-context-chat-container' )  as  HTMLElement ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        this . loadingIndicator  =  element . querySelector ( '.loading-indicator' )  as  HTMLElement ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        this . sourcesList  =  element . querySelector ( '.sources-list' )  as  HTMLElement ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        this . sourcesContainer  =  element . querySelector ( '.sources-container' )  as  HTMLElement ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        this . sourcesCount  =  element . querySelector ( '.sources-count' )  as  HTMLElement ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        this . useAdvancedContextCheckbox  =  element . querySelector ( '.use-advanced-context-checkbox' )  as  HTMLInputElement ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        this . showThinkingCheckbox  =  element . querySelector ( '.show-thinking-checkbox' )  as  HTMLInputElement ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        this . validationWarning  =  element . querySelector ( '.provider-validation-warning' )  as  HTMLElement ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-06-01 03:21:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        this . thinkingContainer  =  element . querySelector ( '.llm-thinking-container' )  as  HTMLElement ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        this . thinkingBubble  =  element . querySelector ( '.thinking-bubble' )  as  HTMLElement ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        this . thinkingText  =  element . querySelector ( '.thinking-text' )  as  HTMLElement ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        this . thinkingToggle  =  element . querySelector ( '.thinking-toggle' )  as  HTMLElement ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Set up event delegation for the settings link
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        this . validationWarning . addEventListener ( 'click' ,  ( e )  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  target  =  e . target  as  HTMLElement ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( target . classList . contains ( 'settings-link' )  ||  target . closest ( '.settings-link' ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                console . log ( 'Settings link clicked, navigating to AI settings URL' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                window . location . href  =  '#root/_hidden/_options/_optionsAi' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-06-01 03:21:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // Set up thinking toggle functionality
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        this . setupThinkingToggle ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-06-01 03:03:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // Initialize CKEditor with mention support (async)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        this . initializeCKEditor ( ) . then ( ( )  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            this . initializeEventListeners ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ) . catch ( error  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            console . error ( 'Failed to initialize CKEditor, falling back to basic event listeners:' ,  error ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            this . initializeBasicEventListeners ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  this . $widget ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-06-01 03:03:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    private  async  initializeCKEditor() { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        const  mentionSetup : MentionFeed [ ]  =  [ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                marker :  "@" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                feed :  ( queryText : string )  = >  noteAutocompleteService . autocompleteSourceForCKEditor ( queryText ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                itemRenderer :  ( item )  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    const  suggestion  =  item  as  Suggestion ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    const  itemElement  =  document . createElement ( "button" ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    itemElement . innerHTML  =  ` ${ suggestion . highlightedNotePathTitle }   ` ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    return  itemElement ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                minimumCharacters : 0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        this . noteContextChatInputEditor  =  await  ClassicEditor . create ( this . noteContextChatInput ,  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            toolbar :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                items :  [ ]  // No toolbar for chat input
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            placeholder : this.noteContextChatInput.getAttribute ( 'data-placeholder' )  ||  'Enter your message...' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            mention :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                feeds : mentionSetup 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            licenseKey :  "GPL" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Set minimal height
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        const  editorElement  =  this . noteContextChatInputEditor . ui . getEditableElement ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( editorElement )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            editorElement . style . minHeight  =  '60px' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            editorElement . style . maxHeight  =  '200px' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            editorElement . style . overflowY  =  'auto' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Set up keybindings after editor is ready
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        this . setupEditorKeyBindings ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        console . log ( 'CKEditor initialized successfully for LLM chat input' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    private  initializeBasicEventListeners() { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Fallback event listeners for when CKEditor fails to initialize
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        this . noteContextChatForm . addEventListener ( 'submit' ,  ( e )  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            e . preventDefault ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // In fallback mode, the noteContextChatInput should contain a textarea
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  textarea  =  this . noteContextChatInput . querySelector ( 'textarea' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( textarea )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                const  content  =  textarea . value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                this . sendMessage ( content ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    cleanup() { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        console . log ( ` LlmChatPanel cleanup called, removing any active WebSocket subscriptions ` ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        this . _messageHandler  =  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        this . _messageHandlerId  =  null ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-06-01 03:03:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Clean up CKEditor instance
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( this . noteContextChatInputEditor )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            this . noteContextChatInputEditor . destroy ( ) . catch ( error  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                console . error ( 'Error destroying CKEditor:' ,  error ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    / * * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  Set  the  callbacks  for  data  persistence 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     * / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    setDataCallbacks ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        saveDataCallback :  ( data : any )  = >  Promise < void > , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        getDataCallback :  ( )  = >  Promise < any > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        this . onSaveData  =  saveDataCallback ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        this . onGetData  =  getDataCallback ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    / * * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  Save  current  chat  data  to  the  note  attribute 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     * / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    async  saveCurrentData() { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! this . onSaveData )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Extract current tool execution steps if any exist
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  toolSteps  =  extractInChatToolSteps ( this . noteContextChatMessages ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:16:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // Get tool executions from both UI and any cached executions in metadata
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            let  toolExecutions : Array < { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                id : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                name : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                arguments : any ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                result : any ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                error? : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                timestamp : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } >  =  [ ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:43:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:16:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // First include any tool executions already in metadata (from streaming events)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( this . metadata ? . toolExecutions  &&  Array . isArray ( this . metadata . toolExecutions ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                toolExecutions  =  [ . . . this . metadata . toolExecutions ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                console . log ( ` Including  ${ toolExecutions . length }  tool executions from metadata ` ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:43:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:16:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // Also extract any visible tool steps from the UI
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  extractedExecutions  =  toolSteps . map ( step  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // Parse tool execution information
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( step . type  ===  'tool-execution' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        const  content  =  JSON . parse ( step . content ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            id : content.toolCallId  ||  ` tool- ${ Date . now ( ) } - ${ Math . random ( ) . toString ( 36 ) . substring ( 2 ,  7 ) } ` , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            name : content.tool  ||  'unknown' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            arguments : content.args  ||  { } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            result : content.result  ||  { } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            error : content.error , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            timestamp : new  Date ( ) . toISOString ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    }  catch  ( e )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        // If we can't parse it, create a basic record
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            id :  ` tool- ${ Date . now ( ) } - ${ Math . random ( ) . toString ( 36 ) . substring ( 2 ,  7 ) } ` , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            name :  'unknown' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            arguments :  { } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            result : step.content , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            timestamp : new  Date ( ) . toISOString ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                }  else  if  ( step . type  ===  'result'  &&  step . name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    // Handle result steps with a name
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        id :  ` tool- ${ Date . now ( ) } - ${ Math . random ( ) . toString ( 36 ) . substring ( 2 ,  7 ) } ` , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        name : step.name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        arguments :  { } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        result : step.content , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        timestamp : new  Date ( ) . toISOString ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    id :  ` tool- ${ Date . now ( ) } - ${ Math . random ( ) . toString ( 36 ) . substring ( 2 ,  7 ) } ` , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    name :  'unknown' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    arguments :  { } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    result :  'Unrecognized tool step' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    timestamp : new  Date ( ) . toISOString ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:43:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:16:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // Merge the tool executions, keeping only unique IDs
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  existingIds  =  new  Set ( toolExecutions . map ( ( t :  { id : string } )  = >  t . id ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            for  ( const  exec  of  extractedExecutions )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( ! existingIds . has ( exec . id ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    toolExecutions . push ( exec ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    existingIds . add ( exec . id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-06-02 00:56:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // Only save if we have a valid note ID
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! this . noteId )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                console . warn ( 'Cannot save chat data: no noteId available' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  dataToSave  =  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								                messages : this.messages , 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-16 18:52:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                noteId : this.noteId , 
							 
						 
					
						
							
								
									
										
										
										
											2025-06-02 00:56:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                chatNoteId : this.noteId ,  // For backward compatibility
 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:16:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                toolSteps : toolSteps , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // Add sources if we have them
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                sources : this.sources  ||  [ ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // Add metadata
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                metadata :  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-06-02 02:38:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    model : this.metadata?.model  ||  undefined , 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:16:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    provider : this.metadata?.provider  ||  undefined , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    temperature : this.metadata?.temperature  ||  0.7 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    lastUpdated : new  Date ( ) . toISOString ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    // Add tool executions
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    toolExecutions : toolExecutions 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-06-02 00:56:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            console . log ( ` Saving chat data with noteId:  ${ this . noteId } ,  ${ toolSteps . length }  tool steps,  ${ this . sources ? . length  ||  0 }  sources,  ${ toolExecutions . length }  tool executions ` ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-16 18:52:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // Save the data to the note attribute via the callback
 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-16 20:09:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // This is the ONLY place we should save data, letting the container widget handle persistence
 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            await  this . onSaveData ( dataToSave ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  catch  ( error )  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-16 18:52:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            console . error ( 'Error saving chat data:' ,  error ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-06-08 00:02:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    / * * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  Save  current  chat  data  to  a  specific  note  ID 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     * / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    async  saveCurrentDataToSpecificNote ( targetNoteId : string  |  null )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! this . onSaveData  ||  ! targetNoteId )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            console . warn ( 'Cannot save chat data: no saveData callback or no targetNoteId available' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Extract current tool execution steps if any exist
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  toolSteps  =  extractInChatToolSteps ( this . noteContextChatMessages ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Get tool executions from both UI and any cached executions in metadata
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            let  toolExecutions : Array < { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                id : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                name : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                arguments : any ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                result : any ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                error? : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                timestamp : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } >  =  [ ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // First include any tool executions already in metadata (from streaming events)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( this . metadata ? . toolExecutions  &&  Array . isArray ( this . metadata . toolExecutions ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                toolExecutions  =  [ . . . this . metadata . toolExecutions ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                console . log ( ` Including  ${ toolExecutions . length }  tool executions from metadata ` ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Also extract any visible tool steps from the UI
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  extractedExecutions  =  toolSteps . map ( step  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // Parse tool execution information
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( step . type  ===  'tool-execution' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        const  content  =  JSON . parse ( step . content ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            id : content.toolCallId  ||  ` tool- ${ Date . now ( ) } - ${ Math . random ( ) . toString ( 36 ) . substring ( 2 ,  7 ) } ` , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            name : content.tool  ||  'unknown' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            arguments : content.args  ||  { } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            result : content.result  ||  { } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            error : content.error , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            timestamp : new  Date ( ) . toISOString ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    }  catch  ( e )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        // If we can't parse it, create a basic record
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            id :  ` tool- ${ Date . now ( ) } - ${ Math . random ( ) . toString ( 36 ) . substring ( 2 ,  7 ) } ` , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            name :  'unknown' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            arguments :  { } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            result : step.content , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            timestamp : new  Date ( ) . toISOString ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                }  else  if  ( step . type  ===  'result'  &&  step . name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    // Handle result steps with a name
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        id :  ` tool- ${ Date . now ( ) } - ${ Math . random ( ) . toString ( 36 ) . substring ( 2 ,  7 ) } ` , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        name : step.name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        arguments :  { } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        result : step.content , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        timestamp : new  Date ( ) . toISOString ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    id :  ` tool- ${ Date . now ( ) } - ${ Math . random ( ) . toString ( 36 ) . substring ( 2 ,  7 ) } ` , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    name :  'unknown' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    arguments :  { } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    result :  'Unrecognized tool step' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    timestamp : new  Date ( ) . toISOString ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Merge the tool executions, keeping only unique IDs
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  existingIds  =  new  Set ( toolExecutions . map ( ( t :  { id : string } )  = >  t . id ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            for  ( const  exec  of  extractedExecutions )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( ! existingIds . has ( exec . id ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    toolExecutions . push ( exec ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    existingIds . add ( exec . id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  dataToSave  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                messages : this.messages , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                noteId : targetNoteId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                chatNoteId : targetNoteId ,  // For backward compatibility
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                toolSteps : toolSteps , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // Add sources if we have them
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                sources : this.sources  ||  [ ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // Add metadata
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                metadata :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    model : this.metadata?.model  ||  undefined , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    provider : this.metadata?.provider  ||  undefined , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    temperature : this.metadata?.temperature  ||  0.7 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    lastUpdated : new  Date ( ) . toISOString ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    // Add tool executions
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    toolExecutions : toolExecutions 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            console . log ( ` Saving chat data to specific note  ${ targetNoteId } ,  ${ toolSteps . length }  tool steps,  ${ this . sources ? . length  ||  0 }  sources,  ${ toolExecutions . length }  tool executions ` ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Save the data to the note attribute via the callback
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // This is the ONLY place we should save data, letting the container widget handle persistence
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            await  this . onSaveData ( dataToSave ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  catch  ( error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            console . error ( 'Error saving chat data to specific note:' ,  error ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    / * * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  Load  saved  chat  data  from  the  note  attribute 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     * / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    async  loadSavedData ( ) :  Promise < boolean >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! this . onGetData )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  savedData  =  await  this . onGetData ( )  as  ChatData ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( savedData ? . messages ? . length  >  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-06-02 22:34:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                // Check if we actually have new content to avoid unnecessary UI rebuilds
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                const  currentMessageCount  =  this . messages . length ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                const  savedMessageCount  =  savedData . messages . length ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // If message counts are the same, check if content is different
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                const  hasNewContent  =  savedMessageCount  >  currentMessageCount  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    JSON . stringify ( this . messages )  !==  JSON . stringify ( savedData . messages ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( ! hasNewContent )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    console . log ( "No new content detected, skipping UI rebuild" ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                console . log ( ` Loading saved data:  ${ currentMessageCount }  ->  ${ savedMessageCount }  messages ` ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // Store current scroll position if we need to preserve it
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                const  shouldPreserveScroll  =  savedMessageCount  >  currentMessageCount  &&  currentMessageCount  >  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                const  currentScrollTop  =  shouldPreserveScroll  ?  this . chatContainer.scrollTop  : 0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                const  currentScrollHeight  =  shouldPreserveScroll  ?  this . chatContainer.scrollHeight  : 0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								                // Load messages
 
							 
						 
					
						
							
								
									
										
										
										
											2025-06-02 22:34:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                const  oldMessages  =  [ . . . this . messages ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								                this . messages  =  savedData . messages ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-06-02 22:34:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                // Only rebuild UI if we have significantly different content
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( savedMessageCount  >  currentMessageCount )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    // We have new messages - just add the new ones instead of rebuilding everything
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    const  newMessages  =  savedData . messages . slice ( currentMessageCount ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    console . log ( ` Adding  ${ newMessages . length }  new messages to UI ` ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-06-02 22:34:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    newMessages . forEach ( message  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        const  role  =  message . role  as  'user'  |  'assistant' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        this . addMessageToChat ( role ,  message . content ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    // Content changed but count is same - need to rebuild
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    console . log ( "Message content changed, rebuilding UI" ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    // Clear and rebuild the chat UI
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    this . noteContextChatMessages . innerHTML  =  '' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    this . messages . forEach ( message  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        const  role  =  message . role  as  'user'  |  'assistant' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        this . addMessageToChat ( role ,  message . content ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // Restore tool execution steps if they exist
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( savedData . toolSteps  &&  Array . isArray ( savedData . toolSteps )  &&  savedData . toolSteps . length  >  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    console . log ( ` Restoring  ${ savedData . toolSteps . length }  saved tool steps ` ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    this . restoreInChatToolSteps ( savedData . toolSteps ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:16:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                // Load sources if available
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( savedData . sources  &&  Array . isArray ( savedData . sources ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    this . sources  =  savedData . sources ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    console . log ( ` Loaded  ${ this . sources . length }  sources from saved data ` ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:43:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:16:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    // Show sources in the UI if they exist
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ( this . sources . length  >  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        this . showSources ( this . sources ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // Load metadata if available
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( savedData . metadata )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    this . metadata  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        . . . this . metadata , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        . . . savedData . metadata 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:43:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:16:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    // Ensure tool executions are loaded
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ( savedData . metadata . toolExecutions  &&  Array . isArray ( savedData . metadata . toolExecutions ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        console . log ( ` Loaded  ${ savedData . metadata . toolExecutions . length }  tool executions from saved data ` ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:43:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:16:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                        if  ( ! this . metadata . toolExecutions )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            this . metadata . toolExecutions  =  [ ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        } 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:43:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:16:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                        // Make sure we don't lose any tool executions
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        this . metadata . toolExecutions  =  savedData . metadata . toolExecutions ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:43:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:16:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    console . log ( ` Loaded metadata from saved data: ` ,  this . metadata ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-16 21:43:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                // Load Chat Note ID if available
 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-16 21:53:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                if  ( savedData . noteId )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    console . log ( ` Using noteId as Chat Note ID:  ${ savedData . noteId } ` ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    this . noteId  =  savedData . noteId ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								                }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-16 21:53:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    console . log ( ` No noteId found in saved data, cannot load chat session ` ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-06-02 22:34:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                // Restore scroll position if we were preserving it
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( shouldPreserveScroll )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    // Calculate the new scroll position to maintain relative position
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    const  newScrollHeight  =  this . chatContainer . scrollHeight ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    const  scrollDifference  =  newScrollHeight  -  currentScrollHeight ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    const  newScrollTop  =  currentScrollTop  +  scrollDifference ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    // Only scroll down if we're near the bottom, otherwise preserve exact position
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    const  wasNearBottom  =  ( currentScrollTop  +  this . chatContainer . clientHeight )  >=  ( currentScrollHeight  -  50 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ( wasNearBottom )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        // User was at bottom, scroll to new bottom
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        this . chatContainer . scrollTop  =  newScrollHeight ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        console . log ( "User was at bottom, scrolling to new bottom" ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        // User was not at bottom, try to preserve their position
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        this . chatContainer . scrollTop  =  newScrollTop ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        console . log ( ` Preserving scroll position:  ${ currentScrollTop }  ->  ${ newScrollTop } ` ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								                return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  catch  ( error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            console . error ( 'Failed to load saved chat data' ,  error ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    / * * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  Restore  tool  execution  steps  in  the  chat  UI 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     * / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    private  restoreInChatToolSteps ( steps : ToolExecutionStep [ ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! steps  ||  steps . length  ===  0 )  return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Create the tool execution element
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        const  toolExecutionElement  =  document . createElement ( 'div' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        toolExecutionElement . className  =  'chat-tool-execution mb-3' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Insert before the assistant message if it exists
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        const  assistantMessage  =  this . noteContextChatMessages . querySelector ( '.assistant-message:last-child' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( assistantMessage )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            this . noteContextChatMessages . insertBefore ( toolExecutionElement ,  assistantMessage ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Otherwise append to the end
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            this . noteContextChatMessages . appendChild ( toolExecutionElement ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Fill with tool execution content
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        toolExecutionElement . innerHTML  =  ` 
 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-17 03:57:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            < div  class = "tool-execution-header d-flex align-items-center p-2 rounded" > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                < i  class = "bx bx-terminal me-2" > < / i > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                < span  class = "flex-grow-1 fw-bold" > Tool  Execution < / span > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                < button  type = "button"  class = "btn btn-sm btn-link p-0 text-muted tool-execution-toggle"  title = "Toggle tool execution details" > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    < i  class = "bx bx-chevron-down" > < / i > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                < / button > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            < / div > 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            < div  class = "tool-execution-container p-2 rounded mb-2" > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                < div  class = "tool-execution-chat-steps" > 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 20:12:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    $ { this . renderToolStepsHtml ( steps ) } 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								                < / div > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            < / div > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ` ;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-17 03:57:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // Add event listener for the toggle button
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        const  toggleButton  =  toolExecutionElement . querySelector ( '.tool-execution-toggle' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( toggleButton )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            toggleButton . addEventListener ( 'click' ,  ( )  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                const  stepsContainer  =  toolExecutionElement . querySelector ( '.tool-execution-container' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                const  icon  =  toggleButton . querySelector ( 'i' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( stepsContainer )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ( stepsContainer . classList . contains ( 'collapsed' ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        // Expand
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        stepsContainer . classList . remove ( 'collapsed' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        ( stepsContainer  as  HTMLElement ) . style . display  =  'block' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        if  ( icon )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            icon . className  =  'bx bx-chevron-down' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        // Collapse
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        stepsContainer . classList . add ( 'collapsed' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        ( stepsContainer  as  HTMLElement ) . style . display  =  'none' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        if  ( icon )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            icon . className  =  'bx bx-chevron-right' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Add click handler for the header to toggle expansion as well
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        const  header  =  toolExecutionElement . querySelector ( '.tool-execution-header' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( header )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            header . addEventListener ( 'click' ,  ( e )  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // Only toggle if the click isn't on the toggle button itself
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                const  target  =  e . target  as  HTMLElement ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( target  &&  ! target . closest ( '.tool-execution-toggle' ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    const  toggleButton  =  toolExecutionElement . querySelector ( '.tool-execution-toggle' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    toggleButton ? . dispatchEvent ( new  Event ( 'click' ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-17 03:57:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            ( header  as  HTMLElement ) . style . cursor  =  'pointer' ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 20:12:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    / * * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  Render  HTML  for  tool  execution  steps 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     * / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    private  renderToolStepsHtml ( steps : ToolExecutionStep [ ] ) :  string  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! steps  ||  steps . length  ===  0 )  return  '' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  steps . map ( step  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            let  icon  =  'bx-info-circle' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            let  className  =  'info' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            let  content  =  '' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( step . type  ===  'executing' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                icon  =  'bx-code-block' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                className  =  'executing' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                content  =  ` <div> ${ step . content  ||  'Executing tools...' } </div> ` ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  else  if  ( step . type  ===  'result' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                icon  =  'bx-terminal' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                className  =  'result' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                content  =  ` 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    < div > Tool :  < strong > $ { step . name  ||  'unknown' } < / strong > < / div > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    < div  class = "mt-1 ps-3" > $ { step . content  ||  '' } < / div > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                ` ;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  else  if  ( step . type  ===  'error' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                icon  =  'bx-error-circle' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                className  =  'error' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                content  =  ` 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    < div > Tool :  < strong > $ { step . name  ||  'unknown' } < / strong > < / div > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    < div  class = "mt-1 ps-3 text-danger" > $ { step . content  ||  'Error occurred' } < / div > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                ` ;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  else  if  ( step . type  ===  'generating' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                icon  =  'bx-message-dots' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                className  =  'generating' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                content  =  ` <div> ${ step . content  ||  'Generating response...' } </div> ` ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  ` 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                < div  class = "tool-step ${className} p-2 mb-2 rounded" > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    < div  class = "d-flex align-items-center" > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        < i  class = "bx ${icon} me-2" > < / i > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        $ { content } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    < / div > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                < / div > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            ` ;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ) . join ( '' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    async  refresh() { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! this . isVisible ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Check for any provider validation issues when refreshing
 
							 
						 
					
						
							
								
									
										
										
										
											2025-06-07 18:20:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        await  validateProviders ( this . validationWarning ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Get current note context if needed
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        const  currentActiveNoteId  =  appContext . tabManager . getActiveContext ( ) ? . note ? . noteId  ||  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-06-02 00:56:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // For AI Chat notes, the note itself IS the chat session
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // So currentNoteId and noteId should be the same
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( this . noteId  &&  currentActiveNoteId  ===  this . noteId )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // We're in an AI Chat note - don't reset, just load saved data
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            console . log ( ` Refreshing AI Chat note  ${ this . noteId }  - loading saved data ` ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            await  this . loadSavedData ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        // If we're switching to a different note, we need to reset
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( this . currentNoteId  !==  currentActiveNoteId )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            console . log ( ` Note ID changed from  ${ this . currentNoteId }  to  ${ currentActiveNoteId } , resetting chat panel ` ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Reset the UI and data
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            this . noteContextChatMessages . innerHTML  =  '' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            this . messages  =  [ ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-16 18:52:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            this . noteId  =  null ;  // Also reset the chat note ID
 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            this . hideSources ( ) ;  // Hide any sources from previous note
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Update our current noteId
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            this . currentNoteId  =  currentActiveNoteId ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Always try to load saved data for the current note
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        const  hasSavedData  =  await  this . loadSavedData ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Only create a new session if we don't have a session or saved data
 
							 
						 
					
						
							
								
									
										
										
										
											2025-06-02 00:56:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( ! this . noteId  ||  ! hasSavedData )  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            // Create a new chat session
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            await  this . createChatSession ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-16 21:53:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    / * * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  Create  a  new  chat  session 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     * / 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    private  async  createChatSession() { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        try  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-06-02 00:56:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // If we already have a noteId (for AI Chat notes), use it
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  contextNoteId  =  this . noteId  ||  this . currentNoteId ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-16 18:52:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-06-02 00:56:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // Create a new chat session, passing the context note ID
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  noteId  =  await  createChatSession ( contextNoteId  ?  contextNoteId  : undefined ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-16 18:52:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-06-02 00:56:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( noteId )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // Set the note ID for this chat
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                this . noteId  =  noteId ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-16 21:53:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                console . log ( ` Created new chat session with noteId:  ${ this . noteId } ` ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-16 18:52:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-16 21:53:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                throw  new  Error ( "Failed to create chat session - no ID returned" ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-16 18:52:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-16 21:53:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // Save the note ID as the session identifier
 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-16 18:52:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            await  this . saveCurrentData ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        }  catch  ( error )  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-16 18:52:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            console . error ( 'Error creating chat session:' ,  error ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            toastService . showError ( 'Failed to create chat session' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    / * * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  Handle  sending  a  user  message  to  the  LLM  service 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     * / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    private  async  sendMessage ( content : string )  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-16 18:52:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( ! content . trim ( ) )  return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-06-01 03:03:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // Extract mentions from the content if using CKEditor
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        let  mentions : Array < { noteId : string ;  title : string ;  notePath : string } >  =  [ ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        let  plainTextContent  =  content ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( this . noteContextChatInputEditor )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  extracted  =  this . extractMentionsAndContent ( content ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            mentions  =  extracted . mentions ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            plainTextContent  =  extracted . content ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-16 18:52:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // Add the user message to the UI and data model
 
							 
						 
					
						
							
								
									
										
										
										
											2025-06-01 03:03:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        this . addMessageToChat ( 'user' ,  plainTextContent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-16 18:52:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        this . messages . push ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            role :  'user' , 
							 
						 
					
						
							
								
									
										
										
										
											2025-06-01 03:03:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            content : plainTextContent , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            mentions : mentions.length  >  0  ?  mentions  : undefined 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-16 18:52:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Save the data immediately after a user message
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        await  this . saveCurrentData ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Clear input and show loading state
 
							 
						 
					
						
							
								
									
										
										
										
											2025-06-01 03:03:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( this . noteContextChatInputEditor )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            this . noteContextChatInputEditor . setData ( '' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-16 18:52:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        showLoadingIndicator ( this . loadingIndicator ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        this . hideSources ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  useAdvancedContext  =  this . useAdvancedContextCheckbox . checked ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  showThinking  =  this . showThinkingCheckbox . checked ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Add logging to verify parameters
 
							 
						 
					
						
							
								
									
										
										
										
											2025-06-02 00:56:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            console . log ( ` Sending message with: useAdvancedContext= ${ useAdvancedContext } , showThinking= ${ showThinking } , noteId= ${ this . currentNoteId } , sessionId= ${ this . noteId } ` ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-16 18:52:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Create the message parameters
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  messageParams  =  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-06-01 03:03:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                content : plainTextContent , 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-16 18:52:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                useAdvancedContext , 
							 
						 
					
						
							
								
									
										
										
										
											2025-06-01 03:03:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                showThinking , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                mentions : mentions.length  >  0  ?  mentions  : undefined 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-16 18:52:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Try websocket streaming (preferred method)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                await  this . setupStreamingResponse ( messageParams ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  catch  ( streamingError )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                console . warn ( "WebSocket streaming failed, falling back to direct response:" ,  streamingError ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // If streaming fails, fall back to direct response
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                const  handled  =  await  this . handleDirectResponse ( messageParams ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( ! handled )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    // If neither method works, show an error
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    throw  new  Error ( "Failed to get response from server" ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-17 03:29:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // Note: We don't need to save here since the streaming completion and direct response methods
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // both call saveCurrentData() when they're done
 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-16 18:52:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }  catch  ( error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            console . error ( 'Error processing user message:' ,  error ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            toastService . showError ( 'Failed to process message' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Add a generic error message to the UI
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            this . addMessageToChat ( 'assistant' ,  'Sorry, I encountered an error processing your message. Please try again.' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            this . messages . push ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                role :  'assistant' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                content :  'Sorry, I encountered an error processing your message. Please try again.' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Save the data even after error
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            await  this . saveCurrentData ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-16 18:52:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-16 18:52:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    / * * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  Process  a  new  user  message  -  add  to  UI  and  save 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     * / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    private  async  processUserMessage ( content : string )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Check for validation issues first
 
							 
						 
					
						
							
								
									
										
										
										
											2025-06-07 18:20:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        await  validateProviders ( this . validationWarning ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Make sure we have a valid session
 
							 
						 
					
						
							
								
									
										
										
										
											2025-06-02 00:56:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( ! this . noteId )  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            // If no session ID, create a new session
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            await  this . createChatSession ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-06-02 00:56:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( ! this . noteId )  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								                // If still no session ID, show error and return
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                console . error ( "Failed to create chat session" ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                toastService . showError ( "Failed to create chat session" ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-16 18:52:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // Add user message to messages array if not already added
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! this . messages . some ( msg  = >  msg . role  ===  'user'  &&  msg . content  ===  content ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            this . messages . push ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                role :  'user' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                content : content 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Clear input and show loading state
 
							 
						 
					
						
							
								
									
										
										
										
											2025-06-01 03:03:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( this . noteContextChatInputEditor )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            this . noteContextChatInputEditor . setData ( '' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        showLoadingIndicator ( this . loadingIndicator ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        this . hideSources ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  useAdvancedContext  =  this . useAdvancedContextCheckbox . checked ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  showThinking  =  this . showThinkingCheckbox . checked ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-16 18:52:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // Save current state to the Chat Note before getting a response
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            await  this . saveCurrentData ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            // Add logging to verify parameters
 
							 
						 
					
						
							
								
									
										
										
										
											2025-06-02 00:56:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            console . log ( ` Sending message with: useAdvancedContext= ${ useAdvancedContext } , showThinking= ${ showThinking } , noteId= ${ this . currentNoteId } , sessionId= ${ this . noteId } ` ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Create the message parameters
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  messageParams  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                content , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                useAdvancedContext , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                showThinking 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Try websocket streaming (preferred method)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                await  this . setupStreamingResponse ( messageParams ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  catch  ( streamingError )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                console . warn ( "WebSocket streaming failed, falling back to direct response:" ,  streamingError ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // If streaming fails, fall back to direct response
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                const  handled  =  await  this . handleDirectResponse ( messageParams ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( ! handled )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    // If neither method works, show an error
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    throw  new  Error ( "Failed to get response from server" ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-16 18:52:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Save final state after getting the response
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            await  this . saveCurrentData ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        }  catch  ( error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            this . handleError ( error  as  Error ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-16 18:52:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // Make sure we save the current state even on error
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            await  this . saveCurrentData ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    / * * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  Try  to  get  a  direct  response  from  the  server 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     * / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    private  async  handleDirectResponse ( messageParams : any ) :  Promise < boolean >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        try  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-06-02 00:56:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( ! this . noteId )  return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-06-02 00:56:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            console . log ( ` Getting direct response using sessionId:  ${ this . noteId }  (noteId:  ${ this . noteId } ) ` ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-16 18:52:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            // Get a direct response from the server
 
							 
						 
					
						
							
								
									
										
										
										
											2025-06-02 00:56:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            const  postResponse  =  await  getDirectResponse ( this . noteId ,  messageParams ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // If the POST request returned content directly, display it
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( postResponse  &&  postResponse . content )  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:16:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                // Store metadata from the response
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( postResponse . metadata )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    console . log ( "Received metadata from response:" ,  postResponse . metadata ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    this . metadata  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        . . . this . metadata , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        . . . postResponse . metadata 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:43:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:16:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                // Store sources from the response
 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								                if  ( postResponse . sources  &&  postResponse . sources . length  >  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:16:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    console . log ( ` Received  ${ postResponse . sources . length }  sources from response ` ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    this . sources  =  postResponse . sources ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								                    this . showSources ( postResponse . sources ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:43:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-06-08 00:02:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                // Process the assistant response with original chat note ID
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                this . processAssistantResponse ( postResponse . content ,  postResponse ,  this . noteId ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                hideLoadingIndicator ( this . loadingIndicator ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  catch  ( error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            console . error ( "Error with direct response:" ,  error ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    / * * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  Process  an  assistant  response  -  add  to  UI  and  save 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     * / 
							 
						 
					
						
							
								
									
										
										
										
											2025-06-08 00:02:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    private  async  processAssistantResponse ( content : string ,  fullResponse? : any ,  originalChatNoteId? : string  |  null )  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        // Add the response to the chat UI
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        this . addMessageToChat ( 'assistant' ,  content ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Add to our local message array too
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        this . messages . push ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            role :  'assistant' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            content , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            timestamp : new  Date ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:43:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:16:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // If we received tool execution information, add it to metadata
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( fullResponse ? . metadata ? . toolExecutions )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            console . log ( ` Storing  ${ fullResponse . metadata . toolExecutions . length }  tool executions from response ` ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Make sure our metadata has toolExecutions
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! this . metadata . toolExecutions )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                this . metadata . toolExecutions  =  [ ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:43:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:16:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // Add new tool executions
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            this . metadata . toolExecutions  =  [ 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:43:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                . . . this . metadata . toolExecutions , 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:16:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                . . . fullResponse . metadata . toolExecutions 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-06-08 00:02:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // Save to note - use original chat note ID if provided
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        this . saveCurrentDataToSpecificNote ( originalChatNoteId  ||  this . noteId ) . catch ( err  = >  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            console . error ( "Failed to save assistant response to note:" ,  err ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    / * * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  Set  up  streaming  response  via  WebSocket 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     * / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    private  async  setupStreamingResponse ( messageParams : any ) :  Promise < void >  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-06-02 00:56:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( ! this . noteId )  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            throw  new  Error ( "No session ID available" ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-06-02 00:56:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        console . log ( ` Setting up streaming response using sessionId:  ${ this . noteId }  (noteId:  ${ this . noteId } ) ` ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-16 18:52:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:16:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // Store tool executions captured during streaming
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        const  toolExecutionsCache : Array < { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            id : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            name : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            arguments : any ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            result : any ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            error? : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            timestamp : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } >  =  [ ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-06-08 00:02:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // Store the original chat note ID to ensure we save to the correct note even if user switches
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        const  originalChatNoteId  =  this . noteId ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        return  setupStreamingResponse ( 
							 
						 
					
						
							
								
									
										
										
										
											2025-06-02 00:56:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            this . noteId , 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            messageParams , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Content update handler
 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:16:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            ( content : string ,  isDone : boolean  =  false )  = >  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-06-08 00:02:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                this . updateStreamingUI ( content ,  isDone ,  originalChatNoteId ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:43:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:16:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                // Update session data with additional metadata when streaming is complete
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( isDone )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    // Update our metadata with info from the server
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    server . get < { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        metadata ? :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            model? : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            provider? : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            temperature? : number ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            maxTokens? : number ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            toolExecutions? : Array < { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                id : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                name : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                arguments : any ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                result : any ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                error? : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                timestamp : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            } > ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            lastUpdated? : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            usage ? :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                promptTokens? : number ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                completionTokens? : number ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                totalTokens? : number ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        sources? : Array < { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            noteId : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            title : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            similarity? : number ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            content? : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        } > ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-06-02 00:56:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    } > ( ` llm/chat/ ${ this . noteId } ` ) 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:16:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                        . then ( ( sessionData )  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            console . log ( "Got updated session data:" ,  sessionData ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:43:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:16:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                            // Store metadata
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            if  ( sessionData . metadata )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                this . metadata  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                    . . . this . metadata , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                    . . . sessionData . metadata 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            } 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:43:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:16:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                            // Store sources
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            if  ( sessionData . sources  &&  sessionData . sources . length  >  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                this . sources  =  sessionData . sources ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                this . showSources ( sessionData . sources ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            } 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:43:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:16:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                            // Make sure we include the cached tool executions
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            if  ( toolExecutionsCache . length  >  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                console . log ( ` Including  ${ toolExecutionsCache . length }  cached tool executions in metadata ` ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                if  ( ! this . metadata . toolExecutions )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                    this . metadata . toolExecutions  =  [ ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                } 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:43:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:16:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                                // Add any tool executions from our cache that aren't already in metadata
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                const  existingIds  =  new  Set ( ( this . metadata . toolExecutions  ||  [ ] ) . map ( ( t :  { id : string } )  = >  t . id ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                for  ( const  toolExec  of  toolExecutionsCache )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                    if  ( ! existingIds . has ( toolExec . id ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                        this . metadata . toolExecutions . push ( toolExec ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                        existingIds . add ( toolExec . id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            } 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:43:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-06-02 22:30:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                            // DON'T save here - let the server handle saving the complete conversation
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            // to avoid race conditions between client and server saves
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            console . log ( "Updated metadata after streaming completion, server should save" ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:16:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                        } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        . catch ( err  = >  console . error ( "Error fetching session data after streaming:" ,  err ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Thinking update handler
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            ( thinking : string )  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                this . showThinkingState ( thinking ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Tool execution handler
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            ( toolData : any )  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                this . showToolExecutionInfo ( toolData ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:43:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:16:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                // Cache tools we see during streaming to include them in the final saved data
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( toolData  &&  toolData . action  ===  'result'  &&  toolData . tool )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    // Create a tool execution record
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    const  toolExec  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        id : toolData.toolCallId  ||  ` tool- ${ Date . now ( ) } - ${ Math . random ( ) . toString ( 36 ) . substring ( 2 ,  7 ) } ` , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        name : toolData.tool , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        arguments : toolData.args  ||  { } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        result : toolData.result  ||  { } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        error : toolData.error , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        timestamp : new  Date ( ) . toISOString ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:43:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:16:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    // Add to both our local cache for immediate saving and to metadata for later saving
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    toolExecutionsCache . push ( toolExec ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:43:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:16:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    // Initialize toolExecutions array if it doesn't exist
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ( ! this . metadata . toolExecutions )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        this . metadata . toolExecutions  =  [ ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:43:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:16:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    // Add tool execution to our metadata
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    this . metadata . toolExecutions . push ( toolExec ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:43:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:16:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    console . log ( ` Cached tool execution for  ${ toolData . tool }  to be saved later ` ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:43:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-06-02 22:30:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    // DON'T save immediately during streaming - let the server handle saving
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    // to avoid race conditions between client and server saves
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    console . log ( ` Tool execution cached, will be saved by server ` ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:16:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Complete handler
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            ( )  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                hideLoadingIndicator ( this . loadingIndicator ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Error handler
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            ( error : Error )  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                this . handleError ( error ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    / * * 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 20:12:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								     *  Update  the  UI  with  streaming  content 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								     * / 
							 
						 
					
						
							
								
									
										
										
										
											2025-06-08 00:02:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    private  updateStreamingUI ( assistantResponse : string ,  isDone : boolean  =  false ,  originalChatNoteId? : string  |  null )  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-06-03 03:12:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // Track if we have a streaming message in progress
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        const  hasStreamingMessage  =  ! ! this . noteContextChatMessages . querySelector ( '.assistant-message.streaming' ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-06-08 00:02:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-06-03 03:12:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // Create a new message element or use the existing streaming one
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        let  assistantMessageEl : HTMLElement ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-06-08 00:02:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-06-03 03:12:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( hasStreamingMessage )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Use the existing streaming message
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            assistantMessageEl  =  this . noteContextChatMessages . querySelector ( '.assistant-message.streaming' ) ! ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Create a new message element
 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-16 18:52:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            assistantMessageEl  =  document . createElement ( 'div' ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-06-03 03:12:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            assistantMessageEl . className  =  'assistant-message message mb-3 streaming' ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-16 18:52:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            this . noteContextChatMessages . appendChild ( assistantMessageEl ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Add assistant profile icon
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  profileIcon  =  document . createElement ( 'div' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            profileIcon . className  =  'profile-icon' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            profileIcon . innerHTML  =  '<i class="bx bx-bot"></i>' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            assistantMessageEl . appendChild ( profileIcon ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Add message content container
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  messageContent  =  document . createElement ( 'div' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            messageContent . className  =  'message-content' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            assistantMessageEl . appendChild ( messageContent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-06-03 03:12:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // Update the content with the current response
 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-16 18:52:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        const  messageContent  =  assistantMessageEl . querySelector ( '.message-content' )  as  HTMLElement ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-06-02 23:25:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        messageContent . innerHTML  =  formatMarkdown ( assistantResponse ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-06-03 03:12:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // When the response is complete
 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-16 18:52:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( isDone )  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-06-03 03:12:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // Remove the streaming class to mark this message as complete
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            assistantMessageEl . classList . remove ( 'streaming' ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-06-08 00:02:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-06-03 03:12:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // Apply syntax highlighting
 
							 
						 
					
						
							
								
									
										
										
										
											2025-05-26 15:17:10 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            formatCodeBlocks ( $ ( assistantMessageEl  as  HTMLElement ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-06-01 03:21:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // Hide the thinking display when response is complete
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            this . hideThinkingDisplay ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-06-03 03:12:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // Always add a new message to the data model
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // This ensures we preserve all distinct assistant messages
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            this . messages . push ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                role :  'assistant' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                content : assistantResponse , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                timestamp : new  Date ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 21:43:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-06-08 00:02:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // Save the updated message list to the original chat note
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            this . saveCurrentDataToSpecificNote ( originalChatNoteId  ||  this . noteId ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-16 18:52:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // Scroll to bottom
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        this . chatContainer . scrollTop  =  this . chatContainer . scrollHeight ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    / * * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  Handle  general  errors  in  the  send  message  flow 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     * / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    private  handleError ( error : Error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        hideLoadingIndicator ( this . loadingIndicator ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        toastService . showError ( 'Error sending message: '  +  error . message ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    private  addMessageToChat ( role :  'user'  |  'assistant' ,  content : string )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        addMessageToChat ( this . noteContextChatMessages ,  this . chatContainer ,  role ,  content ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    private  showSources ( sources : Array < { noteId : string ,  title : string } > )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        showSources ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            this . sourcesList , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            this . sourcesContainer , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            this . sourcesCount , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            sources , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            ( noteId : string )  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // Open the note in a new tab but don't switch to it
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                appContext . tabManager . openTabWithNoteWithHoisting ( noteId ,  {  activate : false  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    private  hideSources() { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        hideSources ( this . sourcesContainer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    / * * 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-12 17:23:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								     *  Handle  tool  execution  updates 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								     * / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    private  showToolExecutionInfo ( toolExecutionData : any )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        console . log ( ` Showing tool execution info:  ${ JSON . stringify ( toolExecutionData ) } ` ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-15 22:34:23 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-14 20:15:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // Enhanced debugging for tool execution
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! toolExecutionData )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            console . error ( 'Tool execution data is missing or undefined' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-15 22:34:23 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-14 20:15:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // Check for required properties
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        const  actionType  =  toolExecutionData . action  ||  '' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        const  toolName  =  toolExecutionData . tool  ||  'unknown' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        console . log ( ` Tool execution details: action= ${ actionType } , tool= ${ toolName } , hasResult= ${ ! ! toolExecutionData . result } ` ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-15 22:34:23 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-14 20:15:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // Force action to 'result' if missing but result is present
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! actionType  &&  toolExecutionData . result )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            console . log ( 'Setting missing action to "result" since result is present' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            toolExecutionData . action  =  'result' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-12 17:23:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // Create or get the tool execution container
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        let  toolExecutionElement  =  this . noteContextChatMessages . querySelector ( '.chat-tool-execution' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! toolExecutionElement )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            toolExecutionElement  =  document . createElement ( 'div' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            toolExecutionElement . className  =  'chat-tool-execution mb-3' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-17 03:57:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // Create header with title and dropdown toggle
 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-12 17:23:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            const  header  =  document . createElement ( 'div' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            header . className  =  'tool-execution-header d-flex align-items-center p-2 rounded' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            header . innerHTML  =  ` 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                < i  class = "bx bx-terminal me-2" > < / i > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                < span  class = "flex-grow-1" > Tool  Execution < / span > 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-17 03:57:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                < button  type = "button"  class = "btn btn-sm btn-link p-0 text-muted tool-execution-toggle"  title = "Toggle tool execution details" > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    < i  class = "bx bx-chevron-down" > < / i > 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-12 17:23:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                < / button > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            ` ;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            toolExecutionElement . appendChild ( header ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Create container for tool steps
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  stepsContainer  =  document . createElement ( 'div' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            stepsContainer . className  =  'tool-execution-container p-2 rounded mb-2' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            toolExecutionElement . appendChild ( stepsContainer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Add to chat messages
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            this . noteContextChatMessages . appendChild ( toolExecutionElement ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-17 03:57:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Add click handler for toggle button
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  toggleButton  =  toolExecutionElement . querySelector ( '.tool-execution-toggle' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( toggleButton )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                toggleButton . addEventListener ( 'click' ,  ( )  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    const  stepsContainer  =  toolExecutionElement ? . querySelector ( '.tool-execution-container' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    const  icon  =  toggleButton . querySelector ( 'i' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ( stepsContainer )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        if  ( stepsContainer . classList . contains ( 'collapsed' ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            // Expand
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            stepsContainer . classList . remove ( 'collapsed' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            ( stepsContainer  as  HTMLElement ) . style . display  =  'block' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            if  ( icon )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                icon . className  =  'bx bx-chevron-down' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            // Collapse
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            stepsContainer . classList . add ( 'collapsed' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            ( stepsContainer  as  HTMLElement ) . style . display  =  'none' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            if  ( icon )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                icon . className  =  'bx bx-chevron-right' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Add click handler for the header to toggle expansion as well
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            header . addEventListener ( 'click' ,  ( e )  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // Only toggle if the click isn't on the toggle button itself
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                const  target  =  e . target  as  HTMLElement ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( target  &&  ! target . closest ( '.tool-execution-toggle' ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    const  toggleButton  =  toolExecutionElement ? . querySelector ( '.tool-execution-toggle' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    toggleButton ? . dispatchEvent ( new  Event ( 'click' ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            ( header  as  HTMLElement ) . style . cursor  =  'pointer' ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-12 17:23:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Get the steps container
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        const  stepsContainer  =  toolExecutionElement . querySelector ( '.tool-execution-container' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! stepsContainer )  return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Process based on action type
 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 20:12:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        const  action  =  toolExecutionData . action  ||  '' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( action  ===  'start'  ||  action  ===  'executing' )  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-12 17:23:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // Tool execution started
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  step  =  document . createElement ( 'div' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            step . className  =  'tool-step executing p-2 mb-2 rounded' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            step . innerHTML  =  ` 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                < div  class = "d-flex align-items-center" > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    < i  class = "bx bx-code-block me-2" > < / i > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    < span > Executing  tool :  < strong > $ { toolExecutionData . tool  ||  'unknown' } < / strong > < / span > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                < / div > 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 20:12:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                $ { toolExecutionData . args  ?  ` 
 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-12 17:23:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                < div  class = "tool-args mt-1 ps-3" > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    < code > Args : $ { JSON . stringify ( toolExecutionData . args  ||  { } ,  null ,  2 ) } < / code > 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 20:12:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                < / div > `  : ''}
 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-12 17:23:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            ` ;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            stepsContainer . appendChild ( step ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 20:12:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        else  if  ( action  ===  'result'  ||  action  ===  'complete' )  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-12 17:23:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // Tool execution completed with results
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  step  =  document . createElement ( 'div' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            step . className  =  'tool-step result p-2 mb-2 rounded' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            let  resultDisplay  =  '' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-14 20:15:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // Special handling for note search tools which have a specific structure
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ( toolExecutionData . tool  ===  'search_notes'  ||  toolExecutionData . tool  ===  'keyword_search_notes' )  && 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 20:12:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                typeof  toolExecutionData . result  ===  'object'  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                toolExecutionData . result . results )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                const  results  =  toolExecutionData . result . results ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( results . length  ===  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    resultDisplay  =  ` <div class="text-muted">No notes found matching the search criteria.</div> ` ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    resultDisplay  =  ` 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        < div  class = "search-results" > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            < div  class = "mb-2" > Found  $ { results . length }  notes : < / div > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            < ul  class = "list-unstyled ps-1" > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                $ { results . map ( ( note : any )  = >  ` 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                    < li  class = "mb-1" > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                        < a  href = "#"  class = "note-link"  data-note-id = "${note.noteId}" > $ { note . title } < / a > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                        $ { note . similarity  <  1  ?  ` <span class="text-muted small ms-1">(similarity:  ${ ( note . similarity  *  100 ) . toFixed ( 0 ) } %)</span> `  :  '' } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                    < / li > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                ` ).join('')}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            < / ul > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        < / div > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    ` ;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Format the result based on type for other tools
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            else  if  ( typeof  toolExecutionData . result  ===  'object' )  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-12 17:23:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                // For objects, format as pretty JSON
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                resultDisplay  =  ` <pre class="mb-0"><code> ${ JSON . stringify ( toolExecutionData . result ,  null ,  2 ) } </code></pre> ` ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // For simple values, display as text
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                resultDisplay  =  ` <div> ${ String ( toolExecutionData . result ) } </div> ` ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            step . innerHTML  =  ` 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                < div  class = "d-flex align-items-center" > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    < i  class = "bx bx-terminal me-2" > < / i > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    < span > Tool :  < strong > $ { toolExecutionData . tool  ||  'unknown' } < / strong > < / span > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                < / div > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                < div  class = "tool-result mt-1 ps-3" > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    $ { resultDisplay } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                < / div > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            ` ;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            stepsContainer . appendChild ( step ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 20:12:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-14 20:15:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // Add event listeners for note links if this is a note search result
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( toolExecutionData . tool  ===  'search_notes'  ||  toolExecutionData . tool  ===  'keyword_search_notes' )  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 20:12:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                const  noteLinks  =  step . querySelectorAll ( '.note-link' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                noteLinks . forEach ( link  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    link . addEventListener ( 'click' ,  ( e )  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        e . preventDefault ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        const  noteId  =  ( e . currentTarget  as  HTMLElement ) . getAttribute ( 'data-note-id' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        if  ( noteId )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            // Open the note in a new tab but don't switch to it
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            appContext . tabManager . openTabWithNoteWithHoisting ( noteId ,  {  activate : false  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-12 17:23:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 20:12:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        else  if  ( action  ===  'error' )  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-12 17:23:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            // Tool execution failed
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  step  =  document . createElement ( 'div' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            step . className  =  'tool-step error p-2 mb-2 rounded' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            step . innerHTML  =  ` 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                < div  class = "d-flex align-items-center" > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    < i  class = "bx bx-error-circle me-2" > < / i > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    < span > Error  in  tool :  < strong > $ { toolExecutionData . tool  ||  'unknown' } < / strong > < / span > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                < / div > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                < div  class = "tool-error mt-1 ps-3 text-danger" > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    $ { toolExecutionData . error  ||  'Unknown error' } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                < / div > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            ` ;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            stepsContainer . appendChild ( step ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-13 20:12:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        else  if  ( action  ===  'generating' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Generating final response with tool results
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  step  =  document . createElement ( 'div' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            step . className  =  'tool-step generating p-2 mb-2 rounded' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            step . innerHTML  =  ` 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                < div  class = "d-flex align-items-center" > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    < i  class = "bx bx-message-dots me-2" > < / i > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    < span > Generating  response  with  tool  results . . . < / span > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                < / div > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            ` ;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            stepsContainer . appendChild ( step ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Make sure the loading indicator is shown during tool execution
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        this . loadingIndicator . style . display  =  'flex' ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-12 17:23:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Scroll the chat container to show the tool execution
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        this . chatContainer . scrollTop  =  this . chatContainer . scrollHeight ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    / * * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  Show  thinking  state  in  the  UI 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     * / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    private  showThinkingState ( thinkingData : string )  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-06-01 03:21:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // Parse the thinking content to extract text between <think> tags
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        const  thinkingContent  =  this . parseThinkingContent ( thinkingData ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( thinkingContent )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            this . showThinkingDisplay ( thinkingContent ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Fallback: show raw thinking data
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            this . showThinkingDisplay ( thinkingData ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-06-01 03:21:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // Show the loading indicator as well
 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        this . loadingIndicator . style . display  =  'flex' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-06-01 03:21:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    / * * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  Parse  thinking  content  from  LLM  response 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     * / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    private  parseThinkingContent ( content : string ) :  string  |  null  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! content )  return  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Look for content between <think> and </think> tags
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        const  thinkRegex  =  /<think>([\s\S]*?)<\/think>/gi ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        const  matches : string [ ]  =  [ ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        let  match : RegExpExecArray  |  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        while  ( ( match  =  thinkRegex . exec ( content ) )  !==  null )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            matches . push ( match [ 1 ] . trim ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( matches . length  >  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  matches . join ( '\n\n--- Next thought ---\n\n' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Check for incomplete thinking blocks (streaming in progress)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        const  incompleteThinkRegex  =  /<think>([\s\S]*?)$/i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        const  incompleteMatch  =  content . match ( incompleteThinkRegex ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( incompleteMatch  &&  incompleteMatch [ 1 ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  incompleteMatch [ 1 ] . trim ( )  +  '\n\n[Thinking in progress...]' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // If no think tags found, check if the entire content might be thinking
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( content . toLowerCase ( ) . includes ( 'thinking' )  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            content . toLowerCase ( ) . includes ( 'reasoning' )  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            content . toLowerCase ( ) . includes ( 'let me think' )  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            content . toLowerCase ( ) . includes ( 'i need to' )  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            content . toLowerCase ( ) . includes ( 'first, ' )  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            content . toLowerCase ( ) . includes ( 'step 1' )  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            content . toLowerCase ( ) . includes ( 'analysis:' ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  content ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    private  initializeEventListeners() { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        this . noteContextChatForm . addEventListener ( 'submit' ,  ( e )  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            e . preventDefault ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-06-01 03:03:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            let  content  =  '' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( this . noteContextChatInputEditor  &&  this . noteContextChatInputEditor . getData )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // Use CKEditor content
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                content  =  this . noteContextChatInputEditor . getData ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // Fallback: check if there's a textarea (fallback mode)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                const  textarea  =  this . noteContextChatInput . querySelector ( 'textarea' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( textarea )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    content  =  textarea . value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    // Last resort: try to get text content from the div
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    content  =  this . noteContextChatInput . textContent  ||  this . noteContextChatInput . innerText  ||  '' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( content . trim ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                this . sendMessage ( content ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-06-01 03:03:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // Handle Enter key (send on Enter, new line on Shift+Enter) via CKEditor
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // We'll set this up after CKEditor is initialized
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        this . setupEditorKeyBindings ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    private  setupEditorKeyBindings() { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( this . noteContextChatInputEditor  &&  this . noteContextChatInputEditor . keystrokes )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                this . noteContextChatInputEditor . keystrokes . set ( 'Enter' ,  ( key ,  stop )  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ( ! key . shiftKey )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        stop ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        this . noteContextChatForm . dispatchEvent ( new  Event ( 'submit' ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                console . log ( 'CKEditor keybindings set up successfully' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  catch  ( error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                console . warn ( 'Failed to set up CKEditor keybindings:' ,  error ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    / * * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  Extract  note  mentions  and  content  from  CKEditor 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     * / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    private  extractMentionsAndContent ( editorData : string ) :  {  content : string ;  mentions : Array < { noteId : string ;  title : string ;  notePath : string } >  }  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        const  mentions : Array < { noteId : string ;  title : string ;  notePath : string } >  =  [ ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Parse the HTML content to extract mentions
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        const  tempDiv  =  document . createElement ( 'div' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        tempDiv . innerHTML  =  editorData ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Find all mention elements - CKEditor uses specific patterns for mentions
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Look for elements with data-mention attribute or specific mention classes
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        const  mentionElements  =  tempDiv . querySelectorAll ( '[data-mention], .mention, span[data-id]' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        mentionElements . forEach ( mentionEl  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // Try different ways to extract mention data based on CKEditor's format
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                let  mentionData : any  =  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // Method 1: data-mention attribute (JSON format)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( mentionEl . hasAttribute ( 'data-mention' ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    mentionData  =  JSON . parse ( mentionEl . getAttribute ( 'data-mention' )  ||  '{}' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // Method 2: data-id attribute (simple format)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                else  if  ( mentionEl . hasAttribute ( 'data-id' ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    const  dataId  =  mentionEl . getAttribute ( 'data-id' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    const  textContent  =  mentionEl . textContent  ||  '' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    // Parse the dataId to extract note information
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ( dataId  &&  dataId . startsWith ( '@' ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        const  cleanId  =  dataId . substring ( 1 ) ;  // Remove the @
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        mentionData  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            id : cleanId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            name : textContent , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            notePath : cleanId  // Assume the ID contains the path
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // Method 3: Check if this is a reference link (href=#notePath)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                else  if  ( mentionEl . tagName  ===  'A'  &&  mentionEl . hasAttribute ( 'href' ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    const  href  =  mentionEl . getAttribute ( 'href' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ( href  &&  href . startsWith ( '#' ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        const  notePath  =  href . substring ( 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        mentionData  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            notePath : notePath , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            noteTitle : mentionEl.textContent  ||  'Unknown Note' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( mentionData  &&  ( mentionData . notePath  ||  mentionData . link ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    const  notePath  =  mentionData . notePath  ||  mentionData . link ? . substring ( 1 ) ;  // Remove # from link
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    const  noteId  =  notePath  ?  notePath . split ( '/' ) . pop ( )  :  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    const  title  =  mentionData . noteTitle  ||  mentionData . name  ||  mentionEl . textContent  ||  'Unknown Note' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ( noteId )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        mentions . push ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            noteId : noteId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            title : title , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            notePath : notePath 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        console . log ( ` Extracted mention: noteId= ${ noteId } , title= ${ title } , notePath= ${ notePath } ` ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  catch  ( e )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                console . warn ( 'Failed to parse mention data:' ,  e ,  mentionEl ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-06-01 03:03:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Convert to plain text for the LLM, but preserve the structure
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        const  content  =  tempDiv . textContent  ||  tempDiv . innerText  ||  '' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        console . log ( ` Extracted  ${ mentions . length }  mentions from editor content ` ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  {  content ,  mentions  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2025-06-01 03:21:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    private  setupThinkingToggle() { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( this . thinkingToggle )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            this . thinkingToggle . addEventListener ( 'click' ,  ( e )  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                e . stopPropagation ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                this . toggleThinkingDetails ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Also make the entire header clickable
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        const  thinkingHeader  =  this . thinkingBubble ? . querySelector ( '.thinking-header' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( thinkingHeader )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            thinkingHeader . addEventListener ( 'click' ,  ( e )  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                const  target  =  e . target  as  HTMLElement ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( ! target . closest ( '.thinking-toggle' ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    this . toggleThinkingDetails ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    private  toggleThinkingDetails() { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        const  content  =  this . thinkingBubble ? . querySelector ( '.thinking-content' )  as  HTMLElement ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        const  toggle  =  this . thinkingToggle ? . querySelector ( 'i' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( content  &&  toggle )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  isVisible  =  content . style . display  !==  'none' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( isVisible )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                content . style . display  =  'none' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                toggle . className  =  'bx bx-chevron-down' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                this . thinkingToggle . classList . remove ( 'expanded' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                content . style . display  =  'block' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                toggle . className  =  'bx bx-chevron-up' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                this . thinkingToggle . classList . add ( 'expanded' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    / * * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  Show  the  thinking  display  with  optional  initial  content 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     * / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    private  showThinkingDisplay ( initialText : string  =  '' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( this . thinkingContainer )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            this . thinkingContainer . style . display  =  'block' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( initialText  &&  this . thinkingText )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                this . updateThinkingText ( initialText ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Scroll to show the thinking display
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            this . chatContainer . scrollTop  =  this . chatContainer . scrollHeight ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    / * * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  Update  the  thinking  text  content 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     * / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    private  updateThinkingText ( text : string )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( this . thinkingText )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Format the thinking text for better readability
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  formattedText  =  this . formatThinkingText ( text ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            this . thinkingText . textContent  =  formattedText ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Auto-scroll if content is expanded
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  content  =  this . thinkingBubble ? . querySelector ( '.thinking-content' )  as  HTMLElement ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( content  &&  content . style . display  !==  'none' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                this . chatContainer . scrollTop  =  this . chatContainer . scrollHeight ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    / * * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  Format  thinking  text  for  better  presentation 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     * / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    private  formatThinkingText ( text : string ) :  string  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! text )  return  text ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Clean up the text
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        let  formatted  =  text . trim ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Add some basic formatting
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        formatted  =  formatted 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Add spacing around section markers
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            . replace ( /(\d+\.\s)/g ,  '\n$1' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Clean up excessive whitespace
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            . replace ( /\n\s*\n\s*\n/g ,  '\n\n' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Trim again
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            . trim ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  formatted ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    / * * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  Hide  the  thinking  display 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     * / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    private  hideThinkingDisplay() { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( this . thinkingContainer )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            this . thinkingContainer . style . display  =  'none' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Reset the toggle state
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  content  =  this . thinkingBubble ? . querySelector ( '.thinking-content' )  as  HTMLElement ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  toggle  =  this . thinkingToggle ? . querySelector ( 'i' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( content  &&  toggle )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                content . style . display  =  'none' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                toggle . className  =  'bx bx-chevron-down' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                this . thinkingToggle ? . classList . remove ( 'expanded' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // Clear the text content
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( this . thinkingText )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                this . thinkingText . textContent  =  '' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    / * * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  Append  to  existing  thinking  content  ( for  streaming  updates ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     * / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    private  appendThinkingText ( additionalText : string )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( this . thinkingText  &&  additionalText )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  currentText  =  this . thinkingText . textContent  ||  '' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            const  newText  =  currentText  +  additionalText ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            this . updateThinkingText ( newText ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-11 21:52:54 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}